@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
|
@@ -6,6 +6,7 @@ import { open, readdir, readFile, stat } from 'node:fs/promises';
|
|
|
6
6
|
import { dirname, extname, join, relative, resolve } from 'node:path';
|
|
7
7
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
8
8
|
import { fileURLToPath } from 'node:url';
|
|
9
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
9
10
|
import { projectDataDir, readJson, writeJson } from '../../storage/base-store.js';
|
|
10
11
|
import { LockBusyError, withSpecLock } from '../safety/cross-process-lock.js';
|
|
11
12
|
const POLICY_PATH = join(dirname(fileURLToPath(import.meta.url)), '../../config/project-knowledge-graph.json');
|
|
@@ -23,6 +24,14 @@ const PROJECT_CODE_IGNORED_DIRS = new Set([
|
|
|
23
24
|
]);
|
|
24
25
|
const CONTENT_HASH_PATTERN = /^[a-f0-9]{64}$/;
|
|
25
26
|
const PROJECT_GRAPH_LOCK_WAIT_MS = 30_000;
|
|
27
|
+
const OPERATIONAL_SOURCE_KINDS = new Set([
|
|
28
|
+
'transition-log',
|
|
29
|
+
'release-events',
|
|
30
|
+
'decisions',
|
|
31
|
+
'handoff',
|
|
32
|
+
'validation',
|
|
33
|
+
]);
|
|
34
|
+
const JSONL_OPERATIONAL_SOURCE_KINDS = new Set(['transition-log', 'release-events']);
|
|
26
35
|
const buildTails = new Map();
|
|
27
36
|
const activeBuilds = new Map();
|
|
28
37
|
export async function loadProjectGraphPolicy() {
|
|
@@ -354,14 +363,150 @@ async function readBoundedFile(descriptor, path, maxFileBytes) {
|
|
|
354
363
|
mtimeMs: info.mtimeMs,
|
|
355
364
|
};
|
|
356
365
|
}
|
|
366
|
+
async function readBoundedFileOrOversized(descriptor, path, maxFileBytes) {
|
|
367
|
+
try {
|
|
368
|
+
return await readBoundedFile(descriptor, path, maxFileBytes);
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
if (error instanceof Error && error.message.startsWith('PROJECT_GRAPH_FILE_TOO_LARGE')) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async function readTailChunk(descriptor, size, maxFileBytes) {
|
|
378
|
+
const start = Math.max(0, size - maxFileBytes);
|
|
379
|
+
const length = size - start;
|
|
380
|
+
const buffer = Buffer.allocUnsafe(length);
|
|
381
|
+
let readTotal = 0;
|
|
382
|
+
while (readTotal < length) {
|
|
383
|
+
const { bytesRead } = await descriptor.read(buffer, readTotal, length - readTotal, start + readTotal);
|
|
384
|
+
if (bytesRead === 0) {
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
readTotal += bytesRead;
|
|
388
|
+
}
|
|
389
|
+
const chunk = buffer.subarray(0, readTotal);
|
|
390
|
+
if (start === 0) {
|
|
391
|
+
return { chunk, atLineBoundary: true };
|
|
392
|
+
}
|
|
393
|
+
const boundaryByte = Buffer.allocUnsafe(1);
|
|
394
|
+
const { bytesRead: boundaryBytesRead } = await descriptor.read(boundaryByte, 0, 1, start - 1);
|
|
395
|
+
return {
|
|
396
|
+
chunk,
|
|
397
|
+
atLineBoundary: boundaryBytesRead === 1 && boundaryByte[0] === 0x0a,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function dropFirstPartialLine(chunk, atLineBoundary) {
|
|
401
|
+
if (atLineBoundary) {
|
|
402
|
+
return chunk;
|
|
403
|
+
}
|
|
404
|
+
const newlineIndex = chunk.indexOf(0x0a);
|
|
405
|
+
return newlineIndex === -1 ? Buffer.alloc(0) : chunk.subarray(newlineIndex + 1);
|
|
406
|
+
}
|
|
407
|
+
async function readTailChunkStable(descriptor, maxFileBytes) {
|
|
408
|
+
const beforeStat = await descriptor.stat();
|
|
409
|
+
const { chunk, atLineBoundary } = await readTailChunk(descriptor, beforeStat.size, maxFileBytes);
|
|
410
|
+
const afterStat = await descriptor.stat();
|
|
411
|
+
return afterStat.size === beforeStat.size
|
|
412
|
+
? { chunk, atLineBoundary, mtimeMs: afterStat.mtimeMs }
|
|
413
|
+
: null;
|
|
414
|
+
}
|
|
415
|
+
async function readBoundedTail(descriptor, maxFileBytes) {
|
|
416
|
+
const stable = (await readTailChunkStable(descriptor, maxFileBytes)) ??
|
|
417
|
+
(await readTailChunkStable(descriptor, maxFileBytes));
|
|
418
|
+
if (stable === null) {
|
|
419
|
+
return null;
|
|
420
|
+
}
|
|
421
|
+
const trimmed = dropFirstPartialLine(stable.chunk, stable.atLineBoundary);
|
|
422
|
+
if (trimmed.length === 0) {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
return {
|
|
426
|
+
content: trimmed.toString('utf8'),
|
|
427
|
+
size: trimmed.length,
|
|
428
|
+
mtimeMs: stable.mtimeMs,
|
|
429
|
+
};
|
|
430
|
+
}
|
|
431
|
+
async function degradedOperationalSource(args) {
|
|
432
|
+
const base = {
|
|
433
|
+
path: args.path,
|
|
434
|
+
kind: args.kind,
|
|
435
|
+
bytes: args.bytes,
|
|
436
|
+
threshold: args.maxFileBytes,
|
|
437
|
+
};
|
|
438
|
+
if (!JSONL_OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
|
|
439
|
+
return { source: null, oversized: { ...base, action: 'skip' } };
|
|
440
|
+
}
|
|
441
|
+
const descriptor = await open(args.filePath, 'r');
|
|
442
|
+
let tail;
|
|
443
|
+
try {
|
|
444
|
+
tail = await readBoundedTail(descriptor, args.maxFileBytes);
|
|
445
|
+
}
|
|
446
|
+
finally {
|
|
447
|
+
await descriptor.close();
|
|
448
|
+
}
|
|
449
|
+
if (tail === null) {
|
|
450
|
+
return { source: null, oversized: { ...base, action: 'skip' } };
|
|
451
|
+
}
|
|
452
|
+
return {
|
|
453
|
+
source: {
|
|
454
|
+
id: args.id,
|
|
455
|
+
kind: args.kind,
|
|
456
|
+
path: args.path,
|
|
457
|
+
content: tail.content,
|
|
458
|
+
hash: hashText(`${String(args.bytes)}\n${tail.content}`),
|
|
459
|
+
size: tail.size,
|
|
460
|
+
mtimeMs: tail.mtimeMs,
|
|
461
|
+
contentLoaded: true,
|
|
462
|
+
},
|
|
463
|
+
oversized: { ...base, action: 'tail' },
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
async function readFreshSource(args) {
|
|
467
|
+
const descriptor = await open(args.filePath, 'r');
|
|
468
|
+
let bounded;
|
|
469
|
+
try {
|
|
470
|
+
bounded = await readBoundedFileOrOversized(descriptor, args.path, args.maxFileBytes);
|
|
471
|
+
if (bounded === null && OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
|
|
472
|
+
bounded = await readBoundedFileOrOversized(descriptor, args.path, args.maxFileBytes);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
finally {
|
|
476
|
+
await descriptor.close();
|
|
477
|
+
}
|
|
478
|
+
if (bounded === null) {
|
|
479
|
+
if (!OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
|
|
480
|
+
throw new Error(`PROJECT_GRAPH_FILE_TOO_LARGE: ${args.path} exceeds maxFileBytes (${String(args.maxFileBytes)})`);
|
|
481
|
+
}
|
|
482
|
+
const currentBytes = (await stat(args.filePath)).size;
|
|
483
|
+
return await degradedOperationalSource({ ...args, bytes: currentBytes });
|
|
484
|
+
}
|
|
485
|
+
return {
|
|
486
|
+
source: {
|
|
487
|
+
id: args.id,
|
|
488
|
+
kind: args.kind,
|
|
489
|
+
path: args.path,
|
|
490
|
+
content: bounded.content,
|
|
491
|
+
hash: hashText(bounded.content),
|
|
492
|
+
size: bounded.size,
|
|
493
|
+
mtimeMs: bounded.mtimeMs,
|
|
494
|
+
contentLoaded: true,
|
|
495
|
+
},
|
|
496
|
+
oversized: null,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
357
499
|
async function sourceFromFile(args) {
|
|
358
500
|
try {
|
|
359
501
|
const info = await stat(args.filePath);
|
|
360
502
|
if (!info.isFile()) {
|
|
361
|
-
return null;
|
|
503
|
+
return { source: null, oversized: null };
|
|
362
504
|
}
|
|
363
505
|
if (info.size > args.maxFileBytes) {
|
|
364
|
-
|
|
506
|
+
if (!OPERATIONAL_SOURCE_KINDS.has(args.kind)) {
|
|
507
|
+
throw new Error(`PROJECT_GRAPH_FILE_TOO_LARGE: ${args.path} exceeds maxFileBytes (${String(args.maxFileBytes)})`);
|
|
508
|
+
}
|
|
509
|
+
return await degradedOperationalSource({ ...args, bytes: info.size });
|
|
365
510
|
}
|
|
366
511
|
const previous = args.previous;
|
|
367
512
|
const expectedNativeVersion = nativeVersionForSource(args.kind, args.nativeCoreVersion);
|
|
@@ -375,53 +520,40 @@ async function sourceFromFile(args) {
|
|
|
375
520
|
args.nativeCoreVersion === undefined ||
|
|
376
521
|
previous.nativeCoreVersion === expectedNativeVersion)) {
|
|
377
522
|
return {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
523
|
+
source: {
|
|
524
|
+
id: args.id,
|
|
525
|
+
kind: args.kind,
|
|
526
|
+
path: args.path,
|
|
527
|
+
content: '',
|
|
528
|
+
hash: previous.contentHash,
|
|
529
|
+
size: info.size,
|
|
530
|
+
mtimeMs: info.mtimeMs,
|
|
531
|
+
contentLoaded: false,
|
|
532
|
+
},
|
|
533
|
+
oversized: null,
|
|
386
534
|
};
|
|
387
535
|
}
|
|
388
|
-
|
|
389
|
-
let bounded;
|
|
390
|
-
try {
|
|
391
|
-
bounded = await readBoundedFile(descriptor, args.path, args.maxFileBytes);
|
|
392
|
-
}
|
|
393
|
-
finally {
|
|
394
|
-
await descriptor.close();
|
|
395
|
-
}
|
|
396
|
-
return {
|
|
397
|
-
id: args.id,
|
|
398
|
-
kind: args.kind,
|
|
399
|
-
path: args.path,
|
|
400
|
-
content: bounded.content,
|
|
401
|
-
hash: hashText(bounded.content),
|
|
402
|
-
size: bounded.size,
|
|
403
|
-
mtimeMs: bounded.mtimeMs,
|
|
404
|
-
contentLoaded: true,
|
|
405
|
-
};
|
|
536
|
+
return await readFreshSource(args);
|
|
406
537
|
}
|
|
407
538
|
catch (error) {
|
|
408
539
|
if (error instanceof Error && error.message.startsWith('PROJECT_GRAPH_')) {
|
|
409
540
|
throw error;
|
|
410
541
|
}
|
|
411
|
-
return null;
|
|
542
|
+
return { source: null, oversized: null };
|
|
412
543
|
}
|
|
413
544
|
}
|
|
414
545
|
export async function hydrateProjectGraphSource(source, maxFileBytes) {
|
|
415
546
|
if (source.contentLoaded !== false || source.kind === 'project-code') {
|
|
416
547
|
return source;
|
|
417
548
|
}
|
|
418
|
-
|
|
549
|
+
const result = await sourceFromFile({
|
|
419
550
|
id: source.id,
|
|
420
551
|
kind: source.kind,
|
|
421
552
|
path: source.path,
|
|
422
553
|
filePath: source.path,
|
|
423
554
|
maxFileBytes,
|
|
424
555
|
});
|
|
556
|
+
return result.source;
|
|
425
557
|
}
|
|
426
558
|
async function collectGitSource(projectPath) {
|
|
427
559
|
try {
|
|
@@ -507,18 +639,26 @@ export async function collectProjectGraphSources(args) {
|
|
|
507
639
|
return { id: `project-code:${path}`, kind: 'project-code', path, filePath };
|
|
508
640
|
}),
|
|
509
641
|
].sort((a, b) => a.id.localeCompare(b.id));
|
|
510
|
-
const
|
|
642
|
+
const results = await Promise.all(raw.map((source) => sourceFromFile({
|
|
511
643
|
...source,
|
|
512
644
|
previous: args.previous?.[source.id],
|
|
513
645
|
nativeCoreVersion: args.nativeCoreVersion,
|
|
514
646
|
maxFileBytes,
|
|
515
647
|
})));
|
|
516
|
-
const available =
|
|
648
|
+
const available = results
|
|
649
|
+
.map((result) => result.source)
|
|
650
|
+
.filter((source) => source !== null);
|
|
651
|
+
const oversizedSources = results
|
|
652
|
+
.map((result) => result.oversized)
|
|
653
|
+
.filter((record) => record !== null);
|
|
517
654
|
const gitSource = await collectGitSource(projectRoot);
|
|
518
655
|
if (gitSource !== null) {
|
|
519
656
|
available.push(gitSource);
|
|
520
657
|
}
|
|
521
|
-
return
|
|
658
|
+
return {
|
|
659
|
+
sources: available.sort((left, right) => left.id.localeCompare(right.id)),
|
|
660
|
+
oversizedSources,
|
|
661
|
+
};
|
|
522
662
|
}
|
|
523
663
|
export async function getProjectGraphFreshness(args) {
|
|
524
664
|
const policy = args.policy ?? (await loadProjectGraphPolicy());
|
|
@@ -546,7 +686,7 @@ export async function getProjectGraphFreshness(args) {
|
|
|
546
686
|
}
|
|
547
687
|
const cacheResult = await readProjectGraphCache(args.projectId, policy);
|
|
548
688
|
const previous = cacheResult.cache?.records ?? {};
|
|
549
|
-
const sources = await collectProjectGraphSources({
|
|
689
|
+
const { sources } = await collectProjectGraphSources({
|
|
550
690
|
projectId: args.projectId,
|
|
551
691
|
projectPath: args.projectPath,
|
|
552
692
|
policy,
|
|
@@ -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 { safeJsonParse } from '../../../storage/base-store.js';
|
|
2
3
|
import { hashText } from '../cache.js';
|
|
3
4
|
import { redactGraphText } from '../redaction.js';
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
2
3
|
import { projectDataDir } from '../../storage/base-store.js';
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
3
5
|
import { RuntimeDatabase } from '../../storage/runtime-db.js';
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
4
7
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
5
8
|
const PROJECTION_WORKSPACE = 'project-graph';
|
|
6
9
|
const PROJECTION_KEY = 'freshness-v1';
|
|
@@ -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 { hashProjectPath } from '../../storage/base-store.js';
|
|
2
3
|
import { buildProjectKnowledgeGraph } from './builder.js';
|
|
3
4
|
import { getProjectGraphFreshness, loadProjectGraphPolicy, readProjectGraph } from './cache.js';
|
|
@@ -50,27 +51,27 @@ function summarize(nodes) {
|
|
|
50
51
|
toolHandlers: count('tool_handler'),
|
|
51
52
|
};
|
|
52
53
|
}
|
|
54
|
+
async function ensureFreshProjectGraph(args) {
|
|
55
|
+
const freshness = await getProjectGraphFreshness(args);
|
|
56
|
+
if (!freshness.exists ||
|
|
57
|
+
freshness.reason === 'source_changed' ||
|
|
58
|
+
freshness.reason === 'corrupt') {
|
|
59
|
+
await buildProjectKnowledgeGraph(args);
|
|
60
|
+
return getProjectGraphFreshness(args);
|
|
61
|
+
}
|
|
62
|
+
return freshness;
|
|
63
|
+
}
|
|
53
64
|
export async function queryProjectGraphSlice(input) {
|
|
54
65
|
const projectId = input.projectId ?? hashProjectPath(input.projectPath);
|
|
55
66
|
const policy = await loadProjectGraphPolicy();
|
|
56
67
|
if (!policy.enabled) {
|
|
57
68
|
return null;
|
|
58
69
|
}
|
|
59
|
-
|
|
70
|
+
const freshness = await ensureFreshProjectGraph({
|
|
60
71
|
projectId,
|
|
61
72
|
projectPath: input.projectPath,
|
|
62
73
|
policy,
|
|
63
74
|
});
|
|
64
|
-
if (!freshness.exists ||
|
|
65
|
-
freshness.reason === 'source_changed' ||
|
|
66
|
-
freshness.reason === 'corrupt') {
|
|
67
|
-
await buildProjectKnowledgeGraph({ projectId, projectPath: input.projectPath, policy });
|
|
68
|
-
freshness = await getProjectGraphFreshness({
|
|
69
|
-
projectId,
|
|
70
|
-
projectPath: input.projectPath,
|
|
71
|
-
policy,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
75
|
const graph = await readProjectGraph(projectId, policy);
|
|
75
76
|
if (graph === null) {
|
|
76
77
|
return null;
|
|
@@ -106,6 +107,8 @@ export async function queryProjectGraphSlice(input) {
|
|
|
106
107
|
freshness,
|
|
107
108
|
nodes,
|
|
108
109
|
edges,
|
|
110
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- pre-SPEC-1674 persisted artifacts predate this field
|
|
111
|
+
oversizedSources: graph.oversizedSources ?? [],
|
|
109
112
|
summary: summarize(nodes),
|
|
110
113
|
tokenSavings: {
|
|
111
114
|
compactNodes: nodes.length,
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { technologyValue } from './technology-registry.js';
|
|
2
|
+
import { fileExists } from '../core/shared/fs.js';
|
|
2
3
|
// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
|
|
3
4
|
// engine/project-health-checker.ts — SPEC-180 + SPEC-192 + SPEC-177: Project health check with convention scanning
|
|
4
5
|
import { execSync } from 'node:child_process';
|
|
5
|
-
import { readFile
|
|
6
|
+
import { readFile } from 'node:fs/promises';
|
|
6
7
|
import { join, relative } from 'node:path';
|
|
7
8
|
import { parseConventions, scanConventions } from './convention-scanner/index.js';
|
|
8
9
|
import { fastFindPatterns } from './core-bridge.js';
|
|
9
10
|
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
10
|
-
function fileExists(path) {
|
|
11
|
-
return access(path)
|
|
12
|
-
.then(() => true)
|
|
13
|
-
.catch(() => false);
|
|
14
|
-
}
|
|
15
11
|
function execSafe(cmd, cwd) {
|
|
16
12
|
try {
|
|
17
13
|
return execSync(cmd, { cwd, stdio: ['pipe', 'pipe', 'pipe'] }).toString();
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// (specBody, technicalBody, signatures, scenarios, file lists) and surfaces non-fatal
|
|
9
9
|
// parser issues in `warnings` instead of throwing.
|
|
10
10
|
import { readFile } from 'node:fs/promises';
|
|
11
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
11
12
|
import { specStore } from '../../../storage/index.js';
|
|
12
13
|
import { stripFrontmatter } from '../../frontmatter-parser.js';
|
|
13
14
|
import { extractSignatures } from './markdown-utils.js';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GATE_CATALOG } from './gate-catalog.js';
|
|
2
|
+
import { escapeRegex } from '../../core/shared/strings.js';
|
|
2
3
|
export function evaluateGates(specMarkdown) {
|
|
3
4
|
const autoGates = GATE_CATALOG.filter((g) => specMarkdown.includes(`[AUTO] ${g.title}`));
|
|
4
5
|
const passed = autoGates.filter((g) => {
|
|
@@ -19,7 +20,4 @@ export function evaluateGates(specMarkdown) {
|
|
|
19
20
|
score: autoGates.length === 0 ? 100 : Math.round((passed.length / autoGates.length) * 100),
|
|
20
21
|
};
|
|
21
22
|
}
|
|
22
|
-
function escapeRegex(str) {
|
|
23
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
24
|
-
}
|
|
25
23
|
//# sourceMappingURL=gate-evaluator.js.map
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
// Planu — SPEC-051: React 19 + Next.js 16 stack detection
|
|
2
|
-
import { readFile
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
|
+
import { fileExistsIn } from '../core/shared/fs.js';
|
|
4
5
|
// ---------------------------------------------------------------------------
|
|
5
6
|
// Helpers
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
|
-
async function fileExists(basePath, relativePath) {
|
|
8
|
-
try {
|
|
9
|
-
await access(join(basePath, relativePath));
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
catch {
|
|
13
|
-
return false;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
8
|
async function readJsonFile(filePath) {
|
|
17
9
|
try {
|
|
18
10
|
const content = await readFile(filePath, 'utf-8');
|
|
@@ -98,11 +90,11 @@ async function detectNextjsVersion(projectPath) {
|
|
|
98
90
|
// Router mode detection
|
|
99
91
|
// ---------------------------------------------------------------------------
|
|
100
92
|
async function detectRouterMode(projectPath) {
|
|
101
|
-
const hasApp = await
|
|
102
|
-
const hasPages = await
|
|
93
|
+
const hasApp = await fileExistsIn(projectPath, 'app');
|
|
94
|
+
const hasPages = await fileExistsIn(projectPath, 'pages');
|
|
103
95
|
// Also check src/ subdirectory (common Next.js project layout)
|
|
104
|
-
const hasAppSrc = await
|
|
105
|
-
const hasPagesSrc = await
|
|
96
|
+
const hasAppSrc = await fileExistsIn(projectPath, 'src/app');
|
|
97
|
+
const hasPagesSrc = await fileExistsIn(projectPath, 'src/pages');
|
|
106
98
|
const appRouter = hasApp || hasAppSrc;
|
|
107
99
|
const pagesRouter = hasPages || hasPagesSrc;
|
|
108
100
|
if (appRouter && pagesRouter) {
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { atomicWriteFile } from '../safety/atomic-write-file.js';
|
|
3
3
|
import { SECTIONS_WITHOUT_LITERAL_BODY_TEXT, } from '../../types/index.js';
|
|
4
|
-
|
|
5
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
6
|
-
}
|
|
4
|
+
import { escapeRegex } from '../../core/shared/strings.js';
|
|
7
5
|
function findSectionBounds(content, section) {
|
|
8
6
|
const headingRe = new RegExp(`^(#{1,6})\\s+${escapeRegex(section)}\\s*$`, 'mi');
|
|
9
7
|
const match = headingRe.exec(content);
|
|
@@ -68,6 +68,7 @@ export { formatReport };
|
|
|
68
68
|
* Custom entries override base entries with the same framework ID.
|
|
69
69
|
*/
|
|
70
70
|
export async function saveCustomEntry(entry) {
|
|
71
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
71
72
|
const { readJson, writeJson, globalDataDir } = await import('../../storage/base-store.js');
|
|
72
73
|
const { join } = await import('node:path');
|
|
73
74
|
const filePath = join(globalDataDir(), 'registry-custom.json');
|
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
import { readFile } from 'node:fs/promises';
|
|
6
6
|
import { join, dirname } from 'node:path';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
8
9
|
import { readJson } from '../../storage/base-store.js';
|
|
10
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
9
11
|
import { resolvedStorageArtifactPath } from '../../storage/storage-catalog.js';
|
|
10
12
|
import { loadTechnologyRegistry } from '../technology-registry.js';
|
|
11
13
|
const REGISTRY_DIR = join(dirname(fileURLToPath(import.meta.url)), '../../config/framework-registry');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// engine/release/postmortem-generator.ts — SPEC-737: Post-mortem skeleton writer
|
|
2
2
|
import { readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
3
3
|
import { 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 { hashProjectPath, projectDataDir } from '../../storage/base-store.js';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Template path
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type RollbackStepName = 'npm-dist-tag-rm' | 'git-tag-delete-local' | 'git-tag-delete-remote' | 'smoke-test-verify';
|
|
2
|
-
export interface
|
|
2
|
+
export interface ReleaseRollbackStep {
|
|
3
3
|
name: RollbackStepName;
|
|
4
4
|
status: 'success' | 'failed' | 'skipped';
|
|
5
5
|
stdout?: string;
|
|
@@ -14,7 +14,7 @@ export interface RollbackRunnerInput {
|
|
|
14
14
|
}
|
|
15
15
|
export interface RollbackRunnerResult {
|
|
16
16
|
ok: boolean;
|
|
17
|
-
steps:
|
|
17
|
+
steps: ReleaseRollbackStep[];
|
|
18
18
|
failedStep?: RollbackStepName;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
@@ -39,7 +39,9 @@ export async function buildMergedBranchSet(projectPath, targetBranch = 'main') {
|
|
|
39
39
|
*/
|
|
40
40
|
export async function detectStuckSpecs(projectPath, targetBranch = 'main') {
|
|
41
41
|
// Lazy-import storage to keep engine layer free of direct storage coupling
|
|
42
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
42
43
|
const { specStore } = await import('../../storage/index.js');
|
|
44
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
43
45
|
const { hashProjectPath } = await import('../../storage/base-store.js');
|
|
44
46
|
const projectId = hashProjectPath(projectPath);
|
|
45
47
|
const allSpecs = await specStore.listSpecs(projectId);
|
|
@@ -73,6 +75,7 @@ export async function detectStuckSpecs(projectPath, targetBranch = 'main') {
|
|
|
73
75
|
*/
|
|
74
76
|
export async function autoCloseStuckSpec(spec, projectPath) {
|
|
75
77
|
try {
|
|
78
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
76
79
|
const { handleUpdateStatus } = await import('../../tools/update-status.js');
|
|
77
80
|
await handleUpdateStatus({
|
|
78
81
|
projectPath,
|
|
@@ -89,7 +92,9 @@ export async function autoCloseStuckSpec(spec, projectPath) {
|
|
|
89
92
|
}
|
|
90
93
|
async function logAutoCloseFailure(specId, projectPath, err) {
|
|
91
94
|
try {
|
|
95
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
92
96
|
const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
|
|
97
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
93
98
|
const { hashProjectPath } = await import('../../storage/base-store.js');
|
|
94
99
|
const projectId = hashProjectPath(projectPath);
|
|
95
100
|
await appendAutopilotLogEntry(projectId, {
|
|
@@ -117,7 +122,9 @@ async function logAutoCloseFailure(specId, projectPath, err) {
|
|
|
117
122
|
*/
|
|
118
123
|
export async function logForceReleaseAudit(specIds, projectPath) {
|
|
119
124
|
try {
|
|
125
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
120
126
|
const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
|
|
127
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
121
128
|
const { hashProjectPath } = await import('../../storage/base-store.js');
|
|
122
129
|
const projectId = hashProjectPath(projectPath);
|
|
123
130
|
await appendAutopilotLogEntry(projectId, {
|
|
@@ -6,7 +6,9 @@ import { join } from 'node:path';
|
|
|
6
6
|
import { promisify } from 'node:util';
|
|
7
7
|
import { atomicWriteFile } from '../safety/atomic-write-file.js';
|
|
8
8
|
import { parseSpecIdsFromCommitMessage } from './parse-spec-refs.js';
|
|
9
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
9
10
|
import { hashProjectPath } from '../../storage/base-store.js';
|
|
11
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
10
12
|
import { specStore } from '../../storage/index.js';
|
|
11
13
|
const execFile = promisify(execFileCb);
|
|
12
14
|
const TERMINAL_STATUSES = new Set(['done', 'discarded']);
|
|
@@ -139,6 +141,7 @@ async function resolveSpecDir(specsRoot, specId) {
|
|
|
139
141
|
function logToAutopilot(projectPath, specId, version, success) {
|
|
140
142
|
void (async () => {
|
|
141
143
|
try {
|
|
144
|
+
// eslint-disable-next-line no-restricted-syntax -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
142
145
|
const { appendAutopilotLogEntry } = await import('../../storage/autopilot-log-store.js');
|
|
143
146
|
const projectId = hashProjectPath(projectPath);
|
|
144
147
|
await appendAutopilotLogEntry(projectId, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RulesReconciliation } from '../types/index.js';
|
|
2
|
+
import { readFileSafeSync as readFileSafe } from '../core/shared/fs.js';
|
|
2
3
|
export type { RulesReconciliation };
|
|
3
|
-
declare function readFileSafe(path: string): string;
|
|
4
4
|
/**
|
|
5
5
|
* Compare CLAUDE.md conventions against existing .claude/rules/ files.
|
|
6
6
|
* Auto-patches missing convention categories by generating new rules files.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// engine/rules-reconciler.ts — Compare CLAUDE.md conventions against .claude/rules/ and auto-patch drift (SPEC-189)
|
|
2
|
-
import {
|
|
2
|
+
import { readdirSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
3
3
|
import { join, basename } from 'node:path';
|
|
4
4
|
import { parseConventions } from './convention-scanner/convention-parser.js';
|
|
5
5
|
import { assertEnglishOnlyArtifactText } from './spec-language/english-only.js';
|
|
6
|
+
import { readFileSafeSync as readFileSafe } from '../core/shared/fs.js';
|
|
6
7
|
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
7
8
|
function listRulesFiles(projectPath) {
|
|
8
9
|
const rulesDir = join(projectPath, '.claude', 'rules');
|
|
@@ -15,14 +16,6 @@ function listRulesFiles(projectPath) {
|
|
|
15
16
|
return [];
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
|
-
function readFileSafe(path) {
|
|
19
|
-
try {
|
|
20
|
-
return readFileSync(path, 'utf-8');
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return '';
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
19
|
/** Unique convention categories detected in CLAUDE.md (source: 'claude-md' only). */
|
|
27
20
|
function categoriesInClaudeMd(rules) {
|
|
28
21
|
const categories = new Set();
|
|
@@ -3,6 +3,7 @@ import { rename, copyFile, unlink, readFile, writeFile, mkdir } from 'node:fs/pr
|
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
4
|
import { dirname } from 'node:path';
|
|
5
5
|
import { randomBytes } from 'node:crypto';
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
6
7
|
import { withFileLock } from '../../storage/file-mutex.js';
|
|
7
8
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
8
9
|
const DEFAULT_BACKUP_COUNT = 3;
|
|
@@ -55,7 +55,9 @@ import { randomUUID } from 'node:crypto';
|
|
|
55
55
|
import { hostname as osHostname } from 'node:os';
|
|
56
56
|
import { isAbsolute, join } from 'node:path';
|
|
57
57
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
58
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
58
59
|
import { hashProjectPath } from '../../storage/base-store.js';
|
|
60
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
59
61
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
60
62
|
import { computeStaleReason, isPidDead, STALE_THRESHOLD_MS } from './lock-staleness.js';
|
|
61
63
|
import { LockLeaseStore, } from './lock-lease-store.js';
|
|
@@ -53,6 +53,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
53
53
|
import { createHash, randomUUID } from 'node:crypto';
|
|
54
54
|
import { hostname } from 'node:os';
|
|
55
55
|
import { dirname, join } from 'node:path';
|
|
56
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
56
57
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
57
58
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
58
59
|
import { LockLeaseStore } from './lock-lease-store.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { chmodSync, existsSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import { DatabaseSync } from 'node:sqlite';
|
|
4
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
4
5
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
5
6
|
const SCHEMA_VERSION = 1;
|
|
6
7
|
const DEFAULT_BUSY_TIMEOUT_MS = 5_000;
|
|
@@ -53,7 +53,9 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
53
53
|
import { readFile, readdir, rm } from 'node:fs/promises';
|
|
54
54
|
import { hostname as osHostname } from 'node:os';
|
|
55
55
|
import { isAbsolute, join } from 'node:path';
|
|
56
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
56
57
|
import { hashProjectPath } from '../../storage/base-store.js';
|
|
58
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
57
59
|
import { resolveStorageLayout } from '../../storage/storage-layout.js';
|
|
58
60
|
import { reportClassifiedDegradation } from '../../errors/classified-degradation.js';
|
|
59
61
|
import { computeStaleReason, isPidDead } from './lock-staleness.js';
|