specweave 0.28.68 → 0.29.1
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 +3 -2
- package/README.md +19 -2
- package/dist/src/cli/commands/discrepancies.d.ts +89 -0
- package/dist/src/cli/commands/discrepancies.d.ts.map +1 -0
- package/dist/src/cli/commands/discrepancies.js +385 -0
- package/dist/src/cli/commands/discrepancies.js.map +1 -0
- package/dist/src/cli/commands/notifications.d.ts +70 -0
- package/dist/src/cli/commands/notifications.d.ts.map +1 -0
- package/dist/src/cli/commands/notifications.js +236 -0
- package/dist/src/cli/commands/notifications.js.map +1 -0
- package/dist/src/cli/commands/sync-logs.d.ts +54 -0
- package/dist/src/cli/commands/sync-logs.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-logs.js +240 -0
- package/dist/src/cli/commands/sync-logs.js.map +1 -0
- package/dist/src/cli/commands/sync-monitor.d.ts +42 -0
- package/dist/src/cli/commands/sync-monitor.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-monitor.js +191 -0
- package/dist/src/cli/commands/sync-monitor.js.map +1 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.d.ts +45 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.js +431 -0
- package/dist/src/cli/helpers/init/brownfield-analysis.js.map +1 -0
- package/dist/src/cli/helpers/init/index.d.ts +1 -0
- package/dist/src/cli/helpers/init/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/index.js +2 -0
- package/dist/src/cli/helpers/init/index.js.map +1 -1
- package/dist/src/cli/workers/brownfield-worker.d.ts +66 -0
- package/dist/src/cli/workers/brownfield-worker.d.ts.map +1 -0
- package/dist/src/cli/workers/brownfield-worker.js +417 -0
- package/dist/src/cli/workers/brownfield-worker.js.map +1 -0
- package/dist/src/core/background/brownfield-launcher.d.ts +86 -0
- package/dist/src/core/background/brownfield-launcher.d.ts.map +1 -0
- package/dist/src/core/background/brownfield-launcher.js +295 -0
- package/dist/src/core/background/brownfield-launcher.js.map +1 -0
- package/dist/src/core/background/index.d.ts +2 -0
- package/dist/src/core/background/index.d.ts.map +1 -1
- package/dist/src/core/background/index.js +2 -0
- package/dist/src/core/background/index.js.map +1 -1
- package/dist/src/core/background/types.d.ts +23 -2
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/config/index.d.ts +1 -0
- package/dist/src/core/config/index.d.ts.map +1 -1
- package/dist/src/core/config/index.js +1 -0
- package/dist/src/core/config/index.js.map +1 -1
- package/dist/src/core/config/types.d.ts +6 -0
- package/dist/src/core/config/types.d.ts.map +1 -1
- package/dist/src/core/config/types.js.map +1 -1
- package/dist/src/core/dashboard/dashboard-data.d.ts +156 -0
- package/dist/src/core/dashboard/dashboard-data.d.ts.map +1 -0
- package/dist/src/core/dashboard/dashboard-data.js +191 -0
- package/dist/src/core/dashboard/dashboard-data.js.map +1 -0
- package/dist/src/core/dashboard/index.d.ts +9 -0
- package/dist/src/core/dashboard/index.d.ts.map +1 -0
- package/dist/src/core/dashboard/index.js +9 -0
- package/dist/src/core/dashboard/index.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts +77 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js +286 -0
- package/dist/src/core/discrepancy/analyzers/api-route-analyzer.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/index.d.ts +8 -0
- package/dist/src/core/discrepancy/analyzers/index.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/index.js +8 -0
- package/dist/src/core/discrepancy/analyzers/index.js.map +1 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts +96 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.d.ts.map +1 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js +247 -0
- package/dist/src/core/discrepancy/analyzers/typescript-analyzer.js.map +1 -0
- package/dist/src/core/discrepancy/brownfield-manager.d.ts +88 -0
- package/dist/src/core/discrepancy/brownfield-manager.d.ts.map +1 -0
- package/dist/src/core/discrepancy/brownfield-manager.js +520 -0
- package/dist/src/core/discrepancy/brownfield-manager.js.map +1 -0
- package/dist/src/core/discrepancy/brownfield-types.d.ts +174 -0
- package/dist/src/core/discrepancy/brownfield-types.d.ts.map +1 -0
- package/dist/src/core/discrepancy/brownfield-types.js +11 -0
- package/dist/src/core/discrepancy/brownfield-types.js.map +1 -0
- package/dist/src/core/discrepancy/detector.d.ts +92 -0
- package/dist/src/core/discrepancy/detector.d.ts.map +1 -0
- package/dist/src/core/discrepancy/detector.js +346 -0
- package/dist/src/core/discrepancy/detector.js.map +1 -0
- package/dist/src/core/discrepancy/increment-generator.d.ts +51 -0
- package/dist/src/core/discrepancy/increment-generator.d.ts.map +1 -0
- package/dist/src/core/discrepancy/increment-generator.js +234 -0
- package/dist/src/core/discrepancy/increment-generator.js.map +1 -0
- package/dist/src/core/discrepancy/index.d.ts +18 -0
- package/dist/src/core/discrepancy/index.d.ts.map +1 -0
- package/dist/src/core/discrepancy/index.js +24 -0
- package/dist/src/core/discrepancy/index.js.map +1 -0
- package/dist/src/core/discrepancy/severity-classifier.d.ts +81 -0
- package/dist/src/core/discrepancy/severity-classifier.d.ts.map +1 -0
- package/dist/src/core/discrepancy/severity-classifier.js +289 -0
- package/dist/src/core/discrepancy/severity-classifier.js.map +1 -0
- package/dist/src/core/discrepancy/spec-parser.d.ts +74 -0
- package/dist/src/core/discrepancy/spec-parser.d.ts.map +1 -0
- package/dist/src/core/discrepancy/spec-parser.js +213 -0
- package/dist/src/core/discrepancy/spec-parser.js.map +1 -0
- package/dist/src/core/discrepancy/update-recommender.d.ts +77 -0
- package/dist/src/core/discrepancy/update-recommender.d.ts.map +1 -0
- package/dist/src/core/discrepancy/update-recommender.js +323 -0
- package/dist/src/core/discrepancy/update-recommender.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts +13 -16
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +31 -112
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/logs/index.d.ts +10 -0
- package/dist/src/core/logs/index.d.ts.map +1 -0
- package/dist/src/core/logs/index.js +10 -0
- package/dist/src/core/logs/index.js.map +1 -0
- package/dist/src/core/logs/log-aggregator.d.ts +130 -0
- package/dist/src/core/logs/log-aggregator.d.ts.map +1 -0
- package/dist/src/core/logs/log-aggregator.js +206 -0
- package/dist/src/core/logs/log-aggregator.js.map +1 -0
- package/dist/src/core/logs/log-exporter.d.ts +81 -0
- package/dist/src/core/logs/log-exporter.d.ts.map +1 -0
- package/dist/src/core/logs/log-exporter.js +141 -0
- package/dist/src/core/logs/log-exporter.js.map +1 -0
- package/dist/src/core/notifications/command-integration.d.ts +82 -0
- package/dist/src/core/notifications/command-integration.d.ts.map +1 -0
- package/dist/src/core/notifications/command-integration.js +80 -0
- package/dist/src/core/notifications/command-integration.js.map +1 -0
- package/dist/src/core/notifications/index.d.ts +12 -0
- package/dist/src/core/notifications/index.d.ts.map +1 -0
- package/dist/src/core/notifications/index.js +12 -0
- package/dist/src/core/notifications/index.js.map +1 -0
- package/dist/src/core/notifications/notification-display.d.ts +70 -0
- package/dist/src/core/notifications/notification-display.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-display.js +177 -0
- package/dist/src/core/notifications/notification-display.js.map +1 -0
- package/dist/src/core/notifications/notification-manager.d.ts +126 -0
- package/dist/src/core/notifications/notification-manager.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-manager.js +287 -0
- package/dist/src/core/notifications/notification-manager.js.map +1 -0
- package/dist/src/core/notifications/notification-types.d.ts +159 -0
- package/dist/src/core/notifications/notification-types.d.ts.map +1 -0
- package/dist/src/core/notifications/notification-types.js +93 -0
- package/dist/src/core/notifications/notification-types.js.map +1 -0
- package/dist/src/core/scheduler/index.d.ts +11 -0
- package/dist/src/core/scheduler/index.d.ts.map +1 -0
- package/dist/src/core/scheduler/index.js +11 -0
- package/dist/src/core/scheduler/index.js.map +1 -0
- package/dist/src/core/scheduler/job-scheduler.d.ts +179 -0
- package/dist/src/core/scheduler/job-scheduler.d.ts.map +1 -0
- package/dist/src/core/scheduler/job-scheduler.js +282 -0
- package/dist/src/core/scheduler/job-scheduler.js.map +1 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts +83 -0
- package/dist/src/core/scheduler/schedule-persistence.d.ts.map +1 -0
- package/dist/src/core/scheduler/schedule-persistence.js +180 -0
- package/dist/src/core/scheduler/schedule-persistence.js.map +1 -0
- package/dist/src/core/scheduler/scheduled-job.d.ts +188 -0
- package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -0
- package/dist/src/core/scheduler/scheduled-job.js +182 -0
- package/dist/src/core/scheduler/scheduled-job.js.map +1 -0
- package/dist/src/core/sync/permission-enforcer.d.ts +206 -0
- package/dist/src/core/sync/permission-enforcer.d.ts.map +1 -0
- package/dist/src/core/sync/permission-enforcer.js +268 -0
- package/dist/src/core/sync/permission-enforcer.js.map +1 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts +217 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -0
- package/dist/src/core/sync/sync-audit-logger.js +327 -0
- package/dist/src/core/sync/sync-audit-logger.js.map +1 -0
- package/dist/src/core/sync/sync-interceptor.d.ts +190 -0
- package/dist/src/core/sync/sync-interceptor.d.ts.map +1 -0
- package/dist/src/core/sync/sync-interceptor.js +224 -0
- package/dist/src/core/sync/sync-interceptor.js.map +1 -0
- package/dist/src/core/types/increment-metadata.d.ts +5 -2
- package/dist/src/core/types/increment-metadata.d.ts.map +1 -1
- package/dist/src/core/types/sync-config.d.ts +267 -0
- package/dist/src/core/types/sync-config.d.ts.map +1 -0
- package/dist/src/core/types/sync-config.js +304 -0
- package/dist/src/core/types/sync-config.js.map +1 -0
- package/dist/src/hooks/index.d.ts +11 -0
- package/dist/src/hooks/index.d.ts.map +1 -0
- package/dist/src/hooks/index.js +11 -0
- package/dist/src/hooks/index.js.map +1 -0
- package/dist/src/hooks/platform.d.ts +125 -0
- package/dist/src/hooks/platform.d.ts.map +1 -0
- package/dist/src/hooks/platform.js +325 -0
- package/dist/src/hooks/platform.js.map +1 -0
- package/dist/src/hooks/processor.d.ts +20 -0
- package/dist/src/hooks/processor.d.ts.map +1 -0
- package/dist/src/hooks/processor.js +317 -0
- package/dist/src/hooks/processor.js.map +1 -0
- package/dist/src/hooks/scheduler-startup.d.ts +19 -0
- package/dist/src/hooks/scheduler-startup.d.ts.map +1 -0
- package/dist/src/hooks/scheduler-startup.js +92 -0
- package/dist/src/hooks/scheduler-startup.js.map +1 -0
- package/dist/src/hooks/session-start.d.ts +16 -0
- package/dist/src/hooks/session-start.d.ts.map +1 -0
- package/dist/src/hooks/session-start.js +92 -0
- package/dist/src/hooks/session-start.js.map +1 -0
- package/dist/src/importers/duplicate-detector.d.ts +13 -2
- package/dist/src/importers/duplicate-detector.d.ts.map +1 -1
- package/dist/src/importers/duplicate-detector.js +21 -2
- package/dist/src/importers/duplicate-detector.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +41 -2
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +225 -38
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.d.ts +7 -0
- package/dist/src/living-docs/fs-id-allocator.d.ts.map +1 -1
- package/dist/src/living-docs/fs-id-allocator.js +30 -4
- package/dist/src/living-docs/fs-id-allocator.js.map +1 -1
- package/dist/src/sync/ado-sync-wrapper.d.ts +137 -0
- package/dist/src/sync/ado-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/ado-sync-wrapper.js +148 -0
- package/dist/src/sync/ado-sync-wrapper.js.map +1 -0
- package/dist/src/sync/github-sync-wrapper.d.ts +195 -0
- package/dist/src/sync/github-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/github-sync-wrapper.js +220 -0
- package/dist/src/sync/github-sync-wrapper.js.map +1 -0
- package/dist/src/sync/jira-sync-wrapper.d.ts +155 -0
- package/dist/src/sync/jira-sync-wrapper.d.ts.map +1 -0
- package/dist/src/sync/jira-sync-wrapper.js +175 -0
- package/dist/src/sync/jira-sync-wrapper.js.map +1 -0
- package/dist/src/utils/feature-id-derivation.d.ts +58 -0
- package/dist/src/utils/feature-id-derivation.d.ts.map +1 -0
- package/dist/src/utils/feature-id-derivation.js +77 -0
- package/dist/src/utils/feature-id-derivation.js.map +1 -0
- package/package.json +3 -1
- package/plugins/specweave/commands/specweave-discrepancies.md +141 -0
- package/plugins/specweave/commands/specweave-discrepancy-to-increment.md +160 -0
- package/plugins/specweave/commands/specweave-jobs.md +45 -2
- package/plugins/specweave/commands/specweave-notifications.md +92 -0
- package/plugins/specweave/commands/specweave-sync-logs.md +131 -0
- package/plugins/specweave/commands/specweave-sync-monitor.md +57 -0
- package/plugins/specweave/hooks/hooks.json +3 -3
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +72 -0
- package/plugins/specweave/hooks/universal/dispatcher.mjs +246 -0
- package/plugins/specweave/hooks/universal/session-start.cmd +16 -0
- package/plugins/specweave/hooks/universal/session-start.ps1 +16 -0
- package/plugins/specweave/hooks/v2/dispatchers/session-start.sh +14 -5
- package/plugins/specweave/lib/vendor/core/types/increment-metadata.d.ts +5 -2
- package/plugins/specweave/skills/discrepancy-viewer.md +154 -0
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +46 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +69 -0
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts +0 -26
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js +0 -249
- package/dist/plugins/specweave-github/lib/enhanced-github-sync.js.map +0 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts +0 -28
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.d.ts.map +0 -1
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -156
- package/dist/plugins/specweave-jira/lib/enhanced-jira-sync.js.map +0 -1
- package/dist/src/core/sync/bidirectional-engine.d.ts +0 -119
- package/dist/src/core/sync/bidirectional-engine.d.ts.map +0 -1
- package/dist/src/core/sync/bidirectional-engine.js +0 -359
- package/dist/src/core/sync/bidirectional-engine.js.map +0 -1
- package/dist/src/core/sync/conflict-resolver.d.ts +0 -66
- package/dist/src/core/sync/conflict-resolver.d.ts.map +0 -1
- package/dist/src/core/sync/conflict-resolver.js +0 -108
- package/dist/src/core/sync/conflict-resolver.js.map +0 -1
- package/dist/src/core/sync/enhanced-content-builder.d.ts +0 -55
- package/dist/src/core/sync/enhanced-content-builder.d.ts.map +0 -1
- package/dist/src/core/sync/enhanced-content-builder.js +0 -203
- package/dist/src/core/sync/enhanced-content-builder.js.map +0 -1
- package/dist/src/core/sync/folder-mapper.d.ts +0 -71
- package/dist/src/core/sync/folder-mapper.d.ts.map +0 -1
- package/dist/src/core/sync/folder-mapper.js +0 -203
- package/dist/src/core/sync/folder-mapper.js.map +0 -1
- package/dist/src/core/sync/label-detector.d.ts +0 -66
- package/dist/src/core/sync/label-detector.d.ts.map +0 -1
- package/dist/src/core/sync/label-detector.js +0 -224
- package/dist/src/core/sync/label-detector.js.map +0 -1
- package/dist/src/core/sync/performance-optimizer.d.ts +0 -153
- package/dist/src/core/sync/performance-optimizer.d.ts.map +0 -1
- package/dist/src/core/sync/performance-optimizer.js +0 -220
- package/dist/src/core/sync/performance-optimizer.js.map +0 -1
- package/dist/src/core/sync/profile-selector.d.ts +0 -52
- package/dist/src/core/sync/profile-selector.d.ts.map +0 -1
- package/dist/src/core/sync/profile-selector.js +0 -179
- package/dist/src/core/sync/profile-selector.js.map +0 -1
- package/dist/src/core/sync/profile-validator.d.ts +0 -52
- package/dist/src/core/sync/profile-validator.d.ts.map +0 -1
- package/dist/src/core/sync/profile-validator.js +0 -170
- package/dist/src/core/sync/profile-validator.js.map +0 -1
- package/dist/src/core/sync/rate-limiter.d.ts +0 -116
- package/dist/src/core/sync/rate-limiter.d.ts.map +0 -1
- package/dist/src/core/sync/rate-limiter.js +0 -308
- package/dist/src/core/sync/rate-limiter.js.map +0 -1
- package/dist/src/core/sync/retry-handler.d.ts +0 -98
- package/dist/src/core/sync/retry-handler.d.ts.map +0 -1
- package/dist/src/core/sync/retry-handler.js +0 -196
- package/dist/src/core/sync/retry-handler.js.map +0 -1
- package/dist/src/core/sync/retry-logic.d.ts +0 -64
- package/dist/src/core/sync/retry-logic.d.ts.map +0 -1
- package/dist/src/core/sync/retry-logic.js +0 -165
- package/dist/src/core/sync/retry-logic.js.map +0 -1
- package/dist/src/core/sync/status-cache.d.ts +0 -91
- package/dist/src/core/sync/status-cache.d.ts.map +0 -1
- package/dist/src/core/sync/status-cache.js +0 -140
- package/dist/src/core/sync/status-cache.js.map +0 -1
- package/dist/src/core/sync/status-mapper.d.ts +0 -69
- package/dist/src/core/sync/status-mapper.d.ts.map +0 -1
- package/dist/src/core/sync/status-mapper.js +0 -90
- package/dist/src/core/sync/status-mapper.js.map +0 -1
- package/dist/src/core/sync/status-sync-engine.d.ts +0 -162
- package/dist/src/core/sync/status-sync-engine.d.ts.map +0 -1
- package/dist/src/core/sync/status-sync-engine.js +0 -347
- package/dist/src/core/sync/status-sync-engine.js.map +0 -1
- package/dist/src/core/sync/sync-event-logger.d.ts +0 -113
- package/dist/src/core/sync/sync-event-logger.d.ts.map +0 -1
- package/dist/src/core/sync/sync-event-logger.js +0 -141
- package/dist/src/core/sync/sync-event-logger.js.map +0 -1
- package/dist/src/core/sync/time-range-selector.d.ts +0 -48
- package/dist/src/core/sync/time-range-selector.d.ts.map +0 -1
- package/dist/src/core/sync/time-range-selector.js +0 -224
- package/dist/src/core/sync/time-range-selector.js.map +0 -1
- package/dist/src/core/sync/types.d.ts +0 -52
- package/dist/src/core/sync/types.d.ts.map +0 -1
- package/dist/src/core/sync/types.js +0 -5
- package/dist/src/core/sync/types.js.map +0 -1
- package/dist/src/core/sync/workflow-detector.d.ts +0 -95
- package/dist/src/core/sync/workflow-detector.d.ts.map +0 -1
- package/dist/src/core/sync/workflow-detector.js +0 -175
- package/dist/src/core/sync/workflow-detector.js.map +0 -1
- package/plugins/specweave-github/lib/enhanced-github-sync.js +0 -220
- package/plugins/specweave-github/lib/enhanced-github-sync.ts +0 -322
- package/plugins/specweave-jira/lib/enhanced-jira-sync.js +0 -134
- package/plugins/specweave-jira/lib/enhanced-jira-sync.ts +0 -196
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sync Profile Validator
|
|
3
|
-
*
|
|
4
|
-
* Validates sync profile configurations for multi-team support
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Validate Jira profile configuration
|
|
8
|
-
*
|
|
9
|
-
* Rules:
|
|
10
|
-
* - Strategy is required
|
|
11
|
-
* - project-per-team: requires projects[] array
|
|
12
|
-
* - shared-project-with-components: requires projectKey + components[]
|
|
13
|
-
* - Cannot mix strategies (no projects[] with shared-project)
|
|
14
|
-
*
|
|
15
|
-
* @param config - Jira configuration
|
|
16
|
-
* @returns Validation result with errors/warnings
|
|
17
|
-
*/
|
|
18
|
-
export function validateJiraConfig(config) {
|
|
19
|
-
const errors = [];
|
|
20
|
-
const warnings = [];
|
|
21
|
-
// Validate domain
|
|
22
|
-
if (!config.domain || config.domain.trim().length === 0) {
|
|
23
|
-
errors.push('Jira domain is required');
|
|
24
|
-
}
|
|
25
|
-
// NOTE: Strategy-based validation temporarily disabled (v0.13.0+ migration in progress)
|
|
26
|
-
// TODO: Update validation to match new v0.13.0 architecture (intelligent/custom strategies)
|
|
27
|
-
// Basic validation: domain + either projectKey or projects[]
|
|
28
|
-
if (!config.projectKey && (!config.projects || config.projects.length === 0)) {
|
|
29
|
-
errors.push('Either projectKey (single project) or projects[] (multiple projects) is required');
|
|
30
|
-
}
|
|
31
|
-
// Validate project keys if provided
|
|
32
|
-
if (config.projects && config.projects.length > 0) {
|
|
33
|
-
const invalidProjects = config.projects.filter((p) => !/^[A-Z][A-Z0-9]*$/.test(p));
|
|
34
|
-
if (invalidProjects.length > 0) {
|
|
35
|
-
errors.push(`Invalid Jira project keys: ${invalidProjects.join(', ')} (must be uppercase alphanumeric, e.g., FRONTEND, QA)`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
// Validate single projectKey if provided
|
|
39
|
-
if (config.projectKey && !/^[A-Z][A-Z0-9]*$/.test(config.projectKey)) {
|
|
40
|
-
errors.push(`Invalid Jira project key: ${config.projectKey} (must be uppercase alphanumeric, e.g., PRODUCT)`);
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
valid: errors.length === 0,
|
|
44
|
-
errors,
|
|
45
|
-
warnings,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Validate Azure DevOps profile configuration
|
|
50
|
-
*
|
|
51
|
-
* Rules:
|
|
52
|
-
* - organization and project are required
|
|
53
|
-
* - teams[] array is optional (single project if not provided)
|
|
54
|
-
* - Team names cannot be empty
|
|
55
|
-
* - areaPaths map must match teams if both provided
|
|
56
|
-
*
|
|
57
|
-
* @param config - ADO configuration
|
|
58
|
-
* @returns Validation result with errors/warnings
|
|
59
|
-
*/
|
|
60
|
-
export function validateAdoConfig(config) {
|
|
61
|
-
const errors = [];
|
|
62
|
-
const warnings = [];
|
|
63
|
-
// Validate organization
|
|
64
|
-
if (!config.organization || config.organization.trim().length === 0) {
|
|
65
|
-
errors.push('ADO organization is required');
|
|
66
|
-
}
|
|
67
|
-
// NOTE: teams[] validation removed in v0.13.0 (deprecated field)
|
|
68
|
-
// TODO: Update validation to match new v0.13.0 architecture (projects[], areaPaths[])
|
|
69
|
-
// Validate project (optional in v0.13.0+ - can have projects[] instead)
|
|
70
|
-
if (!config.project && (!config.projects || config.projects.length === 0)) {
|
|
71
|
-
errors.push('Either project (single) or projects[] (multiple) is required');
|
|
72
|
-
}
|
|
73
|
-
// Validate projects[] if provided
|
|
74
|
-
if (config.projects && config.projects.length > 0) {
|
|
75
|
-
const emptyProjects = config.projects.filter((p) => !p.trim());
|
|
76
|
-
if (emptyProjects.length > 0) {
|
|
77
|
-
errors.push('Project names cannot be empty');
|
|
78
|
-
}
|
|
79
|
-
if (config.projects.length > 10) {
|
|
80
|
-
warnings.push(`Large number of projects (${config.projects.length}). Consider using custom query for complex filtering.`);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
// Validate areaPaths[] if provided (Pattern 3: Single project + area paths)
|
|
84
|
-
if (config.areaPaths && config.areaPaths.length > 0) {
|
|
85
|
-
const emptyPaths = config.areaPaths.filter((p) => !p.trim());
|
|
86
|
-
if (emptyPaths.length > 0) {
|
|
87
|
-
errors.push('Area path names cannot be empty');
|
|
88
|
-
}
|
|
89
|
-
// areaPaths should only be used with single project (not projects[])
|
|
90
|
-
if (config.projects && config.projects.length > 0) {
|
|
91
|
-
warnings.push('areaPaths[] should be used with single project, not projects[]. Use projects[] for multiple projects.');
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
valid: errors.length === 0,
|
|
96
|
-
errors,
|
|
97
|
-
warnings,
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Validate GitHub profile configuration
|
|
102
|
-
*
|
|
103
|
-
* Rules:
|
|
104
|
-
* - owner and repo are required
|
|
105
|
-
*
|
|
106
|
-
* @param config - GitHub configuration
|
|
107
|
-
* @returns Validation result with errors/warnings
|
|
108
|
-
*/
|
|
109
|
-
export function validateGitHubConfig(config) {
|
|
110
|
-
const errors = [];
|
|
111
|
-
const warnings = [];
|
|
112
|
-
if (!config.owner || config.owner.trim().length === 0) {
|
|
113
|
-
errors.push('GitHub owner is required');
|
|
114
|
-
}
|
|
115
|
-
if (!config.repo || config.repo.trim().length === 0) {
|
|
116
|
-
errors.push('GitHub repo is required');
|
|
117
|
-
}
|
|
118
|
-
return {
|
|
119
|
-
valid: errors.length === 0,
|
|
120
|
-
errors,
|
|
121
|
-
warnings,
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Validate sync profile
|
|
126
|
-
*
|
|
127
|
-
* Validates entire profile including provider-specific config
|
|
128
|
-
*
|
|
129
|
-
* @param profile - Sync profile to validate
|
|
130
|
-
* @returns Validation result with errors/warnings
|
|
131
|
-
*/
|
|
132
|
-
export function validateSyncProfile(profile) {
|
|
133
|
-
const errors = [];
|
|
134
|
-
const warnings = [];
|
|
135
|
-
// Validate displayName
|
|
136
|
-
if (!profile.displayName || profile.displayName.trim().length === 0) {
|
|
137
|
-
errors.push('Profile displayName is required');
|
|
138
|
-
}
|
|
139
|
-
// Validate provider
|
|
140
|
-
if (!profile.provider) {
|
|
141
|
-
errors.push('Provider is required (github, jira, or ado)');
|
|
142
|
-
return { valid: false, errors, warnings };
|
|
143
|
-
}
|
|
144
|
-
// Validate provider-specific config
|
|
145
|
-
let providerValidation;
|
|
146
|
-
if (profile.provider === 'github') {
|
|
147
|
-
providerValidation = validateGitHubConfig(profile.config);
|
|
148
|
-
}
|
|
149
|
-
else if (profile.provider === 'jira') {
|
|
150
|
-
providerValidation = validateJiraConfig(profile.config);
|
|
151
|
-
}
|
|
152
|
-
else if (profile.provider === 'ado') {
|
|
153
|
-
providerValidation = validateAdoConfig(profile.config);
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
errors.push(`Unknown provider: ${profile.provider}`);
|
|
157
|
-
return { valid: false, errors, warnings };
|
|
158
|
-
}
|
|
159
|
-
// Merge provider validation results
|
|
160
|
-
errors.push(...providerValidation.errors);
|
|
161
|
-
if (providerValidation.warnings) {
|
|
162
|
-
warnings.push(...providerValidation.warnings);
|
|
163
|
-
}
|
|
164
|
-
return {
|
|
165
|
-
valid: errors.length === 0,
|
|
166
|
-
errors,
|
|
167
|
-
warnings: warnings.length > 0 ? warnings : undefined,
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
//# sourceMappingURL=profile-validator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"profile-validator.js","sourceRoot":"","sources":["../../../../src/core/sync/profile-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rate Limiter for External Sync
|
|
3
|
-
*
|
|
4
|
-
* Provides rate limiting protection, estimation, and backoff strategies
|
|
5
|
-
* for GitHub, JIRA, and Azure DevOps sync operations.
|
|
6
|
-
*/
|
|
7
|
-
import { SyncProvider, TimeRangePreset, TimeRangeEstimate, RateLimitStatus } from '../types/sync-profile.js';
|
|
8
|
-
export declare const PROVIDER_RATE_LIMITS: {
|
|
9
|
-
readonly github: {
|
|
10
|
-
readonly limit: 5000;
|
|
11
|
-
readonly window: "1h";
|
|
12
|
-
readonly thresholds: {
|
|
13
|
-
readonly low: 250;
|
|
14
|
-
readonly medium: 1000;
|
|
15
|
-
readonly high: 2500;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
readonly jira: {
|
|
19
|
-
readonly limit: 100;
|
|
20
|
-
readonly window: "1m";
|
|
21
|
-
readonly thresholds: {
|
|
22
|
-
readonly low: 25;
|
|
23
|
-
readonly medium: 50;
|
|
24
|
-
readonly high: 75;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
readonly ado: {
|
|
28
|
-
readonly limit: 200;
|
|
29
|
-
readonly window: "5m";
|
|
30
|
-
readonly thresholds: {
|
|
31
|
-
readonly low: 50;
|
|
32
|
-
readonly medium: 100;
|
|
33
|
-
readonly high: 150;
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
|
-
};
|
|
37
|
-
export declare class RateLimiter {
|
|
38
|
-
private provider;
|
|
39
|
-
constructor(provider: SyncProvider);
|
|
40
|
-
/**
|
|
41
|
-
* Estimate sync operation impact
|
|
42
|
-
*
|
|
43
|
-
* @param timeRange Time range preset
|
|
44
|
-
* @param customFactor Custom scaling factor (default: 1.0)
|
|
45
|
-
* @returns Estimate of items, API calls, duration, and impact
|
|
46
|
-
*/
|
|
47
|
-
estimateSync(timeRange: TimeRangePreset, customFactor?: number): TimeRangeEstimate;
|
|
48
|
-
/**
|
|
49
|
-
* Calculate rate limit impact level
|
|
50
|
-
*
|
|
51
|
-
* @param apiCalls Number of API calls
|
|
52
|
-
* @returns Impact level: low, medium, high, or critical
|
|
53
|
-
*/
|
|
54
|
-
private calculateImpact;
|
|
55
|
-
/**
|
|
56
|
-
* Check current rate limit status (provider-specific)
|
|
57
|
-
*
|
|
58
|
-
* @param client Provider client (e.g., GitHubClient)
|
|
59
|
-
* @returns Current rate limit status
|
|
60
|
-
*/
|
|
61
|
-
checkRateLimitStatus(client: any): Promise<RateLimitStatus | null>;
|
|
62
|
-
/**
|
|
63
|
-
* Check GitHub rate limit status
|
|
64
|
-
*/
|
|
65
|
-
private checkGitHubRateLimit;
|
|
66
|
-
/**
|
|
67
|
-
* Check JIRA rate limit status
|
|
68
|
-
* (JIRA doesn't expose rate limit info - return estimated)
|
|
69
|
-
*/
|
|
70
|
-
private checkJiraRateLimit;
|
|
71
|
-
/**
|
|
72
|
-
* Check Azure DevOps rate limit status
|
|
73
|
-
* (ADO doesn't expose rate limit info - return estimated)
|
|
74
|
-
*/
|
|
75
|
-
private checkAdoRateLimit;
|
|
76
|
-
/**
|
|
77
|
-
* Validate sync operation is safe to proceed
|
|
78
|
-
*
|
|
79
|
-
* @param estimate Sync estimate
|
|
80
|
-
* @param rateLimitStatus Current rate limit status (optional)
|
|
81
|
-
* @returns Validation result
|
|
82
|
-
*/
|
|
83
|
-
validateSync(estimate: TimeRangeEstimate, rateLimitStatus?: RateLimitStatus | null): {
|
|
84
|
-
safe: boolean;
|
|
85
|
-
warnings: string[];
|
|
86
|
-
blockers: string[];
|
|
87
|
-
};
|
|
88
|
-
/**
|
|
89
|
-
* Get impact percentage for given API calls
|
|
90
|
-
*/
|
|
91
|
-
private getImpactPercentage;
|
|
92
|
-
/**
|
|
93
|
-
* Calculate backoff delay when rate limited
|
|
94
|
-
*
|
|
95
|
-
* @param attempt Current retry attempt (0-indexed)
|
|
96
|
-
* @param maxBackoff Maximum backoff in milliseconds (default: 5 minutes)
|
|
97
|
-
* @returns Delay in milliseconds
|
|
98
|
-
*/
|
|
99
|
-
calculateBackoff(attempt: number, maxBackoff?: number): number;
|
|
100
|
-
/**
|
|
101
|
-
* Wait for rate limit to reset
|
|
102
|
-
*
|
|
103
|
-
* @param resetAt ISO timestamp when rate limit resets
|
|
104
|
-
* @returns Promise that resolves when rate limit resets
|
|
105
|
-
*/
|
|
106
|
-
waitForReset(resetAt: string): Promise<void>;
|
|
107
|
-
/**
|
|
108
|
-
* Format estimate for display
|
|
109
|
-
*/
|
|
110
|
-
formatEstimate(estimate: TimeRangeEstimate): string;
|
|
111
|
-
/**
|
|
112
|
-
* Format rate limit status for display
|
|
113
|
-
*/
|
|
114
|
-
formatRateLimitStatus(status: RateLimitStatus): string;
|
|
115
|
-
}
|
|
116
|
-
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../../../src/core/sync/rate-limiter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,YAAY,EACZ,eAAe,EACf,iBAAiB,EACjB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAMlC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BvB,CAAC;AAkCX,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAe;gBAEnB,QAAQ,EAAE,YAAY;IAQlC;;;;;;OAMG;IACH,YAAY,CACV,SAAS,EAAE,eAAe,EAC1B,YAAY,GAAE,MAAY,GACzB,iBAAiB;IAsBpB;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAoBvB;;;;;OAKG;IACG,oBAAoB,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAiBxE;;OAEG;YACW,oBAAoB;IA+BlC;;;OAGG;YACW,kBAAkB;IAYhC;;;OAGG;YACW,iBAAiB;IAgB/B;;;;;;OAMG;IACH,YAAY,CACV,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,CAAC,EAAE,eAAe,GAAG,IAAI,GACvC;QACD,IAAI,EAAE,OAAO,CAAC;QACd,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB;IAoDD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAS3B;;;;;;OAMG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,GAAE,MAAsB,GAAG,MAAM;IAM7E;;;;;OAKG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM;IAWnD;;OAEG;IACH,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM;CAOvD"}
|
|
@@ -1,308 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rate Limiter for External Sync
|
|
3
|
-
*
|
|
4
|
-
* Provides rate limiting protection, estimation, and backoff strategies
|
|
5
|
-
* for GitHub, JIRA, and Azure DevOps sync operations.
|
|
6
|
-
*/
|
|
7
|
-
import { execFileNoThrow } from '../../utils/execFileNoThrow.js';
|
|
8
|
-
// ============================================================================
|
|
9
|
-
// Provider Rate Limit Constants
|
|
10
|
-
// ============================================================================
|
|
11
|
-
export const PROVIDER_RATE_LIMITS = {
|
|
12
|
-
github: {
|
|
13
|
-
limit: 5000,
|
|
14
|
-
window: '1h',
|
|
15
|
-
thresholds: {
|
|
16
|
-
low: 250, // < 5% of limit
|
|
17
|
-
medium: 1000, // < 20% of limit
|
|
18
|
-
high: 2500, // < 50% of limit
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
jira: {
|
|
22
|
-
limit: 100,
|
|
23
|
-
window: '1m',
|
|
24
|
-
thresholds: {
|
|
25
|
-
low: 25,
|
|
26
|
-
medium: 50,
|
|
27
|
-
high: 75,
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
ado: {
|
|
31
|
-
limit: 200,
|
|
32
|
-
window: '5m',
|
|
33
|
-
thresholds: {
|
|
34
|
-
low: 50,
|
|
35
|
-
medium: 100,
|
|
36
|
-
high: 150,
|
|
37
|
-
},
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
// ============================================================================
|
|
41
|
-
// Time Range Estimation Constants
|
|
42
|
-
// ============================================================================
|
|
43
|
-
/**
|
|
44
|
-
* Average work items created per time period
|
|
45
|
-
* (Adjust based on real project velocity)
|
|
46
|
-
*/
|
|
47
|
-
const ITEMS_PER_PERIOD = {
|
|
48
|
-
'1W': 50,
|
|
49
|
-
'2W': 100,
|
|
50
|
-
'1M': 200,
|
|
51
|
-
'3M': 600,
|
|
52
|
-
'6M': 1200,
|
|
53
|
-
'1Y': 2400,
|
|
54
|
-
ALL: 5000, // Estimate - actual will vary greatly
|
|
55
|
-
};
|
|
56
|
-
/**
|
|
57
|
-
* API call multiplier (overhead for pagination, metadata, etc.)
|
|
58
|
-
*/
|
|
59
|
-
const API_CALL_MULTIPLIER = 1.5;
|
|
60
|
-
/**
|
|
61
|
-
* Throughput (items synced per minute)
|
|
62
|
-
*/
|
|
63
|
-
const ITEMS_PER_MINUTE = 100;
|
|
64
|
-
// ============================================================================
|
|
65
|
-
// Rate Limiter Class
|
|
66
|
-
// ============================================================================
|
|
67
|
-
export class RateLimiter {
|
|
68
|
-
constructor(provider) {
|
|
69
|
-
this.provider = provider;
|
|
70
|
-
}
|
|
71
|
-
// ==========================================================================
|
|
72
|
-
// Estimation
|
|
73
|
-
// ==========================================================================
|
|
74
|
-
/**
|
|
75
|
-
* Estimate sync operation impact
|
|
76
|
-
*
|
|
77
|
-
* @param timeRange Time range preset
|
|
78
|
-
* @param customFactor Custom scaling factor (default: 1.0)
|
|
79
|
-
* @returns Estimate of items, API calls, duration, and impact
|
|
80
|
-
*/
|
|
81
|
-
estimateSync(timeRange, customFactor = 1.0) {
|
|
82
|
-
// Base estimate from preset
|
|
83
|
-
const baseItems = ITEMS_PER_PERIOD[timeRange];
|
|
84
|
-
const items = Math.ceil(baseItems * customFactor);
|
|
85
|
-
// Calculate API calls (with overhead)
|
|
86
|
-
const apiCalls = Math.ceil(items * API_CALL_MULTIPLIER);
|
|
87
|
-
// Estimate duration
|
|
88
|
-
const durationMinutes = Math.ceil(items / ITEMS_PER_MINUTE);
|
|
89
|
-
// Calculate rate limit impact
|
|
90
|
-
const rateLimitImpact = this.calculateImpact(apiCalls);
|
|
91
|
-
return {
|
|
92
|
-
items,
|
|
93
|
-
apiCalls,
|
|
94
|
-
durationMinutes,
|
|
95
|
-
rateLimitImpact,
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Calculate rate limit impact level
|
|
100
|
-
*
|
|
101
|
-
* @param apiCalls Number of API calls
|
|
102
|
-
* @returns Impact level: low, medium, high, or critical
|
|
103
|
-
*/
|
|
104
|
-
calculateImpact(apiCalls) {
|
|
105
|
-
const limits = PROVIDER_RATE_LIMITS[this.provider];
|
|
106
|
-
if (apiCalls < limits.thresholds.low) {
|
|
107
|
-
return 'low';
|
|
108
|
-
}
|
|
109
|
-
else if (apiCalls < limits.thresholds.medium) {
|
|
110
|
-
return 'medium';
|
|
111
|
-
}
|
|
112
|
-
else if (apiCalls < limits.thresholds.high) {
|
|
113
|
-
return 'high';
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
return 'critical';
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// ==========================================================================
|
|
120
|
-
// Rate Limit Checking
|
|
121
|
-
// ==========================================================================
|
|
122
|
-
/**
|
|
123
|
-
* Check current rate limit status (provider-specific)
|
|
124
|
-
*
|
|
125
|
-
* @param client Provider client (e.g., GitHubClient)
|
|
126
|
-
* @returns Current rate limit status
|
|
127
|
-
*/
|
|
128
|
-
async checkRateLimitStatus(client) {
|
|
129
|
-
try {
|
|
130
|
-
if (this.provider === 'github') {
|
|
131
|
-
return await this.checkGitHubRateLimit(client);
|
|
132
|
-
}
|
|
133
|
-
else if (this.provider === 'jira') {
|
|
134
|
-
return await this.checkJiraRateLimit(client);
|
|
135
|
-
}
|
|
136
|
-
else if (this.provider === 'ado') {
|
|
137
|
-
return await this.checkAdoRateLimit(client);
|
|
138
|
-
}
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
console.warn(`Failed to check rate limit for ${this.provider}:`, error);
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Check GitHub rate limit status
|
|
148
|
-
*/
|
|
149
|
-
async checkGitHubRateLimit(client) {
|
|
150
|
-
try {
|
|
151
|
-
// Use secure execFileNoThrow instead of execSync
|
|
152
|
-
const result = await execFileNoThrow('gh', [
|
|
153
|
-
'api',
|
|
154
|
-
'rate_limit',
|
|
155
|
-
'--jq',
|
|
156
|
-
'.resources.core',
|
|
157
|
-
]);
|
|
158
|
-
if (!result.success) {
|
|
159
|
-
throw new Error(`GitHub CLI command failed: ${result.stderr || 'Unknown error'}`);
|
|
160
|
-
}
|
|
161
|
-
const data = JSON.parse(result.stdout);
|
|
162
|
-
return {
|
|
163
|
-
remaining: data.remaining,
|
|
164
|
-
limit: data.limit,
|
|
165
|
-
resetAt: new Date(data.reset * 1000).toISOString(),
|
|
166
|
-
percentUsed: ((data.limit - data.remaining) / data.limit) * 100,
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
throw new Error(`Failed to check GitHub rate limit. Is \`gh\` CLI authenticated? ${error.message}`);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Check JIRA rate limit status
|
|
175
|
-
* (JIRA doesn't expose rate limit info - return estimated)
|
|
176
|
-
*/
|
|
177
|
-
async checkJiraRateLimit(client) {
|
|
178
|
-
// JIRA: No API to check rate limits - return estimated
|
|
179
|
-
const limits = PROVIDER_RATE_LIMITS.jira;
|
|
180
|
-
return {
|
|
181
|
-
remaining: limits.limit,
|
|
182
|
-
limit: limits.limit,
|
|
183
|
-
resetAt: new Date(Date.now() + 60 * 1000).toISOString(), // 1 minute window
|
|
184
|
-
percentUsed: 0, // Unknown
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
/**
|
|
188
|
-
* Check Azure DevOps rate limit status
|
|
189
|
-
* (ADO doesn't expose rate limit info - return estimated)
|
|
190
|
-
*/
|
|
191
|
-
async checkAdoRateLimit(client) {
|
|
192
|
-
// ADO: No API to check rate limits - return estimated
|
|
193
|
-
const limits = PROVIDER_RATE_LIMITS.ado;
|
|
194
|
-
return {
|
|
195
|
-
remaining: limits.limit,
|
|
196
|
-
limit: limits.limit,
|
|
197
|
-
resetAt: new Date(Date.now() + 5 * 60 * 1000).toISOString(), // 5 minute window
|
|
198
|
-
percentUsed: 0, // Unknown
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
// ==========================================================================
|
|
202
|
-
// Sync Protection
|
|
203
|
-
// ==========================================================================
|
|
204
|
-
/**
|
|
205
|
-
* Validate sync operation is safe to proceed
|
|
206
|
-
*
|
|
207
|
-
* @param estimate Sync estimate
|
|
208
|
-
* @param rateLimitStatus Current rate limit status (optional)
|
|
209
|
-
* @returns Validation result
|
|
210
|
-
*/
|
|
211
|
-
validateSync(estimate, rateLimitStatus) {
|
|
212
|
-
const warnings = [];
|
|
213
|
-
const blockers = [];
|
|
214
|
-
// Check impact level
|
|
215
|
-
if (estimate.rateLimitImpact === 'high') {
|
|
216
|
-
warnings.push(`High rate limit impact: ${estimate.apiCalls} API calls (will use ${this.getImpactPercentage(estimate.apiCalls)}% of ${this.provider} rate limit)`);
|
|
217
|
-
}
|
|
218
|
-
else if (estimate.rateLimitImpact === 'critical') {
|
|
219
|
-
blockers.push(`CRITICAL rate limit impact: ${estimate.apiCalls} API calls exceeds safe threshold for ${this.provider}`);
|
|
220
|
-
}
|
|
221
|
-
// Check duration
|
|
222
|
-
if (estimate.durationMinutes > 10) {
|
|
223
|
-
warnings.push(`Long sync duration: ~${estimate.durationMinutes} minutes`);
|
|
224
|
-
}
|
|
225
|
-
// Check current rate limit status
|
|
226
|
-
if (rateLimitStatus) {
|
|
227
|
-
const percentUsed = rateLimitStatus.percentUsed;
|
|
228
|
-
if (percentUsed > 80) {
|
|
229
|
-
warnings.push(`Rate limit already ${Math.round(percentUsed)}% used. Consider waiting until reset at ${rateLimitStatus.resetAt}`);
|
|
230
|
-
}
|
|
231
|
-
// Check if sync would exceed limit
|
|
232
|
-
const afterSync = rateLimitStatus.remaining - estimate.apiCalls;
|
|
233
|
-
if (afterSync < 0) {
|
|
234
|
-
blockers.push(`Not enough rate limit remaining. Need ${estimate.apiCalls} calls, only ${rateLimitStatus.remaining} remaining. Reset at ${rateLimitStatus.resetAt}`);
|
|
235
|
-
}
|
|
236
|
-
else if (afterSync < rateLimitStatus.limit * 0.1) {
|
|
237
|
-
warnings.push(`After sync, only ${afterSync} requests remaining (${Math.round((afterSync / rateLimitStatus.limit) * 100)}%)`);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
return {
|
|
241
|
-
safe: blockers.length === 0,
|
|
242
|
-
warnings,
|
|
243
|
-
blockers,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
/**
|
|
247
|
-
* Get impact percentage for given API calls
|
|
248
|
-
*/
|
|
249
|
-
getImpactPercentage(apiCalls) {
|
|
250
|
-
const limits = PROVIDER_RATE_LIMITS[this.provider];
|
|
251
|
-
return Math.round((apiCalls / limits.limit) * 100);
|
|
252
|
-
}
|
|
253
|
-
// ==========================================================================
|
|
254
|
-
// Backoff Strategy
|
|
255
|
-
// ==========================================================================
|
|
256
|
-
/**
|
|
257
|
-
* Calculate backoff delay when rate limited
|
|
258
|
-
*
|
|
259
|
-
* @param attempt Current retry attempt (0-indexed)
|
|
260
|
-
* @param maxBackoff Maximum backoff in milliseconds (default: 5 minutes)
|
|
261
|
-
* @returns Delay in milliseconds
|
|
262
|
-
*/
|
|
263
|
-
calculateBackoff(attempt, maxBackoff = 5 * 60 * 1000) {
|
|
264
|
-
// Exponential backoff: 2^attempt * 1000ms, capped at maxBackoff
|
|
265
|
-
const delay = Math.min(Math.pow(2, attempt) * 1000, maxBackoff);
|
|
266
|
-
return delay;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Wait for rate limit to reset
|
|
270
|
-
*
|
|
271
|
-
* @param resetAt ISO timestamp when rate limit resets
|
|
272
|
-
* @returns Promise that resolves when rate limit resets
|
|
273
|
-
*/
|
|
274
|
-
async waitForReset(resetAt) {
|
|
275
|
-
const resetTime = new Date(resetAt).getTime();
|
|
276
|
-
const now = Date.now();
|
|
277
|
-
const delay = Math.max(0, resetTime - now);
|
|
278
|
-
if (delay > 0) {
|
|
279
|
-
console.log(`⏳ Waiting for rate limit reset... (${Math.ceil(delay / 1000 / 60)} minutes)`);
|
|
280
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
// ==========================================================================
|
|
284
|
-
// Formatting Helpers
|
|
285
|
-
// ==========================================================================
|
|
286
|
-
/**
|
|
287
|
-
* Format estimate for display
|
|
288
|
-
*/
|
|
289
|
-
formatEstimate(estimate) {
|
|
290
|
-
const impactEmoji = {
|
|
291
|
-
low: '⚡',
|
|
292
|
-
medium: '⚠️ ',
|
|
293
|
-
high: '⚠️ ',
|
|
294
|
-
critical: '❌',
|
|
295
|
-
};
|
|
296
|
-
return `${estimate.items} items | ${estimate.apiCalls} API calls | ${impactEmoji[estimate.rateLimitImpact]} ${estimate.durationMinutes} min | Rate: ${estimate.rateLimitImpact.toUpperCase()}`;
|
|
297
|
-
}
|
|
298
|
-
/**
|
|
299
|
-
* Format rate limit status for display
|
|
300
|
-
*/
|
|
301
|
-
formatRateLimitStatus(status) {
|
|
302
|
-
const resetDate = new Date(status.resetAt);
|
|
303
|
-
const now = new Date();
|
|
304
|
-
const minutesUntilReset = Math.ceil((resetDate.getTime() - now.getTime()) / 1000 / 60);
|
|
305
|
-
return `${status.remaining}/${status.limit} (${Math.round(100 - status.percentUsed)}% available) | Resets in ${minutesUntilReset} min`;
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../../../src/core/sync/rate-limiter.ts"],"names":[],"mappings":"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"}
|