@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readJson, writeJson } from '../../storage/base-store.js';
|
|
2
2
|
import toolGroupsConfigJson from '../../config/tool-groups.json' with { type: 'json' };
|
|
3
|
-
|
|
3
|
+
import { resolvedStorageArtifactPath } from '../../storage/storage-catalog.js';
|
|
4
4
|
const toolGroupsConfig = toolGroupsConfigJson;
|
|
5
5
|
export class GroupManager {
|
|
6
6
|
groups;
|
|
@@ -137,7 +137,7 @@ export class GroupManager {
|
|
|
137
137
|
/** Load persisted group states from disk. */
|
|
138
138
|
async loadPersistedState() {
|
|
139
139
|
const defaultState = { states: [], updatedAt: '' };
|
|
140
|
-
const persisted = await readJson(
|
|
140
|
+
const persisted = await readJson(resolvedStorageArtifactPath('tool-group-state'), defaultState);
|
|
141
141
|
const result = new Map();
|
|
142
142
|
for (const entry of persisted.states) {
|
|
143
143
|
result.set(entry.groupId, entry.enabled);
|
|
@@ -154,7 +154,7 @@ export class GroupManager {
|
|
|
154
154
|
states,
|
|
155
155
|
updatedAt: new Date().toISOString(),
|
|
156
156
|
};
|
|
157
|
-
await writeJson(
|
|
157
|
+
await writeJson(resolvedStorageArtifactPath('tool-group-state'), payload);
|
|
158
158
|
}
|
|
159
159
|
/** Apply enabled/disabled state to all tools in a group via toolMap. */
|
|
160
160
|
applyGroupState(groupId, enabled) {
|
|
@@ -13,7 +13,7 @@ function manifestPath(projectPath, host) {
|
|
|
13
13
|
if (host === 'gemini') {
|
|
14
14
|
return join(projectPath, '.gemini', '.planu-rules-manifest.json');
|
|
15
15
|
}
|
|
16
|
-
return join(projectPath, '
|
|
16
|
+
return join(projectPath, 'planu', 'rules-manifest.codex.json');
|
|
17
17
|
}
|
|
18
18
|
/**
|
|
19
19
|
* Install all default-enabled universal rules applicable to `host`.
|
|
@@ -21,6 +21,7 @@ Never suggest bypassPermissions — it disables all safety checks.
|
|
|
21
21
|
|
|
22
22
|
## How to apply
|
|
23
23
|
|
|
24
|
+
- Run the relevant tests before moving the spec to \`done\`
|
|
24
25
|
- NEVER switch modes automatically — always tell the user and let them decide
|
|
25
26
|
- Critical bash actions (git push, npm publish, rm -rf) require approval regardless of mode
|
|
26
27
|
`;
|
|
@@ -42,6 +43,7 @@ Auto-generated by \`init_project\`.
|
|
|
42
43
|
|
|
43
44
|
## How to apply
|
|
44
45
|
|
|
46
|
+
- Run the relevant tests before moving the spec to \`done\`
|
|
45
47
|
- NEVER switch modes automatically — always inform the user first
|
|
46
48
|
`;
|
|
47
49
|
}
|
|
@@ -15,6 +15,7 @@ When implementation changes are complete and validated, always address release e
|
|
|
15
15
|
|
|
16
16
|
## Required Release Checklist
|
|
17
17
|
|
|
18
|
+
- tests, lint, and typecheck gates passed
|
|
18
19
|
- local validation commands passed
|
|
19
20
|
- changelog or release notes updated when applicable
|
|
20
21
|
- package version and git tag stay aligned
|
|
@@ -5,6 +5,8 @@ import { get } from 'node:https';
|
|
|
5
5
|
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
7
|
import { PLANU_VERSION } from '../config/version.js';
|
|
8
|
+
import { resolveStorageLayout } from '../storage/storage-layout.js';
|
|
9
|
+
import { assertNetworkAllowed } from './network-policy.js';
|
|
8
10
|
const NPM_REGISTRY_URL = 'https://registry.npmjs.org/@planu%2Fcli/latest';
|
|
9
11
|
const CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 24h
|
|
10
12
|
// ---------------------------------------------------------------------------
|
|
@@ -69,6 +71,7 @@ function isCacheValid(cache) {
|
|
|
69
71
|
return age < CACHE_TTL_MS;
|
|
70
72
|
}
|
|
71
73
|
function fetchLatestVersion() {
|
|
74
|
+
assertNetworkAllowed(NPM_REGISTRY_URL);
|
|
72
75
|
return new Promise((resolve, reject) => {
|
|
73
76
|
const req = get(NPM_REGISTRY_URL, { timeout: 5000 }, (res) => {
|
|
74
77
|
if (res.statusCode !== 200) {
|
|
@@ -138,8 +141,8 @@ function emitUpdateHint(latest, deprecated) {
|
|
|
138
141
|
const urgency = deprecated ? '🚨 OUTDATED' : '🆕 Update';
|
|
139
142
|
const msg = [
|
|
140
143
|
`[Planu] ${urgency}: v${PLANU_VERSION} → v${latest}`,
|
|
141
|
-
`[Planu] Run: npm install -g @planu/cli
|
|
142
|
-
`[Planu] Or: npx @planu/cli
|
|
144
|
+
`[Planu] Run: npm install -g @planu/cli@${latest}`,
|
|
145
|
+
`[Planu] Or: npx @planu/cli@${latest}`,
|
|
143
146
|
].join('\n');
|
|
144
147
|
process.stderr.write(msg + '\n');
|
|
145
148
|
isDeprecatedVersion = deprecated;
|
|
@@ -147,12 +150,12 @@ function emitUpdateHint(latest, deprecated) {
|
|
|
147
150
|
pendingUpdateBanner = [
|
|
148
151
|
`🚨 Planu OUTDATED: v${PLANU_VERSION} is ${DEPRECATED_MINOR_GAP}+ minor versions behind v${latest}.`,
|
|
149
152
|
`Some tools may not work correctly. Update NOW:`,
|
|
150
|
-
` npm install -g @planu/cli
|
|
153
|
+
` npm install -g @planu/cli@${latest}`,
|
|
151
154
|
` — or run: check_update_status for instructions`,
|
|
152
155
|
].join('\n');
|
|
153
156
|
}
|
|
154
157
|
else {
|
|
155
|
-
pendingUpdateBanner = `⚠️ Update available: v${PLANU_VERSION} → v${latest}. Run: npm install -g @planu/cli
|
|
158
|
+
pendingUpdateBanner = `⚠️ Update available: v${PLANU_VERSION} → v${latest}. Run: npm install -g @planu/cli@${latest}`;
|
|
156
159
|
}
|
|
157
160
|
}
|
|
158
161
|
/**
|
|
@@ -162,7 +165,7 @@ function emitUpdateHint(latest, deprecated) {
|
|
|
162
165
|
* @param dataDir - Project data directory (default: process.cwd()/data)
|
|
163
166
|
*/
|
|
164
167
|
export async function checkForUpdates(dataDir) {
|
|
165
|
-
const resolvedDataDir = dataDir ??
|
|
168
|
+
const resolvedDataDir = dataDir ?? resolveStorageLayout().cache;
|
|
166
169
|
const cachePath = getCachePath(resolvedDataDir);
|
|
167
170
|
try {
|
|
168
171
|
const cache = readCache(cachePath);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Rebuild machine-local mutable ledgers from the committed approved spec. */
|
|
2
|
+
export declare function reconstructApprovedSpecLedgers(input: {
|
|
3
|
+
readonly canonicalProjectId: string;
|
|
4
|
+
readonly specId: string;
|
|
5
|
+
readonly specPath: string;
|
|
6
|
+
readonly projectPath?: string;
|
|
7
|
+
readonly outputDirectory?: string;
|
|
8
|
+
}): Promise<{
|
|
9
|
+
readonly taskPlanPath: string;
|
|
10
|
+
readonly traceabilityPath: string;
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=approved-spec-portability.d.ts.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { access, readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { atomicWriteFile } from '../safety/atomic-write-file.js';
|
|
4
|
+
import { projectDataDir } from '../../storage/base-store.js';
|
|
5
|
+
import { PROJECT_ID as CANONICAL_PROJECT_ID } from './validation-receipt-codec.js';
|
|
6
|
+
import { parseGroundedTechnicalPaths } from '../spec-grounding/contract.js';
|
|
7
|
+
function section(markdown, title) {
|
|
8
|
+
const escaped = title.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
9
|
+
const match = new RegExp(`^#{2,3}\\s+${escaped}\\s*$`, 'imu').exec(markdown);
|
|
10
|
+
if (!match) {
|
|
11
|
+
return '';
|
|
12
|
+
}
|
|
13
|
+
const start = match.index + match[0].length;
|
|
14
|
+
const remainder = markdown.slice(start);
|
|
15
|
+
const end = /^#{2,3}\s+/mu.exec(remainder)?.index ?? remainder.length;
|
|
16
|
+
return remainder.slice(0, end).trim();
|
|
17
|
+
}
|
|
18
|
+
function frontmatterValue(markdown, key) {
|
|
19
|
+
const frontmatter = /^---\s*\n([\s\S]*?)\n---/u.exec(markdown)?.[1];
|
|
20
|
+
if (!frontmatter) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const escaped = key.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
|
|
24
|
+
return new RegExp(`^${escaped}:\\s*["']?([^"'\\n]+)["']?\\s*$`, 'imu')
|
|
25
|
+
.exec(frontmatter)?.[1]
|
|
26
|
+
?.trim();
|
|
27
|
+
}
|
|
28
|
+
function numberedItems(value) {
|
|
29
|
+
return [...value.matchAll(/^\s*\d+[.)]\s+(.+?)\s*$/gmu)].map((match) => match[1] ?? '');
|
|
30
|
+
}
|
|
31
|
+
function referencedPaths(value) {
|
|
32
|
+
return [...new Set([...value.matchAll(/`([^`]+)`/gu)].map((match) => match[1] ?? ''))]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.sort();
|
|
35
|
+
}
|
|
36
|
+
async function existingProjectPaths(projectPath, paths) {
|
|
37
|
+
const resolved = await Promise.all(paths.map(async (path) => {
|
|
38
|
+
try {
|
|
39
|
+
await access(join(projectPath, path));
|
|
40
|
+
return path;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof Error &&
|
|
44
|
+
'code' in error &&
|
|
45
|
+
error.code === 'ENOENT') {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}));
|
|
51
|
+
return resolved.filter((path) => path !== undefined);
|
|
52
|
+
}
|
|
53
|
+
/** Rebuild machine-local mutable ledgers from the committed approved spec. */
|
|
54
|
+
export async function reconstructApprovedSpecLedgers(input) {
|
|
55
|
+
if (!CANONICAL_PROJECT_ID.test(input.canonicalProjectId)) {
|
|
56
|
+
throw new Error('[Planu] Invalid canonical projectId for approved spec reconstruction');
|
|
57
|
+
}
|
|
58
|
+
const markdown = await readFile(input.specPath, 'utf8');
|
|
59
|
+
const status = frontmatterValue(markdown, 'status');
|
|
60
|
+
if (frontmatterValue(markdown, 'id') !== input.specId ||
|
|
61
|
+
(status !== 'approved' && status !== 'implementing')) {
|
|
62
|
+
throw new Error('[Planu] approved or implementing spec identity/status mismatch');
|
|
63
|
+
}
|
|
64
|
+
const criteria = numberedItems(section(markdown, 'Acceptance Criteria'));
|
|
65
|
+
if (criteria.length === 0) {
|
|
66
|
+
throw new Error('[Planu] Approved spec has no reconstructable acceptance criteria');
|
|
67
|
+
}
|
|
68
|
+
const workPlan = section(markdown, 'File-Level Work Plan');
|
|
69
|
+
const verificationMap = section(markdown, 'Acceptance-To-Verification Map');
|
|
70
|
+
const approvedChangedFiles = parseGroundedTechnicalPaths(markdown);
|
|
71
|
+
const changedFiles = approvedChangedFiles.length > 0
|
|
72
|
+
? approvedChangedFiles
|
|
73
|
+
: referencedPaths(workPlan).filter((path) => !path.startsWith('tests/'));
|
|
74
|
+
const taskStatus = status === 'implementing' ? 'done' : 'pending';
|
|
75
|
+
const tasks = criteria.map((criterion, index) => ({
|
|
76
|
+
id: `T${String(index + 1)}`,
|
|
77
|
+
title: criterion,
|
|
78
|
+
acceptanceCriteria: [`AC${String(index + 1)}`],
|
|
79
|
+
status: taskStatus,
|
|
80
|
+
}));
|
|
81
|
+
const verificationLines = verificationMap
|
|
82
|
+
.split('\n')
|
|
83
|
+
.filter((line) => line.trim().startsWith('-'));
|
|
84
|
+
const rows = await Promise.all(criteria.map(async (criterion, index) => {
|
|
85
|
+
const matchingLine = verificationLines.find((line) => line.includes(criterion) || line.includes(`AC${String(index + 1)}`)) ?? verificationLines[index];
|
|
86
|
+
const candidateTests = referencedPaths(matchingLine ?? '').filter((path) => path.startsWith('tests/'));
|
|
87
|
+
const testEvidence = input.projectPath
|
|
88
|
+
? await existingProjectPaths(input.projectPath, candidateTests)
|
|
89
|
+
: candidateTests;
|
|
90
|
+
return {
|
|
91
|
+
acceptanceCriterion: `AC${String(index + 1)}`,
|
|
92
|
+
scenario: criterion,
|
|
93
|
+
testEvidence,
|
|
94
|
+
changedFiles,
|
|
95
|
+
validationEvidence: matchingLine?.trim() ?? 'Validated against the approved acceptance criterion.',
|
|
96
|
+
reviewerEvidence: 'Approved spec scope and acceptance-to-verification map.',
|
|
97
|
+
};
|
|
98
|
+
}));
|
|
99
|
+
const outputDirectory = input.outputDirectory ??
|
|
100
|
+
join(projectDataDir(input.canonicalProjectId), 'handoffs', input.specId);
|
|
101
|
+
const taskPlanPath = join(outputDirectory, 'task-plan.json');
|
|
102
|
+
const traceabilityPath = join(outputDirectory, 'traceability-matrix.json');
|
|
103
|
+
await atomicWriteFile(taskPlanPath, `${JSON.stringify({ version: 1, tasks }, null, 2)}\n`);
|
|
104
|
+
await atomicWriteFile(traceabilityPath, `${JSON.stringify({ version: 1, rows }, null, 2)}\n`);
|
|
105
|
+
return { taskPlanPath, traceabilityPath };
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=approved-spec-portability.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ValidationArtifactDigests, ValidationReceiptBindings } from '../../types/validation-receipt.js';
|
|
2
|
+
import type { DurableValidationBindings, ValidationPhase, ValidationPhaseGraphResult, ValidationPhaseProgress } from '../../types/durable-validation.js';
|
|
3
|
+
export type { DurableValidationBindings } from '../../types/durable-validation.js';
|
|
4
|
+
export { createPendingValidationSubmission, createValidationSubmission, validationOperationId, validationSubmissionOperationId, } from './validation-submission.js';
|
|
5
|
+
export declare function toValidationReceiptBindings(bindings: DurableValidationBindings, artifactDigests: ValidationArtifactDigests): ValidationReceiptBindings;
|
|
6
|
+
export declare function gitSourceTreeDigest(projectPath: string): Promise<string>;
|
|
7
|
+
/** Compute immutable validation and lifecycle-artifact bindings without trusting spec metadata. */
|
|
8
|
+
export declare function computeDurableValidationBindings(input: {
|
|
9
|
+
readonly canonicalProjectId: string;
|
|
10
|
+
readonly specId: string;
|
|
11
|
+
readonly projectPath: string;
|
|
12
|
+
readonly specPath: string;
|
|
13
|
+
}): Promise<{
|
|
14
|
+
readonly bindings: DurableValidationBindings;
|
|
15
|
+
readonly artifactDigests: ValidationArtifactDigests;
|
|
16
|
+
}>;
|
|
17
|
+
/** Persist content-addressed receipt links beside machine-local lifecycle artifacts. */
|
|
18
|
+
export declare function writeValidationArtifactProvenance(input: {
|
|
19
|
+
readonly canonicalProjectId: string;
|
|
20
|
+
readonly specId: string;
|
|
21
|
+
readonly receiptId: string;
|
|
22
|
+
readonly issuerId: string;
|
|
23
|
+
readonly artifactDigests: ValidationArtifactDigests;
|
|
24
|
+
}): Promise<readonly string[]>;
|
|
25
|
+
/** Redact progress before it crosses the durable checkpoint boundary. */
|
|
26
|
+
export declare function redactValidationProgress(progress: ValidationPhaseProgress): ValidationPhaseProgress;
|
|
27
|
+
/** Execute independent validation gates with one shared deadline and cancellation tree. */
|
|
28
|
+
export declare function runValidationPhaseGraph(input: {
|
|
29
|
+
readonly projectPath: string;
|
|
30
|
+
readonly deadlineAt: number;
|
|
31
|
+
readonly phases: readonly ValidationPhase[];
|
|
32
|
+
readonly maxConcurrency?: number;
|
|
33
|
+
readonly signal?: AbortSignal;
|
|
34
|
+
readonly onProgress?: (progress: ValidationPhaseProgress) => void;
|
|
35
|
+
}): Promise<ValidationPhaseGraphResult>;
|
|
36
|
+
//# sourceMappingURL=durable-validation.d.ts.map
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { technologyValue } from '../technology-registry.js';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { execFile } from 'node:child_process';
|
|
4
|
+
import { lstat, readFile, readlink } from 'node:fs/promises';
|
|
5
|
+
import { basename, join } from 'node:path';
|
|
6
|
+
import { promisify } from 'node:util';
|
|
7
|
+
import { runAbortableProcess } from '../abortable-process-runner.js';
|
|
8
|
+
import { projectDataDir } from '../../storage/base-store.js';
|
|
9
|
+
import { atomicWriteFile } from '../safety/atomic-write-file.js';
|
|
10
|
+
import { evidenceArtifactCollectionDigest, evidenceArtifactDigest, } from '../evidence-gates/artifact-reader.js';
|
|
11
|
+
import { isValidationSourcePath } from './validation-source-policy.js';
|
|
12
|
+
import { PROJECT_ID as CANONICAL_PROJECT_ID } from './validation-receipt-codec.js';
|
|
13
|
+
export { createPendingValidationSubmission, createValidationSubmission, validationOperationId, validationSubmissionOperationId, } from './validation-submission.js';
|
|
14
|
+
const execFileAsync = promisify(execFile);
|
|
15
|
+
const DIGEST_PATTERN = /^sha256:[a-f0-9]{64}$/u;
|
|
16
|
+
const DEFAULT_MAX_CONCURRENCY = 2;
|
|
17
|
+
const MAX_CONCURRENCY = 8;
|
|
18
|
+
const MAX_BUFFER_BYTES = 2 * 1024 * 1024;
|
|
19
|
+
function assertBindings(bindings) {
|
|
20
|
+
if (!CANONICAL_PROJECT_ID.test(bindings.projectId)) {
|
|
21
|
+
throw new Error('[Planu] Durable validation requires a canonical projectId');
|
|
22
|
+
}
|
|
23
|
+
if (!/^SPEC-[A-Za-z0-9][A-Za-z0-9-]*$/u.test(bindings.specId)) {
|
|
24
|
+
throw new Error('[Planu] Durable validation requires a valid specId');
|
|
25
|
+
}
|
|
26
|
+
for (const bindingDigest of [
|
|
27
|
+
bindings.sourceTreeHash,
|
|
28
|
+
bindings.specHash,
|
|
29
|
+
bindings.policyHash,
|
|
30
|
+
bindings.toolchainHash,
|
|
31
|
+
]) {
|
|
32
|
+
if (!DIGEST_PATTERN.test(bindingDigest)) {
|
|
33
|
+
throw new Error('[Planu] Durable validation requires four sha256 bindings');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function digest(value) {
|
|
38
|
+
return `sha256:${createHash('sha256').update(value).digest('hex')}`;
|
|
39
|
+
}
|
|
40
|
+
export function toValidationReceiptBindings(bindings, artifactDigests) {
|
|
41
|
+
return {
|
|
42
|
+
projectId: bindings.projectId,
|
|
43
|
+
specId: bindings.specId,
|
|
44
|
+
sourceDigest: bindings.sourceTreeHash,
|
|
45
|
+
specDigest: bindings.specHash,
|
|
46
|
+
policyDigest: bindings.policyHash,
|
|
47
|
+
toolchainDigest: bindings.toolchainHash,
|
|
48
|
+
artifactDigests,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
async function digestFile(path, missingLabel) {
|
|
52
|
+
try {
|
|
53
|
+
return digest(await readFile(path));
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (error.code === 'ENOENT') {
|
|
57
|
+
return digest(`missing:${missingLabel}`);
|
|
58
|
+
}
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function readEvidenceFile(path) {
|
|
63
|
+
try {
|
|
64
|
+
const value = JSON.parse(await readFile(path, 'utf8'));
|
|
65
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
66
|
+
throw new Error('expected a JSON object');
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (error.code === 'ENOENT') {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`[Planu] Invalid lifecycle evidence: ${path}`, { cause: error });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function mapWithConcurrency(values, concurrency, worker) {
|
|
78
|
+
const results = new Array(values.length);
|
|
79
|
+
let cursor = 0;
|
|
80
|
+
const runners = Array.from({ length: Math.min(concurrency, values.length) }, async () => {
|
|
81
|
+
for (;;) {
|
|
82
|
+
const index = cursor;
|
|
83
|
+
cursor += 1;
|
|
84
|
+
if (index >= values.length) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
results[index] = await worker(values[index]);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
await Promise.all(runners);
|
|
91
|
+
return results;
|
|
92
|
+
}
|
|
93
|
+
export async function gitSourceTreeDigest(projectPath) {
|
|
94
|
+
try {
|
|
95
|
+
const gitOptions = { cwd: projectPath, encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 };
|
|
96
|
+
const [trackedResult, untrackedResult] = await Promise.all([
|
|
97
|
+
execFileAsync('git', ['ls-files', '--cached', '-z'], gitOptions),
|
|
98
|
+
execFileAsync('git', ['ls-files', '--others', '--exclude-standard', '-z'], gitOptions),
|
|
99
|
+
]);
|
|
100
|
+
const sourceEntries = (stdout) => stdout
|
|
101
|
+
.split('\0')
|
|
102
|
+
.filter(Boolean)
|
|
103
|
+
.map((sourcePath) => ({ sourcePath, canonicalPath: sourcePath.normalize('NFC') }))
|
|
104
|
+
.filter(({ canonicalPath }) => isValidationSourcePath(canonicalPath));
|
|
105
|
+
const entriesToRead = [
|
|
106
|
+
...sourceEntries(trackedResult.stdout),
|
|
107
|
+
...sourceEntries(untrackedResult.stdout),
|
|
108
|
+
].sort((left, right) => Buffer.compare(Buffer.from(left.canonicalPath), Buffer.from(right.canonicalPath)));
|
|
109
|
+
if (new Set(entriesToRead.map(({ canonicalPath }) => canonicalPath)).size !== entriesToRead.length) {
|
|
110
|
+
throw new Error('source paths collide after Unicode normalization');
|
|
111
|
+
}
|
|
112
|
+
const entries = await mapWithConcurrency(entriesToRead, MAX_CONCURRENCY, async (entry) => {
|
|
113
|
+
const { canonicalPath: path, sourcePath } = entry;
|
|
114
|
+
const absolutePath = join(projectPath, sourcePath);
|
|
115
|
+
try {
|
|
116
|
+
const stats = await lstat(absolutePath);
|
|
117
|
+
if (stats.isSymbolicLink()) {
|
|
118
|
+
const target = (await readlink(absolutePath)).normalize('NFC');
|
|
119
|
+
return { path, content: Buffer.from(`symlink\0${target}`, 'utf8') };
|
|
120
|
+
}
|
|
121
|
+
if (!stats.isFile()) {
|
|
122
|
+
throw new Error(`unsupported source entry type: ${path}`);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
path,
|
|
126
|
+
content: Buffer.concat([Buffer.from('file\0'), await readFile(absolutePath)]),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (error.code === 'ENOENT') {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
throw error;
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
const hash = createHash('sha256');
|
|
137
|
+
hash.update('planu-source-v1\0');
|
|
138
|
+
for (const entry of entries) {
|
|
139
|
+
if (!entry) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const pathBytes = Buffer.from(entry.path, 'utf8');
|
|
143
|
+
hash.update(`${pathBytes.length}:`);
|
|
144
|
+
hash.update(pathBytes);
|
|
145
|
+
hash.update(`${entry.content.length}:`);
|
|
146
|
+
hash.update(entry.content);
|
|
147
|
+
}
|
|
148
|
+
return `sha256:${hash.digest('hex')}`;
|
|
149
|
+
}
|
|
150
|
+
catch (error) {
|
|
151
|
+
throw new Error('[Planu] Unable to bind validation to the source tree', { cause: error });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/** Compute immutable validation and lifecycle-artifact bindings without trusting spec metadata. */
|
|
155
|
+
export async function computeDurableValidationBindings(input) {
|
|
156
|
+
const handoff = join(projectDataDir(input.canonicalProjectId), 'handoffs', input.specId);
|
|
157
|
+
const specHash = await digestFile(input.specPath, 'approved-spec');
|
|
158
|
+
const [discovery, taskPlan, traceability, ...contracts] = await Promise.all([
|
|
159
|
+
readEvidenceFile(join(handoff, 'discovery.json')),
|
|
160
|
+
readEvidenceFile(join(handoff, 'task-plan.json')),
|
|
161
|
+
readEvidenceFile(join(handoff, 'traceability-matrix.json')),
|
|
162
|
+
...['api', technologyValue('technology-graphql-aed31c'), 'event', 'ui', 'mcp'].map((kind) => readEvidenceFile(join(handoff, `contract-validation-${kind}.json`))),
|
|
163
|
+
]);
|
|
164
|
+
const policyFiles = ['planu.json', 'planu/conventions.json', 'AGENTS.md'];
|
|
165
|
+
const toolchainFiles = ['package.json', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock'];
|
|
166
|
+
const [policyEntries, toolchainEntries] = await Promise.all([
|
|
167
|
+
Promise.all(policyFiles.map(async (path) => [
|
|
168
|
+
path,
|
|
169
|
+
await digestFile(join(input.projectPath, path), path),
|
|
170
|
+
])),
|
|
171
|
+
Promise.all(toolchainFiles.map(async (path) => [
|
|
172
|
+
path,
|
|
173
|
+
await digestFile(join(input.projectPath, path), path),
|
|
174
|
+
])),
|
|
175
|
+
]);
|
|
176
|
+
const contractArtifacts = contracts.filter((artifact) => typeof artifact?.kind === 'string');
|
|
177
|
+
return {
|
|
178
|
+
bindings: {
|
|
179
|
+
projectId: input.canonicalProjectId,
|
|
180
|
+
specId: input.specId,
|
|
181
|
+
sourceTreeHash: await gitSourceTreeDigest(input.projectPath),
|
|
182
|
+
specHash,
|
|
183
|
+
policyHash: digest(JSON.stringify(policyEntries)),
|
|
184
|
+
toolchainHash: digest(JSON.stringify({
|
|
185
|
+
node: process.version,
|
|
186
|
+
platform: process.platform,
|
|
187
|
+
files: toolchainEntries,
|
|
188
|
+
})),
|
|
189
|
+
},
|
|
190
|
+
artifactDigests: {
|
|
191
|
+
approvedSpec: specHash,
|
|
192
|
+
discovery: discovery
|
|
193
|
+
? evidenceArtifactDigest(discovery)
|
|
194
|
+
: evidenceArtifactDigest({ missing: 'discovery' }),
|
|
195
|
+
taskPlan: taskPlan
|
|
196
|
+
? evidenceArtifactDigest(taskPlan)
|
|
197
|
+
: evidenceArtifactDigest({ missing: 'task-plan' }),
|
|
198
|
+
traceability: traceability
|
|
199
|
+
? evidenceArtifactDigest(traceability)
|
|
200
|
+
: evidenceArtifactDigest({ missing: 'traceability' }),
|
|
201
|
+
contractValidation: evidenceArtifactCollectionDigest(contractArtifacts),
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
/** Persist content-addressed receipt links beside machine-local lifecycle artifacts. */
|
|
206
|
+
export async function writeValidationArtifactProvenance(input) {
|
|
207
|
+
assertBindings({
|
|
208
|
+
projectId: input.canonicalProjectId,
|
|
209
|
+
specId: input.specId,
|
|
210
|
+
sourceTreeHash: input.artifactDigests.approvedSpec,
|
|
211
|
+
specHash: input.artifactDigests.approvedSpec,
|
|
212
|
+
policyHash: input.artifactDigests.discovery,
|
|
213
|
+
toolchainHash: input.artifactDigests.taskPlan,
|
|
214
|
+
});
|
|
215
|
+
if (!DIGEST_PATTERN.test(input.receiptId) || !input.issuerId.trim()) {
|
|
216
|
+
throw new Error('[Planu] Invalid validation artifact provenance identity');
|
|
217
|
+
}
|
|
218
|
+
const directory = join(projectDataDir(input.canonicalProjectId), 'handoffs', input.specId);
|
|
219
|
+
const entries = [
|
|
220
|
+
['approved-spec', input.artifactDigests.approvedSpec],
|
|
221
|
+
['discovery', input.artifactDigests.discovery],
|
|
222
|
+
['task-plan', input.artifactDigests.taskPlan],
|
|
223
|
+
['traceability-matrix', input.artifactDigests.traceability],
|
|
224
|
+
['contract-validation', input.artifactDigests.contractValidation],
|
|
225
|
+
];
|
|
226
|
+
const sidecars = await Promise.all(entries.map(async ([name, artifactDigest]) => {
|
|
227
|
+
const path = join(directory, `${name}.provenance.json`);
|
|
228
|
+
await atomicWriteFile(path, `${JSON.stringify({
|
|
229
|
+
receiptId: input.receiptId,
|
|
230
|
+
artifactDigest,
|
|
231
|
+
specId: input.specId,
|
|
232
|
+
issuerId: input.issuerId,
|
|
233
|
+
}, null, 2)}\n`);
|
|
234
|
+
return path;
|
|
235
|
+
}));
|
|
236
|
+
return sidecars;
|
|
237
|
+
}
|
|
238
|
+
/** Redact progress before it crosses the durable checkpoint boundary. */
|
|
239
|
+
export function redactValidationProgress(progress) {
|
|
240
|
+
const redact = (value) => value
|
|
241
|
+
.replace(/\/Users\/[^/\s]+/gu, '/Users/[redacted]')
|
|
242
|
+
.replace(/\/(?:home|root)\/[^/\s]+/gu, '/home/[redacted]')
|
|
243
|
+
.replace(/(--?(?:token|password|secret|api[-_]?key)(?:=|\s+))\S+/giu, '$1[redacted]')
|
|
244
|
+
.replace(/(bearer\s+)\S+/giu, '$1[redacted]');
|
|
245
|
+
return {
|
|
246
|
+
...progress,
|
|
247
|
+
command: redact(progress.command),
|
|
248
|
+
...(progress.remediation === undefined ? {} : { remediation: redact(progress.remediation) }),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Execute independent validation gates with one shared deadline and cancellation tree. */
|
|
252
|
+
export async function runValidationPhaseGraph(input) {
|
|
253
|
+
if (!Number.isSafeInteger(input.deadlineAt) || input.deadlineAt <= Date.now()) {
|
|
254
|
+
throw new Error('[Planu] Validation phase graph requires a future absolute deadline');
|
|
255
|
+
}
|
|
256
|
+
const maxConcurrency = input.maxConcurrency ?? DEFAULT_MAX_CONCURRENCY;
|
|
257
|
+
if (!Number.isSafeInteger(maxConcurrency) ||
|
|
258
|
+
maxConcurrency < 1 ||
|
|
259
|
+
maxConcurrency > MAX_CONCURRENCY) {
|
|
260
|
+
throw new Error(`[Planu] maxConcurrency must be between 1 and ${String(MAX_CONCURRENCY)}`);
|
|
261
|
+
}
|
|
262
|
+
const results = Array.from({ length: input.phases.length }, () => undefined);
|
|
263
|
+
const logs = Array.from({ length: input.phases.length }, () => '');
|
|
264
|
+
let cursor = 0;
|
|
265
|
+
const worker = async () => {
|
|
266
|
+
while (cursor < input.phases.length) {
|
|
267
|
+
const index = cursor++;
|
|
268
|
+
const phase = input.phases[index];
|
|
269
|
+
if (!phase) {
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const completed = await executeValidationPhase(phase, input);
|
|
273
|
+
results[index] = completed.result;
|
|
274
|
+
logs[index] = completed.log;
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
await Promise.all(Array.from({ length: Math.min(maxConcurrency, input.phases.length) }, () => worker()));
|
|
278
|
+
const completedResults = results.filter((result) => result !== undefined);
|
|
279
|
+
const status = completedResults.some((result) => result.status === 'cancelled')
|
|
280
|
+
? 'cancelled'
|
|
281
|
+
: completedResults.some((result) => result.status === 'failed')
|
|
282
|
+
? 'failed'
|
|
283
|
+
: 'passed';
|
|
284
|
+
return { status, gates: completedResults, log: logs.join('\n') };
|
|
285
|
+
}
|
|
286
|
+
async function executeValidationPhase(phase, input) {
|
|
287
|
+
const startedAt = Date.now();
|
|
288
|
+
const safeCommand = [basename(phase.command.executable), ...(phase.command.args ?? [])].join(' ');
|
|
289
|
+
input.onProgress?.(redactValidationProgress({
|
|
290
|
+
phase: phase.id,
|
|
291
|
+
command: safeCommand,
|
|
292
|
+
durationMs: 0,
|
|
293
|
+
...(phase.filesScanned === undefined ? {} : { filesScanned: phase.filesScanned }),
|
|
294
|
+
status: 'running',
|
|
295
|
+
}));
|
|
296
|
+
phase.onStarted?.();
|
|
297
|
+
try {
|
|
298
|
+
const remainingMs = Math.max(1, input.deadlineAt - Date.now());
|
|
299
|
+
const processResult = await runAbortableProcess(phase.command.executable, [...(phase.command.args ?? [])], {
|
|
300
|
+
cwd: input.projectPath,
|
|
301
|
+
timeoutMs: Math.min(phase.timeoutMs ?? remainingMs, remainingMs),
|
|
302
|
+
maxBufferBytes: MAX_BUFFER_BYTES,
|
|
303
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
304
|
+
});
|
|
305
|
+
const log = `${processResult.stdout}${processResult.stderr}`;
|
|
306
|
+
const status = processResult.aborted || processResult.timedOut
|
|
307
|
+
? 'cancelled'
|
|
308
|
+
: processResult.status === 0
|
|
309
|
+
? 'passed'
|
|
310
|
+
: 'failed';
|
|
311
|
+
const durationMs = Date.now() - startedAt;
|
|
312
|
+
input.onProgress?.(redactValidationProgress({
|
|
313
|
+
phase: phase.id,
|
|
314
|
+
command: safeCommand,
|
|
315
|
+
durationMs,
|
|
316
|
+
...(phase.filesScanned === undefined ? {} : { filesScanned: phase.filesScanned }),
|
|
317
|
+
status,
|
|
318
|
+
...(phase.remediation === undefined ? {} : { remediation: phase.remediation }),
|
|
319
|
+
}));
|
|
320
|
+
return {
|
|
321
|
+
log,
|
|
322
|
+
result: {
|
|
323
|
+
id: phase.id,
|
|
324
|
+
status,
|
|
325
|
+
durationMs,
|
|
326
|
+
exitCode: processResult.status,
|
|
327
|
+
logDigest: `sha256:${createHash('sha256').update(log).digest('hex')}`,
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
finally {
|
|
332
|
+
phase.onSettled?.();
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
//# sourceMappingURL=durable-validation.js.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ValidationFreshnessLease, ValidationReceiptBindings } from '../../types/validation-receipt.js';
|
|
2
|
+
export type { ValidationFreshnessLease } from '../../types/validation-receipt.js';
|
|
3
|
+
/**
|
|
4
|
+
* Invalidate the active validation lease for a spec.
|
|
5
|
+
*
|
|
6
|
+
* Filesystem watchers and Planu-owned writers share this entry point so callers
|
|
7
|
+
* that know they changed validation evidence do not depend on fs.watch timing.
|
|
8
|
+
*/
|
|
9
|
+
export declare function invalidateValidationFreshness(input: {
|
|
10
|
+
projectId: string;
|
|
11
|
+
specId: string;
|
|
12
|
+
}): boolean;
|
|
13
|
+
/** Start both watchers before snapshotting and invalidate any older receipt immediately. */
|
|
14
|
+
export declare function beginValidationFreshnessBarrier(input: {
|
|
15
|
+
projectId: string;
|
|
16
|
+
specId: string;
|
|
17
|
+
projectPath: string;
|
|
18
|
+
handoffPath: string;
|
|
19
|
+
invalidateCurrentBindings?: boolean;
|
|
20
|
+
}): Promise<ValidationFreshnessLease>;
|
|
21
|
+
/** Bind the post-watch snapshot; an event before this call makes the lease unusable. */
|
|
22
|
+
export declare function bindValidationFreshnessLease(lease: ValidationFreshnessLease, bindings: ValidationReceiptBindings): Promise<boolean>;
|
|
23
|
+
/** Drain invalidation work and verify epoch, generation, health, expiry and bound inputs. */
|
|
24
|
+
export declare function assertValidationFreshnessBarrier(lease: ValidationFreshnessLease, bindings?: ValidationReceiptBindings): Promise<boolean>;
|
|
25
|
+
export declare function captureValidationFreshnessLease(identity: {
|
|
26
|
+
projectId: string;
|
|
27
|
+
specId: string;
|
|
28
|
+
}, bindings: ValidationReceiptBindings): Promise<ValidationFreshnessLease | undefined>;
|
|
29
|
+
/** Accept validation-generated filesystem activity only after an exact full recomputation. */
|
|
30
|
+
export declare function rebaselineValidationFreshnessLeaseAfterRecompute(input: {
|
|
31
|
+
lease: ValidationFreshnessLease;
|
|
32
|
+
expectedBindings: ValidationReceiptBindings;
|
|
33
|
+
recompute: () => Promise<ValidationReceiptBindings>;
|
|
34
|
+
}): Promise<ValidationFreshnessLease | undefined>;
|
|
35
|
+
export declare function resetValidationFreshnessForTests(): void;
|
|
36
|
+
//# sourceMappingURL=validation-freshness.d.ts.map
|