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,199 +1,19 @@
1
- import { existsSync, mkdirSync } from 'node:fs';
2
- import { dirname, isAbsolute, resolve } from 'node:path';
3
- import { DEFAULT_CONFIG, isConfigV2 } from './config-types.js';
4
- import { stablePath } from '../../shared/path-utils.js';
5
- import { findProjectRoot, getProjectBootstrapConfigPath, getProjectConfigPath, getUserConfigPath, isInsidePath, readConfigFileSafely, resolveProjectRootForConfig, validateArtifactWorkspaceMarkerPath, validateArtifactWorkspaceRoot, validateProjectBootstrapConfigPathForWrite, validateUserConfigPathForWrite, writeConfigFileSafely, writeProjectConfigFile, writeUserConfigFile } from './config-safety.js';
6
- import { globalConfigPath, CONFIG_SCHEMA_VERSION_V2 } from './config-migration.js';
7
- import { SIDECAR_SCHEMA_VERSION, providersConfigPath, proxyConfigPath, readSidecarJson, sidecarExists, workspacesConfigPath, writeSidecarJson } from './sidecar-store.js';
1
+ import { dirname } from 'node:path';
2
+ import { DEFAULT_CONFIG } from './config-types.js';
3
+ import { findProjectRoot, getProjectBootstrapConfigPath, getUserConfigPath, validateProjectBootstrapConfigPathForWrite, validateUserConfigPathForWrite, writeProjectConfigFile, writeUserConfigFile } from './config-safety.js';
4
+ import { getNestedPathParts, getNestedValue, setNestedValue } from './config-nested-path.js';
5
+ import { isRecord, omitProxy } from './config-primitives.js';
6
+ import { inferHumanLanguage, toModelProviderConfig, toPeaksConfig, toProviderModelConfig, toWorkspaceConfigs } from './config-coercion.js';
7
+ import { containsSensitiveConfigValue, getProxyUrlCandidate, isLegacyConfigKey, isProviderBaseUrlPath, isProviderConfigPath, isProxyConfigPath, isSensitiveConfigPath, redactConfigSecrets, validateModelProviderConfig, validateProviderBaseUrl, validateProviderConfig, validateProxyUrl, validateProxyConfig } from './config-validation.js';
8
+ import { ensureDir, getProjectWriteTarget, readExistingJsonFile, readJsonFile, readProjectJsonFile, readUserJsonFile, removeProjectSensitiveConfig } from './config-file-io.js';
8
9
  // Re-export resolveProjectRootForConfig and resolveCanonicalProjectRoot for external consumers
9
10
  export { resolveProjectRootForConfig, resolveCanonicalProjectRoot } from './config-safety.js';
