@namewta/speculo 1.0.18 → 1.0.20

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 (195) 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 +10 -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 +158 -30
  32. package/template/canonical/canonical-specdev-grill-with-docs.md +155 -33
  33. package/template/canonical/canonical-specdev-spec.md +162 -161
  34. package/template/canonical/canonical-specdev-tickets.md +155 -29
  35. package/template/canonical/canonical-specdev-wayfinder.md +144 -29
  36. package/template/commands/handoff.md +16 -0
  37. package/template/commands/retro.md +12 -10
  38. package/template/skills/archive-and-consolidate/SKILL.md +163 -7
  39. package/template/skills/archive-and-consolidate/references/cleanup-rules.md +1 -1
  40. package/template/skills/docs-sync/references/agents/claude-redirect.md +8 -8
  41. package/template/skills/docs-sync/references/agents/content-contract.md +1 -1
  42. package/template/skills/docs-sync/references/agents/manifest-discovery.md +7 -7
  43. package/template/skills/docs-sync/references/agents/role-classification.md +4 -4
  44. package/template/skills/docs-sync/references/agents-contract.md +1 -1
  45. package/template/skills/engineering-standards-builder/SKILL.md +149 -9
  46. package/template/skills/engineering-standards-builder/agents/openai.yaml +2 -0
  47. package/template/skills/engineering-standards-builder/manifest.txt +2 -1
  48. package/template/skills/engineering-standards-builder/references/rules/09-mechanical-guardrails.md +9 -0
  49. package/template/skills/engineering-standards-builder/scripts/validate-builder.mjs +4 -7
  50. package/template/skills/git-history-squash/SKILL.md +87 -11
  51. package/template/skills/git-history-squash/agents/openai.yaml +2 -0
  52. package/template/skills/optimize-codex-config/SKILL.md +71 -11
  53. package/template/skills/retrospective/SKILL.md +43 -0
  54. package/template/skills/{speculo-retro → retrospective}/references/friction-taxonomy.md +22 -13
  55. package/template/skills/{speculo-retro → retrospective}/references/issue-drafting-sop.md +13 -21
  56. package/template/skills/source-code-zip/SKILL.md +44 -8
  57. package/template/skills/source-code-zip/references/{entry-procedure.md → cli-reference.md} +0 -43
  58. package/template/skills/upstream-fork-sync/SKILL.md +71 -8
  59. package/template/skills/{writing-great-skills → writing-for-agents}/GLOSSARY.md +1 -1
  60. package/template/skills/writing-for-agents/SKILL.md +22 -0
  61. package/template/skills/writing-for-agents/agents/openai.yaml +2 -0
  62. package/template/skills/{writing-great-skills/references/entry-procedure.md → writing-for-agents/references/authoring-principles.md} +2 -9
  63. package/template/workflows/learning/A-archive/A-archive.md +2 -5
  64. package/template/workflows/learning/A-assess-and-plan/A-assess-and-plan.md +2 -5
  65. package/template/workflows/learning/C-consolidate/C-consolidate.md +2 -5
  66. package/template/workflows/learning/G-goal/G-goal.md +5 -23
  67. package/template/workflows/learning/H-homework/H-homework.md +2 -5
  68. package/template/workflows/learning/I-init-setup/I-init-setup.md +4 -9
  69. package/template/workflows/learning/L-lesson/L-lesson.md +2 -5
  70. package/template/workflows/learning/Q-question/Q-question.md +16 -8
  71. package/template/workflows/learning/Q-question/inquiry-template.md +2 -0
  72. package/template/workflows/learning/Q-question/tools/validate-inquiry.mjs +112 -0
  73. package/template/workflows/learning/R-review/R-review.md +3 -6
  74. package/template/workflows/learning/README.md +2 -2
  75. package/template/workflows/learning/common/rules/knowledge-organization.md +1 -1
  76. package/template/workflows/learning/common/rules/mastery-policy.md +1 -1
  77. package/template/workflows/learning/common/skills/socratic-questioning/SKILL.md +1 -1
  78. package/template/workflows/ops/D-project-deploy/D-project-deploy.md +6 -2
  79. package/template/workflows/ops/H-host-manage/H-host-manage.md +10 -18
  80. package/template/workflows/ops/H-host-manage/references/host-profiles.md +21 -0
  81. package/template/workflows/ops/I-initialize/I-initialize.md +4 -4
  82. package/template/workflows/ops/README.md +22 -84
  83. package/template/workflows/ops/S-server-connect/S-server-connect.md +3 -3
  84. package/template/workflows/ops/V-inventory-view/V-inventory-view.md +2 -2
  85. package/template/workflows/ops/common/rules/deployment-layout.md +51 -0
  86. package/template/workflows/ops/common/rules/recovery.md +6 -0
  87. package/template/workflows/ops/common/rules/server-onboarding.md +6 -0
  88. package/template/workflows/ops/common/tests/test_ops.mjs +5 -8
  89. package/template/workflows/ops/common/tests/test_ops_bootstrap.mjs +71 -14
  90. package/template/workflows/ops/common/tests/test_ops_workspace.mjs +17 -8
  91. package/template/workflows/ops/common/tools/opslib/bootstrap.mjs +4 -4
  92. package/template/workflows/ops/common/tools/opslib/transport.mjs +3 -3
  93. package/template/workflows/person/M-mao-zedong-cognitive-os/M-mao-zedong-cognitive-os.md +13 -68
  94. package/template/workflows/person/S-steelman-deliberation/S-steelman-deliberation.md +11 -123
  95. package/template/workflows/person/S-steelman-deliberation/references/state-and-publication.md +86 -0
  96. package/template/workflows/specdev/A-archive-and-consolidate/A-archive-and-consolidate.md +2 -17
  97. package/template/workflows/specdev/A-archive-and-consolidate/consolidation-interview.md +13 -4
  98. package/template/workflows/specdev/C-code-review/C-code-review.md +4 -15
  99. package/template/workflows/specdev/C-code-review/code-review-template.md +4 -0
  100. package/template/workflows/specdev/D-diagnose-bugs/D-diagnose-bugs.md +4 -20
  101. package/template/workflows/specdev/G-grill-with-docs/G-grill-with-docs.md +2 -2
  102. package/template/workflows/specdev/G-grill-with-docs/references/interview-procedure.md +6 -6
  103. package/template/workflows/specdev/I-implement/I-implement.md +2 -2
  104. package/template/workflows/specdev/I-implement/evidence-template.md +8 -0
  105. package/template/workflows/specdev/I-implement/references/implementation-procedure.md +9 -43
  106. package/template/workflows/specdev/I-implement/tdd-rules.md +4 -0
  107. package/template/workflows/specdev/I-init-setup/I-init-setup.md +16 -117
  108. package/template/workflows/specdev/I-init-setup/config-template.json +5 -1
  109. package/template/workflows/specdev/I-init-setup/references/first-setup.md +46 -0
  110. package/template/workflows/specdev/INDEX.md +2 -2
  111. package/template/workflows/specdev/L-learn-change/L-learn-change.md +11 -89
  112. package/template/workflows/specdev/L-learn-change/references/lesson-format.md +47 -0
  113. package/template/workflows/specdev/P-goal-plan/P-goal-plan.md +2 -2
  114. package/template/workflows/specdev/P-goal-plan/planning-modes.md +1 -1
  115. package/template/workflows/specdev/P-prototype/P-prototype.md +7 -17
  116. package/template/workflows/specdev/P-prototype/logic-protocol.md +11 -0
  117. package/template/workflows/specdev/P-prototype/logic-template.md +27 -0
  118. package/template/workflows/specdev/P-prototype/project-preview-protocol.md +9 -0
  119. package/template/workflows/specdev/R-retro/R-retro.md +26 -0
  120. package/template/workflows/specdev/R-retro/retro-template.md +27 -0
  121. package/template/workflows/specdev/R-review-architecture/R-review-architecture.md +19 -57
  122. package/template/workflows/specdev/R-review-architecture/architecture-review-template.md +2 -1
  123. package/template/workflows/specdev/R-review-architecture/references/selected-design.md +23 -0
  124. package/template/workflows/specdev/R-review-architecture/review-rubric.md +2 -2
  125. package/template/workflows/specdev/README.md +17 -6
  126. package/template/workflows/specdev/S-spec/S-spec.md +13 -136
  127. package/template/workflows/specdev/T-tickets/T-tickets.md +6 -2
  128. package/template/workflows/specdev/T-triage/T-triage.md +32 -141
  129. package/template/workflows/specdev/T-triage/capture-protocol.md +1 -1
  130. package/template/workflows/specdev/T-triage/ci-security-protocol.md +11 -0
  131. package/template/workflows/specdev/T-triage/intake-protocol.md +29 -4
  132. package/template/workflows/specdev/T-triage/pr-delivery-protocol.md +13 -0
  133. package/template/workflows/specdev/T-triage/pr-record-template.md +39 -0
  134. package/template/workflows/specdev/T-triage/publish-protocol.md +1 -1
  135. package/template/workflows/specdev/T-triage/queue-protocol.md +7 -0
  136. package/template/workflows/specdev/T-triage/reconcile-protocol.md +1 -1
  137. package/template/workflows/specdev/T-triage/references/issue-pr-policy.md +23 -0
  138. package/template/workflows/specdev/T-triage/references/release-authentication.md +9 -0
  139. package/template/workflows/specdev/T-triage/references/release-notes-injection.md +21 -0
  140. package/template/workflows/specdev/T-triage/references/workflow-yaml-reference.md +37 -0
  141. package/template/workflows/specdev/T-triage/release-preflight.md +13 -0
  142. package/template/workflows/specdev/T-triage/release-protocol.md +12 -0
  143. package/template/workflows/specdev/T-triage/release-recovery.md +18 -0
  144. package/template/workflows/specdev/T-triage/remote-operations.md +25 -0
  145. package/template/workflows/specdev/T-triage/scripts/github-transport.mjs +208 -0
  146. package/template/workflows/specdev/T-triage/source-template.md +7 -0
  147. package/template/workflows/specdev/T-triage/triage-run-template.md +34 -0
  148. package/template/workflows/specdev/T-triage/triage-template.md +4 -1
  149. package/template/workflows/specdev/W-wayfinder/W-wayfinder.md +2 -2
  150. package/template/workflows/specdev/common/rules/artifact-contract.md +7 -0
  151. package/template/workflows/specdev/common/rules/change-completion.md +6 -0
  152. package/template/workflows/specdev/common/rules/deployment-handoff.md +23 -0
  153. package/template/workflows/specdev/common/rules/workflow-routing.md +6 -0
  154. package/template/workflows/specdev/common/rules/workflow-state-and-lifecycle.md +1 -1
  155. package/template/workflows/specdev/common/schemas/config.schema.json +137 -26
  156. package/template/workflows/specdev/common/schemas/logic-prototype.schema.json +62 -0
  157. package/template/workflows/specdev/common/schemas/pull-request.schema.json +90 -0
  158. package/template/workflows/specdev/common/schemas/retrospective.schema.json +58 -0
  159. package/template/workflows/specdev/common/schemas/triage-run.schema.json +149 -0
  160. package/template/workflows/specdev/common/schemas/triage.schema.json +117 -15
  161. package/template/workflows/specdev/common/skills/code-review/SKILL.md +5 -4
  162. package/template/workflows/specdev/common/skills/code-review/references/result-reuse.md +15 -0
  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 -219
  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/speculo-retro/references/entry-procedure.md +0 -23
  189. package/template/skills/upstream-fork-sync/references/entry-procedure.md +0 -78
  190. package/template/skills/writing-great-skills/SKILL.md +0 -23
  191. /package/template/skills/{writing-great-skills → writing-for-agents}/references/document-contract.md +0 -0
  192. /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/adr-format.md +0 -0
  193. /package/template/workflows/specdev/{G-grill-with-docs → common/rules}/context-format.md +0 -0
  194. /package/template/workflows/specdev/{I-implement → common/rules}/design-it-twice.md +0 -0
  195. /package/template/workflows/specdev/{G-grill-with-docs/domain-modeling-rules.md → common/rules/domain-modeling.md} +0 -0
