nexus-agents 2.71.0 → 2.72.1

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 (125) hide show
  1. package/dist/{adaptive-memory-MKSYEBST.js → adaptive-memory-UPE76IP6.js} +5 -5
  2. package/dist/{chunk-DWLATKBK.js → child-mcp-config-5HRJGLCR.js} +6 -4
  3. package/dist/child-mcp-config-5HRJGLCR.js.map +1 -0
  4. package/dist/{chunk-ZPPX2K57.js → chunk-2KB63QGE.js} +2 -2
  5. package/dist/{chunk-L2LQ3TSV.js → chunk-2MD5MWCK.js} +2 -2
  6. package/dist/{chunk-ANC3HU6F.js → chunk-345KMHWH.js} +6 -6
  7. package/dist/chunk-345KMHWH.js.map +1 -0
  8. package/dist/{chunk-NER7H3RJ.js → chunk-3FIDMWFC.js} +2 -2
  9. package/dist/{chunk-POQQ7A5E.js → chunk-53K3KEKT.js} +51 -707
  10. package/dist/chunk-53K3KEKT.js.map +1 -0
  11. package/dist/chunk-5MHIWRKB.js +691 -0
  12. package/dist/chunk-5MHIWRKB.js.map +1 -0
  13. package/dist/{chunk-VGZJIR22.js → chunk-5WQ3SRSE.js} +2 -2
  14. package/dist/{chunk-TOYPY5XA.js → chunk-A35XORXU.js} +73 -10
  15. package/dist/chunk-A35XORXU.js.map +1 -0
  16. package/dist/chunk-BVETPIOQ.js +556 -0
  17. package/dist/chunk-BVETPIOQ.js.map +1 -0
  18. package/dist/{chunk-7LHQBMBM.js → chunk-C3JGKBL2.js} +25 -12
  19. package/dist/{chunk-7LHQBMBM.js.map → chunk-C3JGKBL2.js.map} +1 -1
  20. package/dist/{chunk-OF7CYMMA.js → chunk-DA5UDQYW.js} +2 -2
  21. package/dist/{chunk-XATH462F.js → chunk-ES6GFP35.js} +186 -34
  22. package/dist/chunk-ES6GFP35.js.map +1 -0
  23. package/dist/chunk-GOT7OAL5.js +59 -0
  24. package/dist/chunk-GOT7OAL5.js.map +1 -0
  25. package/dist/{chunk-LJT65EA7.js → chunk-I7ORMAO7.js} +2 -2
  26. package/dist/{chunk-AGVLFRN7.js → chunk-J4VR2WNI.js} +2998 -7188
  27. package/dist/chunk-J4VR2WNI.js.map +1 -0
  28. package/dist/{chunk-LMRKHQG5.js → chunk-L6N2S3UB.js} +2 -2
  29. package/dist/{chunk-7OBFO4GF.js → chunk-O4KUCF5S.js} +125 -40
  30. package/dist/chunk-O4KUCF5S.js.map +1 -0
  31. package/dist/chunk-P5OFZWDW.js +303 -0
  32. package/dist/chunk-P5OFZWDW.js.map +1 -0
  33. package/dist/{chunk-MJHOSM5U.js → chunk-QECRZ3YA.js} +2 -2
  34. package/dist/{chunk-WYSHXPKK.js → chunk-QL4HCYRD.js} +4 -44
  35. package/dist/chunk-QL4HCYRD.js.map +1 -0
  36. package/dist/{chunk-E66KFRSJ.js → chunk-TF3GROMO.js} +2 -2
  37. package/dist/{chunk-U3HZQTUF.js → chunk-TQFRPFMG.js} +2 -2
  38. package/dist/{chunk-KJCSRP34.js → chunk-V7ATY4BG.js} +3 -3
  39. package/dist/{chunk-32RIOULO.js → chunk-VPC3YNFR.js} +2 -2
  40. package/dist/{chunk-3BKVYSY6.js → chunk-VTVKC4FS.js} +4 -4
  41. package/dist/{chunk-U6BK5DQU.js → chunk-YOREAPF6.js} +315 -31
  42. package/dist/chunk-YOREAPF6.js.map +1 -0
  43. package/dist/cli-circuit-breaker-GFF2RLBZ.js +14 -0
  44. package/dist/cli.d.ts +3 -1
  45. package/dist/cli.js +1038 -1581
  46. package/dist/cli.js.map +1 -1
  47. package/dist/{composite-router-AYVJPIOS.js → composite-router-33F3F74I.js} +4 -4
  48. package/dist/{consensus-vote-EXWACBMR.js → consensus-vote-5V4KVHBE.js} +12 -11
  49. package/dist/doctor-deep-AHDTNURD.js +13 -0
  50. package/dist/expert-bridge-DMDHHDEU.js +11 -0
  51. package/dist/factory-FVD7PZ6S.js +15 -0
  52. package/dist/{factory-KMBWFIX2.js → factory-VQS3HJ7V.js} +6 -6
  53. package/dist/index.d.ts +997 -3517
  54. package/dist/index.js +74 -807
  55. package/dist/index.js.map +1 -1
  56. package/dist/init-opencode-EIOIPVWL.js +158 -0
  57. package/dist/init-opencode-EIOIPVWL.js.map +1 -0
  58. package/dist/issue-triage-HJUJWGAD.js +16 -0
  59. package/dist/{learning-persistence-FILWP3IR.js → learning-persistence-N6ILD2HX.js} +3 -3
  60. package/dist/{mobimem-77W5ED4Z.js → mobimem-BOJFXQ7B.js} +4 -4
  61. package/dist/{nexus-data-dir-M6DYKIHJ.js → nexus-data-dir-77UO7N6J.js} +2 -2
  62. package/dist/{registry-command-BBLIXULQ.js → registry-command-NCWUJKAF.js} +4 -4
  63. package/dist/{repo-security-plan-7SNM7JQN.js → repo-security-plan-3J45VAD6.js} +5 -5
  64. package/dist/research-helpers-synthesize-UGQHZZJN.js +12 -0
  65. package/dist/{routing-memory-DCIZEEVC.js → routing-memory-NO7QEH7T.js} +4 -4
  66. package/dist/{session-memory-5TSAASQW.js → session-memory-DOXLEWEU.js} +5 -5
  67. package/dist/{setup-command-5VGIQETA.js → setup-command-BWUFMZ7U.js} +10 -10
  68. package/dist/setup-config-E3JZYSLR.js +11 -0
  69. package/dist/{setup-custom-api-IQX3GD2D.js → setup-custom-api-DHJ5DRH2.js} +6 -6
  70. package/dist/{weather-report-NETGWTJX.js → weather-report-FNN4OX3N.js} +4 -4
  71. package/package.json +1 -1
  72. package/dist/chunk-7OBFO4GF.js.map +0 -1
  73. package/dist/chunk-AGVLFRN7.js.map +0 -1
  74. package/dist/chunk-ANC3HU6F.js.map +0 -1
  75. package/dist/chunk-DWLATKBK.js.map +0 -1
  76. package/dist/chunk-FDNWRZNJ.js +0 -22
  77. package/dist/chunk-FDNWRZNJ.js.map +0 -1
  78. package/dist/chunk-POQQ7A5E.js.map +0 -1
  79. package/dist/chunk-TOYPY5XA.js.map +0 -1
  80. package/dist/chunk-U6BK5DQU.js.map +0 -1
  81. package/dist/chunk-WYSHXPKK.js.map +0 -1
  82. package/dist/chunk-XATH462F.js.map +0 -1
  83. package/dist/cli-circuit-breaker-2CJ6NV52.js +0 -14
  84. package/dist/doctor-deep-BJFDBGPO.js +0 -13
  85. package/dist/expert-bridge-75WNNWI4.js +0 -11
  86. package/dist/factory-H5BYL4V5.js +0 -15
  87. package/dist/issue-triage-4SEP4WID.js +0 -16
  88. package/dist/mcp-config-OCWIXE2Y.js +0 -13
  89. package/dist/research-helpers-synthesize-7CI2FJE5.js +0 -12
  90. package/dist/setup-config-EA5RDIO2.js +0 -11
  91. package/dist/weather-report-NETGWTJX.js.map +0 -1
  92. /package/dist/{adaptive-memory-MKSYEBST.js.map → adaptive-memory-UPE76IP6.js.map} +0 -0
  93. /package/dist/{chunk-ZPPX2K57.js.map → chunk-2KB63QGE.js.map} +0 -0
  94. /package/dist/{chunk-L2LQ3TSV.js.map → chunk-2MD5MWCK.js.map} +0 -0
  95. /package/dist/{chunk-NER7H3RJ.js.map → chunk-3FIDMWFC.js.map} +0 -0
  96. /package/dist/{chunk-VGZJIR22.js.map → chunk-5WQ3SRSE.js.map} +0 -0
  97. /package/dist/{chunk-OF7CYMMA.js.map → chunk-DA5UDQYW.js.map} +0 -0
  98. /package/dist/{chunk-LJT65EA7.js.map → chunk-I7ORMAO7.js.map} +0 -0
  99. /package/dist/{chunk-LMRKHQG5.js.map → chunk-L6N2S3UB.js.map} +0 -0
  100. /package/dist/{chunk-MJHOSM5U.js.map → chunk-QECRZ3YA.js.map} +0 -0
  101. /package/dist/{chunk-E66KFRSJ.js.map → chunk-TF3GROMO.js.map} +0 -0
  102. /package/dist/{chunk-U3HZQTUF.js.map → chunk-TQFRPFMG.js.map} +0 -0
  103. /package/dist/{chunk-KJCSRP34.js.map → chunk-V7ATY4BG.js.map} +0 -0
  104. /package/dist/{chunk-32RIOULO.js.map → chunk-VPC3YNFR.js.map} +0 -0
  105. /package/dist/{chunk-3BKVYSY6.js.map → chunk-VTVKC4FS.js.map} +0 -0
  106. /package/dist/{cli-circuit-breaker-2CJ6NV52.js.map → cli-circuit-breaker-GFF2RLBZ.js.map} +0 -0
  107. /package/dist/{composite-router-AYVJPIOS.js.map → composite-router-33F3F74I.js.map} +0 -0
  108. /package/dist/{consensus-vote-EXWACBMR.js.map → consensus-vote-5V4KVHBE.js.map} +0 -0
  109. /package/dist/{doctor-deep-BJFDBGPO.js.map → doctor-deep-AHDTNURD.js.map} +0 -0
  110. /package/dist/{expert-bridge-75WNNWI4.js.map → expert-bridge-DMDHHDEU.js.map} +0 -0
  111. /package/dist/{factory-H5BYL4V5.js.map → factory-FVD7PZ6S.js.map} +0 -0
  112. /package/dist/{factory-KMBWFIX2.js.map → factory-VQS3HJ7V.js.map} +0 -0
  113. /package/dist/{issue-triage-4SEP4WID.js.map → issue-triage-HJUJWGAD.js.map} +0 -0
  114. /package/dist/{learning-persistence-FILWP3IR.js.map → learning-persistence-N6ILD2HX.js.map} +0 -0
  115. /package/dist/{mcp-config-OCWIXE2Y.js.map → mobimem-BOJFXQ7B.js.map} +0 -0
  116. /package/dist/{mobimem-77W5ED4Z.js.map → nexus-data-dir-77UO7N6J.js.map} +0 -0
  117. /package/dist/{registry-command-BBLIXULQ.js.map → registry-command-NCWUJKAF.js.map} +0 -0
  118. /package/dist/{nexus-data-dir-M6DYKIHJ.js.map → repo-security-plan-3J45VAD6.js.map} +0 -0
  119. /package/dist/{repo-security-plan-7SNM7JQN.js.map → research-helpers-synthesize-UGQHZZJN.js.map} +0 -0
  120. /package/dist/{research-helpers-synthesize-7CI2FJE5.js.map → routing-memory-NO7QEH7T.js.map} +0 -0
  121. /package/dist/{routing-memory-DCIZEEVC.js.map → session-memory-DOXLEWEU.js.map} +0 -0
  122. /package/dist/{session-memory-5TSAASQW.js.map → setup-command-BWUFMZ7U.js.map} +0 -0
  123. /package/dist/{setup-command-5VGIQETA.js.map → setup-config-E3JZYSLR.js.map} +0 -0
  124. /package/dist/{setup-custom-api-IQX3GD2D.js.map → setup-custom-api-DHJ5DRH2.js.map} +0 -0
  125. /package/dist/{setup-config-EA5RDIO2.js.map → weather-report-FNN4OX3N.js.map} +0 -0
