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
@@ -1,5 +1,4 @@
1
1
  /**
2
- *
3
2
  * Companion CLI to Part 14 (peaks cron init/list/run). The
4
3
  * scheduler is a long-running background daemon that wakes up
5
4
  * once per minute, reads `.peaks/cron/schedule.json`, and runs
@@ -25,198 +24,48 @@
25
24
  * the scheduler to write its own pid. Or just run from
26
25
  * `nohup peaks-cron-scheduler start &` if you don't need
27
26
  * restart-on-crash.
27
+ *
28
+ * This file owns `registerCronSchedulerCommand`, `runSchedulerLoop` and the
29
+ * standalone entry shim the `bin/peaks-cron-scheduler.js` script loads; the
30
+ * four verb bodies live beside it, over the pid-file vocabulary in
31
+ * `cron-scheduler-shared.ts`.
28
32
  */
29
- import { spawn } from 'node:child_process';
30
- import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
31
- import { dirname, join, resolve } from 'node:path';
32
- import { fileURLToPath } from 'node:url';
33
- import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
34
- import { addJsonOption, printResult } from '../cli-helpers.js';
33
+ import { getErrorMessage } from 'peaks-loop-shared/result';
35
34
  import { findProjectRoot } from '../../services/config/config-safety.js';
36
- import { readSchedule, listDueTasks, runTask } from './cron-commands.js';
35
+ import { listDueTasks, runTask } from './cron-commands.js';
37
36
  import { persistLastRunAt } from './cron-scheduler-persist.js';
