nexus-agents 2.79.3 → 2.79.4

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 (113) hide show
  1. package/README.md +2 -2
  2. package/dist/{child-mcp-config-CTO2MBRM.js → child-mcp-config-DFRYTRBK.js} +2 -2
  3. package/dist/{chunk-HB4MIDHJ.js → chunk-3ENBGGYA.js} +104 -61
  4. package/dist/{chunk-HB4MIDHJ.js.map → chunk-3ENBGGYA.js.map} +1 -1
  5. package/dist/{chunk-6E3NMMEY.js → chunk-3RZWLQSC.js} +2 -2
  6. package/dist/{chunk-6E3NMMEY.js.map → chunk-3RZWLQSC.js.map} +1 -1
  7. package/dist/{chunk-KT5FIBWS.js → chunk-42MM7GKW.js} +2 -2
  8. package/dist/{chunk-3NIPH6UP.js → chunk-45NUO4FE.js} +2 -2
  9. package/dist/{chunk-2YPG6PDG.js → chunk-ACP4YARI.js} +3 -3
  10. package/dist/{chunk-D6TM2VHX.js → chunk-BIH2CBC5.js} +44 -21
  11. package/dist/chunk-BIH2CBC5.js.map +1 -0
  12. package/dist/{chunk-SD76JZBG.js → chunk-BSQ4KTY4.js} +2 -2
  13. package/dist/{chunk-6TFTVW77.js → chunk-BXI6DKBU.js} +3 -3
  14. package/dist/{chunk-PLX6FCFC.js → chunk-DOI7RE3X.js} +2 -2
  15. package/dist/{chunk-SWFJU3W2.js → chunk-DW3UTO43.js} +56 -46
  16. package/dist/{chunk-SWFJU3W2.js.map → chunk-DW3UTO43.js.map} +1 -1
  17. package/dist/{chunk-7XCUZI4G.js → chunk-IPDUZJPH.js} +3 -3
  18. package/dist/{chunk-2UYTFLMO.js → chunk-JMRCMMZ5.js} +2 -2
  19. package/dist/{chunk-GONMG4NM.js → chunk-LFTK5ZQG.js} +2 -2
  20. package/dist/{chunk-DLXT23AC.js → chunk-NJPFN75N.js} +2 -2
  21. package/dist/{chunk-YXWGEIQR.js → chunk-NVSJXN4S.js} +2 -2
  22. package/dist/{chunk-Q5CFPIJ5.js → chunk-NXNNT5XW.js} +3 -3
  23. package/dist/chunk-OFRDE7MK.js +136 -0
  24. package/dist/chunk-OFRDE7MK.js.map +1 -0
  25. package/dist/{chunk-L6SCKLGO.js → chunk-OGV7J5WG.js} +3 -3
  26. package/dist/{chunk-ZVCED4Z4.js → chunk-PAKVXGS2.js} +2 -2
  27. package/dist/{chunk-DNO2INX5.js → chunk-PDCLBWH5.js} +3 -3
  28. package/dist/{chunk-K2QILJG4.js → chunk-PHBRELUK.js} +33 -9
  29. package/dist/chunk-PHBRELUK.js.map +1 -0
  30. package/dist/{chunk-JI7S55R3.js → chunk-SU3Y6LU2.js} +8 -8
  31. package/dist/chunk-SU3Y6LU2.js.map +1 -0
  32. package/dist/{chunk-FJWWSVWB.js → chunk-TN5ZKSGC.js} +2 -2
  33. package/dist/{chunk-5O6XLBPP.js → chunk-UNFS6YBY.js} +2 -2
  34. package/dist/{chunk-HYU4GZY6.js → chunk-UNRTM43V.js} +2 -2
  35. package/dist/{chunk-VIQOVK4E.js → chunk-UOR2JWFH.js} +7 -136
  36. package/dist/chunk-UOR2JWFH.js.map +1 -0
  37. package/dist/{chunk-WDYCIJWN.js → chunk-UQOSVOEU.js} +4 -3
  38. package/dist/{chunk-WDYCIJWN.js.map → chunk-UQOSVOEU.js.map} +1 -1
  39. package/dist/{chunk-FVPYP5DD.js → chunk-UWDVEMYZ.js} +4 -4
  40. package/dist/{cli-circuit-breaker-I74ZQ44Q.js → cli-circuit-breaker-T75HOLZK.js} +4 -4
  41. package/dist/cli.js +46 -45
  42. package/dist/cli.js.map +1 -1
  43. package/dist/{composite-router-V3OC57IE.js → composite-router-OPSK5FCQ.js} +2 -2
  44. package/dist/{consensus-vote-ESFPGEJE.js → consensus-vote-CYUPIJXR.js} +11 -11
  45. package/dist/{context-retriever-MB3D7KS6.js → context-retriever-6AWHCHRP.js} +5 -5
  46. package/dist/{doctor-deep-KQ765XZA.js → doctor-deep-XBPRQ6ZP.js} +3 -3
  47. package/dist/expert-bridge-5YOPK5IT.js +11 -0
  48. package/dist/{factory-BUUXNGIB.js → factory-DN7SJZ5Z.js} +5 -5
  49. package/dist/{factory-LHHYDVZX.js → factory-Y3TMP4OQ.js} +4 -4
  50. package/dist/index.d.ts +24 -2
  51. package/dist/index.js +30 -28
  52. package/dist/index.js.map +1 -1
  53. package/dist/{init-opencode-GXZN2W5S.js → init-opencode-RV6IQEMS.js} +5 -5
  54. package/dist/{issue-triage-RMXPDZ2K.js → issue-triage-UTWKXLKC.js} +4 -4
  55. package/dist/{pr-reviewer-helpers-XCY7HOPE.js → pr-reviewer-helpers-L4L324FQ.js} +2 -2
  56. package/dist/{registry-command-6E4YKAMT.js → registry-command-6KJWW3W7.js} +2 -2
  57. package/dist/{repo-security-plan-AGRU72DL.js → repo-security-plan-HNLMF7J7.js} +3 -3
  58. package/dist/{research-helpers-synthesize-K2UCJQQG.js → research-helpers-synthesize-77TLYSW4.js} +3 -3
  59. package/dist/{routing-memory-3B6DDZ76.js → routing-memory-6DV6ZPAH.js} +2 -2
  60. package/dist/{session-memory-L7EQIY2O.js → session-memory-XZ3NJIR4.js} +3 -3
  61. package/dist/{setup-command-QSAGFMGN.js → setup-command-QOXG36UV.js} +10 -9
  62. package/dist/{setup-config-EQT24DD4.js → setup-config-B4V4QHDP.js} +3 -3
  63. package/dist/{setup-custom-api-IBDV654K.js → setup-custom-api-PJ6TGHJH.js} +4 -4
  64. package/dist/{tool-memory-6HCHQLAN.js → tool-memory-K2QPTPKV.js} +4 -4
  65. package/dist/{weather-report-ER3WUZ7S.js → weather-report-ZB4AKOIA.js} +2 -2
  66. package/package.json +4 -4
  67. package/scripts/postinstall.js +1 -1
  68. package/dist/chunk-D6TM2VHX.js.map +0 -1
  69. package/dist/chunk-JI7S55R3.js.map +0 -1
  70. package/dist/chunk-K2QILJG4.js.map +0 -1
  71. package/dist/chunk-VIQOVK4E.js.map +0 -1
  72. package/dist/expert-bridge-JKLC57IC.js +0 -10
  73. /package/dist/{child-mcp-config-CTO2MBRM.js.map → child-mcp-config-DFRYTRBK.js.map} +0 -0
  74. /package/dist/{chunk-KT5FIBWS.js.map → chunk-42MM7GKW.js.map} +0 -0
  75. /package/dist/{chunk-3NIPH6UP.js.map → chunk-45NUO4FE.js.map} +0 -0
  76. /package/dist/{chunk-2YPG6PDG.js.map → chunk-ACP4YARI.js.map} +0 -0
  77. /package/dist/{chunk-SD76JZBG.js.map → chunk-BSQ4KTY4.js.map} +0 -0
  78. /package/dist/{chunk-6TFTVW77.js.map → chunk-BXI6DKBU.js.map} +0 -0
  79. /package/dist/{chunk-PLX6FCFC.js.map → chunk-DOI7RE3X.js.map} +0 -0
  80. /package/dist/{chunk-7XCUZI4G.js.map → chunk-IPDUZJPH.js.map} +0 -0
  81. /package/dist/{chunk-2UYTFLMO.js.map → chunk-JMRCMMZ5.js.map} +0 -0
  82. /package/dist/{chunk-GONMG4NM.js.map → chunk-LFTK5ZQG.js.map} +0 -0
  83. /package/dist/{chunk-DLXT23AC.js.map → chunk-NJPFN75N.js.map} +0 -0
  84. /package/dist/{chunk-YXWGEIQR.js.map → chunk-NVSJXN4S.js.map} +0 -0
  85. /package/dist/{chunk-Q5CFPIJ5.js.map → chunk-NXNNT5XW.js.map} +0 -0
  86. /package/dist/{chunk-L6SCKLGO.js.map → chunk-OGV7J5WG.js.map} +0 -0
  87. /package/dist/{chunk-ZVCED4Z4.js.map → chunk-PAKVXGS2.js.map} +0 -0
  88. /package/dist/{chunk-DNO2INX5.js.map → chunk-PDCLBWH5.js.map} +0 -0
  89. /package/dist/{chunk-FJWWSVWB.js.map → chunk-TN5ZKSGC.js.map} +0 -0
  90. /package/dist/{chunk-5O6XLBPP.js.map → chunk-UNFS6YBY.js.map} +0 -0
  91. /package/dist/{chunk-HYU4GZY6.js.map → chunk-UNRTM43V.js.map} +0 -0
  92. /package/dist/{chunk-FVPYP5DD.js.map → chunk-UWDVEMYZ.js.map} +0 -0
  93. /package/dist/{cli-circuit-breaker-I74ZQ44Q.js.map → cli-circuit-breaker-T75HOLZK.js.map} +0 -0
  94. /package/dist/{composite-router-V3OC57IE.js.map → composite-router-OPSK5FCQ.js.map} +0 -0
  95. /package/dist/{consensus-vote-ESFPGEJE.js.map → consensus-vote-CYUPIJXR.js.map} +0 -0
  96. /package/dist/{context-retriever-MB3D7KS6.js.map → context-retriever-6AWHCHRP.js.map} +0 -0
  97. /package/dist/{doctor-deep-KQ765XZA.js.map → doctor-deep-XBPRQ6ZP.js.map} +0 -0
  98. /package/dist/{expert-bridge-JKLC57IC.js.map → expert-bridge-5YOPK5IT.js.map} +0 -0
  99. /package/dist/{factory-BUUXNGIB.js.map → factory-DN7SJZ5Z.js.map} +0 -0
  100. /package/dist/{factory-LHHYDVZX.js.map → factory-Y3TMP4OQ.js.map} +0 -0
  101. /package/dist/{init-opencode-GXZN2W5S.js.map → init-opencode-RV6IQEMS.js.map} +0 -0
  102. /package/dist/{issue-triage-RMXPDZ2K.js.map → issue-triage-UTWKXLKC.js.map} +0 -0
  103. /package/dist/{pr-reviewer-helpers-XCY7HOPE.js.map → pr-reviewer-helpers-L4L324FQ.js.map} +0 -0
  104. /package/dist/{registry-command-6E4YKAMT.js.map → registry-command-6KJWW3W7.js.map} +0 -0
  105. /package/dist/{repo-security-plan-AGRU72DL.js.map → repo-security-plan-HNLMF7J7.js.map} +0 -0
  106. /package/dist/{research-helpers-synthesize-K2UCJQQG.js.map → research-helpers-synthesize-77TLYSW4.js.map} +0 -0
  107. /package/dist/{routing-memory-3B6DDZ76.js.map → routing-memory-6DV6ZPAH.js.map} +0 -0
  108. /package/dist/{session-memory-L7EQIY2O.js.map → session-memory-XZ3NJIR4.js.map} +0 -0
  109. /package/dist/{setup-command-QSAGFMGN.js.map → setup-command-QOXG36UV.js.map} +0 -0
  110. /package/dist/{setup-config-EQT24DD4.js.map → setup-config-B4V4QHDP.js.map} +0 -0
  111. /package/dist/{setup-custom-api-IBDV654K.js.map → setup-custom-api-PJ6TGHJH.js.map} +0 -0
  112. /package/dist/{tool-memory-6HCHQLAN.js.map → tool-memory-K2QPTPKV.js.map} +0 -0
  113. /package/dist/{weather-report-ER3WUZ7S.js.map → weather-report-ZB4AKOIA.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  OpenAIAdapter
3
- } from "./chunk-L6SCKLGO.js";
3
+ } from "./chunk-OGV7J5WG.js";
4
4
  import {
5
5
  ConfigError,
6
6
  createLogger,
@@ -9,7 +9,7 @@ import {
9
9
  getTimeProvider,
10
10
  lookupInTreeCapability,
11
11
  ok
12
- } from "./chunk-WDYCIJWN.js";
12
+ } from "./chunk-UQOSVOEU.js";
13
13
  import {
14
14
  getNexusDataDir
15
15
  } from "./chunk-7BMOZJYS.js";