@@ -0,0 +1,158 @@
1
+ import {
2
+ discoverModels,
3
+ readOpencodeGateway
4
+ } from "./chunk-P5OFZWDW.js";
5
+ import "./chunk-BVETPIOQ.js";
6
+ import "./chunk-5MHIWRKB.js";
7
+ import {
8
+ createLogger
9
+ } from "./chunk-O4KUCF5S.js";
10
+ import "./chunk-I7ORMAO7.js";
11
+ import "./chunk-GOT7OAL5.js";
12
+ import "./chunk-UP2VWCW5.js";
13
+
14
+ // src/cli/init-opencode.ts
15
+ import { existsSync, readFileSync, writeFileSync } from "fs";
16
+ import { dirname } from "path";
17
+ var logger = createLogger({ component: "init-opencode" });
18
+ function buildNexusMcpBlock(opts) {
19
+ const env = {
20
+ NEXUS_DATA_DIR: "{env:NEXUS_DATA_DIR}",
21
+ NEXUS_OPENCODE_CONFIG: opts.opencodeConfigPath
22
+ };
23
+ if (opts.sandboxFlavor !== void 0 && opts.sandboxFlavor !== "") {
24
+ env["NEXUS_SANDBOX"] = opts.sandboxFlavor;
25
+ }
26
+ return {
27
+ type: "local",
28
+ command: ["node", opts.cliPath, "--mode=server"],
29
+ enabled: true,
30
+ environment: env
31
+ };
32
+ }
33
+ function runInitOpencode(opts) {
34
+ const existing = readExisting(opts.path);
35
+ const merged = mergeNexusBlock(existing, opts);
36
+ const before = existing === null ? "" : `${JSON.stringify(existing, null, 2)}
37
+ `;
38
+ const after = `${JSON.stringify(merged, null, 2)}
39
+ `;
40
+ const diff = simpleDiff(before, after);
41
+ if (opts.dryRun === true) {
42
+ return { path: opts.path, action: "dry-run", diff };
43
+ }
44
+ if (existing !== null && before === after) {
45
+ return { path: opts.path, action: "unchanged", diff };
46
+ }
47
+ writeFileSync(opts.path, after, "utf8");
48
+ return { path: opts.path, action: existing === null ? "created" : "updated", diff };
49
+ }
50
+ function readExisting(path) {
51
+ if (!existsSync(path)) return null;
52
+ try {
53
+ const raw = readFileSync(path, "utf8");
54
+ const parsed = JSON.parse(raw);
55
+ if (typeof parsed !== "object" || parsed === null) {
56
+ throw new Error("opencode.json root must be an object");
57
+ }
58
+ return parsed;
59
+ } catch (err) {
60
+ const msg = err instanceof Error ? err.message : String(err);
61
+ throw new Error(`Failed to parse opencode.json at ${path}: ${msg}`);
62
+ }
63
+ }
64
+ function mergeNexusBlock(existing, opts) {
65
+ const block = buildNexusMcpBlock({
66
+ cliPath: opts.cliPath,
67
+ ...opts.sandboxFlavor !== void 0 && { sandboxFlavor: opts.sandboxFlavor },
68
+ opencodeConfigPath: opts.path
69
+ });
70
+ if (existing === null) {
71
+ return {
72
+ $schema: "https://opencode.ai/config.json",
73
+ providers: { "openai-compat": stubOpenaiCompatProvider() },
74
+ mcp: { "nexus-agents": block }
75
+ };
76
+ }
77
+ const existingMcp = existing.mcp ?? {};
78
+ const rawNexus = existingMcp["nexus-agents"];
79
+ const existingNexus = typeof rawNexus === "object" && rawNexus !== null ? rawNexus : {};
80
+ const mergedBlock = {
81
+ type: "local",
82
+ command: block.command,
83
+ enabled: existingNexus.enabled ?? block.enabled,
84
+ environment: { ...block.environment, ...existingNexus.environment ?? {} }
85
+ };
86
+ return {
87
+ ...existing,
88
+ mcp: { ...existingMcp, "nexus-agents": mergedBlock }
89
+ };
90
+ }
91
+ function stubOpenaiCompatProvider() {
92
+ return {
93
+ npm: "@ai-sdk/openai-compatible",
94
+ options: {
95
+ baseURL: "<replace with workspace proxy URL>",
96
+ apiKey: "{env:WORKSPACE_PROXY_KEY}"
97
+ }
98
+ };
99
+ }
100
+ function simpleDiff(before, after) {
101
+ if (before === after) return "(no changes)";
102
+ const beforeLines = before.split("\n");
103
+ const afterLines = after.split("\n");
104
+ const out = [];
105
+ const max = Math.max(beforeLines.length, afterLines.length);
106
+ for (let i = 0; i < max; i += 1) {
107
+ const b = beforeLines[i];
108
+ const a = afterLines[i];
109
+ if (b === a) {
110
+ out.push(` ${b ?? ""}`);
111
+ } else {
112
+ if (b !== void 0) out.push(`- ${b}`);
113
+ if (a !== void 0) out.push(`+ ${a}`);
114
+ }
115
+ }
116
+ return out.join("\n");
117
+ }
118
+ function ensureOpencodeDirExists(path) {
119
+ const dir = dirname(path);
120
+ if (!existsSync(dir)) {
121
+ throw new Error(
122
+ `Parent directory does not exist: ${dir}. Create it first or pass a path under an existing dir.`
123
+ );
124
+ }
125
+ logger.debug("opencode.json target directory exists", { dir });
126
+ }
127
+ async function runOpencodeValidate(opencodePath) {
128
+ const config = readOpencodeGateway(opencodePath);
129
+ if (config === null) {
130
+ return {
131
+ ok: false,
132
+ reason: "opencode.json does not resolve a usable gateway. Check that providers.openai-compat.options.{baseURL, apiKey} are set and that any {env:VAR} interpolation references are exported."
133
+ };
134
+ }
135
+ const result = await discoverModels({ baseUrl: config.baseURL, apiKey: config.apiKey });
136
+ if (!result.ok) {
137
+ return { ok: false, baseURL: config.baseURL, reason: result.error.message };
138
+ }
139
+ if (result.value.length === 0) {
140
+ return {
141
+ ok: false,
142
+ baseURL: config.baseURL,
143
+ reason: "gateway returned 0 models. Check upstream provider quotas / list filters."
144
+ };
145
+ }
146
+ return {
147
+ ok: true,
148
+ baseURL: config.baseURL,
149
+ models: result.value.map((m) => m.id)
150
+ };
151
+ }
152
+ export {
153
+ buildNexusMcpBlock,
154
+ ensureOpencodeDirExists,
155
+ runInitOpencode,
156
+ runOpencodeValidate
157
+ };
158
+ //# sourceMappingURL=init-opencode-EIOIPVWL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/init-opencode.ts"],"sourcesContent":["/**\n * `nexus-agents init --opencode <path>` setup helper (#2504, child 4 of #2500).\n *\n * Injects the nexus-agents MCP block + recommended environment into an\n * existing `opencode.json` without overwriting other operator-set keys.\n * Pairs with the existing `init --portable --mcp-config` (which targets\n * Claude Code's `.mcp.json`). Different harness, same merge-not-overwrite\n * pattern.\n *\n * Behaviour:\n * - File exists → merge `mcp.nexus-agents` into the existing JSON.\n * Preserve every other key the operator has set (provider config,\n * model lists, theme, …). Idempotent: re-running produces the same\n * final file.\n * - File missing → write a minimal template with the nexus-agents MCP\n * block + a stubbed `providers.openai-compat` shell the operator\n * fills in (placeholder baseURL + `{env:WORKSPACE_PROXY_KEY}`).\n * - `--dry-run` → print the diff (proposed vs existing) without writing.\n * - `--validate` → after merge (or alongside dry-run), probe\n * `providers.openai-compat.options.baseURL/v1/models` with the\n * resolved apiKey, exit non-zero if unreachable.\n *\n * @module cli/init-opencode\n */\n\nimport { existsSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\n\nimport { createLogger } from '../core/index.js';\nimport { readOpencodeGateway } from '../config/opencode-bridge.js';\nimport { discoverModels } from '../adapters/openai-compat-adapter.js';\n\nconst logger = createLogger({ component: 'init-opencode' });\n\nexport interface InitOpencodeOptions {\n /** Absolute or relative path to opencode.json. */\n readonly path: string;\n /** Path to the nexus-agents CLI binary that the MCP block will spawn. */\n readonly cliPath: string;\n /** Sandbox flavor written to NEXUS_SANDBOX in the MCP environment. */\n readonly sandboxFlavor?: string;\n /** Print the diff without writing. */\n readonly dryRun?: boolean;\n}\n\nexport interface InitOpencodeResult {\n readonly path: string;\n readonly action: 'created' | 'updated' | 'unchanged' | 'dry-run';\n readonly diff: string;\n}\n\ninterface OpencodeMcpBlock {\n type: 'local';\n command: string[];\n enabled: boolean;\n environment: Record<string, string>;\n}\n\ninterface OpencodeFile {\n $schema?: string;\n providers?: Record<string, unknown>;\n mcp?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\n/**\n * Build the canonical nexus-agents MCP block. Mirrors what\n * `Dockerfile.sandbox` writes today plus the env vars from #2501 + #2503.\n */\nexport function buildNexusMcpBlock(opts: {\n readonly cliPath: string;\n readonly sandboxFlavor?: string;\n readonly opencodeConfigPath: string;\n}): OpencodeMcpBlock {\n const env: Record<string, string> = {\n NEXUS_DATA_DIR: '{env:NEXUS_DATA_DIR}',\n NEXUS_OPENCODE_CONFIG: opts.opencodeConfigPath,\n };\n if (opts.sandboxFlavor !== undefined && opts.sandboxFlavor !== '') {\n env['NEXUS_SANDBOX'] = opts.sandboxFlavor;\n }\n return {\n type: 'local',\n command: ['node', opts.cliPath, '--mode=server'],\n enabled: true,\n environment: env,\n };\n}\n\n/**\n * Execute the merge. Pure with respect to `opts.dryRun: true` — no fs\n * writes. Returns the final-or-proposed JSON + a diff string suitable\n * for printing.\n */\nexport function runInitOpencode(opts: InitOpencodeOptions): InitOpencodeResult {\n const existing = readExisting(opts.path);\n const merged = mergeNexusBlock(existing, opts);\n const before = existing === null ? '' : `${JSON.stringify(existing, null, 2)}\\n`;\n const after = `${JSON.stringify(merged, null, 2)}\\n`;\n const diff = simpleDiff(before, after);\n\n if (opts.dryRun === true) {\n return { path: opts.path, action: 'dry-run', diff };\n }\n\n if (existing !== null && before === after) {\n return { path: opts.path, action: 'unchanged', diff };\n }\n\n writeFileSync(opts.path, after, 'utf8');\n return { path: opts.path, action: existing === null ? 'created' : 'updated', diff };\n}\n\nfunction readExisting(path: string): OpencodeFile | null {\n if (!existsSync(path)) return null;\n try {\n const raw = readFileSync(path, 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n if (typeof parsed !== 'object' || parsed === null) {\n throw new Error('opencode.json root must be an object');\n }\n return parsed as OpencodeFile;\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to parse opencode.json at ${path}: ${msg}`);\n }\n}\n\nfunction mergeNexusBlock(existing: OpencodeFile | null, opts: InitOpencodeOptions): OpencodeFile {\n const block = buildNexusMcpBlock({\n cliPath: opts.cliPath,\n ...(opts.sandboxFlavor !== undefined && { sandboxFlavor: opts.sandboxFlavor }),\n opencodeConfigPath: opts.path,\n });\n\n if (existing === null) {\n return {\n $schema: 'https://opencode.ai/config.json',\n providers: { 'openai-compat': stubOpenaiCompatProvider() },\n mcp: { 'nexus-agents': block },\n };\n }\n\n // Idempotent merge: preserve user-customised fields if they exist on the\n // current MCP block (e.g. `enabled: false`). Update anything else.\n const existingMcp: Record<string, unknown> = existing.mcp ?? {};\n const rawNexus = existingMcp['nexus-agents'];\n const existingNexus: Partial<OpencodeMcpBlock> =\n typeof rawNexus === 'object' && rawNexus !== null ? rawNexus : {};\n const mergedBlock: OpencodeMcpBlock = {\n type: 'local',\n command: block.command,\n enabled: existingNexus.enabled ?? block.enabled,\n environment: { ...block.environment, ...(existingNexus.environment ?? {}) },\n };\n\n return {\n ...existing,\n mcp: { ...existingMcp, 'nexus-agents': mergedBlock },\n };\n}\n\n/**\n * Stub for `providers.openai-compat`. Operators replace the placeholder\n * baseURL + key with their workspace-proxy values. Empty by design — we\n * never overwrite an existing provider block (see `mergeNexusBlock`).\n */\nfunction stubOpenaiCompatProvider(): Record<string, unknown> {\n return {\n npm: '@ai-sdk/openai-compatible',\n options: {\n baseURL: '<replace with workspace proxy URL>',\n apiKey: '{env:WORKSPACE_PROXY_KEY}',\n },\n };\n}\n\n/**\n * Cheap line-based diff. Three-line context, +/- prefixes. Good enough\n * for an operator preview; not a unified-diff replacement.\n */\nfunction simpleDiff(before: string, after: string): string {\n if (before === after) return '(no changes)';\n const beforeLines = before.split('\\n');\n const afterLines = after.split('\\n');\n const out: string[] = [];\n const max = Math.max(beforeLines.length, afterLines.length);\n for (let i = 0; i < max; i += 1) {\n const b = beforeLines[i];\n const a = afterLines[i];\n if (b === a) {\n out.push(` ${b ?? ''}`);\n } else {\n if (b !== undefined) out.push(`- ${b}`);\n if (a !== undefined) out.push(`+ ${a}`);\n }\n }\n return out.join('\\n');\n}\n\nexport function ensureOpencodeDirExists(path: string): void {\n const dir = dirname(path);\n if (!existsSync(dir)) {\n throw new Error(\n `Parent directory does not exist: ${dir}. Create it first or pass a path under an existing dir.`\n );\n }\n logger.debug('opencode.json target directory exists', { dir });\n}\n\n/**\n * --validate flow for `init --opencode` (follow-up to #2504).\n *\n * After the merge step writes the file, optionally probe the gateway it\n * points at. Reuses the same opencode-bridge loader (#2503) that the\n * runtime uses, so what we validate is exactly what the server will see\n * at boot.\n *\n * Returns:\n * - `{ ok: true, models }` when the gateway is reachable and returns ≥1 model\n * - `{ ok: false, reason }` for every failure path (config missing,\n * probe failed, zero models)\n *\n * Caller (cli-commands-handlers) maps to exit codes + stderr / stdout.\n * The API key never reaches the returned object — only model IDs +\n * baseURL appear in the success payload.\n */\nexport interface OpencodeValidateResult {\n readonly ok: boolean;\n readonly baseURL?: string;\n readonly models?: readonly string[];\n readonly reason?: string;\n}\n\nexport async function runOpencodeValidate(opencodePath: string): Promise<OpencodeValidateResult> {\n const config = readOpencodeGateway(opencodePath);\n if (config === null) {\n return {\n ok: false,\n reason:\n 'opencode.json does not resolve a usable gateway. Check that providers.openai-compat.options.{baseURL, apiKey} are set and that any {env:VAR} interpolation references are exported.',\n };\n }\n const result = await discoverModels({ baseUrl: config.baseURL, apiKey: config.apiKey });\n if (!result.ok) {\n return { ok: false, baseURL: config.baseURL, reason: result.error.message };\n }\n if (result.value.length === 0) {\n return {\n ok: false,\n baseURL: config.baseURL,\n reason: 'gateway returned 0 models. Check upstream provider quotas / list filters.',\n };\n }\n return {\n ok: true,\n baseURL: config.baseURL,\n models: result.value.map((m) => m.id),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;AAyBA,SAAS,YAAY,cAAc,qBAAqB;AACxD,SAAS,eAAe;AAMxB,IAAM,SAAS,aAAa,EAAE,WAAW,gBAAgB,CAAC;AAqCnD,SAAS,mBAAmB,MAId;AACnB,QAAM,MAA8B;AAAA,IAClC,gBAAgB;AAAA,IAChB,uBAAuB,KAAK;AAAA,EAC9B;AACA,MAAI,KAAK,kBAAkB,UAAa,KAAK,kBAAkB,IAAI;AACjE,QAAI,eAAe,IAAI,KAAK;AAAA,EAC9B;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,CAAC,QAAQ,KAAK,SAAS,eAAe;AAAA,IAC/C,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AACF;AAOO,SAAS,gBAAgB,MAA+C;AAC7E,QAAM,WAAW,aAAa,KAAK,IAAI;AACvC,QAAM,SAAS,gBAAgB,UAAU,IAAI;AAC7C,QAAM,SAAS,aAAa,OAAO,KAAK,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA;AAC5E,QAAM,QAAQ,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAAA;AAChD,QAAM,OAAO,WAAW,QAAQ,KAAK;AAErC,MAAI,KAAK,WAAW,MAAM;AACxB,WAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,WAAW,KAAK;AAAA,EACpD;AAEA,MAAI,aAAa,QAAQ,WAAW,OAAO;AACzC,WAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,aAAa,KAAK;AAAA,EACtD;AAEA,gBAAc,KAAK,MAAM,OAAO,MAAM;AACtC,SAAO,EAAE,MAAM,KAAK,MAAM,QAAQ,aAAa,OAAO,YAAY,WAAW,KAAK;AACpF;AAEA,SAAS,aAAa,MAAmC;AACvD,MAAI,CAAC,WAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,UAAM,MAAM,aAAa,MAAM,MAAM;AACrC,UAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,QAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AACA,WAAO;AAAA,EACT,SAAS,KAAc;AACrB,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,UAAM,IAAI,MAAM,oCAAoC,IAAI,KAAK,GAAG,EAAE;AAAA,EACpE;AACF;AAEA,SAAS,gBAAgB,UAA+B,MAAyC;AAC/F,QAAM,QAAQ,mBAAmB;AAAA,IAC/B,SAAS,KAAK;AAAA,IACd,GAAI,KAAK,kBAAkB,UAAa,EAAE,eAAe,KAAK,cAAc;AAAA,IAC5E,oBAAoB,KAAK;AAAA,EAC3B,CAAC;AAED,MAAI,aAAa,MAAM;AACrB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,WAAW,EAAE,iBAAiB,yBAAyB,EAAE;AAAA,MACzD,KAAK,EAAE,gBAAgB,MAAM;AAAA,IAC/B;AAAA,EACF;AAIA,QAAM,cAAuC,SAAS,OAAO,CAAC;AAC9D,QAAM,WAAW,YAAY,cAAc;AAC3C,QAAM,gBACJ,OAAO,aAAa,YAAY,aAAa,OAAO,WAAW,CAAC;AAClE,QAAM,cAAgC;AAAA,IACpC,MAAM;AAAA,IACN,SAAS,MAAM;AAAA,IACf,SAAS,cAAc,WAAW,MAAM;AAAA,IACxC,aAAa,EAAE,GAAG,MAAM,aAAa,GAAI,cAAc,eAAe,CAAC,EAAG;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,KAAK,EAAE,GAAG,aAAa,gBAAgB,YAAY;AAAA,EACrD;AACF;AAOA,SAAS,2BAAoD;AAC3D,SAAO;AAAA,IACL,KAAK;AAAA,IACL,SAAS;AAAA,MACP,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA,EACF;AACF;AAMA,SAAS,WAAW,QAAgB,OAAuB;AACzD,MAAI,WAAW,MAAO,QAAO;AAC7B,QAAM,cAAc,OAAO,MAAM,IAAI;AACrC,QAAM,aAAa,MAAM,MAAM,IAAI;AACnC,QAAM,MAAgB,CAAC;AACvB,QAAM,MAAM,KAAK,IAAI,YAAY,QAAQ,WAAW,MAAM;AAC1D,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG;AAC/B,UAAM,IAAI,YAAY,CAAC;AACvB,UAAM,IAAI,WAAW,CAAC;AACtB,QAAI,MAAM,GAAG;AACX,UAAI,KAAK,KAAK,KAAK,EAAE,EAAE;AAAA,IACzB,OAAO;AACL,UAAI,MAAM,OAAW,KAAI,KAAK,KAAK,CAAC,EAAE;AACtC,UAAI,MAAM,OAAW,KAAI,KAAK,KAAK,CAAC,EAAE;AAAA,IACxC;AAAA,EACF;AACA,SAAO,IAAI,KAAK,IAAI;AACtB;AAEO,SAAS,wBAAwB,MAAoB;AAC1D,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,CAAC,WAAW,GAAG,GAAG;AACpB,UAAM,IAAI;AAAA,MACR,oCAAoC,GAAG;AAAA,IACzC;AAAA,EACF;AACA,SAAO,MAAM,yCAAyC,EAAE,IAAI,CAAC;AAC/D;AA0BA,eAAsB,oBAAoB,cAAuD;AAC/F,QAAM,SAAS,oBAAoB,YAAY;AAC/C,MAAI,WAAW,MAAM;AACnB,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,QACE;AAAA,IACJ;AAAA,EACF;AACA,QAAM,SAAS,MAAM,eAAe,EAAE,SAAS,OAAO,SAAS,QAAQ,OAAO,OAAO,CAAC;AACtF,MAAI,CAAC,OAAO,IAAI;AACd,WAAO,EAAE,IAAI,OAAO,SAAS,OAAO,SAAS,QAAQ,OAAO,MAAM,QAAQ;AAAA,EAC5E;AACA,MAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,SAAS,OAAO;AAAA,MAChB,QAAQ;AAAA,IACV;AAAA,EACF;AACA,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,SAAS,OAAO;AAAA,IAChB,QAAQ,OAAO,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EACtC;AACF;","names":[]}
@@ -0,0 +1,16 @@
1
+ import {
2
+ IssueTriage,
3
+ createIssueTriage,
4
+ formatTriageComment
5
+ } from "./chunk-V7ATY4BG.js";
6
+ import "./chunk-3FIDMWFC.js";
7
+ import "./chunk-O4KUCF5S.js";
8
+ import "./chunk-I7ORMAO7.js";
9
+ import "./chunk-GOT7OAL5.js";
10
+ import "./chunk-UP2VWCW5.js";
11
+ export {
12
+ IssueTriage,
13
+ createIssueTriage,
14
+ formatTriageComment
15
+ };
16
+ //# sourceMappingURL=issue-triage-HJUJWGAD.js.map
@@ -4,8 +4,8 @@ import {
4
4
  getOutcomesFile,
5
5
  getRulesFile,
6
6
  isPersistenceEnabled
7
- } from "./chunk-LJT65EA7.js";
8
- import "./chunk-FDNWRZNJ.js";
7
+ } from "./chunk-I7ORMAO7.js";
8
+ import "./chunk-GOT7OAL5.js";
9
9
  import "./chunk-UP2VWCW5.js";