38
- const SCHEDULER_TICK_MS = 60_000; // 1 minute
39
- const PID_FILENAME = 'scheduler.pid';
40
- function schedulerPidPath(projectRoot) {
41
- return join(projectRoot, '.peaks', 'cron', PID_FILENAME);
42
- }
43
- function readSchedulerPid(projectRoot) {
44
- const p = schedulerPidPath(projectRoot);
45
- if (!existsSync(p))
46
- return null;
47
- const raw = readFileSync(p, 'utf8').trim();
48
- const pid = Number.parseInt(raw, 10);
49
- if (!Number.isFinite(pid) || pid <= 0)
50
- return null;
51
- return pid;
52
- }
53
- function isPidAlive(pid) {
54
- try {
55
- // `process.kill(pid, 0)` does not actually kill; it just
56
- // checks if the process exists. ESRCH means no such pid;
57
- // EPERM means it exists but we don't have permission to
58
- // signal it (still alive).
59
- process.kill(pid, 0);
60
- return true;
61
- }
62
- catch (err) {
63
- const code = err.code;
64
- return code === 'EPERM';
65
- }
66
- }
67
- function findSchedulerEntryPoint() {
68
- // The peaks-cron-scheduler.js entry shim lives in bin/ (not
69
- // dist/, so the pnpm build does not overwrite it). It forwards
70
- // to dist/cli/commands/cron-scheduler-commands.js with
71
- // PEAKS_CRON_SCHEDULER_DAEMON=1 set; the CLI detects the env
72
- // and runs runSchedulerLoop directly.
73
- const here = dirname(fileURLToPath(import.meta.url));
74
- // dist/cli/commands/cron-scheduler-commands.js → bin/peaks-cron-scheduler.js
75
- return resolve(here, '..', '..', '..', 'bin', 'peaks-cron-scheduler.js');
76
- }
37
+ import { SCHEDULER_TICK_MS } from './cron-scheduler-shared.js';
38
+ import { registerCronSchedulerStartCommand } from './cron-scheduler-start-command.js';
39
+ import { registerCronSchedulerStopCommand } from './cron-scheduler-stop-command.js';
40
+ import { registerCronSchedulerStatusCommand } from './cron-scheduler-status-command.js';
41
+ import { registerCronSchedulerRunOnceCommand } from './cron-scheduler-run-once-command.js';
77
42
  export function registerCronSchedulerCommand(program, io) {
78
43
  const cmd = program
79
44
  .command('cron-scheduler')
80
45
  .description('Long-running background scheduler for peaks cron tasks (Part 15).');
81
- addJsonOption(cmd
82
- .command('start')
83
- .description('Spawn the scheduler as a detached background process. Idempotent: refuses to start when an alive pid already exists.')
84
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
85
- try {
86
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
87
- const pidFile = schedulerPidPath(projectRoot);
88
- const existing = readSchedulerPid(projectRoot);
89
- if (existing !== null && isPidAlive(existing)) {
90
- printResult(io, ok('cron-scheduler.start', { projectRoot, started: false, alreadyRunning: true, existingPid: existing }, [], [
91
- `Scheduler already running at pid ${existing}; not starting a second one.`,
92
- 'Use `peaks cron-scheduler stop` first if you need to restart.'
93
- ]), options.json);
94
- return;
95
- }
96
- // Spawn detached via `peaks-cron-scheduler.js` — the
97
- // child runs `runSchedulerLoop` (60s setInterval + due-task
98
- // runner). The detached flag + stdio:ignore puts the
99
- // scheduler in its own process group (POSIX) / detaches
100
- // from the console (Windows). PEAKS_CRON_SCHEDULER_DAEMON
101
- // env is the canonical "I'm the long-running child" signal.
102
- const entry = findSchedulerEntryPoint();
103
- const child = spawn(process.execPath, [entry, '--project', projectRoot], {
104
- cwd: projectRoot,
105
- stdio: 'ignore',
106
- detached: true,
107
- windowsHide: true,
108
- env: { ...process.env, PEAKS_CRON_SCHEDULER: '1', PEAKS_CRON_SCHEDULER_DAEMON: '1' }
109
- });
110
- child.unref();
111
- if (typeof child.pid !== 'number') {
112
- throw new Error('spawn returned no pid');
113
- }
114
- writeFileSync(pidFile, String(child.pid), 'utf8');
115
- printResult(io, ok('cron-scheduler.start', { projectRoot, started: true, pid: child.pid, pidFile }, [], [
116
- `Scheduler started at pid ${child.pid}; logs go to .peaks/cron/scheduler.log.`,
117
- 'Use `peaks cron-scheduler status` to confirm it is alive; `stop` to terminate.'
118
- ]), options.json);
119
- }
120
- catch (err) {
121
- printResult(io, fail('cron-scheduler.start', 'SCHEDULER_START_FAILED', getErrorMessage(err), { projectRoot: options.project }, [
122
- 'Verify the peaks-cron-scheduler.js entry point is on disk.',
123
- 'Check that the .peaks/cron/ directory is writable.'
124
- ]), options.json);
125
- process.exitCode = 1;
126
- }
127
- });
128
- addJsonOption(cmd
129
- .command('stop')
130
- .description('Send SIGTERM to the scheduler pid (best-effort; removes the pid file either way).')
131
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
132
- try {
133
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
134
- const pid = readSchedulerPid(projectRoot);
135
- if (pid === null) {
136
- printResult(io, ok('cron-scheduler.stop', { projectRoot, stopped: false, reason: 'no-pid-file' }, [], ['No scheduler pid file found; nothing to stop.']), options.json);
137
- return;
138
- }
139
- let signalSent = false;
140
- if (isPidAlive(pid)) {
141
- try {
142
- process.kill(pid, 'SIGTERM');
143
- signalSent = true;
144
- }
145
- catch {
146
- signalSent = false;
147
- }
148
- }
149
- const pidFile = schedulerPidPath(projectRoot);
150
- try {
151
- unlinkSync(pidFile);
152
- }
153
- catch {
154
- /* best-effort */
155
- }
156
- printResult(io, ok('cron-scheduler.stop', { projectRoot, stopped: signalSent, pid, pidFile }, [], [
157
- signalSent
158
- ? `Sent SIGTERM to pid ${pid}; pid file removed.`
159
- : `pid ${pid} was not alive; pid file removed.`
160
- ]), options.json);
161
- }
162
- catch (err) {
163
- printResult(io, fail('cron-scheduler.stop', 'SCHEDULER_STOP_FAILED', getErrorMessage(err), { projectRoot: options.project }, ['Verify the pid file is readable / the process is yours.']), options.json);
164
- process.exitCode = 1;
165
- }
166
- });
167
- addJsonOption(cmd
168
- .command('status')
169
- .description('Report whether the scheduler is alive + when it last ran a task.')
170
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
171
- try {
172
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
173
- const pid = readSchedulerPid(projectRoot);
174
- const alive = pid !== null && isPidAlive(pid);
175
- let schedule;
176
- try {
177
- schedule = readSchedule(projectRoot);
178
- }
179
- catch (err) {
180
- schedule = { version: 1, entries: [] };
181
- }
182
- const due = alive ? listDueTasks(projectRoot) : [];
183
- printResult(io, ok('cron-scheduler.status', {
184
- projectRoot,
185
- pid,
186
- alive,
187
- scheduleEntries: schedule.entries.length,
188
- dueTaskCount: due.length
189
- }, [], [
190
- alive
191
- ? `Scheduler alive at pid ${pid}; ${due.length} task(s) due now.`
192
- : 'Scheduler is NOT running. Use `peaks cron-scheduler start` to spawn.'
193
- ]), options.json);
194
- }
195
- catch (err) {
196
- printResult(io, fail('cron-scheduler.status', 'SCHEDULER_STATUS_FAILED', getErrorMessage(err), { projectRoot: options.project }, ['Verify the .peaks/cron/ directory exists.']), options.json);
197
- process.exitCode = 1;
198
- }
199
- });
200
- addJsonOption(cmd
201
- .command('run-once')
202
- .description('Synchronous foreground one-shot: run every currently-due task and exit. Useful for manual cron substitute.')
203
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
204
- try {
205
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
206
- const due = listDueTasks(projectRoot);
207
- const records = due.map((t) => runTask(projectRoot, t));
208
- // §2.24 applied to the one-shot path too: without it `run-once` under an
209
- // external crontab re-ran the same task on every invocation.
210
- persistLastRunAt(projectRoot, records);
211
- printResult(io, ok('cron-scheduler.run-once', { projectRoot, ran: records.length, records }, [], [
212
- `${records.length} due task(s) ran; ${records.filter((r) => r.exitCode === 0).length} succeeded.`
213
- ]), options.json);
214
- if (records.some((r) => r.exitCode !== 0))
215
- process.exitCode = 1;
46
+ registerCronSchedulerStartCommand(cmd, io);
47
+ registerCronSchedulerStopCommand(cmd, io);
48
+ registerCronSchedulerStatusCommand(cmd, io);
49
+ registerCronSchedulerRunOnceCommand(cmd, io);
50
+ }
51
+ /** The loop's interval handle, cleared when the shutdown signal arrives. */
52
+ function waitForShutdown(signal, handle) {
53
+ // Wait for the abort signal (POSIX) or the platform equivalent. We don't use
54
+ // Node's process.on('SIGTERM') for portability — the parent process kills us
55
+ // via `process.kill(pid, 'SIGTERM')` and the event loop exits naturally if
56
+ // the interval is the only thing keeping the loop alive.
57
+ return new Promise((resolveShutdown) => {
58
+ const onAbort = () => {
59
+ clearInterval(handle);
60
+ resolveShutdown();
61
+ };
62
+ if (signal) {
63
+ signal.addEventListener('abort', onAbort, { once: true });
216
64
  }
217
- catch (err) {
218
- printResult(io, fail('cron-scheduler.run-once', 'SCHEDULER_RUN_ONCE_FAILED', getErrorMessage(err), { projectRoot: options.project }, ["If schedule.json is missing, run 'peaks cron init' first."]), options.json);
219
- process.exitCode = 1;
65
+ else {
66
+ // POSIX: SIGTERM. Windows: kill the process directly.
67
+ process.on('SIGTERM', onAbort);
68
+ process.on('SIGINT', onAbort);
220
69
  }
221
70
  });
222
71
  }
@@ -246,7 +95,7 @@ export async function runSchedulerLoop(args) {
246
95
  // due. Without it `lastRunAt` stays null, `listDueTasks` keeps the entry
247
96
  // due, and a 24 h task re-fires on every 60,000 ms tick (measured: 6 fires
248
97
  // across 6 ticks, 1 after the write). Killed runs are deliberately NOT
249
- // stamped — here, in `run-once` above, and since repair cycle 1 in `peaks
98
+ // stamped — here, in `run-once`, and since repair cycle 1 in `peaks
250
99
  // cron run` too; the rule and its per-platform costs are in
251
100
  // `cron-scheduler-persist.ts`.
252
101
  persistLastRunAt(args.projectRoot, records);
@@ -259,26 +108,7 @@ export async function runSchedulerLoop(args) {
259
108
  // for the first run after a start).
260
109
  tick();
261
110
  const handle = setInterval(tick, tickMs);
262
- // Wait for the abort signal (POSIX) or the platform
263
- // equivalent. We don't use Node's process.on('SIGTERM')
264
- // for portability — the parent process kills us via
265
- // `process.kill(pid, 'SIGTERM')` and the event loop
266
- // exits naturally if the interval is the only thing
267
- // keeping the loop alive. We clearInterval on exit.
268
- await new Promise((resolve) => {
269
- const onAbort = () => {
270
- clearInterval(handle);
271
- resolve();
272
- };
273
- if (args.signal) {
274
- args.signal.addEventListener('abort', onAbort, { once: true });
275
- }
276
- else {
277
- // POSIX: SIGTERM. Windows: kill the process directly.
278
- process.on('SIGTERM', onAbort);
279
- process.on('SIGINT', onAbort);
280
- }
281
- });
111
+ await waitForShutdown(args.signal, handle);
282
112
  process.exit(0);
283
113
  }
284
114
  // Standalone entry shim. When this file is run directly via
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function runCronSchedulerRunOnce(io: ProgramIO, options: {
4
+ project?: string;
5
+ json?: boolean;
6
+ }): void;
7
+ export declare function registerCronSchedulerRunOnceCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,35 @@
1
+ // src/cli/commands/cron-scheduler-run-once-command.ts
2
+ //
3
+ // `peaks cron-scheduler run-once` — the synchronous foreground one-shot.
4
+ // Split out of `cron-scheduler-commands.ts`; the persistence step, the
5
+ // success envelope and the exit-code rule are unchanged.
6
+ import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
7
+ import { fail, ok } from 'peaks-loop-shared/result';
8
+ import { findProjectRoot } from '../../services/config/config-safety.js';
9
+ import { listDueTasks, runTask } from './cron-commands.js';
10
+ import { persistLastRunAt } from './cron-scheduler-persist.js';
11
+ export function runCronSchedulerRunOnce(io, options) {
12
+ try {
13
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
14
+ const due = listDueTasks(projectRoot);
15
+ const records = due.map((t) => runTask(projectRoot, t));
16
+ // §2.24 applied to the one-shot path too: without it `run-once` under an
17
+ // external crontab re-ran the same task on every invocation.
18
+ persistLastRunAt(projectRoot, records);
19
+ printResult(io, ok('cron-scheduler.run-once', { projectRoot, ran: records.length, records }, [], [
20
+ `${records.length} due task(s) ran; ${records.filter((r) => r.exitCode === 0).length} succeeded.`
21
+ ]), options.json ?? false);
22
+ if (records.some((r) => r.exitCode !== 0))
23
+ process.exitCode = 1;
24
+ }
25
+ catch (err) {
26
+ printResult(io, fail('cron-scheduler.run-once', 'SCHEDULER_RUN_ONCE_FAILED', getErrorMessage(err), { projectRoot: options.project }, ["If schedule.json is missing, run 'peaks cron init' first."]), options.json ?? false);
27
+ process.exitCode = 1;
28
+ }
29
+ }
30
+ export function registerCronSchedulerRunOnceCommand(cmd, io) {
31
+ addJsonOption(cmd
32
+ .command('run-once')
33
+ .description('Synchronous foreground one-shot: run every currently-due task and exit. Useful for manual cron substitute.')
34
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runCronSchedulerRunOnce(io, options));
35
+ }
@@ -0,0 +1,6 @@
1
+ export declare const SCHEDULER_TICK_MS = 60000;
2
+ export declare const PID_FILENAME = "scheduler.pid";
3
+ export declare function schedulerPidPath(projectRoot: string): string;
4
+ export declare function readSchedulerPid(projectRoot: string): number | null;
5
+ export declare function isPidAlive(pid: number): boolean;
6
+ export declare function findSchedulerEntryPoint(): string;
@@ -0,0 +1,48 @@
1
+ // src/cli/commands/cron-scheduler-shared.ts
2
+ //
3
+ // What every `peaks cron-scheduler *` verb shares: the tick period, the pid
4
+ // file, and the two questions asked of it (is there a pid, is it alive) plus
5
+ // where the detached child's entry shim lives. Split out of
6
+ // `cron-scheduler-commands.ts`; every path, probe and constant is unchanged.
7
+ import { existsSync, readFileSync } from 'node:fs';
8
+ import { dirname, join, resolve } from 'node:path';
9
+ import { fileURLToPath } from 'node:url';
10
+ export const SCHEDULER_TICK_MS = 60_000; // 1 minute
11
+ export const PID_FILENAME = 'scheduler.pid';
12
+ export function schedulerPidPath(projectRoot) {
13
+ return join(projectRoot, '.peaks', 'cron', PID_FILENAME);
14
+ }
15
+ export function readSchedulerPid(projectRoot) {
16
+ const p = schedulerPidPath(projectRoot);
17
+ if (!existsSync(p))
18
+ return null;
19
+ const raw = readFileSync(p, 'utf8').trim();
20
+ const pid = Number.parseInt(raw, 10);
21
+ if (!Number.isFinite(pid) || pid <= 0)
22
+ return null;
23
+ return pid;
24
+ }
25
+ export function isPidAlive(pid) {
26
+ try {
27
+ // `process.kill(pid, 0)` does not actually kill; it just
28
+ // checks if the process exists. ESRCH means no such pid;
29
+ // EPERM means it exists but we don't have permission to
30
+ // signal it (still alive).
31
+ process.kill(pid, 0);
32
+ return true;
33
+ }
34
+ catch (err) {
35
+ const code = err.code;
36
+ return code === 'EPERM';
37
+ }
38
+ }
39
+ export function findSchedulerEntryPoint() {
40
+ // The peaks-cron-scheduler.js entry shim lives in bin/ (not
41
+ // dist/, so the pnpm build does not overwrite it). It forwards
42
+ // to dist/cli/commands/cron-scheduler-commands.js with
43
+ // PEAKS_CRON_SCHEDULER_DAEMON=1 set; the CLI detects the env
44
+ // and runs runSchedulerLoop directly.
45
+ const here = dirname(fileURLToPath(import.meta.url));
46
+ // dist/cli/commands/cron-scheduler-commands.js → bin/peaks-cron-scheduler.js
47
+ return resolve(here, '..', '..', '..', 'bin', 'peaks-cron-scheduler.js');
48
+ }
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function runCronSchedulerStart(io: ProgramIO, options: {
4
+ project?: string;
5
+ json?: boolean;
6
+ }): void;
7
+ export declare function registerCronSchedulerStartCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,65 @@
1
+ // src/cli/commands/cron-scheduler-start-command.ts
2
+ //
3
+ // `peaks cron-scheduler start` — spawn the scheduler as a detached background
4
+ // process. Split out of `cron-scheduler-commands.ts`; the idempotency rule,
5
+ // the spawn options, the pid file and both envelopes are unchanged.
6
+ import { spawn } from 'node:child_process';
7
+ import { writeFileSync } from 'node:fs';
8
+ import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
9
+ import { fail, ok } from 'peaks-loop-shared/result';
10
+ import { findProjectRoot } from '../../services/config/config-safety.js';
11
+ import { findSchedulerEntryPoint, isPidAlive, readSchedulerPid, schedulerPidPath } from './cron-scheduler-shared.js';
12
+ /**
13
+ * Spawn detached via `peaks-cron-scheduler.js` — the child runs
14
+ * `runSchedulerLoop` (60s setInterval + due-task runner). The detached flag +
15
+ * stdio:ignore puts the scheduler in its own process group (POSIX) / detaches
16
+ * from the console (Windows). PEAKS_CRON_SCHEDULER_DAEMON env is the canonical
17
+ * "I'm the long-running child" signal.
18
+ */
19
+ function spawnDetachedScheduler(io, options, projectRoot, pidFile) {
20
+ const entry = findSchedulerEntryPoint();
21
+ const child = spawn(process.execPath, [entry, '--project', projectRoot], {
22
+ cwd: projectRoot,
23
+ stdio: 'ignore',
24
+ detached: true,
25
+ windowsHide: true,
26
+ env: { ...process.env, PEAKS_CRON_SCHEDULER: '1', PEAKS_CRON_SCHEDULER_DAEMON: '1' }
27
+ });
28
+ child.unref();
29
+ if (typeof child.pid !== 'number') {
30
+ throw new Error('spawn returned no pid');
31
+ }
32
+ writeFileSync(pidFile, String(child.pid), 'utf8');
33
+ printResult(io, ok('cron-scheduler.start', { projectRoot, started: true, pid: child.pid, pidFile }, [], [
34
+ `Scheduler started at pid ${child.pid}; logs go to .peaks/cron/scheduler.log.`,
35
+ 'Use `peaks cron-scheduler status` to confirm it is alive; `stop` to terminate.'
36
+ ]), options.json ?? false);
37
+ }
38
+ export function runCronSchedulerStart(io, options) {
39
+ try {
40
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
41
+ const pidFile = schedulerPidPath(projectRoot);
42
+ const existing = readSchedulerPid(projectRoot);
43
+ if (existing !== null && isPidAlive(existing)) {
44
+ printResult(io, ok('cron-scheduler.start', { projectRoot, started: false, alreadyRunning: true, existingPid: existing }, [], [
45
+ `Scheduler already running at pid ${existing}; not starting a second one.`,
46
+ 'Use `peaks cron-scheduler stop` first if you need to restart.'
47
+ ]), options.json ?? false);
48
+ return;
49
+ }
50
+ spawnDetachedScheduler(io, options, projectRoot, pidFile);
51
+ }
52
+ catch (err) {
53
+ printResult(io, fail('cron-scheduler.start', 'SCHEDULER_START_FAILED', getErrorMessage(err), { projectRoot: options.project }, [
54
+ 'Verify the peaks-cron-scheduler.js entry point is on disk.',
55
+ 'Check that the .peaks/cron/ directory is writable.'
56
+ ]), options.json ?? false);
57
+ process.exitCode = 1;
58
+ }
59
+ }
60
+ export function registerCronSchedulerStartCommand(cmd, io) {
61
+ addJsonOption(cmd
62
+ .command('start')
63
+ .description('Spawn the scheduler as a detached background process. Idempotent: refuses to start when an alive pid already exists.')
64
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runCronSchedulerStart(io, options));
65
+ }
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function runCronSchedulerStatus(io: ProgramIO, options: {
4
+ project?: string;
5
+ json?: boolean;
6
+ }): void;
7
+ export declare function registerCronSchedulerStatusCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,46 @@
1
+ // src/cli/commands/cron-scheduler-status-command.ts
2
+ //
3
+ // `peaks cron-scheduler status` — report whether the scheduler is alive and
4
+ // how many tasks are due. Split out of `cron-scheduler-commands.ts`; the
5
+ // degraded-tier schedule read and both envelopes are unchanged.
6
+ import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
7
+ import { fail, ok } from 'peaks-loop-shared/result';
8
+ import { findProjectRoot } from '../../services/config/config-safety.js';
9
+ import { listDueTasks, readSchedule } from './cron-commands.js';
10
+ import { isPidAlive, readSchedulerPid } from './cron-scheduler-shared.js';
11
+ export function runCronSchedulerStatus(io, options) {
12
+ try {
13
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
14
+ const pid = readSchedulerPid(projectRoot);
15
+ const alive = pid !== null && isPidAlive(pid);
16
+ let schedule;
17
+ try {
18
+ schedule = readSchedule(projectRoot);
19
+ }
20
+ catch {
21
+ schedule = { version: 1, entries: [] };
22
+ }
23
+ const due = alive ? listDueTasks(projectRoot) : [];
24
+ printResult(io, ok('cron-scheduler.status', {
25
+ projectRoot,
26
+ pid,
27
+ alive,
28
+ scheduleEntries: schedule.entries.length,
29
+ dueTaskCount: due.length
30
+ }, [], [
31
+ alive
32
+ ? `Scheduler alive at pid ${pid}; ${due.length} task(s) due now.`
33
+ : 'Scheduler is NOT running. Use `peaks cron-scheduler start` to spawn.'
34
+ ]), options.json ?? false);
35
+ }
36
+ catch (err) {
37
+ printResult(io, fail('cron-scheduler.status', 'SCHEDULER_STATUS_FAILED', getErrorMessage(err), { projectRoot: options.project }, ['Verify the .peaks/cron/ directory exists.']), options.json ?? false);
38
+ process.exitCode = 1;
39
+ }
40
+ }
41
+ export function registerCronSchedulerStatusCommand(cmd, io) {
42
+ addJsonOption(cmd
43
+ .command('status')
44
+ .description('Report whether the scheduler is alive + when it last ran a task.')
45
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runCronSchedulerStatus(io, options));
46
+ }
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function runCronSchedulerStop(io: ProgramIO, options: {
4
+ project?: string;
5
+ json?: boolean;
6
+ }): void;
7
+ export declare function registerCronSchedulerStopCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,61 @@
1
+ // src/cli/commands/cron-scheduler-stop-command.ts
2
+ //
3
+ // `peaks cron-scheduler stop` — SIGTERM the scheduler pid (best-effort) and
4
+ // remove the pid file either way. Split out of `cron-scheduler-commands.ts`;
5
+ // the signal, the unlink and both envelopes are unchanged.
6
+ import { unlinkSync } from 'node:fs';
7
+ import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
8
+ import { fail, ok } from 'peaks-loop-shared/result';
9
+ import { findProjectRoot } from '../../services/config/config-safety.js';
10
+ import { isPidAlive, readSchedulerPid, schedulerPidPath } from './cron-scheduler-shared.js';
11
+ /** The no-pid-file outcome: nothing to signal, nothing to unlink. */
12
+ function emitNoPidFile(io, options, projectRoot) {
13
+ printResult(io, ok('cron-scheduler.stop', { projectRoot, stopped: false, reason: 'no-pid-file' }, [], ['No scheduler pid file found; nothing to stop.']), options.json ?? false);
14
+ }
15
+ /** SIGTERM the pid (best-effort) and remove the pid file either way. */
16
+ function terminateScheduler(projectRoot, pid) {
17
+ let signalSent = false;
18
+ if (isPidAlive(pid)) {
19
+ try {
20
+ process.kill(pid, 'SIGTERM');
21
+ signalSent = true;
22
+ }
23
+ catch {
24
+ signalSent = false;
25
+ }
26
+ }
27
+ const pidFile = schedulerPidPath(projectRoot);
28
+ try {
29
+ unlinkSync(pidFile);
30
+ }
31
+ catch {
32
+ /* best-effort */
33
+ }
34
+ return { signalSent, pidFile };
35
+ }
36
+ export function runCronSchedulerStop(io, options) {
37
+ try {
38
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
39
+ const pid = readSchedulerPid(projectRoot);
40
+ if (pid === null) {
41
+ emitNoPidFile(io, options, projectRoot);
42
+ return;
43
+ }
44
+ const { signalSent, pidFile } = terminateScheduler(projectRoot, pid);
45
+ printResult(io, ok('cron-scheduler.stop', { projectRoot, stopped: signalSent, pid, pidFile }, [], [
46
+ signalSent
47
+ ? `Sent SIGTERM to pid ${pid}; pid file removed.`
48
+ : `pid ${pid} was not alive; pid file removed.`
49
+ ]), options.json ?? false);
50
+ }
51
+ catch (err) {
52
+ printResult(io, fail('cron-scheduler.stop', 'SCHEDULER_STOP_FAILED', getErrorMessage(err), { projectRoot: options.project }, ['Verify the pid file is readable / the process is yours.']), options.json ?? false);
53
+ process.exitCode = 1;
54
+ }
55
+ }
56
+ export function registerCronSchedulerStopCommand(cmd, io) {
57
+ addJsonOption(cmd
58
+ .command('stop')
59
+ .description('Send SIGTERM to the scheduler pid (best-effort; removes the pid file either way).')
60
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runCronSchedulerStop(io, options));
61
+ }
@@ -0,0 +1,41 @@
1
+ import type { SubAgentToolCall } from '../../services/dispatch/sub-agent-dispatcher.js';
2
+ import type { SliceDag } from '../../services/dispatch/slice-dag.js';
3
+ import type { SliceComplexity } from '../../services/dispatch/slice-dag-types.js';
4
+ /** Everything the `--from-dag` success envelope reports, already resolved. */
5
+ export type DagEnvelopeInput = {
6
+ readonly role: string;
7
+ readonly ide: string;
8
+ readonly fromDag: string;
9
+ readonly batchId: string;
10
+ readonly levelsTotal: number;
11
+ readonly emittedSliceIds: readonly string[];
12
+ readonly emittedToolCalls: readonly SubAgentToolCall[];
13
+ readonly firstLevelWaves: unknown;
14
+ readonly existingContractCount: number;
15
+ readonly dag: SliceDag;
16
+ readonly isSliceComplexity: (value: string) => value is SliceComplexity;
17
+ };
18
+ /** The `ok('sub-agent.dispatch', …)` envelope for a completed `--from-dag` run. */
19
+ export declare function buildDagSuccessEnvelope(input: DagEnvelopeInput): import("peaks-loop-shared/result").ResultEnvelope<{
20
+ envelopeVersion: string;
21
+ role: string;
22
+ ide: string;
23
+ fromDag: string;
24
+ batchId: string;
25
+ dispatchCount: number;
26
+ levelsTotal: number;
27
+ firstLevel: readonly string[];
28
+ firstLevelWaves: unknown;
29
+ toolCalls: readonly SubAgentToolCall[];
30
+ existingContractCount: number;
31
+ expectedCompletionSeconds: number;
32
+ artifactsPublicPaths: never[];
33
+ orchestratorVisibleHint: string;
34
+ sliceMeta: {
35
+ id: string;
36
+ foundation: boolean;
37
+ upstreamSync: boolean;
38
+ complexity: SliceComplexity | null;
39
+ }[];
40
+ nextActions: string[];
41
+ }>;