cogpit 2.1.3 → 2.2.1
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/cli.js +902 -425
- package/dist/web/assets/CommandPaletteHost--_g3tlgk.js +1 -0
- package/dist/web/assets/ConfigBrowser-DrAZQBx8.js +1 -0
- package/dist/web/assets/{HighlightedEditor-qhEWgnBF.js → HighlightedEditor-Byq8pOUC.js} +1 -1
- package/dist/web/assets/{KeyboardShortcutsDialog-B9nMtf5U.js → KeyboardShortcutsDialog-CFhdeGBw.js} +1 -1
- package/dist/web/assets/{MobileFileChanges-j9DCxvz6.js → MobileFileChanges-uxpxh1W6.js} +1 -1
- package/dist/web/assets/{PreviewPanel-DZSVN3mt.js → PreviewPanel-DC6OTZfZ.js} +1 -1
- package/dist/web/assets/ProjectFilesPanel-ByyaiSGy.js +4 -0
- package/dist/web/assets/{ProjectSwitcherModal-o8NhzySH.js → ProjectSwitcherModal-BRbFj3Dd.js} +1 -1
- package/dist/web/assets/{TerminalOutput-CcWkSv29.js → TerminalOutput-Aavw8QCx.js} +1 -1
- package/dist/web/assets/{ThemeSelectorModal-CnbSCgJj.js → ThemeSelectorModal-CxGMhlkF.js} +1 -1
- package/dist/web/assets/WorkflowsPanel-Beg1AAtq.js +1 -0
- package/dist/web/assets/{WorktreePanel-DahbK2L0.js → WorktreePanel-B17_SlFC.js} +1 -1
- package/dist/web/assets/{index-_0HhakEy.js → index-C-5Kgwol.js} +4 -4
- package/dist/web/assets/{index-DXTQExVH.js → index-CJcccHRp.js} +1 -1
- package/dist/web/assets/index-CTpAqQye.js +1 -0
- package/dist/web/assets/index-DB1wEO_I.js +148 -0
- package/dist/web/assets/index-DU9XxwBy.css +1 -0
- package/dist/web/assets/{session-parser.worker-DycJL0jJ.js → session-parser.worker-RMitC4X_.js} +17 -17
- package/dist/web/assets/{vendor-ui-Bg9q4lA4.js → vendor-ui-CyII6N5s.js} +152 -147
- package/dist/web/index.html +3 -3
- package/package.json +1 -1
- package/dist/web/assets/CommandPaletteHost-1UPdv9Nv.js +0 -1
- package/dist/web/assets/ConfigBrowser-B5lZsJDw.js +0 -1
- package/dist/web/assets/ProjectFilesPanel-DSvO4CrB.js +0 -4
- package/dist/web/assets/WorkflowsPanel-CvBweQMf.js +0 -1
- package/dist/web/assets/index-7UiltNKa.js +0 -1
- package/dist/web/assets/index-BESnPMZk.js +0 -144
- package/dist/web/assets/index-Bif4Kdtn.css +0 -1
package/dist/cli.js
CHANGED
|
@@ -486,8 +486,8 @@ async function mint(device, generation2) {
|
|
|
486
486
|
if (prev?.generation === generation2 && prev.error && Date.now() - prev.at < MINT_COOLDOWN_MS) {
|
|
487
487
|
throw prev.error;
|
|
488
488
|
}
|
|
489
|
-
const
|
|
490
|
-
lastAttempt.set(id,
|
|
489
|
+
const record3 = { at: Date.now(), generation: generation2 };
|
|
490
|
+
lastAttempt.set(id, record3);
|
|
491
491
|
const url = `${device.tls ? "https" : "http"}://${device.host}:${device.port}/api/auth/verify`;
|
|
492
492
|
const credential = device.username ? `${device.username}:${device.password ?? ""}` : device.password ?? "";
|
|
493
493
|
let res;
|
|
@@ -503,7 +503,7 @@ async function mint(device, generation2) {
|
|
|
503
503
|
`Could not reach device "${device.name}" at ${device.host}:${device.port}`,
|
|
504
504
|
{ cause: err }
|
|
505
505
|
);
|
|
506
|
-
|
|
506
|
+
record3.error = error;
|
|
507
507
|
if (generationIsCurrent(id, generation2)) {
|
|
508
508
|
setDeviceRuntime(id, { lastProbe: Date.now() });
|
|
509
509
|
}
|
|
@@ -511,7 +511,7 @@ async function mint(device, generation2) {
|
|
|
511
511
|
}
|
|
512
512
|
if (res.status === 401 || res.status === 403) {
|
|
513
513
|
const error = new DeviceAuthError(id, `Device "${device.name}" rejected the password`, res.status);
|
|
514
|
-
|
|
514
|
+
record3.error = error;
|
|
515
515
|
if (generationIsCurrent(id, generation2)) {
|
|
516
516
|
setDeviceRuntime(id, { authState: "bad-password", lastProbe: Date.now() });
|
|
517
517
|
}
|
|
@@ -522,7 +522,7 @@ async function mint(device, generation2) {
|
|
|
522
522
|
id,
|
|
523
523
|
`Device "${device.name}" returned HTTP ${res.status} while minting a token`
|
|
524
524
|
);
|
|
525
|
-
|
|
525
|
+
record3.error = error;
|
|
526
526
|
if (generationIsCurrent(id, generation2)) {
|
|
527
527
|
setDeviceRuntime(id, { lastProbe: Date.now() });
|
|
528
528
|
}
|
|
@@ -536,7 +536,7 @@ async function mint(device, generation2) {
|
|
|
536
536
|
}
|
|
537
537
|
if (!body || body.valid === false || typeof body.token !== "string" || !body.token) {
|
|
538
538
|
const error = new DeviceAuthError(id, `Device "${device.name}" did not return a valid token`, res.status);
|
|
539
|
-
|
|
539
|
+
record3.error = error;
|
|
540
540
|
if (generationIsCurrent(id, generation2)) {
|
|
541
541
|
setDeviceRuntime(id, { authState: "bad-password", lastProbe: Date.now() });
|
|
542
542
|
}
|
|
@@ -779,6 +779,7 @@ var init_agent_descriptors = __esm({
|
|
|
779
779
|
args: ["update"],
|
|
780
780
|
matches: (path) => path.endsWith("/.local/bin/claude") || path.endsWith("/.local/bin/claude.exe") || path.includes("/.local/share/claude/")
|
|
781
781
|
},
|
|
782
|
+
bundledBySdk: true,
|
|
782
783
|
homeDirName: ".claude",
|
|
783
784
|
homeEnvVar: null,
|
|
784
785
|
installMarker: "projects",
|
|
@@ -915,6 +916,7 @@ var init_agent_descriptors = __esm({
|
|
|
915
916
|
// Codex ships no self-updater; a hand-placed binary has to be replaced by
|
|
916
917
|
// whatever put it there.
|
|
917
918
|
selfUpdate: null,
|
|
919
|
+
bundledBySdk: false,
|
|
918
920
|
homeDirName: ".codex",
|
|
919
921
|
homeEnvVar: "CODEX_HOME",
|
|
920
922
|
installMarker: "",
|
|
@@ -1025,6 +1027,7 @@ var init_agent_descriptors = __esm({
|
|
|
1025
1027
|
// only do because the caller passes the realpath in as well.
|
|
1026
1028
|
matches: (path) => path.endsWith("/.local/bin/copilot") || path === "/usr/local/bin/copilot"
|
|
1027
1029
|
},
|
|
1030
|
+
bundledBySdk: false,
|
|
1028
1031
|
homeDirName: ".copilot",
|
|
1029
1032
|
homeEnvVar: "COPILOT_HOME",
|
|
1030
1033
|
installMarker: "session-state",
|
|
@@ -1236,6 +1239,9 @@ function hasExtension(binName, extensions) {
|
|
|
1236
1239
|
function hasExecutableExtension(fileName, env = process.env) {
|
|
1237
1240
|
return hasExtension(fileName, pathExtensions({ env }));
|
|
1238
1241
|
}
|
|
1242
|
+
function isDirectlyLaunchable(fileName) {
|
|
1243
|
+
return DIRECT_EXTENSIONS.includes(win32.extname(fileName).toLowerCase());
|
|
1244
|
+
}
|
|
1239
1245
|
function findExecutableOnPath(binName, options = {}) {
|
|
1240
1246
|
const windows = isWindows(options);
|
|
1241
1247
|
const path = windows ? win32 : posix;
|
|
@@ -1280,7 +1286,7 @@ function resolveAgentCommand(binName, args = [], options = {}) {
|
|
|
1280
1286
|
if (!isWindows(options)) return { command: binName, args, spawnOptions: {} };
|
|
1281
1287
|
const resolved = /[\\/]/.test(binName) ? binName : findExecutableOnPath(binName, options);
|
|
1282
1288
|
if (!resolved) return { command: binName, args, spawnOptions: {} };
|
|
1283
|
-
if (
|
|
1289
|
+
if (isDirectlyLaunchable(resolved)) {
|
|
1284
1290
|
return { command: resolved, args, spawnOptions: {} };
|
|
1285
1291
|
}
|
|
1286
1292
|
return throughCmdExe(resolved, args, options);
|
|
@@ -1297,6 +1303,38 @@ var init_binaryResolver = __esm({
|
|
|
1297
1303
|
}
|
|
1298
1304
|
});
|
|
1299
1305
|
|
|
1306
|
+
// ../../shared/contracts/agentExecutable.ts
|
|
1307
|
+
function isExecutableSource(value) {
|
|
1308
|
+
return EXECUTABLE_SOURCES.includes(value);
|
|
1309
|
+
}
|
|
1310
|
+
function parseExecutableChoice(value) {
|
|
1311
|
+
if (!value || typeof value !== "object") return void 0;
|
|
1312
|
+
const { source, path } = value;
|
|
1313
|
+
if (!isExecutableSource(source) || source === "auto") return void 0;
|
|
1314
|
+
if (source === "custom") {
|
|
1315
|
+
return typeof path === "string" && path.trim() ? { source, path: path.trim() } : void 0;
|
|
1316
|
+
}
|
|
1317
|
+
return { source };
|
|
1318
|
+
}
|
|
1319
|
+
var EXECUTABLE_SOURCES, DEFAULT_EXECUTABLE_CHOICE, DETECTED_EXECUTABLE_SOURCES;
|
|
1320
|
+
var init_agentExecutable = __esm({
|
|
1321
|
+
"../../shared/contracts/agentExecutable.ts"() {
|
|
1322
|
+
EXECUTABLE_SOURCES = [
|
|
1323
|
+
"auto",
|
|
1324
|
+
"path",
|
|
1325
|
+
"npm",
|
|
1326
|
+
"bundled",
|
|
1327
|
+
"custom"
|
|
1328
|
+
];
|
|
1329
|
+
DEFAULT_EXECUTABLE_CHOICE = { source: "auto" };
|
|
1330
|
+
DETECTED_EXECUTABLE_SOURCES = [
|
|
1331
|
+
"path",
|
|
1332
|
+
"npm",
|
|
1333
|
+
"bundled"
|
|
1334
|
+
];
|
|
1335
|
+
}
|
|
1336
|
+
});
|
|
1337
|
+
|
|
1300
1338
|
// ../../server/config.ts
|
|
1301
1339
|
import { readFile as readFile2, stat, readdir, chmod as chmod3 } from "node:fs/promises";
|
|
1302
1340
|
import { join as join2, resolve } from "node:path";
|
|
@@ -1405,7 +1443,8 @@ async function loadConfig() {
|
|
|
1405
1443
|
networkPassword,
|
|
1406
1444
|
terminalApp: parsed.terminalApp || void 0,
|
|
1407
1445
|
editorApp: parsed.editorApp || void 0,
|
|
1408
|
-
useBuiltInEditor: !!parsed.useBuiltInEditor
|
|
1446
|
+
useBuiltInEditor: !!parsed.useBuiltInEditor,
|
|
1447
|
+
agentExecutable: parseExecutableChoice(parsed.agentExecutable)
|
|
1409
1448
|
};
|
|
1410
1449
|
return cachedConfig;
|
|
1411
1450
|
}
|
|
@@ -1460,6 +1499,7 @@ var init_config = __esm({
|
|
|
1460
1499
|
init_password_utils();
|
|
1461
1500
|
init_atomicJsonFile();
|
|
1462
1501
|
init_binaryResolver();
|
|
1502
|
+
init_agentExecutable();
|
|
1463
1503
|
CONFIG_FILE_MODE = 384;
|
|
1464
1504
|
__dirname = fileURLToPath(new URL(".", import.meta.url));
|
|
1465
1505
|
PROJECT_ROOT = resolve(__dirname, "..");
|
|
@@ -3959,7 +3999,7 @@ async function createShare(input) {
|
|
|
3959
3999
|
const passwordHash = hashPassword(passphrase);
|
|
3960
4000
|
const share = await commitShareMutation((draft) => {
|
|
3961
4001
|
const existing = draft.get(input.sessionId);
|
|
3962
|
-
const
|
|
4002
|
+
const record3 = {
|
|
3963
4003
|
sessionId: input.sessionId,
|
|
3964
4004
|
dirName: input.dirName,
|
|
3965
4005
|
fileName: input.fileName,
|
|
@@ -3968,8 +4008,8 @@ async function createShare(input) {
|
|
|
3968
4008
|
// No guest has ever used this passphrase; the UI renders 0 as "never".
|
|
3969
4009
|
lastAccessAt: 0
|
|
3970
4010
|
};
|
|
3971
|
-
draft.set(
|
|
3972
|
-
return { changed: true, value: toPublicShare(
|
|
4011
|
+
draft.set(record3.sessionId, record3);
|
|
4012
|
+
return { changed: true, value: toPublicShare(record3) };
|
|
3973
4013
|
});
|
|
3974
4014
|
return { share, passphrase };
|
|
3975
4015
|
}
|
|
@@ -4819,6 +4859,7 @@ var init_policy = __esm({
|
|
|
4819
4859
|
"project-files": admin("/api/project-files"),
|
|
4820
4860
|
"project-file": admin("/api/project-file"),
|
|
4821
4861
|
"git-status": admin("/api/git-status"),
|
|
4862
|
+
"github-actions": admin("/api/github-actions"),
|
|
4822
4863
|
"project-icon": admin("/api/project-icon"),
|
|
4823
4864
|
"git-diff": admin("/api/git-diff"),
|
|
4824
4865
|
mcp: admin("/api/mcp-servers"),
|
|
@@ -4847,6 +4888,10 @@ var init_policy = __esm({
|
|
|
4847
4888
|
"provider-updates": [
|
|
4848
4889
|
{ prefix: "/api/provider-updates", methods: ["GET"], requires: "authed" },
|
|
4849
4890
|
{ prefix: "/api/provider-updates/run", requires: "admin" }
|
|
4891
|
+
],
|
|
4892
|
+
// Reports which binary the server spawns; the choice itself is saved through /api/config.
|
|
4893
|
+
"agent-executable": [
|
|
4894
|
+
{ prefix: "/api/agent-executable", methods: ["GET"], requires: "authed" }
|
|
4850
4895
|
]
|
|
4851
4896
|
};
|
|
4852
4897
|
ALL_RULES = Object.values(ROUTE_POLICIES).flat();
|
|
@@ -5619,6 +5664,274 @@ var init_subagentWatcher = __esm({
|
|
|
5619
5664
|
}
|
|
5620
5665
|
});
|
|
5621
5666
|
|
|
5667
|
+
// ../../shared/versions.ts
|
|
5668
|
+
function parseVersion(raw) {
|
|
5669
|
+
const match = raw.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
|
|
5670
|
+
if (!match) return null;
|
|
5671
|
+
return {
|
|
5672
|
+
parts: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
5673
|
+
prerelease: match[4] ? match[4].split(".") : []
|
|
5674
|
+
};
|
|
5675
|
+
}
|
|
5676
|
+
function extractVersion(output) {
|
|
5677
|
+
const match = output.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
5678
|
+
return match ? match[0] : null;
|
|
5679
|
+
}
|
|
5680
|
+
function comparePrerelease(a, b) {
|
|
5681
|
+
if (a.length === 0 && b.length === 0) return 0;
|
|
5682
|
+
if (a.length === 0) return 1;
|
|
5683
|
+
if (b.length === 0) return -1;
|
|
5684
|
+
for (let i = 0; i < Math.max(a.length, b.length); i += 1) {
|
|
5685
|
+
const left = a[i];
|
|
5686
|
+
const right = b[i];
|
|
5687
|
+
if (left === void 0) return -1;
|
|
5688
|
+
if (right === void 0) return 1;
|
|
5689
|
+
const leftNumeric = /^\d+$/.test(left);
|
|
5690
|
+
const rightNumeric = /^\d+$/.test(right);
|
|
5691
|
+
if (leftNumeric && rightNumeric) {
|
|
5692
|
+
if (Number(left) !== Number(right)) return Number(left) < Number(right) ? -1 : 1;
|
|
5693
|
+
continue;
|
|
5694
|
+
}
|
|
5695
|
+
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
5696
|
+
if (left !== right) return left < right ? -1 : 1;
|
|
5697
|
+
}
|
|
5698
|
+
return 0;
|
|
5699
|
+
}
|
|
5700
|
+
function compareVersions(a, b) {
|
|
5701
|
+
const left = parseVersion(a);
|
|
5702
|
+
const right = parseVersion(b);
|
|
5703
|
+
if (!left || !right) return null;
|
|
5704
|
+
for (let i = 0; i < 3; i += 1) {
|
|
5705
|
+
if (left.parts[i] !== right.parts[i]) return left.parts[i] < right.parts[i] ? -1 : 1;
|
|
5706
|
+
}
|
|
5707
|
+
return comparePrerelease(left.prerelease, right.prerelease);
|
|
5708
|
+
}
|
|
5709
|
+
var init_versions = __esm({
|
|
5710
|
+
"../../shared/versions.ts"() {
|
|
5711
|
+
}
|
|
5712
|
+
});
|
|
5713
|
+
|
|
5714
|
+
// ../../server/lib/cliProcess.ts
|
|
5715
|
+
import { spawn } from "node:child_process";
|
|
5716
|
+
function runCli(executable, args, timeoutMs) {
|
|
5717
|
+
return new Promise((resolve21) => {
|
|
5718
|
+
const resolved = resolveAgentCommand(executable, [...args]);
|
|
5719
|
+
const child = spawn(resolved.command, resolved.args, {
|
|
5720
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
5721
|
+
...resolved.spawnOptions
|
|
5722
|
+
});
|
|
5723
|
+
let stdout = "";
|
|
5724
|
+
let stderr = "";
|
|
5725
|
+
let timedOut = false;
|
|
5726
|
+
const timer = setTimeout(() => {
|
|
5727
|
+
timedOut = true;
|
|
5728
|
+
child.kill("SIGKILL");
|
|
5729
|
+
}, timeoutMs);
|
|
5730
|
+
const append = (buffer, chunk) => buffer.length >= CLI_OUTPUT_MAX_CHARS ? buffer : buffer + chunk.toString();
|
|
5731
|
+
child.stdout?.on("data", (chunk) => {
|
|
5732
|
+
stdout = append(stdout, chunk);
|
|
5733
|
+
});
|
|
5734
|
+
child.stderr?.on("data", (chunk) => {
|
|
5735
|
+
stderr = append(stderr, chunk);
|
|
5736
|
+
});
|
|
5737
|
+
child.on("error", () => {
|
|
5738
|
+
clearTimeout(timer);
|
|
5739
|
+
resolve21({ code: null, stdout, stderr, timedOut });
|
|
5740
|
+
});
|
|
5741
|
+
child.on("close", (code) => {
|
|
5742
|
+
clearTimeout(timer);
|
|
5743
|
+
resolve21({ code, stdout, stderr, timedOut });
|
|
5744
|
+
});
|
|
5745
|
+
});
|
|
5746
|
+
}
|
|
5747
|
+
async function probeCliVersion(command, versionArgs, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
|
|
5748
|
+
const probe = await runCli(command, versionArgs, timeoutMs);
|
|
5749
|
+
return extractVersion(`${probe.stdout}
|
|
5750
|
+
${probe.stderr}`);
|
|
5751
|
+
}
|
|
5752
|
+
var DEFAULT_PROBE_TIMEOUT_MS, CLI_OUTPUT_MAX_CHARS;
|
|
5753
|
+
var init_cliProcess = __esm({
|
|
5754
|
+
"../../server/lib/cliProcess.ts"() {
|
|
5755
|
+
init_versions();
|
|
5756
|
+
init_binaryResolver();
|
|
5757
|
+
DEFAULT_PROBE_TIMEOUT_MS = 5e3;
|
|
5758
|
+
CLI_OUTPUT_MAX_CHARS = 1e4;
|
|
5759
|
+
}
|
|
5760
|
+
});
|
|
5761
|
+
|
|
5762
|
+
// ../../server/agents/claudeExecutable.ts
|
|
5763
|
+
import { execFileSync } from "node:child_process";
|
|
5764
|
+
import { readFileSync, statSync as statSync2 } from "node:fs";
|
|
5765
|
+
import { createRequire } from "node:module";
|
|
5766
|
+
import { posix as posix2, win32 as win322 } from "node:path";
|
|
5767
|
+
function realIsFile(path) {
|
|
5768
|
+
try {
|
|
5769
|
+
return statSync2(path).isFile();
|
|
5770
|
+
} catch {
|
|
5771
|
+
return false;
|
|
5772
|
+
}
|
|
5773
|
+
}
|
|
5774
|
+
function realReadFile(path) {
|
|
5775
|
+
try {
|
|
5776
|
+
return readFileSync(path, "utf-8");
|
|
5777
|
+
} catch {
|
|
5778
|
+
return void 0;
|
|
5779
|
+
}
|
|
5780
|
+
}
|
|
5781
|
+
function binField(manifest) {
|
|
5782
|
+
let bin;
|
|
5783
|
+
try {
|
|
5784
|
+
bin = JSON.parse(manifest).bin;
|
|
5785
|
+
} catch {
|
|
5786
|
+
return void 0;
|
|
5787
|
+
}
|
|
5788
|
+
if (typeof bin === "string") return bin;
|
|
5789
|
+
if (!bin || typeof bin !== "object") return void 0;
|
|
5790
|
+
const entry = bin[BIN_NAME];
|
|
5791
|
+
return typeof entry === "string" ? entry : void 0;
|
|
5792
|
+
}
|
|
5793
|
+
function findNpmClaude(options = {}) {
|
|
5794
|
+
const platform2 = options.platform ?? process.platform;
|
|
5795
|
+
const windows = platform2 === "win32";
|
|
5796
|
+
const path = windows ? win322 : posix2;
|
|
5797
|
+
const isFile = options.isFile ?? realIsFile;
|
|
5798
|
+
const readFile21 = options.readFile ?? realReadFile;
|
|
5799
|
+
const shim = findExecutableOnPath(BIN_NAME, { platform: platform2, env: options.env, isExecutable: isFile });
|
|
5800
|
+
if (!shim) return void 0;
|
|
5801
|
+
const shimDir = path.dirname(shim);
|
|
5802
|
+
const packageDirs = [
|
|
5803
|
+
path.join(shimDir, "node_modules", NPM_PACKAGE),
|
|
5804
|
+
path.join(shimDir, "..", "lib", "node_modules", NPM_PACKAGE)
|
|
5805
|
+
];
|
|
5806
|
+
for (const packageDir of packageDirs) {
|
|
5807
|
+
const manifest = readFile21(path.join(packageDir, "package.json"));
|
|
5808
|
+
if (!manifest) continue;
|
|
5809
|
+
const relative11 = binField(manifest);
|
|
5810
|
+
if (!relative11) continue;
|
|
5811
|
+
const target = path.normalize(path.join(packageDir, relative11));
|
|
5812
|
+
if (windows && !isDirectlyLaunchable(target)) continue;
|
|
5813
|
+
if (isFile(target)) return target;
|
|
5814
|
+
}
|
|
5815
|
+
return void 0;
|
|
5816
|
+
}
|
|
5817
|
+
function findInstalledClaude() {
|
|
5818
|
+
return findExecutableOnPath(BIN_NAME, { directOnly: true });
|
|
5819
|
+
}
|
|
5820
|
+
function findBundledClaude(resolveModule2) {
|
|
5821
|
+
try {
|
|
5822
|
+
const platformPkg = `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}`;
|
|
5823
|
+
return resolveModule2(`${platformPkg}/package.json`).replace(/package\.json$/, CLI_BIN_NAME).replace(ASAR_SEGMENT, "$1app.asar.unpacked$2");
|
|
5824
|
+
} catch {
|
|
5825
|
+
return void 0;
|
|
5826
|
+
}
|
|
5827
|
+
}
|
|
5828
|
+
function discoverClaudeExecutables(resolveModule2, probes = {}) {
|
|
5829
|
+
return {
|
|
5830
|
+
installed: (probes.findOnPath ?? findInstalledClaude)(),
|
|
5831
|
+
npm: (probes.findNpm ?? findNpmClaude)(),
|
|
5832
|
+
bundled: findBundledClaude(resolveModule2)
|
|
5833
|
+
};
|
|
5834
|
+
}
|
|
5835
|
+
function readCliVersionSync(binPath) {
|
|
5836
|
+
try {
|
|
5837
|
+
const output = execFileSync(binPath, ["--version"], {
|
|
5838
|
+
encoding: "utf-8",
|
|
5839
|
+
timeout: 5e3,
|
|
5840
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
5841
|
+
});
|
|
5842
|
+
const match = output.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
5843
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : void 0;
|
|
5844
|
+
} catch {
|
|
5845
|
+
return void 0;
|
|
5846
|
+
}
|
|
5847
|
+
}
|
|
5848
|
+
function isAtLeast(version, floor) {
|
|
5849
|
+
for (let i = 0; i < 3; i += 1) {
|
|
5850
|
+
if (version[i] !== floor[i]) return version[i] > floor[i];
|
|
5851
|
+
}
|
|
5852
|
+
return true;
|
|
5853
|
+
}
|
|
5854
|
+
function chooseAutomatically(found, readVersion) {
|
|
5855
|
+
const bundled = found.bundled ? { source: "bundled", path: found.bundled } : void 0;
|
|
5856
|
+
if (!found.installed) return bundled;
|
|
5857
|
+
const installed = { source: "path", path: found.installed };
|
|
5858
|
+
const installedVersion = readVersion(found.installed);
|
|
5859
|
+
if (!installedVersion) return bundled ?? installed;
|
|
5860
|
+
const bundledVersion = bundled ? readVersion(bundled.path) : void 0;
|
|
5861
|
+
if (bundledVersion && !isAtLeast(installedVersion, bundledVersion)) return bundled;
|
|
5862
|
+
return installed;
|
|
5863
|
+
}
|
|
5864
|
+
function chooseClaudeExecutable(choice, found, readVersion) {
|
|
5865
|
+
switch (choice.source) {
|
|
5866
|
+
case "auto":
|
|
5867
|
+
return chooseAutomatically(found, readVersion);
|
|
5868
|
+
case "custom":
|
|
5869
|
+
return choice.path ? { source: "custom", path: choice.path } : void 0;
|
|
5870
|
+
case "path":
|
|
5871
|
+
return found.installed ? { source: "path", path: found.installed } : void 0;
|
|
5872
|
+
case "npm":
|
|
5873
|
+
return found.npm ? { source: "npm", path: found.npm } : void 0;
|
|
5874
|
+
case "bundled":
|
|
5875
|
+
return found.bundled ? { source: "bundled", path: found.bundled } : void 0;
|
|
5876
|
+
}
|
|
5877
|
+
}
|
|
5878
|
+
function configuredChoice() {
|
|
5879
|
+
return getConfig()?.agentExecutable ?? DEFAULT_EXECUTABLE_CHOICE;
|
|
5880
|
+
}
|
|
5881
|
+
function resolveClaudeExecutable() {
|
|
5882
|
+
const choice = configuredChoice();
|
|
5883
|
+
const key2 = JSON.stringify(choice);
|
|
5884
|
+
if (memo?.key !== key2) {
|
|
5885
|
+
memo = {
|
|
5886
|
+
key: key2,
|
|
5887
|
+
resolved: chooseClaudeExecutable(choice, discoverClaudeExecutables(resolveModule), readCliVersionSync)
|
|
5888
|
+
};
|
|
5889
|
+
}
|
|
5890
|
+
return memo.resolved;
|
|
5891
|
+
}
|
|
5892
|
+
function claudeCliPath() {
|
|
5893
|
+
return resolveClaudeExecutable()?.path;
|
|
5894
|
+
}
|
|
5895
|
+
async function describeClaudeExecutable() {
|
|
5896
|
+
const choice = configuredChoice();
|
|
5897
|
+
const found = discoverClaudeExecutables(resolveModule);
|
|
5898
|
+
const active = resolveClaudeExecutable();
|
|
5899
|
+
const pathBySource = {
|
|
5900
|
+
path: found.installed,
|
|
5901
|
+
npm: found.npm,
|
|
5902
|
+
bundled: found.bundled
|
|
5903
|
+
};
|
|
5904
|
+
const detected = DETECTED_EXECUTABLE_SOURCES.filter((source) => pathBySource[source] !== void 0).map((source) => ({ source, path: pathBySource[source] }));
|
|
5905
|
+
const paths = /* @__PURE__ */ new Set([...detected.map(({ path }) => path), ...active ? [active.path] : []]);
|
|
5906
|
+
const versions = new Map(
|
|
5907
|
+
await Promise.all(
|
|
5908
|
+
[...paths].map(async (path) => [path, await probeCliVersion(path, ["--version"])])
|
|
5909
|
+
)
|
|
5910
|
+
);
|
|
5911
|
+
return {
|
|
5912
|
+
choice,
|
|
5913
|
+
candidates: detected.map((candidate) => ({
|
|
5914
|
+
...candidate,
|
|
5915
|
+
version: versions.get(candidate.path) ?? null
|
|
5916
|
+
})),
|
|
5917
|
+
active: active ? { ...active, version: versions.get(active.path) ?? null } : null
|
|
5918
|
+
};
|
|
5919
|
+
}
|
|
5920
|
+
var BIN_NAME, NPM_PACKAGE, CLI_BIN_NAME, ASAR_SEGMENT, resolveModule, memo;
|
|
5921
|
+
var init_claudeExecutable = __esm({
|
|
5922
|
+
"../../server/agents/claudeExecutable.ts"() {
|
|
5923
|
+
init_agentExecutable();
|
|
5924
|
+
init_config();
|
|
5925
|
+
init_binaryResolver();
|
|
5926
|
+
init_cliProcess();
|
|
5927
|
+
BIN_NAME = "claude";
|
|
5928
|
+
NPM_PACKAGE = "@anthropic-ai/claude-code";
|
|
5929
|
+
CLI_BIN_NAME = nativeBinaryName(BIN_NAME);
|
|
5930
|
+
ASAR_SEGMENT = /([\\/])app\.asar([\\/])/;
|
|
5931
|
+
resolveModule = (id) => createRequire(import.meta.url).resolve(id);
|
|
5932
|
+
}
|
|
5933
|
+
});
|
|
5934
|
+
|
|
5622
5935
|
// ../../server/lib/streamBus.ts
|
|
5623
5936
|
function getOrCreate(sessionId) {
|
|
5624
5937
|
let state = sessions2.get(sessionId);
|
|
@@ -5887,58 +6200,6 @@ var init_streamBus = __esm({
|
|
|
5887
6200
|
|
|
5888
6201
|
// ../../server/sdk-session.ts
|
|
5889
6202
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
5890
|
-
import { execFileSync } from "node:child_process";
|
|
5891
|
-
import { createRequire } from "node:module";
|
|
5892
|
-
function findClaudeOnPath() {
|
|
5893
|
-
return findExecutableOnPath("claude", { directOnly: true });
|
|
5894
|
-
}
|
|
5895
|
-
function readCliVersion(binPath) {
|
|
5896
|
-
try {
|
|
5897
|
-
const output = execFileSync(binPath, ["--version"], {
|
|
5898
|
-
encoding: "utf-8",
|
|
5899
|
-
timeout: 5e3,
|
|
5900
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
5901
|
-
});
|
|
5902
|
-
const match = output.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
5903
|
-
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : void 0;
|
|
5904
|
-
} catch {
|
|
5905
|
-
return void 0;
|
|
5906
|
-
}
|
|
5907
|
-
}
|
|
5908
|
-
function isAtLeast(version, floor) {
|
|
5909
|
-
for (let i = 0; i < 3; i += 1) {
|
|
5910
|
-
if (version[i] !== floor[i]) return version[i] > floor[i];
|
|
5911
|
-
}
|
|
5912
|
-
return true;
|
|
5913
|
-
}
|
|
5914
|
-
function resolveClaudeCliPath(resolveModule, probes = {}) {
|
|
5915
|
-
const findOnPath = probes.findOnPath ?? findClaudeOnPath;
|
|
5916
|
-
const readVersion = probes.readVersion ?? readCliVersion;
|
|
5917
|
-
let vendored;
|
|
5918
|
-
try {
|
|
5919
|
-
const platformPkg = `@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}`;
|
|
5920
|
-
vendored = resolveModule(`${platformPkg}/package.json`).replace(/package\.json$/, CLI_BIN_NAME);
|
|
5921
|
-
} catch {
|
|
5922
|
-
vendored = void 0;
|
|
5923
|
-
}
|
|
5924
|
-
const insideAsar = vendored !== void 0 && ASAR_SEGMENT.test(vendored);
|
|
5925
|
-
const vendoredExecutable = insideAsar ? vendored.replace(ASAR_SEGMENT, "$1app.asar.unpacked$2") : vendored;
|
|
5926
|
-
const fallback = insideAsar ? vendoredExecutable : void 0;
|
|
5927
|
-
const installed = findOnPath();
|
|
5928
|
-
if (!installed) return fallback;
|
|
5929
|
-
const installedVersion = readVersion(installed);
|
|
5930
|
-
if (!installedVersion) return vendoredExecutable ? fallback : installed;
|
|
5931
|
-
const vendoredVersion = vendoredExecutable ? readVersion(vendoredExecutable) : void 0;
|
|
5932
|
-
if (vendoredVersion && !isAtLeast(installedVersion, vendoredVersion)) return fallback;
|
|
5933
|
-
return installed;
|
|
5934
|
-
}
|
|
5935
|
-
function claudeCliPath() {
|
|
5936
|
-
if (!cliPathProbed) {
|
|
5937
|
-
cliPath = resolveClaudeCliPath((id) => createRequire(import.meta.url).resolve(id));
|
|
5938
|
-
cliPathProbed = true;
|
|
5939
|
-
}
|
|
5940
|
-
return cliPath;
|
|
5941
|
-
}
|
|
5942
6203
|
function streamingEnabled() {
|
|
5943
6204
|
const raw = process.env.COGPIT_STREAM_PARTIAL;
|
|
5944
6205
|
if (raw === void 0) return true;
|
|
@@ -6824,15 +7085,12 @@ function cleanupAllSDKSessions() {
|
|
|
6824
7085
|
sdkSessions.clear();
|
|
6825
7086
|
return killed;
|
|
6826
7087
|
}
|
|
6827
|
-
var
|
|
7088
|
+
var sdkSessions, REFUSAL_FALLBACK_DIALOG, DIALOG_CHOICES, SUPPORTED_DIALOG_KINDS, SDKMessageStream, EDIT_TOOL_NAMES;
|
|
6828
7089
|
var init_sdk_session = __esm({
|
|
6829
7090
|
"../../server/sdk-session.ts"() {
|
|
6830
7091
|
init_subagentWatcher();
|
|
6831
|
-
|
|
7092
|
+
init_claudeExecutable();
|
|
6832
7093
|
init_streamBus();
|
|
6833
|
-
CLI_BIN_NAME = nativeBinaryName("claude");
|
|
6834
|
-
ASAR_SEGMENT = /([\\/])app\.asar([\\/])/;
|
|
6835
|
-
cliPathProbed = false;
|
|
6836
7094
|
sdkSessions = /* @__PURE__ */ new Map();
|
|
6837
7095
|
REFUSAL_FALLBACK_DIALOG = "refusal_fallback_prompt";
|
|
6838
7096
|
DIALOG_CHOICES = {
|
|
@@ -8320,9 +8578,9 @@ function safeParseLine(line) {
|
|
|
8320
8578
|
function isObject2(value) {
|
|
8321
8579
|
return typeof value === "object" && value !== null;
|
|
8322
8580
|
}
|
|
8323
|
-
function isCodexRecord(
|
|
8324
|
-
if (!
|
|
8325
|
-
return
|
|
8581
|
+
function isCodexRecord(record3) {
|
|
8582
|
+
if (!record3 || typeof record3.type !== "string") return false;
|
|
8583
|
+
return record3.type === "session_meta" || record3.type === "turn_context" || record3.type === "event_msg" || record3.type === "response_item" || record3.type === "inter_agent_communication_metadata" || record3.type === "compacted" || record3.type === "world_state";
|
|
8326
8584
|
}
|
|
8327
8585
|
function extractMessageText(payload, blockType) {
|
|
8328
8586
|
const content = payload?.content;
|
|
@@ -8523,22 +8781,22 @@ function createTurn(turnId, timestamp, model) {
|
|
|
8523
8781
|
model
|
|
8524
8782
|
};
|
|
8525
8783
|
}
|
|
8526
|
-
function extractPromptFromRecord(
|
|
8527
|
-
if (
|
|
8528
|
-
return normalizePromptText(
|
|
8784
|
+
function extractPromptFromRecord(record3) {
|
|
8785
|
+
if (record3.type === "event_msg" && isObject2(record3.payload) && record3.payload.type === "user_message" && typeof record3.payload.message === "string") {
|
|
8786
|
+
return normalizePromptText(record3.payload.message);
|
|
8529
8787
|
}
|
|
8530
|
-
if (
|
|
8531
|
-
return normalizePromptText(extractMessageText(
|
|
8788
|
+
if (record3.type === "response_item" && isObject2(record3.payload) && record3.payload.type === "message" && record3.payload.role === "user") {
|
|
8789
|
+
return normalizePromptText(extractMessageText(record3.payload, "input_text"));
|
|
8532
8790
|
}
|
|
8533
8791
|
return "";
|
|
8534
8792
|
}
|
|
8535
|
-
function recordOpensTurn(
|
|
8536
|
-
if (
|
|
8537
|
-
if (
|
|
8538
|
-
if (
|
|
8793
|
+
function recordOpensTurn(record3, payload) {
|
|
8794
|
+
if (record3.type === "session_meta") return false;
|
|
8795
|
+
if (record3.type === "event_msg" && payload?.type === "task_started") return false;
|
|
8796
|
+
if (record3.type === "response_item" && payload?.type === "message") {
|
|
8539
8797
|
if (payload.role === "developer" || payload.role === "system") return false;
|
|
8540
8798
|
if (payload.role === "user") {
|
|
8541
|
-
return extractPromptFromRecord(
|
|
8799
|
+
return extractPromptFromRecord(record3) !== "" || extractResponseMessageImages(payload).length > 0 || extractResponseMessageAudio(payload).length > 0;
|
|
8542
8800
|
}
|
|
8543
8801
|
}
|
|
8544
8802
|
return true;
|
|
@@ -8559,22 +8817,22 @@ function extractMetadataFromRecords(records) {
|
|
|
8559
8817
|
let parentSessionId = null;
|
|
8560
8818
|
let agentPath = "/root";
|
|
8561
8819
|
let previousPrompt = "";
|
|
8562
|
-
for (const
|
|
8563
|
-
if (!isObject2(
|
|
8564
|
-
if (
|
|
8565
|
-
sessionId ||= typeof
|
|
8566
|
-
version ||= typeof
|
|
8567
|
-
cwd ||= typeof
|
|
8568
|
-
if (!branchedFrom && isObject2(
|
|
8569
|
-
const sourceId = typeof
|
|
8820
|
+
for (const record3 of records) {
|
|
8821
|
+
if (!isObject2(record3.payload)) continue;
|
|
8822
|
+
if (record3.type === "session_meta") {
|
|
8823
|
+
sessionId ||= typeof record3.payload.id === "string" ? record3.payload.id : "";
|
|
8824
|
+
version ||= typeof record3.payload.cli_version === "string" ? record3.payload.cli_version : "";
|
|
8825
|
+
cwd ||= typeof record3.payload.cwd === "string" ? record3.payload.cwd : "";
|
|
8826
|
+
if (!branchedFrom && isObject2(record3.payload.branchedFrom)) {
|
|
8827
|
+
const sourceId = typeof record3.payload.branchedFrom.sessionId === "string" ? record3.payload.branchedFrom.sessionId : "";
|
|
8570
8828
|
if (sourceId) {
|
|
8571
8829
|
branchedFrom = {
|
|
8572
8830
|
sessionId: sourceId,
|
|
8573
|
-
turnIndex: typeof
|
|
8831
|
+
turnIndex: typeof record3.payload.branchedFrom.turnIndex === "number" ? record3.payload.branchedFrom.turnIndex : null
|
|
8574
8832
|
};
|
|
8575
8833
|
}
|
|
8576
8834
|
}
|
|
8577
|
-
const source = isObject2(
|
|
8835
|
+
const source = isObject2(record3.payload.source) ? record3.payload.source : null;
|
|
8578
8836
|
if (source && isObject2(source.subagent)) {
|
|
8579
8837
|
isSubagent = true;
|
|
8580
8838
|
const threadSpawn = isObject2(source.subagent.thread_spawn) ? source.subagent.thread_spawn : null;
|
|
@@ -8582,25 +8840,25 @@ function extractMetadataFromRecords(records) {
|
|
|
8582
8840
|
agentPath = threadSpawn.agent_path;
|
|
8583
8841
|
}
|
|
8584
8842
|
}
|
|
8585
|
-
if (typeof
|
|
8586
|
-
parentSessionId =
|
|
8843
|
+
if (typeof record3.payload.forked_from_id === "string" && record3.payload.forked_from_id) {
|
|
8844
|
+
parentSessionId = record3.payload.forked_from_id;
|
|
8587
8845
|
}
|
|
8588
|
-
const git = isObject2(
|
|
8846
|
+
const git = isObject2(record3.payload.git) ? record3.payload.git : null;
|
|
8589
8847
|
gitBranch ||= git && typeof git.branch === "string" ? git.branch : "";
|
|
8590
8848
|
}
|
|
8591
|
-
if (
|
|
8592
|
-
model ||= typeof
|
|
8593
|
-
cwd ||= typeof
|
|
8849
|
+
if (record3.type === "turn_context") {
|
|
8850
|
+
model ||= typeof record3.payload.model === "string" ? record3.payload.model : "";
|
|
8851
|
+
cwd ||= typeof record3.payload.cwd === "string" ? record3.payload.cwd : "";
|
|
8594
8852
|
}
|
|
8595
|
-
const prompt = extractPromptFromRecord(
|
|
8853
|
+
const prompt = extractPromptFromRecord(record3);
|
|
8596
8854
|
if (!prompt) continue;
|
|
8597
8855
|
if (prompt === previousPrompt) continue;
|
|
8598
8856
|
if (!firstUserMessage) firstUserMessage = prompt;
|
|
8599
8857
|
lastUserMessage = prompt;
|
|
8600
8858
|
previousPrompt = prompt;
|
|
8601
8859
|
turnCount++;
|
|
8602
|
-
if (!timestamp) timestamp =
|
|
8603
|
-
lastTimestamp =
|
|
8860
|
+
if (!timestamp) timestamp = record3.timestamp ?? "";
|
|
8861
|
+
lastTimestamp = record3.timestamp ?? lastTimestamp;
|
|
8604
8862
|
}
|
|
8605
8863
|
if (lastTimestamp === "") lastTimestamp = timestamp;
|
|
8606
8864
|
return {
|
|
@@ -8758,19 +9016,19 @@ function walkCodexRecords(records, options) {
|
|
|
8758
9016
|
appendToolCall(targetTurn, toolCall, timestamp);
|
|
8759
9017
|
}
|
|
8760
9018
|
for (let index = 0; index < records.length; index++) {
|
|
8761
|
-
const
|
|
8762
|
-
if (!isCodexRecord(
|
|
9019
|
+
const record3 = records[index];
|
|
9020
|
+
if (!isCodexRecord(record3)) continue;
|
|
8763
9021
|
recordIndex = index;
|
|
8764
|
-
const payload = isObject2(
|
|
8765
|
-
const timestamp =
|
|
8766
|
-
if (
|
|
9022
|
+
const payload = isObject2(record3.payload) ? record3.payload : void 0;
|
|
9023
|
+
const timestamp = record3.timestamp ?? "";
|
|
9024
|
+
if (record3.type === "compacted") {
|
|
8767
9025
|
current = commitTurn(current);
|
|
8768
9026
|
pendingCompaction = "Conversation compacted";
|
|
8769
9027
|
lastTurnTimestamp = timestamp;
|
|
8770
9028
|
continue;
|
|
8771
9029
|
}
|
|
8772
|
-
if (
|
|
8773
|
-
if (
|
|
9030
|
+
if (record3.type === "world_state") continue;
|
|
9031
|
+
if (record3.type === "turn_context") {
|
|
8774
9032
|
current = commitTurn(current);
|
|
8775
9033
|
pendingContextIndex = index;
|
|
8776
9034
|
currentTurnId = typeof payload?.turn_id === "string" ? payload.turn_id : null;
|
|
@@ -8779,7 +9037,7 @@ function walkCodexRecords(records, options) {
|
|
|
8779
9037
|
sawTurnStart = true;
|
|
8780
9038
|
continue;
|
|
8781
9039
|
}
|
|
8782
|
-
if (
|
|
9040
|
+
if (record3.type === "event_msg" && payload?.type === "user_message" && typeof payload.message === "string") {
|
|
8783
9041
|
if (current && (current.assistantText.length > 0 || current.toolCalls.length > 0 || current.thinking.length > 0)) {
|
|
8784
9042
|
current = commitTurn(current);
|
|
8785
9043
|
}
|
|
@@ -8803,12 +9061,12 @@ function walkCodexRecords(records, options) {
|
|
|
8803
9061
|
lastTurnTimestamp = timestamp;
|
|
8804
9062
|
continue;
|
|
8805
9063
|
}
|
|
8806
|
-
if (!current && !recordOpensTurn(
|
|
9064
|
+
if (!current && !recordOpensTurn(record3, payload)) continue;
|
|
8807
9065
|
current ??= createActiveTurn(currentTurnId, timestamp, currentModel);
|
|
8808
9066
|
if (!current.model && currentModel) current.model = currentModel;
|
|
8809
9067
|
if (!current.timestamp) current.timestamp = timestamp;
|
|
8810
9068
|
if (timestamp) lastTurnTimestamp = timestamp;
|
|
8811
|
-
if (
|
|
9069
|
+
if (record3.type === "event_msg" && payload?.type === "token_count") {
|
|
8812
9070
|
const info = isObject2(payload.info) ? payload.info : null;
|
|
8813
9071
|
const lastUsage = info ? parseTokenUsage(info.last_token_usage) : null;
|
|
8814
9072
|
if (lastUsage) {
|
|
@@ -8816,14 +9074,14 @@ function walkCodexRecords(records, options) {
|
|
|
8816
9074
|
}
|
|
8817
9075
|
continue;
|
|
8818
9076
|
}
|
|
8819
|
-
if (
|
|
9077
|
+
if (record3.type === "event_msg" && payload?.type === "web_search_end" && typeof payload.call_id === "string") {
|
|
8820
9078
|
const input = {};
|
|
8821
9079
|
if (typeof payload.query === "string" && payload.query) input.query = payload.query;
|
|
8822
9080
|
if (isObject2(payload.action)) input.action = payload.action;
|
|
8823
9081
|
upsertWebSearchCall(current, payload.call_id, input, "completed", timestamp);
|
|
8824
9082
|
continue;
|
|
8825
9083
|
}
|
|
8826
|
-
if (
|
|
9084
|
+
if (record3.type === "event_msg" && payload?.type === "mcp_tool_call_end" && typeof payload.call_id === "string" && isObject2(payload.invocation)) {
|
|
8827
9085
|
const invocation = payload.invocation;
|
|
8828
9086
|
const server = typeof invocation.server === "string" ? invocation.server : "mcp";
|
|
8829
9087
|
const tool = typeof invocation.tool === "string" ? invocation.tool : "tool";
|
|
@@ -8846,7 +9104,7 @@ function walkCodexRecords(records, options) {
|
|
|
8846
9104
|
}
|
|
8847
9105
|
continue;
|
|
8848
9106
|
}
|
|
8849
|
-
if (
|
|
9107
|
+
if (record3.type === "event_msg" && payload?.type === "sub_agent_activity" && typeof payload.agent_thread_id === "string" && typeof payload.agent_path === "string") {
|
|
8850
9108
|
const agentId = payload.agent_thread_id;
|
|
8851
9109
|
const eventId2 = typeof payload.event_id === "string" ? payload.event_id : "";
|
|
8852
9110
|
const kind = typeof payload.kind === "string" ? payload.kind : "started";
|
|
@@ -8880,7 +9138,7 @@ function walkCodexRecords(records, options) {
|
|
|
8880
9138
|
upsertAgentMessage(agentId, current, timestamp, { status });
|
|
8881
9139
|
continue;
|
|
8882
9140
|
}
|
|
8883
|
-
if (
|
|
9141
|
+
if (record3.type !== "response_item" || !payload) continue;
|
|
8884
9142
|
if (payload.type === "reasoning") {
|
|
8885
9143
|
const summary = Array.isArray(payload.summary) ? payload.summary.filter((item) => typeof item === "string").join("\n") : "";
|
|
8886
9144
|
appendThinking(current, summary.trim(), timestamp);
|
|
@@ -9150,7 +9408,7 @@ function parseCodexSession(jsonlText, options) {
|
|
|
9150
9408
|
return session;
|
|
9151
9409
|
}
|
|
9152
9410
|
function appendCodexSession(existing, newJsonlText) {
|
|
9153
|
-
const prefix = existing.rawMessages.map((
|
|
9411
|
+
const prefix = existing.rawMessages.map((record3) => JSON.stringify(record3)).join("\n");
|
|
9154
9412
|
return parseCodexSession(prefix ? `${prefix}
|
|
9155
9413
|
${newJsonlText}` : newJsonlText);
|
|
9156
9414
|
}
|
|
@@ -9345,16 +9603,16 @@ async function readCodexSessionIdentity(filePath) {
|
|
|
9345
9603
|
let parentSessionId = null;
|
|
9346
9604
|
let sawSessionMeta = false;
|
|
9347
9605
|
for (const line of await readHeadLines(filePath, HEAD_BYTES)) {
|
|
9348
|
-
let
|
|
9606
|
+
let record3;
|
|
9349
9607
|
try {
|
|
9350
|
-
|
|
9608
|
+
record3 = JSON.parse(line);
|
|
9351
9609
|
} catch {
|
|
9352
9610
|
continue;
|
|
9353
9611
|
}
|
|
9354
|
-
if (!isRecord2(
|
|
9355
|
-
if (
|
|
9612
|
+
if (!isRecord2(record3) || !isRecord2(record3.payload)) continue;
|
|
9613
|
+
if (record3.type === "session_meta") {
|
|
9356
9614
|
sawSessionMeta = true;
|
|
9357
|
-
const payload =
|
|
9615
|
+
const payload = record3.payload;
|
|
9358
9616
|
if (!sessionId && typeof payload.id === "string") sessionId = payload.id;
|
|
9359
9617
|
if (!cwd && typeof payload.cwd === "string") cwd = payload.cwd;
|
|
9360
9618
|
if (!parentSessionId && typeof payload.forked_from_id === "string") {
|
|
@@ -9364,8 +9622,8 @@ async function readCodexSessionIdentity(filePath) {
|
|
|
9364
9622
|
if (source && isRecord2(source.subagent)) isSubagent = true;
|
|
9365
9623
|
const git = isRecord2(payload.git) ? payload.git : null;
|
|
9366
9624
|
if (!gitBranch && git && typeof git.branch === "string") gitBranch = git.branch;
|
|
9367
|
-
} else if (
|
|
9368
|
-
if (!cwd && typeof
|
|
9625
|
+
} else if (record3.type === "turn_context") {
|
|
9626
|
+
if (!cwd && typeof record3.payload.cwd === "string") cwd = record3.payload.cwd;
|
|
9369
9627
|
}
|
|
9370
9628
|
}
|
|
9371
9629
|
if (!sawSessionMeta || !cwd) return null;
|
|
@@ -10387,7 +10645,7 @@ function parseCopilotSession(jsonlText, options) {
|
|
|
10387
10645
|
};
|
|
10388
10646
|
}
|
|
10389
10647
|
function appendCopilotSession(existing, newJsonlText) {
|
|
10390
|
-
const prefix = existing.rawMessages.map((
|
|
10648
|
+
const prefix = existing.rawMessages.map((record3) => JSON.stringify(record3)).join("\n");
|
|
10391
10649
|
return parseCopilotSession(prefix ? `${prefix}
|
|
10392
10650
|
${newJsonlText}` : newJsonlText);
|
|
10393
10651
|
}
|
|
@@ -10495,11 +10753,11 @@ function brandCopilotBranch() {
|
|
|
10495
10753
|
function copilotTurnBoundaries(records) {
|
|
10496
10754
|
const boundaries = [];
|
|
10497
10755
|
for (let index = 0; index < records.length; index++) {
|
|
10498
|
-
const
|
|
10499
|
-
if (
|
|
10500
|
-
const data =
|
|
10756
|
+
const record3 = records[index];
|
|
10757
|
+
if (record3.type !== "user.message" || typeof record3.agentId === "string") continue;
|
|
10758
|
+
const data = record3.data;
|
|
10501
10759
|
if (!data || typeof data !== "object" || Array.isArray(data)) continue;
|
|
10502
|
-
if (typeof
|
|
10760
|
+
if (typeof record3.id !== "string" || !record3.id) continue;
|
|
10503
10761
|
boundaries.push(index);
|
|
10504
10762
|
}
|
|
10505
10763
|
return boundaries;
|
|
@@ -10556,14 +10814,14 @@ async function readCopilotSessionIdentity(filePath) {
|
|
|
10556
10814
|
let cwd = "";
|
|
10557
10815
|
let gitBranch = "";
|
|
10558
10816
|
for (const line of await readHeadLines(filePath, HEAD_BYTES)) {
|
|
10559
|
-
let
|
|
10817
|
+
let record3;
|
|
10560
10818
|
try {
|
|
10561
|
-
|
|
10819
|
+
record3 = JSON.parse(line);
|
|
10562
10820
|
} catch {
|
|
10563
10821
|
continue;
|
|
10564
10822
|
}
|
|
10565
|
-
if (!isRecord3(
|
|
10566
|
-
const data = isRecord3(
|
|
10823
|
+
if (!isRecord3(record3) || record3.type !== "session.start" && record3.type !== "session.resume") continue;
|
|
10824
|
+
const data = isRecord3(record3.data) ? record3.data : null;
|
|
10567
10825
|
if (!data) continue;
|
|
10568
10826
|
if (typeof data.sessionId === "string" && data.sessionId) sessionId = data.sessionId;
|
|
10569
10827
|
const context = isRecord3(data.context) ? data.context : null;
|
|
@@ -11926,9 +12184,9 @@ function nonEmpty(value) {
|
|
|
11926
12184
|
function stripTaggedBlocks(text) {
|
|
11927
12185
|
return text.replace(/<[^>]+>[\s\S]*?<\/[^>]+>/g, "").trim();
|
|
11928
12186
|
}
|
|
11929
|
-
function effortFromRecord(
|
|
12187
|
+
function effortFromRecord(record3) {
|
|
11930
12188
|
for (const kind of AGENT_KINDS) {
|
|
11931
|
-
const effort = READERS[kind].effort(
|
|
12189
|
+
const effort = READERS[kind].effort(record3);
|
|
11932
12190
|
if (effort) return effort;
|
|
11933
12191
|
}
|
|
11934
12192
|
return null;
|
|
@@ -11938,15 +12196,15 @@ function userMessageTextFromLine(line) {
|
|
|
11938
12196
|
(kind) => READERS[kind].userMessageMarkers.some((marker) => line.includes(marker))
|
|
11939
12197
|
);
|
|
11940
12198
|
if (candidates.length === 0) return null;
|
|
11941
|
-
let
|
|
12199
|
+
let record3;
|
|
11942
12200
|
try {
|
|
11943
|
-
|
|
12201
|
+
record3 = JSON.parse(line);
|
|
11944
12202
|
} catch {
|
|
11945
12203
|
return null;
|
|
11946
12204
|
}
|
|
11947
|
-
if (!isRecord4(
|
|
12205
|
+
if (!isRecord4(record3)) return null;
|
|
11948
12206
|
for (const kind of candidates) {
|
|
11949
|
-
const text = READERS[kind].userMessageText(
|
|
12207
|
+
const text = READERS[kind].userMessageText(record3);
|
|
11950
12208
|
if (text !== null) return text;
|
|
11951
12209
|
}
|
|
11952
12210
|
return null;
|
|
@@ -11958,11 +12216,11 @@ var init_recordReaders = __esm({
|
|
|
11958
12216
|
claudeReader = {
|
|
11959
12217
|
kind: "claude",
|
|
11960
12218
|
// Every assistant record is tagged with the effort that turn ran at.
|
|
11961
|
-
effort: (
|
|
12219
|
+
effort: (record3) => record3.type === "assistant" ? nonEmpty(record3.effort) : null,
|
|
11962
12220
|
userMessageMarkers: ['"user"'],
|
|
11963
|
-
userMessageText(
|
|
11964
|
-
if (
|
|
11965
|
-
const content = isRecord4(
|
|
12221
|
+
userMessageText(record3) {
|
|
12222
|
+
if (record3.type !== "user" || record3.isMeta) return null;
|
|
12223
|
+
const content = isRecord4(record3.message) ? record3.message.content : void 0;
|
|
11966
12224
|
if (typeof content === "string") return stripTaggedBlocks(content);
|
|
11967
12225
|
if (!Array.isArray(content)) return "";
|
|
11968
12226
|
let text = "";
|
|
@@ -11977,32 +12235,32 @@ var init_recordReaders = __esm({
|
|
|
11977
12235
|
codexReader = {
|
|
11978
12236
|
kind: "codex",
|
|
11979
12237
|
// Effort is recorded per turn; newer CLI versions moved it under `thread_settings`.
|
|
11980
|
-
effort(
|
|
11981
|
-
if (
|
|
11982
|
-
const { payload } =
|
|
12238
|
+
effort(record3) {
|
|
12239
|
+
if (record3.type !== "turn_context" || !isRecord4(record3.payload)) return null;
|
|
12240
|
+
const { payload } = record3;
|
|
11983
12241
|
const direct = nonEmpty(payload.effort);
|
|
11984
12242
|
if (direct) return direct;
|
|
11985
12243
|
const settings = isRecord4(payload.thread_settings) ? payload.thread_settings : null;
|
|
11986
12244
|
return nonEmpty(settings?.reasoning_effort);
|
|
11987
12245
|
},
|
|
11988
12246
|
userMessageMarkers: ['"event_msg"'],
|
|
11989
|
-
userMessageText(
|
|
11990
|
-
if (
|
|
11991
|
-
const { payload } =
|
|
12247
|
+
userMessageText(record3) {
|
|
12248
|
+
if (record3.type !== "event_msg" || !isRecord4(record3.payload)) return null;
|
|
12249
|
+
const { payload } = record3;
|
|
11992
12250
|
return payload.type === "user_message" && typeof payload.message === "string" ? payload.message.trim() : null;
|
|
11993
12251
|
}
|
|
11994
12252
|
};
|
|
11995
12253
|
copilotReader = {
|
|
11996
12254
|
kind: "copilot",
|
|
11997
|
-
effort(
|
|
11998
|
-
if (
|
|
11999
|
-
return nonEmpty(
|
|
12255
|
+
effort(record3) {
|
|
12256
|
+
if (record3.type !== "session.start" && record3.type !== "session.resume" && record3.type !== "session.model_change" || !isRecord4(record3.data)) return null;
|
|
12257
|
+
return nonEmpty(record3.data.reasoningEffort ?? record3.data.effort);
|
|
12000
12258
|
},
|
|
12001
12259
|
userMessageMarkers: ['"user.message"'],
|
|
12002
|
-
userMessageText(
|
|
12003
|
-
if (
|
|
12004
|
-
if (typeof
|
|
12005
|
-
const data = isRecord4(
|
|
12260
|
+
userMessageText(record3) {
|
|
12261
|
+
if (record3.type !== "user.message") return null;
|
|
12262
|
+
if (typeof record3.agentId === "string" && record3.agentId) return null;
|
|
12263
|
+
const data = isRecord4(record3.data) ? record3.data : null;
|
|
12006
12264
|
return typeof data?.content === "string" ? data.content.trim() : "";
|
|
12007
12265
|
}
|
|
12008
12266
|
};
|
|
@@ -12015,16 +12273,16 @@ var init_recordReaders = __esm({
|
|
|
12015
12273
|
});
|
|
12016
12274
|
|
|
12017
12275
|
// ../../server/agents/tailRecords.ts
|
|
12018
|
-
function isSubagentLifecycle(
|
|
12019
|
-
return
|
|
12276
|
+
function isSubagentLifecycle(record3) {
|
|
12277
|
+
return record3.type.startsWith("subagent.") && typeof record3.agentId === "string" && record3.agentId.length > 0;
|
|
12020
12278
|
}
|
|
12021
|
-
function isSubagentNoise(
|
|
12022
|
-
return typeof
|
|
12279
|
+
function isSubagentNoise(record3) {
|
|
12280
|
+
return typeof record3.agentId === "string" && record3.agentId.length > 0;
|
|
12023
12281
|
}
|
|
12024
|
-
function classifyTailRecord(
|
|
12282
|
+
function classifyTailRecord(record3) {
|
|
12025
12283
|
for (const kind of AGENT_KINDS) {
|
|
12026
12284
|
const format = TAIL_FORMATS[kind];
|
|
12027
|
-
const verdict = format.classify(
|
|
12285
|
+
const verdict = format.classify(record3);
|
|
12028
12286
|
if (verdict.kind !== "ignore") return { format, verdict };
|
|
12029
12287
|
}
|
|
12030
12288
|
return null;
|
|
@@ -12041,31 +12299,31 @@ var init_tailRecords = __esm({
|
|
|
12041
12299
|
// Background agent/workflow launches, task notifications and TaskStop calls
|
|
12042
12300
|
// can all still change a verdict that a turn-ending line looked to settle.
|
|
12043
12301
|
markers: ["async_launched", "task-notification", '"TaskStop"'],
|
|
12044
|
-
classify(
|
|
12045
|
-
if (
|
|
12046
|
-
const reason =
|
|
12302
|
+
classify(record3) {
|
|
12303
|
+
if (record3.type === "system" && record3.subtype === "terminal_reason") {
|
|
12304
|
+
const reason = record3.reason;
|
|
12047
12305
|
return reason ? { kind: "final", status: { status: "completed", terminalReason: reason } } : IGNORE;
|
|
12048
12306
|
}
|
|
12049
|
-
if (
|
|
12050
|
-
const data =
|
|
12307
|
+
if (record3.type === "progress") {
|
|
12308
|
+
const data = record3.data;
|
|
12051
12309
|
if (data?.type !== "hook_progress") return IGNORE;
|
|
12052
12310
|
const decision = data.decision ?? data.hookSpecificOutput?.permissionDecision;
|
|
12053
12311
|
return decision === "defer" ? ANSWER : IGNORE;
|
|
12054
12312
|
}
|
|
12055
|
-
if (
|
|
12056
|
-
if (
|
|
12057
|
-
const stopReason =
|
|
12058
|
-
if (
|
|
12313
|
+
if (record3.type === "attachment") return KEEP;
|
|
12314
|
+
if (record3.type === "assistant" || record3.type === "user" || record3.type === "queue-operation") {
|
|
12315
|
+
const stopReason = record3.message?.stop_reason;
|
|
12316
|
+
if (record3.type === "assistant" && stopReason === "end_turn") {
|
|
12059
12317
|
return { kind: "turn-end", awaitUserActivity: true };
|
|
12060
12318
|
}
|
|
12061
|
-
const canDerive =
|
|
12319
|
+
const canDerive = record3.type === "assistant" || record3.type === "user" && !record3.isMeta;
|
|
12062
12320
|
return canDerive ? ANSWER : KEEP;
|
|
12063
12321
|
}
|
|
12064
12322
|
return IGNORE;
|
|
12065
12323
|
},
|
|
12066
|
-
classifyAfterTurnEnd(
|
|
12067
|
-
if (
|
|
12068
|
-
const isRealUserTurn =
|
|
12324
|
+
classifyAfterTurnEnd(record3) {
|
|
12325
|
+
if (record3.type !== "user" && record3.type !== "assistant" && record3.type !== "queue-operation" && record3.type !== "attachment") return IGNORE;
|
|
12326
|
+
const isRealUserTurn = record3.type === "user" && !record3.isMeta;
|
|
12069
12327
|
return { kind: "keep", sawUserActivity: isRealUserTurn };
|
|
12070
12328
|
}
|
|
12071
12329
|
};
|
|
@@ -12084,9 +12342,9 @@ var init_tailRecords = __esm({
|
|
|
12084
12342
|
"agent_message",
|
|
12085
12343
|
"function_call_output"
|
|
12086
12344
|
],
|
|
12087
|
-
classify(
|
|
12088
|
-
if (
|
|
12089
|
-
const payload =
|
|
12345
|
+
classify(record3) {
|
|
12346
|
+
if (record3.type === "event_msg") {
|
|
12347
|
+
const payload = record3.payload;
|
|
12090
12348
|
switch (payload?.type) {
|
|
12091
12349
|
case "task_complete":
|
|
12092
12350
|
return { kind: "turn-end" };
|
|
@@ -12098,32 +12356,32 @@ var init_tailRecords = __esm({
|
|
|
12098
12356
|
return IGNORE;
|
|
12099
12357
|
}
|
|
12100
12358
|
}
|
|
12101
|
-
if (
|
|
12102
|
-
const payload =
|
|
12359
|
+
if (record3.type === "response_item") {
|
|
12360
|
+
const payload = record3.payload;
|
|
12103
12361
|
const decides = payload?.type === "function_call" || payload?.type === "message" && (payload.role === "assistant" || payload.role === "user");
|
|
12104
12362
|
return decides ? ANSWER : IGNORE;
|
|
12105
12363
|
}
|
|
12106
12364
|
return IGNORE;
|
|
12107
12365
|
},
|
|
12108
|
-
classifyAfterTurnEnd(
|
|
12109
|
-
return
|
|
12366
|
+
classifyAfterTurnEnd(record3) {
|
|
12367
|
+
return record3.type === "event_msg" || record3.type === "response_item" ? KEEP : IGNORE;
|
|
12110
12368
|
}
|
|
12111
12369
|
};
|
|
12112
12370
|
copilotTail = {
|
|
12113
12371
|
kind: "copilot",
|
|
12114
12372
|
markers: ['"abort"', '"assistant.message"', '"user.message"', '"subagent.'],
|
|
12115
|
-
classify(
|
|
12116
|
-
if (isSubagentLifecycle(
|
|
12117
|
-
const decidable =
|
|
12118
|
-
if (!decidable || isSubagentNoise(
|
|
12119
|
-
if (
|
|
12120
|
-
if (
|
|
12373
|
+
classify(record3) {
|
|
12374
|
+
if (isSubagentLifecycle(record3)) return KEEP;
|
|
12375
|
+
const decidable = record3.type === "abort" || record3.type === "user.message" || record3.type.startsWith("assistant.") || record3.type.startsWith("permission.") || record3.type.startsWith("session.") || record3.type.startsWith("tool.") || record3.type.startsWith("user_input.");
|
|
12376
|
+
if (!decidable || isSubagentNoise(record3)) return IGNORE;
|
|
12377
|
+
if (record3.type === "assistant.turn_end") return { kind: "turn-end" };
|
|
12378
|
+
if (record3.type === "session.start" || record3.type === "session.resume") return ANSWER;
|
|
12121
12379
|
return { kind: "answer-if-active" };
|
|
12122
12380
|
},
|
|
12123
|
-
classifyAfterTurnEnd(
|
|
12124
|
-
if (isSubagentLifecycle(
|
|
12125
|
-
if (isSubagentNoise(
|
|
12126
|
-
const decides =
|
|
12381
|
+
classifyAfterTurnEnd(record3) {
|
|
12382
|
+
if (isSubagentLifecycle(record3)) return KEEP;
|
|
12383
|
+
if (isSubagentNoise(record3)) return IGNORE;
|
|
12384
|
+
const decides = record3.type === "abort" || record3.type === "assistant.message" || record3.type === "user.message";
|
|
12127
12385
|
return decides ? ANSWER : IGNORE;
|
|
12128
12386
|
}
|
|
12129
12387
|
};
|
|
@@ -12178,14 +12436,14 @@ async function readTranscriptEffort(filePath) {
|
|
|
12178
12436
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
12179
12437
|
const line = lines[i];
|
|
12180
12438
|
if (!line || !line.includes("effort") && !line.includes("Effort")) continue;
|
|
12181
|
-
let
|
|
12439
|
+
let record3;
|
|
12182
12440
|
try {
|
|
12183
|
-
|
|
12441
|
+
record3 = JSON.parse(line);
|
|
12184
12442
|
} catch {
|
|
12185
12443
|
continue;
|
|
12186
12444
|
}
|
|
12187
|
-
if (typeof
|
|
12188
|
-
const effort = effortFromRecord(
|
|
12445
|
+
if (typeof record3 !== "object" || record3 === null) continue;
|
|
12446
|
+
const effort = effortFromRecord(record3);
|
|
12189
12447
|
if (effort) return effort;
|
|
12190
12448
|
}
|
|
12191
12449
|
}
|
|
@@ -12221,14 +12479,14 @@ async function getSessionStatus(filePath) {
|
|
|
12221
12479
|
const line = lines[i];
|
|
12222
12480
|
if (!line) continue;
|
|
12223
12481
|
if (turnEnded && !isTailCandidate(line, turnEnded)) continue;
|
|
12224
|
-
let
|
|
12482
|
+
let record3;
|
|
12225
12483
|
try {
|
|
12226
|
-
|
|
12484
|
+
record3 = JSON.parse(line);
|
|
12227
12485
|
} catch {
|
|
12228
12486
|
continue;
|
|
12229
12487
|
}
|
|
12230
|
-
if (typeof
|
|
12231
|
-
const match = turnEnded ? { format: turnEnded, verdict: turnEnded.classifyAfterTurnEnd(
|
|
12488
|
+
if (typeof record3?.type !== "string") continue;
|
|
12489
|
+
const match = turnEnded ? { format: turnEnded, verdict: turnEnded.classifyAfterTurnEnd(record3) } : classifyTailRecord(record3);
|
|
12232
12490
|
if (!match) continue;
|
|
12233
12491
|
const { verdict } = match;
|
|
12234
12492
|
switch (verdict.kind) {
|
|
@@ -12237,20 +12495,20 @@ async function getSessionStatus(filePath) {
|
|
|
12237
12495
|
case "final":
|
|
12238
12496
|
return verdict.status;
|
|
12239
12497
|
case "keep":
|
|
12240
|
-
meaningful.unshift(
|
|
12498
|
+
meaningful.unshift(record3);
|
|
12241
12499
|
if (verdict.sawUserActivity) needUserActivity = false;
|
|
12242
12500
|
continue;
|
|
12243
12501
|
case "answer":
|
|
12244
|
-
meaningful.unshift(
|
|
12502
|
+
meaningful.unshift(record3);
|
|
12245
12503
|
return deriveSessionStatus(meaningful);
|
|
12246
12504
|
case "answer-if-active": {
|
|
12247
|
-
meaningful.unshift(
|
|
12505
|
+
meaningful.unshift(record3);
|
|
12248
12506
|
const status = deriveSessionStatus(meaningful);
|
|
12249
12507
|
if (status.status !== "idle") return status;
|
|
12250
12508
|
continue;
|
|
12251
12509
|
}
|
|
12252
12510
|
case "turn-end":
|
|
12253
|
-
meaningful.unshift(
|
|
12511
|
+
meaningful.unshift(record3);
|
|
12254
12512
|
turnEnded = match.format;
|
|
12255
12513
|
needUserActivity = verdict.awaitUserActivity === true;
|
|
12256
12514
|
continue;
|
|
@@ -12352,7 +12610,7 @@ var init_sessionPaths = __esm({
|
|
|
12352
12610
|
});
|
|
12353
12611
|
|
|
12354
12612
|
// ../../server/helpers.ts
|
|
12355
|
-
import { spawn } from "node:child_process";
|
|
12613
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
12356
12614
|
import { homedir as homedir4 } from "node:os";
|
|
12357
12615
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
12358
12616
|
import { createInterface } from "node:readline";
|
|
@@ -12525,7 +12783,7 @@ async function fetchClaudeModels() {
|
|
|
12525
12783
|
}
|
|
12526
12784
|
var init_claudeModels = __esm({
|
|
12527
12785
|
"../../server/agents/claudeModels.ts"() {
|
|
12528
|
-
|
|
12786
|
+
init_claudeExecutable();
|
|
12529
12787
|
init_modelCatalog();
|
|
12530
12788
|
init_timeout();
|
|
12531
12789
|
init_model_names();
|
|
@@ -12634,7 +12892,7 @@ function startOneShot(req) {
|
|
|
12634
12892
|
]);
|
|
12635
12893
|
const cleanEnv = { ...process.env };
|
|
12636
12894
|
delete cleanEnv.CLAUDECODE;
|
|
12637
|
-
const child =
|
|
12895
|
+
const child = spawn2(cli.command, cli.args, {
|
|
12638
12896
|
cwd: req.cwd,
|
|
12639
12897
|
env: cleanEnv,
|
|
12640
12898
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -12795,6 +13053,7 @@ var init_claudeRuntime = __esm({
|
|
|
12795
13053
|
"../../server/agents/claudeRuntime.ts"() {
|
|
12796
13054
|
init_agent_descriptors();
|
|
12797
13055
|
init_helpers();
|
|
13056
|
+
init_claudeExecutable();
|
|
12798
13057
|
init_claudeModels();
|
|
12799
13058
|
init_spawnError();
|
|
12800
13059
|
init_binaryResolver();
|
|
@@ -12941,7 +13200,7 @@ var init_package = __esm({
|
|
|
12941
13200
|
package_default = {
|
|
12942
13201
|
name: "cogpit",
|
|
12943
13202
|
private: true,
|
|
12944
|
-
version: "2.1
|
|
13203
|
+
version: "2.2.1",
|
|
12945
13204
|
description: "Control center for Claude Code, OpenAI Codex, and GitHub Copilot CLI sessions",
|
|
12946
13205
|
license: "MIT",
|
|
12947
13206
|
author: {
|
|
@@ -13051,11 +13310,11 @@ var init_package = __esm({
|
|
|
13051
13310
|
overrides: {
|
|
13052
13311
|
"@babel/core": "7.29.7",
|
|
13053
13312
|
"@hono/node-server": "1.19.15",
|
|
13054
|
-
"@xmldom/xmldom": "0.8.
|
|
13313
|
+
"@xmldom/xmldom": "0.8.15",
|
|
13055
13314
|
"app-builder-lib": "26.15.3",
|
|
13056
13315
|
"body-parser": "2.3.0",
|
|
13057
13316
|
"builder-util-runtime": "9.7.0",
|
|
13058
|
-
"fast-uri": "
|
|
13317
|
+
"fast-uri": "4.1.4",
|
|
13059
13318
|
flatted: "3.4.2",
|
|
13060
13319
|
"form-data": "4.0.6",
|
|
13061
13320
|
hono: "4.13.1",
|
|
@@ -13064,7 +13323,7 @@ var init_package = __esm({
|
|
|
13064
13323
|
lodash: "4.18.1",
|
|
13065
13324
|
nanoid: "3.3.18",
|
|
13066
13325
|
postcss: "8.5.26",
|
|
13067
|
-
qs: "6.
|
|
13326
|
+
qs: "6.16.0",
|
|
13068
13327
|
tar: "7.5.21",
|
|
13069
13328
|
tmp: "0.2.7",
|
|
13070
13329
|
undici: "7.29.0"
|
|
@@ -13180,101 +13439,6 @@ var init_codexStreamAdapter = __esm({
|
|
|
13180
13439
|
}
|
|
13181
13440
|
});
|
|
13182
13441
|
|
|
13183
|
-
// ../../shared/versions.ts
|
|
13184
|
-
function parseVersion(raw) {
|
|
13185
|
-
const match = raw.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
|
|
13186
|
-
if (!match) return null;
|
|
13187
|
-
return {
|
|
13188
|
-
parts: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
13189
|
-
prerelease: match[4] ? match[4].split(".") : []
|
|
13190
|
-
};
|
|
13191
|
-
}
|
|
13192
|
-
function extractVersion(output) {
|
|
13193
|
-
const match = output.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
13194
|
-
return match ? match[0] : null;
|
|
13195
|
-
}
|
|
13196
|
-
function comparePrerelease(a, b) {
|
|
13197
|
-
if (a.length === 0 && b.length === 0) return 0;
|
|
13198
|
-
if (a.length === 0) return 1;
|
|
13199
|
-
if (b.length === 0) return -1;
|
|
13200
|
-
for (let i = 0; i < Math.max(a.length, b.length); i += 1) {
|
|
13201
|
-
const left = a[i];
|
|
13202
|
-
const right = b[i];
|
|
13203
|
-
if (left === void 0) return -1;
|
|
13204
|
-
if (right === void 0) return 1;
|
|
13205
|
-
const leftNumeric = /^\d+$/.test(left);
|
|
13206
|
-
const rightNumeric = /^\d+$/.test(right);
|
|
13207
|
-
if (leftNumeric && rightNumeric) {
|
|
13208
|
-
if (Number(left) !== Number(right)) return Number(left) < Number(right) ? -1 : 1;
|
|
13209
|
-
continue;
|
|
13210
|
-
}
|
|
13211
|
-
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
13212
|
-
if (left !== right) return left < right ? -1 : 1;
|
|
13213
|
-
}
|
|
13214
|
-
return 0;
|
|
13215
|
-
}
|
|
13216
|
-
function compareVersions(a, b) {
|
|
13217
|
-
const left = parseVersion(a);
|
|
13218
|
-
const right = parseVersion(b);
|
|
13219
|
-
if (!left || !right) return null;
|
|
13220
|
-
for (let i = 0; i < 3; i += 1) {
|
|
13221
|
-
if (left.parts[i] !== right.parts[i]) return left.parts[i] < right.parts[i] ? -1 : 1;
|
|
13222
|
-
}
|
|
13223
|
-
return comparePrerelease(left.prerelease, right.prerelease);
|
|
13224
|
-
}
|
|
13225
|
-
var init_versions = __esm({
|
|
13226
|
-
"../../shared/versions.ts"() {
|
|
13227
|
-
}
|
|
13228
|
-
});
|
|
13229
|
-
|
|
13230
|
-
// ../../server/lib/cliProcess.ts
|
|
13231
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
13232
|
-
function runCli(executable, args, timeoutMs) {
|
|
13233
|
-
return new Promise((resolve21) => {
|
|
13234
|
-
const resolved = resolveAgentCommand(executable, [...args]);
|
|
13235
|
-
const child = spawn2(resolved.command, resolved.args, {
|
|
13236
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
13237
|
-
...resolved.spawnOptions
|
|
13238
|
-
});
|
|
13239
|
-
let stdout = "";
|
|
13240
|
-
let stderr = "";
|
|
13241
|
-
let timedOut = false;
|
|
13242
|
-
const timer = setTimeout(() => {
|
|
13243
|
-
timedOut = true;
|
|
13244
|
-
child.kill("SIGKILL");
|
|
13245
|
-
}, timeoutMs);
|
|
13246
|
-
const append = (buffer, chunk) => buffer.length >= CLI_OUTPUT_MAX_CHARS ? buffer : buffer + chunk.toString();
|
|
13247
|
-
child.stdout?.on("data", (chunk) => {
|
|
13248
|
-
stdout = append(stdout, chunk);
|
|
13249
|
-
});
|
|
13250
|
-
child.stderr?.on("data", (chunk) => {
|
|
13251
|
-
stderr = append(stderr, chunk);
|
|
13252
|
-
});
|
|
13253
|
-
child.on("error", () => {
|
|
13254
|
-
clearTimeout(timer);
|
|
13255
|
-
resolve21({ code: null, stdout, stderr, timedOut });
|
|
13256
|
-
});
|
|
13257
|
-
child.on("close", (code) => {
|
|
13258
|
-
clearTimeout(timer);
|
|
13259
|
-
resolve21({ code, stdout, stderr, timedOut });
|
|
13260
|
-
});
|
|
13261
|
-
});
|
|
13262
|
-
}
|
|
13263
|
-
async function probeCliVersion(command, versionArgs, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
|
|
13264
|
-
const probe = await runCli(command, versionArgs, timeoutMs);
|
|
13265
|
-
return extractVersion(`${probe.stdout}
|
|
13266
|
-
${probe.stderr}`);
|
|
13267
|
-
}
|
|
13268
|
-
var DEFAULT_PROBE_TIMEOUT_MS, CLI_OUTPUT_MAX_CHARS;
|
|
13269
|
-
var init_cliProcess = __esm({
|
|
13270
|
-
"../../server/lib/cliProcess.ts"() {
|
|
13271
|
-
init_versions();
|
|
13272
|
-
init_binaryResolver();
|
|
13273
|
-
DEFAULT_PROBE_TIMEOUT_MS = 5e3;
|
|
13274
|
-
CLI_OUTPUT_MAX_CHARS = 1e4;
|
|
13275
|
-
}
|
|
13276
|
-
});
|
|
13277
|
-
|
|
13278
13442
|
// ../../server/lib/codexVersion.ts
|
|
13279
13443
|
function parseUserAgentVersion(userAgent) {
|
|
13280
13444
|
if (typeof userAgent !== "string") return null;
|
|
@@ -14505,7 +14669,7 @@ async function startLegacy(req, knownPaths) {
|
|
|
14505
14669
|
...args.turnArgs,
|
|
14506
14670
|
...args.promptArgs
|
|
14507
14671
|
]);
|
|
14508
|
-
const child =
|
|
14672
|
+
const child = spawn2(cli.command, cli.args, {
|
|
14509
14673
|
cwd: req.cwd,
|
|
14510
14674
|
env: process.env,
|
|
14511
14675
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -14597,7 +14761,7 @@ async function sendLegacy(sessionId, req) {
|
|
|
14597
14761
|
sessionId,
|
|
14598
14762
|
...args.promptArgs
|
|
14599
14763
|
]);
|
|
14600
|
-
const child =
|
|
14764
|
+
const child = spawn2(cli.command, cli.args, {
|
|
14601
14765
|
cwd: req.cwd,
|
|
14602
14766
|
env: process.env,
|
|
14603
14767
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -16040,17 +16204,17 @@ function parseJsonRecord(line) {
|
|
|
16040
16204
|
}
|
|
16041
16205
|
}
|
|
16042
16206
|
function parseClaudeUsageLine(line) {
|
|
16043
|
-
const
|
|
16044
|
-
if (!
|
|
16045
|
-
const message = asRecord3(
|
|
16207
|
+
const record3 = parseJsonRecord(line);
|
|
16208
|
+
if (!record3 || record3.type !== "assistant") return null;
|
|
16209
|
+
const message = asRecord3(record3.message);
|
|
16046
16210
|
const usage = message ? asRecord3(message.usage) : null;
|
|
16047
16211
|
if (!message || !usage) return null;
|
|
16048
|
-
const timestampMs = parseTimestampMs(
|
|
16212
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16049
16213
|
if (timestampMs === null) return null;
|
|
16050
16214
|
const model = typeof message.model === "string" ? message.model : "";
|
|
16051
16215
|
if (model.length === 0) return null;
|
|
16052
16216
|
const messageId = typeof message.id === "string" ? message.id : null;
|
|
16053
|
-
const requestId = typeof
|
|
16217
|
+
const requestId = typeof record3.requestId === "string" ? record3.requestId : null;
|
|
16054
16218
|
const dedupeKey = messageId === null && requestId === null ? null : `${messageId ?? ""}:${requestId ?? ""}`;
|
|
16055
16219
|
const cacheCreationTokens = int(usage.cache_creation_input_tokens);
|
|
16056
16220
|
const byTtl = asRecord3(usage.cache_creation);
|
|
@@ -16069,12 +16233,12 @@ function parseClaudeUsageLine(line) {
|
|
|
16069
16233
|
reasoningTokens: 0
|
|
16070
16234
|
};
|
|
16071
16235
|
if (totalUsageCostTokens(totals) === 0) return null;
|
|
16072
|
-
const cost =
|
|
16236
|
+
const cost = record3.costUSD;
|
|
16073
16237
|
return {
|
|
16074
16238
|
provider: "claude",
|
|
16075
16239
|
timestampMs,
|
|
16076
16240
|
model,
|
|
16077
|
-
sessionId: typeof
|
|
16241
|
+
sessionId: typeof record3.sessionId === "string" ? record3.sessionId : "",
|
|
16078
16242
|
totals,
|
|
16079
16243
|
reportedCostUsd: typeof cost === "number" && Number.isFinite(cost) ? cost : null,
|
|
16080
16244
|
dedupeKey
|
|
@@ -16096,30 +16260,30 @@ function isForkedSessionMeta(payload) {
|
|
|
16096
16260
|
return typeof spawn5?.parent_thread_id === "string";
|
|
16097
16261
|
}
|
|
16098
16262
|
function parseCodexUsageLine(line, state) {
|
|
16099
|
-
const
|
|
16100
|
-
if (!
|
|
16101
|
-
const payload = asRecord3(
|
|
16263
|
+
const record3 = parseJsonRecord(line);
|
|
16264
|
+
if (!record3) return null;
|
|
16265
|
+
const payload = asRecord3(record3.payload);
|
|
16102
16266
|
if (!payload) return null;
|
|
16103
|
-
if (
|
|
16267
|
+
if (record3.type === "session_meta") {
|
|
16104
16268
|
if (state.sawSessionMeta) return null;
|
|
16105
16269
|
state.sawSessionMeta = true;
|
|
16106
16270
|
const id = payload.id ?? payload.session_id;
|
|
16107
16271
|
if (typeof id === "string") state.sessionId = id;
|
|
16108
|
-
const metaTimestampMs = parseTimestampMs(
|
|
16272
|
+
const metaTimestampMs = parseTimestampMs(record3.timestamp);
|
|
16109
16273
|
if (metaTimestampMs !== null && isForkedSessionMeta(payload)) {
|
|
16110
16274
|
state.suppressingForkCopies = true;
|
|
16111
16275
|
state.forkCopyAnchorMs = metaTimestampMs;
|
|
16112
16276
|
}
|
|
16113
16277
|
return null;
|
|
16114
16278
|
}
|
|
16115
|
-
if (
|
|
16279
|
+
if (record3.type === "turn_context") {
|
|
16116
16280
|
if (typeof payload.model === "string") state.model = payload.model;
|
|
16117
16281
|
return null;
|
|
16118
16282
|
}
|
|
16119
16283
|
if (payload.type !== "token_count") return null;
|
|
16120
16284
|
const last = asRecord3(asRecord3(payload.info)?.last_token_usage);
|
|
16121
16285
|
if (!last) return null;
|
|
16122
|
-
const timestampMs = parseTimestampMs(
|
|
16286
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16123
16287
|
if (timestampMs === null) return null;
|
|
16124
16288
|
if (state.model.length === 0) return null;
|
|
16125
16289
|
const signature = JSON.stringify(last);
|
|
@@ -16218,17 +16382,17 @@ function parseCopilotUsageMetrics(value, state, timestampMs) {
|
|
|
16218
16382
|
return records;
|
|
16219
16383
|
}
|
|
16220
16384
|
function parseCopilotUsageLine(line, state) {
|
|
16221
|
-
const
|
|
16222
|
-
if (!
|
|
16223
|
-
const data = asRecord3(
|
|
16385
|
+
const record3 = parseJsonRecord(line);
|
|
16386
|
+
if (!record3 || typeof record3.agentId === "string" && record3.agentId.length > 0) return [];
|
|
16387
|
+
const data = asRecord3(record3.data);
|
|
16224
16388
|
if (!data) return [];
|
|
16225
|
-
if (
|
|
16389
|
+
if (record3.type === "session.start") {
|
|
16226
16390
|
const sessionId = data.sessionId;
|
|
16227
16391
|
if (typeof sessionId === "string" && sessionId.length > 0) state.sessionId = sessionId;
|
|
16228
16392
|
return [];
|
|
16229
16393
|
}
|
|
16230
|
-
if (
|
|
16231
|
-
const timestampMs = parseTimestampMs(
|
|
16394
|
+
if (record3.type !== "session.shutdown") return [];
|
|
16395
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16232
16396
|
return timestampMs === null ? [] : parseCopilotUsageMetrics(data, state, timestampMs);
|
|
16233
16397
|
}
|
|
16234
16398
|
function createUsageScanner(provider, filePath) {
|
|
@@ -16245,8 +16409,8 @@ var init_usageScanners = __esm({
|
|
|
16245
16409
|
// object, so a line is either self-contained or of no interest.
|
|
16246
16410
|
wantsLine: (line) => line.includes('"usage"'),
|
|
16247
16411
|
accept: (line) => {
|
|
16248
|
-
const
|
|
16249
|
-
return
|
|
16412
|
+
const record3 = parseClaudeUsageLine(line);
|
|
16413
|
+
return record3 === null ? [] : [record3];
|
|
16250
16414
|
}
|
|
16251
16415
|
}),
|
|
16252
16416
|
codex: () => {
|
|
@@ -16257,8 +16421,8 @@ var init_usageScanners = __esm({
|
|
|
16257
16421
|
// at all but still have to reach the reducer.
|
|
16258
16422
|
wantsLine: (line) => line.includes('"token_count"') || line.includes('"turn_context"') || line.includes('"session_meta"'),
|
|
16259
16423
|
accept: (line) => {
|
|
16260
|
-
const
|
|
16261
|
-
return
|
|
16424
|
+
const record3 = parseCodexUsageLine(line, state);
|
|
16425
|
+
return record3 === null ? [] : [record3];
|
|
16262
16426
|
}
|
|
16263
16427
|
};
|
|
16264
16428
|
},
|
|
@@ -17140,11 +17304,11 @@ function registerRunningProcessesRoute(use) {
|
|
|
17140
17304
|
if (url.pathname.split("/").filter(Boolean).length > 0) return next();
|
|
17141
17305
|
const isWindows2 = process.platform === "win32";
|
|
17142
17306
|
const nameFilter = allDescriptors().map(windowsProcessNameFilter).join(" or ");
|
|
17143
|
-
const child = isWindows2 ?
|
|
17307
|
+
const child = isWindows2 ? spawn2("powershell", [
|
|
17144
17308
|
"-NoProfile",
|
|
17145
17309
|
"-Command",
|
|
17146
17310
|
`Get-CimInstance Win32_Process -Filter "${nameFilter}" | Select-Object ProcessId, WorkingSetSize, CommandLine | ConvertTo-Json -Compress`
|
|
17147
|
-
]) :
|
|
17311
|
+
]) : spawn2("ps", ["aux"]);
|
|
17148
17312
|
let stdout = "";
|
|
17149
17313
|
let responded = false;
|
|
17150
17314
|
child.stdout?.on("data", (data) => {
|
|
@@ -17507,12 +17671,12 @@ function registerBranchSessionRoute(use) {
|
|
|
17507
17671
|
}
|
|
17508
17672
|
}
|
|
17509
17673
|
const newSessionId = randomUUID2();
|
|
17510
|
-
const { record:
|
|
17674
|
+
const { record: record3, originalId } = format.brandBranch(
|
|
17511
17675
|
JSON.parse(lines[0]),
|
|
17512
17676
|
newSessionId,
|
|
17513
17677
|
turnIndex ?? null
|
|
17514
17678
|
);
|
|
17515
|
-
lines[0] = JSON.stringify(
|
|
17679
|
+
lines[0] = JSON.stringify(record3);
|
|
17516
17680
|
const target = storeForDirName(dirName).transcriptPath(dirName, newSessionId);
|
|
17517
17681
|
if (!target) {
|
|
17518
17682
|
res.statusCode = 500;
|
|
@@ -18055,11 +18219,11 @@ import {
|
|
|
18055
18219
|
dirname as dirname5,
|
|
18056
18220
|
isAbsolute as isAbsolute3,
|
|
18057
18221
|
join as join13,
|
|
18058
|
-
posix as
|
|
18222
|
+
posix as posix3,
|
|
18059
18223
|
relative as relative4,
|
|
18060
18224
|
resolve as resolve9,
|
|
18061
18225
|
sep as sep5,
|
|
18062
|
-
win32 as
|
|
18226
|
+
win32 as win323
|
|
18063
18227
|
} from "node:path";
|
|
18064
18228
|
function configuredAgentHomes() {
|
|
18065
18229
|
return new Set(AGENT_KINDS.map((kind) => agentHomeDir(kind)));
|
|
@@ -18168,7 +18332,7 @@ async function resolveConfigBrowserPath(filePath, options = {}) {
|
|
|
18168
18332
|
function isSafeConfigName(name) {
|
|
18169
18333
|
if (!name || name === "." || name === ".." || name.includes("\0")) return false;
|
|
18170
18334
|
if (name.includes("/") || name.includes("\\")) return false;
|
|
18171
|
-
if (isAbsolute3(name) ||
|
|
18335
|
+
if (isAbsolute3(name) || posix3.parse(name).root || win323.parse(name).root) return false;
|
|
18172
18336
|
return true;
|
|
18173
18337
|
}
|
|
18174
18338
|
function isUnderDir(parentDir, dirName) {
|
|
@@ -19411,7 +19575,8 @@ function registerConfigRoutes(use) {
|
|
|
19411
19575
|
networkPassword: config.networkPassword ? "set" : null,
|
|
19412
19576
|
terminalApp: config.terminalApp || null,
|
|
19413
19577
|
editorApp: config.editorApp || null,
|
|
19414
|
-
useBuiltInEditor: config.useBuiltInEditor || false
|
|
19578
|
+
useBuiltInEditor: config.useBuiltInEditor || false,
|
|
19579
|
+
agentExecutable: config.agentExecutable ?? DEFAULT_EXECUTABLE_CHOICE
|
|
19415
19580
|
} : null));
|
|
19416
19581
|
return;
|
|
19417
19582
|
}
|
|
@@ -19474,7 +19639,8 @@ function registerConfigRoutes(use) {
|
|
|
19474
19639
|
networkPassword: finalPassword,
|
|
19475
19640
|
terminalApp: parsed.terminalApp || void 0,
|
|
19476
19641
|
editorApp: parsed.editorApp || void 0,
|
|
19477
|
-
useBuiltInEditor: !!parsed.useBuiltInEditor
|
|
19642
|
+
useBuiltInEditor: !!parsed.useBuiltInEditor,
|
|
19643
|
+
agentExecutable: parseExecutableChoice(parsed.agentExecutable)
|
|
19478
19644
|
});
|
|
19479
19645
|
refreshDirs();
|
|
19480
19646
|
if (currentConfig && resolve11(resolvedClaudeDir) !== resolve11(currentConfig.claudeDir)) {
|
|
@@ -19509,12 +19675,13 @@ var init_config2 = __esm({
|
|
|
19509
19675
|
init_users();
|
|
19510
19676
|
init_config();
|
|
19511
19677
|
init_agent_descriptors();
|
|
19678
|
+
init_agentExecutable();
|
|
19512
19679
|
init_sessionPersistence();
|
|
19513
19680
|
}
|
|
19514
19681
|
});
|
|
19515
19682
|
|
|
19516
19683
|
// ../../server/routes/hello.ts
|
|
19517
|
-
import { readFileSync } from "node:fs";
|
|
19684
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
19518
19685
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19519
19686
|
import { hostname } from "node:os";
|
|
19520
19687
|
import { join as join18 } from "node:path";
|
|
@@ -19563,7 +19730,7 @@ var init_hello = __esm({
|
|
|
19563
19730
|
join18(__dirname2, "../package.json")
|
|
19564
19731
|
]) {
|
|
19565
19732
|
try {
|
|
19566
|
-
const pkg = JSON.parse(
|
|
19733
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
19567
19734
|
if (typeof pkg.version === "string") return pkg.version;
|
|
19568
19735
|
} catch {
|
|
19569
19736
|
}
|
|
@@ -20794,7 +20961,7 @@ function registerFileRoutes(use) {
|
|
|
20794
20961
|
try {
|
|
20795
20962
|
let spawnLines = function(args, cwd) {
|
|
20796
20963
|
return new Promise((resolve21) => {
|
|
20797
|
-
const proc =
|
|
20964
|
+
const proc = spawn2("git", args, { cwd });
|
|
20798
20965
|
let out = "";
|
|
20799
20966
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20800
20967
|
proc.on("close", (code) => {
|
|
@@ -20805,7 +20972,7 @@ function registerFileRoutes(use) {
|
|
|
20805
20972
|
});
|
|
20806
20973
|
}, spawnOutput = function(args, cwd) {
|
|
20807
20974
|
return new Promise((resolve21) => {
|
|
20808
|
-
const proc =
|
|
20975
|
+
const proc = spawn2("git", args, { cwd });
|
|
20809
20976
|
let out = "";
|
|
20810
20977
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20811
20978
|
proc.on("close", () => resolve21(out.trim()));
|
|
@@ -20834,7 +21001,7 @@ function registerFileRoutes(use) {
|
|
|
20834
21001
|
}
|
|
20835
21002
|
}
|
|
20836
21003
|
return new Promise((resolve21) => {
|
|
20837
|
-
const proc =
|
|
21004
|
+
const proc = spawn2("git", ["rev-parse", "--show-toplevel"], { cwd });
|
|
20838
21005
|
let out = "";
|
|
20839
21006
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20840
21007
|
proc.on("close", (code) => {
|
|
@@ -21079,11 +21246,11 @@ function parseGitStatus(output) {
|
|
|
21079
21246
|
const branch = parseBranchHeader(header);
|
|
21080
21247
|
const files = [];
|
|
21081
21248
|
for (let index = 0; index < records.length; index += 1) {
|
|
21082
|
-
const
|
|
21083
|
-
if (!
|
|
21084
|
-
const indexStatus =
|
|
21085
|
-
const workTreeStatus =
|
|
21086
|
-
const path =
|
|
21249
|
+
const record3 = records[index];
|
|
21250
|
+
if (!record3 || record3.length < 3) continue;
|
|
21251
|
+
const indexStatus = record3[0];
|
|
21252
|
+
const workTreeStatus = record3[1];
|
|
21253
|
+
const path = record3.slice(3);
|
|
21087
21254
|
const renamedOrCopied = /[RC]/.test(`${indexStatus}${workTreeStatus}`);
|
|
21088
21255
|
const originalPath = renamedOrCopied ? records[index += 1] || void 0 : void 0;
|
|
21089
21256
|
files.push({ path, originalPath, indexStatus, workTreeStatus });
|
|
@@ -21138,6 +21305,272 @@ var init_git_status = __esm({
|
|
|
21138
21305
|
}
|
|
21139
21306
|
});
|
|
21140
21307
|
|
|
21308
|
+
// ../../server/routes/github-actions.ts
|
|
21309
|
+
import { execFile as execFileCallback2 } from "node:child_process";
|
|
21310
|
+
import { promisify as promisify2 } from "node:util";
|
|
21311
|
+
function record2(value) {
|
|
21312
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
21313
|
+
}
|
|
21314
|
+
function stringValue(value, fallback = "") {
|
|
21315
|
+
return typeof value === "string" ? value : fallback;
|
|
21316
|
+
}
|
|
21317
|
+
function numberValue(value) {
|
|
21318
|
+
return typeof value === "number" && Number.isSafeInteger(value) ? value : null;
|
|
21319
|
+
}
|
|
21320
|
+
function nullableDate(value) {
|
|
21321
|
+
return typeof value === "string" && value ? value : null;
|
|
21322
|
+
}
|
|
21323
|
+
function workflowStatus(value) {
|
|
21324
|
+
return typeof value === "string" && RUN_STATUSES.has(value) ? value : "pending";
|
|
21325
|
+
}
|
|
21326
|
+
function workflowConclusion(value) {
|
|
21327
|
+
return typeof value === "string" && RUN_CONCLUSIONS.has(value) ? value : null;
|
|
21328
|
+
}
|
|
21329
|
+
function parseGitHubRemote(remoteUrl) {
|
|
21330
|
+
const trimmed = remoteUrl.trim();
|
|
21331
|
+
let host = "";
|
|
21332
|
+
let pathname = "";
|
|
21333
|
+
try {
|
|
21334
|
+
const parsed = new URL(trimmed);
|
|
21335
|
+
host = parsed.hostname;
|
|
21336
|
+
pathname = parsed.pathname;
|
|
21337
|
+
} catch {
|
|
21338
|
+
const scp = trimmed.match(/^(?:[^@\s]+@)?([^:/\s]+):(.+)$/);
|
|
21339
|
+
if (!scp) return null;
|
|
21340
|
+
host = scp[1];
|
|
21341
|
+
pathname = scp[2];
|
|
21342
|
+
}
|
|
21343
|
+
const parts = pathname.replace(/^\/+/, "").replace(/\.git$/, "").split("/");
|
|
21344
|
+
if (parts.length !== 2 || !GITHUB_HOST.test(host) || host.toLowerCase() !== "github.com" && !host.toLowerCase().startsWith("github.") || !GITHUB_NAME.test(parts[0]) || !GITHUB_NAME.test(parts[1])) {
|
|
21345
|
+
return null;
|
|
21346
|
+
}
|
|
21347
|
+
return { host: host.toLowerCase(), owner: parts[0], name: parts[1] };
|
|
21348
|
+
}
|
|
21349
|
+
function parseRun(value) {
|
|
21350
|
+
const source = record2(value);
|
|
21351
|
+
if (!source) return null;
|
|
21352
|
+
const id = numberValue(source.id);
|
|
21353
|
+
const url = stringValue(source.html_url);
|
|
21354
|
+
if (id === null || !url.startsWith("https://")) return null;
|
|
21355
|
+
const actor = record2(source.actor);
|
|
21356
|
+
return {
|
|
21357
|
+
id,
|
|
21358
|
+
name: stringValue(source.name, "Workflow"),
|
|
21359
|
+
displayTitle: stringValue(source.display_title, stringValue(source.name, "Workflow run")),
|
|
21360
|
+
status: workflowStatus(source.status),
|
|
21361
|
+
conclusion: workflowConclusion(source.conclusion),
|
|
21362
|
+
url,
|
|
21363
|
+
runNumber: numberValue(source.run_number) ?? 0,
|
|
21364
|
+
event: stringValue(source.event, "workflow"),
|
|
21365
|
+
branch: stringValue(source.head_branch),
|
|
21366
|
+
commitSha: stringValue(source.head_sha),
|
|
21367
|
+
createdAt: stringValue(source.created_at),
|
|
21368
|
+
updatedAt: stringValue(source.updated_at),
|
|
21369
|
+
actor: stringValue(actor?.login)
|
|
21370
|
+
};
|
|
21371
|
+
}
|
|
21372
|
+
function parseStep(value) {
|
|
21373
|
+
const source = record2(value);
|
|
21374
|
+
if (!source) return null;
|
|
21375
|
+
const number = numberValue(source.number);
|
|
21376
|
+
if (number === null) return null;
|
|
21377
|
+
return {
|
|
21378
|
+
number,
|
|
21379
|
+
name: stringValue(source.name, `Step ${number}`),
|
|
21380
|
+
status: workflowStatus(source.status),
|
|
21381
|
+
conclusion: workflowConclusion(source.conclusion),
|
|
21382
|
+
startedAt: nullableDate(source.started_at),
|
|
21383
|
+
completedAt: nullableDate(source.completed_at)
|
|
21384
|
+
};
|
|
21385
|
+
}
|
|
21386
|
+
function parseJob(value) {
|
|
21387
|
+
const source = record2(value);
|
|
21388
|
+
if (!source) return null;
|
|
21389
|
+
const id = numberValue(source.id);
|
|
21390
|
+
const url = stringValue(source.html_url);
|
|
21391
|
+
if (id === null || !url.startsWith("https://")) return null;
|
|
21392
|
+
return {
|
|
21393
|
+
id,
|
|
21394
|
+
name: stringValue(source.name, "Job"),
|
|
21395
|
+
status: workflowStatus(source.status),
|
|
21396
|
+
conclusion: workflowConclusion(source.conclusion),
|
|
21397
|
+
url,
|
|
21398
|
+
startedAt: nullableDate(source.started_at),
|
|
21399
|
+
completedAt: nullableDate(source.completed_at),
|
|
21400
|
+
steps: Array.isArray(source.steps) ? source.steps.map(parseStep).filter((step) => step !== null) : []
|
|
21401
|
+
};
|
|
21402
|
+
}
|
|
21403
|
+
function parseRunsResponse(value) {
|
|
21404
|
+
const source = record2(value);
|
|
21405
|
+
if (!source || !Array.isArray(source.workflow_runs)) {
|
|
21406
|
+
throw new GitHubActionsRouteError(502, "invalid_response", "GitHub returned an invalid workflow response");
|
|
21407
|
+
}
|
|
21408
|
+
return source.workflow_runs.map(parseRun).filter((run2) => run2 !== null);
|
|
21409
|
+
}
|
|
21410
|
+
function parseJobsResponse(value) {
|
|
21411
|
+
const source = record2(value);
|
|
21412
|
+
if (!source || !Array.isArray(source.jobs)) {
|
|
21413
|
+
throw new GitHubActionsRouteError(502, "invalid_response", "GitHub returned an invalid jobs response");
|
|
21414
|
+
}
|
|
21415
|
+
return source.jobs.map(parseJob).filter((job) => job !== null);
|
|
21416
|
+
}
|
|
21417
|
+
async function runGitHubApi(repository, endpoint) {
|
|
21418
|
+
try {
|
|
21419
|
+
const result = await execFile3("gh", [
|
|
21420
|
+
"api",
|
|
21421
|
+
endpoint,
|
|
21422
|
+
"--hostname",
|
|
21423
|
+
repository.host,
|
|
21424
|
+
"-H",
|
|
21425
|
+
"Accept: application/vnd.github+json"
|
|
21426
|
+
], {
|
|
21427
|
+
encoding: "utf-8",
|
|
21428
|
+
env: { ...process.env, GH_PAGER: "cat", NO_COLOR: "1" },
|
|
21429
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
21430
|
+
timeout: 2e4,
|
|
21431
|
+
windowsHide: true
|
|
21432
|
+
});
|
|
21433
|
+
return JSON.parse(result.stdout);
|
|
21434
|
+
} catch (error) {
|
|
21435
|
+
const failure = error;
|
|
21436
|
+
if (failure.code === "ENOENT") {
|
|
21437
|
+
throw new GitHubActionsRouteError(503, "gh_missing", "Install the GitHub CLI to view workflow runs");
|
|
21438
|
+
}
|
|
21439
|
+
const detail = `${failure.message ?? ""}
|
|
21440
|
+
${failure.stderr ?? ""}`;
|
|
21441
|
+
if (/auth login|not logged|authentication|oauth token/i.test(detail)) {
|
|
21442
|
+
throw new GitHubActionsRouteError(503, "gh_auth_required", "Sign in with `gh auth login` to view workflow runs");
|
|
21443
|
+
}
|
|
21444
|
+
throw new GitHubActionsRouteError(502, "github_api_failed", "GitHub workflow data is unavailable");
|
|
21445
|
+
}
|
|
21446
|
+
}
|
|
21447
|
+
async function resolveRepository(cwd, dependencies) {
|
|
21448
|
+
const project = await dependencies.resolveProject(cwd);
|
|
21449
|
+
if (!project.ok) throw new GitHubActionsRouteError(project.status, "no_git_repository", project.error);
|
|
21450
|
+
if (!project.root) {
|
|
21451
|
+
throw new GitHubActionsRouteError(400, "no_git_repository", "This project is not a Git repository");
|
|
21452
|
+
}
|
|
21453
|
+
let remoteUrl = "";
|
|
21454
|
+
try {
|
|
21455
|
+
remoteUrl = (await dependencies.git(project.root, ["remote", "get-url", "origin"])).stdout;
|
|
21456
|
+
} catch {
|
|
21457
|
+
throw new GitHubActionsRouteError(400, "no_github_remote", "This repository has no origin remote");
|
|
21458
|
+
}
|
|
21459
|
+
const repository = parseGitHubRemote(remoteUrl);
|
|
21460
|
+
if (!repository) {
|
|
21461
|
+
throw new GitHubActionsRouteError(400, "no_github_remote", "The origin remote is not a supported GitHub repository");
|
|
21462
|
+
}
|
|
21463
|
+
const branchResult = await dependencies.git(project.root, ["branch", "--show-current"]);
|
|
21464
|
+
return {
|
|
21465
|
+
repository,
|
|
21466
|
+
branch: branchResult.stdout.trim() || null
|
|
21467
|
+
};
|
|
21468
|
+
}
|
|
21469
|
+
function repositoryName(repository) {
|
|
21470
|
+
return `${repository.owner}/${repository.name}`;
|
|
21471
|
+
}
|
|
21472
|
+
function repositoryUrl(repository) {
|
|
21473
|
+
return `https://${repository.host}/${repository.owner}/${repository.name}`;
|
|
21474
|
+
}
|
|
21475
|
+
function sendRouteError2(res, error) {
|
|
21476
|
+
if (error instanceof GitHubActionsRouteError) {
|
|
21477
|
+
sendJson(res, error.status, { error: error.message, code: error.code });
|
|
21478
|
+
return;
|
|
21479
|
+
}
|
|
21480
|
+
sendJson(res, 500, { error: "Unable to load GitHub Actions", code: "github_api_failed" });
|
|
21481
|
+
}
|
|
21482
|
+
function registerGitHubActionsRoutes(use, dependencies = defaultDependencies) {
|
|
21483
|
+
use("/api/github-actions", async (req, res, next) => {
|
|
21484
|
+
if (req.method !== "GET") return next();
|
|
21485
|
+
const url = new URL(req.url || "", "http://localhost");
|
|
21486
|
+
if (url.pathname !== "/" && url.pathname !== "") return next();
|
|
21487
|
+
const cwd = url.searchParams.get("cwd") ?? "";
|
|
21488
|
+
const requestedLimit = Number(url.searchParams.get("limit") ?? DEFAULT_RUNS);
|
|
21489
|
+
const limit = Number.isInteger(requestedLimit) ? Math.min(MAX_RUNS, Math.max(1, requestedLimit)) : DEFAULT_RUNS;
|
|
21490
|
+
try {
|
|
21491
|
+
const { repository, branch } = await resolveRepository(cwd, dependencies);
|
|
21492
|
+
const endpoint = `repos/${repository.owner}/${repository.name}/actions/runs?per_page=${limit}`;
|
|
21493
|
+
const runs = parseRunsResponse(await dependencies.githubApi(repository, endpoint));
|
|
21494
|
+
const response = {
|
|
21495
|
+
repository: repositoryName(repository),
|
|
21496
|
+
repositoryUrl: repositoryUrl(repository),
|
|
21497
|
+
branch,
|
|
21498
|
+
runs
|
|
21499
|
+
};
|
|
21500
|
+
sendJson(res, 200, response);
|
|
21501
|
+
} catch (error) {
|
|
21502
|
+
sendRouteError2(res, error);
|
|
21503
|
+
}
|
|
21504
|
+
});
|
|
21505
|
+
use("/api/github-actions/jobs", async (req, res, next) => {
|
|
21506
|
+
if (req.method !== "GET") return next();
|
|
21507
|
+
const url = new URL(req.url || "", "http://localhost");
|
|
21508
|
+
if (url.pathname !== "/" && url.pathname !== "") return next();
|
|
21509
|
+
const cwd = url.searchParams.get("cwd") ?? "";
|
|
21510
|
+
const runIdText = url.searchParams.get("runId") ?? "";
|
|
21511
|
+
if (!/^\d+$/.test(runIdText)) {
|
|
21512
|
+
return sendJson(res, 400, { error: "runId must be a positive integer", code: "github_api_failed" });
|
|
21513
|
+
}
|
|
21514
|
+
try {
|
|
21515
|
+
const { repository } = await resolveRepository(cwd, dependencies);
|
|
21516
|
+
const runId = Number(runIdText);
|
|
21517
|
+
const endpoint = `repos/${repository.owner}/${repository.name}/actions/runs/${runId}/jobs?filter=latest&per_page=100`;
|
|
21518
|
+
const jobs = parseJobsResponse(await dependencies.githubApi(repository, endpoint));
|
|
21519
|
+
const response = {
|
|
21520
|
+
repository: repositoryName(repository),
|
|
21521
|
+
runId,
|
|
21522
|
+
jobs
|
|
21523
|
+
};
|
|
21524
|
+
sendJson(res, 200, response);
|
|
21525
|
+
} catch (error) {
|
|
21526
|
+
sendRouteError2(res, error);
|
|
21527
|
+
}
|
|
21528
|
+
});
|
|
21529
|
+
}
|
|
21530
|
+
var execFile3, MAX_RUNS, DEFAULT_RUNS, GITHUB_NAME, GITHUB_HOST, RUN_STATUSES, RUN_CONCLUSIONS, GitHubActionsRouteError, defaultDependencies;
|
|
21531
|
+
var init_github_actions = __esm({
|
|
21532
|
+
"../../server/routes/github-actions.ts"() {
|
|
21533
|
+
init_http();
|
|
21534
|
+
init_gitProject();
|
|
21535
|
+
execFile3 = promisify2(execFileCallback2);
|
|
21536
|
+
MAX_RUNS = 30;
|
|
21537
|
+
DEFAULT_RUNS = 20;
|
|
21538
|
+
GITHUB_NAME = /^[A-Za-z0-9_.-]+$/;
|
|
21539
|
+
GITHUB_HOST = /^[A-Za-z0-9.-]+$/;
|
|
21540
|
+
RUN_STATUSES = /* @__PURE__ */ new Set([
|
|
21541
|
+
"completed",
|
|
21542
|
+
"in_progress",
|
|
21543
|
+
"pending",
|
|
21544
|
+
"queued",
|
|
21545
|
+
"requested",
|
|
21546
|
+
"waiting"
|
|
21547
|
+
]);
|
|
21548
|
+
RUN_CONCLUSIONS = /* @__PURE__ */ new Set([
|
|
21549
|
+
"action_required",
|
|
21550
|
+
"cancelled",
|
|
21551
|
+
"failure",
|
|
21552
|
+
"neutral",
|
|
21553
|
+
"skipped",
|
|
21554
|
+
"stale",
|
|
21555
|
+
"startup_failure",
|
|
21556
|
+
"success",
|
|
21557
|
+
"timed_out"
|
|
21558
|
+
]);
|
|
21559
|
+
GitHubActionsRouteError = class extends Error {
|
|
21560
|
+
constructor(status, code, message) {
|
|
21561
|
+
super(message);
|
|
21562
|
+
this.status = status;
|
|
21563
|
+
this.code = code;
|
|
21564
|
+
}
|
|
21565
|
+
};
|
|
21566
|
+
defaultDependencies = {
|
|
21567
|
+
resolveProject: resolveGitProject,
|
|
21568
|
+
git: runGit,
|
|
21569
|
+
githubApi: runGitHubApi
|
|
21570
|
+
};
|
|
21571
|
+
}
|
|
21572
|
+
});
|
|
21573
|
+
|
|
21141
21574
|
// ../../server/lib/projectIcon.ts
|
|
21142
21575
|
import { realpath as realpath8, stat as stat13 } from "node:fs/promises";
|
|
21143
21576
|
import { basename as basename9, extname, join as join20, relative as relative8, sep as sep10 } from "node:path";
|
|
@@ -21321,7 +21754,7 @@ var init_local_file = __esm({
|
|
|
21321
21754
|
});
|
|
21322
21755
|
|
|
21323
21756
|
// ../../server/routes/mcp.ts
|
|
21324
|
-
import { execFile as
|
|
21757
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
21325
21758
|
import { isAbsolute as isAbsolute9, join as join21 } from "node:path";
|
|
21326
21759
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
21327
21760
|
import { homedir as homedir7 } from "node:os";
|
|
@@ -21402,7 +21835,7 @@ async function getMcpServers(cwd) {
|
|
|
21402
21835
|
const env = { ...process.env };
|
|
21403
21836
|
delete env.CLAUDECODE;
|
|
21404
21837
|
const cli = resolveAgentCommand("claude", ["mcp", "list"]);
|
|
21405
|
-
|
|
21838
|
+
execFile4(cli.command, cli.args, { cwd, env, timeout: 15e3, ...cli.spawnOptions }, (err, stdout) => {
|
|
21406
21839
|
if (err) {
|
|
21407
21840
|
resolve21({ servers: cached?.servers ?? [], configs });
|
|
21408
21841
|
return;
|
|
@@ -22201,8 +22634,8 @@ function copilotText(value) {
|
|
|
22201
22634
|
if (!Array.isArray(value)) return "";
|
|
22202
22635
|
return value.flatMap((part) => {
|
|
22203
22636
|
if (typeof part === "string") return part ? [part] : [];
|
|
22204
|
-
const
|
|
22205
|
-
const text = str(
|
|
22637
|
+
const record3 = asRecord5(part);
|
|
22638
|
+
const text = str(record3.text) || str(record3.content);
|
|
22206
22639
|
return text ? [text] : [];
|
|
22207
22640
|
}).join("\n");
|
|
22208
22641
|
}
|
|
@@ -22905,7 +23338,7 @@ var init_notifications = __esm({
|
|
|
22905
23338
|
});
|
|
22906
23339
|
|
|
22907
23340
|
// ../../server/lib/systemProcesses.ts
|
|
22908
|
-
import { execFile as
|
|
23341
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
22909
23342
|
function parseEtimeSeconds(etime) {
|
|
22910
23343
|
const match = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/.exec(etime.trim());
|
|
22911
23344
|
if (!match) return 0;
|
|
@@ -23027,7 +23460,7 @@ function classifyProcesses(rows, selfPid) {
|
|
|
23027
23460
|
}
|
|
23028
23461
|
function listSystemProcesses() {
|
|
23029
23462
|
return new Promise((resolve21, reject) => {
|
|
23030
|
-
|
|
23463
|
+
execFile5(
|
|
23031
23464
|
"ps",
|
|
23032
23465
|
["-axo", "pid=,ppid=,pcpu=,rss=,etime=,args="],
|
|
23033
23466
|
{ maxBuffer: 8 * 1024 * 1024 },
|
|
@@ -23065,7 +23498,7 @@ var init_systemProcesses = __esm({
|
|
|
23065
23498
|
});
|
|
23066
23499
|
|
|
23067
23500
|
// ../../server/lib/desktopNotify.ts
|
|
23068
|
-
import { execFile as
|
|
23501
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
23069
23502
|
function parentMessagePort() {
|
|
23070
23503
|
const { parentPort } = process;
|
|
23071
23504
|
return parentPort && typeof parentPort.postMessage === "function" ? parentPort : null;
|
|
@@ -23078,7 +23511,7 @@ function showNotification(title, body, nav, historyId) {
|
|
|
23078
23511
|
return;
|
|
23079
23512
|
}
|
|
23080
23513
|
if (process.platform === "darwin") {
|
|
23081
|
-
|
|
23514
|
+
execFile6(
|
|
23082
23515
|
"osascript",
|
|
23083
23516
|
["-e", `display notification "${escapeAppleScript(body)}" with title "${escapeAppleScript(title)}"`],
|
|
23084
23517
|
// This is the standalone server's only desktop channel, so a silent
|
|
@@ -23119,7 +23552,7 @@ var init_notifications2 = __esm({
|
|
|
23119
23552
|
});
|
|
23120
23553
|
|
|
23121
23554
|
// ../../server/lib/pushConfig.ts
|
|
23122
|
-
import { readFileSync as
|
|
23555
|
+
import { readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
23123
23556
|
import { homedir as homedir9 } from "node:os";
|
|
23124
23557
|
import { join as join23 } from "node:path";
|
|
23125
23558
|
function warnOnce(message) {
|
|
@@ -23132,7 +23565,7 @@ function asString(value) {
|
|
|
23132
23565
|
}
|
|
23133
23566
|
function fileMtime(path) {
|
|
23134
23567
|
try {
|
|
23135
|
-
return
|
|
23568
|
+
return statSync3(path).mtimeMs;
|
|
23136
23569
|
} catch {
|
|
23137
23570
|
return null;
|
|
23138
23571
|
}
|
|
@@ -23147,8 +23580,8 @@ function warnIfExposed(path, mode) {
|
|
|
23147
23580
|
function readConfigFile(path) {
|
|
23148
23581
|
let raw;
|
|
23149
23582
|
try {
|
|
23150
|
-
warnIfExposed(path,
|
|
23151
|
-
raw =
|
|
23583
|
+
warnIfExposed(path, statSync3(path).mode);
|
|
23584
|
+
raw = readFileSync3(path, "utf8");
|
|
23152
23585
|
} catch (err) {
|
|
23153
23586
|
const code = err.code;
|
|
23154
23587
|
if (code !== "ENOENT") warnOnce(`Could not read ${path}: ${code ?? String(err)}`);
|
|
@@ -23951,7 +24384,7 @@ var init_backgroundAgents = __esm({
|
|
|
23951
24384
|
// ../../server/routes/ports/listeningProcesses.ts
|
|
23952
24385
|
function runCapture(command, args) {
|
|
23953
24386
|
return new Promise((resolve21, reject) => {
|
|
23954
|
-
const child =
|
|
24387
|
+
const child = spawn2(command, args);
|
|
23955
24388
|
let stdout = "";
|
|
23956
24389
|
child.stdout?.on("data", (data) => {
|
|
23957
24390
|
stdout += data.toString();
|
|
@@ -24238,13 +24671,13 @@ var init_project_files_ranking = __esm({
|
|
|
24238
24671
|
});
|
|
24239
24672
|
|
|
24240
24673
|
// ../../server/routes/project-files.ts
|
|
24241
|
-
import { execFile as
|
|
24674
|
+
import { execFile as execFileCallback3 } from "node:child_process";
|
|
24242
24675
|
import { readdir as readdir11, realpath as realpath10, stat as stat16 } from "node:fs/promises";
|
|
24243
24676
|
import { isAbsolute as isAbsolute11, relative as relative9, resolve as resolve17, sep as sep11 } from "node:path";
|
|
24244
|
-
import { promisify as
|
|
24677
|
+
import { promisify as promisify3 } from "node:util";
|
|
24245
24678
|
async function listGitProjectFiles(root) {
|
|
24246
24679
|
try {
|
|
24247
|
-
const result = await
|
|
24680
|
+
const result = await execFile7(
|
|
24248
24681
|
"git",
|
|
24249
24682
|
["ls-files", "--cached", "--others", "--exclude-standard", "-z", "--", "."],
|
|
24250
24683
|
{
|
|
@@ -24320,7 +24753,7 @@ function registerProjectFileRoutes(use) {
|
|
|
24320
24753
|
}
|
|
24321
24754
|
});
|
|
24322
24755
|
}
|
|
24323
|
-
var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache,
|
|
24756
|
+
var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache, execFile7;
|
|
24324
24757
|
var init_project_files = __esm({
|
|
24325
24758
|
"../../server/routes/project-files.ts"() {
|
|
24326
24759
|
init_http();
|
|
@@ -24341,7 +24774,7 @@ var init_project_files = __esm({
|
|
|
24341
24774
|
"target"
|
|
24342
24775
|
]);
|
|
24343
24776
|
fileCache = /* @__PURE__ */ new Map();
|
|
24344
|
-
|
|
24777
|
+
execFile7 = promisify3(execFileCallback3);
|
|
24345
24778
|
}
|
|
24346
24779
|
});
|
|
24347
24780
|
|
|
@@ -24604,12 +25037,12 @@ function createPullRequestScanner() {
|
|
|
24604
25037
|
const command = findCreateCommand(input);
|
|
24605
25038
|
if (command) openCreates.set(id, { command, timestamp });
|
|
24606
25039
|
}
|
|
24607
|
-
function recordPrLink(
|
|
24608
|
-
const url =
|
|
24609
|
-
const number =
|
|
25040
|
+
function recordPrLink(record3, timestamp) {
|
|
25041
|
+
const url = record3.prUrl;
|
|
25042
|
+
const number = record3.prNumber;
|
|
24610
25043
|
if (typeof url !== "string" || !url) return;
|
|
24611
25044
|
if (typeof number !== "number" || !Number.isInteger(number) || number <= 0) return;
|
|
24612
|
-
const repo = typeof
|
|
25045
|
+
const repo = typeof record3.prRepository === "string" ? record3.prRepository : "";
|
|
24613
25046
|
collector.add({
|
|
24614
25047
|
url,
|
|
24615
25048
|
number,
|
|
@@ -24644,19 +25077,19 @@ function createPullRequestScanner() {
|
|
|
24644
25077
|
if (!line.includes(GH_PR_HINT) && !line.includes(URL_HINT) && !line.includes(PR_LINK_HINT)) {
|
|
24645
25078
|
return;
|
|
24646
25079
|
}
|
|
24647
|
-
let
|
|
25080
|
+
let record3;
|
|
24648
25081
|
try {
|
|
24649
|
-
|
|
25082
|
+
record3 = JSON.parse(line);
|
|
24650
25083
|
} catch {
|
|
24651
25084
|
return;
|
|
24652
25085
|
}
|
|
24653
|
-
if (!isRecord5(
|
|
24654
|
-
const timestamp = typeof
|
|
24655
|
-
if (
|
|
24656
|
-
recordPrLink(
|
|
25086
|
+
if (!isRecord5(record3)) return;
|
|
25087
|
+
const timestamp = typeof record3.timestamp === "string" ? record3.timestamp : "";
|
|
25088
|
+
if (record3.type === "pr-link") {
|
|
25089
|
+
recordPrLink(record3, timestamp);
|
|
24657
25090
|
return;
|
|
24658
25091
|
}
|
|
24659
|
-
const payload =
|
|
25092
|
+
const payload = record3.payload;
|
|
24660
25093
|
if (isRecord5(payload)) {
|
|
24661
25094
|
const type = payload.type;
|
|
24662
25095
|
if (type === "function_call" || type === "custom_tool_call") {
|
|
@@ -24666,15 +25099,15 @@ function createPullRequestScanner() {
|
|
|
24666
25099
|
}
|
|
24667
25100
|
return;
|
|
24668
25101
|
}
|
|
24669
|
-
const data =
|
|
25102
|
+
const data = record3.data;
|
|
24670
25103
|
if (isRecord5(data)) {
|
|
24671
|
-
if (
|
|
25104
|
+
if (record3.type === "tool.execution_start") {
|
|
24672
25105
|
recordToolCall(
|
|
24673
25106
|
data.toolCallId,
|
|
24674
25107
|
parseArgs2(data.arguments ?? data.input),
|
|
24675
25108
|
timestamp
|
|
24676
25109
|
);
|
|
24677
|
-
} else if (
|
|
25110
|
+
} else if (record3.type === "tool.execution_complete") {
|
|
24678
25111
|
recordResult(
|
|
24679
25112
|
data.toolCallId,
|
|
24680
25113
|
data.result ?? data.output ?? data.error,
|
|
@@ -24683,7 +25116,7 @@ function createPullRequestScanner() {
|
|
|
24683
25116
|
}
|
|
24684
25117
|
return;
|
|
24685
25118
|
}
|
|
24686
|
-
const message =
|
|
25119
|
+
const message = record3.message;
|
|
24687
25120
|
if (!isRecord5(message) || !Array.isArray(message.content)) return;
|
|
24688
25121
|
for (const block of message.content) {
|
|
24689
25122
|
if (!isRecord5(block)) continue;
|
|
@@ -25547,6 +25980,19 @@ var init_projects2 = __esm({
|
|
|
25547
25980
|
}
|
|
25548
25981
|
});
|
|
25549
25982
|
|
|
25983
|
+
// ../../server/agents/executables.ts
|
|
25984
|
+
function activeExecutableFor(kind) {
|
|
25985
|
+
return kind === "claude" ? claudeCliPath() : void 0;
|
|
25986
|
+
}
|
|
25987
|
+
function describeExecutableFor(kind) {
|
|
25988
|
+
return kind === "claude" ? describeClaudeExecutable() : null;
|
|
25989
|
+
}
|
|
25990
|
+
var init_executables = __esm({
|
|
25991
|
+
"../../server/agents/executables.ts"() {
|
|
25992
|
+
init_claudeExecutable();
|
|
25993
|
+
}
|
|
25994
|
+
});
|
|
25995
|
+
|
|
25550
25996
|
// ../../server/lib/providerUpdates.ts
|
|
25551
25997
|
import { realpathSync } from "node:fs";
|
|
25552
25998
|
function deriveStatus(current, latest) {
|
|
@@ -25649,8 +26095,8 @@ function buildUpdateCommand(provider, method) {
|
|
|
25649
26095
|
function formatCommand(command) {
|
|
25650
26096
|
return [command.executable, ...command.args].join(" ");
|
|
25651
26097
|
}
|
|
25652
|
-
function resolveBinaryPaths(
|
|
25653
|
-
const onPath = findExecutableOnPath(binName);
|
|
26098
|
+
function resolveBinaryPaths(descriptor7) {
|
|
26099
|
+
const onPath = activeExecutableFor(descriptor7.kind) ?? findExecutableOnPath(descriptor7.binName);
|
|
25654
26100
|
if (!onPath) return [];
|
|
25655
26101
|
try {
|
|
25656
26102
|
const real = realpathSync(onPath);
|
|
@@ -25699,7 +26145,7 @@ function fetchLatestVersion(packageName) {
|
|
|
25699
26145
|
});
|
|
25700
26146
|
}
|
|
25701
26147
|
async function probeProvider(descriptor7) {
|
|
25702
|
-
const paths = resolveBinaryPaths(descriptor7
|
|
26148
|
+
const paths = resolveBinaryPaths(descriptor7);
|
|
25703
26149
|
const base = {
|
|
25704
26150
|
provider: descriptor7.kind,
|
|
25705
26151
|
displayName: descriptor7.displayName,
|
|
@@ -25808,6 +26254,7 @@ var init_providerUpdates = __esm({
|
|
|
25808
26254
|
"../../server/lib/providerUpdates.ts"() {
|
|
25809
26255
|
init_agent_descriptors();
|
|
25810
26256
|
init_versions();
|
|
26257
|
+
init_executables();
|
|
25811
26258
|
init_binaryResolver();
|
|
25812
26259
|
init_cliProcess();
|
|
25813
26260
|
REGISTRY_TIMEOUT_MS = 4e3;
|
|
@@ -25864,6 +26311,32 @@ var init_provider_updates = __esm({
|
|
|
25864
26311
|
}
|
|
25865
26312
|
});
|
|
25866
26313
|
|
|
26314
|
+
// ../../server/routes/agent-executable.ts
|
|
26315
|
+
function registerAgentExecutableRoutes(use) {
|
|
26316
|
+
use("/api/agent-executable", async (req, res, next) => {
|
|
26317
|
+
if (req.method !== "GET") return next();
|
|
26318
|
+
const kind = new URL(req.url || "/", "http://localhost").pathname.slice(1);
|
|
26319
|
+
if (!AGENT_KINDS.includes(kind)) return next();
|
|
26320
|
+
const report = describeExecutableFor(kind);
|
|
26321
|
+
if (!report) {
|
|
26322
|
+
sendJson(res, 404, { error: `${kind} has a single executable; nothing to choose` });
|
|
26323
|
+
return;
|
|
26324
|
+
}
|
|
26325
|
+
try {
|
|
26326
|
+
sendJson(res, 200, await report);
|
|
26327
|
+
} catch (err) {
|
|
26328
|
+
sendJson(res, 500, { error: String(err) });
|
|
26329
|
+
}
|
|
26330
|
+
});
|
|
26331
|
+
}
|
|
26332
|
+
var init_agent_executable = __esm({
|
|
26333
|
+
"../../server/routes/agent-executable.ts"() {
|
|
26334
|
+
init_agent_descriptors();
|
|
26335
|
+
init_executables();
|
|
26336
|
+
init_http();
|
|
26337
|
+
}
|
|
26338
|
+
});
|
|
26339
|
+
|
|
25867
26340
|
// ../../server/routes/scripts/discovery.ts
|
|
25868
26341
|
import { readdir as readdir12, readFile as readFile19 } from "node:fs/promises";
|
|
25869
26342
|
import { join as join25, relative as relative10 } from "node:path";
|
|
@@ -26779,7 +27252,7 @@ function normalizeCopilotFileChangeEvents(jsonlContent) {
|
|
|
26779
27252
|
}
|
|
26780
27253
|
});
|
|
26781
27254
|
}
|
|
26782
|
-
return records.map((
|
|
27255
|
+
return records.map((record3) => JSON.stringify(record3)).join("\n");
|
|
26783
27256
|
}
|
|
26784
27257
|
async function parseSessionFileChanges(jsonlContent, includeContent) {
|
|
26785
27258
|
if (formatForText(jsonlContent).kind === "copilot") {
|
|
@@ -28748,20 +29221,20 @@ var init_aggregate = __esm({
|
|
|
28748
29221
|
this.#toDay = makeDayFormatter(options.timeZone);
|
|
28749
29222
|
}
|
|
28750
29223
|
/** Folds one record in; returns whether it actually contributed. */
|
|
28751
|
-
add(
|
|
28752
|
-
if (
|
|
28753
|
-
if (this.#seen.has(
|
|
28754
|
-
this.#seen.add(
|
|
29224
|
+
add(record3) {
|
|
29225
|
+
if (record3.dedupeKey !== null) {
|
|
29226
|
+
if (this.#seen.has(record3.dedupeKey)) return false;
|
|
29227
|
+
this.#seen.add(record3.dedupeKey);
|
|
28755
29228
|
}
|
|
28756
|
-
const day = this.#toDay(
|
|
29229
|
+
const day = this.#toDay(record3.timestampMs);
|
|
28757
29230
|
if (day < this.#options.sinceDay || day > this.#options.untilDay) return false;
|
|
28758
|
-
const key2 = [day,
|
|
29231
|
+
const key2 = [day, record3.provider, record3.model].join(KEY_SEPARATOR);
|
|
28759
29232
|
let bucket = this.#buckets.get(key2);
|
|
28760
29233
|
if (bucket === void 0) {
|
|
28761
29234
|
bucket = {
|
|
28762
29235
|
day,
|
|
28763
|
-
provider:
|
|
28764
|
-
model:
|
|
29236
|
+
provider: record3.provider,
|
|
29237
|
+
model: record3.model,
|
|
28765
29238
|
totals: emptyUsageCostTotals(),
|
|
28766
29239
|
costUsd: 0,
|
|
28767
29240
|
cacheSavingsUsd: 0,
|
|
@@ -28774,19 +29247,19 @@ var init_aggregate = __esm({
|
|
|
28774
29247
|
}
|
|
28775
29248
|
const priced = priceUsage(
|
|
28776
29249
|
this.#options.rates,
|
|
28777
|
-
|
|
28778
|
-
|
|
28779
|
-
|
|
29250
|
+
record3.model,
|
|
29251
|
+
record3.totals,
|
|
29252
|
+
record3.reportedCostUsd
|
|
28780
29253
|
);
|
|
28781
|
-
bucket.totals = addUsageCostTotals(bucket.totals,
|
|
29254
|
+
bucket.totals = addUsageCostTotals(bucket.totals, record3.totals);
|
|
28782
29255
|
bucket.costUsd += priced.costUsd;
|
|
28783
|
-
bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates,
|
|
29256
|
+
bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates, record3.model, record3.totals);
|
|
28784
29257
|
bucket.records += 1;
|
|
28785
29258
|
if (priced.costSource === "unpriced") bucket.unpricedRecords += 1;
|
|
28786
29259
|
if (priced.costSource === "providerReported") bucket.providerReportedRecords += 1;
|
|
28787
|
-
if (
|
|
28788
|
-
bucket.sessions.add(
|
|
28789
|
-
this.#sessions.add(
|
|
29260
|
+
if (record3.sessionId.length > 0) {
|
|
29261
|
+
bucket.sessions.add(record3.sessionId);
|
|
29262
|
+
this.#sessions.add(record3.sessionId);
|
|
28790
29263
|
}
|
|
28791
29264
|
return true;
|
|
28792
29265
|
}
|
|
@@ -28867,17 +29340,17 @@ async function readTranscriptRecords(filePath, provider) {
|
|
|
28867
29340
|
function dedupeWithinFile(records) {
|
|
28868
29341
|
const slotByKey = /* @__PURE__ */ new Map();
|
|
28869
29342
|
const kept = [];
|
|
28870
|
-
for (const
|
|
28871
|
-
if (
|
|
28872
|
-
kept.push(
|
|
29343
|
+
for (const record3 of records) {
|
|
29344
|
+
if (record3.dedupeKey === null) {
|
|
29345
|
+
kept.push(record3);
|
|
28873
29346
|
continue;
|
|
28874
29347
|
}
|
|
28875
|
-
const slot = slotByKey.get(
|
|
29348
|
+
const slot = slotByKey.get(record3.dedupeKey);
|
|
28876
29349
|
if (slot === void 0) {
|
|
28877
|
-
slotByKey.set(
|
|
29350
|
+
slotByKey.set(record3.dedupeKey, kept.push(record3) - 1);
|
|
28878
29351
|
continue;
|
|
28879
29352
|
}
|
|
28880
|
-
if (
|
|
29353
|
+
if (record3.totals.outputTokens > kept[slot].totals.outputTokens) kept[slot] = record3;
|
|
28881
29354
|
}
|
|
28882
29355
|
return kept;
|
|
28883
29356
|
}
|
|
@@ -28986,23 +29459,23 @@ async function readUsageCostSummary(input) {
|
|
|
28986
29459
|
for (const file of files) {
|
|
28987
29460
|
const records = await readFileRecords(file, provider);
|
|
28988
29461
|
scannedFiles += 1;
|
|
28989
|
-
for (const
|
|
28990
|
-
aggregator.add(
|
|
28991
|
-
if (!liveSessionIds.has(
|
|
28992
|
-
const byModel = durableTotals.get(
|
|
29462
|
+
for (const record3 of records) {
|
|
29463
|
+
aggregator.add(record3);
|
|
29464
|
+
if (!liveSessionIds.has(record3.sessionId)) continue;
|
|
29465
|
+
const byModel = durableTotals.get(record3.sessionId) ?? /* @__PURE__ */ new Map();
|
|
28993
29466
|
byModel.set(
|
|
28994
|
-
|
|
29467
|
+
record3.model,
|
|
28995
29468
|
addUsageCostTotals(
|
|
28996
|
-
byModel.get(
|
|
28997
|
-
|
|
29469
|
+
byModel.get(record3.model) ?? emptyUsageCostTotals(),
|
|
29470
|
+
record3.totals
|
|
28998
29471
|
)
|
|
28999
29472
|
);
|
|
29000
|
-
durableTotals.set(
|
|
29473
|
+
durableTotals.set(record3.sessionId, byModel);
|
|
29001
29474
|
}
|
|
29002
29475
|
}
|
|
29003
29476
|
}
|
|
29004
29477
|
for (const runtime of runtimes2) {
|
|
29005
|
-
for (const
|
|
29478
|
+
for (const record3 of await runtime.liveUsageRecords(durableTotals)) aggregator.add(record3);
|
|
29006
29479
|
}
|
|
29007
29480
|
const retentionCutoffMs = startedAtMs - 90 * 24 * 60 * 60 * 1e3;
|
|
29008
29481
|
for (const [path, entry] of fileCache2) {
|
|
@@ -29729,8 +30202,8 @@ var init_workflows2 = __esm({
|
|
|
29729
30202
|
});
|
|
29730
30203
|
|
|
29731
30204
|
// ../../server/routes/worktrees/worktreeIo.ts
|
|
29732
|
-
import { execFile as
|
|
29733
|
-
import { promisify as
|
|
30205
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
30206
|
+
import { promisify as promisify4 } from "node:util";
|
|
29734
30207
|
async function runWorktreeCommand(file, args, { cwd, timeoutMs = WORKTREE_COMMAND_TIMEOUT_MS }) {
|
|
29735
30208
|
const result = await execFileAsync(file, [...args], {
|
|
29736
30209
|
cwd,
|
|
@@ -29769,7 +30242,7 @@ var init_worktreeIo = __esm({
|
|
|
29769
30242
|
WORKTREE_COMMAND_MAX_BUFFER = 4 * 1024 * 1024;
|
|
29770
30243
|
WORKTREE_SCAN_CONCURRENCY = 4;
|
|
29771
30244
|
SESSION_HEADER_CONCURRENCY = 8;
|
|
29772
|
-
execFileAsync =
|
|
30245
|
+
execFileAsync = promisify4(execFile8);
|
|
29773
30246
|
NONINTERACTIVE_ENV = {
|
|
29774
30247
|
...process.env,
|
|
29775
30248
|
GCM_INTERACTIVE: "Never",
|
|
@@ -30357,6 +30830,7 @@ var init_api_routes = __esm({
|
|
|
30357
30830
|
init_files();
|
|
30358
30831
|
init_git_diff();
|
|
30359
30832
|
init_git_status();
|
|
30833
|
+
init_github_actions();
|
|
30360
30834
|
init_project_icon();
|
|
30361
30835
|
init_hello();
|
|
30362
30836
|
init_local_file();
|
|
@@ -30371,6 +30845,7 @@ var init_api_routes = __esm({
|
|
|
30371
30845
|
init_project_files();
|
|
30372
30846
|
init_projects2();
|
|
30373
30847
|
init_provider_updates();
|
|
30848
|
+
init_agent_executable();
|
|
30374
30849
|
init_scripts();
|
|
30375
30850
|
init_session_config();
|
|
30376
30851
|
init_session_context();
|
|
@@ -30425,6 +30900,7 @@ var init_api_routes = __esm({
|
|
|
30425
30900
|
apiRoute("project-files", registerProjectFileRoutes),
|
|
30426
30901
|
apiRoute("project-file", registerProjectFileContentRoutes),
|
|
30427
30902
|
apiRoute("git-status", registerGitStatusRoutes),
|
|
30903
|
+
apiRoute("github-actions", registerGitHubActionsRoutes),
|
|
30428
30904
|
apiRoute("project-icon", registerProjectIconRoutes),
|
|
30429
30905
|
apiRoute("git-diff", registerGitDiffRoutes),
|
|
30430
30906
|
apiRoute("mcp", registerMcpRoutes),
|
|
@@ -30438,7 +30914,8 @@ var init_api_routes = __esm({
|
|
|
30438
30914
|
apiRoute("models", registerModelRoutes),
|
|
30439
30915
|
apiRoute("codex-threads", registerCodexThreadRoutes),
|
|
30440
30916
|
apiRoute("agent-runtime", registerAgentRuntimeRoutes),
|
|
30441
|
-
apiRoute("provider-updates", registerProviderUpdateRoutes)
|
|
30917
|
+
apiRoute("provider-updates", registerProviderUpdateRoutes),
|
|
30918
|
+
apiRoute("agent-executable", registerAgentExecutableRoutes)
|
|
30442
30919
|
];
|
|
30443
30920
|
}
|
|
30444
30921
|
});
|
|
@@ -31266,8 +31743,8 @@ var init_sessionActivityMonitor = __esm({
|
|
|
31266
31743
|
});
|
|
31267
31744
|
|
|
31268
31745
|
// ../../server/lib/standalone-bootstrap.ts
|
|
31269
|
-
import { readFileSync as
|
|
31270
|
-
function resolveEnvPassword(env = process.env, readFileFn = (p) =>
|
|
31746
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
31747
|
+
function resolveEnvPassword(env = process.env, readFileFn = (p) => readFileSync4(p, "utf-8")) {
|
|
31271
31748
|
const file = env.COGPIT_NETWORK_PASSWORD_FILE;
|
|
31272
31749
|
if (file && file.length > 0) {
|
|
31273
31750
|
const trimmed = readFileFn(file).replace(/\r?\n$/, "");
|
|
@@ -31536,7 +32013,7 @@ async function waitForShutdownSignal() {
|
|
|
31536
32013
|
for (const signal of signals) process.once(signal, done);
|
|
31537
32014
|
});
|
|
31538
32015
|
}
|
|
31539
|
-
var
|
|
32016
|
+
var defaultDependencies2 = {
|
|
31540
32017
|
fetch,
|
|
31541
32018
|
openUrl: openExternalUrl,
|
|
31542
32019
|
startServer: startPackagedServer,
|
|
@@ -31563,7 +32040,7 @@ async function verifyServer(server, command, deps) {
|
|
|
31563
32040
|
}
|
|
31564
32041
|
}
|
|
31565
32042
|
async function run(argv, overrides = {}) {
|
|
31566
|
-
const deps = { ...
|
|
32043
|
+
const deps = { ...defaultDependencies2, ...overrides };
|
|
31567
32044
|
let command;
|
|
31568
32045
|
try {
|
|
31569
32046
|
command = parseArgs(argv);
|