peaks-loop 4.1.3 → 4.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (402) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/CHANGELOG.md +56 -0
  3. package/README-en.md +1 -1
  4. package/README.md +1 -1
  5. package/dist/cli/commands/asset-command-shared.d.ts +12 -0
  6. package/dist/cli/commands/asset-command-shared.js +45 -0
  7. package/dist/cli/commands/asset-commands.d.ts +6 -1
  8. package/dist/cli/commands/asset-commands.js +11 -372
  9. package/dist/cli/commands/asset-crystallize-command.d.ts +3 -0
  10. package/dist/cli/commands/asset-crystallize-command.js +60 -0
  11. package/dist/cli/commands/asset-crystallize-payload.d.ts +47 -0
  12. package/dist/cli/commands/asset-crystallize-payload.js +85 -0
  13. package/dist/cli/commands/asset-crystallize-runner.d.ts +3 -0
  14. package/dist/cli/commands/asset-crystallize-runner.js +133 -0
  15. package/dist/cli/commands/asset-dispose-command.d.ts +3 -0
  16. package/dist/cli/commands/asset-dispose-command.js +99 -0
  17. package/dist/cli/commands/asset-status-command.d.ts +3 -0
  18. package/dist/cli/commands/asset-status-command.js +100 -0
  19. package/dist/cli/commands/baseline-audit-command.d.ts +3 -0
  20. package/dist/cli/commands/baseline-audit-command.js +64 -0
  21. package/dist/cli/commands/baseline-command-shared.d.ts +23 -0
  22. package/dist/cli/commands/baseline-command-shared.js +39 -0
  23. package/dist/cli/commands/baseline-commands.js +33 -313
  24. package/dist/cli/commands/baseline-freeze-commands.d.ts +4 -0
  25. package/dist/cli/commands/baseline-freeze-commands.js +81 -0
  26. package/dist/cli/commands/baseline-guard-command.d.ts +3 -0
  27. package/dist/cli/commands/baseline-guard-command.js +52 -0
  28. package/dist/cli/commands/baseline-read-commands.d.ts +5 -0
  29. package/dist/cli/commands/baseline-read-commands.js +72 -0
  30. package/dist/cli/commands/baseline-rollback-commands.d.ts +4 -0
  31. package/dist/cli/commands/baseline-rollback-commands.js +88 -0
  32. package/dist/cli/commands/classify-downgrade-command.d.ts +9 -0
  33. package/dist/cli/commands/classify-downgrade-command.js +21 -0
  34. package/dist/cli/commands/classify-run-command.d.ts +9 -0
  35. package/dist/cli/commands/classify-run-command.js +73 -0
  36. package/dist/cli/commands/classify-signals.d.ts +5 -0
  37. package/dist/cli/commands/classify-signals.js +104 -0
  38. package/dist/cli/commands/code-emit-handoff-command.js +40 -3
  39. package/dist/cli/commands/code-gate-step-08-command.js +25 -9
  40. package/dist/cli/commands/codegraph-command-options.d.ts +22 -0
  41. package/dist/cli/commands/codegraph-command-options.js +22 -0
  42. package/dist/cli/commands/codegraph-commands.d.ts +2 -2
  43. package/dist/cli/commands/codegraph-commands.js +14 -397
  44. package/dist/cli/commands/codegraph-config-restore-command.d.ts +3 -0
  45. package/dist/cli/commands/codegraph-config-restore-command.js +200 -0
  46. package/dist/cli/commands/codegraph-proxy-commands.d.ts +10 -0
  47. package/dist/cli/commands/codegraph-proxy-commands.js +159 -0
  48. package/dist/cli/commands/codegraph-repair-commands.d.ts +3 -0
  49. package/dist/cli/commands/codegraph-repair-commands.js +94 -0
  50. package/dist/cli/commands/codegraph-status-command.d.ts +1 -1
  51. package/dist/cli/commands/codegraph-status-command.js +27 -214
  52. package/dist/cli/commands/codegraph-status-integrity.d.ts +44 -0
  53. package/dist/cli/commands/codegraph-status-integrity.js +121 -0
  54. package/dist/cli/commands/codegraph-status-json.d.ts +5 -0
  55. package/dist/cli/commands/codegraph-status-json.js +127 -0
  56. package/dist/cli/commands/container-command-shared.d.ts +60 -0
  57. package/dist/cli/commands/container-command-shared.js +52 -0
  58. package/dist/cli/commands/container-commands.d.ts +1 -1
  59. package/dist/cli/commands/container-commands.js +4 -216
  60. package/dist/cli/commands/container-release-command.d.ts +3 -0
  61. package/dist/cli/commands/container-release-command.js +105 -0
  62. package/dist/cli/commands/container-spawn-command.d.ts +3 -0
  63. package/dist/cli/commands/container-spawn-command.js +148 -0
  64. package/dist/cli/commands/context-check-command.d.ts +3 -0
  65. package/dist/cli/commands/context-check-command.js +81 -0
  66. package/dist/cli/commands/context-commands.d.ts +2 -7
  67. package/dist/cli/commands/context-commands.js +6 -276
  68. package/dist/cli/commands/context-layer-command.d.ts +3 -0
  69. package/dist/cli/commands/context-layer-command.js +34 -0
  70. package/dist/cli/commands/context-layer-fetchers.d.ts +15 -0
  71. package/dist/cli/commands/context-layer-fetchers.js +162 -0
  72. package/dist/cli/commands/context-status-command.d.ts +17 -0
  73. package/dist/cli/commands/context-status-command.js +41 -0
  74. package/dist/cli/commands/contract-write-command.d.ts +3 -0
  75. package/dist/cli/commands/contract-write-command.js +144 -0
  76. package/dist/cli/commands/core/doctor-bindings.d.ts +17 -0
  77. package/dist/cli/commands/core/doctor-bindings.js +30 -0
  78. package/dist/cli/commands/core/doctor-command.d.ts +4 -18
  79. package/dist/cli/commands/core/doctor-command.js +2 -323
  80. package/dist/cli/commands/core/doctor-logs.d.ts +8 -0
  81. package/dist/cli/commands/core/doctor-logs.js +32 -0
  82. package/dist/cli/commands/core/doctor-probes.d.ts +3 -0
  83. package/dist/cli/commands/core/doctor-probes.js +55 -0
  84. package/dist/cli/commands/core/doctor-run-command.d.ts +12 -0
  85. package/dist/cli/commands/core/doctor-run-command.js +172 -0
  86. package/dist/cli/commands/core/doctor-summary.d.ts +7 -0
  87. package/dist/cli/commands/core/doctor-summary.js +39 -0
  88. package/dist/cli/commands/core/memory-command-shared.d.ts +25 -0
  89. package/dist/cli/commands/core/memory-command-shared.js +20 -0
  90. package/dist/cli/commands/core/memory-command.d.ts +1 -1
  91. package/dist/cli/commands/core/memory-command.js +6 -227
  92. package/dist/cli/commands/core/memory-delegated-verbs.d.ts +4 -0
  93. package/dist/cli/commands/core/memory-delegated-verbs.js +178 -0
  94. package/dist/cli/commands/core/memory-extract-command.d.ts +3 -0
  95. package/dist/cli/commands/core/memory-extract-command.js +90 -0
  96. package/dist/cli/commands/core/memory-sync-command.d.ts +3 -0
  97. package/dist/cli/commands/core/memory-sync-command.js +38 -0
  98. package/dist/cli/commands/core/session-command.d.ts +1 -1
  99. package/dist/cli/commands/core/session-command.js +12 -206
  100. package/dist/cli/commands/core/session-info-command.d.ts +3 -0
  101. package/dist/cli/commands/core/session-info-command.js +142 -0
  102. package/dist/cli/commands/core/session-verb-commands.d.ts +5 -0
  103. package/dist/cli/commands/core/session-verb-commands.js +58 -0
  104. package/dist/cli/commands/core/standards-command.d.ts +1 -24
  105. package/dist/cli/commands/core/standards-command.js +33 -201
  106. package/dist/cli/commands/core/standards-init-command.d.ts +3 -0
  107. package/dist/cli/commands/core/standards-init-command.js +87 -0
  108. package/dist/cli/commands/core/standards-lint.d.ts +24 -0
  109. package/dist/cli/commands/core/standards-lint.js +57 -0
  110. package/dist/cli/commands/core/standards-migrate-command.d.ts +3 -0
  111. package/dist/cli/commands/core/standards-migrate-command.js +57 -0
  112. package/dist/cli/commands/cron-scheduler-commands.d.ts +5 -1
  113. package/dist/cli/commands/cron-scheduler-commands.js +36 -206
  114. package/dist/cli/commands/cron-scheduler-run-once-command.d.ts +7 -0
  115. package/dist/cli/commands/cron-scheduler-run-once-command.js +35 -0
  116. package/dist/cli/commands/cron-scheduler-shared.d.ts +6 -0
  117. package/dist/cli/commands/cron-scheduler-shared.js +48 -0
  118. package/dist/cli/commands/cron-scheduler-start-command.d.ts +7 -0
  119. package/dist/cli/commands/cron-scheduler-start-command.js +65 -0
  120. package/dist/cli/commands/cron-scheduler-status-command.d.ts +7 -0
  121. package/dist/cli/commands/cron-scheduler-status-command.js +46 -0
  122. package/dist/cli/commands/cron-scheduler-stop-command.d.ts +7 -0
  123. package/dist/cli/commands/cron-scheduler-stop-command.js +61 -0
  124. package/dist/cli/commands/dispatch-dag-envelope.d.ts +41 -0
  125. package/dist/cli/commands/dispatch-dag-envelope.js +49 -0
  126. package/dist/cli/commands/dispatch-dag-failure.d.ts +18 -0
  127. package/dist/cli/commands/dispatch-dag-failure.js +16 -0
  128. package/dist/cli/commands/dispatch-dag-preflight.d.ts +51 -0
  129. package/dist/cli/commands/dispatch-dag-preflight.js +105 -0
  130. package/dist/cli/commands/dispatch-dag-runners.d.ts +48 -0
  131. package/dist/cli/commands/dispatch-dag-runners.js +73 -0
  132. package/dist/cli/commands/dispatch-from-dag.d.ts +27 -0
  133. package/dist/cli/commands/dispatch-from-dag.js +87 -257
  134. package/dist/cli/commands/final-review-command-envelopes.d.ts +44 -0
  135. package/dist/cli/commands/final-review-command-envelopes.js +100 -0
  136. package/dist/cli/commands/final-review-command-shared.d.ts +52 -0
  137. package/dist/cli/commands/final-review-command-shared.js +35 -0
  138. package/dist/cli/commands/final-review-commands.d.ts +7 -27
  139. package/dist/cli/commands/final-review-commands.js +13 -240
  140. package/dist/cli/commands/final-review-prepare-command.d.ts +3 -0
  141. package/dist/cli/commands/final-review-prepare-command.js +200 -0
  142. package/dist/cli/commands/governance-classify-contract-commands.d.ts +23 -9
  143. package/dist/cli/commands/governance-classify-contract-commands.js +26 -269
  144. package/dist/cli/commands/hooks-command-shared.d.ts +42 -0
  145. package/dist/cli/commands/hooks-command-shared.js +32 -0
  146. package/dist/cli/commands/hooks-commands.d.ts +20 -0
  147. package/dist/cli/commands/hooks-commands.js +75 -309
  148. package/dist/cli/commands/hooks-install-envelopes.d.ts +6 -0
  149. package/dist/cli/commands/hooks-install-envelopes.js +144 -0
  150. package/dist/cli/commands/hooks-status-command.d.ts +3 -0
  151. package/dist/cli/commands/hooks-status-command.js +93 -0
  152. package/dist/cli/commands/hooks-uninstall-command.d.ts +3 -0
  153. package/dist/cli/commands/hooks-uninstall-command.js +43 -0
  154. package/dist/cli/commands/loop-command-shared.d.ts +31 -0
  155. package/dist/cli/commands/loop-command-shared.js +15 -0
  156. package/dist/cli/commands/loop-commands.d.ts +12 -17
  157. package/dist/cli/commands/loop-commands.js +56 -238
  158. package/dist/cli/commands/loop-export-command.d.ts +3 -0
  159. package/dist/cli/commands/loop-export-command.js +73 -0
  160. package/dist/cli/commands/loop-goal-compose-command.d.ts +3 -0
  161. package/dist/cli/commands/loop-goal-compose-command.js +36 -0
  162. package/dist/cli/commands/loop-import-command.d.ts +3 -0
  163. package/dist/cli/commands/loop-import-command.js +86 -0
  164. package/dist/cli/commands/loop-placeholder-commands.d.ts +3 -0
  165. package/dist/cli/commands/loop-placeholder-commands.js +52 -0
  166. package/dist/cli/commands/memory-command-shared.d.ts +59 -0
  167. package/dist/cli/commands/memory-command-shared.js +39 -0
  168. package/dist/cli/commands/memory-commands.d.ts +6 -79
  169. package/dist/cli/commands/memory-commands.js +19 -309
  170. package/dist/cli/commands/memory-ingest-command.d.ts +3 -0
  171. package/dist/cli/commands/memory-ingest-command.js +50 -0
  172. package/dist/cli/commands/memory-list-command.d.ts +16 -0
  173. package/dist/cli/commands/memory-list-command.js +129 -0
  174. package/dist/cli/commands/memory-reindex-command.d.ts +9 -0
  175. package/dist/cli/commands/memory-reindex-command.js +78 -0
  176. package/dist/cli/commands/memory-rotate-command.d.ts +3 -0
  177. package/dist/cli/commands/memory-rotate-command.js +55 -0
  178. package/dist/cli/commands/memory-search-command.d.ts +7 -0
  179. package/dist/cli/commands/memory-search-command.js +46 -0
  180. package/dist/cli/commands/openspec-archive-command.d.ts +3 -0
  181. package/dist/cli/commands/openspec-archive-command.js +55 -0
  182. package/dist/cli/commands/openspec-command-shared.d.ts +62 -0
  183. package/dist/cli/commands/openspec-command-shared.js +135 -0
  184. package/dist/cli/commands/openspec-commands.d.ts +1 -1
  185. package/dist/cli/commands/openspec-commands.js +33 -306
  186. package/dist/cli/commands/openspec-from-doctor-command.d.ts +3 -0
  187. package/dist/cli/commands/openspec-from-doctor-command.js +66 -0
  188. package/dist/cli/commands/openspec-init-command.d.ts +3 -0
  189. package/dist/cli/commands/openspec-init-command.js +49 -0
  190. package/dist/cli/commands/openspec-list-command.d.ts +3 -0
  191. package/dist/cli/commands/openspec-list-command.js +27 -0
  192. package/dist/cli/commands/openspec-render-command.d.ts +3 -0
  193. package/dist/cli/commands/openspec-render-command.js +33 -0
  194. package/dist/cli/commands/openspec-show-command.d.ts +3 -0
  195. package/dist/cli/commands/openspec-show-command.js +33 -0
  196. package/dist/cli/commands/openspec-to-rd-command.d.ts +3 -0
  197. package/dist/cli/commands/openspec-to-rd-command.js +33 -0
  198. package/dist/cli/commands/openspec-validate-command.d.ts +3 -0
  199. package/dist/cli/commands/openspec-validate-command.js +45 -0
  200. package/dist/cli/commands/playwright-browser-command.d.ts +8 -0
  201. package/dist/cli/commands/playwright-browser-command.js +61 -0
  202. package/dist/cli/commands/playwright-commands.d.ts +10 -62
  203. package/dist/cli/commands/playwright-commands.js +77 -400
  204. package/dist/cli/commands/playwright-envelope.d.ts +8 -0
  205. package/dist/cli/commands/playwright-envelope.js +29 -0
  206. package/dist/cli/commands/playwright-ls-stop-commands.d.ts +4 -0
  207. package/dist/cli/commands/playwright-ls-stop-commands.js +74 -0
  208. package/dist/cli/commands/playwright-session-store.d.ts +65 -0
  209. package/dist/cli/commands/playwright-session-store.js +189 -0
  210. package/dist/cli/commands/project-commands.d.ts +19 -0
  211. package/dist/cli/commands/project-commands.js +98 -259
  212. package/dist/cli/commands/project-context-command.d.ts +3 -0
  213. package/dist/cli/commands/project-context-command.js +44 -0
  214. package/dist/cli/commands/project-dashboard-command.d.ts +3 -0
  215. package/dist/cli/commands/project-dashboard-command.js +74 -0
  216. package/dist/cli/commands/project-knowledge-command.d.ts +3 -0
  217. package/dist/cli/commands/project-knowledge-command.js +48 -0
  218. package/dist/cli/commands/project-memories-show-command.d.ts +3 -0
  219. package/dist/cli/commands/project-memories-show-command.js +87 -0
  220. package/dist/cli/commands/project-memory-index-command.d.ts +3 -0
  221. package/dist/cli/commands/project-memory-index-command.js +31 -0
  222. package/dist/cli/commands/qa-archive-screenshots-command.d.ts +3 -0
  223. package/dist/cli/commands/qa-archive-screenshots-command.js +53 -0
  224. package/dist/cli/commands/qa-commands.d.ts +14 -87
  225. package/dist/cli/commands/qa-commands.js +17 -315
  226. package/dist/cli/commands/qa-context-prestep.d.ts +1 -0
  227. package/dist/cli/commands/qa-context-prestep.js +34 -0
  228. package/dist/cli/commands/qa-run-command.d.ts +3 -0
  229. package/dist/cli/commands/qa-run-command.js +105 -0
  230. package/dist/cli/commands/qa-run-options.d.ts +23 -0
  231. package/dist/cli/commands/qa-run-options.js +31 -0
  232. package/dist/cli/commands/qa-run-slice.d.ts +41 -0
  233. package/dist/cli/commands/qa-run-slice.js +145 -0
  234. package/dist/cli/commands/release-canary-command.d.ts +28 -0
  235. package/dist/cli/commands/release-canary-command.js +129 -0
  236. package/dist/cli/commands/release-command-shared.d.ts +13 -0
  237. package/dist/cli/commands/release-command-shared.js +18 -0
  238. package/dist/cli/commands/release-commands.d.ts +10 -18
  239. package/dist/cli/commands/release-commands.js +25 -298
  240. package/dist/cli/commands/release-done-command.d.ts +3 -0
  241. package/dist/cli/commands/release-done-command.js +64 -0
  242. package/dist/cli/commands/release-hotfix-command.d.ts +3 -0
  243. package/dist/cli/commands/release-hotfix-command.js +50 -0
  244. package/dist/cli/commands/release-plan-command.d.ts +3 -0
  245. package/dist/cli/commands/release-plan-command.js +33 -0
  246. package/dist/cli/commands/release-precheck-command.d.ts +3 -0
  247. package/dist/cli/commands/release-precheck-command.js +28 -0
  248. package/dist/cli/commands/release-promote-command.d.ts +3 -0
  249. package/dist/cli/commands/release-promote-command.js +34 -0
  250. package/dist/cli/commands/release-rollback-command.d.ts +3 -0
  251. package/dist/cli/commands/release-rollback-command.js +33 -0
  252. package/dist/cli/commands/release-watch-command.d.ts +3 -0
  253. package/dist/cli/commands/release-watch-command.js +44 -0
  254. package/dist/cli/commands/sediment-argv-flags.d.ts +54 -0
  255. package/dist/cli/commands/sediment-argv-flags.js +116 -0
  256. package/dist/cli/commands/sediment-command-shared.d.ts +15 -0
  257. package/dist/cli/commands/sediment-command-shared.js +5 -0
  258. package/dist/cli/commands/sediment-commands.d.ts +35 -59
  259. package/dist/cli/commands/sediment-commands.js +36 -590
  260. package/dist/cli/commands/sediment-pool-commands.d.ts +9 -0
  261. package/dist/cli/commands/sediment-pool-commands.js +185 -0
  262. package/dist/cli/commands/sediment-query-commands.d.ts +4 -0
  263. package/dist/cli/commands/sediment-query-commands.js +94 -0
  264. package/dist/cli/commands/sediment-release-commands.d.ts +8 -0
  265. package/dist/cli/commands/sediment-release-commands.js +232 -0
  266. package/dist/cli/commands/sop-advance-command.d.ts +3 -0
  267. package/dist/cli/commands/sop-advance-command.js +160 -0
  268. package/dist/cli/commands/sop-check-command.d.ts +3 -0
  269. package/dist/cli/commands/sop-check-command.js +44 -0
  270. package/dist/cli/commands/sop-command-shared.d.ts +23 -0
  271. package/dist/cli/commands/sop-command-shared.js +18 -0
  272. package/dist/cli/commands/sop-commands.d.ts +15 -1
  273. package/dist/cli/commands/sop-commands.js +26 -240
  274. package/dist/cli/commands/sop-init-command.d.ts +3 -0
  275. package/dist/cli/commands/sop-init-command.js +51 -0
  276. package/dist/cli/commands/sop-lint-command.d.ts +3 -0
  277. package/dist/cli/commands/sop-lint-command.js +64 -0
  278. package/dist/cli/commands/sop-register-command.d.ts +3 -0
  279. package/dist/cli/commands/sop-register-command.js +48 -0
  280. package/dist/cli/commands/sop-registry-command.d.ts +3 -0
  281. package/dist/cli/commands/sop-registry-command.js +30 -0
  282. package/dist/cli/commands/statusline-command-shared.d.ts +73 -0
  283. package/dist/cli/commands/statusline-command-shared.js +90 -0
  284. package/dist/cli/commands/statusline-commands.d.ts +1 -19
  285. package/dist/cli/commands/statusline-commands.js +48 -287
  286. package/dist/cli/commands/statusline-compact-command.d.ts +4 -0
  287. package/dist/cli/commands/statusline-compact-command.js +54 -0
  288. package/dist/cli/commands/statusline-install-command.d.ts +3 -0
  289. package/dist/cli/commands/statusline-install-command.js +48 -0
  290. package/dist/cli/commands/statusline-render-command.d.ts +9 -0
  291. package/dist/cli/commands/statusline-render-command.js +55 -0
  292. package/dist/cli/commands/statusline-status-command.d.ts +3 -0
  293. package/dist/cli/commands/statusline-status-command.js +23 -0
  294. package/dist/cli/commands/statusline-uninstall-command.d.ts +3 -0
  295. package/dist/cli/commands/statusline-uninstall-command.js +23 -0
  296. package/dist/cli/commands/test-command-run-helpers.d.ts +27 -0
  297. package/dist/cli/commands/test-command-run-helpers.js +73 -0
  298. package/dist/cli/commands/test-command-runner-resolution.d.ts +57 -0
  299. package/dist/cli/commands/test-command-runner-resolution.js +183 -0
  300. package/dist/cli/commands/test-commands.d.ts +8 -56
  301. package/dist/cli/commands/test-commands.js +26 -249
  302. package/dist/cli/commands/vm-command-shared.d.ts +23 -0
  303. package/dist/cli/commands/vm-command-shared.js +23 -0
  304. package/dist/cli/commands/vm-commands.d.ts +1 -28
  305. package/dist/cli/commands/vm-commands.js +36 -270
  306. package/dist/cli/commands/vm-hypervisor-runtime.d.ts +15 -0
  307. package/dist/cli/commands/vm-hypervisor-runtime.js +64 -0
  308. package/dist/cli/commands/vm-release-command.d.ts +5 -0
  309. package/dist/cli/commands/vm-release-command.js +101 -0
  310. package/dist/cli/commands/vm-spawn-command.d.ts +5 -0
  311. package/dist/cli/commands/vm-spawn-command.js +177 -0
  312. package/dist/cli/commands/web-command-shared.d.ts +12 -0
  313. package/dist/cli/commands/web-command-shared.js +30 -0
  314. package/dist/cli/commands/web-commands.d.ts +7 -14
  315. package/dist/cli/commands/web-commands.js +6 -314
  316. package/dist/cli/commands/web-install-command.d.ts +10 -0
  317. package/dist/cli/commands/web-install-command.js +116 -0
  318. package/dist/cli/commands/web-lifecycle-commands.d.ts +9 -30
  319. package/dist/cli/commands/web-lifecycle-commands.js +14 -322
  320. package/dist/cli/commands/web-login-command.d.ts +14 -0
  321. package/dist/cli/commands/web-login-command.js +189 -0
  322. package/dist/cli/commands/web-op-payload.d.ts +22 -0
  323. package/dist/cli/commands/web-op-payload.js +89 -0
  324. package/dist/cli/commands/web-op-refusals.d.ts +37 -0
  325. package/dist/cli/commands/web-op-refusals.js +73 -0
  326. package/dist/cli/commands/web-op-runner.d.ts +14 -0
  327. package/dist/cli/commands/web-op-runner.js +166 -0
  328. package/dist/cli/commands/web-status-command.d.ts +4 -0
  329. package/dist/cli/commands/web-status-command.js +32 -0
  330. package/dist/cli/commands/web-stop-command.d.ts +10 -0
  331. package/dist/cli/commands/web-stop-command.js +59 -0
  332. package/dist/cli/commands/web-verb-specs.d.ts +18 -0
  333. package/dist/cli/commands/web-verb-specs.js +66 -0
  334. package/dist/cli/commands/workflow-command-shared.d.ts +102 -0
  335. package/dist/cli/commands/workflow-command-shared.js +74 -0
  336. package/dist/cli/commands/workflow-graph-commands.d.ts +3 -0
  337. package/dist/cli/commands/workflow-graph-commands.js +73 -0
  338. package/dist/cli/commands/workflow-init-command.d.ts +3 -0
  339. package/dist/cli/commands/workflow-init-command.js +68 -0
  340. package/dist/cli/commands/workflow-lifecycle-commands.d.ts +9 -59
  341. package/dist/cli/commands/workflow-lifecycle-commands.js +14 -348
  342. package/dist/cli/commands/workflow-node-commands.d.ts +3 -0
  343. package/dist/cli/commands/workflow-node-commands.js +154 -0
  344. package/dist/cli/commands/workflow-terminalize-command.d.ts +3 -0
  345. package/dist/cli/commands/workflow-terminalize-command.js +56 -0
  346. package/dist/services/code/auto-compact-artifacts.d.ts +54 -0
  347. package/dist/services/code/auto-compact-artifacts.js +135 -0
  348. package/dist/services/code/auto-compact-attempt.d.ts +46 -0
  349. package/dist/services/code/auto-compact-attempt.js +88 -0
  350. package/dist/services/code/auto-compact-decision.d.ts +74 -0
  351. package/dist/services/code/auto-compact-decision.js +149 -0
  352. package/dist/services/code/auto-compact-dispatch-gate.d.ts +36 -0
  353. package/dist/services/code/auto-compact-dispatch-gate.js +86 -0
  354. package/dist/services/code/auto-compact-envelopes.d.ts +33 -0
  355. package/dist/services/code/auto-compact-envelopes.js +134 -0
  356. package/dist/services/code/auto-compact-history.d.ts +46 -0
  357. package/dist/services/code/auto-compact-history.js +17 -0
  358. package/dist/services/code/auto-compact-orchestrator.d.ts +11 -240
  359. package/dist/services/code/auto-compact-orchestrator.js +165 -686
  360. package/dist/services/code/auto-compact-run-types.d.ts +123 -0
  361. package/dist/services/code/auto-compact-run-types.js +1 -0
  362. package/dist/services/code/emit-handoff.d.ts +35 -1
  363. package/dist/services/code/emit-handoff.js +128 -7
  364. package/dist/services/code/step-08-gate.d.ts +28 -19
  365. package/dist/services/code/step-08-gate.js +92 -35
  366. package/dist/services/config/config-coercion.d.ts +7 -0
  367. package/dist/services/config/config-coercion.js +156 -0
  368. package/dist/services/config/config-file-io.d.ts +11 -0
  369. package/dist/services/config/config-file-io.js +61 -0
  370. package/dist/services/config/config-get.d.ts +2 -0
  371. package/dist/services/config/config-get.js +36 -0
  372. package/dist/services/config/config-global-loader.d.ts +15 -0
  373. package/dist/services/config/config-global-loader.js +111 -0
  374. package/dist/services/config/config-nested-path.d.ts +3 -0
  375. package/dist/services/config/config-nested-path.js +53 -0
  376. package/dist/services/config/config-primitives.d.ts +16 -0
  377. package/dist/services/config/config-primitives.js +24 -0
  378. package/dist/services/config/config-service.d.ts +9 -33
  379. package/dist/services/config/config-service.js +16 -665
  380. package/dist/services/config/config-validation.d.ts +19 -0
  381. package/dist/services/config/config-validation.js +152 -0
  382. package/dist/services/config/config-workspace.d.ts +10 -0
  383. package/dist/services/config/config-workspace.js +158 -0
  384. package/dist/services/skills/hooks-settings-deny-list.d.ts +61 -0
  385. package/dist/services/skills/hooks-settings-deny-list.js +173 -0
  386. package/dist/services/skills/hooks-settings-envelopes.d.ts +20 -0
  387. package/dist/services/skills/hooks-settings-envelopes.js +79 -0
  388. package/dist/services/skills/hooks-settings-file-shape.d.ts +43 -0
  389. package/dist/services/skills/hooks-settings-file-shape.js +207 -0
  390. package/dist/services/skills/hooks-settings-paths.d.ts +34 -0
  391. package/dist/services/skills/hooks-settings-paths.js +75 -0
  392. package/dist/services/skills/hooks-settings-read-installed.d.ts +39 -0
  393. package/dist/services/skills/hooks-settings-read-installed.js +60 -0
  394. package/dist/services/skills/hooks-settings-service.d.ts +12 -212
  395. package/dist/services/skills/hooks-settings-service.js +71 -657
  396. package/dist/services/skills/hooks-settings-types.d.ts +139 -0
  397. package/dist/services/skills/hooks-settings-types.js +1 -0
  398. package/dist/services/workspace/claude-settings-template-merge.d.ts +89 -0
  399. package/dist/services/workspace/claude-settings-template-merge.js +243 -0
  400. package/dist/services/workspace/claude-settings-template.d.ts +29 -87
  401. package/dist/services/workspace/claude-settings-template.js +81 -236
  402. package/package.json +5 -5
