peaks-loop 3.1.2 → 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 (301) hide show
  1. package/.claude-plugin/marketplace.json +62 -12
  2. package/CHANGELOG.md +50 -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 +5 -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 +8 -8
  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-resource-snapshot.js +29 -1
  61. package/dist/src/services/memory/project-memory-service.js +1 -1
  62. package/dist/src/services/migrate-skill-name/migrate.d.ts +17 -0
  63. package/dist/src/services/migrate-skill-name/migrate.js +152 -0
  64. package/dist/src/services/migrate-skill-name/schema.d.ts +42 -0
  65. package/dist/src/services/migrate-skill-name/schema.js +25 -0
  66. package/dist/src/services/observability/aggregation.d.ts +1 -1
  67. package/dist/src/services/observability/aggregation.js +1 -1
  68. package/dist/src/services/perf/perf-baseline-service.d.ts +1 -1
  69. package/dist/src/services/perf/perf-baseline-service.js +1 -1
  70. package/dist/src/services/prd/handoff-types.d.ts +1 -1
  71. package/dist/src/services/prd/handoff-types.js +1 -1
  72. package/dist/src/services/progress/progress-service.d.ts +1 -1
  73. package/dist/src/services/progress/progress-service.js +1 -1
  74. package/dist/src/services/rd/standards-diagnostic.js +1 -1
  75. package/dist/src/services/recommendations/capability-seed-mappings.js +1 -1
  76. package/dist/src/services/sc/sc-service.js +1 -1
  77. package/dist/src/services/sediment/dispose-confirm.d.ts +9 -0
  78. package/dist/src/services/sediment/dispose-confirm.js +5 -0
  79. package/dist/src/services/sediment/json-schema.d.ts +247 -0
  80. package/dist/src/services/sediment/json-schema.js +26 -0
  81. package/dist/src/services/sediment/manifest-lint.d.ts +13 -0
  82. package/dist/src/services/sediment/manifest-lint.js +11 -0
  83. package/dist/src/services/sediment/pool-paths.d.ts +22 -0
  84. package/dist/src/services/sediment/pool-paths.js +25 -0
  85. package/dist/src/services/sediment/pool-read.d.ts +20 -0
  86. package/dist/src/services/sediment/pool-read.js +73 -0
  87. package/dist/src/services/sediment/pool-rebuild-index.d.ts +15 -0
  88. package/dist/src/services/sediment/pool-rebuild-index.js +28 -0
  89. package/dist/src/services/sediment/pool-write.d.ts +14 -0
  90. package/dist/src/services/sediment/pool-write.js +25 -0
  91. package/dist/src/services/sediment/promotion-gate.d.ts +12 -0
  92. package/dist/src/services/sediment/promotion-gate.js +20 -0
  93. package/dist/src/services/sediment/types.d.ts +52 -0
  94. package/dist/src/services/sediment/types.js +1 -0
  95. package/dist/src/services/session/binding-store.d.ts +1 -1
  96. package/dist/src/services/session/binding-store.js +1 -1
  97. package/dist/src/services/session/caller-id-types.d.ts +1 -1
  98. package/dist/src/services/session/session-manager.d.ts +1 -1
  99. package/dist/src/services/session/session-manager.js +1 -1
  100. package/dist/src/services/skill/resume-detector.js +1 -1
  101. package/dist/src/services/skill/skill-scheduler.d.ts +1 -1
  102. package/dist/src/services/skill/skill-scheduler.js +1 -1
  103. package/dist/src/services/skillhub/release-diff.d.ts +18 -0
  104. package/dist/src/services/skillhub/release-diff.js +38 -0
  105. package/dist/src/services/skillhub/release-export.d.ts +8 -0
  106. package/dist/src/services/skillhub/release-export.js +31 -0
  107. package/dist/src/services/skillhub/release-gc-blobs.d.ts +13 -0
  108. package/dist/src/services/skillhub/release-gc-blobs.js +32 -0
  109. package/dist/src/services/skillhub/release-import.d.ts +7 -0
  110. package/dist/src/services/skillhub/release-import.js +59 -0
  111. package/dist/src/services/skillhub/release-retain.d.ts +23 -0
  112. package/dist/src/services/skillhub/release-retain.js +89 -0
  113. package/dist/src/services/skillhub/sqlite-store.d.ts +22 -0
  114. package/dist/src/services/skillhub/sqlite-store.js +47 -0
  115. package/dist/src/services/skillhub/tar-runtime.d.ts +21 -0
  116. package/dist/src/services/skillhub/tar-runtime.js +91 -0
  117. package/dist/src/services/skillhub/types.d.ts +105 -0
  118. package/dist/src/services/skillhub/types.js +1 -0
  119. package/dist/src/services/skills/skill-conformance-service.js +8 -5
  120. package/dist/src/services/skills/skill-presence-service.d.ts +4 -4
  121. package/dist/src/services/skills/skill-presence-service.js +2 -2
  122. package/dist/src/services/skills/skill-registry.js +27 -0
  123. package/dist/src/services/skills/skill-runbook-service.js +2 -2
  124. package/dist/src/services/slice/slice-check-service.js +1 -1
  125. package/dist/src/services/slice/slice-check-types.d.ts +1 -1
  126. package/dist/src/services/slice/slice-check-types.js +1 -1
  127. package/dist/src/services/slice/slice-decompose-types.d.ts +1 -1
  128. package/dist/src/services/slice/slice-decompose-types.js +1 -1
  129. package/dist/src/services/solo/auto-compact-orchestrator.d.ts +1 -1
  130. package/dist/src/services/solo/auto-compact-orchestrator.js +2 -2
  131. package/dist/src/services/solo/dag-orchestrator.d.ts +3 -3
  132. package/dist/src/services/solo/dag-orchestrator.js +4 -4
  133. package/dist/src/services/solo/mode-gate.d.ts +2 -2
  134. package/dist/src/services/solo/post-compact-detector.js +2 -2
  135. package/dist/src/services/solo/status-line-renderer.d.ts +4 -4
  136. package/dist/src/services/standards/missing-standards-detector.d.ts +1 -1
  137. package/dist/src/services/standards/missing-standards-detector.js +1 -1
  138. package/dist/src/services/standards/project-standards-service.d.ts +1 -1
  139. package/dist/src/services/standards/project-standards-service.js +4 -4
  140. package/dist/src/services/understand/understand-types.d.ts +1 -1
  141. package/dist/src/services/upgrade/1x-detector-service.js +1 -1
  142. package/dist/src/services/upgrade/upgrade-service.d.ts +34 -0
  143. package/dist/src/services/upgrade/upgrade-service.js +52 -30
  144. package/dist/src/services/verdict/verdict-aggregator.d.ts +1 -1
  145. package/dist/src/services/workflow/workflow-router-service.d.ts +1 -1
  146. package/dist/src/services/workflow/workflow-router-service.js +3 -3
  147. package/dist/src/services/workspace/claude-settings-template.d.ts +1 -1
  148. package/dist/src/services/workspace/claude-settings-template.js +2 -2
  149. package/dist/src/services/workspace/workspace-claude-settings-materializer.d.ts +1 -1
  150. package/dist/src/services/workspace/workspace-claude-settings-materializer.js +1 -1
  151. package/dist/src/services/workspace/workspace-service.d.ts +4 -4
  152. package/dist/src/services/workspace/workspace-service.js +2 -2
  153. package/dist/src/shared/paths.d.ts +1 -1
  154. package/dist/src/shared/paths.js +1 -1
  155. package/dist/src/shared/version.d.ts +1 -1
  156. package/dist/src/shared/version.js +1 -1
  157. package/dist/src/skills/peaks-maker/index.d.ts +5 -0
  158. package/dist/src/skills/peaks-maker/index.js +32 -0
  159. package/package.json +8 -3
  160. package/scripts/install-skills.mjs +29 -4
  161. package/skills/{peaks-prd → bee/peaks-prd}/SKILL.md +8 -2
  162. package/skills/{peaks-prd → bee/peaks-prd}/references/workflow.md +1 -1
  163. package/skills/{peaks-qa → bee/peaks-qa}/SKILL.md +10 -4
  164. package/skills/{peaks-qa → bee/peaks-qa}/references/browser-validation-contracts.md +2 -2
  165. package/skills/{peaks-qa → bee/peaks-qa}/references/external-capability-guidance.md +1 -1
  166. package/skills/{peaks-qa → bee/peaks-qa}/references/qa-fanout-contract.md +3 -3
  167. package/skills/{peaks-qa → bee/peaks-qa}/references/qa-sub-agent-dispatch.md +1 -1
  168. package/skills/{peaks-rd → bee/peaks-rd}/SKILL.md +13 -6
  169. package/skills/{peaks-rd → bee/peaks-rd}/references/browser-self-test-contracts.md +1 -1
  170. package/skills/{peaks-rd → bee/peaks-rd}/references/mock-data-placement.md +1 -1
  171. package/skills/{peaks-rd → bee/peaks-rd}/references/parallel-review-fanout.md +1 -1
  172. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-runbook.md +1 -1
  173. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-sub-agent-dispatch.md +2 -2
  174. package/skills/{peaks-rd → bee/peaks-rd}/references/rd-transition-gates.md +1 -1
  175. package/skills/{peaks-rd → bee/peaks-rd}/references/skill-presence-and-title.md +1 -1
  176. package/skills/{peaks-reviewer → bee/peaks-reviewer}/SKILL.md +2 -2
  177. package/skills/{peaks-sc → bee/peaks-sc}/SKILL.md +7 -1
  178. package/skills/{peaks-txt → bee/peaks-txt}/SKILL.md +9 -3
  179. package/skills/{peaks-ui → bee/peaks-ui}/SKILL.md +11 -5
  180. package/skills/peaks-audit/SKILL.md +1 -1
  181. package/skills/{peaks-solo → peaks-code}/SKILL.md +9 -9
  182. package/skills/{peaks-solo → peaks-code}/references/a2a-artifact-mapping.md +2 -2
  183. package/skills/{peaks-solo → peaks-code}/references/anchoring-and-session-info.md +4 -4
  184. package/skills/{peaks-solo → peaks-code}/references/artifact-contracts.md +2 -2
  185. package/skills/{peaks-solo → peaks-code}/references/browser-workflow.md +1 -1
  186. package/skills/peaks-code/references/command-migration.md +3 -0
  187. package/skills/{peaks-solo → peaks-code}/references/completion-handoff.md +2 -2
  188. package/skills/{peaks-solo → peaks-code}/references/context-governance.md +2 -2
  189. package/skills/{peaks-solo → peaks-code}/references/frontend-only-mode.md +1 -1
  190. package/skills/{peaks-solo → peaks-code}/references/local-artifact-workspace.md +1 -1
  191. package/skills/{peaks-solo → peaks-code}/references/micro-cycle.md +9 -9
  192. package/skills/{peaks-solo → peaks-code}/references/mode-selection-with-stale-presence.md +12 -12
  193. package/skills/{peaks-solo → peaks-code}/references/mode-selection.md +1 -1
  194. package/skills/{peaks-solo → peaks-code}/references/openspec-workflow.md +1 -1
  195. package/skills/{peaks-solo → peaks-code}/references/project-scan-checklist.md +1 -1
  196. package/skills/{peaks-solo → peaks-code}/references/refactor-mode.md +1 -1
  197. package/skills/{peaks-solo → peaks-code}/references/resume-detection.md +1 -1
  198. package/skills/{peaks-solo → peaks-code}/references/runbook.md +5 -5
  199. package/skills/{peaks-solo → peaks-code}/references/skill-presence-and-title.md +3 -3
  200. package/skills/{peaks-solo → peaks-code}/references/standards-preflight.md +1 -1
  201. package/skills/{peaks-solo → peaks-code}/references/step-0-55-1x-detection.md +5 -5
  202. package/skills/{peaks-solo → peaks-code}/references/sub-agent-dispatch.md +10 -10
  203. package/skills/{peaks-solo → peaks-code}/references/swarm-dispatch-contract.md +7 -7
  204. package/skills/{peaks-solo → peaks-code}/references/workflow-gates-and-types.md +3 -3
  205. package/skills/peaks-doctor/SKILL.md +1 -1
  206. package/skills/peaks-doctor/references/doctor-check-catalog.md +1 -1
  207. package/skills/peaks-final-review/SKILL.md +3 -3
  208. package/skills/peaks-final-review/references/4-dimensions.md +1 -1
  209. package/skills/peaks-ide/SKILL.md +1 -1
  210. package/skills/{peaks-solo-resume → peaks-resume}/SKILL.md +14 -14
  211. package/skills/peaks-sop/SKILL.md +1 -1
  212. package/skills/{peaks-solo-status → peaks-status}/SKILL.md +13 -13
  213. package/skills/{peaks-solo-test → peaks-test}/SKILL.md +11 -11
  214. package/skills/peaks-solo/references/command-migration.md +0 -3
  215. /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/SKILL.md +0 -0
  216. /package/skills/{peaks-perf-audit → bee/peaks-perf-audit}/references/audit-protocol.md +0 -0
  217. /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-contracts.md +0 -0
  218. /package/skills/{peaks-prd → bee/peaks-prd}/references/artifact-per-request.md +0 -0
  219. /package/skills/{peaks-prd → bee/peaks-prd}/references/command-migration.md +0 -0
  220. /package/skills/{peaks-prd → bee/peaks-prd}/references/prd-for-multi-pass.md +0 -0
  221. /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-contracts.md +0 -0
  222. /package/skills/{peaks-qa → bee/peaks-qa}/references/artifact-per-request.md +0 -0
  223. /package/skills/{peaks-qa → bee/peaks-qa}/references/codegraph-regression-focus.md +0 -0
  224. /package/skills/{peaks-qa → bee/peaks-qa}/references/command-migration.md +0 -0
  225. /package/skills/{peaks-qa → bee/peaks-qa}/references/openspec-validation-gate.md +0 -0
  226. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-compact-handoff.md +0 -0
  227. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-context-governance.md +0 -0
  228. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-gstack-integration.md +0 -0
  229. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-local-artifacts.md +0 -0
  230. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-matt-pocock-integration.md +0 -0
  231. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-perf-test-plan.md +0 -0
  232. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-refactor-role.md +0 -0
  233. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-runbook.md +0 -0
  234. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-security-test-plan.md +0 -0
  235. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-skill-presence.md +0 -0
  236. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-standards-preflight.md +0 -0
  237. /package/skills/{peaks-qa → bee/peaks-qa}/references/qa-transition-gates.md +0 -0
  238. /package/skills/{peaks-qa → bee/peaks-qa}/references/reading-handoff-frontmatter.md +0 -0
  239. /package/skills/{peaks-qa → bee/peaks-qa}/references/regression-gates.md +0 -0
  240. /package/skills/{peaks-qa → bee/peaks-qa}/references/requirement-boundary-recheck.md +0 -0
  241. /package/skills/{peaks-qa → bee/peaks-qa}/references/test-case-generation.md +0 -0
  242. /package/skills/{peaks-qa → bee/peaks-qa}/references/test-report-output.md +0 -0
  243. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-and-standards-output.md +0 -0
  244. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-contracts.md +0 -0
  245. /package/skills/{peaks-rd → bee/peaks-rd}/references/artifact-per-request.md +0 -0
  246. /package/skills/{peaks-rd → bee/peaks-rd}/references/browser-action-wrapper.md +0 -0
  247. /package/skills/{peaks-rd → bee/peaks-rd}/references/code-reviewer-4dim-hint.md +0 -0
  248. /package/skills/{peaks-rd → bee/peaks-rd}/references/codegraph-project-analysis.md +0 -0
  249. /package/skills/{peaks-rd → bee/peaks-rd}/references/command-migration.md +0 -0
  250. /package/skills/{peaks-rd → bee/peaks-rd}/references/compact-handoff.md +0 -0
  251. /package/skills/{peaks-rd → bee/peaks-rd}/references/external-references.md +0 -0
  252. /package/skills/{peaks-rd → bee/peaks-rd}/references/frontend-project-generation.md +0 -0
  253. /package/skills/{peaks-rd → bee/peaks-rd}/references/karpathy-reviewer-prompt.md +0 -0
  254. /package/skills/{peaks-rd → bee/peaks-rd}/references/library-version-awareness.md +0 -0
  255. /package/skills/{peaks-rd → bee/peaks-rd}/references/mandatory-perf-baseline.md +0 -0
  256. /package/skills/{peaks-rd → bee/peaks-rd}/references/matt-pocock-integration.md +0 -0
  257. /package/skills/{peaks-rd → bee/peaks-rd}/references/ocr-integration.md +0 -0
  258. /package/skills/{peaks-rd → bee/peaks-rd}/references/openspec-cli.md +0 -0
  259. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-context-governance.md +0 -0
  260. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-fanout-contracts.md +0 -0
  261. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-gstack-integration.md +0 -0
  262. /package/skills/{peaks-rd → bee/peaks-rd}/references/rd-standards-preflight.md +0 -0
  263. /package/skills/{peaks-rd → bee/peaks-rd}/references/reading-v2-slice-results.md +0 -0
  264. /package/skills/{peaks-rd → bee/peaks-rd}/references/refactor-workflow.md +0 -0
  265. /package/skills/{peaks-rd → bee/peaks-rd}/references/v2-12-fanout-collapse.md +0 -0
  266. /package/skills/{peaks-rd → bee/peaks-rd}/references/writing-handoff-frontmatter.md +0 -0
  267. /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-prompt.md +0 -0
  268. /package/skills/{peaks-reviewer → bee/peaks-reviewer}/references/reviewer-schema.md +0 -0
  269. /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-contracts.md +0 -0
  270. /package/skills/{peaks-sc → bee/peaks-sc}/references/artifact-retention.md +0 -0
  271. /package/skills/{peaks-sc → bee/peaks-sc}/references/command-migration.md +0 -0
  272. /package/skills/{peaks-sc → bee/peaks-sc}/references/openspec-commit-boundaries.md +0 -0
  273. /package/skills/{peaks-security-audit → bee/peaks-security-audit}/SKILL.md +0 -0
  274. /package/skills/{peaks-security-audit → bee/peaks-security-audit}/references/audit-protocol.md +0 -0
  275. /package/skills/{peaks-txt → bee/peaks-txt}/references/artifact-contracts.md +0 -0
  276. /package/skills/{peaks-txt → bee/peaks-txt}/references/command-migration.md +0 -0
  277. /package/skills/{peaks-txt → bee/peaks-txt}/references/context-capsule.md +0 -0
  278. /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-contracts.md +0 -0
  279. /package/skills/{peaks-ui → bee/peaks-ui}/references/artifact-per-request.md +0 -0
  280. /package/skills/{peaks-ui → bee/peaks-ui}/references/command-migration.md +0 -0
  281. /package/skills/{peaks-ui → bee/peaks-ui}/references/workflow.md +0 -0
  282. /package/skills/{peaks-solo → peaks-code}/references/boundaries.md +0 -0
  283. /package/skills/{peaks-solo → peaks-code}/references/checkpoint-resume.md +0 -0
  284. /package/skills/{peaks-solo → peaks-code}/references/codegraph-orchestration.md +0 -0
  285. /package/skills/{peaks-solo → peaks-code}/references/cross-date-session-check.md +0 -0
  286. /package/skills/{peaks-solo → peaks-code}/references/dag-orchestrator.md +0 -0
  287. /package/skills/{peaks-solo → peaks-code}/references/envelope-contract.md +0 -0
  288. /package/skills/{peaks-solo → peaks-code}/references/existing-system-extraction.md +0 -0
  289. /package/skills/{peaks-solo → peaks-code}/references/external-references.md +0 -0
  290. /package/skills/{peaks-solo → peaks-code}/references/external-skill-invocation.md +0 -0
  291. /package/skills/{peaks-solo → peaks-code}/references/fanout-mandatory.md +0 -0
  292. /package/skills/{peaks-solo → peaks-code}/references/fast-mode.md +0 -0
  293. /package/skills/{peaks-solo → peaks-code}/references/gstack-integration.md +0 -0
  294. /package/skills/{peaks-solo → peaks-code}/references/headroom-integration.md +0 -0
  295. /package/skills/{peaks-solo → peaks-code}/references/job-loop.md +0 -0
  296. /package/skills/{peaks-solo → peaks-code}/references/periodic-checkpoint.md +0 -0
  297. /package/skills/{peaks-solo → peaks-code}/references/playwright-mcp-multi-terminal.md +0 -0
  298. /package/skills/{peaks-solo → peaks-code}/references/project-memory-loading.md +0 -0
  299. /package/skills/{peaks-solo → peaks-code}/references/quality-gate-cheatsheet.md +0 -0
  300. /package/skills/{peaks-solo → peaks-code}/references/step-0-8-gate.md +0 -0
  301. /package/skills/{peaks-solo → peaks-code}/references/workflow.md +0 -0
