@planu/cli 4.12.3 → 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 +35 -0
  2. package/README.md +29 -25
  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
package/CHANGELOG.md CHANGED
@@ -1,3 +1,38 @@
1
+ ## [4.14.1] - 2026-07-29
2
+
3
+ ### Bug Fixes
4
+ - fix(release): defer native install verification
5
+ - fix(release): make local artifacts authoritative
6
+
7
+
8
+ ## [4.14.0] - 2026-07-29
9
+
10
+ ### Features
11
+ - feat: make Planu local-first and harden release integrity
12
+
13
+ ### Bug Fixes
14
+ - fix(native): constrain napi generator compatibility
15
+ - fix(native): pin compatible napi code generator
16
+ - fix(release): validate rebuilt native artifacts
17
+ - fix(release): bump native build manifest
18
+ - fix(release): synchronize session context version
19
+ - fix: classify freshness degradation paths
20
+ - fix: make validation freshness deterministic
21
+ - fix: make transactional locks crash-safe
22
+ - fix: benchmark native runtime in worker threads
23
+ - fix: classify lock degradation paths
24
+ - fix: await init repository hook writes
25
+ - fix: make cross-process leases transactional
26
+ - fix: publish cross-process locks atomically
27
+ - fix: complete process cancellation before settling
28
+
29
+
30
+ ## [4.13.0] - 2026-07-27
31
+
32
+ ### Features
33
+ - feat(website): animate support journey
34
+
35
+
1
36
  ## [4.12.3] - 2026-07-27
2
37
 
3
38
  ### Features
