@planu/cli 4.13.0 → 4.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (787) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +24 -24
  3. package/dist/cli/commands/inspect.d.ts +4 -0
  4. package/dist/cli/commands/inspect.js +144 -0
  5. package/dist/cli/commands/install.d.ts +19 -1
  6. package/dist/cli/commands/install.js +145 -43
  7. package/dist/cli/commands/job.d.ts +3 -0
  8. package/dist/cli/commands/job.js +119 -0
  9. package/dist/cli/commands/offline.d.ts +15 -0
  10. package/dist/cli/commands/offline.js +132 -0
  11. package/dist/cli/commands/serve.js +4 -0
  12. package/dist/cli/commands/spec.js +1 -1
  13. package/dist/cli/commands/storage.d.ts +3 -0
  14. package/dist/cli/commands/storage.js +102 -0
  15. package/dist/cli/commands/uninstall.d.ts +10 -0
  16. package/dist/cli/commands/uninstall.js +93 -7
  17. package/dist/cli/commands/validate.js +1 -1
  18. package/dist/cli/index.js +2 -0
  19. package/dist/cli/router.js +9 -1
  20. package/dist/config/crash-shield-framework-rules.json +93 -0
  21. package/dist/config/environment-schema.json +149 -0
  22. package/dist/config/hardcode-exceptions.json +4 -0
  23. package/dist/config/license-plans.json +7 -0
  24. package/dist/config/native-release-public-key.pem +3 -0
  25. package/dist/config/native-targets.json +87 -0
  26. package/dist/config/product-public.d.ts +89 -0
  27. package/dist/config/product-public.js +140 -0
  28. package/dist/config/product-public.json +312 -0
  29. package/dist/config/product-public.ts +148 -0
  30. package/dist/config/release-compatibility.json +13 -0
  31. package/dist/config/release-policy.json +26 -0
  32. package/dist/config/runtime-policy.json +44 -0
  33. package/dist/config/skill-templates/planu-validate.md +7 -4
  34. package/dist/config/subagent-templates/planu-spec-implementer.md +7 -3
  35. package/dist/config/subagent-templates/planu-validator.md +10 -5
  36. package/dist/config/technology-registry.json +120 -0
  37. package/dist/config/version.js +7 -8
  38. package/dist/config/version.ts +10 -7
  39. package/dist/engine/abortable-process-runner.js +40 -9
  40. package/dist/engine/advanced-testing/accessibility-checker.js +12 -14
  41. package/dist/engine/advanced-testing/mutation-advisor.js +3 -4
  42. package/dist/engine/advanced-testing/property-based.js +2 -3
  43. package/dist/engine/advanced-testing/test-data-advisor.js +2 -3
  44. package/dist/engine/agent-generator.js +2 -1
  45. package/dist/engine/agent-handoff-store.js +2 -1
  46. package/dist/engine/agent-prompt-generator.js +7 -5
  47. package/dist/engine/agent-telemetry.js +2 -1
  48. package/dist/engine/ai-integration/gemini/extensions-advisor.js +41 -9
  49. package/dist/engine/ambiguity-detector.js +12 -11
  50. package/dist/engine/analyzer/db-engine.js +2 -3
  51. package/dist/engine/analyzer/detectors.js +13 -14
  52. package/dist/engine/analyzer/env-setup.js +9 -10
  53. package/dist/engine/analyzer-env-scanner/env-example.js +7 -8
  54. package/dist/engine/api-spec-generator/graphql-parser.js +2 -2
  55. package/dist/engine/api-validation/graphql-schema-validator.js +2 -1
  56. package/dist/engine/api-validation/openapi-impl-validator.js +6 -7
  57. package/dist/engine/architecture-detector.js +10 -8
  58. package/dist/engine/auth/config.d.ts +1 -1
  59. package/dist/engine/auth/config.js +4 -3
  60. package/dist/engine/auto-updater/atomic-upgrade.d.ts +8 -0
  61. package/dist/engine/auto-updater/atomic-upgrade.js +381 -0
  62. package/dist/engine/auto-updater/config-detector.js +9 -3
  63. package/dist/engine/auto-updater/config-patcher.d.ts +0 -4
  64. package/dist/engine/auto-updater/config-patcher.js +10 -15
  65. package/dist/engine/auto-updater/index.d.ts +3 -1
  66. package/dist/engine/auto-updater/index.js +44 -30
  67. package/dist/engine/auto-updater/npm-registry.js +10 -2
  68. package/dist/engine/auto-updater/release-verifier.d.ts +3 -0
  69. package/dist/engine/auto-updater/release-verifier.js +112 -0
  70. package/dist/engine/auto-updater/upgrade-lock.d.ts +6 -0
  71. package/dist/engine/auto-updater/upgrade-lock.js +28 -0
  72. package/dist/engine/auto-updater/upgrade-trust-state.d.ts +7 -0
  73. package/dist/engine/auto-updater/upgrade-trust-state.js +59 -0
  74. package/dist/engine/autopilot/audit-logger.js +2 -5
  75. package/dist/engine/best-practices-library.js +2 -1
  76. package/dist/engine/browser-validator.js +2 -1
  77. package/dist/engine/build-tool-detector.js +3 -2
  78. package/dist/engine/ci-generator/context-builders.js +7 -5
  79. package/dist/engine/ci-generator/stack-detector.js +0 -2
  80. package/dist/engine/ci-generator/yaml-builder.js +0 -2
  81. package/dist/engine/claude-config-auditor/rules-auditor.js +4 -3
  82. package/dist/engine/code-transforms/typescript/ast-utils.js +2 -3
  83. package/dist/engine/complexity-budget/trivial-detector.js +2 -1
  84. package/dist/engine/compliance-test-generator/index.js +7 -2
  85. package/dist/engine/compliance-test-generator/test-formatter.js +2 -2
  86. package/dist/engine/config-health/mcp-config-checker.js +2 -1
  87. package/dist/engine/config-health/ts-checker-scripts.js +4 -3
  88. package/dist/engine/config-health/ts-checker.js +3 -2
  89. package/dist/engine/convention-injector.js +5 -7
  90. package/dist/engine/convention-scanner/convention-parser.js +3 -2
  91. package/dist/engine/core-bridge-duplicate-blocks.d.ts +3 -0
  92. package/dist/engine/core-bridge-duplicate-blocks.js +57 -0
  93. package/dist/engine/core-bridge-gaps.d.ts +4 -0
  94. package/dist/engine/core-bridge-gaps.js +75 -0
  95. package/dist/engine/core-bridge.d.ts +9 -9
  96. package/dist/engine/core-bridge.js +196 -283
  97. package/dist/engine/cost-tracking/ledger.js +2 -5
  98. package/dist/engine/coverage-gap-analyzer.js +10 -1
  99. package/dist/engine/crash-shield/detectors/framework-detector.d.ts +2 -0
  100. package/dist/engine/crash-shield/detectors/framework-detector.js +110 -192
  101. package/dist/engine/crash-shield/detectors/typescript-detector.js +2 -1
  102. package/dist/engine/dashboard/data-loader.js +2 -1
  103. package/dist/engine/data-projects-gc/gc-runner.d.ts +7 -0
  104. package/dist/engine/data-projects-gc/gc-runner.js +113 -3
  105. package/dist/engine/data-projects-gc/scanner.js +5 -1
  106. package/dist/engine/decision-store.js +11 -14
  107. package/dist/engine/deleter/core.js +5 -5
  108. package/dist/engine/dep-auditor/abandonment-data.js +2 -1
  109. package/dist/engine/dep-auditor/abandonment-registry.js +3 -1
  110. package/dist/engine/dep-auditor/cve-fetcher.js +3 -0
  111. package/dist/engine/dep-auditor/dep-duplicates-detector.js +36 -4
  112. package/dist/engine/dep-auditor/license-registry.js +2 -0
  113. package/dist/engine/dependency-evaluator.d.ts +14 -0
  114. package/dist/engine/dependency-evaluator.js +81 -0
  115. package/dist/engine/deploy/providers/fly.js +7 -7
  116. package/dist/engine/deploy/providers/netlify.js +7 -7
  117. package/dist/engine/deploy/providers/railway.js +10 -12
  118. package/dist/engine/deploy/providers/vercel.js +7 -9
  119. package/dist/engine/deprecation-scanner/pattern-loader.js +0 -2
  120. package/dist/engine/desktop-detector.js +2 -3
  121. package/dist/engine/detect-duplication.js +2 -1
  122. package/dist/engine/detectors/advanced-framework-detector/css-state-detector.js +2 -1
  123. package/dist/engine/detectors/advanced-framework-detector/legacy-detector.js +2 -3
  124. package/dist/engine/detectors/advanced-framework-detector/modern-detector.js +3 -4
  125. package/dist/engine/detectors/agent-framework-detector.js +3 -2
  126. package/dist/engine/detectors/ai-native-detector.js +4 -6
  127. package/dist/engine/detectors/cache-db-detector.js +4 -3
  128. package/dist/engine/detectors/cicd-detector.js +4 -3
  129. package/dist/engine/detectors/deployment-detector.js +11 -12
  130. package/dist/engine/detectors/frontend-perf-detector.js +14 -9
  131. package/dist/engine/detectors/library-detector-multilang-a.js +16 -3
  132. package/dist/engine/detectors/library-detector-node.js +14 -4
  133. package/dist/engine/detectors/library-detector-python.js +7 -1
  134. package/dist/engine/detectors/library-detector.js +0 -2
  135. package/dist/engine/detectors/llm-detector/provider-maps.js +3 -2
  136. package/dist/engine/detectors/mcp-candidate-detector.js +12 -16
  137. package/dist/engine/detectors/mfe-detector.js +6 -7
  138. package/dist/engine/detectors/monitoring-detector.js +4 -3
  139. package/dist/engine/detectors/otel-detector.js +3 -2
  140. package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -2
  141. package/dist/engine/detectors/otel-ecosystem-detectors.js +4 -3
  142. package/dist/engine/detectors/platform-specialty-detector.js +3 -5
  143. package/dist/engine/detectors/template-engine-detector.js +3 -4
  144. package/dist/engine/doc-generator/builders.js +2 -3
  145. package/dist/engine/doc-generator/mobile-distribution-guide.js +13 -17
  146. package/dist/engine/doc-generator/portal/dirty-flag-map.d.ts +2 -2
  147. package/dist/engine/doc-generator/portal/portal-regenerator.js +3 -47
  148. package/dist/engine/domain-detector.js +3 -6
  149. package/dist/engine/dynamic-knowledge/knowledge-cache.js +3 -4
  150. package/dist/engine/dynamic-knowledge/knowledge-merger.js +17 -2
  151. package/dist/engine/dynamic-knowledge/web-researcher.js +15 -14
  152. package/dist/engine/dynamic-migration-detector/manifest-readers-extended.js +0 -2
  153. package/dist/engine/e2e-test-generator.js +4 -3
  154. package/dist/engine/ecosystem-absorber/knowledge-cache.js +2 -1
  155. package/dist/engine/ecosystem-absorber/platform-crawler.js +2 -2
  156. package/dist/engine/escalator/retry-counter.js +2 -1
  157. package/dist/engine/evidence-gates/artifact-reader.d.ts +6 -0
  158. package/dist/engine/evidence-gates/artifact-reader.js +105 -21
  159. package/dist/engine/evidence-gates/lifecycle-gate.d.ts +2 -1
  160. package/dist/engine/evidence-gates/lifecycle-gate.js +54 -0
  161. package/dist/engine/execution/context.d.ts +19 -0
  162. package/dist/engine/execution/context.js +127 -0
  163. package/dist/engine/execution/deadline-io.d.ts +21 -0
  164. package/dist/engine/execution/deadline-io.js +45 -0
  165. package/dist/engine/execution/job-executor.d.ts +16 -0
  166. package/dist/engine/execution/job-executor.js +140 -0
  167. package/dist/engine/execution/job-runtime.d.ts +78 -0
  168. package/dist/engine/execution/job-runtime.js +220 -0
  169. package/dist/engine/execution/native-relevance-scorer.d.ts +6 -0
  170. package/dist/engine/execution/native-relevance-scorer.js +64 -0
  171. package/dist/engine/execution/native-worker-dispatch.d.ts +3 -0
  172. package/dist/engine/execution/native-worker-dispatch.js +46 -0
  173. package/dist/engine/execution/native-worker-protocol.d.ts +6 -0
  174. package/dist/engine/execution/native-worker-protocol.js +33 -0
  175. package/dist/engine/execution/native-worker-runtime.d.ts +4 -0
  176. package/dist/engine/execution/native-worker-runtime.js +177 -0
  177. package/dist/engine/execution/native-worker-thread.d.ts +2 -0
  178. package/dist/engine/execution/native-worker-thread.js +66 -0
  179. package/dist/engine/execution/operation-journal.d.ts +66 -0
  180. package/dist/engine/execution/operation-journal.js +260 -0
  181. package/dist/engine/execution/outbox-worker.d.ts +31 -0
  182. package/dist/engine/execution/outbox-worker.js +192 -0
  183. package/dist/engine/execution/validate-job-executor.d.ts +24 -0
  184. package/dist/engine/execution/validate-job-executor.js +342 -0
  185. package/dist/engine/execution/validate-job-payload.d.ts +5 -0
  186. package/dist/engine/execution/validate-job-payload.js +87 -0
  187. package/dist/engine/execution/validate-job-recovery.d.ts +4 -0
  188. package/dist/engine/execution/validate-job-recovery.js +47 -0
  189. package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
  190. package/dist/engine/execution/validate-worker-runtime.js +100 -0
  191. package/dist/engine/execution/validate-worker-thread.d.ts +2 -0
  192. package/dist/engine/execution/validate-worker-thread.js +71 -0
  193. package/dist/engine/execution-plan/desktop-distribution.js +3 -7
  194. package/dist/engine/execution-plan/mobile-distribution.js +4 -9
  195. package/dist/engine/execution-plan/phases.js +4 -5
  196. package/dist/engine/execution-plan/plan-utils.js +8 -5
  197. package/dist/engine/facilitate/context-loader.js +3 -9
  198. package/dist/engine/figma/code-connect-fetcher.js +9 -8
  199. package/dist/engine/filesystem-watcher/index.d.ts +3 -3
  200. package/dist/engine/filesystem-watcher/index.js +5 -5
  201. package/dist/engine/framework-detector.js +14 -15
  202. package/dist/engine/git/planu-autocommit.js +8 -7
  203. package/dist/engine/git/repository-probe.d.ts +3 -0
  204. package/dist/engine/git/repository-probe.js +13 -0
  205. package/dist/engine/global-rules-manager.js +2 -2
  206. package/dist/engine/handoff-artifacts/io.js +2 -3
  207. package/dist/engine/handoff-artifacts/schemas/red-tests-handoff.js +8 -1
  208. package/dist/engine/handoff-artifacts/schemas.d.ts +4 -0
  209. package/dist/engine/handoff-artifacts/schemas.js +5 -0
  210. package/dist/engine/hook-generator/stack-hook-templates.js +4 -4
  211. package/dist/engine/hooks/config-loader.js +1 -1
  212. package/dist/engine/hooks/context-injector.js +4 -7
  213. package/dist/engine/hooks/file-watcher.js +1 -14
  214. package/dist/engine/hooks-reconciler.js +6 -4
  215. package/dist/engine/infrastructure/component-mapper.js +5 -7
  216. package/dist/engine/infrastructure/docker-compose-generator.js +8 -10
  217. package/dist/engine/infrastructure/index.js +6 -3
  218. package/dist/engine/infrastructure/kubernetes-generator.js +2 -2
  219. package/dist/engine/infrastructure/railway-generator.js +10 -8
  220. package/dist/engine/infrastructure/signal-detector.js +6 -8
  221. package/dist/engine/infrastructure/terraform-generator.js +6 -8
  222. package/dist/engine/legal-compliance/detector.js +3 -2
  223. package/dist/engine/local-first/storage-advisor.js +5 -6
  224. package/dist/engine/macos-keychain-native-port.d.ts +5 -0
  225. package/dist/engine/macos-keychain-native-port.js +26 -0
  226. package/dist/engine/marketplace-fetcher/cache.js +3 -1
  227. package/dist/engine/mcp-config/mcp-config-writer.d.ts +2 -2
  228. package/dist/engine/mcp-config/mcp-config-writer.js +10 -8
  229. package/dist/engine/migration/db-migrator.js +2 -5
  230. package/dist/engine/migration/equivalence-mapper.js +12 -13
  231. package/dist/engine/migration/service-catalogs.js +6 -7
  232. package/dist/engine/migration/service-migrator-catalogs.js +6 -7
  233. package/dist/engine/mobile-detector-ios.js +2 -3
  234. package/dist/engine/mobile-detector.js +16 -4
  235. package/dist/engine/model-router/complexity-analyzer.js +4 -7
  236. package/dist/engine/multi-agent-review/security-analyzer.js +3 -1
  237. package/dist/engine/multi-app-detector/app-type.js +26 -21
  238. package/dist/engine/multi-app-detector/core.js +3 -2
  239. package/dist/engine/multi-teammate-review/disagreement-counter.js +2 -1
  240. package/dist/engine/multi-teammate-review/panel-orchestrator.js +0 -2
  241. package/dist/engine/mutation-config-generator.js +10 -7
  242. package/dist/engine/native-capability-policy.d.ts +4 -0
  243. package/dist/engine/native-capability-policy.js +24 -0
  244. package/dist/engine/native-platform.d.ts +3 -0
  245. package/dist/engine/native-platform.js +44 -0
  246. package/dist/engine/native-runtime-handshake.d.ts +20 -0
  247. package/dist/engine/native-runtime-handshake.js +230 -0
  248. package/dist/engine/network-policy.d.ts +27 -0
  249. package/dist/engine/network-policy.js +174 -0
  250. package/dist/engine/next-spec-resolver/dependency-filter.js +2 -22
  251. package/dist/engine/nfr-profile-detector.js +12 -16
  252. package/dist/engine/nli-keywords.js +8 -9
  253. package/dist/engine/oauth/config-guard.js +4 -5
  254. package/dist/engine/observability/local-execution-spans.d.ts +15 -0
  255. package/dist/engine/observability/local-execution-spans.js +63 -0
  256. package/dist/engine/orchestrator/runtime.js +0 -1
  257. package/dist/engine/package-registry.js +2 -6
  258. package/dist/engine/performance-analyzer.js +2 -5
  259. package/dist/engine/permissions-merger/stack-detectors.js +5 -5
  260. package/dist/engine/planu-core.darwin-arm64.node.manifest.json +39 -0
  261. package/dist/engine/planu-core.darwin-arm64.node.sbom.json +1310 -0
  262. package/dist/engine/planu-core.darwin-x64.node.manifest.json +39 -0
  263. package/dist/engine/planu-core.darwin-x64.node.sbom.json +1310 -0
  264. package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +38 -0
  265. package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +1310 -0
  266. package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +38 -0
  267. package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +1310 -0
  268. package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +38 -0
  269. package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +1310 -0
  270. package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +38 -0
  271. package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +1310 -0
  272. package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +38 -0
  273. package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +1310 -0
  274. package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +38 -0
  275. package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +1310 -0
  276. package/dist/engine/platform-detector/desktop.js +15 -2
  277. package/dist/engine/platform-detector/extensions.js +2 -1
  278. package/dist/engine/platform-detector/games.js +2 -1
  279. package/dist/engine/platform-detector.js +3 -2
  280. package/dist/engine/platform-engineering/idp-detector.js +2 -1
  281. package/dist/engine/plugin-installer/stack-matcher.js +9 -17
  282. package/dist/engine/plugins/lifecycle.js +6 -2
  283. package/dist/engine/prior-decisions/contradiction-detector.js +60 -30
  284. package/dist/engine/project-dna/stack-detector.js +15 -17
  285. package/dist/engine/project-graph/builder.js +11 -0
  286. package/dist/engine/project-graph/cache.js +1 -1
  287. package/dist/engine/project-graph/freshness-projection.d.ts +16 -0
  288. package/dist/engine/project-graph/freshness-projection.js +95 -0
  289. package/dist/engine/project-graph/index.d.ts +1 -0
  290. package/dist/engine/project-graph/index.js +1 -0
  291. package/dist/engine/project-graph/query.js +15 -25
  292. package/dist/engine/project-health-checker.js +3 -4
  293. package/dist/engine/project-scanner/stack-detector.js +17 -17
  294. package/dist/engine/property-test-generator.js +2 -3
  295. package/dist/engine/qa-gate.d.ts +1 -0
  296. package/dist/engine/qa-gate.js +6 -4
  297. package/dist/engine/quality-gates/gate-catalog.js +47 -46
  298. package/dist/engine/quality-gates/gate-injector.js +9 -4
  299. package/dist/engine/registry/core.js +0 -2
  300. package/dist/engine/registry/loader.js +9 -12
  301. package/dist/engine/registry/matcher.js +129 -24
  302. package/dist/engine/resilience-detector/concurrency-detector.js +4 -4
  303. package/dist/engine/resilience-detector/middleware-detector.js +11 -13
  304. package/dist/engine/resilience-detector/validation-detector.js +17 -4
  305. package/dist/engine/reverse-engineer/config-analyzer.js +9 -8
  306. package/dist/engine/reverse-engineer/orchestrator.js +5 -9
  307. package/dist/engine/reverse-engineer/test-file-parser.js +6 -3
  308. package/dist/engine/rules-generator/index.js +6 -5
  309. package/dist/engine/runtime-policy.d.ts +7 -0
  310. package/dist/engine/runtime-policy.js +101 -0
  311. package/dist/engine/runtime-security/checkers/content-security.js +21 -6
  312. package/dist/engine/runtime-security/checkers/file-permissions.js +0 -2
  313. package/dist/engine/safety/atomic-write-file.js +20 -9
  314. package/dist/engine/safety/atomic-writer.js +10 -3
  315. package/dist/engine/safety/cross-process-lock.d.ts +3 -40
  316. package/dist/engine/safety/cross-process-lock.js +268 -272
  317. package/dist/engine/safety/file-mutex.d.ts +2 -9
  318. package/dist/engine/safety/file-mutex.js +155 -87
  319. package/dist/engine/safety/health-monitor.js +15 -6
  320. package/dist/engine/safety/lock-lease-store.d.ts +79 -0
  321. package/dist/engine/safety/lock-lease-store.js +372 -0
  322. package/dist/engine/safety/lock-scavenger.d.ts +2 -5
  323. package/dist/engine/safety/lock-scavenger.js +158 -76
  324. package/dist/engine/safety/lock-staleness.js +4 -1
  325. package/dist/engine/safety/obsolete-lock-guard.d.ts +8 -0
  326. package/dist/engine/safety/obsolete-lock-guard.js +31 -0
  327. package/dist/engine/safety/transaction.js +3 -3
  328. package/dist/engine/sandbox/index.js +2 -1
  329. package/dist/engine/sandbox/runner-detect.js +3 -2
  330. package/dist/engine/sandbox/runner-docker.js +4 -3
  331. package/dist/engine/scan-project/module-discoverer.js +3 -2
  332. package/dist/engine/schema-generator.js +16 -9
  333. package/dist/engine/security-analyzer/criteria-generator.js +2 -3
  334. package/dist/engine/self-healing/healer.js +4 -4
  335. package/dist/engine/session-safeguard/learnings-buffer.d.ts +1 -2
  336. package/dist/engine/session-safeguard/learnings-buffer.js +42 -65
  337. package/dist/engine/shared-agent-memory.js +66 -74
  338. package/dist/engine/skill-adapter/command-rewriter.js +3 -2
  339. package/dist/engine/skill-adapter/index.js +3 -3
  340. package/dist/engine/skill-adapter/placeholder-map.js +3 -2
  341. package/dist/engine/skill-bootstrap/stack-matcher.js +47 -48
  342. package/dist/engine/skill-generation/stack-content-generator.js +0 -2
  343. package/dist/engine/skill-generator/workflow-skill-generator.js +2 -1
  344. package/dist/engine/skill-registry/ttl-refresh.js +3 -1
  345. package/dist/engine/skills/skills-fetcher.js +3 -6
  346. package/dist/engine/skills-reconciler.js +19 -39
  347. package/dist/engine/spec-coverage/test-finder.js +7 -6
  348. package/dist/engine/spec-diff-engine.js +3 -3
  349. package/dist/engine/spec-generator/api-key-resolver.d.ts +1 -1
  350. package/dist/engine/spec-generator/api-key-resolver.js +3 -24
  351. package/dist/engine/spec-generators/issue-extractor.js +9 -3
  352. package/dist/engine/spec-migrator/drift-detector.js +5 -13
  353. package/dist/engine/spec-migrator/filesystem-import.js +14 -10
  354. package/dist/engine/spec-migrator/planu-canonical-policy.js +10 -1
  355. package/dist/engine/spec-migrator/strict-planu-cleanup.js +24 -25
  356. package/dist/engine/spec-registry/adapter.d.ts +0 -5
  357. package/dist/engine/spec-registry/adapter.js +45 -46
  358. package/dist/engine/spec-registry/client.js +2 -0
  359. package/dist/engine/spec-source-sync.js +3 -2
  360. package/dist/engine/spec-templates/custom-loader.js +2 -3
  361. package/dist/engine/spec-templates/templates-domain-specific.js +8 -5
  362. package/dist/engine/spec-templates/templates-perf-integration.js +2 -3
  363. package/dist/engine/stack-auditor/manifest-reader.js +0 -2
  364. package/dist/engine/staleness/stale-implementing.js +7 -7
  365. package/dist/engine/tdd-scaffold-generator.js +24 -11
  366. package/dist/engine/teammate-router/green-phase-verifier.js +2 -1
  367. package/dist/engine/teammate-router/red-phase-verifier.js +2 -1
  368. package/dist/engine/technology-registry.d.ts +11 -0
  369. package/dist/engine/technology-registry.js +142 -0
  370. package/dist/engine/telemetry/error-reporter.d.ts +1 -2
  371. package/dist/engine/telemetry/error-reporter.js +11 -18
  372. package/dist/engine/telemetry/health-checker.js +5 -14
  373. package/dist/engine/telemetry/index.d.ts +0 -1
  374. package/dist/engine/telemetry/index.js +0 -1
  375. package/dist/engine/telemetry/stance.js +3 -2
  376. package/dist/engine/telemetry/telemetry-client.d.ts +1 -5
  377. package/dist/engine/telemetry/telemetry-client.js +45 -29
  378. package/dist/engine/telemetry/telemetry-store.d.ts +3 -3
  379. package/dist/engine/telemetry/telemetry-store.js +30 -23
  380. package/dist/engine/test-framework-detector/detectors.js +8 -8
  381. package/dist/engine/test-framework-detector/strategy.js +8 -9
  382. package/dist/engine/test-generators/agent-test-templates.js +2 -3
  383. package/dist/engine/test-generators/contract-test-generator.d.ts +1 -1
  384. package/dist/engine/test-generators/contract-test-generator.js +9 -202
  385. package/dist/engine/test-generators/platform-test-templates-b.js +2 -3
  386. package/dist/engine/test-generators/platform-test-templates.js +2 -5
  387. package/dist/engine/test-mocks-generator.js +4 -3
  388. package/dist/engine/test-plan-generator.js +30 -12
  389. package/dist/engine/test-scaffold-generator/advanced-scaffold.js +4 -5
  390. package/dist/engine/test-scaffold-generator/unit-scaffold.js +5 -6
  391. package/dist/engine/timing/budget.d.ts +6 -17
  392. package/dist/engine/timing/budget.js +80 -64
  393. package/dist/engine/tool-groups/group-manager.js +3 -3
  394. package/dist/engine/universal-rules/installer.js +1 -1
  395. package/dist/engine/universal-rules/rules/planu-modes.js +2 -0
  396. package/dist/engine/universal-rules/rules/planu-release-policy.js +1 -0
  397. package/dist/engine/update-notifier.js +8 -5
  398. package/dist/engine/validation/approved-spec-portability.d.ts +12 -0
  399. package/dist/engine/validation/approved-spec-portability.js +107 -0
  400. package/dist/engine/validation/durable-validation.d.ts +36 -0
  401. package/dist/engine/validation/durable-validation.js +335 -0
  402. package/dist/engine/validation/validation-freshness.d.ts +36 -0
  403. package/dist/engine/validation/validation-freshness.js +427 -0
  404. package/dist/engine/validation/validation-receipt-codec.d.ts +13 -0
  405. package/dist/engine/validation/validation-receipt-codec.js +182 -0
  406. package/dist/engine/validation/validation-receipt.d.ts +59 -0
  407. package/dist/engine/validation/validation-receipt.js +282 -0
  408. package/dist/engine/validation/validation-source-policy.d.ts +4 -0
  409. package/dist/engine/validation/validation-source-policy.js +16 -0
  410. package/dist/engine/validation/validation-submission.d.ts +36 -0
  411. package/dist/engine/validation/validation-submission.js +128 -0
  412. package/dist/engine/validation-evidence-ledger.js +41 -0
  413. package/dist/engine/validation-impact-planner.js +25 -9
  414. package/dist/engine/validator/spec-compliance-runner.d.ts +1 -1
  415. package/dist/engine/validator/spec-compliance-runner.js +17 -8
  416. package/dist/engine/validator/validation-report-writer.js +1 -1
  417. package/dist/engine/validator.js +2 -1
  418. package/dist/engine/verify-integrations/index.js +1 -1
  419. package/dist/engine/version-resolver.js +5 -6
  420. package/dist/engine/web-fetcher/stack-advisor.js +156 -92
  421. package/dist/engine/web-fetcher/stack-detector.js +114 -54
  422. package/dist/engine/workspace-manager.js +3 -2
  423. package/dist/errors/classified-degradation.d.ts +3 -0
  424. package/dist/errors/classified-degradation.js +10 -0
  425. package/dist/errors/degradation-sink.d.ts +3 -0
  426. package/dist/errors/degradation-sink.js +5 -0
  427. package/dist/errors/error-taxonomy.d.ts +12 -0
  428. package/dist/errors/error-taxonomy.js +62 -0
  429. package/dist/hosts/claude-code/ux/mcp-prompts.js +10 -4
  430. package/dist/hosts/claude-code/ux/mcp-resources.js +4 -2
  431. package/dist/hosts/codex/config-scaffold.js +4 -3
  432. package/dist/hosts/gemini/config-scaffold.js +2 -1
  433. package/dist/hosts/gemini/multimodal-spec-flow.js +7 -4
  434. package/dist/index.js +21 -6
  435. package/dist/resources/patterns.js +3 -1
  436. package/dist/resources/specs.js +3 -1
  437. package/dist/resources/templates.js +3 -1
  438. package/dist/security/adapters/environment.d.ts +12 -0
  439. package/dist/security/adapters/environment.js +25 -0
  440. package/dist/security/adapters/linux-secret-service.d.ts +8 -0
  441. package/dist/security/adapters/linux-secret-service.js +60 -0
  442. package/dist/security/adapters/macos-keychain.d.ts +18 -0
  443. package/dist/security/adapters/macos-keychain.js +90 -0
  444. package/dist/security/adapters/windows-credential-manager.d.ts +8 -0
  445. package/dist/security/adapters/windows-credential-manager.js +58 -0
  446. package/dist/security/redactor.d.ts +5 -0
  447. package/dist/security/redactor.js +58 -0
  448. package/dist/security/secret-field.d.ts +5 -0
  449. package/dist/security/secret-field.js +17 -0
  450. package/dist/security/secret-migration.d.ts +3 -0
  451. package/dist/security/secret-migration.js +123 -0
  452. package/dist/security/secret-provider.d.ts +23 -0
  453. package/dist/security/secret-provider.js +145 -0
  454. package/dist/security/secure-json.d.ts +3 -0
  455. package/dist/security/secure-json.js +29 -0
  456. package/dist/storage/api-surfaces-store.js +2 -2
  457. package/dist/storage/approval-operation-lock.d.ts +1 -1
  458. package/dist/storage/approval-operation-lock.js +5 -3
  459. package/dist/storage/audit-trail-store.d.ts +1 -1
  460. package/dist/storage/audit-trail-store.js +48 -62
  461. package/dist/storage/autopilot-log-store.js +12 -5
  462. package/dist/storage/base-store.d.ts +8 -8
  463. package/dist/storage/base-store.js +57 -20
  464. package/dist/storage/checkpoint-store.js +5 -2
  465. package/dist/storage/comments-store.js +2 -2
  466. package/dist/storage/compliance-audit-store.js +5 -2
  467. package/dist/storage/compliance-gate-config-store.js +7 -4
  468. package/dist/storage/compliance-store.js +2 -2
  469. package/dist/storage/context-profile-store.js +2 -2
  470. package/dist/storage/crash-shield-store.js +8 -4
  471. package/dist/storage/feedback-store.js +10 -6
  472. package/dist/storage/figma-store.js +8 -4
  473. package/dist/storage/file-mutex.js +9 -1
  474. package/dist/storage/gaps-log.js +7 -4
  475. package/dist/storage/global-projects-store.js +4 -2
  476. package/dist/storage/ideas-store.js +2 -2
  477. package/dist/storage/index.d.ts +5 -0
  478. package/dist/storage/index.js +5 -0
  479. package/dist/storage/knowledge-store/knowledge.js +27 -33
  480. package/dist/storage/lessons-store.js +2 -2
  481. package/dist/storage/license-store.js +13 -41
  482. package/dist/storage/migrations/canonical-storage.d.ts +15 -0
  483. package/dist/storage/migrations/canonical-storage.js +599 -0
  484. package/dist/storage/oauth-store.js +36 -8
  485. package/dist/storage/path-resolver.js +16 -3
  486. package/dist/storage/pr-store.js +2 -2
  487. package/dist/storage/project-drift-store.js +20 -8
  488. package/dist/storage/project-identity.d.ts +32 -0
  489. package/dist/storage/project-identity.js +194 -0
  490. package/dist/storage/project-resolver.js +14 -7
  491. package/dist/storage/release-notes-store.js +2 -6
  492. package/dist/storage/runtime-db.d.ts +186 -0
  493. package/dist/storage/runtime-db.js +1054 -0
  494. package/dist/storage/schema-registry.d.ts +5 -0
  495. package/dist/storage/schema-registry.js +74 -0
  496. package/dist/storage/sentry-store.js +20 -9
  497. package/dist/storage/session-state-store.js +12 -5
  498. package/dist/storage/session-store.js +12 -4
  499. package/dist/storage/skill-registry-storage.d.ts +1 -1
  500. package/dist/storage/skill-registry-storage.js +13 -11
  501. package/dist/storage/slack-store.js +10 -5
  502. package/dist/storage/spec-store.js +31 -24
  503. package/dist/storage/status-store/file-lock.js +31 -9
  504. package/dist/storage/status-store/self-healing.js +10 -5
  505. package/dist/storage/status-store/version-sync.js +8 -6
  506. package/dist/storage/steering-store.js +2 -2
  507. package/dist/storage/storage-bundle.d.ts +5 -0
  508. package/dist/storage/storage-bundle.js +117 -0
  509. package/dist/storage/storage-catalog-validation.d.ts +3 -0
  510. package/dist/storage/storage-catalog-validation.js +20 -0
  511. package/dist/storage/storage-catalog.d.ts +25 -0
  512. package/dist/storage/storage-catalog.js +390 -0
  513. package/dist/storage/storage-layout.d.ts +24 -0
  514. package/dist/storage/storage-layout.js +101 -0
  515. package/dist/storage/storybook-store.js +2 -2
  516. package/dist/storage/supabase-store.js +24 -6
  517. package/dist/storage/tdd-policy-store.js +8 -6
  518. package/dist/storage/tech-debt-store.js +3 -3
  519. package/dist/storage/technology-selection-store.d.ts +1 -1
  520. package/dist/storage/technology-selection-store.js +6 -3
  521. package/dist/storage/token-cache-store.js +3 -3
  522. package/dist/storage/token-ledger-store.js +13 -8
  523. package/dist/storage/transition-log.js +7 -4
  524. package/dist/storage/trash-store.js +15 -6
  525. package/dist/storage/vector-store/migrator.js +7 -2
  526. package/dist/storage/vector-store/sqlite-adapter.js +4 -1
  527. package/dist/storage/webhook-server-store.js +2 -2
  528. package/dist/tools/api-spec-generator-handler.js +3 -2
  529. package/dist/tools/auto-update-handler.d.ts +1 -1
  530. package/dist/tools/auto-update-handler.js +1 -1
  531. package/dist/tools/browser-validate-handler.js +2 -1
  532. package/dist/tools/challenge-spec/platform-challenge-scenarios-b.js +8 -5
  533. package/dist/tools/challenge-spec/scenarios-desktop.js +8 -3
  534. package/dist/tools/challenge-spec/scenarios-failure.js +7 -2
  535. package/dist/tools/challenge-spec/security-challenge-scenarios.js +3 -3
  536. package/dist/tools/clarify-requirements/multiple-choice.js +53 -41
  537. package/dist/tools/comments-handler.js +2 -3
  538. package/dist/tools/compliance-test-handler.js +2 -2
  539. package/dist/tools/configure-telemetry.js +11 -11
  540. package/dist/tools/create-spec/auto-pipeline.js +13 -1
  541. package/dist/tools/create-spec/autopilot-analyzer.d.ts +1 -1
  542. package/dist/tools/create-spec/autopilot-analyzer.js +2 -4
  543. package/dist/tools/create-spec/mcp-tool-contract.d.ts +10 -4
  544. package/dist/tools/create-spec/mcp-tool-contract.js +7 -36
  545. package/dist/tools/create-spec/post-creation.d.ts +2 -1
  546. package/dist/tools/create-spec/post-creation.js +56 -54
  547. package/dist/tools/create-spec/relevance-scorer.d.ts +1 -1
  548. package/dist/tools/create-spec/relevance-scorer.js +17 -1
  549. package/dist/tools/create-spec/spec-builder.js +2 -12
  550. package/dist/tools/create-spec/spec-created-outbox-consumer.d.ts +14 -0
  551. package/dist/tools/create-spec/spec-created-outbox-consumer.js +176 -0
  552. package/dist/tools/create-spec.js +385 -520
  553. package/dist/tools/define-ui-contract/agent-interaction-contract.js +2 -4
  554. package/dist/tools/define-ui-contract-desktop/desktop-contract.js +12 -4
  555. package/dist/tools/define-ui-contract-desktop/native-contract.js +7 -3
  556. package/dist/tools/define-ui-contract-extensions.js +2 -3
  557. package/dist/tools/define-ui-contract-mobile.js +5 -9
  558. package/dist/tools/define-ui-contract-web/component-tree.js +4 -3
  559. package/dist/tools/define-ui-contract.js +7 -4
  560. package/dist/tools/deploy/deploy-spec.js +2 -4
  561. package/dist/tools/deploy/deploy-status.js +2 -4
  562. package/dist/tools/design-schema/nosql-category-schemas.js +2 -3
  563. package/dist/tools/design-schema-sql/migrations.js +3 -2
  564. package/dist/tools/design-schema-sql/tables.js +4 -1
  565. package/dist/tools/design-schema.js +4 -3
  566. package/dist/tools/feedback-handler.js +2 -4
  567. package/dist/tools/gc-data-projects.js +5 -5
  568. package/dist/tools/generate-execution-plan.js +3 -4
  569. package/dist/tools/generate-sub-agent.js +2 -1
  570. package/dist/tools/generate-tests/generators/a11y-tests-generator.js +5 -4
  571. package/dist/tools/generate-tests/generators/advanced-testing-generator.js +5 -4
  572. package/dist/tools/generate-tests/generators/concurrency-test-generator/js-templates.js +9 -4
  573. package/dist/tools/generate-tests/generators/concurrency-test-generator.js +8 -4
  574. package/dist/tools/generate-tests/generators/database/detectors.js +9 -3
  575. package/dist/tools/generate-tests/generators/database/index.js +2 -4
  576. package/dist/tools/generate-tests/generators/event-test-generator.js +5 -4
  577. package/dist/tools/generate-tests/generators/game-tests-generator.js +2 -1
  578. package/dist/tools/generate-tests/generators/graphql-test-generator.js +11 -5
  579. package/dist/tools/generate-tests/generators/grpc-test-generator.js +2 -3
  580. package/dist/tools/generate-tests/generators/llm-security-test-generator.js +4 -3
  581. package/dist/tools/generate-tests/generators/local-first-test-generator.js +4 -3
  582. package/dist/tools/generate-tests/generators/mcp-tests-generator.js +11 -9
  583. package/dist/tools/generate-tests/generators/microservices/index.js +2 -3
  584. package/dist/tools/generate-tests/generators/otel-test-generator.js +6 -3
  585. package/dist/tools/generate-tests/generators/security/detectors.js +2 -5
  586. package/dist/tools/generate-tests/generators/security/index.js +2 -4
  587. package/dist/tools/generate-tests/generators/supply-chain-test-generator.js +2 -3
  588. package/dist/tools/generate-tests/generators/visual-regression-generator.js +14 -17
  589. package/dist/tools/generate-tests/generators/websocket-test-generator.js +2 -3
  590. package/dist/tools/generate-tests/test-helpers.js +11 -12
  591. package/dist/tools/generate-tests-content.js +4 -3
  592. package/dist/tools/generate-tests.js +7 -4
  593. package/dist/tools/git/git-helpers.d.ts +0 -2
  594. package/dist/tools/git/git-helpers.js +7 -7
  595. package/dist/tools/github-pr-handler.js +10 -3
  596. package/dist/tools/heal-spec-docs.js +6 -53
  597. package/dist/tools/hook-generator-handler.js +6 -6
  598. package/dist/tools/init-constitution/platform-principles.js +4 -2
  599. package/dist/tools/init-project/agents-md-writer.js +14 -5
  600. package/dist/tools/init-project/claude-md-generator.js +19 -12
  601. package/dist/tools/init-project/handler.js +165 -73
  602. package/dist/tools/init-project/host-assets-writer.d.ts +1 -1
  603. package/dist/tools/init-project/host-assets-writer.js +4 -2
  604. package/dist/tools/init-project/lifecycle-helpers.js +3 -5
  605. package/dist/tools/init-project/lint-scaffolder.js +6 -2
  606. package/dist/tools/init-project/migration-runner.d.ts +10 -1
  607. package/dist/tools/init-project/migration-runner.js +68 -3
  608. package/dist/tools/init-project/per-client-files-writer.js +14 -4
  609. package/dist/tools/init-project/rules-generator.js +10 -2
  610. package/dist/tools/init-project/scaffold-writer.d.ts +1 -1
  611. package/dist/tools/init-project/scaffold-writer.js +17 -15
  612. package/dist/tools/jobs/handlers.d.ts +15 -0
  613. package/dist/tools/jobs/handlers.js +126 -0
  614. package/dist/tools/list-specs.js +35 -34
  615. package/dist/tools/manage-plugins-handler.js +17 -9
  616. package/dist/tools/migrate-tech/advanced-handlers.js +3 -2
  617. package/dist/tools/migrate-tech/build-tool-handlers.js +3 -2
  618. package/dist/tools/migrate-tech/core-handlers.js +5 -2
  619. package/dist/tools/migrate-tech/data-handlers.js +6 -3
  620. package/dist/tools/migrate-tech-advanced/rollback-handlers.js +3 -2
  621. package/dist/tools/migrate-tech-advanced/service-handlers.js +5 -2
  622. package/dist/tools/oauth-handler.js +7 -1
  623. package/dist/tools/register-sdd-tools.d.ts +1 -1
  624. package/dist/tools/register-sdd-tools.js +5 -0
  625. package/dist/tools/register-spec-tools/core-spec-tools.js +31 -0
  626. package/dist/tools/registry/auth.js +13 -5
  627. package/dist/tools/registry/publish.js +7 -4
  628. package/dist/tools/resolve-project-path.d.ts +2 -2
  629. package/dist/tools/resolve-project-path.js +7 -7
  630. package/dist/tools/reverse-engineer/analyzer.js +14 -14
  631. package/dist/tools/rollback-release.js +3 -2
  632. package/dist/tools/safe-handler.js +295 -171
  633. package/dist/tools/schema-generator-handler.js +2 -1
  634. package/dist/tools/schemas/output-schemas.d.ts +88 -82
  635. package/dist/tools/schemas/output-schemas.js +12 -94
  636. package/dist/tools/schemas/plugins-schemas.js +0 -2
  637. package/dist/tools/schemas/registry.js +0 -2
  638. package/dist/tools/schemas/skill-registry-schemas.js +0 -2
  639. package/dist/tools/schemas/validate-output-schema.d.ts +256 -0
  640. package/dist/tools/schemas/validate-output-schema.js +212 -0
  641. package/dist/tools/sentry-handler.js +6 -1
  642. package/dist/tools/skill-bootstrap-handler.js +7 -4
  643. package/dist/tools/status-handler.js +4 -0
  644. package/dist/tools/storage-bundle-handler.d.ts +9 -0
  645. package/dist/tools/storage-bundle-handler.js +29 -0
  646. package/dist/tools/storage-paths-handler.d.ts +9 -0
  647. package/dist/tools/storage-paths-handler.js +17 -0
  648. package/dist/tools/suggest-mcp-server.js +11 -5
  649. package/dist/tools/suggest-mcps.js +29 -9
  650. package/dist/tools/suggest-tooling/advanced-testing-catalog.js +4 -5
  651. package/dist/tools/suggest-tooling/build-tool-catalog.js +2 -1
  652. package/dist/tools/suggest-tooling/css-framework-catalog.js +13 -7
  653. package/dist/tools/suggest-tooling/framework-catalog.js +3 -5
  654. package/dist/tools/suggest-tooling/frontend-perf-catalog.js +2 -6
  655. package/dist/tools/suggest-tooling/handler.js +10 -4
  656. package/dist/tools/suggest-tooling/hypermedia-catalog.js +11 -3
  657. package/dist/tools/suggest-tooling/linting-catalog.js +4 -7
  658. package/dist/tools/suggest-tooling/llm-security-catalog.js +2 -1
  659. package/dist/tools/suggest-tooling/local-first-catalog.js +7 -5
  660. package/dist/tools/suggest-tooling/observability-catalog.js +3 -4
  661. package/dist/tools/suggest-tooling/otel-catalog.js +4 -1
  662. package/dist/tools/suggest-tooling/resilience-catalog.js +16 -5
  663. package/dist/tools/suggest-tooling/skills-catalog.js +10 -9
  664. package/dist/tools/suggest-tooling/supply-chain-catalog.js +2 -3
  665. package/dist/tools/supabase-handler.js +2 -1
  666. package/dist/tools/token-intelligence-handler.js +2 -2
  667. package/dist/tools/token-recording.js +2 -2
  668. package/dist/tools/token-savings-handler.js +2 -2
  669. package/dist/tools/tool-registry/core-tools.js +131 -0
  670. package/dist/tools/tool-registry/group-infra.js +10 -12
  671. package/dist/tools/tool-registry/group-quality-compliance.js +5 -12
  672. package/dist/tools/update-status/approval-gates.d.ts +13 -0
  673. package/dist/tools/update-status/approval-gates.js +81 -0
  674. package/dist/tools/update-status/batch.js +4 -2
  675. package/dist/tools/update-status/dod-gates.d.ts +6 -24
  676. package/dist/tools/update-status/dod-gates.js +60 -135
  677. package/dist/tools/update-status/done-receipt-verifier.d.ts +15 -0
  678. package/dist/tools/update-status/done-receipt-verifier.js +145 -0
  679. package/dist/tools/update-status/evidence-gate.js +154 -2
  680. package/dist/tools/update-status/file-sync.js +23 -12
  681. package/dist/tools/update-status/gate-harness.d.ts +7 -0
  682. package/dist/tools/update-status/gate-harness.js +8 -0
  683. package/dist/tools/update-status/index.js +228 -325
  684. package/dist/tools/update-status/qa-gate.d.ts +1 -1
  685. package/dist/tools/update-status/qa-gate.js +2 -2
  686. package/dist/tools/update-status/side-effects.js +30 -37
  687. package/dist/tools/update-status/transition-guard.d.ts +4 -2
  688. package/dist/tools/update-status/transition-guard.js +57 -10
  689. package/dist/tools/update-status-convention-gate.js +24 -23
  690. package/dist/tools/update-status-reconcile.js +2 -2
  691. package/dist/tools/validate-api-contract-handler.js +3 -3
  692. package/dist/tools/validate-lint.js +20 -13
  693. package/dist/tools/validate.d.ts +3 -1
  694. package/dist/tools/validate.js +213 -5
  695. package/dist/transports/http-transport.js +84 -61
  696. package/dist/transports/middleware/with-telemetry.js +3 -2
  697. package/dist/types/abortable-process.d.ts +2 -0
  698. package/dist/types/advanced-framework.js +0 -2
  699. package/dist/types/atomic-upgrade.d.ts +71 -0
  700. package/dist/types/atomic-upgrade.js +2 -0
  701. package/dist/types/ci.js +0 -2
  702. package/dist/types/core-bridge.d.ts +78 -1
  703. package/dist/types/crash-shield-framework-rules.d.ts +24 -0
  704. package/dist/types/crash-shield-framework-rules.js +2 -0
  705. package/dist/types/data-gc.d.ts +16 -0
  706. package/dist/types/deploy.js +0 -2
  707. package/dist/types/durable-job.d.ts +78 -0
  708. package/dist/types/durable-job.js +2 -0
  709. package/dist/types/durable-validation.d.ts +60 -0
  710. package/dist/types/durable-validation.js +2 -0
  711. package/dist/types/estimation.d.ts +2 -0
  712. package/dist/types/evidence-gates.d.ts +9 -1
  713. package/dist/types/execution.d.ts +43 -0
  714. package/dist/types/handoff-artifacts.d.ts +2 -0
  715. package/dist/types/index.d.ts +2 -0
  716. package/dist/types/index.js +2 -0
  717. package/dist/types/infrastructure.js +0 -2
  718. package/dist/types/lifecycle.js +0 -2
  719. package/dist/types/migration/canonical-storage.d.ts +37 -0
  720. package/dist/types/migration/canonical-storage.js +2 -0
  721. package/dist/types/migration/index.d.ts +1 -1
  722. package/dist/types/native-worker.d.ts +48 -0
  723. package/dist/types/native-worker.js +2 -0
  724. package/dist/types/network-policy.d.ts +12 -0
  725. package/dist/types/network-policy.js +2 -0
  726. package/dist/types/oauth.js +0 -2
  727. package/dist/types/observability.d.ts +32 -0
  728. package/dist/types/outbox-worker.d.ts +35 -0
  729. package/dist/types/outbox-worker.js +11 -0
  730. package/dist/types/permissions-config.d.ts +0 -27
  731. package/dist/types/permissions-config.js +0 -2
  732. package/dist/types/plugin-install.d.ts +0 -11
  733. package/dist/types/plugin-install.js +0 -2
  734. package/dist/types/portal.d.ts +1 -0
  735. package/dist/types/product-public.d.ts +75 -0
  736. package/dist/types/product-public.js +2 -0
  737. package/dist/types/project/inputs.d.ts +2 -0
  738. package/dist/types/project/mfe-detection.js +0 -2
  739. package/dist/types/project/platform-mobile.js +0 -2
  740. package/dist/types/project/platform-specialty.js +0 -2
  741. package/dist/types/project-knowledge-graph.d.ts +7 -0
  742. package/dist/types/runtime-database.d.ts +10 -0
  743. package/dist/types/runtime-database.js +2 -0
  744. package/dist/types/runtime-policy.d.ts +40 -0
  745. package/dist/types/runtime-policy.js +2 -0
  746. package/dist/types/safety.d.ts +4 -5
  747. package/dist/types/schema-registry.d.ts +12 -0
  748. package/dist/types/schema-registry.js +2 -0
  749. package/dist/types/security.d.ts +52 -0
  750. package/dist/types/skill-registry.js +0 -2
  751. package/dist/types/spec/inputs.d.ts +2 -0
  752. package/dist/types/spec-lock-v2.d.ts +13 -7
  753. package/dist/types/spec-lock-v2.js +1 -1
  754. package/dist/types/spec-registry.js +0 -2
  755. package/dist/types/storage-bundle.d.ts +13 -0
  756. package/dist/types/storage-bundle.js +2 -0
  757. package/dist/types/storage-catalog.d.ts +18 -0
  758. package/dist/types/storage-catalog.js +2 -0
  759. package/dist/types/team-planner.js +0 -2
  760. package/dist/types/technology-registry.d.ts +35 -0
  761. package/dist/types/technology-registry.js +2 -0
  762. package/dist/types/technology-symbols.generated.d.ts +117 -0
  763. package/dist/types/technology-symbols.generated.js +2 -0
  764. package/dist/types/telemetry.d.ts +3 -3
  765. package/dist/types/transport.d.ts +2 -0
  766. package/dist/types/validate-worker.d.ts +44 -0
  767. package/dist/types/validate-worker.js +2 -0
  768. package/dist/types/validation-evidence.d.ts +1 -1
  769. package/dist/types/validation-receipt.d.ts +104 -0
  770. package/dist/types/validation-receipt.js +2 -0
  771. package/package.json +31 -20
  772. package/planu-native.json +1 -1
  773. package/planu-plugin.json +1 -1
  774. package/dist/engine/telemetry/geo-resolver.d.ts +0 -9
  775. package/dist/engine/telemetry/geo-resolver.js +0 -43
  776. package/dist/storage/data-dir-discovery.d.ts +0 -31
  777. package/dist/storage/data-dir-discovery.js +0 -140
  778. package/dist/storage/migrations/cwd-to-absolute.d.ts +0 -25
  779. package/dist/storage/migrations/cwd-to-absolute.js +0 -281
  780. package/dist/tools/create-spec/adapters/prior-decisions-hint.d.ts +0 -14
  781. package/dist/tools/create-spec/adapters/prior-decisions-hint.js +0 -30
  782. package/dist/tools/init-project/ancestor-data-detector.d.ts +0 -22
  783. package/dist/tools/init-project/ancestor-data-detector.js +0 -81
  784. package/dist/tools/update-status/force-done-audit.d.ts +0 -2
  785. package/dist/tools/update-status/force-done-audit.js +0 -23
  786. package/dist/types/migration/cwd-to-absolute.d.ts +0 -8
  787. package/dist/types/migration/cwd-to-absolute.js +0 -3
