nexus-agents 2.79.3 → 2.80.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 (127) hide show
  1. package/README.md +2 -2
  2. package/dist/{child-mcp-config-CTO2MBRM.js → child-mcp-config-SM5I7USN.js} +3 -3
  3. package/dist/{chunk-YXWGEIQR.js → chunk-2DBPZQLO.js} +8 -5
  4. package/dist/chunk-2DBPZQLO.js.map +1 -0
  5. package/dist/chunk-2JQXC3CK.js +317 -0
  6. package/dist/chunk-2JQXC3CK.js.map +1 -0
  7. package/dist/{chunk-6E3NMMEY.js → chunk-3RZWLQSC.js} +2 -2
  8. package/dist/{chunk-6E3NMMEY.js.map → chunk-3RZWLQSC.js.map} +1 -1
  9. package/dist/{chunk-2UYTFLMO.js → chunk-4XGKCVJL.js} +2 -2
  10. package/dist/{chunk-SWFJU3W2.js → chunk-6CJIKX6I.js} +63 -51
  11. package/dist/chunk-6CJIKX6I.js.map +1 -0
  12. package/dist/{chunk-3NIPH6UP.js → chunk-AYZ6P7CK.js} +2 -2
  13. package/dist/{chunk-HYU4GZY6.js → chunk-BSIGP5XF.js} +2 -2
  14. package/dist/{chunk-GONMG4NM.js → chunk-CTSESEFA.js} +2 -2
  15. package/dist/{chunk-FVPYP5DD.js → chunk-EKRMWVAH.js} +4 -4
  16. package/dist/{chunk-7XCUZI4G.js → chunk-EVZ7YR7H.js} +4 -4
  17. package/dist/{chunk-L6SCKLGO.js → chunk-FAJAWO42.js} +3 -3
  18. package/dist/{chunk-5O6XLBPP.js → chunk-FJHZW7CR.js} +2 -2
  19. package/dist/{chunk-HB4MIDHJ.js → chunk-GNRANMQ3.js} +122 -72
  20. package/dist/chunk-GNRANMQ3.js.map +1 -0
  21. package/dist/{chunk-KT5FIBWS.js → chunk-HBKZ2DJK.js} +2 -2
  22. package/dist/{chunk-2YPG6PDG.js → chunk-J5XEJHIQ.js} +3 -3
  23. package/dist/{chunk-ZVCED4Z4.js → chunk-JLWKHYIU.js} +2 -2
  24. package/dist/{chunk-DLXT23AC.js → chunk-JXDDSNEK.js} +2 -2
  25. package/dist/{chunk-Q5CFPIJ5.js → chunk-OO6MTUDS.js} +4 -4
  26. package/dist/chunk-Q2U6SFN2.js +136 -0
  27. package/dist/chunk-Q2U6SFN2.js.map +1 -0
  28. package/dist/{chunk-6TFTVW77.js → chunk-QVHXEQFM.js} +3 -3
  29. package/dist/{chunk-FJWWSVWB.js → chunk-RIUUFBX4.js} +2 -2
  30. package/dist/{chunk-DNO2INX5.js → chunk-SHVGZK4A.js} +4 -4
  31. package/dist/{chunk-VIQOVK4E.js → chunk-SJUSQGKH.js} +82 -186
  32. package/dist/chunk-SJUSQGKH.js.map +1 -0
  33. package/dist/{chunk-JI7S55R3.js → chunk-UGXR4PAY.js} +35 -9
  34. package/dist/chunk-UGXR4PAY.js.map +1 -0
  35. package/dist/{chunk-SD76JZBG.js → chunk-UVALD724.js} +2 -2
  36. package/dist/{chunk-K2QILJG4.js → chunk-VS4KB3AX.js} +33 -9
  37. package/dist/chunk-VS4KB3AX.js.map +1 -0
  38. package/dist/{chunk-PLX6FCFC.js → chunk-YGKPWUJ6.js} +2 -2
  39. package/dist/{chunk-WDYCIJWN.js → chunk-YMT6H2HQ.js} +13 -14
  40. package/dist/chunk-YMT6H2HQ.js.map +1 -0
  41. package/dist/{chunk-D6TM2VHX.js → chunk-ZU2Q3DWE.js} +49 -24
  42. package/dist/chunk-ZU2Q3DWE.js.map +1 -0
  43. package/dist/{cli-circuit-breaker-I74ZQ44Q.js → cli-circuit-breaker-JGX54DAD.js} +5 -5
  44. package/dist/cli.d.ts +1 -1
  45. package/dist/cli.js +574 -531
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{composite-router-V3OC57IE.js → composite-router-UYFYSMBT.js} +3 -3
  48. package/dist/{consensus-vote-ESFPGEJE.js → consensus-vote-BZ6JSN67.js} +12 -12
  49. package/dist/{context-retriever-MB3D7KS6.js → context-retriever-G23VVJ5S.js} +6 -6
  50. package/dist/{doctor-deep-KQ765XZA.js → doctor-deep-OF2LXZ6A.js} +4 -4
  51. package/dist/expert-bridge-6ZLD2NWD.js +11 -0
  52. package/dist/{factory-LHHYDVZX.js → factory-I54TX7OY.js} +5 -5
  53. package/dist/factory-UHDCLEUE.js +14 -0
  54. package/dist/index.d.ts +31 -7
  55. package/dist/index.js +31 -29
  56. package/dist/index.js.map +1 -1
  57. package/dist/{init-opencode-GXZN2W5S.js → init-opencode-FE7HVWQL.js} +6 -6
  58. package/dist/issue-triage-7NR5NQUY.js +15 -0
  59. package/dist/{learning-persistence-Q3HTOGTU.js → learning-persistence-TGOBRUUU.js} +2 -2
  60. package/dist/{pr-reviewer-helpers-XCY7HOPE.js → pr-reviewer-helpers-L4L324FQ.js} +2 -2
  61. package/dist/{registry-command-6E4YKAMT.js → registry-command-NZLX7ZFV.js} +3 -3
  62. package/dist/{repo-security-plan-AGRU72DL.js → repo-security-plan-74GJWJSV.js} +4 -4
  63. package/dist/{research-helpers-synthesize-K2UCJQQG.js → research-helpers-synthesize-LFPEXRIV.js} +4 -4
  64. package/dist/{routing-memory-3B6DDZ76.js → routing-memory-Y2LSEQVS.js} +3 -3
  65. package/dist/{session-memory-L7EQIY2O.js → session-memory-RCNQJDJR.js} +4 -4
  66. package/dist/{setup-command-QSAGFMGN.js → setup-command-ZPLPOJF2.js} +13 -10
  67. package/dist/setup-config-F7VRWXY3.js +10 -0
  68. package/dist/{setup-custom-api-IBDV654K.js → setup-custom-api-XTJ6YZM6.js} +5 -5
  69. package/dist/{tool-memory-6HCHQLAN.js → tool-memory-COZK6SR7.js} +5 -5
  70. package/dist/{weather-report-ER3WUZ7S.js → weather-report-O4XOYGPK.js} +3 -3
  71. package/package.json +4 -4
  72. package/scripts/postinstall.js +1 -1
  73. package/dist/chunk-7BMOZJYS.js +0 -83
  74. package/dist/chunk-7BMOZJYS.js.map +0 -1
  75. package/dist/chunk-D6TM2VHX.js.map +0 -1
  76. package/dist/chunk-HB4MIDHJ.js.map +0 -1
  77. package/dist/chunk-JI7S55R3.js.map +0 -1
  78. package/dist/chunk-K2QILJG4.js.map +0 -1
  79. package/dist/chunk-SWFJU3W2.js.map +0 -1
  80. package/dist/chunk-VIQOVK4E.js.map +0 -1
  81. package/dist/chunk-WDYCIJWN.js.map +0 -1
  82. package/dist/chunk-YXWGEIQR.js.map +0 -1
  83. package/dist/expert-bridge-JKLC57IC.js +0 -10
  84. package/dist/factory-BUUXNGIB.js +0 -14
  85. package/dist/issue-triage-RMXPDZ2K.js +0 -15
  86. package/dist/setup-config-EQT24DD4.js +0 -10
  87. /package/dist/{child-mcp-config-CTO2MBRM.js.map → child-mcp-config-SM5I7USN.js.map} +0 -0
  88. /package/dist/{chunk-2UYTFLMO.js.map → chunk-4XGKCVJL.js.map} +0 -0
  89. /package/dist/{chunk-3NIPH6UP.js.map → chunk-AYZ6P7CK.js.map} +0 -0
  90. /package/dist/{chunk-HYU4GZY6.js.map → chunk-BSIGP5XF.js.map} +0 -0
  91. /package/dist/{chunk-GONMG4NM.js.map → chunk-CTSESEFA.js.map} +0 -0
  92. /package/dist/{chunk-FVPYP5DD.js.map → chunk-EKRMWVAH.js.map} +0 -0
  93. /package/dist/{chunk-7XCUZI4G.js.map → chunk-EVZ7YR7H.js.map} +0 -0
  94. /package/dist/{chunk-L6SCKLGO.js.map → chunk-FAJAWO42.js.map} +0 -0
  95. /package/dist/{chunk-5O6XLBPP.js.map → chunk-FJHZW7CR.js.map} +0 -0
  96. /package/dist/{chunk-KT5FIBWS.js.map → chunk-HBKZ2DJK.js.map} +0 -0
  97. /package/dist/{chunk-2YPG6PDG.js.map → chunk-J5XEJHIQ.js.map} +0 -0
  98. /package/dist/{chunk-ZVCED4Z4.js.map → chunk-JLWKHYIU.js.map} +0 -0
  99. /package/dist/{chunk-DLXT23AC.js.map → chunk-JXDDSNEK.js.map} +0 -0
  100. /package/dist/{chunk-Q5CFPIJ5.js.map → chunk-OO6MTUDS.js.map} +0 -0
  101. /package/dist/{chunk-6TFTVW77.js.map → chunk-QVHXEQFM.js.map} +0 -0
  102. /package/dist/{chunk-FJWWSVWB.js.map → chunk-RIUUFBX4.js.map} +0 -0
  103. /package/dist/{chunk-DNO2INX5.js.map → chunk-SHVGZK4A.js.map} +0 -0
  104. /package/dist/{chunk-SD76JZBG.js.map → chunk-UVALD724.js.map} +0 -0
  105. /package/dist/{chunk-PLX6FCFC.js.map → chunk-YGKPWUJ6.js.map} +0 -0
  106. /package/dist/{cli-circuit-breaker-I74ZQ44Q.js.map → cli-circuit-breaker-JGX54DAD.js.map} +0 -0
  107. /package/dist/{composite-router-V3OC57IE.js.map → composite-router-UYFYSMBT.js.map} +0 -0
  108. /package/dist/{consensus-vote-ESFPGEJE.js.map → consensus-vote-BZ6JSN67.js.map} +0 -0
  109. /package/dist/{context-retriever-MB3D7KS6.js.map → context-retriever-G23VVJ5S.js.map} +0 -0
  110. /package/dist/{doctor-deep-KQ765XZA.js.map → doctor-deep-OF2LXZ6A.js.map} +0 -0
  111. /package/dist/{expert-bridge-JKLC57IC.js.map → expert-bridge-6ZLD2NWD.js.map} +0 -0
  112. /package/dist/{factory-BUUXNGIB.js.map → factory-I54TX7OY.js.map} +0 -0
  113. /package/dist/{factory-LHHYDVZX.js.map → factory-UHDCLEUE.js.map} +0 -0
  114. /package/dist/{init-opencode-GXZN2W5S.js.map → init-opencode-FE7HVWQL.js.map} +0 -0
  115. /package/dist/{issue-triage-RMXPDZ2K.js.map → issue-triage-7NR5NQUY.js.map} +0 -0
  116. /package/dist/{learning-persistence-Q3HTOGTU.js.map → learning-persistence-TGOBRUUU.js.map} +0 -0
  117. /package/dist/{pr-reviewer-helpers-XCY7HOPE.js.map → pr-reviewer-helpers-L4L324FQ.js.map} +0 -0
  118. /package/dist/{registry-command-6E4YKAMT.js.map → registry-command-NZLX7ZFV.js.map} +0 -0
  119. /package/dist/{repo-security-plan-AGRU72DL.js.map → repo-security-plan-74GJWJSV.js.map} +0 -0
  120. /package/dist/{research-helpers-synthesize-K2UCJQQG.js.map → research-helpers-synthesize-LFPEXRIV.js.map} +0 -0
  121. /package/dist/{routing-memory-3B6DDZ76.js.map → routing-memory-Y2LSEQVS.js.map} +0 -0
  122. /package/dist/{session-memory-L7EQIY2O.js.map → session-memory-RCNQJDJR.js.map} +0 -0
  123. /package/dist/{setup-command-QSAGFMGN.js.map → setup-command-ZPLPOJF2.js.map} +0 -0
  124. /package/dist/{setup-config-EQT24DD4.js.map → setup-config-F7VRWXY3.js.map} +0 -0
  125. /package/dist/{setup-custom-api-IBDV654K.js.map → setup-custom-api-XTJ6YZM6.js.map} +0 -0
  126. /package/dist/{tool-memory-6HCHQLAN.js.map → tool-memory-COZK6SR7.js.map} +0 -0
  127. /package/dist/{weather-report-ER3WUZ7S.js.map → weather-report-O4XOYGPK.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createLogger
3
- } from "./chunk-WDYCIJWN.js";
3
+ } from "./chunk-YMT6H2HQ.js";
4
4
 
