@wipcomputer/wip-ai-devops-toolbox 1.9.59 → 1.9.61

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 (742) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/SKILL.md +1 -1
  3. package/package.json +1 -1
  4. package/tools/deploy-public/package.json +1 -1
  5. package/tools/post-merge-rename/package.json +1 -1
  6. package/tools/wip-branch-guard/guard.mjs +1 -1
  7. package/tools/wip-branch-guard/package.json +1 -1
  8. package/tools/wip-branch-guard/test.sh +117 -0
  9. package/tools/wip-file-guard/package.json +1 -1
  10. package/tools/wip-license-guard/package.json +1 -1
  11. package/tools/wip-license-hook/package.json +1 -1
  12. package/tools/wip-readme-format/package.json +1 -1
  13. package/tools/wip-release/core.mjs +38 -0
  14. package/tools/wip-release/package.json +1 -1
  15. package/tools/wip-repo-init/package.json +1 -1
  16. package/tools/wip-repo-permissions-hook/package.json +1 -1
  17. package/tools/wip-repos/package.json +1 -1
  18. package/tools/wip-universal-installer/package.json +1 -1
  19. package/.worktrees/toolbox--guard-plan/.license-guard.json +0 -7
  20. package/.worktrees/toolbox--guard-plan/.publish-skill.json +0 -4
  21. package/.worktrees/toolbox--guard-plan/CHANGELOG.md +0 -1965
  22. package/.worktrees/toolbox--guard-plan/CLA.md +0 -19
  23. package/.worktrees/toolbox--guard-plan/DEV-GUIDE-GENERAL-PUBLIC.md +0 -949
  24. package/.worktrees/toolbox--guard-plan/LICENSE +0 -52
  25. package/.worktrees/toolbox--guard-plan/README.md +0 -238
  26. package/.worktrees/toolbox--guard-plan/RELEASE-NOTES-v1-9-59.md +0 -28
  27. package/.worktrees/toolbox--guard-plan/SKILL.md +0 -821
  28. package/.worktrees/toolbox--guard-plan/TECHNICAL.md +0 -416
  29. package/.worktrees/toolbox--guard-plan/UNIVERSAL-INTERFACE.md +0 -180
  30. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-8-0.md +0 -29
  31. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-8-1.md +0 -7
  32. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-8-2.md +0 -7
  33. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-0.md +0 -37
  34. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-1.md +0 -38
  35. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-10.md +0 -40
  36. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-2.md +0 -40
  37. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-31.md +0 -26
  38. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-32.md +0 -18
  39. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-41.md +0 -28
  40. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-45.md +0 -25
  41. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-46.md +0 -38
  42. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-47.md +0 -42
  43. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-48.md +0 -22
  44. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-49.md +0 -31
  45. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-50.md +0 -24
  46. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-51.md +0 -11
  47. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-52.md +0 -25
  48. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-53.md +0 -22
  49. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-54.md +0 -13
  50. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-55.md +0 -11
  51. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-56.md +0 -42
  52. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-57.md +0 -18
  53. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-58.md +0 -21
  54. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-6.md +0 -72
  55. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-7.md +0 -23
  56. package/.worktrees/toolbox--guard-plan/_trash/RELEASE-NOTES-v1-9-9.md +0 -75
  57. package/.worktrees/toolbox--guard-plan/_trash/guide 2/DEV-GUIDE.md +0 -487
  58. package/.worktrees/toolbox--guard-plan/_trash/guide 2/scripts/deploy-public.sh +0 -152
  59. package/.worktrees/toolbox--guard-plan/package.json +0 -27
  60. package/.worktrees/toolbox--guard-plan/scripts/SKILL-deploy-public.md +0 -61
  61. package/.worktrees/toolbox--guard-plan/scripts/SKILL-post-merge-rename.md +0 -47
  62. package/.worktrees/toolbox--guard-plan/scripts/deploy-public.sh +0 -350
  63. package/.worktrees/toolbox--guard-plan/scripts/post-merge-rename.sh +0 -210
  64. package/.worktrees/toolbox--guard-plan/scripts/publish-skill.sh +0 -134
  65. package/.worktrees/toolbox--guard-plan/templates/global-claude-md.md +0 -73
  66. package/.worktrees/toolbox--guard-plan/templates/repo-claude-md.template +0 -24
  67. package/.worktrees/toolbox--guard-plan/tools/deploy-public/LICENSE +0 -52
  68. package/.worktrees/toolbox--guard-plan/tools/deploy-public/README.md +0 -31
  69. package/.worktrees/toolbox--guard-plan/tools/deploy-public/SKILL.md +0 -71
  70. package/.worktrees/toolbox--guard-plan/tools/deploy-public/deploy-public.sh +0 -264
  71. package/.worktrees/toolbox--guard-plan/tools/deploy-public/package.json +0 -9
  72. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/LICENSE +0 -52
  73. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/README.md +0 -46
  74. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/backup.sh +0 -16
  75. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/branch-protect.sh +0 -39
  76. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/crystal-capture.sh +0 -19
  77. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/setup-shell.sh +0 -27
  78. package/.worktrees/toolbox--guard-plan/tools/ldm-jobs/visibility-audit.sh +0 -27
  79. package/.worktrees/toolbox--guard-plan/tools/post-merge-rename/LICENSE +0 -52
  80. package/.worktrees/toolbox--guard-plan/tools/post-merge-rename/README.md +0 -29
  81. package/.worktrees/toolbox--guard-plan/tools/post-merge-rename/SKILL.md +0 -57
  82. package/.worktrees/toolbox--guard-plan/tools/post-merge-rename/package.json +0 -9
  83. package/.worktrees/toolbox--guard-plan/tools/post-merge-rename/post-merge-rename.sh +0 -122
  84. package/.worktrees/toolbox--guard-plan/tools/wip-branch-guard/INSTALL.md +0 -41
  85. package/.worktrees/toolbox--guard-plan/tools/wip-branch-guard/guard.mjs +0 -477
  86. package/.worktrees/toolbox--guard-plan/tools/wip-branch-guard/package.json +0 -18
  87. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/CHANGELOG.md +0 -6
  88. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/LICENSE +0 -52
  89. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/README.md +0 -113
  90. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/REFERENCE.md +0 -86
  91. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/SKILL.md +0 -105
  92. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/guard.mjs +0 -161
  93. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/openclaw.plugin.json +0 -8
  94. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/package.json +0 -27
  95. package/.worktrees/toolbox--guard-plan/tools/wip-file-guard/test.sh +0 -119
  96. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/LICENSE +0 -52
  97. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/README.md +0 -69
  98. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/SKILL.md +0 -65
  99. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/cli.mjs +0 -472
  100. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/core.mjs +0 -310
  101. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/guard.mjs +0 -146
  102. package/.worktrees/toolbox--guard-plan/tools/wip-license-guard/package.json +0 -22
  103. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/CHANGELOG.md +0 -17
  104. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/LICENSE +0 -52
  105. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/README.md +0 -200
  106. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/SKILL.md +0 -111
  107. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/cli/index.d.ts +0 -15
  108. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/cli/index.js +0 -170
  109. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/cli/index.js.map +0 -1
  110. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/detector.d.ts +0 -12
  111. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/detector.js +0 -104
  112. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/detector.js.map +0 -1
  113. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/index.d.ts +0 -4
  114. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/index.js +0 -5
  115. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/index.js.map +0 -1
  116. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/ledger.d.ts +0 -49
  117. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/ledger.js +0 -72
  118. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/ledger.js.map +0 -1
  119. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/reporter.d.ts +0 -14
  120. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/reporter.js +0 -227
  121. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/reporter.js.map +0 -1
  122. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/scanner.d.ts +0 -39
  123. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/scanner.js +0 -325
  124. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/dist/core/scanner.js.map +0 -1
  125. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/hooks/pre-pull.sh +0 -55
  126. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/hooks/pre-push.sh +0 -51
  127. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/mcp-server.mjs +0 -119
  128. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/package-lock.json +0 -54
  129. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/package.json +0 -43
  130. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/cli/index.ts +0 -189
  131. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/core/detector.ts +0 -130
  132. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/core/index.ts +0 -4
  133. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/core/ledger.ts +0 -116
  134. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/core/reporter.ts +0 -255
  135. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/src/core/scanner.ts +0 -367
  136. package/.worktrees/toolbox--guard-plan/tools/wip-license-hook/tsconfig.json +0 -16
  137. package/.worktrees/toolbox--guard-plan/tools/wip-readme-format/README.md +0 -49
  138. package/.worktrees/toolbox--guard-plan/tools/wip-readme-format/SKILL.md +0 -84
  139. package/.worktrees/toolbox--guard-plan/tools/wip-readme-format/format.mjs +0 -597
  140. package/.worktrees/toolbox--guard-plan/tools/wip-readme-format/package.json +0 -15
  141. package/.worktrees/toolbox--guard-plan/tools/wip-release/CHANGELOG.md +0 -42
  142. package/.worktrees/toolbox--guard-plan/tools/wip-release/LICENSE +0 -52
  143. package/.worktrees/toolbox--guard-plan/tools/wip-release/README.md +0 -45
  144. package/.worktrees/toolbox--guard-plan/tools/wip-release/REFERENCE.md +0 -100
  145. package/.worktrees/toolbox--guard-plan/tools/wip-release/SKILL.md +0 -139
  146. package/.worktrees/toolbox--guard-plan/tools/wip-release/cli.js +0 -175
  147. package/.worktrees/toolbox--guard-plan/tools/wip-release/core.mjs +0 -1664
  148. package/.worktrees/toolbox--guard-plan/tools/wip-release/mcp-server.mjs +0 -113
  149. package/.worktrees/toolbox--guard-plan/tools/wip-release/package.json +0 -36
  150. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/README.md +0 -38
  151. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/SKILL.md +0 -77
  152. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/init.mjs +0 -148
  153. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/package.json +0 -11
  154. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/_sort/README.md +0 -15
  155. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/_trash/README.md +0 -16
  156. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/dev-updates/README.md +0 -50
  157. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/product/notes/README.md +0 -26
  158. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/product/plans-prds/roadmap.md +0 -77
  159. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/product/plans-prds/todos/README.md +0 -63
  160. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/product/product-ideas/README.md +0 -24
  161. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/product/readme-first-product.md +0 -128
  162. package/.worktrees/toolbox--guard-plan/tools/wip-repo-init/templates/read-me-first.md +0 -80
  163. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/LICENSE +0 -52
  164. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/README.md +0 -86
  165. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/SKILL.md +0 -73
  166. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/cli.js +0 -93
  167. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/core.mjs +0 -122
  168. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/guard.mjs +0 -64
  169. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/mcp-server.mjs +0 -92
  170. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/openclaw.plugin.json +0 -8
  171. package/.worktrees/toolbox--guard-plan/tools/wip-repo-permissions-hook/package.json +0 -31
  172. package/.worktrees/toolbox--guard-plan/tools/wip-repos/LICENSE +0 -52
  173. package/.worktrees/toolbox--guard-plan/tools/wip-repos/README.md +0 -77
  174. package/.worktrees/toolbox--guard-plan/tools/wip-repos/SKILL.md +0 -80
  175. package/.worktrees/toolbox--guard-plan/tools/wip-repos/claude.mjs +0 -248
  176. package/.worktrees/toolbox--guard-plan/tools/wip-repos/cli.mjs +0 -191
  177. package/.worktrees/toolbox--guard-plan/tools/wip-repos/core.mjs +0 -290
  178. package/.worktrees/toolbox--guard-plan/tools/wip-repos/mcp-server.mjs +0 -157
  179. package/.worktrees/toolbox--guard-plan/tools/wip-repos/package.json +0 -34
  180. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/CHANGELOG.md +0 -57
  181. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/LICENSE +0 -52
  182. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/README.md +0 -81
  183. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/REFERENCE.md +0 -122
  184. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/SKILL.md +0 -87
  185. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/SPEC.md +0 -206
  186. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/detect.mjs +0 -130
  187. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/README.md +0 -20
  188. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/SKILL.md +0 -28
  189. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/cli.mjs +0 -4
  190. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/core.mjs +0 -8
  191. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +0 -27
  192. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/examples/minimal/package.json +0 -12
  193. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/install.js +0 -930
  194. package/.worktrees/toolbox--guard-plan/tools/wip-universal-installer/package.json +0 -32
  195. package/.worktrees/toolbox--release-notes/.license-guard.json +0 -7
  196. package/.worktrees/toolbox--release-notes/.publish-skill.json +0 -4
  197. package/.worktrees/toolbox--release-notes/CHANGELOG.md +0 -1875
  198. package/.worktrees/toolbox--release-notes/CLA.md +0 -19
  199. package/.worktrees/toolbox--release-notes/DEV-GUIDE-GENERAL-PUBLIC.md +0 -949
  200. package/.worktrees/toolbox--release-notes/LICENSE +0 -52
  201. package/.worktrees/toolbox--release-notes/README.md +0 -238
  202. package/.worktrees/toolbox--release-notes/RELEASE-NOTES-v1-9-56.md +0 -42
  203. package/.worktrees/toolbox--release-notes/SKILL.md +0 -821
  204. package/.worktrees/toolbox--release-notes/TECHNICAL.md +0 -416
  205. package/.worktrees/toolbox--release-notes/UNIVERSAL-INTERFACE.md +0 -180
  206. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-8-0.md +0 -29
  207. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-8-1.md +0 -7
  208. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-8-2.md +0 -7
  209. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-0.md +0 -37
  210. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-1.md +0 -38
  211. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-10.md +0 -40
  212. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-2.md +0 -40
  213. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-31.md +0 -26
  214. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-32.md +0 -18
  215. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-41.md +0 -28
  216. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-45.md +0 -25
  217. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-46.md +0 -38
  218. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-47.md +0 -42
  219. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-48.md +0 -22
  220. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-49.md +0 -31
  221. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-50.md +0 -24
  222. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-51.md +0 -11
  223. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-52.md +0 -25
  224. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-53.md +0 -22
  225. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-54.md +0 -13
  226. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-55.md +0 -11
  227. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-6.md +0 -72
  228. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-7.md +0 -23
  229. package/.worktrees/toolbox--release-notes/_trash/RELEASE-NOTES-v1-9-9.md +0 -75
  230. package/.worktrees/toolbox--release-notes/_trash/guide 2/DEV-GUIDE.md +0 -487
  231. package/.worktrees/toolbox--release-notes/_trash/guide 2/scripts/deploy-public.sh +0 -152
  232. package/.worktrees/toolbox--release-notes/package.json +0 -27
  233. package/.worktrees/toolbox--release-notes/scripts/SKILL-deploy-public.md +0 -61
  234. package/.worktrees/toolbox--release-notes/scripts/SKILL-post-merge-rename.md +0 -47
  235. package/.worktrees/toolbox--release-notes/scripts/deploy-public.sh +0 -345
  236. package/.worktrees/toolbox--release-notes/scripts/post-merge-rename.sh +0 -210
  237. package/.worktrees/toolbox--release-notes/scripts/publish-skill.sh +0 -134
  238. package/.worktrees/toolbox--release-notes/templates/global-claude-md.md +0 -73
  239. package/.worktrees/toolbox--release-notes/templates/repo-claude-md.template +0 -24
  240. package/.worktrees/toolbox--release-notes/tools/deploy-public/LICENSE +0 -52
  241. package/.worktrees/toolbox--release-notes/tools/deploy-public/README.md +0 -31
  242. package/.worktrees/toolbox--release-notes/tools/deploy-public/SKILL.md +0 -71
  243. package/.worktrees/toolbox--release-notes/tools/deploy-public/deploy-public.sh +0 -264
  244. package/.worktrees/toolbox--release-notes/tools/deploy-public/package.json +0 -9
  245. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/LICENSE +0 -52
  246. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/README.md +0 -46
  247. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/backup.sh +0 -16
  248. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/branch-protect.sh +0 -39
  249. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/crystal-capture.sh +0 -19
  250. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/setup-shell.sh +0 -27
  251. package/.worktrees/toolbox--release-notes/tools/ldm-jobs/visibility-audit.sh +0 -27
  252. package/.worktrees/toolbox--release-notes/tools/post-merge-rename/LICENSE +0 -52
  253. package/.worktrees/toolbox--release-notes/tools/post-merge-rename/README.md +0 -29
  254. package/.worktrees/toolbox--release-notes/tools/post-merge-rename/SKILL.md +0 -57
  255. package/.worktrees/toolbox--release-notes/tools/post-merge-rename/package.json +0 -9
  256. package/.worktrees/toolbox--release-notes/tools/post-merge-rename/post-merge-rename.sh +0 -122
  257. package/.worktrees/toolbox--release-notes/tools/wip-branch-guard/INSTALL.md +0 -41
  258. package/.worktrees/toolbox--release-notes/tools/wip-branch-guard/guard.mjs +0 -459
  259. package/.worktrees/toolbox--release-notes/tools/wip-branch-guard/package.json +0 -18
  260. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/CHANGELOG.md +0 -6
  261. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/LICENSE +0 -52
  262. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/README.md +0 -113
  263. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/REFERENCE.md +0 -86
  264. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/SKILL.md +0 -105
  265. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/guard.mjs +0 -161
  266. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/openclaw.plugin.json +0 -8
  267. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/package.json +0 -27
  268. package/.worktrees/toolbox--release-notes/tools/wip-file-guard/test.sh +0 -119
  269. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/LICENSE +0 -52
  270. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/README.md +0 -69
  271. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/SKILL.md +0 -65
  272. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/cli.mjs +0 -472
  273. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/core.mjs +0 -310
  274. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/guard.mjs +0 -146
  275. package/.worktrees/toolbox--release-notes/tools/wip-license-guard/package.json +0 -22
  276. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/CHANGELOG.md +0 -17
  277. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/LICENSE +0 -52
  278. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/README.md +0 -200
  279. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/SKILL.md +0 -111
  280. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/cli/index.d.ts +0 -15
  281. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/cli/index.js +0 -170
  282. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/cli/index.js.map +0 -1
  283. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/detector.d.ts +0 -12
  284. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/detector.js +0 -104
  285. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/detector.js.map +0 -1
  286. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/index.d.ts +0 -4
  287. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/index.js +0 -5
  288. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/index.js.map +0 -1
  289. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/ledger.d.ts +0 -49
  290. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/ledger.js +0 -72
  291. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/ledger.js.map +0 -1
  292. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/reporter.d.ts +0 -14
  293. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/reporter.js +0 -227
  294. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/reporter.js.map +0 -1
  295. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/scanner.d.ts +0 -39
  296. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/scanner.js +0 -325
  297. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/dist/core/scanner.js.map +0 -1
  298. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/hooks/pre-pull.sh +0 -55
  299. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/hooks/pre-push.sh +0 -51
  300. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/mcp-server.mjs +0 -119
  301. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/package-lock.json +0 -54
  302. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/package.json +0 -43
  303. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/cli/index.ts +0 -189
  304. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/core/detector.ts +0 -130
  305. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/core/index.ts +0 -4
  306. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/core/ledger.ts +0 -116
  307. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/core/reporter.ts +0 -255
  308. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/src/core/scanner.ts +0 -367
  309. package/.worktrees/toolbox--release-notes/tools/wip-license-hook/tsconfig.json +0 -16
  310. package/.worktrees/toolbox--release-notes/tools/wip-readme-format/README.md +0 -49
  311. package/.worktrees/toolbox--release-notes/tools/wip-readme-format/SKILL.md +0 -84
  312. package/.worktrees/toolbox--release-notes/tools/wip-readme-format/format.mjs +0 -597
  313. package/.worktrees/toolbox--release-notes/tools/wip-readme-format/package.json +0 -15
  314. package/.worktrees/toolbox--release-notes/tools/wip-release/CHANGELOG.md +0 -42
  315. package/.worktrees/toolbox--release-notes/tools/wip-release/LICENSE +0 -52
  316. package/.worktrees/toolbox--release-notes/tools/wip-release/README.md +0 -45
  317. package/.worktrees/toolbox--release-notes/tools/wip-release/REFERENCE.md +0 -100
  318. package/.worktrees/toolbox--release-notes/tools/wip-release/SKILL.md +0 -139
  319. package/.worktrees/toolbox--release-notes/tools/wip-release/cli.js +0 -175
  320. package/.worktrees/toolbox--release-notes/tools/wip-release/core.mjs +0 -1664
  321. package/.worktrees/toolbox--release-notes/tools/wip-release/mcp-server.mjs +0 -113
  322. package/.worktrees/toolbox--release-notes/tools/wip-release/package.json +0 -36
  323. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/README.md +0 -38
  324. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/SKILL.md +0 -77
  325. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/init.mjs +0 -148
  326. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/package.json +0 -11
  327. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/_sort/README.md +0 -15
  328. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/_trash/README.md +0 -16
  329. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/dev-updates/README.md +0 -50
  330. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/product/notes/README.md +0 -26
  331. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/product/plans-prds/roadmap.md +0 -77
  332. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/product/plans-prds/todos/README.md +0 -63
  333. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/product/product-ideas/README.md +0 -24
  334. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/product/readme-first-product.md +0 -128
  335. package/.worktrees/toolbox--release-notes/tools/wip-repo-init/templates/read-me-first.md +0 -80
  336. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/LICENSE +0 -52
  337. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/README.md +0 -86
  338. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/SKILL.md +0 -73
  339. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/cli.js +0 -93
  340. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/core.mjs +0 -122
  341. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/guard.mjs +0 -64
  342. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/mcp-server.mjs +0 -92
  343. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/openclaw.plugin.json +0 -8
  344. package/.worktrees/toolbox--release-notes/tools/wip-repo-permissions-hook/package.json +0 -31
  345. package/.worktrees/toolbox--release-notes/tools/wip-repos/LICENSE +0 -52
  346. package/.worktrees/toolbox--release-notes/tools/wip-repos/README.md +0 -77
  347. package/.worktrees/toolbox--release-notes/tools/wip-repos/SKILL.md +0 -80
  348. package/.worktrees/toolbox--release-notes/tools/wip-repos/claude.mjs +0 -248
  349. package/.worktrees/toolbox--release-notes/tools/wip-repos/cli.mjs +0 -191
  350. package/.worktrees/toolbox--release-notes/tools/wip-repos/core.mjs +0 -290
  351. package/.worktrees/toolbox--release-notes/tools/wip-repos/mcp-server.mjs +0 -157
  352. package/.worktrees/toolbox--release-notes/tools/wip-repos/package.json +0 -34
  353. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/CHANGELOG.md +0 -57
  354. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/LICENSE +0 -52
  355. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/README.md +0 -81
  356. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/REFERENCE.md +0 -122
  357. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/SKILL.md +0 -87
  358. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/SPEC.md +0 -206
  359. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/detect.mjs +0 -130
  360. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/README.md +0 -20
  361. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/SKILL.md +0 -28
  362. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/cli.mjs +0 -4
  363. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/core.mjs +0 -8
  364. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +0 -27
  365. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/examples/minimal/package.json +0 -12
  366. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/install.js +0 -930
  367. package/.worktrees/toolbox--release-notes/tools/wip-universal-installer/package.json +0 -32
  368. package/.worktrees/toolbox--save-stale/.license-guard.json +0 -7
  369. package/.worktrees/toolbox--save-stale/.publish-skill.json +0 -4
  370. package/.worktrees/toolbox--save-stale/CHANGELOG.md +0 -1875
  371. package/.worktrees/toolbox--save-stale/CLA.md +0 -19
  372. package/.worktrees/toolbox--save-stale/DEV-GUIDE-GENERAL-PUBLIC.md +0 -949
  373. package/.worktrees/toolbox--save-stale/LICENSE +0 -52
  374. package/.worktrees/toolbox--save-stale/README.md +0 -238
  375. package/.worktrees/toolbox--save-stale/SKILL.md +0 -821
  376. package/.worktrees/toolbox--save-stale/TECHNICAL.md +0 -416
  377. package/.worktrees/toolbox--save-stale/UNIVERSAL-INTERFACE.md +0 -180
  378. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-8-0.md +0 -29
  379. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-8-1.md +0 -7
  380. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-8-2.md +0 -7
  381. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-0.md +0 -37
  382. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-1.md +0 -38
  383. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-10.md +0 -40
  384. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-2.md +0 -40
  385. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-31.md +0 -26
  386. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-32.md +0 -18
  387. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-41.md +0 -28
  388. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-45.md +0 -25
  389. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-46.md +0 -38
  390. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-47.md +0 -42
  391. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-48.md +0 -22
  392. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-49.md +0 -31
  393. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-50.md +0 -24
  394. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-51.md +0 -11
  395. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-52.md +0 -25
  396. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-53.md +0 -22
  397. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-54.md +0 -13
  398. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-55.md +0 -11
  399. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-6.md +0 -72
  400. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-7.md +0 -23
  401. package/.worktrees/toolbox--save-stale/_trash/RELEASE-NOTES-v1-9-9.md +0 -75
  402. package/.worktrees/toolbox--save-stale/_trash/guide 2/DEV-GUIDE.md +0 -487
  403. package/.worktrees/toolbox--save-stale/_trash/guide 2/scripts/deploy-public.sh +0 -152
  404. package/.worktrees/toolbox--save-stale/package.json +0 -27
  405. package/.worktrees/toolbox--save-stale/scripts/SKILL-deploy-public.md +0 -61
  406. package/.worktrees/toolbox--save-stale/scripts/SKILL-post-merge-rename.md +0 -47
  407. package/.worktrees/toolbox--save-stale/scripts/deploy-public.sh +0 -345
  408. package/.worktrees/toolbox--save-stale/scripts/post-merge-rename.sh +0 -210
  409. package/.worktrees/toolbox--save-stale/scripts/publish-skill.sh +0 -134
  410. package/.worktrees/toolbox--save-stale/templates/global-claude-md.md +0 -73
  411. package/.worktrees/toolbox--save-stale/templates/repo-claude-md.template +0 -24
  412. package/.worktrees/toolbox--save-stale/tools/deploy-public/LICENSE +0 -52
  413. package/.worktrees/toolbox--save-stale/tools/deploy-public/README.md +0 -31
  414. package/.worktrees/toolbox--save-stale/tools/deploy-public/SKILL.md +0 -71
  415. package/.worktrees/toolbox--save-stale/tools/deploy-public/deploy-public.sh +0 -264
  416. package/.worktrees/toolbox--save-stale/tools/deploy-public/package.json +0 -9
  417. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/LICENSE +0 -52
  418. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/README.md +0 -46
  419. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/backup.sh +0 -16
  420. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/branch-protect.sh +0 -39
  421. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/crystal-capture.sh +0 -19
  422. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/setup-shell.sh +0 -27
  423. package/.worktrees/toolbox--save-stale/tools/ldm-jobs/visibility-audit.sh +0 -27
  424. package/.worktrees/toolbox--save-stale/tools/post-merge-rename/LICENSE +0 -52
  425. package/.worktrees/toolbox--save-stale/tools/post-merge-rename/README.md +0 -29
  426. package/.worktrees/toolbox--save-stale/tools/post-merge-rename/SKILL.md +0 -57
  427. package/.worktrees/toolbox--save-stale/tools/post-merge-rename/package.json +0 -9
  428. package/.worktrees/toolbox--save-stale/tools/post-merge-rename/post-merge-rename.sh +0 -122
  429. package/.worktrees/toolbox--save-stale/tools/wip-branch-guard/INSTALL.md +0 -41
  430. package/.worktrees/toolbox--save-stale/tools/wip-branch-guard/guard.mjs +0 -459
  431. package/.worktrees/toolbox--save-stale/tools/wip-branch-guard/package.json +0 -18
  432. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/CHANGELOG.md +0 -6
  433. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/LICENSE +0 -52
  434. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/README.md +0 -113
  435. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/REFERENCE.md +0 -86
  436. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/SKILL.md +0 -105
  437. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/guard.mjs +0 -161
  438. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/openclaw.plugin.json +0 -8
  439. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/package.json +0 -27
  440. package/.worktrees/toolbox--save-stale/tools/wip-file-guard/test.sh +0 -119
  441. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/LICENSE +0 -52
  442. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/README.md +0 -69
  443. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/SKILL.md +0 -65
  444. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/cli.mjs +0 -472
  445. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/core.mjs +0 -310
  446. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/guard.mjs +0 -146
  447. package/.worktrees/toolbox--save-stale/tools/wip-license-guard/package.json +0 -22
  448. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/CHANGELOG.md +0 -17
  449. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/LICENSE +0 -52
  450. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/README.md +0 -200
  451. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/SKILL.md +0 -111
  452. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/cli/index.d.ts +0 -15
  453. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/cli/index.js +0 -170
  454. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/cli/index.js.map +0 -1
  455. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/detector.d.ts +0 -12
  456. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/detector.js +0 -104
  457. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/detector.js.map +0 -1
  458. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/index.d.ts +0 -4
  459. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/index.js +0 -5
  460. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/index.js.map +0 -1
  461. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/ledger.d.ts +0 -49
  462. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/ledger.js +0 -72
  463. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/ledger.js.map +0 -1
  464. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/reporter.d.ts +0 -14
  465. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/reporter.js +0 -227
  466. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/reporter.js.map +0 -1
  467. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/scanner.d.ts +0 -39
  468. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/scanner.js +0 -325
  469. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/dist/core/scanner.js.map +0 -1
  470. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/hooks/pre-pull.sh +0 -55
  471. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/hooks/pre-push.sh +0 -51
  472. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/mcp-server.mjs +0 -119
  473. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/package-lock.json +0 -54
  474. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/package.json +0 -43
  475. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/cli/index.ts +0 -189
  476. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/core/detector.ts +0 -130
  477. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/core/index.ts +0 -4
  478. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/core/ledger.ts +0 -116
  479. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/core/reporter.ts +0 -255
  480. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/src/core/scanner.ts +0 -367
  481. package/.worktrees/toolbox--save-stale/tools/wip-license-hook/tsconfig.json +0 -16
  482. package/.worktrees/toolbox--save-stale/tools/wip-readme-format/README.md +0 -49
  483. package/.worktrees/toolbox--save-stale/tools/wip-readme-format/SKILL.md +0 -84
  484. package/.worktrees/toolbox--save-stale/tools/wip-readme-format/format.mjs +0 -597
  485. package/.worktrees/toolbox--save-stale/tools/wip-readme-format/package.json +0 -15
  486. package/.worktrees/toolbox--save-stale/tools/wip-release/CHANGELOG.md +0 -42
  487. package/.worktrees/toolbox--save-stale/tools/wip-release/LICENSE +0 -52
  488. package/.worktrees/toolbox--save-stale/tools/wip-release/README.md +0 -45
  489. package/.worktrees/toolbox--save-stale/tools/wip-release/REFERENCE.md +0 -100
  490. package/.worktrees/toolbox--save-stale/tools/wip-release/SKILL.md +0 -139
  491. package/.worktrees/toolbox--save-stale/tools/wip-release/cli.js +0 -175
  492. package/.worktrees/toolbox--save-stale/tools/wip-release/core.mjs +0 -1664
  493. package/.worktrees/toolbox--save-stale/tools/wip-release/mcp-server.mjs +0 -113
  494. package/.worktrees/toolbox--save-stale/tools/wip-release/package.json +0 -36
  495. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/README.md +0 -38
  496. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/SKILL.md +0 -77
  497. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/init.mjs +0 -148
  498. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/package.json +0 -11
  499. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/_sort/README.md +0 -15
  500. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/_trash/README.md +0 -16
  501. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/dev-updates/README.md +0 -50
  502. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/product/notes/README.md +0 -26
  503. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/product/plans-prds/roadmap.md +0 -77
  504. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/product/plans-prds/todos/README.md +0 -63
  505. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/product/product-ideas/README.md +0 -24
  506. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/product/readme-first-product.md +0 -128
  507. package/.worktrees/toolbox--save-stale/tools/wip-repo-init/templates/read-me-first.md +0 -80
  508. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/LICENSE +0 -52
  509. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/README.md +0 -86
  510. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/SKILL.md +0 -73
  511. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/cli.js +0 -93
  512. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/core.mjs +0 -122
  513. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/guard.mjs +0 -64
  514. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/mcp-server.mjs +0 -92
  515. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/openclaw.plugin.json +0 -8
  516. package/.worktrees/toolbox--save-stale/tools/wip-repo-permissions-hook/package.json +0 -31
  517. package/.worktrees/toolbox--save-stale/tools/wip-repos/LICENSE +0 -52
  518. package/.worktrees/toolbox--save-stale/tools/wip-repos/README.md +0 -77
  519. package/.worktrees/toolbox--save-stale/tools/wip-repos/SKILL.md +0 -80
  520. package/.worktrees/toolbox--save-stale/tools/wip-repos/claude.mjs +0 -248
  521. package/.worktrees/toolbox--save-stale/tools/wip-repos/cli.mjs +0 -191
  522. package/.worktrees/toolbox--save-stale/tools/wip-repos/core.mjs +0 -290
  523. package/.worktrees/toolbox--save-stale/tools/wip-repos/mcp-server.mjs +0 -157
  524. package/.worktrees/toolbox--save-stale/tools/wip-repos/package.json +0 -34
  525. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/CHANGELOG.md +0 -57
  526. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/LICENSE +0 -52
  527. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/README.md +0 -81
  528. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/REFERENCE.md +0 -122
  529. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/SKILL.md +0 -87
  530. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/SPEC.md +0 -206
  531. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/detect.mjs +0 -130
  532. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/README.md +0 -20
  533. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/SKILL.md +0 -28
  534. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/cli.mjs +0 -4
  535. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/core.mjs +0 -8
  536. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +0 -27
  537. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/examples/minimal/package.json +0 -12
  538. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/install.js +0 -930
  539. package/.worktrees/toolbox--save-stale/tools/wip-universal-installer/package.json +0 -32
  540. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/.license-guard.json +0 -7
  541. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/.publish-skill.json +0 -4
  542. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/CHANGELOG.md +0 -1875
  543. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/CLA.md +0 -19
  544. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/DEV-GUIDE-GENERAL-PUBLIC.md +0 -949
  545. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/LICENSE +0 -52
  546. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/README.md +0 -238
  547. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/SKILL.md +0 -821
  548. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/TECHNICAL.md +0 -416
  549. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/UNIVERSAL-INTERFACE.md +0 -180
  550. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-8-0.md +0 -29
  551. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-8-1.md +0 -7
  552. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-8-2.md +0 -7
  553. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-0.md +0 -37
  554. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-1.md +0 -38
  555. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-10.md +0 -40
  556. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-2.md +0 -40
  557. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-31.md +0 -26
  558. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-32.md +0 -18
  559. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-41.md +0 -28
  560. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-45.md +0 -25
  561. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-46.md +0 -38
  562. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-47.md +0 -42
  563. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-48.md +0 -22
  564. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-49.md +0 -31
  565. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-50.md +0 -24
  566. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-51.md +0 -11
  567. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-52.md +0 -25
  568. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-53.md +0 -22
  569. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-54.md +0 -13
  570. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-55.md +0 -11
  571. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-6.md +0 -72
  572. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-7.md +0 -23
  573. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/RELEASE-NOTES-v1-9-9.md +0 -75
  574. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/guide 2/DEV-GUIDE.md +0 -487
  575. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/_trash/guide 2/scripts/deploy-public.sh +0 -152
  576. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/package.json +0 -27
  577. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/scripts/SKILL-deploy-public.md +0 -61
  578. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/scripts/SKILL-post-merge-rename.md +0 -47
  579. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/scripts/deploy-public.sh +0 -345
  580. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/scripts/post-merge-rename.sh +0 -210
  581. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/scripts/publish-skill.sh +0 -134
  582. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/templates/global-claude-md.md +0 -73
  583. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/templates/repo-claude-md.template +0 -24
  584. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/deploy-public/LICENSE +0 -52
  585. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/deploy-public/README.md +0 -31
  586. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/deploy-public/SKILL.md +0 -71
  587. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/deploy-public/deploy-public.sh +0 -264
  588. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/deploy-public/package.json +0 -9
  589. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/LICENSE +0 -52
  590. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/README.md +0 -46
  591. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/backup.sh +0 -16
  592. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/branch-protect.sh +0 -39
  593. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/crystal-capture.sh +0 -19
  594. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/setup-shell.sh +0 -27
  595. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/ldm-jobs/visibility-audit.sh +0 -27
  596. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/post-merge-rename/LICENSE +0 -52
  597. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/post-merge-rename/README.md +0 -29
  598. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/post-merge-rename/SKILL.md +0 -57
  599. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/post-merge-rename/package.json +0 -9
  600. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/post-merge-rename/post-merge-rename.sh +0 -122
  601. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-branch-guard/INSTALL.md +0 -41
  602. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-branch-guard/guard.mjs +0 -418
  603. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-branch-guard/package.json +0 -18
  604. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/CHANGELOG.md +0 -6
  605. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/LICENSE +0 -52
  606. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/README.md +0 -113
  607. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/REFERENCE.md +0 -86
  608. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/SKILL.md +0 -105
  609. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/guard.mjs +0 -161
  610. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/openclaw.plugin.json +0 -8
  611. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/package.json +0 -27
  612. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-file-guard/test.sh +0 -119
  613. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/LICENSE +0 -52
  614. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/README.md +0 -69
  615. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/SKILL.md +0 -65
  616. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/cli.mjs +0 -472
  617. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/core.mjs +0 -310
  618. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/guard.mjs +0 -146
  619. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-guard/package.json +0 -22
  620. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/CHANGELOG.md +0 -17
  621. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/LICENSE +0 -52
  622. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/README.md +0 -200
  623. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/SKILL.md +0 -111
  624. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/cli/index.d.ts +0 -15
  625. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/cli/index.js +0 -170
  626. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/cli/index.js.map +0 -1
  627. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/detector.d.ts +0 -12
  628. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/detector.js +0 -104
  629. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/detector.js.map +0 -1
  630. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/index.d.ts +0 -4
  631. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/index.js +0 -5
  632. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/index.js.map +0 -1
  633. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/ledger.d.ts +0 -49
  634. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/ledger.js +0 -72
  635. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/ledger.js.map +0 -1
  636. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/reporter.d.ts +0 -14
  637. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/reporter.js +0 -227
  638. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/reporter.js.map +0 -1
  639. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/scanner.d.ts +0 -39
  640. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/scanner.js +0 -325
  641. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/dist/core/scanner.js.map +0 -1
  642. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/hooks/pre-pull.sh +0 -55
  643. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/hooks/pre-push.sh +0 -51
  644. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/mcp-server.mjs +0 -119
  645. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/package-lock.json +0 -54
  646. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/package.json +0 -43
  647. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/cli/index.ts +0 -189
  648. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/core/detector.ts +0 -130
  649. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/core/index.ts +0 -4
  650. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/core/ledger.ts +0 -116
  651. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/core/reporter.ts +0 -255
  652. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/src/core/scanner.ts +0 -367
  653. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-license-hook/tsconfig.json +0 -16
  654. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-readme-format/README.md +0 -49
  655. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-readme-format/SKILL.md +0 -84
  656. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-readme-format/format.mjs +0 -597
  657. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-readme-format/package.json +0 -15
  658. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/CHANGELOG.md +0 -42
  659. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/LICENSE +0 -52
  660. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/README.md +0 -45
  661. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/REFERENCE.md +0 -100
  662. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/SKILL.md +0 -139
  663. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/cli.js +0 -175
  664. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/core.mjs +0 -1664
  665. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/mcp-server.mjs +0 -113
  666. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-release/package.json +0 -36
  667. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/README.md +0 -38
  668. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/SKILL.md +0 -77
  669. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/init.mjs +0 -148
  670. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/package.json +0 -11
  671. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/_sort/README.md +0 -15
  672. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/_trash/README.md +0 -16
  673. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/dev-updates/README.md +0 -50
  674. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/product/notes/README.md +0 -26
  675. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/product/plans-prds/roadmap.md +0 -77
  676. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/product/plans-prds/todos/README.md +0 -63
  677. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/product/product-ideas/README.md +0 -24
  678. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/product/readme-first-product.md +0 -128
  679. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-init/templates/read-me-first.md +0 -80
  680. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/LICENSE +0 -52
  681. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/README.md +0 -86
  682. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/SKILL.md +0 -73
  683. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/cli.js +0 -93
  684. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/core.mjs +0 -122
  685. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/guard.mjs +0 -64
  686. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/mcp-server.mjs +0 -92
  687. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/openclaw.plugin.json +0 -8
  688. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repo-permissions-hook/package.json +0 -31
  689. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/LICENSE +0 -52
  690. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/README.md +0 -77
  691. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/SKILL.md +0 -80
  692. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/claude.mjs +0 -248
  693. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/cli.mjs +0 -191
  694. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/core.mjs +0 -290
  695. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/mcp-server.mjs +0 -157
  696. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-repos/package.json +0 -34
  697. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/CHANGELOG.md +0 -57
  698. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/LICENSE +0 -52
  699. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/README.md +0 -81
  700. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/REFERENCE.md +0 -122
  701. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/SKILL.md +0 -87
  702. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/SPEC.md +0 -206
  703. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/detect.mjs +0 -130
  704. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/README.md +0 -20
  705. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/SKILL.md +0 -28
  706. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/cli.mjs +0 -4
  707. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/core.mjs +0 -8
  708. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/mcp-server.mjs +0 -27
  709. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/examples/minimal/package.json +0 -12
  710. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/install.js +0 -930
  711. package/.worktrees/wip-ai-devops-toolbox-private--cc-mini--dot-worktrees/tools/wip-universal-installer/package.json +0 -32
  712. package/_trash/RELEASE-NOTES-v1-8-0.md +0 -29
  713. package/_trash/RELEASE-NOTES-v1-8-1.md +0 -7
  714. package/_trash/RELEASE-NOTES-v1-8-2.md +0 -7
  715. package/_trash/RELEASE-NOTES-v1-9-0.md +0 -37
  716. package/_trash/RELEASE-NOTES-v1-9-1.md +0 -38
  717. package/_trash/RELEASE-NOTES-v1-9-10.md +0 -40
  718. package/_trash/RELEASE-NOTES-v1-9-2.md +0 -40
  719. package/_trash/RELEASE-NOTES-v1-9-31.md +0 -26
  720. package/_trash/RELEASE-NOTES-v1-9-32.md +0 -18
  721. package/_trash/RELEASE-NOTES-v1-9-41.md +0 -28
  722. package/_trash/RELEASE-NOTES-v1-9-45.md +0 -25
  723. package/_trash/RELEASE-NOTES-v1-9-46.md +0 -38
  724. package/_trash/RELEASE-NOTES-v1-9-47.md +0 -42
  725. package/_trash/RELEASE-NOTES-v1-9-48.md +0 -22
  726. package/_trash/RELEASE-NOTES-v1-9-49.md +0 -31
  727. package/_trash/RELEASE-NOTES-v1-9-50.md +0 -24
  728. package/_trash/RELEASE-NOTES-v1-9-51.md +0 -11
  729. package/_trash/RELEASE-NOTES-v1-9-52.md +0 -25
  730. package/_trash/RELEASE-NOTES-v1-9-53.md +0 -22
  731. package/_trash/RELEASE-NOTES-v1-9-54.md +0 -13
  732. package/_trash/RELEASE-NOTES-v1-9-55.md +0 -11
  733. package/_trash/RELEASE-NOTES-v1-9-56.md +0 -42
  734. package/_trash/RELEASE-NOTES-v1-9-57.md +0 -18
  735. package/_trash/RELEASE-NOTES-v1-9-58.md +0 -21
  736. package/_trash/RELEASE-NOTES-v1-9-59.md +0 -28
  737. package/_trash/RELEASE-NOTES-v1-9-6.md +0 -72
  738. package/_trash/RELEASE-NOTES-v1-9-7.md +0 -23
  739. package/_trash/RELEASE-NOTES-v1-9-9.md +0 -75
  740. package/_trash/guide 2/DEV-GUIDE.md +0 -487
  741. package/_trash/guide 2/scripts/deploy-public.sh +0 -152
  742. package/tools/wip-repo-init/templates/_trash/README.md +0 -16