10
- /**
11
- * Load the slim 2.0 `~/.peaks/config.json` file. Returns the parsed
12
- * object when the file is at schema 2.0.0; returns null when the
13
- * file is absent (fresh install, no global config yet).
14
- *
15
- * Throws `CONFIG_LEGACY_VERSION` when the file exists at a 1.x
16
- * schema version — the caller is expected to run
17
- * `peaks config migrate --apply` to bring it forward before
18
- * continuing. This gate is intentional: a slim 2.0 reader must
19
- * not silently pass through a 1.x shape, because every field it
20
- * ignores is a field the caller is going to look for elsewhere
21
- * (preferences.json, .bak, _state/).
22
- */
23
- export function loadGlobalConfig() {
24
- const path = globalConfigPath();
25
- if (!existsSync(path))
26
- return null;
27
- const content = readConfigFileSafely(path, 'Global config path must stay inside the user root');
28
- const raw = JSON.parse(content);
29
- if (isConfigV2(raw)) {
30
- if (hasLegacyGlobalFields(raw)) {
31
- promoteLegacyGlobalFieldsToSidecars(raw);
32
- rewriteSlimGlobalConfig();
33
- }
34
- return readSlimGlobalConfig();
35
- }
36
- const detected = typeof raw.version === 'string' ? raw.version : 'unknown';
37
- throw new Error(`CONFIG_LEGACY_VERSION: ~/.peaks/config.json is at version "${detected}", expected ${CONFIG_SCHEMA_VERSION_V2}. Run \`peaks config migrate --apply\`.`);
38
- }
39
- /**
40
- * Slim 2.0 schema allows `version` + `ocr`. Any other top-level
41
- * field is a legacy artifact that needs to be promoted to a
42
- * sidecar file.
43
- */
44
- function hasLegacyGlobalFields(raw) {
45
- const allowed = new Set(['version', 'ocr']);
46
- return Object.keys(raw).some((k) => !allowed.has(k));
47
- }
48
- /**
49
- * One-shot promotion of legacy fields into their dedicated sidecar
50
- * files. Idempotent: if the sidecar already has the field, the
51
- * legacy value is dropped (sidecar is the new source of truth).
52
- */
53
- function promoteLegacyGlobalFieldsToSidecars(raw) {
54
- if (isRecord(raw.providers)) {
55
- const existing = readSidecarJson(providersConfigPath(), {
56
- version: SIDECAR_SCHEMA_VERSION,
57
- providers: {}
58
- });
59
- const mergedProviders = {
60
- ...(existing.providers ?? {}),
61
- ...raw.providers
62
- };
63
- writeSidecarJson(providersConfigPath(), {
64
- version: SIDECAR_SCHEMA_VERSION,
65
- providers: mergedProviders
66
- });
67
- }
68
- if (isRecord(raw.proxy) && typeof raw.proxy.httpProxy === 'string') {
69
- const httpProxy = raw.proxy.httpProxy;
70
- if (!sidecarExists(proxyConfigPath())) {
71
- writeSidecarJson(proxyConfigPath(), { version: SIDECAR_SCHEMA_VERSION, httpProxy });
72
- }
73
- }
74
- if (Array.isArray(raw.workspaces) || typeof raw.currentWorkspace === 'string') {
75
- if (!sidecarExists(workspacesConfigPath())) {
76
- writeSidecarJson(workspacesConfigPath(), {
77
- version: SIDECAR_SCHEMA_VERSION,
78
- workspaces: Array.isArray(raw.workspaces) ? raw.workspaces : [],
79
- currentWorkspace: typeof raw.currentWorkspace === 'string' ? raw.currentWorkspace : null
80
- });
81
- }
82
- }
83
- }
84
- function readSlimGlobalConfig() {
85
- const path = globalConfigPath();
86
- if (!existsSync(path)) {
87
- return { version: CONFIG_SCHEMA_VERSION_V2 };
88
- }
89
- const content = readConfigFileSafely(path, 'Global config path must stay inside the user root');
90
- return JSON.parse(content);
91
- }
92
- function rewriteSlimGlobalConfig() {
93
- const path = globalConfigPath();
94
- const ocr = readOcrFromRawConfigFile();
95
- const slim = { version: CONFIG_SCHEMA_VERSION_V2 };
96
- if (ocr !== null)
97
- slim['ocr'] = ocr;
98
- writeUserConfigFile(path, JSON.stringify(slim, null, 2) + '\n');
99
- }
100
- function readOcrFromRawConfigFile() {
101
- const path = globalConfigPath();
102
- if (!existsSync(path))
103
- return null;
104
- const content = readConfigFileSafely(path, 'Global config path must stay inside the user root');
105
- const raw = JSON.parse(content);
106
- return isRecord(raw.ocr) ? raw.ocr : null;
107
- }
108
- function readJsonFile(path, validateBeforeRead, errorMessage = 'Config path must stay inside the config root') {
109
- if (!path || !existsSync(path))
110
- return null;
111
- validateBeforeRead?.();
112
- const content = readConfigFileSafely(path, errorMessage);
113
- try {
114
- return JSON.parse(content);
115
- }
116
- catch {
117
- // TODO(g2): legacy silent catch — grace: 1 minor release (v2.14.0)
118
- return null;
119
- }
120
- }
121
- function readExistingJsonFile(path, errorMessage, validateBeforeRead) {
122
- if (!existsSync(path))
123
- return null;
124
- validateBeforeRead?.();
125
- try {
126
- return JSON.parse(readConfigFileSafely(path, errorMessage));
127
- }
128
- catch {
129
- throw new Error(errorMessage);
130
- }
131
- }
132
- function readUserJsonFile() {
133
- const userPath = getUserConfigPath();
134
- return readJsonFile(userPath, () => validateUserConfigPathForWrite(userPath), 'User config path must stay inside the user root');
135
- }
136
- function readProjectJsonFile(projectRoot) {
137
- const projectPath = getProjectConfigPath(projectRoot);
138
- return readJsonFile(projectPath, projectRoot && projectPath
139
- ? () => validateProjectBootstrapConfigPathForWrite(projectRoot, projectPath)
140
- : undefined, 'Project config path must stay inside the project root');
141
- }
142
- function ensureDir(dirPath) {
143
- if (!existsSync(dirPath)) {
144
- mkdirSync(dirPath, { recursive: true });
145
- }
146
- }
147
- const UNSAFE_NESTED_PATH_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype']);
148
- function getNestedPathParts(path) {
149
- return path
150
- .replace(/\[(\d+)\]/g, '.$1')
151
- .split('.')
152
- .filter(Boolean);
153
- }
154
- function hasUnsafeNestedPathSegment(parts) {
155
- return parts.some((part) => UNSAFE_NESTED_PATH_SEGMENTS.has(part));
156
- }
157
- function getNestedValue(obj, path) {
158
- const parts = getNestedPathParts(path);
159
- if (parts.length === 0 || hasUnsafeNestedPathSegment(parts)) {
160
- return undefined;
161
- }
162
- let current = obj;
163
- for (const part of parts) {
164
- if (current === null ||
165
- current === undefined ||
166
- typeof current !== 'object' ||
167
- !Object.prototype.hasOwnProperty.call(current, part)) {
168
- return undefined;
169
- }
170
- current = current[part];
171
- }
172
- return current;
173
- }
174
- function setNestedValue(obj, path, value) {
175
- const parts = getNestedPathParts(path);
176
- if (parts.length === 0 || hasUnsafeNestedPathSegment(parts)) {
177
- throw new Error('Unsafe config path');
178
- }
179
- let current = obj;
180
- for (let i = 0; i < parts.length - 1; i++) {
181
- const part = parts[i];
182
- if (!Object.prototype.hasOwnProperty.call(current, part) ||
183
- typeof current[part] !== 'object' ||
184
- current[part] === null ||
185
- Array.isArray(current[part])) {
186
- current[part] = {};
187
- }
188
- current = current[part];
189
- }
190
- const last = parts[parts.length - 1];
191
- current[last] = value;
192
- }
193
- function removeProjectSensitiveConfig(config) {
194
- const { providers, proxy, tokens, ...safeConfig } = config;
195
- return Object.fromEntries(Object.entries(safeConfig).filter(([key, value]) => !isSecretKey(key) && !containsSensitiveConfigValue(value)));
196
- }
11
+ // Every name below moved into a sibling module for the file-size cap; the
12
+ // declarations are unchanged, so importers of this path are unaffected.
13
+ export { getConfig } from './config-get.js';
14
+ export { loadGlobalConfig } from './config-global-loader.js';
15
+ export { addWorkspace, ensureWorkspaceConfigForCurrentPath, ensureWorkspaceConfigForPath, getCurrentWorkspaceConfig, getWorkspaceConfig, getWorkspaceConfigForCurrentPath, getWorkspaceConfigForPath, removeWorkspace, setCurrentWorkspace } from './config-workspace.js';
16
+ export { containsSensitiveConfigValue, isLegacyConfigKey, isSensitiveConfigPath, redactConfigSecrets };
197
17
  export function isConfigLayer(value) {
198
18
  return value === 'user' || value === 'project';
199
19
  }