@@ -1,108 +1,38 @@
1
- /**
2
- *
3
- * L4 VM isolation runtime. Parallels the design of
4
- * `container-commands.ts` (Part 12, docker) and
5
- * `worktree-auth-commands.ts` (Part 1-2, git worktree).
6
- *
7
- * Hypervisor dispatch:
8
- * - `kvm` : `virsh create` + `virsh destroy` (Linux KVM via libvirt)
9
- * - `hyperkit` : `hvftool create` + `hvftool stop` (macOS HyperKit)
10
- * - `hyperv` : `hvc create` + `hvftool stop` (Windows Hyper-V via
11
- * the operator-installed `hvc` shim)
12
- *
13
- * The runtime check: which hypervisor binary is on PATH +
14
- * (for kvm) whether the host kernel exposes /dev/kvm. The
15
- * spawn is fail-fast: if the requested hypervisor is not
16
- * available, the CLI returns VM_RUNTIME_UNAVAILABLE with a
17
- * remediation hint rather than falling through to a different
18
- * hypervisor (the caller chose a specific mode for a reason).
19
- *
20
- * Each spawned VM runs `sleep infinity` as the entrypoint; the
21
- * VM's working dir is mounted from the host path, and the
22
- * `peaks.leaseId` / `peaks.rid` labels are propagated via
23
- * cloud-init metadata. Real workloads are expected to use
24
- * `peaks vm exec` (a follow-up rid) to run commands inside
25
- * the VM; Part 35 ships the lease + spawn/release surface
26
- * only.
27
- */
28
- import { execSync } from 'node:child_process';
29
- import { existsSync, readFileSync, writeFileSync } from 'node:fs';
30
- import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
31
- import { addJsonOption, printResult } from '../cli-helpers.js';
32
- import { findProjectRoot } from '../../services/config/config-safety.js';
33
- import { getCurrentSessionId } from '../../services/skills/skill-presence-service.js';
34
- import { atomicWriteJson } from '../../services/ide/shared/atomic-json.js';
35
- import { DEFAULT_VM_IMAGE, deserializeVmLease, finalizeVmLease, generateVmLeaseId, markVmReleased, ttlForVmRole, vmLeaseFilePath } from '../../services/vm/vm-lease.js';
36
- import { detectHypervisor } from './vm-hypervisor-probe.js';
1
+ // src/cli/commands/vm-commands.ts
2
+ //
3
+ // L4 VM isolation: the `peaks vm` parent, its status probe, and the
4
+ // spawn/release pair. Split out of the single file this used to be; the parent
5
+ // description, the registration order and every verb's surface are unchanged.
6
+ //
7
+ // Hypervisor dispatch:
8
+ // - `kvm` : `virsh create` + `virsh destroy` (Linux KVM via libvirt)
9
+ // - `hyperkit` : `hvftool create` + `hvftool stop` (macOS HyperKit)
10
+ // - `hyperv` : `hvc create` + `hvftool stop` (Windows Hyper-V via
11
+ // the operator-installed `hvc` shim)
12
+ //
13
+ // The runtime check: which hypervisor binary is on PATH +
14
+ // (for kvm) whether the host kernel exposes /dev/kvm. The
15
+ // spawn is fail-fast: if the requested hypervisor is not
16
+ // available, the CLI returns VM_RUNTIME_UNAVAILABLE with a
17
+ // remediation hint rather than falling through to a different
18
+ // hypervisor (the caller chose a specific mode for a reason).
19
+ //
20
+ // Each spawned VM runs `sleep infinity` as the entrypoint; the
21
+ // VM's working dir is mounted from the host path, and the
22
+ // `peaks.leaseId` / `peaks.rid` labels are propagated via
23
+ // cloud-init metadata. Real workloads are expected to use
24
+ // `peaks vm exec` (a follow-up rid) to run commands inside
25
+ // the VM; Part 35 ships the lease + spawn/release surface
26
+ // only.
27
+ //
28
+ // The verb bodies live beside this file (`vm-spawn-command.ts`,
29
+ // `vm-release-command.ts`), over the shared vocabulary in
30
+ // `vm-command-shared.ts` and the dispatch helpers in
31
+ // `vm-hypervisor-runtime.ts`; `vm-hypervisor-probe.ts` and
32
+ // `vm-status-command.ts` were already siblings.
37
33
  import { registerVmStatusCommand } from './vm-status-command.js';
