@wrongstack/cli 0.296.4 → 0.297.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/boot/dispatch-webui.d.ts +7 -0
- package/dist/boot/dispatch-webui.d.ts.map +1 -1
- package/dist/boot/launch-banner.d.ts +22 -0
- package/dist/boot/launch-banner.d.ts.map +1 -0
- package/dist/boot/launch-menu.d.ts.map +1 -1
- package/dist/boot/tui-settings-adapter.d.ts.map +1 -1
- package/dist/{chunk-OI7GWJDS.js → chunk-7JABKXET.js} +372 -10
- package/dist/chunk-7JABKXET.js.map +7 -0
- package/dist/{chunk-WY7KKOUK.js → chunk-JW75HY4F.js} +31 -10
- package/dist/chunk-JW75HY4F.js.map +7 -0
- package/dist/{chunk-Z7YGASQP.js → chunk-QZKWRNIP.js} +19 -18
- package/dist/chunk-QZKWRNIP.js.map +7 -0
- package/dist/{chunk-BQCAJ7FI.js → chunk-XTIXVJXP.js} +16 -3
- package/dist/chunk-XTIXVJXP.js.map +7 -0
- package/dist/{cli-main-TOAWVJDY.js → cli-main-GOY5YGVL.js} +25199 -25107
- package/dist/cli-main-GOY5YGVL.js.map +7 -0
- package/dist/cli-main.d.ts.map +1 -1
- package/dist/{execution-O7I5DYE6.js → execution-A4PGK4XV.js} +39 -9
- package/dist/execution-A4PGK4XV.js.map +7 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/fleet-statusline.d.ts.map +1 -1
- package/dist/goal-host.d.ts +1 -1
- package/dist/goal-host.d.ts.map +1 -1
- package/dist/{hq-JUYKUNJX.js → hq-GBPGXIR5.js} +2 -2
- package/dist/hq-publisher.d.ts +3 -2
- package/dist/hq-publisher.d.ts.map +1 -1
- package/dist/hq-server/types.d.ts +8 -0
- package/dist/hq-server/types.d.ts.map +1 -1
- package/dist/hq-server/ws.d.ts +61 -2
- package/dist/hq-server/ws.d.ts.map +1 -1
- package/dist/{hq-server-6AQ3BXZA.js → hq-server-YQUUMTPU.js} +2 -2
- package/dist/index.js +293 -26
- package/dist/index.js.map +4 -4
- package/dist/kanban-hq-sync.d.ts +13 -1
- package/dist/kanban-hq-sync.d.ts.map +1 -1
- package/dist/live-settings-input.d.ts +9 -0
- package/dist/live-settings-input.d.ts.map +1 -1
- package/dist/{mailbox-serve-2UWHEN3M.js → mailbox-serve-DBOOOOWZ.js} +50 -8
- package/dist/mailbox-serve-DBOOOOWZ.js.map +7 -0
- package/dist/{sdd-runtime-JG4EEKL6.js → sdd-runtime-AIJCJGWC.js} +2 -2
- package/dist/services/sdd/state.d.ts +3 -3
- package/dist/services/sdd/state.d.ts.map +1 -1
- package/dist/services/sdd/task-manager.d.ts.map +1 -1
- package/dist/session-stats.d.ts.map +1 -1
- package/dist/settings-menu.d.ts.map +1 -1
- package/dist/slash-commands/command-context.d.ts +2 -0
- package/dist/slash-commands/command-context.d.ts.map +1 -1
- package/dist/slash-commands/goal.d.ts +1 -1
- package/dist/slash-commands/goal.d.ts.map +1 -1
- package/dist/slash-commands/sdd.d.ts.map +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts +1 -1
- package/dist/webui-server/kanban-host-adapter.d.ts.map +1 -1
- package/dist/webui-server/session-start-payload.d.ts +4 -0
- package/dist/webui-server/session-start-payload.d.ts.map +1 -1
- package/dist/{webui-server-ZF5KVGC5.js → webui-server-XKFUOKMJ.js} +155 -132
- package/dist/webui-server-XKFUOKMJ.js.map +7 -0
- package/dist/webui-server-options.d.ts +7 -0
- package/dist/webui-server-options.d.ts.map +1 -1
- package/dist/webui-server.d.ts.map +1 -1
- package/dist/wiring/command-host-state.d.ts.map +1 -1
- package/dist/wiring/hq-telemetry.d.ts +4 -3
- package/dist/wiring/hq-telemetry.d.ts.map +1 -1
- package/dist/wiring/lifecycle-plugins.d.ts +5 -8
- package/dist/wiring/lifecycle-plugins.d.ts.map +1 -1
- package/dist/wiring/metrics.d.ts +1 -1
- package/dist/wiring/metrics.d.ts.map +1 -1
- package/dist/wiring/runtime-lifecycle-deps.d.ts.map +1 -1
- package/dist/wiring/sage.d.ts.map +1 -1
- package/dist/wiring/sdd-handlers.d.ts.map +1 -1
- package/package.json +22 -22
- package/dist/chunk-BQCAJ7FI.js.map +0 -7
- package/dist/chunk-OI7GWJDS.js.map +0 -7
- package/dist/chunk-WY7KKOUK.js.map +0 -7
- package/dist/chunk-Z7YGASQP.js.map +0 -7
- package/dist/cli-main-TOAWVJDY.js.map +0 -7
- package/dist/execution-O7I5DYE6.js.map +0 -7
- package/dist/mailbox-serve-2UWHEN3M.js.map +0 -7
- package/dist/webui-server-ZF5KVGC5.js.map +0 -7
- /package/dist/{hq-JUYKUNJX.js.map → hq-GBPGXIR5.js.map} +0 -0
- /package/dist/{hq-server-6AQ3BXZA.js.map → hq-server-YQUUMTPU.js.map} +0 -0
- /package/dist/{sdd-runtime-JG4EEKL6.js.map → sdd-runtime-AIJCJGWC.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-OP47B3IX.js";
|
|
7
7
|
import {
|
|
8
8
|
startCliHqConnection
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-JW75HY4F.js";
|
|
10
10
|
import {
|
|
11
11
|
loadConfigProviders,
|
|
12
12
|
mutateConfigProviders
|
|
@@ -17,12 +17,15 @@ import "./chunk-7OCVIDC7.js";
|
|
|
17
17
|
import { findPackageJSON } from "node:module";
|
|
18
18
|
import * as os from "node:os";
|
|
19
19
|
import * as path5 from "node:path";
|
|
20
|
-
import { DefaultSecretScrubber } from "@wrongstack/core/security";
|
|
21
|
-
import { PromptUsageStore, watchProviderConfig } from "@wrongstack/core/storage";
|
|
22
|
-
import { resolveWstackPaths as resolveWstackPaths2, wstackGlobalRoot } from "@wrongstack/core/utils";
|
|
23
20
|
import { TOKENS } from "@wrongstack/core/kernel";
|
|
24
|
-
import { createCompatibilityTrustBoundary } from "@wrongstack/core/security";
|
|
21
|
+
import { createCompatibilityTrustBoundary, DefaultSecretScrubber } from "@wrongstack/core/security";
|
|
25
22
|
import { SkillInstaller } from "@wrongstack/core/skills";
|
|
23
|
+
import { PromptUsageStore, watchProviderConfig } from "@wrongstack/core/storage";
|
|
24
|
+
import {
|
|
25
|
+
resolveWstackPaths as resolveWstackPaths2,
|
|
26
|
+
startSharedHeapWatchdog,
|
|
27
|
+
wstackGlobalRoot
|
|
28
|
+
} from "@wrongstack/core/utils";
|
|
26
29
|
import { toErrorMessage } from "@wrongstack/core/utils/error";
|
|
27
30
|
import { makeProviderFromConfig } from "@wrongstack/providers";
|
|
28
31
|
import {
|
|
@@ -172,6 +175,7 @@ function createConnectionHandler(deps) {
|
|
|
172
175
|
import { PhaseGraphBuilder } from "@wrongstack/core/goal";
|
|
173
176
|
import { resolveWstackPaths } from "@wrongstack/core/utils";
|
|
174
177
|
import { exportBoardToTaskGraph } from "@wrongstack/kanban";
|
|
178
|
+
import { TaskGraphStore } from "@wrongstack/sdd";
|
|
175
179
|
import {
|
|
176
180
|
startSddRunFromGraph
|
|
177
181
|
} from "@wrongstack/webui-server";
|
|
@@ -301,6 +305,8 @@ function createCliKanbanHostRoutes(deps) {
|
|
|
301
305
|
return failRun("SDD runs need the multi-agent host, which is not available here.");
|
|
302
306
|
}
|
|
303
307
|
const paths = resolveWstackPaths({ projectRoot });
|
|
308
|
+
const taskStore = new TaskGraphStore({ baseDir: paths.projectTaskGraphs });
|
|
309
|
+
await taskStore.save(exported.graph);
|
|
304
310
|
const handle = await startSddRunFromGraph(
|
|
305
311
|
exported.graph,
|
|
306
312
|
{
|
|
@@ -309,6 +315,7 @@ function createCliKanbanHostRoutes(deps) {
|
|
|
309
315
|
projectRoot,
|
|
310
316
|
subagentFactory: opts.sddSubagentFactory,
|
|
311
317
|
projectSddBoards: paths.projectSddBoards,
|
|
318
|
+
taskStore,
|
|
312
319
|
...opts.brain ? { brain: opts.brain } : {},
|
|
313
320
|
...runIsolatedTurn ? { runIsolatedTurn } : {}
|
|
314
321
|
},
|
|
@@ -347,6 +354,52 @@ import {
|
|
|
347
354
|
registerWebuiSignalHandlers
|
|
348
355
|
} from "@wrongstack/webui-server";
|
|
349
356
|
|
|
357
|
+
// src/webui-server/listen-helpers.ts
|
|
358
|
+
import * as http from "node:http";
|
|
359
|
+
async function startDeferredHttpListen(args) {
|
|
360
|
+
const { server, host, httpPort, logger } = args;
|
|
361
|
+
await new Promise((resolveListen, rejectListen) => {
|
|
362
|
+
server.listen(httpPort, host, () => resolveListen());
|
|
363
|
+
server.once("error", rejectListen);
|
|
364
|
+
});
|
|
365
|
+
server.on("error", (err) => {
|
|
366
|
+
logger.error("http_server_error", {
|
|
367
|
+
message: err.message,
|
|
368
|
+
port: httpPort
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
async function startIpv6LoopbackProxy(args) {
|
|
373
|
+
const { primary, httpPort, logger } = args;
|
|
374
|
+
const v6 = http.createServer();
|
|
375
|
+
v6.on("request", (req, res) => primary.emit("request", req, res));
|
|
376
|
+
v6.on("upgrade", (req, socket, head) => primary.emit("upgrade", req, socket, head));
|
|
377
|
+
const logIpv6Error = (err) => {
|
|
378
|
+
if (err.code === "EAFNOSUPPORT" || err.code === "EADDRNOTAVAIL" || err.code === "EADDRINUSE") {
|
|
379
|
+
logger.warn("ipv6_loopback_unavailable", { code: err.code, port: httpPort });
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
logger.error("http_server_error", { message: err.message, port: httpPort });
|
|
383
|
+
};
|
|
384
|
+
v6.on("error", logIpv6Error);
|
|
385
|
+
const ipv6Listening = await new Promise((resolveListen) => {
|
|
386
|
+
const onListening = () => {
|
|
387
|
+
v6.off("error", onInitialError);
|
|
388
|
+
resolveListen(true);
|
|
389
|
+
};
|
|
390
|
+
const onInitialError = () => {
|
|
391
|
+
v6.off("listening", onListening);
|
|
392
|
+
resolveListen(false);
|
|
393
|
+
};
|
|
394
|
+
v6.once("listening", onListening);
|
|
395
|
+
v6.once("error", onInitialError);
|
|
396
|
+
v6.listen(httpPort, "::1");
|
|
397
|
+
});
|
|
398
|
+
if (!ipv6Listening) return null;
|
|
399
|
+
console.log(`[WebUI] Also listening on http://[::1]:${httpPort}`);
|
|
400
|
+
return v6;
|
|
401
|
+
}
|
|
402
|
+
|
|
350
403
|
// src/webui-server/logger-shim.ts
|
|
351
404
|
var structuredLine = (level, message) => JSON.stringify({
|
|
352
405
|
level,
|
|
@@ -376,9 +429,63 @@ var consoleLogger = {
|
|
|
376
429
|
}
|
|
377
430
|
};
|
|
378
431
|
|
|
432
|
+
// src/webui-server/node-pty-loader.ts
|
|
433
|
+
import { existsSync } from "node:fs";
|
|
434
|
+
import { createRequire } from "node:module";
|
|
435
|
+
import * as path from "node:path";
|
|
436
|
+
import { fileURLToPath } from "node:url";
|
|
437
|
+
function createNodePtyLoader(importMetaUrl, logger) {
|
|
438
|
+
const requireFromCli = createRequire(importMetaUrl);
|
|
439
|
+
let cachedNodePty;
|
|
440
|
+
return () => {
|
|
441
|
+
if (cachedNodePty !== void 0) return cachedNodePty;
|
|
442
|
+
try {
|
|
443
|
+
const webuiEntry = requireFromCli.resolve("@wrongstack/webui");
|
|
444
|
+
const webuiDir = webuiEntry.replace(/[\\/]dist.*$/, "");
|
|
445
|
+
const webuiPkgJson = path.join(webuiDir, "package.json");
|
|
446
|
+
cachedNodePty = createRequire(webuiPkgJson)("node-pty");
|
|
447
|
+
if (cachedNodePty) {
|
|
448
|
+
logger.debug?.(`[terminal] node-pty loaded via webui package (${webuiDir})`);
|
|
449
|
+
return cachedNodePty;
|
|
450
|
+
}
|
|
451
|
+
} catch (err) {
|
|
452
|
+
logger.debug?.(`[terminal] webui-route failed: ${err.message}`);
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
cachedNodePty = requireFromCli("node-pty");
|
|
456
|
+
logger.debug?.("[terminal] node-pty loaded via direct requireFromCli");
|
|
457
|
+
return cachedNodePty;
|
|
458
|
+
} catch (err) {
|
|
459
|
+
logger.debug?.(`[terminal] direct require failed: ${err.message}`);
|
|
460
|
+
}
|
|
461
|
+
try {
|
|
462
|
+
const cliPkgJson = path.join(path.dirname(fileURLToPath(importMetaUrl)), "..", "package.json");
|
|
463
|
+
let dir = path.dirname(cliPkgJson);
|
|
464
|
+
for (let i = 0; i < 6; i++) {
|
|
465
|
+
const candidate = path.join(dir, "node_modules", "node-pty");
|
|
466
|
+
if (existsSync(candidate)) {
|
|
467
|
+
cachedNodePty = createRequire(candidate)("node-pty");
|
|
468
|
+
if (cachedNodePty) {
|
|
469
|
+
logger.debug?.(`[terminal] node-pty loaded via workspace root (${candidate})`);
|
|
470
|
+
return cachedNodePty;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const parent = path.dirname(dir);
|
|
474
|
+
if (parent === dir) break;
|
|
475
|
+
dir = parent;
|
|
476
|
+
}
|
|
477
|
+
} catch (err) {
|
|
478
|
+
logger.debug?.(`[terminal] workspace-root walk failed: ${err.message}`);
|
|
479
|
+
}
|
|
480
|
+
cachedNodePty = null;
|
|
481
|
+
logger.debug?.('[terminal] node-pty resolution failed; terminal panel will report "unavailable"');
|
|
482
|
+
return cachedNodePty;
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
|
|
379
486
|
// src/webui-server/prefs-seeding.ts
|
|
380
487
|
import * as fs from "node:fs/promises";
|
|
381
|
-
import * as
|
|
488
|
+
import * as path2 from "node:path";
|
|
382
489
|
import { DefaultSecretVault } from "@wrongstack/core/security";
|
|
383
490
|
import {
|
|
384
491
|
PREF_KEYS,
|
|
@@ -434,8 +541,8 @@ function createPrefsSeeding(opts) {
|
|
|
434
541
|
patchLiveAppConfig({ modelMatrix: payload["modelMatrix"] });
|
|
435
542
|
}
|
|
436
543
|
if (!opts.profileConfigPath) return;
|
|
437
|
-
const globalRoot = opts.globalConfigPath ?
|
|
438
|
-
const vault = new DefaultSecretVault({ keyFile:
|
|
544
|
+
const globalRoot = opts.globalConfigPath ? path2.dirname(opts.globalConfigPath) : path2.dirname(opts.profileConfigPath);
|
|
545
|
+
const vault = new DefaultSecretVault({ keyFile: path2.join(globalRoot, ".key") });
|
|
439
546
|
await persistPrefsToConfig(
|
|
440
547
|
{
|
|
441
548
|
profileConfigPath: opts.profileConfigPath,
|
|
@@ -464,13 +571,13 @@ function createPrefsSeeding(opts) {
|
|
|
464
571
|
}
|
|
465
572
|
|
|
466
573
|
// src/webui-server/provider-config.ts
|
|
467
|
-
import * as
|
|
574
|
+
import * as path3 from "node:path";
|
|
468
575
|
import { DefaultSecretVault as DefaultSecretVault2 } from "@wrongstack/core/security";
|
|
469
576
|
function getVault(globalConfigPath) {
|
|
470
|
-
const configDir =
|
|
471
|
-
const parentDir =
|
|
472
|
-
const globalRoot =
|
|
473
|
-
const keyFile =
|
|
577
|
+
const configDir = path3.dirname(globalConfigPath ?? "");
|
|
578
|
+
const parentDir = path3.dirname(configDir);
|
|
579
|
+
const globalRoot = path3.basename(parentDir) === "profiles" ? path3.dirname(parentDir) : configDir;
|
|
580
|
+
const keyFile = path3.join(globalRoot, ".key");
|
|
474
581
|
return new DefaultSecretVault2({ keyFile });
|
|
475
582
|
}
|
|
476
583
|
async function loadSavedProviders(globalConfigPath) {
|
|
@@ -496,7 +603,7 @@ function createProviderConfigStore(globalConfigPath, configProvidersRef) {
|
|
|
496
603
|
}
|
|
497
604
|
|
|
498
605
|
// src/webui-server/session-start-payload.ts
|
|
499
|
-
import * as
|
|
606
|
+
import * as path4 from "node:path";
|
|
500
607
|
import { DEFAULT_CONTEXT_WINDOW_MODE_ID } from "@wrongstack/core/types";
|
|
501
608
|
import { protocolAdvertisement } from "@wrongstack/webui-server/protocol";
|
|
502
609
|
|
|
@@ -513,6 +620,7 @@ function createSessionStartPayloadBuilder(deps) {
|
|
|
513
620
|
let inputCost = 0;
|
|
514
621
|
let outputCost = 0;
|
|
515
622
|
let cacheReadCost = 0;
|
|
623
|
+
const updateInfo = deps.updateInfo;
|
|
516
624
|
try {
|
|
517
625
|
if (deps.modelsRegistry) {
|
|
518
626
|
const m = await deps.modelsRegistry.getModel(
|
|
@@ -536,7 +644,7 @@ function createSessionStartPayloadBuilder(deps) {
|
|
|
536
644
|
model: deps.agent.ctx.model,
|
|
537
645
|
provider: deps.agent.ctx.provider.id,
|
|
538
646
|
mode: deps.modeId ?? "default",
|
|
539
|
-
projectName: deps.projectRoot ?
|
|
647
|
+
projectName: deps.projectRoot ? path4.basename(deps.projectRoot) : void 0,
|
|
540
648
|
// Frontend reads `projectRoot` from session.start (ws-handlers setEnv) —
|
|
541
649
|
// omitting it left the store's projectRoot empty after a project switch.
|
|
542
650
|
projectRoot: deps.projectRoot ?? deps.agent.ctx.projectRoot ?? "",
|
|
@@ -552,6 +660,10 @@ function createSessionStartPayloadBuilder(deps) {
|
|
|
552
660
|
cacheReadCost,
|
|
553
661
|
lastInputTokens,
|
|
554
662
|
providerStatuses: deps.statusTracker?.getAllStatuses() ?? [],
|
|
663
|
+
appVersion: updateInfo?.current,
|
|
664
|
+
latestVersion: updateInfo?.latest,
|
|
665
|
+
updateAvailable: updateInfo?.outdated ?? false,
|
|
666
|
+
updateCheckFailed: updateInfo?.checkFailed ?? false,
|
|
555
667
|
...protocolAdvertisement(),
|
|
556
668
|
...overrides
|
|
557
669
|
};
|
|
@@ -711,106 +823,6 @@ function startBoundedTerminalLogView(options = {}) {
|
|
|
711
823
|
};
|
|
712
824
|
}
|
|
713
825
|
|
|
714
|
-
// src/webui-server/node-pty-loader.ts
|
|
715
|
-
import { existsSync } from "node:fs";
|
|
716
|
-
import { createRequire } from "node:module";
|
|
717
|
-
import * as path4 from "node:path";
|
|
718
|
-
import { fileURLToPath } from "node:url";
|
|
719
|
-
function createNodePtyLoader(importMetaUrl, logger) {
|
|
720
|
-
const requireFromCli = createRequire(importMetaUrl);
|
|
721
|
-
let cachedNodePty;
|
|
722
|
-
return () => {
|
|
723
|
-
if (cachedNodePty !== void 0) return cachedNodePty;
|
|
724
|
-
try {
|
|
725
|
-
const webuiEntry = requireFromCli.resolve("@wrongstack/webui");
|
|
726
|
-
const webuiDir = webuiEntry.replace(/[\\/]dist.*$/, "");
|
|
727
|
-
const webuiPkgJson = path4.join(webuiDir, "package.json");
|
|
728
|
-
cachedNodePty = createRequire(webuiPkgJson)("node-pty");
|
|
729
|
-
if (cachedNodePty) {
|
|
730
|
-
logger.debug?.(`[terminal] node-pty loaded via webui package (${webuiDir})`);
|
|
731
|
-
return cachedNodePty;
|
|
732
|
-
}
|
|
733
|
-
} catch (err) {
|
|
734
|
-
logger.debug?.(`[terminal] webui-route failed: ${err.message}`);
|
|
735
|
-
}
|
|
736
|
-
try {
|
|
737
|
-
cachedNodePty = requireFromCli("node-pty");
|
|
738
|
-
logger.debug?.("[terminal] node-pty loaded via direct requireFromCli");
|
|
739
|
-
return cachedNodePty;
|
|
740
|
-
} catch (err) {
|
|
741
|
-
logger.debug?.(`[terminal] direct require failed: ${err.message}`);
|
|
742
|
-
}
|
|
743
|
-
try {
|
|
744
|
-
const cliPkgJson = path4.join(path4.dirname(fileURLToPath(importMetaUrl)), "..", "package.json");
|
|
745
|
-
let dir = path4.dirname(cliPkgJson);
|
|
746
|
-
for (let i = 0; i < 6; i++) {
|
|
747
|
-
const candidate = path4.join(dir, "node_modules", "node-pty");
|
|
748
|
-
if (existsSync(candidate)) {
|
|
749
|
-
cachedNodePty = createRequire(candidate)("node-pty");
|
|
750
|
-
if (cachedNodePty) {
|
|
751
|
-
logger.debug?.(`[terminal] node-pty loaded via workspace root (${candidate})`);
|
|
752
|
-
return cachedNodePty;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
const parent = path4.dirname(dir);
|
|
756
|
-
if (parent === dir) break;
|
|
757
|
-
dir = parent;
|
|
758
|
-
}
|
|
759
|
-
} catch (err) {
|
|
760
|
-
logger.debug?.(`[terminal] workspace-root walk failed: ${err.message}`);
|
|
761
|
-
}
|
|
762
|
-
cachedNodePty = null;
|
|
763
|
-
logger.debug?.('[terminal] node-pty resolution failed; terminal panel will report "unavailable"');
|
|
764
|
-
return cachedNodePty;
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
|
|
768
|
-
// src/webui-server/listen-helpers.ts
|
|
769
|
-
import * as http from "node:http";
|
|
770
|
-
async function startDeferredHttpListen(args) {
|
|
771
|
-
const { server, host, httpPort, logger } = args;
|
|
772
|
-
await new Promise((resolveListen, rejectListen) => {
|
|
773
|
-
server.listen(httpPort, host, () => resolveListen());
|
|
774
|
-
server.once("error", rejectListen);
|
|
775
|
-
});
|
|
776
|
-
server.on("error", (err) => {
|
|
777
|
-
logger.error("http_server_error", {
|
|
778
|
-
message: err.message,
|
|
779
|
-
port: httpPort
|
|
780
|
-
});
|
|
781
|
-
});
|
|
782
|
-
}
|
|
783
|
-
async function startIpv6LoopbackProxy(args) {
|
|
784
|
-
const { primary, httpPort, logger } = args;
|
|
785
|
-
const v6 = http.createServer();
|
|
786
|
-
v6.on("request", (req, res) => primary.emit("request", req, res));
|
|
787
|
-
v6.on("upgrade", (req, socket, head) => primary.emit("upgrade", req, socket, head));
|
|
788
|
-
const logIpv6Error = (err) => {
|
|
789
|
-
if (err.code === "EAFNOSUPPORT" || err.code === "EADDRNOTAVAIL" || err.code === "EADDRINUSE") {
|
|
790
|
-
logger.warn("ipv6_loopback_unavailable", { code: err.code, port: httpPort });
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
logger.error("http_server_error", { message: err.message, port: httpPort });
|
|
794
|
-
};
|
|
795
|
-
v6.on("error", logIpv6Error);
|
|
796
|
-
const ipv6Listening = await new Promise((resolveListen) => {
|
|
797
|
-
const onListening = () => {
|
|
798
|
-
v6.off("error", onInitialError);
|
|
799
|
-
resolveListen(true);
|
|
800
|
-
};
|
|
801
|
-
const onInitialError = () => {
|
|
802
|
-
v6.off("listening", onListening);
|
|
803
|
-
resolveListen(false);
|
|
804
|
-
};
|
|
805
|
-
v6.once("listening", onListening);
|
|
806
|
-
v6.once("error", onInitialError);
|
|
807
|
-
v6.listen(httpPort, "::1");
|
|
808
|
-
});
|
|
809
|
-
if (!ipv6Listening) return null;
|
|
810
|
-
console.log(`[WebUI] Also listening on http://[::1]:${httpPort}`);
|
|
811
|
-
return v6;
|
|
812
|
-
}
|
|
813
|
-
|
|
814
826
|
// src/webui-server.ts
|
|
815
827
|
async function runWebUI(opts) {
|
|
816
828
|
const trustBoundary = opts.trustBoundary ?? createCompatibilityTrustBoundary({ policyId: "cli-webui-trusted-host-compat-v1" });
|
|
@@ -858,6 +870,17 @@ async function runWebUI(opts) {
|
|
|
858
870
|
...opts.onKanbanDispatch ? { dispatchTask: opts.onKanbanDispatch } : {},
|
|
859
871
|
log: (message) => consoleLogger.info(message)
|
|
860
872
|
}) : null;
|
|
873
|
+
const stopKanbanSupervisorMemoryStats = kanbanSupervisor ? startSharedHeapWatchdog({
|
|
874
|
+
collectStats: () => {
|
|
875
|
+
const stats = kanbanSupervisor.getStats();
|
|
876
|
+
return {
|
|
877
|
+
kanbanSupervisorSnapshots: stats.snapshots,
|
|
878
|
+
kanbanSupervisorScheduledBoards: stats.scheduledBoards,
|
|
879
|
+
kanbanSupervisorAgentCooldowns: stats.agentCooldowns,
|
|
880
|
+
kanbanSupervisorRunningAgents: stats.runningAgents
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
}) : void 0;
|
|
861
884
|
const goalHandler = new GoalWebSocketHandler(
|
|
862
885
|
opts.agent,
|
|
863
886
|
opts.agent.ctx,
|
|
@@ -1290,6 +1313,8 @@ async function runWebUI(opts) {
|
|
|
1290
1313
|
...kanbanSupervisor ? { kanbanSupervisor } : {},
|
|
1291
1314
|
...kanbanRunMirror ? { kanbanRunMirror } : {}
|
|
1292
1315
|
});
|
|
1316
|
+
let signalShutdown;
|
|
1317
|
+
const shutdown = () => signalShutdown?.();
|
|
1293
1318
|
const handleMessage = createEmbeddedMessageRouter({
|
|
1294
1319
|
trustBoundary,
|
|
1295
1320
|
opts,
|
|
@@ -1386,7 +1411,7 @@ async function runWebUI(opts) {
|
|
|
1386
1411
|
})
|
|
1387
1412
|
);
|
|
1388
1413
|
});
|
|
1389
|
-
|
|
1414
|
+
signalShutdown = createWebuiShutdown({
|
|
1390
1415
|
abortInFlight: () => {
|
|
1391
1416
|
if (abortController) {
|
|
1392
1417
|
abortController.abort();
|
|
@@ -1399,6 +1424,18 @@ async function runWebUI(opts) {
|
|
|
1399
1424
|
flushAllStreamBuffers();
|
|
1400
1425
|
for (const unsub of eventUnsubscribers) unsub();
|
|
1401
1426
|
},
|
|
1427
|
+
disposeResources: () => {
|
|
1428
|
+
credentialWatcherClose?.();
|
|
1429
|
+
credentialWatcherClose = void 0;
|
|
1430
|
+
goalHandler.dispose();
|
|
1431
|
+
sddBoardHandler.dispose();
|
|
1432
|
+
worktreeHandler.dispose();
|
|
1433
|
+
terminalHandler.dispose();
|
|
1434
|
+
kanbanRunMirror?.dispose();
|
|
1435
|
+
kanbanSupervisor?.dispose();
|
|
1436
|
+
void stopKanbanSupervisorMemoryStats?.();
|
|
1437
|
+
unregisterWebuiClient();
|
|
1438
|
+
},
|
|
1402
1439
|
closeClients: () => {
|
|
1403
1440
|
for (const [ws] of clients) ws.close();
|
|
1404
1441
|
clients.clear();
|
|
@@ -1413,6 +1450,7 @@ async function runWebUI(opts) {
|
|
|
1413
1450
|
onStopped: () => {
|
|
1414
1451
|
terminalLogView.redraw();
|
|
1415
1452
|
terminalLogView.stop();
|
|
1453
|
+
opts.onExit?.();
|
|
1416
1454
|
resolve();
|
|
1417
1455
|
}
|
|
1418
1456
|
});
|
|
@@ -1423,21 +1461,6 @@ async function runWebUI(opts) {
|
|
|
1423
1461
|
ws.send(JSON.stringify(msg));
|
|
1424
1462
|
}
|
|
1425
1463
|
}
|
|
1426
|
-
function shutdown() {
|
|
1427
|
-
console.log("[WebUI] Shutting down...");
|
|
1428
|
-
terminalLogView.redraw();
|
|
1429
|
-
terminalLogView.stop();
|
|
1430
|
-
credentialWatcherClose?.();
|
|
1431
|
-
flushAllStreamBuffers();
|
|
1432
|
-
worktreeHandler.dispose();
|
|
1433
|
-
terminalHandler.dispose();
|
|
1434
|
-
kanbanRunMirror?.dispose();
|
|
1435
|
-
kanbanSupervisor?.dispose();
|
|
1436
|
-
unregisterWebuiClient();
|
|
1437
|
-
ipv6LoopbackServer?.close();
|
|
1438
|
-
httpServer?.server.close();
|
|
1439
|
-
opts.onExit?.();
|
|
1440
|
-
}
|
|
1441
1464
|
function broadcast(msg) {
|
|
1442
1465
|
const data = JSON.stringify(msg);
|
|
1443
1466
|
for (const [ws] of clients) {
|
|
@@ -1457,4 +1480,4 @@ async function runWebUI(opts) {
|
|
|
1457
1480
|
export {
|
|
1458
1481
|
runWebUI
|
|
1459
1482
|
};
|
|
1460
|
-
//# sourceMappingURL=webui-server-
|
|
1483
|
+
//# sourceMappingURL=webui-server-XKFUOKMJ.js.map
|