nexus-agents 2.79.4 → 2.80.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 (119) hide show
  1. package/dist/{child-mcp-config-DFRYTRBK.js → child-mcp-config-Q6UMCPGZ.js} +3 -3
  2. package/dist/{chunk-UWDVEMYZ.js → chunk-23XU4LE2.js} +4 -4
  3. package/dist/chunk-2JQXC3CK.js +317 -0
  4. package/dist/chunk-2JQXC3CK.js.map +1 -0
  5. package/dist/{chunk-DOI7RE3X.js → chunk-33LDLZCC.js} +2 -2
  6. package/dist/{chunk-UNRTM43V.js → chunk-54UT2JUQ.js} +2 -2
  7. package/dist/{chunk-OGV7J5WG.js → chunk-5WN3WGXG.js} +3 -3
  8. package/dist/{chunk-NJPFN75N.js → chunk-7UM5XRGG.js} +2 -2
  9. package/dist/{chunk-JMRCMMZ5.js → chunk-7ZKZ7K7J.js} +2 -2
  10. package/dist/{chunk-45NUO4FE.js → chunk-ALDKPBOZ.js} +2 -2
  11. package/dist/{chunk-DW3UTO43.js → chunk-D3MQ4U2R.js} +51 -21
  12. package/dist/chunk-D3MQ4U2R.js.map +1 -0
  13. package/dist/{chunk-NVSJXN4S.js → chunk-D4NEYNBO.js} +8 -5
  14. package/dist/chunk-D4NEYNBO.js.map +1 -0
  15. package/dist/{chunk-42MM7GKW.js → chunk-D5C5N5Q4.js} +2 -2
  16. package/dist/{chunk-BIH2CBC5.js → chunk-EPZMFIAX.js} +105 -10
  17. package/dist/chunk-EPZMFIAX.js.map +1 -0
  18. package/dist/{chunk-ACP4YARI.js → chunk-GODRGVF4.js} +3 -3
  19. package/dist/{chunk-IPDUZJPH.js → chunk-HR7C4DSA.js} +4 -4
  20. package/dist/{chunk-PAKVXGS2.js → chunk-I5KYDT23.js} +2 -2
  21. package/dist/{chunk-PDCLBWH5.js → chunk-L7433REX.js} +4 -4
  22. package/dist/{chunk-3ENBGGYA.js → chunk-LDD272PW.js} +959 -885
  23. package/dist/chunk-LDD272PW.js.map +1 -0
  24. package/dist/{chunk-OFRDE7MK.js → chunk-MUIA32LU.js} +2 -2
  25. package/dist/{chunk-TN5ZKSGC.js → chunk-MVIYQMQM.js} +2 -2
  26. package/dist/{chunk-NXNNT5XW.js → chunk-NALIFUBD.js} +4 -4
  27. package/dist/{chunk-LFTK5ZQG.js → chunk-NCBWA6RU.js} +2 -2
  28. package/dist/{chunk-BXI6DKBU.js → chunk-O2ECPTFH.js} +3 -3
  29. package/dist/{chunk-UNFS6YBY.js → chunk-Q4DXTNGR.js} +2 -2
  30. package/dist/{chunk-BSQ4KTY4.js → chunk-SX3P2PD2.js} +2 -2
  31. package/dist/{chunk-UQOSVOEU.js → chunk-T4E6UFFC.js} +16 -14
  32. package/dist/chunk-T4E6UFFC.js.map +1 -0
  33. package/dist/{chunk-UOR2JWFH.js → chunk-TFTP7EUQ.js} +82 -57
  34. package/dist/chunk-TFTP7EUQ.js.map +1 -0
  35. package/dist/{chunk-PHBRELUK.js → chunk-UEKTTIDA.js} +7 -7
  36. package/dist/{chunk-SU3Y6LU2.js → chunk-WZ2T4T7N.js} +32 -6
  37. package/dist/chunk-WZ2T4T7N.js.map +1 -0
  38. package/dist/{cli-circuit-breaker-T75HOLZK.js → cli-circuit-breaker-EUERR2HK.js} +5 -5
  39. package/dist/cli.d.ts +1 -1
  40. package/dist/cli.js +618 -567
  41. package/dist/cli.js.map +1 -1
  42. package/dist/{composite-router-OPSK5FCQ.js → composite-router-ZP72LQFH.js} +3 -3
  43. package/dist/{consensus-vote-CYUPIJXR.js → consensus-vote-TU3TQ4VH.js} +12 -12
  44. package/dist/{context-retriever-6AWHCHRP.js → context-retriever-OTLV46DF.js} +6 -6
  45. package/dist/{doctor-deep-XBPRQ6ZP.js → doctor-deep-ZMBSG2DF.js} +4 -4
  46. package/dist/expert-bridge-IK4TY7HA.js +11 -0
  47. package/dist/{factory-Y3TMP4OQ.js → factory-45NHZFLK.js} +5 -5
  48. package/dist/factory-QDHYIYVE.js +14 -0
  49. package/dist/index.d.ts +40 -5
  50. package/dist/index.js +25 -25
  51. package/dist/{init-opencode-RV6IQEMS.js → init-opencode-WFL4OXMB.js} +6 -6
  52. package/dist/issue-triage-UHFCGTEJ.js +15 -0
  53. package/dist/{learning-persistence-Q3HTOGTU.js → learning-persistence-TGOBRUUU.js} +2 -2
  54. package/dist/{registry-command-6KJWW3W7.js → registry-command-YMZPSW7S.js} +3 -3
  55. package/dist/{repo-security-plan-HNLMF7J7.js → repo-security-plan-TGDXTSHS.js} +4 -4
  56. package/dist/{research-helpers-synthesize-77TLYSW4.js → research-helpers-synthesize-5BAN353Y.js} +4 -4
  57. package/dist/{routing-memory-6DV6ZPAH.js → routing-memory-RG3U2MC2.js} +3 -3
  58. package/dist/{session-memory-XZ3NJIR4.js → session-memory-C5GC2JAX.js} +4 -4
  59. package/dist/{setup-command-QOXG36UV.js → setup-command-OXJ32UAI.js} +13 -11
  60. package/dist/setup-config-KNMVMGDD.js +10 -0
  61. package/dist/{setup-custom-api-PJ6TGHJH.js → setup-custom-api-4EYRKCHB.js} +5 -5
  62. package/dist/{tool-memory-K2QPTPKV.js → tool-memory-LUXUOE6Q.js} +5 -5
  63. package/dist/{weather-report-ZB4AKOIA.js → weather-report-3KSDTC7T.js} +3 -3
  64. package/package.json +1 -1
  65. package/dist/chunk-3ENBGGYA.js.map +0 -1
  66. package/dist/chunk-7BMOZJYS.js +0 -83
  67. package/dist/chunk-7BMOZJYS.js.map +0 -1
  68. package/dist/chunk-BIH2CBC5.js.map +0 -1
  69. package/dist/chunk-DW3UTO43.js.map +0 -1
  70. package/dist/chunk-NVSJXN4S.js.map +0 -1
  71. package/dist/chunk-SU3Y6LU2.js.map +0 -1
  72. package/dist/chunk-UOR2JWFH.js.map +0 -1
  73. package/dist/chunk-UQOSVOEU.js.map +0 -1
  74. package/dist/expert-bridge-5YOPK5IT.js +0 -11
  75. package/dist/factory-DN7SJZ5Z.js +0 -14
  76. package/dist/issue-triage-UTWKXLKC.js +0 -15
  77. package/dist/setup-config-B4V4QHDP.js +0 -10
  78. /package/dist/{child-mcp-config-DFRYTRBK.js.map → child-mcp-config-Q6UMCPGZ.js.map} +0 -0
  79. /package/dist/{chunk-UWDVEMYZ.js.map → chunk-23XU4LE2.js.map} +0 -0
  80. /package/dist/{chunk-DOI7RE3X.js.map → chunk-33LDLZCC.js.map} +0 -0
  81. /package/dist/{chunk-UNRTM43V.js.map → chunk-54UT2JUQ.js.map} +0 -0
  82. /package/dist/{chunk-OGV7J5WG.js.map → chunk-5WN3WGXG.js.map} +0 -0
  83. /package/dist/{chunk-NJPFN75N.js.map → chunk-7UM5XRGG.js.map} +0 -0
  84. /package/dist/{chunk-JMRCMMZ5.js.map → chunk-7ZKZ7K7J.js.map} +0 -0
  85. /package/dist/{chunk-45NUO4FE.js.map → chunk-ALDKPBOZ.js.map} +0 -0
  86. /package/dist/{chunk-42MM7GKW.js.map → chunk-D5C5N5Q4.js.map} +0 -0
  87. /package/dist/{chunk-ACP4YARI.js.map → chunk-GODRGVF4.js.map} +0 -0
  88. /package/dist/{chunk-IPDUZJPH.js.map → chunk-HR7C4DSA.js.map} +0 -0
  89. /package/dist/{chunk-PAKVXGS2.js.map → chunk-I5KYDT23.js.map} +0 -0
  90. /package/dist/{chunk-PDCLBWH5.js.map → chunk-L7433REX.js.map} +0 -0
  91. /package/dist/{chunk-OFRDE7MK.js.map → chunk-MUIA32LU.js.map} +0 -0
  92. /package/dist/{chunk-TN5ZKSGC.js.map → chunk-MVIYQMQM.js.map} +0 -0
  93. /package/dist/{chunk-NXNNT5XW.js.map → chunk-NALIFUBD.js.map} +0 -0
  94. /package/dist/{chunk-LFTK5ZQG.js.map → chunk-NCBWA6RU.js.map} +0 -0
  95. /package/dist/{chunk-BXI6DKBU.js.map → chunk-O2ECPTFH.js.map} +0 -0
  96. /package/dist/{chunk-UNFS6YBY.js.map → chunk-Q4DXTNGR.js.map} +0 -0
  97. /package/dist/{chunk-BSQ4KTY4.js.map → chunk-SX3P2PD2.js.map} +0 -0
  98. /package/dist/{chunk-PHBRELUK.js.map → chunk-UEKTTIDA.js.map} +0 -0
  99. /package/dist/{cli-circuit-breaker-T75HOLZK.js.map → cli-circuit-breaker-EUERR2HK.js.map} +0 -0
  100. /package/dist/{composite-router-OPSK5FCQ.js.map → composite-router-ZP72LQFH.js.map} +0 -0
  101. /package/dist/{consensus-vote-CYUPIJXR.js.map → consensus-vote-TU3TQ4VH.js.map} +0 -0
  102. /package/dist/{context-retriever-6AWHCHRP.js.map → context-retriever-OTLV46DF.js.map} +0 -0
  103. /package/dist/{doctor-deep-XBPRQ6ZP.js.map → doctor-deep-ZMBSG2DF.js.map} +0 -0
  104. /package/dist/{expert-bridge-5YOPK5IT.js.map → expert-bridge-IK4TY7HA.js.map} +0 -0
  105. /package/dist/{factory-DN7SJZ5Z.js.map → factory-45NHZFLK.js.map} +0 -0
  106. /package/dist/{factory-Y3TMP4OQ.js.map → factory-QDHYIYVE.js.map} +0 -0
  107. /package/dist/{init-opencode-RV6IQEMS.js.map → init-opencode-WFL4OXMB.js.map} +0 -0
  108. /package/dist/{issue-triage-UTWKXLKC.js.map → issue-triage-UHFCGTEJ.js.map} +0 -0
  109. /package/dist/{learning-persistence-Q3HTOGTU.js.map → learning-persistence-TGOBRUUU.js.map} +0 -0
  110. /package/dist/{registry-command-6KJWW3W7.js.map → registry-command-YMZPSW7S.js.map} +0 -0
  111. /package/dist/{repo-security-plan-HNLMF7J7.js.map → repo-security-plan-TGDXTSHS.js.map} +0 -0
  112. /package/dist/{research-helpers-synthesize-77TLYSW4.js.map → research-helpers-synthesize-5BAN353Y.js.map} +0 -0
  113. /package/dist/{routing-memory-6DV6ZPAH.js.map → routing-memory-RG3U2MC2.js.map} +0 -0
  114. /package/dist/{session-memory-XZ3NJIR4.js.map → session-memory-C5GC2JAX.js.map} +0 -0
  115. /package/dist/{setup-command-QOXG36UV.js.map → setup-command-OXJ32UAI.js.map} +0 -0
  116. /package/dist/{setup-config-B4V4QHDP.js.map → setup-config-KNMVMGDD.js.map} +0 -0
  117. /package/dist/{setup-custom-api-PJ6TGHJH.js.map → setup-custom-api-4EYRKCHB.js.map} +0 -0
  118. /package/dist/{tool-memory-K2QPTPKV.js.map → tool-memory-LUXUOE6Q.js.map} +0 -0
  119. /package/dist/{weather-report-ZB4AKOIA.js.map → weather-report-3KSDTC7T.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -12,18 +12,18 @@ import {
12
12
  parseFindings,
13
13
  sumFindings
14
14
  } from "./chunk-3RZWLQSC.js";
15
- import "./chunk-JMRCMMZ5.js";
15
+ import "./chunk-7ZKZ7K7J.js";
16
16
  import {
17
17
  buildOpenAICompatAdapters,
18
18
  loadUsageEvents,
19
19
  readOpenAICompatEnv,
20
20
  rollupByModel
21
- } from "./chunk-IPDUZJPH.js";
21
+ } from "./chunk-HR7C4DSA.js";
22
22
  import {
23
23
  setupCommandAsync,
24
24
  verifyCommand
25
- } from "./chunk-SU3Y6LU2.js";
26
- import "./chunk-NVSJXN4S.js";
25
+ } from "./chunk-WZ2T4T7N.js";
26
+ import "./chunk-D4NEYNBO.js";
27
27
  import {
28
28
  AuthHandler,
29
29
  DEFAULT_EXPERTS,
@@ -153,56 +153,61 @@ import {
153
153
  validateCommand,
154
154
  validateWorkflow,
155
155
  wrapInMarkdownFence
156
- } from "./chunk-3ENBGGYA.js";
156
+ } from "./chunk-LDD272PW.js";
157
157
  import "./chunk-AP2FD37C.js";
158
158
  import "./chunk-ED6VQWNG.js";
159
159
  import {
160
160
  resolveToken
161
- } from "./chunk-LFTK5ZQG.js";
161
+ } from "./chunk-NCBWA6RU.js";
162
162
  import {
163
163
  CATEGORY_DISPLAY_NAMES,
164
164
  DEFAULT_PR_REVIEW_CONFIG
165
165
  } from "./chunk-X2M7OF27.js";
166
- import "./chunk-OGV7J5WG.js";
167
- import "./chunk-ACP4YARI.js";
168
- import "./chunk-PHBRELUK.js";
166
+ import "./chunk-5WN3WGXG.js";
167
+ import "./chunk-GODRGVF4.js";
168
+ import "./chunk-UEKTTIDA.js";
169
169
  import {
170
170
  DEFAULT_VOTE_TIMEOUT_MS,
171
171
  ErrorPolicySchema,
172
172
  VOTER_ROLES,
173
173
  VoteThresholdSchema,
174
174
  createDefaultPolicyFirewall,
175
+ createSecureHandler,
175
176
  createUnifiedRegistry,
176
177
  executeVoting,
177
178
  getToolAnnotations,
179
+ getToolTimeout,
178
180
  registerConsensusVoteTool,
181
+ toSdkCallback,
179
182
  toolStructuredError,
180
- warnIfSimulatedOutsideTests
181
- } from "./chunk-DW3UTO43.js";
182
- import "./chunk-PAKVXGS2.js";
183
- import "./chunk-DOI7RE3X.js";
183
+ toolSuccessStructured,
184
+ warnIfSimulatedOutsideTests,
185
+ wrapToolWithTimeout
186
+ } from "./chunk-D3MQ4U2R.js";
187
+ import "./chunk-I5KYDT23.js";
188
+ import "./chunk-33LDLZCC.js";
184
189
  import {
185
190
  loadPapersRegistry,
186
191
  loadTechniquesRegistry,
187
192
  savePapersRegistry,
188
193
  synthesizeResearch
189
- } from "./chunk-UNFS6YBY.js";
194
+ } from "./chunk-Q4DXTNGR.js";
190
195
  import {
191
196
  classifyTrust,
192
197
  createFullGitHubProvider,
193
198
  evaluatePolicy,
194
199
  parsePRUrl,
195
200
  sanitizeInput
196
- } from "./chunk-BXI6DKBU.js";
197
- import "./chunk-BSQ4KTY4.js";
198
- import "./chunk-TN5ZKSGC.js";
201
+ } from "./chunk-O2ECPTFH.js";
202
+ import "./chunk-SX3P2PD2.js";
203
+ import "./chunk-MVIYQMQM.js";
199
204
  import "./chunk-7J7PNOJQ.js";
200
205
  import "./chunk-BQ4YXGGQ.js";
201
- import "./chunk-PDCLBWH5.js";
206
+ import "./chunk-L7433REX.js";
202
207
  import {
203
208
  MemoryError,
204
209
  shutdownToolMemory
205
- } from "./chunk-NXNNT5XW.js";
210
+ } from "./chunk-NALIFUBD.js";
206
211
  import {
207
212
  CustomExpertDefinitionSchema,
208
213
  DATA_SUBDIRECTORIES,
@@ -221,12 +226,12 @@ import {
221
226
  loadConfig,
222
227
  runDoctor,
223
228
  validateNexusEnv
224
- } from "./chunk-UOR2JWFH.js";
225
- import "./chunk-OFRDE7MK.js";
226
- import "./chunk-42MM7GKW.js";
229
+ } from "./chunk-TFTP7EUQ.js";
230
+ import "./chunk-MUIA32LU.js";
231
+ import "./chunk-D5C5N5Q4.js";
227
232
  import {
228
233
  DEFAULTS
229
- } from "./chunk-UNRTM43V.js";
234
+ } from "./chunk-54UT2JUQ.js";
230
235
  import "./chunk-NUBSJGQZ.js";
231
236
  import {
232
237
  capitalize,
@@ -238,11 +243,11 @@ import {
238
243
  getAvailableClis,
239
244
  isRecord,
240
245
  probeAllClis
241
- } from "./chunk-BIH2CBC5.js";
242
- import "./chunk-NJPFN75N.js";
246
+ } from "./chunk-EPZMFIAX.js";
247
+ import "./chunk-7UM5XRGG.js";
243
248
  import "./chunk-ZM4O442V.js";
244
249
  import "./chunk-PQHVC4BD.js";
245
- import "./chunk-45NUO4FE.js";
250
+ import "./chunk-ALDKPBOZ.js";
246
251
  import {
247
252
  API_TIMEOUTS,
248
253
  AgentCapability,
@@ -310,125 +315,19 @@ import {
310
315
  validateTimeout,
311
316
  writeEmptyLine,
312
317
  writeLine
313
- } from "./chunk-UQOSVOEU.js";
318
+ } from "./chunk-T4E6UFFC.js";
314
319
  import {
320
+ applyPortableMode,
315
321
  detectSandbox,
322
+ findRepoRoot,
316
323
  getNexusDataDir,
324
+ getPerRepoSubdirs,
317
325
  nexusDataPath
318
- } from "./chunk-7BMOZJYS.js";
326
+ } from "./chunk-2JQXC3CK.js";
319
327
  import "./chunk-UP2VWCW5.js";
320
328
 
321
329
  // src/cli/cli-log-bootstrap.ts
322
330
  import { argv, env } from "process";