@@ -399,7 +399,7 @@ export function getSessionId(projectRoot) {
399
399
  * caller is operating on a user-supplied `--project` flag
400
400
  * and the binding may have been written by a CLI invocation
401
401
  * that was running from inside the project dir (the common
402
- * peaks-solo / peaks-sop scenario). Other modules depend
402
+ * peaks-code / peaks-sop scenario). Other modules depend
403
403
  * on the strict-equality semantics of `getSessionId` (the
404
404
  * "no binding" fallback path is part of their contract),
405
405
  * so this variant is opt-in.
@@ -2,7 +2,7 @@
2
2
  * Peaks-Loop Solo Step 0.7 — Resume-mode detector.
3
3
  *
4
4
  * Mirrors the classification table in
5
- * `skills/peaks-solo/SKILL.md` "Peaks-Loop Step 0.7: Detect unfinished work
5
+ * `skills/peaks-code/SKILL.md` "Peaks-Loop Step 0.7: Detect unfinished work
6
6
  * and offer resume". The function is a pure read of session artifacts;
7
7
  * it performs no side effects and is safe to call from hooks, scripts,
8
8
  * and skills.
@@ -2,7 +2,7 @@
2
2
  * G6 — skill-level heartbeat scheduler config.
3
3
  *
4
4
  * Slice 2026-06-07-sub-agent-dispatch-decouple (G6): the SKILL.md front
