nexus-agents 2.29.0 → 2.29.2

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 (112) hide show
  1. package/dist/adaptive-memory-5VP5WWTE.js +15 -0
  2. package/dist/chunk-5COIDGQJ.js +1585 -0
  3. package/dist/chunk-5COIDGQJ.js.map +1 -0
  4. package/dist/{chunk-HWDBNDUX.js → chunk-63AJLNKU.js} +2 -2
  5. package/dist/chunk-66NNHMVB.js +195 -0
  6. package/dist/chunk-66NNHMVB.js.map +1 -0
  7. package/dist/chunk-AP2FD37C.js +127 -0
  8. package/dist/chunk-AP2FD37C.js.map +1 -0
  9. package/dist/chunk-BC3M4VLP.js +359 -0
  10. package/dist/chunk-BC3M4VLP.js.map +1 -0
  11. package/dist/chunk-BQ4YXGGQ.js +127 -0
  12. package/dist/chunk-BQ4YXGGQ.js.map +1 -0
  13. package/dist/{chunk-ZBZJHXRT.js → chunk-CW2Z773T.js} +19 -347
  14. package/dist/chunk-CW2Z773T.js.map +1 -0
  15. package/dist/chunk-DDQGAVQA.js +944 -0
  16. package/dist/chunk-DDQGAVQA.js.map +1 -0
  17. package/dist/chunk-ED6VQWNG.js +63 -0
  18. package/dist/chunk-ED6VQWNG.js.map +1 -0
  19. package/dist/{chunk-7F6HYUIY.js → chunk-EPMBGZQX.js} +16 -97
  20. package/dist/chunk-EPMBGZQX.js.map +1 -0
  21. package/dist/chunk-GX436VRU.js +931 -0
  22. package/dist/chunk-GX436VRU.js.map +1 -0
  23. package/dist/{chunk-IMWYKX4H.js → chunk-HSOPD265.js} +444 -399
  24. package/dist/chunk-HSOPD265.js.map +1 -0
  25. package/dist/{chunk-S3BKWNST.js → chunk-J245RJGW.js} +680 -1436
  26. package/dist/chunk-J245RJGW.js.map +1 -0
  27. package/dist/{chunk-I6YDS23R.js → chunk-KQIDTE52.js} +2 -2
  28. package/dist/{chunk-POBO4G2P.js → chunk-LDIN2PLV.js} +250 -110
  29. package/dist/chunk-LDIN2PLV.js.map +1 -0
  30. package/dist/{chunk-KGDG6PWZ.js → chunk-LKDHAJJB.js} +2 -2
  31. package/dist/{chunk-T7PU3NPQ.js → chunk-NKGTEJYU.js} +7 -5
  32. package/dist/{chunk-T7PU3NPQ.js.map → chunk-NKGTEJYU.js.map} +1 -1
  33. package/dist/chunk-QGODFK36.js +122 -0
  34. package/dist/chunk-QGODFK36.js.map +1 -0
  35. package/dist/{chunk-DAMRMAM2.js → chunk-QSNAFOE6.js} +12369 -14499
  36. package/dist/chunk-QSNAFOE6.js.map +1 -0
  37. package/dist/chunk-TL2GJMJ5.js +700 -0
  38. package/dist/chunk-TL2GJMJ5.js.map +1 -0
  39. package/dist/{chunk-WSK4VSXP.js → chunk-V6MSPUQF.js} +2 -2
  40. package/dist/chunk-VZ2YOQWU.js +90 -0
  41. package/dist/chunk-VZ2YOQWU.js.map +1 -0
  42. package/dist/{chunk-5VZLXMO7.js → chunk-WSYJN7BI.js} +7 -6
  43. package/dist/chunk-WSYJN7BI.js.map +1 -0
  44. package/dist/chunk-Y477EGI4.js +356 -0
  45. package/dist/chunk-Y477EGI4.js.map +1 -0
  46. package/dist/{chunk-HH5LVGEE.js → chunk-Z4OZ25VS.js} +4 -4
  47. package/dist/cli-circuit-breaker-6EJO3PPU.js +13 -0
  48. package/dist/cli.js +123 -68
  49. package/dist/cli.js.map +1 -1
  50. package/dist/codebase-search-CZUA37RU.js +9 -0
  51. package/dist/{composite-router-YPRWVTRB.js → composite-router-JD7URTC2.js} +2 -2
  52. package/dist/{consensus-vote-DBE6RNZG.js → consensus-vote-COW34Q2Y.js} +7 -5
  53. package/dist/{dist-7PQR2BQB.js → dist-CV74KUT7.js} +1302 -805
  54. package/dist/dist-CV74KUT7.js.map +1 -0
  55. package/dist/{doctor-deep-AWE7SRU6.js → doctor-deep-4A4X5X6U.js} +3 -3
  56. package/dist/expert-bridge-J36C7VES.js +10 -0
  57. package/dist/{expert-config-FHNBQRX2.js → expert-config-MQ5OJE3U.js} +2 -2
  58. package/dist/{factory-O5C7ZBZO.js → factory-4Z4RSUYE.js} +5 -4
  59. package/dist/{factory-PCHGQ3ZG.js → factory-NHORX63J.js} +4 -3
  60. package/dist/index.d.ts +507 -42
  61. package/dist/index.js +331 -78
  62. package/dist/index.js.map +1 -1
  63. package/dist/issue-triage-TIG3RKXF.js +15 -0
  64. package/dist/{mcp-config-AUZQPUBY.js → mcp-config-ETY7GFGW.js} +3 -3
  65. package/dist/mobimem-5PAAMVFR.js +13 -0
  66. package/dist/mobimem-5PAAMVFR.js.map +1 -0
  67. package/dist/repo-analyze-HWMXSK5C.js +24 -0
  68. package/dist/repo-analyze-HWMXSK5C.js.map +1 -0
  69. package/dist/repo-security-plan-KQB3ZJTE.js +17 -0
  70. package/dist/repo-security-plan-KQB3ZJTE.js.map +1 -0
  71. package/dist/research-helpers-synthesize-ZMERZZ5B.js +10 -0
  72. package/dist/research-helpers-synthesize-ZMERZZ5B.js.map +1 -0
  73. package/dist/{routing-memory-QY3XMU2R.js → routing-memory-3ES3OHLM.js} +2 -2
  74. package/dist/routing-memory-3ES3OHLM.js.map +1 -0
  75. package/dist/{session-memory-3MBCE5KS.js → session-memory-E2OE2CYR.js} +3 -3
  76. package/dist/session-memory-E2OE2CYR.js.map +1 -0
  77. package/dist/{setup-command-IQ4MD3FT.js → setup-command-CMCQRBJF.js} +7 -6
  78. package/dist/setup-command-CMCQRBJF.js.map +1 -0
  79. package/dist/{setup-config-5YUPLDXF.js → setup-config-KITOPV7V.js} +3 -3
  80. package/dist/setup-config-KITOPV7V.js.map +1 -0
  81. package/dist/shared-memory-AEO2HJLC.js +8 -0
  82. package/dist/shared-memory-AEO2HJLC.js.map +1 -0
  83. package/dist/symbol-extractor-UEBANFSN.js +10 -0
  84. package/dist/symbol-extractor-UEBANFSN.js.map +1 -0
  85. package/dist/{weather-report-CC2C4KAX.js → weather-report-KUSVNXDZ.js} +2 -2
  86. package/dist/weather-report-KUSVNXDZ.js.map +1 -0
  87. package/package.json +14 -13
  88. package/dist/chunk-5VZLXMO7.js.map +0 -1
  89. package/dist/chunk-7F6HYUIY.js.map +0 -1
  90. package/dist/chunk-DAMRMAM2.js.map +0 -1
  91. package/dist/chunk-IMWYKX4H.js.map +0 -1
  92. package/dist/chunk-POBO4G2P.js.map +0 -1
  93. package/dist/chunk-S3BKWNST.js.map +0 -1
  94. package/dist/chunk-ZBZJHXRT.js.map +0 -1
  95. package/dist/dist-7PQR2BQB.js.map +0 -1
  96. /package/dist/{composite-router-YPRWVTRB.js.map → adaptive-memory-5VP5WWTE.js.map} +0 -0
  97. /package/dist/{chunk-HWDBNDUX.js.map → chunk-63AJLNKU.js.map} +0 -0
  98. /package/dist/{chunk-I6YDS23R.js.map → chunk-KQIDTE52.js.map} +0 -0
  99. /package/dist/{chunk-KGDG6PWZ.js.map → chunk-LKDHAJJB.js.map} +0 -0
  100. /package/dist/{chunk-WSK4VSXP.js.map → chunk-V6MSPUQF.js.map} +0 -0
  101. /package/dist/{chunk-HH5LVGEE.js.map → chunk-Z4OZ25VS.js.map} +0 -0
  102. /package/dist/{consensus-vote-DBE6RNZG.js.map → cli-circuit-breaker-6EJO3PPU.js.map} +0 -0
  103. /package/dist/{doctor-deep-AWE7SRU6.js.map → codebase-search-CZUA37RU.js.map} +0 -0
  104. /package/dist/{expert-config-FHNBQRX2.js.map → composite-router-JD7URTC2.js.map} +0 -0
  105. /package/dist/{factory-O5C7ZBZO.js.map → consensus-vote-COW34Q2Y.js.map} +0 -0
  106. /package/dist/{factory-PCHGQ3ZG.js.map → doctor-deep-4A4X5X6U.js.map} +0 -0
  107. /package/dist/{mcp-config-AUZQPUBY.js.map → expert-bridge-J36C7VES.js.map} +0 -0
  108. /package/dist/{routing-memory-QY3XMU2R.js.map → expert-config-MQ5OJE3U.js.map} +0 -0
  109. /package/dist/{session-memory-3MBCE5KS.js.map → factory-4Z4RSUYE.js.map} +0 -0
  110. /package/dist/{setup-command-IQ4MD3FT.js.map → factory-NHORX63J.js.map} +0 -0
  111. /package/dist/{setup-config-5YUPLDXF.js.map → issue-triage-TIG3RKXF.js.map} +0 -0
  112. /package/dist/{weather-report-CC2C4KAX.js.map → mcp-config-ETY7GFGW.js.map} +0 -0
