cogpit 2.2.1 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/cli.js +938 -585
  2. package/dist/web/assets/{CommandPaletteHost--_g3tlgk.js → CommandPaletteHost-D-VvT_HL.js} +1 -1
  3. package/dist/web/assets/ConfigBrowser-Cc2lrh85.js +1 -0
  4. package/dist/web/assets/{HighlightedEditor-Byq8pOUC.js → HighlightedEditor-DWNz1Jcz.js} +2 -2
  5. package/dist/web/assets/{KeyboardShortcutsDialog-CFhdeGBw.js → KeyboardShortcutsDialog-yOs1u5D6.js} +1 -1
  6. package/dist/web/assets/{MobileFileChanges-uxpxh1W6.js → MobileFileChanges-B1dtcdSZ.js} +1 -1
  7. package/dist/web/assets/PreviewPanel-BJwfunf9.js +1 -0
  8. package/dist/web/assets/{ProjectFilesPanel-ByyaiSGy.js → ProjectFilesPanel-DppuIFEt.js} +3 -3
  9. package/dist/web/assets/{ProjectSwitcherModal-BRbFj3Dd.js → ProjectSwitcherModal-DgsuH5CY.js} +1 -1
  10. package/dist/web/assets/{TerminalOutput-Aavw8QCx.js → TerminalOutput-DlGDS0Wx.js} +1 -1
  11. package/dist/web/assets/ThemeSelectorModal-oI9Vm3EH.js +1 -0
  12. package/dist/web/assets/WorkflowsPanel-SKbsv_IK.js +1 -0
  13. package/dist/web/assets/WorktreePanel-CcSLupr7.js +1 -0
  14. package/dist/web/assets/{index-C-5Kgwol.js → index-7FuVzOBC.js} +4 -4
  15. package/dist/web/assets/index-BVkjlOVU.js +1 -0
  16. package/dist/web/assets/index-Bw-DFQut.js +1 -0
  17. package/dist/web/assets/index-Du17HzQD.js +151 -0
  18. package/dist/web/assets/index-xdv0cIL2.css +1 -0
  19. package/dist/web/assets/{vendor-ui-CyII6N5s.js → vendor-ui-CdA11Wfh.js} +158 -148
  20. package/dist/web/index.html +3 -3
  21. package/package.json +1 -1
  22. package/dist/web/assets/ConfigBrowser-DrAZQBx8.js +0 -1
  23. package/dist/web/assets/PreviewPanel-DC6OTZfZ.js +0 -1
  24. package/dist/web/assets/ThemeSelectorModal-CxGMhlkF.js +0 -1
  25. package/dist/web/assets/WorkflowsPanel-Beg1AAtq.js +0 -1
  26. package/dist/web/assets/WorktreePanel-B17_SlFC.js +0 -1
  27. package/dist/web/assets/index-CJcccHRp.js +0 -1
  28. package/dist/web/assets/index-CTpAqQye.js +0 -1
  29. package/dist/web/assets/index-DB1wEO_I.js +0 -148
  30. package/dist/web/assets/index-DU9XxwBy.css +0 -1