5
- * matter for a Dispatcher (peaks-solo / peaks-rd / peaks-qa) can opt
5
+ * matter for a Dispatcher (peaks-code / peaks-rd / peaks-qa) can opt
6
6
  * into a non-default heartbeat interval by including a line like:
7
7
  *
8
8
  * heartbeatIntervalSec: 15
@@ -2,7 +2,7 @@
2
2
  * G6 — skill-level heartbeat scheduler config.
3
3
  *
4
4
  * Slice 2026-06-07-sub-agent-dispatch-decouple (G6): the SKILL.md front
5
- * matter for a Dispatcher (peaks-solo / peaks-rd / peaks-qa) can opt
5
+ * matter for a Dispatcher (peaks-code / peaks-rd / peaks-qa) can opt
6
6
  * into a non-default heartbeat interval by including a line like:
7
7
  *
8
8
  * heartbeatIntervalSec: 15
@@ -0,0 +1,18 @@
1
+ import type Database from "better-sqlite3";
2
+ export interface ReleaseDiff {
3
+ added: string[];
4
+ removed: string[];
5
+ modified: string[];
6
+ }
7
+ /**
8
+ * Compare two releases of the same bee and report which file paths were
9
+ * added, removed, or had their content (sha256) changed.
10
+ *
11
+ * Throws `VERSION_NOT_FOUND` if either (bee_name, version) tuple is missing.
12
+ */
13
+ export declare function releaseDiff({ db, beeName, fromVersion, toVersion, }: {
14
+ db: Database.Database;
15
+ beeName: string;
16
+ fromVersion: string;
17
+ toVersion: string;
18
+ }): ReleaseDiff;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Compare two releases of the same bee and report which file paths were
3
+ * added, removed, or had their content (sha256) changed.
4
+ *
5
+ * Throws `VERSION_NOT_FOUND` if either (bee_name, version) tuple is missing.
6
+ */
7
+ export function releaseDiff({ db, beeName, fromVersion, toVersion, }) {
8
+ const aRow = db
9
+ .prepare("SELECT id FROM bee_release WHERE bee_name = ? AND version = ?")
10
+ .get(beeName, fromVersion);
11
+ const bRow = db
12
+ .prepare("SELECT id FROM bee_release WHERE bee_name = ? AND version = ?")
13
+ .get(beeName, toVersion);
14
+ if (!aRow || !bRow)
15
+ throw new Error("VERSION_NOT_FOUND");
16
+ const a = aRow.id;
17
+ const b = bRow.id;
18
+ const aFiles = new Map(db
19
+ .prepare("SELECT path, sha256 FROM bee_file WHERE release_id = ?")
20
+ .all(a).map((r) => [r.path, r.sha256]));
21
+ const bFiles = new Map(db
22
+ .prepare("SELECT path, sha256 FROM bee_file WHERE release_id = ?")
23
+ .all(b).map((r) => [r.path, r.sha256]));
24
+ const added = [];
25
+ const removed = [];
26
+ const modified = [];
27
+ for (const [p, sha] of bFiles) {
28
+ if (!aFiles.has(p))
29
+ added.push(p);
30
+ else if (aFiles.get(p) !== sha)
31
+ modified.push(p);
32
+ }
33
+ for (const [p] of aFiles) {
34
+ if (!bFiles.has(p))
35
+ removed.push(p);
36
+ }
37
+ return { added, removed, modified };
38
+ }
@@ -0,0 +1,8 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare function exportRelease({ db, blobsDir, beeName, version, outPath, }: {
3
+ db: Database.Database;
4
+ blobsDir: string;
5
+ beeName: string;
6
+ version: string;
7
+ outPath: string;
8
+ }): void;
@@ -0,0 +1,31 @@
1
+ import { mkdirSync, writeFileSync, readFileSync, rmSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { runTar } from "./tar-runtime.js";
4
+ export function exportRelease({ db, blobsDir, beeName, version, outPath, }) {
5
+ const id = db
6
+ .prepare("SELECT id FROM bee_release WHERE bee_name = ? AND version = ?")
7
+ .get(beeName, version)?.id;
8
+ if (!id)
9
+ throw new Error("VERSION_NOT_FOUND");
10
+ const manifestRows = db.prepare("SELECT * FROM bee_manifest WHERE release_id = ?").all(id);
11
+ const segRows = db.prepare("SELECT * FROM bee_segment_ref WHERE release_id = ?").all(id);
12
+ const fileRows = db
13
+ .prepare("SELECT * FROM bee_file WHERE release_id = ?")
14
+ .all(id);
15
+ const changeRows = db.prepare("SELECT * FROM bee_change WHERE release_id = ?").all(id);
16
+ const stageDir = join(outPath + ".stage");
17
+ mkdirSync(stageDir, { recursive: true });
18
+ writeFileSync(join(stageDir, "manifest.json"), JSON.stringify({ bee_name: beeName, version, manifestRows, segRows, fileRows, changeRows }, null, 2));
19
+ mkdirSync(join(stageDir, "blobs"), { recursive: true });
20
+ for (const f of fileRows) {
21
+ const src = join(blobsDir, f.sha256.slice(0, 2), f.sha256);
22
+ const dest = join(stageDir, "blobs", f.sha256);
23
+ writeFileSync(dest, readFileSync(src));
24
+ }
25
+ try {
26
+ runTar(["-czf", outPath, "-C", stageDir, "."]);
27
+ }
28
+ finally {
29
+ rmSync(stageDir, { recursive: true, force: true });
30
+ }
31
+ }
@@ -0,0 +1,13 @@
1
+ import type Database from "better-sqlite3";
2
+ /**
3
+ * Garbage-collect content-addressed blobs under `blobsDir/<aa>/<sha>` that
4
+ * no `bee_file` row currently references.
5
+ *
6
+ * @param dryRun if true, list removed SHAs without deleting files.
7
+ * @returns the list of removed SHA names.
8
+ */
9
+ export declare function gcBlobs({ db, blobsDir, dryRun, }: {
10
+ db: Database.Database;
11
+ blobsDir: string;
12
+ dryRun: boolean;
13
+ }): string[];
@@ -0,0 +1,32 @@
1
+ import { readdirSync, rmSync, existsSync, statSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Garbage-collect content-addressed blobs under `blobsDir/<aa>/<sha>` that
5
+ * no `bee_file` row currently references.
6
+ *
7
+ * @param dryRun if true, list removed SHAs without deleting files.
8
+ * @returns the list of removed SHA names.
9
+ */
10
+ export function gcBlobs({ db, blobsDir, dryRun, }) {
11
+ const refs = new Set(db.prepare("SELECT DISTINCT sha256 FROM bee_file").all().map((r) => r.sha256));
12
+ const removed = [];
13
+ if (!existsSync(blobsDir))
14
+ return removed;
15
+ for (const sub of readdirSync(blobsDir)) {
16
+ const subDir = join(blobsDir, sub);
17
+ if (!statSync(subDir).isDirectory())
18
+ continue;
19
+ for (const sha of readdirSync(subDir)) {
20
+ if (refs.has(sha))
21
+ continue;
22
+ const p = join(subDir, sha);
23
+ if (dryRun) {
24
+ removed.push(sha);
25
+ continue;
26
+ }
27
+ rmSync(p);
28
+ removed.push(sha);
29
+ }
30
+ }
31
+ return removed;
32
+ }
@@ -0,0 +1,7 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare function importRelease({ db, blobsDir, inPath, asName, }: {
3
+ db: Database.Database;
4
+ blobsDir: string;
5
+ inPath: string;
6
+ asName?: string;
7
+ }): void;
@@ -0,0 +1,59 @@
1
+ import { readFileSync, mkdirSync, writeFileSync, existsSync, rmSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { assertNotSystemPath } from "../sediment/pool-paths.js";
4
+ import { runTar } from "./tar-runtime.js";
5
+ export function importRelease({ db, blobsDir, inPath, asName, }) {
6
+ const stageDir = inPath + ".extract";
7
+ if (existsSync(stageDir))
8
+ rmSync(stageDir, { recursive: true, force: true });
9
+ mkdirSync(stageDir, { recursive: true });
10
+ let extractOk = false;
11
+ try {
12
+ runTar(["-xzf", inPath, "-C", stageDir]);
13
+ extractOk = true;
14
+ }
15
+ finally {
16
+ if (!extractOk)
17
+ rmSync(stageDir, { recursive: true, force: true });
18
+ }
19
+ // ExportPayload (defined in ./types.ts) is the structural contract
20
+ // shared with release-export.ts, which writes the same JSON shape
21
+ // into <stageDir>/manifest.json. Minor #13: replace the previous
22
+ // inline anonymous type so producer and consumer stay in lock-step.
23
+ const payload = JSON.parse(readFileSync(join(stageDir, "manifest.json"), "utf-8"));
24
+ const beeName = asName ?? payload.bee_name;
25
+ assertNotSystemPath(beeName);
26
+ // Always check collision (the asName path previously skipped it and
27
+ // fell through to a UNIQUE-constraint mid-INSERT failure). Whether
28
+ // the user gave an explicit asName or relied on payload.bee_name, a
29
+ // pre-existing row must be reported cleanly.
30
+ if (db.prepare("SELECT 1 FROM bee_release WHERE bee_name = ?").get(beeName)) {
31
+ throw new Error("IMPORT_NAME_COLLIDES");
32
+ }
33
+ // Copy blobs
34
+ for (const f of payload.fileRows) {
35
+ const dest = join(blobsDir, f.sha256.slice(0, 2));
36
+ mkdirSync(dest, { recursive: true });
37
+ writeFileSync(join(dest, f.sha256), readFileSync(join(stageDir, "blobs", f.sha256)));
38
+ }
39
+ // Re-insert rows: pick a new release id, mirror payload rows
40
+ const tx = db.transaction(() => {
41
+ const ins = db.prepare(`INSERT INTO bee_release (bee_name, version, source, archived_at, archived_by, user_intent_raw, description, parent_version, changelog) VALUES (?, ?, 'user', ?, 'user', ?, ?, ?, ?)`);
42
+ const id = ins.run(beeName, payload.version, new Date().toISOString(), null, null, null, null).lastInsertRowid;
43
+ db.prepare(`INSERT OR REPLACE INTO bee_release_pointer (bee_name, latest_version, released_at) VALUES (?, ?, ?)`).run(beeName, payload.version, new Date().toISOString());
44
+ for (const m of payload.manifestRows) {
45
+ db.prepare(`INSERT INTO bee_manifest (release_id, schema_version, description, segments_json, entrypoint_preamble, promotion, min_cycles, requires_human, requires_smoke, retire_on_misses) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, m.schema_version, m.description, m.segments_json, m.entrypoint_preamble, m.promotion, m.min_cycles, m.requires_human, m.requires_smoke, m.retire_on_misses);
46
+ }
47
+ for (const s of payload.segRows) {
48
+ db.prepare(`INSERT INTO bee_segment_ref (release_id, segment_name, inputs_json, outputs_json, side_effects) VALUES (?, ?, ?, ?, ?)`).run(id, s.segment_name, s.inputs_json, s.outputs_json, s.side_effects);
49
+ }
50
+ for (const f of payload.fileRows) {
51
+ db.prepare(`INSERT INTO bee_file (release_id, owner_kind, owner_name, path, kind, size_bytes, sha256, blob_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(id, f.owner_kind, beeName, f.path, f.kind, f.size_bytes, f.sha256, f.blob_path);
52
+ }
53
+ for (const c of payload.changeRows) {
54
+ db.prepare(`INSERT INTO bee_change (release_id, change_kind, target_kind, target_name, detail) VALUES (?, ?, ?, ?, ?)`).run(id, c.change_kind, c.target_kind, c.target_name, c.detail);
55
+ }
56
+ });
57
+ tx();
58
+ rmSync(stageDir, { recursive: true, force: true });
59
+ }
@@ -0,0 +1,23 @@
1
+ import type Database from "better-sqlite3";
2
+ import type { BeeManifest } from "../sediment/types.js";
3
+ /** Compute the sha256 hash and byte length of a single file. */
4
+ export declare function sha256OfFile(p: string): {
5
+ sha: string;
6
+ bytes: number;
7
+ };
8
+ /** Copy a file into the content-addressed blob store under `blobsDir/<aa>/<sha>`
9
+ * if not already present, and return the relative blob_path used by `bee_file`. */
10
+ export declare function ensureBlob(blobsDir: string, sha: string, srcPath: string): string;
11
+ export declare function walk(root: string, base?: string): Generator<{
12
+ abs: string;
13
+ rel: string;
14
+ }>;
15
+ export declare function retainRelease({ db, blobsDir, scratchDir, manifest, version: explicitVersion, parentVersion, changelog, }: {
16
+ db: Database.Database;
17
+ blobsDir: string;
18
+ scratchDir: string;
19
+ manifest: BeeManifest;
20
+ version?: string;
21
+ parentVersion?: string;
22
+ changelog?: string;
23
+ }): number;
@@ -0,0 +1,89 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFileSync, readdirSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
3
+ import { join, relative } from "node:path";
4
+ /** Compute the sha256 hash and byte length of a single file. */
5
+ export function sha256OfFile(p) {
6
+ const buf = readFileSync(p);
7
+ return { sha: createHash("sha256").update(buf).digest("hex"), bytes: buf.length };
8
+ }
9
+ /** Copy a file into the content-addressed blob store under `blobsDir/<aa>/<sha>`
10
+ * if not already present, and return the relative blob_path used by `bee_file`. */
11
+ export function ensureBlob(blobsDir, sha, srcPath) {
12
+ const dir = join(blobsDir, sha.slice(0, 2));
13
+ const dest = join(dir, sha);
14
+ if (!existsSync(dir))
15
+ mkdirSync(dir, { recursive: true });
16
+ if (!existsSync(dest))
17
+ writeFileSync(dest, readFileSync(srcPath));
18
+ return `blobs/${sha.slice(0, 2)}/${sha}`;
19
+ }
20
+ export function* walk(root, base = root) {
21
+ for (const ent of readdirSync(base, { withFileTypes: true })) {
22
+ const abs = join(base, ent.name);
23
+ if (ent.isDirectory())
24
+ yield* walk(root, abs);
25
+ else {
26
+ const relPosix = relative(root, abs).split(/[\\/]/).join("/");
27
+ yield { abs, rel: relPosix };
28
+ }
29
+ }
30
+ }
31
+ function warnOverflow(column, length) {
32
+ // Soft warning, no truncation: the spec does not mandate truncation,
33
+ // but a stale over-16KB row would silently break downstream readers
34
+ // that assume <16KB. Surface it for ops review.
35
+ // eslint-disable-next-line no-console
36
+ console.warn(`[release-retain] WARN: column ${column} overflowed 16KB guard (${length} bytes) — review and consider truncation`);
37
+ }
38
+ /**
39
+ * Defensive 16KB check: if the value would exceed SQLite's
40
+ * recommended 16KB single-column limit, log a warning. Not a hard
41
+ * error — we let SQLite handle overflow. The columns covered are the
42
+ * four TEXT columns previously unchecked: bee_manifest.segments_json,
43
+ * bee_segment_ref.inputs_json, bee_segment_ref.outputs_json,
44
+ * bee_segment_ref.side_effects.
45
+ */
46
+ function checkOverflow({ table, col }, value) {
47
+ const len = Buffer.byteLength(value, "utf-8");
48
+ if (len > 16 * 1024)
49
+ warnOverflow(`${table}.${col}`, len);
50
+ }
51
+ export function retainRelease({ db, blobsDir, scratchDir, manifest, version: explicitVersion, parentVersion, changelog, }) {
52
+ const version = explicitVersion ?? "0.1.0";
53
+ const tx = db.transaction(() => {
54
+ const ins = db.prepare(`INSERT INTO bee_release (bee_name, version, source, archived_at, archived_by, user_intent_raw, description, parent_version, changelog) VALUES (?, ?, 'user', ?, ?, ?, ?, ?, ?)`);
55
+ const info = ins.run(manifest.name, version, new Date().toISOString(), "llm", null, manifest.description, parentVersion ?? null, changelog ?? null);
56
+ const id = info.lastInsertRowid;
57
+ db.prepare(`INSERT OR REPLACE INTO bee_release_pointer (bee_name, latest_version, released_at) VALUES (?, ?, ?)`).run(manifest.name, version, new Date().toISOString());
58
+ for (const s of manifest.segments) {
59
+ const inputsJson = JSON.stringify(s.inputs);
60
+ const outputsJson = JSON.stringify(s.outputs);
61
+ const sideEffectsStr = s.sideEffects.join(",");
62
+ checkOverflow({ table: "bee_segment_ref", col: "inputs_json" }, inputsJson);
63
+ checkOverflow({ table: "bee_segment_ref", col: "outputs_json" }, outputsJson);
64
+ checkOverflow({ table: "bee_segment_ref", col: "side_effects" }, sideEffectsStr);
65
+ db.prepare(`INSERT INTO bee_segment_ref (release_id, segment_name, inputs_json, outputs_json, side_effects) VALUES (?, ?, ?, ?, ?)`).run(id, s.name, inputsJson, outputsJson, sideEffectsStr);
66
+ }
67
+ // Also guard the manifest-level JSON column that holds the segment
68
+ // name list (can exceed 16KB if a bee advertises thousands of
69
+ // segments).
70
+ const segmentsJson = JSON.stringify(manifest.segments.map((s) => s.name));
71
+ checkOverflow({ table: "bee_manifest", col: "segments_json" }, segmentsJson);
72
+ db.prepare(`INSERT INTO bee_manifest (release_id, schema_version, description, segments_json, entrypoint_preamble, promotion, min_cycles, requires_human, requires_smoke, retire_on_misses) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(id, manifest.schemaVersion, manifest.description, segmentsJson, manifest.entrypoint.preamble, manifest.promotion_status, manifest.promotion.minCycles, manifest.promotion.requiresHumanApproval ? 1 : 0, manifest.promotion.requiresSmokeTest ? 1 : 0, manifest.promotion.retireOnMissesInRow ?? null);
73
+ const insFile = db.prepare(`INSERT INTO bee_file (release_id, owner_kind, owner_name, path, kind, size_bytes, sha256, blob_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
74
+ for (const f of walk(scratchDir)) {
75
+ const { sha, bytes } = sha256OfFile(f.abs);
76
+ const blobPath = ensureBlob(blobsDir, sha, f.abs);
77
+ const kind = f.rel.endsWith(".md")
78
+ ? "markdown"
79
+ : f.rel.startsWith("scripts/")
80
+ ? "script"
81
+ : f.rel.startsWith("references/")
82
+ ? "reference"
83
+ : "other";
84
+ insFile.run(id, "bee", manifest.name, f.rel, kind, bytes, sha, blobPath);
85
+ }
86
+ return id;
87
+ });
88
+ return tx();
89
+ }
@@ -0,0 +1,22 @@
1
+ import Database from "better-sqlite3";
2
+ /**
3
+ * Open (or create) a SkillHub state database at the given path.
4
+ *
5
+ * Behavior:
6
+ * - Creates the parent directory if it does not exist.
7
+ * - Enables WAL journal mode and foreign-key enforcement.
8
+ * - Applies every `migrations/*.sql` file in lexicographic order.
9
+ * Migrations must be idempotent (CREATE TABLE IF NOT EXISTS, etc.).
10
+ *
11
+ * The migrations directory lives next to this source file at build time;
12
+ * we resolve it via `import.meta.url` so the lookup survives vitest ESM
13
+ * (where `__dirname` is undefined). Migration files are discovered by
14
+ * globbing (`*.sql`) and sorted lexicographically so future
15
+ * `002-…`, `003-…` additions are picked up automatically.
16
+ */
17
+ export declare function openStateDb(path: string): Database.Database;
18
+ /**
19
+ * Return the user-defined table names present in `db` (excluding SQLite
20
+ * system tables such as `sqlite_sequence`).
21
+ */
22
+ export declare function listTables(db: Database.Database): string[];
@@ -0,0 +1,47 @@
1
+ import Database from "better-sqlite3";
2
+ import { readFileSync, readdirSync, existsSync, mkdirSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ /**
6
+ * Open (or create) a SkillHub state database at the given path.
7
+ *
8
+ * Behavior:
9
+ * - Creates the parent directory if it does not exist.
10
+ * - Enables WAL journal mode and foreign-key enforcement.
11
+ * - Applies every `migrations/*.sql` file in lexicographic order.
12
+ * Migrations must be idempotent (CREATE TABLE IF NOT EXISTS, etc.).
13
+ *
14
+ * The migrations directory lives next to this source file at build time;
15
+ * we resolve it via `import.meta.url` so the lookup survives vitest ESM
16
+ * (where `__dirname` is undefined). Migration files are discovered by
17
+ * globbing (`*.sql`) and sorted lexicographically so future
18
+ * `002-…`, `003-…` additions are picked up automatically.
19
+ */
20
+ export function openStateDb(path) {
21
+ const parent = dirname(path);
22
+ if (!existsSync(parent))
23
+ mkdirSync(parent, { recursive: true });
24
+ const db = new Database(path);
25
+ db.pragma("journal_mode = WAL");
26
+ db.pragma("foreign_keys = ON");
27
+ const here = dirname(fileURLToPath(import.meta.url));
28
+ const migrationsDir = join(here, "migrations");
29
+ if (existsSync(migrationsDir)) {
30
+ const files = readdirSync(migrationsDir).filter((f) => f.endsWith(".sql")).sort();
31
+ for (const f of files) {
32
+ const sql = readFileSync(join(migrationsDir, f), "utf-8");
33
+ db.exec(sql);
34
+ }
35
+ }
36
+ return db;
37
+ }
38
+ /**
39
+ * Return the user-defined table names present in `db` (excluding SQLite
40
+ * system tables such as `sqlite_sequence`).
41
+ */
42
+ export function listTables(db) {
43
+ const rows = db
44
+ .prepare("SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%'")
45
+ .all();
46
+ return rows.map((r) => r.name);
47
+ }
@@ -0,0 +1,21 @@
1
+ /** Thrown when no usable tar binary can be located. */
2
+ export declare class TAR_NOT_FOUND extends Error {
3
+ constructor(msg: string);
4
+ }
5
+ /**
6
+ * Run `tar <args...>` in a cross-platform way.
7
+ *
8
+ * Args MUST be `["-czf", outPath, "-C", stageDir, "."]` style (no
9
+ * shell quoting needed because we use execFileSync, not execSync).
10
+ *
11
+ * After the Critical #3 fix:
12
+ * - Honors PEAKS_TAR_BIN / TAR env vars.
13
+ * - On Windows, tries C:\Windows\System32\tar.exe first; falls back
14
+ * to PATH lookup if it's missing.
15
+ * - Accumulates tar's stderr and re-throws it on non-zero exit so
16
+ * operators can see WHY tar failed (path typo, permission, corrupt
17
+ * stage dir, etc.) instead of swallowing it.
18
+ *
19
+ * Throws `TAR_NOT_FOUND` when the binary cannot be located.
20
+ */
21
+ export declare function runTar(args: string[]): void;
@@ -0,0 +1,91 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ /** Thrown when no usable tar binary can be located. */
4
+ export class TAR_NOT_FOUND extends Error {
5
+ constructor(msg) {
6
+ super(`TAR_NOT_FOUND: ${msg}`);
7
+ this.name = "TAR_NOT_FOUND";
8
+ }
9
+ }
10
+ /**
11
+ * Resolve a tar binary path, in priority order:
12
+ * 1. process.env.PEAKS_TAR_BIN (explicit override; honored unconditionally)
13
+ * 2. process.env.TAR (POSIX convention, honored if set)
14
+ * 3. On Windows: C:\Windows\System32\tar.exe (bsdtar — accepts
15
+ * Windows-style paths verbatim, unlike git-bash GNU tar)
16
+ * 4. PATH lookup: "tar" (delegates to the platform default)
17
+ *
18
+ * Throws `TAR_NOT_FOUND` when none of the candidates exist (Windows
19
+ * file-system check) or no override is set (POSIX). On POSIX we
20
+ * always trust PATH; tar is in base images 99.9% of the time. On
21
+ * Windows we explicitly stat each candidate so a missing
22
+ * C:\Windows\System32\tar.exe falls through to PATH instead of
23
+ * throwing an opaque spawn-ENOENT.
24
+ */
25
+ function resolveTarBin() {
26
+ const envOverride = process.env.PEAKS_TAR_BIN;
27
+ if (envOverride && envOverride.length > 0)
28
+ return envOverride;
29
+ const envTar = process.env.TAR;
30
+ if (envTar && envTar.length > 0)
31
+ return envTar;
32
+ if (process.platform === "win32") {
33
+ const systemTar = "C:\\Windows\\System32\\tar.exe";
34
+ if (existsSync(systemTar))
35
+ return systemTar;
36
+ // Fall through to PATH lookup below — many dev setups install tar
37
+ // under Git for Windows or WindowsApps rather than System32.
38
+ }
39
+ // PATH lookup. We can't stat `tar` directly (it's a name, not a path),
40
+ // so we trust the resolution to execFileSync and surface a clean
41
+ // TAR_NOT_FOUND error from the caller if it fails.
42
+ return "tar";
43
+ }
44
+ /**
45
+ * Run `tar <args...>` in a cross-platform way.
46
+ *
47
+ * Args MUST be `["-czf", outPath, "-C", stageDir, "."]` style (no
48
+ * shell quoting needed because we use execFileSync, not execSync).
49
+ *
50
+ * After the Critical #3 fix:
51
+ * - Honors PEAKS_TAR_BIN / TAR env vars.
52
+ * - On Windows, tries C:\Windows\System32\tar.exe first; falls back
53
+ * to PATH lookup if it's missing.
54
+ * - Accumulates tar's stderr and re-throws it on non-zero exit so
55
+ * operators can see WHY tar failed (path typo, permission, corrupt
56
+ * stage dir, etc.) instead of swallowing it.
57
+ *
58
+ * Throws `TAR_NOT_FOUND` when the binary cannot be located.
59
+ */
60
+ export function runTar(args) {
61
+ const cmd = resolveTarBin();
62
+ try {
63
+ execFileSync(cmd, args, {
64
+ stdio: ["ignore", "ignore", "pipe"],
65
+ // Surface stderr text rather than dumping a Buffer at the caller.
66
+ // execFileSync with stdio: ["ignore","ignore","pipe"] captures the
67
+ // stderr stream into the Error's `.stderr` Buffer when the child
68
+ // exits non-zero.
69
+ });
70
+ }
71
+ catch (e) {
72
+ // Distinguish "binary not found" from "binary ran but failed".
73
+ if (e && typeof e === "object" && "code" in e) {
74
+ const code = e.code;
75
+ if (code === "ENOENT") {
76
+ throw new TAR_NOT_FOUND(`tar binary not found (cmd="${cmd}"). Set PEAKS_TAR_BIN to override, or install tar (Windows: bsdtar is bundled with Windows 10+).`);
77
+ }
78
+ }
79
+ // Non-zero exit from tar itself — re-throw with stderr text.
80
+ const stderr = e?.stderr;
81
+ const stderrText = stderr instanceof Buffer
82
+ ? stderr.toString("utf-8")
83
+ : typeof stderr === "string"
84
+ ? stderr
85
+ : "";
86
+ const baseMsg = e instanceof Error ? e.message : typeof e === "string" ? e : String(e);
87
+ const wrapped = new Error(`tar exited non-zero (cmd="${cmd}"): ${baseMsg}${stderrText ? `\ntar stderr:\n${stderrText.trimEnd()}` : ""}`);
88
+ wrapped.cause = e;
89
+ throw wrapped;
90
+ }
91
+ }
@@ -0,0 +1,105 @@
1
+ export interface BeeReleaseRow {
2
+ id: number;
3
+ bee_name: string;
4
+ version: string;
5
+ source: "user";
6
+ archived_at: string;
7
+ archived_by: "user" | "llm";
8
+ user_intent_raw: string | null;
9
+ description: string | null;
10
+ parent_version: string | null;
11
+ changelog: string | null;
12
+ }
13
+ export interface BeeReleasePointerRow {
14
+ bee_name: string;
15
+ latest_version: string;
16
+ released_at: string;
17
+ }
18
+ export interface BeeManifestRow {
19
+ release_id: number;
20
+ schema_version: string;
21
+ description: string;
22
+ segments_json: string;
23
+ entrypoint_preamble: string | null;
24
+ promotion: string;
25
+ min_cycles: number | null;
26
+ requires_human: number;
27
+ requires_smoke: number;
28
+ retire_on_misses: number | null;
29
+ }
30
+ export interface BeeSegmentRefRow {
31
+ id: number;
32
+ release_id: number;
33
+ segment_name: string;
34
+ inputs_json: string | null;
35
+ outputs_json: string | null;
36
+ side_effects: string | null;
37
+ }
38
+ export interface BeeFileRow {
39
+ id: number;
40
+ release_id: number;
41
+ owner_kind: "bee" | "segment";
42
+ owner_name: string;
43
+ path: string;
44
+ kind: "markdown" | "script" | "reference" | "binary" | "other";
45
+ size_bytes: number;
46
+ sha256: string;
47
+ blob_path: string;
48
+ }
49
+ export interface BeeChangeRow {
50
+ id: number;
51
+ release_id: number;
52
+ change_kind: string;
53
+ target_kind: string;
54
+ target_name: string;
55
+ detail: string | null;
56
+ }
57
+ /**
58
+ * Shape of `manifest.json` inside a release export tarball.
59
+ *
60
+ * Producer: `src/services/skillhub/release-export.ts` writes this file via
61
+ * `JSON.stringify({ bee_name, version, manifestRows, segRows, fileRows, changeRows })`.
62
+ * Consumer: `src/services/skillhub/release-import.ts` parses it back with
63
+ * `JSON.parse(readFileSync(join(stageDir, "manifest.json"), "utf-8"))`.
64
+ *
65
+ * Defining it once here (rather than as an inline anonymous type at the
66
+ * call-site) lets both sides share a structural contract. If a future
67
+ * field is added — e.g. an exported schema-version stamp — it lands in
68
+ * one place and TypeScript flags every consumer that needs updating.
69
+ */
70
+ export interface ExportPayload {
71
+ bee_name: string;
72
+ version: string;
73
+ manifestRows: Array<{
74
+ schema_version: string;
75
+ description: string;
76
+ segments_json: string;
77
+ entrypoint_preamble: string | null;
78
+ promotion: string;
79
+ min_cycles: number | null;
80
+ requires_human: number;
81
+ requires_smoke: number;
82
+ retire_on_misses: number | null;
83
+ }>;
84
+ segRows: Array<{
85
+ segment_name: string;
86
+ inputs_json: string | null;
87
+ outputs_json: string | null;
88
+ side_effects: string | null;
89
+ }>;
90
+ fileRows: Array<{
91
+ owner_kind: string;
92
+ owner_name: string;
93
+ path: string;
94
+ kind: string;
95
+ size_bytes: number;
96
+ sha256: string;
97
+ blob_path: string;
98
+ }>;
99
+ changeRows: Array<{
100
+ change_kind: string;
101
+ target_kind: string;
102
+ target_name: string;
103
+ detail: string | null;
104
+ }>;
105
+ }
@@ -0,0 +1 @@
1
+ export {};