@wrongstack/cli 0.306.4 → 0.307.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{auth-L3WGSGDX.js → auth-TVOOHL4Q.js} +45 -106
- package/dist/boot/short-circuit-flags.d.ts +2 -2
- package/dist/chimera-cascade-evidence.d.ts +1 -1
- package/dist/chunk-2VMJ3E5Z.js +71 -0
- package/dist/{chunk-RHLQT3EV.js → chunk-CB35UVXO.js} +1636 -1528
- package/dist/{chunk-YKBRFSGL.js → chunk-DOJLAULS.js} +28 -28
- package/dist/{chunk-KXN5HZDL.js → chunk-PKHGLWUJ.js} +24 -6
- package/dist/{chunk-HITHEXE3.js → chunk-TOG7OMKJ.js} +2 -2
- package/dist/{chunk-ARWGQUB3.js → chunk-XSG33WHN.js} +15 -5
- package/dist/{cli-main-4TZCCZR6.js → cli-main-YDOZZOZA.js} +21606 -20849
- package/dist/cli-main.d.ts +0 -20
- package/dist/{execution-547PM3NI.js → execution-CGT6J5ZN.js} +304 -272
- package/dist/fleet/host-learning-scheduler.d.ts +27 -0
- package/dist/fleet/host-shadow-manager.d.ts +64 -0
- package/dist/fleet/host.d.ts +5 -140
- package/dist/{hq-ZK6PGN3W.js → hq-PA6RH2UW.js} +2 -2
- package/dist/hq-server/mailbox-gateway-manager.d.ts +32 -0
- package/dist/hq-server/routes/auth/bootstrap-routes.d.ts +5 -0
- package/dist/hq-server/routes/auth/common.d.ts +11 -0
- package/dist/hq-server/routes/auth/password-routes.d.ts +9 -0
- package/dist/hq-server/routes/auth/session-audit-routes.d.ts +6 -0
- package/dist/hq-server/routes/auth/totp-routes.d.ts +9 -0
- package/dist/hq-server/routes/auth-handlers.d.ts +5 -132
- package/dist/hq-server/routes/command-handlers.d.ts +7 -0
- package/dist/hq-server/routes/data-handlers.d.ts +8 -0
- package/dist/hq-server/routes/mailbox-handlers.d.ts +22 -0
- package/dist/hq-server/routes.d.ts +3 -3
- package/dist/hq-server/server-lifecycle.d.ts +37 -0
- package/dist/hq-server/snapshot.d.ts +6 -5
- package/dist/hq-server/types.d.ts +4 -0
- package/dist/hq-server/upgrade-handler.d.ts +34 -0
- package/dist/hq-server/ws-client-events.d.ts +25 -0
- package/dist/hq-server/ws-leader.d.ts +47 -0
- package/dist/hq-server/ws-resume.d.ts +27 -0
- package/dist/hq-server/ws.d.ts +4 -71
- package/dist/{hq-server-IVZLVCFV.js → hq-server-PBRU275L.js} +2 -2
- package/dist/hq-server.d.ts +0 -38
- package/dist/index.js +1267 -122
- package/dist/{mcp-W7HHN7IA.js → mcp-CMLFHRG2.js} +14 -7
- package/dist/mcp-serve.d.ts +12 -1
- package/dist/{modeldiag-6VS5KDP5.js → modeldiag-ICMPHT5L.js} +868 -831
- package/dist/{providers-models-HQN3AT3K.js → providers-models-4FAKM2WO.js} +4 -4
- package/dist/repl-eternal-loop.d.ts +8 -0
- package/dist/repl-goal-banner.d.ts +21 -0
- package/dist/slash-commands/brain-council.d.ts +36 -0
- package/dist/slash-commands/brain-status.d.ts +12 -0
- package/dist/slash-commands/kanban-board-handlers.d.ts +13 -0
- package/dist/slash-commands/kanban-lifecycle-diagnostics.d.ts +16 -0
- package/dist/slash-commands/kanban-task-subcommands.d.ts +8 -0
- package/dist/slash-commands/memory-audience.d.ts +14 -0
- package/dist/slash-commands/memory-gather.d.ts +9 -0
- package/dist/slash-commands/memory-stats.d.ts +5 -0
- package/dist/slash-commands/settings-mutations.d.ts +6 -0
- package/dist/slash-commands/settings-view.d.ts +5 -0
- package/dist/subcommands/handlers/modeldiag-bench.d.ts +10 -0
- package/dist/subcommands/handlers/modeldiag-eval.d.ts +27 -0
- package/dist/subcommands/handlers/modeldiag-test.d.ts +8 -0
- package/dist/{version-help-ASKQYXDJ.js → version-help-TFD6VPF3.js} +2 -2
- package/dist/vibe-protocol-wiring.d.ts +10 -0
- package/dist/webui-server/credential-watcher.d.ts +15 -0
- package/dist/webui-server/domain-handlers.d.ts +21 -0
- package/dist/webui-server/route-contexts.d.ts +41 -0
- package/dist/{webui-server-FTG7JAZU.js → webui-server-IPHGJGXE.js} +515 -437
- package/dist/wiring/cli-execute-builder.d.ts +88 -0
- package/dist/wiring/cli-heap-watchdog.d.ts +33 -0
- package/dist/wiring/cli-prompt-and-tools-setup.d.ts +25 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +79 -0
- package/dist/wiring/heap-watchdog-setup.d.ts +53 -0
- package/dist/wiring/metrics.d.ts +1 -0
- package/dist/wiring/replay-governance-setup.d.ts +31 -0
- package/package.json +27 -27
|
@@ -18,36 +18,22 @@ import "./chunk-7OCVIDC7.js";
|
|
|
18
18
|
|
|
19
19
|
// src/webui-server.ts
|
|
20
20
|
import { findPackageJSON } from "node:module";
|
|
21
|
-
import * as
|
|
22
|
-
import * as path5 from "node:path";
|
|
23
|
-
import { TOKENS } from "@wrongstack/core/kernel";
|
|
21
|
+
import * as path7 from "node:path";
|
|
24
22
|
import { createCompatibilityTrustBoundary, DefaultSecretScrubber } from "@wrongstack/core/security";
|
|
25
|
-
import { SkillInstaller } from "@wrongstack/core/skills";
|
|
26
|
-
import { PromptUsageStore, watchProviderConfig } from "@wrongstack/core/storage";
|
|
27
23
|
import {
|
|
28
|
-
resolveWstackPaths as resolveWstackPaths2,
|
|
29
24
|
startSharedHeapWatchdog,
|
|
30
25
|
wstackGlobalRoot
|
|
31
26
|
} from "@wrongstack/core/utils";
|
|
32
|
-
import { toErrorMessage } from "@wrongstack/core/utils/error";
|
|
33
|
-
import { makeProviderFromConfig } from "@wrongstack/providers";
|
|
27
|
+
import { toErrorMessage as toErrorMessage2 } from "@wrongstack/core/utils/error";
|
|
34
28
|
import {
|
|
35
|
-
buildSddWizardDeps,
|
|
36
29
|
buildWebUIAccessUrl,
|
|
37
30
|
createCustomModeStore,
|
|
38
31
|
createEmbeddedMessageRouter,
|
|
39
32
|
createEmbeddedProviderOperations,
|
|
40
|
-
createMailboxRouteHandlers,
|
|
41
33
|
envFlag,
|
|
42
34
|
findFreePort,
|
|
43
|
-
GoalWebSocketHandler,
|
|
44
35
|
resolveAuthToken,
|
|
45
|
-
|
|
46
|
-
SddWizardWebSocketHandler,
|
|
47
|
-
SpecsWebSocketHandler,
|
|
48
|
-
sendSerialized,
|
|
49
|
-
TerminalWebSocketHandler,
|
|
50
|
-
WorktreeWebSocketHandler
|
|
36
|
+
sendSerialized
|
|
51
37
|
} from "@wrongstack/webui-server";
|
|
52
38
|
import { WebSocketServer } from "ws";
|
|
53
39
|
|
|
@@ -177,9 +163,310 @@ function createConnectionHandler(deps) {
|
|
|
177
163
|
});
|
|
178
164
|
}
|
|
179
165
|
|
|
166
|
+
// src/webui-server/credential-watcher.ts
|
|
167
|
+
import { TOKENS } from "@wrongstack/core/kernel";
|
|
168
|
+
import { watchProviderConfig } from "@wrongstack/core/storage";
|
|
169
|
+
import { toErrorMessage } from "@wrongstack/core/utils/error";
|
|
170
|
+
import { makeProviderFromConfig } from "@wrongstack/providers";
|
|
171
|
+
|
|
172
|
+
// src/webui-server/provider-config.ts
|
|
173
|
+
import * as path from "node:path";
|
|
174
|
+
import { DefaultSecretVault } from "@wrongstack/core/security";
|
|
175
|
+
function getVault(globalConfigPath) {
|
|
176
|
+
const configDir = path.dirname(globalConfigPath ?? "");
|
|
177
|
+
const parentDir = path.dirname(configDir);
|
|
178
|
+
const globalRoot = path.basename(parentDir) === "profiles" ? path.dirname(parentDir) : configDir;
|
|
179
|
+
const keyFile = path.join(globalRoot, ".key");
|
|
180
|
+
return new DefaultSecretVault({ keyFile });
|
|
181
|
+
}
|
|
182
|
+
async function loadSavedProviders(globalConfigPath) {
|
|
183
|
+
if (!globalConfigPath) return {};
|
|
184
|
+
return loadConfigProviders(globalConfigPath, getVault(globalConfigPath));
|
|
185
|
+
}
|
|
186
|
+
async function saveProviders(globalConfigPath, providers) {
|
|
187
|
+
if (!globalConfigPath) return;
|
|
188
|
+
await mutateConfigProviders(
|
|
189
|
+
globalConfigPath,
|
|
190
|
+
getVault(globalConfigPath),
|
|
191
|
+
(existing) => {
|
|
192
|
+
for (const key of Object.keys(existing)) delete existing[key];
|
|
193
|
+
Object.assign(existing, providers);
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
function createProviderConfigStore(globalConfigPath, configProvidersRef) {
|
|
198
|
+
return {
|
|
199
|
+
load: () => configProvidersRef ? Promise.resolve(configProvidersRef()) : loadSavedProviders(globalConfigPath),
|
|
200
|
+
save: (providers) => saveProviders(globalConfigPath, providers)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/webui-server/credential-watcher.ts
|
|
205
|
+
function startWebuiCredentialWatcher({
|
|
206
|
+
opts,
|
|
207
|
+
profileConfigPath,
|
|
208
|
+
broadcast,
|
|
209
|
+
broadcastSaved
|
|
210
|
+
}) {
|
|
211
|
+
const watchConfigPath = profileConfigPath;
|
|
212
|
+
if (!watchConfigPath || process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] === "1") {
|
|
213
|
+
return void 0;
|
|
214
|
+
}
|
|
215
|
+
let lastActiveCfg = JSON.stringify(
|
|
216
|
+
opts.appConfig?.providers?.[opts.agent.ctx.provider.id] ?? null
|
|
217
|
+
);
|
|
218
|
+
let lastUiLocale = opts.appConfig?.uiLocale;
|
|
219
|
+
const watcher = watchProviderConfig(
|
|
220
|
+
watchConfigPath,
|
|
221
|
+
// Vault key lives at ~/.wrongstack/.key (derived from globalConfigPath),
|
|
222
|
+
// not inside the profile directory — resolve via global root to stay correct.
|
|
223
|
+
getVault(opts.globalConfigPath),
|
|
224
|
+
(snapshot) => {
|
|
225
|
+
const hadFallbackBridge = Boolean(opts.appConfig?.fallbackBridge?.trim());
|
|
226
|
+
try {
|
|
227
|
+
if (opts.appConfig && !Object.isFrozen(opts.appConfig)) {
|
|
228
|
+
opts.appConfig.providers = snapshot.providers;
|
|
229
|
+
if (snapshot.uiLocale) opts.appConfig.uiLocale = snapshot.uiLocale;
|
|
230
|
+
if (snapshot.fallbackBridge !== void 0) {
|
|
231
|
+
opts.appConfig.fallbackBridge = snapshot.fallbackBridge;
|
|
232
|
+
} else {
|
|
233
|
+
delete opts.appConfig.fallbackBridge;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
} catch {
|
|
237
|
+
}
|
|
238
|
+
const routingChanged = snapshot.fallbackModels !== void 0 || snapshot.fallbackBridge !== void 0 || hadFallbackBridge || snapshot.fallbackProfiles !== void 0 || snapshot.favoriteModels !== void 0 || snapshot.favoriteModelsOnly !== void 0 || snapshot.modelMatrix !== void 0 || snapshot.fallbackAuto !== void 0;
|
|
239
|
+
if (routingChanged) {
|
|
240
|
+
const configStore = opts.agent.container?.safeResolve?.(TOKENS.ConfigStore);
|
|
241
|
+
configStore?.update({
|
|
242
|
+
...snapshot.fallbackModels !== void 0 ? { fallbackModels: snapshot.fallbackModels } : {},
|
|
243
|
+
fallbackBridge: snapshot.fallbackBridge ?? "",
|
|
244
|
+
...snapshot.fallbackProfiles !== void 0 ? { fallbackProfiles: snapshot.fallbackProfiles } : {},
|
|
245
|
+
...snapshot.favoriteModels !== void 0 ? { favoriteModels: snapshot.favoriteModels } : {},
|
|
246
|
+
...snapshot.favoriteModelsOnly !== void 0 ? { favoriteModelsOnly: snapshot.favoriteModelsOnly } : {},
|
|
247
|
+
...snapshot.modelMatrix !== void 0 ? { modelMatrix: snapshot.modelMatrix } : {},
|
|
248
|
+
...snapshot.fallbackAuto !== void 0 ? { fallbackAuto: snapshot.fallbackAuto } : {}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
broadcastSaved(snapshot.providers);
|
|
252
|
+
if (snapshot.uiLocale !== lastUiLocale) {
|
|
253
|
+
lastUiLocale = snapshot.uiLocale;
|
|
254
|
+
if (snapshot.uiLocale) {
|
|
255
|
+
opts.agent.ctx.meta["uiLocale"] = snapshot.uiLocale;
|
|
256
|
+
broadcast({ type: "prefs.updated", payload: { uiLocale: snapshot.uiLocale } });
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const activeId = opts.agent.ctx.provider.id;
|
|
260
|
+
const newCfgStr = JSON.stringify(snapshot.providers[activeId] ?? null);
|
|
261
|
+
if (newCfgStr === lastActiveCfg) return;
|
|
262
|
+
lastActiveCfg = newCfgStr;
|
|
263
|
+
try {
|
|
264
|
+
const newCfg = snapshot.providers[activeId] ?? {
|
|
265
|
+
type: activeId,
|
|
266
|
+
...snapshot.apiKey !== void 0 ? { apiKey: snapshot.apiKey } : {},
|
|
267
|
+
...snapshot.baseUrl !== void 0 ? { baseUrl: snapshot.baseUrl } : {}
|
|
268
|
+
};
|
|
269
|
+
const oldMax = opts.agent.ctx.provider.capabilities?.maxContext;
|
|
270
|
+
const prov = makeProviderFromConfig(activeId, {
|
|
271
|
+
...newCfg,
|
|
272
|
+
type: newCfg.type ?? activeId
|
|
273
|
+
});
|
|
274
|
+
if (oldMax != null && prov.capabilities) prov.capabilities.maxContext = oldMax;
|
|
275
|
+
opts.agent.ctx.provider = prov;
|
|
276
|
+
console.log(`[WebUI] Provider credentials reloaded from config.json (${activeId})`);
|
|
277
|
+
} catch (err) {
|
|
278
|
+
console.warn(
|
|
279
|
+
`[WebUI] Credential hot-reload failed for ${activeId}: ${toErrorMessage(err)}`
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
warn: (m) => console.warn(
|
|
285
|
+
JSON.stringify({
|
|
286
|
+
level: "warn",
|
|
287
|
+
event: "webui.config_watcher",
|
|
288
|
+
message: m,
|
|
289
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
290
|
+
})
|
|
291
|
+
)
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
return watcher.close;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// src/webui-server/domain-handlers.ts
|
|
298
|
+
import * as os from "node:os";
|
|
299
|
+
import * as path3 from "node:path";
|
|
300
|
+
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
301
|
+
import {
|
|
302
|
+
buildSddWizardDeps,
|
|
303
|
+
GoalWebSocketHandler,
|
|
304
|
+
SddBoardWebSocketHandler,
|
|
305
|
+
SddWizardWebSocketHandler,
|
|
306
|
+
SpecsWebSocketHandler,
|
|
307
|
+
TerminalWebSocketHandler,
|
|
308
|
+
WorktreeWebSocketHandler
|
|
309
|
+
} from "@wrongstack/webui-server";
|
|
310
|
+
|
|
311
|
+
// src/webui-server/logger-shim.ts
|
|
312
|
+
var structuredLine = (level, message) => JSON.stringify({
|
|
313
|
+
level,
|
|
314
|
+
event: "webui.goal",
|
|
315
|
+
message,
|
|
316
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
317
|
+
});
|
|
318
|
+
var consoleLogger = {
|
|
319
|
+
level: "debug",
|
|
320
|
+
error(msg, _ctx) {
|
|
321
|
+
console.error(structuredLine("error", msg));
|
|
322
|
+
},
|
|
323
|
+
warn(msg, _ctx) {
|
|
324
|
+
console.warn(structuredLine("warn", msg));
|
|
325
|
+
},
|
|
326
|
+
info(msg, _ctx) {
|
|
327
|
+
console.log(structuredLine("info", msg));
|
|
328
|
+
},
|
|
329
|
+
debug(msg, _ctx) {
|
|
330
|
+
console.debug(structuredLine("debug", msg));
|
|
331
|
+
},
|
|
332
|
+
trace(msg, _ctx) {
|
|
333
|
+
console.debug(structuredLine("trace", msg));
|
|
334
|
+
},
|
|
335
|
+
child(_bindings) {
|
|
336
|
+
return this;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
// src/webui-server/node-pty-loader.ts
|
|
341
|
+
import { existsSync } from "node:fs";
|
|
342
|
+
import { createRequire } from "node:module";
|
|
343
|
+
import * as path2 from "node:path";
|
|
344
|
+
import { fileURLToPath } from "node:url";
|
|
345
|
+
function createNodePtyLoader(importMetaUrl, logger) {
|
|
346
|
+
const requireFromCli = createRequire(importMetaUrl);
|
|
347
|
+
let cachedNodePty;
|
|
348
|
+
return () => {
|
|
349
|
+
if (cachedNodePty !== void 0) return cachedNodePty;
|
|
350
|
+
try {
|
|
351
|
+
const webuiEntry = requireFromCli.resolve("@wrongstack/webui");
|
|
352
|
+
const webuiDir = webuiEntry.replace(/[\\/]dist.*$/, "");
|
|
353
|
+
const webuiPkgJson = path2.join(webuiDir, "package.json");
|
|
354
|
+
cachedNodePty = createRequire(webuiPkgJson)("node-pty");
|
|
355
|
+
if (cachedNodePty) {
|
|
356
|
+
logger.debug?.(`[terminal] node-pty loaded via webui package (${webuiDir})`);
|
|
357
|
+
return cachedNodePty;
|
|
358
|
+
}
|
|
359
|
+
} catch (err) {
|
|
360
|
+
logger.debug?.(`[terminal] webui-route failed: ${err.message}`);
|
|
361
|
+
}
|
|
362
|
+
try {
|
|
363
|
+
cachedNodePty = requireFromCli("node-pty");
|
|
364
|
+
logger.debug?.("[terminal] node-pty loaded via direct requireFromCli");
|
|
365
|
+
return cachedNodePty;
|
|
366
|
+
} catch (err) {
|
|
367
|
+
logger.debug?.(`[terminal] direct require failed: ${err.message}`);
|
|
368
|
+
}
|
|
369
|
+
try {
|
|
370
|
+
const cliPkgJson = path2.join(
|
|
371
|
+
path2.dirname(fileURLToPath(importMetaUrl)),
|
|
372
|
+
"..",
|
|
373
|
+
"package.json"
|
|
374
|
+
);
|
|
375
|
+
let dir = path2.dirname(cliPkgJson);
|
|
376
|
+
for (let i = 0; i < 6; i++) {
|
|
377
|
+
const candidate = path2.join(dir, "node_modules", "node-pty");
|
|
378
|
+
if (existsSync(candidate)) {
|
|
379
|
+
cachedNodePty = createRequire(candidate)("node-pty");
|
|
380
|
+
if (cachedNodePty) {
|
|
381
|
+
logger.debug?.(`[terminal] node-pty loaded via workspace root (${candidate})`);
|
|
382
|
+
return cachedNodePty;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const parent = path2.dirname(dir);
|
|
386
|
+
if (parent === dir) break;
|
|
387
|
+
dir = parent;
|
|
388
|
+
}
|
|
389
|
+
} catch (err) {
|
|
390
|
+
logger.debug?.(`[terminal] workspace-root walk failed: ${err.message}`);
|
|
391
|
+
}
|
|
392
|
+
cachedNodePty = null;
|
|
393
|
+
logger.debug?.(
|
|
394
|
+
'[terminal] node-pty resolution failed; terminal panel will report "unavailable"'
|
|
395
|
+
);
|
|
396
|
+
return cachedNodePty;
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// src/webui-server/domain-handlers.ts
|
|
401
|
+
function createWebuiDomainHandlers(opts, trustBoundary, kanbanRunMirror) {
|
|
402
|
+
const goalStoreDir = opts.projectRoot ? path3.join(opts.projectRoot, ".wrongstack", "goal") : path3.join(os.tmpdir(), ".wrongstack", "goal");
|
|
403
|
+
const goalHandler = new GoalWebSocketHandler(
|
|
404
|
+
opts.agent,
|
|
405
|
+
opts.agent.ctx,
|
|
406
|
+
consoleLogger,
|
|
407
|
+
goalStoreDir,
|
|
408
|
+
opts.events,
|
|
409
|
+
opts.projectRoot,
|
|
410
|
+
kanbanRunMirror ? (graphId, state) => kanbanRunMirror.onGoalState(graphId, state) : void 0
|
|
411
|
+
);
|
|
412
|
+
const worktreeHandler = new WorktreeWebSocketHandler(opts.events, consoleLogger);
|
|
413
|
+
const loadNodePtyViaWebui = createNodePtyLoader(import.meta.url, consoleLogger);
|
|
414
|
+
const terminalHandler = new TerminalWebSocketHandler(
|
|
415
|
+
() => opts.agent.ctx.cwd ?? opts.projectRoot ?? process.cwd(),
|
|
416
|
+
consoleLogger,
|
|
417
|
+
loadNodePtyViaWebui,
|
|
418
|
+
void 0,
|
|
419
|
+
trustBoundary
|
|
420
|
+
);
|
|
421
|
+
const specsPaths = opts.projectRoot ? resolveWstackPaths({ projectRoot: opts.projectRoot }) : null;
|
|
422
|
+
const specsHandler = new SpecsWebSocketHandler(
|
|
423
|
+
specsPaths?.projectSpecs ?? path3.join(os.tmpdir(), ".wrongstack", "specs"),
|
|
424
|
+
specsPaths?.projectTaskGraphs ?? path3.join(os.tmpdir(), ".wrongstack", "task-graphs")
|
|
425
|
+
);
|
|
426
|
+
const sddBoardHandler = new SddBoardWebSocketHandler(
|
|
427
|
+
specsPaths?.projectSddBoards ?? path3.join(os.tmpdir(), ".wrongstack", "sdd-boards"),
|
|
428
|
+
opts.events,
|
|
429
|
+
specsPaths && opts.projectRoot ? {
|
|
430
|
+
projectRoot: opts.projectRoot,
|
|
431
|
+
paths: {
|
|
432
|
+
projectSpecs: specsPaths.projectSpecs,
|
|
433
|
+
projectTaskGraphs: specsPaths.projectTaskGraphs,
|
|
434
|
+
projectSddSession: specsPaths.projectSddSession,
|
|
435
|
+
projectSddBoards: specsPaths.projectSddBoards
|
|
436
|
+
}
|
|
437
|
+
} : void 0,
|
|
438
|
+
{ trustBoundary, logger: consoleLogger }
|
|
439
|
+
);
|
|
440
|
+
const sddWizardHandler = opts.sddSubagentFactory && specsPaths ? new SddWizardWebSocketHandler(
|
|
441
|
+
buildSddWizardDeps({
|
|
442
|
+
agent: opts.agent,
|
|
443
|
+
events: opts.events,
|
|
444
|
+
projectRoot: opts.projectRoot ?? process.cwd(),
|
|
445
|
+
subagentFactory: opts.sddSubagentFactory,
|
|
446
|
+
...opts.brain ? { brain: opts.brain } : {},
|
|
447
|
+
paths: {
|
|
448
|
+
projectSpecs: specsPaths.projectSpecs,
|
|
449
|
+
projectTaskGraphs: specsPaths.projectTaskGraphs,
|
|
450
|
+
projectSddBoards: specsPaths.projectSddBoards,
|
|
451
|
+
projectDir: specsPaths.projectDir,
|
|
452
|
+
projectSddSession: specsPaths.projectSddSession
|
|
453
|
+
}
|
|
454
|
+
})
|
|
455
|
+
) : null;
|
|
456
|
+
return {
|
|
457
|
+
goalHandler,
|
|
458
|
+
worktreeHandler,
|
|
459
|
+
terminalHandler,
|
|
460
|
+
specsHandler,
|
|
461
|
+
sddBoardHandler,
|
|
462
|
+
sddWizardHandler,
|
|
463
|
+
specsPaths
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
|
|
180
467
|
// src/webui-server/kanban-host-adapter.ts
|
|
181
468
|
import { PhaseGraphBuilder } from "@wrongstack/core/goal";
|
|
182
|
-
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
469
|
+
import { resolveWstackPaths as resolveWstackPaths2 } from "@wrongstack/core/utils";
|
|
183
470
|
import { exportBoardToTaskGraph } from "@wrongstack/kanban";
|
|
184
471
|
import { TaskGraphStore } from "@wrongstack/sdd";
|
|
185
472
|
import {
|
|
@@ -310,7 +597,7 @@ function createCliKanbanHostRoutes(deps) {
|
|
|
310
597
|
if (!opts.sddSubagentFactory) {
|
|
311
598
|
return failRun("SDD runs need the multi-agent host, which is not available here.");
|
|
312
599
|
}
|
|
313
|
-
const paths =
|
|
600
|
+
const paths = resolveWstackPaths2({ projectRoot });
|
|
314
601
|
const taskStore = new TaskGraphStore({ baseDir: paths.projectTaskGraphs });
|
|
315
602
|
await taskStore.save(exported.graph);
|
|
316
603
|
const handle = await startSddRunFromGraph(
|
|
@@ -406,99 +693,10 @@ async function startIpv6LoopbackProxy(args) {
|
|
|
406
693
|
return v6;
|
|
407
694
|
}
|
|
408
695
|
|
|
409
|
-
// src/webui-server/logger-shim.ts
|
|
410
|
-
var structuredLine = (level, message) => JSON.stringify({
|
|
411
|
-
level,
|
|
412
|
-
event: "webui.goal",
|
|
413
|
-
message,
|
|
414
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
415
|
-
});
|
|
416
|
-
var consoleLogger = {
|
|
417
|
-
level: "debug",
|
|
418
|
-
error(msg, _ctx) {
|
|
419
|
-
console.error(structuredLine("error", msg));
|
|
420
|
-
},
|
|
421
|
-
warn(msg, _ctx) {
|
|
422
|
-
console.warn(structuredLine("warn", msg));
|
|
423
|
-
},
|
|
424
|
-
info(msg, _ctx) {
|
|
425
|
-
console.log(structuredLine("info", msg));
|
|
426
|
-
},
|
|
427
|
-
debug(msg, _ctx) {
|
|
428
|
-
console.debug(structuredLine("debug", msg));
|
|
429
|
-
},
|
|
430
|
-
trace(msg, _ctx) {
|
|
431
|
-
console.debug(structuredLine("trace", msg));
|
|
432
|
-
},
|
|
433
|
-
child(_bindings) {
|
|
434
|
-
return this;
|
|
435
|
-
}
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
// src/webui-server/node-pty-loader.ts
|
|
439
|
-
import { existsSync } from "node:fs";
|
|
440
|
-
import { createRequire } from "node:module";
|
|
441
|
-
import * as path from "node:path";
|
|
442
|
-
import { fileURLToPath } from "node:url";
|
|
443
|
-
function createNodePtyLoader(importMetaUrl, logger) {
|
|
444
|
-
const requireFromCli = createRequire(importMetaUrl);
|
|
445
|
-
let cachedNodePty;
|
|
446
|
-
return () => {
|
|
447
|
-
if (cachedNodePty !== void 0) return cachedNodePty;
|
|
448
|
-
try {
|
|
449
|
-
const webuiEntry = requireFromCli.resolve("@wrongstack/webui");
|
|
450
|
-
const webuiDir = webuiEntry.replace(/[\\/]dist.*$/, "");
|
|
451
|
-
const webuiPkgJson = path.join(webuiDir, "package.json");
|
|
452
|
-
cachedNodePty = createRequire(webuiPkgJson)("node-pty");
|
|
453
|
-
if (cachedNodePty) {
|
|
454
|
-
logger.debug?.(`[terminal] node-pty loaded via webui package (${webuiDir})`);
|
|
455
|
-
return cachedNodePty;
|
|
456
|
-
}
|
|
457
|
-
} catch (err) {
|
|
458
|
-
logger.debug?.(`[terminal] webui-route failed: ${err.message}`);
|
|
459
|
-
}
|
|
460
|
-
try {
|
|
461
|
-
cachedNodePty = requireFromCli("node-pty");
|
|
462
|
-
logger.debug?.("[terminal] node-pty loaded via direct requireFromCli");
|
|
463
|
-
return cachedNodePty;
|
|
464
|
-
} catch (err) {
|
|
465
|
-
logger.debug?.(`[terminal] direct require failed: ${err.message}`);
|
|
466
|
-
}
|
|
467
|
-
try {
|
|
468
|
-
const cliPkgJson = path.join(
|
|
469
|
-
path.dirname(fileURLToPath(importMetaUrl)),
|
|
470
|
-
"..",
|
|
471
|
-
"package.json"
|
|
472
|
-
);
|
|
473
|
-
let dir = path.dirname(cliPkgJson);
|
|
474
|
-
for (let i = 0; i < 6; i++) {
|
|
475
|
-
const candidate = path.join(dir, "node_modules", "node-pty");
|
|
476
|
-
if (existsSync(candidate)) {
|
|
477
|
-
cachedNodePty = createRequire(candidate)("node-pty");
|
|
478
|
-
if (cachedNodePty) {
|
|
479
|
-
logger.debug?.(`[terminal] node-pty loaded via workspace root (${candidate})`);
|
|
480
|
-
return cachedNodePty;
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
const parent = path.dirname(dir);
|
|
484
|
-
if (parent === dir) break;
|
|
485
|
-
dir = parent;
|
|
486
|
-
}
|
|
487
|
-
} catch (err) {
|
|
488
|
-
logger.debug?.(`[terminal] workspace-root walk failed: ${err.message}`);
|
|
489
|
-
}
|
|
490
|
-
cachedNodePty = null;
|
|
491
|
-
logger.debug?.(
|
|
492
|
-
'[terminal] node-pty resolution failed; terminal panel will report "unavailable"'
|
|
493
|
-
);
|
|
494
|
-
return cachedNodePty;
|
|
495
|
-
};
|
|
496
|
-
}
|
|
497
|
-
|
|
498
696
|
// src/webui-server/prefs-seeding.ts
|
|
499
697
|
import * as fs from "node:fs/promises";
|
|
500
|
-
import * as
|
|
501
|
-
import { DefaultSecretVault } from "@wrongstack/core/security";
|
|
698
|
+
import * as path4 from "node:path";
|
|
699
|
+
import { DefaultSecretVault as DefaultSecretVault2 } from "@wrongstack/core/security";
|
|
502
700
|
import {
|
|
503
701
|
PREF_KEYS,
|
|
504
702
|
persistPrefsToConfig,
|
|
@@ -553,8 +751,8 @@ function createPrefsSeeding(opts) {
|
|
|
553
751
|
patchLiveAppConfig({ modelMatrix: payload["modelMatrix"] });
|
|
554
752
|
}
|
|
555
753
|
if (!opts.profileConfigPath) return;
|
|
556
|
-
const globalRoot = opts.globalConfigPath ?
|
|
557
|
-
const vault = new
|
|
754
|
+
const globalRoot = opts.globalConfigPath ? path4.dirname(opts.globalConfigPath) : path4.dirname(opts.profileConfigPath);
|
|
755
|
+
const vault = new DefaultSecretVault2({ keyFile: path4.join(globalRoot, ".key") });
|
|
558
756
|
await persistPrefsToConfig(
|
|
559
757
|
{
|
|
560
758
|
profileConfigPath: opts.profileConfigPath,
|
|
@@ -576,46 +774,172 @@ function createPrefsSeeding(opts) {
|
|
|
576
774
|
payload
|
|
577
775
|
);
|
|
578
776
|
};
|
|
579
|
-
return {
|
|
580
|
-
prefSnapshot: () => snapshotPrefs(opts.agent.ctx.meta),
|
|
581
|
-
persistPrefs
|
|
777
|
+
return {
|
|
778
|
+
prefSnapshot: () => snapshotPrefs(opts.agent.ctx.meta),
|
|
779
|
+
persistPrefs
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// src/webui-server/route-contexts.ts
|
|
784
|
+
import * as path5 from "node:path";
|
|
785
|
+
import { TOKENS as TOKENS2 } from "@wrongstack/core/kernel";
|
|
786
|
+
import { SkillInstaller } from "@wrongstack/core/skills";
|
|
787
|
+
import { PromptUsageStore } from "@wrongstack/core/storage";
|
|
788
|
+
import { resolveWstackPaths as resolveWstackPaths3 } from "@wrongstack/core/utils";
|
|
789
|
+
import {
|
|
790
|
+
createMailboxRouteHandlers
|
|
791
|
+
} from "@wrongstack/webui-server";
|
|
792
|
+
function createWebuiRouteContexts({
|
|
793
|
+
opts,
|
|
794
|
+
profileConfigPath,
|
|
795
|
+
profileDir,
|
|
796
|
+
globalRoot,
|
|
797
|
+
sessionStartedAt,
|
|
798
|
+
currentSessionId,
|
|
799
|
+
getCustomModeStore,
|
|
800
|
+
buildSessionStartPayload,
|
|
801
|
+
prefSnapshot,
|
|
802
|
+
persistPrefs,
|
|
803
|
+
pendingConfirms,
|
|
804
|
+
abortControllers,
|
|
805
|
+
getAbortController,
|
|
806
|
+
clearAbortController,
|
|
807
|
+
send,
|
|
808
|
+
broadcast
|
|
809
|
+
}) {
|
|
810
|
+
const brainCtx = {
|
|
811
|
+
brainSettings: opts.brainSettings,
|
|
812
|
+
brainRuntime: opts.brainRuntime,
|
|
813
|
+
getBrainLog: opts.getBrainLog,
|
|
814
|
+
resolveArbiter: () => opts.brain ?? (opts.agent.container.has(TOKENS2.BrainArbiter) ? opts.agent.container.resolve(TOKENS2.BrainArbiter) : void 0),
|
|
815
|
+
getSessionId: currentSessionId,
|
|
816
|
+
send
|
|
817
|
+
};
|
|
818
|
+
const introspectionConfigStore = opts.agent.container?.safeResolve?.(TOKENS2.ConfigStore);
|
|
819
|
+
const introspectionCtx = {
|
|
820
|
+
agent: opts.agent,
|
|
821
|
+
modelsRegistry: opts.modelsRegistry,
|
|
822
|
+
configStore: introspectionConfigStore,
|
|
823
|
+
getConfig: () => {
|
|
824
|
+
const cfg = introspectionConfigStore?.get() ?? opts.appConfig;
|
|
825
|
+
if (!cfg)
|
|
826
|
+
throw new Error(
|
|
827
|
+
"Introspection route requires a config but neither ConfigStore nor opts.appConfig is available"
|
|
828
|
+
);
|
|
829
|
+
return cfg;
|
|
830
|
+
},
|
|
831
|
+
getProjectRoot: () => opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "",
|
|
832
|
+
getSessionId: currentSessionId,
|
|
833
|
+
getSessionStartedAt: () => sessionStartedAt,
|
|
834
|
+
getModeId: () => opts.modeId ?? "default",
|
|
835
|
+
send
|
|
836
|
+
};
|
|
837
|
+
const skillsProjectRoot = opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "";
|
|
838
|
+
const skillsPaths = skillsProjectRoot ? resolveWstackPaths3({
|
|
839
|
+
projectRoot: skillsProjectRoot,
|
|
840
|
+
globalRoot
|
|
841
|
+
}) : void 0;
|
|
842
|
+
const skillsCtx = {
|
|
843
|
+
skillLoader: opts.skillLoader,
|
|
844
|
+
skillInstaller: opts.skillLoader ? new SkillInstaller({
|
|
845
|
+
manifestPath: path5.join(skillsPaths?.configDir ?? profileDir, "installed-skills.json"),
|
|
846
|
+
projectSkillsDir: skillsPaths?.inProjectSkills ?? path5.join(skillsProjectRoot, ".wrongstack", "skills"),
|
|
847
|
+
globalSkillsDir: skillsPaths?.globalSkills ?? path5.join(profileDir, "skills"),
|
|
848
|
+
projectHash: skillsPaths?.projectHash ?? "",
|
|
849
|
+
skillLoader: opts.skillLoader
|
|
850
|
+
}) : void 0,
|
|
851
|
+
projectRoot: skillsProjectRoot,
|
|
852
|
+
projectSkillsDir: skillsPaths?.inProjectSkills,
|
|
853
|
+
globalSkillsDir: skillsPaths?.globalSkills
|
|
854
|
+
};
|
|
855
|
+
const promptsCtx = {
|
|
856
|
+
promptLoader: opts.promptLoader,
|
|
857
|
+
promptUsage: new PromptUsageStore(
|
|
858
|
+
skillsPaths?.promptUsage ?? path5.join(profileDir, "prompt-usage.json")
|
|
859
|
+
)
|
|
860
|
+
};
|
|
861
|
+
const designCtx = {
|
|
862
|
+
projectRoot: skillsProjectRoot,
|
|
863
|
+
agentMeta: opts.agent.ctx
|
|
864
|
+
};
|
|
865
|
+
const agentConfigCtx = {
|
|
866
|
+
agent: opts.agent,
|
|
867
|
+
modeStore: opts.modeStore,
|
|
868
|
+
loadSavedProviders: () => loadSavedProviders(profileConfigPath),
|
|
869
|
+
buildSessionStart: (overrides) => buildSessionStartPayload(overrides),
|
|
870
|
+
modelsRegistry: opts.modelsRegistry,
|
|
871
|
+
memoryStore: opts.memoryStore,
|
|
872
|
+
getConfig: () => opts.appConfig,
|
|
873
|
+
onMaxContextResolved: opts.onModelContextResolved,
|
|
874
|
+
persistPrefs,
|
|
875
|
+
send,
|
|
876
|
+
broadcast,
|
|
877
|
+
log: (m) => console.log(m)
|
|
878
|
+
};
|
|
879
|
+
const prefsCtx = {
|
|
880
|
+
meta: opts.agent.ctx.meta,
|
|
881
|
+
snapshot: prefSnapshot,
|
|
882
|
+
persist: persistPrefs,
|
|
883
|
+
setYolo: opts.onYoloSwitch,
|
|
884
|
+
setAutonomy: opts.onAutonomySwitch,
|
|
885
|
+
pendingConfirms,
|
|
886
|
+
configStore: opts.agent.container?.safeResolve?.(TOKENS2.ConfigStore),
|
|
887
|
+
send,
|
|
888
|
+
broadcast
|
|
889
|
+
};
|
|
890
|
+
const projectsCtx = {
|
|
891
|
+
opts,
|
|
892
|
+
abortControllers,
|
|
893
|
+
abortLegacyRun: () => {
|
|
894
|
+
const controller = getAbortController();
|
|
895
|
+
if (controller) {
|
|
896
|
+
controller.abort();
|
|
897
|
+
clearAbortController();
|
|
898
|
+
}
|
|
899
|
+
},
|
|
900
|
+
buildSessionStart: (overrides) => buildSessionStartPayload(overrides),
|
|
901
|
+
send,
|
|
902
|
+
broadcast,
|
|
903
|
+
log: (m) => console.log(m)
|
|
904
|
+
};
|
|
905
|
+
const mailboxRoutes = createMailboxRouteHandlers({
|
|
906
|
+
getProjectRoot: () => opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "",
|
|
907
|
+
getGlobalRoot: () => opts.globalConfigPath ? path5.dirname(opts.globalConfigPath) : "",
|
|
908
|
+
events: opts.events
|
|
909
|
+
});
|
|
910
|
+
const sessionsCtx = {
|
|
911
|
+
opts,
|
|
912
|
+
buildSessionStart: (overrides) => buildSessionStartPayload(overrides),
|
|
913
|
+
getCustomModeStore,
|
|
914
|
+
send,
|
|
915
|
+
broadcast,
|
|
916
|
+
log: (m) => console.log(m)
|
|
917
|
+
};
|
|
918
|
+
const connectionCtx = {
|
|
919
|
+
agent: opts.agent,
|
|
920
|
+
abortControllers,
|
|
921
|
+
pendingConfirms,
|
|
922
|
+
send,
|
|
923
|
+
broadcast,
|
|
924
|
+
log: (m) => console.log(m)
|
|
582
925
|
};
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// src/webui-server/provider-config.ts
|
|
586
|
-
import * as path3 from "node:path";
|
|
587
|
-
import { DefaultSecretVault as DefaultSecretVault2 } from "@wrongstack/core/security";
|
|
588
|
-
function getVault(globalConfigPath) {
|
|
589
|
-
const configDir = path3.dirname(globalConfigPath ?? "");
|
|
590
|
-
const parentDir = path3.dirname(configDir);
|
|
591
|
-
const globalRoot = path3.basename(parentDir) === "profiles" ? path3.dirname(parentDir) : configDir;
|
|
592
|
-
const keyFile = path3.join(globalRoot, ".key");
|
|
593
|
-
return new DefaultSecretVault2({ keyFile });
|
|
594
|
-
}
|
|
595
|
-
async function loadSavedProviders(globalConfigPath) {
|
|
596
|
-
if (!globalConfigPath) return {};
|
|
597
|
-
return loadConfigProviders(globalConfigPath, getVault(globalConfigPath));
|
|
598
|
-
}
|
|
599
|
-
async function saveProviders(globalConfigPath, providers) {
|
|
600
|
-
if (!globalConfigPath) return;
|
|
601
|
-
await mutateConfigProviders(
|
|
602
|
-
globalConfigPath,
|
|
603
|
-
getVault(globalConfigPath),
|
|
604
|
-
(existing) => {
|
|
605
|
-
for (const key of Object.keys(existing)) delete existing[key];
|
|
606
|
-
Object.assign(existing, providers);
|
|
607
|
-
}
|
|
608
|
-
);
|
|
609
|
-
}
|
|
610
|
-
function createProviderConfigStore(globalConfigPath, configProvidersRef) {
|
|
611
926
|
return {
|
|
612
|
-
|
|
613
|
-
|
|
927
|
+
brainCtx,
|
|
928
|
+
introspectionCtx,
|
|
929
|
+
skillsCtx,
|
|
930
|
+
promptsCtx,
|
|
931
|
+
designCtx,
|
|
932
|
+
agentConfigCtx,
|
|
933
|
+
prefsCtx,
|
|
934
|
+
projectsCtx,
|
|
935
|
+
mailboxRoutes,
|
|
936
|
+
sessionsCtx,
|
|
937
|
+
connectionCtx
|
|
614
938
|
};
|
|
615
939
|
}
|
|
616
940
|
|
|
617
941
|
// src/webui-server/session-start-payload.ts
|
|
618
|
-
import * as
|
|
942
|
+
import * as path6 from "node:path";
|
|
619
943
|
import { DEFAULT_CONTEXT_WINDOW_MODE_ID } from "@wrongstack/core/types";
|
|
620
944
|
import { protocolAdvertisement } from "@wrongstack/webui-server/protocol";
|
|
621
945
|
|
|
@@ -656,7 +980,7 @@ function createSessionStartPayloadBuilder(deps) {
|
|
|
656
980
|
model: deps.agent.ctx.model,
|
|
657
981
|
provider: deps.agent.ctx.provider.id,
|
|
658
982
|
mode: deps.modeId ?? "default",
|
|
659
|
-
projectName: deps.projectRoot ?
|
|
983
|
+
projectName: deps.projectRoot ? path6.basename(deps.projectRoot) : void 0,
|
|
660
984
|
// Frontend reads `projectRoot` from session.start (ws-handlers setEnv) —
|
|
661
985
|
// omitting it left the store's projectRoot empty after a project switch.
|
|
662
986
|
projectRoot: deps.projectRoot ?? deps.agent.ctx.projectRoot ?? "",
|
|
@@ -889,15 +1213,15 @@ async function runWebUI(opts) {
|
|
|
889
1213
|
httpPort = await findFreePort(host, requestedHttpPort);
|
|
890
1214
|
}
|
|
891
1215
|
const wsPort = httpPort;
|
|
892
|
-
const globalRoot = opts.globalConfigPath ?
|
|
893
|
-
const profileConfigPath = opts.profileConfigPath ?? opts.globalConfigPath ??
|
|
1216
|
+
const globalRoot = opts.globalConfigPath ? path7.dirname(opts.globalConfigPath) : wstackGlobalRoot();
|
|
1217
|
+
const profileConfigPath = opts.profileConfigPath ?? opts.globalConfigPath ?? path7.join(globalRoot, "config.json");
|
|
894
1218
|
const rateLimitMax = Number.parseInt(process.env["WEBUI_RATE_LIMIT"] ?? "600", 10);
|
|
895
1219
|
const clients = /* @__PURE__ */ new Map();
|
|
896
1220
|
const pendingConfirms = /* @__PURE__ */ new Map();
|
|
897
1221
|
const secretScrubber = new DefaultSecretScrubber();
|
|
898
1222
|
let abortController = null;
|
|
899
1223
|
const abortControllers = /* @__PURE__ */ new Map();
|
|
900
|
-
const profileDir =
|
|
1224
|
+
const profileDir = path7.dirname(profileConfigPath);
|
|
901
1225
|
let customModeStoreP = null;
|
|
902
1226
|
const getCustomModeStore = () => {
|
|
903
1227
|
customModeStoreP ??= (async () => {
|
|
@@ -907,7 +1231,6 @@ async function runWebUI(opts) {
|
|
|
907
1231
|
})();
|
|
908
1232
|
return customModeStoreP;
|
|
909
1233
|
};
|
|
910
|
-
const goalStoreDir = opts.projectRoot ? path5.join(opts.projectRoot, ".wrongstack", "goal") : path5.join(os.tmpdir(), ".wrongstack", "goal");
|
|
911
1234
|
const kanbanRunMirror = opts.projectRoot ? createKanbanRunMirror({
|
|
912
1235
|
projectRoot: opts.projectRoot,
|
|
913
1236
|
events: opts.events,
|
|
@@ -931,61 +1254,14 @@ async function runWebUI(opts) {
|
|
|
931
1254
|
};
|
|
932
1255
|
}
|
|
933
1256
|
}) : void 0;
|
|
934
|
-
const
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
);
|
|
943
|
-
const worktreeHandler = new WorktreeWebSocketHandler(opts.events, consoleLogger);
|
|
944
|
-
const loadNodePtyViaWebui = createNodePtyLoader(import.meta.url, consoleLogger);
|
|
945
|
-
const terminalHandler = new TerminalWebSocketHandler(
|
|
946
|
-
() => opts.agent.ctx.cwd ?? opts.projectRoot ?? process.cwd(),
|
|
947
|
-
consoleLogger,
|
|
948
|
-
loadNodePtyViaWebui,
|
|
949
|
-
void 0,
|
|
950
|
-
trustBoundary
|
|
951
|
-
);
|
|
952
|
-
const specsPaths = opts.projectRoot ? resolveWstackPaths2({ projectRoot: opts.projectRoot }) : null;
|
|
953
|
-
const specsHandler = new SpecsWebSocketHandler(
|
|
954
|
-
specsPaths?.projectSpecs ?? path5.join(os.tmpdir(), ".wrongstack", "specs"),
|
|
955
|
-
specsPaths?.projectTaskGraphs ?? path5.join(os.tmpdir(), ".wrongstack", "task-graphs")
|
|
956
|
-
);
|
|
957
|
-
const sddBoardHandler = new SddBoardWebSocketHandler(
|
|
958
|
-
specsPaths?.projectSddBoards ?? path5.join(os.tmpdir(), ".wrongstack", "sdd-boards"),
|
|
959
|
-
opts.events,
|
|
960
|
-
specsPaths && opts.projectRoot ? {
|
|
961
|
-
projectRoot: opts.projectRoot,
|
|
962
|
-
paths: {
|
|
963
|
-
projectSpecs: specsPaths.projectSpecs,
|
|
964
|
-
projectTaskGraphs: specsPaths.projectTaskGraphs,
|
|
965
|
-
projectSddSession: specsPaths.projectSddSession,
|
|
966
|
-
projectSddBoards: specsPaths.projectSddBoards
|
|
967
|
-
}
|
|
968
|
-
} : void 0,
|
|
969
|
-
{ trustBoundary, logger: consoleLogger }
|
|
970
|
-
);
|
|
971
|
-
const sddWizardHandler = opts.sddSubagentFactory && specsPaths ? new SddWizardWebSocketHandler(
|
|
972
|
-
buildSddWizardDeps({
|
|
973
|
-
agent: opts.agent,
|
|
974
|
-
events: opts.events,
|
|
975
|
-
projectRoot: opts.projectRoot ?? process.cwd(),
|
|
976
|
-
subagentFactory: opts.sddSubagentFactory,
|
|
977
|
-
// Failure supervisor parity with /sdd execute — omit only when
|
|
978
|
-
// the host never bound a BrainArbiter.
|
|
979
|
-
...opts.brain ? { brain: opts.brain } : {},
|
|
980
|
-
paths: {
|
|
981
|
-
projectSpecs: specsPaths.projectSpecs,
|
|
982
|
-
projectTaskGraphs: specsPaths.projectTaskGraphs,
|
|
983
|
-
projectSddBoards: specsPaths.projectSddBoards,
|
|
984
|
-
projectDir: specsPaths.projectDir,
|
|
985
|
-
projectSddSession: specsPaths.projectSddSession
|
|
986
|
-
}
|
|
987
|
-
})
|
|
988
|
-
) : null;
|
|
1257
|
+
const {
|
|
1258
|
+
goalHandler,
|
|
1259
|
+
worktreeHandler,
|
|
1260
|
+
terminalHandler,
|
|
1261
|
+
specsHandler,
|
|
1262
|
+
sddBoardHandler,
|
|
1263
|
+
sddWizardHandler
|
|
1264
|
+
} = createWebuiDomainHandlers(opts, trustBoundary, kanbanRunMirror);
|
|
989
1265
|
await seedConfigToMeta(opts);
|
|
990
1266
|
if (typeof opts.agent.ctx?.meta?.["yolo"] === "boolean") {
|
|
991
1267
|
opts.onYoloSwitch?.(opts.agent.ctx.meta["yolo"]);
|
|
@@ -999,11 +1275,6 @@ async function runWebUI(opts) {
|
|
|
999
1275
|
events: opts.events,
|
|
1000
1276
|
hqSessionId: opts.session.id,
|
|
1001
1277
|
getSessionId: () => opts.agent.ctx.session?.id ?? opts.session.id,
|
|
1002
|
-
// Two-way HQ control for the WebUI client: steer/btw/queue/broadcast
|
|
1003
|
-
// land in the project mailbox (the WebUI's agent reads it like any
|
|
1004
|
-
// other surface), and abort tears down every in-flight run on this
|
|
1005
|
-
// instance. Without this block the WebUI would be HQ-invisible to the
|
|
1006
|
-
// Control tab — telemetry only.
|
|
1007
1278
|
hqControl: {
|
|
1008
1279
|
interruptLeader: () => {
|
|
1009
1280
|
let aborted = false;
|
|
@@ -1055,16 +1326,11 @@ async function runWebUI(opts) {
|
|
|
1055
1326
|
void fleetBroadcastCli?.();
|
|
1056
1327
|
},
|
|
1057
1328
|
onTechStackEvent: (event) => broadcast(event),
|
|
1058
|
-
// Read through the live agent context so a mid-session model switch or a
|
|
1059
|
-
// credential hot-reload takes effect on the next analyze.
|
|
1060
1329
|
getLlm: () => opts.agent.ctx.provider && opts.agent.ctx.model ? { provider: opts.agent.ctx.provider, model: opts.agent.ctx.model } : void 0,
|
|
1061
1330
|
projectRoot: opts.projectRoot,
|
|
1062
1331
|
publicWsUrl,
|
|
1063
1332
|
apiToken: wsToken,
|
|
1064
1333
|
requireToken,
|
|
1065
|
-
// SimpleUI only: defer listen until after the WebSocketServer is
|
|
1066
|
-
// attached, so a WS upgrade request cannot arrive between listen()
|
|
1067
|
-
// and the WS handler registration.
|
|
1068
1334
|
deferListen: surface === "simpleui"
|
|
1069
1335
|
});
|
|
1070
1336
|
const wss = httpServer ? new WebSocketServer({ server: httpServer.server, maxPayload: 20 * 1024 * 1024 }) : new WebSocketServer({ port: httpPort, host, maxPayload: 20 * 1024 * 1024 });
|
|
@@ -1114,8 +1380,6 @@ async function runWebUI(opts) {
|
|
|
1114
1380
|
projectRoot: opts.projectRoot,
|
|
1115
1381
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1116
1382
|
registryBaseDir,
|
|
1117
|
-
// Lets a same-project TUI/REPL authenticate `POST /api/fleet/ping` now
|
|
1118
|
-
// that the API requires a token on every bind (H3).
|
|
1119
1383
|
authToken: wsToken,
|
|
1120
1384
|
...opts.webuiSessionChild ? {
|
|
1121
1385
|
role: "session-child",
|
|
@@ -1169,7 +1433,7 @@ async function runWebUI(opts) {
|
|
|
1169
1433
|
secretScrubber,
|
|
1170
1434
|
getClients: () => clients,
|
|
1171
1435
|
eventUnsubscribers,
|
|
1172
|
-
globalConfigPath:
|
|
1436
|
+
globalConfigPath: path7.join(globalRoot, "config.json"),
|
|
1173
1437
|
onFleetBroadcaster: (fn) => {
|
|
1174
1438
|
fleetBroadcastCli = fn;
|
|
1175
1439
|
},
|
|
@@ -1178,11 +1442,6 @@ async function runWebUI(opts) {
|
|
|
1178
1442
|
const wsHandlerCtx = {
|
|
1179
1443
|
providerStore: createProviderConfigStore(
|
|
1180
1444
|
profileConfigPath,
|
|
1181
|
-
// Use the in-memory merged config providers so the WebUI sees the
|
|
1182
|
-
// same provider list the agent uses. Without this, providers stored
|
|
1183
|
-
// only in the project-local config (config.local.json) would be
|
|
1184
|
-
// invisible to the WebUI's saved-providers panel because the store
|
|
1185
|
-
// reads exclusively from the global config file.
|
|
1186
1445
|
() => opts.appConfig?.providers ?? {}
|
|
1187
1446
|
),
|
|
1188
1447
|
modelsRegistry: opts.modelsRegistry,
|
|
@@ -1191,207 +1450,32 @@ async function runWebUI(opts) {
|
|
|
1191
1450
|
log: (m) => console.log(m)
|
|
1192
1451
|
};
|
|
1193
1452
|
const embeddedProviderOperations = createEmbeddedProviderOperations(wsHandlerCtx);
|
|
1194
|
-
|
|
1195
|
-
let credentialWatcherClose;
|
|
1196
|
-
if (watchConfigPath && process.env["WRONGSTACK_DISABLE_CONFIG_WATCH"] !== "1") {
|
|
1197
|
-
let lastActiveCfg = JSON.stringify(
|
|
1198
|
-
opts.appConfig?.providers?.[opts.agent.ctx.provider.id] ?? null
|
|
1199
|
-
);
|
|
1200
|
-
let lastUiLocale = opts.appConfig?.uiLocale;
|
|
1201
|
-
const watcher = watchProviderConfig(
|
|
1202
|
-
watchConfigPath,
|
|
1203
|
-
// Vault key lives at ~/.wrongstack/.key (derived from globalConfigPath),
|
|
1204
|
-
// not inside the profile directory — resolve via global root to stay correct.
|
|
1205
|
-
getVault(opts.globalConfigPath),
|
|
1206
|
-
(snapshot) => {
|
|
1207
|
-
const hadFallbackBridge = Boolean(opts.appConfig?.fallbackBridge?.trim());
|
|
1208
|
-
try {
|
|
1209
|
-
if (opts.appConfig && !Object.isFrozen(opts.appConfig)) {
|
|
1210
|
-
opts.appConfig.providers = snapshot.providers;
|
|
1211
|
-
if (snapshot.uiLocale) opts.appConfig.uiLocale = snapshot.uiLocale;
|
|
1212
|
-
if (snapshot.fallbackBridge !== void 0) {
|
|
1213
|
-
opts.appConfig.fallbackBridge = snapshot.fallbackBridge;
|
|
1214
|
-
} else {
|
|
1215
|
-
delete opts.appConfig.fallbackBridge;
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
} catch {
|
|
1219
|
-
}
|
|
1220
|
-
const routingChanged = snapshot.fallbackModels !== void 0 || snapshot.fallbackBridge !== void 0 || hadFallbackBridge || snapshot.fallbackProfiles !== void 0 || snapshot.favoriteModels !== void 0 || snapshot.favoriteModelsOnly !== void 0 || snapshot.modelMatrix !== void 0 || snapshot.fallbackAuto !== void 0;
|
|
1221
|
-
if (routingChanged) {
|
|
1222
|
-
const configStore = opts.agent.container?.safeResolve?.(TOKENS.ConfigStore);
|
|
1223
|
-
configStore?.update({
|
|
1224
|
-
...snapshot.fallbackModels !== void 0 ? { fallbackModels: snapshot.fallbackModels } : {},
|
|
1225
|
-
fallbackBridge: snapshot.fallbackBridge ?? "",
|
|
1226
|
-
...snapshot.fallbackProfiles !== void 0 ? { fallbackProfiles: snapshot.fallbackProfiles } : {},
|
|
1227
|
-
...snapshot.favoriteModels !== void 0 ? { favoriteModels: snapshot.favoriteModels } : {},
|
|
1228
|
-
...snapshot.favoriteModelsOnly !== void 0 ? { favoriteModelsOnly: snapshot.favoriteModelsOnly } : {},
|
|
1229
|
-
...snapshot.modelMatrix !== void 0 ? { modelMatrix: snapshot.modelMatrix } : {},
|
|
1230
|
-
...snapshot.fallbackAuto !== void 0 ? { fallbackAuto: snapshot.fallbackAuto } : {}
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
embeddedProviderOperations.broadcastSaved(snapshot.providers);
|
|
1234
|
-
if (snapshot.uiLocale !== lastUiLocale) {
|
|
1235
|
-
lastUiLocale = snapshot.uiLocale;
|
|
1236
|
-
if (snapshot.uiLocale) {
|
|
1237
|
-
opts.agent.ctx.meta["uiLocale"] = snapshot.uiLocale;
|
|
1238
|
-
broadcast({ type: "prefs.updated", payload: { uiLocale: snapshot.uiLocale } });
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
const activeId = opts.agent.ctx.provider.id;
|
|
1242
|
-
const newCfgStr = JSON.stringify(snapshot.providers[activeId] ?? null);
|
|
1243
|
-
if (newCfgStr === lastActiveCfg) return;
|
|
1244
|
-
lastActiveCfg = newCfgStr;
|
|
1245
|
-
try {
|
|
1246
|
-
const newCfg = snapshot.providers[activeId] ?? {
|
|
1247
|
-
type: activeId,
|
|
1248
|
-
...snapshot.apiKey !== void 0 ? { apiKey: snapshot.apiKey } : {},
|
|
1249
|
-
...snapshot.baseUrl !== void 0 ? { baseUrl: snapshot.baseUrl } : {}
|
|
1250
|
-
};
|
|
1251
|
-
const oldMax = opts.agent.ctx.provider.capabilities?.maxContext;
|
|
1252
|
-
const prov = makeProviderFromConfig(activeId, {
|
|
1253
|
-
...newCfg,
|
|
1254
|
-
type: newCfg.type ?? activeId
|
|
1255
|
-
});
|
|
1256
|
-
if (oldMax != null && prov.capabilities) prov.capabilities.maxContext = oldMax;
|
|
1257
|
-
opts.agent.ctx.provider = prov;
|
|
1258
|
-
console.log(`[WebUI] Provider credentials reloaded from config.json (${activeId})`);
|
|
1259
|
-
} catch (err) {
|
|
1260
|
-
console.warn(
|
|
1261
|
-
`[WebUI] Credential hot-reload failed for ${activeId}: ${toErrorMessage(err)}`
|
|
1262
|
-
);
|
|
1263
|
-
}
|
|
1264
|
-
},
|
|
1265
|
-
{
|
|
1266
|
-
warn: (m) => console.warn(
|
|
1267
|
-
JSON.stringify({
|
|
1268
|
-
level: "warn",
|
|
1269
|
-
event: "webui.config_watcher",
|
|
1270
|
-
message: m,
|
|
1271
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1272
|
-
})
|
|
1273
|
-
)
|
|
1274
|
-
}
|
|
1275
|
-
);
|
|
1276
|
-
credentialWatcherClose = watcher.close;
|
|
1277
|
-
}
|
|
1278
|
-
const brainCtx = {
|
|
1279
|
-
brainSettings: opts.brainSettings,
|
|
1280
|
-
brainRuntime: opts.brainRuntime,
|
|
1281
|
-
getBrainLog: opts.getBrainLog,
|
|
1282
|
-
// Prefer the host-supplied arbiter; otherwise resolve the one bound
|
|
1283
|
-
// in the agent container (if any). Mirrors the former inline lookup.
|
|
1284
|
-
resolveArbiter: () => opts.brain ?? (opts.agent.container.has(TOKENS.BrainArbiter) ? opts.agent.container.resolve(TOKENS.BrainArbiter) : void 0),
|
|
1285
|
-
getSessionId: currentSessionId,
|
|
1286
|
-
send
|
|
1287
|
-
};
|
|
1288
|
-
const introspectionConfigStore = opts.agent.container?.safeResolve?.(TOKENS.ConfigStore);
|
|
1289
|
-
const introspectionCtx = {
|
|
1290
|
-
agent: opts.agent,
|
|
1291
|
-
modelsRegistry: opts.modelsRegistry,
|
|
1292
|
-
configStore: introspectionConfigStore,
|
|
1293
|
-
getConfig: () => {
|
|
1294
|
-
const cfg = introspectionConfigStore?.get() ?? opts.appConfig;
|
|
1295
|
-
if (!cfg)
|
|
1296
|
-
throw new Error(
|
|
1297
|
-
"Introspection route requires a config but neither ConfigStore nor opts.appConfig is available"
|
|
1298
|
-
);
|
|
1299
|
-
return cfg;
|
|
1300
|
-
},
|
|
1301
|
-
getProjectRoot: () => opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "",
|
|
1302
|
-
getSessionId: currentSessionId,
|
|
1303
|
-
getSessionStartedAt: () => sessionStartedAt,
|
|
1304
|
-
getModeId: () => opts.modeId ?? "default",
|
|
1305
|
-
send
|
|
1306
|
-
};
|
|
1307
|
-
const skillsProjectRoot = opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "";
|
|
1308
|
-
const skillsPaths = skillsProjectRoot ? resolveWstackPaths2({
|
|
1309
|
-
projectRoot: skillsProjectRoot,
|
|
1310
|
-
globalRoot
|
|
1311
|
-
}) : void 0;
|
|
1312
|
-
const skillsCtx = {
|
|
1313
|
-
skillLoader: opts.skillLoader,
|
|
1314
|
-
skillInstaller: opts.skillLoader ? new SkillInstaller({
|
|
1315
|
-
manifestPath: path5.join(skillsPaths?.configDir ?? profileDir, "installed-skills.json"),
|
|
1316
|
-
projectSkillsDir: skillsPaths?.inProjectSkills ?? path5.join(skillsProjectRoot, ".wrongstack", "skills"),
|
|
1317
|
-
globalSkillsDir: skillsPaths?.globalSkills ?? path5.join(profileDir, "skills"),
|
|
1318
|
-
projectHash: skillsPaths?.projectHash ?? "",
|
|
1319
|
-
skillLoader: opts.skillLoader
|
|
1320
|
-
}) : void 0,
|
|
1321
|
-
projectRoot: skillsProjectRoot,
|
|
1322
|
-
projectSkillsDir: skillsPaths?.inProjectSkills,
|
|
1323
|
-
globalSkillsDir: skillsPaths?.globalSkills
|
|
1324
|
-
};
|
|
1325
|
-
const promptsCtx = {
|
|
1326
|
-
promptLoader: opts.promptLoader,
|
|
1327
|
-
promptUsage: new PromptUsageStore(
|
|
1328
|
-
skillsPaths?.promptUsage ?? path5.join(profileDir, "prompt-usage.json")
|
|
1329
|
-
)
|
|
1330
|
-
};
|
|
1331
|
-
const designCtx = {
|
|
1332
|
-
projectRoot: skillsProjectRoot,
|
|
1333
|
-
agentMeta: opts.agent.ctx
|
|
1334
|
-
};
|
|
1335
|
-
const agentConfigCtx = {
|
|
1336
|
-
agent: opts.agent,
|
|
1337
|
-
modeStore: opts.modeStore,
|
|
1338
|
-
loadSavedProviders: () => loadSavedProviders(profileConfigPath),
|
|
1339
|
-
buildSessionStart: (overrides) => buildSessionStartPayload(overrides),
|
|
1340
|
-
modelsRegistry: opts.modelsRegistry,
|
|
1341
|
-
memoryStore: opts.memoryStore,
|
|
1342
|
-
getConfig: () => opts.appConfig,
|
|
1343
|
-
onMaxContextResolved: opts.onModelContextResolved,
|
|
1344
|
-
persistPrefs,
|
|
1345
|
-
send,
|
|
1346
|
-
broadcast,
|
|
1347
|
-
log: (m) => console.log(m)
|
|
1348
|
-
};
|
|
1349
|
-
const prefsCtx = {
|
|
1350
|
-
meta: opts.agent.ctx.meta,
|
|
1351
|
-
snapshot: prefSnapshot,
|
|
1352
|
-
persist: persistPrefs,
|
|
1353
|
-
setYolo: opts.onYoloSwitch,
|
|
1354
|
-
setAutonomy: opts.onAutonomySwitch,
|
|
1355
|
-
pendingConfirms,
|
|
1356
|
-
configStore: opts.agent.container?.safeResolve?.(TOKENS.ConfigStore),
|
|
1357
|
-
send,
|
|
1358
|
-
broadcast
|
|
1359
|
-
};
|
|
1360
|
-
const projectsCtx = {
|
|
1453
|
+
let credentialWatcherClose = startWebuiCredentialWatcher({
|
|
1361
1454
|
opts,
|
|
1362
|
-
|
|
1363
|
-
abortLegacyRun: () => {
|
|
1364
|
-
if (abortController) {
|
|
1365
|
-
abortController.abort();
|
|
1366
|
-
abortController = null;
|
|
1367
|
-
}
|
|
1368
|
-
},
|
|
1369
|
-
buildSessionStart: (overrides) => buildSessionStartPayload(overrides),
|
|
1370
|
-
send,
|
|
1455
|
+
profileConfigPath,
|
|
1371
1456
|
broadcast,
|
|
1372
|
-
|
|
1373
|
-
};
|
|
1374
|
-
const mailboxRoutes = createMailboxRouteHandlers({
|
|
1375
|
-
getProjectRoot: () => opts.projectRoot ?? opts.agent.ctx.projectRoot ?? "",
|
|
1376
|
-
getGlobalRoot: () => opts.globalConfigPath ? path5.dirname(opts.globalConfigPath) : "",
|
|
1377
|
-
events: opts.events
|
|
1457
|
+
broadcastSaved: (providers) => embeddedProviderOperations.broadcastSaved(providers)
|
|
1378
1458
|
});
|
|
1379
|
-
const
|
|
1459
|
+
const routeContexts = createWebuiRouteContexts({
|
|
1380
1460
|
opts,
|
|
1381
|
-
|
|
1461
|
+
profileConfigPath,
|
|
1462
|
+
profileDir,
|
|
1463
|
+
globalRoot,
|
|
1464
|
+
sessionStartedAt,
|
|
1465
|
+
currentSessionId,
|
|
1382
1466
|
getCustomModeStore,
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
};
|
|
1387
|
-
const connectionCtx = {
|
|
1388
|
-
agent: opts.agent,
|
|
1389
|
-
abortControllers,
|
|
1467
|
+
buildSessionStartPayload,
|
|
1468
|
+
prefSnapshot,
|
|
1469
|
+
persistPrefs,
|
|
1390
1470
|
pendingConfirms,
|
|
1471
|
+
abortControllers,
|
|
1472
|
+
getAbortController: () => abortController,
|
|
1473
|
+
clearAbortController: () => {
|
|
1474
|
+
abortController = null;
|
|
1475
|
+
},
|
|
1391
1476
|
send,
|
|
1392
|
-
broadcast
|
|
1393
|
-
|
|
1394
|
-
};
|
|
1477
|
+
broadcast
|
|
1478
|
+
});
|
|
1395
1479
|
const kanbanHostRoutes = createCliKanbanHostRoutes({
|
|
1396
1480
|
opts,
|
|
1397
1481
|
send,
|
|
@@ -1412,17 +1496,17 @@ async function runWebUI(opts) {
|
|
|
1412
1496
|
currentSessionId,
|
|
1413
1497
|
shutdown,
|
|
1414
1498
|
providerCtx: wsHandlerCtx,
|
|
1415
|
-
brainCtx,
|
|
1416
|
-
introspectionCtx,
|
|
1417
|
-
skillsCtx,
|
|
1418
|
-
promptsCtx,
|
|
1419
|
-
designCtx,
|
|
1420
|
-
agentConfigCtx,
|
|
1421
|
-
prefsCtx,
|
|
1422
|
-
projectCtx: projectsCtx,
|
|
1423
|
-
mailboxRoutes,
|
|
1424
|
-
sessionCtx: sessionsCtx,
|
|
1425
|
-
conversationCtx: connectionCtx,
|
|
1499
|
+
brainCtx: routeContexts.brainCtx,
|
|
1500
|
+
introspectionCtx: routeContexts.introspectionCtx,
|
|
1501
|
+
skillsCtx: routeContexts.skillsCtx,
|
|
1502
|
+
promptsCtx: routeContexts.promptsCtx,
|
|
1503
|
+
designCtx: routeContexts.designCtx,
|
|
1504
|
+
agentConfigCtx: routeContexts.agentConfigCtx,
|
|
1505
|
+
prefsCtx: routeContexts.prefsCtx,
|
|
1506
|
+
projectCtx: routeContexts.projectsCtx,
|
|
1507
|
+
mailboxRoutes: routeContexts.mailboxRoutes,
|
|
1508
|
+
sessionCtx: routeContexts.sessionsCtx,
|
|
1509
|
+
conversationCtx: routeContexts.connectionCtx,
|
|
1426
1510
|
goalHandler,
|
|
1427
1511
|
specsHandler,
|
|
1428
1512
|
sddBoardHandler,
|
|
@@ -1449,7 +1533,7 @@ async function runWebUI(opts) {
|
|
|
1449
1533
|
webuiInstanceRegistered
|
|
1450
1534
|
});
|
|
1451
1535
|
} catch (err) {
|
|
1452
|
-
consoleLogger.error("setup_events_failed", { message:
|
|
1536
|
+
consoleLogger.error("setup_events_failed", { message: toErrorMessage2(err) });
|
|
1453
1537
|
}
|
|
1454
1538
|
};
|
|
1455
1539
|
wss.on("listening", announceListening);
|
|
@@ -1487,9 +1571,6 @@ async function runWebUI(opts) {
|
|
|
1487
1571
|
const usage = opts.agent.ctx.tokenCounter.total();
|
|
1488
1572
|
return { messages: opts.agent.ctx.messages, usage };
|
|
1489
1573
|
},
|
|
1490
|
-
// Reads the on-disk transcripts when the in-memory ring is cold, which
|
|
1491
|
-
// it always is after a resume — the ring only holds what this process
|
|
1492
|
-
// watched happen.
|
|
1493
1574
|
loadAgentSessions: async () => await opts.agentTranscripts?.loadSessionsFromDisk() ?? [],
|
|
1494
1575
|
needsSetup: opts.needsSetup ?? false
|
|
1495
1576
|
})
|
|
@@ -1517,9 +1598,6 @@ async function runWebUI(opts) {
|
|
|
1517
1598
|
flushAllStreamBuffers();
|
|
1518
1599
|
for (const unsub of eventUnsubscribers) unsub();
|
|
1519
1600
|
},
|
|
1520
|
-
// Issue #322: kill session-owned children (MCP, bash/exec, tool-spawned
|
|
1521
|
-
// dev servers) before closing the listen socket so Windows process trees
|
|
1522
|
-
// do not outlive the parent and strand the event loop on open stdio.
|
|
1523
1601
|
stopOwnedChildren: async () => {
|
|
1524
1602
|
try {
|
|
1525
1603
|
const { getProcessRegistry } = await import("@wrongstack/tools");
|
|
@@ -1591,4 +1669,4 @@ async function runWebUI(opts) {
|
|
|
1591
1669
|
export {
|
|
1592
1670
|
runWebUI
|
|
1593
1671
|
};
|
|
1594
|
-
//# sourceMappingURL=webui-server-
|
|
1672
|
+
//# sourceMappingURL=webui-server-IPHGJGXE.js.map
|