@heihei0299/matt-skills 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/.agents/skills/ci-guard/SKILL.md +6 -2
  2. package/.agents/skills/commit-check/scripts/scan-sensitive.sh +14 -6
  3. package/.agents/skills/diagnose-fix/SKILL.md +16 -15
  4. package/.agents/skills/diagnose-fix/references/anti-patterns.md +5 -4
  5. package/.agents/skills/grill-to-spec/SKILL.md +4 -0
  6. package/.agents/skills/grill-to-spec/references/rules.md +19 -24
  7. package/.agents/skills/scaffold-functional-test/SKILL.md +9 -6
  8. package/.agents/skills/scaffold-functional-test/references/schema.md +56 -11
  9. package/.agents/skills/tdd-implement/SKILL.md +14 -9
  10. package/.agents/skills/tdd-implement/references/contract.md +21 -0
  11. package/.agents/skills/tdd-implement/references/deliver.md +33 -0
  12. package/.agents/skills/tdd-implement/references/orchestration.md +9 -6
  13. package/.agents/skills/tdd-implement/references/red-green.md +25 -0
  14. package/.agents/skills/tdd-implement/references/stages.md +11 -9
  15. package/.agents/skills/tdd-implement/references/verify.md +24 -0
  16. package/.agents/skills/tdd-implement/scripts/scan-sensitive.sh +37 -0
  17. package/README.md +48 -27
  18. package/bin/cli.js +85 -24
  19. package/bin/skill-boundaries.js +61 -0
  20. package/config/proprietary.json +28 -9
  21. package/package.json +1 -1
  22. package/scripts/sync-upstream.js +4 -8
  23. package/template/.agents/skills/diagnose-fix/SKILL.md +16 -15
  24. package/template/.agents/skills/diagnose-fix/references/anti-patterns.md +5 -4
  25. package/template/.agents/skills/grill-to-spec/SKILL.md +4 -0
  26. package/template/.agents/skills/grill-to-spec/references/rules.md +19 -24
  27. package/template/.agents/skills/scaffold-functional-test/SKILL.md +9 -6
  28. package/template/.agents/skills/scaffold-functional-test/references/schema.md +56 -11
  29. package/template/.agents/skills/tdd-implement/SKILL.md +14 -9
  30. package/template/.agents/skills/tdd-implement/references/contract.md +21 -0
  31. package/template/.agents/skills/tdd-implement/references/deliver.md +33 -0
  32. package/template/.agents/skills/tdd-implement/references/orchestration.md +9 -6
  33. package/template/.agents/skills/tdd-implement/references/red-green.md +25 -0
  34. package/template/.agents/skills/tdd-implement/references/stages.md +11 -9
  35. package/template/.agents/skills/tdd-implement/references/verify.md +24 -0
  36. package/template/.agents/skills/tdd-implement/scripts/scan-sensitive.sh +37 -0
  37. package/template/.opencode/CONTEXT.md +7 -7
  38. package/template/.opencode/docs/agents/skill-design.md +3 -3
  39. package/template/.opencode/skills/README.md +1 -1
  40. package/template/.pi/CONTEXT.md +7 -7
  41. package/template/.pi/docs/agents/skill-design.md +3 -3
  42. package/template/.pi/skills/README.md +1 -1
  43. package/template/AGENTS.md +49 -30
  44. package/template/.agents/skills/ci-guard/SKILL.md +0 -50
  45. package/template/.agents/skills/ci-guard/agents/openai.yaml +0 -5
  46. package/template/.agents/skills/commit-check/SKILL.md +0 -95
  47. package/template/.agents/skills/commit-check/agents/openai.yaml +0 -5
  48. package/template/.agents/skills/commit-check/scripts/scan-sensitive.sh +0 -29
  49. package/template/.opencode/commands/commit-check.md +0 -9
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env bash
2
+ # Deterministic staged-diff secret scan for the tdd-implement deliver gate.
3
+ # Only ADDED lines are inspected: removing a leaked secret must never be blocked.
4
+ # Match contents are never echoed, so detected credentials do not leak into agent/log output.
5
+ # FAIL: structured assignments and private-key blocks.
6
+ # WARN: bare keywords that may legitimately appear in documentation.
7
+ set -euo pipefail
8
+
9
+ if [[ $# -gt 1 || ( $# -eq 1 && "$1" != "--staged-only" ) ]]; then
10
+ echo "usage: $0 [--staged-only]" >&2
11
+ exit 2
12
+ fi
13
+
14
+ fail_patterns='(api[_-]?key|secret|token|passwd|password)[[:space:]]*[=:][[:space:]]*[^[:space:]]{8,}|BEGIN (RSA|OPENSSH|EC|DSA) PRIVATE KEY'
15
+ warn_patterns='(api[_-]?key|secret|token|passwd|password|\.env)'
16
+
17
+ # Strip diff metadata and deletions. The scanner cares only about content that the
18
+ # commit would introduce, not secrets that the commit is removing.
19
+ added_lines=$(
20
+ git diff --cached --unified=0 --no-color \
21
+ | awk '/^\+\+\+ / { next } /^\+/ { print substr($0, 2) }'
22
+ )
23
+
24
+ fail=0
25
+
26
+ if grep -qiE "$fail_patterns" <<< "$added_lines"; then
27
+ echo "❌ Possible structured secret found in ADDED staged content — remove or redact it before committing." >&2
28
+ fail=1
29
+ else
30
+ echo "✅ No structured secrets in added staged content."
31
+ fi
32
+
33
+ if grep -qiE "$warn_patterns" <<< "$added_lines"; then
34
+ echo "⚠ Sensitive keyword found in ADDED staged content — inspect the staged diff manually." >&2
35
+ fi
36
+
37
+ exit "$fail"
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # matt-skills
2
2
 
3
- mattpocock/skills(`skills/engineering` + `skills/productivity`)的配置仓库:工作区内容镜像为 `template/` 模板快照,以 npm 包 `@heihei0299/matt-skills` 分发,目标仓库一条命令即完成初始化。
3
+ mattpocock/skills(`skills/engineering` + `skills/productivity`)的配置仓库:工作区维护完整 skill 集合,其中一部分 proprietary skill 只供本仓库使用;`template/` 只包含可分发内容,以 npm 包 `@heihei0299/matt-skills` 分发,目标仓库一条命令即完成初始化。
4
4
 
5
5
  ## 模板结构
6
6
 
@@ -8,7 +8,7 @@ mattpocock/skills(`skills/engineering` + `skills/productivity`)的配置仓
8
8
  template/
9
9
  ├── AGENTS.md 项目级全局配置(行为路由 + 分文件指针)
10
10
  ├── .agents/
11
- │ └── skills/ 33 个技能(上游 26 + 独有 6:ci-guard、tdd-implement、grill-to-spec、diagnose-fix、commit-check、scaffold-functional-test;另含 show-me)单一源;模板全量 33,默认安装编程相关 26(engineering 18 + 独有所需 1 + 核心独有 4,见 config/engineering.json 与 config/required.json),--all 展开全量
11
+ │ └── skills/ workspace 的完整 skill 单一源;template 只携带可分发 skill,默认安装 programming 范围,--all 展开全部可分发 skill
12
12
  ├── .pi/ pi-agent 项目配置
13
13
  │ ├── skills/ 空占位(项目自定义技能,含 .gitkeep + README.md)
14
14
  │ ├── prompts/ issue-audit 命令(prompt template)
@@ -17,39 +17,60 @@ template/
17
17
  └── .opencode/ opencode 项目配置
18
18
  ├── skills/ 空占位(项目自定义技能,含 .gitkeep + README.md)
19
19
  ├── agents/ issue-audit 子代理定义
20
- ├── commands/ issue-audit + 10 个显式触发技能命令(grill-to-spec/wayfinder/to-spec/to-tickets/triage/improve-codebase-architecture/teach/handoff/writing-for-agents/commit-check
20
+ ├── commands/ issue-audit + 可分发的显式触发技能命令(grill-to-spec/wayfinder/to-spec/to-tickets/triage/improve-codebase-architecture/teach/handoff/writing-for-agents)
21
21
  ├── docs/agents/ 5 个分文件(运行时纪律 / 技能设计 / issue tracker / triage labels / domain)
22
22
  ├── CONTEXT.md 术语表
23
23
  ├── package.json 插件依赖清单
24
24
  └── .gitignore
25
25
  ```
26
26
 
27
+ ## 独有 skill 分发边界
28
+
29
+ 本仓库维护 7 个独有(proprietary)skill:
30
+
31
+ ### 可分发的 5 个
32
+
33
+ - `tdd-implement`
34
+ - `diagnose-fix`
35
+ - `grill-to-spec`
36
+ - `scaffold-functional-test`
37
+ - `show-me`
38
+
39
+ 默认 programming 范围中的 4 个独有 skill 是 `tdd-implement`、`diagnose-fix`、`grill-to-spec`、`show-me`;`scaffold-functional-test` 可分发但默认可选。
40
+
41
+ ### 仓库内部的 2 个
42
+
43
+ - `ci-guard`
44
+ - `commit-check`
45
+
46
+ `ci-guard` 和 `commit-check` 只服务 matt-skills 仓库自身,不会通过 `list`、`install`、`init`、`sync`、`--all` 或 global install 分发到用户项目。workspace 保留完整集合,template 只包含可分发集合。
47
+
27
48
  ## 初始化
28
49
 
29
50
  在目标仓库根目录执行一条命令:
30
51
 
31
52
  ```sh
32
- npx @heihei0299/matt-skills init # 默认编程相关 26(engineering 18 + 独有所需 4 + 核心独有 4),--all 展开全量 33
33
- npx @heihei0299/matt-skills init --all # 安装全量 33(含 productivity)
53
+ npx @heihei0299/matt-skills init # 默认 programming 范围
54
+ npx @heihei0299/matt-skills init --all # 安装全部可分发 skill(含 productivity)
34
55
  ```
35
56
 
36
- `init` 默认只在目标没有 `AGENTS.md` 时初始化;已有项目默认跳过以保护定制,显式 `init --all` 会刷新模板并安装/覆盖全量 33 skill。模板全量 33,默认仅安装默认范围 26(engineering 18 + 独有所需 4 + 核心独有 4,见 config/engineering.json 与 config/required.json),无需二次拉取上游。
57
+ `init` 默认只在目标没有 `AGENTS.md` 时初始化;已有项目默认跳过以保护定制,显式 `init --all` 会刷新模板并安装/覆盖全部可分发 skill。模板已经包含可分发内容,无需二次拉取上游;repo-local skill 不会进入目标项目。
37
58
 
38
- 选项:`--dest <path>` 指定目标目录(默认当前目录);`--all` 包含非编程技能(productivity,默认编程 26:engineering 18 + 独有所需 4 + 核心独有 4);已有目标使用 `init --all` 刷新,普通 `init` 跳过。
59
+ 选项:`--dest <path>` 指定目标目录(默认当前目录);`--all` 包含全部可分发的非默认 skill(包括 productivity optional proprietary);已有目标使用 `init --all` 刷新,普通 `init` 跳过。
39
60
  **增量同步(已有项目)**:已有项目更新到最新模板与技能:
40
61
 
41
62
  ```sh
42
- npx @heihei0299/matt-skills sync # 默认安全增量:AGENTS.md 有定制则跳过,默认技能 26 rm+cp(不删多余)
43
- npx @heihei0299/matt-skills sync --all # 仅更新同名技能内容(存在则覆盖,不存在则新增)并更新 AGENTS.md(不跳过定制),不删多余
44
- npx @heihei0299/matt-skills sync --dry-run --json # 预演:只比对不写盘(默认范围,--all 全量可透传)
63
+ npx @heihei0299/matt-skills sync # 默认安全增量:同步默认 programming skill(不删多余)
64
+ npx @heihei0299/matt-skills sync --all # 同步全部可分发 skill(不删多余)
65
+ npx @heihei0299/matt-skills sync --dry-run --json # 预演:只比对不写盘(默认范围,--all 可透传)
45
66
  npx @heihei0299/matt-skills sync --dest <path> --upstream <url> --ref <ref> --json # 选项可组合
46
67
  ```
47
68
 
48
- `sync` 专为已有项目设计,两档语义:`--dry-run` 仅对比不写盘(默认范围 engineering + 独有所需,`--all` 展开全量同名集合,打印“上游 HEAD / 本地非独有 vs 上游 / 新增/更新/删除/一致”表,`--json` 可解析,有差异 `exit 1`);默认安全增量写盘(`AGENTS.md` 若含 `tdd-implement` 则跳过,`.agents/skills` 按默认范围 26 `rm+cp` 覆盖但不删多余,`template/.opencode/.pi` 增量 `add/update`,旧镜像 `.pi/skills` + `.opencode/skills` 中残留共享技能自动清理但保留项目自定义);`--all` 仅更新同名技能内容(存在则覆盖,不存在则新增)并更新 `AGENTS.md`(不跳过定制),不删多余。`--dest`、`--upstream`、`--ref`、`--json`、`--all`、`--dry-run` 可透传。
49
- 目标仓库会话即自动加载共享技能(`.agents/skills/` 单一源,默认编程 26,`--all` 全量 33)与项目级全局配置(行为路由表、分文件约定);项目自定义技能可按需放入 `.pi/skills/` 或 `.opencode/skills/`(按 harness 自动发现);`issue-audit` 以子代理 + 命令形式分发(`.opencode/agents/`、`.opencode/commands/`);10 个显式触发技能注册为 opencode 命令(`.opencode/commands/`,`/命令名` 触发)。
50
- **pi-agent 用户**:初始化命令完全相同。pi 从 `.agents/skills/` 自动发现全部共享技能,无需额外指向;`.pi/skills/` 仅用于项目自定义。首次在目标仓库交互启动时 pi 会询问项目信任,用 `/trust` 保存即可。
69
+ `sync` 专为已有项目设计,两档语义:写盘模式下默认同步默认 programming 范围,`--all` 同步全部可分发 skill;`--dry-run` 仅对比上游、不写盘,默认比较 engineering + required 的上游部分,`--all` 比较全量上游范围,打印“上游 HEAD / 本地非独有 vs 上游 / 新增/更新/删除/一致”表,`--json` 可解析,有差异 `exit 1`。上游 dry-run/check 不比较 proprietary,因为它们不属于上游;默认安全增量写盘不删多余,模板配置增量更新,旧镜像中的共享 skill 自动清理但保留项目自定义。repo-local skill 永远不新增、不覆盖、不删除,发现历史副本时只提示保留。`--dest`、`--upstream`、`--ref`、`--json`、`--all`、`--dry-run` 可透传。
70
+ 目标仓库会话即自动加载可分发共享技能(`.agents/skills/` 单一源)与项目级全局配置(行为路由表、分文件约定);项目自定义技能可按需放入 `.pi/skills/` 或 `.opencode/skills/`(按 harness 自动发现);`issue-audit` 以子代理 + 命令形式分发(`.opencode/agents/`、`.opencode/commands/`);可分发的显式触发技能注册为 opencode 命令(`.opencode/commands/`,`/命令名` 触发)。
71
+ **pi-agent 用户**:初始化命令完全相同。pi 从 `.agents/skills/` 自动发现全部可分发共享技能,无需额外指向;`.pi/skills/` 仅用于项目自定义。首次在目标仓库交互启动时 pi 会询问项目信任,用 `/trust` 保存即可。
51
72
 
52
- **手动方式(备选)**:无 npx 环境时,将 `template/` 整个文件夹复制到目标仓库根目录即可(已含全量技能):
73
+ **手动方式(备选)**:无 npx 环境时,将 `template/` 整个文件夹复制到目标仓库根目录即可(已含全部可分发 skill):
53
74
 
54
75
  ```sh
55
76
  cp -r template/. /path/to/target/
@@ -67,9 +88,9 @@ git clone --depth 1 https://github.com/mattpocock/skills.git /tmp/mattpocock-ski
67
88
 
68
89
  | 工作区 | 模板 |
69
90
  |--------|------|
70
- | `.agents/skills/`(全部 33 个:上游 26 + 独有 7:ci-guard、tdd-implement、grill-to-spec、diagnose-fix、commit-check、scaffold-functional-test、show-me) | `template/.agents/skills/`(全量快照,单一源) |
91
+ | `.agents/skills/`(workspace 完整 skill 集合:upstream + proprietary) | `template/.agents/skills/`(仅可分发 skill) |
71
92
  | `.agents/skills/` 的 harness 占位说明 | `template/.pi/skills/.gitkeep` + `README.md`、`template/.opencode/skills/.gitkeep` + `README.md`(空目录占位,供项目自定义) |
72
- │ │ ├── commands/ issue-audit + 10 个显式触发技能命令(grill-to-spec/wayfinder/to-spec/to-tickets/triage/improve-codebase-architecture/teach/handoff/writing-for-agents/commit-check
93
+ │ │ ├── commands/ issue-audit + 可分发的显式触发技能命令(grill-to-spec/wayfinder/to-spec/to-tickets/triage/improve-codebase-architecture/teach/handoff/writing-for-agents)
73
94
  | `.pi/prompts/issue-audit.md`(pi 命令:opencode 版适配,去 subagent frontmatter) | `template/.pi/prompts/issue-audit.md` |
74
95
  | `AGENTS.md` | `template/AGENTS.md`(引用映射为 `.opencode/` 路径) |
75
96
  | `CONTEXT.md` | `template/.opencode/CONTEXT.md` + `template/.pi/CONTEXT.md` |
@@ -78,7 +99,7 @@ git clone --depth 1 https://github.com/mattpocock/skills.git /tmp/mattpocock-ski
78
99
  共享技能统一在 `.agents/skills` 单一源,不再双份镜像到 `.opencode/skills` / `.pi/skills`。
79
100
  `test/template-sync.test.js` 守护同步(含路径映射),漏同步测试即红。
80
101
 
81
- 新增技能前先查上游 `mattpocock/skills` 是否已存在;仅上游没有的技能才作为独有技能落在本仓库(当前独有:ci-guard、tdd-implement、grill-to-spec、diagnose-fix、commit-check、scaffold-functional-test),上游技能通过 `scripts/sync-upstream.js` 同步到 `.agents/skills` 后随模板分发。
102
+ 新增技能前先查上游 `mattpocock/skills` 是否已存在;仅上游没有的技能才作为 proprietary skill 落在本仓库。Proprietary skill 再分为 distributable 和 repo-local:后者只服务本仓库,不进入 template 或任何用户安装路径。上游技能通过 `scripts/sync-upstream.js` 同步到 `.agents/skills` 后,只有可分发内容会进入模板。
82
103
 
83
104
  ## harness 支持
84
105
 
@@ -119,13 +140,13 @@ CODEX_E2E=1 npm run codex:smoke # 显式运行真实 smoke test
119
140
 
120
141
  - **全局**:`~/.pi/agent/skills/`、`~/.agents/skills/`(用户级技能,自动发现);配置在 `~/.pi/agent/settings.json`
121
142
  - **项目**:
122
- - `.agents/skills/` — 共享技能单一源(默认编程 26,`--all` 全量 32,自动发现)
143
+ - `.agents/skills/` — 可分发共享技能单一源(默认 programming,`--all` 全部可分发,自动发现)
123
144
  - `.pi/skills/` — 项目自定义技能(pi 标准结构,自动发现,仅放项目本地技能)
124
145
  - `.pi/prompts/` — pi 命令(prompt template)自动发现,如 `issue-audit.md` → `/issue-audit`
125
146
  - `.pi/settings.json` — 已简化为空对象(历史指向 `.opencode/skills` 已移除,共享技能走 `.agents/skills`)
126
147
  ### opencode
127
148
 
128
- - **项目**:`.agents/skills/`(共享技能单一源,默认编程 26,`--all` 全量 33)、`.opencode/skills/`(项目自定义技能)、`.opencode/agents/`(子代理)、`.opencode/commands/`(命令:issue-audit + 10 个显式触发技能,`/命令名` 触发)、`.opencode/docs/`(文档)
149
+ - **项目**:`.agents/skills/`(可分发共享技能单一源,默认 programming,`--all` 全部可分发)、`.opencode/skills/`(项目自定义技能)、`.opencode/agents/`(子代理)、`.opencode/commands/`(命令:issue-audit + 可分发显式触发技能,`/命令名` 触发)、`.opencode/docs/`(文档)
129
150
 
130
151
  同一份技能(Agent Skills 标准)与 `AGENTS.md` 行为路由在两种 harness 下均可加载:pi 与 codex/claude 从 `.agents/skills/` 自动发现;opencode 按本模板约定同样优先读取 `.agents/skills/`(`.opencode/skills/` 仅用于项目自定义)。
131
152
 
@@ -134,23 +155,23 @@ CODEX_E2E=1 npm run codex:smoke # 显式运行真实 smoke test
134
155
  仓库内提供安装管理 CLI(`bin/cli.js`,依赖 `prompts`,见 `package.json`),同时作为 npm 包 `@heihei0299/matt-skills` 分发(`npx @heihei0299/matt-skills <command>`):
135
156
 
136
157
  ```sh
137
- node bin/cli.js init [--dest <dir>] [--all] # 初始化项目:template 全量 33,默认编程 26
158
+ node bin/cli.js init [--dest <dir>] [--all] # 初始化项目:默认 programming 或全部可分发 skill
138
159
  node bin/cli.js sync [--all] [--dry-run] [--dest <path>] [--upstream <url>] [--ref <ref>] [--json] # 同步已有项目到最新(默认编程,--all 仅同名 upsert + AGENTS.md)
139
160
  node bin/cli.js list [--json] [--all] # 列出技能(默认编程)
140
161
  node bin/cli.js install [选项] # 把技能复制到目标工具目录(交互式选择,默认编程)
141
162
  node bin/cli.js check [--json] [--all] [--upstream <url>] [--ref <ref>] # 只读检查上游技能是否最新(等价 sync --dry-run,默认范围)
142
163
  ```
143
164
 
144
- `init` 选项:`--dest <path>` 指定目标目录(默认当前目录);`--all` 包含非编程(productivity,默认编程 26:engineering 18 + 独有所需 1 + 核心独有 4),见「初始化」。
145
- `sync` 选项:`--all` 仅更新同名技能内容(存在则覆盖,不存在则新增)并更新 `AGENTS.md`(不跳过定制),不删多余;`--dry-run` 预演(只比对不写盘,`--json` 可解析,有差异 `exit 1`);`--all` 展开同名全量;`--dest <path>` 目标目录;`--upstream <url>` 上游地址;`--ref <ref>` 上游分支;`--json` JSON 输出;默认即安全增量(`AGENTS.md` 有定制则跳过)。
146
- `check` 选项:`--json`、`--all`(默认范围:engineering + 独有所需)、`--upstream <url>`、`--ref <ref>`(等价 `sync --dry-run`)。
165
+ `init` 选项:`--dest <path>` 指定目标目录(默认当前目录);`--all` 包含全部可分发 skill,见「初始化」。
166
+ `sync` 选项:写盘时 `--all` 更新全部可分发同名技能内容(存在则覆盖,不存在则新增)并更新 `AGENTS.md`(不跳过定制),不删多余;默认写盘只同步默认 programming;`--dry-run` 只比对上游、不写盘(默认 engineering + required 上游范围,`--all` 为全量上游范围,`--json` 可解析,有差异 `exit 1`);`--dest <path>` 目标目录;`--upstream <url>` 上游地址;`--ref <ref>` 上游分支;`--json` JSON 输出;默认安全增量会保留目标定制。
167
+ `check` 选项:`--json`、`--all`(默认只比较 engineering + required 上游范围;proprietary 不参与上游 compare)、`--upstream <url>`、`--ref <ref>`(等价 `sync --dry-run`)。
147
168
 
148
169
  `install` 选项:
149
170
 
150
171
  - `--dest <dir>`:复制到指定目录(覆盖工具映射)
151
172
  - `--tools <t1,t2>`:指定工具,项目级已统一 `codex/pi/opencode/claude → .agents/skills`(共享技能单一源,`.pi/skills`/`.opencode/skills` 仅用于项目自定义)
152
173
  - `--global`:安装到全局目录(`~/.codex/skills`、`~/.pi/agent/skills`、`~/.config/opencode/skills`、`~/.claude/skills`);`--project` 回到项目级
153
- - `--all`:安装全部技能(默认编程 26,`--all` 33,交互勾选时仅列默认范围);`--force`:覆盖已存在的技能
174
+ - `--all`:安装全部可分发 skill(交互勾选时默认只列 programming 范围);`--force`:覆盖已存在的技能
154
175
 
155
176
 
156
177
  ### 上游同步(自动更新)
@@ -160,14 +181,14 @@ node bin/cli.js check [--json] [--all] [--upstream <url>] [--ref <ref>]
160
181
  - **本地 CLI**:`matt-skills sync` 两档——`--dry-run` 只读比对(有差异 `exit 1`,`--json` 可解析)、默认安全增量与 `sync --all` 仅同名 upsert + `AGENTS.md`;`matt-skills check [--json] [--upstream <url>] [--ref <ref>]` 为只读别名(等价 `sync --dry-run`);`matt-skills update` 已合并到 `sync`(执行提示 `update 已合并到 sync` 且 `exit 1`)
161
182
  ```sh
162
183
  npx @heihei0299/matt-skills sync --dry-run --json # 预演只读检查,JSON 输出:{ head, counts, result: { added, updated, renamed, removed, same } }
163
- npx @heihei0299/matt-skills sync # 默认安全增量(AGENTS.md 定制跳过,默认技能 26
184
+ npx @heihei0299/matt-skills sync # 默认安全增量(AGENTS.md 定制跳过,默认 programming
164
185
  npx @heihei0299/matt-skills sync --all # 仅同名 upsert + AGENTS.md
165
186
  npx @heihei0299/matt-skills check --json # 等价 sync --dry-run
166
187
  node scripts/sync-upstream.js --check # 等价底层脚本(CLI sync/check 的实现)
167
188
  node scripts/sync-upstream.js --apply --dry-run
168
189
  ```
169
190
 
170
- 实现细节:`scripts/sync-upstream.js` 为单一事实源(CLI 与 Actions 共用),以 `config/proprietary.json` 为独有白名单 + `config/engineering.json` 为编程白名单 + `config/required.json` 为独有所需白名单(当前仅 grilling:grill-to-spec 经 grill-with-docs 所需,属 productivity 但默认同步;其余 productivity 默认不装,`--all` 展开),上游通过 `git clone --depth 1 https://github.com/mattpocock/skills.git` 获取,比对 `SKILL.md` 的 sha256,自动处理新增/更新/重命名/删除;Actions PR 后需人工合入,合入后按“发布”节打 `v*` 标签即发布(自动 patch 发版可在后续扩展为 PR 合入后自动 bump)。
191
+ 实现细节:`scripts/sync-upstream.js` 为单一事实源(CLI 与 Actions 共用),以 proprietary 分类契约排除本仓库独有 skill,以 `config/engineering.json` 为编程白名单,以 `config/required.json` 为独有所需白名单;上游通过 `git clone --depth 1 https://github.com/mattpocock/skills.git` 获取,比对 `SKILL.md` 的 sha256,自动处理新增/更新/重命名/删除。上游同步只维护 workspace,模板生成时再按 distributable 边界投影。
171
192
  上游重命名映射:`RENAMES = { "writing-great-skills": "writing-for-agents" }`,Actions/CLI 均会删除旧目录并复制新目录。
172
193
  ## 发布
173
194
 
@@ -200,7 +221,7 @@ npm publish
200
221
 
201
222
  ```sh
202
223
  npm test # 全量测试
203
- npm run build:template # 从单源生成 template/.agents/skills(全量 33 技能)+ 空占位
224
+ npm run build:template # workspace 生成仅含可分发 skill 的 template + 空占位
204
225
  ```
205
226
 
206
227
  交互模式依赖 `prompts`(见 `package.json`);测试见 `test/cli.test.js`、`test/cli-init.test.js`、`test/template-sync.test.js`。
package/bin/cli.js CHANGED
@@ -4,11 +4,17 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import prompts from 'prompts';
7
+ import {
8
+ PROPRIETARY_SKILLS,
9
+ isDefaultProgrammingSkill,
10
+ isDistributableProprietarySkill,
11
+ isDistributableSkill,
12
+ isRepoLocalSkill,
13
+ REPO_LOCAL_SKILLS,
14
+ } from './skill-boundaries.js';
7
15
 
8
16
  const SKILLS_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', '.agents', 'skills');
9
17
  const TEMPLATE_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'template');
10
- const PROPRIETARY_SKILLS = new Set(['ci-guard', 'tdd-implement', 'grill-to-spec', 'diagnose-fix', 'commit-check', 'scaffold-functional-test', 'show-me']);
11
- const PROPRIETARY_DEFAULT = new Set(['tdd-implement', 'diagnose-fix', 'commit-check', 'grill-to-spec', 'show-me']); // 默认仅装核心 4 + show-me,--all 才装全部 7
12
18
  const ENGINEERING_PATH = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'config', 'engineering.json');
13
19
  const REQUIRED_PATH = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'config', 'required.json');
14
20
  let ENGINEERING_SKILLS = null;
@@ -34,10 +40,10 @@ async function loadRequiredSkills() {
34
40
  return REQUIRED_SKILLS;
35
41
  }
36
42
  function isProgrammingSkill(name, engineering, required) {
37
- return PROPRIETARY_DEFAULT.has(name) || engineering.has(name) || (required && required.has(name));
43
+ return isDefaultProgrammingSkill(name, engineering, required);
38
44
  }
39
45
  function isProgrammingAll(name, engineering) {
40
- return PROPRIETARY_SKILLS.has(name) || engineering.has(name);
46
+ return isDistributableProprietarySkill(name) || engineering.has(name);
41
47
  }
42
48
  process.stdout.on('error', (err) => {
43
49
  if (err.code === 'EPIPE') process.exit(0);
@@ -64,9 +70,9 @@ Usage:
64
70
 
65
71
  Init options:
66
72
  --dest <path> Target directory (default: current directory)
67
- --all Include non-programming skills (productivity) and optional proprietary; default only core programming (engineering 18 + required 4 + default proprietary 4 → 26)
73
+ --all Include all distributable skills; default only default programming skills
68
74
  --help, -h Show this help
69
- 提示:已有 AGENTS.md 时普通 init 跳过;显式 init --all 刷新模板并覆盖全量 skills。
75
+ 提示:已有 AGENTS.md 时普通 init 跳过;显式 init --all 刷新模板并覆盖全量可分发 skills。
70
76
 
71
77
  提示:matt-skills --help 查看全量
72
78
  `;
@@ -82,7 +88,7 @@ Sync options:
82
88
  --dest <path> Target directory (default: current directory)
83
89
  --help, -h Show this help
84
90
 
85
- 说明:默认不带 --all 仅增量同步默认技能(26)且 AGENTS.md 有定制则跳过;--all 时对同名技能 upsert 并强制更新 AGENTS.md。
91
+ 说明:默认不带 --all 仅增量同步默认 programming skill 且 AGENTS.md 有定制则跳过;--all 时同步全部可分发 skill 并强制更新 AGENTS.md。
86
92
 
87
93
  提示:matt-skills --help 查看全量
88
94
  `;
@@ -93,7 +99,7 @@ Usage:
93
99
  matt-skills list [--all] [--json]
94
100
 
95
101
  List options:
96
- --all List all skills (default only core programming 26)
102
+ --all List all distributable skills (default only default programming skills)
97
103
  --json Output as JSON
98
104
  --help, -h Show this help
99
105
 
@@ -106,7 +112,7 @@ Usage:
106
112
  matt-skills check [--all] [--json] [--upstream <url>] [--ref <ref>]
107
113
 
108
114
  Check options:
109
- --all Include non-programming and optional proprietary; default only core programming (26: engineering 18 + required 4 + default proprietary 4)
115
+ --all Include the full upstream comparison scope; default engineering + required upstream skills (proprietary excluded)
110
116
  --json Output as JSON
111
117
  --upstream <url> Upstream repo URL (default: https://github.com/mattpocock/skills.git)
112
118
  --ref <ref> Upstream ref (default: HEAD)
@@ -122,7 +128,7 @@ Usage:
122
128
 
123
129
  Install options:
124
130
  --tools <a,b> Install for the given tools (codex, pi, opencode, claude); skips tool selection — 共享技能统一指向 .agents/skills,.pi/skills/.opencode/skills 仅用于项目自定义
125
- --all Install all skills (default only core programming 26); skips skill selection
131
+ --all Install all distributable skills (default only default programming); skips skill selection
126
132
  --force Overwrite existing skills
127
133
  --global Install to the user's global skill directories
128
134
  --project Install to project skill directories (default)
@@ -161,6 +167,7 @@ async function listSkills({ onlyProgramming = false } = {}) {
161
167
  if (!entry.isDirectory()) continue;
162
168
  if (entry.name.endsWith('.bak')) continue;
163
169
  if (entry.name === 'skill-creator') continue;
170
+ if (isRepoLocalSkill(entry.name)) continue;
164
171
  if (onlyProgramming && !isProgrammingSkill(entry.name, engineering, required)) continue;
165
172
  let content;
166
173
  try {
@@ -182,6 +189,13 @@ async function pathExists(p) {
182
189
  return false;
183
190
  }
184
191
  }
192
+
193
+ function shouldCopyTemplatePath(src) {
194
+ const relative = path.relative(TEMPLATE_DIR, src);
195
+ const parts = relative.split(path.sep);
196
+ return !(parts[0] === '.agents' && parts[1] === 'skills' && isRepoLocalSkill(parts[2]));
197
+ }
198
+
185
199
  const TOOLS = ['codex', 'pi', 'opencode', 'claude'];
186
200
 
187
201
  // 统一源:共享技能全部在 .agents/skills,harness 的 .pi/skills/.opencode/skills 仅用于项目自定义
@@ -262,6 +276,12 @@ async function installCommand({ dest, all, force, tools, global }) {
262
276
  process.stdout.write('未选择任何技能,未安装任何技能\n');
263
277
  return;
264
278
  }
279
+ const knownDistributable = new Set(skills.map((skill) => skill.name));
280
+ for (const name of selected) {
281
+ if (!isDistributableSkill(name, knownDistributable)) {
282
+ throw new Error(`${name} is repository-local or unavailable and cannot be distributed`);
283
+ }
284
+ }
265
285
  for (const { tool, dir } of targets) {
266
286
  let installed = 0;
267
287
  let skipped = 0;
@@ -287,7 +307,11 @@ async function initCommand({ dest, all }) {
287
307
  if (await pathExists(marker) && !all) {
288
308
  process.stdout.write('模板已存在(AGENTS.md),跳过\n');
289
309
  } else {
290
- await cp(TEMPLATE_DIR, target, { recursive: true, force: true });
310
+ await cp(TEMPLATE_DIR, target, {
311
+ recursive: true,
312
+ force: true,
313
+ filter: shouldCopyTemplatePath,
314
+ });
291
315
  process.stdout.write('模板:已复制(AGENTS.md、.agents/skills、.opencode/、.pi/)\n');
292
316
  // 默认范围(engineering + 独有所需 + 默认独有),--all 才保留其余 productivity
293
317
  if (onlyProgramming && path.resolve(target) !== path.resolve(path.join(path.dirname(fileURLToPath(import.meta.url)), '..'))) {
@@ -311,7 +335,7 @@ async function initCommand({ dest, all }) {
311
335
  let installed = 0;
312
336
  try {
313
337
  const entries = await readdir(skillsDir, { withFileTypes: true });
314
- installed = entries.filter((e) => e.isDirectory() && !e.name.endsWith('.bak') && e.name !== '.git' && e.name !== 'skill-creator').length;
338
+ installed = entries.filter((e) => e.isDirectory() && !e.name.endsWith('.bak') && e.name !== '.git' && e.name !== 'skill-creator' && !isRepoLocalSkill(e.name)).length;
315
339
  } catch {}
316
340
  const allSkillsFull = await listSkills({ onlyProgramming: false });
317
341
  const engineeringForStats = await loadEngineeringSkills();
@@ -322,12 +346,12 @@ async function initCommand({ dest, all }) {
322
346
  const displayTotal = onlyProgramming ? programmingCount : allSkillsFull.length;
323
347
  const displayUpstream = onlyProgramming ? upstreamProg : upstreamFull;
324
348
  if (path.resolve(skillsDir) === path.resolve(SKILLS_DIR)) {
325
- process.stdout.write(`技能:已装 ${installed}、跳过 0(全量 ${allSkillsFull.length},含上游 ${upstreamFull};编程 ${programmingCount},含上游 ${upstreamProg})\n`);
349
+ process.stdout.write(`技能:已装 ${installed}、跳过 0(可分发 ${allSkillsFull.length},含上游 ${upstreamFull};默认编程 ${programmingCount},含上游 ${upstreamProg})\n`);
326
350
  } else {
327
351
  if (onlyProgramming) {
328
- process.stdout.write(`技能:已装 ${installed}(编程 ${displayTotal},含上游 ${displayUpstream};全量 ${allSkillsFull.length},含上游 ${upstreamFull})\n`);
352
+ process.stdout.write(`技能:已装 ${installed}(默认编程 ${displayTotal},含上游 ${displayUpstream};可分发 ${allSkillsFull.length},含上游 ${upstreamFull})\n`);
329
353
  } else {
330
- process.stdout.write(`技能:已装 ${installed}(全量 ${displayTotal},含上游 ${displayUpstream})\n`);
354
+ process.stdout.write(`技能:已装 ${installed}(可分发 ${displayTotal},含上游 ${displayUpstream})\n`);
331
355
  }
332
356
  }
333
357
  process.stdout.write(`目标路径:${target}\n`);
@@ -340,7 +364,7 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
340
364
  if (json) {
341
365
  process.stdout.write(JSON.stringify({ head: cmp.head, counts: cmp.counts, result: cmp.result, onlyProgramming }, null, 2) + '\n');
342
366
  } else {
343
- const modeHint = onlyProgramming ? '(默认:engineering + 独有所需)' : '(全量)';
367
+ const modeHint = onlyProgramming ? '(默认:engineering + 独有所需)' : '(全量上游)';
344
368
  const lines = [];
345
369
  lines.push(`上游 HEAD: ${cmp.head}`);
346
370
  lines.push(`本地非独有: ${cmp.counts.local} 上游: ${cmp.counts.upstream} ${modeHint}`);
@@ -368,7 +392,11 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
368
392
  // 模板同步:默认模式下过滤 skills,仅同步默认子集
369
393
  async function copyTemplateFiltered() {
370
394
  if (!onlyProgramming) {
371
- await cp(TEMPLATE_DIR, target, { recursive: true, force: true });
395
+ await cp(TEMPLATE_DIR, target, {
396
+ recursive: true,
397
+ force: true,
398
+ filter: shouldCopyTemplatePath,
399
+ });
372
400
  return;
373
401
  }
374
402
  // 默认范围:分别复制非 skills 部分,skills 由后续 allSkills 循环处理
@@ -391,7 +419,11 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
391
419
  if (!(await pathExists(marker))) {
392
420
  process.stdout.write('未检测到现有项目(AGENTS.md 不存在),将执行全新初始化\n');
393
421
  if (onlyProgramming) await copyTemplateFiltered();
394
- else await cp(TEMPLATE_DIR, target, { recursive: true, force: true });
422
+ else await cp(TEMPLATE_DIR, target, {
423
+ recursive: true,
424
+ force: true,
425
+ filter: shouldCopyTemplatePath,
426
+ });
395
427
  process.stdout.write('模板:已复制(AGENTS.md、.agents/skills、.opencode/、.pi/)\n');
396
428
  } else {
397
429
  process.stdout.write('同步:检测到现有项目,将增量更新\n');
@@ -416,21 +448,30 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
416
448
  }
417
449
  } catch {}
418
450
  } else {
419
- await cp(path.join(TEMPLATE_DIR, '.agents'), path.join(target, '.agents'), { recursive: true, force: true });
451
+ await cp(path.join(TEMPLATE_DIR, '.agents'), path.join(target, '.agents'), {
452
+ recursive: true,
453
+ force: true,
454
+ filter: shouldCopyTemplatePath,
455
+ });
420
456
  await cp(path.join(TEMPLATE_DIR, '.opencode'), path.join(target, '.opencode'), { recursive: true, force: true });
421
457
  await cp(path.join(TEMPLATE_DIR, '.pi'), path.join(target, '.pi'), { recursive: true, force: true });
422
458
  }
423
459
  process.stdout.write('模板:已同步(AGENTS.md 跳过,已含定制)\n');
424
460
  } else {
425
461
  if (onlyProgramming) await copyTemplateFiltered();
426
- else await cp(TEMPLATE_DIR, target, { recursive: true, force: true });
462
+ else await cp(TEMPLATE_DIR, target, {
463
+ recursive: true,
464
+ force: true,
465
+ filter: shouldCopyTemplatePath,
466
+ });
427
467
  process.stdout.write('模板:已同步(AGENTS.md、.agents/skills、.opencode/、.pi/)\n');
428
468
  }
429
469
  }
430
- // 技能同步:--all 仅更新同名技能内容,存在则覆盖,不存在则新增,并更新 AGENTS.md(由上一步已处理);默认范围 26,--all 时按全量同名集合处理,不删多余
470
+ // 技能同步:--all 仅更新同名可分发技能内容,存在则覆盖,不存在则新增,并更新 AGENTS.md(由上一步已处理);默认范围为默认 programming,不删多余
431
471
  const entries = await readdir(SKILLS_DIR, { withFileTypes: true });
432
472
  const allNames = entries.filter((e) => e.isDirectory() && !e.name.endsWith('.bak') && e.name !== 'skill-creator' && e.name !== '.git').map((e) => e.name);
433
473
  let allSkills = allNames.sort();
474
+ allSkills = allSkills.filter((name) => !isRepoLocalSkill(name));
434
475
  if (onlyProgramming) {
435
476
  const engineering = await loadEngineeringSkills();
436
477
  const required = await loadRequiredSkills();
@@ -438,6 +479,23 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
438
479
  }
439
480
  const skillsDir = path.join(target, '.agents', 'skills');
440
481
  await mkdir(skillsDir, { recursive: true });
482
+ const preservedRepoLocal = [];
483
+ const preserveLocations = [
484
+ {
485
+ dir: skillsDir,
486
+ label: '.agents/skills',
487
+ isWorkspaceSource: path.resolve(skillsDir) === path.resolve(SKILLS_DIR),
488
+ },
489
+ { dir: path.join(target, '.pi', 'skills'), label: '.pi/skills', isWorkspaceSource: false },
490
+ { dir: path.join(target, '.opencode', 'skills'), label: '.opencode/skills', isWorkspaceSource: false },
491
+ ];
492
+ for (const name of REPO_LOCAL_SKILLS) {
493
+ for (const location of preserveLocations) {
494
+ if (!location.isWorkspaceSource && await pathExists(path.join(location.dir, name))) {
495
+ preservedRepoLocal.push(`${location.label}/${name}`);
496
+ }
497
+ }
498
+ }
441
499
  let installed = 0;
442
500
  let updated = 0;
443
501
  for (const name of allSkills) {
@@ -468,7 +526,7 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
468
526
  if (!e.isDirectory()) continue;
469
527
  if (e.name === '.git' || e.name.endsWith('.bak')) continue;
470
528
  if (e.name === '.gitkeep' || e.name === 'README.md') continue;
471
- if (allSkills.includes(e.name) || PROPRIETARY_SKILLS.has(e.name)) {
529
+ if (allSkills.includes(e.name)) {
472
530
  await rm(path.join(dir, e.name), { recursive: true, force: true });
473
531
  }
474
532
  }
@@ -484,7 +542,10 @@ async function syncCommand({ dest, all, dryRun, json, upstreamUrl, ref }) {
484
542
  }
485
543
  }
486
544
  } catch {}
487
- const modeLabel = onlyProgramming ? '编程' : '全量';
545
+ if (preservedRepoLocal.length) {
546
+ process.stdout.write(`迁移提示:${preservedRepoLocal.join(', ')} 已不再分发,现有副本已保留\n`);
547
+ }
548
+ const modeLabel = onlyProgramming ? '默认编程' : '全部可分发';
488
549
  process.stdout.write(`技能:新增 ${installed}、更新 ${updated}(${modeLabel} ${allSkills.length})\n`);
489
550
  process.stdout.write(`目标路径:${target}\n`);
490
551
  }
@@ -584,7 +645,7 @@ async function checkCommand(args) {
584
645
  } else {
585
646
  const lines = [];
586
647
  lines.push(`上游 HEAD: ${cmp.head}`);
587
- const modeHint = onlyProgramming ? '(默认:engineering + 独有所需)' : '(全量)';
648
+ const modeHint = onlyProgramming ? '(默认:engineering + 独有所需)' : '(全量上游)';
588
649
  lines.push(`本地非独有: ${cmp.counts.local} 上游: ${cmp.counts.upstream} ${modeHint}`);
589
650
  lines.push('');
590
651
  const totalDiff = cmp.result.added.length + cmp.result.updated.length + cmp.result.removed.length + cmp.result.renamed.length;
@@ -0,0 +1,61 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
6
+ const CONFIG_PATH = path.join(ROOT, 'config', 'proprietary.json');
7
+ const config = JSON.parse(readFileSync(CONFIG_PATH, 'utf8'));
8
+
9
+ function toUniqueSet(value, key) {
10
+ if (!Array.isArray(value) || new Set(value).size !== value.length) {
11
+ throw new Error(`invalid proprietary classification: ${key} must be a unique array`);
12
+ }
13
+ return new Set(value);
14
+ }
15
+
16
+ export const PROPRIETARY_SKILLS = toUniqueSet(config.all, 'all');
17
+ export const DISTRIBUTABLE_PROPRIETARY_SKILLS = toUniqueSet(config.distributable, 'distributable');
18
+ export const REPO_LOCAL_SKILLS = toUniqueSet(config.repoLocal, 'repoLocal');
19
+ export const DEFAULT_PROPRIETARY_SKILLS = toUniqueSet(config.default, 'default');
20
+
21
+ const classified = new Set([...DISTRIBUTABLE_PROPRIETARY_SKILLS, ...REPO_LOCAL_SKILLS]);
22
+ const missing = [...PROPRIETARY_SKILLS].filter((name) => !classified.has(name));
23
+ const extra = [...classified].filter((name) => !PROPRIETARY_SKILLS.has(name));
24
+ const overlap = [...DISTRIBUTABLE_PROPRIETARY_SKILLS].filter((name) => REPO_LOCAL_SKILLS.has(name));
25
+ const invalidDefaults = [...DEFAULT_PROPRIETARY_SKILLS].filter((name) => !DISTRIBUTABLE_PROPRIETARY_SKILLS.has(name));
26
+ if (missing.length || extra.length || overlap.length || invalidDefaults.length) {
27
+ throw new Error(
28
+ `invalid proprietary classification: missing=${missing.join(',')} extra=${extra.join(',')} ` +
29
+ `overlap=${overlap.join(',')} defaults=${invalidDefaults.join(',')}`,
30
+ );
31
+ }
32
+
33
+ export function isProprietarySkill(name) {
34
+ return PROPRIETARY_SKILLS.has(name);
35
+ }
36
+
37
+ export function isDistributableProprietarySkill(name) {
38
+ return DISTRIBUTABLE_PROPRIETARY_SKILLS.has(name);
39
+ }
40
+
41
+ export function isRepoLocalSkill(name) {
42
+ return REPO_LOCAL_SKILLS.has(name);
43
+ }
44
+
45
+ export function isDefaultProprietarySkill(name) {
46
+ return DEFAULT_PROPRIETARY_SKILLS.has(name);
47
+ }
48
+
49
+ export function isDefaultProgrammingSkill(name, engineering, required) {
50
+ return (
51
+ DEFAULT_PROPRIETARY_SKILLS.has(name) ||
52
+ engineering.has(name) ||
53
+ (required && required.has(name))
54
+ );
55
+ }
56
+
57
+ export function isDistributableSkill(name, knownNames) {
58
+ if (!knownNames) return isDistributableProprietarySkill(name);
59
+ const known = knownNames instanceof Set ? knownNames : new Set(knownNames);
60
+ return known.has(name) && !REPO_LOCAL_SKILLS.has(name);
61
+ }
@@ -1,9 +1,28 @@
1
- [
2
- "ci-guard",
3
- "tdd-implement",
4
- "grill-to-spec",
5
- "diagnose-fix",
6
- "commit-check",
7
- "scaffold-functional-test",
8
- "show-me"
9
- ]
1
+ {
2
+ "all": [
3
+ "ci-guard",
4
+ "tdd-implement",
5
+ "grill-to-spec",
6
+ "diagnose-fix",
7
+ "commit-check",
8
+ "scaffold-functional-test",
9
+ "show-me"
10
+ ],
11
+ "distributable": [
12
+ "tdd-implement",
13
+ "diagnose-fix",
14
+ "grill-to-spec",
15
+ "scaffold-functional-test",
16
+ "show-me"
17
+ ],
18
+ "repoLocal": [
19
+ "ci-guard",
20
+ "commit-check"
21
+ ],
22
+ "default": [
23
+ "tdd-implement",
24
+ "diagnose-fix",
25
+ "grill-to-spec",
26
+ "show-me"
27
+ ]
28
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heihei0299/matt-skills",
3
- "version": "2.0.2",
3
+ "version": "2.1.0",
4
4
  "description": "Agent skills + 项目配置模板:一条命令初始化 opencode / pi-agent 项目(含 mattpocock/skills 上游技能)",
5
5
  "type": "module",
6
6
  "bin": {