@@ -307,4 +307,4 @@ export {
307
307
  discoverModels,
308
308
  buildOpenAICompatAdapters
309
309
  };
310
- //# sourceMappingURL=chunk-7XCUZI4G.js.map
310
+ //# sourceMappingURL=chunk-IPDUZJPH.js.map
@@ -2,7 +2,7 @@ import {
2
2
  TASK_CATEGORIES,
3
3
  getAdaptiveBonus,
4
4
  getOutcomeStore
5
- } from "./chunk-WDYCIJWN.js";
5
+ } from "./chunk-UQOSVOEU.js";
6
6
 
7
7
  // src/cli/doctor-deep.ts
8
8
  var CLI_NAMES = ["claude", "gemini", "codex", "opencode"];
@@ -106,4 +106,4 @@ export {
106
106
  runDeepDiagnostics,
107
107
  formatDeepDiagnostics
108
108
  };
109
- //# sourceMappingURL=chunk-2UYTFLMO.js.map
109
+ //# sourceMappingURL=chunk-JMRCMMZ5.js.map
@@ -2,7 +2,7 @@ import {
2
2
  createLogger,
3
3
  err,
4
4
  ok
5
- } from "./chunk-WDYCIJWN.js";
5
+ } from "./chunk-UQOSVOEU.js";
6
6
 
