fix(skills): 修复 14 个 pointer 条目安装失败 + 7 个合集声明 children (#81)

## 背景 / Background

市场里 25 个 pointer 条目中有 **14 个点安装必然失败**,客户端返回 502「源仓库中未找到 SKILL.md(pointer
指向有误)」。

根因是 `entry.json` 的 `source` 指错:客户端按 `source.path` 定位内容(缺省则取仓库根),而这些条目的
`path` 缺失或 URL 指向了 HTML 页面,`contentDir/SKILL.md` 自然不存在。

Of the 25 pointer entries, **14 always failed to install** with a 502.
The `source` pointers were wrong: `path` was missing (so the client
looked at the repo root) or `repoUrl` pointed at an HTML page instead of
the content.

## 改动 / Changes

### 1. 补 `source.path`(5 个)

| 条目 | path | 上游 SKILL.md 实际位置 |
|---|---|---|
| `impeccable` | `plugin/skills/impeccable` | 根目录没有;`plugin/` 与
`.claude/` 两份内容逐字节一致,取中立的分发目录 |
| `ai-news-radar` | `skills/ai-news-radar` | 仓库另有 `skills/radar`,取与条目 id
对应的 |
| `taste-skill` | `skills/taste-skill` | 同名子目录 |
| `wechatpay-skills` | `wechatpay-payment-integration` | 仓库另有
`wechatpay-product-coupon` 未覆盖,见下方遗留项 |
| `luckin-my-coffee` | `my-coffee` | zip 内有一层顶层目录 |

### 2. 修正 web 类条目的源地址(2 个)

`amap-jsapi-skill` / `dingtalk-api` 原先指向 ClawHub 的**网页**(`content-type:
text/html`),客户端只在 markdown 时才写成 `SKILL.md`,HTML 会落成 `index.html`,校验必失败。

- `amap-jsapi-skill` → 改用 ClawHub 文件 API(返回 `text/markdown`)。该技能在
ClawHub 的发布包 `version.files` 只有一个 `SKILL.md`,单文件抓取正是对的形态。
- `dingtalk-api` → ClawHub 包有 38 个文件(`scripts/*.ts` 等),单文件抓不全,改指内容完整的
GitHub 上游 `ogenes/dingtalk-api` 并锁 ref。

### 3. 合集条目声明 `children`(7 个,147 个子技能)

这 7 个的上游是「一个仓库装着 N 个平级技能」,没有单一 SKILL.md 可指,靠改 `path`
修不了。配合客户端新增的合集能力(desirecore 主仓库 PR),`entry.json`
现在可声明子技能清单,市场仍是一个条目,安装时由用户勾选装哪几个。

| 条目 | 子技能数 |
|---|---|
| `marketingskills` | 49 |
| `mattpocock-skills` | 35 |
| `larksuite-cli` | 27 |
| `baoyu-skills` | 21 |
| `wecom-cli` | 7 |
| `khazix-skills` | 5 |
| `netease-skills` | 3 |

新增 `scripts/gen-collection-children.py`:按 `entry.json` 锁定的 ref
克隆上游、扫描子技能、读 frontmatter 生成 `children`。约定「仓库有顶层 `skills/` 就只扫它」——否则会收录
`larksuite/cli` 的 linter 测试夹具
`internal/qualitygate/skillscan/testdata/skills/lark-demo`。

### 4. `netease-skills` 分支修正

`repoBranch` 写的是 `main`,上游默认分支是 `master`,此前 clone 必然失败(`Could not find
main`)。

### 5. 版本号

`manifest.json` `1.2.24` → `1.2.25`。

## 验证 / Verification

- `uv run scripts/i18n/validate-i18n.py` — OK
- `uv run scripts/i18n/validate-i18n.py --online` — OK
- **真实运行的 agent-service 上逐个安装**(独立 home + standalone 服务,非模拟):18 个非合集
pointer 条目 **18/18 成功**并完整落盘;7 个合集条目 **7/7 成功**,并验证了部分安装、追加、取消勾选卸载、装到
Agent 私有目录。

## 遗留项 / Known gaps

- `wechatpay-skills` 只覆盖了 `wechatpay-payment-integration`,同仓库的
`wechatpay-product-coupon` 未上架。条目名是复数,后续可拆成两条或改成合集。
- `children[].i18n` 目前只有 `shortDesc`(取自上游
description),**没有中文名**——子技能名沿用上游 id(如 `lark-approval`),以保证与上游文档、Agent
加载路径一致。宝玉 / Matt Pocock / Marketing 三个合集的描述本身就是英文。如需中文化,可接
`i18n-translate.yml` 覆盖 `children` 字段。
- 在线校验目前只查 URL 可达性,**查不出 `path` 指向的目录里有没有 SKILL.md**——这 14
个坏条目当初就是这么一路绿灯合进主干的。建议后续给 `--online` 加这条断言。

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: xieyuanxiang <xieyuanxiang123@gmail.com>
This commit is contained in:
2026-08-09 16:25:20 +08:00
committed by GitHub
parent b1f0719d40
commit 27589d013d
16 changed files with 2073 additions and 16 deletions

View File

@@ -31,5 +31,427 @@
"kind": "git",
"repoUrl": "https://github.com/mattpocock/skills.git",
"repoBranch": "main"
}
},
"children": [
{
"id": "ask-matt",
"path": "skills/engineering/ask-matt",
"i18n": {
"zh-CN": {
"shortDesc": "Ask which skill or flow fits your situation."
},
"en-US": {
"shortDesc": "Ask which skill or flow fits your situation."
}
}
},
{
"id": "code-review",
"path": "skills/engineering/code-review",
"i18n": {
"zh-CN": {
"shortDesc": "Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding stand…"
},
"en-US": {
"shortDesc": "Review the changes since a fixed point (commit, branch, tag, or merge-base) along two axes — Standards (does the code follow this repo's documented coding stand…"
}
}
},
{
"id": "codebase-design",
"path": "skills/engineering/codebase-design",
"i18n": {
"zh-CN": {
"shortDesc": "Shared vocabulary for designing deep modules."
},
"en-US": {
"shortDesc": "Shared vocabulary for designing deep modules."
}
}
},
{
"id": "diagnosing-bugs",
"path": "skills/engineering/diagnosing-bugs",
"i18n": {
"zh-CN": {
"shortDesc": "Diagnosis loop for hard bugs and performance regressions."
},
"en-US": {
"shortDesc": "Diagnosis loop for hard bugs and performance regressions."
}
}
},
{
"id": "domain-modeling",
"path": "skills/engineering/domain-modeling",
"i18n": {
"zh-CN": {
"shortDesc": "Build and sharpen a project's domain model."
},
"en-US": {
"shortDesc": "Build and sharpen a project's domain model."
}
}
},
{
"id": "grill-with-docs",
"path": "skills/engineering/grill-with-docs",
"i18n": {
"zh-CN": {
"shortDesc": "A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go."
},
"en-US": {
"shortDesc": "A relentless interview to sharpen a plan or design, which also creates docs (ADR's and glossary) as we go."
}
}
},
{
"id": "implement",
"path": "skills/engineering/implement",
"i18n": {
"zh-CN": {
"shortDesc": "Implement a piece of work based on a spec or set of tickets."
},
"en-US": {
"shortDesc": "Implement a piece of work based on a spec or set of tickets."
}
}
},
{
"id": "improve-codebase-architecture",
"path": "skills/engineering/improve-codebase-architecture",
"i18n": {
"zh-CN": {
"shortDesc": "Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick."
},
"en-US": {
"shortDesc": "Scan a codebase for deepening opportunities, present them as a visual HTML report, then grill through whichever one you pick."
}
}
},
{
"id": "prototype",
"path": "skills/engineering/prototype",
"i18n": {
"zh-CN": {
"shortDesc": "Build a throwaway prototype to answer a design question."
},
"en-US": {
"shortDesc": "Build a throwaway prototype to answer a design question."
}
}
},
{
"id": "research",
"path": "skills/engineering/research",
"i18n": {
"zh-CN": {
"shortDesc": "Investigate a question against high-trust primary sources and capture the findings as a Markdown file in the repo."
},
"en-US": {
"shortDesc": "Investigate a question against high-trust primary sources and capture the findings as a Markdown file in the repo."
}
}
},
{
"id": "resolving-merge-conflicts",
"path": "skills/engineering/resolving-merge-conflicts",
"i18n": {
"zh-CN": {
"shortDesc": "Use when you need to resolve an in-progress git merge/rebase conflict."
},
"en-US": {
"shortDesc": "Use when you need to resolve an in-progress git merge/rebase conflict."
}
}
},
{
"id": "setup-matt-pocock-skills",
"path": "skills/engineering/setup-matt-pocock-skills",
"i18n": {
"zh-CN": {
"shortDesc": "Configure this repo for the engineering skills — set up its issue tracker, triage label vocabulary, and domain doc layout."
},
"en-US": {
"shortDesc": "Configure this repo for the engineering skills — set up its issue tracker, triage label vocabulary, and domain doc layout."
}
}
},
{
"id": "tdd",
"path": "skills/engineering/tdd",
"i18n": {
"zh-CN": {
"shortDesc": "Test-driven development."
},
"en-US": {
"shortDesc": "Test-driven development."
}
}
},
{
"id": "to-spec",
"path": "skills/engineering/to-spec",
"i18n": {
"zh-CN": {
"shortDesc": "Turn the current conversation into a spec and publish it to the project issue tracker — no interview, just synthesis of what you've already discussed."
},
"en-US": {
"shortDesc": "Turn the current conversation into a spec and publish it to the project issue tracker — no interview, just synthesis of what you've already discussed."
}
}
},
{
"id": "to-tickets",
"path": "skills/engineering/to-tickets",
"i18n": {
"zh-CN": {
"shortDesc": "Break a plan, spec, or the current conversation into a set of tracer-bullet tickets, each declaring its blocking edges, published to the configured tracker — ed…"
},
"en-US": {
"shortDesc": "Break a plan, spec, or the current conversation into a set of tracer-bullet tickets, each declaring its blocking edges, published to the configured tracker — ed…"
}
}
},
{
"id": "triage",
"path": "skills/engineering/triage",
"i18n": {
"zh-CN": {
"shortDesc": "Move issues and external PRs through a state machine of triage roles — categorise, verify, grill if needed, and write agent-ready briefs."
},
"en-US": {
"shortDesc": "Move issues and external PRs through a state machine of triage roles — categorise, verify, grill if needed, and write agent-ready briefs."
}
}
},
{
"id": "wayfinder",
"path": "skills/engineering/wayfinder",
"i18n": {
"zh-CN": {
"shortDesc": "Plan a huge chunk of work — more than one agent session can hold — as a shared map of decision tickets on your issue tracker, and resolve them one at a time unt…"
},
"en-US": {
"shortDesc": "Plan a huge chunk of work — more than one agent session can hold — as a shared map of decision tickets on your issue tracker, and resolve them one at a time unt…"
}
}
},
{
"id": "wizard",
"path": "skills/engineering/wizard",
"i18n": {
"zh-CN": {
"shortDesc": "Generate an interactive bash wizard that walks a human through steps only they can perform."
},
"en-US": {
"shortDesc": "Generate an interactive bash wizard that walks a human through steps only they can perform."
}
}
},
{
"id": "claude-handoff",
"path": "skills/in-progress/claude-handoff",
"i18n": {
"zh-CN": {
"shortDesc": "Hand the current conversation off to a fresh background agent that picks up the work immediately."
},
"en-US": {
"shortDesc": "Hand the current conversation off to a fresh background agent that picks up the work immediately."
}
}
},
{
"id": "loop-me",
"path": "skills/in-progress/loop-me",
"i18n": {
"zh-CN": {
"shortDesc": "Grill me about specs for the workflows I want to build, within this workspace."
},
"en-US": {
"shortDesc": "Grill me about specs for the workflows I want to build, within this workspace."
}
}
},
{
"id": "setup-ts-deep-modules",
"path": "skills/in-progress/setup-ts-deep-modules",
"i18n": {
"zh-CN": {
"shortDesc": "Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point fi…"
},
"en-US": {
"shortDesc": "Wire dependency-cruiser into a TypeScript repo so each package is a deep module — implementation hidden in subfolders, reachable only through its entry-point fi…"
}
}
},
{
"id": "writing-beats",
"path": "skills/in-progress/writing-beats",
"i18n": {
"zh-CN": {
"shortDesc": "Writing, exploit — assemble raw material into a journey of beats, grounding each term before a beat leans on it."
},
"en-US": {
"shortDesc": "Writing, exploit — assemble raw material into a journey of beats, grounding each term before a beat leans on it."
}
}
},
{
"id": "writing-fragments",
"path": "skills/in-progress/writing-fragments",
"i18n": {
"zh-CN": {
"shortDesc": "Writing, explore — mine raw fragments, no structure yet."
},
"en-US": {
"shortDesc": "Writing, explore — mine raw fragments, no structure yet."
}
}
},
{
"id": "writing-shape",
"path": "skills/in-progress/writing-shape",
"i18n": {
"zh-CN": {
"shortDesc": "Writing, exploit — shape raw material into an article, paragraph by paragraph."
},
"en-US": {
"shortDesc": "Writing, exploit — shape raw material into an article, paragraph by paragraph."
}
}
},
{
"id": "git-guardrails-claude-code",
"path": "skills/misc/git-guardrails-claude-code",
"i18n": {
"zh-CN": {
"shortDesc": "Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute."
},
"en-US": {
"shortDesc": "Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute."
}
}
},
{
"id": "migrate-to-shoehorn",
"path": "skills/misc/migrate-to-shoehorn",
"i18n": {
"zh-CN": {
"shortDesc": "Migrate test files from `as` type assertions to @total-typescript/shoehorn."
},
"en-US": {
"shortDesc": "Migrate test files from `as` type assertions to @total-typescript/shoehorn."
}
}
},
{
"id": "scaffold-exercises",
"path": "skills/misc/scaffold-exercises",
"i18n": {
"zh-CN": {
"shortDesc": "Create exercise directory structures with sections, problems, solutions, and explainers that pass linting."
},
"en-US": {
"shortDesc": "Create exercise directory structures with sections, problems, solutions, and explainers that pass linting."
}
}
},
{
"id": "setup-pre-commit",
"path": "skills/misc/setup-pre-commit",
"i18n": {
"zh-CN": {
"shortDesc": "Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo."
},
"en-US": {
"shortDesc": "Set up Husky pre-commit hooks with lint-staged (Prettier), type checking, and tests in the current repo."
}
}
},
{
"id": "grill-me",
"path": "skills/productivity/grill-me",
"i18n": {
"zh-CN": {
"shortDesc": "A relentless interview to sharpen a plan or design."
},
"en-US": {
"shortDesc": "A relentless interview to sharpen a plan or design."
}
}
},
{
"id": "grilling",
"path": "skills/productivity/grilling",
"i18n": {
"zh-CN": {
"shortDesc": "Grill the user relentlessly about a plan, decision, or idea."
},
"en-US": {
"shortDesc": "Grill the user relentlessly about a plan, decision, or idea."
}
}
},
{
"id": "handoff",
"path": "skills/productivity/handoff",
"i18n": {
"zh-CN": {
"shortDesc": "Compact the current conversation into a handoff document for another agent to pick up."
},
"en-US": {
"shortDesc": "Compact the current conversation into a handoff document for another agent to pick up."
}
}
},
{
"id": "teach",
"path": "skills/productivity/teach",
"i18n": {
"zh-CN": {
"shortDesc": "Teach the user a new skill or concept, within this workspace."
},
"en-US": {
"shortDesc": "Teach the user a new skill or concept, within this workspace."
}
}
},
{
"id": "to-questionnaire",
"path": "skills/productivity/to-questionnaire",
"i18n": {
"zh-CN": {
"shortDesc": "Turn a decision you can't fully answer into a questionnaire for someone else to fill in."
},
"en-US": {
"shortDesc": "Turn a decision you can't fully answer into a questionnaire for someone else to fill in."
}
}
},
{
"id": "wait-what",
"path": "skills/productivity/wait-what",
"i18n": {
"zh-CN": {
"shortDesc": "Stop."
},
"en-US": {
"shortDesc": "Stop."
}
}
},
{
"id": "writing-for-agents",
"path": "skills/productivity/writing-for-agents",
"i18n": {
"zh-CN": {
"shortDesc": "Writing documents for agents."
},
"en-US": {
"shortDesc": "Writing documents for agents."
}
}
}
]
}