@wrongstack/cli 0.300.0 → 0.302.0
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/{acp-IDNS2YVE.js → acp-DATHHPNT.js} +34 -15
- package/dist/acp-server-agent.d.ts +1 -1
- package/dist/{audit-2ZSFGNIF.js → audit-QRCLEHHW.js} +5 -1
- package/dist/{auth-6T6ZOT2R.js → auth-PJD3JRH2.js} +150 -37
- package/dist/boot/dispatch-webui.d.ts +3 -16
- package/dist/boot/launch-menu.d.ts +2 -4
- package/dist/boot/tool-registry.d.ts +3 -0
- package/dist/boot/webui-session-child.d.ts +91 -0
- package/dist/chimera-reviewer-policy.d.ts +10 -3
- package/dist/chimera-work-registry.d.ts +19 -0
- package/dist/{chronicle-QQEQFSSE.js → chronicle-63MFCZN6.js} +26 -5
- package/dist/{chunk-YWUPHRGB.js → chunk-263G3FMB.js} +33 -10
- package/dist/{chunk-GYDQABMA.js → chunk-2KDOFTTM.js} +44 -32
- package/dist/{chunk-V76R7DC5.js → chunk-3MOUBRKZ.js} +311 -309
- package/dist/chunk-CSAPOCBP.js +24 -0
- package/dist/{chunk-N7ULWBO5.js → chunk-ETOEGL3V.js} +3 -7
- package/dist/{chunk-3MWUZMOL.js → chunk-GUHQQG63.js} +14 -3
- package/dist/chunk-KE7E7DPX.js +38 -0
- package/dist/{chunk-PEMN4T5O.js → chunk-MT6FGXO3.js} +23 -4
- package/dist/chunk-PFVVUH5B.js +127 -0
- package/dist/{chunk-DPJZQCVP.js → chunk-YMXXOOFN.js} +1 -1
- package/dist/{chunk-4WJKVQJY.js → chunk-ZECLGUTF.js} +15 -3
- package/dist/cli-context.d.ts +2 -0
- package/dist/{cli-main-7B3G2YSG.js → cli-main-EOJ74CI4.js} +336 -99
- package/dist/execute-deps.d.ts +3 -0
- package/dist/{execution-SHGM7BVC.js → execution-CQ772VPS.js} +246 -97
- package/dist/execution-chimera-cascade.d.ts +3 -4
- package/dist/execution-chimera-review.d.ts +2 -3
- package/dist/execution-cleanup.d.ts +3 -2
- package/dist/execution.d.ts +1 -1
- package/dist/{export-TPORYVRZ.js → export-DOBGPY23.js} +12 -1
- package/dist/fleet/host-context.d.ts +1 -1
- package/dist/fleet/host-helpers.d.ts +14 -0
- package/dist/fleet/status-broadcast.d.ts +1 -1
- package/dist/{hq-DVDD4XPV.js → hq-LN5CJHCM.js} +2 -2
- package/dist/hq-server/routes.d.ts +10 -1
- package/dist/hq-server/ws.d.ts +17 -6
- package/dist/{hq-server-DQHLNHDL.js → hq-server-S7HZG3PA.js} +3 -2
- package/dist/index.js +142 -100
- package/dist/live-settings-input.d.ts +5 -0
- package/dist/{mcp-CYLPUEHC.js → mcp-OHPJH73U.js} +6 -2
- package/dist/{modeldiag-YOQZHBQV.js → modeldiag-3DOK4BWW.js} +2 -2
- package/dist/{plugin-usage-EOG4ET4S.js → plugin-usage-YEVLOR33.js} +7 -3
- package/dist/{plugins-56CMWMPR.js → plugins-K3BAUP4D.js} +3 -3
- package/dist/profile-config-path.d.ts +0 -2
- package/dist/provider-helpers.d.ts +0 -5
- package/dist/{providers-models-K6RT7ABI.js → providers-models-WEZ4EGLL.js} +6 -5
- package/dist/{replay-KCTXNMZQ.js → replay-FCBNHW3K.js} +5 -1
- package/dist/{rewind-EJMVFVLS.js → rewind-AOD3JIYX.js} +5 -1
- package/dist/{sessions-config-NLCMK3BY.js → sessions-config-XXN7267N.js} +8 -3
- package/dist/subcommands/flags.d.ts +23 -0
- package/dist/terminal-format.d.ts +15 -0
- package/dist/{webui-server-G3EKFXLL.js → webui-server-NFNRGNNT.js} +54 -29
- package/dist/webui-server-options.d.ts +7 -0
- package/dist/wiring/brain-and-orchestration.d.ts +1 -1
- package/dist/wiring/mailbox-bridge-bootstrap.d.ts +3 -1
- package/dist/wiring/management-tools.d.ts +9 -1
- package/dist/wiring/pipeline.d.ts +5 -5
- package/dist/wiring/plugins.d.ts +2 -3
- package/dist/wiring/provider-utility-tools.d.ts +1 -0
- package/dist/wiring/tools.d.ts +4 -5
- package/package.json +23 -23
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
setupPlugins
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZECLGUTF.js";
|
|
4
4
|
import {
|
|
5
5
|
runProjectPicker
|
|
6
6
|
} from "./chunk-5N34EWJR.js";
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
import {
|
|
44
44
|
PLUGIN_AUDIT_ENTRIES,
|
|
45
45
|
runPluginManagementCommand
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-GUHQQG63.js";
|
|
47
47
|
import {
|
|
48
48
|
configureSimpleUiRuntimeContext,
|
|
49
49
|
detectProjectFacts,
|
|
@@ -80,15 +80,15 @@ import {
|
|
|
80
80
|
runClaudeOAuthLogin,
|
|
81
81
|
runCopilotOAuthLogin,
|
|
82
82
|
validateFamily
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-3MOUBRKZ.js";
|
|
84
84
|
import {
|
|
85
85
|
LOCAL_LLM_PRESETS,
|
|
86
86
|
parseSpawnFlags
|
|
87
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-MT6FGXO3.js";
|
|
88
88
|
import {
|
|
89
89
|
buildPickableProviders,
|
|
90
90
|
visibleModelIds
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-ETOEGL3V.js";
|
|
92
92
|
import {
|
|
93
93
|
runCodexOAuthLogin
|
|
94
94
|
} from "./chunk-PYTFS4MC.js";
|
|
@@ -102,10 +102,10 @@ import {
|
|
|
102
102
|
} from "./chunk-PJHET45A.js";
|
|
103
103
|
import {
|
|
104
104
|
appendHistory
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-263G3FMB.js";
|
|
106
106
|
import {
|
|
107
107
|
activeProfileConfigPath
|
|
108
|
-
} from "./chunk-
|
|
108
|
+
} from "./chunk-YMXXOOFN.js";
|
|
109
109
|
import {
|
|
110
110
|
__require
|
|
111
111
|
} from "./chunk-7OCVIDC7.js";
|
|
@@ -1567,6 +1567,7 @@ function registerBuiltinTools(deps) {
|
|
|
1567
1567
|
tier,
|
|
1568
1568
|
contextTool: createContextManagerTool({ compactor: deps.compactor }),
|
|
1569
1569
|
memory: { enabled: deps.config.features.memory, store: deps.memoryStore },
|
|
1570
|
+
nextSteps: { enabled: deps.config.tools?.nextsteps?.enabled === true },
|
|
1570
1571
|
coordinationTools: [
|
|
1571
1572
|
makeMailboxTool({ projectDir: deps.wpaths.projectDir, events: deps.events }),
|
|
1572
1573
|
makeMailSendTool({ projectDir: deps.wpaths.projectDir, events: deps.events }),
|
|
@@ -2782,6 +2783,9 @@ import {
|
|
|
2782
2783
|
} from "@wrongstack/core/execution";
|
|
2783
2784
|
import { TOKENS as TOKENS6 } from "@wrongstack/core/kernel";
|
|
2784
2785
|
import { createMcpControlTool, createMcpUseTool } from "@wrongstack/core/tools";
|
|
2786
|
+
import {
|
|
2787
|
+
normalizeTokenSavingTier as normalizeTokenSavingTier2
|
|
2788
|
+
} from "@wrongstack/core/types";
|
|
2785
2789
|
|
|
2786
2790
|
// src/boot/brain-decision-log.ts
|
|
2787
2791
|
var MAX_BRAIN_LOG_ENTRIES = 20;
|
|
@@ -2876,9 +2880,7 @@ import { wstackGlobalRoot } from "@wrongstack/core/utils";
|
|
|
2876
2880
|
|
|
2877
2881
|
// src/fleet/host-helpers.ts
|
|
2878
2882
|
import * as path2 from "node:path";
|
|
2879
|
-
import {
|
|
2880
|
-
makeSubagentResultTool
|
|
2881
|
-
} from "@wrongstack/core/coordination";
|
|
2883
|
+
import { makeSubagentResultTool } from "@wrongstack/core/coordination";
|
|
2882
2884
|
import { ToolCapabilities, WIDE_SUBAGENT_CAPABILITIES } from "@wrongstack/core/security";
|
|
2883
2885
|
import { makePreferSideConflictResolver } from "@wrongstack/sdd";
|
|
2884
2886
|
function isInsideDirectory(root, candidate) {
|
|
@@ -2954,10 +2956,13 @@ var DEFAULT_SUBAGENT_HIDDEN_TOOLS = /* @__PURE__ */ new Set([
|
|
|
2954
2956
|
"collab_debug",
|
|
2955
2957
|
"fleet_emit"
|
|
2956
2958
|
]);
|
|
2959
|
+
var NEVER_SUBAGENT_TOOLS = /* @__PURE__ */ new Set(["nextsteps"]);
|
|
2957
2960
|
function selectSubagentTools(allTools, directorToolsByName, allow) {
|
|
2958
2961
|
if (!allow || allow.length === 0) {
|
|
2959
2962
|
const visible = new Map(
|
|
2960
|
-
allTools.filter(
|
|
2963
|
+
allTools.filter(
|
|
2964
|
+
(tool) => !DEFAULT_SUBAGENT_HIDDEN_TOOLS.has(tool.name) && !NEVER_SUBAGENT_TOOLS.has(tool.name)
|
|
2965
|
+
).map((tool) => [tool.name, tool])
|
|
2961
2966
|
);
|
|
2962
2967
|
visible.set("submit_result", makeSubagentResultTool());
|
|
2963
2968
|
return Array.from(visible.values());
|
|
@@ -2965,12 +2970,20 @@ function selectSubagentTools(allTools, directorToolsByName, allow) {
|
|
|
2965
2970
|
const allowSet = new Set(allow);
|
|
2966
2971
|
const result = /* @__PURE__ */ new Map();
|
|
2967
2972
|
for (const tool of allTools) {
|
|
2968
|
-
if (allowSet.has(tool.name)
|
|
2973
|
+
if (allowSet.has(tool.name) && !NEVER_SUBAGENT_TOOLS.has(tool.name))
|
|
2974
|
+
result.set(tool.name, tool);
|
|
2969
2975
|
}
|
|
2970
2976
|
for (const name of allowSet) {
|
|
2977
|
+
if (NEVER_SUBAGENT_TOOLS.has(name)) continue;
|
|
2971
2978
|
const directorTool = directorToolsByName.get(name);
|
|
2972
2979
|
if (directorTool && !result.has(name)) result.set(name, directorTool);
|
|
2973
2980
|
}
|
|
2981
|
+
const missing = [...allowSet].filter(
|
|
2982
|
+
(name) => !NEVER_SUBAGENT_TOOLS.has(name) && !result.has(name)
|
|
2983
|
+
);
|
|
2984
|
+
if (missing.length > 0) {
|
|
2985
|
+
throw new Error(`Subagent tool contract is not registered: ${missing.sort().join(", ")}`);
|
|
2986
|
+
}
|
|
2974
2987
|
result.set("submit_result", makeSubagentResultTool());
|
|
2975
2988
|
return Array.from(result.values());
|
|
2976
2989
|
}
|
|
@@ -3351,7 +3364,8 @@ import {
|
|
|
3351
3364
|
Agent,
|
|
3352
3365
|
Context,
|
|
3353
3366
|
createDefaultPipelines,
|
|
3354
|
-
createFallbackModelExtension
|
|
3367
|
+
createFallbackModelExtension,
|
|
3368
|
+
renderInstructionLayer
|
|
3355
3369
|
} from "@wrongstack/core/agent";
|
|
3356
3370
|
import {
|
|
3357
3371
|
applyProjectAgentConfig,
|
|
@@ -3376,9 +3390,14 @@ import { EventBus } from "@wrongstack/core/kernel";
|
|
|
3376
3390
|
import { AutoApprovePermissionPolicy } from "@wrongstack/core/security";
|
|
3377
3391
|
|
|
3378
3392
|
// src/fleet/host-context.ts
|
|
3393
|
+
import {
|
|
3394
|
+
missingRequiredRuntimeTools,
|
|
3395
|
+
missingRuntimeCapabilities,
|
|
3396
|
+
runtimeToolReferencesFromText
|
|
3397
|
+
} from "@wrongstack/core/agent-catalog";
|
|
3379
3398
|
import { TOKENS as TOKENS2 } from "@wrongstack/core/kernel";
|
|
3380
3399
|
import { getSageRetrieval } from "@wrongstack/sage";
|
|
3381
|
-
async function resolveHostSubagentSkillContent(deps, roster, subCfg) {
|
|
3400
|
+
async function resolveHostSubagentSkillContent(deps, roster, subCfg, availableToolNames = []) {
|
|
3382
3401
|
const rosterSkillNames = subCfg.role ? roster[subCfg.role]?.skillNames : void 0;
|
|
3383
3402
|
const skillNames = [...new Set(subCfg.skillNames ?? rosterSkillNames ?? [])];
|
|
3384
3403
|
const directContent = subCfg.skillContent?.trim();
|
|
@@ -3391,8 +3410,14 @@ async function resolveHostSubagentSkillContent(deps, roster, subCfg) {
|
|
|
3391
3410
|
try {
|
|
3392
3411
|
const manifest = await deps.skillLoader.find(skillName);
|
|
3393
3412
|
if (!manifest) continue;
|
|
3413
|
+
if (missingRuntimeCapabilities(manifest.requiredCapabilities, availableToolNames).length > 0 || missingRequiredRuntimeTools(manifest.requiredTools, availableToolNames).length > 0) {
|
|
3414
|
+
continue;
|
|
3415
|
+
}
|
|
3394
3416
|
const body = (await deps.skillLoader.readSaveBody(skillName)).trim();
|
|
3395
3417
|
if (!body) continue;
|
|
3418
|
+
if (missingRequiredRuntimeTools(runtimeToolReferencesFromText(body), availableToolNames).length > 0) {
|
|
3419
|
+
continue;
|
|
3420
|
+
}
|
|
3396
3421
|
const entry = `## Skill: ${skillName}
|
|
3397
3422
|
|
|
3398
3423
|
${body.slice(0, maxCharsPerSkill)}`;
|
|
@@ -3808,16 +3833,26 @@ ${message} Falling back to the assigned checkout.` : `${message} Falling back to
|
|
|
3808
3833
|
onlineAgents = await subagentMailbox.getAgentStatuses();
|
|
3809
3834
|
} catch {
|
|
3810
3835
|
}
|
|
3836
|
+
const subagentTools = host.filterTools(effectiveCfg.tools);
|
|
3811
3837
|
const baseSystem = await host.deps.systemPromptBuilder.build({
|
|
3812
3838
|
cwd: subCwd,
|
|
3813
3839
|
projectRoot: host.deps.projectRoot,
|
|
3814
|
-
tools:
|
|
3840
|
+
tools: subagentTools,
|
|
3841
|
+
catalogTools: subagentTools,
|
|
3815
3842
|
model: effModel,
|
|
3816
3843
|
provider: effProvider,
|
|
3817
3844
|
subagent: true,
|
|
3818
3845
|
onlineAgents
|
|
3819
3846
|
});
|
|
3820
|
-
baseSystem.unshift({
|
|
3847
|
+
baseSystem.unshift({
|
|
3848
|
+
type: "text",
|
|
3849
|
+
text: renderInstructionLayer(DEFAULT_SUBAGENT_BASELINE, {
|
|
3850
|
+
toolNames: new Set(subagentTools.map((tool) => tool.name)),
|
|
3851
|
+
tier: "off",
|
|
3852
|
+
subagent: true,
|
|
3853
|
+
strictToolReferences: true
|
|
3854
|
+
})
|
|
3855
|
+
});
|
|
3821
3856
|
if (availabilityNotice) baseSystem.push({ type: "text", text: availabilityNotice });
|
|
3822
3857
|
const audienceMemory = await retrieveHostSubagentMemory(
|
|
3823
3858
|
host.deps,
|
|
@@ -3835,7 +3870,8 @@ ${audienceMemory.map((text) => `- ${text}`).join("\n")}`
|
|
|
3835
3870
|
const roleSkillContent = await resolveHostSubagentSkillContent(
|
|
3836
3871
|
host.deps,
|
|
3837
3872
|
host.roster,
|
|
3838
|
-
effectiveCfg
|
|
3873
|
+
effectiveCfg,
|
|
3874
|
+
subagentTools.map((tool) => tool.name)
|
|
3839
3875
|
);
|
|
3840
3876
|
if (roleSkillContent) {
|
|
3841
3877
|
for (let index = baseSystem.length - 1; index >= 0; index--) {
|
|
@@ -3882,7 +3918,8 @@ ${audienceMemory.map((text) => `- ${text}`).join("\n")}`
|
|
|
3882
3918
|
projectRoot: host.deps.projectRoot,
|
|
3883
3919
|
allowOutsideProjectRoot: config.features?.allowOutsideProjectRoot ?? !(config.tools?.restrictToProjectRoot ?? false),
|
|
3884
3920
|
model: effModel,
|
|
3885
|
-
tools:
|
|
3921
|
+
tools: subagentTools,
|
|
3922
|
+
catalogTools: subagentTools,
|
|
3886
3923
|
agentId: subagentName,
|
|
3887
3924
|
agentName: effectiveCfg.name ?? subagentName
|
|
3888
3925
|
});
|
|
@@ -4135,6 +4172,9 @@ import {
|
|
|
4135
4172
|
var DEFAULT_MIN_INTERVAL_MS = 15e3;
|
|
4136
4173
|
var DEFAULT_GLOBAL_PER_MINUTE = 20;
|
|
4137
4174
|
var BODY_MAX = 200;
|
|
4175
|
+
function isSilentInfrastructureAgent(name) {
|
|
4176
|
+
return name.trim().toLowerCase() === "chimera-review";
|
|
4177
|
+
}
|
|
4138
4178
|
function createFleetStatusBroadcaster(opts) {
|
|
4139
4179
|
const cfg = opts.config;
|
|
4140
4180
|
const minIntervalMs = cfg?.minIntervalMsPerAgent ?? DEFAULT_MIN_INTERVAL_MS;
|
|
@@ -4154,6 +4194,7 @@ function createFleetStatusBroadcaster(opts) {
|
|
|
4154
4194
|
let droppedSinceLastSend = 0;
|
|
4155
4195
|
const announcedSpawn = /* @__PURE__ */ new Set();
|
|
4156
4196
|
const announcedBudget = /* @__PURE__ */ new Set();
|
|
4197
|
+
const silentInfrastructureAgents = /* @__PURE__ */ new Set();
|
|
4157
4198
|
const disposers = [];
|
|
4158
4199
|
let stopped = false;
|
|
4159
4200
|
function underGlobalCap(now) {
|
|
@@ -4218,9 +4259,14 @@ function createFleetStatusBroadcaster(opts) {
|
|
|
4218
4259
|
opts.events.on("subagent.spawned", (e) => {
|
|
4219
4260
|
if (announcedSpawn.has(e.subagentId)) return;
|
|
4220
4261
|
announcedSpawn.add(e.subagentId);
|
|
4262
|
+
const name = e.name ?? nameOf(e.subagentId);
|
|
4263
|
+
if (isSilentInfrastructureAgent(name)) {
|
|
4264
|
+
silentInfrastructureAgents.add(e.subagentId);
|
|
4265
|
+
return;
|
|
4266
|
+
}
|
|
4221
4267
|
broadcast(e.subagentId, {
|
|
4222
|
-
subject: `[${
|
|
4223
|
-
body: `${
|
|
4268
|
+
subject: `[${name}] joined the fleet`,
|
|
4269
|
+
body: `${name} spawned${e.model ? ` on ${e.model}` : ""}${e.description ? ` \u2014 ${e.description.slice(0, 80)}` : ""}`,
|
|
4224
4270
|
priority: "low"
|
|
4225
4271
|
});
|
|
4226
4272
|
}),
|
|
@@ -4234,6 +4280,9 @@ function createFleetStatusBroadcaster(opts) {
|
|
|
4234
4280
|
opts.events.on("subagent.task_completed", (e) => {
|
|
4235
4281
|
heartbeat({ agentId: e.subagentId, status: "idle" });
|
|
4236
4282
|
const name = nameOf(e.subagentId);
|
|
4283
|
+
if (silentInfrastructureAgents.has(e.subagentId) || isSilentInfrastructureAgent(name)) {
|
|
4284
|
+
return;
|
|
4285
|
+
}
|
|
4237
4286
|
const ok = e.status === "success";
|
|
4238
4287
|
const secs = Math.round(e.durationMs / 1e3);
|
|
4239
4288
|
broadcast(e.subagentId, {
|
|
@@ -4244,6 +4293,9 @@ function createFleetStatusBroadcaster(opts) {
|
|
|
4244
4293
|
}),
|
|
4245
4294
|
opts.events.on("subagent.budget_warning", (e) => {
|
|
4246
4295
|
if (!broadcastBudgetWarnings) return;
|
|
4296
|
+
if (silentInfrastructureAgents.has(e.subagentId) || isSilentInfrastructureAgent(nameOf(e.subagentId))) {
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4247
4299
|
const key = `${e.subagentId}|${e.kind}`;
|
|
4248
4300
|
if (announcedBudget.has(key)) return;
|
|
4249
4301
|
announcedBudget.add(key);
|
|
@@ -4270,6 +4322,7 @@ function createFleetStatusBroadcaster(opts) {
|
|
|
4270
4322
|
void mb().deregisterAgent(e.subagentId).catch(() => {
|
|
4271
4323
|
});
|
|
4272
4324
|
announcedSpawn.delete(e.subagentId);
|
|
4325
|
+
silentInfrastructureAgents.delete(e.subagentId);
|
|
4273
4326
|
lastSentAt.delete(e.subagentId);
|
|
4274
4327
|
for (const key of announcedBudget) {
|
|
4275
4328
|
if (key.startsWith(`${e.subagentId}|`)) announcedBudget.delete(key);
|
|
@@ -5530,6 +5583,7 @@ function setupBrainAndOrchestration(deps) {
|
|
|
5530
5583
|
events
|
|
5531
5584
|
})
|
|
5532
5585
|
);
|
|
5586
|
+
toolRegistry.exposeToProvider("delegate");
|
|
5533
5587
|
toolRegistry.register(
|
|
5534
5588
|
createMcpControlTool({
|
|
5535
5589
|
getConfig: () => configStore.get(),
|
|
@@ -5537,13 +5591,17 @@ function setupBrainAndOrchestration(deps) {
|
|
|
5537
5591
|
registry: mcpRegistry
|
|
5538
5592
|
})
|
|
5539
5593
|
);
|
|
5540
|
-
if (config.features.tokenSavingMode) {
|
|
5541
|
-
toolRegistry.
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5594
|
+
if (normalizeTokenSavingTier2(config.features.tokenSavingMode) !== "off") {
|
|
5595
|
+
toolRegistry.exposeToProvider("mcp_control");
|
|
5596
|
+
}
|
|
5597
|
+
toolRegistry.register(
|
|
5598
|
+
createMcpUseTool({
|
|
5599
|
+
registry: mcpRegistry,
|
|
5600
|
+
toolRegistry
|
|
5601
|
+
})
|
|
5602
|
+
);
|
|
5603
|
+
if (normalizeTokenSavingTier2(config.features.tokenSavingMode) !== "off") {
|
|
5604
|
+
toolRegistry.exposeToProvider("mcp_use");
|
|
5547
5605
|
}
|
|
5548
5606
|
return {
|
|
5549
5607
|
brain,
|
|
@@ -6940,7 +6998,7 @@ import { NotifierImpl } from "@wrongstack/core/notifications";
|
|
|
6940
6998
|
import {
|
|
6941
6999
|
SlashCommandRegistry
|
|
6942
7000
|
} from "@wrongstack/core/registry";
|
|
6943
|
-
import { normalizeTokenSavingTier as
|
|
7001
|
+
import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
|
|
6944
7002
|
import {
|
|
6945
7003
|
createVaultBackedMcpAuthorizationProviderFactory,
|
|
6946
7004
|
MCPAuthorizationManager,
|
|
@@ -7212,13 +7270,19 @@ function setupMetrics(params) {
|
|
|
7212
7270
|
}
|
|
7213
7271
|
|
|
7214
7272
|
// src/wiring/pipeline.ts
|
|
7215
|
-
import {
|
|
7216
|
-
|
|
7217
|
-
|
|
7273
|
+
import {
|
|
7274
|
+
Agent as Agent2,
|
|
7275
|
+
createDefaultPipelines as createDefaultPipelines2
|
|
7276
|
+
} from "@wrongstack/core/agent";
|
|
7277
|
+
import {
|
|
7278
|
+
AutoCompactionMiddleware,
|
|
7279
|
+
applyModelRuntime as applyModelRuntime2,
|
|
7280
|
+
ToolExecutor as ToolExecutor2
|
|
7281
|
+
} from "@wrongstack/core/execution";
|
|
7218
7282
|
import { TOKENS as TOKENS7 } from "@wrongstack/core/kernel";
|
|
7219
|
-
import {
|
|
7283
|
+
import { createSessionEventBridge as createSessionEventBridge2, resolveAuditLevel } from "@wrongstack/core/storage";
|
|
7220
7284
|
import { resolveContextWindowPolicy } from "@wrongstack/core/types";
|
|
7221
|
-
import {
|
|
7285
|
+
import { estimateRequestTokensCalibrated } from "@wrongstack/core/utils";
|
|
7222
7286
|
|
|
7223
7287
|
// src/wiring/mailbox-bridge-bootstrap.ts
|
|
7224
7288
|
import { resolveProjectDir as resolveProjectDir2 } from "@wrongstack/core/coordination";
|
|
@@ -7330,7 +7394,7 @@ async function bootstrapMailboxBridgeAtStartup(params) {
|
|
|
7330
7394
|
if (!params.projectRoot) {
|
|
7331
7395
|
return null;
|
|
7332
7396
|
}
|
|
7333
|
-
const mode = params.config?.features?.mailboxBridge ?? "
|
|
7397
|
+
const mode = params.config?.features?.mailboxBridge ?? "off";
|
|
7334
7398
|
if (mode === "off") {
|
|
7335
7399
|
return null;
|
|
7336
7400
|
}
|
|
@@ -7352,10 +7416,10 @@ async function bootstrapMailboxBridgeAtStartup(params) {
|
|
|
7352
7416
|
switch (handle.source) {
|
|
7353
7417
|
case "joined":
|
|
7354
7418
|
case "spawned":
|
|
7355
|
-
params.logger.debug(
|
|
7356
|
-
|
|
7357
|
-
|
|
7358
|
-
);
|
|
7419
|
+
params.logger.debug(`mailbox bridge ready via ${handle.source} on ${params.source} boot`, {
|
|
7420
|
+
url: handle.url,
|
|
7421
|
+
lockPath: handle.lockPath
|
|
7422
|
+
});
|
|
7359
7423
|
break;
|
|
7360
7424
|
case "unhealthy":
|
|
7361
7425
|
params.logger.warn(
|
|
@@ -7587,7 +7651,8 @@ function registerProviderUtilityTools(input) {
|
|
|
7587
7651
|
getConfig: input.getConfig,
|
|
7588
7652
|
fallbackProfileManager: input.fallbackProfileManager,
|
|
7589
7653
|
defaultProvider: config.provider,
|
|
7590
|
-
defaultModel: config.model
|
|
7654
|
+
defaultModel: config.model,
|
|
7655
|
+
wrapProviderCall: input.wrapProviderCall
|
|
7591
7656
|
});
|
|
7592
7657
|
registerOrOverride(input.toolRegistry, "llm", llmTool);
|
|
7593
7658
|
const councilOrchestrator = new OneShotOrchestrator({
|
|
@@ -7600,7 +7665,8 @@ function registerProviderUtilityTools(input) {
|
|
|
7600
7665
|
// router those hints were inert: every seat fell through to the session
|
|
7601
7666
|
// provider/model, so a three-seat panel asked one model three times and
|
|
7602
7667
|
// reported a distinctness warning on every single call.
|
|
7603
|
-
modelRouter: createLiveModelRouter(input.getConfig)
|
|
7668
|
+
modelRouter: createLiveModelRouter(input.getConfig),
|
|
7669
|
+
wrapProviderCall: input.wrapProviderCall
|
|
7604
7670
|
});
|
|
7605
7671
|
registerOrOverride(
|
|
7606
7672
|
input.toolRegistry,
|
|
@@ -7616,7 +7682,8 @@ function registerProviderUtilityTools(input) {
|
|
|
7616
7682
|
buildProvider: input.buildProvider,
|
|
7617
7683
|
getConfig: input.getConfig,
|
|
7618
7684
|
fallbackProfileManager: input.fallbackProfileManager,
|
|
7619
|
-
statusTracker: input.statusTracker
|
|
7685
|
+
statusTracker: input.statusTracker,
|
|
7686
|
+
wrapProviderCall: input.wrapProviderCall
|
|
7620
7687
|
});
|
|
7621
7688
|
input.toolRegistry.override(
|
|
7622
7689
|
"context_manager",
|
|
@@ -7801,7 +7868,7 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7801
7868
|
toolRegistry,
|
|
7802
7869
|
events,
|
|
7803
7870
|
log: logger,
|
|
7804
|
-
lazyMode:
|
|
7871
|
+
lazyMode: normalizeTokenSavingTier3(config.features.tokenSavingMode) !== "off",
|
|
7805
7872
|
cacheDir: wpaths.cacheDir,
|
|
7806
7873
|
authorizationProviderFactory: createVaultBackedMcpAuthorizationProviderFactory({
|
|
7807
7874
|
store: mcpTokenStore
|
|
@@ -7837,7 +7904,15 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7837
7904
|
fallbackProfileManager,
|
|
7838
7905
|
statusTracker,
|
|
7839
7906
|
modelRouter: createLiveModelRouter(getLiveConfig),
|
|
7840
|
-
logger
|
|
7907
|
+
logger,
|
|
7908
|
+
// Route plugin completions through the same extension chain the agent loop
|
|
7909
|
+
// uses. `prompt-firewall` (credential redaction), `llm-cache`,
|
|
7910
|
+
// `model-router` and the token budgeter all live on `wrapProviderRunner`,
|
|
7911
|
+
// and `api.llm` reached the provider without any of them. Resolved per
|
|
7912
|
+
// call so a plugin enabled mid-session joins the chain.
|
|
7913
|
+
wrapProviderCall: (request, inner) => agent.extensions.wrapProviderRunner((_ctx, req) => inner(req), {
|
|
7914
|
+
exclude: ["fallback-model"]
|
|
7915
|
+
})(agent.ctx, request)
|
|
7841
7916
|
});
|
|
7842
7917
|
const pluginCouncil = new CouncilOrchestrator({
|
|
7843
7918
|
caller: pluginOneShot,
|
|
@@ -7907,12 +7982,16 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
7907
7982
|
|
|
7908
7983
|
// src/wiring/management-tools.ts
|
|
7909
7984
|
import * as fs5 from "node:fs/promises";
|
|
7910
|
-
import {
|
|
7985
|
+
import {
|
|
7986
|
+
createFallbackManageTools,
|
|
7987
|
+
createPluginManagerTool
|
|
7988
|
+
} from "@wrongstack/core/tools";
|
|
7911
7989
|
function registerCliManagementTools({
|
|
7912
7990
|
toolRegistry,
|
|
7913
7991
|
configStore,
|
|
7914
7992
|
profileConfigPath,
|
|
7915
|
-
stdinInteractive
|
|
7993
|
+
stdinInteractive,
|
|
7994
|
+
getHookRunner
|
|
7916
7995
|
}) {
|
|
7917
7996
|
const fallbackManageTools = createFallbackManageTools({
|
|
7918
7997
|
getConfig: () => configStore.get(),
|
|
@@ -7942,6 +8021,7 @@ ${prompt}
|
|
|
7942
8021
|
for (const tool of fallbackManageTools) toolRegistry.register(tool);
|
|
7943
8022
|
toolRegistry.register(
|
|
7944
8023
|
createPluginManagerTool({
|
|
8024
|
+
...getHookRunner ? { getHookRunner } : {},
|
|
7945
8025
|
getConfig: () => configStore.get(),
|
|
7946
8026
|
catalog: PLUGIN_AUDIT_ENTRIES.map((entry) => {
|
|
7947
8027
|
const aliases = [
|
|
@@ -8158,19 +8238,34 @@ function setupProviderRuntime(deps) {
|
|
|
8158
8238
|
if (process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
|
|
8159
8239
|
const activeProfile = typeof cfg.activeProfile === "string" && cfg.activeProfile ? cfg.activeProfile : "default";
|
|
8160
8240
|
const configLayers = [
|
|
8161
|
-
{ path: wpaths.profileConfig(activeProfile), priority: 1 },
|
|
8162
|
-
{ path: wpaths.projectLocalConfig, priority: 2 },
|
|
8163
|
-
{ path: wpaths.inProjectConfig, priority: 3 }
|
|
8241
|
+
{ path: wpaths.profileConfig(activeProfile), priority: 1, trusted: true },
|
|
8242
|
+
{ path: wpaths.projectLocalConfig, priority: 2, trusted: true },
|
|
8243
|
+
{ path: wpaths.inProjectConfig, priority: 3, trusted: false }
|
|
8164
8244
|
];
|
|
8245
|
+
const sanitizeUntrustedSnapshot = (snap, path32) => {
|
|
8246
|
+
const { providers, apiKey, baseUrl, ...rest } = snap;
|
|
8247
|
+
const dropped = [
|
|
8248
|
+
...Object.keys(providers ?? {}).length > 0 ? ["providers"] : [],
|
|
8249
|
+
...apiKey !== void 0 ? ["apiKey"] : [],
|
|
8250
|
+
...baseUrl !== void 0 ? ["baseUrl"] : []
|
|
8251
|
+
];
|
|
8252
|
+
if (dropped.length > 0) {
|
|
8253
|
+
logger.warn(
|
|
8254
|
+
`Config watcher: ignored credential field(s) from the repo-committed config "${path32}": ${dropped.join(", ")}. Only your profile config may set these.`
|
|
8255
|
+
);
|
|
8256
|
+
}
|
|
8257
|
+
return { ...rest, providers: {}, snapshotHasProviders: false };
|
|
8258
|
+
};
|
|
8165
8259
|
const readMergedSnapshot = async () => {
|
|
8166
8260
|
let merged;
|
|
8167
8261
|
for (const layer of configLayers.sort((a, b) => a.priority - b.priority)) {
|
|
8168
|
-
const
|
|
8262
|
+
const raw = await readProviderSnapshot(
|
|
8169
8263
|
layer.path,
|
|
8170
8264
|
vault,
|
|
8171
8265
|
(msg) => logger.warn(`Config watcher (${layer.path}): ${msg}`)
|
|
8172
8266
|
);
|
|
8173
|
-
if (!
|
|
8267
|
+
if (!raw) continue;
|
|
8268
|
+
const snap = layer.trusted ? raw : sanitizeUntrustedSnapshot(raw, layer.path);
|
|
8174
8269
|
if (!merged) {
|
|
8175
8270
|
merged = {
|
|
8176
8271
|
...snap,
|
|
@@ -10836,15 +10931,16 @@ ${color13.dim("YOLO enabled; tool calls run without approval unless an explicit
|
|
|
10836
10931
|
// src/slash-commands/brain.ts
|
|
10837
10932
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
10838
10933
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
10934
|
+
import { parseModelRef } from "@wrongstack/core/agent";
|
|
10839
10935
|
import { BUILTIN_COUNCIL_PERSONA_IDS, BUILTIN_COUNCIL_PERSONAS } from "@wrongstack/core/execution";
|
|
10840
10936
|
import { color as color14 } from "@wrongstack/core/utils";
|
|
10841
|
-
import { parseModelRef } from "@wrongstack/core/agent";
|
|
10842
10937
|
var RISK_LEVELS = /* @__PURE__ */ new Set(["off", "low", "medium", "high", "all"]);
|
|
10843
10938
|
var COUNCIL_RISKS = /* @__PURE__ */ new Set(["medium", "high", "critical"]);
|
|
10844
10939
|
var COUNCIL_DISTINCTNESS = /* @__PURE__ */ new Set(["none", "model", "provider"]);
|
|
10845
10940
|
var COUNCIL_NUMERIC_OPS = {
|
|
10846
10941
|
timeout: "perCallTimeoutMs",
|
|
10847
10942
|
concurrency: "maxConcurrency",
|
|
10943
|
+
votertokens: "voterMaxTokens",
|
|
10848
10944
|
judgetokens: "judgeMaxTokens"
|
|
10849
10945
|
};
|
|
10850
10946
|
var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
|
|
@@ -10859,7 +10955,14 @@ var DENY_TERMINAL_VALUES = ["never", "when-decided", "always"];
|
|
|
10859
10955
|
var TRACE_CONTENT_VALUES = ["none", "redacted", "full"];
|
|
10860
10956
|
var TERMINAL_POLICY_VALUES = ["conservative", "deny-all", "continue-on-recommended"];
|
|
10861
10957
|
var MONITOR_POLICY_VALUES = ["llm", "steer", "observe"];
|
|
10862
|
-
var DETERMINISTIC_TIER_NAMES = [
|
|
10958
|
+
var DETERMINISTIC_TIER_NAMES = [
|
|
10959
|
+
"rule",
|
|
10960
|
+
"policy",
|
|
10961
|
+
"heuristic",
|
|
10962
|
+
"cache",
|
|
10963
|
+
"ledger-guard",
|
|
10964
|
+
"terminal"
|
|
10965
|
+
];
|
|
10863
10966
|
function parseRefEntry(ref) {
|
|
10864
10967
|
const parsed = parseModelRef(ref);
|
|
10865
10968
|
const model = parsed.model?.trim();
|
|
@@ -10927,7 +11030,7 @@ function buildBrainCommand(opts) {
|
|
|
10927
11030
|
" /brain council personas List the built-in decision lenses",
|
|
10928
11031
|
" /brain council judge <ref|auto> | quorum <0..1> | approval <0..1>",
|
|
10929
11032
|
" /brain council distinctness <none|model|provider> warn on a non-diverse panel",
|
|
10930
|
-
" /brain council timeout|concurrency|judgetokens <n|default>",
|
|
11033
|
+
" /brain council timeout|concurrency|votertokens|judgetokens <n|default>",
|
|
10931
11034
|
" /brain ledger [n] Show the last n rows (default 15) of the persistent decision ledger",
|
|
10932
11035
|
" /brain ledger on|off | autodeny <n>",
|
|
10933
11036
|
" /brain stats Per-tier decision counts: how often the Brain actually calls a model",
|
|
@@ -11039,7 +11142,10 @@ function buildBrainCommand(opts) {
|
|
|
11039
11142
|
return { message: msg2 };
|
|
11040
11143
|
}
|
|
11041
11144
|
if (ref.toLowerCase() === "session") {
|
|
11042
|
-
return applyPatch(
|
|
11145
|
+
return applyPatch(
|
|
11146
|
+
{ models: null },
|
|
11147
|
+
(s) => `Brain decision model: ${color14.cyan("session model")} (pool cleared)${s.councilLabels.length === 0 ? "" : " \u2014 council dissolved"}`
|
|
11148
|
+
);
|
|
11043
11149
|
}
|
|
11044
11150
|
return applyPatch(
|
|
11045
11151
|
{ models: [ref] },
|
|
@@ -11055,7 +11161,10 @@ function buildBrainCommand(opts) {
|
|
|
11055
11161
|
return { message: msg2 };
|
|
11056
11162
|
}
|
|
11057
11163
|
if (op === "clear") {
|
|
11058
|
-
return applyPatch(
|
|
11164
|
+
return applyPatch(
|
|
11165
|
+
{ models: null },
|
|
11166
|
+
() => `Brain LLM pool cleared \u2014 using the ${color14.cyan("session model")}`
|
|
11167
|
+
);
|
|
11059
11168
|
}
|
|
11060
11169
|
if (op === "add") {
|
|
11061
11170
|
const ref = rest[1];
|
|
@@ -11065,7 +11174,10 @@ function buildBrainCommand(opts) {
|
|
|
11065
11174
|
return { message: msg2 };
|
|
11066
11175
|
}
|
|
11067
11176
|
const current = (snapshot?.models ?? []).map(compactEntry);
|
|
11068
|
-
return applyPatch(
|
|
11177
|
+
return applyPatch(
|
|
11178
|
+
{ models: [...current, ref] },
|
|
11179
|
+
(s) => `Brain LLM pool: ${color14.cyan(poolSummary(s))}`
|
|
11180
|
+
);
|
|
11069
11181
|
}
|
|
11070
11182
|
if (op === "remove") {
|
|
11071
11183
|
const target = rest[1];
|
|
@@ -11075,16 +11187,24 @@ function buildBrainCommand(opts) {
|
|
|
11075
11187
|
return { message: msg2 };
|
|
11076
11188
|
}
|
|
11077
11189
|
const current = snapshot.models.map(compactEntry);
|
|
11078
|
-
const idx = /^\d+$/.test(target) ? Number.parseInt(target, 10) - 1 : current.findIndex(
|
|
11190
|
+
const idx = /^\d+$/.test(target) ? Number.parseInt(target, 10) - 1 : current.findIndex(
|
|
11191
|
+
(c) => c === target || c.endsWith(`/${target}`) || c === parseRefEntry(target)?.model
|
|
11192
|
+
);
|
|
11079
11193
|
if (idx < 0 || idx >= current.length) {
|
|
11080
11194
|
const msg2 = `No pool entry matches "${target}". Current pool: ${current.join(", ") || "(empty)"}`;
|
|
11081
11195
|
opts.renderer.writeWarning(msg2);
|
|
11082
11196
|
return { message: msg2 };
|
|
11083
11197
|
}
|
|
11084
11198
|
const next = current.filter((_, i) => i !== idx);
|
|
11085
|
-
return applyPatch(
|
|
11199
|
+
return applyPatch(
|
|
11200
|
+
{ models: next.length > 0 ? next : null },
|
|
11201
|
+
(s) => `Brain LLM pool: ${color14.cyan(poolSummary(s))}`
|
|
11202
|
+
);
|
|
11086
11203
|
}
|
|
11087
|
-
return applyPatch(
|
|
11204
|
+
return applyPatch(
|
|
11205
|
+
{ models: rest },
|
|
11206
|
+
(s) => `Brain LLM pool: ${color14.cyan(poolSummary(s))} ${color14.dim(`(${s.poolLabels.length}/${rest.length} resolved)`)}`
|
|
11207
|
+
);
|
|
11088
11208
|
}
|
|
11089
11209
|
if (subcommand === "strategy") {
|
|
11090
11210
|
const strategy = (rest[0] ?? "").toLowerCase();
|
|
@@ -11134,7 +11254,10 @@ function buildBrainCommand(opts) {
|
|
|
11134
11254
|
return { message: msg3 };
|
|
11135
11255
|
}
|
|
11136
11256
|
if (op === "on" || op === "off") {
|
|
11137
|
-
return applyPatch(
|
|
11257
|
+
return applyPatch(
|
|
11258
|
+
{ council: { enabled: op === "on" } },
|
|
11259
|
+
(s) => `Brain ${councilSummary(s)}${op === "on" && !s.council.enabled ? " \u2014 needs \u22652 resolvable voters (set /brain council voters or a \u22652-model pool)" : ""}`
|
|
11260
|
+
);
|
|
11138
11261
|
}
|
|
11139
11262
|
if (op === "minrisk") {
|
|
11140
11263
|
const level = (rest[1] ?? "").toLowerCase();
|
|
@@ -11143,7 +11266,10 @@ function buildBrainCommand(opts) {
|
|
|
11143
11266
|
opts.renderer.writeWarning(msg3);
|
|
11144
11267
|
return { message: msg3 };
|
|
11145
11268
|
}
|
|
11146
|
-
return applyPatch(
|
|
11269
|
+
return applyPatch(
|
|
11270
|
+
{ council: { minRisk: level } },
|
|
11271
|
+
(s) => `Brain council risk floor set to ${color14.cyan(s.council.minRisk)} \u2014 questions at/above it convene the council`
|
|
11272
|
+
);
|
|
11147
11273
|
}
|
|
11148
11274
|
if (op === "voters") {
|
|
11149
11275
|
const seats = rest.slice(1).map(parseSeat);
|
|
@@ -11152,7 +11278,10 @@ function buildBrainCommand(opts) {
|
|
|
11152
11278
|
opts.renderer.writeWarning(msg3);
|
|
11153
11279
|
return { message: msg3 };
|
|
11154
11280
|
}
|
|
11155
|
-
return applyPatch(
|
|
11281
|
+
return applyPatch(
|
|
11282
|
+
{ council: { voters: seats } },
|
|
11283
|
+
councilSummary
|
|
11284
|
+
);
|
|
11156
11285
|
}
|
|
11157
11286
|
if (op === "personas") {
|
|
11158
11287
|
const lines = [
|
|
@@ -11173,7 +11302,10 @@ function buildBrainCommand(opts) {
|
|
|
11173
11302
|
opts.renderer.writeWarning(msg3);
|
|
11174
11303
|
return { message: msg3 };
|
|
11175
11304
|
}
|
|
11176
|
-
return applyPatch(
|
|
11305
|
+
return applyPatch(
|
|
11306
|
+
{ council: { judge: ref.toLowerCase() === "auto" ? null : ref } },
|
|
11307
|
+
(s) => `Brain council judge: ${color14.cyan(s.council.judge ? compactEntry(s.council.judge) : "auto")}${s.council.judge ? "" : color14.dim(judgeSummary(s).replace(/^, judge: /, " \u2192 "))}`
|
|
11308
|
+
);
|
|
11177
11309
|
}
|
|
11178
11310
|
if (op === "quorum" || op === "approval") {
|
|
11179
11311
|
const value = Number(rest[1]);
|
|
@@ -11208,7 +11340,7 @@ function buildBrainCommand(opts) {
|
|
|
11208
11340
|
return `Brain council ${op} set to ${color14.cyan(applied === void 0 ? "default" : String(applied))}`;
|
|
11209
11341
|
});
|
|
11210
11342
|
}
|
|
11211
|
-
const msg2 = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, or judgetokens.`;
|
|
11343
|
+
const msg2 = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, votertokens, or judgetokens.`;
|
|
11212
11344
|
opts.renderer.writeWarning(msg2);
|
|
11213
11345
|
return { message: msg2 };
|
|
11214
11346
|
}
|
|
@@ -11329,7 +11461,9 @@ ${color14.dim(decision.rationale)}` : ""}`;
|
|
|
11329
11461
|
lines.push(` decision timeout: ${color14.cyan(`${snapshot.decisionTimeoutMs}ms`)}`);
|
|
11330
11462
|
}
|
|
11331
11463
|
if (snapshot?.humanTimeoutMs) {
|
|
11332
|
-
lines.push(
|
|
11464
|
+
lines.push(
|
|
11465
|
+
` human timeout: ${color14.cyan(`${snapshot.humanTimeoutMs}ms`)} ${color14.dim("(then terminal policy)")}`
|
|
11466
|
+
);
|
|
11333
11467
|
}
|
|
11334
11468
|
const councilSeats = opts.brainSettings?.councilLabels ?? [];
|
|
11335
11469
|
if (councilSeats.length > 0) {
|
|
@@ -11548,7 +11682,9 @@ ${color14.dim(decision.rationale)}` : ""}`;
|
|
|
11548
11682
|
` enabled ${snapshot.trace.enabled ? color14.cyan("yes") : color14.dim("no")}`,
|
|
11549
11683
|
` content ${color14.cyan(snapshot.trace.content)}`,
|
|
11550
11684
|
snapshot.trace.path ? ` path ${color14.dim(snapshot.trace.path)}` : "",
|
|
11551
|
-
color14.dim(
|
|
11685
|
+
color14.dim(
|
|
11686
|
+
" Records tiers, every pool target (incl. failures), council votes and tokens."
|
|
11687
|
+
)
|
|
11552
11688
|
].filter(Boolean).join("\n");
|
|
11553
11689
|
opts.renderer.write(msg2);
|
|
11554
11690
|
return { message: msg2 };
|
|
@@ -11640,7 +11776,9 @@ Usage: /brain escalation <conservative|deny-all|continue-on-recommended>`;
|
|
|
11640
11776
|
` enabled ${m.enabled === false ? color14.dim("no") : color14.cyan("yes")}`,
|
|
11641
11777
|
` policy ${color14.cyan(m.policy ?? "llm")}`,
|
|
11642
11778
|
color14.dim(" Signals: tool-failure streak, error storm, agent stall, file churn."),
|
|
11643
|
-
color14.dim(
|
|
11779
|
+
color14.dim(
|
|
11780
|
+
" Changes apply live; a change restarts the watchers, resetting signal counters."
|
|
11781
|
+
)
|
|
11644
11782
|
].join("\n");
|
|
11645
11783
|
opts.renderer.write(msg2);
|
|
11646
11784
|
return { message: msg2 };
|
|
@@ -11678,7 +11816,10 @@ Usage: /brain escalation <conservative|deny-all|continue-on-recommended>`;
|
|
|
11678
11816
|
}
|
|
11679
11817
|
const snapshot = opts.brainRuntime?.getSnapshot();
|
|
11680
11818
|
if (snapshot?.cache.enabled) {
|
|
11681
|
-
lines.push(
|
|
11819
|
+
lines.push(
|
|
11820
|
+
"",
|
|
11821
|
+
color14.dim(` cache: ${snapshot.cache.hits} hit / ${snapshot.cache.misses} miss`)
|
|
11822
|
+
);
|
|
11682
11823
|
}
|
|
11683
11824
|
if (snapshot?.circuit && snapshot.circuit.state !== "closed") {
|
|
11684
11825
|
lines.push(color14.dim(` circuit: ${snapshot.circuit.state}`));
|
|
@@ -11689,7 +11830,10 @@ Usage: /brain escalation <conservative|deny-all|continue-on-recommended>`;
|
|
|
11689
11830
|
lines.push(color14.dim(` ${fmtAge(w.at).padEnd(8)} ${w.outcome}`));
|
|
11690
11831
|
}
|
|
11691
11832
|
}
|
|
11692
|
-
lines.push(
|
|
11833
|
+
lines.push(
|
|
11834
|
+
"",
|
|
11835
|
+
color14.dim(` Based on the last ${log.length} logged decision(s) of this session.`)
|
|
11836
|
+
);
|
|
11693
11837
|
const msg2 = lines.join("\n");
|
|
11694
11838
|
opts.renderer.write(msg2);
|
|
11695
11839
|
return { message: msg2 };
|
|
@@ -11826,6 +11970,7 @@ function buildClearCommand(opts) {
|
|
|
11826
11970
|
ctx.contextEvidence = createContextEvidenceState();
|
|
11827
11971
|
ctx.toolAdjacencyDirty = false;
|
|
11828
11972
|
ctx.pendingPostToolContext = void 0;
|
|
11973
|
+
ctx.clearMemoryEvidence?.();
|
|
11829
11974
|
ctx.lastRequestTokens = void 0;
|
|
11830
11975
|
ctx.lastRealInputTokens = void 0;
|
|
11831
11976
|
for (const key of Object.keys(ctx.meta)) ctx.state.deleteMeta(key);
|
|
@@ -12113,8 +12258,17 @@ function buildCompactCommand(opts) {
|
|
|
12113
12258
|
|
|
12114
12259
|
// src/slash-commands/context.ts
|
|
12115
12260
|
import * as fs7 from "node:fs/promises";
|
|
12116
|
-
import {
|
|
12117
|
-
|
|
12261
|
+
import {
|
|
12262
|
+
formatContextWindowModeList,
|
|
12263
|
+
getContextWindowMode,
|
|
12264
|
+
resolveContextWindowPolicy as resolveContextWindowPolicy2
|
|
12265
|
+
} from "@wrongstack/core/types";
|
|
12266
|
+
import {
|
|
12267
|
+
atomicWrite as atomicWrite3,
|
|
12268
|
+
color as color18,
|
|
12269
|
+
getContextBreakdown,
|
|
12270
|
+
repairToolUseAdjacency
|
|
12271
|
+
} from "@wrongstack/core/utils";
|
|
12118
12272
|
function buildContextCommand(opts) {
|
|
12119
12273
|
return {
|
|
12120
12274
|
name: "context",
|
|
@@ -12386,7 +12540,14 @@ function safeBreakdown(ctx) {
|
|
|
12386
12540
|
return getContextBreakdown(ctx);
|
|
12387
12541
|
} catch (err) {
|
|
12388
12542
|
if (process.env["DEBUG_WS"]) {
|
|
12389
|
-
console.warn(
|
|
12543
|
+
console.warn(
|
|
12544
|
+
JSON.stringify({
|
|
12545
|
+
level: "warn",
|
|
12546
|
+
event: "context.breakdown_failed",
|
|
12547
|
+
message: String(err),
|
|
12548
|
+
timestamp: Date.now()
|
|
12549
|
+
})
|
|
12550
|
+
);
|
|
12390
12551
|
}
|
|
12391
12552
|
return null;
|
|
12392
12553
|
}
|
|
@@ -12414,7 +12575,7 @@ function renderBreakdown(bd, detailed) {
|
|
|
12414
12575
|
`${color18.bold("Breakdown")} (${headerSuffix})`,
|
|
12415
12576
|
` system: ${K(bd.system.total)} (${PCT(bd.system.total, limit)})`,
|
|
12416
12577
|
` tools: ${K(bd.tools.total)} (${PCT(bd.tools.total, limit)}) \xB7 builtin ${K(bd.tools.builtin)}, mcp ${K(bd.tools.mcp)} across ${bd.tools.count} defs`,
|
|
12417
|
-
` history: ${K(bd.history.total)} (${PCT(bd.history.total, limit)}) \xB7 text ${K(bd.history.text)}, tool results ${K(bd.history.toolResults)}`,
|
|
12578
|
+
` history: ${K(bd.history.total)} (${PCT(bd.history.total, limit)}) \xB7 text ${K(bd.history.text)}, tool inputs ${K(bd.history.toolInputs ?? 0)}, results ${K(bd.history.toolResults)}, thinking ${K(bd.history.thinking ?? 0)}`,
|
|
12418
12579
|
` volatile: ${K(bd.volatile.total)} (${PCT(bd.volatile.total, limit)}) \xB7 ledger ${K(bd.volatile.ledger)}, nextsteps ${K(bd.volatile.nextsteps)}`,
|
|
12419
12580
|
` ${color18.bold("total")}: ${K(bd.total)}${overBy > 0 ? "" : ` (${PCT(bd.total, limit)})`}`
|
|
12420
12581
|
];
|
|
@@ -12427,7 +12588,9 @@ function renderBreakdown(bd, detailed) {
|
|
|
12427
12588
|
if (sources.length > 0) {
|
|
12428
12589
|
const top = detailed ? sources : sources.slice(0, 3);
|
|
12429
12590
|
out.push(
|
|
12430
|
-
` ${color18.dim("heaviest static:")} ${top.map(
|
|
12591
|
+
` ${color18.dim("heaviest static:")} ${top.map(
|
|
12592
|
+
([src, tokens]) => `${SOURCE_LABELS[src] ?? src} ${K(tokens)}`
|
|
12593
|
+
).join(", ")}`
|
|
12431
12594
|
);
|
|
12432
12595
|
if (detailed && bd.tools.total > 0 && (bd.system.bySource["tool-usage"] ?? 0) > 0) {
|
|
12433
12596
|
out.push(
|
|
@@ -13685,7 +13848,7 @@ function buildDoctorCommand(opts) {
|
|
|
13685
13848
|
].join("\n");
|
|
13686
13849
|
async function loadPluginSchemas() {
|
|
13687
13850
|
try {
|
|
13688
|
-
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-
|
|
13851
|
+
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-K3BAUP4D.js");
|
|
13689
13852
|
const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
|
|
13690
13853
|
const loaded = [];
|
|
13691
13854
|
for (const s of settled) {
|
|
@@ -20778,6 +20941,7 @@ ${targetMode.description}`
|
|
|
20778
20941
|
|
|
20779
20942
|
// src/slash-commands/modelcaps.ts
|
|
20780
20943
|
import * as fs14 from "node:fs/promises";
|
|
20944
|
+
import { hasProviderCredential } from "@wrongstack/core/models";
|
|
20781
20945
|
import { color as color36 } from "@wrongstack/core/utils";
|
|
20782
20946
|
function fmtTokens(n) {
|
|
20783
20947
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
@@ -20885,13 +21049,7 @@ function buildModelCapsCommand(opts) {
|
|
|
20885
21049
|
}
|
|
20886
21050
|
const config = opts.configStore.get();
|
|
20887
21051
|
const configProviders = config?.providers ?? {};
|
|
20888
|
-
|
|
20889
|
-
const pc = configProviders[providerId];
|
|
20890
|
-
if (!pc) return false;
|
|
20891
|
-
if (typeof pc.apiKey === "string" && pc.apiKey.length > 0) return true;
|
|
20892
|
-
if (Array.isArray(pc.apiKeys) && pc.apiKeys.some((k) => k?.apiKey)) return true;
|
|
20893
|
-
return false;
|
|
20894
|
-
}
|
|
21052
|
+
const hasKey = (provider) => hasProviderCredential(provider, { providers: configProviders });
|
|
20895
21053
|
const lines = [
|
|
20896
21054
|
`${color36.bold("Available Models")} ${color36.dim("\u2014 capacities + pricing")}`,
|
|
20897
21055
|
""
|
|
@@ -20901,7 +21059,7 @@ function buildModelCapsCommand(opts) {
|
|
|
20901
21059
|
if (trimmed && !trimmed.includes("/") && !prov.id.toLowerCase().includes(trimmed) && !prov.name.toLowerCase().includes(trimmed)) {
|
|
20902
21060
|
continue;
|
|
20903
21061
|
}
|
|
20904
|
-
const keyed = hasKey(prov
|
|
21062
|
+
const keyed = hasKey(prov);
|
|
20905
21063
|
const marker = keyed ? color36.green("\u25CF") : color36.dim("\u25CB");
|
|
20906
21064
|
lines.push(` ${marker} ${color36.bold(prov.id.padEnd(16))} ${color36.dim(`(${prov.name})`)}`);
|
|
20907
21065
|
const models = prov.models ?? [];
|
|
@@ -25417,8 +25575,13 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
|
25417
25575
|
const child = spawn7(nodeExe, [cliPath, "--no-interactive"], {
|
|
25418
25576
|
cwd: resolved,
|
|
25419
25577
|
stdio: "inherit",
|
|
25420
|
-
detached: false
|
|
25421
|
-
signal:
|
|
25578
|
+
detached: false
|
|
25579
|
+
// NO abort signal: this child is a long-lived INTERACTIVE session that
|
|
25580
|
+
// is meant to outlive the spawn call. The 30 s timeout fired 30 seconds
|
|
25581
|
+
// after "Switched to <project> … (current session stays open)" and
|
|
25582
|
+
// SIGTERM'd the new session mid-typing, with no message. Sibling
|
|
25583
|
+
// long-lived spawns pass no signal (slash-commands/mailbox-serve.ts:98),
|
|
25584
|
+
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
25422
25585
|
});
|
|
25423
25586
|
child.on("error", (err) => {
|
|
25424
25587
|
console.error(color47.red(`Failed to spawn wstack: ${err.message}`));
|
|
@@ -25554,8 +25717,13 @@ async function spawnInProject(opts, _ctx, root, projectName) {
|
|
|
25554
25717
|
const child = spawn7(nodeExe, [cliPath, "--no-interactive"], {
|
|
25555
25718
|
cwd: root,
|
|
25556
25719
|
stdio: "inherit",
|
|
25557
|
-
detached: false
|
|
25558
|
-
signal:
|
|
25720
|
+
detached: false
|
|
25721
|
+
// NO abort signal: this child is a long-lived INTERACTIVE session that
|
|
25722
|
+
// is meant to outlive the spawn call. The 30 s timeout fired 30 seconds
|
|
25723
|
+
// after "Switched to <project> … (current session stays open)" and
|
|
25724
|
+
// SIGTERM'd the new session mid-typing, with no message. Sibling
|
|
25725
|
+
// long-lived spawns pass no signal (slash-commands/mailbox-serve.ts:98),
|
|
25726
|
+
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
25559
25727
|
});
|
|
25560
25728
|
child.on("error", (err) => {
|
|
25561
25729
|
console.error(color47.red(`Failed to spawn wstack: ${err.message}`));
|
|
@@ -25591,8 +25759,13 @@ async function handleNewSession(_opts, _ctx) {
|
|
|
25591
25759
|
const child = spawn7(nodeExe, [cliPath, "--no-interactive"], {
|
|
25592
25760
|
cwd: process.cwd(),
|
|
25593
25761
|
stdio: "inherit",
|
|
25594
|
-
detached: false
|
|
25595
|
-
signal:
|
|
25762
|
+
detached: false
|
|
25763
|
+
// NO abort signal: this child is a long-lived INTERACTIVE session that
|
|
25764
|
+
// is meant to outlive the spawn call. The 30 s timeout fired 30 seconds
|
|
25765
|
+
// after "Switched to <project> … (current session stays open)" and
|
|
25766
|
+
// SIGTERM'd the new session mid-typing, with no message. Sibling
|
|
25767
|
+
// long-lived spawns pass no signal (slash-commands/mailbox-serve.ts:98),
|
|
25768
|
+
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
25596
25769
|
});
|
|
25597
25770
|
child.on("error", (err) => {
|
|
25598
25771
|
console.error(color47.red(`Failed to spawn wstack: ${err.message}`));
|
|
@@ -25639,6 +25812,7 @@ async function handlePrevSessions(opts, _ctx) {
|
|
|
25639
25812
|
import { spawn as spawn8 } from "node:child_process";
|
|
25640
25813
|
import * as fsp3 from "node:fs/promises";
|
|
25641
25814
|
import * as path27 from "node:path";
|
|
25815
|
+
import { emitReviewIfChanged } from "@wrongstack/core/plugin";
|
|
25642
25816
|
async function runGit2(args, cwd) {
|
|
25643
25817
|
return new Promise((resolve8) => {
|
|
25644
25818
|
const child = spawn8("git", args, {
|
|
@@ -25732,16 +25906,29 @@ function buildReviewCommand(opts) {
|
|
|
25732
25906
|
enabled: true,
|
|
25733
25907
|
provider: ctx.provider.id,
|
|
25734
25908
|
model: ctx.model,
|
|
25735
|
-
maxFiles: limit
|
|
25909
|
+
maxFiles: limit,
|
|
25910
|
+
autoFix: "off",
|
|
25911
|
+
cascadeOn: "off",
|
|
25912
|
+
maxCascadeDepth: 0
|
|
25736
25913
|
},
|
|
25737
25914
|
cwd,
|
|
25738
25915
|
files: filesWithContent
|
|
25739
25916
|
};
|
|
25740
|
-
|
|
25917
|
+
const emitted = await emitReviewIfChanged(
|
|
25918
|
+
{ events: opts.events, emitCustom: opts.events.emitCustom.bind(opts.events) },
|
|
25919
|
+
payload
|
|
25920
|
+
);
|
|
25921
|
+
if (!emitted) {
|
|
25922
|
+
return {
|
|
25923
|
+
message: "\u{1F982} Chimera review skipped \u2014 this file content already has a review in progress."
|
|
25924
|
+
};
|
|
25925
|
+
}
|
|
25926
|
+
const skipped = filesWithContent.length - emitted.files.length;
|
|
25741
25927
|
const note = truncated ? `
|
|
25742
25928
|
${existing.length - limit} more changed file(s) were not included \u2014 raise the cap with /review --limit ${existing.length}.` : "";
|
|
25929
|
+
const skippedNote = skipped > 0 ? ` ${skipped} file(s) already under review were skipped.` : "";
|
|
25743
25930
|
return {
|
|
25744
|
-
message: `\u{1F982} Chimera review triggered for ${
|
|
25931
|
+
message: `\u{1F982} Chimera review triggered for ${emitted.files.length} file(s).${skippedNote}
|
|
25745
25932
|
The review report will appear in chat history shortly.${note}`
|
|
25746
25933
|
};
|
|
25747
25934
|
}
|
|
@@ -25863,6 +26050,7 @@ function buildSettingsCommand(opts) {
|
|
|
25863
26050
|
" /settings context-strategy hybrid|intelligent|selective Compactor strategy",
|
|
25864
26051
|
" /settings context-auto-compact on|off Auto-compact context when thresholds crossed",
|
|
25865
26052
|
" /settings token-saving off|minimal|light|medium|aggressive Token-saving mode",
|
|
26053
|
+
" /settings nextsteps-tool on|off Give the leader a `nextsteps` tool alongside the <nextsteps> block (next session)",
|
|
25866
26054
|
" /settings mcp on|off Load MCP servers declared in config",
|
|
25867
26055
|
" /settings plugins on|off Load npm plugins declared in config",
|
|
25868
26056
|
" /settings memory on|off Register remember/forget tools",
|
|
@@ -25912,6 +26100,7 @@ function buildSettingsCommand(opts) {
|
|
|
25912
26100
|
const contextAutoCompact = context?.autoCompact !== false;
|
|
25913
26101
|
const features = opts.configStore.get().features;
|
|
25914
26102
|
const tokenSavingTier = features?.tokenSavingMode ?? "off";
|
|
26103
|
+
const nextStepsToolEnabled = opts.configStore.get().tools?.nextsteps?.enabled === true;
|
|
25915
26104
|
const maxConcurrent = opts.configStore.get().maxConcurrent ?? 4;
|
|
25916
26105
|
const titleAnimation = autonomy?.terminalTitleAnimation !== false;
|
|
25917
26106
|
const modelRuntime = opts.configStore.get().modelRuntime;
|
|
@@ -25954,6 +26143,7 @@ function buildSettingsCommand(opts) {
|
|
|
25954
26143
|
` context strategy: ${color48.cyan(contextStrategy)} ${color48.dim("change: /settings context-strategy hybrid|intelligent|selective")}`,
|
|
25955
26144
|
` context auto-compact: ${contextAutoCompact ? color48.cyan("on") : color48.dim("off")} ${color48.dim("change: /settings context-auto-compact on|off")}`,
|
|
25956
26145
|
` token-saving: ${color48.cyan(tokenSavingTier)} ${color48.dim("change: /settings token-saving off|minimal|light|medium|aggressive")}`,
|
|
26146
|
+
` nextsteps tool: ${nextStepsToolEnabled ? color48.cyan("on") : color48.dim("off")} ${color48.dim("change: /settings nextsteps-tool on|off")}`,
|
|
25957
26147
|
` MCP features: ${feats?.mcp !== false ? color48.cyan("on") : color48.dim("off")} ${color48.dim("change: /settings mcp on|off")}`,
|
|
25958
26148
|
` plugin features: ${feats?.plugins !== false ? color48.cyan("on") : color48.dim("off")} ${color48.dim("change: /settings plugins on|off")}`,
|
|
25959
26149
|
` memory features: ${feats?.memory !== false ? color48.cyan("on") : color48.dim("off")} ${color48.dim("change: /settings memory on|off")}`,
|
|
@@ -26383,6 +26573,21 @@ function buildSettingsCommand(opts) {
|
|
|
26383
26573
|
message: `${color48.green("\u2713")} context auto-compact \u2192 ${on ? color48.cyan("on") : color48.dim("off")} ${color48.dim("auto-compact context when thresholds crossed")}`
|
|
26384
26574
|
};
|
|
26385
26575
|
}
|
|
26576
|
+
if (sub === "nextsteps-tool") {
|
|
26577
|
+
const raw = (rest[0] ?? "").toLowerCase();
|
|
26578
|
+
if (!["on", "off"].includes(raw)) {
|
|
26579
|
+
return { message: `${color48.amber("Usage:")} /settings nextsteps-tool on|off` };
|
|
26580
|
+
}
|
|
26581
|
+
const on = raw === "on";
|
|
26582
|
+
await persistConfigSetting(persistDeps, (cfg) => {
|
|
26583
|
+
const tools = cfg.tools ?? {};
|
|
26584
|
+
tools.nextsteps = { enabled: on };
|
|
26585
|
+
cfg.tools = tools;
|
|
26586
|
+
});
|
|
26587
|
+
return {
|
|
26588
|
+
message: `${color48.green("\u2713")} nextsteps tool \u2192 ${on ? color48.cyan("on") : color48.dim("off")} ${color48.dim("takes effect in the next session")}`
|
|
26589
|
+
};
|
|
26590
|
+
}
|
|
26386
26591
|
if (sub === "token-saving") {
|
|
26387
26592
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
26388
26593
|
const tiers = ["off", "minimal", "light", "medium", "aggressive"];
|
|
@@ -30130,7 +30335,8 @@ async function runInteractive(cliCtx) {
|
|
|
30130
30335
|
events,
|
|
30131
30336
|
container,
|
|
30132
30337
|
configStore,
|
|
30133
|
-
updateInfo
|
|
30338
|
+
updateInfo,
|
|
30339
|
+
webuiSessionChild
|
|
30134
30340
|
} = cliCtx;
|
|
30135
30341
|
const profileConfigPath = activeProfileConfigPath(wpaths, config);
|
|
30136
30342
|
const modeStore = container.resolve(TOKENS9.ModeStore);
|
|
@@ -30193,11 +30399,13 @@ async function runInteractive(cliCtx) {
|
|
|
30193
30399
|
wpaths
|
|
30194
30400
|
});
|
|
30195
30401
|
const stdinInteractive = process.stdin.isTTY;
|
|
30402
|
+
const hookRunnerRef = { current: null };
|
|
30196
30403
|
registerCliManagementTools({
|
|
30197
30404
|
toolRegistry,
|
|
30198
30405
|
configStore,
|
|
30199
30406
|
profileConfigPath,
|
|
30200
|
-
stdinInteractive
|
|
30407
|
+
stdinInteractive,
|
|
30408
|
+
getHookRunner: () => hookRunnerRef.current
|
|
30201
30409
|
});
|
|
30202
30410
|
const { metricsSink, healthRegistry, metricsStatus } = (() => {
|
|
30203
30411
|
const ms = setupMetrics({
|
|
@@ -30231,7 +30439,8 @@ async function runInteractive(cliCtx) {
|
|
|
30231
30439
|
const systemPrompt = await promptBuilder.build({
|
|
30232
30440
|
cwd,
|
|
30233
30441
|
projectRoot,
|
|
30234
|
-
tools: toolRegistry.
|
|
30442
|
+
tools: toolRegistry.listForProvider(),
|
|
30443
|
+
catalogTools: toolRegistry.list(),
|
|
30235
30444
|
provider: config.provider,
|
|
30236
30445
|
model: config.model,
|
|
30237
30446
|
onlineAgents
|
|
@@ -30345,7 +30554,8 @@ async function runInteractive(cliCtx) {
|
|
|
30345
30554
|
slashRegistry,
|
|
30346
30555
|
hqPublisherRef,
|
|
30347
30556
|
brainMailbox,
|
|
30348
|
-
pluginHost
|
|
30557
|
+
pluginHost,
|
|
30558
|
+
hookRunner
|
|
30349
30559
|
} = await setupLifecycleAndPlugins({
|
|
30350
30560
|
flags,
|
|
30351
30561
|
config,
|
|
@@ -30382,6 +30592,7 @@ async function runInteractive(cliCtx) {
|
|
|
30382
30592
|
logger,
|
|
30383
30593
|
teardownHandlers
|
|
30384
30594
|
});
|
|
30595
|
+
hookRunnerRef.current = hookRunner;
|
|
30385
30596
|
const fallbackProfileManager = container.resolve(TOKENS9.FallbackProfileManager);
|
|
30386
30597
|
const statusTracker = await setupProviderStatus({
|
|
30387
30598
|
events,
|
|
@@ -30426,6 +30637,13 @@ async function runInteractive(cliCtx) {
|
|
|
30426
30637
|
getConfig: () => config,
|
|
30427
30638
|
fallbackProfileManager,
|
|
30428
30639
|
statusTracker,
|
|
30640
|
+
wrapProviderCall: (request, inner) => agent.extensions.wrapProviderRunner(
|
|
30641
|
+
(_ctx, wrappedRequest) => inner(wrappedRequest),
|
|
30642
|
+
// OneShotOrchestrator owns the selected provider and fallback chain.
|
|
30643
|
+
// The agent-loop fallback wrapper routes from and mutates agent.ctx,
|
|
30644
|
+
// which may describe a different provider/model than this utility call.
|
|
30645
|
+
{ exclude: ["fallback-model"] }
|
|
30646
|
+
)(agent.ctx, request),
|
|
30429
30647
|
compactor: container.resolve(TOKENS9.Compactor)
|
|
30430
30648
|
});
|
|
30431
30649
|
let {
|
|
@@ -30746,7 +30964,25 @@ async function runInteractive(cliCtx) {
|
|
|
30746
30964
|
effectiveMaxContext: effectiveMaxContextRef.current,
|
|
30747
30965
|
configRef,
|
|
30748
30966
|
autonomyModeRef,
|
|
30749
|
-
logger
|
|
30967
|
+
logger,
|
|
30968
|
+
// WITHOUT this the helper primed an engine and dropped it: the only live
|
|
30969
|
+
// holder is the `eternalEngine` binding below, written solely by the slash
|
|
30970
|
+
// handler. `--eternal "<mission>"` therefore forced YOLO on and set the
|
|
30971
|
+
// mode to 'eternal', then the REPL found no engine, printed "no engine
|
|
30972
|
+
// wired — falling back to off" on EVERY loop iteration without actually
|
|
30973
|
+
// flipping the mode back or `continue`-ing, and left the user staring at
|
|
30974
|
+
// unconfirmed tool calls. `cli-eternal-flag.test.ts` passes this ref, so
|
|
30975
|
+
// the test exercised a wiring production never had.
|
|
30976
|
+
// The live holder is `EternalAutonomyEngine | null`; the ref contract is
|
|
30977
|
+
// `| undefined`. Bridge rather than widen either side.
|
|
30978
|
+
eternalEngineRef: {
|
|
30979
|
+
get current() {
|
|
30980
|
+
return eternalEngine ?? void 0;
|
|
30981
|
+
},
|
|
30982
|
+
set current(engine) {
|
|
30983
|
+
eternalEngine = engine ?? null;
|
|
30984
|
+
}
|
|
30985
|
+
}
|
|
30750
30986
|
});
|
|
30751
30987
|
config = configRef.current;
|
|
30752
30988
|
if (eternalFlag.length > 0) {
|
|
@@ -30776,7 +31012,7 @@ async function runInteractive(cliCtx) {
|
|
|
30776
31012
|
onEvent: evOn
|
|
30777
31013
|
});
|
|
30778
31014
|
const savedProviderCfg = config.providers?.[config.provider];
|
|
30779
|
-
const { execute } = await import("./execution-
|
|
31015
|
+
const { execute } = await import("./execution-CQ772VPS.js");
|
|
30780
31016
|
const stopHeapWatchdog = startSharedHeapWatchdog({
|
|
30781
31017
|
collectStats: () => {
|
|
30782
31018
|
const hqQueue = hqPublisherRef.current?.getQueueStats();
|
|
@@ -30834,6 +31070,7 @@ async function runInteractive(cliCtx) {
|
|
|
30834
31070
|
projectRoot,
|
|
30835
31071
|
flags,
|
|
30836
31072
|
positional,
|
|
31073
|
+
webuiSessionChild,
|
|
30837
31074
|
// Forward preflight's update-info so the TUI banner can render
|
|
30838
31075
|
// the "(update available: v…)" indicator next to the version
|
|
30839
31076
|
// chip. May be undefined (e.g. when the registry check was
|
|
@@ -31008,4 +31245,4 @@ export {
|
|
|
31008
31245
|
CLI_VERSION,
|
|
31009
31246
|
runInteractive
|
|
31010
31247
|
};
|
|
31011
|
-
//# sourceMappingURL=cli-main-
|
|
31248
|
+
//# sourceMappingURL=cli-main-EOJ74CI4.js.map
|