@planu/cli 0.43.1 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/colors.d.ts +14 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +26 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/commands/audit.d.ts +3 -0
- package/dist/cli/commands/audit.d.ts.map +1 -0
- package/dist/cli/commands/audit.js +38 -0
- package/dist/cli/commands/audit.js.map +1 -0
- package/dist/cli/commands/create.d.ts +3 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +50 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/dashboard.d.ts +3 -0
- package/dist/cli/commands/dashboard.d.ts.map +1 -0
- package/dist/cli/commands/dashboard.js +29 -0
- package/dist/cli/commands/dashboard.js.map +1 -0
- package/dist/cli/commands/estimate.d.ts +3 -0
- package/dist/cli/commands/estimate.d.ts.map +1 -0
- package/dist/cli/commands/estimate.js +36 -0
- package/dist/cli/commands/estimate.js.map +1 -0
- package/dist/cli/commands/handoff.d.ts +3 -0
- package/dist/cli/commands/handoff.d.ts.map +1 -0
- package/dist/cli/commands/handoff.js +49 -0
- package/dist/cli/commands/handoff.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +43 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/list.d.ts +3 -0
- package/dist/cli/commands/list.d.ts.map +1 -0
- package/dist/cli/commands/list.js +36 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +3 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +34 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +49 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +36 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/commands/watch.d.ts +3 -0
- package/dist/cli/commands/watch.d.ts.map +1 -0
- package/dist/cli/commands/watch.js +156 -0
- package/dist/cli/commands/watch.js.map +1 -0
- package/dist/cli/formatter.d.ts +18 -0
- package/dist/cli/formatter.d.ts.map +1 -0
- package/dist/cli/formatter.js +78 -0
- package/dist/cli/formatter.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/interactive.d.ts +13 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +42 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/project-detector.d.ts +6 -0
- package/dist/cli/project-detector.d.ts.map +1 -0
- package/dist/cli/project-detector.js +12 -0
- package/dist/cli/project-detector.js.map +1 -0
- package/dist/cli/router.d.ts +5 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +104 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/config/hook-defaults.json +19 -0
- package/dist/config/license-plans.json +23 -2
- package/dist/config/registry-categories.json +20 -0
- package/dist/config/registry-stacks.json +16 -0
- package/dist/config/tool-groups.json +12 -1
- package/dist/engine/analyzer/analyze-project.d.ts +15 -0
- package/dist/engine/analyzer/analyze-project.d.ts.map +1 -0
- package/dist/engine/analyzer/analyze-project.js +101 -0
- package/dist/engine/analyzer/analyze-project.js.map +1 -0
- package/dist/engine/analyzer/completeness-checker.d.ts +6 -0
- package/dist/engine/analyzer/completeness-checker.d.ts.map +1 -0
- package/dist/engine/analyzer/completeness-checker.js +79 -0
- package/dist/engine/analyzer/completeness-checker.js.map +1 -0
- package/dist/engine/analyzer/db-engine.d.ts +9 -0
- package/dist/engine/analyzer/db-engine.d.ts.map +1 -0
- package/dist/engine/analyzer/db-engine.js +137 -0
- package/dist/engine/analyzer/db-engine.js.map +1 -0
- package/dist/engine/analyzer/detectors.d.ts +7 -0
- package/dist/engine/analyzer/detectors.d.ts.map +1 -0
- package/dist/engine/analyzer/detectors.js +234 -0
- package/dist/engine/analyzer/detectors.js.map +1 -0
- package/dist/engine/analyzer/env-setup.d.ts +6 -0
- package/dist/engine/analyzer/env-setup.d.ts.map +1 -0
- package/dist/engine/analyzer/env-setup.js +174 -0
- package/dist/engine/analyzer/env-setup.js.map +1 -0
- package/dist/engine/analyzer/index.d.ts +6 -0
- package/dist/engine/analyzer/index.d.ts.map +1 -0
- package/dist/engine/analyzer/index.js +8 -0
- package/dist/engine/analyzer/index.js.map +1 -0
- package/dist/engine/analyzer-db.d.ts +1 -8
- package/dist/engine/analyzer-db.d.ts.map +1 -1
- package/dist/engine/analyzer-db.js +3 -136
- package/dist/engine/analyzer-db.js.map +1 -1
- package/dist/engine/analyzer-detectors.d.ts +1 -6
- package/dist/engine/analyzer-detectors.d.ts.map +1 -1
- package/dist/engine/analyzer-detectors.js +3 -231
- package/dist/engine/analyzer-detectors.js.map +1 -1
- package/dist/engine/analyzer-env.d.ts +1 -5
- package/dist/engine/analyzer-env.d.ts.map +1 -1
- package/dist/engine/analyzer-env.js +3 -173
- package/dist/engine/analyzer-env.js.map +1 -1
- package/dist/engine/analyzer.d.ts +2 -18
- package/dist/engine/analyzer.d.ts.map +1 -1
- package/dist/engine/analyzer.js +4 -172
- package/dist/engine/analyzer.js.map +1 -1
- package/dist/engine/dashboard/data-loader.d.ts +16 -1
- package/dist/engine/dashboard/data-loader.d.ts.map +1 -1
- package/dist/engine/dashboard/data-loader.js +140 -2
- package/dist/engine/dashboard/data-loader.js.map +1 -1
- package/dist/engine/dashboard/index.d.ts +2 -0
- package/dist/engine/dashboard/index.d.ts.map +1 -1
- package/dist/engine/dashboard/index.js +2 -0
- package/dist/engine/dashboard/index.js.map +1 -1
- package/dist/engine/dashboard/kanban-logic.d.ts +31 -0
- package/dist/engine/dashboard/kanban-logic.d.ts.map +1 -0
- package/dist/engine/dashboard/kanban-logic.js +122 -0
- package/dist/engine/dashboard/kanban-logic.js.map +1 -0
- package/dist/engine/dashboard/routes.d.ts +2 -0
- package/dist/engine/dashboard/routes.d.ts.map +1 -1
- package/dist/engine/dashboard/routes.js +112 -23
- package/dist/engine/dashboard/routes.js.map +1 -1
- package/dist/engine/dashboard/server.d.ts +5 -0
- package/dist/engine/dashboard/server.d.ts.map +1 -1
- package/dist/engine/dashboard/server.js +48 -0
- package/dist/engine/dashboard/server.js.map +1 -1
- package/dist/engine/dashboard/spec-updater.d.ts +8 -0
- package/dist/engine/dashboard/spec-updater.d.ts.map +1 -0
- package/dist/engine/dashboard/spec-updater.js +37 -0
- package/dist/engine/dashboard/spec-updater.js.map +1 -0
- package/dist/engine/dashboard/templates-kanban.d.ts +6 -0
- package/dist/engine/dashboard/templates-kanban.d.ts.map +1 -0
- package/dist/engine/dashboard/templates-kanban.js +100 -0
- package/dist/engine/dashboard/templates-kanban.js.map +1 -0
- package/dist/engine/dashboard/templates-layout.d.ts +3 -3
- package/dist/engine/dashboard/templates-layout.d.ts.map +1 -1
- package/dist/engine/dashboard/templates-layout.js +167 -44
- package/dist/engine/dashboard/templates-layout.js.map +1 -1
- package/dist/engine/dashboard/templates-project.d.ts +1 -1
- package/dist/engine/dashboard/templates-project.d.ts.map +1 -1
- package/dist/engine/dashboard/templates-project.js +109 -3
- package/dist/engine/dashboard/templates-project.js.map +1 -1
- package/dist/engine/dashboard/templates.d.ts +1 -0
- package/dist/engine/dashboard/templates.d.ts.map +1 -1
- package/dist/engine/dashboard/templates.js +1 -0
- package/dist/engine/dashboard/templates.js.map +1 -1
- package/dist/engine/hooks/config-loader.d.ts +36 -0
- package/dist/engine/hooks/config-loader.d.ts.map +1 -0
- package/dist/engine/hooks/config-loader.js +142 -0
- package/dist/engine/hooks/config-loader.js.map +1 -0
- package/dist/engine/hooks/debouncer.d.ts +30 -0
- package/dist/engine/hooks/debouncer.d.ts.map +1 -0
- package/dist/engine/hooks/debouncer.js +124 -0
- package/dist/engine/hooks/debouncer.js.map +1 -0
- package/dist/engine/hooks/event-bus.d.ts +40 -0
- package/dist/engine/hooks/event-bus.d.ts.map +1 -0
- package/dist/engine/hooks/event-bus.js +83 -0
- package/dist/engine/hooks/event-bus.js.map +1 -0
- package/dist/engine/hooks/file-watcher.d.ts +48 -0
- package/dist/engine/hooks/file-watcher.d.ts.map +1 -0
- package/dist/engine/hooks/file-watcher.js +193 -0
- package/dist/engine/hooks/file-watcher.js.map +1 -0
- package/dist/engine/hooks/handlers/on-commit.d.ts +26 -0
- package/dist/engine/hooks/handlers/on-commit.d.ts.map +1 -0
- package/dist/engine/hooks/handlers/on-commit.js +198 -0
- package/dist/engine/hooks/handlers/on-commit.js.map +1 -0
- package/dist/engine/hooks/handlers/on-create.d.ts +8 -0
- package/dist/engine/hooks/handlers/on-create.d.ts.map +1 -0
- package/dist/engine/hooks/handlers/on-create.js +30 -0
- package/dist/engine/hooks/handlers/on-create.js.map +1 -0
- package/dist/engine/hooks/handlers/on-delete.d.ts +9 -0
- package/dist/engine/hooks/handlers/on-delete.d.ts.map +1 -0
- package/dist/engine/hooks/handlers/on-delete.js +33 -0
- package/dist/engine/hooks/handlers/on-delete.js.map +1 -0
- package/dist/engine/hooks/handlers/on-save.d.ts +29 -0
- package/dist/engine/hooks/handlers/on-save.d.ts.map +1 -0
- package/dist/engine/hooks/handlers/on-save.js +118 -0
- package/dist/engine/hooks/handlers/on-save.js.map +1 -0
- package/dist/engine/hooks/handlers/on-test-pass.d.ts +33 -0
- package/dist/engine/hooks/handlers/on-test-pass.d.ts.map +1 -0
- package/dist/engine/hooks/handlers/on-test-pass.js +103 -0
- package/dist/engine/hooks/handlers/on-test-pass.js.map +1 -0
- package/dist/engine/hooks/hook-engine.d.ts +50 -0
- package/dist/engine/hooks/hook-engine.d.ts.map +1 -0
- package/dist/engine/hooks/hook-engine.js +159 -0
- package/dist/engine/hooks/hook-engine.js.map +1 -0
- package/dist/engine/hooks/index.d.ts +10 -0
- package/dist/engine/hooks/index.d.ts.map +1 -1
- package/dist/engine/hooks/index.js +12 -0
- package/dist/engine/hooks/index.js.map +1 -1
- package/dist/engine/living-spec/annotation-parser.d.ts +18 -0
- package/dist/engine/living-spec/annotation-parser.d.ts.map +1 -0
- package/dist/engine/living-spec/annotation-parser.js +105 -0
- package/dist/engine/living-spec/annotation-parser.js.map +1 -0
- package/dist/engine/living-spec/auto-reconciler.d.ts +28 -0
- package/dist/engine/living-spec/auto-reconciler.d.ts.map +1 -0
- package/dist/engine/living-spec/auto-reconciler.js +103 -0
- package/dist/engine/living-spec/auto-reconciler.js.map +1 -0
- package/dist/engine/living-spec/bidirectional-sync.d.ts +26 -0
- package/dist/engine/living-spec/bidirectional-sync.d.ts.map +1 -0
- package/dist/engine/living-spec/bidirectional-sync.js +160 -0
- package/dist/engine/living-spec/bidirectional-sync.js.map +1 -0
- package/dist/engine/living-spec/dashboard-collector.d.ts +22 -0
- package/dist/engine/living-spec/dashboard-collector.d.ts.map +1 -0
- package/dist/engine/living-spec/dashboard-collector.js +97 -0
- package/dist/engine/living-spec/dashboard-collector.js.map +1 -0
- package/dist/engine/living-spec/drift-watcher.d.ts +15 -0
- package/dist/engine/living-spec/drift-watcher.d.ts.map +1 -0
- package/dist/engine/living-spec/drift-watcher.js +126 -0
- package/dist/engine/living-spec/drift-watcher.js.map +1 -0
- package/dist/engine/living-spec/hash-tracker.d.ts +24 -0
- package/dist/engine/living-spec/hash-tracker.d.ts.map +1 -0
- package/dist/engine/living-spec/hash-tracker.js +123 -0
- package/dist/engine/living-spec/hash-tracker.js.map +1 -0
- package/dist/engine/living-spec/index.d.ts +9 -0
- package/dist/engine/living-spec/index.d.ts.map +1 -0
- package/dist/engine/living-spec/index.js +10 -0
- package/dist/engine/living-spec/index.js.map +1 -0
- package/dist/engine/living-spec/signature-tracker.d.ts +18 -0
- package/dist/engine/living-spec/signature-tracker.d.ts.map +1 -0
- package/dist/engine/living-spec/signature-tracker.js +136 -0
- package/dist/engine/living-spec/signature-tracker.js.map +1 -0
- package/dist/engine/living-spec/test-coverage-correlator.d.ts +22 -0
- package/dist/engine/living-spec/test-coverage-correlator.d.ts.map +1 -0
- package/dist/engine/living-spec/test-coverage-correlator.js +130 -0
- package/dist/engine/living-spec/test-coverage-correlator.js.map +1 -0
- package/dist/engine/plugins/extensions/worker-extension.d.ts.map +1 -1
- package/dist/engine/plugins/extensions/worker-extension.js +3 -1
- package/dist/engine/plugins/extensions/worker-extension.js.map +1 -1
- package/dist/engine/safety/file-mutex.d.ts.map +1 -1
- package/dist/engine/safety/file-mutex.js +3 -0
- package/dist/engine/safety/file-mutex.js.map +1 -1
- package/dist/engine/spec-registry/adapter.d.ts +9 -0
- package/dist/engine/spec-registry/adapter.d.ts.map +1 -0
- package/dist/engine/spec-registry/adapter.js +303 -0
- package/dist/engine/spec-registry/adapter.js.map +1 -0
- package/dist/engine/spec-registry/client.d.ts +8 -0
- package/dist/engine/spec-registry/client.d.ts.map +1 -0
- package/dist/engine/spec-registry/client.js +194 -0
- package/dist/engine/spec-registry/client.js.map +1 -0
- package/dist/engine/spec-registry/index.d.ts +7 -0
- package/dist/engine/spec-registry/index.d.ts.map +1 -0
- package/dist/engine/spec-registry/index.js +7 -0
- package/dist/engine/spec-registry/index.js.map +1 -0
- package/dist/engine/spec-registry/packager.d.ts +24 -0
- package/dist/engine/spec-registry/packager.d.ts.map +1 -0
- package/dist/engine/spec-registry/packager.js +122 -0
- package/dist/engine/spec-registry/packager.js.map +1 -0
- package/dist/engine/spec-registry/scorer.d.ts +10 -0
- package/dist/engine/spec-registry/scorer.d.ts.map +1 -0
- package/dist/engine/spec-registry/scorer.js +151 -0
- package/dist/engine/spec-registry/scorer.js.map +1 -0
- package/dist/engine/spec-registry/validator.d.ts +11 -0
- package/dist/engine/spec-registry/validator.d.ts.map +1 -0
- package/dist/engine/spec-registry/validator.js +144 -0
- package/dist/engine/spec-registry/validator.js.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/hash-snapshot-store.d.ts +18 -0
- package/dist/storage/hash-snapshot-store.d.ts.map +1 -0
- package/dist/storage/hash-snapshot-store.js +43 -0
- package/dist/storage/hash-snapshot-store.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +3 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/living-dashboard-store.d.ts +10 -0
- package/dist/storage/living-dashboard-store.d.ts.map +1 -0
- package/dist/storage/living-dashboard-store.js +31 -0
- package/dist/storage/living-dashboard-store.js.map +1 -0
- package/dist/storage/sync-log-store.d.ts +26 -0
- package/dist/storage/sync-log-store.d.ts.map +1 -0
- package/dist/storage/sync-log-store.js +60 -0
- package/dist/storage/sync-log-store.js.map +1 -0
- package/dist/tools/auto-reconcile.d.ts +3 -0
- package/dist/tools/auto-reconcile.d.ts.map +1 -0
- package/dist/tools/auto-reconcile.js +81 -0
- package/dist/tools/auto-reconcile.js.map +1 -0
- package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.d.ts.map +1 -1
- package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js +6 -0
- package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js.map +1 -1
- package/dist/tools/create-spec/spec-builder.js +2 -0
- package/dist/tools/create-spec/spec-builder.js.map +1 -1
- package/dist/tools/dashboard.d.ts.map +1 -1
- package/dist/tools/dashboard.js +20 -13
- package/dist/tools/dashboard.js.map +1 -1
- package/dist/tools/generate-annotations.d.ts +3 -0
- package/dist/tools/generate-annotations.d.ts.map +1 -0
- package/dist/tools/generate-annotations.js +70 -0
- package/dist/tools/generate-annotations.js.map +1 -0
- package/dist/tools/generate-execution-plan.d.ts.map +1 -1
- package/dist/tools/generate-execution-plan.js +1 -0
- package/dist/tools/generate-execution-plan.js.map +1 -1
- package/dist/tools/github-pr-handler.d.ts.map +1 -1
- package/dist/tools/github-pr-handler.js +1 -0
- package/dist/tools/github-pr-handler.js.map +1 -1
- package/dist/tools/github-review-handler.d.ts.map +1 -1
- package/dist/tools/github-review-handler.js +1 -0
- package/dist/tools/github-review-handler.js.map +1 -1
- package/dist/tools/ide-config-handler.d.ts.map +1 -1
- package/dist/tools/ide-config-handler.js +3 -0
- package/dist/tools/ide-config-handler.js.map +1 -1
- package/dist/tools/init-project/handler.d.ts.map +1 -1
- package/dist/tools/init-project/handler.js +0 -3
- package/dist/tools/init-project/handler.js.map +1 -1
- package/dist/tools/living-spec-coverage.d.ts +3 -0
- package/dist/tools/living-spec-coverage.d.ts.map +1 -0
- package/dist/tools/living-spec-coverage.js +100 -0
- package/dist/tools/living-spec-coverage.js.map +1 -0
- package/dist/tools/living-spec-watch.d.ts +4 -0
- package/dist/tools/living-spec-watch.d.ts.map +1 -0
- package/dist/tools/living-spec-watch.js +94 -0
- package/dist/tools/living-spec-watch.js.map +1 -0
- package/dist/tools/manage-plugins-handler.d.ts.map +1 -1
- package/dist/tools/manage-plugins-handler.js +2 -1
- package/dist/tools/manage-plugins-handler.js.map +1 -1
- package/dist/tools/orchestrate-distribution.d.ts.map +1 -1
- package/dist/tools/orchestrate-distribution.js +1 -0
- package/dist/tools/orchestrate-distribution.js.map +1 -1
- package/dist/tools/orchestrate-runtime.js +2 -0
- package/dist/tools/orchestrate-runtime.js.map +1 -1
- package/dist/tools/plan-team-distribution.d.ts.map +1 -1
- package/dist/tools/plan-team-distribution.js +2 -0
- package/dist/tools/plan-team-distribution.js.map +1 -1
- package/dist/tools/register-dashboard-tools.d.ts.map +1 -1
- package/dist/tools/register-dashboard-tools.js +5 -1
- package/dist/tools/register-dashboard-tools.js.map +1 -1
- package/dist/tools/register-hooks-tools.d.ts.map +1 -1
- package/dist/tools/register-hooks-tools.js +82 -1
- package/dist/tools/register-hooks-tools.js.map +1 -1
- package/dist/tools/register-living-spec-advanced-tools.d.ts +6 -0
- package/dist/tools/register-living-spec-advanced-tools.d.ts.map +1 -0
- package/dist/tools/register-living-spec-advanced-tools.js +113 -0
- package/dist/tools/register-living-spec-advanced-tools.js.map +1 -0
- package/dist/tools/register-living-spec-tools.d.ts +6 -0
- package/dist/tools/register-living-spec-tools.d.ts.map +1 -0
- package/dist/tools/register-living-spec-tools.js +67 -0
- package/dist/tools/register-living-spec-tools.js.map +1 -0
- package/dist/tools/register-spec-registry-tools.d.ts +3 -0
- package/dist/tools/register-spec-registry-tools.d.ts.map +1 -0
- package/dist/tools/register-spec-registry-tools.js +91 -0
- package/dist/tools/register-spec-registry-tools.js.map +1 -0
- package/dist/tools/registry/auth.d.ts +17 -0
- package/dist/tools/registry/auth.d.ts.map +1 -0
- package/dist/tools/registry/auth.js +132 -0
- package/dist/tools/registry/auth.js.map +1 -0
- package/dist/tools/registry/index.d.ts +5 -0
- package/dist/tools/registry/index.d.ts.map +1 -0
- package/dist/tools/registry/index.js +6 -0
- package/dist/tools/registry/index.js.map +1 -0
- package/dist/tools/registry/install.d.ts +7 -0
- package/dist/tools/registry/install.d.ts.map +1 -0
- package/dist/tools/registry/install.js +125 -0
- package/dist/tools/registry/install.js.map +1 -0
- package/dist/tools/registry/publish.d.ts +7 -0
- package/dist/tools/registry/publish.d.ts.map +1 -0
- package/dist/tools/registry/publish.js +96 -0
- package/dist/tools/registry/publish.js.map +1 -0
- package/dist/tools/registry/search.d.ts +7 -0
- package/dist/tools/registry/search.d.ts.map +1 -0
- package/dist/tools/registry/search.js +79 -0
- package/dist/tools/registry/search.js.map +1 -0
- package/dist/tools/resolve-sync-conflict.d.ts +3 -0
- package/dist/tools/resolve-sync-conflict.d.ts.map +1 -0
- package/dist/tools/resolve-sync-conflict.js +38 -0
- package/dist/tools/resolve-sync-conflict.js.map +1 -0
- package/dist/tools/schemas/index.d.ts +1 -0
- package/dist/tools/schemas/index.d.ts.map +1 -1
- package/dist/tools/schemas/index.js +1 -0
- package/dist/tools/schemas/index.js.map +1 -1
- package/dist/tools/schemas/spec-registry-schemas.d.ts +39 -0
- package/dist/tools/schemas/spec-registry-schemas.d.ts.map +1 -0
- package/dist/tools/schemas/spec-registry-schemas.js +72 -0
- package/dist/tools/schemas/spec-registry-schemas.js.map +1 -0
- package/dist/tools/snapshot-spec-hashes.d.ts +3 -0
- package/dist/tools/snapshot-spec-hashes.d.ts.map +1 -0
- package/dist/tools/snapshot-spec-hashes.js +100 -0
- package/dist/tools/snapshot-spec-hashes.js.map +1 -0
- package/dist/tools/spec-diff.d.ts +3 -0
- package/dist/tools/spec-diff.d.ts.map +1 -0
- package/dist/tools/spec-diff.js +58 -0
- package/dist/tools/spec-diff.js.map +1 -0
- package/dist/tools/start-hooks.d.ts +17 -0
- package/dist/tools/start-hooks.d.ts.map +1 -0
- package/dist/tools/start-hooks.js +209 -0
- package/dist/tools/start-hooks.js.map +1 -0
- package/dist/tools/sync-code-to-spec.d.ts +3 -0
- package/dist/tools/sync-code-to-spec.d.ts.map +1 -0
- package/dist/tools/sync-code-to-spec.js +51 -0
- package/dist/tools/sync-code-to-spec.js.map +1 -0
- package/dist/tools/sync-spec-to-code.d.ts +3 -0
- package/dist/tools/sync-spec-to-code.d.ts.map +1 -0
- package/dist/tools/sync-spec-to-code.js +58 -0
- package/dist/tools/sync-spec-to-code.js.map +1 -0
- package/dist/tools/validate-annotations.d.ts +3 -0
- package/dist/tools/validate-annotations.d.ts.map +1 -0
- package/dist/tools/validate-annotations.js +90 -0
- package/dist/tools/validate-annotations.js.map +1 -0
- package/dist/types/cli.d.ts +14 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +3 -0
- package/dist/types/cli.js.map +1 -0
- package/dist/types/dashboard.d.ts +86 -1
- package/dist/types/dashboard.d.ts.map +1 -1
- package/dist/types/file-hooks.d.ts +230 -0
- package/dist/types/file-hooks.d.ts.map +1 -0
- package/dist/types/file-hooks.js +3 -0
- package/dist/types/file-hooks.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/living-spec.d.ts +382 -0
- package/dist/types/living-spec.d.ts.map +1 -0
- package/dist/types/living-spec.js +3 -0
- package/dist/types/living-spec.js.map +1 -0
- package/dist/types/spec-registry.d.ts +194 -0
- package/dist/types/spec-registry.d.ts.map +1 -0
- package/dist/types/spec-registry.js +3 -0
- package/dist/types/spec-registry.js.map +1 -0
- package/package.json +1 -1
- package/src/config/hook-defaults.json +19 -0
- package/src/config/license-plans.json +23 -2
- package/src/config/registry-categories.json +20 -0
- package/src/config/registry-stacks.json +16 -0
- package/src/config/tool-groups.json +12 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// engine/living-spec/drift-watcher.ts — AC-6: In-memory drift state cache
|
|
2
|
+
// Provides a configurable TTL cache for drift detection results.
|
|
3
|
+
const DEFAULT_TTL_SECONDS = 60;
|
|
4
|
+
/**
|
|
5
|
+
* Simple glob-to-regex converter for exclude patterns.
|
|
6
|
+
* Supports *, **, and ? wildcards without external deps.
|
|
7
|
+
*/
|
|
8
|
+
export function globToRegex(pattern) {
|
|
9
|
+
let regex = '';
|
|
10
|
+
let i = 0;
|
|
11
|
+
while (i < pattern.length) {
|
|
12
|
+
const ch = pattern.charAt(i);
|
|
13
|
+
if (ch === '*') {
|
|
14
|
+
const next = i + 1 < pattern.length ? pattern.charAt(i + 1) : '';
|
|
15
|
+
if (next === '*') {
|
|
16
|
+
regex += '.*';
|
|
17
|
+
i += 2;
|
|
18
|
+
if (i < pattern.length && pattern.charAt(i) === '/') {
|
|
19
|
+
i++;
|
|
20
|
+
}
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
regex += '[^/]*';
|
|
24
|
+
}
|
|
25
|
+
else if (ch === '?') {
|
|
26
|
+
regex += '[^/]';
|
|
27
|
+
}
|
|
28
|
+
else if ('.+^${}()|[]\\'.includes(ch)) {
|
|
29
|
+
regex += `\\${ch}`;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
regex += ch;
|
|
33
|
+
}
|
|
34
|
+
i++;
|
|
35
|
+
}
|
|
36
|
+
return new RegExp(`^${regex}$`);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if a file path matches any exclude pattern.
|
|
40
|
+
*/
|
|
41
|
+
export function matchesExcludePattern(filePath, patterns) {
|
|
42
|
+
return patterns.some((p) => globToRegex(p).test(filePath));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a drift watcher with in-memory caching and configurable TTL.
|
|
46
|
+
*/
|
|
47
|
+
export function createDriftWatcher(options) {
|
|
48
|
+
const ttlSeconds = options.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
49
|
+
const excludePatterns = options.excludePatterns ?? [];
|
|
50
|
+
const cache = new Map();
|
|
51
|
+
let running = false;
|
|
52
|
+
let startedAt = null;
|
|
53
|
+
function isExpired(entry) {
|
|
54
|
+
return new Date(entry.expiresAt).getTime() < Date.now();
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
start() {
|
|
58
|
+
if (running) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
running = true;
|
|
62
|
+
startedAt = new Date().toISOString();
|
|
63
|
+
},
|
|
64
|
+
stop() {
|
|
65
|
+
running = false;
|
|
66
|
+
startedAt = null;
|
|
67
|
+
cache.clear();
|
|
68
|
+
},
|
|
69
|
+
status() {
|
|
70
|
+
for (const [key, entry] of cache) {
|
|
71
|
+
if (isExpired(entry)) {
|
|
72
|
+
cache.delete(key);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
running,
|
|
77
|
+
startedAt,
|
|
78
|
+
cacheSize: cache.size,
|
|
79
|
+
projectId: options.projectId,
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
invalidate(specId) {
|
|
83
|
+
if (specId) {
|
|
84
|
+
cache.delete(specId);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
cache.clear();
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
getCachedDrift(specId) {
|
|
91
|
+
const entry = cache.get(specId);
|
|
92
|
+
if (!entry) {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
if (isExpired(entry)) {
|
|
96
|
+
cache.delete(specId);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (excludePatterns.length > 0) {
|
|
100
|
+
const filtered = {
|
|
101
|
+
...entry,
|
|
102
|
+
data: {
|
|
103
|
+
...entry.data,
|
|
104
|
+
changedFiles: entry.data.changedFiles.filter((f) => !matchesExcludePattern(f.file, excludePatterns)),
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
return filtered;
|
|
108
|
+
}
|
|
109
|
+
return entry;
|
|
110
|
+
},
|
|
111
|
+
setCachedDrift(specId, data) {
|
|
112
|
+
if (!running) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const now = new Date();
|
|
116
|
+
const expiresAt = new Date(now.getTime() + ttlSeconds * 1000).toISOString();
|
|
117
|
+
cache.set(specId, {
|
|
118
|
+
specId,
|
|
119
|
+
data,
|
|
120
|
+
cachedAt: now.toISOString(),
|
|
121
|
+
expiresAt,
|
|
122
|
+
});
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=drift-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drift-watcher.js","sourceRoot":"","sources":["../../../src/engine/living-spec/drift-watcher.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,iEAAiE;AAUjE,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,IAAI,IAAI,KAAK,GAAG,EAAE,CAAC;gBACjB,KAAK,IAAI,IAAI,CAAC;gBACd,CAAC,IAAI,CAAC,CAAC;gBACP,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;oBACpD,CAAC,EAAE,CAAC;gBACN,CAAC;gBACD,SAAS;YACX,CAAC;YACD,KAAK,IAAI,OAAO,CAAC;QACnB,CAAC;aAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACtB,KAAK,IAAI,MAAM,CAAC;QAClB,CAAC;aAAM,IAAI,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,KAAK,IAAI,KAAK,EAAE,EAAE,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,EAAE,CAAC;QACd,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB,EAAE,QAAkB;IACxE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA4B;IAC7D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,mBAAmB,CAAC;IAC7D,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC;IACtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IACjD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,IAAI,SAAS,GAAkB,IAAI,CAAC;IAEpC,SAAS,SAAS,CAAC,KAAsB;QACvC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO;QACL,KAAK;YACH,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;YACT,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;YACf,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACvC,CAAC;QAED,IAAI;YACF,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS,GAAG,IAAI,CAAC;YACjB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;QAED,MAAM;YACJ,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;gBACjC,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;oBACrB,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACpB,CAAC;YACH,CAAC;YACD,OAAO;gBACL,OAAO;gBACP,SAAS;gBACT,SAAS,EAAE,KAAK,CAAC,IAAI;gBACrB,SAAS,EAAE,OAAO,CAAC,SAAS;aAC7B,CAAC;QACJ,CAAC;QAED,UAAU,CAAC,MAAe;YACxB,IAAI,MAAM,EAAE,CAAC;gBACX,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAED,cAAc,CAAC,MAAc;YAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACrB,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,QAAQ,GAAoB;oBAChC,GAAG,KAAK;oBACR,IAAI,EAAE;wBACJ,GAAG,KAAK,CAAC,IAAI;wBACb,YAAY,EAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAC1C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,IAAI,EAAE,eAAe,CAAC,CACvD;qBACF;iBACF,CAAC;gBACF,OAAO,QAAQ,CAAC;YAClB,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,cAAc,CAAC,MAAc,EAAE,IAAoB;YACjD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,UAAU,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5E,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE;gBAChB,MAAM;gBACN,IAAI;gBACJ,QAAQ,EAAE,GAAG,CAAC,WAAW,EAAE;gBAC3B,SAAS;aACV,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { FileHashEntry, FileHashDiff, SpecHashSnapshot } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Compute SHA-256 hash of a file's content.
|
|
4
|
+
*/
|
|
5
|
+
export declare function computeFileHash(filePath: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Create a hash entry for a single file.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createFileHashEntry(projectPath: string, relativePath: string): Promise<FileHashEntry | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Create hash entries for multiple files.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createFileHashEntries(projectPath: string, relativePaths: string[]): Promise<FileHashEntry[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Compare current file hashes against a stored snapshot.
|
|
16
|
+
* Returns a list of changed, added, and removed files.
|
|
17
|
+
*/
|
|
18
|
+
export declare function diffFileHashes(projectPath: string, previousSnapshot: SpecHashSnapshot, currentFiles: string[]): Promise<FileHashDiff[]>;
|
|
19
|
+
/**
|
|
20
|
+
* Extract file paths from a technical.md File Plan section.
|
|
21
|
+
* Looks for markdown table rows or list items with file path patterns.
|
|
22
|
+
*/
|
|
23
|
+
export declare function extractFilePlanPaths(technicalContent: string): string[];
|
|
24
|
+
//# sourceMappingURL=hash-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-tracker.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/hash-tracker.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,aAAa,EACb,YAAY,EACZ,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAE9B;;GAEG;AACH,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAc/B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,WAAW,EAAE,MAAM,EACnB,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgDzB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BvE"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// engine/living-spec/hash-tracker.ts — File hash tracking for spec drift detection
|
|
2
|
+
// Stores SHA-256 hashes of files referenced in spec's technical.md File Plan section.
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Compute SHA-256 hash of a file's content.
|
|
8
|
+
*/
|
|
9
|
+
export async function computeFileHash(filePath) {
|
|
10
|
+
const content = await readFile(filePath, 'utf-8');
|
|
11
|
+
return createHash('sha256').update(content).digest('hex');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Create a hash entry for a single file.
|
|
15
|
+
*/
|
|
16
|
+
export async function createFileHashEntry(projectPath, relativePath) {
|
|
17
|
+
const fullPath = join(projectPath, relativePath);
|
|
18
|
+
try {
|
|
19
|
+
const hash = await computeFileHash(fullPath);
|
|
20
|
+
const fileStat = await stat(fullPath);
|
|
21
|
+
return {
|
|
22
|
+
file: relativePath,
|
|
23
|
+
hash,
|
|
24
|
+
size: fileStat.size,
|
|
25
|
+
snapshotAt: new Date().toISOString(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Create hash entries for multiple files.
|
|
34
|
+
*/
|
|
35
|
+
export async function createFileHashEntries(projectPath, relativePaths) {
|
|
36
|
+
const entries = [];
|
|
37
|
+
for (const relativePath of relativePaths) {
|
|
38
|
+
const entry = await createFileHashEntry(projectPath, relativePath);
|
|
39
|
+
if (entry) {
|
|
40
|
+
entries.push(entry);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return entries;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Compare current file hashes against a stored snapshot.
|
|
47
|
+
* Returns a list of changed, added, and removed files.
|
|
48
|
+
*/
|
|
49
|
+
export async function diffFileHashes(projectPath, previousSnapshot, currentFiles) {
|
|
50
|
+
const diffs = [];
|
|
51
|
+
const previousMap = new Map();
|
|
52
|
+
for (const entry of previousSnapshot.files) {
|
|
53
|
+
previousMap.set(entry.file, entry.hash);
|
|
54
|
+
}
|
|
55
|
+
const currentSet = new Set(currentFiles);
|
|
56
|
+
// Check current files against previous
|
|
57
|
+
for (const file of currentFiles) {
|
|
58
|
+
const previousHash = previousMap.get(file) ?? '';
|
|
59
|
+
try {
|
|
60
|
+
const currentHash = await computeFileHash(join(projectPath, file));
|
|
61
|
+
if (currentHash !== previousHash) {
|
|
62
|
+
diffs.push({
|
|
63
|
+
file,
|
|
64
|
+
previousHash,
|
|
65
|
+
currentHash,
|
|
66
|
+
linkedCriteria: [],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
// File unreadable — treat as changed if it had a previous hash
|
|
72
|
+
if (previousHash) {
|
|
73
|
+
diffs.push({
|
|
74
|
+
file,
|
|
75
|
+
previousHash,
|
|
76
|
+
currentHash: '',
|
|
77
|
+
linkedCriteria: [],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Check for removed files (in previous but not in current)
|
|
83
|
+
for (const [file, hash] of previousMap) {
|
|
84
|
+
if (!currentSet.has(file)) {
|
|
85
|
+
diffs.push({
|
|
86
|
+
file,
|
|
87
|
+
previousHash: hash,
|
|
88
|
+
currentHash: '',
|
|
89
|
+
linkedCriteria: [],
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return diffs;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Extract file paths from a technical.md File Plan section.
|
|
97
|
+
* Looks for markdown table rows or list items with file path patterns.
|
|
98
|
+
*/
|
|
99
|
+
export function extractFilePlanPaths(technicalContent) {
|
|
100
|
+
const paths = [];
|
|
101
|
+
const seen = new Set();
|
|
102
|
+
// Match paths in table cells: | src/foo/bar.ts | or | `src/foo/bar.ts` |
|
|
103
|
+
const tablePattern = /\|\s*`?([a-zA-Z][\w/.\\-]+\.\w{1,10})`?\s*\|/g;
|
|
104
|
+
let match;
|
|
105
|
+
while ((match = tablePattern.exec(technicalContent)) !== null) {
|
|
106
|
+
const path = match[1];
|
|
107
|
+
if (path && !seen.has(path)) {
|
|
108
|
+
seen.add(path);
|
|
109
|
+
paths.push(path);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
// Match paths in list items: - src/foo/bar.ts or - `src/foo/bar.ts`
|
|
113
|
+
const listPattern = /[-*]\s+`?([a-zA-Z][\w/.\\-]+\.\w{1,10})`?/g;
|
|
114
|
+
while ((match = listPattern.exec(technicalContent)) !== null) {
|
|
115
|
+
const path = match[1];
|
|
116
|
+
if (path && !seen.has(path)) {
|
|
117
|
+
seen.add(path);
|
|
118
|
+
paths.push(path);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return paths;
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=hash-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash-tracker.js","sourceRoot":"","sources":["../../../src/engine/living-spec/hash-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { parseAnnotationLine, parseCriteriaList, parseAnnotationsFromContent, parseAnnotationsFromProject, } from './annotation-parser.js';
|
|
2
|
+
export { computeFileHash, createFileHashEntry, createFileHashEntries, diffFileHashes, extractFilePlanPaths, } from './hash-tracker.js';
|
|
3
|
+
export { extractSignaturesFromContent, extractSignaturesFromFile, extractSignaturesFromFiles, diffSignatures, } from './signature-tracker.js';
|
|
4
|
+
export { isRateLimited, recordReconcile, clearRateLimit, classifyChange, createLogEntry, buildAutoReconcileResult, } from './auto-reconciler.js';
|
|
5
|
+
export { createDriftWatcher, globToRegex, matchesExcludePattern } from './drift-watcher.js';
|
|
6
|
+
export { collectSpecEntries, collectSummary, collectTrends, buildSpecDiffRows, formatMarkdownDiff, } from './dashboard-collector.js';
|
|
7
|
+
export { parseVitestJson, parseJUnitXml, groupByAnnotation, determineCriterionStatus, buildCoverageReport, } from './test-coverage-correlator.js';
|
|
8
|
+
export { generateTodoComments, generateProgressUpdates, detectConflicts, createSyncLogEntry, buildSpecToCodeResult, buildCodeToSpecResult, } from './bidirectional-sync.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAC1B,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// engine/living-spec/ — Barrel export for living spec engine modules
|
|
2
|
+
export { parseAnnotationLine, parseCriteriaList, parseAnnotationsFromContent, parseAnnotationsFromProject, } from './annotation-parser.js';
|
|
3
|
+
export { computeFileHash, createFileHashEntry, createFileHashEntries, diffFileHashes, extractFilePlanPaths, } from './hash-tracker.js';
|
|
4
|
+
export { extractSignaturesFromContent, extractSignaturesFromFile, extractSignaturesFromFiles, diffSignatures, } from './signature-tracker.js';
|
|
5
|
+
export { isRateLimited, recordReconcile, clearRateLimit, classifyChange, createLogEntry, buildAutoReconcileResult, } from './auto-reconciler.js';
|
|
6
|
+
export { createDriftWatcher, globToRegex, matchesExcludePattern } from './drift-watcher.js';
|
|
7
|
+
export { collectSpecEntries, collectSummary, collectTrends, buildSpecDiffRows, formatMarkdownDiff, } from './dashboard-collector.js';
|
|
8
|
+
export { parseVitestJson, parseJUnitXml, groupByAnnotation, determineCriterionStatus, buildCoverageReport, } from './test-coverage-correlator.js';
|
|
9
|
+
export { generateTodoComments, generateProgressUpdates, detectConflicts, createSyncLogEntry, buildSpecToCodeResult, buildCodeToSpecResult, } from './bidirectional-sync.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/living-spec/index.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,GACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,0BAA0B,EAC1B,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAE5F,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { FunctionSignature, SignatureChange } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Extract exported function signatures from a TypeScript file content.
|
|
4
|
+
*/
|
|
5
|
+
export declare function extractSignaturesFromContent(content: string, file: string): FunctionSignature[];
|
|
6
|
+
/**
|
|
7
|
+
* Extract exported function signatures from a file on disk.
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractSignaturesFromFile(projectPath: string, relativePath: string): Promise<FunctionSignature[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Extract signatures from multiple files.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractSignaturesFromFiles(projectPath: string, relativePaths: string[]): Promise<FunctionSignature[]>;
|
|
14
|
+
/**
|
|
15
|
+
* Compare two sets of signatures to find added, modified, and removed.
|
|
16
|
+
*/
|
|
17
|
+
export declare function diffSignatures(previous: FunctionSignature[], current: FunctionSignature[]): SignatureChange[];
|
|
18
|
+
//# sourceMappingURL=signature-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature-tracker.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/signature-tracker.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAe/E;;GAEG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,iBAAiB,EAAE,CA8BrB;AASD;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAO9B;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EAAE,GACtB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAU9B;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,iBAAiB,EAAE,EAC7B,OAAO,EAAE,iBAAiB,EAAE,GAC3B,eAAe,EAAE,CA+CnB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// engine/living-spec/signature-tracker.ts — Extract and track exported function signatures
|
|
2
|
+
// AST-free: uses regex-based extraction from TypeScript source files.
|
|
3
|
+
// Supports: export function, export const arrow, export async function, export default
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Regex patterns for exported function signatures in TypeScript.
|
|
8
|
+
* Each pattern captures: name, params, returnType
|
|
9
|
+
*/
|
|
10
|
+
const EXPORT_PATTERNS = [
|
|
11
|
+
// export function foo(params): ReturnType
|
|
12
|
+
/^export\s+(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)\s*:\s*([^{]+)/,
|
|
13
|
+
// export const foo = (params): ReturnType =>
|
|
14
|
+
/^export\s+const\s+(\w+)\s*=\s*(?:async\s+)?\(([^)]*)\)\s*:\s*([^=>{]+)/,
|
|
15
|
+
// export default function foo(params): ReturnType
|
|
16
|
+
/^export\s+default\s+(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)\s*:\s*([^{]+)/,
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Extract exported function signatures from a TypeScript file content.
|
|
20
|
+
*/
|
|
21
|
+
export function extractSignaturesFromContent(content, file) {
|
|
22
|
+
const signatures = [];
|
|
23
|
+
const lines = content.split('\n');
|
|
24
|
+
for (let i = 0; i < lines.length; i++) {
|
|
25
|
+
const line = lines[i];
|
|
26
|
+
if (line === undefined) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const trimmed = line.trim();
|
|
30
|
+
if (!trimmed.startsWith('export')) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
for (const pattern of EXPORT_PATTERNS) {
|
|
34
|
+
const match = pattern.exec(trimmed);
|
|
35
|
+
if (match?.[1]) {
|
|
36
|
+
signatures.push({
|
|
37
|
+
name: match[1],
|
|
38
|
+
params: normalizeWhitespace(match[2] ?? ''),
|
|
39
|
+
returnType: normalizeWhitespace(match[3] ?? 'unknown'),
|
|
40
|
+
file,
|
|
41
|
+
line: i + 1,
|
|
42
|
+
});
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return signatures;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Normalize whitespace in type strings for consistent comparison.
|
|
51
|
+
*/
|
|
52
|
+
function normalizeWhitespace(str) {
|
|
53
|
+
return str.trim().replace(/\s+/g, ' ');
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Extract exported function signatures from a file on disk.
|
|
57
|
+
*/
|
|
58
|
+
export async function extractSignaturesFromFile(projectPath, relativePath) {
|
|
59
|
+
try {
|
|
60
|
+
const content = await readFile(join(projectPath, relativePath), 'utf-8');
|
|
61
|
+
return extractSignaturesFromContent(content, relativePath);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Extract signatures from multiple files.
|
|
69
|
+
*/
|
|
70
|
+
export async function extractSignaturesFromFiles(projectPath, relativePaths) {
|
|
71
|
+
const all = [];
|
|
72
|
+
for (const path of relativePaths) {
|
|
73
|
+
// Only process TypeScript/JavaScript files
|
|
74
|
+
if (/\.[tj]sx?$/.test(path)) {
|
|
75
|
+
const sigs = await extractSignaturesFromFile(projectPath, path);
|
|
76
|
+
all.push(...sigs);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return all;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Compare two sets of signatures to find added, modified, and removed.
|
|
83
|
+
*/
|
|
84
|
+
export function diffSignatures(previous, current) {
|
|
85
|
+
const changes = [];
|
|
86
|
+
const prevMap = new Map();
|
|
87
|
+
for (const sig of previous) {
|
|
88
|
+
prevMap.set(`${sig.file}::${sig.name}`, sig);
|
|
89
|
+
}
|
|
90
|
+
const currMap = new Map();
|
|
91
|
+
for (const sig of current) {
|
|
92
|
+
currMap.set(`${sig.file}::${sig.name}`, sig);
|
|
93
|
+
}
|
|
94
|
+
// Check for added and modified
|
|
95
|
+
for (const [key, curr] of currMap) {
|
|
96
|
+
const prev = prevMap.get(key);
|
|
97
|
+
if (!prev) {
|
|
98
|
+
changes.push({
|
|
99
|
+
name: curr.name,
|
|
100
|
+
file: curr.file,
|
|
101
|
+
changeType: 'added',
|
|
102
|
+
before: '',
|
|
103
|
+
after: formatSignature(curr),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
else if (prev.params !== curr.params || prev.returnType !== curr.returnType) {
|
|
107
|
+
changes.push({
|
|
108
|
+
name: curr.name,
|
|
109
|
+
file: curr.file,
|
|
110
|
+
changeType: 'modified',
|
|
111
|
+
before: formatSignature(prev),
|
|
112
|
+
after: formatSignature(curr),
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Check for removed
|
|
117
|
+
for (const [key, prev] of prevMap) {
|
|
118
|
+
if (!currMap.has(key)) {
|
|
119
|
+
changes.push({
|
|
120
|
+
name: prev.name,
|
|
121
|
+
file: prev.file,
|
|
122
|
+
changeType: 'removed',
|
|
123
|
+
before: formatSignature(prev),
|
|
124
|
+
after: '',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return changes;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Format a signature as a human-readable string.
|
|
132
|
+
*/
|
|
133
|
+
function formatSignature(sig) {
|
|
134
|
+
return `${sig.name}(${sig.params}): ${sig.returnType}`;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=signature-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signature-tracker.js","sourceRoot":"","sources":["../../../src/engine/living-spec/signature-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { AnnotationCoverageGroup, LivingSpecCoverageReport, CriterionCoverageStatus, SpecAnnotation, VitestFileResult, JUnitTestCase, NormalizedTestResult } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse a Vitest JSON report string into structured results.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseVitestJson(json: string): VitestFileResult[];
|
|
6
|
+
/**
|
|
7
|
+
* Parse JUnit XML string into test cases (simple regex-based parser).
|
|
8
|
+
*/
|
|
9
|
+
export declare function parseJUnitXml(xml: string): JUnitTestCase[];
|
|
10
|
+
/**
|
|
11
|
+
* Group test results by spec annotation, matching test file paths to annotations.
|
|
12
|
+
*/
|
|
13
|
+
export declare function groupByAnnotation(tests: NormalizedTestResult[], annotations: SpecAnnotation[]): AnnotationCoverageGroup[];
|
|
14
|
+
/**
|
|
15
|
+
* Determine criterion status based on test results.
|
|
16
|
+
*/
|
|
17
|
+
export declare function determineCriterionStatus(group: AnnotationCoverageGroup): CriterionCoverageStatus;
|
|
18
|
+
/**
|
|
19
|
+
* Build a full test coverage report from grouped results.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildCoverageReport(projectId: string, groups: AnnotationCoverageGroup[], totalTests: number, passedTests: number, failedTests: number): LivingSpecCoverageReport;
|
|
22
|
+
//# sourceMappingURL=test-coverage-correlator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-coverage-correlator.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/test-coverage-correlator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,cAAc,EACd,gBAAgB,EAEhB,aAAa,EACb,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAM9B;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAGhE;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,EAAE,CAkB1D;AAYD;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,oBAAoB,EAAE,EAC7B,WAAW,EAAE,cAAc,EAAE,GAC5B,uBAAuB,EAAE,CA+C3B;AAsBD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,uBAAuB,GAAG,uBAAuB,CAQhG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,uBAAuB,EAAE,EACjC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,wBAAwB,CAe1B"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// engine/living-spec/test-coverage-correlator.ts — AC-8: Test coverage correlation
|
|
2
|
+
// Parses Vitest JSON and JUnit XML outputs, groups by spec/criteria annotations,
|
|
3
|
+
// determines criterion status, and builds coverage reports.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Vitest JSON parsing
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/**
|
|
8
|
+
* Parse a Vitest JSON report string into structured results.
|
|
9
|
+
*/
|
|
10
|
+
export function parseVitestJson(json) {
|
|
11
|
+
const report = JSON.parse(json);
|
|
12
|
+
return report.testResults ?? [];
|
|
13
|
+
}
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// JUnit XML parsing (simple, no external deps)
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
/**
|
|
18
|
+
* Parse JUnit XML string into test cases (simple regex-based parser).
|
|
19
|
+
*/
|
|
20
|
+
export function parseJUnitXml(xml) {
|
|
21
|
+
const cases = [];
|
|
22
|
+
const testCaseRegex = /<testcase\s+([^>]*)>([\s\S]*?)<\/testcase>|<testcase\s+([^>]*)\/>/g;
|
|
23
|
+
let match;
|
|
24
|
+
while ((match = testCaseRegex.exec(xml)) !== null) {
|
|
25
|
+
const attrs = match[1] ?? match[3] ?? '';
|
|
26
|
+
const body = match[2] ?? '';
|
|
27
|
+
const name = extractAttr(attrs, 'name') ?? 'unknown';
|
|
28
|
+
const classname = extractAttr(attrs, 'classname') ?? '';
|
|
29
|
+
const file = extractAttr(attrs, 'file') ?? classname;
|
|
30
|
+
const hasFailure = body.includes('<failure') || body.includes('<error');
|
|
31
|
+
cases.push({ name, classname, file, passed: !hasFailure });
|
|
32
|
+
}
|
|
33
|
+
return cases;
|
|
34
|
+
}
|
|
35
|
+
function extractAttr(attrs, name) {
|
|
36
|
+
const regex = new RegExp(`${name}="([^"]*)"`, 'i');
|
|
37
|
+
const match = regex.exec(attrs);
|
|
38
|
+
return match?.[1] ?? null;
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Annotation grouping
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
/**
|
|
44
|
+
* Group test results by spec annotation, matching test file paths to annotations.
|
|
45
|
+
*/
|
|
46
|
+
export function groupByAnnotation(tests, annotations) {
|
|
47
|
+
const fileAnnotations = new Map();
|
|
48
|
+
for (const ann of annotations) {
|
|
49
|
+
const existing = fileAnnotations.get(ann.file) ?? [];
|
|
50
|
+
existing.push(ann);
|
|
51
|
+
fileAnnotations.set(ann.file, existing);
|
|
52
|
+
}
|
|
53
|
+
const groupMap = new Map();
|
|
54
|
+
for (const test of tests) {
|
|
55
|
+
const matchedAnnotations = findMatchingAnnotations(test.file, fileAnnotations);
|
|
56
|
+
for (const ann of matchedAnnotations) {
|
|
57
|
+
for (const criterion of ann.criteria) {
|
|
58
|
+
const key = `${ann.specId}:AC-${criterion}`;
|
|
59
|
+
const group = groupMap.get(key) ?? {
|
|
60
|
+
specId: ann.specId,
|
|
61
|
+
criterion,
|
|
62
|
+
status: 'untested',
|
|
63
|
+
testCount: 0,
|
|
64
|
+
passCount: 0,
|
|
65
|
+
failCount: 0,
|
|
66
|
+
files: [],
|
|
67
|
+
};
|
|
68
|
+
group.testCount++;
|
|
69
|
+
if (test.passed) {
|
|
70
|
+
group.passCount++;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
group.failCount++;
|
|
74
|
+
}
|
|
75
|
+
if (!group.files.includes(test.file)) {
|
|
76
|
+
group.files.push(test.file);
|
|
77
|
+
}
|
|
78
|
+
groupMap.set(key, group);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
for (const group of groupMap.values()) {
|
|
83
|
+
group.status = determineCriterionStatus(group);
|
|
84
|
+
}
|
|
85
|
+
return Array.from(groupMap.values());
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Find annotations matching a test file path.
|
|
89
|
+
*/
|
|
90
|
+
function findMatchingAnnotations(testFile, fileAnnotations) {
|
|
91
|
+
const results = [];
|
|
92
|
+
for (const [annotatedFile, anns] of fileAnnotations) {
|
|
93
|
+
if (testFile === annotatedFile ||
|
|
94
|
+
testFile.includes(annotatedFile) ||
|
|
95
|
+
annotatedFile.includes(testFile)) {
|
|
96
|
+
results.push(...anns);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return results;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Determine criterion status based on test results.
|
|
103
|
+
*/
|
|
104
|
+
export function determineCriterionStatus(group) {
|
|
105
|
+
if (group.testCount === 0) {
|
|
106
|
+
return 'untested';
|
|
107
|
+
}
|
|
108
|
+
if (group.failCount > 0) {
|
|
109
|
+
return 'regression';
|
|
110
|
+
}
|
|
111
|
+
return 'verified';
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Build a full test coverage report from grouped results.
|
|
115
|
+
*/
|
|
116
|
+
export function buildCoverageReport(projectId, groups, totalTests, passedTests, failedTests) {
|
|
117
|
+
const coveredCriteria = groups.filter((g) => g.status !== 'untested').length;
|
|
118
|
+
const totalCriteria = groups.length;
|
|
119
|
+
const coveragePercentage = totalCriteria > 0 ? Math.round((coveredCriteria / totalCriteria) * 100) : 0;
|
|
120
|
+
return {
|
|
121
|
+
projectId,
|
|
122
|
+
groups,
|
|
123
|
+
totalTests,
|
|
124
|
+
passedTests,
|
|
125
|
+
failedTests,
|
|
126
|
+
coveragePercentage,
|
|
127
|
+
generatedAt: new Date().toISOString(),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=test-coverage-correlator.js.map
|