@planu/cli 5.3.67 → 5.3.69

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 (389) hide show
  1. package/CHANGELOG.md +92 -0
  2. package/dist/.planu-build.json +1 -1
  3. package/dist/cli/commands/install.d.ts +2 -15
  4. package/dist/config/release-policy.json +2 -2
  5. package/dist/core/shared/fs.d.ts +11 -0
  6. package/dist/core/shared/fs.js +90 -0
  7. package/dist/core/shared/strings.d.ts +3 -0
  8. package/dist/core/shared/strings.js +13 -0
  9. package/dist/engine/actuals/git-analyzer.js +1 -1
  10. package/dist/engine/actuals/progress-parser.js +1 -3
  11. package/dist/engine/agent-handoff-store.js +1 -0
  12. package/dist/engine/agent-squad/dispatcher.js +1 -0
  13. package/dist/engine/agent-telemetry.js +1 -0
  14. package/dist/engine/auth/config.js +1 -0
  15. package/dist/engine/auto-updater/atomic-upgrade.js +1 -0
  16. package/dist/engine/auto-updater/index.js +1 -0
  17. package/dist/engine/autopilot/action-registry.js +20 -0
  18. package/dist/engine/autopilot/audit-logger.js +1 -0
  19. package/dist/engine/autopilot/bootstrap.js +9 -2
  20. package/dist/engine/autopilot/complete-loop.js +4 -0
  21. package/dist/engine/autopilot/crash-shield-rate-limiter.js +1 -0
  22. package/dist/engine/autopilot/event-bus.js +1 -0
  23. package/dist/engine/autopilot/state-updater.js +6 -0
  24. package/dist/engine/browser-validator.js +1 -3
  25. package/dist/engine/build-tool-detector.js +1 -8
  26. package/dist/engine/bundle-installer.js +2 -10
  27. package/dist/engine/cascade-hooks/core/append-releases.js +1 -0
  28. package/dist/engine/cascade-hooks/core/write-session-json.js +2 -2
  29. package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.d.ts +3 -1
  30. package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.js +12 -3
  31. package/dist/engine/cascade-hooks/hooks/estimate-calibration.hook.js +1 -0
  32. package/dist/engine/cascade-hooks/hooks/housekeeping-on-done.hook.js +2 -0
  33. package/dist/engine/cascade-hooks/hooks/implementing-kickoff.hook.js +5 -1
  34. package/dist/engine/cascade-hooks/hooks/lesson-drift.hook.js +1 -0
  35. package/dist/engine/cascade-hooks/hooks/orchestration-plan.hook.js +1 -0
  36. package/dist/engine/cascade-hooks/hooks/session-context.hook.js +4 -2
  37. package/dist/engine/cascade-hooks/hooks/slack-notify.hook.js +1 -0
  38. package/dist/engine/cascade-hooks/hooks/status-json.hook.js +2 -0
  39. package/dist/engine/cascade-hooks/hooks/velocity-profile.hook.js +2 -0
  40. package/dist/engine/cascade-hooks/runner.js +2 -0
  41. package/dist/engine/cascade-hooks/state-drift-detector.js +2 -0
  42. package/dist/engine/checkpoint/checkpoint-manager.js +2 -0
  43. package/dist/engine/checkpoint/policy-engine.js +1 -0
  44. package/dist/engine/ci-generator/stack-detector.js +2 -10
  45. package/dist/engine/clarification-gate/token-store.js +1 -0
  46. package/dist/engine/claude-config-auditor/claudemd-auditor.js +2 -10
  47. package/dist/engine/claude-config-auditor/settings-auditor.js +2 -10
  48. package/dist/engine/client-detection.js +2 -10
  49. package/dist/engine/compliance/auto-remediator.js +1 -0
  50. package/dist/engine/compliance/evidence-builder.d.ts +2 -2
  51. package/dist/engine/compliance/framework-catalog.d.ts +6 -6
  52. package/dist/engine/compliance/gap-analyzer.d.ts +2 -2
  53. package/dist/engine/config-health/build-tool-checker.js +1 -9
  54. package/dist/engine/config-health/ci-commands-collector.d.ts +2 -1
  55. package/dist/engine/config-health/ci-commands-collector.js +2 -9
  56. package/dist/engine/config-health/go-checker.js +1 -9
  57. package/dist/engine/config-health/mcp-config-checker.js +2 -10
  58. package/dist/engine/config-health/python-checker.js +1 -9
  59. package/dist/engine/config-health/rust-checker.js +1 -9
  60. package/dist/engine/config-health/ts-checker-scripts.js +1 -9
  61. package/dist/engine/config-health/ts-checker.js +1 -9
  62. package/dist/engine/context-artifacts/store.js +1 -0
  63. package/dist/engine/context-md-generator.js +1 -0
  64. package/dist/engine/context-orchestrator/index.js +2 -0
  65. package/dist/engine/convention-scanner/convention-parser.js +2 -9
  66. package/dist/engine/cost-guardrails.js +1 -0
  67. package/dist/engine/cost-tracking/ledger.js +1 -0
  68. package/dist/engine/criterion-identity.js +1 -1
  69. package/dist/engine/dashboard/data-loader.js +1 -0
  70. package/dist/engine/dashboard/drift-score.js +2 -0
  71. package/dist/engine/dashboard/spec-updater.d.ts +3 -1
  72. package/dist/engine/dashboard/spec-updater.js +9 -2
  73. package/dist/engine/dashboard/templates-layout.d.ts +2 -2
  74. package/dist/engine/dashboard/templates-layout.js +2 -9
  75. package/dist/engine/data-projects-gc/gc-runner.js +2 -4
  76. package/dist/engine/deleter/audit-logger.js +1 -0
  77. package/dist/engine/deleter/core.js +6 -0
  78. package/dist/engine/deleter/trash-manager.js +1 -0
  79. package/dist/engine/desktop-detector.js +1 -9
  80. package/dist/engine/detection-utils.d.ts +2 -1
  81. package/dist/engine/detection-utils.js +3 -10
  82. package/dist/engine/detectors/advanced-framework-detector/helpers.d.ts +3 -2
  83. package/dist/engine/detectors/advanced-framework-detector/helpers.js +3 -17
  84. package/dist/engine/detectors/cicd-detector.js +2 -10
  85. package/dist/engine/detectors/css-framework-detector.js +2 -10
  86. package/dist/engine/detectors/deployment-detector.js +3 -12
  87. package/dist/engine/detectors/frontend-perf-detector.js +2 -10
  88. package/dist/engine/detectors/gitops-detector.js +3 -11
  89. package/dist/engine/detectors/idp-detector.js +1 -3
  90. package/dist/engine/detectors/k3s-detector.js +3 -11
  91. package/dist/engine/detectors/llm-detector/file-readers.d.ts +2 -1
  92. package/dist/engine/detectors/llm-detector/file-readers.js +2 -9
  93. package/dist/engine/detectors/mfe-detector.js +5 -13
  94. package/dist/engine/detectors/monitoring-detector.js +2 -11
  95. package/dist/engine/detectors/monorepo-detector.d.ts +1 -0
  96. package/dist/engine/detectors/monorepo-detector.js +1 -10
  97. package/dist/engine/detectors/nomad-detector.js +3 -11
  98. package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -1
  99. package/dist/engine/detectors/otel-ecosystem-detectors.js +2 -10
  100. package/dist/engine/doc-generator/executive-summary/html-template.js +1 -7
  101. package/dist/engine/doc-generator/executive-summary/section-builders.js +1 -7
  102. package/dist/engine/doc-generator/per-spec-report/mermaid-renderer.js +1 -7
  103. package/dist/engine/doc-generator/per-spec-report/spec-section-builders.js +1 -7
  104. package/dist/engine/doc-generator/per-spec-report/technical-report.js +1 -7
  105. package/dist/engine/doc-generator/portal/analytics-page.js +1 -7
  106. package/dist/engine/doc-generator/portal/architecture-page.js +1 -7
  107. package/dist/engine/doc-generator/portal/changelog-page.js +1 -7
  108. package/dist/engine/doc-generator/portal/decision-page.js +1 -7
  109. package/dist/engine/doc-generator/portal/decision-timeline-builder.js +1 -7
  110. package/dist/engine/doc-generator/portal/kanban-view-builder.js +1 -7
  111. package/dist/engine/doc-generator/portal/portal-breadcrumbs.js +1 -7
  112. package/dist/engine/doc-generator/portal/portal-landing-cards.js +1 -7
  113. package/dist/engine/doc-generator/portal/portal-navbar.js +1 -7
  114. package/dist/engine/doc-generator/portal/portal-page-detector.d.ts +3 -0
  115. package/dist/engine/doc-generator/portal/portal-page-detector.js +1 -10
  116. package/dist/engine/doc-generator/portal/portal-regenerator.js +2 -0
  117. package/dist/engine/doc-generator/portal/risk-matrix-svg.js +1 -7
  118. package/dist/engine/doc-generator/portal/risk-page.js +1 -7
  119. package/dist/engine/doc-generator/portal/roadmap-page.js +1 -7
  120. package/dist/engine/doc-generator/proposal/proposal-gantt-builder.js +1 -7
  121. package/dist/engine/doc-generator/proposal/proposal-kpi-builder.js +1 -7
  122. package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.js +2 -8
  123. package/dist/engine/doc-generator/proposal/proposal-section-builders.js +1 -7
  124. package/dist/engine/docs-site-generator/html-templates.js +1 -7
  125. package/dist/engine/docs-site-generator/markdown-renderer.js +1 -7
  126. package/dist/engine/drift/violation-resolver.js +2 -0
  127. package/dist/engine/dynamic-knowledge/knowledge-cache.js +1 -0
  128. package/dist/engine/ecosystem-absorber/knowledge-cache.js +1 -0
  129. package/dist/engine/edge-db-detector.js +1 -10
  130. package/dist/engine/escalator/retry-counter.js +1 -0
  131. package/dist/engine/evidence-gates/artifact-reader.js +1 -0
  132. package/dist/engine/evidence-gates/evidence-autofill.js +1 -0
  133. package/dist/engine/evidence-gates/evidence-skeletons.js +1 -0
  134. package/dist/engine/evidence-gates/reconciliation-freshness.js +1 -0
  135. package/dist/engine/execution/durable-job-heartbeat-runtime.js +1 -0
  136. package/dist/engine/execution/job-runtime.js +2 -0
  137. package/dist/engine/execution/validate-job-executor.d.ts +1 -1
  138. package/dist/engine/execution/validate-job-executor.js +3 -0
  139. package/dist/engine/execution/validate-job-payload.js +1 -0
  140. package/dist/engine/execution/validate-worker-thread.js +1 -0
  141. package/dist/engine/facilitate/context-loader.js +1 -0
  142. package/dist/engine/figma/change-detector.d.ts +1 -8
  143. package/dist/engine/figma/code-connect-fetcher.d.ts +1 -7
  144. package/dist/engine/figma/design-enricher.d.ts +1 -17
  145. package/dist/engine/figma/design-enricher.js +0 -1
  146. package/dist/engine/figma/e2e-generator.d.ts +1 -23
  147. package/dist/engine/figma/flow-analyzer.d.ts +1 -11
  148. package/dist/engine/figma/frame-extractor.d.ts +1 -11
  149. package/dist/engine/figma/frame-extractor.js +3 -0
  150. package/dist/engine/figma/multi-file-manager.d.ts +1 -6
  151. package/dist/engine/figma/spec-generator.js +2 -0
  152. package/dist/engine/figma/thumbnail-fetcher.d.ts +1 -1
  153. package/dist/engine/figma/token-extractor.d.ts +1 -6
  154. package/dist/engine/figma/token-extractor.js +0 -1
  155. package/dist/engine/figma/version-tracker.d.ts +1 -7
  156. package/dist/engine/figma/version-tracker.js +0 -1
  157. package/dist/engine/figma/visual-qa.d.ts +5 -19
  158. package/dist/engine/figma/visual-qa.js +1 -2
  159. package/dist/engine/figma/webhook-manager.d.ts +1 -7
  160. package/dist/engine/frontmatter-sha/reseal.js +1 -0
  161. package/dist/engine/frontmatter-sha/verify-terminal.js +1 -0
  162. package/dist/engine/git-hook-injector.js +2 -10
  163. package/dist/engine/github/quality-dimensions.js +1 -3
  164. package/dist/engine/global-rules-manager.js +2 -3
  165. package/dist/engine/handoff-artifacts/implementation-review-reader.js +1 -0
  166. package/dist/engine/handoff-artifacts/io.js +2 -0
  167. package/dist/engine/handoff-packager.js +2 -1
  168. package/dist/engine/health/auto-fixer.js +1 -0
  169. package/dist/engine/hooks/context-injector.js +1 -0
  170. package/dist/engine/hooks-reconciler.js +1 -8
  171. package/dist/engine/impact-detector/index.js +2 -9
  172. package/dist/engine/implementation-contract/common.js +1 -3
  173. package/dist/engine/implementation-contract/evaluator.js +1 -3
  174. package/dist/engine/keyword-matcher/boundary.d.ts +2 -7
  175. package/dist/engine/keyword-matcher/boundary.js +2 -14
  176. package/dist/engine/lifecycle-reconciliation-io.js +1 -0
  177. package/dist/engine/lifecycle-reconciliation.js +3 -0
  178. package/dist/engine/local-first/detector.js +1 -9
  179. package/dist/engine/marketplace-fetcher/cache.js +2 -0
  180. package/dist/engine/marketplace-fetcher/index.js +1 -0
  181. package/dist/engine/mcp-config/mcp-config-writer.js +2 -10
  182. package/dist/engine/migrations/remove-commercial-state.js +2 -0
  183. package/dist/engine/mobile-detector-shared.d.ts +1 -1
  184. package/dist/engine/mobile-detector-shared.js +2 -9
  185. package/dist/engine/multi-channel-notifier.js +1 -0
  186. package/dist/engine/multi-teammate-review/disagreement-counter.js +1 -0
  187. package/dist/engine/multi-teammate-review/panel-orchestrator.js +1 -0
  188. package/dist/engine/onboarding-engine.js +1 -9
  189. package/dist/engine/permissions-merger/stack-detectors.js +2 -10
  190. package/dist/engine/pii-detector/core.js +1 -3
  191. package/dist/engine/platform-engineering/dx-analyzer.js +1 -10
  192. package/dist/engine/platform-engineering/idp-detector.js +2 -10
  193. package/dist/engine/project-dna/ai-tool-detector.js +2 -10
  194. package/dist/engine/project-dna/stack-detector.js +2 -10
  195. package/dist/engine/project-graph/builder.js +11 -2
  196. package/dist/engine/project-graph/cache.d.ts +5 -2
  197. package/dist/engine/project-graph/cache.js +174 -34
  198. package/dist/engine/project-graph/extractors/decision-store-extractor.js +1 -0
  199. package/dist/engine/project-graph/freshness-projection.js +3 -0
  200. package/dist/engine/project-graph/query.js +14 -11
  201. package/dist/engine/project-health-checker.js +2 -6
  202. package/dist/engine/provider-adapters/shared/spec-loader.js +1 -0
  203. package/dist/engine/quality-gates/gate-evaluator.js +1 -3
  204. package/dist/engine/react-detector.js +6 -14
  205. package/dist/engine/reconcile/apply-changes.js +1 -3
  206. package/dist/engine/registry/core.js +1 -0
  207. package/dist/engine/registry/loader.js +2 -0
  208. package/dist/engine/release/postmortem-generator.js +1 -0
  209. package/dist/engine/release/rollback-runner.d.ts +2 -2
  210. package/dist/engine/release/stuck-spec-detector.js +7 -0
  211. package/dist/engine/release-pipeline/release-spec-closer.js +3 -0
  212. package/dist/engine/rules-reconciler.d.ts +1 -1
  213. package/dist/engine/rules-reconciler.js +2 -9
  214. package/dist/engine/safety/atomic-writer.js +1 -0
  215. package/dist/engine/safety/cross-process-lock.js +2 -0
  216. package/dist/engine/safety/file-mutex.js +1 -0
  217. package/dist/engine/safety/lock-lease-store.js +1 -0
  218. package/dist/engine/safety/lock-scavenger.js +2 -0
  219. package/dist/engine/saga/transition-cascade.js +3 -0
  220. package/dist/engine/scan-project/index.js +1 -0
  221. package/dist/engine/scan-project/module-discoverer.js +1 -9
  222. package/dist/engine/schema-parity-auditor/handler-checker.js +1 -3
  223. package/dist/engine/schema-parity-auditor/index.js +1 -3
  224. package/dist/engine/schema-parity-auditor/type-checker.js +1 -3
  225. package/dist/engine/self-healing/strategies/coverage-fix.js +2 -10
  226. package/dist/engine/session-context-generator.d.ts +8 -0
  227. package/dist/engine/session-context-generator.js +33 -23
  228. package/dist/engine/session-state/session-artifact-refresher.d.ts +7 -0
  229. package/dist/engine/session-state/session-artifact-refresher.js +140 -0
  230. package/dist/engine/session-state/writer.d.ts +3 -0
  231. package/dist/engine/session-state/writer.js +35 -17
  232. package/dist/engine/shared-agent-memory.js +1 -0
  233. package/dist/engine/skill-adapter/index.js +3 -0
  234. package/dist/engine/skill-bootstrap/registry-fetcher.js +1 -0
  235. package/dist/engine/skill-bootstrap/skill-writer.js +2 -9
  236. package/dist/engine/skill-bootstrap/stack-matcher.js +1 -9
  237. package/dist/engine/skill-discovery/multi-agent-writer.d.ts +1 -0
  238. package/dist/engine/skill-discovery/multi-agent-writer.js +1 -9
  239. package/dist/engine/skill-generator/workflow-skill-generator.js +1 -0
  240. package/dist/engine/skill-registry/ttl-refresh.js +2 -0
  241. package/dist/engine/spec-audit/index.js +2 -0
  242. package/dist/engine/spec-audit/report-writer.js +1 -0
  243. package/dist/engine/spec-coverage/core.js +1 -0
  244. package/dist/engine/spec-decomposer/analyzer.js +1 -11
  245. package/dist/engine/spec-dependency-graph/dot-exporter.d.ts +1 -1
  246. package/dist/engine/spec-dependency-graph/graph-builder.d.ts +1 -20
  247. package/dist/engine/spec-dependency-graph/superseded-set.d.ts +1 -1
  248. package/dist/engine/spec-diff-engine.js +1 -7
  249. package/dist/engine/spec-format/read-technical-section.js +1 -3
  250. package/dist/engine/spec-format/replace-section.js +1 -3
  251. package/dist/engine/spec-format/spec-id.d.ts +9 -1
  252. package/dist/engine/spec-format/spec-id.js +24 -3
  253. package/dist/engine/spec-format/unified-spec-builder.js +1 -3
  254. package/dist/engine/spec-migrator/canonical-deduplicator.js +2 -0
  255. package/dist/engine/spec-observability/tracker.js +1 -0
  256. package/dist/engine/spec-registry/adapter.js +2 -10
  257. package/dist/engine/spec-registry/validator.d.ts +1 -0
  258. package/dist/engine/spec-registry/validator.js +1 -9
  259. package/dist/engine/spec-state-machine/transition-spec.js +1 -0
  260. package/dist/engine/spec-templates/custom-loader.js +1 -0
  261. package/dist/engine/stack-auditor/build-tool-auditor.js +1 -9
  262. package/dist/engine/staleness/stale-implementing.js +5 -14
  263. package/dist/engine/status-reconciler/index.js +4 -1
  264. package/dist/engine/structural-memory/helpers.js +1 -0
  265. package/dist/engine/supply-chain/slsa-checker.js +1 -9
  266. package/dist/engine/tdd-enforcer/stub-artifact-path.js +1 -0
  267. package/dist/engine/telemetry/health-checker.js +1 -0
  268. package/dist/engine/telemetry/telemetry-store.js +1 -0
  269. package/dist/engine/token-optimizer/response-cache.js +1 -3
  270. package/dist/engine/tool-groups/group-manager.js +2 -0
  271. package/dist/engine/update-notifier.js +1 -0
  272. package/dist/engine/validation/approved-spec-portability.js +1 -0
  273. package/dist/engine/validation/durable-validation.js +1 -0
  274. package/dist/engine/validation/validation-freshness.js +2 -0
  275. package/dist/engine/validation/validation-receipt.js +1 -0
  276. package/dist/engine/validation/validation-submission.d.ts +1 -1
  277. package/dist/engine/validation-evidence-ledger.js +1 -0
  278. package/dist/engine/validator/deep-code-checker.js +1 -3
  279. package/dist/engine/validator/executable-evidence.d.ts +1 -14
  280. package/dist/engine/validator/scope-resolver.d.ts +2 -2
  281. package/dist/engine/validator/spec-compliance-runner.d.ts +1 -31
  282. package/dist/engine/validator/validation-report-writer.js +1 -1
  283. package/dist/engine/validator.d.ts +1 -1
  284. package/dist/engine/validator.js +1 -0
  285. package/dist/engine/velocity/measure-velocity.js +2 -0
  286. package/dist/engine/version-resolver.js +1 -0
  287. package/dist/engine/workers/handlers/auto-drift.js +3 -0
  288. package/dist/engine/workspace-manager.js +4 -0
  289. package/dist/hosts/gemini/config-scaffold.js +2 -10
  290. package/dist/storage/approval-operation-lock.js +1 -0
  291. package/dist/storage/auto-promoter-config-store.js +1 -0
  292. package/dist/storage/autopilot-log-store.js +1 -0
  293. package/dist/storage/base-store.js +1 -0
  294. package/dist/storage/checkpoint-store.js +1 -0
  295. package/dist/storage/feedback-remote.js +1 -0
  296. package/dist/storage/gaps-log.js +1 -0
  297. package/dist/storage/global-projects-store.d.ts +17 -0
  298. package/dist/storage/global-projects-store.js +47 -0
  299. package/dist/storage/global-store.js +1 -0
  300. package/dist/storage/knowledge-store/sessions.js +2 -0
  301. package/dist/storage/migrations/canonical-storage.js +42 -18
  302. package/dist/storage/project-drift-store.js +1 -0
  303. package/dist/storage/project-identity.d.ts +27 -0
  304. package/dist/storage/project-identity.js +132 -2
  305. package/dist/storage/project-resolver.js +1 -17
  306. package/dist/storage/runtime-db.d.ts +2 -20
  307. package/dist/storage/runtime-db.js +2 -9
  308. package/dist/storage/semantic-index-store.js +1 -0
  309. package/dist/storage/sentry-store.js +1 -0
  310. package/dist/storage/session-state-store.js +1 -0
  311. package/dist/storage/spec-store.d.ts +31 -3
  312. package/dist/storage/spec-store.js +146 -5
  313. package/dist/storage/status-store/atomic-status-write.js +1 -0
  314. package/dist/storage/status-store/file-lock.js +1 -0
  315. package/dist/storage/status-store/self-healing.js +1 -0
  316. package/dist/storage/storage-bundle.d.ts +12 -2
  317. package/dist/storage/supabase-store.js +1 -0
  318. package/dist/storage/technology-selection-store.js +1 -0
  319. package/dist/storage/trash-store.d.ts +2 -4
  320. package/dist/storage/trash-store.js +2 -15
  321. package/dist/storage/vector-store/json-fallback.js +1 -0
  322. package/dist/storage/vector-store/migrator.js +1 -0
  323. package/dist/storage/vector-store/sqlite-adapter.js +1 -0
  324. package/dist/tools/audit-claude-config.js +1 -10
  325. package/dist/tools/challenge-spec-helpers.d.ts +1 -1
  326. package/dist/tools/challenge-spec-helpers.js +7 -2
  327. package/dist/tools/challenge-spec.js +11 -6
  328. package/dist/tools/check-readiness.js +121 -24
  329. package/dist/tools/clarify-requirements/multiple-choice.d.ts +3 -3
  330. package/dist/tools/configure-oauth-handler.js +1 -0
  331. package/dist/tools/create-spec-helpers.d.ts +1 -3
  332. package/dist/tools/create-spec-helpers.js +1 -8
  333. package/dist/tools/create-spec.js +1 -13
  334. package/dist/tools/dashboard.js +5 -0
  335. package/dist/tools/generate-execution-plan.js +10 -6
  336. package/dist/tools/github-pr-handler.js +1 -0
  337. package/dist/tools/github-release-handler.d.ts +1 -0
  338. package/dist/tools/github-release-handler.js +4 -3
  339. package/dist/tools/graph-specs.d.ts +1 -1
  340. package/dist/tools/heal-spec-docs.js +1 -3
  341. package/dist/tools/init-project/git-setup.d.ts +2 -2
  342. package/dist/tools/init-project/host-assets-writer.js +2 -10
  343. package/dist/tools/init-project/lifecycle-helpers.d.ts +2 -2
  344. package/dist/tools/init-project/lint-scaffolder.js +2 -10
  345. package/dist/tools/init-project/stack-detector.d.ts +2 -2
  346. package/dist/tools/reconcile-interactive-question-hooks.d.ts +2 -2
  347. package/dist/tools/register-sdd-tools.js +1 -0
  348. package/dist/tools/safe-handler.js +1 -0
  349. package/dist/tools/schemas/spec-id.d.ts +1 -6
  350. package/dist/tools/schemas/spec-id.js +1 -16
  351. package/dist/tools/tool-entry.d.ts +2 -2
  352. package/dist/tools/tool-entry.js +1 -1
  353. package/dist/tools/tool-registry/core-tools.d.ts +2 -2
  354. package/dist/tools/tool-registry/deprecated-stubs.d.ts +3 -3
  355. package/dist/tools/tool-registry/deprecated-stubs.js +1 -1
  356. package/dist/tools/triage-request.d.ts +2 -2
  357. package/dist/tools/update-status/approval-gates.d.ts +2 -2
  358. package/dist/tools/update-status/approval-gates.js +1 -0
  359. package/dist/tools/update-status/dod-gates.d.ts +1 -1
  360. package/dist/tools/update-status/done-receipt-verifier.d.ts +1 -1
  361. package/dist/tools/update-status/evidence-gate.js +5 -5
  362. package/dist/tools/update-status/file-sync.js +11 -39
  363. package/dist/tools/update-status/index.js +1 -1
  364. package/dist/tools/update-status/side-effects.js +5 -0
  365. package/dist/tools/update-status/transition-guard.d.ts +1 -1
  366. package/dist/tools/update-status/transition-guard.js +40 -8
  367. package/dist/tools/update-status-actions.js +28 -40
  368. package/dist/tools/validate-graph-coverage.js +14 -2
  369. package/dist/tools/validate.js +2 -0
  370. package/dist/transports/middleware/types.d.ts +3 -3
  371. package/dist/types/atomic-upgrade.d.ts +1 -1
  372. package/dist/types/cascade-hooks.d.ts +3 -0
  373. package/dist/types/cross-repo-search.d.ts +2 -0
  374. package/dist/types/dashboard.d.ts +4 -1
  375. package/dist/types/durable-job.d.ts +20 -0
  376. package/dist/types/durable-job.js +9 -1
  377. package/dist/types/index.d.ts +2 -0
  378. package/dist/types/index.js +2 -0
  379. package/dist/types/installation.d.ts +16 -0
  380. package/dist/types/installation.js +2 -0
  381. package/dist/types/project-knowledge-graph.d.ts +11 -0
  382. package/dist/types/session-checkpoint.d.ts +16 -0
  383. package/dist/types/spec-dependency-graph.d.ts +21 -0
  384. package/dist/types/spec-dependency-graph.js +2 -0
  385. package/dist/types/validation-evidence.d.ts +45 -0
  386. package/package.json +2 -2
  387. package/planu-plugin.json +1 -1
  388. package/dist/types/storage-bundle.d.ts +0 -13
  389. package/dist/types/storage-bundle.js +0 -2