38
- function joinPathSession(projectRoot, sessionId) {
39
- return `${projectRoot.replace(/[\\/]+$/, '')}/.peaks/_runtime/${sessionId}`;
40
- }
41
- function resolveTtlMs(raw, role) {
42
- if (typeof raw !== 'string' || raw.length === 0)
43
- return ttlForVmRole(role);
44
- const parsed = Number.parseInt(raw, 10);
45
- if (!Number.isInteger(parsed) || parsed <= 0)
46
- return ttlForVmRole(role);
47
- return parsed;
48
- }
49
- function spawnVmWithHypervisor(args) {
50
- if (args.hypervisor === 'kvm') {
51
- // virsh create expects a domain XML file. We emit a minimal
52
- // XML with the image, mount, and our peaks labels.
53
- const xml = `<?xml version="1.0"?>
54
- <domain type="kvm">
55
- <name>peaks-${args.leaseId}</name>
56
- <metadata><peaks:label xmlns:peaks="urn:peaks">peaks.leaseId=${args.leaseId};peaks.rid=${args.rid}</peaks:label></metadata>
57
- <memory>1048576</memory>
58
- <vcpu>1</vcpu>
59
- <os><type arch="x86_64">hvm</type></os>
60
- <devices>
61
- <disk type="file"><source file="${args.image}"/><target dev="vda"/></disk>
62
- <filesystem type="mount"><source dir="${args.mount}"/><target dir="/work"/></filesystem>
63
- </devices>
64
- </domain>`;
65
- const xmlPath = `${args.workdir}/.peaks-vm-${args.leaseId}.xml`;
66
- writeFileSync(xmlPath, xml, 'utf8');
67
- const out = execSync(`virsh create ${xmlPath}`, {
68
- cwd: args.workdir,
69
- stdio: ['ignore', 'pipe', 'pipe'],
70
- encoding: 'utf8',
71
- windowsHide: true
72
- });
73
- return { vmId: out.trim() };
74
- }
75
- if (args.hypervisor === 'hyperkit') {
76
- const out = execSync(`hvftool create --image ${args.image} --mount ${args.mount}:/work --label peaks.leaseId=${args.leaseId} --label peaks.rid=${args.rid} --entrypoint sleep -- infinity`, { cwd: args.workdir, stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf8', windowsHide: true });
77
- return { vmId: out.trim() };
78
- }
79
- // hyperv: the hvc shim writes a vhdx + emits the new VM id.
80
- const out = execSync(`hvc create --image ${args.image} --mount ${args.mount} --label peaks.leaseId=${args.leaseId} --label peaks.rid=${args.rid}`, { cwd: args.workdir, stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf8', windowsHide: true });
81
- return { vmId: out.trim() };
82
- }
83
- function destroyVmWithHypervisor(args) {
84
- try {
85
- if (args.hypervisor === 'kvm') {
86
- execSync(`virsh destroy ${args.vmId}`, {
87
- stdio: ['ignore', 'pipe', 'pipe'],
88
- windowsHide: true
89
- });
90
- }
91
- else if (args.hypervisor === 'hyperkit') {
92
- execSync(`hvftool stop ${args.vmId}`, {
93
- stdio: ['ignore', 'pipe', 'pipe'],
94
- windowsHide: true
95
- });
96
- }
97
- else {
98
- execSync(`hvc stop ${args.vmId}`, { stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
99
- }
100
- return true;
101
- }
102
- catch {
103
- return false;
104
- }
105
- }
34
+ import { registerVmSpawnCommand } from './vm-spawn-command.js';
35
+ import { registerVmReleaseCommand } from './vm-release-command.js';
106
36
  export function registerVmCommand(program, io) {
107
37
  const cmd = program
108
38
  .command('vm')
@@ -110,170 +40,6 @@ export function registerVmCommand(program, io) {
110
40
  // The host probe rides on the same parent, so `peaks vm status`
111
41
  // can say which prerequisite is missing before a spawn fails.
112
42
  registerVmStatusCommand(cmd, io);
113
- addJsonOption(cmd
114
- .command('spawn')
115
- .description('Spawn a VM via the requested hypervisor (kvm | hyperkit | hyperv) and write a VM lease. ' +
116
- 'Default TTL is role-aware (rd=30m / qa=15m / ui=1h); pass --ttl <ms> to override. ' +
117
- 'Default image is `peaks-base:22-slim`; pass --image <name> to override.')
118
- .requiredOption('--rid <rid>', 'peaks request id the lease is associated with')
119
- .requiredOption('--role <role>', 'sub-agent role (rd | qa | ui | sc | prd | general-purpose)')
120
- .requiredOption('--purpose <text>', 'why this VM was spawned (audit log)')
121
- .option('--hypervisor <name>', 'hypervisor to use: kvm | hyperkit | hyperv (default: auto-detect from host)')
122
- .option('--image <name>', `container image / vhdx to boot (default ${DEFAULT_VM_IMAGE})`)
123
- .option('--ttl <ms>', 'time-to-live in ms (default role-aware; override with positive number)')
124
- .option('--mount <path>', 'host path to mount as the VM working dir (default: <projectRoot>)')
125
- .option('--session <sid>', 'override session id')
126
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
127
- try {
128
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
129
- const sessionId = options.session ??
130
- process.env.PEAKS_SESSION_ID ??
131
- getCurrentSessionId(projectRoot) ??
132
- 'unknown-sid';
133
- // Pick hypervisor: explicit > auto-detect.
134
- const explicit = options.hypervisor;
135
- const detected = explicit
136
- ? explicit
137
- : (() => {
138
- if (existsSync('/dev/kvm'))
139
- return 'kvm';
140
- // No platform detector for hyperkit / hyperv — those
141
- // require explicit --hypervisor.
142
- return null;
143
- })();
144
- if (detected === null) {
145
- printResult(io, fail('vm.spawn', 'VM_HYPERVISOR_UNSPECIFIED', 'No --hypervisor given and the host does not advertise /dev/kvm. Pass --hypervisor hyperkit|hyperv to force one.', { rid: options.rid, sessionId }, [
146
- 'Linux KVM: ensure /dev/kvm exists and the kvm kernel module is loaded.',
147
- 'macOS HyperKit: install hvftool (brew install hyperkit) and pass --hypervisor hyperkit.',
148
- 'Windows Hyper-V: install the hvc shim and pass --hypervisor hyperv.'
149
- ]), options.json);
150
- process.exitCode = 1;
151
- return;
152
- }
153
- const probe = detectHypervisor(detected);
154
- if (!probe.ok) {
155
- printResult(io, fail('vm.spawn', 'VM_RUNTIME_UNAVAILABLE', `${detected} runtime not available: ${probe.stderr}`, { rid: options.rid, hypervisor: detected, sessionId }, [
156
- `Install the ${detected} runtime binary on PATH.`,
157
- 'The dispatch fail-fast prevents fallback to a different hypervisor (caller chose this mode for a reason).'
158
- ]), options.json);
159
- process.exitCode = 1;
160
- return;
161
- }
162
- const leaseId = generateVmLeaseId();
163
- const now = Date.now();
164
- const ttlMs = resolveTtlMs(options.ttl, options.role);
165
- const image = options.image ?? DEFAULT_VM_IMAGE;
166
- const mount = options.mount ?? projectRoot;
167
- let spawnResult;
168
- try {
169
- spawnResult = spawnVmWithHypervisor({
170
- hypervisor: detected,
171
- image,
172
- mount,
173
- leaseId,
174
- rid: options.rid,
175
- workdir: projectRoot
176
- });
177
- }
178
- catch (err) {
179
- printResult(io, fail('vm.spawn', 'VM_SPAWN_FAILED', getErrorMessage(err), { rid: options.rid, hypervisor: detected, image, sessionId }, [
180
- 'Verify the image / vhdx is reachable on the host.',
181
- `For ${detected}: the spawn helper expects domain XML / hvftool args / hvc shim.`
182
- ]), options.json);
183
- process.exitCode = 1;
184
- return;
185
- }
186
- const lease = finalizeVmLease({
187
- leaseId,
188
- rid: options.rid,
189
- role: options.role,
190
- path: mount,
191
- hypervisor: detected,
192
- image,
193
- vmId: spawnResult.vmId,
194
- createdAt: now,
195
- expiresAt: now + ttlMs,
196
- purpose: options.purpose
197
- });
198
- atomicWriteJson(vmLeaseFilePath(joinPathSession(projectRoot, sessionId), leaseId), lease);
199
- printResult(io, ok('vm.spawn', {
200
- lease,
201
- sessionId,
202
- projectRoot,
203
- hypervisor: detected,
204
- runtime: probe.binary,
205
- ttlMs,
206
- nextActions: [
207
- `VM domain id: ${spawnResult.vmId}`,
208
- `Image: ${image}`,
209
- `Lease expires at: ${new Date(lease.expiresAt).toISOString()}`,
210
- 'Run `peaks vm release --lease-id <lease-id>` when done',
211
- 'For inside-the-VM exec, a follow-up rid adds `peaks vm exec` (Part 35 ships lease + spawn/release only).'
212
- ]
213
- }, [], []), options.json);
214
- }
215
- catch (err) {
216
- printResult(io, fail('vm.spawn', 'SPAWN_FAILED', getErrorMessage(err), {
217
- rid: options.rid,
218
- sessionId: options.session ?? process.env.PEAKS_SESSION_ID ?? 'unknown-sid'
219
- }, [
220
- 'See error message; if the lease was not written, retry after fixing the underlying issue.'
221
- ]), options.json);
222
- process.exitCode = 1;
223
- }
224
- });
225
- addJsonOption(cmd
226
- .command('release')
227
- .description('Transition a VM lease to released and run the hypervisor destroy command. Idempotent on already-released leases.')
228
- .requiredOption('--lease-id <id>', 'lease id returned by `peaks vm spawn`')
229
- .option('--session <sid>', 'override session id')
230
- .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => {
231
- try {
232
- const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
233
- const sessionId = options.session ??
234
- process.env.PEAKS_SESSION_ID ??
235
- getCurrentSessionId(projectRoot) ??
236
- 'unknown-sid';
237
- const file = vmLeaseFilePath(joinPathSession(projectRoot, sessionId), options.leaseId);
238
- if (!existsSync(file)) {
239
- printResult(io, fail('vm.release', 'LEASE_NOT_FOUND', `no VM lease on disk at ${file}`, { leaseId: options.leaseId, file }, [
240
- 'Run `peaks vm list` (follow-up) to inspect active leases.',
241
- 'For a never-spawned lease, this is a no-op.'
242
- ]), options.json);
243
- process.exitCode = 1;
244
- return;
245
- }
246
- let lease;
247
- try {
248
- lease = deserializeVmLease(readFileSync(file, 'utf8'));
249
- }
250
- catch (err) {
251
- printResult(io, fail('vm.release', 'LEASE_FILE_INVALID', getErrorMessage(err), { leaseId: options.leaseId, file }, ['Delete the malformed lease file manually and re-spawn.']), options.json);
252
- process.exitCode = 1;
253
- return;
254
- }
255
- if (lease.status === 'released') {
256
- printResult(io, ok('vm.release', { lease, sessionId, projectRoot, alreadyReleased: true }, [], [`Lease ${lease.leaseId} already released; nothing to do.`]), options.json);
257
- return;
258
- }
259
- const destroyed = destroyVmWithHypervisor({ hypervisor: lease.hypervisor, vmId: lease.vmId });
260
- const released = markVmReleased(lease);
261
- atomicWriteJson(file, released);
262
- printResult(io, ok('vm.release', { lease: released, sessionId, projectRoot, vmDestroyed: destroyed }, destroyed
263
- ? []
264
- : [`${lease.hypervisor} destroy command failed; the lease was marked released anyway.`], [
265
- `Lease ${lease.leaseId} marked released.`,
266
- destroyed
267
- ? `${lease.hypervisor} domain ${lease.vmId} stopped.`
268
- : `Manual \`${lease.hypervisor} stop ${lease.vmId}\` may be needed.`
269
- ]), options.json);
270
- }
271
- catch (err) {
272
- printResult(io, fail('vm.release', 'RELEASE_FAILED', getErrorMessage(err), {
273
- leaseId: options.leaseId,
274
- sessionId: options.session ?? process.env.PEAKS_SESSION_ID ?? 'unknown-sid'
275
- }, ['Verify the lease id and re-run.']), options.json);
276
- process.exitCode = 1;
277
- }
278
- });
43
+ registerVmSpawnCommand(cmd, io);
44
+ registerVmReleaseCommand(cmd, io);
279
45
  }
@@ -0,0 +1,15 @@
1
+ import type { VmHypervisor } from '../../services/vm/vm-lease.js';
2
+ export declare function spawnVmWithHypervisor(args: {
3
+ hypervisor: VmHypervisor;
4
+ image: string;
5
+ mount: string;
6
+ leaseId: string;
7
+ rid: string;
8
+ workdir: string;
9
+ }): {
10
+ vmId: string;
11
+ };
12
+ export declare function destroyVmWithHypervisor(args: {
13
+ hypervisor: VmHypervisor;
14
+ vmId: string;
15
+ }): boolean;
@@ -0,0 +1,64 @@
1
+ // src/cli/commands/vm-hypervisor-runtime.ts
2
+ //
3
+ // The two hypervisor dispatch helpers `peaks vm spawn` / `peaks vm release`
4
+ // call: create a domain and destroy one. Split out of `vm-commands.ts`; every
5
+ // command line, cwd, stdio tuple and `windowsHide` flag is unchanged.
6
+ import { execSync } from 'node:child_process';
7
+ import { writeFileSync } from 'node:fs';
8
+ export function spawnVmWithHypervisor(args) {
9
+ if (args.hypervisor === 'kvm') {
10
+ // virsh create expects a domain XML file. We emit a minimal
11
+ // XML with the image, mount, and our peaks labels.
12
+ const xml = `<?xml version="1.0"?>
13
+ <domain type="kvm">
14
+ <name>peaks-${args.leaseId}</name>
15
+ <metadata><peaks:label xmlns:peaks="urn:peaks">peaks.leaseId=${args.leaseId};peaks.rid=${args.rid}</peaks:label></metadata>
16
+ <memory>1048576</memory>
17
+ <vcpu>1</vcpu>
18
+ <os><type arch="x86_64">hvm</type></os>
19
+ <devices>
20
+ <disk type="file"><source file="${args.image}"/><target dev="vda"/></disk>
21
+ <filesystem type="mount"><source dir="${args.mount}"/><target dir="/work"/></filesystem>
22
+ </devices>
23
+ </domain>`;
24
+ const xmlPath = `${args.workdir}/.peaks-vm-${args.leaseId}.xml`;
25
+ writeFileSync(xmlPath, xml, 'utf8');
26
+ const out = execSync(`virsh create ${xmlPath}`, {
27
+ cwd: args.workdir,
28
+ stdio: ['ignore', 'pipe', 'pipe'],
29
+ encoding: 'utf8',
30
+ windowsHide: true
31
+ });
32
+ return { vmId: out.trim() };
33
+ }
34
+ if (args.hypervisor === 'hyperkit') {
35
+ const out = execSync(`hvftool create --image ${args.image} --mount ${args.mount}:/work --label peaks.leaseId=${args.leaseId} --label peaks.rid=${args.rid} --entrypoint sleep -- infinity`, { cwd: args.workdir, stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf8', windowsHide: true });
36
+ return { vmId: out.trim() };
37
+ }
38
+ // hyperv: the hvc shim writes a vhdx + emits the new VM id.
39
+ const out = execSync(`hvc create --image ${args.image} --mount ${args.mount} --label peaks.leaseId=${args.leaseId} --label peaks.rid=${args.rid}`, { cwd: args.workdir, stdio: ['ignore', 'pipe', 'pipe'], encoding: 'utf8', windowsHide: true });
40
+ return { vmId: out.trim() };
41
+ }
42
+ export function destroyVmWithHypervisor(args) {
43
+ try {
44
+ if (args.hypervisor === 'kvm') {
45
+ execSync(`virsh destroy ${args.vmId}`, {
46
+ stdio: ['ignore', 'pipe', 'pipe'],
47
+ windowsHide: true
48
+ });
49
+ }
50
+ else if (args.hypervisor === 'hyperkit') {
51
+ execSync(`hvftool stop ${args.vmId}`, {
52
+ stdio: ['ignore', 'pipe', 'pipe'],
53
+ windowsHide: true
54
+ });
55
+ }
56
+ else {
57
+ execSync(`hvc stop ${args.vmId}`, { stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true });
58
+ }
59
+ return true;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
@@ -0,0 +1,5 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ import { type ReleaseOptions } from './vm-command-shared.js';
4
+ export declare function runVmRelease(io: ProgramIO, options: ReleaseOptions): void;
5
+ export declare function registerVmReleaseCommand(cmd: Command, io: ProgramIO): void;
@@ -0,0 +1,101 @@
1
+ // src/cli/commands/vm-release-command.ts
2
+ //
3
+ // `peaks vm release` — transition a VM lease to released and run the
4
+ // hypervisor destroy command. Split out of `vm-commands.ts`; every refusal
5
+ // code, message, `data` field, warning and next-action string is unchanged.
6
+ import { existsSync, readFileSync } from 'node:fs';
7
+ import { fail, getErrorMessage, ok } from 'peaks-loop-shared/result';
8
+ import { addJsonOption, printResult } from '../cli-helpers.js';
9
+ import { findProjectRoot } from '../../services/config/config-safety.js';
10
+ import { atomicWriteJson } from '../../services/ide/shared/atomic-json.js';
11
+ import { deserializeVmLease, markVmReleased, vmLeaseFilePath } from '../../services/vm/vm-lease.js';
12
+ import { destroyVmWithHypervisor } from './vm-hypervisor-runtime.js';
13
+ import { joinPathSession, resolveVmSessionId } from './vm-command-shared.js';
14
+ /** Print a `vm.release` refusal; the caller stops. */
15
+ function emitReleaseRefusal(io, options, refusal) {
16
+ printResult(io, fail('vm.release', refusal.code, refusal.message, refusal.data, refusal.nextActions), options.json ?? false);
17
+ process.exitCode = 1;
18
+ }
19
+ /** The lease on disk, or null after the matching refusal envelope was printed. */
20
+ function readLeaseOrRefuse(io, options, file) {
21
+ if (!existsSync(file)) {
22
+ emitReleaseRefusal(io, options, {
23
+ code: 'LEASE_NOT_FOUND',
24
+ message: `no VM lease on disk at ${file}`,
25
+ data: { leaseId: options.leaseId, file },
26
+ nextActions: [
27
+ 'Run `peaks vm list` (follow-up) to inspect active leases.',
28
+ 'For a never-spawned lease, this is a no-op.'
29
+ ]
30
+ });
31
+ return null;
32
+ }
33
+ try {
34
+ return deserializeVmLease(readFileSync(file, 'utf8'));
35
+ }
36
+ catch (err) {
37
+ emitReleaseRefusal(io, options, {
38
+ code: 'LEASE_FILE_INVALID',
39
+ message: getErrorMessage(err),
40
+ data: { leaseId: options.leaseId, file },
41
+ nextActions: ['Delete the malformed lease file manually and re-spawn.']
42
+ });
43
+ return null;
44
+ }
45
+ }
46
+ function emitAlreadyReleased(io, options, target, lease) {
47
+ printResult(io, ok('vm.release', {
48
+ lease,
49
+ sessionId: target.sessionId,
50
+ projectRoot: target.projectRoot,
51
+ alreadyReleased: true
52
+ }, [], [`Lease ${lease.leaseId} already released; nothing to do.`]), options.json ?? false);
53
+ }
54
+ function emitReleaseSuccess(io, options, target, lease) {
55
+ const destroyed = destroyVmWithHypervisor({ hypervisor: lease.hypervisor, vmId: lease.vmId });
56
+ const released = markVmReleased(lease);
57
+ atomicWriteJson(target.file, released);
58
+ printResult(io, ok('vm.release', {
59
+ lease: released,
60
+ sessionId: target.sessionId,
61
+ projectRoot: target.projectRoot,
62
+ vmDestroyed: destroyed
63
+ }, destroyed
64
+ ? []
65
+ : [`${lease.hypervisor} destroy command failed; the lease was marked released anyway.`], [
66
+ `Lease ${lease.leaseId} marked released.`,
67
+ destroyed
68
+ ? `${lease.hypervisor} domain ${lease.vmId} stopped.`
69
+ : `Manual \`${lease.hypervisor} stop ${lease.vmId}\` may be needed.`
70
+ ]), options.json ?? false);
71
+ }
72
+ export function runVmRelease(io, options) {
73
+ try {
74
+ const projectRoot = options.project ?? findProjectRoot(process.cwd()) ?? process.cwd();
75
+ const sessionId = resolveVmSessionId(projectRoot, options.session);
76
+ const file = vmLeaseFilePath(joinPathSession(projectRoot, sessionId), options.leaseId);
77
+ const lease = readLeaseOrRefuse(io, options, file);
78
+ if (lease === null)
79
+ return;
80
+ if (lease.status === 'released') {
81
+ emitAlreadyReleased(io, options, { projectRoot, sessionId, file }, lease);
82
+ return;
83
+ }
84
+ emitReleaseSuccess(io, options, { projectRoot, sessionId, file }, lease);
85
+ }
86
+ catch (err) {
87
+ printResult(io, fail('vm.release', 'RELEASE_FAILED', getErrorMessage(err), {
88
+ leaseId: options.leaseId,
89
+ sessionId: options.session ?? process.env.PEAKS_SESSION_ID ?? 'unknown-sid'
90
+ }, ['Verify the lease id and re-run.']), options.json ?? false);
91
+ process.exitCode = 1;
92
+ }
93
+ }
94
+ export function registerVmReleaseCommand(cmd, io) {
95
+ addJsonOption(cmd
96
+ .command('release')
97
+ .description('Transition a VM lease to released and run the hypervisor destroy command. Idempotent on already-released leases.')
98
+ .requiredOption('--lease-id <id>', 'lease id returned by `peaks vm spawn`')
99
+ .option('--session <sid>', 'override session id')
100
+ .option('--project <path>', 'project root (default: findProjectRoot(cwd))')).action((options) => runVmRelease(io, options));
101
+ }
@@ -0,0 +1,5 @@
1
+ import type { Command } from 'commander';
2
+ import { type ProgramIO } from '../cli-helpers.js';
3
+ import { type SpawnOptions } from './vm-command-shared.js';
4
+ export declare function runVmSpawn(io: ProgramIO, options: SpawnOptions): void;
5
+ export declare function registerVmSpawnCommand(cmd: Command, io: ProgramIO): void;