5
5
  // src/config/available-models-cache.ts
6
6
  var logger = createLogger({ component: "available-models-cache" });
@@ -150,4 +150,4 @@ export {
150
150
  getDefaultAvailableModelsCache,
151
151
  setDefaultAvailableModelsCache
152
152
  };
153
- //# sourceMappingURL=chunk-KT5FIBWS.js.map
153
+ //# sourceMappingURL=chunk-HBKZ2DJK.js.map
@@ -2,14 +2,14 @@ import {
2
2
  CircuitBreakerRegistry,
3
3
  CircuitError,
4
4
  mapCliErrorToCategory
5
- } from "./chunk-DLXT23AC.js";
5
+ } from "./chunk-JXDDSNEK.js";
6
6
  import {
7
7
  createLogger,
8
8
  err,
9
9
  getFallbackChainForCategory,
10
10
  getTimeProvider,
11
11
  ok
12
- } from "./chunk-WDYCIJWN.js";
12
+ } from "./chunk-YMT6H2HQ.js";
13
13
 
14
14
  // src/cli-adapters/cli-circuit-breaker.ts
15
15
  var CATEGORY_TO_FALLBACK = {
@@ -152,4 +152,4 @@ export {
152
152
  CliCircuitBreakerIntegration,
153
153
  createCliCircuitBreakerIntegration
154
154
  };
155
- //# sourceMappingURL=chunk-2YPG6PDG.js.map
155
+ //# sourceMappingURL=chunk-J5XEJHIQ.js.map
@@ -2,7 +2,7 @@ import {
2
2
  ConfigError,
3
3
  err,
4
4
  ok
5
- } from "./chunk-WDYCIJWN.js";
5
+ } from "./chunk-YMT6H2HQ.js";
6
6
 