7
7
  // src/scm/token-resolver.ts
8
8
  import { execFile } from "child_process";
@@ -87,4 +87,4 @@ export {
87
87
  hasToken,
88
88
  getTokenEnvVars
89
89
  };
90
- //# sourceMappingURL=chunk-GONMG4NM.js.map
90
+ //# sourceMappingURL=chunk-LFTK5ZQG.js.map
@@ -5,7 +5,7 @@ import {
5
5
  getErrorMessage,
6
6
  getTimeProvider,
7
7
  ok
8
- } from "./chunk-WDYCIJWN.js";
8
+ } from "./chunk-UQOSVOEU.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-NJPFN75N.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getErrorMessage
3
- } from "./chunk-WDYCIJWN.js";
3
+ } from "./chunk-UQOSVOEU.js";
4
4
 
5
5
  // src/cli/setup-config.ts
6
6
  import { copyFileSync, existsSync, writeFileSync } from "fs";
@@ -74,4 +74,4 @@ function ensureBackup(outputPath) {
74
74
  export {
75
75
  runConfigInitSync
76
76
  };
77
- //# sourceMappingURL=chunk-YXWGEIQR.js.map
77
+ //# sourceMappingURL=chunk-NVSJXN4S.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-45NUO4FE.js";
12
12
  import {
13
13
  ErrorCode,
14
14
  NexusError,
@@ -22,7 +22,7 @@ import {
22
22
  getTimeProvider,
23
23
  ok,
24
24
  setSharedMobiMemDbPathResolver
25
- } from "./chunk-WDYCIJWN.js";
25
+ } from "./chunk-UQOSVOEU.js";
26
26
  import {
27
27
  nexusDataPath
28
28
  } from "./chunk-7BMOZJYS.js";
@@ -5578,4 +5578,4 @@ export {
5578
5578
  reinitializeMemoryBackends,
5579
5579
  ToolMemoryManager
5580
5580
  };
5581
- //# sourceMappingURL=chunk-Q5CFPIJ5.js.map
5581
+ //# sourceMappingURL=chunk-NXNNT5XW.js.map
@@ -0,0 +1,136 @@
1
+ import {
2
+ DEFAULT_MODEL_PER_CLI,
3
+ getTimeProvider
4
+ } from "./chunk-UQOSVOEU.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-OFRDE7MK.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":[]}
@@ -3,14 +3,14 @@ import {
3
3
  createStream,
4
4
  requireApiKey,
5
5
  validateApiKeyPresence
6
- } from "./chunk-PLX6FCFC.js";
6
+ } from "./chunk-DOI7RE3X.js";
7
7
  import {
8
8
  ModelCapability,
9
9
  err,
10
10
  getCliModelName,
11
11
  getTokenEstimator,
12
12
  ok
13
- } from "./chunk-WDYCIJWN.js";
13
+ } from "./chunk-UQOSVOEU.js";
14
14
 
