fleetlens 0.16.6 → 0.16.8

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 (118) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/build-manifest.json +3 -3
  3. package/app/apps/web/.next/prerender-manifest.json +3 -3
  4. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  12. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/app/apps/web/.next/server/app/agent/page.js.nft.json +1 -1
  14. package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
  15. package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
  16. package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
  18. package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  23. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  25. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
  27. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  29. package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  31. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  33. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  34. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  35. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  36. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  37. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  38. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  39. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  40. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  41. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  42. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  43. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  44. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  45. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  46. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  47. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  48. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  49. package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
  50. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  51. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  52. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  53. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  54. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  55. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  56. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  57. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  58. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  59. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  60. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  61. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  62. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  63. package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
  64. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  65. package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
  66. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  67. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  68. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  69. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
  70. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  71. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  72. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0-zxvif._.js +1 -1
  73. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__01wj6p0._.js +1 -1
  74. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0f3q8gt._.js +1 -1
  75. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ygwqfa._.js +1 -1
  76. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0z0wa91._.js +1 -1
  77. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__12s3gv9._.js +1 -1
  78. package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
  79. package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +1 -1
  80. package/app/apps/web/.next/server/chunks/ssr/apps_web_0~aj0~u._.js +1 -1
  81. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.js +1 -1
  82. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
  83. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  84. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  85. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
  86. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  87. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  88. package/app/apps/web/.next/server/pages/500.html +1 -1
  89. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  90. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  91. package/app/apps/web/.next/static/chunks/01ky0t_.38u4u.js +14 -0
  92. package/app/apps/web/.next/static/chunks/0d~6j~aj2vr1t.js +1 -0
  93. package/app/apps/web/.next/static/chunks/{0-z49mtd-zwgv.js → 0~opjw4gew2-w.js} +1 -1
  94. package/app/apps/web/app/settings/page.tsx +1 -1
  95. package/app/apps/web/app/usage/page.tsx +178 -13
  96. package/app/apps/web/components/menubar-install-banner.tsx +1 -1
  97. package/app/apps/web/components/menubar-install.tsx +1 -1
  98. package/app/apps/web/components/usage-chart-range.tsx +9 -3
  99. package/app/apps/web/components/usage-chart.tsx +9 -3
  100. package/app/apps/web/components/usage-charts-dashboard.tsx +10 -3
  101. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  102. package/app/apps/web/lib/format.test.ts +10 -0
  103. package/app/apps/web/lib/format.ts +6 -4
  104. package/app/apps/web/lib/usage-data.ts +11 -0
  105. package/app/apps/web/lib/usage-display.test.ts +79 -0
  106. package/app/apps/web/lib/usage-display.ts +59 -0
  107. package/app/apps/web/package.json +1 -1
  108. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  109. package/dist/daemon-worker.js +994 -328
  110. package/dist/index.js +1085 -413
  111. package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
  112. package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
  113. package/package.json +1 -1
  114. package/app/apps/web/.next/static/chunks/0rrcj195v1nd..js +0 -1
  115. package/app/apps/web/.next/static/chunks/1350ox0.qybjo.js +0 -14
  116. /package/app/apps/web/.next/static/{8slBxbEObd72azKwDvtmy → yxbgwGc3dXx7HY0GSHJeG}/_buildManifest.js +0 -0
  117. /package/app/apps/web/.next/static/{8slBxbEObd72azKwDvtmy → yxbgwGc3dXx7HY0GSHJeG}/_clientMiddlewareManifest.js +0 -0
  118. /package/app/apps/web/.next/static/{8slBxbEObd72azKwDvtmy → yxbgwGc3dXx7HY0GSHJeG}/_ssgManifest.js +0 -0