package/README.md CHANGED
@@ -5,23 +5,23 @@
5
5
  [![npm version](https://img.shields.io/npm/v/@planu/cli?color=blue&label=npm)](https://www.npmjs.com/package/@planu/cli)
6
6
  ![Node](https://img.shields.io/badge/node-%3E%3D24.0.0-green)
7
7
  ![Rust](https://img.shields.io/badge/core-rust-orange)
8
- ![License](https://img.shields.io/badge/license-MIT-blue)
8
+ ![License](https://img.shields.io/badge/license-proprietary-blue)
9
9
 
10
- **[Documentation](https://planu.dev)** · **[Docs in Spanish](https://planu.dev/es)** · **[Docs in Portuguese](https://planu.dev/pt)**
10
+ **[Documentation](https://planu.dev)** · **[Español (Latinoamérica)](https://planu.dev/es)** · **[Español (España)](https://planu.dev/es-ES)** · **[Português](https://planu.dev/pt)**
11
11
 
12
12
  ---
13
13
 
14
14
  ## What is Planu?
15
15
 
16
- Planu is the **complete Spec Driven Development stack** for AI coding agents an MCP server that enforces a structured workflow from brainstorm to validation. Powered by a **native Rust core**, Planu provides the performance and reliability needed for large-scale AI development.
16
+ Planu is a Spec Driven Development stack for AI coding agents: an MCP server and local CLI that move work from a reviewed specification to validation evidence. Supported installations can use the bundled native Rust core for selected local hot paths.
17
17
 
18
18
  **Spec first, always.** No approved spec means no code. This eliminates vibe-coding debt at scale.
19
19
 
20
- - **Native Rust Engine** — 10x faster project scanning, parallel hashing, and regex extraction.
21
- - **Instant Drift Detection** — OS-level file watcher reacts to changes with 0% CPU overhead.
20
+ - **Native Rust Engine** — accelerates supported project scanning, hashing, and extraction paths.
21
+ - **Local change detection** — observes project changes without requiring a hosted configuration service.
22
22
  - **Unified Spec Format** — Requirements and technical details in a single, context-efficient `spec.md`.
23
23
  - **Atomic Integrity** — Indestructible writes and **Freeze-on-done** immutability (P0).
24
- - **14 official MCP tools** for the complete SDD loop, with advanced workflows kept in skills, CLI commands, and internal pipelines.
24
+ - **27 official MCP tools** for the public SDD surface, with advanced workflows kept in skills, CLI commands, and internal pipelines.
25
25
  - **Multi-agent compatible** — Optimized for Claude Code, Cursor, Windsurf, and Gemini CLI.
26
26
 
27
27
  ---
@@ -43,6 +43,8 @@ Add to your MCP client config (Claude Desktop: `~/Library/Application Support/Cl
43
43
 
44
44
  **Requirements:** Node.js >= 24. The native Rust core is bundled and auto-detected for macOS (Intel/M1), Linux, and Windows.
45
45
 
46
+ **Upgrade safety:** stop every running Planu process before upgrading. Current releases use a single transactional SQLite lock authority with monotonic fencing; concurrent mixed-version execution is intentionally unsupported because older file-lock clients cannot participate in the same atomic protocol.
47
+
46
48
  ---
47
49
 
48
50
  ## The SDD Lifecycle
@@ -63,29 +65,27 @@ Planu runs follow-up actions automatically after each step:
63
65
 
64
66
  ---
65
67
 
66
- ## Unified Spec Format (v3.0)
68
+ ## Artifact lifecycle
67
69
 
68
- Specs are context-efficient: **1 single file per spec** containing both functional requirements and technical implementation details.
70
+ The portable contract stays small and versionable:
69
71
 
70
72
  ```
71
73
  planu/specs/SPEC-001-auth/
72
- └── spec.md # Requirements + Technical + Criteria + Status
74
+ └── spec.md # Requirements, technical contract, criteria, and lifecycle status
73
75
  ```
74
76
 
75
- Criteria use **zero-ambiguity GIVEN/WHEN/THEN format** ensuring your AI never misinterprets the goal.
76
-
77
- ---
77
+ Operational evidence does not live beside `spec.md`. Planu stores it in the external project data directory for the logical project:
78
78
 
79
- ## Native Performance (v3.0)
79
+ | Artifact | Purpose | Lifecycle |
80
+ |---|---|---|
81
+ | `discovery.json` | Rules, examples, open questions, scope boundaries, and glossary used before approval | Created/reviewed before `approved` |
82
+ | `task-plan.json` | Implementation tasks mapped to acceptance criteria | Required before `implementing` |
83
+ | `traceability-matrix.json` | Links every criterion to changed files and test/review evidence | Required before `done` |
84
+ | `contract-validation-*.json` | API, GraphQL, event, UI, or MCP contract results when applicable | Produced during validation |
85
+ | validation receipts and logs | Immutable result identity plus content-addressed command output | Persisted after validation |
86
+ | durable jobs | Local execution state, progress, cancellation, deadlines, and terminal outcome | Persisted in the runtime database across process restarts |
80
87
 
81
- Planu v3.0 introduces **The Rust Revolution**:
82
-
83
- | Feature | Node.js (Legacy) | **Planu-RS (v3.0)** | Benefit |
84
- |---------|:----------------:|:-------------------:|:-------:|
85
- | Project Scanning | Sequential (Slow) | **Parallel (Rayon)** | **10x Speedup** |
86
- | File Watching | Polling/Event Loop | **OS-level (Notify)** | **0% CPU Idle** |
87
- | Spec Hashing | JS Crypto | **Native SHA-256** | Instant Sync |
88
- | Drift Monitor | Memory Heavy | **Streaming Scan** | Monorepo Ready |
88
+ The external root follows the operating system's application-data convention and can be redirected with `PLANU_HOME`. Project evidence is stored under `<data>/projects/<logical-project-id>/`; durable jobs and authentic validation receipts are stored in `<data>/runtime/planu.sqlite3`. These files are machine-local by default, while `planu/specs/<id>/spec.md` remains the version-controlled source of truth.
89
89
 
90
90
  ---
91
91
 
@@ -99,9 +99,13 @@ src/
99
99
  ├── storage/ # Atomic persistence layer
100
100
  └── types/ # Strict TypeScript contracts
101
101
 
102
- data/ # Local storage (gitignored)
103
- ├── projects/{hash}/ # Per-project: specs, metrics, patterns, knowledge
104
- └── global/ # Shared: templates, pricing
102
+ <data>/ # Resolved platform-specific Planu data root
103
+ ├── projects/<logical-project-id>/ # Evidence, handoffs, reviews, and projections
104
+ └── runtime/planu.sqlite3 # Durable jobs, receipts, indexes, and audit state
105
+
106
+ planu/ # Portable, version-controlled project contract
107
+ ├── specs/{spec}/spec.md # Canonical specifications
108
+ └── project.json # Portable logical project identity
105
109
  ```
106
110
 
107
111
  ---
@@ -122,4 +126,4 @@ pnpm release:local # Local-first release flow when shipping
122
126
 
123
127
  ## License
124
128
 
125
- [MIT](LICENSE)
129
+ Planu is proprietary software. See the [license terms](LICENSE) for permitted use and distribution restrictions.
@@ -0,0 +1,4 @@
1
+ import type { CliCommand } from '../../types/cli.js';
2
+ export declare function buildInspectionReport(): Promise<Record<string, unknown>>;
3
+ export declare const inspectCommand: CliCommand;
4
+ //# sourceMappingURL=inspect.d.ts.map
@@ -0,0 +1,144 @@
1
+ import { lstat, readdir } from 'node:fs/promises';
2
+ import { existsSync } from 'node:fs';
3
+ import { basename, isAbsolute, join, relative, sep } from 'node:path';
4
+ import { homedir } from 'node:os';
5
+ import { PLANU_VERSION } from '../../config/version.js';
6
+ import { createStorageCatalog } from '../../storage/storage-catalog.js';
7
+ import { resolveStorageLayout } from '../../storage/storage-layout.js';
8
+ import { NATIVE_CAPABILITY_ABI, NATIVE_PROTOCOL_ABI, RUNTIME_STORAGE_SCHEMA, nativeLoadDiagnostic, } from '../../engine/core-bridge.js';
9
+ import { readInstallationManifest } from './install.js';
10
+ import { getProjects } from '../../storage/global-projects-store.js';
11
+ async function inspectPath(path) {
12
+ try {
13
+ const info = await lstat(path);
14
+ if (info.isSymbolicLink()) {
15
+ return { path, exists: true, bytes: 0, mode: (info.mode & 0o777).toString(8) };
16
+ }
17
+ if (!info.isDirectory()) {
18
+ return { path, exists: true, bytes: info.size, mode: (info.mode & 0o777).toString(8) };
19
+ }
20
+ let bytes = 0;
21
+ for (const entry of await readdir(path, { withFileTypes: true })) {
22
+ if (entry.isSymbolicLink()) {
23
+ continue;
24
+ }
25
+ bytes += (await inspectPath(`${path}/${entry.name}`)).bytes;
26
+ }
27
+ return { path, exists: true, bytes, mode: (info.mode & 0o777).toString(8) };
28
+ }
29
+ catch (error) {
30
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
31
+ return { path, exists: false, bytes: 0 };
32
+ }
33
+ throw error;
34
+ }
35
+ }
36
+ export async function buildInspectionReport() {
37
+ const layout = resolveStorageLayout();
38
+ const portablePath = (path) => {
39
+ const roots = [
40
+ ['<runtime-db>', layout.runtimeDatabase],
41
+ ['<installation-manifest>', layout.installationManifest],
42
+ ['<projects>', layout.projects],
43
+ ['<native-cache>', layout.nativeCache],
44
+ ['<trash>', layout.trash],
45
+ ['<config>', layout.config],
46
+ ['<data>', layout.data],
47
+ ['<cache>', layout.cache],
48
+ ['<state>', layout.state],
49
+ ['<logs>', layout.logs],
50
+ ['<secrets>', layout.secrets],
51
+ ['<home>', homedir()],
52
+ ];
53
+ for (const [token, root] of roots.sort((left, right) => right[1].length - left[1].length)) {
54
+ const suffix = relative(root, path);
55
+ if (suffix === '') {
56
+ return token;
57
+ }
58
+ if (!suffix.startsWith(`..${sep}`) && suffix !== '..' && !isAbsolute(suffix)) {
59
+ return `${token}/${suffix.split(sep).join('/')}`;
60
+ }
61
+ }
62
+ return isAbsolute(path) ? `<absolute>/${basename(path)}` : path;
63
+ };
64
+ const sanitize = (value) => {
65
+ if (Array.isArray(value)) {
66
+ return value.map(sanitize);
67
+ }
68
+ if (value && typeof value === 'object') {
69
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [
70
+ key,
71
+ sanitize(item),
72
+ ]));
73
+ }
74
+ return typeof value === 'string' && isAbsolute(value) ? portablePath(value) : value;
75
+ };
76
+ const layoutEntries = Object.entries(layout);
77
+ const roots = await Promise.all(layoutEntries.map(async ([kind, path]) => ({
78
+ kind,
79
+ ...(await inspectPath(path)),
80
+ path: portablePath(path),
81
+ })));
82
+ let installation = null;
83
+ if (existsSync(layout.installationManifest)) {
84
+ installation = sanitize(readInstallationManifest(layout.installationManifest));
85
+ }
86
+ const registered = await getProjects().catch(() => []);
87
+ const registeredHashes = new Set(registered.map((project) => project.hash));
88
+ const projectEntries = await readdir(layout.projects, { withFileTypes: true }).catch(() => []);
89
+ const orphanProjects = projectEntries
90
+ .filter((entry) => entry.isDirectory() && !registeredHashes.has(entry.name))
91
+ .map((entry) => entry.name);
92
+ const legacy = await Promise.all([
93
+ join(homedir(), '.planu'),
94
+ join(process.cwd(), /* @planu-storage-read-only legacy inspection */ '.planu'),
95
+ ].map(async (path) => ({
96
+ path: portablePath(path),
97
+ exists: (await inspectPath(path)).exists,
98
+ })));
99
+ const native = nativeLoadDiagnostic();
100
+ const displayArtifact = (value) => isAbsolute(value) ? `<local>/${basename(value)}` : value;
101
+ return {
102
+ schemaVersion: 1,
103
+ cliVersion: PLANU_VERSION,
104
+ offline: process.env.PLANU_OFFLINE === '1',
105
+ native: {
106
+ loaded: native.loaded ? displayArtifact(native.loaded) : null,
107
+ compatibility: native.compatibility ?? null,
108
+ attempted: native.attempted.map(displayArtifact),
109
+ errorCount: native.errors.length,
110
+ capabilities: native.capabilities ?? [],
111
+ executionScope: native.executionScope ?? null,
112
+ protocolAbi: NATIVE_PROTOCOL_ABI,
113
+ capabilityAbi: NATIVE_CAPABILITY_ABI,
114
+ storageSchema: RUNTIME_STORAGE_SCHEMA,
115
+ },
116
+ installation,
117
+ hostAdapters: installation && typeof installation === 'object' && 'installations' in installation
118
+ ? installation.installations
119
+ : [],
120
+ roots,
121
+ artifacts: sanitize(createStorageCatalog({ layout })),
122
+ legacy,
123
+ orphanProjects,
124
+ networkPolicy: {
125
+ offlineEnforced: process.env.PLANU_OFFLINE === '1',
126
+ fetchGuard: true,
127
+ directHttpsGuard: true,
128
+ },
129
+ };
130
+ }
131
+ export const inspectCommand = {
132
+ name: 'inspect',
133
+ description: 'Report local versions, storage, permissions and host adapters',
134
+ usage: 'planu inspect [--json]',
135
+ async run(_args, flags) {
136
+ const report = await buildInspectionReport();
137
+ if (flags?.json) {
138
+ process.stdout.write(`${JSON.stringify(report)}\n`);
139
+ return;
140
+ }
141
+ process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
142
+ },
143
+ };
144
+ //# sourceMappingURL=inspect.js.map
@@ -31,9 +31,27 @@ interface ToolDefinition {
31
31
  projectScopePath: string | null;
32
32
  format: 'standard' | 'zed';
33
33
  }
34
- declare function buildMcpEntry(licenseKey?: string): McpEntry;
34
+ export interface InstallationRecord {
35
+ host: string;
36
+ configPath: string;
37
+ format: ToolDefinition['format'];
38
+ scope: 'user' | 'project';
39
+ package: string;
40
+ version: string;
41
+ offline: boolean;
42
+ installedAt: string;
43
+ }
44
+ export interface InstallationManifest {
45
+ schemaVersion: 1;
46
+ updatedAt: string;
47
+ installations: InstallationRecord[];
48
+ }
49
+ declare function buildMcpEntry(_licenseKey?: string): McpEntry;
35
50
  declare function readJsonFile(filePath: string): ToolConfig;
36
51
  declare function hasPlanuEntry(config: ToolConfig, format: ToolDefinition['format']): boolean;
52
+ export declare function readInstallationManifest(manifestPath: string): InstallationManifest;
53
+ export declare function recordInstallation(manifestPath: string, record: InstallationRecord): InstallationManifest;
54
+ export declare function removeInstallationRecords(manifestPath: string, removedConfigPaths: ReadonlySet<string>): InstallationManifest;
37
55
  declare function writeStandardEntry(filePath: string, entry: McpEntry): void;
38
56
  declare function writeZedEntry(filePath: string, entry: McpEntry): void;
39
57
  declare function removeEntry(filePath: string, format: ToolDefinition['format']): void;
@@ -1,16 +1,18 @@
1
1
  // @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
2
2
  // cli/commands/install.ts — planu install: detect AI tools and install MCP entry (SPEC-236)
3
- import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
3
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync, } from 'node:fs';
4
4
  import { homedir } from 'node:os';
5
- import { dirname, join } from 'node:path';
5
+ import { dirname, isAbsolute, join } from 'node:path';
6
6
  import { bold, cyan, green, yellow, dim } from '../colors.js';
7
7
  import { PLANU_VERSION } from '../../config/version.js';
8
8
  import { confirm, select, ask } from '../interactive.js';
9
9
  import { activateLicense } from '../../engine/license-validator.js';
10
+ import { resolveStorageLayout } from '../../storage/storage-layout.js';
10
11
  // ---------------------------------------------------------------------------
11
12
  // Constants
12
13
  // ---------------------------------------------------------------------------
13
14
  const PLANU_KEY = 'planu';
15
+ const SENSITIVE_ENV_KEY = /(?:token|secret|password|api[_-]?key|license|credential)/iu;
14
16
  // ---------------------------------------------------------------------------
15
17
  // Locale helpers
16
18
  // ---------------------------------------------------------------------------
@@ -64,16 +66,16 @@ const TOOLS = [
64
66
  // ---------------------------------------------------------------------------
65
67
  // Helpers
66
68
  // ---------------------------------------------------------------------------
67
- function buildMcpEntry(licenseKey) {
68
- const entry = {
69
+ function buildMcpEntry(_licenseKey) {
70
+ const offline = process.env.PLANU_OFFLINE === '1';
71
+ return {
69
72
  command: 'npx',
70
- args: ['--prefer-online', '-y', '@planu/cli@latest'],
73
+ args: [
74
+ ...(offline ? ['--offline'] : ['--prefer-offline']),
75
+ '-y',
76
+ `@planu/cli@${PLANU_VERSION}`,
77
+ ],
71
78
  };
72
- const ownerToken = licenseKey ?? process.env.SDD_OWNER_TOKEN;
73
- if (ownerToken) {
74
- entry.env = { SDD_OWNER_TOKEN: ownerToken };
75
- }
76
- return entry;
77
79
  }
78
80
  function readJsonFile(filePath) {
79
81
  if (!existsSync(filePath)) {
@@ -81,7 +83,7 @@ function readJsonFile(filePath) {
81
83
  }
82
84
  const raw = readFileSync(filePath, 'utf-8').trim();
83
85
  if (!raw) {
84
- return {};
86
+ throw new Error(`Refusing to overwrite empty or whitespace-only JSON: ${filePath}`);
85
87
  }
86
88
  return JSON.parse(raw);
87
89
  }
@@ -99,27 +101,107 @@ function ensureParentDir(filePath) {
99
101
  mkdirSync(dir, { recursive: true });
100
102
  }
101
103
  }
102
- function writeStandardEntry(filePath, entry) {
103
- let config = {};
104
+ function emptyInstallationManifest(now = new Date().toISOString()) {
105
+ return { schemaVersion: 1, updatedAt: now, installations: [] };
106
+ }
107
+ export function readInstallationManifest(manifestPath) {
108
+ if (!existsSync(manifestPath)) {
109
+ return emptyInstallationManifest();
110
+ }
111
+ const parsed = JSON.parse(readFileSync(manifestPath, 'utf8'));
112
+ if (typeof parsed !== 'object' ||
113
+ parsed === null ||
114
+ !('schemaVersion' in parsed) ||
115
+ parsed.schemaVersion !== 1 ||
116
+ !('installations' in parsed) ||
117
+ !Array.isArray(parsed.installations)) {
118
+ throw new Error(`Unsupported or invalid installation manifest at ${manifestPath}`);
119
+ }
120
+ const manifest = parsed;
121
+ const recordsValid = manifest.installations.every((record) => {
122
+ return (isAbsolute(record.configPath) &&
123
+ typeof record.host === 'string' &&
124
+ record.host.trim().length > 0 &&
125
+ record.package === '@planu/cli' &&
126
+ /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/.test(record.version) &&
127
+ typeof record.offline === 'boolean' &&
128
+ typeof record.installedAt === 'string' &&
129
+ Number.isFinite(Date.parse(record.installedAt)));
130
+ });
131
+ if (!recordsValid) {
132
+ throw new Error(`Unsafe installation manifest at ${manifestPath}`);
133
+ }
134
+ return manifest;
135
+ }
136
+ function writeInstallationManifest(manifestPath, manifest) {
137
+ ensureParentDir(manifestPath);
138
+ const temporaryPath = `${manifestPath}.${String(process.pid)}.${String(Date.now())}.tmp`;
104
139
  try {
105
- config = readJsonFile(filePath);
140
+ writeFileSync(temporaryPath, `${JSON.stringify(manifest, null, 2)}\n`, {
141
+ encoding: 'utf8',
142
+ mode: 0o600,
143
+ });
144
+ renameSync(temporaryPath, manifestPath);
106
145
  }
107
- catch {
108
- // invalid JSON start fresh
146
+ catch (err) {
147
+ rmSync(temporaryPath, { force: true });
148
+ throw err;
109
149
  }
110
- config.mcpServers ??= {};
111
- config.mcpServers[PLANU_KEY] = entry;
112
- ensureParentDir(filePath);
113
- writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
114
150
  }
115
- function writeZedEntry(filePath, entry) {
116
- let config = {};
151
+ function writeJsonAtomically(filePath, value) {
152
+ ensureParentDir(filePath);
153
+ const temporaryPath = `${filePath}.${String(process.pid)}.${String(Date.now())}.tmp`;
154
+ const mode = existsSync(filePath) ? statSync(filePath).mode & 0o777 : 0o600;
117
155
  try {
118
- config = readJsonFile(filePath);
156
+ writeFileSync(temporaryPath, `${JSON.stringify(value, null, 2)}\n`, {
157
+ encoding: 'utf8',
158
+ mode,
159
+ });
160
+ renameSync(temporaryPath, filePath);
161
+ chmodSync(filePath, mode);
119
162
  }
120
- catch {
121
- // invalid JSON start fresh
163
+ catch (err) {
164
+ rmSync(temporaryPath, { force: true });
165
+ throw err;
122
166
  }
167
+ }
168
+ function assertCredentialFree(entry) {
169
+ if (Object.keys(entry.env ?? {}).some((key) => SENSITIVE_ENV_KEY.test(key))) {
170
+ throw new Error('[Planu] Refusing to embed credentials in an MCP host configuration');
171
+ }
172
+ }
173
+ export function recordInstallation(manifestPath, record) {
174
+ const manifest = readInstallationManifest(manifestPath);
175
+ const installations = manifest.installations.filter((item) => !(item.host === record.host && item.configPath === record.configPath));
176
+ installations.push(record);
177
+ const updated = {
178
+ schemaVersion: 1,
179
+ updatedAt: record.installedAt,
180
+ installations,
181
+ };
182
+ writeInstallationManifest(manifestPath, updated);
183
+ return updated;
184
+ }
185
+ export function removeInstallationRecords(manifestPath, removedConfigPaths) {
186
+ const manifest = readInstallationManifest(manifestPath);
187
+ const updated = {
188
+ ...manifest,
189
+ updatedAt: new Date().toISOString(),
190
+ installations: manifest.installations.filter((item) => !removedConfigPaths.has(item.configPath)),
191
+ };
192
+ writeInstallationManifest(manifestPath, updated);
193
+ return updated;
194
+ }
195
+ function writeStandardEntry(filePath, entry) {
196
+ assertCredentialFree(entry);
197
+ const config = readJsonFile(filePath);
198
+ config.mcpServers ??= {};
199
+ config.mcpServers[PLANU_KEY] = entry;
200
+ writeJsonAtomically(filePath, config);
201
+ }
202
+ function writeZedEntry(filePath, entry) {
203
+ assertCredentialFree(entry);
204
+ const config = readJsonFile(filePath);
123
205
  config.context_servers ??= {};
124
206
  const zedEntry = {
125
207
  command: { path: entry.command, args: entry.args },
@@ -128,8 +210,7 @@ function writeZedEntry(filePath, entry) {
128
210
  zedEntry.env = entry.env;
129
211
  }
130
212
  config.context_servers[PLANU_KEY] = zedEntry;
131
- ensureParentDir(filePath);
132
- writeFileSync(filePath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
213
+ writeJsonAtomically(filePath, config);
133
214
  }
134
215
  function removePlanuFromStandard(config) {
135
216
  if (!config.mcpServers) {
@@ -156,17 +237,11 @@ function removePlanuFromZed(config) {
156
237
  return { ...config, context_servers: filtered };
157
238
  }
158
239
  function removeEntry(filePath, format) {
159
- let config;
160
- try {
161
- config = readJsonFile(filePath);
162
- }
163
- catch {
164
- return; // nothing to do
165
- }
240
+ const config = readJsonFile(filePath);
166
241
  const updated = format === 'zed'
167
242
  ? removePlanuFromZed(config)
168
243
  : removePlanuFromStandard(config);
169
- writeFileSync(filePath, JSON.stringify(updated, null, 2) + '\n', 'utf-8');
244
+ writeJsonAtomically(filePath, updated);
170
245
  }
171
246
  // ---------------------------------------------------------------------------
172
247
  // License step helper (exported for tests)
@@ -182,6 +257,9 @@ export async function promptLicense() {
182
257
  if (envToken) {
183
258
  return { key: envToken, customerEmail: '', variantName: 'Pro' };
184
259
  }
260
+ if (process.env.PLANU_OFFLINE === '1') {
261
+ return null;
262
+ }
185
263
  const wantsLicense = await confirm('Do you have a Pro license key?', false);
186
264
  if (!wantsLicense) {
187
265
  return null;
@@ -294,20 +372,22 @@ async function resolveTargets(detected, installAll) {
294
372
  }
295
373
  return detected.filter((t) => t.name === choice);
296
374
  }
297
- async function installToPath(tool, targetPath, quiet, licenseKey) {
375
+ async function installToPath(tool, targetPath, scope, quiet, licenseKey) {
298
376
  const entry = buildMcpEntry(licenseKey);
377
+ const targetExisted = existsSync(targetPath);
378
+ const previousContent = targetExisted ? readFileSync(targetPath, 'utf8') : null;
299
379
  let existingConfig = {};
300
- let jsonError = false;
301
380
  try {
302
381
  if (existsSync(targetPath)) {
303
382
  existingConfig = readJsonFile(targetPath);
304
383
  }
305
384
  }
306
- catch {
307
- jsonError = true;
308
- process.stdout.write(` ${yellow('!')} ${tool.name}: config file has invalid JSON — will create a new one\n`);
385
+ catch (err) {
386
+ const detail = err instanceof Error ? err.message : String(err);
387
+ process.stdout.write(` ${yellow('!')} ${tool.name}: config file has invalid JSON — no changes made (${detail})\n`);
388
+ return false;
309
389
  }
310
- if (!jsonError && hasPlanuEntry(existingConfig, tool.format)) {
390
+ if (hasPlanuEntry(existingConfig, tool.format)) {
311
391
  if (quiet) {
312
392
  return false;
313
393
  }
@@ -324,12 +404,34 @@ async function installToPath(tool, targetPath, quiet, licenseKey) {
324
404
  else {
325
405
  writeStandardEntry(targetPath, entry);
326
406
  }
407
+ recordInstallation(resolveStorageLayout().installationManifest, {
408
+ host: tool.name,
409
+ configPath: targetPath,
410
+ format: tool.format,
411
+ scope,
412
+ package: '@planu/cli',
413
+ version: PLANU_VERSION,
414
+ offline: process.env.PLANU_OFFLINE === '1',
415
+ installedAt: new Date().toISOString(),
416
+ });
327
417
  process.stdout.write(` ${green('+')} Installed in ${bold(tool.name)} → ${dim(targetPath)}\n`);
328
418
  return true;
329
419
  }
330
420
  catch (err) {
421
+ try {
422
+ if (previousContent === null) {
423
+ rmSync(targetPath, { force: true });
424
+ }
425
+ else {
426
+ writeFileSync(targetPath, previousContent, 'utf8');
427
+ }
428
+ }
429
+ catch (rollbackError) {
430
+ const rollbackDetail = rollbackError instanceof Error ? rollbackError.message : String(rollbackError);
431
+ process.stdout.write(` ${yellow('!')} ${tool.name}: rollback failed — ${rollbackDetail}\n`);
432
+ }
331
433
  const msg = err instanceof Error ? err.message : String(err);
332
- process.stdout.write(` ${yellow('!')} ${tool.name}: failed to write — ${msg}\n`);
434
+ process.stdout.write(` ${yellow('!')} ${tool.name}: installation rolled back — ${msg}\n`);
333
435
  return false;
334
436
  }
335
437
  }
@@ -402,7 +504,7 @@ export const installCommand = {
402
504
  else {
403
505
  targetPath = tool.userScopePath;
404
506
  }
405
- const ok = await installToPath(tool, targetPath, quiet, licenseKey);
507
+ const ok = await installToPath(tool, targetPath, scope, quiet, licenseKey);
406
508
  if (ok) {
407
509
  installed++;
408
510
  }
@@ -0,0 +1,3 @@
1
+ import type { CliCommand } from '../../types/cli.js';
2
+ export declare const jobCommand: CliCommand;
3
+ //# sourceMappingURL=job.d.ts.map