@@ -15,6 +15,6 @@ export declare const TriageRequestInputSchema: z.ZodObject<{
15
15
  projectId: z.ZodOptional<z.ZodString>;
16
16
  specId: z.ZodOptional<z.ZodString>;
17
17
  }, z.core.$strip>;
18
- export type TriageRequestInput = z.infer<typeof TriageRequestInputSchema>;
19
- export declare function handleTriageRequest(input: TriageRequestInput): Promise<ToolResult>;
18
+ export type TriageRequestParsedInput = z.infer<typeof TriageRequestInputSchema>;
19
+ export declare function handleTriageRequest(input: TriageRequestParsedInput): Promise<ToolResult>;
20
20
  //# sourceMappingURL=triage-request.d.ts.map
@@ -1,13 +1,13 @@
1
1
  import type { FormatGateOutput } from '../../types/spec/inputs.js';
2
2
  import type { Spec } from '../../types/spec/core.js';
3
- export interface ComplianceGateResult {
3
+ export interface ApprovalComplianceGateResult {
4
4
  skipped: boolean;
5
5
  score: number | null;
6
6
  issues: string[];
7
7
  blocked: boolean;
8
8
  }
9
9
  /** Run the optional compliance check for a transition into review. */
10
- export declare function checkComplianceGate(specId: string, projectId: string, projectPath: string | undefined): Promise<ComplianceGateResult>;
10
+ export declare function checkComplianceGate(specId: string, projectId: string, projectPath: string | undefined): Promise<ApprovalComplianceGateResult>;
11
11
  /** Validate canonical spec format before approval, preserving audited bypass warnings. */
12
12
  export declare function checkApprovedFormatGate(spec: Spec, newStatus: string, forceApprove?: boolean | undefined): Promise<FormatGateOutput>;
13
13
  //# sourceMappingURL=approval-gates.d.ts.map
@@ -1,3 +1,4 @@
1
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
1
2
  import { validateSpecFormat } from '../../core/spec-validator.js';
2
3
  import { getComplianceGateConfig } from '../../storage/compliance-gate-config-store.js';
3
4
  import { formatKeyValue } from '../output-formatter.js';
@@ -118,7 +118,7 @@ export declare function checkImplementationReviewGate(specId: string, projectId:
118
118
  */
119
119
  export declare function checkDoneGates(spec: Spec, specId: string, projectId: string, projectPath: string | undefined, _force: boolean | undefined, _forceReason?: string, verifyReceipt?: DoneReceiptVerifier, implementationReviewDigest?: string): Promise<DoneGateResult>;
120
120
  export { checkQaGate } from './qa-gate.js';
121
- export { checkApprovedFormatGate, checkComplianceGate, type ComplianceGateResult, } from './approval-gates.js';
121
+ export { checkApprovedFormatGate, checkComplianceGate, type ApprovalComplianceGateResult, } from './approval-gates.js';
122
122
  /**
123
123
  * Run the validate gate wrapped in withEscalation for bounded retries.
124
124
  *
@@ -1,4 +1,4 @@
1
- import { type DurableJobRecord } from '../../storage/runtime-db.js';
1
+ import type { DurableJobRecord } from '../../types/durable-job.js';
2
2
  import { type ValidationFreshnessLease } from '../../engine/validation/validation-freshness.js';
3
3
  export { doneReceiptBindingsDifferOnlyInEvidence } from '../../engine/validation/durable-validation.js';
4
4
  export type DoneReceiptVerifier = (identity: {
@@ -51,7 +51,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
53
  import { readFile } from 'node:fs/promises';
54
- import { isAbsolute, join } from 'node:path';
54
+ import { resolvePortableSpecPath } from '../../storage/project-identity.js';
55
55
  import { extractCriteria } from '../../engine/validator/extractors.js';
56
56
  import { readEvidenceArtifacts } from '../../engine/evidence-gates/artifact-reader.js';
57
57
  import { checkLifecycleEvidenceGate } from '../../engine/evidence-gates/lifecycle-gate.js';
@@ -290,9 +290,7 @@ async function currentBindingsAreFresh(identity, currentBindings) {
290
290
  return false;
291
291
  }
292
292
  try {
293
- const specPath = isAbsolute(identity.specPath)
294
- ? identity.specPath
295
- : join(identity.projectPath, identity.specPath);
293
+ const specPath = await resolvePortableSpecPath(identity.specId, identity.specPath, identity.projectPath);
296
294
  const observed = await computeDurableValidationBindings({
297
295
  canonicalProjectId: identity.projectId,
298
296
  specId: identity.specId,
@@ -311,8 +309,10 @@ async function currentBindingsAreFresh(identity, currentBindings) {
311
309
  }
312
310
  }
313
311
  async function extractLifecycleGateCriteriaAndBody(spec, projectPath) {
314
- const specPath = isAbsolute(spec.specPath) || !projectPath ? spec.specPath : join(projectPath, spec.specPath);
315
312
  try {
313
+ const specPath = projectPath
314
+ ? await resolvePortableSpecPath(spec.id, spec.specPath, projectPath)
315
+ : spec.specPath;
316
316
  const raw = await readFile(specPath, 'utf-8');
317
317
  const criteria = extractAcceptanceCriteriaTexts(raw);
318
318
  if (criteria.length > 0) {
@@ -3,12 +3,12 @@ import { metricsStore } from '../../storage/index.js';
3
3
  import { addLesson, getLessons } from '../../storage/lessons-store.js';
4
4
  import { dispatchFeedbackEvent } from '../learn.js';
5
5
  import { autoReconcileOnDone } from '../update-status-reconcile.js';
6
- import { lstat, readFile, realpath } from 'node:fs/promises';
6
+ import { readFile } from 'node:fs/promises';
7
7
  import { parseFrontmatter } from '../../engine/frontmatter-parser.js';
8
8
  import { computeFrontmatterSha } from '../../engine/frontmatter-sha/index.js';
9
9
  import { appendTransitionEvent } from '../../storage/transition-log.js';
10
10
  import { atomicWriteFile } from '../../engine/safety/atomic-write-file.js';
11
- import { isAbsolute, normalize, relative, resolve, sep } from 'node:path';
11
+ import { resolvePortableSpecPath, PortablePathError } from '../../storage/project-identity.js';
12
12
  import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
13
13
  export async function recordDoneMetrics(projectId, specId, spec, actuals, projectPath) {
14
14
  if (actuals.devHours + actuals.reviewHours === 0) {
@@ -97,46 +97,18 @@ async function resolveSpecPathForTransition(spec, projectPath) {
97
97
  if (!projectPath) {
98
98
  return spec.specPath;
99
99
  }
100
- const normalizedPath = normalize(spec.specPath);
101
- const segments = normalizedPath.split(sep).filter(Boolean);
102
- const planuIndex = segments.lastIndexOf('planu');
103
- const specDirectory = segments[planuIndex + 2];
104
- const isPortableContract = planuIndex >= 0 &&
105
- segments[planuIndex + 1] === 'specs' &&
106
- segments[planuIndex + 3] === 'spec.md' &&
107
- planuIndex + 4 === segments.length &&
108
- specDirectory !== undefined &&
109
- (specDirectory === spec.id || specDirectory.startsWith(`${spec.id}-`));
110
- if (!isPortableContract) {
111
- throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a portable spec contract');
112
- }
113
- const selectedRoot = resolve(projectPath);
114
- const candidate = resolve(selectedRoot, 'planu', 'specs', specDirectory, 'spec.md');
115
- const relativeCandidate = relative(selectedRoot, candidate);
116
- if (relativeCandidate.startsWith(`..${sep}`) ||
117
- relativeCandidate === '..' ||
118
- isAbsolute(relativeCandidate)) {
119
- throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath escapes the selected root');
100
+ try {
101
+ return await resolvePortableSpecPath(spec.id, spec.specPath, projectPath);
120
102
  }
121
- const rootRealpath = await realpath(selectedRoot);
122
- const [candidateRealpath, candidateStat] = await Promise.all([
123
- realpath(candidate),
124
- lstat(candidate),
125
- ]).catch((err) => {
126
- if (err instanceof Error && err.code === 'ENOENT') {
127
- throw specArtifactAbsentError();
103
+ catch (error) {
104
+ if (error instanceof PortablePathError) {
105
+ if (error.code === 'NOT_FOUND') {
106
+ throw specArtifactAbsentError();
107
+ }
108
+ throw new Error(`SPEC_PATH_RELOCALIZATION_FAILED: ${error.message}`, { cause: error });
128
109
  }
129
- throw err;
130
- });
131
- const realRelative = relative(rootRealpath, candidateRealpath);
132
- if (candidateStat.isSymbolicLink() ||
133
- !candidateStat.isFile() ||
134
- realRelative.startsWith(`..${sep}`) ||
135
- realRelative === '..' ||
136
- isAbsolute(realRelative)) {
137
- throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a contained regular file');
110
+ throw error;
138
111
  }
139
- return candidateRealpath;
140
112
  }
141
113
  function bodyWithoutFrontmatter(content) {
142
114
  return parseFrontmatter(content).body;
@@ -932,7 +932,7 @@ export async function handleUpdateStatus(params, server) {
932
932
  return ambiguityError;
933
933
  }
934
934
  // SPEC-769: Readiness gate — block 'approved' if spec has 0 criteria or score < 70
935
- const readinessGate = await checkReadinessGate(spec, approvalGateStatus, params.forceApprove);
935
+ const readinessGate = await checkReadinessGate(spec, approvalGateStatus, params.forceApprove, transitionProjectPath);
936
936
  if (readinessGate.blockResult) {
937
937
  return readinessGate.blockResult;
938
938
  }
@@ -1,9 +1,14 @@
1
1
  import { specStore } from '../../storage/index.js';
2
2
  import { runCascade } from '../../engine/cascade-hooks/runner.js';
3
+ import { setDispatchHookEventHandler } from '../../engine/cascade-hooks/hooks/dispatch-hook-event.hook.js';
3
4
  import { appendAutopilotLogEntry } from '../../storage/autopilot-log-store.js';
4
5
  import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
5
6
  import { getRuntimePolicy } from '../../engine/runtime-policy.js';
6
7
  import { createExecutionScope } from '../../engine/execution/context.js';
8
+ import { dispatchHookEvent } from '../manage-hooks.js';
9
+ // Wire the tools-layer hook dispatcher into the engine's cascade hook
10
+ // (see engine/cascade-hooks/hooks/dispatch-hook-event.hook.ts — engine must not import tools/ directly).
11
+ setDispatchHookEventHandler(dispatchHookEvent);
7
12
  const queuedTransitions = new Map();
8
13
  const CASCADE_ISOLATED_SCOPE_MS = 30_000;
9
14
  const pendingPostCommitWork = new Set();
@@ -73,7 +73,7 @@ export declare function checkSpecArtifactCommittedGate(spec: Spec, newStatus: Sp
73
73
  * - non-English prose → hard block
74
74
  * - score >= 70 → proceed, no warnings
75
75
  */
76
- export declare function checkReadinessGate(spec: Spec, newStatus: SpecStatus, forceApprove: boolean | undefined): Promise<ReadinessGateOutput>;
76
+ export declare function checkReadinessGate(spec: Spec, newStatus: SpecStatus, forceApprove: boolean | undefined, projectPath?: string): Promise<ReadinessGateOutput>;
77
77
  /**
78
78
  * SPEC-964: Challenge gate — block 'review' if challenge_spec was never run
79
79
  * or does not contain enough explicit resolution evidence.
@@ -1,6 +1,7 @@
1
1
  // tools/update-status/transition-guard.ts — Valid state transitions and DoR gate
2
2
  import { readFile } from 'node:fs/promises';
3
3
  import { isAbsolute, join } from 'node:path';
4
+ import { toPortableSpecPath, resolveVerifiedSpecPath, PortablePathError, } from '../../storage/project-identity.js';
4
5
  import { ti } from '../../i18n/index.js';
5
6
  import { validateDoR } from '../../engine/dor-dod.js';
6
7
  import { dispatchFeedbackEvent } from '../learn.js';
@@ -237,9 +238,30 @@ export async function checkSpecArtifactCommittedGate(spec, newStatus, projectPat
237
238
  if (newStatus !== 'implementing' || !projectPath || !spec.specPath) {
238
239
  return null;
239
240
  }
240
- const absoluteSpecPath = isAbsolute(spec.specPath)
241
- ? spec.specPath
242
- : join(projectPath, spec.specPath);
241
+ let absoluteSpecPath;
242
+ try {
243
+ absoluteSpecPath = join(projectPath, toPortableSpecPath(spec.id, spec.specPath));
244
+ }
245
+ catch (error) {
246
+ if (!(error instanceof PortablePathError)) {
247
+ throw error;
248
+ }
249
+ return {
250
+ content: [
251
+ {
252
+ type: 'text',
253
+ text: formatKeyValue({
254
+ error: 'SPEC_PATH_UNRESOLVABLE',
255
+ message: `spec.md for ${spec.id} could not be resolved under the canonical project root (${error.code}).`,
256
+ specId: spec.id,
257
+ fixHint: 'Run reconcile_spec to re-link this spec to its file, then retry update_status.',
258
+ }),
259
+ },
260
+ ],
261
+ isError: true,
262
+ structuredContent: { error: 'SPEC_PATH_UNRESOLVABLE', code: error.code, specId: spec.id },
263
+ };
264
+ }
243
265
  try {
244
266
  const { git } = await import('../git/git-helpers.js');
245
267
  const { stdout } = await git(projectPath, ['status', '--porcelain', '--', absoluteSpecPath]);
@@ -286,13 +308,18 @@ export async function checkSpecArtifactCommittedGate(spec, newStatus, projectPat
286
308
  * - non-English prose → hard block
287
309
  * - score >= 70 → proceed, no warnings
288
310
  */
289
- export async function checkReadinessGate(spec, newStatus, forceApprove) {
311
+ export async function checkReadinessGate(spec, newStatus, forceApprove, projectPath) {
290
312
  if ((newStatus !== 'review' && newStatus !== 'approved') || !spec.specPath) {
291
313
  return { blockResult: null, qualityWarnings: [] };
292
314
  }
293
315
  let body;
316
+ let resolvedPath;
294
317
  try {
295
- body = await readFile(spec.specPath, 'utf-8');
318
+ resolvedPath =
319
+ !isAbsolute(spec.specPath) && projectPath
320
+ ? await resolveVerifiedSpecPath(spec.id, spec.specPath, projectPath)
321
+ : spec.specPath;
322
+ body = await readFile(resolvedPath, 'utf-8');
296
323
  }
297
324
  catch (error) {
298
325
  /* reliability-optional: READINESS_SPEC_UNREADABLE — transition fails closed below */
@@ -301,10 +328,12 @@ export async function checkReadinessGate(spec, newStatus, forceApprove) {
301
328
  // situation — surface an actionable message instead of the raw fs error
302
329
  // ("ENOENT: no such file or directory, open '<path>'") that update_status
303
330
  // was previously appending "Transition blocked..." to verbatim.
304
- const isMissingFile = typeof error === 'object' &&
331
+ const isMissingFile = (typeof error === 'object' &&
305
332
  error !== null &&
306
333
  'code' in error &&
307
- error.code === 'ENOENT';
334
+ error.code === 'ENOENT') ||
335
+ (error instanceof PortablePathError &&
336
+ (error.code === 'NOT_FOUND' || error.code === 'ROOT_NOT_FOUND'));
308
337
  return readinessUnavailable('READINESS_SPEC_UNREADABLE', isMissingFile
309
338
  ? `spec.md is missing at ${spec.specPath}. Recreate the spec via create_spec or restore spec.md from git/backup before retrying this transition.`
310
339
  : error instanceof Error
@@ -397,9 +426,12 @@ export async function checkReadinessGate(spec, newStatus, forceApprove) {
397
426
  qualityWarnings: structuralInterpolationWarnings,
398
427
  };
399
428
  }
429
+ const specWithResolvedPath = resolvedPath === spec.specPath
430
+ ? spec
431
+ : { ...spec, specPath: resolvedPath, technicalPath: resolvedPath };
400
432
  let readiness;
401
433
  try {
402
- readiness = await checkSpecReadiness(spec, 'strict');
434
+ readiness = await checkSpecReadiness(specWithResolvedPath, 'strict');
403
435
  }
404
436
  catch (error) {
405
437
  /* reliability-optional: READINESS_EVALUATION_FAILED — transition fails closed below */
@@ -78,12 +78,18 @@ export async function runImplementingSideEffects(projectId, specId, transitionPr
78
78
  try {
79
79
  const spec = foundSpec ?? (await specStore.getSpec(projectId, specId));
80
80
  const results = await Promise.allSettled([
81
- // SPEC-633: Write session state when spec moves to implementing
81
+ // SPEC-633: Write session state when spec moves to implementing, then refresh
82
+ // the paired session artifacts from the resulting store state.
82
83
  (async () => {
83
- const { writeSpecSessionState } = await import('../engine/session-state/writer.js');
84
- await writeSpecSessionState(projectPath, specId, spec?.title ?? specId, 'moved to implementing').catch(() => {
84
+ try {
85
+ const { writeSpecSessionState } = await import('../engine/session-state/writer.js');
86
+ await writeSpecSessionState(projectPath, specId, spec?.title ?? specId, 'moved to implementing');
87
+ const { refreshSessionArtifacts } = await import('../engine/session-state/session-artifact-refresher.js');
88
+ await refreshSessionArtifacts(projectPath, projectId);
89
+ }
90
+ catch {
85
91
  /* best-effort */
86
- });
92
+ }
87
93
  })(),
88
94
  // SPEC-635: Regenerate context.md
89
95
  (async () => {
@@ -92,19 +98,6 @@ export async function runImplementingSideEffects(projectId, specId, transitionPr
92
98
  /* best-effort */
93
99
  });
94
100
  })(),
95
- // SPEC-656: Recalculate epicProgress when spec moves to implementing
96
- (async () => {
97
- try {
98
- const { updateEpicProgressInSession } = await import('../engine/session-state/writer.js');
99
- const allSpecs = await specStore.listSpecs(projectId);
100
- await updateEpicProgressInSession(projectPath, allSpecs).catch(() => {
101
- /* best-effort */
102
- });
103
- }
104
- catch {
105
- /* best-effort */
106
- }
107
- })(),
108
101
  // recommend_model — suggest haiku/sonnet/opus based on spec complexity
109
102
  (async () => {
110
103
  try {
@@ -166,13 +159,6 @@ export async function runDoneActions(projectId, specId, gitBranch, options = {})
166
159
  try {
167
160
  const { resolveProjectPath, git: gitCmd } = await import('./git/git-helpers.js');
168
161
  const projectPath = suppliedProjectPath(options.projectPath) ?? (await resolveProjectPath(projectId));
169
- if (process.env.PLANU_ENABLE_AUTOCOMMIT === 'true') {
170
- await gitCmd(projectPath, ['add', 'planu/']);
171
- const { planuAutoCommit } = await import('../engine/git/planu-autocommit.js');
172
- void planuAutoCommit({ projectPath, specId, reason: 'mark-done' }).catch((err) => {
173
- console.error('[update-status] planuAutoCommit failed:', err instanceof Error ? err.message : String(err));
174
- });
175
- }
176
162
  const { stdout } = await gitCmd(projectPath, ['status', '--porcelain']);
177
163
  const nonPlanuLines = stdout
178
164
  .trim()
@@ -243,15 +229,6 @@ export async function runDoneSideEffects(projectId, specId, gitBranch, transitio
243
229
  const { cleanupSpecOnDone } = await import('./git/cleanup-ops.js');
244
230
  return withAudit(projectPath, 'update_status(done)', 'cleanupSpecOnDone', () => cleanupSpecOnDone(projectPath, specId, gitBranch));
245
231
  })(),
246
- (async () => {
247
- const { removeSpecFromSession } = await import('../engine/session-state/writer.js');
248
- await removeSpecFromSession(projectPath, specId);
249
- })(),
250
- (async () => {
251
- const { updateEpicProgressInSession } = await import('../engine/session-state/writer.js');
252
- const allSpecs = await specStore.listSpecs(projectId);
253
- await updateEpicProgressInSession(projectPath, allSpecs);
254
- })(),
255
232
  (async () => {
256
233
  const { generateContextMd } = await import('../engine/context-md-generator.js');
257
234
  await generateContextMd(projectPath, projectId);
@@ -266,26 +243,37 @@ export async function runDoneSideEffects(projectId, specId, gitBranch, transitio
266
243
  return runHousekeepingSweep({ projectPath });
267
244
  })(),
268
245
  (async () => {
269
- if (hasPending(specId, 'generateSessionContext')) {
246
+ if (hasPending(specId, 'refreshSessionArtifacts')) {
270
247
  return;
271
248
  }
272
- markPending(specId, 'generateSessionContext');
249
+ markPending(specId, 'refreshSessionArtifacts');
273
250
  try {
274
- const { generateSessionContext } = await import('../engine/session-context-generator.js');
275
- await generateSessionContext(projectPath, projectId);
251
+ const { refreshSessionArtifacts } = await import('../engine/session-state/session-artifact-refresher.js');
252
+ await refreshSessionArtifacts(projectPath, projectId);
276
253
  }
277
254
  finally {
278
- clearPending(specId, 'generateSessionContext');
255
+ clearPending(specId, 'refreshSessionArtifacts');
279
256
  }
280
257
  })(),
281
258
  ]);
259
+ if (process.env.PLANU_ENABLE_AUTOCOMMIT === 'true') {
260
+ try {
261
+ const { git: gitCmd } = await import('./git/git-helpers.js');
262
+ await gitCmd(projectPath, ['add', 'planu/']);
263
+ const { planuAutoCommit } = await import('../engine/git/planu-autocommit.js');
264
+ await planuAutoCommit({ projectPath, specId, reason: 'mark-done' });
265
+ }
266
+ catch (err) {
267
+ console.error('[update-status] planuAutoCommit failed:', err instanceof Error ? err.message : String(err));
268
+ }
269
+ }
282
270
  const failures = results.filter((result) => result.status === 'rejected');
283
271
  if (failures.length > 0) {
284
272
  throw new AggregateError(normalizeRejectedReasons(failures), `${String(failures.length)} done side effect(s) failed`);
285
273
  }
286
274
  const cleanup = results[0].status === 'fulfilled' ? results[0].value : null;
287
- const planuCleanup = results[4].status === 'fulfilled' ? results[4].value : null;
288
- const housekeeping = results[5].status === 'fulfilled' ? results[5].value : null;
275
+ const planuCleanup = results[2].status === 'fulfilled' ? results[2].value : null;
276
+ const housekeeping = results[3].status === 'fulfilled' ? results[3].value : null;
289
277
  return {
290
278
  cleanupProposals: cleanup?.proposals ?? [],
291
279
  housekeepingProposal: housekeeping ?? {
@@ -11,6 +11,9 @@ function graphCoverageGaps(slice) {
11
11
  .map((criterion) => criterion.label)
12
12
  .slice(0, 10);
13
13
  }
14
+ function graphCoverageWarnings(slice) {
15
+ return slice.oversizedSources.map((record) => `oversized source: ${record.path} (${record.kind}, ${record.action})`);
16
+ }
14
17
  export async function buildGraphCoverageReport(args) {
15
18
  let graphSlice;
16
19
  try {
@@ -21,7 +24,13 @@ export async function buildGraphCoverageReport(args) {
21
24
  graphSlice = null;
22
25
  }
23
26
  if (graphSlice === null) {
24
- return { availability: 'unavailable', gaps: [], compactNodes: 0, compactEdges: 0 };
27
+ return {
28
+ availability: 'unavailable',
29
+ gaps: [],
30
+ compactNodes: 0,
31
+ compactEdges: 0,
32
+ warnings: [],
33
+ };
25
34
  }
26
35
  return {
27
36
  availability: 'available',
@@ -29,14 +38,17 @@ export async function buildGraphCoverageReport(args) {
29
38
  gaps: graphCoverageGaps(graphSlice),
30
39
  compactNodes: graphSlice.nodes.length,
31
40
  compactEdges: graphSlice.edges.length,
41
+ warnings: graphCoverageWarnings(graphSlice),
32
42
  };
33
43
  }
34
44
  export function formatGraphCoverageText(report) {
35
45
  if (report.availability === 'unavailable') {
36
46
  return '\nGRAPH unavailable (project graph unreadable)';
37
47
  }
38
- return report.gaps.length > 0
48
+ const gapLine = report.gaps.length > 0
39
49
  ? `\nGRAPH ${String(report.gaps.length)} graph-backed coverage gap(s)`
40
50
  : '';
51
+ const warningLines = report.warnings.map((warning) => `\nGRAPH ${warning}`).join('');
52
+ return gapLine + warningLines;
41
53
  }
42
54
  //# sourceMappingURL=validate-graph-coverage.js.map
@@ -867,6 +867,8 @@ function buildValidateStructuredContent(args) {
867
867
  availability: args.graphCoverage.availability,
868
868
  gapsCount: args.graphCoverage.gaps.length,
869
869
  gapsTop5: args.graphCoverage.gaps.slice(0, 5),
870
+ warningsCount: args.graphCoverage.warnings.length,
871
+ warningsTop5: args.graphCoverage.warnings.slice(0, 5),
870
872
  freshness: args.graphCoverage.freshness,
871
873
  },
872
874
  suggestionsTop5: args.suggestions.slice(0, 5),
@@ -11,9 +11,9 @@ export interface ToolContext {
11
11
  /**
12
12
  * A tool handler function signature.
13
13
  */
14
- export type ToolHandler = (input: Record<string, unknown>, ctx: ToolContext) => Promise<ToolResult>;
14
+ export type MiddlewareToolHandler = (input: Record<string, unknown>, ctx: ToolContext) => Promise<ToolResult>;
15
15
  /**
16
- * A middleware is a higher-order function that wraps a ToolHandler.
16
+ * A middleware is a higher-order function that wraps a MiddlewareToolHandler.
17
17
  */
18
- export type Middleware = (handler: ToolHandler) => ToolHandler;
18
+ export type Middleware = (handler: MiddlewareToolHandler) => MiddlewareToolHandler;
19
19
  //# sourceMappingURL=types.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import type { SpawnSyncReturns } from 'node:child_process';
2
- import type { InstallationManifest, InstallationRecord } from '../cli/commands/install.js';
2
+ import type { InstallationManifest, InstallationRecord } from './installation.js';
3
3
  export type UpgradePhase = 'after-runtime-verification' | 'before-adapter-switch' | 'after-adapter-switch' | 'before-manifest-switch' | 'after-manifest-switch' | 'after-trust-switch';
4
4
  export type UpgradeJournalState = 'prepared' | 'switching' | 'trust-switched' | 'committed';
5
5
  export interface UpgradeJournal {
@@ -1,5 +1,8 @@
1
1
  import type { Spec } from './spec/core.js';
2
2
  import type { SpecStatus } from './common/primitives.js';
3
+ import type { HookEventPayload } from './hooks.js';
4
+ /** Port through which the dispatch-hook-event hook reaches the tools-layer hook dispatcher. */
5
+ export type DispatchHookEventFn = (projectId: string, payload: HookEventPayload) => Promise<void>;
3
6
  export interface CascadeContext {
4
7
  specId: string;
5
8
  spec: Spec;
@@ -13,6 +13,8 @@ export interface RegisteredProject {
13
13
  specCount: number;
14
14
  /** ISO timestamp of the last spec scan, if any */
15
15
  lastScanAt?: string;
16
+ /** Logical project identity from planu/project.json, when the checkout has one */
17
+ logicalProjectId?: string;
16
18
  }
17
19
  /**
18
20
  * Global registry persisted at data/global/registered-projects.json.
@@ -1,4 +1,5 @@
1
- import type { Difficulty, RiskLevel, SpecStatus } from './common/index.js';
1
+ import type { Difficulty, RiskLevel, SpecStatus, ToolResult } from './common/index.js';
2
+ import type { UpdateStatusInput } from './spec/inputs.js';
2
3
  /** State of the dashboard HTTP server (singleton in memory) */
3
4
  export interface DashboardServerState {
4
5
  port: number;
@@ -69,6 +70,8 @@ export interface SpecStatusUpdateResult {
69
70
  newStatus: string;
70
71
  error?: string;
71
72
  }
73
+ /** Port through which the dashboard status route reaches the tools-layer status gate. */
74
+ export type UpdateStatusHandler = (input: UpdateStatusInput) => Promise<ToolResult>;
72
75
  /** Project health score with weighted components */
73
76
  export interface ProjectHealthScore {
74
77
  overall: number;
@@ -35,4 +35,24 @@ export interface ValidateDurableJobPayload {
35
35
  readonly freshnessLease?: ValidationFreshnessLease;
36
36
  readonly specPath: string;
37
37
  }
38
+ export declare const DURABLE_JOB_STATES: readonly ['accepted', 'running', 'checkpointed', 'cancelled', 'failed', 'dead-letter', 'completed'];
39
+ export type DurableJobState = (typeof DURABLE_JOB_STATES)[number];
40
+ export interface DurableJobRecord {
41
+ readonly id: string;
42
+ readonly projectId: string;
43
+ readonly workspaceId: string;
44
+ readonly state: DurableJobState;
45
+ readonly payload: unknown;
46
+ readonly checkpoint?: unknown;
47
+ readonly result?: unknown;
48
+ readonly error?: string;
49
+ readonly attempts: number;
50
+ readonly maxAttempts: number;
51
+ readonly cancelRequested: boolean;
52
+ readonly leaseOwner?: string;
53
+ readonly leaseExpiresAt?: string;
54
+ readonly fencingToken: number;
55
+ readonly createdAt: string;
56
+ readonly updatedAt: string;
57
+ }
38
58
  //# sourceMappingURL=durable-job.d.ts.map
@@ -1,2 +1,10 @@
1
- export {};
1
+ export const DURABLE_JOB_STATES = [
2
+ 'accepted',
3
+ 'running',
4
+ 'checkpointed',
5
+ 'cancelled',
6
+ 'failed',
7
+ 'dead-letter',
8
+ 'completed',
9
+ ];
2
10
  //# sourceMappingURL=durable-job.js.map
@@ -1,4 +1,5 @@
1
1
  export * from './agent-roles.js';
2
+ export * from './installation.js';
2
3
  export * from './cost-ledger.js';
3
4
  export * from './autopilot-summary.js';
4
5
  export * from './common/index.js';
@@ -264,6 +265,7 @@ export * from './agent-memory.js';
264
265
  export * from './agent-spawner.js';
265
266
  export * from './qa-gate.js';
266
267
  export * from './validation-evidence.js';
268
+ export * from './spec-dependency-graph.js';
267
269
  export * from './project-drift.js';
268
270
  export * from './technical-enrichment.js';
269
271
  export * from './agent-team.js';
@@ -1,5 +1,6 @@
1
1
  // Planu — SDD MCP Server Types (barrel re-export)
2
2
  export * from './agent-roles.js';
3
+ export * from './installation.js';
3
4
  export * from './cost-ledger.js';
4
5
  export * from './autopilot-summary.js';
5
6
  export * from './common/index.js';
@@ -261,6 +262,7 @@ export * from './agent-memory.js';
261
262
  export * from './agent-spawner.js';
262
263
  export * from './qa-gate.js';
263
264
  export * from './validation-evidence.js';
265
+ export * from './spec-dependency-graph.js';
264
266
  export * from './project-drift.js';
265
267
  export * from './technical-enrichment.js';
266
268
  export * from './agent-team.js';
@@ -0,0 +1,16 @@
1
+ export interface InstallationRecord {
2
+ host: string;
3
+ configPath: string;
4
+ format: 'standard' | 'zed';
5
+ scope: 'user' | 'project';
6
+ package: string;
7
+ version: string;
8
+ offline: boolean;
9
+ installedAt: string;
10
+ }
11
+ export interface InstallationManifest {
12
+ schemaVersion: 1;
13
+ updatedAt: string;
14
+ installations: InstallationRecord[];
15
+ }
16
+ //# sourceMappingURL=installation.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=installation.js.map