@planu/cli 4.14.1 → 5.1.1

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 (452) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/LICENSE +55 -12
  3. package/README.md +10 -2
  4. package/dist/cli/commands/install.d.ts +1 -12
  5. package/dist/cli/commands/install.js +9 -65
  6. package/dist/cli/commands/job.js +4 -3
  7. package/dist/cli/commands/spec.js +12 -3
  8. package/dist/cli/commands/validate.js +2 -2
  9. package/dist/cli/router.js +1 -3
  10. package/dist/config/environment-schema.json +1 -3
  11. package/dist/config/official-sdd-tools.d.ts +4 -0
  12. package/dist/config/official-sdd-tools.js +35 -0
  13. package/dist/config/product-public.d.ts +139 -3
  14. package/dist/config/product-public.js +8 -1
  15. package/dist/config/product-public.json +7 -36
  16. package/dist/config/registries/hosts/codex.json +20 -363
  17. package/dist/config/release-policy.json +84 -2
  18. package/dist/config/runtime-policy.json +12 -1
  19. package/dist/config/skill-templates/planu-resume-work.md +2 -2
  20. package/dist/core/index.d.ts +1 -1
  21. package/dist/core/spec-validator.d.ts +4 -4
  22. package/dist/core/spec-validator.js +33 -19
  23. package/dist/engine/abortable-process-runner.d.ts +20 -2
  24. package/dist/engine/abortable-process-runner.js +243 -74
  25. package/dist/engine/ambiguity-scorer.js +4 -26
  26. package/dist/engine/auth/scope-mapper.js +1 -7
  27. package/dist/engine/autopilot/state-updater.js +4 -4
  28. package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
  29. package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
  30. package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
  31. package/dist/engine/ci-generator/planu-config.js +1 -7
  32. package/dist/engine/clarification-gate/gate.d.ts +3 -3
  33. package/dist/engine/code-scanner/layer-scanner.js +6 -22
  34. package/dist/engine/core-bridge.d.ts +3 -3
  35. package/dist/engine/cost-guardrails.d.ts +1 -1
  36. package/dist/engine/cost-guardrails.js +1 -1
  37. package/dist/engine/criterion-identity.d.ts +1 -0
  38. package/dist/engine/criterion-identity.js +7 -0
  39. package/dist/engine/dashboard/data-loader.js +2 -7
  40. package/dist/engine/dashboard/templates-layout.js +0 -3
  41. package/dist/engine/dashboard/templates-project.js +1 -13
  42. package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
  43. package/dist/engine/docs-site-generator/data-collector.js +7 -28
  44. package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
  45. package/dist/engine/evidence-gates/artifact-reader.d.ts +12 -1
  46. package/dist/engine/evidence-gates/artifact-reader.js +174 -4
  47. package/dist/engine/evidence-gates/evidence-autofill.d.ts +10 -0
  48. package/dist/engine/evidence-gates/evidence-autofill.js +148 -0
  49. package/dist/engine/evidence-gates/evidence-skeletons.d.ts +19 -0
  50. package/dist/engine/evidence-gates/evidence-skeletons.js +69 -0
  51. package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
  52. package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
  53. package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
  54. package/dist/engine/evidence-index/done-drift.d.ts +1 -1
  55. package/dist/engine/evidence-index/done-drift.js +40 -18
  56. package/dist/engine/execution/context.js +3 -0
  57. package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
  58. package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
  59. package/dist/engine/execution/job-runtime.d.ts +30 -0
  60. package/dist/engine/execution/job-runtime.js +114 -6
  61. package/dist/engine/execution/operation-journal.js +10 -4
  62. package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
  63. package/dist/engine/execution/public-job-sanitizer.js +31 -0
  64. package/dist/engine/execution/validate-job-executor.d.ts +12 -1
  65. package/dist/engine/execution/validate-job-executor.js +549 -86
  66. package/dist/engine/execution/validate-job-payload.js +107 -50
  67. package/dist/engine/execution/validate-job-recovery.js +1 -1
  68. package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
  69. package/dist/engine/execution/validate-worker-runtime.js +90 -2
  70. package/dist/engine/execution/validate-worker-thread.js +17 -24
  71. package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
  72. package/dist/engine/handoff-artifacts/schemas.js +33 -0
  73. package/dist/engine/handoff-packager.d.ts +19 -0
  74. package/dist/engine/handoff-packager.js +415 -13
  75. package/dist/engine/hooks/effort-configurator.js +1 -1
  76. package/dist/engine/impact-detector/test-break-predictor.js +3 -3
  77. package/dist/engine/impact-detector/tool-registration.js +1 -1
  78. package/dist/engine/implementation-contract/renderer.js +23 -8
  79. package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
  80. package/dist/engine/lifecycle-reconciliation-io.js +180 -0
  81. package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
  82. package/dist/engine/lifecycle-reconciliation.js +406 -0
  83. package/dist/engine/local-first/tool-classification.js +2 -0
  84. package/dist/engine/macos-keychain-native-port.d.ts +5 -0
  85. package/dist/engine/macos-keychain-native-port.js +19 -7
  86. package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
  87. package/dist/engine/migrations/remove-commercial-state.js +343 -0
  88. package/dist/engine/minimality/policy-loader.js +247 -6
  89. package/dist/engine/network-policy.js +1 -0
  90. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
  91. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +20 -20
  92. package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
  93. package/dist/engine/planu-core.darwin-x64.node.sbom.json +20 -20
  94. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
  95. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +20 -20
  96. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
  97. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +20 -20
  98. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
  99. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +20 -20
  100. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
  101. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +20 -20
  102. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
  103. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +20 -20
  104. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
  105. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +20 -20
  106. package/dist/engine/readiness-checker.d.ts +1 -16
  107. package/dist/engine/readiness-checker.js +27 -88
  108. package/dist/engine/reverse-engineer/api-detector.js +2 -13
  109. package/dist/engine/reverse-engineer/complexity-analyzer.js +2 -13
  110. package/dist/engine/reverse-engineer/config-analyzer.js +2 -13
  111. package/dist/engine/reverse-engineer/dependency-graph.js +2 -13
  112. package/dist/engine/reverse-engineer/test-analyzer.js +2 -13
  113. package/dist/engine/reverse-engineer/walk-ignore.d.ts +3 -0
  114. package/dist/engine/reverse-engineer/walk-ignore.js +26 -0
  115. package/dist/engine/runtime-policy.d.ts +2 -0
  116. package/dist/engine/runtime-policy.js +42 -5
  117. package/dist/engine/runtime-security/rate-limiter.js +0 -1
  118. package/dist/engine/safety/contained-project-file.d.ts +3 -0
  119. package/dist/engine/safety/contained-project-file.js +23 -0
  120. package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
  121. package/dist/engine/scope-boundaries/scope-validator.js +45 -7
  122. package/dist/engine/session/checkpoint-writer.js +0 -9
  123. package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
  124. package/dist/engine/spec-format/acceptance-criteria.js +82 -22
  125. package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
  126. package/dist/engine/spec-format/markdown-sections.js +105 -0
  127. package/dist/engine/spec-format/read-technical-section.js +33 -5
  128. package/dist/engine/spec-format/technical-md-populator.js +3 -2
  129. package/dist/engine/spec-format/text-fences.js +20 -2
  130. package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
  131. package/dist/engine/spec-format/unified-spec-builder.js +202 -0
  132. package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
  133. package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
  134. package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
  135. package/dist/engine/spec-migrator/filesystem-import.js +121 -14
  136. package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
  137. package/dist/engine/spec-migrator/index.d.ts +1 -0
  138. package/dist/engine/spec-migrator/index.js +1 -0
  139. package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
  140. package/dist/engine/spec-state-machine/transition-spec.js +10 -1
  141. package/dist/engine/spec-state-syncer.js +1 -1
  142. package/dist/engine/technical-enricher/index.js +16 -8
  143. package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
  144. package/dist/engine/technical-enricher/render-enriched.js +42 -14
  145. package/dist/engine/telemetry/health-checker.js +53 -17
  146. package/dist/engine/telemetry/telemetry-client.js +26 -8
  147. package/dist/engine/text-signal-boundaries.d.ts +2 -0
  148. package/dist/engine/text-signal-boundaries.js +25 -2
  149. package/dist/engine/time/relative-date.d.ts +3 -0
  150. package/dist/engine/time/relative-date.js +16 -0
  151. package/dist/engine/timing/budget.d.ts +11 -0
  152. package/dist/engine/timing/budget.js +31 -9
  153. package/dist/engine/token-optimizer/analytics.d.ts +1 -1
  154. package/dist/engine/token-optimizer/analytics.js +5 -6
  155. package/dist/engine/usage-tracker/core.d.ts +2 -2
  156. package/dist/engine/usage-tracker/core.js +1 -2
  157. package/dist/engine/usage-tracker/index.d.ts +0 -3
  158. package/dist/engine/usage-tracker/index.js +0 -3
  159. package/dist/engine/usage-tracker/stats.d.ts +2 -2
  160. package/dist/engine/usage-tracker/stats.js +1 -28
  161. package/dist/engine/validation/durable-validation.d.ts +1 -1
  162. package/dist/engine/validation/durable-validation.js +3 -82
  163. package/dist/engine/validation/validation-freshness.d.ts +11 -1
  164. package/dist/engine/validation/validation-freshness.js +231 -91
  165. package/dist/engine/validation/validation-receipt.d.ts +9 -6
  166. package/dist/engine/validation/validation-receipt.js +84 -24
  167. package/dist/engine/validation/validation-source-digest.d.ts +2 -0
  168. package/dist/engine/validation/validation-source-digest.js +86 -0
  169. package/dist/engine/validation/validation-submission.d.ts +5 -4
  170. package/dist/engine/validation/validation-submission.js +25 -11
  171. package/dist/engine/validation/validation-worktree.d.ts +21 -0
  172. package/dist/engine/validation/validation-worktree.js +260 -0
  173. package/dist/engine/validation-impact-planner.d.ts +14 -2
  174. package/dist/engine/validation-impact-planner.js +0 -3
  175. package/dist/engine/validator/dor-dod.d.ts +1 -0
  176. package/dist/engine/validator/dor-dod.js +5 -3
  177. package/dist/engine/validator/extractors.d.ts +1 -5
  178. package/dist/engine/validator/extractors.js +24 -69
  179. package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
  180. package/dist/engine/validator/spec-compliance-runner.js +429 -211
  181. package/dist/engine/validator.js +35 -22
  182. package/dist/index.js +4 -16
  183. package/dist/resources/usage-stats-resource.js +2 -18
  184. package/dist/security/adapters/linux-secret-service.js +7 -3
  185. package/dist/security/adapters/windows-credential-manager.js +6 -4
  186. package/dist/server/routes/specs.js +13 -1
  187. package/dist/storage/base-store.d.ts +1 -1
  188. package/dist/storage/base-store.js +1 -1
  189. package/dist/storage/feedback-remote.d.ts +2 -3
  190. package/dist/storage/feedback-remote.js +45 -31
  191. package/dist/storage/global-store.d.ts +1 -17
  192. package/dist/storage/global-store.js +1 -42
  193. package/dist/storage/index.d.ts +0 -2
  194. package/dist/storage/index.js +0 -2
  195. package/dist/storage/migrations/canonical-storage.js +124 -11
  196. package/dist/storage/runtime-db.d.ts +9 -0
  197. package/dist/storage/runtime-db.js +64 -8
  198. package/dist/storage/spec-store.d.ts +14 -2
  199. package/dist/storage/spec-store.js +104 -14
  200. package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
  201. package/dist/storage/status-store/atomic-status-write.js +57 -0
  202. package/dist/storage/status-store/file-lock.js +30 -11
  203. package/dist/storage/status-store/self-healing.js +3 -3
  204. package/dist/storage/status-store/version-sync.d.ts +2 -1
  205. package/dist/storage/status-store/version-sync.js +35 -40
  206. package/dist/storage/usage-store.d.ts +1 -5
  207. package/dist/storage/usage-store.js +0 -35
  208. package/dist/tools/auto-update-handler.d.ts +3 -3
  209. package/dist/tools/auto-update-handler.js +3 -3
  210. package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
  211. package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
  212. package/dist/tools/challenge-spec/scenario-collector.js +1 -1
  213. package/dist/tools/challenge-spec/scenarios-data.js +1 -1
  214. package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
  215. package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
  216. package/dist/tools/challenge-spec-helpers.d.ts +10 -1
  217. package/dist/tools/challenge-spec-helpers.js +63 -22
  218. package/dist/tools/challenge-spec.js +23 -8
  219. package/dist/tools/check-readiness.js +38 -14
  220. package/dist/tools/configure-telemetry.js +30 -2
  221. package/dist/tools/create-spec/spec-builder.d.ts +7 -0
  222. package/dist/tools/create-spec/spec-builder.js +19 -15
  223. package/dist/tools/create-spec.d.ts +1 -0
  224. package/dist/tools/create-spec.js +584 -309
  225. package/dist/tools/git/branch-ops.d.ts +1 -1
  226. package/dist/tools/git/branch-ops.js +3 -2
  227. package/dist/tools/init-project/handler.js +10 -12
  228. package/dist/tools/init-project/host-assets-writer.js +26 -1
  229. package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
  230. package/dist/tools/init-project/migration-runner.d.ts +2 -4
  231. package/dist/tools/init-project/migration-runner.js +3 -2
  232. package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
  233. package/dist/tools/init-project/portable-index-reconciler.js +14 -0
  234. package/dist/tools/init-project/result-builder.js +1 -3
  235. package/dist/tools/jobs/handlers.js +38 -6
  236. package/dist/tools/list-specs.js +5 -26
  237. package/dist/tools/merge-risk-handler.js +2 -2
  238. package/dist/tools/package-handoff.js +2 -0
  239. package/dist/tools/reconcile-spec.js +0 -27
  240. package/dist/tools/register-agent-squad-tools.js +2 -2
  241. package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
  242. package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
  243. package/dist/tools/register-sdd-tools.d.ts +1 -1
  244. package/dist/tools/register-sdd-tools.js +2 -29
  245. package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
  246. package/dist/tools/register-spec-tools/core-spec-tools.js +29 -19
  247. package/dist/tools/safe-handler.d.ts +5 -13
  248. package/dist/tools/safe-handler.js +7 -23
  249. package/dist/tools/schemas/index.d.ts +1 -1
  250. package/dist/tools/schemas/index.js +1 -1
  251. package/dist/tools/schemas/output-schemas.d.ts +0 -23
  252. package/dist/tools/schemas/output-schemas.js +0 -28
  253. package/dist/tools/schemas/spec.d.ts +4 -0
  254. package/dist/tools/schemas/spec.js +3 -0
  255. package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
  256. package/dist/tools/schemas/validate-output-schema.js +7 -0
  257. package/dist/tools/spec-prompt-handler.js +3 -3
  258. package/dist/tools/sync-spec-state-handler.d.ts +1 -1
  259. package/dist/tools/sync-spec-state-handler.js +50 -2
  260. package/dist/tools/tool-entry.d.ts +4 -4
  261. package/dist/tools/tool-entry.js +3 -3
  262. package/dist/tools/tool-registry/core-tools.js +31 -15
  263. package/dist/tools/tool-registry/group-infra.js +27 -110
  264. package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
  265. package/dist/tools/tool-registry/inventory.d.ts +2 -0
  266. package/dist/tools/tool-registry/inventory.js +2 -0
  267. package/dist/tools/tool-registry-helpers.d.ts +3 -3
  268. package/dist/tools/tool-registry-helpers.js +3 -3
  269. package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
  270. package/dist/tools/tool-usage-report/registered-tools.js +3 -15
  271. package/dist/tools/update-status/approval-gates.js +3 -0
  272. package/dist/tools/update-status/batch.d.ts +6 -2
  273. package/dist/tools/update-status/batch.js +58 -1
  274. package/dist/tools/update-status/dod-gates.d.ts +16 -1
  275. package/dist/tools/update-status/dod-gates.js +191 -1
  276. package/dist/tools/update-status/done-receipt-verifier.d.ts +8 -0
  277. package/dist/tools/update-status/done-receipt-verifier.js +75 -27
  278. package/dist/tools/update-status/evidence-gate.d.ts +4 -0
  279. package/dist/tools/update-status/evidence-gate.js +103 -3
  280. package/dist/tools/update-status/file-sync.d.ts +4 -3
  281. package/dist/tools/update-status/file-sync.js +57 -6
  282. package/dist/tools/update-status/index.d.ts +25 -1
  283. package/dist/tools/update-status/index.js +292 -78
  284. package/dist/tools/update-status/response-builder.js +3 -3
  285. package/dist/tools/update-status/side-effects.d.ts +2 -0
  286. package/dist/tools/update-status/side-effects.js +2 -2
  287. package/dist/tools/update-status/transition-guard.js +45 -16
  288. package/dist/tools/update-status-actions.d.ts +4 -2
  289. package/dist/tools/update-status-actions.js +16 -14
  290. package/dist/tools/usage-report.js +1 -16
  291. package/dist/tools/usage-stats.js +1 -18
  292. package/dist/tools/usage-tracking.d.ts +4 -0
  293. package/dist/tools/usage-tracking.js +20 -0
  294. package/dist/tools/validate-lint.d.ts +1 -0
  295. package/dist/tools/validate-lint.js +1 -1
  296. package/dist/tools/validate.d.ts +2 -1
  297. package/dist/tools/validate.js +114 -34
  298. package/dist/tools/workspace-dashboard-handler.js +38 -0
  299. package/dist/transports/http-transport.js +6 -8
  300. package/dist/transports/mcp-types.d.ts +0 -2
  301. package/dist/transports/session-context.js +1 -1
  302. package/dist/types/cascade-hooks.d.ts +1 -1
  303. package/dist/types/ci.d.ts +0 -4
  304. package/dist/types/clarification-token.d.ts +1 -1
  305. package/dist/types/claude-code-runtime.d.ts +0 -27
  306. package/dist/types/commercial-migration.d.ts +17 -0
  307. package/dist/types/commercial-migration.js +2 -0
  308. package/dist/types/common/primitives.d.ts +0 -2
  309. package/dist/types/core-bridge.d.ts +4 -10
  310. package/dist/types/dashboard.d.ts +3 -7
  311. package/dist/types/docs.d.ts +0 -1
  312. package/dist/types/durable-job.d.ts +4 -4
  313. package/dist/types/durable-validation.d.ts +100 -2
  314. package/dist/types/durable-validation.js +165 -1
  315. package/dist/types/errors/structured-error.d.ts +3 -3
  316. package/dist/types/estimation.d.ts +2 -0
  317. package/dist/types/evidence-autofill.d.ts +34 -0
  318. package/dist/types/evidence-autofill.js +2 -0
  319. package/dist/types/evidence-gates.d.ts +9 -1
  320. package/dist/types/execution.d.ts +2 -0
  321. package/dist/types/gemini-integration.d.ts +0 -11
  322. package/dist/types/handoff-artifacts.d.ts +41 -0
  323. package/dist/types/hooks-advanced.d.ts +0 -13
  324. package/dist/types/impact-detection.d.ts +2 -2
  325. package/dist/types/index.d.ts +3 -6
  326. package/dist/types/index.js +2 -5
  327. package/dist/types/kiro-integration.d.ts +0 -6
  328. package/dist/types/network-policy.d.ts +1 -1
  329. package/dist/types/project/lint-scaffolder.d.ts +1 -1
  330. package/dist/types/runtime-policy.d.ts +11 -0
  331. package/dist/types/session-safeguard.d.ts +0 -31
  332. package/dist/types/spec/canonical-repair.d.ts +81 -0
  333. package/dist/types/spec/canonical-repair.js +2 -0
  334. package/dist/types/spec/core.d.ts +20 -0
  335. package/dist/types/spec/index.d.ts +1 -0
  336. package/dist/types/spec/index.js +1 -0
  337. package/dist/types/spec/inputs.d.ts +35 -1
  338. package/dist/types/spec-format.d.ts +25 -1
  339. package/dist/types/telemetry.d.ts +4 -1
  340. package/dist/types/transition-log.d.ts +1 -1
  341. package/dist/types/transport.d.ts +0 -2
  342. package/dist/types/usage.d.ts +1 -36
  343. package/dist/types/usage.js +1 -1
  344. package/dist/types/validate-worker.d.ts +6 -0
  345. package/dist/types/validation-receipt.d.ts +1 -1
  346. package/dist/types/validation.d.ts +10 -4
  347. package/package.json +17 -12
  348. package/planu-native.json +1 -1
  349. package/planu-plugin.json +23 -40
  350. package/scripts/lib/pending-release-file.mjs +93 -0
  351. package/src/i18n/messages/en.json +0 -41
  352. package/src/i18n/messages/es.json +0 -41
  353. package/src/i18n/messages/pt.json +0 -41
  354. package/dist/cli/commands/activate.d.ts +0 -14
  355. package/dist/cli/commands/activate.js +0 -174
  356. package/dist/config/license-plans.json +0 -251
  357. package/dist/config/product-public.ts +0 -148
  358. package/dist/config/server-instructions.ts +0 -121
  359. package/dist/config/version-defaults.ts +0 -76
  360. package/dist/config/version.ts +0 -21
  361. package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
  362. package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
  363. package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
  364. package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
  365. package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
  366. package/dist/engine/hooks/full-spectrum-generator.js +0 -117
  367. package/dist/engine/license-validator/config-loader.d.ts +0 -5
  368. package/dist/engine/license-validator/config-loader.js +0 -16
  369. package/dist/engine/license-validator/core.d.ts +0 -15
  370. package/dist/engine/license-validator/core.js +0 -151
  371. package/dist/engine/license-validator/fingerprint.d.ts +0 -3
  372. package/dist/engine/license-validator/fingerprint.js +0 -17
  373. package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
  374. package/dist/engine/license-validator/lemon-squeezy.js +0 -55
  375. package/dist/engine/license-validator.d.ts +0 -5
  376. package/dist/engine/license-validator.js +0 -6
  377. package/dist/engine/product-intelligence/index.d.ts +0 -7
  378. package/dist/engine/product-intelligence/index.js +0 -211
  379. package/dist/engine/session/auto-save.d.ts +0 -18
  380. package/dist/engine/session/auto-save.js +0 -98
  381. package/dist/engine/session/context-snapshot.d.ts +0 -8
  382. package/dist/engine/session/context-snapshot.js +0 -49
  383. package/dist/engine/session/memory-sync.d.ts +0 -12
  384. package/dist/engine/session/memory-sync.js +0 -34
  385. package/dist/engine/session/session-diff.d.ts +0 -11
  386. package/dist/engine/session/session-diff.js +0 -42
  387. package/dist/engine/session/session-merge.d.ts +0 -12
  388. package/dist/engine/session/session-merge.js +0 -55
  389. package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
  390. package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
  391. package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
  392. package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
  393. package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
  394. package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
  395. package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
  396. package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
  397. package/dist/engine/spec-changelog/core.d.ts +0 -16
  398. package/dist/engine/spec-changelog/core.js +0 -176
  399. package/dist/engine/spec-changelog/diff.d.ts +0 -18
  400. package/dist/engine/spec-changelog/diff.js +0 -121
  401. package/dist/engine/spec-changelog/index.d.ts +0 -3
  402. package/dist/engine/spec-changelog/index.js +0 -4
  403. package/dist/engine/trial-engine.d.ts +0 -5
  404. package/dist/engine/trial-engine.js +0 -14
  405. package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
  406. package/dist/engine/usage-tracker/rate-check.js +0 -18
  407. package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
  408. package/dist/engine/usage-tracker/rate-limiter.js +0 -73
  409. package/dist/engine/usage-tracker/trial.d.ts +0 -27
  410. package/dist/engine/usage-tracker/trial.js +0 -49
  411. package/dist/engine/webhook/event-handlers.d.ts +0 -25
  412. package/dist/engine/webhook/event-handlers.js +0 -89
  413. package/dist/engine/webhook/index.d.ts +0 -4
  414. package/dist/engine/webhook/index.js +0 -5
  415. package/dist/engine/webhook/server.d.ts +0 -12
  416. package/dist/engine/webhook/server.js +0 -249
  417. package/dist/engine/webhook/signature.d.ts +0 -16
  418. package/dist/engine/webhook/signature.js +0 -49
  419. package/dist/storage/license-store.d.ts +0 -6
  420. package/dist/storage/license-store.js +0 -63
  421. package/dist/storage/session-store.d.ts +0 -20
  422. package/dist/storage/session-store.js +0 -136
  423. package/dist/tools/activate-license.d.ts +0 -6
  424. package/dist/tools/activate-license.js +0 -132
  425. package/dist/tools/checkpoint-handler.d.ts +0 -3
  426. package/dist/tools/checkpoint-handler.js +0 -130
  427. package/dist/tools/export-session.d.ts +0 -3
  428. package/dist/tools/export-session.js +0 -90
  429. package/dist/tools/license-gate.d.ts +0 -18
  430. package/dist/tools/license-gate.js +0 -222
  431. package/dist/tools/license-status.d.ts +0 -3
  432. package/dist/tools/license-status.js +0 -93
  433. package/dist/tools/list-sessions.d.ts +0 -3
  434. package/dist/tools/list-sessions.js +0 -46
  435. package/dist/tools/planu-session-checkpoint.d.ts +0 -6
  436. package/dist/tools/planu-session-checkpoint.js +0 -42
  437. package/dist/tools/restore-session.d.ts +0 -3
  438. package/dist/tools/restore-session.js +0 -71
  439. package/dist/tools/spec-history.d.ts +0 -3
  440. package/dist/tools/spec-history.js +0 -59
  441. package/dist/tools/webhook.d.ts +0 -6
  442. package/dist/tools/webhook.js +0 -150
  443. package/dist/types/changelog.d.ts +0 -49
  444. package/dist/types/changelog.js +0 -3
  445. package/dist/types/licensing.d.ts +0 -109
  446. package/dist/types/licensing.js +0 -4
  447. package/dist/types/product-intelligence.d.ts +0 -60
  448. package/dist/types/product-intelligence.js +0 -3
  449. package/dist/types/session.d.ts +0 -84
  450. package/dist/types/session.js +0 -3
  451. package/dist/types/webhook.d.ts +0 -62
  452. package/dist/types/webhook.js +0 -4
