@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,142 @@
|
|
|
1
|
+
// engine/hooks/config-loader.ts — Load & validate hook config with live reload (SPEC-129)
|
|
2
|
+
import { watch as fsWatch } from 'node:fs';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Default config (matches hook-defaults.json)
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
import hookDefaults from '../../config/hook-defaults.json' with { type: 'json' };
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
// Zod schemas
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
const hookTypeConfigSchema = z.object({
|
|
14
|
+
enabled: z.boolean().default(true),
|
|
15
|
+
include: z.array(z.string()).optional(),
|
|
16
|
+
exclude: z.array(z.string()).optional(),
|
|
17
|
+
});
|
|
18
|
+
const fileHookConfigSchema = z.object({
|
|
19
|
+
enabled: z.boolean().default(true),
|
|
20
|
+
debounceMs: z.number().min(50).max(10_000).default(300),
|
|
21
|
+
rateLimitPerFileMs: z.number().min(1000).max(60_000).default(5000),
|
|
22
|
+
hooks: z.record(z.string(), hookTypeConfigSchema).default({}),
|
|
23
|
+
});
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Config file paths
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
const HOOKS_JSON = '.planu/hooks.json';
|
|
28
|
+
const PLANU_JSON = 'planu.json';
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// ConfigLoader
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
export class ConfigLoader {
|
|
33
|
+
config;
|
|
34
|
+
projectRoot;
|
|
35
|
+
watcher = null;
|
|
36
|
+
changeCallbacks = [];
|
|
37
|
+
constructor(projectRoot) {
|
|
38
|
+
this.projectRoot = projectRoot;
|
|
39
|
+
this.config = hookDefaults;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Load config from `.planu/hooks.json` or `planu.json`.
|
|
43
|
+
* Falls back to defaults if file missing or invalid.
|
|
44
|
+
*/
|
|
45
|
+
async load() {
|
|
46
|
+
// Try .planu/hooks.json first
|
|
47
|
+
let raw = await this.readJsonFile(join(this.projectRoot, HOOKS_JSON));
|
|
48
|
+
// Try planu.json -> hooks key
|
|
49
|
+
if (!raw) {
|
|
50
|
+
const planuJson = await this.readJsonFile(join(this.projectRoot, PLANU_JSON));
|
|
51
|
+
if (planuJson &&
|
|
52
|
+
typeof planuJson === 'object' &&
|
|
53
|
+
'hooks' in planuJson) {
|
|
54
|
+
raw = planuJson.hooks;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (raw) {
|
|
58
|
+
const parsed = fileHookConfigSchema.safeParse(raw);
|
|
59
|
+
if (parsed.success) {
|
|
60
|
+
this.config = parsed.data;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const messages = parsed.error.issues.map((i) => i.message).join(', ');
|
|
64
|
+
console.warn(`[hooks] Invalid hook config, using defaults: ${messages}`);
|
|
65
|
+
this.config = hookDefaults;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.config = hookDefaults;
|
|
70
|
+
}
|
|
71
|
+
return this.config;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get current config (synchronous, must call load() first).
|
|
75
|
+
*/
|
|
76
|
+
getConfig() {
|
|
77
|
+
return this.config;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get config for a specific hook type.
|
|
81
|
+
*/
|
|
82
|
+
getHookConfig(hookType) {
|
|
83
|
+
return this.config.hooks[hookType];
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Start watching config files for live reload.
|
|
87
|
+
*/
|
|
88
|
+
startWatching() {
|
|
89
|
+
const hooksJsonPath = join(this.projectRoot, HOOKS_JSON);
|
|
90
|
+
try {
|
|
91
|
+
this.watcher = fsWatch(hooksJsonPath, () => {
|
|
92
|
+
void this.reloadConfig();
|
|
93
|
+
});
|
|
94
|
+
this.watcher.on('error', () => {
|
|
95
|
+
// Ignore watch errors — config just won't live-reload
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// File doesn't exist yet — that's fine
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Register a callback for config changes.
|
|
104
|
+
*/
|
|
105
|
+
onChange(callback) {
|
|
106
|
+
this.changeCallbacks.push(callback);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Stop watching and clean up.
|
|
110
|
+
*/
|
|
111
|
+
close() {
|
|
112
|
+
if (this.watcher) {
|
|
113
|
+
this.watcher.close();
|
|
114
|
+
this.watcher = null;
|
|
115
|
+
}
|
|
116
|
+
this.changeCallbacks = [];
|
|
117
|
+
}
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// Private
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
async reloadConfig() {
|
|
122
|
+
try {
|
|
123
|
+
await this.load();
|
|
124
|
+
for (const cb of this.changeCallbacks) {
|
|
125
|
+
cb(this.config);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Ignore reload errors — keep previous config
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async readJsonFile(filePath) {
|
|
133
|
+
try {
|
|
134
|
+
const data = await readFile(filePath, 'utf-8');
|
|
135
|
+
return JSON.parse(data);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=config-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../../src/engine/hooks/config-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { WatcherEvent, DebouncerConfig, DebouncedCallback } from '../../types/file-hooks.js';
|
|
2
|
+
export declare class Debouncer {
|
|
3
|
+
private readonly config;
|
|
4
|
+
/** Pending debounce timers per file path */
|
|
5
|
+
private readonly pendingTimers;
|
|
6
|
+
/** Pending event per file (latest wins) */
|
|
7
|
+
private readonly pendingEvents;
|
|
8
|
+
/** Rate limit buckets per file path */
|
|
9
|
+
private readonly fileBuckets;
|
|
10
|
+
/** Rate limit buckets per spec ID */
|
|
11
|
+
private readonly specBuckets;
|
|
12
|
+
private readonly callback;
|
|
13
|
+
constructor(callback: DebouncedCallback, config?: Partial<DebouncerConfig>);
|
|
14
|
+
/**
|
|
15
|
+
* Feed a raw watcher event. The debouncer will coalesce rapid events
|
|
16
|
+
* and apply rate limiting before invoking the callback.
|
|
17
|
+
*/
|
|
18
|
+
push(event: WatcherEvent): void;
|
|
19
|
+
/**
|
|
20
|
+
* Check spec-level rate limit for auto-reconcile.
|
|
21
|
+
* Returns true if allowed, false if rate-limited.
|
|
22
|
+
*/
|
|
23
|
+
checkSpecRateLimit(specId: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Cancel all pending timers and clear state.
|
|
26
|
+
*/
|
|
27
|
+
dispose(): void;
|
|
28
|
+
private tryEmit;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=debouncer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/debouncer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AA4CnC,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoD;IAClF,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;gBAEjC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAK1E;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAyB/B;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAU3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,OAAO;CAkBhB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// engine/hooks/debouncer.ts — Debounce + rate limit for file events (SPEC-129)
|
|
2
|
+
// 300ms debounce per file, global rate limit per file per 5s,
|
|
3
|
+
// per-spec rate limit per 5 min. Token bucket algorithm.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Token Bucket helpers
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
function createBucket(capacity, refillIntervalMs) {
|
|
8
|
+
return {
|
|
9
|
+
tokens: capacity,
|
|
10
|
+
lastRefill: Date.now(),
|
|
11
|
+
capacity,
|
|
12
|
+
refillIntervalMs,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function tryConsume(bucket, now) {
|
|
16
|
+
// Refill tokens based on elapsed time
|
|
17
|
+
const elapsed = now - bucket.lastRefill;
|
|
18
|
+
const tokensToAdd = Math.floor(elapsed / bucket.refillIntervalMs);
|
|
19
|
+
if (tokensToAdd > 0) {
|
|
20
|
+
const updated = {
|
|
21
|
+
...bucket,
|
|
22
|
+
tokens: Math.min(bucket.capacity, bucket.tokens + tokensToAdd),
|
|
23
|
+
lastRefill: now,
|
|
24
|
+
};
|
|
25
|
+
Object.assign(bucket, updated);
|
|
26
|
+
}
|
|
27
|
+
if (bucket.tokens > 0) {
|
|
28
|
+
Object.assign(bucket, { tokens: bucket.tokens - 1 });
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Debouncer
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
const DEFAULT_CONFIG = {
|
|
37
|
+
debounceMs: 300,
|
|
38
|
+
rateLimitPerFileMs: 5000,
|
|
39
|
+
rateLimitPerSpecMs: 300_000,
|
|
40
|
+
};
|
|
41
|
+
export class Debouncer {
|
|
42
|
+
config;
|
|
43
|
+
/** Pending debounce timers per file path */
|
|
44
|
+
pendingTimers = new Map();
|
|
45
|
+
/** Pending event per file (latest wins) */
|
|
46
|
+
pendingEvents = new Map();
|
|
47
|
+
/** Rate limit buckets per file path */
|
|
48
|
+
fileBuckets = new Map();
|
|
49
|
+
/** Rate limit buckets per spec ID */
|
|
50
|
+
specBuckets = new Map();
|
|
51
|
+
callback;
|
|
52
|
+
constructor(callback, config) {
|
|
53
|
+
this.callback = callback;
|
|
54
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Feed a raw watcher event. The debouncer will coalesce rapid events
|
|
58
|
+
* and apply rate limiting before invoking the callback.
|
|
59
|
+
*/
|
|
60
|
+
push(event) {
|
|
61
|
+
const key = event.path;
|
|
62
|
+
// Store the latest event (coalescing — last wins)
|
|
63
|
+
this.pendingEvents.set(key, event);
|
|
64
|
+
// Clear existing timer for this path
|
|
65
|
+
const existing = this.pendingTimers.get(key);
|
|
66
|
+
if (existing !== undefined) {
|
|
67
|
+
clearTimeout(existing);
|
|
68
|
+
}
|
|
69
|
+
// Set new debounce timer
|
|
70
|
+
const timer = setTimeout(() => {
|
|
71
|
+
this.pendingTimers.delete(key);
|
|
72
|
+
const latest = this.pendingEvents.get(key);
|
|
73
|
+
this.pendingEvents.delete(key);
|
|
74
|
+
if (latest) {
|
|
75
|
+
this.tryEmit(latest);
|
|
76
|
+
}
|
|
77
|
+
}, this.config.debounceMs);
|
|
78
|
+
this.pendingTimers.set(key, timer);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check spec-level rate limit for auto-reconcile.
|
|
82
|
+
* Returns true if allowed, false if rate-limited.
|
|
83
|
+
*/
|
|
84
|
+
checkSpecRateLimit(specId) {
|
|
85
|
+
const now = Date.now();
|
|
86
|
+
let bucket = this.specBuckets.get(specId);
|
|
87
|
+
if (!bucket) {
|
|
88
|
+
bucket = createBucket(1, this.config.rateLimitPerSpecMs);
|
|
89
|
+
this.specBuckets.set(specId, bucket);
|
|
90
|
+
}
|
|
91
|
+
return tryConsume(bucket, now);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Cancel all pending timers and clear state.
|
|
95
|
+
*/
|
|
96
|
+
dispose() {
|
|
97
|
+
for (const timer of this.pendingTimers.values()) {
|
|
98
|
+
clearTimeout(timer);
|
|
99
|
+
}
|
|
100
|
+
this.pendingTimers.clear();
|
|
101
|
+
this.pendingEvents.clear();
|
|
102
|
+
this.fileBuckets.clear();
|
|
103
|
+
this.specBuckets.clear();
|
|
104
|
+
}
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Private
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
tryEmit(event) {
|
|
109
|
+
const now = Date.now();
|
|
110
|
+
const key = event.path;
|
|
111
|
+
// File-level rate limit
|
|
112
|
+
let bucket = this.fileBuckets.get(key);
|
|
113
|
+
if (!bucket) {
|
|
114
|
+
bucket = createBucket(1, this.config.rateLimitPerFileMs);
|
|
115
|
+
this.fileBuckets.set(key, bucket);
|
|
116
|
+
}
|
|
117
|
+
if (!tryConsume(bucket, now)) {
|
|
118
|
+
// Rate limited — drop the event
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
this.callback(event);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=debouncer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../../../src/engine/hooks/debouncer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { EventBusEvent } from '../../types/file-hooks.js';
|
|
3
|
+
/**
|
|
4
|
+
* Typed event bus extending EventEmitter.
|
|
5
|
+
* Provides typed events with discriminated unions, filtering,
|
|
6
|
+
* event history (FIFO, last 100), and meta-events.
|
|
7
|
+
*/
|
|
8
|
+
export declare class EventBus extends EventEmitter {
|
|
9
|
+
private readonly history;
|
|
10
|
+
private idCounter;
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* Emit a typed event. Automatically adds to history and fires meta-events.
|
|
14
|
+
*/
|
|
15
|
+
emitEvent(type: EventBusEvent['type'], data: Record<string, unknown>): EventBusEvent;
|
|
16
|
+
/**
|
|
17
|
+
* Subscribe to events of a specific type.
|
|
18
|
+
*/
|
|
19
|
+
onEvent(type: EventBusEvent['type'] | '*', listener: (event: EventBusEvent) => void): this;
|
|
20
|
+
/**
|
|
21
|
+
* Subscribe to events once.
|
|
22
|
+
*/
|
|
23
|
+
onceEvent(type: EventBusEvent['type'] | '*', listener: (event: EventBusEvent) => void): this;
|
|
24
|
+
/**
|
|
25
|
+
* Get filtered event history.
|
|
26
|
+
*/
|
|
27
|
+
getHistory(filter?: {
|
|
28
|
+
type?: EventBusEvent['type'];
|
|
29
|
+
filePattern?: string;
|
|
30
|
+
}): EventBusEvent[];
|
|
31
|
+
/**
|
|
32
|
+
* Get all events in history (readonly).
|
|
33
|
+
*/
|
|
34
|
+
getFullHistory(): readonly EventBusEvent[];
|
|
35
|
+
/**
|
|
36
|
+
* Clear history.
|
|
37
|
+
*/
|
|
38
|
+
clearHistory(): void;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=event-bus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/event-bus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAY/D;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAAK;;IAOtB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAoBpF;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI1F;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI5F;;OAEG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,EAAE;IAkB5F;;OAEG;IACH,cAAc,IAAI,SAAS,aAAa,EAAE;IAI1C;;OAEG;IACH,YAAY,IAAI,IAAI;CAGrB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// engine/hooks/event-bus.ts — Typed event bus with history (SPEC-130)
|
|
2
|
+
import { EventEmitter } from 'node:events';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Constants
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const MAX_HISTORY = 100;
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// EventBus
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
/**
|
|
11
|
+
* Typed event bus extending EventEmitter.
|
|
12
|
+
* Provides typed events with discriminated unions, filtering,
|
|
13
|
+
* event history (FIFO, last 100), and meta-events.
|
|
14
|
+
*/
|
|
15
|
+
export class EventBus extends EventEmitter {
|
|
16
|
+
history = [];
|
|
17
|
+
idCounter = 0;
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
this.setMaxListeners(50);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Emit a typed event. Automatically adds to history and fires meta-events.
|
|
24
|
+
*/
|
|
25
|
+
emitEvent(type, data) {
|
|
26
|
+
const event = {
|
|
27
|
+
id: `evt-${String(++this.idCounter)}-${Date.now()}`,
|
|
28
|
+
type,
|
|
29
|
+
timestamp: Date.now(),
|
|
30
|
+
data,
|
|
31
|
+
};
|
|
32
|
+
// FIFO eviction
|
|
33
|
+
if (this.history.length >= MAX_HISTORY) {
|
|
34
|
+
this.history.shift();
|
|
35
|
+
}
|
|
36
|
+
this.history.push(event);
|
|
37
|
+
this.emit(type, event);
|
|
38
|
+
this.emit('*', event);
|
|
39
|
+
return event;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to events of a specific type.
|
|
43
|
+
*/
|
|
44
|
+
onEvent(type, listener) {
|
|
45
|
+
return this.on(type, listener);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Subscribe to events once.
|
|
49
|
+
*/
|
|
50
|
+
onceEvent(type, listener) {
|
|
51
|
+
return this.once(type, listener);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Get filtered event history.
|
|
55
|
+
*/
|
|
56
|
+
getHistory(filter) {
|
|
57
|
+
let result = [...this.history];
|
|
58
|
+
if (filter?.type) {
|
|
59
|
+
result = result.filter((e) => e.type === filter.type);
|
|
60
|
+
}
|
|
61
|
+
if (filter?.filePattern) {
|
|
62
|
+
const regex = new RegExp(filter.filePattern);
|
|
63
|
+
result = result.filter((e) => {
|
|
64
|
+
const path = e.data.path;
|
|
65
|
+
return typeof path === 'string' && regex.test(path);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get all events in history (readonly).
|
|
72
|
+
*/
|
|
73
|
+
getFullHistory() {
|
|
74
|
+
return this.history;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Clear history.
|
|
78
|
+
*/
|
|
79
|
+
clearHistory() {
|
|
80
|
+
this.history.length = 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=event-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../../src/engine/hooks/event-bus.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;IACvB,OAAO,GAAoB,EAAE,CAAC;IACvC,SAAS,GAAG,CAAC,CAAC;IAEtB;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAA2B,EAAE,IAA6B;QAClE,MAAM,KAAK,GAAkB;YAC3B,EAAE,EAAE,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC;QAEF,gBAAgB;QAChB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAiC,EAAE,QAAwC;QACjF,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAiC,EAAE,QAAwC;QACnF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,MAA+D;QACxE,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAE/B,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;YACjB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC7C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBACzB,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import type { FileWatcherOptions } from '../../types/file-hooks.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert a glob pattern to a RegExp. Supports:
|
|
5
|
+
* - `**` matches any path segment (including nested)
|
|
6
|
+
* - `*` matches any characters except path separator
|
|
7
|
+
* - `?` matches a single character
|
|
8
|
+
*/
|
|
9
|
+
export declare function globToRegex(pattern: string): RegExp;
|
|
10
|
+
/**
|
|
11
|
+
* Test whether `filePath` matches a glob pattern.
|
|
12
|
+
*/
|
|
13
|
+
export declare function matchesGlobPattern(filePath: string, pattern: string): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Returns true if filePath matches any include pattern
|
|
16
|
+
* and does not match any exclude pattern.
|
|
17
|
+
*/
|
|
18
|
+
export declare function matchesPatterns(filePath: string, include?: string[], exclude?: string[]): boolean;
|
|
19
|
+
export declare class FileWatcher extends EventEmitter {
|
|
20
|
+
private watcher;
|
|
21
|
+
private readonly rootDir;
|
|
22
|
+
private readonly include;
|
|
23
|
+
private readonly exclude;
|
|
24
|
+
/** Track known files to distinguish create vs modify */
|
|
25
|
+
private readonly knownFiles;
|
|
26
|
+
private closed;
|
|
27
|
+
constructor(options: FileWatcherOptions);
|
|
28
|
+
/**
|
|
29
|
+
* Start watching. Emits 'change' events with WatcherEvent payloads.
|
|
30
|
+
* Emits 'error' on watch failure — never throws.
|
|
31
|
+
*/
|
|
32
|
+
start(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Mark a file as known (pre-existing). Call this for initial file scan.
|
|
35
|
+
*/
|
|
36
|
+
addKnownFile(relPath: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Mark multiple files as known.
|
|
39
|
+
*/
|
|
40
|
+
addKnownFiles(paths: string[]): void;
|
|
41
|
+
/**
|
|
42
|
+
* Graceful shutdown: release all handles.
|
|
43
|
+
*/
|
|
44
|
+
close(): void;
|
|
45
|
+
private handleFsEvent;
|
|
46
|
+
private determineEventType;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=file-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/file-watcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAkC,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAMpG;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA6BnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAG7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAYjG;AAYD,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,kBAAkB;IAOvC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAqBb;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAMpC;;OAEG;IACH,KAAK,IAAI,IAAI;YAaC,aAAa;YA4Bb,kBAAkB;CAoBjC"}
|