15
15
  // src/adapters/openai-types.ts
16
16
  var OPENAI_MODELS = {
@@ -553,4 +553,4 @@ export {
553
553
  OpenAIAdapter,
554
554
  createOpenAIAdapter
555
555
  };
556
- //# sourceMappingURL=chunk-L6SCKLGO.js.map
556
+ //# sourceMappingURL=chunk-OGV7J5WG.js.map
@@ -2,7 +2,7 @@ import {
2
2
  ConfigError,
3
3
  err,
4
4
  ok
5
- } from "./chunk-WDYCIJWN.js";
5
+ } from "./chunk-UQOSVOEU.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-PAKVXGS2.js.map
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  getToolMemory
3
- } from "./chunk-Q5CFPIJ5.js";
3
+ } from "./chunk-NXNNT5XW.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-UQOSVOEU.js";
11
11
  import {
12
12
  ensureLearningDir,
13
13
  getRulesFile
@@ -273,4 +273,4 @@ export {
273
273
  inferTaskCategory,
274
274
  summarizeContextForPrompt
275
275
  };
276
- //# sourceMappingURL=chunk-DNO2INX5.js.map
276
+ //# sourceMappingURL=chunk-PDCLBWH5.js.map
@@ -1,10 +1,19 @@
1
1
  import {
2
+ getCliForModelId
3
+ } from "./chunk-OFRDE7MK.js";
4
+ import {
5
+ MODEL_IDS,
2
6
  createLogger,
3
7
  getTimeProvider,
4
8
  isRateLimitText
5
- } from "./chunk-WDYCIJWN.js";
9
+ } from "./chunk-UQOSVOEU.js";
6
10
 
7
11
  // src/pipeline/expert-bridge.ts
12
+ function resolveCliFromModelString(model) {
13
+ if (model === void 0) return void 0;
14
+ if (!MODEL_IDS.includes(model)) return void 0;
15
+ return getCliForModelId(model);
16
+ }
8
17
  var logger = createLogger({ component: "expert-bridge" });
9
18
  var RATE_LIMIT_BASE_DELAY_MS = 3e3;
10
19
  var cachedRouter = null;