10
10
  export {
11
11
  ensureLearningDir,
@@ -14,4 +14,4 @@ export {
14
14
  getRulesFile,
15
15
  isPersistenceEnabled
16
16
  };
17
- //# sourceMappingURL=learning-persistence-FILWP3IR.js.map
17
+ //# sourceMappingURL=learning-persistence-N6ILD2HX.js.map
@@ -2,13 +2,13 @@ import {
2
2
  DEFAULT_MOBIMEM_CONFIG,
3
3
  MobiMem,
4
4
  createMobiMem
5
- } from "./chunk-7OBFO4GF.js";
6
- import "./chunk-LJT65EA7.js";
7
- import "./chunk-FDNWRZNJ.js";
5
+ } from "./chunk-O4KUCF5S.js";
6
+ import "./chunk-I7ORMAO7.js";
7
+ import "./chunk-GOT7OAL5.js";
8
8
  import "./chunk-UP2VWCW5.js";
9
9
  export {
10
10
  DEFAULT_MOBIMEM_CONFIG,
11
11
  MobiMem,
12
12
  createMobiMem
13
13
  };
14
- //# sourceMappingURL=mobimem-77W5ED4Z.js.map
14
+ //# sourceMappingURL=mobimem-BOJFXQ7B.js.map
@@ -2,11 +2,11 @@ import {
2
2
  getNexusDataDir,
3
3
  nexusDataPath,
4
4
  resetNexusDataDirCache
5
- } from "./chunk-FDNWRZNJ.js";
5
+ } from "./chunk-GOT7OAL5.js";
6
6
  import "./chunk-UP2VWCW5.js";
