@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,381 @@
1
+ import { readFile, rm } from 'node:fs/promises';
2
+ import { isAbsolute } from 'node:path';
3
+ import { atomicWriteFile } from '../safety/atomic-write-file.js';
4
+ import { readInstallationManifest, } from '../../cli/commands/install.js';
5
+ import { buildPinnedEntry } from './config-patcher.js';
6
+ import { stageAndVerifyRelease } from './release-verifier.js';
7
+ import { assertVersionNotQuarantined, markUpgradeVerified, quarantineUpgradeVersion, readUpgradeTrustState, upgradeTrustStatePath, } from './upgrade-trust-state.js';
8
+ import { withUpgradeLock } from './upgrade-lock.js';
9
+ import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
10
+ const PACKAGE_PREFIX = '@planu/cli@';
11
+ const EXACT_VERSION = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
12
+ export class UpgradeInterruptionError extends Error {
13
+ constructor(message = 'Simulated process interruption during upgrade') {
14
+ super(message);
15
+ this.name = 'UpgradeInterruptionError';
16
+ }
17
+ }
18
+ export function upgradeJournalPath(manifestPath) {
19
+ return `${manifestPath}.upgrade-journal.json`;
20
+ }
21
+ // eslint-disable-next-line complexity -- every persisted journal field is fail-closed
22
+ function parseJournal(raw, manifestPath) {
23
+ const parsed = JSON.parse(raw);
24
+ const adapterPaths = parsed.adapters?.map((item) => item.configPath) ?? [];
25
+ if (parsed.schemaVersion !== 2 ||
26
+ !['prepared', 'switching', 'trust-switched', 'committed'].includes(parsed.state ?? '') ||
27
+ parsed.manifestPath !== manifestPath ||
28
+ !EXACT_VERSION.test(parsed.previousVersion ?? '') ||
29
+ !EXACT_VERSION.test(parsed.targetVersion ?? '') ||
30
+ typeof parsed.originalManifest !== 'string' ||
31
+ parsed.trustStatePath !== upgradeTrustStatePath(manifestPath) ||
32
+ (parsed.originalTrustState !== null && typeof parsed.originalTrustState !== 'string') ||
33
+ !Array.isArray(parsed.adapters) ||
34
+ parsed.adapters.some((item) => !isAbsolute(item.configPath) || typeof item.original !== 'string') ||
35
+ new Set(adapterPaths).size !== adapterPaths.length ||
36
+ !Array.isArray(parsed.switchedPaths) ||
37
+ parsed.switchedPaths.some((path) => !adapterPaths.includes(path)) ||
38
+ typeof parsed.updatedAt !== 'string') {
39
+ throw new Error('[Planu upgrade] Persisted upgrade journal is unsafe or corrupt');
40
+ }
41
+ return parsed;
42
+ }
43
+ async function writeJournal(path, journal, writeFile) {
44
+ await writeFile(path, `${JSON.stringify(journal, null, 2)}\n`);
45
+ }
46
+ async function readUpgradeFile(path, code, message) {
47
+ try {
48
+ return await readFile(path, 'utf8');
49
+ }
50
+ catch (error) {
51
+ /* reliability-optional: UPGRADE_FILE_READ_FAILED */
52
+ reportClassifiedDegradation(code, error);
53
+ throw new Error(message, { cause: error });
54
+ }
55
+ }
56
+ async function recoverInterruptedUpgradeLocked(manifestPath, assertFence, dependencies = {}) {
57
+ const path = upgradeJournalPath(manifestPath);
58
+ const raw = await readFile(path, 'utf8').catch((error) => {
59
+ if (error.code === 'ENOENT') {
60
+ return null;
61
+ }
62
+ /* reliability-optional: UPGRADE_JOURNAL_READ_FAILED */
63
+ reportClassifiedDegradation('UPGRADE_JOURNAL_READ_FAILED', error);
64
+ throw new Error('[Planu upgrade] Persisted upgrade journal is unreadable');
65
+ });
66
+ if (raw === null) {
67
+ return false;
68
+ }
69
+ const journal = parseJournal(raw, manifestPath);
70
+ if (journal.state === 'committed') {
71
+ await assertFence();
72
+ await rm(path, { force: true });
73
+ return true;
74
+ }
75
+ const writeFile = dependencies.writeFile ??
76
+ ((target, content) => atomicWriteFile(target, content, { mode: 0o600 }));
77
+ for (const adapter of journal.adapters) {
78
+ await assertFence();
79
+ await writeFile(adapter.configPath, adapter.original);
80
+ }
81
+ await assertFence();
82
+ await writeFile(manifestPath, journal.originalManifest);
83
+ await assertFence();
84
+ if (journal.originalTrustState === null) {
85
+ await rm(journal.trustStatePath, { force: true });
86
+ }
87
+ else {
88
+ await writeFile(journal.trustStatePath, journal.originalTrustState);
89
+ }
90
+ await rm(path, { force: true });
91
+ return true;
92
+ }
93
+ export async function recoverInterruptedUpgrade(manifestPath, dependencies = {}) {
94
+ return withUpgradeLock(manifestPath, (assertFence) => recoverInterruptedUpgradeLocked(manifestPath, assertFence, dependencies));
95
+ }
96
+ function exactConfiguredVersion(record, config) {
97
+ if (typeof config !== 'object' || config === null || Array.isArray(config)) {
98
+ return null;
99
+ }
100
+ const root = config;
101
+ let command;
102
+ let args;
103
+ if (record.format === 'zed') {
104
+ const servers = root.context_servers;
105
+ const planu = servers?.planu;
106
+ const commandEntry = planu?.command;
107
+ command = commandEntry?.path;
108
+ args = commandEntry?.args;
109
+ }
110
+ else {
111
+ const servers = root.mcpServers;
112
+ const planu = servers?.planu;
113
+ command = planu?.command;
114
+ args = planu?.args;
115
+ }
116
+ if (command !== 'npx' || !Array.isArray(args)) {
117
+ return null;
118
+ }
119
+ const packageArgs = args.filter((arg) => typeof arg === 'string' && arg.startsWith(PACKAGE_PREFIX));
120
+ return packageArgs.length === 1 ? (packageArgs[0]?.slice(PACKAGE_PREFIX.length) ?? null) : null;
121
+ }
122
+ function buildUpdatedConfig(record, raw, version) {
123
+ let parsed;
124
+ try {
125
+ parsed = JSON.parse(raw);
126
+ }
127
+ catch (error) {
128
+ throw new Error('[Planu upgrade] An inventoried adapter contains invalid JSON', {
129
+ cause: error,
130
+ });
131
+ }
132
+ if (exactConfiguredVersion(record, parsed) !== record.version) {
133
+ throw new Error('[Planu upgrade] An inventoried adapter no longer matches the verified inventory version');
134
+ }
135
+ const root = parsed;
136
+ const entry = buildPinnedEntry(version);
137
+ if (record.format === 'zed') {
138
+ const servers = root.context_servers ?? {};
139
+ root.context_servers = {
140
+ ...servers,
141
+ planu: { command: { path: entry.command, args: entry.args } },
142
+ };
143
+ }
144
+ else {
145
+ const servers = root.mcpServers ?? {};
146
+ root.mcpServers = { ...servers, planu: entry };
147
+ }
148
+ return `${JSON.stringify(root, null, 2)}\n`;
149
+ }
150
+ async function prepareAdapters(installations, version) {
151
+ const seen = new Set();
152
+ const prepared = [];
153
+ for (const record of installations) {
154
+ if (seen.has(record.configPath)) {
155
+ throw new Error('[Planu upgrade] Installation inventory contains a duplicate adapter');
156
+ }
157
+ seen.add(record.configPath);
158
+ const original = await readUpgradeFile(record.configPath, 'UPGRADE_ADAPTER_READ_FAILED', '[Planu upgrade] An inventoried adapter is unreadable');
159
+ prepared.push({ record, original, updated: buildUpdatedConfig(record, original, version) });
160
+ }
161
+ return prepared;
162
+ }
163
+ async function inject(dependencies, context) {
164
+ await dependencies.faultInjector?.(context);
165
+ }
166
+ async function rollback(prepared, manifestPath, originalManifest, trustStatePath, originalTrustState, writeFile, assertFence) {
167
+ const failures = [];
168
+ for (const adapter of prepared) {
169
+ try {
170
+ await writeFile(adapter.record.configPath, adapter.original);
171
+ }
172
+ catch (error) {
173
+ /* reliability-cleanup: ADAPTER_ROLLBACK_FAILURE — aggregate failure throws below */
174
+ reportClassifiedDegradation('ADAPTER_ROLLBACK_FAILURE', error);
175
+ failures.push(`adapter rollback: ${redactFailureMessage(error)}`);
176
+ }
177
+ }
178
+ try {
179
+ await writeFile(manifestPath, originalManifest);
180
+ }
181
+ catch (error) {
182
+ /* reliability-cleanup: MANIFEST_ROLLBACK_FAILURE — aggregate failure throws below */
183
+ reportClassifiedDegradation('MANIFEST_ROLLBACK_FAILURE', error);
184
+ failures.push(`manifest rollback: ${redactFailureMessage(error)}`);
185
+ }
186
+ try {
187
+ if (originalTrustState === null) {
188
+ await assertFence();
189
+ await rm(trustStatePath, { force: true });
190
+ }
191
+ else {
192
+ await writeFile(trustStatePath, originalTrustState);
193
+ }
194
+ }
195
+ catch (error) {
196
+ /* reliability-cleanup: TRUST_ROLLBACK_FAILURE — aggregate failure throws below */
197
+ reportClassifiedDegradation('TRUST_ROLLBACK_FAILURE', error);
198
+ failures.push(`trust rollback: ${redactFailureMessage(error)}`);
199
+ }
200
+ if (failures.length > 0) {
201
+ throw new Error(`Global rollback was incomplete: ${failures.join('; ')}`);
202
+ }
203
+ }
204
+ // eslint-disable-next-line max-lines-per-function -- one ordered transaction keeps journal and rollback phases auditable
205
+ async function upgradeInventoriedAdaptersLocked(manifestPath, version, dependencies, assertFence) {
206
+ if (!EXACT_VERSION.test(version)) {
207
+ throw new Error(`Upgrade target must be an exact semantic version: ${version}`);
208
+ }
209
+ await recoverInterruptedUpgradeLocked(manifestPath, assertFence, dependencies);
210
+ const originalManifest = await readUpgradeFile(manifestPath, 'UPGRADE_MANIFEST_READ_FAILED', '[Planu upgrade] Installation inventory is unreadable');
211
+ const trustPath = upgradeTrustStatePath(manifestPath);
212
+ const originalTrustState = await readFile(trustPath, 'utf8').catch((error) => {
213
+ if (error.code === 'ENOENT') {
214
+ return null;
215
+ }
216
+ /* reliability-optional: UPGRADE_TRUST_READ_FAILED */
217
+ reportClassifiedDegradation('UPGRADE_TRUST_READ_FAILED', error);
218
+ throw new Error('[Planu upgrade] Last-known-good trust state is unreadable');
219
+ });
220
+ let manifest;
221
+ try {
222
+ manifest = readInstallationManifest(manifestPath);
223
+ }
224
+ catch (error) {
225
+ /* reliability-optional: UPGRADE_MANIFEST_PARSE_FAILED */
226
+ reportClassifiedDegradation('UPGRADE_MANIFEST_PARSE_FAILED', error);
227
+ throw new Error('[Planu upgrade] Installation inventory is invalid', {
228
+ cause: error,
229
+ });
230
+ }
231
+ if (manifest.installations.length === 0) {
232
+ throw new Error('Cannot upgrade: installation inventory is empty.');
233
+ }
234
+ const versions = new Set(manifest.installations.map((record) => record.version));
235
+ if (versions.size !== 1) {
236
+ throw new Error('Cannot establish a single previously verified version from the inventory.');
237
+ }
238
+ const previousVersion = manifest.installations[0]?.version;
239
+ if (previousVersion === undefined || !EXACT_VERSION.test(previousVersion)) {
240
+ throw new Error('Cannot establish the previously verified version.');
241
+ }
242
+ const trustState = await readUpgradeTrustState(manifestPath);
243
+ if (trustState !== null && trustState.lastKnownGoodVersion !== previousVersion) {
244
+ throw new Error(`Cannot upgrade: inventory ${previousVersion} differs from last-known-good ${trustState.lastKnownGoodVersion}.`);
245
+ }
246
+ assertVersionNotQuarantined(trustState, version);
247
+ const prepared = await prepareAdapters(manifest.installations, version);
248
+ const now = dependencies.now ?? (() => new Date());
249
+ let verification;
250
+ try {
251
+ verification = await (dependencies.stageAndVerify ?? stageAndVerifyRelease)(version);
252
+ }
253
+ catch (error) {
254
+ await assertFence();
255
+ await quarantineUpgradeVersion(manifestPath, previousVersion, version, 'verification-failed', now());
256
+ throw error;
257
+ }
258
+ if (verification.version !== version) {
259
+ await assertFence();
260
+ await quarantineUpgradeVersion(manifestPath, previousVersion, version, 'verification-failed', now());
261
+ throw new Error(`Release verifier returned ${verification.version}; expected exact target ${version}.`);
262
+ }
263
+ await inject(dependencies, { phase: 'after-runtime-verification', switchedAdapters: 0 });
264
+ const writeFile = dependencies.writeFile ??
265
+ ((path, content) => atomicWriteFile(path, content, { mode: 0o600 }));
266
+ const fencedWriteFile = async (path, content) => {
267
+ await assertFence();
268
+ await writeFile(path, content);
269
+ };
270
+ let switchedAdapters = 0;
271
+ const journalPath = upgradeJournalPath(manifestPath);
272
+ let journal = {
273
+ schemaVersion: 2,
274
+ state: 'prepared',
275
+ manifestPath,
276
+ previousVersion,
277
+ targetVersion: version,
278
+ originalManifest,
279
+ trustStatePath: trustPath,
280
+ originalTrustState,
281
+ adapters: prepared.map((adapter) => ({
282
+ configPath: adapter.record.configPath,
283
+ original: adapter.original,
284
+ })),
285
+ switchedPaths: [],
286
+ updatedAt: now().toISOString(),
287
+ };
288
+ await writeJournal(journalPath, journal, fencedWriteFile);
289
+ try {
290
+ for (const adapter of prepared) {
291
+ await inject(dependencies, {
292
+ phase: 'before-adapter-switch',
293
+ adapter: adapter.record,
294
+ switchedAdapters,
295
+ });
296
+ await fencedWriteFile(adapter.record.configPath, adapter.updated);
297
+ switchedAdapters += 1;
298
+ journal = {
299
+ ...journal,
300
+ state: 'switching',
301
+ switchedPaths: [...journal.switchedPaths, adapter.record.configPath],
302
+ updatedAt: now().toISOString(),
303
+ };
304
+ await writeJournal(journalPath, journal, fencedWriteFile);
305
+ await inject(dependencies, {
306
+ phase: 'after-adapter-switch',
307
+ adapter: adapter.record,
308
+ switchedAdapters,
309
+ });
310
+ }
311
+ await inject(dependencies, { phase: 'before-manifest-switch', switchedAdapters });
312
+ const installedAt = now().toISOString();
313
+ const updatedManifest = {
314
+ ...manifest,
315
+ updatedAt: installedAt,
316
+ installations: manifest.installations.map((record) => ({
317
+ ...record,
318
+ version,
319
+ offline: false,
320
+ installedAt,
321
+ })),
322
+ };
323
+ await fencedWriteFile(manifestPath, `${JSON.stringify(updatedManifest, null, 2)}\n`);
324
+ await inject(dependencies, { phase: 'after-manifest-switch', switchedAdapters });
325
+ await assertFence();
326
+ await markUpgradeVerified(manifestPath, version, verification.verifiedAt);
327
+ journal = {
328
+ ...journal,
329
+ state: 'trust-switched',
330
+ updatedAt: installedAt,
331
+ };
332
+ await writeJournal(journalPath, journal, fencedWriteFile);
333
+ await inject(dependencies, { phase: 'after-trust-switch', switchedAdapters });
334
+ journal = {
335
+ ...journal,
336
+ state: 'committed',
337
+ updatedAt: installedAt,
338
+ };
339
+ await writeJournal(journalPath, journal, fencedWriteFile);
340
+ await assertFence();
341
+ await rm(journalPath, { force: true });
342
+ return {
343
+ previousVersion,
344
+ version,
345
+ switchedAdapters,
346
+ manifest: updatedManifest,
347
+ verification,
348
+ };
349
+ }
350
+ catch (error) {
351
+ if (error instanceof UpgradeInterruptionError) {
352
+ throw error;
353
+ }
354
+ try {
355
+ await rollback(prepared, manifestPath, originalManifest, trustPath, originalTrustState, fencedWriteFile, assertFence);
356
+ await assertFence();
357
+ await rm(journalPath, { force: true });
358
+ }
359
+ catch (rollbackError) {
360
+ /* reliability-cleanup: UPGRADE_ROLLBACK_INCOMPLETE */
361
+ reportClassifiedDegradation('UPGRADE_ROLLBACK_INCOMPLETE', rollbackError);
362
+ throw new AggregateError([new Error(redactFailureMessage(error)), new Error(redactFailureMessage(rollbackError))], `Upgrade to ${version} failed and global rollback was incomplete.`, { cause: rollbackError });
363
+ }
364
+ try {
365
+ await assertFence();
366
+ await quarantineUpgradeVersion(manifestPath, previousVersion, version, 'activation-failed', now());
367
+ }
368
+ catch (quarantineError) {
369
+ /* reliability-cleanup: UPGRADE_QUARANTINE_FAILED */
370
+ reportClassifiedDegradation('UPGRADE_QUARANTINE_FAILED', quarantineError);
371
+ throw new AggregateError([new Error(redactFailureMessage(error)), new Error(redactFailureMessage(quarantineError))], `Upgrade to ${version} rolled back but quarantine persistence failed.`, { cause: quarantineError });
372
+ }
373
+ reportClassifiedDegradation('UPGRADE_ACTIVATION_FAILED', error);
374
+ const symptom = new Error(`Upgrade to ${version} failed; all adapters restored to ${previousVersion}.`);
375
+ throw symptom;
376
+ }
377
+ }
378
+ export async function upgradeInventoriedAdapters(manifestPath, version, dependencies = {}) {
379
+ return withUpgradeLock(manifestPath, (assertFence) => upgradeInventoriedAdaptersLocked(manifestPath, version, dependencies, assertFence));
380
+ }
381
+ //# sourceMappingURL=atomic-upgrade.js.map
@@ -5,6 +5,7 @@ import { readFile } from 'node:fs/promises';
5
5
  import { homedir } from 'node:os';