7
7
  // src/adapters/sdk/types.ts
8
8
  var PROVIDER_ENV_KEYS = {
@@ -117,4 +117,4 @@ export {
117
117
  CUSTOM_API_ALLOW_PRIVATE_ENV,
118
118
  validateCustomApiBaseUrl
119
119
  };
120
- //# sourceMappingURL=chunk-ZVCED4Z4.js.map
120
+ //# sourceMappingURL=chunk-JLWKHYIU.js.map
@@ -5,7 +5,7 @@ import {
5
5
  getErrorMessage,
6
6
  getTimeProvider,
7
7
  ok
8
- } from "./chunk-WDYCIJWN.js";
8
+ } from "./chunk-YMT6H2HQ.js";
9
9
 
10
10
  // src/cli-adapters/circuit-breaker-types.ts
11
11
  var CircuitErrorCode = {
@@ -353,4 +353,4 @@ export {
353
353
  CircuitBreakerRegistry,
354
354
  mapCliErrorToCategory
355
355
  };
356
- //# sourceMappingURL=chunk-DLXT23AC.js.map
356
+ //# sourceMappingURL=chunk-JXDDSNEK.js.map
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-PQHVC4BD.js";
9
9
  import {
10
10
  SessionMemory
11
- } from "./chunk-3NIPH6UP.js";
11
+ } from "./chunk-AYZ6P7CK.js";
12
12
  import {
13
13
  ErrorCode,
14
14
  NexusError,
@@ -22,10 +22,10 @@ import {
22
22
  getTimeProvider,
23
23
  ok,
24
24
  setSharedMobiMemDbPathResolver
25
- } from "./chunk-WDYCIJWN.js";
25
+ } from "./chunk-YMT6H2HQ.js";
26
26
  import {
27
27
  nexusDataPath
28
- } from "./chunk-7BMOZJYS.js";
28
+ } from "./chunk-2JQXC3CK.js";
29
29
 
