@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.
- package/CHANGELOG.md +35 -0
- package/README.md +29 -25
- package/dist/cli/commands/inspect.d.ts +4 -0
- package/dist/cli/commands/inspect.js +144 -0
- package/dist/cli/commands/install.d.ts +19 -1
- package/dist/cli/commands/install.js +145 -43
- package/dist/cli/commands/job.d.ts +3 -0
- package/dist/cli/commands/job.js +119 -0
- package/dist/cli/commands/offline.d.ts +15 -0
- package/dist/cli/commands/offline.js +132 -0
- package/dist/cli/commands/serve.js +4 -0
- package/dist/cli/commands/spec.js +1 -1
- package/dist/cli/commands/storage.d.ts +3 -0
- package/dist/cli/commands/storage.js +102 -0
- package/dist/cli/commands/uninstall.d.ts +10 -0
- package/dist/cli/commands/uninstall.js +93 -7
- package/dist/cli/commands/validate.js +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/router.js +9 -1
- package/dist/config/crash-shield-framework-rules.json +93 -0
- package/dist/config/environment-schema.json +149 -0
- package/dist/config/hardcode-exceptions.json +4 -0
- package/dist/config/license-plans.json +7 -0
- package/dist/config/native-release-public-key.pem +3 -0
- package/dist/config/native-targets.json +87 -0
- package/dist/config/product-public.d.ts +89 -0
- package/dist/config/product-public.js +140 -0
- package/dist/config/product-public.json +312 -0
- package/dist/config/product-public.ts +148 -0
- package/dist/config/release-compatibility.json +13 -0
- package/dist/config/release-policy.json +26 -0
- package/dist/config/runtime-policy.json +44 -0
- package/dist/config/skill-templates/planu-validate.md +7 -4
- package/dist/config/subagent-templates/planu-spec-implementer.md +7 -3
- package/dist/config/subagent-templates/planu-validator.md +10 -5
- package/dist/config/technology-registry.json +120 -0
- package/dist/config/version.js +7 -8
- package/dist/config/version.ts +10 -7
- package/dist/engine/abortable-process-runner.js +40 -9
- package/dist/engine/advanced-testing/accessibility-checker.js +12 -14
- package/dist/engine/advanced-testing/mutation-advisor.js +3 -4
- package/dist/engine/advanced-testing/property-based.js +2 -3
- package/dist/engine/advanced-testing/test-data-advisor.js +2 -3
- package/dist/engine/agent-generator.js +2 -1
- package/dist/engine/agent-handoff-store.js +2 -1
- package/dist/engine/agent-prompt-generator.js +7 -5
- package/dist/engine/agent-telemetry.js +2 -1
- package/dist/engine/ai-integration/gemini/extensions-advisor.js +41 -9
- package/dist/engine/ambiguity-detector.js +12 -11
- package/dist/engine/analyzer/db-engine.js +2 -3
- package/dist/engine/analyzer/detectors.js +13 -14
- package/dist/engine/analyzer/env-setup.js +9 -10
- package/dist/engine/analyzer-env-scanner/env-example.js +7 -8
- package/dist/engine/api-spec-generator/graphql-parser.js +2 -2
- package/dist/engine/api-validation/graphql-schema-validator.js +2 -1
- package/dist/engine/api-validation/openapi-impl-validator.js +6 -7
- package/dist/engine/architecture-detector.js +10 -8
- package/dist/engine/auth/config.d.ts +1 -1
- package/dist/engine/auth/config.js +4 -3
- package/dist/engine/auto-updater/atomic-upgrade.d.ts +8 -0
- package/dist/engine/auto-updater/atomic-upgrade.js +381 -0
- package/dist/engine/auto-updater/config-detector.js +9 -3
- package/dist/engine/auto-updater/config-patcher.d.ts +0 -4
- package/dist/engine/auto-updater/config-patcher.js +10 -15
- package/dist/engine/auto-updater/index.d.ts +3 -1
- package/dist/engine/auto-updater/index.js +44 -30
- package/dist/engine/auto-updater/npm-registry.js +10 -2
- package/dist/engine/auto-updater/release-verifier.d.ts +3 -0
- package/dist/engine/auto-updater/release-verifier.js +112 -0
- package/dist/engine/auto-updater/upgrade-lock.d.ts +6 -0
- package/dist/engine/auto-updater/upgrade-lock.js +28 -0
- package/dist/engine/auto-updater/upgrade-trust-state.d.ts +7 -0
- package/dist/engine/auto-updater/upgrade-trust-state.js +59 -0
- package/dist/engine/autopilot/audit-logger.js +2 -5
- package/dist/engine/best-practices-library.js +2 -1
- package/dist/engine/browser-validator.js +2 -1
- package/dist/engine/build-tool-detector.js +3 -2
- package/dist/engine/ci-generator/context-builders.js +7 -5
- package/dist/engine/ci-generator/stack-detector.js +0 -2
- package/dist/engine/ci-generator/yaml-builder.js +0 -2
- package/dist/engine/claude-config-auditor/rules-auditor.js +4 -3
- package/dist/engine/code-transforms/typescript/ast-utils.js +2 -3
- package/dist/engine/complexity-budget/trivial-detector.js +2 -1
- package/dist/engine/compliance-test-generator/index.js +7 -2
- package/dist/engine/compliance-test-generator/test-formatter.js +2 -2
- package/dist/engine/config-health/mcp-config-checker.js +2 -1
- package/dist/engine/config-health/ts-checker-scripts.js +4 -3
- package/dist/engine/config-health/ts-checker.js +3 -2
- package/dist/engine/convention-injector.js +5 -7
- package/dist/engine/convention-scanner/convention-parser.js +3 -2
- package/dist/engine/core-bridge-duplicate-blocks.d.ts +3 -0
- package/dist/engine/core-bridge-duplicate-blocks.js +57 -0
- package/dist/engine/core-bridge-gaps.d.ts +4 -0
- package/dist/engine/core-bridge-gaps.js +75 -0
- package/dist/engine/core-bridge.d.ts +9 -9
- package/dist/engine/core-bridge.js +196 -283
- package/dist/engine/cost-tracking/ledger.js +2 -5
- package/dist/engine/coverage-gap-analyzer.js +10 -1
- package/dist/engine/crash-shield/detectors/framework-detector.d.ts +2 -0
- package/dist/engine/crash-shield/detectors/framework-detector.js +110 -192
- package/dist/engine/crash-shield/detectors/typescript-detector.js +2 -1
- package/dist/engine/dashboard/data-loader.js +2 -1
- package/dist/engine/data-projects-gc/gc-runner.d.ts +7 -0
- package/dist/engine/data-projects-gc/gc-runner.js +113 -3
- package/dist/engine/data-projects-gc/scanner.js +5 -1
- package/dist/engine/decision-store.js +11 -14
- package/dist/engine/deleter/core.js +5 -5
- package/dist/engine/dep-auditor/abandonment-data.js +2 -1
- package/dist/engine/dep-auditor/abandonment-registry.js +3 -1
- package/dist/engine/dep-auditor/cve-fetcher.js +3 -0
- package/dist/engine/dep-auditor/dep-duplicates-detector.js +36 -4
- package/dist/engine/dep-auditor/license-registry.js +2 -0
- package/dist/engine/dependency-evaluator.d.ts +14 -0
- package/dist/engine/dependency-evaluator.js +81 -0
- package/dist/engine/deploy/providers/fly.js +7 -7
- package/dist/engine/deploy/providers/netlify.js +7 -7
- package/dist/engine/deploy/providers/railway.js +10 -12
- package/dist/engine/deploy/providers/vercel.js +7 -9
- package/dist/engine/deprecation-scanner/pattern-loader.js +0 -2
- package/dist/engine/desktop-detector.js +2 -3
- package/dist/engine/detect-duplication.js +2 -1
- package/dist/engine/detectors/advanced-framework-detector/css-state-detector.js +2 -1
- package/dist/engine/detectors/advanced-framework-detector/legacy-detector.js +2 -3
- package/dist/engine/detectors/advanced-framework-detector/modern-detector.js +3 -4
- package/dist/engine/detectors/agent-framework-detector.js +3 -2
- package/dist/engine/detectors/ai-native-detector.js +4 -6
- package/dist/engine/detectors/cache-db-detector.js +4 -3
- package/dist/engine/detectors/cicd-detector.js +4 -3
- package/dist/engine/detectors/deployment-detector.js +11 -12
- package/dist/engine/detectors/frontend-perf-detector.js +14 -9
- package/dist/engine/detectors/library-detector-multilang-a.js +16 -3
- package/dist/engine/detectors/library-detector-node.js +14 -4
- package/dist/engine/detectors/library-detector-python.js +7 -1
- package/dist/engine/detectors/library-detector.js +0 -2
- package/dist/engine/detectors/llm-detector/provider-maps.js +3 -2
- package/dist/engine/detectors/mcp-candidate-detector.js +12 -16
- package/dist/engine/detectors/mfe-detector.js +6 -7
- package/dist/engine/detectors/monitoring-detector.js +4 -3
- package/dist/engine/detectors/otel-detector.js +3 -2
- package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -2
- package/dist/engine/detectors/otel-ecosystem-detectors.js +4 -3
- package/dist/engine/detectors/platform-specialty-detector.js +3 -5
- package/dist/engine/detectors/template-engine-detector.js +3 -4
- package/dist/engine/doc-generator/builders.js +2 -3
- package/dist/engine/doc-generator/mobile-distribution-guide.js +13 -17
- package/dist/engine/doc-generator/portal/dirty-flag-map.d.ts +2 -2
- package/dist/engine/doc-generator/portal/portal-regenerator.js +3 -47
- package/dist/engine/domain-detector.js +3 -6
- package/dist/engine/dynamic-knowledge/knowledge-cache.js +3 -4
- package/dist/engine/dynamic-knowledge/knowledge-merger.js +17 -2
- package/dist/engine/dynamic-knowledge/web-researcher.js +15 -14
- package/dist/engine/dynamic-migration-detector/manifest-readers-extended.js +0 -2
- package/dist/engine/e2e-test-generator.js +4 -3
- package/dist/engine/ecosystem-absorber/knowledge-cache.js +2 -1
- package/dist/engine/ecosystem-absorber/platform-crawler.js +2 -2
- package/dist/engine/escalator/retry-counter.js +2 -1
- package/dist/engine/evidence-gates/artifact-reader.d.ts +6 -0
- package/dist/engine/evidence-gates/artifact-reader.js +105 -21
- package/dist/engine/evidence-gates/lifecycle-gate.d.ts +2 -1
- package/dist/engine/evidence-gates/lifecycle-gate.js +54 -0
- package/dist/engine/execution/context.d.ts +19 -0
- package/dist/engine/execution/context.js +127 -0
- package/dist/engine/execution/deadline-io.d.ts +21 -0
- package/dist/engine/execution/deadline-io.js +45 -0
- package/dist/engine/execution/job-executor.d.ts +16 -0
- package/dist/engine/execution/job-executor.js +140 -0
- package/dist/engine/execution/job-runtime.d.ts +78 -0
- package/dist/engine/execution/job-runtime.js +220 -0
- package/dist/engine/execution/native-relevance-scorer.d.ts +6 -0
- package/dist/engine/execution/native-relevance-scorer.js +64 -0
- package/dist/engine/execution/native-worker-dispatch.d.ts +3 -0
- package/dist/engine/execution/native-worker-dispatch.js +46 -0
- package/dist/engine/execution/native-worker-protocol.d.ts +6 -0
- package/dist/engine/execution/native-worker-protocol.js +33 -0
- package/dist/engine/execution/native-worker-runtime.d.ts +4 -0
- package/dist/engine/execution/native-worker-runtime.js +177 -0
- package/dist/engine/execution/native-worker-thread.d.ts +2 -0
- package/dist/engine/execution/native-worker-thread.js +66 -0
- package/dist/engine/execution/operation-journal.d.ts +66 -0
- package/dist/engine/execution/operation-journal.js +260 -0
- package/dist/engine/execution/outbox-worker.d.ts +31 -0
- package/dist/engine/execution/outbox-worker.js +192 -0
- package/dist/engine/execution/validate-job-executor.d.ts +24 -0
- package/dist/engine/execution/validate-job-executor.js +342 -0
- package/dist/engine/execution/validate-job-payload.d.ts +5 -0
- package/dist/engine/execution/validate-job-payload.js +87 -0
- package/dist/engine/execution/validate-job-recovery.d.ts +4 -0
- package/dist/engine/execution/validate-job-recovery.js +47 -0
- package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
- package/dist/engine/execution/validate-worker-runtime.js +100 -0
- package/dist/engine/execution/validate-worker-thread.d.ts +2 -0
- package/dist/engine/execution/validate-worker-thread.js +71 -0
- package/dist/engine/execution-plan/desktop-distribution.js +3 -7
- package/dist/engine/execution-plan/mobile-distribution.js +4 -9
- package/dist/engine/execution-plan/phases.js +4 -5
- package/dist/engine/execution-plan/plan-utils.js +8 -5
- package/dist/engine/facilitate/context-loader.js +3 -9
- package/dist/engine/figma/code-connect-fetcher.js +9 -8
- package/dist/engine/filesystem-watcher/index.d.ts +3 -3
- package/dist/engine/filesystem-watcher/index.js +5 -5
- package/dist/engine/framework-detector.js +14 -15
- package/dist/engine/git/planu-autocommit.js +8 -7
- package/dist/engine/git/repository-probe.d.ts +3 -0
- package/dist/engine/git/repository-probe.js +13 -0
- package/dist/engine/global-rules-manager.js +2 -2
- package/dist/engine/handoff-artifacts/io.js +2 -3
- package/dist/engine/handoff-artifacts/schemas/red-tests-handoff.js +8 -1
- package/dist/engine/handoff-artifacts/schemas.d.ts +4 -0
- package/dist/engine/handoff-artifacts/schemas.js +5 -0
- package/dist/engine/hook-generator/stack-hook-templates.js +4 -4
- package/dist/engine/hooks/config-loader.js +1 -1
- package/dist/engine/hooks/context-injector.js +4 -7
- package/dist/engine/hooks/file-watcher.js +1 -14
- package/dist/engine/hooks-reconciler.js +6 -4
- package/dist/engine/infrastructure/component-mapper.js +5 -7
- package/dist/engine/infrastructure/docker-compose-generator.js +8 -10
- package/dist/engine/infrastructure/index.js +6 -3
- package/dist/engine/infrastructure/kubernetes-generator.js +2 -2
- package/dist/engine/infrastructure/railway-generator.js +10 -8
- package/dist/engine/infrastructure/signal-detector.js +6 -8
- package/dist/engine/infrastructure/terraform-generator.js +6 -8
- package/dist/engine/legal-compliance/detector.js +3 -2
- package/dist/engine/local-first/storage-advisor.js +5 -6
- package/dist/engine/macos-keychain-native-port.d.ts +5 -0
- package/dist/engine/macos-keychain-native-port.js +26 -0
- package/dist/engine/marketplace-fetcher/cache.js +3 -1
- package/dist/engine/mcp-config/mcp-config-writer.d.ts +2 -2
- package/dist/engine/mcp-config/mcp-config-writer.js +10 -8
- package/dist/engine/migration/db-migrator.js +2 -5
- package/dist/engine/migration/equivalence-mapper.js +12 -13
- package/dist/engine/migration/service-catalogs.js +6 -7
- package/dist/engine/migration/service-migrator-catalogs.js +6 -7
- package/dist/engine/mobile-detector-ios.js +2 -3
- package/dist/engine/mobile-detector.js +16 -4
- package/dist/engine/model-router/complexity-analyzer.js +4 -7
- package/dist/engine/multi-agent-review/security-analyzer.js +3 -1
- package/dist/engine/multi-app-detector/app-type.js +26 -21
- package/dist/engine/multi-app-detector/core.js +3 -2
- package/dist/engine/multi-teammate-review/disagreement-counter.js +2 -1
- package/dist/engine/multi-teammate-review/panel-orchestrator.js +0 -2
- package/dist/engine/mutation-config-generator.js +10 -7
- package/dist/engine/native-capability-policy.d.ts +4 -0
- package/dist/engine/native-capability-policy.js +24 -0
- package/dist/engine/native-platform.d.ts +3 -0
- package/dist/engine/native-platform.js +44 -0
- package/dist/engine/native-runtime-handshake.d.ts +20 -0
- package/dist/engine/native-runtime-handshake.js +230 -0
- package/dist/engine/network-policy.d.ts +27 -0
- package/dist/engine/network-policy.js +174 -0
- package/dist/engine/next-spec-resolver/dependency-filter.js +2 -22
- package/dist/engine/nfr-profile-detector.js +12 -16
- package/dist/engine/nli-keywords.js +8 -9
- package/dist/engine/oauth/config-guard.js +4 -5
- package/dist/engine/observability/local-execution-spans.d.ts +15 -0
- package/dist/engine/observability/local-execution-spans.js +63 -0
- package/dist/engine/orchestrator/runtime.js +0 -1
- package/dist/engine/package-registry.js +2 -6
- package/dist/engine/performance-analyzer.js +2 -5
- package/dist/engine/permissions-merger/stack-detectors.js +5 -5
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +39 -0
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +1310 -0
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +39 -0
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +1310 -0
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +38 -0
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +1310 -0
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +38 -0
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +1310 -0
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +38 -0
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +1310 -0
- package/dist/engine/platform-detector/desktop.js +15 -2
- package/dist/engine/platform-detector/extensions.js +2 -1
- package/dist/engine/platform-detector/games.js +2 -1
- package/dist/engine/platform-detector.js +3 -2
- package/dist/engine/platform-engineering/idp-detector.js +2 -1
- package/dist/engine/plugin-installer/stack-matcher.js +9 -17
- package/dist/engine/plugins/lifecycle.js +6 -2
- package/dist/engine/prior-decisions/contradiction-detector.js +60 -30
- package/dist/engine/project-dna/stack-detector.js +15 -17
- package/dist/engine/project-graph/builder.js +11 -0
- package/dist/engine/project-graph/cache.js +1 -1
- package/dist/engine/project-graph/freshness-projection.d.ts +16 -0
- package/dist/engine/project-graph/freshness-projection.js +95 -0
- package/dist/engine/project-graph/index.d.ts +1 -0
- package/dist/engine/project-graph/index.js +1 -0
- package/dist/engine/project-graph/query.js +15 -25
- package/dist/engine/project-health-checker.js +3 -4
- package/dist/engine/project-scanner/stack-detector.js +17 -17
- package/dist/engine/property-test-generator.js +2 -3
- package/dist/engine/qa-gate.d.ts +1 -0
- package/dist/engine/qa-gate.js +6 -4
- package/dist/engine/quality-gates/gate-catalog.js +47 -46
- package/dist/engine/quality-gates/gate-injector.js +9 -4
- package/dist/engine/registry/core.js +0 -2
- package/dist/engine/registry/loader.js +9 -12
- package/dist/engine/registry/matcher.js +129 -24
- package/dist/engine/resilience-detector/concurrency-detector.js +4 -4
- package/dist/engine/resilience-detector/middleware-detector.js +11 -13
- package/dist/engine/resilience-detector/validation-detector.js +17 -4
- package/dist/engine/reverse-engineer/config-analyzer.js +9 -8
- package/dist/engine/reverse-engineer/orchestrator.js +5 -9
- package/dist/engine/reverse-engineer/test-file-parser.js +6 -3
- package/dist/engine/rules-generator/index.js +6 -5
- package/dist/engine/runtime-policy.d.ts +7 -0
- package/dist/engine/runtime-policy.js +101 -0
- package/dist/engine/runtime-security/checkers/content-security.js +21 -6
- package/dist/engine/runtime-security/checkers/file-permissions.js +0 -2
- package/dist/engine/safety/atomic-write-file.js +20 -9
- package/dist/engine/safety/atomic-writer.js +10 -3
- package/dist/engine/safety/cross-process-lock.d.ts +3 -40
- package/dist/engine/safety/cross-process-lock.js +268 -272
- package/dist/engine/safety/file-mutex.d.ts +2 -9
- package/dist/engine/safety/file-mutex.js +155 -87
- package/dist/engine/safety/health-monitor.js +15 -6
- package/dist/engine/safety/lock-lease-store.d.ts +79 -0
- package/dist/engine/safety/lock-lease-store.js +372 -0
- package/dist/engine/safety/lock-scavenger.d.ts +2 -5
- package/dist/engine/safety/lock-scavenger.js +158 -76
- package/dist/engine/safety/lock-staleness.js +4 -1
- package/dist/engine/safety/obsolete-lock-guard.d.ts +8 -0
- package/dist/engine/safety/obsolete-lock-guard.js +31 -0
- package/dist/engine/safety/transaction.js +3 -3
- package/dist/engine/sandbox/index.js +2 -1
- package/dist/engine/sandbox/runner-detect.js +3 -2
- package/dist/engine/sandbox/runner-docker.js +4 -3
- package/dist/engine/scan-project/module-discoverer.js +3 -2
- package/dist/engine/schema-generator.js +16 -9
- package/dist/engine/security-analyzer/criteria-generator.js +2 -3
- package/dist/engine/self-healing/healer.js +4 -4
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +1 -2
- package/dist/engine/session-safeguard/learnings-buffer.js +42 -65
- package/dist/engine/shared-agent-memory.js +66 -74
- package/dist/engine/skill-adapter/command-rewriter.js +3 -2
- package/dist/engine/skill-adapter/index.js +3 -3
- package/dist/engine/skill-adapter/placeholder-map.js +3 -2
- package/dist/engine/skill-bootstrap/stack-matcher.js +47 -48
- package/dist/engine/skill-generation/stack-content-generator.js +0 -2
- package/dist/engine/skill-generator/workflow-skill-generator.js +2 -1
- package/dist/engine/skill-registry/ttl-refresh.js +3 -1
- package/dist/engine/skills/skills-fetcher.js +3 -6
- package/dist/engine/skills-reconciler.js +19 -39
- package/dist/engine/spec-coverage/test-finder.js +7 -6
- package/dist/engine/spec-diff-engine.js +3 -3
- package/dist/engine/spec-generator/api-key-resolver.d.ts +1 -1
- package/dist/engine/spec-generator/api-key-resolver.js +3 -24
- package/dist/engine/spec-generators/issue-extractor.js +9 -3
- package/dist/engine/spec-migrator/drift-detector.js +5 -13
- package/dist/engine/spec-migrator/filesystem-import.js +14 -10
- package/dist/engine/spec-migrator/planu-canonical-policy.js +10 -1
- package/dist/engine/spec-migrator/strict-planu-cleanup.js +24 -25
- package/dist/engine/spec-registry/adapter.d.ts +0 -5
- package/dist/engine/spec-registry/adapter.js +45 -46
- package/dist/engine/spec-registry/client.js +2 -0
- package/dist/engine/spec-source-sync.js +3 -2
- package/dist/engine/spec-templates/custom-loader.js +2 -3
- package/dist/engine/spec-templates/templates-domain-specific.js +8 -5
- package/dist/engine/spec-templates/templates-perf-integration.js +2 -3
- package/dist/engine/stack-auditor/manifest-reader.js +0 -2
- package/dist/engine/staleness/stale-implementing.js +7 -7
- package/dist/engine/tdd-scaffold-generator.js +24 -11
- package/dist/engine/teammate-router/green-phase-verifier.js +2 -1
- package/dist/engine/teammate-router/red-phase-verifier.js +2 -1
- package/dist/engine/technology-registry.d.ts +11 -0
- package/dist/engine/technology-registry.js +142 -0
- package/dist/engine/telemetry/error-reporter.d.ts +1 -2
- package/dist/engine/telemetry/error-reporter.js +11 -18
- package/dist/engine/telemetry/health-checker.js +5 -14
- package/dist/engine/telemetry/index.d.ts +0 -1
- package/dist/engine/telemetry/index.js +0 -1
- package/dist/engine/telemetry/stance.js +3 -2
- package/dist/engine/telemetry/telemetry-client.d.ts +1 -5
- package/dist/engine/telemetry/telemetry-client.js +45 -29
- package/dist/engine/telemetry/telemetry-store.d.ts +3 -3
- package/dist/engine/telemetry/telemetry-store.js +30 -23
- package/dist/engine/test-framework-detector/detectors.js +8 -8
- package/dist/engine/test-framework-detector/strategy.js +8 -9
- package/dist/engine/test-generators/agent-test-templates.js +2 -3
- package/dist/engine/test-generators/contract-test-generator.d.ts +1 -1
- package/dist/engine/test-generators/contract-test-generator.js +9 -202
- package/dist/engine/test-generators/platform-test-templates-b.js +2 -3
- package/dist/engine/test-generators/platform-test-templates.js +2 -5
- package/dist/engine/test-mocks-generator.js +4 -3
- package/dist/engine/test-plan-generator.js +30 -12
- package/dist/engine/test-scaffold-generator/advanced-scaffold.js +4 -5
- package/dist/engine/test-scaffold-generator/unit-scaffold.js +5 -6
- package/dist/engine/timing/budget.d.ts +6 -17
- package/dist/engine/timing/budget.js +80 -64
- package/dist/engine/tool-groups/group-manager.js +3 -3
- package/dist/engine/universal-rules/installer.js +1 -1
- package/dist/engine/universal-rules/rules/planu-modes.js +2 -0
- package/dist/engine/universal-rules/rules/planu-release-policy.js +1 -0
- package/dist/engine/update-notifier.js +8 -5
- package/dist/engine/validation/approved-spec-portability.d.ts +12 -0
- package/dist/engine/validation/approved-spec-portability.js +107 -0
- package/dist/engine/validation/durable-validation.d.ts +36 -0
- package/dist/engine/validation/durable-validation.js +335 -0
- package/dist/engine/validation/validation-freshness.d.ts +36 -0
- package/dist/engine/validation/validation-freshness.js +427 -0
- package/dist/engine/validation/validation-receipt-codec.d.ts +13 -0
- package/dist/engine/validation/validation-receipt-codec.js +182 -0
- package/dist/engine/validation/validation-receipt.d.ts +59 -0
- package/dist/engine/validation/validation-receipt.js +282 -0
- package/dist/engine/validation/validation-source-policy.d.ts +4 -0
- package/dist/engine/validation/validation-source-policy.js +16 -0
- package/dist/engine/validation/validation-submission.d.ts +36 -0
- package/dist/engine/validation/validation-submission.js +128 -0
- package/dist/engine/validation-evidence-ledger.js +41 -0
- package/dist/engine/validation-impact-planner.js +25 -9
- package/dist/engine/validator/spec-compliance-runner.d.ts +1 -1
- package/dist/engine/validator/spec-compliance-runner.js +17 -8
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/validator.js +2 -1
- package/dist/engine/verify-integrations/index.js +1 -1
- package/dist/engine/version-resolver.js +5 -6
- package/dist/engine/web-fetcher/stack-advisor.js +156 -92
- package/dist/engine/web-fetcher/stack-detector.js +114 -54
- package/dist/engine/workspace-manager.js +3 -2
- package/dist/errors/classified-degradation.d.ts +3 -0
- package/dist/errors/classified-degradation.js +10 -0
- package/dist/errors/degradation-sink.d.ts +3 -0
- package/dist/errors/degradation-sink.js +5 -0
- package/dist/errors/error-taxonomy.d.ts +12 -0
- package/dist/errors/error-taxonomy.js +62 -0
- package/dist/hosts/claude-code/ux/mcp-prompts.js +10 -4
- package/dist/hosts/claude-code/ux/mcp-resources.js +4 -2
- package/dist/hosts/codex/config-scaffold.js +4 -3
- package/dist/hosts/gemini/config-scaffold.js +2 -1
- package/dist/hosts/gemini/multimodal-spec-flow.js +7 -4
- package/dist/index.js +21 -6
- package/dist/resources/patterns.js +3 -1
- package/dist/resources/specs.js +3 -1
- package/dist/resources/templates.js +3 -1
- package/dist/security/adapters/environment.d.ts +12 -0
- package/dist/security/adapters/environment.js +25 -0
- package/dist/security/adapters/linux-secret-service.d.ts +8 -0
- package/dist/security/adapters/linux-secret-service.js +60 -0
- package/dist/security/adapters/macos-keychain.d.ts +18 -0
- package/dist/security/adapters/macos-keychain.js +90 -0
- package/dist/security/adapters/windows-credential-manager.d.ts +8 -0
- package/dist/security/adapters/windows-credential-manager.js +58 -0
- package/dist/security/redactor.d.ts +5 -0
- package/dist/security/redactor.js +58 -0
- package/dist/security/secret-field.d.ts +5 -0
- package/dist/security/secret-field.js +17 -0
- package/dist/security/secret-migration.d.ts +3 -0
- package/dist/security/secret-migration.js +123 -0
- package/dist/security/secret-provider.d.ts +23 -0
- package/dist/security/secret-provider.js +145 -0
- package/dist/security/secure-json.d.ts +3 -0
- package/dist/security/secure-json.js +29 -0
- package/dist/storage/api-surfaces-store.js +2 -2
- package/dist/storage/approval-operation-lock.d.ts +1 -1
- package/dist/storage/approval-operation-lock.js +5 -3
- package/dist/storage/audit-trail-store.d.ts +1 -1
- package/dist/storage/audit-trail-store.js +48 -62
- package/dist/storage/autopilot-log-store.js +12 -5
- package/dist/storage/base-store.d.ts +8 -8
- package/dist/storage/base-store.js +57 -20
- package/dist/storage/checkpoint-store.js +5 -2
- package/dist/storage/comments-store.js +2 -2
- package/dist/storage/compliance-audit-store.js +5 -2
- package/dist/storage/compliance-gate-config-store.js +7 -4
- package/dist/storage/compliance-store.js +2 -2
- package/dist/storage/context-profile-store.js +2 -2
- package/dist/storage/crash-shield-store.js +8 -4
- package/dist/storage/feedback-store.js +10 -6
- package/dist/storage/figma-store.js +8 -4
- package/dist/storage/file-mutex.js +9 -1
- package/dist/storage/gaps-log.js +7 -4
- package/dist/storage/global-projects-store.js +4 -2
- package/dist/storage/ideas-store.js +2 -2
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/knowledge-store/knowledge.js +27 -33
- package/dist/storage/lessons-store.js +2 -2
- package/dist/storage/license-store.js +13 -41
- package/dist/storage/migrations/canonical-storage.d.ts +15 -0
- package/dist/storage/migrations/canonical-storage.js +599 -0
- package/dist/storage/oauth-store.js +36 -8
- package/dist/storage/path-resolver.js +16 -3
- package/dist/storage/pr-store.js +2 -2
- package/dist/storage/project-drift-store.js +20 -8
- package/dist/storage/project-identity.d.ts +32 -0
- package/dist/storage/project-identity.js +194 -0
- package/dist/storage/project-resolver.js +14 -7
- package/dist/storage/release-notes-store.js +2 -6
- package/dist/storage/runtime-db.d.ts +186 -0
- package/dist/storage/runtime-db.js +1054 -0
- package/dist/storage/schema-registry.d.ts +5 -0
- package/dist/storage/schema-registry.js +74 -0
- package/dist/storage/sentry-store.js +20 -9
- package/dist/storage/session-state-store.js +12 -5
- package/dist/storage/session-store.js +12 -4
- package/dist/storage/skill-registry-storage.d.ts +1 -1
- package/dist/storage/skill-registry-storage.js +13 -11
- package/dist/storage/slack-store.js +10 -5
- package/dist/storage/spec-store.js +31 -24
- package/dist/storage/status-store/file-lock.js +31 -9
- package/dist/storage/status-store/self-healing.js +10 -5
- package/dist/storage/status-store/version-sync.js +8 -6
- package/dist/storage/steering-store.js +2 -2
- package/dist/storage/storage-bundle.d.ts +5 -0
- package/dist/storage/storage-bundle.js +117 -0
- package/dist/storage/storage-catalog-validation.d.ts +3 -0
- package/dist/storage/storage-catalog-validation.js +20 -0
- package/dist/storage/storage-catalog.d.ts +25 -0
- package/dist/storage/storage-catalog.js +390 -0
- package/dist/storage/storage-layout.d.ts +24 -0
- package/dist/storage/storage-layout.js +101 -0
- package/dist/storage/storybook-store.js +2 -2
- package/dist/storage/supabase-store.js +24 -6
- package/dist/storage/tdd-policy-store.js +8 -6
- package/dist/storage/tech-debt-store.js +3 -3
- package/dist/storage/technology-selection-store.d.ts +1 -1
- package/dist/storage/technology-selection-store.js +6 -3
- package/dist/storage/token-cache-store.js +3 -3
- package/dist/storage/token-ledger-store.js +13 -8
- package/dist/storage/transition-log.js +7 -4
- package/dist/storage/trash-store.js +15 -6
- package/dist/storage/vector-store/migrator.js +7 -2
- package/dist/storage/vector-store/sqlite-adapter.js +4 -1
- package/dist/storage/webhook-server-store.js +2 -2
- package/dist/tools/api-spec-generator-handler.js +3 -2
- package/dist/tools/auto-update-handler.d.ts +1 -1
- package/dist/tools/auto-update-handler.js +1 -1
- package/dist/tools/browser-validate-handler.js +2 -1
- package/dist/tools/challenge-spec/platform-challenge-scenarios-b.js +8 -5
- package/dist/tools/challenge-spec/scenarios-desktop.js +8 -3
- package/dist/tools/challenge-spec/scenarios-failure.js +7 -2
- package/dist/tools/challenge-spec/security-challenge-scenarios.js +3 -3
- package/dist/tools/clarify-requirements/multiple-choice.js +53 -41
- package/dist/tools/comments-handler.js +2 -3
- package/dist/tools/compliance-test-handler.js +2 -2
- package/dist/tools/configure-telemetry.js +11 -11
- package/dist/tools/create-spec/auto-pipeline.js +13 -1
- package/dist/tools/create-spec/autopilot-analyzer.d.ts +1 -1
- package/dist/tools/create-spec/autopilot-analyzer.js +2 -4
- package/dist/tools/create-spec/mcp-tool-contract.d.ts +10 -4
- package/dist/tools/create-spec/mcp-tool-contract.js +7 -36
- package/dist/tools/create-spec/post-creation.d.ts +2 -1
- package/dist/tools/create-spec/post-creation.js +56 -54
- package/dist/tools/create-spec/relevance-scorer.d.ts +1 -1
- package/dist/tools/create-spec/relevance-scorer.js +17 -1
- package/dist/tools/create-spec/spec-builder.js +2 -12
- package/dist/tools/create-spec/spec-created-outbox-consumer.d.ts +14 -0
- package/dist/tools/create-spec/spec-created-outbox-consumer.js +176 -0
- package/dist/tools/create-spec.js +385 -520
- package/dist/tools/define-ui-contract/agent-interaction-contract.js +2 -4
- package/dist/tools/define-ui-contract-desktop/desktop-contract.js +12 -4
- package/dist/tools/define-ui-contract-desktop/native-contract.js +7 -3
- package/dist/tools/define-ui-contract-extensions.js +2 -3
- package/dist/tools/define-ui-contract-mobile.js +5 -9
- package/dist/tools/define-ui-contract-web/component-tree.js +4 -3
- package/dist/tools/define-ui-contract.js +7 -4
- package/dist/tools/deploy/deploy-spec.js +2 -4
- package/dist/tools/deploy/deploy-status.js +2 -4
- package/dist/tools/design-schema/nosql-category-schemas.js +2 -3
- package/dist/tools/design-schema-sql/migrations.js +3 -2
- package/dist/tools/design-schema-sql/tables.js +4 -1
- package/dist/tools/design-schema.js +4 -3
- package/dist/tools/feedback-handler.js +2 -4
- package/dist/tools/gc-data-projects.js +5 -5
- package/dist/tools/generate-execution-plan.js +3 -4
- package/dist/tools/generate-sub-agent.js +2 -1
- package/dist/tools/generate-tests/generators/a11y-tests-generator.js +5 -4
- package/dist/tools/generate-tests/generators/advanced-testing-generator.js +5 -4
- package/dist/tools/generate-tests/generators/concurrency-test-generator/js-templates.js +9 -4
- package/dist/tools/generate-tests/generators/concurrency-test-generator.js +8 -4
- package/dist/tools/generate-tests/generators/database/detectors.js +9 -3
- package/dist/tools/generate-tests/generators/database/index.js +2 -4
- package/dist/tools/generate-tests/generators/event-test-generator.js +5 -4
- package/dist/tools/generate-tests/generators/game-tests-generator.js +2 -1
- package/dist/tools/generate-tests/generators/graphql-test-generator.js +11 -5
- package/dist/tools/generate-tests/generators/grpc-test-generator.js +2 -3
- package/dist/tools/generate-tests/generators/llm-security-test-generator.js +4 -3
- package/dist/tools/generate-tests/generators/local-first-test-generator.js +4 -3
- package/dist/tools/generate-tests/generators/mcp-tests-generator.js +11 -9
- package/dist/tools/generate-tests/generators/microservices/index.js +2 -3
- package/dist/tools/generate-tests/generators/otel-test-generator.js +6 -3
- package/dist/tools/generate-tests/generators/security/detectors.js +2 -5
- package/dist/tools/generate-tests/generators/security/index.js +2 -4
- package/dist/tools/generate-tests/generators/supply-chain-test-generator.js +2 -3
- package/dist/tools/generate-tests/generators/visual-regression-generator.js +14 -17
- package/dist/tools/generate-tests/generators/websocket-test-generator.js +2 -3
- package/dist/tools/generate-tests/test-helpers.js +11 -12
- package/dist/tools/generate-tests-content.js +4 -3
- package/dist/tools/generate-tests.js +7 -4
- package/dist/tools/git/git-helpers.d.ts +0 -2
- package/dist/tools/git/git-helpers.js +7 -7
- package/dist/tools/github-pr-handler.js +10 -3
- package/dist/tools/heal-spec-docs.js +6 -53
- package/dist/tools/hook-generator-handler.js +6 -6
- package/dist/tools/init-constitution/platform-principles.js +4 -2
- package/dist/tools/init-project/agents-md-writer.js +14 -5
- package/dist/tools/init-project/claude-md-generator.js +19 -12
- package/dist/tools/init-project/handler.js +165 -73
- package/dist/tools/init-project/host-assets-writer.d.ts +1 -1
- package/dist/tools/init-project/host-assets-writer.js +4 -2
- package/dist/tools/init-project/lifecycle-helpers.js +3 -5
- package/dist/tools/init-project/lint-scaffolder.js +6 -2
- package/dist/tools/init-project/migration-runner.d.ts +10 -1
- package/dist/tools/init-project/migration-runner.js +68 -3
- package/dist/tools/init-project/per-client-files-writer.js +14 -4
- package/dist/tools/init-project/rules-generator.js +10 -2
- package/dist/tools/init-project/scaffold-writer.d.ts +1 -1
- package/dist/tools/init-project/scaffold-writer.js +17 -15
- package/dist/tools/jobs/handlers.d.ts +15 -0
- package/dist/tools/jobs/handlers.js +126 -0
- package/dist/tools/list-specs.js +35 -34
- package/dist/tools/manage-plugins-handler.js +17 -9
- package/dist/tools/migrate-tech/advanced-handlers.js +3 -2
- package/dist/tools/migrate-tech/build-tool-handlers.js +3 -2
- package/dist/tools/migrate-tech/core-handlers.js +5 -2
- package/dist/tools/migrate-tech/data-handlers.js +6 -3
- package/dist/tools/migrate-tech-advanced/rollback-handlers.js +3 -2
- package/dist/tools/migrate-tech-advanced/service-handlers.js +5 -2
- package/dist/tools/oauth-handler.js +7 -1
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +5 -0
- package/dist/tools/register-spec-tools/core-spec-tools.js +31 -0
- package/dist/tools/registry/auth.js +13 -5
- package/dist/tools/registry/publish.js +7 -4
- package/dist/tools/resolve-project-path.d.ts +2 -2
- package/dist/tools/resolve-project-path.js +7 -7
- package/dist/tools/reverse-engineer/analyzer.js +14 -14
- package/dist/tools/rollback-release.js +3 -2
- package/dist/tools/safe-handler.js +295 -171
- package/dist/tools/schema-generator-handler.js +2 -1
- package/dist/tools/schemas/output-schemas.d.ts +88 -82
- package/dist/tools/schemas/output-schemas.js +12 -94
- package/dist/tools/schemas/plugins-schemas.js +0 -2
- package/dist/tools/schemas/registry.js +0 -2
- package/dist/tools/schemas/skill-registry-schemas.js +0 -2
- package/dist/tools/schemas/validate-output-schema.d.ts +256 -0
- package/dist/tools/schemas/validate-output-schema.js +212 -0
- package/dist/tools/sentry-handler.js +6 -1
- package/dist/tools/skill-bootstrap-handler.js +7 -4
- package/dist/tools/status-handler.js +4 -0
- package/dist/tools/storage-bundle-handler.d.ts +9 -0
- package/dist/tools/storage-bundle-handler.js +29 -0
- package/dist/tools/storage-paths-handler.d.ts +9 -0
- package/dist/tools/storage-paths-handler.js +17 -0
- package/dist/tools/suggest-mcp-server.js +11 -5
- package/dist/tools/suggest-mcps.js +29 -9
- package/dist/tools/suggest-tooling/advanced-testing-catalog.js +4 -5
- package/dist/tools/suggest-tooling/build-tool-catalog.js +2 -1
- package/dist/tools/suggest-tooling/css-framework-catalog.js +13 -7
- package/dist/tools/suggest-tooling/framework-catalog.js +3 -5
- package/dist/tools/suggest-tooling/frontend-perf-catalog.js +2 -6
- package/dist/tools/suggest-tooling/handler.js +10 -4
- package/dist/tools/suggest-tooling/hypermedia-catalog.js +11 -3
- package/dist/tools/suggest-tooling/linting-catalog.js +4 -7
- package/dist/tools/suggest-tooling/llm-security-catalog.js +2 -1
- package/dist/tools/suggest-tooling/local-first-catalog.js +7 -5
- package/dist/tools/suggest-tooling/observability-catalog.js +3 -4
- package/dist/tools/suggest-tooling/otel-catalog.js +4 -1
- package/dist/tools/suggest-tooling/resilience-catalog.js +16 -5
- package/dist/tools/suggest-tooling/skills-catalog.js +10 -9
- package/dist/tools/suggest-tooling/supply-chain-catalog.js +2 -3
- package/dist/tools/supabase-handler.js +2 -1
- package/dist/tools/token-intelligence-handler.js +2 -2
- package/dist/tools/token-recording.js +2 -2
- package/dist/tools/token-savings-handler.js +2 -2
- package/dist/tools/tool-registry/core-tools.js +131 -0
- package/dist/tools/tool-registry/group-infra.js +10 -12
- package/dist/tools/tool-registry/group-quality-compliance.js +5 -12
- package/dist/tools/update-status/approval-gates.d.ts +13 -0
- package/dist/tools/update-status/approval-gates.js +81 -0
- package/dist/tools/update-status/batch.js +4 -2
- package/dist/tools/update-status/dod-gates.d.ts +6 -24
- package/dist/tools/update-status/dod-gates.js +60 -135
- package/dist/tools/update-status/done-receipt-verifier.d.ts +15 -0
- package/dist/tools/update-status/done-receipt-verifier.js +145 -0
- package/dist/tools/update-status/evidence-gate.js +154 -2
- package/dist/tools/update-status/file-sync.js +23 -12
- package/dist/tools/update-status/gate-harness.d.ts +7 -0
- package/dist/tools/update-status/gate-harness.js +8 -0
- package/dist/tools/update-status/index.js +228 -325
- package/dist/tools/update-status/qa-gate.d.ts +1 -1
- package/dist/tools/update-status/qa-gate.js +2 -2
- package/dist/tools/update-status/side-effects.js +30 -37
- package/dist/tools/update-status/transition-guard.d.ts +4 -2
- package/dist/tools/update-status/transition-guard.js +57 -10
- package/dist/tools/update-status-convention-gate.js +24 -23
- package/dist/tools/update-status-reconcile.js +2 -2
- package/dist/tools/validate-api-contract-handler.js +3 -3
- package/dist/tools/validate-lint.js +20 -13
- package/dist/tools/validate.d.ts +3 -1
- package/dist/tools/validate.js +213 -5
- package/dist/transports/http-transport.js +84 -61
- package/dist/transports/middleware/with-telemetry.js +3 -2
- package/dist/types/abortable-process.d.ts +2 -0
- package/dist/types/advanced-framework.js +0 -2
- package/dist/types/atomic-upgrade.d.ts +71 -0
- package/dist/types/atomic-upgrade.js +2 -0
- package/dist/types/ci.js +0 -2
- package/dist/types/core-bridge.d.ts +78 -1
- package/dist/types/crash-shield-framework-rules.d.ts +24 -0
- package/dist/types/crash-shield-framework-rules.js +2 -0
- package/dist/types/data-gc.d.ts +16 -0
- package/dist/types/deploy.js +0 -2
- package/dist/types/durable-job.d.ts +78 -0
- package/dist/types/durable-job.js +2 -0
- package/dist/types/durable-validation.d.ts +60 -0
- package/dist/types/durable-validation.js +2 -0
- package/dist/types/estimation.d.ts +2 -0
- package/dist/types/evidence-gates.d.ts +9 -1
- package/dist/types/execution.d.ts +43 -0
- package/dist/types/handoff-artifacts.d.ts +2 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/infrastructure.js +0 -2
- package/dist/types/lifecycle.js +0 -2
- package/dist/types/migration/canonical-storage.d.ts +37 -0
- package/dist/types/migration/canonical-storage.js +2 -0
- package/dist/types/migration/index.d.ts +1 -1
- package/dist/types/native-worker.d.ts +48 -0
- package/dist/types/native-worker.js +2 -0
- package/dist/types/network-policy.d.ts +12 -0
- package/dist/types/network-policy.js +2 -0
- package/dist/types/oauth.js +0 -2
- package/dist/types/observability.d.ts +32 -0
- package/dist/types/outbox-worker.d.ts +35 -0
- package/dist/types/outbox-worker.js +11 -0
- package/dist/types/permissions-config.d.ts +0 -27
- package/dist/types/permissions-config.js +0 -2
- package/dist/types/plugin-install.d.ts +0 -11
- package/dist/types/plugin-install.js +0 -2
- package/dist/types/portal.d.ts +1 -0
- package/dist/types/product-public.d.ts +75 -0
- package/dist/types/product-public.js +2 -0
- package/dist/types/project/inputs.d.ts +2 -0
- package/dist/types/project/mfe-detection.js +0 -2
- package/dist/types/project/platform-mobile.js +0 -2
- package/dist/types/project/platform-specialty.js +0 -2
- package/dist/types/project-knowledge-graph.d.ts +7 -0
- package/dist/types/runtime-database.d.ts +10 -0
- package/dist/types/runtime-database.js +2 -0
- package/dist/types/runtime-policy.d.ts +40 -0
- package/dist/types/runtime-policy.js +2 -0
- package/dist/types/safety.d.ts +4 -5
- package/dist/types/schema-registry.d.ts +12 -0
- package/dist/types/schema-registry.js +2 -0
- package/dist/types/security.d.ts +52 -0
- package/dist/types/skill-registry.js +0 -2
- package/dist/types/spec/inputs.d.ts +2 -0
- package/dist/types/spec-lock-v2.d.ts +13 -7
- package/dist/types/spec-lock-v2.js +1 -1
- package/dist/types/spec-registry.js +0 -2
- package/dist/types/storage-bundle.d.ts +13 -0
- package/dist/types/storage-bundle.js +2 -0
- package/dist/types/storage-catalog.d.ts +18 -0
- package/dist/types/storage-catalog.js +2 -0
- package/dist/types/team-planner.js +0 -2
- package/dist/types/technology-registry.d.ts +35 -0
- package/dist/types/technology-registry.js +2 -0
- package/dist/types/technology-symbols.generated.d.ts +117 -0
- package/dist/types/technology-symbols.generated.js +2 -0
- package/dist/types/telemetry.d.ts +3 -3
- package/dist/types/transport.d.ts +2 -0
- package/dist/types/validate-worker.d.ts +44 -0
- package/dist/types/validate-worker.js +2 -0
- package/dist/types/validation-evidence.d.ts +1 -1
- package/dist/types/validation-receipt.d.ts +104 -0
- package/dist/types/validation-receipt.js +2 -0
- package/package.json +31 -20
- package/planu-native.json +1 -1
- package/planu-plugin.json +1 -1
- package/dist/engine/telemetry/geo-resolver.d.ts +0 -9
- package/dist/engine/telemetry/geo-resolver.js +0 -43
- package/dist/storage/data-dir-discovery.d.ts +0 -31
- package/dist/storage/data-dir-discovery.js +0 -140
- package/dist/storage/migrations/cwd-to-absolute.d.ts +0 -25
- package/dist/storage/migrations/cwd-to-absolute.js +0 -281
- package/dist/tools/create-spec/adapters/prior-decisions-hint.d.ts +0 -14
- package/dist/tools/create-spec/adapters/prior-decisions-hint.js +0 -30
- package/dist/tools/init-project/ancestor-data-detector.d.ts +0 -22
- package/dist/tools/init-project/ancestor-data-detector.js +0 -81
- package/dist/tools/update-status/force-done-audit.d.ts +0 -2
- package/dist/tools/update-status/force-done-audit.js +0 -23
- package/dist/types/migration/cwd-to-absolute.d.ts +0 -8
- 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
|
[](https://www.npmjs.com/package/@planu/cli)
|
|
6
6
|

|
|
7
7
|

|
|
8
|
-

|
|
9
9
|
|
|
10
|
-
**[Documentation](https://planu.dev)** · **[
|
|
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
|
|
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** —
|
|
21
|
-
- **
|
|
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
|
-
- **
|
|
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
|
-
##
|
|
68
|
+
## Artifact lifecycle
|
|
67
69
|
|
|
68
|
-
|
|
70
|
+
The portable contract stays small and versionable:
|
|
69
71
|
|
|
70
72
|
```
|
|
71
73
|
planu/specs/SPEC-001-auth/
|
|
72
|
-
└── spec.md # Requirements
|
|
74
|
+
└── spec.md # Requirements, technical contract, criteria, and lifecycle status
|
|
73
75
|
```
|
|
74
76
|
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
103
|
-
├── projects
|
|
104
|
-
└──
|
|
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
|
-
[
|
|
129
|
+
Planu is proprietary software. See the [license terms](LICENSE) for permitted use and distribution restrictions.
|
|
@@ -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
|
-
|
|
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,
|
|
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(
|
|
68
|
-
const
|
|
69
|
+
function buildMcpEntry(_licenseKey) {
|
|
70
|
+
const offline = process.env.PLANU_OFFLINE === '1';
|
|
71
|
+
return {
|
|
69
72
|
command: 'npx',
|
|
70
|
-
args: [
|
|
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
|
-
|
|
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
|
|
103
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
308
|
-
process.stdout.write(` ${yellow('!')} ${tool.name}: config file has invalid JSON —
|
|
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 (
|
|
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}:
|
|
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
|
}
|