@@ -1,6 +1,24 @@
1
- import { execFileSync, spawn } from 'node:child_process';
1
+ /* eslint-disable max-lines-per-function -- process-tree termination and single-settlement share one ownership boundary. */
2
+ import { spawn } from 'node:child_process';
2
3
  import { getExecutionSignal, remainingExecutionMs } from './execution/context.js';
3
- const TERM_GRACE_MS = 75;
4
+ export const PROCESS_TERMINATION_GRACE_MS = 75;
5
+ export const PROCESS_TREE_EXTINCTION_TIMEOUT_MS = 1_000;
6
+ export const PROCESS_CHILD_CLOSE_TIMEOUT_MS = 1_000;
7
+ let platformOverrideForTests;
8
+ let spawnOverrideForTests;
9
+ let processGroupLivenessOverrideForTests;
10
+ /** Isolates platform-specific process supervision in unit tests without changing host state. */
11
+ export function configureAbortableProcessRunnerForTests(options = {}) {
12
+ platformOverrideForTests = options.platform;
13
+ spawnOverrideForTests = options.spawnProcess;
14
+ processGroupLivenessOverrideForTests = options.isProcessGroupAlive;
15
+ }
16
+ function runtimePlatform() {
17
+ return platformOverrideForTests ?? process.platform;
18
+ }
19
+ function spawnProcess(...args) {
20
+ return (spawnOverrideForTests ?? spawn)(...args);
21
+ }
4
22
  function operationSignal(signal) {
5
23
  const parentSignal = getExecutionSignal();
6
24
  if (signal === undefined) {
@@ -11,29 +29,121 @@ function operationSignal(signal) {
11
29
  }
12
30
  return AbortSignal.any([signal, parentSignal]);
13
31
  }
32
+ function immediateAbortResult(reason) {
33
+ return {
34
+ stdout: '',
35
+ stderr: '',
36
+ status: null,
37
+ signal: null,
38
+ error: abortError(reason),
39
+ timedOut: false,
40
+ aborted: true,
41
+ };
42
+ }
43
+ function appendOutput(current, chunk, maxBufferBytes) {
44
+ return `${current}${chunk.toString('utf8')}`.slice(-maxBufferBytes);
45
+ }
46
+ function detachOwnedStreams(child, onStdout, onStderr) {
47
+ child.stdout?.removeListener('data', onStdout);
48
+ child.stderr?.removeListener('data', onStderr);
49
+ child.stdout?.destroy();
50
+ child.stderr?.destroy();
51
+ }
52
+ function delay(ms) {
53
+ return new Promise((resolve) => {
54
+ const timer = setTimeout(resolve, ms);
55
+ timer.unref();
56
+ });
57
+ }
58
+ function processGroupIsAlive(pid) {
59
+ if (processGroupLivenessOverrideForTests !== undefined) {
60
+ return processGroupLivenessOverrideForTests(pid);
61
+ }
62
+ try {
63
+ process.kill(-pid, 0);
64
+ return true;
65
+ }
66
+ catch (error) {
67
+ return error.code === 'EPERM';
68
+ }
69
+ }
70
+ async function awaitProcessGroupExtinction(pid) {
71
+ const deadlineAt = Date.now() + PROCESS_TREE_EXTINCTION_TIMEOUT_MS;
72
+ while (processGroupIsAlive(pid) && Date.now() < deadlineAt) {
73
+ await delay(Math.min(10, Math.max(1, deadlineAt - Date.now())));
74
+ }
75
+ return !processGroupIsAlive(pid);
76
+ }
77
+ async function terminateWindowsTree(child, childPid) {
78
+ if (childPid === undefined) {
79
+ child.kill('SIGKILL');
80
+ return false;
81
+ }
82
+ try {
83
+ const taskkill = spawnProcess('taskkill', ['/pid', String(childPid), '/T', '/F'], {
84
+ stdio: 'ignore',
85
+ windowsHide: true,
86
+ });
87
+ const succeeded = await new Promise((resolve) => {
88
+ let settled = false;
89
+ const finish = (value) => {
90
+ if (settled) {
91
+ return;
92
+ }
93
+ settled = true;
94
+ clearTimeout(timer);
95
+ resolve(value);
96
+ };
97
+ const timer = setTimeout(() => {
98
+ taskkill.kill('SIGKILL');
99
+ finish(false);
100
+ }, PROCESS_TREE_EXTINCTION_TIMEOUT_MS);
101
+ timer.unref();
102
+ taskkill.once('error', () => {
103
+ finish(false);
104
+ });
105
+ taskkill.once('close', (status) => {
106
+ finish(status === 0);
107
+ });
108
+ });
109
+ if (!succeeded) {
110
+ child.kill('SIGKILL');
111
+ }
112
+ return succeeded;
113
+ }
114
+ catch {
115
+ child.kill('SIGKILL');
116
+ return false;
117
+ }
118
+ }
119
+ export class ProcessTreeTerminationError extends Error {
120
+ code = 'PROCESS_TREE_TERMINATION_UNVERIFIED';
121
+ constructor() {
122
+ super('[Planu] PROCESS_TREE_TERMINATION_UNVERIFIED');
123
+ this.name = 'ProcessTreeTerminationError';
124
+ }
125
+ }
126
+ export class ChildProcessCloseTimeoutError extends Error {
127
+ code = 'PROCESS_CLOSE_UNOBSERVED';
128
+ constructor() {
129
+ super('[Planu] PROCESS_CLOSE_UNOBSERVED');
130
+ this.name = 'ChildProcessCloseTimeoutError';
131
+ }
132
+ }
14
133
  /**
15
134
  * Runs a validation command in its own process group. Cancellation and timeouts
16
- * terminate the complete group and settle only after the child has closed, so a
17
- * cancelled gate cannot keep writing output or publish late evidence.
135
+ * terminate the complete group and settle only after child closure or a bounded,
136
+ * typed close-observation failure, so a cancelled gate cannot publish late evidence.
18
137
  */
19
138
  export function runAbortableProcess(command, args, options) {
139
+ const signal = operationSignal(options.signal);
140
+ if (signal?.aborted === true) {
141
+ return Promise.resolve(immediateAbortResult(signal.reason));
142
+ }
20
143
  return new Promise((resolve) => {
21
- const signal = operationSignal(options.signal);
22
- if (signal?.aborted === true) {
23
- resolve({
24
- stdout: '',
25
- stderr: '',
26
- status: null,
27
- signal: null,
28
- error: abortError(signal.reason),
29
- timedOut: false,
30
- aborted: true,
31
- });
32
- return;
33
- }
34
- const child = spawn(command, args, {
144
+ const child = spawnProcess(command, args, {
35
145
  cwd: options.cwd,
36
- detached: process.platform !== 'win32',
146
+ detached: runtimePlatform() !== 'win32',
37
147
  stdio: ['ignore', 'pipe', 'pipe'],
38
148
  });
39
149
  let stdout = '';
@@ -42,53 +152,121 @@ export function runAbortableProcess(command, args, options) {
42
152
  let timedOut = false;
43
153
  let aborted = false;
44
154
  let processError;
45
- let hardStop;
46
- let deferredClose;
155
+ let terminationStarted = false;
156
+ let observedTerminationSignal = null;
157
+ let closeResult;
158
+ let terminationResolved = false;
159
+ let processTreeExtinct = false;
160
+ let closeFallbackTimer;
161
+ const childPid = child.pid;
47
162
  const parentRemainingMs = remainingExecutionMs();
48
163
  const timeoutMs = Math.max(0, Math.min(options.timeoutMs, parentRemainingMs));
49
- const append = (current, chunk) => `${current}${chunk.toString('utf8')}`.slice(-options.maxBufferBytes);
50
- child.stdout.on('data', (chunk) => {
51
- stdout = append(stdout, chunk);
52
- });
53
- child.stderr.on('data', (chunk) => {
54
- stderr = append(stderr, chunk);
55
- });
56
- const terminateTree = () => {
57
- if (child.pid === undefined) {
164
+ const onStdout = (chunk) => {
165
+ stdout = appendOutput(stdout, chunk, options.maxBufferBytes);
166
+ };
167
+ const onStderr = (chunk) => {
168
+ stderr = appendOutput(stderr, chunk, options.maxBufferBytes);
169
+ };
170
+ child.stdout?.on('data', onStdout);
171
+ child.stderr?.on('data', onStderr);
172
+ const finish = (status, closeSignal, forced = false) => {
173
+ if (settled) {
58
174
  return;
59
175
  }
60
- if (process.platform === 'win32') {
61
- try {
62
- execFileSync('taskkill', ['/pid', String(child.pid), '/T', '/F'], { stdio: 'ignore' });
63
- }
64
- catch {
65
- child.kill('SIGKILL');
66
- }
176
+ settled = true;
177
+ clearTimeout(timer);
178
+ if (closeFallbackTimer !== undefined) {
179
+ clearTimeout(closeFallbackTimer);
180
+ closeFallbackTimer = undefined;
181
+ }
182
+ signal?.removeEventListener('abort', onAbort);
183
+ child.removeListener('error', onError);
184
+ child.removeListener('close', onClose);
185
+ if (forced) {
186
+ detachOwnedStreams(child, onStdout, onStderr);
187
+ }
188
+ resolve({
189
+ stdout,
190
+ stderr,
191
+ status,
192
+ signal: closeSignal,
193
+ ...(processError ? { error: processError } : {}),
194
+ timedOut,
195
+ aborted,
196
+ });
197
+ };
198
+ const finishTerminatedProcess = () => {
199
+ if (!terminationResolved) {
67
200
  return;
68
201
  }
69
- try {
70
- process.kill(-child.pid, 'SIGTERM');
202
+ if (!processTreeExtinct) {
203
+ finish(null, observedTerminationSignal, true);
204
+ return;
71
205
  }
72
- catch {
73
- child.kill('SIGTERM');
206
+ if (closeResult === undefined) {
207
+ return;
208
+ }
209
+ finish(closeResult[0], closeResult[1] ?? observedTerminationSignal, true);
210
+ };
211
+ const scheduleCloseFallback = () => {
212
+ if (closeFallbackTimer !== undefined || closeResult !== undefined || !processTreeExtinct) {
213
+ return;
74
214
  }
75
- hardStop = setTimeout(() => {
76
- try {
77
- process.kill(-(child.pid ?? 0), 'SIGKILL');
215
+ closeFallbackTimer = setTimeout(() => {
216
+ closeFallbackTimer = undefined;
217
+ if (settled || closeResult !== undefined || !terminationResolved || !processTreeExtinct) {
218
+ return;
219
+ }
220
+ processError = new ChildProcessCloseTimeoutError();
221
+ finish(null, observedTerminationSignal, true);
222
+ }, PROCESS_CHILD_CLOSE_TIMEOUT_MS);
223
+ closeFallbackTimer.unref();
224
+ };
225
+ const terminateTree = () => {
226
+ if (terminationStarted || settled) {
227
+ return;
228
+ }
229
+ terminationStarted = true;
230
+ void (async () => {
231
+ if (runtimePlatform() === 'win32') {
232
+ processTreeExtinct = await terminateWindowsTree(child, childPid);
233
+ }
234
+ else if (childPid !== undefined) {
235
+ try {
236
+ process.kill(-childPid, 'SIGTERM');
237
+ observedTerminationSignal = 'SIGTERM';
238
+ }
239
+ catch {
240
+ child.kill('SIGTERM');
241
+ }
242
+ await delay(PROCESS_TERMINATION_GRACE_MS);
243
+ if (processGroupIsAlive(childPid)) {
244
+ try {
245
+ process.kill(-childPid, 'SIGKILL');
246
+ observedTerminationSignal = 'SIGKILL';
247
+ }
248
+ catch {
249
+ child.kill('SIGKILL');
250
+ observedTerminationSignal = 'SIGKILL';
251
+ }
252
+ }
253
+ processTreeExtinct = await awaitProcessGroupExtinction(childPid);
78
254
  }
79
- catch {
255
+ else {
80
256
  child.kill('SIGKILL');
81
257
  }
82
- hardStop = undefined;
83
- if (deferredClose !== undefined) {
84
- const [status, closeSignal] = deferredClose;
85
- deferredClose = undefined;
86
- finish(status, closeSignal);
258
+ if (!processTreeExtinct) {
259
+ processError = new ProcessTreeTerminationError();
87
260
  }
88
- }, TERM_GRACE_MS);
89
- hardStop.unref();
261
+ terminationResolved = true;
262
+ finishTerminatedProcess();
263
+ scheduleCloseFallback();
264
+ })();
90
265
  };
91
266
  const onAbort = () => {
267
+ if (terminationStarted || settled) {
268
+ return;
269
+ }
92
270
  aborted = true;
93
271
  processError = abortError(signal?.reason);
94
272
  terminateTree();
@@ -101,35 +279,26 @@ export function runAbortableProcess(command, args, options) {
101
279
  };
102
280
  signal?.addEventListener('abort', onAbort, { once: true });
103
281
  const timer = setTimeout(() => {
282
+ if (terminationStarted || settled) {
283
+ return;
284
+ }
104
285
  timedOut = true;
105
286
  processError = new Error(`Process timed out after ${String(timeoutMs)}ms`);
106
287
  terminateTree();
107
288
  }, timeoutMs);
108
- const finish = (status, closeSignal) => {
109
- if (settled) {
110
- return;
111
- }
112
- if (hardStop !== undefined && process.platform !== 'win32') {
113
- deferredClose = [status, closeSignal];
289
+ const onError = (error) => {
290
+ processError = error;
291
+ };
292
+ const onClose = (status, closeSignal) => {
293
+ if (terminationStarted) {
294
+ closeResult = [status, closeSignal];
295
+ finishTerminatedProcess();
114
296
  return;
115
297
  }
116
- settled = true;
117
- clearTimeout(timer);
118
- signal?.removeEventListener('abort', onAbort);
119
- resolve({
120
- stdout,
121
- stderr,
122
- status,
123
- signal: closeSignal,
124
- ...(processError ? { error: processError } : {}),
125
- timedOut,
126
- aborted,
127
- });
298
+ finish(status, closeSignal);
128
299
  };
129
- child.on('error', (error) => {
130
- processError = error;
131
- });
132
- child.on('close', finish);
300
+ child.on('error', onError);
301
+ child.on('close', onClose);
133
302
  });
134
303
  }
135
304
  function abortError(reason) {
@@ -1,6 +1,6 @@
1
1
  // engine/ambiguity-scorer.ts — SPEC-632: Detect undefined units and vague triggers in criteria
2
2
  import { readFile } from 'node:fs/promises';
3
- import { stripFrontmatter } from './frontmatter-parser.js';
3
+ import { extractAcceptanceCriteriaTexts } from './spec-format/acceptance-criteria.js';
4
4
  const VAGUE_UNITS = {
5
5
  fast: 'No latency target specified (e.g. "< 200ms")',
6
6
  slow: 'No latency target specified (e.g. "> 5s")',
@@ -96,27 +96,6 @@ export function scoreAmbiguity(criteriaLines) {
96
96
  : [];
97
97
  return { score, violations, blockers };
98
98
  }
99
- /** Minimal criteria extractor — same logic as readiness-checker without the full dependency chain. */
100
- function extractLines(body) {
101
- const lines = body.split('\n');
102
- const result = [];
103
- let inSection = false;
104
- for (const raw of lines) {
105
- const line = raw.trim();
106
- if (/^#{1,6}\s+/.test(line)) {
107
- inSection = /^#{1,6}\s+(acceptance\s+criteria|criteria|criterios)\b/i.test(line);
108
- continue;
109
- }
110
- if (/^- \[[ x]\]/i.test(line) || /^- .*\bgiven\b.*\bwhen\b.*\bthen\b/i.test(line)) {
111
- result.push(line);
112
- continue;
113
- }
114
- if (inSection && /^- \S/.test(line)) {
115
- result.push(line);
116
- }
117
- }
118
- return result;
119
- }
120
99
  /**
121
100
  * SPEC-632: Read spec file at path, extract criteria, and return an AmbiguityReport.
122
101
  * Returns null if file cannot be read (best-effort, never blocks).
@@ -124,12 +103,11 @@ function extractLines(body) {
124
103
  export async function scoreAmbiguityFromPath(specPath) {
125
104
  try {
126
105
  const raw = await readFile(specPath, 'utf-8');
127
- const body = stripFrontmatter(raw);
128
- const lines = extractLines(body);
129
- if (lines.length === 0) {
106
+ const criteria = extractAcceptanceCriteriaTexts(raw, { allowLegacyBodyFallback: false });
107
+ if (criteria.length === 0) {
130
108
  return null;
131
109
  }
132
- return scoreAmbiguity(lines);
110
+ return scoreAmbiguity(criteria);
133
111
  }
134
112
  catch {
135
113
  return null;
@@ -15,16 +15,12 @@ export const BUILTIN_SCOPE_MAPPINGS = [
15
15
  'validate',
16
16
  'analyze_spec_dependencies',
17
17
  'export_spec',
18
- 'export_session',
19
- 'list_sessions',
20
18
  'hook_status',
21
19
  'worker_status',
22
- 'webhook_status',
23
20
  'token_usage',
24
21
  'usage_report',
25
22
  'usage_stats',
26
23
  'llm_provider_status',
27
- 'license_status',
28
24
  'security_report',
29
25
  'pr_status',
30
26
  'agent_swarm_status',
@@ -56,8 +52,6 @@ export const BUILTIN_SCOPE_MAPPINGS = [
56
52
  'configure_llm_providers',
57
53
  'start_hooks',
58
54
  'stop_hooks',
59
- 'start_webhook',
60
- 'stop_webhook',
61
55
  'start_dashboard',
62
56
  'stop_dashboard',
63
57
  'manage_trash',
@@ -74,7 +68,7 @@ export const BUILTIN_SCOPE_MAPPINGS = [
74
68
  },
75
69
  {
76
70
  scope: 'planu:admin',
77
- tools: ['configure_auth', 'activate_license', 'deactivate_license', 'activate_group'],
71
+ tools: ['configure_auth', 'activate_group'],
78
72
  },
79
73
  ];
80
74
  /**
@@ -2,12 +2,13 @@
2
2
  // engine/autopilot/state-updater.ts — SPEC-459: Auto-update external project status on every status change
3
3
  // Fire-and-forget: never blocks the event pipeline, never throws to callers.
4
4
  // SPEC-753: File-lock applied to all writes; self-healing on corrupt reads.
5
- import { readFile, writeFile, mkdir } from 'node:fs/promises';
6
- import { join, dirname } from 'node:path';
5
+ import { readFile } from 'node:fs/promises';
6
+ import { join } from 'node:path';
7
7
  import { withStatusLock } from '../../storage/status-store/file-lock.js';
8
8
  import { validateStatusJson, rebuildStatusFromFrontmatters, writeRebuiltStatus, } from '../../storage/status-store/self-healing.js';
9
9
  import { syncVersionField } from '../../storage/status-store/version-sync.js';
10
10
  import { hashProjectPath, projectDataDir } from '../../storage/base-store.js';
11
+ import { atomicStatusWrite } from '../../storage/status-store/atomic-status-write.js';
11
12
  const STATUS_FILENAME = 'status.json';
12
13
  const MAX_RECENT_CHANGES = 20;
13
14
  function getStatusPath(projectPath) {
@@ -52,8 +53,7 @@ async function loadStatus(projectPath) {
52
53
  }
53
54
  async function saveStatus(projectPath, status) {
54
55
  const filePath = getStatusPath(projectPath);
55
- await mkdir(dirname(filePath), { recursive: true });
56
- await writeFile(filePath, JSON.stringify(status, null, 2), 'utf-8');
56
+ await atomicStatusWrite(filePath, status);
57
57
  }
58
58
  /**
59
59
  * Record a spec status change and recalculate counts.
@@ -1,3 +1,4 @@
1
+ import { reportClassifiedDegradation } from '../../../errors/classified-degradation.js';
1
2
  async function handler(ctx) {
2
3
  const { projectPath, specId, spec } = ctx;
3
4
  if (!projectPath) {
@@ -7,17 +8,19 @@ async function handler(ctx) {
7
8
  if (spec.scope === 'trivial') {
8
9
  return;
9
10
  }
10
- await import('../../../engine/technical-enricher/index.js')
11
- .then(({ runTechnicalEnricher }) => runTechnicalEnricher({ specId, projectPath, specScope: spec.scope }))
12
- .catch(() => {
13
- /* best-effort — never blocks update_status */
14
- });
11
+ try {
12
+ const { runTechnicalEnricher } = await import('../../../engine/technical-enricher/index.js');
13
+ await runTechnicalEnricher({ specId, projectPath, specScope: spec.scope });
14
+ }
15
+ catch {
16
+ reportClassifiedDegradation('REVIEW_ENRICHER_FAILED', new Error('Technical review enrichment failed'));
17
+ }
15
18
  }
16
19
  export const reviewEnricherHook = {
17
20
  id: 'review-enricher',
18
21
  triggers: ['review'],
19
22
  requiresProjectPath: true,
20
- label: 'Auto-enrich technical.md when spec moves to review (SPEC-696)',
23
+ label: 'Auto-enrich the bounded Technical spec section on review',
21
24
  handler,
22
25
  };
23
26
  //# sourceMappingURL=review-enricher.hook.js.map
@@ -1,8 +1,8 @@
1
- import type { DriftReport } from '../../types/cascade-hooks.js';
1
+ import type { StateFilesDriftReport } from '../../types/cascade-hooks.js';
2
2
  /**
3
3
  * SPEC-776: Compare in-memory spec counts vs external status.json and
4
4
  * recently-done spec vs planu/session-context.md.
5
- * Returns a DriftReport with any detected mismatches.
5
+ * Returns a StateFilesDriftReport with any detected mismatches.
6
6
  */
7
- export declare function verifyStateFiles(projectPath: string): Promise<DriftReport>;
7
+ export declare function verifyStateFiles(projectPath: string): Promise<StateFilesDriftReport>;
8
8
  //# sourceMappingURL=state-drift-detector.d.ts.map
@@ -62,7 +62,7 @@ function extractLastDoneSpecFromContext(content) {
62
62
  /**
63
63
  * SPEC-776: Compare in-memory spec counts vs external status.json and
64
64
  * recently-done spec vs planu/session-context.md.
65
- * Returns a DriftReport with any detected mismatches.
65
+ * Returns a StateFilesDriftReport with any detected mismatches.
66
66
  */
67
67
  export async function verifyStateFiles(projectPath) {
68
68
  const alerts = [];
@@ -4,7 +4,7 @@
4
4
  * This file configures the Planu CI check workflow behavior.
5
5
  */
6
6
  export function generatePlanuConfigYaml(options) {
7
- const { specsDir, failOnDrift, severityThreshold, postComment, badge, include, exclude, licenseKeyRef, } = options;
7
+ const { specsDir, failOnDrift, severityThreshold, postComment, badge, include, exclude } = options;
8
8
  const lines = ['# .planu.yml — Planu CI configuration', ''];
9
9
  // Specs section
10
10
  lines.push('specs:');
@@ -28,12 +28,6 @@ export function generatePlanuConfigYaml(options) {
28
28
  lines.push(` severity-threshold: ${severityThreshold}`);
29
29
  lines.push(` post-comment: ${String(postComment)}`);
30
30
  lines.push(` badge: ${String(badge)}`);
31
- // License section
32
- if (licenseKeyRef) {
33
- lines.push('');
34
- lines.push('license:');
35
- lines.push(` key: \${${licenseKeyRef}}`);
36
- }
37
31
  lines.push('');
38
32
  return lines.join('\n');
39
33
  }
@@ -1,5 +1,5 @@
1
- import type { GateContext, GateResult } from '../../types/clarification-token.js';
2
- export type { GateContext, GateResult };
1
+ import type { ClarificationGateContext, GateResult } from '../../types/clarification-token.js';
2
+ export type { ClarificationGateContext as GateContext, GateResult };
3
3
  /**
4
4
  * Check whether the tool is allowed to proceed.
5
5
  *
@@ -11,5 +11,5 @@ export type { GateContext, GateResult };
11
11
  * Fails open: if token storage is unavailable, the gate allows the call
12
12
  * to proceed rather than blocking the entire tool.
13
13
  */
14
- export declare function checkGate(ctx: GateContext): Promise<GateResult>;
14
+ export declare function checkGate(ctx: ClarificationGateContext): Promise<GateResult>;
15
15
  //# sourceMappingURL=gate.d.ts.map
@@ -1,5 +1,5 @@
1
1
  // src/engine/code-scanner/layer-scanner.ts — Scans the 4 implementation layers (SPEC-441)
2
- import { readFile, stat } from 'node:fs/promises';
2
+ import { stat } from 'node:fs/promises';
3
3
  import { join, relative, basename } from 'node:path';
4
4
  import { fastFindFilesByExt, fastReadFiles } from '../core-bridge.js';
5
5
  /**
@@ -25,8 +25,8 @@ export async function scanLayers(projectPath, keywords, symbolVariants) {
25
25
  const symbols = findSymbols(filesToScanForSymbols, symbolVariants);
26
26
  // Layer 3: test files matching keywords
27
27
  const matchedTests = testFiles.filter((f) => keywords.some((kw) => basename(f).toLowerCase().includes(kw)));
28
- // Layer 4: registrations in license-plans.json and register-*.ts files
29
- const registrations = await findRegistrations(projectPath, srcFiles, keywords);
28
+ // Layer 4: registrations in canonical registry source files.
29
+ const registrations = findRegistrations(projectPath, srcFiles, keywords);
30
30
  return {
31
31
  files: matchedFiles.map((f) => relative(projectPath, f)),
32
32
  symbols,
@@ -55,27 +55,11 @@ function findSymbols(files, variants) {
55
55
  }
56
56
  return [...found];
57
57
  }
58
- async function findRegistrations(projectPath, srcFiles, keywords) {
58
+ function findRegistrations(_projectPath, srcFiles, keywords) {
59
59
  const found = new Set();
60
- // Check license-plans.json for tool names matching keywords
61
- const licensePath = join(projectPath, 'src', 'config', 'license-plans.json');
62
- try {
63
- const content = await readFile(licensePath, 'utf8');
64
- const json = JSON.parse(content);
65
- const allTools = [...(json.freeTools ?? []), ...(json.proTools ?? [])];
66
- for (const tool of allTools) {
67
- if (keywords.some((kw) => tool.includes(kw))) {
68
- found.add(`license:${tool}`);
69
- }
70
- }
71
- }
72
- catch {
73
- // not a planu project — skip
74
- }
75
- // Check register-*.ts files for registerTool calls matching keywords
76
- const registerFiles = srcFiles.filter((f) => /register.*\.ts$/.test(f));
60
+ const registerFiles = srcFiles.filter((f) => /register.*\.ts$|tool-registry\/.*\.ts$/.test(f));
77
61
  if (registerFiles.length > 0) {
78
- const REGISTER_RE = /registerTool\s*\(\s*['"]([^'"]+)['"]/g;
62
+ const REGISTER_RE = /(?:registerTool\s*\(\s*|name:\s*)['"]([^'"]+)['"]/g;
79
63
  for (const file of fastReadFiles(registerFiles)) {
80
64
  let match;
81
65
  while ((match = REGISTER_RE.exec(file.content)) !== null) {
@@ -1,8 +1,8 @@
1
- import type { FileHash, FileMetadata, SpecAnnotation, DriftResult, PlanuCore, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, SearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, NativeRuntimeHandshake, NativeRuntimeCompatibility, NativeArtifactManifest, NativeLoadDiagnostic } from '../types/core-bridge.js';
1
+ import type { FileHash, FileMetadata, SpecAnnotation, DriftResult, PlanuCore, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, NativeVectorSearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, NativeRuntimeHandshake, NativeRuntimeCompatibility, NativeArtifactManifest, NativeLoadDiagnostic } from '../types/core-bridge.js';
2
2
  import type { MacOSKeychainNativePort } from '../types/security.js';
3
3
  import { negotiateNativeRuntime, NATIVE_CAPABILITY_ABI, NATIVE_NODE_API_ABI, NATIVE_PROTOCOL_ABI, RUNTIME_STORAGE_SCHEMA } from './native-runtime-handshake.js';
4
4
  export { negotiateNativeRuntime, NATIVE_CAPABILITY_ABI, NATIVE_NODE_API_ABI, NATIVE_PROTOCOL_ABI, RUNTIME_STORAGE_SCHEMA, };
5
- export type { FileHash, FileMetadata, SpecAnnotation, DriftResult, PlanuCore, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, SearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, NativeRuntimeHandshake, NativeRuntimeCompatibility, NativeArtifactManifest, NativeLoadDiagnostic as LoadDiagnostic, };
5
+ export type { FileHash, FileMetadata, SpecAnnotation, DriftResult, PlanuCore, DuplicateRawBlockRs, DuplicateBlockLocationRs, FastGrepMatch, FileContent, SpecBriefRs, AmbiguousCriterionRs, GapsLogChainResultRs, NativeVectorSearchResult, VectorNode, ProjectGraphSourceFileRs, TsRelationRs, GraphNodeInputRs, GraphEdgeInputRs, AffectedNodeRs, ShortestPathResultRs, CompactGraphSliceRs, CompactGraphEdgesRs, ProjectGraphLimitsPolicyRs, ResolvedProjectGraphLimitsRs, NativeRuntimeHandshake, NativeRuntimeCompatibility, NativeArtifactManifest, NativeLoadDiagnostic as LoadDiagnostic, };
6
6
  export declare function currentNativePackageName(): string | null;
7
7
  /** Main-thread port for async Keychain calls; never accepts override or unverified native code. */
8
8
  export declare function requireMacOSKeychainNativePort(): MacOSKeychainNativePort;
@@ -23,7 +23,7 @@ export declare function fastScanSpecs(rootPath: string): SpecBriefRs[] | null;
23
23
  export declare function fastVerifyGapsChain(filePath: string): GapsLogChainResultRs;
24
24
  export declare function fastAppendGapEntry(filePath: string, id: string, timestamp: string, specId: string, description: string, severity: string, affectedSpecs: string[]): string;
25
25
  export declare function fastCosineSimilarity(v1: number[], v2: number[]): number;
26
- export declare function fastHnswSearchFlat(query: number[], nodes: VectorNode[], topK: number): SearchResult[];
26
+ export declare function fastHnswSearchFlat(query: number[], nodes: VectorNode[], topK: number): NativeVectorSearchResult[];
27
27
  export declare function fastHmacSign(secret: string, data: string): string;
28
28
  export declare function fastHmacVerify(secret: string, data: string, signature: string): boolean;
29
29
  export declare function fastScanProjectGraphSources(rootPath: string, policy: ProjectGraphLimitsPolicyRs, overrides?: Partial<ResolvedProjectGraphLimitsRs>): ProjectGraphSourceFileRs[];
@@ -9,7 +9,7 @@ export declare function computeBudgetStatus(budget: SpecBudget): SpecBudgetStatu
9
9
  */
10
10
  export declare function formatBudgetMessage(status: SpecBudgetStatus): string;
11
11
  /**
12
- * Enforces budget limits before executing a licensed tool.
12
+ * Enforces engineering budget limits before executing a governed tool.
13
13
  * - If no budget is configured for the spec → no-op (pass through).
14
14
  * - If budget is exhausted → throws an Error to block tool execution.
15
15
  * - If warning threshold is reached → logs a warning but allows execution.