7
7
  export {
8
8
  getNexusDataDir,
9
9
  nexusDataPath,
10
10
  resetNexusDataDirCache
11
11
  };
12
- //# sourceMappingURL=nexus-data-dir-M6DYKIHJ.js.map
12
+ //# sourceMappingURL=nexus-data-dir-77UO7N6J.js.map
@@ -3,11 +3,11 @@ import {
3
3
  ModelCapabilitySchema,
4
4
  createLogger,
5
5
  getModelCapabilities
6
- } from "./chunk-7OBFO4GF.js";
7
- import "./chunk-LJT65EA7.js";
6
+ } from "./chunk-O4KUCF5S.js";
7
+ import "./chunk-I7ORMAO7.js";
8
8
  import {
9
9
  nexusDataPath
10
- } from "./chunk-FDNWRZNJ.js";
10
+ } from "./chunk-GOT7OAL5.js";
11
11
  import "./chunk-UP2VWCW5.js";
12
12
 
13
13
  // src/cli/registry-command.ts
@@ -577,4 +577,4 @@ export {
577
577
  isValidRegistrySubcommand,
578
578
  registryCommand
579
579
  };
580
- //# sourceMappingURL=registry-command-BBLIXULQ.js.map
580
+ //# sourceMappingURL=registry-command-NCWUJKAF.js.map
@@ -3,11 +3,11 @@ import {
3
3
  buildPlanFromAnalysis,
4
4
  generateSecurityPlan,
5
5
  resolveScannerData
6
- } from "./chunk-LMRKHQG5.js";
6
+ } from "./chunk-L6N2S3UB.js";
7
7
  import "./chunk-BC3M4VLP.js";