@@ -607,7 +607,7 @@ function getAgentMetadata(kind) {
607
607
  function isAgentKind(s) {
608
608
  return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
609
609
  }
610
- var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
610
+ var CLAUDE_CODE_METADATA, CODEX_METADATA, COPILOT_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
611
611
  var init_agent_metadata = __esm({
612
612
  "../parser/dist/agent-metadata.js"() {
613
613
  "use strict";
@@ -625,6 +625,13 @@ var init_agent_metadata = __esm({
625
625
  accentColor: "rgb(16, 163, 127)",
626
626
  iconChar: "\u25C6"
627
627
  };
628
+ COPILOT_METADATA = {
629
+ kind: "copilot",
630
+ displayName: "GitHub Copilot CLI",
631
+ shortLabel: "Copilot",
632
+ accentColor: "rgb(137, 87, 229)",
633
+ iconChar: "\u221E"
634
+ };
628
635
  GEMINI_METADATA = {
629
636
  kind: "gemini",
630
637
  displayName: "Gemini CLI",
@@ -664,6 +671,7 @@ var init_agent_metadata = __esm({
664
671
  agentMetadata = [
665
672
  CLAUDE_CODE_METADATA,
666
673
  CODEX_METADATA,
674
+ COPILOT_METADATA,
667
675
  GEMINI_METADATA,
668
676
  ANTIGRAVITY_METADATA,
669
677
  COWORK_METADATA,
@@ -1525,11 +1533,11 @@ function defaultBranch(commonDir) {
1525
1533
  }
1526
1534
  return void 0;
1527
1535
  }
1528
- function readGitFolder(path10) {
1529
- if (!existsSync(path10))
1536
+ function readGitFolder(path11) {
1537
+ if (!existsSync(path11))
1530
1538
  return { exists: false, isWorktree: false };
1531
1539
  try {
1532
- const git = nearestDotGit(realpathOrSelf(path10));
1540
+ const git = nearestDotGit(realpathOrSelf(path11));
1533
1541
  if (!git)
1534
1542
  return { exists: true, isWorktree: false };
1535
1543
  const projectRoot = projectRootFromCommonDir(git.commonDir);
@@ -3311,24 +3319,442 @@ var init_codex = __esm({
3311
3319
  }
3312
3320
  });
3313
3321
 
3314
- // ../parser/dist/gemini.js
3322
+ // ../parser/dist/copilot.js
3315
3323
  import { promises as fs3 } from "node:fs";
3316
3324
  import os3 from "node:os";
3317
3325
  import path3 from "node:path";
3318
- async function safeReaddir2(p) {
3319
- return fs3.readdir(p).catch(() => []);
3326
+ function recordOf(value) {
3327
+ return typeof value === "object" && value !== null ? value : void 0;
3328
+ }
3329
+ function stringOf(value) {
3330
+ return typeof value === "string" ? value : void 0;
3331
+ }
3332
+ function numberOf2(value) {
3333
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
3334
+ }
3335
+ function emptyUsage2() {
3336
+ return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
3337
+ }
3338
+ function previewOf2(value) {
3339
+ const text = typeof value === "string" ? value : JSON.stringify(value ?? "");
3340
+ return text.replace(/\s+/g, " ").trim().slice(0, 200);
3341
+ }
3342
+ function tokenCount(details, key) {
3343
+ return numberOf2(recordOf(details?.[key])?.tokenCount);
3344
+ }
3345
+ function syntheticProjectDir(cwd) {
3346
+ return cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : "(unknown)";
3320
3347
  }
3321
3348
  async function listSessionFiles(root) {
3349
+ const entries = await fs3.readdir(root, { withFileTypes: true }).catch(() => []);
3350
+ const out = [];
3351
+ for (const entry of entries) {
3352
+ if (!entry.isDirectory())
3353
+ continue;
3354
+ const filePath = path3.join(root, entry.name, "events.jsonl");
3355
+ const stat = await fs3.stat(filePath).catch(() => null);
3356
+ if (!stat?.isFile())
3357
+ continue;
3358
+ out.push({
3359
+ filePath,
3360
+ sessionId: entry.name,
3361
+ mtimeMs: stat.mtimeMs,
3362
+ sizeBytes: stat.size
3363
+ });
3364
+ }
3365
+ return out;
3366
+ }
3367
+ async function readJsonl2(filePath) {
3368
+ const raw = await fs3.readFile(filePath, "utf8");
3369
+ const out = [];
3370
+ for (const line of raw.split("\n")) {
3371
+ const trimmed = line.trim();
3372
+ if (!trimmed)
3373
+ continue;
3374
+ try {
3375
+ out.push(JSON.parse(trimmed));
3376
+ } catch {
3377
+ }
3378
+ }
3379
+ return out;
3380
+ }
3381
+ function computeActiveSegments3(timestamps) {
3382
+ const sorted = [...new Set(timestamps)].sort((a, b) => a - b);
3383
+ if (sorted.length === 0)
3384
+ return [];
3385
+ const segments = [];
3386
+ let start = sorted[0];
3387
+ let end = start;
3388
+ for (let i = 1; i < sorted.length; i++) {
3389
+ const next = sorted[i];
3390
+ if (next - end > IDLE_GAP_MS2) {
3391
+ segments.push({ startMs: start, endMs: end });
3392
+ start = next;
3393
+ }
3394
+ end = next;
3395
+ }
3396
+ segments.push({ startMs: start, endMs: end });
3397
+ return segments;
3398
+ }
3399
+ function parseSession(file, lines) {
3400
+ const records = lines.map(recordOf).filter((line) => line !== void 0);
3401
+ const executionCallIds = /* @__PURE__ */ new Set();
3402
+ for (const record of records) {
3403
+ if (record.type !== "tool.execution_start")
3404
+ continue;
3405
+ const callId = stringOf(recordOf(record.data)?.toolCallId);
3406
+ if (callId)
3407
+ executionCallIds.add(callId);
3408
+ }
3409
+ const events = [];
3410
+ const timestamps = [];
3411
+ const totalUsage = emptyUsage2();
3412
+ let firstMs;
3413
+ let lastMs;
3414
+ let cwd;
3415
+ let repository;
3416
+ let gitBranch;
3417
+ let model;
3418
+ let firstUserPreview;
3419
+ let lastUserPreview;
3420
+ let lastAgentPreview;
3421
+ let toolCallCount = 0;
3422
+ let turnCount = 0;
3423
+ let observedOutput = 0;
3424
+ let sawShutdown = false;
3425
+ let linesAdded;
3426
+ let linesRemoved;
3427
+ let filesEdited;
3428
+ let idx = 0;
3429
+ function push(event) {
3430
+ events.push({ index: idx++, ...event });
3431
+ }
3432
+ for (const obj of records) {
3433
+ const type = stringOf(obj.type) ?? "";
3434
+ const data = recordOf(obj.data) ?? {};
3435
+ const timestamp = stringOf(obj.timestamp);
3436
+ if (timestamp) {
3437
+ const ms = Date.parse(timestamp);
3438
+ if (Number.isFinite(ms)) {
3439
+ timestamps.push(ms);
3440
+ firstMs = firstMs === void 0 ? ms : Math.min(firstMs, ms);
3441
+ lastMs = lastMs === void 0 ? ms : Math.max(lastMs, ms);
3442
+ }
3443
+ }
3444
+ if (type === "session.start") {
3445
+ const context = recordOf(data.context);
3446
+ cwd = stringOf(context?.cwd) ?? cwd;
3447
+ repository = stringOf(context?.repository) ?? repository;
3448
+ gitBranch = stringOf(context?.branch) ?? gitBranch;
3449
+ push({
3450
+ timestamp,
3451
+ role: "meta",
3452
+ rawType: type,
3453
+ preview: "Copilot session started",
3454
+ blocks: [],
3455
+ raw: obj
3456
+ });
3457
+ continue;
3458
+ }
3459
+ if (type === "session.model_change") {
3460
+ const selected = stringOf(data.newModel);
3461
+ if (selected && selected !== "auto")
3462
+ model = selected;
3463
+ } else if (type === "session.auto_mode_resolved") {
3464
+ model = stringOf(data.chosenModel) ?? model;
3465
+ } else if (type === "assistant.turn_start" || type === "assistant.message") {
3466
+ model = stringOf(data.model) ?? model;
3467
+ }
3468
+ if (type === "system.message") {
3469
+ push({
3470
+ timestamp,
3471
+ role: "system",
3472
+ rawType: type,
3473
+ preview: "Copilot system instructions",
3474
+ blocks: [],
3475
+ raw: obj
3476
+ });
3477
+ continue;
3478
+ }
3479
+ if (type === "user.message") {
3480
+ const text = stringOf(data.content) ?? "";
3481
+ const preview = previewOf2(text);
3482
+ if (text && !isFrameworkInjectedUserInput(text)) {
3483
+ firstUserPreview ??= preview;
3484
+ lastUserPreview = preview;
3485
+ turnCount += 1;
3486
+ }
3487
+ push({
3488
+ timestamp,
3489
+ role: "user",
3490
+ rawType: type,
3491
+ preview,
3492
+ blocks: text ? [{ type: "text", text }] : [],
3493
+ raw: obj
3494
+ });
3495
+ continue;
3496
+ }
3497
+ if (type === "assistant.message") {
3498
+ const text = stringOf(data.content) ?? "";
3499
+ const outputTokens = numberOf2(data.outputTokens) ?? 0;
3500
+ observedOutput += outputTokens;
3501
+ if (text) {
3502
+ const preview = previewOf2(text);
3503
+ lastAgentPreview = preview;
3504
+ push({
3505
+ timestamp,
3506
+ role: "agent",
3507
+ rawType: type,
3508
+ messageId: stringOf(data.messageId),
3509
+ preview,
3510
+ blocks: [{ type: "text", text }],
3511
+ model,
3512
+ raw: obj
3513
+ });
3514
+ }
3515
+ const requests = Array.isArray(data.toolRequests) ? data.toolRequests : [];
3516
+ for (const requestValue of requests) {
3517
+ const request = recordOf(requestValue);
3518
+ if (!request)
3519
+ continue;
3520
+ const callId = stringOf(request.toolCallId);
3521
+ if (callId && executionCallIds.has(callId))
3522
+ continue;
3523
+ const name = stringOf(request.name) ?? "(unknown)";
3524
+ const input = recordOf(request.arguments) ?? request.arguments ?? null;
3525
+ toolCallCount += 1;
3526
+ push({
3527
+ timestamp,
3528
+ role: "tool-call",
3529
+ rawType: "assistant.message/tool_request",
3530
+ preview: `${name}(${previewOf2(input).slice(0, 80)})`,
3531
+ blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
3532
+ toolName: name,
3533
+ toolUseId: callId,
3534
+ model,
3535
+ raw: obj
3536
+ });
3537
+ }
3538
+ continue;
3539
+ }
3540
+ if (type === "tool.execution_start") {
3541
+ const callId = stringOf(data.toolCallId);
3542
+ const name = stringOf(data.toolName) ?? "(unknown)";
3543
+ const input = data.arguments ?? null;
3544
+ toolCallCount += 1;
3545
+ push({
3546
+ timestamp,
3547
+ role: "tool-call",
3548
+ rawType: type,
3549
+ preview: `${name}(${previewOf2(input).slice(0, 80)})`,
3550
+ blocks: [{ type: "tool_use", id: callId ?? `copilot-${idx}`, name, input }],
3551
+ toolName: name,
3552
+ toolUseId: callId,
3553
+ model: stringOf(data.model) ?? model,
3554
+ raw: obj
3555
+ });
3556
+ continue;
3557
+ }
3558
+ if (type === "tool.execution_complete") {
3559
+ const callId = stringOf(data.toolCallId);
3560
+ const resultRecord = recordOf(data.result);
3561
+ const result = resultRecord && "content" in resultRecord ? resultRecord.content : data.result;
3562
+ const success = data.success !== false;
3563
+ push({
3564
+ timestamp,
3565
+ role: "tool-result",
3566
+ rawType: type,
3567
+ preview: previewOf2(result),
3568
+ blocks: [{ type: "tool_result", tool_use_id: callId ?? "", content: result, is_error: !success }],
3569
+ toolUseId: callId,
3570
+ toolResult: data.result,
3571
+ raw: obj
3572
+ });
3573
+ continue;
3574
+ }
3575
+ if (type === "assistant.reasoning") {
3576
+ const text = stringOf(data.content) ?? "";
3577
+ push({
3578
+ timestamp,
3579
+ role: "agent-thinking",
3580
+ rawType: type,
3581
+ preview: previewOf2(text),
3582
+ blocks: text ? [{ type: "thinking", thinking: text }] : [],
3583
+ model,
3584
+ raw: obj
3585
+ });
3586
+ continue;
3587
+ }
3588
+ if (type === "session.shutdown") {
3589
+ sawShutdown = true;
3590
+ model = stringOf(data.currentModel) ?? model;
3591
+ const details = recordOf(data.tokenDetails);
3592
+ totalUsage.input = tokenCount(details, "input") ?? totalUsage.input;
3593
+ totalUsage.output = tokenCount(details, "output") ?? observedOutput;
3594
+ totalUsage.cacheRead = tokenCount(details, "cache_read") ?? totalUsage.cacheRead;
3595
+ totalUsage.cacheWrite = tokenCount(details, "cache_write") ?? totalUsage.cacheWrite;
3596
+ const changes = recordOf(data.codeChanges);
3597
+ linesAdded = numberOf2(changes?.linesAdded);
3598
+ linesRemoved = numberOf2(changes?.linesRemoved);
3599
+ const modified = changes?.filesModified;
3600
+ filesEdited = Array.isArray(modified) ? modified.length : void 0;
3601
+ }
3602
+ push({
3603
+ timestamp,
3604
+ role: "meta",
3605
+ rawType: type,
3606
+ preview: "",
3607
+ blocks: [],
3608
+ raw: obj
3609
+ });
3610
+ }
3611
+ if (totalUsage.output === 0)
3612
+ totalUsage.output = observedOutput;
3613
+ if (totalUsage.input || totalUsage.output || totalUsage.cacheRead || totalUsage.cacheWrite) {
3614
+ const usageEvent = [...events].reverse().find((event) => event.role === "agent" || event.role === "agent-thinking" || event.role === "tool-call");
3615
+ if (usageEvent) {
3616
+ usageEvent.messageId = `copilot-${file.sessionId}-total`;
3617
+ usageEvent.usage = { ...totalUsage };
3618
+ }
3619
+ }
3620
+ const firstTimestamp = firstMs === void 0 ? void 0 : new Date(firstMs).toISOString();
3621
+ const lastTimestamp = lastMs === void 0 ? void 0 : new Date(lastMs).toISOString();
3622
+ if (firstMs !== void 0) {
3623
+ let previousMs;
3624
+ for (const event of events) {
3625
+ if (!event.timestamp)
3626
+ continue;
3627
+ const ms = Date.parse(event.timestamp);
3628
+ if (!Number.isFinite(ms))
3629
+ continue;
3630
+ event.tOffsetMs = Math.max(0, ms - firstMs);
3631
+ if (previousMs !== void 0)
3632
+ event.gapMs = Math.max(0, ms - previousMs);
3633
+ previousMs = ms;
3634
+ }
3635
+ }
3636
+ const activeSegments = computeActiveSegments3(timestamps);
3637
+ const airTimeMs = activeSegments.reduce((sum, segment) => sum + segment.endMs - segment.startMs, 0);
3638
+ const project = cwd ? resolveProjectIdentity(cwd) : void 0;
3639
+ const repoName = project?.repoName ?? repository?.split("/").filter(Boolean).at(-1);
3640
+ const meta = {
3641
+ agent: "copilot",
3642
+ id: file.sessionId,
3643
+ filePath: file.filePath,
3644
+ projectName: project?.projectName ?? cwd ?? "(unknown)",
3645
+ worktreeName: project?.worktreeName,
3646
+ repoName,
3647
+ projectDir: syntheticProjectDir(cwd),
3648
+ sessionId: file.sessionId,
3649
+ firstTimestamp,
3650
+ lastTimestamp,
3651
+ lastActivityMs: file.mtimeMs,
3652
+ durationMs: firstMs !== void 0 && lastMs !== void 0 ? lastMs - firstMs : void 0,
3653
+ eventCount: events.length,
3654
+ model,
3655
+ cwd,
3656
+ gitBranch,
3657
+ totalUsage,
3658
+ status: sawShutdown || Date.now() - file.mtimeMs > IDLE_GAP_MS2 ? "idle" : "running",
3659
+ firstUserPreview,
3660
+ lastUserPreview,
3661
+ lastAgentPreview,
3662
+ toolCallCount,
3663
+ turnCount,
3664
+ linesAdded,
3665
+ linesRemoved,
3666
+ filesEdited,
3667
+ airTimeMs,
3668
+ activeSegments
3669
+ };
3670
+ return { meta, events };
3671
+ }
3672
+ function clearCopilotCaches() {
3673
+ metaCache3.clear();
3674
+ detailCache3.clear();
3675
+ }
3676
+ async function scanCopilot(root) {
3677
+ const files = await listSessionFiles(root);
3678
+ const out = [];
3679
+ for (const file of files) {
3680
+ const cached = metaCache3.get(file.filePath);
3681
+ if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3682
+ out.push({ file, meta: cached.meta });
3683
+ continue;
3684
+ }
3685
+ try {
3686
+ const lines = await readJsonl2(file.filePath);
3687
+ const { meta } = parseSession(file, lines);
3688
+ metaCache3.set(file.filePath, { meta, mtimeMs: file.mtimeMs, sizeBytes: file.sizeBytes });
3689
+ out.push({ file, meta });
3690
+ } catch {
3691
+ }
3692
+ }
3693
+ return out;
3694
+ }
3695
+ async function listCopilotSessions(opts = {}) {
3696
+ const root = opts.root ?? DEFAULT_COPILOT_ROOT;
3697
+ const sessions = (await scanCopilot(root)).map((entry) => entry.meta);
3698
+ sessions.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
3699
+ return opts.limit === void 0 ? sessions : sessions.slice(0, opts.limit);
3700
+ }
3701
+ async function getCopilotSession(id, opts = {}) {
3702
+ const root = opts.root ?? DEFAULT_COPILOT_ROOT;
3703
+ const entry = (await scanCopilot(root)).find((candidate) => candidate.meta.id === id);
3704
+ if (!entry)
3705
+ return null;
3706
+ const cached = detailCache3.get(entry.file.filePath);
3707
+ if (cached && cached.mtimeMs === entry.file.mtimeMs && cached.sizeBytes === entry.file.sizeBytes) {
3708
+ return cached.detail;
3709
+ }
3710
+ const lines = await readJsonl2(entry.file.filePath);
3711
+ const { meta, events } = parseSession(entry.file, lines);
3712
+ const detail = { ...meta, events };
3713
+ detailCache3.set(entry.file.filePath, {
3714
+ detail,
3715
+ mtimeMs: entry.file.mtimeMs,
3716
+ sizeBytes: entry.file.sizeBytes
3717
+ });
3718
+ return detail;
3719
+ }
3720
+ function copilotSessionLocalDay(meta) {
3721
+ if (!meta.firstTimestamp)
3722
+ return void 0;
3723
+ const ms = Date.parse(meta.firstTimestamp);
3724
+ return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
3725
+ }
3726
+ var DEFAULT_COPILOT_ROOT, IDLE_GAP_MS2, metaCache3, detailCache3;
3727
+ var init_copilot = __esm({
3728
+ "../parser/dist/copilot.js"() {
3729
+ "use strict";
3730
+ init_analytics();
3731
+ init_git_project();
3732
+ init_user_input();
3733
+ DEFAULT_COPILOT_ROOT = path3.join(os3.homedir(), ".copilot", "session-state");
3734
+ IDLE_GAP_MS2 = 3 * 60 * 1e3;
3735
+ metaCache3 = /* @__PURE__ */ new Map();
3736
+ detailCache3 = /* @__PURE__ */ new Map();
3737
+ }
3738
+ });
3739
+
3740
+ // ../parser/dist/gemini.js
3741
+ import { promises as fs4 } from "node:fs";
3742
+ import os4 from "node:os";
3743
+ import path4 from "node:path";
3744
+ async function safeReaddir2(p) {
3745
+ return fs4.readdir(p).catch(() => []);
3746
+ }
3747
+ async function listSessionFiles2(root) {
3322
3748
  const out = [];
3323
3749
  const slugs = await safeReaddir2(root);
3324
3750
  for (const slug of slugs) {
3325
- const chatsDir = path3.join(root, slug, "chats");
3751
+ const chatsDir = path4.join(root, slug, "chats");
3326
3752
  const entries = await safeReaddir2(chatsDir);
3327
3753
  for (const entry of entries) {
3328
3754
  if (!SESSION_FILE_RE.test(entry))
3329
3755
  continue;
3330
- const full = path3.join(chatsDir, entry);
3331
- const stat = await fs3.stat(full).catch(() => null);
3756
+ const full = path4.join(chatsDir, entry);
3757
+ const stat = await fs4.stat(full).catch(() => null);
3332
3758
  if (!stat || !stat.isFile())
3333
3759
  continue;
3334
3760
  const filenameId = entry.replace(/\.(jsonl|json)$/, "").split("-").pop() ?? entry;
@@ -3345,13 +3771,13 @@ async function listSessionFiles(root) {
3345
3771
  return out;
3346
3772
  }
3347
3773
  async function loadSlugToCwd() {
3348
- const stat = await fs3.stat(GEMINI_PROJECTS_FILE).catch(() => null);
3774
+ const stat = await fs4.stat(GEMINI_PROJECTS_FILE).catch(() => null);
3349
3775
  if (!stat)
3350
3776
  return /* @__PURE__ */ new Map();
3351
3777
  if (projectsCache && projectsCache.mtimeMs === stat.mtimeMs) {
3352
3778
  return projectsCache.slugToCwd;
3353
3779
  }
3354
- const raw = await fs3.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
3780
+ const raw = await fs4.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
3355
3781
  let parsed;
3356
3782
  try {
3357
3783
  parsed = JSON.parse(raw);
@@ -3376,7 +3802,7 @@ function isMessageRecord(o) {
3376
3802
  return !!o && typeof o === "object" && typeof o.id === "string" && typeof o.type === "string";
3377
3803
  }
3378
3804
  async function readAndReplay(file) {
3379
- const raw = await fs3.readFile(file.filePath, "utf8");
3805
+ const raw = await fs4.readFile(file.filePath, "utf8");
3380
3806
  if (file.format === "legacy-json") {
3381
3807
  let blob;
3382
3808
  try {
@@ -3451,10 +3877,10 @@ async function readAndReplay(file) {
3451
3877
  }
3452
3878
  return { meta, messages };
3453
3879
  }
3454
- function emptyUsage2() {
3880
+ function emptyUsage3() {
3455
3881
  return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
3456
3882
  }
3457
- function previewOf2(text) {
3883
+ function previewOf3(text) {
3458
3884
  return text.replace(/\s+/g, " ").trim().slice(0, 200);
3459
3885
  }
3460
3886
  function flattenContent(c) {
@@ -3493,12 +3919,12 @@ function flattenContent(c) {
3493
3919
  function truncate3(s, n) {
3494
3920
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
3495
3921
  }
3496
- async function parseSession(file) {
3922
+ async function parseSession2(file) {
3497
3923
  const { meta: metaRec, messages } = await readAndReplay(file);
3498
3924
  const slugToCwd = await loadSlugToCwd();
3499
3925
  const cwd = slugToCwd.get(file.slug);
3500
3926
  const events = [];
3501
- const totalUsage = emptyUsage2();
3927
+ const totalUsage = emptyUsage3();
3502
3928
  let firstTimestamp;
3503
3929
  let lastTimestamp;
3504
3930
  let model;
@@ -3524,7 +3950,7 @@ async function parseSession(file) {
3524
3950
  const ts = msg.timestamp;
3525
3951
  if (msg.type === "user") {
3526
3952
  const text = flattenContent(msg.displayContent ?? msg.content);
3527
- const preview = previewOf2(text);
3953
+ const preview = previewOf3(text);
3528
3954
  const isHidden = isFrameworkInjectedUserInput(text);
3529
3955
  if (text && !isHidden) {
3530
3956
  if (!firstUserPreview)
@@ -3548,7 +3974,7 @@ async function parseSession(file) {
3548
3974
  if (typeof msg.model === "string")
3549
3975
  model = msg.model;
3550
3976
  const text = flattenContent(msg.content);
3551
- const preview = previewOf2(text);
3977
+ const preview = previewOf3(text);
3552
3978
  if (text)
3553
3979
  lastAgentPreview = preview;
3554
3980
  let usage;
@@ -3574,7 +4000,7 @@ async function parseSession(file) {
3574
4000
  timestamp: th.timestamp ?? ts,
3575
4001
  role: "agent-thinking",
3576
4002
  rawType: "gemini/thought",
3577
- preview: previewOf2(thText),
4003
+ preview: previewOf3(thText),
3578
4004
  blocks: [{ type: "thinking", thinking: thText }],
3579
4005
  model,
3580
4006
  raw: th
@@ -3631,7 +4057,7 @@ async function parseSession(file) {
3631
4057
  timestamp: tc.timestamp ?? ts,
3632
4058
  role: "tool-result",
3633
4059
  rawType: "gemini/tool_result",
3634
- preview: previewOf2(resultText),
4060
+ preview: previewOf3(resultText),
3635
4061
  blocks: [
3636
4062
  {
3637
4063
  type: "tool_result",
@@ -3655,7 +4081,7 @@ async function parseSession(file) {
3655
4081
  timestamp: ts,
3656
4082
  role: "meta",
3657
4083
  rawType: `gemini/${msg.type}`,
3658
- preview: previewOf2(text),
4084
+ preview: previewOf3(text),
3659
4085
  blocks: text ? [{ type: "text", text }] : [],
3660
4086
  raw: msg
3661
4087
  });
@@ -3677,7 +4103,7 @@ async function parseSession(file) {
3677
4103
  prevMs = ms;
3678
4104
  }
3679
4105
  }
3680
- const activeSegments = computeActiveSegments3(tsMs);
4106
+ const activeSegments = computeActiveSegments4(tsMs);
3681
4107
  const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
3682
4108
  const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
3683
4109
  const sessionId = metaRec.sessionId ?? file.filenameId;
@@ -3711,7 +4137,7 @@ async function parseSession(file) {
3711
4137
  };
3712
4138
  return { meta, events };
3713
4139
  }
3714
- function computeActiveSegments3(tsMs) {
4140
+ function computeActiveSegments4(tsMs) {
3715
4141
  if (tsMs.length === 0)
3716
4142
  return [];
3717
4143
  const sorted = [...tsMs].sort((a, b) => a - b);
@@ -3719,7 +4145,7 @@ function computeActiveSegments3(tsMs) {
3719
4145
  let segStart = sorted[0];
3720
4146
  let segEnd = sorted[0];
3721
4147
  for (let i = 1; i < sorted.length; i++) {
3722
- if (sorted[i] - segEnd > IDLE_GAP_MS2) {
4148
+ if (sorted[i] - segEnd > IDLE_GAP_MS3) {
3723
4149
  out.push({ startMs: segStart, endMs: segEnd });
3724
4150
  segStart = sorted[i];
3725
4151
  }
@@ -3729,23 +4155,23 @@ function computeActiveSegments3(tsMs) {
3729
4155
  return out;
3730
4156
  }
3731
4157
  function clearGeminiCaches() {
3732
- metaCache3.clear();
3733
- detailCache3.clear();
4158
+ metaCache4.clear();
4159
+ detailCache4.clear();
3734
4160
  projectsCache = null;
3735
4161
  }
3736
4162
  async function listGeminiSessions(opts = {}) {
3737
4163
  const root = opts.root ?? DEFAULT_GEMINI_ROOT;
3738
- const files = await listSessionFiles(root);
4164
+ const files = await listSessionFiles2(root);
3739
4165
  const out = [];
3740
4166
  for (const file of files) {
3741
- const cached = metaCache3.get(file.filePath);
4167
+ const cached = metaCache4.get(file.filePath);
3742
4168
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3743
4169
  out.push(cached.meta);
3744
4170
  continue;
3745
4171
  }
3746
4172
  try {
3747
- const { meta } = await parseSession(file);
3748
- metaCache3.set(file.filePath, {
4173
+ const { meta } = await parseSession2(file);
4174
+ metaCache4.set(file.filePath, {
3749
4175
  meta,
3750
4176
  mtimeMs: file.mtimeMs,
3751
4177
  sizeBytes: file.sizeBytes
@@ -3761,7 +4187,7 @@ async function listGeminiSessions(opts = {}) {
3761
4187
  }
3762
4188
  async function getGeminiSession(id, opts = {}) {
3763
4189
  const root = opts.root ?? DEFAULT_GEMINI_ROOT;
3764
- const files = await listSessionFiles(root);
4190
+ const files = await listSessionFiles2(root);
3765
4191
  let chosen;
3766
4192
  for (const file of files) {
3767
4193
  if (file.filenameId === id || id.startsWith(file.filenameId)) {
@@ -3771,7 +4197,7 @@ async function getGeminiSession(id, opts = {}) {
3771
4197
  }
3772
4198
  if (!chosen) {
3773
4199
  for (const file of files) {
3774
- const { meta: meta2 } = await parseSession(file).catch(() => ({ meta: { id: "" } }));
4200
+ const { meta: meta2 } = await parseSession2(file).catch(() => ({ meta: { id: "" } }));
3775
4201
  if (meta2.id === id) {
3776
4202
  chosen = file;
3777
4203
  break;
@@ -3780,13 +4206,13 @@ async function getGeminiSession(id, opts = {}) {
3780
4206
  }
3781
4207
  if (!chosen)
3782
4208
  return null;
3783
- const cached = detailCache3.get(chosen.filePath);
4209
+ const cached = detailCache4.get(chosen.filePath);
3784
4210
  if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
3785
4211
  return cached.detail;
3786
4212
  }
3787
- const { meta, events } = await parseSession(chosen);
4213
+ const { meta, events } = await parseSession2(chosen);
3788
4214
  const detail = { ...meta, events };
3789
- detailCache3.set(chosen.filePath, {
4215
+ detailCache4.set(chosen.filePath, {
3790
4216
  detail,
3791
4217
  mtimeMs: chosen.mtimeMs,
3792
4218
  sizeBytes: chosen.sizeBytes
@@ -3799,39 +4225,39 @@ function geminiSessionLocalDay(meta) {
3799
4225
  const ms = Date.parse(meta.firstTimestamp);
3800
4226
  return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
3801
4227
  }
3802
- var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS2, projectsCache, metaCache3, detailCache3;
4228
+ var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS3, projectsCache, metaCache4, detailCache4;
3803
4229
  var init_gemini = __esm({
3804
4230
  "../parser/dist/gemini.js"() {
3805
4231
  "use strict";
3806
4232
  init_analytics();
3807
4233
  init_git_project();
3808
4234
  init_user_input();
3809
- DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
3810
- GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
4235
+ DEFAULT_GEMINI_ROOT = path4.join(os4.homedir(), ".gemini", "tmp");
4236
+ GEMINI_PROJECTS_FILE = path4.join(os4.homedir(), ".gemini", "projects.json");
3811
4237
  SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
3812
- IDLE_GAP_MS2 = 3 * 60 * 1e3;
4238
+ IDLE_GAP_MS3 = 3 * 60 * 1e3;
3813
4239
  projectsCache = null;
3814
- metaCache3 = /* @__PURE__ */ new Map();
3815
- detailCache3 = /* @__PURE__ */ new Map();
4240
+ metaCache4 = /* @__PURE__ */ new Map();
4241
+ detailCache4 = /* @__PURE__ */ new Map();
3816
4242
  }
3817
4243
  });
3818
4244
 
3819
4245
  // ../parser/dist/antigravity.js
3820
- import { promises as fs4 } from "node:fs";
3821
- import os4 from "node:os";
3822
- import path4 from "node:path";
4246
+ import { promises as fs5 } from "node:fs";
4247
+ import os5 from "node:os";
4248
+ import path5 from "node:path";
3823
4249
  async function safeReaddir3(p) {
3824
- return fs4.readdir(p).catch(() => []);
4250
+ return fs5.readdir(p).catch(() => []);
3825
4251
  }
3826
4252
  async function loadSlugToCwd2(root) {
3827
- const historyFile = path4.join(root, "history.jsonl");
3828
- const stat = await fs4.stat(historyFile).catch(() => null);
4253
+ const historyFile = path5.join(root, "history.jsonl");
4254
+ const stat = await fs5.stat(historyFile).catch(() => null);
3829
4255
  if (!stat)
3830
4256
  return /* @__PURE__ */ new Map();
3831
4257
  if (historyCache && historyCache.mtimeMs === stat.mtimeMs) {
3832
4258
  return historyCache.slugToCwd;
3833
4259
  }
3834
- const raw = await fs4.readFile(historyFile, "utf8").catch(() => "");
4260
+ const raw = await fs5.readFile(historyFile, "utf8").catch(() => "");
3835
4261
  const slugToCwd = /* @__PURE__ */ new Map();
3836
4262
  for (const line of raw.split("\n")) {
3837
4263
  const trimmed = line.trim();
@@ -3848,14 +4274,14 @@ async function loadSlugToCwd2(root) {
3848
4274
  historyCache = { mtimeMs: stat.mtimeMs, slugToCwd };
3849
4275
  return slugToCwd;
3850
4276
  }
3851
- async function listSessionFiles2(root) {
4277
+ async function listSessionFiles3(root) {
3852
4278
  const slugToCwd = await loadSlugToCwd2(root);
3853
4279
  const out = [];
3854
- const brainDir = path4.join(root, "brain");
4280
+ const brainDir = path5.join(root, "brain");
3855
4281
  const entries = await safeReaddir3(brainDir);
3856
4282
  for (const entry of entries) {
3857
- const transcriptPath = path4.join(brainDir, entry, ".system_generated", "logs", "transcript.jsonl");
3858
- const stat = await fs4.stat(transcriptPath).catch(() => null);
4283
+ const transcriptPath = path5.join(brainDir, entry, ".system_generated", "logs", "transcript.jsonl");
4284
+ const stat = await fs5.stat(transcriptPath).catch(() => null);
3859
4285
  if (stat && stat.isFile()) {
3860
4286
  out.push({
3861
4287
  filePath: transcriptPath,
@@ -3868,19 +4294,19 @@ async function listSessionFiles2(root) {
3868
4294
  }
3869
4295
  return out;
3870
4296
  }
3871
- function emptyUsage3() {
4297
+ function emptyUsage4() {
3872
4298
  return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
3873
4299
  }
3874
- function previewOf3(text) {
4300
+ function previewOf4(text) {
3875
4301
  return text.replace(/\s+/g, " ").trim().slice(0, 200);
3876
4302
  }
3877
4303
  function truncate4(s, n) {
3878
4304
  return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
3879
4305
  }
3880
- async function parseSession2(file) {
3881
- const raw = await fs4.readFile(file.filePath, "utf8");
4306
+ async function parseSession3(file) {
4307
+ const raw = await fs5.readFile(file.filePath, "utf8");
3882
4308
  const events = [];
3883
- const totalUsage = emptyUsage3();
4309
+ const totalUsage = emptyUsage4();
3884
4310
  let firstTimestamp;
3885
4311
  let lastTimestamp;
3886
4312
  let model;
@@ -3952,7 +4378,7 @@ async function parseSession2(file) {
3952
4378
  if (requestMatch) {
3953
4379
  text2 = requestMatch[1].trim();
3954
4380
  }
3955
- const preview = previewOf3(text2);
4381
+ const preview = previewOf4(text2);
3956
4382
  const isHidden = isFrameworkInjectedUserInput(text2);
3957
4383
  if (text2 && !isHidden) {
3958
4384
  if (!firstUserPreview)
@@ -3981,14 +4407,14 @@ async function parseSession2(file) {
3981
4407
  timestamp: ts,
3982
4408
  role: "agent-thinking",
3983
4409
  rawType: "antigravity/thought",
3984
- preview: previewOf3(thinking),
4410
+ preview: previewOf4(thinking),
3985
4411
  blocks: [{ type: "thinking", thinking }],
3986
4412
  model,
3987
4413
  raw: eventObj
3988
4414
  });
3989
4415
  }
3990
4416
  if (content) {
3991
- const preview = previewOf3(content);
4417
+ const preview = previewOf4(content);
3992
4418
  lastAgentPreview = preview;
3993
4419
  pushEvent({
3994
4420
  index: idx++,
@@ -4034,7 +4460,7 @@ async function parseSession2(file) {
4034
4460
  timestamp: ts,
4035
4461
  role: "tool-result",
4036
4462
  rawType: "antigravity/tool_result",
4037
- preview: previewOf3(contentStr),
4463
+ preview: previewOf4(contentStr),
4038
4464
  blocks: [{
4039
4465
  type: "tool_result",
4040
4466
  tool_use_id: toolUseId,
@@ -4053,7 +4479,7 @@ async function parseSession2(file) {
4053
4479
  timestamp: ts,
4054
4480
  role: "meta",
4055
4481
  rawType: `antigravity/${eventObj.type?.toLowerCase() || "unknown"}`,
4056
- preview: previewOf3(text),
4482
+ preview: previewOf4(text),
4057
4483
  blocks: text ? [{ type: "text", text }] : [],
4058
4484
  raw: eventObj
4059
4485
  });
@@ -4073,7 +4499,7 @@ async function parseSession2(file) {
4073
4499
  prevMs = ms;
4074
4500
  }
4075
4501
  }
4076
- const activeSegments = computeActiveSegments4(tsMs);
4502
+ const activeSegments = computeActiveSegments5(tsMs);
4077
4503
  const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
4078
4504
  const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
4079
4505
  const sessionId = file.conversationId;
@@ -4108,7 +4534,7 @@ async function parseSession2(file) {
4108
4534
  };
4109
4535
  return { meta, events };
4110
4536
  }
4111
- function computeActiveSegments4(tsMs) {
4537
+ function computeActiveSegments5(tsMs) {
4112
4538
  if (tsMs.length === 0)
4113
4539
  return [];
4114
4540
  const sorted = [...tsMs].sort((a, b) => a - b);
@@ -4116,7 +4542,7 @@ function computeActiveSegments4(tsMs) {
4116
4542
  let segStart = sorted[0];
4117
4543
  let segEnd = sorted[0];
4118
4544
  for (let i = 1; i < sorted.length; i++) {
4119
- if (sorted[i] - segEnd > IDLE_GAP_MS3) {
4545
+ if (sorted[i] - segEnd > IDLE_GAP_MS4) {
4120
4546
  out.push({ startMs: segStart, endMs: segEnd });
4121
4547
  segStart = sorted[i];
4122
4548
  }
@@ -4126,23 +4552,23 @@ function computeActiveSegments4(tsMs) {
4126
4552
  return out;
4127
4553
  }
4128
4554
  function clearAntigravityCaches() {
4129
- metaCache4.clear();
4130
- detailCache4.clear();
4555
+ metaCache5.clear();
4556
+ detailCache5.clear();
4131
4557
  historyCache = null;
4132
4558
  }
4133
4559
  async function listAntigravitySessions(opts = {}) {
4134
4560
  const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
4135
- const files = await listSessionFiles2(root);
4561
+ const files = await listSessionFiles3(root);
4136
4562
  const out = [];
4137
4563
  for (const file of files) {
4138
- const cached = metaCache4.get(file.filePath);
4564
+ const cached = metaCache5.get(file.filePath);
4139
4565
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes && cached.cwd === file.cwd) {
4140
4566
  out.push(cached.meta);
4141
4567
  continue;
4142
4568
  }
4143
4569
  try {
4144
- const { meta } = await parseSession2(file);
4145
- metaCache4.set(file.filePath, {
4570
+ const { meta } = await parseSession3(file);
4571
+ metaCache5.set(file.filePath, {
4146
4572
  meta,
4147
4573
  mtimeMs: file.mtimeMs,
4148
4574
  sizeBytes: file.sizeBytes,
@@ -4159,7 +4585,7 @@ async function listAntigravitySessions(opts = {}) {
4159
4585
  }
4160
4586
  async function getAntigravitySession(id, opts = {}) {
4161
4587
  const root = opts.root ?? DEFAULT_ANTIGRAVITY_ROOT;
4162
- const files = await listSessionFiles2(root);
4588
+ const files = await listSessionFiles3(root);
4163
4589
  let chosen;
4164
4590
  for (const file of files) {
4165
4591
  if (file.conversationId === id) {
@@ -4169,13 +4595,13 @@ async function getAntigravitySession(id, opts = {}) {
4169
4595
  }
4170
4596
  if (!chosen)
4171
4597
  return null;
4172
- const cached = detailCache4.get(chosen.filePath);
4598
+ const cached = detailCache5.get(chosen.filePath);
4173
4599
  if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes && cached.cwd === chosen.cwd) {
4174
4600
  return cached.detail;
4175
4601
  }
4176
- const { meta, events } = await parseSession2(chosen);
4602
+ const { meta, events } = await parseSession3(chosen);
4177
4603
  const detail = { ...meta, events };
4178
- detailCache4.set(chosen.filePath, {
4604
+ detailCache5.set(chosen.filePath, {
4179
4605
  detail,
4180
4606
  mtimeMs: chosen.mtimeMs,
4181
4607
  sizeBytes: chosen.sizeBytes,
@@ -4189,61 +4615,61 @@ function antigravitySessionLocalDay(meta) {
4189
4615
  const ms = Date.parse(meta.firstTimestamp);
4190
4616
  return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
4191
4617
  }
4192
- var DEFAULT_ANTIGRAVITY_ROOT, IDLE_GAP_MS3, historyCache, metaCache4, detailCache4;
4618
+ var DEFAULT_ANTIGRAVITY_ROOT, IDLE_GAP_MS4, historyCache, metaCache5, detailCache5;
4193
4619
  var init_antigravity = __esm({
4194
4620
  "../parser/dist/antigravity.js"() {
4195
4621
  "use strict";
4196
4622
  init_analytics();
4197
4623
  init_git_project();
4198
4624
  init_user_input();
4199
- DEFAULT_ANTIGRAVITY_ROOT = path4.join(os4.homedir(), ".gemini", "antigravity-cli");
4200
- IDLE_GAP_MS3 = 3 * 60 * 1e3;
4625
+ DEFAULT_ANTIGRAVITY_ROOT = path5.join(os5.homedir(), ".gemini", "antigravity-cli");
4626
+ IDLE_GAP_MS4 = 3 * 60 * 1e3;
4201
4627
  historyCache = null;
4202
- metaCache4 = /* @__PURE__ */ new Map();
4203
- detailCache4 = /* @__PURE__ */ new Map();
4628
+ metaCache5 = /* @__PURE__ */ new Map();
4629
+ detailCache5 = /* @__PURE__ */ new Map();
4204
4630
  }
4205
4631
  });
4206
4632
 
4207
4633
  // ../parser/dist/cowork.js
4208
- import { promises as fs5 } from "node:fs";
4209
- import os5 from "node:os";
4210
- import path5 from "node:path";
4634
+ import { promises as fs6 } from "node:fs";
4635
+ import os6 from "node:os";
4636
+ import path6 from "node:path";
4211
4637
  function defaultCoworkRoot() {
4212
- const home = os5.homedir();
4638
+ const home = os6.homedir();
4213
4639
  if (process.platform === "darwin") {
4214
- return path5.join(home, "Library", "Application Support", "Claude", "local-agent-mode-sessions");
4640
+ return path6.join(home, "Library", "Application Support", "Claude", "local-agent-mode-sessions");
4215
4641
  }
4216
4642
  if (process.platform === "win32") {
4217
- const appData = process.env.APPDATA ?? path5.join(home, "AppData", "Roaming");
4218
- return path5.join(appData, "Claude", "local-agent-mode-sessions");
4643
+ const appData = process.env.APPDATA ?? path6.join(home, "AppData", "Roaming");
4644
+ return path6.join(appData, "Claude", "local-agent-mode-sessions");
4219
4645
  }
4220
- return path5.join(home, ".config", "Claude", "local-agent-mode-sessions");
4646
+ return path6.join(home, ".config", "Claude", "local-agent-mode-sessions");
4221
4647
  }
4222
4648
  async function safeReaddir4(p) {
4223
- return fs5.readdir(p).catch(() => []);
4649
+ return fs6.readdir(p).catch(() => []);
4224
4650
  }
4225
4651
  async function statMs(p) {
4226
- const s = await fs5.stat(p).catch(() => null);
4652
+ const s = await fs6.stat(p).catch(() => null);
4227
4653
  return s ? s.mtimeMs : 0;
4228
4654
  }
4229
- async function listSessionFiles3(root) {
4655
+ async function listSessionFiles4(root) {
4230
4656
  const out = [];
4231
4657
  const accounts = await safeReaddir4(root);
4232
4658
  for (const accountId of accounts) {
4233
- const accountDir = path5.join(root, accountId);
4659
+ const accountDir = path6.join(root, accountId);
4234
4660
  const workspaces = await safeReaddir4(accountDir);
4235
4661
  for (const workspaceId of workspaces) {
4236
- const workspaceDir = path5.join(accountDir, workspaceId);
4237
- const spacesMtimeMs = await statMs(path5.join(workspaceDir, "spaces.json"));
4662
+ const workspaceDir = path6.join(accountDir, workspaceId);
4663
+ const spacesMtimeMs = await statMs(path6.join(workspaceDir, "spaces.json"));
4238
4664
  const entries = await safeReaddir4(workspaceDir);
4239
4665
  for (const entry of entries) {
4240
4666
  if (!SESSION_ID_RE.test(entry))
4241
4667
  continue;
4242
- const auditPath = path5.join(workspaceDir, entry, "audit.jsonl");
4243
- const auditStat = await fs5.stat(auditPath).catch(() => null);
4668
+ const auditPath = path6.join(workspaceDir, entry, "audit.jsonl");
4669
+ const auditStat = await fs6.stat(auditPath).catch(() => null);
4244
4670
  if (!auditStat || !auditStat.isFile() || auditStat.size === 0)
4245
4671
  continue;
4246
- const metaPath = path5.join(workspaceDir, `${entry}.json`);
4672
+ const metaPath = path6.join(workspaceDir, `${entry}.json`);
4247
4673
  const metaMtimeMs = await statMs(metaPath);
4248
4674
  out.push({
4249
4675
  sessionId: entry,
@@ -4261,14 +4687,14 @@ async function listSessionFiles3(root) {
4261
4687
  return out;
4262
4688
  }
4263
4689
  async function loadSpacesForWorkspace(workspaceDir) {
4264
- const spacesPath = path5.join(workspaceDir, "spaces.json");
4265
- const stat = await fs5.stat(spacesPath).catch(() => null);
4690
+ const spacesPath = path6.join(workspaceDir, "spaces.json");
4691
+ const stat = await fs6.stat(spacesPath).catch(() => null);
4266
4692
  if (!stat)
4267
4693
  return /* @__PURE__ */ new Map();
4268
4694
  const cached = spacesCache.get(workspaceDir);
4269
4695
  if (cached && cached.mtimeMs === stat.mtimeMs)
4270
4696
  return cached.spaceIdToPath;
4271
- const raw = await fs5.readFile(spacesPath, "utf8").catch(() => "");
4697
+ const raw = await fs6.readFile(spacesPath, "utf8").catch(() => "");
4272
4698
  const out = /* @__PURE__ */ new Map();
4273
4699
  try {
4274
4700
  const parsed = JSON.parse(raw);
@@ -4286,7 +4712,7 @@ async function loadSpacesForWorkspace(workspaceDir) {
4286
4712
  return out;
4287
4713
  }
4288
4714
  async function readCoworkMeta(metaPath) {
4289
- const raw = await fs5.readFile(metaPath, "utf8").catch(() => "");
4715
+ const raw = await fs6.readFile(metaPath, "utf8").catch(() => "");
4290
4716
  if (!raw)
4291
4717
  return {};
4292
4718
  try {
@@ -4322,8 +4748,8 @@ function resolveProject(meta, spaceIdToPath) {
4322
4748
  cwd: projectPath
4323
4749
  };
4324
4750
  }
4325
- async function readJsonl2(filePath) {
4326
- const raw = await fs5.readFile(filePath, "utf8");
4751
+ async function readJsonl3(filePath) {
4752
+ const raw = await fs6.readFile(filePath, "utf8");
4327
4753
  const out = [];
4328
4754
  for (const line of raw.split("\n")) {
4329
4755
  const trimmed = line.trim();
@@ -4459,7 +4885,7 @@ function buildCoworkSubagents(subagentGroups, allLines, sessionStartMs) {
4459
4885
  }
4460
4886
  async function parseCoworkSession(file) {
4461
4887
  const [lines, coworkMeta, spaceIdToPath] = await Promise.all([
4462
- readJsonl2(file.auditPath),
4888
+ readJsonl3(file.auditPath),
4463
4889
  readCoworkMeta(file.metaPath),
4464
4890
  loadSpacesForWorkspace(file.workspaceDir)
4465
4891
  ]);
@@ -4494,24 +4920,24 @@ function cacheKeyMatches(a, b) {
4494
4920
  return a.auditMtimeMs === b.auditMtimeMs && a.auditSize === b.auditSize && a.metaMtimeMs === b.metaMtimeMs && a.spacesMtimeMs === b.spacesMtimeMs;
4495
4921
  }
4496
4922
  function clearCoworkCaches() {
4497
- metaCache5.clear();
4498
- detailCache5.clear();
4923
+ metaCache6.clear();
4924
+ detailCache6.clear();
4499
4925
  spacesCache.clear();
4500
4926
  }
4501
4927
  async function listCoworkSessions(opts = {}) {
4502
4928
  const root = opts.root ?? DEFAULT_COWORK_ROOT;
4503
- const files = await listSessionFiles3(root);
4929
+ const files = await listSessionFiles4(root);
4504
4930
  const out = [];
4505
4931
  for (const file of files) {
4506
4932
  const key = cacheKeyFor(file);
4507
- const cached = metaCache5.get(file.auditPath);
4933
+ const cached = metaCache6.get(file.auditPath);
4508
4934
  if (cached && cacheKeyMatches(cached.key, key)) {
4509
4935
  out.push(cached.meta);
4510
4936
  continue;
4511
4937
  }
4512
4938
  try {
4513
4939
  const { meta } = await parseCoworkSession(file);
4514
- metaCache5.set(file.auditPath, { meta, key });
4940
+ metaCache6.set(file.auditPath, { meta, key });
4515
4941
  out.push(meta);
4516
4942
  } catch {
4517
4943
  }
@@ -4523,12 +4949,12 @@ async function listCoworkSessions(opts = {}) {
4523
4949
  }
4524
4950
  async function getCoworkSession(id, opts = {}) {
4525
4951
  const root = opts.root ?? DEFAULT_COWORK_ROOT;
4526
- const files = await listSessionFiles3(root);
4952
+ const files = await listSessionFiles4(root);
4527
4953
  const file = files.find((f) => f.sessionId === id);
4528
4954
  if (!file)
4529
4955
  return null;
4530
4956
  const key = cacheKeyFor(file);
4531
- const cached = detailCache5.get(file.auditPath);
4957
+ const cached = detailCache6.get(file.auditPath);
4532
4958
  if (cached && cacheKeyMatches(cached.key, key))
4533
4959
  return cached.detail;
4534
4960
  const { meta, events, subagents } = await parseCoworkSession(file);
@@ -4537,10 +4963,10 @@ async function getCoworkSession(id, opts = {}) {
4537
4963
  events,
4538
4964
  ...subagents.length ? { subagents } : {}
4539
4965
  };
4540
- detailCache5.set(file.auditPath, { detail, key });
4966
+ detailCache6.set(file.auditPath, { detail, key });
4541
4967
  return detail;
4542
4968
  }
4543
- var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache5, detailCache5;
4969
+ var DEFAULT_COWORK_ROOT, SESSION_ID_RE, spacesCache, metaCache6, detailCache6;
4544
4970
  var init_cowork = __esm({
4545
4971
  "../parser/dist/cowork.js"() {
4546
4972
  "use strict";
@@ -4550,24 +4976,24 @@ var init_cowork = __esm({
4550
4976
  DEFAULT_COWORK_ROOT = defaultCoworkRoot();
4551
4977
  SESSION_ID_RE = /^local_[0-9a-f-]+$/;
4552
4978
  spacesCache = /* @__PURE__ */ new Map();
4553
- metaCache5 = /* @__PURE__ */ new Map();
4554
- detailCache5 = /* @__PURE__ */ new Map();
4979
+ metaCache6 = /* @__PURE__ */ new Map();
4980
+ detailCache6 = /* @__PURE__ */ new Map();
4555
4981
  }
4556
4982
  });
4557
4983
 
4558
4984
  // ../parser/dist/grok.js
4559
- import { promises as fs6 } from "node:fs";
4560
- import os6 from "node:os";
4561
- import path6 from "node:path";
4985
+ import { promises as fs7 } from "node:fs";
4986
+ import os7 from "node:os";
4987
+ import path7 from "node:path";
4562
4988
  function resolveDefaultGrokRoot() {
4563
- const home = process.env.GROK_HOME || path6.join(os6.homedir(), ".grok");
4564
- return path6.join(home, "sessions");
4989
+ const home = process.env.GROK_HOME || path7.join(os7.homedir(), ".grok");
4990
+ return path7.join(home, "sessions");
4565
4991
  }
4566
4992
  async function safeReaddir5(p) {
4567
- return fs6.readdir(p).catch(() => []);
4993
+ return fs7.readdir(p).catch(() => []);
4568
4994
  }
4569
4995
  async function safeReadJson(p) {
4570
- const raw = await fs6.readFile(p, "utf8").catch(() => null);
4996
+ const raw = await fs7.readFile(p, "utf8").catch(() => null);
4571
4997
  if (raw == null)
4572
4998
  return null;
4573
4999
  try {
@@ -4577,8 +5003,8 @@ async function safeReadJson(p) {
4577
5003
  }
4578
5004
  }
4579
5005
  async function resolveEncodedCwd(groupDir, encoded) {
4580
- const cwdFile = path6.join(groupDir, ".cwd");
4581
- const fromFile = await fs6.readFile(cwdFile, "utf8").catch(() => null);
5006
+ const cwdFile = path7.join(groupDir, ".cwd");
5007
+ const fromFile = await fs7.readFile(cwdFile, "utf8").catch(() => null);
4582
5008
  if (fromFile && fromFile.trim())
4583
5009
  return fromFile.trim();
4584
5010
  try {
@@ -4593,8 +5019,8 @@ async function listSessionDirs(root) {
4593
5019
  for (const group of groups) {
4594
5020
  if (group === "session_search.sqlite" || group.startsWith("."))
4595
5021
  continue;
4596
- const groupDir = path6.join(root, group);
4597
- const groupStat = await fs6.stat(groupDir).catch(() => null);
5022
+ const groupDir = path7.join(root, group);
5023
+ const groupStat = await fs7.stat(groupDir).catch(() => null);
4598
5024
  if (!groupStat?.isDirectory())
4599
5025
  continue;
4600
5026
  const decodedCwd = await resolveEncodedCwd(groupDir, group);
@@ -4602,14 +5028,14 @@ async function listSessionDirs(root) {
4602
5028
  for (const entry of entries) {
4603
5029
  if (entry === "prompt_history.jsonl" || entry.startsWith("."))
4604
5030
  continue;
4605
- const dirPath = path6.join(groupDir, entry);
4606
- const summaryPath = path6.join(dirPath, "summary.json");
4607
- const updatesPath = path6.join(dirPath, "updates.jsonl");
4608
- const signalsCandidate = path6.join(dirPath, "signals.json");
5031
+ const dirPath = path7.join(groupDir, entry);
5032
+ const summaryPath = path7.join(dirPath, "summary.json");
5033
+ const updatesPath = path7.join(dirPath, "updates.jsonl");
5034
+ const signalsCandidate = path7.join(dirPath, "signals.json");
4609
5035
  const [summaryStat, updatesStat, signalsStat] = await Promise.all([
4610
- fs6.stat(summaryPath).catch(() => null),
4611
- fs6.stat(updatesPath).catch(() => null),
4612
- fs6.stat(signalsCandidate).catch(() => null)
5036
+ fs7.stat(summaryPath).catch(() => null),
5037
+ fs7.stat(updatesPath).catch(() => null),
5038
+ fs7.stat(signalsCandidate).catch(() => null)
4613
5039
  ]);
4614
5040
  if (!summaryStat?.isFile())
4615
5041
  continue;
@@ -4630,10 +5056,10 @@ async function listSessionDirs(root) {
4630
5056
  }
4631
5057
  return out;
4632
5058
  }
4633
- function emptyUsage4() {
5059
+ function emptyUsage5() {
4634
5060
  return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
4635
5061
  }
4636
- function previewOf4(text) {
5062
+ function previewOf5(text) {
4637
5063
  return text.replace(/\s+/g, " ").trim().slice(0, 200);
4638
5064
  }
4639
5065
  function truncate5(s, n) {
@@ -4747,7 +5173,7 @@ function lineTimestampIso(line) {
4747
5173
  }
4748
5174
  return void 0;
4749
5175
  }
4750
- function computeActiveSegments5(tsMs) {
5176
+ function computeActiveSegments6(tsMs) {
4751
5177
  if (tsMs.length === 0)
4752
5178
  return [];
4753
5179
  const sorted = [...tsMs].sort((a, b) => a - b);
@@ -4756,7 +5182,7 @@ function computeActiveSegments5(tsMs) {
4756
5182
  let segEnd = sorted[0];
4757
5183
  for (let i = 1; i < sorted.length; i++) {
4758
5184
  const t = sorted[i];
4759
- if (t - segEnd > IDLE_GAP_MS4) {
5185
+ if (t - segEnd > IDLE_GAP_MS5) {
4760
5186
  out.push({ startMs: segStart, endMs: segEnd });
4761
5187
  segStart = t;
4762
5188
  }
@@ -4765,17 +5191,17 @@ function computeActiveSegments5(tsMs) {
4765
5191
  out.push({ startMs: segStart, endMs: segEnd });
4766
5192
  return out;
4767
5193
  }
4768
- async function parseSession3(dir) {
5194
+ async function parseSession4(dir) {
4769
5195
  const [summary, signals, updatesRaw] = await Promise.all([
4770
5196
  safeReadJson(dir.summaryPath),
4771
5197
  dir.signalsPath ? safeReadJson(dir.signalsPath) : Promise.resolve(null),
4772
- fs6.readFile(dir.updatesPath, "utf8").catch(() => "")
5198
+ fs7.readFile(dir.updatesPath, "utf8").catch(() => "")
4773
5199
  ]);
4774
5200
  const sessionId = summary?.info?.id ?? dir.sessionId;
4775
5201
  const cwd = summary?.info?.cwd ?? dir.decodedCwd;
4776
5202
  let model = summary?.current_model_id ?? signals?.primaryModelId ?? signals?.modelsUsed?.[0];
4777
5203
  const events = [];
4778
- const totalUsage = emptyUsage4();
5204
+ const totalUsage = emptyUsage5();
4779
5205
  if (signals?.contextTokensUsed && signals.contextTokensUsed > 0) {
4780
5206
  totalUsage.input = signals.contextTokensUsed;
4781
5207
  }
@@ -4809,7 +5235,7 @@ async function parseSession3(dir) {
4809
5235
  if (!buf)
4810
5236
  return;
4811
5237
  const text = buf.texts.join("");
4812
- const preview = previewOf4(text);
5238
+ const preview = previewOf5(text);
4813
5239
  if (buf.kind === "user") {
4814
5240
  const isHidden = !text || isFrameworkInjectedUserInput(text);
4815
5241
  if (text && !isHidden) {
@@ -4969,7 +5395,7 @@ async function parseSession3(dir) {
4969
5395
  timestamp: ts,
4970
5396
  role: "tool-result",
4971
5397
  rawType: "grok/tool_result",
4972
- preview: previewOf4(resultText),
5398
+ preview: previewOf5(resultText),
4973
5399
  blocks: [
4974
5400
  {
4975
5401
  type: "tool_result",
@@ -5018,7 +5444,7 @@ async function parseSession3(dir) {
5018
5444
  prevMs = ms;
5019
5445
  }
5020
5446
  }
5021
- const activeSegments = computeActiveSegments5(tsMs);
5447
+ const activeSegments = computeActiveSegments6(tsMs);
5022
5448
  const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
5023
5449
  const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
5024
5450
  const project = cwd ? resolveProjectIdentity(cwd) : void 0;
@@ -5027,7 +5453,7 @@ async function parseSession3(dir) {
5027
5453
  if (!firstUserPreview) {
5028
5454
  const title = summary?.generated_title || summary?.session_summary;
5029
5455
  if (title)
5030
- firstUserPreview = previewOf4(title);
5456
+ firstUserPreview = previewOf5(title);
5031
5457
  }
5032
5458
  const spawnedAgentCount = await countSubagentChildren(dir.dirPath);
5033
5459
  const meta = {
@@ -5064,38 +5490,38 @@ async function parseSession3(dir) {
5064
5490
  return { meta, events, sessionKind: summary?.session_kind };
5065
5491
  }
5066
5492
  async function countSubagentChildren(dirPath) {
5067
- const subRoot = path6.join(dirPath, "subagents");
5493
+ const subRoot = path7.join(dirPath, "subagents");
5068
5494
  const entries = await safeReaddir5(subRoot);
5069
5495
  let n = 0;
5070
5496
  for (const e of entries) {
5071
- const st = await fs6.stat(path6.join(subRoot, e)).catch(() => null);
5497
+ const st = await fs7.stat(path7.join(subRoot, e)).catch(() => null);
5072
5498
  if (st?.isDirectory())
5073
5499
  n += 1;
5074
5500
  }
5075
5501
  return n;
5076
5502
  }
5077
5503
  async function loadGrokSubagents(parentDir, parentStartMs) {
5078
- const subRoot = path6.join(parentDir.dirPath, "subagents");
5504
+ const subRoot = path7.join(parentDir.dirPath, "subagents");
5079
5505
  const entries = await safeReaddir5(subRoot);
5080
- const groupDir = path6.dirname(parentDir.dirPath);
5506
+ const groupDir = path7.dirname(parentDir.dirPath);
5081
5507
  const runs = [];
5082
5508
  for (const entry of entries) {
5083
- const metaPath = path6.join(subRoot, entry, "meta.json");
5509
+ const metaPath = path7.join(subRoot, entry, "meta.json");
5084
5510
  const meta = await safeReadJson(metaPath);
5085
5511
  if (!meta)
5086
5512
  continue;
5087
5513
  const childId = meta.child_session_id ?? meta.subagent_id ?? entry;
5088
- const childDir = path6.join(groupDir, childId);
5514
+ const childDir = path7.join(groupDir, childId);
5089
5515
  const [childSummary, childSignals] = await Promise.all([
5090
- safeReadJson(path6.join(childDir, "summary.json")),
5091
- safeReadJson(path6.join(childDir, "signals.json"))
5516
+ safeReadJson(path7.join(childDir, "summary.json")),
5517
+ safeReadJson(path7.join(childDir, "signals.json"))
5092
5518
  ]);
5093
5519
  const startMs = childSummary?.created_at ? Date.parse(childSummary.created_at) : void 0;
5094
5520
  const endIso = childSummary?.last_active_at ?? childSummary?.updated_at;
5095
5521
  const endMs = endIso ? Date.parse(endIso) : void 0;
5096
5522
  const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
5097
5523
  const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
5098
- const usage = emptyUsage4();
5524
+ const usage = emptyUsage5();
5099
5525
  if (childSignals?.contextTokensUsed)
5100
5526
  usage.input = childSignals.contextTokensUsed;
5101
5527
  runs.push({
@@ -5118,8 +5544,8 @@ async function loadGrokSubagents(parentDir, parentStartMs) {
5118
5544
  return runs;
5119
5545
  }
5120
5546
  function clearGrokCaches() {
5121
- metaCache6.clear();
5122
- detailCache6.clear();
5547
+ metaCache7.clear();
5548
+ detailCache7.clear();
5123
5549
  }
5124
5550
  async function listGrokSessions(opts = {}) {
5125
5551
  const root = opts.root ?? resolveDefaultGrokRoot();
@@ -5129,16 +5555,16 @@ async function listGrokSessions(opts = {}) {
5129
5555
  const summaryPeek = await safeReadJson(dir.summaryPath);
5130
5556
  if (summaryPeek?.session_kind === "subagent")
5131
5557
  continue;
5132
- const cached = metaCache6.get(dir.dirPath);
5558
+ const cached = metaCache7.get(dir.dirPath);
5133
5559
  if (cached && cached.mtimeMs === dir.mtimeMs && cached.sizeBytes === dir.sizeBytes) {
5134
5560
  out.push(cached.meta);
5135
5561
  continue;
5136
5562
  }
5137
5563
  try {
5138
- const { meta, sessionKind } = await parseSession3(dir);
5564
+ const { meta, sessionKind } = await parseSession4(dir);
5139
5565
  if (sessionKind === "subagent")
5140
5566
  continue;
5141
- metaCache6.set(dir.dirPath, {
5567
+ metaCache7.set(dir.dirPath, {
5142
5568
  meta,
5143
5569
  mtimeMs: dir.mtimeMs,
5144
5570
  sizeBytes: dir.sizeBytes
@@ -5159,10 +5585,10 @@ async function getGrokSession(id, opts = {}) {
5159
5585
  if (!chosen) {
5160
5586
  for (const dir of dirs) {
5161
5587
  try {
5162
- const { meta: meta2, events: events2 } = await parseSession3(dir);
5588
+ const { meta: meta2, events: events2 } = await parseSession4(dir);
5163
5589
  if (meta2.id === id) {
5164
5590
  const detail2 = { ...meta2, events: events2 };
5165
- detailCache6.set(dir.dirPath, {
5591
+ detailCache7.set(dir.dirPath, {
5166
5592
  detail: detail2,
5167
5593
  mtimeMs: dir.mtimeMs,
5168
5594
  sizeBytes: dir.sizeBytes
@@ -5174,11 +5600,11 @@ async function getGrokSession(id, opts = {}) {
5174
5600
  }
5175
5601
  return null;
5176
5602
  }
5177
- const cached = detailCache6.get(chosen.dirPath);
5603
+ const cached = detailCache7.get(chosen.dirPath);
5178
5604
  if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
5179
5605
  return cached.detail;
5180
5606
  }
5181
- const { meta, events } = await parseSession3(chosen);
5607
+ const { meta, events } = await parseSession4(chosen);
5182
5608
  const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
5183
5609
  const subagents = await loadGrokSubagents(chosen, parentStartMs !== void 0 && Number.isFinite(parentStartMs) ? parentStartMs : void 0);
5184
5610
  const detail = {
@@ -5186,12 +5612,12 @@ async function getGrokSession(id, opts = {}) {
5186
5612
  events,
5187
5613
  ...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
5188
5614
  };
5189
- detailCache6.set(chosen.dirPath, {
5615
+ detailCache7.set(chosen.dirPath, {
5190
5616
  detail,
5191
5617
  mtimeMs: chosen.mtimeMs,
5192
5618
  sizeBytes: chosen.sizeBytes
5193
5619
  });
5194
- metaCache6.set(chosen.dirPath, {
5620
+ metaCache7.set(chosen.dirPath, {
5195
5621
  meta: {
5196
5622
  ...meta,
5197
5623
  ...subagents.length > 0 ? { spawnedAgentCount: subagents.length } : {}
@@ -5207,17 +5633,17 @@ function grokSessionLocalDay(meta) {
5207
5633
  const ms = Date.parse(meta.firstTimestamp);
5208
5634
  return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
5209
5635
  }
5210
- var DEFAULT_GROK_ROOT, IDLE_GAP_MS4, metaCache6, detailCache6;
5636
+ var DEFAULT_GROK_ROOT, IDLE_GAP_MS5, metaCache7, detailCache7;
5211
5637
  var init_grok = __esm({
5212
5638
  "../parser/dist/grok.js"() {
5213
5639
  "use strict";
5214
5640
  init_analytics();
5215
5641
  init_git_project();
5216
5642
  init_user_input();
5217
- DEFAULT_GROK_ROOT = path6.join(os6.homedir(), ".grok", "sessions");
5218
- IDLE_GAP_MS4 = 3 * 60 * 1e3;
5219
- metaCache6 = /* @__PURE__ */ new Map();
5220
- detailCache6 = /* @__PURE__ */ new Map();
5643
+ DEFAULT_GROK_ROOT = path7.join(os7.homedir(), ".grok", "sessions");
5644
+ IDLE_GAP_MS5 = 3 * 60 * 1e3;
5645
+ metaCache7 = /* @__PURE__ */ new Map();
5646
+ detailCache7 = /* @__PURE__ */ new Map();
5221
5647
  }
5222
5648
  });
5223
5649
 
@@ -5278,6 +5704,7 @@ var fs_exports = {};
5278
5704
  __export(fs_exports, {
5279
5705
  DEFAULT_ANTIGRAVITY_ROOT: () => DEFAULT_ANTIGRAVITY_ROOT,
5280
5706
  DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
5707
+ DEFAULT_COPILOT_ROOT: () => DEFAULT_COPILOT_ROOT,
5281
5708
  DEFAULT_COWORK_ROOT: () => DEFAULT_COWORK_ROOT,
5282
5709
  DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
5283
5710
  DEFAULT_GROK_ROOT: () => DEFAULT_GROK_ROOT,
@@ -5294,6 +5721,7 @@ __export(fs_exports, {
5294
5721
  clearGrokCaches: () => clearGrokCaches,
5295
5722
  clearTeamConfig: () => clearTeamConfig,
5296
5723
  codexSessionLocalDay: () => codexSessionLocalDay,
5724
+ copilotSessionLocalDay: () => copilotSessionLocalDay,
5297
5725
  decodeProjectName: () => decodeProjectName,
5298
5726
  findTeamLead: () => findTeamLead,
5299
5727
  geminiSessionLocalDay: () => geminiSessionLocalDay,
@@ -5301,6 +5729,7 @@ __export(fs_exports, {
5301
5729
  getAntigravitySession: () => getAntigravitySession,
5302
5730
  getAnySession: () => getAnySession,
5303
5731
  getCodexSession: () => getCodexSession,
5732
+ getCopilotSession: () => getCopilotSession,
5304
5733
  getCoworkSession: () => getCoworkSession,
5305
5734
  getGeminiSession: () => getGeminiSession,
5306
5735
  getGrokSession: () => getGrokSession,
@@ -5312,6 +5741,7 @@ __export(fs_exports, {
5312
5741
  listAllSessions: () => listAllSessions,
5313
5742
  listAntigravitySessions: () => listAntigravitySessions,
5314
5743
  listCodexSessions: () => listCodexSessions,
5744
+ listCopilotSessions: () => listCopilotSessions,
5315
5745
  listCoworkSessions: () => listCoworkSessions,
5316
5746
  listGeminiSessions: () => listGeminiSessions,
5317
5747
  listGrokSessions: () => listGrokSessions,
@@ -5334,14 +5764,14 @@ __export(fs_exports, {
5334
5764
  walkJsonlFiles: () => walkJsonlFiles,
5335
5765
  writeTeamConfig: () => writeTeamConfig
5336
5766
  });
5337
- import { promises as fs7, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
5338
- import os7 from "node:os";
5339
- import path7 from "node:path";
5767
+ import { promises as fs8, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
5768
+ import os8 from "node:os";
5769
+ import path8 from "node:path";
5340
5770
  function cclensHome() {
5341
- return process.env.CCLENS_HOME || path7.join(os7.homedir(), ".cclens");
5771
+ return process.env.CCLENS_HOME || path8.join(os8.homedir(), ".cclens");
5342
5772
  }
5343
5773
  function cclensPath(...parts) {
5344
- return path7.join(cclensHome(), ...parts);
5774
+ return path8.join(cclensHome(), ...parts);
5345
5775
  }
5346
5776
  function cacheStats() {
5347
5777
  return claudeCodeCacheStats();
@@ -5349,6 +5779,7 @@ function cacheStats() {
5349
5779
  function clearCaches() {
5350
5780
  clearClaudeCodeCaches();
5351
5781
  clearCodexCaches();
5782
+ clearCopilotCaches();
5352
5783
  clearGeminiCaches();
5353
5784
  clearAntigravityCaches();
5354
5785
  clearCoworkCaches();
@@ -5383,7 +5814,7 @@ function usageLogPath() {
5383
5814
  }
5384
5815
  function appendUsageSnapshot(snapshot) {
5385
5816
  const p = usageLogPath();
5386
- mkdirSync2(path7.dirname(p), { recursive: true });
5817
+ mkdirSync2(path8.dirname(p), { recursive: true });
5387
5818
  appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
5388
5819
  }
5389
5820
  function pruneUsageAgent(agent) {
@@ -5399,13 +5830,13 @@ function pruneUsageAgent(agent) {
5399
5830
  return true;
5400
5831
  }
5401
5832
  });
5402
- mkdirSync2(path7.dirname(p), { recursive: true });
5833
+ mkdirSync2(path8.dirname(p), { recursive: true });
5403
5834
  writeFileSync2(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
5404
5835
  }
5405
5836
  async function loadUsageByDay(start, end) {
5406
5837
  let raw;
5407
5838
  try {
5408
- raw = await fs7.readFile(usageLogPath(), "utf8");
5839
+ raw = await fs8.readFile(usageLogPath(), "utf8");
5409
5840
  } catch {
5410
5841
  return { by_day: [] };
5411
5842
  }
@@ -5450,7 +5881,7 @@ async function loadUsageByDay(start, end) {
5450
5881
  async function loadCalibrationSnapshots() {
5451
5882
  let raw;
5452
5883
  try {
5453
- raw = await fs7.readFile(usageLogPath(), "utf8");
5884
+ raw = await fs8.readFile(usageLogPath(), "utf8");
5454
5885
  } catch {
5455
5886
  return [];
5456
5887
  }
@@ -5614,7 +6045,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
5614
6045
  ]);
5615
6046
  return buildCalibrationCurve(events, snapshots, tier, granularityMin);
5616
6047
  }
5617
- var codexSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
6048
+ var codexSource, copilotSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
5618
6049
  var init_fs = __esm({
5619
6050
  "../parser/dist/fs.js"() {
5620
6051
  "use strict";
@@ -5623,6 +6054,7 @@ var init_fs = __esm({
5623
6054
  init_calibration();
5624
6055
  init_claude_code();
5625
6056
  init_codex();
6057
+ init_copilot();
5626
6058
  init_gemini();
5627
6059
  init_antigravity();
5628
6060
  init_cowork();
@@ -5630,6 +6062,7 @@ var init_fs = __esm({
5630
6062
  init_claude_code();
5631
6063
  init_git_project();
5632
6064
  init_codex();
6065
+ init_copilot();
5633
6066
  init_gemini();
5634
6067
  init_antigravity();
5635
6068
  init_cowork();
@@ -5646,6 +6079,16 @@ var init_fs = __esm({
5646
6079
  return getCodexSession(id);
5647
6080
  }
5648
6081
  };
6082
+ copilotSource = {
6083
+ ...COPILOT_METADATA,
6084
+ defaultRoot: DEFAULT_COPILOT_ROOT,
6085
+ async listSessions(opts) {
6086
+ return listCopilotSessions(opts);
6087
+ },
6088
+ async getSession(id, opts) {
6089
+ return getCopilotSession(id, opts);
6090
+ }
6091
+ };
5649
6092
  geminiSource = {
5650
6093
  ...GEMINI_METADATA,
5651
6094
  defaultRoot: DEFAULT_GEMINI_ROOT,
@@ -5690,6 +6133,7 @@ var init_fs = __esm({
5690
6133
  agentSources = [
5691
6134
  claudeCodeSource,
5692
6135
  codexSource,
6136
+ copilotSource,
5693
6137
  geminiSource,
5694
6138
  antigravitySource,
5695
6139
  coworkSource,
@@ -5699,14 +6143,14 @@ var init_fs = __esm({
5699
6143
  });
5700
6144
 
5701
6145
  // src/usage/storage.ts
5702
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync6 } from "node:fs";
5703
- import { dirname as dirname2 } from "node:path";
6146
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync8, writeFileSync as writeFileSync4, existsSync as existsSync7 } from "node:fs";
6147
+ import { dirname as dirname3 } from "node:path";
5704
6148
  function appendSnapshot(filePath, snapshot) {
5705
- mkdirSync3(dirname2(filePath), { recursive: true });
6149
+ mkdirSync3(dirname3(filePath), { recursive: true });
5706
6150
  appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
5707
6151
  }
5708
6152
  function readSnapshots(filePath) {
5709
- if (!existsSync6(filePath)) return [];
6153
+ if (!existsSync7(filePath)) return [];
5710
6154
  const content = readFileSync8(filePath, "utf8");
5711
6155
  const snapshots = [];
5712
6156
  for (const line of content.split("\n")) {
@@ -5719,7 +6163,7 @@ function readSnapshots(filePath) {
5719
6163
  return snapshots;
5720
6164
  }
5721
6165
  function pruneAgent(filePath, agent) {
5722
- if (!existsSync6(filePath)) return;
6166
+ if (!existsSync7(filePath)) return;
5723
6167
  const kept = readFileSync8(filePath, "utf8").split("\n").filter((line) => {
5724
6168
  if (!line.trim()) return false;
5725
6169
  try {
@@ -5728,7 +6172,7 @@ function pruneAgent(filePath, agent) {
5728
6172
  return true;
5729
6173
  }
5730
6174
  });
5731
- mkdirSync3(dirname2(filePath), { recursive: true });
6175
+ mkdirSync3(dirname3(filePath), { recursive: true });
5732
6176
  writeFileSync4(filePath, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
5733
6177
  }
5734
6178
  function latestClaudeCodeSnapshot(filePath) {
@@ -6156,6 +6600,7 @@ __export(dist_exports, {
6156
6600
  ANTIGRAVITY_METADATA: () => ANTIGRAVITY_METADATA,
6157
6601
  CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
6158
6602
  CODEX_METADATA: () => CODEX_METADATA,
6603
+ COPILOT_METADATA: () => COPILOT_METADATA,
6159
6604
  COWORK_METADATA: () => COWORK_METADATA,
6160
6605
  GEMINI_METADATA: () => GEMINI_METADATA,
6161
6606
  GROK_METADATA: () => GROK_METADATA,
@@ -6232,25 +6677,25 @@ __export(file_probe_exports, {
6232
6677
  probeArtifactSignals: () => probeArtifactSignals
6233
6678
  });
6234
6679
  import { createHash } from "node:crypto";
6235
- import { existsSync as existsSync11, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
6680
+ import { existsSync as existsSync12, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
6236
6681
  import { homedir as homedir3 } from "node:os";
6237
- import { join as join8, relative, resolve as resolve3, sep } from "node:path";
6682
+ import { join as join9, relative, resolve as resolve3, sep } from "node:path";
6238
6683
  import { execFileSync as execFileSync2 } from "node:child_process";
6239
6684
  function pathHash(relPath) {
6240
6685
  return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
6241
6686
  }
6242
6687
  function defaultScanRoots(extraRoots = []) {
6243
6688
  const roots = [];
6244
- const home = join8(homedir3(), ".claude");
6245
- if (existsSync11(home)) roots.push({ root: home, label: "user" });
6689
+ const home = join9(homedir3(), ".claude");
6690
+ if (existsSync12(home)) roots.push({ root: home, label: "user" });
6246
6691
  for (const e of extraRoots) {
6247
6692
  const r = resolve3(e, ".claude");
6248
- if (existsSync11(r) && r !== home) roots.push({ root: r, label: "project" });
6693
+ if (existsSync12(r) && r !== home) roots.push({ root: r, label: "project" });
6249
6694
  }
6250
6695
  return roots;
6251
6696
  }
6252
6697
  function listMarkdownFiles(dir) {
6253
- if (!existsSync11(dir)) return [];
6698
+ if (!existsSync12(dir)) return [];
6254
6699
  const out = [];
6255
6700
  let entries;
6256
6701
  try {
@@ -6260,7 +6705,7 @@ function listMarkdownFiles(dir) {
6260
6705
  }
6261
6706
  for (const name of entries) {
6262
6707
  if (name.startsWith(".")) continue;
6263
- const full = join8(dir, name);
6708
+ const full = join9(dir, name);
6264
6709
  let stat;
6265
6710
  try {
6266
6711
  stat = statSync5(full);
@@ -6280,7 +6725,7 @@ function firstSeenDateOf(file) {
6280
6725
  const out = execFileSync2(
6281
6726
  "git",
6282
6727
  ["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
6283
- { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname8(file) }
6728
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname9(file) }
6284
6729
  ).trim().split("\n").filter(Boolean);
6285
6730
  if (out.length > 0) return out[out.length - 1];
6286
6731
  } catch {
@@ -6292,7 +6737,7 @@ function firstSeenDateOf(file) {
6292
6737
  return todayLocal();
6293
6738
  }
6294
6739
  }
6295
- function dirname8(p) {
6740
+ function dirname9(p) {
6296
6741
  const i = p.lastIndexOf(sep);
6297
6742
  return i < 0 ? "." : p.slice(0, i);
6298
6743
  }
@@ -6319,8 +6764,8 @@ function todayLocal() {
6319
6764
  function scanAuthored(roots, subdir, day) {
6320
6765
  const out = [];
6321
6766
  for (const r of roots) {
6322
- const dir = join8(r.root, subdir);
6323
- if (!existsSync11(dir)) continue;
6767
+ const dir = join9(r.root, subdir);
6768
+ if (!existsSync12(dir)) continue;
6324
6769
  for (const f of listMarkdownFiles(dir)) {
6325
6770
  const firstSeen = firstSeenDateOf(f);
6326
6771
  if (firstSeen !== day) continue;
@@ -6333,8 +6778,8 @@ function scanAuthored(roots, subdir, day) {
6333
6778
  function scanEdited(roots, day) {
6334
6779
  const out = [];
6335
6780
  for (const r of roots) {
6336
- const dir = join8(r.root, "skills");
6337
- if (!existsSync11(dir)) continue;
6781
+ const dir = join9(r.root, "skills");
6782
+ if (!existsSync12(dir)) continue;
6338
6783
  for (const f of listMarkdownFiles(dir)) {
6339
6784
  const firstSeen = firstSeenDateOf(f);
6340
6785
  if (firstSeen === day) continue;
@@ -6357,16 +6802,16 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
6357
6802
  const candidates = [];
6358
6803
  for (const e of extraRoots) {
6359
6804
  const f = resolve3(e, "CLAUDE.md");
6360
- if (existsSync11(f)) candidates.push(f);
6805
+ if (existsSync12(f)) candidates.push(f);
6361
6806
  }
6362
- const homeClaudeMd = join8(homedir3(), "CLAUDE.md");
6363
- if (existsSync11(homeClaudeMd)) candidates.push(homeClaudeMd);
6807
+ const homeClaudeMd = join9(homedir3(), "CLAUDE.md");
6808
+ if (existsSync12(homeClaudeMd)) candidates.push(homeClaudeMd);
6364
6809
  for (const file of candidates) {
6365
6810
  try {
6366
6811
  const out = execFileSync2(
6367
6812
  "git",
6368
6813
  ["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
6369
- { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname8(file) }
6814
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname9(file) }
6370
6815
  );
6371
6816
  let currentDate = "";
6372
6817
  let currentEmail = "";
@@ -6416,9 +6861,9 @@ var init_file_probe = __esm({
6416
6861
  });
6417
6862
 
6418
6863
  // src/daemon-worker.ts
6419
- import { spawn as spawn2 } from "node:child_process";
6420
- import { closeSync, existsSync as existsSync18, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
6421
- import { dirname as dirname11, join as join12 } from "node:path";
6864
+ import { spawn as spawn3 } from "node:child_process";
6865
+ import { closeSync, existsSync as existsSync19, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
6866
+ import { dirname as dirname12, join as join13 } from "node:path";
6422
6867
  import { fileURLToPath } from "node:url";
6423
6868
 
6424
6869
  // src/usage/token.ts
@@ -6449,9 +6894,9 @@ function readFromCredentialsFile() {
6449
6894
  join(homedir(), ".claude", ".credentials.json"),
6450
6895
  join(homedir(), ".config", "claude", "credentials.json")
6451
6896
  ];
6452
- for (const path10 of candidates) {
6897
+ for (const path11 of candidates) {
6453
6898
  try {
6454
- const blob = readFileSync(path10, "utf8");
6899
+ const blob = readFileSync(path11, "utf8");
6455
6900
  const creds = extractCredentials(blob);
6456
6901
  if (creds) return creds;
6457
6902
  } catch {
@@ -6665,8 +7110,8 @@ async function fetchZaiUsage() {
6665
7110
 
6666
7111
  // src/usage/grok.ts
6667
7112
  import { existsSync as existsSync4, readFileSync as readFileSync6 } from "node:fs";
6668
- import os8 from "node:os";
6669
- import path8 from "node:path";
7113
+ import os9 from "node:os";
7114
+ import path9 from "node:path";
6670
7115
  var CREDITS_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
6671
7116
  var SETTINGS_URL = "https://cli-chat-proxy.grok.com/v1/settings";
6672
7117
  var REFRESH_URL = "https://auth.x.ai/oauth2/token";
@@ -6681,10 +7126,10 @@ var GrokApiError = class extends Error {
6681
7126
  }
6682
7127
  };
6683
7128
  function grokHome() {
6684
- return process.env.GROK_HOME || path8.join(os8.homedir(), ".grok");
7129
+ return process.env.GROK_HOME || path9.join(os9.homedir(), ".grok");
6685
7130
  }
6686
7131
  function authPath() {
6687
- return path8.join(grokHome(), "auth.json");
7132
+ return path9.join(grokHome(), "auth.json");
6688
7133
  }
6689
7134
  function loadAuthEntry() {
6690
7135
  const p = authPath();
@@ -6881,8 +7326,8 @@ import {
6881
7326
  readFileSync as readFileSync7,
6882
7327
  writeFileSync as writeFileSync3
6883
7328
  } from "node:fs";
6884
- import os9 from "node:os";
6885
- import path9 from "node:path";
7329
+ import os10 from "node:os";
7330
+ import path10 from "node:path";
6886
7331
  var USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
6887
7332
  var REFRESH_URL2 = "https://auth.openai.com/oauth/token";
6888
7333
  var CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
@@ -6898,10 +7343,10 @@ var CodexApiError = class extends Error {
6898
7343
  function codexHome() {
6899
7344
  const env = process.env.CODEX_HOME?.trim();
6900
7345
  if (env) return env;
6901
- return path9.join(os9.homedir(), ".codex");
7346
+ return path10.join(os10.homedir(), ".codex");
6902
7347
  }
6903
7348
  function authPath2() {
6904
- return path9.join(codexHome(), "auth.json");
7349
+ return path10.join(codexHome(), "auth.json");
6905
7350
  }
6906
7351
  function loadAuth() {
6907
7352
  const p = authPath2();
@@ -7016,7 +7461,7 @@ function authHeaders2(accessToken, accountId) {
7016
7461
  }
7017
7462
  return headers;
7018
7463
  }
7019
- function numberOf2(v) {
7464
+ function numberOf3(v) {
7020
7465
  if (typeof v === "number" && Number.isFinite(v)) return v;
7021
7466
  if (typeof v === "string" && v.trim()) {
7022
7467
  const n = Number(v);
@@ -7026,21 +7471,21 @@ function numberOf2(v) {
7026
7471
  }
7027
7472
  function windowSeconds(raw) {
7028
7473
  if (!raw) return void 0;
7029
- const sec = numberOf2(raw.limit_window_seconds);
7474
+ const sec = numberOf3(raw.limit_window_seconds);
7030
7475
  if (sec !== void 0) return sec;
7031
- const minutes = numberOf2(raw.window_minutes);
7476
+ const minutes = numberOf3(raw.window_minutes);
7032
7477
  if (minutes !== void 0) return minutes * 60;
7033
7478
  return void 0;
7034
7479
  }
7035
7480
  function normalizeWindow2(raw, headerPercent, nowMs) {
7036
- const used = numberOf2(raw?.used_percent) ?? headerPercent;
7481
+ const used = numberOf3(raw?.used_percent) ?? headerPercent;
7037
7482
  if (used === void 0) return null;
7038
7483
  let resetsAt = null;
7039
- const resetUnix = numberOf2(raw?.reset_at) ?? numberOf2(raw?.resets_at);
7484
+ const resetUnix = numberOf3(raw?.reset_at) ?? numberOf3(raw?.resets_at);
7040
7485
  if (resetUnix !== void 0) {
7041
7486
  resetsAt = new Date(resetUnix * 1e3).toISOString();
7042
7487
  } else {
7043
- const after = numberOf2(raw?.reset_after_seconds);
7488
+ const after = numberOf3(raw?.reset_after_seconds);
7044
7489
  if (after !== void 0) {
7045
7490
  resetsAt = new Date(nowMs + after * 1e3).toISOString();
7046
7491
  }
@@ -7056,8 +7501,8 @@ function parseCodexWhamUsage(body, headers = {}, nowMs = Date.now()) {
7056
7501
  }
7057
7502
  const b = body;
7058
7503
  const rateLimit = b.rate_limit && typeof b.rate_limit === "object" ? b.rate_limit : {};
7059
- const headerPrimary = numberOf2(headers["x-codex-primary-used-percent"]);
7060
- const headerSecondary = numberOf2(headers["x-codex-secondary-used-percent"]);
7504
+ const headerPrimary = numberOf3(headers["x-codex-primary-used-percent"]);
7505
+ const headerSecondary = numberOf3(headers["x-codex-secondary-used-percent"]);
7061
7506
  const primary = rateLimit.primary_window && typeof rateLimit.primary_window === "object" ? rateLimit.primary_window : null;
7062
7507
  const secondary = rateLimit.secondary_window && typeof rateLimit.secondary_window === "object" ? rateLimit.secondary_window : null;
7063
7508
  const candidates = [
@@ -7155,6 +7600,208 @@ async function fetchCodexUsage() {
7155
7600
  };
7156
7601
  }
7157
7602
 
7603
+ // src/usage/copilot.ts
7604
+ import { spawn } from "node:child_process";
7605
+ import { existsSync as existsSync6 } from "node:fs";
7606
+ import { dirname as dirname2, join as join4 } from "node:path";
7607
+ var RPC_TIMEOUT_MS = 1e4;
7608
+ var CopilotApiError = class extends Error {
7609
+ constructor(message, code) {
7610
+ super(message);
7611
+ this.code = code;
7612
+ }
7613
+ };
7614
+ function recordOf2(value) {
7615
+ return typeof value === "object" && value !== null ? value : void 0;
7616
+ }
7617
+ function numberOf4(value) {
7618
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
7619
+ }
7620
+ function clampPercent(value) {
7621
+ return Math.min(100, Math.max(0, value));
7622
+ }
7623
+ function nextCopilotMonthlyReset(nowMs = Date.now()) {
7624
+ const now = new Date(nowMs);
7625
+ return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)).toISOString();
7626
+ }
7627
+ function quotaResetDate(value, nowMs) {
7628
+ const parsed = typeof value === "string" ? Date.parse(value) : Number.NaN;
7629
+ return Number.isFinite(parsed) && parsed > nowMs + 6e4 ? new Date(parsed).toISOString() : nextCopilotMonthlyReset(nowMs);
7630
+ }
7631
+ function parseCopilotQuota(body, nowMs = Date.now()) {
7632
+ const root = recordOf2(body);
7633
+ const snapshots = recordOf2(root?.quotaSnapshots);
7634
+ if (!snapshots) {
7635
+ throw new CopilotApiError("Copilot quota response missing quotaSnapshots", "parse");
7636
+ }
7637
+ const chat = recordOf2(snapshots.chat);
7638
+ const legacy = recordOf2(snapshots.premium_interactions);
7639
+ const chatLimit = numberOf4(chat?.entitlementRequests);
7640
+ const quota = chat && (chatLimit !== void 0 && chatLimit > 0 || chat.isUnlimitedEntitlement === true) ? chat : legacy;
7641
+ if (!quota) {
7642
+ throw new CopilotApiError("Copilot quota response has no chat allowance", "parse");
7643
+ }
7644
+ const unlimited = quota.isUnlimitedEntitlement === true;
7645
+ const remainingPercent = numberOf4(quota.remainingPercentage);
7646
+ const utilization = unlimited ? null : remainingPercent === void 0 ? null : clampPercent(100 - remainingPercent);
7647
+ const limit = numberOf4(quota.entitlementRequests) ?? null;
7648
+ const used = numberOf4(quota.usedRequests) ?? null;
7649
+ const unit = quota.tokenBasedBilling === true ? "ai-credits" : "premium-requests";
7650
+ return {
7651
+ captured_at: new Date(nowMs).toISOString(),
7652
+ agent: "copilot",
7653
+ five_hour: { utilization: null, resets_at: null },
7654
+ seven_day: { utilization: null, resets_at: null },
7655
+ monthly: {
7656
+ utilization,
7657
+ resets_at: quotaResetDate(quota.resetDate, nowMs)
7658
+ },
7659
+ monthly_quota: {
7660
+ used,
7661
+ limit,
7662
+ remaining: used !== null && limit !== null ? Math.max(0, limit - used) : null,
7663
+ unit,
7664
+ unlimited
7665
+ },
7666
+ seven_day_opus: null,
7667
+ seven_day_sonnet: null,
7668
+ seven_day_oauth_apps: null,
7669
+ seven_day_cowork: null,
7670
+ extra_usage: null,
7671
+ plan_type: unit === "ai-credits" ? "AI credits" : "premium requests"
7672
+ };
7673
+ }
7674
+ var ContentLengthDecoder = class {
7675
+ buffer = Buffer.alloc(0);
7676
+ push(chunk2) {
7677
+ this.buffer = Buffer.concat([this.buffer, chunk2]);
7678
+ const messages = [];
7679
+ while (true) {
7680
+ const headerEnd = this.buffer.indexOf("\r\n\r\n");
7681
+ if (headerEnd === -1) break;
7682
+ const header = this.buffer.subarray(0, headerEnd).toString("ascii");
7683
+ const match = header.match(/(?:^|\r\n)Content-Length:\s*(\d+)/i);
7684
+ if (!match) {
7685
+ throw new CopilotApiError("Copilot RPC response missing Content-Length", "protocol");
7686
+ }
7687
+ const length = Number(match[1]);
7688
+ const bodyStart = headerEnd + 4;
7689
+ if (this.buffer.length < bodyStart + length) break;
7690
+ const body = this.buffer.subarray(bodyStart, bodyStart + length).toString("utf8");
7691
+ this.buffer = this.buffer.subarray(bodyStart + length);
7692
+ try {
7693
+ messages.push(JSON.parse(body));
7694
+ } catch {
7695
+ throw new CopilotApiError("Copilot RPC returned invalid JSON", "protocol");
7696
+ }
7697
+ }
7698
+ return messages;
7699
+ }
7700
+ };
7701
+ function rpcFrame(message) {
7702
+ const body = Buffer.from(JSON.stringify(message), "utf8");
7703
+ return Buffer.concat([
7704
+ Buffer.from(`Content-Length: ${body.length}\r
7705
+ \r
7706
+ `, "ascii"),
7707
+ body
7708
+ ]);
7709
+ }
7710
+ function resolveCopilotCliPath() {
7711
+ const configured = process.env.COPILOT_CLI_PATH?.trim();
7712
+ if (configured) return configured;
7713
+ const sibling = join4(dirname2(process.execPath), process.platform === "win32" ? "copilot.cmd" : "copilot");
7714
+ return existsSync6(sibling) ? sibling : process.platform === "win32" ? "copilot.cmd" : "copilot";
7715
+ }
7716
+ async function requestQuota(child) {
7717
+ const decoder = new ContentLengthDecoder();
7718
+ const pending = /* @__PURE__ */ new Map();
7719
+ let nextId = 1;
7720
+ const rejectAll = (error) => {
7721
+ for (const waiter of pending.values()) waiter.reject(error);
7722
+ pending.clear();
7723
+ };
7724
+ child.stdout.on("data", (chunk2) => {
7725
+ try {
7726
+ for (const value of decoder.push(chunk2)) {
7727
+ const message = recordOf2(value);
7728
+ const id = numberOf4(message?.id);
7729
+ if (id === void 0) continue;
7730
+ const waiter = pending.get(id);
7731
+ if (!waiter) continue;
7732
+ pending.delete(id);
7733
+ const rpcError = recordOf2(message?.error);
7734
+ if (rpcError) {
7735
+ waiter.reject(new CopilotApiError(
7736
+ typeof rpcError.message === "string" ? rpcError.message : "Copilot RPC request failed",
7737
+ "protocol"
7738
+ ));
7739
+ } else {
7740
+ waiter.resolve(message?.result);
7741
+ }
7742
+ }
7743
+ } catch (error) {
7744
+ rejectAll(error);
7745
+ }
7746
+ });
7747
+ const exited = new Promise((_, reject) => {
7748
+ child.once("error", (error) => {
7749
+ reject(new CopilotApiError(
7750
+ error.message,
7751
+ error.code === "ENOENT" ? "no_cli" : "protocol"
7752
+ ));
7753
+ });
7754
+ child.once("exit", (code) => {
7755
+ reject(new CopilotApiError(`Copilot RPC exited before responding (code ${code ?? "unknown"})`, "protocol"));
7756
+ });
7757
+ });
7758
+ const request = (method, params = {}) => {
7759
+ const id = nextId++;
7760
+ const response = new Promise((resolve4, reject) => {
7761
+ pending.set(id, { resolve: resolve4, reject });
7762
+ child.stdin.write(rpcFrame({ jsonrpc: "2.0", id, method, params }));
7763
+ });
7764
+ return Promise.race([response, exited]);
7765
+ };
7766
+ await request("connect", {});
7767
+ return request("account.getQuota", {});
7768
+ }
7769
+ async function fetchCopilotUsage() {
7770
+ const cliPath = resolveCopilotCliPath();
7771
+ const child = spawn(cliPath, ["--headless", "--no-auto-update", "--stdio", "--log-level", "none"], {
7772
+ cwd: process.cwd(),
7773
+ env: process.env,
7774
+ stdio: ["pipe", "pipe", "pipe"],
7775
+ windowsHide: true,
7776
+ shell: process.platform === "win32"
7777
+ });
7778
+ let stderr = "";
7779
+ child.stderr.on("data", (chunk2) => {
7780
+ stderr = (stderr + chunk2.toString("utf8")).slice(-2e3);
7781
+ });
7782
+ const timeout = new Promise((_, reject) => {
7783
+ const handle = setTimeout(() => {
7784
+ reject(new CopilotApiError("Timed out reading Copilot quota", "timeout"));
7785
+ }, RPC_TIMEOUT_MS);
7786
+ handle.unref();
7787
+ });
7788
+ try {
7789
+ const body = await Promise.race([requestQuota(child), timeout]);
7790
+ return parseCopilotQuota(body);
7791
+ } catch (error) {
7792
+ if (error instanceof CopilotApiError) {
7793
+ const message = `${error.message} ${stderr}`.toLowerCase();
7794
+ if (message.includes("not logged") || message.includes("authentication")) {
7795
+ throw new CopilotApiError("Copilot not logged in. Run `copilot login`.", "no_auth");
7796
+ }
7797
+ throw error;
7798
+ }
7799
+ throw new CopilotApiError(error.message, "protocol");
7800
+ } finally {
7801
+ child.kill();
7802
+ }
7803
+ }
7804
+
7158
7805
  // src/daemon-worker.ts
7159
7806
  init_storage();
7160
7807
  init_fs();
@@ -7196,9 +7843,9 @@ import { randomUUID } from "node:crypto";
7196
7843
 
7197
7844
  // ../entries/dist/fs.js
7198
7845
  init_fs();
7199
- import { readFileSync as readFileSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync8 } from "node:fs";
7846
+ import { readFileSync as readFileSync10, readdirSync as readdirSync2, writeFileSync as writeFileSync6, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync9 } from "node:fs";
7200
7847
  import { randomBytes } from "node:crypto";
7201
- import { join as join5 } from "node:path";
7848
+ import { join as join6 } from "node:path";
7202
7849
 
7203
7850
  // ../entries/dist/types.js
7204
7851
  var CURRENT_ENTRY_SCHEMA_VERSION = 2;
@@ -7271,12 +7918,12 @@ var PROMPT_FRAME_ORIGIN = {
7271
7918
 
7272
7919
  // ../entries/dist/digest-fs.js
7273
7920
  init_fs();
7274
- import { readFileSync as readFileSync9, readdirSync, writeFileSync as writeFileSync5, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync7 } from "node:fs";
7275
- import { dirname as dirname3, join as join4 } from "node:path";
7921
+ import { readFileSync as readFileSync9, readdirSync, writeFileSync as writeFileSync5, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync8 } from "node:fs";
7922
+ import { dirname as dirname4, join as join5 } from "node:path";
7276
7923
  var digestsDirCached = null;
7277
- function parseDigestFile(path10, expectedVersion) {
7924
+ function parseDigestFile(path11, expectedVersion) {
7278
7925
  try {
7279
- const parsed = JSON.parse(readFileSync9(path10, "utf8"));
7926
+ const parsed = JSON.parse(readFileSync9(path11, "utf8"));
7280
7927
  if (!parsed || typeof parsed !== "object")
7281
7928
  return null;
7282
7929
  if (parsed.version !== expectedVersion)
@@ -7296,14 +7943,14 @@ function digestsDir() {
7296
7943
  return digestsDirCached;
7297
7944
  }
7298
7945
  function dayDigestPath(date) {
7299
- return join4(digestsDir(), "day", `${date}.json`);
7946
+ return join5(digestsDir(), "day", `${date}.json`);
7300
7947
  }
7301
7948
  function weekDigestPath(monday) {
7302
- return join4(digestsDir(), "week", `${monday}.json`);
7949
+ return join5(digestsDir(), "week", `${monday}.json`);
7303
7950
  }
7304
7951
  function writeDayDigest(digest) {
7305
7952
  const final = dayDigestPath(digest.key);
7306
- mkdirSync4(dirname3(final), { recursive: true });
7953
+ mkdirSync4(dirname4(final), { recursive: true });
7307
7954
  const tmp = `${final}.tmp`;
7308
7955
  writeFileSync5(tmp, JSON.stringify(digest, null, 2), "utf8");
7309
7956
  if (process.platform !== "win32") {
@@ -7316,7 +7963,7 @@ function writeDayDigest(digest) {
7316
7963
  }
7317
7964
  function readDayDigest(date) {
7318
7965
  const p = dayDigestPath(date);
7319
- if (!existsSync7(p))
7966
+ if (!existsSync8(p))
7320
7967
  return null;
7321
7968
  return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
7322
7969
  }
@@ -7336,7 +7983,7 @@ function setTodayDigestInCache(date, digest, nowMs) {
7336
7983
  }
7337
7984
  function writeWeekDigest(digest) {
7338
7985
  const final = weekDigestPath(digest.key);
7339
- mkdirSync4(dirname3(final), { recursive: true });
7986
+ mkdirSync4(dirname4(final), { recursive: true });
7340
7987
  const tmp = `${final}.tmp`;
7341
7988
  writeFileSync5(tmp, JSON.stringify(digest, null, 2), "utf8");
7342
7989
  if (process.platform !== "win32") {
@@ -7349,7 +7996,7 @@ function writeWeekDigest(digest) {
7349
7996
  }
7350
7997
  function readWeekDigest(monday) {
7351
7998
  const p = weekDigestPath(monday);
7352
- if (!existsSync7(p))
7999
+ if (!existsSync8(p))
7353
8000
  return null;
7354
8001
  return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
7355
8002
  }
@@ -7379,7 +8026,7 @@ function entriesDir() {
7379
8026
  return entriesDirCached;
7380
8027
  }
7381
8028
  function pathFor(sessionId, localDay2) {
7382
- return join5(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
8029
+ return join6(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
7383
8030
  }
7384
8031
  function tmpPathFor(final) {
7385
8032
  return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
@@ -7427,17 +8074,17 @@ function writeEntryPreservingEnrichment(fresh) {
7427
8074
  }
7428
8075
  function readEntry(sessionId, localDay2) {
7429
8076
  const p = pathFor(sessionId, localDay2);
7430
- if (!existsSync8(p))
8077
+ if (!existsSync9(p))
7431
8078
  return null;
7432
8079
  const raw = readFileSync10(p, "utf8");
7433
8080
  return JSON.parse(raw);
7434
8081
  }
7435
8082
  function entryExists(sessionId, localDay2) {
7436
- return existsSync8(pathFor(sessionId, localDay2));
8083
+ return existsSync9(pathFor(sessionId, localDay2));
7437
8084
  }
7438
8085
  function listEntryKeys() {
7439
8086
  const dir = entriesDir();
7440
- if (!existsSync8(dir))
8087
+ if (!existsSync9(dir))
7441
8088
  return [];
7442
8089
  return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
7443
8090
  }
@@ -7457,7 +8104,7 @@ function listEntriesForDay(localDay2) {
7457
8104
  // src/perception/build-entries.ts
7458
8105
  init_dist();
7459
8106
  import { statSync as statSync2, readFileSync as readFileSync11 } from "node:fs";
7460
- import { basename as basename2, dirname as dirname4 } from "node:path";
8107
+ import { basename as basename2, dirname as dirname5 } from "node:path";
7461
8108
 
7462
8109
  // ../entries/dist/signals.js
7463
8110
  init_dist();
@@ -7690,7 +8337,7 @@ function viewEvent(ev) {
7690
8337
  cwd: rawCwd
7691
8338
  };
7692
8339
  }
7693
- var IDLE_GAP_MS5 = 3 * 60 * 1e3;
8340
+ var IDLE_GAP_MS6 = 3 * 60 * 1e3;
7694
8341
  var INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
7695
8342
  var PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
7696
8343
  var BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
@@ -7802,7 +8449,7 @@ function closeTurn(t, closed, cwd) {
7802
8449
  let active = 0;
7803
8450
  for (let i = 1; i < ts.length; i++) {
7804
8451
  const dt = ts[i] - ts[i - 1];
7805
- if (dt < IDLE_GAP_MS5)
8452
+ if (dt < IDLE_GAP_MS6)
7806
8453
  active += dt;
7807
8454
  }
7808
8455
  closed.push({
@@ -7999,7 +8646,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
7999
8646
  let activeMs2 = 0;
8000
8647
  for (let i = 1; i < tsSorted.length; i++) {
8001
8648
  const dt = tsSorted[i] - tsSorted[i - 1];
8002
- if (dt < IDLE_GAP_MS5)
8649
+ if (dt < IDLE_GAP_MS6)
8003
8650
  activeMs2 += dt;
8004
8651
  }
8005
8652
  const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
@@ -8207,7 +8854,7 @@ function buildEntriesForFile(filePath) {
8207
8854
  if (rawLines.length === 0) return null;
8208
8855
  const { meta, events } = parseTranscript(rawLines);
8209
8856
  const fileName = basename2(filePath);
8210
- const projectDir = basename2(dirname4(filePath));
8857
+ const projectDir = basename2(dirname5(filePath));
8211
8858
  const sessionId = fileName.replace(/\.jsonl$/, "");
8212
8859
  const sd = {
8213
8860
  ...meta,
@@ -8457,7 +9104,7 @@ function buildIngestPayload(inputs) {
8457
9104
  return {
8458
9105
  ingestId: randomUUID(),
8459
9106
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
8460
- cliVersion: "0.16.6",
9107
+ cliVersion: "0.16.8",
8461
9108
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
8462
9109
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
8463
9110
  ...richRollup ? { richRollup } : {},
@@ -8484,8 +9131,8 @@ async function pushToTeamServer(config, payload) {
8484
9131
  }
8485
9132
 
8486
9133
  // src/team/git-remote.ts
8487
- import { existsSync as existsSync9, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
8488
- import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, resolve as resolve2 } from "node:path";
9134
+ import { existsSync as existsSync10, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
9135
+ import { dirname as dirname6, isAbsolute as isAbsolute2, join as join7, resolve as resolve2 } from "node:path";
8489
9136
  var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
8490
9137
  function parseGithubRemote(url) {
8491
9138
  const m = url.trim().match(GITHUB_URL_RE);
@@ -8506,19 +9153,19 @@ function originUrl2(configText) {
8506
9153
  return null;
8507
9154
  }
8508
9155
  function gitConfigPathFor(dir) {
8509
- const dotGit = join6(dir, ".git");
9156
+ const dotGit = join7(dir, ".git");
8510
9157
  const st = statSync3(dotGit, { throwIfNoEntry: false });
8511
9158
  if (!st) return null;
8512
- if (st.isDirectory()) return join6(dotGit, "config");
9159
+ if (st.isDirectory()) return join7(dotGit, "config");
8513
9160
  const m = readFileSync12(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
8514
9161
  if (!m) return null;
8515
9162
  const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
8516
- const commondirFile = join6(gd, "commondir");
8517
- if (existsSync9(commondirFile)) {
9163
+ const commondirFile = join7(gd, "commondir");
9164
+ if (existsSync10(commondirFile)) {
8518
9165
  const common = readFileSync12(commondirFile, "utf8").trim();
8519
- return join6(isAbsolute2(common) ? common : resolve2(gd, common), "config");
9166
+ return join7(isAbsolute2(common) ? common : resolve2(gd, common), "config");
8520
9167
  }
8521
- return join6(gd, "config");
9168
+ return join7(gd, "config");
8522
9169
  }
8523
9170
  function createRepoResolver() {
8524
9171
  const cache = /* @__PURE__ */ new Map();
@@ -8528,14 +9175,14 @@ function createRepoResolver() {
8528
9175
  if (hit !== void 0) return hit;
8529
9176
  let repo = null;
8530
9177
  try {
8531
- for (let d = dir; ; d = dirname5(d)) {
9178
+ for (let d = dir; ; d = dirname6(d)) {
8532
9179
  const config = gitConfigPathFor(d);
8533
- if (config && existsSync9(config)) {
9180
+ if (config && existsSync10(config)) {
8534
9181
  const url = originUrl2(readFileSync12(config, "utf8"));
8535
9182
  repo = url ? parseGithubRemote(url) : null;
8536
9183
  break;
8537
9184
  }
8538
- if (d === dirname5(d)) break;
9185
+ if (d === dirname6(d)) break;
8539
9186
  }
8540
9187
  } catch {
8541
9188
  repo = null;
@@ -8548,12 +9195,12 @@ function createRepoResolver() {
8548
9195
  // src/team/queue.ts
8549
9196
  init_fs();
8550
9197
  import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, appendFileSync as appendFileSync4, statSync as statSync4, mkdirSync as mkdirSync6 } from "node:fs";
8551
- import { dirname as dirname6 } from "node:path";
9198
+ import { dirname as dirname7 } from "node:path";
8552
9199
  var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
8553
9200
  var MAX_SIZE_BYTES = 10 * 1024 * 1024;
8554
9201
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
8555
9202
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
8556
- mkdirSync6(dirname6(queuePath), { recursive: true });
9203
+ mkdirSync6(dirname7(queuePath), { recursive: true });
8557
9204
  const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
8558
9205
  appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
8559
9206
  try {
@@ -8601,8 +9248,8 @@ init_storage();
8601
9248
  import { randomUUID as randomUUID2 } from "node:crypto";
8602
9249
 
8603
9250
  // src/usage/profile.ts
8604
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
8605
- import { dirname as dirname7 } from "node:path";
9251
+ import { existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync14, writeFileSync as writeFileSync8 } from "node:fs";
9252
+ import { dirname as dirname8 } from "node:path";
8606
9253
  var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
8607
9254
  var BETA_HEADER2 = "oauth-2025-04-20";
8608
9255
  var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
@@ -8645,7 +9292,7 @@ async function fetchProfile(nowMs = Date.now()) {
8645
9292
  };
8646
9293
  }
8647
9294
  function readCachedProfile(cachePath) {
8648
- if (!existsSync10(cachePath)) return null;
9295
+ if (!existsSync11(cachePath)) return null;
8649
9296
  try {
8650
9297
  const raw = JSON.parse(readFileSync14(cachePath, "utf8"));
8651
9298
  if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
@@ -8655,7 +9302,7 @@ function readCachedProfile(cachePath) {
8655
9302
  }
8656
9303
  }
8657
9304
  function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
8658
- mkdirSync7(dirname7(cachePath), { recursive: true });
9305
+ mkdirSync7(dirname8(cachePath), { recursive: true });
8659
9306
  writeFileSync8(
8660
9307
  cachePath,
8661
9308
  JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
@@ -8843,12 +9490,12 @@ function readPendingSyncLog(watermark) {
8843
9490
  // src/team/last-push.ts
8844
9491
  init_fs();
8845
9492
  import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
8846
- import { join as join7 } from "node:path";
9493
+ import { join as join8 } from "node:path";
8847
9494
  var LAST_PUSH_FILE = "team-last-push.json";
8848
9495
  function write(record, dir) {
8849
9496
  const d = dir ?? cclensHome();
8850
9497
  mkdirSync8(d, { recursive: true });
8851
- writeFileSync9(join7(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
9498
+ writeFileSync9(join8(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
8852
9499
  }
8853
9500
  function writeLastPushSuccess(payload, dir) {
8854
9501
  write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
@@ -9448,8 +10095,8 @@ init_fs();
9448
10095
 
9449
10096
  // src/perception/state.ts
9450
10097
  init_fs();
9451
- import { existsSync as existsSync12, readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
9452
- import { dirname as dirname9 } from "node:path";
10098
+ import { existsSync as existsSync13, readFileSync as readFileSync16, writeFileSync as writeFileSync10, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
10099
+ import { dirname as dirname10 } from "node:path";
9453
10100
  var STALE_MS = 15 * 60 * 1e3;
9454
10101
  var pathCached = null;
9455
10102
  function statePath() {
@@ -9459,7 +10106,7 @@ function statePath() {
9459
10106
  }
9460
10107
  function readState() {
9461
10108
  const p = statePath();
9462
- if (!existsSync12(p)) {
10109
+ if (!existsSync13(p)) {
9463
10110
  return {
9464
10111
  sweep_in_progress: false,
9465
10112
  last_sweep_started_at: null,
@@ -9472,7 +10119,7 @@ function readState() {
9472
10119
  }
9473
10120
  function writeState(s) {
9474
10121
  const p = statePath();
9475
- mkdirSync9(dirname9(p), { recursive: true });
10122
+ mkdirSync9(dirname10(p), { recursive: true });
9476
10123
  const tmp = `${p}.tmp`;
9477
10124
  writeFileSync10(tmp, JSON.stringify(s, null, 2), "utf8");
9478
10125
  renameSync4(tmp, p);
@@ -9504,17 +10151,17 @@ function updateCheckpoint(jsonlPath, cp) {
9504
10151
 
9505
10152
  // src/perception/scan.ts
9506
10153
  import { readdirSync as readdirSync4 } from "node:fs";
9507
- import { join as join9 } from "node:path";
10154
+ import { join as join10 } from "node:path";
9508
10155
  import { homedir as homedir4 } from "node:os";
9509
10156
  async function listAllSessionJsonls(root) {
9510
- const projectsRoot = root ?? join9(homedir4(), ".claude", "projects");
10157
+ const projectsRoot = root ?? join10(homedir4(), ".claude", "projects");
9511
10158
  const out = [];
9512
10159
  try {
9513
10160
  for (const project of readdirSync4(projectsRoot)) {
9514
- const dir = join9(projectsRoot, project);
10161
+ const dir = join10(projectsRoot, project);
9515
10162
  try {
9516
10163
  for (const f of readdirSync4(dir)) {
9517
- if (f.endsWith(".jsonl")) out.push(join9(dir, f));
10164
+ if (f.endsWith(".jsonl")) out.push(join10(dir, f));
9518
10165
  }
9519
10166
  } catch {
9520
10167
  }
@@ -10075,8 +10722,8 @@ function getErrorMap() {
10075
10722
 
10076
10723
  // ../../node_modules/zod/v3/helpers/parseUtil.js
10077
10724
  var makeIssue = (params) => {
10078
- const { data, path: path10, errorMaps, issueData } = params;
10079
- const fullPath = [...path10, ...issueData.path || []];
10725
+ const { data, path: path11, errorMaps, issueData } = params;
10726
+ const fullPath = [...path11, ...issueData.path || []];
10080
10727
  const fullIssue = {
10081
10728
  ...issueData,
10082
10729
  path: fullPath
@@ -10192,11 +10839,11 @@ var errorUtil;
10192
10839
 
10193
10840
  // ../../node_modules/zod/v3/types.js
10194
10841
  var ParseInputLazyPath = class {
10195
- constructor(parent, value, path10, key) {
10842
+ constructor(parent, value, path11, key) {
10196
10843
  this._cachedPath = [];
10197
10844
  this.parent = parent;
10198
10845
  this.data = value;
10199
- this._path = path10;
10846
+ this._path = path11;
10200
10847
  this._key = key;
10201
10848
  }
10202
10849
  get path() {
@@ -13729,14 +14376,14 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
13729
14376
 
13730
14377
  // ../entries/dist/llm-runner.js
13731
14378
  init_fs();
13732
- import { spawn } from "node:child_process";
13733
- import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync12, existsSync as existsSync14 } from "node:fs";
13734
- import { join as join11 } from "node:path";
14379
+ import { spawn as spawn2 } from "node:child_process";
14380
+ import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync12, existsSync as existsSync15 } from "node:fs";
14381
+ import { join as join12 } from "node:path";
13735
14382
  import { randomUUID as randomUUID4 } from "node:crypto";
13736
14383
 
13737
14384
  // ../entries/dist/tmux-runner.js
13738
- import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync13, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync17, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
13739
- import { join as join10 } from "node:path";
14385
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11, existsSync as existsSync14, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync17, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
14386
+ import { join as join11 } from "node:path";
13740
14387
  import { homedir as homedir5 } from "node:os";
13741
14388
  import { spawnSync } from "node:child_process";
13742
14389
  var TmuxUnavailableError = class extends Error {
@@ -13765,13 +14412,13 @@ function tmuxRunnerAvailable() {
13765
14412
  return { ok: true };
13766
14413
  }
13767
14414
  function runtimeCwd() {
13768
- const dir = join10(homedir5(), ".cclens", "runtime");
13769
- if (!existsSync13(dir))
14415
+ const dir = join11(homedir5(), ".cclens", "runtime");
14416
+ if (!existsSync14(dir))
13770
14417
  mkdirSync10(dir, { recursive: true });
13771
14418
  return realpathSync2(dir);
13772
14419
  }
13773
14420
  function ensureRuntimeCwdTrusted(cwd) {
13774
- const cfgPath = join10(homedir5(), ".claude.json");
14421
+ const cfgPath = join11(homedir5(), ".claude.json");
13775
14422
  let cfg;
13776
14423
  try {
13777
14424
  cfg = JSON.parse(readFileSync17(cfgPath, "utf8"));
@@ -13817,9 +14464,9 @@ async function runClaudeUnderTmuxImpl(args) {
13817
14464
  ensureRuntimeCwdTrusted(cwd);
13818
14465
  const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
13819
14466
  const sessionName = `cclens-${runId}`;
13820
- const systemFile = join10(cwd, `system-${runId}.txt`);
13821
- const userFile = join10(cwd, `user-${runId}.txt`);
13822
- const wrapper = join10(cwd, `run-${runId}.sh`);
14467
+ const systemFile = join11(cwd, `system-${runId}.txt`);
14468
+ const userFile = join11(cwd, `user-${runId}.txt`);
14469
+ const wrapper = join11(cwd, `run-${runId}.sh`);
13823
14470
  writeFileSync11(systemFile, args.systemPrompt);
13824
14471
  writeFileSync11(userFile, args.reminder ? `${args.userPrompt}
13825
14472
 
@@ -13838,10 +14485,10 @@ exec ${shellEscape(claudeBin)} \\
13838
14485
  "$USR"
13839
14486
  `, { mode: 493 });
13840
14487
  const existingBefore = snapshotAllTranscripts();
13841
- const spawn3 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
13842
- if (spawn3.status !== 0) {
14488
+ const spawn4 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
14489
+ if (spawn4.status !== 0) {
13843
14490
  cleanup(cwd, runId, tmuxBin, sessionName);
13844
- throw new TmuxRunError(`tmux new-session failed: ${spawn3.stderr.trim()}`);
14491
+ throw new TmuxRunError(`tmux new-session failed: ${spawn4.stderr.trim()}`);
13845
14492
  }
13846
14493
  const onAbort = () => {
13847
14494
  try {
@@ -13898,7 +14545,7 @@ function num(v) {
13898
14545
  function sleep(ms) {
13899
14546
  return new Promise((r) => setTimeout(r, ms));
13900
14547
  }
13901
- var PROJECTS_ROOT = () => join10(homedir5(), ".claude", "projects");
14548
+ var PROJECTS_ROOT = () => join11(homedir5(), ".claude", "projects");
13902
14549
  function snapshotAllTranscripts() {
13903
14550
  const out = /* @__PURE__ */ new Set();
13904
14551
  const root = PROJECTS_ROOT();
@@ -13909,7 +14556,7 @@ function snapshotAllTranscripts() {
13909
14556
  return out;
13910
14557
  }
13911
14558
  for (const sub of subs) {
13912
- const dir = join10(root, sub);
14559
+ const dir = join11(root, sub);
13913
14560
  let files;
13914
14561
  try {
13915
14562
  files = readdirSync5(dir);
@@ -13918,15 +14565,15 @@ function snapshotAllTranscripts() {
13918
14565
  }
13919
14566
  for (const f of files) {
13920
14567
  if (f.endsWith(".jsonl"))
13921
- out.add(join10(dir, f));
14568
+ out.add(join11(dir, f));
13922
14569
  }
13923
14570
  }
13924
14571
  return out;
13925
14572
  }
13926
- function readJsonlCwd(path10, maxLines = 8) {
14573
+ function readJsonlCwd(path11, maxLines = 8) {
13927
14574
  let raw;
13928
14575
  try {
13929
- raw = readFileSync17(path10, "utf8");
14576
+ raw = readFileSync17(path11, "utf8");
13930
14577
  } catch {
13931
14578
  return void 0;
13932
14579
  }
@@ -13959,7 +14606,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
13959
14606
  subs = [];
13960
14607
  }
13961
14608
  for (const sub of subs) {
13962
- const dir = join10(root, sub);
14609
+ const dir = join11(root, sub);
13963
14610
  let files;
13964
14611
  try {
13965
14612
  files = readdirSync5(dir);
@@ -13969,7 +14616,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
13969
14616
  for (const f of files) {
13970
14617
  if (!f.endsWith(".jsonl"))
13971
14618
  continue;
13972
- const full = join10(dir, f);
14619
+ const full = join11(dir, f);
13973
14620
  if (existingBefore.has(full))
13974
14621
  continue;
13975
14622
  if (readJsonlCwd(full) === targetCwd)
@@ -13980,10 +14627,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
13980
14627
  }
13981
14628
  throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
13982
14629
  }
13983
- function parseTranscript2(path10, defaultModel) {
14630
+ function parseTranscript2(path11, defaultModel) {
13984
14631
  let raw;
13985
14632
  try {
13986
- raw = readFileSync17(path10, "utf8");
14633
+ raw = readFileSync17(path11, "utf8");
13987
14634
  } catch {
13988
14635
  return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
13989
14636
  }
@@ -14043,7 +14690,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
14043
14690
  }
14044
14691
  for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
14045
14692
  try {
14046
- unlinkSync3(join10(cwd, f));
14693
+ unlinkSync3(join11(cwd, f));
14047
14694
  } catch {
14048
14695
  }
14049
14696
  }
@@ -14058,7 +14705,7 @@ function shellEscape(s) {
14058
14705
  // ../entries/dist/llm-runner.js
14059
14706
  var RUNS_DIR = cclensPath("llm-runs");
14060
14707
  function ensureRunsDir() {
14061
- if (!existsSync14(RUNS_DIR)) {
14708
+ if (!existsSync15(RUNS_DIR)) {
14062
14709
  try {
14063
14710
  mkdirSync11(RUNS_DIR, { recursive: true });
14064
14711
  } catch {
@@ -14087,17 +14734,17 @@ function newRunId(kind) {
14087
14734
  return `${ts}_${kind}_${short}`;
14088
14735
  }
14089
14736
  function tracePath(runId) {
14090
- return join11(RUNS_DIR, `${runId}.jsonl`);
14737
+ return join12(RUNS_DIR, `${runId}.jsonl`);
14091
14738
  }
14092
- function safeAppend(path10, line) {
14739
+ function safeAppend(path11, line) {
14093
14740
  try {
14094
- appendFileSync5(path10, line);
14741
+ appendFileSync5(path11, line);
14095
14742
  } catch {
14096
14743
  }
14097
14744
  }
14098
- function safeWrite(path10, line) {
14745
+ function safeWrite(path11, line) {
14099
14746
  try {
14100
- writeFileSync12(path10, line);
14747
+ writeFileSync12(path11, line);
14101
14748
  } catch {
14102
14749
  }
14103
14750
  }
@@ -14230,7 +14877,7 @@ function runClaudePrintMode(args) {
14230
14877
  "--append-system-prompt",
14231
14878
  args.systemPrompt
14232
14879
  ];
14233
- const proc = spawn("claude", claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: { ...process.env } });
14880
+ const proc = spawn2("claude", claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: { ...process.env } });
14234
14881
  safeAppend(trace, JSON.stringify({ _meta: { type: "spawned", run_id: runId, pid: proc.pid } }) + "\n");
14235
14882
  const stdinPayload = args.reminder ? `${args.userPrompt}
14236
14883
 
@@ -14486,8 +15133,8 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
14486
15133
 
14487
15134
  // ../entries/dist/budget.js
14488
15135
  init_fs();
14489
- import { appendFileSync as appendFileSync6, readFileSync as readFileSync18, existsSync as existsSync15, mkdirSync as mkdirSync12 } from "node:fs";
14490
- import { dirname as dirname10 } from "node:path";
15136
+ import { appendFileSync as appendFileSync6, readFileSync as readFileSync18, existsSync as existsSync16, mkdirSync as mkdirSync12 } from "node:fs";
15137
+ import { dirname as dirname11 } from "node:path";
14491
15138
  var spendPathCached = null;
14492
15139
  function spendPath() {
14493
15140
  if (spendPathCached)
@@ -14497,12 +15144,12 @@ function spendPath() {
14497
15144
  }
14498
15145
  function appendSpend(record) {
14499
15146
  const p = spendPath();
14500
- mkdirSync12(dirname10(p), { recursive: true });
15147
+ mkdirSync12(dirname11(p), { recursive: true });
14501
15148
  appendFileSync6(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
14502
15149
  }
14503
15150
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
14504
15151
  const p = spendPath();
14505
- if (!existsSync15(p))
15152
+ if (!existsSync16(p))
14506
15153
  return 0;
14507
15154
  const year = now.getUTCFullYear();
14508
15155
  const month = now.getUTCMonth();
@@ -14529,7 +15176,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
14529
15176
 
14530
15177
  // ../entries/dist/pipeline-lock.js
14531
15178
  init_fs();
14532
- import { writeFileSync as writeFileSync13, unlinkSync as unlinkSync4, existsSync as existsSync16, readFileSync as readFileSync19, statSync as statSync7 } from "node:fs";
15179
+ import { writeFileSync as writeFileSync13, unlinkSync as unlinkSync4, existsSync as existsSync17, readFileSync as readFileSync19, statSync as statSync7 } from "node:fs";
14533
15180
  var STALE_MS2 = 60 * 1e3;
14534
15181
  var HEARTBEAT_MS = 30 * 1e3;
14535
15182
  var lockPathCached = null;
@@ -14575,7 +15222,7 @@ function pidAlive(pid) {
14575
15222
  }
14576
15223
  function interactiveLockFresh(nowMs) {
14577
15224
  const p = lockPath();
14578
- if (!existsSync16(p))
15225
+ if (!existsSync17(p))
14579
15226
  return false;
14580
15227
  try {
14581
15228
  const mtime = statSync7(p).mtimeMs;
@@ -14596,7 +15243,7 @@ function interactiveLockFresh(nowMs) {
14596
15243
  var THIRTY_MIN_MS = 30 * 60 * 1e3;
14597
15244
 
14598
15245
  // ../entries/dist/settings.js
14599
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync14, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync17 } from "node:fs";
15246
+ import { readFileSync as readFileSync20, writeFileSync as writeFileSync14, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync18 } from "node:fs";
14600
15247
  init_fs();
14601
15248
  var DEFAULT_SETTINGS = {
14602
15249
  ai_features: {
@@ -14628,7 +15275,7 @@ function fromDisk(d) {
14628
15275
  }
14629
15276
  function readSettings() {
14630
15277
  const p = settingsPath();
14631
- if (!existsSync17(p))
15278
+ if (!existsSync18(p))
14632
15279
  return DEFAULT_SETTINGS;
14633
15280
  try {
14634
15281
  const raw = readFileSync20(p, "utf8");
@@ -16302,7 +16949,7 @@ var MonthDigestResponseSchema = external_exports.object({
16302
16949
  }).passthrough();
16303
16950
 
16304
16951
  // ../entries/dist/top-sessions.js
16305
- var IDLE_GAP_MS6 = 3 * 60 * 1e3;
16952
+ var IDLE_GAP_MS7 = 3 * 60 * 1e3;
16306
16953
  var LONG_AUTONOMOUS_MIN = 20;
16307
16954
  var N_USER = 150;
16308
16955
  var N_FIRST_AGENT = 150;
@@ -16333,7 +16980,7 @@ function activeMs(timestamps) {
16333
16980
  let active = 0;
16334
16981
  for (let i = 1; i < ts.length; i++) {
16335
16982
  const dt = ts[i] - ts[i - 1];
16336
- if (dt < IDLE_GAP_MS6)
16983
+ if (dt < IDLE_GAP_MS7)
16337
16984
  active += dt;
16338
16985
  }
16339
16986
  return active;
@@ -16507,7 +17154,7 @@ function buildSessionSlice(entry, events, daySignature) {
16507
17154
  let intEnd = sortedTs[0];
16508
17155
  for (let i = 1; i < sortedTs.length; i++) {
16509
17156
  const dt = sortedTs[i] - intEnd;
16510
- if (dt >= IDLE_GAP_MS6) {
17157
+ if (dt >= IDLE_GAP_MS7) {
16511
17158
  intervals.push({
16512
17159
  start_min: fmtMin(intStart - sliceStartMs),
16513
17160
  end_min: fmtMin(intEnd - sliceStartMs)
@@ -17391,14 +18038,14 @@ async function getUpdateAvailability() {
17391
18038
  if (isDevMode()) return null;
17392
18039
  const latest = await fetchLatestVersion();
17393
18040
  if (latest === null) return {
17394
- current: "0.16.6",
18041
+ current: "0.16.8",
17395
18042
  latest: null,
17396
18043
  updateAvailable: false
17397
18044
  };
17398
18045
  return {
17399
- current: "0.16.6",
18046
+ current: "0.16.8",
17400
18047
  latest,
17401
- updateAvailable: shouldUpdate("0.16.6", latest)
18048
+ updateAvailable: shouldUpdate("0.16.8", latest)
17402
18049
  };
17403
18050
  }
17404
18051
 
@@ -17408,11 +18055,12 @@ var DAEMON_LOG = cclensPath("daemon.log");
17408
18055
  var UPDATE_STATE = cclensPath("daemon-update.json");
17409
18056
  var WATCHDOG_INTERVAL_MS = 5 * 1e3;
17410
18057
  var AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
17411
- mkdirSync14(dirname11(USAGE_LOG3), { recursive: true });
18058
+ mkdirSync14(dirname12(USAGE_LOG3), { recursive: true });
17412
18059
  function log2(level, message) {
17413
18060
  appendDaemonLogLine(level, message);
17414
18061
  }
17415
18062
  var nextPollAtMs = 0;
18063
+ var nextAuxPollAtMs = 0;
17416
18064
  var nextTeamSyncAtMs = 0;
17417
18065
  var firstTeamSync = true;
17418
18066
  var currentIntervalMs = BASE_INTERVAL_MS;
@@ -17466,7 +18114,7 @@ function nextUpdateCheckFromState(nowMs) {
17466
18114
  }
17467
18115
  var nextUpdateCheckAtMs = nextUpdateCheckFromState(Date.now());
17468
18116
  function cliEntryPath() {
17469
- return join12(dirname11(fileURLToPath(import.meta.url)), "index.js");
18117
+ return join13(dirname12(fileURLToPath(import.meta.url)), "index.js");
17470
18118
  }
17471
18119
  async function runDaemonUpdateCheck() {
17472
18120
  if (process.env.FLEETLENS_DAEMON_AUTO_UPDATE === "0") {
@@ -17498,7 +18146,7 @@ async function runDaemonUpdateCheck() {
17498
18146
  return;
17499
18147
  }
17500
18148
  const entry = cliEntryPath();
17501
- if (!existsSync18(entry)) {
18149
+ if (!existsSync19(entry)) {
17502
18150
  log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
17503
18151
  return;
17504
18152
  }
@@ -17507,7 +18155,7 @@ async function runDaemonUpdateCheck() {
17507
18155
  logFd = openSync(DAEMON_LOG, "a");
17508
18156
  } catch {
17509
18157
  }
17510
- const child = spawn2(process.execPath, [entry, "update"], {
18158
+ const child = spawn3(process.execPath, [entry, "update"], {
17511
18159
  detached: true,
17512
18160
  stdio: ["ignore", logFd, logFd],
17513
18161
  env: { ...process.env, FLEETLENS_UPDATE_SOURCE: "daemon" }
@@ -17537,7 +18185,7 @@ async function runDaemonUpdateCheck() {
17537
18185
  nextUpdateCheckAtMs = Date.now() + AUTO_UPDATE_INTERVAL_MS;
17538
18186
  }
17539
18187
  }
17540
- async function tick() {
18188
+ async function pollAuxiliaryUsage() {
17541
18189
  for (const source of agentSources) {
17542
18190
  if (source.kind === "claude-code") continue;
17543
18191
  if (!source.usagePoller) continue;
@@ -17577,6 +18225,18 @@ async function tick() {
17577
18225
  log2("warn", `zai poll failed: ${err.message}`);
17578
18226
  }
17579
18227
  }
18228
+ try {
18229
+ const copilotSnapshot = await fetchCopilotUsage();
18230
+ appendSnapshot(USAGE_LOG3, copilotSnapshot);
18231
+ const monthly = copilotSnapshot.monthly?.utilization;
18232
+ log2("info", `copilot snapshot monthly=${monthly === null || monthly === void 0 ? "\u2014" : `${monthly}%`}`);
18233
+ } catch (err) {
18234
+ if (err instanceof CopilotApiError && err.code === "no_cli") {
18235
+ pruneAgent(USAGE_LOG3, "copilot");
18236
+ } else if (!(err instanceof CopilotApiError && err.code === "no_auth")) {
18237
+ log2("warn", `copilot poll failed: ${err.message}`);
18238
+ }
18239
+ }
17580
18240
  try {
17581
18241
  const codexSnapshot = await fetchCodexUsage();
17582
18242
  appendSnapshot(USAGE_LOG3, codexSnapshot);
@@ -17608,6 +18268,8 @@ async function tick() {
17608
18268
  log2("warn", `grok poll failed: ${err.message}`);
17609
18269
  }
17610
18270
  }
18271
+ }
18272
+ async function pollClaudeUsage() {
17611
18273
  try {
17612
18274
  const snapshot = await fetchUsage();
17613
18275
  appendSnapshot(USAGE_LOG3, snapshot);
@@ -17642,6 +18304,10 @@ function sleep2(ms) {
17642
18304
  async function runLoop() {
17643
18305
  while (true) {
17644
18306
  const now = Date.now();
18307
+ if (now >= nextAuxPollAtMs) {
18308
+ await pollAuxiliaryUsage();
18309
+ nextAuxPollAtMs = Date.now() + BASE_INTERVAL_MS;
18310
+ }
17645
18311
  if (now >= nextPollAtMs) {
17646
18312
  if (nextPollAtMs > 0 && now - nextPollAtMs > currentIntervalMs) {
17647
18313
  log2(
@@ -17664,7 +18330,7 @@ async function runLoop() {
17664
18330
  log2("info", "token refreshed; resuming polls");
17665
18331
  waitingForRefresh = false;
17666
18332
  }
17667
- const outcome = await tick();
18333
+ const outcome = await pollClaudeUsage();
17668
18334
  scheduleAfter(Date.now(), outcome);
17669
18335
  }
17670
18336
  }