@@ -0,0 +1,599 @@
1
+ /* eslint-disable no-restricted-syntax, no-param-reassign, complexity, max-lines, max-lines-per-function -- journaled migration keeps its state machine and private contract together for auditability */
2
+ import { copyFile, lstat, mkdir, readFile, readdir, rename, rm, writeFile } from 'node:fs/promises';
3
+ import { createHash, randomUUID } from 'node:crypto';
4
+ import { homedir, tmpdir } from 'node:os';
5
+ import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from 'node:path';
6
+ import { acquireLock as acquireFileMutex, releaseLock as releaseFileMutex, } from '../../engine/safety/file-mutex.js';
7
+ import { assertNoObsoleteFileLock } from '../../engine/safety/obsolete-lock-guard.js';
8
+ function sha256(value) {
9
+ return createHash('sha256').update(value).digest('hex');
10
+ }
11
+ function assertAbsolute(path, label) {
12
+ if (!path.trim() || !isAbsolute(path)) {
13
+ throw new Error(`[Planu] ${label} must be absolute`);
14
+ }
15
+ return resolve(path);
16
+ }
17
+ function assertNarrowLegacyRoot(path) {
18
+ const root = parse(path).root;
19
+ const segments = relative(root, path).split(sep).filter(Boolean);
20
+ const protectedRoots = new Set([resolve(homedir()), resolve(tmpdir()), resolve(process.cwd())]);
21
+ if (path === root || segments.length < 2 || protectedRoots.has(path)) {
22
+ throw new Error(`[Planu] Legacy root is too broad for safe migration: ${path}`);
23
+ }
24
+ }
25
+ function isInside(parent, child) {
26
+ const rel = relative(parent, child);
27
+ return rel === '' || (!rel.startsWith(`..${sep}`) && rel !== '..' && !isAbsolute(rel));
28
+ }
29
+ async function exists(path) {
30
+ try {
31
+ await lstat(path);
32
+ return true;
33
+ }
34
+ catch (error) {
35
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
36
+ return false;
37
+ }
38
+ throw error;
39
+ }
40
+ }
41
+ async function listFiles(root, current = root) {
42
+ const entries = await readdir(current, { withFileTypes: true });
43
+ const files = [];
44
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
45
+ const path = join(current, entry.name);
46
+ if (entry.isSymbolicLink()) {
47
+ throw new Error(`[Planu] Migration refuses symlink: ${path}`);
48
+ }
49
+ if (entry.isDirectory()) {
50
+ files.push(...(await listFiles(root, path)));
51
+ }
52
+ else if (entry.isFile()) {
53
+ files.push(path);
54
+ }
55
+ else {
56
+ throw new Error(`[Planu] Migration refuses non-regular file: ${path}`);
57
+ }
58
+ }
59
+ return files;
60
+ }
61
+ export async function inventoryStorageRoot(rootInput) {
62
+ const root = assertAbsolute(rootInput, 'inventory root');
63
+ const info = await lstat(root);
64
+ if (info.isSymbolicLink() || !info.isDirectory()) {
65
+ throw new Error(`[Planu] Migration root must be a real directory: ${root}`);
66
+ }
67
+ const files = [];
68
+ let totalBytes = 0;
69
+ for (const path of await listFiles(root)) {
70
+ const content = await readFile(path);
71
+ const relativePath = relative(root, path).split(sep).join('/');
72
+ files.push({ relativePath, size: content.byteLength, sha256: sha256(content) });
73
+ totalBytes += content.byteLength;
74
+ }
75
+ const digest = sha256(files.map((file) => `${file.relativePath}\0${file.size}\0${file.sha256}\n`).join(''));
76
+ return { root, files, totalBytes, digest };
77
+ }
78
+ function migrationPaths(destinationRoot) {
79
+ const prefix = join(dirname(destinationRoot), `.${basename(destinationRoot)}.canonical-migration`);
80
+ return {
81
+ journalPath: `${prefix}.journal.json`,
82
+ stagingRoot: `${prefix}.staging`,
83
+ backupRoot: `${prefix}.backup`,
84
+ lockPath: `${prefix}.lock`,
85
+ };
86
+ }
87
+ async function writeJournal(path, journal) {
88
+ journal.updatedAt = new Date().toISOString();
89
+ await mkdir(dirname(path), { recursive: true });
90
+ const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`;
91
+ try {
92
+ await writeFile(temporary, `${JSON.stringify(journal, null, 2)}\n`, { mode: 0o600 });
93
+ await rename(temporary, path);
94
+ }
95
+ catch (error) {
96
+ await rm(temporary, { force: true });
97
+ throw error;
98
+ }
99
+ }
100
+ function isSafeInventory(value, expectedRoot) {
101
+ if (!value || typeof value !== 'object') {
102
+ return false;
103
+ }
104
+ const inventory = value;
105
+ const files = inventory.files;
106
+ return (inventory.root === expectedRoot &&
107
+ typeof inventory.digest === 'string' &&
108
+ /^[a-f0-9]{64}$/.test(inventory.digest) &&
109
+ Number.isSafeInteger(inventory.totalBytes) &&
110
+ (inventory.totalBytes ?? -1) >= 0 &&
111
+ Array.isArray(files) &&
112
+ files.every((file) => {
113
+ if (!file || typeof file !== 'object') {
114
+ return false;
115
+ }
116
+ const entry = file;
117
+ return (typeof entry.relativePath === 'string' &&
118
+ entry.relativePath.length > 0 &&
119
+ !entry.relativePath.startsWith('/') &&
120
+ !entry.relativePath.split('/').includes('..') &&
121
+ Number.isSafeInteger(entry.size) &&
122
+ entry.size >= 0 &&
123
+ typeof entry.sha256 === 'string' &&
124
+ /^[a-f0-9]{64}$/.test(entry.sha256));
125
+ }));
126
+ }
127
+ function validateJournal(value, expected) {
128
+ if (!value || typeof value !== 'object') {
129
+ throw new Error('[Planu] Invalid migration journal structure');
130
+ }
131
+ const journal = value;
132
+ const phases = [
133
+ 'prepared',
134
+ 'switched',
135
+ 'verified',
136
+ 'completed',
137
+ 'rolled-back',
138
+ ];
139
+ const validSources = Array.isArray(journal.sourceInventories) &&
140
+ journal.sourceInventories.length <= expected.legacyRoots.length &&
141
+ journal.sourceInventories.every((inventory) => {
142
+ if (!inventory || typeof inventory !== 'object') {
143
+ return false;
144
+ }
145
+ const rootValue = inventory.root;
146
+ const sourceRoot = expected.legacyRoots.find((root) => root === rootValue);
147
+ return sourceRoot !== undefined && isSafeInventory(inventory, sourceRoot);
148
+ });
149
+ if (journal.schemaVersion !== 1 ||
150
+ journal.destinationRoot !== expected.destinationRoot ||
151
+ journal.stagingRoot !== expected.stagingRoot ||
152
+ journal.backupRoot !== expected.backupRoot ||
153
+ JSON.stringify(journal.legacyRoots) !== JSON.stringify(expected.legacyRoots) ||
154
+ !journal.phase ||
155
+ !phases.includes(journal.phase) ||
156
+ typeof journal.destinationExisted !== 'boolean' ||
157
+ typeof journal.updatedAt !== 'string' ||
158
+ !Array.isArray(journal.collisions) ||
159
+ !validSources ||
160
+ !isSafeInventory(journal.expectedInventory, expected.stagingRoot)) {
161
+ throw new Error('[Planu] Invalid or unsafe migration journal');
162
+ }
163
+ return journal;
164
+ }
165
+ async function readJournal(path, expected) {
166
+ try {
167
+ const parsed = JSON.parse(await readFile(path, 'utf8'));
168
+ return validateJournal(parsed, expected);
169
+ }
170
+ catch (error) {
171
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
172
+ return null;
173
+ }
174
+ throw error;
175
+ }
176
+ }
177
+ async function retireCompletedJournalForNewSources(journalPath, expected) {
178
+ let parsed;
179
+ try {
180
+ parsed = JSON.parse(await readFile(journalPath, 'utf8'));
181
+ }
182
+ catch (error) {
183
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
184
+ return;
185
+ }
186
+ throw error;
187
+ }
188
+ if (!parsed || typeof parsed !== 'object' || !('legacyRoots' in parsed)) {
189
+ throw new Error('[Planu] Invalid or unsafe migration journal');
190
+ }
191
+ const rawRoots = parsed.legacyRoots;
192
+ if (!Array.isArray(rawRoots) || !rawRoots.every((root) => typeof root === 'string')) {
193
+ throw new Error('[Planu] Invalid or unsafe migration journal');
194
+ }
195
+ if (JSON.stringify(rawRoots) === JSON.stringify(expected.legacyRoots)) {
196
+ return;
197
+ }
198
+ const previousRoots = rawRoots.map((root) => assertAbsolute(root, 'journal legacyRoot'));
199
+ for (const root of previousRoots) {
200
+ assertNarrowLegacyRoot(root);
201
+ if (isInside(root, expected.destinationRoot) || isInside(expected.destinationRoot, root)) {
202
+ throw new Error('[Planu] Invalid or unsafe migration journal');
203
+ }
204
+ }
205
+ const previous = validateJournal(parsed, { ...expected, legacyRoots: previousRoots });
206
+ if (previous.phase !== 'completed') {
207
+ throw new Error('[Planu] Active migration journal does not match requested roots');
208
+ }
209
+ // A completed destination remains live and may legitimately receive newer
210
+ // canonical records. Re-inventory its real directory instead of requiring
211
+ // the historical generation digest to remain frozen forever.
212
+ await inventoryStorageRoot(expected.destinationRoot);
213
+ await rm(journalPath, { force: true });
214
+ }
215
+ function recordTimestamp(value) {
216
+ if (!value || typeof value !== 'object') {
217
+ return 0;
218
+ }
219
+ const record = value;
220
+ for (const field of ['updatedAt', 'lastAnalyzed', 'modifiedAt', 'createdAt']) {
221
+ if (typeof record[field] === 'string') {
222
+ const parsed = Date.parse(record[field]);
223
+ if (Number.isFinite(parsed)) {
224
+ return parsed;
225
+ }
226
+ }
227
+ }
228
+ return 0;
229
+ }
230
+ function mergeKnowledge(source, destination) {
231
+ if (!source || typeof source !== 'object' || Array.isArray(source)) {
232
+ throw new Error('[Planu] Invalid legacy knowledge.json');
233
+ }
234
+ if (!destination || typeof destination !== 'object' || Array.isArray(destination)) {
235
+ throw new Error('[Planu] Invalid destination knowledge.json');
236
+ }
237
+ const sourceRecord = source;
238
+ const destinationRecord = destination;
239
+ if (recordTimestamp(source) > recordTimestamp(destination)) {
240
+ return { value: { ...destinationRecord, ...sourceRecord }, resolution: 'source-newer' };
241
+ }
242
+ return { value: { ...sourceRecord, ...destinationRecord }, resolution: 'destination-newer' };
243
+ }
244
+ function specKey(value, index) {
245
+ if (value && typeof value === 'object') {
246
+ const record = value;
247
+ if (typeof record.uuid === 'string' && record.uuid) {
248
+ return `uuid:${record.uuid}`;
249
+ }
250
+ if (typeof record.id === 'string' && record.id) {
251
+ return `id:${record.id}`;
252
+ }
253
+ }
254
+ return `anonymous:${index}`;
255
+ }
256
+ function mergeSpecs(source, destination) {
257
+ if (!Array.isArray(source) || !Array.isArray(destination)) {
258
+ throw new Error('[Planu] specs.json must contain arrays');
259
+ }
260
+ const merged = new Map();
261
+ destination.forEach((record, index) => merged.set(specKey(record, index), record));
262
+ let sourceWon = false;
263
+ for (const [index, record] of source.entries()) {
264
+ const key = specKey(record, index);
265
+ const current = merged.get(key);
266
+ if (current === undefined) {
267
+ merged.set(key, record);
268
+ continue;
269
+ }
270
+ if (recordTimestamp(record) > recordTimestamp(current)) {
271
+ merged.set(key, record);
272
+ sourceWon = true;
273
+ }
274
+ }
275
+ return {
276
+ value: [...merged.values()],
277
+ resolution: sourceWon ? 'source-newer' : 'destination-newer',
278
+ };
279
+ }
280
+ async function mergeFile(sourceRoot, sourceDigest, stagingRoot, destinationRoot, file, collisions) {
281
+ const sourcePath = join(sourceRoot, ...file.relativePath.split('/'));
282
+ const stagingPath = join(stagingRoot, ...file.relativePath.split('/'));
283
+ const destinationPath = join(destinationRoot, ...file.relativePath.split('/'));
284
+ const current = await readFile(sourcePath);
285
+ if (sha256(current) !== file.sha256) {
286
+ throw new Error(`[Planu] Legacy source changed during migration: ${sourcePath}`);
287
+ }
288
+ await mkdir(dirname(stagingPath), { recursive: true });
289
+ if (!(await exists(stagingPath))) {
290
+ await copyFile(sourcePath, stagingPath);
291
+ return;
292
+ }
293
+ const staged = await readFile(stagingPath);
294
+ if (sha256(staged) === file.sha256) {
295
+ return;
296
+ }
297
+ let resolution;
298
+ let archivedPath;
299
+ if (file.relativePath === 'knowledge.json' || file.relativePath === 'specs.json') {
300
+ const sourceJson = JSON.parse(current.toString('utf8'));
301
+ const destinationJson = JSON.parse(await readFile(stagingPath, 'utf8'));
302
+ const merged = file.relativePath === 'knowledge.json'
303
+ ? mergeKnowledge(sourceJson, destinationJson)
304
+ : mergeSpecs(sourceJson, destinationJson);
305
+ await writeFile(stagingPath, `${JSON.stringify(merged.value, null, 2)}\n`, { mode: 0o600 });
306
+ resolution = merged.resolution;
307
+ }
308
+ else {
309
+ archivedPath = join(destinationRoot, 'migration-conflicts', sourceDigest, ...file.relativePath.split('/'));
310
+ const stagedArchivePath = join(stagingRoot, 'migration-conflicts', sourceDigest, ...file.relativePath.split('/'));
311
+ if (await exists(stagedArchivePath)) {
312
+ const archived = await readFile(stagedArchivePath);
313
+ if (sha256(archived) !== file.sha256) {
314
+ throw new Error(`[Planu] Migration conflict archive collision: ${stagedArchivePath}`);
315
+ }
316
+ }
317
+ else {
318
+ await mkdir(dirname(stagedArchivePath), { recursive: true });
319
+ await copyFile(sourcePath, stagedArchivePath);
320
+ const archived = await readFile(stagedArchivePath);
321
+ if (sha256(archived) !== file.sha256) {
322
+ throw new Error(`[Planu] Migration conflict archive verification failed: ${stagedArchivePath}`);
323
+ }
324
+ }
325
+ resolution = 'source-archived';
326
+ }
327
+ const collision = {
328
+ relativePath: file.relativePath,
329
+ sourcePath,
330
+ destinationPath,
331
+ ...(archivedPath ? { archivedPath } : {}),
332
+ resolution,
333
+ };
334
+ collisions.push(collision);
335
+ }
336
+ async function planCollisions(sourceInventories, destination, destinationRoot) {
337
+ const state = new Map((destination?.files ?? []).map((file) => [file.relativePath, { sha256: file.sha256 }]));
338
+ const collisions = [];
339
+ for (const inventory of sourceInventories) {
340
+ for (const file of inventory.files) {
341
+ const sourcePath = join(inventory.root, ...file.relativePath.split('/'));
342
+ const current = state.get(file.relativePath);
343
+ const schemaFile = file.relativePath === 'knowledge.json' || file.relativePath === 'specs.json';
344
+ if (!current) {
345
+ state.set(file.relativePath, {
346
+ sha256: file.sha256,
347
+ ...(schemaFile
348
+ ? { value: JSON.parse(await readFile(sourcePath, 'utf8')) }
349
+ : {}),
350
+ });
351
+ continue;
352
+ }
353
+ if (current.sha256 === file.sha256) {
354
+ continue;
355
+ }
356
+ let resolution;
357
+ let archivedPath;
358
+ if (schemaFile) {
359
+ const source = JSON.parse(await readFile(sourcePath, 'utf8'));
360
+ const target = current.value ??
361
+ JSON.parse(await readFile(join(destinationRoot, ...file.relativePath.split('/')), 'utf8'));
362
+ const merged = file.relativePath === 'knowledge.json'
363
+ ? mergeKnowledge(source, target)
364
+ : mergeSpecs(source, target);
365
+ resolution = merged.resolution;
366
+ state.set(file.relativePath, {
367
+ sha256: sha256(JSON.stringify(merged.value)),
368
+ value: merged.value,
369
+ });
370
+ }
371
+ else {
372
+ resolution = 'source-archived';
373
+ archivedPath = join(destinationRoot, 'migration-conflicts', inventory.digest, ...file.relativePath.split('/'));
374
+ }
375
+ collisions.push({
376
+ relativePath: file.relativePath,
377
+ sourcePath,
378
+ destinationPath: join(destinationRoot, ...file.relativePath.split('/')),
379
+ ...(archivedPath ? { archivedPath } : {}),
380
+ resolution,
381
+ });
382
+ }
383
+ }
384
+ return collisions;
385
+ }
386
+ async function prepare(journal) {
387
+ await rm(journal.stagingRoot, { recursive: true, force: true });
388
+ if (journal.destinationExisted) {
389
+ await mkdir(journal.stagingRoot, { recursive: true });
390
+ for (const file of (await inventoryStorageRoot(journal.destinationRoot)).files) {
391
+ const source = join(journal.destinationRoot, ...file.relativePath.split('/'));
392
+ const target = join(journal.stagingRoot, ...file.relativePath.split('/'));
393
+ await mkdir(dirname(target), { recursive: true });
394
+ await copyFile(source, target);
395
+ }
396
+ }
397
+ else {
398
+ await mkdir(journal.stagingRoot, { recursive: true });
399
+ }
400
+ journal.collisions = [];
401
+ for (const inventory of journal.sourceInventories) {
402
+ for (const file of inventory.files) {
403
+ await mergeFile(inventory.root, inventory.digest, journal.stagingRoot, journal.destinationRoot, file, journal.collisions);
404
+ }
405
+ }
406
+ journal.expectedInventory = await inventoryStorageRoot(journal.stagingRoot);
407
+ }
408
+ async function switchDestination(journal) {
409
+ if (await exists(journal.destinationRoot)) {
410
+ if (await exists(journal.backupRoot)) {
411
+ throw new Error('[Planu] Migration found both destination and rollback backup');
412
+ }
413
+ await rename(journal.destinationRoot, journal.backupRoot);
414
+ }
415
+ await rename(journal.stagingRoot, journal.destinationRoot);
416
+ }
417
+ async function rollbackSwitch(journal) {
418
+ await rm(journal.stagingRoot, { recursive: true, force: true });
419
+ if (await exists(journal.backupRoot)) {
420
+ await rm(journal.destinationRoot, { recursive: true, force: true });
421
+ await rename(journal.backupRoot, journal.destinationRoot);
422
+ }
423
+ else if (!journal.destinationExisted) {
424
+ await rm(journal.destinationRoot, { recursive: true, force: true });
425
+ }
426
+ journal.phase = 'rolled-back';
427
+ }
428
+ async function verifyDestination(journal) {
429
+ const actual = await inventoryStorageRoot(journal.destinationRoot);
430
+ if (actual.digest !== journal.expectedInventory.digest) {
431
+ throw new Error('[Planu] Canonical destination checksum verification failed');
432
+ }
433
+ return actual;
434
+ }
435
+ async function acquireMigrationLock(path) {
436
+ try {
437
+ await assertNoObsoleteFileLock(path, 'canonical storage migration');
438
+ const handle = await acquireFileMutex(path, 1);
439
+ return () => releaseFileMutex(handle);
440
+ }
441
+ catch (error) {
442
+ if (error instanceof Error && 'code' in error && error.code === 'LOCK_TIMEOUT') {
443
+ throw new Error(`[Planu] Canonical migration is already running: ${path}`, { cause: error });
444
+ }
445
+ throw error;
446
+ }
447
+ }
448
+ function result(status, journal, journalPath, resumed, destinationInventory, reason) {
449
+ return {
450
+ status,
451
+ destinationRoot: journal.destinationRoot,
452
+ journalPath,
453
+ sourceInventories: journal.sourceInventories,
454
+ destinationInventory,
455
+ collisions: journal.collisions,
456
+ resumed,
457
+ ...(reason ? { reason } : {}),
458
+ };
459
+ }
460
+ /** Migrate explicit legacy roots into one canonical absolute directory. */
461
+ export async function migrateCanonicalStorage(input) {
462
+ const destinationRoot = assertAbsolute(input.destinationRoot, 'destinationRoot');
463
+ const legacyRoots = [
464
+ ...new Set(input.legacyRoots.map((path) => assertAbsolute(path, 'legacyRoot'))),
465
+ ];
466
+ for (const source of legacyRoots) {
467
+ assertNarrowLegacyRoot(source);
468
+ if (isInside(source, destinationRoot) || isInside(destinationRoot, source)) {
469
+ throw new Error('[Planu] Legacy and destination roots must not overlap');
470
+ }
471
+ }
472
+ const paths = migrationPaths(destinationRoot);
473
+ const existingRoots = [];
474
+ for (const source of legacyRoots) {
475
+ if (await exists(source)) {
476
+ existingRoots.push(source);
477
+ }
478
+ }
479
+ const sourceInventories = await Promise.all(existingRoots.map(inventoryStorageRoot));
480
+ const destinationInventory = (await exists(destinationRoot))
481
+ ? await inventoryStorageRoot(destinationRoot)
482
+ : null;
483
+ const emptyJournal = {
484
+ schemaVersion: 1,
485
+ destinationRoot,
486
+ legacyRoots,
487
+ phase: 'prepared',
488
+ stagingRoot: paths.stagingRoot,
489
+ backupRoot: paths.backupRoot,
490
+ sourceInventories,
491
+ expectedInventory: destinationInventory ?? {
492
+ root: paths.stagingRoot,
493
+ files: [],
494
+ totalBytes: 0,
495
+ digest: sha256(''),
496
+ },
497
+ collisions: [],
498
+ destinationExisted: destinationInventory !== null,
499
+ updatedAt: new Date().toISOString(),
500
+ };
501
+ if (input.dryRun) {
502
+ if (sourceInventories.length === 0) {
503
+ return result('noop', emptyJournal, paths.journalPath, false, destinationInventory);
504
+ }
505
+ emptyJournal.collisions = await planCollisions(sourceInventories, destinationInventory, destinationRoot);
506
+ return result('planned', emptyJournal, paths.journalPath, false, destinationInventory);
507
+ }
508
+ const release = await acquireMigrationLock(paths.lockPath);
509
+ let journal = emptyJournal;
510
+ let resumed = false;
511
+ let journalLoaded = false;
512
+ try {
513
+ await retireCompletedJournalForNewSources(paths.journalPath, {
514
+ destinationRoot,
515
+ legacyRoots,
516
+ stagingRoot: paths.stagingRoot,
517
+ backupRoot: paths.backupRoot,
518
+ });
519
+ const existingJournal = await readJournal(paths.journalPath, {
520
+ destinationRoot,
521
+ legacyRoots,
522
+ stagingRoot: paths.stagingRoot,
523
+ backupRoot: paths.backupRoot,
524
+ });
525
+ journal = existingJournal ?? emptyJournal;
526
+ resumed = existingJournal !== null;
527
+ journalLoaded = true;
528
+ if (!existingJournal && sourceInventories.length === 0) {
529
+ return result('noop', emptyJournal, paths.journalPath, false, destinationInventory);
530
+ }
531
+ if (journal.destinationRoot !== destinationRoot ||
532
+ JSON.stringify(journal.legacyRoots) !== JSON.stringify(legacyRoots)) {
533
+ throw new Error('[Planu] Existing migration journal does not match requested roots');
534
+ }
535
+ if (journal.phase === 'completed') {
536
+ const verified = await verifyDestination(journal);
537
+ return result('noop', journal, paths.journalPath, true, verified);
538
+ }
539
+ if (journal.phase === 'rolled-back') {
540
+ journal = emptyJournal;
541
+ }
542
+ if (journal.phase === 'prepared') {
543
+ const stagingExists = await exists(journal.stagingRoot);
544
+ if (resumed && !stagingExists && (await exists(journal.destinationRoot))) {
545
+ const possibleSwitched = await inventoryStorageRoot(journal.destinationRoot);
546
+ if (possibleSwitched.digest === journal.expectedInventory.digest) {
547
+ journal.phase = 'switched';
548
+ await writeJournal(paths.journalPath, journal);
549
+ }
550
+ else {
551
+ await prepare(journal);
552
+ await writeJournal(paths.journalPath, journal);
553
+ }
554
+ }
555
+ else if (!stagingExists) {
556
+ await prepare(journal);
557
+ await writeJournal(paths.journalPath, journal);
558
+ }
559
+ else {
560
+ const staged = await inventoryStorageRoot(journal.stagingRoot);
561
+ if (staged.digest !== journal.expectedInventory.digest) {
562
+ await prepare(journal);
563
+ await writeJournal(paths.journalPath, journal);
564
+ }
565
+ }
566
+ if (journal.phase === 'prepared') {
567
+ await switchDestination(journal);
568
+ journal.phase = 'switched';
569
+ await writeJournal(paths.journalPath, journal);
570
+ }
571
+ }
572
+ const verified = await verifyDestination(journal);
573
+ journal.phase = 'verified';
574
+ await writeJournal(paths.journalPath, journal);
575
+ for (const source of journal.legacyRoots) {
576
+ await rm(source, { recursive: true, force: true });
577
+ }
578
+ await rm(journal.backupRoot, { recursive: true, force: true });
579
+ journal.phase = 'completed';
580
+ await writeJournal(paths.journalPath, journal);
581
+ return result(resumed ? 'resumed' : 'migrated', journal, paths.journalPath, resumed, verified);
582
+ }
583
+ catch (error) {
584
+ if (!journalLoaded) {
585
+ throw error;
586
+ }
587
+ if (journal.phase === 'prepared' || journal.phase === 'switched') {
588
+ await rollbackSwitch(journal);
589
+ await writeJournal(paths.journalPath, journal);
590
+ return result('rolled-back', journal, paths.journalPath, resumed, destinationInventory, error instanceof Error ? error.message : String(error));
591
+ }
592
+ return result('error', journal, paths.journalPath, resumed, null, error instanceof Error ? error.message : String(error));
593
+ }
594
+ finally {
595
+ await release();
596
+ }
597
+ }
598
+ export const CANONICAL_MIGRATION_INTERNALS = Object.freeze({ migrationPaths });
599
+ //# sourceMappingURL=canonical-storage.js.map
@@ -1,16 +1,29 @@
1
1
  // storage/oauth-store.ts — OAuth token persistence (SPEC-440)
2
2
  import { join } from 'node:path';
3
- import { hashProjectPath, readJson, writeJson } from './base-store.js';
3
+ import { hashProjectPath, projectDataDir, readJson } from './base-store.js';
4
+ import { deleteSecretField, resolveSecretField, storeSecretField, } from '../security/secret-field.js';
5
+ import { writeSecureJson } from '../security/secure-json.js';
6
+ function secretId(projectPath, integration, kind) {
7
+ return `${hashProjectPath(projectPath)}/oauth/${integration}/${kind}`;
8
+ }
9
+ async function resolveToken(token) {
10
+ return {
11
+ ...token,
12
+ accessToken: await resolveSecretField(token.accessToken),
13
+ ...(token.refreshToken ? { refreshToken: await resolveSecretField(token.refreshToken) } : {}),
14
+ };
15
+ }
4
16
  function tokensPath(projectPath) {
5
17
  const id = hashProjectPath(projectPath);
6
- return join('data', 'projects', id, 'oauth', 'tokens.json');
18
+ return join(projectDataDir(id), 'oauth', 'tokens.json');
7
19
  }
8
20
  /**
9
21
  * Retrieve the stored OAuth token for a specific integration, or null if not stored.
10
22
  */
11
23
  export async function getOAuthToken(projectPath, integration) {
12
24
  const tokens = await readJson(tokensPath(projectPath), []);
13
- return tokens.find((t) => t.integration === integration) ?? null;
25
+ const token = tokens.find((t) => t.integration === integration);
26
+ return token ? resolveToken(token) : null;
14
27
  }
15
28
  /**
16
29
  * Persist an OAuth token for a project, replacing any existing token for the same integration.
@@ -18,14 +31,23 @@ export async function getOAuthToken(projectPath, integration) {
18
31
  export async function saveOAuthToken(projectPath, token) {
19
32
  const path = tokensPath(projectPath);
20
33
  const tokens = await readJson(path, []);
34
+ const stored = {
35
+ ...token,
36
+ accessToken: await storeSecretField(secretId(projectPath, token.integration, 'access'), 'oauth-access', token.accessToken),
37
+ ...(token.refreshToken
38
+ ? {
39
+ refreshToken: await storeSecretField(secretId(projectPath, token.integration, 'refresh'), 'oauth-refresh', token.refreshToken),
40
+ }
41
+ : {}),
42
+ };
21
43
  const index = tokens.findIndex((t) => t.integration === token.integration);
22
44
  if (index >= 0) {
23
- tokens[index] = token;
45
+ tokens[index] = stored;
24
46
  }
25
47
  else {
26
- tokens.push(token);
48
+ tokens.push(stored);
27
49
  }
28
- await writeJson(path, tokens);
50
+ await writeSecureJson(path, tokens);
29
51
  }
30
52
  /**
31
53
  * Remove the stored OAuth token for a specific integration.
@@ -33,13 +55,19 @@ export async function saveOAuthToken(projectPath, token) {
33
55
  export async function removeOAuthToken(projectPath, integration) {
34
56
  const path = tokensPath(projectPath);
35
57
  const tokens = await readJson(path, []);
58
+ const removed = tokens.find((token) => token.integration === integration);
59
+ if (removed) {
60
+ await deleteSecretField(removed.accessToken);
61
+ await deleteSecretField(removed.refreshToken);
62
+ }
36
63
  const filtered = tokens.filter((t) => t.integration !== integration);
37
- await writeJson(path, filtered);
64
+ await writeSecureJson(path, filtered);
38
65
  }
39
66
  /**
40
67
  * List all stored OAuth tokens for a project.
41
68
  */
42
69
  export async function listOAuthTokens(projectPath) {
43
- return readJson(tokensPath(projectPath), []);
70
+ const tokens = await readJson(tokensPath(projectPath), []);
71
+ return Promise.all(tokens.map(resolveToken));
44
72
  }
45
73
  //# sourceMappingURL=oauth-store.js.map