@wrongstack/cli 0.319.1 → 1.0.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 (105) hide show
  1. package/data/providers.json +22 -15
  2. package/dist/{acp-5ANIAOZC.js → acp-3LARESEO.js} +113 -10
  3. package/dist/acp-hq-telemetry.d.ts +44 -0
  4. package/dist/{audit-ZPCLCC3C.js → audit-46YK5DSC.js} +1 -2
  5. package/dist/{auth-ND7J7DTD.js → auth-ZUMCDNE5.js} +6 -7
  6. package/dist/auth-menu/add-provider.d.ts +7 -0
  7. package/dist/auth-menu/panel-service.d.ts +2 -20
  8. package/dist/{auto-discover-providers-MHFLDSD3.js → auto-discover-providers-VQU3IZMR.js} +1 -2
  9. package/dist/{bench-XYG56AMO.js → bench-YBU6BVQP.js} +175 -35
  10. package/dist/boot/brain-decision-log.d.ts +22 -2
  11. package/dist/boot/system-prompt-menu.d.ts +7 -0
  12. package/dist/{boot-auto-thin-BZ675EVT.js → boot-auto-thin-MANHOYHE.js} +1 -2
  13. package/dist/{chronicle-6EPPMUC5.js → chronicle-UTFETHP6.js} +1 -2
  14. package/dist/{chunk-HF5VQWIY.js → chunk-5IA5337I.js} +3 -3
  15. package/dist/{chunk-TALOKMIC.js → chunk-C2E24IXZ.js} +31 -15
  16. package/dist/chunk-D2VCUN7M.js +54 -0
  17. package/dist/{chunk-XPX432BZ.js → chunk-DR2OXU46.js} +50 -39
  18. package/dist/{chunk-GGGUZSAU.js → chunk-E6RFXHWD.js} +18 -13
  19. package/dist/{chunk-TYO2OVAD.js → chunk-EWKESL4L.js} +8 -4
  20. package/dist/{chunk-QAC263FZ.js → chunk-FPIWTJ2G.js} +2 -3
  21. package/dist/{chunk-7YLN7YUA.js → chunk-IMWXXF4J.js} +61 -9
  22. package/dist/{chunk-LIWVIEZM.js → chunk-KHWDTNBZ.js} +5 -5
  23. package/dist/{chunk-IMT6PNV5.js → chunk-MNQQ4ZNF.js} +26 -22
  24. package/dist/{chunk-P2OKBDCH.js → chunk-MXEJEYT7.js} +53 -14
  25. package/dist/{chunk-PCBJSXYV.js → chunk-O4A3HHKD.js} +2 -2
  26. package/dist/{chunk-XYKYXFEE.js → chunk-TE3Q32JP.js} +10 -4
  27. package/dist/{chunk-635WW3II.js → chunk-TEBMCYZN.js} +67 -18
  28. package/dist/{chunk-E4I2TF5S.js → chunk-TNK6237M.js} +2 -2
  29. package/dist/chunk-UQUYBDMG.js +51 -0
  30. package/dist/{chunk-F5GA2QW2.js → chunk-ZSZ3EYWH.js} +2 -2
  31. package/dist/{cli-context-K73EIND5.js → cli-context-7X3M6U73.js} +59 -308
  32. package/dist/{cli-main-QXSKKANW.js → cli-main-53KG6HAV.js} +972 -293
  33. package/dist/config-transfer-2YF3CRTN.js +99 -0
  34. package/dist/{diag-doctor-QZVKUAE5.js → diag-doctor-7LYUYU35.js} +1 -2
  35. package/dist/execute-deps.d.ts +5 -1
  36. package/dist/{execution-7ZFY4FJY.js → execution-MIBWBYB6.js} +52 -35
  37. package/dist/{export-ROG3DKTZ.js → export-VVRIOWFV.js} +1 -2
  38. package/dist/{governance-JSGHHA2R.js → governance-RYSHV675.js} +1 -2
  39. package/dist/{hq-4QQJO2GN.js → hq-IG3YRGCO.js} +2 -3
  40. package/dist/hq-command-controller.d.ts +37 -7
  41. package/dist/hq-server/ws.d.ts +1 -1
  42. package/dist/{hq-server-CVAYICIS.js → hq-server-OILU3NPI.js} +2 -3
  43. package/dist/{hq-ttl-KUO3AU7X.js → hq-ttl-VJR65OBJ.js} +1 -2
  44. package/dist/{hq-tunnel-LO55RCZE.js → hq-tunnel-NIJ5EP2Y.js} +1 -2
  45. package/dist/index.js +5 -6
  46. package/dist/{init-4JQSG66Q.js → init-DRMMFG2G.js} +1 -2
  47. package/dist/{kanban-run-mirror-EKVNGXWW.js → kanban-run-mirror-22HQ5FNG.js} +1 -2
  48. package/dist/live-settings-input.d.ts +2 -0
  49. package/dist/{mailbox-serve-VKQIRCCB.js → mailbox-serve-VUCWZ2SJ.js} +2 -3
  50. package/dist/{mcp-AQKSASHD.js → mcp-HOMLC4WE.js} +1 -2
  51. package/dist/{modeldiag-ZL4ROTQ5.js → modeldiag-FMJT37SN.js} +2 -3
  52. package/dist/{per-subcommand-help-6VCIKDUW.js → per-subcommand-help-BWBHYVJO.js} +2 -3
  53. package/dist/{permissions-2PWBL4YU.js → permissions-CFDLXETM.js} +1 -2
  54. package/dist/{plugin-usage-7WCZW4NP.js → plugin-usage-HFBI3TFT.js} +2 -3
  55. package/dist/{plugins-7N3TF2QF.js → plugins-PZ2VZL7V.js} +4 -5
  56. package/dist/{project-BLQ3ALVL.js → project-AOQI5XTK.js} +1 -2
  57. package/dist/{project-manifest-RV5FXGQI.js → project-manifest-7NSFVBM3.js} +1 -2
  58. package/dist/{project-picker-CCQR3W4I.js → project-picker-SVBXMPKX.js} +1 -2
  59. package/dist/{projects-5J727S4L.js → projects-L6C6XLDY.js} +1 -2
  60. package/dist/provider-config-utils.d.ts +1 -1
  61. package/dist/{providers-models-OKKQZIWU.js → providers-models-YVMVYWRS.js} +3 -4
  62. package/dist/{proxy-wiring-QCI7EWQC.js → proxy-wiring-MGRSKZZB.js} +1 -2
  63. package/dist/{quick-XLYLZX4B.js → quick-CNB4Z3HS.js} +1 -2
  64. package/dist/{replay-RZXZKP2U.js → replay-JJ2NOWD6.js} +1 -2
  65. package/dist/{replay-FJ2JBXUA.js → replay-Z3FTJEMM.js} +1 -2
  66. package/dist/{rewind-2FFNOOKS.js → rewind-JA3ZLCNM.js} +1 -2
  67. package/dist/{sdd-runtime-R6FAK2G2.js → sdd-runtime-PTOSPYI4.js} +1 -2
  68. package/dist/services/statusline-config.d.ts +43 -13
  69. package/dist/{sessions-config-KAMEBVOX.js → sessions-config-UL45XKX7.js} +2 -3
  70. package/dist/{sessions-doctor-EXHAZSSE.js → sessions-doctor-QUL37U32.js} +1 -2
  71. package/dist/settings-behavior-sections.d.ts +20 -0
  72. package/dist/short-circuit-flags-UREFSYBL.js +10 -0
  73. package/dist/{simpleui-dist-JKNRCRRK.js → simpleui-dist-CXSIDAXZ.js} +1 -2
  74. package/dist/slash-commands/command-context.d.ts +10 -0
  75. package/dist/slash-commands/statusline.d.ts +1 -1
  76. package/dist/subcommands/handlers/bench-run-config.d.ts +18 -0
  77. package/dist/subcommands/handlers/bench.d.ts +8 -7
  78. package/dist/subcommands/handlers/config-transfer.d.ts +6 -0
  79. package/dist/subcommands-WJLBHVKC.js +9 -0
  80. package/dist/{tools-skills-Q4P27URS.js → tools-skills-GH24UCBY.js} +1 -2
  81. package/dist/{update-K45CS6SS.js → update-5DPB4YD4.js} +1 -2
  82. package/dist/{update-check-PKSMSMD6.js → update-check-BS3DHTSI.js} +1 -2
  83. package/dist/version-help-MYKF724O.js +10 -0
  84. package/dist/webui-server/client-registration.d.ts +9 -1
  85. package/dist/{webui-server-F7MSRHOF.js → webui-server-5R35BHWZ.js} +54 -15
  86. package/dist/wiring/brain-and-orchestration.d.ts +2 -0
  87. package/dist/wiring/cli-execute-builder.d.ts +4 -0
  88. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  89. package/dist/wiring/command-host-state.d.ts +50 -5
  90. package/dist/wiring/external-plugins.d.ts +9 -0
  91. package/dist/wiring/provider-runtime-setup.d.ts +2 -0
  92. package/dist/wiring/runtime-controller-deps.d.ts +3 -0
  93. package/dist/wiring/vector-memory-setup.d.ts +12 -0
  94. package/dist/wiring/wrongtrace-prompt-contributor.d.ts +5 -2
  95. package/dist/{wrongtrace-gate-counters-GSVY372D.js → wrongtrace-gate-counters-7C2EAAZL.js} +1 -2
  96. package/dist/{wrongtrace-telemetry-KBBM5NLQ.js → wrongtrace-telemetry-3ASFKOZO.js} +1 -2
  97. package/package.json +28 -28
  98. package/dist/chunk-7OCVIDC7.js +0 -11
  99. package/dist/chunk-KYDJJLJI.js +0 -52
  100. package/dist/launch-hints.d.ts +0 -49
  101. package/dist/short-circuit-flags-7YUCERBB.js +0 -11
  102. package/dist/subcommands-KE6MEQQP.js +0 -10
  103. package/dist/version-help-WMPSEL4U.js +0 -11
  104. package/dist/webui-server/privileged-actions.d.ts +0 -14
  105. package/dist/wiring/cli-heap-watchdog.d.ts +0 -34
