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,105 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, readFileSync } from 'node:fs';
3
+ import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
4
+ import { addJsonOption, printResult } from '../cli-helpers.js';
5
+ import { atomicWriteJson } from '../../services/ide/shared/atomic-json.js';
6
+ import { containerLeaseFilePath, deserializeContainerLease, markContainerReleased } from '../../services/container/container-lease.js';
7
+ import { detectContainerRuntime, joinPathSession, resolveContainerTarget } from './container-command-shared.js';
8
+ export function registerContainerReleaseCommand(cmd, io) {
9
+ addJsonOption(cmd
10
+ .command('release')
11
+ .description('Transition a container lease to released and run `docker rm --force`. Idempotent on already-released leases.')
12
+ .requiredOption('--lease-id <id>', 'lease id returned by `peaks container spawn`')
13
+ .option('--session <sid>', 'override session id')
14
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runContainerRelease(io, options));
15
+ }
16
+ /** Read + parse the lease file; `null` once the refusal is emitted. */
17
+ function readLease(io, options, file) {
18
+ if (!existsSync(file)) {
19
+ printResult(io, fail('container.release', 'LEASE_NOT_FOUND', `no lease on disk at ${file}`, {
20
+ leaseId: options.leaseId,
21
+ file
22
+ }, [
23
+ 'Run `peaks container list` to inspect active leases.',
24
+ 'For a never-spawned lease, this is a no-op — no further action needed.'
25
+ ]), options.json);
26
+ process.exitCode = 1;
27
+ return null;
28
+ }
29
+ try {
30
+ return deserializeContainerLease(readFileSync(file, 'utf8'));
31
+ }
32
+ catch (err) {
33
+ printResult(io, fail('container.release', 'LEASE_FILE_INVALID', getErrorMessage(err), {
34
+ leaseId: options.leaseId,
35
+ file
36
+ }, [
37
+ 'Delete the malformed lease file manually and re-issue spawn.',
38
+ 'For security, release never fails open on a malformed lease.'
39
+ ]), options.json);
40
+ process.exitCode = 1;
41
+ return null;
42
+ }
43
+ }
44
+ /** `docker rm --force`, tolerating a container that is already gone. */
45
+ function removeContainer(lease, projectRoot) {
46
+ try {
47
+ const detected = detectContainerRuntime(undefined);
48
+ const runtimeCmd = detected.ok ? detected.runtime : 'docker';
49
+ execSync(`${runtimeCmd} rm --force "${lease.containerId}"`, {
50
+ cwd: projectRoot,
51
+ stdio: 'pipe',
52
+ encoding: 'utf8',
53
+ windowsHide: true
54
+ });
55
+ return false;
56
+ }
57
+ catch {
58
+ return true;
59
+ }
60
+ }
61
+ function runContainerRelease(io, options) {
62
+ const { projectRoot, sessionId } = resolveContainerTarget(options);
63
+ try {
64
+ const file = containerLeaseFilePath(joinPathSession(projectRoot, sessionId), options.leaseId);
65
+ const lease = readLease(io, options, file);
66
+ if (lease === null)
67
+ return;
68
+ if (lease.status === 'released') {
69
+ printResult(io, ok('container.release', { lease, sessionId, projectRoot, alreadyReleased: true }, [], [`Lease ${lease.leaseId} already released; nothing to do.`]), options.json);
70
+ return;
71
+ }
72
+ const outcome = releaseLease({ options, io, projectRoot, sessionId, file, lease });
73
+ printResult(io, ok('container.release', outcome.data, outcome.warnings, outcome.nextActions), options.json);
74
+ }
75
+ catch (err) {
76
+ printResult(io, fail('container.release', 'RELEASE_FAILED', getErrorMessage(err), {
77
+ leaseId: options.leaseId,
78
+ sessionId
79
+ }, ['Verify the lease id and re-run.', 'If the lease was never spawned, no-op.']), options.json);
80
+ process.exitCode = 1;
81
+ }
82
+ }
83
+ /**
84
+ * `docker rm --force` the container, flip the lease to released and write it
85
+ * back. A failed `docker rm` is reported, not fatal: the lease is the source
86
+ * of truth and it is still marked released.
87
+ */
88
+ function releaseLease(plan) {
89
+ const { projectRoot, sessionId, file, lease } = plan;
90
+ const dockerRmFailed = removeContainer(lease, projectRoot);
91
+ const released = markContainerReleased(lease);
92
+ atomicWriteJson(file, released);
93
+ return {
94
+ data: { lease: released, sessionId, projectRoot, dockerRmFailed },
95
+ warnings: dockerRmFailed
96
+ ? ['docker rm failed (likely the container was already removed); lease marked released.']
97
+ : [],
98
+ nextActions: [
99
+ `Lease ${lease.leaseId} marked released.`,
100
+ dockerRmFailed
101
+ ? 'Manual `docker ps -a` + `docker rm` may be needed.'
102
+ : `Container ${lease.containerId} removed.`
103
+ ]
104
+ };
105
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function registerContainerSpawnCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,148 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { readFileSync } from 'node:fs';
3
+ import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
4
+ import { addJsonOption, printResult } from '../cli-helpers.js';
5
+ import { atomicWriteJson } from '../../services/ide/shared/atomic-json.js';
6
+ import { normalizePath } from '../../shared/path-utils.js';
7
+ import { containerLeaseFilePath, finalizeContainerLease, generateContainerLeaseId, ttlForContainerRole } from '../../services/container/container-lease.js';
8
+ import { DEFAULT_DOCKER_IMAGE, detectContainerRuntime, joinPathSession, resolveContainerTarget } from './container-command-shared.js';
9
+ export function registerContainerSpawnCommand(cmd, io) {
10
+ addJsonOption(cmd
11
+ .command('spawn')
12
+ .description('Spawn a container via `docker run` and write a container lease. ' +
13
+ 'The lease is the source of truth for the L4 PreToolUse gate (Part 12 follow-up). ' +
14
+ 'Default TTL is role-aware (rd=30m / qa=15m / ui=1h); pass --ttl <ms> to override. ' +
15
+ 'Default image is `node:22-slim`; pass --image <name> to override.')
16
+ .requiredOption('--rid <rid>', 'peaks request id the lease is associated with')
17
+ .requiredOption('--role <role>', 'sub-agent role (rd | qa | ui | sc | prd | general-purpose)')
18
+ .requiredOption('--purpose <text>', 'why this container was spawned (audit log)')
19
+ .option('--image <name>', `container image (default ${DEFAULT_DOCKER_IMAGE})`)
20
+ .option('--ttl <ms>', 'time-to-live in ms (default role-aware; override with positive number)')
21
+ .option('--mount <path>', 'host path to mount as the container working dir (default: <projectRoot>)')
22
+ .option('--session <sid>', 'override session id')
23
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runContainerSpawn(io, options));
24
+ }
25
+ /** The `--runtime` flag, narrowed to the two runtimes the adapter supports. */
26
+ function explicitRuntimeOf(options) {
27
+ if (options.runtime === 'docker')
28
+ return 'docker';
29
+ if (options.runtime === 'podman')
30
+ return 'podman';
31
+ return undefined;
32
+ }
33
+ /** Refuse `--runtime` when neither binary answers; `null` once refused. */
34
+ function requireRuntime(options, io, projectRoot, sessionId) {
35
+ const detected = detectContainerRuntime(explicitRuntimeOf(options));
36
+ if (detected.ok)
37
+ return detected;
38
+ printResult(io, fail('container.spawn', 'CONTAINER_RUNTIME_UNAVAILABLE', `${detected.stderr}: ${detected.hint}`, { rid: options.rid, role: options.role, sessionId }, [
39
+ 'Install docker (Docker Desktop on macOS / Windows) or podman (RHEL / Fedora).',
40
+ 'On Windows, ensure WSL2 backend is enabled and the daemon is running.',
41
+ 'Pass --runtime docker|podman to force a specific runtime.'
42
+ ]), options.json);
43
+ process.exitCode = 1;
44
+ return null;
45
+ }
46
+ /** Resolve `--ttl`, refusing a non-positive integer; `null` once refused. */
47
+ function requireTtl(options, io) {
48
+ const ttlMs = options.ttl === undefined
49
+ ? ttlForContainerRole(options.role)
50
+ : Number.parseInt(options.ttl, 10);
51
+ if (Number.isInteger(ttlMs) && ttlMs > 0)
52
+ return ttlMs;
53
+ printResult(io, fail('container.spawn', 'INVALID_TTL', '--ttl must be a positive integer (ms)', { ttl: options.ttl }, ['Re-run with --ttl 1800000 (30 min) or omit to use role default.']), options.json);
54
+ process.exitCode = 1;
55
+ return null;
56
+ }
57
+ /** The worker root the cidfile lives in; `normalizePath` keeps Windows paths sane. */
58
+ function cidFileFor(plan) {
59
+ const root = normalizePath(joinPathSession(plan.projectRoot, plan.sessionId));
60
+ return `${root}/.${plan.detected.runtime}-cid-${plan.leaseId}`;
61
+ }
62
+ /**
63
+ * `docker run --rm -d` so the container is detached and auto-removed when
64
+ * stopped; `--cidfile` writes the container id to a file we read back. The
65
+ * `--label peaks.leaseId=<id>` lets `peaks container list` / `peaks container gc`
66
+ * find orphans by label when the lease file is missing.
67
+ *
68
+ * Returns the container id, or `null` once DOCKER_RUN_FAILED is emitted.
69
+ */
70
+ function runDockerSpawn(plan) {
71
+ const { options, io, projectRoot, detected, image, mount } = plan;
72
+ const cidFile = cidFileFor(plan);
73
+ try {
74
+ execSync(`${detected.runtime} run --rm -d --cidfile "${cidFile}" --label "peaks.leaseId=${plan.leaseId}" --label "peaks.rid=${options.rid}" -v "${mount}:/work" -w /work ${image} sleep infinity`, { cwd: projectRoot, stdio: 'pipe', encoding: 'utf8', windowsHide: true });
75
+ }
76
+ catch (err) {
77
+ printResult(io, fail('container.spawn', 'DOCKER_RUN_FAILED', getErrorMessage(err), { rid: options.rid, image, runtime: detected.runtime, sessionId: plan.sessionId }, [
78
+ 'Verify the image name is reachable on the configured registry.',
79
+ 'Verify the host path is mounted correctly (Windows: the path must be visible to WSL2).',
80
+ `Run \`${detected.runtime} ps -a\` to inspect any leftover containers with the peaks.leaseId label.`
81
+ ]), options.json);
82
+ process.exitCode = 1;
83
+ return null;
84
+ }
85
+ return readFileSync(cidFile, 'utf8').trim();
86
+ }
87
+ /** Write the lease and print the success envelope. */
88
+ function finishSpawn(plan, containerId) {
89
+ const { options, io, projectRoot, sessionId, detected, image, mount, leaseId, now, ttlMs } = plan;
90
+ const lease = finalizeContainerLease({
91
+ leaseId,
92
+ rid: options.rid,
93
+ role: options.role,
94
+ path: mount,
95
+ image,
96
+ containerId,
97
+ createdAt: now,
98
+ expiresAt: now + ttlMs,
99
+ purpose: options.purpose
100
+ });
101
+ atomicWriteJson(containerLeaseFilePath(joinPathSession(projectRoot, sessionId), leaseId), lease);
102
+ printResult(io, ok('container.spawn', {
103
+ lease,
104
+ sessionId,
105
+ projectRoot,
106
+ runtime: detected.runtime,
107
+ runtimeVersion: detected.binary,
108
+ nextActions: [
109
+ `Container id: ${containerId}`,
110
+ `Image: ${image}`,
111
+ `Lease expires at: ${new Date(lease.expiresAt).toISOString()}`,
112
+ 'Run `peaks container release --lease-id <id>` when done'
113
+ ]
114
+ }, [], []), options.json);
115
+ }
116
+ function runContainerSpawn(io, options) {
117
+ const { projectRoot, sessionId } = resolveContainerTarget(options);
118
+ try {
119
+ const detected = requireRuntime(options, io, projectRoot, sessionId);
120
+ if (detected === null)
121
+ return;
122
+ const ttlMs = requireTtl(options, io);
123
+ if (ttlMs === null)
124
+ return;
125
+ const plan = {
126
+ options,
127
+ io,
128
+ projectRoot,
129
+ sessionId,
130
+ detected,
131
+ image: options.image ?? DEFAULT_DOCKER_IMAGE,
132
+ mount: options.mount ?? projectRoot,
133
+ leaseId: generateContainerLeaseId(),
134
+ now: Date.now(),
135
+ ttlMs
136
+ };
137
+ const containerId = runDockerSpawn(plan);
138
+ if (containerId === null)
139
+ return;
140
+ finishSpawn(plan, containerId);
141
+ }
142
+ catch (err) {
143
+ printResult(io, fail('container.spawn', 'SPAWN_FAILED', getErrorMessage(err), { rid: options.rid, sessionId }, [
144
+ 'See error message; if the lease was not written, retry after fixing the underlying issue.'
145
+ ]), options.json);
146
+ process.exitCode = 1;
147
+ }
148
+ }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function registerContextCheckCommand(context: Command, io: ProgramIO): void;
@@ -0,0 +1,81 @@
1
+ import { fail, ok } from 'peaks-loop-shared/result';
2
+ import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
3
+ import { formatMainSessionTriggerLogLine, pickMainSessionTrigger } from '../../services/context/main-session-monitor.js';
4
+ import { emitObservabilityEvent } from '../../services/observability/observability-service.js';
5
+ import { findProjectRoot } from '../../services/config/config-safety.js';
6
+ import { getSessionIdCanonical } from '../../services/session/session-manager.js';
7
+ import { capacityOf, requirePromptSize } from './context-status-command.js';
8
+ /** The `--in-flight-batch` seam: a sub-agent batch defers the trigger (D6.e). */
9
+ function inFlightOf(opts) {
10
+ return opts.inFlightBatch === true
11
+ ? { hasInFlightBatch: true, sharedChannelEntries: 1 }
12
+ : undefined;
13
+ }
14
+ /**
15
+ * Observability hook #5/7. Fire-and-forget per PRD Q4; the synchronous emit
16
+ * never throws. Only fires when a session id is resolvable.
17
+ */
18
+ function emitContextTrigger(trigger, promptSize) {
19
+ const projectRoot = findProjectRoot(process.cwd()) ?? process.cwd();
20
+ const sid = getSessionIdCanonical(projectRoot) ?? '';
21
+ if (sid.length === 0)
22
+ return;
23
+ emitObservabilityEvent({
24
+ schemaVersion: 1,
25
+ ts: new Date().toISOString(),
26
+ sessionId: sid,
27
+ category: 'context-trigger',
28
+ detail: {
29
+ kind: trigger.kind,
30
+ promptSize,
31
+ ...(trigger.kind === 'soft-warn' || trigger.kind === 'compact'
32
+ ? { ratio: trigger.ratio }
33
+ : {})
34
+ }
35
+ }, { projectRoot });
36
+ }
37
+ /** The single advisory line the tier decides. */
38
+ function triggerAdvice(trigger) {
39
+ if (trigger.kind === 'compact') {
40
+ return `Tier reached → trigger ${trigger.path} on ${trigger.ide} (code=${trigger.code})`;
41
+ }
42
+ if (trigger.kind === 'defer')
43
+ return `Deferred: ${trigger.reason}`;
44
+ if (trigger.kind === 'soft-warn') {
45
+ return `Soft warning at ${(trigger.ratio * 100).toFixed(0)}% (no trigger yet)`;
46
+ }
47
+ return 'Below threshold; no trigger';
48
+ }
49
+ export function registerContextCheckCommand(context, io) {
50
+ addJsonOption(context
51
+ .command('check')
52
+ .description('v2.11.0 D6: threshold check + IDE-aware trigger dispatch. With --auto-trigger, returns the trigger path the LLM should follow; without, returns a dry-run recommendation. The LLM is responsible for actually invoking the trigger (slash command, self-compress, or escalation).')
53
+ .requiredOption('--prompt-size <bytes>', 'estimated prompt size in bytes')
54
+ .option('--capacity <bytes>', 'override the 256K default capacity (test seam)', '262144')
55
+ .option('--in-flight-batch', 'a sub-agent batch is in flight (defer trigger per D6.e)', false)
56
+ .option('--auto-trigger', 'return the trigger path the LLM should follow', false)).action((opts) => {
57
+ try {
58
+ const promptSize = requirePromptSize('context.check', opts, io);
59
+ if (promptSize === null)
60
+ return;
61
+ const trigger = pickMainSessionTrigger({
62
+ promptSize,
63
+ capacityBytes: capacityOf(opts),
64
+ inFlightBatch: inFlightOf(opts)
65
+ });
66
+ emitContextTrigger(trigger, promptSize);
67
+ const payload = {
68
+ ...trigger,
69
+ autoTrigger: opts.autoTrigger === true,
70
+ logLine: formatMainSessionTriggerLogLine(trigger, 'main')
71
+ };
72
+ printResult(io, ok('context.check', payload, [], [triggerAdvice(trigger)]), opts.json);
73
+ }
74
+ catch (err) {
75
+ printResult(io, fail('context.check', 'CONTEXT_CHECK_FAILED', getErrorMessage(err), null, [
76
+ 'Verify --prompt-size is a non-negative number'
77
+ ]), opts.json);
78
+ process.exitCode = 1;
79
+ }
80
+ });
81
+ }
@@ -1,11 +1,6 @@
1
1
  /**
2
2
  * peaks context * CLI (Slice #3 L1c) — context 4-layer loader.
3
3
  *
4
- * - L0: full read (every SKILL.md in full)
5
- * - L1: summary (one paragraph per skill + the skill list)
6
- * - L2: index (just names + paths)
7
- * - L3: fuzzy search by query (delegates to peaks memory search)
8
- *
9
4
  * The LLM-side UX layer (peaks-code / peaks-ide) picks the layer based
10
5
  * on the L1a task level:
11
6
  * - typo: L0 only (a few lines)
@@ -15,6 +10,6 @@
15
10
  * - migration: L0 + L1 + L2 + L3 + codegraph
16
11
  */
17
12
  import type { Command } from 'commander';
18
- import { type ProgramIO } from '../cli-helpers.js';
19
- export type ContextLayer = 'L0' | 'L1' | 'L2' | 'L3';
13
+ import type { ProgramIO } from '../cli-helpers.js';
14
+ export type { ContextLayer } from './context-layer-fetchers.js';
20
15
  export declare function registerContextCommands(program: Command, io: ProgramIO): void;
@@ -1,281 +1,11 @@
1
- /**
2
- * peaks context * CLI (Slice #3 L1c) — context 4-layer loader.
3
- *
4
- * - L0: full read (every SKILL.md in full)
5
- * - L1: summary (one paragraph per skill + the skill list)
6
- * - L2: index (just names + paths)
7
- * - L3: fuzzy search by query (delegates to peaks memory search)
8
- *
9
- * The LLM-side UX layer (peaks-code / peaks-ide) picks the layer based
10
- * on the L1a task level:
11
- * - typo: L0 only (a few lines)
12
- * - bug: L0 + L1
13
- * - feature: L0 + L1 + L2 + L3(按需)
14
- * - refactor: L0 + L1 + L2 + L3
15
- * - migration: L0 + L1 + L2 + L3 + codegraph
16
- */
17
- import { existsSync, readFileSync, readdirSync } from 'node:fs';
18
- import { join } from 'node:path';
19
- import { searchMemory } from '../../services/memory/memory-search-service.js';
20
- import { addJsonOption, getErrorMessage, printResult } from '../cli-helpers.js';
21
- import { fail, ok } from 'peaks-loop-shared/result';
22
- import { emitObservabilityEvent } from '../../services/observability/observability-service.js';
23
- import { findProjectRoot } from '../../services/config/config-safety.js';
24
- import { getSessionIdCanonical } from '../../services/session/session-manager.js';
25
- import { evaluateMainSessionThreshold, pickMainSessionTrigger, formatMainSessionTriggerLogLine } from '../../services/context/main-session-monitor.js';
26
- import { detectIdeFromEnv } from '../../services/context/ide-detect.js';
27
- const SKILLS_DIR = 'skills';
28
- function readSkillsDir(projectRoot) {
29
- const skillsRoot = join(projectRoot, SKILLS_DIR);
30
- if (!existsSync(skillsRoot))
31
- return [];
32
- const out = [];
33
- for (const entry of readdirSync(skillsRoot, { withFileTypes: true })) {
34
- if (!entry.isDirectory() || entry.name.startsWith('.'))
35
- continue;
36
- const skillMd = join(skillsRoot, entry.name, 'SKILL.md');
37
- if (existsSync(skillMd)) {
38
- out.push(`skills/${entry.name}/SKILL.md`);
39
- }
40
- }
41
- return out;
42
- }
43
- function readSkillFile(projectRoot, relPath) {
44
- const abs = join(projectRoot, relPath);
45
- try {
46
- return readFileSync(abs, 'utf-8');
47
- }
48
- catch {
49
- return '';
50
- }
51
- }
52
- async function fetchL0(projectRoot) {
53
- const files = readSkillsDir(projectRoot);
54
- const warnings = [];
55
- let content = '';
56
- let byteSize = 0;
57
- const sizes = [];
58
- for (const rel of files) {
59
- const body = readSkillFile(projectRoot, rel);
60
- if (body.length === 0) {
61
- warnings.push(`failed to read ${rel}`);
62
- continue;
63
- }
64
- content += `## ${rel}\n\n${body}\n\n`;
65
- sizes.push({ path: rel, bytes: body.length });
66
- byteSize += body.length;
67
- }
68
- return {
69
- layer: 'L0',
70
- description: 'full read: every SKILL.md concatenated',
71
- files: sizes,
72
- content,
73
- byteSize,
74
- warnings
75
- };
76
- }
77
- async function fetchL1(projectRoot) {
78
- const files = readSkillsDir(projectRoot);
79
- const warnings = [];
80
- let content = '';
81
- let byteSize = 0;
82
- const sizes = [];
83
- for (const rel of files) {
84
- const body = readSkillFile(projectRoot, rel);
85
- if (body.length === 0) {
86
- warnings.push(`failed to read ${rel}`);
87
- continue;
88
- }
89
- const firstPara = body.split(/\r?\n\r?\n/, 2)[0] ?? body.slice(0, 400);
90
- content += `## ${rel}\n\n${firstPara}\n\n`;
91
- sizes.push({ path: rel, bytes: firstPara.length });
92
- byteSize += firstPara.length;
93
- }
94
- return {
95
- layer: 'L1',
96
- description: 'summary: first paragraph per skill',
97
- files: sizes,
98
- content,
99
- byteSize,
100
- warnings
101
- };
102
- }
103
- async function fetchL2(projectRoot) {
104
- const files = readSkillsDir(projectRoot);
105
- const content = files.map((f) => `- ${f}`).join('\n') + '\n';
106
- const byteSize = content.length;
107
- return {
108
- layer: 'L2',
109
- description: 'index: skill paths only (no body)',
110
- files: files.map((f) => ({ path: f, bytes: 0 })),
111
- content,
112
- byteSize,
113
- warnings: []
114
- };
115
- }
116
- async function fetchL3(projectRoot, query) {
117
- const warnings = [];
118
- if (query.trim().length === 0) {
119
- warnings.push('empty query; L3 requires a --query string for fuzzy search');
120
- return {
121
- layer: 'L3',
122
- description: 'fuzzy search (empty query)',
123
- files: [],
124
- content: '',
125
- byteSize: 0,
126
- warnings
127
- };
128
- }
129
- try {
130
- const hits = searchMemory({ projectRoot, query, limit: 10 });
131
- const lines = [];
132
- for (const hit of hits) {
133
- lines.push(`- [${hit.score.toFixed(2)}] ${hit.sourcePath}: ${hit.description.slice(0, 120)}`);
134
- }
135
- const content = lines.join('\n') + '\n';
136
- return {
137
- layer: 'L3',
138
- description: 'fuzzy search: top 10 hits from memory index',
139
- files: hits.map((h) => ({ path: h.sourcePath, bytes: h.description.length })),
140
- content,
141
- byteSize: content.length,
142
- warnings
143
- };
144
- }
145
- catch (error) {
146
- return {
147
- layer: 'L3',
148
- description: 'fuzzy search (failed)',
149
- files: [],
150
- content: '',
151
- byteSize: 0,
152
- warnings: [`L3 search failed: ${getErrorMessage(error)}`]
153
- };
154
- }
155
- }
1
+ import { registerContextCheckCommand } from './context-check-command.js';
2
+ import { registerContextLayerCommand } from './context-layer-command.js';
3
+ import { registerContextStatusCommand } from './context-status-command.js';
156
4
  export function registerContextCommands(program, io) {
157
5
  const context = program
158
6
  .command('context')
159
7
  .description('Slice L1c: context 4-layer loader (L0 full / L1 summary / L2 index / L3 fuzzy)');
160
- addJsonOption(context
161
- .command('layer')
162
- .description('Fetch a context layer (L0 = full SKILL.md; L1 = first paragraph; L2 = index; L3 = fuzzy search by --query)')
163
- .requiredOption('--project <path>', 'target project root')
164
- .requiredOption('--level <L0|L1|L2|L3>', 'context layer to load')
165
- .option('--query <text>', 'fuzzy search query (required for L3)')).action(async (options) => {
166
- try {
167
- const level = options.level;
168
- if (level !== 'L0' && level !== 'L1' && level !== 'L2' && level !== 'L3') {
169
- printResult(io, fail('context.layer', 'INVALID_LEVEL', `level must be one of L0, L1, L2, L3 (got ${level})`, { provided: level }, ['Pass --level L0|L1|L2|L3']), options.json);
170
- process.exitCode = 1;
171
- return;
172
- }
173
- let payload;
174
- if (level === 'L0')
175
- payload = await fetchL0(options.project);
176
- else if (level === 'L1')
177
- payload = await fetchL1(options.project);
178
- else if (level === 'L2')
179
- payload = await fetchL2(options.project);
180
- else
181
- payload = await fetchL3(options.project, options.query ?? '');
182
- printResult(io, ok('context.layer', payload, [], [
183
- `${payload.layer} loaded: ${payload.byteSize} bytes across ${payload.files.length} file(s)`,
184
- payload.warnings.length > 0
185
- ? `${payload.warnings.length} warning(s); see envelope.warnings`
186
- : null
187
- ].filter((x) => typeof x === 'string')), options.json);
188
- }
189
- catch (error) {
190
- printResult(io, fail('context.layer', 'CONTEXT_LAYER_FAILED', getErrorMessage(error), { projectRoot: options.project }, ['Verify the project path and --level value']), options.json);
191
- process.exitCode = 1;
192
- }
193
- });
194
- addJsonOption(context
195
- .command('status')
196
- .description('v2.11.0 D6: report main-session threshold tier for a given prompt size (no trigger dispatched). Useful for `--json` probes before invoking `peaks context check --auto-trigger`.')
197
- .requiredOption('--prompt-size <bytes>', 'estimated prompt size in bytes')
198
- .option('--capacity <bytes>', 'override the 256K default capacity (test seam)', '262144')).action((opts) => {
199
- try {
200
- const promptSize = Number(opts.promptSize);
201
- const capacity = opts.capacity !== undefined ? Number(opts.capacity) : undefined;
202
- if (!Number.isFinite(promptSize) || promptSize < 0) {
203
- printResult(io, fail('context.status', 'INVALID_PROMPT_SIZE', `prompt-size must be a non-negative number (got "${opts.promptSize}")`, { provided: opts.promptSize }, ['Pass --prompt-size <bytes>']), opts.json);
204
- process.exitCode = 1;
205
- return;
206
- }
207
- const evaluation = evaluateMainSessionThreshold(promptSize, capacity);
208
- printResult(io, ok('context.status', { ...evaluation, ide: detectIdeFromEnv() }, [...evaluation.warnings], [`Main-session tier=${evaluation.tier} (${(evaluation.ratio * 100).toFixed(0)}%)`]), opts.json);
209
- }
210
- catch (err) {
211
- printResult(io, fail('context.status', 'CONTEXT_STATUS_FAILED', getErrorMessage(err), null, [
212
- 'Verify --prompt-size is a non-negative number'
213
- ]), opts.json);
214
- process.exitCode = 1;
215
- }
216
- });
217
- addJsonOption(context
218
- .command('check')
219
- .description('v2.11.0 D6: threshold check + IDE-aware trigger dispatch. With --auto-trigger, returns the trigger path the LLM should follow; without, returns a dry-run recommendation. The LLM is responsible for actually invoking the trigger (slash command, self-compress, or escalation).')
220
- .requiredOption('--prompt-size <bytes>', 'estimated prompt size in bytes')
221
- .option('--capacity <bytes>', 'override the 256K default capacity (test seam)', '262144')
222
- .option('--in-flight-batch', 'a sub-agent batch is in flight (defer trigger per D6.e)', false)
223
- .option('--auto-trigger', 'return the trigger path the LLM should follow', false)).action((opts) => {
224
- try {
225
- const promptSize = Number(opts.promptSize);
226
- const capacity = opts.capacity !== undefined ? Number(opts.capacity) : undefined;
227
- if (!Number.isFinite(promptSize) || promptSize < 0) {
228
- printResult(io, fail('context.check', 'INVALID_PROMPT_SIZE', `prompt-size must be a non-negative number (got "${opts.promptSize}")`, { provided: opts.promptSize }, ['Pass --prompt-size <bytes>']), opts.json);
229
- process.exitCode = 1;
230
- return;
231
- }
232
- const trigger = pickMainSessionTrigger({
233
- promptSize,
234
- capacityBytes: capacity,
235
- inFlightBatch: opts.inFlightBatch === true
236
- ? { hasInFlightBatch: true, sharedChannelEntries: 1 }
237
- : undefined
238
- });
239
- // Slice C of v2.11.1 — observability hook #5/7. Fire-and-forget
240
- // per PRD Q4. The synchronous emit never throws.
241
- const projectRoot = findProjectRoot(process.cwd()) ?? process.cwd();
242
- const sid = getSessionIdCanonical(projectRoot) ?? '';
243
- if (sid.length > 0) {
244
- emitObservabilityEvent({
245
- schemaVersion: 1,
246
- ts: new Date().toISOString(),
247
- sessionId: sid,
248
- category: 'context-trigger',
249
- detail: {
250
- kind: trigger.kind,
251
- promptSize,
252
- ...(trigger.kind === 'soft-warn' || trigger.kind === 'compact'
253
- ? { ratio: trigger.ratio }
254
- : {})
255
- }
256
- }, { projectRoot });
257
- }
258
- const logLine = formatMainSessionTriggerLogLine(trigger, 'main');
259
- const payload = {
260
- ...trigger,
261
- autoTrigger: opts.autoTrigger === true,
262
- logLine
263
- };
264
- printResult(io, ok('context.check', payload, [], [
265
- trigger.kind === 'compact'
266
- ? `Tier reached → trigger ${trigger.path} on ${trigger.ide} (code=${trigger.code})`
267
- : trigger.kind === 'defer'
268
- ? `Deferred: ${trigger.reason}`
269
- : trigger.kind === 'soft-warn'
270
- ? `Soft warning at ${(trigger.ratio * 100).toFixed(0)}% (no trigger yet)`
271
- : 'Below threshold; no trigger'
272
- ]), opts.json);
273
- }
274
- catch (err) {
275
- printResult(io, fail('context.check', 'CONTEXT_CHECK_FAILED', getErrorMessage(err), null, [
276
- 'Verify --prompt-size is a non-negative number'
277
- ]), opts.json);
278
- process.exitCode = 1;
279
- }
280
- });
8
+ registerContextLayerCommand(context, io);
9
+ registerContextStatusCommand(context, io);
10
+ registerContextCheckCommand(context, io);
281
11
  }
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ export declare function registerContextLayerCommand(context: Command, io: ProgramIO): void;