@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
@@ -6,6 +6,7 @@ import { open, readdir, readFile, stat } from 'node:fs/promises';
6
6
  import { dirname, extname, join, relative, resolve } from 'node:path';
7
7
  import { setTimeout as delay } from 'node:timers/promises';
8
8
  import { fileURLToPath } from 'node:url';
9
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
9
10
  import { projectDataDir, readJson, writeJson } from '../../storage/base-store.js';
10
11
  import { LockBusyError, withSpecLock } from '../safety/cross-process-lock.js';
11
12
  const POLICY_PATH = join(dirname(fileURLToPath(import.meta.url)), '../../config/project-knowledge-graph.json');
@@ -23,6 +24,14 @@ const PROJECT_CODE_IGNORED_DIRS = new Set([
23
24
  ]);
24
25
  const CONTENT_HASH_PATTERN = /^[a-f0-9]{64}$/;
25
26
  const PROJECT_GRAPH_LOCK_WAIT_MS = 30_000;
27
+ const OPERATIONAL_SOURCE_KINDS = new Set([
28
+ 'transition-log',
29
+ 'release-events',
30
+ 'decisions',
31
+ 'handoff',
32
+ 'validation',
33
+ ]);
34
+ const JSONL_OPERATIONAL_SOURCE_KINDS = new Set(['transition-log', 'release-events']);
26
35
  const buildTails = new Map();
27
36
  const activeBuilds = new Map();
28
37
  export async function loadProjectGraphPolicy() {
@@ -354,14 +363,150 @@ async function readBoundedFile(descriptor, path, maxFileBytes) {
354
363
  mtimeMs: info.mtimeMs,
355
364
  };
356
365
  }