8
- import "./chunk-7OBFO4GF.js";
9
- import "./chunk-LJT65EA7.js";
10
- import "./chunk-FDNWRZNJ.js";
8
+ import "./chunk-O4KUCF5S.js";
9
+ import "./chunk-I7ORMAO7.js";
10
+ import "./chunk-GOT7OAL5.js";
11
11
  import "./chunk-UP2VWCW5.js";
12
12
  export {
13
13
  FALLBACK_SCANNER_DATA,
@@ -15,4 +15,4 @@ export {
15
15
  generateSecurityPlan,
16
16
  resolveScannerData
17
17
  };
18
- //# sourceMappingURL=repo-security-plan-7SNM7JQN.js.map
18
+ //# sourceMappingURL=repo-security-plan-3J45VAD6.js.map
@@ -0,0 +1,12 @@
1
+ import {
2
+ synthesizeResearch
3
+ } from "./chunk-A35XORXU.js";
4
+ import "./chunk-NUBSJGQZ.js";
5
+ import "./chunk-O4KUCF5S.js";
6
+ import "./chunk-I7ORMAO7.js";
7
+ import "./chunk-GOT7OAL5.js";
8
+ import "./chunk-UP2VWCW5.js";
9
+ export {
10
+ synthesizeResearch
11
+ };
12
+ //# sourceMappingURL=research-helpers-synthesize-UGQHZZJN.js.map
@@ -2,13 +2,13 @@ import {
2
2
  DEFAULT_ROUTING_MEMORY_CONFIG,
3
3
  RoutingMemory,
4
4
  createRoutingMemory
5
- } from "./chunk-7OBFO4GF.js";
6
- import "./chunk-LJT65EA7.js";
7
- import "./chunk-FDNWRZNJ.js";
5
+ } from "./chunk-O4KUCF5S.js";
6
+ import "./chunk-I7ORMAO7.js";
7
+ import "./chunk-GOT7OAL5.js";
8
8
  import "./chunk-UP2VWCW5.js";