@@ -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
- - 失败恢复或后续建议
@@ -1,63 +0,0 @@
1
- # 配置 npm Token 与 GitHub Secret
2
-
3
- npm 现在强制要求发布时通过 2FA 或等效机制。Classic token 在多数账号设置下会返回 `E403`,必须改用 **Granular Access Token**。
4
-
5
- ## 生成 Granular Access Token
6
-
7
- 1. 登录 [npmjs.com](https://www.npmjs.com),点头像 → **Access Tokens**
8
- 2. 点 **Generate New Token** → 选择 **Granular Access Token**
9
- 3. 关键字段:
10
-
11
- | 字段 | 推荐值 |
12
- | ----------------------- | ------------------------------------------------------------------------------------------ |
13
- | Token name | `<package>-ci-release`(可识别用途) |
14
- | Expiration | 90–365 天;设提醒到期前轮换 |
15
- | Packages and scopes | 选 `Only select packages and scopes`,勾选目标包或整个 scope(如 `@scope`) |
16
- | Permissions | **Read and write** |
17
- | Allowed organizations | 如果在组织下发布,勾选对应组织 |
18
- | Bypass two-factor auth | 勾选(CI 无法交互完成 2FA) |
19
- | Allowed IP ranges | 留空(GitHub Actions runner IP 不固定) |
20
-
21
- 4. 点 **Generate**,**立刻复制** token,关掉页面就再也看不到了
22
-
23
- ## 配置到 GitHub Secret
24
-
25
- 1. 仓库 → **Settings** → **Secrets and variables** → **Actions**
26
- 2. 点 **New repository secret**
27
- 3. `Name: NPM_TOKEN`,`Value: <粘贴 token>`
28
- 4. 点 **Add secret**
29
-
30
- ## 在 workflow 中引用
31
-
32
- ```yaml
33
- - name: Publish to npm
34
- run: npm publish --provenance --access public
35
- env:
36
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
37
- ```
38
-
39
- 重点:变量名必须是 `NODE_AUTH_TOKEN`(`actions/setup-node` 约定),不是 `NPM_TOKEN`。Secret 的名字可以是 `NPM_TOKEN`,但要映射过来。
40
-
41
- ## 验证 token 生效
42
-
43
- 本地不需要这个 token,它只在 CI 使用。如果想本地预演:
44
-
45
- ```bash
46
- echo "//registry.npmjs.org/:_authToken=<token>" >> ~/.npmrc
47
- npm whoami # 应返回你的 npm 用户名
48
- npm publish --dry-run --access public
49
- ```
50
-
51
- 预演完记得把 `.npmrc` 里的这行删掉。
52
-
53
- ## 轮换策略
54
-
55
- - Token 到期前 7 天收到邮件提醒
56
- - 轮换步骤:生成新 token → 更新 GitHub Secret → 在 npm 上 revoke 旧 token
57
- - 如果怀疑泄露:立即在 npm Access Tokens 页面点 **Revoke**,workflow 会在下次运行时失败,再补生成新 token
58
-
59
- ## 常见误区
60
-
61
- - **不要用 Classic Token 的 `Automation` 类型** — 某些账号策略下仍会触发 2FA 检查
62
- - **不要把 token 写进 `.npmrc` 提交** — 只能走 `secrets`
63
- - **不要与个人 publish token 混用** — CI 用专用 token,出问题可独立撤销
@@ -1,293 +0,0 @@
1
- # Release 故障排查手册
2
-
3
- 基于真实失败记录的排查流程。遇到问题先按这个顺序走。
4
-
5
- ## 统一诊断流程
6
-
7
- ```bash
8
- # 1. 找到失败的 run
9
- gh run list --workflow release.yml --limit 5 \
10
- --json databaseId,conclusion,displayTitle
11
-
12
- # 2. 查看失败步骤的日志
13
- gh run view <databaseId> --log-failed 2>&1 \
14
- | grep -E "npm error|npm warn publish|##\[error\]|Error:" \
15
- | head -30
16
-
17
- # 3. 按下面的错误表对应修复
18
- ```
19
-
20
- ## 错误分类与修复
21
-
22
- ### 1. `E404 Not Found - PUT /<pkg>`
23
-
24
- ```
25
- npm error code E404
26
- npm error 404 Not Found - PUT https://registry.npmjs.org/my-cli
27
- npm error 404 The requested resource 'my-cli@0.0.2' could not be found
28
- or you do not have permission to access it.
29
- ```
30
-
31
- **两种原因:**
32
-
33
- - **包名被占用**:别人已注册这个名字,你没权限写入
34
- - **私有包但未创建 scope/org**:scope 不存在
35
-
36
- **诊断:**
37
-
38
- ```bash
39
- npm view <pkg-name> # 有内容说明被占
40
- npm owner ls <pkg-name> # 看当前 owner
41
- ```
42
-
43
- **修复:**
44
-
45
- - 改用 scoped 包名:`@yourname/pkg-name`
46
- - 同步更新 `package.json` 的 `name` 字段
47
- - 若要用现有名字:联系当前 owner 做 transfer,或走 `npm support`
48
-
49
- ### 2. `E403 Two-factor authentication required`
50
-
51
- ```
52
- npm error code E403
53
- npm error 403 403 Forbidden - PUT https://registry.npmjs.org/@scope%2fmy-cli
54
- - Two-factor authentication or granular access token
55
- with bypass 2fa enabled is required to publish packages.
56
- ```
57
-
58
- **原因:** 使用了 Classic Token 或未开启 2FA bypass 的 Granular Token。
59
-
60
- **修复:**
61
-
62
- 1. npm → Access Tokens → **Generate New Token** → **Granular Access Token**
63
- 2. 勾选 **Bypass two-factor authentication**
64
- 3. 选择目标包或 scope,permission 为 **Read and write**
65
- 4. 复制新 token,更新 GitHub Secret `NPM_TOKEN`
66
- 5. 重新触发 workflow(删旧 tag 重推)
67
-
68
- 详见 [setup-npm-token.md](./setup-npm-token.md)。
69
-
70
- ### 3. `EUSAGE Can't generate provenance for new or private package`
71
-
72
- ```
73
- npm error code EUSAGE
74
- npm error Can't generate provenance for new or private package,
75
- you must set `access` to public.
76
- ```
77
-
78
- **原因:** Scoped 包默认 private,首次发布未加 `--access public`。
79
-
80
- **修复:**
81
-
82
- ```yaml
83
- - run: npm publish --provenance --access public
84
- ```
85
-
86
- ### 4. `E422 Error verifying sigstore provenance bundle`
87
-
88
- ```
89
- npm error code E422
90
- npm error 422 Unprocessable Entity - PUT https://registry.npmjs.org/@scope%2fmy-cli
91
- - Error verifying sigstore provenance bundle:
92
- Failed to validate repository information:
93
- package.json: "repository.url" is "", expected to match
94
- "https://github.com/owner/my-cli" from provenance
95
- ```
96
-
97
- **原因:** `package.json` 缺 `repository.url`,或值与实际 GitHub 仓库不匹配。
98
-
99
- **修复:**
100
-
101
- ```json
102
- {
103
- "repository": {
104
- "type": "git",
105
- "url": "https://github.com/owner/my-cli"
106
- }
107
- }
108
- ```
109
-
110
- - URL 不要带 `.git` 后缀也能通过(npm 会归一化)
111
- - 注意大小写:虽然 GitHub 不区分,但 provenance 严格校验,保持与 workflow 运行环境一致
112
-
113
- ### 5. `Tag version does not match package.json version`
114
-
115
- ```
116
- Tag version (0.0.2) does not match package.json version (0.0.1)
117
- ```
118
-
119
- **原因:** 打 tag 前忘记 bump `package.json`,或 bump 后没 commit。
120
-
121
- **修复:**
122
-
123
- ```bash
124
- # 删除错误 tag
125
- git tag -d v0.0.2
126
- git push origin :refs/tags/v0.0.2
127
-
128
- # 修复 package.json
129
- npm version 0.0.2 --no-git-tag-version # 只改文件,不打 tag
130
- git add package.json && git commit -m "chore: bump version to 0.0.2"
131
- git push origin main
132
-
133
- # 重新打 tag
134
- git tag v0.0.2
135
- git push origin v0.0.2
136
- ```
137
-
138
- ### 6. `npm warn publish "bin[name]" script name ... was invalid and removed`
139
-
140
- ```
141
- npm warn publish "bin[my-cli]" script name dist/cli/index.js was invalid and removed
142
- ```
143
-
144
- **原因:** `bin` 路径没有 `./` 前缀,或 npm 版本对该路径格式敏感。
145
-
146
- **修复:** 确认 `package.json` 已经是 `"./dist/cli/index.js"`。如果已经正确但警告仍在,可能是 npm 的误报——检查 npm publish 最终有没有返回 `+ @scope/pkg@version`,有就成功了。
147
-
148
- ### 7. Workflow 根本没触发
149
-
150
- **诊断:**
151
-
152
- ```bash
153
- gh run list --workflow release.yml --limit 3
154
- # 如果最新的那个不在列表里,就是没触发
155
- ```
156
-
157
- **原因:**
158
-
159
- - Tag 名不匹配 `v*` 模式
160
- - Tag 已存在,再次 push 被 Git 拒绝
161
- - 仓库关闭了 Actions
162
-
163
- **修复:**
164
-
165
- ```bash
166
- # 确认 tag 推到远端了
167
- git ls-remote --tags origin | grep v0.0.2
168
-
169
- # 如果旧 tag 残留,先删
170
- git tag -d v0.0.2
171
- git push origin :refs/tags/v0.0.2
172
-
173
- # 重新打
174
- git tag v0.0.2
175
- git push origin v0.0.2
176
- ```
177
-
178
- ### 8. 安装 pnpm 或 Node 失败
179
-
180
- ```
181
- Error: Unable to find 'pnpm' executable
182
- ```
183
-
184
- **修复:** 在 setup 里加:
185
-
186
- ```yaml
187
- - uses: pnpm/action-setup@v2
188
- with:
189
- version: 9 # 匹配 packageManager 字段或 lockfile 格式
190
- ```
191
-
192
- 如果 `package.json` 里写了 `packageManager: "pnpm@9.x.x"`,`pnpm/action-setup` 可不传 `version`,它会自动读取。
193
-
194
- ### 9. `npm ERR! 403 Forbidden - PUT` 但 token 正常
195
-
196
- 可能是包名大小写问题。npm 内部是小写,但 `package.json` 里写了大写:
197
-
198
- ```json
199
- { "name": "MyCli" } // ❌
200
- { "name": "my-cli" } // ✅
201
- ```
202
-
203
- ### 10. GitHub Release 正文为空 / 仅一行 `Full Changelog`
204
-
205
- ```
206
- Release v0.0.10 (Latest)
207
- Full Changelog: v0.0.9...v0.0.10
208
- [Source code (zip)] [Source code (tar.gz)]
209
- ```
210
-
211
- **原因**:`softprops/action-gh-release@v2` 只设了 `generate_release_notes: true`,而 GitHub 自动生成器从 PR 标题 + label 抽取 changelog。直 push main 的仓库没有 PR 流量,生成器只剩 compare 链接可写。
212
-
213
- **修复(workflow 改造)**:在 Create GitHub Release 之前加一步从 `CHANGELOG.md` 抽取段落,再用 `body_path` 注入。完整 YAML 见 [workflow-yaml-reference.md](workflow-yaml-reference.md) 的 `Extract release notes from CHANGELOG.md` 步骤;模式说明见 [release-notes-injection.md](release-notes-injection.md)。
214
-
215
- **修复(事后回填历史 Release,无需重发版)**:按 [release-notes-injection.md](release-notes-injection.md) 抽取 CHANGELOG 段落,再 `gh release edit "v$VERSION" --notes-file "$notes_file"`。
216
-
217
- **诊断**:
218
-
219
- ```bash
220
- # Release body 长度过短就是出问题了
221
- gh release view v0.0.10 --json body --jq '.body | length'
222
-
223
- # workflow 里 Extract release notes 步骤是否存在并 success
224
- gh run view <run-id> --json jobs \
225
- --jq '.jobs[].steps[] | select(.name | test("Extract|Release"))'
226
- ```
227
-
228
- ### 11. `Extract release notes` 步骤报 "release-notes.md is empty"
229
-
230
- **根因**:CHANGELOG 段落标题与 tag 不匹配,awk 抽空。
231
-
232
- **自查**:
233
-
234
- ```bash
235
- # 实际 CHANGELOG 标题
236
- grep '^## \[' CHANGELOG.md | head -5
237
-
238
- # 当前 tag 应当对应的标题
239
- echo "## [${GITHUB_REF_NAME#v}]"
240
- ```
241
-
242
- 常见问题:
243
-
244
- - 全角中括号 `【0.0.10】` 而非半角 `[0.0.10]`
245
- - 版本号有 `v` 前缀(`## [v0.0.10]`)— awk 期望去前缀的纯数字
246
- - 段落写错位置(`[Unreleased]` 段还没迁移到正式版本段)
247
-
248
- ## 发布成功但找不到包
249
-
250
- 典型场景:workflow 显示绿色,但 `npm view @scope/pkg` 返回 404。
251
-
252
- - **传播延迟**:npm CDN 有 30–60 秒缓存延迟,等一下再查
253
- - **日志确认**:`gh run view <id> --log | grep "+ @scope"`——有 `+ @scope/pkg@version` 才算真的成功
254
- - **provenance 页面**:https://search.sigstore.dev/ 能查到签名日志
255
-
256
- ```bash
257
- # 等待 + 轮询
258
- for i in {1..10}; do
259
- npm view @scope/my-cli version 2>/dev/null && break
260
- sleep 10
261
- done
262
- ```
263
-
264
- ## 已发布但需要撤回
265
-
266
- npm **24 小时内**可以 `unpublish`(仅限无依赖项):
267
-
268
- ```bash
269
- npm unpublish @scope/my-cli@0.0.2
270
- ```
271
-
272
- 超过 24 小时或有依赖者只能 `deprecate`:
273
-
274
- ```bash
275
- npm deprecate @scope/my-cli@0.0.2 "Security issue, use 0.0.3+"
276
- ```
277
-
278
- **npm 不允许重发同一个 version**——即使 unpublish 过了。必须 bump 版本号。
279
-
280
- ## 排查 checklist
281
-
282
- 按顺序检查,90% 的问题在前三项:
283
-
284
- 1. [ ] `NPM_TOKEN` 是 Granular Token、bypass 2FA、包含目标 scope 的 read+write
285
- 2. [ ] `package.json` 有 `repository.url` 且匹配 GitHub repo
286
- 3. [ ] Workflow 含 `permissions: id-token: write` 和 `--access public`
287
- 4. [ ] Tag 版本与 `package.json` version 字符一致
288
- 5. [ ] Publish step 在 Release step 之前
289
- 6. [ ] Workflow 触发器是 `on.push.tags: ['v*']`,没写 branches
290
- 7. [ ] `bin` 路径以 `./` 开头
291
- 8. [ ] `files` 字段不排除构建产物
292
- 9. [ ] **Workflow 包含 `Extract release notes from CHANGELOG.md` 步骤,且 `Create GitHub Release` 设了 `body_path: release-notes.md`**
293
- 10. [ ] **CHANGELOG.md 顶部有当前版本对应的 `## [X.Y.Z]` 段落(半角中括号)**