specweave 0.18.0 → 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/locales/de/.gitkeep +0 -0
- package/dist/locales/de/cli.json +108 -0
- package/dist/locales/en/cli.json +287 -0
- package/dist/locales/en/errors.json +7 -0
- package/dist/locales/en/templates.json +6 -0
- package/dist/locales/es/.gitkeep +0 -0
- package/dist/locales/es/cli.json +41 -0
- package/dist/locales/fr/.gitkeep +0 -0
- package/dist/locales/fr/cli.json +108 -0
- package/dist/locales/ja/.gitkeep +0 -0
- package/dist/locales/ja/cli.json +108 -0
- package/dist/locales/ko/.gitkeep +0 -0
- package/dist/locales/ko/cli.json +108 -0
- package/dist/locales/pt/.gitkeep +0 -0
- package/dist/locales/pt/cli.json +108 -0
- package/dist/locales/ru/.gitkeep +0 -0
- package/dist/locales/ru/cli.json +269 -0
- package/dist/locales/zh/.gitkeep +0 -0
- package/dist/locales/zh/cli.json +108 -0
- 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-ado/lib/enhanced-ado-sync.d.ts +25 -0
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js +191 -0
- package/dist/plugins/specweave-ado/lib/enhanced-ado-sync.js.map +1 -0
- 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 +70 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.d.ts.map +1 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.js +258 -0
- package/dist/plugins/specweave-github/lib/epic-content-builder.js.map +1 -0
- 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.d.ts +2 -2
- package/dist/plugins/specweave-github/lib/github-epic-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-epic-sync.js +20 -5
- 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 +28 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +1 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +156 -0
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +1 -0
- 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/spec-parser.js +629 -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/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +107 -3
- package/dist/src/cli/commands/init.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 +32 -54
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +1 -1
- package/dist/src/core/sync/enhanced-content-builder.js +142 -138
- 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/sync/spec-content-sync.d.ts +88 -0
- package/dist/src/core/sync/spec-content-sync.d.ts.map +1 -0
- package/dist/src/core/sync/spec-content-sync.js +5 -0
- package/dist/src/core/sync/spec-content-sync.js.map +1 -0
- package/dist/src/core/sync/types.d.ts +52 -0
- package/dist/src/core/sync/types.d.ts.map +1 -0
- package/dist/src/core/sync/types.js +5 -0
- package/dist/src/core/sync/types.js.map +1 -0
- package/dist/src/core/types/config.d.ts +125 -0
- package/dist/src/core/types/config.d.ts.map +1 -1
- package/dist/src/core/types/config.js +25 -0
- package/dist/src/core/types/config.js.map +1 -1
- package/dist/src/core/types/increment-metadata.d.ts +10 -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/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +1 -1
- package/plugins/specweave/COMMANDS.md +13 -4
- package/plugins/specweave/agents/pm/AGENT.md +159 -12
- 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/commands/specweave.md +70 -405
- package/plugins/specweave/hooks/hooks.json +4 -0
- package/plugins/specweave/hooks/lib/sync-spec-content.sh +2 -2
- package/plugins/specweave/hooks/post-increment-planning.sh +26 -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-ado/lib/enhanced-ado-sync.js +170 -0
- 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 +42 -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 +265 -0
- package/plugins/specweave-github/lib/epic-content-builder.ts +376 -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.js +23 -24
- package/plugins/specweave-github/lib/github-epic-sync.ts +30 -5
- 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,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Optimizer for Status Sync
|
|
3
|
+
*
|
|
4
|
+
* Implements caching, batching, and optimization strategies to ensure
|
|
5
|
+
* status sync operations complete within performance targets:
|
|
6
|
+
* - Status sync: <2 seconds
|
|
7
|
+
* - Conflict detection: <1 second
|
|
8
|
+
* - Bulk sync (10 items): <5 seconds
|
|
9
|
+
*
|
|
10
|
+
* @module performance-optimizer
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Performance metrics
|
|
14
|
+
*/
|
|
15
|
+
export interface PerformanceMetrics {
|
|
16
|
+
operationType: 'status-sync' | 'conflict-detection' | 'bulk-sync';
|
|
17
|
+
duration: number;
|
|
18
|
+
itemCount: number;
|
|
19
|
+
cacheHits: number;
|
|
20
|
+
cacheMisses: number;
|
|
21
|
+
timestamp: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Performance Optimizer
|
|
25
|
+
*
|
|
26
|
+
* Provides caching and optimization for status sync operations.
|
|
27
|
+
*/
|
|
28
|
+
export declare class PerformanceOptimizer {
|
|
29
|
+
private cache;
|
|
30
|
+
private readonly DEFAULT_TTL_MS;
|
|
31
|
+
private metrics;
|
|
32
|
+
/**
|
|
33
|
+
* Get cached value if available and not expired
|
|
34
|
+
*
|
|
35
|
+
* @param key - Cache key
|
|
36
|
+
* @returns Cached value or null if not found/expired
|
|
37
|
+
*/
|
|
38
|
+
get<T>(key: string): T | null;
|
|
39
|
+
/**
|
|
40
|
+
* Set cache value with TTL
|
|
41
|
+
*
|
|
42
|
+
* @param key - Cache key
|
|
43
|
+
* @param value - Value to cache
|
|
44
|
+
* @param ttlMs - Time to live in milliseconds (default: 5 minutes)
|
|
45
|
+
*/
|
|
46
|
+
set<T>(key: string, value: T, ttlMs?: number): void;
|
|
47
|
+
/**
|
|
48
|
+
* Clear specific cache entry
|
|
49
|
+
*
|
|
50
|
+
* @param key - Cache key
|
|
51
|
+
*/
|
|
52
|
+
clear(key: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Clear all cache entries
|
|
55
|
+
*/
|
|
56
|
+
clearAll(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Clear expired cache entries
|
|
59
|
+
*/
|
|
60
|
+
clearExpired(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Get cache statistics
|
|
63
|
+
*/
|
|
64
|
+
getCacheStats(): {
|
|
65
|
+
size: number;
|
|
66
|
+
keys: string[];
|
|
67
|
+
hitRate: number;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Record performance metric
|
|
71
|
+
*
|
|
72
|
+
* @param metric - Performance metric
|
|
73
|
+
*/
|
|
74
|
+
recordMetric(metric: PerformanceMetrics): void;
|
|
75
|
+
/**
|
|
76
|
+
* Get performance metrics
|
|
77
|
+
*
|
|
78
|
+
* @param operationType - Filter by operation type
|
|
79
|
+
* @returns Performance metrics
|
|
80
|
+
*/
|
|
81
|
+
getMetrics(operationType?: PerformanceMetrics['operationType']): PerformanceMetrics[];
|
|
82
|
+
/**
|
|
83
|
+
* Get average duration for operation type
|
|
84
|
+
*
|
|
85
|
+
* @param operationType - Operation type
|
|
86
|
+
* @returns Average duration in milliseconds
|
|
87
|
+
*/
|
|
88
|
+
getAverageDuration(operationType: PerformanceMetrics['operationType']): number;
|
|
89
|
+
/**
|
|
90
|
+
* Check if performance targets are met
|
|
91
|
+
*
|
|
92
|
+
* Performance targets:
|
|
93
|
+
* - status-sync: <2000ms
|
|
94
|
+
* - conflict-detection: <1000ms
|
|
95
|
+
* - bulk-sync (10 items): <5000ms
|
|
96
|
+
*
|
|
97
|
+
* @returns Performance target status
|
|
98
|
+
*/
|
|
99
|
+
checkPerformanceTargets(): {
|
|
100
|
+
statusSync: {
|
|
101
|
+
target: number;
|
|
102
|
+
actual: number;
|
|
103
|
+
met: boolean;
|
|
104
|
+
};
|
|
105
|
+
conflictDetection: {
|
|
106
|
+
target: number;
|
|
107
|
+
actual: number;
|
|
108
|
+
met: boolean;
|
|
109
|
+
};
|
|
110
|
+
bulkSync: {
|
|
111
|
+
target: number;
|
|
112
|
+
actual: number;
|
|
113
|
+
met: boolean;
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Generate cache key for external status
|
|
118
|
+
*
|
|
119
|
+
* @param tool - External tool
|
|
120
|
+
* @param identifier - Issue/item identifier
|
|
121
|
+
* @returns Cache key
|
|
122
|
+
*/
|
|
123
|
+
static generateStatusCacheKey(tool: string, identifier: string): string;
|
|
124
|
+
/**
|
|
125
|
+
* Generate cache key for workflow
|
|
126
|
+
*
|
|
127
|
+
* @param tool - External tool
|
|
128
|
+
* @param project - Project identifier
|
|
129
|
+
* @returns Cache key
|
|
130
|
+
*/
|
|
131
|
+
static generateWorkflowCacheKey(tool: string, project: string): string;
|
|
132
|
+
/**
|
|
133
|
+
* Batch process with delay
|
|
134
|
+
*
|
|
135
|
+
* Processes items in batches with configurable delay between batches
|
|
136
|
+
* to avoid rate limiting and improve throughput.
|
|
137
|
+
*
|
|
138
|
+
* @param items - Items to process
|
|
139
|
+
* @param processor - Async function to process each item
|
|
140
|
+
* @param batchSize - Batch size (default: 5)
|
|
141
|
+
* @param delayMs - Delay between batches in milliseconds (default: 1000)
|
|
142
|
+
* @returns Array of results
|
|
143
|
+
*/
|
|
144
|
+
static batchProcess<T, R>(items: T[], processor: (item: T) => Promise<R>, batchSize?: number, delayMs?: number): Promise<R[]>;
|
|
145
|
+
/**
|
|
146
|
+
* Measure execution time of an async function
|
|
147
|
+
*
|
|
148
|
+
* @param operation - Async operation to measure
|
|
149
|
+
* @returns Tuple of [result, duration in ms]
|
|
150
|
+
*/
|
|
151
|
+
static measureTime<T>(operation: () => Promise<T>): Promise<[T, number]>;
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=performance-optimizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-optimizer.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/performance-optimizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,aAAa,GAAG,oBAAoB,GAAG,WAAW,CAAC;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAA2C;IACxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,OAAO,CAA4B;IAE3C;;;;;OAKG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI;IAgB7B;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAE,MAA4B,GAAG,IAAI;IAOxE;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIxB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,YAAY,IAAI,IAAI;IASpB;;OAEG;IACH,aAAa,IAAI;QACf,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,EAAE,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB;IAcD;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAS9C;;;;;OAKG;IACH,UAAU,CAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,GAAG,kBAAkB,EAAE;IAQrF;;;;;OAKG;IACH,kBAAkB,CAAC,aAAa,EAAE,kBAAkB,CAAC,eAAe,CAAC,GAAG,MAAM;IAW9E;;;;;;;;;OASG;IACH,uBAAuB,IAAI;QACzB,UAAU,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,OAAO,CAAA;SAAE,CAAC;QAC7D,iBAAiB,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,OAAO,CAAA;SAAE,CAAC;QACpE,QAAQ,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,OAAO,CAAA;SAAE,CAAC;KAC5D;IAwBD;;;;;;OAMG;IACH,MAAM,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM;IAIvE;;;;;;OAMG;IACH,MAAM,CAAC,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM;IAItE;;;;;;;;;;;OAWG;WACU,YAAY,CAAC,CAAC,EAAE,CAAC,EAC5B,KAAK,EAAE,CAAC,EAAE,EACV,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EAClC,SAAS,GAAE,MAAU,EACrB,OAAO,GAAE,MAAa,GACrB,OAAO,CAAC,CAAC,EAAE,CAAC;IAsBf;;;;;OAKG;WACU,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;CAO/E"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance Optimizer for Status Sync
|
|
3
|
+
*
|
|
4
|
+
* Implements caching, batching, and optimization strategies to ensure
|
|
5
|
+
* status sync operations complete within performance targets:
|
|
6
|
+
* - Status sync: <2 seconds
|
|
7
|
+
* - Conflict detection: <1 second
|
|
8
|
+
* - Bulk sync (10 items): <5 seconds
|
|
9
|
+
*
|
|
10
|
+
* @module performance-optimizer
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Performance Optimizer
|
|
14
|
+
*
|
|
15
|
+
* Provides caching and optimization for status sync operations.
|
|
16
|
+
*/
|
|
17
|
+
export class PerformanceOptimizer {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.cache = new Map();
|
|
20
|
+
this.DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
21
|
+
this.metrics = [];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get cached value if available and not expired
|
|
25
|
+
*
|
|
26
|
+
* @param key - Cache key
|
|
27
|
+
* @returns Cached value or null if not found/expired
|
|
28
|
+
*/
|
|
29
|
+
get(key) {
|
|
30
|
+
const entry = this.cache.get(key);
|
|
31
|
+
if (!entry) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
// Check expiration
|
|
35
|
+
if (Date.now() > entry.expiresAt) {
|
|
36
|
+
this.cache.delete(key);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return entry.value;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Set cache value with TTL
|
|
43
|
+
*
|
|
44
|
+
* @param key - Cache key
|
|
45
|
+
* @param value - Value to cache
|
|
46
|
+
* @param ttlMs - Time to live in milliseconds (default: 5 minutes)
|
|
47
|
+
*/
|
|
48
|
+
set(key, value, ttlMs = this.DEFAULT_TTL_MS) {
|
|
49
|
+
this.cache.set(key, {
|
|
50
|
+
value,
|
|
51
|
+
expiresAt: Date.now() + ttlMs
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Clear specific cache entry
|
|
56
|
+
*
|
|
57
|
+
* @param key - Cache key
|
|
58
|
+
*/
|
|
59
|
+
clear(key) {
|
|
60
|
+
this.cache.delete(key);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Clear all cache entries
|
|
64
|
+
*/
|
|
65
|
+
clearAll() {
|
|
66
|
+
this.cache.clear();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Clear expired cache entries
|
|
70
|
+
*/
|
|
71
|
+
clearExpired() {
|
|
72
|
+
const now = Date.now();
|
|
73
|
+
for (const [key, entry] of this.cache.entries()) {
|
|
74
|
+
if (now > entry.expiresAt) {
|
|
75
|
+
this.cache.delete(key);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get cache statistics
|
|
81
|
+
*/
|
|
82
|
+
getCacheStats() {
|
|
83
|
+
const totalRequests = this.metrics.reduce((sum, m) => sum + m.cacheHits + m.cacheMisses, 0);
|
|
84
|
+
const totalHits = this.metrics.reduce((sum, m) => sum + m.cacheHits, 0);
|
|
85
|
+
return {
|
|
86
|
+
size: this.cache.size,
|
|
87
|
+
keys: Array.from(this.cache.keys()),
|
|
88
|
+
hitRate: totalRequests > 0 ? totalHits / totalRequests : 0
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Record performance metric
|
|
93
|
+
*
|
|
94
|
+
* @param metric - Performance metric
|
|
95
|
+
*/
|
|
96
|
+
recordMetric(metric) {
|
|
97
|
+
this.metrics.push(metric);
|
|
98
|
+
// Keep only last 100 metrics
|
|
99
|
+
if (this.metrics.length > 100) {
|
|
100
|
+
this.metrics.shift();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get performance metrics
|
|
105
|
+
*
|
|
106
|
+
* @param operationType - Filter by operation type
|
|
107
|
+
* @returns Performance metrics
|
|
108
|
+
*/
|
|
109
|
+
getMetrics(operationType) {
|
|
110
|
+
if (!operationType) {
|
|
111
|
+
return [...this.metrics];
|
|
112
|
+
}
|
|
113
|
+
return this.metrics.filter(m => m.operationType === operationType);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get average duration for operation type
|
|
117
|
+
*
|
|
118
|
+
* @param operationType - Operation type
|
|
119
|
+
* @returns Average duration in milliseconds
|
|
120
|
+
*/
|
|
121
|
+
getAverageDuration(operationType) {
|
|
122
|
+
const metrics = this.getMetrics(operationType);
|
|
123
|
+
if (metrics.length === 0) {
|
|
124
|
+
return 0;
|
|
125
|
+
}
|
|
126
|
+
const sum = metrics.reduce((total, m) => total + m.duration, 0);
|
|
127
|
+
return sum / metrics.length;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Check if performance targets are met
|
|
131
|
+
*
|
|
132
|
+
* Performance targets:
|
|
133
|
+
* - status-sync: <2000ms
|
|
134
|
+
* - conflict-detection: <1000ms
|
|
135
|
+
* - bulk-sync (10 items): <5000ms
|
|
136
|
+
*
|
|
137
|
+
* @returns Performance target status
|
|
138
|
+
*/
|
|
139
|
+
checkPerformanceTargets() {
|
|
140
|
+
const statusSyncAvg = this.getAverageDuration('status-sync');
|
|
141
|
+
const conflictAvg = this.getAverageDuration('conflict-detection');
|
|
142
|
+
const bulkSyncAvg = this.getAverageDuration('bulk-sync');
|
|
143
|
+
return {
|
|
144
|
+
statusSync: {
|
|
145
|
+
target: 2000,
|
|
146
|
+
actual: statusSyncAvg,
|
|
147
|
+
met: statusSyncAvg < 2000 || statusSyncAvg === 0
|
|
148
|
+
},
|
|
149
|
+
conflictDetection: {
|
|
150
|
+
target: 1000,
|
|
151
|
+
actual: conflictAvg,
|
|
152
|
+
met: conflictAvg < 1000 || conflictAvg === 0
|
|
153
|
+
},
|
|
154
|
+
bulkSync: {
|
|
155
|
+
target: 5000,
|
|
156
|
+
actual: bulkSyncAvg,
|
|
157
|
+
met: bulkSyncAvg < 5000 || bulkSyncAvg === 0
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Generate cache key for external status
|
|
163
|
+
*
|
|
164
|
+
* @param tool - External tool
|
|
165
|
+
* @param identifier - Issue/item identifier
|
|
166
|
+
* @returns Cache key
|
|
167
|
+
*/
|
|
168
|
+
static generateStatusCacheKey(tool, identifier) {
|
|
169
|
+
return `status:${tool}:${identifier}`;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Generate cache key for workflow
|
|
173
|
+
*
|
|
174
|
+
* @param tool - External tool
|
|
175
|
+
* @param project - Project identifier
|
|
176
|
+
* @returns Cache key
|
|
177
|
+
*/
|
|
178
|
+
static generateWorkflowCacheKey(tool, project) {
|
|
179
|
+
return `workflow:${tool}:${project}`;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Batch process with delay
|
|
183
|
+
*
|
|
184
|
+
* Processes items in batches with configurable delay between batches
|
|
185
|
+
* to avoid rate limiting and improve throughput.
|
|
186
|
+
*
|
|
187
|
+
* @param items - Items to process
|
|
188
|
+
* @param processor - Async function to process each item
|
|
189
|
+
* @param batchSize - Batch size (default: 5)
|
|
190
|
+
* @param delayMs - Delay between batches in milliseconds (default: 1000)
|
|
191
|
+
* @returns Array of results
|
|
192
|
+
*/
|
|
193
|
+
static async batchProcess(items, processor, batchSize = 5, delayMs = 1000) {
|
|
194
|
+
const results = [];
|
|
195
|
+
for (let i = 0; i < items.length; i += batchSize) {
|
|
196
|
+
const batch = items.slice(i, i + batchSize);
|
|
197
|
+
// Process batch in parallel
|
|
198
|
+
const batchResults = await Promise.all(batch.map(item => processor(item)));
|
|
199
|
+
results.push(...batchResults);
|
|
200
|
+
// Add delay between batches (except for last batch)
|
|
201
|
+
if (i + batchSize < items.length) {
|
|
202
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return results;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Measure execution time of an async function
|
|
209
|
+
*
|
|
210
|
+
* @param operation - Async operation to measure
|
|
211
|
+
* @returns Tuple of [result, duration in ms]
|
|
212
|
+
*/
|
|
213
|
+
static async measureTime(operation) {
|
|
214
|
+
const startTime = Date.now();
|
|
215
|
+
const result = await operation();
|
|
216
|
+
const duration = Date.now() - startTime;
|
|
217
|
+
return [result, duration];
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
//# sourceMappingURL=performance-optimizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"performance-optimizer.js","sourceRoot":"","sources":["../../../../src/core/sync/performance-optimizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Handler for Status Sync
|
|
3
|
+
*
|
|
4
|
+
* Implements exponential backoff retry logic for handling transient failures
|
|
5
|
+
* in external API calls (GitHub, JIRA, Azure DevOps).
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Exponential backoff (1s, 2s, 4s, 8s)
|
|
9
|
+
* - Maximum retry attempts (default: 3)
|
|
10
|
+
* - Rate limit detection and handling
|
|
11
|
+
* - Clear error messages
|
|
12
|
+
*
|
|
13
|
+
* @module retry-handler
|
|
14
|
+
*/
|
|
15
|
+
export type RetryableError = 'network-error' | 'rate-limit' | 'server-error' | 'timeout' | 'unknown';
|
|
16
|
+
export interface RetryConfig {
|
|
17
|
+
maxRetries?: number;
|
|
18
|
+
initialDelayMs?: number;
|
|
19
|
+
maxDelayMs?: number;
|
|
20
|
+
backoffMultiplier?: number;
|
|
21
|
+
}
|
|
22
|
+
export interface RetryContext {
|
|
23
|
+
attempt: number;
|
|
24
|
+
maxRetries: number;
|
|
25
|
+
lastError: Error;
|
|
26
|
+
errorType: RetryableError;
|
|
27
|
+
}
|
|
28
|
+
export interface RetryResult<T> {
|
|
29
|
+
success: boolean;
|
|
30
|
+
value?: T;
|
|
31
|
+
error?: Error;
|
|
32
|
+
attempts: number;
|
|
33
|
+
totalDelay: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Retry Handler
|
|
37
|
+
*
|
|
38
|
+
* Handles retries with exponential backoff for external API calls.
|
|
39
|
+
*/
|
|
40
|
+
export declare class RetryHandler {
|
|
41
|
+
private config;
|
|
42
|
+
constructor(config?: RetryConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Execute operation with retry logic
|
|
45
|
+
*
|
|
46
|
+
* @param operation - Async operation to execute
|
|
47
|
+
* @param errorClassifier - Function to classify errors (determines if retryable)
|
|
48
|
+
* @returns Retry result with value or error
|
|
49
|
+
*/
|
|
50
|
+
executeWithRetry<T>(operation: () => Promise<T>, errorClassifier?: (error: Error) => RetryableError): Promise<RetryResult<T>>;
|
|
51
|
+
/**
|
|
52
|
+
* Classify error type
|
|
53
|
+
*
|
|
54
|
+
* @param error - Error to classify
|
|
55
|
+
* @returns Error type
|
|
56
|
+
*/
|
|
57
|
+
private classifyError;
|
|
58
|
+
/**
|
|
59
|
+
* Check if error type is retryable
|
|
60
|
+
*
|
|
61
|
+
* @param errorType - Error type
|
|
62
|
+
* @returns True if retryable
|
|
63
|
+
*/
|
|
64
|
+
private isRetryable;
|
|
65
|
+
/**
|
|
66
|
+
* Calculate delay for retry attempt
|
|
67
|
+
*
|
|
68
|
+
* Uses exponential backoff: initialDelay * (multiplier ^ (attempt - 1))
|
|
69
|
+
*
|
|
70
|
+
* @param attempt - Current attempt number (1-based)
|
|
71
|
+
* @returns Delay in milliseconds
|
|
72
|
+
*/
|
|
73
|
+
private calculateDelay;
|
|
74
|
+
/**
|
|
75
|
+
* Delay execution
|
|
76
|
+
*
|
|
77
|
+
* @param ms - Milliseconds to delay
|
|
78
|
+
*/
|
|
79
|
+
private delay;
|
|
80
|
+
/**
|
|
81
|
+
* Create clear error message for user
|
|
82
|
+
*
|
|
83
|
+
* @param error - Original error
|
|
84
|
+
* @param context - Retry context
|
|
85
|
+
* @returns User-friendly error message
|
|
86
|
+
*/
|
|
87
|
+
static createErrorMessage(error: Error, context: RetryContext): string;
|
|
88
|
+
/**
|
|
89
|
+
* Handle rate limit error
|
|
90
|
+
*
|
|
91
|
+
* Detects rate limit from error and calculates wait time.
|
|
92
|
+
*
|
|
93
|
+
* @param error - Error that may contain rate limit info
|
|
94
|
+
* @returns Wait time in seconds (null if not rate limit)
|
|
95
|
+
*/
|
|
96
|
+
static detectRateLimitWait(error: Error): number | null;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=retry-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-handler.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/retry-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,YAAY,GACZ,cAAc,GACd,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,KAAK,CAAC;IACjB,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,GAAE,WAAgB;IASpC;;;;;;OAMG;IACG,gBAAgB,CAAC,CAAC,EACtB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,cAAc,GACjD,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAoD1B;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IA0CrB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAInB;;;;;;;OAOG;IACH,OAAO,CAAC,cAAc;IAStB;;;;OAIG;IACH,OAAO,CAAC,KAAK;IAIb;;;;;;OAMG;IACH,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,GAAG,MAAM;IAkBtE;;;;;;;OAOG;IACH,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI;CAsBxD"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retry Handler for Status Sync
|
|
3
|
+
*
|
|
4
|
+
* Implements exponential backoff retry logic for handling transient failures
|
|
5
|
+
* in external API calls (GitHub, JIRA, Azure DevOps).
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Exponential backoff (1s, 2s, 4s, 8s)
|
|
9
|
+
* - Maximum retry attempts (default: 3)
|
|
10
|
+
* - Rate limit detection and handling
|
|
11
|
+
* - Clear error messages
|
|
12
|
+
*
|
|
13
|
+
* @module retry-handler
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Retry Handler
|
|
17
|
+
*
|
|
18
|
+
* Handles retries with exponential backoff for external API calls.
|
|
19
|
+
*/
|
|
20
|
+
export class RetryHandler {
|
|
21
|
+
constructor(config = {}) {
|
|
22
|
+
this.config = {
|
|
23
|
+
maxRetries: config.maxRetries ?? 3,
|
|
24
|
+
initialDelayMs: config.initialDelayMs ?? 1000,
|
|
25
|
+
maxDelayMs: config.maxDelayMs ?? 8000,
|
|
26
|
+
backoffMultiplier: config.backoffMultiplier ?? 2
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Execute operation with retry logic
|
|
31
|
+
*
|
|
32
|
+
* @param operation - Async operation to execute
|
|
33
|
+
* @param errorClassifier - Function to classify errors (determines if retryable)
|
|
34
|
+
* @returns Retry result with value or error
|
|
35
|
+
*/
|
|
36
|
+
async executeWithRetry(operation, errorClassifier) {
|
|
37
|
+
let attempt = 0;
|
|
38
|
+
let totalDelay = 0;
|
|
39
|
+
let lastError;
|
|
40
|
+
while (attempt <= this.config.maxRetries) {
|
|
41
|
+
try {
|
|
42
|
+
const value = await operation();
|
|
43
|
+
return {
|
|
44
|
+
success: true,
|
|
45
|
+
value,
|
|
46
|
+
attempts: attempt + 1,
|
|
47
|
+
totalDelay
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
lastError = error;
|
|
52
|
+
attempt++;
|
|
53
|
+
// Classify error
|
|
54
|
+
const errorType = errorClassifier
|
|
55
|
+
? errorClassifier(lastError)
|
|
56
|
+
: this.classifyError(lastError);
|
|
57
|
+
// Check if we should retry
|
|
58
|
+
if (!this.isRetryable(errorType) || attempt > this.config.maxRetries) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
error: lastError,
|
|
62
|
+
attempts: attempt,
|
|
63
|
+
totalDelay
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
// Calculate delay for next retry
|
|
67
|
+
const delay = this.calculateDelay(attempt);
|
|
68
|
+
totalDelay += delay;
|
|
69
|
+
// Wait before retrying
|
|
70
|
+
await this.delay(delay);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Should not reach here, but TypeScript needs this
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: lastError ?? new Error('Unknown error'),
|
|
77
|
+
attempts: attempt,
|
|
78
|
+
totalDelay
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Classify error type
|
|
83
|
+
*
|
|
84
|
+
* @param error - Error to classify
|
|
85
|
+
* @returns Error type
|
|
86
|
+
*/
|
|
87
|
+
classifyError(error) {
|
|
88
|
+
const message = error.message.toLowerCase();
|
|
89
|
+
// Network errors (retry)
|
|
90
|
+
if (message.includes('network') ||
|
|
91
|
+
message.includes('econnrefused') ||
|
|
92
|
+
message.includes('enotfound') ||
|
|
93
|
+
message.includes('etimedout')) {
|
|
94
|
+
return 'network-error';
|
|
95
|
+
}
|
|
96
|
+
// Rate limit errors (retry with longer delay)
|
|
97
|
+
if (message.includes('rate limit') ||
|
|
98
|
+
message.includes('429') ||
|
|
99
|
+
message.includes('too many requests')) {
|
|
100
|
+
return 'rate-limit';
|
|
101
|
+
}
|
|
102
|
+
// Server errors (retry)
|
|
103
|
+
if (message.includes('500') ||
|
|
104
|
+
message.includes('502') ||
|
|
105
|
+
message.includes('503') ||
|
|
106
|
+
message.includes('504') ||
|
|
107
|
+
message.includes('internal server error')) {
|
|
108
|
+
return 'server-error';
|
|
109
|
+
}
|
|
110
|
+
// Timeout errors (retry)
|
|
111
|
+
if (message.includes('timeout')) {
|
|
112
|
+
return 'timeout';
|
|
113
|
+
}
|
|
114
|
+
// Unknown errors (don't retry by default)
|
|
115
|
+
return 'unknown';
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if error type is retryable
|
|
119
|
+
*
|
|
120
|
+
* @param errorType - Error type
|
|
121
|
+
* @returns True if retryable
|
|
122
|
+
*/
|
|
123
|
+
isRetryable(errorType) {
|
|
124
|
+
return errorType !== 'unknown';
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Calculate delay for retry attempt
|
|
128
|
+
*
|
|
129
|
+
* Uses exponential backoff: initialDelay * (multiplier ^ (attempt - 1))
|
|
130
|
+
*
|
|
131
|
+
* @param attempt - Current attempt number (1-based)
|
|
132
|
+
* @returns Delay in milliseconds
|
|
133
|
+
*/
|
|
134
|
+
calculateDelay(attempt) {
|
|
135
|
+
const delay = this.config.initialDelayMs *
|
|
136
|
+
Math.pow(this.config.backoffMultiplier, attempt - 1);
|
|
137
|
+
// Cap at max delay
|
|
138
|
+
return Math.min(delay, this.config.maxDelayMs);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Delay execution
|
|
142
|
+
*
|
|
143
|
+
* @param ms - Milliseconds to delay
|
|
144
|
+
*/
|
|
145
|
+
delay(ms) {
|
|
146
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Create clear error message for user
|
|
150
|
+
*
|
|
151
|
+
* @param error - Original error
|
|
152
|
+
* @param context - Retry context
|
|
153
|
+
* @returns User-friendly error message
|
|
154
|
+
*/
|
|
155
|
+
static createErrorMessage(error, context) {
|
|
156
|
+
const messages = {
|
|
157
|
+
'network-error': `Network error occurred. Please check your internet connection and try again.`,
|
|
158
|
+
'rate-limit': `Rate limit exceeded for external API. Please wait a few minutes and try again.`,
|
|
159
|
+
'server-error': `External service is experiencing issues. Please try again later.`,
|
|
160
|
+
'timeout': `Request timed out. Please check your connection and try again.`,
|
|
161
|
+
'unknown': `An unexpected error occurred: ${error.message}`
|
|
162
|
+
};
|
|
163
|
+
const baseMessage = messages[context.errorType];
|
|
164
|
+
if (context.attempt >= context.maxRetries) {
|
|
165
|
+
return `${baseMessage}\n\nFailed after ${context.attempt} attempts.`;
|
|
166
|
+
}
|
|
167
|
+
return baseMessage;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Handle rate limit error
|
|
171
|
+
*
|
|
172
|
+
* Detects rate limit from error and calculates wait time.
|
|
173
|
+
*
|
|
174
|
+
* @param error - Error that may contain rate limit info
|
|
175
|
+
* @returns Wait time in seconds (null if not rate limit)
|
|
176
|
+
*/
|
|
177
|
+
static detectRateLimitWait(error) {
|
|
178
|
+
const message = error.message;
|
|
179
|
+
// GitHub rate limit format: "API rate limit exceeded. Retry after 60 seconds"
|
|
180
|
+
const githubMatch = message.match(/retry after (\d+) seconds/i);
|
|
181
|
+
if (githubMatch) {
|
|
182
|
+
return parseInt(githubMatch[1], 10);
|
|
183
|
+
}
|
|
184
|
+
// JIRA rate limit (typically in headers, but may be in error message)
|
|
185
|
+
const jiraMatch = message.match(/retry after (\d+)/i);
|
|
186
|
+
if (jiraMatch) {
|
|
187
|
+
return parseInt(jiraMatch[1], 10);
|
|
188
|
+
}
|
|
189
|
+
// Generic 429 error - default to 60 seconds
|
|
190
|
+
if (message.includes('429') || message.toLowerCase().includes('rate limit')) {
|
|
191
|
+
return 60;
|
|
192
|
+
}
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=retry-handler.js.map
|