peaks-loop 4.1.3 → 4.1.4

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 (402) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +56 -0
  3. package/README-en.md +1 -1
  4. package/README.md +1 -1
  5. package/dist/cli/commands/asset-command-shared.d.ts +12 -0
  6. package/dist/cli/commands/asset-command-shared.js +45 -0
  7. package/dist/cli/commands/asset-commands.d.ts +6 -1
  8. package/dist/cli/commands/asset-commands.js +11 -372
  9. package/dist/cli/commands/asset-crystallize-command.d.ts +3 -0
  10. package/dist/cli/commands/asset-crystallize-command.js +60 -0
  11. package/dist/cli/commands/asset-crystallize-payload.d.ts +47 -0
  12. package/dist/cli/commands/asset-crystallize-payload.js +85 -0
  13. package/dist/cli/commands/asset-crystallize-runner.d.ts +3 -0
  14. package/dist/cli/commands/asset-crystallize-runner.js +133 -0
  15. package/dist/cli/commands/asset-dispose-command.d.ts +3 -0
  16. package/dist/cli/commands/asset-dispose-command.js +99 -0
  17. package/dist/cli/commands/asset-status-command.d.ts +3 -0
  18. package/dist/cli/commands/asset-status-command.js +100 -0
  19. package/dist/cli/commands/baseline-audit-command.d.ts +3 -0
  20. package/dist/cli/commands/baseline-audit-command.js +64 -0
  21. package/dist/cli/commands/baseline-command-shared.d.ts +23 -0
  22. package/dist/cli/commands/baseline-command-shared.js +39 -0
  23. package/dist/cli/commands/baseline-commands.js +33 -313
  24. package/dist/cli/commands/baseline-freeze-commands.d.ts +4 -0
  25. package/dist/cli/commands/baseline-freeze-commands.js +81 -0
  26. package/dist/cli/commands/baseline-guard-command.d.ts +3 -0
  27. package/dist/cli/commands/baseline-guard-command.js +52 -0
  28. package/dist/cli/commands/baseline-read-commands.d.ts +5 -0
  29. package/dist/cli/commands/baseline-read-commands.js +72 -0
  30. package/dist/cli/commands/baseline-rollback-commands.d.ts +4 -0
  31. package/dist/cli/commands/baseline-rollback-commands.js +88 -0
  32. package/dist/cli/commands/classify-downgrade-command.d.ts +9 -0
  33. package/dist/cli/commands/classify-downgrade-command.js +21 -0
  34. package/dist/cli/commands/classify-run-command.d.ts +9 -0
  35. package/dist/cli/commands/classify-run-command.js +73 -0
  36. package/dist/cli/commands/classify-signals.d.ts +5 -0
  37. package/dist/cli/commands/classify-signals.js +104 -0
  38. package/dist/cli/commands/code-emit-handoff-command.js +40 -3
  39. package/dist/cli/commands/code-gate-step-08-command.js +25 -9
  40. package/dist/cli/commands/codegraph-command-options.d.ts +22 -0
  41. package/dist/cli/commands/codegraph-command-options.js +22 -0
  42. package/dist/cli/commands/codegraph-commands.d.ts +2 -2
  43. package/dist/cli/commands/codegraph-commands.js +14 -397
  44. package/dist/cli/commands/codegraph-config-restore-command.d.ts +3 -0
  45. package/dist/cli/commands/codegraph-config-restore-command.js +200 -0
  46. package/dist/cli/commands/codegraph-proxy-commands.d.ts +10 -0
  47. package/dist/cli/commands/codegraph-proxy-commands.js +159 -0
  48. package/dist/cli/commands/codegraph-repair-commands.d.ts +3 -0
  49. package/dist/cli/commands/codegraph-repair-commands.js +94 -0
  50. package/dist/cli/commands/codegraph-status-command.d.ts +1 -1
  51. package/dist/cli/commands/codegraph-status-command.js +27 -214
  52. package/dist/cli/commands/codegraph-status-integrity.d.ts +44 -0
  53. package/dist/cli/commands/codegraph-status-integrity.js +121 -0
  54. package/dist/cli/commands/codegraph-status-json.d.ts +5 -0
  55. package/dist/cli/commands/codegraph-status-json.js +127 -0
  56. package/dist/cli/commands/container-command-shared.d.ts +60 -0
  57. package/dist/cli/commands/container-command-shared.js +52 -0
  58. package/dist/cli/commands/container-commands.d.ts +1 -1
  59. package/dist/cli/commands/container-commands.js +4 -216
  60. package/dist/cli/commands/container-release-command.d.ts +3 -0
  61. package/dist/cli/commands/container-release-command.js +105 -0
  62. package/dist/cli/commands/container-spawn-command.d.ts +3 -0
  63. package/dist/cli/commands/container-spawn-command.js +148 -0
  64. package/dist/cli/commands/context-check-command.d.ts +3 -0
  65. package/dist/cli/commands/context-check-command.js +81 -0
  66. package/dist/cli/commands/context-commands.d.ts +2 -7
  67. package/dist/cli/commands/context-commands.js +6 -276
  68. package/dist/cli/commands/context-layer-command.d.ts +3 -0
  69. package/dist/cli/commands/context-layer-command.js +34 -0
  70. package/dist/cli/commands/context-layer-fetchers.d.ts +15 -0
  71. package/dist/cli/commands/context-layer-fetchers.js +162 -0
  72. package/dist/cli/commands/context-status-command.d.ts +17 -0
  73. package/dist/cli/commands/context-status-command.js +41 -0
  74. package/dist/cli/commands/contract-write-command.d.ts +3 -0
  75. package/dist/cli/commands/contract-write-command.js +144 -0
  76. package/dist/cli/commands/core/doctor-bindings.d.ts +17 -0
  77. package/dist/cli/commands/core/doctor-bindings.js +30 -0
  78. package/dist/cli/commands/core/doctor-command.d.ts +4 -18
  79. package/dist/cli/commands/core/doctor-command.js +2 -323
  80. package/dist/cli/commands/core/doctor-logs.d.ts +8 -0
  81. package/dist/cli/commands/core/doctor-logs.js +32 -0
  82. package/dist/cli/commands/core/doctor-probes.d.ts +3 -0
  83. package/dist/cli/commands/core/doctor-probes.js +55 -0
  84. package/dist/cli/commands/core/doctor-run-command.d.ts +12 -0
  85. package/dist/cli/commands/core/doctor-run-command.js +172 -0
  86. package/dist/cli/commands/core/doctor-summary.d.ts +7 -0
  87. package/dist/cli/commands/core/doctor-summary.js +39 -0
  88. package/dist/cli/commands/core/memory-command-shared.d.ts +25 -0
  89. package/dist/cli/commands/core/memory-command-shared.js +20 -0
  90. package/dist/cli/commands/core/memory-command.d.ts +1 -1
  91. package/dist/cli/commands/core/memory-command.js +6 -227
  92. package/dist/cli/commands/core/memory-delegated-verbs.d.ts +4 -0
  93. package/dist/cli/commands/core/memory-delegated-verbs.js +178 -0
  94. package/dist/cli/commands/core/memory-extract-command.d.ts +3 -0
  95. package/dist/cli/commands/core/memory-extract-command.js +90 -0
  96. package/dist/cli/commands/core/memory-sync-command.d.ts +3 -0
  97. package/dist/cli/commands/core/memory-sync-command.js +38 -0
  98. package/dist/cli/commands/core/session-command.d.ts +1 -1
  99. package/dist/cli/commands/core/session-command.js +12 -206
  100. package/dist/cli/commands/core/session-info-command.d.ts +3 -0
  101. package/dist/cli/commands/core/session-info-command.js +142 -0
  102. package/dist/cli/commands/core/session-verb-commands.d.ts +5 -0
  103. package/dist/cli/commands/core/session-verb-commands.js +58 -0
  104. package/dist/cli/commands/core/standards-command.d.ts +1 -24
  105. package/dist/cli/commands/core/standards-command.js +33 -201
  106. package/dist/cli/commands/core/standards-init-command.d.ts +3 -0
  107. package/dist/cli/commands/core/standards-init-command.js +87 -0
  108. package/dist/cli/commands/core/standards-lint.d.ts +24 -0
  109. package/dist/cli/commands/core/standards-lint.js +57 -0
  110. package/dist/cli/commands/core/standards-migrate-command.d.ts +3 -0
  111. package/dist/cli/commands/core/standards-migrate-command.js +57 -0
  112. package/dist/cli/commands/cron-scheduler-commands.d.ts +5 -1
  113. package/dist/cli/commands/cron-scheduler-commands.js +36 -206
  114. package/dist/cli/commands/cron-scheduler-run-once-command.d.ts +7 -0
  115. package/dist/cli/commands/cron-scheduler-run-once-command.js +35 -0
  116. package/dist/cli/commands/cron-scheduler-shared.d.ts +6 -0
  117. package/dist/cli/commands/cron-scheduler-shared.js +48 -0
  118. package/dist/cli/commands/cron-scheduler-start-command.d.ts +7 -0
  119. package/dist/cli/commands/cron-scheduler-start-command.js +65 -0
  120. package/dist/cli/commands/cron-scheduler-status-command.d.ts +7 -0
  121. package/dist/cli/commands/cron-scheduler-status-command.js +46 -0
  122. package/dist/cli/commands/cron-scheduler-stop-command.d.ts +7 -0
  123. package/dist/cli/commands/cron-scheduler-stop-command.js +61 -0
  124. package/dist/cli/commands/dispatch-dag-envelope.d.ts +41 -0
  125. package/dist/cli/commands/dispatch-dag-envelope.js +49 -0
  126. package/dist/cli/commands/dispatch-dag-failure.d.ts +18 -0
  127. package/dist/cli/commands/dispatch-dag-failure.js +16 -0
  128. package/dist/cli/commands/dispatch-dag-preflight.d.ts +51 -0
  129. package/dist/cli/commands/dispatch-dag-preflight.js +105 -0
  130. package/dist/cli/commands/dispatch-dag-runners.d.ts +48 -0
  131. package/dist/cli/commands/dispatch-dag-runners.js +73 -0
  132. package/dist/cli/commands/dispatch-from-dag.d.ts +27 -0
  133. package/dist/cli/commands/dispatch-from-dag.js +87 -257
  134. package/dist/cli/commands/final-review-command-envelopes.d.ts +44 -0
  135. package/dist/cli/commands/final-review-command-envelopes.js +100 -0
  136. package/dist/cli/commands/final-review-command-shared.d.ts +52 -0
  137. package/dist/cli/commands/final-review-command-shared.js +35 -0
  138. package/dist/cli/commands/final-review-commands.d.ts +7 -27
  139. package/dist/cli/commands/final-review-commands.js +13 -240
  140. package/dist/cli/commands/final-review-prepare-command.d.ts +3 -0
  141. package/dist/cli/commands/final-review-prepare-command.js +200 -0
  142. package/dist/cli/commands/governance-classify-contract-commands.d.ts +23 -9
  143. package/dist/cli/commands/governance-classify-contract-commands.js +26 -269
  144. package/dist/cli/commands/hooks-command-shared.d.ts +42 -0
  145. package/dist/cli/commands/hooks-command-shared.js +32 -0
  146. package/dist/cli/commands/hooks-commands.d.ts +20 -0
  147. package/dist/cli/commands/hooks-commands.js +75 -309
  148. package/dist/cli/commands/hooks-install-envelopes.d.ts +6 -0
  149. package/dist/cli/commands/hooks-install-envelopes.js +144 -0
  150. package/dist/cli/commands/hooks-status-command.d.ts +3 -0
  151. package/dist/cli/commands/hooks-status-command.js +93 -0
  152. package/dist/cli/commands/hooks-uninstall-command.d.ts +3 -0
  153. package/dist/cli/commands/hooks-uninstall-command.js +43 -0
  154. package/dist/cli/commands/loop-command-shared.d.ts +31 -0
  155. package/dist/cli/commands/loop-command-shared.js +15 -0
  156. package/dist/cli/commands/loop-commands.d.ts +12 -17
  157. package/dist/cli/commands/loop-commands.js +56 -238
  158. package/dist/cli/commands/loop-export-command.d.ts +3 -0
  159. package/dist/cli/commands/loop-export-command.js +73 -0
  160. package/dist/cli/commands/loop-goal-compose-command.d.ts +3 -0
  161. package/dist/cli/commands/loop-goal-compose-command.js +36 -0
  162. package/dist/cli/commands/loop-import-command.d.ts +3 -0
  163. package/dist/cli/commands/loop-import-command.js +86 -0
  164. package/dist/cli/commands/loop-placeholder-commands.d.ts +3 -0
  165. package/dist/cli/commands/loop-placeholder-commands.js +52 -0
  166. package/dist/cli/commands/memory-command-shared.d.ts +59 -0
  167. package/dist/cli/commands/memory-command-shared.js +39 -0
  168. package/dist/cli/commands/memory-commands.d.ts +6 -79
  169. package/dist/cli/commands/memory-commands.js +19 -309
  170. package/dist/cli/commands/memory-ingest-command.d.ts +3 -0
  171. package/dist/cli/commands/memory-ingest-command.js +50 -0
  172. package/dist/cli/commands/memory-list-command.d.ts +16 -0
  173. package/dist/cli/commands/memory-list-command.js +129 -0
  174. package/dist/cli/commands/memory-reindex-command.d.ts +9 -0
  175. package/dist/cli/commands/memory-reindex-command.js +78 -0
  176. package/dist/cli/commands/memory-rotate-command.d.ts +3 -0
  177. package/dist/cli/commands/memory-rotate-command.js +55 -0
  178. package/dist/cli/commands/memory-search-command.d.ts +7 -0
  179. package/dist/cli/commands/memory-search-command.js +46 -0
  180. package/dist/cli/commands/openspec-archive-command.d.ts +3 -0
  181. package/dist/cli/commands/openspec-archive-command.js +55 -0
  182. package/dist/cli/commands/openspec-command-shared.d.ts +62 -0
  183. package/dist/cli/commands/openspec-command-shared.js +135 -0
  184. package/dist/cli/commands/openspec-commands.d.ts +1 -1
  185. package/dist/cli/commands/openspec-commands.js +33 -306
  186. package/dist/cli/commands/openspec-from-doctor-command.d.ts +3 -0
  187. package/dist/cli/commands/openspec-from-doctor-command.js +66 -0
  188. package/dist/cli/commands/openspec-init-command.d.ts +3 -0
  189. package/dist/cli/commands/openspec-init-command.js +49 -0
  190. package/dist/cli/commands/openspec-list-command.d.ts +3 -0
  191. package/dist/cli/commands/openspec-list-command.js +27 -0
  192. package/dist/cli/commands/openspec-render-command.d.ts +3 -0
  193. package/dist/cli/commands/openspec-render-command.js +33 -0
  194. package/dist/cli/commands/openspec-show-command.d.ts +3 -0
  195. package/dist/cli/commands/openspec-show-command.js +33 -0
  196. package/dist/cli/commands/openspec-to-rd-command.d.ts +3 -0
  197. package/dist/cli/commands/openspec-to-rd-command.js +33 -0
  198. package/dist/cli/commands/openspec-validate-command.d.ts +3 -0
  199. package/dist/cli/commands/openspec-validate-command.js +45 -0
  200. package/dist/cli/commands/playwright-browser-command.d.ts +8 -0
  201. package/dist/cli/commands/playwright-browser-command.js +61 -0
  202. package/dist/cli/commands/playwright-commands.d.ts +10 -62
  203. package/dist/cli/commands/playwright-commands.js +77 -400
  204. package/dist/cli/commands/playwright-envelope.d.ts +8 -0
  205. package/dist/cli/commands/playwright-envelope.js +29 -0
  206. package/dist/cli/commands/playwright-ls-stop-commands.d.ts +4 -0
  207. package/dist/cli/commands/playwright-ls-stop-commands.js +74 -0
  208. package/dist/cli/commands/playwright-session-store.d.ts +65 -0
  209. package/dist/cli/commands/playwright-session-store.js +189 -0
  210. package/dist/cli/commands/project-commands.d.ts +19 -0
  211. package/dist/cli/commands/project-commands.js +98 -259
  212. package/dist/cli/commands/project-context-command.d.ts +3 -0
  213. package/dist/cli/commands/project-context-command.js +44 -0
  214. package/dist/cli/commands/project-dashboard-command.d.ts +3 -0
  215. package/dist/cli/commands/project-dashboard-command.js +74 -0
  216. package/dist/cli/commands/project-knowledge-command.d.ts +3 -0
  217. package/dist/cli/commands/project-knowledge-command.js +48 -0
  218. package/dist/cli/commands/project-memories-show-command.d.ts +3 -0
  219. package/dist/cli/commands/project-memories-show-command.js +87 -0
  220. package/dist/cli/commands/project-memory-index-command.d.ts +3 -0
  221. package/dist/cli/commands/project-memory-index-command.js +31 -0
  222. package/dist/cli/commands/qa-archive-screenshots-command.d.ts +3 -0
  223. package/dist/cli/commands/qa-archive-screenshots-command.js +53 -0
  224. package/dist/cli/commands/qa-commands.d.ts +14 -87
  225. package/dist/cli/commands/qa-commands.js +17 -315
  226. package/dist/cli/commands/qa-context-prestep.d.ts +1 -0
  227. package/dist/cli/commands/qa-context-prestep.js +34 -0
  228. package/dist/cli/commands/qa-run-command.d.ts +3 -0
  229. package/dist/cli/commands/qa-run-command.js +105 -0
  230. package/dist/cli/commands/qa-run-options.d.ts +23 -0
  231. package/dist/cli/commands/qa-run-options.js +31 -0
  232. package/dist/cli/commands/qa-run-slice.d.ts +41 -0
  233. package/dist/cli/commands/qa-run-slice.js +145 -0
  234. package/dist/cli/commands/release-canary-command.d.ts +28 -0
  235. package/dist/cli/commands/release-canary-command.js +129 -0
  236. package/dist/cli/commands/release-command-shared.d.ts +13 -0
  237. package/dist/cli/commands/release-command-shared.js +18 -0
  238. package/dist/cli/commands/release-commands.d.ts +10 -18
  239. package/dist/cli/commands/release-commands.js +25 -298
  240. package/dist/cli/commands/release-done-command.d.ts +3 -0
  241. package/dist/cli/commands/release-done-command.js +64 -0
  242. package/dist/cli/commands/release-hotfix-command.d.ts +3 -0
  243. package/dist/cli/commands/release-hotfix-command.js +50 -0
  244. package/dist/cli/commands/release-plan-command.d.ts +3 -0
  245. package/dist/cli/commands/release-plan-command.js +33 -0
  246. package/dist/cli/commands/release-precheck-command.d.ts +3 -0
  247. package/dist/cli/commands/release-precheck-command.js +28 -0
  248. package/dist/cli/commands/release-promote-command.d.ts +3 -0
  249. package/dist/cli/commands/release-promote-command.js +34 -0
  250. package/dist/cli/commands/release-rollback-command.d.ts +3 -0
  251. package/dist/cli/commands/release-rollback-command.js +33 -0
  252. package/dist/cli/commands/release-watch-command.d.ts +3 -0
  253. package/dist/cli/commands/release-watch-command.js +44 -0
  254. package/dist/cli/commands/sediment-argv-flags.d.ts +54 -0
  255. package/dist/cli/commands/sediment-argv-flags.js +116 -0
  256. package/dist/cli/commands/sediment-command-shared.d.ts +15 -0
  257. package/dist/cli/commands/sediment-command-shared.js +5 -0
  258. package/dist/cli/commands/sediment-commands.d.ts +35 -59
  259. package/dist/cli/commands/sediment-commands.js +36 -590
  260. package/dist/cli/commands/sediment-pool-commands.d.ts +9 -0
  261. package/dist/cli/commands/sediment-pool-commands.js +185 -0
  262. package/dist/cli/commands/sediment-query-commands.d.ts +4 -0
  263. package/dist/cli/commands/sediment-query-commands.js +94 -0
  264. package/dist/cli/commands/sediment-release-commands.d.ts +8 -0
  265. package/dist/cli/commands/sediment-release-commands.js +232 -0
  266. package/dist/cli/commands/sop-advance-command.d.ts +3 -0
  267. package/dist/cli/commands/sop-advance-command.js +160 -0
  268. package/dist/cli/commands/sop-check-command.d.ts +3 -0
  269. package/dist/cli/commands/sop-check-command.js +44 -0
  270. package/dist/cli/commands/sop-command-shared.d.ts +23 -0
  271. package/dist/cli/commands/sop-command-shared.js +18 -0
  272. package/dist/cli/commands/sop-commands.d.ts +15 -1
  273. package/dist/cli/commands/sop-commands.js +26 -240
  274. package/dist/cli/commands/sop-init-command.d.ts +3 -0
  275. package/dist/cli/commands/sop-init-command.js +51 -0
  276. package/dist/cli/commands/sop-lint-command.d.ts +3 -0
  277. package/dist/cli/commands/sop-lint-command.js +64 -0
  278. package/dist/cli/commands/sop-register-command.d.ts +3 -0
  279. package/dist/cli/commands/sop-register-command.js +48 -0
  280. package/dist/cli/commands/sop-registry-command.d.ts +3 -0
  281. package/dist/cli/commands/sop-registry-command.js +30 -0
  282. package/dist/cli/commands/statusline-command-shared.d.ts +73 -0
  283. package/dist/cli/commands/statusline-command-shared.js +90 -0
  284. package/dist/cli/commands/statusline-commands.d.ts +1 -19
  285. package/dist/cli/commands/statusline-commands.js +48 -287
  286. package/dist/cli/commands/statusline-compact-command.d.ts +4 -0
  287. package/dist/cli/commands/statusline-compact-command.js +54 -0
  288. package/dist/cli/commands/statusline-install-command.d.ts +3 -0
  289. package/dist/cli/commands/statusline-install-command.js +48 -0
  290. package/dist/cli/commands/statusline-render-command.d.ts +9 -0
  291. package/dist/cli/commands/statusline-render-command.js +55 -0
  292. package/dist/cli/commands/statusline-status-command.d.ts +3 -0
  293. package/dist/cli/commands/statusline-status-command.js +23 -0
  294. package/dist/cli/commands/statusline-uninstall-command.d.ts +3 -0
  295. package/dist/cli/commands/statusline-uninstall-command.js +23 -0
  296. package/dist/cli/commands/test-command-run-helpers.d.ts +27 -0
  297. package/dist/cli/commands/test-command-run-helpers.js +73 -0
  298. package/dist/cli/commands/test-command-runner-resolution.d.ts +57 -0
  299. package/dist/cli/commands/test-command-runner-resolution.js +183 -0
  300. package/dist/cli/commands/test-commands.d.ts +8 -56
  301. package/dist/cli/commands/test-commands.js +26 -249
  302. package/dist/cli/commands/vm-command-shared.d.ts +23 -0
  303. package/dist/cli/commands/vm-command-shared.js +23 -0
  304. package/dist/cli/commands/vm-commands.d.ts +1 -28
  305. package/dist/cli/commands/vm-commands.js +36 -270
  306. package/dist/cli/commands/vm-hypervisor-runtime.d.ts +15 -0
  307. package/dist/cli/commands/vm-hypervisor-runtime.js +64 -0
  308. package/dist/cli/commands/vm-release-command.d.ts +5 -0
  309. package/dist/cli/commands/vm-release-command.js +101 -0
  310. package/dist/cli/commands/vm-spawn-command.d.ts +5 -0
  311. package/dist/cli/commands/vm-spawn-command.js +177 -0
  312. package/dist/cli/commands/web-command-shared.d.ts +12 -0
  313. package/dist/cli/commands/web-command-shared.js +30 -0
  314. package/dist/cli/commands/web-commands.d.ts +7 -14
  315. package/dist/cli/commands/web-commands.js +6 -314
  316. package/dist/cli/commands/web-install-command.d.ts +10 -0
  317. package/dist/cli/commands/web-install-command.js +116 -0
  318. package/dist/cli/commands/web-lifecycle-commands.d.ts +9 -30
  319. package/dist/cli/commands/web-lifecycle-commands.js +14 -322
  320. package/dist/cli/commands/web-login-command.d.ts +14 -0
  321. package/dist/cli/commands/web-login-command.js +189 -0
  322. package/dist/cli/commands/web-op-payload.d.ts +22 -0
  323. package/dist/cli/commands/web-op-payload.js +89 -0
  324. package/dist/cli/commands/web-op-refusals.d.ts +37 -0
  325. package/dist/cli/commands/web-op-refusals.js +73 -0
  326. package/dist/cli/commands/web-op-runner.d.ts +14 -0
  327. package/dist/cli/commands/web-op-runner.js +166 -0
  328. package/dist/cli/commands/web-status-command.d.ts +4 -0
  329. package/dist/cli/commands/web-status-command.js +32 -0
  330. package/dist/cli/commands/web-stop-command.d.ts +10 -0
  331. package/dist/cli/commands/web-stop-command.js +59 -0
  332. package/dist/cli/commands/web-verb-specs.d.ts +18 -0
  333. package/dist/cli/commands/web-verb-specs.js +66 -0
  334. package/dist/cli/commands/workflow-command-shared.d.ts +102 -0
  335. package/dist/cli/commands/workflow-command-shared.js +74 -0
  336. package/dist/cli/commands/workflow-graph-commands.d.ts +3 -0
  337. package/dist/cli/commands/workflow-graph-commands.js +73 -0
  338. package/dist/cli/commands/workflow-init-command.d.ts +3 -0
  339. package/dist/cli/commands/workflow-init-command.js +68 -0
  340. package/dist/cli/commands/workflow-lifecycle-commands.d.ts +9 -59
  341. package/dist/cli/commands/workflow-lifecycle-commands.js +14 -348
  342. package/dist/cli/commands/workflow-node-commands.d.ts +3 -0
  343. package/dist/cli/commands/workflow-node-commands.js +154 -0
  344. package/dist/cli/commands/workflow-terminalize-command.d.ts +3 -0
  345. package/dist/cli/commands/workflow-terminalize-command.js +56 -0
  346. package/dist/services/code/auto-compact-artifacts.d.ts +54 -0
  347. package/dist/services/code/auto-compact-artifacts.js +135 -0
  348. package/dist/services/code/auto-compact-attempt.d.ts +46 -0
  349. package/dist/services/code/auto-compact-attempt.js +88 -0
  350. package/dist/services/code/auto-compact-decision.d.ts +74 -0
  351. package/dist/services/code/auto-compact-decision.js +149 -0
  352. package/dist/services/code/auto-compact-dispatch-gate.d.ts +36 -0
  353. package/dist/services/code/auto-compact-dispatch-gate.js +86 -0
  354. package/dist/services/code/auto-compact-envelopes.d.ts +33 -0
  355. package/dist/services/code/auto-compact-envelopes.js +134 -0
  356. package/dist/services/code/auto-compact-history.d.ts +46 -0
  357. package/dist/services/code/auto-compact-history.js +17 -0
  358. package/dist/services/code/auto-compact-orchestrator.d.ts +11 -240
  359. package/dist/services/code/auto-compact-orchestrator.js +165 -686
  360. package/dist/services/code/auto-compact-run-types.d.ts +123 -0
  361. package/dist/services/code/auto-compact-run-types.js +1 -0
  362. package/dist/services/code/emit-handoff.d.ts +35 -1
  363. package/dist/services/code/emit-handoff.js +128 -7
  364. package/dist/services/code/step-08-gate.d.ts +28 -19
  365. package/dist/services/code/step-08-gate.js +92 -35
  366. package/dist/services/config/config-coercion.d.ts +7 -0
  367. package/dist/services/config/config-coercion.js +156 -0
  368. package/dist/services/config/config-file-io.d.ts +11 -0
  369. package/dist/services/config/config-file-io.js +61 -0
  370. package/dist/services/config/config-get.d.ts +2 -0
  371. package/dist/services/config/config-get.js +36 -0
  372. package/dist/services/config/config-global-loader.d.ts +15 -0
  373. package/dist/services/config/config-global-loader.js +111 -0
  374. package/dist/services/config/config-nested-path.d.ts +3 -0
  375. package/dist/services/config/config-nested-path.js +53 -0
  376. package/dist/services/config/config-primitives.d.ts +16 -0
  377. package/dist/services/config/config-primitives.js +24 -0
  378. package/dist/services/config/config-service.d.ts +9 -33
  379. package/dist/services/config/config-service.js +16 -665
  380. package/dist/services/config/config-validation.d.ts +19 -0
  381. package/dist/services/config/config-validation.js +152 -0
  382. package/dist/services/config/config-workspace.d.ts +10 -0
  383. package/dist/services/config/config-workspace.js +158 -0
  384. package/dist/services/skills/hooks-settings-deny-list.d.ts +61 -0
  385. package/dist/services/skills/hooks-settings-deny-list.js +173 -0
  386. package/dist/services/skills/hooks-settings-envelopes.d.ts +20 -0
  387. package/dist/services/skills/hooks-settings-envelopes.js +79 -0
  388. package/dist/services/skills/hooks-settings-file-shape.d.ts +43 -0
  389. package/dist/services/skills/hooks-settings-file-shape.js +207 -0
  390. package/dist/services/skills/hooks-settings-paths.d.ts +34 -0
  391. package/dist/services/skills/hooks-settings-paths.js +75 -0
  392. package/dist/services/skills/hooks-settings-read-installed.d.ts +39 -0
  393. package/dist/services/skills/hooks-settings-read-installed.js +60 -0
  394. package/dist/services/skills/hooks-settings-service.d.ts +12 -212
  395. package/dist/services/skills/hooks-settings-service.js +71 -657
  396. package/dist/services/skills/hooks-settings-types.d.ts +139 -0
  397. package/dist/services/skills/hooks-settings-types.js +1 -0
  398. package/dist/services/workspace/claude-settings-template-merge.d.ts +89 -0
  399. package/dist/services/workspace/claude-settings-template-merge.js +243 -0
  400. package/dist/services/workspace/claude-settings-template.d.ts +29 -87
  401. package/dist/services/workspace/claude-settings-template.js +81 -236
  402. package/package.json +5 -5
