@specforge/mcp 2.6.0 → 3.0.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.
Files changed (237) hide show
  1. package/README.md +73 -0
  2. package/bin/{specforge-mcp → specforge} +0 -5
  3. package/dist/ai-provider/circuit-breaker.d.ts +63 -0
  4. package/dist/ai-provider/circuit-breaker.d.ts.map +1 -0
  5. package/dist/ai-provider/circuit-breaker.js +160 -0
  6. package/dist/ai-provider/circuit-breaker.js.map +1 -0
  7. package/dist/ai-provider/cli-version.d.ts +50 -0
  8. package/dist/ai-provider/cli-version.d.ts.map +1 -0
  9. package/dist/ai-provider/cli-version.js +141 -0
  10. package/dist/ai-provider/cli-version.js.map +1 -0
  11. package/dist/ai-provider/config-loader.d.ts +45 -0
  12. package/dist/ai-provider/config-loader.d.ts.map +1 -0
  13. package/dist/ai-provider/config-loader.js +106 -0
  14. package/dist/ai-provider/config-loader.js.map +1 -0
  15. package/dist/ai-provider/errors.d.ts +48 -0
  16. package/dist/ai-provider/errors.d.ts.map +1 -0
  17. package/dist/ai-provider/errors.js +102 -0
  18. package/dist/ai-provider/errors.js.map +1 -0
  19. package/dist/ai-provider/events.d.ts +73 -0
  20. package/dist/ai-provider/events.d.ts.map +1 -0
  21. package/dist/ai-provider/events.js +75 -0
  22. package/dist/ai-provider/events.js.map +1 -0
  23. package/dist/ai-provider/factory.d.ts +31 -0
  24. package/dist/ai-provider/factory.d.ts.map +1 -0
  25. package/dist/ai-provider/factory.js +100 -0
  26. package/dist/ai-provider/factory.js.map +1 -0
  27. package/dist/ai-provider/index.d.ts +24 -0
  28. package/dist/ai-provider/index.d.ts.map +1 -0
  29. package/dist/ai-provider/index.js +46 -0
  30. package/dist/ai-provider/index.js.map +1 -0
  31. package/dist/ai-provider/instance-coordinator.d.ts +54 -0
  32. package/dist/ai-provider/instance-coordinator.d.ts.map +1 -0
  33. package/dist/ai-provider/instance-coordinator.js +199 -0
  34. package/dist/ai-provider/instance-coordinator.js.map +1 -0
  35. package/dist/ai-provider/jsonl-parser.d.ts +43 -0
  36. package/dist/ai-provider/jsonl-parser.d.ts.map +1 -0
  37. package/dist/ai-provider/jsonl-parser.js +107 -0
  38. package/dist/ai-provider/jsonl-parser.js.map +1 -0
  39. package/dist/ai-provider/lifecycle.d.ts +50 -0
  40. package/dist/ai-provider/lifecycle.d.ts.map +1 -0
  41. package/dist/ai-provider/lifecycle.js +145 -0
  42. package/dist/ai-provider/lifecycle.js.map +1 -0
  43. package/dist/ai-provider/logger.d.ts +69 -0
  44. package/dist/ai-provider/logger.d.ts.map +1 -0
  45. package/dist/ai-provider/logger.js +161 -0
  46. package/dist/ai-provider/logger.js.map +1 -0
  47. package/dist/ai-provider/metrics.d.ts +91 -0
  48. package/dist/ai-provider/metrics.d.ts.map +1 -0
  49. package/dist/ai-provider/metrics.js +187 -0
  50. package/dist/ai-provider/metrics.js.map +1 -0
  51. package/dist/ai-provider/process-manager.d.ts +97 -0
  52. package/dist/ai-provider/process-manager.d.ts.map +1 -0
  53. package/dist/ai-provider/process-manager.js +477 -0
  54. package/dist/ai-provider/process-manager.js.map +1 -0
  55. package/dist/ai-provider/providers/claude-code.d.ts +64 -0
  56. package/dist/ai-provider/providers/claude-code.d.ts.map +1 -0
  57. package/dist/ai-provider/providers/claude-code.js +205 -0
  58. package/dist/ai-provider/providers/claude-code.js.map +1 -0
  59. package/dist/ai-provider/retry-executor.d.ts +52 -0
  60. package/dist/ai-provider/retry-executor.d.ts.map +1 -0
  61. package/dist/ai-provider/retry-executor.js +138 -0
  62. package/dist/ai-provider/retry-executor.js.map +1 -0
  63. package/dist/ai-provider/safe-args.d.ts +58 -0
  64. package/dist/ai-provider/safe-args.d.ts.map +1 -0
  65. package/dist/ai-provider/safe-args.js +176 -0
  66. package/dist/ai-provider/safe-args.js.map +1 -0
  67. package/dist/ai-provider/semaphore.d.ts +50 -0
  68. package/dist/ai-provider/semaphore.d.ts.map +1 -0
  69. package/dist/ai-provider/semaphore.js +97 -0
  70. package/dist/ai-provider/semaphore.js.map +1 -0
  71. package/dist/ai-provider/tracer.d.ts +67 -0
  72. package/dist/ai-provider/tracer.d.ts.map +1 -0
  73. package/dist/ai-provider/tracer.js +209 -0
  74. package/dist/ai-provider/tracer.js.map +1 -0
  75. package/dist/ai-provider/types.d.ts +181 -0
  76. package/dist/ai-provider/types.d.ts.map +1 -0
  77. package/dist/ai-provider/types.js +8 -0
  78. package/dist/ai-provider/types.js.map +1 -0
  79. package/dist/autopilot/agents/agent-runner.d.ts +109 -0
  80. package/dist/autopilot/agents/agent-runner.d.ts.map +1 -0
  81. package/dist/autopilot/agents/agent-runner.js +731 -0
  82. package/dist/autopilot/agents/agent-runner.js.map +1 -0
  83. package/dist/autopilot/agents/agent-selector.d.ts +59 -0
  84. package/dist/autopilot/agents/agent-selector.d.ts.map +1 -0
  85. package/dist/autopilot/agents/agent-selector.js +234 -0
  86. package/dist/autopilot/agents/agent-selector.js.map +1 -0
  87. package/dist/autopilot/agents/model-selector.d.ts +49 -0
  88. package/dist/autopilot/agents/model-selector.d.ts.map +1 -0
  89. package/dist/autopilot/agents/model-selector.js +62 -0
  90. package/dist/autopilot/agents/model-selector.js.map +1 -0
  91. package/dist/autopilot/agents/profiles/builtin.d.ts +55 -0
  92. package/dist/autopilot/agents/profiles/builtin.d.ts.map +1 -0
  93. package/dist/autopilot/agents/profiles/builtin.js +323 -0
  94. package/dist/autopilot/agents/profiles/builtin.js.map +1 -0
  95. package/dist/autopilot/agents/profiles/types.d.ts +98 -0
  96. package/dist/autopilot/agents/profiles/types.d.ts.map +1 -0
  97. package/dist/autopilot/agents/profiles/types.js +17 -0
  98. package/dist/autopilot/agents/profiles/types.js.map +1 -0
  99. package/dist/autopilot/api/autopilot-api-client.d.ts +217 -0
  100. package/dist/autopilot/api/autopilot-api-client.d.ts.map +1 -0
  101. package/dist/autopilot/api/autopilot-api-client.js +402 -0
  102. package/dist/autopilot/api/autopilot-api-client.js.map +1 -0
  103. package/dist/autopilot/cli/abort.d.ts +20 -0
  104. package/dist/autopilot/cli/abort.d.ts.map +1 -0
  105. package/dist/autopilot/cli/abort.js +201 -0
  106. package/dist/autopilot/cli/abort.js.map +1 -0
  107. package/dist/autopilot/cli/display.d.ts +63 -0
  108. package/dist/autopilot/cli/display.d.ts.map +1 -0
  109. package/dist/autopilot/cli/display.js +260 -0
  110. package/dist/autopilot/cli/display.js.map +1 -0
  111. package/dist/autopilot/cli/index.d.ts +24 -0
  112. package/dist/autopilot/cli/index.d.ts.map +1 -0
  113. package/dist/autopilot/cli/index.js +79 -0
  114. package/dist/autopilot/cli/index.js.map +1 -0
  115. package/dist/autopilot/cli/pause.d.ts +18 -0
  116. package/dist/autopilot/cli/pause.d.ts.map +1 -0
  117. package/dist/autopilot/cli/pause.js +110 -0
  118. package/dist/autopilot/cli/pause.js.map +1 -0
  119. package/dist/autopilot/cli/resume.d.ts +22 -0
  120. package/dist/autopilot/cli/resume.d.ts.map +1 -0
  121. package/dist/autopilot/cli/resume.js +172 -0
  122. package/dist/autopilot/cli/resume.js.map +1 -0
  123. package/dist/autopilot/cli/run.d.ts +25 -0
  124. package/dist/autopilot/cli/run.d.ts.map +1 -0
  125. package/dist/autopilot/cli/run.js +220 -0
  126. package/dist/autopilot/cli/run.js.map +1 -0
  127. package/dist/autopilot/cli/status.d.ts +20 -0
  128. package/dist/autopilot/cli/status.d.ts.map +1 -0
  129. package/dist/autopilot/cli/status.js +217 -0
  130. package/dist/autopilot/cli/status.js.map +1 -0
  131. package/dist/autopilot/config.d.ts +45 -0
  132. package/dist/autopilot/config.d.ts.map +1 -0
  133. package/dist/autopilot/config.js +269 -0
  134. package/dist/autopilot/config.js.map +1 -0
  135. package/dist/autopilot/core/dependency-resolver.d.ts +108 -0
  136. package/dist/autopilot/core/dependency-resolver.d.ts.map +1 -0
  137. package/dist/autopilot/core/dependency-resolver.js +394 -0
  138. package/dist/autopilot/core/dependency-resolver.js.map +1 -0
  139. package/dist/autopilot/core/dispatcher.d.ts +215 -0
  140. package/dist/autopilot/core/dispatcher.d.ts.map +1 -0
  141. package/dist/autopilot/core/dispatcher.js +594 -0
  142. package/dist/autopilot/core/dispatcher.js.map +1 -0
  143. package/dist/autopilot/core/failure-handler.d.ts +145 -0
  144. package/dist/autopilot/core/failure-handler.d.ts.map +1 -0
  145. package/dist/autopilot/core/failure-handler.js +308 -0
  146. package/dist/autopilot/core/failure-handler.js.map +1 -0
  147. package/dist/autopilot/core/rate-limit-handler.d.ts +108 -0
  148. package/dist/autopilot/core/rate-limit-handler.d.ts.map +1 -0
  149. package/dist/autopilot/core/rate-limit-handler.js +195 -0
  150. package/dist/autopilot/core/rate-limit-handler.js.map +1 -0
  151. package/dist/autopilot/core/state-manager.d.ts +160 -0
  152. package/dist/autopilot/core/state-manager.d.ts.map +1 -0
  153. package/dist/autopilot/core/state-manager.js +393 -0
  154. package/dist/autopilot/core/state-manager.js.map +1 -0
  155. package/dist/autopilot/core/timeout-manager.d.ts +95 -0
  156. package/dist/autopilot/core/timeout-manager.d.ts.map +1 -0
  157. package/dist/autopilot/core/timeout-manager.js +188 -0
  158. package/dist/autopilot/core/timeout-manager.js.map +1 -0
  159. package/dist/autopilot/git/branch-manager.d.ts +117 -0
  160. package/dist/autopilot/git/branch-manager.d.ts.map +1 -0
  161. package/dist/autopilot/git/branch-manager.js +238 -0
  162. package/dist/autopilot/git/branch-manager.js.map +1 -0
  163. package/dist/autopilot/git/index.d.ts +9 -0
  164. package/dist/autopilot/git/index.d.ts.map +1 -0
  165. package/dist/autopilot/git/index.js +9 -0
  166. package/dist/autopilot/git/index.js.map +1 -0
  167. package/dist/autopilot/git/merge-manager.d.ts +118 -0
  168. package/dist/autopilot/git/merge-manager.d.ts.map +1 -0
  169. package/dist/autopilot/git/merge-manager.js +304 -0
  170. package/dist/autopilot/git/merge-manager.js.map +1 -0
  171. package/dist/autopilot/git/worktree-manager.d.ts +128 -0
  172. package/dist/autopilot/git/worktree-manager.d.ts.map +1 -0
  173. package/dist/autopilot/git/worktree-manager.js +298 -0
  174. package/dist/autopilot/git/worktree-manager.js.map +1 -0
  175. package/dist/autopilot/index.d.ts +30 -0
  176. package/dist/autopilot/index.d.ts.map +1 -0
  177. package/dist/autopilot/index.js +55 -0
  178. package/dist/autopilot/index.js.map +1 -0
  179. package/dist/autopilot/sync/index.d.ts +7 -0
  180. package/dist/autopilot/sync/index.d.ts.map +1 -0
  181. package/dist/autopilot/sync/index.js +7 -0
  182. package/dist/autopilot/sync/index.js.map +1 -0
  183. package/dist/autopilot/sync/sync-manager.d.ts +168 -0
  184. package/dist/autopilot/sync/sync-manager.d.ts.map +1 -0
  185. package/dist/autopilot/sync/sync-manager.js +303 -0
  186. package/dist/autopilot/sync/sync-manager.js.map +1 -0
  187. package/dist/autopilot/types.d.ts +454 -0
  188. package/dist/autopilot/types.d.ts.map +1 -0
  189. package/dist/autopilot/types.js +26 -0
  190. package/dist/autopilot/types.js.map +1 -0
  191. package/dist/autopilot/utils/audit-logger.d.ts +176 -0
  192. package/dist/autopilot/utils/audit-logger.d.ts.map +1 -0
  193. package/dist/autopilot/utils/audit-logger.js +308 -0
  194. package/dist/autopilot/utils/audit-logger.js.map +1 -0
  195. package/dist/autopilot/utils/cost-tracker.d.ts +162 -0
  196. package/dist/autopilot/utils/cost-tracker.d.ts.map +1 -0
  197. package/dist/autopilot/utils/cost-tracker.js +269 -0
  198. package/dist/autopilot/utils/cost-tracker.js.map +1 -0
  199. package/dist/autopilot/utils/index.d.ts +9 -0
  200. package/dist/autopilot/utils/index.d.ts.map +1 -0
  201. package/dist/autopilot/utils/index.js +9 -0
  202. package/dist/autopilot/utils/index.js.map +1 -0
  203. package/dist/autopilot/utils/progress-reporter.d.ts +132 -0
  204. package/dist/autopilot/utils/progress-reporter.d.ts.map +1 -0
  205. package/dist/autopilot/utils/progress-reporter.js +290 -0
  206. package/dist/autopilot/utils/progress-reporter.js.map +1 -0
  207. package/dist/autopilot/worker/worker-pool.d.ts +179 -0
  208. package/dist/autopilot/worker/worker-pool.d.ts.map +1 -0
  209. package/dist/autopilot/worker/worker-pool.js +331 -0
  210. package/dist/autopilot/worker/worker-pool.js.map +1 -0
  211. package/dist/autopilot/worker/worker-session.d.ts +171 -0
  212. package/dist/autopilot/worker/worker-session.d.ts.map +1 -0
  213. package/dist/autopilot/worker/worker-session.js +295 -0
  214. package/dist/autopilot/worker/worker-session.js.map +1 -0
  215. package/dist/cli/index.d.ts +1 -1
  216. package/dist/cli/index.d.ts.map +1 -1
  217. package/dist/cli/index.js +4 -1
  218. package/dist/cli/index.js.map +1 -1
  219. package/dist/index.js +0 -1
  220. package/dist/index.js.map +1 -1
  221. package/dist/tools/core/epic.js +1 -1
  222. package/dist/tools/core/epic.js.map +1 -1
  223. package/dist/tools/core/lookup.d.ts.map +1 -1
  224. package/dist/tools/core/lookup.js +3 -2
  225. package/dist/tools/core/lookup.js.map +1 -1
  226. package/dist/tools/core/specification.js +1 -1
  227. package/dist/tools/core/specification.js.map +1 -1
  228. package/dist/tools/core/ticket.d.ts.map +1 -1
  229. package/dist/tools/core/ticket.js +4 -6
  230. package/dist/tools/core/ticket.js.map +1 -1
  231. package/dist/tools/index.d.ts.map +1 -1
  232. package/dist/tools/index.js +60 -0
  233. package/dist/tools/index.js.map +1 -1
  234. package/dist/validation/index.d.ts.map +1 -1
  235. package/dist/validation/index.js +4 -1
  236. package/dist/validation/index.js.map +1 -1
  237. package/package.json +8 -4
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Failure Handler
3
+ *
4
+ * Retry logic, systemic failure detection, and pause decisions.
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ import type { AutopilotConfig } from '../types.js';
8
+ /**
9
+ * Failure category
10
+ */
11
+ export type FailureCategory = 'transient' | 'rate_limit' | 'auth' | 'timeout' | 'validation' | 'implementation' | 'systemic' | 'unknown';
12
+ /**
13
+ * Failure info
14
+ */
15
+ export interface FailureInfo {
16
+ ticketId: string;
17
+ workerId: number;
18
+ error: string;
19
+ category: FailureCategory;
20
+ attempt: number;
21
+ timestamp: Date;
22
+ retryable: boolean;
23
+ retryAfterMs?: number;
24
+ }
25
+ /**
26
+ * Failure Handler Events
27
+ */
28
+ export interface FailureHandlerEvents {
29
+ 'failure:recorded': FailureInfo;
30
+ 'failure:systemic': {
31
+ count: number;
32
+ recentFailures: FailureInfo[];
33
+ };
34
+ 'failure:should_pause': {
35
+ reason: string;
36
+ };
37
+ 'failure:retry_scheduled': {
38
+ ticketId: string;
39
+ retryAfterMs: number;
40
+ };
41
+ }
42
+ /**
43
+ * Failure Handler
44
+ */
45
+ export declare class FailureHandler extends EventEmitter {
46
+ private failures;
47
+ private ticketAttempts;
48
+ private config;
49
+ constructor(config: AutopilotConfig | Partial<{
50
+ maxTicketRetries: number;
51
+ systemicThreshold: number;
52
+ systemicWindowMs: number;
53
+ }>);
54
+ /**
55
+ * Record a failure
56
+ */
57
+ recordFailure(info: Omit<FailureInfo, 'attempt' | 'timestamp' | 'retryable' | 'category'>): FailureInfo;
58
+ /**
59
+ * Categorize error message
60
+ */
61
+ private categorizeError;
62
+ /**
63
+ * Determine if failure is retryable
64
+ */
65
+ private isRetryable;
66
+ /**
67
+ * Calculate retry delay based on category and attempt
68
+ */
69
+ private calculateRetryDelay;
70
+ /**
71
+ * Detect systemic failures (many failures in short window)
72
+ * Excludes rate_limit failures as they are handled separately
73
+ */
74
+ private detectSystemicFailure;
75
+ /**
76
+ * Get attempt count for a ticket
77
+ */
78
+ getAttemptCount(ticketId: string): number;
79
+ /**
80
+ * Check if ticket should be retried
81
+ * Returns false if ticket has no recorded failures (nothing to retry)
82
+ */
83
+ shouldRetry(ticketId: string): boolean;
84
+ /**
85
+ * Get last failure for a ticket
86
+ */
87
+ getLastFailure(ticketId: string): FailureInfo | undefined;
88
+ /**
89
+ * Get all failures for a ticket
90
+ */
91
+ getTicketFailures(ticketId: string): FailureInfo[];
92
+ /**
93
+ * Clear failures for a ticket (e.g., after success)
94
+ */
95
+ clearTicketFailures(ticketId: string): void;
96
+ /**
97
+ * Get failure statistics
98
+ */
99
+ getStats(): {
100
+ totalFailures: number;
101
+ byCategory: Record<FailureCategory, number>;
102
+ recentCount: number;
103
+ uniqueTickets: number;
104
+ };
105
+ /**
106
+ * Check if should pause due to failures
107
+ */
108
+ shouldPause(): {
109
+ should: boolean;
110
+ reason?: string;
111
+ };
112
+ /**
113
+ * Reset all failure tracking
114
+ */
115
+ reset(): void;
116
+ /**
117
+ * Alias for reset - clear all failures
118
+ */
119
+ clearAll(): void;
120
+ /**
121
+ * Get total failure count
122
+ */
123
+ getFailureCount(): number;
124
+ /**
125
+ * Get failures within a time window
126
+ */
127
+ getRecentFailures(windowMs?: number): FailureInfo[];
128
+ /**
129
+ * Get failure rate (failures per minute) within a time window
130
+ */
131
+ getFailureRate(windowMs?: number): number;
132
+ /**
133
+ * Update configuration
134
+ */
135
+ updateConfig(updates: Partial<typeof this.config>): void;
136
+ }
137
+ /**
138
+ * Create a failure handler
139
+ */
140
+ export declare function createFailureHandler(config?: Partial<{
141
+ maxTicketRetries: number;
142
+ systemicThreshold: number;
143
+ systemicWindowMs: number;
144
+ }>): FailureHandler;
145
+ //# sourceMappingURL=failure-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-handler.d.ts","sourceRoot":"","sources":["../../../src/autopilot/core/failure-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,308 @@
1
+ /**
2
+ * Failure Handler
3
+ *
4
+ * Retry logic, systemic failure detection, and pause decisions.
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ /**
8
+ * Failure Handler
9
+ */
10
+ export class FailureHandler extends EventEmitter {
11
+ failures = [];
12
+ ticketAttempts = new Map();
13
+ config;
14
+ constructor(config) {
15
+ super();
16
+ this.config = {
17
+ maxTicketRetries: config?.maxTicketRetries ?? 2,
18
+ systemicThreshold: ('systemicThreshold' in config ? config.systemicThreshold : undefined) ?? 5,
19
+ systemicWindowMs: ('systemicWindowMs' in config ? config.systemicWindowMs : undefined) ?? 5 * 60 * 1000,
20
+ };
21
+ }
22
+ /**
23
+ * Record a failure
24
+ */
25
+ recordFailure(info) {
26
+ // Get current attempt count
27
+ const currentAttempt = (this.ticketAttempts.get(info.ticketId) || 0) + 1;
28
+ this.ticketAttempts.set(info.ticketId, currentAttempt);
29
+ // Categorize the failure
30
+ const category = this.categorizeError(info.error);
31
+ // Determine if retryable
32
+ const retryable = this.isRetryable(category, currentAttempt);
33
+ // Calculate retry delay if applicable
34
+ const retryAfterMs = retryable ? this.calculateRetryDelay(category, currentAttempt) : undefined;
35
+ const failure = {
36
+ ...info,
37
+ category,
38
+ attempt: currentAttempt,
39
+ timestamp: new Date(),
40
+ retryable,
41
+ retryAfterMs,
42
+ };
43
+ this.failures.push(failure);
44
+ this.emit('failure:recorded', failure);
45
+ // Check for systemic failures
46
+ if (this.detectSystemicFailure()) {
47
+ const recentFailures = this.getRecentFailures();
48
+ this.emit('failure:systemic', {
49
+ count: recentFailures.length,
50
+ recentFailures,
51
+ });
52
+ this.emit('failure:should_pause', {
53
+ reason: `Systemic failure detected: ${recentFailures.length} failures in last 5 minutes`,
54
+ });
55
+ }
56
+ // Schedule retry if applicable
57
+ if (retryable && retryAfterMs) {
58
+ this.emit('failure:retry_scheduled', {
59
+ ticketId: info.ticketId,
60
+ retryAfterMs,
61
+ });
62
+ }
63
+ return failure;
64
+ }
65
+ /**
66
+ * Categorize error message
67
+ */
68
+ categorizeError(error) {
69
+ const errorLower = error.toLowerCase();
70
+ // Rate limit
71
+ if (errorLower.includes('rate limit') ||
72
+ errorLower.includes('quota') ||
73
+ errorLower.includes('too many requests')) {
74
+ return 'rate_limit';
75
+ }
76
+ // Authentication
77
+ if (errorLower.includes('auth') ||
78
+ errorLower.includes('unauthorized') ||
79
+ errorLower.includes('not logged in')) {
80
+ return 'auth';
81
+ }
82
+ // Timeout
83
+ if (errorLower.includes('timeout') || errorLower.includes('timed out')) {
84
+ return 'timeout';
85
+ }
86
+ // Transient network errors
87
+ if (errorLower.includes('network') ||
88
+ errorLower.includes('econnrefused') ||
89
+ errorLower.includes('econnreset') ||
90
+ errorLower.includes('etimedout') ||
91
+ errorLower.includes('connection')) {
92
+ return 'transient';
93
+ }
94
+ // Validation failures (includes compilation errors)
95
+ if (errorLower.includes('test') ||
96
+ errorLower.includes('lint') ||
97
+ errorLower.includes('type error') ||
98
+ errorLower.includes('validation') ||
99
+ errorLower.includes('compile') ||
100
+ errorLower.includes('compilation')) {
101
+ return 'validation';
102
+ }
103
+ // Implementation errors (syntax, build failures)
104
+ if (errorLower.includes('syntax') ||
105
+ errorLower.includes('build')) {
106
+ return 'implementation';
107
+ }
108
+ return 'unknown';
109
+ }
110
+ /**
111
+ * Determine if failure is retryable
112
+ */
113
+ isRetryable(category, attempt) {
114
+ // Never retry auth failures
115
+ if (category === 'auth') {
116
+ return false;
117
+ }
118
+ // Check attempt count
119
+ if (attempt >= this.config.maxTicketRetries) {
120
+ return false;
121
+ }
122
+ // Transient and timeout are always retryable if under limit
123
+ if (category === 'transient' || category === 'timeout') {
124
+ return true;
125
+ }
126
+ // Rate limit is retryable after backoff
127
+ if (category === 'rate_limit') {
128
+ return true;
129
+ }
130
+ // Validation and implementation might be retried once
131
+ if (category === 'validation' || category === 'implementation') {
132
+ return attempt < 2;
133
+ }
134
+ // Unknown errors get one retry
135
+ return attempt < 2;
136
+ }
137
+ /**
138
+ * Calculate retry delay based on category and attempt
139
+ */
140
+ calculateRetryDelay(category, attempt) {
141
+ // Base delay with exponential backoff
142
+ const baseDelay = 1000; // 1 second
143
+ const maxDelay = 60000; // 1 minute
144
+ const exponentialDelay = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
145
+ // Add jitter (10%)
146
+ const jitter = exponentialDelay * 0.1 * Math.random();
147
+ // Category-specific adjustments
148
+ switch (category) {
149
+ case 'rate_limit':
150
+ // Rate limits need longer backoff
151
+ return Math.min(exponentialDelay * 2 + 30000, 5 * 60 * 1000);
152
+ case 'transient':
153
+ // Quick retry for transient errors
154
+ return exponentialDelay + jitter;
155
+ case 'timeout':
156
+ // Moderate delay for timeouts
157
+ return exponentialDelay * 1.5 + jitter;
158
+ default:
159
+ return exponentialDelay + jitter;
160
+ }
161
+ }
162
+ /**
163
+ * Detect systemic failures (many failures in short window)
164
+ * Excludes rate_limit failures as they are handled separately
165
+ */
166
+ detectSystemicFailure() {
167
+ const recentFailures = this.getRecentFailures();
168
+ // Exclude rate limit failures from systemic detection
169
+ const nonRateLimitFailures = recentFailures.filter(f => f.category !== 'rate_limit');
170
+ return nonRateLimitFailures.length >= this.config.systemicThreshold;
171
+ }
172
+ /**
173
+ * Get attempt count for a ticket
174
+ */
175
+ getAttemptCount(ticketId) {
176
+ return this.ticketAttempts.get(ticketId) || 0;
177
+ }
178
+ /**
179
+ * Check if ticket should be retried
180
+ * Returns false if ticket has no recorded failures (nothing to retry)
181
+ */
182
+ shouldRetry(ticketId) {
183
+ const attempts = this.getAttemptCount(ticketId);
184
+ // Must have at least one failure to retry, and be under the retry limit
185
+ if (attempts === 0) {
186
+ return false;
187
+ }
188
+ // Also check if the last failure was marked as retryable
189
+ const lastFailure = this.getLastFailure(ticketId);
190
+ return lastFailure?.retryable ?? false;
191
+ }
192
+ /**
193
+ * Get last failure for a ticket
194
+ */
195
+ getLastFailure(ticketId) {
196
+ const ticketFailures = this.failures.filter(f => f.ticketId === ticketId);
197
+ return ticketFailures[ticketFailures.length - 1];
198
+ }
199
+ /**
200
+ * Get all failures for a ticket
201
+ */
202
+ getTicketFailures(ticketId) {
203
+ return this.failures.filter(f => f.ticketId === ticketId);
204
+ }
205
+ /**
206
+ * Clear failures for a ticket (e.g., after success)
207
+ */
208
+ clearTicketFailures(ticketId) {
209
+ this.failures = this.failures.filter(f => f.ticketId !== ticketId);
210
+ this.ticketAttempts.delete(ticketId);
211
+ }
212
+ /**
213
+ * Get failure statistics
214
+ */
215
+ getStats() {
216
+ const byCategory = {
217
+ transient: 0,
218
+ rate_limit: 0,
219
+ auth: 0,
220
+ timeout: 0,
221
+ validation: 0,
222
+ implementation: 0,
223
+ systemic: 0,
224
+ unknown: 0,
225
+ };
226
+ const uniqueTickets = new Set();
227
+ for (const failure of this.failures) {
228
+ byCategory[failure.category]++;
229
+ uniqueTickets.add(failure.ticketId);
230
+ }
231
+ return {
232
+ totalFailures: this.failures.length,
233
+ byCategory,
234
+ recentCount: this.getRecentFailures().length,
235
+ uniqueTickets: uniqueTickets.size,
236
+ };
237
+ }
238
+ /**
239
+ * Check if should pause due to failures
240
+ */
241
+ shouldPause() {
242
+ // Check for auth failure - always pause
243
+ const authFailures = this.failures.filter(f => f.category === 'auth');
244
+ if (authFailures.length > 0) {
245
+ return { should: true, reason: 'Authentication failure' };
246
+ }
247
+ // Check for rate limit
248
+ const rateLimitFailures = this.getRecentFailures().filter(f => f.category === 'rate_limit');
249
+ if (rateLimitFailures.length >= 2) {
250
+ return { should: true, reason: 'Rate limit hit multiple times' };
251
+ }
252
+ // Check for systemic failure
253
+ if (this.detectSystemicFailure()) {
254
+ return {
255
+ should: true,
256
+ reason: `Systemic failure: ${this.getRecentFailures().length} failures in 5 minutes`,
257
+ };
258
+ }
259
+ return { should: false };
260
+ }
261
+ /**
262
+ * Reset all failure tracking
263
+ */
264
+ reset() {
265
+ this.failures = [];
266
+ this.ticketAttempts.clear();
267
+ }
268
+ /**
269
+ * Alias for reset - clear all failures
270
+ */
271
+ clearAll() {
272
+ this.reset();
273
+ }
274
+ /**
275
+ * Get total failure count
276
+ */
277
+ getFailureCount() {
278
+ return this.failures.length;
279
+ }
280
+ /**
281
+ * Get failures within a time window
282
+ */
283
+ getRecentFailures(windowMs = this.config.systemicWindowMs) {
284
+ const cutoff = Date.now() - windowMs;
285
+ return this.failures.filter(f => f.timestamp.getTime() > cutoff);
286
+ }
287
+ /**
288
+ * Get failure rate (failures per minute) within a time window
289
+ */
290
+ getFailureRate(windowMs = this.config.systemicWindowMs) {
291
+ const recentFailures = this.getRecentFailures(windowMs);
292
+ const windowMinutes = windowMs / (60 * 1000);
293
+ return recentFailures.length / windowMinutes;
294
+ }
295
+ /**
296
+ * Update configuration
297
+ */
298
+ updateConfig(updates) {
299
+ Object.assign(this.config, updates);
300
+ }
301
+ }
302
+ /**
303
+ * Create a failure handler
304
+ */
305
+ export function createFailureHandler(config) {
306
+ return new FailureHandler(config ?? {});
307
+ }
308
+ //# sourceMappingURL=failure-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"failure-handler.js","sourceRoot":"","sources":["../../../src/autopilot/core/failure-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAwCtC;;GAEG;AACH,MAAM,OAAO,cAAe,SAAQ,YAAY;IACtC,QAAQ,GAAkB,EAAE,CAAC;IAC7B,cAAc,GAAwB,IAAI,GAAG,EAAE,CAAC;IAChD,MAAM,CAIZ;IAEF,YAAY,MAIV;QACA,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG;YACZ,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,IAAI,CAAC;YAC/C,iBAAiB,EAAE,CAAC,mBAAmB,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;YAC9F,gBAAgB,EAAE,CAAC,kBAAkB,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI;SACxG,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,IAA2E;QACvF,4BAA4B;QAC5B,MAAM,cAAc,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACzE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAEvD,yBAAyB;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAElD,yBAAyB;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAE7D,sCAAsC;QACtC,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAEhG,MAAM,OAAO,GAAgB;YAC3B,GAAG,IAAI;YACP,QAAQ;YACR,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,SAAS;YACT,YAAY;SACb,CAAC;QAEF,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;QAEvC,8BAA8B;QAC9B,IAAI,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;YACjC,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE;gBAC5B,KAAK,EAAE,cAAc,CAAC,MAAM;gBAC5B,cAAc;aACf,CAAC,CAAC;YACH,IAAI,CAAC,IAAI,CAAC,sBAAsB,EAAE;gBAChC,MAAM,EAAE,8BAA8B,cAAc,CAAC,MAAM,6BAA6B;aACzF,CAAC,CAAC;QACL,CAAC;QAED,+BAA+B;QAC/B,IAAI,SAAS,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE;gBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,YAAY;aACb,CAAC,CAAC;QACL,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,KAAa;QACnC,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QAEvC,aAAa;QACb,IACE,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;YACjC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC5B,UAAU,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EACxC,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,iBAAiB;QACjB,IACE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC3B,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC;YACnC,UAAU,CAAC,QAAQ,CAAC,eAAe,CAAC,EACpC,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,UAAU;QACV,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACvE,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,2BAA2B;QAC3B,IACE,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC9B,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC;YACnC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;YACjC,UAAU,CAAC,QAAQ,CAAC,WAAW,CAAC;YAChC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,EACjC,CAAC;YACD,OAAO,WAAW,CAAC;QACrB,CAAC;QAED,oDAAoD;QACpD,IACE,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC3B,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC3B,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;YACjC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC;YACjC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC9B,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAClC,CAAC;YACD,OAAO,YAAY,CAAC;QACtB,CAAC;QAED,iDAAiD;QACjD,IACE,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC7B,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAC5B,CAAC;YACD,OAAO,gBAAgB,CAAC;QAC1B,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,QAAyB,EAAE,OAAe;QAC5D,4BAA4B;QAC5B,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,sBAAsB;QACtB,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;QAED,4DAA4D;QAC5D,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACvD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,wCAAwC;QACxC,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,sDAAsD;QACtD,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;YAC/D,OAAO,OAAO,GAAG,CAAC,CAAC;QACrB,CAAC;QAED,+BAA+B;QAC/B,OAAO,OAAO,GAAG,CAAC,CAAC;IACrB,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,QAAyB,EAAE,OAAe;QACpE,sCAAsC;QACtC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,WAAW;QACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,WAAW;QACnC,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAElF,mBAAmB;QACnB,MAAM,MAAM,GAAG,gBAAgB,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAEtD,gCAAgC;QAChC,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,YAAY;gBACf,kCAAkC;gBAClC,OAAO,IAAI,CAAC,GAAG,CAAC,gBAAgB,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YAE/D,KAAK,WAAW;gBACd,mCAAmC;gBACnC,OAAO,gBAAgB,GAAG,MAAM,CAAC;YAEnC,KAAK,SAAS;gBACZ,8BAA8B;gBAC9B,OAAO,gBAAgB,GAAG,GAAG,GAAG,MAAM,CAAC;YAEzC;gBACE,OAAO,gBAAgB,GAAG,MAAM,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,qBAAqB;QAC3B,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAChD,sDAAsD;QACtD,MAAM,oBAAoB,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC;QACrF,OAAO,oBAAoB,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,QAAgB;QAC9B,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED;;;OAGG;IACH,WAAW,CAAC,QAAgB;QAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;QAChD,wEAAwE;QACxE,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACnB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,yDAAyD;QACzD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClD,OAAO,WAAW,EAAE,SAAS,IAAI,KAAK,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,QAAgB;QAC7B,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QAC1E,OAAO,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,QAAgB;QAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACnE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,QAAQ;QAMN,MAAM,UAAU,GAAoC;YAClD,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,CAAC;YACV,UAAU,EAAE,CAAC;YACb,cAAc,EAAE,CAAC;YACjB,QAAQ,EAAE,CAAC;YACX,OAAO,EAAE,CAAC;SACX,CAAC;QAEF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QAExC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;QAED,OAAO;YACL,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM;YACnC,UAAU;YACV,WAAW,EAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM;YAC5C,aAAa,EAAE,aAAa,CAAC,IAAI;SAClC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,WAAW;QACT,wCAAwC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC;QACtE,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QAC5D,CAAC;QAED,uBAAuB;QACvB,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,CACvD,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CACjC,CAAC;QACF,IAAI,iBAAiB,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;QACnE,CAAC;QAED,6BAA6B;QAC7B,IAAI,IAAI,CAAC,qBAAqB,EAAE,EAAE,CAAC;YACjC,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,qBAAqB,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,wBAAwB;aACrF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;IAC9B,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,WAAmB,IAAI,CAAC,MAAM,CAAC,gBAAgB;QAC/D,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,WAAmB,IAAI,CAAC,MAAM,CAAC,gBAAgB;QAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,aAAa,GAAG,QAAQ,GAAG,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,OAAO,cAAc,CAAC,MAAM,GAAG,aAAa,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,OAAoC;QAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;CACF;AAGD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAInC;IACA,OAAO,IAAI,cAAc,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Rate Limit Handler
3
+ *
4
+ * Handles rate limit events from AI Provider and pauses workers.
5
+ */
6
+ import { EventEmitter } from 'events';
7
+ import type { RateLimitInfo } from '../types.js';
8
+ /**
9
+ * Rate Limit Handler Events
10
+ */
11
+ export interface RateLimitHandlerEvents {
12
+ 'rate_limit:detected': RateLimitInfo;
13
+ 'rate_limit:cleared': void;
14
+ 'rate_limit:workers_should_pause': void;
15
+ 'rate_limit:workers_can_resume': void;
16
+ }
17
+ /**
18
+ * Rate Limit Handler
19
+ */
20
+ export declare class RateLimitHandler extends EventEmitter {
21
+ private isRateLimited;
22
+ private rateLimitInfo?;
23
+ private autoResumeTimeout?;
24
+ private resumeCheckInterval?;
25
+ private subscribed;
26
+ /**
27
+ * Default backoff time when rate limited (5 minutes)
28
+ */
29
+ private backoffMs;
30
+ /**
31
+ * Bound event handlers (stored to enable proper unsubscription)
32
+ */
33
+ private boundHandleRateLimitHit;
34
+ private boundHandleRateLimitCleared;
35
+ /**
36
+ * Subscribe to AI Provider rate limit events
37
+ */
38
+ subscribe(): void;
39
+ /**
40
+ * Unsubscribe from AI Provider events
41
+ */
42
+ unsubscribe(): void;
43
+ /**
44
+ * Handle rate limit hit event
45
+ */
46
+ private handleRateLimitHit;
47
+ /**
48
+ * Handle rate limit cleared event
49
+ */
50
+ private handleRateLimitCleared;
51
+ /**
52
+ * Schedule a check to see if we can resume
53
+ */
54
+ private scheduleResumeCheck;
55
+ /**
56
+ * Attempt to resume after backoff
57
+ */
58
+ private attemptResume;
59
+ /**
60
+ * Clear rate limit state
61
+ */
62
+ clearRateLimit(): void;
63
+ /**
64
+ * Clear all timers
65
+ */
66
+ private clearTimers;
67
+ /**
68
+ * Manually trigger rate limit (e.g., from failure detection)
69
+ */
70
+ triggerRateLimit(message: string, backoffMs?: number): void;
71
+ /**
72
+ * Check if currently rate limited
73
+ */
74
+ isCurrentlyRateLimited(): boolean;
75
+ /**
76
+ * Get rate limit info
77
+ */
78
+ getRateLimitInfo(): RateLimitInfo | undefined;
79
+ /**
80
+ * Get estimated time until resume
81
+ */
82
+ getEstimatedResumeTime(): Date | undefined;
83
+ /**
84
+ * Get remaining backoff time in ms
85
+ */
86
+ getRemainingBackoffMs(): number;
87
+ /**
88
+ * Update backoff duration
89
+ */
90
+ setBackoffMs(ms: number): void;
91
+ /**
92
+ * Get backoff duration
93
+ */
94
+ getBackoffMs(): number;
95
+ /**
96
+ * Force resume (skip backoff)
97
+ */
98
+ forceResume(): void;
99
+ /**
100
+ * Destroy handler and cleanup
101
+ */
102
+ destroy(): void;
103
+ }
104
+ /**
105
+ * Create a rate limit handler instance
106
+ */
107
+ export declare function createRateLimitHandler(): RateLimitHandler;
108
+ //# sourceMappingURL=rate-limit-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-handler.d.ts","sourceRoot":"","sources":["../../../src/autopilot/core/rate-limit-handler.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,EAAE,aAAa,CAAC;IACrC,oBAAoB,EAAE,IAAI,CAAC;IAC3B,iCAAiC,EAAE,IAAI,CAAC;IACxC,+BAA+B,EAAE,IAAI,CAAC;CACvC;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAiB;IAC3C,OAAO,CAAC,mBAAmB,CAAC,CAAiB;IAC7C,OAAO,CAAC,UAAU,CAAkB;IAEpC;;OAEG;IACH,OAAO,CAAC,SAAS,CAAyB;IAE1C;;OAEG;IACH,OAAO,CAAC,uBAAuB,CAAsC;IACrE,OAAO,CAAC,2BAA2B,CAA0C;IAE7E;;OAEG;IACH,SAAS,IAAI,IAAI;IASjB;;OAEG;IACH,WAAW,IAAI,IAAI;IAUnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAI9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiB3B;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,cAAc,IAAI,IAAI;IAatB;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAW3D;;OAEG;IACH,sBAAsB,IAAI,OAAO;IAIjC;;OAEG;IACH,gBAAgB,IAAI,aAAa,GAAG,SAAS;IAI7C;;OAEG;IACH,sBAAsB,IAAI,IAAI,GAAG,SAAS;IAI1C;;OAEG;IACH,qBAAqB,IAAI,MAAM;IAO/B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI9B;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,OAAO,IAAI,IAAI;CAOhB;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,gBAAgB,CAEzD"}