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,123 @@
1
+ /**
2
+ * The orchestrator’s input and run-context types.
3
+ *
4
+ * Split out of `auto-compact-orchestrator.ts` (file-size cap campaign). The
5
+ * orchestrator re-exports every name declared here, so existing importers keep
6
+ * using `./auto-compact-orchestrator.js` unchanged.
7
+ */
8
+ import type { AutoCompactMode } from './auto-compact-modes.js';
9
+ import type { CompactTarget } from '../context/auto-compact-dispatcher.js';
10
+ import type { ContextPercentProbe, InFlightBatchProbe } from '../context/auto-compact-types.js';
11
+ import type { HarnessWindowSyncResult } from '../context/harness-window-config.js';
12
+ import type { CompactLifecycleRecord, CompactLifecycleStage } from '../compact-statusline/compact-lifecycle-store.js';
13
+ import type { evaluateAutoCompactDecision } from './auto-compact-decision.js';
14
+ export interface AutoCompactInput {
15
+ /** Project root for context (default cwd). */
16
+ readonly projectRoot: string;
17
+ /**
18
+ * Caller-provided in-flight batch probe (default false). Slice
19
+ * 4.0.8 (D4d): production callers should pass a `probeInflightBatch`
20
+ * function (see below). The legacy `inFlightBatch` boolean
21
+ * remains as a TEST-ONLY seam — the CLI gates it behind
22
+ * `process.env.PEAKS_TEST_SEAM === '1'` so a production run
23
+ * never consults the boolean as truth.
24
+ */
25
+ readonly inFlightBatch?: InFlightBatchProbe | undefined;
26
+ /**
27
+ * Slice 4.0.8 (D4d): graph-only in-flight probe. When supplied,
28
+ * the orchestrator calls this function and uses the boolean
29
+ * result as the production `inFlightBatch` signal. The legacy
30
+ * boolean parameter is suppressed in production callers — the
31
+ * CLI's `--in-flight-batch` flag is gated behind
32
+ * `PEAKS_TEST_SEAM === '1'`. The pure decision function
33
+ * `evaluateAutoCompactDecision` retains the boolean signature
34
+ * for the test seam + the red-line override.
35
+ */
36
+ readonly probeInflightBatch?: (() => boolean) | undefined;
37
+ /**
38
+ * Force execute even when ratio < threshold (test seam). In
39
+ * production this is always `false` — peaks-loop drives compact
40
+ * autonomously at 0.85+ with zero human / zero LLM intervention.
41
+ */
42
+ readonly force?: boolean | undefined;
43
+ /**
44
+ * INERT — nothing reads this. It is threaded from the CLI's
45
+ * `--bypass-red-line` (a published flag, kept for backward compatibility;
46
+ * see the option's own note) down to `evaluateAutoCompactDecision`, where the
47
+ * red-line branch ignores it.
48
+ *
49
+ * Why nothing reads it any more: it used to skip a gate that refused to
50
+ * dispatch below 0.85. That gate was removed (slice
51
+ * compact a running session, so the refusal could not shorten the wait it
52
+ * was waiting for, and it deadlocked the runner at the worst moment. With the
53
+ * gate gone, the red line still ASKS the harness to compact (when it always
54
+ * did) and no longer needs a bypass. Kept as a field so the published
55
+ * signature does not change under callers that pass it.
56
+ */
57
+ readonly bypassRedLine?: boolean | undefined;
58
+ /** Current session id (default = resolve via session-id-service). */
59
+ readonly sessionId?: string | undefined;
60
+ /** Injectable env for IDE detection (test seam). */
61
+ readonly env?: NodeJS.ProcessEnv | undefined;
62
+ /** Injectable clock for mtime checks (test seam). */
63
+ readonly now?: Date | undefined;
64
+ /**
65
+ * the compact should target. Default `'main'` — the orchestrator
66
+ * (peaks-code body) runs in the main-session Claude Code window and
67
+ * wants to compress *its* context. Sub-agent shells pass
68
+ * `'sub-agent'` to preserve the legacy shell-spawn behaviour.
69
+ */
70
+ readonly target?: CompactTarget | undefined;
71
+ /**
72
+ * `'standard'` (v2.13.0 zero-pause contract, 0.85/0.95). `'partial'`
73
+ * fires earlier (0.70/0.85) for 24h long-run scenarios. CLI flag
74
+ * `--mode <mode>` overrides the 24h-mode auto-detection.
75
+ */
76
+ readonly mode?: AutoCompactMode | undefined;
77
+ /**
78
+ * every lifecycle stage this process actually proved. Telemetry
79
+ * only — it can neither change the threshold decision nor the
80
+ * dispatch outcome, and a throwing observer is swallowed.
81
+ */
82
+ readonly onLifecycleStage?: ((stage: CompactLifecycleStage, record: CompactLifecycleRecord) => void) | undefined;
83
+ /**
84
+ * Test-only injection seams for lifecycle failure paths. NEVER set in
85
+ * production — these exist so the unit suite can drive the `failed`
86
+ * transition and the store-outage branch without mocking the SUT.
87
+ * Each flag toggles a single, well-scoped throw at a documented point:
88
+ * - `failPreparing`: throw inside the checkpoint/plan/recovery phase
89
+ * (so the record rests at `failedAt: 'preparing'`)
90
+ * - `failCompacting`: throw inside the IDE-dispatch phase
91
+ * (so the record rests at `failedAt: 'compacting'`)
92
+ * - `failLifecycleWrite`: make every lifecycle-store write throw
93
+ * (so the compact envelope is proven independent of telemetry)
94
+ */
95
+ readonly testHooks?: AutoCompactTestHooks | undefined;
96
+ }
97
+ /**
98
+ * Test-only injection seams. The `boolean` shape (vs. an injected error)
99
+ * is deliberate: tests assert the *transition*, not the thrown value —
100
+ * the value would just be a brittle fingerprint. The real error path
101
+ * is still exercised by `summarizeLifecycleError`'s tests.
102
+ */
103
+ export interface AutoCompactTestHooks {
104
+ readonly failPreparing?: boolean | undefined;
105
+ readonly failCompacting?: boolean | undefined;
106
+ readonly failLifecycleWrite?: boolean | undefined;
107
+ }
108
+ /** The decision shape `evaluateAutoCompactDecision` returns. */
109
+ export type AutoCompactDecision = ReturnType<typeof evaluateAutoCompactDecision>;
110
+ /**
111
+ * One probe's worth of resolved state, threaded through the whole run so each
112
+ * phase takes the same object rather than a widening parameter list.
113
+ */
114
+ export type CompactRun = {
115
+ readonly input: AutoCompactInput;
116
+ readonly sessionId: string;
117
+ readonly mode: AutoCompactMode;
118
+ readonly probe: ContextPercentProbe;
119
+ readonly harnessWindow: HarnessWindowSyncResult | null;
120
+ readonly decision: AutoCompactDecision;
121
+ readonly isRedLine: boolean;
122
+ readonly now: Date;
123
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -11,9 +11,16 @@
11
11
  * skipped `peaks job init`)
