@wrongstack/cli 0.256.1 → 0.257.2
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.
- package/dist/index.js +264 -119
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.js
CHANGED
|
@@ -37,8 +37,13 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
37
37
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
38
38
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
39
39
|
});
|
|
40
|
-
var __esm = (fn, res) => function __init() {
|
|
41
|
-
|
|
40
|
+
var __esm = (fn, res, err) => function __init() {
|
|
41
|
+
if (err) throw err[0];
|
|
42
|
+
try {
|
|
43
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
44
|
+
} catch (e) {
|
|
45
|
+
throw err = [e], e;
|
|
46
|
+
}
|
|
42
47
|
};
|
|
43
48
|
var __export = (target, all) => {
|
|
44
49
|
for (var name in all)
|
|
@@ -5724,15 +5729,14 @@ function gitText(args, cwd) {
|
|
|
5724
5729
|
reject(err);
|
|
5725
5730
|
return;
|
|
5726
5731
|
}
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
if (
|
|
5730
|
-
}
|
|
5731
|
-
child.
|
|
5732
|
-
|
|
5733
|
-
});
|
|
5734
|
-
child.on("
|
|
5735
|
-
child.on("close", (code) => resolve10({ code: code ?? 1, out: out.trim() }));
|
|
5732
|
+
const chunks = [];
|
|
5733
|
+
const emit = (c) => {
|
|
5734
|
+
if (chunks.join("").length < MAX_CMD_OUTPUT) chunks.push(c.toString());
|
|
5735
|
+
};
|
|
5736
|
+
child.stdout?.on("data", emit);
|
|
5737
|
+
child.stderr?.on("data", emit);
|
|
5738
|
+
child.on("error", () => resolve10({ code: 1, out: chunks.join("") }));
|
|
5739
|
+
child.on("close", (code) => resolve10({ code: code ?? 1, out: chunks.join("").trim() }));
|
|
5736
5740
|
});
|
|
5737
5741
|
}
|
|
5738
5742
|
async function isGitRepo(cwd) {
|
|
@@ -5769,7 +5773,7 @@ function runCmd(cmd, args, cwd, shell = false) {
|
|
|
5769
5773
|
}
|
|
5770
5774
|
}
|
|
5771
5775
|
return new Promise((resolve10, reject) => {
|
|
5772
|
-
|
|
5776
|
+
const chunks = [];
|
|
5773
5777
|
let child;
|
|
5774
5778
|
try {
|
|
5775
5779
|
child = spawn(cmd, args, {
|
|
@@ -5787,13 +5791,16 @@ function runCmd(cmd, args, cwd, shell = false) {
|
|
|
5787
5791
|
return;
|
|
5788
5792
|
}
|
|
5789
5793
|
const append = (c) => {
|
|
5790
|
-
|
|
5791
|
-
if (out.length > MAX_CMD_OUTPUT) out = out.slice(-MAX_CMD_OUTPUT);
|
|
5794
|
+
chunks.push(c.toString());
|
|
5792
5795
|
};
|
|
5793
5796
|
child.stdout?.on("data", append);
|
|
5794
5797
|
child.stderr?.on("data", append);
|
|
5795
|
-
child.on("error", (e) => resolve10({ code: 1, out: `${
|
|
5796
|
-
child.on("close", (code) =>
|
|
5798
|
+
child.on("error", (e) => resolve10({ code: 1, out: `${chunks.join("")}${String(e)}` }));
|
|
5799
|
+
child.on("close", (code) => {
|
|
5800
|
+
let out = chunks.join("");
|
|
5801
|
+
if (out.length > MAX_CMD_OUTPUT) out = out.slice(-MAX_CMD_OUTPUT);
|
|
5802
|
+
resolve10({ code: code ?? 1, out: out.trim() });
|
|
5803
|
+
});
|
|
5797
5804
|
});
|
|
5798
5805
|
}
|
|
5799
5806
|
function detectPackageManager(root) {
|
|
@@ -8646,8 +8653,19 @@ function listRoles() {
|
|
|
8646
8653
|
}
|
|
8647
8654
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
8648
8655
|
var MAX_OUTPUT_LINES = 500;
|
|
8656
|
+
var WINDOWS_CMD_METACHARACTERS = /[;&|<>^$,(){}[\]!#%'"\\/`]/;
|
|
8657
|
+
function validateCommand(cmd) {
|
|
8658
|
+
if (process.platform !== "win32") return;
|
|
8659
|
+
if (WINDOWS_CMD_METACHARACTERS.test(cmd)) {
|
|
8660
|
+
throw new Error(
|
|
8661
|
+
`Command contains disallowed metacharacters for Windows: ${cmd.match(WINDOWS_CMD_METACHARACTERS)?.[0] ?? "?"}
|
|
8662
|
+
The following characters are not allowed: ; & | < > ^ $ , ( ) { } [ ] ! # % ' " \\ / \` * ?`
|
|
8663
|
+
);
|
|
8664
|
+
}
|
|
8665
|
+
}
|
|
8649
8666
|
function runCommand(cmd, cwd, timeout) {
|
|
8650
8667
|
return new Promise((resolve10) => {
|
|
8668
|
+
validateCommand(cmd);
|
|
8651
8669
|
const opts = {
|
|
8652
8670
|
cwd,
|
|
8653
8671
|
timeout,
|
|
@@ -8728,6 +8746,7 @@ Examples:
|
|
|
8728
8746
|
/dev git diff --stat`
|
|
8729
8747
|
};
|
|
8730
8748
|
}
|
|
8749
|
+
validateCommand(cmd);
|
|
8731
8750
|
const cwd = opts.cwd;
|
|
8732
8751
|
const startedAt = Date.now();
|
|
8733
8752
|
opts.renderer.write(color.dim(`$ ${cmd}`));
|
|
@@ -10425,11 +10444,11 @@ function classifyError(input) {
|
|
|
10425
10444
|
}
|
|
10426
10445
|
function extractCode(s) {
|
|
10427
10446
|
const ts = /\bTS\d+\b|\bCS\d+\b/.exec(s);
|
|
10428
|
-
if (ts) return ts[0];
|
|
10447
|
+
if (ts !== null) return ts[0];
|
|
10429
10448
|
const rust = /\bE\d{4,}\b/.exec(s);
|
|
10430
|
-
if (rust) return rust[0];
|
|
10449
|
+
if (rust !== null) return rust[0];
|
|
10431
10450
|
const c = /\bc\d+\b/i.exec(s);
|
|
10432
|
-
if (c) return c[0];
|
|
10451
|
+
if (c !== null) return c[0];
|
|
10433
10452
|
return void 0;
|
|
10434
10453
|
}
|
|
10435
10454
|
function needsSubagent(c) {
|
|
@@ -12155,8 +12174,20 @@ async function runAdd(name, enable, configured, configPath2, mcpRegistry, all) {
|
|
|
12155
12174
|
}
|
|
12156
12175
|
async function runRemove(name, configured, configPath2, mcpRegistry) {
|
|
12157
12176
|
if (!configured[name]) return `Server "${name}" is not in config.`;
|
|
12158
|
-
|
|
12159
|
-
|
|
12177
|
+
try {
|
|
12178
|
+
await mcpRegistry.stop(name);
|
|
12179
|
+
} catch (err) {
|
|
12180
|
+
console.error(
|
|
12181
|
+
JSON.stringify({
|
|
12182
|
+
level: "warn",
|
|
12183
|
+
event: "mcp.stop_failed_on_remove",
|
|
12184
|
+
server: name,
|
|
12185
|
+
message: err instanceof Error ? err.message : String(err),
|
|
12186
|
+
note: "config entry removed but server may still be running",
|
|
12187
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12188
|
+
})
|
|
12189
|
+
);
|
|
12190
|
+
}
|
|
12160
12191
|
const full = await readConfig(configPath2);
|
|
12161
12192
|
const mcpServers = {
|
|
12162
12193
|
...full.mcpServers ?? {}
|
|
@@ -12195,8 +12226,20 @@ async function runEnable(name, configured, configPath2, mcpRegistry) {
|
|
|
12195
12226
|
async function runDisable(name, configured, configPath2, mcpRegistry) {
|
|
12196
12227
|
const cfg = configured[name];
|
|
12197
12228
|
if (!cfg) return `Server "${name}" is not in config.`;
|
|
12198
|
-
|
|
12199
|
-
|
|
12229
|
+
try {
|
|
12230
|
+
await mcpRegistry.stop(name);
|
|
12231
|
+
} catch (err) {
|
|
12232
|
+
console.error(
|
|
12233
|
+
JSON.stringify({
|
|
12234
|
+
level: "warn",
|
|
12235
|
+
event: "mcp.stop_failed_on_disable",
|
|
12236
|
+
server: name,
|
|
12237
|
+
message: err instanceof Error ? err.message : String(err),
|
|
12238
|
+
note: "config marked disabled but server may still be running",
|
|
12239
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12240
|
+
})
|
|
12241
|
+
);
|
|
12242
|
+
}
|
|
12200
12243
|
const full = await readConfig(configPath2);
|
|
12201
12244
|
const mcpServers = {
|
|
12202
12245
|
...full.mcpServers ?? {}
|
|
@@ -21730,22 +21773,22 @@ function renderFleetLine(states, now, columns, version) {
|
|
|
21730
21773
|
const visible = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
21731
21774
|
if (visible.length > max) {
|
|
21732
21775
|
let count = 0;
|
|
21733
|
-
|
|
21776
|
+
const out = [];
|
|
21734
21777
|
let i = 0;
|
|
21735
21778
|
while (i < line.length && count < max - 1) {
|
|
21736
21779
|
if (line[i] === "\x1B") {
|
|
21737
21780
|
const end = line.indexOf("m", i);
|
|
21738
21781
|
if (end !== -1) {
|
|
21739
|
-
out
|
|
21782
|
+
out.push(line.slice(i, end + 1));
|
|
21740
21783
|
i = end + 1;
|
|
21741
21784
|
continue;
|
|
21742
21785
|
}
|
|
21743
21786
|
}
|
|
21744
|
-
|
|
21787
|
+
if (line[i] !== void 0) out.push(line[i]);
|
|
21745
21788
|
count++;
|
|
21746
21789
|
i++;
|
|
21747
21790
|
}
|
|
21748
|
-
line = out + "\u2026";
|
|
21791
|
+
line = out.join("") + "\u2026";
|
|
21749
21792
|
}
|
|
21750
21793
|
return line;
|
|
21751
21794
|
}
|
|
@@ -21999,7 +22042,8 @@ init_sdd();
|
|
|
21999
22042
|
init_utils();
|
|
22000
22043
|
var DEFAULT_MAX_CONSECUTIVE_AUTO_PROCEED = 50;
|
|
22001
22044
|
function parseSuggestionsFromOutput(finalText) {
|
|
22002
|
-
const { texts } = parseNextSteps(finalText, false);
|
|
22045
|
+
const { texts, autoTexts } = parseNextSteps(finalText, false);
|
|
22046
|
+
if (autoTexts.length > 0) ;
|
|
22003
22047
|
return texts.length > 0 ? texts : null;
|
|
22004
22048
|
}
|
|
22005
22049
|
async function runRepl(opts) {
|
|
@@ -22224,13 +22268,17 @@ ${lines.join("\n")}
|
|
|
22224
22268
|
);
|
|
22225
22269
|
}
|
|
22226
22270
|
} else {
|
|
22227
|
-
const
|
|
22271
|
+
const isYolo = opts.getYolo?.() ?? false;
|
|
22272
|
+
const autoSuggestions = opts.getAutoSuggestions?.() ?? [];
|
|
22273
|
+
const useAutoSuggestions = isYolo && autoSuggestions.length > 0;
|
|
22274
|
+
const top = useAutoSuggestions ? autoSuggestions[0] ?? "" : suggestions[0] ?? "";
|
|
22228
22275
|
const delay = opts.autoProceedDelayMs ?? 1e3;
|
|
22229
22276
|
const ctrl = new AbortController();
|
|
22230
22277
|
activeCtrl = ctrl;
|
|
22231
22278
|
try {
|
|
22232
22279
|
autoIterCount++;
|
|
22233
|
-
|
|
22280
|
+
const promptToFeed = useAutoSuggestions && opts.autonomyNextPrompt ? opts.autonomyNextPrompt.replace("{{suggestion}}", top) : top;
|
|
22281
|
+
await runAutoProceed(opts, promptToFeed, delay, ctrl);
|
|
22234
22282
|
} finally {
|
|
22235
22283
|
activeCtrl = void 0;
|
|
22236
22284
|
}
|
|
@@ -22909,6 +22957,8 @@ async function execute(deps) {
|
|
|
22909
22957
|
getNextPredict,
|
|
22910
22958
|
onSuggestionsParsed,
|
|
22911
22959
|
getSuggestions: getSuggestions2,
|
|
22960
|
+
getAutoSuggestions,
|
|
22961
|
+
autonomyNextPrompt,
|
|
22912
22962
|
autoProceedDelayMs,
|
|
22913
22963
|
autoProceedMaxIterations,
|
|
22914
22964
|
brain,
|
|
@@ -23269,7 +23319,8 @@ async function execute(deps) {
|
|
|
23269
23319
|
enhanceDelayMs: cfg.autonomy?.enhanceDelayMs ?? 6e4,
|
|
23270
23320
|
enhanceEnabled: cfg.autonomy?.enhance ?? true,
|
|
23271
23321
|
enhanceLanguage: cfg.autonomy?.enhanceLanguage === "english" ? "english" : "original",
|
|
23272
|
-
mouseMode: autonomy?.mouseMode ?? false
|
|
23322
|
+
mouseMode: autonomy?.mouseMode ?? false,
|
|
23323
|
+
autonomyNextPrompt: cfg.autonomy?.autonomyNextPrompt ?? "auto {{suggestion}}"
|
|
23273
23324
|
};
|
|
23274
23325
|
},
|
|
23275
23326
|
async saveSettings(s) {
|
|
@@ -23293,6 +23344,7 @@ async function execute(deps) {
|
|
|
23293
23344
|
if (s.mouseMode !== void 0) a["mouseMode"] = s.mouseMode;
|
|
23294
23345
|
if (s.enhanceEnabled !== void 0) a["enhance"] = s.enhanceEnabled;
|
|
23295
23346
|
if (s.enhanceLanguage !== void 0) a["enhanceLanguage"] = s.enhanceLanguage;
|
|
23347
|
+
if (s.autonomyNextPrompt !== void 0) a["autonomyNextPrompt"] = s.autonomyNextPrompt;
|
|
23296
23348
|
}
|
|
23297
23349
|
);
|
|
23298
23350
|
if (s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0) {
|
|
@@ -23437,6 +23489,8 @@ async function execute(deps) {
|
|
|
23437
23489
|
onClearHistory: (dispatch) => {
|
|
23438
23490
|
dispatch({ type: "clearHistory" });
|
|
23439
23491
|
dispatch({ type: "resetContextChip" });
|
|
23492
|
+
dispatch({ type: "streamReset" });
|
|
23493
|
+
dispatch({ type: "toolStreamClear" });
|
|
23440
23494
|
},
|
|
23441
23495
|
fleetStreamController,
|
|
23442
23496
|
interruptController,
|
|
@@ -23521,31 +23575,35 @@ async function execute(deps) {
|
|
|
23521
23575
|
const metaMode = context.meta?.["mode"];
|
|
23522
23576
|
return typeof metaMode === "string" ? metaMode : modeId ?? "default";
|
|
23523
23577
|
},
|
|
23524
|
-
registerDebugStreamCallback: (cb) => {
|
|
23525
|
-
|
|
23526
|
-
|
|
23578
|
+
registerDebugStreamCallback: async (cb) => {
|
|
23579
|
+
try {
|
|
23580
|
+
const { setDebugStreamCallback } = await import('@wrongstack/providers');
|
|
23581
|
+
setDebugStreamCallback(cb);
|
|
23582
|
+
} catch (err) {
|
|
23583
|
+
console.error(
|
|
23527
23584
|
JSON.stringify({
|
|
23528
23585
|
level: "error",
|
|
23529
23586
|
event: "execution.debug_stream_register_failed",
|
|
23530
23587
|
message: err instanceof Error ? err.message : String(err),
|
|
23531
23588
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23532
23589
|
})
|
|
23533
|
-
)
|
|
23534
|
-
|
|
23590
|
+
);
|
|
23591
|
+
}
|
|
23535
23592
|
},
|
|
23536
|
-
restoreDebugStreamCallback: () => {
|
|
23537
|
-
|
|
23538
|
-
|
|
23539
|
-
|
|
23540
|
-
|
|
23593
|
+
restoreDebugStreamCallback: async () => {
|
|
23594
|
+
try {
|
|
23595
|
+
const { setDebugStreamCallback, defaultDebugStreamCallback } = await import('@wrongstack/providers');
|
|
23596
|
+
setDebugStreamCallback(defaultDebugStreamCallback);
|
|
23597
|
+
} catch (err) {
|
|
23598
|
+
console.error(
|
|
23541
23599
|
JSON.stringify({
|
|
23542
23600
|
level: "error",
|
|
23543
23601
|
event: "execution.debug_stream_restore_failed",
|
|
23544
23602
|
message: err instanceof Error ? err.message : String(err),
|
|
23545
23603
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23546
23604
|
})
|
|
23547
|
-
)
|
|
23548
|
-
|
|
23605
|
+
);
|
|
23606
|
+
}
|
|
23549
23607
|
},
|
|
23550
23608
|
restoredMessages,
|
|
23551
23609
|
restoredToolCalls,
|
|
@@ -23600,12 +23658,14 @@ async function execute(deps) {
|
|
|
23600
23658
|
if (oldWriter && oldWriter !== resumed.writer) {
|
|
23601
23659
|
const endedUsage = tokenCounter.total();
|
|
23602
23660
|
void (async () => {
|
|
23661
|
+
let appendOk = false;
|
|
23603
23662
|
try {
|
|
23604
23663
|
await oldWriter.append({
|
|
23605
23664
|
type: "session_end",
|
|
23606
23665
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
23607
23666
|
usage: endedUsage
|
|
23608
23667
|
});
|
|
23668
|
+
appendOk = true;
|
|
23609
23669
|
} catch (err) {
|
|
23610
23670
|
console.error(
|
|
23611
23671
|
JSON.stringify({
|
|
@@ -23616,32 +23676,50 @@ async function execute(deps) {
|
|
|
23616
23676
|
})
|
|
23617
23677
|
);
|
|
23618
23678
|
}
|
|
23619
|
-
|
|
23620
|
-
|
|
23621
|
-
|
|
23622
|
-
|
|
23623
|
-
|
|
23624
|
-
|
|
23625
|
-
|
|
23626
|
-
|
|
23627
|
-
|
|
23628
|
-
|
|
23629
|
-
|
|
23679
|
+
if (appendOk) {
|
|
23680
|
+
try {
|
|
23681
|
+
await oldWriter.close();
|
|
23682
|
+
} catch (err) {
|
|
23683
|
+
console.error(
|
|
23684
|
+
JSON.stringify({
|
|
23685
|
+
level: "error",
|
|
23686
|
+
event: "execution.session_close_failed",
|
|
23687
|
+
message: err instanceof Error ? err.message : String(err),
|
|
23688
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23689
|
+
})
|
|
23690
|
+
);
|
|
23691
|
+
}
|
|
23630
23692
|
}
|
|
23631
23693
|
})();
|
|
23632
23694
|
}
|
|
23633
23695
|
agent.ctx.session = resumed.writer;
|
|
23634
23696
|
tokenCounter.reset();
|
|
23635
|
-
void
|
|
23636
|
-
|
|
23637
|
-
|
|
23638
|
-
|
|
23639
|
-
|
|
23640
|
-
|
|
23641
|
-
|
|
23642
|
-
|
|
23643
|
-
|
|
23644
|
-
|
|
23697
|
+
void (async () => {
|
|
23698
|
+
try {
|
|
23699
|
+
await recoveryLock.clear();
|
|
23700
|
+
} catch (err) {
|
|
23701
|
+
console.error(
|
|
23702
|
+
JSON.stringify({
|
|
23703
|
+
level: "warn",
|
|
23704
|
+
event: "execution.recovery_lock_clear_failed",
|
|
23705
|
+
message: err instanceof Error ? err.message : String(err),
|
|
23706
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23707
|
+
})
|
|
23708
|
+
);
|
|
23709
|
+
}
|
|
23710
|
+
try {
|
|
23711
|
+
await recoveryLock.write(resumed.writer.id);
|
|
23712
|
+
} catch (err) {
|
|
23713
|
+
console.error(
|
|
23714
|
+
JSON.stringify({
|
|
23715
|
+
level: "error",
|
|
23716
|
+
event: "execution.recovery_lock_update_failed",
|
|
23717
|
+
message: err instanceof Error ? err.message : String(err),
|
|
23718
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23719
|
+
})
|
|
23720
|
+
);
|
|
23721
|
+
}
|
|
23722
|
+
})();
|
|
23645
23723
|
const { replaySessionEvents } = await import('@wrongstack/tui');
|
|
23646
23724
|
const entries = replaySessionEvents(
|
|
23647
23725
|
resumed.data.events,
|
|
@@ -23870,6 +23948,9 @@ ${parts.join("\n")}
|
|
|
23870
23948
|
getNextPredict,
|
|
23871
23949
|
onSuggestionsParsed,
|
|
23872
23950
|
getSuggestions: getSuggestions2,
|
|
23951
|
+
getAutoSuggestions,
|
|
23952
|
+
getYolo,
|
|
23953
|
+
autonomyNextPrompt,
|
|
23873
23954
|
autoProceedDelayMs,
|
|
23874
23955
|
onValidateAutoProceed,
|
|
23875
23956
|
autoProceedMaxIterations,
|
|
@@ -23984,7 +24065,7 @@ function buildRoutingRunner(config, host) {
|
|
|
23984
24065
|
}
|
|
23985
24066
|
|
|
23986
24067
|
// src/fleet/host.ts
|
|
23987
|
-
var MultiAgentHost = class {
|
|
24068
|
+
var MultiAgentHost = class _MultiAgentHost {
|
|
23988
24069
|
constructor(deps, opts = {}) {
|
|
23989
24070
|
this.deps = deps;
|
|
23990
24071
|
this.opts = opts;
|
|
@@ -24013,6 +24094,19 @@ var MultiAgentHost = class {
|
|
|
24013
24094
|
* actionable error instead of a generic "Director could not be activated".
|
|
24014
24095
|
*/
|
|
24015
24096
|
promotionBlockReason = null;
|
|
24097
|
+
/** Guards `buildDirector` from overwriting a runner set by `spawnACP`. */
|
|
24098
|
+
directorRunnerSet = false;
|
|
24099
|
+
/** Event-bus off-handles registered in `buildDirector` — cleaned up in `dispose()`. */
|
|
24100
|
+
directorOffHandles = [];
|
|
24101
|
+
/** Coordinator task.assigned listener — cleaned up in `dispose()`. */
|
|
24102
|
+
coordinatorOffHandle = null;
|
|
24103
|
+
/** ACP runner cache — keyed by role/subagentId, reused across tasks to avoid
|
|
24104
|
+
* creating a new transport process on every ACP task dispatch. Stores the
|
|
24105
|
+
* pending promise so concurrent calls for the same subagentId share one spawn.
|
|
24106
|
+
* Bounded to 20 entries with LRU eviction to prevent unbounded memory growth. */
|
|
24107
|
+
acpRunnerCache = /* @__PURE__ */ new Map();
|
|
24108
|
+
acpRunnerAccessOrder = [];
|
|
24109
|
+
static ACP_CACHE_MAX = 20;
|
|
24016
24110
|
/**
|
|
24017
24111
|
* Force the lazy build path to run *now* and return the live Director,
|
|
24018
24112
|
* or null when director mode is off. Used by the CLI to register the
|
|
@@ -24094,60 +24188,71 @@ var MultiAgentHost = class {
|
|
|
24094
24188
|
this.fleetManager?.removePendingTask(task.id);
|
|
24095
24189
|
this.emitLifecycleCompleted(task.id, result);
|
|
24096
24190
|
});
|
|
24097
|
-
this.
|
|
24098
|
-
|
|
24099
|
-
|
|
24100
|
-
|
|
24101
|
-
|
|
24102
|
-
|
|
24103
|
-
|
|
24104
|
-
|
|
24105
|
-
});
|
|
24106
|
-
this.director.fleet.filter("budget.extended", (e) => {
|
|
24107
|
-
const payload = e.payload;
|
|
24108
|
-
this.deps.events.emit("subagent.budget_extended", {
|
|
24109
|
-
subagentId: e.subagentId,
|
|
24110
|
-
kind: payload.kind,
|
|
24111
|
-
newLimit: payload.newLimit,
|
|
24112
|
-
totalExtensions: payload.totalExtensions
|
|
24113
|
-
});
|
|
24114
|
-
});
|
|
24115
|
-
this.director.fleet.filter("ctx.pct", (e) => {
|
|
24116
|
-
const payload = e.payload;
|
|
24117
|
-
this.deps.events.emit("subagent.ctx_pct", {
|
|
24118
|
-
subagentId: e.subagentId,
|
|
24119
|
-
load: payload.load,
|
|
24120
|
-
tokens: payload.tokens,
|
|
24121
|
-
maxContext: payload.maxContext
|
|
24122
|
-
});
|
|
24123
|
-
});
|
|
24124
|
-
this.director.fleet.filter("subagent.spawned", (e) => {
|
|
24125
|
-
const payload = e.payload;
|
|
24126
|
-
this.deps.events.emit("subagent.spawned", {
|
|
24127
|
-
subagentId: payload.subagentId,
|
|
24128
|
-
taskId: payload.taskId,
|
|
24129
|
-
name: payload.name,
|
|
24130
|
-
provider: payload.provider,
|
|
24131
|
-
model: payload.model
|
|
24132
|
-
});
|
|
24133
|
-
});
|
|
24134
|
-
this.getCoordinator().on(
|
|
24135
|
-
"task.assigned",
|
|
24136
|
-
({
|
|
24137
|
-
task,
|
|
24138
|
-
subagentId
|
|
24139
|
-
}) => {
|
|
24140
|
-
this.deps.events.emit("subagent.task_started", {
|
|
24141
|
-
subagentId,
|
|
24142
|
-
taskId: task.id,
|
|
24143
|
-
description: task.description
|
|
24191
|
+
this.directorOffHandles.push(
|
|
24192
|
+
this.director.fleet.filter("budget.threshold_reached", (e) => {
|
|
24193
|
+
const payload = e.payload;
|
|
24194
|
+
this.deps.events.emit("subagent.budget_warning", {
|
|
24195
|
+
subagentId: e.subagentId,
|
|
24196
|
+
kind: payload.kind,
|
|
24197
|
+
used: payload.used,
|
|
24198
|
+
limit: payload.limit
|
|
24144
24199
|
});
|
|
24145
|
-
}
|
|
24200
|
+
})
|
|
24146
24201
|
);
|
|
24202
|
+
this.directorOffHandles.push(
|
|
24203
|
+
this.director.fleet.filter("budget.extended", (e) => {
|
|
24204
|
+
const payload = e.payload;
|
|
24205
|
+
this.deps.events.emit("subagent.budget_extended", {
|
|
24206
|
+
subagentId: e.subagentId,
|
|
24207
|
+
kind: payload.kind,
|
|
24208
|
+
newLimit: payload.newLimit,
|
|
24209
|
+
totalExtensions: payload.totalExtensions
|
|
24210
|
+
});
|
|
24211
|
+
})
|
|
24212
|
+
);
|
|
24213
|
+
this.directorOffHandles.push(
|
|
24214
|
+
this.director.fleet.filter("ctx.pct", (e) => {
|
|
24215
|
+
const payload = e.payload;
|
|
24216
|
+
this.deps.events.emit("subagent.ctx_pct", {
|
|
24217
|
+
subagentId: e.subagentId,
|
|
24218
|
+
load: payload.load,
|
|
24219
|
+
tokens: payload.tokens,
|
|
24220
|
+
maxContext: payload.maxContext
|
|
24221
|
+
});
|
|
24222
|
+
})
|
|
24223
|
+
);
|
|
24224
|
+
this.directorOffHandles.push(
|
|
24225
|
+
this.director.fleet.filter("subagent.spawned", (e) => {
|
|
24226
|
+
const payload = e.payload;
|
|
24227
|
+
this.deps.events.emit("subagent.spawned", {
|
|
24228
|
+
subagentId: payload.subagentId,
|
|
24229
|
+
taskId: payload.taskId,
|
|
24230
|
+
name: payload.name,
|
|
24231
|
+
provider: payload.provider,
|
|
24232
|
+
model: payload.model
|
|
24233
|
+
});
|
|
24234
|
+
})
|
|
24235
|
+
);
|
|
24236
|
+
const coordinatorTaskAssignedHandler = ({
|
|
24237
|
+
task,
|
|
24238
|
+
subagentId
|
|
24239
|
+
}) => {
|
|
24240
|
+
this.deps.events.emit("subagent.task_started", {
|
|
24241
|
+
subagentId,
|
|
24242
|
+
taskId: task.id,
|
|
24243
|
+
description: task.description
|
|
24244
|
+
});
|
|
24245
|
+
};
|
|
24246
|
+
const coordinator = this.getCoordinator();
|
|
24247
|
+
coordinator.on("task.assigned", coordinatorTaskAssignedHandler);
|
|
24248
|
+
this.coordinatorOffHandle = () => coordinator.off("task.assigned", coordinatorTaskAssignedHandler);
|
|
24147
24249
|
this.fleetEmitTool = makeFleetEmitTool(this.director);
|
|
24148
24250
|
this.fleetStatusTool = makeFleetStatusTool(this.director);
|
|
24149
24251
|
const runner = await this.buildSubagentRunner(config);
|
|
24150
|
-
this.
|
|
24252
|
+
if (!this.directorRunnerSet) {
|
|
24253
|
+
this.getCoordinator().setRunner(runner);
|
|
24254
|
+
this.directorRunnerSet = true;
|
|
24255
|
+
}
|
|
24151
24256
|
}
|
|
24152
24257
|
/**
|
|
24153
24258
|
* Returns the FleetEmitTool for director-mode subagents, if the director
|
|
@@ -24349,9 +24454,23 @@ var MultiAgentHost = class {
|
|
|
24349
24454
|
return buildRoutingRunner(config, this);
|
|
24350
24455
|
}
|
|
24351
24456
|
async buildACPRunner(subagentId) {
|
|
24457
|
+
const cached = this.acpRunnerCache.get(subagentId);
|
|
24458
|
+
if (cached) {
|
|
24459
|
+
const idx = this.acpRunnerAccessOrder.indexOf(subagentId);
|
|
24460
|
+
if (idx !== -1) this.acpRunnerAccessOrder.splice(idx, 1);
|
|
24461
|
+
this.acpRunnerAccessOrder.push(subagentId);
|
|
24462
|
+
return cached;
|
|
24463
|
+
}
|
|
24352
24464
|
const cmd = ACP_AGENT_COMMANDS[subagentId];
|
|
24353
24465
|
if (!cmd) throw new Error(`Unknown ACP agent: ${subagentId}`);
|
|
24354
|
-
|
|
24466
|
+
while (this.acpRunnerAccessOrder.length >= _MultiAgentHost.ACP_CACHE_MAX) {
|
|
24467
|
+
const oldest = this.acpRunnerAccessOrder.shift();
|
|
24468
|
+
if (oldest) this.acpRunnerCache.delete(oldest);
|
|
24469
|
+
}
|
|
24470
|
+
const p = makeACPSubagentRunner(cmd);
|
|
24471
|
+
this.acpRunnerCache.set(subagentId, p);
|
|
24472
|
+
this.acpRunnerAccessOrder.push(subagentId);
|
|
24473
|
+
return p;
|
|
24355
24474
|
}
|
|
24356
24475
|
/**
|
|
24357
24476
|
* Build a Provider for a subagent. When `overrideId` is supplied (from
|
|
@@ -24394,6 +24513,7 @@ var MultiAgentHost = class {
|
|
|
24394
24513
|
const coordinator = this.getCoordinator();
|
|
24395
24514
|
const acpRunner = await this.buildACPRunner(subagentId);
|
|
24396
24515
|
coordinator.setRunner(acpRunner);
|
|
24516
|
+
this.directorRunnerSet = true;
|
|
24397
24517
|
await coordinator.spawn({
|
|
24398
24518
|
id: subagentId,
|
|
24399
24519
|
name: subagentId,
|
|
@@ -24463,8 +24583,9 @@ var MultiAgentHost = class {
|
|
|
24463
24583
|
*/
|
|
24464
24584
|
async spawnAndWait(description, opts) {
|
|
24465
24585
|
const { taskId } = await this.spawn(description, opts);
|
|
24466
|
-
|
|
24467
|
-
|
|
24586
|
+
const director = this.director;
|
|
24587
|
+
if (!director) throw new Error("Director is not initialized");
|
|
24588
|
+
const results = await director.awaitTasks([taskId]);
|
|
24468
24589
|
const result = results[0];
|
|
24469
24590
|
if (!result) throw new Error(`Task ${taskId} completed but no result returned`);
|
|
24470
24591
|
return result;
|
|
@@ -24678,6 +24799,24 @@ var MultiAgentHost = class {
|
|
|
24678
24799
|
this.getCoordinator().setMaxConcurrent(v);
|
|
24679
24800
|
}
|
|
24680
24801
|
}
|
|
24802
|
+
/**
|
|
24803
|
+
* Clean up all listeners and resources held by the host.
|
|
24804
|
+
* Unregisters all EventBus/FleetBus listeners registered in `buildDirector`
|
|
24805
|
+
* and stops the Director and its coordinator.
|
|
24806
|
+
*
|
|
24807
|
+
* Safe to call multiple times — subsequent calls are no-ops.
|
|
24808
|
+
*/
|
|
24809
|
+
async dispose() {
|
|
24810
|
+
for (const off of this.directorOffHandles) {
|
|
24811
|
+
off();
|
|
24812
|
+
}
|
|
24813
|
+
this.directorOffHandles.length = 0;
|
|
24814
|
+
this.coordinatorOffHandle?.();
|
|
24815
|
+
this.coordinatorOffHandle = null;
|
|
24816
|
+
if (this.director) {
|
|
24817
|
+
await this.director.shutdown();
|
|
24818
|
+
}
|
|
24819
|
+
}
|
|
24681
24820
|
};
|
|
24682
24821
|
|
|
24683
24822
|
// src/session-stats.ts
|
|
@@ -27014,6 +27153,9 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
27014
27153
|
brainMonitor.stop();
|
|
27015
27154
|
brainQueue.dispose();
|
|
27016
27155
|
void mcpRegistry.stopAll();
|
|
27156
|
+
multiAgentHost.dispose().catch(
|
|
27157
|
+
(err) => logger.warn(`multiAgentHost.dispose() failed: ${err instanceof Error ? err.message : String(err)}`)
|
|
27158
|
+
);
|
|
27017
27159
|
},
|
|
27018
27160
|
onBeforeExit: async () => {
|
|
27019
27161
|
const cwd2 = projectRoot;
|
|
@@ -27295,8 +27437,11 @@ Reply YES to auto-proceed, NO to wait for human input.`
|
|
|
27295
27437
|
brain,
|
|
27296
27438
|
brainSettings,
|
|
27297
27439
|
getBrainLog: () => brainLog,
|
|
27298
|
-
// Clean up SessionStats event listeners when the REPL exits.
|
|
27299
|
-
onDestroy: () =>
|
|
27440
|
+
// Clean up SessionStats event listeners and all EventBus handlers when the REPL exits.
|
|
27441
|
+
onDestroy: () => {
|
|
27442
|
+
teardownHandlers.forEach((fn) => fn());
|
|
27443
|
+
stats.destroy(events);
|
|
27444
|
+
}
|
|
27300
27445
|
});
|
|
27301
27446
|
}
|
|
27302
27447
|
var isMain = import.meta.url === `file://${process.argv[1]?.replace(/\\/g, "/")}` || process.argv[1]?.endsWith("/cli/dist/index.js") || process.argv[1]?.endsWith("\\cli\\dist\\index.js");
|