peaks-loop 3.1.1 → 4.0.0-beta

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 (308) hide show
  1. package/.claude-plugin/marketplace.json +62 -12
  2. package/CHANGELOG.md +74 -36
  3. package/README-en.md +58 -240
  4. package/README.md +49 -325
  5. package/agents/karpathy-reviewer.md +3 -3
  6. package/dist/src/cli/cli-helpers.d.ts +18 -0
  7. package/dist/src/cli/cli-helpers.js +8 -0
  8. package/dist/src/cli/commands/adapter-commands.d.ts +30 -0
  9. package/dist/src/cli/commands/adapter-commands.js +35 -0
  10. package/dist/src/cli/commands/context-commands.d.ts +1 -1
  11. package/dist/src/cli/commands/context-commands.js +1 -1
  12. package/dist/src/cli/commands/contract-commands.d.ts +1 -1
  13. package/dist/src/cli/commands/contract-commands.js +1 -1
  14. package/dist/src/cli/commands/core/session-command.js +12 -0
  15. package/dist/src/cli/commands/core/skill-command.js +4 -4
  16. package/dist/src/cli/commands/dispatch-commands.js +2 -2
  17. package/dist/src/cli/commands/job-commands.js +58 -5
  18. package/dist/src/cli/commands/observability-commands.js +1 -1
  19. package/dist/src/cli/commands/perf-audit-commands.js +2 -2
  20. package/dist/src/cli/commands/security-audit-commands.js +2 -2
  21. package/dist/src/cli/commands/sediment-commands.d.ts +80 -0
  22. package/dist/src/cli/commands/sediment-commands.js +640 -0
  23. package/dist/src/cli/commands/session-migrate-skill-name.d.ts +17 -0
  24. package/dist/src/cli/commands/session-migrate-skill-name.js +41 -0
  25. package/dist/src/cli/commands/skill-visibility.d.ts +8 -0
  26. package/dist/src/cli/commands/skill-visibility.js +63 -0
  27. package/dist/src/cli/commands/slice-commands.js +2 -2
  28. package/dist/src/cli/commands/solo-commands.d.ts +2 -2
  29. package/dist/src/cli/commands/solo-commands.js +246 -20
  30. package/dist/src/cli/commands/sub-agent-commands.d.ts +1 -1
  31. package/dist/src/cli/commands/sub-agent-commands.js +1 -1
  32. package/dist/src/cli/commands/understand-commands.js +1 -1
  33. package/dist/src/cli/commands/upgrade-commands.d.ts +1 -1
  34. package/dist/src/cli/commands/upgrade-commands.js +3 -3
  35. package/dist/src/cli/commands/user-touchpoint-commands.js +1 -1
  36. package/dist/src/cli/commands/verdict-aggregate-command.d.ts +1 -1
  37. package/dist/src/cli/commands/verdict-aggregate-command.js +2 -2
  38. package/dist/src/cli/commands/workflow-commands.js +2 -2
  39. package/dist/src/cli/commands/workspace/init-command.d.ts +3 -3
  40. package/dist/src/cli/commands/workspace/init-command.js +7 -7
  41. package/dist/src/cli/program.js +19 -2
  42. package/dist/src/services/adapter/adapter.d.ts +27 -0
  43. package/dist/src/services/adapter/adapter.js +5 -0
  44. package/dist/src/services/adapter/auto-adapter.d.ts +11 -0
  45. package/dist/src/services/adapter/auto-adapter.js +15 -0
  46. package/dist/src/services/adapter/claude-adapter.d.ts +14 -0
  47. package/dist/src/services/adapter/claude-adapter.js +40 -0
  48. package/dist/src/services/adapter/codex-adapter.d.ts +14 -0
  49. package/dist/src/services/adapter/codex-adapter.js +14 -0
  50. package/dist/src/services/adapter/copilot-adapter.d.ts +14 -0
  51. package/dist/src/services/adapter/copilot-adapter.js +14 -0
  52. package/dist/src/services/audit/enforcers/solo-code-ban.d.ts +1 -1
  53. package/dist/src/services/audit/enforcers/solo-code-ban.js +2 -2
  54. package/dist/src/services/audit/red-line-catalog.js +1 -1
  55. package/dist/src/services/audit/scanners/skills-tree-scanner.js +22 -0
  56. package/dist/src/services/context/auto-compact-dispatcher.d.ts +1 -1
  57. package/dist/src/services/dispatch/batch-counter.js +1 -1
  58. package/dist/src/services/dispatch/leak-detector.js +1 -1
  59. package/dist/src/services/doctor/doctor-service.js +2 -2
  60. package/dist/src/services/job/job-progress-store.d.ts +60 -0
  61. package/dist/src/services/job/job-progress-store.js +70 -0
  62. package/dist/src/services/job/job-resource-snapshot.js +29 -1
  63. package/dist/src/services/job/job-types.d.ts +4 -4
  64. package/dist/src/services/memory/project-memory-service.js +1 -1
  65. package/dist/src/services/migrate-skill-name/migrate.d.ts +17 -0
  66. package/dist/src/services/migrate-skill-name/migrate.js +152 -0
  67. package/dist/src/services/migrate-skill-name/schema.d.ts +42 -0
  68. package/dist/src/services/migrate-skill-name/schema.js +25 -0
  69. package/dist/src/services/observability/aggregation.d.ts +1 -1
  70. package/dist/src/services/observability/aggregation.js +1 -1
  71. package/dist/src/services/perf/perf-baseline-service.d.ts +1 -1
  72. package/dist/src/services/perf/perf-baseline-service.js +1 -1
  73. package/dist/src/services/prd/handoff-types.d.ts +1 -1
  74. package/dist/src/services/prd/handoff-types.js +1 -1
  75. package/dist/src/services/progress/progress-service.d.ts +1 -1
  76. package/dist/src/services/progress/progress-service.js +1 -1
  77. package/dist/src/services/rd/standards-diagnostic.js +1 -1
  78. package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
  79. package/dist/src/services/sc/sc-service.js +1 -1
  80. package/dist/src/services/sediment/dispose-confirm.d.ts +9 -0
  81. package/dist/src/services/sediment/dispose-confirm.js +5 -0
  82. package/dist/src/services/sediment/json-schema.d.ts +247 -0
  83. package/dist/src/services/sediment/json-schema.js +26 -0
  84. package/dist/src/services/sediment/manifest-lint.d.ts +13 -0
  85. package/dist/src/services/sediment/manifest-lint.js +11 -0
  86. package/dist/src/services/sediment/pool-paths.d.ts +22 -0
  87. package/dist/src/services/sediment/pool-paths.js +25 -0
  88. package/dist/src/services/sediment/pool-read.d.ts +20 -0
  89. package/dist/src/services/sediment/pool-read.js +73 -0
  90. package/dist/src/services/sediment/pool-rebuild-index.d.ts +15 -0
  91. package/dist/src/services/sediment/pool-rebuild-index.js +28 -0
  92. package/dist/src/services/sediment/pool-write.d.ts +14 -0
  93. package/dist/src/services/sediment/pool-write.js +25 -0
  94. package/dist/src/services/sediment/promotion-gate.d.ts +12 -0
  95. package/dist/src/services/sediment/promotion-gate.js +20 -0
  96. package/dist/src/services/sediment/types.d.ts +52 -0
  97. package/dist/src/services/sediment/types.js +1 -0
  98. package/dist/src/services/session/binding-store.d.ts +1 -1
  99. package/dist/src/services/session/binding-store.js +1 -1
  100. package/dist/src/services/session/caller-id-types.d.ts +1 -1
  101. package/dist/src/services/session/session-manager.d.ts +1 -1
  102. package/dist/src/services/session/session-manager.js +1 -1
  103. package/dist/src/services/skill/resume-detector.js +1 -1
  104. package/dist/src/services/skill/skill-scheduler.d.ts +1 -1
  105. package/dist/src/services/skill/skill-scheduler.js +1 -1
  106. package/dist/src/services/skillhub/release-diff.d.ts +18 -0
  107. package/dist/src/services/skillhub/release-diff.js +38 -0
  108. package/dist/src/services/skillhub/release-export.d.ts +8 -0
  109. package/dist/src/services/skillhub/release-export.js +31 -0
  110. package/dist/src/services/skillhub/release-gc-blobs.d.ts +13 -0
  111. package/dist/src/services/skillhub/release-gc-blobs.js +32 -0
  112. package/dist/src/services/skillhub/release-import.d.ts +7 -0
  113. package/dist/src/services/skillhub/release-import.js +59 -0
  114. package/dist/src/services/skillhub/release-retain.d.ts +23 -0
  115. package/dist/src/services/skillhub/release-retain.js +89 -0
  116. package/dist/src/services/skillhub/sqlite-store.d.ts +22 -0
  117. package/dist/src/services/skillhub/sqlite-store.js +47 -0
  118. package/dist/src/services/skillhub/tar-runtime.d.ts +21 -0
  119. package/dist/src/services/skillhub/tar-runtime.js +91 -0
  120. package/dist/src/services/skillhub/types.d.ts +105 -0
  121. package/dist/src/services/skillhub/types.js +1 -0
  122. package/dist/src/services/skills/skill-conformance-service.js +8 -5
  123. package/dist/src/services/skills/skill-presence-service.d.ts +4 -4
  124. package/dist/src/services/skills/skill-presence-service.js +2 -2
  125. package/dist/src/services/skills/skill-registry.js +27 -0
  126. package/dist/src/services/skills/skill-runbook-service.js +2 -2
  127. package/dist/src/services/slice/slice-check-service.js +1 -1
  128. package/dist/src/services/slice/slice-check-types.d.ts +1 -1
  129. package/dist/src/services/slice/slice-check-types.js +1 -1
  130. package/dist/src/services/slice/slice-decompose-types.d.ts +1 -1
  131. package/dist/src/services/slice/slice-decompose-types.js +1 -1
  132. package/dist/src/services/solo/auto-compact-orchestrator.d.ts +1 -1
  133. package/dist/src/services/solo/auto-compact-orchestrator.js +2 -2
  134. package/dist/src/services/solo/dag-orchestrator.d.ts +3 -3
  135. package/dist/src/services/solo/dag-orchestrator.js +4 -4
  136. package/dist/src/services/solo/emit-handoff.d.ts +49 -0
  137. package/dist/src/services/solo/emit-handoff.js +79 -0
  138. package/dist/src/services/solo/mode-gate.d.ts +2 -2
  139. package/dist/src/services/solo/post-compact-detector.js +2 -2
  140. package/dist/src/services/solo/status-line-renderer.d.ts +4 -4
  141. package/dist/src/services/solo/step-08-gate.d.ts +90 -0
  142. package/dist/src/services/solo/step-08-gate.js +136 -0
  143. package/dist/src/services/standards/missing-standards-detector.d.ts +1 -1
  144. package/dist/src/services/standards/missing-standards-detector.js +1 -1
  145. package/dist/src/services/standards/project-standards-service.d.ts +1 -1
  146. package/dist/src/services/standards/project-standards-service.js +4 -4
  147. package/dist/src/services/understand/understand-types.d.ts +1 -1
  148. package/dist/src/services/upgrade/1x-detector-service.js +1 -1
  149. package/dist/src/services/upgrade/upgrade-service.d.ts +34 -0
  150. package/dist/src/services/upgrade/upgrade-service.js +52 -30
  151. package/dist/src/services/verdict/verdict-aggregator.d.ts +1 -1
  152. package/dist/src/services/workflow/workflow-router-service.d.ts +1 -1
  153. package/dist/src/services/workflow/workflow-router-service.js +3 -3
  154. package/dist/src/services/workspace/claude-settings-template.d.ts +7 -2
  155. package/dist/src/services/workspace/claude-settings-template.js +42 -3
  156. package/dist/src/services/workspace/workspace-claude-settings-materializer.d.ts +1 -1
  157. package/dist/src/services/workspace/workspace-claude-settings-materializer.js +1 -1
  158. package/dist/src/services/workspace/workspace-service.d.ts +4 -4
  159. package/dist/src/services/workspace/workspace-service.js +2 -2
  160. package/dist/src/shared/paths.d.ts +1 -1
  161. package/dist/src/shared/paths.js +1 -1
  162. package/dist/src/shared/version.d.ts +1 -1
  163. package/dist/src/shared/version.js +1 -1
  164. package/dist/src/skills/peaks-maker/index.d.ts +5 -0
  165. package/dist/src/skills/peaks-maker/index.js +32 -0
  166. package/package.json +8 -3
  167. package/scripts/install-skills.mjs +29 -4
  168. package/skills/{peaks-prd → bee/peaks-prd}/SKILL.md +8 -2
  169. package/skills/{peaks-prd → bee/peaks-prd}/references/workflow.md +1 -1
  170. package/skills/{peaks-qa → bee/peaks-qa}/SKILL.md +10 -4
  171. package/skills/{peaks-qa → bee/peaks-qa}/references/browser-validation-contracts.md +2 -2
  172. package/skills/{peaks-qa → bee/peaks-qa}/references/external-capability-guidance.md +1 -1
  173. package/skills/{peaks-qa → bee/peaks-qa}/references/qa-fanout-contract.md +3 -3
  174. package/skills/{peaks-qa → bee/peaks-qa}/references/qa-sub-agent-dispatch.md +1 -1
  175. package/skills/{peaks-rd → bee/peaks-rd}/SKILL.md +13 -6
  176. package/skills/{peaks-rd → bee/peaks-rd}/references/browser-self-test-contracts.md +1 -1
  177. package/skills/{peaks-rd → bee/peaks-rd}/references/mock-data-placement.md +1 -1
  178. package/skills/{peaks-rd → bee/peaks-rd}/references/parallel-review-fanout.md +1 -1
  179. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-runbook.md +1 -1
  180. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-sub-agent-dispatch.md +2 -2
  181. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-transition-gates.md +1 -1
  182. package/skills/{peaks-rd → bee/peaks-rd}/references/skill-presence-and-title.md +1 -1
  183. package/skills/{peaks-reviewer → bee/peaks-reviewer}/SKILL.md +2 -2
  184. package/skills/{peaks-sc → bee/peaks-sc}/SKILL.md +7 -1
  185. package/skills/{peaks-txt → bee/peaks-txt}/SKILL.md +9 -3
  186. package/skills/{peaks-ui → bee/peaks-ui}/SKILL.md +11 -5
  187. package/skills/peaks-audit/SKILL.md +1 -1
  188. package/skills/{peaks-solo → peaks-code}/SKILL.md +53 -104
  189. package/skills/{peaks-solo → peaks-code}/references/a2a-artifact-mapping.md +2 -2
  190. package/skills/{peaks-solo → peaks-code}/references/anchoring-and-session-info.md +4 -4
  191. package/skills/{peaks-solo → peaks-code}/references/artifact-contracts.md +2 -2
  192. package/skills/{peaks-solo → peaks-code}/references/browser-workflow.md +1 -1
  193. package/skills/peaks-code/references/command-migration.md +3 -0
  194. package/skills/{peaks-solo → peaks-code}/references/completion-handoff.md +2 -2
  195. package/skills/{peaks-solo → peaks-code}/references/context-governance.md +2 -2
  196. package/skills/{peaks-solo → peaks-code}/references/frontend-only-mode.md +1 -1
  197. package/skills/{peaks-solo → peaks-code}/references/local-artifact-workspace.md +1 -1
  198. package/skills/{peaks-solo → peaks-code}/references/micro-cycle.md +9 -9
  199. package/skills/{peaks-solo → peaks-code}/references/mode-selection-with-stale-presence.md +12 -12
  200. package/skills/{peaks-solo → peaks-code}/references/mode-selection.md +1 -1
  201. package/skills/{peaks-solo → peaks-code}/references/openspec-workflow.md +1 -1
  202. package/skills/{peaks-solo → peaks-code}/references/project-scan-checklist.md +1 -1
  203. package/skills/{peaks-solo → peaks-code}/references/refactor-mode.md +1 -1
  204. package/skills/{peaks-solo → peaks-code}/references/resume-detection.md +1 -1
  205. package/skills/{peaks-solo → peaks-code}/references/runbook.md +25 -5
  206. package/skills/{peaks-solo → peaks-code}/references/skill-presence-and-title.md +3 -3
  207. package/skills/{peaks-solo → peaks-code}/references/standards-preflight.md +1 -1
  208. package/skills/{peaks-solo → peaks-code}/references/step-0-55-1x-detection.md +5 -5
  209. package/skills/peaks-code/references/step-0-8-gate.md +60 -0
  210. package/skills/{peaks-solo → peaks-code}/references/sub-agent-dispatch.md +10 -10
  211. package/skills/{peaks-solo → peaks-code}/references/swarm-dispatch-contract.md +7 -7
  212. package/skills/{peaks-solo → peaks-code}/references/workflow-gates-and-types.md +3 -3
  213. package/skills/peaks-doctor/SKILL.md +1 -1
  214. package/skills/peaks-doctor/references/doctor-check-catalog.md +1 -1
  215. package/skills/peaks-final-review/SKILL.md +3 -3
  216. package/skills/peaks-final-review/references/4-dimensions.md +1 -1
  217. package/skills/peaks-ide/SKILL.md +1 -1
  218. package/skills/{peaks-solo-resume → peaks-resume}/SKILL.md +14 -14
  219. package/skills/peaks-sop/SKILL.md +1 -1
  220. package/skills/{peaks-solo-status → peaks-status}/SKILL.md +13 -13
  221. package/skills/{peaks-solo-test → peaks-test}/SKILL.md +11 -11
  222. package/skills/peaks-solo/references/command-migration.md +0 -3
  223. /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/SKILL.md +0 -0
  224. /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/references/audit-protocol.md +0 -0
  225. /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-contracts.md +0 -0
  226. /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-per-request.md +0 -0
  227. /package/skills/{peaks-prd → bee/peaks-prd}/references/command-migration.md +0 -0
  228. /package/skills/{peaks-prd → bee/peaks-prd}/references/prd-for-multi-pass.md +0 -0
  229. /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-contracts.md +0 -0
  230. /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-per-request.md +0 -0
  231. /package/skills/{peaks-qa → bee/peaks-qa}/references/codegraph-regression-focus.md +0 -0
  232. /package/skills/{peaks-qa → bee/peaks-qa}/references/command-migration.md +0 -0
  233. /package/skills/{peaks-qa → bee/peaks-qa}/references/openspec-validation-gate.md +0 -0
  234. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-compact-handoff.md +0 -0
  235. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-context-governance.md +0 -0
  236. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-gstack-integration.md +0 -0
  237. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-local-artifacts.md +0 -0
  238. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-matt-pocock-integration.md +0 -0
  239. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-perf-test-plan.md +0 -0
  240. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-refactor-role.md +0 -0
  241. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-runbook.md +0 -0
  242. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-security-test-plan.md +0 -0
  243. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-skill-presence.md +0 -0
  244. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-standards-preflight.md +0 -0
  245. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-transition-gates.md +0 -0
  246. /package/skills/{peaks-qa → bee/peaks-qa}/references/reading-handoff-frontmatter.md +0 -0
  247. /package/skills/{peaks-qa → bee/peaks-qa}/references/regression-gates.md +0 -0
  248. /package/skills/{peaks-qa → bee/peaks-qa}/references/requirement-boundary-recheck.md +0 -0
  249. /package/skills/{peaks-qa → bee/peaks-qa}/references/test-case-generation.md +0 -0
  250. /package/skills/{peaks-qa → bee/peaks-qa}/references/test-report-output.md +0 -0
  251. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-and-standards-output.md +0 -0
  252. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-contracts.md +0 -0
  253. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-per-request.md +0 -0
  254. /package/skills/{peaks-rd → bee/peaks-rd}/references/browser-action-wrapper.md +0 -0
  255. /package/skills/{peaks-rd → bee/peaks-rd}/references/code-reviewer-4dim-hint.md +0 -0
  256. /package/skills/{peaks-rd → bee/peaks-rd}/references/codegraph-project-analysis.md +0 -0
  257. /package/skills/{peaks-rd → bee/peaks-rd}/references/command-migration.md +0 -0
  258. /package/skills/{peaks-rd → bee/peaks-rd}/references/compact-handoff.md +0 -0
  259. /package/skills/{peaks-rd → bee/peaks-rd}/references/external-references.md +0 -0
  260. /package/skills/{peaks-rd → bee/peaks-rd}/references/frontend-project-generation.md +0 -0
  261. /package/skills/{peaks-rd → bee/peaks-rd}/references/karpathy-reviewer-prompt.md +0 -0
  262. /package/skills/{peaks-rd → bee/peaks-rd}/references/library-version-awareness.md +0 -0
  263. /package/skills/{peaks-rd → bee/peaks-rd}/references/mandatory-perf-baseline.md +0 -0
  264. /package/skills/{peaks-rd → bee/peaks-rd}/references/matt-pocock-integration.md +0 -0
  265. /package/skills/{peaks-rd → bee/peaks-rd}/references/ocr-integration.md +0 -0
  266. /package/skills/{peaks-rd → bee/peaks-rd}/references/openspec-cli.md +0 -0
  267. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-context-governance.md +0 -0
  268. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-fanout-contracts.md +0 -0
  269. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-gstack-integration.md +0 -0
  270. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-standards-preflight.md +0 -0
  271. /package/skills/{peaks-rd → bee/peaks-rd}/references/reading-v2-slice-results.md +0 -0
  272. /package/skills/{peaks-rd → bee/peaks-rd}/references/refactor-workflow.md +0 -0
  273. /package/skills/{peaks-rd → bee/peaks-rd}/references/v2-12-fanout-collapse.md +0 -0
  274. /package/skills/{peaks-rd → bee/peaks-rd}/references/writing-handoff-frontmatter.md +0 -0
  275. /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-prompt.md +0 -0
  276. /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-schema.md +0 -0
  277. /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-contracts.md +0 -0
  278. /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-retention.md +0 -0
  279. /package/skills/{peaks-sc → bee/peaks-sc}/references/command-migration.md +0 -0
  280. /package/skills/{peaks-sc → bee/peaks-sc}/references/openspec-commit-boundaries.md +0 -0
  281. /package/skills/{peaks-security-audit → bee/peaks-security-audit}/SKILL.md +0 -0
  282. /package/skills/{peaks-security-audit → bee/peaks-security-audit}/references/audit-protocol.md +0 -0
  283. /package/skills/{peaks-txt → bee/peaks-txt}/references/artifact-contracts.md +0 -0
  284. /package/skills/{peaks-txt → bee/peaks-txt}/references/command-migration.md +0 -0
  285. /package/skills/{peaks-txt → bee/peaks-txt}/references/context-capsule.md +0 -0
  286. /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-contracts.md +0 -0
  287. /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-per-request.md +0 -0
  288. /package/skills/{peaks-ui → bee/peaks-ui}/references/command-migration.md +0 -0
  289. /package/skills/{peaks-ui → bee/peaks-ui}/references/workflow.md +0 -0
  290. /package/skills/{peaks-solo → peaks-code}/references/boundaries.md +0 -0
  291. /package/skills/{peaks-solo → peaks-code}/references/checkpoint-resume.md +0 -0
  292. /package/skills/{peaks-solo → peaks-code}/references/codegraph-orchestration.md +0 -0
  293. /package/skills/{peaks-solo → peaks-code}/references/cross-date-session-check.md +0 -0
  294. /package/skills/{peaks-solo → peaks-code}/references/dag-orchestrator.md +0 -0
  295. /package/skills/{peaks-solo → peaks-code}/references/envelope-contract.md +0 -0
  296. /package/skills/{peaks-solo → peaks-code}/references/existing-system-extraction.md +0 -0
  297. /package/skills/{peaks-solo → peaks-code}/references/external-references.md +0 -0
  298. /package/skills/{peaks-solo → peaks-code}/references/external-skill-invocation.md +0 -0
  299. /package/skills/{peaks-solo → peaks-code}/references/fanout-mandatory.md +0 -0
  300. /package/skills/{peaks-solo → peaks-code}/references/fast-mode.md +0 -0
  301. /package/skills/{peaks-solo → peaks-code}/references/gstack-integration.md +0 -0
  302. /package/skills/{peaks-solo → peaks-code}/references/headroom-integration.md +0 -0
  303. /package/skills/{peaks-solo → peaks-code}/references/job-loop.md +0 -0
  304. /package/skills/{peaks-solo → peaks-code}/references/periodic-checkpoint.md +0 -0
  305. /package/skills/{peaks-solo → peaks-code}/references/playwright-mcp-multi-terminal.md +0 -0
  306. /package/skills/{peaks-solo → peaks-code}/references/project-memory-loading.md +0 -0
  307. /package/skills/{peaks-solo → peaks-code}/references/quality-gate-cheatsheet.md +0 -0
  308. /package/skills/{peaks-solo → peaks-code}/references/workflow.md +0 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * v3.1.2 Step 11 / final handoff — Size-fear ban.
