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,127 @@
1
+ // src/indexer/symbol-extractor.ts
2
+ import { readFile } from "fs/promises";
3
+ import { extname } from "path";
4
+ import ts from "typescript";
5
+ function getKind(node) {
6
+ if (ts.isFunctionDeclaration(node)) return "function";
7
+ if (ts.isClassDeclaration(node)) return "class";
8
+ if (ts.isInterfaceDeclaration(node)) return "interface";
9
+ if (ts.isTypeAliasDeclaration(node)) return "type";
10
+ if (ts.isEnumDeclaration(node)) return "enum";
11
+ if (ts.isMethodDeclaration(node)) return "method";
12
+ if (ts.isVariableStatement(node)) return "variable";
13
+ return null;
14
+ }
15
+ function getName(node) {
16
+ if (ts.isFunctionDeclaration(node) || ts.isClassDeclaration(node) || ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isMethodDeclaration(node)) {
17
+ const nameNode = node.name;
18
+ return nameNode ? nameNode.getText() : "<anonymous>";
19
+ }
20
+ if (ts.isVariableStatement(node)) {
21
+ const decls = node.declarationList.declarations;
22
+ const firstDecl = decls[0];
23
+ if (firstDecl !== void 0) {
24
+ return firstDecl.name.getText();
25
+ }
26
+ }
27
+ return "<anonymous>";
28
+ }
29
+ function isExported(node) {
30
+ const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : void 0;
31
+ if (modifiers) {
32
+ return modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);
33
+ }
34
+ return false;
35
+ }
36
+ function visitNode(node, sourceFile, symbols) {
37
+ const kind = getKind(node);
38
+ if (kind !== null) {
39
+ const name = getName(node);
40
+ if (name !== "<anonymous>") {
41
+ const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());
42
+ const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
43
+ symbols.push({
44
+ name,
45
+ kind,
46
+ startLine: start.line + 1,
47
+ endLine: end.line + 1,
48
+ text: node.getText(sourceFile),
49
+ exported: isExported(node)
50
+ });
51
+ }
52
+ }
53
+ if (ts.isClassDeclaration(node)) {
54
+ visitClassMembers(node, sourceFile, symbols);
55
+ return;
56
+ }
57
+ ts.forEachChild(node, (child) => {
58
+ visitNode(child, sourceFile, symbols);
59
+ });
60
+ }
61
+ function visitClassMembers(node, sourceFile, symbols) {
62
+ for (const member of node.members) {
63
+ if (ts.isMethodDeclaration(member) || ts.isPropertyDeclaration(member)) {
64
+ const memberName = member.name.getText();
65
+ if (memberName !== "<anonymous>") {
66
+ const start = sourceFile.getLineAndCharacterOfPosition(member.getStart());
67
+ const end = sourceFile.getLineAndCharacterOfPosition(member.getEnd());
68
+ symbols.push({
69
+ name: memberName,
70
+ kind: "method",
71
+ startLine: start.line + 1,
72
+ endLine: end.line + 1,
73
+ text: member.getText(sourceFile),
74
+ exported: false
75
+ });
76
+ }
77
+ }
78
+ }
79
+ }
80
+ function computeSavings(totalChars, symbolChars) {
81
+ return totalChars > 0 ? Math.round(100 * (1 - symbolChars / totalChars) * 10) / 10 : 0;
82
+ }
83
+ async function extractSymbols(filePath) {
84
+ const ext = extname(filePath).toLowerCase();
85
+ if (![".ts", ".tsx", ".js", ".jsx"].includes(ext)) {
86
+ return {
87
+ filePath,
88
+ symbols: [],
89
+ totalLines: 0,
90
+ totalChars: 0,
91
+ symbolChars: 0,
92
+ savingsPercent: 0
93
+ };
94
+ }
95
+ const source = await readFile(filePath, "utf-8");
96
+ const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);
97
+ const symbols = [];
98
+ ts.forEachChild(sourceFile, (node) => {
99
+ visitNode(node, sourceFile, symbols);
100
+ });
101
+ const totalChars = source.length;
102
+ const symbolChars = symbols.reduce((sum, s) => sum + s.text.length, 0);
103
+ return {
104
+ filePath,
105
+ symbols,
106
+ totalLines: source.split("\n").length,
107
+ totalChars,
108
+ symbolChars,
109
+ savingsPercent: computeSavings(totalChars, symbolChars)
110
+ };
111
+ }
112
+ async function extractSymbolIndex(filePath) {
113
+ const result = await extractSymbols(filePath);
114
+ if (result.symbols.length === 0) return "";
115
+ const lines = result.symbols.map((s) => {
116
+ const exp = s.exported ? "export " : "";
117
+ return `${exp}${s.kind} ${s.name} (L${String(s.startLine)}-${String(s.endLine)})`;
118
+ });
119
+ return `// ${filePath} \u2014 ${String(result.symbols.length)} symbols
120
+ ${lines.join("\n")}`;
121
+ }
122
+
123
+ export {
124
+ extractSymbols,
125
+ extractSymbolIndex
126
+ };
127
+ //# sourceMappingURL=chunk-BQ4YXGGQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/indexer/symbol-extractor.ts"],"sourcesContent":["/**\n * AST symbol extraction for token-efficient code retrieval.\n *\n * Uses TypeScript's compiler API to extract function, class, method,\n * interface, and type definitions from source files.\n *\n * Token savings: ~80-99% vs reading full files.\n * No additional dependencies — uses TypeScript (already a project dep).\n *\n * @module indexer/symbol-extractor\n */\n\nimport { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport ts from 'typescript';\n\n/** A symbol extracted from source code. */\nexport interface CodeSymbol {\n /** Symbol name */\n name: string;\n /** Symbol kind */\n kind: 'function' | 'class' | 'method' | 'interface' | 'type' | 'variable' | 'enum';\n /** Start line (1-based) */\n startLine: number;\n /** End line (1-based) */\n endLine: number;\n /** Full source text of the symbol */\n text: string;\n /** Whether the symbol is exported */\n exported: boolean;\n}\n\n/** Result of extracting symbols from a file. */\nexport interface SymbolExtractionResult {\n filePath: string;\n symbols: CodeSymbol[];\n totalLines: number;\n totalChars: number;\n symbolChars: number;\n savingsPercent: number;\n}\n\nfunction getKind(node: ts.Node): CodeSymbol['kind'] | null {\n if (ts.isFunctionDeclaration(node)) return 'function';\n if (ts.isClassDeclaration(node)) return 'class';\n if (ts.isInterfaceDeclaration(node)) return 'interface';\n if (ts.isTypeAliasDeclaration(node)) return 'type';\n if (ts.isEnumDeclaration(node)) return 'enum';\n if (ts.isMethodDeclaration(node)) return 'method';\n if (ts.isVariableStatement(node)) return 'variable';\n return null;\n}\n\nfunction getName(node: ts.Node): string {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isClassDeclaration(node) ||\n ts.isInterfaceDeclaration(node) ||\n ts.isTypeAliasDeclaration(node) ||\n ts.isEnumDeclaration(node) ||\n ts.isMethodDeclaration(node)\n ) {\n const nameNode = (node as ts.NamedDeclaration).name;\n return nameNode ? nameNode.getText() : '<anonymous>';\n }\n if (ts.isVariableStatement(node)) {\n const decls = node.declarationList.declarations;\n const firstDecl = decls[0];\n if (firstDecl !== undefined) {\n return firstDecl.name.getText();\n }\n }\n return '<anonymous>';\n}\n\nfunction isExported(node: ts.Node): boolean {\n const modifiers = ts.canHaveModifiers(node) ? ts.getModifiers(node) : undefined;\n if (modifiers) {\n return modifiers.some((m) => m.kind === ts.SyntaxKind.ExportKeyword);\n }\n return false;\n}\n\nfunction visitNode(node: ts.Node, sourceFile: ts.SourceFile, symbols: CodeSymbol[]): void {\n const kind = getKind(node);\n if (kind !== null) {\n const name = getName(node);\n if (name !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n symbols.push({\n name,\n kind,\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: node.getText(sourceFile),\n exported: isExported(node),\n });\n }\n }\n if (ts.isClassDeclaration(node)) {\n visitClassMembers(node, sourceFile, symbols);\n return;\n }\n ts.forEachChild(node, (child) => {\n visitNode(child, sourceFile, symbols);\n });\n}\n\nfunction visitClassMembers(\n node: ts.ClassDeclaration,\n sourceFile: ts.SourceFile,\n symbols: CodeSymbol[]\n): void {\n for (const member of node.members) {\n if (ts.isMethodDeclaration(member) || ts.isPropertyDeclaration(member)) {\n const memberName = member.name.getText();\n if (memberName !== '<anonymous>') {\n const start = sourceFile.getLineAndCharacterOfPosition(member.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(member.getEnd());\n symbols.push({\n name: memberName,\n kind: 'method',\n startLine: start.line + 1,\n endLine: end.line + 1,\n text: member.getText(sourceFile),\n exported: false,\n });\n }\n }\n }\n}\n\nfunction computeSavings(totalChars: number, symbolChars: number): number {\n return totalChars > 0 ? Math.round(100 * (1 - symbolChars / totalChars) * 10) / 10 : 0;\n}\n\n/**\n * Extract symbols from a TypeScript/JavaScript file.\n */\nexport async function extractSymbols(filePath: string): Promise<SymbolExtractionResult> {\n const ext = extname(filePath).toLowerCase();\n if (!['.ts', '.tsx', '.js', '.jsx'].includes(ext)) {\n return {\n filePath,\n symbols: [],\n totalLines: 0,\n totalChars: 0,\n symbolChars: 0,\n savingsPercent: 0,\n };\n }\n\n const source = await readFile(filePath, 'utf-8');\n const sourceFile = ts.createSourceFile(filePath, source, ts.ScriptTarget.Latest, true);\n const symbols: CodeSymbol[] = [];\n\n ts.forEachChild(sourceFile, (node) => {\n visitNode(node, sourceFile, symbols);\n });\n\n const totalChars = source.length;\n const symbolChars = symbols.reduce((sum, s) => sum + s.text.length, 0);\n\n return {\n filePath,\n symbols,\n totalLines: source.split('\\n').length,\n totalChars,\n symbolChars,\n savingsPercent: computeSavings(totalChars, symbolChars),\n };\n}\n\n/**\n * Extract a compact symbol index (names + locations only, no source text).\n * This is the minimal representation for LLM context — ~95%+ token savings.\n */\nexport async function extractSymbolIndex(filePath: string): Promise<string> {\n const result = await extractSymbols(filePath);\n if (result.symbols.length === 0) return '';\n\n const lines = result.symbols.map((s) => {\n const exp = s.exported ? 'export ' : '';\n return `${exp}${s.kind} ${s.name} (L${String(s.startLine)}-${String(s.endLine)})`;\n });\n\n return `// ${filePath} — ${String(result.symbols.length)} symbols\\n${lines.join('\\n')}`;\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ CliCircuitBreaker,
3
+ DEFAULT_CIRCUIT_BREAKER_CONFIG
4
+ } from "./chunk-Y477EGI4.js";
1
5
  import {
2
6
  CLI_SUBPROCESS_TIMEOUTS,
3
7
  CLI_TIMEOUTS,
@@ -6,8 +10,6 @@ import {
6
10
  DEFAULT_CAPABILITIES,
7
11
  DEFAULT_MODEL_CAPABILITIES,
8
12
  DEFAULT_MODEL_PER_CLI,
9
- ErrorCode,
10
- NexusError,
11
13
  buildModelInfo,
12
14
  clampPercent,
13
15
  createLogger,
@@ -22,7 +24,7 @@ import {
22
24
  getTimeProvider,
23
25
  isRateLimitText,
24
26
  ok
25
- } from "./chunk-IMWYKX4H.js";
27
+ } from "./chunk-HSOPD265.js";
26
28
 
27
29
  // src/cli-adapters/subprocess-adapter.ts
28
30
  import { spawn } from "child_process";
@@ -51,7 +53,19 @@ function estimateTaskComplexity(taskDescription) {
51
53
  if (complexIndicators.some((indicator) => lower.includes(indicator))) {
52
54
  return "complex";
53
55
  }
54
- const simpleIndicators = ["single", "quick", "one function", "simple", "small", "brief", "short"];
56
+ const simpleIndicators = [
57
+ "single",
58
+ "quick",
59
+ "one function",
60
+ "simple",
61
+ "small",
62
+ "brief",
63
+ "short",
64
+ "run tests",
65
+ "test suite",
66
+ "exploration",
67
+ "explore"
68
+ ];
55
69
  if (simpleIndicators.some((indicator) => lower.includes(indicator))) {
56
70
  return "simple";
57
71
  }
@@ -1375,345 +1389,6 @@ var ResilientGeminiParser = class {
1375
1389
  }
1376
1390
  };
1377
1391
 
1378
- // src/cli-adapters/circuit-breaker-types.ts
1379
- var CircuitErrorCode = {
1380
- CIRCUIT_OPEN: "CIRCUIT_OPEN",
1381
- CIRCUIT_HALF_OPEN_REJECTED: "CIRCUIT_HALF_OPEN_REJECTED",
1382
- EXECUTION_FAILED: "EXECUTION_FAILED"
1383
- };
1384
- var CircuitError = class extends NexusError {
1385
- circuitErrorCode;
1386
- cliName;
1387
- circuitState;
1388
- failureCategory;
1389
- constructor(message, options) {
1390
- const baseOptions = {
1391
- code: ErrorCode.INTERNAL_ERROR,
1392
- context: {
1393
- circuitErrorCode: options.circuitErrorCode,
1394
- cliName: options.cliName,
1395
- circuitState: options.circuitState
1396
- }
1397
- };
1398
- if (options.cause !== void 0) {
1399
- baseOptions.cause = options.cause;
1400
- }
1401
- if (options.failureCategory !== void 0) {
1402
- baseOptions.context["failureCategory"] = options.failureCategory;
1403
- }
1404
- super(message, baseOptions);
1405
- this.name = "CircuitError";
1406
- this.circuitErrorCode = options.circuitErrorCode;
1407
- this.cliName = options.cliName;
1408
- this.circuitState = options.circuitState;
1409
- if (options.failureCategory !== void 0) {
1410
- this.failureCategory = options.failureCategory;
1411
- }
1412
- }
1413
- };
1414
- var DEFAULT_CIRCUIT_BREAKER_CONFIG = {
1415
- failureThreshold: 5,
1416
- resetTimeoutMs: 3e4,
1417
- halfOpenSuccessThreshold: 2,
1418
- countTimeoutsAsFailures: true,
1419
- countAuthFailuresAsFailures: false,
1420
- countRateLimitsAsFailures: true,
1421
- halfOpenMaxRequests: 3
1422
- };
1423
- var TIMEOUT_PATTERNS = ["timeout", "timed out"];
1424
- var AUTH_PATTERNS = ["auth", "unauthorized", "forbidden", "oauth"];
1425
- var RATE_LIMIT_PATTERNS = ["rate limit", "too many requests", "429"];
1426
- var CONNECTION_PATTERNS = [
1427
- "connection",
1428
- "econnrefused",
1429
- "enotfound",
1430
- "mcp",
1431
- "eaddrinuse",
1432
- "address already in use"
1433
- ];
1434
- var CRASH_PATTERNS = ["crash", "exited", "killed", "sigterm", "sigkill"];
1435
- function matchesPatterns(text, patterns) {
1436
- return patterns.some((pattern) => text.includes(pattern));
1437
- }
1438
- function categorizeError2(error) {
1439
- if (!(error instanceof Error)) {
1440
- return "unknown";
1441
- }
1442
- const message = error.message.toLowerCase();
1443
- const name = error.name.toLowerCase();
1444
- const combined = `${message} ${name}`;
1445
- if (matchesPatterns(combined, TIMEOUT_PATTERNS)) return "timeout";
1446
- if (matchesPatterns(combined, AUTH_PATTERNS)) return "authentication";
1447
- if (matchesPatterns(combined, RATE_LIMIT_PATTERNS)) return "rate_limit";
1448
- if (matchesPatterns(combined, CONNECTION_PATTERNS)) return "connection";
1449
- if (matchesPatterns(combined, CRASH_PATTERNS)) return "crash";
1450
- return "unknown";
1451
- }
1452
-
1453
- // src/cli-adapters/circuit-breaker.ts
1454
- var CliCircuitBreaker = class {
1455
- constructor(cliName, config = DEFAULT_CIRCUIT_BREAKER_CONFIG) {
1456
- this.cliName = cliName;
1457
- this.config = config;
1458
- this.lastStateChange = getTimeProvider().now();
1459
- }
1460
- state = "closed";
1461
- failureCount = 0;
1462
- successCount = 0;
1463
- lastFailureTime = null;
1464
- lastStateChange;
1465
- halfOpenRequests = 0;
1466
- listeners = /* @__PURE__ */ new Set();
1467
- /**
1468
- * Executes a function with circuit breaker protection.
1469
- */
1470
- async execute(fn) {
1471
- const canExecute = this.canExecute();
1472
- if (!canExecute.ok) {
1473
- return canExecute;
1474
- }
1475
- try {
1476
- const result = await fn();
1477
- this.onSuccess();
1478
- return ok(result);
1479
- } catch (error) {
1480
- const category = categorizeError2(error);
1481
- if (this.shouldCountFailure(category)) {
1482
- this.onFailure(category);
1483
- }
1484
- return err(this.createExecutionError(error, category));
1485
- }
1486
- }
1487
- getState() {
1488
- this.checkStateTransition();
1489
- return this.state;
1490
- }
1491
- getSnapshot() {
1492
- this.checkStateTransition();
1493
- return {
1494
- state: this.state,
1495
- failureCount: this.failureCount,
1496
- successCount: this.successCount,
1497
- lastFailureTime: this.lastFailureTime,
1498
- lastStateChange: this.lastStateChange,
1499
- halfOpenRequests: this.halfOpenRequests,
1500
- config: this.config
1501
- };
1502
- }
1503
- reset() {
1504
- const previousState = this.state;
1505
- this.state = "closed";
1506
- this.failureCount = 0;
1507
- this.successCount = 0;
1508
- this.lastFailureTime = null;
1509
- this.halfOpenRequests = 0;
1510
- this.lastStateChange = getTimeProvider().now();
1511
- if (previousState !== "closed") {
1512
- this.emitStateChange(previousState, "closed", "Manual reset");
1513
- }
1514
- }
1515
- recordFailure(category) {
1516
- if (this.shouldCountFailure(category)) {
1517
- this.onFailure(category);
1518
- }
1519
- }
1520
- recordSuccess() {
1521
- this.onSuccess();
1522
- }
1523
- addStateChangeListener(listener) {
1524
- this.listeners.add(listener);
1525
- }
1526
- removeStateChangeListener(listener) {
1527
- this.listeners.delete(listener);
1528
- }
1529
- // -------------------------------------------------------------------------
1530
- // Private Methods
1531
- // -------------------------------------------------------------------------
1532
- canExecute() {
1533
- this.checkStateTransition();
1534
- if (this.state === "closed") {
1535
- return ok(true);
1536
- }
1537
- if (this.state === "open") {
1538
- return err(
1539
- new CircuitError(`Circuit is open for CLI: ${this.cliName}`, {
1540
- circuitErrorCode: CircuitErrorCode.CIRCUIT_OPEN,
1541
- cliName: this.cliName,
1542
- circuitState: this.state
1543
- })
1544
- );
1545
- }
1546
- if (this.halfOpenRequests >= this.config.halfOpenMaxRequests) {
1547
- return err(
1548
- new CircuitError(`Circuit half-open request limit reached for CLI: ${this.cliName}`, {
1549
- circuitErrorCode: CircuitErrorCode.CIRCUIT_HALF_OPEN_REJECTED,
1550
- cliName: this.cliName,
1551
- circuitState: this.state
1552
- })
1553
- );
1554
- }
1555
- this.halfOpenRequests++;
1556
- return ok(true);
1557
- }
1558
- checkStateTransition() {
1559
- if (this.state === "open" && this.lastFailureTime !== null) {
1560
- const elapsed = getTimeProvider().now() - this.lastFailureTime;
1561
- if (elapsed >= this.config.resetTimeoutMs) {
1562
- this.transitionTo("half-open", "Reset timeout elapsed");
1563
- }
1564
- }
1565
- }
1566
- onSuccess() {
1567
- if (this.state === "closed") {
1568
- this.failureCount = 0;
1569
- } else if (this.state === "half-open") {
1570
- this.successCount++;
1571
- if (this.successCount >= this.config.halfOpenSuccessThreshold) {
1572
- const reason = `${String(this.successCount)} consecutive successes in half-open state`;
1573
- this.transitionTo("closed", reason);
1574
- }
1575
- }
1576
- }
1577
- onFailure(category) {
1578
- this.failureCount++;
1579
- this.lastFailureTime = getTimeProvider().now();
1580
- if (this.state === "closed" && this.failureCount >= this.config.failureThreshold) {
1581
- const reason = `Failure threshold (${String(this.config.failureThreshold)}) exceeded`;
1582
- this.transitionTo("open", reason);
1583
- } else if (this.state === "half-open") {
1584
- this.transitionTo("open", `Failure during half-open recovery (category: ${category})`);
1585
- }
1586
- }
1587
- transitionTo(newState, reason) {
1588
- const previousState = this.state;
1589
- this.state = newState;
1590
- this.lastStateChange = getTimeProvider().now();
1591
- if (newState === "closed") {
1592
- this.failureCount = 0;
1593
- this.successCount = 0;
1594
- this.halfOpenRequests = 0;
1595
- } else if (newState === "half-open") {
1596
- this.successCount = 0;
1597
- this.halfOpenRequests = 0;
1598
- }
1599
- this.emitStateChange(previousState, newState, reason);
1600
- }
1601
- emitStateChange(previousState, newState, reason) {
1602
- const event = {
1603
- cliName: this.cliName,
1604
- previousState,
1605
- newState,
1606
- timestamp: this.lastStateChange,
1607
- failureCount: this.failureCount,
1608
- reason
1609
- };
1610
- for (const listener of this.listeners) {
1611
- try {
1612
- listener(event);
1613
- } catch {
1614
- }
1615
- }
1616
- }
1617
- shouldCountFailure(category) {
1618
- if (category === "timeout") return this.config.countTimeoutsAsFailures;
1619
- if (category === "authentication") return this.config.countAuthFailuresAsFailures;
1620
- if (category === "rate_limit") return this.config.countRateLimitsAsFailures;
1621
- return true;
1622
- }
1623
- createExecutionError(error, category) {
1624
- const message = getErrorMessage(error);
1625
- const cause = error instanceof Error ? error : new Error(String(error));
1626
- return new CircuitError(`CLI execution failed: ${message}`, {
1627
- circuitErrorCode: CircuitErrorCode.EXECUTION_FAILED,
1628
- cliName: this.cliName,
1629
- circuitState: this.state,
1630
- failureCategory: category,
1631
- cause
1632
- });
1633
- }
1634
- };
1635
- var CircuitBreakerRegistry = class {
1636
- constructor(defaultConfig = {}) {
1637
- this.defaultConfig = defaultConfig;
1638
- }
1639
- breakers = /* @__PURE__ */ new Map();
1640
- globalListeners = /* @__PURE__ */ new Set();
1641
- getBreaker(cliName, config) {
1642
- let breaker = this.breakers.get(cliName);
1643
- if (!breaker) {
1644
- const mergedConfig = {
1645
- ...DEFAULT_CIRCUIT_BREAKER_CONFIG,
1646
- ...this.defaultConfig,
1647
- ...config
1648
- };
1649
- breaker = new CliCircuitBreaker(cliName, mergedConfig);
1650
- for (const listener of this.globalListeners) {
1651
- breaker.addStateChangeListener(listener);
1652
- }
1653
- this.breakers.set(cliName, breaker);
1654
- }
1655
- return breaker;
1656
- }
1657
- isOpen(cliName) {
1658
- return this.breakers.get(cliName)?.getState() === "open";
1659
- }
1660
- getAllSnapshots() {
1661
- const snapshots = /* @__PURE__ */ new Map();
1662
- for (const [name, breaker] of this.breakers) {
1663
- snapshots.set(name, breaker.getSnapshot());
1664
- }
1665
- return snapshots;
1666
- }
1667
- resetAll() {
1668
- for (const breaker of this.breakers.values()) {
1669
- breaker.reset();
1670
- }
1671
- }
1672
- reset(cliName) {
1673
- this.breakers.get(cliName)?.reset();
1674
- }
1675
- addGlobalStateChangeListener(listener) {
1676
- this.globalListeners.add(listener);
1677
- for (const breaker of this.breakers.values()) {
1678
- breaker.addStateChangeListener(listener);
1679
- }
1680
- }
1681
- removeGlobalStateChangeListener(listener) {
1682
- this.globalListeners.delete(listener);
1683
- for (const breaker of this.breakers.values()) {
1684
- breaker.removeStateChangeListener(listener);
1685
- }
1686
- }
1687
- getHealthyClis() {
1688
- const healthy = [];
1689
- for (const [name, breaker] of this.breakers) {
1690
- if (breaker.getState() === "closed") {
1691
- healthy.push(name);
1692
- }
1693
- }
1694
- return healthy;
1695
- }
1696
- getUnhealthyClis() {
1697
- const unhealthy = [];
1698
- for (const [name, breaker] of this.breakers) {
1699
- const state = breaker.getState();
1700
- if (state === "open" || state === "half-open") {
1701
- unhealthy.push(name);
1702
- }
1703
- }
1704
- return unhealthy;
1705
- }
1706
- };
1707
- function mapCliErrorToCategory(errorCode) {
1708
- const mapping = {
1709
- TIMEOUT: "timeout",
1710
- NOT_AUTHENTICATED: "authentication",
1711
- RATE_LIMITED: "rate_limit",
1712
- CONNECTION_ERROR: "connection"
1713
- };
1714
- return mapping[errorCode] ?? "unknown";
1715
- }
1716
-
1717
1392
  // src/cli-adapters/adapters/gemini-adapter-helpers.ts
1718
1393
  var GEMINI_LEGACY_DEFAULTS = {
1719
1394
  displayNames: {},
@@ -2986,9 +2661,6 @@ export {
2986
2661
  extractNumberField,
2987
2662
  ClaudeResponseParser,
2988
2663
  ClaudeCliAdapter,
2989
- CircuitError,
2990
- CircuitBreakerRegistry,
2991
- mapCliErrorToCategory,
2992
2664
  GeminiCliAdapter,
2993
2665
  CodexResponseParser,
2994
2666
  CodexCliAdapter,
@@ -3003,4 +2675,4 @@ export {
3003
2675
  isCliAvailable,
3004
2676
  getAvailableClis
3005
2677
  };
3006
- //# sourceMappingURL=chunk-ZBZJHXRT.js.map
2678
+ //# sourceMappingURL=chunk-CW2Z773T.js.map