specweave 0.18.1 → 0.20.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/CLAUDE.md +229 -1817
- package/README.md +68 -0
- package/bin/specweave.js +62 -6
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.d.ts.map +1 -1
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js +3 -0
- package/dist/plugins/specweave/lib/hooks/sync-living-docs.js.map +1 -1
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts +21 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.d.ts.map +1 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js +162 -0
- package/dist/plugins/specweave/lib/hooks/update-ac-status.js.map +1 -0
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +65 -6
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts +112 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js +301 -0
- package/dist/plugins/specweave-github/lib/completion-calculator.js.map +1 -0
- package/dist/plugins/specweave-github/lib/duplicate-detector.d.ts +3 -3
- package/dist/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts +7 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/epic-content-builder.js +42 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +14 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +51 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +87 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js +412 -0
- package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +64 -13
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts +78 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js +237 -0
- package/dist/plugins/specweave-github/lib/progress-comment-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts +97 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js +301 -0
- package/dist/plugins/specweave-github/lib/user-story-content-builder.js.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts +83 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js +386 -0
- package/dist/plugins/specweave-github/lib/user-story-issue-builder.js.map +1 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +8 -6
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +78 -117
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -1
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts +57 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +248 -0
- package/dist/plugins/specweave-kafka/lib/cli/kcat-wrapper.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.d.ts +82 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.js +13 -0
- package/dist/plugins/specweave-kafka/lib/cli/types.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts +49 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.js +316 -0
- package/dist/plugins/specweave-kafka/lib/mcp/detector.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts +70 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.js +23 -0
- package/dist/plugins/specweave-kafka/lib/mcp/types.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts +85 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.js +281 -0
- package/dist/plugins/specweave-kafka/lib/utils/partitioning.js.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts +75 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.d.ts.map +1 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.js +238 -0
- package/dist/plugins/specweave-kafka/lib/utils/sizing.js.map +1 -0
- package/dist/src/cli/commands/import-docs.js +4 -4
- package/dist/src/cli/commands/import-docs.js.map +1 -1
- package/dist/src/cli/commands/init-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/init-multiproject.js +17 -18
- package/dist/src/cli/commands/init-multiproject.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.d.ts.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js +8 -4
- package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
- package/dist/src/cli/commands/switch-project.d.ts.map +1 -1
- package/dist/src/cli/commands/switch-project.js +9 -26
- package/dist/src/cli/commands/switch-project.js.map +1 -1
- package/dist/src/cli/commands/sync-spec-content.js +3 -0
- package/dist/src/cli/commands/sync-spec-content.js.map +1 -1
- package/dist/src/core/deduplication/command-deduplicator.d.ts +166 -0
- package/dist/src/core/deduplication/command-deduplicator.d.ts.map +1 -0
- package/dist/src/core/deduplication/command-deduplicator.js +254 -0
- package/dist/src/core/deduplication/command-deduplicator.js.map +1 -0
- package/dist/src/core/increment/active-increment-manager.d.ts +42 -15
- package/dist/src/core/increment/active-increment-manager.d.ts.map +1 -1
- package/dist/src/core/increment/active-increment-manager.js +113 -46
- package/dist/src/core/increment/active-increment-manager.js.map +1 -1
- package/dist/src/core/increment/conflict-resolver.d.ts +40 -0
- package/dist/src/core/increment/conflict-resolver.d.ts.map +1 -0
- package/dist/src/core/increment/conflict-resolver.js +219 -0
- package/dist/src/core/increment/conflict-resolver.js.map +1 -0
- package/dist/src/core/increment/discipline-checker.d.ts.map +1 -1
- package/dist/src/core/increment/discipline-checker.js +7 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/duplicate-detector.d.ts +52 -0
- package/dist/src/core/increment/duplicate-detector.d.ts.map +1 -0
- package/dist/src/core/increment/duplicate-detector.js +276 -0
- package/dist/src/core/increment/duplicate-detector.js.map +1 -0
- package/dist/src/core/increment/increment-archiver.d.ts +90 -0
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -0
- package/dist/src/core/increment/increment-archiver.js +368 -0
- package/dist/src/core/increment/increment-archiver.js.map +1 -0
- package/dist/src/core/increment/increment-reopener.d.ts +165 -0
- package/dist/src/core/increment/increment-reopener.d.ts.map +1 -0
- package/dist/src/core/increment/increment-reopener.js +390 -0
- package/dist/src/core/increment/increment-reopener.js.map +1 -0
- package/dist/src/core/increment/metadata-manager.d.ts +26 -1
- package/dist/src/core/increment/metadata-manager.d.ts.map +1 -1
- package/dist/src/core/increment/metadata-manager.js +143 -5
- package/dist/src/core/increment/metadata-manager.js.map +1 -1
- package/dist/src/core/increment/recent-work-scanner.d.ts +121 -0
- package/dist/src/core/increment/recent-work-scanner.d.ts.map +1 -0
- package/dist/src/core/increment/recent-work-scanner.js +303 -0
- package/dist/src/core/increment/recent-work-scanner.js.map +1 -0
- package/dist/src/core/increment/types.d.ts +1 -0
- package/dist/src/core/increment/types.d.ts.map +1 -1
- package/dist/src/core/increment-utils.d.ts +112 -0
- package/dist/src/core/increment-utils.d.ts.map +1 -0
- package/dist/src/core/increment-utils.js +210 -0
- package/dist/src/core/increment-utils.js.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts +65 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js +175 -0
- package/dist/src/core/living-docs/ac-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts +130 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.js +549 -0
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts +81 -0
- package/dist/src/core/living-docs/feature-id-manager.d.ts.map +1 -0
- package/dist/src/core/living-docs/feature-id-manager.js +339 -0
- package/dist/src/core/living-docs/feature-id-manager.js.map +1 -0
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts +144 -83
- package/dist/src/core/living-docs/hierarchy-mapper.d.ts.map +1 -1
- package/dist/src/core/living-docs/hierarchy-mapper.js +488 -270
- package/dist/src/core/living-docs/hierarchy-mapper.js.map +1 -1
- package/dist/src/core/living-docs/index.d.ts +6 -0
- package/dist/src/core/living-docs/index.d.ts.map +1 -1
- package/dist/src/core/living-docs/index.js +6 -0
- package/dist/src/core/living-docs/index.js.map +1 -1
- package/dist/src/core/living-docs/project-detector.d.ts +6 -0
- package/dist/src/core/living-docs/project-detector.d.ts.map +1 -1
- package/dist/src/core/living-docs/project-detector.js +35 -1
- package/dist/src/core/living-docs/project-detector.js.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.d.ts +100 -26
- package/dist/src/core/living-docs/spec-distributor.d.ts.map +1 -1
- package/dist/src/core/living-docs/spec-distributor.js +1275 -258
- package/dist/src/core/living-docs/spec-distributor.js.map +1 -1
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts +109 -0
- package/dist/src/core/living-docs/task-project-specific-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js +221 -0
- package/dist/src/core/living-docs/task-project-specific-generator.js.map +1 -0
- package/dist/src/core/living-docs/types.d.ts +143 -0
- package/dist/src/core/living-docs/types.d.ts.map +1 -1
- package/dist/src/core/project-manager.d.ts +2 -17
- package/dist/src/core/project-manager.d.ts.map +1 -1
- package/dist/src/core/project-manager.js +68 -48
- package/dist/src/core/project-manager.js.map +1 -1
- package/dist/src/core/spec-content-sync.d.ts +1 -1
- package/dist/src/core/spec-content-sync.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.js +2 -1
- package/dist/src/core/sync/enhanced-content-builder.js.map +1 -1
- package/dist/src/core/sync/performance-optimizer.d.ts +153 -0
- package/dist/src/core/sync/performance-optimizer.d.ts.map +1 -0
- package/dist/src/core/sync/performance-optimizer.js +220 -0
- package/dist/src/core/sync/performance-optimizer.js.map +1 -0
- package/dist/src/core/sync/retry-handler.d.ts +98 -0
- package/dist/src/core/sync/retry-handler.d.ts.map +1 -0
- package/dist/src/core/sync/retry-handler.js +196 -0
- package/dist/src/core/sync/retry-handler.js.map +1 -0
- package/dist/src/core/types/config.d.ts +94 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js +16 -0
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +6 -0
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/increment-metadata.js +10 -1
- package/dist/src/core/types/increment-metadata.js.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +4 -8
- package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
- package/package.json +1 -1
- package/plugins/specweave/COMMANDS.md +13 -4
- package/plugins/specweave/commands/specweave-abandon.md +22 -20
- package/plugins/specweave/commands/specweave-archive-features.md +121 -0
- package/plugins/specweave/commands/specweave-archive-increments.md +82 -0
- package/plugins/specweave/commands/specweave-archive.md +363 -0
- package/plugins/specweave/commands/specweave-backlog.md +211 -0
- package/plugins/specweave/commands/specweave-fix-duplicates.md +517 -0
- package/plugins/specweave/commands/specweave-increment.md +4 -3
- package/plugins/specweave/commands/specweave-progress.md +176 -27
- package/plugins/specweave/commands/specweave-reopen.md +391 -0
- package/plugins/specweave/commands/specweave-restore-feature.md +90 -0
- package/plugins/specweave/commands/specweave-restore.md +309 -0
- package/plugins/specweave/commands/specweave-resume.md +51 -23
- package/plugins/specweave/commands/specweave-status.md +41 -7
- package/plugins/specweave/commands/specweave-sync-specs.md +425 -0
- package/plugins/specweave/hooks/hooks.json +4 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
- package/plugins/specweave/hooks/post-task-completion.sh +39 -0
- package/plugins/specweave/hooks/pre-command-deduplication.sh +83 -0
- package/plugins/specweave/hooks/user-prompt-submit.sh +1 -1
- package/plugins/specweave/lib/hooks/sync-living-docs.js +2 -0
- package/plugins/specweave/lib/hooks/sync-living-docs.ts +4 -0
- package/plugins/specweave/lib/hooks/update-ac-status.js +102 -0
- package/plugins/specweave/lib/hooks/update-ac-status.ts +192 -0
- package/plugins/specweave/skills/archive-increments/SKILL.md +198 -0
- package/plugins/specweave/skills/increment-planner/scripts/feature-utils.js +14 -0
- package/plugins/specweave/skills/smart-reopen-detector/SKILL.md +244 -0
- package/plugins/specweave-ado/lib/ado-spec-content-sync.js +49 -5
- package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +72 -6
- package/plugins/specweave-confluent/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-confluent/README.md +375 -0
- package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +306 -0
- package/plugins/specweave-confluent/skills/confluent-kafka-connect/SKILL.md +453 -0
- package/plugins/specweave-confluent/skills/confluent-ksqldb/SKILL.md +470 -0
- package/plugins/specweave-confluent/skills/confluent-schema-registry/SKILL.md +316 -0
- package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +2 -2
- package/plugins/specweave-github/agents/user-story-updater/AGENT.md +148 -0
- package/plugins/specweave-github/commands/specweave-github-cleanup-duplicates.md +1 -1
- package/plugins/specweave-github/commands/specweave-github-update-user-story.md +156 -0
- package/plugins/specweave-github/hooks/post-task-completion.sh +10 -9
- package/plugins/specweave-github/lib/completion-calculator.js +262 -0
- package/plugins/specweave-github/lib/completion-calculator.ts +434 -0
- package/plugins/specweave-github/lib/duplicate-detector.js +3 -3
- package/plugins/specweave-github/lib/duplicate-detector.ts +4 -4
- package/plugins/specweave-github/lib/epic-content-builder.js +38 -0
- package/plugins/specweave-github/lib/epic-content-builder.ts +59 -0
- package/plugins/specweave-github/lib/github-client-v2.js +49 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +59 -0
- package/plugins/specweave-github/lib/github-epic-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-feature-sync.js +381 -0
- package/plugins/specweave-github/lib/github-feature-sync.ts +568 -0
- package/plugins/specweave-github/lib/github-spec-content-sync.js +40 -10
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +82 -14
- package/plugins/specweave-github/lib/progress-comment-builder.js +229 -0
- package/plugins/specweave-github/lib/progress-comment-builder.ts +324 -0
- package/plugins/specweave-github/lib/user-story-content-builder.js +299 -0
- package/plugins/specweave-github/lib/user-story-content-builder.ts +413 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.js +344 -0
- package/plugins/specweave-github/lib/user-story-issue-builder.ts +543 -0
- package/plugins/specweave-github/skills/github-issue-standard/SKILL.md +189 -0
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +134 -0
- package/plugins/specweave-jira/lib/{enhanced-jira-sync.ts.disabled → enhanced-jira-sync.ts} +26 -52
- package/plugins/specweave-kafka/.claude-plugin/plugin.json +26 -0
- package/plugins/specweave-kafka/IMPLEMENTATION-COMPLETE.md +483 -0
- package/plugins/specweave-kafka/README.md +242 -0
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +235 -0
- package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +209 -0
- package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +266 -0
- package/plugins/specweave-kafka/commands/deploy.md +99 -0
- package/plugins/specweave-kafka/commands/dev-env.md +176 -0
- package/plugins/specweave-kafka/commands/mcp-configure.md +101 -0
- package/plugins/specweave-kafka/commands/monitor-setup.md +96 -0
- package/plugins/specweave-kafka/docker/kafka-local/docker-compose.yml +187 -0
- package/plugins/specweave-kafka/docker/redpanda/docker-compose.yml +199 -0
- package/plugins/specweave-kafka/docker/templates/consumer-nodejs.js +225 -0
- package/plugins/specweave-kafka/docker/templates/consumer-python.py +220 -0
- package/plugins/specweave-kafka/docker/templates/producer-nodejs.js +168 -0
- package/plugins/specweave-kafka/docker/templates/producer-python.py +167 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.js +438 -0
- package/plugins/specweave-kafka/lib/adapters/apache-kafka-adapter.ts +541 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.js +47 -0
- package/plugins/specweave-kafka/lib/adapters/platform-adapter.ts +343 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.js +258 -0
- package/plugins/specweave-kafka/lib/cli/kcat-wrapper.ts +298 -0
- package/plugins/specweave-kafka/lib/cli/types.js +10 -0
- package/plugins/specweave-kafka/lib/cli/types.ts +92 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.js +305 -0
- package/plugins/specweave-kafka/lib/connectors/connector-catalog.ts +528 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.js +114 -0
- package/plugins/specweave-kafka/lib/documentation/diagram-generator.ts +195 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.js +210 -0
- package/plugins/specweave-kafka/lib/documentation/exporter.ts +338 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.js +60 -0
- package/plugins/specweave-kafka/lib/documentation/schema-catalog-generator.ts +130 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.js +143 -0
- package/plugins/specweave-kafka/lib/documentation/topology-generator.ts +290 -0
- package/plugins/specweave-kafka/lib/mcp/detector.js +298 -0
- package/plugins/specweave-kafka/lib/mcp/detector.ts +352 -0
- package/plugins/specweave-kafka/lib/mcp/types.js +21 -0
- package/plugins/specweave-kafka/lib/mcp/types.ts +77 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.js +193 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-config-manager.ts +362 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.js +188 -0
- package/plugins/specweave-kafka/lib/multi-cluster/cluster-switcher.ts +359 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.js +195 -0
- package/plugins/specweave-kafka/lib/multi-cluster/health-aggregator.ts +380 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.js +209 -0
- package/plugins/specweave-kafka/lib/observability/opentelemetry-kafka.ts +358 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.js +354 -0
- package/plugins/specweave-kafka/lib/patterns/advanced-ksqldb-patterns.ts +563 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.js +259 -0
- package/plugins/specweave-kafka/lib/patterns/circuit-breaker-resilience.ts +516 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.js +233 -0
- package/plugins/specweave-kafka/lib/patterns/dead-letter-queue.ts +423 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.js +266 -0
- package/plugins/specweave-kafka/lib/patterns/exactly-once-semantics.ts +445 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.js +312 -0
- package/plugins/specweave-kafka/lib/patterns/flink-kafka-integration.ts +561 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.js +289 -0
- package/plugins/specweave-kafka/lib/patterns/multi-dc-replication.ts +607 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.js +264 -0
- package/plugins/specweave-kafka/lib/patterns/rate-limiting-backpressure.ts +498 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.js +263 -0
- package/plugins/specweave-kafka/lib/patterns/stream-processing-optimization.ts +549 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.js +205 -0
- package/plugins/specweave-kafka/lib/patterns/tiered-storage-compaction.ts +399 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.js +249 -0
- package/plugins/specweave-kafka/lib/performance/performance-optimizer.ts +427 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.js +252 -0
- package/plugins/specweave-kafka/lib/security/kafka-security.ts +494 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.js +203 -0
- package/plugins/specweave-kafka/lib/utils/capacity-planner.ts +469 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.js +419 -0
- package/plugins/specweave-kafka/lib/utils/config-validator.ts +564 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.js +329 -0
- package/plugins/specweave-kafka/lib/utils/partitioning.ts +473 -0
- package/plugins/specweave-kafka/lib/utils/sizing.js +221 -0
- package/plugins/specweave-kafka/lib/utils/sizing.ts +374 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-broker-metrics.json +628 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-cluster-overview.json +564 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-consumer-lag.json +509 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-jvm-metrics.json +674 -0
- package/plugins/specweave-kafka/monitoring/grafana/dashboards/kafka-topic-metrics.json +578 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/dashboards/kafka.yml +17 -0
- package/plugins/specweave-kafka/monitoring/grafana/provisioning/datasources/prometheus.yml +17 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-alerts.yml +415 -0
- package/plugins/specweave-kafka/monitoring/prometheus/kafka-jmx-exporter.yml +256 -0
- package/plugins/specweave-kafka/package.json +41 -0
- package/plugins/specweave-kafka/skills/kafka-architecture/SKILL.md +647 -0
- package/plugins/specweave-kafka/skills/kafka-cli-tools/SKILL.md +433 -0
- package/plugins/specweave-kafka/skills/kafka-iac-deployment/SKILL.md +449 -0
- package/plugins/specweave-kafka/skills/kafka-kubernetes/SKILL.md +667 -0
- package/plugins/specweave-kafka/skills/kafka-mcp-integration/SKILL.md +273 -0
- package/plugins/specweave-kafka/skills/kafka-observability/SKILL.md +576 -0
- package/plugins/specweave-kafka/templates/config/broker-production.properties +254 -0
- package/plugins/specweave-kafka/templates/config/consumer-low-latency.properties +112 -0
- package/plugins/specweave-kafka/templates/config/producer-high-throughput.properties +120 -0
- package/plugins/specweave-kafka/templates/migration/mirrormaker2-config.properties +234 -0
- package/plugins/specweave-kafka/templates/monitoring/grafana/multi-cluster-dashboard.json +686 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/main.tf +347 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/outputs.tf +107 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/templates/kafka-broker-init.sh.tpl +216 -0
- package/plugins/specweave-kafka/terraform/apache-kafka/variables.tf +156 -0
- package/plugins/specweave-kafka/terraform/aws-msk/main.tf +362 -0
- package/plugins/specweave-kafka/terraform/aws-msk/outputs.tf +93 -0
- package/plugins/specweave-kafka/terraform/aws-msk/templates/server.properties.tpl +32 -0
- package/plugins/specweave-kafka/terraform/aws-msk/variables.tf +235 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/main.tf +281 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/outputs.tf +118 -0
- package/plugins/specweave-kafka/terraform/azure-event-hubs/variables.tf +148 -0
- package/plugins/specweave-kafka/tsconfig.json +21 -0
- package/plugins/specweave-kafka-streams/.claude-plugin/plugin.json +23 -0
- package/plugins/specweave-kafka-streams/README.md +310 -0
- package/plugins/specweave-kafka-streams/skills/kafka-streams-topology/SKILL.md +539 -0
- package/plugins/specweave-n8n/.claude-plugin/plugin.json +22 -0
- package/plugins/specweave-n8n/README.md +354 -0
- package/plugins/specweave-n8n/skills/n8n-kafka-workflows/SKILL.md +504 -0
- package/plugins/specweave-release/commands/specweave-release-platform.md +1 -1
- package/plugins/specweave-release/hooks/post-task-completion.sh +2 -2
- package/src/templates/AGENTS.md.template +601 -7
- package/src/templates/CLAUDE.md.template +188 -88
- package/plugins/specweave-ado/commands/specweave-ado-sync-spec.md +0 -255
- package/plugins/specweave-github/commands/specweave-github-sync-epic.md +0 -248
- package/plugins/specweave-github/commands/specweave-github-sync-from.md +0 -147
- package/plugins/specweave-github/commands/specweave-github-sync-spec.md +0 -208
- package/plugins/specweave-github/commands/specweave-github-sync-tasks.md +0 -530
- package/plugins/specweave-jira/commands/specweave-jira-sync-epic.md +0 -267
- package/plugins/specweave-jira/commands/specweave-jira-sync-spec.md +0 -240
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Command Deduplication System
|
|
3
|
+
*
|
|
4
|
+
* Prevents ANY command/tool from being invoked twice within a configurable time window.
|
|
5
|
+
* Tracks all SlashCommand, Write, Edit, and other tool invocations.
|
|
6
|
+
*
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - File-based cache: `.specweave/state/command-invocations.json`
|
|
9
|
+
* - Hash-based deduplication: command + args → unique fingerprint
|
|
10
|
+
* - Time-windowed checks: Configurable window (default: 1000ms)
|
|
11
|
+
* - Automatic cleanup: Removes old entries to prevent bloat
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { CommandDeduplicator } from './command-deduplicator.js';
|
|
16
|
+
*
|
|
17
|
+
* const dedup = new CommandDeduplicator();
|
|
18
|
+
* const isDuplicate = await dedup.checkDuplicate('/specweave:do', ['0031']);
|
|
19
|
+
*
|
|
20
|
+
* if (isDuplicate) {
|
|
21
|
+
* console.log('⚠️ Duplicate invocation blocked!');
|
|
22
|
+
* return;
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* await dedup.recordInvocation('/specweave:do', ['0031']);
|
|
26
|
+
* // ... execute command
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @module core/deduplication
|
|
30
|
+
*/
|
|
31
|
+
import fs from 'fs-extra';
|
|
32
|
+
import * as path from 'path';
|
|
33
|
+
import * as crypto from 'crypto';
|
|
34
|
+
/**
|
|
35
|
+
* Global command deduplication system
|
|
36
|
+
*/
|
|
37
|
+
export class CommandDeduplicator {
|
|
38
|
+
/**
|
|
39
|
+
* Create new deduplicator instance
|
|
40
|
+
*
|
|
41
|
+
* @param config - Configuration options
|
|
42
|
+
* @param projectRoot - Project root directory (default: process.cwd())
|
|
43
|
+
*/
|
|
44
|
+
constructor(config = {}, projectRoot = process.cwd()) {
|
|
45
|
+
this.projectRoot = projectRoot;
|
|
46
|
+
this.lastCleanupCheck = 0;
|
|
47
|
+
this.config = {
|
|
48
|
+
windowMs: config.windowMs ?? 1000,
|
|
49
|
+
cachePath: config.cachePath ?? path.join(projectRoot, '.specweave', 'state', 'command-invocations.json'),
|
|
50
|
+
maxCacheSize: config.maxCacheSize ?? 1000,
|
|
51
|
+
debug: config.debug ?? false,
|
|
52
|
+
cleanupIntervalMs: config.cleanupIntervalMs ?? 60000
|
|
53
|
+
};
|
|
54
|
+
this.cache = this.loadCache();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Check if command invocation is a duplicate
|
|
58
|
+
*
|
|
59
|
+
* @param command - Command name (e.g., '/specweave:do')
|
|
60
|
+
* @param args - Command arguments
|
|
61
|
+
* @returns true if duplicate detected, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
async checkDuplicate(command, args = []) {
|
|
64
|
+
const fingerprint = this.createFingerprint(command, args);
|
|
65
|
+
const now = Date.now();
|
|
66
|
+
const windowStart = now - this.config.windowMs;
|
|
67
|
+
// Check for recent invocations with same fingerprint
|
|
68
|
+
const recentDuplicates = this.cache.invocations.filter(inv => inv.fingerprint === fingerprint &&
|
|
69
|
+
inv.timestamp >= windowStart);
|
|
70
|
+
if (recentDuplicates.length > 0) {
|
|
71
|
+
const mostRecent = recentDuplicates[recentDuplicates.length - 1];
|
|
72
|
+
const timeSince = now - mostRecent.timestamp;
|
|
73
|
+
if (this.config.debug) {
|
|
74
|
+
console.log(`[CommandDeduplicator] 🚫 DUPLICATE DETECTED!`);
|
|
75
|
+
console.log(` Command: ${command}`);
|
|
76
|
+
console.log(` Args: ${JSON.stringify(args)}`);
|
|
77
|
+
console.log(` Time since last: ${timeSince}ms`);
|
|
78
|
+
console.log(` Window: ${this.config.windowMs}ms`);
|
|
79
|
+
}
|
|
80
|
+
// Increment duplicate counter
|
|
81
|
+
this.cache.totalDuplicatesBlocked++;
|
|
82
|
+
await this.saveCache();
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Record command invocation
|
|
89
|
+
*
|
|
90
|
+
* @param command - Command name
|
|
91
|
+
* @param args - Command arguments
|
|
92
|
+
*/
|
|
93
|
+
async recordInvocation(command, args = []) {
|
|
94
|
+
const fingerprint = this.createFingerprint(command, args);
|
|
95
|
+
const now = Date.now();
|
|
96
|
+
const record = {
|
|
97
|
+
fingerprint,
|
|
98
|
+
command,
|
|
99
|
+
args,
|
|
100
|
+
timestamp: now,
|
|
101
|
+
date: new Date(now).toISOString()
|
|
102
|
+
};
|
|
103
|
+
this.cache.invocations.push(record);
|
|
104
|
+
this.cache.totalInvocations++;
|
|
105
|
+
if (this.config.debug) {
|
|
106
|
+
console.log(`[CommandDeduplicator] ✅ Recorded invocation: ${command} ${args.join(' ')}`);
|
|
107
|
+
}
|
|
108
|
+
// Trigger cleanup if needed
|
|
109
|
+
if (now - this.lastCleanupCheck > this.config.cleanupIntervalMs) {
|
|
110
|
+
await this.cleanup();
|
|
111
|
+
this.lastCleanupCheck = now;
|
|
112
|
+
}
|
|
113
|
+
await this.saveCache();
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create unique fingerprint for command + args
|
|
117
|
+
*
|
|
118
|
+
* @param command - Command name
|
|
119
|
+
* @param args - Command arguments
|
|
120
|
+
* @returns SHA256 hash of command + args
|
|
121
|
+
*/
|
|
122
|
+
createFingerprint(command, args) {
|
|
123
|
+
const data = JSON.stringify({ command, args });
|
|
124
|
+
return crypto.createHash('sha256').update(data).digest('hex');
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Load cache from disk
|
|
128
|
+
*
|
|
129
|
+
* @returns Invocation cache
|
|
130
|
+
*/
|
|
131
|
+
loadCache() {
|
|
132
|
+
try {
|
|
133
|
+
if (fs.existsSync(this.config.cachePath)) {
|
|
134
|
+
const data = fs.readJsonSync(this.config.cachePath);
|
|
135
|
+
if (this.config.debug) {
|
|
136
|
+
console.log(`[CommandDeduplicator] 📂 Loaded cache: ${data.invocations.length} invocations`);
|
|
137
|
+
}
|
|
138
|
+
return data;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
if (this.config.debug) {
|
|
143
|
+
console.log(`[CommandDeduplicator] ⚠️ Failed to load cache: ${error}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Return empty cache
|
|
147
|
+
return {
|
|
148
|
+
invocations: [],
|
|
149
|
+
lastCleanup: Date.now(),
|
|
150
|
+
totalInvocations: 0,
|
|
151
|
+
totalDuplicatesBlocked: 0
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Save cache to disk
|
|
156
|
+
*/
|
|
157
|
+
async saveCache() {
|
|
158
|
+
try {
|
|
159
|
+
await fs.ensureDir(path.dirname(this.config.cachePath));
|
|
160
|
+
await fs.writeJson(this.config.cachePath, this.cache, { spaces: 2 });
|
|
161
|
+
if (this.config.debug) {
|
|
162
|
+
console.log(`[CommandDeduplicator] 💾 Saved cache: ${this.cache.invocations.length} invocations`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error(`[CommandDeduplicator] ❌ Failed to save cache: ${error}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Clean up old invocation records
|
|
171
|
+
*
|
|
172
|
+
* Removes records older than 10x the deduplication window to prevent cache bloat.
|
|
173
|
+
*/
|
|
174
|
+
async cleanup() {
|
|
175
|
+
const now = Date.now();
|
|
176
|
+
const cutoff = now - (this.config.windowMs * 10); // Keep 10x window
|
|
177
|
+
const before = this.cache.invocations.length;
|
|
178
|
+
this.cache.invocations = this.cache.invocations.filter(inv => inv.timestamp >= cutoff);
|
|
179
|
+
const after = this.cache.invocations.length;
|
|
180
|
+
// Also enforce max cache size
|
|
181
|
+
if (this.cache.invocations.length > this.config.maxCacheSize) {
|
|
182
|
+
this.cache.invocations = this.cache.invocations.slice(-this.config.maxCacheSize);
|
|
183
|
+
}
|
|
184
|
+
this.cache.lastCleanup = now;
|
|
185
|
+
if (this.config.debug && before > after) {
|
|
186
|
+
console.log(`[CommandDeduplicator] 🧹 Cleanup: Removed ${before - after} old records`);
|
|
187
|
+
}
|
|
188
|
+
await this.saveCache();
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get statistics about deduplication
|
|
192
|
+
*
|
|
193
|
+
* @returns Statistics object
|
|
194
|
+
*/
|
|
195
|
+
getStats() {
|
|
196
|
+
return {
|
|
197
|
+
totalInvocations: this.cache.totalInvocations,
|
|
198
|
+
totalDuplicatesBlocked: this.cache.totalDuplicatesBlocked,
|
|
199
|
+
currentCacheSize: this.cache.invocations.length,
|
|
200
|
+
lastCleanup: new Date(this.cache.lastCleanup).toISOString()
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Clear all cached invocations (useful for testing)
|
|
205
|
+
*/
|
|
206
|
+
async clear() {
|
|
207
|
+
this.cache = {
|
|
208
|
+
invocations: [],
|
|
209
|
+
lastCleanup: Date.now(),
|
|
210
|
+
totalInvocations: 0,
|
|
211
|
+
totalDuplicatesBlocked: 0
|
|
212
|
+
};
|
|
213
|
+
await this.saveCache();
|
|
214
|
+
if (this.config.debug) {
|
|
215
|
+
console.log(`[CommandDeduplicator] 🗑️ Cache cleared`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Global singleton instance (convenience)
|
|
221
|
+
*/
|
|
222
|
+
let globalInstance = null;
|
|
223
|
+
/**
|
|
224
|
+
* Get global deduplicator instance
|
|
225
|
+
*
|
|
226
|
+
* @param config - Configuration (only used on first call)
|
|
227
|
+
* @returns Global deduplicator instance
|
|
228
|
+
*/
|
|
229
|
+
export function getGlobalDeduplicator(config) {
|
|
230
|
+
if (!globalInstance) {
|
|
231
|
+
globalInstance = new CommandDeduplicator(config);
|
|
232
|
+
}
|
|
233
|
+
return globalInstance;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Convenience function: Check if command is duplicate
|
|
237
|
+
*
|
|
238
|
+
* @param command - Command name
|
|
239
|
+
* @param args - Command arguments
|
|
240
|
+
* @returns true if duplicate, false otherwise
|
|
241
|
+
*/
|
|
242
|
+
export async function isDuplicate(command, args = []) {
|
|
243
|
+
return await getGlobalDeduplicator().checkDuplicate(command, args);
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Convenience function: Record command invocation
|
|
247
|
+
*
|
|
248
|
+
* @param command - Command name
|
|
249
|
+
* @param args - Command arguments
|
|
250
|
+
*/
|
|
251
|
+
export async function recordCommand(command, args = []) {
|
|
252
|
+
await getGlobalDeduplicator().recordInvocation(command, args);
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=command-deduplicator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-deduplicator.js","sourceRoot":"","sources":["../../../../src/core/deduplication/command-deduplicator.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,15 @@
|
|
|
14
14
|
*/
|
|
15
15
|
/**
|
|
16
16
|
* Active increment state stored in .specweave/state/active-increment.json
|
|
17
|
+
*
|
|
18
|
+
* **UPGRADED**: Now supports MULTIPLE active increments (up to 2)
|
|
19
|
+
* - One regular feature increment
|
|
20
|
+
* - One hotfix/bug increment (optional)
|
|
17
21
|
*/
|
|
18
22
|
export interface ActiveIncrementState {
|
|
19
|
-
|
|
23
|
+
ids: string[];
|
|
24
|
+
id?: string | null;
|
|
25
|
+
lastUpdated: string;
|
|
20
26
|
}
|
|
21
27
|
/**
|
|
22
28
|
* Active Increment Manager
|
|
@@ -28,22 +34,43 @@ export declare class ActiveIncrementManager {
|
|
|
28
34
|
private stateFile;
|
|
29
35
|
constructor(rootDir?: string);
|
|
30
36
|
/**
|
|
31
|
-
* Get
|
|
32
|
-
* Returns
|
|
37
|
+
* Get all currently active increment IDs
|
|
38
|
+
* Returns empty array if no increments are active
|
|
39
|
+
*
|
|
40
|
+
* **NEW**: Returns array of ALL active increments (max 2)
|
|
41
|
+
*/
|
|
42
|
+
getActive(): string[];
|
|
43
|
+
/**
|
|
44
|
+
* Get the primary active increment (first in list)
|
|
45
|
+
* Returns null if no increments are active
|
|
46
|
+
*
|
|
47
|
+
* This maintains backwards compatibility with code expecting a single ID
|
|
33
48
|
*/
|
|
34
|
-
|
|
49
|
+
getPrimary(): string | null;
|
|
35
50
|
/**
|
|
36
|
-
*
|
|
51
|
+
* Add an increment to the active list
|
|
37
52
|
* Validates that the increment exists and is actually active
|
|
53
|
+
*
|
|
54
|
+
* **NEW**: Adds to list instead of replacing (max 2)
|
|
55
|
+
* @param skipValidation - Skip validation (used during lazy initialization to prevent circular dependency)
|
|
56
|
+
*/
|
|
57
|
+
addActive(incrementId: string, skipValidation?: boolean): void;
|
|
58
|
+
/**
|
|
59
|
+
* Remove an increment from the active list
|
|
60
|
+
*/
|
|
61
|
+
removeActive(incrementId: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Set the active increment (legacy method for backwards compatibility)
|
|
64
|
+
* Now delegates to addActive()
|
|
65
|
+
* @param skipValidation - Skip validation (used during lazy initialization to prevent circular dependency)
|
|
38
66
|
*/
|
|
39
|
-
setActive(incrementId: string): void;
|
|
67
|
+
setActive(incrementId: string, skipValidation?: boolean): void;
|
|
40
68
|
/**
|
|
41
|
-
* Clear
|
|
69
|
+
* Clear all active increments
|
|
42
70
|
*/
|
|
43
71
|
clearActive(): void;
|
|
44
72
|
/**
|
|
45
|
-
* Smart update:
|
|
46
|
-
* or clear if none are active.
|
|
73
|
+
* Smart update: Rebuild active list from metadata
|
|
47
74
|
*
|
|
48
75
|
* This is called when:
|
|
49
76
|
* - An increment is completed
|
|
@@ -51,16 +78,16 @@ export declare class ActiveIncrementManager {
|
|
|
51
78
|
* - An increment is abandoned
|
|
52
79
|
*
|
|
53
80
|
* Logic:
|
|
54
|
-
* 1.
|
|
55
|
-
* 2.
|
|
56
|
-
* 3.
|
|
81
|
+
* 1. Scan all increments for status=active
|
|
82
|
+
* 2. Update cache to match reality
|
|
83
|
+
* 3. Max 2 increments (sorted by lastActivity)
|
|
57
84
|
*/
|
|
58
85
|
smartUpdate(): void;
|
|
59
86
|
/**
|
|
60
|
-
* Validate that
|
|
61
|
-
*
|
|
87
|
+
* Validate that all active increment pointers are correct
|
|
88
|
+
* Does NOT fix stale pointers - caller should call smartUpdate() if needed
|
|
62
89
|
*
|
|
63
|
-
* Returns true if valid
|
|
90
|
+
* Returns true if all valid, false if any invalid
|
|
64
91
|
*/
|
|
65
92
|
validate(): boolean;
|
|
66
93
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-increment-manager.d.ts","sourceRoot":"","sources":["../../../../src/core/increment/active-increment-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH
|
|
1
|
+
{"version":3,"file":"active-increment-manager.d.ts","sourceRoot":"","sources":["../../../../src/core/increment/active-increment-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IAEnC,GAAG,EAAE,MAAM,EAAE,CAAC;IAGd,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAGnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,qBAAa,sBAAsB;IAGrB,OAAO,CAAC,OAAO;IAF3B,OAAO,CAAC,SAAS,CAAS;gBAEN,OAAO,GAAE,MAAsB;IAInD;;;;;OAKG;IACH,SAAS,IAAI,MAAM,EAAE;IAqBrB;;;;;OAKG;IACH,UAAU,IAAI,MAAM,GAAG,IAAI;IAK3B;;;;;;OAMG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,GAAE,OAAe,GAAG,IAAI;IAgCrE;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAWvC;;;;OAIG;IACH,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,cAAc,GAAE,OAAe,GAAG,IAAI;IAIrE;;OAEG;IACH,WAAW,IAAI,IAAI;IAQnB;;;;;;;;;;;;OAYG;IACH,WAAW,IAAI,IAAI;IAyBnB;;;;;OAKG;IACH,QAAQ,IAAI,OAAO;IAmCnB;;OAEG;IACH,OAAO,CAAC,UAAU;IAalB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,MAAM,IAAI,OAAO;CAGlB"}
|
|
@@ -27,48 +27,102 @@ export class ActiveIncrementManager {
|
|
|
27
27
|
this.stateFile = path.join(rootDir, '.specweave/state/active-increment.json');
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
|
-
* Get
|
|
31
|
-
* Returns
|
|
30
|
+
* Get all currently active increment IDs
|
|
31
|
+
* Returns empty array if no increments are active
|
|
32
|
+
*
|
|
33
|
+
* **NEW**: Returns array of ALL active increments (max 2)
|
|
32
34
|
*/
|
|
33
35
|
getActive() {
|
|
34
36
|
try {
|
|
35
37
|
if (!fs.existsSync(this.stateFile)) {
|
|
36
|
-
return
|
|
38
|
+
return [];
|
|
37
39
|
}
|
|
38
40
|
const content = fs.readFileSync(this.stateFile, 'utf-8');
|
|
39
41
|
const state = JSON.parse(content);
|
|
40
|
-
|
|
42
|
+
// Backwards compatibility: Support old format
|
|
43
|
+
if (state.id && !state.ids) {
|
|
44
|
+
return [state.id];
|
|
45
|
+
}
|
|
46
|
+
return state.ids || [];
|
|
41
47
|
}
|
|
42
48
|
catch (error) {
|
|
43
|
-
// File read/parse error = no active
|
|
44
|
-
return
|
|
49
|
+
// File read/parse error = no active increments
|
|
50
|
+
return [];
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
53
|
/**
|
|
48
|
-
*
|
|
54
|
+
* Get the primary active increment (first in list)
|
|
55
|
+
* Returns null if no increments are active
|
|
56
|
+
*
|
|
57
|
+
* This maintains backwards compatibility with code expecting a single ID
|
|
58
|
+
*/
|
|
59
|
+
getPrimary() {
|
|
60
|
+
const active = this.getActive();
|
|
61
|
+
return active.length > 0 ? active[0] : null;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Add an increment to the active list
|
|
49
65
|
* Validates that the increment exists and is actually active
|
|
66
|
+
*
|
|
67
|
+
* **NEW**: Adds to list instead of replacing (max 2)
|
|
68
|
+
* @param skipValidation - Skip validation (used during lazy initialization to prevent circular dependency)
|
|
50
69
|
*/
|
|
51
|
-
|
|
52
|
-
// Validate increment exists
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
70
|
+
addActive(incrementId, skipValidation = false) {
|
|
71
|
+
// Validate increment exists and is active (unless skipValidation is true)
|
|
72
|
+
if (!skipValidation) {
|
|
73
|
+
const metadata = MetadataManager.read(incrementId);
|
|
74
|
+
// Validate increment is actually active
|
|
75
|
+
if (metadata.status !== IncrementStatus.ACTIVE) {
|
|
76
|
+
throw new Error(`Cannot add ${incrementId} as active: status is ${metadata.status}, not active`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Get current active list
|
|
80
|
+
const currentActive = this.getActive();
|
|
81
|
+
// Don't add if already in list
|
|
82
|
+
if (currentActive.includes(incrementId)) {
|
|
83
|
+
return;
|
|
57
84
|
}
|
|
58
|
-
//
|
|
59
|
-
const
|
|
85
|
+
// Add to list (max 2)
|
|
86
|
+
const newActive = [...currentActive, incrementId].slice(0, 2);
|
|
87
|
+
// Write state
|
|
88
|
+
const state = {
|
|
89
|
+
ids: newActive,
|
|
90
|
+
lastUpdated: new Date().toISOString()
|
|
91
|
+
};
|
|
60
92
|
this.writeState(state);
|
|
61
93
|
}
|
|
62
94
|
/**
|
|
63
|
-
*
|
|
95
|
+
* Remove an increment from the active list
|
|
96
|
+
*/
|
|
97
|
+
removeActive(incrementId) {
|
|
98
|
+
const currentActive = this.getActive();
|
|
99
|
+
const newActive = currentActive.filter(id => id !== incrementId);
|
|
100
|
+
const state = {
|
|
101
|
+
ids: newActive,
|
|
102
|
+
lastUpdated: new Date().toISOString()
|
|
103
|
+
};
|
|
104
|
+
this.writeState(state);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Set the active increment (legacy method for backwards compatibility)
|
|
108
|
+
* Now delegates to addActive()
|
|
109
|
+
* @param skipValidation - Skip validation (used during lazy initialization to prevent circular dependency)
|
|
110
|
+
*/
|
|
111
|
+
setActive(incrementId, skipValidation = false) {
|
|
112
|
+
this.addActive(incrementId, skipValidation);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Clear all active increments
|
|
64
116
|
*/
|
|
65
117
|
clearActive() {
|
|
66
|
-
const state = {
|
|
118
|
+
const state = {
|
|
119
|
+
ids: [],
|
|
120
|
+
lastUpdated: new Date().toISOString()
|
|
121
|
+
};
|
|
67
122
|
this.writeState(state);
|
|
68
123
|
}
|
|
69
124
|
/**
|
|
70
|
-
* Smart update:
|
|
71
|
-
* or clear if none are active.
|
|
125
|
+
* Smart update: Rebuild active list from metadata
|
|
72
126
|
*
|
|
73
127
|
* This is called when:
|
|
74
128
|
* - An increment is completed
|
|
@@ -76,16 +130,26 @@ export class ActiveIncrementManager {
|
|
|
76
130
|
* - An increment is abandoned
|
|
77
131
|
*
|
|
78
132
|
* Logic:
|
|
79
|
-
* 1.
|
|
80
|
-
* 2.
|
|
81
|
-
* 3.
|
|
133
|
+
* 1. Scan all increments for status=active
|
|
134
|
+
* 2. Update cache to match reality
|
|
135
|
+
* 3. Max 2 increments (sorted by lastActivity)
|
|
82
136
|
*/
|
|
83
137
|
smartUpdate() {
|
|
84
138
|
const activeIncrements = MetadataManager.getActive();
|
|
85
139
|
if (activeIncrements.length > 0) {
|
|
86
|
-
//
|
|
87
|
-
|
|
88
|
-
|
|
140
|
+
// Sort by lastActivity (most recent first)
|
|
141
|
+
const sorted = activeIncrements.sort((a, b) => {
|
|
142
|
+
const aTime = new Date(a.lastActivity).getTime();
|
|
143
|
+
const bTime = new Date(b.lastActivity).getTime();
|
|
144
|
+
return bTime - aTime; // Descending
|
|
145
|
+
});
|
|
146
|
+
// Take max 2
|
|
147
|
+
const activeIds = sorted.slice(0, 2).map(m => m.id);
|
|
148
|
+
const state = {
|
|
149
|
+
ids: activeIds,
|
|
150
|
+
lastUpdated: new Date().toISOString()
|
|
151
|
+
};
|
|
152
|
+
this.writeState(state);
|
|
89
153
|
}
|
|
90
154
|
else {
|
|
91
155
|
// No active increments
|
|
@@ -93,35 +157,38 @@ export class ActiveIncrementManager {
|
|
|
93
157
|
}
|
|
94
158
|
}
|
|
95
159
|
/**
|
|
96
|
-
* Validate that
|
|
97
|
-
*
|
|
160
|
+
* Validate that all active increment pointers are correct
|
|
161
|
+
* Does NOT fix stale pointers - caller should call smartUpdate() if needed
|
|
98
162
|
*
|
|
99
|
-
* Returns true if valid
|
|
163
|
+
* Returns true if all valid, false if any invalid
|
|
100
164
|
*/
|
|
101
165
|
validate() {
|
|
102
166
|
const currentActive = this.getActive();
|
|
103
|
-
// No active
|
|
104
|
-
if (currentActive ===
|
|
167
|
+
// No active increments = valid (nothing to validate)
|
|
168
|
+
if (currentActive.length === 0) {
|
|
105
169
|
return true;
|
|
106
170
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
171
|
+
let hasStale = false;
|
|
172
|
+
for (const incrementId of currentActive) {
|
|
173
|
+
try {
|
|
174
|
+
// Check if increment still exists
|
|
175
|
+
const metadata = MetadataManager.read(incrementId);
|
|
176
|
+
// Check if increment is actually active
|
|
177
|
+
if (metadata.status !== IncrementStatus.ACTIVE) {
|
|
178
|
+
// Stale pointer! Mark for fix
|
|
179
|
+
console.warn(`⚠️ Active increment pointer is stale: ${incrementId} is ${metadata.status}`);
|
|
180
|
+
hasStale = true;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
// Increment doesn't exist = stale pointer
|
|
185
|
+
console.warn(`⚠️ Active increment pointer is invalid: ${incrementId} not found`);
|
|
186
|
+
hasStale = true;
|
|
116
187
|
}
|
|
117
|
-
return true;
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
// Increment doesn't exist = stale pointer
|
|
121
|
-
console.warn(`⚠️ Active increment pointer is invalid: ${currentActive} not found`);
|
|
122
|
-
this.smartUpdate();
|
|
123
|
-
return false;
|
|
124
188
|
}
|
|
189
|
+
// Return false if stale found, but DON'T auto-fix (prevents circular dependency)
|
|
190
|
+
// Caller should call smartUpdate() if needed
|
|
191
|
+
return !hasStale;
|
|
125
192
|
}
|
|
126
193
|
/**
|
|
127
194
|
* Write state file atomically (temp file → rename)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"active-increment-manager.js","sourceRoot":"","sources":["../../../../src/core/increment/active-increment-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"active-increment-manager.js","sourceRoot":"","sources":["../../../../src/core/increment/active-increment-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolver - Merge content and resolve duplicate conflicts
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities to merge valuable content from losing versions to winning version,
|
|
5
|
+
* and delete losing versions with user confirmation.
|
|
6
|
+
*
|
|
7
|
+
* Part of increment 0033: Duplicate Increment Prevention System
|
|
8
|
+
*/
|
|
9
|
+
import type { Duplicate, IncrementLocation } from './duplicate-detector.js';
|
|
10
|
+
/**
|
|
11
|
+
* Options for conflict resolution
|
|
12
|
+
*/
|
|
13
|
+
export interface ResolveOptions {
|
|
14
|
+
dryRun?: boolean;
|
|
15
|
+
force?: boolean;
|
|
16
|
+
merge?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of conflict resolution
|
|
20
|
+
*/
|
|
21
|
+
export interface ResolutionResult {
|
|
22
|
+
winner: string;
|
|
23
|
+
merged: string[];
|
|
24
|
+
deleted: string[];
|
|
25
|
+
reportPath: string;
|
|
26
|
+
dryRun: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Resolve conflict by merging winner + losers
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveConflict(duplicate: Duplicate, options?: ResolveOptions): Promise<ResolutionResult>;
|
|
32
|
+
/**
|
|
33
|
+
* Merge content from losing versions into winner
|
|
34
|
+
*/
|
|
35
|
+
export declare function mergeContent(winner: IncrementLocation, losers: IncrementLocation[], options?: ResolveOptions): Promise<string[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve multiple duplicates in batch
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveAllDuplicates(duplicates: Duplicate[], options?: ResolveOptions): Promise<ResolutionResult[]>;
|
|
40
|
+
//# sourceMappingURL=conflict-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-resolver.d.ts","sourceRoot":"","sources":["../../../../src/core/increment/conflict-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5E;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAmC3B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,iBAAiB,EAAE,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,EAAE,CAAC,CAiEnB;AAgHD;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,SAAS,EAAE,EACvB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAa7B"}
|