@namewta/speculo 1.0.19 → 1.0.21

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 (194) hide show
  1. package/README.md +8 -7
  2. package/THIRD-PARTY-NOTICES.md +33 -0
  3. package/dist/src/agent-files.js +2 -2
  4. package/dist/src/agent-files.js.map +1 -1
  5. package/dist/src/agent-skills.d.ts +81 -0
  6. package/dist/src/agent-skills.js +530 -0
  7. package/dist/src/agent-skills.js.map +1 -0
  8. package/dist/src/cli.js +11 -3
  9. package/dist/src/cli.js.map +1 -1
  10. package/dist/src/config.js +5 -3
  11. package/dist/src/config.js.map +1 -1
  12. package/dist/src/doctor.js +7 -2
  13. package/dist/src/doctor.js.map +1 -1
  14. package/dist/src/index.d.ts +8 -0
  15. package/dist/src/index.js +23 -3
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/manifest.d.ts +9 -0
  18. package/dist/src/manifest.js +45 -7
  19. package/dist/src/manifest.js.map +1 -1
  20. package/dist/src/refresh.js +40 -0
  21. package/dist/src/refresh.js.map +1 -1
  22. package/dist/src/structured.js +15 -4
  23. package/dist/src/structured.js.map +1 -1
  24. package/dist/src/transaction.d.ts +24 -3
  25. package/dist/src/transaction.js +191 -12
  26. package/dist/src/transaction.js.map +1 -1
  27. package/package.json +7 -4
  28. package/scripts/validate-skills.mjs +56 -0
  29. package/template/AGENTS.md +1 -1
  30. package/template/CLAUDE.md +1 -1
  31. package/template/canonical/canonical-specdev-goal-plan.md +156 -28
  32. package/template/canonical/canonical-specdev-grill-with-docs.md +153 -31
  33. package/template/canonical/canonical-specdev-spec.md +153 -27
  34. package/template/canonical/canonical-specdev-tickets.md +153 -27
  35. package/template/canonical/canonical-specdev-wayfinder.md +142 -27
  36. package/template/commands/retro.md +11 -9
  37. package/template/skills/archive-and-consolidate/SKILL.md +163 -7
  38. package/template/skills/archive-and-consolidate/references/cleanup-rules.md +1 -1
  39. package/template/skills/docs-sync/references/agents/claude-redirect.md +8 -8
  40. package/template/skills/docs-sync/references/agents/content-contract.md +1 -1
  41. package/template/skills/docs-sync/references/agents/manifest-discovery.md +7 -7
  42. package/template/skills/docs-sync/references/agents/role-classification.md +4 -4
  43. package/template/skills/docs-sync/references/agents-contract.md +1 -1
  44. package/template/skills/engineering-standards-builder/SKILL.md +149 -9
  45. package/template/skills/engineering-standards-builder/agents/openai.yaml +2 -0
  46. package/template/skills/engineering-standards-builder/manifest.txt +2 -1
  47. package/template/skills/engineering-standards-builder/references/rules/09-mechanical-guardrails.md +9 -0
  48. package/template/skills/engineering-standards-builder/scripts/validate-builder.mjs +4 -7
  49. package/template/skills/git-history-squash/SKILL.md +87 -11
  50. package/template/skills/git-history-squash/agents/openai.yaml +2 -0
  51. package/template/skills/optimize-codex-config/SKILL.md +71 -11
  52. package/template/skills/{speculo-retro/references/entry-procedure.md → retrospective/SKILL.md} +12 -8
  53. package/template/skills/{speculo-retro → retrospective}/references/friction-taxonomy.md +22 -13
  54. package/template/skills/{speculo-retro → retrospective}/references/issue-drafting-sop.md +10 -20
  55. package/template/skills/source-code-zip/SKILL.md +44 -8
  56. package/template/skills/source-code-zip/references/{entry-procedure.md → cli-reference.md} +0 -43
  57. package/template/skills/upstream-fork-sync/SKILL.md +71 -8
  58. package/template/skills/{writing-great-skills → writing-for-agents}/GLOSSARY.md +1 -1
  59. package/template/skills/writing-for-agents/SKILL.md +22 -0
  60. package/template/skills/writing-for-agents/agents/openai.yaml +2 -0
  61. package/template/skills/{writing-great-skills/references/entry-procedure.md → writing-for-agents/references/authoring-principles.md} +2 -9
  62. package/template/workflows/ops/D-project-deploy/D-project-deploy.md +1 -1
  63. package/template/workflows/ops/H-host-manage/H-host-manage.md +4 -0
  64. package/template/workflows/ops/H-host-manage/references/host-profiles.md +4 -0
  65. package/template/workflows/ops/I-initialize/I-initialize.md +1 -1
  66. package/template/workflows/ops/INDEX.md +2 -0
  67. package/template/workflows/ops/README.md +7 -3
  68. package/template/workflows/ops/S-server-connect/S-server-connect.md +5 -5
  69. package/template/workflows/ops/V-inventory-view/V-inventory-view.md +2 -0
  70. package/template/workflows/ops/common/CAPABILITIES.md +2 -0
  71. package/template/workflows/ops/common/USAGE.md +5 -5
  72. package/template/workflows/ops/common/WORKSPACE-USAGE.md +29 -2
  73. package/template/workflows/ops/common/examples/README.md +1 -1
  74. package/template/workflows/ops/common/examples/register.example.json +7 -3
  75. package/template/workflows/ops/common/examples/server-connection.example.json +11 -0
  76. package/template/workflows/ops/common/rules/deployment-layout.md +1 -1
  77. package/template/workflows/ops/common/rules/host-root-and-onboarding.md +47 -0
  78. package/template/workflows/ops/common/rules/persistence-and-secrets.md +1 -1
  79. package/template/workflows/ops/common/rules/research-and-decisions.md +8 -0
  80. package/template/workflows/ops/common/rules/server-onboarding.md +3 -3
  81. package/template/workflows/ops/common/rules/workspace-and-authorization.md +2 -2
  82. package/template/workflows/ops/common/schemas/fleet-view.schema.json +64 -0
  83. package/template/workflows/ops/common/schemas/host.schema.json +19 -0
  84. package/template/workflows/ops/common/schemas/plan.schema.json +57 -0
  85. package/template/workflows/ops/common/schemas/root-confirmation.schema.json +118 -0
  86. package/template/workflows/ops/common/schemas/server-connection.schema.json +67 -0
  87. package/template/workflows/ops/common/schemas/server-discovery.schema.json +171 -0
  88. package/template/workflows/ops/common/schemas/spec.schema.json +19 -0
  89. package/template/workflows/ops/common/schemas/status.schema.json +19 -0
  90. package/template/workflows/ops/common/templates/FLEET.html +1 -1
  91. package/template/workflows/ops/common/templates/HOST-README.md +3 -1
  92. package/template/workflows/ops/common/tests/test_ops.mjs +8 -11
  93. package/template/workflows/ops/common/tests/test_ops_bootstrap.mjs +101 -16
  94. package/template/workflows/ops/common/tests/test_ops_onboarding.mjs +225 -0
  95. package/template/workflows/ops/common/tests/test_ops_workspace.mjs +17 -8
  96. package/template/workflows/ops/common/tools/demo-local.mjs +4 -0
  97. package/template/workflows/ops/common/tools/opslib/agent.mjs +26 -0
  98. package/template/workflows/ops/common/tools/opslib/bootstrap.mjs +52 -26
  99. package/template/workflows/ops/common/tools/opslib/cli.mjs +1 -0
  100. package/template/workflows/ops/common/tools/opslib/core.mjs +1 -1
  101. package/template/workflows/ops/common/tools/opslib/docs.mjs +1 -0
  102. package/template/workflows/ops/common/tools/opslib/execution.mjs +4 -0
  103. package/template/workflows/ops/common/tools/opslib/fleet.mjs +26 -4
  104. package/template/workflows/ops/common/tools/opslib/host_recipes.mjs +34 -0
  105. package/template/workflows/ops/common/tools/opslib/model.mjs +6 -0
  106. package/template/workflows/ops/common/tools/opslib/onboarding.mjs +215 -0
  107. package/template/workflows/ops/common/tools/opslib/planner.mjs +3 -0
  108. package/template/workflows/ops/common/tools/opslib/transport.mjs +10 -6
  109. package/template/workflows/ops/common/tools/opslib/workspace_cli.mjs +20 -1
  110. package/template/workflows/ops/common/tools/server-discover.sh +65 -0
  111. package/template/workflows/ops/common/tools/validate-ops.mjs +1 -1
  112. package/template/workflows/ops/manifest.json +12 -5
  113. package/template/workflows/specdev/A-archive-and-consolidate/consolidation-interview.md +3 -3
  114. package/template/workflows/specdev/C-code-review/C-code-review.md +1 -1
  115. package/template/workflows/specdev/D-diagnose-bugs/D-diagnose-bugs.md +6 -0
  116. package/template/workflows/specdev/G-grill-with-docs/references/interview-procedure.md +6 -6
  117. package/template/workflows/specdev/I-implement/references/implementation-procedure.md +1 -1
  118. package/template/workflows/specdev/I-implement/tdd-rules.md +4 -0
  119. package/template/workflows/specdev/I-init-setup/config-template.json +5 -1
  120. package/template/workflows/specdev/INDEX.md +2 -2
  121. package/template/workflows/specdev/P-goal-plan/planning-modes.md +1 -1
  122. package/template/workflows/specdev/P-prototype/P-prototype.md +7 -3
  123. package/template/workflows/specdev/P-prototype/logic-protocol.md +11 -0
  124. package/template/workflows/specdev/P-prototype/logic-template.md +27 -0
  125. package/template/workflows/specdev/P-prototype/project-preview-protocol.md +9 -0
  126. package/template/workflows/specdev/R-retro/R-retro.md +26 -0
  127. package/template/workflows/specdev/R-retro/retro-template.md +27 -0
  128. package/template/workflows/specdev/R-review-architecture/references/selected-design.md +1 -1
  129. package/template/workflows/specdev/README.md +13 -2
  130. package/template/workflows/specdev/S-spec/S-spec.md +4 -0
  131. package/template/workflows/specdev/T-tickets/T-tickets.md +4 -0
  132. package/template/workflows/specdev/T-triage/T-triage.md +31 -25
  133. package/template/workflows/specdev/T-triage/capture-protocol.md +1 -1
  134. package/template/workflows/specdev/T-triage/ci-security-protocol.md +11 -0
  135. package/template/workflows/specdev/T-triage/intake-protocol.md +10 -4
  136. package/template/workflows/specdev/T-triage/pr-delivery-protocol.md +13 -0
  137. package/template/workflows/specdev/T-triage/pr-record-template.md +39 -0
  138. package/template/workflows/specdev/T-triage/publish-protocol.md +1 -1
  139. package/template/workflows/specdev/T-triage/queue-protocol.md +7 -0
  140. package/template/workflows/specdev/T-triage/reconcile-protocol.md +1 -1
  141. package/template/workflows/specdev/T-triage/references/issue-pr-policy.md +23 -0
  142. package/template/workflows/specdev/T-triage/references/release-authentication.md +9 -0
  143. package/template/workflows/specdev/T-triage/references/release-notes-injection.md +21 -0
  144. package/template/workflows/specdev/T-triage/references/workflow-yaml-reference.md +37 -0
  145. package/template/workflows/specdev/T-triage/release-preflight.md +13 -0
  146. package/template/workflows/specdev/T-triage/release-protocol.md +12 -0
  147. package/template/workflows/specdev/T-triage/release-recovery.md +18 -0
  148. package/template/workflows/specdev/T-triage/remote-operations.md +25 -0
  149. package/template/workflows/specdev/T-triage/scripts/github-transport.mjs +208 -0
  150. package/template/workflows/specdev/T-triage/source-template.md +7 -0
  151. package/template/workflows/specdev/T-triage/triage-run-template.md +34 -0
  152. package/template/workflows/specdev/T-triage/triage-template.md +4 -1
  153. package/template/workflows/specdev/common/rules/artifact-contract.md +7 -0
  154. package/template/workflows/specdev/common/rules/change-completion.md +6 -0
  155. package/template/workflows/specdev/common/rules/workflow-routing.md +6 -0
  156. package/template/workflows/specdev/common/rules/workflow-state-and-lifecycle.md +1 -1
  157. package/template/workflows/specdev/common/schemas/config.schema.json +137 -26
  158. package/template/workflows/specdev/common/schemas/logic-prototype.schema.json +62 -0
  159. package/template/workflows/specdev/common/schemas/pull-request.schema.json +90 -0
  160. package/template/workflows/specdev/common/schemas/retrospective.schema.json +58 -0
  161. package/template/workflows/specdev/common/schemas/triage-run.schema.json +149 -0
  162. package/template/workflows/specdev/common/schemas/triage.schema.json +117 -15
  163. package/template/workflows/specdev/common/tools/delivery-artifacts.mjs +95 -0
  164. package/template/workflows/specdev/common/tools/validate-specdev.mjs +60 -19
  165. package/template/workflows/specdev/runtime-contract.json +4 -2
  166. package/template/skills/archive-and-consolidate/references/entry-procedure.md +0 -178
  167. package/template/skills/docs-sync/references/entry-procedure.md +0 -3
  168. package/template/skills/engineering-standards-builder/references/entry-procedure.md +0 -154
  169. package/template/skills/git-history-squash/references/entry-procedure.md +0 -94
  170. package/template/skills/github-npm-ops/SKILL.md +0 -19
  171. package/template/skills/github-npm-ops/references/ci-and-security-ops.md +0 -178
  172. package/template/skills/github-npm-ops/references/entry-procedure.md +0 -25
  173. package/template/skills/github-npm-ops/references/failure-recovery.md +0 -123
  174. package/template/skills/github-npm-ops/references/issue-pr-triage.md +0 -227
  175. package/template/skills/github-npm-ops/references/issue-transport.md +0 -26
  176. package/template/skills/github-npm-ops/references/package-json-checklist.md +0 -171
  177. package/template/skills/github-npm-ops/references/preflight-checklist.md +0 -39
  178. package/template/skills/github-npm-ops/references/publish-detection.md +0 -68
  179. package/template/skills/github-npm-ops/references/release-notes-injection.md +0 -238
  180. package/template/skills/github-npm-ops/references/release-pipeline.md +0 -108
  181. package/template/skills/github-npm-ops/references/setup-npm-token.md +0 -63
  182. package/template/skills/github-npm-ops/references/troubleshooting-playbook.md +0 -293
  183. package/template/skills/github-npm-ops/references/version-bump-flow.md +0 -217
  184. package/template/skills/github-npm-ops/references/workflow-yaml-reference.md +0 -268
  185. package/template/skills/github-npm-ops/scripts/issue-transport.mjs +0 -227
  186. package/template/skills/optimize-codex-config/references/entry-procedure.md +0 -78
  187. package/template/skills/speculo-retro/SKILL.md +0 -19
  188. package/template/skills/upstream-fork-sync/references/entry-procedure.md +0 -78
  189. package/template/skills/writing-great-skills/SKILL.md +0 -23
  190. /package/template/skills/{writing-great-skills → writing-for-agents}/references/document-contract.md +0 -0
  191. /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/adr-format.md +0 -0
  192. /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/context-format.md +0 -0
  193. /package/template/workflows/specdev/{I-implement → common/rules}/design-it-twice.md +0 -0
  194. /package/template/workflows/specdev/{G-grill-with-docs/domain-modeling-rules.md → common/rules/domain-modeling.md} +0 -0