12
12
  * - isJob === true, state.json, remaining > 0,
13
13
  * no --force-under-job → JOB_REMAINING_BLOCKED
14
- * - isJob === true, state.json, remaining === 0 → ALLOW (Job done)
15
14
  * - isJob === true, state.json, remaining > 0,
16
15
  * --force-under-job → ALLOW (override path)
16
+ * - isJob === true, state.json, remaining === 0,
17
+ * no session sediment, no --force-no-sediment → JOB_COMPLETED_NO_SEDIMENT
18
+ * - isJob === true, state.json, remaining === 0,
19
+ * session sediment OR --force-no-sediment → ALLOW (Job done)
20
+ *
21
+ * The sediment arm is the refusal point for Step 11: a completed Job whose
22
+ * session put nothing into `.peaks/memory/` is refused, and an unanswerable
23
+ * sediment question is refused too (fail closed).
17
24
  *
18
25
  * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
26
  * Pure read + arithmetic. The CLI wrapper in code-commands.ts
@@ -21,6 +28,15 @@
21
28
  */
22
29
  export declare const JOB_NOT_INITIALIZED: "JOB_NOT_INITIALIZED";
23
30
  export declare const JOB_REMAINING_BLOCKED: "JOB_REMAINING_BLOCKED";
31
+ export declare const JOB_COMPLETED_NO_SEDIMENT: "JOB_COMPLETED_NO_SEDIMENT";
32
+ /**
33
+ * What the memory index says about this session.
34
+ *
35
+ * `unknown` is a first-class answer, not an error code: it means the question
36
+ * could not be put to peaks' own store at all, and the handoff refuses on it
37
+ * rather than assuming the session sedimented nothing.
38
+ */
39
+ export type SessionSedimentState = 'sedimented' | 'none' | 'unknown';
24
40
  export type EmitHandoffVerdict = {
25
41
  readonly kind: 'allow-not-job';
26
42
  } | {
@@ -38,6 +54,18 @@ export type EmitHandoffVerdict = {
38
54
  readonly code: typeof JOB_REMAINING_BLOCKED;
39
55
  readonly jobId: string;
40
56
  readonly remaining: number;
57
+ } | {
58
+ readonly kind: 'block-no-sediment';
59
+ readonly code: typeof JOB_COMPLETED_NO_SEDIMENT;
60
+ readonly jobId: string;
61
+ /** `none` = the index was read and holds no entry for this session. */
62
+ readonly sedimentState: Exclude<SessionSedimentState, 'sedimented'>;
63
+ } | {
64
+ readonly kind: 'allow-forced-no-sediment';
65
+ readonly remaining: number;
66
+ /** The reason the user approved a no-sediment outcome. Never blank. */
67
+ readonly reason: string;
68
+ readonly sedimentState: Exclude<SessionSedimentState, 'sedimented'>;
41
69
  };
42
70
  export interface EvaluateEmitHandoffInput {
43
71
  readonly projectRoot: string;
@@ -45,5 +73,11 @@ export interface EvaluateEmitHandoffInput {
45
73
  /** Suggested job id — read from job-shape.json when omitted. */
46
74
  readonly jobId?: string;
47
75
  readonly forceUnderJob?: boolean;
76
+ /**
77
+ * The reason the user approved a no-sediment outcome. Present and non-blank
78
+ * overrides the completed-Job no-sediment block; blank is treated as absent,
79
+ * so an override nobody justified does not open the gate.
80
+ */
81
+ readonly forceNoSedimentReason?: string;
48
82
  }
49
83
  export declare function evaluateEmitHandoff(input: EvaluateEmitHandoffInput): EmitHandoffVerdict;
@@ -11,9 +11,16 @@
11
11
  * skipped `peaks job init`)
12
12
  * - isJob === true, state.json, remaining > 0,
13
13
  * no --force-under-job → JOB_REMAINING_BLOCKED
14
- * - isJob === true, state.json, remaining === 0 → ALLOW (Job done)
15
14
  * - isJob === true, state.json, remaining > 0,
16
15
  * --force-under-job → ALLOW (override path)
16
+ * - isJob === true, state.json, remaining === 0,
17
+ * no session sediment, no --force-no-sediment → JOB_COMPLETED_NO_SEDIMENT
18
+ * - isJob === true, state.json, remaining === 0,
19
+ * session sediment OR --force-no-sediment → ALLOW (Job done)
20
+ *
21
+ * The sediment arm is the refusal point for Step 11: a completed Job whose
22
+ * session put nothing into `.peaks/memory/` is refused, and an unanswerable
23
+ * sediment question is refused too (fail closed).
17
24
  *
18
25
  * Karpathy §2 (Simplicity First): ~70 lines, no LLM call, no regex.
19
26
  * Pure read + arithmetic. The CLI wrapper in code-commands.ts
@@ -21,9 +28,11 @@
21
28
  */
22
29
  import { existsSync, readFileSync } from 'node:fs';
23
30
  import { join } from 'node:path';
31
+ import { isExpectedFsMiss } from '../../shared/fs-utils.js';
24
32
  import { readJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED } from './job-shape-decision.js';
25
33
  export const JOB_NOT_INITIALIZED = 'JOB_NOT_INITIALIZED';
26
34
  export const JOB_REMAINING_BLOCKED = 'JOB_REMAINING_BLOCKED';
35
+ export const JOB_COMPLETED_NO_SEDIMENT = 'JOB_COMPLETED_NO_SEDIMENT';
27
36
  function countRemaining(statePath) {
28
37
  let raw;
29
38
  try {
@@ -46,6 +55,119 @@ function countRemaining(statePath) {
46
55
  function statePath(projectRoot, sessionId, jobId) {
47
56
  return join(projectRoot, '.peaks', '_runtime', sessionId, 'job', jobId, 'state.json');
48
57
  }
58
+ /**
59
+ * Which session a memory came from, as the memory index records it.
60
+ *
61
+ * The runtime directory is the link: `peaks memory extract` stamps each
62
+ * extracted memory with the `sourceArtifact` it read, and every artifact a
63
+ * session can sediment from lives under its own runtime directory, so an
64
+ * index entry naming this session's runtime directory IS this session's
65
+ * sediment. Nothing here reads a modification time.
66
+ */
67
+ function sourceArtifactNamesSession(sourceArtifact, sessionId) {
68
+ if (typeof sourceArtifact !== 'string')
69
+ return false;
70
+ return sourceArtifact.replaceAll('\\', '/').includes(`_runtime/${sessionId}/`);
71
+ }
72
+ function isPlainRecord(value) {
73
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
74
+ }
75
+ /**
76
+ * One `hot` / `warm` bucket flattened to its entries, or null when the bucket
77
+ * is not the shape this reader knows. A bucket whose kind maps to something
78
+ * other than a list is a shape deviation, and a shape deviation has to read as
79
+ * "cannot tell" rather than as "no entries": the two answers disagree about
80
+ * whether the handoff may proceed.
81
+ */
82
+ function bucketEntries(bucket) {
83
+ if (!isPlainRecord(bucket))
84
+ return null;
85
+ const entries = [];
86
+ for (const list of Object.values(bucket)) {
87
+ if (!Array.isArray(list))
88
+ return null;
89
+ for (const entry of list)
90
+ entries.push(entry);
91
+ }
92
+ return entries;
93
+ }
94
+ /** Every index entry, or null when the file is not the shape this reader knows. */
95
+ function readIndexEntries(parsed) {
96
+ if (!isPlainRecord(parsed))
97
+ return null;
98
+ const hot = bucketEntries(parsed.hot);
99
+ const warm = bucketEntries(parsed.warm);
100
+ if (hot === null || warm === null)
101
+ return null;
102
+ return [...hot, ...warm];
103
+ }
104
+ /**
105
+ * Did this session sediment anything into the project memory store?
106
+ *
107
+ * The basis is peaks' own memory index, which both `peaks memory extract
108
+ * --apply` paths rebuild after writing, so it is a peaks-owned projection of
109
+ * the store rather than a guess about timestamps.
110
+ */
111
+ function readSessionSedimentState(projectRoot, sessionId) {
112
+ const indexPath = join(projectRoot, '.peaks', 'memory', 'index.json');
113
+ if (!existsSync(indexPath))
114
+ return 'unknown';
115
+ let raw;
116
+ try {
117
+ raw = readFileSync(indexPath, 'utf8');
118
+ }
119
+ catch (err) {
120
+ if (!isExpectedFsMiss(err))
121
+ throw err;
122
+ return 'unknown';
123
+ }
124
+ let parsed;
125
+ try {
126
+ parsed = JSON.parse(raw);
127
+ }
128
+ catch {
129
+ return 'unknown';
130
+ }
131
+ const entries = readIndexEntries(parsed);
132
+ if (entries === null)
133
+ return 'unknown';
134
+ for (const entry of entries) {
135
+ if (!isPlainRecord(entry))
136
+ return 'unknown';
137
+ if (sourceArtifactNamesSession(entry.sourceArtifact, sessionId))
138
+ return 'sedimented';
139
+ }
140
+ return 'none';
141
+ }
142
+ /** A blank override reason is the same as no override at all. */
143
+ function approvedNoSedimentReason(reason) {
144
+ if (reason === undefined)
145
+ return null;
146
+ const trimmed = reason.trim();
147
+ return trimmed.length === 0 ? null : trimmed;
148
+ }
149
+ /**
150
+ * The verdict for a Job with no slices left. This is the moment Step 11 is
151
+ * owed: the workflow is about to be declared complete, so the session must
152
+ * have sedimented something, or have been granted an explicit no-sediment
153
+ * outcome. `unknown` refuses too — cannot tell is not a pass.
154
+ */
155
+ function decideCompletedJob(input, jobId) {
156
+ const sedimentState = readSessionSedimentState(input.projectRoot, input.sessionId);
157
+ if (sedimentState === 'sedimented') {
158
+ return { kind: 'allow-done', remaining: 0 };
159
+ }
160
+ const approvedReason = approvedNoSedimentReason(input.forceNoSedimentReason);
161
+ if (approvedReason !== null) {
162
+ return {
163
+ kind: 'allow-forced-no-sediment',
164
+ remaining: 0,
165
+ reason: approvedReason,
166
+ sedimentState
167
+ };
168
+ }
169
+ return { kind: 'block-no-sediment', code: JOB_COMPLETED_NO_SEDIMENT, jobId, sedimentState };
170
+ }
49
171
  export function evaluateEmitHandoff(input) {
50
172
  let decision = null;
51
173
  try {
@@ -69,11 +191,10 @@ export function evaluateEmitHandoff(input) {
69
191
  if (!Number.isFinite(remaining)) {
70
192
  return { kind: 'block-not-initialized', code: JOB_NOT_INITIALIZED, jobId };
71
193
  }
72
- if (remaining === 0) {
73
- return { kind: 'allow-done', remaining };
74
- }
75
- if (input.forceUnderJob === true) {
76
- return { kind: 'allow-force-override', remaining };
194
+ if (remaining > 0) {
195
+ return input.forceUnderJob === true
196
+ ? { kind: 'allow-force-override', remaining }
197
+ : { kind: 'block-remaining', code: JOB_REMAINING_BLOCKED, jobId, remaining };
77
198
  }
78
- return { kind: 'block-remaining', code: JOB_REMAINING_BLOCKED, jobId, remaining };
199
+ return decideCompletedJob(input, jobId);
79
200
  }
@@ -19,19 +19,24 @@
19
19
  * — so the LLM sees its resume context BEFORE any Bash call lands.
20
20
  * 2. `job-shape.json` exists with `decision.isJob === false`.
21
21
  * → allow, print `{ ok, allow, mode: 'single' }`.
22
- * 3. `job-shape.json` is MISSING — fail-closed guard. The LLM is the
23
- * source of truth, but if it never recorded a decision we run a
24
- * lightweight backup regex against the user's prompt:
25
- * /until|全部|until all done|disavow cost|不用考虑费用|all of them/i
26
- * match → block (exit 2) with the BLOCKED: stderr message.
27
- * no match → allow (exit 0) — most prompts are not Job-shaped.
22
+ * 3. `job-shape.json` is MISSING. Every answer here is about the decision
23
+ * that was never recorded, not about the prompt:
24
+ * a. the backup regex matches the prompt → block (exit 2) with the
25
+ * BLOCKED: stderr message.
26
+ * b. no regex match, but the session owns a Job ledger
27
+ * (`job/<jid>/state.json` exists) → block (exit 2). `peaks job
28
+ * init` ran and `peaks code detect-job` did not.
29
+ * c. no regex match and no ledger → allow (exit 0), reporting that NO
30
+ * decision was recorded. The absence of a judgement is stated as an
31
+ * absence, not as a judgement that the prompt is not Job-shaped.
32
+ * The gate never blocks on the ABSENCE of a decision alone: it runs on
33
+ * every Bash call in every session, so a normal non-Job session must
34
+ * keep passing through case (c).
28
35
  *
29
- * Karpathy §2 (Simplicity First): ~120 lines, no LLM call inside. The
30
- * regex is the FIRST time peaks-loop accepts hardcoded keywords —
31
- * explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
32
- * judgement. The LLM still owns the semantic call via
33
- * `peaks code detect-job`. The regex is a safety net for the v3.1.1
34
- * incident class (LLM under load never records the decision at all).
36
+ * Karpathy §2 (Simplicity First): no LLM call inside. The regex is the FIRST
37
+ * time peaks-loop accepts hardcoded keywords — explicitly scoped as a
38
+ * *fail-closed backup* (case 3), NOT a primary judgement. The LLM still owns
39
+ * the semantic call via `peaks code detect-job`.
35
40
  */
36
41
  export declare const STEP_08_GATE_FILE_NAME: "job-shape.json";
37
42
  export declare const STEP_08_PROGRESS_FILE_NAME: "progress.json";
@@ -56,6 +61,7 @@ export interface Step08Progress {
56
61
  readonly lastCommitSha: string | null;
57
62
  readonly updatedAt: string;
58
63
  }
64
+ export type Step08PromptSource = 'flag' | 'last-prompt-file' | 'stdin-empty';
59
65
  export type Step08Verdict = {
60
66
  readonly kind: 'allow-job';
61
67
  readonly decision: import('./job-shape-decision.js').JobShapeDecision;
@@ -64,8 +70,15 @@ export type Step08Verdict = {
64
70
  readonly kind: 'allow-single';
65
71
  } | {
66
72
  readonly kind: 'block-missing-decision';
67
- readonly promptHit: boolean;
68
- readonly promptSource: 'flag' | 'last-prompt-file' | 'stdin-empty';
73
+ readonly promptSource: Step08PromptSource;
74
+ } | {
75
+ readonly kind: 'allow-no-decision-recorded';
76
+ readonly promptSource: Step08PromptSource;
77
+ readonly reason: string;
78
+ } | {
79
+ readonly kind: 'block-no-decision-with-ledger';
80
+ readonly ledgerJobIds: readonly string[];
81
+ readonly reason: string;
69
82
  };
70
83
  export declare function runtimeSessionDir(projectRoot: string, sessionId: string): string;
71
84
  export interface EvaluateStep08Input {
@@ -83,9 +96,5 @@ export interface EvaluateStep08Result {
83
96
  readonly verdict: Step08Verdict;
84
97
  readonly nextSliceLine: string | null;
85
98
  }
86
- /**
87
- * Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
88
- * `src/cli/commands/code-commands.ts` reads `allow` to set the process
89
- * exit code (0 allow / 2 block) and prints the structured envelope.
90
- */
99
+ /** Pure evaluator — does NOT write, does NOT exit. The CLI wrapper reads `allow`. */
91
100
  export declare function evaluateStep08(input: EvaluateStep08Input): EvaluateStep08Result;
@@ -19,21 +19,26 @@
19
19
  * — so the LLM sees its resume context BEFORE any Bash call lands.
20
20
  * 2. `job-shape.json` exists with `decision.isJob === false`.
21
21
  * → allow, print `{ ok, allow, mode: 'single' }`.
22
- * 3. `job-shape.json` is MISSING — fail-closed guard. The LLM is the
23
- * source of truth, but if it never recorded a decision we run a
24
- * lightweight backup regex against the user's prompt:
25
- * /until|全部|until all done|disavow cost|不用考虑费用|all of them/i
26
- * match → block (exit 2) with the BLOCKED: stderr message.
27
- * no match → allow (exit 0) — most prompts are not Job-shaped.
22
+ * 3. `job-shape.json` is MISSING. Every answer here is about the decision
23
+ * that was never recorded, not about the prompt:
24
+ * a. the backup regex matches the prompt → block (exit 2) with the
25
+ * BLOCKED: stderr message.
26
+ * b. no regex match, but the session owns a Job ledger
27
+ * (`job/<jid>/state.json` exists) → block (exit 2). `peaks job
28
+ * init` ran and `peaks code detect-job` did not.
29
+ * c. no regex match and no ledger → allow (exit 0), reporting that NO
30
+ * decision was recorded. The absence of a judgement is stated as an
31
+ * absence, not as a judgement that the prompt is not Job-shaped.
32
+ * The gate never blocks on the ABSENCE of a decision alone: it runs on
33
+ * every Bash call in every session, so a normal non-Job session must
34
+ * keep passing through case (c).
28
35
  *
29
- * Karpathy §2 (Simplicity First): ~120 lines, no LLM call inside. The
30
- * regex is the FIRST time peaks-loop accepts hardcoded keywords —
31
- * explicitly scoped as a *fail-closed backup* (case 3), NOT a primary
32
- * judgement. The LLM still owns the semantic call via
33
- * `peaks code detect-job`. The regex is a safety net for the v3.1.1
34
- * incident class (LLM under load never records the decision at all).
36
+ * Karpathy §2 (Simplicity First): no LLM call inside. The regex is the FIRST
37
+ * time peaks-loop accepts hardcoded keywords — explicitly scoped as a
38
+ * *fail-closed backup* (case 3), NOT a primary judgement. The LLM still owns
39
+ * the semantic call via `peaks code detect-job`.
35
40
  */
36
- import { existsSync, readFileSync } from 'node:fs';
41
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
37
42
  import { join } from 'node:path';
38
43
  import { readJobShapeDecision, JobShapeDecisionError, JOB_SHAPE_NOT_DECIDED } from './job-shape-decision.js';
39
44
  import { describeNextSlice } from '../job/job-progress-store.js';
@@ -122,10 +127,41 @@ function readPromptFromLastPromptFile(projectRoot, sessionId) {
122
127
  }
123
128
  }
124
129
  /**
125
- * Pure evaluator — does NOT write, does NOT exit. CLI wrapper in
126
- * `src/cli/commands/code-commands.ts` reads `allow` to set the process
127
- * exit code (0 allow / 2 block) and prints the structured envelope.
130
+ * Job ids this session owns a ledger for, sorted.
131
+ *
132
+ * A ledger is `job/<jid>/state.json`, which only `peaks job init` writes, and
133
+ * `job-shape.json` is written by `peaks code detect-job` and by nothing else —
134
+ * so a ledger with no decision is the decision step having been skipped.
128
135
  */
136
+ function ledgerJobIds(projectRoot, sessionId) {
137
+ const jobDir = join(runtimeSessionDir(projectRoot, sessionId), 'job');
138
+ if (!existsSync(jobDir))
139
+ return [];
140
+ let names;
141
+ try {
142
+ names = readdirSync(jobDir);
143
+ }
144
+ catch (err) {
145
+ if (!isExpectedFsMiss(err))
146
+ throw err;
147
+ return [];
148
+ }
149
+ return names
150
+ .filter((name) => existsSync(join(jobDir, name, 'state.json')))
151
+ .sort((left, right) => left.localeCompare(right));
152
+ }
153
+ /**
154
+ * The reason a Job ledger with no decision is refused — it names both commands,
155
+ * so the reader sees WHICH step was skipped.
156
+ */
157
+ function noDecisionWithLedgerReason(ledger) {
158
+ const paths = ledger.map((jid) => `job/${jid}/state.json`).join(', ');
159
+ return (`No Job-shape decision was recorded for this session, but it owns a Job ledger (${paths}). ` +
160
+ 'That means `peaks job init` ran and `peaks code detect-job` did not, so every ' +
161
+ 'Job-mode step this gate keys on was skipped. Record the verdict with ' +
162
+ '`peaks code detect-job --is-job true|false ...`, then retry.');
163
+ }
164
+ /** Pure evaluator — does NOT write, does NOT exit. The CLI wrapper reads `allow`. */
129
165
  export function evaluateStep08(input) {
130
166
  try {
131
167
  const record = readJobShapeDecision(input.projectRoot, input.sessionId);
@@ -142,26 +178,47 @@ export function evaluateStep08(input) {
142
178
  }
143
179
  catch (err) {
144
180
  if (err instanceof JobShapeDecisionError && err.code === JOB_SHAPE_NOT_DECIDED) {
145
- const promptText = input.prompt ?? readPromptFromLastPromptFile(input.projectRoot, input.sessionId);
146
- const hit = promptText.length > 0 && STEP_08_BACKUP_REGEX.test(promptText);
147
- const source = input.prompt !== undefined
148
- ? 'flag'
149
- : promptText.length > 0
150
- ? 'last-prompt-file'
151
- : 'stdin-empty';
152
- if (hit) {
153
- return {
154
- allow: false,
155
- verdict: { kind: 'block-missing-decision', promptHit: true, promptSource: source },
156
- nextSliceLine: null
157
- };
158
- }
159
- return {
160
- allow: true,
161
- verdict: { kind: 'block-missing-decision', promptHit: false, promptSource: source },
162
- nextSliceLine: null
163
- };
181
+ return decideWithoutJobShapeDecision(input);
164
182
  }
165
183
  throw err;
166
184
  }
167
185
  }
186
+ /** `job-shape.json` is missing — see the module header for the three answers. */
187
+ function decideWithoutJobShapeDecision(input) {
188
+ const promptText = input.prompt ?? readPromptFromLastPromptFile(input.projectRoot, input.sessionId);
189
+ const promptSource = input.prompt !== undefined
190
+ ? 'flag'
191
+ : promptText.length > 0
192
+ ? 'last-prompt-file'
193
+ : 'stdin-empty';
194
+ if (promptText.length > 0 && STEP_08_BACKUP_REGEX.test(promptText)) {
195
+ return {
196
+ allow: false,
197
+ verdict: { kind: 'block-missing-decision', promptSource },
198
+ nextSliceLine: null
199
+ };
200
+ }
201
+ const ledger = ledgerJobIds(input.projectRoot, input.sessionId);
202
+ if (ledger.length > 0) {
203
+ return {
204
+ allow: false,
205
+ verdict: {
206
+ kind: 'block-no-decision-with-ledger',
207
+ ledgerJobIds: ledger,
208
+ reason: noDecisionWithLedgerReason(ledger)
209
+ },
210
+ nextSliceLine: null
211
+ };
212
+ }
213
+ return {
214
+ allow: true,
215
+ verdict: {
216
+ kind: 'allow-no-decision-recorded',
217
+ promptSource,
218
+ reason: 'No Job-shape decision was recorded for this session and no Job ledger exists, ' +
219
+ 'so this gate has no Job-shape judgement to report. It allows, and names the ' +
220
+ 'absence of the decision rather than claiming the prompt is not Job-shaped.'
221
+ },
222
+ nextSliceLine: null
223
+ };
224
+ }
@@ -0,0 +1,7 @@
1
+ import type { ModelProviderConfig, PeaksConfig, ProviderModelConfig, TokenConfig, WorkspaceConfig } from './config-types.js';
2
+ export declare function toWorkspaceConfigs(value: unknown): WorkspaceConfig[];
3
+ export declare function toProviderModelConfig(value: unknown): ProviderModelConfig;
4
+ export declare function toTokenConfig(value: unknown): TokenConfig;
5
+ export declare function toModelProviderConfig(value: unknown): ModelProviderConfig;
6
+ export declare function inferHumanLanguage(value: string): string;
7
+ export declare function toPeaksConfig(value: unknown): Partial<PeaksConfig>;