323
-
324
- // src/config/portable-mode.ts
325
- import { accessSync, constants, existsSync, readFileSync, appendFileSync, statSync } from "fs";
326
- import { homedir } from "os";
327
- import { join, resolve } from "path";
328
- var SANDBOX_ENV_VARS = [
329
- "KUBERNETES_SERVICE_HOST",
330
- "DOCKER_CONTAINER",
331
- "ECS_CONTAINER_METADATA_URI",
332
- "ECS_CONTAINER_METADATA_URI_V4",
333
- "SANDBOX",
334
- "NEXUS_SANDBOX"
335
- ];
336
- var DETECTED = false;
337
- function isHomeWritable() {
338
- try {
339
- const home = homedir();
340
- if (!existsSync(home)) return false;
341
- accessSync(home, constants.W_OK);
342
- return true;
343
- } catch {
344
- return false;
345
- }
346
- }
347
- function inSandboxEnv() {
348
- for (const v of SANDBOX_ENV_VARS) {
349
- const val = process.env[v];
350
- if (val !== void 0 && val !== "") return true;
351
- }
352
- return false;
353
- }
354
- function checkExplicitEnv(cwd) {
355
- const fromEnv = process.env["NEXUS_DATA_DIR"]?.trim();
356
- if (fromEnv !== void 0 && fromEnv !== "") {
357
- return { portable: false, dataDir: resolve(fromEnv), reason: "env-data-dir" };
358
- }
359
- const portableEnv = process.env["NEXUS_PORTABLE_MODE"];
360
- if (portableEnv === "0" || portableEnv === "false") {
361
- return { portable: false, dataDir: join(homedir(), ".nexus-agents"), reason: "env-opt-out" };
362
- }
363
- if (portableEnv === "1" || portableEnv === "true") {
364
- return { portable: true, dataDir: join(cwd, ".nexus-agents"), reason: "env-opt-in" };
365
- }
366
- return null;
367
- }
368
- function checkHeuristics(cwd) {
369
- if (!isHomeWritable()) {
370
- return { portable: true, dataDir: join(cwd, ".nexus-agents"), reason: "home-unwritable" };
371
- }
372
- if (inSandboxEnv()) {
373
- return { portable: true, dataDir: join(cwd, ".nexus-agents"), reason: "container-env" };
374
- }
375
- return null;
376
- }
377
- function detectPortableMode(cwd = process.cwd()) {
378
- return checkExplicitEnv(cwd) ?? checkHeuristics(cwd) ?? {
379
- portable: false,
380
- dataDir: join(homedir(), ".nexus-agents"),
381
- reason: "default"
382
- };
383
- }
384
- function applyPortableMode(cwd = process.cwd()) {
385
- if (DETECTED) return;
386
- DETECTED = true;
387
- const result = detectPortableMode(cwd);
388
- if (!result.portable) return;
389
- if (result.reason === "home-unwritable" || result.reason === "container-env") {
390
- process.stderr.write(
391
- `[portable-mode] Sandbox detected (${result.reason}). Using ${result.dataDir} for all nexus-agents data.
392
- Set NEXUS_PORTABLE_MODE=0 to override; see docs/guides/SANDBOXED-USAGE.md
393
- `
394
- );
395
- }
396
- process.env["NEXUS_DATA_DIR"] = result.dataDir;
397
- if (isInsideGitRepo(cwd)) {
398
- ensureGitignored(cwd, ".nexus-agents/");
399
- }
400
- }
401
- function isInsideGitRepo(cwd) {
402
- try {
403
- const gitDir = join(cwd, ".git");
404
- return existsSync(gitDir) && statSync(gitDir).isDirectory();
405
- } catch {
406
- return false;
407
- }
408
- }
409
- function ensureGitignored(cwd, entry) {
410
- const path22 = join(cwd, ".gitignore");
411
- try {
412
- const existing = existsSync(path22) ? readFileSync(path22, "utf-8") : "";
413
- const lines = existing.split("\n").map((l) => l.trim());
414
- if (lines.includes(entry) || lines.includes(entry.replace(/\/$/, ""))) return;
415
- const sep3 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
416
- appendFileSync(path22, `${sep3}${entry}
417
- `, "utf-8");
418
- process.stderr.write(
419
- `[portable-mode] Added '${entry}' to ${path22} so nexus-agents data is gitignored.
420
- `
421
- );
422
- } catch (e) {
423
- const msg = e instanceof Error ? e.message : String(e);
424
- process.stderr.write(
425
- `[portable-mode] Could not auto-update ${path22} (${msg}). Add '${entry}' manually if you don't want nexus-agents data tracked by git.
426
- `
427
- );
428
- }
429
- }
430
-
431
- // src/cli/cli-log-bootstrap.ts
432
331
  var SERVER_COMMANDS = /* @__PURE__ */ new Set(["server"]);
433
332
  var VERBOSE_FLAGS = /* @__PURE__ */ new Set(["--verbose", "-v", "--debug"]);
434
333
  function findSubcommand(args) {
@@ -512,10 +411,11 @@ function helloCommand() {
512
411
  }
513
412
 
514
413
  // src/cli/config-init.ts
515
- import { existsSync as existsSync2 } from "fs";
414
+ import { existsSync } from "fs";
516
415
  import { writeFile, mkdir } from "fs/promises";
517
- import { dirname, resolve as resolve2 } from "path";
416
+ import { dirname, resolve } from "path";
518
417
  var DEFAULT_CONFIG_FILE = "nexus-agents.yaml";
418
+ var DEFAULT_CONFIG_REL_PATH = `.nexus-agents/${DEFAULT_CONFIG_FILE}`;
519
419
  function qualifiesPowerful(m) {
520
420
  return (m.qualityScores?.reasoning ?? 0) >= 9;
521
421
  }
@@ -692,16 +592,20 @@ logging:
692
592
  `;
693
593
  function resolveOutputPath(output2) {
694
594
  if (output2 !== void 0 && output2 !== "") {
695
- return resolve2(process.cwd(), output2);
595
+ return resolve(process.cwd(), output2);
696
596
  }
697
- return resolve2(process.cwd(), DEFAULT_CONFIG_FILE);
597
+ const legacyPath = resolve(process.cwd(), DEFAULT_CONFIG_FILE);
598
+ if (existsSync(legacyPath)) {
599
+ return legacyPath;
600
+ }
601
+ return resolve(process.cwd(), DEFAULT_CONFIG_REL_PATH);
698
602
  }
699
603
  function fileExists(path22) {
700
- return existsSync2(path22);
604
+ return existsSync(path22);
701
605
  }
702
606
  async function ensureDirectory(filePath) {
703
607
  const dir = dirname(filePath);
704
- if (dir !== "." && !existsSync2(dir)) {
608
+ if (dir !== "." && !existsSync(dir)) {
705
609
  await mkdir(dir, { recursive: true });
706
610
  }
707
611
  }
@@ -765,10 +669,10 @@ async function configInitCommand(options = {}) {
765
669
  }
766
670
 
767
671
  // src/cli/custom-expert-validation.ts
768
- import { resolve as resolve3, sep } from "path";
672
+ import { resolve as resolve2, sep } from "path";
769
673
  function validateConfigPath(userPath, allowedRoot) {
770
- const resolvedRoot = resolve3(allowedRoot);
771
- const resolved = resolve3(allowedRoot, userPath);
674
+ const resolvedRoot = resolve2(allowedRoot);
675
+ const resolved = resolve2(allowedRoot, userPath);
772
676
  if (!resolved.startsWith(resolvedRoot + sep) && resolved !== resolvedRoot) {
773
677
  return err(
774
678
  new SecurityError("Path traversal detected: config path escapes allowed root directory", {
@@ -836,8 +740,8 @@ function formatValidationErrors(errors) {
836
740
  }
837
741
 
838
742
  // src/cli/custom-expert-parsing.ts
839
- import { readFileSync as readFileSync2, existsSync as existsSync3 } from "fs";
840
- import { resolve as resolve4 } from "path";
743
+ import { readFileSync, existsSync as existsSync2 } from "fs";
744
+ import { resolve as resolve3 } from "path";
841
745
  import * as yaml from "yaml";
842
746
  var DEFAULT_CONFIG_FILE2 = "nexus-agents.yaml";
843
747
  function findConfigPath() {
@@ -848,12 +752,12 @@ function findConfigPath() {
848
752
  if (!validation.ok) {
849
753
  return { securityError: validation.error };
850
754
  }
851
- if (existsSync3(validation.value)) {
755
+ if (existsSync2(validation.value)) {
852
756
  return { path: validation.value };
853
757
  }
854
758
  }
855
- const cwdPath = resolve4(cwd, DEFAULT_CONFIG_FILE2);
856
- if (existsSync3(cwdPath)) {
759
+ const cwdPath = resolve3(cwd, DEFAULT_CONFIG_FILE2);
760
+ if (existsSync2(cwdPath)) {
857
761
  return { path: cwdPath };
858
762
  }
859
763
  return {};
@@ -956,7 +860,7 @@ function resolveConfigPath(configPath) {
956
860
  }
957
861
  function readConfigContent(configPath) {
958
862
  try {
959
- return { content: readFileSync2(configPath, "utf-8") };
863
+ return { content: readFileSync(configPath, "utf-8") };
960
864
  } catch (error) {
961
865
  return {
962
866
  error: {
@@ -1604,10 +1508,10 @@ async function handleBuiltInCommand(input, session) {
1604
1508
  }
1605
1509
  return { handled: false, exit: false };
1606
1510
  }
1607
- function handleTask(input, session, logger17) {
1511
+ function handleTask(input, session, logger18) {
1608
1512
  const trimmed = input.trim();
1609
1513
  if (session.verbose) {
1610
- logger17.debug("Processing task", { task: trimmed, sessionId: session.sessionId });
1514
+ logger18.debug("Processing task", { task: trimmed, sessionId: session.sessionId });
1611
1515
  }
1612
1516
  process.stdout.write(`
1613
1517
  ${colors.bold}Task Analysis:${colors.reset}
@@ -1651,7 +1555,7 @@ function createReadlineInterface() {
1651
1555
  historySize: 100
1652
1556
  });
1653
1557
  }