366
+ async function readBoundedFileOrOversized(descriptor, path, maxFileBytes) {
367
+ try {
368
+ return await readBoundedFile(descriptor, path, maxFileBytes);
369
+ }
370
+ catch (error) {
371
+ if (error instanceof Error && error.message.startsWith('PROJECT_GRAPH_FILE_TOO_LARGE')) {
372
+ return null;
373
+ }
374
+ throw error;
375
+ }
376
+ }
377
+ async function readTailChunk(descriptor, size, maxFileBytes) {
378
+ const start = Math.max(0, size - maxFileBytes);
379
+ const length = size - start;
380
+ const buffer = Buffer.allocUnsafe(length);
381
+ let readTotal = 0;
382
+ while (readTotal < length) {
383
+ const { bytesRead } = await descriptor.read(buffer, readTotal, length - readTotal, start + readTotal);
384
+ if (bytesRead === 0) {
385
+ break;
386
+ }
387
+ readTotal += bytesRead;
388
+ }
389
+ const chunk = buffer.subarray(0, readTotal);
390
+ if (start === 0) {
391
+ return { chunk, atLineBoundary: true };
392
+ }
393
+ const boundaryByte = Buffer.allocUnsafe(1);
394
+ const { bytesRead: boundaryBytesRead } = await descriptor.read(boundaryByte, 0, 1, start - 1);
395
+ return {
396
+ chunk,
397
+ atLineBoundary: boundaryBytesRead === 1 && boundaryByte[0] === 0x0a,
398
+ };
399
+ }
400
+ function dropFirstPartialLine(chunk, atLineBoundary) {
401
+ if (atLineBoundary) {
402
+ return chunk;
403
+ }
404
+ const newlineIndex = chunk.indexOf(0x0a);
405
+ return newlineIndex === -1 ? Buffer.alloc(0) : chunk.subarray(newlineIndex + 1);
406
+ }
407
+ async function readTailChunkStable(descriptor, maxFileBytes) {
408
+ const beforeStat = await descriptor.stat();
409
+ const { chunk, atLineBoundary } = await readTailChunk(descriptor, beforeStat.size, maxFileBytes);
410
+ const afterStat = await descriptor.stat();
411
+ return afterStat.size === beforeStat.size
412
+ ? { chunk, atLineBoundary, mtimeMs: afterStat.mtimeMs }
413
+ : null;
414
+ }
415
+ async function readBoundedTail(descriptor, maxFileBytes) {
416
+ const stable = (await readTailChunkStable(descriptor, maxFileBytes)) ??
417
+ (await readTailChunkStable(descriptor, maxFileBytes));
418
+ if (stable === null) {
419
+ return null;
420
+ }
421
+ const trimmed = dropFirstPartialLine(stable.chunk, stable.atLineBoundary);
422
+ if (trimmed.length === 0) {
423
+ return null;
424
+ }
425
+ return {
426
+ content: trimmed.toString('utf8'),
427
+ size: trimmed.length,
428
+ mtimeMs: stable.mtimeMs,
429
+ };
430
+ }
431
+ async function degradedOperationalSource(args) {
432
+ const base = {
433
+ path: args.path,
434
+ kind: args.kind,
435
+ bytes: args.bytes,
436
+ threshold: args.maxFileBytes,
437
+ };
438
+ if (!JSONL_OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
439
+ return { source: null, oversized: { ...base, action: 'skip' } };
440
+ }
441
+ const descriptor = await open(args.filePath, 'r');
442
+ let tail;
443
+ try {
444
+ tail = await readBoundedTail(descriptor, args.maxFileBytes);
445
+ }
446
+ finally {
447
+ await descriptor.close();
448
+ }
449
+ if (tail === null) {
450
+ return { source: null, oversized: { ...base, action: 'skip' } };
451
+ }
452
+ return {
453
+ source: {
454
+ id: args.id,
455
+ kind: args.kind,
456
+ path: args.path,
457
+ content: tail.content,
458
+ hash: hashText(`${String(args.bytes)}\n${tail.content}`),
459
+ size: tail.size,
460
+ mtimeMs: tail.mtimeMs,
461
+ contentLoaded: true,
462
+ },
463
+ oversized: { ...base, action: 'tail' },
464
+ };
465
+ }
466
+ async function readFreshSource(args) {
467
+ const descriptor = await open(args.filePath, 'r');
468
+ let bounded;
469
+ try {
470
+ bounded = await readBoundedFileOrOversized(descriptor, args.path, args.maxFileBytes);
471
+ if (bounded === null && OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
472
+ bounded = await readBoundedFileOrOversized(descriptor, args.path, args.maxFileBytes);
473
+ }
474
+ }
475
+ finally {
476
+ await descriptor.close();
477
+ }
478
+ if (bounded === null) {
479
+ if (!OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
480
+ throw new Error(`PROJECT_GRAPH_FILE_TOO_LARGE: ${args.path} exceeds maxFileBytes (${String(args.maxFileBytes)})`);
481
+ }
482
+ const currentBytes = (await stat(args.filePath)).size;
483
+ return await degradedOperationalSource({ ...args, bytes: currentBytes });
484
+ }
485
+ return {
486
+ source: {
487
+ id: args.id,
488
+ kind: args.kind,
489
+ path: args.path,
490
+ content: bounded.content,
491
+ hash: hashText(bounded.content),
492
+ size: bounded.size,
493
+ mtimeMs: bounded.mtimeMs,
494
+ contentLoaded: true,
495
+ },
496
+ oversized: null,
497
+ };
498
+ }
357
499
  async function sourceFromFile(args) {
358
500
  try {
359
501
  const info = await stat(args.filePath);
360
502
  if (!info.isFile()) {
361
- return null;
503
+ return { source: null, oversized: null };
362
504
  }
363
505
  if (info.size > args.maxFileBytes) {
364
- throw new Error(`PROJECT_GRAPH_FILE_TOO_LARGE: ${args.path} exceeds maxFileBytes (${String(args.maxFileBytes)})`);
506
+ if (!OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
507
+ throw new Error(`PROJECT_GRAPH_FILE_TOO_LARGE: ${args.path} exceeds maxFileBytes (${String(args.maxFileBytes)})`);
508
+ }
509
+ return await degradedOperationalSource({ ...args, bytes: info.size });
365
510
  }
366
511
  const previous = args.previous;
367
512
  const expectedNativeVersion = nativeVersionForSource(args.kind, args.nativeCoreVersion);
@@ -375,53 +520,40 @@ async function sourceFromFile(args) {
375
520
  args.nativeCoreVersion === undefined ||
376
521
  previous.nativeCoreVersion === expectedNativeVersion)) {
377
522
  return {
378
- id: args.id,
379
- kind: args.kind,
380
- path: args.path,
381
- content: '',
382
- hash: previous.contentHash,
383
- size: info.size,
384
- mtimeMs: info.mtimeMs,
385
- contentLoaded: false,
523
+ source: {
524
+ id: args.id,
525
+ kind: args.kind,
526
+ path: args.path,
527
+ content: '',
528
+ hash: previous.contentHash,
529
+ size: info.size,
530
+ mtimeMs: info.mtimeMs,
531
+ contentLoaded: false,
532
+ },
533
+ oversized: null,
386
534
  };
387
535
  }
388
- const descriptor = await open(args.filePath, 'r');
389
- let bounded;
390
- try {
391
- bounded = await readBoundedFile(descriptor, args.path, args.maxFileBytes);
392
- }
393
- finally {
394
- await descriptor.close();
395
- }
396
- return {
397
- id: args.id,
398
- kind: args.kind,
399
- path: args.path,
400
- content: bounded.content,
401
- hash: hashText(bounded.content),
402
- size: bounded.size,
403
- mtimeMs: bounded.mtimeMs,
404
- contentLoaded: true,
405
- };
536
+ return await readFreshSource(args);
406
537
  }