30
30
  // src/mcp/tools/tool-memory.ts
31
31
  import * as fs3 from "fs";
@@ -5578,4 +5578,4 @@ export {
5578
5578
  reinitializeMemoryBackends,
5579
5579
  ToolMemoryManager
5580
5580
  };
5581
- //# sourceMappingURL=chunk-Q5CFPIJ5.js.map
5581
+ //# sourceMappingURL=chunk-OO6MTUDS.js.map
@@ -0,0 +1,136 @@
1
+ import {
2
+ DEFAULT_MODEL_PER_CLI,
3
+ getTimeProvider
4
+ } from "./chunk-YMT6H2HQ.js";
5
+
6
+ // src/config/model-availability.ts
7
+ var DEFAULT_TTL_MS = 6e4;
8
+ var DEFAULT_MAX_ENTRIES = 50;
9
+ var AvailabilityCache = class {
10
+ cache = /* @__PURE__ */ new Map();
11
+ ttlMs;
12
+ maxEntries;
13
+ constructor(config = {}) {
14
+ this.ttlMs = config.ttlMs ?? DEFAULT_TTL_MS;
15
+ this.maxEntries = config.maxEntries ?? DEFAULT_MAX_ENTRIES;
16
+ }
17
+ /** Get a cached probe result, or undefined if expired/missing. */
18
+ get(modelId) {
19
+ const entry = this.cache.get(modelId);
20
+ if (entry === void 0) return void 0;
21
+ if (getTimeProvider().now() - entry.checkedAt > this.ttlMs) {
22
+ this.cache.delete(modelId);
23
+ return void 0;
24
+ }
25
+ return entry;
26
+ }
27
+ /** Store a probe result, evicting oldest if at capacity. */
28
+ set(result) {
29
+ if (this.cache.size >= this.maxEntries && !this.cache.has(result.modelId)) {
30
+ const oldest = this.cache.keys().next();
31
+ if (oldest.done !== true) {
32
+ this.cache.delete(oldest.value);
33
+ }
34
+ }
35
+ this.cache.set(result.modelId, result);
36
+ }
37
+ /** Mark a model as unavailable without a full probe. */
38
+ markUnavailable(modelId, error) {
39
+ this.set({
40
+ modelId,
41
+ available: false,
42
+ latencyMs: 0,
43
+ checkedAt: getTimeProvider().now(),
44
+ error
45
+ });
46
+ }
47
+ /** Mark a model as available. */
48
+ markAvailable(modelId, latencyMs) {
49
+ this.set({
50
+ modelId,
51
+ available: true,
52
+ latencyMs,
53
+ checkedAt: getTimeProvider().now()
54
+ });
55
+ }
56
+ /** Check if a model is known-unavailable (cached and not expired). */
57
+ isKnownUnavailable(modelId) {
58
+ const entry = this.get(modelId);
59
+ return entry !== void 0 && !entry.available;
60
+ }
61
+ /** Get all cached entries (for diagnostics). */
62
+ entries() {
63
+ return [...this.cache.values()];
64
+ }
65
+ /** Number of cached entries. */
66
+ get size() {
67
+ return this.cache.size;
68
+ }
69
+ /** Clear all cached entries. */
70
+ clear() {
71
+ this.cache.clear();
72
+ }
73
+ };
74
+ var FALLBACK_CHAINS = {
75
+ claude: ["claude-opus", "claude-sonnet", "claude-haiku"],
76
+ gemini: ["gemini-3-pro", "gemini-pro", "gemini-3-flash", "gemini-flash"],
77
+ codex: ["codex-5.3", "codex-5.2", "codex-5.1-mini"],
78
+ opencode: ["opencode-custom-opus", "opencode-custom-sonnet", "opencode-default"]
79
+ };
80
+ function resolveFallback(modelId, cache) {
81
+ const cli = getCliForModelId(modelId);
82
+ if (cli === void 0) return null;
83
+ const chain = FALLBACK_CHAINS[cli];
84
+ for (const candidate of chain) {
85
+ if (candidate === modelId) continue;
86
+ if (!cache.isKnownUnavailable(candidate)) {
87
+ return {
88
+ modelId: candidate,
89
+ reason: `Fallback from ${modelId} (unavailable) to ${candidate}`
90
+ };
91
+ }
92
+ }
93
+ return null;
94
+ }
95
+ function getFallbackChain(cli) {
96
+ return FALLBACK_CHAINS[cli];
97
+ }
98
+ function getCliForModelId(modelId) {
99
+ for (const [cli, defaultModel] of Object.entries(DEFAULT_MODEL_PER_CLI)) {
100
+ const chain = FALLBACK_CHAINS[cli];
101
+ if (chain.includes(modelId)) return cli;
102
+ if (defaultModel === modelId) return cli;
103
+ }
104
+ return void 0;
105
+ }
106
+ var globalCache;
107
+ function getAvailabilityCache() {
108
+ globalCache ??= new AvailabilityCache();
109
+ return globalCache;
110
+ }
111
+ function resetAvailabilityCache() {
112
+ globalCache = void 0;
113
+ }
114
+ function filterAvailableModels(modelIds, cache) {
115
+ const available = [];
116
+ const removed = [];
117
+ for (const id of modelIds) {
118
+ if (cache.isKnownUnavailable(id)) {
119
+ removed.push(id);
120
+ } else {
121
+ available.push(id);
122
+ }
123
+ }
124
+ return { available, removed };
125
+ }
126
+
127
+ export {
128
+ AvailabilityCache,
129
+ resolveFallback,
130
+ getFallbackChain,
131
+ getCliForModelId,
132
+ getAvailabilityCache,
133
+ resetAvailabilityCache,
134
+ filterAvailableModels
135
+ };
136
+ //# sourceMappingURL=chunk-Q2U6SFN2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/model-availability.ts"],"sourcesContent":["/**\n * nexus-agents/config - Model Availability Probes & Fallback Chains\n *\n * Runtime availability tracking for model APIs. Maintains a bounded\n * TTL cache of probe results and provides fallback chain resolution\n * when a model is unavailable.\n *\n * @module config/model-availability\n * (Source: Issue #869)\n */\n\nimport { getTimeProvider } from '../core/index.js';\nimport type { ModelId, CliNameLiteral } from './model-capabilities-types.js';\nimport { DEFAULT_MODEL_PER_CLI } from './in-tree-data.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Status of a model probe. */\nexport interface ProbeResult {\n readonly modelId: ModelId;\n readonly available: boolean;\n readonly latencyMs: number;\n readonly checkedAt: number;\n readonly error?: string;\n}\n\n/** Configuration for the availability cache. */\nexport interface AvailabilityCacheConfig {\n /** Time-to-live in ms for probe results. Default: 60_000 (1 min). */\n readonly ttlMs?: number;\n /** Maximum entries in the cache. Default: 50. */\n readonly maxEntries?: number;\n}\n\n/** A function that probes whether a model is reachable. */\nexport type ProbeFn = (modelId: ModelId) => Promise<ProbeResult>;\n\n/** Fallback chain entry with model and reason for fallback. */\nexport interface FallbackEntry {\n readonly modelId: ModelId;\n readonly reason: string;\n}\n\n// ---------------------------------------------------------------------------\n// Availability Cache\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TTL_MS = 60_000;\nconst DEFAULT_MAX_ENTRIES = 50;\n\n/**\n * Bounded TTL cache for model availability probe results.\n * Thread-safe for single-threaded Node.js; no locks needed.\n */\nexport class AvailabilityCache {\n private readonly cache = new Map<ModelId, ProbeResult>();\n private readonly ttlMs: number;\n private readonly maxEntries: number;\n\n constructor(config: AvailabilityCacheConfig = {}) {\n this.ttlMs = config.ttlMs ?? DEFAULT_TTL_MS;\n this.maxEntries = config.maxEntries ?? DEFAULT_MAX_ENTRIES;\n }\n\n /** Get a cached probe result, or undefined if expired/missing. */\n get(modelId: ModelId): ProbeResult | undefined {\n const entry = this.cache.get(modelId);\n if (entry === undefined) return undefined;\n if (getTimeProvider().now() - entry.checkedAt > this.ttlMs) {\n this.cache.delete(modelId);\n return undefined;\n }\n return entry;\n }\n\n /** Store a probe result, evicting oldest if at capacity. */\n set(result: ProbeResult): void {\n if (this.cache.size >= this.maxEntries && !this.cache.has(result.modelId)) {\n const oldest = this.cache.keys().next();\n if (oldest.done !== true) {\n this.cache.delete(oldest.value);\n }\n }\n this.cache.set(result.modelId, result);\n }\n\n /** Mark a model as unavailable without a full probe. */\n markUnavailable(modelId: ModelId, error: string): void {\n this.set({\n modelId,\n available: false,\n latencyMs: 0,\n checkedAt: getTimeProvider().now(),\n error,\n });\n }\n\n /** Mark a model as available. */\n markAvailable(modelId: ModelId, latencyMs: number): void {\n this.set({\n modelId,\n available: true,\n latencyMs,\n checkedAt: getTimeProvider().now(),\n });\n }\n\n /** Check if a model is known-unavailable (cached and not expired). */\n isKnownUnavailable(modelId: ModelId): boolean {\n const entry = this.get(modelId);\n return entry !== undefined && !entry.available;\n }\n\n /** Get all cached entries (for diagnostics). */\n entries(): ReadonlyArray<ProbeResult> {\n return [...this.cache.values()];\n }\n\n /** Number of cached entries. */\n get size(): number {\n return this.cache.size;\n }\n\n /** Clear all cached entries. */\n clear(): void {\n this.cache.clear();\n }\n}\n\n// ---------------------------------------------------------------------------\n// Fallback Chain Resolution\n// ---------------------------------------------------------------------------\n\n/** Default fallback order per CLI (strongest → weakest). */\nconst FALLBACK_CHAINS: Readonly<Record<CliNameLiteral, readonly ModelId[]>> = {\n claude: ['claude-opus', 'claude-sonnet', 'claude-haiku'],\n gemini: ['gemini-3-pro', 'gemini-pro', 'gemini-3-flash', 'gemini-flash'],\n codex: ['codex-5.3', 'codex-5.2', 'codex-5.1-mini'],\n opencode: ['opencode-custom-opus', 'opencode-custom-sonnet', 'opencode-default'],\n};\n\n/**\n * Resolves a fallback chain for a given model.\n * Returns the first available model in the chain, skipping known-unavailable ones.\n */\nexport function resolveFallback(modelId: ModelId, cache: AvailabilityCache): FallbackEntry | null {\n const cli = getCliForModelId(modelId);\n if (cli === undefined) return null;\n\n const chain = FALLBACK_CHAINS[cli];\n for (const candidate of chain) {\n if (candidate === modelId) continue;\n if (!cache.isKnownUnavailable(candidate)) {\n return {\n modelId: candidate,\n reason: `Fallback from ${modelId} (unavailable) to ${candidate}`,\n };\n }\n }\n return null;\n}\n\n/**\n * Get the fallback chain for a CLI tool.\n */\nexport function getFallbackChain(cli: CliNameLiteral): readonly ModelId[] {\n return FALLBACK_CHAINS[cli];\n}\n\n/**\n * Get the CLI name for a model ID.\n */\nexport function getCliForModelId(modelId: ModelId): CliNameLiteral | undefined {\n for (const [cli, defaultModel] of Object.entries(DEFAULT_MODEL_PER_CLI)) {\n const chain = FALLBACK_CHAINS[cli as CliNameLiteral];\n if (chain.includes(modelId)) return cli as CliNameLiteral;\n if (defaultModel === modelId) return cli as CliNameLiteral;\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Singleton Cache (shared across the process)\n// ---------------------------------------------------------------------------\n\nlet globalCache: AvailabilityCache | undefined;\n\n/** Get the shared availability cache (lazy-init). */\nexport function getAvailabilityCache(): AvailabilityCache {\n globalCache ??= new AvailabilityCache();\n return globalCache;\n}\n\n/** Reset the global cache (for testing). */\nexport function resetAvailabilityCache(): void {\n globalCache = undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Filter Integration\n// ---------------------------------------------------------------------------\n\n/**\n * Filters out known-unavailable models from a set of model IDs.\n * Returns the filtered set, or null if no models were removed.\n * Used by scoreAllModels() to skip unavailable models.\n */\nexport function filterAvailableModels(\n modelIds: readonly string[],\n cache: AvailabilityCache\n): { available: string[]; removed: string[] } {\n const available: string[] = [];\n const removed: string[] = [];\n for (const id of modelIds) {\n if (cache.isKnownUnavailable(id as ModelId)) {\n removed.push(id);\n } else {\n available.push(id);\n }\n }\n return { available, removed };\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  GitHubProvider,
3
3
  ScmError