1654
- async function processLine(line, session, logger17) {
1558
+ async function processLine(line, session, logger18) {
1655
1559
  const trimmed = line.trim();
1656
1560
  if (trimmed === "") {
1657
1561
  return false;
@@ -1665,36 +1569,36 @@ async function processLine(line, session, logger17) {
1665
1569
  }
1666
1570
  return result.exit;
1667
1571
  }
1668
- handleTask(trimmed, session, logger17);
1572
+ handleTask(trimmed, session, logger18);
1669
1573
  return false;
1670
1574
  }
1671
1575
  async function startRepl(options = {}) {
1672
- const logger17 = createLogger({ component: "repl" });
1576
+ const logger18 = createLogger({ component: "repl" });
1673
1577
  const session = createSession(options.verbose ?? false);
1674
1578
  if (session.verbose) {
1675
- logger17.setLevel("debug");
1579
+ logger18.setLevel("debug");
1676
1580
  }
1677
- logger17.info("Starting interactive REPL", { sessionId: session.sessionId });
1581
+ logger18.info("Starting interactive REPL", { sessionId: session.sessionId });
1678
1582
  printBanner();
1679
1583
  const rl = createReadlineInterface();
1680
1584
  rl.on("close", () => {
1681
1585
  process.stdout.write(`
1682
1586
  ${colors.dim}Session ended.${colors.reset}
1683
1587
  `);
1684
- logger17.info("REPL session ended", {
1588
+ logger18.info("REPL session ended", {
1685
1589
  sessionId: session.sessionId,
1686
1590
  commandsRun: session.history.length
1687
1591
  });
1688
1592
  });
1689
1593
  rl.prompt();
1690
- return new Promise((resolve15) => {
1594
+ return new Promise((resolve14) => {
1691
1595
  rl.on("line", (line) => {
1692
1596
  void (async () => {
1693
1597
  try {
1694
- const shouldExit = await processLine(line, session, logger17);
1598
+ const shouldExit = await processLine(line, session, logger18);
1695
1599
  if (shouldExit) {
1696
1600
  rl.close();
1697
- resolve15();
1601
+ resolve14();
1698
1602
  return;
1699
1603
  }
1700
1604
  } catch (error) {
@@ -1706,7 +1610,7 @@ ${colors.dim}Session ended.${colors.reset}
1706
1610
  })();
1707
1611
  });
1708
1612
  rl.on("close", () => {
1709
- resolve15();
1613
+ resolve14();
1710
1614
  });
1711
1615
  });
1712
1616
  }
@@ -1724,7 +1628,7 @@ async function replCommand(options = {}) {
1724
1628
 
1725
1629
  // src/self-eval/component-scanner.ts
1726
1630
  import { readdir, readFile, stat } from "fs/promises";
1727
- import { join as join2, basename, extname, relative } from "path";
1631
+ import { join, basename, extname, relative } from "path";
1728
1632
  var DEFAULT_EXTENSIONS = [".ts"];
1729
1633
  var DEFAULT_MAX_FILE_SIZE = 1024 * 1024;
1730
1634
  var COMPLEXITY_PATTERNS = [
@@ -1789,7 +1693,7 @@ var ComponentScanner = class {
1789
1693
  const files = [];
1790
1694
  const entries = await readdir(directory, { withFileTypes: true });
1791
1695
  for (const entry of entries) {
1792
- const fullPath = join2(directory, entry.name);
1696
+ const fullPath = join(directory, entry.name);
1793
1697
  if (entry.isDirectory()) {
1794
1698
  const subFiles = await this.findFiles(fullPath);
1795
1699
  files.push(...subFiles);
@@ -3339,6 +3243,9 @@ function safeExecSandboxed(commandString, options = {}) {
3339
3243
  if (options.cwd !== void 0) {
3340
3244
  execOptions.cwd = options.cwd;
3341
3245
  }
3246
+ if (options.stdin !== void 0) {
3247
+ execOptions.input = options.stdin;
3248
+ }
3342
3249
  const result = execSync(commandString, execOptions);
3343
3250
  return typeof result === "string" ? result.trim() : result.toString("utf-8").trim();
3344
3251
  } catch (error) {
@@ -4214,27 +4121,27 @@ var CliAdapterAgent = class {
4214
4121
  };
4215
4122
 
4216
4123
  // src/cli/orchestrate-puppeteer.ts
4217
- function loadPolicyParameters(path22, logger17) {
4124
+ function loadPolicyParameters(path22, logger18) {
4218
4125
  try {
4219
4126
  if (fs2.existsSync(path22)) {
4220
4127
  const content = fs2.readFileSync(path22, "utf-8");
4221
4128
  const params = JSON.parse(content);
4222
- logger17.info("Loaded policy parameters", { path: path22 });
4129
+ logger18.info("Loaded policy parameters", { path: path22 });
4223
4130
  return params;
4224
4131
  }
4225
4132
  } catch (error) {
4226
4133
  const message = getErrorMessage(error);
4227
- logger17.warn("Failed to load policy parameters", { path: path22, error: message });
4134
+ logger18.warn("Failed to load policy parameters", { path: path22, error: message });
4228
4135
  }
4229
4136
  return void 0;
4230
4137
  }
4231
- function savePolicyParameters(path22, params, logger17) {
4138
+ function savePolicyParameters(path22, params, logger18) {
4232
4139
  try {
4233
4140
  fs2.writeFileSync(path22, JSON.stringify(params, null, 2));
4234
- logger17.info("Saved policy parameters", { path: path22 });
4141
+ logger18.info("Saved policy parameters", { path: path22 });
4235
4142
  } catch (error) {
4236
4143
  const message = getErrorMessage(error);
4237
- logger17.warn("Failed to save policy parameters", { path: path22, error: message });
4144
+ logger18.warn("Failed to save policy parameters", { path: path22, error: message });
4238
4145
  }
4239
4146
  }
4240
4147
  function createAgentsFromAdapters(adapters) {
@@ -4244,7 +4151,7 @@ function createAgentsFromAdapters(adapters) {
4244
4151
  }
4245
4152
  return agents;
4246
4153
  }
4247
- function createPolicyEngine(options, logger17) {
4154
+ function createPolicyEngine(options, logger18) {
4248
4155
  const useLearnable = options.learn === true;
4249
4156
  if (useLearnable) {
4250
4157
  const learnablePolicy = createLearnablePolicy({
@@ -4252,7 +4159,7 @@ function createPolicyEngine(options, logger17) {
4252
4159
  warmupUpdates: 5
4253
4160
  });
4254
4161
  if (options.policyPath !== void 0) {
4255
- const savedParams = loadPolicyParameters(options.policyPath, logger17);
4162
+ const savedParams = loadPolicyParameters(options.policyPath, logger18);
4256
4163
  if (savedParams !== void 0) {
4257
4164
  learnablePolicy.loadParameters(savedParams);
4258
4165
  }
@@ -4293,7 +4200,7 @@ function buildPuppeteerResult(puppeteerResult, startTime, policyEngine, useLearn
4293
4200
  }
4294
4201
  return result;
4295
4202
  }
4296
- async function executeWithPuppeteer(taskContent, adapters, options, logger17) {
4203
+ async function executeWithPuppeteer(taskContent, adapters, options, logger18) {
4297
4204
  const startTime = getTimeProvider().now();
4298
4205
  const useLearnable = options.learn === true;
4299
4206
  const agents = createAgentsFromAdapters(adapters);
@@ -4305,14 +4212,14 @@ async function executeWithPuppeteer(taskContent, adapters, options, logger17) {
4305
4212
  durationMs: getTimeProvider().now() - startTime
4306
4213
  };
4307
4214
  }
4308
- const policyEngine = createPolicyEngine(options, logger17);
4215
+ const policyEngine = createPolicyEngine(options, logger18);
4309
4216
  const orchestrator = createOrchestrator(policyEngine, agents, options);
4310
4217
  const task = {
4311
4218
  id: `cli-${String(getTimeProvider().now())}`,
4312
4219
  description: taskContent,
4313
4220
  context: { workingDirectory: process.cwd() }
4314
4221
  };
4315
- logger17.info("Executing with PuppeteerOrchestrator", {
4222
+ logger18.info("Executing with PuppeteerOrchestrator", {
4316
4223
  agents: agents.map((a) => a.id),
4317
4224
  learnable: useLearnable,
4318
4225
  maxSteps: options.maxSteps ?? 5
@@ -4329,7 +4236,7 @@ async function executeWithPuppeteer(taskContent, adapters, options, logger17) {
4329
4236
  const puppeteerResult = execResult.value;
4330
4237
  if (useLearnable && options.policyPath !== void 0) {
4331
4238
  const learnablePolicy = policyEngine;
4332
- savePolicyParameters(options.policyPath, learnablePolicy.getParameters(), logger17);
4239
+ savePolicyParameters(options.policyPath, learnablePolicy.getParameters(), logger18);
4333
4240
  }
4334
4241
  return buildPuppeteerResult(puppeteerResult, startTime, policyEngine, useLearnable);
4335
4242
  }
@@ -4408,9 +4315,9 @@ function formatPct(value) {
4408
4315
  }
4409
4316
 
4410
4317
  // src/cli/orchestrate-command.ts
4411
- async function runWithAdapter(task, decision, logger17, startTime) {
4318
+ async function runWithAdapter(task, decision, logger18, startTime) {
4412
4319
  const time = getTimeProvider();
4413
- logger17.info("Executing task...", { model: decision.cliName });
4320
+ logger18.info("Executing task...", { model: decision.cliName });
4414
4321
  const execResult = await decision.adapter.execute(task);
4415
4322
  if (!execResult.ok) {
4416
4323
  return {
@@ -4429,7 +4336,7 @@ async function runWithAdapter(task, decision, logger17, startTime) {
4429
4336
  durationMs: time.now() - startTime
4430
4337
  };
4431
4338
  }
4432
- async function executeWithRouting(task, adapters, options, logger17) {
4339
+ async function executeWithRouting(task, adapters, options, logger18) {
4433
4340
  const time = getTimeProvider();
4434
4341
  const startTime = time.now();
4435
4342
  const configResult = getConfig();
@@ -4443,7 +4350,7 @@ async function executeWithRouting(task, adapters, options, logger17) {
4443
4350
  ...routingConfig,
4444
4351
  budgetConstraints
4445
4352
  });
4446
- logger17.info("Routing task...", { task: task.content.slice(0, 50) });
4353
+ logger18.info("Routing task...", { task: task.content.slice(0, 50) });
4447
4354
  const routingResult = await router.route(task);
4448
4355
  if (!routingResult.ok) {
4449
4356
  return {
@@ -4463,9 +4370,9 @@ async function executeWithRouting(task, adapters, options, logger17) {
4463
4370
  durationMs: time.now() - startTime
4464
4371
  };
4465
4372
  }
4466
- return runWithAdapter(task, decision, logger17, startTime);
4373
+ return runWithAdapter(task, decision, logger18, startTime);
4467
4374
  }
4468
- async function executeWithModel(task, model, adapters, logger17) {
4375
+ async function executeWithModel(task, model, adapters, logger18) {
4469
4376
  const time = getTimeProvider();
4470
4377
  const startTime = time.now();
4471
4378
  const adapter = adapters.get(model);
@@ -4477,7 +4384,7 @@ async function executeWithModel(task, model, adapters, logger17) {
4477
4384
  durationMs: time.now() - startTime
4478
4385
  };
4479
4386
  }
4480
- logger17.info("Executing task...", { model });
4387
+ logger18.info("Executing task...", { model });
4481
4388
  const execResult = await adapter.execute(task);
4482
4389
  if (!execResult.ok) {
4483
4390
  return {
@@ -4575,7 +4482,7 @@ function formatResult(result, format) {
4575
4482
  return format === "json" ? formatResultJson(result) : formatResultText(result);
4576
4483
  }
4577
4484
  async function orchestrateCommand(options) {
4578
- const logger17 = createLogger({ component: "orchestrate", verbose: options.verbose });
4485
+ const logger18 = createLogger({ component: "orchestrate", verbose: options.verbose });
4579
4486
  const availableClis = await getAvailableClis();
4580
4487
  if (availableClis.length === 0) {
4581
4488
  console.error("No CLI tools available.");
@@ -4587,23 +4494,23 @@ async function orchestrateCommand(options) {
4587
4494
  console.log(`Available CLIs: ${availableClis.join(", ")}`);
4588
4495
  }
4589
4496
  const codexTransport = options.engine === "puppeteer" ? "subprocess" : "mcp";
4590
- const adapters = createAllAdapters(logger17, codexTransport);
4497
+ const adapters = createAllAdapters(logger18, codexTransport);
4591
4498
  if (adapters.size === 0) {
4592
4499
  console.error("Failed to create CLI adapters.");
4593
4500
  return 1;
4594
4501
  }
4595
4502
  let result;
4596
4503
  if (options.engine === "puppeteer") {
4597
- result = await executeWithPuppeteer(options.task, adapters, options, logger17);
4504
+ result = await executeWithPuppeteer(options.task, adapters, options, logger18);
4598
4505
  } else {
4599
4506
  const task = {
4600
4507
  content: options.task,
4601
4508
  systemPrompt: "You are a helpful assistant."
4602
4509
  };
4603
4510
  if (options.model !== void 0) {
4604
- result = await executeWithModel(task, options.model, adapters, logger17);
4511
+ result = await executeWithModel(task, options.model, adapters, logger18);
4605
4512
  } else {
4606
- result = await executeWithRouting(task, adapters, options, logger17);
4513
+ result = await executeWithRouting(task, adapters, options, logger18);
4607
4514
  }
4608
4515
  }
4609
4516
  const output2 = formatResult(result, options.format ?? "text");
@@ -5295,8 +5202,8 @@ async function handlePrune(args, log) {
5295
5202
  const count = String(result.value);
5296
5203
  output(dryRun ? "Would delete " + count + " sessions." : "Deleted " + count + " sessions.");
5297
5204
  }
5298
- async function sessionCommand(subcommand, args, logger17) {
5299
- const log = logger17 ?? createLogger({ component: "SessionCommand" });
5205
+ async function sessionCommand(subcommand, args, logger18) {
5206
+ const log = logger18 ?? createLogger({ component: "SessionCommand" });
5300
5207
  const handlers = {
5301
5208
  list: handleList,
5302
5209
  show: handleShow,
@@ -6052,9 +5959,6 @@ function validateGitHubIssue(issueNumber) {
6052
5959
  });
6053
5960
  return output2 !== null;
6054
5961
  }
6055
- function escapeForShell(text) {
6056
- return text.replace(/'/g, "'\\''");
6057
- }
6058
5962
  function formatVoteComment(result) {
6059
5963
  const now = new Date(getTimeProvider().now()).toLocaleDateString("en-US", {
6060
5964
  timeZone: "America/New_York",
@@ -6091,11 +5995,10 @@ ${voteRows}
6091
5995
  }
6092
5996
  function recordVoteToGitHub(issueNumber, result) {
6093
5997
  const comment = formatVoteComment(result);
6094
- const escapedComment = escapeForShell(comment);
6095
- const output2 = safeExecSandboxed(
6096
- `gh issue comment ${String(issueNumber)} --body '${escapedComment}'`,
6097
- { context: "gh" }
6098
- );
5998
+ const output2 = safeExecSandboxed(`gh issue comment ${String(issueNumber)} --body-file -`, {
5999
+ context: "gh",
6000
+ stdin: comment
6001
+ });
6099
6002
  if (output2 !== null) {
6100
6003
  writeLine(
6101
6004
  `${colors.green}${symbols.check}${colors.reset} Vote recorded to issue #${String(issueNumber)}
@@ -6129,8 +6032,8 @@ async function runVote(options) {
6129
6032
  ...options.threshold !== void 0 && { threshold: options.threshold },
6130
6033
  ...options.errorPolicy !== void 0 && { errorPolicy: options.errorPolicy }
6131
6034
  };
6132
- const logger17 = createLogger({ component: "cli-vote" });
6133
- const result = await executeVoting(input, logger17, { voteTimeoutMs: timeoutMs });
6035
+ const logger18 = createLogger({ component: "cli-vote" });
6036
+ const result = await executeVoting(input, logger18, { voteTimeoutMs: timeoutMs });
6134
6037
  return {
6135
6038
  proposal: result.proposal,
6136
6039
  threshold: result.threshold,
@@ -6831,7 +6734,7 @@ function generateSprintTitle(duration) {
6831
6734
  month: "2-digit",
6832
6735
  day: "2-digit"
6833
6736
  });
6834
- return `sprint: ${dateStr} (${duration})`;
6737
+ return `sprint: ${dateStr} - ${duration}`;
6835
6738
  }
6836
6739
  function formatIssueForBody(issue) {
6837
6740
  const effort = issue.estimatedEffort !== void 0 ? ` (${issue.estimatedEffort})` : "";
@@ -6913,10 +6816,9 @@ function generateProposal(issues, options) {
6913
6816
  function createSprintIssue(proposal) {
6914
6817
  try {
6915
6818
  const escapedTitle = proposal.title.replace(/'/g, "'\\''");
6916
- const escapedBody = proposal.body.replace(/'/g, "'\\''");
6917
6819
  const output2 = safeExecSandboxed(
6918
- `gh issue create --title '${escapedTitle}' --body '${escapedBody}' --label 'epic'`,
6919
- { context: "gh" }
6820
+ `gh issue create --title '${escapedTitle}' --body-file - --label epic`,
6821
+ { context: "gh", stdin: proposal.body }
6920
6822
  );
6921
6823
  if (output2 === null) {
6922
6824
  return null;
@@ -8231,7 +8133,7 @@ async function researchIndexCommand(options) {
8231
8133
 
8232
8134
  // src/cli/research-import-command.ts
8233
8135
  import * as fs9 from "fs/promises";
8234
- import { resolve as resolve6 } from "path";
8136
+ import { resolve as resolve5 } from "path";
8235
8137
  var VALID_TYPES = ["paper", "repo", "tool", "blog"];
8236
8138
  function parseCsvLine(line) {
8237
8139
  const fields = [];
@@ -8335,7 +8237,7 @@ function mapToSourceType(csvType) {
8335
8237
  }
8336
8238
  }
8337
8239
  async function executeImport(options) {
8338
- const csvPath = resolve6(options.csvPath);
8240
+ const csvPath = resolve5(options.csvPath);
8339
8241
  let content;
8340
8242
  try {
8341
8243
  content = await fs9.readFile(csvPath, "utf-8");
@@ -8540,8 +8442,8 @@ async function handleAddCommand(args, options) {
8540
8442
  ...topic !== void 0 && { topic },
8541
8443
  ...priority !== void 0 && { priority }
8542
8444
  };
8543
- const logger17 = createLogger({ component: "cli-research-add" });
8544
- const result = await executeResearchAdd(input, logger17);
8445
+ const logger18 = createLogger({ component: "cli-research-add" });
8446
+ const result = await executeResearchAdd(input, logger18);
8545
8447
  return result.message;
8546
8448
  }
8547
8449
  var SOURCE_PROVIDERS = [
@@ -8606,8 +8508,8 @@ async function handleDiscoverCommand(args, options) {
8606
8508
  if (!parsed.success) {
8607
8509
  return `Error: ${parsed.error.issues.map((i) => i.message).join("; ")}`;
8608
8510
  }
8609
- const logger17 = createLogger({ component: "cli-research-discover" });
8610
- const response = await executeDiscovery(parsed.data, logger17);
8511
+ const logger18 = createLogger({ component: "cli-research-discover" });
8512
+ const response = await executeDiscovery(parsed.data, logger18);
8611
8513
  return renderDiscoverResponse(response);
8612
8514
  }
8613
8515
  async function handleReviewCommand(args, options) {
@@ -9643,6 +9545,11 @@ var COMMAND_CATALOG = [
9643
9545
  description: "Inspect + refresh the dynamic model registry (doctor / refresh)",
9644
9546
  audience: "advanced"
9645
9547
  },
9548
+ {
9549
+ command: "migrate",
9550
+ description: "Relocate homedir state (sessions, checkpoints, traces, runs, audit, pipeline, tasks) into <repo>/.nexus-agents/ for users adopting NEXUS_REPO_PREFERRED=1. Cross-repo state stays homedir. --dry-run for a no-op plan. Epic #2872.",
9551
+ audience: "advanced"
9552
+ },
9646
9553
  {
9647
9554
  command: "review",
9648
9555
  description: "Review a GitHub PR (dogfooding helper)",
@@ -11359,7 +11266,7 @@ function isValidConfigAction(value) {
11359
11266
  // src/cli/config-command-helpers.ts
11360
11267
  import * as fs14 from "fs/promises";
11361
11268
  import * as path18 from "path";
11362
- import { existsSync as existsSync11 } from "fs";
11269
+ import { existsSync as existsSync10 } from "fs";
11363
11270
 
11364
11271
  // src/cli/config-command-formatting.ts
11365
11272
  function formatSource(source) {
@@ -11645,7 +11552,7 @@ function getDefaultExportPath(format) {
11645
11552
 
11646
11553
  // src/cli/config-command-handlers.ts
11647
11554
  import * as fs15 from "fs/promises";
11648
- import { existsSync as existsSync12 } from "fs";
11555
+ import { existsSync as existsSync11 } from "fs";
11649
11556
  async function handleGet(key) {
11650
11557
  const parsed = parseConfigKey(key);
11651
11558
  const config = getConfigManager();
@@ -11767,7 +11674,7 @@ async function handleExport2(file, format = "json") {
11767
11674
  };
11768
11675
  }
11769
11676
  async function readImportFile(filePath) {
11770
- if (!existsSync12(filePath)) {
11677
+ if (!existsSync11(filePath)) {
11771
11678
  throw new ConfigCommandError("FILE_NOT_FOUND", `File not found: ${filePath}`);
11772
11679
  }
11773
11680
  const format = filePath.endsWith(".yaml") || filePath.endsWith(".yml") ? "yaml" : "json";
@@ -12270,7 +12177,7 @@ function writeResultAndExit(result) {
12270
12177
 
12271
12178
  // src/cli/hooks/hook-router.ts
12272
12179
  async function readStdin() {
12273
- return new Promise((resolve15, reject) => {
12180
+ return new Promise((resolve14, reject) => {
12274
12181
  let data = "";
12275
12182
  process.stdin.setEncoding("utf8");
12276
12183
  process.stdin.on("readable", () => {
@@ -12281,24 +12188,24 @@ async function readStdin() {
12281
12188
  }
12282
12189
  });
12283
12190
  process.stdin.on("end", () => {
12284
- resolve15(data);
12191
+ resolve14(data);
12285
12192
  });
12286
12193
  process.stdin.on("error", (err2) => {
12287
12194
  reject(err2);
12288
12195
  });
12289
12196
  if (process.stdin.isTTY) {
12290
- resolve15("");
12197
+ resolve14("");
12291
12198
  }
12292
12199
  });
12293
12200
  }
12294
12201
  async function readStdinWithTimeout(timeoutMs = 5e3) {
12295
- return new Promise((resolve15, reject) => {
12202
+ return new Promise((resolve14, reject) => {
12296
12203
  const timeout2 = setTimeout(() => {
12297
12204
  reject(new Error(`Stdin read timeout after ${String(timeoutMs)}ms`));
12298
12205
  }, timeoutMs);
12299
12206
  readStdin().then((data) => {
12300
12207
  clearTimeout(timeout2);
12301
- resolve15(data);
12208
+ resolve14(data);
12302
12209
  }).catch((err2) => {
12303
12210
  clearTimeout(timeout2);
12304
12211
  reject(err2 instanceof Error ? err2 : new Error(String(err2)));
@@ -14045,11 +13952,11 @@ async function releaseNotesCommand(args) {
14045
13952
  }
14046
13953
 
14047
13954
  // src/cli/release-validate-command.ts
14048
- import { readFileSync as readFileSync8 } from "fs";
13955
+ import { readFileSync as readFileSync7 } from "fs";
14049
13956
 
14050
13957
  // src/cli/release-validate-helpers.ts
14051
13958
  import { execSync as execSync2 } from "child_process";
14052
- import { existsSync as existsSync13, readFileSync as readFileSync7 } from "fs";
13959
+ import { existsSync as existsSync12, readFileSync as readFileSync6 } from "fs";
14053
13960
  async function validateSecurity(options) {
14054
13961
  const startTime = Date.now();
14055
13962
  const findings = [];
@@ -14068,7 +13975,7 @@ async function validateSecurity(options) {
14068
13975
  remediation: "Run npm audit fix or review and update vulnerable dependencies."
14069
13976
  });
14070
13977
  }
14071
- if (existsSync13(".env")) {
13978
+ if (existsSync12(".env")) {
14072
13979
  findings.push({
14073
13980
  severity: "error",
14074
13981
  category: "security",
@@ -14164,7 +14071,7 @@ async function validateArchitecture2(options) {
14164
14071
  async function validateDocumentation(options) {
14165
14072
  const startTime = Date.now();
14166
14073
  const findings = [];
14167
- if (!existsSync13("CHANGELOG.md")) {
14074
+ if (!existsSync12("CHANGELOG.md")) {
14168
14075
  findings.push({
14169
14076
  severity: "error",
14170
14077
  category: "docs",
@@ -14172,7 +14079,7 @@ async function validateDocumentation(options) {
14172
14079
  description: "No CHANGELOG.md found in repository root.",
14173
14080
  remediation: "Create CHANGELOG.md following Keep a Changelog format."
14174
14081
  });
14175
- } else if (!readFileSync7("CHANGELOG.md", "utf-8").includes(options.version)) {
14082
+ } else if (!readFileSync6("CHANGELOG.md", "utf-8").includes(options.version)) {
14176
14083
  findings.push({
14177
14084
  severity: "warning",
14178
14085
  category: "docs",
@@ -14182,7 +14089,7 @@ async function validateDocumentation(options) {
14182
14089
  });
14183
14090
  }
14184
14091
  const pkgCl = "packages/nexus-agents/CHANGELOG.md";
14185
- if (existsSync13(pkgCl) && !readFileSync7(pkgCl, "utf-8").includes(options.version)) {
14092
+ if (existsSync12(pkgCl) && !readFileSync6(pkgCl, "utf-8").includes(options.version)) {
14186
14093
  findings.push({
14187
14094
  severity: "warning",
14188
14095
  category: "docs",
@@ -14191,7 +14098,7 @@ async function validateDocumentation(options) {
14191
14098
  remediation: "Run pnpm changeset:version to generate changelog from pending changesets."
14192
14099
  });
14193
14100
  }
14194
- if (!existsSync13("README.md")) {
14101
+ if (!existsSync12("README.md")) {
14195
14102
  findings.push({
14196
14103
  severity: "error",
14197
14104
  category: "docs",
@@ -14200,8 +14107,8 @@ async function validateDocumentation(options) {
14200
14107
  remediation: "Create README.md with project overview and usage instructions."
14201
14108
  });
14202
14109
  }
14203
- if (existsSync13("CLAUDE.md")) {
14204
- const claudeMd = readFileSync7("CLAUDE.md", "utf-8");
14110
+ if (existsSync12("CLAUDE.md")) {
14111
+ const claudeMd = readFileSync6("CLAUDE.md", "utf-8");
14205
14112
  const match = claudeMd.match(/Governance Version: (\d{4}-\d{2}-\d{2})/);
14206
14113
  if (match?.[1]) {
14207
14114
  const governanceDate = new Date(match[1]);
@@ -14309,7 +14216,7 @@ var DEFAULT_OPTIONS2 = {
14309
14216
  };
14310
14217
  function readVersionFromPackage() {
14311
14218
  try {
14312
- const raw = JSON.parse(readFileSync8("package.json", "utf-8"));
14219
+ const raw = JSON.parse(readFileSync7("package.json", "utf-8"));
14313
14220
  if (typeof raw === "object" && raw !== null && "version" in raw) {
14314
14221
  const pkg = raw;
14315
14222
  return typeof pkg.version === "string" ? pkg.version : "unknown";
@@ -14423,7 +14330,7 @@ async function releaseValidateCommand(args) {
14423
14330
  }
14424
14331
 
14425
14332
  // src/cli/release-announce-command.ts
14426
- import { readFileSync as readFileSync9, existsSync as existsSync14 } from "fs";
14333
+ import { readFileSync as readFileSync8, existsSync as existsSync13 } from "fs";
14427
14334
 
14428
14335
  // src/cli/release-announce-types.ts
14429
14336
  var BLUESKY_LIMITS = {
@@ -14490,8 +14397,8 @@ var DEFAULT_OPTIONS3 = {
14490
14397
  verbose: false
14491
14398
  };
14492
14399
  function extractHighlightsFromChangelog(version) {
14493
- if (!existsSync14("CHANGELOG.md")) return [];
14494
- const changelog = readFileSync9("CHANGELOG.md", "utf-8");
14400
+ if (!existsSync13("CHANGELOG.md")) return [];
14401
+ const changelog = readFileSync8("CHANGELOG.md", "utf-8");
14495
14402
  const escaped = version.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
14496
14403
  const versionRegex = new RegExp(`## \\[${escaped}\\][^#]*`, "s");
14497
14404
  const match = changelog.match(versionRegex);
@@ -14753,7 +14660,7 @@ async function releaseAnnounceCommand(args) {
14753
14660
  version = args.options.version;
14754
14661
  } else {
14755
14662
  try {
14756
- const pkg = JSON.parse(readFileSync9("package.json", "utf-8"));
14663
+ const pkg = JSON.parse(readFileSync8("package.json", "utf-8"));
14757
14664
  if (!pkg.version) {
14758
14665
  console.error(`${colors.red}Error: Could not determine version${colors.reset}`);
14759
14666
  return 1;
@@ -15320,8 +15227,8 @@ function buildDetails(taskCount, counts, nonZero, score, passed) {
15320
15227
  lines.push(`Result: ${passed ? "PASSED" : "FAILED"}`);
15321
15228
  return lines;
15322
15229
  }
15323
- function runE2EEval(config, logger17) {
15324
- const log = logger17 ?? createLogger({ component: "e2e-eval" });
15230
+ function runE2EEval(config, logger18) {
15231
+ const log = logger18 ?? createLogger({ component: "e2e-eval" });
15325
15232
  const taskCount = config?.taskCount ?? 50;
15326
15233
  if (config?.resetStore !== false) {
15327
15234
  resetOutcomeStore();
@@ -15685,13 +15592,13 @@ function formatEvalDetails(baseline, reflective, improvement, datasetSize) {
15685
15592
  }
15686
15593
 
15687
15594
  // src/cli/auth-command.ts
15688
- import { existsSync as existsSync16, statSync as statSync2, chmodSync } from "fs";
15595
+ import { existsSync as existsSync15, statSync, chmodSync } from "fs";
15689
15596
  function isValidAuthSubcommand(value) {
15690
15597
  return value === "init" || value === "show" || value === "rotate" || value === "help" || value === "status";
15691
15598
  }
15692
15599
  function getFilePermissions(filePath) {
15693
15600
  try {
15694
- const stats = statSync2(filePath);
15601
+ const stats = statSync(filePath);
15695
15602
  return (stats.mode & 511).toString(8);
15696
15603
  } catch {
15697
15604
  return void 0;
@@ -15705,7 +15612,7 @@ function fixPermissions(filePath) {
15705
15612
  }
15706
15613
  function runAuthInit(options) {
15707
15614
  const tokenFile = options.tokenFile ?? getDefaultTokenPath();
15708
- const tokenExists = existsSync16(tokenFile);
15615
+ const tokenExists = existsSync15(tokenFile);
15709
15616
  if (tokenExists && options.force !== true) {
15710
15617
  return {
15711
15618
  success: false,
@@ -15729,7 +15636,7 @@ function runAuthInit(options) {
15729
15636
  }
15730
15637
  function runAuthShow(options) {
15731
15638
  const tokenFile = options.tokenFile ?? getDefaultTokenPath();
15732
- const tokenExists = existsSync16(tokenFile);
15639
+ const tokenExists = existsSync15(tokenFile);
15733
15640
  const token = readStoredToken(tokenFile);
15734
15641
  if (!tokenExists || token === void 0) {
15735
15642
  return {
@@ -15750,7 +15657,7 @@ function runAuthShow(options) {
15750
15657
  }
15751
15658
  function runAuthRotate(options) {
15752
15659
  const tokenFile = options.tokenFile ?? getDefaultTokenPath();
15753
- const tokenExists = existsSync16(tokenFile);
15660
+ const tokenExists = existsSync15(tokenFile);
15754
15661
  if (!tokenExists) {
15755
15662
  return {
15756
15663
  success: false,
@@ -15786,14 +15693,14 @@ function runAuthCommand(options) {
15786
15693
  success: true,
15787
15694
  operation: "help",
15788
15695
  tokenFile: getDefaultTokenPath(),
15789
- tokenExists: existsSync16(getDefaultTokenPath())
15696
+ tokenExists: existsSync15(getDefaultTokenPath())
15790
15697
  };
15791
15698
  default:
15792
15699
  return {
15793
15700
  success: false,
15794
15701
  operation: "help",
15795
15702
  tokenFile: getDefaultTokenPath(),
15796
- tokenExists: existsSync16(getDefaultTokenPath()),
15703
+ tokenExists: existsSync15(getDefaultTokenPath()),
15797
15704
  error: `Unknown subcommand: ${subcommand}`
15798
15705
  };
15799
15706
  }
@@ -16163,8 +16070,12 @@ var PARSE_ARGS_CONFIG = {
16163
16070
  type: "string"
16164
16071
  },
16165
16072
  "output-dir": {
16166
- type: "string",
16167
- default: "./logs/run_evaluation"
16073
+ type: "string"
16074
+ // No default: the only consumer (handleSweBenchCommand) is a
16075
+ // deprecation shim that ignores it. Live callers should pass an
16076
+ // explicit path or resolve through getNexusDataDir() at use time.
16077
+ // Removed the './logs/run_evaluation' default per epic #2872 to
16078
+ // stop the parser from advertising a sprawl-creating fallback.
16168
16079
  },
16169
16080
  // ATBench command options (#1981)
16170
16081
  fixture: {
@@ -16349,29 +16260,30 @@ var VALID_COMMANDS = [
16349
16260
  "registry",
16350
16261
  "login",
16351
16262
  "usage",
16352
- "improvement-review"
16263
+ "improvement-review",
16264
+ "migrate"
16353
16265
  ];
16354
16266
  function isValidCommand(value) {
16355
16267
  return VALID_COMMANDS.includes(value);
16356
16268
  }
16357
16269
 
16358
16270
  // src/cli-commands-handlers.ts
16359
- import { existsSync as existsSync21 } from "fs";
16271
+ import { existsSync as existsSync20 } from "fs";
16360
16272
 
16361
16273
  // src/cli/init-portable.ts
16362
16274
  import {
16363
- existsSync as existsSync20,
16275
+ existsSync as existsSync19,
16364
16276
  mkdirSync as mkdirSync5,
16365
16277
  readdirSync,
16366
- statSync as statSync3,
16367
- appendFileSync as appendFileSync3,
16368
- readFileSync as readFileSync12
16278
+ statSync as statSync2,
16279
+ appendFileSync as appendFileSync2,
16280
+ readFileSync as readFileSync11
16369
16281
  } from "fs";
16370
- import { resolve as resolve11, join as join16, isAbsolute as isAbsolute2 } from "path";
16282
+ import { resolve as resolve10, join as join15, isAbsolute as isAbsolute2 } from "path";
16371
16283
 
16372
16284
  // src/cli/mcp-config-emitter.ts
16373
- import { existsSync as existsSync17, readFileSync as readFileSync10, writeFileSync as writeFileSync5, appendFileSync as appendFileSync2 } from "fs";
16374
- import { join as join13 } from "path";
16285
+ import { existsSync as existsSync16, readFileSync as readFileSync9, writeFileSync as writeFileSync5, appendFileSync } from "fs";
16286
+ import { join as join12 } from "path";
16375
16287
  var MCP_CONFIG_FILENAME = ".mcp.json";
16376
16288
  var NEXUS_SERVER_KEY = "nexus-agents";
16377
16289
  function buildNexusServerEntry(dataDir, commandPath) {
@@ -16394,10 +16306,10 @@ function entriesEqual(a, b) {
16394
16306
  return true;
16395
16307
  }
16396
16308
  function loadExistingConfig(path22) {
16397
- if (!existsSync17(path22)) return { ok: true, value: void 0 };
16309
+ if (!existsSync16(path22)) return { ok: true, value: void 0 };
16398
16310
  let raw;
16399
16311
  try {
16400
- raw = readFileSync10(path22, "utf-8");
16312
+ raw = readFileSync9(path22, "utf-8");
16401
16313
  } catch (e) {
16402
16314
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
16403
16315
  }
@@ -16431,24 +16343,24 @@ function decideEmission(existing, desired, force) {
16431
16343
  return { kind: "write", nextConfig: { ...existing, mcpServers: nextServers } };
16432
16344
  }
16433
16345
  function autoGitignoreMcpConfig(workspaceDir, dryRun) {
16434
- const gitDir = join13(workspaceDir, ".git");
16435
- if (!existsSync17(gitDir)) return false;
16436
- const gitignorePath = join13(workspaceDir, ".gitignore");
16346
+ const gitDir = join12(workspaceDir, ".git");
16347
+ if (!existsSync16(gitDir)) return false;
16348
+ const gitignorePath = join12(workspaceDir, ".gitignore");
16437
16349
  let existing = "";
16438
- if (existsSync17(gitignorePath)) {
16439
- existing = readFileSync10(gitignorePath, "utf-8");
16350
+ if (existsSync16(gitignorePath)) {
16351
+ existing = readFileSync9(gitignorePath, "utf-8");
16440
16352
  const already = existing.split("\n").some((l) => l.trim() === MCP_CONFIG_FILENAME || l.trim() === `/${MCP_CONFIG_FILENAME}`);
16441
16353
  if (already) return false;
16442
16354
  }
16443
16355
  if (!dryRun) {
16444
16356
  const sep3 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
16445
- appendFileSync2(gitignorePath, `${sep3}${MCP_CONFIG_FILENAME}
16357
+ appendFileSync(gitignorePath, `${sep3}${MCP_CONFIG_FILENAME}
16446
16358
  `, "utf-8");
16447
16359
  }
16448
16360
  return true;
16449
16361
  }
16450
16362
  function emitMcpConfig(options) {
16451
- const mcpConfigPath = join13(options.workspaceDir, MCP_CONFIG_FILENAME);
16363
+ const mcpConfigPath = join12(options.workspaceDir, MCP_CONFIG_FILENAME);
16452
16364
  const dryRun = options.dryRun === true;
16453
16365
  const force = options.force === true;
16454
16366
  const desired = buildNexusServerEntry(options.dataDir, options.commandPath);
@@ -16486,13 +16398,13 @@ function makeFailure(mcpConfigPath, error) {
16486
16398
 
16487
16399
  // src/cli/portable-installer.ts
16488
16400
  import { execFile } from "child_process";
16489
- import { existsSync as existsSync19, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync7 } from "fs";
16490
- import { join as join15 } from "path";
16401
+ import { existsSync as existsSync18, mkdirSync as mkdirSync4, rmSync, writeFileSync as writeFileSync7 } from "fs";
16402
+ import { join as join14 } from "path";
16491
16403
  import { promisify } from "util";
16492
16404
 
16493
16405
  // src/cli/bin-shim.ts
16494
- import { existsSync as existsSync18, readFileSync as readFileSync11, writeFileSync as writeFileSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "fs";
16495
- import { join as join14 } from "path";
16406
+ import { existsSync as existsSync17, readFileSync as readFileSync10, writeFileSync as writeFileSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync3 } from "fs";
16407
+ import { join as join13 } from "path";
16496
16408
  var SHIM_BASENAME = "nexus-agents";
16497
16409
  var SHIM_MODE = 493;
16498
16410
  function buildShimContents(cliEntryPath) {
@@ -16506,18 +16418,18 @@ function buildShimContents(cliEntryPath) {
16506
16418
  return lines.join("\n");
16507
16419
  }
16508
16420
  function writeBinShim(options) {
16509
- const shimPath = join14(options.binDir, SHIM_BASENAME);
16421
+ const shimPath = join13(options.binDir, SHIM_BASENAME);
16510
16422
  const desired = buildShimContents(options.cliEntryPath);
16511
16423
  const dryRun = options.dryRun === true;
16512
16424
  try {
16513
- if (existsSync18(shimPath)) {
16514
- const current = readFileSync11(shimPath, "utf-8");
16425
+ if (existsSync17(shimPath)) {
16426
+ const current = readFileSync10(shimPath, "utf-8");
16515
16427
  if (current === desired) {
16516
16428
  return { success: true, shimPath, written: false, alreadyMatched: true, error: null };
16517
16429
  }
16518
16430
  }
16519
16431
  if (!dryRun) {
16520
- if (!existsSync18(options.binDir)) mkdirSync3(options.binDir, { recursive: true });
16432
+ if (!existsSync17(options.binDir)) mkdirSync3(options.binDir, { recursive: true });
16521
16433
  writeFileSync6(shimPath, desired, "utf-8");
16522
16434
  chmodSync2(shimPath, SHIM_MODE);
16523
16435
  }
@@ -16552,10 +16464,10 @@ function writeInstallManifest(cliDir, version) {
16552
16464
  description: "Local install root for portable nexus-agents (generated; do not commit)",
16553
16465
  dependencies: { "nexus-agents": version }
16554
16466
  };
16555
- writeFileSync7(join15(cliDir, "package.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
16467
+ writeFileSync7(join14(cliDir, "package.json"), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
16556
16468
  }
16557
16469
  function isAlreadyInstalled(cliDir) {
16558
- return existsSync19(join15(cliDir, "node_modules", "nexus-agents", "package.json"));
16470
+ return existsSync18(join14(cliDir, "node_modules", "nexus-agents", "package.json"));
16559
16471
  }
16560
16472
  async function spawnNpmInstall(cliDir) {
16561
16473
  await execFileAsync("npm", ["install", "--no-audit", "--no-fund", "--silent"], {
@@ -16571,7 +16483,7 @@ function cleanupOnFailure(cliDir) {
16571
16483
  }
16572
16484
  async function runNpmStep(ctx) {
16573
16485
  try {
16574
- if (!existsSync19(ctx.cliDir)) mkdirSync4(ctx.cliDir, { recursive: true });
16486
+ if (!existsSync18(ctx.cliDir)) mkdirSync4(ctx.cliDir, { recursive: true });
16575
16487
  writeInstallManifest(ctx.cliDir, ctx.version);
16576
16488
  await spawnNpmInstall(ctx.cliDir);
16577
16489
  return void 0;
@@ -16582,8 +16494,8 @@ async function runNpmStep(ctx) {
16582
16494
  }
16583
16495
  }
16584
16496
  async function installPortable(options) {
16585
- const cliDir = join15(options.dataDir, CLI_SUBDIR);
16586
- const binDir = join15(options.dataDir, BIN_SUBDIR);
16497
+ const cliDir = join14(options.dataDir, CLI_SUBDIR);
16498
+ const binDir = join14(options.dataDir, BIN_SUBDIR);
16587
16499
  const versionResolution = resolveInstallVersion(options.version);
16588
16500
  if (!versionResolution.ok) {
16589
16501
  return {
@@ -16604,7 +16516,7 @@ async function installPortable(options) {
16604
16516
  }
16605
16517
  const npmFailure = await runNpmStep(ctx);
16606
16518
  if (npmFailure !== void 0) return npmFailure;
16607
- const shim = writeBinShim({ binDir, cliEntryPath: join15(cliDir, CLI_ENTRY_RELATIVE) });
16519
+ const shim = writeBinShim({ binDir, cliEntryPath: join14(cliDir, CLI_ENTRY_RELATIVE) });
16608
16520
  if (!shim.success) {
16609
16521
  cleanupOnFailure(cliDir);
16610
16522
  return {
@@ -16618,14 +16530,14 @@ async function installPortable(options) {
16618
16530
  return { success: true, ...ctx, shim, skipped: false, error: null };
16619
16531
  }
16620
16532
  function uninstallPortable(options) {
16621
- const cliDir = join15(options.dataDir, CLI_SUBDIR);
16622
- const binDir = join15(options.dataDir, BIN_SUBDIR);
16533
+ const cliDir = join14(options.dataDir, CLI_SUBDIR);
16534
+ const binDir = join14(options.dataDir, BIN_SUBDIR);
16623
16535
  const removed = [];
16624
16536
  const notPresent = [];
16625
16537
  const dryRun = options.dryRun === true;
16626
16538
  try {
16627
16539
  for (const dir of [cliDir, binDir]) {
16628
- if (!existsSync19(dir)) {
16540
+ if (!existsSync18(dir)) {
16629
16541
  notPresent.push(dir);
16630
16542
  continue;
16631
16543
  }
@@ -16639,8 +16551,8 @@ function uninstallPortable(options) {
16639
16551
  }
16640
16552
  }
16641
16553
  function findBinShim(dataDir) {
16642
- const shimPath = join15(dataDir, BIN_SUBDIR, "nexus-agents");
16643
- return existsSync19(shimPath) ? shimPath : void 0;
16554
+ const shimPath = join14(dataDir, BIN_SUBDIR, "nexus-agents");
16555
+ return existsSync18(shimPath) ? shimPath : void 0;
16644
16556
  }
16645
16557
 
16646
16558
  // src/cli/init-portable.ts
@@ -16648,18 +16560,18 @@ var DEFAULT_PORTABLE_DIRNAME = ".nexus-agents";
16648
16560
  var RESTRICTED_SUBDIRS = /* @__PURE__ */ new Set(["auth"]);
16649
16561
  function resolveTargetPath(rawPath) {
16650
16562
  if (rawPath === void 0 || rawPath === "") {
16651
- return resolve11(process.cwd(), DEFAULT_PORTABLE_DIRNAME);
16563
+ return resolve10(process.cwd(), DEFAULT_PORTABLE_DIRNAME);
16652
16564
  }
16653
- return isAbsolute2(rawPath) ? rawPath : resolve11(process.cwd(), rawPath);
16565
+ return isAbsolute2(rawPath) ? rawPath : resolve10(process.cwd(), rawPath);
16654
16566
  }
16655
16567
  function isNonEmpty(dir) {
16656
- if (!existsSync20(dir)) return false;
16657
- const stat2 = statSync3(dir);
16568
+ if (!existsSync19(dir)) return false;
16569
+ const stat2 = statSync2(dir);
16658
16570
  if (!stat2.isDirectory()) return true;
16659
16571
  return readdirSync(dir).length > 0;
16660
16572
  }
16661
16573
  function ensureDir(path22, dryRun, created, alreadyExisted, mode) {
16662
- if (existsSync20(path22)) {
16574
+ if (existsSync19(path22)) {
16663
16575
  alreadyExisted.push(path22);
16664
16576
  return;
16665
16577
  }
@@ -16669,37 +16581,37 @@ function ensureDir(path22, dryRun, created, alreadyExisted, mode) {
16669
16581
  created.push(path22);
16670
16582
  }
16671
16583
  function maybeUpdateGitignore(workspaceDir, portableDirName, dryRun) {
16672
- const gitDir = join16(workspaceDir, ".git");
16673
- if (!existsSync20(gitDir)) return false;
16674
- const gitignorePath = join16(workspaceDir, ".gitignore");
16584
+ const gitDir = join15(workspaceDir, ".git");
16585
+ if (!existsSync19(gitDir)) return false;
16586
+ const gitignorePath = join15(workspaceDir, ".gitignore");
16675
16587
  const entry = `${portableDirName}/`;
16676
16588
  let existing = "";
16677
- if (existsSync20(gitignorePath)) {
16678
- existing = readFileSync12(gitignorePath, "utf-8");
16589
+ if (existsSync19(gitignorePath)) {
16590
+ existing = readFileSync11(gitignorePath, "utf-8");
16679
16591
  if (existing.split("\n").some((l) => l.trim() === entry || l.trim() === portableDirName)) {
16680
16592
  return false;
16681
16593
  }
16682
16594
  }
16683
16595
  if (!dryRun) {
16684
16596
  const sep3 = existing.length > 0 && !existing.endsWith("\n") ? "\n" : "";
16685
- appendFileSync3(gitignorePath, `${sep3}${entry}
16597
+ appendFileSync2(gitignorePath, `${sep3}${entry}
16686
16598
  `, "utf-8");
16687
16599
  }
16688
16600
  return true;
16689
16601
  }
16690
16602
  function inspectTarget(target) {
16691
- const exists = existsSync20(target);
16603
+ const exists = existsSync19(target);
16692
16604
  if (!exists) return { exists: false, nonEmpty: false, isExistingNexusDir: false };
16693
16605
  const nonEmpty = isNonEmpty(target);
16694
- const stat2 = statSync3(target);
16695
- const isExistingNexusDir = stat2.isDirectory() && existsSync20(join16(target, "audit"));
16606
+ const stat2 = statSync2(target);
16607
+ const isExistingNexusDir = stat2.isDirectory() && existsSync19(join15(target, "audit"));
16696
16608
  return { exists, nonEmpty, isExistingNexusDir };
16697
16609
  }
16698
16610
  function createDataLayout(target, dryRun, created, alreadyExisted) {
16699
16611
  ensureDir(target, dryRun, created, alreadyExisted);
16700
16612
  for (const subdir of DATA_SUBDIRECTORIES) {
16701
16613
  const mode = RESTRICTED_SUBDIRS.has(subdir) ? 448 : void 0;
16702
- ensureDir(join16(target, subdir), dryRun, created, alreadyExisted, mode);
16614
+ ensureDir(join15(target, subdir), dryRun, created, alreadyExisted, mode);
16703
16615
  }
16704
16616
  }
16705
16617
  function makeResult(opts) {
@@ -16718,13 +16630,13 @@ function makeResult(opts) {
16718
16630
  }
16719
16631
  function applyGitignoreOption(target, options, dryRun) {
16720
16632
  if (options.gitignore !== true) return false;
16721
- const workspaceDir = resolve11(target, "..");
16633
+ const workspaceDir = resolve10(target, "..");
16722
16634
  const portableName = target.slice(workspaceDir.length + 1);
16723
16635
  return maybeUpdateGitignore(workspaceDir, portableName, dryRun);
16724
16636
  }
16725
16637
  function applyMcpConfigOption(target, options, dryRun) {
16726
16638
  if (options.mcpConfig !== true) return void 0;
16727
- const workspaceDir = resolve11(target, "..");
16639
+ const workspaceDir = resolve10(target, "..");
16728
16640
  const shimPath = findBinShim(target);
16729
16641
  return emitMcpConfig({
16730
16642
  workspaceDir,
@@ -16981,7 +16893,45 @@ function buildStructuredOutput(result) {
16981
16893
  };
16982
16894
  }
16983
16895
  var RUN_DEV_PIPELINE_DESCRIPTION = "Run the multi-agent development pipeline. Accepts direct task instructions, a plan file, or a spec file. Supports dry-run (plan+vote only).";
16984
- function registerDevPipelineTool(server, _deps) {
16896
+ async function runDevPipelineHandler(args, logger18) {
16897
+ const parsed = DevPipelineInputSchema.safeParse(args);
16898
+ if (!parsed.success) {
16899
+ return toolStructuredError({
16900
+ errorCategory: "validation",
16901
+ message: `Invalid input: ${formatZodError(parsed.error)}`
16902
+ });
16903
+ }
16904
+ const input = parsed.data;
16905
+ if (input.simulateVotes) {
16906
+ warnIfSimulatedOutsideTests("run_dev_pipeline", logger18);
16907
+ }
16908
+ try {
16909
+ const taskText = await resolveTaskInput(input);
16910
+ const stages = await createStages(input);
16911
+ const pipelineOptions = {
16912
+ ...input.sessionId !== void 0 ? { sessionId: input.sessionId } : {},
16913
+ ...input.dryRun ? { dryRun: true } : {},
16914
+ ...input.mode === "harness" ? { mode: "harness" } : {}
16915
+ };
16916
+ const hasOptions = Object.keys(pipelineOptions).length > 0;
16917
+ const result = await runDevPipeline(taskText, stages, hasOptions ? pipelineOptions : void 0);
16918
+ flushPipelineMemory();
16919
+ return toolSuccessStructured(buildStructuredOutput(result));
16920
+ } catch (error) {
16921
+ return toolStructuredError({
16922
+ errorCategory: "internal",
16923
+ message: `Pipeline error: ${getErrorMessage(error)}`
16924
+ });
16925
+ }
16926
+ }
16927
+ function registerDevPipelineTool(server, deps) {
16928
+ const logger18 = deps.logger ?? createLogger({ tool: "run_dev_pipeline" });
16929
+ const secureHandler = createSecureHandler(
16930
+ (args) => runDevPipelineHandler(args, logger18),
16931
+ { toolName: "run_dev_pipeline", rateLimiter: deps.rateLimiter, logger: logger18 }
16932
+ );
16933
+ const timeoutMs = getToolTimeout("run_dev_pipeline", deps.security);
16934
+ const wrapped = wrapToolWithTimeout("run_dev_pipeline", secureHandler, { timeoutMs, logger: logger18 });
16985
16935
  server.registerTool(
16986
16936
  "run_dev_pipeline",
16987
16937
  {
@@ -16989,41 +16939,9 @@ function registerDevPipelineTool(server, _deps) {
16989
16939
  inputSchema: DevPipelineInputSchema.shape,
16990
16940
  annotations: getToolAnnotations("run_dev_pipeline")
16991
16941
  },
16992
- async (args) => {
16993
- const input = DevPipelineInputSchema.parse(args);
16994
- if (input.simulateVotes) {
16995
- warnIfSimulatedOutsideTests("run_dev_pipeline", createLogger({ tool: "run_dev_pipeline" }));
16996
- }
16997
- try {
16998
- const taskText = await resolveTaskInput(input);
16999
- const stages = await createStages(input);
17000
- const pipelineOptions = {
17001
- ...input.sessionId !== void 0 ? { sessionId: input.sessionId } : {},
17002
- ...input.dryRun ? { dryRun: true } : {},
17003
- ...input.mode === "harness" ? { mode: "harness" } : {}
17004
- };
17005
- const hasOptions = Object.keys(pipelineOptions).length > 0;
17006
- const result = await runDevPipeline(
17007
- taskText,
17008
- stages,
17009
- hasOptions ? pipelineOptions : void 0
17010
- );
17011
- flushPipelineMemory();
17012
- const structured = buildStructuredOutput(result);
17013
- return {
17014
- content: [{ type: "text", text: JSON.stringify(structured, null, 2) }],
17015
- structuredContent: structured
17016
- };
17017
- } catch (error) {
17018
- return {
17019
- ...toolStructuredError({
17020
- errorCategory: "internal",
17021
- message: `Pipeline error: ${getErrorMessage(error)}`
17022
- })
17023
- };
17024
- }
17025
- }
16942
+ toSdkCallback(wrapped)
17026
16943
  );
16944
+ logger18.info("Registered run_dev_pipeline tool");
17027
16945
  }
17028
16946
 
17029
16947
  // src/cli-server-stpa.ts
@@ -17136,7 +17054,7 @@ var StpaSafetyError = class extends NexusError {
17136
17054
  this.analysisResult = analysisResult;
17137
17055
  }
17138
17056
  };
17139
- function logToolResults(logger17, result) {
17057
+ function logToolResults(logger18, result) {
17140
17058
  for (const toolResult of result.toolResults) {
17141
17059
  if (toolResult.hazards.length === 0) continue;
17142
17060
  const criticalCount = toolResult.hazards.filter(
@@ -17144,7 +17062,7 @@ function logToolResults(logger17, result) {
17144
17062
  ).length;
17145
17063
  const highCount = toolResult.hazards.filter((h) => h.severity === "high" /* HIGH */).length;
17146
17064
  if (criticalCount > 0 || highCount > 0) {
17147
- logger17.warn(`STPA hazards for tool '${toolResult.toolName}'`, {
17065
+ logger18.warn(`STPA hazards for tool '${toolResult.toolName}'`, {
17148
17066
  riskLevel: toolResult.riskLevel,
17149
17067
  riskScore: toolResult.riskScore,
17150
17068
  criticalHazards: criticalCount,
@@ -17152,7 +17070,7 @@ function logToolResults(logger17, result) {
17152
17070
  safetyConstraints: toolResult.safetyConstraints.length
17153
17071
  });
17154
17072
  } else {
17155
- logger17.debug(`STPA analysis for tool '${toolResult.toolName}'`, {
17073
+ logger18.debug(`STPA analysis for tool '${toolResult.toolName}'`, {
17156
17074
  riskLevel: toolResult.riskLevel,
17157
17075
  hazards: toolResult.hazards.length
17158
17076
  });
@@ -17170,7 +17088,7 @@ function checkHighSeverityTools(result, failOnHighSeverity) {
17170
17088
  result
17171
17089
  );
17172
17090
  }
17173
- function runStpaSafetyAnalysis(logger17, failOnHighSeverity) {
17091
+ function runStpaSafetyAnalysis(logger18, failOnHighSeverity) {
17174
17092
  const analysisResult = analyzeTools(TOOL_DEFINITIONS);
17175
17093
  if (!analysisResult.ok) {
17176
17094
  const errorMsg = analysisResult.error.message;
@@ -17179,12 +17097,12 @@ function runStpaSafetyAnalysis(logger17, failOnHighSeverity) {
17179
17097
  code: ErrorCode.SECURITY_ERROR
17180
17098
  });
17181
17099
  }
17182
- logger17.warn("STPA safety analysis failed", { error: errorMsg });
17100
+ logger18.warn("STPA safety analysis failed", { error: errorMsg });
17183
17101
  return;
17184
17102
  }
17185
17103
  const result = analysisResult.value;
17186
17104
  const { summary } = result;
17187
- logger17.info("STPA safety analysis completed", {
17105
+ logger18.info("STPA safety analysis completed", {
17188
17106
  toolsAnalyzed: summary.totalTools,
17189
17107
  hazardsIdentified: summary.totalHazards,
17190
17108
  unsafeControlActions: summary.totalUnsafeControlActions,
@@ -17192,10 +17110,10 @@ function runStpaSafetyAnalysis(logger17, failOnHighSeverity) {
17192
17110
  averageRiskScore: summary.averageRiskScore.toFixed(1),
17193
17111
  toolsByRiskLevel: summary.toolsByRiskLevel
17194
17112
  });
17195
- logToolResults(logger17, result);
17113
+ logToolResults(logger18, result);
17196
17114
  checkHighSeverityTools(result, failOnHighSeverity);
17197
17115
  if (result.interactions.length > 0) {
17198
- logger17.info("STPA cross-tool hazard interactions detected", {
17116
+ logger18.info("STPA cross-tool hazard interactions detected", {
17199
17117
  interactionCount: result.interactions.length,
17200
17118
  interactions: result.interactions.map((i) => ({
17201
17119
  tools: i.involvedTools,
@@ -17232,10 +17150,10 @@ var UpstreamClient = class {
17232
17150
  transport = null;
17233
17151
  state = "disconnected";
17234
17152
  tools = [];
17235
- constructor(config, logger17) {
17153
+ constructor(config, logger18) {
17236
17154
  this.name = config.name;
17237
17155
  this.config = config;
17238
- this.log = logger17 ?? createLogger({ component: `upstream:${config.name}` });
17156
+ this.log = logger18 ?? createLogger({ component: `upstream:${config.name}` });
17239
17157
  }
17240
17158
  /** Connect to the upstream server. Idempotent. */
17241
17159
  async connect() {
@@ -17335,8 +17253,8 @@ var UpstreamClient = class {
17335
17253
  var UpstreamClientManager = class {
17336
17254
  clients = /* @__PURE__ */ new Map();
17337
17255
  log;
17338
- constructor(logger17) {
17339
- this.log = logger17 ?? createLogger({ component: "UpstreamClientManager" });
17256
+ constructor(logger18) {
17257
+ this.log = logger18 ?? createLogger({ component: "UpstreamClientManager" });
17340
17258
  }
17341
17259
  /** Register upstream servers from config. */
17342
17260
  registerServers(configs) {
@@ -17444,11 +17362,11 @@ var REGISTERED_TOOLS = [
17444
17362
  "improvement_review"
17445
17363
  ];
17446
17364
  var MOCK_ORCHESTRATION_ENV = "NEXUS_ALLOW_MOCK_ORCHESTRATION";
17447
- function createOrchestratorForOrchestration(modelAdapter, logger17, useMockTechLead) {
17365
+ function createOrchestratorForOrchestration(modelAdapter, logger18, useMockTechLead) {
17448
17366
  if (modelAdapter !== void 0) {
17449
- const orchestratorAgent = new Orchestrator({ adapter: modelAdapter, logger: logger17 });
17367
+ const orchestratorAgent = new Orchestrator({ adapter: modelAdapter, logger: logger18 });
17450
17368
  const factory = new OrchestratorFactory({
17451
- logger: logger17,
17369
+ logger: logger18,
17452
17370
  techLead: orchestratorAgent
17453
17371
  });
17454
17372
  return factory.create("orchestrator");
@@ -17457,7 +17375,7 @@ function createOrchestratorForOrchestration(modelAdapter, logger17, useMockTechL
17457
17375
  const mockEnabled = useMockTechLead === true || envMockEnabled;
17458
17376
  if (mockEnabled) {
17459
17377
  const source = envMockEnabled ? `${MOCK_ORCHESTRATION_ENV} env var` : "config";
17460
- logger17.warn(
17378
+ logger18.warn(
17461
17379
  `Using mock orchestrator as explicitly configured via ${source} (no real adapter available)`
17462
17380
  );
17463
17381
  return createMockOrchestrator();
@@ -17611,14 +17529,14 @@ function registerOrchestrateToolSafe(ctx) {
17611
17529
  });
17612
17530
  }
17613
17531
  }
17614
- async function initUpstreamServers(gatewayConfig, server, logger17) {
17532
+ async function initUpstreamServers(gatewayConfig, server, logger18) {
17615
17533
  const upstreamServers = gatewayConfig?.["upstreamServers"];
17616
17534
  if (upstreamServers === void 0 || upstreamServers.length === 0) return;
17617
- const manager = new UpstreamClientManager(logger17);
17535
+ const manager = new UpstreamClientManager(logger18);
17618
17536
  manager.registerServers(upstreamServers);
17619
17537
  await manager.connectEager();
17620
17538
  const tools = manager.getAllTools();
17621
- logger17.info("Upstream MCP servers initialized", {
17539
+ logger18.info("Upstream MCP servers initialized", {
17622
17540
  servers: upstreamServers.length,
17623
17541
  tools: tools.length
17624
17542
  });
@@ -17638,11 +17556,11 @@ async function initUpstreamServers(gatewayConfig, server, logger17) {
17638
17556
  );
17639
17557
  }
17640
17558
  }
17641
- function maybeRunStpaAnalysis(options, logger17) {
17559
+ function maybeRunStpaAnalysis(options, logger18) {
17642
17560
  const enableStpa = options.enableStpaSafetyAnalysis ?? false;
17643
17561
  if (!enableStpa) return;
17644
- logger17.info("Running STPA safety analysis on registered tools");
17645
- runStpaSafetyAnalysis(logger17, options.failOnHighSeverityHazards ?? false);
17562
+ logger18.info("Running STPA safety analysis on registered tools");
17563
+ runStpaSafetyAnalysis(logger18, options.failOnHighSeverityHazards ?? false);
17646
17564
  }
17647
17565
  function copyOptionalProps(opts) {
17648
17566
  const result = {};
@@ -17668,16 +17586,16 @@ function createToolContext(options, toolInfra, rateLimiterFactory) {
17668
17586
  }
17669
17587
  };
17670
17588
  }
17671
- function logToolRegistration(logger17, allowlist, info) {
17589
+ function logToolRegistration(logger18, allowlist, info) {
17672
17590
  const activeTools = allowlist ? REGISTERED_TOOLS.filter((t) => allowlist.has(t)) : [...REGISTERED_TOOLS];
17673
17591
  if (allowlist !== void 0) {
17674
- logger17.info("Tool allowlist active", {
17592
+ logger18.info("Tool allowlist active", {
17675
17593
  allowed: activeTools.length,
17676
17594
  total: REGISTERED_TOOLS.length,
17677
17595
  blocked: REGISTERED_TOOLS.filter((t) => !allowlist.has(t))
17678
17596
  });
17679
17597
  }
17680
- logger17.info("Tools registered with per-tool rate limiting", {
17598
+ logger18.info("Tools registered with per-tool rate limiting", {
17681
17599
  registeredTools: activeTools,
17682
17600
  rateLimitingEnabled: info.rateLimiterFactory.isEnabled(),
17683
17601
  customRateLimitsConfigured: info.perToolConfig !== void 0,
@@ -17733,13 +17651,13 @@ function registerToolCategories(ctx) {
17733
17651
  if (allowed(tool.name)) tool.register(ctx.server, buildStandardDeps(ctx, tool.name));
17734
17652
  }
17735
17653
  }
17736
- function initV2PipelineSubsystems(logger17) {
17654
+ function initV2PipelineSubsystems(logger18) {
17737
17655
  const pluginRegistry = getPipelinePluginRegistry();
17738
17656
  const pipelineEventBus = getPipelineEventBus();
17739
17657
  const bridge = createEventBusBridge({ source: pipelineEventBus });
17740
17658
  const policyEngine = createDefaultPolicyEngine();
17741
17659
  const v2Config = resolveV2Config();
17742
- logger17.info("V2 Pipeline OS initialized", {
17660
+ logger18.info("V2 Pipeline OS initialized", {
17743
17661
  plugins: pluginRegistry.listEnabled().length,
17744
17662
  bridged: bridge.forwarded(),
17745
17663
  policyRules: policyEngine.listRules().length,
@@ -17750,7 +17668,7 @@ function initV2PipelineSubsystems(logger17) {
17750
17668
  function registerMcpTools(options) {
17751
17669
  const {
17752
17670
  server,
17753
- logger: logger17,
17671
+ logger: logger18,
17754
17672
  builtInTemplates,
17755
17673
  modelAdapter,
17756
17674
  policyFirewall,
@@ -17761,7 +17679,7 @@ function registerMcpTools(options) {
17761
17679
  const gatewayServer = gatewayConfig !== void 0 ? createGatewayServerProxy(server, gatewayConfig) : server;
17762
17680
  const annotatedServer = createAnnotationsProxy(gatewayServer);
17763
17681
  const observableServer = createToolObservabilityProxy(annotatedServer, getPipelineEventBus());
17764
- const toolInfra = registerTools(observableServer, { logger: logger17 });
17682
+ const toolInfra = registerTools(observableServer, { logger: logger18 });
17765
17683
  const rateLimitConfig = securityConfig?.rateLimit;
17766
17684
  const perToolConfig = rateLimitConfig?.perTool;
17767
17685
  const rateLimiterFactory = createToolRateLimiterFactory({
@@ -17770,14 +17688,14 @@ function registerMcpTools(options) {
17770
17688
  logger: toolInfra.logger
17771
17689
  });
17772
17690
  setGlobalToolRateLimiterFactory(rateLimiterFactory);
17773
- initV2PipelineSubsystems(logger17);
17691
+ initV2PipelineSubsystems(logger18);
17774
17692
  const gatewayOptions = { ...options, server: observableServer };
17775
17693
  const ctx = createToolContext(gatewayOptions, toolInfra, rateLimiterFactory);
17776
17694
  registerToolCategories(ctx);
17777
- void initUpstreamServers(gatewayConfig, observableServer, logger17);
17778
- registerPrompts(observableServer, logger17);
17779
- registerResources(observableServer, logger17);
17780
- logToolRegistration(logger17, ctx.toolAllowlist, {
17695
+ void initUpstreamServers(gatewayConfig, observableServer, logger18);
17696
+ registerPrompts(observableServer, logger18);
17697
+ registerResources(observableServer, logger18);
17698
+ logToolRegistration(logger18, ctx.toolAllowlist, {
17781
17699
  rateLimiterFactory,
17782
17700
  perToolConfig,
17783
17701
  builtInTemplates,
@@ -17785,34 +17703,34 @@ function registerMcpTools(options) {
17785
17703
  policyFirewall,
17786
17704
  executionMode
17787
17705
  });
17788
- maybeRunStpaAnalysis(options, logger17);
17706
+ maybeRunStpaAnalysis(options, logger18);
17789
17707
  }
17790
17708
 
17791
17709
  // src/cli-server.ts
17792
17710
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17793
17711
 
17794
17712
  // src/cli-server-lifecycle.ts
17795
- function initializeSwarmObserver(logger17, options) {
17713
+ function initializeSwarmObserver(logger18, options) {
17796
17714
  const maxEvents = options?.maxEvents ?? 1e4;
17797
17715
  const observer = getSwarmObserver({
17798
17716
  maxEvents
17799
17717
  });
17800
- logger17.info("SwarmObserver initialized for interaction tracing", {
17718
+ logger18.info("SwarmObserver initialized for interaction tracing", {
17801
17719
  maxEvents,
17802
17720
  configuredFromYaml: options?.maxEvents !== void 0
17803
17721
  });
17804
17722
  return observer;
17805
17723
  }
17806
- function initializeEventBus(observer, logger17, config) {
17724
+ function initializeEventBus(observer, logger18, config) {
17807
17725
  const envEnabled = process.env["NEXUS_EVENTBUS_ENABLED"];
17808
17726
  const enabled = envEnabled !== void 0 ? envEnabled === "true" : config?.enabled ?? true;
17809
17727
  const effectiveConfig = {
17810
17728
  ...config,
17811
17729
  enabled
17812
17730
  };
17813
- const result = initializeEventBusBridge(observer, logger17, effectiveConfig);
17731
+ const result = initializeEventBusBridge(observer, logger18, effectiveConfig);
17814
17732
  if (result.initialized) {
17815
- logger17.info("EventBus bridge initialized for A2A visibility", {
17733
+ logger18.info("EventBus bridge initialized for A2A visibility", {
17816
17734
  subscriptionCount: result.subscriptionCount,
17817
17735
  eventBusEnabled: enabled
17818
17736
  });
@@ -17857,17 +17775,17 @@ function recordServerShutdown(observer, context) {
17857
17775
  }
17858
17776
  });
17859
17777
  }
17860
- function logFinalHealthMetrics(observer, logger17) {
17778
+ function logFinalHealthMetrics(observer, logger18) {
17861
17779
  const healthMetrics = observer.getHealthMetrics();
17862
- logger17.info("Final swarm health metrics", {
17780
+ logger18.info("Final swarm health metrics", {
17863
17781
  activeAgents: healthMetrics.activeAgents,
17864
17782
  totalAgents: healthMetrics.totalAgents,
17865
17783
  totalInteractions: healthMetrics.totalInteractions
17866
17784
  });
17867
17785
  }
17868
- function logFinalEventBusStats(logger17) {
17786
+ function logFinalEventBusStats(logger18) {
17869
17787
  const finalStats = getEventBusStats();
17870
- logger17.info("Final EventBus statistics", {
17788
+ logger18.info("Final EventBus statistics", {
17871
17789
  eventsEmitted: finalStats.eventsEmitted,
17872
17790
  activeSubscriptions: finalStats.activeSubscriptions,
17873
17791
  historySize: finalStats.historySize,
@@ -17877,14 +17795,14 @@ function logFinalEventBusStats(logger17) {
17877
17795
 
17878
17796
  // src/cli-orchestrator.ts
17879
17797
  import * as readline2 from "readline";
17880
- function runOrchestratorRepl(options, logger17) {
17881
- return new Promise((resolve15) => {
17798
+ function runOrchestratorRepl(options, logger18) {
17799
+ return new Promise((resolve14) => {
17882
17800
  const rl = readline2.createInterface({
17883
17801
  input: process.stdin,
17884
17802
  output: process.stdout,
17885
17803
  prompt: "nexus> "
17886
17804
  });
17887
- logger17.info('Orchestrator REPL started (type "exit" to quit)');
17805
+ logger18.info('Orchestrator REPL started (type "exit" to quit)');
17888
17806
  process.stdout.write("\n");
17889
17807
  rl.prompt();
17890
17808
  rl.on("line", (line) => {
@@ -17913,15 +17831,15 @@ function runOrchestratorRepl(options, logger17) {
17913
17831
  })();
17914
17832
  });
17915
17833
  rl.on("close", () => {
17916
- logger17.info("Orchestrator REPL closed");
17917
- resolve15();
17834
+ logger18.info("Orchestrator REPL closed");
17835
+ resolve14();
17918
17836
  });
17919
17837
  });
17920
17838
  }
17921
17839
  async function startOrchestratorMode(options) {
17922
- const logger17 = createLogger({ component: "orchestrator" });
17923
- if (options.verbose) logger17.setLevel("debug");
17924
- logger17.info("Starting Nexus Agents in orchestrator mode", {
17840
+ const logger18 = createLogger({ component: "orchestrator" });
17841
+ if (options.verbose) logger18.setLevel("debug");
17842
+ logger18.info("Starting Nexus Agents in orchestrator mode", {
17925
17843
  version: VERSION,
17926
17844
  hasTask: options.task !== void 0
17927
17845
  });
@@ -17939,17 +17857,17 @@ async function startOrchestratorMode(options) {
17939
17857
  process.exit(exitCode2);
17940
17858
  }
17941
17859
  if (process.stdin.isTTY) {
17942
- await runOrchestratorRepl(options, logger17);
17860
+ await runOrchestratorRepl(options, logger18);
17943
17861
  process.exit(EXIT_CODES.SUCCESS);
17944
17862
  }
17945
- logger17.info("Reading task from stdin...");
17863
+ logger18.info("Reading task from stdin...");
17946
17864
  const chunks = [];
17947
17865
  for await (const chunk of process.stdin) {
17948
17866
  chunks.push(String(chunk));
17949
17867
  }
17950
17868
  const task = chunks.join("").trim();
17951
17869
  if (task.length === 0) {
17952
- logger17.error("No task provided. Use --task or pipe input via stdin.");
17870
+ logger18.error("No task provided. Use --task or pipe input via stdin.");
17953
17871
  process.exit(EXIT_CODES.INVALID_ARGS);
17954
17872
  }
17955
17873
  const orchestrateOptions = {
@@ -18015,50 +17933,50 @@ function convertCustomExpert(id, def) {
18015
17933
  }
18016
17934
  };
18017
17935
  }
18018
- function createBuiltInExperts(logger17, options) {
17936
+ function createBuiltInExperts(logger18, options) {
18019
17937
  const result = ExpertFactory.createAllBuiltIn(options);
18020
17938
  if (!result.ok) {
18021
- logger17.warn("Failed to create built-in experts", { error: result.error.message });
17939
+ logger18.warn("Failed to create built-in experts", { error: result.error.message });
18022
17940
  return { count: 0, ids: [] };
18023
17941
  }
18024
17942
  const registry = getExpertRegistry();
18025
17943
  const registerResult = registry.registerMany(result.value, { replace: true });
18026
17944
  if (!registerResult.ok) {
18027
- logger17.warn("Failed to register built-in experts", { error: registerResult.error.message });
17945
+ logger18.warn("Failed to register built-in experts", { error: registerResult.error.message });
18028
17946
  return { count: 0, ids: [] };
18029
17947
  }
18030
17948
  const ids = result.value.map((e) => e.id);
18031
- logger17.info("Registered built-in experts", { count: result.value.length, ids });
17949
+ logger18.info("Registered built-in experts", { count: result.value.length, ids });
18032
17950
  return { count: result.value.length, ids };
18033
17951
  }
18034
- function createCustomExperts(customDefs, logger17, options) {
17952
+ function createCustomExperts(customDefs, logger18, options) {
18035
17953
  const registry = getExpertRegistry();
18036
17954
  const ids = [];
18037
17955
  for (const [id, def] of Object.entries(customDefs)) {
18038
17956
  if (!def.available) {
18039
- logger17.debug("Skipping unavailable custom expert", { id });
17957
+ logger18.debug("Skipping unavailable custom expert", { id });
18040
17958
  continue;
18041
17959
  }
18042
17960
  const config = convertCustomExpert(id, def);
18043
17961
  const result = ExpertFactory.create(config, options);
18044
17962
  if (!result.ok) {
18045
- logger17.warn("Failed to create custom expert", { id, error: result.error.message });
17963
+ logger18.warn("Failed to create custom expert", { id, error: result.error.message });
18046
17964
  continue;
18047
17965
  }
18048
17966
  const registerResult = registry.register(result.value, { replace: true });
18049
17967
  if (!registerResult.ok) {
18050
- logger17.warn("Failed to register custom expert", { id, error: registerResult.error.message });
17968
+ logger18.warn("Failed to register custom expert", { id, error: registerResult.error.message });
18051
17969
  continue;
18052
17970
  }
18053
17971
  ids.push(id);
18054
17972
  }
18055
17973
  if (ids.length > 0) {
18056
- logger17.info("Registered custom experts", { count: ids.length, ids });
17974
+ logger18.info("Registered custom experts", { count: ids.length, ids });
18057
17975
  }
18058
17976
  return { count: ids.length, ids };
18059
17977
  }
18060
17978
  function initializeExperts(options) {
18061
- const { expertConfig, logger: logger17, modelAdapter } = options;
17979
+ const { expertConfig, logger: logger18, modelAdapter } = options;
18062
17980
  const createOptions = {};
18063
17981
  if (modelAdapter !== void 0) {
18064
17982
  createOptions.adapter = modelAdapter;
@@ -18068,19 +17986,19 @@ function initializeExperts(options) {
18068
17986
  const registeredIds = [];
18069
17987
  const shouldCreateBuiltIn = expertConfig?.builtin !== false;
18070
17988
  if (shouldCreateBuiltIn) {
18071
- const builtInResult = createBuiltInExperts(logger17, createOptions);
17989
+ const builtInResult = createBuiltInExperts(logger18, createOptions);
18072
17990
  builtInCount = builtInResult.count;
18073
17991
  registeredIds.push(...builtInResult.ids);
18074
17992
  } else {
18075
- logger17.info("Built-in experts disabled by configuration");
17993
+ logger18.info("Built-in experts disabled by configuration");
18076
17994
  }
18077
17995
  if (expertConfig?.custom !== void 0 && Object.keys(expertConfig.custom).length > 0) {
18078
- const customResult = createCustomExperts(expertConfig.custom, logger17, createOptions);
17996
+ const customResult = createCustomExperts(expertConfig.custom, logger18, createOptions);
18079
17997
  customCount = customResult.count;
18080
17998
  registeredIds.push(...customResult.ids);
18081
17999
  }
18082
18000
  const totalCount = builtInCount + customCount;
18083
- logger17.info("Expert initialization complete", {
18001
+ logger18.info("Expert initialization complete", {
18084
18002
  builtInCount,
18085
18003
  customCount,
18086
18004
  totalCount,
@@ -18095,33 +18013,33 @@ function initializeExperts(options) {
18095
18013
  }
18096
18014
 
18097
18015
  // src/cli-server-gateway.ts
18098
- async function tryWireGatewayAdapter(logger17) {
18016
+ async function tryWireGatewayAdapter(logger18) {
18099
18017
  const sandboxActive = detectSandbox().active;
18100
18018
  const env2 = readOpenAICompatEnv();
18101
18019
  if (env2 === null) {
18102
- handleMissingEnv(logger17, sandboxActive);
18020
+ handleMissingEnv(logger18, sandboxActive);
18103
18021
  return void 0;
18104
18022
  }
18105
18023
  const result = await buildOpenAICompatAdapters();
18106
18024
  if (result === null) return void 0;
18107
18025
  if (!result.ok) {
18108
- handleProbeFailure(logger17, sandboxActive, result.error.message);
18026
+ handleProbeFailure(logger18, sandboxActive, result.error.message);
18109
18027
  return void 0;
18110
18028
  }
18111
18029
  if (result.value.length === 0) {
18112
- handleZeroModels(logger17, sandboxActive);
18030
+ handleZeroModels(logger18, sandboxActive);
18113
18031
  return void 0;
18114
18032
  }
18115
- logger17.info("OpenAI-compatible gateway wired", {
18033
+ logger18.info("OpenAI-compatible gateway wired", {
18116
18034
  baseUrl: env2.baseUrl,
18117
18035
  modelCount: result.value.length,
18118
18036
  models: result.value.map((a) => a.modelId)
18119
18037
  });
18120
18038
  return result.value[0];
18121
18039
  }
18122
- function handleMissingEnv(logger17, sandboxActive) {
18040
+ function handleMissingEnv(logger18, sandboxActive) {
18123
18041
  if (sandboxActive) {
18124
- logger17.error(
18042
+ logger18.error(
18125
18043
  "Sandbox mode active but NEXUS_OPENAI_COMPAT_URL / NEXUS_OPENAI_COMPAT_KEY are not set. Configure the gateway in your launch env or opencode.json. See docs/guides/SANDBOXED-USAGE.md.",
18126
18044
  new Error("Missing gateway configuration in sandbox mode")
18127
18045
  );
@@ -18129,28 +18047,28 @@ function handleMissingEnv(logger17, sandboxActive) {
18129
18047
  }
18130
18048
  return void 0;
18131
18049
  }
18132
- function handleProbeFailure(logger17, sandboxActive, reason) {
18050
+ function handleProbeFailure(logger18, sandboxActive, reason) {
18133
18051
  if (sandboxActive) {
18134
- logger17.error(
18052
+ logger18.error(
18135
18053
  "Sandbox mode active and OpenAI-compatible gateway probe failed.",
18136
18054
  new Error(reason)
18137
18055
  );
18138
18056
  process.exit(EXIT_CODES.SERVER_START_FAILED);
18139
18057
  }
18140
- logger17.warn("OpenAI-compatible gateway probe failed; continuing with CLI adapters", {
18058
+ logger18.warn("OpenAI-compatible gateway probe failed; continuing with CLI adapters", {
18141
18059
  error: reason
18142
18060
  });
18143
18061
  return void 0;
18144
18062
  }
18145
- function handleZeroModels(logger17, sandboxActive) {
18063
+ function handleZeroModels(logger18, sandboxActive) {
18146
18064
  if (sandboxActive) {
18147
- logger17.error(
18065
+ logger18.error(
18148
18066
  "Sandbox mode active and gateway returned 0 models. Check upstream provider quotas / list filters.",
18149
18067
  new Error("Gateway discovered 0 models")
18150
18068
  );
18151
18069
  process.exit(EXIT_CODES.SERVER_START_FAILED);
18152
18070
  }
18153
- logger17.warn("OpenAI-compatible gateway returned 0 models; ignoring");
18071
+ logger18.warn("OpenAI-compatible gateway returned 0 models; ignoring");
18154
18072
  return void 0;
18155
18073
  }
18156
18074
 
@@ -19007,7 +18925,7 @@ var ALL_STANDARDS_SKILLS = [
19007
18925
  ...CODING_SKILLS,
19008
18926
  ...ARCHITECTURE_SKILLS
19009
18927
  ];
19010
- function registerStandardsSkills(library, logger17) {
18928
+ function registerStandardsSkills(library, logger18) {
19011
18929
  let registered = 0;
19012
18930
  for (const skillDef of ALL_STANDARDS_SKILLS) {
19013
18931
  try {
@@ -19015,10 +18933,10 @@ function registerStandardsSkills(library, logger17) {
19015
18933
  registered++;
19016
18934
  } catch (error) {
19017
18935
  const message = getErrorMessage(error);
19018
- logger17.warn(`Failed to register skill "${skillDef.name}": ${message}`);
18936
+ logger18.warn(`Failed to register skill "${skillDef.name}": ${message}`);
19019
18937
  }
19020
18938
  }
19021
- logger17.info(
18939
+ logger18.info(
19022
18940
  `Registered ${String(registered)}/${String(ALL_STANDARDS_SKILLS.length)} standards skills`,
19023
18941
  {
19024
18942
  domains: {
@@ -19048,7 +18966,7 @@ function adaptConfigToLibrary(config) {
19048
18966
  }
19049
18967
  function createBeliefPromoter() {
19050
18968
  return async (event) => {
19051
- const { getToolMemory } = await import("./tool-memory-K2QPTPKV.js");
18969
+ const { getToolMemory } = await import("./tool-memory-LUXUOE6Q.js");
19052
18970
  const tm = getToolMemory();
19053
18971
  await tm.recordBelief(
19054
18972
  `skill:${event.name}`,
@@ -19059,40 +18977,40 @@ function createBeliefPromoter() {
19059
18977
  };
19060
18978
  }
19061
18979
  async function initializeSkillLibrary(options) {
19062
- const { skillsConfig, logger: logger17 } = options;
18980
+ const { skillsConfig, logger: logger18 } = options;
19063
18981
  if (globalSkillLibrary !== void 0) {
19064
- logger17.debug("Skill library already initialized");
18982
+ logger18.debug("Skill library already initialized");
19065
18983
  return { initialized: true, library: globalSkillLibrary };
19066
18984
  }
19067
18985
  if (skillsConfig?.enabled === false) {
19068
- logger17.info("Skill library disabled by configuration");
18986
+ logger18.info("Skill library disabled by configuration");
19069
18987
  return { initialized: false, reason: "disabled in config" };
19070
18988
  }
19071
18989
  const libraryConfig = skillsConfig !== void 0 ? adaptConfigToLibrary(skillsConfig) : void 0;
19072
- globalSkillLibrary = createSkillLibrary(libraryConfig, logger17);
19073
- registerStandardsSkills(globalSkillLibrary, logger17);
19074
- await loadExternalSkillPacks(skillsConfig, globalSkillLibrary, logger17);
19075
- logger17.info("Skill library initialized", {
18990
+ globalSkillLibrary = createSkillLibrary(libraryConfig, logger18);
18991
+ registerStandardsSkills(globalSkillLibrary, logger18);
18992
+ await loadExternalSkillPacks(skillsConfig, globalSkillLibrary, logger18);
18993
+ logger18.info("Skill library initialized", {
19076
18994
  maxSkills: globalSkillLibrary.getConfig().maxSkills,
19077
18995
  enablePruning: globalSkillLibrary.getConfig().enablePruning,
19078
18996
  trackHistory: globalSkillLibrary.getConfig().trackExecutionHistory
19079
18997
  });
19080
18998
  return { initialized: true, library: globalSkillLibrary };
19081
18999
  }
19082
- async function loadExternalSkillPacks(skillsConfig, library, logger17) {
19000
+ async function loadExternalSkillPacks(skillsConfig, library, logger18) {
19083
19001
  const externalPacks = skillsConfig?.externalPacks;
19084
19002
  if (!externalPacks || externalPacks.length === 0) {
19085
19003
  return;
19086
19004
  }
19087
- logger17.info("Loading external skill packs", { count: externalPacks.length });
19088
- const { loaded, errors } = await loadAllExternalPacks(externalPacks, logger17);
19005
+ logger18.info("Loading external skill packs", { count: externalPacks.length });
19006
+ const { loaded, errors } = await loadAllExternalPacks(externalPacks, logger18);
19089
19007
  for (const packResult of loaded) {
19090
19008
  for (const skill of packResult.skills) {
19091
19009
  library.addSkill(skill);
19092
19010
  }
19093
19011
  }
19094
19012
  if (errors.length > 0) {
19095
- logger17.warn("Some external packs failed to load", {
19013
+ logger18.warn("Some external packs failed to load", {
19096
19014
  failedCount: errors.length,
19097
19015
  failedPacks: errors.map((e) => e.packName)
19098
19016
  });
@@ -19102,19 +19020,19 @@ async function loadExternalSkillPacks(skillsConfig, library, logger17) {
19102
19020
  // src/cli-server-feedback.ts
19103
19021
  var globalFeedbackIntegration;
19104
19022
  function initializeFeedbackIntegration(options) {
19105
- const { logger: logger17, config, router } = options;
19023
+ const { logger: logger18, config, router } = options;
19106
19024
  try {
19107
19025
  globalFeedbackIntegration = createFeedbackIntegration({
19108
19026
  enableAutoFeedback: true,
19109
19027
  // Enable automatic feedback collection
19110
19028
  ...config,
19111
- logger: logger17
19029
+ logger: logger18
19112
19030
  });
19113
19031
  if (router !== void 0 && globalFeedbackIntegration instanceof FeedbackIntegration) {
19114
19032
  globalFeedbackIntegration.registerCompositeRouter(router);
19115
- logger17.debug("FeedbackIntegration attached to CompositeRouter");
19033
+ logger18.debug("FeedbackIntegration attached to CompositeRouter");
19116
19034
  }
19117
- logger17.info("FeedbackIntegration initialized", {
19035
+ logger18.info("FeedbackIntegration initialized", {
19118
19036
  enableAutoFeedback: config?.enableAutoFeedback ?? true,
19119
19037
  hasRouter: router !== void 0
19120
19038
  });
@@ -19125,7 +19043,7 @@ function initializeFeedbackIntegration(options) {
19125
19043
  };
19126
19044
  } catch (error) {
19127
19045
  const message = getErrorMessage(error);
19128
- logger17.warn("FeedbackIntegration initialization failed", { error: message });
19046
+ logger18.warn("FeedbackIntegration initialization failed", { error: message });
19129
19047
  return {
19130
19048
  initialized: false,
19131
19049
  reason: `Initialization failed: ${message}`
@@ -19151,8 +19069,8 @@ function buildAuthConfig(config) {
19151
19069
  tokenFile: configAuth?.tokenFile ?? getDefaultTokenPath()
19152
19070
  };
19153
19071
  }
19154
- function initializeAuth(config, logger17) {
19155
- const log = logger17 ?? createLogger({ component: "auth" });
19072
+ function initializeAuth(config, logger18) {
19073
+ const log = logger18 ?? createLogger({ component: "auth" });
19156
19074
  const authConfig = buildAuthConfig(config);
19157
19075
  const handler = new AuthHandler(authConfig, log);
19158
19076
  const tokenFile = authConfig.tokenFile ?? getDefaultTokenPath();
@@ -19178,9 +19096,9 @@ function initializeAuth(config, logger17) {
19178
19096
 
19179
19097
  // src/cli-server-audit.ts
19180
19098
  var DEFAULT_AUDIT_DIR = nexusDataPath("audit");
19181
- function initializeAuditLogger(securityConfig, logger17) {
19099
+ function initializeAuditLogger(securityConfig, logger18) {
19182
19100
  if (securityConfig?.audit?.enabled !== true) {
19183
- logger17.debug("Audit logging disabled (set security.audit.enabled: true to enable)");
19101
+ logger18.debug("Audit logging disabled (set security.audit.enabled: true to enable)");
19184
19102
  return null;
19185
19103
  }
19186
19104
  const auditConfig = securityConfig.audit;
@@ -19197,20 +19115,20 @@ function initializeAuditLogger(securityConfig, logger17) {
19197
19115
  flushIntervalMs: 1e3
19198
19116
  },
19199
19117
  void 0,
19200
- logger17
19118
+ logger18
19201
19119
  );
19202
19120
  auditLogger.logSystemStartup({ auditLogDir: logDir });
19203
- logger17.info("Audit logging enabled", { logDir });
19121
+ logger18.info("Audit logging enabled", { logDir });
19204
19122
  return auditLogger;
19205
19123
  }
19206
- async function shutdownAuditLogger(auditLogger, logger17) {
19124
+ async function shutdownAuditLogger(auditLogger, logger18) {
19207
19125
  if (auditLogger === null) return;
19208
19126
  try {
19209
19127
  auditLogger.logSystemShutdown();
19210
19128
  await auditLogger.close();
19211
- logger17.info("Audit logger shutdown complete");
19129
+ logger18.info("Audit logger shutdown complete");
19212
19130
  } catch (error) {
19213
- logger17.error(
19131
+ logger18.error(
19214
19132
  "Error shutting down audit logger",
19215
19133
  error instanceof Error ? error : new Error(String(error))
19216
19134
  );
@@ -19224,9 +19142,9 @@ function getRateLimitValues(config) {
19224
19142
  const rl = config?.security?.rateLimit;
19225
19143
  return { enabled: rl?.enabled ?? true, rpm: rl?.requestsPerMinute ?? 60 };
19226
19144
  }
19227
- function createConfiguredPolicyFirewall(logger17, config) {
19145
+ function createConfiguredPolicyFirewall(logger18, config) {
19228
19146
  const policyVals = getPolicyValues(config);
19229
- return createDefaultPolicyFirewall({ mode: policyVals.mode, logger: logger17 });
19147
+ return createDefaultPolicyFirewall({ mode: policyVals.mode, logger: logger18 });
19230
19148
  }
19231
19149
  function getAuthValues(config) {
19232
19150
  const envAuth = process.env["NEXUS_AUTH_ENABLED"];
@@ -19235,12 +19153,12 @@ function getAuthValues(config) {
19235
19153
  const method = configAuth?.method ?? process.env["NEXUS_AUTH_METHOD"] ?? "none";
19236
19154
  return { enabled, method };
19237
19155
  }
19238
- function logSecurityConfig(logger17, config) {
19239
- const policyFirewall = createConfiguredPolicyFirewall(logger17, config);
19156
+ function logSecurityConfig(logger18, config) {
19157
+ const policyFirewall = createConfiguredPolicyFirewall(logger18, config);
19240
19158
  const authVals = getAuthValues(config);
19241
19159
  const policyVals = getPolicyValues(config);
19242
19160
  const rateLimitVals = getRateLimitValues(config);
19243
- logger17.info("Security configuration", {
19161
+ logger18.info("Security configuration", {
19244
19162
  policyMode: policyVals.mode,
19245
19163
  defaultExecutionMode: policyVals.defaultExec,
19246
19164
  policyRuleCount: policyFirewall.getRules().length,
@@ -19251,32 +19169,32 @@ function logSecurityConfig(logger17, config) {
19251
19169
  allowedPaths: config?.security?.allowedPaths ?? ["./"]
19252
19170
  });
19253
19171
  if (!authVals.enabled) {
19254
- logger17.warn(
19172
+ logger18.warn(
19255
19173
  "Authentication explicitly disabled \u2014 network-exposed endpoints are unprotected. Remove NEXUS_AUTH_ENABLED=false to re-enable."
19256
19174
  );
19257
19175
  }
19258
- logger17.debug("Policy firewall rules", {
19176
+ logger18.debug("Policy firewall rules", {
19259
19177
  rules: policyFirewall.getRules().map((r) => ({ name: r.name, description: r.description }))
19260
19178
  });
19261
19179
  return policyFirewall;
19262
19180
  }
19263
19181
 
19264
19182
  // src/cli-server.ts
19265
- function setupShutdownHandlers(cleanup, logger17) {
19183
+ function setupShutdownHandlers(cleanup, logger18) {
19266
19184
  let isShuttingDown = false;
19267
19185
  const handleShutdown = async (signal) => {
19268
19186
  if (isShuttingDown) {
19269
- logger17.debug("Shutdown already in progress, ignoring signal", { signal });
19187
+ logger18.debug("Shutdown already in progress, ignoring signal", { signal });
19270
19188
  return;
19271
19189
  }
19272
19190
  isShuttingDown = true;
19273
- logger17.info("Received shutdown signal", { signal });
19191
+ logger18.info("Received shutdown signal", { signal });
19274
19192
  try {
19275
19193
  await cleanup();
19276
- logger17.info("Shutdown complete");
19194
+ logger18.info("Shutdown complete");
19277
19195
  process.exit(EXIT_CODES.SUCCESS);
19278
19196
  } catch (error) {
19279
- logger17.error(
19197
+ logger18.error(
19280
19198
  "Error during shutdown",
19281
19199
  error instanceof Error ? error : new Error(String(error))
19282
19200
  );
@@ -19285,24 +19203,24 @@ function setupShutdownHandlers(cleanup, logger17) {
19285
19203
  };
19286
19204
  const onSignal = (signal) => () => {
19287
19205
  handleShutdown(signal).catch((err2) => {
19288
- logger17.error("Shutdown handler crashed", err2 instanceof Error ? err2 : new Error(String(err2)));
19206
+ logger18.error("Shutdown handler crashed", err2 instanceof Error ? err2 : new Error(String(err2)));
19289
19207
  process.exit(EXIT_CODES.SHUTDOWN_ERROR);
19290
19208
  });
19291
19209
  };
19292
19210
  process.on("SIGINT", onSignal("SIGINT"));
19293
19211
  process.on("SIGTERM", onSignal("SIGTERM"));
19294
19212
  process.on("uncaughtException", (error) => {
19295
- logger17.error("Uncaught exception", error);
19213
+ logger18.error("Uncaught exception", error);
19296
19214
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19297
19215
  });
19298
19216
  process.on("unhandledRejection", (reason) => {
19299
19217
  const error = reason instanceof Error ? reason : new Error(String(reason));
19300
- logger17.error("Unhandled rejection", error);
19218
+ logger18.error("Unhandled rejection", error);
19301
19219
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19302
19220
  });
19303
19221
  }
19304
- function logStartupInfo(logger17, detectionResult, verbose) {
19305
- logger17.info("Starting Nexus Agents", {
19222
+ function logStartupInfo(logger18, detectionResult, verbose) {
19223
+ logger18.info("Starting Nexus Agents", {
19306
19224
  version: VERSION,
19307
19225
  mode: detectionResult.mode,
19308
19226
  modeSource: detectionResult.source,
@@ -19312,7 +19230,7 @@ function logStartupInfo(logger17, detectionResult, verbose) {
19312
19230
  platform: process.platform
19313
19231
  });
19314
19232
  if (verbose) {
19315
- logger17.debug("Mode detection signals", {
19233
+ logger18.debug("Mode detection signals", {
19316
19234
  stdinIsTty: detectionResult.signals.stdinIsTty,
19317
19235
  stdoutIsTty: detectionResult.signals.stdoutIsTty,
19318
19236
  mcpClientName: detectionResult.signals.mcpClientName,
@@ -19322,20 +19240,20 @@ function logStartupInfo(logger17, detectionResult, verbose) {
19322
19240
  });
19323
19241
  }
19324
19242
  }
19325
- function validateModeOrExit(logger17, mode) {
19243
+ function validateModeOrExit(logger18, mode) {
19326
19244
  if (mode === "mesh") {
19327
- logger17.error("Mesh mode is not yet implemented. Use --mode=server or --mode=orchestrator.");
19245
+ logger18.error("Mesh mode is not yet implemented. Use --mode=server or --mode=orchestrator.");
19328
19246
  process.exit(EXIT_CODES.INVALID_ARGS);
19329
19247
  }
19330
19248
  }
19331
- function loadAndLogConfig(logger17) {
19332
- const result = loadConfig({ logger: logger17 });
19249
+ function loadAndLogConfig(logger18) {
19250
+ const result = loadConfig({ logger: logger18 });
19333
19251
  if (!result.ok) {
19334
- logger17.error("Failed to load configuration", new Error(result.error.message));
19252
+ logger18.error("Failed to load configuration", new Error(result.error.message));
19335
19253
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19336
19254
  }
19337
19255
  const configResult = result.value;
19338
- logger17.info("Configuration loaded", {
19256
+ logger18.info("Configuration loaded", {
19339
19257
  configPath: configResult.configPath ?? "(defaults)",
19340
19258
  usingDefaults: configResult.usingDefaults,
19341
19259
  warningCount: configResult.warnings.length,
@@ -19344,20 +19262,20 @@ function loadAndLogConfig(logger17) {
19344
19262
  hasSecurity: configResult.config.security !== void 0
19345
19263
  });
19346
19264
  for (const warning of configResult.warnings) {
19347
- logger17.warn(warning);
19265
+ logger18.warn(warning);
19348
19266
  }
19349
19267
  return configResult;
19350
19268
  }
19351
19269
  function createShutdownCleanup(options) {
19352
- const { eventBusBridge, observer, eventContext, server, serverLogger, logger: logger17, auditLogger } = options;
19270
+ const { eventBusBridge, observer, eventContext, server, serverLogger, logger: logger18, auditLogger } = options;
19353
19271
  return async () => {
19354
- await shutdownAuditLogger(auditLogger, logger17);
19272
+ await shutdownAuditLogger(auditLogger, logger18);
19355
19273
  if (eventBusBridge.initialized) {
19356
- logFinalEventBusStats(logger17);
19274
+ logFinalEventBusStats(logger18);
19357
19275
  eventBusBridge.cleanup();
19358
19276
  }
19359
19277
  recordServerShutdown(observer, eventContext);
19360
- logFinalHealthMetrics(observer, logger17);
19278
+ logFinalHealthMetrics(observer, logger18);
19361
19279
  shutdownToolMemory();
19362
19280
  const closeResult = await closeServer(server, serverLogger);
19363
19281
  if (!closeResult.ok) {
@@ -19365,61 +19283,61 @@ function createShutdownCleanup(options) {
19365
19283
  }
19366
19284
  };
19367
19285
  }
19368
- function createAndValidateMcpServer(logger17) {
19286
+ function createAndValidateMcpServer(logger18) {
19369
19287
  const serverResult = createServer({
19370
19288
  name: "nexus-agents",
19371
19289
  version: VERSION,
19372
- logger: logger17
19290
+ logger: logger18
19373
19291
  });
19374
19292
  if (!serverResult.ok) {
19375
- logger17.error("Failed to create MCP server", new Error(serverResult.error.message));
19293
+ logger18.error("Failed to create MCP server", new Error(serverResult.error.message));
19376
19294
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19377
19295
  }
19378
19296
  return serverResult.value;
19379
19297
  }
19380
- async function initializeAndLogSandbox(logger17, sandboxConfig) {
19298
+ async function initializeAndLogSandbox(logger18, sandboxConfig) {
19381
19299
  const sandboxResult = await initializeSandbox(sandboxConfig);
19382
- logger17.info("Sandbox initialized", {
19300
+ logger18.info("Sandbox initialized", {
19383
19301
  mode: getSandboxMode(),
19384
19302
  executor: sandboxResult.executor.name,
19385
19303
  usedFallback: sandboxResult.usedFallback,
19386
19304
  configuredMode: sandboxConfig?.mode ?? "default"
19387
19305
  });
19388
19306
  }
19389
- async function connectToStdioTransport(server, logger17, serverLogger) {
19390
- logger17.setDestination?.("stderr");
19307
+ async function connectToStdioTransport(server, logger18, serverLogger) {
19308
+ logger18.setDestination?.("stderr");
19391
19309
  serverLogger.setDestination?.("stderr");
19392
- logger17.info("Connecting to stdio transport");
19310
+ logger18.info("Connecting to stdio transport");
19393
19311
  const transport = new StdioServerTransport();
19394
19312
  const connectResult = await connectTransport(server, transport, serverLogger);
19395
19313
  if (!connectResult.ok) {
19396
- logger17.error("Failed to connect MCP server", new Error(connectResult.error.message));
19314
+ logger18.error("Failed to connect MCP server", new Error(connectResult.error.message));
19397
19315
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19398
19316
  }
19399
- logger17.info("MCP server started successfully");
19317
+ logger18.info("MCP server started successfully");
19400
19318
  }
19401
- function createAdapterRegistry(logger17) {
19319
+ function createAdapterRegistry(logger18) {
19402
19320
  return createUnifiedRegistry({
19403
- logger: logger17,
19321
+ logger: logger18,
19404
19322
  defaultCliTimeoutMs: MCP_TIMEOUTS.perTool["orchestrate"] ?? MCP_TIMEOUTS.defaultMs
19405
19323
  });
19406
19324
  }
19407
- function buildGatewayConfig(config, logger17) {
19325
+ function buildGatewayConfig(config, logger18) {
19408
19326
  const gatewaySection = config.gateway;
19409
19327
  const enabled = gatewaySection?.enabled !== false;
19410
19328
  const tierOverrides = parseTierOverrides(gatewaySection?.tierOverrides);
19411
19329
  return {
19412
19330
  enabled,
19413
- logger: logger17,
19331
+ logger: logger18,
19414
19332
  ...tierOverrides !== void 0 && { tierOverrides }
19415
19333
  };
19416
19334
  }
19417
- async function initializeAndRegisterTools(server, logger17, policyFirewall, config, feedbackIntegration) {
19418
- logger17.info("Loading built-in workflow templates");
19335
+ async function initializeAndRegisterTools(server, logger18, policyFirewall, config, feedbackIntegration) {
19336
+ logger18.info("Loading built-in workflow templates");
19419
19337
  const builtInTemplates = await initializeBuiltInTemplates();
19420
- logger17.info("Loaded built-in templates", { count: builtInTemplates.size });
19421
- const adapterRegistry = createAdapterRegistry(logger17);
19422
- const gatewayAdapter = await tryWireGatewayAdapter(logger17);
19338
+ logger18.info("Loaded built-in templates", { count: builtInTemplates.size });
19339
+ const adapterRegistry = createAdapterRegistry(logger18);
19340
+ const gatewayAdapter = await tryWireGatewayAdapter(logger18);
19423
19341
  const modelAdapter = gatewayAdapter ?? adapterRegistry.getDefault();
19424
19342
  const policyVals = getPolicyValues(config);
19425
19343
  const allowedPaths = config.security?.allowedPaths;
@@ -19427,13 +19345,13 @@ async function initializeAndRegisterTools(server, logger17, policyFirewall, conf
19427
19345
  const workflowConfig = config.workflows;
19428
19346
  const toolsOptions = {
19429
19347
  server,
19430
- logger: logger17,
19348
+ logger: logger18,
19431
19349
  builtInTemplates,
19432
19350
  policyFirewall,
19433
19351
  executionMode: policyVals.defaultExec,
19434
19352
  modelAdapter,
19435
19353
  // Gateway middleware for tier-aware dispatch logging (Issue #896, #897)
19436
- gatewayConfig: buildGatewayConfig(config, logger17),
19354
+ gatewayConfig: buildGatewayConfig(config, logger18),
19437
19355
  ...allowedPaths !== void 0 && { allowedPaths },
19438
19356
  ...securityConfig !== void 0 && { securityConfig },
19439
19357
  ...workflowConfig !== void 0 && { workflowConfig },
@@ -19441,45 +19359,45 @@ async function initializeAndRegisterTools(server, logger17, policyFirewall, conf
19441
19359
  };
19442
19360
  registerMcpTools(toolsOptions);
19443
19361
  }
19444
- function applyLoggingConfig(logger17, verbose, config) {
19362
+ function applyLoggingConfig(logger18, verbose, config) {
19445
19363
  if (!verbose && config.logging?.level !== void 0) {
19446
- logger17.setLevel(config.logging.level);
19447
- logger17.debug("Log level set from configuration", { level: config.logging.level });
19364
+ logger18.setLevel(config.logging.level);
19365
+ logger18.debug("Log level set from configuration", { level: config.logging.level });
19448
19366
  }
19449
- if (config.logging?.format !== void 0 && logger17.setFormat !== void 0) {
19450
- logger17.setFormat(config.logging.format);
19451
- logger17.debug("Log format set from configuration", { format: config.logging.format });
19367
+ if (config.logging?.format !== void 0 && logger18.setFormat !== void 0) {
19368
+ logger18.setFormat(config.logging.format);
19369
+ logger18.debug("Log format set from configuration", { format: config.logging.format });
19452
19370
  }
19453
- if (config.logging?.destination !== void 0 && logger17.setDestination !== void 0) {
19454
- logger17.setDestination(config.logging.destination, config.logging.filePath);
19455
- logger17.debug("Log destination set from configuration", {
19371
+ if (config.logging?.destination !== void 0 && logger18.setDestination !== void 0) {
19372
+ logger18.setDestination(config.logging.destination, config.logging.filePath);
19373
+ logger18.debug("Log destination set from configuration", {
19456
19374
  destination: config.logging.destination,
19457
19375
  filePath: config.logging.filePath
19458
19376
  });
19459
19377
  }
19460
19378
  }
19461
- async function initializeSubsystems(config, logger17) {
19462
- const expertResult = initializeExperts({ expertConfig: config.experts, logger: logger17 });
19463
- logger17.debug("Expert system initialized", {
19379
+ async function initializeSubsystems(config, logger18) {
19380
+ const expertResult = initializeExperts({ expertConfig: config.experts, logger: logger18 });
19381
+ logger18.debug("Expert system initialized", {
19464
19382
  builtIn: expertResult.builtInCount,
19465
19383
  custom: expertResult.customCount
19466
19384
  });
19467
- const skillsResult = await initializeSkillLibrary({ skillsConfig: config.skills, logger: logger17 });
19468
- logger17.debug("Skill library initialization", {
19385
+ const skillsResult = await initializeSkillLibrary({ skillsConfig: config.skills, logger: logger18 });
19386
+ logger18.debug("Skill library initialization", {
19469
19387
  initialized: skillsResult.initialized,
19470
19388
  reason: skillsResult.reason
19471
19389
  });
19472
- const sicaResult = initializeSica({ sicaConfig: config.sica, logger: logger17 });
19473
- logger17.debug("SICA initialization", {
19390
+ const sicaResult = initializeSica({ sicaConfig: config.sica, logger: logger18 });
19391
+ logger18.debug("SICA initialization", {
19474
19392
  enabled: sicaResult.enabled,
19475
19393
  reason: sicaResult.reason
19476
19394
  });
19477
- const feedbackResult = initializeFeedbackIntegration({ logger: logger17 });
19478
- logger17.debug("FeedbackIntegration initialization", {
19395
+ const feedbackResult = initializeFeedbackIntegration({ logger: logger18 });
19396
+ logger18.debug("FeedbackIntegration initialization", {
19479
19397
  initialized: feedbackResult.initialized,
19480
19398
  reason: feedbackResult.reason
19481
19399
  });
19482
- const { server, logger: serverLogger } = createAndValidateMcpServer(logger17);
19400
+ const { server, logger: serverLogger } = createAndValidateMcpServer(logger18);
19483
19401
  const observer = initializeSwarmObserver(serverLogger, {
19484
19402
  maxEvents: config.observability?.swarmObserverMaxEvents
19485
19403
  });
@@ -19499,32 +19417,32 @@ async function initializeSubsystems(config, logger17) {
19499
19417
  }
19500
19418
  var SERVER_STARTUP_TIMEOUT_MS = 3e4;
19501
19419
  async function startServer(verbose, mode, modeWasExplicit = false, orchestratorOptions) {
19502
- const logger17 = createLogger({ component: "cli" });
19503
- if (verbose) logger17.setLevel("debug");
19504
- validateModeOrExit(logger17, mode);
19420
+ const logger18 = createLogger({ component: "cli" });
19421
+ if (verbose) logger18.setLevel("debug");
19422
+ validateModeOrExit(logger18, mode);
19505
19423
  if (mode === "orchestrator") {
19506
19424
  await startOrchestratorMode(orchestratorOptions ?? { verbose });
19507
19425
  return;
19508
19426
  }
19509
19427
  const startupWatchdog = setTimeout(() => {
19510
- logger17.error(
19428
+ logger18.error(
19511
19429
  `Server startup exceeded ${String(SERVER_STARTUP_TIMEOUT_MS)}ms \u2014 aborting. Common causes: hung config load, blocked subsystem init, stdio transport stall.`
19512
19430
  );
19513
19431
  process.exit(EXIT_CODES.SERVER_START_FAILED);
19514
19432
  }, SERVER_STARTUP_TIMEOUT_MS);
19515
19433
  startupWatchdog.unref();
19516
19434
  const detectionResult = detectMode({ explicitMode: modeWasExplicit ? mode : void 0 });
19517
- logStartupInfo(logger17, detectionResult, verbose);
19518
- const configResult = loadAndLogConfig(logger17);
19519
- applyLoggingConfig(logger17, verbose, configResult.config);
19520
- validateNexusEnv(logger17);
19521
- const { server, serverLogger, observer, eventBusBridge, auditLogger } = await initializeSubsystems(configResult.config, logger17);
19522
- await connectToStdioTransport(server, logger17, serverLogger);
19435
+ logStartupInfo(logger18, detectionResult, verbose);
19436
+ const configResult = loadAndLogConfig(logger18);
19437
+ applyLoggingConfig(logger18, verbose, configResult.config);
19438
+ validateNexusEnv(logger18);
19439
+ const { server, serverLogger, observer, eventBusBridge, auditLogger } = await initializeSubsystems(configResult.config, logger18);
19440
+ await connectToStdioTransport(server, logger18, serverLogger);
19523
19441
  const eventContext = recordServerStartup(observer);
19524
19442
  const stdinMonitor = getStdinLifecycleMonitor();
19525
19443
  stdinMonitor.start();
19526
19444
  stdinMonitor.onClose(() => {
19527
- logger17.warn("Parent process closed stdin, shutting down");
19445
+ logger18.warn("Parent process closed stdin, shutting down");
19528
19446
  process.exit(0);
19529
19447
  });
19530
19448
  const cleanup = createShutdownCleanup({
@@ -19533,12 +19451,12 @@ async function startServer(verbose, mode, modeWasExplicit = false, orchestratorO
19533
19451
  eventContext,
19534
19452
  server,
19535
19453
  serverLogger,
19536
- logger: logger17,
19454
+ logger: logger18,
19537
19455
  auditLogger
19538
19456
  });
19539
- setupShutdownHandlers(cleanup, logger17);
19457
+ setupShutdownHandlers(cleanup, logger18);
19540
19458
  clearTimeout(startupWatchdog);
19541
- logger17.debug("Server running, waiting for requests...");
19459
+ logger18.debug("Server running, waiting for requests...");
19542
19460
  }
19543
19461
 
19544
19462
  // src/cli-commands-validators.ts
@@ -19792,8 +19710,8 @@ function printFirstRunHint() {
19792
19710
  const isTTY = process.stderr.isTTY;
19793
19711
  if (!isTTY) return;
19794
19712
  const dataDir = getNexusDataDir();
19795
- const hasConfig = existsSync21("./nexus-agents.yaml") || existsSync21("./nexus-agents.yml");
19796
- if (existsSync21(dataDir) || hasConfig) return;
19713
+ const hasConfig = existsSync20("./.nexus-agents/nexus-agents.yaml") || existsSync20("./.nexus-agents/nexus-agents.yml") || existsSync20("./nexus-agents.yaml") || existsSync20("./nexus-agents.yml");
19714
+ if (existsSync20(dataDir) || hasConfig) return;
19797
19715
  process.stderr.write(
19798
19716
  "\n\x1B[36mnexus-agents\x1B[0m: First time? Run \x1B[1mnexus-agents setup\x1B[0m to configure.\n\n"
19799
19717
  );
@@ -19908,7 +19826,7 @@ async function handleResearchCommand(args) {
19908
19826
  }
19909
19827
  }
19910
19828
  async function handleRegistryCommand(args) {
19911
- const { registryCommand, isValidRegistrySubcommand, formatRegistryUsage } = await import("./registry-command-6KJWW3W7.js");
19829
+ const { registryCommand, isValidRegistrySubcommand, formatRegistryUsage } = await import("./registry-command-YMZPSW7S.js");
19912
19830
  const subcommand = args.subcommand;
19913
19831
  if (!isValidRegistrySubcommand(subcommand)) {
19914
19832
  process.stdout.write(`${formatRegistryUsage()}
@@ -19956,7 +19874,7 @@ async function handleVerifyCommand(args) {
19956
19874
  async function handleDoctorCommand(args) {
19957
19875
  const exitCode = await doctorCommand({ fix: args.options.fix });
19958
19876
  if (args.options.deep) {
19959
- const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-XBPRQ6ZP.js");
19877
+ const { runDeepDiagnostics: runDeepDiagnostics2, formatDeepDiagnostics: formatDeepDiagnostics2 } = await import("./doctor-deep-ZMBSG2DF.js");
19960
19878
  const diag = runDeepDiagnostics2();
19961
19879
  process.stdout.write(formatDeepDiagnostics2(diag) + "\n");
19962
19880
  }
@@ -20000,7 +19918,7 @@ async function handleInitCommand(args) {
20000
19918
  process.exit(result.success ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
20001
19919
  }
20002
19920
  async function runInitOpencodeFlow(args) {
20003
- const { runInitOpencode } = await import("./init-opencode-RV6IQEMS.js");
19921
+ const { runInitOpencode } = await import("./init-opencode-WFL4OXMB.js");
20004
19922
  const opencodePath = args.options.opencode;
20005
19923
  if (opencodePath === void 0 || opencodePath === "") {
20006
19924
  process.stderr.write("Error: --opencode requires a path argument.\n");
@@ -20027,7 +19945,7 @@ async function runInitOpencodeFlow(args) {
20027
19945
  process.exit(EXIT_CODES.SUCCESS);
20028
19946
  }
20029
19947
  async function renderOpencodeValidate(opencodePath) {
20030
- const { runOpencodeValidate } = await import("./init-opencode-RV6IQEMS.js");
19948
+ const { runOpencodeValidate } = await import("./init-opencode-WFL4OXMB.js");
20031
19949
  const result = await runOpencodeValidate(opencodePath);
20032
19950
  if (!result.ok) {
20033
19951
  process.stderr.write(`init --opencode --validate: ${result.reason ?? "failed"}
@@ -20067,7 +19985,7 @@ async function handleSetupCommandAsync(args) {
20067
19985
  process.exit(exitCode === 0 ? EXIT_CODES.SUCCESS : EXIT_CODES.SERVER_START_FAILED);
20068
19986
  }
20069
19987
  async function runCustomApiSetup(args) {
20070
- const { configureCustomApi } = await import("./setup-custom-api-PJ6TGHJH.js");
19988
+ const { configureCustomApi } = await import("./setup-custom-api-4EYRKCHB.js");
20071
19989
  const baseUrl = args.options.customApi;
20072
19990
  if (baseUrl === void 0) return EXIT_CODES.SERVER_START_FAILED;
20073
19991
  const input = {
@@ -20964,7 +20882,7 @@ function handleCapabilitiesCommand(args) {
20964
20882
  }
20965
20883
 
20966
20884
  // src/testing/memory-benchmark-phase3.ts
20967
- async function measurePromotionEffectiveness(backend, logger17) {
20885
+ async function measurePromotionEffectiveness(backend, logger18) {
20968
20886
  const promotedEntries = [];
20969
20887
  const metadata = { importance: "high", tags: ["promoted", "benchmark"] };
20970
20888
  for (let i = 0; i < 10; i++) {
@@ -20984,7 +20902,7 @@ async function measurePromotionEffectiveness(backend, logger17) {
20984
20902
  if (result.ok) retained++;
20985
20903
  }
20986
20904
  const retentionRate = promotedEntries.length > 0 ? retained / promotedEntries.length : 1;
20987
- logger17?.debug("Promotion effectiveness measured", {
20905
+ logger18?.debug("Promotion effectiveness measured", {
20988
20906
  promoted: promotedEntries.length,
20989
20907
  retained,
20990
20908
  retentionRate
@@ -21010,7 +20928,7 @@ async function countDecayed(backend, keys) {
21010
20928
  }
21011
20929
  return decayed;
21012
20930
  }
21013
- async function measureDecayAppropriateness(backend, logger17) {
20931
+ async function measureDecayAppropriateness(backend, logger18) {
21014
20932
  const lowKeys = await storeTestEntries(backend, "low", 5);
21015
20933
  const highKeys = await storeTestEntries(backend, "high", 5);
21016
20934
  const cutoffDate = new Date(Date.now() + 1e3);
@@ -21019,7 +20937,7 @@ async function measureDecayAppropriateness(backend, logger17) {
21019
20937
  const lowDecayed = await countDecayed(backend, lowKeys);
21020
20938
  const totalDecayed = highDecayed + lowDecayed;
21021
20939
  const regret = totalDecayed > 0 ? highDecayed / totalDecayed : 0;
21022
- logger17?.debug("Decay appropriateness measured", {
20940
+ logger18?.debug("Decay appropriateness measured", {
21023
20941
  highImportanceDecayed: highDecayed,
21024
20942
  lowImportanceDecayed: lowDecayed,
21025
20943
  regretScore: regret
@@ -21215,13 +21133,13 @@ function averageMetrics(acc, kValues, numCases) {
21215
21133
  }
21216
21134
  return { recallAtK, precisionAtK, mrr: acc.mrrSum / numCases };
21217
21135
  }
21218
- async function measureRetrievalQuality(backend, testCases, kValues, logger17) {
21136
+ async function measureRetrievalQuality(backend, testCases, kValues, logger18) {
21219
21137
  const acc = createAccumulators(kValues);
21220
21138
  const maxK = Math.max(...kValues);
21221
21139
  for (const testCase of testCases) {
21222
21140
  const searchResult = await backend.search(testCase.query, maxK);
21223
21141
  if (!searchResult.ok) {
21224
- logger17.warn("Search failed during benchmark", { query: testCase.query });
21142
+ logger18.warn("Search failed during benchmark", { query: testCase.query });
21225
21143
  continue;
21226
21144
  }
21227
21145
  const retrievedKeys = searchResult.value.map((e) => e.key);
@@ -21275,21 +21193,21 @@ async function measureSelfConsistency(backend) {
21275
21193
  }
21276
21194
  return buildCoherenceResult(validCount, allEntries.value.length);
21277
21195
  }
21278
- async function validateCrossRefs(refs, targetBackend, logger17) {
21196
+ async function validateCrossRefs(refs, targetBackend, logger18) {
21279
21197
  let validCount = 0;
21280
21198
  for (const ref of refs) {
21281
21199
  const result = await targetBackend.retrieve(ref.targetKey);
21282
21200
  if (result.ok) validCount++;
21283
- else logger17?.debug("Orphaned reference", { source: ref.sourceKey, target: ref.targetKey });
21201
+ else logger18?.debug("Orphaned reference", { source: ref.sourceKey, target: ref.targetKey });
21284
21202
  }
21285
21203
  return buildCoherenceResult(validCount, refs.length);
21286
21204
  }
21287
- async function measureCoherence(backend, config, logger17) {
21205
+ async function measureCoherence(backend, config, logger18) {
21288
21206
  const refs = config?.crossReferences ?? [];
21289
21207
  if (refs.length === 0) return measureSelfConsistency(backend);
21290
- return validateCrossRefs(refs, config?.targetBackend ?? backend, logger17);
21208
+ return validateCrossRefs(refs, config?.targetBackend ?? backend, logger18);
21291
21209
  }
21292
- async function measureGrowthRate(backend, operationCount = 50, logger17) {
21210
+ async function measureGrowthRate(backend, operationCount = 50, logger18) {
21293
21211
  const initialEntries = await backend.search("", 1e4);
21294
21212
  let initialBytes = 0;
21295
21213
  if (initialEntries.ok) {
@@ -21307,13 +21225,13 @@ async function measureGrowthRate(backend, operationCount = 50, logger17) {
21307
21225
  finalBytes = finalEntries.value.reduce((sum, e) => sum + estimateStorageBytes(e), 0);
21308
21226
  }
21309
21227
  const bytesPerOp = operationCount > 0 ? (finalBytes - initialBytes) / operationCount : 0;
21310
- logger17?.debug("Growth rate measured", { initialBytes, finalBytes, bytesPerOp });
21228
+ logger18?.debug("Growth rate measured", { initialBytes, finalBytes, bytesPerOp });
21311
21229
  return { bytesPerOperation: bytesPerOp, operationsExecuted: operationCount };
21312
21230
  }
21313
- async function measureDecayConsistency(backend, logger17) {
21231
+ async function measureDecayConsistency(backend, logger18) {
21314
21232
  const beforePrune = await backend.search("", 1e4);
21315
21233
  if (!beforePrune.ok) {
21316
- logger17?.debug("Cannot measure decay consistency - search failed");
21234
+ logger18?.debug("Cannot measure decay consistency - search failed");
21317
21235
  return { consistencyScore: 1, itemsChecked: 0 };
21318
21236
  }
21319
21237
  const beforeCount = beforePrune.value.length;
@@ -21328,7 +21246,7 @@ async function measureDecayConsistency(backend, logger17) {
21328
21246
  if (result.ok) retrievable++;
21329
21247
  }
21330
21248
  const score = sampleSize > 0 ? retrievable / sampleSize : 1;
21331
- logger17?.debug("Decay consistency measured", { sampleSize, retrievable, score });
21249
+ logger18?.debug("Decay consistency measured", { sampleSize, retrievable, score });
21332
21250
  return { consistencyScore: score, itemsChecked: sampleSize };
21333
21251
  }
21334
21252
  function buildBenchmarkResult(m) {
@@ -21354,20 +21272,20 @@ function buildBenchmarkResult(m) {
21354
21272
  };
21355
21273
  }
21356
21274
  async function runMemoryBenchmark(backend, testCases, config) {
21357
- const { logger: logger17, kValues, iterations } = parseConfig(config);
21275
+ const { logger: logger18, kValues, iterations } = parseConfig(config);
21358
21276
  const startTime = getTimeProvider().now();
21359
- logger17.info("Starting memory benchmark", { testCases: testCases.length, iterations });
21360
- const quality = await measureRetrievalQuality(backend, testCases, kValues, logger17);
21277
+ logger18.info("Starting memory benchmark", { testCases: testCases.length, iterations });
21278
+ const quality = await measureRetrievalQuality(backend, testCases, kValues, logger18);
21361
21279
  const latency = await measureLatency(backend, iterations);
21362
21280
  const storage = await measureStorage(backend);
21363
- const coherence = await measureCoherence(backend, config?.coherenceConfig, logger17);
21281
+ const coherence = await measureCoherence(backend, config?.coherenceConfig, logger18);
21364
21282
  const growthIterations = config?.quickMode === true ? 10 : 50;
21365
- const growth = await measureGrowthRate(backend, growthIterations, logger17);
21366
- const decay = await measureDecayConsistency(backend, logger17);
21367
- const promotion = await measurePromotionEffectiveness(backend, logger17);
21368
- const appropriateness = await measureDecayAppropriateness(backend, logger17);
21283
+ const growth = await measureGrowthRate(backend, growthIterations, logger18);
21284
+ const decay = await measureDecayConsistency(backend, logger18);
21285
+ const promotion = await measurePromotionEffectiveness(backend, logger18);
21286
+ const appropriateness = await measureDecayAppropriateness(backend, logger18);
21369
21287
  const durationMs = getTimeProvider().now() - startTime;
21370
- logger17.info("Memory benchmark complete", { mrr: quality.mrr, durationMs });
21288
+ logger18.info("Memory benchmark complete", { mrr: quality.mrr, durationMs });
21371
21289
  return buildBenchmarkResult({
21372
21290
  quality,
21373
21291
  latency,
@@ -21561,8 +21479,8 @@ function determineStrategy(cliTools, adapters) {
21561
21479
  return "none (no adapters available)";
21562
21480
  }
21563
21481
  function collectStatus() {
21564
- const logger17 = createLogger({ component: "status", level: "error" });
21565
- const calculator = createFitnessScoreCalculator(logger17);
21482
+ const logger18 = createLogger({ component: "status", level: "error" });
21483
+ const calculator = createFitnessScoreCalculator(logger18);
21566
21484
  const audit = calculator.audit(VERSION);
21567
21485
  const adapters = checkApiAdapters();
21568
21486
  const cliTools = detectCliTools();
@@ -21626,7 +21544,7 @@ function handleStatusCommand2(args) {
21626
21544
 
21627
21545
  // src/cli/scenario-command.ts
21628
21546
  import { readdir as readdir4 } from "fs/promises";
21629
- import { join as join18, resolve as resolve14 } from "path";
21547
+ import { join as join17, resolve as resolve13 } from "path";
21630
21548
 
21631
21549
  // src/testing/e2e/scenario-runner.ts
21632
21550
  import { readFile as readFile7 } from "fs/promises";
@@ -21786,7 +21704,7 @@ function checkCircularDependencies(workflow) {
21786
21704
  var defaultStubFactory = {
21787
21705
  createAgentStub(agentType, action) {
21788
21706
  return async (inputs) => {
21789
- await new Promise((resolve15) => setTimeout(resolve15, 10));
21707
+ await new Promise((resolve14) => setTimeout(resolve14, 10));
21790
21708
  return {
21791
21709
  stepId: `${agentType}-${action}`,
21792
21710
  status: "success",
@@ -21945,7 +21863,7 @@ function createScenarioRunner(stubFactory) {
21945
21863
  }
21946
21864
 
21947
21865
  // src/cli/scenario-command.ts
21948
- var FIXTURES_DIR = resolve14(import.meta.dirname, "../testing/e2e/fixtures");
21866
+ var FIXTURES_DIR = resolve13(import.meta.dirname, "../testing/e2e/fixtures");
21949
21867
  var SCENARIO_SUFFIX = ".scenario.yaml";
21950
21868
  async function listScenarios() {
21951
21869
  try {
@@ -21996,7 +21914,7 @@ async function handleRun(args) {
21996
21914
  process.exit(EXIT_CODES.SERVER_START_FAILED);
21997
21915
  }
21998
21916
  const runner = createScenarioRunner();
21999
- const fixturePath = join18(FIXTURES_DIR, `${name}${SCENARIO_SUFFIX}`);
21917
+ const fixturePath = join17(FIXTURES_DIR, `${name}${SCENARIO_SUFFIX}`);
22000
21918
  try {
22001
21919
  const fixture = await runner.loadFixture(fixturePath);
22002
21920
  const result = await runner.run(fixture);
@@ -22386,6 +22304,137 @@ function printSignal(signal) {
22386
22304
  console.log("");
22387
22305
  }
22388
22306
 
22307
+ // src/cli/migrate-command.ts
22308
+ import { cpSync, existsSync as existsSync22, mkdirSync as mkdirSync6, readdirSync as readdirSync3 } from "fs";
22309
+ import { homedir } from "os";
22310
+ import { join as join18 } from "path";
22311
+ var logger17 = createLogger({ component: "migrate-command" });
22312
+ var HOMEDIR_DEFAULT_BASE = join18(homedir(), ".nexus-agents");
22313
+ function countItems(dir) {
22314
+ if (!existsSync22(dir)) return 0;
22315
+ try {
22316
+ const entries = readdirSync3(dir, { withFileTypes: true });
22317
+ let n = 0;
22318
+ for (const e of entries) {
22319
+ const p = join18(dir, e.name);
22320
+ if (e.isDirectory()) {
22321
+ n += countItems(p);
22322
+ } else {
22323
+ n += 1;
22324
+ }
22325
+ }
22326
+ return n;
22327
+ } catch {
22328
+ return 0;
22329
+ }
22330
+ }
22331
+ function runMigrate(options = {}) {
22332
+ const fromBase = options.from ?? HOMEDIR_DEFAULT_BASE;
22333
+ const cwd = options.cwd ?? process.cwd();
22334
+ const dryRun = options.dryRun ?? false;
22335
+ const toBase = options.to ?? resolveDefaultTarget(cwd);
22336
+ const earlyExit = checkEarlyExits(fromBase, toBase, dryRun);
22337
+ if (earlyExit !== null) return earlyExit;
22338
+ const perRepoSet = getPerRepoSubdirs();
22339
+ const sourceEntries = readdirSync3(fromBase, { withFileTypes: true });
22340
+ const subdirs = [];
22341
+ for (const entry of sourceEntries) {
22342
+ if (!entry.isDirectory()) continue;
22343
+ subdirs.push(planAndExecuteEntry(entry.name, fromBase, toBase, perRepoSet, dryRun));
22344
+ }
22345
+ const copied = subdirs.filter((s) => s.status === "copied").length;
22346
+ const summary = dryRun ? `Dry run: would copy ${String(copied)} per-repo subdir(s) from ${fromBase} \u2192 ${String(toBase)}.` : `Copied ${String(copied)} per-repo subdir(s) from ${fromBase} \u2192 ${String(toBase)}.`;
22347
+ logger17.info("Migration complete", { dryRun, copied, fromBase, toBase });
22348
+ return { fromBase, toBase, dryRun, subdirs, success: true, summary };
22349
+ }
22350
+ function checkEarlyExits(fromBase, toBase, dryRun) {
22351
+ if (toBase === null) {
22352
+ return {
22353
+ fromBase,
22354
+ toBase: "",
22355
+ dryRun,
22356
+ subdirs: [],
22357
+ success: false,
22358
+ summary: "No git repo detected from cwd. Run from inside a repo or pass --to <path> to choose an explicit destination."
22359
+ };
22360
+ }
22361
+ if (!existsSync22(fromBase)) {
22362
+ return {
22363
+ fromBase,
22364
+ toBase,
22365
+ dryRun,
22366
+ subdirs: [],
22367
+ success: true,
22368
+ summary: `No source state at ${fromBase}. Nothing to migrate.`
22369
+ };
22370
+ }
22371
+ return null;
22372
+ }
22373
+ function planAndExecuteEntry(name, fromBase, toBase, perRepoSet, dryRun) {
22374
+ const source = join18(fromBase, name);
22375
+ const target = join18(toBase, name);
22376
+ if (!perRepoSet.has(name)) {
22377
+ return { subdir: name, status: "skipped-not-per-repo", source, target: "", itemsCopied: 0 };
22378
+ }
22379
+ const items = countItems(source);
22380
+ if (items === 0) {
22381
+ return { subdir: name, status: "skipped-empty", source, target, itemsCopied: 0 };
22382
+ }
22383
+ if (existsSync22(target) && readdirSync3(target).length > 0) {
22384
+ return { subdir: name, status: "skipped-exists", source, target, itemsCopied: 0 };
22385
+ }
22386
+ if (!dryRun) {
22387
+ mkdirSync6(toBase, { recursive: true });
22388
+ cpSync(source, target, { recursive: true, errorOnExist: false });
22389
+ }
22390
+ return { subdir: name, status: "copied", source, target, itemsCopied: items };
22391
+ }
22392
+ function resolveDefaultTarget(cwd) {
22393
+ const repoRoot = findRepoRoot(cwd);
22394
+ if (repoRoot === null) return null;
22395
+ return join18(repoRoot, ".nexus-agents");
22396
+ }
22397
+ function formatMigrationResult(result) {
22398
+ if (!result.success) {
22399
+ return `migrate: ${result.summary}
22400
+ `;
22401
+ }
22402
+ const lines = [];
22403
+ lines.push(result.summary);
22404
+ if (result.subdirs.length === 0) {
22405
+ return `${lines.join("\n")}
22406
+ `;
22407
+ }
22408
+ lines.push("");
22409
+ for (const s of result.subdirs) {
22410
+ const tag = s.status === "copied" ? "\u2713" : "\xB7";
22411
+ const detail = s.status === "copied" ? `(${String(s.itemsCopied)} item(s))` : s.status === "skipped-not-per-repo" ? "(cross-repo \u2014 kept in homedir)" : s.status === "skipped-exists" ? "(destination already has state \u2014 skipped)" : "(empty source \u2014 skipped)";
22412
+ lines.push(` ${tag} ${s.subdir} ${detail}`);
22413
+ }
22414
+ if (!result.dryRun && result.subdirs.some((s) => s.status === "copied")) {
22415
+ lines.push("");
22416
+ lines.push("Next: export NEXUS_REPO_PREFERRED=1 to start using the per-repo data dir.");
22417
+ lines.push(
22418
+ "See: https://github.com/nexus-substrate/nexus-agents/issues/2872 for the full epic."
22419
+ );
22420
+ }
22421
+ return `${lines.join("\n")}
22422
+ `;
22423
+ }
22424
+ async function handleMigrateCommand(args) {
22425
+ const opts = {
22426
+ ...args.options.input !== void 0 ? { from: args.options.input } : {},
22427
+ ...args.options.output !== void 0 ? { to: args.options.output } : {},
22428
+ ...args.options.dryRun !== void 0 ? { dryRun: args.options.dryRun } : {}
22429
+ };
22430
+ const result = runMigrate(opts);
22431
+ process.stderr.write(formatMigrationResult(result));
22432
+ await Promise.resolve();
22433
+ if (!result.success) {
22434
+ process.exit(1);
22435
+ }
22436
+ }
22437
+
22389
22438
  // src/cli-commands.ts
22390
22439
  function printHelp(args) {
22391
22440
  const all = args?.options.all ?? false;
@@ -22464,6 +22513,8 @@ var ASYNC_COMMAND_HANDLERS = {
22464
22513
  usage: handleUsageCommand,
22465
22514
  // Issue #2444: improvement-review command (observability-driven improvement loop)
22466
22515
  "improvement-review": handleImprovementReviewCommand,
22516
+ // Issue #2879 / epic #2872: migrate command (relocate homedir state per-repo)
22517
+ migrate: handleMigrateCommand,
22467
22518
  // #2305 / #2308 / #2311: Init Portable Command (async because --install spawns npm)
22468
22519
  init: handleInitCommand,
22469
22520
  demo: handleDemoCommand,
@@ -22948,8 +22999,8 @@ var isDirectRun = () => {
22948
22999
  };
22949
23000
  if (isDirectRun()) {
22950
23001
  main().catch((error) => {
22951
- const logger17 = createLogger({ component: "cli" });
22952
- logger17.error(
23002
+ const logger18 = createLogger({ component: "cli" });
23003
+ logger18.error(
22953
23004
  "Fatal error during startup",
22954
23005
  error instanceof Error ? error : new Error(String(error))
22955
23006
  );