3
+ *
4
+ * Refuses to emit a final handoff while a Job has remaining slices.
5
+ * Closes the v3.1.0 incident pattern: LLM writes a fake-completion
6
+ * message at high context-fill before Job mode kicks in.
7
+ *
8
+ * Decision tree:
9
+ * - job-shape.json missing OR isJob === false → ALLOW (normal handoff)
10
+ * - isJob === true, no state.json → JOB_NOT_INITIALIZED (LLM
11
+ * skipped `peaks job init`)
12
+ * - isJob === true, state.json, remaining > 0,
13
+ * no --force-under-job → JOB_REMAINING_BLOCKED
14
+ * - isJob === true, state.json, remaining === 0 → ALLOW (Job done)
15
+ * - isJob === true, state.json, remaining > 0,
16
+ * --force-under-job → ALLOW (override path)
17
+ *
18
+ * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
+ * Pure read + arithmetic. The CLI wrapper in solo-commands.ts
20
+ * translates the verdict into exit code + JSON envelope.
21
+ */
22
+ export declare const JOB_NOT_INITIALIZED: "JOB_NOT_INITIALIZED";
23
+ export declare const JOB_REMAINING_BLOCKED: "JOB_REMAINING_BLOCKED";
24
+ export type EmitHandoffVerdict = {
25
+ readonly kind: 'allow-not-job';
26
+ } | {
27
+ readonly kind: 'allow-done';
28
+ readonly remaining: number;
29
+ } | {
30
+ readonly kind: 'allow-force-override';
31
+ readonly remaining: number;
32
+ } | {
33
+ readonly kind: 'block-not-initialized';
34
+ readonly code: typeof JOB_NOT_INITIALIZED;
35
+ readonly jobId: string;
36
+ } | {
37
+ readonly kind: 'block-remaining';
38
+ readonly code: typeof JOB_REMAINING_BLOCKED;
39
+ readonly jobId: string;
40
+ readonly remaining: number;
41
+ };
42
+ export interface EvaluateEmitHandoffInput {
43
+ readonly projectRoot: string;
44
+ readonly sessionId: string;
45
+ /** Suggested job id — read from job-shape.json when omitted. */
46
+ readonly jobId?: string;
47
+ readonly forceUnderJob?: boolean;
48
+ }
49
+ export declare function evaluateEmitHandoff(input: EvaluateEmitHandoffInput): EmitHandoffVerdict;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * v3.1.2 Step 11 / final handoff — Size-fear ban.
3
+ *
4
+ * Refuses to emit a final handoff while a Job has remaining slices.
5
+ * Closes the v3.1.0 incident pattern: LLM writes a fake-completion
6
+ * message at high context-fill before Job mode kicks in.
7
+ *
8
+ * Decision tree:
9
+ * - job-shape.json missing OR isJob === false → ALLOW (normal handoff)
10
+ * - isJob === true, no state.json → JOB_NOT_INITIALIZED (LLM
11
+ * skipped `peaks job init`)
12
+ * - isJob === true, state.json, remaining > 0,
13
+ * no --force-under-job → JOB_REMAINING_BLOCKED
14
+ * - isJob === true, state.json, remaining === 0 → ALLOW (Job done)
15
+ * - isJob === true, state.json, remaining > 0,
16
+ * --force-under-job → ALLOW (override path)
17
+ *
18
+ * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
+ * Pure read + arithmetic. The CLI wrapper in solo-commands.ts
20
+ * translates the verdict into exit code + JSON envelope.
21
+ */
22
+ import { existsSync, readFileSync } from 'node:fs';
23
+ import { join } from 'node:path';
24
+ import { readJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED } from './job-shape-decision.js';
25
+ export const JOB_NOT_INITIALIZED = 'JOB_NOT_INITIALIZED';
26
+ export const JOB_REMAINING_BLOCKED = 'JOB_REMAINING_BLOCKED';
27
+ function countRemaining(statePath) {
28
+ let raw;
29
+ try {
30
+ raw = readFileSync(statePath, 'utf8');
31
+ }
32
+ catch {
33
+ return Number.NaN;
34
+ }
35
+ let parsed;
36
+ try {
37
+ parsed = JSON.parse(raw);
38
+ }
39
+ catch {
40
+ return Number.NaN;
41
+ }
42
+ if (!Array.isArray(parsed.slices))
43
+ return Number.NaN;
44
+ return parsed.slices.filter((sl) => sl.status !== 'done' && sl.status !== 'skipped').length;
45
+ }
46
+ function statePath(projectRoot, sessionId, jobId) {
47
+ return join(projectRoot, '.peaks', '_runtime', sessionId, 'job', jobId, 'state.json');
48
+ }
49
+ export function evaluateEmitHandoff(input) {
50
+ let decision = null;
51
+ try {
52
+ const record = readJobShapeDecision(input.projectRoot, input.sessionId);
53
+ decision = record.decision;
54
+ }
55
+ catch (err) {
56
+ if (err instanceof JobShapeDecisionError && err.code === JOB_SHAPE_NOT_DECIDED) {
57
+ return { kind: 'allow-not-job' };
58
+ }
59
+ throw err;
60
+ }
61
+ if (!decision.isJob)
62
+ return { kind: 'allow-not-job' };
63
+ const jobId = input.jobId ?? decision.suggestedJobId;
64
+ const path = statePath(input.projectRoot, input.sessionId, jobId);
65
+ if (!existsSync(path)) {
66
+ return { kind: 'block-not-initialized', code: JOB_NOT_INITIALIZED, jobId };
67
+ }
68
+ const remaining = countRemaining(path);
69
+ if (!Number.isFinite(remaining)) {
70
+ return { kind: 'block-not-initialized', code: JOB_NOT_INITIALIZED, jobId };
71
+ }
72
+ if (remaining === 0) {
73
+ return { kind: 'allow-done', remaining };
74
+ }
75
+ if (input.forceUnderJob === true) {
76
+ return { kind: 'allow-force-override', remaining };
77
+ }
78
+ return { kind: 'block-remaining', code: JOB_REMAINING_BLOCKED, jobId, remaining };
79
+ }
@@ -43,7 +43,7 @@ export type GatedStepId = 'step-0.5-openspec-opt-in' | 'step-0.6-audit-goal' | '
43
43
  export declare const GATED_STEPS: readonly GatedStepId[];