407
538
  catch (error) {
408
539
  if (error instanceof Error && error.message.startsWith('PROJECT_GRAPH_')) {
409
540
  throw error;
410
541
  }
411
- return null;
542
+ return { source: null, oversized: null };
412
543
  }
413
544
  }
414
545
  export async function hydrateProjectGraphSource(source, maxFileBytes) {
415
546
  if (source.contentLoaded !== false || source.kind === 'project-code') {
416
547
  return source;
417
548
  }
418
- return sourceFromFile({
549
+ const result = await sourceFromFile({
419
550
  id: source.id,
420
551
  kind: source.kind,
421
552
  path: source.path,
422
553
  filePath: source.path,
423
554
  maxFileBytes,
424
555
  });
556
+ return result.source;
425
557
  }
426
558
  async function collectGitSource(projectPath) {
427
559
  try {
@@ -507,18 +639,26 @@ export async function collectProjectGraphSources(args) {
507
639
  return { id: `project-code:${path}`, kind: 'project-code', path, filePath };
508
640
  }),
509
641
  ].sort((a, b) => a.id.localeCompare(b.id));
510
- const sources = await Promise.all(raw.map((source) => sourceFromFile({
642
+ const results = await Promise.all(raw.map((source) => sourceFromFile({
511
643
  ...source,
512
644
  previous: args.previous?.[source.id],
513
645
  nativeCoreVersion: args.nativeCoreVersion,
514
646
  maxFileBytes,
515
647
  })));
516
- const available = sources.filter((source) => source !== null);
648
+ const available = results
649
+ .map((result) => result.source)
650
+ .filter((source) => source !== null);
651
+ const oversizedSources = results
652
+ .map((result) => result.oversized)
653
+ .filter((record) => record !== null);
517
654
  const gitSource = await collectGitSource(projectRoot);
518
655
  if (gitSource !== null) {
519
656
  available.push(gitSource);
520
657
  }
521
- return available.sort((left, right) => left.id.localeCompare(right.id));
658
+ return {
659
+ sources: available.sort((left, right) => left.id.localeCompare(right.id)),
660
+ oversizedSources,
661
+ };
522
662
  }
523
663
  export async function getProjectGraphFreshness(args) {
524
664
  const policy = args.policy ?? (await loadProjectGraphPolicy());
@@ -546,7 +686,7 @@ export async function getProjectGraphFreshness(args) {
546
686
  }
547
687
  const cacheResult = await readProjectGraphCache(args.projectId, policy);
548
688
  const previous = cacheResult.cache?.records ?? {};
549
- const sources = await collectProjectGraphSources({
689
+ const { sources } = await collectProjectGraphSources({
550
690
  projectId: args.projectId,
551
691
  projectPath: args.projectPath,
552
692
  policy,
@@ -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 { safeJsonParse } from '../../../storage/base-store.js';
2
3
  import { hashText } from '../cache.js';
3
4
  import { redactGraphText } from '../redaction.js';
@@ -1,6 +1,9 @@
1
1
  import { join } from 'node:path';
2
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
2
3
  import { projectDataDir } from '../../storage/base-store.js';
4
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
3
5
  import { RuntimeDatabase } from '../../storage/runtime-db.js';
6
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
4
7
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
5
8
  const PROJECTION_WORKSPACE = 'project-graph';
6
9
  const PROJECTION_KEY = 'freshness-v1';
@@ -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 { hashProjectPath } from '../../storage/base-store.js';
2
3
  import { buildProjectKnowledgeGraph } from './builder.js';
3
4
  import { getProjectGraphFreshness, loadProjectGraphPolicy, readProjectGraph } from './cache.js';
@@ -50,27 +51,27 @@ function summarize(nodes) {
50
51
  toolHandlers: count('tool_handler'),
51
52
  };
52
53
  }
54
+ async function ensureFreshProjectGraph(args) {
55
+ const freshness = await getProjectGraphFreshness(args);
56
+ if (!freshness.exists ||
57
+ freshness.reason === 'source_changed' ||
58
+ freshness.reason === 'corrupt') {
59
+ await buildProjectKnowledgeGraph(args);
60
+ return getProjectGraphFreshness(args);
61
+ }
62
+ return freshness;
63
+ }
53
64
  export async function queryProjectGraphSlice(input) {
54
65
  const projectId = input.projectId ?? hashProjectPath(input.projectPath);
55
66
  const policy = await loadProjectGraphPolicy();
56
67
  if (!policy.enabled) {
57
68
  return null;
58
69
  }
59
- let freshness = await getProjectGraphFreshness({
70
+ const freshness = await ensureFreshProjectGraph({
60
71
  projectId,
61
72
  projectPath: input.projectPath,
62
73
  policy,
63
74
  });
64
- if (!freshness.exists ||
65
- freshness.reason === 'source_changed' ||
66
- freshness.reason === 'corrupt') {
67
- await buildProjectKnowledgeGraph({ projectId, projectPath: input.projectPath, policy });
68
- freshness = await getProjectGraphFreshness({
69
- projectId,
70
- projectPath: input.projectPath,
71
- policy,
72
- });
73
- }
74
75
  const graph = await readProjectGraph(projectId, policy);
75
76
  if (graph === null) {
76
77
  return null;
@@ -106,6 +107,8 @@ export async function queryProjectGraphSlice(input) {
106
107
  freshness,
107
108
  nodes,
108
109
  edges,
110
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- pre-SPEC-1674 persisted artifacts predate this field
111
+ oversizedSources: graph.oversizedSources ?? [],
109
112
  summary: summarize(nodes),
110
113
  tokenSavings: {
111
114
  compactNodes: nodes.length,
@@ -1,17 +1,13 @@
1
1
  import { technologyValue } from './technology-registry.js';
2
+ import { fileExists } from '../core/shared/fs.js';
2
3
  // @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
3
4
  // engine/project-health-checker.ts — SPEC-180 + SPEC-192 + SPEC-177: Project health check with convention scanning
4
5
  import { execSync } from 'node:child_process';
5
- import { readFile, access } from 'node:fs/promises';
6
+ import { readFile } from 'node:fs/promises';
6
7
  import { join, relative } from 'node:path';
7
8
  import { parseConventions, scanConventions } from './convention-scanner/index.js';
8
9
  import { fastFindPatterns } from './core-bridge.js';
9
10
  // ── helpers ──────────────────────────────────────────────────────────────────
10
- function fileExists(path) {
11
- return access(path)
12
- .then(() => true)
13
- .catch(() => false);
14
- }
15
11
  function execSafe(cmd, cwd) {
16
12
  try {
17
13
  return execSync(cmd, { cwd, stdio: ['pipe', 'pipe', 'pipe'] }).toString();
@@ -8,6 +8,7 @@
8
8
  // (specBody, technicalBody, signatures, scenarios, file lists) and surfaces non-fatal
9
9
  // parser issues in `warnings` instead of throwing.
10
10
  import { readFile } from 'node:fs/promises';
11
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
11
12
  import { specStore } from '../../../storage/index.js';
12
13
  import { stripFrontmatter } from '../../frontmatter-parser.js';
13
14
  import { extractSignatures } from './markdown-utils.js';
@@ -1,4 +1,5 @@
1
1
  import { GATE_CATALOG } from './gate-catalog.js';
2
+ import { escapeRegex } from '../../core/shared/strings.js';
2
3
  export function evaluateGates(specMarkdown) {
3
4
  const autoGates = GATE_CATALOG.filter((g) => specMarkdown.includes(`[AUTO] ${g.title}`));
4
5
  const passed = autoGates.filter((g) => {
@@ -19,7 +20,4 @@ export function evaluateGates(specMarkdown) {
19
20
  score: autoGates.length === 0 ? 100 : Math.round((passed.length / autoGates.length) * 100),
20
21
  };
21
22
  }
22
- function escapeRegex(str) {
23
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
24
- }
25
23
  //# sourceMappingURL=gate-evaluator.js.map
@@ -1,18 +1,10 @@
1
1
  // Planu — SPEC-051: React 19 + Next.js 16 stack detection
2
- import { readFile, access } from 'node:fs/promises';
2
+ import { readFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
+ import { fileExistsIn } from '../core/shared/fs.js';
4
5
  // ---------------------------------------------------------------------------
5
6
  // Helpers
6
7
  // ---------------------------------------------------------------------------
7
- async function fileExists(basePath, relativePath) {
8
- try {
9
- await access(join(basePath, relativePath));
10
- return true;
11
- }
12
- catch {
13
- return false;
14
- }
15
- }
16
8
  async function readJsonFile(filePath) {
17
9
  try {
18
10
  const content = await readFile(filePath, 'utf-8');
@@ -98,11 +90,11 @@ async function detectNextjsVersion(projectPath) {
98
90
  // Router mode detection
99
91
  // ---------------------------------------------------------------------------
100
92
  async function detectRouterMode(projectPath) {
101
- const hasApp = await fileExists(projectPath, 'app');
102
- const hasPages = await fileExists(projectPath, 'pages');
93
+ const hasApp = await fileExistsIn(projectPath, 'app');
94
+ const hasPages = await fileExistsIn(projectPath, 'pages');
103
95
  // Also check src/ subdirectory (common Next.js project layout)
104
- const hasAppSrc = await fileExists(projectPath, 'src/app');
105
- const hasPagesSrc = await fileExists(projectPath, 'src/pages');
96
+ const hasAppSrc = await fileExistsIn(projectPath, 'src/app');
97
+ const hasPagesSrc = await fileExistsIn(projectPath, 'src/pages');
106
98
  const appRouter = hasApp || hasAppSrc;
107
99
  const pagesRouter = hasPages || hasPagesSrc;
108
100
  if (appRouter && pagesRouter) {
@@ -1,9 +1,7 @@
1
1
  import { readFile } from 'node:fs/promises';
2
2
  import { atomicWriteFile } from '../safety/atomic-write-file.js';
3
3
  import { SECTIONS_WITHOUT_LITERAL_BODY_TEXT, } from '../../types/index.js';
4
- function escapeRegex(str) {
5
- return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
6
- }
4
+ import { escapeRegex } from '../../core/shared/strings.js';
7
5
  function findSectionBounds(content, section) {
8
6
  const headingRe = new RegExp(`^(#{1,6})\\s+${escapeRegex(section)}\\s*$`, 'mi');
9
7
  const match = headingRe.exec(content);
@@ -68,6 +68,7 @@ export { formatReport };
68
68
  * Custom entries override base entries with the same framework ID.
69
69
  */
70
70
  export async function saveCustomEntry(entry) {
71
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
71
72
  const { readJson, writeJson, globalDataDir } = await import('../../storage/base-store.js');
72
73
  const { join } = await import('node:path');
73
74
  const filePath = join(globalDataDir(), 'registry-custom.json');
@@ -5,7 +5,9 @@
5
5
  import { readFile } from 'node:fs/promises';
6
6
  import { join, dirname } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
8
9
  import { readJson } from '../../storage/base-store.js';
10
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
9
11
  import { resolvedStorageArtifactPath } from '../../storage/storage-catalog.js';
10
12
  import { loadTechnologyRegistry } from '../technology-registry.js';
11
13
  const REGISTRY_DIR = join(dirname(fileURLToPath(import.meta.url)), '../../config/framework-registry');
@@ -1,6 +1,7 @@
1
1
  // engine/release/postmortem-generator.ts — SPEC-737: Post-mortem skeleton writer
2
2
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
4
5
  import { hashProjectPath, projectDataDir } from '../../storage/base-store.js';
5
6
  // ---------------------------------------------------------------------------
6
7
  // Template path
@@ -1,5 +1,5 @@
1
1
  export type RollbackStepName = 'npm-dist-tag-rm' | 'git-tag-delete-local' | 'git-tag-delete-remote' | 'smoke-test-verify';
2
- export interface RollbackStep {
2
+ export interface ReleaseRollbackStep {
3
3
  name: RollbackStepName;
4
4
  status: 'success' | 'failed' | 'skipped';
5
5
  stdout?: string;
@@ -14,7 +14,7 @@ export interface RollbackRunnerInput {
14
14
  }
15
15
  export interface RollbackRunnerResult {
16
16
  ok: boolean;
17
- steps: RollbackStep[];
17
+ steps: ReleaseRollbackStep[];
18
18
  failedStep?: RollbackStepName;
19
19
  }
20
20
  /**
@@ -39,7 +39,9 @@ export async function buildMergedBranchSet(projectPath, targetBranch = 'main') {
39
39
  */
40
40
  export async function detectStuckSpecs(projectPath, targetBranch = 'main') {
41
41
  // Lazy-import storage to keep engine layer free of direct storage coupling
42
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
42
43
  const { specStore } = await import('../../storage/index.js');
44
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
43
45
  const { hashProjectPath } = await import('../../storage/base-store.js');
44
46
  const projectId = hashProjectPath(projectPath);
45
47
  const allSpecs = await specStore.listSpecs(projectId);
@@ -73,6 +75,7 @@ export async function detectStuckSpecs(projectPath, targetBranch = 'main') {
73
75
  */
74
76
  export async function autoCloseStuckSpec(spec, projectPath) {
75
77
  try {
78
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
76
79
  const { handleUpdateStatus } = await import('../../tools/update-status.js');
77
80
  await handleUpdateStatus({
78
81
  projectPath,
@@ -89,7 +92,9 @@ export async function autoCloseStuckSpec(spec, projectPath) {
89
92
  }
90
93
  async function logAutoCloseFailure(specId, projectPath, err) {
91
94
  try {
95
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
92
96
  const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
97
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
93
98
  const { hashProjectPath } = await import('../../storage/base-store.js');
94
99
  const projectId = hashProjectPath(projectPath);
95
100
  await appendAutopilotLogEntry(projectId, {
@@ -117,7 +122,9 @@ async function logAutoCloseFailure(specId, projectPath, err) {
117
122
  */
118
123
  export async function logForceReleaseAudit(specIds, projectPath) {
119
124
  try {
125
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
120
126
  const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
127
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
121
128
  const { hashProjectPath } = await import('../../storage/base-store.js');
122
129
  const projectId = hashProjectPath(projectPath);
123
130
  await appendAutopilotLogEntry(projectId, {
@@ -6,7 +6,9 @@ import { join } from 'node:path';
6
6
  import { promisify } from 'node:util';
7
7
  import { atomicWriteFile } from '../safety/atomic-write-file.js';
8
8
  import { parseSpecIdsFromCommitMessage } from './parse-spec-refs.js';
9
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
9
10
  import { hashProjectPath } from '../../storage/base-store.js';
11
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
10
12
  import { specStore } from '../../storage/index.js';
11
13
  const execFile = promisify(execFileCb);
12
14
  const TERMINAL_STATUSES = new Set(['done', 'discarded']);
@@ -139,6 +141,7 @@ async function resolveSpecDir(specsRoot, specId) {
139
141
  function logToAutopilot(projectPath, specId, version, success) {
140
142
  void (async () => {
141
143
  try {
144
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
142
145
  const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
143
146
  const projectId = hashProjectPath(projectPath);
144
147
  await appendAutopilotLogEntry(projectId, {
@@ -1,6 +1,6 @@
1
1
  import type { RulesReconciliation } from '../types/index.js';
2
+ import { readFileSafeSync as readFileSafe } from '../core/shared/fs.js';
2
3
  export type { RulesReconciliation };
3
- declare function readFileSafe(path: string): string;
4
4
  /**
5
5
  * Compare CLAUDE.md conventions against existing .claude/rules/ files.
6
6
  * Auto-patches missing convention categories by generating new rules files.
@@ -1,8 +1,9 @@
1
1
  // engine/rules-reconciler.ts — Compare CLAUDE.md conventions against .claude/rules/ and auto-patch drift (SPEC-189)
2
- import { readFileSync, readdirSync, writeFileSync, mkdirSync } from 'node:fs';
2
+ import { readdirSync, writeFileSync, mkdirSync } from 'node:fs';
3
3
  import { join, basename } from 'node:path';
4
4
  import { parseConventions } from './convention-scanner/convention-parser.js';
5
5
  import { assertEnglishOnlyArtifactText } from './spec-language/english-only.js';
6
+ import { readFileSafeSync as readFileSafe } from '../core/shared/fs.js';
6
7
  // ── Helpers ───────────────────────────────────────────────────────────────────
7
8
  function listRulesFiles(projectPath) {
8
9
  const rulesDir = join(projectPath, '.claude', 'rules');
@@ -15,14 +16,6 @@ function listRulesFiles(projectPath) {
15
16
  return [];
16
17
  }
17
18
  }
18
- function readFileSafe(path) {
19
- try {
20
- return readFileSync(path, 'utf-8');
21
- }
22
- catch {
23
- return '';
24
- }
25
- }
26
19
  /** Unique convention categories detected in CLAUDE.md (source: 'claude-md' only). */
27
20
  function categoriesInClaudeMd(rules) {
28
21
  const categories = new Set();
@@ -3,6 +3,7 @@ import { rename, copyFile, unlink, readFile, writeFile, mkdir } from 'node:fs/pr
3
3
  import { existsSync } from 'node:fs';
4
4
  import { dirname } from 'node:path';
5
5
  import { randomBytes } from 'node:crypto';
6
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
6
7
  import { withFileLock } from '../../storage/file-mutex.js';
7
8
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
8
9
  const DEFAULT_BACKUP_COUNT = 3;
@@ -55,7 +55,9 @@ import { randomUUID } from 'node:crypto';
55
55
  import { hostname as osHostname } from 'node:os';
56
56
  import { isAbsolute, join } from 'node:path';
57
57
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
58
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
58
59
  import { hashProjectPath } from '../../storage/base-store.js';
60
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
59
61
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
60
62
  import { computeStaleReason, isPidDead, STALE_THRESHOLD_MS } from './lock-staleness.js';
61
63
  import { LockLeaseStore, } from './lock-lease-store.js';
@@ -53,6 +53,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
53
53
  import { createHash, randomUUID } from 'node:crypto';
54
54
  import { hostname } from 'node:os';
55
55
  import { dirname, join } from 'node:path';
56
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
56
57
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
57
58
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
58
59
  import { LockLeaseStore } from './lock-lease-store.js';
@@ -1,6 +1,7 @@
1
1
  import { chmodSync, existsSync, mkdirSync } from 'node:fs';
2
2
  import { dirname, isAbsolute, resolve } from 'node:path';
3
3
  import { DatabaseSync } from 'node:sqlite';
4
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
4
5
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
5
6
  const SCHEMA_VERSION = 1;
6
7
  const DEFAULT_BUSY_TIMEOUT_MS = 5_000;
@@ -53,7 +53,9 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
53
53
  import { readFile, readdir, rm } from 'node:fs/promises';
54
54
  import { hostname as osHostname } from 'node:os';
55
55
  import { isAbsolute, join } from 'node:path';
56
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
56
57
  import { hashProjectPath } from '../../storage/base-store.js';
58
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
57
59
  import { resolveStorageLayout } from '../../storage/storage-layout.js';
58
60
  import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
59
61
  import { computeStaleReason, isPidDead } from './lock-staleness.js';