@@ -107,47 +107,58 @@ async function loadConfigProviders(configPath, vault, opts) {
107
107
  const decrypted = decryptConfigSecrets(parsed, vault);
108
108
  return decrypted.providers ?? {};
109
109
  }
110
+ var configMutationChain = Promise.resolve();
111
+ function queueConfigMutation(mutate) {
112
+ const run = configMutationChain.then(mutate, mutate);
113
+ configMutationChain = run.then(
114
+ () => void 0,
115
+ () => void 0
116
+ );
117
+ return run;
118
+ }
110
119
  async function mutateConfigProviders(configPath, vault, mutator, profileConfigPath) {
111
- const targetPath = profileConfigPath ?? configPath;
112
- let raw;
113
- let fileExists = true;
114
- try {
115
- raw = await fs.readFile(targetPath, "utf8");
116
- } catch (err) {
117
- if (err.code !== "ENOENT") {
118
- throw new FsError({
119
- message: `Refusing to mutate ${configPath}: ${err.message}`,
120
- code: "FS_READ_FAILED",
121
- path: targetPath,
122
- context: { operation: "mutateConfigProviders", phase: "read" },
123
- cause: err
124
- });
120
+ await queueConfigMutation(async () => {
121
+ const targetPath = profileConfigPath ?? configPath;
122
+ let raw;
123
+ let fileExists = true;
124
+ try {
125
+ raw = await fs.readFile(targetPath, "utf8");
126
+ } catch (err) {
127
+ if (err.code !== "ENOENT") {
128
+ throw new FsError({
129
+ message: `Refusing to mutate ${configPath}: ${err.message}`,
130
+ code: "FS_READ_FAILED",
131
+ path: targetPath,
132
+ context: { operation: "mutateConfigProviders", phase: "read" },
133
+ cause: err
134
+ });
135
+ }
136
+ fileExists = false;
137
+ raw = "{}";
125
138
  }
126
- fileExists = false;
127
- raw = "{}";
128
- }
129
- let parsed;
130
- try {
131
- parsed = JSON.parse(raw);
132
- } catch (err) {
133
- if (fileExists) {
134
- throw new FsError({
135
- message: `Refusing to overwrite corrupt config at ${targetPath} (${err.message}). Fix or move the file aside before retrying.`,
136
- code: "FS_READ_FAILED",
137
- path: targetPath,
138
- context: { operation: "mutateConfigProviders", phase: "parse" },
139
- cause: err
140
- });
139
+ let parsed;
140
+ try {
141
+ parsed = JSON.parse(raw);
142
+ } catch (err) {
143
+ if (fileExists) {
144
+ throw new FsError({
145
+ message: `Refusing to overwrite corrupt config at ${targetPath} (${err.message}). Fix or move the file aside before retrying.`,
146
+ code: "FS_READ_FAILED",
147
+ path: targetPath,
148
+ context: { operation: "mutateConfigProviders", phase: "parse" },
149
+ cause: err
150
+ });
151
+ }
152
+ parsed = {};
141
153
  }
142
- parsed = {};
143
- }
144
- const decrypted = decryptConfigSecrets(parsed, vault);
145
- const providers = decrypted.providers ?? {};
146
- mutator(providers);
147
- decrypted.providers = providers;
148
- clearStaleProviderDefaults(decrypted);
149
- const encrypted = encryptConfigSecrets(decrypted, vault);
150
- await atomicWrite(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
154
+ const decrypted = decryptConfigSecrets(parsed, vault);
155
+ const providers = decrypted.providers ?? {};
156
+ mutator(providers, decrypted);
157
+ decrypted.providers = providers;
158
+ clearStaleProviderDefaults(decrypted);
159
+ const encrypted = encryptConfigSecrets(decrypted, vault);
160
+ await atomicWrite(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
161
+ });
151
162
  }
152
163
 
153
164
  export {
@@ -160,4 +171,4 @@ export {
160
171
  mutateConfigProviders,
161
172
  nowIso
162
173
  };
163
- //# sourceMappingURL=chunk-XPX432BZ.js.map
174
+ //# sourceMappingURL=chunk-DR2OXU46.js.map
@@ -22,7 +22,6 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
22
22
  "no-recovery",
23
23
  "recover",
24
24
  "output-json",
25
- "prompt",
26
25
  "metrics",
27
26
  "webui",
28
27
  "webui-session-child",
@@ -36,8 +35,6 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
36
35
  "no-models-refresh",
37
36
  // (removed: 'director' and 'no-director' — Director Mode is always on)
38
37
  "no-autonomy",
39
- "no-hints",
40
- "hints",
41
38
  "no-menu",
42
39
  "no-hooks",
43
40
  "skip",
@@ -174,20 +171,28 @@ function parseAuthFlags(args) {
174
171
  const out = { positional: [] };
175
172
  for (let i = 0; i < args.length; i++) {
176
173
  const a = args[i];
177
- if (a === "--label") {
178
- const v = args[++i];
174
+ if (!a) continue;
175
+ let key = a;
176
+ let inlineVal;
177
+ const eq = a.indexOf("=");
178
+ if (a.startsWith("--") && eq !== -1) {
179
+ key = a.slice(0, eq);
180
+ inlineVal = a.slice(eq + 1);
181
+ }
182
+ if (key === "--label") {
183
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
179
184
  if (v) out.label = v;
180
- } else if (a === "--family") {
181
- const v = args[++i];
185
+ } else if (key === "--family") {
186
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
182
187
  if (v) out.family = v;
183
- } else if (a === "--base-url") {
184
- const v = args[++i];
188
+ } else if (key === "--base-url") {
189
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
185
190
  if (v) out.baseUrl = v;
186
- } else if (a === "--env") {
187
- const v = args[++i];
191
+ } else if (key === "--env") {
192
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
188
193
  if (v)
189
194
  out.envVars = v.split(",").map((s) => s.trim()).filter(Boolean);
190
- } else if (a && !a.startsWith("--")) {
195
+ } else if (!a.startsWith("--")) {
191
196
  out.positional.push(a);
192
197
  }
193
198
  }
@@ -232,4 +237,4 @@ export {
232
237
  parseAuthFlags,
233
238
  parseSpawnFlags
234
239
  };
235
- //# sourceMappingURL=chunk-GGGUZSAU.js.map
240
+ //# sourceMappingURL=chunk-E6RFXHWD.js.map
@@ -11,9 +11,13 @@ function patchConfig(base, patch) {
11
11
  function fmtDuration(ms) {
12
12
  if (ms < 1e3) return `${ms}ms`;
13
13
  const s = ms / 1e3;
14
- if (s < 60) return `${s.toFixed(s < 10 ? 1 : 0)}s`;
15
- const m = Math.floor(s / 60);
16
- const remSec = Math.round(s - m * 60);
14
+ if (s < 59.5) return `${s.toFixed(s < 10 ? 1 : 0)}s`;
15
+ let m = Math.floor(s / 60);
16
+ let remSec = Math.round(s - m * 60);
17
+ if (remSec === 60) {
18
+ remSec = 0;
19
+ m++;
20
+ }
17
21
  if (m < 60) return remSec === 0 ? `${m}m` : `${m}m${remSec}s`;
18
22
  const h = Math.floor(m / 60);
19
23
  const remMin = m - h * 60;
@@ -47,4 +51,4 @@ export {
47
51
  patchConfig,
48
52
  fmtTaskResultLine
49
53
  };
50
- //# sourceMappingURL=chunk-TYO2OVAD.js.map
54
+ //# sourceMappingURL=chunk-EWKESL4L.js.map
@@ -55,7 +55,7 @@ var helpCmd = async (_args, deps) => {
55
55
  " wstack mailbox serve [opts] Start external-agent mailbox HTTP bridge",
56
56
  " wstack permissions explain Explain tool permission policy decisions",
57
57
  " wstack modeldiag [test] Model benchmarks and capability diagnostics",
58
- " wstack bench [run|list] Agentic benchmarks against standard suites",
58
+ " wstack bench [run|compare] Agentic benchmarks against standard suites",
59
59
  " wstack acp [serve] Agent Client Protocol (ACP) server",
60
60
  " wstack update [--check-only] Self-update the CLI",
61
61
  " wstack diag Full diagnostics",
@@ -81,7 +81,6 @@ var helpCmd = async (_args, deps) => {
81
81
  " Serve the independent minimal chat UI",
82
82
  " --full-auto SimpleUI: runtime-only YOLO + Director + autonomy override",
83
83
  ' --eternal "<mission>" Start an eternal-autonomy loop',
84
- " --no-hints Hide launch hints",
85
84
  " --skip-index Skip codebase indexing on startup",
86
85
  " --chimera-auto-fix off|ask|auto",
87
86
  " How to handle Chimera review findings (default: config value)"
@@ -94,4 +93,4 @@ export {
94
93
  versionCmd,
95
94
  helpCmd
96
95
  };
97
- //# sourceMappingURL=chunk-QAC263FZ.js.map
96
+ //# sourceMappingURL=chunk-FPIWTJ2G.js.map
@@ -20,7 +20,34 @@ function createHqCommandDispatcher(controller) {
20
20
  }
21
21
  };
22
22
  }
23
+ function resolveCommandSessionId(controller, payload) {
24
+ const named = payload["sessionId"];
25
+ if (typeof named === "string" && named.length > 0) return named;
26
+ return controller.sessionId?.();
27
+ }
28
+ function rejectUnknownSession(controller, commandId, sessionId) {
29
+ const named = sessionId;
30
+ if (named === void 0) return null;
31
+ const owns = controller.ownsSession?.(named) ?? (controller.sessionId === void 0 ? true : controller.sessionId() === named);
32
+ if (owns) return null;
33
+ return {
34
+ commandId,
35
+ status: "rejected",
36
+ message: `session ${named} is not active on this client`
37
+ };
38
+ }
39
+ function leaderSessionAffinity(to, sessionId) {
40
+ if (to.trim().toLowerCase() !== "leader") return {};
41
+ if (typeof sessionId !== "string" || sessionId.length === 0) return {};
42
+ return { sessionAffinity: { sessionId } };
43
+ }
23
44
  async function dispatch(controller, commandId, type, payload) {
45
+ const sessionId = resolveCommandSessionId(controller, payload);
46
+ const namedSession = typeof payload["sessionId"] === "string" ? payload["sessionId"] : void 0;
47
+ if (type !== "broadcast") {
48
+ const rejected = rejectUnknownSession(controller, commandId, namedSession);
49
+ if (rejected !== null) return rejected;
50
+ }
24
51
  switch (type) {
25
52
  case "steer": {
26
53
  const mailbox = controller.steerMailbox;
@@ -32,7 +59,15 @@ async function dispatch(controller, commandId, type, payload) {
32
59
  const body = typeof payload["body"] === "string" ? payload["body"] : "";
33
60
  const priority = payload["priority"] === "high" ? "high" : payload["priority"] === "low" ? "low" : "normal";
34
61
  const from = `hq@${controller.sessionTag()}`;
35
- await mailbox.send({ from, to, type: "steer", subject, body, priority });
62
+ await mailbox.send({
63
+ from,
64
+ to,
65
+ type: "steer",
66
+ subject,
67
+ body,
68
+ priority,
69
+ ...leaderSessionAffinity(to, sessionId)
70
+ });
36
71
  return { commandId, status: "accepted", message: `steered ${to}` };
37
72
  }
38
73
  case "btw": {
@@ -45,7 +80,15 @@ async function dispatch(controller, commandId, type, payload) {
45
80
  const body = typeof payload["body"] === "string" ? payload["body"] : "";
46
81
  const priority = payload["priority"] === "high" ? "high" : payload["priority"] === "low" ? "low" : "normal";
47
82
  const from = `hq@${controller.sessionTag()}`;
48
- await mailbox.send({ from, to, type: "btw", subject, body, priority });
83
+ await mailbox.send({
84
+ from,
85
+ to,
86
+ type: "btw",
87
+ subject,
88
+ body,
89
+ priority,
90
+ ...leaderSessionAffinity(to, sessionId)
91
+ });
49
92
  return { commandId, status: "accepted", message: `noted ${to}` };
50
93
  }
51
94
  case "queue": {
@@ -58,7 +101,15 @@ async function dispatch(controller, commandId, type, payload) {
58
101
  const body = typeof payload["body"] === "string" ? payload["body"] : "";
59
102
  const priority = payload["priority"] === "high" ? "high" : payload["priority"] === "low" ? "low" : "normal";
60
103
  const from = `hq@${controller.sessionTag()}`;
61
- await mailbox.send({ from, to, type: "note", subject, body, priority });
104
+ await mailbox.send({
105
+ from,
106
+ to,
107
+ type: "note",
108
+ subject,
109
+ body,
110
+ priority,
111
+ ...leaderSessionAffinity(to, sessionId)
112
+ });
62
113
  return { commandId, status: "accepted", message: `queued for ${to}` };
63
114
  }
64
115
  case "broadcast": {
@@ -76,7 +127,7 @@ async function dispatch(controller, commandId, type, payload) {
76
127
  case "abort": {
77
128
  const target = typeof payload["target"] === "string" ? payload["target"] : "leader";
78
129
  if (target === "leader") {
79
- const aborted = controller.interruptLeader();
130
+ const aborted = controller.interruptLeader(sessionId);
80
131
  return {
81
132
  commandId,
82
133
  status: aborted ? "completed" : "accepted",
@@ -84,14 +135,14 @@ async function dispatch(controller, commandId, type, payload) {
84
135
  };
85
136
  }
86
137
  if (target === "fleet") {
87
- const killed = await controller.killFleet?.() ?? 0;
138
+ const killed = await controller.killFleet?.(sessionId) ?? 0;
88
139
  return {
89
140
  commandId,
90
141
  status: "completed",
91
142
  message: `fleet stopped (${killed} agents)`
92
143
  };
93
144
  }
94
- const terminated = await controller.terminateAgent?.(target) ?? false;
145
+ const terminated = await controller.terminateAgent?.(target, sessionId) ?? false;
95
146
  return {
96
147
  commandId,
97
148
  status: terminated ? "completed" : "rejected",
@@ -105,7 +156,7 @@ async function dispatch(controller, commandId, type, payload) {
105
156
  if (controller.spawnAgent === void 0) {
106
157
  return { commandId, status: "rejected", message: "no director active" };
107
158
  }
108
- const subagentId = await controller.spawnAgent(role, task, maxIterations);
159
+ const subagentId = await controller.spawnAgent(role, task, maxIterations, sessionId);
109
160
  return { commandId, status: "completed", message: `spawned ${subagentId}` };
110
161
  }
111
162
  case "run-command": {
@@ -130,7 +181,8 @@ async function dispatch(controller, commandId, type, payload) {
130
181
  \`\`\`
131
182
  ${command}
132
183
  \`\`\``,
133
- priority: "high"
184
+ priority: "high",
185
+ ...leaderSessionAffinity("leader", sessionId)
134
186
  });
135
187
  return { commandId, status: "accepted", message: "run-command routed to leader as steer" };
136
188
  }
@@ -144,4 +196,4 @@ ${command}
144
196
  export {
145
197
  createHqCommandDispatcher
146
198
  };
147
- //# sourceMappingURL=chunk-7YLN7YUA.js.map
199
+ //# sourceMappingURL=chunk-IMWXXF4J.js.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  helpCmd,
3
3
  versionCmd
4
- } from "./chunk-QAC263FZ.js";
4
+ } from "./chunk-FPIWTJ2G.js";
5
5
  import {
6
6
  parseArgs
7
- } from "./chunk-GGGUZSAU.js";
7
+ } from "./chunk-E6RFXHWD.js";
8
8
 
9
9
  // src/boot/short-circuit-flags.ts
10
10
  async function handleHelpVersionShortCircuit(argv) {
@@ -22,11 +22,11 @@ async function handleHelpVersionShortCircuit(argv) {
22
22
  }
23
23
  if (earlyFlags["help"] === true) {
24
24
  if (positional.length > 0) {
25
- const { subcommandNames } = await import("./subcommands-KE6MEQQP.js");
25
+ const { subcommandNames } = await import("./subcommands-WJLBHVKC.js");
26
26
  if (subcommandNames.includes(positional[0])) {
27
27
  const first = positional[0];
28
28
  const deep = positional[1];
29
- const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-6VCIKDUW.js");
29
+ const { renderDeepHelp, renderFocusedHelp } = await import("./per-subcommand-help-BWBHYVJO.js");
30
30
  if (deep && renderDeepHelp(`${first}:${deep}`, stubRenderer)) {
31
31
  return 0;
32
32
  }
@@ -43,4 +43,4 @@ async function handleHelpVersionShortCircuit(argv) {
43
43
  export {
44
44
  handleHelpVersionShortCircuit
45
45
  };
46
- //# sourceMappingURL=chunk-LIWVIEZM.js.map
46
+ //# sourceMappingURL=chunk-KHWDTNBZ.js.map
@@ -11,7 +11,7 @@ import {
11
11
  openBrowser,
12
12
  runCodexOAuthLogin,
13
13
  startLoopbackServer
14
- } from "./chunk-E4I2TF5S.js";
14
+ } from "./chunk-TNK6237M.js";
15
15
  import {
16
16
  activeLabel,
17
17
  loadConfigProviders,
@@ -20,7 +20,7 @@ import {
20
20
  normalizeKeys,
21
21
  nowIso,
22
22
  writeKeysBack
23
- } from "./chunk-XPX432BZ.js";
23
+ } from "./chunk-DR2OXU46.js";
24
24
 
25
25
  // src/auth-menu/local.ts
26
26
  import { DefaultSecretScrubber as DefaultSecretScrubber2 } from "@wrongstack/core/security";
@@ -1444,11 +1444,11 @@ function renderLiveProviderList(query, filtered, selectedIdx, savedSet) {
1444
1444
  }
1445
1445
  async function saveToGlobalConfig(configPath, provider, model, homeFn = () => process.env.HOME ?? os.homedir()) {
1446
1446
  try {
1447
- const { atomicWrite: atomicWrite2 } = await import("@wrongstack/core/utils");
1448
- const fs2 = await import("node:fs/promises");
1447
+ const { atomicWrite } = await import("@wrongstack/core/utils");
1448
+ const fs = await import("node:fs/promises");
1449
1449
  let existing = {};
1450
1450
  try {
1451
- const raw = await fs2.readFile(configPath, "utf8");
1451
+ const raw = await fs.readFile(configPath, "utf8");
1452
1452
  existing = JSON.parse(raw);
1453
1453
  } catch {
1454
1454
  }
@@ -1467,7 +1467,7 @@ async function saveToGlobalConfig(configPath, provider, model, homeFn = () => pr
1467
1467
  })
1468
1468
  );
1469
1469
  }
1470
- await atomicWrite2(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
1470
+ await atomicWrite(configPath, JSON.stringify(existing, null, 2), { mode: 384 });
1471
1471
  try {
1472
1472
  await appendHistory(
1473
1473
  oldCfg,
@@ -1899,8 +1899,7 @@ async function resolveModelSelection(answer, models, provider, _registry, render
1899
1899
  }
1900
1900
 
1901
1901
  // src/auth-menu/add-provider.ts
1902
- import * as fs from "node:fs/promises";
1903
- import { atomicWrite, color as color9 } from "@wrongstack/core/utils";
1902
+ import { color as color9 } from "@wrongstack/core/utils";
1904
1903
  import { catalogProviderIdFor, PROVIDER_DEFINITIONS } from "@wrongstack/providers";
1905
1904
 
1906
1905
  // src/provider-id.ts
@@ -2148,22 +2147,26 @@ async function resolveDefaultModelId(deps, providerId, template) {
2148
2147
  return provider?.models?.[0]?.id;
2149
2148
  }
2150
2149
  async function adoptAsDefaultIfUnset(deps, providerId, template) {
2151
- const targetPath = deps.profileConfigPath;
2152
- let cfg = {};
2153
- try {
2154
- cfg = JSON.parse(await fs.readFile(targetPath, "utf8"));
2155
- } catch {
2156
- }
2157
- if (cfg["provider"] && cfg["model"]) return;
2158
2150
  const modelId = await resolveDefaultModelId(deps, providerId, template);
2159
2151
  if (!modelId) return;
2160
- cfg["provider"] = providerId;
2161
- cfg["model"] = modelId;
2162
- await atomicWrite(targetPath, JSON.stringify(cfg, null, 2), { mode: 384 });
2163
- deps.renderer.write(
2164
- ` ${color9.green("\u2713")} Set ${color9.bold(providerId)}/${color9.bold(modelId)} as the default.
2165
- `
2152
+ let adopted = false;
2153
+ await mutateConfigProviders(
2154
+ deps.profileConfigPath,
2155
+ deps.vault,
2156
+ (_providers, config) => {
2157
+ if (config["provider"] && config["model"]) return;
2158
+ config["provider"] = providerId;
2159
+ config["model"] = modelId;
2160
+ adopted = true;
2161
+ },
2162
+ deps.profileConfigPath
2166
2163
  );
2164
+ if (adopted) {
2165
+ deps.renderer.write(
2166
+ ` ${color9.green("\u2713")} Set ${color9.bold(providerId)}/${color9.bold(modelId)} as the default.
2167
+ `
2168
+ );
2169
+ }
2167
2170
  }
2168
2171
  async function promptForLabel(deps, usedLabels) {
2169
2172
  const defaultLabel = suggestLabel(usedLabels);
@@ -2201,9 +2204,10 @@ export {
2201
2204
  saveToGlobalConfig,
2202
2205
  runPicker,
2203
2206
  nextCustomProviderId,
2207
+ ownDefinitionsAsCatalog,
2204
2208
  addFromCatalog,
2205
2209
  addKeyForCatalogProvider,
2206
2210
  addCustomProvider,
2207
2211
  addKeyForProvider
2208
2212
  };
2209
- //# sourceMappingURL=chunk-IMT6PNV5.js.map
2213
+ //# sourceMappingURL=chunk-MNQQ4ZNF.js.map
@@ -12,18 +12,17 @@ var BENCH_RUN_FLAGS = [
12
12
  {
13
13
  name: "suite",
14
14
  flag: "--suite <id>",
15
- description: "Benchmark suite id (`polyglot` or `swebench`).",
15
+ description: "Benchmark suite id (`core`, `smoke`, `local`, `polyglot`, or `swebench`).",
16
16
  group: "suite",
17
17
  kind: "value",
18
- defaultValue: "polyglot"
18
+ defaultValue: "core"
19
19
  },
20
20
  {
21
21
  name: "polyglot-dir",
22
22
  flag: "--polyglot-dir <path>",
23
23
  description: "Path to the Aider polyglot dataset (required when --suite polyglot).",
24
24
  group: "suite",
25
- kind: "value",
26
- required: true
25
+ kind: "value"
27
26
  },
28
27
  {
29
28
  name: "languages",
@@ -46,15 +45,36 @@ var BENCH_RUN_FLAGS = [
46
45
  group: "suite",
47
46
  kind: "boolean"
48
47
  },
48
+ {
49
+ name: "suite-dir",
50
+ flag: "--suite-dir <path>",
51
+ description: "Directory containing bench.local.json (required when --suite local).",
52
+ group: "suite",
53
+ kind: "value"
54
+ },
55
+ {
56
+ name: "manifest",
57
+ flag: "--manifest <file>",
58
+ description: "Explicit local-manifest path (alternative to --suite-dir).",
59
+ group: "suite",
60
+ kind: "value"
61
+ },
49
62
  // -- Model matrix ---------------------------------------------------
50
63
  {
51
64
  name: "models",
52
65
  flag: "--models <config>",
53
- description: "Path to the model-cells config (JSON).",
66
+ description: "Path to the model-cells config (JSON). Optional when --cell or a saved model is set.",
54
67
  group: "models",
55
68
  kind: "value",
56
69
  defaultValue: "bench.config.json"
57
70
  },
71
+ {
72
+ name: "cell",
73
+ flag: "--cell <spec>",
74
+ description: "Comma-separated model cells (`provider/model` or `label=provider/model`). Skips the config file.",
75
+ group: "models",
76
+ kind: "value"
77
+ },
58
78
  // -- Run control ----------------------------------------------------
59
79
  {
60
80
  name: "limit",
@@ -77,6 +97,21 @@ var BENCH_RUN_FLAGS = [
77
97
  description: "Override the per-cell concurrency from the model config.",
78
98
  group: "control",
79
99
  kind: "value"
100
+ },
101
+ {
102
+ name: "repeats",
103
+ flag: "--repeats <N>",
104
+ description: "Attempts per (task x model). >1 adds pass@k and a flakiness count so run-to-run noise is visible.",
105
+ group: "control",
106
+ kind: "value",
107
+ defaultValue: "1"
108
+ },
109
+ {
110
+ name: "keep-sandbox",
111
+ flag: "--keep-sandbox",
112
+ description: "Keep the temporary sandbox (workdirs + isolated home) on disk for debugging.",
113
+ group: "control",
114
+ kind: "boolean"
80
115
  }
81
116
  ];
82
117
  var BENCH_RUN_BOOLEAN_FLAG_NAMES = BENCH_RUN_FLAGS.filter(
@@ -89,10 +124,10 @@ var BENCH_RUN_FLAG_COLUMN_WIDTH = 28;
89
124
  function renderBenchRunHelpToString() {
90
125
  const lines = [
91
126
  color.bold("wstack bench run \u2014 execute a benchmark suite across a model matrix"),
92
- color.dim(" Runs a benchmark suite (polyglot or swebench) across every model cell"),
93
- color.dim(" in the config. Output is a per-run directory with `report.md`, JSON"),
94
- color.dim(" artifacts, and (for swebench) per-cell predictions for the official"),
95
- color.dim(" harness."),
127
+ color.dim(" Default suite is bundled core (6 agent-edit tasks with tests). Pass --cell"),
128
+ color.dim(" provider/model to start immediately. Output is a per-run directory"),
129
+ color.dim(" with `report.md` (leaderboard + per-task matrix), JSON artifacts,"),
130
+ color.dim(" and (for swebench) per-cell predictions for the official harness."),
96
131
  "",
97
132
  color.bold("Usage"),
98
133
  ` ${buildUsageLine()}`,
@@ -101,7 +136,7 @@ function renderBenchRunHelpToString() {
101
136
  ...buildFlagBlock(),
102
137
  "",
103
138
  color.dim(
104
- "See also: wstack bench list (show available suites + cells); wstack bench report <dir>"
139
+ "See also: wstack bench list; wstack bench report <dir>; wstack bench compare <a> <b>"
105
140
  )
106
141
  ];
107
142
  return lines.join("\n") + "\n";
@@ -969,10 +1004,14 @@ var helpTable = {
969
1004
  bench: {
970
1005
  name: "bench",
971
1006
  title: "wstack bench \u2014 run model-independent agentic benchmarks",
972
- description: "Run WrongStack against the Aider polyglot or SWE-bench Verified suites with deterministic graders. Used internally to compare model quality across releases; also useful for evaluating a new model before adopting it.",
973
- usage: "wstack bench [run|report|list] [...]",
1007
+ description: "Run WrongStack against the bundled smoke suite, a local manifest, Aider polyglot, or SWE-bench Verified with deterministic graders. Default `bench run` is the bundled core edit-eval; pass --cell provider/model (or a saved model).",
1008
+ usage: "wstack bench [run|compare|report|list] [...]",
974
1009
  subcommands: [
975
- { name: "run", description: "Run a benchmark suite (--suite <id> --models <config>)." },
1010
+ { name: "run", description: "Run a suite. Default: bundled smoke + --cell or saved model." },
1011
+ {
1012
+ name: "compare <a> <b>",
1013
+ description: "Diff two finished run directories (fingerprint-aware)."
1014
+ },
976
1015
  { name: "report <dir>", description: "Render the Markdown report for a prior run." },
977
1016
  { name: "list", description: "List available suites and the model configs in the catalog." }
978
1017
  ],
@@ -1163,4 +1202,4 @@ export {
1163
1202
  subcommandsWithFocusedHelp,
1164
1203
  renderGenericHelp
1165
1204
  };
1166
- //# sourceMappingURL=chunk-P2OKBDCH.js.map
1205
+ //# sourceMappingURL=chunk-MXEJEYT7.js.map
@@ -14,7 +14,7 @@ async function printUpdateNotice(initialUpdateInfo) {
14
14
  const ac = new AbortController();
15
15
  const timer = setTimeout(() => ac.abort(), 2e3);
16
16
  try {
17
- const { checkForUpdate } = await import("./update-check-PKSMSMD6.js");
17
+ const { checkForUpdate } = await import("./update-check-BS3DHTSI.js");
18
18
  info = await checkForUpdate(ac.signal);
19
19
  } catch {
20
20
  } finally {
@@ -62,4 +62,4 @@ export {
62
62
  applySessionShellDefault,
63
63
  runPreflight
64
64
  };
65
- //# sourceMappingURL=chunk-PCBJSXYV.js.map
65
+ //# sourceMappingURL=chunk-O4A3HHKD.js.map
@@ -423,6 +423,7 @@ async function writeState(projectRoot, state) {
423
423
  }
424
424
 
425
425
  // src/hq-publisher.ts
426
+ var HQ_DISCOVERY_CONNECTION_KEY = "<discover>";
426
427
  function nodeWsSocketFactory(url) {
427
428
  return new WebSocket(url);
428
429
  }
@@ -440,11 +441,13 @@ function hqExplicitlyDisabled(options) {
440
441
  }
441
442
  function resolvedHqConnectionKey(options) {
442
443
  if (options.config !== void 0) {
443
- return options.config.enabled === false ? void 0 : `${options.config.url}
444
+ if (options.config.enabled === false) return void 0;
445
+ return options.config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${options.config.url}
444
446
  ${options.config.token ?? ""}`;
445
447
  }
446
448
  const config = resolveHqConfig({ config: options.appConfig?.hq });
447
- return config === void 0 ? void 0 : `${config.url}
449
+ if (config === void 0) return void 0;
450
+ return config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${config.url}
448
451
  ${config.token ?? ""}`;
449
452
  }
450
453
  function startCliHqConnection(options) {
@@ -460,7 +463,10 @@ function startCliHqConnection(options) {
460
463
  const tryConnect = () => {
461
464
  const nextKey = resolvedHqConnectionKey(options);
462
465
  if (nextKey === void 0) return;
463
- if (publisher !== void 0 && publisherKey === nextKey) return;
466
+ if (publisher !== void 0 && publisherKey === nextKey) {
467
+ if (nextKey === HQ_DISCOVERY_CONNECTION_KEY) publisher.refreshEndpoint();
468
+ return;
469
+ }
464
470
  publisher?.close();
465
471
  publisher = void 0;
466
472
  publisherKey = void 0;
@@ -507,4 +513,4 @@ function startCliHqConnection(options) {
507
513
  export {
508
514
  startCliHqConnection
509
515
  };
510
- //# sourceMappingURL=chunk-XYKYXFEE.js.map
516
+ //# sourceMappingURL=chunk-TE3Q32JP.js.map