44
44
  /**
45
45
  * Slice 2026-06-28-solo-mode-bypass-fix: the kind of gate that
46
- * produced this decision. The LLM-side caller (peaks-solo body) reads
46
+ * produced this decision. The LLM-side caller (peaks-code body) reads
47
47
  * this to distinguish "you paused because the user must choose the
48
48
  * mode" (`mode-selection-itself`) from "you paused because the mode
49
49
  * you already chose is assisted/strict" (`mode-driven`) from "you
@@ -98,7 +98,7 @@ export declare function shouldAutoProceed(mode: SoloMode): boolean;
98
98
  /**
99
99
  * v2.15.0 slice 002 AC-4: the 5 action identifiers that qualify as
100
100
  * commit-boundary side effects. Matched by the LLM-side caller
101
- * (peaks-solo body / peaks-rd fork agent) when it is about to run a
101
+ * (peaks-code body / peaks-rd fork agent) when it is about to run a
102
102
  * Bash command that maps to one of these. Set `commitBoundaryAction:
103
103
  * true` on the `shouldPauseAtGate` call to trigger the hard-floor
104
104
  * override.
@@ -146,7 +146,7 @@ export async function detectPostCompactResume(opts) {
146
146
  };
147
147
  }
148
148
  // Active skill check (D7.a.4). Defaults to reading from skill presence.
149
- const expectedActiveSkill = 'peaks-solo';
149
+ const expectedActiveSkill = 'peaks-code';
150
150
  const observedActiveSkill = opts.activeSkill ?? readActiveSkillName(opts.projectRoot);
151
151
  if (observedActiveSkill !== expectedActiveSkill) {
152
152
  return {
@@ -154,7 +154,7 @@ export async function detectPostCompactResume(opts) {
154
154
  reason: 'active-skill-mismatch',
155
155
  checkpointPath: file.path,
156
156
  checkpointMtime: file.mtime.toISOString(),
157
- warnings: [`active skill "${observedActiveSkill ?? 'unset'}" is not peaks-solo`]
157
+ warnings: [`active skill "${observedActiveSkill ?? 'unset'}" is not peaks-code`]
158
158
  };
159
159
  }
160
160
  // Mode: prefer the checkpoint's mode; fall back to the presence override
@@ -1,13 +1,13 @@
1
1
  /**
2
- * G6.5 — status line renderer for the peaks-solo batch-sync wait period.
2
+ * G6.5 — status line renderer for the peaks-code batch-sync wait period.
3
3
  *
4
4
  * Single line, 80-120 chars, status-line-friendly. The shape is
5
5
  * documented in PRD §G6.5:
6
6
  *
7
- * [peaks-solo] swarm 3/3 running | rd-planning 45% (12s ago) | qa-test-cases 30% (5s ago) | ui-design 20% (2s ago)
8
- * [peaks-solo] swarm 3/3 running | rd-planning 70% (8s ago) | qa-test-cases 50% (3s ago) | ui-design 30% (6s ago)
7
+ * [peaks-code] swarm 3/3 running | rd-planning 45% (12s ago) | qa-test-cases 30% (5s ago) | ui-design 20% (2s ago)
8
+ * [peaks-code] swarm 3/3 running | rd-planning 70% (8s ago) | qa-test-cases 50% (3s ago) | ui-design 30% (6s ago)
9
9
  * ...
10
- * [peaks-solo] swarm 3/3 done in 47.3s
10
+ * [peaks-code] swarm 3/3 done in 47.3s
11
11
  *
12
12
  * Pure helper; the poller calls it once per tick. No IO.
13
13
  */