9
9
  export {
10
10
  DEFAULT_ROUTING_MEMORY_CONFIG,
11
11
  RoutingMemory,
12
12
  createRoutingMemory
13
13
  };
14
- //# sourceMappingURL=routing-memory-DCIZEEVC.js.map
14
+ //# sourceMappingURL=routing-memory-NO7QEH7T.js.map
@@ -6,10 +6,10 @@ import {
6
6
  SessionMemory,
7
7
  SessionMemoryError,
8
8
  createSessionMemory
9
- } from "./chunk-ZPPX2K57.js";
10
- import "./chunk-7OBFO4GF.js";
11
- import "./chunk-LJT65EA7.js";
12
- import "./chunk-FDNWRZNJ.js";
9
+ } from "./chunk-2KB63QGE.js";
10
+ import "./chunk-O4KUCF5S.js";
11
+ import "./chunk-I7ORMAO7.js";
12
+ import "./chunk-GOT7OAL5.js";
13
13
  import "./chunk-UP2VWCW5.js";
14
14
  export {
15
15
  CompletedTaskSchema,
@@ -20,4 +20,4 @@ export {
20
20
  SessionMemoryError,
21
21
  createSessionMemory
22
22
  };
23
- //# sourceMappingURL=session-memory-5TSAASQW.js.map
23
+ //# sourceMappingURL=session-memory-DOXLEWEU.js.map
@@ -7,18 +7,18 @@ import {
7
7
  runWizard,
8
8
  setupCommand,
9
9
  setupCommandAsync
10
- } from "./chunk-7LHQBMBM.js";
11
- import "./chunk-OF7CYMMA.js";
12
- import "./chunk-U6BK5DQU.js";
13
- import "./chunk-L2LQ3TSV.js";
10
+ } from "./chunk-C3JGKBL2.js";
11
+ import "./chunk-DA5UDQYW.js";
12
+ import "./chunk-YOREAPF6.js";
13
+ import "./chunk-2MD5MWCK.js";
14
14
  import "./chunk-NUBSJGQZ.js";
