@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
@@ -1,17 +1,8 @@
1
1
  // engine/detectors/monorepo-detector.ts — Monorepo tool detection
2
2
  // SPEC-004 tech-debt: Nx, Turborepo, Bazel, Rush, Moon monorepo detection
3
- import { access } from 'node:fs/promises';
4
3
  import { join } from 'node:path';
4
+ import { fileExists } from '../../core/shared/fs.js';
5
5
  /** File existence check — returns true if file is accessible */
6
- async function fileExists(filePath) {
7
- try {
8
- await access(filePath);
9
- return true;
10
- }
11
- catch {
12
- return false;
13
- }
14
- }
15
6
  /**
16
7
  * Detect which monorepo tool (if any) is used in the given project directory.
17
8
  *
@@ -3,6 +3,7 @@
3
3
  import { readFile } from 'node:fs/promises';
4
4
  import { join } from 'node:path';
5
5
  import { glob } from 'glob';
6
+ import { fileExistsByRead } from '../../core/shared/fs.js';
6
7
  // === Detection signals ===
7
8
  /** Explicit top-level files that indicate Nomad is configured. */
8
9
  const NOMAD_EXPLICIT_PATHS = ['nomad.hcl', 'nomad.json'];
@@ -25,13 +26,13 @@ const NOMAD_TASK_PATTERN = 'task "';
25
26
  export async function detectNomad(projectPath) {
26
27
  // Check explicit top-level Nomad config files
27
28
  for (const p of NOMAD_EXPLICIT_PATHS) {
28
- if (await fileExists(join(projectPath, p))) {
29
+ if (await fileExistsByRead(join(projectPath, p))) {
29
30
  return true;
30
31
  }
31
32
  }
32
33
  // Check Nomad directories
33
34
  for (const dir of NOMAD_DIRS) {
34
- if (await fileExists(join(projectPath, dir))) {
35
+ if (await fileExistsByRead(join(projectPath, dir))) {
35
36
  return true;
36
37
  }
37
38
  }
@@ -79,15 +80,6 @@ async function globMatch(projectPath, pattern) {
79
80
  return [];
80
81
  }
81
82
  }
82
- async function fileExists(filePath) {
83
- try {
84
- await readFile(filePath, 'utf-8');
85
- return true;
86
- }
87
- catch {
88
- return false;
89
- }
90
- }
91
83
  async function fileContainsAny(filePath, jobPatterns, taskPattern) {
92
84
  try {
93
85
  const content = await readFile(filePath, 'utf-8');
@@ -1,3 +1,5 @@
1
+ import { readFileOrNull } from '../../core/shared/fs.js';
2
+ export { readFileOrNull };
1
3
  /** npm package names that indicate OTel is installed */
2
4
  export declare const OTEL_NPM_PACKAGES: string[];
3
5
  /** Python package patterns (requirements.txt, pyproject.toml) */
@@ -10,7 +12,6 @@ export declare const OTEL_RUST_CRATE: "opentelemetry";
10
12
  export declare const OTEL_JAVA_PATTERN: "opentelemetry";
11
13
  /** Dependencies that indicate a project might need OTel (async workers, HTTP clients) */
12
14
  export declare const MULTISERVICE_DEPS: string[];
13
- export declare function readFileOrNull(filePath: string): Promise<string | null>;
14
15
  export declare function readPackageDeps(projectPath: string): Promise<{
15
16
  deps: Record<string, string>;
16
17
  devDeps: Record<string, string>;
@@ -1,8 +1,9 @@
1
1
  import { technologyValue } from '../technology-registry.js';
2
2
  // engine/detectors/otel-ecosystem-detectors.ts — SPEC-044
3
3
  // Per-ecosystem OTel detection helpers extracted from otel-detector.ts.
4
- import { readFile } from 'node:fs/promises';
5
4
  import { join } from 'node:path';
5
+ import { readFileOrNull } from '../../core/shared/fs.js';
6
+ export { readFileOrNull };
6
7
  // === OTel package patterns per ecosystem ===
7
8
  /** npm package names that indicate OTel is installed */
8
9
  export const OTEL_NPM_PACKAGES = [
@@ -35,15 +36,6 @@ export const MULTISERVICE_DEPS = [
35
36
  'amqplib',
36
37
  'nats',
37
38
  ];
38
- // === Shared helper ===
39
- export async function readFileOrNull(filePath) {
40
- try {
41
- return await readFile(filePath, 'utf-8');
42
- }
43
- catch {
44
- return null;
45
- }
46
- }
47
39
  export async function readPackageDeps(projectPath) {
48
40
  const content = await readFileOrNull(join(projectPath, 'package.json'));
49
41
  if (!content) {
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  // Planu — HTML document wrapper with inline CSS for executive summary
2
3
  const CSS = `
3
4
  @page { margin: 2cm; size: A4; }
@@ -47,11 +48,4 @@ ${bodyContent}
47
48
  </body>
48
49
  </html>`;
49
50
  }
50
- function escapeHtml(str) {
51
- return str
52
- .replace(/&/g, '&amp;')
53
- .replace(/</g, '&lt;')
54
- .replace(/>/g, '&gt;')
55
- .replace(/"/g, '&quot;');
56
- }
57
51
  //# sourceMappingURL=html-template.js.map
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  // ── Helpers ─────────────────────────────────────────────────────────────────
2
3
  function statusToBadgeClass(status) {
3
4
  switch (status) {
@@ -142,11 +143,4 @@ export function buildTimelineSection(svgContent) {
142
143
  export function buildFooterSection() {
143
144
  return `<div class="footer">Generated by Planu &mdash; ${new Date().toUTCString()}</div>`;
144
145
  }
145
- function escapeHtml(str) {
146
- return str
147
- .replace(/&/g, '&amp;')
148
- .replace(/</g, '&lt;')
149
- .replace(/>/g, '&gt;')
150
- .replace(/"/g, '&quot;');
151
- }
152
146
  //# sourceMappingURL=section-builders.js.map
@@ -1,4 +1,5 @@
1
1
  import { getCdnUrl } from '../../../config/version-defaults.js';
2
+ import { escapeHtml } from '../../../core/shared/strings.js';
2
3
  /**
3
4
  * Render an array of SpecDiagrams as HTML sections with Mermaid pre blocks.
4
5
  * Uses Mermaid.js CDN for client-side rendering with raw code fallback.
@@ -30,11 +31,4 @@ export function getMermaidScript() {
30
31
  </script>
31
32
  <noscript><style>.mermaid { white-space: pre; font-family: monospace; background: #f3f4f6; padding: 16px; border-radius: 8px; }</style></noscript>`;
32
33
  }
33
- function escapeHtml(str) {
34
- return str
35
- .replace(/&/g, '&amp;')
36
- .replace(/</g, '&lt;')
37
- .replace(/>/g, '&gt;')
38
- .replace(/"/g, '&quot;');
39
- }
40
34
  //# sourceMappingURL=mermaid-renderer.js.map
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  const STATUS_COLORS = {
2
3
  draft: { bg: '#e5e7eb', fg: '#374151' },
3
4
  review: { bg: '#dbeafe', fg: '#1d4ed8' },
@@ -299,11 +300,4 @@ function metricCard(value, label) {
299
300
  <div class="metric-label">${escapeHtml(label)}</div>
300
301
  </div>`;
301
302
  }
302
- function escapeHtml(str) {
303
- return str
304
- .replace(/&/g, '&amp;')
305
- .replace(/</g, '&lt;')
306
- .replace(/>/g, '&gt;')
307
- .replace(/"/g, '&quot;');
308
- }
309
303
  //# sourceMappingURL=spec-section-builders.js.map
@@ -2,6 +2,7 @@ import { extractPerSpecData } from './spec-data-extractor.js';
2
2
  import { buildSpecHeaderSection, buildAffectedFilesSection, buildArchDecisionsSection, buildSpecFooterSection, buildImpactAnalysisSection, buildEstimationReasoningSection, buildLivingSpecSection, buildAcceptanceCriteriaSection, } from './spec-section-builders.js';
3
3
  import { renderMermaidDiagrams, getMermaidScript } from './mermaid-renderer.js';
4
4
  import { wrapPerSpecHtml } from './html-wrapper.js';
5
+ import { escapeHtml } from '../../../core/shared/strings.js';
5
6
  /**
6
7
  * Generate a self-contained HTML technical report for a single spec.
7
8
  * Includes: header, scope, diagrams, impact analysis, affected files,
@@ -57,11 +58,4 @@ function buildScopeSection(scope, target, gitBranch) {
57
58
  ${gitBranch ? `<p><strong>Branch:</strong> <code>${escapeHtml(gitBranch)}</code></p>` : ''}
58
59
  </div>`;
59
60
  }
60
- function escapeHtml(str) {
61
- return str
62
- .replace(/&/g, '&amp;')
63
- .replace(/</g, '&lt;')
64
- .replace(/>/g, '&gt;')
65
- .replace(/"/g, '&quot;');
66
- }
67
61
  //# sourceMappingURL=technical-report.js.map
@@ -8,6 +8,7 @@ import { computeVelocity } from './data-aggregators/velocity-aggregator.js';
8
8
  import { computeBurndown } from './data-aggregators/burndown-aggregator.js';
9
9
  import { detectBottlenecks } from './data-aggregators/bottleneck-detector.js';
10
10
  import { computeAccuracy } from './data-aggregators/accuracy-aggregator.js';
11
+ import { escapeHtml } from '../../../core/shared/strings.js';
11
12
  /**
12
13
  * Generate the full analytics.html page for the Planu portal.
13
14
  * Returns an HTML string ready to write to disk.
@@ -202,13 +203,6 @@ function mapToPieSlices(counts) {
202
203
  color: CHART_COLORS[i % CHART_COLORS.length] ?? '#e94560',
203
204
  }));
204
205
  }
205
- function escapeHtml(str) {
206
- return str
207
- .replace(/&/g, '&amp;')
208
- .replace(/</g, '&lt;')
209
- .replace(/>/g, '&gt;')
210
- .replace(/"/g, '&quot;');
211
- }
212
206
  const ANALYTICS_CSS = `
213
207
  .analytics-main {
214
208
  max-width: 1100px;
@@ -1,12 +1,6 @@
1
1
  import { buildNavbar } from './portal-navbar.js';
2
2
  import { getPortalThemeCSS } from './portal-theme.js';
3
- function escapeHtml(s) {
4
- return s
5
- .replace(/&/g, '&amp;')
6
- .replace(/</g, '&lt;')
7
- .replace(/>/g, '&gt;')
8
- .replace(/"/g, '&quot;');
9
- }
3
+ import { escapeHtml } from '../../../core/shared/strings.js';
10
4
  const TECH_ICONS = {
11
5
  typescript: '🔷',
12
6
  javascript: '🟡',
@@ -1,12 +1,6 @@
1
1
  import { buildNavbar } from './portal-navbar.js';
2
2
  import { getPortalThemeCSS } from './portal-theme.js';
3
- function escapeHtml(s) {
4
- return s
5
- .replace(/&/g, '&amp;')
6
- .replace(/</g, '&lt;')
7
- .replace(/>/g, '&gt;')
8
- .replace(/"/g, '&quot;');
9
- }
3
+ import { escapeHtml } from '../../../core/shared/strings.js';
10
4
  function formatDate(dateStr) {
11
5
  try {
12
6
  const d = new Date(dateStr);
@@ -1,13 +1,7 @@
1
1
  import { buildNavbar } from './portal-navbar.js';
2
2
  import { getPortalThemeCSS } from './portal-theme.js';
3
3
  import { buildDecisionTimeline, DECISION_TIMELINE_CSS } from './decision-timeline-builder.js';
4
- function escapeHtml(s) {
5
- return s
6
- .replace(/&/g, '&amp;')
7
- .replace(/</g, '&lt;')
8
- .replace(/>/g, '&gt;')
9
- .replace(/"/g, '&quot;');
10
- }
4
+ import { escapeHtml } from '../../../core/shared/strings.js';
11
5
  const CATEGORY_COLORS = {
12
6
  architecture: '#7c3aed',
13
7
  stack: '#2563eb',
@@ -1,10 +1,4 @@
1
- function escapeHtml(s) {
2
- return s
3
- .replace(/&/g, '&amp;')
4
- .replace(/</g, '&lt;')
5
- .replace(/>/g, '&gt;')
6
- .replace(/"/g, '&quot;');
7
- }
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
8
2
  const CATEGORY_COLORS = {
9
3
  architecture: '#7c3aed', // purple
10
4
  stack: '#2563eb', // blue
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  const COLUMNS = [
2
3
  { key: 'draft', label: 'Draft' },
3
4
  { key: 'review', label: 'Review' },
@@ -77,13 +78,6 @@ function buildCard(spec) {
77
78
  ${tags ? `<div class="kanban-card-tags">${tags}</div>` : ''}
78
79
  </div>`;
79
80
  }
80
- function escapeHtml(str) {
81
- return str
82
- .replace(/&/g, '&amp;')
83
- .replace(/</g, '&lt;')
84
- .replace(/>/g, '&gt;')
85
- .replace(/"/g, '&quot;');
86
- }
87
81
  const KANBAN_CSS = `
88
82
  .kanban-board {
89
83
  display: grid;
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  function getBreadcrumbCss() {
2
3
  return `
3
4
  .planu-breadcrumbs {
@@ -48,13 +49,6 @@ function getBreadcrumbCss() {
48
49
  .planu-breadcrumbs, .planu-spec-nav { display: none !important; }
49
50
  }`;
50
51
  }
51
- function escapeHtml(str) {
52
- return str
53
- .replace(/&/g, '&amp;')
54
- .replace(/</g, '&lt;')
55
- .replace(/>/g, '&gt;')
56
- .replace(/"/g, '&quot;');
57
- }
58
52
  /**
59
53
  * Build a breadcrumb trail.
60
54
  * Last item is rendered as plain text (current page); all others are links.
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  const PAGE_CARDS = [
2
3
  {
3
4
  key: 'proposal',
@@ -131,13 +132,6 @@ function getLandingCardsCss() {
131
132
  .planu-cards-grid { grid-template-columns: repeat(2, 1fr); }
132
133
  }`;
133
134
  }
134
- function escapeHtml(str) {
135
- return str
136
- .replace(/&/g, '&amp;')
137
- .replace(/</g, '&lt;')
138
- .replace(/>/g, '&gt;')
139
- .replace(/"/g, '&quot;');
140
- }
141
135
  /**
142
136
  * Build the Quick Links section rendered between the navbar and the spec table
143
137
  * in planu/index.html. Cards that aren't yet generated are rendered greyed out.
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  /** All portal pages in display order */
2
3
  export const NAV_ITEMS = [
3
4
  { key: 'dashboard', label: 'Dashboard', filename: 'index.html', icon: '📋' },
@@ -99,13 +100,6 @@ const NAVBAR_CSS = `
99
100
  function getNavbarCss() {
100
101
  return NAVBAR_CSS;
101
102
  }
102
- function escapeHtml(str) {
103
- return str
104
- .replace(/&/g, '&amp;')
105
- .replace(/</g, '&lt;')
106
- .replace(/>/g, '&gt;')
107
- .replace(/"/g, '&quot;');
108
- }
109
103
  /**
110
104
  * Build a horizontal portal navbar.
111
105
  *
@@ -3,6 +3,9 @@
3
3
  * Order matches the navbar display order.
4
4
  */
5
5
  export declare const DETECTABLE_PAGES: Record<string, string>;
6
+ /**
7
+ * Check whether a single file exists on disk (non-throwing).
8
+ */
6
9
  /**
7
10
  * Detect which portal pages currently exist inside planu/.
8
11
  * Returns an array of page keys (e.g. ['proposal', 'executive-summary']).
@@ -1,6 +1,6 @@
1
1
  // Planu — Detects which portal pages exist on disk in planu/
2
- import { access } from 'node:fs/promises';
3
2
  import { join } from 'node:path';
3
+ import { fileExists } from '../../../core/shared/fs.js';
4
4
  /**
5
5
  * All detectable portal page keys mapped to their filenames within planu/.
6
6
  * Order matches the navbar display order.
@@ -18,15 +18,6 @@ export const DETECTABLE_PAGES = {
18
18
  /**
19
19
  * Check whether a single file exists on disk (non-throwing).
20
20
  */
21
- async function fileExists(filePath) {
22
- try {
23
- await access(filePath);
24
- return true;
25
- }
26
- catch {
27
- return false;
28
- }
29
- }
30
21
  /**
31
22
  * Detect which portal pages currently exist inside planu/.
32
23
  * Returns an array of page keys (e.g. ['proposal', 'executive-summary']).
@@ -1,6 +1,7 @@
1
1
  // Planu — Portal regenerator: auto-regen pages when stores change (SPEC-146)
2
2
  import { mkdir, writeFile } 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 } from '../../../storage/base-store.js';
5
6
  import { getAffectedPages } from './dirty-flag-map.js';
6
7
  import { withAudit } from '../../../engine/autopilot/audit-logger.js';
@@ -71,6 +72,7 @@ export async function regeneratePages(projectPath, changedStores) {
71
72
  async function generatePage(projectPath, page) {
72
73
  const projectId = hashProjectPath(projectPath);
73
74
  try {
75
+ // eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
74
76
  const { listSpecs } = await import('../../../storage/spec-store.js');
75
77
  const specs = await listSpecs(projectId);
76
78
  return await dispatchPageGenerator(projectPath, page, specs);
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  const IMPACT_LEVELS = ['low', 'medium', 'high', 'very_high', 'critical'];
2
3
  const PROB_LEVELS = [20, 40, 60, 80, 100];
3
4
  const CATEGORY_COLORS = {
@@ -74,13 +75,6 @@ function circleSizeFromUsd(usd) {
74
75
  }
75
76
  return 24;
76
77
  }
77
- function escapeHtml(s) {
78
- return s
79
- .replace(/&/g, '&amp;')
80
- .replace(/</g, '&lt;')
81
- .replace(/>/g, '&gt;')
82
- .replace(/"/g, '&quot;');
83
- }
84
78
  function buildGridCells() {
85
79
  const cells = [];
86
80
  for (let row = 0; row < 5; row++) {
@@ -2,13 +2,7 @@ import { buildNavbar } from './portal-navbar.js';
2
2
  import { getPortalThemeCSS } from './portal-theme.js';
3
3
  import { buildRiskMatrixSvg } from './risk-matrix-svg.js';
4
4
  import { buildRiskGaugeSvg } from './risk-gauge-svg.js';
5
- function escapeHtml(s) {
6
- return s
7
- .replace(/&/g, '&amp;')
8
- .replace(/</g, '&lt;')
9
- .replace(/>/g, '&gt;')
10
- .replace(/"/g, '&quot;');
11
- }
5
+ import { escapeHtml } from '../../../core/shared/strings.js';
12
6
  const STATUS_BADGE = {
13
7
  identified: 'planu-badge-muted',
14
8
  mitigating: 'planu-badge-info',
@@ -1,6 +1,7 @@
1
1
  import { getPortalThemeCSS } from './portal-theme.js';
2
2
  import { buildNavbar } from './portal-navbar.js';
3
3
  import { buildGanttChart } from '../proposal/proposal-gantt-builder.js';
4
+ import { escapeHtml } from '../../../core/shared/strings.js';
4
5
  /**
5
6
  * Generate the full roadmap.html page for the Planu portal.
6
7
  * Returns an HTML string ready to write to disk.
@@ -116,13 +117,6 @@ function buildMilestonesSection(specs) {
116
117
  return `<div class="milestone-timeline">${items.join('\n')}</div>`;
117
118
  }
118
119
  // --- Helpers ---
119
- function escapeHtml(str) {
120
- return str
121
- .replace(/&/g, '&amp;')
122
- .replace(/</g, '&lt;')
123
- .replace(/>/g, '&gt;')
124
- .replace(/"/g, '&quot;');
125
- }
126
120
  const ROADMAP_CSS = `
127
121
  .roadmap-main {
128
122
  max-width: 1100px;
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  const PHASE_COLORS = [
2
3
  '#7c3aed',
3
4
  '#0891b2',
@@ -116,11 +117,4 @@ ${ganttRows.join('\n')}
116
117
  </div>`;
117
118
  }
118
119
  // Internal helper
119
- function escapeHtml(str) {
120
- return str
121
- .replace(/&/g, '&amp;')
122
- .replace(/</g, '&lt;')
123
- .replace(/>/g, '&gt;')
124
- .replace(/"/g, '&quot;');
125
- }
126
120
  //# sourceMappingURL=proposal-gantt-builder.js.map
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../../core/shared/strings.js';
1
2
  /**
2
3
  * Build a responsive KPI grid with large value + small label per card.
3
4
  * Uses CSS class `.kpi-grid` and `.kpi-card` from proposal-themes.ts.
@@ -22,11 +23,4 @@ export function buildKpiGrid(kpis) {
22
23
  return `<div class="kpi-grid">${cards}</div>`;
23
24
  }
24
25
  // Internal helper
25
- function escapeHtml(str) {
26
- return str
27
- .replace(/&/g, '&amp;')
28
- .replace(/</g, '&lt;')
29
- .replace(/>/g, '&gt;')
30
- .replace(/"/g, '&quot;');
31
- }
32
26
  //# sourceMappingURL=proposal-kpi-builder.js.map
@@ -1,11 +1,5 @@
1
1
  import { t } from './proposal-i18n.js';
2
- function escapeHtml(str) {
3
- return str
4
- .replace(/&/g, '&amp;')
5
- .replace(/</g, '&lt;')
6
- .replace(/>/g, '&gt;')
7
- .replace(/"/g, '&quot;');
8
- }
2
+ import { escapeHtml } from '../../../core/shared/strings.js';
9
3
  function sectionTitle(icon, text) {
10
4
  return `<h2 class="section-title"><span class="icon">${icon}</span>${escapeHtml(text)}</h2>`;
11
5
  }
@@ -269,7 +263,7 @@ export function buildScorecardSection(items, title = 'Scorecard') {
269
263
  <span class="score-delta ${totalDelta > 0 ? 'delta-positive' : totalDelta < 0 ? 'delta-negative' : 'delta-neutral'}">${totalSign}${String(totalDelta)}</span>
270
264
  </div>`;
271
265
  return `<section>
272
- ${sectionTitle('&#128200;', escapeHtml(title))}
266
+ ${sectionTitle('&#128200;', title)}
273
267
  <div class="kpi-grid">
274
268
  ${cards.join('\n ')}
275
269
  ${totalCard}
@@ -1,14 +1,8 @@
1
1
  import { buildGanttChart } from './proposal-gantt-builder.js';
2
2
  import { buildKpiGrid } from './proposal-kpi-builder.js';
3
3
  import { t } from './proposal-i18n.js';
4
+ import { escapeHtml } from '../../../core/shared/strings.js';
4
5
  // ── Internal helpers ──────────────────────────────────────────────────────────
5
- function escapeHtml(str) {
6
- return str
7
- .replace(/&/g, '&amp;')
8
- .replace(/</g, '&lt;')
9
- .replace(/>/g, '&gt;')
10
- .replace(/"/g, '&quot;');
11
- }
12
6
  function sectionTitle(icon, text) {
13
7
  return `<h2 class="section-title"><span class="icon">${icon}</span>${escapeHtml(text)}</h2>`;
14
8
  }
@@ -2,6 +2,7 @@
2
2
  * HTML templates for the static docs site generator.
3
3
  * Provides layout, CSS, navigation, and shared HTML utilities.
4
4
  */
5
+ import { escapeHtml } from '../../core/shared/strings.js';
5
6
  // eslint-disable-next-line max-lines-per-function -- CSS template is inherently long
6
7
  export function getStyles() {
7
8
  return `
@@ -346,13 +347,6 @@ export function renderSearchScript() {
346
347
  });
347
348
  })();`;
348
349
  }
349
- function escapeHtml(text) {
350
- return text
351
- .replace(/&/g, '&amp;')
352
- .replace(/</g, '&lt;')
353
- .replace(/>/g, '&gt;')
354
- .replace(/"/g, '&quot;');
355
- }
356
350
  function escapeAttr(text) {
357
351
  return escapeHtml(text).replace(/'/g, '&#39;');
358
352
  }
@@ -1,3 +1,4 @@
1
+ import { escapeHtml } from '../../core/shared/strings.js';
1
2
  /**
2
3
  * Minimal markdown-to-HTML converter for spec rendering.
3
4
  * No external dependencies — pure regex-based transformation.
@@ -142,13 +143,6 @@ function renderInline(text) {
142
143
  result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
143
144
  return result;
144
145
  }
145
- function escapeHtml(text) {
146
- return text
147
- .replace(/&/g, '&amp;')
148
- .replace(/</g, '&lt;')
149
- .replace(/>/g, '&gt;')
150
- .replace(/"/g, '&quot;');
151
- }
152
146
  function closeList(output, inList) {
153
147
  if (inList) {
154
148
  output.push('</ul>');
@@ -1,7 +1,9 @@
1
1
  // engine/drift/violation-resolver.ts — Semi-automatic drift violation resolution (SPEC-408)
2
2
  import { mkdir, access } 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 { specStore } from '../../storage/index.js';
6
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
5
7
  import { DriftCacheStore } from '../../storage/drift-cache-store.js';
6
8
  import { atomicWriteFile } from '../safety/atomic-write-file.js';
7
9
  // ---------------------------------------------------------------------------
@@ -4,6 +4,7 @@
4
4
  import { CATEGORY_TTL, } from '../../types/index.js';
5
5
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
6
6
  import { dirname } from 'node:path';
7
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
7
8
  import { resolvedStorageArtifactPath } from '../../storage/storage-catalog.js';
8
9
  const MAX_ENTRIES = 200;
9
10
  const PRUNE_THRESHOLD_DAYS = 30;
@@ -1,6 +1,7 @@
1
1
  // engine/ecosystem-absorber/knowledge-cache.ts — Reads/writes ecosystem capability cache
2
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
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 { resolveStorageLayout } from '../../storage/storage-layout.js';
5
6
  const CACHE_VERSION = '1';
6
7
  const PRUNE_DAYS = 30;
@@ -1,19 +1,10 @@
1
1
  // engine/edge-db-detector.ts — SPEC-052
2
2
  // Detects edge-native SQLite usage: Turso (libSQL) and Cloudflare D1.
3
- import { readFile } from 'node:fs/promises';
4
3
  import { join } from 'node:path';
5
4
  import { glob } from 'glob';
5
+ import { readFileOrNull } from '../core/shared/fs.js';
6
6
  // === Source file glob ignore list ===
7
7
  const SOURCE_GLOB_IGNORE = ['node_modules/**', 'dist/**', 'build/**', '.git/**', 'coverage/**'];
8
- // === Helpers ===
9
- async function readFileOrNull(filePath) {
10
- try {
11
- return await readFile(filePath, 'utf-8');
12
- }
13
- catch {
14
- return null;
15
- }
16
- }
17
8
  async function readEdgeDbPackageDeps(projectPath) {
18
9
  const content = await readFileOrNull(join(projectPath, 'package.json'));
19
10
  if (!content) {
@@ -3,6 +3,7 @@
3
3
  import { join } from 'node:path';
4
4
  import { readFile } from 'node:fs/promises';
5
5
  import { atomicWriteFile } from '../safety/atomic-write-file.js';
6
+ // eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
6
7
  import { projectDataDir } from '../../storage/base-store.js';
7
8
  // ---------------------------------------------------------------------------
8
9
  // Constants