4
- } from "./chunk-SD76JZBG.js";
4
+ } from "./chunk-UVALD724.js";
5
5
  import {
6
6
  CACHE_TIMEOUTS,
7
7
  createLogger,
8
8
  err,
9
9
  getTimeProvider,
10
10
  ok
11
- } from "./chunk-WDYCIJWN.js";
11
+ } from "./chunk-YMT6H2HQ.js";
12
12
 
13
13
  // src/security/trust-types.ts
14
14
  import { z } from "zod";
@@ -1656,4 +1656,4 @@ export {
1656
1656
  IssueTriage,
1657
1657
  createIssueTriage
1658
1658
  };
1659
- //# sourceMappingURL=chunk-6TFTVW77.js.map
1659
+ //# sourceMappingURL=chunk-QVHXEQFM.js.map
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  createLogger,
6
6
  getTimeProvider
7
- } from "./chunk-WDYCIJWN.js";
7
+ } from "./chunk-YMT6H2HQ.js";
8
8
 
9
9
  // src/mcp/tools/scanner-registry-fetcher.ts
10
10
  import { z } from "zod";
@@ -721,4 +721,4 @@ export {
721
721
  generateSecurityPlan,
722
722
  buildPlanFromAnalysis
723
723
  };
724
- //# sourceMappingURL=chunk-FJWWSVWB.js.map
724
+ //# sourceMappingURL=chunk-RIUUFBX4.js.map
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  getToolMemory
3
- } from "./chunk-Q5CFPIJ5.js";
3
+ } from "./chunk-OO6MTUDS.js";
4
4
  import {
5
5
  CLI_NAMES,
6
6
  StrategyDistiller,
7
7
  createLogger,
8
8
  getOutcomeStore,
9
9
  registerPersistentDistillerFactory
10
- } from "./chunk-WDYCIJWN.js";
10
+ } from "./chunk-YMT6H2HQ.js";
11
11
  import {
12
12
  ensureLearningDir,
13
13
  getRulesFile
14
- } from "./chunk-7BMOZJYS.js";
14
+ } from "./chunk-2JQXC3CK.js";
15
15
 
16
16
  // src/learning/strategy-distiller-persistence.ts
17
17
  import { writeFileSync, readFileSync, renameSync, unlinkSync, existsSync } from "fs";
@@ -273,4 +273,4 @@ export {
273
273
  inferTaskCategory,
274
274
  summarizeContextForPrompt
275
275
  };
276
- //# sourceMappingURL=chunk-DNO2INX5.js.map
276
+ //# sourceMappingURL=chunk-SHVGZK4A.js.map