@@ -1,26 +0,0 @@
1
- # GitHub Issue Transport
2
-
3
- 本合同提供 GitHub 的读取和受控写入原语,不承担 SpecDev tracker、change、Ticket、Map 或报告所有权。
4
-
5
- ## 操作
6
-
7
- - `issue-read`:读取 title、body、state、URL、author、labels、时间与全部可见评论。
8
- - `pr-read`:读取 PR 正文、评论、文件列表以及不可变 base/head SHA。
9
- - `issue-search`:按 query 返回候选,用于去重。
10
- - `issue-create`:默认 dry-run;调用方确认后使用 `--apply`。
11
- - `issue-comment-close`:按 marker 幂等评论并关闭;默认 dry-run,只有调用方确认后使用 `--apply`。
12
-
13
- 脚本:`scripts/issue-transport.mjs`。所有参数通过 argv 传递,不使用 shell 拼接;输出为 JSON,失败退出非零。
14
-
15
- ## 写入边界
16
-
17
- 调用方必须在执行前展示 repo、Issue、标题或评论、labels/reason 和准确动作,并取得本次明确授权。脚本的 `--apply` 只表示调用方已经完成该确认,不替代授权本身。
18
-
19
- 不得把 token、Cookie、认证输出、机器绝对路径或包含秘密的正文写入长期工件。部分失败由调用方保存已完成步骤和恢复条件;不得因远程失败回滚本地事实。
20
-
21
- ## 完成标准
22
-
23
- - 读取结果可以冻结为调用方拥有的工件;
24
- - dry-run 的外部写入为零;
25
- - comment-close 的 marker 使重试不会重复评论;
26
- - 成功结论来自执行后的远程重读。
@@ -1,171 +0,0 @@
1
- # package.json 发布前字段清单
2
-
3
- 发布失败的一半原因都是 `package.json` 少字段或字段错位。按这张清单逐项确认。
4
-
5
- ## 必填字段
6
-
7
- ### name
8
-
9
- - 普通包:全局唯一,小写 + 连字符(如 `my-cli`)
10
- - Scoped 包:`@scope/name`,必须先在 npm 上拥有 scope
11
- - **首次发布前用 `npm view <name>` 查询是否被占用**;返回 404 才可用
12
-
13
- ```bash
14
- npm view my-cli # 404 = 可用;有输出 = 已占用
15
- npm view @scope/my-cli # 首次发布会 404,正常
16
- ```
17
-
18
- ### version
19
-
20
- - 遵循 SemVer(MAJOR.MINOR.PATCH)
21
- - 必须与要发布的 git tag 严格匹配:tag `v0.0.2` ↔ version `0.0.2`
22
- - npm **不允许重复发布同一个 version**,即使之前 unpublished 也不行(24h 内)
23
-
24
- ### repository
25
-
26
- **npm provenance 强制要求这个字段**,缺失会报 `E422`。
27
-
28
- ```json
29
- {
30
- "repository": {
31
- "type": "git",
32
- "url": "https://github.com/owner/my-cli"
33
- }
34
- }
35
- ```
36
-
37
- - `url` 必须指向实际托管 workflow 的 GitHub 仓库
38
- - 注意大小写:GitHub 虽不区分,但 provenance 验证严格匹配
39
-
40
- ### license
41
-
42
- SPDX 标识符(如 `MIT`、`Apache-2.0`、`ISC`)。别写 `LICENSE.md` 或随意字符串。
43
-
44
- ## CLI 包专用字段
45
-
46
- ### bin
47
-
48
- 命令入口。路径必须以 `./` 开头:
49
-
50
- ```json
51
- {
52
- "bin": {
53
- "my-cli": "./dist/cli/index.js"
54
- }
55
- }
56
- ```
57
-
58
- 入口文件必须:
59
-
60
- 1. 有可执行权限(`chmod +x`,或通过 `scripts/inject-shebang.mjs` 注入 shebang)
61
- 2. 首行是 `#!/usr/bin/env node`
62
- 3. 是 ESM(`"type": "module"` 时)或 CJS,与 package 一致
63
-
64
- ### files
65
-
66
- 显式允许列表,避免把源码、测试、`.env` 发到 npm:
67
-
68
- ```json
69
- {
70
- "files": [
71
- "dist",
72
- "templates",
73
- "!dist/**/*.test.js",
74
- "!dist/**/__tests__",
75
- "!dist/**/*.map"
76
- ]
77
- }
78
- ```
79
-
80
- - 不写 `files` 时,npm 走 `.gitignore` 加一堆默认规则,通常会漏发或误发
81
- - 发布前用 `npm pack --dry-run` 看看 tarball 实际内容
82
-
83
- ## 推荐但可选字段
84
-
85
- ### description / keywords
86
-
87
- 影响 npm 搜索结果,写清楚。
88
-
89
- ### homepage / bugs
90
-
91
- ```json
92
- {
93
- "homepage": "https://github.com/owner/my-cli#readme",
94
- "bugs": {
95
- "url": "https://github.com/owner/my-cli/issues"
96
- }
97
- }
98
- ```
99
-
100
- 显示在 npm 包页面,方便用户找文档和报问题。
101
-
102
- ### engines
103
-
104
- ```json
105
- {
106
- "engines": {
107
- "node": ">=24.14.1"
108
- }
109
- }
110
- ```
111
-
112
- 声明最低 Node 版本;npm 会在安装时提示(但不会阻止)。
113
-
114
- ### type / exports
115
-
116
- ESM 包:
117
-
118
- ```json
119
- {
120
- "type": "module",
121
- "exports": {
122
- ".": {
123
- "types": "./dist/index.d.ts",
124
- "default": "./dist/index.js"
125
- }
126
- }
127
- }
128
- ```
129
-
130
- ## scripts
131
-
132
- ### prepublishOnly
133
-
134
- 发布前的质量闸门。仅在 `npm publish` 前执行(`npm install` 不触发):
135
-
136
- ```json
137
- {
138
- "scripts": {
139
- "prepublishOnly": "pnpm check"
140
- }
141
- }
142
- ```
143
-
144
- `pnpm check` 通常是 `pnpm lint && pnpm test && pnpm build`。
145
-
146
- ### 不要用的 scripts
147
-
148
- - `prepublish` — 已废弃,会在 `install` 时也触发,容易误伤
149
- - `prepare` — 在 `install` 时也跑,写构建命令会导致普通安装变慢
150
-
151
- ## 发布前自检流程
152
-
153
- ```bash
154
- # 1. 检查 name 可用(首次发布)
155
- npm view @scope/my-cli
156
-
157
- # 2. 版本一致性
158
- node -e "console.log(require('./package.json').version)"
159
- git tag --list 'v*' | sort -V | tail -3
160
-
161
- # 3. tarball 内容预览
162
- npm pack --dry-run
163
-
164
- # 4. 运行质量闸门
165
- pnpm check
166
-
167
- # 5. 预演发布(不会真的推送)
168
- npm publish --dry-run --access public --provenance
169
- ```
170
-
171
- 如果 5 个命令都正常,再执行真正的 `git tag && git push origin <tag>` 触发 CI 发布。
@@ -1,39 +0,0 @@
1
- # Phase 0 — 前置检测完整清单
2
-
3
- > 本文件是发布编排流程([release-pipeline.md](release-pipeline.md))Phase 0 的「展开形态」。编排正文只列出核心前置;这里给出 11 项完整探测、失败信号与建议修复。
4
- > 全部探测都是**只读**的,不会修改任何文件。任一项不通过 → 命令终止,输出修复建议;不要尝试自动跳过。
5
-
6
- ## 探测矩阵
7
-
8
- | # | 项 | 探测命令 | 通过判定 | 失败建议 |
9
- |---|----|---------|---------|---------|
10
- | 1 | 当前分支 | `git rev-parse --abbrev-ref HEAD` | 输出 = 仓库声明的发布分支(默认 `main`) | `git checkout main` 后重新触发;或显式声明本仓库的发布分支 |
11
- | 2 | 工作区干净 | `git status --porcelain` | 输出为空 | 先 stash / commit;不允许 `git stash` 后立刻发版(stash 内容易丢失) |
12
- | 3 | 远端可达 | `git ls-remote --exit-code origin` | 退出码 0 | 检查网络 / SSH key / `gh auth status` |
13
- | 4 | gh 已登录 | `gh auth status` | 含 `Logged in to github.com` | `gh auth login` |
14
- | 5 | gh 仓库权限 | `gh repo view --json viewerCanAdminister` | `viewerCanAdminister == true` 或至少 push 权限 | 联系仓库管理员;或 fork 后申请 PR 流程 |
15
- | 6 | Node 版本 | `node --version` | ≥ `package.json#engines.node` | `nvm use` / `fnm use` / 升级本机 Node |
16
- | 7 | 包管理器 | `pnpm --version` (或 `npm` / `yarn`) | 版本 ≥ 仓库 lockfile 隐含版本 | 安装匹配版本;不要随意切换包管理器 |
17
- | 8 | release.yml 存在 | `test -f .github/workflows/release.yml` | 文件存在 | 转 `github-npm-ops` skill 的 `references/workflow-yaml-reference.md` 先落该文件 |
18
- | 9 | release.yml 形态 | 见 [publish-detection.md](publish-detection.md) | 输出 `PUBLISH_TO_NPM=true` 或 `false` | 见 publish-detection 文档的判定矩阵 |
19
- | 10 | docs-sync state | 对 `<Path>{roots.state}/commands/docs-sync/state.json</Path>` 执行存在性检查与 JSON 解析 | schema v4、scope 已确认,baseline 可解析 | 不存在/未确认 → 走 docs-sync command bootstrap;旧 schema 或损坏 → 停止发布并按 docs-sync state contract 修复,`speculo init` 不解析未登记的 command state |
20
- | 11 | tag 名称冲突 | `git rev-parse vX.Y.Z 2>/dev/null` | 退出码非 0(tag 不存在) | 同 tag 已存在:先确认是否真的失败需要重发;若是则 `git tag -d` + `git push origin :refs/tags/vX.Y.Z`,否则 bump 到下一版本 |
21
-
22
- ## 失败处理总策略
23
-
24
- - 探测项 1–3、6–7:本机环境问题,提示用户人工修复后重跑命令
25
- - 探测项 4–5:GitHub 权限问题,给出对应的 `gh` 命令
26
- - 探测项 8:基础设施缺失,明确转交 `github-npm-ops` skill 而不是在本命令里现写 release.yml
27
- - 探测项 9:影响 Phase 5 的分支选择,**不阻塞**命令执行(仅决定后续是否做 npm view 校验)
28
- - 探测项 10:影响 Phase 2 是否进入 docs-sync 主流程
29
- - 探测项 11:直接关系到能否打 tag,必须在 Phase 0 阶段就排除
30
-
31
- ## 与后续 Phase 的边界
32
-
33
- Phase 0 只做**只读探测**,不执行任何修复 SOP:
34
-
35
- - 提交与版本操作在 Phase 1 / Phase 3(见 [version-bump-flow.md](version-bump-flow.md))
36
- - 文档同步在 Phase 2 / Phase 6(由调用方执行 `docs-sync` command)
37
- - 发布监控、验证与恢复在 Phase 4 / 5(见 [release-pipeline.md](release-pipeline.md)、[failure-recovery.md](failure-recovery.md))
38
-
39
- 如果 Phase 0 嗅探到的状态需要某个修复 SOP(如 release.yml 缺失),明确转交对应 reference,不要在前置检测阶段现场修复。
@@ -1,68 +0,0 @@
1
- # Release.yml 是否含 npm publish 的判定脚本
2
-
3
- > 用于决定 Phase 5 是否做 npm 端校验。命令正文只展示了核心 grep;这里给出完整模式集合、第三方 action 清单与误判排除策略。
4
-
5
- ## 判定输出
6
-
7
- ```bash
8
- RELEASE_YML=".github/workflows/release.yml"
9
-
10
- if [ ! -f "$RELEASE_YML" ]; then
11
- echo "RELEASE_YML_MISSING=true"
12
- exit 0
13
- fi
14
-
15
- # 主判定:是否含 npm publish 步骤
16
- if grep -Eq 'npm[[:space:]]+publish|run:[[:space:]]*pnpm[[:space:]]+publish|run:[[:space:]]*yarn[[:space:]]+publish|JS-DevTools/npm-publish|cycjimmy/semantic-release-action|changesets/action' "$RELEASE_YML"; then
17
- echo "PUBLISH_TO_NPM=true"
18
- else
19
- echo "PUBLISH_TO_NPM=false"
20
- fi
21
- ```
22
-
23
- ## 模式集合
24
-
25
- `PUBLISH_TO_NPM=true` 命中下列任一行时为真:
26
-
27
- | 模式 | 形态 | 说明 |
28
- |------|------|------|
29
- | `npm publish` | `run: npm publish --provenance --access public` | 官方 npm CLI |
30
- | `pnpm publish` | `run: pnpm publish --no-git-checks` | pnpm 包管理器 |
31
- | `yarn publish` | `run: yarn publish --new-version $VERSION` | 旧 yarn / berry |
32
- | `JS-DevTools/npm-publish@vN` | `uses: JS-DevTools/npm-publish@v3` | 第三方封装 action |
33
- | `cycjimmy/semantic-release-action@vN` | `uses: cycjimmy/semantic-release-action@v4` | semantic-release 流水线 |
34
- | `changesets/action@vN` | `uses: changesets/action@v1` 且配置 `publish:` 输入 | Changesets 风格的多包发布 |
35
-
36
- ## 误判排除
37
-
38
- 下列形态**不应**触发 `PUBLISH_TO_NPM=true`:
39
-
40
- | 形态 | 是否触发 | 原因 |
41
- |------|---------|------|
42
- | `# npm publish` 注释行 | ❌ | grep `-E` 默认匹配整行;如需更严格可加 `^[^#]*` 锚定 |
43
- | `description: 'Run npm publish ...'` | ⚠️ 可能误命中 | 收紧 grep 为 `run:[[:space:]]*npm[[:space:]]+publish` 即可避免 |
44
- | `npm publish --dry-run` | ✅ 仍命中 | 视作真发布意图;如需排除,可在判定后追加 `--dry-run` 检查并手动降级 |
45
- | `npm pack` | ❌ | `pack` 不是 `publish` |
46
- | 仅 `softprops/action-gh-release` | ❌ | 这是 GitHub Release 创建器,不是 npm publish |
47
-
48
- ## 收紧版(推荐用于精确判定)
49
-
50
- ```bash
51
- grep -E '^\s*(run:\s*(npm|pnpm|yarn)\s+publish|uses:\s*(JS-DevTools/npm-publish|cycjimmy/semantic-release-action|changesets/action))\b' "$RELEASE_YML"
52
- ```
53
-
54
- > 如果仓库使用了非主流的发布方式(如自写 shell 脚本里调用 `npm publish`),grep 仍可能漏判。
55
- > 漏判后果:Phase 5 跳过 `npm view` 校验。这是**安全侧**漏判(不会误报"未发布"),但用户应在该仓库的 README 或 SKILL 注释里明确发布方式,避免歧义。
56
-
57
- ## 多 workflow 文件的处理
58
-
59
- 若仓库有多个 release 相关 workflow(如 `release.yml` + `publish-canary.yml`),默认只看 `release.yml`。
60
- 如需扩展,在调用方 workflow 或项目上下文中声明 `releaseWorkflowPaths: [...]`,执行时按该列表逐个判定。
61
-
62
- ## 与 Phase 5 的衔接
63
-
64
- | 嗅探结果 | Phase 5 行为 |
65
- |---------|-------------|
66
- | `PUBLISH_TO_NPM=true` | 跑 `gh release view` + `gh run` + `npm view` 三端 |
67
- | `PUBLISH_TO_NPM=false` | 仅跑 `gh release view` + `gh run` 两端,并向用户输出「本仓库 release.yml 不含 npm publish 步骤」提示 |
68
- | `RELEASE_YML_MISSING=true` | Phase 0 直接终止,不进入后续 phase |
@@ -1,238 +0,0 @@
1
- # CHANGELOG → GitHub Release notes 注入
2
-
3
- 让每次 `git push origin vX.Y.Z` 触发的 GitHub Release **正文非空**、**与 CHANGELOG 段落严格一致**的标准方案。
4
-
5
- ## 1. 为什么 GitHub Release 默认是空的
6
-
7
- `softprops/action-gh-release@v2` 仅设 `generate_release_notes: true` 时,GitHub 内部调用的是 **REST API `POST /repos/{owner}/{repo}/releases/generate-notes`**,该接口的输入是「上一个 tag → 当前 tag」之间的 **commit + PR + label**,优先取 PR 标题做分类。
8
-
9
- 两种典型场景下生成器会"贫瘠":
10
-
11
- | 场景 | 生成器输出 | 原因 |
12
- |------|----------|------|
13
- | 直 push main(无 PR 流程) | 仅 `Full Changelog: vA...vB` 一行 | 生成器没有 PR 可分类,只能给 compare 链接 |
14
- | 有 PR 但仓库没有 `.github/release.yml` | 全部 PR 都被塞进 "What's Changed" 一节 | 没有 label → 章节映射 |
15
-
16
- 而仓库通常已经维护了 `CHANGELOG.md`(Keep a Changelog 格式)。**正确做法是把 CHANGELOG 段落作为 Release 正文的事实来源**,自动生成器仅作为补充链接。
17
-
18
- ## 2. 注入方案
19
-
20
- 核心思路:在 workflow 里加一步,从 `CHANGELOG.md` 抽取当前 tag 对应的版本段落,写到 `release-notes.md`,再通过 `softprops/action-gh-release` 的 `body_path` 注入。
21
-
22
- ### 2.1 完整 workflow 步骤
23
-
24
- 加到 `Verify bin entry` 之后、`Publish to npm` 之前(也可以放 publish 之后,只要在 Create GitHub Release 之前):
25
-
26
- ```yaml
27
- - name: Extract release notes from CHANGELOG.md
28
- run: |
29
- VERSION="${GITHUB_REF_NAME#v}"
30
- awk -v v="$VERSION" '
31
- $0 ~ "^## \\["v"\\]" { found=1; print; next }
32
- found && /^## \[/ { exit }
33
- found && /^---[[:space:]]*$/ { next }
34
- found { print }
35
- ' CHANGELOG.md > release-notes.md
36
-
37
- if [ ! -s release-notes.md ]; then
38
- echo "::warning::CHANGELOG.md 中未找到 [$VERSION] 段落,回退到自动生成。"
39
- echo "See [CHANGELOG.md](https://github.com/${{ github.repository }}/blob/main/CHANGELOG.md) for details." > release-notes.md
40
- fi
41
-
42
- echo "--- Release notes preview ---"
43
- cat release-notes.md
44
- echo "-----------------------------"
45
-
46
- - name: Create GitHub Release
47
- uses: softprops/action-gh-release@v2
48
- if: success()
49
- with:
50
- tag_name: ${{ github.ref_name }}
51
- name: Release ${{ github.ref_name }}
52
- body_path: release-notes.md # ← 关键
53
- generate_release_notes: true # ← 与 body_path 共存,不冲突
54
- draft: false
55
- prerelease: false
56
- env:
57
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58
- ```
59
-
60
- ### 2.2 awk 抽取规则解释
61
-
62
- ```awk
63
- $0 ~ "^## \\["v"\\]" { found=1; print; next } # 1. 命中 "## [X.Y.Z]" 起始锚点,开关打开,打印当行
64
- found && /^## \[/ { exit } # 2. 已在段落内,遇到下一个 "## [" 立刻退出
65
- found && /^---[[:space:]]*$/ { next } # 3. 跳过 "---" 分隔符(GitHub Release 不需要)
66
- found { print } # 4. 段落内的其他行原样输出
67
- ```
68
-
69
- 边界用例:
70
-
71
- - **段落是 CHANGELOG 末尾**:没有下一个 `## [`,awk 跑到 EOF 自然结束
72
- - **存在 `[Unreleased]` 段落**:不会被误抓,因为锚点要求精确匹配 `[X.Y.Z]` 形式
73
- - **版本号含连字符(rc / beta)**:`0.0.10-rc1` 也能匹配,因为 awk 把 `v` 当字面量
74
- - **CHANGELOG 缺该段**:`-s` 测试为空 → 写入兜底文案 + 输出 warning
75
-
76
- ### 2.3 `body_path` + `generate_release_notes` 共存语义
77
-
78
- `softprops/action-gh-release@v2` 在两者同时存在时:
79
-
80
- - **正文头部**:`body_path` 文件内容(你的 CHANGELOG 段落)
81
- - **正文尾部**:GitHub 自动生成的 "What's Changed" + "Full Changelog" compare 链接
82
-
83
- 这是最优组合:**人写的精炼说明 + 机器可追溯的 PR/commit 索引**。
84
-
85
- ## 3. 事后修复历史 Release(已发布版本正文为空)
86
-
87
- GitHub Release 的正文(body)**事后可改**(tag 不可改、npm 包不可改、但 Release body 可改)。两种方式:
88
-
89
- ### 3.1 命令行(推荐)
90
-
91
- `notes_file` 只是一次性传给 `gh --notes-file` 的中间文件;若需要保留回填记录或 release notes,由调用方写入 `<Path>{roots.state}/commands/{command}/{date}-{scope}-{topic}[-NN].md</Path>`。
92
-
93
- ```bash
94
- VERSION="0.0.10"
95
- notes_file="$(mktemp -t speculo-release-notes.XXXXXX)"
96
- trap 'rm -f "$notes_file"' EXIT
97
-
98
- awk -v v="$VERSION" '
99
- $0 ~ "^## \\["v"\\]" { found=1; print; next }
100
- found && /^## \[/ { exit }
101
- found && /^---[[:space:]]*$/ { next }
102
- found { print }
103
- ' CHANGELOG.md > "$notes_file" && \
104
- gh release edit "v$VERSION" --notes-file "$notes_file"
105
- ```
106
-
107
- ### 3.2 GitHub UI
108
-
109
- 进入 `https://github.com/<owner>/<repo>/releases/tag/vX.Y.Z`,右上角铅笔图标 → 粘贴 CHANGELOG 段落 → Update release。
110
-
111
- ### 3.3 批量回填多个历史版本
112
-
113
- ```bash
114
- notes_file="$(mktemp -t speculo-release-notes.XXXXXX)"
115
- trap 'rm -f "$notes_file"' EXIT
116
-
117
- for v in 0.0.7 0.0.8 0.0.9; do
118
- awk -v ver="$v" '
119
- $0 ~ "^## \\["ver"\\]" { found=1; print; next }
120
- found && /^## \[/ { exit }
121
- found && /^---[[:space:]]*$/ { next }
122
- found { print }
123
- ' CHANGELOG.md > "$notes_file"
124
-
125
- if [ -s "$notes_file" ]; then
126
- gh release edit "v$v" --notes-file "$notes_file"
127
- echo "✓ v$v"
128
- else
129
- echo "✗ v$v: CHANGELOG 中无对应段落,跳过"
130
- fi
131
- done
132
- ```
133
-
134
- ## 4. 进阶:走 PR 流程的项目
135
-
136
- 若仓库以 PR 为主、合并产生 commit,推荐 **同时**保留 CHANGELOG 注入 + 配置 `.github/release.yml` 让自动生成器分类更友好。
137
-
138
- ### 4.1 `.github/release.yml`(GitHub 原生分类配置)
139
-
140
- ```yaml
141
- # .github/release.yml
142
- changelog:
143
- exclude:
144
- labels:
145
- - ignore-for-release
146
- - dependencies # 可选:依赖升级单独成节
147
- categories:
148
- - title: 🚀 Features
149
- labels:
150
- - feat
151
- - feature
152
- - enhancement
153
- - title: 🐛 Bug Fixes
154
- labels:
155
- - fix
156
- - bug
157
- - title: 📚 Documentation
158
- labels:
159
- - docs
160
- - documentation
161
- - title: ♻️ Refactoring
162
- labels:
163
- - refactor
164
- - title: 🧪 Testing
165
- labels:
166
- - test
167
- - title: 🔧 Maintenance
168
- labels:
169
- - chore
170
- - ci
171
- - title: Other Changes
172
- labels:
173
- - "*"
174
- ```
175
-
176
- 效果:`generate_release_notes` 自动产出的 "What's Changed" 会被分类到上述章节中,与 CHANGELOG 段落叠加在 Release 正文内。
177
-
178
- ### 4.2 配套的 PR label 自动化
179
-
180
- 参考仓库已有 `.github/labeler.yml` + `.github/workflows/label-pr.yml`,基于改动路径自动打 label。也可让 PR 模板提示作者按 Conventional Commits 选择类型。
181
-
182
- ## 5. 多语言 CHANGELOG 处理
183
-
184
- 如果项目同时维护 `CHANGELOG.md` + `CHANGELOG-ZH.md`,Release 正文应优先取**主语言**(通常英文)。两种策略:
185
-
186
- ### A. workflow 选择主语言(简单)
187
-
188
- ```yaml
189
- - name: Extract release notes
190
- run: |
191
- # 主语言文件名作为输入
192
- awk -v v="${GITHUB_REF_NAME#v}" '...' CHANGELOG.md > release-notes.md
193
- ```
194
-
195
- ### B. workflow 拼接双语(完整)
196
-
197
- ```yaml
198
- - name: Extract release notes (bilingual)
199
- run: |
200
- VERSION="${GITHUB_REF_NAME#v}"
201
- EXTRACT='$0 ~ "^## \\["v"\\]" { found=1; print; next } found && /^## \[/ { exit } found && /^---[[:space:]]*$/ { next } found { print }'
202
-
203
- {
204
- awk -v v="$VERSION" "$EXTRACT" CHANGELOG.md
205
- echo
206
- echo "---"
207
- echo
208
- echo "### 中文版本说明"
209
- echo
210
- awk -v v="$VERSION" "$EXTRACT" CHANGELOG-ZH.md
211
- } > release-notes.md
212
- ```
213
-
214
- ## 6. 常见坑位
215
-
216
- | 坑 | 现象 | 解法 |
217
- |---|------|------|
218
- | `body_path` 文件不存在 | action 失败 `Could not find the body_path` | 加 `if [ ! -s release-notes.md ]` 兜底写入 |
219
- | awk 没匹配到 | release-notes.md 为空,Release 正文兜底文案 | 检查 CHANGELOG 段落标题与 tag 是否对应(`v0.0.10` ↔ `## [0.0.10]`) |
220
- | awk 多匹配(同一版本写了两次) | Release 正文重复内容 | CHANGELOG 是 source of truth,先去重 |
221
- | 全角中括号 `【】` 被当锚点 | 抽取失败 | CHANGELOG 标题统一用半角 `[` |
222
- | body_path 文件含 BOM | Release 渲染异常 | 用 `sed -i '1s/^\xef\xbb\xbf//' release-notes.md` 去 BOM |
223
-
224
- ## 7. 验证
225
-
226
- 每次发布后必查:
227
-
228
- ```bash
229
- # Release body 必须非空且包含 CHANGELOG 关键章节
230
- gh release view "v$VERSION" --json body --jq '.body' | head -20
231
-
232
- # 三端齐绿才算发布完成
233
- npm view @scope/pkg version
234
- gh release view "v$VERSION" --json isDraft,isPrerelease,publishedAt
235
- gh run view <run-id> --json conclusion,jobs --jq '{conclusion, steps: [.jobs[].steps[] | select(.name | contains("Extract") or contains("Release")) | {name, conclusion}]}'
236
- ```
237
-
238
- `Extract release notes` 步骤未 success → Release 正文将走兜底文案,需排查 awk 是否抽空。
@@ -1,108 +0,0 @@
1
- # npm + GitHub Release 编排
2
-
3
- 把一次 npm 包发布拆成可验证的单向流水线:前置检查 -> 普通改动 commit -> docs-sync -> release commit -> tag -> workflow 监控 -> 三端验证 -> docs-sync 记录 release 节点。
4
-
5
- ## Iron Law
6
-
7
- - 禁止提交破坏构建的代码;release 前必须运行仓库声明的 lint / test / build 或等价质量闸。
8
- - docs-sync 必须由调用方按 `<Path>{roots.commands}/docs-sync.md</Path>` 执行;输入起点来自最后修改 state 文件的 commit,终点是运行前清洁后的 HEAD,并写入 `last_range`。
9
- - tag 必须精确指向 release commit,即包含 `package.json` version bump 与 CHANGELOG 迁移的 commit;禁止指向后续 docs / state commit。
10
- - npm 已成功上传后,同一 version 不可重发;不要通过删 tag 或 unpublish 试图覆盖。
11
-
12
- ## Phase 0 — 前置检测
13
-
14
- 读取 `preflight-checklist.md` 和 `publish-detection.md`,固定确认:
15
-
16
- - 当前分支是发布分支,默认 `main`
17
- - 工作区干净,远端可达,`gh auth status` 正常
18
- - Node 与包管理器满足仓库声明
19
- - `.github/workflows/release.yml` 存在
20
- - 已确定 `PUBLISH_TO_NPM=true | false`
21
- - `<Path>{roots.state}/commands/docs-sync/state.json</Path>` 存在且可解析;不存在时转 docs-sync command 的首次 bootstrap
22
- - 目标 tag `vX.Y.Z` 不存在,除非正在执行明确的失败恢复
23
-
24
- 任一项不通过就停止,输出修复建议。
25
-
26
- ## Phase 1 — 普通改动 commit
27
-
28
- - 运行仓库质量闸:优先 `pnpm check`,否则按项目脚本组合 lint / test / build。
29
- - 审查提交粒度;不把无关修改塞进一个 commit。
30
- - 暂存显式路径,避免 `git add .` 纳入噪声。
31
- - 使用 Conventional Commits;body 说明做了什么和为什么。
32
-
33
- ## Phase 2 — Docs Sync
34
-
35
- - 由调用方执行 `<Path>{roots.commands}/docs-sync.md</Path>`。
36
- - 只修改全局 state 与 workflow sidecar 已确认范围中需要同步的文档或知识资产。
37
- - CHANGELOG 类文档只写 `[Unreleased]`,保留该段落。
38
- - 本阶段由 docs-sync 自动提交文档、报告与 state;最终 release commit 仍在 Phase 3 创建,发布后再由 Phase 6 记录为新输入终点。
39
-
40
- ## Phase 3 — 版本 bump + release commit + tag
41
-
42
- 读取 `version-bump-flow.md`。
43
-
44
- - 将 CHANGELOG 的 `[Unreleased]` 内容迁移到 `## [X.Y.Z] - YYYY-MM-DD` 或项目既有等价格式,并重新保留空 `[Unreleased]`。
45
- - 将 `package.json#version` 改为 `X.Y.Z`;tag 使用 `vX.Y.Z`。
46
- - 运行质量闸;除非调用方明确记录外部预演证据,不跳过。
47
- - release commit 只包含版本 bump 与 CHANGELOG 迁移,提交信息为 `chore(release): vX.Y.Z`。
48
- - 记录 `RELEASE_COMMIT_SHA`。
49
- - 先 push 发布分支,再 `git tag vX.Y.Z $RELEASE_COMMIT_SHA`,再 push tag。
50
-
51
- ## Phase 4 — 监控 release workflow
52
-
53
- 用 `gh run list` 找到 head SHA 等于 `RELEASE_COMMIT_SHA` 的 release run,再 `gh run watch --exit-status`。
54
-
55
- 重点检查:
56
-
57
- - Verify tag matches package version
58
- - lint / tests / build / bin entry
59
- - Extract release notes from CHANGELOG
60
- - Publish to npm(仅 `PUBLISH_TO_NPM=true`)
61
- - Create GitHub Release
62
-
63
- 失败时进入 `failure-recovery.md` 和 `troubleshooting-playbook.md`。
64
-
65
- ## Phase 5 — 三端验证
66
-
67
- 始终验证:
68
-
69
- ```bash
70
- gh release view "vX.Y.Z" --json name,tagName,isDraft,isPrerelease,body
71
- gh run list --workflow release.yml --limit 1 --json conclusion,headSha
72
- ```
73
-
74
- 判定:
75
-
76
- - Release 非 draft、非 prerelease
77
- - Release body 非空,且包含 CHANGELOG 段落;仅 `Full Changelog` 一行视为残缺
78
- - workflow conclusion 为 success,headSha 等于 `RELEASE_COMMIT_SHA`
79
-
80
- 仅当 `PUBLISH_TO_NPM=true` 时验证:
81
-
82
- ```bash
83
- npm view "<package-name>" version
84
- npm view "<package-name>" dist-tags
85
- ```
86
-
87
- 判定 version 与 `dist-tags.latest` 均为 `X.Y.Z`。
88
-
89
- ## Phase 6 — 记录 release 输入节点
90
-
91
- 仅当 Phase 1-5 全绿时执行。再次调用 `<Path>{roots.commands}/docs-sync.md</Path>`,并确认运行前 `HEAD` 等于 `RELEASE_COMMIT_SHA`:
92
-
93
- - state 的 `last_range.to_sha` 必须等于 `RELEASE_COMMIT_SHA`。
94
- - `last_range.from_sha` 来自最后修改旧 state 的 commit,或迁移期 explicit baseline。
95
- - docs-sync 写入 release 后报告/state commit;tag 继续精确指向 release commit,不移动。
96
-
97
- 本 skill 不直接改 state 或 workflow sidecar;原子写入、范围检查和本地 commit 均由 docs-sync command 负责。
98
-
99
- ## 完成报告
100
-
101
- 报告至少包含:
102
-
103
- - 版本号、release commit SHA、tag SHA
104
- - workflow run id 与结论
105
- - GitHub Release 检查结果
106
- - npm 检查结果或跳过原因
107
- - docs-sync `last_range` 与 state-file baseline commit
108
- - 失败恢复或后续建议