Bundled scripts — 附帶的 script¶
Terminology rule (zh-TW pages)
技術名詞首次出現以「中文 (English original)」格式呈現,例:依賴注入
(dependency injection)。不自創翻譯——若無公認譯名直接保留英文
(如 embedding、tokenizer)。代碼、API 名、CLI flag、套件名、檔名一律不翻。
這個 repo
scripts/
目錄裡的每一個 script 也都被打包進擁有它的 skill 內(這樣透過
npx skills 出貨的 package 才能維持自包含 (self-contained))。
這對副本必須保持 byte-identical —— 詳見 Conventions。
Shell script 用 Bash 3.2 寫(這樣才能在沒裝 homebrew bash 的原生 macOS 上跑)。MkDocs build helper 是 Python,會在 project 由 uv 管理的 docs environment 裡執行。
Vendor 系統¶
add-vendor.sh¶
./scripts/add-vendor.sh owner/repo/path/to/skill
./scripts/add-vendor.sh https://github.com/owner/repo/tree/branch/path/to/skill
./scripts/add-vendor.sh --name custom --branch dev owner/repo/skills/some-skill
./scripts/add-vendor.sh --no-sync owner/repo/path/to/skill
透過 gh api 驗證 upstream 路徑存在、對
vendor.yaml
中既有條目去重 (deduplicate)、追加新條目、並觸發 sync-vendor.sh
(用 --no-sync 跳過)。
依賴項目: gh(已認證)跟 yq。
sync-vendor.sh¶
./scripts/sync-vendor.sh # 下載所有 vendored skill
./scripts/sync-vendor.sh --check # dry-run:報告哪些條目有 upstream 新 commit
迭代 vendor.yaml,透過 GitHub trees API 下載每個 skill,
成功時更新 last_sync.{date,commit}。--check 印出會改變什麼但不寫入。
Project memory¶
這些隨
project-knowledge-harness
出貨;canonical 副本在
skills/local/project-knowledge-harness/scripts/。
todo-kanban.sh¶
./scripts/todo-kanban.sh # 預設:TODO.md,Markdown 看板
./scripts/todo-kanban.sh path/to/TODO.md # 顯式指定檔案
./scripts/todo-kanban.sh --validate-only # 只回 exit code,不渲染
./scripts/todo-kanban.sh --json # 機器可讀的 lane 摘要
驗證 TODO format 並渲染看板樣式 (kanban-style) 的板子
到 stdout。任何不是頂層 - [ ] / - ✅ 條目的東西都會被忽略,
所以你可以在 section heading 底下灑點散文。
Exit code:0 有效;1 驗證失敗(行號印到 stderr);2 用法錯誤。
add-todo.sh¶
./scripts/add-todo.sh \
--priority P3 \
--effort M \
--title "Add docs versioning" \
--description "Use mike for versioned docs"
./scripts/add-todo.sh \
--priority "P?" \
--effort "?" \
--title "Try Rspress for docs" \
--description "Evaluate AI-native docs framework alternative"
./scripts/add-todo.sh \
--priority P2 --effort L \
--title "Migrate kanban to Python" \
--description "Bash 3.2 compat is getting expensive" \
--backlog
把符合 canonical 格式的條目插入到對應的 ## P* lane。
帶 --backlog 時也會從 skill template 產生 backlog/<slug>.md,
並在新行尾追加 → [research](backlog/<slug>.md)。
寫入後重新跑 validator。如果驗證失敗,原本的 TODO.md 會被還原。
Flag:
--priority {P1|P2|P3|P?}—— 必要。--effort {S|M|L|XL|?}—— 必要。?只在P?時有效。--title TEXT—— 必要。不能含*。--description TEXT—— 必要。em-dash 後是自由形式。--backlog—— 同時建立 backlog 研究文件。--file PATH—— TODO 檔案 (預設TODO.md)。--dry-run—— 把改寫後的檔案印到 stdout,不修改原檔。
promote-todo.sh¶
./scripts/promote-todo.sh \
--title "<substring of the item's title>" \
--summary "<one-line shipped summary>"
原子性地把 active 條目從其 lane 搬到 ## Done,使用日期化的
Done 語法,並重新驗證。如果 substring 匹配 0 個或多於一個
active 條目就拒絕執行 —— 把 substring 寫精準一點。
Flag:
--title SUBSTRING—— 必要。標題的 case-sensitive substring。--summary TEXT—— 必要。--file PATH—— TODO 檔案 (預設TODO.md)。--date YYYY-MM-DD—— 覆寫完成日期 (預設:今天,UTC)。--dry-run—— 印到 stdout,不修改檔案。--validator PATH—— 覆寫 validator 路徑 (預設:siblingtodo-kanban.sh)。
sweep-inbox.sh¶
./scripts/sweep-inbox.sh # backlog/inbox.md 的互動式分流
./scripts/sweep-inbox.sh --dry-run # 預覽不修改 inbox 或 TODO
./scripts/sweep-inbox.sh --batch # 非互動:跳過需要 prompt 的行
逐行讀
backlog/inbox.md。
對每一行非空、非註解的行,prompt 詢問 priority / effort / 正式
title / description(盡量提供預設),呼叫 add-todo.sh,並在條目
被 commit 後從 inbox 移除該行。
--batch 是設計給 agent 工作流程:當行能推斷出 priority: /
effort: / title: / description: 就自動形式化;模糊的留在 inbox
等下一次互動式 sweep。
Inbox 行慣例(全部可選;零散行也接受):
# 註解跟空行被忽略。
- maybe add docs versioning with mike
- priority=P3 effort=M title="Add docs versioning" desc="Use mike for versioned docs"
- the find-skills bootstrap UX is rough
第一種需要互動 prompt。第二種完全可解析,在 --batch 模式有效。
init.sh¶
只住在 skill 內(沒有鏡射到頂層 scripts/):
skills/local/project-knowledge-harness/scripts/init.sh。
skills/local/project-knowledge-harness/scripts/init.sh \
--target /path/to/project \
--project-name "My Project" \
--deployment chezmoi # 或 npm | pip | docker | none
對任何目標 repo 一次設置 TODO.md + backlog/ + pitfalls/ +
agent 指引片段 + README 片段。Idempotent。完整 flag 列表見
project-knowledge-harness。
Documentation 站點¶
這兩支跟著
mkdocs-site-bootstrap 出貨,沒有鏡射到
repo 範圍的 scripts/:build helper 會被複製進每個 scaffold project,
migration 則從已安裝的 skill 執行。
build-docs-site.py¶
uv run python scripts/build-docs-site.py
uv run python scripts/build-docs-site.py --dry-run
uv run python scripts/build-docs-site.py --site-dir public --keep-temp
Scaffold docs 站的 canonical strict production build。單語站跑一個 pass;
保留 llmstxt 的多語站把預設語言輸出與完整 locale HTML 分開 build,驗證並合併
artifact,兩個 pass 都成功後才替換目標 site 目錄。Root llms.txt、
llms-full.txt 與 raw .md sidecar 只包含預設語言。
Flags:--target-dir DIR、--config-file FILE、--site-dir DIR、
--dry-run、--keep-temp。Stdout 是 JSON;MkDocs log 與 diagnostics 走
stderr。Exit:0 成功、2 input 無效/缺失、3 MkDocs 失敗、4 輸出
驗證失敗。沒有 non-strict 模式。直接 mkdocs build --strict 仍是 HTML-only
preview,因為 scaffold config 預設停用 llmstxt。
migrate-i18n-llmstxt.sh¶
bash .agents/skills/mkdocs-site-bootstrap/scripts/migrate-i18n-llmstxt.sh \
--target-dir . --json
bash .agents/skills/mkdocs-site-bootstrap/scripts/migrate-i18n-llmstxt.sh \
--target-dir . --apply --dry-run --json
bash .agents/skills/mkdocs-site-bootstrap/scripts/migrate-i18n-llmstxt.sh \
--target-dir . --apply --verify --json
預設只 audit,只有 --apply 才寫入。它只 patch 可辨識的舊 scaffold 形狀,
只安裝/更新帶 managed marker 的 build helper,並把自訂 config、CI、
Makefile 形狀留在 manual_actions[]。候選檔案會先 staged 並驗證,再進行
替換;migration 可 idempotent 重跑。更新 skill 只會下載工具,不會自動執行。
Flags:--target-dir DIR、--apply、--dry-run、--verify、--json。
重要 exit:0 安全/已遷移、10 audit/dry-run 找到受影響的 legacy
config、11 仍有人工工作、12 strict verification 失敗。完整契約見 canonical
migration guide。
Skill authoring¶
跟著 skill-author 一起出貨;canonical
位於
skills/local/skill-author/scripts/。
沒有鏡射到頂層 scripts/,因為這是 skill author 用的工具,不是 repo
範圍的 make target。
new-skill.sh¶
bash skills/local/skill-author/scripts/new-skill.sh <skill-name>
bash skills/local/skill-author/scripts/new-skill.sh --project my-skill
bash skills/local/skill-author/scripts/new-skill.sh --global my-skill
bash skills/local/skill-author/scripts/new-skill.sh --local --vendor cherry-picked
bash skills/local/skill-author/scripts/new-skill.sh --dry-run my-skill
從 template scaffold 出 canonical 的 skill 目錄(SKILL.md +
references/ + scripts/ + assets/),並為 non-universal agents 加上
相對 (relative) 的 discovery symlinks。Script 從 CWD 往上走自動挑
placement scope;顯式 flag 可覆寫。
Placement scopes(完整表格見 creating local skills):
- LOCAL —— 往上找到 publishing-repo anchor(
vendor.yaml/skills/local//skills/.claude-plugin/)。Canonical 放在<repo>/skills/local/<name>/(搭--vendor則放skills/vendor/); symlinks 給.agents/skills/跟.claude/skills/。 - PROJECT —— 往上找到
.git。Canonical 放在<repo>/.agents/skills/<name>/;symlink 給.claude/skills/<name>(加上 repo root 已存在的其他 non-universal agent dir)。 - GLOBAL —— 找不到 anchor 或顯式
--global。Canonical 放在~/.agents/skills/<name>/;symlinks 給~/.claude/skills/<name>跟$HOME下已存在的其他 non-universal agent dir。
Symlink fan-out 遵循 npx skills add 的紀律:「claude-code 永遠加;其他
agent 只在它的 config root 已存在於 base dir 時才加」——絕不為使用者
其實沒在用的 agent 建立新的 .windsurf/ 之類目錄。每個 symlink
建立後會用 test -e <link>/SKILL.md 驗證;dangling link 直接 exit 4。
Flags:
--local/--project/--global—— 強制 scope(互斥)。--vendor—— 只在 LOCAL 有效;改用skills/vendor/<name>/。--root DIR—— 覆寫 walk-up 起點。--no-symlinks—— 跳過 agent dir fan-out。--dry-run—— 印出所有動作但不寫檔。--force—— 覆寫 canonical dir 並取代已存在的 symlinks。
Output:stdout 單一 JSON 物件
({skill, mode, canonical, symlinks[], next_steps[]});prose 走
stderr。
Exit codes:0 ok;1 參數錯誤;2 canonical dir 已存在(用
--force);3 scope 前提沒過(例如 --project 卻不在 git repo
裡);4 寫完 symlink 驗證失敗(就是
symlink-target-relative 那個坑)。
lint-skill.sh¶
bash skills/local/skill-author/scripts/lint-skill.sh skills/local/<name>
bash skills/local/skill-author/scripts/lint-skill.sh --strict skills/local/<name>
bash skills/local/skill-author/scripts/lint-skill.sh --json skills/local/<name>
檢查一個 skill 目錄的 frontmatter + 長度、script hygiene
(shebang / +x / --help handler)、reference 可達性。完整 checklist
見 skill-author。
lint-frontmatter.sh¶
make lint-frontmatter # 掃過整個 skills/
./scripts/lint-frontmatter.sh skills/local/<name>/SKILL.md
./scripts/lint-frontmatter.sh --parser node skills # 跟 npx skills 用同一顆 parser
把指定路徑底下每個 SKILL.md 的 frontmatter 真的丟給 YAML parser 解析,
並確認 root 是 mapping、name 與 description 都是字串。單一 skill 的
情況 lint-skill.sh 會直接呼叫它。
之所以需要這支:frontmatter 解析失敗時各家 harness 是默默跳過那個
skill——npx skills add 只印一行 ⚠ Skipped … YAML parse error,exit code
仍然是 0。最常見的原因是沒加引號的 description: 裡出現 ": ";沒加引號
的值裡出現 # 更陰險,因為它解析得過,但 description 會被當成註解從那裡
截斷(所以只報 warning,不是 error)。詳見
pitfalls。
Parser 會自動偵測:yq → PyYAML → js 的 yaml 套件(npx skills 自己用
的那顆,可用 --parser node 強制指定)。三個都沒有時會退化成 pattern
heuristic,並在輸出裡講明。
Exit codes:0 全過;1 至少一個檔案失敗;2 參數錯誤、路徑不存在,或
指定的 parser 不可用。
git-hooks/pre-push¶
make install-hooks # symlink 到 .git/hooks/pre-push
git push --no-verify # 單次略過
rm .git/hooks/pre-push # 移除
跑 make validate(frontmatter + marketplace.json + TODO.md 格式),
失敗就中止 push 並印出輸出尾巴。跟
.github/workflows/validate.yml
是同三道關卡(CI 在 push 與 PR 時跑);hook 只是把訊號往前挪——畢竟壞掉的
SKILL.md 在安裝當下是看不見的。