@@ -1,1664 +0,0 @@
1
- /**
2
- * wip-release/core.mjs
3
- * Local release tool. Bumps version, updates changelog + SKILL.md,
4
- * commits, tags, publishes to npm + GitHub Packages, creates GitHub release.
5
- * Zero dependencies.
6
- */
7
-
8
- import { execSync, execFileSync } from 'node:child_process';
9
- import { readFileSync, writeFileSync, existsSync, readdirSync, mkdirSync, renameSync } from 'node:fs';
10
- import { join, basename } from 'node:path';
11
-
12
- // ── Version ─────────────────────────────────────────────────────────
13
-
14
- /**
15
- * Read current version from package.json.
16
- */
17
- export function detectCurrentVersion(repoPath) {
18
- const pkgPath = join(repoPath, 'package.json');
19
- if (!existsSync(pkgPath)) throw new Error(`No package.json found at ${repoPath}`);
20
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
21
- return pkg.version;
22
- }
23
-
24
- /**
25
- * Bump a semver string by level.
26
- */
27
- export function bumpSemver(version, level) {
28
- const [major, minor, patch] = version.split('.').map(Number);
29
- switch (level) {
30
- case 'major': return `${major + 1}.0.0`;
31
- case 'minor': return `${major}.${minor + 1}.0`;
32
- case 'patch': return `${major}.${minor}.${patch + 1}`;
33
- default: throw new Error(`Invalid level: ${level}. Use major, minor, or patch.`);
34
- }
35
- }
36
-
37
- /**
38
- * Write new version to package.json.
39
- */
40
- function writePackageVersion(repoPath, newVersion) {
41
- const pkgPath = join(repoPath, 'package.json');
42
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
43
- pkg.version = newVersion;
44
- writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n');
45
- }
46
-
47
- // ── SKILL.md ────────────────────────────────────────────────────────
48
-
49
- /**
50
- * Update version in SKILL.md YAML frontmatter.
51
- */
52
- export function syncSkillVersion(repoPath, newVersion) {
53
- const skillPath = join(repoPath, 'SKILL.md');
54
- if (!existsSync(skillPath)) return false;
55
-
56
- let content = readFileSync(skillPath, 'utf8');
57
-
58
- // Check for staleness: if SKILL.md version is more than a patch behind,
59
- // warn that content may need updating (not just the version number)
60
- const skillVersionMatch = content.match(/^---[\s\S]*?version:\s*"?(\d+\.\d+\.\d+)"?[\s\S]*?---/);
61
- if (skillVersionMatch) {
62
- const skillVersion = skillVersionMatch[1];
63
- const [sMaj, sMin] = skillVersion.split('.').map(Number);
64
- const [nMaj, nMin] = newVersion.split('.').map(Number);
65
- if (nMaj > sMaj || nMin > sMin + 1) {
66
- console.warn(` ! SKILL.md is at ${skillVersion}, releasing ${newVersion}`);
67
- console.warn(` SKILL.md content may be stale. Review tool list and interfaces.`);
68
- }
69
- }
70
-
71
- // Match version line in YAML frontmatter (between --- markers).
72
- // Uses "[^\n]* for quoted values (including corrupted multi-quote strings
73
- // like "1.9.5".9.4".9.3") or \S+ for unquoted values. This replaces the
74
- // ENTIRE value on the line, preventing the accumulation bug (#71).
75
- const updated = content.replace(
76
- /^(---[\s\S]*?version:\s*)(?:"[^\n]*|\S+)([\s\S]*?---)/,
77
- `$1"${newVersion}"$2`
78
- );
79
-
80
- if (updated === content) return false;
81
- writeFileSync(skillPath, updated);
82
- return true;
83
- }
84
-
85
- // ── CHANGELOG.md ────────────────────────────────────────────────────
86
-
87
- /**
88
- * Prepend a new version entry to CHANGELOG.md.
89
- */
90
- export function updateChangelog(repoPath, newVersion, notes) {
91
- const changelogPath = join(repoPath, 'CHANGELOG.md');
92
- const d = new Date();
93
- const date = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
94
-
95
- // Bug fix #121: never silently default to "Release." when notes are empty.
96
- // If notes are empty at this point, warn loudly.
97
- if (!notes || !notes.trim()) {
98
- console.warn(` ! WARNING: No release notes provided for v${newVersion}. CHANGELOG entry will be minimal.`);
99
- notes = 'No release notes provided.';
100
- }
101
-
102
- const entry = `## ${newVersion} (${date})\n\n${notes}\n`;
103
-
104
- if (!existsSync(changelogPath)) {
105
- writeFileSync(changelogPath, `# Changelog\n\n${entry}`);
106
- return;
107
- }
108
-
109
- let content = readFileSync(changelogPath, 'utf8');
110
- // Insert after the # Changelog header (single newline, no accumulation)
111
- const headerMatch = content.match(/^# Changelog\s*\n+/);
112
- if (headerMatch) {
113
- const insertPoint = headerMatch[0].length;
114
- content = content.slice(0, insertPoint) + entry + '\n' + content.slice(insertPoint);
115
- } else {
116
- content = `# Changelog\n\n${entry}\n${content}`;
117
- }
118
-
119
- writeFileSync(changelogPath, content);
120
- }
121
-
122
- // ── Git ─────────────────────────────────────────────────────────────
123
-
124
- /**
125
- * Move all RELEASE-NOTES-v*.md files to _trash/.
126
- * Returns the number of files moved.
127
- */
128
- function trashReleaseNotes(repoPath) {
129
- const files = readdirSync(repoPath).filter(f => /^RELEASE-NOTES-v.*\.md$/i.test(f));
130
- if (files.length === 0) return 0;
131
-
132
- const trashDir = join(repoPath, '_trash');
133
- if (!existsSync(trashDir)) mkdirSync(trashDir);
134
-
135
- for (const f of files) {
136
- renameSync(join(repoPath, f), join(trashDir, f));
137
- execFileSync('git', ['add', join('_trash', f)], { cwd: repoPath, stdio: 'pipe' });
138
- // Only git rm if the file was tracked (committed or staged).
139
- // Untracked scaffolded files from failed releases just need the rename.
140
- try {
141
- execFileSync('git', ['ls-files', '--error-unmatch', f], { cwd: repoPath, stdio: 'pipe' });
142
- execFileSync('git', ['rm', '--cached', f], { cwd: repoPath, stdio: 'pipe' });
143
- } catch {
144
- // File wasn't tracked. Rename already moved it.
145
- }
146
- }
147
- return files.length;
148
- }
149
-
150
- function gitCommitAndTag(repoPath, newVersion, notes) {
151
- const msg = `v${newVersion}: ${notes || 'Release'}`;
152
- // Stage known files (ignore missing ones)
153
- for (const f of ['package.json', 'CHANGELOG.md', 'SKILL.md']) {
154
- if (existsSync(join(repoPath, f))) {
155
- execFileSync('git', ['add', f], { cwd: repoPath, stdio: 'pipe' });
156
- }
157
- }
158
- // Use execFileSync to avoid shell injection via notes.
159
- // --no-verify: wip-release legitimately commits on main (version bump + changelog).
160
- // The pre-commit hook blocks all commits on main, but wip-release is the one exception.
161
- execFileSync('git', ['commit', '--no-verify', '-m', msg], { cwd: repoPath, stdio: 'pipe' });
162
- execFileSync('git', ['tag', `v${newVersion}`], { cwd: repoPath, stdio: 'pipe' });
163
- }
164
-
165
- // ── Publish ─────────────────────────────────────────────────────────
166
-
167
- /**
168
- * Publish to npm via 1Password for auth.
169
- */
170
- export function publishNpm(repoPath) {
171
- const token = getNpmToken();
172
- execFileSync('npm', [
173
- 'publish', '--access', 'public',
174
- `--//registry.npmjs.org/:_authToken=${token}`
175
- ], { cwd: repoPath, stdio: 'inherit' });
176
- }
177
-
178
- /**
179
- * Publish to GitHub Packages.
180
- */
181
- export function publishGitHubPackages(repoPath) {
182
- const ghToken = execSync('gh auth token', { encoding: 'utf8' }).trim();
183
- execFileSync('npm', [
184
- 'publish',
185
- '--registry', 'https://npm.pkg.github.com',
186
- `--//npm.pkg.github.com/:_authToken=${ghToken}`
187
- ], { cwd: repoPath, stdio: 'inherit' });
188
- }
189
-
190
- /**
191
- * Categorize a commit message into a section.
192
- * Returns: 'changes', 'fixes', 'docs', 'internal'
193
- */
194
- function categorizeCommit(subject) {
195
- const lower = subject.toLowerCase();
196
-
197
- // Fixes
198
- if (lower.startsWith('fix') || lower.startsWith('hotfix') || lower.startsWith('bugfix') ||
199
- lower.includes('fix:') || lower.includes('bug:')) {
200
- return 'fixes';
201
- }
202
-
203
- // Docs
204
- if (lower.startsWith('doc') || lower.startsWith('readme') ||
205
- lower.includes('docs:') || lower.includes('doc:') ||
206
- lower.startsWith('update readme') || lower.startsWith('rewrite readme') ||
207
- lower.startsWith('update technical') || lower.startsWith('rewrite relay') ||
208
- lower.startsWith('update relay')) {
209
- return 'docs';
210
- }
211
-
212
- // Internal (skip in release notes)
213
- if (lower.startsWith('chore') || lower.startsWith('auto-commit') ||
214
- lower.startsWith('merge pull request') || lower.startsWith('merge branch') ||
215
- lower.match(/^v\d+\.\d+\.\d+/) || lower.startsWith('mark ') ||
216
- lower.startsWith('clean up todo') || lower.startsWith('keep ')) {
217
- return 'internal';
218
- }
219
-
220
- // Everything else is a change
221
- return 'changes';
222
- }
223
-
224
- /**
225
- * Check release notes quality. Returns { ok, issues[] }.
226
- *
227
- * notesSource: 'file' (RELEASE-NOTES-v*.md or --notes-file),
228
- * 'dev-update' (ai/dev-updates/ fallback),
229
- * 'flag' (bare --notes="string"),
230
- * 'none' (nothing provided).
231
- *
232
- * For minor/major: BLOCKS if notes came from bare --notes flag or are missing.
233
- * Agents must write a RELEASE-NOTES-v{version}.md file and commit it.
234
- * For patch: WARNS only.
235
- */
236
- function checkReleaseNotes(notes, notesSource, level) {
237
- const issues = [];
238
-
239
- if (!notes) {
240
- issues.push('No release notes found. A file is REQUIRED.');
241
- issues.push('Write RELEASE-NOTES-v{version}.md or ai/dev-updates/YYYY-MM-DD--description.md');
242
- issues.push('Commit it on your branch so it is reviewable in the PR.');
243
- return { ok: false, issues, block: true };
244
- }
245
-
246
- // HARD RULE: release notes must come from a file on disk.
247
- // --notes flag is NOT accepted. Write a file. Commit it. Review it.
248
- if (notesSource === 'flag') {
249
- issues.push('Release notes must come from a file, not the --notes flag.');
250
- issues.push('Write RELEASE-NOTES-v{version}.md or ai/dev-updates/YYYY-MM-DD--description.md');
251
- issues.push('Commit it on your branch so it is reviewable in the PR before merge.');
252
- return { ok: false, issues, block: true };
253
- }
254
-
255
- // Notes too short.
256
- if (notes.length < 50) {
257
- issues.push('Release notes are too short (under 50 chars). Explain what changed and why.');
258
- }
259
-
260
- // Check for changelog-style one-liners
261
- const looksLikeChangelog = /^(fix|add|update|remove|bump|chore|refactor|docs?)[\s:]/i.test(notes);
262
- if (looksLikeChangelog && notes.length < 100) {
263
- issues.push('Notes look like a changelog entry, not a narrative. Explain the impact.');
264
- }
265
-
266
- // Narrative quality: must have at least one paragraph (not just bullets/headers)
267
- // A paragraph is 2+ consecutive lines of prose (not starting with -, *, #, |, or ```)
268
- const lines = notes.split('\n').filter(l => l.trim().length > 0);
269
- const proseLines = lines.filter(l => {
270
- const t = l.trim();
271
- return !t.startsWith('#') && !t.startsWith('-') && !t.startsWith('*') &&
272
- !t.startsWith('|') && !t.startsWith('```') && !t.startsWith('>') &&
273
- t.length > 30;
274
- });
275
- if (proseLines.length < 2) {
276
- issues.push('Release notes need narrative, not just bullets. Write at least one paragraph explaining what changed and why it matters. Tell the story.');
277
- }
278
-
279
- // Must be substantial (not just a header + bullets)
280
- if (notes.length < 200) {
281
- issues.push('Release notes are too short (under 200 chars). Every release deserves a story: what was broken or missing, what we built, why the user should care.');
282
- }
283
-
284
- // Release notes should reference at least one issue
285
- const hasIssueRef = /#\d+/.test(notes);
286
- if (!hasIssueRef) {
287
- issues.push('No issue reference found (#XX). Every release should close or reference an issue.');
288
- }
289
-
290
- return { ok: issues.length === 0, issues, block: issues.length > 0 };
291
- }
292
-
293
- /**
294
- * Scaffold a RELEASE-NOTES-v{version}.md template if one doesn't exist.
295
- * Called when the release notes gate blocks. Gives the agent a file to fill in.
296
- */
297
- export function scaffoldReleaseNotes(repoPath, version) {
298
- const dashed = version.replace(/\./g, '-');
299
- const notesPath = join(repoPath, `RELEASE-NOTES-v${dashed}.md`);
300
- if (existsSync(notesPath)) return notesPath;
301
-
302
- const pkg = JSON.parse(readFileSync(join(repoPath, 'package.json'), 'utf8'));
303
- const name = pkg.name?.replace(/^@[^/]+\//, '') || basename(repoPath);
304
-
305
- // Auto-detect issue references from commits since last tag
306
- let issueRefs = '';
307
- try {
308
- const lastTag = execFileSync('git', ['describe', '--tags', '--abbrev=0'],
309
- { cwd: repoPath, encoding: 'utf8' }).trim();
310
- const log = execFileSync('git', ['log', `${lastTag}..HEAD`, '--oneline'],
311
- { cwd: repoPath, encoding: 'utf8' });
312
- const issues = [...new Set(log.match(/#\d+/g) || [])];
313
- if (issues.length > 0) {
314
- issueRefs = issues.map(i => `- ${i}`).join('\n');
315
- }
316
- } catch {}
317
-
318
- const template = `# Release Notes: ${name} v${version}
319
-
320
- **One-line summary of what this release does**
321
-
322
- Tell the story. What was broken or missing? What did we build? Why does the user care?
323
- Write at least one real paragraph of prose. Not just bullets. The release notes gate
324
- will block if there is no narrative. Bullets are fine for details, but the story comes first.
325
-
326
- ## The story
327
-
328
- (Write a paragraph here. What was the problem? What does this release fix? Why does it matter?
329
- This is what users read. Make it worth reading.)
330
-
331
- ## Issues closed
332
-
333
- ${issueRefs || '- #XX (replace with actual issue numbers)'}
334
-
335
- ## How to verify
336
-
337
- \`\`\`bash
338
- # Commands to test the changes
339
- \`\`\`
340
- `;
341
-
342
- writeFileSync(notesPath, template);
343
- return notesPath;
344
- }
345
-
346
- /**
347
- * Check if a file was modified in commits since the last git tag.
348
- */
349
- function fileModifiedSinceLastTag(repoPath, relativePath) {
350
- try {
351
- const lastTag = execFileSync('git', ['describe', '--tags', '--abbrev=0'],
352
- { cwd: repoPath, encoding: 'utf8' }).trim();
353
- const diff = execFileSync('git', ['diff', '--name-only', lastTag, 'HEAD'],
354
- { cwd: repoPath, encoding: 'utf8' });
355
- return diff.split('\n').some(f => f.trim() === relativePath);
356
- } catch {
357
- // No tags yet or git error ... skip check
358
- return true;
359
- }
360
- }
361
-
362
- /**
363
- * Check that product docs were updated for this release.
364
- * Returns { missing: string[], ok: boolean, skipped: boolean }.
365
- * Only runs if ai/ directory structure exists.
366
- */
367
- function checkProductDocs(repoPath) {
368
- const missing = [];
369
-
370
- // Skip repos without ai/ structure
371
- const aiDir = join(repoPath, 'ai');
372
- if (!existsSync(aiDir)) return { missing: [], ok: true, skipped: true };
373
-
374
- // 1. Dev update: must have a file modified since last release tag.
375
- // Old check ("any file from last 3 days") let the same stale file pass
376
- // across 11 releases in one session. Now uses the same git-based check
377
- // as roadmap and readme-first: was the file actually changed since the tag?
378
- const devUpdatesDir = join(aiDir, 'dev-updates');
379
- if (existsSync(devUpdatesDir)) {
380
- const files = readdirSync(devUpdatesDir).filter(f => f.endsWith('.md'));
381
- if (files.length === 0) {
382
- missing.push('ai/dev-updates/ (no dev update files)');
383
- } else {
384
- const anyModified = files.some(f =>
385
- fileModifiedSinceLastTag(repoPath, `ai/dev-updates/${f}`)
386
- );
387
- if (!anyModified) {
388
- missing.push('ai/dev-updates/ (no dev update modified since last release)');
389
- }
390
- }
391
- }
392
-
393
- // 2. Roadmap: modified since last tag
394
- const roadmapPath = 'ai/product/plans-prds/roadmap.md';
395
- if (existsSync(join(repoPath, roadmapPath))) {
396
- if (!fileModifiedSinceLastTag(repoPath, roadmapPath)) {
397
- missing.push('ai/product/plans-prds/roadmap.md (not updated since last release)');
398
- }
399
- }
400
-
401
- // 3. Readme-first: modified since last tag
402
- const readmeFirstPath = 'ai/product/readme-first-product.md';
403
- if (existsSync(join(repoPath, readmeFirstPath))) {
404
- if (!fileModifiedSinceLastTag(repoPath, readmeFirstPath)) {
405
- missing.push('ai/product/readme-first-product.md (not updated since last release)');
406
- }
407
- }
408
-
409
- // 4. Product update doc: modified since last tag
410
- const productUpdateDir = join(aiDir, 'dev-updates', 'product-update');
411
- if (existsSync(productUpdateDir)) {
412
- const puFiles = readdirSync(productUpdateDir).filter(f => f.endsWith('.md'));
413
- if (puFiles.length > 0) {
414
- const anyModified = puFiles.some(f =>
415
- fileModifiedSinceLastTag(repoPath, `ai/dev-updates/product-update/${f}`)
416
- );
417
- if (!anyModified) {
418
- missing.push('ai/dev-updates/product-update/ (product update doc not updated since last release)');
419
- }
420
- }
421
- }
422
-
423
- return { missing, ok: missing.length === 0, skipped: false };
424
- }
425
-
426
- /**
427
- * Check that technical docs (SKILL.md, TECHNICAL.md) were updated
428
- * when source code changed since last release tag.
429
- * Returns { missing: string[], ok: boolean, skipped: boolean }.
430
- */
431
- function checkTechnicalDocs(repoPath) {
432
- try {
433
- let lastTag;
434
- try {
435
- lastTag = execFileSync('git', ['describe', '--tags', '--abbrev=0'],
436
- { cwd: repoPath, encoding: 'utf8' }).trim();
437
- } catch {
438
- return { missing: [], ok: true, skipped: true }; // No tags yet
439
- }
440
-
441
- const diff = execFileSync('git', ['diff', '--name-only', lastTag, 'HEAD'],
442
- { cwd: repoPath, encoding: 'utf8' });
443
- const changedFiles = diff.split('\n').map(f => f.trim()).filter(Boolean);
444
-
445
- // Find source code changes (*.mjs, *.js, *.ts) excluding non-source dirs
446
- const excludePattern = /\/(node_modules|dist|_trash|examples)\//;
447
- const sourcePattern = /\.(mjs|js|ts)$/;
448
- const sourceChanges = changedFiles.filter(f =>
449
- sourcePattern.test(f) && !excludePattern.test(f) && !f.startsWith('ai/')
450
- );
451
-
452
- if (sourceChanges.length === 0) {
453
- return { missing: [], ok: true, skipped: false }; // No source changes
454
- }
455
-
456
- // Check if any doc files were also modified
457
- const docChanges = changedFiles.filter(f =>
458
- f === 'SKILL.md' || f === 'TECHNICAL.md' ||
459
- /^tools\/[^/]+\/SKILL\.md$/.test(f) ||
460
- /^tools\/[^/]+\/TECHNICAL\.md$/.test(f)
461
- );
462
-
463
- if (docChanges.length > 0) {
464
- return { missing: [], ok: true, skipped: false }; // Docs updated
465
- }
466
-
467
- // Source changed but no doc updates
468
- const missing = [];
469
- const preview = sourceChanges.slice(0, 5).join(', ');
470
- const more = sourceChanges.length > 5 ? ` (and ${sourceChanges.length - 5} more)` : '';
471
- missing.push('Source files changed since last tag but no SKILL.md or TECHNICAL.md was updated');
472
- missing.push(`Changed: ${preview}${more}`);
473
- missing.push('Update SKILL.md or TECHNICAL.md to document these changes');
474
-
475
- return { missing, ok: false, skipped: false };
476
- } catch {
477
- return { missing: [], ok: true, skipped: true }; // Graceful fallback
478
- }
479
- }
480
-
481
- /**
482
- * Parse the interface coverage table from a markdown file.
483
- * Returns array of { name, cli, module, mcp, openclaw, skill, ccHook } or null.
484
- */
485
- function parseInterfaceCoverageTable(filePath) {
486
- if (!existsSync(filePath)) return null;
487
- const content = readFileSync(filePath, 'utf8');
488
- const lines = content.split('\n');
489
-
490
- const headerIdx = lines.findIndex(l => /^\|\s*#\s*\|\s*Tool\s*\|/i.test(l));
491
- if (headerIdx === -1) return null;
492
-
493
- const rows = [];
494
- for (let i = headerIdx + 2; i < lines.length; i++) {
495
- const line = lines[i].trim();
496
- if (!line.startsWith('|')) break;
497
- const cells = line.split('|').map(c => c.trim()).filter(c => c !== '');
498
- if (cells.length < 8) continue;
499
- // Skip category header rows (# cell is empty, non-numeric, or bold)
500
- const num = cells[0].trim();
501
- if (!num || /^\*\*/.test(num) || isNaN(parseInt(num))) continue;
502
- rows.push({
503
- name: cells[1].trim(),
504
- cli: /^Y$/i.test(cells[2]),
505
- module: /^Y$/i.test(cells[3]),
506
- mcp: /^Y$/i.test(cells[4]),
507
- openclaw: /^Y$/i.test(cells[5]),
508
- skill: /^Y$/i.test(cells[6]),
509
- ccHook: /^Y$/i.test(cells[7]),
510
- });
511
- }
512
- return rows.length > 0 ? rows : null;
513
- }
514
-
515
- /**
516
- * Read display name from a tool's SKILL.md frontmatter.
517
- * Tries display-name, then name field. Falls back to null.
518
- */
519
- function getToolDisplayName(toolPath) {
520
- const skillPath = join(toolPath, 'SKILL.md');
521
- if (!existsSync(skillPath)) return null;
522
- try {
523
- const content = readFileSync(skillPath, 'utf8');
524
- const displayMatch = content.match(/^\s*display-name:\s*"?([^"\n]+)"?/m);
525
- if (displayMatch) return displayMatch[1].trim();
526
- const nameMatch = content.match(/^name:\s*"?([^"\n]+)"?/m);
527
- if (nameMatch) return nameMatch[1].trim();
528
- } catch {}
529
- return null;
530
- }
531
-
532
- /**
533
- * Check that the interface coverage table in README.md and SKILL.md
534
- * matches the actual interfaces detected in tools/* subdirectories.
535
- * Returns { missing: string[], ok: boolean, skipped: boolean }.
536
- */
537
- function checkInterfaceCoverage(repoPath) {
538
- try {
539
- // Only applies to toolbox repos
540
- const toolsDir = join(repoPath, 'tools');
541
- if (!existsSync(toolsDir)) return { missing: [], ok: true, skipped: true };
542
-
543
- const entries = readdirSync(toolsDir, { withFileTypes: true });
544
- const tools = entries
545
- .filter(e => e.isDirectory() && existsSync(join(toolsDir, e.name, 'package.json')))
546
- .map(e => ({ name: e.name, path: join(toolsDir, e.name) }));
547
-
548
- if (tools.length === 0) return { missing: [], ok: true, skipped: true };
549
-
550
- // Detect actual interfaces for each tool
551
- const actualMap = {};
552
- for (const tool of tools) {
553
- const pkg = JSON.parse(readFileSync(join(tool.path, 'package.json'), 'utf8'));
554
- actualMap[tool.name] = {
555
- displayName: getToolDisplayName(tool.path) || tool.name,
556
- cli: !!(pkg.bin),
557
- module: !!(pkg.main || pkg.exports),
558
- mcp: ['mcp-server.mjs', 'mcp-server.js', 'dist/mcp-server.js'].some(f => existsSync(join(tool.path, f))),
559
- openclaw: existsSync(join(tool.path, 'openclaw.plugin.json')),
560
- skill: existsSync(join(tool.path, 'SKILL.md')),
561
- ccHook: !!(pkg.claudeCode?.hook) || existsSync(join(tool.path, 'guard.mjs')),
562
- };
563
- }
564
-
565
- const missing = [];
566
-
567
- // Check both README.md and SKILL.md tables
568
- for (const [label, filePath] of [['README.md', join(repoPath, 'README.md')], ['SKILL.md', join(repoPath, 'SKILL.md')]]) {
569
- const tableRows = parseInterfaceCoverageTable(filePath);
570
- if (!tableRows) continue;
571
-
572
- // Tool count
573
- if (tools.length !== tableRows.length) {
574
- missing.push(`${label}: tool count mismatch (${tools.length} in tools/, ${tableRows.length} in table)`);
575
- }
576
-
577
- // Check each actual tool against the table
578
- for (const tool of tools) {
579
- const actual = actualMap[tool.name];
580
- const displayName = actual.displayName;
581
- const tableRow = tableRows.find(r =>
582
- r.name === displayName ||
583
- r.name.toLowerCase() === displayName.toLowerCase() ||
584
- r.name.toLowerCase().includes(tool.name.replace(/^wip-/, '').replace(/-/g, ' '))
585
- );
586
-
587
- if (!tableRow) {
588
- missing.push(`${label}: ${tool.name} (${displayName}) missing from coverage table`);
589
- continue;
590
- }
591
-
592
- const ifaceMap = [
593
- ['cli', 'CLI'], ['module', 'Module'], ['mcp', 'MCP'],
594
- ['openclaw', 'OC Plugin'], ['skill', 'Skill'], ['ccHook', 'CC Hook']
595
- ];
596
-
597
- for (const [key, name] of ifaceMap) {
598
- if (actual[key] && !tableRow[key]) {
599
- missing.push(`${label}: ${displayName} has ${name} but table says no`);
600
- }
601
- if (tableRow[key] && !actual[key]) {
602
- missing.push(`${label}: ${displayName} marked ${name} in table but not detected`);
603
- }
604
- }
605
- }
606
- }
607
-
608
- return { missing, ok: missing.length === 0, skipped: false };
609
- } catch {
610
- return { missing: [], ok: true, skipped: true }; // Graceful fallback
611
- }
612
- }
613
-
614
- /**
615
- * Auto-update version/date lines in product docs before the release commit.
616
- * Updates roadmap.md "Current version" and "Last updated",
617
- * and readme-first-product.md "Last updated" and "What's Built (as of vX.Y.Z)".
618
- * Returns number of files updated.
619
- */
620
- function syncProductDocs(repoPath, newVersion) {
621
- let updated = 0;
622
- const td = new Date();
623
- const today = `${td.getFullYear()}-${String(td.getMonth()+1).padStart(2,'0')}-${String(td.getDate()).padStart(2,'0')}`;
624
-
625
- // 1. roadmap.md
626
- const roadmapPath = join(repoPath, 'ai', 'product', 'plans-prds', 'roadmap.md');
627
- if (existsSync(roadmapPath)) {
628
- let content = readFileSync(roadmapPath, 'utf8');
629
- let changed = false;
630
-
631
- // Update "Current version: vX.Y.Z"
632
- const versionRe = /(\*\*Current version:\*\*\s*)v[\d.]+/;
633
- if (versionRe.test(content)) {
634
- content = content.replace(versionRe, `$1v${newVersion}`);
635
- changed = true;
636
- }
637
-
638
- // Update "Last updated: YYYY-MM-DD"
639
- const dateRe = /(\*\*Last updated:\*\*\s*)[\d-]+/;
640
- if (dateRe.test(content)) {
641
- content = content.replace(dateRe, `$1${today}`);
642
- changed = true;
643
- }
644
-
645
- if (changed) {
646
- writeFileSync(roadmapPath, content);
647
- updated++;
648
- }
649
- }
650
-
651
- // 2. readme-first-product.md
652
- const rfpPath = join(repoPath, 'ai', 'product', 'readme-first-product.md');
653
- if (existsSync(rfpPath)) {
654
- let content = readFileSync(rfpPath, 'utf8');
655
- let changed = false;
656
-
657
- // Update "Last updated: YYYY-MM-DD"
658
- const dateRe = /(\*\*Last updated:\*\*\s*)[\d-]+/;
659
- if (dateRe.test(content)) {
660
- content = content.replace(dateRe, `$1${today}`);
661
- changed = true;
662
- }
663
-
664
- // Update "What's Built (as of vX.Y.Z)"
665
- const builtRe = /(What's Built \(as of\s*)v[\d.]+(\))/;
666
- if (builtRe.test(content)) {
667
- content = content.replace(builtRe, `$1v${newVersion}$2`);
668
- changed = true;
669
- }
670
-
671
- if (changed) {
672
- writeFileSync(rfpPath, content);
673
- updated++;
674
- }
675
- }
676
-
677
- return updated;
678
- }
679
-
680
- /**
681
- * Build release notes with narrative first, commit details second.
682
- *
683
- * Release notes should tell the story: what was built, why, and why it matters.
684
- * Commit history is included as supporting detail, not the main content.
685
- * ai/ files are excluded from the files-changed stats.
686
- */
687
- export function buildReleaseNotes(repoPath, currentVersion, newVersion, notes) {
688
- const slug = detectRepoSlug(repoPath);
689
- const pkg = JSON.parse(readFileSync(join(repoPath, 'package.json'), 'utf8'));
690
- const lines = [];
691
-
692
- // Narrative summary (the main content of the release notes)
693
- if (notes) {
694
- lines.push(notes);
695
- lines.push('');
696
- }
697
-
698
- // Gather commits since last tag
699
- const prevTag = `v${currentVersion}`;
700
- let rawCommits = [];
701
- try {
702
- const raw = execFileSync('git', [
703
- 'log', `${prevTag}..HEAD`, '--pretty=format:%h\t%s'
704
- ], { cwd: repoPath, encoding: 'utf8' }).trim();
705
- if (raw) rawCommits = raw.split('\n').map(line => {
706
- const [hash, ...rest] = line.split('\t');
707
- return { hash, subject: rest.join('\t') };
708
- });
709
- } catch {
710
- try {
711
- const raw = execFileSync('git', [
712
- 'log', '--pretty=format:%h\t%s', '-30'
713
- ], { cwd: repoPath, encoding: 'utf8' }).trim();
714
- if (raw) rawCommits = raw.split('\n').map(line => {
715
- const [hash, ...rest] = line.split('\t');
716
- return { hash, subject: rest.join('\t') };
717
- });
718
- } catch {}
719
- }
720
-
721
- // Categorize commits
722
- const categories = { changes: [], fixes: [], docs: [], internal: [] };
723
- for (const commit of rawCommits) {
724
- const cat = categorizeCommit(commit.subject);
725
- categories[cat].push(commit);
726
- }
727
-
728
- // Commit details section (supporting detail, not the headline)
729
- const hasCommits = categories.changes.length + categories.fixes.length + categories.docs.length > 0;
730
- if (hasCommits) {
731
- lines.push('<details>');
732
- lines.push('<summary>What changed (commits)</summary>');
733
- lines.push('');
734
-
735
- if (categories.changes.length > 0) {
736
- lines.push('**Changes**');
737
- for (const c of categories.changes) {
738
- lines.push(`- ${c.subject} (${c.hash})`);
739
- }
740
- lines.push('');
741
- }
742
-
743
- if (categories.fixes.length > 0) {
744
- lines.push('**Fixes**');
745
- for (const c of categories.fixes) {
746
- lines.push(`- ${c.subject} (${c.hash})`);
747
- }
748
- lines.push('');
749
- }
750
-
751
- if (categories.docs.length > 0) {
752
- lines.push('**Docs**');
753
- for (const c of categories.docs) {
754
- lines.push(`- ${c.subject} (${c.hash})`);
755
- }
756
- lines.push('');
757
- }
758
-
759
- lines.push('</details>');
760
- lines.push('');
761
- }
762
-
763
- // Install section
764
- lines.push('### Install');
765
- lines.push('```bash');
766
- lines.push(`npm install -g ${pkg.name}@${newVersion}`);
767
- lines.push('```');
768
- lines.push('');
769
- lines.push('Or update your local clone:');
770
- lines.push('```bash');
771
- lines.push('git pull origin main');
772
- lines.push('```');
773
- lines.push('');
774
-
775
- // Attribution
776
- lines.push('---');
777
- lines.push('');
778
- lines.push('Built by Parker Todd Brooks, Lēsa (OpenClaw, Claude Opus 4.6), Claude Code (Claude Opus 4.6).');
779
-
780
- // Compare URL
781
- if (slug) {
782
- lines.push('');
783
- lines.push(`Full changelog: https://github.com/${slug}/compare/v${currentVersion}...v${newVersion}`);
784
- }
785
-
786
- return lines.join('\n');
787
- }
788
-
789
- /**
790
- * Create a GitHub release with detailed notes.
791
- */
792
- export function createGitHubRelease(repoPath, newVersion, notes, currentVersion) {
793
- const repoSlug = detectRepoSlug(repoPath);
794
- const body = buildReleaseNotes(repoPath, currentVersion, newVersion, notes);
795
-
796
- // Write notes to a temp file to avoid shell escaping issues
797
- const tmpFile = join(repoPath, '.release-notes-tmp.md');
798
- writeFileSync(tmpFile, body);
799
-
800
- try {
801
- execFileSync('gh', [
802
- 'release', 'create', `v${newVersion}`,
803
- '--title', `v${newVersion}`,
804
- '--notes-file', '.release-notes-tmp.md',
805
- '--repo', repoSlug
806
- ], { cwd: repoPath, stdio: 'inherit' });
807
-
808
- // Bug fix #121: verify the release was actually created
809
- try {
810
- const verify = execFileSync('gh', [
811
- 'release', 'view', `v${newVersion}`,
812
- '--repo', repoSlug, '--json', 'body', '--jq', '.body | length'
813
- ], { cwd: repoPath, encoding: 'utf8' }).trim();
814
- const bodyLen = parseInt(verify, 10);
815
- if (bodyLen < 50) {
816
- console.warn(` ! GitHub release body is only ${bodyLen} chars. Notes may be truncated.`);
817
- }
818
- } catch {}
819
-
820
- // Auto-close referenced issues
821
- const issueNums = [...new Set((body.match(/#(\d+)/g) || []).map(m => m.slice(1)))];
822
- for (const num of issueNums) {
823
- try {
824
- // Only close if issue exists and is open on the public repo
825
- const publicSlug = repoSlug.replace(/-private$/, '');
826
- execFileSync('gh', [
827
- 'issue', 'close', num,
828
- '--repo', publicSlug,
829
- '--comment', `Closed by v${newVersion}. See release notes.`
830
- ], { cwd: repoPath, stdio: 'pipe' });
831
- console.log(` ✓ Closed #${num} on ${publicSlug}`);
832
- } catch {
833
- // Issue doesn't exist on public repo or already closed. Fine.
834
- }
835
- }
836
- } finally {
837
- try { execFileSync('rm', ['-f', tmpFile]); } catch {}
838
- }
839
- }
840
-
841
- /**
842
- * Publish skill to ClawHub.
843
- */
844
- export function publishClawHub(repoPath, newVersion, notes) {
845
- const skillPath = join(repoPath, 'SKILL.md');
846
- if (!existsSync(skillPath)) return false;
847
-
848
- const slug = detectSkillSlug(repoPath);
849
- const changelog = notes || 'Release.';
850
-
851
- execFileSync('clawhub', [
852
- 'publish', repoPath,
853
- '--slug', slug,
854
- '--version', newVersion,
855
- '--changelog', changelog
856
- ], { cwd: repoPath, stdio: 'inherit' });
857
- return true;
858
- }
859
-
860
- // ── Skill Publish ────────────────────────────────────────────────────
861
-
862
- /**
863
- * Publish SKILL.md to website as plain text.
864
- *
865
- * Auto-detects: if SKILL.md exists and WIP_WEBSITE_REPO is set,
866
- * publishes automatically. No config file needed.
867
- *
868
- * Name resolution (first match wins):
869
- * 1. .publish-skill.json { "name": "memory-crystal" }
870
- * 2. SKILL.md frontmatter name: field
871
- * 3. Directory name (basename of repoPath)
872
- *
873
- * Copies SKILL.md to {website}/wip.computer/install/{name}.txt
874
- * Then runs deploy.sh to push to VPS.
875
- *
876
- * Non-blocking: returns result, never throws.
877
- */
878
- export function publishSkillToWebsite(repoPath) {
879
- // Resolve website repo: .publish-skill.json > env var
880
- let websiteRepo;
881
- let targetName;
882
- const configPath = join(repoPath, '.publish-skill.json');
883
- let publishConfig = {};
884
- if (existsSync(configPath)) {
885
- try { publishConfig = JSON.parse(readFileSync(configPath, 'utf8')); } catch {}
886
- }
887
-
888
- websiteRepo = publishConfig.websiteRepo || process.env.WIP_WEBSITE_REPO;
889
- if (!websiteRepo) return { skipped: true, reason: 'no websiteRepo in .publish-skill.json and WIP_WEBSITE_REPO not set' };
890
-
891
- // Find SKILL.md: check root, then skills/*/SKILL.md
892
- let skillFile = join(repoPath, 'SKILL.md');
893
- if (!existsSync(skillFile)) {
894
- const skillsDir = join(repoPath, 'skills');
895
- if (existsSync(skillsDir)) {
896
- for (const sub of readdirSync(skillsDir)) {
897
- const candidate = join(skillsDir, sub, 'SKILL.md');
898
- if (existsSync(candidate)) { skillFile = candidate; break; }
899
- }
900
- }
901
- }
902
- if (!existsSync(skillFile)) return { skipped: true, reason: 'no SKILL.md found' };
903
-
904
- // Resolve target name: config > package.json > directory name
905
- // SKILL.md frontmatter name is skipped because it's a short slug
906
- // (e.g., "memory") not the full install name (e.g., "memory-crystal").
907
-
908
- // 1. Explicit config (optional, overrides auto-detect)
909
- if (publishConfig.name) targetName = publishConfig.name;
910
-
911
- // 2. package.json name (strip @scope/ prefix, most reliable)
912
- if (!targetName) {
913
- const pkgPath = join(repoPath, 'package.json');
914
- if (existsSync(pkgPath)) {
915
- try {
916
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
917
- if (pkg.name) targetName = pkg.name.replace(/^@[^/]+\//, '');
918
- } catch {}
919
- }
920
- }
921
-
922
- // 3. Directory name fallback (strip -private suffix)
923
- if (!targetName) {
924
- targetName = basename(repoPath).replace(/-private$/, '').toLowerCase();
925
- }
926
-
927
- // Copy to website install dir
928
- const installDir = join(websiteRepo, 'wip.computer', 'install');
929
- if (!existsSync(installDir)) {
930
- try { mkdirSync(installDir, { recursive: true }); } catch {}
931
- }
932
-
933
- const targetFile = join(installDir, `${targetName}.txt`);
934
- try {
935
- const content = readFileSync(skillFile, 'utf8');
936
- writeFileSync(targetFile, content);
937
- } catch (e) {
938
- return { ok: false, error: `copy failed: ${e.message}` };
939
- }
940
-
941
- // Deploy to VPS (non-blocking ... warn on failure)
942
- const deployScript = join(websiteRepo, 'deploy.sh');
943
- if (existsSync(deployScript)) {
944
- try {
945
- execSync(`bash deploy.sh`, { cwd: websiteRepo, stdio: 'pipe', timeout: 30000 });
946
- } catch (e) {
947
- return { ok: true, deployed: false, target: targetName, error: `deploy failed: ${e.message}` };
948
- }
949
- } else {
950
- return { ok: true, deployed: false, target: targetName, error: 'no deploy.sh found' };
951
- }
952
-
953
- return { ok: true, deployed: true, target: targetName };
954
- }
955
-
956
- // ── Helpers ──────────────────────────────────────────────────────────
957
-
958
- function getNpmToken() {
959
- try {
960
- return execSync(
961
- `OP_SERVICE_ACCOUNT_TOKEN=$(cat ~/.openclaw/secrets/op-sa-token) op item get "npm Token" --vault "Agent Secrets" --fields label=password --reveal 2>/dev/null`,
962
- { encoding: 'utf8' }
963
- ).trim();
964
- } catch {
965
- throw new Error('Could not fetch npm token from 1Password. Check op CLI and SA token.');
966
- }
967
- }
968
-
969
- function detectSkillSlug(repoPath) {
970
- // Read the name field from SKILL.md frontmatter (agentskills.io spec: lowercase-hyphen slug).
971
- // Falls back to directory name.
972
- const skillPath = join(repoPath, 'SKILL.md');
973
- if (existsSync(skillPath)) {
974
- const content = readFileSync(skillPath, 'utf8');
975
- const nameMatch = content.match(/^---[\s\S]*?\nname:\s*(.+?)\n/);
976
- if (nameMatch) {
977
- const name = nameMatch[1].trim().replace(/^["']|["']$/g, '');
978
- // Only use if it looks like a slug (lowercase, hyphens)
979
- if (/^[a-z][a-z0-9-]*$/.test(name)) return name;
980
- }
981
- }
982
- return basename(repoPath).toLowerCase();
983
- }
984
-
985
- function detectRepoSlug(repoPath) {
986
- try {
987
- const url = execSync('git remote get-url origin', { cwd: repoPath, encoding: 'utf8' }).trim();
988
- // git@github.com:wipcomputer/wip-grok.git or https://github.com/wipcomputer/wip-grok.git
989
- const match = url.match(/github\.com[:/](.+?)(?:\.git)?$/);
990
- return match ? match[1] : null;
991
- } catch {
992
- return null;
993
- }
994
- }
995
-
996
- // ── Stale Branch Check ──────────────────────────────────────────────
997
-
998
- /**
999
- * Check for remote branches that are already merged into origin/main.
1000
- * These should be cleaned up before releasing.
1001
- *
1002
- * For patch: WARN (non-blocking, just print stale branches).
1003
- * For minor/major: BLOCK (return { failed: true }).
1004
- *
1005
- * Filters out origin/main, origin/HEAD, and already-renamed --merged- branches.
1006
- */
1007
- export function checkStaleBranches(repoPath, level) {
1008
- try {
1009
- // Fetch latest remote state so --merged check is accurate
1010
- try {
1011
- execFileSync('git', ['fetch', '--prune'], { cwd: repoPath, stdio: 'pipe' });
1012
- } catch {
1013
- // Non-fatal: proceed with local state if fetch fails
1014
- }
1015
-
1016
- const raw = execFileSync('git', ['branch', '-r', '--merged', 'origin/main'], {
1017
- cwd: repoPath, encoding: 'utf8'
1018
- }).trim();
1019
-
1020
- if (!raw) return { stale: [], ok: true };
1021
-
1022
- const stale = raw.split('\n')
1023
- .map(b => b.trim())
1024
- .filter(b =>
1025
- b &&
1026
- !b.includes('origin/main') &&
1027
- !b.includes('origin/HEAD') &&
1028
- !b.includes('--merged-')
1029
- );
1030
-
1031
- if (stale.length === 0) return { stale: [], ok: true };
1032
-
1033
- const isMinorOrMajor = level === 'minor' || level === 'major';
1034
- return {
1035
- stale,
1036
- ok: !isMinorOrMajor,
1037
- blocked: isMinorOrMajor,
1038
- };
1039
- } catch {
1040
- // Git command failed... skip check gracefully
1041
- return { stale: [], ok: true, skipped: true };
1042
- }
1043
- }
1044
-
1045
- // ── Main ────────────────────────────────────────────────────────────
1046
-
1047
- /**
1048
- * Run the full release pipeline.
1049
- */
1050
- export async function release({ repoPath, level, notes, notesSource, dryRun, noPublish, skipProductCheck, skipStaleCheck, skipWorktreeCheck, skipTechDocsCheck, skipCoverageCheck }) {
1051
- repoPath = repoPath || process.cwd();
1052
- const currentVersion = detectCurrentVersion(repoPath);
1053
- const newVersion = bumpSemver(currentVersion, level);
1054
- const repoName = basename(repoPath);
1055
-
1056
- console.log('');
1057
- console.log(` ${repoName}: ${currentVersion} -> ${newVersion} (${level})`);
1058
- console.log(` ${'─'.repeat(40)}`);
1059
-
1060
- // -1. Worktree guard: block releases from linked worktrees
1061
- if (!skipWorktreeCheck) {
1062
- try {
1063
- const gitDir = execFileSync('git', ['rev-parse', '--git-dir'], {
1064
- cwd: repoPath, encoding: 'utf8'
1065
- }).trim();
1066
-
1067
- // Linked worktrees have "/worktrees/" in their git-dir path
1068
- if (gitDir.includes('/worktrees/')) {
1069
- // Get the main working tree path from `git worktree list`
1070
- const worktreeList = execFileSync('git', ['worktree', 'list', '--porcelain'], {
1071
- cwd: repoPath, encoding: 'utf8'
1072
- });
1073
- const mainWorktree = worktreeList.split('\n')
1074
- .find(line => line.startsWith('worktree '));
1075
- const mainPath = mainWorktree ? mainWorktree.replace('worktree ', '') : '(unknown)';
1076
-
1077
- console.log(` \u2717 wip-release must run from the main working tree, not a worktree.`);
1078
- console.log(` Current: ${repoPath}`);
1079
- console.log(` Main working tree: ${mainPath}`);
1080
- console.log(` Switch to the main working tree and run again.`);
1081
- console.log('');
1082
- return { currentVersion, newVersion, dryRun: false, failed: true };
1083
- }
1084
- console.log(' \u2713 Running from main working tree');
1085
- } catch {
1086
- // Git command failed... skip check gracefully
1087
- }
1088
- }
1089
-
1090
- // 0. License compliance gate
1091
- const configPath = join(repoPath, '.license-guard.json');
1092
- if (existsSync(configPath)) {
1093
- const config = JSON.parse(readFileSync(configPath, 'utf8'));
1094
- const licenseIssues = [];
1095
-
1096
- const licensePath = join(repoPath, 'LICENSE');
1097
- if (!existsSync(licensePath)) {
1098
- licenseIssues.push('LICENSE file is missing');
1099
- } else {
1100
- const licenseText = readFileSync(licensePath, 'utf8');
1101
- if (!licenseText.includes(config.copyright)) {
1102
- licenseIssues.push(`LICENSE copyright does not match "${config.copyright}"`);
1103
- }
1104
- if (config.license === 'MIT+AGPL' && !licenseText.includes('AGPL') && !licenseText.includes('GNU Affero')) {
1105
- licenseIssues.push('LICENSE is MIT-only but config requires MIT+AGPL');
1106
- }
1107
- }
1108
-
1109
- if (!existsSync(join(repoPath, 'CLA.md'))) {
1110
- licenseIssues.push('CLA.md is missing');
1111
- }
1112
-
1113
- const readmePath = join(repoPath, 'README.md');
1114
- if (existsSync(readmePath)) {
1115
- const readme = readFileSync(readmePath, 'utf8');
1116
- if (!readme.includes('## License')) licenseIssues.push('README.md missing ## License section');
1117
- if (config.license === 'MIT+AGPL' && !readme.includes('AGPL')) licenseIssues.push('README.md License section missing AGPL reference');
1118
- }
1119
-
1120
- if (licenseIssues.length > 0) {
1121
- console.log(` ✗ License compliance failed:`);
1122
- for (const issue of licenseIssues) console.log(` - ${issue}`);
1123
- console.log(`\n Run \`wip-license-guard check --fix\` to auto-repair, then try again.`);
1124
- console.log('');
1125
- return { currentVersion, newVersion, dryRun: false, failed: true };
1126
- }
1127
- console.log(` ✓ License compliance passed`);
1128
- }
1129
-
1130
- // 0.5. Product docs check
1131
- if (!skipProductCheck) {
1132
- const productCheck = checkProductDocs(repoPath);
1133
- if (!productCheck.skipped) {
1134
- if (productCheck.ok) {
1135
- console.log(' ✓ Product docs up to date');
1136
- } else {
1137
- const isMinorOrMajor = level === 'minor' || level === 'major';
1138
- const prefix = isMinorOrMajor ? '✗' : '!';
1139
- console.log(` ${prefix} Product docs need attention:`);
1140
- for (const m of productCheck.missing) console.log(` - ${m}`);
1141
- if (isMinorOrMajor) {
1142
- console.log('');
1143
- console.log(' Update product docs before a minor/major release.');
1144
- console.log(' Use --skip-product-check to override.');
1145
- console.log('');
1146
- return { currentVersion, newVersion, dryRun: false, failed: true };
1147
- }
1148
- }
1149
- }
1150
- }
1151
-
1152
- // 0.75. Release notes quality gate
1153
- {
1154
- const notesCheck = checkReleaseNotes(notes, notesSource || 'flag', level);
1155
- if (notesCheck.ok) {
1156
- const sourceLabel = notesSource === 'file' ? 'from file' : notesSource === 'dev-update' ? 'from dev update' : 'from --notes';
1157
- console.log(` ✓ Release notes OK (${sourceLabel})`);
1158
- } else {
1159
- console.log(` ✗ Release notes blocked:`);
1160
- for (const issue of notesCheck.issues) console.log(` - ${issue}`);
1161
- console.log('');
1162
- // Scaffold a template so the agent has something to fill in
1163
- const templatePath = scaffoldReleaseNotes(repoPath, newVersion);
1164
- console.log(` Scaffolded template: ${basename(templatePath)}`);
1165
- console.log(' Fill it in, commit, then run wip-release again.');
1166
- console.log('');
1167
- return { currentVersion, newVersion, dryRun: false, failed: true };
1168
- }
1169
- }
1170
-
1171
- // 0.8. Stale remote branch check
1172
- if (!skipStaleCheck) {
1173
- const staleCheck = checkStaleBranches(repoPath, level);
1174
- if (staleCheck.skipped) {
1175
- // Silently skip if git command failed
1176
- } else if (staleCheck.stale.length === 0) {
1177
- console.log(' ✓ No stale remote branches');
1178
- } else {
1179
- const isMinorOrMajor = level === 'minor' || level === 'major';
1180
- const prefix = isMinorOrMajor ? '✗' : '!';
1181
- console.log(` ${prefix} Stale remote branches merged into main:`);
1182
- for (const b of staleCheck.stale) console.log(` - ${b}`);
1183
- if (isMinorOrMajor) {
1184
- console.log('');
1185
- console.log(' Clean up stale branches before a minor/major release.');
1186
- console.log(' Delete them with: git push origin --delete <branch>');
1187
- console.log(' Use --skip-stale-check to override.');
1188
- console.log('');
1189
- return { currentVersion, newVersion, dryRun: false, failed: true };
1190
- }
1191
- }
1192
- }
1193
-
1194
- // 0.85. Technical docs check
1195
- if (!skipTechDocsCheck) {
1196
- const techDocsCheck = checkTechnicalDocs(repoPath);
1197
- if (!techDocsCheck.skipped) {
1198
- if (techDocsCheck.ok) {
1199
- console.log(' ✓ Technical docs up to date');
1200
- } else {
1201
- const isMinorOrMajor = level === 'minor' || level === 'major';
1202
- const prefix = isMinorOrMajor ? '✗' : '!';
1203
- console.log(` ${prefix} Technical docs need attention:`);
1204
- for (const m of techDocsCheck.missing) console.log(` - ${m}`);
1205
- if (isMinorOrMajor) {
1206
- console.log('');
1207
- console.log(' Update SKILL.md or TECHNICAL.md before a minor/major release.');
1208
- console.log(' Use --skip-tech-docs-check to override.');
1209
- console.log('');
1210
- return { currentVersion, newVersion, dryRun: false, failed: true };
1211
- }
1212
- }
1213
- }
1214
- }
1215
-
1216
- // 0.9. Interface coverage check
1217
- if (!skipCoverageCheck) {
1218
- const coverageCheck = checkInterfaceCoverage(repoPath);
1219
- if (!coverageCheck.skipped) {
1220
- if (coverageCheck.ok) {
1221
- console.log(' ✓ Interface coverage table matches');
1222
- } else {
1223
- const isMinorOrMajor = level === 'minor' || level === 'major';
1224
- const prefix = isMinorOrMajor ? '✗' : '!';
1225
- console.log(` ${prefix} Interface coverage table has mismatches:`);
1226
- for (const m of coverageCheck.missing) console.log(` - ${m}`);
1227
- if (isMinorOrMajor) {
1228
- console.log('');
1229
- console.log(' Update the coverage table in README.md and SKILL.md.');
1230
- console.log(' Use --skip-coverage-check to override.');
1231
- console.log('');
1232
- return { currentVersion, newVersion, dryRun: false, failed: true };
1233
- }
1234
- }
1235
- }
1236
- }
1237
-
1238
- if (dryRun) {
1239
- // Product docs check (dry-run)
1240
- if (!skipProductCheck) {
1241
- const productCheck = checkProductDocs(repoPath);
1242
- if (!productCheck.skipped) {
1243
- if (productCheck.ok) {
1244
- console.log(' [dry run] ✓ Product docs up to date');
1245
- } else {
1246
- const isMinorOrMajor = level === 'minor' || level === 'major';
1247
- console.log(` [dry run] ${isMinorOrMajor ? '✗ Would BLOCK' : '! Would WARN'}: product docs need updates`);
1248
- for (const m of productCheck.missing) console.log(` - ${m}`);
1249
- }
1250
- }
1251
- }
1252
- // Release notes check (dry-run)
1253
- {
1254
- const notesCheck = checkReleaseNotes(notes, notesSource || 'flag', level);
1255
- if (notesCheck.ok) {
1256
- const sourceLabel = notesSource === 'file' ? 'from file' : notesSource === 'dev-update' ? 'from dev update' : 'from --notes';
1257
- console.log(` [dry run] ✓ Release notes OK (${sourceLabel})`);
1258
- } else {
1259
- const isMinorOrMajor = level === 'minor' || level === 'major';
1260
- console.log(` [dry run] ${isMinorOrMajor ? '✗ Would BLOCK' : '! Would WARN'}: release notes need attention`);
1261
- for (const issue of notesCheck.issues) console.log(` - ${issue}`);
1262
- }
1263
- }
1264
- // Stale branch check (dry-run)
1265
- if (!skipStaleCheck) {
1266
- const staleCheck = checkStaleBranches(repoPath, level);
1267
- if (!staleCheck.skipped && staleCheck.stale.length > 0) {
1268
- const isMinorOrMajor = level === 'minor' || level === 'major';
1269
- console.log(` [dry run] ${isMinorOrMajor ? '✗ Would BLOCK' : '! Would WARN'}: stale remote branches`);
1270
- for (const b of staleCheck.stale) console.log(` - ${b}`);
1271
- } else if (!staleCheck.skipped) {
1272
- console.log(' [dry run] ✓ No stale remote branches');
1273
- }
1274
- }
1275
- // Technical docs check (dry-run)
1276
- if (!skipTechDocsCheck) {
1277
- const techDocsCheck = checkTechnicalDocs(repoPath);
1278
- if (!techDocsCheck.skipped) {
1279
- if (techDocsCheck.ok) {
1280
- console.log(' [dry run] ✓ Technical docs up to date');
1281
- } else {
1282
- const isMinorOrMajor = level === 'minor' || level === 'major';
1283
- console.log(` [dry run] ${isMinorOrMajor ? '✗ Would BLOCK' : '! Would WARN'}: technical docs need updates`);
1284
- for (const m of techDocsCheck.missing) console.log(` - ${m}`);
1285
- }
1286
- }
1287
- }
1288
- // Interface coverage check (dry-run)
1289
- if (!skipCoverageCheck) {
1290
- const coverageCheck = checkInterfaceCoverage(repoPath);
1291
- if (!coverageCheck.skipped) {
1292
- if (coverageCheck.ok) {
1293
- console.log(' [dry run] ✓ Interface coverage table matches');
1294
- } else {
1295
- const isMinorOrMajor = level === 'minor' || level === 'major';
1296
- console.log(` [dry run] ${isMinorOrMajor ? '✗ Would BLOCK' : '! Would WARN'}: interface coverage mismatches`);
1297
- for (const m of coverageCheck.missing) console.log(` - ${m}`);
1298
- }
1299
- }
1300
- }
1301
- const hasSkill = existsSync(join(repoPath, 'SKILL.md'));
1302
- console.log(` [dry run] Would bump package.json to ${newVersion}`);
1303
- if (hasSkill) console.log(` [dry run] Would update SKILL.md version`);
1304
- console.log(` [dry run] Would update CHANGELOG.md`);
1305
- console.log(` [dry run] Would commit and tag v${newVersion}`);
1306
- if (!noPublish) {
1307
- console.log(` [dry run] Would publish to npm (@wipcomputer scope)`);
1308
- console.log(` [dry run] GitHub Packages: handled by deploy-public.sh`);
1309
- console.log(` [dry run] Would create GitHub release v${newVersion}`);
1310
- if (hasSkill) console.log(` [dry run] Would publish to ClawHub`);
1311
- // Skill-to-website dry run (auto-detects SKILL.md, no config needed)
1312
- if (hasSkill) {
1313
- const envSet = !!process.env.WIP_WEBSITE_REPO;
1314
- if (envSet) {
1315
- // Resolve name same way as publishSkillToWebsite
1316
- let dryName;
1317
- const publishConfig = join(repoPath, '.publish-skill.json');
1318
- if (existsSync(publishConfig)) {
1319
- try { dryName = JSON.parse(readFileSync(publishConfig, 'utf8')).name; } catch {}
1320
- }
1321
- if (!dryName) {
1322
- const pkgPath = join(repoPath, 'package.json');
1323
- if (existsSync(pkgPath)) {
1324
- try { dryName = JSON.parse(readFileSync(pkgPath, 'utf8')).name?.replace(/^@[^/]+\//, ''); } catch {}
1325
- }
1326
- }
1327
- if (!dryName) dryName = basename(repoPath).replace(/-private$/, '').toLowerCase();
1328
- console.log(` [dry run] Would publish SKILL.md to website: install/${dryName}.txt`);
1329
- } else {
1330
- console.log(` [dry run] Would publish SKILL.md to website but WIP_WEBSITE_REPO not set`);
1331
- }
1332
- }
1333
- }
1334
- console.log('');
1335
- console.log(` Dry run complete. No changes made.`);
1336
- console.log('');
1337
- return { currentVersion, newVersion, dryRun: true };
1338
- }
1339
-
1340
- // 1. Bump package.json
1341
- writePackageVersion(repoPath, newVersion);
1342
- console.log(` ✓ package.json -> ${newVersion}`);
1343
-
1344
- // 1.5. Bump sub-tool versions in toolbox repos (tools/*/)
1345
- const toolsDir = join(repoPath, 'tools');
1346
- if (existsSync(toolsDir)) {
1347
- let subBumped = 0;
1348
- try {
1349
- const entries = readdirSync(toolsDir, { withFileTypes: true });
1350
- for (const entry of entries) {
1351
- if (!entry.isDirectory()) continue;
1352
- const subPkgPath = join(toolsDir, entry.name, 'package.json');
1353
- if (existsSync(subPkgPath)) {
1354
- try {
1355
- const subPkg = JSON.parse(readFileSync(subPkgPath, 'utf8'));
1356
- subPkg.version = newVersion;
1357
- writeFileSync(subPkgPath, JSON.stringify(subPkg, null, 2) + '\n');
1358
- subBumped++;
1359
- } catch {}
1360
- }
1361
- }
1362
- } catch {}
1363
- if (subBumped > 0) {
1364
- console.log(` ✓ ${subBumped} sub-tool(s) -> ${newVersion}`);
1365
- }
1366
- }
1367
-
1368
- // 2. Sync SKILL.md
1369
- if (syncSkillVersion(repoPath, newVersion)) {
1370
- console.log(` ✓ SKILL.md -> ${newVersion}`);
1371
- }
1372
-
1373
- // 3. Update CHANGELOG.md
1374
- updateChangelog(repoPath, newVersion, notes);
1375
- console.log(` ✓ CHANGELOG.md updated`);
1376
-
1377
- // 3.5. Move RELEASE-NOTES-v*.md to _trash/
1378
- const trashed = trashReleaseNotes(repoPath);
1379
- if (trashed > 0) {
1380
- console.log(` ✓ Moved ${trashed} RELEASE-NOTES file(s) to _trash/`);
1381
- }
1382
-
1383
- // 3.75. Auto-update product docs version/date
1384
- const docsUpdated = syncProductDocs(repoPath, newVersion);
1385
- if (docsUpdated > 0) {
1386
- console.log(` ✓ Product docs synced to v${newVersion} (${docsUpdated} file(s))`);
1387
- }
1388
-
1389
- // 4. Git commit + tag
1390
- gitCommitAndTag(repoPath, newVersion, notes);
1391
- console.log(` ✓ Committed and tagged v${newVersion}`);
1392
-
1393
- // 5. Push commit + tag
1394
- try {
1395
- execSync('git push && git push --tags', { cwd: repoPath, stdio: 'pipe' });
1396
- console.log(` ✓ Pushed to remote`);
1397
- } catch {
1398
- console.log(` ! Push failed (maybe branch protection). Push manually.`);
1399
- }
1400
-
1401
- // Distribution results collector (#104)
1402
- const distResults = [];
1403
-
1404
- if (!noPublish) {
1405
- // 6. npm publish
1406
- try {
1407
- publishNpm(repoPath);
1408
- const pkg = JSON.parse(readFileSync(join(repoPath, 'package.json'), 'utf8'));
1409
- distResults.push({ target: 'npm', status: 'ok', detail: `${pkg.name}@${newVersion}` });
1410
- console.log(` ✓ Published to npm`);
1411
- } catch (e) {
1412
- distResults.push({ target: 'npm', status: 'failed', detail: e.message });
1413
- console.log(` ✗ npm publish failed: ${e.message}`);
1414
- }
1415
-
1416
- // 7. GitHub Packages ... SKIPPED from private repos.
1417
- // deploy-public.sh publishes to GitHub Packages from the public repo clone.
1418
- // Publishing from private ties the package to the private repo, making it
1419
- // invisible on the public repo's Packages tab. (#53)
1420
- console.log(` - GitHub Packages: handled by deploy-public.sh (from public repo)`);
1421
-
1422
- // 8. GitHub release
1423
- try {
1424
- createGitHubRelease(repoPath, newVersion, notes, currentVersion);
1425
- distResults.push({ target: 'GitHub', status: 'ok', detail: `v${newVersion}` });
1426
- console.log(` ✓ GitHub release v${newVersion} created`);
1427
- } catch (e) {
1428
- distResults.push({ target: 'GitHub', status: 'failed', detail: e.message });
1429
- console.log(` ✗ GitHub release failed: ${e.message}`);
1430
- }
1431
-
1432
- // 9. ClawHub skill publish (root + sub-tools)
1433
- const rootSkill = join(repoPath, 'SKILL.md');
1434
- const toolsDir = join(repoPath, 'tools');
1435
-
1436
- // Publish root SKILL.md
1437
- if (existsSync(rootSkill)) {
1438
- try {
1439
- publishClawHub(repoPath, newVersion, notes);
1440
- const slug = detectSkillSlug(repoPath);
1441
- distResults.push({ target: `ClawHub`, status: 'ok', detail: `${slug}@${newVersion}` });
1442
- console.log(` ✓ Published to ClawHub: ${slug}`);
1443
- } catch (e) {
1444
- distResults.push({ target: 'ClawHub (root)', status: 'failed', detail: e.message });
1445
- console.log(` ✗ ClawHub publish failed: ${e.message}`);
1446
- }
1447
- }
1448
-
1449
- // Publish each sub-tool SKILL.md (#97)
1450
- if (existsSync(toolsDir)) {
1451
- for (const tool of readdirSync(toolsDir)) {
1452
- const toolPath = join(toolsDir, tool);
1453
- const toolSkill = join(toolPath, 'SKILL.md');
1454
- if (existsSync(toolSkill)) {
1455
- try {
1456
- publishClawHub(toolPath, newVersion, notes);
1457
- const slug = detectSkillSlug(toolPath);
1458
- distResults.push({ target: `ClawHub`, status: 'ok', detail: `${slug}@${newVersion}` });
1459
- console.log(` ✓ Published to ClawHub: ${slug}`);
1460
- } catch (e) {
1461
- const slug = detectSkillSlug(toolPath);
1462
- distResults.push({ target: `ClawHub (${slug})`, status: 'failed', detail: e.message });
1463
- console.log(` ✗ ClawHub publish failed for ${slug}: ${e.message}`);
1464
- }
1465
- }
1466
- }
1467
- }
1468
-
1469
- // 9.5. Publish SKILL.md to website as plain text
1470
- const skillWebResult = publishSkillToWebsite(repoPath);
1471
- if (skillWebResult.skipped) {
1472
- // Silent skip ... no config or env var
1473
- } else if (skillWebResult.ok) {
1474
- const deployNote = skillWebResult.deployed ? '' : ' (copied, deploy skipped)';
1475
- distResults.push({ target: 'Website', status: 'ok', detail: `install/${skillWebResult.target}.txt${deployNote}` });
1476
- console.log(` ✓ Published to website: install/${skillWebResult.target}.txt${deployNote}`);
1477
- if (!skillWebResult.deployed && skillWebResult.error) {
1478
- console.log(` ! ${skillWebResult.error}`);
1479
- }
1480
- } else {
1481
- distResults.push({ target: 'Website', status: 'failed', detail: skillWebResult.error });
1482
- console.log(` ✗ Website publish failed: ${skillWebResult.error}`);
1483
- }
1484
- }
1485
-
1486
- // Distribution summary (#104)
1487
- if (distResults.length > 0) {
1488
- console.log('');
1489
- console.log(' Distribution:');
1490
- for (const r of distResults) {
1491
- const icon = r.status === 'ok' ? '✓' : '✗';
1492
- console.log(` ${icon} ${r.target}: ${r.detail}`);
1493
- }
1494
- const failed = distResults.filter(r => r.status !== 'ok');
1495
- if (failed.length > 0) {
1496
- console.log(`\n ! ${failed.length} of ${distResults.length} target(s) failed.`);
1497
- }
1498
- }
1499
-
1500
- // 10. Post-merge branch cleanup: rename merged branches with --merged-YYYY-MM-DD
1501
- try {
1502
- const merged = execSync(
1503
- 'git branch --merged main', { cwd: repoPath, encoding: 'utf8' }
1504
- ).split('\n')
1505
- .map(b => b.trim())
1506
- .filter(b => b && b !== 'main' && b !== 'master' && !b.startsWith('*') && !b.includes('--merged-'));
1507
-
1508
- if (merged.length > 0) {
1509
- console.log(` Scanning ${merged.length} merged branch(es) for rename...`);
1510
- for (const branch of merged) {
1511
- const current = execSync('git branch --show-current', { cwd: repoPath, encoding: 'utf8' }).trim();
1512
- if (branch === current) continue;
1513
-
1514
- let mergeDate;
1515
- try {
1516
- const mergeBase = execSync(`git merge-base main ${branch}`, { cwd: repoPath, encoding: 'utf8' }).trim();
1517
- mergeDate = execSync(
1518
- `git log main --format="%ai" --ancestry-path ${mergeBase}..main`,
1519
- { cwd: repoPath, encoding: 'utf8' }
1520
- ).trim().split('\n').pop().split(' ')[0];
1521
- } catch {}
1522
- if (!mergeDate) {
1523
- try {
1524
- mergeDate = execSync(`git log ${branch} -1 --format="%ai"`, { cwd: repoPath, encoding: 'utf8' }).trim().split(' ')[0];
1525
- } catch {}
1526
- }
1527
- if (!mergeDate) continue;
1528
-
1529
- const newName = `${branch}--merged-${mergeDate}`;
1530
- try {
1531
- execSync(`git branch -m "${branch}" "${newName}"`, { cwd: repoPath, stdio: 'pipe' });
1532
- execSync(`git push origin "${newName}"`, { cwd: repoPath, stdio: 'pipe' });
1533
- execSync(`git push origin --delete "${branch}"`, { cwd: repoPath, stdio: 'pipe' });
1534
- console.log(` ✓ Renamed: ${branch} -> ${newName}`);
1535
- } catch (e) {
1536
- console.log(` ! Could not rename ${branch}: ${e.message}`);
1537
- }
1538
- }
1539
- }
1540
- } catch (e) {
1541
- // Non-fatal: branch cleanup is a convenience, not a blocker
1542
- console.log(` ! Branch cleanup skipped: ${e.message}`);
1543
- }
1544
-
1545
- // 11. Prune old merged branches (keep last 3 per developer prefix)
1546
- try {
1547
- const KEEP_COUNT = 3;
1548
- const remoteBranches = execSync(
1549
- 'git branch -r', { cwd: repoPath, encoding: 'utf8' }
1550
- ).split('\n')
1551
- .map(b => b.trim())
1552
- .filter(b => b && !b.includes('HEAD') && b.includes('--merged-'))
1553
- .map(b => b.replace('origin/', ''));
1554
-
1555
- if (remoteBranches.length > 0) {
1556
- // Group by developer prefix (everything before first /)
1557
- const byPrefix = {};
1558
- for (const branch of remoteBranches) {
1559
- const prefix = branch.split('/')[0];
1560
- if (!byPrefix[prefix]) byPrefix[prefix] = [];
1561
- byPrefix[prefix].push(branch);
1562
- }
1563
-
1564
- let pruned = 0;
1565
- for (const [prefix, branches] of Object.entries(byPrefix)) {
1566
- // Sort by date descending (date is at the end: --merged-YYYY-MM-DD)
1567
- branches.sort((a, b) => {
1568
- const dateA = a.match(/--merged-(\d{4}-\d{2}-\d{2})/)?.[1] || '';
1569
- const dateB = b.match(/--merged-(\d{4}-\d{2}-\d{2})/)?.[1] || '';
1570
- return dateB.localeCompare(dateA);
1571
- });
1572
-
1573
- for (let i = KEEP_COUNT; i < branches.length; i++) {
1574
- try {
1575
- execSync(`git push origin --delete "${branches[i]}"`, { cwd: repoPath, stdio: 'pipe' });
1576
- execSync(`git branch -d "${branches[i]}" 2>/dev/null || true`, { cwd: repoPath, stdio: 'pipe', shell: true });
1577
- pruned++;
1578
- } catch {}
1579
- }
1580
- }
1581
-
1582
- if (pruned > 0) {
1583
- console.log(` ✓ Pruned ${pruned} old merged branch(es)`);
1584
- }
1585
- }
1586
-
1587
- // Clean stale branches (merged into main but never renamed)
1588
- const current = execSync('git branch --show-current', { cwd: repoPath, encoding: 'utf8' }).trim();
1589
- const allRemote = execSync(
1590
- 'git branch -r', { cwd: repoPath, encoding: 'utf8' }
1591
- ).split('\n')
1592
- .map(b => b.trim())
1593
- .filter(b => b && !b.includes('HEAD') && !b.includes('origin/main') && !b.includes('--merged-'))
1594
- .map(b => b.replace('origin/', ''));
1595
-
1596
- let staleCleaned = 0;
1597
- for (const branch of allRemote) {
1598
- if (branch === current) continue;
1599
- try {
1600
- execSync(`git merge-base --is-ancestor origin/${branch} origin/main`, { cwd: repoPath, stdio: 'pipe' });
1601
- // If we get here, branch is fully merged
1602
- execSync(`git push origin --delete "${branch}"`, { cwd: repoPath, stdio: 'pipe' });
1603
- execSync(`git branch -d "${branch}" 2>/dev/null || true`, { cwd: repoPath, stdio: 'pipe', shell: true });
1604
- staleCleaned++;
1605
- } catch {}
1606
- }
1607
- if (staleCleaned > 0) {
1608
- console.log(` ✓ Cleaned ${staleCleaned} stale branch(es)`);
1609
- }
1610
- } catch (e) {
1611
- console.log(` ! Branch prune skipped: ${e.message}`);
1612
- }
1613
-
1614
- // 12. Prune stale worktrees (#212)
1615
- try {
1616
- execSync('git worktree prune', { cwd: repoPath, stdio: 'pipe' });
1617
- // Also check .worktrees/ for dirs whose branches are now merged
1618
- const worktreesDir = join(dirname(repoPath), '.worktrees');
1619
- if (existsSync(worktreesDir)) {
1620
- const repoBase = basename(repoPath);
1621
- const wtDirs = readdirSync(worktreesDir, { withFileTypes: true })
1622
- .filter(d => d.isDirectory() && d.name.startsWith(repoBase + '--'));
1623
- let wtPruned = 0;
1624
- for (const d of wtDirs) {
1625
- const wtPath = join(worktreesDir, d.name);
1626
- try {
1627
- // Check if branch is merged into main
1628
- const branch = execSync('git branch --show-current', {
1629
- cwd: wtPath, encoding: 'utf8', timeout: 3000
1630
- }).trim();
1631
- if (branch) {
1632
- execSync(`git merge-base --is-ancestor "${branch}" main`, {
1633
- cwd: repoPath, stdio: 'pipe', timeout: 5000
1634
- });
1635
- // Branch is merged. Remove worktree.
1636
- execSync(`git worktree remove "${wtPath}"`, { cwd: repoPath, stdio: 'pipe' });
1637
- wtPruned++;
1638
- }
1639
- } catch {} // Branch not merged or other issue, leave it
1640
- }
1641
- if (wtPruned > 0) {
1642
- console.log(` ✓ Pruned ${wtPruned} merged worktree(s) from .worktrees/`);
1643
- }
1644
- }
1645
- } catch {}
1646
-
1647
- // Write release marker so branch guard blocks immediate install (#73)
1648
- try {
1649
- const markerDir = join(process.env.HOME || '', '.ldm', 'state');
1650
- const { mkdirSync, writeFileSync } = await import('node:fs');
1651
- mkdirSync(markerDir, { recursive: true });
1652
- writeFileSync(join(markerDir, '.last-release'), JSON.stringify({
1653
- repo: repoName,
1654
- version: newVersion,
1655
- timestamp: new Date().toISOString(),
1656
- }) + '\n');
1657
- } catch {}
1658
-
1659
- console.log('');
1660
- console.log(` Done. ${repoName} v${newVersion} released.`);
1661
- console.log('');
1662
-
1663
- return { currentVersion, newVersion, dryRun: false };
1664
- }