@wrongstack/cli 0.319.0 → 1.0.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/data/providers.json +22 -15
- package/dist/{acp-5ANIAOZC.js → acp-3LARESEO.js} +113 -10
- package/dist/acp-hq-telemetry.d.ts +44 -0
- package/dist/{audit-ZPCLCC3C.js → audit-46YK5DSC.js} +1 -2
- package/dist/{auth-KF5TAD7V.js → auth-KIBJZZIE.js} +5 -6
- package/dist/auth-menu/add-provider.d.ts +7 -0
- package/dist/auth-menu/panel-service.d.ts +2 -20
- package/dist/{auto-discover-providers-MHFLDSD3.js → auto-discover-providers-VQU3IZMR.js} +1 -2
- package/dist/{bench-XYG56AMO.js → bench-YBU6BVQP.js} +175 -35
- package/dist/boot/brain-decision-log.d.ts +22 -2
- package/dist/{boot-auto-thin-BZ675EVT.js → boot-auto-thin-MANHOYHE.js} +1 -2
- package/dist/{chronicle-6EPPMUC5.js → chronicle-UTFETHP6.js} +1 -2
- package/dist/{chunk-VWCZL4OH.js → chunk-4HV5RKZH.js} +5 -5
- package/dist/{chunk-42JD25KU.js → chunk-5IA5337I.js} +3 -3
- package/dist/{chunk-7JBKXVMK.js → chunk-C2E24IXZ.js} +44 -32
- package/dist/{chunk-7CECQDNH.js → chunk-D3K4NYQL.js} +1 -1
- package/dist/{chunk-XPX432BZ.js → chunk-DR2OXU46.js} +50 -39
- package/dist/{chunk-4JRIWVJ4.js → chunk-ERX4BLKP.js} +1 -1
- package/dist/chunk-ETYHZPXP.js +52 -0
- package/dist/{chunk-TYO2OVAD.js → chunk-EWKESL4L.js} +8 -4
- package/dist/{chunk-QAC263FZ.js → chunk-FPIWTJ2G.js} +2 -3
- package/dist/{chunk-7YLN7YUA.js → chunk-IMWXXF4J.js} +61 -9
- package/dist/{chunk-G7337TTK.js → chunk-IS2PPBQV.js} +1 -1
- package/dist/{chunk-G3IMKQRH.js → chunk-JHPXJRRI.js} +1 -1
- package/dist/{chunk-XHIEA6LG.js → chunk-MNQQ4ZNF.js} +26 -22
- package/dist/{chunk-P2OKBDCH.js → chunk-MXEJEYT7.js} +53 -14
- package/dist/{chunk-PCBJSXYV.js → chunk-O4A3HHKD.js} +2 -2
- package/dist/{chunk-XYKYXFEE.js → chunk-TE3Q32JP.js} +10 -4
- package/dist/{chunk-H7GABTGS.js → chunk-TEBMCYZN.js} +69 -30
- package/dist/{chunk-E4I2TF5S.js → chunk-TNK6237M.js} +2 -2
- package/dist/{chunk-SYIBTG3X.js → chunk-VOTTENR5.js} +3 -5
- package/dist/chunk-WHOIR577.js +1 -0
- package/dist/{chunk-2ZNBRZ4W.js → chunk-WQZW3RDP.js} +2 -2
- package/dist/{chunk-GGGUZSAU.js → chunk-Z7A5MXKJ.js} +18 -12
- package/dist/{chunk-F5GA2QW2.js → chunk-ZSZ3EYWH.js} +2 -2
- package/dist/{cli-context-LH4QP4W2.js → cli-context-CYMKNOK3.js} +58 -307
- package/dist/{cli-main-72XUFUCL.js → cli-main-TTIVR4DI.js} +925 -329
- package/dist/{diag-doctor-LFCCBPMD.js → diag-doctor-7LYUYU35.js} +4 -6
- package/dist/execute-deps.d.ts +5 -1
- package/dist/{execution-DKJDNPYF.js → execution-3Y55IWBK.js} +512 -469
- package/dist/{export-ROG3DKTZ.js → export-VVRIOWFV.js} +1 -2
- package/dist/{governance-JSGHHA2R.js → governance-RYSHV675.js} +1 -2
- package/dist/{hq-3GWBFLON.js → hq-IG3YRGCO.js} +2 -3
- package/dist/hq-command-controller.d.ts +37 -7
- package/dist/hq-server/routes.d.ts +1 -1
- package/dist/hq-server/ws.d.ts +1 -1
- package/dist/{hq-server-OARPUSQJ.js → hq-server-OILU3NPI.js} +2 -3
- package/dist/{hq-ttl-KUO3AU7X.js → hq-ttl-VJR65OBJ.js} +1 -2
- package/dist/{hq-tunnel-LO55RCZE.js → hq-tunnel-NIJ5EP2Y.js} +1 -2
- package/dist/index.js +5 -6
- package/dist/{init-4JQSG66Q.js → init-DRMMFG2G.js} +1 -2
- package/dist/{kanban-run-mirror-EKVNGXWW.js → kanban-run-mirror-22HQ5FNG.js} +1 -2
- package/dist/live-settings-input.d.ts +2 -0
- package/dist/{mailbox-serve-VKQIRCCB.js → mailbox-serve-VUCWZ2SJ.js} +2 -3
- package/dist/{mcp-AQKSASHD.js → mcp-HOMLC4WE.js} +1 -2
- package/dist/{modeldiag-5FRMT6FQ.js → modeldiag-FMJT37SN.js} +2 -3
- package/dist/{per-subcommand-help-6VCIKDUW.js → per-subcommand-help-BWBHYVJO.js} +2 -3
- package/dist/{permissions-2PWBL4YU.js → permissions-CFDLXETM.js} +1 -2
- package/dist/{plugin-usage-CYUORYM6.js → plugin-usage-HFBI3TFT.js} +2 -3
- package/dist/{plugins-RV3OBBND.js → plugins-PZ2VZL7V.js} +4 -5
- package/dist/{project-BLQ3ALVL.js → project-AOQI5XTK.js} +1 -2
- package/dist/{project-manifest-YFTJ3D5N.js → project-manifest-7NSFVBM3.js} +2 -3
- package/dist/{project-picker-R5TYAE3Q.js → project-picker-SVBXMPKX.js} +3 -4
- package/dist/{projects-5J727S4L.js → projects-L6C6XLDY.js} +1 -2
- package/dist/provider-config-utils.d.ts +1 -1
- package/dist/{providers-models-OKKQZIWU.js → providers-models-YVMVYWRS.js} +3 -4
- package/dist/{proxy-wiring-EQB5X5YH.js → proxy-wiring-MGRSKZZB.js} +3 -4
- package/dist/{quick-XLYLZX4B.js → quick-CNB4Z3HS.js} +1 -2
- package/dist/{replay-RZXZKP2U.js → replay-JJ2NOWD6.js} +1 -2
- package/dist/{replay-FJ2JBXUA.js → replay-Z3FTJEMM.js} +1 -2
- package/dist/{rewind-2FFNOOKS.js → rewind-JA3ZLCNM.js} +1 -2
- package/dist/{sdd-runtime-FLKCSTYV.js → sdd-runtime-PTOSPYI4.js} +2 -3
- package/dist/services/sdd-runtime.d.ts +1 -1
- package/dist/services/statusline-config.d.ts +43 -13
- package/dist/{sessions-config-KAMEBVOX.js → sessions-config-UL45XKX7.js} +2 -3
- package/dist/{sessions-doctor-EXHAZSSE.js → sessions-doctor-QUL37U32.js} +1 -2
- package/dist/short-circuit-flags-6PSP56L7.js +10 -0
- package/dist/{simpleui-dist-JKNRCRRK.js → simpleui-dist-CXSIDAXZ.js} +1 -2
- package/dist/slash-commands/command-context.d.ts +10 -0
- package/dist/slash-commands/sdd.d.ts +1 -1
- package/dist/slash-commands/statusline.d.ts +1 -1
- package/dist/subcommands/handlers/bench-run-config.d.ts +18 -0
- package/dist/subcommands/handlers/bench.d.ts +8 -7
- package/dist/subcommands-HZQKA4G2.js +9 -0
- package/dist/{tools-skills-Q4P27URS.js → tools-skills-GH24UCBY.js} +1 -2
- package/dist/{update-K45CS6SS.js → update-5DPB4YD4.js} +1 -2
- package/dist/{update-check-PKSMSMD6.js → update-check-BS3DHTSI.js} +1 -2
- package/dist/version-help-MYKF724O.js +10 -0
- package/dist/webui-server/client-registration.d.ts +9 -1
- package/dist/{webui-server-SY4EQCKD.js → webui-server-T6AMOXJJ.js} +54 -13
- package/dist/wiring/brain-and-orchestration.d.ts +2 -0
- package/dist/wiring/cli-execute-builder.d.ts +4 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
- package/dist/wiring/command-host-state.d.ts +50 -5
- package/dist/wiring/external-plugins.d.ts +9 -0
- package/dist/wiring/provider-runtime-setup.d.ts +2 -0
- package/dist/wiring/runtime-controller-deps.d.ts +3 -0
- package/dist/wiring/vector-memory-setup.d.ts +12 -0
- package/dist/wiring/wrongtrace-gate.d.ts +2 -2
- package/dist/wiring/wrongtrace-hooks.d.ts +1 -1
- package/dist/wiring/wrongtrace-prompt-contributor.d.ts +5 -2
- package/dist/{wrongtrace-gate-counters-P5BCBXQN.js → wrongtrace-gate-counters-7C2EAAZL.js} +2 -3
- package/dist/{wrongtrace-telemetry-FNLANZ5I.js → wrongtrace-telemetry-3ASFKOZO.js} +2 -3
- package/package.json +28 -28
- package/dist/chunk-7OCVIDC7.js +0 -11
- package/dist/chunk-ALE5KHCA.js +0 -1
- package/dist/chunk-OZDE3OWD.js +0 -52
- package/dist/launch-hints.d.ts +0 -49
- package/dist/short-circuit-flags-U6CJAF6J.js +0 -11
- package/dist/subcommands-J4JMWC5W.js +0 -10
- package/dist/version-help-WMPSEL4U.js +0 -11
- package/dist/webui-server/privileged-actions.d.ts +0 -14
- package/dist/wiring/cli-heap-watchdog.d.ts +0 -34
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createHqCommandDispatcher
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IMWXXF4J.js";
|
|
4
4
|
import {
|
|
5
5
|
runProjectPicker
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WQZW3RDP.js";
|
|
7
7
|
import {
|
|
8
8
|
ensureProjectDataDir,
|
|
9
9
|
findProject,
|
|
10
10
|
generateSlug,
|
|
11
11
|
loadManifest,
|
|
12
12
|
saveManifest
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-IS2PPBQV.js";
|
|
14
14
|
import {
|
|
15
15
|
getWrongTrace
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-ERX4BLKP.js";
|
|
17
17
|
import {
|
|
18
18
|
MAX_TUI_THINKING_WORD_LENGTH,
|
|
19
19
|
clearSuggestions,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "./chunk-SXJTVNWF.js";
|
|
26
26
|
import {
|
|
27
27
|
setupPlugins
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-5IA5337I.js";
|
|
29
29
|
import {
|
|
30
30
|
deriveFsAccessPair,
|
|
31
31
|
filterSafeForProject,
|
|
@@ -44,11 +44,15 @@ import {
|
|
|
44
44
|
fmtTaskResultLine,
|
|
45
45
|
fmtTok,
|
|
46
46
|
patchConfig
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-EWKESL4L.js";
|
|
48
|
+
import {
|
|
49
|
+
renderDeepHelpToString,
|
|
50
|
+
renderFocusedHelpToString
|
|
51
|
+
} from "./chunk-MXEJEYT7.js";
|
|
48
52
|
import {
|
|
49
53
|
awaitFirstWrongProxyProbe,
|
|
50
54
|
bootstrapWrongProxy
|
|
51
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-VOTTENR5.js";
|
|
52
56
|
import {
|
|
53
57
|
advanceToNextTask,
|
|
54
58
|
findSpec,
|
|
@@ -59,17 +63,14 @@ import {
|
|
|
59
63
|
matchTaskNode,
|
|
60
64
|
sddState
|
|
61
65
|
} from "./chunk-JHUJUIOH.js";
|
|
62
|
-
import {
|
|
63
|
-
startCliHqConnection
|
|
64
|
-
} from "./chunk-XYKYXFEE.js";
|
|
65
66
|
import {
|
|
66
67
|
PLUGIN_AUDIT_ENTRIES,
|
|
67
68
|
runPluginManagementCommand
|
|
68
|
-
} from "./chunk-
|
|
69
|
-
import "./chunk-
|
|
69
|
+
} from "./chunk-TEBMCYZN.js";
|
|
70
|
+
import "./chunk-JHPXJRRI.js";
|
|
70
71
|
import {
|
|
71
72
|
recordGateDecision
|
|
72
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-D3K4NYQL.js";
|
|
73
74
|
import {
|
|
74
75
|
CLI_VERSION
|
|
75
76
|
} from "./chunk-XJXDOF63.js";
|
|
@@ -80,18 +81,23 @@ import {
|
|
|
80
81
|
refreshAcpRegistry,
|
|
81
82
|
resolveProviderCfg,
|
|
82
83
|
setupProvider
|
|
83
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-ZSZ3EYWH.js";
|
|
85
|
+
import {
|
|
86
|
+
startCliHqConnection
|
|
87
|
+
} from "./chunk-TE3Q32JP.js";
|
|
84
88
|
import {
|
|
85
89
|
LOCAL_LLM_PRESETS,
|
|
86
90
|
addCustomProvider,
|
|
87
91
|
addKeyForCatalogProvider,
|
|
88
92
|
addKeyForProvider,
|
|
89
93
|
nextCustomProviderId,
|
|
94
|
+
ownDefinitionsAsCatalog,
|
|
90
95
|
runAuthLocal,
|
|
91
96
|
runClaudeOAuthLogin,
|
|
92
97
|
runCopilotOAuthLogin,
|
|
93
98
|
validateFamily
|
|
94
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-MNQQ4ZNF.js";
|
|
100
|
+
import "./chunk-2VMJ3E5Z.js";
|
|
95
101
|
import {
|
|
96
102
|
appendHistory
|
|
97
103
|
} from "./chunk-B4JLSXZB.js";
|
|
@@ -104,10 +110,10 @@ import {
|
|
|
104
110
|
} from "./chunk-YMXXOOFN.js";
|
|
105
111
|
import {
|
|
106
112
|
parseSpawnFlags
|
|
107
|
-
} from "./chunk-
|
|
113
|
+
} from "./chunk-Z7A5MXKJ.js";
|
|
108
114
|
import {
|
|
109
115
|
runCodexOAuthLogin
|
|
110
|
-
} from "./chunk-
|
|
116
|
+
} from "./chunk-TNK6237M.js";
|
|
111
117
|
import {
|
|
112
118
|
activeLabel,
|
|
113
119
|
loadConfigProviders,
|
|
@@ -115,19 +121,16 @@ import {
|
|
|
115
121
|
normalizeKeys,
|
|
116
122
|
nowIso,
|
|
117
123
|
writeKeysBack
|
|
118
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-DR2OXU46.js";
|
|
119
125
|
import {
|
|
120
126
|
buildWin32CmdShimInvocation
|
|
121
127
|
} from "./chunk-U3SS4NRH.js";
|
|
122
128
|
import {
|
|
123
129
|
checkForUpdate
|
|
124
130
|
} from "./chunk-YLQEGYV4.js";
|
|
125
|
-
import {
|
|
126
|
-
__require
|
|
127
|
-
} from "./chunk-7OCVIDC7.js";
|
|
128
131
|
|
|
129
132
|
// src/cli-main.ts
|
|
130
|
-
import { mailboxSessionTag as
|
|
133
|
+
import { mailboxSessionTag as mailboxSessionTag7 } from "@wrongstack/core/coordination";
|
|
131
134
|
import { TOKENS as TOKENS13 } from "@wrongstack/core/kernel";
|
|
132
135
|
import { writeErr as writeErr3 } from "@wrongstack/core/utils";
|
|
133
136
|
import { setProxyTransitionLogger } from "@wrongstack/core/wiring/proxy-rewrite";
|
|
@@ -1094,7 +1097,7 @@ async function loadOnlineAgentsForPrompt(projectDir, skip) {
|
|
|
1094
1097
|
}
|
|
1095
1098
|
}
|
|
1096
1099
|
async function getSddRuntimeStateForCli() {
|
|
1097
|
-
const sdd = await import("./sdd-runtime-
|
|
1100
|
+
const sdd = await import("./sdd-runtime-PTOSPYI4.js");
|
|
1098
1101
|
return {
|
|
1099
1102
|
tracker: sdd.getTaskTracker(),
|
|
1100
1103
|
builder: sdd.getActiveBuilder(),
|
|
@@ -1136,10 +1139,12 @@ import {
|
|
|
1136
1139
|
} from "@wrongstack/core/types";
|
|
1137
1140
|
|
|
1138
1141
|
// src/boot/brain-decision-log.ts
|
|
1142
|
+
import { BrainTierCounter } from "@wrongstack/core/coordination";
|
|
1139
1143
|
var MAX_BRAIN_LOG_ENTRIES = 20;
|
|
1140
1144
|
function subscribeBrainDecisionLog(events) {
|
|
1141
1145
|
const listeners = [];
|
|
1142
1146
|
const brainLog = [];
|
|
1147
|
+
const tierCounter = new BrainTierCounter();
|
|
1143
1148
|
const pushBrainLog = (entry) => {
|
|
1144
1149
|
brainLog.push(entry);
|
|
1145
1150
|
if (brainLog.length > MAX_BRAIN_LOG_ENTRIES) brainLog.shift();
|
|
@@ -1154,8 +1159,10 @@ function subscribeBrainDecisionLog(events) {
|
|
|
1154
1159
|
at: e.at,
|
|
1155
1160
|
kind: "answered",
|
|
1156
1161
|
question: e.request.question,
|
|
1157
|
-
outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text ?? "" : ""
|
|
1162
|
+
outcome: e.decision.type === "answer" ? e.decision.optionId ?? e.decision.text ?? "" : "",
|
|
1163
|
+
...e.tier ? { tier: e.tier } : {}
|
|
1158
1164
|
});
|
|
1165
|
+
tierCounter.record(e.tier);
|
|
1159
1166
|
});
|
|
1160
1167
|
subscribe("brain.decision_ask_human", (raw) => {
|
|
1161
1168
|
const e = raw;
|
|
@@ -1163,8 +1170,13 @@ function subscribeBrainDecisionLog(events) {
|
|
|
1163
1170
|
at: e.at,
|
|
1164
1171
|
kind: "ask_human",
|
|
1165
1172
|
question: e.request.question,
|
|
1166
|
-
|
|
1173
|
+
// A pending ask_human is the prompt; the same request lands again as
|
|
1174
|
+
// answered/denied once the human replies. Labelling them apart keeps
|
|
1175
|
+
// the ring readable when both rows are present.
|
|
1176
|
+
outcome: e.pending ? "waiting on a human" : "escalated to human",
|
|
1177
|
+
...e.tier ? { tier: e.tier } : {}
|
|
1167
1178
|
});
|
|
1179
|
+
if (!e.pending) tierCounter.record(e.tier);
|
|
1168
1180
|
});
|
|
1169
1181
|
subscribe("brain.decision_denied", (raw) => {
|
|
1170
1182
|
const e = raw;
|
|
@@ -1172,8 +1184,10 @@ function subscribeBrainDecisionLog(events) {
|
|
|
1172
1184
|
at: e.at,
|
|
1173
1185
|
kind: "denied",
|
|
1174
1186
|
question: e.request.question,
|
|
1175
|
-
outcome: e.decision.type === "deny" ? e.decision.reason ?? "" : ""
|
|
1187
|
+
outcome: e.decision.type === "deny" ? e.decision.reason ?? "" : "",
|
|
1188
|
+
...e.tier ? { tier: e.tier } : {}
|
|
1176
1189
|
});
|
|
1190
|
+
tierCounter.record(e.tier);
|
|
1177
1191
|
});
|
|
1178
1192
|
subscribe("brain.council_resolved", (raw) => {
|
|
1179
1193
|
const e = raw;
|
|
@@ -1203,7 +1217,7 @@ function subscribeBrainDecisionLog(events) {
|
|
|
1203
1217
|
);
|
|
1204
1218
|
}
|
|
1205
1219
|
};
|
|
1206
|
-
return { brainLog, pushBrainLog, dispose };
|
|
1220
|
+
return { brainLog, pushBrainLog, getTierStats: () => tierCounter.snapshot(), dispose };
|
|
1207
1221
|
}
|
|
1208
1222
|
|
|
1209
1223
|
// src/fleet/subagent-hook-runner.ts
|
|
@@ -1219,12 +1233,7 @@ function createSubagentWrongTraceHookRunner(sessionId, emit) {
|
|
|
1219
1233
|
const hooks = createWrongTraceHookPair(sessionId, {
|
|
1220
1234
|
emit: (event) => emit?.(event)
|
|
1221
1235
|
});
|
|
1222
|
-
registry.registerInProcess(
|
|
1223
|
-
"PreToolUse",
|
|
1224
|
-
WRONGTRACE_MATCHER,
|
|
1225
|
-
hooks.preToolUse,
|
|
1226
|
-
"wrongtrace-gate"
|
|
1227
|
-
);
|
|
1236
|
+
registry.registerInProcess("PreToolUse", WRONGTRACE_MATCHER, hooks.preToolUse, "wrongtrace-gate");
|
|
1228
1237
|
registry.registerInProcess(
|
|
1229
1238
|
"PostToolUse",
|
|
1230
1239
|
WRONGTRACE_MATCHER,
|
|
@@ -1236,9 +1245,7 @@ function createSubagentWrongTraceHookRunner(sessionId, emit) {
|
|
|
1236
1245
|
|
|
1237
1246
|
// src/fleet/host.ts
|
|
1238
1247
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
1239
|
-
import {
|
|
1240
|
-
createProjectAgentRoster
|
|
1241
|
-
} from "@wrongstack/core/agent-catalog";
|
|
1248
|
+
import { createProjectAgentRoster } from "@wrongstack/core/agent-catalog";
|
|
1242
1249
|
import {
|
|
1243
1250
|
AdaptiveConcurrencyController,
|
|
1244
1251
|
areSubagentsAllowedForSession as areSubagentsAllowedForSession2,
|
|
@@ -4504,7 +4511,7 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4504
4511
|
cwd,
|
|
4505
4512
|
wpaths,
|
|
4506
4513
|
teardownHandlers,
|
|
4507
|
-
mailboxSessionTag:
|
|
4514
|
+
mailboxSessionTag: mailboxSessionTag8,
|
|
4508
4515
|
brainMailbox,
|
|
4509
4516
|
agentMonitor,
|
|
4510
4517
|
manifestPath,
|
|
@@ -4629,12 +4636,17 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4629
4636
|
brainRuntime.arbiter,
|
|
4630
4637
|
brainQueue,
|
|
4631
4638
|
() => brainRuntime.getMode(),
|
|
4632
|
-
() => brainRuntime.getSnapshot().terminalPolicy
|
|
4639
|
+
() => brainRuntime.getSnapshot().terminalPolicy,
|
|
4640
|
+
events
|
|
4633
4641
|
),
|
|
4634
4642
|
events
|
|
4635
4643
|
);
|
|
4636
4644
|
container.bind(TOKENS6.BrainArbiter, () => brain);
|
|
4637
|
-
const {
|
|
4645
|
+
const {
|
|
4646
|
+
brainLog,
|
|
4647
|
+
getTierStats: brainTierStats,
|
|
4648
|
+
dispose: disposeBrainLog
|
|
4649
|
+
} = subscribeBrainDecisionLog(events);
|
|
4638
4650
|
teardownHandlers.push(disposeBrainLog);
|
|
4639
4651
|
brainMonitor = new BrainMonitor({
|
|
4640
4652
|
events,
|
|
@@ -4661,7 +4673,7 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4661
4673
|
body,
|
|
4662
4674
|
sessionId
|
|
4663
4675
|
}) => {
|
|
4664
|
-
const tag =
|
|
4676
|
+
const tag = mailboxSessionTag8(sessionId || context.session?.id || session.id);
|
|
4665
4677
|
const leaderUniqueId = `leader@${tag}`;
|
|
4666
4678
|
await brainMailbox.send({
|
|
4667
4679
|
from: `brain@${tag}`,
|
|
@@ -4787,6 +4799,7 @@ function setupBrainAndOrchestration(deps) {
|
|
|
4787
4799
|
return {
|
|
4788
4800
|
brain,
|
|
4789
4801
|
brainLog,
|
|
4802
|
+
brainTierStats,
|
|
4790
4803
|
brainSettings,
|
|
4791
4804
|
brainRuntime,
|
|
4792
4805
|
brainQueue,
|
|
@@ -4802,6 +4815,7 @@ import { gatedEnhancerReasoning } from "@wrongstack/core/execution";
|
|
|
4802
4815
|
import { TOKENS as TOKENS7 } from "@wrongstack/core/kernel";
|
|
4803
4816
|
|
|
4804
4817
|
// src/auth-menu/panel-service.ts
|
|
4818
|
+
import { parseModelRef } from "@wrongstack/core/agent";
|
|
4805
4819
|
var ANSI_RE = /\u001b\[[0-9;]*m/g;
|
|
4806
4820
|
function stripAnsi(text) {
|
|
4807
4821
|
return text.replace(ANSI_RE, "");
|
|
@@ -4836,9 +4850,10 @@ function flowDeps(base, io) {
|
|
|
4836
4850
|
function isCancel(err) {
|
|
4837
4851
|
return err instanceof Error && err.name === "AbortError" || err instanceof DOMException && err.name === "AbortError";
|
|
4838
4852
|
}
|
|
4839
|
-
async function runFlow(run) {
|
|
4853
|
+
async function runFlow(run, onSuccess) {
|
|
4840
4854
|
try {
|
|
4841
4855
|
const ok = await run();
|
|
4856
|
+
if (ok) await onSuccess?.();
|
|
4842
4857
|
return { ok };
|
|
4843
4858
|
} catch (err) {
|
|
4844
4859
|
if (isCancel(err)) return { ok: false, message: "Cancelled." };
|
|
@@ -4850,6 +4865,141 @@ function plainMaskedKey(key) {
|
|
|
4850
4865
|
if (key.length <= 8) return "\u2022".repeat(key.length);
|
|
4851
4866
|
return `${key.slice(0, 4)}\u2026${key.slice(-4)}`;
|
|
4852
4867
|
}
|
|
4868
|
+
function isRecord(value) {
|
|
4869
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4870
|
+
}
|
|
4871
|
+
function isProviderModelRef(value, providerId) {
|
|
4872
|
+
return typeof value === "string" && parseModelRef(value).provider === providerId;
|
|
4873
|
+
}
|
|
4874
|
+
function removeProviderFallbackReferences(config, providerId) {
|
|
4875
|
+
const removeModelRefs = (value) => Array.isArray(value) ? value.filter((ref) => !isProviderModelRef(ref, providerId)) : void 0;
|
|
4876
|
+
if (Array.isArray(config["fallbackModels"])) {
|
|
4877
|
+
config["fallbackModels"] = removeModelRefs(config["fallbackModels"]);
|
|
4878
|
+
}
|
|
4879
|
+
if (typeof config["fallbackBridge"] === "string" && isProviderModelRef(config["fallbackBridge"], providerId)) {
|
|
4880
|
+
delete config["fallbackBridge"];
|
|
4881
|
+
}
|
|
4882
|
+
if (Array.isArray(config["favoriteModels"])) {
|
|
4883
|
+
config["favoriteModels"] = removeModelRefs(config["favoriteModels"]);
|
|
4884
|
+
}
|
|
4885
|
+
if (isRecord(config["models"])) {
|
|
4886
|
+
for (const [modelId, definition] of Object.entries(config["models"])) {
|
|
4887
|
+
if (isRecord(definition) && definition["provider"] === providerId) {
|
|
4888
|
+
delete config["models"][modelId];
|
|
4889
|
+
}
|
|
4890
|
+
}
|
|
4891
|
+
if (Object.keys(config["models"]).length === 0) delete config["models"];
|
|
4892
|
+
}
|
|
4893
|
+
const removedProfiles = /* @__PURE__ */ new Set();
|
|
4894
|
+
if (isRecord(config["fallbackProfiles"])) {
|
|
4895
|
+
const profiles = config["fallbackProfiles"];
|
|
4896
|
+
for (const [name, chain] of Object.entries(profiles)) {
|
|
4897
|
+
if (!Array.isArray(chain)) continue;
|
|
4898
|
+
const next = chain.filter((ref) => !isProviderModelRef(ref, providerId));
|
|
4899
|
+
if (next.length === 0) {
|
|
4900
|
+
delete profiles[name];
|
|
4901
|
+
removedProfiles.add(name);
|
|
4902
|
+
} else {
|
|
4903
|
+
profiles[name] = next;
|
|
4904
|
+
}
|
|
4905
|
+
}
|
|
4906
|
+
if (Object.keys(profiles).length === 0) delete config["fallbackProfiles"];
|
|
4907
|
+
}
|
|
4908
|
+
const clearRemovedProfile = (entry) => {
|
|
4909
|
+
if (typeof entry["fallbackProfile"] === "string" && removedProfiles.has(entry["fallbackProfile"])) {
|
|
4910
|
+
delete entry["fallbackProfile"];
|
|
4911
|
+
}
|
|
4912
|
+
};
|
|
4913
|
+
if (typeof config["fallbackProfile"] === "string" && removedProfiles.has(config["fallbackProfile"])) {
|
|
4914
|
+
delete config["fallbackProfile"];
|
|
4915
|
+
}
|
|
4916
|
+
if (isRecord(config["modelMatrix"])) {
|
|
4917
|
+
for (const [role, value] of Object.entries(config["modelMatrix"])) {
|
|
4918
|
+
if (!isRecord(value)) continue;
|
|
4919
|
+
if (value["provider"] === providerId) {
|
|
4920
|
+
delete value["provider"];
|
|
4921
|
+
delete value["model"];
|
|
4922
|
+
}
|
|
4923
|
+
clearRemovedProfile(value);
|
|
4924
|
+
if (Object.keys(value).length === 0) delete config["modelMatrix"][role];
|
|
4925
|
+
}
|
|
4926
|
+
if (Object.keys(config["modelMatrix"]).length === 0) delete config["modelMatrix"];
|
|
4927
|
+
}
|
|
4928
|
+
if (isRecord(config["modelTiers"]) && isRecord(config["modelTiers"]["levels"])) {
|
|
4929
|
+
const levels = config["modelTiers"]["levels"];
|
|
4930
|
+
for (const level of Object.values(levels)) {
|
|
4931
|
+
if (!isRecord(level)) continue;
|
|
4932
|
+
if (level["provider"] === providerId) {
|
|
4933
|
+
delete level["provider"];
|
|
4934
|
+
delete level["model"];
|
|
4935
|
+
}
|
|
4936
|
+
clearRemovedProfile(level);
|
|
4937
|
+
}
|
|
4938
|
+
}
|
|
4939
|
+
if (isRecord(config["autonomy"])) {
|
|
4940
|
+
const autonomy = config["autonomy"];
|
|
4941
|
+
if (autonomy["refinerProvider"] === providerId) {
|
|
4942
|
+
delete autonomy["refinerProvider"];
|
|
4943
|
+
delete autonomy["refinerModel"];
|
|
4944
|
+
}
|
|
4945
|
+
if (isProviderModelRef(autonomy["enhanceFallbackModel"], providerId)) {
|
|
4946
|
+
delete autonomy["enhanceFallbackModel"];
|
|
4947
|
+
}
|
|
4948
|
+
if (typeof autonomy["refinerFallbackProfile"] === "string" && removedProfiles.has(autonomy["refinerFallbackProfile"])) {
|
|
4949
|
+
delete autonomy["refinerFallbackProfile"];
|
|
4950
|
+
}
|
|
4951
|
+
}
|
|
4952
|
+
if (isRecord(config["brain"])) {
|
|
4953
|
+
const brain = config["brain"];
|
|
4954
|
+
if (Array.isArray(brain["models"])) {
|
|
4955
|
+
brain["models"] = brain["models"].filter(
|
|
4956
|
+
(entry) => !isProviderModelRef(entry, providerId) && !(isRecord(entry) && entry["provider"] === providerId)
|
|
4957
|
+
);
|
|
4958
|
+
}
|
|
4959
|
+
if (isRecord(brain["council"])) {
|
|
4960
|
+
const council = brain["council"];
|
|
4961
|
+
if (Array.isArray(council["voters"])) {
|
|
4962
|
+
council["voters"] = council["voters"].filter(
|
|
4963
|
+
(entry) => !isProviderModelRef(entry, providerId) && !(isRecord(entry) && entry["provider"] === providerId)
|
|
4964
|
+
);
|
|
4965
|
+
}
|
|
4966
|
+
if (isProviderModelRef(council["judge"], providerId) || isRecord(council["judge"]) && council["judge"]["provider"] === providerId) {
|
|
4967
|
+
delete council["judge"];
|
|
4968
|
+
}
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
const councilProfiles = isRecord(config["tools"]) && isRecord(config["tools"]["council"]) ? config["tools"]["council"]["profiles"] : void 0;
|
|
4972
|
+
if (Array.isArray(councilProfiles)) {
|
|
4973
|
+
for (const profile of councilProfiles) {
|
|
4974
|
+
if (!isRecord(profile)) continue;
|
|
4975
|
+
for (const seat of Array.isArray(profile["seats"]) ? profile["seats"] : []) {
|
|
4976
|
+
if (!isRecord(seat) || !isRecord(seat["target"])) continue;
|
|
4977
|
+
const target = seat["target"];
|
|
4978
|
+
if (target["providerId"] === providerId) {
|
|
4979
|
+
delete target["providerId"];
|
|
4980
|
+
delete target["model"];
|
|
4981
|
+
}
|
|
4982
|
+
if (Array.isArray(target["fallbackModels"])) {
|
|
4983
|
+
target["fallbackModels"] = removeModelRefs(target["fallbackModels"]);
|
|
4984
|
+
}
|
|
4985
|
+
clearRemovedProfile(target);
|
|
4986
|
+
if (Object.keys(target).length === 0) delete seat["target"];
|
|
4987
|
+
}
|
|
4988
|
+
if (isRecord(profile["judge"])) {
|
|
4989
|
+
const judge = profile["judge"];
|
|
4990
|
+
if (judge["providerId"] === providerId) {
|
|
4991
|
+
delete judge["providerId"];
|
|
4992
|
+
delete judge["model"];
|
|
4993
|
+
}
|
|
4994
|
+
if (Array.isArray(judge["fallbackModels"])) {
|
|
4995
|
+
judge["fallbackModels"] = removeModelRefs(judge["fallbackModels"]);
|
|
4996
|
+
}
|
|
4997
|
+
clearRemovedProfile(judge);
|
|
4998
|
+
if (Object.keys(judge).length === 0) delete profile["judge"];
|
|
4999
|
+
}
|
|
5000
|
+
}
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
4853
5003
|
function createAuthPanelHost(deps) {
|
|
4854
5004
|
const loadProviders = () => loadConfigProviders(deps.profileConfigPath, deps.vault);
|
|
4855
5005
|
const mutate = async (mutator) => {
|
|
@@ -4858,14 +5008,21 @@ function createAuthPanelHost(deps) {
|
|
|
4858
5008
|
await mutateConfigProviders(
|
|
4859
5009
|
deps.profileConfigPath,
|
|
4860
5010
|
deps.vault,
|
|
4861
|
-
(all) => {
|
|
4862
|
-
result = mutator(all);
|
|
5011
|
+
(all, config) => {
|
|
5012
|
+
result = mutator(all, config);
|
|
4863
5013
|
},
|
|
4864
5014
|
deps.profileConfigPath
|
|
4865
5015
|
);
|
|
4866
5016
|
} catch (err) {
|
|
4867
5017
|
return err instanceof Error ? err.message : String(err);
|
|
4868
5018
|
}
|
|
5019
|
+
if (result === null && deps.onProvidersChanged) {
|
|
5020
|
+
try {
|
|
5021
|
+
await deps.onProvidersChanged();
|
|
5022
|
+
} catch (err) {
|
|
5023
|
+
return `Saved, but live config reload failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
5024
|
+
}
|
|
5025
|
+
}
|
|
4869
5026
|
return result;
|
|
4870
5027
|
};
|
|
4871
5028
|
return {
|
|
@@ -4903,7 +5060,10 @@ function createAuthPanelHost(deps) {
|
|
|
4903
5060
|
loadProviders()
|
|
4904
5061
|
]);
|
|
4905
5062
|
const saved = new Set(Object.keys(providers));
|
|
4906
|
-
return
|
|
5063
|
+
return [
|
|
5064
|
+
...catalog,
|
|
5065
|
+
...ownDefinitionsAsCatalog(new Set(catalog.map((provider) => provider.id)))
|
|
5066
|
+
].filter((p) => p.family !== "unsupported").sort((a, b) => a.id.localeCompare(b.id)).map((p) => ({
|
|
4907
5067
|
id: p.id,
|
|
4908
5068
|
name: p.name || p.id,
|
|
4909
5069
|
family: p.family,
|
|
@@ -4939,9 +5099,10 @@ function createAuthPanelHost(deps) {
|
|
|
4939
5099
|
});
|
|
4940
5100
|
},
|
|
4941
5101
|
removeProvider(providerId) {
|
|
4942
|
-
return mutate((all) => {
|
|
5102
|
+
return mutate((all, config) => {
|
|
4943
5103
|
if (!all[providerId]) return `Provider "${providerId}" no longer in config.`;
|
|
4944
5104
|
delete all[providerId];
|
|
5105
|
+
removeProviderFallbackReferences(config, providerId);
|
|
4945
5106
|
return null;
|
|
4946
5107
|
});
|
|
4947
5108
|
},
|
|
@@ -4950,6 +5111,157 @@ function createAuthPanelHost(deps) {
|
|
|
4950
5111
|
const providers = await loadProviders();
|
|
4951
5112
|
const template = providers[providerId] ?? { type: providerId };
|
|
4952
5113
|
return addKeyForProvider(providerId, flowDeps(deps, io), template);
|
|
5114
|
+
}, deps.onProvidersChanged);
|
|
5115
|
+
},
|
|
5116
|
+
async saveProviderSetup(setup) {
|
|
5117
|
+
const type = setup.type.trim();
|
|
5118
|
+
const alias = setup.alias.trim();
|
|
5119
|
+
const keyLabel = setup.keyLabel.trim();
|
|
5120
|
+
const apiKey = setup.apiKey.trim();
|
|
5121
|
+
const family = validateFamily(setup.family);
|
|
5122
|
+
if (!type) return "Provider id is required.";
|
|
5123
|
+
if (!alias) return "Alias is required.";
|
|
5124
|
+
if (!family) return "Choose a supported protocol family.";
|
|
5125
|
+
if (!keyLabel) return "Key alias is required.";
|
|
5126
|
+
if (!apiKey) return "API key is required.";
|
|
5127
|
+
const split = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
5128
|
+
const baseUrl = setup.baseUrl.trim();
|
|
5129
|
+
const models = split(setup.models);
|
|
5130
|
+
const envVars = split(setup.envVars);
|
|
5131
|
+
let catalogDefaultModel;
|
|
5132
|
+
try {
|
|
5133
|
+
catalogDefaultModel = (await deps.modelsRegistry.getProvider(type))?.models?.[0]?.id;
|
|
5134
|
+
} catch {
|
|
5135
|
+
}
|
|
5136
|
+
const result = await mutate((all, config) => {
|
|
5137
|
+
const existing = all[alias];
|
|
5138
|
+
if (existing) {
|
|
5139
|
+
const existingFamily = existing.family ?? family;
|
|
5140
|
+
const existingBaseUrl = existing.baseUrl ?? "";
|
|
5141
|
+
if (existingFamily !== family || existingBaseUrl !== baseUrl) {
|
|
5142
|
+
return `Alias "${alias}" already uses ${existingFamily} / ${existingBaseUrl || "default endpoint"}. Choose a different alias.`;
|
|
5143
|
+
}
|
|
5144
|
+
if (existing.type && existing.type !== type) {
|
|
5145
|
+
return `Alias "${alias}" already belongs to provider type "${existing.type}".`;
|
|
5146
|
+
}
|
|
5147
|
+
}
|
|
5148
|
+
const provider = existing ?? { type, family };
|
|
5149
|
+
provider.type = type;
|
|
5150
|
+
provider.family = family;
|
|
5151
|
+
if (baseUrl) provider.baseUrl = baseUrl;
|
|
5152
|
+
else delete provider.baseUrl;
|
|
5153
|
+
if (models.length > 0) provider.models = models;
|
|
5154
|
+
else if (setup.source === "custom") delete provider.models;
|
|
5155
|
+
if (envVars.length > 0) provider.envVars = envVars;
|
|
5156
|
+
else if (setup.source === "custom") delete provider.envVars;
|
|
5157
|
+
const keys = normalizeKeys(provider);
|
|
5158
|
+
if (keys.some((key) => key.label === keyLabel)) {
|
|
5159
|
+
return `Key alias "${keyLabel}" already exists for "${alias}". Pick another key alias or update that key.`;
|
|
5160
|
+
}
|
|
5161
|
+
keys.push({ label: keyLabel, apiKey, createdAt: nowIso() });
|
|
5162
|
+
writeKeysBack(provider, keys);
|
|
5163
|
+
if (!provider.activeKey) provider.activeKey = keyLabel;
|
|
5164
|
+
all[alias] = provider;
|
|
5165
|
+
if ((!config["provider"] || !config["model"]) && catalogDefaultModel) {
|
|
5166
|
+
config["provider"] = alias;
|
|
5167
|
+
config["model"] = catalogDefaultModel;
|
|
5168
|
+
}
|
|
5169
|
+
return null;
|
|
5170
|
+
});
|
|
5171
|
+
return result;
|
|
5172
|
+
},
|
|
5173
|
+
async saveProviderEdit(edit) {
|
|
5174
|
+
const providerId = edit.providerId.trim();
|
|
5175
|
+
const family = validateFamily(edit.family);
|
|
5176
|
+
if (!providerId) return "Provider id is required.";
|
|
5177
|
+
if (!family) return "Choose a supported protocol family.";
|
|
5178
|
+
const list = (value) => value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
5179
|
+
const baseUrl = edit.baseUrl.trim();
|
|
5180
|
+
const models = list(edit.models);
|
|
5181
|
+
const envVars = list(edit.envVars);
|
|
5182
|
+
return mutate((all) => {
|
|
5183
|
+
const provider = all[providerId];
|
|
5184
|
+
if (!provider) return `Provider "${providerId}" no longer in config.`;
|
|
5185
|
+
provider.family = family;
|
|
5186
|
+
if (baseUrl) provider.baseUrl = baseUrl;
|
|
5187
|
+
else delete provider.baseUrl;
|
|
5188
|
+
if (models.length > 0) provider.models = models;
|
|
5189
|
+
else delete provider.models;
|
|
5190
|
+
if (envVars.length > 0) provider.envVars = envVars;
|
|
5191
|
+
else delete provider.envVars;
|
|
5192
|
+
return null;
|
|
5193
|
+
});
|
|
5194
|
+
},
|
|
5195
|
+
async getModelEdit(providerId, modelId) {
|
|
5196
|
+
const provider = (await loadProviders())[providerId];
|
|
5197
|
+
if (!provider?.models?.includes(modelId)) return null;
|
|
5198
|
+
const details = provider.customModels?.[modelId];
|
|
5199
|
+
const modelsDev = details?.modelsDev ?? {};
|
|
5200
|
+
const limit = modelsDev["limit"];
|
|
5201
|
+
const cost = modelsDev["cost"];
|
|
5202
|
+
return {
|
|
5203
|
+
providerId,
|
|
5204
|
+
modelId,
|
|
5205
|
+
name: typeof modelsDev["name"] === "string" ? modelsDev["name"] : "",
|
|
5206
|
+
contextWindow: limit?.["context"] === void 0 ? "" : String(limit["context"]),
|
|
5207
|
+
maxOutput: details?.maxOutput === void 0 ? limit?.["output"] === void 0 ? "" : String(limit["output"]) : String(details.maxOutput),
|
|
5208
|
+
costInput: cost?.["input"] === void 0 ? "" : String(cost["input"]),
|
|
5209
|
+
costOutput: cost?.["output"] === void 0 ? "" : String(cost["output"])
|
|
5210
|
+
};
|
|
5211
|
+
},
|
|
5212
|
+
async saveModelEdit(edit) {
|
|
5213
|
+
const parse = (value, label) => {
|
|
5214
|
+
if (!value.trim()) return void 0;
|
|
5215
|
+
const number = Number(value);
|
|
5216
|
+
return Number.isFinite(number) && number >= 0 ? number : `${label} must be a non-negative number.`;
|
|
5217
|
+
};
|
|
5218
|
+
const context = parse(edit.contextWindow, "Context window");
|
|
5219
|
+
const output = parse(edit.maxOutput, "Max output");
|
|
5220
|
+
const inputCost = parse(edit.costInput, "Input cost");
|
|
5221
|
+
const outputCost = parse(edit.costOutput, "Output cost");
|
|
5222
|
+
for (const value of [context, output, inputCost, outputCost]) if (typeof value === "string") return value;
|
|
5223
|
+
return mutate((all) => {
|
|
5224
|
+
const provider = all[edit.providerId];
|
|
5225
|
+
if (!provider?.models?.includes(edit.modelId)) return `Model "${edit.modelId}" no longer exists.`;
|
|
5226
|
+
const existing = provider.customModels?.[edit.modelId] ?? {};
|
|
5227
|
+
const modelsDev = { ...existing.modelsDev ?? {} };
|
|
5228
|
+
if (edit.name.trim()) modelsDev["name"] = edit.name.trim();
|
|
5229
|
+
else delete modelsDev["name"];
|
|
5230
|
+
const limit = { ...modelsDev["limit"] ?? {} };
|
|
5231
|
+
if (context === void 0) delete limit["context"];
|
|
5232
|
+
else limit["context"] = context;
|
|
5233
|
+
if (output === void 0) delete limit["output"];
|
|
5234
|
+
else limit["output"] = output;
|
|
5235
|
+
if (Object.keys(limit).length) modelsDev["limit"] = limit;
|
|
5236
|
+
else delete modelsDev["limit"];
|
|
5237
|
+
const cost = { ...modelsDev["cost"] ?? {} };
|
|
5238
|
+
if (inputCost === void 0) delete cost["input"];
|
|
5239
|
+
else cost["input"] = inputCost;
|
|
5240
|
+
if (outputCost === void 0) delete cost["output"];
|
|
5241
|
+
else cost["output"] = outputCost;
|
|
5242
|
+
if (Object.keys(cost).length) modelsDev["cost"] = cost;
|
|
5243
|
+
else delete modelsDev["cost"];
|
|
5244
|
+
if (!provider.customModels) provider.customModels = {};
|
|
5245
|
+
provider.customModels[edit.modelId] = { ...existing, ...Object.keys(modelsDev).length ? { modelsDev } : {} };
|
|
5246
|
+
return null;
|
|
5247
|
+
});
|
|
5248
|
+
},
|
|
5249
|
+
async saveKeyEdit(edit) {
|
|
5250
|
+
const label = edit.label.trim();
|
|
5251
|
+
const apiKey = edit.apiKey.trim();
|
|
5252
|
+
if (!label) return "Key alias is required.";
|
|
5253
|
+
if (!apiKey) return "API key is required.";
|
|
5254
|
+
return mutate((all) => {
|
|
5255
|
+
const provider = all[edit.providerId];
|
|
5256
|
+
if (!provider) return `Provider "${edit.providerId}" no longer in config.`;
|
|
5257
|
+
const keys = normalizeKeys(provider);
|
|
5258
|
+
const original = edit.originalLabel;
|
|
5259
|
+
if (original && !keys.some((key) => key.label === original)) return `Key "${original}" not found.`;
|
|
5260
|
+
if (keys.some((key) => key.label === label && key.label !== original)) return `Key alias "${label}" already exists.`;
|
|
5261
|
+
const next = original ? keys.map((key) => key.label === original ? { ...key, label, apiKey, createdAt: nowIso() } : key) : [...keys, { label, apiKey, createdAt: nowIso() }];
|
|
5262
|
+
writeKeysBack(provider, next);
|
|
5263
|
+
if (!provider.activeKey || provider.activeKey === original) provider.activeKey = label;
|
|
5264
|
+
return null;
|
|
4953
5265
|
});
|
|
4954
5266
|
},
|
|
4955
5267
|
updateKey(providerId, label, io) {
|
|
@@ -4976,7 +5288,7 @@ function createAuthPanelHost(deps) {
|
|
|
4976
5288
|
}
|
|
4977
5289
|
io.onLog(`\u2713 Updated ${providerId}/${label}.`);
|
|
4978
5290
|
return true;
|
|
4979
|
-
});
|
|
5291
|
+
}, deps.onProvidersChanged);
|
|
4980
5292
|
},
|
|
4981
5293
|
editField(providerId, field, io) {
|
|
4982
5294
|
return runFlow(async () => {
|
|
@@ -5062,7 +5374,7 @@ function createAuthPanelHost(deps) {
|
|
|
5062
5374
|
}
|
|
5063
5375
|
io.onLog(`\u2713 models \u2192 ${list.length === 0 ? "(catalog default)" : list.join(", ")}`);
|
|
5064
5376
|
return true;
|
|
5065
|
-
});
|
|
5377
|
+
}, deps.onProvidersChanged);
|
|
5066
5378
|
},
|
|
5067
5379
|
editModelDetails(providerId, modelId, io) {
|
|
5068
5380
|
return runFlow(async () => {
|
|
@@ -5156,7 +5468,7 @@ function createAuthPanelHost(deps) {
|
|
|
5156
5468
|
}
|
|
5157
5469
|
io.onLog(`\u2713 ${modelId} updated`);
|
|
5158
5470
|
return true;
|
|
5159
|
-
});
|
|
5471
|
+
}, deps.onProvidersChanged);
|
|
5160
5472
|
},
|
|
5161
5473
|
addModel(providerId, io, opts) {
|
|
5162
5474
|
return runFlow(async () => {
|
|
@@ -5194,7 +5506,7 @@ function createAuthPanelHost(deps) {
|
|
|
5194
5506
|
}
|
|
5195
5507
|
io.onLog(`\u2713 Added model "${modelId}" to ${providerId}`);
|
|
5196
5508
|
return true;
|
|
5197
|
-
});
|
|
5509
|
+
}, deps.onProvidersChanged);
|
|
5198
5510
|
},
|
|
5199
5511
|
removeModel(providerId, modelId) {
|
|
5200
5512
|
return (async () => {
|
|
@@ -5244,10 +5556,10 @@ function createAuthPanelHost(deps) {
|
|
|
5244
5556
|
return false;
|
|
5245
5557
|
}
|
|
5246
5558
|
return addKeyForCatalogProvider(flowDeps(deps, io), chosen);
|
|
5247
|
-
});
|
|
5559
|
+
}, deps.onProvidersChanged);
|
|
5248
5560
|
},
|
|
5249
5561
|
addCustomProvider(io) {
|
|
5250
|
-
return runFlow(() => addCustomProvider(flowDeps(deps, io)));
|
|
5562
|
+
return runFlow(() => addCustomProvider(flowDeps(deps, io)), deps.onProvidersChanged);
|
|
5251
5563
|
},
|
|
5252
5564
|
addLocal(presetId, io) {
|
|
5253
5565
|
return runFlow(async () => {
|
|
@@ -5263,7 +5575,7 @@ function createAuthPanelHost(deps) {
|
|
|
5263
5575
|
models: "999"
|
|
5264
5576
|
});
|
|
5265
5577
|
return code === 0;
|
|
5266
|
-
});
|
|
5578
|
+
}, deps.onProvidersChanged);
|
|
5267
5579
|
},
|
|
5268
5580
|
oauthLogin(kind, io) {
|
|
5269
5581
|
return runFlow(async () => {
|
|
@@ -5271,7 +5583,7 @@ function createAuthPanelHost(deps) {
|
|
|
5271
5583
|
const opts = { signal: io.signal };
|
|
5272
5584
|
const code = kind === "chatgpt" ? await runCodexOAuthLogin(d, opts) : kind === "claude" ? await runClaudeOAuthLogin(d, opts) : await runCopilotOAuthLogin(d, opts);
|
|
5273
5585
|
return code === 0;
|
|
5274
|
-
});
|
|
5586
|
+
}, deps.onProvidersChanged);
|
|
5275
5587
|
}
|
|
5276
5588
|
};
|
|
5277
5589
|
}
|
|
@@ -5299,6 +5611,9 @@ function createRuntimeControllerDeps(input) {
|
|
|
5299
5611
|
statuslineLines: input.statuslineLines,
|
|
5300
5612
|
setStatuslineLines: input.setStatuslineLines,
|
|
5301
5613
|
saveStatuslineLines: input.saveStatuslineLines,
|
|
5614
|
+
statuslineDensities: input.statuslineDensities,
|
|
5615
|
+
setStatuslineDensities: input.setStatuslineDensities,
|
|
5616
|
+
saveStatuslineDensities: input.saveStatuslineDensities,
|
|
5302
5617
|
getYolo: input.getYolo,
|
|
5303
5618
|
onYolo: input.onYolo,
|
|
5304
5619
|
getAutonomy: input.getAutonomy,
|
|
@@ -5654,6 +5969,7 @@ async function runCliExecution(params) {
|
|
|
5654
5969
|
resolvedProvider,
|
|
5655
5970
|
logger,
|
|
5656
5971
|
switchProviderAndModel,
|
|
5972
|
+
reloadProviderConfig,
|
|
5657
5973
|
applyMaxContext,
|
|
5658
5974
|
renderer,
|
|
5659
5975
|
reader,
|
|
@@ -5682,6 +5998,9 @@ async function runCliExecution(params) {
|
|
|
5682
5998
|
statuslineLines,
|
|
5683
5999
|
setStatuslineLines,
|
|
5684
6000
|
saveStatuslineLines: saveStatuslineLines2,
|
|
6001
|
+
statuslineDensities,
|
|
6002
|
+
setStatuslineDensities,
|
|
6003
|
+
saveStatuslineDensities,
|
|
5685
6004
|
setYoloMode,
|
|
5686
6005
|
autonomyMode,
|
|
5687
6006
|
setAutonomyMode,
|
|
@@ -5710,7 +6029,7 @@ async function runCliExecution(params) {
|
|
|
5710
6029
|
governanceHandle,
|
|
5711
6030
|
setConfig
|
|
5712
6031
|
} = params;
|
|
5713
|
-
const { execute } = await import("./execution-
|
|
6032
|
+
const { execute } = await import("./execution-3Y55IWBK.js");
|
|
5714
6033
|
return execute(
|
|
5715
6034
|
toExecuteDeps({
|
|
5716
6035
|
core: {
|
|
@@ -5786,7 +6105,8 @@ async function runCliExecution(params) {
|
|
|
5786
6105
|
authHost: createAuthPanelHost({
|
|
5787
6106
|
vault,
|
|
5788
6107
|
modelsRegistry,
|
|
5789
|
-
profileConfigPath
|
|
6108
|
+
profileConfigPath,
|
|
6109
|
+
onProvidersChanged: reloadProviderConfig
|
|
5790
6110
|
}),
|
|
5791
6111
|
onPanelOpen
|
|
5792
6112
|
},
|
|
@@ -5826,6 +6146,9 @@ async function runCliExecution(params) {
|
|
|
5826
6146
|
statuslineLines,
|
|
5827
6147
|
setStatuslineLines,
|
|
5828
6148
|
saveStatuslineLines: saveStatuslineLines2,
|
|
6149
|
+
statuslineDensities,
|
|
6150
|
+
setStatuslineDensities,
|
|
6151
|
+
saveStatuslineDensities,
|
|
5829
6152
|
getYolo: setYoloMode,
|
|
5830
6153
|
onYolo: setYoloMode,
|
|
5831
6154
|
getAutonomy: () => autonomyMode,
|
|
@@ -5918,6 +6241,7 @@ import { makeAutonomyPromptContributor } from "@wrongstack/core/execution";
|
|
|
5918
6241
|
import { sessionScopedPath } from "@wrongstack/core/utils";
|
|
5919
6242
|
|
|
5920
6243
|
// src/wiring/wrongtrace-prompt-contributor.ts
|
|
6244
|
+
import { normalizeTokenSavingTier as normalizeTokenSavingTier2 } from "@wrongstack/core/types";
|
|
5921
6245
|
import { digestAtlas, summarizeFriction } from "@wrongstack/wrongtrace";
|
|
5922
6246
|
var CONTRIBUTOR_DEADLINE_MS = 800;
|
|
5923
6247
|
function raceWithDeadline(p, ms) {
|
|
@@ -5936,16 +6260,16 @@ function raceWithDeadline(p, ms) {
|
|
|
5936
6260
|
);
|
|
5937
6261
|
});
|
|
5938
6262
|
}
|
|
5939
|
-
function createWrongTracePromptContributor() {
|
|
5940
|
-
|
|
6263
|
+
function createWrongTracePromptContributor(options = {}) {
|
|
6264
|
+
const tier = normalizeTokenSavingTier2(options.tokenSavingMode);
|
|
6265
|
+
return async (ctx) => {
|
|
6266
|
+
if (ctx.subagent) return [];
|
|
6267
|
+
if (tier === "minimal" || tier === "aggressive") return [];
|
|
5941
6268
|
try {
|
|
5942
6269
|
const wt = await raceWithDeadline(getWrongTrace(), CONTRIBUTOR_DEADLINE_MS);
|
|
5943
6270
|
if (!wt?.isAvailable) return [];
|
|
5944
6271
|
const [atlas, friction] = await raceWithDeadline(
|
|
5945
|
-
Promise.all([
|
|
5946
|
-
wt.getAtlas({ includeSymbols: false }),
|
|
5947
|
-
wt.getFrictionMatrix(50)
|
|
5948
|
-
]),
|
|
6272
|
+
Promise.all([wt.getAtlas({ includeSymbols: false }), wt.getFrictionMatrix(50)]),
|
|
5949
6273
|
CONTRIBUTOR_DEADLINE_MS
|
|
5950
6274
|
) ?? [null, []];
|
|
5951
6275
|
const digest = digestAtlas(atlas);
|
|
@@ -6036,7 +6360,9 @@ function bindSystemPromptBuilder(deps) {
|
|
|
6036
6360
|
// is reachable, the leader prompt carries a compact atlas digest +
|
|
6037
6361
|
// friction summary block. Fail-open and deadline-bounded (<1s), so
|
|
6038
6362
|
// an absent/slow daemon never stalls the boot prompt.
|
|
6039
|
-
createWrongTracePromptContributor(
|
|
6363
|
+
createWrongTracePromptContributor({
|
|
6364
|
+
tokenSavingMode: deps.tokenSavingMode
|
|
6365
|
+
})
|
|
6040
6366
|
]
|
|
6041
6367
|
})
|
|
6042
6368
|
);
|
|
@@ -6051,7 +6377,7 @@ import {
|
|
|
6051
6377
|
makeSessionNoteTool as makeSessionNoteTool2
|
|
6052
6378
|
} from "@wrongstack/core/coordination";
|
|
6053
6379
|
import { createContextManagerTool } from "@wrongstack/core/infrastructure";
|
|
6054
|
-
import { normalizeTokenSavingTier as
|
|
6380
|
+
import { normalizeTokenSavingTier as normalizeTokenSavingTier3 } from "@wrongstack/core/types";
|
|
6055
6381
|
import { configureChildEnvGitIdentity } from "@wrongstack/core/utils";
|
|
6056
6382
|
import { registerCanonicalHostTools } from "@wrongstack/runtime/tool-registration";
|
|
6057
6383
|
import { configureDangerBypass, configureExecPolicy } from "@wrongstack/tools";
|
|
@@ -6684,7 +7010,7 @@ ${commit.out}`;
|
|
|
6684
7010
|
|
|
6685
7011
|
// src/boot/tool-registry.ts
|
|
6686
7012
|
function registerBuiltinTools(deps) {
|
|
6687
|
-
const tier =
|
|
7013
|
+
const tier = normalizeTokenSavingTier3(deps.config.features.tokenSavingMode);
|
|
6688
7014
|
registerCanonicalHostTools({
|
|
6689
7015
|
registry: deps.toolRegistry,
|
|
6690
7016
|
tier,
|
|
@@ -7605,9 +7931,9 @@ async function generateCommitMessageWithLLM(diff, opts) {
|
|
|
7605
7931
|
const userPrompt = `Here is the git diff:
|
|
7606
7932
|
|
|
7607
7933
|
${diff}`;
|
|
7934
|
+
const signal = new AbortController();
|
|
7935
|
+
const timeout = setTimeout(() => signal.abort(), 15e3);
|
|
7608
7936
|
try {
|
|
7609
|
-
const signal = new AbortController();
|
|
7610
|
-
const timeout = setTimeout(() => signal.abort(), 15e3);
|
|
7611
7937
|
const resp = await opts.provider.complete(
|
|
7612
7938
|
{
|
|
7613
7939
|
model: opts.model,
|
|
@@ -7618,7 +7944,6 @@ ${diff}`;
|
|
|
7618
7944
|
},
|
|
7619
7945
|
{ signal: signal.signal }
|
|
7620
7946
|
);
|
|
7621
|
-
clearTimeout(timeout);
|
|
7622
7947
|
const rawContent = resp.content;
|
|
7623
7948
|
const text = Array.isArray(rawContent) ? rawContent[0]?.text ?? "" : typeof rawContent === "object" && rawContent !== null ? rawContent.text ?? "" : String(rawContent);
|
|
7624
7949
|
const message = expectDefined3(text.trim().split("\n")[0]);
|
|
@@ -7626,6 +7951,8 @@ ${diff}`;
|
|
|
7626
7951
|
return message;
|
|
7627
7952
|
}
|
|
7628
7953
|
} catch {
|
|
7954
|
+
} finally {
|
|
7955
|
+
clearTimeout(timeout);
|
|
7629
7956
|
}
|
|
7630
7957
|
return "chore: update";
|
|
7631
7958
|
}
|
|
@@ -8041,57 +8368,25 @@ function formatDiagnostics(input) {
|
|
|
8041
8368
|
import * as fs3 from "node:fs/promises";
|
|
8042
8369
|
import * as os from "node:os";
|
|
8043
8370
|
import * as path9 from "node:path";
|
|
8371
|
+
import {
|
|
8372
|
+
clampLine,
|
|
8373
|
+
defaultChipEnabledMap,
|
|
8374
|
+
STATUSLINE_DENSITY_LEVELS,
|
|
8375
|
+
STATUSLINE_ITEMS
|
|
8376
|
+
} from "@wrongstack/core/statusline";
|
|
8044
8377
|
import { ERROR_CODES, FsError } from "@wrongstack/core/types";
|
|
8045
8378
|
import { atomicWrite, resolveWstackPaths, toErrorMessage as toErrorMessage3 } from "@wrongstack/core/utils";
|
|
8046
8379
|
var CONFIG_ENV = "WRONGSTACK_STATUSLINE_CONFIG";
|
|
8047
|
-
var STATUSLINE_CONFIG_VERSION =
|
|
8048
|
-
var STATUSLINE_CONFIG_KEYS =
|
|
8049
|
-
|
|
8050
|
-
"model",
|
|
8051
|
-
"context",
|
|
8052
|
-
"tokens",
|
|
8053
|
-
"cache",
|
|
8054
|
-
"cost",
|
|
8055
|
-
"queue",
|
|
8056
|
-
"hint",
|
|
8057
|
-
"index",
|
|
8058
|
-
"breaker",
|
|
8059
|
-
"yolo",
|
|
8060
|
-
"autonomy",
|
|
8061
|
-
"eternal_stage",
|
|
8062
|
-
"elapsed",
|
|
8063
|
-
"project",
|
|
8064
|
-
"working_dir",
|
|
8065
|
-
"goal",
|
|
8066
|
-
"mode",
|
|
8067
|
-
"auto_proceed",
|
|
8068
|
-
"git",
|
|
8069
|
-
"sessions",
|
|
8070
|
-
"tools",
|
|
8071
|
-
"theme",
|
|
8072
|
-
"token_saving",
|
|
8073
|
-
"processes",
|
|
8074
|
-
"version",
|
|
8075
|
-
"dropped_tools",
|
|
8076
|
-
"prompt_variant",
|
|
8077
|
-
"side_effects",
|
|
8078
|
-
"todos",
|
|
8079
|
-
"plan",
|
|
8080
|
-
"tasks",
|
|
8081
|
-
"fleet",
|
|
8082
|
-
"brain",
|
|
8083
|
-
"debug_stream",
|
|
8084
|
-
"enhance",
|
|
8085
|
-
"next_steps",
|
|
8086
|
-
"mailbox",
|
|
8087
|
-
"fleet_agents",
|
|
8088
|
-
"memory_context"
|
|
8089
|
-
];
|
|
8090
|
-
var DEFAULTS = Object.fromEntries(
|
|
8091
|
-
STATUSLINE_CONFIG_KEYS.map((key) => [key, true])
|
|
8092
|
-
);
|
|
8380
|
+
var STATUSLINE_CONFIG_VERSION = 3;
|
|
8381
|
+
var STATUSLINE_CONFIG_KEYS = STATUSLINE_ITEMS;
|
|
8382
|
+
var DEFAULTS = defaultChipEnabledMap();
|
|
8093
8383
|
function emptyDocument() {
|
|
8094
|
-
return {
|
|
8384
|
+
return {
|
|
8385
|
+
version: STATUSLINE_CONFIG_VERSION,
|
|
8386
|
+
chips: { ...DEFAULTS },
|
|
8387
|
+
lines: {},
|
|
8388
|
+
densities: {}
|
|
8389
|
+
};
|
|
8095
8390
|
}
|
|
8096
8391
|
function resolveConfigPath() {
|
|
8097
8392
|
const override = process.env[CONFIG_ENV];
|
|
@@ -8102,12 +8397,12 @@ function resolveConfigPath() {
|
|
|
8102
8397
|
});
|
|
8103
8398
|
return paths.profileStatuslineConfig(paths.profileName);
|
|
8104
8399
|
}
|
|
8105
|
-
function
|
|
8400
|
+
function isRecord2(value) {
|
|
8106
8401
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8107
8402
|
}
|
|
8108
8403
|
function normalizeChips(value) {
|
|
8109
8404
|
const config = { ...DEFAULTS };
|
|
8110
|
-
if (!
|
|
8405
|
+
if (!isRecord2(value)) return config;
|
|
8111
8406
|
for (const key of STATUSLINE_CONFIG_KEYS) {
|
|
8112
8407
|
if (typeof value[key] === "boolean") config[key] = value[key];
|
|
8113
8408
|
}
|
|
@@ -8115,33 +8410,50 @@ function normalizeChips(value) {
|
|
|
8115
8410
|
}
|
|
8116
8411
|
function normalizeLines(value) {
|
|
8117
8412
|
const lines = {};
|
|
8118
|
-
if (!
|
|
8413
|
+
if (!isRecord2(value)) return lines;
|
|
8119
8414
|
for (const key of STATUSLINE_CONFIG_KEYS) {
|
|
8120
8415
|
const raw = value[key];
|
|
8121
8416
|
if (typeof raw !== "number" || !Number.isInteger(raw)) continue;
|
|
8122
|
-
lines[key] =
|
|
8417
|
+
lines[key] = clampLine(raw);
|
|
8123
8418
|
}
|
|
8124
8419
|
return lines;
|
|
8125
8420
|
}
|
|
8421
|
+
function normalizeDensities(value) {
|
|
8422
|
+
const densities = {};
|
|
8423
|
+
if (!isRecord2(value)) return densities;
|
|
8424
|
+
for (const key of STATUSLINE_CONFIG_KEYS) {
|
|
8425
|
+
const raw = value[key];
|
|
8426
|
+
if (typeof raw !== "string") continue;
|
|
8427
|
+
if (!STATUSLINE_DENSITY_LEVELS.includes(raw)) continue;
|
|
8428
|
+
densities[key] = raw;
|
|
8429
|
+
}
|
|
8430
|
+
return densities;
|
|
8431
|
+
}
|
|
8126
8432
|
function parseDocument(value) {
|
|
8127
|
-
if (
|
|
8433
|
+
if (isRecord2(value) && (isRecord2(value["chips"]) || isRecord2(value["lines"]) || isRecord2(value["densities"]))) {
|
|
8128
8434
|
return {
|
|
8129
8435
|
version: STATUSLINE_CONFIG_VERSION,
|
|
8130
8436
|
chips: normalizeChips(value["chips"]),
|
|
8131
|
-
lines: normalizeLines(value["lines"])
|
|
8437
|
+
lines: normalizeLines(value["lines"]),
|
|
8438
|
+
densities: normalizeDensities(value["densities"])
|
|
8132
8439
|
};
|
|
8133
8440
|
}
|
|
8134
|
-
return {
|
|
8441
|
+
return {
|
|
8442
|
+
version: STATUSLINE_CONFIG_VERSION,
|
|
8443
|
+
chips: normalizeChips(value),
|
|
8444
|
+
lines: {},
|
|
8445
|
+
densities: {}
|
|
8446
|
+
};
|
|
8135
8447
|
}
|
|
8136
8448
|
function isMissingKnownChips(value) {
|
|
8137
|
-
return !
|
|
8449
|
+
return !isRecord2(value) || STATUSLINE_CONFIG_KEYS.some((key) => typeof value[key] !== "boolean");
|
|
8138
8450
|
}
|
|
8139
8451
|
function needsRewrite(value) {
|
|
8140
|
-
if (
|
|
8452
|
+
if (isRecord2(value) && isRecord2(value["chips"])) {
|
|
8141
8453
|
if (value["version"] !== STATUSLINE_CONFIG_VERSION) return true;
|
|
8142
8454
|
if (isMissingKnownChips(value["chips"])) return true;
|
|
8143
|
-
if (!
|
|
8144
|
-
return JSON.stringify(normalizeLines(value["lines"])) !== JSON.stringify(value["lines"]);
|
|
8455
|
+
if (!isRecord2(value["lines"]) || !isRecord2(value["densities"])) return true;
|
|
8456
|
+
return JSON.stringify(normalizeLines(value["lines"])) !== JSON.stringify(value["lines"]) || JSON.stringify(normalizeDensities(value["densities"])) !== JSON.stringify(value["densities"]);
|
|
8145
8457
|
}
|
|
8146
8458
|
return true;
|
|
8147
8459
|
}
|
|
@@ -8170,7 +8482,7 @@ async function ensureStatuslineConfig() {
|
|
|
8170
8482
|
raw = JSON.parse(await fs3.readFile(resolveConfigPath(), "utf8"));
|
|
8171
8483
|
config = parseDocument(raw);
|
|
8172
8484
|
} catch (error) {
|
|
8173
|
-
if (
|
|
8485
|
+
if (isRecord2(error) && error["code"] === "ENOENT") {
|
|
8174
8486
|
sawFile = false;
|
|
8175
8487
|
config = emptyDocument();
|
|
8176
8488
|
} else {
|
|
@@ -8198,7 +8510,8 @@ async function saveStatuslineConfig(config) {
|
|
|
8198
8510
|
{
|
|
8199
8511
|
version: STATUSLINE_CONFIG_VERSION,
|
|
8200
8512
|
chips: normalizeChips(config.chips),
|
|
8201
|
-
lines: normalizeLines(config.lines)
|
|
8513
|
+
lines: normalizeLines(config.lines),
|
|
8514
|
+
densities: normalizeDensities(config.densities)
|
|
8202
8515
|
},
|
|
8203
8516
|
null,
|
|
8204
8517
|
2
|
|
@@ -8216,9 +8529,33 @@ async function saveStatuslineConfig(config) {
|
|
|
8216
8529
|
async function loadStatuslineLines() {
|
|
8217
8530
|
return (await loadStatuslineConfig()).lines;
|
|
8218
8531
|
}
|
|
8219
|
-
async function
|
|
8220
|
-
|
|
8221
|
-
|
|
8532
|
+
async function loadStatuslineDensities() {
|
|
8533
|
+
return (await loadStatuslineConfig()).densities;
|
|
8534
|
+
}
|
|
8535
|
+
var docMutationChain = Promise.resolve();
|
|
8536
|
+
function queueDocMutation(mutate) {
|
|
8537
|
+
const run = docMutationChain.then(mutate, mutate);
|
|
8538
|
+
docMutationChain = run.then(
|
|
8539
|
+
() => void 0,
|
|
8540
|
+
() => void 0
|
|
8541
|
+
);
|
|
8542
|
+
return run;
|
|
8543
|
+
}
|
|
8544
|
+
async function saveStatuslineLayout(layout) {
|
|
8545
|
+
await queueDocMutation(async () => {
|
|
8546
|
+
const doc = await ensureStatuslineConfig();
|
|
8547
|
+
await saveStatuslineConfig({
|
|
8548
|
+
...doc,
|
|
8549
|
+
lines: normalizeLines(layout.lines ?? doc.lines),
|
|
8550
|
+
densities: normalizeDensities(layout.densities ?? doc.densities)
|
|
8551
|
+
});
|
|
8552
|
+
});
|
|
8553
|
+
}
|
|
8554
|
+
async function saveStatuslineChips(chips) {
|
|
8555
|
+
await queueDocMutation(async () => {
|
|
8556
|
+
const doc = await ensureStatuslineConfig();
|
|
8557
|
+
await saveStatuslineConfig({ ...doc, chips: normalizeChips(chips) });
|
|
8558
|
+
});
|
|
8222
8559
|
}
|
|
8223
8560
|
|
|
8224
8561
|
// src/slash-commands/helpers.ts
|
|
@@ -9256,7 +9593,7 @@ import { randomUUID as randomUUID6 } from "node:crypto";
|
|
|
9256
9593
|
import { color as color15 } from "@wrongstack/core/utils";
|
|
9257
9594
|
|
|
9258
9595
|
// src/slash-commands/brain-council.ts
|
|
9259
|
-
import { parseModelRef } from "@wrongstack/core/agent";
|
|
9596
|
+
import { parseModelRef as parseModelRef2 } from "@wrongstack/core/agent";
|
|
9260
9597
|
import {
|
|
9261
9598
|
BUILTIN_COUNCIL_PERSONA_IDS,
|
|
9262
9599
|
BUILTIN_COUNCIL_PERSONAS
|
|
@@ -9268,11 +9605,12 @@ var COUNCIL_NUMERIC_OPS = {
|
|
|
9268
9605
|
timeout: "perCallTimeoutMs",
|
|
9269
9606
|
concurrency: "maxConcurrency",
|
|
9270
9607
|
votertokens: "voterMaxTokens",
|
|
9271
|
-
judgetokens: "judgeMaxTokens"
|
|
9608
|
+
judgetokens: "judgeMaxTokens",
|
|
9609
|
+
rounds: "deliberationRounds"
|
|
9272
9610
|
};
|
|
9273
9611
|
var PERSONA_SHORTHANDS = new Set(BUILTIN_COUNCIL_PERSONA_IDS);
|
|
9274
9612
|
function parseRefEntry(ref) {
|
|
9275
|
-
const parsed =
|
|
9613
|
+
const parsed = parseModelRef2(ref);
|
|
9276
9614
|
const model = parsed.model?.trim();
|
|
9277
9615
|
if (!model) return null;
|
|
9278
9616
|
return parsed.provider ? { provider: parsed.provider, model } : { model };
|
|
@@ -9342,10 +9680,7 @@ async function handleBrainCouncilSubcommand(rest, opts, applyPatch) {
|
|
|
9342
9680
|
opts.renderer.writeWarning(msg2);
|
|
9343
9681
|
return { message: msg2 };
|
|
9344
9682
|
}
|
|
9345
|
-
return applyPatch(
|
|
9346
|
-
{ council: { voters: seats } },
|
|
9347
|
-
councilSummary
|
|
9348
|
-
);
|
|
9683
|
+
return applyPatch({ council: { voters: seats } }, councilSummary);
|
|
9349
9684
|
}
|
|
9350
9685
|
if (op === "personas") {
|
|
9351
9686
|
const lines = [
|
|
@@ -9404,22 +9739,19 @@ async function handleBrainCouncilSubcommand(rest, opts, applyPatch) {
|
|
|
9404
9739
|
return `Brain council ${op} set to ${color13.cyan(applied === void 0 ? "default" : String(applied))}`;
|
|
9405
9740
|
});
|
|
9406
9741
|
}
|
|
9407
|
-
const msg = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, votertokens, or
|
|
9742
|
+
const msg = `Unknown council subcommand: ${op}. Use on, off, minrisk, voters, personas, judge, quorum, approval, distinctness, timeout, concurrency, votertokens, judgetokens, or rounds.`;
|
|
9408
9743
|
opts.renderer.writeWarning(msg);
|
|
9409
9744
|
return { message: msg };
|
|
9410
9745
|
}
|
|
9411
9746
|
|
|
9412
9747
|
// src/slash-commands/brain-status.ts
|
|
9413
9748
|
import { readFile as readFile5 } from "node:fs/promises";
|
|
9749
|
+
import { DETERMINISTIC_BRAIN_TIERS } from "@wrongstack/core/coordination";
|
|
9414
9750
|
import { color as color14 } from "@wrongstack/core/utils";
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
"
|
|
9418
|
-
|
|
9419
|
-
"cache",
|
|
9420
|
-
"ledger-guard",
|
|
9421
|
-
"terminal"
|
|
9422
|
-
];
|
|
9751
|
+
function councilRoundsSummary(snapshot) {
|
|
9752
|
+
const rounds = snapshot.council.deliberationRounds ?? 2;
|
|
9753
|
+
return rounds > 1 ? `, ${rounds} rounds` : ", no deliberation";
|
|
9754
|
+
}
|
|
9423
9755
|
function fmtAge(at) {
|
|
9424
9756
|
const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
|
|
9425
9757
|
if (s < 60) return `${s}s ago`;
|
|
@@ -9453,7 +9785,7 @@ function formatBrainStatus(opts) {
|
|
|
9453
9785
|
const councilSeats = opts.brainSettings?.councilLabels ?? [];
|
|
9454
9786
|
if (councilSeats.length > 0) {
|
|
9455
9787
|
lines.push(
|
|
9456
|
-
` council: ${color14.cyan(councilSeats.join(", "))}${snapshot ? color14.dim(` (minRisk: ${snapshot.council.minRisk}${judgeSummary(snapshot)})`) : ""}`
|
|
9788
|
+
` council: ${color14.cyan(councilSeats.join(", "))}${snapshot ? color14.dim(` (minRisk: ${snapshot.council.minRisk}${judgeSummary(snapshot)}${councilRoundsSummary(snapshot)})`) : ""}`
|
|
9457
9789
|
);
|
|
9458
9790
|
} else if (snapshot) {
|
|
9459
9791
|
lines.push(` council: ${color14.dim("disabled (/brain council on + voters)")}`);
|
|
@@ -9482,21 +9814,25 @@ function formatBrainStatus(opts) {
|
|
|
9482
9814
|
}
|
|
9483
9815
|
function formatBrainStats(opts) {
|
|
9484
9816
|
const log = opts.getBrainLog?.() ?? [];
|
|
9817
|
+
const councilWarnings = log.filter((entry) => entry.kind === "council_warn");
|
|
9818
|
+
const lifetime = opts.brainTierStats?.();
|
|
9485
9819
|
const counts = /* @__PURE__ */ new Map();
|
|
9486
|
-
|
|
9487
|
-
|
|
9488
|
-
if (
|
|
9489
|
-
|
|
9490
|
-
|
|
9820
|
+
if (lifetime) {
|
|
9821
|
+
for (const [tier, n] of Object.entries(lifetime.byTier)) counts.set(tier, n ?? 0);
|
|
9822
|
+
if (lifetime.unattributed > 0) counts.set("unattributed", lifetime.unattributed);
|
|
9823
|
+
} else {
|
|
9824
|
+
for (const entry of log) {
|
|
9825
|
+
if (entry.kind === "council_warn") continue;
|
|
9826
|
+
counts.set(entry.tier ?? "unattributed", (counts.get(entry.tier ?? "unattributed") ?? 0) + 1);
|
|
9491
9827
|
}
|
|
9492
|
-
const tier = entry.tier ?? "unattributed";
|
|
9493
|
-
counts.set(tier, (counts.get(tier) ?? 0) + 1);
|
|
9494
9828
|
}
|
|
9495
|
-
let free = 0;
|
|
9496
|
-
let paid = 0;
|
|
9497
|
-
|
|
9498
|
-
|
|
9499
|
-
|
|
9829
|
+
let free = lifetime?.deterministic ?? 0;
|
|
9830
|
+
let paid = lifetime?.llmBacked ?? 0;
|
|
9831
|
+
if (!lifetime) {
|
|
9832
|
+
for (const [tier, n] of counts) {
|
|
9833
|
+
if (DETERMINISTIC_BRAIN_TIERS.has(tier)) free += n;
|
|
9834
|
+
else if (tier === "llm" || tier === "council") paid += n;
|
|
9835
|
+
}
|
|
9500
9836
|
}
|
|
9501
9837
|
const lines = [color14.bold("Brain decision tiers"), ""];
|
|
9502
9838
|
if (counts.size === 0) {
|
|
@@ -9529,7 +9865,9 @@ function formatBrainStats(opts) {
|
|
|
9529
9865
|
}
|
|
9530
9866
|
lines.push(
|
|
9531
9867
|
"",
|
|
9532
|
-
color14.dim(
|
|
9868
|
+
color14.dim(
|
|
9869
|
+
lifetime ? ` ${lifetime.total} decision(s) this session.` : ` Based on the last ${log.length} logged decision(s) of this session.`
|
|
9870
|
+
)
|
|
9533
9871
|
);
|
|
9534
9872
|
return lines.join("\n");
|
|
9535
9873
|
}
|
|
@@ -12460,7 +12798,7 @@ function buildDoctorCommand(opts) {
|
|
|
12460
12798
|
].join("\n");
|
|
12461
12799
|
async function loadPluginSchemas() {
|
|
12462
12800
|
try {
|
|
12463
|
-
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-
|
|
12801
|
+
const { BUILTIN_PLUGIN_FACTORIES } = await import("./plugins-PZ2VZL7V.js");
|
|
12464
12802
|
const settled = await Promise.allSettled(BUILTIN_PLUGIN_FACTORIES.map((f) => f()));
|
|
12465
12803
|
const loaded = [];
|
|
12466
12804
|
for (const s of settled) {
|
|
@@ -12864,7 +13202,7 @@ import * as fs7 from "node:fs/promises";
|
|
|
12864
13202
|
import {
|
|
12865
13203
|
diagnoseFallbackConfig,
|
|
12866
13204
|
normalizeModelRef,
|
|
12867
|
-
parseModelRef as
|
|
13205
|
+
parseModelRef as parseModelRef3,
|
|
12868
13206
|
runtimeFallbackChain,
|
|
12869
13207
|
simulateFallbackFailover,
|
|
12870
13208
|
smartDefaultFallbackChain
|
|
@@ -12873,7 +13211,7 @@ import { decryptConfigSecrets, encryptConfigSecrets, noOpVault as noOpVault2 } f
|
|
|
12873
13211
|
import { ConfigError } from "@wrongstack/core/types";
|
|
12874
13212
|
import { atomicWrite as atomicWrite4, color as color25, toErrorMessage as toErrorMessage10 } from "@wrongstack/core/utils";
|
|
12875
13213
|
function refInvalidReason(ref, config) {
|
|
12876
|
-
const parsed =
|
|
13214
|
+
const parsed = parseModelRef3(ref);
|
|
12877
13215
|
if (!parsed.model) return "no model in reference";
|
|
12878
13216
|
const favorites = config.favoriteModels ?? [];
|
|
12879
13217
|
if (favorites.length === 0) return void 0;
|
|
@@ -12883,7 +13221,7 @@ function refInvalidReason(ref, config) {
|
|
|
12883
13221
|
return void 0;
|
|
12884
13222
|
}
|
|
12885
13223
|
function refStaleModelListWarning(ref, config) {
|
|
12886
|
-
const parsed =
|
|
13224
|
+
const parsed = parseModelRef3(ref);
|
|
12887
13225
|
if (!parsed.model) return "no model in reference";
|
|
12888
13226
|
const providerId = parsed.provider ?? config.provider;
|
|
12889
13227
|
const entry = config.providers?.[providerId];
|
|
@@ -13172,7 +13510,7 @@ function buildFallbackCommand(opts) {
|
|
|
13172
13510
|
};
|
|
13173
13511
|
}
|
|
13174
13512
|
const ref = normalizeRef(parts.slice(2).join(" "));
|
|
13175
|
-
const parsed =
|
|
13513
|
+
const parsed = parseModelRef3(ref);
|
|
13176
13514
|
if (!ref || !parsed.provider || !parsed.model) {
|
|
13177
13515
|
return {
|
|
13178
13516
|
message: `${color25.amber("Usage:")} /fallback bridge set <provider/model>`
|
|
@@ -13414,13 +13752,13 @@ ${color25.dim("Add favorites first: /fallback fav add <ref>, or fix provider mod
|
|
|
13414
13752
|
return { message: `${color25.amber("Already favorite")}: ${color25.cyan(ref)}` };
|
|
13415
13753
|
}
|
|
13416
13754
|
const providerEntry = (() => {
|
|
13417
|
-
const parsed =
|
|
13755
|
+
const parsed = parseModelRef3(ref);
|
|
13418
13756
|
const provId = parsed.provider ?? config.provider;
|
|
13419
13757
|
return config.providers?.[provId];
|
|
13420
13758
|
})();
|
|
13421
|
-
if (providerEntry?.models && providerEntry.models.length > 0 && !providerEntry.models.includes(
|
|
13759
|
+
if (providerEntry?.models && providerEntry.models.length > 0 && !providerEntry.models.includes(parseModelRef3(ref).model)) {
|
|
13422
13760
|
return {
|
|
13423
|
-
message: `${color25.red("Cannot favorite")}: "${ref}" \u2014 ${
|
|
13761
|
+
message: `${color25.red("Cannot favorite")}: "${ref}" \u2014 ${parseModelRef3(ref).model} not in ${parseModelRef3(ref).provider ?? config.provider} model list (${providerEntry.models.join(", ")}). ${color25.dim("Pick a model the provider actually exposes.")}`
|
|
13424
13762
|
};
|
|
13425
13763
|
}
|
|
13426
13764
|
favorites.push(ref);
|
|
@@ -15854,6 +16192,75 @@ function buildHealthCommand(opts) {
|
|
|
15854
16192
|
};
|
|
15855
16193
|
}
|
|
15856
16194
|
|
|
16195
|
+
// src/slash-commands/slash-deep-help.ts
|
|
16196
|
+
var slashToSubcommand = {
|
|
16197
|
+
// ── Existing slash commands ───────────────────────────────────────
|
|
16198
|
+
// These slash commands ARE registered today. The wiring on the
|
|
16199
|
+
// slash side imports `renderSlashFocusedHelp` from this module
|
|
16200
|
+
// and short-circuits `help` / `--help` / `-h` to the focused
|
|
16201
|
+
// block. The entries here are the bridge that wires each
|
|
16202
|
+
// slash command to its top-level subcommand counterpart.
|
|
16203
|
+
auth: "auth",
|
|
16204
|
+
mcp: "mcp",
|
|
16205
|
+
plugin: "plugin",
|
|
16206
|
+
models: "models",
|
|
16207
|
+
sessions: "sessions",
|
|
16208
|
+
tools: "tools",
|
|
16209
|
+
init: "init",
|
|
16210
|
+
doctor: "doctor",
|
|
16211
|
+
// ── Forward-compatible bindings ───────────────────────────────────
|
|
16212
|
+
// No slash command with this name exists yet. When a future
|
|
16213
|
+
// contributor adds one (e.g. `packages/cli/src/slash-commands/config.ts`
|
|
16214
|
+
// with `name: 'config'`), the entry below is the wiring point
|
|
16215
|
+
// for `/help <name>` to render the same block `wstack <name> --help`
|
|
16216
|
+
// would write. The contributor still has to add the
|
|
16217
|
+
// `wantsDeepHelp` / focused-help short-circuit to the new slash
|
|
16218
|
+
// command's `run()` method (mirroring the pattern in
|
|
16219
|
+
// `auth.ts` / `mcp.ts` / etc.) — this map just registers the
|
|
16220
|
+
// dispatch target for the existing `/help <name>` renderer.
|
|
16221
|
+
//
|
|
16222
|
+
// Adding an entry here is a one-line, type-checked change.
|
|
16223
|
+
// There's no runtime cost when the slash command doesn't exist
|
|
16224
|
+
// yet — `renderSlashFocusedHelp` only fires when the user types
|
|
16225
|
+
// `/help <name>`, and if the slash command isn't registered,
|
|
16226
|
+
// the existing inline-help path is the fallback.
|
|
16227
|
+
config: "config",
|
|
16228
|
+
audit: "audit",
|
|
16229
|
+
replay: "replay",
|
|
16230
|
+
rewind: "rewind",
|
|
16231
|
+
export: "export",
|
|
16232
|
+
usage: "usage",
|
|
16233
|
+
providers: "providers",
|
|
16234
|
+
skills: "skills",
|
|
16235
|
+
update: "update",
|
|
16236
|
+
projects: "projects",
|
|
16237
|
+
acp: "acp",
|
|
16238
|
+
modeldiag: "modeldiag",
|
|
16239
|
+
bench: "bench",
|
|
16240
|
+
diag: "diag",
|
|
16241
|
+
version: "version",
|
|
16242
|
+
// `quick` is intercepted by `boot()` for the TUI launch, but
|
|
16243
|
+
// its focused-help entry (`wstack quick --help`) still resolves
|
|
16244
|
+
// through the per-subcommand-help table. Including it here
|
|
16245
|
+
// means a future `/quick` slash command (if one is ever added)
|
|
16246
|
+
// gets the focused-help wiring automatically.
|
|
16247
|
+
quick: "quick"
|
|
16248
|
+
};
|
|
16249
|
+
var slashesWithFocusedHelp = Object.keys(slashToSubcommand);
|
|
16250
|
+
function resolveSlashSubcommand(slashName) {
|
|
16251
|
+
return slashToSubcommand[slashName];
|
|
16252
|
+
}
|
|
16253
|
+
function renderSlashFocusedHelp(slashName) {
|
|
16254
|
+
const sub = resolveSlashSubcommand(slashName);
|
|
16255
|
+
if (!sub) return void 0;
|
|
16256
|
+
return renderFocusedHelpToString(sub);
|
|
16257
|
+
}
|
|
16258
|
+
function renderSlashDeepHelp(slashName, deep) {
|
|
16259
|
+
const sub = resolveSlashSubcommand(slashName);
|
|
16260
|
+
if (!sub) return void 0;
|
|
16261
|
+
return renderDeepHelpToString(`${sub}:${deep}`);
|
|
16262
|
+
}
|
|
16263
|
+
|
|
15857
16264
|
// src/slash-commands/help.ts
|
|
15858
16265
|
function buildHelpCommand(opts) {
|
|
15859
16266
|
return {
|
|
@@ -15877,6 +16284,12 @@ function buildHelpCommand(opts) {
|
|
|
15877
16284
|
return { message: "" };
|
|
15878
16285
|
}
|
|
15879
16286
|
if (query) {
|
|
16287
|
+
const queryParts = query.split(/\s+/).filter(Boolean);
|
|
16288
|
+
if (queryParts.length === 2) {
|
|
16289
|
+
const head = queryParts[0].replace(/^\//, "");
|
|
16290
|
+
const deepHelp = renderSlashDeepHelp(head, queryParts[1]);
|
|
16291
|
+
if (deepHelp) return { message: deepHelp };
|
|
16292
|
+
}
|
|
15880
16293
|
const needle = query.startsWith("/") ? query.slice(1) : query;
|
|
15881
16294
|
let match;
|
|
15882
16295
|
for (const entry of opts.registry.listWithOwner()) {
|
|
@@ -15897,7 +16310,8 @@ function buildHelpCommand(opts) {
|
|
|
15897
16310
|
const header = `/${prefix}${match.cmd.name}`;
|
|
15898
16311
|
const aliasLine = match.cmd.aliases?.length ? `Aliases: ${match.cmd.aliases.map((a) => `/${prefix}${a}`).join(", ")}
|
|
15899
16312
|
` : "";
|
|
15900
|
-
const
|
|
16313
|
+
const focused = renderSlashFocusedHelp(match.cmd.name);
|
|
16314
|
+
const body = [match.cmd.help ?? match.cmd.description, focused].filter(Boolean).join("\n\n");
|
|
15901
16315
|
return {
|
|
15902
16316
|
message: [
|
|
15903
16317
|
header,
|
|
@@ -18542,7 +18956,7 @@ function errorMessage(err) {
|
|
|
18542
18956
|
|
|
18543
18957
|
// src/slash-commands/memory.ts
|
|
18544
18958
|
import { toErrorMessage as toErrorMessage18 } from "@wrongstack/core/utils";
|
|
18545
|
-
import { getSageSurface as
|
|
18959
|
+
import { getSageSurface as getSageSurface4 } from "@wrongstack/sage";
|
|
18546
18960
|
|
|
18547
18961
|
// src/slash-commands/memory-audience.ts
|
|
18548
18962
|
import { toErrorMessage as toErrorMessage14 } from "@wrongstack/core/utils";
|
|
@@ -19412,7 +19826,9 @@ function formatMemoryDiagnostics(diag) {
|
|
|
19412
19826
|
lines.push(` with vectors: ${v.vectors}`);
|
|
19413
19827
|
lines.push(` providers: ${v.providers.join(", ") || "\u2205"}`);
|
|
19414
19828
|
lines.push(` model: ${v.modelId} (${v.dimensions}-dim)`);
|
|
19415
|
-
lines.push(
|
|
19829
|
+
lines.push(
|
|
19830
|
+
` cache: ${v.cacheEntries} rows \xB7 ${v.cacheProviders} provider(s) \xB7 ${v.totalUseCount} hits`
|
|
19831
|
+
);
|
|
19416
19832
|
if (v.oldestLastUsedAt) {
|
|
19417
19833
|
lines.push(` cache oldest: ${v.oldestLastUsedAt}`);
|
|
19418
19834
|
}
|
|
@@ -19421,7 +19837,9 @@ function formatMemoryDiagnostics(diag) {
|
|
|
19421
19837
|
lines.push("Cross-system coverage:");
|
|
19422
19838
|
lines.push(` vector \u2194 SAGE: ${v.mirroredInSage} mirrored`);
|
|
19423
19839
|
if (v.standalone > 0) {
|
|
19424
|
-
lines.push(
|
|
19840
|
+
lines.push(
|
|
19841
|
+
` standalone: ${v.standalone} vector-only entries (no SAGE id \u2014 lexical recall misses these)`
|
|
19842
|
+
);
|
|
19425
19843
|
}
|
|
19426
19844
|
if (v.mirroredInSage === 0 && diag.sageTotal > 0) {
|
|
19427
19845
|
lines.push(" \u{1F4A1} Run `wrongstack --vector-sync` to backfill the vector mirror.");
|
|
@@ -19522,18 +19940,14 @@ function formatSearchRace(race) {
|
|
|
19522
19940
|
if (race.lexicalOnly.length > 0) {
|
|
19523
19941
|
lines.push("### \u{1F170}\uFE0F Lexical only (vector missed)");
|
|
19524
19942
|
for (const row of race.lexicalOnly) {
|
|
19525
|
-
lines.push(
|
|
19526
|
-
`- \`${row.id.slice(0, 12)}\u2026\` L=${pct2(row.lexicalScore ?? 0)} ${row.preview}`
|
|
19527
|
-
);
|
|
19943
|
+
lines.push(`- \`${row.id.slice(0, 12)}\u2026\` L=${pct2(row.lexicalScore ?? 0)} ${row.preview}`);
|
|
19528
19944
|
}
|
|
19529
19945
|
lines.push("");
|
|
19530
19946
|
}
|
|
19531
19947
|
if (race.vectorOnly.length > 0) {
|
|
19532
19948
|
lines.push("### \u{1F171}\uFE0F Vector only (lexical missed)");
|
|
19533
19949
|
for (const row of race.vectorOnly) {
|
|
19534
|
-
lines.push(
|
|
19535
|
-
`- \`${row.id.slice(0, 12)}\u2026\` V=${pct2(row.vectorScore ?? 0)} ${row.preview}`
|
|
19536
|
-
);
|
|
19950
|
+
lines.push(`- \`${row.id.slice(0, 12)}\u2026\` V=${pct2(row.vectorScore ?? 0)} ${row.preview}`);
|
|
19537
19951
|
}
|
|
19538
19952
|
lines.push("");
|
|
19539
19953
|
}
|
|
@@ -19867,6 +20281,7 @@ import { toErrorMessage as toErrorMessage17 } from "@wrongstack/core/utils";
|
|
|
19867
20281
|
import {
|
|
19868
20282
|
fileTriageProposals,
|
|
19869
20283
|
formatTriageReport,
|
|
20284
|
+
getSageSurface as getSageSurface3,
|
|
19870
20285
|
runTriage
|
|
19871
20286
|
} from "@wrongstack/sage";
|
|
19872
20287
|
var DEFAULT_MAX_PHASE3 = 1e3;
|
|
@@ -19988,8 +20403,7 @@ Usage: /memory triage [--dry-run|--apply] [--limit N] [--max-phase3 N] [--max-ph
|
|
|
19988
20403
|
function getSage(opts) {
|
|
19989
20404
|
if (!opts.memoryStore) return null;
|
|
19990
20405
|
try {
|
|
19991
|
-
|
|
19992
|
-
return getSageSurface4(opts.memoryStore);
|
|
20406
|
+
return getSageSurface3(opts.memoryStore) ?? null;
|
|
19993
20407
|
} catch {
|
|
19994
20408
|
return null;
|
|
19995
20409
|
}
|
|
@@ -20082,7 +20496,7 @@ function buildMemoryCommand(opts) {
|
|
|
20082
20496
|
async run(args) {
|
|
20083
20497
|
const store = opts.memoryStore;
|
|
20084
20498
|
if (!store) return { message: "No memory store configured." };
|
|
20085
|
-
const Sage =
|
|
20499
|
+
const Sage = getSageSurface4(store);
|
|
20086
20500
|
const { cmd, rest } = parseSubcommand(args);
|
|
20087
20501
|
const restJoined = rest.join(" ").trim();
|
|
20088
20502
|
switch (cmd) {
|
|
@@ -20295,7 +20709,7 @@ function buildMemoryCommand(opts) {
|
|
|
20295
20709
|
};
|
|
20296
20710
|
}
|
|
20297
20711
|
try {
|
|
20298
|
-
const lexical = await Sage.searchSage(restJoined, { limit: 20 });
|
|
20712
|
+
const lexical = Sage.searchSageWithBreakdown ? (await Sage.searchSageWithBreakdown(restJoined, { limit: 20 })).filter((hit) => hit.lexicalScore !== null).sort((a, b) => (b.lexicalScore ?? 0) - (a.lexicalScore ?? 0)).map((hit) => hit.memory) : await Sage.searchSage(restJoined, { limit: 20 });
|
|
20299
20713
|
const race = await runSearchRace(restJoined, lexical, vectorStore, { limit: 20 });
|
|
20300
20714
|
return { message: formatSearchRace(race) };
|
|
20301
20715
|
} catch (err) {
|
|
@@ -20547,9 +20961,7 @@ File size reduced. Audit-logged as \`memory.log_compacted\`.`
|
|
|
20547
20961
|
try {
|
|
20548
20962
|
[sageStats, sageTotal] = await Promise.all([
|
|
20549
20963
|
Sage.stats(),
|
|
20550
|
-
Sage.listSagePage({ limit: 1 }).then(
|
|
20551
|
-
(page) => page.total ?? page.memories.length
|
|
20552
|
-
)
|
|
20964
|
+
Sage.listSagePage({ limit: 1 }).then((page) => page.total ?? page.memories.length)
|
|
20553
20965
|
]);
|
|
20554
20966
|
} catch (err) {
|
|
20555
20967
|
return {
|
|
@@ -22072,7 +22484,7 @@ function buildPruneCommand(opts) {
|
|
|
22072
22484
|
return {
|
|
22073
22485
|
name: "prune",
|
|
22074
22486
|
category: "Session",
|
|
22075
|
-
description: "Delete old sessions. /prune (default 30d)
|
|
22487
|
+
description: "Delete old sessions. /prune (default 30d). To compress instead of delete, use /sessions archive.",
|
|
22076
22488
|
help: "Usage:\n /prune Delete sessions older than 30 days.\n /prune 14 Delete sessions older than 14 days.\n /prune --dry-run Show what would be deleted without deleting.\n /prune --rebuild-index Rebuild the session index from disk.",
|
|
22077
22489
|
async run(args) {
|
|
22078
22490
|
const parts = args.split(/\s+/).filter(Boolean);
|
|
@@ -23467,7 +23879,11 @@ ${sddHelp()}`
|
|
|
23467
23879
|
}
|
|
23468
23880
|
|
|
23469
23881
|
// src/slash-commands/session.ts
|
|
23470
|
-
import {
|
|
23882
|
+
import {
|
|
23883
|
+
extractInterruptedTools,
|
|
23884
|
+
getSessionRegistry,
|
|
23885
|
+
SessionRecovery
|
|
23886
|
+
} from "@wrongstack/core/storage";
|
|
23471
23887
|
import { color as color47, isPidAlive, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
|
|
23472
23888
|
function statusIcon2(status) {
|
|
23473
23889
|
switch (status) {
|
|
@@ -23499,6 +23915,12 @@ function agentStatusIcon(status) {
|
|
|
23499
23915
|
return color47.dim("?");
|
|
23500
23916
|
}
|
|
23501
23917
|
}
|
|
23918
|
+
function formatBytes(value) {
|
|
23919
|
+
if (!value || !Number.isFinite(value) || value <= 0) return "0B";
|
|
23920
|
+
if (value < 1024) return `${value}B`;
|
|
23921
|
+
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1)}KB`;
|
|
23922
|
+
return `${(value / (1024 * 1024)).toFixed(1)}MB`;
|
|
23923
|
+
}
|
|
23502
23924
|
function fmtDuration(startedAt) {
|
|
23503
23925
|
const diff = Date.now() - new Date(startedAt).getTime();
|
|
23504
23926
|
const min = Math.floor(diff / 6e4);
|
|
@@ -23516,8 +23938,7 @@ function fmtAgentLine(agent) {
|
|
|
23516
23938
|
}
|
|
23517
23939
|
function getRegistry() {
|
|
23518
23940
|
try {
|
|
23519
|
-
|
|
23520
|
-
return mod.getSessionRegistry?.();
|
|
23941
|
+
return getSessionRegistry();
|
|
23521
23942
|
} catch {
|
|
23522
23943
|
return void 0;
|
|
23523
23944
|
}
|
|
@@ -23544,7 +23965,7 @@ function buildLoadCommand(opts) {
|
|
|
23544
23965
|
name: "sessions",
|
|
23545
23966
|
category: "Session",
|
|
23546
23967
|
aliases: ["resume", "load"],
|
|
23547
|
-
description: "List
|
|
23968
|
+
description: "List, resume, archive, or recover sessions. /sessions archive compresses old JSONL logs.",
|
|
23548
23969
|
async run(args) {
|
|
23549
23970
|
const parts = args.split(/\s+/).filter(Boolean);
|
|
23550
23971
|
const first = parts[0]?.toLowerCase();
|
|
@@ -23593,6 +24014,58 @@ function buildLoadCommand(opts) {
|
|
|
23593
24014
|
return { message: color47.red(`Rename failed: ${toErrorMessage21(err)}`) };
|
|
23594
24015
|
}
|
|
23595
24016
|
}
|
|
24017
|
+
if (first === "archive") {
|
|
24018
|
+
if (!opts.sessionStore?.archive || !opts.sessionStore.archiveIdle) {
|
|
24019
|
+
return { message: color47.yellow("Session store does not support archive.") };
|
|
24020
|
+
}
|
|
24021
|
+
const apply = parts.includes("--apply");
|
|
24022
|
+
const targetId = parts.filter((p) => p !== "--apply" && p !== "archive")[0];
|
|
24023
|
+
if (targetId) {
|
|
24024
|
+
try {
|
|
24025
|
+
const result2 = await opts.sessionStore.archive(targetId);
|
|
24026
|
+
return {
|
|
24027
|
+
message: result2.action === "archived" ? color47.green(
|
|
24028
|
+
`Archived ${targetId} (${formatBytes(result2.uncompressedBytes)} \u2192 ${formatBytes(result2.compressedBytes)})`
|
|
24029
|
+
) : color47.dim(`Archive ${result2.action}: ${targetId}${result2.reason ? ` (${result2.reason})` : ""}`)
|
|
24030
|
+
};
|
|
24031
|
+
} catch (err) {
|
|
24032
|
+
return { message: color47.red(`Archive failed: ${toErrorMessage21(err)}`) };
|
|
24033
|
+
}
|
|
24034
|
+
}
|
|
24035
|
+
if (!apply) {
|
|
24036
|
+
const preview = await opts.sessionStore.list(1e3);
|
|
24037
|
+
return {
|
|
24038
|
+
message: [
|
|
24039
|
+
color47.bold("Dry run \u2014 gzip existing closed session logs (JSONL stays the resume authority)."),
|
|
24040
|
+
color47.dim("Last 20 stay hot; everything else is gzipped immediately. /prune still deletes."),
|
|
24041
|
+
color47.dim(`Currently listed: ${preview.length} session(s).`),
|
|
24042
|
+
"",
|
|
24043
|
+
color47.dim("Run /sessions archive --apply to compress, or /sessions archive <id> for one session.")
|
|
24044
|
+
].join("\n")
|
|
24045
|
+
};
|
|
24046
|
+
}
|
|
24047
|
+
const result = await opts.sessionStore.archiveIdle({ backfill: true });
|
|
24048
|
+
return {
|
|
24049
|
+
message: `Archived ${color47.green(String(result.archived))} \xB7 skipped ${color47.dim(String(result.skipped))} \xB7 failed ${result.failed ? color47.red(String(result.failed)) : color47.dim("0")}.`
|
|
24050
|
+
};
|
|
24051
|
+
}
|
|
24052
|
+
if (first === "rehydrate") {
|
|
24053
|
+
const targetId = parts[1];
|
|
24054
|
+
if (!targetId) {
|
|
24055
|
+
return { message: color47.yellow("Usage: /sessions rehydrate <sessionId>") };
|
|
24056
|
+
}
|
|
24057
|
+
if (!opts.sessionStore?.rehydrate) {
|
|
24058
|
+
return { message: color47.yellow("Session store does not support rehydrate.") };
|
|
24059
|
+
}
|
|
24060
|
+
try {
|
|
24061
|
+
const result = await opts.sessionStore.rehydrate(targetId);
|
|
24062
|
+
return {
|
|
24063
|
+
message: result.action === "rehydrated" ? color47.green(`Rehydrated ${targetId}`) : color47.dim(`Rehydrate ${result.action}: ${targetId}`)
|
|
24064
|
+
};
|
|
24065
|
+
} catch (err) {
|
|
24066
|
+
return { message: color47.red(`Rehydrate failed: ${toErrorMessage21(err)}`) };
|
|
24067
|
+
}
|
|
24068
|
+
}
|
|
23596
24069
|
if (first === "delete") {
|
|
23597
24070
|
const targetId = parts[1];
|
|
23598
24071
|
if (!targetId) {
|
|
@@ -23727,10 +24200,11 @@ function buildLoadCommand(opts) {
|
|
|
23727
24200
|
}
|
|
23728
24201
|
const stat6 = parts2.join(" ");
|
|
23729
24202
|
const date = color47.dim(s.startedAt.slice(0, 16).replace("T", " "));
|
|
24203
|
+
const archived = s.storageState === "cold" ? color47.dim(" gz") : "";
|
|
23730
24204
|
const isCurrent = s.id === currentId;
|
|
23731
24205
|
const marker = isCurrent ? color47.cyan(" (current)") : "";
|
|
23732
24206
|
const label = s.name ? `${color47.bold(s.id)} ${color47.cyan(`(${s.name})`)}` : color47.bold(s.id);
|
|
23733
|
-
return ` ${label}${marker}
|
|
24207
|
+
return ` ${label}${marker}${archived}
|
|
23734
24208
|
${date} ${stat6}
|
|
23735
24209
|
${color47.dim(s.title)}`;
|
|
23736
24210
|
});
|
|
@@ -24007,7 +24481,7 @@ async function killSession(sessionId, confirm) {
|
|
|
24007
24481
|
|
|
24008
24482
|
// src/slash-commands/setmodel.ts
|
|
24009
24483
|
import * as fs15 from "node:fs/promises";
|
|
24010
|
-
import { fallbackProfileChain, parseModelRef as
|
|
24484
|
+
import { fallbackProfileChain, parseModelRef as parseModelRef4 } from "@wrongstack/core/agent";
|
|
24011
24485
|
import { AGENT_CATALOG as AGENT_CATALOG2, AGENTS_BY_PHASE as AGENTS_BY_PHASE3 } from "@wrongstack/core/agent-catalog";
|
|
24012
24486
|
import {
|
|
24013
24487
|
MATRIX_PHASE_KEYS,
|
|
@@ -24405,7 +24879,7 @@ function buildSetModelCommand(opts) {
|
|
|
24405
24879
|
const first = chain[0];
|
|
24406
24880
|
if (!first)
|
|
24407
24881
|
return { message: `${color48.red("Empty profile")}: ${color48.amber(profile)}` };
|
|
24408
|
-
const parsed =
|
|
24882
|
+
const parsed = parseModelRef4(first);
|
|
24409
24883
|
const provider2 = parsed.provider ?? config.provider;
|
|
24410
24884
|
if (!keyed.includes(provider2)) {
|
|
24411
24885
|
return {
|
|
@@ -24694,7 +25168,9 @@ function buildEffortCommand(opts) {
|
|
|
24694
25168
|
` ${color49.bold("effort")} ${color49.bold(current)}${ok ? "" : ` ${color49.amber(`(not advertised by this model \u2014 supported: ${levels.join(", ")})`)}`}`
|
|
24695
25169
|
);
|
|
24696
25170
|
} else {
|
|
24697
|
-
lines.push(
|
|
25171
|
+
lines.push(
|
|
25172
|
+
` ${color49.bold("effort")} ${color49.dim("(not set \u2014 auto \xB7 provider default applies)")}`
|
|
25173
|
+
);
|
|
24698
25174
|
}
|
|
24699
25175
|
if (levels) {
|
|
24700
25176
|
const rendered = REASONING_EFFORT_LEVELS2.filter((l) => levels.includes(l)).map(
|
|
@@ -24714,15 +25190,14 @@ function buildEffortCommand(opts) {
|
|
|
24714
25190
|
` ${color49.bold("levels")} ${color49.dim("(unknown \u2014 the resolver drops unsupported values with a warning)")}`
|
|
24715
25191
|
);
|
|
24716
25192
|
}
|
|
24717
|
-
lines.push(
|
|
24718
|
-
"",
|
|
24719
|
-
` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`
|
|
24720
|
-
);
|
|
25193
|
+
lines.push("", ` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`);
|
|
24721
25194
|
return { message: lines.join("\n") };
|
|
24722
25195
|
}
|
|
24723
25196
|
if (sub === "clear" || sub === "off-default") {
|
|
24724
25197
|
if (current === void 0) {
|
|
24725
|
-
return {
|
|
25198
|
+
return {
|
|
25199
|
+
message: `${color49.dim("No session effort set \u2014 provider default already applies.")}`
|
|
25200
|
+
};
|
|
24726
25201
|
}
|
|
24727
25202
|
await patchSessionEffort(void 0, opts.paths, config.activeProfile ?? "default");
|
|
24728
25203
|
opts.configStore.update({
|
|
@@ -25203,6 +25678,38 @@ var THEME_META = {
|
|
|
25203
25678
|
"gruvbox-dark-hard": {
|
|
25204
25679
|
name: "Gruvbox Dark Hard",
|
|
25205
25680
|
desc: "Maximum contrast Gruvbox on deep pitch charcoal"
|
|
25681
|
+
},
|
|
25682
|
+
"oceanic-next": {
|
|
25683
|
+
name: "Oceanic Next",
|
|
25684
|
+
desc: "Teal-and-slate classic \u2014 calm blue, warm coral"
|
|
25685
|
+
},
|
|
25686
|
+
"one-half-dark": {
|
|
25687
|
+
name: "One Half Dark",
|
|
25688
|
+
desc: "Atom's One Half \u2014 One Dark with cleaner contrast"
|
|
25689
|
+
},
|
|
25690
|
+
"ayu-mirage": { name: "Ayu Mirage", desc: "Dusk-slate Ayu, between Dark and Light" },
|
|
25691
|
+
seti: { name: "Seti", desc: "Long-running VS Code classic \u2014 charcoal, gold, cyan" },
|
|
25692
|
+
"paraiso-dark": { name: "Paraiso Dark", desc: "Base16 plum \u2014 warm, muted, low-glare" },
|
|
25693
|
+
darcula: { name: "Darcula", desc: "JetBrains' default dark \u2014 grey-green with amber" },
|
|
25694
|
+
"slack-dark": { name: "Slack Aubergine", desc: "Deep aubergine with sky blue and lime" },
|
|
25695
|
+
"vitesse-black": { name: "Vitesse Black", desc: "Vitesse on true black \u2014 least glare here" },
|
|
25696
|
+
"atom-dark": { name: "Atom Dark", desc: "The original Atom grey \u2014 neutral, low-chroma" },
|
|
25697
|
+
"github-dark-high-contrast": {
|
|
25698
|
+
name: "GitHub Dark High Contrast",
|
|
25699
|
+
desc: "Accessible GitHub \u2014 boosted text and borders"
|
|
25700
|
+
},
|
|
25701
|
+
"contrast-max": {
|
|
25702
|
+
name: "Maximum Contrast",
|
|
25703
|
+
desc: "Original \u2014 pure black, AAA-targeted text and borders"
|
|
25704
|
+
},
|
|
25705
|
+
"colorblind-safe": {
|
|
25706
|
+
name: "Colorblind Safe",
|
|
25707
|
+
desc: "Original \u2014 blue/orange coding, no red-vs-green reliance"
|
|
25708
|
+
},
|
|
25709
|
+
sandstone: { name: "Sandstone", desc: "Original \u2014 warm stone neutrals with sage and clay" },
|
|
25710
|
+
"everforest-hard": {
|
|
25711
|
+
name: "Everforest Hard",
|
|
25712
|
+
desc: "Everforest on its deepest base \u2014 more depth, same greens"
|
|
25206
25713
|
}
|
|
25207
25714
|
};
|
|
25208
25715
|
var THEME_OPTIONS = THEME_PRESET_IDS.map((id) => ({ id, ...THEME_META[id] }));
|
|
@@ -26622,7 +27129,6 @@ function formatDelay(ms) {
|
|
|
26622
27129
|
var ALL_SETTINGS_KEYS = [
|
|
26623
27130
|
"delay",
|
|
26624
27131
|
"mode",
|
|
26625
|
-
"hints",
|
|
26626
27132
|
"debug-stream",
|
|
26627
27133
|
"config-scope",
|
|
26628
27134
|
"fs-access",
|
|
@@ -26764,19 +27270,6 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26764
27270
|
});
|
|
26765
27271
|
return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
|
|
26766
27272
|
}
|
|
26767
|
-
if (sub === "hints") {
|
|
26768
|
-
const raw = (rest[0] ?? "").toLowerCase();
|
|
26769
|
-
if (!["on", "off"].includes(raw)) {
|
|
26770
|
-
return { message: `${color54.amber("Usage:")} /settings hints on|off` };
|
|
26771
|
-
}
|
|
26772
|
-
const on = raw === "on";
|
|
26773
|
-
await persistConfigSetting(persistDeps, (cfg) => {
|
|
26774
|
-
cfg.hints = on;
|
|
26775
|
-
});
|
|
26776
|
-
return {
|
|
26777
|
-
message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
26778
|
-
};
|
|
26779
|
-
}
|
|
26780
27273
|
if (sub === "debug-stream") {
|
|
26781
27274
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
26782
27275
|
if (!["on", "off"].includes(raw)) {
|
|
@@ -27480,7 +27973,6 @@ var SETTINGS_HELP = [
|
|
|
27480
27973
|
" /settings stream-fleet off|full Fleet-chat verbosity (on = full)",
|
|
27481
27974
|
" /settings chime on|off Ring terminal bell when a run completes",
|
|
27482
27975
|
" /settings confirm-exit on|off Ask for confirmation before interrupt/exit",
|
|
27483
|
-
" /settings hints on|off Show or suppress rotating launch hints",
|
|
27484
27976
|
" /settings debug-stream on|off Raw SSE hex-dump to stderr for debugging",
|
|
27485
27977
|
" /settings config-scope global|project Save settings globally or per-project",
|
|
27486
27978
|
" /settings fs-access unrestricted|project File-tool access scope (project = confine to project root)",
|
|
@@ -27537,7 +28029,6 @@ function formatSettingsDefaults() {
|
|
|
27537
28029
|
"",
|
|
27538
28030
|
` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
|
|
27539
28031
|
` default autonomy mode: ${color55.cyan("off")}`,
|
|
27540
|
-
` launch hints: ${color55.cyan("on")}`,
|
|
27541
28032
|
` iteration timeout: ${color55.cyan("5 min")}`,
|
|
27542
28033
|
` session timeout: ${color55.cyan("30 min")}`,
|
|
27543
28034
|
` max iterations: ${color55.cyan("100")}`,
|
|
@@ -27549,7 +28040,6 @@ function formatCurrentSettingsView(opts) {
|
|
|
27549
28040
|
const autonomy = opts.configStore.get().autonomy;
|
|
27550
28041
|
const delay = autonomy?.autoProceedDelayMs ?? 45e3;
|
|
27551
28042
|
const mode = autonomy?.defaultMode ?? "off";
|
|
27552
|
-
const hints = opts.configStore.get().hints !== false;
|
|
27553
28043
|
const debugStream = opts.configStore.get().debugStream === true;
|
|
27554
28044
|
const configScope = opts.configStore.get().configScope ?? "global";
|
|
27555
28045
|
const fsAccess = opts.configStore.get().tools?.restrictToProjectRoot === true ? "project" : "unrestricted";
|
|
@@ -27598,7 +28088,6 @@ function formatCurrentSettingsView(opts) {
|
|
|
27598
28088
|
` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
|
|
27599
28089
|
` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
|
|
27600
28090
|
` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
|
|
27601
|
-
` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
|
|
27602
28091
|
` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
|
|
27603
28092
|
` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
|
|
27604
28093
|
` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
|
|
@@ -28093,67 +28582,68 @@ function buildDirectorCommand(opts) {
|
|
|
28093
28582
|
}
|
|
28094
28583
|
|
|
28095
28584
|
// src/slash-commands/statusline.ts
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28100
|
-
|
|
28101
|
-
|
|
28102
|
-
|
|
28103
|
-
|
|
28104
|
-
git: "Git branch name",
|
|
28105
|
-
elapsed: "Session elapsed time",
|
|
28106
|
-
context: "Context window usage (input tokens)",
|
|
28107
|
-
tokens: "Input/output token counters",
|
|
28108
|
-
cache: "Prompt cache hit ratio",
|
|
28109
|
-
cost: "Token cost estimate (input/output/total)",
|
|
28110
|
-
queue: "Queued prompt count",
|
|
28111
|
-
hint: "Transient status hint text",
|
|
28112
|
-
index: "Codebase indexing status",
|
|
28113
|
-
breaker: "Process breaker countdown",
|
|
28114
|
-
working_dir: "Current working directory",
|
|
28115
|
-
project: "Project name",
|
|
28116
|
-
yolo: "YOLO permission mode",
|
|
28117
|
-
autonomy: "Autonomy mode",
|
|
28118
|
-
eternal_stage: "Autonomy stage",
|
|
28119
|
-
goal: "Active goal summary",
|
|
28120
|
-
mode: "Active agent mode label",
|
|
28121
|
-
auto_proceed: "Auto-proceed countdown",
|
|
28122
|
-
sessions: "Live session count",
|
|
28123
|
-
tools: "Registered tool count",
|
|
28124
|
-
theme: "Active color theme preset",
|
|
28125
|
-
token_saving: "Token-saving mode indicator",
|
|
28126
|
-
side_effects: "Side-effect / audit event count",
|
|
28127
|
-
processes: "Tracked bash/exec process count",
|
|
28128
|
-
version: "WrongStack version + update notice (right-anchored)",
|
|
28129
|
-
dropped_tools: "Tools dropped from the provider request (maxTools limit)",
|
|
28130
|
-
prompt_variant: "System prompt variant (Lite / Standard / Pro)",
|
|
28131
|
-
brain: "Brain arbiter decisions",
|
|
28132
|
-
mailbox: "Mailbox unread messages and peers",
|
|
28133
|
-
enhance: "Prompt-enhance countdown",
|
|
28134
|
-
debug_stream: "Stream debug telemetry",
|
|
28135
|
-
next_steps: "Next-step auto-submit countdown",
|
|
28136
|
-
memory_context: "Memory context detail (total records + active-in-context)"
|
|
28137
|
-
};
|
|
28585
|
+
import {
|
|
28586
|
+
CHIP_DESCRIPTIONS,
|
|
28587
|
+
clampLine as clampLine2,
|
|
28588
|
+
effectiveDensity,
|
|
28589
|
+
effectiveLine,
|
|
28590
|
+
LINE_TITLES,
|
|
28591
|
+
STATUSLINE_DENSITY_LEVELS as STATUSLINE_DENSITY_LEVELS2
|
|
28592
|
+
} from "@wrongstack/core/statusline";
|
|
28138
28593
|
var ALL_CONFIG_KEYS = STATUSLINE_CONFIG_KEYS;
|
|
28594
|
+
function isConfigKey(value) {
|
|
28595
|
+
return value != null && ALL_CONFIG_KEYS.includes(value);
|
|
28596
|
+
}
|
|
28597
|
+
function isDensity(value) {
|
|
28598
|
+
return value === "auto" || value != null && STATUSLINE_DENSITY_LEVELS2.includes(value);
|
|
28599
|
+
}
|
|
28600
|
+
function renderLayout(cfg) {
|
|
28601
|
+
const out = [];
|
|
28602
|
+
for (const line of [1, 2, 3, 4]) {
|
|
28603
|
+
const items = ALL_CONFIG_KEYS.filter(
|
|
28604
|
+
(key) => effectiveLine(key, cfg.lines) === line && cfg.chips[key] !== false
|
|
28605
|
+
);
|
|
28606
|
+
out.push(`Line ${line} \u2014 ${LINE_TITLES[line]}`);
|
|
28607
|
+
out.push(
|
|
28608
|
+
items.length === 0 ? " (empty)" : ` ${items.map((key) => {
|
|
28609
|
+
const density = effectiveDensity(key, cfg.densities);
|
|
28610
|
+
return density === "auto" ? key : `${key}:${density}`;
|
|
28611
|
+
}).join(" ")}`
|
|
28612
|
+
);
|
|
28613
|
+
}
|
|
28614
|
+
const off = ALL_CONFIG_KEYS.filter((key) => cfg.chips[key] === false);
|
|
28615
|
+
if (off.length > 0) out.push(`Off \u2014 ${off.join(" ")}`);
|
|
28616
|
+
return out;
|
|
28617
|
+
}
|
|
28139
28618
|
function buildStatuslineCommand(deps) {
|
|
28140
28619
|
return {
|
|
28141
28620
|
name: "statusline",
|
|
28142
28621
|
category: "Config",
|
|
28143
28622
|
aliases: ["sl"],
|
|
28144
|
-
description: "Customize status bar chips: /statusline [item] [on|off|
|
|
28623
|
+
description: "Customize status bar chips: /statusline [item] [on|off|line N|density D]",
|
|
28145
28624
|
help: [
|
|
28146
|
-
"Usage: /statusline
|
|
28147
|
-
" /statusline
|
|
28148
|
-
" /statusline <item>
|
|
28149
|
-
" /statusline <item> on
|
|
28150
|
-
" /statusline <item>
|
|
28151
|
-
" /statusline
|
|
28152
|
-
" /statusline all off
|
|
28153
|
-
" /statusline reset
|
|
28625
|
+
"Usage: /statusline \u2014 open the picker (TUI) or list the config",
|
|
28626
|
+
" /statusline preview \u2014 show the four lines as they are laid out",
|
|
28627
|
+
" /statusline <item> \u2014 toggle a chip on/off",
|
|
28628
|
+
" /statusline <item> on|off \u2014 enable/disable a chip",
|
|
28629
|
+
" /statusline <item> line <1-4> \u2014 move a chip to another line",
|
|
28630
|
+
" /statusline <item> density <d> \u2014 pin a chip to auto|full|short|micro",
|
|
28631
|
+
" /statusline all on|off \u2014 enable/disable every chip",
|
|
28632
|
+
" /statusline layout reset \u2014 restore default lines and densities",
|
|
28633
|
+
" /statusline reset \u2014 restore default chip visibility",
|
|
28634
|
+
"",
|
|
28635
|
+
"Lines are assigned by volatility:",
|
|
28636
|
+
" 1 IDENTITY fixed for the session",
|
|
28637
|
+
" 2 VITALS redraws every token",
|
|
28638
|
+
" 3 SAFETY & WORK posture + work in flight",
|
|
28639
|
+
" 4 ASYNC background activity & countdowns",
|
|
28640
|
+
"",
|
|
28641
|
+
"Density controls how much of a chip renders. With `auto` the rail",
|
|
28642
|
+
"shortens the widest chip first and only drops a chip once every chip",
|
|
28643
|
+
"on that line is already at `micro`.",
|
|
28154
28644
|
"",
|
|
28155
28645
|
"Available items:",
|
|
28156
|
-
...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(
|
|
28646
|
+
...ALL_CONFIG_KEYS.map((k) => ` ${k.padEnd(16)} ${CHIP_DESCRIPTIONS[k]}`),
|
|
28157
28647
|
"",
|
|
28158
28648
|
"Density mode (minimum/detailed/no-color) is a separate setting \u2014 see /settings.",
|
|
28159
28649
|
"These toggles set chip eligibility in any mode; some chips only render in detailed mode.",
|
|
@@ -28163,8 +28653,8 @@ function buildStatuslineCommand(deps) {
|
|
|
28163
28653
|
async run(args) {
|
|
28164
28654
|
const cfg = await deps.getConfig();
|
|
28165
28655
|
const trimmed = args.trim();
|
|
28166
|
-
const parts = trimmed.split(/\s+/);
|
|
28167
|
-
const [item, action] = parts;
|
|
28656
|
+
const parts = trimmed.split(/\s+/).filter(Boolean);
|
|
28657
|
+
const [item, action, value] = parts;
|
|
28168
28658
|
if (!item && deps.onPanelOpen?.current) {
|
|
28169
28659
|
const opened = deps.onPanelOpen.current("statuslineOpen");
|
|
28170
28660
|
if (opened) return { message: "Opened statusline picker." };
|
|
@@ -28174,14 +28664,26 @@ function buildStatuslineCommand(deps) {
|
|
|
28174
28664
|
for (const k of ALL_CONFIG_KEYS) {
|
|
28175
28665
|
const val = cfg.chips[k];
|
|
28176
28666
|
if (val === void 0) continue;
|
|
28177
|
-
|
|
28667
|
+
const line = effectiveLine(k, cfg.lines);
|
|
28668
|
+
const density = effectiveDensity(k, cfg.densities);
|
|
28669
|
+
lines.push(
|
|
28670
|
+
` ${val ? "\u25CF" : "\u25CB"} ${k.padEnd(16)} L${line} ${density === "auto" ? " " : density.padEnd(5)} ${CHIP_DESCRIPTIONS[k]}`
|
|
28671
|
+
);
|
|
28178
28672
|
}
|
|
28179
28673
|
return { message: lines.join("\n") };
|
|
28180
28674
|
}
|
|
28675
|
+
if (item === "preview") {
|
|
28676
|
+
return { message: ["StatusBar layout:", ...renderLayout(cfg)].join("\n") };
|
|
28677
|
+
}
|
|
28181
28678
|
if (item === "reset") {
|
|
28182
28679
|
await deps.setConfig({ ...cfg, chips: { ...DEFAULTS } });
|
|
28183
|
-
deps.setHiddenItems([]);
|
|
28184
|
-
return { message: "StatusBar
|
|
28680
|
+
deps.setHiddenItems(ALL_CONFIG_KEYS.filter((k) => DEFAULTS[k] === false));
|
|
28681
|
+
return { message: "StatusBar chip visibility reset to defaults." };
|
|
28682
|
+
}
|
|
28683
|
+
if (item === "layout") {
|
|
28684
|
+
if (action !== "reset") return { message: "Usage: /statusline layout reset" };
|
|
28685
|
+
await deps.setConfig({ ...cfg, lines: {}, densities: {} });
|
|
28686
|
+
return { message: "StatusBar layout reset: default lines and densities restored." };
|
|
28185
28687
|
}
|
|
28186
28688
|
if (item === "all") {
|
|
28187
28689
|
const onOff2 = action?.toLowerCase();
|
|
@@ -28198,13 +28700,31 @@ function buildStatuslineCommand(deps) {
|
|
|
28198
28700
|
message: `statusline all: ${onOff2 === "on" ? "showing all chips" : "hiding all chips"}`
|
|
28199
28701
|
};
|
|
28200
28702
|
}
|
|
28201
|
-
|
|
28202
|
-
if (!validItems.includes(item)) {
|
|
28703
|
+
if (!isConfigKey(item)) {
|
|
28203
28704
|
return {
|
|
28204
28705
|
message: `Unknown item "${item}". Run /statusline to see available items.`
|
|
28205
28706
|
};
|
|
28206
28707
|
}
|
|
28207
28708
|
const onOff = action?.toLowerCase();
|
|
28709
|
+
if (onOff === "line") {
|
|
28710
|
+
const parsed = Number(value);
|
|
28711
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > 4) {
|
|
28712
|
+
return { message: `Usage: /statusline ${item} line 1|2|3|4` };
|
|
28713
|
+
}
|
|
28714
|
+
const line = clampLine2(parsed);
|
|
28715
|
+
await deps.setConfig({ ...cfg, lines: { ...cfg.lines, [item]: line } });
|
|
28716
|
+
return { message: `statusline ${item}: line ${line} (${LINE_TITLES[line]})` };
|
|
28717
|
+
}
|
|
28718
|
+
if (onOff === "density") {
|
|
28719
|
+
if (!isDensity(value)) {
|
|
28720
|
+
return { message: `Usage: /statusline ${item} density auto|full|short|micro` };
|
|
28721
|
+
}
|
|
28722
|
+
const densities = { ...cfg.densities };
|
|
28723
|
+
if (value === "auto") delete densities[item];
|
|
28724
|
+
else densities[item] = value;
|
|
28725
|
+
await deps.setConfig({ ...cfg, densities });
|
|
28726
|
+
return { message: `statusline ${item}: density ${value}` };
|
|
28727
|
+
}
|
|
28208
28728
|
if (!onOff) {
|
|
28209
28729
|
const currentValue = cfg.chips[item] ?? true;
|
|
28210
28730
|
const newValue = !currentValue;
|
|
@@ -28217,7 +28737,7 @@ function buildStatuslineCommand(deps) {
|
|
|
28217
28737
|
return { message: `statusline ${item}: ${newValue ? "on" : "off"}` };
|
|
28218
28738
|
}
|
|
28219
28739
|
if (onOff !== "on" && onOff !== "off") {
|
|
28220
|
-
return { message: `Usage: /statusline ${item} on|off
|
|
28740
|
+
return { message: `Usage: /statusline ${item} on|off|line <1-4>|density <level>` };
|
|
28221
28741
|
}
|
|
28222
28742
|
await deps.setConfig({ ...cfg, chips: { ...cfg.chips, [item]: onOff === "on" } });
|
|
28223
28743
|
if (onOff === "off") {
|
|
@@ -29950,7 +30470,7 @@ function buildToolCommand(opts) {
|
|
|
29950
30470
|
);
|
|
29951
30471
|
}
|
|
29952
30472
|
async function runAutoThinDryRun() {
|
|
29953
|
-
const { runBootAutoThin } = await import("./boot-auto-thin-
|
|
30473
|
+
const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
|
|
29954
30474
|
const cfg = getAutoThin();
|
|
29955
30475
|
const result = await runBootAutoThin({
|
|
29956
30476
|
toolRegistry: opts.toolRegistry,
|
|
@@ -30014,7 +30534,7 @@ function buildToolCommand(opts) {
|
|
|
30014
30534
|
if (!cfg.enabled) {
|
|
30015
30535
|
return `${color63.amber("Auto-thinning is off")}. Run ${color63.cyan("/settings autothin on")} first.`;
|
|
30016
30536
|
}
|
|
30017
|
-
const { runBootAutoThin } = await import("./boot-auto-thin-
|
|
30537
|
+
const { runBootAutoThin } = await import("./boot-auto-thin-MANHOYHE.js");
|
|
30018
30538
|
const result = await runBootAutoThin({
|
|
30019
30539
|
toolRegistry: opts.toolRegistry,
|
|
30020
30540
|
events: opts.events,
|
|
@@ -31531,6 +32051,7 @@ function setupCliSlashCommands(params) {
|
|
|
31531
32051
|
brainSettings,
|
|
31532
32052
|
brainRuntime,
|
|
31533
32053
|
initialBrainLog,
|
|
32054
|
+
brainTierStats,
|
|
31534
32055
|
coordinatorController,
|
|
31535
32056
|
statusTracker,
|
|
31536
32057
|
shadowController,
|
|
@@ -31617,6 +32138,7 @@ function setupCliSlashCommands(params) {
|
|
|
31617
32138
|
brainSettings,
|
|
31618
32139
|
brainRuntime,
|
|
31619
32140
|
getBrainLog: () => initialBrainLog,
|
|
32141
|
+
brainTierStats,
|
|
31620
32142
|
...coordinatorController ? { coordinatorController } : {},
|
|
31621
32143
|
statusTracker,
|
|
31622
32144
|
shadowController,
|
|
@@ -31710,7 +32232,8 @@ function setupCliSlashCommands(params) {
|
|
|
31710
32232
|
// src/wiring/command-host-state.ts
|
|
31711
32233
|
import {
|
|
31712
32234
|
areSubagentsAllowedForSession as areSubagentsAllowedForSession4,
|
|
31713
|
-
FLEET_ROSTER as FLEET_ROSTER5
|
|
32235
|
+
FLEET_ROSTER as FLEET_ROSTER5,
|
|
32236
|
+
mailboxSessionTag as mailboxSessionTag6
|
|
31714
32237
|
} from "@wrongstack/core/coordination";
|
|
31715
32238
|
import {
|
|
31716
32239
|
AgentError as AgentError3,
|
|
@@ -31773,8 +32296,7 @@ async function loadStatuslineHiddenItems() {
|
|
|
31773
32296
|
for (const k of STATUSLINE_CONFIG_KEYS) {
|
|
31774
32297
|
chips[k] = !items.includes(k);
|
|
31775
32298
|
}
|
|
31776
|
-
|
|
31777
|
-
await saveStatuslineConfig({ ...doc2, chips });
|
|
32299
|
+
await saveStatuslineChips(chips);
|
|
31778
32300
|
};
|
|
31779
32301
|
return { hiddenItems: hiddenItemsList, setHiddenItems, saveHiddenItems };
|
|
31780
32302
|
}
|
|
@@ -31786,9 +32308,12 @@ async function setupCommandHostState(input) {
|
|
|
31786
32308
|
);
|
|
31787
32309
|
const interruptController = createInterruptController();
|
|
31788
32310
|
input.hqCommandController.interruptLeader = () => interruptController.abortLeader();
|
|
32311
|
+
const liveSessionId = () => input.sessionRef.current?.id ?? input.session.id;
|
|
32312
|
+
input.hqCommandController.sessionId = liveSessionId;
|
|
32313
|
+
input.hqCommandController.sessionTag = () => mailboxSessionTag6(liveSessionId());
|
|
31789
32314
|
input.hqCommandController.killFleet = () => killFleet2(input.getDirector());
|
|
31790
32315
|
input.hqCommandController.terminateAgent = (subagentId) => terminateAgent(input.getDirector(), subagentId);
|
|
31791
|
-
input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(input.getDirector(),
|
|
32316
|
+
input.hqCommandController.spawnAgent = (role, task, maxIterations) => spawnAgent2(input.getDirector(), liveSessionId(), role, task, maxIterations);
|
|
31792
32317
|
const enhanceController = createEnhanceController(input.getConfig());
|
|
31793
32318
|
const statuslineConfigDeps = createStatuslineConfigDeps();
|
|
31794
32319
|
const hidden = await loadStatuslineHiddenItems();
|
|
@@ -31807,7 +32332,16 @@ async function setupCommandHostState(input) {
|
|
|
31807
32332
|
};
|
|
31808
32333
|
const saveStatuslineLines2 = async (next) => {
|
|
31809
32334
|
currentLines = { ...next };
|
|
31810
|
-
await
|
|
32335
|
+
await saveStatuslineLayout({ lines: next });
|
|
32336
|
+
};
|
|
32337
|
+
const statuslineDensities = await loadStatuslineDensities();
|
|
32338
|
+
let currentDensities = { ...statuslineDensities };
|
|
32339
|
+
const setStatuslineDensities = (next) => {
|
|
32340
|
+
currentDensities = { ...next };
|
|
32341
|
+
};
|
|
32342
|
+
const saveStatuslineDensities = async (next) => {
|
|
32343
|
+
currentDensities = { ...next };
|
|
32344
|
+
await saveStatuslineLayout({ densities: next });
|
|
31811
32345
|
};
|
|
31812
32346
|
const agentsMonitorController = createAgentsMonitorController();
|
|
31813
32347
|
const onPanelOpen = { current: null };
|
|
@@ -31857,6 +32391,10 @@ async function setupCommandHostState(input) {
|
|
|
31857
32391
|
getCurrentStatuslineLines: () => currentLines,
|
|
31858
32392
|
setStatuslineLines,
|
|
31859
32393
|
saveStatuslineLines: saveStatuslineLines2,
|
|
32394
|
+
statuslineDensities: { ...statuslineDensities },
|
|
32395
|
+
getCurrentStatuslineDensities: () => currentDensities,
|
|
32396
|
+
setStatuslineDensities,
|
|
32397
|
+
saveStatuslineDensities,
|
|
31860
32398
|
agentsMonitorController,
|
|
31861
32399
|
onPanelOpen,
|
|
31862
32400
|
goalHost,
|
|
@@ -32404,7 +32942,7 @@ function setupHqTelemetry(deps) {
|
|
|
32404
32942
|
agentMonitor,
|
|
32405
32943
|
brainMailbox,
|
|
32406
32944
|
teardownHandlers,
|
|
32407
|
-
mailboxSessionTag:
|
|
32945
|
+
mailboxSessionTag: mailboxSessionTag8,
|
|
32408
32946
|
hqPublisherRef,
|
|
32409
32947
|
mcpRegistry
|
|
32410
32948
|
} = deps;
|
|
@@ -32413,7 +32951,11 @@ function setupHqTelemetry(deps) {
|
|
|
32413
32951
|
const hqCommandController = {
|
|
32414
32952
|
steerMailbox: brainMailbox,
|
|
32415
32953
|
interruptLeader: () => false,
|
|
32416
|
-
sessionTag: () =>
|
|
32954
|
+
sessionTag: () => mailboxSessionTag8(session.id),
|
|
32955
|
+
// Boot-session seed. `setupCommandHostState` rebinds both to the LIVE
|
|
32956
|
+
// writer ref, because an in-process resume / session.new swaps
|
|
32957
|
+
// `ctx.session` for a new writer object and this captured one goes stale.
|
|
32958
|
+
sessionId: () => session.id,
|
|
32417
32959
|
allowRunCommand: () => flags["hq-allow-exec"] === true
|
|
32418
32960
|
};
|
|
32419
32961
|
const hqOnCommand = createHqCommandDispatcher(hqCommandController);
|
|
@@ -32577,7 +33119,7 @@ import { NotifierImpl } from "@wrongstack/core/notifications";
|
|
|
32577
33119
|
import {
|
|
32578
33120
|
SlashCommandRegistry
|
|
32579
33121
|
} from "@wrongstack/core/registry";
|
|
32580
|
-
import { normalizeTokenSavingTier as
|
|
33122
|
+
import { normalizeTokenSavingTier as normalizeTokenSavingTier4 } from "@wrongstack/core/types";
|
|
32581
33123
|
import {
|
|
32582
33124
|
CONTEXT_WINDOW_MODE_PINNED_META_KEY as CONTEXT_WINDOW_MODE_PINNED_META_KEY2,
|
|
32583
33125
|
resolveContextWindowPolicy as resolveContextWindowPolicy3
|
|
@@ -33094,11 +33636,7 @@ async function setupCompaction(params) {
|
|
|
33094
33636
|
providerId: config.provider ?? provider.id,
|
|
33095
33637
|
modelId: config.model ?? context.model
|
|
33096
33638
|
});
|
|
33097
|
-
const initialPolicy = resolveContextWindowPolicy2(
|
|
33098
|
-
config.context,
|
|
33099
|
-
void 0,
|
|
33100
|
-
effectiveMaxContext
|
|
33101
|
-
);
|
|
33639
|
+
const initialPolicy = resolveContextWindowPolicy2(config.context, void 0, effectiveMaxContext);
|
|
33102
33640
|
context.meta ??= {};
|
|
33103
33641
|
context.meta["contextWindowMode"] = initialPolicy.id;
|
|
33104
33642
|
context.meta["contextWindowPolicy"] = initialPolicy;
|
|
@@ -33632,7 +34170,7 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
33632
34170
|
toolRegistry,
|
|
33633
34171
|
events,
|
|
33634
34172
|
log: logger,
|
|
33635
|
-
lazyMode:
|
|
34173
|
+
lazyMode: normalizeTokenSavingTier4(config.features.tokenSavingMode) !== "off",
|
|
33636
34174
|
cacheDir: wpaths.cacheDir,
|
|
33637
34175
|
authorizationProviderFactory: createVaultBackedMcpAuthorizationProviderFactory({
|
|
33638
34176
|
store: mcpTokenStore
|
|
@@ -33661,10 +34199,7 @@ async function setupLifecycleAndPlugins(deps) {
|
|
|
33661
34199
|
const getLiveConfig = () => configStore.get();
|
|
33662
34200
|
const fallbackProfileManager = container.resolve(TOKENS11.FallbackProfileManager);
|
|
33663
34201
|
const statusTracker = container.resolve(TOKENS11.ProviderModelStatusTracker);
|
|
33664
|
-
const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn(
|
|
33665
|
-
{ config: getLiveConfig(), providerRegistry, logger },
|
|
33666
|
-
providerId
|
|
33667
|
-
);
|
|
34202
|
+
const buildUtilityProvider = (providerId) => buildProviderForIdRuntimeFn({ config: getLiveConfig(), providerRegistry, logger }, providerId);
|
|
33668
34203
|
const pluginOneShot = new OneShotOrchestrator2({
|
|
33669
34204
|
buildProvider: buildUtilityProvider,
|
|
33670
34205
|
getConfig: getLiveConfig,
|
|
@@ -34120,7 +34655,10 @@ function setupProviderRuntime(deps) {
|
|
|
34120
34655
|
"uiLocale"
|
|
34121
34656
|
];
|
|
34122
34657
|
const activeProfileOf = (c) => typeof c.activeProfile === "string" && c.activeProfile ? c.activeProfile : "default";
|
|
34123
|
-
|
|
34658
|
+
let reloadProviderConfig = async () => {
|
|
34659
|
+
};
|
|
34660
|
+
const configWatchEnabled = process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1";
|
|
34661
|
+
{
|
|
34124
34662
|
let activeProfile = activeProfileOf(cfg);
|
|
34125
34663
|
let configLayers = [];
|
|
34126
34664
|
const rebuildLayers = () => {
|
|
@@ -34211,6 +34749,7 @@ function setupProviderRuntime(deps) {
|
|
|
34211
34749
|
);
|
|
34212
34750
|
}
|
|
34213
34751
|
};
|
|
34752
|
+
reloadProviderConfig = onAnyConfigChange;
|
|
34214
34753
|
let watchers = [];
|
|
34215
34754
|
const openWatchers = () => {
|
|
34216
34755
|
watchers = configLayers.map(
|
|
@@ -34228,20 +34767,22 @@ function setupProviderRuntime(deps) {
|
|
|
34228
34767
|
for (const w of watchers) w.close();
|
|
34229
34768
|
watchers = [];
|
|
34230
34769
|
};
|
|
34231
|
-
|
|
34232
|
-
|
|
34233
|
-
|
|
34234
|
-
|
|
34235
|
-
|
|
34236
|
-
|
|
34237
|
-
|
|
34238
|
-
|
|
34239
|
-
|
|
34240
|
-
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34770
|
+
if (configWatchEnabled) {
|
|
34771
|
+
openWatchers();
|
|
34772
|
+
teardownHandlers.push(
|
|
34773
|
+
configStore.watch((next) => {
|
|
34774
|
+
const nextProfile = activeProfileOf(next);
|
|
34775
|
+
if (nextProfile === activeProfile) return;
|
|
34776
|
+
activeProfile = nextProfile;
|
|
34777
|
+
closeWatchers();
|
|
34778
|
+
rebuildLayers();
|
|
34779
|
+
openWatchers();
|
|
34780
|
+
previousSnapshotSerialized = void 0;
|
|
34781
|
+
void onAnyConfigChange();
|
|
34782
|
+
})
|
|
34783
|
+
);
|
|
34784
|
+
teardownHandlers.push(closeWatchers);
|
|
34785
|
+
}
|
|
34245
34786
|
}
|
|
34246
34787
|
return {
|
|
34247
34788
|
resolveProviderCfg: resolveProviderCfg2,
|
|
@@ -34249,7 +34790,8 @@ function setupProviderRuntime(deps) {
|
|
|
34249
34790
|
buildProviderForModel,
|
|
34250
34791
|
refreshMaxContextFor,
|
|
34251
34792
|
refreshRuntimeModelStateFor,
|
|
34252
|
-
switchProviderAndModel
|
|
34793
|
+
switchProviderAndModel,
|
|
34794
|
+
reloadProviderConfig
|
|
34253
34795
|
};
|
|
34254
34796
|
}
|
|
34255
34797
|
|
|
@@ -34470,7 +35012,7 @@ async function setupReplayAndGovernance({
|
|
|
34470
35012
|
const replayFlag = flags["replay"];
|
|
34471
35013
|
const recordFlag = flags["record"];
|
|
34472
35014
|
if (typeof replayFlag === "string" || recordFlag === true) {
|
|
34473
|
-
const { bindReplayToContainer } = await import("./replay-
|
|
35015
|
+
const { bindReplayToContainer } = await import("./replay-Z3FTJEMM.js");
|
|
34474
35016
|
const mode = recordFlag === true ? "record" : "replay";
|
|
34475
35017
|
bindReplayToContainer({
|
|
34476
35018
|
container,
|
|
@@ -34658,7 +35200,7 @@ async function prepareRuntimeDispatch(input) {
|
|
|
34658
35200
|
// src/wiring/session-establishment.ts
|
|
34659
35201
|
import * as path31 from "node:path";
|
|
34660
35202
|
import { TOKENS as TOKENS12 } from "@wrongstack/core/kernel";
|
|
34661
|
-
import { getSessionRegistry as
|
|
35203
|
+
import { getSessionRegistry as getSessionRegistry3 } from "@wrongstack/core/storage";
|
|
34662
35204
|
import { addFatalSalvageHook } from "@wrongstack/core/utils";
|
|
34663
35205
|
|
|
34664
35206
|
// src/wiring/session.ts
|
|
@@ -34695,7 +35237,7 @@ import {
|
|
|
34695
35237
|
} from "@wrongstack/tools/session-kanban";
|
|
34696
35238
|
|
|
34697
35239
|
// src/wiring/resume-candidate.ts
|
|
34698
|
-
import { getSessionRegistry, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
|
|
35240
|
+
import { getSessionRegistry as getSessionRegistry2, SessionRecovery as SessionRecovery2 } from "@wrongstack/core/storage";
|
|
34699
35241
|
var MAX_CANDIDATES = 20;
|
|
34700
35242
|
async function pickResumeCandidate(options) {
|
|
34701
35243
|
const live = await liveSessionIds(options.globalRoot);
|
|
@@ -34716,7 +35258,7 @@ async function recentCandidates(sessionStore) {
|
|
|
34716
35258
|
}
|
|
34717
35259
|
async function liveSessionIds(globalRoot) {
|
|
34718
35260
|
try {
|
|
34719
|
-
const registry =
|
|
35261
|
+
const registry = getSessionRegistry2(globalRoot);
|
|
34720
35262
|
const entries = await registry.list();
|
|
34721
35263
|
return new Set(entries.map((entry) => entry.sessionId));
|
|
34722
35264
|
} catch {
|
|
@@ -35036,7 +35578,7 @@ async function setupSessionEstablishment(args) {
|
|
|
35036
35578
|
const sessionStore = container.resolve(TOKENS12.SessionStore);
|
|
35037
35579
|
const tokenCounter = container.resolve(TOKENS12.TokenCounter);
|
|
35038
35580
|
tokenCounter.setSessionId?.(() => sessionRef.current?.id);
|
|
35039
|
-
const sessionRegistry =
|
|
35581
|
+
const sessionRegistry = getSessionRegistry3(wpaths.globalRoot);
|
|
35040
35582
|
const sessResult = await setupSession({
|
|
35041
35583
|
config: { model: config.model, provider: config.provider },
|
|
35042
35584
|
wpaths,
|
|
@@ -35126,11 +35668,11 @@ async function setupSessionRegistry(deps) {
|
|
|
35126
35668
|
};
|
|
35127
35669
|
let ownershipEstablished = false;
|
|
35128
35670
|
try {
|
|
35129
|
-
const [{ getSessionRegistry:
|
|
35671
|
+
const [{ getSessionRegistry: getSessionRegistry4 }, { AgentStatusTracker, FleetNotifier }] = await Promise.all([
|
|
35130
35672
|
import("@wrongstack/core/storage"),
|
|
35131
35673
|
import("@wrongstack/core/coordination")
|
|
35132
35674
|
]);
|
|
35133
|
-
const registry =
|
|
35675
|
+
const registry = getSessionRegistry4(wpaths.globalRoot);
|
|
35134
35676
|
const projectSlug = path32.basename(wpaths.projectDir);
|
|
35135
35677
|
const projectName = path32.basename(projectRoot);
|
|
35136
35678
|
let gitBranch = await new Promise((resolve8) => {
|
|
@@ -35223,7 +35765,9 @@ async function setupSessionRegistry(deps) {
|
|
|
35223
35765
|
// src/session-event-wiring.ts
|
|
35224
35766
|
import {
|
|
35225
35767
|
createChronicleContext,
|
|
35768
|
+
createChronicleCounterSink,
|
|
35226
35769
|
createChronicleEventJournal,
|
|
35770
|
+
resolveChronicleDetail,
|
|
35227
35771
|
startChronicleFileObserver,
|
|
35228
35772
|
startChronicleHealthMonitor,
|
|
35229
35773
|
wireDecisionsToChronicle,
|
|
@@ -35247,6 +35791,10 @@ function resolveChronicleRetentionDays(config) {
|
|
|
35247
35791
|
if (raw <= 0) return 0;
|
|
35248
35792
|
return Math.max(MIN_CHRONICLE_RETENTION_DAYS, raw);
|
|
35249
35793
|
}
|
|
35794
|
+
function chronicleLimit(config, key) {
|
|
35795
|
+
const raw = config.chronicle?.[key];
|
|
35796
|
+
return typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : void 0;
|
|
35797
|
+
}
|
|
35250
35798
|
function tryCreateChronicleJournal(options) {
|
|
35251
35799
|
try {
|
|
35252
35800
|
return createChronicleEventJournal(options);
|
|
@@ -35288,11 +35836,18 @@ function wireSessionEvents(deps) {
|
|
|
35288
35836
|
let chronicleFileObserver;
|
|
35289
35837
|
let stopChronicleHealth;
|
|
35290
35838
|
let stopNetworkTelemetry;
|
|
35839
|
+
let disposeCounterSink;
|
|
35291
35840
|
if (deps.events && wpaths.projectDir) {
|
|
35292
35841
|
const retentionDays = resolveChronicleRetentionDays(config);
|
|
35293
35842
|
chronicleHandle = tryCreateChronicleJournal({
|
|
35294
35843
|
projectRoot,
|
|
35295
35844
|
retentionDays,
|
|
35845
|
+
// Undefined means "whatever the daemon already runs with": these only
|
|
35846
|
+
// take effect for the client that wins the spawn race, so passing an
|
|
35847
|
+
// explicit fallback here would imply a control this layer does not have.
|
|
35848
|
+
maxEvents: chronicleLimit(config, "maxEvents"),
|
|
35849
|
+
maxBytes: chronicleLimit(config, "maxBytes"),
|
|
35850
|
+
metricsRowRetentionDays: chronicleLimit(config, "metricsRowRetentionDays"),
|
|
35296
35851
|
projectPaths: {
|
|
35297
35852
|
globalRoot: wpaths.globalRoot,
|
|
35298
35853
|
projectId: wpaths.projectHash ?? wpaths.projectSlug,
|
|
@@ -35302,7 +35857,12 @@ function wireSessionEvents(deps) {
|
|
|
35302
35857
|
});
|
|
35303
35858
|
}
|
|
35304
35859
|
if (chronicleHandle && deps.events) {
|
|
35305
|
-
|
|
35860
|
+
const counterSink = createChronicleCounterSink({
|
|
35861
|
+
inner: chronicleHandle.journal,
|
|
35862
|
+
level: resolveChronicleDetail(config)
|
|
35863
|
+
});
|
|
35864
|
+
chronicleJournal = counterSink;
|
|
35865
|
+
disposeCounterSink = () => counterSink.dispose();
|
|
35306
35866
|
const location = chronicleHandle.identity;
|
|
35307
35867
|
const chronicleContext = createChronicleContext(
|
|
35308
35868
|
{
|
|
@@ -35628,6 +36188,7 @@ function wireSessionEvents(deps) {
|
|
|
35628
36188
|
stopChronicleHealth?.();
|
|
35629
36189
|
stopNetworkTelemetry?.();
|
|
35630
36190
|
unsubscribeChronicle?.();
|
|
36191
|
+
await disposeCounterSink?.();
|
|
35631
36192
|
if (chronicleFileObserver) {
|
|
35632
36193
|
try {
|
|
35633
36194
|
await (await chronicleFileObserver).close();
|
|
@@ -35914,12 +36475,17 @@ import * as path33 from "node:path";
|
|
|
35914
36475
|
import {
|
|
35915
36476
|
startFirstBootSageSync,
|
|
35916
36477
|
subscribeVectorMemoryToSage,
|
|
36478
|
+
sweepStaleSageMirrors,
|
|
35917
36479
|
TransformersEmbeddingProvider,
|
|
35918
36480
|
VectorMemoryStore,
|
|
35919
36481
|
wrapMemoryPortWithVectorRecall
|
|
35920
36482
|
} from "@wrongstack/vector-memory";
|
|
36483
|
+
var DEFAULT_VECTOR_WEIGHT = 0.3;
|
|
35921
36484
|
async function setupVectorMemory(args) {
|
|
35922
|
-
const { projectRoot, flags, logger, memoryStore, teardownHandlers } = args;
|
|
36485
|
+
const { projectRoot, flags, logger, memoryStore, teardownHandlers, tuning } = args;
|
|
36486
|
+
if (tuning?.enabled === false) {
|
|
36487
|
+
return { memoryStore, vectorMemoryStore: void 0, vectorMemoryModelCacheDir: "" };
|
|
36488
|
+
}
|
|
35923
36489
|
let vectorMemoryStore;
|
|
35924
36490
|
const vectorMemoryModelCacheDir = path33.join(
|
|
35925
36491
|
projectRoot,
|
|
@@ -35950,7 +36516,10 @@ async function setupVectorMemory(args) {
|
|
|
35950
36516
|
});
|
|
35951
36517
|
wrapped = wrapMemoryPortWithVectorRecall(wrapped, {
|
|
35952
36518
|
store: vectorMemoryStore,
|
|
35953
|
-
weight:
|
|
36519
|
+
weight: tuning?.weight ?? DEFAULT_VECTOR_WEIGHT,
|
|
36520
|
+
...tuning?.threshold !== void 0 ? { threshold: tuning.threshold } : {},
|
|
36521
|
+
...tuning?.vectorOnlyThreshold !== void 0 ? { vectorOnlyThreshold: tuning.vectorOnlyThreshold } : {},
|
|
36522
|
+
...tuning?.maxMaterializations !== void 0 ? { maxMaterializations: tuning.maxMaterializations } : {}
|
|
35954
36523
|
});
|
|
35955
36524
|
const mirrorHandle = subscribeVectorMemoryToSage({
|
|
35956
36525
|
store: vectorMemoryStore,
|
|
@@ -35958,6 +36527,11 @@ async function setupVectorMemory(args) {
|
|
|
35958
36527
|
logger
|
|
35959
36528
|
});
|
|
35960
36529
|
teardownHandlers.push(() => mirrorHandle.dispose());
|
|
36530
|
+
void sweepStaleSageMirrors({
|
|
36531
|
+
store: vectorMemoryStore,
|
|
36532
|
+
memoryStore: wrapped,
|
|
36533
|
+
logger
|
|
36534
|
+
});
|
|
35961
36535
|
if (flags["vector-sync"] === true) {
|
|
35962
36536
|
const forced = await startFirstBootSageSync({
|
|
35963
36537
|
store: vectorMemoryStore,
|
|
@@ -36026,7 +36600,8 @@ async function runInteractive(cliCtx) {
|
|
|
36026
36600
|
flags,
|
|
36027
36601
|
logger,
|
|
36028
36602
|
memoryStore,
|
|
36029
|
-
teardownHandlers
|
|
36603
|
+
teardownHandlers,
|
|
36604
|
+
tuning: config.Sage?.vector
|
|
36030
36605
|
});
|
|
36031
36606
|
memoryStore = vectorWrappedMemoryStore;
|
|
36032
36607
|
const skillLoader = container.resolve(TOKENS13.SkillLoader);
|
|
@@ -36242,7 +36817,12 @@ async function runInteractive(cliCtx) {
|
|
|
36242
36817
|
container.override(TOKENS13.ProviderModelStatusTracker, () => statusTracker);
|
|
36243
36818
|
bootstrapWrongProxy(config.tools?.wrongProxy);
|
|
36244
36819
|
await awaitFirstWrongProxyProbe();
|
|
36245
|
-
const {
|
|
36820
|
+
const {
|
|
36821
|
+
buildProviderForId: buildProviderForId2,
|
|
36822
|
+
buildProviderForModel,
|
|
36823
|
+
switchProviderAndModel,
|
|
36824
|
+
reloadProviderConfig
|
|
36825
|
+
} = setupProviderRuntime({
|
|
36246
36826
|
config,
|
|
36247
36827
|
onConfigUpdate: (newConfig) => {
|
|
36248
36828
|
config = newConfig;
|
|
@@ -36315,7 +36895,15 @@ async function runInteractive(cliCtx) {
|
|
|
36315
36895
|
events,
|
|
36316
36896
|
autonomyModeRef
|
|
36317
36897
|
});
|
|
36318
|
-
const {
|
|
36898
|
+
const {
|
|
36899
|
+
brain,
|
|
36900
|
+
brainLog,
|
|
36901
|
+
brainTierStats,
|
|
36902
|
+
brainSettings,
|
|
36903
|
+
brainRuntime,
|
|
36904
|
+
multiAgentHost,
|
|
36905
|
+
shadowController
|
|
36906
|
+
} = setupBrainAndOrchestration({
|
|
36319
36907
|
events,
|
|
36320
36908
|
config,
|
|
36321
36909
|
vault,
|
|
@@ -36334,7 +36922,7 @@ async function runInteractive(cliCtx) {
|
|
|
36334
36922
|
cwd,
|
|
36335
36923
|
wpaths,
|
|
36336
36924
|
teardownHandlers,
|
|
36337
|
-
mailboxSessionTag:
|
|
36925
|
+
mailboxSessionTag: mailboxSessionTag7,
|
|
36338
36926
|
brainMailbox,
|
|
36339
36927
|
agentMonitor,
|
|
36340
36928
|
manifestPath,
|
|
@@ -36365,7 +36953,7 @@ async function runInteractive(cliCtx) {
|
|
|
36365
36953
|
agentMonitor,
|
|
36366
36954
|
brainMailbox,
|
|
36367
36955
|
teardownHandlers,
|
|
36368
|
-
mailboxSessionTag:
|
|
36956
|
+
mailboxSessionTag: mailboxSessionTag7,
|
|
36369
36957
|
hqPublisherRef,
|
|
36370
36958
|
mcpRegistry
|
|
36371
36959
|
});
|
|
@@ -36403,6 +36991,9 @@ async function runInteractive(cliCtx) {
|
|
|
36403
36991
|
statuslineLines,
|
|
36404
36992
|
setStatuslineLines,
|
|
36405
36993
|
saveStatuslineLines: saveStatuslineLines2,
|
|
36994
|
+
statuslineDensities,
|
|
36995
|
+
setStatuslineDensities,
|
|
36996
|
+
saveStatuslineDensities,
|
|
36406
36997
|
agentsMonitorController,
|
|
36407
36998
|
onPanelOpen,
|
|
36408
36999
|
goalHost,
|
|
@@ -36471,6 +37062,7 @@ async function runInteractive(cliCtx) {
|
|
|
36471
37062
|
brainSettings,
|
|
36472
37063
|
brainRuntime,
|
|
36473
37064
|
initialBrainLog: brainLog,
|
|
37065
|
+
brainTierStats,
|
|
36474
37066
|
coordinatorController,
|
|
36475
37067
|
statusTracker,
|
|
36476
37068
|
shadowController,
|
|
@@ -36615,6 +37207,7 @@ async function runInteractive(cliCtx) {
|
|
|
36615
37207
|
resolvedProvider,
|
|
36616
37208
|
logger,
|
|
36617
37209
|
switchProviderAndModel,
|
|
37210
|
+
reloadProviderConfig,
|
|
36618
37211
|
applyMaxContext,
|
|
36619
37212
|
renderer,
|
|
36620
37213
|
reader,
|
|
@@ -36642,6 +37235,9 @@ async function runInteractive(cliCtx) {
|
|
|
36642
37235
|
statuslineLines,
|
|
36643
37236
|
setStatuslineLines,
|
|
36644
37237
|
saveStatuslineLines: saveStatuslineLines2,
|
|
37238
|
+
statuslineDensities,
|
|
37239
|
+
setStatuslineDensities,
|
|
37240
|
+
saveStatuslineDensities,
|
|
36645
37241
|
setYoloMode,
|
|
36646
37242
|
autonomyMode,
|
|
36647
37243
|
setAutonomyMode: (mode) => {
|
|
@@ -36683,4 +37279,4 @@ export {
|
|
|
36683
37279
|
CLI_VERSION,
|
|
36684
37280
|
runInteractive
|
|
36685
37281
|
};
|
|
36686
|
-
//# sourceMappingURL=cli-main-
|
|
37282
|
+
//# sourceMappingURL=cli-main-TTIVR4DI.js.map
|