@@ -0,0 +1,90 @@
1
+ /**
2
+ * v3.1.2 Step 0.8 — Mechanical PreToolUse gate.
3
+ *
4
+ * Wire-installed by `peaks workspace init` (extends the existing hook
5
+ * installer; does NOT replace the Write|Edit|MultiEdit fact-forcing
6
+ * bypass). The hook runs `peaks solo gate-step-08 --project .` before
7
+ * every Bash tool call. Exit code is the load-bearing contract:
8
+ *
9
+ * exit 0 → allow (with structured stdout describing the decision)
10
+ * exit 2 → block (stderr contains the BLOCKED: ... reason)
11
+ *
12
+ * Three decision paths:
13
+ *
14
+ * 1. `job-shape.json` exists with `decision.isJob === true`.
15
+ * → allow, print `{ ok, allow, mode: 'job', decision }`. When a
16
+ * matching `job/<jid>/progress.json` exists, also print
17
+ * `Next: slice #<N+1> of <M> (<currentSlice>)` so the LLM sees
18
+ * its resume context BEFORE any Bash call lands.
19
+ * 2. `job-shape.json` exists with `decision.isJob === false`.
20
+ * → allow, print `{ ok, allow, mode: 'single' }`.
21
+ * 3. `job-shape.json` is MISSING — fail-closed guard. The LLM is the
22
+ * source of truth, but if it never recorded a decision we run a
23
+ * lightweight backup regex against the user's prompt:
24
+ * /until|全部|until all done|disavow cost|不用考虑费用|all of them/i
25
+ * match → block (exit 2) with the BLOCKED: stderr message.
26
+ * no match → allow (exit 0) — most prompts are not Job-shaped.
27
+ *
28
+ * Karpathy §2 (Simplicity First): ~120 lines, no LLM call inside. The
29
+ * regex is the FIRST time peaks-loop accepts hardcoded keywords —
30
+ * explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
31
+ * judgement. The LLM still owns the semantic call via
32
+ * `peaks solo detect-job`. The regex is a safety net for the v3.1.1
33
+ * incident class (LLM under load never records the decision at all).
34
+ */
35
+ export declare const STEP_08_GATE_FILE_NAME: "job-shape.json";
36
+ export declare const STEP_08_PROGRESS_FILE_NAME: "progress.json";
37
+ /**
38
+ * Fail-closed backup regex — see module docstring case 3 for why this
39
+ * exists. Kept short and explicit; if the prompt mentions any of these
40
+ * triggers and `job-shape.json` is missing, the LLM is treated as
41
+ * having skipped `peaks solo detect-job` and the gate blocks.
42
+ *
43
+ * The list mirrors the v3.1.0 / v3.1.1 incident triggers verbatim:
44
+ * 继续执行下个 slice (until next slice) → until / 直到
45
+ * 全部添加完 / all of them → 全部 / all of them
46
+ * 不用考虑费用 → 不用考虑费用 / disavow cost
47
+ * until all done → until all done
48
+ */
49
+ export declare const STEP_08_BACKUP_REGEX: RegExp;
50
+ export interface Step08Progress {
51
+ readonly jobId: string;
52
+ readonly done: number;
53
+ readonly total: number;
54
+ readonly currentSlice: string;
55
+ readonly lastCommitSha: string | null;
56
+ readonly updatedAt: string;
57
+ }
58
+ export type Step08Verdict = {
59
+ readonly kind: 'allow-job';
60
+ readonly decision: import('./job-shape-decision.js').JobShapeDecision;
61
+ readonly progress: Step08Progress | null;
62
+ } | {
63
+ readonly kind: 'allow-single';
64
+ } | {
65
+ readonly kind: 'block-missing-decision';
66
+ readonly promptHit: boolean;
67
+ readonly promptSource: 'flag' | 'last-prompt-file' | 'stdin-empty';
68
+ };
69
+ export declare function runtimeSessionDir(projectRoot: string, sessionId: string): string;
70
+ export interface EvaluateStep08Input {
71
+ readonly projectRoot: string;
72
+ readonly sessionId: string;
73
+ /**
74
+ * Explicit prompt text. When omitted, falls back to
75
+ * `.peaks/_runtime/<sid>/txt/last-prompt.txt`, then to stdin (the
76
+ * caller passes stdin verbatim — usually empty in tests).
77
+ */
78
+ readonly prompt?: string;
79
+ }
80
+ export interface EvaluateStep08Result {
81
+ readonly allow: boolean;
82
+ readonly verdict: Step08Verdict;
83
+ readonly nextSliceLine: string | null;
84
+ }
85
+ /**
86
+ * Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
87
+ * `src/cli/commands/solo-commands.ts` reads `allow` to set the process
88
+ * exit code (0 allow / 2 block) and prints the structured envelope.
89
+ */
90
+ export declare function evaluateStep08(input: EvaluateStep08Input): EvaluateStep08Result;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * v3.1.2 Step 0.8 — Mechanical PreToolUse gate.
3
+ *
4
+ * Wire-installed by `peaks workspace init` (extends the existing hook
5
+ * installer; does NOT replace the Write|Edit|MultiEdit fact-forcing
6
+ * bypass). The hook runs `peaks solo gate-step-08 --project .` before
7
+ * every Bash tool call. Exit code is the load-bearing contract:
8
+ *
9
+ * exit 0 → allow (with structured stdout describing the decision)
10
+ * exit 2 → block (stderr contains the BLOCKED: ... reason)
11
+ *
12
+ * Three decision paths:
13
+ *
14
+ * 1. `job-shape.json` exists with `decision.isJob === true`.
15
+ * → allow, print `{ ok, allow, mode: 'job', decision }`. When a
16
+ * matching `job/<jid>/progress.json` exists, also print
17
+ * `Next: slice #<N+1> of <M> (<currentSlice>)` so the LLM sees
18
+ * its resume context BEFORE any Bash call lands.
19
+ * 2. `job-shape.json` exists with `decision.isJob === false`.
20
+ * → allow, print `{ ok, allow, mode: 'single' }`.
21
+ * 3. `job-shape.json` is MISSING — fail-closed guard. The LLM is the
22
+ * source of truth, but if it never recorded a decision we run a
23
+ * lightweight backup regex against the user's prompt:
24
+ * /until|全部|until all done|disavow cost|不用考虑费用|all of them/i
25
+ * match → block (exit 2) with the BLOCKED: stderr message.
26
+ * no match → allow (exit 0) — most prompts are not Job-shaped.
27
+ *
28
+ * Karpathy §2 (Simplicity First): ~120 lines, no LLM call inside. The
29
+ * regex is the FIRST time peaks-loop accepts hardcoded keywords —
30
+ * explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
31
+ * judgement. The LLM still owns the semantic call via
32
+ * `peaks solo detect-job`. The regex is a safety net for the v3.1.1
33
+ * incident class (LLM under load never records the decision at all).
34
+ */
35
+ import { existsSync, readFileSync } from 'node:fs';
36
+ import { join } from 'node:path';
37
+ import { readJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED } from './job-shape-decision.js';
38
+ export const STEP_08_GATE_FILE_NAME = 'job-shape.json';
39
+ export const STEP_08_PROGRESS_FILE_NAME = 'progress.json';
40
+ /**
41
+ * Fail-closed backup regex — see module docstring case 3 for why this
42
+ * exists. Kept short and explicit; if the prompt mentions any of these
43
+ * triggers and `job-shape.json` is missing, the LLM is treated as
44
+ * having skipped `peaks solo detect-job` and the gate blocks.
45
+ *
46
+ * The list mirrors the v3.1.0 / v3.1.1 incident triggers verbatim:
47
+ * 继续执行下个 slice (until next slice) → until / 直到
48
+ * 全部添加完 / all of them → 全部 / all of them
49
+ * 不用考虑费用 → 不用考虑费用 / disavow cost
50
+ * until all done → until all done
51
+ */
52
+ export const STEP_08_BACKUP_REGEX = /直到|全部|until all done|disavow cost|不用考虑费用|all of them/i;
53
+ export function runtimeSessionDir(projectRoot, sessionId) {
54
+ return join(projectRoot, '.peaks', '_runtime', sessionId);
55
+ }
56
+ function progressPath(projectRoot, sessionId, jid) {
57
+ // The progress file lives under job/<jid>/progress.json. The jid
58
+ // comes from job-shape.json (decision.suggestedJobId) — there is
59
+ // exactly one canonical jid per session under Job mode, so we read
60
+ // the matching path directly rather than enumerating the job/ dir.
61
+ // (Rotating mode spawns new jids but only one is "active" at a time;
62
+ // the active jid is the latest write to job-shape.json.)
63
+ return join(runtimeSessionDir(projectRoot, sessionId), 'job', jid, STEP_08_PROGRESS_FILE_NAME);
64
+ }
65
+ function readProgressIfAny(projectRoot, sessionId, jid) {
66
+ const path = progressPath(projectRoot, sessionId, jid);
67
+ if (!existsSync(path))
68
+ return null;
69
+ try {
70
+ const raw = readFileSync(path, 'utf8');
71
+ const parsed = JSON.parse(raw);
72
+ if (typeof parsed.jobId === 'string' &&
73
+ typeof parsed.done === 'number' &&
74
+ typeof parsed.total === 'number' &&
75
+ typeof parsed.currentSlice === 'string' &&
76
+ typeof parsed.updatedAt === 'string') {
77
+ return {
78
+ jobId: parsed.jobId,
79
+ done: parsed.done,
80
+ total: parsed.total,
81
+ currentSlice: parsed.currentSlice,
82
+ lastCommitSha: typeof parsed.lastCommitSha === 'string' ? parsed.lastCommitSha : null,
83
+ updatedAt: parsed.updatedAt
84
+ };
85
+ }
86
+ return null;
87
+ }
88
+ catch { // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
89
+ return null;
90
+ }
91
+ }
92
+ function readPromptFromLastPromptFile(projectRoot, sessionId) {
93
+ const path = join(runtimeSessionDir(projectRoot, sessionId), 'txt', 'last-prompt.txt');
94
+ if (!existsSync(path))
95
+ return '';
96
+ try {
97
+ return readFileSync(path, 'utf8');
98
+ }
99
+ catch {
100
+ return '';
101
+ }
102
+ }
103
+ /**
104
+ * Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
105
+ * `src/cli/commands/solo-commands.ts` reads `allow` to set the process
106
+ * exit code (0 allow / 2 block) and prints the structured envelope.
107
+ */
108
+ export function evaluateStep08(input) {
109
+ try {
110
+ const record = readJobShapeDecision(input.projectRoot, input.sessionId);
111
+ if (record.decision.isJob) {
112
+ const progress = readProgressIfAny(input.projectRoot, input.sessionId, record.decision.suggestedJobId);
113
+ const nextSliceLine = progress !== null
114
+ ? `Next: slice #${progress.done + 1} of ${progress.total} (${progress.currentSlice})`
115
+ : null;
116
+ return {
117
+ allow: true,
118
+ verdict: { kind: 'allow-job', decision: record.decision, progress },
119
+ nextSliceLine
120
+ };
121
+ }
122
+ return { allow: true, verdict: { kind: 'allow-single' }, nextSliceLine: null };
123
+ }
124
+ catch (err) {
125
+ if (err instanceof JobShapeDecisionError && err.code === JOB_SHAPE_NOT_DECIDED) {
126
+ const promptText = input.prompt ?? readPromptFromLastPromptFile(input.projectRoot, input.sessionId);
127
+ const hit = promptText.length > 0 && STEP_08_BACKUP_REGEX.test(promptText);
128
+ const source = input.prompt !== undefined ? 'flag' : promptText.length > 0 ? 'last-prompt-file' : 'stdin-empty';
129
+ if (hit) {
130
+ return { allow: false, verdict: { kind: 'block-missing-decision', promptHit: true, promptSource: source }, nextSliceLine: null };
131
+ }
132
+ return { allow: true, verdict: { kind: 'block-missing-decision', promptHit: false, promptSource: source }, nextSliceLine: null };
133
+ }
134
+ throw err;
135
+ }
136
+ }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Slice 2026-06-16-peaks-solo-auto-scaffold (RD#7) — missing-standards-detector.
2
+ * Slice 2026-06-16-peaks-code-auto-scaffold (RD#7) — missing-standards-detector.
3
3
  *
4
4
  * Read-side companion to the `peaks standards init` / `peaks standards update`
5
5
  * writers in `./project-standards-service.ts`. The writer KNOWS how to scaffold
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Slice 2026-06-16-peaks-solo-auto-scaffold (RD#7) — missing-standards-detector.
2
+ * Slice 2026-06-16-peaks-code-auto-scaffold (RD#7) — missing-standards-detector.
3
3
  *
4
4
  * Read-side companion to the `peaks standards init` / `peaks standards update`
5
5
  * writers in `./project-standards-service.ts`. The writer KNOWS how to scaffold
@@ -30,7 +30,7 @@ export type ProjectStandardsSource = {
30
30
  readonly usage: 'curated-baseline-reference';
31
31
  };
32
32
  export type StandardsSkillPreflight = {
33
- readonly appliesTo: readonly ['peaks-rd', 'peaks-qa', 'peaks-solo'];
33
+ readonly appliesTo: readonly ['peaks-rd', 'peaks-qa', 'peaks-code'];
34
34
  readonly summary: string;
35
35
  };
36
36
  export type ProjectStandardsInitPlan = {
@@ -23,8 +23,8 @@ const SOURCE = {
23
23
  usage: 'curated-baseline-reference'
24
24
  };
25
25
  const SKILL_PREFLIGHT = {
26
- appliesTo: ['peaks-rd', 'peaks-qa', 'peaks-solo'],
27
- summary: 'peaks-rd、peaks-qa、peaks-solo 进入代码仓工作流时自动 preflight 项目规范。'
26
+ appliesTo: ['peaks-rd', 'peaks-qa', 'peaks-code'],
27
+ summary: 'peaks-rd、peaks-qa、peaks-code 进入代码仓工作流时自动 preflight 项目规范。'
28
28
  };
29
29
  const SUPPORTED_LANGUAGES = new Set(['generic', 'typescript', 'javascript', 'python', 'go', 'rust']);
30
30
  function normalizeRoot(path) {
@@ -104,7 +104,7 @@ function renderHeader(title) {
104
104
  `# ${title}`,
105
105
  '',
106
106
  'Source: Peaks curated baseline; everything-claude-code reference: https://github.com/affaan-m/everything-claude-code',
107
- 'Scope: project-local standards for peaks-rd, peaks-qa, and peaks-solo workflow preflight.',
107
+ 'Scope: project-local standards for peaks-rd, peaks-qa, and peaks-code workflow preflight.',
108
108
  ''
109
109
  ].join('\n');
110
110
  }
@@ -151,7 +151,7 @@ function renderClaudeMd(language, ctx) {
151
151
  'Peaks workflow automation:',
152
152
  '- peaks-rd checks these standards before RD planning or implementation work.',
153
153
  '- peaks-qa checks code review and security guidance before verification work.',
154
- '- peaks-solo summarizes RD and QA standards preflight before end-to-end code workflows.',
154
+ '- peaks-code summarizes RD and QA standards preflight before end-to-end code workflows.',
155
155
  '',
156
156
  'Rules:',
157
157
  '- Read `.claude/rules/common/coding-style.md` before editing code.',
@@ -33,7 +33,7 @@ export type UnderstandScanReport = {
33
33
  };
34
34
  /**
35
35
  * Slice L3.1 — opt-in prompt payload. When uaPrompt === 'unset' and UA is
36
- * absent, the peaks-solo / peaks-ide layer surfaces this to the user via
36
+ * absent, the peaks-code / peaks-ide layer surfaces this to the user via
37
37
  * AskUserQuestion. The CLI does not prompt directly; it returns this
38
38
  * payload so the LLM-side UX layer can decide.
39
39
  */
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * The canonical implementation lives in the .mjs postinstall
8
8
  * (because the postinstall runs before any TS compile step).
9
- * This TS mirror exists so the peaks-solo skill can call
9
+ * This TS mirror exists so the peaks-code skill can call
10
10
  * `peaks upgrade --detect-1x --project <root> --json` and
11
11
  * read a structured JSON envelope to gate the
12
12
  * AskUserQuestion that prompts the 1.x → 2.0 upgrade.
@@ -1,3 +1,30 @@
1
+ /**
2
+ * Pluggable executor for sub-step command spawns. Production
3
+ * callers omit `executor` on `UpgradeInput`; the default
4
+ * (`defaultSubstepExecutor`) wraps `node:child_process` `spawnSync`.
5
+ * Tests pass a synchronous fake executor to avoid the spawn cost.
6
+ *
7
+ * Contract:
8
+ * - Return `status: 0` for success, non-zero for failure, `null`
9
+ * for synchronous spawn errors (binary not found, EACCES, …).
10
+ * - `stdout` / `stderr` are captured as UTF-8 strings.
11
+ * - `durationMs` is the wall-clock duration of the spawn
12
+ * (caller-facing field on `SubStepResult`).
13
+ */
14
+ export type SubstepExecutor = (command: string, args: readonly string[], timeoutMs: number) => {
15
+ status: number | null;
16
+ stdout: string;
17
+ stderr: string;
18
+ durationMs: number;
19
+ };
20
+ /**
21
+ * Default substep executor — wraps `spawnSync` with the same
22
+ * stdio / encoding / timeout config the umbrella has used since
23
+ * v1. Exported for test coverage: the seam-preservation test
24
+ * imports this directly to verify the normalized return shape
25
+ * on a spawn failure (e.g. a non-existent command).
26
+ */
27
+ export declare const defaultSubstepExecutor: SubstepExecutor;
1
28
  export interface UpgradeInput {
2
29
  readonly projectRoot: string;
3
30
  /**
@@ -14,6 +41,13 @@ export interface UpgradeInput {
14
41
  * install hint in `nextActions` instead.
15
42
  */
16
43
  readonly peaksBin?: string;
44
+ /**
45
+ * Optional injectable executor for sub-step command execution.
46
+ * When omitted, the umbrella uses `defaultSubstepExecutor`
47
+ * (real `spawnSync`). Tests pass a synchronous fake to avoid
48
+ * the per-sub-step `node peaks.js …` spawn cost.
49
+ */
50
+ readonly executor?: SubstepExecutor;
17
51
  }
18
52
  export interface SubStepResult {
19
53
  readonly name: string;
@@ -33,6 +33,38 @@ import { fileURLToPath } from 'node:url';
33
33
  import { runRedLinesAudit } from '../audit/red-lines-service.js';
34
34
  import { savePreferences } from '../preferences/preferences-service.js';
35
35
  import { migrateGitignoreFile } from './gitignore-migrate-service.js';
36
+ /**
37
+ * Default substep executor — wraps `spawnSync` with the same
38
+ * stdio / encoding / timeout config the umbrella has used since
39
+ * v1. Exported for test coverage: the seam-preservation test
40
+ * imports this directly to verify the normalized return shape
41
+ * on a spawn failure (e.g. a non-existent command).
42
+ */
43
+ export const defaultSubstepExecutor = (command, args, timeoutMs) => {
44
+ const start = Date.now();
45
+ try {
46
+ const result = spawnSync(command, args, {
47
+ encoding: 'utf8',
48
+ stdio: ['ignore', 'pipe', 'pipe'],
49
+ timeout: timeoutMs,
50
+ });
51
+ return {
52
+ status: result.status,
53
+ stdout: result.stdout ?? '',
54
+ stderr: result.stderr ?? '',
55
+ durationMs: Date.now() - start,
56
+ };
57
+ }
58
+ catch (err) {
59
+ const message = err instanceof Error ? err.message : String(err);
60
+ return {
61
+ status: null,
62
+ stdout: '',
63
+ stderr: message,
64
+ durationMs: Date.now() - start,
65
+ };
66
+ }
67
+ };
36
68
  const STEPS = [
37
69
  { name: 'config-migrate', args: (p) => ['config', 'migrate', '--project', p, '--apply', '--json'] },
38
70
  { name: 'standards-migrate', args: (p) => ['standards', 'migrate', '--from-claude-rules', '--project', p, '--apply', '--json'] },
@@ -145,8 +177,7 @@ function read1xVersion(cwd) {
145
177
  }
146
178
  return null;
147
179
  }
148
- function runStep(peaksBin, name, args, timeoutMs = 60_000) {
149
- const start = Date.now();
180
+ function runStep(peaksBin, name, args, timeoutMs = 60_000, executor = defaultSubstepExecutor) {
150
181
  // The global `peaks` shim is a `/bin/sh` symlink script (the
151
182
  // npm install postinstall creates `peaks` → `peaks.sh` on
152
183
  // Windows). cmd.exe (the default Windows shell) cannot run
@@ -168,32 +199,18 @@ function runStep(peaksBin, name, args, timeoutMs = 60_000) {
168
199
  command = peaksBin;
169
200
  spawnArgs = args;
170
201
  }
171
- try {
172
- const result = spawnSync(command, spawnArgs, {
173
- encoding: 'utf8',
174
- stdio: ['ignore', 'pipe', 'pipe'],
175
- timeout: timeoutMs,
176
- });
177
- return {
178
- name,
179
- status: result.status === 0 ? 'pass' : 'fail',
180
- exitCode: result.status,
181
- stdout: result.stdout ?? '',
182
- stderr: result.stderr ?? '',
183
- durationMs: Date.now() - start,
184
- };
185
- }
186
- catch (err) {
187
- const message = err instanceof Error ? err.message : String(err);
188
- return {
189
- name,
190
- status: 'fail',
191
- exitCode: null,
192
- stdout: '',
193
- stderr: message,
194
- durationMs: Date.now() - start,
195
- };
196
- }
202
+ // The executor normalizes spawn errors to { status: null, stderr: ... }
203
+ // so no try/catch wrapper is needed here — the call always returns
204
+ // a shaped record. See defaultSubstepExecutor for the reference impl.
205
+ const result = executor(command, spawnArgs, timeoutMs);
206
+ return {
207
+ name,
208
+ status: result.status === 0 ? 'pass' : 'fail',
209
+ exitCode: result.status,
210
+ stdout: result.stdout,
211
+ stderr: result.stderr,
212
+ durationMs: result.durationMs,
213
+ };
197
214
  }
198
215
  function writeUpgradeRecord(projectRoot, result) {
199
216
  try {
@@ -260,6 +277,11 @@ export function runUpgrade(input) {
260
277
  resolve(here, '..', '..', '..', '..', 'bin', 'peaks.js');
261
278
  const fallbackPeaks = 'peaks';
262
279
  const resolvedPeaksBin = existsSync(peaksBin) ? peaksBin : fallbackPeaks;
280
+ // Resolve the executor once at the top of runUpgrade so every
281
+ // sub-step call shares the same instance. Tests pass a fake
282
+ // executor via UpgradeInput.executor; production callers omit
283
+ // it and get the default spawnSync wrapper.
284
+ const executor = input.executor ?? defaultSubstepExecutor;
263
285
  const fromVersion = read1xVersion(input.projectRoot);
264
286
  const steps = [];
265
287
  const warnings = [];
@@ -325,7 +347,7 @@ export function runUpgrade(input) {
325
347
  continue;
326
348
  }
327
349
  const args = ['memory', 'extract', '--project', input.projectRoot, '--artifact', ...artifacts, '--apply', '--json'];
328
- const r = runStep(resolvedPeaksBin, 'memory-extract', args);
350
+ const r = runStep(resolvedPeaksBin, 'memory-extract', args, 60_000, executor);
329
351
  steps.push(r);
330
352
  if (r.status === 'fail') {
331
353
  warnings.push(`memory-extract failed: ${r.stderr.slice(0, 200)}`);
@@ -333,7 +355,7 @@ export function runUpgrade(input) {
333
355
  continue;
334
356
  }
335
357
  const args = step.args(input.projectRoot);
336
- const r = runStep(resolvedPeaksBin, step.name, args);
358
+ const r = runStep(resolvedPeaksBin, step.name, args, 60_000, executor);
337
359
  steps.push(r);
338
360
  if (r.status === 'fail') {
339
361
  warnings.push(`${step.name} failed: ${r.stderr.slice(0, 200)}`);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * peaks-solo multi-signal verdict aggregator (v2.13.1 Group A).
2
+ * peaks-code multi-signal verdict aggregator (v2.13.1 Group A).
3
3
  *
4
4
  * Implements the 4 aggregation rules documented in
5
5
  * `.peaks/project-scan/audit-output-schema.md:66-78` plus 3rd-party