cogpit 2.1.2 → 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 +947 -425
- package/dist/web/assets/CommandPaletteHost--_g3tlgk.js +1 -0
- package/dist/web/assets/ConfigBrowser-DrAZQBx8.js +1 -0
- package/dist/web/assets/{HighlightedEditor-BYfv1SYX.js → HighlightedEditor-Byq8pOUC.js} +1 -1
- package/dist/web/assets/{KeyboardShortcutsDialog-YDYAOpa5.js → KeyboardShortcutsDialog-CFhdeGBw.js} +1 -1
- package/dist/web/assets/{MobileFileChanges-Bb3zEFSH.js → MobileFileChanges-uxpxh1W6.js} +1 -1
- package/dist/web/assets/{PreviewPanel-B9CQNmuh.js → PreviewPanel-DC6OTZfZ.js} +1 -1
- package/dist/web/assets/ProjectFilesPanel-ByyaiSGy.js +4 -0
- package/dist/web/assets/{ProjectSwitcherModal-CxbGrX7A.js → ProjectSwitcherModal-BRbFj3Dd.js} +1 -1
- package/dist/web/assets/{TerminalOutput-LwRcBZWA.js → TerminalOutput-Aavw8QCx.js} +1 -1
- package/dist/web/assets/{ThemeSelectorModal-BG_Jah0i.js → ThemeSelectorModal-CxGMhlkF.js} +1 -1
- package/dist/web/assets/WorkflowsPanel-Beg1AAtq.js +1 -0
- package/dist/web/assets/{WorktreePanel-gR-fCesa.js → WorktreePanel-B17_SlFC.js} +1 -1
- package/dist/web/assets/{index-EmT8Vg0x.js → index-C-5Kgwol.js} +4 -4
- package/dist/web/assets/{index-BaKcHvT2.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-Bq0_FFr0.js +0 -1
- package/dist/web/assets/ConfigBrowser-DmOlS3cU.js +0 -1
- package/dist/web/assets/ProjectFilesPanel-C3jKD37-.js +0 -4
- package/dist/web/assets/WorkflowsPanel-CiZjrfSd.js +0 -1
- package/dist/web/assets/index-Bif4Kdtn.css +0 -1
- package/dist/web/assets/index-C_pb6rZe.js +0 -1
- package/dist/web/assets/index-D-Mg0tNr.js +0 -144
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";
|
|
@@ -12414,6 +12672,35 @@ var init_timeout = __esm({
|
|
|
12414
12672
|
}
|
|
12415
12673
|
});
|
|
12416
12674
|
|
|
12675
|
+
// ../../shared/session/model-names.ts
|
|
12676
|
+
function capitalize(word) {
|
|
12677
|
+
return word.charAt(0).toUpperCase() + word.slice(1);
|
|
12678
|
+
}
|
|
12679
|
+
function shortenModel(model) {
|
|
12680
|
+
if (!model) return "unknown";
|
|
12681
|
+
const lower = model.toLowerCase();
|
|
12682
|
+
const context = /\[1m\]$/.test(lower) ? " 1M" : "";
|
|
12683
|
+
const id = lower.replace(/\[[^\]]*\]$/, "");
|
|
12684
|
+
for (const family of MODEL_FAMILIES) {
|
|
12685
|
+
const match = id.match(new RegExp(`${family}(?:-(\\d+)(?:-(\\d{1,2}))?(?!\\d))?`));
|
|
12686
|
+
if (!match) continue;
|
|
12687
|
+
const version = match[1] ? ` ${match[1]}${match[2] ? `.${match[2]}` : ""}` : "";
|
|
12688
|
+
return `${capitalize(family)}${version}${context}`;
|
|
12689
|
+
}
|
|
12690
|
+
if (id.startsWith("gpt-")) {
|
|
12691
|
+
const [version, ...rest] = id.slice(4).split("-");
|
|
12692
|
+
const suffix = rest.map(capitalize).join(" ");
|
|
12693
|
+
return `GPT-${version}${suffix ? ` ${suffix}` : ""}${context}`;
|
|
12694
|
+
}
|
|
12695
|
+
return model.length > 20 ? model.slice(0, 20) + "..." : model;
|
|
12696
|
+
}
|
|
12697
|
+
var MODEL_FAMILIES;
|
|
12698
|
+
var init_model_names = __esm({
|
|
12699
|
+
"../../shared/session/model-names.ts"() {
|
|
12700
|
+
MODEL_FAMILIES = ["fable", "mythos", "opus", "sonnet", "haiku"];
|
|
12701
|
+
}
|
|
12702
|
+
});
|
|
12703
|
+
|
|
12417
12704
|
// ../../server/agents/claudeModels.ts
|
|
12418
12705
|
import { query as query2 } from "@anthropic-ai/claude-agent-sdk";
|
|
12419
12706
|
function mapClaudeModels(models) {
|
|
@@ -12448,6 +12735,7 @@ function mapClaudeModels(models) {
|
|
|
12448
12735
|
...capabilities
|
|
12449
12736
|
});
|
|
12450
12737
|
}
|
|
12738
|
+
disambiguateLabels(options);
|
|
12451
12739
|
if (!options.some((o) => o.value === "")) {
|
|
12452
12740
|
options.unshift({ value: "", label: "Default" });
|
|
12453
12741
|
} else {
|
|
@@ -12455,6 +12743,20 @@ function mapClaudeModels(models) {
|
|
|
12455
12743
|
}
|
|
12456
12744
|
return options.length > 1 ? options : null;
|
|
12457
12745
|
}
|
|
12746
|
+
function disambiguateLabels(options) {
|
|
12747
|
+
const byLabel = /* @__PURE__ */ new Map();
|
|
12748
|
+
for (const option of options) {
|
|
12749
|
+
byLabel.set(option.label, [...byLabel.get(option.label) ?? [], option]);
|
|
12750
|
+
}
|
|
12751
|
+
for (const group of byLabel.values()) {
|
|
12752
|
+
if (group.length < 2) continue;
|
|
12753
|
+
const slots = group.map((option) => options.indexOf(option));
|
|
12754
|
+
const relabelled = group.map((option) => ({ ...option, label: shortenModel(option.resolvedModel ?? option.value) })).sort((a, b) => b.label.localeCompare(a.label, void 0, { numeric: true }));
|
|
12755
|
+
slots.forEach((slot, index) => {
|
|
12756
|
+
options[slot] = relabelled[index];
|
|
12757
|
+
});
|
|
12758
|
+
}
|
|
12759
|
+
}
|
|
12458
12760
|
async function fetchClaudeModels() {
|
|
12459
12761
|
const abort = new AbortController();
|
|
12460
12762
|
try {
|
|
@@ -12481,9 +12783,10 @@ async function fetchClaudeModels() {
|
|
|
12481
12783
|
}
|
|
12482
12784
|
var init_claudeModels = __esm({
|
|
12483
12785
|
"../../server/agents/claudeModels.ts"() {
|
|
12484
|
-
|
|
12786
|
+
init_claudeExecutable();
|
|
12485
12787
|
init_modelCatalog();
|
|
12486
12788
|
init_timeout();
|
|
12789
|
+
init_model_names();
|
|
12487
12790
|
}
|
|
12488
12791
|
});
|
|
12489
12792
|
|
|
@@ -12589,7 +12892,7 @@ function startOneShot(req) {
|
|
|
12589
12892
|
]);
|
|
12590
12893
|
const cleanEnv = { ...process.env };
|
|
12591
12894
|
delete cleanEnv.CLAUDECODE;
|
|
12592
|
-
const child =
|
|
12895
|
+
const child = spawn2(cli.command, cli.args, {
|
|
12593
12896
|
cwd: req.cwd,
|
|
12594
12897
|
env: cleanEnv,
|
|
12595
12898
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -12750,6 +13053,7 @@ var init_claudeRuntime = __esm({
|
|
|
12750
13053
|
"../../server/agents/claudeRuntime.ts"() {
|
|
12751
13054
|
init_agent_descriptors();
|
|
12752
13055
|
init_helpers();
|
|
13056
|
+
init_claudeExecutable();
|
|
12753
13057
|
init_claudeModels();
|
|
12754
13058
|
init_spawnError();
|
|
12755
13059
|
init_binaryResolver();
|
|
@@ -12896,7 +13200,7 @@ var init_package = __esm({
|
|
|
12896
13200
|
package_default = {
|
|
12897
13201
|
name: "cogpit",
|
|
12898
13202
|
private: true,
|
|
12899
|
-
version: "2.1
|
|
13203
|
+
version: "2.2.1",
|
|
12900
13204
|
description: "Control center for Claude Code, OpenAI Codex, and GitHub Copilot CLI sessions",
|
|
12901
13205
|
license: "MIT",
|
|
12902
13206
|
author: {
|
|
@@ -13006,11 +13310,11 @@ var init_package = __esm({
|
|
|
13006
13310
|
overrides: {
|
|
13007
13311
|
"@babel/core": "7.29.7",
|
|
13008
13312
|
"@hono/node-server": "1.19.15",
|
|
13009
|
-
"@xmldom/xmldom": "0.8.
|
|
13313
|
+
"@xmldom/xmldom": "0.8.15",
|
|
13010
13314
|
"app-builder-lib": "26.15.3",
|
|
13011
13315
|
"body-parser": "2.3.0",
|
|
13012
13316
|
"builder-util-runtime": "9.7.0",
|
|
13013
|
-
"fast-uri": "
|
|
13317
|
+
"fast-uri": "4.1.4",
|
|
13014
13318
|
flatted: "3.4.2",
|
|
13015
13319
|
"form-data": "4.0.6",
|
|
13016
13320
|
hono: "4.13.1",
|
|
@@ -13019,7 +13323,7 @@ var init_package = __esm({
|
|
|
13019
13323
|
lodash: "4.18.1",
|
|
13020
13324
|
nanoid: "3.3.18",
|
|
13021
13325
|
postcss: "8.5.26",
|
|
13022
|
-
qs: "6.
|
|
13326
|
+
qs: "6.16.0",
|
|
13023
13327
|
tar: "7.5.21",
|
|
13024
13328
|
tmp: "0.2.7",
|
|
13025
13329
|
undici: "7.29.0"
|
|
@@ -13135,101 +13439,6 @@ var init_codexStreamAdapter = __esm({
|
|
|
13135
13439
|
}
|
|
13136
13440
|
});
|
|
13137
13441
|
|
|
13138
|
-
// ../../shared/versions.ts
|
|
13139
|
-
function parseVersion(raw) {
|
|
13140
|
-
const match = raw.trim().replace(/^v/i, "").match(/^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/);
|
|
13141
|
-
if (!match) return null;
|
|
13142
|
-
return {
|
|
13143
|
-
parts: [Number(match[1]), Number(match[2]), Number(match[3])],
|
|
13144
|
-
prerelease: match[4] ? match[4].split(".") : []
|
|
13145
|
-
};
|
|
13146
|
-
}
|
|
13147
|
-
function extractVersion(output) {
|
|
13148
|
-
const match = output.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
|
|
13149
|
-
return match ? match[0] : null;
|
|
13150
|
-
}
|
|
13151
|
-
function comparePrerelease(a, b) {
|
|
13152
|
-
if (a.length === 0 && b.length === 0) return 0;
|
|
13153
|
-
if (a.length === 0) return 1;
|
|
13154
|
-
if (b.length === 0) return -1;
|
|
13155
|
-
for (let i = 0; i < Math.max(a.length, b.length); i += 1) {
|
|
13156
|
-
const left = a[i];
|
|
13157
|
-
const right = b[i];
|
|
13158
|
-
if (left === void 0) return -1;
|
|
13159
|
-
if (right === void 0) return 1;
|
|
13160
|
-
const leftNumeric = /^\d+$/.test(left);
|
|
13161
|
-
const rightNumeric = /^\d+$/.test(right);
|
|
13162
|
-
if (leftNumeric && rightNumeric) {
|
|
13163
|
-
if (Number(left) !== Number(right)) return Number(left) < Number(right) ? -1 : 1;
|
|
13164
|
-
continue;
|
|
13165
|
-
}
|
|
13166
|
-
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
13167
|
-
if (left !== right) return left < right ? -1 : 1;
|
|
13168
|
-
}
|
|
13169
|
-
return 0;
|
|
13170
|
-
}
|
|
13171
|
-
function compareVersions(a, b) {
|
|
13172
|
-
const left = parseVersion(a);
|
|
13173
|
-
const right = parseVersion(b);
|
|
13174
|
-
if (!left || !right) return null;
|
|
13175
|
-
for (let i = 0; i < 3; i += 1) {
|
|
13176
|
-
if (left.parts[i] !== right.parts[i]) return left.parts[i] < right.parts[i] ? -1 : 1;
|
|
13177
|
-
}
|
|
13178
|
-
return comparePrerelease(left.prerelease, right.prerelease);
|
|
13179
|
-
}
|
|
13180
|
-
var init_versions = __esm({
|
|
13181
|
-
"../../shared/versions.ts"() {
|
|
13182
|
-
}
|
|
13183
|
-
});
|
|
13184
|
-
|
|
13185
|
-
// ../../server/lib/cliProcess.ts
|
|
13186
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
13187
|
-
function runCli(executable, args, timeoutMs) {
|
|
13188
|
-
return new Promise((resolve21) => {
|
|
13189
|
-
const resolved = resolveAgentCommand(executable, [...args]);
|
|
13190
|
-
const child = spawn2(resolved.command, resolved.args, {
|
|
13191
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
13192
|
-
...resolved.spawnOptions
|
|
13193
|
-
});
|
|
13194
|
-
let stdout = "";
|
|
13195
|
-
let stderr = "";
|
|
13196
|
-
let timedOut = false;
|
|
13197
|
-
const timer = setTimeout(() => {
|
|
13198
|
-
timedOut = true;
|
|
13199
|
-
child.kill("SIGKILL");
|
|
13200
|
-
}, timeoutMs);
|
|
13201
|
-
const append = (buffer, chunk) => buffer.length >= CLI_OUTPUT_MAX_CHARS ? buffer : buffer + chunk.toString();
|
|
13202
|
-
child.stdout?.on("data", (chunk) => {
|
|
13203
|
-
stdout = append(stdout, chunk);
|
|
13204
|
-
});
|
|
13205
|
-
child.stderr?.on("data", (chunk) => {
|
|
13206
|
-
stderr = append(stderr, chunk);
|
|
13207
|
-
});
|
|
13208
|
-
child.on("error", () => {
|
|
13209
|
-
clearTimeout(timer);
|
|
13210
|
-
resolve21({ code: null, stdout, stderr, timedOut });
|
|
13211
|
-
});
|
|
13212
|
-
child.on("close", (code) => {
|
|
13213
|
-
clearTimeout(timer);
|
|
13214
|
-
resolve21({ code, stdout, stderr, timedOut });
|
|
13215
|
-
});
|
|
13216
|
-
});
|
|
13217
|
-
}
|
|
13218
|
-
async function probeCliVersion(command, versionArgs, timeoutMs = DEFAULT_PROBE_TIMEOUT_MS) {
|
|
13219
|
-
const probe = await runCli(command, versionArgs, timeoutMs);
|
|
13220
|
-
return extractVersion(`${probe.stdout}
|
|
13221
|
-
${probe.stderr}`);
|
|
13222
|
-
}
|
|
13223
|
-
var DEFAULT_PROBE_TIMEOUT_MS, CLI_OUTPUT_MAX_CHARS;
|
|
13224
|
-
var init_cliProcess = __esm({
|
|
13225
|
-
"../../server/lib/cliProcess.ts"() {
|
|
13226
|
-
init_versions();
|
|
13227
|
-
init_binaryResolver();
|
|
13228
|
-
DEFAULT_PROBE_TIMEOUT_MS = 5e3;
|
|
13229
|
-
CLI_OUTPUT_MAX_CHARS = 1e4;
|
|
13230
|
-
}
|
|
13231
|
-
});
|
|
13232
|
-
|
|
13233
13442
|
// ../../server/lib/codexVersion.ts
|
|
13234
13443
|
function parseUserAgentVersion(userAgent) {
|
|
13235
13444
|
if (typeof userAgent !== "string") return null;
|
|
@@ -14460,7 +14669,7 @@ async function startLegacy(req, knownPaths) {
|
|
|
14460
14669
|
...args.turnArgs,
|
|
14461
14670
|
...args.promptArgs
|
|
14462
14671
|
]);
|
|
14463
|
-
const child =
|
|
14672
|
+
const child = spawn2(cli.command, cli.args, {
|
|
14464
14673
|
cwd: req.cwd,
|
|
14465
14674
|
env: process.env,
|
|
14466
14675
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -14552,7 +14761,7 @@ async function sendLegacy(sessionId, req) {
|
|
|
14552
14761
|
sessionId,
|
|
14553
14762
|
...args.promptArgs
|
|
14554
14763
|
]);
|
|
14555
|
-
const child =
|
|
14764
|
+
const child = spawn2(cli.command, cli.args, {
|
|
14556
14765
|
cwd: req.cwd,
|
|
14557
14766
|
env: process.env,
|
|
14558
14767
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -15995,17 +16204,17 @@ function parseJsonRecord(line) {
|
|
|
15995
16204
|
}
|
|
15996
16205
|
}
|
|
15997
16206
|
function parseClaudeUsageLine(line) {
|
|
15998
|
-
const
|
|
15999
|
-
if (!
|
|
16000
|
-
const message = asRecord3(
|
|
16207
|
+
const record3 = parseJsonRecord(line);
|
|
16208
|
+
if (!record3 || record3.type !== "assistant") return null;
|
|
16209
|
+
const message = asRecord3(record3.message);
|
|
16001
16210
|
const usage = message ? asRecord3(message.usage) : null;
|
|
16002
16211
|
if (!message || !usage) return null;
|
|
16003
|
-
const timestampMs = parseTimestampMs(
|
|
16212
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16004
16213
|
if (timestampMs === null) return null;
|
|
16005
16214
|
const model = typeof message.model === "string" ? message.model : "";
|
|
16006
16215
|
if (model.length === 0) return null;
|
|
16007
16216
|
const messageId = typeof message.id === "string" ? message.id : null;
|
|
16008
|
-
const requestId = typeof
|
|
16217
|
+
const requestId = typeof record3.requestId === "string" ? record3.requestId : null;
|
|
16009
16218
|
const dedupeKey = messageId === null && requestId === null ? null : `${messageId ?? ""}:${requestId ?? ""}`;
|
|
16010
16219
|
const cacheCreationTokens = int(usage.cache_creation_input_tokens);
|
|
16011
16220
|
const byTtl = asRecord3(usage.cache_creation);
|
|
@@ -16024,12 +16233,12 @@ function parseClaudeUsageLine(line) {
|
|
|
16024
16233
|
reasoningTokens: 0
|
|
16025
16234
|
};
|
|
16026
16235
|
if (totalUsageCostTokens(totals) === 0) return null;
|
|
16027
|
-
const cost =
|
|
16236
|
+
const cost = record3.costUSD;
|
|
16028
16237
|
return {
|
|
16029
16238
|
provider: "claude",
|
|
16030
16239
|
timestampMs,
|
|
16031
16240
|
model,
|
|
16032
|
-
sessionId: typeof
|
|
16241
|
+
sessionId: typeof record3.sessionId === "string" ? record3.sessionId : "",
|
|
16033
16242
|
totals,
|
|
16034
16243
|
reportedCostUsd: typeof cost === "number" && Number.isFinite(cost) ? cost : null,
|
|
16035
16244
|
dedupeKey
|
|
@@ -16051,30 +16260,30 @@ function isForkedSessionMeta(payload) {
|
|
|
16051
16260
|
return typeof spawn5?.parent_thread_id === "string";
|
|
16052
16261
|
}
|
|
16053
16262
|
function parseCodexUsageLine(line, state) {
|
|
16054
|
-
const
|
|
16055
|
-
if (!
|
|
16056
|
-
const payload = asRecord3(
|
|
16263
|
+
const record3 = parseJsonRecord(line);
|
|
16264
|
+
if (!record3) return null;
|
|
16265
|
+
const payload = asRecord3(record3.payload);
|
|
16057
16266
|
if (!payload) return null;
|
|
16058
|
-
if (
|
|
16267
|
+
if (record3.type === "session_meta") {
|
|
16059
16268
|
if (state.sawSessionMeta) return null;
|
|
16060
16269
|
state.sawSessionMeta = true;
|
|
16061
16270
|
const id = payload.id ?? payload.session_id;
|
|
16062
16271
|
if (typeof id === "string") state.sessionId = id;
|
|
16063
|
-
const metaTimestampMs = parseTimestampMs(
|
|
16272
|
+
const metaTimestampMs = parseTimestampMs(record3.timestamp);
|
|
16064
16273
|
if (metaTimestampMs !== null && isForkedSessionMeta(payload)) {
|
|
16065
16274
|
state.suppressingForkCopies = true;
|
|
16066
16275
|
state.forkCopyAnchorMs = metaTimestampMs;
|
|
16067
16276
|
}
|
|
16068
16277
|
return null;
|
|
16069
16278
|
}
|
|
16070
|
-
if (
|
|
16279
|
+
if (record3.type === "turn_context") {
|
|
16071
16280
|
if (typeof payload.model === "string") state.model = payload.model;
|
|
16072
16281
|
return null;
|
|
16073
16282
|
}
|
|
16074
16283
|
if (payload.type !== "token_count") return null;
|
|
16075
16284
|
const last = asRecord3(asRecord3(payload.info)?.last_token_usage);
|
|
16076
16285
|
if (!last) return null;
|
|
16077
|
-
const timestampMs = parseTimestampMs(
|
|
16286
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16078
16287
|
if (timestampMs === null) return null;
|
|
16079
16288
|
if (state.model.length === 0) return null;
|
|
16080
16289
|
const signature = JSON.stringify(last);
|
|
@@ -16173,17 +16382,17 @@ function parseCopilotUsageMetrics(value, state, timestampMs) {
|
|
|
16173
16382
|
return records;
|
|
16174
16383
|
}
|
|
16175
16384
|
function parseCopilotUsageLine(line, state) {
|
|
16176
|
-
const
|
|
16177
|
-
if (!
|
|
16178
|
-
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);
|
|
16179
16388
|
if (!data) return [];
|
|
16180
|
-
if (
|
|
16389
|
+
if (record3.type === "session.start") {
|
|
16181
16390
|
const sessionId = data.sessionId;
|
|
16182
16391
|
if (typeof sessionId === "string" && sessionId.length > 0) state.sessionId = sessionId;
|
|
16183
16392
|
return [];
|
|
16184
16393
|
}
|
|
16185
|
-
if (
|
|
16186
|
-
const timestampMs = parseTimestampMs(
|
|
16394
|
+
if (record3.type !== "session.shutdown") return [];
|
|
16395
|
+
const timestampMs = parseTimestampMs(record3.timestamp);
|
|
16187
16396
|
return timestampMs === null ? [] : parseCopilotUsageMetrics(data, state, timestampMs);
|
|
16188
16397
|
}
|
|
16189
16398
|
function createUsageScanner(provider, filePath) {
|
|
@@ -16200,8 +16409,8 @@ var init_usageScanners = __esm({
|
|
|
16200
16409
|
// object, so a line is either self-contained or of no interest.
|
|
16201
16410
|
wantsLine: (line) => line.includes('"usage"'),
|
|
16202
16411
|
accept: (line) => {
|
|
16203
|
-
const
|
|
16204
|
-
return
|
|
16412
|
+
const record3 = parseClaudeUsageLine(line);
|
|
16413
|
+
return record3 === null ? [] : [record3];
|
|
16205
16414
|
}
|
|
16206
16415
|
}),
|
|
16207
16416
|
codex: () => {
|
|
@@ -16212,8 +16421,8 @@ var init_usageScanners = __esm({
|
|
|
16212
16421
|
// at all but still have to reach the reducer.
|
|
16213
16422
|
wantsLine: (line) => line.includes('"token_count"') || line.includes('"turn_context"') || line.includes('"session_meta"'),
|
|
16214
16423
|
accept: (line) => {
|
|
16215
|
-
const
|
|
16216
|
-
return
|
|
16424
|
+
const record3 = parseCodexUsageLine(line, state);
|
|
16425
|
+
return record3 === null ? [] : [record3];
|
|
16217
16426
|
}
|
|
16218
16427
|
};
|
|
16219
16428
|
},
|
|
@@ -17095,11 +17304,11 @@ function registerRunningProcessesRoute(use) {
|
|
|
17095
17304
|
if (url.pathname.split("/").filter(Boolean).length > 0) return next();
|
|
17096
17305
|
const isWindows2 = process.platform === "win32";
|
|
17097
17306
|
const nameFilter = allDescriptors().map(windowsProcessNameFilter).join(" or ");
|
|
17098
|
-
const child = isWindows2 ?
|
|
17307
|
+
const child = isWindows2 ? spawn2("powershell", [
|
|
17099
17308
|
"-NoProfile",
|
|
17100
17309
|
"-Command",
|
|
17101
17310
|
`Get-CimInstance Win32_Process -Filter "${nameFilter}" | Select-Object ProcessId, WorkingSetSize, CommandLine | ConvertTo-Json -Compress`
|
|
17102
|
-
]) :
|
|
17311
|
+
]) : spawn2("ps", ["aux"]);
|
|
17103
17312
|
let stdout = "";
|
|
17104
17313
|
let responded = false;
|
|
17105
17314
|
child.stdout?.on("data", (data) => {
|
|
@@ -17462,12 +17671,12 @@ function registerBranchSessionRoute(use) {
|
|
|
17462
17671
|
}
|
|
17463
17672
|
}
|
|
17464
17673
|
const newSessionId = randomUUID2();
|
|
17465
|
-
const { record:
|
|
17674
|
+
const { record: record3, originalId } = format.brandBranch(
|
|
17466
17675
|
JSON.parse(lines[0]),
|
|
17467
17676
|
newSessionId,
|
|
17468
17677
|
turnIndex ?? null
|
|
17469
17678
|
);
|
|
17470
|
-
lines[0] = JSON.stringify(
|
|
17679
|
+
lines[0] = JSON.stringify(record3);
|
|
17471
17680
|
const target = storeForDirName(dirName).transcriptPath(dirName, newSessionId);
|
|
17472
17681
|
if (!target) {
|
|
17473
17682
|
res.statusCode = 500;
|
|
@@ -18010,11 +18219,11 @@ import {
|
|
|
18010
18219
|
dirname as dirname5,
|
|
18011
18220
|
isAbsolute as isAbsolute3,
|
|
18012
18221
|
join as join13,
|
|
18013
|
-
posix as
|
|
18222
|
+
posix as posix3,
|
|
18014
18223
|
relative as relative4,
|
|
18015
18224
|
resolve as resolve9,
|
|
18016
18225
|
sep as sep5,
|
|
18017
|
-
win32 as
|
|
18226
|
+
win32 as win323
|
|
18018
18227
|
} from "node:path";
|
|
18019
18228
|
function configuredAgentHomes() {
|
|
18020
18229
|
return new Set(AGENT_KINDS.map((kind) => agentHomeDir(kind)));
|
|
@@ -18123,7 +18332,7 @@ async function resolveConfigBrowserPath(filePath, options = {}) {
|
|
|
18123
18332
|
function isSafeConfigName(name) {
|
|
18124
18333
|
if (!name || name === "." || name === ".." || name.includes("\0")) return false;
|
|
18125
18334
|
if (name.includes("/") || name.includes("\\")) return false;
|
|
18126
|
-
if (isAbsolute3(name) ||
|
|
18335
|
+
if (isAbsolute3(name) || posix3.parse(name).root || win323.parse(name).root) return false;
|
|
18127
18336
|
return true;
|
|
18128
18337
|
}
|
|
18129
18338
|
function isUnderDir(parentDir, dirName) {
|
|
@@ -19366,7 +19575,8 @@ function registerConfigRoutes(use) {
|
|
|
19366
19575
|
networkPassword: config.networkPassword ? "set" : null,
|
|
19367
19576
|
terminalApp: config.terminalApp || null,
|
|
19368
19577
|
editorApp: config.editorApp || null,
|
|
19369
|
-
useBuiltInEditor: config.useBuiltInEditor || false
|
|
19578
|
+
useBuiltInEditor: config.useBuiltInEditor || false,
|
|
19579
|
+
agentExecutable: config.agentExecutable ?? DEFAULT_EXECUTABLE_CHOICE
|
|
19370
19580
|
} : null));
|
|
19371
19581
|
return;
|
|
19372
19582
|
}
|
|
@@ -19429,7 +19639,8 @@ function registerConfigRoutes(use) {
|
|
|
19429
19639
|
networkPassword: finalPassword,
|
|
19430
19640
|
terminalApp: parsed.terminalApp || void 0,
|
|
19431
19641
|
editorApp: parsed.editorApp || void 0,
|
|
19432
|
-
useBuiltInEditor: !!parsed.useBuiltInEditor
|
|
19642
|
+
useBuiltInEditor: !!parsed.useBuiltInEditor,
|
|
19643
|
+
agentExecutable: parseExecutableChoice(parsed.agentExecutable)
|
|
19433
19644
|
});
|
|
19434
19645
|
refreshDirs();
|
|
19435
19646
|
if (currentConfig && resolve11(resolvedClaudeDir) !== resolve11(currentConfig.claudeDir)) {
|
|
@@ -19464,12 +19675,13 @@ var init_config2 = __esm({
|
|
|
19464
19675
|
init_users();
|
|
19465
19676
|
init_config();
|
|
19466
19677
|
init_agent_descriptors();
|
|
19678
|
+
init_agentExecutable();
|
|
19467
19679
|
init_sessionPersistence();
|
|
19468
19680
|
}
|
|
19469
19681
|
});
|
|
19470
19682
|
|
|
19471
19683
|
// ../../server/routes/hello.ts
|
|
19472
|
-
import { readFileSync } from "node:fs";
|
|
19684
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
19473
19685
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
19474
19686
|
import { hostname } from "node:os";
|
|
19475
19687
|
import { join as join18 } from "node:path";
|
|
@@ -19518,7 +19730,7 @@ var init_hello = __esm({
|
|
|
19518
19730
|
join18(__dirname2, "../package.json")
|
|
19519
19731
|
]) {
|
|
19520
19732
|
try {
|
|
19521
|
-
const pkg = JSON.parse(
|
|
19733
|
+
const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
|
|
19522
19734
|
if (typeof pkg.version === "string") return pkg.version;
|
|
19523
19735
|
} catch {
|
|
19524
19736
|
}
|
|
@@ -20749,7 +20961,7 @@ function registerFileRoutes(use) {
|
|
|
20749
20961
|
try {
|
|
20750
20962
|
let spawnLines = function(args, cwd) {
|
|
20751
20963
|
return new Promise((resolve21) => {
|
|
20752
|
-
const proc =
|
|
20964
|
+
const proc = spawn2("git", args, { cwd });
|
|
20753
20965
|
let out = "";
|
|
20754
20966
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20755
20967
|
proc.on("close", (code) => {
|
|
@@ -20760,7 +20972,7 @@ function registerFileRoutes(use) {
|
|
|
20760
20972
|
});
|
|
20761
20973
|
}, spawnOutput = function(args, cwd) {
|
|
20762
20974
|
return new Promise((resolve21) => {
|
|
20763
|
-
const proc =
|
|
20975
|
+
const proc = spawn2("git", args, { cwd });
|
|
20764
20976
|
let out = "";
|
|
20765
20977
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20766
20978
|
proc.on("close", () => resolve21(out.trim()));
|
|
@@ -20789,7 +21001,7 @@ function registerFileRoutes(use) {
|
|
|
20789
21001
|
}
|
|
20790
21002
|
}
|
|
20791
21003
|
return new Promise((resolve21) => {
|
|
20792
|
-
const proc =
|
|
21004
|
+
const proc = spawn2("git", ["rev-parse", "--show-toplevel"], { cwd });
|
|
20793
21005
|
let out = "";
|
|
20794
21006
|
proc.stdout.on("data", (d) => out += d.toString());
|
|
20795
21007
|
proc.on("close", (code) => {
|
|
@@ -21034,11 +21246,11 @@ function parseGitStatus(output) {
|
|
|
21034
21246
|
const branch = parseBranchHeader(header);
|
|
21035
21247
|
const files = [];
|
|
21036
21248
|
for (let index = 0; index < records.length; index += 1) {
|
|
21037
|
-
const
|
|
21038
|
-
if (!
|
|
21039
|
-
const indexStatus =
|
|
21040
|
-
const workTreeStatus =
|
|
21041
|
-
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);
|
|
21042
21254
|
const renamedOrCopied = /[RC]/.test(`${indexStatus}${workTreeStatus}`);
|
|
21043
21255
|
const originalPath = renamedOrCopied ? records[index += 1] || void 0 : void 0;
|
|
21044
21256
|
files.push({ path, originalPath, indexStatus, workTreeStatus });
|
|
@@ -21093,6 +21305,272 @@ var init_git_status = __esm({
|
|
|
21093
21305
|
}
|
|
21094
21306
|
});
|
|
21095
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
|
+
|
|
21096
21574
|
// ../../server/lib/projectIcon.ts
|
|
21097
21575
|
import { realpath as realpath8, stat as stat13 } from "node:fs/promises";
|
|
21098
21576
|
import { basename as basename9, extname, join as join20, relative as relative8, sep as sep10 } from "node:path";
|
|
@@ -21276,7 +21754,7 @@ var init_local_file = __esm({
|
|
|
21276
21754
|
});
|
|
21277
21755
|
|
|
21278
21756
|
// ../../server/routes/mcp.ts
|
|
21279
|
-
import { execFile as
|
|
21757
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
21280
21758
|
import { isAbsolute as isAbsolute9, join as join21 } from "node:path";
|
|
21281
21759
|
import { readFile as readFile15 } from "node:fs/promises";
|
|
21282
21760
|
import { homedir as homedir7 } from "node:os";
|
|
@@ -21357,7 +21835,7 @@ async function getMcpServers(cwd) {
|
|
|
21357
21835
|
const env = { ...process.env };
|
|
21358
21836
|
delete env.CLAUDECODE;
|
|
21359
21837
|
const cli = resolveAgentCommand("claude", ["mcp", "list"]);
|
|
21360
|
-
|
|
21838
|
+
execFile4(cli.command, cli.args, { cwd, env, timeout: 15e3, ...cli.spawnOptions }, (err, stdout) => {
|
|
21361
21839
|
if (err) {
|
|
21362
21840
|
resolve21({ servers: cached?.servers ?? [], configs });
|
|
21363
21841
|
return;
|
|
@@ -22156,8 +22634,8 @@ function copilotText(value) {
|
|
|
22156
22634
|
if (!Array.isArray(value)) return "";
|
|
22157
22635
|
return value.flatMap((part) => {
|
|
22158
22636
|
if (typeof part === "string") return part ? [part] : [];
|
|
22159
|
-
const
|
|
22160
|
-
const text = str(
|
|
22637
|
+
const record3 = asRecord5(part);
|
|
22638
|
+
const text = str(record3.text) || str(record3.content);
|
|
22161
22639
|
return text ? [text] : [];
|
|
22162
22640
|
}).join("\n");
|
|
22163
22641
|
}
|
|
@@ -22860,7 +23338,7 @@ var init_notifications = __esm({
|
|
|
22860
23338
|
});
|
|
22861
23339
|
|
|
22862
23340
|
// ../../server/lib/systemProcesses.ts
|
|
22863
|
-
import { execFile as
|
|
23341
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
22864
23342
|
function parseEtimeSeconds(etime) {
|
|
22865
23343
|
const match = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/.exec(etime.trim());
|
|
22866
23344
|
if (!match) return 0;
|
|
@@ -22982,7 +23460,7 @@ function classifyProcesses(rows, selfPid) {
|
|
|
22982
23460
|
}
|
|
22983
23461
|
function listSystemProcesses() {
|
|
22984
23462
|
return new Promise((resolve21, reject) => {
|
|
22985
|
-
|
|
23463
|
+
execFile5(
|
|
22986
23464
|
"ps",
|
|
22987
23465
|
["-axo", "pid=,ppid=,pcpu=,rss=,etime=,args="],
|
|
22988
23466
|
{ maxBuffer: 8 * 1024 * 1024 },
|
|
@@ -23020,7 +23498,7 @@ var init_systemProcesses = __esm({
|
|
|
23020
23498
|
});
|
|
23021
23499
|
|
|
23022
23500
|
// ../../server/lib/desktopNotify.ts
|
|
23023
|
-
import { execFile as
|
|
23501
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
23024
23502
|
function parentMessagePort() {
|
|
23025
23503
|
const { parentPort } = process;
|
|
23026
23504
|
return parentPort && typeof parentPort.postMessage === "function" ? parentPort : null;
|
|
@@ -23033,7 +23511,7 @@ function showNotification(title, body, nav, historyId) {
|
|
|
23033
23511
|
return;
|
|
23034
23512
|
}
|
|
23035
23513
|
if (process.platform === "darwin") {
|
|
23036
|
-
|
|
23514
|
+
execFile6(
|
|
23037
23515
|
"osascript",
|
|
23038
23516
|
["-e", `display notification "${escapeAppleScript(body)}" with title "${escapeAppleScript(title)}"`],
|
|
23039
23517
|
// This is the standalone server's only desktop channel, so a silent
|
|
@@ -23074,7 +23552,7 @@ var init_notifications2 = __esm({
|
|
|
23074
23552
|
});
|
|
23075
23553
|
|
|
23076
23554
|
// ../../server/lib/pushConfig.ts
|
|
23077
|
-
import { readFileSync as
|
|
23555
|
+
import { readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
|
|
23078
23556
|
import { homedir as homedir9 } from "node:os";
|
|
23079
23557
|
import { join as join23 } from "node:path";
|
|
23080
23558
|
function warnOnce(message) {
|
|
@@ -23087,7 +23565,7 @@ function asString(value) {
|
|
|
23087
23565
|
}
|
|
23088
23566
|
function fileMtime(path) {
|
|
23089
23567
|
try {
|
|
23090
|
-
return
|
|
23568
|
+
return statSync3(path).mtimeMs;
|
|
23091
23569
|
} catch {
|
|
23092
23570
|
return null;
|
|
23093
23571
|
}
|
|
@@ -23102,8 +23580,8 @@ function warnIfExposed(path, mode) {
|
|
|
23102
23580
|
function readConfigFile(path) {
|
|
23103
23581
|
let raw;
|
|
23104
23582
|
try {
|
|
23105
|
-
warnIfExposed(path,
|
|
23106
|
-
raw =
|
|
23583
|
+
warnIfExposed(path, statSync3(path).mode);
|
|
23584
|
+
raw = readFileSync3(path, "utf8");
|
|
23107
23585
|
} catch (err) {
|
|
23108
23586
|
const code = err.code;
|
|
23109
23587
|
if (code !== "ENOENT") warnOnce(`Could not read ${path}: ${code ?? String(err)}`);
|
|
@@ -23906,7 +24384,7 @@ var init_backgroundAgents = __esm({
|
|
|
23906
24384
|
// ../../server/routes/ports/listeningProcesses.ts
|
|
23907
24385
|
function runCapture(command, args) {
|
|
23908
24386
|
return new Promise((resolve21, reject) => {
|
|
23909
|
-
const child =
|
|
24387
|
+
const child = spawn2(command, args);
|
|
23910
24388
|
let stdout = "";
|
|
23911
24389
|
child.stdout?.on("data", (data) => {
|
|
23912
24390
|
stdout += data.toString();
|
|
@@ -24193,13 +24671,13 @@ var init_project_files_ranking = __esm({
|
|
|
24193
24671
|
});
|
|
24194
24672
|
|
|
24195
24673
|
// ../../server/routes/project-files.ts
|
|
24196
|
-
import { execFile as
|
|
24674
|
+
import { execFile as execFileCallback3 } from "node:child_process";
|
|
24197
24675
|
import { readdir as readdir11, realpath as realpath10, stat as stat16 } from "node:fs/promises";
|
|
24198
24676
|
import { isAbsolute as isAbsolute11, relative as relative9, resolve as resolve17, sep as sep11 } from "node:path";
|
|
24199
|
-
import { promisify as
|
|
24677
|
+
import { promisify as promisify3 } from "node:util";
|
|
24200
24678
|
async function listGitProjectFiles(root) {
|
|
24201
24679
|
try {
|
|
24202
|
-
const result = await
|
|
24680
|
+
const result = await execFile7(
|
|
24203
24681
|
"git",
|
|
24204
24682
|
["ls-files", "--cached", "--others", "--exclude-standard", "-z", "--", "."],
|
|
24205
24683
|
{
|
|
@@ -24275,7 +24753,7 @@ function registerProjectFileRoutes(use) {
|
|
|
24275
24753
|
}
|
|
24276
24754
|
});
|
|
24277
24755
|
}
|
|
24278
|
-
var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache,
|
|
24756
|
+
var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache, execFile7;
|
|
24279
24757
|
var init_project_files = __esm({
|
|
24280
24758
|
"../../server/routes/project-files.ts"() {
|
|
24281
24759
|
init_http();
|
|
@@ -24296,7 +24774,7 @@ var init_project_files = __esm({
|
|
|
24296
24774
|
"target"
|
|
24297
24775
|
]);
|
|
24298
24776
|
fileCache = /* @__PURE__ */ new Map();
|
|
24299
|
-
|
|
24777
|
+
execFile7 = promisify3(execFileCallback3);
|
|
24300
24778
|
}
|
|
24301
24779
|
});
|
|
24302
24780
|
|
|
@@ -24559,12 +25037,12 @@ function createPullRequestScanner() {
|
|
|
24559
25037
|
const command = findCreateCommand(input);
|
|
24560
25038
|
if (command) openCreates.set(id, { command, timestamp });
|
|
24561
25039
|
}
|
|
24562
|
-
function recordPrLink(
|
|
24563
|
-
const url =
|
|
24564
|
-
const number =
|
|
25040
|
+
function recordPrLink(record3, timestamp) {
|
|
25041
|
+
const url = record3.prUrl;
|
|
25042
|
+
const number = record3.prNumber;
|
|
24565
25043
|
if (typeof url !== "string" || !url) return;
|
|
24566
25044
|
if (typeof number !== "number" || !Number.isInteger(number) || number <= 0) return;
|
|
24567
|
-
const repo = typeof
|
|
25045
|
+
const repo = typeof record3.prRepository === "string" ? record3.prRepository : "";
|
|
24568
25046
|
collector.add({
|
|
24569
25047
|
url,
|
|
24570
25048
|
number,
|
|
@@ -24599,19 +25077,19 @@ function createPullRequestScanner() {
|
|
|
24599
25077
|
if (!line.includes(GH_PR_HINT) && !line.includes(URL_HINT) && !line.includes(PR_LINK_HINT)) {
|
|
24600
25078
|
return;
|
|
24601
25079
|
}
|
|
24602
|
-
let
|
|
25080
|
+
let record3;
|
|
24603
25081
|
try {
|
|
24604
|
-
|
|
25082
|
+
record3 = JSON.parse(line);
|
|
24605
25083
|
} catch {
|
|
24606
25084
|
return;
|
|
24607
25085
|
}
|
|
24608
|
-
if (!isRecord5(
|
|
24609
|
-
const timestamp = typeof
|
|
24610
|
-
if (
|
|
24611
|
-
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);
|
|
24612
25090
|
return;
|
|
24613
25091
|
}
|
|
24614
|
-
const payload =
|
|
25092
|
+
const payload = record3.payload;
|
|
24615
25093
|
if (isRecord5(payload)) {
|
|
24616
25094
|
const type = payload.type;
|
|
24617
25095
|
if (type === "function_call" || type === "custom_tool_call") {
|
|
@@ -24621,15 +25099,15 @@ function createPullRequestScanner() {
|
|
|
24621
25099
|
}
|
|
24622
25100
|
return;
|
|
24623
25101
|
}
|
|
24624
|
-
const data =
|
|
25102
|
+
const data = record3.data;
|
|
24625
25103
|
if (isRecord5(data)) {
|
|
24626
|
-
if (
|
|
25104
|
+
if (record3.type === "tool.execution_start") {
|
|
24627
25105
|
recordToolCall(
|
|
24628
25106
|
data.toolCallId,
|
|
24629
25107
|
parseArgs2(data.arguments ?? data.input),
|
|
24630
25108
|
timestamp
|
|
24631
25109
|
);
|
|
24632
|
-
} else if (
|
|
25110
|
+
} else if (record3.type === "tool.execution_complete") {
|
|
24633
25111
|
recordResult(
|
|
24634
25112
|
data.toolCallId,
|
|
24635
25113
|
data.result ?? data.output ?? data.error,
|
|
@@ -24638,7 +25116,7 @@ function createPullRequestScanner() {
|
|
|
24638
25116
|
}
|
|
24639
25117
|
return;
|
|
24640
25118
|
}
|
|
24641
|
-
const message =
|
|
25119
|
+
const message = record3.message;
|
|
24642
25120
|
if (!isRecord5(message) || !Array.isArray(message.content)) return;
|
|
24643
25121
|
for (const block of message.content) {
|
|
24644
25122
|
if (!isRecord5(block)) continue;
|
|
@@ -25502,6 +25980,19 @@ var init_projects2 = __esm({
|
|
|
25502
25980
|
}
|
|
25503
25981
|
});
|
|
25504
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
|
+
|
|
25505
25996
|
// ../../server/lib/providerUpdates.ts
|
|
25506
25997
|
import { realpathSync } from "node:fs";
|
|
25507
25998
|
function deriveStatus(current, latest) {
|
|
@@ -25604,8 +26095,8 @@ function buildUpdateCommand(provider, method) {
|
|
|
25604
26095
|
function formatCommand(command) {
|
|
25605
26096
|
return [command.executable, ...command.args].join(" ");
|
|
25606
26097
|
}
|
|
25607
|
-
function resolveBinaryPaths(
|
|
25608
|
-
const onPath = findExecutableOnPath(binName);
|
|
26098
|
+
function resolveBinaryPaths(descriptor7) {
|
|
26099
|
+
const onPath = activeExecutableFor(descriptor7.kind) ?? findExecutableOnPath(descriptor7.binName);
|
|
25609
26100
|
if (!onPath) return [];
|
|
25610
26101
|
try {
|
|
25611
26102
|
const real = realpathSync(onPath);
|
|
@@ -25654,7 +26145,7 @@ function fetchLatestVersion(packageName) {
|
|
|
25654
26145
|
});
|
|
25655
26146
|
}
|
|
25656
26147
|
async function probeProvider(descriptor7) {
|
|
25657
|
-
const paths = resolveBinaryPaths(descriptor7
|
|
26148
|
+
const paths = resolveBinaryPaths(descriptor7);
|
|
25658
26149
|
const base = {
|
|
25659
26150
|
provider: descriptor7.kind,
|
|
25660
26151
|
displayName: descriptor7.displayName,
|
|
@@ -25763,6 +26254,7 @@ var init_providerUpdates = __esm({
|
|
|
25763
26254
|
"../../server/lib/providerUpdates.ts"() {
|
|
25764
26255
|
init_agent_descriptors();
|
|
25765
26256
|
init_versions();
|
|
26257
|
+
init_executables();
|
|
25766
26258
|
init_binaryResolver();
|
|
25767
26259
|
init_cliProcess();
|
|
25768
26260
|
REGISTRY_TIMEOUT_MS = 4e3;
|
|
@@ -25819,6 +26311,32 @@ var init_provider_updates = __esm({
|
|
|
25819
26311
|
}
|
|
25820
26312
|
});
|
|
25821
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
|
+
|
|
25822
26340
|
// ../../server/routes/scripts/discovery.ts
|
|
25823
26341
|
import { readdir as readdir12, readFile as readFile19 } from "node:fs/promises";
|
|
25824
26342
|
import { join as join25, relative as relative10 } from "node:path";
|
|
@@ -26734,7 +27252,7 @@ function normalizeCopilotFileChangeEvents(jsonlContent) {
|
|
|
26734
27252
|
}
|
|
26735
27253
|
});
|
|
26736
27254
|
}
|
|
26737
|
-
return records.map((
|
|
27255
|
+
return records.map((record3) => JSON.stringify(record3)).join("\n");
|
|
26738
27256
|
}
|
|
26739
27257
|
async function parseSessionFileChanges(jsonlContent, includeContent) {
|
|
26740
27258
|
if (formatForText(jsonlContent).kind === "copilot") {
|
|
@@ -28703,20 +29221,20 @@ var init_aggregate = __esm({
|
|
|
28703
29221
|
this.#toDay = makeDayFormatter(options.timeZone);
|
|
28704
29222
|
}
|
|
28705
29223
|
/** Folds one record in; returns whether it actually contributed. */
|
|
28706
|
-
add(
|
|
28707
|
-
if (
|
|
28708
|
-
if (this.#seen.has(
|
|
28709
|
-
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);
|
|
28710
29228
|
}
|
|
28711
|
-
const day = this.#toDay(
|
|
29229
|
+
const day = this.#toDay(record3.timestampMs);
|
|
28712
29230
|
if (day < this.#options.sinceDay || day > this.#options.untilDay) return false;
|
|
28713
|
-
const key2 = [day,
|
|
29231
|
+
const key2 = [day, record3.provider, record3.model].join(KEY_SEPARATOR);
|
|
28714
29232
|
let bucket = this.#buckets.get(key2);
|
|
28715
29233
|
if (bucket === void 0) {
|
|
28716
29234
|
bucket = {
|
|
28717
29235
|
day,
|
|
28718
|
-
provider:
|
|
28719
|
-
model:
|
|
29236
|
+
provider: record3.provider,
|
|
29237
|
+
model: record3.model,
|
|
28720
29238
|
totals: emptyUsageCostTotals(),
|
|
28721
29239
|
costUsd: 0,
|
|
28722
29240
|
cacheSavingsUsd: 0,
|
|
@@ -28729,19 +29247,19 @@ var init_aggregate = __esm({
|
|
|
28729
29247
|
}
|
|
28730
29248
|
const priced = priceUsage(
|
|
28731
29249
|
this.#options.rates,
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
29250
|
+
record3.model,
|
|
29251
|
+
record3.totals,
|
|
29252
|
+
record3.reportedCostUsd
|
|
28735
29253
|
);
|
|
28736
|
-
bucket.totals = addUsageCostTotals(bucket.totals,
|
|
29254
|
+
bucket.totals = addUsageCostTotals(bucket.totals, record3.totals);
|
|
28737
29255
|
bucket.costUsd += priced.costUsd;
|
|
28738
|
-
bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates,
|
|
29256
|
+
bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates, record3.model, record3.totals);
|
|
28739
29257
|
bucket.records += 1;
|
|
28740
29258
|
if (priced.costSource === "unpriced") bucket.unpricedRecords += 1;
|
|
28741
29259
|
if (priced.costSource === "providerReported") bucket.providerReportedRecords += 1;
|
|
28742
|
-
if (
|
|
28743
|
-
bucket.sessions.add(
|
|
28744
|
-
this.#sessions.add(
|
|
29260
|
+
if (record3.sessionId.length > 0) {
|
|
29261
|
+
bucket.sessions.add(record3.sessionId);
|
|
29262
|
+
this.#sessions.add(record3.sessionId);
|
|
28745
29263
|
}
|
|
28746
29264
|
return true;
|
|
28747
29265
|
}
|
|
@@ -28822,17 +29340,17 @@ async function readTranscriptRecords(filePath, provider) {
|
|
|
28822
29340
|
function dedupeWithinFile(records) {
|
|
28823
29341
|
const slotByKey = /* @__PURE__ */ new Map();
|
|
28824
29342
|
const kept = [];
|
|
28825
|
-
for (const
|
|
28826
|
-
if (
|
|
28827
|
-
kept.push(
|
|
29343
|
+
for (const record3 of records) {
|
|
29344
|
+
if (record3.dedupeKey === null) {
|
|
29345
|
+
kept.push(record3);
|
|
28828
29346
|
continue;
|
|
28829
29347
|
}
|
|
28830
|
-
const slot = slotByKey.get(
|
|
29348
|
+
const slot = slotByKey.get(record3.dedupeKey);
|
|
28831
29349
|
if (slot === void 0) {
|
|
28832
|
-
slotByKey.set(
|
|
29350
|
+
slotByKey.set(record3.dedupeKey, kept.push(record3) - 1);
|
|
28833
29351
|
continue;
|
|
28834
29352
|
}
|
|
28835
|
-
if (
|
|
29353
|
+
if (record3.totals.outputTokens > kept[slot].totals.outputTokens) kept[slot] = record3;
|
|
28836
29354
|
}
|
|
28837
29355
|
return kept;
|
|
28838
29356
|
}
|
|
@@ -28941,23 +29459,23 @@ async function readUsageCostSummary(input) {
|
|
|
28941
29459
|
for (const file of files) {
|
|
28942
29460
|
const records = await readFileRecords(file, provider);
|
|
28943
29461
|
scannedFiles += 1;
|
|
28944
|
-
for (const
|
|
28945
|
-
aggregator.add(
|
|
28946
|
-
if (!liveSessionIds.has(
|
|
28947
|
-
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();
|
|
28948
29466
|
byModel.set(
|
|
28949
|
-
|
|
29467
|
+
record3.model,
|
|
28950
29468
|
addUsageCostTotals(
|
|
28951
|
-
byModel.get(
|
|
28952
|
-
|
|
29469
|
+
byModel.get(record3.model) ?? emptyUsageCostTotals(),
|
|
29470
|
+
record3.totals
|
|
28953
29471
|
)
|
|
28954
29472
|
);
|
|
28955
|
-
durableTotals.set(
|
|
29473
|
+
durableTotals.set(record3.sessionId, byModel);
|
|
28956
29474
|
}
|
|
28957
29475
|
}
|
|
28958
29476
|
}
|
|
28959
29477
|
for (const runtime of runtimes2) {
|
|
28960
|
-
for (const
|
|
29478
|
+
for (const record3 of await runtime.liveUsageRecords(durableTotals)) aggregator.add(record3);
|
|
28961
29479
|
}
|
|
28962
29480
|
const retentionCutoffMs = startedAtMs - 90 * 24 * 60 * 60 * 1e3;
|
|
28963
29481
|
for (const [path, entry] of fileCache2) {
|
|
@@ -29684,8 +30202,8 @@ var init_workflows2 = __esm({
|
|
|
29684
30202
|
});
|
|
29685
30203
|
|
|
29686
30204
|
// ../../server/routes/worktrees/worktreeIo.ts
|
|
29687
|
-
import { execFile as
|
|
29688
|
-
import { promisify as
|
|
30205
|
+
import { execFile as execFile8 } from "node:child_process";
|
|
30206
|
+
import { promisify as promisify4 } from "node:util";
|
|
29689
30207
|
async function runWorktreeCommand(file, args, { cwd, timeoutMs = WORKTREE_COMMAND_TIMEOUT_MS }) {
|
|
29690
30208
|
const result = await execFileAsync(file, [...args], {
|
|
29691
30209
|
cwd,
|
|
@@ -29724,7 +30242,7 @@ var init_worktreeIo = __esm({
|
|
|
29724
30242
|
WORKTREE_COMMAND_MAX_BUFFER = 4 * 1024 * 1024;
|
|
29725
30243
|
WORKTREE_SCAN_CONCURRENCY = 4;
|
|
29726
30244
|
SESSION_HEADER_CONCURRENCY = 8;
|
|
29727
|
-
execFileAsync =
|
|
30245
|
+
execFileAsync = promisify4(execFile8);
|
|
29728
30246
|
NONINTERACTIVE_ENV = {
|
|
29729
30247
|
...process.env,
|
|
29730
30248
|
GCM_INTERACTIVE: "Never",
|
|
@@ -30312,6 +30830,7 @@ var init_api_routes = __esm({
|
|
|
30312
30830
|
init_files();
|
|
30313
30831
|
init_git_diff();
|
|
30314
30832
|
init_git_status();
|
|
30833
|
+
init_github_actions();
|
|
30315
30834
|
init_project_icon();
|
|
30316
30835
|
init_hello();
|
|
30317
30836
|
init_local_file();
|
|
@@ -30326,6 +30845,7 @@ var init_api_routes = __esm({
|
|
|
30326
30845
|
init_project_files();
|
|
30327
30846
|
init_projects2();
|
|
30328
30847
|
init_provider_updates();
|
|
30848
|
+
init_agent_executable();
|
|
30329
30849
|
init_scripts();
|
|
30330
30850
|
init_session_config();
|
|
30331
30851
|
init_session_context();
|
|
@@ -30380,6 +30900,7 @@ var init_api_routes = __esm({
|
|
|
30380
30900
|
apiRoute("project-files", registerProjectFileRoutes),
|
|
30381
30901
|
apiRoute("project-file", registerProjectFileContentRoutes),
|
|
30382
30902
|
apiRoute("git-status", registerGitStatusRoutes),
|
|
30903
|
+
apiRoute("github-actions", registerGitHubActionsRoutes),
|
|
30383
30904
|
apiRoute("project-icon", registerProjectIconRoutes),
|
|
30384
30905
|
apiRoute("git-diff", registerGitDiffRoutes),
|
|
30385
30906
|
apiRoute("mcp", registerMcpRoutes),
|
|
@@ -30393,7 +30914,8 @@ var init_api_routes = __esm({
|
|
|
30393
30914
|
apiRoute("models", registerModelRoutes),
|
|
30394
30915
|
apiRoute("codex-threads", registerCodexThreadRoutes),
|
|
30395
30916
|
apiRoute("agent-runtime", registerAgentRuntimeRoutes),
|
|
30396
|
-
apiRoute("provider-updates", registerProviderUpdateRoutes)
|
|
30917
|
+
apiRoute("provider-updates", registerProviderUpdateRoutes),
|
|
30918
|
+
apiRoute("agent-executable", registerAgentExecutableRoutes)
|
|
30397
30919
|
];
|
|
30398
30920
|
}
|
|
30399
30921
|
});
|
|
@@ -31221,8 +31743,8 @@ var init_sessionActivityMonitor = __esm({
|
|
|
31221
31743
|
});
|
|
31222
31744
|
|
|
31223
31745
|
// ../../server/lib/standalone-bootstrap.ts
|
|
31224
|
-
import { readFileSync as
|
|
31225
|
-
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")) {
|
|
31226
31748
|
const file = env.COGPIT_NETWORK_PASSWORD_FILE;
|
|
31227
31749
|
if (file && file.length > 0) {
|
|
31228
31750
|
const trimmed = readFileFn(file).replace(/\r?\n$/, "");
|
|
@@ -31491,7 +32013,7 @@ async function waitForShutdownSignal() {
|
|
|
31491
32013
|
for (const signal of signals) process.once(signal, done);
|
|
31492
32014
|
});
|
|
31493
32015
|
}
|
|
31494
|
-
var
|
|
32016
|
+
var defaultDependencies2 = {
|
|
31495
32017
|
fetch,
|
|
31496
32018
|
openUrl: openExternalUrl,
|
|
31497
32019
|
startServer: startPackagedServer,
|
|
@@ -31518,7 +32040,7 @@ async function verifyServer(server, command, deps) {
|
|
|
31518
32040
|
}
|
|
31519
32041
|
}
|
|
31520
32042
|
async function run(argv, overrides = {}) {
|
|
31521
|
-
const deps = { ...
|
|
32043
|
+
const deps = { ...defaultDependencies2, ...overrides };
|
|
31522
32044
|
let command;
|
|
31523
32045
|
try {
|
|
31524
32046
|
command = parseArgs(argv);
|