6
6
  import { join } from 'node:path';
7
7
  import { PLANU_VERSION } from '../../config/version.js';
8
+ import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
8
9
  // ---------------------------------------------------------------------------
9
10
  // Config path resolution
10
11
  // ---------------------------------------------------------------------------
@@ -34,8 +35,11 @@ export async function findMcpConfig() {
34
35
  await readFile(candidate.path, 'utf-8');
35
36
  return { configPath: candidate.path, configType: candidate.type };
36
37
  }
37
- catch {
38
- // File does not exist or is not readable — try next
38
+ catch (error) {
39
+ /* reliability-optional: MCP_CONFIG_CANDIDATE_UNREADABLE */
40
+ if (error.code !== 'ENOENT') {
41
+ reportClassifiedDegradation('MCP_CONFIG_CANDIDATE_UNREADABLE', error);
42
+ }
39
43
  }
40
44
  }
41
45
  return { configPath: null, configType: null };
@@ -84,7 +88,9 @@ export async function detectPlanuInstall() {
84
88
  const raw = await readFile(location.configPath, 'utf-8');
85
89
  config = JSON.parse(raw);
86
90
  }
87
- catch {
91
+ catch (error) {
92
+ /* reliability-optional: MCP_CONFIG_PARSE_FAILED */
93
+ reportClassifiedDegradation('MCP_CONFIG_PARSE_FAILED', error);
88
94
  return {
89
95
  method: 'unknown',
90
96
  currentVersion: PLANU_VERSION,
@@ -14,10 +14,6 @@ export declare function patchPlanuEntry(configPath: string, newEntry: McpServerE
14
14
  backupPath: string;
15
15
  previousEntry: McpServerEntry | null;
16
16
  }>;
17
- /**
18
- * Returns the standard npx @latest entry for Planu.
19
- */
20
- export declare function buildNpxLatestEntry(): McpServerEntry;
21
17
  /**
22
18
  * Returns an npx entry pinned to a specific version.
23
19
  */
@@ -2,7 +2,9 @@
2
2
  // engine/auto-updater/config-patcher.ts — Patches the MCP config file to enable auto-update.
3
3
  // SPEC-443
4
4
  // Creates a backup before any modification. Restores backup on write failure.
5
- import { readFile, writeFile } from 'node:fs/promises';
5
+ import { readFile } from 'node:fs/promises';
6
+ import { randomUUID } from 'node:crypto';
7
+ import { atomicWriteFile } from '../safety/atomic-write-file.js';
6
8
  export const PLANU_MCP_STARTUP_TIMEOUT_SEC = 120;
7
9
  // ---------------------------------------------------------------------------
8
10
  // Helpers
@@ -11,7 +13,7 @@ function dateStr() {
11
13
  return new Date().toISOString().slice(0, 10);
12
14
  }
13
15
  function backupPathFor(configPath) {
14
- return configPath.replace(/\.json$/, `.backup-${dateStr()}.json`);
16
+ return configPath.replace(/\.json$/, `.backup-${dateStr()}-${randomUUID()}.json`);
15
17
  }
16
18
  // ---------------------------------------------------------------------------
17
19
  // Patch operations
@@ -39,7 +41,7 @@ export async function patchPlanuEntry(configPath, newEntry) {
39
41
  const previousEntry = config.mcpServers?.planu ?? null;
40
42
  // Create backup BEFORE modifying anything
41
43
  const backupPath = backupPathFor(configPath);
42
- await writeFile(backupPath, raw, 'utf-8');
44
+ await atomicWriteFile(backupPath, raw, { mode: 0o600 });
43
45
  // Patch
44
46
  const updated = {
45
47
  ...config,
@@ -49,29 +51,22 @@ export async function patchPlanuEntry(configPath, newEntry) {
49
51
  },
50
52
  };
51
53
  try {
52
- await writeFile(configPath, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
54
+ await atomicWriteFile(configPath, JSON.stringify(updated, null, 2) + '\n', { mode: 0o600 });
53
55
  }
54
56
  catch (writeErr) {
55
57
  // Restore from backup
56
- await writeFile(configPath, raw, 'utf-8');
58
+ await atomicWriteFile(configPath, raw, { mode: 0o600 });
57
59
  throw new Error(`Failed to write updated config to ${configPath}. Restored original from backup. Error: ${String(writeErr)}`, { cause: writeErr });
58
60
  }
59
61
  return { backupPath, previousEntry };
60
62
  }
61
- /**
62
- * Returns the standard npx @latest entry for Planu.
63
- */
64
- export function buildNpxLatestEntry() {
65
- return {
66
- command: 'npx',
67
- args: ['-y', '@planu/cli@latest'],
68
- startup_timeout_sec: PLANU_MCP_STARTUP_TIMEOUT_SEC,
69
- };
70
- }
71
63
  /**
72
64
  * Returns an npx entry pinned to a specific version.
73
65
  */
74
66
  export function buildPinnedEntry(version) {
67
+ if (!/^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/.test(version)) {
68
+ throw new Error(`[Planu] Refusing non-exact CLI version: ${version}`);
69
+ }
75
70
  return {
76
71
  command: 'npx',
77
72
  args: ['-y', `@planu/cli@${version}`],
@@ -1,10 +1,12 @@
1
1
  import type { EnableAutoUpdateResult, PinVersionResult, UpdateCheckResult } from '../../types/auto-update.js';
2
+ export { upgradeInventoriedAdapters } from './atomic-upgrade.js';
3
+ export { stageAndVerifyRelease } from './release-verifier.js';
2
4
  /**
3
5
  * Checks the current install info and npm registry for update availability.
4
6
  */
5
7
  export declare function checkForUpdates(): Promise<UpdateCheckResult>;
6
8
  /**
7
- * Enables auto-update by patching the MCP config to use npx @planu/cli@latest.
9
+ * Resolves a verified release and pins the MCP config to that exact version.
8
10
  * If confirm is false (default), returns a preview of changes without applying.
9
11
  * If confirm is true, applies the change immediately.
10
12
  */
@@ -1,9 +1,14 @@
1
1
  // engine/auto-updater/index.ts — Public API for the auto-updater engine.
2
2
  // SPEC-443
3
+ import { existsSync } from 'node:fs';
3
4
  import { detectPlanuInstall } from './config-detector.js';
4
- import { buildNpxLatestEntry, buildPinnedEntry, patchPlanuEntry } from './config-patcher.js';
5
+ import { buildPinnedEntry } from './config-patcher.js';
5
6
  import { fetchLatestVersion } from './npm-registry.js';
6
7
  import { PLANU_VERSION } from '../../config/version.js';
8
+ import { resolveStorageLayout } from '../../storage/storage-layout.js';
9
+ import { upgradeInventoriedAdapters } from './atomic-upgrade.js';
10
+ export { upgradeInventoriedAdapters } from './atomic-upgrade.js';
11
+ export { stageAndVerifyRelease } from './release-verifier.js';
7
12
  // ---------------------------------------------------------------------------
8
13
  // check_update_status
9
14
  // ---------------------------------------------------------------------------
@@ -16,20 +21,21 @@ export async function checkForUpdates() {
16
21
  fetchLatestVersion(),
17
22
  ]);
18
23
  const isUpToDate = latestVersion === null ? true : latestVersion === installInfo.currentVersion;
19
- const autoUpdateActive = installInfo.method === 'npx-latest';
24
+ // Legacy @latest entries are detected but never considered a safe active mode.
25
+ const autoUpdateActive = false;
20
26
  let updateCommand;
21
- if (autoUpdateActive) {
27
+ if (installInfo.method === 'npx-latest') {
22
28
  updateCommand =
23
- 'Auto-update is active Planu updates automatically on each Claude session start.';
29
+ 'Legacy unpinned entry detected; run enable_auto_update to pin an exact release.';
24
30
  }
25
31
  else if (installInfo.method === 'global') {
26
- updateCommand = 'npm install -g @planu/cli@latest';
32
+ updateCommand = `npm install -g @planu/cli@${latestVersion ?? PLANU_VERSION}`;
27
33
  }
28
34
  else if (installInfo.method === 'local-path') {
29
35
  updateCommand = 'Update your local installation and rebuild.';
30
36
  }
31
37
  else {
32
- updateCommand = 'Run enable_auto_update to switch to npx @latest for automatic updates.';
38
+ updateCommand = 'Run enable_auto_update to resolve and pin the latest verified version.';
33
39
  }
34
40
  return {
35
41
  currentVersion: installInfo.currentVersion,
@@ -44,11 +50,19 @@ export async function checkForUpdates() {
44
50
  // enable_auto_update
45
51
  // ---------------------------------------------------------------------------
46
52
  /**
47
- * Enables auto-update by patching the MCP config to use npx @planu/cli@latest.
53
+ * Resolves a verified release and pins the MCP config to that exact version.
48
54
  * If confirm is false (default), returns a preview of changes without applying.
49
55
  * If confirm is true, applies the change immediately.
50
56
  */
51
57
  export async function enableAutoUpdate(confirm, overrideConfigPath) {
58
+ if (process.env.PLANU_OFFLINE === '1') {
59
+ throw new Error('Auto-update is unavailable while PLANU_OFFLINE=1. Pin an installed version.');
60
+ }
61
+ const latestVersion = await fetchLatestVersion();
62
+ if (latestVersion === null) {
63
+ throw new Error('Could not resolve an exact Planu version; no config changes were made.');
64
+ }
65
+ const resolvedEntry = buildPinnedEntry(latestVersion);
52
66
  let installInfo;
53
67
  if (overrideConfigPath !== undefined) {
54
68
  // Build a minimal install info using the override path
@@ -62,21 +76,11 @@ export async function enableAutoUpdate(confirm, overrideConfigPath) {
62
76
  else {
63
77
  installInfo = await detectPlanuInstall();
64
78
  }
65
- if (installInfo.method === 'npx-latest') {
66
- return {
67
- configPath: installInfo.configPath ?? '(unknown)',
68
- previousEntry: installInfo.mcpEntry,
69
- newEntry: buildNpxLatestEntry(),
70
- backupPath: '',
71
- alreadyOptimal: true,
72
- message: 'Auto-update is already active. Planu uses npx @planu/cli@latest — it updates automatically on each Claude session start.',
73
- };
74
- }
75
79
  if (installInfo.configPath === null) {
76
80
  throw new Error('Could not find MCP config file (~/.claude.json or Claude Desktop config). ' +
77
81
  'Please specify the path manually using the configPath parameter.');
78
82
  }
79
- const newEntry = buildNpxLatestEntry();
83
+ const newEntry = resolvedEntry;
80
84
  if (!confirm) {
81
85
  return {
82
86
  configPath: installInfo.configPath,
@@ -85,20 +89,27 @@ export async function enableAutoUpdate(confirm, overrideConfigPath) {
85
89
  backupPath: '',
86
90
  alreadyOptimal: false,
87
91
  message: `Preview: The planu entry in ${installInfo.configPath} will be updated to use ` +
88
- `"command": "npx", "args": ["-y", "@planu/cli@latest"]. ` +
92
+ `"command": "npx", "args": ["-y", "@planu/cli@${latestVersion}"]. ` +
89
93
  'Call enable_auto_update with confirm=true to apply.',
90
94
  };
91
95
  }
92
- const { backupPath, previousEntry } = await patchPlanuEntry(installInfo.configPath, newEntry);
96
+ if (overrideConfigPath !== undefined) {
97
+ throw new Error('Direct config-path updates are not recoverable. Run planu install to inventory the adapter first.');
98
+ }
99
+ const manifestPath = resolveStorageLayout().installationManifest;
100
+ if (!existsSync(manifestPath)) {
101
+ throw new Error('Auto-update requires an installation inventory and last-known-good rollback target. Run planu install first.');
102
+ }
103
+ const upgraded = await upgradeInventoriedAdapters(manifestPath, latestVersion);
93
104
  return {
94
105
  configPath: installInfo.configPath,
95
- previousEntry,
106
+ previousEntry: installInfo.mcpEntry,
96
107
  newEntry,
97
- backupPath,
108
+ backupPath: '',
98
109
  alreadyOptimal: false,
99
- message: `Auto-update enabled. Config updated at ${installInfo.configPath}. ` +
100
- `Backup saved to ${backupPath}. ` +
101
- 'Restart Claude to activate the change.',
110
+ message: `Verified version ${latestVersion} staged and smoke-tested. ` +
111
+ `${String(upgraded.switchedAdapters)} inventoried adapter(s) switched atomically; ` +
112
+ `global rollback target was ${upgraded.previousVersion}. Restart your AI tools to activate.`,
102
113
  };
103
114
  }
104
115
  // ---------------------------------------------------------------------------
@@ -113,7 +124,6 @@ export async function pinVersion(version, confirm) {
113
124
  if (installInfo.configPath === null) {
114
125
  throw new Error('Could not find MCP config file. Please ensure Claude Code or Claude Desktop is configured.');
115
126
  }
116
- const pinnedEntry = buildPinnedEntry(version);
117
127
  if (!confirm) {
118
128
  return {
119
129
  configPath: installInfo.configPath,
@@ -124,14 +134,18 @@ export async function pinVersion(version, confirm) {
124
134
  'To return to auto-update, call enable_auto_update.',
125
135
  };
126
136
  }
127
- const { backupPath } = await patchPlanuEntry(installInfo.configPath, pinnedEntry);
137
+ const manifestPath = resolveStorageLayout().installationManifest;
138
+ if (!existsSync(manifestPath)) {
139
+ throw new Error('Pinning requires an installation inventory and last-known-good rollback target. Run planu install first.');
140
+ }
141
+ await upgradeInventoriedAdapters(manifestPath, version);
128
142
  return {
129
143
  configPath: installInfo.configPath,
130
144
  pinnedVersion: version,
131
- backupPath,
145
+ backupPath: '',
132
146
  message: `Version pinned to @planu/cli@${version} in ${installInfo.configPath}. ` +
133
- `Backup saved to ${backupPath}. ` +
134
- 'Restart Claude to activate. To return to auto-update, call enable_auto_update.',
147
+ 'The previously verified release remains available for rollback. ' +
148
+ 'Restart your AI tools to activate. To return to auto-update, call enable_auto_update.',
135
149
  };
136
150
  }
137
151
  //# sourceMappingURL=index.js.map