15
- import "./chunk-XATH462F.js";
15
+ import "./chunk-ES6GFP35.js";
16
16
  import "./chunk-ZM4O442V.js";
17
17
  import "./chunk-633WH2ML.js";
18
- import "./chunk-U3HZQTUF.js";
19
- import "./chunk-7OBFO4GF.js";
20
- import "./chunk-LJT65EA7.js";
21
- import "./chunk-FDNWRZNJ.js";
18
+ import "./chunk-TQFRPFMG.js";
19
+ import "./chunk-O4KUCF5S.js";
20
+ import "./chunk-I7ORMAO7.js";
21
+ import "./chunk-GOT7OAL5.js";
22
22
  import "./chunk-UP2VWCW5.js";
23
23
  export {
24
24
  detectEnvironment,
@@ -30,4 +30,4 @@ export {
30
30
  setupCommand,
31
31
  setupCommandAsync
32
32
  };
33
- //# sourceMappingURL=setup-command-5VGIQETA.js.map
33
+ //# sourceMappingURL=setup-command-BWUFMZ7U.js.map
@@ -0,0 +1,11 @@
1
+ import {
2
+ runConfigInitSync
3
+ } from "./chunk-DA5UDQYW.js";
4
+ import "./chunk-O4KUCF5S.js";
5
+ import "./chunk-I7ORMAO7.js";
6
+ import "./chunk-GOT7OAL5.js";
7
+ import "./chunk-UP2VWCW5.js";
8
+ export {
9
+ runConfigInitSync
10
+ };
11
+ //# sourceMappingURL=setup-config-E3JZYSLR.js.map
@@ -2,16 +2,16 @@ import {
2
2
  CUSTOM_API_ALLOW_PRIVATE_ENV,
3
3
  CUSTOM_API_BASE_URL_ENV,
4
4
  validateCustomApiBaseUrl
5
- } from "./chunk-VGZJIR22.js";
5
+ } from "./chunk-5WQ3SRSE.js";
6
6
  import {
7
7
  CUSTOM_API_DEFAULT_MODEL
8
- } from "./chunk-L2LQ3TSV.js";
8
+ } from "./chunk-2MD5MWCK.js";
9
9
  import {
10
10
  err,
11
11
  ok
12
- } from "./chunk-7OBFO4GF.js";
13
- import "./chunk-LJT65EA7.js";
14
- import "./chunk-FDNWRZNJ.js";
12
+ } from "./chunk-O4KUCF5S.js";
13
+ import "./chunk-I7ORMAO7.js";
14
+ import "./chunk-GOT7OAL5.js";
15
15
  import "./chunk-UP2VWCW5.js";