@@ -12,7 +21,7 @@ var cachedMcpConfigPath = null;
12
21
  async function getMcpConfigPath() {
13
22
  if (cachedMcpConfigPath !== null) return cachedMcpConfigPath;
14
23
  try {
15
- const { generateMcpConfig } = await import("./child-mcp-config-CTO2MBRM.js");
24
+ const { generateMcpConfig } = await import("./child-mcp-config-DFRYTRBK.js");
16
25
  const config = await generateMcpConfig();
17
26
  cachedMcpConfigPath = config.configPath;
18
27
  return cachedMcpConfigPath;
@@ -30,7 +39,12 @@ function adaptCompositeRouter(compositeRouter) {
30
39
  };
31
40
  const result = await compositeRouter.executeTask(cliTask);
32
41
  if (result.ok) {
33
- return { ok: true, value: { text: result.value.text }, error: { message: "" } };
42
+ const cli = resolveCliFromModelString(result.value.model);
43
+ return {
44
+ ok: true,
45
+ value: { text: result.value.text, ...cli !== void 0 && { cli } },
46
+ error: { message: "" }
47
+ };
34
48
  }
35
49
  return { ok: false, value: { text: "" }, error: { message: result.error.message } };
36
50
  }
@@ -38,13 +52,13 @@ function adaptCompositeRouter(compositeRouter) {
38
52
  }
39
53
  async function getRouter() {
40
54
  if (cachedRouter !== null) return cachedRouter;
41
- const { createAllAdapters } = await import("./factory-LHHYDVZX.js");
42
- const { createCompositeRouter } = await import("./composite-router-V3OC57IE.js");
55
+ const { createAllAdapters } = await import("./factory-Y3TMP4OQ.js");
56
+ const { createCompositeRouter } = await import("./composite-router-OPSK5FCQ.js");
43
57
  const adapters = createAllAdapters();
44
58
  if (adapters.size === 0) return null;
45
59
  cachedRouter = adaptCompositeRouter(createCompositeRouter(adapters));
46
60
  try {
47
- const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-I74ZQ44Q.js");
61
+ const { createCliCircuitBreakerIntegration } = await import("./cli-circuit-breaker-T75HOLZK.js");
48
62
  cachedCircuitBreaker = createCliCircuitBreakerIntegration([...adapters.values()]);
49
63
  } catch (error) {
50
64
  const msg = error instanceof Error ? error.message : String(error);
@@ -69,8 +83,18 @@ async function dispatchWithRateLimitRetry(router, task, expertType, start) {
69
83
  const result = await router.executeTask(task);
70
84
  const durationMs = getTimeProvider().now() - start;
71
85
  if (result.ok) {
72
- logger.info("Expert executed successfully", { expertType, durationMs });
73
- return { success: true, text: result.value.text, expertType, durationMs };
86
+ logger.info("Expert executed successfully", {
87
+ expertType,
88
+ durationMs,
89
+ cli: result.value.cli
90
+ });
91
+ return {
92
+ success: true,
93
+ text: result.value.text,
94
+ expertType,
95
+ durationMs,
96
+ ...result.value.cli !== void 0 && { cli: result.value.cli }
97
+ };
74
98
  }
75
99
  const isRateLimit = isRateLimitText(result.error.message);
76
100
  if (isRateLimit && attempt < maxAttempts - 1) {
@@ -136,4 +160,4 @@ ${prompt}`;
136
160
  export {
137
161
  executeExpert
138
162
  };
139
- //# sourceMappingURL=chunk-K2QILJG4.js.map
163
+ //# sourceMappingURL=chunk-PHBRELUK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pipeline/expert-bridge.ts"],"sourcesContent":["/**\n * Expert Bridge — Programmatic access to the execute_expert pipeline (#1693)\n *\n * Provides a clean wrapper for calling experts with the full pipeline:\n * timeout, fallback cascade, degradation detection, heartbeat, outcome recording.\n *\n * DRY: reuses createBuiltInExpert + CompositeRouter instead of reimplementing.\n *\n * @module pipeline/expert-bridge\n */\n\nimport { createLogger, getTimeProvider } from '../core/index.js';\nimport type { BuiltInExpertType } from '../agents/experts/expert-config.js';\nimport { isRateLimitText } from '../adapters/rate-limit-detector.js';\nimport { getCliForModelId } from '../config/model-availability.js';\nimport { MODEL_IDS } from '../config/model-capabilities-types.js';\nimport type { CliNameLiteral, ModelId } from '../config/model-capabilities-types.js';\n\n/**\n * Resolves a CLI from a possibly-unknown model string returned by a CLI\n * response. Returns undefined if the model string isn't in the registry —\n * caller treats undefined as \"don't know which CLI ran\" rather than\n * fabricating a default (#2823).\n */\nfunction resolveCliFromModelString(model: string | undefined): CliNameLiteral | undefined {\n if (model === undefined) return undefined;\n if (!(MODEL_IDS as readonly string[]).includes(model)) return undefined;\n return getCliForModelId(model as ModelId);\n}\n\nconst logger = createLogger({ component: 'expert-bridge' });\n\n/** Base delay for rate limit retry backoff (ms). Scales linearly: 3s, 6s, 9s. */\nconst RATE_LIMIT_BASE_DELAY_MS = 3000;\n\n/** Result of an expert execution. */\nexport interface ExpertBridgeResult {\n readonly success: boolean;\n readonly text: string;\n readonly expertType: BuiltInExpertType;\n readonly durationMs: number;\n readonly error?: string;\n /**\n * CLI that actually executed the task, resolved from the underlying\n * `CliResponse.model` via `getCliForModelId`. Undefined when the bridge\n * failed before dispatch (no adapters / circuit-open / rate-limit cap).\n * Callers writing to OutcomeStore should use this rather than hardcoding\n * a cli — see #2823 (#1154 regression).\n */\n readonly cli?: CliNameLiteral;\n}\n\n/**\n * Execute an expert task with the full nexus-agents expert pipeline.\n *\n * Creates a built-in expert, executes via CompositeRouter (for intelligent\n * CLI routing), and records outcomes. Falls back gracefully on failure.\n *\n * @param expertType - Built-in expert type (code, architecture, security, qa, etc.)\n * @param prompt - Task prompt for the expert\n * @returns Expert result with text output\n */\n/** Minimal router interface for the bridge. */\ninterface RouterLike {\n executeTask(task: { content: string; options?: Record<string, unknown> | undefined }): Promise<{\n ok: boolean;\n value: { text: string; cli?: CliNameLiteral };\n error: { message: string };\n }>;\n}\n\n// Cached router — lazily initialized, reused across calls within a session\nlet cachedRouter: RouterLike | null = null;\n\n// Cached MCP config — generated once, reused across expert calls (#1708)\nlet cachedMcpConfigPath: string | null = null;\n\n/** Get or create cached MCP config path for expert CLI sessions (#1708). */\nasync function getMcpConfigPath(): Promise<string | null> {\n if (cachedMcpConfigPath !== null) return cachedMcpConfigPath;\n try {\n const { generateMcpConfig } = await import('../cli-adapters/child-mcp-config.js');\n const config = await generateMcpConfig();\n cachedMcpConfigPath = config.configPath;\n return cachedMcpConfigPath;\n } catch {\n return null; // MCP config not available — experts run without tools\n }\n}\n\n/** Cached circuit breaker for health monitoring (#1766). */\nlet cachedCircuitBreaker: {\n getHealthStatus(): {\n systemHealthy: boolean;\n healthyCount: number;\n clis: ReadonlyArray<{ name: string; healthy: boolean }>;\n };\n} | null = null;\n\n/**\n * Adapt a CompositeRouter to the narrower RouterLike interface used by this\n * bridge. Previously did `as unknown as RouterLike` which hid any structural\n * mismatch between CompositeRouter's `Result<CliResponse, CliError>` and\n * RouterLike's flat `{ ok, value: { text }, error: { message } }` shape.\n * If CliResponse renames `.text` → `.output` (or similar), this adapter\n * breaks at compile time instead of silently returning wrong data (#1921).\n */\nfunction adaptCompositeRouter(\n compositeRouter: import('../cli-adapters/composite-router.js').ICompositeRouter\n): RouterLike {\n return {\n async executeTask(task): Promise<{\n ok: boolean;\n value: { text: string; cli?: CliNameLiteral };\n error: { message: string };\n }> {\n const cliTask: import('../cli-adapters/types.js').CliTask = {\n content: task.content,\n ...(task.options !== undefined ? { options: task.options } : {}),\n };\n const result = await compositeRouter.executeTask(cliTask);\n if (result.ok) {\n // #2823: surface which CLI actually executed so callers writing to\n // OutcomeStore don't have to hardcode 'claude' (the bug #1154 fixed\n // and that regressed into the pipeline/ tree). Derive via the\n // canonical model→cli mapping in the registry — if the underlying\n // adapter didn't set `model` or the model isn't in the registry,\n // cli stays undefined and downstream code can skip the record\n // rather than lie.\n const cli = resolveCliFromModelString(result.value.model);\n return {\n ok: true,\n value: { text: result.value.text, ...(cli !== undefined && { cli }) },\n error: { message: '' },\n };\n }\n return { ok: false, value: { text: '' }, error: { message: result.error.message } };\n },\n };\n}\n\n/** Get or create a cached CompositeRouter with circuit breaker monitoring. */\nasync function getRouter(): Promise<RouterLike | null> {\n if (cachedRouter !== null) return cachedRouter;\n const { createAllAdapters } = await import('../cli-adapters/factory.js');\n const { createCompositeRouter } = await import('../cli-adapters/composite-router.js');\n const adapters = createAllAdapters();\n if (adapters.size === 0) return null;\n cachedRouter = adaptCompositeRouter(createCompositeRouter(adapters));\n\n // Initialize circuit breaker monitoring (#1766)\n try {\n const { createCliCircuitBreakerIntegration } =\n await import('../cli-adapters/cli-circuit-breaker.js');\n cachedCircuitBreaker = createCliCircuitBreakerIntegration([...adapters.values()]);\n } catch (error: unknown) {\n // Circuit breaker not available — continue without it. Log so we can\n // notice if initialization silently stops working (#1913 Class B).\n const msg = error instanceof Error ? error.message : String(error);\n logger.debug('Circuit breaker init failed; continuing without it', { error: msg });\n }\n\n return cachedRouter;\n}\n\n/** Check CLI health before dispatch (#1766). */\nfunction checkCircuitHealth(): { healthy: boolean; message: string } {\n if (cachedCircuitBreaker === null) return { healthy: true, message: '' };\n const status = cachedCircuitBreaker.getHealthStatus();\n if (!status.systemHealthy) {\n return {\n healthy: false,\n message: `All CLI circuits open (${String(status.healthyCount)}/${String(status.clis.length)} healthy)`,\n };\n }\n return { healthy: true, message: '' };\n}\n\n/** Dispatch task to router with rate limit retry (#1802). */\nasync function dispatchWithRateLimitRetry(\n router: RouterLike,\n task: { content: string; options?: Record<string, unknown> | undefined },\n expertType: BuiltInExpertType,\n start: number\n): Promise<ExpertBridgeResult> {\n const maxAttempts = 3;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const result = await router.executeTask(task);\n const durationMs = getTimeProvider().now() - start;\n\n if (result.ok) {\n logger.info('Expert executed successfully', {\n expertType,\n durationMs,\n cli: result.value.cli,\n });\n return {\n success: true,\n text: result.value.text,\n expertType,\n durationMs,\n ...(result.value.cli !== undefined && { cli: result.value.cli }),\n };\n }\n\n const isRateLimit = isRateLimitText(result.error.message);\n if (isRateLimit && attempt < maxAttempts - 1) {\n const backoffMs = RATE_LIMIT_BASE_DELAY_MS * (attempt + 1);\n logger.warn('Expert rate limited, retrying', { expertType, attempt: attempt + 1, backoffMs });\n await new Promise((resolve) => setTimeout(resolve, backoffMs));\n continue;\n }\n\n logger.warn('Expert execution failed', { expertType, error: result.error.message });\n return { success: false, text: '', expertType, durationMs, error: result.error.message };\n }\n\n return {\n success: false,\n text: '',\n expertType,\n durationMs: getTimeProvider().now() - start,\n error: 'Max retry attempts exceeded',\n };\n}\n\nexport async function executeExpert(\n expertType: BuiltInExpertType,\n prompt: string\n): Promise<ExpertBridgeResult> {\n const start = getTimeProvider().now();\n try {\n const { BUILT_IN_EXPERTS } = await import('../agents/experts/expert-config.js');\n const config = BUILT_IN_EXPERTS[expertType];\n const fullPrompt = `${config.systemPrompt}\\n\\n${prompt}`;\n\n const router = await getRouter();\n if (router === null) {\n return {\n success: false,\n text: `[No adapters] ${prompt}`,\n expertType,\n durationMs: getTimeProvider().now() - start,\n error: 'No CLI adapters available',\n };\n }\n\n // Check circuit breaker health before dispatch (#1766)\n const health = checkCircuitHealth();\n if (!health.healthy) {\n logger.warn('Circuit breaker: all CLIs unavailable', { expertType, reason: health.message });\n return {\n success: false,\n text: '',\n expertType,\n durationMs: getTimeProvider().now() - start,\n error: health.message,\n };\n }\n\n // Pass MCP config so CLI experts can call nexus-agents tools (#1708)\n const mcpConfigPath = await getMcpConfigPath();\n const task: { content: string; options?: Record<string, unknown> | undefined } = {\n content: fullPrompt,\n };\n if (mcpConfigPath !== null) task.options = { mcpConfigPath };\n\n return await dispatchWithRateLimitRetry(router, task, expertType, start);\n } catch (error) {\n const durationMs = getTimeProvider().now() - start;\n const msg = error instanceof Error ? error.message : String(error);\n logger.warn('Expert bridge error', { expertType, error: msg });\n return { success: false, text: '', expertType, durationMs, error: msg };\n }\n}\n"],"mappings":";;;;;;;;;;;AAwBA,SAAS,0BAA0B,OAAuD;AACxF,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,CAAE,UAAgC,SAAS,KAAK,EAAG,QAAO;AAC9D,SAAO,iBAAiB,KAAgB;AAC1C;AAEA,IAAM,SAAS,aAAa,EAAE,WAAW,gBAAgB,CAAC;AAG1D,IAAM,2BAA2B;AAuCjC,IAAI,eAAkC;AAGtC,IAAI,sBAAqC;AAGzC,eAAe,mBAA2C;AACxD,MAAI,wBAAwB,KAAM,QAAO;AACzC,MAAI;AACF,UAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,gCAAqC;AAChF,UAAM,SAAS,MAAM,kBAAkB;AACvC,0BAAsB,OAAO;AAC7B,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,IAAI,uBAMO;AAUX,SAAS,qBACP,iBACY;AACZ,SAAO;AAAA,IACL,MAAM,YAAY,MAIf;AACD,YAAM,UAAsD;AAAA,QAC1D,SAAS,KAAK;AAAA,QACd,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,MAChE;AACA,YAAM,SAAS,MAAM,gBAAgB,YAAY,OAAO;AACxD,UAAI,OAAO,IAAI;AAQb,cAAM,MAAM,0BAA0B,OAAO,MAAM,KAAK;AACxD,eAAO;AAAA,UACL,IAAI;AAAA,UACJ,OAAO,EAAE,MAAM,OAAO,MAAM,MAAM,GAAI,QAAQ,UAAa,EAAE,IAAI,EAAG;AAAA,UACpE,OAAO,EAAE,SAAS,GAAG;AAAA,QACvB;AAAA,MACF;AACA,aAAO,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,GAAG,GAAG,OAAO,EAAE,SAAS,OAAO,MAAM,QAAQ,EAAE;AAAA,IACpF;AAAA,EACF;AACF;AAGA,eAAe,YAAwC;AACrD,MAAI,iBAAiB,KAAM,QAAO;AAClC,QAAM,EAAE,kBAAkB,IAAI,MAAM,OAAO,uBAA4B;AACvE,QAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,gCAAqC;AACpF,QAAM,WAAW,kBAAkB;AACnC,MAAI,SAAS,SAAS,EAAG,QAAO;AAChC,iBAAe,qBAAqB,sBAAsB,QAAQ,CAAC;AAGnE,MAAI;AACF,UAAM,EAAE,mCAAmC,IACzC,MAAM,OAAO,mCAAwC;AACvD,2BAAuB,mCAAmC,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC;AAAA,EAClF,SAAS,OAAgB;AAGvB,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,WAAO,MAAM,sDAAsD,EAAE,OAAO,IAAI,CAAC;AAAA,EACnF;AAEA,SAAO;AACT;AAGA,SAAS,qBAA4D;AACnE,MAAI,yBAAyB,KAAM,QAAO,EAAE,SAAS,MAAM,SAAS,GAAG;AACvE,QAAM,SAAS,qBAAqB,gBAAgB;AACpD,MAAI,CAAC,OAAO,eAAe;AACzB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS,0BAA0B,OAAO,OAAO,YAAY,CAAC,IAAI,OAAO,OAAO,KAAK,MAAM,CAAC;AAAA,IAC9F;AAAA,EACF;AACA,SAAO,EAAE,SAAS,MAAM,SAAS,GAAG;AACtC;AAGA,eAAe,2BACb,QACA,MACA,YACA,OAC6B;AAC7B,QAAM,cAAc;AACpB,WAAS,UAAU,GAAG,UAAU,aAAa,WAAW;AACtD,UAAM,SAAS,MAAM,OAAO,YAAY,IAAI;AAC5C,UAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAE7C,QAAI,OAAO,IAAI;AACb,aAAO,KAAK,gCAAgC;AAAA,QAC1C;AAAA,QACA;AAAA,QACA,KAAK,OAAO,MAAM;AAAA,MACpB,CAAC;AACD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM,OAAO,MAAM;AAAA,QACnB;AAAA,QACA;AAAA,QACA,GAAI,OAAO,MAAM,QAAQ,UAAa,EAAE,KAAK,OAAO,MAAM,IAAI;AAAA,MAChE;AAAA,IACF;AAEA,UAAM,cAAc,gBAAgB,OAAO,MAAM,OAAO;AACxD,QAAI,eAAe,UAAU,cAAc,GAAG;AAC5C,YAAM,YAAY,4BAA4B,UAAU;AACxD,aAAO,KAAK,iCAAiC,EAAE,YAAY,SAAS,UAAU,GAAG,UAAU,CAAC;AAC5F,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,SAAS,CAAC;AAC7D;AAAA,IACF;AAEA,WAAO,KAAK,2BAA2B,EAAE,YAAY,OAAO,OAAO,MAAM,QAAQ,CAAC;AAClF,WAAO,EAAE,SAAS,OAAO,MAAM,IAAI,YAAY,YAAY,OAAO,OAAO,MAAM,QAAQ;AAAA,EACzF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA,YAAY,gBAAgB,EAAE,IAAI,IAAI;AAAA,IACtC,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,cACpB,YACA,QAC6B;AAC7B,QAAM,QAAQ,gBAAgB,EAAE,IAAI;AACpC,MAAI;AACF,UAAM,EAAE,iBAAiB,IAAI,MAAM,OAAO,6BAAoC;AAC9E,UAAM,SAAS,iBAAiB,UAAU;AAC1C,UAAM,aAAa,GAAG,OAAO,YAAY;AAAA;AAAA,EAAO,MAAM;AAEtD,UAAM,SAAS,MAAM,UAAU;AAC/B,QAAI,WAAW,MAAM;AACnB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM,iBAAiB,MAAM;AAAA,QAC7B;AAAA,QACA,YAAY,gBAAgB,EAAE,IAAI,IAAI;AAAA,QACtC,OAAO;AAAA,MACT;AAAA,IACF;AAGA,UAAM,SAAS,mBAAmB;AAClC,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,KAAK,yCAAyC,EAAE,YAAY,QAAQ,OAAO,QAAQ,CAAC;AAC3F,aAAO;AAAA,QACL,SAAS;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,YAAY,gBAAgB,EAAE,IAAI,IAAI;AAAA,QACtC,OAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,gBAAgB,MAAM,iBAAiB;AAC7C,UAAM,OAA2E;AAAA,MAC/E,SAAS;AAAA,IACX;AACA,QAAI,kBAAkB,KAAM,MAAK,UAAU,EAAE,cAAc;AAE3D,WAAO,MAAM,2BAA2B,QAAQ,MAAM,YAAY,KAAK;AAAA,EACzE,SAAS,OAAO;AACd,UAAM,aAAa,gBAAgB,EAAE,IAAI,IAAI;AAC7C,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,WAAO,KAAK,uBAAuB,EAAE,YAAY,OAAO,IAAI,CAAC;AAC7D,WAAO,EAAE,SAAS,OAAO,MAAM,IAAI,YAAY,YAAY,OAAO,IAAI;AAAA,EACxE;AACF;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runConfigInitSync
3
- } from "./chunk-YXWGEIQR.js";
3
+ } from "./chunk-NVSJXN4S.js";
4
4
  import {
5
5
  VERSION,
6
6
  checkApiKeys,
@@ -8,10 +8,10 @@ import {
8
8
  checkSqlite,
9
9
  defaultConfig,
10
10
  initDataDirectories
11
- } from "./chunk-VIQOVK4E.js";
11
+ } from "./chunk-UOR2JWFH.js";
12
12
  import {
13
13
  probeAllClis
14
- } from "./chunk-D6TM2VHX.js";
14
+ } from "./chunk-BIH2CBC5.js";
15
15
  import {
16
16
  BUILT_IN_EXPERTS
17
17
  } from "./chunk-ZM4O442V.js";
@@ -25,7 +25,7 @@ import {
25
25
  getErrorMessage,
26
26
  getTimeProvider,
27
27
  symbols
28
- } from "./chunk-WDYCIJWN.js";
28
+ } from "./chunk-UQOSVOEU.js";
29
29
 
30
30
  // src/cli/setup-command.ts
31
31
  import { existsSync as existsSync4 } from "fs";
@@ -419,7 +419,7 @@ import { join as join3, dirname } from "path";
419
419
  function generateRulesContent() {
420
420
  return `# Nexus-Agents Integration
421
421
 
422
- This project uses [nexus-agents](https://github.com/williamzujkowski/nexus-agents) v${VERSION} for multi-agent orchestration.
422
+ This project uses [nexus-agents](https://github.com/nexus-substrate/nexus-agents) v${VERSION} for multi-agent orchestration.
423
423
 
424
424
  ## MCP Tools Available
425
425
 
@@ -1063,7 +1063,7 @@ function buildPermissionsBanner(snippet) {
1063
1063
  "Without these, each MCP tool call will prompt for approval in interactive",
1064
1064
  "mode, or be rejected outright in `dangerously-skip-permissions` mode.",
1065
1065
  "",
1066
- "Reference: https://github.com/williamzujkowski/nexus-agents/issues/1945",
1066
+ "Reference: https://github.com/nexus-substrate/nexus-agents/issues/1945",
1067
1067
  ""
1068
1068
  ].join("\n");
1069
1069
  }
@@ -1848,7 +1848,7 @@ function printGettingStartedBanner(mcpConfigured) {
1848
1848
  }
1849
1849
  writeLine2(" 3. nexus-agents workflow list \u2014 explore built-in workflows");
1850
1850
  writeEmptyLine2();
1851
- writeLine2(` ${colors.dim}Docs: https://github.com/williamzujkowski/nexus-agents${colors.reset}`);
1851
+ writeLine2(` ${colors.dim}Docs: https://github.com/nexus-substrate/nexus-agents${colors.reset}`);
1852
1852
  writeLine2(` ${colors.dim}Harness wiring: docs/guides/HARNESS_COMPATIBILITY.md${colors.reset}`);
1853
1853
  }
1854
1854
  async function runPostSetupHealthGate(dryRun) {
@@ -1948,4 +1948,4 @@ export {
1948
1948
  setupCommand,
1949
1949
  setupCommandAsync
1950
1950
  };
1951
- //# sourceMappingURL=chunk-JI7S55R3.js.map
1951
+ //# sourceMappingURL=chunk-SU3Y6LU2.js.map