@planu/cli 5.3.67 → 5.3.69
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 +92 -0
- package/dist/.planu-build.json +1 -1
- package/dist/cli/commands/install.d.ts +2 -15
- package/dist/config/release-policy.json +2 -2
- package/dist/core/shared/fs.d.ts +11 -0
- package/dist/core/shared/fs.js +90 -0
- package/dist/core/shared/strings.d.ts +3 -0
- package/dist/core/shared/strings.js +13 -0
- package/dist/engine/actuals/git-analyzer.js +1 -1
- package/dist/engine/actuals/progress-parser.js +1 -3
- package/dist/engine/agent-handoff-store.js +1 -0
- package/dist/engine/agent-squad/dispatcher.js +1 -0
- package/dist/engine/agent-telemetry.js +1 -0
- package/dist/engine/auth/config.js +1 -0
- package/dist/engine/auto-updater/atomic-upgrade.js +1 -0
- package/dist/engine/auto-updater/index.js +1 -0
- package/dist/engine/autopilot/action-registry.js +20 -0
- package/dist/engine/autopilot/audit-logger.js +1 -0
- package/dist/engine/autopilot/bootstrap.js +9 -2
- package/dist/engine/autopilot/complete-loop.js +4 -0
- package/dist/engine/autopilot/crash-shield-rate-limiter.js +1 -0
- package/dist/engine/autopilot/event-bus.js +1 -0
- package/dist/engine/autopilot/state-updater.js +6 -0
- package/dist/engine/browser-validator.js +1 -3
- package/dist/engine/build-tool-detector.js +1 -8
- package/dist/engine/bundle-installer.js +2 -10
- package/dist/engine/cascade-hooks/core/append-releases.js +1 -0
- package/dist/engine/cascade-hooks/core/write-session-json.js +2 -2
- package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.d.ts +3 -1
- package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.js +12 -3
- package/dist/engine/cascade-hooks/hooks/estimate-calibration.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/housekeeping-on-done.hook.js +2 -0
- package/dist/engine/cascade-hooks/hooks/implementing-kickoff.hook.js +5 -1
- package/dist/engine/cascade-hooks/hooks/lesson-drift.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/orchestration-plan.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/session-context.hook.js +4 -2
- package/dist/engine/cascade-hooks/hooks/slack-notify.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/status-json.hook.js +2 -0
- package/dist/engine/cascade-hooks/hooks/velocity-profile.hook.js +2 -0
- package/dist/engine/cascade-hooks/runner.js +2 -0
- package/dist/engine/cascade-hooks/state-drift-detector.js +2 -0
- package/dist/engine/checkpoint/checkpoint-manager.js +2 -0
- package/dist/engine/checkpoint/policy-engine.js +1 -0
- package/dist/engine/ci-generator/stack-detector.js +2 -10
- package/dist/engine/clarification-gate/token-store.js +1 -0
- package/dist/engine/claude-config-auditor/claudemd-auditor.js +2 -10
- package/dist/engine/claude-config-auditor/settings-auditor.js +2 -10
- package/dist/engine/client-detection.js +2 -10
- package/dist/engine/compliance/auto-remediator.js +1 -0
- package/dist/engine/compliance/evidence-builder.d.ts +2 -2
- package/dist/engine/compliance/framework-catalog.d.ts +6 -6
- package/dist/engine/compliance/gap-analyzer.d.ts +2 -2
- package/dist/engine/config-health/build-tool-checker.js +1 -9
- package/dist/engine/config-health/ci-commands-collector.d.ts +2 -1
- package/dist/engine/config-health/ci-commands-collector.js +2 -9
- package/dist/engine/config-health/go-checker.js +1 -9
- package/dist/engine/config-health/mcp-config-checker.js +2 -10
- package/dist/engine/config-health/python-checker.js +1 -9
- package/dist/engine/config-health/rust-checker.js +1 -9
- package/dist/engine/config-health/ts-checker-scripts.js +1 -9
- package/dist/engine/config-health/ts-checker.js +1 -9
- package/dist/engine/context-artifacts/store.js +1 -0
- package/dist/engine/context-md-generator.js +1 -0
- package/dist/engine/context-orchestrator/index.js +2 -0
- package/dist/engine/convention-scanner/convention-parser.js +2 -9
- package/dist/engine/cost-guardrails.js +1 -0
- package/dist/engine/cost-tracking/ledger.js +1 -0
- package/dist/engine/criterion-identity.js +1 -1
- package/dist/engine/dashboard/data-loader.js +1 -0
- package/dist/engine/dashboard/drift-score.js +2 -0
- package/dist/engine/dashboard/spec-updater.d.ts +3 -1
- package/dist/engine/dashboard/spec-updater.js +9 -2
- package/dist/engine/dashboard/templates-layout.d.ts +2 -2
- package/dist/engine/dashboard/templates-layout.js +2 -9
- package/dist/engine/data-projects-gc/gc-runner.js +2 -4
- package/dist/engine/deleter/audit-logger.js +1 -0
- package/dist/engine/deleter/core.js +6 -0
- package/dist/engine/deleter/trash-manager.js +1 -0
- package/dist/engine/desktop-detector.js +1 -9
- package/dist/engine/detection-utils.d.ts +2 -1
- package/dist/engine/detection-utils.js +3 -10
- package/dist/engine/detectors/advanced-framework-detector/helpers.d.ts +3 -2
- package/dist/engine/detectors/advanced-framework-detector/helpers.js +3 -17
- package/dist/engine/detectors/cicd-detector.js +2 -10
- package/dist/engine/detectors/css-framework-detector.js +2 -10
- package/dist/engine/detectors/deployment-detector.js +3 -12
- package/dist/engine/detectors/frontend-perf-detector.js +2 -10
- package/dist/engine/detectors/gitops-detector.js +3 -11
- package/dist/engine/detectors/idp-detector.js +1 -3
- package/dist/engine/detectors/k3s-detector.js +3 -11
- package/dist/engine/detectors/llm-detector/file-readers.d.ts +2 -1
- package/dist/engine/detectors/llm-detector/file-readers.js +2 -9
- package/dist/engine/detectors/mfe-detector.js +5 -13
- package/dist/engine/detectors/monitoring-detector.js +2 -11
- package/dist/engine/detectors/monorepo-detector.d.ts +1 -0
- package/dist/engine/detectors/monorepo-detector.js +1 -10
- package/dist/engine/detectors/nomad-detector.js +3 -11
- package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -1
- package/dist/engine/detectors/otel-ecosystem-detectors.js +2 -10
- package/dist/engine/doc-generator/executive-summary/html-template.js +1 -7
- package/dist/engine/doc-generator/executive-summary/section-builders.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/mermaid-renderer.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/spec-section-builders.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/technical-report.js +1 -7
- package/dist/engine/doc-generator/portal/analytics-page.js +1 -7
- package/dist/engine/doc-generator/portal/architecture-page.js +1 -7
- package/dist/engine/doc-generator/portal/changelog-page.js +1 -7
- package/dist/engine/doc-generator/portal/decision-page.js +1 -7
- package/dist/engine/doc-generator/portal/decision-timeline-builder.js +1 -7
- package/dist/engine/doc-generator/portal/kanban-view-builder.js +1 -7
- package/dist/engine/doc-generator/portal/portal-breadcrumbs.js +1 -7
- package/dist/engine/doc-generator/portal/portal-landing-cards.js +1 -7
- package/dist/engine/doc-generator/portal/portal-navbar.js +1 -7
- package/dist/engine/doc-generator/portal/portal-page-detector.d.ts +3 -0
- package/dist/engine/doc-generator/portal/portal-page-detector.js +1 -10
- package/dist/engine/doc-generator/portal/portal-regenerator.js +2 -0
- package/dist/engine/doc-generator/portal/risk-matrix-svg.js +1 -7
- package/dist/engine/doc-generator/portal/risk-page.js +1 -7
- package/dist/engine/doc-generator/portal/roadmap-page.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-gantt-builder.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-kpi-builder.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.js +2 -8
- package/dist/engine/doc-generator/proposal/proposal-section-builders.js +1 -7
- package/dist/engine/docs-site-generator/html-templates.js +1 -7
- package/dist/engine/docs-site-generator/markdown-renderer.js +1 -7
- package/dist/engine/drift/violation-resolver.js +2 -0
- package/dist/engine/dynamic-knowledge/knowledge-cache.js +1 -0
- package/dist/engine/ecosystem-absorber/knowledge-cache.js +1 -0
- package/dist/engine/edge-db-detector.js +1 -10
- package/dist/engine/escalator/retry-counter.js +1 -0
- package/dist/engine/evidence-gates/artifact-reader.js +1 -0
- package/dist/engine/evidence-gates/evidence-autofill.js +1 -0
- package/dist/engine/evidence-gates/evidence-skeletons.js +1 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +1 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +1 -0
- package/dist/engine/execution/job-runtime.js +2 -0
- package/dist/engine/execution/validate-job-executor.d.ts +1 -1
- package/dist/engine/execution/validate-job-executor.js +3 -0
- package/dist/engine/execution/validate-job-payload.js +1 -0
- package/dist/engine/execution/validate-worker-thread.js +1 -0
- package/dist/engine/facilitate/context-loader.js +1 -0
- package/dist/engine/figma/change-detector.d.ts +1 -8
- package/dist/engine/figma/code-connect-fetcher.d.ts +1 -7
- package/dist/engine/figma/design-enricher.d.ts +1 -17
- package/dist/engine/figma/design-enricher.js +0 -1
- package/dist/engine/figma/e2e-generator.d.ts +1 -23
- package/dist/engine/figma/flow-analyzer.d.ts +1 -11
- package/dist/engine/figma/frame-extractor.d.ts +1 -11
- package/dist/engine/figma/frame-extractor.js +3 -0
- package/dist/engine/figma/multi-file-manager.d.ts +1 -6
- package/dist/engine/figma/spec-generator.js +2 -0
- package/dist/engine/figma/thumbnail-fetcher.d.ts +1 -1
- package/dist/engine/figma/token-extractor.d.ts +1 -6
- package/dist/engine/figma/token-extractor.js +0 -1
- package/dist/engine/figma/version-tracker.d.ts +1 -7
- package/dist/engine/figma/version-tracker.js +0 -1
- package/dist/engine/figma/visual-qa.d.ts +5 -19
- package/dist/engine/figma/visual-qa.js +1 -2
- package/dist/engine/figma/webhook-manager.d.ts +1 -7
- package/dist/engine/frontmatter-sha/reseal.js +1 -0
- package/dist/engine/frontmatter-sha/verify-terminal.js +1 -0
- package/dist/engine/git-hook-injector.js +2 -10
- package/dist/engine/github/quality-dimensions.js +1 -3
- package/dist/engine/global-rules-manager.js +2 -3
- package/dist/engine/handoff-artifacts/implementation-review-reader.js +1 -0
- package/dist/engine/handoff-artifacts/io.js +2 -0
- package/dist/engine/handoff-packager.js +2 -1
- package/dist/engine/health/auto-fixer.js +1 -0
- package/dist/engine/hooks/context-injector.js +1 -0
- package/dist/engine/hooks-reconciler.js +1 -8
- package/dist/engine/impact-detector/index.js +2 -9
- package/dist/engine/implementation-contract/common.js +1 -3
- package/dist/engine/implementation-contract/evaluator.js +1 -3
- package/dist/engine/keyword-matcher/boundary.d.ts +2 -7
- package/dist/engine/keyword-matcher/boundary.js +2 -14
- package/dist/engine/lifecycle-reconciliation-io.js +1 -0
- package/dist/engine/lifecycle-reconciliation.js +3 -0
- package/dist/engine/local-first/detector.js +1 -9
- package/dist/engine/marketplace-fetcher/cache.js +2 -0
- package/dist/engine/marketplace-fetcher/index.js +1 -0
- package/dist/engine/mcp-config/mcp-config-writer.js +2 -10
- package/dist/engine/migrations/remove-commercial-state.js +2 -0
- package/dist/engine/mobile-detector-shared.d.ts +1 -1
- package/dist/engine/mobile-detector-shared.js +2 -9
- package/dist/engine/multi-channel-notifier.js +1 -0
- package/dist/engine/multi-teammate-review/disagreement-counter.js +1 -0
- package/dist/engine/multi-teammate-review/panel-orchestrator.js +1 -0
- package/dist/engine/onboarding-engine.js +1 -9
- package/dist/engine/permissions-merger/stack-detectors.js +2 -10
- package/dist/engine/pii-detector/core.js +1 -3
- package/dist/engine/platform-engineering/dx-analyzer.js +1 -10
- package/dist/engine/platform-engineering/idp-detector.js +2 -10
- package/dist/engine/project-dna/ai-tool-detector.js +2 -10
- package/dist/engine/project-dna/stack-detector.js +2 -10
- package/dist/engine/project-graph/builder.js +11 -2
- package/dist/engine/project-graph/cache.d.ts +5 -2
- package/dist/engine/project-graph/cache.js +174 -34
- package/dist/engine/project-graph/extractors/decision-store-extractor.js +1 -0
- package/dist/engine/project-graph/freshness-projection.js +3 -0
- package/dist/engine/project-graph/query.js +14 -11
- package/dist/engine/project-health-checker.js +2 -6
- package/dist/engine/provider-adapters/shared/spec-loader.js +1 -0
- package/dist/engine/quality-gates/gate-evaluator.js +1 -3
- package/dist/engine/react-detector.js +6 -14
- package/dist/engine/reconcile/apply-changes.js +1 -3
- package/dist/engine/registry/core.js +1 -0
- package/dist/engine/registry/loader.js +2 -0
- package/dist/engine/release/postmortem-generator.js +1 -0
- package/dist/engine/release/rollback-runner.d.ts +2 -2
- package/dist/engine/release/stuck-spec-detector.js +7 -0
- package/dist/engine/release-pipeline/release-spec-closer.js +3 -0
- package/dist/engine/rules-reconciler.d.ts +1 -1
- package/dist/engine/rules-reconciler.js +2 -9
- package/dist/engine/safety/atomic-writer.js +1 -0
- package/dist/engine/safety/cross-process-lock.js +2 -0
- package/dist/engine/safety/file-mutex.js +1 -0
- package/dist/engine/safety/lock-lease-store.js +1 -0
- package/dist/engine/safety/lock-scavenger.js +2 -0
- package/dist/engine/saga/transition-cascade.js +3 -0
- package/dist/engine/scan-project/index.js +1 -0
- package/dist/engine/scan-project/module-discoverer.js +1 -9
- package/dist/engine/schema-parity-auditor/handler-checker.js +1 -3
- package/dist/engine/schema-parity-auditor/index.js +1 -3
- package/dist/engine/schema-parity-auditor/type-checker.js +1 -3
- package/dist/engine/self-healing/strategies/coverage-fix.js +2 -10
- package/dist/engine/session-context-generator.d.ts +8 -0
- package/dist/engine/session-context-generator.js +33 -23
- package/dist/engine/session-state/session-artifact-refresher.d.ts +7 -0
- package/dist/engine/session-state/session-artifact-refresher.js +140 -0
- package/dist/engine/session-state/writer.d.ts +3 -0
- package/dist/engine/session-state/writer.js +35 -17
- package/dist/engine/shared-agent-memory.js +1 -0
- package/dist/engine/skill-adapter/index.js +3 -0
- package/dist/engine/skill-bootstrap/registry-fetcher.js +1 -0
- package/dist/engine/skill-bootstrap/skill-writer.js +2 -9
- package/dist/engine/skill-bootstrap/stack-matcher.js +1 -9
- package/dist/engine/skill-discovery/multi-agent-writer.d.ts +1 -0
- package/dist/engine/skill-discovery/multi-agent-writer.js +1 -9
- package/dist/engine/skill-generator/workflow-skill-generator.js +1 -0
- package/dist/engine/skill-registry/ttl-refresh.js +2 -0
- package/dist/engine/spec-audit/index.js +2 -0
- package/dist/engine/spec-audit/report-writer.js +1 -0
- package/dist/engine/spec-coverage/core.js +1 -0
- package/dist/engine/spec-decomposer/analyzer.js +1 -11
- package/dist/engine/spec-dependency-graph/dot-exporter.d.ts +1 -1
- package/dist/engine/spec-dependency-graph/graph-builder.d.ts +1 -20
- package/dist/engine/spec-dependency-graph/superseded-set.d.ts +1 -1
- package/dist/engine/spec-diff-engine.js +1 -7
- package/dist/engine/spec-format/read-technical-section.js +1 -3
- package/dist/engine/spec-format/replace-section.js +1 -3
- package/dist/engine/spec-format/spec-id.d.ts +9 -1
- package/dist/engine/spec-format/spec-id.js +24 -3
- package/dist/engine/spec-format/unified-spec-builder.js +1 -3
- package/dist/engine/spec-migrator/canonical-deduplicator.js +2 -0
- package/dist/engine/spec-observability/tracker.js +1 -0
- package/dist/engine/spec-registry/adapter.js +2 -10
- package/dist/engine/spec-registry/validator.d.ts +1 -0
- package/dist/engine/spec-registry/validator.js +1 -9
- package/dist/engine/spec-state-machine/transition-spec.js +1 -0
- package/dist/engine/spec-templates/custom-loader.js +1 -0
- package/dist/engine/stack-auditor/build-tool-auditor.js +1 -9
- package/dist/engine/staleness/stale-implementing.js +5 -14
- package/dist/engine/status-reconciler/index.js +4 -1
- package/dist/engine/structural-memory/helpers.js +1 -0
- package/dist/engine/supply-chain/slsa-checker.js +1 -9
- package/dist/engine/tdd-enforcer/stub-artifact-path.js +1 -0
- package/dist/engine/telemetry/health-checker.js +1 -0
- package/dist/engine/telemetry/telemetry-store.js +1 -0
- package/dist/engine/token-optimizer/response-cache.js +1 -3
- package/dist/engine/tool-groups/group-manager.js +2 -0
- package/dist/engine/update-notifier.js +1 -0
- package/dist/engine/validation/approved-spec-portability.js +1 -0
- package/dist/engine/validation/durable-validation.js +1 -0
- package/dist/engine/validation/validation-freshness.js +2 -0
- package/dist/engine/validation/validation-receipt.js +1 -0
- package/dist/engine/validation/validation-submission.d.ts +1 -1
- package/dist/engine/validation-evidence-ledger.js +1 -0
- package/dist/engine/validator/deep-code-checker.js +1 -3
- package/dist/engine/validator/executable-evidence.d.ts +1 -14
- package/dist/engine/validator/scope-resolver.d.ts +2 -2
- package/dist/engine/validator/spec-compliance-runner.d.ts +1 -31
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/validator.d.ts +1 -1
- package/dist/engine/validator.js +1 -0
- package/dist/engine/velocity/measure-velocity.js +2 -0
- package/dist/engine/version-resolver.js +1 -0
- package/dist/engine/workers/handlers/auto-drift.js +3 -0
- package/dist/engine/workspace-manager.js +4 -0
- package/dist/hosts/gemini/config-scaffold.js +2 -10
- package/dist/storage/approval-operation-lock.js +1 -0
- package/dist/storage/auto-promoter-config-store.js +1 -0
- package/dist/storage/autopilot-log-store.js +1 -0
- package/dist/storage/base-store.js +1 -0
- package/dist/storage/checkpoint-store.js +1 -0
- package/dist/storage/feedback-remote.js +1 -0
- package/dist/storage/gaps-log.js +1 -0
- package/dist/storage/global-projects-store.d.ts +17 -0
- package/dist/storage/global-projects-store.js +47 -0
- package/dist/storage/global-store.js +1 -0
- package/dist/storage/knowledge-store/sessions.js +2 -0
- package/dist/storage/migrations/canonical-storage.js +42 -18
- package/dist/storage/project-drift-store.js +1 -0
- package/dist/storage/project-identity.d.ts +27 -0
- package/dist/storage/project-identity.js +132 -2
- package/dist/storage/project-resolver.js +1 -17
- package/dist/storage/runtime-db.d.ts +2 -20
- package/dist/storage/runtime-db.js +2 -9
- package/dist/storage/semantic-index-store.js +1 -0
- package/dist/storage/sentry-store.js +1 -0
- package/dist/storage/session-state-store.js +1 -0
- package/dist/storage/spec-store.d.ts +31 -3
- package/dist/storage/spec-store.js +146 -5
- package/dist/storage/status-store/atomic-status-write.js +1 -0
- package/dist/storage/status-store/file-lock.js +1 -0
- package/dist/storage/status-store/self-healing.js +1 -0
- package/dist/storage/storage-bundle.d.ts +12 -2
- package/dist/storage/supabase-store.js +1 -0
- package/dist/storage/technology-selection-store.js +1 -0
- package/dist/storage/trash-store.d.ts +2 -4
- package/dist/storage/trash-store.js +2 -15
- package/dist/storage/vector-store/json-fallback.js +1 -0
- package/dist/storage/vector-store/migrator.js +1 -0
- package/dist/storage/vector-store/sqlite-adapter.js +1 -0
- package/dist/tools/audit-claude-config.js +1 -10
- package/dist/tools/challenge-spec-helpers.d.ts +1 -1
- package/dist/tools/challenge-spec-helpers.js +7 -2
- package/dist/tools/challenge-spec.js +11 -6
- package/dist/tools/check-readiness.js +121 -24
- package/dist/tools/clarify-requirements/multiple-choice.d.ts +3 -3
- package/dist/tools/configure-oauth-handler.js +1 -0
- package/dist/tools/create-spec-helpers.d.ts +1 -3
- package/dist/tools/create-spec-helpers.js +1 -8
- package/dist/tools/create-spec.js +1 -13
- package/dist/tools/dashboard.js +5 -0
- package/dist/tools/generate-execution-plan.js +10 -6
- package/dist/tools/github-pr-handler.js +1 -0
- package/dist/tools/github-release-handler.d.ts +1 -0
- package/dist/tools/github-release-handler.js +4 -3
- package/dist/tools/graph-specs.d.ts +1 -1
- package/dist/tools/heal-spec-docs.js +1 -3
- package/dist/tools/init-project/git-setup.d.ts +2 -2
- package/dist/tools/init-project/host-assets-writer.js +2 -10
- package/dist/tools/init-project/lifecycle-helpers.d.ts +2 -2
- package/dist/tools/init-project/lint-scaffolder.js +2 -10
- package/dist/tools/init-project/stack-detector.d.ts +2 -2
- package/dist/tools/reconcile-interactive-question-hooks.d.ts +2 -2
- package/dist/tools/register-sdd-tools.js +1 -0
- package/dist/tools/safe-handler.js +1 -0
- package/dist/tools/schemas/spec-id.d.ts +1 -6
- package/dist/tools/schemas/spec-id.js +1 -16
- package/dist/tools/tool-entry.d.ts +2 -2
- package/dist/tools/tool-entry.js +1 -1
- package/dist/tools/tool-registry/core-tools.d.ts +2 -2
- package/dist/tools/tool-registry/deprecated-stubs.d.ts +3 -3
- package/dist/tools/tool-registry/deprecated-stubs.js +1 -1
- package/dist/tools/triage-request.d.ts +2 -2
- package/dist/tools/update-status/approval-gates.d.ts +2 -2
- package/dist/tools/update-status/approval-gates.js +1 -0
- package/dist/tools/update-status/dod-gates.d.ts +1 -1
- package/dist/tools/update-status/done-receipt-verifier.d.ts +1 -1
- package/dist/tools/update-status/evidence-gate.js +5 -5
- package/dist/tools/update-status/file-sync.js +11 -39
- package/dist/tools/update-status/index.js +1 -1
- package/dist/tools/update-status/side-effects.js +5 -0
- package/dist/tools/update-status/transition-guard.d.ts +1 -1
- package/dist/tools/update-status/transition-guard.js +40 -8
- package/dist/tools/update-status-actions.js +28 -40
- package/dist/tools/validate-graph-coverage.js +14 -2
- package/dist/tools/validate.js +2 -0
- package/dist/transports/middleware/types.d.ts +3 -3
- package/dist/types/atomic-upgrade.d.ts +1 -1
- package/dist/types/cascade-hooks.d.ts +3 -0
- package/dist/types/cross-repo-search.d.ts +2 -0
- package/dist/types/dashboard.d.ts +4 -1
- package/dist/types/durable-job.d.ts +20 -0
- package/dist/types/durable-job.js +9 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/installation.d.ts +16 -0
- package/dist/types/installation.js +2 -0
- package/dist/types/project-knowledge-graph.d.ts +11 -0
- package/dist/types/session-checkpoint.d.ts +16 -0
- package/dist/types/spec-dependency-graph.d.ts +21 -0
- package/dist/types/spec-dependency-graph.js +2 -0
- package/dist/types/validation-evidence.d.ts +45 -0
- package/package.json +2 -2
- package/planu-plugin.json +1 -1
- package/dist/types/storage-bundle.d.ts +0 -13
- package/dist/types/storage-bundle.js +0 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
1
2
|
import { technologyValue } from '../engine/technology-registry.js';
|
|
2
3
|
// storage/sentry-store.ts — Sentry integration persistence (SPEC-435)
|
|
3
4
|
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
@@ -4,6 +4,7 @@ import { readJson, writeJson } from './base-store.js';
|
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { execSync } from 'node:child_process';
|
|
6
6
|
import { readFile } from 'node:fs/promises';
|
|
7
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
7
8
|
import { getUniqueTopLevelFrontmatterString } from '../engine/frontmatter-parser.js';
|
|
8
9
|
import { reportClassifiedDegradation } from '../errors/classified-degradation.js';
|
|
9
10
|
// ---------------------------------------------------------------------------
|
|
@@ -20,6 +20,13 @@ export declare function validateCanonicalSpecRows(projectId: string, specs: read
|
|
|
20
20
|
export declare function withCanonicalSpecRepairLock<T>(projectId: string, fn: () => Promise<T>): Promise<T>;
|
|
21
21
|
/** Evict the cache for a project (e.g. after external file changes). */
|
|
22
22
|
export declare function invalidateSpecsCache(projectId: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Discover the canonical `planu/specs/<specId[-slug]>/spec.md` for a spec by ID,
|
|
25
|
+
* independent of any stale or missing registry record. Fails closed (returns
|
|
26
|
+
* `null`) on zero or ambiguous matches, matching the fail-closed contract of
|
|
27
|
+
* {@link resolveVerifiedSpecPath}.
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverCanonicalSpecPath(specId: string, canonicalRoot: string): Promise<string | null>;
|
|
23
30
|
/**
|
|
24
31
|
* List every spec for a project.
|
|
25
32
|
*/
|
|
@@ -31,10 +38,31 @@ export declare function listSpecs(projectId: string): Promise<Spec[]>;
|
|
|
31
38
|
export declare function withFreshSpecsLock<T>(projectId: string, fn: (specs: Spec[]) => Promise<T>): Promise<T>;
|
|
32
39
|
/**
|
|
33
40
|
* Get a single spec by ID. Returns `null` when not found.
|
|
34
|
-
|
|
35
|
-
|
|
41
|
+
*
|
|
42
|
+
* When `canonicalRoot` is supplied, a legacy absolute `specPath`/`technicalPath`
|
|
43
|
+
* for this spec is migrated to its portable project-relative identity first
|
|
44
|
+
* (best-effort — a failed migration attempt never blocks the read).
|
|
45
|
+
*/
|
|
46
|
+
export declare function getSpec(projectId: string, specId: string, canonicalRoot?: string): Promise<Spec | null>;
|
|
47
|
+
/** Result of a {@link migrateLegacySpecPaths} run. */
|
|
48
|
+
export interface SpecPathMigrationResult {
|
|
49
|
+
readonly migrated: number;
|
|
50
|
+
readonly specIds: readonly string[];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Atomically migrate every eligible legacy absolute `specPath`/`technicalPath`
|
|
54
|
+
* in this project to its portable project-relative identity.
|
|
55
|
+
*
|
|
56
|
+
* Runs under the existing cross-process spec-store lock. A record migrates only
|
|
57
|
+
* when its normalized relative suffix identifies the same spec and the file
|
|
58
|
+
* exists under the verified `canonicalRoot` — never by guessing. Migration
|
|
59
|
+
* changes only the stored path identity; it never touches spec content.
|
|
60
|
+
* Idempotent: a spec already holding a portable path is a no-op. Emits at
|
|
61
|
+
* most one audit event per call, regardless of how many specs migrated.
|
|
62
|
+
*/
|
|
63
|
+
export declare function migrateLegacySpecPaths(projectId: string, canonicalRoot: string, specIds?: readonly string[]): Promise<SpecPathMigrationResult>;
|
|
36
64
|
/** Reload a spec from disk after the caller acquires its cross-process lock. */
|
|
37
|
-
export declare function getSpecFresh(projectId: string, specId: string): Promise<Spec | null>;
|
|
65
|
+
export declare function getSpecFresh(projectId: string, specId: string, canonicalRoot?: string): Promise<Spec | null>;
|
|
38
66
|
/** SPEC-601: Lookup a spec by its globally unique UUID. */
|
|
39
67
|
export declare function getSpecByUuid(projectId: string, uuid: string): Promise<Spec | null>;
|
|
40
68
|
/**
|
|
@@ -3,10 +3,19 @@ import { CriticalJsonReadError, readCriticalJson, readJson, writeJson, projectDa
|
|
|
3
3
|
import { decodeCriticalSchema, registerCriticalSchema } from './schema-registry.js';
|
|
4
4
|
import { BoundaryFailure } from '../errors/error-taxonomy.js';
|
|
5
5
|
import { withFileLock } from './file-mutex.js';
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
6
7
|
import { computeHealthScore } from '../engine/spec-health-scorer.js';
|
|
8
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
7
9
|
import { loadSpecContent } from '../engine/validation-loop.js';
|
|
8
10
|
import { createHash, randomUUID } from 'node:crypto';
|
|
11
|
+
import { basename, dirname, isAbsolute, join } from 'node:path';
|
|
12
|
+
import { glob } from 'glob';
|
|
13
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
9
14
|
import { acquireLock, releaseLock } from '../engine/safety/cross-process-lock.js';
|
|
15
|
+
import { resolvePortableSpecPath, toPortableSpecPath, PortablePathError, } from './project-identity.js';
|
|
16
|
+
import { appendEntry, getLastHash } from './audit-trail-store.js';
|
|
17
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
18
|
+
import { hashEntry } from '../engine/audit-trail/hasher.js';
|
|
10
19
|
// ---------------------------------------------------------------------------
|
|
11
20
|
// SPEC-720: Guard error — direct status write forbidden
|
|
12
21
|
// ---------------------------------------------------------------------------
|
|
@@ -197,6 +206,21 @@ async function saveAll(projectId, specs) {
|
|
|
197
206
|
export function invalidateSpecsCache(projectId) {
|
|
198
207
|
specsCache.delete(projectId);
|
|
199
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Discover the canonical `planu/specs/<specId[-slug]>/spec.md` for a spec by ID,
|
|
211
|
+
* independent of any stale or missing registry record. Fails closed (returns
|
|
212
|
+
* `null`) on zero or ambiguous matches, matching the fail-closed contract of
|
|
213
|
+
* {@link resolveVerifiedSpecPath}.
|
|
214
|
+
*/
|
|
215
|
+
export async function discoverCanonicalSpecPath(specId, canonicalRoot) {
|
|
216
|
+
const pattern = join(canonicalRoot, 'planu', 'specs', '*', 'spec.md');
|
|
217
|
+
const matches = await glob(pattern, { absolute: true });
|
|
218
|
+
const candidates = matches.filter((path) => {
|
|
219
|
+
const dir = basename(dirname(path));
|
|
220
|
+
return dir === specId || dir.startsWith(`${specId}-`);
|
|
221
|
+
});
|
|
222
|
+
return candidates.length === 1 ? (candidates[0] ?? null) : null;
|
|
223
|
+
}
|
|
200
224
|
// --- public API ---
|
|
201
225
|
/**
|
|
202
226
|
* List every spec for a project.
|
|
@@ -213,21 +237,136 @@ export async function withFreshSpecsLock(projectId, fn) {
|
|
|
213
237
|
}
|
|
214
238
|
/**
|
|
215
239
|
* Get a single spec by ID. Returns `null` when not found.
|
|
240
|
+
*
|
|
241
|
+
* When `canonicalRoot` is supplied, a legacy absolute `specPath`/`technicalPath`
|
|
242
|
+
* for this spec is migrated to its portable project-relative identity first
|
|
243
|
+
* (best-effort — a failed migration attempt never blocks the read).
|
|
216
244
|
*/
|
|
217
|
-
export async function getSpec(projectId, specId) {
|
|
245
|
+
export async function getSpec(projectId, specId, canonicalRoot) {
|
|
246
|
+
if (canonicalRoot !== undefined) {
|
|
247
|
+
await migrateLegacySpecPaths(projectId, canonicalRoot, [specId]).catch((error) => {
|
|
248
|
+
reportClassifiedDegradation('SPEC_PATH_MIGRATION_DEFERRED', error);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
218
251
|
const specs = await loadAll(projectId);
|
|
219
252
|
return specs.find((s) => s.id === specId) ?? null;
|
|
220
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Record one hash-chained audit event for a legacy specPath migration batch.
|
|
256
|
+
* Best-effort: an audit failure never rolls back an already-persisted migration.
|
|
257
|
+
*/
|
|
258
|
+
function recordSpecPathMigrationAudit(projectId, specIds) {
|
|
259
|
+
try {
|
|
260
|
+
const partial = {
|
|
261
|
+
id: randomUUID(),
|
|
262
|
+
timestamp: new Date().toISOString(),
|
|
263
|
+
toolName: 'spec-store.migrateLegacySpecPaths',
|
|
264
|
+
inputSummary: `projectId=${projectId} specIds=${specIds.join(',')}`.slice(0, 200),
|
|
265
|
+
outputType: 'success',
|
|
266
|
+
durationMs: 0,
|
|
267
|
+
prevHash: getLastHash(),
|
|
268
|
+
};
|
|
269
|
+
appendEntry({ ...partial, hash: hashEntry(partial) });
|
|
270
|
+
}
|
|
271
|
+
catch (error) {
|
|
272
|
+
reportClassifiedDegradation('SPEC_PATH_MIGRATION_AUDIT', error);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Atomically migrate every eligible legacy absolute `specPath`/`technicalPath`
|
|
277
|
+
* in this project to its portable project-relative identity.
|
|
278
|
+
*
|
|
279
|
+
* Runs under the existing cross-process spec-store lock. A record migrates only
|
|
280
|
+
* when its normalized relative suffix identifies the same spec and the file
|
|
281
|
+
* exists under the verified `canonicalRoot` — never by guessing. Migration
|
|
282
|
+
* changes only the stored path identity; it never touches spec content.
|
|
283
|
+
* Idempotent: a spec already holding a portable path is a no-op. Emits at
|
|
284
|
+
* most one audit event per call, regardless of how many specs migrated.
|
|
285
|
+
*/
|
|
286
|
+
export async function migrateLegacySpecPaths(projectId, canonicalRoot, specIds) {
|
|
287
|
+
return withSpecMutationLock(projectId, async () => {
|
|
288
|
+
const specs = await loadAll(projectId);
|
|
289
|
+
const scope = specIds ? new Set(specIds) : null;
|
|
290
|
+
const migratedIds = [];
|
|
291
|
+
const next = await Promise.all(specs.map(async (spec) => {
|
|
292
|
+
if (scope && !scope.has(spec.id)) {
|
|
293
|
+
return spec;
|
|
294
|
+
}
|
|
295
|
+
if (typeof spec.specPath !== 'string' || !isAbsolute(spec.specPath)) {
|
|
296
|
+
return spec;
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
await resolvePortableSpecPath(spec.id, spec.specPath, canonicalRoot);
|
|
300
|
+
}
|
|
301
|
+
catch (error) {
|
|
302
|
+
reportClassifiedDegradation('SPEC_PATH_MIGRATION_SKIPPED', error);
|
|
303
|
+
return spec;
|
|
304
|
+
}
|
|
305
|
+
const portableSpecPath = toPortableSpecPath(spec.id, spec.specPath);
|
|
306
|
+
let portableTechnicalPath = spec.technicalPath;
|
|
307
|
+
if (typeof spec.technicalPath === 'string' && isAbsolute(spec.technicalPath)) {
|
|
308
|
+
try {
|
|
309
|
+
portableTechnicalPath = toPortableSpecPath(spec.id, spec.technicalPath);
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
reportClassifiedDegradation('TECHNICAL_PATH_MIGRATION_SKIPPED', error);
|
|
313
|
+
portableTechnicalPath = spec.technicalPath;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
migratedIds.push(spec.id);
|
|
317
|
+
return { ...spec, specPath: portableSpecPath, technicalPath: portableTechnicalPath };
|
|
318
|
+
}));
|
|
319
|
+
if (migratedIds.length > 0) {
|
|
320
|
+
await saveAll(projectId, next);
|
|
321
|
+
recordSpecPathMigrationAudit(projectId, migratedIds);
|
|
322
|
+
}
|
|
323
|
+
return { migrated: migratedIds.length, specIds: migratedIds };
|
|
324
|
+
});
|
|
325
|
+
}
|
|
221
326
|
/** Reload a spec from disk after the caller acquires its cross-process lock. */
|
|
222
|
-
export async function getSpecFresh(projectId, specId) {
|
|
327
|
+
export async function getSpecFresh(projectId, specId, canonicalRoot) {
|
|
223
328
|
specsCache.delete(projectId);
|
|
224
|
-
return getSpec(projectId, specId);
|
|
329
|
+
return getSpec(projectId, specId, canonicalRoot);
|
|
225
330
|
}
|
|
226
331
|
/** SPEC-601: Lookup a spec by its globally unique UUID. */
|
|
227
332
|
export async function getSpecByUuid(projectId, uuid) {
|
|
228
333
|
const specs = await loadAll(projectId);
|
|
229
334
|
return (specs.find((spec) => spec.uuid === uuid || spec.uuidAliases?.includes(uuid) === true) ?? null);
|
|
230
335
|
}
|
|
336
|
+
/**
|
|
337
|
+
* Normalize an incoming absolute `specPath`/`technicalPath` — rooted in whatever
|
|
338
|
+
* checkout the caller invoked from — to its portable project-relative identity
|
|
339
|
+
* before it ever reaches disk. A value that is not the standard
|
|
340
|
+
* `planu/specs/<specId[-slug]>/<file>` shape is left untouched (best-effort):
|
|
341
|
+
* the shared resolver still fails closed for it at read time.
|
|
342
|
+
*/
|
|
343
|
+
function portableizeSpecPaths(spec) {
|
|
344
|
+
let specPath = spec.specPath;
|
|
345
|
+
let technicalPath = spec.technicalPath;
|
|
346
|
+
if (typeof specPath === 'string' && isAbsolute(specPath)) {
|
|
347
|
+
try {
|
|
348
|
+
specPath = toPortableSpecPath(spec.id, specPath);
|
|
349
|
+
}
|
|
350
|
+
catch (error) {
|
|
351
|
+
if (!(error instanceof PortablePathError)) {
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
if (typeof technicalPath === 'string' && isAbsolute(technicalPath)) {
|
|
357
|
+
try {
|
|
358
|
+
technicalPath = toPortableSpecPath(spec.id, technicalPath);
|
|
359
|
+
}
|
|
360
|
+
catch (error) {
|
|
361
|
+
if (!(error instanceof PortablePathError)) {
|
|
362
|
+
throw error;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return specPath === spec.specPath && technicalPath === spec.technicalPath
|
|
367
|
+
? spec
|
|
368
|
+
: { ...spec, specPath, technicalPath };
|
|
369
|
+
}
|
|
231
370
|
/**
|
|
232
371
|
* Create a new spec. Throws if a spec with the same ID already exists.
|
|
233
372
|
*/
|
|
@@ -238,9 +377,11 @@ export async function createSpec(projectId, spec) {
|
|
|
238
377
|
throw new Error(`Spec "${spec.id}" already exists in project "${projectId}"`);
|
|
239
378
|
}
|
|
240
379
|
const { criteria } = await loadSpecContent(spec);
|
|
380
|
+
const portableSpec = portableizeSpecPaths(spec);
|
|
241
381
|
const specWithScore = {
|
|
242
|
-
...
|
|
243
|
-
healthScore: computeHealthScore(
|
|
382
|
+
...portableSpec,
|
|
383
|
+
healthScore: computeHealthScore(portableSpec, criteria.length > 0 ? criteria : undefined)
|
|
384
|
+
.score,
|
|
244
385
|
};
|
|
245
386
|
const nextSpecs = [...specs, specWithScore];
|
|
246
387
|
await saveAll(projectId, nextSpecs);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { readdir, unlink } from 'node:fs/promises';
|
|
2
2
|
import { basename, dirname } from 'node:path';
|
|
3
3
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
4
5
|
import { atomicWriteFile } from '../../engine/safety/atomic-write-file.js';
|
|
5
6
|
/** Publish one complete canonical status snapshot with same-directory atomic replacement. */
|
|
6
7
|
export function atomicStatusWrite(statusPath, status) {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// Uses a local FIFO for fair in-process ordering and the existing SQLite fenced lease for
|
|
4
4
|
// exclusion across CLI, MCP, durable-worker, and background-side-effect processes.
|
|
5
5
|
import { resolve } from 'node:path';
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
6
7
|
import { acquireLock, releaseLock } from '../../engine/safety/file-mutex.js';
|
|
7
8
|
import { cleanupDeadStatusTemps } from './atomic-status-write.js';
|
|
8
9
|
const lockQueues = new Map();
|
|
@@ -110,6 +110,7 @@ export async function quarantineCorruptStatus(statusPath, projectPath) {
|
|
|
110
110
|
}
|
|
111
111
|
return { quarantinedAt: new Date().toISOString(), quarantinePath };
|
|
112
112
|
}
|
|
113
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
113
114
|
import { fastScanSpecsAsync } from '../../engine/core-bridge.js';
|
|
114
115
|
/**
|
|
115
116
|
* Rebuild a fresh status.json by reading all spec.md frontmatters.
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
export
|
|
1
|
+
import { RuntimeDatabase, type RuntimeProjectBundle } from './runtime-db.js';
|
|
2
|
+
export interface StorageBundle {
|
|
3
|
+
readonly schemaVersion: 1;
|
|
4
|
+
readonly createdAt: string;
|
|
5
|
+
readonly runtimeSchemaVersion: number;
|
|
6
|
+
readonly projectId: string;
|
|
7
|
+
readonly payload: RuntimeProjectBundle;
|
|
8
|
+
readonly checksum: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StorageBundleOptions {
|
|
11
|
+
readonly database?: RuntimeDatabase;
|
|
12
|
+
}
|
|
3
13
|
export declare function exportStorageBundle(projectId: string, outputPath: string, options?: StorageBundleOptions): Promise<StorageBundle>;
|
|
4
14
|
export declare function importStorageBundle(inputPath: string, options?: StorageBundleOptions): Promise<StorageBundle>;
|
|
5
15
|
//# sourceMappingURL=storage-bundle.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
1
2
|
import { technologyValue } from '../engine/technology-registry.js';
|
|
2
3
|
// storage/supabase-store.ts — Supabase integration persistence (SPEC-437)
|
|
3
4
|
import { join } from 'node:path';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// storage/technology-selection-store.ts — SPEC-1021 project-local technology contract
|
|
2
2
|
import { mkdir, readFile } from 'node:fs/promises';
|
|
3
3
|
import { dirname, join } from 'node:path';
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
4
5
|
import { writeJsonSafe } from '../engine/safety/atomic-writer.js';
|
|
5
6
|
import { safeJsonParse } from './base-store.js';
|
|
6
7
|
import { withFileLock } from './file-mutex.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { TrashItem } from '../types/index.js';
|
|
2
2
|
import type { TrashCleanupConfig, TrashCleanupResult } from '../types/safety.js';
|
|
3
|
+
import { pathExistsStrictByStat as pathExists } from '../core/shared/fs.js';
|
|
4
|
+
export { pathExists };
|
|
3
5
|
/**
|
|
4
6
|
* Load the trash manifest (list of all trashed items).
|
|
5
7
|
*/
|
|
@@ -29,10 +31,6 @@ export declare function purgeAllTrash(projectId: string): Promise<number>;
|
|
|
29
31
|
* Count files in a directory recursively (for project delete summary).
|
|
30
32
|
*/
|
|
31
33
|
export declare function countFiles(dirPath: string): Promise<number>;
|
|
32
|
-
/**
|
|
33
|
-
* Check if a path exists.
|
|
34
|
-
*/
|
|
35
|
-
export declare function pathExists(p: string): Promise<boolean>;
|
|
36
34
|
/**
|
|
37
35
|
* Recursively sum file sizes in a directory.
|
|
38
36
|
*/
|
|
@@ -2,6 +2,8 @@ import { readJson, writeJson, projectDataDir } from './base-store.js';
|
|
|
2
2
|
import { withFileLock } from './file-mutex.js';
|
|
3
3
|
import { mkdir, cp, rm, readdir, stat } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
|
+
import { pathExistsStrictByStat as pathExists } from '../core/shared/fs.js';
|
|
6
|
+
export { pathExists };
|
|
5
7
|
function sanitizeId(id) {
|
|
6
8
|
const sanitized = id.replace(/[/\\]/g, '_').replace(/\.\./g, '_');
|
|
7
9
|
if (!sanitized || sanitized === '.' || sanitized === '..') {
|
|
@@ -176,21 +178,6 @@ export async function countFiles(dirPath) {
|
|
|
176
178
|
throw error;
|
|
177
179
|
}
|
|
178
180
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Check if a path exists.
|
|
181
|
-
*/
|
|
182
|
-
export async function pathExists(p) {
|
|
183
|
-
try {
|
|
184
|
-
await stat(p);
|
|
185
|
-
return true;
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
if (error.code === 'ENOENT') {
|
|
189
|
-
return false;
|
|
190
|
-
}
|
|
191
|
-
throw error;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
181
|
// ---------------------------------------------------------------------------
|
|
195
182
|
// Trash TTL cleanup (SPEC-094 AC-6)
|
|
196
183
|
// ---------------------------------------------------------------------------
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPEC-075 AC-04: Same interface as SQLite adapter, uses JSON files.
|
|
3
3
|
import { readJson, writeJson, projectDataDir } from '../base-store.js';
|
|
4
4
|
import { withFileLock } from '../file-mutex.js';
|
|
5
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
5
6
|
import { cosineSimilarity } from '../../engine/vector-store/similarity.js';
|
|
6
7
|
let warnedOnce = false;
|
|
7
8
|
/**
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPEC-075 AC-05: Idempotent, preserves JSON backup.
|
|
3
3
|
import { readJson, projectDataDir } from '../base-store.js';
|
|
4
4
|
import { existsSync } from 'node:fs';
|
|
5
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
5
6
|
import { TFIDFEngine } from '../../engine/vector-store/tfidf.js';
|
|
6
7
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
7
8
|
/** Check if a migration marker exists (idempotency). */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// storage/vector-store/sqlite-adapter.ts — SQLite storage backend using better-sqlite3.
|
|
2
2
|
// SPEC-075 AC-03: WAL mode, BLOB embeddings, optional native dependency.
|
|
3
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
3
4
|
import { cosineSimilarity } from '../../engine/vector-store/similarity.js';
|
|
4
5
|
import { projectDataDir, safeJsonParse } from '../base-store.js';
|
|
5
6
|
import { mkdirSync, existsSync } from 'node:fs';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// audit-claude-config.ts — Tool handler for audit_claude_config (SPEC-092)
|
|
2
2
|
// SPEC-724: Added gate='core-rules' to assert per-host rule files exist.
|
|
3
3
|
import { compactResult } from './output-formatter.js';
|
|
4
|
+
import { fileExists } from '../core/shared/fs.js';
|
|
4
5
|
import { auditClaudeMd, auditRules, auditMemory, auditSettings, calculateScore, pickQuickWins, } from '../engine/claude-config-auditor/index.js';
|
|
5
6
|
import { detectHost } from '../engine/host-detection/detect-host.js';
|
|
6
|
-
import { access } from 'node:fs/promises';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { homedir } from 'node:os';
|
|
9
9
|
// ---------------------------------------------------------------------------
|
|
@@ -14,15 +14,6 @@ const CORE_RULES_FILES = [
|
|
|
14
14
|
'parallelism.md',
|
|
15
15
|
'token-optimization.md',
|
|
16
16
|
];
|
|
17
|
-
async function fileExists(filePath) {
|
|
18
|
-
try {
|
|
19
|
-
await access(filePath);
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
17
|
async function checkCoreRulesGate(projectPath) {
|
|
27
18
|
const host = detectHost();
|
|
28
19
|
const blockers = [];
|
|
@@ -11,5 +11,5 @@ export interface ConcurrencyAnalysisResult extends ConcurrencyAnalysis {
|
|
|
11
11
|
export declare function generateConcurrencyAnalysis(_spec: Spec, content: string, _knowledge: ProjectKnowledge): ConcurrencyAnalysisResult;
|
|
12
12
|
export declare function buildScalabilityAssessment(spec: Spec, knowledge: ProjectKnowledge, scenarios: FailureScenario[], hasRolloutEvidence?: boolean): string;
|
|
13
13
|
export declare function calculateOverallRisk(scenarios: FailureScenario[], concurrency: ConcurrencyAnalysis): RiskLevel;
|
|
14
|
-
export declare function readSpecContent(spec: Spec): Promise<string>;
|
|
14
|
+
export declare function readSpecContent(spec: Spec, projectPath?: string): Promise<string>;
|
|
15
15
|
//# sourceMappingURL=challenge-spec-helpers.d.ts.map
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// tools/challenge-spec-helpers.ts — Concurrency, risk, and spec-reader helpers for challenge-spec
|
|
2
2
|
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { isAbsolute } from 'node:path';
|
|
4
|
+
import { resolveVerifiedSpecPath } from '../storage/project-identity.js';
|
|
3
5
|
import { readSpecTechnicalSection } from '../engine/spec-format/read-technical-section.js';
|
|
4
6
|
import { hasAffirmedMatch, stripMetaAnalysisText, stripNonContractText, } from '../engine/text-signal-boundaries.js';
|
|
5
7
|
// Bare keyword matches (counter, status, draft, ...) are common in unrelated
|
|
@@ -131,11 +133,14 @@ export function calculateOverallRisk(scenarios, concurrency) {
|
|
|
131
133
|
return 'low';
|
|
132
134
|
}
|
|
133
135
|
// --- Spec content reader ---
|
|
134
|
-
export async function readSpecContent(spec) {
|
|
136
|
+
export async function readSpecContent(spec, projectPath) {
|
|
135
137
|
let content = `${spec.title} ${spec.type} ${spec.scope} ${spec.target} ${spec.tags.join(' ')}`;
|
|
136
138
|
try {
|
|
137
139
|
if (spec.specPath) {
|
|
138
|
-
|
|
140
|
+
const resolvedPath = !isAbsolute(spec.specPath) && projectPath
|
|
141
|
+
? await resolveVerifiedSpecPath(spec.id, spec.specPath, projectPath)
|
|
142
|
+
: spec.specPath;
|
|
143
|
+
content += ' ' + (await readFile(resolvedPath, 'utf-8'));
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
catch {
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
// Analyzes a spec from adversarial perspectives: failure scenarios,
|
|
3
3
|
// concurrency issues, scale limits, security holes, and data consistency.
|
|
4
4
|
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { isAbsolute } from 'node:path';
|
|
5
6
|
import { createHash } from 'node:crypto';
|
|
6
7
|
import { specStore, knowledgeStore } from '../storage/index.js';
|
|
7
8
|
// SPEC-1011 Bug F: fallback resolver using disk fingerprints
|
|
8
9
|
import { resolveProjectFromPath } from '../storage/project-resolver.js';
|
|
9
10
|
import { updateSpec } from '../storage/spec-store.js';
|
|
11
|
+
import { resolveVerifiedSpecPath } from '../storage/project-identity.js';
|
|
10
12
|
import { resolveProjectId, missingProjectIdError } from './resolve-project-id.js';
|
|
11
13
|
import { elicitOrFallback, buildEnumSchema } from '../engine/elicitation/elicit-helper.js';
|
|
12
14
|
import { t, ti } from '../i18n/index.js';
|
|
@@ -83,13 +85,16 @@ function extractOutOfScopeSection(content) {
|
|
|
83
85
|
}
|
|
84
86
|
return found ? captured.join('\n') : null;
|
|
85
87
|
}
|
|
86
|
-
async function resolveDocumentOutOfScope(spec) {
|
|
88
|
+
async function resolveDocumentOutOfScope(spec, projectPath) {
|
|
87
89
|
if (!spec.specPath) {
|
|
88
90
|
return [];
|
|
89
91
|
}
|
|
90
92
|
let fileContent;
|
|
91
93
|
try {
|
|
92
|
-
|
|
94
|
+
const resolvedPath = !isAbsolute(spec.specPath) && projectPath
|
|
95
|
+
? await resolveVerifiedSpecPath(spec.id, spec.specPath, projectPath)
|
|
96
|
+
: spec.specPath;
|
|
97
|
+
fileContent = await readFile(resolvedPath, 'utf-8');
|
|
93
98
|
}
|
|
94
99
|
catch {
|
|
95
100
|
return [];
|
|
@@ -97,8 +102,8 @@ async function resolveDocumentOutOfScope(spec) {
|
|
|
97
102
|
const sectionContent = extractOutOfScopeSection(fileContent);
|
|
98
103
|
return sectionContent === null ? [] : extractListItems(sectionContent);
|
|
99
104
|
}
|
|
100
|
-
async function resolveOutOfScopeItems(spec) {
|
|
101
|
-
const documentItems = await resolveDocumentOutOfScope(spec);
|
|
105
|
+
async function resolveOutOfScopeItems(spec, projectPath) {
|
|
106
|
+
const documentItems = await resolveDocumentOutOfScope(spec, projectPath);
|
|
102
107
|
return documentItems.length > 0 ? documentItems : (spec.outOfScope ?? []);
|
|
103
108
|
}
|
|
104
109
|
/**
|
|
@@ -192,7 +197,7 @@ export async function handleChallengeSpec(args, server) {
|
|
|
192
197
|
// 2b. Load Constitution for compliance context
|
|
193
198
|
const constitution = await knowledgeStore.getConstitution(projectId);
|
|
194
199
|
// 3. Read spec content
|
|
195
|
-
const specContent = await readSpecContent(spec);
|
|
200
|
+
const specContent = await readSpecContent(spec, knowledge.projectPath);
|
|
196
201
|
const capabilities = detectChallengeCapabilities(spec, specContent);
|
|
197
202
|
// 4. Determine focus areas
|
|
198
203
|
const focusAreas = focus && focus.length > 0 ? focus : ALL_FOCUS_AREAS;
|
|
@@ -224,7 +229,7 @@ export async function handleChallengeSpec(args, server) {
|
|
|
224
229
|
}
|
|
225
230
|
failureScenarios.push(...collectCapabilityScenarios({ spec, specContent, knowledge, focusAreas, capabilities }));
|
|
226
231
|
// SPEC-612: Check for contradictions between outOfScope and acceptance criteria
|
|
227
|
-
const resolvedOutOfScope = await resolveOutOfScopeItems(spec);
|
|
232
|
+
const resolvedOutOfScope = await resolveOutOfScopeItems(spec, knowledge.projectPath);
|
|
228
233
|
if (resolvedOutOfScope.length > 0) {
|
|
229
234
|
const criteriaRange = findMarkdownSectionRange(specContent, 'Acceptance Criteria');
|
|
230
235
|
const criteriaTexts = criteriaRange === null
|