16
16
 
17
17
  // src/cli/setup-custom-api.ts
@@ -107,4 +107,4 @@ function buildShellFragment(params) {
107
107
  export {
108
108
  configureCustomApi
109
109
  };
110
- //# sourceMappingURL=setup-custom-api-IQX3GD2D.js.map
110
+ //# sourceMappingURL=setup-custom-api-DHJ5DRH2.js.map
@@ -3,9 +3,9 @@ import {
3
3
  getAdaptiveBonus,
4
4
  queryWithLookback,
5
5
  shouldExplore
6
- } from "./chunk-7OBFO4GF.js";
7
- import "./chunk-LJT65EA7.js";
8
- import "./chunk-FDNWRZNJ.js";
6
+ } from "./chunk-O4KUCF5S.js";
7
+ import "./chunk-I7ORMAO7.js";
8
+ import "./chunk-GOT7OAL5.js";
9
9
  import "./chunk-UP2VWCW5.js";
10
10
  export {
11
11
  generateWeatherReport,
@@ -13,4 +13,4 @@ export {
13
13
  queryWithLookback,
14
14
  shouldExplore
15
15
  };
16
- //# sourceMappingURL=weather-report-NETGWTJX.js.map
16
+ //# sourceMappingURL=weather-report-FNN4OX3N.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexus-agents",
3
- "version": "2.71.0",
3
+ "version": "2.72.1",
4
4
  "description": "Intelligent orchestration platform for AI coding tools — routes tasks to the best model, learns from outcomes, and enforces quality through multi-model consensus",
5
5
  "mcpName": "io.github.williamzujkowski/nexus-agents",
6
6
  "license": "MIT",