release v0.1.1
This commit is contained in:
parent
6ef16e7b9d
commit
b900340a42
@ -4,13 +4,13 @@
|
|||||||
"summary": "技能目录站:把对外发布的技能生成一个静态站(能干什么 / 先装什么 / 要配什么 / 依赖谁 / 一条安装命令),生成物不手改页面。",
|
"summary": "技能目录站:把对外发布的技能生成一个静态站(能干什么 / 先装什么 / 要配什么 / 依赖谁 / 一条安装命令),生成物不手改页面。",
|
||||||
"tier": 1,
|
"tier": 1,
|
||||||
"status": "stable",
|
"status": "stable",
|
||||||
"version": "5da1a0f",
|
"version": "f7a6763",
|
||||||
"source": {
|
"source": {
|
||||||
"path": "skills/skill-catalog",
|
"path": "skills/skill-catalog",
|
||||||
"commit": "5da1a0f",
|
"commit": "f7a6763",
|
||||||
"describe": "5da1a0f",
|
"describe": "f7a6763",
|
||||||
"dirty": false,
|
"dirty": false,
|
||||||
"packed_at": "2026-10-02T01:27:14.099Z"
|
"packed_at": "2026-10-02T01:30:47.222Z"
|
||||||
},
|
},
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"darwin",
|
"darwin",
|
||||||
@ -174,17 +174,22 @@
|
|||||||
{
|
{
|
||||||
"path": "VERSION",
|
"path": "VERSION",
|
||||||
"bytes": 6,
|
"bytes": 6,
|
||||||
"sha256": "e9dd8507f4bf0c6f"
|
"sha256": "80447316529fc620"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "assets/app.js",
|
"path": "assets/app.js",
|
||||||
"bytes": 3114,
|
"bytes": 4601,
|
||||||
"sha256": "bfb8b03ff9d4b971"
|
"sha256": "78a507c30e6c9cf9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "assets/favicon.svg",
|
||||||
|
"bytes": 235,
|
||||||
|
"sha256": "dc255fa0fe62baca"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "assets/style.css",
|
"path": "assets/style.css",
|
||||||
"bytes": 16162,
|
"bytes": 16997,
|
||||||
"sha256": "16217b36cb3db39d"
|
"sha256": "dfe35d419987cc81"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "contract.lock.json",
|
"path": "contract.lock.json",
|
||||||
@ -193,8 +198,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "interface.json",
|
"path": "interface.json",
|
||||||
"bytes": 2783,
|
"bytes": 2780,
|
||||||
"sha256": "d413b130d1140cfd"
|
"sha256": "1417b2ba9c473218"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "scripts/setup-hosting.sh",
|
"path": "scripts/setup-hosting.sh",
|
||||||
@ -203,8 +208,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "scripts/skill-catalog.mjs",
|
"path": "scripts/skill-catalog.mjs",
|
||||||
"bytes": 36074,
|
"bytes": 37551,
|
||||||
"sha256": "d97ba74c71008450"
|
"sha256": "7bdd12c1aeea89c5"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"leak_scan": {
|
"leak_scan": {
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
## 安装
|
## 安装
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
pi install git:gitea.vhkd.top/geekinney/skill-catalog.git@v0.1.0
|
pi install git:gitea.vhkd.top/pi-hub/skill-catalog.git@v0.1.1
|
||||||
```
|
```
|
||||||
|
|
||||||
装完 `pi-skill list` 能看到 `skill-catalog`,`pi-skill skill-catalog check` 会告诉还缺什么。
|
装完 `pi-skill list` 能看到 `skill-catalog`,`pi-skill skill-catalog check` 会告诉还缺什么。
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "skill-catalog",
|
"name": "skill-catalog",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"description": "技能目录站:把对外发布的技能生成一个静态站(能干什么 / 先装什么 / 要配什么 / 依赖谁 / 一条安装命令),生成物不手改页面。"
|
"description": "技能目录站:把对外发布的技能生成一个静态站(能干什么 / 先装什么 / 要配什么 / 依赖谁 / 一条安装命令),生成物不手改页面。"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
0.1.0
|
0.1.1
|
||||||
|
|||||||
@ -77,5 +77,46 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 键盘:/ 聚焦搜索,Esc 清空并退出;筛选状态写进 URL(可分享/可回退)。
|
||||||
|
document.addEventListener('keydown', event => {
|
||||||
|
const typing = /^(INPUT|TEXTAREA|SELECT)$/.test(document.activeElement?.tagName ?? '');
|
||||||
|
if (event.key === '/' && !typing) {
|
||||||
|
event.preventDefault();
|
||||||
|
search?.focus();
|
||||||
|
search?.select();
|
||||||
|
} else if (event.key === 'Escape' && (typing || search?.value)) {
|
||||||
|
if (search) {
|
||||||
|
search.value = '';
|
||||||
|
apply();
|
||||||
|
if (typing) search.blur();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const syncHash = () => {
|
||||||
|
const hash = activeLayers.size ? `#${[...activeLayers].sort().join(',')}` : '';
|
||||||
|
if (location.hash !== hash) history.replaceState(null, '', `${location.pathname}${location.search}${hash}`);
|
||||||
|
};
|
||||||
|
const readHash = () => {
|
||||||
|
const wanted = location.hash.replace(/^#/, '').split(',').map(s => s.trim()).filter(Boolean);
|
||||||
|
for (const chip of layerFilters) {
|
||||||
|
const layer = chip.dataset.layerFilter;
|
||||||
|
if (wanted.includes(layer)) {
|
||||||
|
activeLayers.add(layer);
|
||||||
|
chip.classList.add('active');
|
||||||
|
chip.setAttribute('aria-pressed', 'true');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
for (const chip of layerFilters) {
|
||||||
|
chip.addEventListener('click', () => {
|
||||||
|
chip.setAttribute('aria-pressed', String(activeLayers.has(chip.dataset.layerFilter)));
|
||||||
|
syncHash();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
window.addEventListener('hashchange', () => location.reload());
|
||||||
|
readHash();
|
||||||
|
if (activeLayers.size) apply();
|
||||||
|
|
||||||
apply();
|
apply();
|
||||||
})();
|
})();
|
||||||
|
|||||||
4
skills/skill-catalog/assets/favicon.svg
Normal file
4
skills/skill-catalog/assets/favicon.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64">
|
||||||
|
<rect width="64" height="64" rx="6" fill="#1b1e24"/>
|
||||||
|
<text x="32" y="45" text-anchor="middle" font-family="Georgia, serif" font-size="40" fill="#fbfbf9">π</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 235 B |
@ -334,3 +334,25 @@ button.chip.active { color: var(--accent); border-color: currentColor; }
|
|||||||
@media (prefers-reduced-motion: reduce) {
|
@media (prefers-reduced-motion: reduce) {
|
||||||
* { transition: none !important; }
|
* { transition: none !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ── 产品细节:静态信息 vs 可点控件要有区分 ───────────── */
|
||||||
|
.meta-chip {
|
||||||
|
font-family: var(--mono); font-size: 11px; letter-spacing: .04em;
|
||||||
|
color: var(--faint); white-space: nowrap;
|
||||||
|
}
|
||||||
|
.meta-chip-warn { color: var(--warn); }
|
||||||
|
.card-foot .meta-chip { margin-right: 2px; }
|
||||||
|
|
||||||
|
.cta-label {
|
||||||
|
font-family: var(--mono); font-size: var(--t-xs); letter-spacing: .12em;
|
||||||
|
text-transform: uppercase; color: var(--faint); margin: 0 0 var(--s-2);
|
||||||
|
}
|
||||||
|
.cta-more { font-size: var(--t-sm); color: var(--muted); border-bottom: 1px solid var(--line-2); padding-bottom: 1px; }
|
||||||
|
.cta-more:hover { color: var(--accent); border-color: currentColor; }
|
||||||
|
|
||||||
|
/* 移动端:只收起文字链接,主题开关必须留着 */
|
||||||
|
@media (max-width: 720px) {
|
||||||
|
.nav-links { gap: 0; }
|
||||||
|
.nav-links a { display: none; }
|
||||||
|
}
|
||||||
|
|||||||
@ -101,6 +101,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"publish": {
|
"publish": {
|
||||||
"package_repo": "https://gitea.vhkd.top/geekinney/skill-catalog.git"
|
"package_repo": "https://gitea.vhkd.top/pi-hub/skill-catalog.git"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -206,7 +206,7 @@ function siteNav(depth = 0) {
|
|||||||
<a class="nav-brand" href="${prefix}index.html"><span class="brand-mark">π</span><span><strong>${BRAND.name}</strong><em>${BRAND.scope}</em></span></a>
|
<a class="nav-brand" href="${prefix}index.html"><span class="brand-mark">π</span><span><strong>${BRAND.name}</strong><em>${BRAND.scope}</em></span></a>
|
||||||
<div class="nav-links">
|
<div class="nav-links">
|
||||||
<a href="${prefix}index.html">目录</a>
|
<a href="${prefix}index.html">目录</a>
|
||||||
<a href="https://gitea.vhkd.top/geekinney" target="_blank" rel="noreferrer">仓库</a>
|
<a href="https://gitea.vhkd.top/pi-hub" target="_blank" rel="noreferrer">仓库</a>
|
||||||
<a href="https://pi.dev/packages" target="_blank" rel="noreferrer">官方画廊</a>
|
<a href="https://pi.dev/packages" target="_blank" rel="noreferrer">官方画廊</a>
|
||||||
<button class="theme-toggle" id="theme-toggle" type="button" aria-label="切换明暗主题" title="切换明暗主题">
|
<button class="theme-toggle" id="theme-toggle" type="button" aria-label="切换明暗主题" title="切换明暗主题">
|
||||||
<svg class="icon-sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4.2"/><g stroke-linecap="round"><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.3 5.3l1.6 1.6M17.1 17.1l1.6 1.6M18.7 5.3l-1.6 1.6M6.9 17.1l-1.6 1.6"/></g></svg>
|
<svg class="icon-sun" viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="4.2"/><g stroke-linecap="round"><path d="M12 2.6v2.2M12 19.2v2.2M2.6 12h2.2M19.2 12h2.2M5.3 5.3l1.6 1.6M17.1 17.1l1.6 1.6M18.7 5.3l-1.6 1.6M6.9 17.1l-1.6 1.6"/></g></svg>
|
||||||
@ -223,7 +223,7 @@ function siteFoot(depth = 0) {
|
|||||||
<div><h4>关于</h4><p>这里收录的条目都从技能自己的声明生成,和仓库同步;页面不手改。</p></div>
|
<div><h4>关于</h4><p>这里收录的条目都从技能自己的声明生成,和仓库同步;页面不手改。</p></div>
|
||||||
<div><h4>资源</h4><ul>
|
<div><h4>资源</h4><ul>
|
||||||
<li><a href="https://pi.dev/packages" target="_blank" rel="noreferrer">官方画廊 pi.dev/packages</a></li>
|
<li><a href="https://pi.dev/packages" target="_blank" rel="noreferrer">官方画廊 pi.dev/packages</a></li>
|
||||||
<li><a href="https://gitea.vhkd.top/geekinney" target="_blank" rel="noreferrer">Gitea 仓库</a></li>
|
<li><a href="https://gitea.vhkd.top/pi-hub" target="_blank" rel="noreferrer">Gitea 仓库</a></li>
|
||||||
<li><a href="${prefix}catalog.json">catalog.json(机器可读)</a></li>
|
<li><a href="${prefix}catalog.json">catalog.json(机器可读)</a></li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<div><h4>字体</h4><ul>
|
<div><h4>字体</h4><ul>
|
||||||
@ -253,6 +253,14 @@ function pageShell({ title, description, body, siteUrl, depth = 0, fontsCss = nu
|
|||||||
<title>${escapeHtml(title)}</title>
|
<title>${escapeHtml(title)}</title>
|
||||||
<meta name="description" content="${escapeHtml(description)}">
|
<meta name="description" content="${escapeHtml(description)}">
|
||||||
${fontsCss ? fontsCss.map(href => `<link rel="stylesheet" href="${prefix}assets/${href}">`).join('\n') : ''}
|
${fontsCss ? fontsCss.map(href => `<link rel="stylesheet" href="${prefix}assets/${href}">`).join('\n') : ''}
|
||||||
|
<link rel="icon" href="${prefix}assets/favicon.svg" type="image/svg+xml">
|
||||||
|
<meta name="theme-color" content="#fbfbf9" media="(prefers-color-scheme: light)">
|
||||||
|
<meta name="theme-color" content="#101114" media="(prefers-color-scheme: dark)">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta property="og:title" content="${escapeHtml(title)}">
|
||||||
|
<meta property="og:description" content="${escapeHtml(description)}">
|
||||||
|
${siteUrl ? `<meta property="og:url" content="${escapeHtml(siteUrl)}">` : ''}
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
<link rel="stylesheet" href="${prefix}assets/style.css">
|
<link rel="stylesheet" href="${prefix}assets/style.css">
|
||||||
${siteUrl ? `<link rel="canonical" href="${escapeHtml(siteUrl)}">` : ''}
|
${siteUrl ? `<link rel="canonical" href="${escapeHtml(siteUrl)}">` : ''}
|
||||||
</head>
|
</head>
|
||||||
@ -277,8 +285,8 @@ const LAYER_HINT = {
|
|||||||
|
|
||||||
function cardOf(entry) {
|
function cardOf(entry) {
|
||||||
const facts = [
|
const facts = [
|
||||||
...entry.requires.slice(0, 3).map(item => `<span class="chip">${escapeHtml(item.name)}</span>`),
|
...entry.requires.slice(0, 3).map(item => `<span class="meta-chip">${escapeHtml(item.name)}</span>`),
|
||||||
...(entry.installable ? [] : ['<span class="chip chip-warn">依赖未公开</span>']),
|
...(entry.installable ? [] : ['<span class="meta-chip meta-chip-warn">依赖未公开</span>']),
|
||||||
].join('');
|
].join('');
|
||||||
const used = entry.usedByCount ? `<span class="used">被 ${entry.usedByCount} 个技能使用</span>` : '';
|
const used = entry.usedByCount ? `<span class="used">被 ${entry.usedByCount} 个技能使用</span>` : '';
|
||||||
return `<a class="card" href="skills/${escapeHtml(entry.name)}.html" data-layer="${entry.layer}"
|
return `<a class="card" href="skills/${escapeHtml(entry.name)}.html" data-layer="${entry.layer}"
|
||||||
@ -382,9 +390,9 @@ ${entry.usesPublic.length || entry.usedBy.length ? '' : '<li class="muted">独
|
|||||||
<p class="lede">${escapeHtml(entry.summary)}</p>
|
<p class="lede">${escapeHtml(entry.summary)}</p>
|
||||||
<div class="chips">
|
<div class="chips">
|
||||||
<span class="chip layer-${entry.layer}">${LAYER_LABEL[entry.layer]}</span>
|
<span class="chip layer-${entry.layer}">${LAYER_LABEL[entry.layer]}</span>
|
||||||
<span class="chip">${LAYER_HINT[entry.layer]}</span>
|
<span class="meta-chip">${LAYER_HINT[entry.layer]}</span>
|
||||||
${entry.status !== 'stable' ? `<span class="chip chip-warn">${entry.status === 'experimental' ? '实验性' : '将退役'}</span>` : ''}
|
${entry.status !== 'stable' ? `<span class="meta-chip meta-chip-warn">${entry.status === 'experimental' ? '实验性' : '将退役'}</span>` : ''}
|
||||||
${entry.platforms.map(platform => `<span class="chip">${escapeHtml(platform)}</span>`).join('')}
|
${entry.platforms.map(platform => `<span class="meta-chip">${escapeHtml(platform)}</span>`).join('')}
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="detail-grid">
|
<div class="detail-grid">
|
||||||
@ -432,23 +440,24 @@ function indexPage(entries, siteUrl, fontsCss) {
|
|||||||
</section>`;
|
</section>`;
|
||||||
})
|
})
|
||||||
.join('\n');
|
.join('\n');
|
||||||
const latest = entries[0];
|
// 安装示例取最底层的一个:稳定、有意义,不是随便挑第一条。
|
||||||
const kinds = entries.length;
|
const sample = entries.find(entry => entry.layer === 'core') ?? entries[0];
|
||||||
const body = `<header class="masthead">
|
const body = `<header class="masthead">
|
||||||
<p class="eyebrow">${BRAND.name} · 自托管目录</p>
|
<p class="eyebrow">${BRAND.name} · 自托管目录</p>
|
||||||
<h1>${BRAND.tagline}</h1>
|
<h1>${BRAND.tagline}</h1>
|
||||||
<p class="lede">${SCOPE_HTML}的集中目录。每条都写清依赖、前置条件与安装命令,装完就能用。</p>
|
<p class="lede">${SCOPE_HTML}的集中目录。每条都写清依赖、前置条件与安装命令,装完就能用。</p>
|
||||||
${
|
${
|
||||||
latest
|
sample
|
||||||
? `<div class="cta">
|
? `<p class="cta-label">安装示例</p>
|
||||||
<code class="cta-cmd">${escapeHtml(latest.install.pi)}</code>
|
<div class="cta">
|
||||||
<button class="copy primary" data-copy="${escapeHtml(latest.install.pi)}">复制命令</button>
|
<code class="cta-cmd">${escapeHtml(sample.install.pi)}</code>
|
||||||
</div>
|
<button class="copy primary" data-copy="${escapeHtml(sample.install.pi)}">复制命令</button>
|
||||||
<p class="cta-hint">先从 <a href="skills/${escapeHtml(latest.name)}.html">${escapeHtml(latest.name)}</a> 试起</p>`
|
<a class="cta-more" href="skills/${escapeHtml(sample.name)}.html">看它怎么用 →</a>
|
||||||
|
</div>`
|
||||||
: ''
|
: ''
|
||||||
}
|
}
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<span class="stat">${kinds} 个条目</span>
|
<span class="stat">${entries.length} 个条目</span>
|
||||||
<span class="legend">
|
<span class="legend">
|
||||||
<span class="legend-item core"><span class="dot"></span>底座</span>
|
<span class="legend-item core"><span class="dot"></span>底座</span>
|
||||||
<span class="legend-item tool"><span class="dot"></span>工具</span>
|
<span class="legend-item tool"><span class="dot"></span>工具</span>
|
||||||
@ -458,11 +467,11 @@ function indexPage(entries, siteUrl, fontsCss) {
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<input id="search" type="search" placeholder="搜索技能、命令或关键词" autocomplete="off">
|
<input id="search" type="search" placeholder="搜索技能、命令或关键词…" aria-label="搜索技能" autocomplete="off">
|
||||||
<div class="segmented" id="layers">
|
<div class="segmented" id="layers" role="group" aria-label="按层筛选">
|
||||||
${layers
|
${layers
|
||||||
.filter(layer => entries.some(entry => entry.layer === layer))
|
.filter(layer => entries.some(entry => entry.layer === layer))
|
||||||
.map(layer => `<button class="seg" data-layer-filter="${layer}">${LAYER_LABEL[layer]}</button>`)
|
.map(layer => `<button class="seg" data-layer-filter="${layer}" aria-pressed="false">${LAYER_LABEL[layer]}</button>`)
|
||||||
.join('')}
|
.join('')}
|
||||||
</div>
|
</div>
|
||||||
<span class="count" id="count">${entries.length}</span>
|
<span class="count" id="count">${entries.length}</span>
|
||||||
@ -473,7 +482,7 @@ ${sections}
|
|||||||
</main>
|
</main>
|
||||||
<p class="empty muted" id="empty" hidden>没有匹配的技能。</p>`;
|
<p class="empty muted" id="empty" hidden>没有匹配的技能。</p>`;
|
||||||
return pageShell({
|
return pageShell({
|
||||||
title: 'Pi 能力目录',
|
title: BRAND.name,
|
||||||
description: 'Pi 能力目录:技能与扩展,写清依赖与前置条件,一条命令装好就能用。',
|
description: 'Pi 能力目录:技能与扩展,写清依赖与前置条件,一条命令装好就能用。',
|
||||||
body,
|
body,
|
||||||
fontsCss,
|
fontsCss,
|
||||||
@ -481,6 +490,7 @@ ${sections}
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** 取(或首次下载)一套网络字体到 local 缓存;失败返回 { dir: null, error }。 */
|
/** 取(或首次下载)一套网络字体到 local 缓存;失败返回 { dir: null, error }。 */
|
||||||
export function ensureFont(repo, font) {
|
export function ensureFont(repo, font) {
|
||||||
// 字体缓存是机器级的(与构建哪个仓库无关),跟着 agent 目录走。
|
// 字体缓存是机器级的(与构建哪个仓库无关),跟着 agent 目录走。
|
||||||
@ -535,6 +545,17 @@ export function buildCatalog({ repo = repoRoot(), out, siteUrl = '' } = {}) {
|
|||||||
fs.mkdirSync(path.join(outDir, 'assets'), { recursive: true });
|
fs.mkdirSync(path.join(outDir, 'assets'), { recursive: true });
|
||||||
fs.cpSync(path.join(SKILL_DIR, 'assets', 'style.css'), path.join(outDir, 'assets', 'style.css'));
|
fs.cpSync(path.join(SKILL_DIR, 'assets', 'style.css'), path.join(outDir, 'assets', 'style.css'));
|
||||||
fs.cpSync(path.join(SKILL_DIR, 'assets', 'app.js'), path.join(outDir, 'assets', 'app.js'));
|
fs.cpSync(path.join(SKILL_DIR, 'assets', 'app.js'), path.join(outDir, 'assets', 'app.js'));
|
||||||
|
fs.cpSync(path.join(SKILL_DIR, 'assets', 'favicon.svg'), path.join(outDir, 'assets', 'favicon.svg'));
|
||||||
|
const siteRoot = (siteUrl || '').replace(/\/$/, '');
|
||||||
|
const urls = [`${siteRoot}/`, ...entries.map(entry => `${siteRoot}/skills/${entry.name}.html`)];
|
||||||
|
fs.writeFileSync(path.join(outDir, 'robots.txt'), `User-agent: *\nAllow: /\n${siteRoot ? `Sitemap: ${siteRoot}/sitemap.xml\n` : ''}`);
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(outDir, 'sitemap.xml'),
|
||||||
|
`<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls
|
||||||
|
.filter(url => url.startsWith('http'))
|
||||||
|
.map(url => ` <url><loc>${url}</loc></url>`)
|
||||||
|
.join('\n')}\n</urlset>\n`,
|
||||||
|
);
|
||||||
// 中文正文字体(霞鹜文楷 Screen):首次构建下载到 local 缓存,之后直接用;
|
// 中文正文字体(霞鹜文楷 Screen):首次构建下载到 local 缓存,之后直接用;
|
||||||
// 拿不到就退回系统字体并 warn(页面仍可用)。
|
// 拿不到就退回系统字体并 warn(页面仍可用)。
|
||||||
const fontLinks = [];
|
const fontLinks = [];
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user