@planu/cli 4.14.1 → 5.0.0
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 -1
- package/LICENSE +55 -12
- package/README.md +10 -2
- package/dist/cli/commands/install.d.ts +1 -12
- package/dist/cli/commands/install.js +9 -65
- package/dist/cli/commands/job.js +4 -3
- package/dist/cli/commands/spec.js +2 -2
- package/dist/cli/commands/validate.js +2 -2
- package/dist/cli/router.js +1 -3
- package/dist/config/environment-schema.json +1 -3
- package/dist/config/official-sdd-tools.d.ts +4 -0
- package/dist/config/official-sdd-tools.js +35 -0
- package/dist/config/product-public.d.ts +139 -3
- package/dist/config/product-public.js +8 -1
- package/dist/config/product-public.json +7 -36
- package/dist/config/registries/hosts/codex.json +20 -363
- package/dist/config/release-policy.json +84 -2
- package/dist/config/runtime-policy.json +12 -1
- package/dist/config/skill-templates/planu-resume-work.md +2 -2
- package/dist/core/index.d.ts +1 -1
- package/dist/core/spec-validator.d.ts +4 -4
- package/dist/core/spec-validator.js +1 -1
- package/dist/engine/abortable-process-runner.d.ts +20 -2
- package/dist/engine/abortable-process-runner.js +243 -74
- package/dist/engine/ambiguity-scorer.js +4 -26
- package/dist/engine/auth/scope-mapper.js +1 -7
- package/dist/engine/autopilot/state-updater.js +4 -4
- package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
- package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
- package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
- package/dist/engine/ci-generator/planu-config.js +1 -7
- package/dist/engine/clarification-gate/gate.d.ts +3 -3
- package/dist/engine/code-scanner/layer-scanner.js +6 -22
- package/dist/engine/core-bridge.d.ts +3 -3
- package/dist/engine/cost-guardrails.d.ts +1 -1
- package/dist/engine/cost-guardrails.js +1 -1
- package/dist/engine/criterion-identity.d.ts +1 -0
- package/dist/engine/criterion-identity.js +7 -0
- package/dist/engine/dashboard/data-loader.js +2 -7
- package/dist/engine/dashboard/templates-layout.js +0 -3
- package/dist/engine/dashboard/templates-project.js +1 -13
- package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
- package/dist/engine/docs-site-generator/data-collector.js +7 -28
- package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
- package/dist/engine/evidence-gates/artifact-reader.d.ts +10 -1
- package/dist/engine/evidence-gates/artifact-reader.js +115 -2
- package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
- package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
- package/dist/engine/evidence-index/done-drift.d.ts +1 -1
- package/dist/engine/evidence-index/done-drift.js +40 -18
- package/dist/engine/execution/context.js +3 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
- package/dist/engine/execution/job-runtime.d.ts +30 -0
- package/dist/engine/execution/job-runtime.js +114 -6
- package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
- package/dist/engine/execution/public-job-sanitizer.js +31 -0
- package/dist/engine/execution/validate-job-executor.d.ts +12 -1
- package/dist/engine/execution/validate-job-executor.js +549 -86
- package/dist/engine/execution/validate-job-payload.js +107 -50
- package/dist/engine/execution/validate-job-recovery.js +1 -1
- package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
- package/dist/engine/execution/validate-worker-runtime.js +90 -2
- package/dist/engine/execution/validate-worker-thread.js +17 -24
- package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
- package/dist/engine/handoff-artifacts/schemas.js +33 -0
- package/dist/engine/handoff-packager.d.ts +19 -0
- package/dist/engine/handoff-packager.js +415 -13
- package/dist/engine/hooks/effort-configurator.js +1 -1
- package/dist/engine/impact-detector/test-break-predictor.js +3 -3
- package/dist/engine/impact-detector/tool-registration.js +1 -1
- package/dist/engine/implementation-contract/renderer.js +23 -8
- package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
- package/dist/engine/lifecycle-reconciliation-io.js +180 -0
- package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
- package/dist/engine/lifecycle-reconciliation.js +406 -0
- package/dist/engine/local-first/tool-classification.js +2 -0
- package/dist/engine/macos-keychain-native-port.d.ts +5 -0
- package/dist/engine/macos-keychain-native-port.js +19 -7
- package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
- package/dist/engine/migrations/remove-commercial-state.js +343 -0
- package/dist/engine/network-policy.js +1 -0
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +10 -10
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +10 -10
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +10 -10
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +10 -10
- package/dist/engine/readiness-checker.d.ts +1 -16
- package/dist/engine/readiness-checker.js +27 -88
- package/dist/engine/runtime-policy.d.ts +2 -0
- package/dist/engine/runtime-policy.js +42 -5
- package/dist/engine/runtime-security/rate-limiter.js +0 -1
- package/dist/engine/safety/contained-project-file.d.ts +3 -0
- package/dist/engine/safety/contained-project-file.js +23 -0
- package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
- package/dist/engine/scope-boundaries/scope-validator.js +45 -7
- package/dist/engine/session/checkpoint-writer.js +0 -9
- package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
- package/dist/engine/spec-format/acceptance-criteria.js +77 -18
- package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
- package/dist/engine/spec-format/markdown-sections.js +105 -0
- package/dist/engine/spec-format/read-technical-section.js +33 -5
- package/dist/engine/spec-format/technical-md-populator.js +3 -2
- package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
- package/dist/engine/spec-format/unified-spec-builder.js +202 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
- package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
- package/dist/engine/spec-migrator/filesystem-import.js +121 -14
- package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
- package/dist/engine/spec-migrator/index.d.ts +1 -0
- package/dist/engine/spec-migrator/index.js +1 -0
- package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
- package/dist/engine/spec-state-machine/transition-spec.js +10 -1
- package/dist/engine/technical-enricher/index.js +16 -8
- package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
- package/dist/engine/technical-enricher/render-enriched.js +42 -14
- package/dist/engine/telemetry/health-checker.js +53 -17
- package/dist/engine/telemetry/telemetry-client.js +26 -8
- package/dist/engine/text-signal-boundaries.d.ts +2 -0
- package/dist/engine/text-signal-boundaries.js +25 -2
- package/dist/engine/time/relative-date.d.ts +3 -0
- package/dist/engine/time/relative-date.js +16 -0
- package/dist/engine/timing/budget.d.ts +11 -0
- package/dist/engine/timing/budget.js +27 -9
- package/dist/engine/token-optimizer/analytics.d.ts +1 -1
- package/dist/engine/token-optimizer/analytics.js +5 -6
- package/dist/engine/usage-tracker/core.d.ts +2 -2
- package/dist/engine/usage-tracker/core.js +1 -2
- package/dist/engine/usage-tracker/index.d.ts +0 -3
- package/dist/engine/usage-tracker/index.js +0 -3
- package/dist/engine/usage-tracker/stats.d.ts +2 -2
- package/dist/engine/usage-tracker/stats.js +1 -28
- package/dist/engine/validation/durable-validation.d.ts +1 -1
- package/dist/engine/validation/durable-validation.js +3 -82
- package/dist/engine/validation/validation-freshness.d.ts +11 -1
- package/dist/engine/validation/validation-freshness.js +231 -91
- package/dist/engine/validation/validation-receipt.d.ts +9 -6
- package/dist/engine/validation/validation-receipt.js +84 -24
- package/dist/engine/validation/validation-source-digest.d.ts +2 -0
- package/dist/engine/validation/validation-source-digest.js +86 -0
- package/dist/engine/validation/validation-submission.d.ts +5 -4
- package/dist/engine/validation/validation-submission.js +25 -11
- package/dist/engine/validation/validation-worktree.d.ts +21 -0
- package/dist/engine/validation/validation-worktree.js +260 -0
- package/dist/engine/validation-impact-planner.d.ts +14 -2
- package/dist/engine/validation-impact-planner.js +0 -3
- package/dist/engine/validator/dor-dod.d.ts +1 -0
- package/dist/engine/validator/dor-dod.js +5 -3
- package/dist/engine/validator/extractors.d.ts +1 -5
- package/dist/engine/validator/extractors.js +24 -69
- package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
- package/dist/engine/validator/spec-compliance-runner.js +429 -211
- package/dist/engine/validator.js +35 -22
- package/dist/index.js +4 -16
- package/dist/resources/usage-stats-resource.js +2 -18
- package/dist/security/adapters/linux-secret-service.js +7 -3
- package/dist/security/adapters/windows-credential-manager.js +6 -4
- package/dist/server/routes/specs.js +10 -0
- package/dist/storage/base-store.d.ts +1 -1
- package/dist/storage/base-store.js +1 -1
- package/dist/storage/feedback-remote.d.ts +2 -3
- package/dist/storage/feedback-remote.js +45 -31
- package/dist/storage/global-store.d.ts +1 -17
- package/dist/storage/global-store.js +1 -42
- package/dist/storage/index.d.ts +0 -2
- package/dist/storage/index.js +0 -2
- package/dist/storage/migrations/canonical-storage.js +124 -11
- package/dist/storage/runtime-db.d.ts +9 -0
- package/dist/storage/runtime-db.js +64 -8
- package/dist/storage/spec-store.d.ts +14 -2
- package/dist/storage/spec-store.js +104 -14
- package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
- package/dist/storage/status-store/atomic-status-write.js +57 -0
- package/dist/storage/status-store/file-lock.js +30 -11
- package/dist/storage/status-store/self-healing.js +3 -3
- package/dist/storage/status-store/version-sync.d.ts +2 -1
- package/dist/storage/status-store/version-sync.js +35 -40
- package/dist/storage/usage-store.d.ts +1 -5
- package/dist/storage/usage-store.js +0 -35
- package/dist/tools/auto-update-handler.d.ts +3 -3
- package/dist/tools/auto-update-handler.js +3 -3
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
- package/dist/tools/challenge-spec/scenario-collector.js +1 -1
- package/dist/tools/challenge-spec/scenarios-data.js +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
- package/dist/tools/challenge-spec.js +5 -5
- package/dist/tools/check-readiness.js +1 -1
- package/dist/tools/configure-telemetry.js +30 -2
- package/dist/tools/create-spec/spec-builder.js +0 -11
- package/dist/tools/create-spec.d.ts +1 -0
- package/dist/tools/create-spec.js +444 -239
- package/dist/tools/git/branch-ops.d.ts +1 -1
- package/dist/tools/git/branch-ops.js +3 -2
- package/dist/tools/init-project/handler.js +10 -12
- package/dist/tools/init-project/host-assets-writer.js +26 -1
- package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
- package/dist/tools/init-project/migration-runner.d.ts +2 -4
- package/dist/tools/init-project/migration-runner.js +3 -2
- package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
- package/dist/tools/init-project/portable-index-reconciler.js +14 -0
- package/dist/tools/init-project/result-builder.js +1 -3
- package/dist/tools/jobs/handlers.js +38 -6
- package/dist/tools/list-specs.js +5 -26
- package/dist/tools/merge-risk-handler.js +2 -2
- package/dist/tools/package-handoff.js +2 -0
- package/dist/tools/reconcile-spec.js +0 -27
- package/dist/tools/register-agent-squad-tools.js +2 -2
- package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +2 -29
- package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
- package/dist/tools/register-spec-tools/core-spec-tools.js +17 -8
- package/dist/tools/safe-handler.d.ts +5 -13
- package/dist/tools/safe-handler.js +7 -23
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/output-schemas.d.ts +0 -23
- package/dist/tools/schemas/output-schemas.js +0 -28
- package/dist/tools/schemas/spec.d.ts +4 -0
- package/dist/tools/schemas/spec.js +3 -0
- package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
- package/dist/tools/schemas/validate-output-schema.js +7 -0
- package/dist/tools/spec-prompt-handler.js +3 -3
- package/dist/tools/sync-spec-state-handler.d.ts +1 -1
- package/dist/tools/sync-spec-state-handler.js +1 -1
- package/dist/tools/tool-entry.d.ts +4 -4
- package/dist/tools/tool-entry.js +3 -3
- package/dist/tools/tool-registry/core-tools.js +31 -15
- package/dist/tools/tool-registry/group-infra.js +27 -110
- package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
- package/dist/tools/tool-registry/inventory.d.ts +2 -0
- package/dist/tools/tool-registry/inventory.js +2 -0
- package/dist/tools/tool-registry-helpers.d.ts +3 -3
- package/dist/tools/tool-registry-helpers.js +3 -3
- package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
- package/dist/tools/tool-usage-report/registered-tools.js +3 -15
- package/dist/tools/update-status/approval-gates.js +3 -0
- package/dist/tools/update-status/done-receipt-verifier.js +40 -27
- package/dist/tools/update-status/evidence-gate.js +36 -1
- package/dist/tools/update-status/file-sync.d.ts +2 -1
- package/dist/tools/update-status/file-sync.js +57 -6
- package/dist/tools/update-status/index.d.ts +2 -0
- package/dist/tools/update-status/index.js +95 -58
- package/dist/tools/update-status/response-builder.js +3 -3
- package/dist/tools/update-status/side-effects.d.ts +2 -0
- package/dist/tools/update-status/side-effects.js +2 -2
- package/dist/tools/update-status/transition-guard.js +32 -15
- package/dist/tools/update-status-actions.d.ts +4 -2
- package/dist/tools/update-status-actions.js +16 -14
- package/dist/tools/usage-report.js +1 -16
- package/dist/tools/usage-stats.js +1 -18
- package/dist/tools/usage-tracking.d.ts +4 -0
- package/dist/tools/usage-tracking.js +20 -0
- package/dist/tools/validate-lint.d.ts +1 -0
- package/dist/tools/validate-lint.js +1 -1
- package/dist/tools/validate.d.ts +2 -1
- package/dist/tools/validate.js +114 -34
- package/dist/transports/http-transport.js +6 -8
- package/dist/transports/mcp-types.d.ts +0 -2
- package/dist/transports/session-context.js +1 -1
- package/dist/types/cascade-hooks.d.ts +1 -1
- package/dist/types/ci.d.ts +0 -4
- package/dist/types/clarification-token.d.ts +1 -1
- package/dist/types/claude-code-runtime.d.ts +0 -27
- package/dist/types/commercial-migration.d.ts +17 -0
- package/dist/types/commercial-migration.js +2 -0
- package/dist/types/common/primitives.d.ts +0 -2
- package/dist/types/core-bridge.d.ts +4 -10
- package/dist/types/dashboard.d.ts +3 -7
- package/dist/types/docs.d.ts +0 -1
- package/dist/types/durable-job.d.ts +4 -4
- package/dist/types/durable-validation.d.ts +100 -2
- package/dist/types/durable-validation.js +165 -1
- package/dist/types/errors/structured-error.d.ts +3 -3
- package/dist/types/estimation.d.ts +2 -0
- package/dist/types/evidence-gates.d.ts +9 -1
- package/dist/types/execution.d.ts +2 -0
- package/dist/types/gemini-integration.d.ts +0 -11
- package/dist/types/handoff-artifacts.d.ts +41 -0
- package/dist/types/hooks-advanced.d.ts +0 -13
- package/dist/types/impact-detection.d.ts +2 -2
- package/dist/types/index.d.ts +2 -6
- package/dist/types/index.js +1 -5
- package/dist/types/kiro-integration.d.ts +0 -6
- package/dist/types/network-policy.d.ts +1 -1
- package/dist/types/project/lint-scaffolder.d.ts +1 -1
- package/dist/types/runtime-policy.d.ts +11 -0
- package/dist/types/session-safeguard.d.ts +0 -31
- package/dist/types/spec/canonical-repair.d.ts +81 -0
- package/dist/types/spec/canonical-repair.js +2 -0
- package/dist/types/spec/core.d.ts +14 -0
- package/dist/types/spec/index.d.ts +1 -0
- package/dist/types/spec/index.js +1 -0
- package/dist/types/spec/inputs.d.ts +29 -0
- package/dist/types/spec-format.d.ts +24 -0
- package/dist/types/telemetry.d.ts +4 -1
- package/dist/types/transport.d.ts +0 -2
- package/dist/types/usage.d.ts +1 -36
- package/dist/types/usage.js +1 -1
- package/dist/types/validate-worker.d.ts +6 -0
- package/dist/types/validation-receipt.d.ts +1 -1
- package/dist/types/validation.d.ts +2 -2
- package/package.json +16 -12
- package/planu-native.json +1 -1
- package/planu-plugin.json +23 -40
- package/scripts/lib/pending-release-file.mjs +93 -0
- package/src/i18n/messages/en.json +0 -41
- package/src/i18n/messages/es.json +0 -41
- package/src/i18n/messages/pt.json +0 -41
- package/dist/cli/commands/activate.d.ts +0 -14
- package/dist/cli/commands/activate.js +0 -174
- package/dist/config/license-plans.json +0 -251
- package/dist/config/product-public.ts +0 -148
- package/dist/config/server-instructions.ts +0 -121
- package/dist/config/version-defaults.ts +0 -76
- package/dist/config/version.ts +0 -21
- package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
- package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
- package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
- package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
- package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
- package/dist/engine/hooks/full-spectrum-generator.js +0 -117
- package/dist/engine/license-validator/config-loader.d.ts +0 -5
- package/dist/engine/license-validator/config-loader.js +0 -16
- package/dist/engine/license-validator/core.d.ts +0 -15
- package/dist/engine/license-validator/core.js +0 -151
- package/dist/engine/license-validator/fingerprint.d.ts +0 -3
- package/dist/engine/license-validator/fingerprint.js +0 -17
- package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
- package/dist/engine/license-validator/lemon-squeezy.js +0 -55
- package/dist/engine/license-validator.d.ts +0 -5
- package/dist/engine/license-validator.js +0 -6
- package/dist/engine/product-intelligence/index.d.ts +0 -7
- package/dist/engine/product-intelligence/index.js +0 -211
- package/dist/engine/session/auto-save.d.ts +0 -18
- package/dist/engine/session/auto-save.js +0 -98
- package/dist/engine/session/context-snapshot.d.ts +0 -8
- package/dist/engine/session/context-snapshot.js +0 -49
- package/dist/engine/session/memory-sync.d.ts +0 -12
- package/dist/engine/session/memory-sync.js +0 -34
- package/dist/engine/session/session-diff.d.ts +0 -11
- package/dist/engine/session/session-diff.js +0 -42
- package/dist/engine/session/session-merge.d.ts +0 -12
- package/dist/engine/session/session-merge.js +0 -55
- package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
- package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
- package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
- package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
- package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
- package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
- package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
- package/dist/engine/spec-changelog/core.d.ts +0 -16
- package/dist/engine/spec-changelog/core.js +0 -176
- package/dist/engine/spec-changelog/diff.d.ts +0 -18
- package/dist/engine/spec-changelog/diff.js +0 -121
- package/dist/engine/spec-changelog/index.d.ts +0 -3
- package/dist/engine/spec-changelog/index.js +0 -4
- package/dist/engine/trial-engine.d.ts +0 -5
- package/dist/engine/trial-engine.js +0 -14
- package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
- package/dist/engine/usage-tracker/rate-check.js +0 -18
- package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
- package/dist/engine/usage-tracker/rate-limiter.js +0 -73
- package/dist/engine/usage-tracker/trial.d.ts +0 -27
- package/dist/engine/usage-tracker/trial.js +0 -49
- package/dist/engine/webhook/event-handlers.d.ts +0 -25
- package/dist/engine/webhook/event-handlers.js +0 -89
- package/dist/engine/webhook/index.d.ts +0 -4
- package/dist/engine/webhook/index.js +0 -5
- package/dist/engine/webhook/server.d.ts +0 -12
- package/dist/engine/webhook/server.js +0 -249
- package/dist/engine/webhook/signature.d.ts +0 -16
- package/dist/engine/webhook/signature.js +0 -49
- package/dist/storage/license-store.d.ts +0 -6
- package/dist/storage/license-store.js +0 -63
- package/dist/storage/session-store.d.ts +0 -20
- package/dist/storage/session-store.js +0 -136
- package/dist/tools/activate-license.d.ts +0 -6
- package/dist/tools/activate-license.js +0 -132
- package/dist/tools/checkpoint-handler.d.ts +0 -3
- package/dist/tools/checkpoint-handler.js +0 -130
- package/dist/tools/export-session.d.ts +0 -3
- package/dist/tools/export-session.js +0 -90
- package/dist/tools/license-gate.d.ts +0 -18
- package/dist/tools/license-gate.js +0 -222
- package/dist/tools/license-status.d.ts +0 -3
- package/dist/tools/license-status.js +0 -93
- package/dist/tools/list-sessions.d.ts +0 -3
- package/dist/tools/list-sessions.js +0 -46
- package/dist/tools/planu-session-checkpoint.d.ts +0 -6
- package/dist/tools/planu-session-checkpoint.js +0 -42
- package/dist/tools/restore-session.d.ts +0 -3
- package/dist/tools/restore-session.js +0 -71
- package/dist/tools/spec-history.d.ts +0 -3
- package/dist/tools/spec-history.js +0 -59
- package/dist/tools/webhook.d.ts +0 -6
- package/dist/tools/webhook.js +0 -150
- package/dist/types/changelog.d.ts +0 -49
- package/dist/types/changelog.js +0 -3
- package/dist/types/licensing.d.ts +0 -109
- package/dist/types/licensing.js +0 -4
- package/dist/types/product-intelligence.d.ts +0 -60
- package/dist/types/product-intelligence.js +0 -3
- package/dist/types/session.d.ts +0 -84
- package/dist/types/session.js +0 -3
- package/dist/types/webhook.d.ts +0 -62
- package/dist/types/webhook.js +0 -4
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { technologyValue } from '../../engine/technology-registry.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import {
|
|
3
|
+
import { safeGoverned, safeTracked } from '../safe-handler.js';
|
|
4
4
|
import { projectIdSchema, withProject } from '../tool-registry-helpers.js';
|
|
5
5
|
import { t } from '../../i18n/index.js';
|
|
6
6
|
import { makeDeprecationStub } from './deprecated-stubs.js';
|
|
@@ -269,7 +269,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
269
269
|
outputFormat: z.enum(['html', 'json']).optional().describe(FORMAT_DESCRIBE),
|
|
270
270
|
},
|
|
271
271
|
annotations: { title: 'Generate Compliance Report', readOnlyHint: true },
|
|
272
|
-
},
|
|
272
|
+
}, safeGoverned('generate_compliance_report', (args) => Promise.resolve(handleGenerateComplianceReport(args))));
|
|
273
273
|
s.registerTool('audit_log_export', {
|
|
274
274
|
description: 'Export the project audit trail in CSV, JSON, or JSON-LD format. ' +
|
|
275
275
|
'Supports optional date range filtering. ' +
|
|
@@ -290,7 +290,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
290
290
|
.describe('Optional date range filter for audit entries'),
|
|
291
291
|
},
|
|
292
292
|
annotations: { title: 'Export Audit Log', readOnlyHint: true },
|
|
293
|
-
},
|
|
293
|
+
}, safeGoverned('audit_log_export', async (args) => handleAuditLogExport(args)));
|
|
294
294
|
s.registerTool('data_retention_policy', {
|
|
295
295
|
description: 'Configure the data retention policy for the project. ' +
|
|
296
296
|
'Specifies how long data should be retained and whether auto-deletion is enabled. ' +
|
|
@@ -320,7 +320,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
320
320
|
.describe('Days before deletion to notify (default: 7)'),
|
|
321
321
|
},
|
|
322
322
|
annotations: { title: 'Configure Data Retention Policy', readOnlyHint: false },
|
|
323
|
-
},
|
|
323
|
+
}, safeGoverned('data_retention_policy', async (args) => handleDataRetentionPolicy(args)));
|
|
324
324
|
// ── Compliance gate ───────────────────────────────────────────────────────────
|
|
325
325
|
s.registerTool('configure_compliance_gate', {
|
|
326
326
|
description: 'Configure the compliance gate that runs automatically when a spec is sent to review. ' +
|
|
@@ -329,9 +329,9 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
329
329
|
'Pro feature.',
|
|
330
330
|
inputSchema: ConfigureComplianceGateSchema.shape,
|
|
331
331
|
annotations: { title: 'Configure Compliance Gate', destructiveHint: false },
|
|
332
|
-
},
|
|
332
|
+
}, safeGoverned('configure_compliance_gate', async (args) => handleConfigureComplianceGate(args)));
|
|
333
333
|
s.registerTool('compliance_gate_status', {
|
|
334
|
-
description: 'Check the compliance gate configuration for this project. Returns the current mode and threshold.
|
|
334
|
+
description: 'Check the compliance gate configuration for this project. Returns the current mode and threshold.',
|
|
335
335
|
inputSchema: {
|
|
336
336
|
projectPath: z.string().describe('Absolute path to the project root'),
|
|
337
337
|
},
|
|
@@ -363,7 +363,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
363
363
|
.describe(TEST_FORMAT_DESCRIBE),
|
|
364
364
|
},
|
|
365
365
|
annotations: { title: 'Generate Compliance Tests', readOnlyHint: true },
|
|
366
|
-
},
|
|
366
|
+
}, safeGoverned('generate_compliance_tests', async (args) => handleGenerateComplianceTests(args)));
|
|
367
367
|
s.registerTool('compliance_coverage_report', {
|
|
368
368
|
description: 'List all compliance controls for the requested frameworks, showing their IDs, ' +
|
|
369
369
|
'titles, descriptions, and matching keywords. ' +
|
|
@@ -380,7 +380,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
380
380
|
.describe(COMPLIANCE_TEST_FRAMEWORK_DESCRIBE),
|
|
381
381
|
},
|
|
382
382
|
annotations: { title: 'Compliance Coverage Report', readOnlyHint: true },
|
|
383
|
-
},
|
|
383
|
+
}, safeGoverned('compliance_coverage_report', (args) => Promise.resolve(handleComplianceCoverageReport(args))));
|
|
384
384
|
// ── Security ─────────────────────────────────────────────────────────────────
|
|
385
385
|
s.registerTool('security_check', {
|
|
386
386
|
description: t('tools.security_check.description'),
|
|
@@ -398,7 +398,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
398
398
|
.optional()
|
|
399
399
|
.describe('Absolute paths to code files to scan for insecure patterns'),
|
|
400
400
|
},
|
|
401
|
-
},
|
|
401
|
+
}, safeGoverned('security_check', withProject((args) => handleSecurityCheck(args))));
|
|
402
402
|
// ── Audit trail ──────────────────────────────────────────────────────────────
|
|
403
403
|
s.registerTool('audit_trail', {
|
|
404
404
|
description: 'Query the immutable audit log for a project. Supports filtering by specId, userId, eventType, and date range. Returns events with SHA-256 chain integrity status.',
|
|
@@ -430,7 +430,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
430
430
|
.optional()
|
|
431
431
|
.describe('Maximum number of events to return (default: 100, max: 1000).'),
|
|
432
432
|
},
|
|
433
|
-
},
|
|
433
|
+
}, safeGoverned('audit_trail', withProject((args) => handleAuditTrail(args))));
|
|
434
434
|
s.registerTool('generate_attestation', {
|
|
435
435
|
description: 'Generate a compliance attestation document for a specific spec. Includes full audit history, chain integrity verification, and event summary for SOC2/HIPAA/ISO27001 audits.',
|
|
436
436
|
annotations: { readOnlyHint: true },
|
|
@@ -442,7 +442,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
442
442
|
.max(500)
|
|
443
443
|
.describe('Spec ID to generate attestation for (e.g. SPEC-042).'),
|
|
444
444
|
},
|
|
445
|
-
},
|
|
445
|
+
}, safeGoverned('generate_attestation', withProject((args) => handleGenerateAttestation(args))));
|
|
446
446
|
s.registerTool('export_audit_trail', {
|
|
447
447
|
description: 'Export the EU AI Act Article 12 immutable audit trail for every Planu tool invocation. ' +
|
|
448
448
|
'Supports filtering by project, date range, or spec. Verifies SHA-256 chain integrity. ' +
|
|
@@ -478,7 +478,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
478
478
|
.optional()
|
|
479
479
|
.describe('Maximum number of entries to return.'),
|
|
480
480
|
},
|
|
481
|
-
},
|
|
481
|
+
}, safeGoverned('export_audit_trail', (args) => Promise.resolve(handleExportAuditTrail(args))));
|
|
482
482
|
// ── Schema parity ────────────────────────────────────────────────────────────
|
|
483
483
|
s.registerTool('audit_schema_type_parity', {
|
|
484
484
|
description: 'Scans all register-*.ts tool files in the project for mismatches between Zod optional ' +
|
|
@@ -493,7 +493,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
493
493
|
.max(4096)
|
|
494
494
|
.describe('Absolute path to the project root to scan. The auditor will look for src/tools/register-*.ts and src/types/**/*.ts.'),
|
|
495
495
|
},
|
|
496
|
-
},
|
|
496
|
+
}, safeGoverned('audit_schema_type_parity', async (args) => handleAuditSchemaParity(args)));
|
|
497
497
|
s.registerTool('fix_schema_type_parity', {
|
|
498
498
|
description: 'Automatically fixes Zod/TypeScript optional parity issues found by audit_schema_type_parity. ' +
|
|
499
499
|
'Adds "?" to TypeScript type definitions for fields that are marked .optional() in Zod schemas. ' +
|
|
@@ -510,7 +510,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
510
510
|
.default(true)
|
|
511
511
|
.describe('When true (default), shows what would change without writing any files. Set to false to apply the fixes.'),
|
|
512
512
|
},
|
|
513
|
-
},
|
|
513
|
+
}, safeGoverned('fix_schema_type_parity', async (args) => handleFixSchemaParity(args)));
|
|
514
514
|
// ── Schema generator ─────────────────────────────────────────────────────────
|
|
515
515
|
s.registerTool('generate_validation_schema', {
|
|
516
516
|
description: 'Analyze a spec and generate validation schema code (Zod, Yup, or Valibot). ' +
|
|
@@ -605,7 +605,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
605
605
|
.describe('Spec ID to analyze (e.g., "SPEC-001"), or "all" to analyze every spec in the project'),
|
|
606
606
|
},
|
|
607
607
|
annotations: { title: 'Spec Test Coverage', readOnlyHint: true },
|
|
608
|
-
},
|
|
608
|
+
}, safeGoverned('spec_coverage', withProject((args) => handleSpecCoverage(args))));
|
|
609
609
|
// ── Eval skill ───────────────────────────────────────────────────────────────
|
|
610
610
|
s.registerTool('eval_skill', {
|
|
611
611
|
description: 'Evaluate the quality of a Claude skill file against a set of test scenarios. ' +
|
|
@@ -838,7 +838,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
838
838
|
.describe('Evaluation mode: strict (default) requires score >=70; lenient requires >=60'),
|
|
839
839
|
},
|
|
840
840
|
outputSchema: CheckReadinessOutputSchema,
|
|
841
|
-
},
|
|
841
|
+
}, safeGoverned('check_readiness', withProject((args) => handleCheckReadiness(args))));
|
|
842
842
|
// ── SPEC-961: Architecture lint ─────────────────────────────────────────────
|
|
843
843
|
s.registerTool('architecture_lint', {
|
|
844
844
|
description: 'Scan project codebase for Clean Architecture and SOLID principle violations. Reports handler bloat, layer violations, and missing repository patterns.',
|
|
@@ -857,7 +857,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
857
857
|
.describe('Glob patterns to exclude (default: node_modules, .git, dist)'),
|
|
858
858
|
failFast: z.boolean().optional().describe('Stop on first error (default: false)'),
|
|
859
859
|
},
|
|
860
|
-
},
|
|
860
|
+
}, safeGoverned('architecture_lint', withProject((args) => handleArchitectureLint(args))));
|
|
861
861
|
// ── SPEC-962: SOLID check ───────────────────────────────────────────────────
|
|
862
862
|
s.registerTool('solid_check', {
|
|
863
863
|
description: 'Scan project codebase for SOLID principle violations. Reports SRP, OCP, LSP, ISP, and DIP issues with a scored report (0-100) and per-principle breakdown.',
|
|
@@ -870,7 +870,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
870
870
|
.describe('Glob patterns to exclude (default: node_modules, .git, dist)'),
|
|
871
871
|
failFast: z.boolean().optional().describe('Stop on first error (default: false)'),
|
|
872
872
|
},
|
|
873
|
-
},
|
|
873
|
+
}, safeGoverned('solid_check', withProject((args) => handleSolidCheck({
|
|
874
874
|
projectPath: args.projectPath,
|
|
875
875
|
exclude: args.exclude,
|
|
876
876
|
failFast: args.failFast,
|
|
@@ -917,7 +917,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
917
917
|
.optional()
|
|
918
918
|
.describe('Fail on first failing endpoint (default: false)'),
|
|
919
919
|
},
|
|
920
|
-
},
|
|
920
|
+
}, safeGoverned('verify_integrations', withProject((args) => handleVerifyIntegrations({
|
|
921
921
|
projectPath: args.projectPath,
|
|
922
922
|
endpoints: args.endpoints,
|
|
923
923
|
timeout: args.timeout,
|
|
@@ -954,7 +954,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
954
954
|
...projectIdSchema,
|
|
955
955
|
specId: SpecIdSchema.describe('Spec ID to generate handoff package for'),
|
|
956
956
|
},
|
|
957
|
-
},
|
|
957
|
+
}, safeGoverned('package_handoff', withProject((args) => handlePackageHandoff(args))));
|
|
958
958
|
// ── Approval ─────────────────────────────────────────────────────────────────
|
|
959
959
|
s.registerTool('configure_approval_policy', {
|
|
960
960
|
description: 'Define the approval policy for a project: how many approvals are required, ' +
|
|
@@ -980,7 +980,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
980
980
|
.describe('Roles allowed to approve specs. If empty or omitted, any reviewer can approve.'),
|
|
981
981
|
},
|
|
982
982
|
annotations: { title: 'Configure Approval Policy', destructiveHint: false },
|
|
983
|
-
},
|
|
983
|
+
}, safeGoverned('configure_approval_policy', (args) => handleConfigureApprovalPolicy(args)));
|
|
984
984
|
s.registerTool('issue_reviewer_token', {
|
|
985
985
|
description: '[SPEC-722] Issue a signed reviewer token for approve_spec. ' +
|
|
986
986
|
'Must be called from a DIFFERENT session than the one that created the spec. ' +
|
|
@@ -1002,7 +1002,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
1002
1002
|
.describe('Host/agent platform identifier (e.g. "claude-code", "cursor").'),
|
|
1003
1003
|
},
|
|
1004
1004
|
annotations: { title: 'Issue Reviewer Token', destructiveHint: false },
|
|
1005
|
-
},
|
|
1005
|
+
}, safeGoverned('issue_reviewer_token', (args) => handleIssueReviewerToken(args)));
|
|
1006
1006
|
s.registerTool('approve_spec', {
|
|
1007
1007
|
description: '[SPEC-722] Record that a reviewer has approved a spec. ' +
|
|
1008
1008
|
'Requires a signed reviewerToken (from issue_reviewer_token) and the plannerToken ' +
|
|
@@ -1036,7 +1036,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
1036
1036
|
'Allows approval from the same model if the panel was heterogeneous.'),
|
|
1037
1037
|
},
|
|
1038
1038
|
annotations: { title: 'Approve Spec', destructiveHint: true },
|
|
1039
|
-
},
|
|
1039
|
+
}, safeGoverned('approve_spec', (args) => handleApproveSpec(args)));
|
|
1040
1040
|
s.registerTool('request_changes', {
|
|
1041
1041
|
description: 'Request changes on a spec. The spec is moved back to draft and prior approvals are cleared. ' +
|
|
1042
1042
|
'A comment explaining the required changes is mandatory.',
|
|
@@ -1068,7 +1068,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
1068
1068
|
.describe('Role of the reviewer (e.g. "tech-lead", "qa").'),
|
|
1069
1069
|
},
|
|
1070
1070
|
annotations: { title: 'Request Changes', destructiveHint: true },
|
|
1071
|
-
},
|
|
1071
|
+
}, safeGoverned('request_changes', (args) => handleRequestChanges(args)));
|
|
1072
1072
|
s.registerTool('approval_status', {
|
|
1073
1073
|
description: 'Show the current approval status for a spec: who approved, how many are needed, ' +
|
|
1074
1074
|
'time in review, and SLA breach warning if applicable.',
|
|
@@ -1103,7 +1103,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
1103
1103
|
.optional()
|
|
1104
1104
|
.describe('Raw spec content to analyze when specId is not available'),
|
|
1105
1105
|
},
|
|
1106
|
-
},
|
|
1106
|
+
}, safeGoverned('data_governance', withProject((args) => handleDataGovernance(args))));
|
|
1107
1107
|
s.registerTool('legal_compliance_report', {
|
|
1108
1108
|
description: 'Generate a legal compliance report for the project. ' +
|
|
1109
1109
|
'Shows detected legal domains, applicable regulations by country, ' +
|
|
@@ -1113,7 +1113,7 @@ export function registerQualityComplianceGroupTools(s) {
|
|
|
1113
1113
|
inputSchema: {
|
|
1114
1114
|
...projectIdSchema,
|
|
1115
1115
|
},
|
|
1116
|
-
},
|
|
1116
|
+
}, safeGoverned('legal_compliance_report', withProject((args) => handleLegalComplianceReport(args))));
|
|
1117
1117
|
// ── SPEC-322: API Contract Validation ────────────────────────────────────────
|
|
1118
1118
|
s.registerTool('validate_api_contract', {
|
|
1119
1119
|
description: 'Validate an OpenAPI 3.x/Swagger or GraphQL SDL contract against the actual implementation in a project. ' +
|
|
@@ -14,17 +14,17 @@ interface MaybeProjectArgs {
|
|
|
14
14
|
* Wraps a handler that requires a resolved projectId.
|
|
15
15
|
* Resolves projectId from projectId or projectPath; returns missingProjectIdError if neither.
|
|
16
16
|
*
|
|
17
|
-
* Usage (replaces the 5-line resolveProjectId block in each safeTracked/
|
|
17
|
+
* Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeGoverned callback):
|
|
18
18
|
* ```ts
|
|
19
19
|
* // Before:
|
|
20
|
-
*
|
|
20
|
+
* safeGoverned('tool', async (args) => {
|
|
21
21
|
* const pid = resolveProjectId(args as { projectId?: string; projectPath?: string });
|
|
22
22
|
* if (!pid) return missingProjectIdError;
|
|
23
23
|
* return handleFoo({ ...args, projectId: pid } as FooInput);
|
|
24
24
|
* })
|
|
25
25
|
*
|
|
26
26
|
* // After:
|
|
27
|
-
*
|
|
27
|
+
* safeGoverned('tool', withProject((args) => handleFoo(args as never)))
|
|
28
28
|
* ```
|
|
29
29
|
*/
|
|
30
30
|
export declare function withProject<T extends MaybeProjectArgs>(handler: (args: T & {
|
|
@@ -16,17 +16,17 @@ export const projectIdSchema = {
|
|
|
16
16
|
* Wraps a handler that requires a resolved projectId.
|
|
17
17
|
* Resolves projectId from projectId or projectPath; returns missingProjectIdError if neither.
|
|
18
18
|
*
|
|
19
|
-
* Usage (replaces the 5-line resolveProjectId block in each safeTracked/
|
|
19
|
+
* Usage (replaces the 5-line resolveProjectId block in each safeTracked/safeGoverned callback):
|
|
20
20
|
* ```ts
|
|
21
21
|
* // Before:
|
|
22
|
-
*
|
|
22
|
+
* safeGoverned('tool', async (args) => {
|
|
23
23
|
* const pid = resolveProjectId(args as { projectId?: string; projectPath?: string });
|
|
24
24
|
* if (!pid) return missingProjectIdError;
|
|
25
25
|
* return handleFoo({ ...args, projectId: pid } as FooInput);
|
|
26
26
|
* })
|
|
27
27
|
*
|
|
28
28
|
* // After:
|
|
29
|
-
*
|
|
29
|
+
* safeGoverned('tool', withProject((args) => handleFoo(args as never)))
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export function withProject(handler) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns
|
|
2
|
+
* Returns the live tool inventory captured by the canonical registry.
|
|
3
3
|
*/
|
|
4
4
|
export declare function readRegisteredToolNames(): Promise<string[]>;
|
|
5
5
|
//# sourceMappingURL=registered-tools.d.ts.map
|
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
// tools/tool-usage-report/registered-tools.ts — SPEC-574
|
|
2
|
-
|
|
3
|
-
import { readFileSync } from 'node:fs';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { dirname, join } from 'node:path';
|
|
6
|
-
function loadLicensePlans() {
|
|
7
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
-
const __dirname = dirname(__filename);
|
|
9
|
-
const configPath = join(__dirname, '../../config/license-plans.json');
|
|
10
|
-
const raw = readFileSync(configPath, 'utf-8');
|
|
11
|
-
return JSON.parse(raw);
|
|
12
|
-
}
|
|
2
|
+
import { readCanonicalToolNames } from '../tool-registry/inventory.js';
|
|
13
3
|
/**
|
|
14
|
-
* Returns
|
|
4
|
+
* Returns the live tool inventory captured by the canonical registry.
|
|
15
5
|
*/
|
|
16
6
|
export function readRegisteredToolNames() {
|
|
17
|
-
|
|
18
|
-
const allTools = new Set([...plans.freeTools, ...plans.proTools, ...plans.alwaysAllowed]);
|
|
19
|
-
return Promise.resolve([...allTools].sort());
|
|
7
|
+
return Promise.resolve(readCanonicalToolNames().sort());
|
|
20
8
|
}
|
|
21
9
|
//# sourceMappingURL=registered-tools.js.map
|
|
@@ -10,6 +10,9 @@ export async function checkComplianceGate(specId, projectId, projectPath) {
|
|
|
10
10
|
try {
|
|
11
11
|
const { scoreCompliance } = await import('../../engine/verifier/compliance-scorer.js');
|
|
12
12
|
const result = await scoreCompliance(specId, projectPath);
|
|
13
|
+
if (result.totalCriteria === 0 && result.criteriaDetails.length === 0) {
|
|
14
|
+
return { skipped: true, score: null, issues: [], blocked: false };
|
|
15
|
+
}
|
|
13
16
|
const score = result.score;
|
|
14
17
|
const issues = result.criteriaDetails
|
|
15
18
|
.filter((detail) => detail.status === 'unverified')
|
|
@@ -54,8 +54,9 @@ import { isAbsolute, join } from 'node:path';
|
|
|
54
54
|
import { RuntimeDatabase } from '../../storage/runtime-db.js';
|
|
55
55
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
56
56
|
import { projectDataDir } from '../../storage/base-store.js';
|
|
57
|
+
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
57
58
|
import { ValidationReceiptStore, LOCAL_VALIDATION_RECEIPT_ISSUER, createValidationReceiptAuthority, readCurrentValidationReceipt, } from '../../engine/validation/validation-receipt.js';
|
|
58
|
-
import { beginValidationFreshnessBarrier, bindValidationFreshnessLease, captureValidationFreshnessLease, } from '../../engine/validation/validation-freshness.js';
|
|
59
|
+
import { beginValidationFreshnessBarrier, bindValidationFreshnessLease, captureValidationFreshnessLease, closeValidationFreshnessLease, } from '../../engine/validation/validation-freshness.js';
|
|
59
60
|
import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
|
|
60
61
|
export function completedJobPublishesReceipt(job, receiptId) {
|
|
61
62
|
if (job?.state !== 'completed' || !job.result || typeof job.result !== 'object') {
|
|
@@ -105,34 +106,46 @@ export async function verifyCurrentDoneReceipt(identity) {
|
|
|
105
106
|
if (!receiptJobExists) {
|
|
106
107
|
return { valid: false, reason: 'missing-receipt' };
|
|
107
108
|
}
|
|
108
|
-
let
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
109
|
+
let ownedLease = await captureValidationFreshnessLease(identity, currentBindings);
|
|
110
|
+
try {
|
|
111
|
+
if (!ownedLease && identity.projectPath && identity.specPath) {
|
|
112
|
+
const projectPath = identity.projectPath;
|
|
113
|
+
const specPath = isAbsolute(identity.specPath)
|
|
114
|
+
? identity.specPath
|
|
115
|
+
: join(projectPath, identity.specPath);
|
|
116
|
+
ownedLease = await beginValidationFreshnessBarrier({
|
|
117
|
+
projectId: identity.projectId,
|
|
118
|
+
specId: identity.specId,
|
|
119
|
+
projectPath,
|
|
120
|
+
handoffPath: join(projectDataDir(identity.projectId), 'handoffs', identity.specId),
|
|
121
|
+
invalidateCurrentBindings: false,
|
|
122
|
+
});
|
|
123
|
+
const observed = await computeDurableValidationBindings({
|
|
124
|
+
canonicalProjectId: identity.projectId,
|
|
125
|
+
specId: identity.specId,
|
|
126
|
+
projectPath,
|
|
127
|
+
specPath,
|
|
128
|
+
});
|
|
129
|
+
const observedBindings = toValidationReceiptBindings(observed.bindings, observed.artifactDigests);
|
|
130
|
+
if (JSON.stringify(observedBindings) !== JSON.stringify(currentBindings) ||
|
|
131
|
+
!(await bindValidationFreshnessLease(ownedLease, observedBindings))) {
|
|
132
|
+
return { valid: false, reason: 'stale-bindings' };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (!ownedLease) {
|
|
136
|
+
return { valid: false, reason: 'stale-bindings' };
|
|
137
|
+
}
|
|
138
|
+
const transferred = ownedLease;
|
|
139
|
+
ownedLease = undefined;
|
|
140
|
+
return { ...verification, freshnessLease: transferred };
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
if (ownedLease) {
|
|
144
|
+
await closeValidationFreshnessLease(ownedLease).catch((error) => {
|
|
145
|
+
reportClassifiedDegradation('VALIDATION_FRESHNESS_CHECK_FAILED', error);
|
|
146
|
+
});
|
|
131
147
|
}
|
|
132
148
|
}
|
|
133
|
-
return freshnessLease
|
|
134
|
-
? { ...verification, freshnessLease }
|
|
135
|
-
: { valid: false, reason: 'stale-bindings' };
|
|
136
149
|
}
|
|
137
150
|
catch (e_1) {
|
|
138
151
|
env_1.error = e_1;
|
|
@@ -66,8 +66,25 @@ import { ValidationReceiptStore, LOCAL_VALIDATION_RECEIPT_ISSUER, createValidati
|
|
|
66
66
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
67
67
|
import { captureValidationFreshnessLease } from '../../engine/validation/validation-freshness.js';
|
|
68
68
|
import { computeDurableValidationBindings, toValidationReceiptBindings, } from '../../engine/validation/durable-validation.js';
|
|
69
|
+
import { checkReconciliationFreshness } from '../../engine/evidence-gates/reconciliation-freshness.js';
|
|
70
|
+
import { extractCanonicalFileOwnership } from '../../engine/handoff-packager.js';
|
|
69
71
|
/** SPEC-1054: BDD/SDD lifecycle evidence gate. */
|
|
70
72
|
export async function checkLifecycleEvidenceTransitionGate(args) {
|
|
73
|
+
const staleReconciliationEvidence = await checkReconciliationFreshness({
|
|
74
|
+
projectId: args.projectId,
|
|
75
|
+
specId: args.specId,
|
|
76
|
+
});
|
|
77
|
+
if (staleReconciliationEvidence.length > 0) {
|
|
78
|
+
return evidenceGateError({
|
|
79
|
+
specId: args.specId,
|
|
80
|
+
transition: args.transition,
|
|
81
|
+
issues: staleReconciliationEvidence.map(({ artifactId }) => ({
|
|
82
|
+
code: 'SUPERSEDED_RECONCILIATION_EVIDENCE',
|
|
83
|
+
message: artifactId,
|
|
84
|
+
})),
|
|
85
|
+
requiredContractKinds: [],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
71
88
|
const [criteriaResult, artifacts] = await Promise.all([
|
|
72
89
|
extractLifecycleGateCriteriaAndBody(args.spec, args.projectPath),
|
|
73
90
|
readEvidenceArtifacts({
|
|
@@ -108,8 +125,26 @@ export async function checkLifecycleEvidenceTransitionGate(args) {
|
|
|
108
125
|
artifacts,
|
|
109
126
|
projectPath: args.projectPath,
|
|
110
127
|
});
|
|
128
|
+
const canonicalOwnership = body
|
|
129
|
+
? extractCanonicalFileOwnership(body)
|
|
130
|
+
: { present: false, toCreate: [], toModify: [], toTest: [], blockers: [] };
|
|
111
131
|
const groundedTechnicalPaths = body ? parseGroundedTechnicalPaths(body) : [];
|
|
112
|
-
|
|
132
|
+
const approvedScopePaths = [
|
|
133
|
+
...new Set([
|
|
134
|
+
...canonicalOwnership.toCreate,
|
|
135
|
+
...canonicalOwnership.toModify,
|
|
136
|
+
...canonicalOwnership.toTest,
|
|
137
|
+
...groundedTechnicalPaths,
|
|
138
|
+
]),
|
|
139
|
+
];
|
|
140
|
+
if (canonicalOwnership.blockers.length > 0) {
|
|
141
|
+
const safeBlockers = canonicalOwnership.blockers.map((blocker) => blocker.startsWith('CONFLICTING_FILE_OWNERSHIP:') ? blocker : 'INVALID_FILE_OWNERSHIP');
|
|
142
|
+
result.issues.push({
|
|
143
|
+
code: 'done_drift_unapproved_scope',
|
|
144
|
+
message: `Approved canonical ownership is invalid: ${[...new Set(safeBlockers)].join(', ')}.`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
result.issues.push(...checkDoneDriftContract({ index, approvedScopePaths }));
|
|
113
148
|
}
|
|
114
149
|
if (result.issues.length === 0) {
|
|
115
150
|
return null;
|
|
@@ -10,7 +10,7 @@ export interface FrontmatterSyncWarning {
|
|
|
10
10
|
specPath: string | null;
|
|
11
11
|
reason: string;
|
|
12
12
|
}
|
|
13
|
-
export declare function syncSpecFiles(updatedSpec: Spec, _currentStatus: SpecStatus, newStatus: SpecStatus, projectPath?: string): Promise<{
|
|
13
|
+
export declare function syncSpecFiles(updatedSpec: Spec, _currentStatus: SpecStatus, newStatus: SpecStatus, projectPath?: string, qualityWarnings?: readonly string[]): Promise<{
|
|
14
14
|
warning?: FrontmatterSyncWarning;
|
|
15
15
|
}>;
|
|
16
16
|
export declare function tryReconcile(newStatus: string, specId: string, projectId: string): Promise<string | null>;
|
|
@@ -32,5 +32,6 @@ export declare function recordTerminalTransitionEvent(args: {
|
|
|
32
32
|
modelId?: string;
|
|
33
33
|
gateResults?: Record<string, 'pass' | 'fail' | 'skip' | 'forced'>;
|
|
34
34
|
meta?: Record<string, unknown>;
|
|
35
|
+
projectPath?: string;
|
|
35
36
|
}): Promise<void>;
|
|
36
37
|
//# sourceMappingURL=file-sync.d.ts.map
|
|
@@ -3,11 +3,12 @@ import { metricsStore } from '../../storage/index.js';
|
|
|
3
3
|
import { addLesson, getLessons } from '../../storage/lessons-store.js';
|
|
4
4
|
import { dispatchFeedbackEvent } from '../learn.js';
|
|
5
5
|
import { autoReconcileOnDone } from '../update-status-reconcile.js';
|
|
6
|
-
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import { lstat, readFile, realpath } from 'node:fs/promises';
|
|
7
7
|
import { parseFrontmatter } from '../../engine/frontmatter-parser.js';
|
|
8
8
|
import { computeFrontmatterSha } from '../../engine/frontmatter-sha/index.js';
|
|
9
9
|
import { appendTransitionEvent } from '../../storage/transition-log.js';
|
|
10
10
|
import { atomicWriteFile } from '../../engine/safety/atomic-write-file.js';
|
|
11
|
+
import { isAbsolute, normalize, relative, resolve, sep } from 'node:path';
|
|
11
12
|
import { redactFailureMessage, reportClassifiedDegradation, } from '../../errors/classified-degradation.js';
|
|
12
13
|
export async function recordDoneMetrics(projectId, specId, spec, actuals, projectPath) {
|
|
13
14
|
if (actuals.devHours + actuals.reviewHours === 0) {
|
|
@@ -74,6 +75,46 @@ async function autoCaptureLessonEstimation(spec, actuals, accuracy, projectId, p
|
|
|
74
75
|
}
|
|
75
76
|
const SPEC_BODY_SHRINK_ABSOLUTE_THRESHOLD = 200;
|
|
76
77
|
const SPEC_BODY_SHRINK_RATIO_THRESHOLD = 0.05;
|
|
78
|
+
async function resolveSpecPathForTransition(spec, projectPath) {
|
|
79
|
+
if (!projectPath) {
|
|
80
|
+
return spec.specPath;
|
|
81
|
+
}
|
|
82
|
+
const normalizedPath = normalize(spec.specPath);
|
|
83
|
+
const segments = normalizedPath.split(sep).filter(Boolean);
|
|
84
|
+
const planuIndex = segments.lastIndexOf('planu');
|
|
85
|
+
const specDirectory = segments[planuIndex + 2];
|
|
86
|
+
const isPortableContract = planuIndex >= 0 &&
|
|
87
|
+
segments[planuIndex + 1] === 'specs' &&
|
|
88
|
+
segments[planuIndex + 3] === 'spec.md' &&
|
|
89
|
+
planuIndex + 4 === segments.length &&
|
|
90
|
+
specDirectory !== undefined &&
|
|
91
|
+
(specDirectory === spec.id || specDirectory.startsWith(`${spec.id}-`));
|
|
92
|
+
if (!isPortableContract) {
|
|
93
|
+
throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a portable spec contract');
|
|
94
|
+
}
|
|
95
|
+
const selectedRoot = resolve(projectPath);
|
|
96
|
+
const candidate = resolve(selectedRoot, 'planu', 'specs', specDirectory, 'spec.md');
|
|
97
|
+
const relativeCandidate = relative(selectedRoot, candidate);
|
|
98
|
+
if (relativeCandidate.startsWith(`..${sep}`) ||
|
|
99
|
+
relativeCandidate === '..' ||
|
|
100
|
+
isAbsolute(relativeCandidate)) {
|
|
101
|
+
throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath escapes the selected root');
|
|
102
|
+
}
|
|
103
|
+
const [rootRealpath, candidateRealpath, candidateStat] = await Promise.all([
|
|
104
|
+
realpath(selectedRoot),
|
|
105
|
+
realpath(candidate),
|
|
106
|
+
lstat(candidate),
|
|
107
|
+
]);
|
|
108
|
+
const realRelative = relative(rootRealpath, candidateRealpath);
|
|
109
|
+
if (candidateStat.isSymbolicLink() ||
|
|
110
|
+
!candidateStat.isFile() ||
|
|
111
|
+
realRelative.startsWith(`..${sep}`) ||
|
|
112
|
+
realRelative === '..' ||
|
|
113
|
+
isAbsolute(realRelative)) {
|
|
114
|
+
throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: specPath is not a contained regular file');
|
|
115
|
+
}
|
|
116
|
+
return candidateRealpath;
|
|
117
|
+
}
|
|
77
118
|
function bodyWithoutFrontmatter(content) {
|
|
78
119
|
return parseFrontmatter(content).body;
|
|
79
120
|
}
|
|
@@ -95,13 +136,23 @@ function assertSpecBodyIntegrity(args) {
|
|
|
95
136
|
throw new Error(`SPEC_INTEGRITY_WRITE_FAILED: refusing to write ${args.specId} because update_status(${args.newStatus}) would shrink spec.md body by ${String(lost)} characters without an explicit migration marker.`);
|
|
96
137
|
}
|
|
97
138
|
}
|
|
98
|
-
export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, projectPath) {
|
|
139
|
+
export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, projectPath, qualityWarnings = []) {
|
|
99
140
|
let warning;
|
|
100
141
|
if (updatedSpec.specPath) {
|
|
101
142
|
try {
|
|
102
|
-
const
|
|
143
|
+
const transitionSpecPath = await resolveSpecPathForTransition(updatedSpec, projectPath);
|
|
144
|
+
const specContent = await readFile(transitionSpecPath, 'utf-8');
|
|
145
|
+
if (projectPath) {
|
|
146
|
+
const parsedId = parseFrontmatter(specContent).metadata.id;
|
|
147
|
+
if (parsedId !== updatedSpec.id) {
|
|
148
|
+
throw new Error('SPEC_PATH_RELOCALIZATION_FAILED: spec frontmatter ID does not match');
|
|
149
|
+
}
|
|
150
|
+
}
|
|
103
151
|
const { updateFrontmatterField } = await import('../../engine/frontmatter-parser.js');
|
|
104
152
|
let updatedContent = updateFrontmatterField(specContent, 'status', newStatus);
|
|
153
|
+
if (qualityWarnings.length > 0) {
|
|
154
|
+
updatedContent = updateFrontmatterField(updatedContent, 'qualityWarnings', JSON.stringify(qualityWarnings));
|
|
155
|
+
}
|
|
105
156
|
if (newStatus === 'done') {
|
|
106
157
|
updatedContent = markAllCriteriaDone(updatedContent);
|
|
107
158
|
if (isLeanSpecContent(updatedContent)) {
|
|
@@ -114,7 +165,7 @@ export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, proj
|
|
|
114
165
|
newStatus,
|
|
115
166
|
specId: updatedSpec.id,
|
|
116
167
|
});
|
|
117
|
-
await atomicWriteFile(
|
|
168
|
+
await atomicWriteFile(transitionSpecPath, updatedContent);
|
|
118
169
|
// SPEC-544: Auto-stage spec.md after writing so it's included in the user's next commit
|
|
119
170
|
// SPEC-575: Auto-commit staged planu/ docs (idempotent, safe-fail)
|
|
120
171
|
// Commit message must reflect the actual transition — 'mark-done' is only
|
|
@@ -125,7 +176,7 @@ export async function syncSpecFiles(updatedSpec, _currentStatus, newStatus, proj
|
|
|
125
176
|
process.env.PLANU_SUPPRESS_AUTOCOMMIT !== 'true') {
|
|
126
177
|
try {
|
|
127
178
|
const { git: gitCmd } = await import('../git/git-helpers.js');
|
|
128
|
-
await gitCmd(projectPath, ['add', '--',
|
|
179
|
+
await gitCmd(projectPath, ['add', '--', transitionSpecPath]);
|
|
129
180
|
const { planuAutoCommit } = await import('../../engine/git/planu-autocommit.js');
|
|
130
181
|
void planuAutoCommit({
|
|
131
182
|
projectPath,
|
|
@@ -197,7 +248,7 @@ export async function recordTerminalTransitionEvent(args) {
|
|
|
197
248
|
let frontmatterSha;
|
|
198
249
|
if (args.specPath) {
|
|
199
250
|
try {
|
|
200
|
-
const content = await readFile(args.specPath, 'utf-8');
|
|
251
|
+
const content = await readFile(await resolveSpecPathForTransition({ id: args.specId, specPath: args.specPath }, args.projectPath), 'utf-8');
|
|
201
252
|
const { metadata } = parseFrontmatter(content);
|
|
202
253
|
frontmatterSha = computeFrontmatterSha(metadata);
|
|
203
254
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { UpdateStatusInput, ToolResult } from '../../types/index.js';
|
|
3
|
+
/** Bind deferred lifecycle work to one normalized absolute root without persisting that path. */
|
|
4
|
+
export declare function computeTransitionRootBinding(projectPath: string): string;
|
|
3
5
|
/** Recover durable post-commit work for every registered project after server startup. */
|
|
4
6
|
export declare function recoverPendingPostCommitTasksAtStartup(): Promise<void>;
|
|
5
7
|
export declare function handleUpdateStatus(params: UpdateStatusInput, server?: McpServer): Promise<ToolResult>;
|