package/dist/cli.js CHANGED
@@ -73,7 +73,7 @@ var init_compression = __esm({
73
73
  import { StringDecoder } from "node:string_decoder";
74
74
  function readJsonBody(req, options = {}) {
75
75
  const maxBytes = options.maxBytes ?? DEFAULT_MAX_REQUEST_BODY_BYTES;
76
- return new Promise((resolve21, reject) => {
76
+ return new Promise((resolve22, reject) => {
77
77
  let body = "";
78
78
  let bytesRead = 0;
79
79
  let settled = false;
@@ -97,11 +97,11 @@ function readJsonBody(req, options = {}) {
97
97
  settled = true;
98
98
  body += decoder.end();
99
99
  if (!body.trim() && options.allowEmpty) {
100
- resolve21({});
100
+ resolve22({});
101
101
  return;
102
102
  }
103
103
  try {
104
- resolve21(JSON.parse(body));
104
+ resolve22(JSON.parse(body));
105
105
  } catch {
106
106
  reject(new HttpBodyError("Invalid JSON body", 400));
107
107
  }
@@ -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 record3 = { at: Date.now(), generation: generation2 };
490
- lastAttempt.set(id, record3);
489
+ const record4 = { at: Date.now(), generation: generation2 };
490
+ lastAttempt.set(id, record4);
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
- record3.error = error;
506
+ record4.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
- record3.error = error;
514
+ record4.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
- record3.error = error;
525
+ record4.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
- record3.error = error;
539
+ record4.error = error;
540
540
  if (generationIsCurrent(id, generation2)) {
541
541
  setDeviceRuntime(id, { authState: "bad-password", lastProbe: Date.now() });
542
542
  }
@@ -1164,7 +1164,7 @@ function verifyPassword(password, stored) {
1164
1164
  async function verifyPasswordAsync(password, stored) {
1165
1165
  const scryptHash = parseScryptHash(stored);
1166
1166
  if (!scryptHash) return verifyPassword(password, stored);
1167
- const candidate = await new Promise((resolve21, reject) => {
1167
+ const candidate = await new Promise((resolve22, reject) => {
1168
1168
  scrypt(
1169
1169
  password,
1170
1170
  Buffer.from(scryptHash.salt, "hex"),
@@ -1175,7 +1175,7 @@ async function verifyPasswordAsync(password, stored) {
1175
1175
  p: SCRYPT_PARALLELISM,
1176
1176
  maxmem: SCRYPT_MAX_MEMORY
1177
1177
  },
1178
- (error, derivedKey) => error ? reject(error) : resolve21(derivedKey)
1178
+ (error, derivedKey) => error ? reject(error) : resolve22(derivedKey)
1179
1179
  );
1180
1180
  });
1181
1181
  return safeCompareBuffers(candidate, Buffer.from(scryptHash.hash, "hex"));
@@ -3999,7 +3999,7 @@ async function createShare(input) {
3999
3999
  const passwordHash = hashPassword(passphrase);
4000
4000
  const share = await commitShareMutation((draft) => {
4001
4001
  const existing = draft.get(input.sessionId);
4002
- const record3 = {
4002
+ const record4 = {
4003
4003
  sessionId: input.sessionId,
4004
4004
  dirName: input.dirName,
4005
4005
  fileName: input.fileName,
@@ -4008,8 +4008,8 @@ async function createShare(input) {
4008
4008
  // No guest has ever used this passphrase; the UI renders 0 as "never".
4009
4009
  lastAccessAt: 0
4010
4010
  };
4011
- draft.set(record3.sessionId, record3);
4012
- return { changed: true, value: toPublicShare(record3) };
4011
+ draft.set(record4.sessionId, record4);
4012
+ return { changed: true, value: toPublicShare(record4) };
4013
4013
  });
4014
4014
  return { share, passphrase };
4015
4015
  }
@@ -4860,6 +4860,7 @@ var init_policy = __esm({
4860
4860
  "project-file": admin("/api/project-file"),
4861
4861
  "git-status": admin("/api/git-status"),
4862
4862
  "github-actions": admin("/api/github-actions"),
4863
+ "vercel-deployments": admin("/api/vercel-deployments"),
4863
4864
  "project-icon": admin("/api/project-icon"),
4864
4865
  "git-diff": admin("/api/git-diff"),
4865
4866
  mcp: admin("/api/mcp-servers"),
@@ -5714,7 +5715,7 @@ var init_versions = __esm({
5714
5715
  // ../../server/lib/cliProcess.ts
5715
5716
  import { spawn } from "node:child_process";
5716
5717
  function runCli(executable, args, timeoutMs) {
5717
- return new Promise((resolve21) => {
5718
+ return new Promise((resolve22) => {
5718
5719
  const resolved = resolveAgentCommand(executable, [...args]);
5719
5720
  const child = spawn(resolved.command, resolved.args, {
5720
5721
  stdio: ["ignore", "pipe", "pipe"],
@@ -5736,11 +5737,11 @@ function runCli(executable, args, timeoutMs) {
5736
5737
  });
5737
5738
  child.on("error", () => {
5738
5739
  clearTimeout(timer);
5739
- resolve21({ code: null, stdout, stderr, timedOut });
5740
+ resolve22({ code: null, stdout, stderr, timedOut });
5740
5741
  });
5741
5742
  child.on("close", (code) => {
5742
5743
  clearTimeout(timer);
5743
- resolve21({ code, stdout, stderr, timedOut });
5744
+ resolve22({ code, stdout, stderr, timedOut });
5744
5745
  });
5745
5746
  });
5746
5747
  }
@@ -5795,7 +5796,7 @@ function findNpmClaude(options = {}) {
5795
5796
  const windows = platform2 === "win32";
5796
5797
  const path = windows ? win322 : posix2;
5797
5798
  const isFile = options.isFile ?? realIsFile;
5798
- const readFile21 = options.readFile ?? realReadFile;
5799
+ const readFile22 = options.readFile ?? realReadFile;
5799
5800
  const shim = findExecutableOnPath(BIN_NAME, { platform: platform2, env: options.env, isExecutable: isFile });
5800
5801
  if (!shim) return void 0;
5801
5802
  const shimDir = path.dirname(shim);
@@ -5804,7 +5805,7 @@ function findNpmClaude(options = {}) {
5804
5805
  path.join(shimDir, "..", "lib", "node_modules", NPM_PACKAGE)
5805
5806
  ];
5806
5807
  for (const packageDir of packageDirs) {
5807
- const manifest = readFile21(path.join(packageDir, "package.json"));
5808
+ const manifest = readFile22(path.join(packageDir, "package.json"));
5808
5809
  if (!manifest) continue;
5809
5810
  const relative11 = binField(manifest);
5810
5811
  if (!relative11) continue;
@@ -6217,16 +6218,16 @@ function makeCanUseTool(state) {
6217
6218
  return (toolName, input, options) => {
6218
6219
  if (toolName === "AskUserQuestion") {
6219
6220
  const toolUseId = options.toolUseID;
6220
- return new Promise((resolve21) => {
6221
+ return new Promise((resolve22) => {
6221
6222
  const pending = {
6222
6223
  input,
6223
6224
  askedAt: Date.now(),
6224
- resolve: resolve21
6225
+ resolve: resolve22
6225
6226
  };
6226
6227
  state.pendingUserQuestions.set(toolUseId, pending);
6227
6228
  const onAbort = () => {
6228
6229
  if (state.pendingUserQuestions.delete(toolUseId)) {
6229
- resolve21({ behavior: "deny", message: "Session aborted", interrupt: true });
6230
+ resolve22({ behavior: "deny", message: "Session aborted", interrupt: true });
6230
6231
  }
6231
6232
  };
6232
6233
  options.signal?.addEventListener("abort", onAbort, { once: true });
@@ -6239,7 +6240,7 @@ function makeCanUseTool(state) {
6239
6240
  return Promise.resolve({ behavior: "allow", updatedInput: input });
6240
6241
  }
6241
6242
  const requestId = options.toolUseID;
6242
- return new Promise((resolve21) => {
6243
+ return new Promise((resolve22) => {
6243
6244
  const pending = {
6244
6245
  requestId,
6245
6246
  toolName,
@@ -6252,12 +6253,12 @@ function makeCanUseTool(state) {
6252
6253
  blockedPath: options.blockedPath,
6253
6254
  suggestions: options.suggestions,
6254
6255
  timestamp: Date.now(),
6255
- resolve: resolve21
6256
+ resolve: resolve22
6256
6257
  };
6257
6258
  state.pendingPermissions.set(requestId, pending);
6258
6259
  const onAbort = () => {
6259
6260
  if (state.pendingPermissions.delete(requestId)) {
6260
- resolve21({ behavior: "deny", message: "Session aborted", interrupt: true });
6261
+ resolve22({ behavior: "deny", message: "Session aborted", interrupt: true });
6261
6262
  }
6262
6263
  };
6263
6264
  options.signal?.addEventListener("abort", onAbort, { once: true });
@@ -6334,16 +6335,16 @@ function makeOnElicitation(state) {
6334
6335
  );
6335
6336
  return Promise.resolve({ action: "decline" });
6336
6337
  }
6337
- return new Promise((resolve21) => {
6338
+ return new Promise((resolve22) => {
6338
6339
  const requestId = options.requestId;
6339
6340
  state.pendingElicitations.set(requestId, {
6340
6341
  request,
6341
6342
  fields: projection.fields,
6342
6343
  askedAt: Date.now(),
6343
- resolve: resolve21
6344
+ resolve: resolve22
6344
6345
  });
6345
6346
  const onAbort = () => {
6346
- if (state.pendingElicitations.delete(requestId)) resolve21({ action: "decline" });
6347
+ if (state.pendingElicitations.delete(requestId)) resolve22({ action: "decline" });
6347
6348
  };
6348
6349
  options.signal?.addEventListener("abort", onAbort, { once: true });
6349
6350
  });
@@ -6367,14 +6368,14 @@ function makeOnUserDialog(state) {
6367
6368
  if (!(request.dialogKind in DIALOG_CHOICES)) return Promise.resolve(null);
6368
6369
  const projected = projectUserDialog(request);
6369
6370
  if (!projected) return Promise.resolve({ behavior: "cancelled" });
6370
- return new Promise((resolve21) => {
6371
+ return new Promise((resolve22) => {
6371
6372
  const requestId = options.requestId;
6372
6373
  state.pendingUserDialogs.set(requestId, {
6373
6374
  dialog: { ...projected, requestId, askedAt: Date.now() },
6374
- resolve: resolve21
6375
+ resolve: resolve22
6375
6376
  });
6376
6377
  const onAbort = () => {
6377
- if (state.pendingUserDialogs.delete(requestId)) resolve21({ behavior: "cancelled" });
6378
+ if (state.pendingUserDialogs.delete(requestId)) resolve22({ behavior: "cancelled" });
6378
6379
  };
6379
6380
  options.signal?.addEventListener("abort", onAbort, { once: true });
6380
6381
  });
@@ -7103,8 +7104,8 @@ var init_sdk_session = __esm({
7103
7104
  closed = false;
7104
7105
  enqueue(message) {
7105
7106
  if (this.closed) return false;
7106
- const resolve21 = this.waiting.shift();
7107
- if (resolve21) resolve21({ value: message, done: false });
7107
+ const resolve22 = this.waiting.shift();
7108
+ if (resolve22) resolve22({ value: message, done: false });
7108
7109
  else this.queued.push(message);
7109
7110
  return true;
7110
7111
  }
@@ -7112,15 +7113,15 @@ var init_sdk_session = __esm({
7112
7113
  if (this.closed) return;
7113
7114
  this.closed = true;
7114
7115
  this.queued.length = 0;
7115
- for (const resolve21 of this.waiting.splice(0)) {
7116
- resolve21({ value: void 0, done: true });
7116
+ for (const resolve22 of this.waiting.splice(0)) {
7117
+ resolve22({ value: void 0, done: true });
7117
7118
  }
7118
7119
  }
7119
7120
  next() {
7120
7121
  const message = this.queued.shift();
7121
7122
  if (message) return Promise.resolve({ value: message, done: false });
7122
7123
  if (this.closed) return Promise.resolve({ value: void 0, done: true });
7123
- return new Promise((resolve21) => this.waiting.push(resolve21));
7124
+ return new Promise((resolve22) => this.waiting.push(resolve22));
7124
7125
  }
7125
7126
  return() {
7126
7127
  this.close();
@@ -7256,8 +7257,8 @@ var init_agent_prompts = __esm({
7256
7257
  function observeExit(proc) {
7257
7258
  let didExit = proc.exitCode !== null && proc.exitCode !== void 0 || proc.signalCode !== null && proc.signalCode !== void 0;
7258
7259
  let resolveExit = () => void 0;
7259
- const exited = new Promise((resolve21) => {
7260
- resolveExit = resolve21;
7260
+ const exited = new Promise((resolve22) => {
7261
+ resolveExit = resolve22;
7261
7262
  });
7262
7263
  if (didExit) resolveExit();
7263
7264
  const markExited = () => {
@@ -7283,14 +7284,14 @@ function observeExit(proc) {
7283
7284
  async function waitForExit(observers, timeoutMs, onTimeout = () => void 0) {
7284
7285
  const pending = observers.filter((observer) => !observer.hasExited());
7285
7286
  if (pending.length === 0) return;
7286
- await new Promise((resolve21) => {
7287
+ await new Promise((resolve22) => {
7287
7288
  const timer = setTimeout(() => {
7288
7289
  onTimeout();
7289
- resolve21();
7290
+ resolve22();
7290
7291
  }, timeoutMs);
7291
7292
  void Promise.all(pending.map((observer) => observer.exited)).then(() => {
7292
7293
  clearTimeout(timer);
7293
- resolve21();
7294
+ resolve22();
7294
7295
  });
7295
7296
  });
7296
7297
  }
@@ -7573,7 +7574,7 @@ async function readClaudeSessionMeta(filePath, head) {
7573
7574
  let cwd = "";
7574
7575
  let firstUserMessage = "";
7575
7576
  let lastUserMessage = "";
7576
- let timestamp = "";
7577
+ let timestamp2 = "";
7577
7578
  let lastTimestamp = "";
7578
7579
  let turnCount = 0;
7579
7580
  let aiTitle = "";
@@ -7612,8 +7613,8 @@ async function readClaudeSessionMeta(filePath, head) {
7612
7613
  if (obj.type === "assistant" && obj.message?.model && !model) {
7613
7614
  model = obj.message.model;
7614
7615
  }
7615
- if (obj.type === "user" && !obj.isMeta && !timestamp) {
7616
- timestamp = obj.timestamp || "";
7616
+ if (obj.type === "user" && !obj.isMeta && !timestamp2) {
7617
+ timestamp2 = obj.timestamp || "";
7617
7618
  }
7618
7619
  if (obj.type === "user" && !obj.isMeta) {
7619
7620
  if (obj.timestamp) lastTimestamp = obj.timestamp;
@@ -7708,8 +7709,8 @@ async function readClaudeSessionMeta(filePath, head) {
7708
7709
  cwd,
7709
7710
  firstUserMessage,
7710
7711
  lastUserMessage,
7711
- timestamp,
7712
- lastTimestamp: lastTimestamp || timestamp,
7712
+ timestamp: timestamp2,
7713
+ lastTimestamp: lastTimestamp || timestamp2,
7713
7714
  turnCount,
7714
7715
  lineCount: isPartialRead ? Math.round(head.size / (HEAD_BYTES / lines.length)) : lines.length,
7715
7716
  branchedFrom,
@@ -7998,7 +7999,7 @@ var init_sessionStats = __esm({
7998
7999
  });
7999
8000
 
8000
8001
  // ../../shared/session/turnContent.ts
8001
- function appendAssistantText(turn, text, timestamp) {
8002
+ function appendAssistantText(turn, text, timestamp2) {
8002
8003
  if (!text) return;
8003
8004
  turn.assistantText.push(text);
8004
8005
  const last = turn.contentBlocks[turn.contentBlocks.length - 1];
@@ -8006,7 +8007,7 @@ function appendAssistantText(turn, text, timestamp) {
8006
8007
  last.text.push(text);
8007
8008
  return;
8008
8009
  }
8009
- turn.contentBlocks.push({ kind: "text", text: [text], timestamp });
8010
+ turn.contentBlocks.push({ kind: "text", text: [text], timestamp: timestamp2 });
8010
8011
  }
8011
8012
  var init_turnContent = __esm({
8012
8013
  "../../shared/session/turnContent.ts"() {
@@ -8376,7 +8377,7 @@ function resolveCodexPatchPath(filePath, cwd) {
8376
8377
  const relative11 = filePath.replace(/^\.[\\/]/, "");
8377
8378
  return /^[A-Za-z]:[\\/]/.test(cwd) ? `${base}\\${relative11.replace(/\//g, "\\")}` : `${base}/${relative11}`;
8378
8379
  }
8379
- function parseApplyPatch(patchText, callId, timestamp, cwd = "") {
8380
+ function parseApplyPatch(patchText, callId, timestamp2, cwd = "") {
8380
8381
  const toolCalls = [];
8381
8382
  const filePattern = /^\*\*\*\s+(Update File|Add File|Delete File):\s*(.+)$/gm;
8382
8383
  const sections = [];
@@ -8419,7 +8420,7 @@ function parseApplyPatch(patchText, callId, timestamp, cwd = "") {
8419
8420
  input: { file_path: filePath, content: newLines.join("\n") },
8420
8421
  result: null,
8421
8422
  isError: false,
8422
- timestamp
8423
+ timestamp: timestamp2
8423
8424
  });
8424
8425
  } else if (section.action === "Delete File") {
8425
8426
  toolCalls.push({
@@ -8428,7 +8429,7 @@ function parseApplyPatch(patchText, callId, timestamp, cwd = "") {
8428
8429
  input: { file_path: filePath, old_string: oldLines.join("\n"), new_string: "" },
8429
8430
  result: null,
8430
8431
  isError: false,
8431
- timestamp
8432
+ timestamp: timestamp2
8432
8433
  });
8433
8434
  } else {
8434
8435
  toolCalls.push({
@@ -8442,18 +8443,18 @@ function parseApplyPatch(patchText, callId, timestamp, cwd = "") {
8442
8443
  },
8443
8444
  result: null,
8444
8445
  isError: false,
8445
- timestamp
8446
+ timestamp: timestamp2
8446
8447
  });
8447
8448
  }
8448
8449
  }
8449
8450
  return toolCalls;
8450
8451
  }
8451
- function parseCodexToolPatches(toolName, rawInput, callId, timestamp, cwd = "") {
8452
+ function parseCodexToolPatches(toolName, rawInput, callId, timestamp2, cwd = "") {
8452
8453
  if (toolName === "apply_patch") {
8453
- return parseApplyPatch(rawInput, callId, timestamp, cwd);
8454
+ return parseApplyPatch(rawInput, callId, timestamp2, cwd);
8454
8455
  }
8455
8456
  return extractApplyPatchInputs(rawInput).flatMap(
8456
- (patch, patchIndex) => parseApplyPatch(patch, `${callId}:patch-${patchIndex}`, timestamp, cwd)
8457
+ (patch, patchIndex) => parseApplyPatch(patch, `${callId}:patch-${patchIndex}`, timestamp2, cwd)
8457
8458
  );
8458
8459
  }
8459
8460
  function findFailedNestedPatchCallIds(output, wrapperIsError, calls) {
@@ -8578,9 +8579,9 @@ function safeParseLine(line) {
8578
8579
  function isObject2(value) {
8579
8580
  return typeof value === "object" && value !== null;
8580
8581
  }
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";
8582
+ function isCodexRecord(record4) {
8583
+ if (!record4 || typeof record4.type !== "string") return false;
8584
+ return record4.type === "session_meta" || record4.type === "turn_context" || record4.type === "event_msg" || record4.type === "response_item" || record4.type === "inter_agent_communication_metadata" || record4.type === "compacted" || record4.type === "world_state";
8584
8585
  }
8585
8586
  function extractMessageText(payload, blockType) {
8586
8587
  const content = payload?.content;
@@ -8697,7 +8698,7 @@ function parseTokenUsage(value) {
8697
8698
  cache_read_input_tokens: cacheRead
8698
8699
  };
8699
8700
  }
8700
- function appendThinking(turn, text, timestamp) {
8701
+ function appendThinking(turn, text, timestamp2) {
8701
8702
  if (!text) return;
8702
8703
  const block = { type: "thinking", thinking: text, signature: "" };
8703
8704
  turn.thinking.push(block);
@@ -8706,16 +8707,16 @@ function appendThinking(turn, text, timestamp) {
8706
8707
  last.blocks.push(block);
8707
8708
  return;
8708
8709
  }
8709
- turn.contentBlocks.push({ kind: "thinking", blocks: [block], timestamp });
8710
+ turn.contentBlocks.push({ kind: "thinking", blocks: [block], timestamp: timestamp2 });
8710
8711
  }
8711
- function appendToolCall(turn, toolCall, timestamp) {
8712
+ function appendToolCall(turn, toolCall, timestamp2) {
8712
8713
  turn.toolCalls.push(toolCall);
8713
8714
  const last = turn.contentBlocks[turn.contentBlocks.length - 1];
8714
- if (last && last.kind === "tool_calls" && last.timestamp === timestamp) {
8715
+ if (last && last.kind === "tool_calls" && last.timestamp === timestamp2) {
8715
8716
  last.toolCalls.push(toolCall);
8716
8717
  return;
8717
8718
  }
8718
- turn.contentBlocks.push({ kind: "tool_calls", toolCalls: [toolCall], timestamp });
8719
+ turn.contentBlocks.push({ kind: "tool_calls", toolCalls: [toolCall], timestamp: timestamp2 });
8719
8720
  }
8720
8721
  function finalizeTurn(turns, current, lastTimestamp) {
8721
8722
  if (!current) return null;
@@ -8766,37 +8767,37 @@ function parseMcpEventResult(value) {
8766
8767
  isError: ok.isError === true || parsedContent.isError
8767
8768
  };
8768
8769
  }
8769
- function createTurn(turnId, timestamp, model) {
8770
+ function createTurn(turnId, timestamp2, model) {
8770
8771
  return {
8771
- id: turnId ? `${turnId}@${timestamp}` : randomTurnId("codex-turn"),
8772
+ id: turnId ? `${turnId}@${timestamp2}` : randomTurnId("codex-turn"),
8772
8773
  userMessage: null,
8773
8774
  contentBlocks: [],
8774
8775
  thinking: [],
8775
8776
  assistantText: [],
8776
8777
  toolCalls: [],
8777
8778
  subAgentActivity: [],
8778
- timestamp,
8779
+ timestamp: timestamp2,
8779
8780
  durationMs: null,
8780
8781
  tokenUsage: null,
8781
8782
  model
8782
8783
  };
8783
8784
  }
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);
8785
+ function extractPromptFromRecord(record4) {
8786
+ if (record4.type === "event_msg" && isObject2(record4.payload) && record4.payload.type === "user_message" && typeof record4.payload.message === "string") {
8787
+ return normalizePromptText(record4.payload.message);
8787
8788
  }
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"));
8789
+ if (record4.type === "response_item" && isObject2(record4.payload) && record4.payload.type === "message" && record4.payload.role === "user") {
8790
+ return normalizePromptText(extractMessageText(record4.payload, "input_text"));
8790
8791
  }
8791
8792
  return "";
8792
8793
  }
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") {
8794
+ function recordOpensTurn(record4, payload) {
8795
+ if (record4.type === "session_meta") return false;
8796
+ if (record4.type === "event_msg" && payload?.type === "task_started") return false;
8797
+ if (record4.type === "response_item" && payload?.type === "message") {
8797
8798
  if (payload.role === "developer" || payload.role === "system") return false;
8798
8799
  if (payload.role === "user") {
8799
- return extractPromptFromRecord(record3) !== "" || extractResponseMessageImages(payload).length > 0 || extractResponseMessageAudio(payload).length > 0;
8800
+ return extractPromptFromRecord(record4) !== "" || extractResponseMessageImages(payload).length > 0 || extractResponseMessageAudio(payload).length > 0;
8800
8801
  }
8801
8802
  }
8802
8803
  return true;
@@ -8810,29 +8811,29 @@ function extractMetadataFromRecords(records) {
8810
8811
  let branchedFrom;
8811
8812
  let firstUserMessage = "";
8812
8813
  let lastUserMessage = "";
8813
- let timestamp = "";
8814
+ let timestamp2 = "";
8814
8815
  let lastTimestamp = "";
8815
8816
  let turnCount = 0;
8816
8817
  let isSubagent = false;
8817
8818
  let parentSessionId = null;
8818
8819
  let agentPath = "/root";
8819
8820
  let previousPrompt = "";
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 : "";
8821
+ for (const record4 of records) {
8822
+ if (!isObject2(record4.payload)) continue;
8823
+ if (record4.type === "session_meta") {
8824
+ sessionId ||= typeof record4.payload.id === "string" ? record4.payload.id : "";
8825
+ version ||= typeof record4.payload.cli_version === "string" ? record4.payload.cli_version : "";
8826
+ cwd ||= typeof record4.payload.cwd === "string" ? record4.payload.cwd : "";
8827
+ if (!branchedFrom && isObject2(record4.payload.branchedFrom)) {
8828
+ const sourceId = typeof record4.payload.branchedFrom.sessionId === "string" ? record4.payload.branchedFrom.sessionId : "";
8828
8829
  if (sourceId) {
8829
8830
  branchedFrom = {
8830
8831
  sessionId: sourceId,
8831
- turnIndex: typeof record3.payload.branchedFrom.turnIndex === "number" ? record3.payload.branchedFrom.turnIndex : null
8832
+ turnIndex: typeof record4.payload.branchedFrom.turnIndex === "number" ? record4.payload.branchedFrom.turnIndex : null
8832
8833
  };
8833
8834
  }
8834
8835
  }
8835
- const source = isObject2(record3.payload.source) ? record3.payload.source : null;
8836
+ const source = isObject2(record4.payload.source) ? record4.payload.source : null;
8836
8837
  if (source && isObject2(source.subagent)) {
8837
8838
  isSubagent = true;
8838
8839
  const threadSpawn = isObject2(source.subagent.thread_spawn) ? source.subagent.thread_spawn : null;
@@ -8840,27 +8841,27 @@ function extractMetadataFromRecords(records) {
8840
8841
  agentPath = threadSpawn.agent_path;
8841
8842
  }
8842
8843
  }
8843
- if (typeof record3.payload.forked_from_id === "string" && record3.payload.forked_from_id) {
8844
- parentSessionId = record3.payload.forked_from_id;
8844
+ if (typeof record4.payload.forked_from_id === "string" && record4.payload.forked_from_id) {
8845
+ parentSessionId = record4.payload.forked_from_id;
8845
8846
  }
8846
- const git = isObject2(record3.payload.git) ? record3.payload.git : null;
8847
+ const git = isObject2(record4.payload.git) ? record4.payload.git : null;
8847
8848
  gitBranch ||= git && typeof git.branch === "string" ? git.branch : "";
8848
8849
  }
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 : "";
8850
+ if (record4.type === "turn_context") {
8851
+ model ||= typeof record4.payload.model === "string" ? record4.payload.model : "";
8852
+ cwd ||= typeof record4.payload.cwd === "string" ? record4.payload.cwd : "";
8852
8853
  }
8853
- const prompt = extractPromptFromRecord(record3);
8854
+ const prompt = extractPromptFromRecord(record4);
8854
8855
  if (!prompt) continue;
8855
8856
  if (prompt === previousPrompt) continue;
8856
8857
  if (!firstUserMessage) firstUserMessage = prompt;
8857
8858
  lastUserMessage = prompt;
8858
8859
  previousPrompt = prompt;
8859
8860
  turnCount++;
8860
- if (!timestamp) timestamp = record3.timestamp ?? "";
8861
- lastTimestamp = record3.timestamp ?? lastTimestamp;
8861
+ if (!timestamp2) timestamp2 = record4.timestamp ?? "";
8862
+ lastTimestamp = record4.timestamp ?? lastTimestamp;
8862
8863
  }
8863
- if (lastTimestamp === "") lastTimestamp = timestamp;
8864
+ if (lastTimestamp === "") lastTimestamp = timestamp2;
8864
8865
  return {
8865
8866
  sessionId,
8866
8867
  version,
@@ -8872,7 +8873,7 @@ function extractMetadataFromRecords(records) {
8872
8873
  branchedFrom,
8873
8874
  firstUserMessage,
8874
8875
  lastUserMessage,
8875
- timestamp,
8876
+ timestamp: timestamp2,
8876
8877
  lastTimestamp,
8877
8878
  turnCount,
8878
8879
  isSubagent,
@@ -8985,8 +8986,8 @@ function walkCodexRecords(records, options) {
8985
8986
  pendingTurnStart = null;
8986
8987
  return result;
8987
8988
  }
8988
- function createActiveTurn(turnId, timestamp, model) {
8989
- const turn = createTurn(turnId, timestamp, model);
8989
+ function createActiveTurn(turnId, timestamp2, model) {
8990
+ const turn = createTurn(turnId, timestamp2, model);
8990
8991
  pendingTurnStart = pendingContextIndex ?? recordIndex;
8991
8992
  pendingContextIndex = null;
8992
8993
  if (!sawTurnStart) turn.isFragment = true;
@@ -8996,7 +8997,7 @@ function walkCodexRecords(records, options) {
8996
8997
  }
8997
8998
  return turn;
8998
8999
  }
8999
- function upsertWebSearchCall(targetTurn, id, input, status, timestamp) {
9000
+ function upsertWebSearchCall(targetTurn, id, input, status, timestamp2) {
9000
9001
  const existing = webSearchCalls.get(id);
9001
9002
  if (existing) {
9002
9003
  existing.input = { ...existing.input, ...input };
@@ -9010,39 +9011,39 @@ function walkCodexRecords(records, options) {
9010
9011
  input,
9011
9012
  result: status,
9012
9013
  isError: status === "failed",
9013
- timestamp
9014
+ timestamp: timestamp2
9014
9015
  };
9015
9016
  webSearchCalls.set(id, toolCall);
9016
- appendToolCall(targetTurn, toolCall, timestamp);
9017
+ appendToolCall(targetTurn, toolCall, timestamp2);
9017
9018
  }
9018
9019
  for (let index = 0; index < records.length; index++) {
9019
- const record3 = records[index];
9020
- if (!isCodexRecord(record3)) continue;
9020
+ const record4 = records[index];
9021
+ if (!isCodexRecord(record4)) continue;
9021
9022
  recordIndex = index;
9022
- const payload = isObject2(record3.payload) ? record3.payload : void 0;
9023
- const timestamp = record3.timestamp ?? "";
9024
- if (record3.type === "compacted") {
9023
+ const payload = isObject2(record4.payload) ? record4.payload : void 0;
9024
+ const timestamp2 = record4.timestamp ?? "";
9025
+ if (record4.type === "compacted") {
9025
9026
  current = commitTurn(current);
9026
9027
  pendingCompaction = "Conversation compacted";
9027
- lastTurnTimestamp = timestamp;
9028
+ lastTurnTimestamp = timestamp2;
9028
9029
  continue;
9029
9030
  }
9030
- if (record3.type === "world_state") continue;
9031
- if (record3.type === "turn_context") {
9031
+ if (record4.type === "world_state") continue;
9032
+ if (record4.type === "turn_context") {
9032
9033
  current = commitTurn(current);
9033
9034
  pendingContextIndex = index;
9034
9035
  currentTurnId = typeof payload?.turn_id === "string" ? payload.turn_id : null;
9035
9036
  currentModel = typeof payload?.model === "string" ? payload.model : currentModel;
9036
- lastTurnTimestamp = timestamp;
9037
+ lastTurnTimestamp = timestamp2;
9037
9038
  sawTurnStart = true;
9038
9039
  continue;
9039
9040
  }
9040
- if (record3.type === "event_msg" && payload?.type === "user_message" && typeof payload.message === "string") {
9041
+ if (record4.type === "event_msg" && payload?.type === "user_message" && typeof payload.message === "string") {
9041
9042
  if (current && (current.assistantText.length > 0 || current.toolCalls.length > 0 || current.thinking.length > 0)) {
9042
9043
  current = commitTurn(current);
9043
9044
  }
9044
9045
  sawTurnStart = true;
9045
- current ??= createActiveTurn(currentTurnId, timestamp, currentModel);
9046
+ current ??= createActiveTurn(currentTurnId, timestamp2, currentModel);
9046
9047
  const localImages = (Array.isArray(payload.local_images) ? payload.local_images : []).filter(
9047
9048
  (p) => typeof p === "string" && p.length > 0
9048
9049
  );
@@ -9057,16 +9058,16 @@ function walkCodexRecords(records, options) {
9057
9058
  localAudio
9058
9059
  );
9059
9060
  current.isFragment = false;
9060
- current.timestamp = current.timestamp || timestamp;
9061
- lastTurnTimestamp = timestamp;
9061
+ current.timestamp = current.timestamp || timestamp2;
9062
+ lastTurnTimestamp = timestamp2;
9062
9063
  continue;
9063
9064
  }
9064
- if (!current && !recordOpensTurn(record3, payload)) continue;
9065
- current ??= createActiveTurn(currentTurnId, timestamp, currentModel);
9065
+ if (!current && !recordOpensTurn(record4, payload)) continue;
9066
+ current ??= createActiveTurn(currentTurnId, timestamp2, currentModel);
9066
9067
  if (!current.model && currentModel) current.model = currentModel;
9067
- if (!current.timestamp) current.timestamp = timestamp;
9068
- if (timestamp) lastTurnTimestamp = timestamp;
9069
- if (record3.type === "event_msg" && payload?.type === "token_count") {
9068
+ if (!current.timestamp) current.timestamp = timestamp2;
9069
+ if (timestamp2) lastTurnTimestamp = timestamp2;
9070
+ if (record4.type === "event_msg" && payload?.type === "token_count") {
9070
9071
  const info = isObject2(payload.info) ? payload.info : null;
9071
9072
  const lastUsage = info ? parseTokenUsage(info.last_token_usage) : null;
9072
9073
  if (lastUsage) {
@@ -9074,14 +9075,14 @@ function walkCodexRecords(records, options) {
9074
9075
  }
9075
9076
  continue;
9076
9077
  }
9077
- if (record3.type === "event_msg" && payload?.type === "web_search_end" && typeof payload.call_id === "string") {
9078
+ if (record4.type === "event_msg" && payload?.type === "web_search_end" && typeof payload.call_id === "string") {
9078
9079
  const input = {};
9079
9080
  if (typeof payload.query === "string" && payload.query) input.query = payload.query;
9080
9081
  if (isObject2(payload.action)) input.action = payload.action;
9081
- upsertWebSearchCall(current, payload.call_id, input, "completed", timestamp);
9082
+ upsertWebSearchCall(current, payload.call_id, input, "completed", timestamp2);
9082
9083
  continue;
9083
9084
  }
9084
- if (record3.type === "event_msg" && payload?.type === "mcp_tool_call_end" && typeof payload.call_id === "string" && isObject2(payload.invocation)) {
9085
+ if (record4.type === "event_msg" && payload?.type === "mcp_tool_call_end" && typeof payload.call_id === "string" && isObject2(payload.invocation)) {
9085
9086
  const invocation = payload.invocation;
9086
9087
  const server = typeof invocation.server === "string" ? invocation.server : "mcp";
9087
9088
  const tool = typeof invocation.tool === "string" ? invocation.tool : "tool";
@@ -9099,12 +9100,12 @@ function walkCodexRecords(records, options) {
9099
9100
  input,
9100
9101
  result: result.text,
9101
9102
  isError: result.isError,
9102
- timestamp
9103
- }, timestamp);
9103
+ timestamp: timestamp2
9104
+ }, timestamp2);
9104
9105
  }
9105
9106
  continue;
9106
9107
  }
9107
- if (record3.type === "event_msg" && payload?.type === "sub_agent_activity" && typeof payload.agent_thread_id === "string" && typeof payload.agent_path === "string") {
9108
+ if (record4.type === "event_msg" && payload?.type === "sub_agent_activity" && typeof payload.agent_thread_id === "string" && typeof payload.agent_path === "string") {
9108
9109
  const agentId = payload.agent_thread_id;
9109
9110
  const eventId2 = typeof payload.event_id === "string" ? payload.event_id : "";
9110
9111
  const kind = typeof payload.kind === "string" ? payload.kind : "started";
@@ -9128,24 +9129,24 @@ function walkCodexRecords(records, options) {
9128
9129
  message: existing?.message ?? spawnInfo?.message ?? "",
9129
9130
  model: existing?.model ?? spawnInfo?.model ?? null,
9130
9131
  agentType: existing?.agentType ?? spawnInfo?.agentType ?? null,
9131
- timestamp: existing?.timestamp ?? (timestamp || spawnInfo?.timestamp || ""),
9132
+ timestamp: existing?.timestamp ?? (timestamp2 || spawnInfo?.timestamp || ""),
9132
9133
  parentToolCallId: existing?.parentToolCallId ?? eventId2
9133
9134
  };
9134
9135
  agentRegistry.set(agentId, info);
9135
9136
  agentIdByPath.set(payload.agent_path, agentId);
9136
9137
  if (eventId2 && (kind === "started" || spawnInfo)) agentIdBySpawnCall.set(eventId2, agentId);
9137
9138
  const status = kind === "interrupted" ? "interrupted" : "running";
9138
- upsertAgentMessage(agentId, current, timestamp, { status });
9139
+ upsertAgentMessage(agentId, current, timestamp2, { status });
9139
9140
  continue;
9140
9141
  }
9141
- if (record3.type !== "response_item" || !payload) continue;
9142
+ if (record4.type !== "response_item" || !payload) continue;
9142
9143
  if (payload.type === "reasoning") {
9143
9144
  const summary = Array.isArray(payload.summary) ? payload.summary.filter((item) => typeof item === "string").join("\n") : "";
9144
- appendThinking(current, summary.trim(), timestamp);
9145
+ appendThinking(current, summary.trim(), timestamp2);
9145
9146
  continue;
9146
9147
  }
9147
9148
  if (payload.type === "message" && payload.role === "assistant") {
9148
- appendAssistantText(current, extractMessageText(payload, "output_text"), timestamp);
9149
+ appendAssistantText(current, extractMessageText(payload, "output_text"), timestamp2);
9149
9150
  continue;
9150
9151
  }
9151
9152
  if (payload.type === "message" && payload.role === "user" && current.userMessage === null) {
@@ -9163,7 +9164,7 @@ function walkCodexRecords(records, options) {
9163
9164
  const input = {};
9164
9165
  if (isObject2(payload.action)) input.action = payload.action;
9165
9166
  const status = typeof payload.status === "string" ? payload.status : "completed";
9166
- upsertWebSearchCall(current, payload.id, input, status, timestamp);
9167
+ upsertWebSearchCall(current, payload.id, input, status, timestamp2);
9167
9168
  continue;
9168
9169
  }
9169
9170
  if (payload.type === "tool_search_call") {
@@ -9175,10 +9176,10 @@ function walkCodexRecords(records, options) {
9175
9176
  input: isObject2(payload.arguments) ? payload.arguments : {},
9176
9177
  result: null,
9177
9178
  isError: false,
9178
- timestamp
9179
+ timestamp: timestamp2
9179
9180
  };
9180
9181
  pendingToolCalls.set(callId, toolCall);
9181
- appendToolCall(current, toolCall, timestamp);
9182
+ appendToolCall(current, toolCall, timestamp2);
9182
9183
  }
9183
9184
  continue;
9184
9185
  }
@@ -9212,7 +9213,7 @@ function walkCodexRecords(records, options) {
9212
9213
  message: "",
9213
9214
  model: null,
9214
9215
  agentType: null,
9215
- timestamp,
9216
+ timestamp: timestamp2,
9216
9217
  parentToolCallId: ""
9217
9218
  });
9218
9219
  agentIdByPath.set(author, agentId);
@@ -9222,7 +9223,7 @@ function walkCodexRecords(records, options) {
9222
9223
  else if (interAgentMessage.messageType === "ERROR" || interAgentMessage.messageType === "FAILED") status = "failed";
9223
9224
  else if (interAgentMessage.messageType === "INTERRUPTED") status = "interrupted";
9224
9225
  else if (interAgentMessage.messageType === "MESSAGE") status = "running";
9225
- upsertAgentMessage(agentId, current, timestamp, {
9226
+ upsertAgentMessage(agentId, current, timestamp2, {
9226
9227
  status,
9227
9228
  text: interAgentMessage.text || void 0
9228
9229
  });
@@ -9247,7 +9248,7 @@ function walkCodexRecords(records, options) {
9247
9248
  taskName: typeof parsedInput.task_name === "string" ? parsedInput.task_name : null,
9248
9249
  model: typeof parsedInput.model === "string" ? parsedInput.model : null,
9249
9250
  agentType: typeof parsedInput.agent_type === "string" ? parsedInput.agent_type : null,
9250
- timestamp
9251
+ timestamp: timestamp2
9251
9252
  });
9252
9253
  }
9253
9254
  const toolCall = {
@@ -9256,10 +9257,10 @@ function walkCodexRecords(records, options) {
9256
9257
  input,
9257
9258
  result: null,
9258
9259
  isError: false,
9259
- timestamp
9260
+ timestamp: timestamp2
9260
9261
  };
9261
9262
  pendingToolCalls.set(toolCall.id, toolCall);
9262
- appendToolCall(current, toolCall, timestamp);
9263
+ appendToolCall(current, toolCall, timestamp2);
9263
9264
  continue;
9264
9265
  }
9265
9266
  if (payload.type === "function_call_output" && typeof payload.call_id === "string") {
@@ -9285,13 +9286,13 @@ function walkCodexRecords(records, options) {
9285
9286
  message: existing?.message ?? spawnInfo?.message ?? "",
9286
9287
  model: existing?.model ?? spawnInfo?.model ?? null,
9287
9288
  agentType: existing?.agentType ?? spawnInfo?.agentType ?? null,
9288
- timestamp: existing?.timestamp ?? spawnInfo?.timestamp ?? timestamp,
9289
+ timestamp: existing?.timestamp ?? spawnInfo?.timestamp ?? timestamp2,
9289
9290
  parentToolCallId: existing?.parentToolCallId ?? toolCall.id
9290
9291
  };
9291
9292
  agentRegistry.set(agentId, info);
9292
9293
  agentIdBySpawnCall.set(toolCall.id, agentId);
9293
9294
  if (info.agentPath) agentIdByPath.set(info.agentPath, agentId);
9294
- upsertAgentMessage(agentId, current, timestamp, { status: "running" });
9295
+ upsertAgentMessage(agentId, current, timestamp2, { status: "running" });
9295
9296
  }
9296
9297
  } catch {
9297
9298
  }
@@ -9314,11 +9315,11 @@ function walkCodexRecords(records, options) {
9314
9315
  message: "",
9315
9316
  model: null,
9316
9317
  agentType: null,
9317
- timestamp,
9318
+ timestamp: timestamp2,
9318
9319
  parentToolCallId: ""
9319
9320
  });
9320
9321
  }
9321
- upsertAgentMessage(agentId, current, timestamp, {
9322
+ upsertAgentMessage(agentId, current, timestamp2, {
9322
9323
  status: lifecycle,
9323
9324
  text: completedText || failedText || interruptedText || void 0
9324
9325
  });
@@ -9332,7 +9333,7 @@ function walkCodexRecords(records, options) {
9332
9333
  const name = typeof payload.name === "string" ? payload.name : "tool";
9333
9334
  const rawInput = typeof payload.input === "string" ? payload.input : "";
9334
9335
  const callId = payload.call_id;
9335
- const perFileCalls = rawInput ? parseCodexToolPatches(name, rawInput, callId, timestamp, metadata.cwd) : [];
9336
+ const perFileCalls = rawInput ? parseCodexToolPatches(name, rawInput, callId, timestamp2, metadata.cwd) : [];
9336
9337
  if (name !== "apply_patch") {
9337
9338
  const toolCall = {
9338
9339
  id: callId,
@@ -9340,14 +9341,14 @@ function walkCodexRecords(records, options) {
9340
9341
  input: parseToolInput(rawInput),
9341
9342
  result: null,
9342
9343
  isError: false,
9343
- timestamp
9344
+ timestamp: timestamp2
9344
9345
  };
9345
9346
  pendingToolCalls.set(toolCall.id, toolCall);
9346
- appendToolCall(current, toolCall, timestamp);
9347
+ appendToolCall(current, toolCall, timestamp2);
9347
9348
  }
9348
9349
  for (const tc of perFileCalls) {
9349
9350
  pendingToolCalls.set(tc.id, tc);
9350
- appendToolCall(current, tc, timestamp);
9351
+ appendToolCall(current, tc, timestamp2);
9351
9352
  }
9352
9353
  if (perFileCalls.length > 0) {
9353
9354
  patchCallIds.set(callId, {
@@ -9408,7 +9409,7 @@ function parseCodexSession(jsonlText, options) {
9408
9409
  return session;
9409
9410
  }
9410
9411
  function appendCodexSession(existing, newJsonlText) {
9411
- const prefix = existing.rawMessages.map((record3) => JSON.stringify(record3)).join("\n");
9412
+ const prefix = existing.rawMessages.map((record4) => JSON.stringify(record4)).join("\n");
9412
9413
  return parseCodexSession(prefix ? `${prefix}
9413
9414
  ${newJsonlText}` : newJsonlText);
9414
9415
  }
@@ -9603,16 +9604,16 @@ async function readCodexSessionIdentity(filePath) {
9603
9604
  let parentSessionId = null;
9604
9605
  let sawSessionMeta = false;
9605
9606
  for (const line of await readHeadLines(filePath, HEAD_BYTES)) {
9606
- let record3;
9607
+ let record4;
9607
9608
  try {
9608
- record3 = JSON.parse(line);
9609
+ record4 = JSON.parse(line);
9609
9610
  } catch {
9610
9611
  continue;
9611
9612
  }
9612
- if (!isRecord2(record3) || !isRecord2(record3.payload)) continue;
9613
- if (record3.type === "session_meta") {
9613
+ if (!isRecord2(record4) || !isRecord2(record4.payload)) continue;
9614
+ if (record4.type === "session_meta") {
9614
9615
  sawSessionMeta = true;
9615
- const payload = record3.payload;
9616
+ const payload = record4.payload;
9616
9617
  if (!sessionId && typeof payload.id === "string") sessionId = payload.id;
9617
9618
  if (!cwd && typeof payload.cwd === "string") cwd = payload.cwd;
9618
9619
  if (!parentSessionId && typeof payload.forked_from_id === "string") {
@@ -9622,8 +9623,8 @@ async function readCodexSessionIdentity(filePath) {
9622
9623
  if (source && isRecord2(source.subagent)) isSubagent = true;
9623
9624
  const git = isRecord2(payload.git) ? payload.git : null;
9624
9625
  if (!gitBranch && git && typeof git.branch === "string") gitBranch = git.branch;
9625
- } else if (record3.type === "turn_context") {
9626
- if (!cwd && typeof record3.payload.cwd === "string") cwd = record3.payload.cwd;
9626
+ } else if (record4.type === "turn_context") {
9627
+ if (!cwd && typeof record4.payload.cwd === "string") cwd = record4.payload.cwd;
9627
9628
  }
9628
9629
  }
9629
9630
  if (!sawSessionMeta || !cwd) return null;
@@ -9946,8 +9947,8 @@ function extractMetadata(events) {
9946
9947
  for (const event of events) {
9947
9948
  if (!isRootEvent(event)) continue;
9948
9949
  const { data } = event;
9949
- const timestamp = eventTimestamp(event);
9950
- if (timestamp) metadata.lastTimestamp = timestamp;
9950
+ const timestamp2 = eventTimestamp(event);
9951
+ if (timestamp2) metadata.lastTimestamp = timestamp2;
9951
9952
  if (event.type === "session.start") {
9952
9953
  metadata.sessionId ||= readString(data.sessionId);
9953
9954
  metadata.version ||= readString(data.copilotVersion) || (typeof data.version === "number" ? String(data.version) : readString(data.version));
@@ -9985,7 +9986,7 @@ function extractMetadata(events) {
9985
9986
  }
9986
9987
  if (event.type !== "user.message") continue;
9987
9988
  metadata.turnCount++;
9988
- metadata.timestamp ||= timestamp;
9989
+ metadata.timestamp ||= timestamp2;
9989
9990
  const content = readString(data.content).trim();
9990
9991
  if (!content) continue;
9991
9992
  metadata.firstUserMessage ||= content;
@@ -10209,7 +10210,7 @@ function extractToolResult(data) {
10209
10210
  if (result.structuredContent !== void 0) return safeStringify2(result.structuredContent);
10210
10211
  return safeStringify2(result);
10211
10212
  }
10212
- function appendThinking2(turn, text, timestamp, signature) {
10213
+ function appendThinking2(turn, text, timestamp2, signature) {
10213
10214
  if (!text || turn.thinking.some((block2) => block2.thinking === text)) return;
10214
10215
  const block = { type: "thinking", thinking: text, signature };
10215
10216
  turn.thinking.push(block);
@@ -10218,21 +10219,21 @@ function appendThinking2(turn, text, timestamp, signature) {
10218
10219
  last.blocks.push(block);
10219
10220
  return;
10220
10221
  }
10221
- turn.contentBlocks.push({ kind: "thinking", blocks: [block], timestamp });
10222
+ turn.contentBlocks.push({ kind: "thinking", blocks: [block], timestamp: timestamp2 });
10222
10223
  }
10223
- function appendToolCall2(turn, call, timestamp) {
10224
+ function appendToolCall2(turn, call, timestamp2) {
10224
10225
  turn.toolCalls.push(call);
10225
10226
  const last = turn.contentBlocks[turn.contentBlocks.length - 1];
10226
10227
  if (last?.kind === "tool_calls") {
10227
10228
  last.toolCalls.push(call);
10228
10229
  return;
10229
10230
  }
10230
- turn.contentBlocks.push({ kind: "tool_calls", toolCalls: [call], timestamp });
10231
+ turn.contentBlocks.push({ kind: "tool_calls", toolCalls: [call], timestamp: timestamp2 });
10231
10232
  }
10232
- function newToolCall(id, name, input, timestamp) {
10233
- return { id, name, input, result: null, isError: false, timestamp };
10233
+ function newToolCall(id, name, input, timestamp2) {
10234
+ return { id, name, input, result: null, isError: false, timestamp: timestamp2 };
10234
10235
  }
10235
- function toolCallsFromRequests(value, timestamp, isPending) {
10236
+ function toolCallsFromRequests(value, timestamp2, isPending) {
10236
10237
  if (!Array.isArray(value)) return [];
10237
10238
  const calls = [];
10238
10239
  for (const request of value) {
@@ -10241,14 +10242,14 @@ function toolCallsFromRequests(value, timestamp, isPending) {
10241
10242
  const rawName = readString(request.name);
10242
10243
  if (!id || !rawName || isPending(id)) continue;
10243
10244
  const name = normalizeToolName(rawName);
10244
- calls.push(newToolCall(id, name, normalizeToolInput(name, request.arguments), timestamp));
10245
+ calls.push(newToolCall(id, name, normalizeToolInput(name, request.arguments), timestamp2));
10245
10246
  }
10246
10247
  return calls;
10247
10248
  }
10248
- function updateToolCallStart(call, name, input, timestamp) {
10249
+ function updateToolCallStart(call, name, input, timestamp2) {
10249
10250
  call.name = name;
10250
10251
  call.input = normalizeToolInput(name, input);
10251
- call.timestamp = timestamp || call.timestamp;
10252
+ call.timestamp = timestamp2 || call.timestamp;
10252
10253
  }
10253
10254
  function updateToolCallResult(call, data, binaryAssets) {
10254
10255
  call.result = extractToolResult(data);
@@ -10256,7 +10257,7 @@ function updateToolCallResult(call, data, binaryAssets) {
10256
10257
  if (resultImages.length > 0) call.resultImages = resultImages;
10257
10258
  call.isError = data.success === false || data.error !== void 0 && data.error !== null;
10258
10259
  }
10259
- function createTurn2(id, timestamp, userMessage, model, effort, isFragment) {
10260
+ function createTurn2(id, timestamp2, userMessage, model, effort, isFragment) {
10260
10261
  return {
10261
10262
  id,
10262
10263
  userMessage,
@@ -10265,7 +10266,7 @@ function createTurn2(id, timestamp, userMessage, model, effort, isFragment) {
10265
10266
  assistantText: [],
10266
10267
  toolCalls: [],
10267
10268
  subAgentActivity: [],
10268
- timestamp,
10269
+ timestamp: timestamp2,
10269
10270
  durationMs: null,
10270
10271
  tokenUsage: null,
10271
10272
  model,
@@ -10292,8 +10293,8 @@ function parseCopilotSession(jsonlText, options) {
10292
10293
  let sawAssistantUsage = false;
10293
10294
  let sawAssistantDuration = false;
10294
10295
  let shutdownUsage = null;
10295
- function noteTimestamp(turn, timestamp) {
10296
- if (timestamp) endTimestamps.set(turn, timestamp);
10296
+ function noteTimestamp(turn, timestamp2) {
10297
+ if (timestamp2) endTimestamps.set(turn, timestamp2);
10297
10298
  }
10298
10299
  function ensureTurn(event) {
10299
10300
  if (!current) {
@@ -10354,7 +10355,7 @@ function parseCopilotSession(jsonlText, options) {
10354
10355
  const message = ensureAgent(event);
10355
10356
  if (!message) return true;
10356
10357
  const { data } = event;
10357
- const timestamp = eventTimestamp(event);
10358
+ const timestamp2 = eventTimestamp(event);
10358
10359
  if (event.type === "subagent.started" || event.type === "subagent.configured") {
10359
10360
  message.parentToolUseId ||= readString(data.toolCallId) || void 0;
10360
10361
  message.agentName = readString(data.agentDisplayName, data.agentName) || message.agentName;
@@ -10393,7 +10394,7 @@ function parseCopilotSession(jsonlText, options) {
10393
10394
  if (text && !message.text.includes(text)) message.text.push(text);
10394
10395
  for (const call of toolCallsFromRequests(
10395
10396
  data.toolRequests,
10396
- timestamp,
10397
+ timestamp2,
10397
10398
  (id) => pendingAgentToolCalls.has(id)
10398
10399
  )) {
10399
10400
  message.toolCalls.push(call);
@@ -10413,13 +10414,13 @@ function parseCopilotSession(jsonlText, options) {
10413
10414
  const name = normalizeToolName(rawName);
10414
10415
  const existing = pendingAgentToolCalls.get(callId);
10415
10416
  if (existing) {
10416
- updateToolCallStart(existing.call, name, data.arguments, timestamp);
10417
+ updateToolCallStart(existing.call, name, data.arguments, timestamp2);
10417
10418
  } else {
10418
10419
  const call = newToolCall(
10419
10420
  callId,
10420
10421
  name,
10421
10422
  normalizeToolInput(name, data.arguments),
10422
- timestamp
10423
+ timestamp2
10423
10424
  );
10424
10425
  message.toolCalls.push(call);
10425
10426
  pendingAgentToolCalls.set(callId, { call, message });
@@ -10432,7 +10433,7 @@ function parseCopilotSession(jsonlText, options) {
10432
10433
  if (!pending) {
10433
10434
  const rawName = readString(data.toolName) || "Tool";
10434
10435
  const name = normalizeToolName(rawName);
10435
- const call = newToolCall(callId, name, {}, timestamp);
10436
+ const call = newToolCall(callId, name, {}, timestamp2);
10436
10437
  message.toolCalls.push(call);
10437
10438
  pending = { call, message };
10438
10439
  }
@@ -10445,7 +10446,7 @@ function parseCopilotSession(jsonlText, options) {
10445
10446
  for (const event of events) {
10446
10447
  if (applyAgentEvent(event)) continue;
10447
10448
  const { data } = event;
10448
- const timestamp = eventTimestamp(event);
10449
+ const timestamp2 = eventTimestamp(event);
10449
10450
  if (event.type === "session.start" || event.type === "session.resume") {
10450
10451
  currentModel = readString(data.selectedModel) || currentModel;
10451
10452
  currentEffort = readString(data.reasoningEffort) || currentEffort;
@@ -10478,13 +10479,13 @@ function parseCopilotSession(jsonlText, options) {
10478
10479
  finalizeCurrent();
10479
10480
  current = createTurn2(
10480
10481
  turnEventId(event),
10481
- timestamp,
10482
+ timestamp2,
10482
10483
  buildUserContent(data, binaryAssets),
10483
10484
  currentModel,
10484
10485
  currentEffort,
10485
10486
  false
10486
10487
  );
10487
- noteTimestamp(current, timestamp);
10488
+ noteTimestamp(current, timestamp2);
10488
10489
  continue;
10489
10490
  }
10490
10491
  if (event.type === "assistant.turn_start") {
@@ -10492,7 +10493,7 @@ function parseCopilotSession(jsonlText, options) {
10492
10493
  const turn = ensureTurn(event);
10493
10494
  turn.model = currentModel;
10494
10495
  if (currentEffort) turn.effort = currentEffort;
10495
- noteTimestamp(turn, timestamp);
10496
+ noteTimestamp(turn, timestamp2);
10496
10497
  continue;
10497
10498
  }
10498
10499
  if (event.type === "assistant.reasoning") {
@@ -10500,10 +10501,10 @@ function parseCopilotSession(jsonlText, options) {
10500
10501
  appendThinking2(
10501
10502
  turn,
10502
10503
  readString(data.content),
10503
- timestamp,
10504
+ timestamp2,
10504
10505
  readString(data.reasoningId) || eventId(event, "copilot-thinking")
10505
10506
  );
10506
- noteTimestamp(turn, timestamp);
10507
+ noteTimestamp(turn, timestamp2);
10507
10508
  continue;
10508
10509
  }
10509
10510
  if (event.type === "assistant.message") {
@@ -10514,19 +10515,19 @@ function parseCopilotSession(jsonlText, options) {
10514
10515
  appendThinking2(
10515
10516
  turn,
10516
10517
  readString(data.reasoningText),
10517
- timestamp,
10518
+ timestamp2,
10518
10519
  eventId(event, "copilot-thinking")
10519
10520
  );
10520
- appendAssistantText(turn, textFromValue(data.content), timestamp);
10521
+ appendAssistantText(turn, textFromValue(data.content), timestamp2);
10521
10522
  for (const call of toolCallsFromRequests(
10522
10523
  data.toolRequests,
10523
- timestamp,
10524
+ timestamp2,
10524
10525
  (id) => pendingToolCalls.has(id)
10525
10526
  )) {
10526
- appendToolCall2(turn, call, timestamp);
10527
+ appendToolCall2(turn, call, timestamp2);
10527
10528
  pendingToolCalls.set(call.id, { call, turn });
10528
10529
  }
10529
- noteTimestamp(turn, timestamp);
10530
+ noteTimestamp(turn, timestamp2);
10530
10531
  continue;
10531
10532
  }
10532
10533
  if (event.type === "assistant.usage") {
@@ -10541,7 +10542,7 @@ function parseCopilotSession(jsonlText, options) {
10541
10542
  if (currentEffort) turn.effort = currentEffort;
10542
10543
  if (usage) turn.tokenUsage = mergeTokenUsage2(turn.tokenUsage, usage);
10543
10544
  if (duration) apiDurationMs.set(turn, (apiDurationMs.get(turn) ?? 0) + duration);
10544
- noteTimestamp(turn, timestamp);
10545
+ noteTimestamp(turn, timestamp2);
10545
10546
  continue;
10546
10547
  }
10547
10548
  if (event.type === "tool.execution_start") {
@@ -10553,18 +10554,18 @@ function parseCopilotSession(jsonlText, options) {
10553
10554
  const name = normalizeToolName(rawName);
10554
10555
  const existing = pendingToolCalls.get(callId);
10555
10556
  if (existing) {
10556
- updateToolCallStart(existing.call, name, data.arguments, timestamp);
10557
+ updateToolCallStart(existing.call, name, data.arguments, timestamp2);
10557
10558
  } else {
10558
10559
  const call = newToolCall(
10559
10560
  callId,
10560
10561
  name,
10561
10562
  normalizeToolInput(name, data.arguments),
10562
- timestamp
10563
+ timestamp2
10563
10564
  );
10564
- appendToolCall2(turn, call, timestamp);
10565
+ appendToolCall2(turn, call, timestamp2);
10565
10566
  pendingToolCalls.set(callId, { call, turn });
10566
10567
  }
10567
- noteTimestamp(turn, timestamp);
10568
+ noteTimestamp(turn, timestamp2);
10568
10569
  continue;
10569
10570
  }
10570
10571
  if (event.type === "tool.execution_complete") {
@@ -10575,13 +10576,13 @@ function parseCopilotSession(jsonlText, options) {
10575
10576
  const turn = ensureTurn(event);
10576
10577
  const rawName = readString(data.toolName) || "Tool";
10577
10578
  const name = normalizeToolName(rawName);
10578
- const call = newToolCall(callId, name, {}, timestamp);
10579
- appendToolCall2(turn, call, timestamp);
10579
+ const call = newToolCall(callId, name, {}, timestamp2);
10580
+ appendToolCall2(turn, call, timestamp2);
10580
10581
  pending = { call, turn };
10581
10582
  }
10582
10583
  updateToolCallResult(pending.call, data, binaryAssets);
10583
10584
  pendingToolCalls.delete(callId);
10584
- noteTimestamp(pending.turn, timestamp);
10585
+ noteTimestamp(pending.turn, timestamp2);
10585
10586
  continue;
10586
10587
  }
10587
10588
  if (event.type === "session.error") {
@@ -10596,13 +10597,13 @@ function parseCopilotSession(jsonlText, options) {
10596
10597
  input,
10597
10598
  result: readString(data.message) || "Copilot session error",
10598
10599
  isError: true,
10599
- timestamp
10600
- }, timestamp);
10601
- noteTimestamp(turn, timestamp);
10600
+ timestamp: timestamp2
10601
+ }, timestamp2);
10602
+ noteTimestamp(turn, timestamp2);
10602
10603
  continue;
10603
10604
  }
10604
10605
  if (event.type === "assistant.turn_end" || event.type === "assistant.idle" || event.type === "session.idle") {
10605
- if (current) noteTimestamp(current, timestamp);
10606
+ if (current) noteTimestamp(current, timestamp2);
10606
10607
  }
10607
10608
  }
10608
10609
  finalizeCurrent();
@@ -10645,7 +10646,7 @@ function parseCopilotSession(jsonlText, options) {
10645
10646
  };
10646
10647
  }
10647
10648
  function appendCopilotSession(existing, newJsonlText) {
10648
- const prefix = existing.rawMessages.map((record3) => JSON.stringify(record3)).join("\n");
10649
+ const prefix = existing.rawMessages.map((record4) => JSON.stringify(record4)).join("\n");
10649
10650
  return parseCopilotSession(prefix ? `${prefix}
10650
10651
  ${newJsonlText}` : newJsonlText);
10651
10652
  }
@@ -10753,11 +10754,11 @@ function brandCopilotBranch() {
10753
10754
  function copilotTurnBoundaries(records) {
10754
10755
  const boundaries = [];
10755
10756
  for (let index = 0; index < records.length; index++) {
10756
- const record3 = records[index];
10757
- if (record3.type !== "user.message" || typeof record3.agentId === "string") continue;
10758
- const data = record3.data;
10757
+ const record4 = records[index];
10758
+ if (record4.type !== "user.message" || typeof record4.agentId === "string") continue;
10759
+ const data = record4.data;
10759
10760
  if (!data || typeof data !== "object" || Array.isArray(data)) continue;
10760
- if (typeof record3.id !== "string" || !record3.id) continue;
10761
+ if (typeof record4.id !== "string" || !record4.id) continue;
10761
10762
  boundaries.push(index);
10762
10763
  }
10763
10764
  return boundaries;
@@ -10814,14 +10815,14 @@ async function readCopilotSessionIdentity(filePath) {
10814
10815
  let cwd = "";
10815
10816
  let gitBranch = "";
10816
10817
  for (const line of await readHeadLines(filePath, HEAD_BYTES)) {
10817
- let record3;
10818
+ let record4;
10818
10819
  try {
10819
- record3 = JSON.parse(line);
10820
+ record4 = JSON.parse(line);
10820
10821
  } catch {
10821
10822
  continue;
10822
10823
  }
10823
- if (!isRecord3(record3) || record3.type !== "session.start" && record3.type !== "session.resume") continue;
10824
- const data = isRecord3(record3.data) ? record3.data : null;
10824
+ if (!isRecord3(record4) || record4.type !== "session.start" && record4.type !== "session.resume") continue;
10825
+ const data = isRecord3(record4.data) ? record4.data : null;
10825
10826
  if (!data) continue;
10826
10827
  if (typeof data.sessionId === "string" && data.sessionId) sessionId = data.sessionId;
10827
10828
  const context = isRecord3(data.context) ? data.context : null;
@@ -11141,7 +11142,7 @@ function groupPlanModeBlocks(blocks) {
11141
11142
  if (enterIdx !== -1) {
11142
11143
  const enterCall = block.toolCalls[enterIdx];
11143
11144
  const plan = String(enterCall.input.plan ?? "");
11144
- const timestamp = block.timestamp;
11145
+ const timestamp2 = block.timestamp;
11145
11146
  const before = block.toolCalls.slice(0, enterIdx);
11146
11147
  if (before.length > 0) {
11147
11148
  result.push({ kind: "tool_calls", toolCalls: before, timestamp: block.timestamp });
@@ -11157,7 +11158,7 @@ function groupPlanModeBlocks(blocks) {
11157
11158
  if (exitCall.result !== null) {
11158
11159
  status = exitCall.isError ? "rejected" : "approved";
11159
11160
  }
11160
- result.push({ kind: "plan_mode", plan, planFilePath, status, toolCalls: embedded, timestamp });
11161
+ result.push({ kind: "plan_mode", plan, planFilePath, status, toolCalls: embedded, timestamp: timestamp2 });
11161
11162
  const after = afterEnterInSameBlock.slice(exitInSameBlock + 1);
11162
11163
  if (after.length > 0) {
11163
11164
  result.push({ kind: "tool_calls", toolCalls: after, timestamp: block.timestamp });
@@ -11183,7 +11184,7 @@ function groupPlanModeBlocks(blocks) {
11183
11184
  status = exitCall.isError ? "rejected" : "approved";
11184
11185
  }
11185
11186
  const tail = next.toolCalls.slice(exitIdx + 1);
11186
- result.push({ kind: "plan_mode", plan, planFilePath, status, toolCalls: embedded, timestamp });
11187
+ result.push({ kind: "plan_mode", plan, planFilePath, status, toolCalls: embedded, timestamp: timestamp2 });
11187
11188
  result.push(...passthroughBlocks);
11188
11189
  if (tail.length > 0) {
11189
11190
  result.push({ kind: "tool_calls", toolCalls: tail, timestamp: next.timestamp });
@@ -11202,7 +11203,7 @@ function groupPlanModeBlocks(blocks) {
11202
11203
  }
11203
11204
  }
11204
11205
  if (!exitCall) {
11205
- result.push({ kind: "plan_mode", plan, planFilePath: void 0, status: "pending", toolCalls: embedded, timestamp });
11206
+ result.push({ kind: "plan_mode", plan, planFilePath: void 0, status: "pending", toolCalls: embedded, timestamp: timestamp2 });
11206
11207
  result.push(...passthroughBlocks);
11207
11208
  i = j;
11208
11209
  }
@@ -12184,9 +12185,9 @@ function nonEmpty(value) {
12184
12185
  function stripTaggedBlocks(text) {
12185
12186
  return text.replace(/<[^>]+>[\s\S]*?<\/[^>]+>/g, "").trim();
12186
12187
  }
12187
- function effortFromRecord(record3) {
12188
+ function effortFromRecord(record4) {
12188
12189
  for (const kind of AGENT_KINDS) {
12189
- const effort = READERS[kind].effort(record3);
12190
+ const effort = READERS[kind].effort(record4);
12190
12191
  if (effort) return effort;
12191
12192
  }
12192
12193
  return null;
@@ -12196,15 +12197,15 @@ function userMessageTextFromLine(line) {
12196
12197
  (kind) => READERS[kind].userMessageMarkers.some((marker) => line.includes(marker))
12197
12198
  );
12198
12199
  if (candidates.length === 0) return null;
12199
- let record3;
12200
+ let record4;
12200
12201
  try {
12201
- record3 = JSON.parse(line);
12202
+ record4 = JSON.parse(line);
12202
12203
  } catch {
12203
12204
  return null;
12204
12205
  }
12205
- if (!isRecord4(record3)) return null;
12206
+ if (!isRecord4(record4)) return null;
12206
12207
  for (const kind of candidates) {
12207
- const text = READERS[kind].userMessageText(record3);
12208
+ const text = READERS[kind].userMessageText(record4);
12208
12209
  if (text !== null) return text;
12209
12210
  }
12210
12211
  return null;
@@ -12216,11 +12217,11 @@ var init_recordReaders = __esm({
12216
12217
  claudeReader = {
12217
12218
  kind: "claude",
12218
12219
  // Every assistant record is tagged with the effort that turn ran at.
12219
- effort: (record3) => record3.type === "assistant" ? nonEmpty(record3.effort) : null,
12220
+ effort: (record4) => record4.type === "assistant" ? nonEmpty(record4.effort) : null,
12220
12221
  userMessageMarkers: ['"user"'],
12221
- userMessageText(record3) {
12222
- if (record3.type !== "user" || record3.isMeta) return null;
12223
- const content = isRecord4(record3.message) ? record3.message.content : void 0;
12222
+ userMessageText(record4) {
12223
+ if (record4.type !== "user" || record4.isMeta) return null;
12224
+ const content = isRecord4(record4.message) ? record4.message.content : void 0;
12224
12225
  if (typeof content === "string") return stripTaggedBlocks(content);
12225
12226
  if (!Array.isArray(content)) return "";
12226
12227
  let text = "";
@@ -12235,32 +12236,32 @@ var init_recordReaders = __esm({
12235
12236
  codexReader = {
12236
12237
  kind: "codex",
12237
12238
  // Effort is recorded per turn; newer CLI versions moved it under `thread_settings`.
12238
- effort(record3) {
12239
- if (record3.type !== "turn_context" || !isRecord4(record3.payload)) return null;
12240
- const { payload } = record3;
12239
+ effort(record4) {
12240
+ if (record4.type !== "turn_context" || !isRecord4(record4.payload)) return null;
12241
+ const { payload } = record4;
12241
12242
  const direct = nonEmpty(payload.effort);
12242
12243
  if (direct) return direct;
12243
12244
  const settings = isRecord4(payload.thread_settings) ? payload.thread_settings : null;
12244
12245
  return nonEmpty(settings?.reasoning_effort);
12245
12246
  },
12246
12247
  userMessageMarkers: ['"event_msg"'],
12247
- userMessageText(record3) {
12248
- if (record3.type !== "event_msg" || !isRecord4(record3.payload)) return null;
12249
- const { payload } = record3;
12248
+ userMessageText(record4) {
12249
+ if (record4.type !== "event_msg" || !isRecord4(record4.payload)) return null;
12250
+ const { payload } = record4;
12250
12251
  return payload.type === "user_message" && typeof payload.message === "string" ? payload.message.trim() : null;
12251
12252
  }
12252
12253
  };
12253
12254
  copilotReader = {
12254
12255
  kind: "copilot",
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);
12256
+ effort(record4) {
12257
+ if (record4.type !== "session.start" && record4.type !== "session.resume" && record4.type !== "session.model_change" || !isRecord4(record4.data)) return null;
12258
+ return nonEmpty(record4.data.reasoningEffort ?? record4.data.effort);
12258
12259
  },
12259
12260
  userMessageMarkers: ['"user.message"'],
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;
12261
+ userMessageText(record4) {
12262
+ if (record4.type !== "user.message") return null;
12263
+ if (typeof record4.agentId === "string" && record4.agentId) return null;
12264
+ const data = isRecord4(record4.data) ? record4.data : null;
12264
12265
  return typeof data?.content === "string" ? data.content.trim() : "";
12265
12266
  }
12266
12267
  };
@@ -12273,16 +12274,16 @@ var init_recordReaders = __esm({
12273
12274
  });
12274
12275
 
12275
12276
  // ../../server/agents/tailRecords.ts
12276
- function isSubagentLifecycle(record3) {
12277
- return record3.type.startsWith("subagent.") && typeof record3.agentId === "string" && record3.agentId.length > 0;
12277
+ function isSubagentLifecycle(record4) {
12278
+ return record4.type.startsWith("subagent.") && typeof record4.agentId === "string" && record4.agentId.length > 0;
12278
12279
  }
12279
- function isSubagentNoise(record3) {
12280
- return typeof record3.agentId === "string" && record3.agentId.length > 0;
12280
+ function isSubagentNoise(record4) {
12281
+ return typeof record4.agentId === "string" && record4.agentId.length > 0;
12281
12282
  }
12282
- function classifyTailRecord(record3) {
12283
+ function classifyTailRecord(record4) {
12283
12284
  for (const kind of AGENT_KINDS) {
12284
12285
  const format = TAIL_FORMATS[kind];
12285
- const verdict = format.classify(record3);
12286
+ const verdict = format.classify(record4);
12286
12287
  if (verdict.kind !== "ignore") return { format, verdict };
12287
12288
  }
12288
12289
  return null;
@@ -12299,31 +12300,31 @@ var init_tailRecords = __esm({
12299
12300
  // Background agent/workflow launches, task notifications and TaskStop calls
12300
12301
  // can all still change a verdict that a turn-ending line looked to settle.
12301
12302
  markers: ["async_launched", "task-notification", '"TaskStop"'],
12302
- classify(record3) {
12303
- if (record3.type === "system" && record3.subtype === "terminal_reason") {
12304
- const reason = record3.reason;
12303
+ classify(record4) {
12304
+ if (record4.type === "system" && record4.subtype === "terminal_reason") {
12305
+ const reason = record4.reason;
12305
12306
  return reason ? { kind: "final", status: { status: "completed", terminalReason: reason } } : IGNORE;
12306
12307
  }
12307
- if (record3.type === "progress") {
12308
- const data = record3.data;
12308
+ if (record4.type === "progress") {
12309
+ const data = record4.data;
12309
12310
  if (data?.type !== "hook_progress") return IGNORE;
12310
12311
  const decision = data.decision ?? data.hookSpecificOutput?.permissionDecision;
12311
12312
  return decision === "defer" ? ANSWER : IGNORE;
12312
12313
  }
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") {
12314
+ if (record4.type === "attachment") return KEEP;
12315
+ if (record4.type === "assistant" || record4.type === "user" || record4.type === "queue-operation") {
12316
+ const stopReason = record4.message?.stop_reason;
12317
+ if (record4.type === "assistant" && stopReason === "end_turn") {
12317
12318
  return { kind: "turn-end", awaitUserActivity: true };
12318
12319
  }
12319
- const canDerive = record3.type === "assistant" || record3.type === "user" && !record3.isMeta;
12320
+ const canDerive = record4.type === "assistant" || record4.type === "user" && !record4.isMeta;
12320
12321
  return canDerive ? ANSWER : KEEP;
12321
12322
  }
12322
12323
  return IGNORE;
12323
12324
  },
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;
12325
+ classifyAfterTurnEnd(record4) {
12326
+ if (record4.type !== "user" && record4.type !== "assistant" && record4.type !== "queue-operation" && record4.type !== "attachment") return IGNORE;
12327
+ const isRealUserTurn = record4.type === "user" && !record4.isMeta;
12327
12328
  return { kind: "keep", sawUserActivity: isRealUserTurn };
12328
12329
  }
12329
12330
  };
@@ -12342,9 +12343,9 @@ var init_tailRecords = __esm({
12342
12343
  "agent_message",
12343
12344
  "function_call_output"
12344
12345
  ],
12345
- classify(record3) {
12346
- if (record3.type === "event_msg") {
12347
- const payload = record3.payload;
12346
+ classify(record4) {
12347
+ if (record4.type === "event_msg") {
12348
+ const payload = record4.payload;
12348
12349
  switch (payload?.type) {
12349
12350
  case "task_complete":
12350
12351
  return { kind: "turn-end" };
@@ -12356,32 +12357,32 @@ var init_tailRecords = __esm({
12356
12357
  return IGNORE;
12357
12358
  }
12358
12359
  }
12359
- if (record3.type === "response_item") {
12360
- const payload = record3.payload;
12360
+ if (record4.type === "response_item") {
12361
+ const payload = record4.payload;
12361
12362
  const decides = payload?.type === "function_call" || payload?.type === "message" && (payload.role === "assistant" || payload.role === "user");
12362
12363
  return decides ? ANSWER : IGNORE;
12363
12364
  }
12364
12365
  return IGNORE;
12365
12366
  },
12366
- classifyAfterTurnEnd(record3) {
12367
- return record3.type === "event_msg" || record3.type === "response_item" ? KEEP : IGNORE;
12367
+ classifyAfterTurnEnd(record4) {
12368
+ return record4.type === "event_msg" || record4.type === "response_item" ? KEEP : IGNORE;
12368
12369
  }
12369
12370
  };
12370
12371
  copilotTail = {
12371
12372
  kind: "copilot",
12372
12373
  markers: ['"abort"', '"assistant.message"', '"user.message"', '"subagent.'],
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;
12374
+ classify(record4) {
12375
+ if (isSubagentLifecycle(record4)) return KEEP;
12376
+ const decidable = record4.type === "abort" || record4.type === "user.message" || record4.type.startsWith("assistant.") || record4.type.startsWith("permission.") || record4.type.startsWith("session.") || record4.type.startsWith("tool.") || record4.type.startsWith("user_input.");
12377
+ if (!decidable || isSubagentNoise(record4)) return IGNORE;
12378
+ if (record4.type === "assistant.turn_end") return { kind: "turn-end" };
12379
+ if (record4.type === "session.start" || record4.type === "session.resume") return ANSWER;
12379
12380
  return { kind: "answer-if-active" };
12380
12381
  },
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";
12382
+ classifyAfterTurnEnd(record4) {
12383
+ if (isSubagentLifecycle(record4)) return KEEP;
12384
+ if (isSubagentNoise(record4)) return IGNORE;
12385
+ const decides = record4.type === "abort" || record4.type === "assistant.message" || record4.type === "user.message";
12385
12386
  return decides ? ANSWER : IGNORE;
12386
12387
  }
12387
12388
  };
@@ -12436,14 +12437,14 @@ async function readTranscriptEffort(filePath) {
12436
12437
  for (let i = lines.length - 1; i >= 0; i--) {
12437
12438
  const line = lines[i];
12438
12439
  if (!line || !line.includes("effort") && !line.includes("Effort")) continue;
12439
- let record3;
12440
+ let record4;
12440
12441
  try {
12441
- record3 = JSON.parse(line);
12442
+ record4 = JSON.parse(line);
12442
12443
  } catch {
12443
12444
  continue;
12444
12445
  }
12445
- if (typeof record3 !== "object" || record3 === null) continue;
12446
- const effort = effortFromRecord(record3);
12446
+ if (typeof record4 !== "object" || record4 === null) continue;
12447
+ const effort = effortFromRecord(record4);
12447
12448
  if (effort) return effort;
12448
12449
  }
12449
12450
  }
@@ -12479,14 +12480,14 @@ async function getSessionStatus(filePath) {
12479
12480
  const line = lines[i];
12480
12481
  if (!line) continue;
12481
12482
  if (turnEnded && !isTailCandidate(line, turnEnded)) continue;
12482
- let record3;
12483
+ let record4;
12483
12484
  try {
12484
- record3 = JSON.parse(line);
12485
+ record4 = JSON.parse(line);
12485
12486
  } catch {
12486
12487
  continue;
12487
12488
  }
12488
- if (typeof record3?.type !== "string") continue;
12489
- const match = turnEnded ? { format: turnEnded, verdict: turnEnded.classifyAfterTurnEnd(record3) } : classifyTailRecord(record3);
12489
+ if (typeof record4?.type !== "string") continue;
12490
+ const match = turnEnded ? { format: turnEnded, verdict: turnEnded.classifyAfterTurnEnd(record4) } : classifyTailRecord(record4);
12490
12491
  if (!match) continue;
12491
12492
  const { verdict } = match;
12492
12493
  switch (verdict.kind) {
@@ -12495,20 +12496,20 @@ async function getSessionStatus(filePath) {
12495
12496
  case "final":
12496
12497
  return verdict.status;
12497
12498
  case "keep":
12498
- meaningful.unshift(record3);
12499
+ meaningful.unshift(record4);
12499
12500
  if (verdict.sawUserActivity) needUserActivity = false;
12500
12501
  continue;
12501
12502
  case "answer":
12502
- meaningful.unshift(record3);
12503
+ meaningful.unshift(record4);
12503
12504
  return deriveSessionStatus(meaningful);
12504
12505
  case "answer-if-active": {
12505
- meaningful.unshift(record3);
12506
+ meaningful.unshift(record4);
12506
12507
  const status = deriveSessionStatus(meaningful);
12507
12508
  if (status.status !== "idle") return status;
12508
12509
  continue;
12509
12510
  }
12510
12511
  case "turn-end":
12511
- meaningful.unshift(record3);
12512
+ meaningful.unshift(record4);
12512
12513
  turnEnded = match.format;
12513
12514
  needUserActivity = verdict.awaitUserActivity === true;
12514
12515
  continue;
@@ -12653,12 +12654,12 @@ var init_modelCatalog = __esm({
12653
12654
 
12654
12655
  // ../../server/agents/timeout.ts
12655
12656
  function withTimeout(promise, ms, label) {
12656
- return new Promise((resolve21, reject) => {
12657
+ return new Promise((resolve22, reject) => {
12657
12658
  const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
12658
12659
  promise.then(
12659
12660
  (value) => {
12660
12661
  clearTimeout(timer);
12661
- resolve21(value);
12662
+ resolve22(value);
12662
12663
  },
12663
12664
  (error) => {
12664
12665
  clearTimeout(timer);
@@ -12861,7 +12862,7 @@ async function awaitTranscript(filePath, isSettled) {
12861
12862
  return true;
12862
12863
  } catch {
12863
12864
  }
12864
- await new Promise((resolve21) => setTimeout(resolve21, TRANSCRIPT_POLL_INTERVAL_MS));
12865
+ await new Promise((resolve22) => setTimeout(resolve22, TRANSCRIPT_POLL_INTERVAL_MS));
12865
12866
  }
12866
12867
  return false;
12867
12868
  }
@@ -12908,7 +12909,7 @@ function startOneShot(req) {
12908
12909
  child.on("close", () => {
12909
12910
  activeProcesses.delete(sessionId);
12910
12911
  });
12911
- return new Promise((resolve21, reject) => {
12912
+ return new Promise((resolve22, reject) => {
12912
12913
  let settled = false;
12913
12914
  const fail = (message) => {
12914
12915
  if (settled) return;
@@ -12930,7 +12931,7 @@ function startOneShot(req) {
12930
12931
  await stat7(filePath);
12931
12932
  settled = true;
12932
12933
  clearTimeout(timer);
12933
- resolve21({ sessionId, dirName: req.dirName, fileName, filePath });
12934
+ resolve22({ sessionId, dirName: req.dirName, fileName, filePath });
12934
12935
  } catch {
12935
12936
  fail(
12936
12937
  stderr.trim() || `${descriptor4.binName} exited with code ${code} before creating session`
@@ -12960,7 +12961,7 @@ function startInteractive(req) {
12960
12961
  worktreeName: req.worktreeName,
12961
12962
  mcpConfig: req.mcpConfig
12962
12963
  });
12963
- return new Promise((resolve21, reject) => {
12964
+ return new Promise((resolve22, reject) => {
12964
12965
  let settled = false;
12965
12966
  const succeed = async () => {
12966
12967
  if (settled) return;
@@ -12970,7 +12971,7 @@ function startInteractive(req) {
12970
12971
  initialContent = await readFile9(filePath, "utf-8");
12971
12972
  } catch {
12972
12973
  }
12973
- resolve21({ sessionId, dirName: req.dirName, fileName, filePath, initialContent });
12974
+ resolve22({ sessionId, dirName: req.dirName, fileName, filePath, initialContent });
12974
12975
  };
12975
12976
  const fail = (message) => {
12976
12977
  if (settled) return;
@@ -13111,10 +13112,10 @@ var init_claudeRuntime = __esm({
13111
13112
  mcpConfig: req.mcpConfig
13112
13113
  });
13113
13114
  watchSubagentsFor(state, req.filePath ?? null);
13114
- const completion = new Promise((resolve21) => {
13115
+ const completion = new Promise((resolve22) => {
13115
13116
  state.onResult = (result) => {
13116
13117
  state.onResult = null;
13117
- resolve21(turnResultFrom(result));
13118
+ resolve22(turnResultFrom(result));
13118
13119
  };
13119
13120
  });
13120
13121
  return { delivery: "started", completion };
@@ -13200,7 +13201,7 @@ var init_package = __esm({
13200
13201
  package_default = {
13201
13202
  name: "cogpit",
13202
13203
  private: true,
13203
- version: "2.2.1",
13204
+ version: "2.3.0",
13204
13205
  description: "Control center for Claude Code, OpenAI Codex, and GitHub Copilot CLI sessions",
13205
13206
  license: "MIT",
13206
13207
  author: {
@@ -14072,7 +14073,7 @@ var init_codexAppServer = __esm({
14072
14073
  );
14073
14074
  }
14074
14075
  const id = this.nextRequestId++;
14075
- return new Promise((resolve21, reject) => {
14076
+ return new Promise((resolve22, reject) => {
14076
14077
  const timer = timeoutMs > 0 ? this.setTimer(() => {
14077
14078
  const pending = this.pendingRequests.get(id);
14078
14079
  if (!pending) return;
@@ -14085,7 +14086,7 @@ var init_codexAppServer = __esm({
14085
14086
  }, timeoutMs) : null;
14086
14087
  this.pendingRequests.set(id, {
14087
14088
  method,
14088
- resolve: (result) => resolve21(result),
14089
+ resolve: (result) => resolve22(result),
14089
14090
  reject,
14090
14091
  timer
14091
14092
  });
@@ -14111,12 +14112,12 @@ var init_codexAppServer = __esm({
14111
14112
  new CodexAppServerError("Codex app-server stdin is not writable")
14112
14113
  );
14113
14114
  }
14114
- return new Promise((resolve21, reject) => {
14115
+ return new Promise((resolve22, reject) => {
14115
14116
  try {
14116
14117
  child.stdin.write(`${JSON.stringify(message)}
14117
14118
  `, (error) => {
14118
14119
  if (error) reject(error);
14119
- else resolve21();
14120
+ else resolve22();
14120
14121
  });
14121
14122
  } catch (error) {
14122
14123
  reject(error);
@@ -14217,13 +14218,13 @@ var init_codexAppServer = __esm({
14217
14218
  }
14218
14219
  }
14219
14220
  waitForChildClose(closed, timeoutMs) {
14220
- return new Promise((resolve21) => {
14221
+ return new Promise((resolve22) => {
14221
14222
  let settled = false;
14222
14223
  const finish = (didClose) => {
14223
14224
  if (settled) return;
14224
14225
  settled = true;
14225
14226
  this.clearTimer(timer);
14226
- resolve21(didClose);
14227
+ resolve22(didClose);
14227
14228
  };
14228
14229
  const timer = this.setTimer(() => finish(false), timeoutMs);
14229
14230
  void closed.then(() => finish(true));
@@ -14232,8 +14233,8 @@ var init_codexAppServer = __esm({
14232
14233
  async terminateChild(child, error) {
14233
14234
  let didClose = false;
14234
14235
  let resolveClose = () => void 0;
14235
- const closed = new Promise((resolve21) => {
14236
- resolveClose = resolve21;
14236
+ const closed = new Promise((resolve22) => {
14237
+ resolveClose = resolve22;
14237
14238
  });
14238
14239
  child.on("close", () => {
14239
14240
  didClose = true;
@@ -14593,7 +14594,7 @@ async function waitForNewSession(cwd, knownPaths, startedAt2, timeoutMs = SESSIO
14593
14594
  while (Date.now() < deadline) {
14594
14595
  const match = await findNewestCodexSessionForCwd(cwd, knownPaths, startedAt2);
14595
14596
  if (match) return match;
14596
- await new Promise((resolve21) => setTimeout(resolve21, SESSION_DISCOVERY_INTERVAL_MS));
14597
+ await new Promise((resolve22) => setTimeout(resolve22, SESSION_DISCOVERY_INTERVAL_MS));
14597
14598
  }
14598
14599
  return null;
14599
14600
  }
@@ -14607,9 +14608,9 @@ function identityFromMetaLine(line) {
14607
14608
  const sessionId = typeof payload.id === "string" ? payload.id : "";
14608
14609
  const timestampText = typeof payload.timestamp === "string" ? payload.timestamp : typeof parsed.timestamp === "string" ? parsed.timestamp : "";
14609
14610
  if (!sessionId || !timestampText) return null;
14610
- const timestamp = new Date(timestampText);
14611
- if (Number.isNaN(timestamp.getTime())) return null;
14612
- const fileName = descriptor5.sessionFile.name(sessionId, timestamp);
14611
+ const timestamp2 = new Date(timestampText);
14612
+ if (Number.isNaN(timestamp2.getTime())) return null;
14613
+ const fileName = descriptor5.sessionFile.name(sessionId, timestamp2);
14613
14614
  return { sessionId, fileName, filePath: join11(sessionsRoot2(), fileName) };
14614
14615
  } catch {
14615
14616
  return null;
@@ -14680,7 +14681,7 @@ async function startLegacy(req, knownPaths) {
14680
14681
  child.stderr?.on("data", (data) => {
14681
14682
  stderr += data.toString();
14682
14683
  });
14683
- return new Promise((resolve21, reject) => {
14684
+ return new Promise((resolve22, reject) => {
14684
14685
  let settled = false;
14685
14686
  let sessionId = null;
14686
14687
  const discovery = waitForNewSession(req.cwd, knownPaths, startedAt2);
@@ -14698,7 +14699,7 @@ async function startLegacy(req, knownPaths) {
14698
14699
  } catch {
14699
14700
  }
14700
14701
  }
14701
- resolve21({
14702
+ resolve22({
14702
14703
  sessionId: identity.sessionId,
14703
14704
  dirName: req.dirName,
14704
14705
  fileName: identity.fileName,
@@ -14775,10 +14776,10 @@ async function sendLegacy(sessionId, req) {
14775
14776
  child.stderr?.on("data", (data) => {
14776
14777
  stderr += data.toString();
14777
14778
  });
14778
- const completion = new Promise((resolve21) => {
14779
+ const completion = new Promise((resolve22) => {
14779
14780
  session.onResult = (result) => {
14780
14781
  session.onResult = null;
14781
- resolve21({
14782
+ resolve22({
14782
14783
  isError: result.is_error === true,
14783
14784
  message: result.result
14784
14785
  });
@@ -15816,7 +15817,7 @@ var init_copilotTransport = __esm({
15816
15817
  }
15817
15818
  waitForRequest(request, method, timeoutMs = this.transportTimeoutMs, onTimeout) {
15818
15819
  if (timeoutMs <= 0) return request;
15819
- return new Promise((resolve21, reject) => {
15820
+ return new Promise((resolve22, reject) => {
15820
15821
  const timer = setTimeout(() => {
15821
15822
  try {
15822
15823
  onTimeout?.();
@@ -15827,7 +15828,7 @@ var init_copilotTransport = __esm({
15827
15828
  request.then(
15828
15829
  (value) => {
15829
15830
  clearTimeout(timer);
15830
- resolve21(value);
15831
+ resolve22(value);
15831
15832
  },
15832
15833
  (error) => {
15833
15834
  clearTimeout(timer);
@@ -15953,10 +15954,10 @@ var init_copilotTransport = __esm({
15953
15954
  ...typeof params.allowFreeform === "boolean" ? { allowFreeform: params.allowFreeform } : {},
15954
15955
  askedAt: Date.now()
15955
15956
  };
15956
- return new Promise((resolve21, reject) => {
15957
+ return new Promise((resolve22, reject) => {
15957
15958
  this.pendingUserInputs.set(
15958
15959
  this.pendingInteractionKey(sessionId, requestId),
15959
- { value, resolve: resolve21, reject }
15960
+ { value, resolve: resolve22, reject }
15960
15961
  );
15961
15962
  });
15962
15963
  }
@@ -15976,10 +15977,10 @@ var init_copilotTransport = __esm({
15976
15977
  recommendedAction: typeof params.recommendedAction === "string" ? params.recommendedAction : actions[0] ?? "interactive",
15977
15978
  askedAt: Date.now()
15978
15979
  };
15979
- return new Promise((resolve21, reject) => {
15980
+ return new Promise((resolve22, reject) => {
15980
15981
  this.pendingExitPlans.set(
15981
15982
  this.pendingInteractionKey(sessionId, requestId),
15982
- { value, resolve: resolve21, reject }
15983
+ { value, resolve: resolve22, reject }
15983
15984
  );
15984
15985
  });
15985
15986
  }
@@ -16204,17 +16205,17 @@ function parseJsonRecord(line) {
16204
16205
  }
16205
16206
  }
16206
16207
  function parseClaudeUsageLine(line) {
16207
- const record3 = parseJsonRecord(line);
16208
- if (!record3 || record3.type !== "assistant") return null;
16209
- const message = asRecord3(record3.message);
16208
+ const record4 = parseJsonRecord(line);
16209
+ if (!record4 || record4.type !== "assistant") return null;
16210
+ const message = asRecord3(record4.message);
16210
16211
  const usage = message ? asRecord3(message.usage) : null;
16211
16212
  if (!message || !usage) return null;
16212
- const timestampMs = parseTimestampMs(record3.timestamp);
16213
+ const timestampMs = parseTimestampMs(record4.timestamp);
16213
16214
  if (timestampMs === null) return null;
16214
16215
  const model = typeof message.model === "string" ? message.model : "";
16215
16216
  if (model.length === 0) return null;
16216
16217
  const messageId = typeof message.id === "string" ? message.id : null;
16217
- const requestId = typeof record3.requestId === "string" ? record3.requestId : null;
16218
+ const requestId = typeof record4.requestId === "string" ? record4.requestId : null;
16218
16219
  const dedupeKey = messageId === null && requestId === null ? null : `${messageId ?? ""}:${requestId ?? ""}`;
16219
16220
  const cacheCreationTokens = int(usage.cache_creation_input_tokens);
16220
16221
  const byTtl = asRecord3(usage.cache_creation);
@@ -16233,12 +16234,12 @@ function parseClaudeUsageLine(line) {
16233
16234
  reasoningTokens: 0
16234
16235
  };
16235
16236
  if (totalUsageCostTokens(totals) === 0) return null;
16236
- const cost = record3.costUSD;
16237
+ const cost = record4.costUSD;
16237
16238
  return {
16238
16239
  provider: "claude",
16239
16240
  timestampMs,
16240
16241
  model,
16241
- sessionId: typeof record3.sessionId === "string" ? record3.sessionId : "",
16242
+ sessionId: typeof record4.sessionId === "string" ? record4.sessionId : "",
16242
16243
  totals,
16243
16244
  reportedCostUsd: typeof cost === "number" && Number.isFinite(cost) ? cost : null,
16244
16245
  dedupeKey
@@ -16260,30 +16261,30 @@ function isForkedSessionMeta(payload) {
16260
16261
  return typeof spawn5?.parent_thread_id === "string";
16261
16262
  }
16262
16263
  function parseCodexUsageLine(line, state) {
16263
- const record3 = parseJsonRecord(line);
16264
- if (!record3) return null;
16265
- const payload = asRecord3(record3.payload);
16264
+ const record4 = parseJsonRecord(line);
16265
+ if (!record4) return null;
16266
+ const payload = asRecord3(record4.payload);
16266
16267
  if (!payload) return null;
16267
- if (record3.type === "session_meta") {
16268
+ if (record4.type === "session_meta") {
16268
16269
  if (state.sawSessionMeta) return null;
16269
16270
  state.sawSessionMeta = true;
16270
16271
  const id = payload.id ?? payload.session_id;
16271
16272
  if (typeof id === "string") state.sessionId = id;
16272
- const metaTimestampMs = parseTimestampMs(record3.timestamp);
16273
+ const metaTimestampMs = parseTimestampMs(record4.timestamp);
16273
16274
  if (metaTimestampMs !== null && isForkedSessionMeta(payload)) {
16274
16275
  state.suppressingForkCopies = true;
16275
16276
  state.forkCopyAnchorMs = metaTimestampMs;
16276
16277
  }
16277
16278
  return null;
16278
16279
  }
16279
- if (record3.type === "turn_context") {
16280
+ if (record4.type === "turn_context") {
16280
16281
  if (typeof payload.model === "string") state.model = payload.model;
16281
16282
  return null;
16282
16283
  }
16283
16284
  if (payload.type !== "token_count") return null;
16284
16285
  const last = asRecord3(asRecord3(payload.info)?.last_token_usage);
16285
16286
  if (!last) return null;
16286
- const timestampMs = parseTimestampMs(record3.timestamp);
16287
+ const timestampMs = parseTimestampMs(record4.timestamp);
16287
16288
  if (timestampMs === null) return null;
16288
16289
  if (state.model.length === 0) return null;
16289
16290
  const signature = JSON.stringify(last);
@@ -16382,17 +16383,17 @@ function parseCopilotUsageMetrics(value, state, timestampMs) {
16382
16383
  return records;
16383
16384
  }
16384
16385
  function parseCopilotUsageLine(line, state) {
16385
- const record3 = parseJsonRecord(line);
16386
- if (!record3 || typeof record3.agentId === "string" && record3.agentId.length > 0) return [];
16387
- const data = asRecord3(record3.data);
16386
+ const record4 = parseJsonRecord(line);
16387
+ if (!record4 || typeof record4.agentId === "string" && record4.agentId.length > 0) return [];
16388
+ const data = asRecord3(record4.data);
16388
16389
  if (!data) return [];
16389
- if (record3.type === "session.start") {
16390
+ if (record4.type === "session.start") {
16390
16391
  const sessionId = data.sessionId;
16391
16392
  if (typeof sessionId === "string" && sessionId.length > 0) state.sessionId = sessionId;
16392
16393
  return [];
16393
16394
  }
16394
- if (record3.type !== "session.shutdown") return [];
16395
- const timestampMs = parseTimestampMs(record3.timestamp);
16395
+ if (record4.type !== "session.shutdown") return [];
16396
+ const timestampMs = parseTimestampMs(record4.timestamp);
16396
16397
  return timestampMs === null ? [] : parseCopilotUsageMetrics(data, state, timestampMs);
16397
16398
  }
16398
16399
  function createUsageScanner(provider, filePath) {
@@ -16409,8 +16410,8 @@ var init_usageScanners = __esm({
16409
16410
  // object, so a line is either self-contained or of no interest.
16410
16411
  wantsLine: (line) => line.includes('"usage"'),
16411
16412
  accept: (line) => {
16412
- const record3 = parseClaudeUsageLine(line);
16413
- return record3 === null ? [] : [record3];
16413
+ const record4 = parseClaudeUsageLine(line);
16414
+ return record4 === null ? [] : [record4];
16414
16415
  }
16415
16416
  }),
16416
16417
  codex: () => {
@@ -16421,8 +16422,8 @@ var init_usageScanners = __esm({
16421
16422
  // at all but still have to reach the reducer.
16422
16423
  wantsLine: (line) => line.includes('"token_count"') || line.includes('"turn_context"') || line.includes('"session_meta"'),
16423
16424
  accept: (line) => {
16424
- const record3 = parseCodexUsageLine(line, state);
16425
- return record3 === null ? [] : [record3];
16425
+ const record4 = parseCodexUsageLine(line, state);
16426
+ return record4 === null ? [] : [record4];
16426
16427
  }
16427
16428
  };
16428
16429
  },
@@ -16668,7 +16669,7 @@ var init_copilotRuntime = __esm({
16668
16669
  initialContent = await readFile9(filePath, "utf-8");
16669
16670
  break;
16670
16671
  } catch {
16671
- await new Promise((resolve21) => setTimeout(resolve21, TRANSCRIPT_POLL_INTERVAL_MS2));
16672
+ await new Promise((resolve22) => setTimeout(resolve22, TRANSCRIPT_POLL_INTERVAL_MS2));
16672
16673
  }
16673
16674
  }
16674
16675
  return { sessionId, dirName: req.dirName, fileName, filePath, initialContent };
@@ -17671,12 +17672,12 @@ function registerBranchSessionRoute(use) {
17671
17672
  }
17672
17673
  }
17673
17674
  const newSessionId = randomUUID2();
17674
- const { record: record3, originalId } = format.brandBranch(
17675
+ const { record: record4, originalId } = format.brandBranch(
17675
17676
  JSON.parse(lines[0]),
17676
17677
  newSessionId,
17677
17678
  turnIndex ?? null
17678
17679
  );
17679
- lines[0] = JSON.stringify(record3);
17680
+ lines[0] = JSON.stringify(record4);
17680
17681
  const target = storeForDirName(dirName).transcriptPath(dirName, newSessionId);
17681
17682
  if (!target) {
17682
17683
  res.statusCode = 500;
@@ -19843,21 +19844,21 @@ function toPublic(device) {
19843
19844
  return rest;
19844
19845
  }
19845
19846
  function readJsonBody2(req) {
19846
- return new Promise((resolve21) => {
19847
+ return new Promise((resolve22) => {
19847
19848
  let raw = "";
19848
19849
  req.on("data", (chunk) => {
19849
19850
  raw += chunk.toString();
19850
19851
  });
19851
19852
  req.on("end", () => {
19852
- if (!raw.trim()) return resolve21({});
19853
+ if (!raw.trim()) return resolve22({});
19853
19854
  try {
19854
19855
  const parsed = JSON.parse(raw);
19855
- resolve21(parsed && typeof parsed === "object" ? parsed : null);
19856
+ resolve22(parsed && typeof parsed === "object" ? parsed : null);
19856
19857
  } catch {
19857
- resolve21(null);
19858
+ resolve22(null);
19858
19859
  }
19859
19860
  });
19860
- req.on("error", () => resolve21(null));
19861
+ req.on("error", () => resolve22(null));
19861
19862
  });
19862
19863
  }
19863
19864
  function handleList(res) {
@@ -20245,9 +20246,9 @@ function terminalCommand(terminal, dirPath) {
20245
20246
  return { cmd: terminal, args: ["--working-directory", dirPath] };
20246
20247
  }
20247
20248
  function whichEditor(name) {
20248
- return new Promise((resolve21) => {
20249
+ return new Promise((resolve22) => {
20249
20250
  const cmd = platform() === "win32" ? "where" : "which";
20250
- execFile(cmd, [name], (err) => resolve21(err ? null : name));
20251
+ execFile(cmd, [name], (err) => resolve22(err ? null : name));
20251
20252
  });
20252
20253
  }
20253
20254
  async function resolveEditor(configuredEditor) {
@@ -20261,10 +20262,10 @@ async function resolveEditor(configuredEditor) {
20261
20262
  return null;
20262
20263
  }
20263
20264
  function openWithEditor(editor, args) {
20264
- return new Promise((resolve21, reject) => {
20265
+ return new Promise((resolve22, reject) => {
20265
20266
  execFile(editor, args, (err) => {
20266
20267
  if (err) reject(err);
20267
- else resolve21();
20268
+ else resolve22();
20268
20269
  });
20269
20270
  });
20270
20271
  }
@@ -20277,14 +20278,14 @@ function editorOpenArgs(editor, filePath, line, column) {
20277
20278
  return [filePath];
20278
20279
  }
20279
20280
  function getGitHeadContent(filePath) {
20280
- return new Promise((resolve21, reject) => {
20281
+ return new Promise((resolve22, reject) => {
20281
20282
  execFile(
20282
20283
  "git",
20283
20284
  ["-C", dirname7(filePath), "show", `HEAD:./${basename7(filePath)}`],
20284
20285
  { maxBuffer: 10 * 1024 * 1024 },
20285
20286
  (err, stdout) => {
20286
20287
  if (err) reject(err);
20287
- else resolve21(stdout);
20288
+ else resolve22(stdout);
20288
20289
  }
20289
20290
  );
20290
20291
  });
@@ -20960,23 +20961,23 @@ function registerFileRoutes(use) {
20960
20961
  req.on("end", async () => {
20961
20962
  try {
20962
20963
  let spawnLines = function(args, cwd) {
20963
- return new Promise((resolve21) => {
20964
+ return new Promise((resolve22) => {
20964
20965
  const proc = spawn2("git", args, { cwd });
20965
20966
  let out = "";
20966
20967
  proc.stdout.on("data", (d) => out += d.toString());
20967
20968
  proc.on("close", (code) => {
20968
- if (code !== 0 || !out) return resolve21(0);
20969
- resolve21(out.split("\n").length);
20969
+ if (code !== 0 || !out) return resolve22(0);
20970
+ resolve22(out.split("\n").length);
20970
20971
  });
20971
- proc.on("error", () => resolve21(0));
20972
+ proc.on("error", () => resolve22(0));
20972
20973
  });
20973
20974
  }, spawnOutput = function(args, cwd) {
20974
- return new Promise((resolve21) => {
20975
+ return new Promise((resolve22) => {
20975
20976
  const proc = spawn2("git", args, { cwd });
20976
20977
  let out = "";
20977
20978
  proc.stdout.on("data", (d) => out += d.toString());
20978
- proc.on("close", () => resolve21(out.trim()));
20979
- proc.on("error", () => resolve21(""));
20979
+ proc.on("close", () => resolve22(out.trim()));
20980
+ proc.on("error", () => resolve22(""));
20980
20981
  });
20981
20982
  };
20982
20983
  const { files, dirs: dirs2 } = JSON.parse(body);
@@ -21000,18 +21001,18 @@ function registerFileRoutes(use) {
21000
21001
  cwd = cwd.substring(0, cwd.lastIndexOf("/")) || "/";
21001
21002
  }
21002
21003
  }
21003
- return new Promise((resolve21) => {
21004
+ return new Promise((resolve22) => {
21004
21005
  const proc = spawn2("git", ["rev-parse", "--show-toplevel"], { cwd });
21005
21006
  let out = "";
21006
21007
  proc.stdout.on("data", (d) => out += d.toString());
21007
21008
  proc.on("close", (code) => {
21008
21009
  const root = code === 0 ? out.trim() : null;
21009
21010
  gitRootCache.set(dir, root);
21010
- resolve21(root);
21011
+ resolve22(root);
21011
21012
  });
21012
21013
  proc.on("error", () => {
21013
21014
  gitRootCache.set(dir, null);
21014
- resolve21(null);
21015
+ resolve22(null);
21015
21016
  });
21016
21017
  });
21017
21018
  }
@@ -21246,11 +21247,11 @@ function parseGitStatus(output) {
21246
21247
  const branch = parseBranchHeader(header);
21247
21248
  const files = [];
21248
21249
  for (let index = 0; index < records.length; index += 1) {
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);
21250
+ const record4 = records[index];
21251
+ if (!record4 || record4.length < 3) continue;
21252
+ const indexStatus = record4[0];
21253
+ const workTreeStatus = record4[1];
21254
+ const path = record4.slice(3);
21254
21255
  const renamedOrCopied = /[RC]/.test(`${indexStatus}${workTreeStatus}`);
21255
21256
  const originalPath = renamedOrCopied ? records[index += 1] || void 0 : void 0;
21256
21257
  files.push({ path, originalPath, indexStatus, workTreeStatus });
@@ -21571,14 +21572,364 @@ var init_github_actions = __esm({
21571
21572
  }
21572
21573
  });
21573
21574
 
21575
+ // ../../server/routes/vercel-deployments.ts
21576
+ import { execFile as execFileCallback3 } from "node:child_process";
21577
+ import { readFile as readFile15, realpath as realpath8, stat as stat13 } from "node:fs/promises";
21578
+ import { isAbsolute as isAbsolute8, join as join20, resolve as resolve15 } from "node:path";
21579
+ import { promisify as promisify3 } from "node:util";
21580
+ function record3(value) {
21581
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
21582
+ }
21583
+ function stringValue2(value, fallback = "") {
21584
+ return typeof value === "string" ? value : fallback;
21585
+ }
21586
+ function nullableString(value) {
21587
+ return typeof value === "string" && value ? value : null;
21588
+ }
21589
+ function timestamp(value) {
21590
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
21591
+ }
21592
+ function firstString2(source, keys) {
21593
+ if (!source) return "";
21594
+ for (const key2 of keys) {
21595
+ const value = stringValue2(source[key2]);
21596
+ if (value) return value;
21597
+ }
21598
+ return "";
21599
+ }
21600
+ function deploymentState(value) {
21601
+ return typeof value === "string" && DEPLOYMENT_STATES.has(value) ? value : "QUEUED";
21602
+ }
21603
+ function httpsUrl(value, hostnameOnly = false) {
21604
+ const text = stringValue2(value);
21605
+ if (!text) return null;
21606
+ const candidate = hostnameOnly && !text.includes("://") ? `https://${text}` : text;
21607
+ try {
21608
+ const url = new URL(candidate);
21609
+ return url.protocol === "https:" ? url.toString().replace(/\/$/, "") : null;
21610
+ } catch {
21611
+ return null;
21612
+ }
21613
+ }
21614
+ function projectUrlFromInspector(value) {
21615
+ if (!value) return null;
21616
+ try {
21617
+ const url = new URL(value);
21618
+ const parts = url.pathname.split("/").filter(Boolean);
21619
+ if (parts.length < 3) return null;
21620
+ url.pathname = `/${parts.slice(0, -1).join("/")}`;
21621
+ url.search = "";
21622
+ url.hash = "";
21623
+ return url.toString().replace(/\/$/, "");
21624
+ } catch {
21625
+ return null;
21626
+ }
21627
+ }
21628
+ function parseDeployment(value) {
21629
+ const source = record3(value);
21630
+ if (!source) return null;
21631
+ const id = stringValue2(source.uid);
21632
+ const createdAt = timestamp(source.createdAt) ?? timestamp(source.created);
21633
+ if (!DEPLOYMENT_ID.test(id) || createdAt === null) return null;
21634
+ const meta = record3(source.meta);
21635
+ const creator = record3(source.creator);
21636
+ return {
21637
+ id,
21638
+ name: stringValue2(source.name, "Deployment"),
21639
+ url: httpsUrl(source.url, true),
21640
+ inspectorUrl: httpsUrl(source.inspectorUrl),
21641
+ state: deploymentState(source.readyState ?? source.state),
21642
+ target: nullableString(source.target),
21643
+ createdAt,
21644
+ buildingAt: timestamp(source.buildingAt),
21645
+ readyAt: timestamp(source.ready),
21646
+ branch: firstString2(meta, [
21647
+ "githubCommitRef",
21648
+ "gitlabCommitRef",
21649
+ "bitbucketCommitRef",
21650
+ "branchAlias"
21651
+ ]),
21652
+ commitSha: firstString2(meta, [
21653
+ "githubCommitSha",
21654
+ "gitlabCommitSha",
21655
+ "bitbucketCommitSha"
21656
+ ]),
21657
+ commitMessage: firstString2(meta, [
21658
+ "githubCommitMessage",
21659
+ "gitlabCommitMessage",
21660
+ "bitbucketCommitMessage"
21661
+ ]),
21662
+ creator: firstString2(creator, ["username", "githubLogin", "email"]),
21663
+ errorCode: nullableString(source.errorCode),
21664
+ errorMessage: nullableString(source.errorMessage)
21665
+ };
21666
+ }
21667
+ function parseDeploymentsResponse(value) {
21668
+ const source = record3(value);
21669
+ if (!source || !Array.isArray(source.deployments)) {
21670
+ throw new VercelDeploymentsRouteError(
21671
+ 502,
21672
+ "invalid_response",
21673
+ "Vercel returned an invalid deployments response"
21674
+ );
21675
+ }
21676
+ return source.deployments.map(parseDeployment).filter((deployment) => deployment !== null);
21677
+ }
21678
+ function parseBuildLog(value) {
21679
+ const source = record3(value);
21680
+ if (!source) return null;
21681
+ const createdAt = timestamp(source.created) ?? timestamp(source.date);
21682
+ const text = stringValue2(source.text);
21683
+ if (createdAt === null || !text) return null;
21684
+ return {
21685
+ id: stringValue2(source.id, `${createdAt}-${text}`),
21686
+ createdAt,
21687
+ type: stringValue2(source.type, "stdout"),
21688
+ text
21689
+ };
21690
+ }
21691
+ function parseBuildLogsResponse(value) {
21692
+ if (!Array.isArray(value)) {
21693
+ throw new VercelDeploymentsRouteError(
21694
+ 502,
21695
+ "invalid_response",
21696
+ "Vercel returned an invalid build log response"
21697
+ );
21698
+ }
21699
+ return value.map(parseBuildLog).filter((event) => event !== null).sort((left, right) => left.createdAt - right.createdAt);
21700
+ }
21701
+ function parseProjectFile(value, root) {
21702
+ const source = record3(value);
21703
+ const projectId = stringValue2(source?.projectId);
21704
+ const teamId = stringValue2(source?.orgId);
21705
+ const projectName = stringValue2(source?.projectName, "Vercel project");
21706
+ if (!VERCEL_ID.test(projectId) || !VERCEL_ID.test(teamId)) {
21707
+ throw new VercelDeploymentsRouteError(
21708
+ 400,
21709
+ "vercel_project_unlinked",
21710
+ "This project has an invalid .vercel/project.json link"
21711
+ );
21712
+ }
21713
+ return { root, projectId, projectName, teamId };
21714
+ }
21715
+ async function resolveLinkedVercelProject(cwd) {
21716
+ if (!isAbsolute8(cwd)) {
21717
+ throw new VercelDeploymentsRouteError(400, "vercel_project_unlinked", "cwd must be an absolute path");
21718
+ }
21719
+ let root;
21720
+ try {
21721
+ root = await realpath8(resolve15(cwd));
21722
+ if (!(await stat13(root)).isDirectory()) throw new Error("not a directory");
21723
+ } catch {
21724
+ throw new VercelDeploymentsRouteError(404, "vercel_project_unlinked", "Project directory not found");
21725
+ }
21726
+ const projectFile = join20(root, ".vercel", "project.json");
21727
+ try {
21728
+ const info = await stat13(projectFile);
21729
+ if (!info.isFile() || info.size > MAX_PROJECT_FILE_BYTES) throw new Error("invalid project file");
21730
+ return parseProjectFile(JSON.parse(await readFile15(projectFile, "utf8")), root);
21731
+ } catch (error) {
21732
+ if (error instanceof VercelDeploymentsRouteError) throw error;
21733
+ const detail = error;
21734
+ if (detail.code === "ENOENT") {
21735
+ throw new VercelDeploymentsRouteError(
21736
+ 400,
21737
+ "vercel_project_unlinked",
21738
+ "Link this project with `vercel link` before viewing deployments"
21739
+ );
21740
+ }
21741
+ throw new VercelDeploymentsRouteError(
21742
+ 400,
21743
+ "vercel_project_unlinked",
21744
+ "Unable to read this project's .vercel/project.json link"
21745
+ );
21746
+ }
21747
+ }
21748
+ async function executeVercel(cwd, args) {
21749
+ const cli = resolveAgentCommand("vercel", args);
21750
+ const result = await execFile4(cli.command, cli.args, {
21751
+ cwd,
21752
+ encoding: "utf-8",
21753
+ env: {
21754
+ ...process.env,
21755
+ NO_COLOR: "1",
21756
+ VERCEL_TELEMETRY_DISABLED: "1"
21757
+ },
21758
+ maxBuffer: 16 * 1024 * 1024,
21759
+ timeout: 3e4,
21760
+ windowsHide: true,
21761
+ ...cli.spawnOptions
21762
+ });
21763
+ return { stdout: result.stdout, stderr: result.stderr };
21764
+ }
21765
+ function parseCliVersion(output) {
21766
+ const match = output.match(/(?:^|\s)(\d+)\.(\d+)\.(\d+)(?:\s|$)/);
21767
+ return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
21768
+ }
21769
+ function isVersionAtLeast(actual, minimum) {
21770
+ for (let index = 0; index < minimum.length; index += 1) {
21771
+ if (actual[index] > minimum[index]) return true;
21772
+ if (actual[index] < minimum[index]) return false;
21773
+ }
21774
+ return true;
21775
+ }
21776
+ function mapVercelFailure(error) {
21777
+ if (error instanceof VercelDeploymentsRouteError) return error;
21778
+ const failure = error;
21779
+ if (failure.code === "ENOENT") {
21780
+ return new VercelDeploymentsRouteError(503, "vercel_missing", "Install Vercel CLI to view deployments");
21781
+ }
21782
+ const detail = `${failure.message ?? ""}
21783
+ ${failure.stderr ?? ""}
21784
+ ${failure.stdout ?? ""}`;
21785
+ if (/not authenticated|not logged|log in|login|authentication|invalid token|unauthorized|401/i.test(detail)) {
21786
+ return new VercelDeploymentsRouteError(
21787
+ 503,
21788
+ "vercel_auth_required",
21789
+ "Sign in with `vercel login` to view deployments"
21790
+ );
21791
+ }
21792
+ if (/forbidden|access denied|not authorized|permission|403/i.test(detail)) {
21793
+ return new VercelDeploymentsRouteError(
21794
+ 403,
21795
+ "vercel_access_denied",
21796
+ "Your Vercel account cannot access this linked project"
21797
+ );
21798
+ }
21799
+ return new VercelDeploymentsRouteError(502, "vercel_api_failed", "Vercel deployment data is unavailable");
21800
+ }
21801
+ async function runVercelApi(project, endpoint, runCommand = executeVercel) {
21802
+ try {
21803
+ const versionResult = await runCommand(project.root, ["--version"]);
21804
+ const version = parseCliVersion(`${versionResult.stdout}
21805
+ ${versionResult.stderr}`);
21806
+ if (!version || !isVersionAtLeast(version, MINIMUM_API_CLI_VERSION)) {
21807
+ throw new VercelDeploymentsRouteError(
21808
+ 503,
21809
+ "vercel_cli_too_old",
21810
+ "Update Vercel CLI to version 50.5.1 or newer to view deployments safely"
21811
+ );
21812
+ }
21813
+ const result = await runCommand(project.root, [
21814
+ "api",
21815
+ endpoint,
21816
+ "--raw",
21817
+ "--cwd",
21818
+ project.root,
21819
+ "--non-interactive",
21820
+ "--no-color"
21821
+ ]);
21822
+ try {
21823
+ return JSON.parse(result.stdout);
21824
+ } catch {
21825
+ throw new VercelDeploymentsRouteError(
21826
+ 502,
21827
+ "invalid_response",
21828
+ "Vercel returned invalid JSON"
21829
+ );
21830
+ }
21831
+ } catch (error) {
21832
+ throw mapVercelFailure(error);
21833
+ }
21834
+ }
21835
+ function boundedLimit(value, fallback, maximum) {
21836
+ const requested = Number(value ?? fallback);
21837
+ return Number.isInteger(requested) ? Math.min(maximum, Math.max(1, requested)) : fallback;
21838
+ }
21839
+ function sendRouteError3(res, error) {
21840
+ const detail = mapVercelFailure(error);
21841
+ sendJson(res, detail.status, { error: detail.message, code: detail.code });
21842
+ }
21843
+ function registerVercelDeploymentRoutes(use, dependencies = defaultDependencies2) {
21844
+ use("/api/vercel-deployments", async (req, res, next) => {
21845
+ if (req.method !== "GET") return next();
21846
+ const url = new URL(req.url || "", "http://localhost");
21847
+ if (url.pathname !== "/" && url.pathname !== "") return next();
21848
+ const limit = boundedLimit(url.searchParams.get("limit"), DEFAULT_DEPLOYMENT_LIMIT, MAX_DEPLOYMENT_LIMIT);
21849
+ try {
21850
+ const project = await dependencies.resolveProject(url.searchParams.get("cwd") ?? "");
21851
+ const endpoint = `/v7/deployments?projectId=${encodeURIComponent(project.projectId)}&teamId=${encodeURIComponent(project.teamId)}&limit=${limit}`;
21852
+ const deployments = parseDeploymentsResponse(await dependencies.vercelApi(project, endpoint));
21853
+ const response = {
21854
+ projectId: project.projectId,
21855
+ projectName: project.projectName,
21856
+ teamId: project.teamId,
21857
+ projectUrl: projectUrlFromInspector(deployments[0]?.inspectorUrl ?? null),
21858
+ deployments
21859
+ };
21860
+ sendJson(res, 200, response);
21861
+ } catch (error) {
21862
+ sendRouteError3(res, error);
21863
+ }
21864
+ });
21865
+ use("/api/vercel-deployments/build-logs", async (req, res, next) => {
21866
+ if (req.method !== "GET") return next();
21867
+ const url = new URL(req.url || "", "http://localhost");
21868
+ if (url.pathname !== "/" && url.pathname !== "") return next();
21869
+ const deploymentId = url.searchParams.get("deploymentId") ?? "";
21870
+ if (!DEPLOYMENT_ID.test(deploymentId)) {
21871
+ return sendJson(res, 400, {
21872
+ error: "deploymentId must be a Vercel deployment ID",
21873
+ code: "vercel_api_failed"
21874
+ });
21875
+ }
21876
+ const limit = boundedLimit(url.searchParams.get("limit"), DEFAULT_LOG_LIMIT, MAX_LOG_LIMIT);
21877
+ try {
21878
+ const project = await dependencies.resolveProject(url.searchParams.get("cwd") ?? "");
21879
+ const endpoint = `/v3/deployments/${deploymentId}/events?teamId=${encodeURIComponent(project.teamId)}&direction=backward&limit=${limit}`;
21880
+ const events = parseBuildLogsResponse(await dependencies.vercelApi(project, endpoint));
21881
+ const response = { deploymentId, events };
21882
+ sendJson(res, 200, response);
21883
+ } catch (error) {
21884
+ sendRouteError3(res, error);
21885
+ }
21886
+ });
21887
+ }
21888
+ var execFile4, DEFAULT_DEPLOYMENT_LIMIT, MAX_DEPLOYMENT_LIMIT, DEFAULT_LOG_LIMIT, MAX_LOG_LIMIT, MAX_PROJECT_FILE_BYTES, MINIMUM_API_CLI_VERSION, VERCEL_ID, DEPLOYMENT_ID, DEPLOYMENT_STATES, VercelDeploymentsRouteError, defaultDependencies2;
21889
+ var init_vercel_deployments = __esm({
21890
+ "../../server/routes/vercel-deployments.ts"() {
21891
+ init_http();
21892
+ init_binaryResolver();
21893
+ execFile4 = promisify3(execFileCallback3);
21894
+ DEFAULT_DEPLOYMENT_LIMIT = 20;
21895
+ MAX_DEPLOYMENT_LIMIT = 30;
21896
+ DEFAULT_LOG_LIMIT = 200;
21897
+ MAX_LOG_LIMIT = 500;
21898
+ MAX_PROJECT_FILE_BYTES = 64 * 1024;
21899
+ MINIMUM_API_CLI_VERSION = [50, 5, 1];
21900
+ VERCEL_ID = /^[A-Za-z0-9_-]+$/;
21901
+ DEPLOYMENT_ID = /^dpl_[A-Za-z0-9]+$/;
21902
+ DEPLOYMENT_STATES = /* @__PURE__ */ new Set([
21903
+ "BLOCKED",
21904
+ "BUILDING",
21905
+ "CANCELED",
21906
+ "ERROR",
21907
+ "INITIALIZING",
21908
+ "QUEUED",
21909
+ "READY"
21910
+ ]);
21911
+ VercelDeploymentsRouteError = class extends Error {
21912
+ constructor(status, code, message) {
21913
+ super(message);
21914
+ this.status = status;
21915
+ this.code = code;
21916
+ }
21917
+ };
21918
+ defaultDependencies2 = {
21919
+ resolveProject: resolveLinkedVercelProject,
21920
+ vercelApi: runVercelApi
21921
+ };
21922
+ }
21923
+ });
21924
+
21574
21925
  // ../../server/lib/projectIcon.ts
21575
- import { realpath as realpath8, stat as stat13 } from "node:fs/promises";
21576
- import { basename as basename9, extname, join as join20, relative as relative8, sep as sep10 } from "node:path";
21926
+ import { realpath as realpath9, stat as stat14 } from "node:fs/promises";
21927
+ import { basename as basename9, extname, join as join21, relative as relative8, sep as sep10 } from "node:path";
21577
21928
  function namedIconCandidates(root) {
21578
21929
  const name = basename9(root);
21579
21930
  if (!name || name.startsWith(".")) return [];
21580
21931
  return ["public", "assets", "static", "."].flatMap(
21581
- (dir) => NAMED_ICON_EXTENSIONS.map((ext) => join20(dir, `${name}${ext}`))
21932
+ (dir) => NAMED_ICON_EXTENSIONS.map((ext) => join21(dir, `${name}${ext}`))
21582
21933
  );
21583
21934
  }
21584
21935
  function iconContentType(path) {
@@ -21591,7 +21942,7 @@ function isInside(root, candidate) {
21591
21942
  async function resolveProjectIcon(projectPath) {
21592
21943
  let root;
21593
21944
  try {
21594
- root = await realpath8(projectPath);
21945
+ root = await realpath9(projectPath);
21595
21946
  } catch {
21596
21947
  return null;
21597
21948
  }
@@ -21601,11 +21952,11 @@ async function resolveProjectIcon(projectPath) {
21601
21952
  ...PROJECT_ICON_CANDIDATES.slice(6)
21602
21953
  ];
21603
21954
  for (const candidate of candidates) {
21604
- const guess = join20(root, candidate);
21955
+ const guess = join21(root, candidate);
21605
21956
  try {
21606
- const resolved = await realpath8(guess);
21957
+ const resolved = await realpath9(guess);
21607
21958
  if (!isInside(root, resolved)) continue;
21608
- const info = await stat13(resolved);
21959
+ const info = await stat14(resolved);
21609
21960
  if (!info.isFile() || info.size === 0 || info.size > MAX_ICON_BYTES) continue;
21610
21961
  if (!iconContentType(resolved)) continue;
21611
21962
  return resolved;
@@ -21663,13 +22014,13 @@ var init_projectIcon = __esm({
21663
22014
 
21664
22015
  // ../../server/routes/project-icon.ts
21665
22016
  import { createReadStream } from "node:fs";
21666
- import { isAbsolute as isAbsolute8 } from "node:path";
22017
+ import { isAbsolute as isAbsolute9 } from "node:path";
21667
22018
  function registerProjectIconRoutes(use) {
21668
22019
  use("/api/project-icon", async (req, res, next) => {
21669
22020
  if (req.method !== "GET") return next();
21670
22021
  const url = new URL(req.url || "", "http://localhost");
21671
22022
  const cwd = url.searchParams.get("cwd") ?? "";
21672
- if (!isAbsolute8(cwd)) {
22023
+ if (!isAbsolute9(cwd)) {
21673
22024
  return sendJson(res, 400, { error: "cwd must be an absolute path" });
21674
22025
  }
21675
22026
  const icon = await resolveProjectIcon(cwd);
@@ -21754,14 +22105,14 @@ var init_local_file = __esm({
21754
22105
  });
21755
22106
 
21756
22107
  // ../../server/routes/mcp.ts
21757
- import { execFile as execFile4 } from "node:child_process";
21758
- import { isAbsolute as isAbsolute9, join as join21 } from "node:path";
21759
- import { readFile as readFile15 } from "node:fs/promises";
22108
+ import { execFile as execFile5 } from "node:child_process";
22109
+ import { isAbsolute as isAbsolute10, join as join22 } from "node:path";
22110
+ import { readFile as readFile16 } from "node:fs/promises";
21760
22111
  import { homedir as homedir7 } from "node:os";
21761
22112
  async function readMcpConfigs(cwd) {
21762
22113
  const configs = {};
21763
22114
  try {
21764
- const raw = await readFile15(join21(homedir7(), ".claude.json"), "utf-8");
22115
+ const raw = await readFile16(join22(homedir7(), ".claude.json"), "utf-8");
21765
22116
  const parsed = JSON.parse(raw);
21766
22117
  if (parsed.mcpServers && typeof parsed.mcpServers === "object") {
21767
22118
  Object.assign(configs, parsed.mcpServers);
@@ -21779,16 +22130,16 @@ async function readMcpConfigs(cwd) {
21779
22130
  } catch {
21780
22131
  }
21781
22132
  const otherSources = [
21782
- join21(homedir7(), ".claude", "settings.json"),
22133
+ join22(homedir7(), ".claude", "settings.json"),
21783
22134
  // global settings
21784
- join21(cwd, ".mcp.json"),
22135
+ join22(cwd, ".mcp.json"),
21785
22136
  // project
21786
- join21(cwd, ".claude", "settings.local.json")
22137
+ join22(cwd, ".claude", "settings.local.json")
21787
22138
  // project local
21788
22139
  ];
21789
22140
  for (const path of otherSources) {
21790
22141
  try {
21791
- const raw = await readFile15(path, "utf-8");
22142
+ const raw = await readFile16(path, "utf-8");
21792
22143
  const parsed = JSON.parse(raw);
21793
22144
  if (parsed.mcpServers && typeof parsed.mcpServers === "object") {
21794
22145
  Object.assign(configs, parsed.mcpServers);
@@ -21831,18 +22182,18 @@ async function getMcpServers(cwd) {
21831
22182
  return { servers: cached.servers, configs: cached.configs };
21832
22183
  }
21833
22184
  const configs = await readMcpConfigs(cwd);
21834
- return new Promise((resolve21) => {
22185
+ return new Promise((resolve22) => {
21835
22186
  const env = { ...process.env };
21836
22187
  delete env.CLAUDECODE;
21837
22188
  const cli = resolveAgentCommand("claude", ["mcp", "list"]);
21838
- execFile4(cli.command, cli.args, { cwd, env, timeout: 15e3, ...cli.spawnOptions }, (err, stdout) => {
22189
+ execFile5(cli.command, cli.args, { cwd, env, timeout: 15e3, ...cli.spawnOptions }, (err, stdout) => {
21839
22190
  if (err) {
21840
- resolve21({ servers: cached?.servers ?? [], configs });
22191
+ resolve22({ servers: cached?.servers ?? [], configs });
21841
22192
  return;
21842
22193
  }
21843
22194
  const servers = parseMcpListOutput(stdout);
21844
22195
  cache.set(cwd, { servers, configs, timestamp: Date.now() });
21845
- resolve21({ servers, configs });
22196
+ resolve22({ servers, configs });
21846
22197
  });
21847
22198
  });
21848
22199
  }
@@ -21852,7 +22203,7 @@ function registerMcpRoutes(use) {
21852
22203
  const url = new URL(req.url || "", `http://${req.headers.host}`);
21853
22204
  const cwd = url.searchParams.get("cwd");
21854
22205
  const refresh = url.searchParams.get("refresh") === "1";
21855
- if (!cwd || !isAbsolute9(cwd)) {
22206
+ if (!cwd || !isAbsolute10(cwd)) {
21856
22207
  return sendJson(res, 400, { error: "cwd must be an absolute path" });
21857
22208
  }
21858
22209
  if (refresh) clearMcpCache(cwd);
@@ -21964,7 +22315,7 @@ var init_diff_utils = __esm({
21964
22315
  function isObject9(value) {
21965
22316
  return typeof value === "object" && value !== null;
21966
22317
  }
21967
- function firstString2(...values) {
22318
+ function firstString3(...values) {
21968
22319
  return values.find((value) => typeof value === "string") ?? "";
21969
22320
  }
21970
22321
  function truncate(value, length = 140) {
@@ -22211,19 +22562,19 @@ function nativeWebPresentation(input) {
22211
22562
  if (type === "open_page" || type === "openPage") {
22212
22563
  return {
22213
22564
  label: "Open page",
22214
- summary: firstString2(action?.url, input.query),
22565
+ summary: firstString3(action?.url, input.query),
22215
22566
  styleName: "WebSearch"
22216
22567
  };
22217
22568
  }
22218
22569
  if (type === "find_in_page" || type === "findInPage") {
22219
22570
  return {
22220
22571
  label: "Find on page",
22221
- summary: [firstString2(action?.pattern), firstString2(action?.url)].filter(Boolean).join(" \xB7 "),
22572
+ summary: [firstString3(action?.pattern), firstString3(action?.url)].filter(Boolean).join(" \xB7 "),
22222
22573
  styleName: "WebSearch"
22223
22574
  };
22224
22575
  }
22225
22576
  const queries = Array.isArray(action?.queries) ? action.queries.filter((query5) => typeof query5 === "string") : [];
22226
- const query4 = firstString2(action?.query, input.query);
22577
+ const query4 = firstString3(action?.query, input.query);
22227
22578
  return {
22228
22579
  label: "Search web",
22229
22580
  summary: compactValues([query4, ...queries]),
@@ -22231,7 +22582,7 @@ function nativeWebPresentation(input) {
22231
22582
  };
22232
22583
  }
22233
22584
  function schemaFreeSummary(input) {
22234
- const gist = firstString2(...SCHEMA_FREE_GIST_KEYS.map((key2) => input[key2]));
22585
+ const gist = firstString3(...SCHEMA_FREE_GIST_KEYS.map((key2) => input[key2]));
22235
22586
  if (gist) return truncate(gist);
22236
22587
  for (const [key2, value] of Object.entries(input)) {
22237
22588
  if (!Array.isArray(value)) continue;
@@ -22241,11 +22592,11 @@ function schemaFreeSummary(input) {
22241
22592
  return "";
22242
22593
  }
22243
22594
  function workflowSummary(input) {
22244
- const description = firstString2(input.description);
22595
+ const description = firstString3(input.description);
22245
22596
  if (description) return truncate(description);
22246
- const script = firstString2(input.script);
22597
+ const script = firstString3(input.script);
22247
22598
  const metaName = script ? extractJsStringPropertyValues(script, "name")[0] ?? "" : "";
22248
- return metaName || firstString2(input.scriptPath);
22599
+ return metaName || firstString3(input.scriptPath);
22249
22600
  }
22250
22601
  function firstStringValue(input) {
22251
22602
  const keys = Object.keys(input);
@@ -22322,19 +22673,19 @@ function defaultToolSummary(tc) {
22322
22673
  case "ToolSearch":
22323
22674
  return String(input.query ?? "");
22324
22675
  case "SendMessage": {
22325
- const recipient = firstString2(input.to, input.recipient);
22326
- const gist = truncate(firstString2(input.summary, input.message, input.content));
22676
+ const recipient = firstString3(input.to, input.recipient);
22677
+ const gist = truncate(firstString3(input.summary, input.message, input.content));
22327
22678
  return [recipient, gist].filter(Boolean).join(" \xB7 ");
22328
22679
  }
22329
22680
  case "ListAgents":
22330
22681
  case "TaskList":
22331
22682
  return "";
22332
22683
  case "TaskCreate":
22333
- return truncate(firstString2(input.subject, input.description));
22684
+ return truncate(firstString3(input.subject, input.description));
22334
22685
  case "TaskUpdate": {
22335
22686
  const taskId = String(input.taskId ?? "");
22336
22687
  const blockers = Array.isArray(input.addBlockedBy) ? input.addBlockedBy.filter((id) => typeof id === "string") : [];
22337
- const change = firstString2(input.status) || (blockers.length > 0 ? `blocked by ${blockers.join(", ")}` : "");
22688
+ const change = firstString3(input.status) || (blockers.length > 0 ? `blocked by ${blockers.join(", ")}` : "");
22338
22689
  return change ? `${taskId} \u2192 ${change}` : taskId;
22339
22690
  }
22340
22691
  case "TaskOutput":
@@ -22634,8 +22985,8 @@ function copilotText(value) {
22634
22985
  if (!Array.isArray(value)) return "";
22635
22986
  return value.flatMap((part) => {
22636
22987
  if (typeof part === "string") return part ? [part] : [];
22637
- const record3 = asRecord5(part);
22638
- const text = str(record3.text) || str(record3.content);
22988
+ const record4 = asRecord5(part);
22989
+ const text = str(record4.text) || str(record4.content);
22639
22990
  return text ? [text] : [];
22640
22991
  }).join("\n");
22641
22992
  }
@@ -22967,7 +23318,7 @@ var init_summaryFolds = __esm({
22967
23318
  });
22968
23319
 
22969
23320
  // ../../server/lib/missionControlSummary.ts
22970
- import { open as open7, stat as stat14 } from "node:fs/promises";
23321
+ import { open as open7, stat as stat15 } from "node:fs/promises";
22971
23322
  function foldLine(acc, line) {
22972
23323
  const trimmed = line.trim();
22973
23324
  if (!trimmed) return;
@@ -22977,10 +23328,10 @@ function foldLine(acc, line) {
22977
23328
  } catch {
22978
23329
  return;
22979
23330
  }
22980
- const timestamp = str(entry.timestamp);
22981
- if (timestamp) {
22982
- acc.startedAt ??= timestamp;
22983
- acc.lastEventAt = timestamp;
23331
+ const timestamp2 = str(entry.timestamp);
23332
+ if (timestamp2) {
23333
+ acc.startedAt ??= timestamp2;
23334
+ acc.lastEventAt = timestamp2;
22984
23335
  }
22985
23336
  foldSummaryEntry(acc, entry);
22986
23337
  }
@@ -23042,7 +23393,7 @@ async function readSince(filePath, from, to) {
23042
23393
  async function summarizeSession(sessionId, filePath) {
23043
23394
  let size;
23044
23395
  try {
23045
- size = (await stat14(filePath)).size;
23396
+ size = (await stat15(filePath)).size;
23046
23397
  } catch {
23047
23398
  return null;
23048
23399
  }
@@ -23199,14 +23550,14 @@ var init_models = __esm({
23199
23550
  });
23200
23551
 
23201
23552
  // ../../server/lib/notificationHistory.ts
23202
- import { mkdir as mkdir5, readFile as readFile16 } from "node:fs/promises";
23553
+ import { mkdir as mkdir5, readFile as readFile17 } from "node:fs/promises";
23203
23554
  import { mkdirSync, writeFileSync } from "node:fs";
23204
23555
  import { homedir as homedir8 } from "node:os";
23205
- import { dirname as dirname9, join as join22 } from "node:path";
23556
+ import { dirname as dirname9, join as join23 } from "node:path";
23206
23557
  import { randomUUID as randomUUID4 } from "node:crypto";
23207
23558
  async function load() {
23208
23559
  if (entries) return entries;
23209
- loadPromise ??= readFile16(NOTIFICATION_HISTORY_FILE, "utf-8").then((raw) => {
23560
+ loadPromise ??= readFile17(NOTIFICATION_HISTORY_FILE, "utf-8").then((raw) => {
23210
23561
  const parsed = JSON.parse(raw);
23211
23562
  return Array.isArray(parsed) ? parsed.filter(isEntry) : [];
23212
23563
  }).catch(() => []).then((loaded2) => {
@@ -23290,7 +23641,7 @@ var NOTIFICATION_HISTORY_FILE, MAX_ENTRIES, PERSIST_DEBOUNCE_MS, entries, loadPr
23290
23641
  var init_notificationHistory = __esm({
23291
23642
  "../../server/lib/notificationHistory.ts"() {
23292
23643
  init_atomicJsonFile();
23293
- NOTIFICATION_HISTORY_FILE = join22(homedir8(), ".cogpit", "notifications.json");
23644
+ NOTIFICATION_HISTORY_FILE = join23(homedir8(), ".cogpit", "notifications.json");
23294
23645
  MAX_ENTRIES = 200;
23295
23646
  PERSIST_DEBOUNCE_MS = 500;
23296
23647
  entries = null;
@@ -23338,7 +23689,7 @@ var init_notifications = __esm({
23338
23689
  });
23339
23690
 
23340
23691
  // ../../server/lib/systemProcesses.ts
23341
- import { execFile as execFile5 } from "node:child_process";
23692
+ import { execFile as execFile6 } from "node:child_process";
23342
23693
  function parseEtimeSeconds(etime) {
23343
23694
  const match = /^(?:(\d+)-)?(?:(\d+):)?(\d+):(\d+)$/.exec(etime.trim());
23344
23695
  if (!match) return 0;
@@ -23459,12 +23810,12 @@ function classifyProcesses(rows, selfPid) {
23459
23810
  }).slice(0, MAX_LISTED_PROCESSES);
23460
23811
  }
23461
23812
  function listSystemProcesses() {
23462
- return new Promise((resolve21, reject) => {
23463
- execFile5(
23813
+ return new Promise((resolve22, reject) => {
23814
+ execFile6(
23464
23815
  "ps",
23465
23816
  ["-axo", "pid=,ppid=,pcpu=,rss=,etime=,args="],
23466
23817
  { maxBuffer: 8 * 1024 * 1024 },
23467
- (error, stdout) => error ? reject(error) : resolve21(stdout)
23818
+ (error, stdout) => error ? reject(error) : resolve22(stdout)
23468
23819
  );
23469
23820
  });
23470
23821
  }
@@ -23498,7 +23849,7 @@ var init_systemProcesses = __esm({
23498
23849
  });
23499
23850
 
23500
23851
  // ../../server/lib/desktopNotify.ts
23501
- import { execFile as execFile6 } from "node:child_process";
23852
+ import { execFile as execFile7 } from "node:child_process";
23502
23853
  function parentMessagePort() {
23503
23854
  const { parentPort } = process;
23504
23855
  return parentPort && typeof parentPort.postMessage === "function" ? parentPort : null;
@@ -23511,7 +23862,7 @@ function showNotification(title, body, nav, historyId) {
23511
23862
  return;
23512
23863
  }
23513
23864
  if (process.platform === "darwin") {
23514
- execFile6(
23865
+ execFile7(
23515
23866
  "osascript",
23516
23867
  ["-e", `display notification "${escapeAppleScript(body)}" with title "${escapeAppleScript(title)}"`],
23517
23868
  // This is the standalone server's only desktop channel, so a silent
@@ -23554,7 +23905,7 @@ var init_notifications2 = __esm({
23554
23905
  // ../../server/lib/pushConfig.ts
23555
23906
  import { readFileSync as readFileSync3, statSync as statSync3 } from "node:fs";
23556
23907
  import { homedir as homedir9 } from "node:os";
23557
- import { join as join23 } from "node:path";
23908
+ import { join as join24 } from "node:path";
23558
23909
  function warnOnce(message) {
23559
23910
  if (lastWarning === message) return;
23560
23911
  lastWarning = message;
@@ -23614,7 +23965,7 @@ function normalizeBaseUrl(value, label) {
23614
23965
  }
23615
23966
  return parsed.toString().replace(/\/+$/, "");
23616
23967
  }
23617
- function resolve15(path) {
23968
+ function resolve16(path) {
23618
23969
  const file = readConfigFile(path);
23619
23970
  const topic = asString(process.env.COGPIT_NTFY_TOPIC) ?? asString(file.topic);
23620
23971
  if (!topic) return null;
@@ -23642,14 +23993,14 @@ function getPushConfig(path = PUSH_CONFIG_FILE) {
23642
23993
  process.env.COGPIT_PUBLIC_URL
23643
23994
  ].join("\0");
23644
23995
  if (cache3?.key === key2) return cache3.config;
23645
- const config = resolve15(path);
23996
+ const config = resolve16(path);
23646
23997
  cache3 = { key: key2, config };
23647
23998
  return config;
23648
23999
  }
23649
24000
  var PUSH_CONFIG_FILE, DEFAULT_NTFY_URL, TOPIC_PATTERN, cache3, lastWarning;
23650
24001
  var init_pushConfig = __esm({
23651
24002
  "../../server/lib/pushConfig.ts"() {
23652
- PUSH_CONFIG_FILE = join23(homedir9(), ".cogpit", "push.json");
24003
+ PUSH_CONFIG_FILE = join24(homedir9(), ".cogpit", "push.json");
23653
24004
  DEFAULT_NTFY_URL = "https://ntfy.sh";
23654
24005
  TOPIC_PATTERN = /^[-_A-Za-z0-9]{1,64}$/;
23655
24006
  cache3 = null;
@@ -24264,22 +24615,22 @@ async function handleBackgroundTasks(req, res, next) {
24264
24615
  const portAlive = {};
24265
24616
  await Promise.all(
24266
24617
  allPorts.map(
24267
- (port) => new Promise((resolve21) => {
24618
+ (port) => new Promise((resolve22) => {
24268
24619
  const socket = createConnection({ port, host: "127.0.0.1" });
24269
24620
  socket.setTimeout(500);
24270
24621
  socket.on("connect", () => {
24271
24622
  portAlive[port] = true;
24272
24623
  socket.destroy();
24273
- resolve21();
24624
+ resolve22();
24274
24625
  });
24275
24626
  socket.on("timeout", () => {
24276
24627
  portAlive[port] = false;
24277
24628
  socket.destroy();
24278
- resolve21();
24629
+ resolve22();
24279
24630
  });
24280
24631
  socket.on("error", () => {
24281
24632
  portAlive[port] = false;
24282
- resolve21();
24633
+ resolve22();
24283
24634
  });
24284
24635
  })
24285
24636
  )
@@ -24383,14 +24734,14 @@ var init_backgroundAgents = __esm({
24383
24734
 
24384
24735
  // ../../server/routes/ports/listeningProcesses.ts
24385
24736
  function runCapture(command, args) {
24386
- return new Promise((resolve21, reject) => {
24737
+ return new Promise((resolve22, reject) => {
24387
24738
  const child = spawn2(command, args);
24388
24739
  let stdout = "";
24389
24740
  child.stdout?.on("data", (data) => {
24390
24741
  stdout += data.toString();
24391
24742
  });
24392
24743
  child.on("error", reject);
24393
- child.on("close", () => resolve21(stdout));
24744
+ child.on("close", () => resolve22(stdout));
24394
24745
  });
24395
24746
  }
24396
24747
  async function findListeningPids(port) {
@@ -24430,22 +24781,22 @@ function registerPortRoutes(use) {
24430
24781
  const results = {};
24431
24782
  await Promise.all(
24432
24783
  ports.map(
24433
- (port) => new Promise((resolve21) => {
24784
+ (port) => new Promise((resolve22) => {
24434
24785
  const socket = createConnection({ port, host: "127.0.0.1" });
24435
24786
  socket.setTimeout(500);
24436
24787
  socket.on("connect", () => {
24437
24788
  results[port] = true;
24438
24789
  socket.destroy();
24439
- resolve21();
24790
+ resolve22();
24440
24791
  });
24441
24792
  socket.on("timeout", () => {
24442
24793
  results[port] = false;
24443
24794
  socket.destroy();
24444
- resolve21();
24795
+ resolve22();
24445
24796
  });
24446
24797
  socket.on("error", () => {
24447
24798
  results[port] = false;
24448
- resolve21();
24799
+ resolve22();
24449
24800
  });
24450
24801
  })
24451
24802
  )
@@ -24515,8 +24866,8 @@ var init_ports2 = __esm({
24515
24866
 
24516
24867
  // ../../server/routes/project-file.ts
24517
24868
  import { randomUUID as randomUUID5 } from "node:crypto";
24518
- import { readFile as readFile17, realpath as realpath9, rename as rename3, stat as stat15, unlink as unlink6, writeFile as writeFile6 } from "node:fs/promises";
24519
- import { dirname as dirname10, isAbsolute as isAbsolute10, resolve as resolve16 } from "node:path";
24869
+ import { readFile as readFile18, realpath as realpath10, rename as rename3, stat as stat16, unlink as unlink6, writeFile as writeFile6 } from "node:fs/promises";
24870
+ import { dirname as dirname10, isAbsolute as isAbsolute11, resolve as resolve17 } from "node:path";
24520
24871
  function readBody(req) {
24521
24872
  return new Promise((resolveBody, reject) => {
24522
24873
  let body = "";
@@ -24534,26 +24885,26 @@ function readBody(req) {
24534
24885
  });
24535
24886
  }
24536
24887
  async function resolveProjectFile(cwd, filePath) {
24537
- if (!isAbsolute10(cwd)) throw new ProjectFileError(400, "cwd must be an absolute path");
24538
- if (!filePath || isAbsolute10(filePath) || filePath.includes("\0")) {
24888
+ if (!isAbsolute11(cwd)) throw new ProjectFileError(400, "cwd must be an absolute path");
24889
+ if (!filePath || isAbsolute11(filePath) || filePath.includes("\0")) {
24539
24890
  throw new ProjectFileError(400, "path must be a relative project file");
24540
24891
  }
24541
24892
  let root;
24542
24893
  try {
24543
- root = await realpath9(resolve16(cwd));
24894
+ root = await realpath10(resolve17(cwd));
24544
24895
  } catch {
24545
24896
  throw new ProjectFileError(404, "Project directory not found");
24546
24897
  }
24547
- const candidate = resolve16(root, filePath);
24898
+ const candidate = resolve17(root, filePath);
24548
24899
  if (!isWithinDir(root, candidate)) throw new ProjectFileError(403, "File is outside the project");
24549
24900
  let absolutePath;
24550
24901
  try {
24551
- absolutePath = await realpath9(candidate);
24902
+ absolutePath = await realpath10(candidate);
24552
24903
  } catch {
24553
24904
  throw new ProjectFileError(404, "File not found");
24554
24905
  }
24555
24906
  if (!isWithinDir(root, absolutePath)) throw new ProjectFileError(403, "File is outside the project");
24556
- const info = await stat15(absolutePath);
24907
+ const info = await stat16(absolutePath);
24557
24908
  if (!info.isFile()) throw new ProjectFileError(400, "Path must point to a file");
24558
24909
  if (info.size > MAX_FILE_BYTES) throw new ProjectFileError(413, "File is larger than 2 MB");
24559
24910
  return { absolutePath, info };
@@ -24573,14 +24924,14 @@ function decodeTextFile(buffer) {
24573
24924
  }
24574
24925
  }
24575
24926
  async function writeAtomically(absolutePath, content, mode, expectedMtimeMs) {
24576
- const latest = await stat15(absolutePath);
24927
+ const latest = await stat16(absolutePath);
24577
24928
  if (latest.mtimeMs !== expectedMtimeMs) {
24578
24929
  throw new ProjectFileError(409, "File changed on disk. Reload it before saving.");
24579
24930
  }
24580
- const temporaryPath = resolve16(dirname10(absolutePath), `.${randomUUID5()}.cogpit-save`);
24931
+ const temporaryPath = resolve17(dirname10(absolutePath), `.${randomUUID5()}.cogpit-save`);
24581
24932
  try {
24582
24933
  await writeFile6(temporaryPath, content, { encoding: "utf-8", mode });
24583
- const beforeRename = await stat15(absolutePath);
24934
+ const beforeRename = await stat16(absolutePath);
24584
24935
  if (beforeRename.mtimeMs !== expectedMtimeMs) {
24585
24936
  throw new ProjectFileError(409, "File changed on disk. Reload it before saving.");
24586
24937
  }
@@ -24597,7 +24948,7 @@ function registerProjectFileContentRoutes(use) {
24597
24948
  const filePath = url.searchParams.get("path") ?? "";
24598
24949
  try {
24599
24950
  const file = await resolveProjectFile(cwd, filePath);
24600
- const buffer = await readFile17(file.absolutePath);
24951
+ const buffer = await readFile18(file.absolutePath);
24601
24952
  return sendJson(res, 200, {
24602
24953
  content: decodeTextFile(buffer),
24603
24954
  mtimeMs: file.info.mtimeMs,
@@ -24621,7 +24972,7 @@ function registerProjectFileContentRoutes(use) {
24621
24972
  throw new ProjectFileError(409, "File changed on disk. Reload it before saving.");
24622
24973
  }
24623
24974
  await writeAtomically(file.absolutePath, body.content, file.info.mode, body.expectedMtimeMs);
24624
- const saved = await stat15(file.absolutePath);
24975
+ const saved = await stat16(file.absolutePath);
24625
24976
  return sendJson(res, 200, { ok: true, mtimeMs: saved.mtimeMs, size: saved.size });
24626
24977
  } catch (error) {
24627
24978
  return respondWithError(res, error);
@@ -24671,13 +25022,13 @@ var init_project_files_ranking = __esm({
24671
25022
  });
24672
25023
 
24673
25024
  // ../../server/routes/project-files.ts
24674
- import { execFile as execFileCallback3 } from "node:child_process";
24675
- import { readdir as readdir11, realpath as realpath10, stat as stat16 } from "node:fs/promises";
24676
- import { isAbsolute as isAbsolute11, relative as relative9, resolve as resolve17, sep as sep11 } from "node:path";
24677
- import { promisify as promisify3 } from "node:util";
25025
+ import { execFile as execFileCallback4 } from "node:child_process";
25026
+ import { readdir as readdir11, realpath as realpath11, stat as stat17 } from "node:fs/promises";
25027
+ import { isAbsolute as isAbsolute12, relative as relative9, resolve as resolve18, sep as sep11 } from "node:path";
25028
+ import { promisify as promisify4 } from "node:util";
24678
25029
  async function listGitProjectFiles(root) {
24679
25030
  try {
24680
- const result = await execFile7(
25031
+ const result = await execFile8(
24681
25032
  "git",
24682
25033
  ["ls-files", "--cached", "--others", "--exclude-standard", "-z", "--", "."],
24683
25034
  {
@@ -24713,7 +25064,7 @@ async function listProjectFiles(root, { skipCache = false } = {}) {
24713
25064
  }
24714
25065
  for (const entry of entries3) {
24715
25066
  if (entry.isSymbolicLink()) continue;
24716
- const absolutePath = resolve17(directory, entry.name);
25067
+ const absolutePath = resolve18(directory, entry.name);
24717
25068
  if (entry.isDirectory()) {
24718
25069
  if (!IGNORED_DIRECTORIES.has(entry.name)) pending.push(absolutePath);
24719
25070
  continue;
@@ -24735,12 +25086,12 @@ function registerProjectFileRoutes(use) {
24735
25086
  const query4 = url.searchParams.get("q") ?? "";
24736
25087
  const limit = Math.min(Math.max(Number(url.searchParams.get("limit")) || 30, 1), 100);
24737
25088
  const skipCache = url.searchParams.get("refresh") === "1";
24738
- if (!isAbsolute11(cwd)) return sendJson(res, 400, { error: "cwd must be an absolute path" });
24739
- let root = resolve17(cwd);
25089
+ if (!isAbsolute12(cwd)) return sendJson(res, 400, { error: "cwd must be an absolute path" });
25090
+ let root = resolve18(cwd);
24740
25091
  try {
24741
- const info = await stat16(root);
25092
+ const info = await stat17(root);
24742
25093
  if (!info.isDirectory()) return sendJson(res, 400, { error: "cwd must be a directory" });
24743
- root = await realpath10(root);
25094
+ root = await realpath11(root);
24744
25095
  const files = await listProjectFiles(root, { skipCache });
24745
25096
  const ranked = rankProjectFiles(files, query4, limit);
24746
25097
  return sendJson(res, 200, {
@@ -24753,7 +25104,7 @@ function registerProjectFileRoutes(use) {
24753
25104
  }
24754
25105
  });
24755
25106
  }
24756
- var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache, execFile7;
25107
+ var MAX_FILES, CACHE_TTL_MS3, IGNORED_DIRECTORIES, fileCache, execFile8;
24757
25108
  var init_project_files = __esm({
24758
25109
  "../../server/routes/project-files.ts"() {
24759
25110
  init_http();
@@ -24774,7 +25125,7 @@ var init_project_files = __esm({
24774
25125
  "target"
24775
25126
  ]);
24776
25127
  fileCache = /* @__PURE__ */ new Map();
24777
- execFile7 = promisify3(execFileCallback3);
25128
+ execFile8 = promisify4(execFileCallback4);
24778
25129
  }
24779
25130
  });
24780
25131
 
@@ -24988,7 +25339,7 @@ function createCollector() {
24988
25339
  return {
24989
25340
  pullRequests,
24990
25341
  add,
24991
- record(output, command, toolCallId, timestamp) {
25342
+ record(output, command, toolCallId, timestamp2) {
24992
25343
  const match = PR_URL.exec(output);
24993
25344
  if (!match) return;
24994
25345
  add({
@@ -24998,7 +25349,7 @@ function createCollector() {
24998
25349
  title: extractTitle(command),
24999
25350
  isDraft: /(?:^|\s)--draft(?:\s|$)/.test(command),
25000
25351
  toolCallId,
25001
- timestamp
25352
+ timestamp: timestamp2
25002
25353
  });
25003
25354
  }
25004
25355
  };
@@ -25027,22 +25378,22 @@ function createPullRequestScanner() {
25027
25378
  seenReferences.add(key2);
25028
25379
  references.push(reference);
25029
25380
  }
25030
- function recordToolCall(id, input, timestamp) {
25381
+ function recordToolCall(id, input, timestamp2) {
25031
25382
  const reference = findPullRequestReference(input);
25032
25383
  if (reference) recordReference(reference);
25033
- recordCreate(id, input, timestamp);
25384
+ recordCreate(id, input, timestamp2);
25034
25385
  }
25035
- function recordCreate(id, input, timestamp) {
25386
+ function recordCreate(id, input, timestamp2) {
25036
25387
  if (typeof id !== "string" || !id) return;
25037
25388
  const command = findCreateCommand(input);
25038
- if (command) openCreates.set(id, { command, timestamp });
25389
+ if (command) openCreates.set(id, { command, timestamp: timestamp2 });
25039
25390
  }
25040
- function recordPrLink(record3, timestamp) {
25041
- const url = record3.prUrl;
25042
- const number = record3.prNumber;
25391
+ function recordPrLink(record4, timestamp2) {
25392
+ const url = record4.prUrl;
25393
+ const number = record4.prNumber;
25043
25394
  if (typeof url !== "string" || !url) return;
25044
25395
  if (typeof number !== "number" || !Number.isInteger(number) || number <= 0) return;
25045
- const repo = typeof record3.prRepository === "string" ? record3.prRepository : "";
25396
+ const repo = typeof record4.prRepository === "string" ? record4.prRepository : "";
25046
25397
  collector.add({
25047
25398
  url,
25048
25399
  number,
@@ -25050,7 +25401,7 @@ function createPullRequestScanner() {
25050
25401
  title: null,
25051
25402
  isDraft: false,
25052
25403
  toolCallId: "",
25053
- timestamp
25404
+ timestamp: timestamp2
25054
25405
  });
25055
25406
  recordReference({ number, repo });
25056
25407
  }
@@ -25077,37 +25428,37 @@ function createPullRequestScanner() {
25077
25428
  if (!line.includes(GH_PR_HINT) && !line.includes(URL_HINT) && !line.includes(PR_LINK_HINT)) {
25078
25429
  return;
25079
25430
  }
25080
- let record3;
25431
+ let record4;
25081
25432
  try {
25082
- record3 = JSON.parse(line);
25433
+ record4 = JSON.parse(line);
25083
25434
  } catch {
25084
25435
  return;
25085
25436
  }
25086
- if (!isRecord5(record3)) return;
25087
- const timestamp = typeof record3.timestamp === "string" ? record3.timestamp : "";
25088
- if (record3.type === "pr-link") {
25089
- recordPrLink(record3, timestamp);
25437
+ if (!isRecord5(record4)) return;
25438
+ const timestamp2 = typeof record4.timestamp === "string" ? record4.timestamp : "";
25439
+ if (record4.type === "pr-link") {
25440
+ recordPrLink(record4, timestamp2);
25090
25441
  return;
25091
25442
  }
25092
- const payload = record3.payload;
25443
+ const payload = record4.payload;
25093
25444
  if (isRecord5(payload)) {
25094
25445
  const type = payload.type;
25095
25446
  if (type === "function_call" || type === "custom_tool_call") {
25096
- recordToolCall(payload.call_id, parseArgs2(payload.arguments ?? payload.input), timestamp);
25447
+ recordToolCall(payload.call_id, parseArgs2(payload.arguments ?? payload.input), timestamp2);
25097
25448
  } else if (type === "function_call_output" || type === "custom_tool_call_output") {
25098
25449
  recordResult(payload.call_id, payload.output, false);
25099
25450
  }
25100
25451
  return;
25101
25452
  }
25102
- const data = record3.data;
25453
+ const data = record4.data;
25103
25454
  if (isRecord5(data)) {
25104
- if (record3.type === "tool.execution_start") {
25455
+ if (record4.type === "tool.execution_start") {
25105
25456
  recordToolCall(
25106
25457
  data.toolCallId,
25107
25458
  parseArgs2(data.arguments ?? data.input),
25108
- timestamp
25459
+ timestamp2
25109
25460
  );
25110
- } else if (record3.type === "tool.execution_complete") {
25461
+ } else if (record4.type === "tool.execution_complete") {
25111
25462
  recordResult(
25112
25463
  data.toolCallId,
25113
25464
  data.result ?? data.output ?? data.error,
@@ -25116,12 +25467,12 @@ function createPullRequestScanner() {
25116
25467
  }
25117
25468
  return;
25118
25469
  }
25119
- const message = record3.message;
25470
+ const message = record4.message;
25120
25471
  if (!isRecord5(message) || !Array.isArray(message.content)) return;
25121
25472
  for (const block of message.content) {
25122
25473
  if (!isRecord5(block)) continue;
25123
25474
  if (block.type === "tool_use" && isRecord5(block.input)) {
25124
- recordToolCall(block.id, block.input, timestamp);
25475
+ recordToolCall(block.id, block.input, timestamp2);
25125
25476
  } else if (block.type === "tool_result") {
25126
25477
  recordResult(block.tool_use_id, block.content, block.is_error === true);
25127
25478
  }
@@ -25226,15 +25577,15 @@ var init_sessionPrIndex = __esm({
25226
25577
  });
25227
25578
 
25228
25579
  // ../../server/lib/sessionPrSearchIndex.ts
25229
- import { mkdir as mkdir6, readFile as readFile18 } from "node:fs/promises";
25230
- import { join as join24 } from "node:path";
25580
+ import { mkdir as mkdir6, readFile as readFile19 } from "node:fs/promises";
25581
+ import { join as join25 } from "node:path";
25231
25582
  function isIndexEntry(value) {
25232
25583
  if (typeof value !== "object" || value === null) return false;
25233
25584
  const entry = value;
25234
25585
  return typeof entry.size === "number" && typeof entry.mtimeMs === "number" && Array.isArray(entry.pullRequests) && Array.isArray(entry.references);
25235
25586
  }
25236
25587
  function currentIndexPath() {
25237
- return join24(dirs.SESSION_CONFIG_DIR, INDEX_FILE);
25588
+ return join25(dirs.SESSION_CONFIG_DIR, INDEX_FILE);
25238
25589
  }
25239
25590
  function resetForPath(indexPath) {
25240
25591
  activeIndexPath = indexPath;
@@ -25251,7 +25602,7 @@ async function loadIndex() {
25251
25602
  if (loaded) return;
25252
25603
  if (loading) return loading;
25253
25604
  const expectedGeneration = generation;
25254
- const pendingLoad = readFile18(indexPath, "utf-8").then((raw) => {
25605
+ const pendingLoad = readFile19(indexPath, "utf-8").then((raw) => {
25255
25606
  if (expectedGeneration !== generation) return;
25256
25607
  const parsed = JSON.parse(raw);
25257
25608
  if (typeof parsed !== "object" || parsed === null) return;
@@ -25295,7 +25646,7 @@ async function runQueue(expectedGeneration) {
25295
25646
  await persistIndex(expectedGeneration).catch(() => void 0);
25296
25647
  sincePersist = 0;
25297
25648
  }
25298
- await new Promise((resolve21) => setImmediate(resolve21));
25649
+ await new Promise((resolve22) => setImmediate(resolve22));
25299
25650
  }
25300
25651
  if (sincePersist > 0) await persistIndex(expectedGeneration).catch(() => void 0);
25301
25652
  } finally {
@@ -26338,11 +26689,11 @@ var init_agent_executable = __esm({
26338
26689
  });
26339
26690
 
26340
26691
  // ../../server/routes/scripts/discovery.ts
26341
- import { readdir as readdir12, readFile as readFile19 } from "node:fs/promises";
26342
- import { join as join25, relative as relative10 } from "node:path";
26692
+ import { readdir as readdir12, readFile as readFile20 } from "node:fs/promises";
26693
+ import { join as join26, relative as relative10 } from "node:path";
26343
26694
  async function extractScripts(dir, dirLabel) {
26344
26695
  try {
26345
- const raw = await readFile19(join25(dir, "package.json"), "utf-8");
26696
+ const raw = await readFile20(join26(dir, "package.json"), "utf-8");
26346
26697
  const pkg = JSON.parse(raw);
26347
26698
  const scripts = pkg.scripts;
26348
26699
  if (!scripts || typeof scripts !== "object") return [];
@@ -26368,7 +26719,7 @@ async function discoverScripts(projectDir) {
26368
26719
  );
26369
26720
  const childResults = await Promise.all(
26370
26721
  childDirs.map(async (entry) => {
26371
- const childPath = join25(projectDir, entry.name);
26722
+ const childPath = join26(projectDir, entry.name);
26372
26723
  const label = relative10(projectDir, childPath) + "/";
26373
26724
  return extractScripts(childPath, label);
26374
26725
  })
@@ -26415,12 +26766,12 @@ var init_discovery = __esm({
26415
26766
  });
26416
26767
 
26417
26768
  // ../../server/routes/scripts/index.ts
26418
- import { stat as stat17 } from "node:fs/promises";
26419
- import { resolve as resolve18 } from "node:path";
26769
+ import { stat as stat18 } from "node:fs/promises";
26770
+ import { resolve as resolve19 } from "node:path";
26420
26771
  async function validateDir(dir) {
26421
26772
  try {
26422
- const resolved = resolve18(dir);
26423
- const info = await stat17(resolved);
26773
+ const resolved = resolve19(dir);
26774
+ const info = await stat18(resolved);
26424
26775
  return info.isDirectory() ? resolved : null;
26425
26776
  } catch {
26426
26777
  return null;
@@ -26485,7 +26836,7 @@ async function withTranscriptEffort(key2, stored) {
26485
26836
  }
26486
26837
  }
26487
26838
  function collectBody(req) {
26488
- return new Promise((resolve21, reject) => {
26839
+ return new Promise((resolve22, reject) => {
26489
26840
  let body = "";
26490
26841
  req.on("data", (chunk) => {
26491
26842
  body += chunk.toString();
@@ -26494,7 +26845,7 @@ function collectBody(req) {
26494
26845
  req.destroy();
26495
26846
  }
26496
26847
  });
26497
- req.on("end", () => resolve21(body));
26848
+ req.on("end", () => resolve22(body));
26498
26849
  req.on("error", reject);
26499
26850
  });
26500
26851
  }
@@ -26554,12 +26905,12 @@ var init_session_config = __esm({
26554
26905
 
26555
26906
  // ../../server/lib/agentTeamIdentity.ts
26556
26907
  import { open as open9, readdir as readdir13 } from "node:fs/promises";
26557
- import { join as join26 } from "node:path";
26908
+ import { join as join27 } from "node:path";
26558
26909
  async function matchSubagentToMember(leadSessionId, subagentFileName, members) {
26559
26910
  const entries3 = await readdir13(dirs.PROJECTS_DIR, { withFileTypes: true });
26560
26911
  for (const entry of entries3) {
26561
26912
  if (!entry.isDirectory() || entry.name === "memory") continue;
26562
- const filePath = join26(
26913
+ const filePath = join27(
26563
26914
  dirs.PROJECTS_DIR,
26564
26915
  entry.name,
26565
26916
  leadSessionId,
@@ -27252,7 +27603,7 @@ function normalizeCopilotFileChangeEvents(jsonlContent) {
27252
27603
  }
27253
27604
  });
27254
27605
  }
27255
- return records.map((record3) => JSON.stringify(record3)).join("\n");
27606
+ return records.map((record4) => JSON.stringify(record4)).join("\n");
27256
27607
  }
27257
27608
  async function parseSessionFileChanges(jsonlContent, includeContent) {
27258
27609
  if (formatForText(jsonlContent).kind === "copilot") {
@@ -28672,8 +29023,8 @@ var init_paths = __esm({
28672
29023
  });
28673
29024
 
28674
29025
  // ../../server/routes/undo/fileOperations.ts
28675
- import { basename as basename12, dirname as dirname13, isAbsolute as isAbsolute12 } from "node:path";
28676
- import { lstat as lstat6, realpath as realpath11 } from "node:fs/promises";
29026
+ import { basename as basename12, dirname as dirname13, isAbsolute as isAbsolute13 } from "node:path";
29027
+ import { lstat as lstat6, realpath as realpath12 } from "node:fs/promises";
28677
29028
  function hasTraversalSegment(filePath) {
28678
29029
  return filePath.split(/[\\/]+/).includes("..");
28679
29030
  }
@@ -28684,7 +29035,7 @@ function isForbiddenPath(filePath) {
28684
29035
  return FORBIDDEN_PREFIXES.some((prefix) => isWithinDir(prefix, filePath));
28685
29036
  }
28686
29037
  async function resolveSafeOperationPath(filePath, home, canonicalHome) {
28687
- if (typeof filePath !== "string" || !isAbsolute12(filePath) || hasTraversalSegment(filePath)) {
29038
+ if (typeof filePath !== "string" || !isAbsolute13(filePath) || hasTraversalSegment(filePath)) {
28688
29039
  return null;
28689
29040
  }
28690
29041
  const resolved = resolve7(filePath);
@@ -28692,12 +29043,12 @@ async function resolveSafeOperationPath(filePath, home, canonicalHome) {
28692
29043
  try {
28693
29044
  const stats = await lstat6(resolved);
28694
29045
  if (stats.isSymbolicLink()) return null;
28695
- const canonicalTarget = await realpath11(resolved);
29046
+ const canonicalTarget = await realpath12(resolved);
28696
29047
  return isWithinDir(canonicalHome, canonicalTarget) && !isForbiddenPath(canonicalTarget) ? canonicalTarget : null;
28697
29048
  } catch (error) {
28698
29049
  if (!isMissingPathError(error)) return null;
28699
29050
  try {
28700
- const canonicalParent = await realpath11(dirname13(resolved));
29051
+ const canonicalParent = await realpath12(dirname13(resolved));
28701
29052
  const canonicalTarget = join11(canonicalParent, basename12(resolved));
28702
29053
  return isWithinDir(canonicalHome, canonicalTarget) && !isForbiddenPath(canonicalTarget) ? canonicalTarget : null;
28703
29054
  } catch {
@@ -28745,7 +29096,7 @@ async function prepareFileOperations(operationValues, options = {}) {
28745
29096
  const home = resolve7(homedir4());
28746
29097
  let canonicalHome;
28747
29098
  try {
28748
- canonicalHome = await realpath11(home);
29099
+ canonicalHome = await realpath12(home);
28749
29100
  } catch {
28750
29101
  throw new UndoOperationError(403, "File operations restricted to home directory");
28751
29102
  }
@@ -28949,7 +29300,7 @@ function applySessionMutation(content, mutation) {
28949
29300
  ` : "";
28950
29301
  }
28951
29302
  async function readBody2(req) {
28952
- return await new Promise((resolve21, reject) => {
29303
+ return await new Promise((resolve22, reject) => {
28953
29304
  let body = "";
28954
29305
  let bytes = 0;
28955
29306
  let settled = false;
@@ -28968,7 +29319,7 @@ async function readBody2(req) {
28968
29319
  req.on("end", () => {
28969
29320
  if (!settled) {
28970
29321
  settled = true;
28971
- resolve21(body);
29322
+ resolve22(body);
28972
29323
  }
28973
29324
  });
28974
29325
  req.on("error", (error) => {
@@ -29221,20 +29572,20 @@ var init_aggregate = __esm({
29221
29572
  this.#toDay = makeDayFormatter(options.timeZone);
29222
29573
  }
29223
29574
  /** Folds one record in; returns whether it actually contributed. */
29224
- add(record3) {
29225
- if (record3.dedupeKey !== null) {
29226
- if (this.#seen.has(record3.dedupeKey)) return false;
29227
- this.#seen.add(record3.dedupeKey);
29575
+ add(record4) {
29576
+ if (record4.dedupeKey !== null) {
29577
+ if (this.#seen.has(record4.dedupeKey)) return false;
29578
+ this.#seen.add(record4.dedupeKey);
29228
29579
  }
29229
- const day = this.#toDay(record3.timestampMs);
29580
+ const day = this.#toDay(record4.timestampMs);
29230
29581
  if (day < this.#options.sinceDay || day > this.#options.untilDay) return false;
29231
- const key2 = [day, record3.provider, record3.model].join(KEY_SEPARATOR);
29582
+ const key2 = [day, record4.provider, record4.model].join(KEY_SEPARATOR);
29232
29583
  let bucket = this.#buckets.get(key2);
29233
29584
  if (bucket === void 0) {
29234
29585
  bucket = {
29235
29586
  day,
29236
- provider: record3.provider,
29237
- model: record3.model,
29587
+ provider: record4.provider,
29588
+ model: record4.model,
29238
29589
  totals: emptyUsageCostTotals(),
29239
29590
  costUsd: 0,
29240
29591
  cacheSavingsUsd: 0,
@@ -29247,19 +29598,19 @@ var init_aggregate = __esm({
29247
29598
  }
29248
29599
  const priced = priceUsage(
29249
29600
  this.#options.rates,
29250
- record3.model,
29251
- record3.totals,
29252
- record3.reportedCostUsd
29601
+ record4.model,
29602
+ record4.totals,
29603
+ record4.reportedCostUsd
29253
29604
  );
29254
- bucket.totals = addUsageCostTotals(bucket.totals, record3.totals);
29605
+ bucket.totals = addUsageCostTotals(bucket.totals, record4.totals);
29255
29606
  bucket.costUsd += priced.costUsd;
29256
- bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates, record3.model, record3.totals);
29607
+ bucket.cacheSavingsUsd += cacheSavingsUsd(this.#options.rates, record4.model, record4.totals);
29257
29608
  bucket.records += 1;
29258
29609
  if (priced.costSource === "unpriced") bucket.unpricedRecords += 1;
29259
29610
  if (priced.costSource === "providerReported") bucket.providerReportedRecords += 1;
29260
- if (record3.sessionId.length > 0) {
29261
- bucket.sessions.add(record3.sessionId);
29262
- this.#sessions.add(record3.sessionId);
29611
+ if (record4.sessionId.length > 0) {
29612
+ bucket.sessions.add(record4.sessionId);
29613
+ this.#sessions.add(record4.sessionId);
29263
29614
  }
29264
29615
  return true;
29265
29616
  }
@@ -29289,8 +29640,8 @@ var init_aggregate = __esm({
29289
29640
 
29290
29641
  // ../../server/lib/usageCost/reader.ts
29291
29642
  import { createReadStream as createReadStream3 } from "node:fs";
29292
- import { readdir as readdir14, stat as stat18 } from "node:fs/promises";
29293
- import { join as join27 } from "node:path";
29643
+ import { readdir as readdir14, stat as stat19 } from "node:fs/promises";
29644
+ import { join as join28 } from "node:path";
29294
29645
  import { createInterface as createInterface3 } from "node:readline";
29295
29646
  async function listTranscriptFiles(root, sinceMs) {
29296
29647
  const found = [];
@@ -29302,14 +29653,14 @@ async function listTranscriptFiles(root, sinceMs) {
29302
29653
  return;
29303
29654
  }
29304
29655
  for (const entry of entries3) {
29305
- const child = join27(dir, entry.name);
29656
+ const child = join28(dir, entry.name);
29306
29657
  if (entry.isDirectory()) {
29307
29658
  await walk2(child);
29308
29659
  continue;
29309
29660
  }
29310
29661
  if (!entry.name.endsWith(".jsonl")) continue;
29311
29662
  try {
29312
- const stats = await stat18(child);
29663
+ const stats = await stat19(child);
29313
29664
  if (stats.mtimeMs >= sinceMs) {
29314
29665
  found.push({ path: child, size: stats.size, mtimeMs: stats.mtimeMs });
29315
29666
  }
@@ -29340,17 +29691,17 @@ async function readTranscriptRecords(filePath, provider) {
29340
29691
  function dedupeWithinFile(records) {
29341
29692
  const slotByKey = /* @__PURE__ */ new Map();
29342
29693
  const kept = [];
29343
- for (const record3 of records) {
29344
- if (record3.dedupeKey === null) {
29345
- kept.push(record3);
29694
+ for (const record4 of records) {
29695
+ if (record4.dedupeKey === null) {
29696
+ kept.push(record4);
29346
29697
  continue;
29347
29698
  }
29348
- const slot = slotByKey.get(record3.dedupeKey);
29699
+ const slot = slotByKey.get(record4.dedupeKey);
29349
29700
  if (slot === void 0) {
29350
- slotByKey.set(record3.dedupeKey, kept.push(record3) - 1);
29701
+ slotByKey.set(record4.dedupeKey, kept.push(record4) - 1);
29351
29702
  continue;
29352
29703
  }
29353
- if (record3.totals.outputTokens > kept[slot].totals.outputTokens) kept[slot] = record3;
29704
+ if (record4.totals.outputTokens > kept[slot].totals.outputTokens) kept[slot] = record4;
29354
29705
  }
29355
29706
  return kept;
29356
29707
  }
@@ -29361,10 +29712,10 @@ var init_reader = __esm({
29361
29712
  });
29362
29713
 
29363
29714
  // ../../server/lib/usageCost/service.ts
29364
- import { readFile as readFile20, writeFile as writeFile7 } from "node:fs/promises";
29365
- import { join as join28 } from "node:path";
29715
+ import { readFile as readFile21, writeFile as writeFile7 } from "node:fs/promises";
29716
+ import { join as join29 } from "node:path";
29366
29717
  function ratesCachePath() {
29367
- return join28(getDataRoot(), "usage-model-rates.json");
29718
+ return join29(getDataRoot(), "usage-model-rates.json");
29368
29719
  }
29369
29720
  function ratesFetchedAt() {
29370
29721
  return ratesFetchedAtMs === null ? null : new Date(ratesFetchedAtMs).toISOString();
@@ -29374,7 +29725,7 @@ async function ensureRatesInner() {
29374
29725
  if (ratesFetchedAtMs !== null && now - ratesFetchedAtMs < RATES_TTL_MS) return;
29375
29726
  if (ratesFetchedAtMs === null) {
29376
29727
  try {
29377
- const raw = JSON.parse(await readFile20(ratesCachePath(), "utf8"));
29728
+ const raw = JSON.parse(await readFile21(ratesCachePath(), "utf8"));
29378
29729
  if (typeof raw.fetchedAtMs === "number") {
29379
29730
  const parsed2 = parseRateTable(raw.document);
29380
29731
  if (parsed2.size > 0) {
@@ -29459,23 +29810,23 @@ async function readUsageCostSummary(input) {
29459
29810
  for (const file of files) {
29460
29811
  const records = await readFileRecords(file, provider);
29461
29812
  scannedFiles += 1;
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();
29813
+ for (const record4 of records) {
29814
+ aggregator.add(record4);
29815
+ if (!liveSessionIds.has(record4.sessionId)) continue;
29816
+ const byModel = durableTotals.get(record4.sessionId) ?? /* @__PURE__ */ new Map();
29466
29817
  byModel.set(
29467
- record3.model,
29818
+ record4.model,
29468
29819
  addUsageCostTotals(
29469
- byModel.get(record3.model) ?? emptyUsageCostTotals(),
29470
- record3.totals
29820
+ byModel.get(record4.model) ?? emptyUsageCostTotals(),
29821
+ record4.totals
29471
29822
  )
29472
29823
  );
29473
- durableTotals.set(record3.sessionId, byModel);
29824
+ durableTotals.set(record4.sessionId, byModel);
29474
29825
  }
29475
29826
  }
29476
29827
  }
29477
29828
  for (const runtime of runtimes2) {
29478
- for (const record3 of await runtime.liveUsageRecords(durableTotals)) aggregator.add(record3);
29829
+ for (const record4 of await runtime.liveUsageRecords(durableTotals)) aggregator.add(record4);
29479
29830
  }
29480
29831
  const retentionCutoffMs = startedAtMs - 90 * 24 * 60 * 60 * 1e3;
29481
29832
  for (const [path, entry] of fileCache2) {
@@ -29561,12 +29912,12 @@ async function readKeychainCredentials() {
29561
29912
  if (process.platform !== "darwin") {
29562
29913
  return null;
29563
29914
  }
29564
- return new Promise((resolve21) => {
29915
+ return new Promise((resolve22) => {
29565
29916
  let resolved = false;
29566
29917
  const done = (value) => {
29567
29918
  if (resolved) return;
29568
29919
  resolved = true;
29569
- resolve21(value);
29920
+ resolve22(value);
29570
29921
  };
29571
29922
  const child = spawn3("/usr/bin/security", [
29572
29923
  "find-generic-password",
@@ -30202,8 +30553,8 @@ var init_workflows2 = __esm({
30202
30553
  });
30203
30554
 
30204
30555
  // ../../server/routes/worktrees/worktreeIo.ts
30205
- import { execFile as execFile8 } from "node:child_process";
30206
- import { promisify as promisify4 } from "node:util";
30556
+ import { execFile as execFile9 } from "node:child_process";
30557
+ import { promisify as promisify5 } from "node:util";
30207
30558
  async function runWorktreeCommand(file, args, { cwd, timeoutMs = WORKTREE_COMMAND_TIMEOUT_MS }) {
30208
30559
  const result = await execFileAsync(file, [...args], {
30209
30560
  cwd,
@@ -30242,7 +30593,7 @@ var init_worktreeIo = __esm({
30242
30593
  WORKTREE_COMMAND_MAX_BUFFER = 4 * 1024 * 1024;
30243
30594
  WORKTREE_SCAN_CONCURRENCY = 4;
30244
30595
  SESSION_HEADER_CONCURRENCY = 8;
30245
- execFileAsync = promisify4(execFile8);
30596
+ execFileAsync = promisify5(execFile9);
30246
30597
  NONINTERACTIVE_ENV = {
30247
30598
  ...process.env,
30248
30599
  GCM_INTERACTIVE: "Never",
@@ -30255,7 +30606,7 @@ var init_worktreeIo = __esm({
30255
30606
  });
30256
30607
 
30257
30608
  // ../../server/routes/worktrees/worktreeUtils.ts
30258
- import { resolve as resolve19, dirname as dirname14 } from "node:path";
30609
+ import { resolve as resolve20, dirname as dirname14 } from "node:path";
30259
30610
  function isValidWorktreeName(name) {
30260
30611
  return /^[a-zA-Z0-9._-]+$/.test(name) && name.length <= 40;
30261
30612
  }
@@ -30318,7 +30669,7 @@ async function getMainWorktreeRoot(projectPath) {
30318
30669
  const commonDir = (await runWorktreeCommand("git", ["rev-parse", "--git-common-dir"], {
30319
30670
  cwd: projectPath
30320
30671
  })).trim();
30321
- return dirname14(resolve19(projectPath, commonDir));
30672
+ return dirname14(resolve20(projectPath, commonDir));
30322
30673
  } catch {
30323
30674
  return null;
30324
30675
  }
@@ -30343,7 +30694,7 @@ var init_worktreeUtils = __esm({
30343
30694
  });
30344
30695
 
30345
30696
  // ../../server/routes/worktrees/worktreeListRoute.ts
30346
- import { stat as stat19 } from "node:fs/promises";
30697
+ import { stat as stat20 } from "node:fs/promises";
30347
30698
  async function loadSessionBranches(projectDir) {
30348
30699
  const sessionBranches = /* @__PURE__ */ new Map();
30349
30700
  try {
@@ -30458,7 +30809,7 @@ async function buildWorktreeInfo(worktree, defaultBranch, sessionBranches) {
30458
30809
  }
30459
30810
  let createdAt = "";
30460
30811
  try {
30461
- createdAt = (await stat19(worktree.path)).birthtime.toISOString();
30812
+ createdAt = (await stat20(worktree.path)).birthtime.toISOString();
30462
30813
  } catch {
30463
30814
  }
30464
30815
  return {
@@ -30519,9 +30870,9 @@ var init_worktreeListRoute = __esm({
30519
30870
  });
30520
30871
 
30521
30872
  // ../../server/routes/worktrees/index.ts
30522
- import { stat as stat20 } from "node:fs/promises";
30873
+ import { stat as stat21 } from "node:fs/promises";
30523
30874
  async function readJsonRequestBody(req) {
30524
- const body = await new Promise((resolve21, reject) => {
30875
+ const body = await new Promise((resolve22, reject) => {
30525
30876
  let data = "";
30526
30877
  let bytesRead = 0;
30527
30878
  let settled = false;
@@ -30538,7 +30889,7 @@ async function readJsonRequestBody(req) {
30538
30889
  req.on("end", () => {
30539
30890
  if (!settled) {
30540
30891
  settled = true;
30541
- resolve21(data);
30892
+ resolve22(data);
30542
30893
  }
30543
30894
  });
30544
30895
  req.on("error", () => {
@@ -30589,7 +30940,7 @@ async function findStaleWorktrees(worktrees, cutoff) {
30589
30940
  cwd: worktree.path
30590
30941
  });
30591
30942
  if (status.trim()) return null;
30592
- const worktreeStat = await stat20(worktree.path);
30943
+ const worktreeStat = await stat21(worktree.path);
30593
30944
  return worktreeStat.birthtime.getTime() < cutoff ? worktree : null;
30594
30945
  } catch {
30595
30946
  return null;
@@ -30831,6 +31182,7 @@ var init_api_routes = __esm({
30831
31182
  init_git_diff();
30832
31183
  init_git_status();
30833
31184
  init_github_actions();
31185
+ init_vercel_deployments();
30834
31186
  init_project_icon();
30835
31187
  init_hello();
30836
31188
  init_local_file();
@@ -30901,6 +31253,7 @@ var init_api_routes = __esm({
30901
31253
  apiRoute("project-file", registerProjectFileContentRoutes),
30902
31254
  apiRoute("git-status", registerGitStatusRoutes),
30903
31255
  apiRoute("github-actions", registerGitHubActionsRoutes),
31256
+ apiRoute("vercel-deployments", registerVercelDeploymentRoutes),
30904
31257
  apiRoute("project-icon", registerProjectIconRoutes),
30905
31258
  apiRoute("git-diff", registerGitDiffRoutes),
30906
31259
  apiRoute("mcp", registerMcpRoutes),
@@ -31331,18 +31684,18 @@ var init_pty_authorization = __esm({
31331
31684
  // ../../server/app-server.ts
31332
31685
  import express from "express";
31333
31686
  import { createServer, request as httpRequest2 } from "node:http";
31334
- import { join as join29 } from "node:path";
31687
+ import { join as join30 } from "node:path";
31335
31688
  import { WebSocketServer as WebSocketServer2 } from "ws";
31336
31689
  async function createServerComposition(staticDir, userDataDir, environment) {
31337
31690
  setDataRoot(userDataDir);
31338
- setConfigPath(join29(userDataDir, "config.local.json"));
31691
+ setConfigPath(join30(userDataDir, "config.local.json"));
31339
31692
  await loadConfig();
31340
31693
  const configEdition = getConfiguredEditionValue();
31341
31694
  initEdition({ shell: environment.mode, configEdition });
31342
31695
  const suppression = describeEditionSuppression(process.env, configEdition, environment.mode);
31343
31696
  if (suppression) console.warn(suppression);
31344
31697
  if (isTeamEdition()) {
31345
- const teamDir = join29(getDataRoot(), "team");
31698
+ const teamDir = join30(getDataRoot(), "team");
31346
31699
  await initUsersStore(teamDir);
31347
31700
  await initSessionPersistence(teamDir);
31348
31701
  initializeBootstrapToken(userCount());
@@ -31453,7 +31806,7 @@ async function createServerComposition(staticDir, userDataDir, environment) {
31453
31806
  for (const socket of upgradedSockets) socket.destroy();
31454
31807
  upgradedSockets.clear();
31455
31808
  await Promise.all([
31456
- new Promise((resolve21) => wss.close(() => resolve21())),
31809
+ new Promise((resolve22) => wss.close(() => resolve22())),
31457
31810
  cleanupProcesses(),
31458
31811
  ...allRuntimes().map((runtime) => runtime.shutdown()),
31459
31812
  flushSessionPersistence()
@@ -31465,8 +31818,8 @@ async function createServerComposition(staticDir, userDataDir, environment) {
31465
31818
  void cleanupRuntime();
31466
31819
  });
31467
31820
  const dispose = async () => {
31468
- const serverClosed = httpServer.listening ? new Promise((resolve21, reject) => {
31469
- httpServer.close((error) => error ? reject(error) : resolve21());
31821
+ const serverClosed = httpServer.listening ? new Promise((resolve22, reject) => {
31822
+ httpServer.close((error) => error ? reject(error) : resolve22());
31470
31823
  }) : Promise.resolve();
31471
31824
  await cleanupRuntime();
31472
31825
  await serverClosed;
@@ -31513,7 +31866,7 @@ var init_standalone_app_server = __esm({
31513
31866
  // ../../server/lib/portFile.ts
31514
31867
  import { mkdirSync as mkdirSync2, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
31515
31868
  import { homedir as homedir12 } from "node:os";
31516
- import { dirname as dirname15, join as join30 } from "node:path";
31869
+ import { dirname as dirname15, join as join31 } from "node:path";
31517
31870
  function writePortFile(port) {
31518
31871
  try {
31519
31872
  mkdirSync2(dirname15(PORT_FILE), { recursive: true });
@@ -31533,7 +31886,7 @@ function removePortFile() {
31533
31886
  var PORT_FILE;
31534
31887
  var init_portFile = __esm({
31535
31888
  "../../server/lib/portFile.ts"() {
31536
- PORT_FILE = join30(homedir12(), ".cogpit", "port");
31889
+ PORT_FILE = join31(homedir12(), ".cogpit", "port");
31537
31890
  }
31538
31891
  });
31539
31892
 
@@ -31782,9 +32135,9 @@ __export(standalone_runtime_exports, {
31782
32135
  });
31783
32136
  import { existsSync, mkdirSync as mkdirSync3 } from "node:fs";
31784
32137
  import { homedir as homedir13 } from "node:os";
31785
- import { join as join31 } from "node:path";
32138
+ import { join as join32 } from "node:path";
31786
32139
  function listen(server, port, host) {
31787
- return new Promise((resolve21, reject) => {
32140
+ return new Promise((resolve22, reject) => {
31788
32141
  const onError = (error) => reject(error);
31789
32142
  server.once("error", onError);
31790
32143
  server.listen(port, host, () => {
@@ -31794,27 +32147,27 @@ function listen(server, port, host) {
31794
32147
  reject(new Error("Cogpit started without a listening address."));
31795
32148
  return;
31796
32149
  }
31797
- resolve21(address.port);
32150
+ resolve22(address.port);
31798
32151
  });
31799
32152
  });
31800
32153
  }
31801
32154
  async function startStandaloneServer({
31802
32155
  staticDir,
31803
- dataDir = join31(homedir13(), ".config", "cogpit"),
32156
+ dataDir = join32(homedir13(), ".config", "cogpit"),
31804
32157
  host = "127.0.0.1",
31805
32158
  port = 19384,
31806
32159
  env = process.env,
31807
32160
  publishPort = false
31808
32161
  }) {
31809
32162
  mkdirSync3(dataDir, { recursive: true });
31810
- const configPath = join31(dataDir, "config.local.json");
32163
+ const configPath = join32(dataDir, "config.local.json");
31811
32164
  setConfigPath(configPath);
31812
32165
  const configExisted = existsSync(configPath);
31813
32166
  await loadConfig();
31814
32167
  let createdConfig;
31815
32168
  if (!configExisted) {
31816
- const claudeDir = join31(homedir13(), ".claude");
31817
- if (existsSync(join31(claudeDir, "projects"))) {
32169
+ const claudeDir = join32(homedir13(), ".claude");
32170
+ if (existsSync(join32(claudeDir, "projects"))) {
31818
32171
  await saveConfig({ claudeDir });
31819
32172
  createdConfig = `${configPath} for ${claudeDir}`;
31820
32173
  }
@@ -31887,7 +32240,7 @@ var init_standalone_runtime = __esm({
31887
32240
  // src/index.ts
31888
32241
  import { spawn as spawn4 } from "node:child_process";
31889
32242
  import { homedir as homedir14 } from "node:os";
31890
- import { join as join32, resolve as resolve20 } from "node:path";
32243
+ import { join as join33, resolve as resolve21 } from "node:path";
31891
32244
  var SESSION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/;
31892
32245
  var USAGE = `Cogpit
31893
32246
 
@@ -31954,7 +32307,7 @@ function parseArgs(argv) {
31954
32307
  if (value === "--data-dir") {
31955
32308
  const path = argv[index + 1];
31956
32309
  if (!path) throw new Error("--data-dir requires a directory.");
31957
- dataDir = resolve20(path);
32310
+ dataDir = resolve21(path);
31958
32311
  index += 1;
31959
32312
  continue;
31960
32313
  }
@@ -31996,8 +32349,8 @@ async function openExternalUrl(url) {
31996
32349
  async function startPackagedServer(options) {
31997
32350
  const { startStandaloneServer: startStandaloneServer2 } = await Promise.resolve().then(() => (init_standalone_runtime(), standalone_runtime_exports));
31998
32351
  return startStandaloneServer2({
31999
- staticDir: join32(import.meta.dirname, "web"),
32000
- dataDir: options.dataDir ?? join32(homedir14(), ".config", "cogpit"),
32352
+ staticDir: join33(import.meta.dirname, "web"),
32353
+ dataDir: options.dataDir ?? join33(homedir14(), ".config", "cogpit"),
32001
32354
  host: "127.0.0.1",
32002
32355
  port: options.port,
32003
32356
  publishPort: false
@@ -32013,7 +32366,7 @@ async function waitForShutdownSignal() {
32013
32366
  for (const signal of signals) process.once(signal, done);
32014
32367
  });
32015
32368
  }
32016
- var defaultDependencies2 = {
32369
+ var defaultDependencies3 = {
32017
32370
  fetch,
32018
32371
  openUrl: openExternalUrl,
32019
32372
  startServer: startPackagedServer,
@@ -32040,7 +32393,7 @@ async function verifyServer(server, command, deps) {
32040
32393
  }
32041
32394
  }
32042
32395
  async function run(argv, overrides = {}) {
32043
- const deps = { ...defaultDependencies2, ...overrides };
32396
+ const deps = { ...defaultDependencies3, ...overrides };
32044
32397
  let command;
32045
32398
  try {
32046
32399
  command = parseArgs(argv);