@@ -0,0 +1,121 @@
1
+ // src/cli/commands/codegraph-status-integrity.ts
2
+ //
3
+ // The two integrity axes `peaks codegraph status` evaluates, and the human
4
+ // reading of them. Split out of `codegraph-status-command.ts`; every
5
+ // applicability predicate, degradation rule and printed line is unchanged.
6
+ import { inspectCodegraphExcludeIntegrity, isCodegraphExcludeConfigPresent, renderCodegraphExcludeIntegrityLines } from '../../services/codegraph/codegraph-exclude-integrity.js';
7
+ import { inspectCodegraphIndexIntegrity, isCodegraphIndexStrictMode, renderCodegraphIndexIntegrityLines, resolveCodegraphIndexIntegrityVerdict } from '../../services/codegraph/codegraph-index-integrity.js';
8
+ import { isCodegraphInitialized } from '../../services/codegraph/codegraph-service.js';
9
+ import { readCodegraphProjectInputs } from '../../services/codegraph/codegraph-exclude-reconciler.js';
10
+ import { getErrorMessage } from '../cli-helpers.js';
11
+ /**
12
+ * Read both axes for a project root.
13
+ *
14
+ * R12-1: the two axes have DIFFERENT applicability predicates, and folding
15
+ * them into the config's alone is how a db-present / config-absent project
16
+ * came to exit 0 in SILENCE — under `PEAKS_CODEGRAPH_INDEX_STRICT=1` too.
17
+ * "Could not evaluate" is a verdict; it may not be spelled the same way as
18
+ * "verified clean" merely because the read happened to be gated out.
19
+ *
20
+ * - exclude axis: applicable iff `.codegraph/config.json` exists. The
21
+ * config IS the subject of that axis, so with no config there is no
22
+ * exclusion list in play — `not-applicable`, silent, as before.
23
+ * - index axis: applicable iff `.codegraph/codegraph.db` exists — the
24
+ * SAME predicate the doctor's `defaultProbe` uses
25
+ * (`isCodegraphInitialized` in
26
+ * `doctor-service/checks/codegraph-index-integrity.ts`), so the two
27
+ * consumers now agree about when the axis is evaluable at all. The
28
+ * index is the subject here and the config is only an INPUT it reads,
29
+ * so a missing config is "could not evaluate" (exit 76, `[FAIL]`),
30
+ * not "nothing to evaluate".
31
+ *
32
+ * The user's constraint holds either way: an absent config is LEGITIMATE
33
+ * for a project that never ran `peaks codegraph init` — with no db BOTH
34
+ * predicates are false and the command stays silent exactly as before.
35
+ *
36
+ * The two axes are evaluated INDEPENDENTLY: an unreadable index must not
37
+ * blind the exclude verdict, and a malformed exclude list must not hide a
38
+ * stale index. Each failure degrades to its own warning.
39
+ */
40
+ export function readStatusAxes(projectRoot) {
41
+ let integrity = null;
42
+ let integrityWarning = null;
43
+ let indexIntegrity = null;
44
+ let indexIntegrityWarning = null;
45
+ const configPresent = isCodegraphExcludeConfigPresent(projectRoot);
46
+ const indexPresent = isCodegraphInitialized(projectRoot);
47
+ if (configPresent || indexPresent) {
48
+ // Perf audit F1: both axes need the SAME tracked-file list and the SAME
49
+ // config, and reading them per-axis spawned `git ls-files` twice per
50
+ // command and re-ran the identical 32-glob `include` filter. Read once
51
+ // and hand the values to both inspectors through their deps seam.
52
+ let sharedInputs = null;
53
+ try {
54
+ sharedInputs = readCodegraphProjectInputs(projectRoot);
55
+ }
56
+ catch (error) {
57
+ // One read, two blind axes — they consume exactly these two inputs,
58
+ // so a failure here blinds both. Report it on both, rather than
59
+ // letting the second axis re-run the same failing read to find out.
60
+ // Each axis claims the failure only where it was applicable at all:
61
+ // an unreadable CONFIG is not an exclude-axis finding on a project
62
+ // that has no config by design.
63
+ if (configPresent)
64
+ integrityWarning = getErrorMessage(error);
65
+ if (indexPresent)
66
+ indexIntegrityWarning = getErrorMessage(error);
67
+ }
68
+ if (sharedInputs !== null) {
69
+ if (configPresent) {
70
+ try {
71
+ integrity = inspectCodegraphExcludeIntegrity(projectRoot, sharedInputs);
72
+ }
73
+ catch (error) {
74
+ integrityWarning = getErrorMessage(error);
75
+ }
76
+ }
77
+ // The index axis needs an index. A config without `codegraph.db` is a
78
+ // pre-init / dangling state, not a defect: there are no rows to be
79
+ // stale and nothing `include` withheld from a graph that does not exist.
80
+ if (indexPresent) {
81
+ try {
82
+ indexIntegrity = inspectCodegraphIndexIntegrity(projectRoot, sharedInputs);
83
+ }
84
+ catch (error) {
85
+ indexIntegrityWarning = getErrorMessage(error);
86
+ }
87
+ }
88
+ }
89
+ }
90
+ return {
91
+ integrity,
92
+ integrityWarning,
93
+ indexIntegrity,
94
+ indexIntegrityWarning,
95
+ indexVerdict: resolveCodegraphIndexIntegrityVerdict(indexIntegrity, indexIntegrityWarning),
96
+ strict: isCodegraphIndexStrictMode()
97
+ };
98
+ }
99
+ /** The human-readable axis report, printed only by the non-JSON branch. */
100
+ export function emitIntegrityText(io, axes) {
101
+ if (axes.integrityWarning !== null) {
102
+ io.stdout(`[WARN] codegraph exclude integrity not evaluated: ${axes.integrityWarning}`);
103
+ }
104
+ else if (axes.integrity !== null) {
105
+ for (const line of renderCodegraphExcludeIntegrityLines(axes.integrity)) {
106
+ io.stdout(line);
107
+ }
108
+ }
109
+ if (axes.indexVerdict === 'not-evaluated') {
110
+ // `[FAIL]`, in every mode, because the command exits non-zero in
111
+ // every mode: the axis was attempted and failed, so this is not a
112
+ // statement about the index. Distinct wording from the gap line so
113
+ // the two can never be confused.
114
+ io.stdout(`[FAIL] codegraph index integrity could not be evaluated (the index was NOT measured): ${axes.indexIntegrityWarning ?? 'unknown cause'}`);
115
+ }
116
+ else if (axes.indexIntegrity !== null) {
117
+ for (const line of renderCodegraphIndexIntegrityLines(axes.indexIntegrity, axes.strict)) {
118
+ io.stdout(line);
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,5 @@
1
+ import { type ProgramIO } from '../cli-helpers.js';
2
+ import { type CommonCodegraphOptions } from './codegraph-command-runtime.js';
3
+ import type { CodegraphStatusAxes } from './codegraph-status-integrity.js';
4
+ /** Returns true when upstream failed (the caller must stop before the gates). */
5
+ export declare function runCodegraphStatusJson(io: ProgramIO, options: CommonCodegraphOptions, axes: CodegraphStatusAxes): Promise<boolean>;
@@ -0,0 +1,127 @@
1
+ // src/cli/commands/codegraph-status-json.ts
2
+ //
3
+ // The `--peaks-json` machine report for `peaks codegraph status`. Split out of
4
+ // `codegraph-status-command.ts`; every envelope code, message, `data` field,
5
+ // next-action string and exit-code rule is unchanged.
6
+ //
7
+ // EXIT-CODE PRECEDENCE (decided here, mirrored on the human path, pinned
8
+ // by tests on BOTH axes):
9
+ //
10
+ // 1. upstream failed → upstream's exit code. Ranked FIRST because
11
+ // every gate's remedy assumes upstream can run, and because the
12
+ // gate's own branches would otherwise MASK a real command failure:
13
+ // under the advisory default a gap exits 0, so a "gate first" order
14
+ // would turn "upstream failed + gap" into exit 0 — the gate hiding a
15
+ // failure. The gate verdicts stay in `data` verbatim, so ranking
16
+ // them lower hides nothing.
17
+ // 2. exclude gap → 74 (`CODEGRAPH_INDEX_INCOMPLETE`).
18
+ // 3. index not evaluated → 76 (`CODEGRAPH_INDEX_NOT_EVALUATED`): the
19
+ // axis was attempted and failed, which is NOT "verified clean".
20
+ // 4. index gap → 75 (`CODEGRAPH_INDEX_GAP`) in strict mode,
21
+ // 0 in the advisory default.
22
+ //
23
+ // The envelope still reports the finding in case 4 (`ok:false`, the same
24
+ // `code`, plus `indexIntegritySeverity: 'warning'`) — the policy governs
25
+ // the EXIT CODE, not whether the finding is visible. This mirrors the
26
+ // doctor's established convention: `ok:false` + `severity:'warning'`
27
+ // surfaces the finding without escalating the exit code.
28
+ import { fail, ok } from 'peaks-loop-shared/result';
29
+ import { CODEGRAPH_INDEX_INTEGRITY_EXIT_CODE, CODEGRAPH_INDEX_STRICT_ENV_VAR, CODEGRAPH_REPAIR_INDEX_COMMAND } from '../../services/codegraph/codegraph-index-integrity.js';
30
+ import { createCodegraphInvocation, executeCodegraphInvocation } from '../../services/codegraph/codegraph-service.js';
31
+ import { printResult, redactSensitiveErrorMessage } from '../cli-helpers.js';
32
+ import { localizeUpstreamCodegraphText, printCodegraphFailure } from './codegraph-command-runtime.js';
33
+ /**
34
+ * `--peaks-json` machine report for `status`. Carries the upstream
35
+ * result AND the peaks-loop integrity verdict as one JSON document so a
36
+ * CI job can gate on `data.integrity.gap` / `data.integrity.rulesToRemove`
37
+ * without scraping human text.
38
+ */
39
+ function buildStatusReport(result, axes) {
40
+ const upstream = {
41
+ exitCode: result.exitCode,
42
+ stdout: localizeUpstreamCodegraphText(result.stdout).trimEnd(),
43
+ stderr: redactSensitiveErrorMessage(localizeUpstreamCodegraphText(result.stderr)).trimEnd()
44
+ };
45
+ return {
46
+ upstream,
47
+ data: {
48
+ upstream,
49
+ integrity: axes.integrity,
50
+ integrityWarning: axes.integrityWarning,
51
+ indexIntegrity: axes.indexIntegrity,
52
+ indexIntegrityWarning: axes.indexIntegrityWarning,
53
+ indexIntegrityVerdict: axes.indexVerdict,
54
+ // Only meaningful where there IS a finding: a `clean` or `not-applicable`
55
+ // axis has no severity, and reporting `'warning'` there would read as
56
+ // "something was wrong but advisory".
57
+ indexIntegritySeverity: axes.indexVerdict === 'gap' ? (axes.strict ? 'error' : 'warning') : null
58
+ }
59
+ };
60
+ }
61
+ /** The refusal an index gap produces, in strict or advisory wording. */
62
+ function indexGapVerdict(axes) {
63
+ const includeGap = axes.indexIntegrity?.includeGap.length ?? 0;
64
+ const deadRows = axes.indexIntegrity?.deadRows.length ?? 0;
65
+ return {
66
+ message: `codegraph index does not cover the repository: ${includeGap} extractor-supported tracked file(s) are not admitted by the config's include globs, and ${deadRows} index row(s) point at files that no longer exist.`,
67
+ nextActions: axes.strict
68
+ ? [
69
+ 'The index must admit every extractor-supported tracked file and hold no row for a path that is gone.',
70
+ `Run \`${CODEGRAPH_REPAIR_INDEX_COMMAND}\` to drop the blocking exclude rules and rebuild the index without the stale rows.`
71
+ ]
72
+ : [
73
+ 'Advisory: this gap is reported as a warning and the command exits 0.',
74
+ `Set ${CODEGRAPH_INDEX_STRICT_ENV_VAR}=1 to make it blocking (exit ${CODEGRAPH_INDEX_INTEGRITY_EXIT_CODE}).`,
75
+ `Run \`${CODEGRAPH_REPAIR_INDEX_COMMAND}\` to drop the blocking exclude rules and rebuild the index without the stale rows.`
76
+ ]
77
+ };
78
+ }
79
+ /** Upstream failed: its exit code outranks both gates, so it is ranked first. */
80
+ function emitUpstreamFailure(io, result, report) {
81
+ const { stdout, stderr } = report.upstream;
82
+ printResult(io, fail('codegraph.status', 'CODEGRAPH_COMMAND_FAILED', redactSensitiveErrorMessage(stderr || stdout || `codegraph exited with code ${String(result.exitCode)}`), report.data, ['Check the codegraph project path before retrying']), true);
83
+ }
84
+ /** The gate verdicts, in precedence order, when upstream itself succeeded. */
85
+ function emitGateVerdict(io, axes, data) {
86
+ const integrity = axes.integrity;
87
+ if (integrity?.gap === true) {
88
+ printResult(io, fail('codegraph.status', 'CODEGRAPH_INDEX_INCOMPLETE', `codegraph index is incomplete: ${integrity.excludedTrackedCount} of ${integrity.trackedSourceCount} tracked source files are excluded by ${integrity.rulesToRemove.length} rule(s).`, data, [
89
+ 'Run `peaks codegraph repair-exclude --project <root>` to drop the offending rules and rebuild the index.'
90
+ ]), true);
91
+ return;
92
+ }
93
+ if (axes.indexVerdict === 'not-evaluated') {
94
+ // Distinct from the `ok` branch below on purpose: this axis produced
95
+ // NO verdict, and the envelope must not read as "index verified".
96
+ printResult(io, fail('codegraph.status', 'CODEGRAPH_INDEX_NOT_EVALUATED', `codegraph index integrity could not be evaluated: ${axes.indexIntegrityWarning ?? 'unknown cause'}`, data, [
97
+ 'The index was NOT measured — this is not a statement that the index is correct.',
98
+ 'Re-run once the cause above is resolved.'
99
+ ]), true);
100
+ return;
101
+ }
102
+ if (axes.indexVerdict === 'gap') {
103
+ const verdict = indexGapVerdict(axes);
104
+ printResult(io, fail('codegraph.status', 'CODEGRAPH_INDEX_GAP', verdict.message, data, verdict.nextActions), true);
105
+ return;
106
+ }
107
+ printResult(io, ok('codegraph.status', data), true);
108
+ }
109
+ /** Returns true when upstream failed (the caller must stop before the gates). */
110
+ export async function runCodegraphStatusJson(io, options, axes) {
111
+ let result;
112
+ try {
113
+ result = await executeCodegraphInvocation(createCodegraphInvocation({ subcommand: 'status', project: options.project }));
114
+ }
115
+ catch (error) {
116
+ printCodegraphFailure(io, 'codegraph.status', error, true);
117
+ return true;
118
+ }
119
+ const report = buildStatusReport(result, axes);
120
+ if (result.exitCode !== null && result.exitCode !== 0) {
121
+ emitUpstreamFailure(io, result, report);
122
+ process.exitCode = result.exitCode ?? 1;
123
+ return true;
124
+ }
125
+ emitGateVerdict(io, axes, report.data);
126
+ return false;
127
+ }
@@ -0,0 +1,60 @@
1
+ export declare const DEFAULT_DOCKER_IMAGE = "node:22-slim";
2
+ /**
3
+ * runtime adapter. The container CLI supports both docker and
4
+ * podman as the underlying runtime. The auto-detect order is:
5
+ * 1. `--runtime docker|podman` if explicit
6
+ * 2. docker (most common, ships with Docker Desktop on
7
+ * macOS/Windows, docker.io on Linux)
8
+ * 3. podman (RHEL/Fedora default, runs rootless by default,
9
+ * same CLI surface as docker)
10
+ * Each runtime has the same spawn/release shape; the
11
+ * difference is the binary name (`docker` vs `podman`). The
12
+ * `--cidfile` flag is supported by both.
13
+ */
14
+ export type ContainerRuntime = 'docker' | 'podman';
15
+ /** A runtime that answered `--version`, or the reason none did. */
16
+ export type ContainerRuntimeProbe = {
17
+ ok: true;
18
+ runtime: ContainerRuntime;
19
+ binary: string;
20
+ } | {
21
+ ok: false;
22
+ stderr: string;
23
+ hint: string;
24
+ };
25
+ export declare function detectContainerRuntime(explicit: ContainerRuntime | undefined): ContainerRuntimeProbe;
26
+ export type ContainerOptions = {
27
+ session?: string;
28
+ project?: string;
29
+ json?: boolean;
30
+ };
31
+ export type SpawnOptions = ContainerOptions & {
32
+ rid: string;
33
+ role: string;
34
+ purpose: string;
35
+ image?: string;
36
+ ttl?: string;
37
+ mount?: string;
38
+ /** Part 43: explicit runtime selector (docker | podman). */
39
+ runtime?: string;
40
+ };
41
+ export type ReleaseOptions = ContainerOptions & {
42
+ leaseId: string;
43
+ };
44
+ export declare function joinPathSession(projectRoot: string, sessionId: string): string;
45
+ /**
46
+ * Resolve the project root and session id every container verb works against.
47
+ * The sid falls back through `PEAKS_SESSION_ID` and the canonical binding
48
+ * before the `unknown-sid` sentinel.
49
+ */
50
+ export declare function resolveContainerTarget(options: ContainerOptions): {
51
+ projectRoot: string;
52
+ sessionId: string;
53
+ };
54
+ export declare function checkDockerAvailable(): {
55
+ ok: true;
56
+ version: string;
57
+ } | {
58
+ ok: false;
59
+ stderr: string;
60
+ };
@@ -0,0 +1,52 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { findProjectRoot } from '../../services/config/config-safety.js';
3
+ import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
4
+ export const DEFAULT_DOCKER_IMAGE = 'node:22-slim';
5
+ export function detectContainerRuntime(explicit) {
6
+ const tryOrder = explicit ? [explicit] : ['docker', 'podman'];
7
+ for (const r of tryOrder) {
8
+ try {
9
+ const version = execSync(`${r} --version`, {
10
+ stdio: ['ignore', 'pipe', 'pipe'],
11
+ encoding: 'utf8',
12
+ windowsHide: true
13
+ }).trim();
14
+ return { ok: true, runtime: r, binary: `${r} (${version.split('\n')[0] ?? ''})` };
15
+ }
16
+ catch {
17
+ /* try next */
18
+ }
19
+ }
20
+ return {
21
+ ok: false,
22
+ stderr: explicit
23
+ ? `explicit --runtime ${explicit} not on PATH`
24
+ : 'neither docker nor podman is on PATH',
25
+ hint: explicit
26
+ ? `Install ${explicit} or pass a different --runtime.`
27
+ : 'Install docker (Docker Desktop on macOS / Windows) or podman (RHEL / Fedora).'
28
+ };
29
+ }
30
+ export function joinPathSession(projectRoot, sessionId) {
31
+ return `${projectRoot.replace(/[\\/]+$/, '')}/.peaks/_runtime/${sessionId}`;
32
+ }
33
+ /**
34
+ * Resolve the project root and session id every container verb works against.
35
+ * The sid falls back through `PEAKS_SESSION_ID` and the canonical binding
36
+ * before the `unknown-sid` sentinel.
37
+ */
38
+ export function resolveContainerTarget(options) {
39
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
40
+ const sessionId = options.session ??
41
+ process.env.PEAKS_SESSION_ID ??
42
+ getCurrentSessionId(projectRoot) ??
43
+ 'unknown-sid';
44
+ return { projectRoot, sessionId };
45
+ }
46
+ export function checkDockerAvailable() {
47
+ // Part 43: superseded by detectContainerRuntime above; this
48
+ // function is preserved for callers that imported it. The
49
+ // container-commands.ts action handlers all use
50
+ // detectContainerRuntime directly.
51
+ return { ok: false, stderr: 'deprecated — use detectContainerRuntime' };
52
+ }
@@ -23,5 +23,5 @@
23
23
  * follow-up rid.
24
24
  */
25
25
  import type { Command } from 'commander';
26
- import { type ProgramIO } from '../cli-helpers.js';
26
+ import type { ProgramIO } from '../cli-helpers.js';
27
27
  export declare function registerContainerCommand(program: Command, io: ProgramIO): void;
@@ -22,224 +22,12 @@
22
22
  * allowing docker-related tool calls. The gate bridge is a
23
23
  * follow-up rid.
24
24
  */
25
- import { execSync } from 'node:child_process';
26
- import { existsSync, readFileSync } from 'node:fs';
27
- import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
28
- import { addJsonOption, printResult } from '../cli-helpers.js';
29
- import { findProjectRoot } from '../../services/config/config-safety.js';
30
- import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
31
- import { atomicWriteJson } from '../../services/ide/shared/atomic-json.js';
32
- import { normalizePath } from '../../shared/path-utils.js';
33
- import { containerLeaseFilePath, deserializeContainerLease, finalizeContainerLease, generateContainerLeaseId, markContainerReleased, ttlForContainerRole } from '../../services/container/container-lease.js';
34
- const DEFAULT_DOCKER_IMAGE = 'node:22-slim';
35
- function detectContainerRuntime(explicit) {
36
- const tryOrder = explicit ? [explicit] : ['docker', 'podman'];
37
- for (const r of tryOrder) {
38
- try {
39
- const version = execSync(`${r} --version`, {
40
- stdio: ['ignore', 'pipe', 'pipe'],
41
- encoding: 'utf8',
42
- windowsHide: true
43
- }).trim();
44
- return { ok: true, runtime: r, binary: `${r} (${version.split('\n')[0] ?? ''})` };
45
- }
46
- catch {
47
- /* try next */
48
- }
49
- }
50
- return {
51
- ok: false,
52
- stderr: explicit
53
- ? `explicit --runtime ${explicit} not on PATH`
54
- : 'neither docker nor podman is on PATH',
55
- hint: explicit
56
- ? `Install ${explicit} or pass a different --runtime.`
57
- : 'Install docker (Docker Desktop on macOS / Windows) or podman (RHEL / Fedora).'
58
- };
59
- }
60
- function joinPathSession(projectRoot, sessionId) {
61
- return `${projectRoot.replace(/[\\/]+$/, '')}/.peaks/_runtime/${sessionId}`;
62
- }
63
- function checkDockerAvailable() {
64
- // Part 43: superseded by detectContainerRuntime above; this
65
- // function is preserved for callers that imported it. The
66
- // container-commands.ts action handlers all use
67
- // detectContainerRuntime directly.
68
- return { ok: false, stderr: 'deprecated — use detectContainerRuntime' };
69
- }
25
+ import { registerContainerReleaseCommand } from './container-release-command.js';
26
+ import { registerContainerSpawnCommand } from './container-spawn-command.js';
70
27
  export function registerContainerCommand(program, io) {
71
28
  const cmd = program
72
29
  .command('container')
73
30
  .description('L4 container isolation: spawn/release container leases (Part 12; pairs with --isolation container on dispatch).');
74
- addJsonOption(cmd
75
- .command('spawn')
76
- .description('Spawn a container via `docker run` and write a container lease. ' +
77
- 'The lease is the source of truth for the L4 PreToolUse gate (Part 12 follow-up). ' +
78
- 'Default TTL is role-aware (rd=30m / qa=15m / ui=1h); pass --ttl <ms> to override. ' +
79
- 'Default image is `node:22-slim`; pass --image <name> to override.')
80
- .requiredOption('--rid <rid>', 'peaks request id the lease is associated with')
81
- .requiredOption('--role <role>', 'sub-agent role (rd | qa | ui | sc | prd | general-purpose)')
82
- .requiredOption('--purpose <text>', 'why this container was spawned (audit log)')
83
- .option('--image <name>', `container image (default ${DEFAULT_DOCKER_IMAGE})`)
84
- .option('--ttl <ms>', 'time-to-live in ms (default role-aware; override with positive number)')
85
- .option('--mount <path>', 'host path to mount as the container working dir (default: <projectRoot>)')
86
- .option('--session <sid>', 'override session id')
87
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
88
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
89
- const sessionId = options.session ??
90
- process.env.PEAKS_SESSION_ID ??
91
- getCurrentSessionId(projectRoot) ??
92
- 'unknown-sid';
93
- try {
94
- const explicitRuntime = (() => {
95
- if (options.runtime === 'docker')
96
- return 'docker';
97
- if (options.runtime === 'podman')
98
- return 'podman';
99
- return undefined;
100
- })();
101
- const runtime = detectContainerRuntime(explicitRuntime);
102
- if (!runtime.ok) {
103
- printResult(io, fail('container.spawn', 'CONTAINER_RUNTIME_UNAVAILABLE', `${runtime.stderr}: ${runtime.hint}`, { rid: options.rid, role: options.role, sessionId }, [
104
- 'Install docker (Docker Desktop on macOS / Windows) or podman (RHEL / Fedora).',
105
- 'On Windows, ensure WSL2 backend is enabled and the daemon is running.',
106
- 'Pass --runtime docker|podman to force a specific runtime.'
107
- ]), options.json);
108
- process.exitCode = 1;
109
- return;
110
- }
111
- const leaseId = generateContainerLeaseId();
112
- const now = Date.now();
113
- const ttlMs = options.ttl === undefined
114
- ? ttlForContainerRole(options.role)
115
- : Number.parseInt(options.ttl, 10);
116
- if (!Number.isInteger(ttlMs) || ttlMs <= 0) {
117
- printResult(io, fail('container.spawn', 'INVALID_TTL', '--ttl must be a positive integer (ms)', { ttl: options.ttl }, ['Re-run with --ttl 1800000 (30 min) or omit to use role default.']), options.json);
118
- process.exitCode = 1;
119
- return;
120
- }
121
- const image = options.image ?? DEFAULT_DOCKER_IMAGE;
122
- const mount = options.mount ?? projectRoot;
123
- // `docker run --rm -d` so the container is detached and
124
- // auto-removed when stopped; --cidfile writes the
125
- // container id to a file we can read back. The
126
- // `--label peaks.leaseId=<id>` lets `peaks container
127
- // list` / `peaks container gc` find orphans by label
128
- // when the lease file is missing.
129
- const cidFile = `${normalizePath(joinPathSession(projectRoot, sessionId))}/.${runtime.runtime}-cid-${leaseId}`;
130
- try {
131
- execSync(`${runtime.runtime} run --rm -d --cidfile "${cidFile}" --label "peaks.leaseId=${leaseId}" --label "peaks.rid=${options.rid}" -v "${mount}:/work" -w /work ${image} sleep infinity`, { cwd: projectRoot, stdio: 'pipe', encoding: 'utf8', windowsHide: true });
132
- }
133
- catch (err) {
134
- printResult(io, fail('container.spawn', 'DOCKER_RUN_FAILED', getErrorMessage(err), { rid: options.rid, image, runtime: runtime.runtime, sessionId }, [
135
- 'Verify the image name is reachable on the configured registry.',
136
- 'Verify the host path is mounted correctly (Windows: the path must be visible to WSL2).',
137
- `Run \`${runtime.runtime} ps -a\` to inspect any leftover containers with the peaks.leaseId label.`
138
- ]), options.json);
139
- process.exitCode = 1;
140
- return;
141
- }
142
- const containerId = readFileSync(cidFile, 'utf8').trim();
143
- const lease = finalizeContainerLease({
144
- leaseId,
145
- rid: options.rid,
146
- role: options.role,
147
- path: mount,
148
- image,
149
- containerId,
150
- createdAt: now,
151
- expiresAt: now + ttlMs,
152
- purpose: options.purpose
153
- });
154
- atomicWriteJson(containerLeaseFilePath(joinPathSession(projectRoot, sessionId), leaseId), lease);
155
- printResult(io, ok('container.spawn', {
156
- lease,
157
- sessionId,
158
- projectRoot,
159
- runtime: runtime.runtime,
160
- runtimeVersion: runtime.binary,
161
- nextActions: [
162
- `Container id: ${containerId}`,
163
- `Image: ${image}`,
164
- `Lease expires at: ${new Date(lease.expiresAt).toISOString()}`,
165
- 'Run `peaks container release --lease-id <id>` when done'
166
- ]
167
- }, [], []), options.json);
168
- }
169
- catch (err) {
170
- printResult(io, fail('container.spawn', 'SPAWN_FAILED', getErrorMessage(err), { rid: options.rid, sessionId }, [
171
- 'See error message; if the lease was not written, retry after fixing the underlying issue.'
172
- ]), options.json);
173
- process.exitCode = 1;
174
- }
175
- });
176
- addJsonOption(cmd
177
- .command('release')
178
- .description('Transition a container lease to released and run `docker rm --force`. Idempotent on already-released leases.')
179
- .requiredOption('--lease-id <id>', 'lease id returned by `peaks container spawn`')
180
- .option('--session <sid>', 'override session id')
181
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
182
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
183
- const sessionId = options.session ??
184
- process.env.PEAKS_SESSION_ID ??
185
- getCurrentSessionId(projectRoot) ??
186
- 'unknown-sid';
187
- try {
188
- const file = containerLeaseFilePath(joinPathSession(projectRoot, sessionId), options.leaseId);
189
- if (!existsSync(file)) {
190
- printResult(io, fail('container.release', 'LEASE_NOT_FOUND', `no lease on disk at ${file}`, { leaseId: options.leaseId, file }, [
191
- 'Run `peaks container list` to inspect active leases.',
192
- 'For a never-spawned lease, this is a no-op — no further action needed.'
193
- ]), options.json);
194
- process.exitCode = 1;
195
- return;
196
- }
197
- let lease;
198
- try {
199
- lease = deserializeContainerLease(readFileSync(file, 'utf8'));
200
- }
201
- catch (err) {
202
- printResult(io, fail('container.release', 'LEASE_FILE_INVALID', getErrorMessage(err), { leaseId: options.leaseId, file }, [
203
- 'Delete the malformed lease file manually and re-issue spawn.',
204
- 'For security, release never fails open on a malformed lease.'
205
- ]), options.json);
206
- process.exitCode = 1;
207
- return;
208
- }
209
- if (lease.status === 'released') {
210
- printResult(io, ok('container.release', { lease, sessionId, projectRoot, alreadyReleased: true }, [], [`Lease ${lease.leaseId} already released; nothing to do.`]), options.json);
211
- return;
212
- }
213
- let dockerRmFailed = false;
214
- try {
215
- const releaseRuntime = detectContainerRuntime(undefined);
216
- const runtimeCmd = releaseRuntime.ok ? releaseRuntime.runtime : 'docker';
217
- execSync(`${runtimeCmd} rm --force "${lease.containerId}"`, {
218
- cwd: projectRoot,
219
- stdio: 'pipe',
220
- encoding: 'utf8',
221
- windowsHide: true
222
- });
223
- }
224
- catch {
225
- dockerRmFailed = true;
226
- }
227
- const released = markContainerReleased(lease);
228
- atomicWriteJson(file, released);
229
- printResult(io, ok('container.release', { lease: released, sessionId, projectRoot, dockerRmFailed }, dockerRmFailed
230
- ? [
231
- 'docker rm failed (likely the container was already removed); lease marked released.'
232
- ]
233
- : [], [
234
- `Lease ${lease.leaseId} marked released.`,
235
- dockerRmFailed
236
- ? 'Manual `docker ps -a` + `docker rm` may be needed.'
237
- : `Container ${lease.containerId} removed.`
238
- ]), options.json);
239
- }
240
- catch (err) {
241
- printResult(io, fail('container.release', 'RELEASE_FAILED', getErrorMessage(err), { leaseId: options.leaseId, sessionId }, ['Verify the lease id and re-run.', 'If the lease was never spawned, no-op.']), options.json);
242
- process.exitCode = 1;
243
- }
244
- });
31
+ registerContainerSpawnCommand(cmd, io);
32
+ registerContainerReleaseCommand(cmd, io);
245
33
  }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function registerContainerReleaseCommand(cmd: Command, io: ProgramIO): void;