@@ -0,0 +1,356 @@
1
+ import {
2
+ ErrorCode,
3
+ NexusError,
4
+ err,
5
+ getErrorMessage,
6
+ getTimeProvider,
7
+ ok
8
+ } from "./chunk-HSOPD265.js";
9
+
10
+ // src/cli-adapters/circuit-breaker-types.ts
11
+ var CircuitErrorCode = {
12
+ CIRCUIT_OPEN: "CIRCUIT_OPEN",
13
+ CIRCUIT_HALF_OPEN_REJECTED: "CIRCUIT_HALF_OPEN_REJECTED",
14
+ EXECUTION_FAILED: "EXECUTION_FAILED"
15
+ };
16
+ var CircuitError = class extends NexusError {
17
+ circuitErrorCode;
18
+ cliName;
19
+ circuitState;
20
+ failureCategory;
21
+ constructor(message, options) {
22
+ const baseOptions = {
23
+ code: ErrorCode.INTERNAL_ERROR,
24
+ context: {
25
+ circuitErrorCode: options.circuitErrorCode,
26
+ cliName: options.cliName,
27
+ circuitState: options.circuitState
28
+ }
29
+ };
30
+ if (options.cause !== void 0) {
31
+ baseOptions.cause = options.cause;
32
+ }
33
+ if (options.failureCategory !== void 0) {
34
+ baseOptions.context["failureCategory"] = options.failureCategory;
35
+ }
36
+ super(message, baseOptions);
37
+ this.name = "CircuitError";
38
+ this.circuitErrorCode = options.circuitErrorCode;
39
+ this.cliName = options.cliName;
40
+ this.circuitState = options.circuitState;
41
+ if (options.failureCategory !== void 0) {
42
+ this.failureCategory = options.failureCategory;
43
+ }
44
+ }
45
+ };
46
+ var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
47
+ failureThreshold: 5,
48
+ resetTimeoutMs: 3e4,
49
+ halfOpenSuccessThreshold: 2,
50
+ countTimeoutsAsFailures: true,
51
+ countAuthFailuresAsFailures: false,
52
+ countRateLimitsAsFailures: true,
53
+ halfOpenMaxRequests: 3
54
+ };
55
+ var TIMEOUT_PATTERNS = ["timeout", "timed out"];
56
+ var AUTH_PATTERNS = ["auth", "unauthorized", "forbidden", "oauth"];
57
+ var RATE_LIMIT_PATTERNS = ["rate limit", "too many requests", "429"];
58
+ var CONNECTION_PATTERNS = [
59
+ "connection",
60
+ "econnrefused",
61
+ "enotfound",
62
+ "mcp",
63
+ "eaddrinuse",
64
+ "address already in use"
65
+ ];
66
+ var CRASH_PATTERNS = ["crash", "exited", "killed", "sigterm", "sigkill"];
67
+ function matchesPatterns(text, patterns) {
68
+ return patterns.some((pattern) => text.includes(pattern));
69
+ }
70
+ function categorizeError(error) {
71
+ if (!(error instanceof Error)) {
72
+ return "unknown";
73
+ }
74
+ const message = error.message.toLowerCase();
75
+ const name = error.name.toLowerCase();
76
+ const combined = `${message} ${name}`;
77
+ if (matchesPatterns(combined, TIMEOUT_PATTERNS)) return "timeout";
78
+ if (matchesPatterns(combined, AUTH_PATTERNS)) return "authentication";
79
+ if (matchesPatterns(combined, RATE_LIMIT_PATTERNS)) return "rate_limit";
80
+ if (matchesPatterns(combined, CONNECTION_PATTERNS)) return "connection";
81
+ if (matchesPatterns(combined, CRASH_PATTERNS)) return "crash";
82
+ return "unknown";
83
+ }
84
+
85
+ // src/cli-adapters/circuit-breaker.ts
86
+ var CliCircuitBreaker = class {
87
+ constructor(cliName, config = DEFAULT_CIRCUIT_BREAKER_CONFIG) {
88
+ this.cliName = cliName;
89
+ this.config = config;
90
+ this.lastStateChange = getTimeProvider().now();
91
+ }
92
+ state = "closed";
93
+ failureCount = 0;
94
+ successCount = 0;
95
+ lastFailureTime = null;
96
+ lastStateChange;
97
+ halfOpenRequests = 0;
98
+ listeners = /* @__PURE__ */ new Set();
99
+ /**
100
+ * Executes a function with circuit breaker protection.
101
+ */
102
+ async execute(fn) {
103
+ const canExecute = this.canExecute();
104
+ if (!canExecute.ok) {
105
+ return canExecute;
106
+ }
107
+ try {
108
+ const result = await fn();
109
+ this.onSuccess();
110
+ return ok(result);
111
+ } catch (error) {
112
+ const category = categorizeError(error);
113
+ if (this.shouldCountFailure(category)) {
114
+ this.onFailure(category);
115
+ }
116
+ return err(this.createExecutionError(error, category));
117
+ }
118
+ }
119
+ getState() {
120
+ this.checkStateTransition();
121
+ return this.state;
122
+ }
123
+ getSnapshot() {
124
+ this.checkStateTransition();
125
+ return {
126
+ state: this.state,
127
+ failureCount: this.failureCount,
128
+ successCount: this.successCount,
129
+ lastFailureTime: this.lastFailureTime,
130
+ lastStateChange: this.lastStateChange,
131
+ halfOpenRequests: this.halfOpenRequests,
132
+ config: this.config
133
+ };
134
+ }
135
+ reset() {
136
+ const previousState = this.state;
137
+ this.state = "closed";
138
+ this.failureCount = 0;
139
+ this.successCount = 0;
140
+ this.lastFailureTime = null;
141
+ this.halfOpenRequests = 0;
142
+ this.lastStateChange = getTimeProvider().now();
143
+ if (previousState !== "closed") {
144
+ this.emitStateChange(previousState, "closed", "Manual reset");
145
+ }
146
+ }
147
+ recordFailure(category) {
148
+ if (this.shouldCountFailure(category)) {
149
+ this.onFailure(category);
150
+ }
151
+ }
152
+ recordSuccess() {
153
+ this.onSuccess();
154
+ }
155
+ addStateChangeListener(listener) {
156
+ this.listeners.add(listener);
157
+ }
158
+ removeStateChangeListener(listener) {
159
+ this.listeners.delete(listener);
160
+ }
161
+ // -------------------------------------------------------------------------
162
+ // Private Methods
163
+ // -------------------------------------------------------------------------
164
+ canExecute() {
165
+ this.checkStateTransition();
166
+ if (this.state === "closed") {
167
+ return ok(true);
168
+ }
169
+ if (this.state === "open") {
170
+ return err(
171
+ new CircuitError(`Circuit is open for CLI: ${this.cliName}`, {
172
+ circuitErrorCode: CircuitErrorCode.CIRCUIT_OPEN,
173
+ cliName: this.cliName,
174
+ circuitState: this.state
175
+ })
176
+ );
177
+ }
178
+ if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {
179
+ return err(
180
+ new CircuitError(`Circuit half-open request limit reached for CLI: ${this.cliName}`, {
181
+ circuitErrorCode: CircuitErrorCode.CIRCUIT_HALF_OPEN_REJECTED,
182
+ cliName: this.cliName,
183
+ circuitState: this.state
184
+ })
185
+ );
186
+ }
187
+ this.halfOpenRequests++;
188
+ return ok(true);
189
+ }
190
+ checkStateTransition() {
191
+ if (this.state === "open" && this.lastFailureTime !== null) {
192
+ const elapsed = getTimeProvider().now() - this.lastFailureTime;
193
+ if (elapsed >= this.config.resetTimeoutMs) {
194
+ this.transitionTo("half-open", "Reset timeout elapsed");
195
+ }
196
+ }
197
+ }
198
+ onSuccess() {
199
+ if (this.state === "closed") {
200
+ this.failureCount = 0;
201
+ } else if (this.state === "half-open") {
202
+ this.successCount++;
203
+ if (this.successCount >= this.config.halfOpenSuccessThreshold) {
204
+ const reason = `${String(this.successCount)} consecutive successes in half-open state`;
205
+ this.transitionTo("closed", reason);
206
+ }
207
+ }
208
+ }
209
+ onFailure(category) {
210
+ this.failureCount++;
211
+ this.lastFailureTime = getTimeProvider().now();
212
+ if (this.state === "closed" && this.failureCount >= this.config.failureThreshold) {
213
+ const reason = `Failure threshold (${String(this.config.failureThreshold)}) exceeded`;
214
+ this.transitionTo("open", reason);
215
+ } else if (this.state === "half-open") {
216
+ this.transitionTo("open", `Failure during half-open recovery (category: ${category})`);
217
+ }
218
+ }
219
+ transitionTo(newState, reason) {
220
+ const previousState = this.state;
221
+ this.state = newState;
222
+ this.lastStateChange = getTimeProvider().now();
223
+ if (newState === "closed") {
224
+ this.failureCount = 0;
225
+ this.successCount = 0;
226
+ this.halfOpenRequests = 0;
227
+ } else if (newState === "half-open") {
228
+ this.successCount = 0;
229
+ this.halfOpenRequests = 0;
230
+ }
231
+ this.emitStateChange(previousState, newState, reason);
232
+ }
233
+ emitStateChange(previousState, newState, reason) {
234
+ const event = {
235
+ cliName: this.cliName,
236
+ previousState,
237
+ newState,
238
+ timestamp: this.lastStateChange,
239
+ failureCount: this.failureCount,
240
+ reason
241
+ };
242
+ for (const listener of this.listeners) {
243
+ try {
244
+ listener(event);
245
+ } catch {
246
+ }
247
+ }
248
+ }
249
+ shouldCountFailure(category) {
250
+ if (category === "timeout") return this.config.countTimeoutsAsFailures;
251
+ if (category === "authentication") return this.config.countAuthFailuresAsFailures;
252
+ if (category === "rate_limit") return this.config.countRateLimitsAsFailures;
253
+ return true;
254
+ }
255
+ createExecutionError(error, category) {
256
+ const message = getErrorMessage(error);
257
+ const cause = error instanceof Error ? error : new Error(String(error));
258
+ return new CircuitError(`CLI execution failed: ${message}`, {
259
+ circuitErrorCode: CircuitErrorCode.EXECUTION_FAILED,
260
+ cliName: this.cliName,
261
+ circuitState: this.state,
262
+ failureCategory: category,
263
+ cause
264
+ });
265
+ }
266
+ };
267
+ var CircuitBreakerRegistry = class {
268
+ constructor(defaultConfig = {}) {
269
+ this.defaultConfig = defaultConfig;
270
+ }
271
+ breakers = /* @__PURE__ */ new Map();
272
+ globalListeners = /* @__PURE__ */ new Set();
273
+ getBreaker(cliName, config) {
274
+ let breaker = this.breakers.get(cliName);
275
+ if (!breaker) {
276
+ const mergedConfig = {
277
+ ...DEFAULT_CIRCUIT_BREAKER_CONFIG,
278
+ ...this.defaultConfig,
279
+ ...config
280
+ };
281
+ breaker = new CliCircuitBreaker(cliName, mergedConfig);
282
+ for (const listener of this.globalListeners) {
283
+ breaker.addStateChangeListener(listener);
284
+ }
285
+ this.breakers.set(cliName, breaker);
286
+ }
287
+ return breaker;
288
+ }
289
+ isOpen(cliName) {
290
+ return this.breakers.get(cliName)?.getState() === "open";
291
+ }
292
+ getAllSnapshots() {
293
+ const snapshots = /* @__PURE__ */ new Map();
294
+ for (const [name, breaker] of this.breakers) {
295
+ snapshots.set(name, breaker.getSnapshot());
296
+ }
297
+ return snapshots;
298
+ }
299
+ resetAll() {
300
+ for (const breaker of this.breakers.values()) {
301
+ breaker.reset();
302
+ }
303
+ }
304
+ reset(cliName) {
305
+ this.breakers.get(cliName)?.reset();
306
+ }
307
+ addGlobalStateChangeListener(listener) {
308
+ this.globalListeners.add(listener);
309
+ for (const breaker of this.breakers.values()) {
310
+ breaker.addStateChangeListener(listener);
311
+ }
312
+ }
313
+ removeGlobalStateChangeListener(listener) {
314
+ this.globalListeners.delete(listener);
315
+ for (const breaker of this.breakers.values()) {
316
+ breaker.removeStateChangeListener(listener);
317
+ }
318
+ }
319
+ getHealthyClis() {
320
+ const healthy = [];
321
+ for (const [name, breaker] of this.breakers) {
322
+ if (breaker.getState() === "closed") {
323
+ healthy.push(name);
324
+ }
325
+ }
326
+ return healthy;
327
+ }
328
+ getUnhealthyClis() {
329
+ const unhealthy = [];
330
+ for (const [name, breaker] of this.breakers) {
331
+ const state = breaker.getState();
332
+ if (state === "open" || state === "half-open") {
333
+ unhealthy.push(name);
334
+ }
335
+ }
336
+ return unhealthy;
337
+ }
338
+ };
339
+ function mapCliErrorToCategory(errorCode) {
340
+ const mapping = {
341
+ TIMEOUT: "timeout",
342
+ NOT_AUTHENTICATED: "authentication",
343
+ RATE_LIMITED: "rate_limit",
344
+ CONNECTION_ERROR: "connection"
345
+ };
346
+ return mapping[errorCode] ?? "unknown";
347
+ }
348
+
349
+ export {
350
+ CircuitError,
351
+ DEFAULT_CIRCUIT_BREAKER_CONFIG,
352
+ CliCircuitBreaker,
353
+ CircuitBreakerRegistry,
354
+ mapCliErrorToCategory
355
+ };
356
+ //# sourceMappingURL=chunk-Y477EGI4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli-adapters/circuit-breaker-types.ts","../src/cli-adapters/circuit-breaker.ts"],"sourcesContent":["/**\n * nexus-agents/cli-adapters - Circuit Breaker Types\n *\n * Type definitions and error classes for the circuit breaker pattern.\n *\n * (Source: Issue #81 - Circuit breaker for CLI failures)\n */\n\nimport { NexusError, ErrorCode } from '../core/errors.js';\nimport type { CliName } from './types.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Circuit breaker states.\n */\nexport type CircuitState = 'closed' | 'open' | 'half-open';\n\n/**\n * Categories of failures for circuit breaker decisions.\n */\nexport type FailureCategory =\n | 'timeout' // CLI didn't respond in time\n | 'crash' // Process crashed or exited unexpectedly\n | 'authentication' // OAuth/auth failure\n | 'rate_limit' // Rate limit exceeded\n | 'connection' // MCP connection failed\n | 'unknown'; // Uncategorized failure\n\n/**\n * Configuration options for circuit breaker.\n */\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit (default: 5) */\n readonly failureThreshold: number;\n /** Time in ms before attempting recovery (default: 30000) */\n readonly resetTimeoutMs: number;\n /** Successful calls needed in half-open to close (default: 2) */\n readonly halfOpenSuccessThreshold: number;\n /** Whether to count timeouts as failures (default: true) */\n readonly countTimeoutsAsFailures: boolean;\n /** Whether to count auth failures as failures (default: false) */\n readonly countAuthFailuresAsFailures: boolean;\n /** Whether to count rate limit errors as failures (default: false) */\n readonly countRateLimitsAsFailures: boolean;\n /** Maximum number of requests allowed in half-open state (default: 3) */\n readonly halfOpenMaxRequests: number;\n}\n\n/**\n * Circuit breaker state snapshot.\n */\nexport interface CircuitBreakerSnapshot {\n /** Current state */\n readonly state: CircuitState;\n /** Total failure count since last closed */\n readonly failureCount: number;\n /** Success count in half-open state */\n readonly successCount: number;\n /** Timestamp of last failure */\n readonly lastFailureTime: number | null;\n /** Timestamp of last state change */\n readonly lastStateChange: number;\n /** Requests in current half-open window */\n readonly halfOpenRequests: number;\n /** Configuration */\n readonly config: CircuitBreakerConfig;\n}\n\n/**\n * Event emitted on circuit state changes.\n */\nexport interface CircuitStateChangeEvent {\n /** CLI name */\n readonly cliName: CliName;\n /** Previous state */\n readonly previousState: CircuitState;\n /** New state */\n readonly newState: CircuitState;\n /** Timestamp of change */\n readonly timestamp: number;\n /** Failure count at time of change */\n readonly failureCount: number;\n /** Reason for state change */\n readonly reason: string;\n}\n\n/**\n * Event listener for circuit state changes.\n */\nexport type CircuitStateChangeListener = (event: CircuitStateChangeEvent) => void;\n\n/**\n * Interface for circuit breaker operations.\n */\nexport interface ICircuitBreaker {\n /**\n * Executes a function with circuit breaker protection.\n */\n execute<T>(fn: () => Promise<T>): Promise<import('../core/index.js').Result<T, CircuitError>>;\n\n /**\n * Gets the current circuit state.\n */\n getState(): CircuitState;\n\n /**\n * Gets a full snapshot of circuit breaker state.\n */\n getSnapshot(): CircuitBreakerSnapshot;\n\n /**\n * Manually resets the circuit breaker to closed state.\n */\n reset(): void;\n\n /**\n * Records a failure manually (for external failure detection).\n */\n recordFailure(category: FailureCategory): void;\n\n /**\n * Records a success manually (for external success detection).\n */\n recordSuccess(): void;\n}\n\n// ============================================================================\n// Error Codes\n// ============================================================================\n\n/**\n * Error codes specific to circuit breaker.\n */\nexport const CircuitErrorCode = {\n CIRCUIT_OPEN: 'CIRCUIT_OPEN',\n CIRCUIT_HALF_OPEN_REJECTED: 'CIRCUIT_HALF_OPEN_REJECTED',\n EXECUTION_FAILED: 'EXECUTION_FAILED',\n} as const;\n\nexport type CircuitErrorCode = (typeof CircuitErrorCode)[keyof typeof CircuitErrorCode];\n\n// ============================================================================\n// Error Class\n// ============================================================================\n\n/**\n * Error thrown when circuit breaker blocks a request.\n */\nexport class CircuitError extends NexusError {\n readonly circuitErrorCode: CircuitErrorCode;\n readonly cliName: CliName;\n readonly circuitState: CircuitState;\n readonly failureCategory?: FailureCategory;\n\n constructor(\n message: string,\n options: {\n circuitErrorCode: CircuitErrorCode;\n cliName: CliName;\n circuitState: CircuitState;\n failureCategory?: FailureCategory;\n cause?: Error;\n }\n ) {\n const baseOptions: { code: ErrorCode; cause?: Error; context: Record<string, unknown> } = {\n code: ErrorCode.INTERNAL_ERROR,\n context: {\n circuitErrorCode: options.circuitErrorCode,\n cliName: options.cliName,\n circuitState: options.circuitState,\n },\n };\n if (options.cause !== undefined) {\n baseOptions.cause = options.cause;\n }\n if (options.failureCategory !== undefined) {\n baseOptions.context['failureCategory'] = options.failureCategory;\n }\n super(message, baseOptions);\n this.name = 'CircuitError';\n this.circuitErrorCode = options.circuitErrorCode;\n this.cliName = options.cliName;\n this.circuitState = options.circuitState;\n if (options.failureCategory !== undefined) {\n this.failureCategory = options.failureCategory;\n }\n }\n}\n\n// ============================================================================\n// Default Configuration\n// ============================================================================\n\n/**\n * Default circuit breaker configuration.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeoutMs: 30_000,\n halfOpenSuccessThreshold: 2,\n countTimeoutsAsFailures: true,\n countAuthFailuresAsFailures: false,\n countRateLimitsAsFailures: true,\n halfOpenMaxRequests: 3,\n} as const;\n\n// ============================================================================\n// Error Categorization Patterns\n// ============================================================================\n\n/**\n * Pattern matchers for categorizing errors.\n */\nconst TIMEOUT_PATTERNS = ['timeout', 'timed out'];\nconst AUTH_PATTERNS = ['auth', 'unauthorized', 'forbidden', 'oauth'];\nconst RATE_LIMIT_PATTERNS = ['rate limit', 'too many requests', '429'];\nconst CONNECTION_PATTERNS = [\n 'connection',\n 'econnrefused',\n 'enotfound',\n 'mcp',\n 'eaddrinuse',\n 'address already in use',\n];\nconst CRASH_PATTERNS = ['crash', 'exited', 'killed', 'sigterm', 'sigkill'];\n\n/**\n * Checks if text contains any of the patterns.\n */\nfunction matchesPatterns(text: string, patterns: string[]): boolean {\n return patterns.some((pattern) => text.includes(pattern));\n}\n\n/**\n * Categorizes an error into a failure category.\n */\nexport function categorizeError(error: unknown): FailureCategory {\n if (!(error instanceof Error)) {\n return 'unknown';\n }\n\n const message = error.message.toLowerCase();\n const name = error.name.toLowerCase();\n const combined = `${message} ${name}`;\n\n if (matchesPatterns(combined, TIMEOUT_PATTERNS)) return 'timeout';\n if (matchesPatterns(combined, AUTH_PATTERNS)) return 'authentication';\n if (matchesPatterns(combined, RATE_LIMIT_PATTERNS)) return 'rate_limit';\n if (matchesPatterns(combined, CONNECTION_PATTERNS)) return 'connection';\n if (matchesPatterns(combined, CRASH_PATTERNS)) return 'crash';\n\n return 'unknown';\n}\n","/**\n * nexus-agents/cli-adapters - Circuit Breaker Implementation\n *\n * Implements the circuit breaker pattern to handle CLI failures gracefully\n * and prevent cascade failures in the multi-CLI mesh.\n *\n * (Source: Issue #81 - Circuit breaker for CLI failures)\n * (Source: Martin Fowler's Circuit Breaker pattern)\n */\n\nimport type { Result } from '../core/index.js';\nimport { getErrorMessage, err, ok, getTimeProvider } from '../core/index.js';\n\nimport type { CliName, CliErrorCode } from './types.js';\nimport {\n CircuitError,\n CircuitErrorCode,\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n categorizeError,\n type CircuitState,\n type FailureCategory,\n type CircuitBreakerConfig,\n type CircuitBreakerSnapshot,\n type CircuitStateChangeEvent,\n type CircuitStateChangeListener,\n type ICircuitBreaker,\n} from './circuit-breaker-types.js';\n\n// Re-export all types for convenience\nexport {\n CircuitError,\n CircuitErrorCode,\n DEFAULT_CIRCUIT_BREAKER_CONFIG,\n categorizeError,\n type CircuitState,\n type FailureCategory,\n type CircuitBreakerConfig,\n type CircuitBreakerSnapshot,\n type CircuitStateChangeEvent,\n type CircuitStateChangeListener,\n type ICircuitBreaker,\n} from './circuit-breaker-types.js';\n\n// ============================================================================\n// Circuit Breaker Implementation\n// ============================================================================\n\n/**\n * Circuit breaker implementation for CLI adapters.\n *\n * Provides protection against cascading failures by:\n * 1. Tracking failure counts\n * 2. Opening circuit when threshold exceeded\n * 3. Allowing gradual recovery through half-open state\n */\nexport class CliCircuitBreaker implements ICircuitBreaker {\n private state: CircuitState = 'closed';\n private failureCount = 0;\n private successCount = 0;\n private lastFailureTime: number | null = null;\n private lastStateChange: number;\n private halfOpenRequests = 0;\n private readonly listeners: Set<CircuitStateChangeListener> = new Set();\n\n constructor(\n private readonly cliName: CliName,\n private readonly config: CircuitBreakerConfig = DEFAULT_CIRCUIT_BREAKER_CONFIG\n ) {\n this.lastStateChange = getTimeProvider().now();\n }\n\n /**\n * Executes a function with circuit breaker protection.\n */\n async execute<T>(fn: () => Promise<T>): Promise<Result<T, CircuitError>> {\n const canExecute = this.canExecute();\n if (!canExecute.ok) {\n return canExecute;\n }\n\n try {\n const result = await fn();\n this.onSuccess();\n return ok(result);\n } catch (error) {\n const category = categorizeError(error);\n if (this.shouldCountFailure(category)) {\n this.onFailure(category);\n }\n return err(this.createExecutionError(error, category));\n }\n }\n\n getState(): CircuitState {\n this.checkStateTransition();\n return this.state;\n }\n\n getSnapshot(): CircuitBreakerSnapshot {\n this.checkStateTransition();\n return {\n state: this.state,\n failureCount: this.failureCount,\n successCount: this.successCount,\n lastFailureTime: this.lastFailureTime,\n lastStateChange: this.lastStateChange,\n halfOpenRequests: this.halfOpenRequests,\n config: this.config,\n };\n }\n\n reset(): void {\n const previousState = this.state;\n this.state = 'closed';\n this.failureCount = 0;\n this.successCount = 0;\n this.lastFailureTime = null;\n this.halfOpenRequests = 0;\n this.lastStateChange = getTimeProvider().now();\n\n if (previousState !== 'closed') {\n this.emitStateChange(previousState, 'closed', 'Manual reset');\n }\n }\n\n recordFailure(category: FailureCategory): void {\n if (this.shouldCountFailure(category)) {\n this.onFailure(category);\n }\n }\n\n recordSuccess(): void {\n this.onSuccess();\n }\n\n addStateChangeListener(listener: CircuitStateChangeListener): void {\n this.listeners.add(listener);\n }\n\n removeStateChangeListener(listener: CircuitStateChangeListener): void {\n this.listeners.delete(listener);\n }\n\n // -------------------------------------------------------------------------\n // Private Methods\n // -------------------------------------------------------------------------\n\n private canExecute(): Result<true, CircuitError> {\n this.checkStateTransition();\n\n if (this.state === 'closed') {\n return ok(true);\n }\n\n if (this.state === 'open') {\n return err(\n new CircuitError(`Circuit is open for CLI: ${this.cliName}`, {\n circuitErrorCode: CircuitErrorCode.CIRCUIT_OPEN,\n cliName: this.cliName,\n circuitState: this.state,\n })\n );\n }\n\n // half-open state\n if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {\n return err(\n new CircuitError(`Circuit half-open request limit reached for CLI: ${this.cliName}`, {\n circuitErrorCode: CircuitErrorCode.CIRCUIT_HALF_OPEN_REJECTED,\n cliName: this.cliName,\n circuitState: this.state,\n })\n );\n }\n this.halfOpenRequests++;\n return ok(true);\n }\n\n private checkStateTransition(): void {\n if (this.state === 'open' && this.lastFailureTime !== null) {\n const elapsed = getTimeProvider().now() - this.lastFailureTime;\n if (elapsed >= this.config.resetTimeoutMs) {\n this.transitionTo('half-open', 'Reset timeout elapsed');\n }\n }\n }\n\n private onSuccess(): void {\n if (this.state === 'closed') {\n this.failureCount = 0;\n } else if (this.state === 'half-open') {\n this.successCount++;\n if (this.successCount >= this.config.halfOpenSuccessThreshold) {\n const reason = `${String(this.successCount)} consecutive successes in half-open state`;\n this.transitionTo('closed', reason);\n }\n }\n }\n\n private onFailure(category: FailureCategory): void {\n this.failureCount++;\n this.lastFailureTime = getTimeProvider().now();\n\n if (this.state === 'closed' && this.failureCount >= this.config.failureThreshold) {\n const reason = `Failure threshold (${String(this.config.failureThreshold)}) exceeded`;\n this.transitionTo('open', reason);\n } else if (this.state === 'half-open') {\n this.transitionTo('open', `Failure during half-open recovery (category: ${category})`);\n }\n }\n\n private transitionTo(newState: CircuitState, reason: string): void {\n const previousState = this.state;\n this.state = newState;\n this.lastStateChange = getTimeProvider().now();\n\n if (newState === 'closed') {\n this.failureCount = 0;\n this.successCount = 0;\n this.halfOpenRequests = 0;\n } else if (newState === 'half-open') {\n this.successCount = 0;\n this.halfOpenRequests = 0;\n }\n\n this.emitStateChange(previousState, newState, reason);\n }\n\n private emitStateChange(\n previousState: CircuitState,\n newState: CircuitState,\n reason: string\n ): void {\n const event: CircuitStateChangeEvent = {\n cliName: this.cliName,\n previousState,\n newState,\n timestamp: this.lastStateChange,\n failureCount: this.failureCount,\n reason,\n };\n\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n // Ignore listener errors to prevent cascade\n }\n }\n }\n\n private shouldCountFailure(category: FailureCategory): boolean {\n if (category === 'timeout') return this.config.countTimeoutsAsFailures;\n if (category === 'authentication') return this.config.countAuthFailuresAsFailures;\n if (category === 'rate_limit') return this.config.countRateLimitsAsFailures;\n return true;\n }\n\n private createExecutionError(error: unknown, category: FailureCategory): CircuitError {\n const message = getErrorMessage(error);\n const cause = error instanceof Error ? error : new Error(String(error));\n return new CircuitError(`CLI execution failed: ${message}`, {\n circuitErrorCode: CircuitErrorCode.EXECUTION_FAILED,\n cliName: this.cliName,\n circuitState: this.state,\n failureCategory: category,\n cause,\n });\n }\n}\n\n// ============================================================================\n// Registry\n// ============================================================================\n\n/**\n * Registry for managing per-CLI circuit breakers.\n */\nexport class CircuitBreakerRegistry {\n private readonly breakers: Map<CliName, CliCircuitBreaker> = new Map();\n private readonly globalListeners: Set<CircuitStateChangeListener> = new Set();\n\n constructor(private readonly defaultConfig: Partial<CircuitBreakerConfig> = {}) {}\n\n getBreaker(cliName: CliName, config?: Partial<CircuitBreakerConfig>): CliCircuitBreaker {\n let breaker = this.breakers.get(cliName);\n\n if (!breaker) {\n const mergedConfig: CircuitBreakerConfig = {\n ...DEFAULT_CIRCUIT_BREAKER_CONFIG,\n ...this.defaultConfig,\n ...config,\n };\n breaker = new CliCircuitBreaker(cliName, mergedConfig);\n\n for (const listener of this.globalListeners) {\n breaker.addStateChangeListener(listener);\n }\n\n this.breakers.set(cliName, breaker);\n }\n\n return breaker;\n }\n\n isOpen(cliName: CliName): boolean {\n return this.breakers.get(cliName)?.getState() === 'open';\n }\n\n getAllSnapshots(): Map<CliName, CircuitBreakerSnapshot> {\n const snapshots = new Map<CliName, CircuitBreakerSnapshot>();\n for (const [name, breaker] of this.breakers) {\n snapshots.set(name, breaker.getSnapshot());\n }\n return snapshots;\n }\n\n resetAll(): void {\n for (const breaker of this.breakers.values()) {\n breaker.reset();\n }\n }\n\n reset(cliName: CliName): void {\n this.breakers.get(cliName)?.reset();\n }\n\n addGlobalStateChangeListener(listener: CircuitStateChangeListener): void {\n this.globalListeners.add(listener);\n for (const breaker of this.breakers.values()) {\n breaker.addStateChangeListener(listener);\n }\n }\n\n removeGlobalStateChangeListener(listener: CircuitStateChangeListener): void {\n this.globalListeners.delete(listener);\n for (const breaker of this.breakers.values()) {\n breaker.removeStateChangeListener(listener);\n }\n }\n\n getHealthyClis(): CliName[] {\n const healthy: CliName[] = [];\n for (const [name, breaker] of this.breakers) {\n if (breaker.getState() === 'closed') {\n healthy.push(name);\n }\n }\n return healthy;\n }\n\n getUnhealthyClis(): CliName[] {\n const unhealthy: CliName[] = [];\n for (const [name, breaker] of this.breakers) {\n const state = breaker.getState();\n if (state === 'open' || state === 'half-open') {\n unhealthy.push(name);\n }\n }\n return unhealthy;\n }\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Maps CLI error codes to failure categories.\n */\nexport function mapCliErrorToCategory(errorCode: CliErrorCode): FailureCategory {\n const mapping: Record<string, FailureCategory> = {\n TIMEOUT: 'timeout',\n NOT_AUTHENTICATED: 'authentication',\n RATE_LIMITED: 'rate_limit',\n CONNECTION_ERROR: 'connection',\n };\n return mapping[errorCode] ?? 'unknown';\n}\n\n/**\n * Creates a circuit breaker registry with metrics logging.\n */\nexport function createCircuitBreakerRegistryWithMetrics(\n logger: { info: (message: string, context?: Record<string, unknown>) => void },\n config?: Partial<CircuitBreakerConfig>\n): CircuitBreakerRegistry {\n const registry = new CircuitBreakerRegistry(config);\n\n registry.addGlobalStateChangeListener((event) => {\n logger.info('Circuit breaker state change', {\n cliName: event.cliName,\n previousState: event.previousState,\n newState: event.newState,\n failureCount: event.failureCount,\n reason: event.reason,\n timestamp: new Date(event.timestamp).toISOString(),\n });\n });\n\n return registry;\n}\n\n// ============================================================================\n// Capacity Monitor Integration\n// ============================================================================\n\n/**\n * Configuration for capacity monitor integration.\n */\nexport interface CapacityMonitorIntegrationConfig {\n /** Token threshold below which to trip circuit (default: 1000) */\n readonly criticalTokenThreshold?: number;\n /** Provider name to CLI name mapping */\n readonly providerToCliMapping?: Record<string, CliName>;\n}\n\nconst DEFAULT_CAPACITY_INTEGRATION_CONFIG: Required<CapacityMonitorIntegrationConfig> = {\n criticalTokenThreshold: 1000,\n providerToCliMapping: {\n anthropic: 'claude',\n openai: 'codex',\n google: 'gemini',\n },\n} as const;\n\n/**\n * Integrates a CapacityMonitor with CircuitBreakerRegistry to trip circuits\n * when provider capacity is critically low.\n *\n * This addresses Issue #543: Wire up onLowCapacity callback.\n *\n * @param monitor - The capacity monitor to integrate\n * @param registry - The circuit breaker registry\n * @param config - Optional configuration\n * @param logger - Optional logger for diagnostics\n * @returns Unsubscribe function to remove the callback\n *\n * @example\n * ```typescript\n * const monitor = createCapacityMonitor();\n * const registry = new CircuitBreakerRegistry();\n *\n * // Wire up capacity signals to circuit breaker\n * const unsubscribe = integrateCapacityMonitorWithCircuitBreaker(\n * monitor,\n * registry,\n * { criticalTokenThreshold: 500 }\n * );\n *\n * // Later: clean up\n * unsubscribe();\n * ```\n */\nexport function integrateCapacityMonitorWithCircuitBreaker(\n monitor: {\n onLowCapacity: (callback: (provider: string, remaining: number) => void) => () => void;\n },\n registry: CircuitBreakerRegistry,\n config?: CapacityMonitorIntegrationConfig,\n logger?: { warn: (message: string, context?: Record<string, unknown>) => void }\n): () => void {\n const mergedConfig = { ...DEFAULT_CAPACITY_INTEGRATION_CONFIG, ...config };\n\n return monitor.onLowCapacity((provider: string, remaining: number) => {\n // Map provider name to CLI name\n const cliName = mergedConfig.providerToCliMapping[provider];\n if (cliName === undefined) {\n logger?.warn('Unknown provider for capacity monitoring', { provider, remaining });\n return;\n }\n\n // Trip the circuit if capacity is critically low\n // Use 'connection' category since exhausted capacity is an availability issue,\n // not a transient rate limit (which is exempt from circuit breaker counting).\n if (remaining < mergedConfig.criticalTokenThreshold) {\n const breaker = registry.getBreaker(cliName);\n breaker.recordFailure('connection');\n logger?.warn('Circuit tripped due to low capacity', {\n provider,\n cliName,\n remaining,\n threshold: mergedConfig.criticalTokenThreshold,\n });\n }\n });\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  runConfigInitSync
3
- } from "./chunk-WSK4VSXP.js";
3
+ } from "./chunk-V6MSPUQF.js";
4
4
  import {
5
5
  VERSION,
6
6
  initDataDirectories
7
- } from "./chunk-5VZLXMO7.js";
7
+ } from "./chunk-WSYJN7BI.js";
8
8
  import {
9
9
  CLI_SUBPROCESS_TIMEOUTS,
10
10
  createLogger,
@@ -13,7 +13,7 @@ import {
13
13
  formatStatus,
14
14
  getErrorMessage,
15
15
  getTimeProvider
16
- } from "./chunk-IMWYKX4H.js";
16
+ } from "./chunk-HSOPD265.js";
17
17
 
18
18
  // src/cli/setup-command.ts
19
19
  import { existsSync as existsSync4 } from "fs";
@@ -1523,4 +1523,4 @@ export {
1523
1523
  setupCommand,
1524
1524
  setupCommandAsync
1525
1525
  };
1526
- //# sourceMappingURL=chunk-HH5LVGEE.js.map
1526
+ //# sourceMappingURL=chunk-Z4OZ25VS.js.map
@@ -0,0 +1,13 @@
1
+ import {
2
+ CliCircuitBreakerIntegration,
3
+ createCliCircuitBreakerIntegration
4
+ } from "./chunk-66NNHMVB.js";
5
+ import "./chunk-Y477EGI4.js";
6
+ import "./chunk-HSOPD265.js";
7
+ import "./chunk-CLYZ7FWP.js";
8
+ import "./chunk-UP2VWCW5.js";
9
+ export {
10
+ CliCircuitBreakerIntegration,
11
+ createCliCircuitBreakerIntegration
12
+ };
13
+ //# sourceMappingURL=cli-circuit-breaker-6EJO3PPU.js.map