@@ -231,311 +51,6 @@ export function readContextWindowTokensOverride(projectRoot) {
231
51
  return undefined;
232
52
  }
233
53
  }
234
- export function isSensitiveConfigPath(path) {
235
- const normalized = path.toLowerCase().replace(/[^a-z0-9]/g, '');
236
- return (normalized.includes('apikey') ||
237
- normalized.includes('accesskey') ||
238
- normalized.includes('privatekey') ||
239
- normalized.includes('token') ||
240
- normalized.includes('secret') ||
241
- normalized.includes('password') ||
242
- normalized.includes('bearer') ||
243
- normalized.includes('credential') ||
244
- normalized.includes('auth'));
245
- }
246
- /**
247
- * 2.0.1 slim-config contract: `~/.peaks/config.json` only stores
248
- * `version` + `ocr.llm.*` placeholders. The 1.x → 2.0 migration
249
- * moved per-project fields (`language`, `model`, `economyMode`,
250
- * `swarmMode`) to `<project>/.peaks/preferences.json` (per spec
251
- * §10.4). `setConfig` rejects writes to those keys and points the
252
- * user to the preferences path; tokens / providers / proxy still
253
- * live in `~/.peaks/config.json` (the loader is tolerant of them
254
- * but does not synthesise defaults for them anymore).
255
- */
256
- const LEGACY_CONFIG_KEYS = new Set([
257
- 'language',
258
- 'model',
259
- 'economyMode',
260
- 'swarmMode'
261
- ]);
262
- export function isLegacyConfigKey(path) {
263
- const topLevel = path.split(/[.[].*/, 1)[0] ?? '';
264
- return LEGACY_CONFIG_KEYS.has(topLevel);
265
- }
266
- function isProviderConfigPath(path) {
267
- return path === 'providers' || path.startsWith('providers.');
268
- }
269
- function isSecretKey(key) {
270
- return isSensitiveConfigPath(key);
271
- }
272
- function sanitizeBaseUrlForDisplay(value) {
273
- try {
274
- const url = new URL(value);
275
- url.username = '';
276
- url.password = '';
277
- url.search = '';
278
- url.hash = '';
279
- return url.toString();
280
- }
281
- catch {
282
- return '[invalid-url-redacted]';
283
- }
284
- }
285
- function isProviderBaseUrlPath(path) {
286
- return /^providers\.[^.]+\.baseUrl$/.test(path);
287
- }
288
- function isValidProviderBaseUrl(value) {
289
- try {
290
- const url = new URL(value);
291
- return (url.protocol === 'https:' &&
292
- url.username.length === 0 &&
293
- url.password.length === 0 &&
294
- url.search.length === 0 &&
295
- url.hash.length === 0);
296
- }
297
- catch {
298
- return false;
299
- }
300
- }
301
- function validateProviderBaseUrl(value) {
302
- if (value !== undefined && (typeof value !== 'string' || !isValidProviderBaseUrl(value))) {
303
- throw new Error('Provider base URL must be HTTPS without embedded credentials, query, or fragment');
304
- }
305
- }
306
- function getProxyUrlCandidate(key, value) {
307
- if (key === 'proxy.httpProxy') {
308
- return value;
309
- }
310
- if (key === 'proxy' && isRecord(value)) {
311
- return value.httpProxy;
312
- }
313
- return undefined;
314
- }
315
- function isProxyConfigPath(path) {
316
- return path === 'proxy' || path.startsWith('proxy.');
317
- }
318
- function validateModelProviderConfig(providers) {
319
- for (const [providerId, provider] of Object.entries(providers)) {
320
- validateProviderBaseUrl(provider?.baseUrl);
321
- }
322
- }
323
- function validateProviderConfig(partial) {
324
- validateModelProviderConfig(partial.providers ?? {});
325
- }
326
- function isValidProxyUrl(value) {
327
- try {
328
- const url = new URL(value);
329
- return ((url.protocol === 'http:' || url.protocol === 'https:') &&
330
- url.username.length === 0 &&
331
- url.password.length === 0 &&
332
- url.pathname === '/' &&
333
- url.search.length === 0 &&
334
- url.hash.length === 0);
335
- }
336
- catch {
337
- return false;
338
- }
339
- }
340
- function validateProxyUrl(value) {
341
- if (value !== undefined && (typeof value !== 'string' || !isValidProxyUrl(value))) {
342
- throw new Error('Proxy URL must be an HTTP or HTTPS URL without embedded credentials');
343
- }
344
- }
345
- function validateProxyConfig(partial) {
346
- validateProxyUrl(partial.proxy?.httpProxy);
347
- }
348
- function isRecord(value) {
349
- return value !== null && typeof value === 'object' && !Array.isArray(value);
350
- }
351
- function isSafeConfigSegment(value) {
352
- return (/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(value) && !value.includes('..') && !value.endsWith('.'));
353
- }
354
- function toArtifactRemoteRepoConfig(value) {
355
- if (!isRecord(value) ||
356
- (value.provider !== 'github' && value.provider !== 'gitlab') ||
357
- typeof value.owner !== 'string' ||
358
- typeof value.name !== 'string') {
359
- return null;
360
- }
361
- if (!isSafeConfigSegment(value.owner) || !isSafeConfigSegment(value.name)) {
362
- return null;
363
- }
364
- return { provider: value.provider, owner: value.owner, name: value.name };
365
- }
366
- function toArtifactStorageConfig(value) {
367
- if (!isRecord(value))
368
- return null;
369
- const localPath = typeof value.localPath === 'string' ? { localPath: value.localPath } : {};
370
- if (value.mode === 'local') {
371
- return { mode: 'local', ...localPath };
372
- }
373
- const remote = toArtifactRemoteRepoConfig(value.remote);
374
- if (value.mode === 'local-with-remote-sync' && remote) {
375
- return { mode: 'local-with-remote-sync', ...localPath, remote };
376
- }
377
- return null;
378
- }
379
- function toWorkspaceConfig(value) {
380
- if (!isRecord(value))
381
- return null;
382
- const { workspaceId, name, rootPath, installedCapabilityIds } = value;
383
- if (typeof workspaceId !== 'string' ||
384
- !isSafeConfigSegment(workspaceId) ||
385
- typeof name !== 'string' ||
386
- typeof rootPath !== 'string' ||
387
- !Array.isArray(installedCapabilityIds) ||
388
- !installedCapabilityIds.every((id) => typeof id === 'string')) {
389
- return null;
390
- }
391
- const artifactRepo = toArtifactRemoteRepoConfig(value.artifactRepo);
392
- const artifactStorage = toArtifactStorageConfig(value.artifactStorage);
393
- return {
394
- workspaceId,
395
- name,
396
- rootPath,
397
- installedCapabilityIds,
398
- ...(artifactRepo ? { artifactRepo } : {}),
399
- ...(artifactStorage ? { artifactStorage } : {})
400
- };
401
- }
402
- function toWorkspaceConfigs(value) {
403
- return Array.isArray(value)
404
- ? value
405
- .map(toWorkspaceConfig)
406
- .filter((workspace) => workspace !== null)
407
- : [];
408
- }
409
- function toProviderModelConfig(value) {
410
- if (!isRecord(value))
411
- return {};
412
- return {
413
- ...(typeof value.model === 'string' && value.model.trim().length > 0
414
- ? { model: value.model.trim() }
415
- : {}),
416
- ...(typeof value.baseUrl === 'string' ? { baseUrl: value.baseUrl } : {}),
417
- ...(typeof value.apiKey === 'string' ? { apiKey: value.apiKey } : {})
418
- };
419
- }
420
- const TOKEN_CONFIG_KEYS = new Set([
421
- 'AnthropicApiKey',
422
- 'OpenAiApiKey',
423
- 'GitHubToken',
424
- 'GitLabToken'
425
- ]);
426
- function toTokenRef(value) {
427
- if (!isRecord(value))
428
- return null;
429
- const env = typeof value.env === 'string' ? value.env.trim() : '';
430
- const keychain = typeof value.keychain === 'string' ? value.keychain.trim() : '';
431
- if (env.length > 0) {
432
- return { env };
433
- }
434
- if (keychain.length > 0) {
435
- return { keychain };
436
- }
437
- if (value.ghCli === true) {
438
- return { ghCli: true };
439
- }
440
- return null;
441
- }
442
- function toTokenConfig(value) {
443
- if (!isRecord(value))
444
- return {};
445
- const tokens = {};
446
- for (const [key, entry] of Object.entries(value)) {
447
- if (!TOKEN_CONFIG_KEYS.has(key))
448
- continue;
449
- const tokenRef = toTokenRef(entry);
450
- if (tokenRef) {
451
- tokens[key] = tokenRef;
452
- }
453
- }
454
- return tokens;
455
- }
456
- function toModelProviderConfig(value) {
457
- if (!isRecord(value))
458
- return {};
459
- return Object.fromEntries(Object.entries(value).map(([providerId, providerConfig]) => [
460
- providerId,
461
- toProviderModelConfig(providerConfig)
462
- ]));
463
- }
464
- function toProxyConfig(value) {
465
- if (!isRecord(value))
466
- return null;
467
- return typeof value.httpProxy === 'string' && isValidProxyUrl(value.httpProxy)
468
- ? { httpProxy: value.httpProxy }
469
- : null;
470
- }
471
- function getProjectWriteTarget() {
472
- const projectRoot = findProjectRoot(process.cwd());
473
- const configPath = getProjectConfigPath(projectRoot);
474
- if (!projectRoot || !configPath) {
475
- throw new Error('Project config not found');
476
- }
477
- return { projectRoot, configPath };
478
- }
479
- export function containsSensitiveConfigValue(value) {
480
- if (Array.isArray(value)) {
481
- return value.some(containsSensitiveConfigValue);
482
- }
483
- if (value === null || typeof value !== 'object') {
484
- return false;
485
- }
486
- return Object.entries(value).some(([key, entry]) => isSecretKey(key) || containsSensitiveConfigValue(entry));
487
- }
488
- export function redactConfigSecrets(value, path = '') {
489
- if (Array.isArray(value)) {
490
- return value.map((item, index) => redactConfigSecrets(item, `${path}[${index}]`));
491
- }
492
- if (value === null || typeof value !== 'object') {
493
- if (isProviderBaseUrlPath(path) && typeof value === 'string') {
494
- return sanitizeBaseUrlForDisplay(value);
495
- }
496
- return value;
497
- }
498
- return Object.fromEntries(Object.entries(value).map(([key, entry]) => {
499
- const nextPath = path ? `${path}.${key}` : key;
500
- if (isSecretKey(key)) {
501
- return [key, '***'];
502
- }
503
- if (isProviderBaseUrlPath(nextPath) && typeof entry === 'string') {
504
- return [key, sanitizeBaseUrlForDisplay(entry)];
505
- }
506
- return [key, redactConfigSecrets(entry, nextPath)];
507
- }));
508
- }
509
- function inferHumanLanguage(value) {
510
- const normalized = value.trim();
511
- if (!normalized) {
512
- throw new Error('Language must be non-empty');
513
- }
514
- if (/^zh(?:-|$)/i.test(normalized) || /[㐀-鿿]/u.test(normalized)) {
515
- return 'zh-CN';
516
- }
517
- if (/^en(?:-|$)/i.test(normalized)) {
518
- return 'en';
519
- }
520
- return 'en';
521
- }
522
- function toPeaksConfig(value) {
523
- if (!isRecord(value))
524
- return {};
525
- const proxy = toProxyConfig(value.proxy);
526
- return {
527
- ...(typeof value.version === 'string' ? { version: value.version } : {}),
528
- ...(typeof value.language === 'string' ? { language: value.language } : {}),
529
- ...(typeof value.model === 'string' && ['haiku', 'sonnet', 'opus'].includes(value.model)
530
- ? { model: value.model }
531
- : {}),
532
- ...(typeof value.economyMode === 'boolean' ? { economyMode: value.economyMode } : {}),
533
- ...(typeof value.swarmMode === 'boolean' ? { swarmMode: value.swarmMode } : {}),
534
- ...(isRecord(value.tokens) ? { tokens: toTokenConfig(value.tokens) } : {}),
535
- ...(isRecord(value.providers) ? { providers: toModelProviderConfig(value.providers) } : {}),
536
- ...(proxy ? { proxy } : {})
537
- };
538
- }
539
54
  export function bootstrapProjectLanguageConfig(projectRoot, language) {
540
55
  const inferredLanguage = inferHumanLanguage(language);
541
56
  const projectPath = getProjectBootstrapConfigPath(projectRoot);
@@ -549,7 +64,7 @@ export function readConfig(projectRoot) {
549
64
  const detectedRoot = projectRoot ?? findProjectRoot(process.cwd());
550
65
  const userConfig = toPeaksConfig(readUserJsonFile());
551
66
  const projectConfig = removeProjectSensitiveConfig(toPeaksConfig(readProjectJsonFile(detectedRoot)));
552
- const { proxy: projectProxy, ...projectConfigWithoutProxy } = projectConfig;
67
+ const projectConfigWithoutProxy = omitProxy(projectConfig);
553
68
  return {
554
69
  ...DEFAULT_CONFIG,
555
70
  ...userConfig,
@@ -594,30 +109,6 @@ export function writeConfig(partial, layer = 'user') {
594
109
  const merged = sanitizeWorkspacePartial({ ...existing, ...partial });
595
110
  writeUserConfigFile(userPath, JSON.stringify(merged, null, 2));
596
111
  }
597
- export function getConfig(options = {}) {
598
- const projectRoot = findProjectRoot(process.cwd());
599
- const userConfig = readUserJsonFile() ?? {};
600
- const projectConfig = removeProjectSensitiveConfig(readProjectJsonFile(projectRoot) ?? {});
601
- const { proxy: projectProxy, ...projectConfigWithoutProxy } = projectConfig;
602
- const source = options.layer === 'user'
603
- ? userConfig
604
- : options.layer === 'project'
605
- ? projectConfig
606
- : {
607
- ...userConfig,
608
- ...projectConfigWithoutProxy
609
- };
610
- const config = isRecord(source)
611
- ? {
612
- ...source,
613
- ...(source.tokens !== undefined ? { tokens: toTokenConfig(source.tokens) } : {})
614
- }
615
- : source;
616
- if (options.key !== undefined) {
617
- return getNestedValue(config, options.key);
618
- }
619
- return config;
620
- }
621
112
  export function setConfig(options) {
622
113
  const layer = options.layer ?? 'user';
623
114
  if (!isConfigLayer(layer)) {
@@ -663,145 +154,5 @@ export function setConfig(options) {
663
154
  writeUserConfigFile(targetPath, content);
664
155
  }
665
156
  }
666
- function readRawWorkspaceData(layer) {
667
- const config = getConfig({ layer });
668
- return isRecord(config)
669
- ? {
670
- currentWorkspace: typeof config.currentWorkspace === 'string' ? config.currentWorkspace : null,
671
- workspaces: toWorkspaceConfigs(config.workspaces)
672
- }
673
- : { currentWorkspace: null, workspaces: [] };
674
- }
675
- function writeRawWorkspaceData(data, layer) {
676
- const projectTarget = layer === 'project' ? getProjectWriteTarget() : null;
677
- const targetPath = projectTarget?.configPath ?? getUserConfigPath();
678
- ensureDir(dirname(targetPath));
679
- const existing = projectTarget
680
- ? (readJsonFile(targetPath, () => validateProjectBootstrapConfigPathForWrite(projectTarget.projectRoot, targetPath)) ?? {})
681
- : (readJsonFile(targetPath, () => validateUserConfigPathForWrite(targetPath)) ?? {});
682
- const merged = { ...existing, ...data };
683
- const content = JSON.stringify(merged, null, 2);
684
- if (projectTarget) {
685
- writeProjectConfigFile(projectTarget.projectRoot, targetPath, content);
686
- }
687
- else {
688
- writeUserConfigFile(targetPath, content);
689
- }
690
- }
691
- function readAllWorkspaces() {
692
- const userData = readRawWorkspaceData('user');
693
- const projectData = readRawWorkspaceData('project');
694
- const mergedWorkspaces = new Map();
695
- for (const w of userData.workspaces)
696
- mergedWorkspaces.set(w.workspaceId, w);
697
- for (const w of projectData.workspaces)
698
- mergedWorkspaces.set(w.workspaceId, w);
699
- return {
700
- currentWorkspace: projectData.currentWorkspace ?? userData.currentWorkspace,
701
- workspaces: [...mergedWorkspaces.values()]
702
- };
703
- }
704
- export function getWorkspaceConfig(workspaceId, _projectRoot) {
705
- const { workspaces } = readAllWorkspaces();
706
- return workspaces.find((w) => w.workspaceId === workspaceId) ?? null;
707
- }
708
- function readLayerConfig(layer) {
709
- return readRawWorkspaceData(layer);
710
- }
711
- export function addWorkspace(workspace, layer = 'user') {
712
- if (!isSafeConfigSegment(workspace.workspaceId)) {
713
- throw new Error('Workspace id must only contain letters, numbers, dots, underscores, or hyphens and must not contain path traversal');
714
- }
715
- const config = readRawWorkspaceData(layer);
716
- const workspaces = config.workspaces;
717
- const existing = workspaces.findIndex((w) => w.workspaceId === workspace.workspaceId);
718
- const updatedWorkspaces = existing >= 0
719
- ? workspaces.map((existingWorkspace) => existingWorkspace.workspaceId === workspace.workspaceId ? workspace : existingWorkspace)
720
- : [...workspaces, workspace];
721
- writeRawWorkspaceData({ workspaces: updatedWorkspaces }, layer);
722
- }
723
- export function removeWorkspace(workspaceId, layer = 'user') {
724
- if (!isSafeConfigSegment(workspaceId))
725
- return false;
726
- const config = readRawWorkspaceData(layer);
727
- const workspaces = config.workspaces;
728
- const idx = workspaces.findIndex((w) => w.workspaceId === workspaceId);
729
- if (idx < 0)
730
- return false;
731
- const updatedWorkspaces = workspaces.filter((w) => w.workspaceId !== workspaceId);
732
- const currentWorkspace = config.currentWorkspace === workspaceId
733
- ? (updatedWorkspaces[0]?.workspaceId ?? null)
734
- : (config.currentWorkspace ?? null);
735
- writeRawWorkspaceData({ workspaces: updatedWorkspaces, currentWorkspace }, layer);
736
- return true;
737
- }
738
- export function setCurrentWorkspace(workspaceId, layer = 'user') {
739
- if (!isSafeConfigSegment(workspaceId))
740
- return false;
741
- const config = readRawWorkspaceData(layer);
742
- const workspaces = config.workspaces;
743
- const exists = workspaces.some((w) => w.workspaceId === workspaceId);
744
- if (!exists)
745
- return false;
746
- writeRawWorkspaceData({ currentWorkspace: workspaceId }, layer);
747
- return true;
748
- }
749
- export function getCurrentWorkspaceConfig() {
750
- const { currentWorkspace, workspaces } = readAllWorkspaces();
751
- if (!currentWorkspace)
752
- return null;
753
- return workspaces.find((w) => w.workspaceId === currentWorkspace) ?? null;
754
- }
755
- export function getWorkspaceConfigForPath(path = process.cwd()) {
756
- const { workspaces } = readAllWorkspaces();
757
- return findWorkspaceForPath(workspaces, path);
758
- }
759
- function findWorkspaceForPath(workspaces, path) {
760
- const targetPath = stablePath(path);
761
- const matches = workspaces.flatMap((workspace) => {
762
- if (!isAbsolute(workspace.rootPath) || !existsSync(workspace.rootPath))
763
- return [];
764
- const rootPath = stablePath(workspace.rootPath);
765
- return isInsidePath(targetPath, rootPath) ? [{ workspace, rootPath }] : [];
766
- });
767
- if (matches.length === 0)
768
- return null;
769
- return matches.reduce((best, match) => match.rootPath.length > best.rootPath.length ? match : best).workspace;
770
- }
771
- function getWorkspaceArtifactRoot(workspace) {
772
- return workspace.artifactStorage?.localPath
773
- ? resolve(workspace.artifactStorage.localPath)
774
- : resolve(workspace.rootPath, '.peaks', 'artifacts');
775
- }
776
- function ensureArtifactWorkspaceMarker(workspace) {
777
- const artifactRoot = getWorkspaceArtifactRoot(workspace);
778
- const peaksPath = resolve(artifactRoot, '.peaks');
779
- const markerPath = resolve(peaksPath, 'config.json');
780
- ensureDir(artifactRoot);
781
- validateArtifactWorkspaceRoot(artifactRoot, workspace.rootPath);
782
- ensureDir(peaksPath);
783
- validateArtifactWorkspaceMarkerPath(artifactRoot, peaksPath, markerPath);
784
- if (!existsSync(markerPath)) {
785
- writeConfigFileSafely(markerPath, '{}\n', () => validateArtifactWorkspaceMarkerPath(artifactRoot, peaksPath, markerPath), 'Artifact workspace marker must stay inside the artifact workspace');
786
- }
787
- }
788
- export function ensureWorkspaceConfigForPath(path = process.cwd()) {
789
- const projectRoot = resolveProjectRootForConfig(path);
790
- if (!isAbsolute(projectRoot) || !existsSync(projectRoot))
791
- return null;
792
- const config = readLayerConfig('user');
793
- const existingWorkspace = findWorkspaceForPath(config.workspaces, path);
794
- if (existingWorkspace) {
795
- ensureArtifactWorkspaceMarker(existingWorkspace);
796
- return existingWorkspace;
797
- }
798
- return null;
799
- }
800
- export function getWorkspaceConfigForCurrentPath() {
801
- return getWorkspaceConfigForPath(process.cwd());
802
- }
803
- export function ensureWorkspaceConfigForCurrentPath() {
804
- return ensureWorkspaceConfigForPath(process.cwd());
805
- }
806
- export { getUserConfigPath } from './config-safety.js';
157
+ export { getUserConfigPath };
807
158
  export { globalConfigPath } from './config-migration.js';