fleetlens 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/app-path-routes-manifest.json +1 -0
  3. package/app/apps/web/.next/build-manifest.json +5 -5
  4. package/app/apps/web/.next/prerender-manifest.json +3 -3
  5. package/app/apps/web/.next/routes-manifest.json +6 -0
  6. package/app/apps/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  7. package/app/apps/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/app/apps/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  12. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  13. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  14. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  15. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/app/apps/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  17. package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
  18. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +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/jobs/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  27. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  29. package/app/apps/web/.next/server/app/changelog/page/app-paths-manifest.json +3 -0
  30. package/app/apps/web/.next/server/app/changelog/page/build-manifest.json +17 -0
  31. package/app/apps/web/.next/server/app/changelog/page/next-font-manifest.json +6 -0
  32. package/app/apps/web/.next/server/app/changelog/page/react-loadable-manifest.json +1 -0
  33. package/app/apps/web/.next/server/app/changelog/page/server-reference-manifest.json +4 -0
  34. package/app/apps/web/.next/server/app/changelog/page.js +17 -0
  35. package/app/apps/web/.next/server/app/changelog/page.js.map +5 -0
  36. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -0
  37. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +3 -0
  38. package/app/apps/web/.next/server/app/day/[date]/page/build-manifest.json +2 -2
  39. package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
  40. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  41. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  42. package/app/apps/web/.next/server/app/day/page/build-manifest.json +2 -2
  43. package/app/apps/web/.next/server/app/day/page.js +1 -1
  44. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  45. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  46. package/app/apps/web/.next/server/app/digest/[date]/page/build-manifest.json +2 -2
  47. package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
  48. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  49. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  50. package/app/apps/web/.next/server/app/digest/page/build-manifest.json +2 -2
  51. package/app/apps/web/.next/server/app/digest/page.js +1 -1
  52. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  53. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  54. package/app/apps/web/.next/server/app/insights/[key]/page/build-manifest.json +2 -2
  55. package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
  56. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  58. package/app/apps/web/.next/server/app/insights/page/build-manifest.json +2 -2
  59. package/app/apps/web/.next/server/app/insights/page.js +1 -1
  60. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  61. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  62. package/app/apps/web/.next/server/app/page/build-manifest.json +2 -2
  63. package/app/apps/web/.next/server/app/page.js +1 -1
  64. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  65. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  66. package/app/apps/web/.next/server/app/parallelism/page/build-manifest.json +2 -2
  67. package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
  68. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  69. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  70. package/app/apps/web/.next/server/app/projects/[slug]/page/build-manifest.json +2 -2
  71. package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
  72. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  73. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  74. package/app/apps/web/.next/server/app/projects/page/build-manifest.json +2 -2
  75. package/app/apps/web/.next/server/app/projects/page.js +1 -1
  76. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  77. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  78. package/app/apps/web/.next/server/app/runs/page/build-manifest.json +2 -2
  79. package/app/apps/web/.next/server/app/runs/page.js +1 -1
  80. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  81. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  82. package/app/apps/web/.next/server/app/sessions/[id]/page/build-manifest.json +2 -2
  83. package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -1
  84. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  85. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  86. package/app/apps/web/.next/server/app/sessions/page/build-manifest.json +2 -2
  87. package/app/apps/web/.next/server/app/sessions/page.js +1 -1
  88. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  89. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  90. package/app/apps/web/.next/server/app/settings/page/build-manifest.json +2 -2
  91. package/app/apps/web/.next/server/app/settings/page.js +1 -1
  92. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  93. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  94. package/app/apps/web/.next/server/app/usage/page/build-manifest.json +2 -2
  95. package/app/apps/web/.next/server/app/usage/page.js +1 -1
  96. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  97. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  98. package/app/apps/web/.next/server/app-paths-manifest.json +1 -0
  99. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.z48ue._.js +1 -1
  100. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0dctov1._.js +2 -2
  101. package/app/apps/web/.next/server/chunks/packages_09hmrqx._.js +1 -1
  102. package/app/apps/web/.next/server/chunks/packages_118y1lp._.js +1 -1
  103. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +1 -1
  104. package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0vvlth5._.js → [root-of-the-server]__02~v50d._.js} +2 -2
  105. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__09rjz7_._.js +3 -0
  106. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
  107. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ytdqxt._.js +3 -0
  108. package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
  109. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_changelog_page_actions_12_04gy.js +3 -0
  110. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
  111. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_changelog-mark-read_tsx_0hm41sv._.js +3 -0
  112. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +3 -0
  113. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0uwo3v3.js +4 -0
  114. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +1 -1
  115. package/app/apps/web/.next/server/middleware-build-manifest.js +5 -5
  116. package/app/apps/web/.next/server/pages/500.html +1 -1
  117. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  118. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  119. package/app/apps/web/.next/static/chunks/05b689hq3x49w.js +1 -0
  120. package/app/apps/web/.next/static/chunks/0cxyt4-24..b7.js +14 -0
  121. package/app/apps/web/.next/static/chunks/{0mykrrv810ra-.js → 0kjot8367asxe.js} +1 -1
  122. package/app/apps/web/.next/static/chunks/{turbopack-0_p36yduv.waj.js → turbopack-00w.w1u3c~d-6.js} +1 -1
  123. package/app/apps/web/app/changelog/page.tsx +238 -0
  124. package/app/apps/web/app/layout.tsx +2 -0
  125. package/app/apps/web/components/changelog-icon.tsx +62 -0
  126. package/app/apps/web/components/changelog-mark-read.tsx +12 -0
  127. package/app/apps/web/components/sidebar.tsx +7 -0
  128. package/app/apps/web/lib/calibration-data.ts +4 -64
  129. package/app/apps/web/lib/changelog-data.generated.ts +3 -0
  130. package/app/apps/web/lib/changelog.ts +67 -0
  131. package/app/apps/web/lib/cycle-peaks.test.ts +185 -0
  132. package/app/apps/web/lib/cycle-peaks.ts +104 -0
  133. package/app/apps/web/package.json +1 -1
  134. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  135. package/dist/daemon-worker.js +574 -38
  136. package/dist/index.js +601 -65
  137. package/package.json +1 -1
  138. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0v.6dx0._.js +0 -3
  139. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_usage-data_ts_0xtv99n._.js +0 -3
  140. package/app/apps/web/.next/static/chunks/09gdxttgu~.aj.js +0 -14
  141. /package/app/apps/web/.next/static/{qYW0u_NOmV0v7lf7xZc6x → u6-8f8u1tspYCacGAz53R}/_buildManifest.js +0 -0
  142. /package/app/apps/web/.next/static/{qYW0u_NOmV0v7lf7xZc6x → u6-8f8u1tspYCacGAz53R}/_clientMiddlewareManifest.js +0 -0
  143. /package/app/apps/web/.next/static/{qYW0u_NOmV0v7lf7xZc6x → u6-8f8u1tspYCacGAz53R}/_ssgManifest.js +0 -0
@@ -538,7 +538,7 @@ function getAgentMetadata(kind) {
538
538
  function isAgentKind(s) {
539
539
  return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
540
540
  }
541
- var CLAUDE_CODE_METADATA, CODEX_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
541
+ var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
542
542
  var init_agent_metadata = __esm({
543
543
  "../parser/dist/agent-metadata.js"() {
544
544
  "use strict";
@@ -556,9 +556,17 @@ var init_agent_metadata = __esm({
556
556
  accentColor: "rgb(16, 163, 127)",
557
557
  iconChar: "\u25C6"
558
558
  };
559
+ GEMINI_METADATA = {
560
+ kind: "gemini",
561
+ displayName: "Gemini CLI",
562
+ shortLabel: "Gemini",
563
+ accentColor: "rgb(124, 92, 246)",
564
+ iconChar: "\u273A"
565
+ };
559
566
  agentMetadata = [
560
567
  CLAUDE_CODE_METADATA,
561
- CODEX_METADATA
568
+ CODEX_METADATA,
569
+ GEMINI_METADATA
562
570
  ];
563
571
  KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
564
572
  }
@@ -2342,10 +2350,510 @@ var init_codex = __esm({
2342
2350
  }
2343
2351
  });
2344
2352
 
2353
+ // ../parser/dist/gemini.js
2354
+ import { promises as fs3 } from "node:fs";
2355
+ import os3 from "node:os";
2356
+ import path3 from "node:path";
2357
+ async function safeReaddir2(p) {
2358
+ return fs3.readdir(p).catch(() => []);
2359
+ }
2360
+ async function listSessionFiles(root) {
2361
+ const out = [];
2362
+ const slugs = await safeReaddir2(root);
2363
+ for (const slug of slugs) {
2364
+ const chatsDir = path3.join(root, slug, "chats");
2365
+ const entries = await safeReaddir2(chatsDir);
2366
+ for (const entry of entries) {
2367
+ if (!SESSION_FILE_RE.test(entry))
2368
+ continue;
2369
+ const full = path3.join(chatsDir, entry);
2370
+ const stat = await fs3.stat(full).catch(() => null);
2371
+ if (!stat || !stat.isFile())
2372
+ continue;
2373
+ const filenameId = entry.replace(/\.(jsonl|json)$/, "").split("-").pop() ?? entry;
2374
+ out.push({
2375
+ filePath: full,
2376
+ slug,
2377
+ filenameId,
2378
+ format: entry.endsWith(".jsonl") ? "jsonl" : "legacy-json",
2379
+ mtimeMs: stat.mtimeMs,
2380
+ sizeBytes: stat.size
2381
+ });
2382
+ }
2383
+ }
2384
+ return out;
2385
+ }
2386
+ async function loadSlugToCwd() {
2387
+ const stat = await fs3.stat(GEMINI_PROJECTS_FILE).catch(() => null);
2388
+ if (!stat)
2389
+ return /* @__PURE__ */ new Map();
2390
+ if (projectsCache && projectsCache.mtimeMs === stat.mtimeMs) {
2391
+ return projectsCache.slugToCwd;
2392
+ }
2393
+ const raw = await fs3.readFile(GEMINI_PROJECTS_FILE, "utf8").catch(() => "");
2394
+ let parsed;
2395
+ try {
2396
+ parsed = JSON.parse(raw);
2397
+ } catch {
2398
+ parsed = {};
2399
+ }
2400
+ const slugToCwd = /* @__PURE__ */ new Map();
2401
+ for (const [cwd, slug] of Object.entries(parsed.projects ?? {})) {
2402
+ if (typeof slug === "string")
2403
+ slugToCwd.set(slug, cwd);
2404
+ }
2405
+ projectsCache = { mtimeMs: stat.mtimeMs, slugToCwd };
2406
+ return slugToCwd;
2407
+ }
2408
+ function isRewindMarker(o) {
2409
+ return !!o && typeof o === "object" && "$rewindTo" in o;
2410
+ }
2411
+ function isSetMarker(o) {
2412
+ return !!o && typeof o === "object" && "$set" in o;
2413
+ }
2414
+ function isMessageRecord(o) {
2415
+ return !!o && typeof o === "object" && typeof o.id === "string" && typeof o.type === "string";
2416
+ }
2417
+ async function readAndReplay(file) {
2418
+ const raw = await fs3.readFile(file.filePath, "utf8");
2419
+ if (file.format === "legacy-json") {
2420
+ let blob;
2421
+ try {
2422
+ blob = JSON.parse(raw);
2423
+ } catch {
2424
+ return { meta: {}, messages: [] };
2425
+ }
2426
+ const meta2 = {
2427
+ sessionId: typeof blob.sessionId === "string" ? blob.sessionId : void 0,
2428
+ projectHash: typeof blob.projectHash === "string" ? blob.projectHash : void 0,
2429
+ startTime: typeof blob.startTime === "string" ? blob.startTime : void 0,
2430
+ lastUpdated: typeof blob.lastUpdated === "string" ? blob.lastUpdated : void 0,
2431
+ summary: typeof blob.summary === "string" ? blob.summary : void 0
2432
+ };
2433
+ const msgs = Array.isArray(blob.messages) ? blob.messages : [];
2434
+ const messages2 = msgs.filter(isMessageRecord);
2435
+ return { meta: meta2, messages: messages2 };
2436
+ }
2437
+ const meta = {};
2438
+ const byId = /* @__PURE__ */ new Map();
2439
+ const order = [];
2440
+ for (const line of raw.split("\n")) {
2441
+ const trimmed = line.trim();
2442
+ if (!trimmed)
2443
+ continue;
2444
+ let obj;
2445
+ try {
2446
+ obj = JSON.parse(trimmed);
2447
+ } catch {
2448
+ continue;
2449
+ }
2450
+ if (isRewindMarker(obj)) {
2451
+ const target = obj.$rewindTo;
2452
+ const idx = order.indexOf(target);
2453
+ if (idx >= 0) {
2454
+ for (const id of order.slice(idx))
2455
+ byId.delete(id);
2456
+ order.length = idx;
2457
+ }
2458
+ continue;
2459
+ }
2460
+ if (isSetMarker(obj)) {
2461
+ Object.assign(meta, obj.$set);
2462
+ continue;
2463
+ }
2464
+ if (isMessageRecord(obj)) {
2465
+ if (!byId.has(obj.id))
2466
+ order.push(obj.id);
2467
+ byId.set(obj.id, obj);
2468
+ continue;
2469
+ }
2470
+ if (typeof obj === "object" && obj !== null) {
2471
+ const m = obj;
2472
+ if (typeof m.sessionId === "string" && !meta.sessionId) {
2473
+ meta.sessionId = m.sessionId;
2474
+ if (typeof m.projectHash === "string")
2475
+ meta.projectHash = m.projectHash;
2476
+ if (typeof m.startTime === "string")
2477
+ meta.startTime = m.startTime;
2478
+ if (typeof m.lastUpdated === "string")
2479
+ meta.lastUpdated = m.lastUpdated;
2480
+ if (typeof m.summary === "string")
2481
+ meta.summary = m.summary;
2482
+ }
2483
+ }
2484
+ }
2485
+ const messages = [];
2486
+ for (const id of order) {
2487
+ const m = byId.get(id);
2488
+ if (m)
2489
+ messages.push(m);
2490
+ }
2491
+ return { meta, messages };
2492
+ }
2493
+ function emptyUsage2() {
2494
+ return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
2495
+ }
2496
+ function previewOf2(text) {
2497
+ return text.replace(/\s+/g, " ").trim().slice(0, 200);
2498
+ }
2499
+ function flattenContent(c) {
2500
+ if (!c)
2501
+ return "";
2502
+ if (typeof c === "string")
2503
+ return c;
2504
+ const parts = Array.isArray(c) ? c : [c];
2505
+ const out = [];
2506
+ for (const p of parts) {
2507
+ if (!p || typeof p !== "object")
2508
+ continue;
2509
+ const part = p;
2510
+ if (typeof part.text === "string") {
2511
+ out.push(part.text);
2512
+ continue;
2513
+ }
2514
+ const fr = part.functionResponse;
2515
+ if (fr) {
2516
+ const resp = fr.response;
2517
+ if (typeof resp === "string") {
2518
+ out.push(resp);
2519
+ } else if (resp && typeof resp === "object") {
2520
+ const r = resp;
2521
+ if (typeof r.output === "string")
2522
+ out.push(r.output);
2523
+ else if (typeof r.error === "string")
2524
+ out.push(`error: ${r.error}`);
2525
+ else
2526
+ out.push(JSON.stringify(r));
2527
+ }
2528
+ }
2529
+ }
2530
+ return out.join("\n");
2531
+ }
2532
+ function truncate3(s, n) {
2533
+ return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
2534
+ }
2535
+ async function parseSession(file) {
2536
+ const { meta: metaRec, messages } = await readAndReplay(file);
2537
+ const slugToCwd = await loadSlugToCwd();
2538
+ const cwd = slugToCwd.get(file.slug);
2539
+ const events = [];
2540
+ const totalUsage = emptyUsage2();
2541
+ let firstTimestamp;
2542
+ let lastTimestamp;
2543
+ let model;
2544
+ let toolCallCount = 0;
2545
+ let turnCount = 0;
2546
+ let firstUserPreview;
2547
+ let lastUserPreview;
2548
+ let lastAgentPreview;
2549
+ const tsMs = [];
2550
+ let idx = 0;
2551
+ function pushEvent(e) {
2552
+ events.push(e);
2553
+ if (e.timestamp && e.role !== "meta") {
2554
+ if (!firstTimestamp)
2555
+ firstTimestamp = e.timestamp;
2556
+ lastTimestamp = e.timestamp;
2557
+ const ms = Date.parse(e.timestamp);
2558
+ if (Number.isFinite(ms))
2559
+ tsMs.push(ms);
2560
+ }
2561
+ }
2562
+ for (const msg of messages) {
2563
+ const ts = msg.timestamp;
2564
+ if (msg.type === "user") {
2565
+ const text = flattenContent(msg.displayContent ?? msg.content);
2566
+ const preview = previewOf2(text);
2567
+ if (text) {
2568
+ if (!firstUserPreview)
2569
+ firstUserPreview = preview;
2570
+ lastUserPreview = preview;
2571
+ turnCount += 1;
2572
+ }
2573
+ pushEvent({
2574
+ index: idx++,
2575
+ timestamp: ts,
2576
+ role: "user",
2577
+ rawType: "gemini/user",
2578
+ preview,
2579
+ blocks: text ? [{ type: "text", text }] : [],
2580
+ messageId: msg.id,
2581
+ raw: msg
2582
+ });
2583
+ continue;
2584
+ }
2585
+ if (msg.type === "gemini") {
2586
+ if (typeof msg.model === "string")
2587
+ model = msg.model;
2588
+ const text = flattenContent(msg.content);
2589
+ const preview = previewOf2(text);
2590
+ if (text)
2591
+ lastAgentPreview = preview;
2592
+ let usage;
2593
+ if (msg.tokens) {
2594
+ const t = msg.tokens;
2595
+ const u = {
2596
+ input: t.input ?? 0,
2597
+ output: t.output ?? 0,
2598
+ cacheRead: t.cached ?? 0,
2599
+ cacheWrite: 0
2600
+ };
2601
+ usage = u;
2602
+ totalUsage.input += u.input;
2603
+ totalUsage.output += u.output;
2604
+ totalUsage.cacheRead += u.cacheRead;
2605
+ }
2606
+ for (const th of msg.thoughts ?? []) {
2607
+ const thText = [th.subject, th.description].filter(Boolean).join(": ");
2608
+ if (!thText)
2609
+ continue;
2610
+ pushEvent({
2611
+ index: idx++,
2612
+ timestamp: th.timestamp ?? ts,
2613
+ role: "agent-thinking",
2614
+ rawType: "gemini/thought",
2615
+ preview: previewOf2(thText),
2616
+ blocks: [{ type: "thinking", thinking: thText }],
2617
+ model,
2618
+ raw: th
2619
+ });
2620
+ }
2621
+ if (text) {
2622
+ pushEvent({
2623
+ index: idx++,
2624
+ timestamp: ts,
2625
+ role: "agent",
2626
+ rawType: "gemini/agent",
2627
+ preview,
2628
+ blocks: [{ type: "text", text }],
2629
+ messageId: msg.id,
2630
+ model,
2631
+ usage,
2632
+ raw: msg
2633
+ });
2634
+ } else if (usage) {
2635
+ pushEvent({
2636
+ index: idx++,
2637
+ timestamp: ts,
2638
+ role: "agent",
2639
+ rawType: "gemini/agent",
2640
+ preview: "",
2641
+ blocks: [],
2642
+ messageId: msg.id,
2643
+ model,
2644
+ usage,
2645
+ raw: msg
2646
+ });
2647
+ }
2648
+ for (const tc of msg.toolCalls ?? []) {
2649
+ toolCallCount += 1;
2650
+ const argsStr = tc.args ? JSON.stringify(tc.args) : "";
2651
+ pushEvent({
2652
+ index: idx++,
2653
+ timestamp: tc.timestamp ?? ts,
2654
+ role: "tool-call",
2655
+ rawType: "gemini/tool_call",
2656
+ preview: `${tc.name}(${truncate3(argsStr, 80)})`,
2657
+ blocks: [{ type: "tool_use", id: tc.id, name: tc.name, input: tc.args ?? {} }],
2658
+ toolName: tc.name,
2659
+ toolUseId: tc.id,
2660
+ model,
2661
+ raw: tc
2662
+ });
2663
+ const status = (tc.status ?? "").toLowerCase();
2664
+ const isTerminal = status === "success" || status === "error" || status === "cancelled";
2665
+ if (isTerminal) {
2666
+ const resultText = flattenContent(tc.result);
2667
+ pushEvent({
2668
+ index: idx++,
2669
+ timestamp: tc.timestamp ?? ts,
2670
+ role: "tool-result",
2671
+ rawType: "gemini/tool_result",
2672
+ preview: previewOf2(resultText),
2673
+ blocks: [
2674
+ {
2675
+ type: "tool_result",
2676
+ tool_use_id: tc.id,
2677
+ content: resultText,
2678
+ is_error: status === "error" || status === "cancelled"
2679
+ }
2680
+ ],
2681
+ toolUseId: tc.id,
2682
+ toolResult: resultText,
2683
+ raw: tc
2684
+ });
2685
+ }
2686
+ }
2687
+ continue;
2688
+ }
2689
+ if (msg.type === "info" || msg.type === "warning" || msg.type === "error") {
2690
+ const text = flattenContent(msg.content);
2691
+ pushEvent({
2692
+ index: idx++,
2693
+ timestamp: ts,
2694
+ role: "meta",
2695
+ rawType: `gemini/${msg.type}`,
2696
+ preview: previewOf2(text),
2697
+ blocks: text ? [{ type: "text", text }] : [],
2698
+ raw: msg
2699
+ });
2700
+ continue;
2701
+ }
2702
+ }
2703
+ const startMs = firstTimestamp ? Date.parse(firstTimestamp) : void 0;
2704
+ if (startMs !== void 0 && Number.isFinite(startMs)) {
2705
+ let prevMs;
2706
+ for (const ev of events) {
2707
+ if (!ev.timestamp)
2708
+ continue;
2709
+ const ms = Date.parse(ev.timestamp);
2710
+ if (!Number.isFinite(ms))
2711
+ continue;
2712
+ ev.tOffsetMs = Math.max(0, ms - startMs);
2713
+ if (prevMs !== void 0)
2714
+ ev.gapMs = Math.max(0, ms - prevMs);
2715
+ prevMs = ms;
2716
+ }
2717
+ }
2718
+ const activeSegments = computeActiveSegments3(tsMs);
2719
+ const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
2720
+ const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
2721
+ const sessionId = metaRec.sessionId ?? file.filenameId;
2722
+ const projectName = cwd ? canonicalProjectName(cwd) : file.slug;
2723
+ const projectDir = cwd ? cwd.replace(/^\//, "-").replace(/\//g, "-") : file.slug;
2724
+ const meta = {
2725
+ agent: "gemini",
2726
+ id: sessionId,
2727
+ filePath: file.filePath,
2728
+ projectName,
2729
+ projectDir,
2730
+ sessionId,
2731
+ firstTimestamp,
2732
+ lastTimestamp,
2733
+ durationMs: durationMs && Number.isFinite(durationMs) ? durationMs : void 0,
2734
+ eventCount: events.length,
2735
+ model,
2736
+ cwd,
2737
+ totalUsage,
2738
+ status: "idle",
2739
+ firstUserPreview,
2740
+ lastUserPreview,
2741
+ lastAgentPreview,
2742
+ toolCallCount,
2743
+ turnCount,
2744
+ airTimeMs,
2745
+ activeSegments
2746
+ };
2747
+ return { meta, events };
2748
+ }
2749
+ function computeActiveSegments3(tsMs) {
2750
+ if (tsMs.length === 0)
2751
+ return [];
2752
+ const sorted = [...tsMs].sort((a, b) => a - b);
2753
+ const out = [];
2754
+ let segStart = sorted[0];
2755
+ let segEnd = sorted[0];
2756
+ for (let i = 1; i < sorted.length; i++) {
2757
+ if (sorted[i] - segEnd > IDLE_GAP_MS2) {
2758
+ out.push({ startMs: segStart, endMs: segEnd });
2759
+ segStart = sorted[i];
2760
+ }
2761
+ segEnd = sorted[i];
2762
+ }
2763
+ out.push({ startMs: segStart, endMs: segEnd });
2764
+ return out;
2765
+ }
2766
+ function clearGeminiCaches() {
2767
+ metaCache3.clear();
2768
+ detailCache3.clear();
2769
+ projectsCache = null;
2770
+ }
2771
+ async function listGeminiSessions(opts = {}) {
2772
+ const root = opts.root ?? DEFAULT_GEMINI_ROOT;
2773
+ const files = await listSessionFiles(root);
2774
+ const out = [];
2775
+ for (const file of files) {
2776
+ const cached = metaCache3.get(file.filePath);
2777
+ if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
2778
+ out.push(cached.meta);
2779
+ continue;
2780
+ }
2781
+ try {
2782
+ const { meta } = await parseSession(file);
2783
+ metaCache3.set(file.filePath, {
2784
+ meta,
2785
+ mtimeMs: file.mtimeMs,
2786
+ sizeBytes: file.sizeBytes
2787
+ });
2788
+ out.push(meta);
2789
+ } catch {
2790
+ }
2791
+ }
2792
+ out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
2793
+ if (opts.limit !== void 0)
2794
+ return out.slice(0, opts.limit);
2795
+ return out;
2796
+ }
2797
+ async function getGeminiSession(id, opts = {}) {
2798
+ const root = opts.root ?? DEFAULT_GEMINI_ROOT;
2799
+ const files = await listSessionFiles(root);
2800
+ let chosen;
2801
+ for (const file of files) {
2802
+ if (file.filenameId === id || id.startsWith(file.filenameId)) {
2803
+ chosen = file;
2804
+ break;
2805
+ }
2806
+ }
2807
+ if (!chosen) {
2808
+ for (const file of files) {
2809
+ const { meta: meta2 } = await parseSession(file).catch(() => ({ meta: { id: "" } }));
2810
+ if (meta2.id === id) {
2811
+ chosen = file;
2812
+ break;
2813
+ }
2814
+ }
2815
+ }
2816
+ if (!chosen)
2817
+ return null;
2818
+ const cached = detailCache3.get(chosen.filePath);
2819
+ if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
2820
+ return cached.detail;
2821
+ }
2822
+ const { meta, events } = await parseSession(chosen);
2823
+ const detail = { ...meta, events };
2824
+ detailCache3.set(chosen.filePath, {
2825
+ detail,
2826
+ mtimeMs: chosen.mtimeMs,
2827
+ sizeBytes: chosen.sizeBytes
2828
+ });
2829
+ return detail;
2830
+ }
2831
+ function geminiSessionLocalDay(meta) {
2832
+ if (!meta.firstTimestamp)
2833
+ return void 0;
2834
+ const ms = Date.parse(meta.firstTimestamp);
2835
+ return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
2836
+ }
2837
+ var DEFAULT_GEMINI_ROOT, GEMINI_PROJECTS_FILE, SESSION_FILE_RE, IDLE_GAP_MS2, projectsCache, metaCache3, detailCache3;
2838
+ var init_gemini = __esm({
2839
+ "../parser/dist/gemini.js"() {
2840
+ "use strict";
2841
+ init_analytics();
2842
+ DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
2843
+ GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
2844
+ SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
2845
+ IDLE_GAP_MS2 = 3 * 60 * 1e3;
2846
+ projectsCache = null;
2847
+ metaCache3 = /* @__PURE__ */ new Map();
2848
+ detailCache3 = /* @__PURE__ */ new Map();
2849
+ }
2850
+ });
2851
+
2345
2852
  // ../parser/dist/fs.js
2346
2853
  var fs_exports = {};
2347
2854
  __export(fs_exports, {
2348
2855
  DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
2856
+ DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
2349
2857
  DEFAULT_ROOT: () => DEFAULT_ROOT,
2350
2858
  agentSources: () => agentSources,
2351
2859
  buildCalibrationCurve: () => buildCalibrationCurve,
@@ -2354,14 +2862,17 @@ __export(fs_exports, {
2354
2862
  codexSessionLocalDay: () => codexSessionLocalDay,
2355
2863
  decodeProjectName: () => decodeProjectName,
2356
2864
  findTeamLead: () => findTeamLead,
2865
+ geminiSessionLocalDay: () => geminiSessionLocalDay,
2357
2866
  getAgentSource: () => getAgentSource,
2358
2867
  getAnySession: () => getAnySession,
2359
2868
  getCodexSession: () => getCodexSession,
2869
+ getGeminiSession: () => getGeminiSession,
2360
2870
  getLatestCodexUsage: () => getLatestCodexUsage,
2361
2871
  getSession: () => getSession,
2362
2872
  invalidateFile: () => invalidateFile,
2363
2873
  listAllSessions: () => listAllSessions,
2364
2874
  listCodexSessions: () => listCodexSessions,
2875
+ listGeminiSessions: () => listGeminiSessions,
2365
2876
  listProjects: () => listProjects,
2366
2877
  listSessions: () => listSessions,
2367
2878
  loadCalibrationCurve: () => loadCalibrationCurve,
@@ -2373,15 +2884,16 @@ __export(fs_exports, {
2373
2884
  sessionIdFromFileName: () => sessionIdFromFileName,
2374
2885
  walkJsonlFiles: () => walkJsonlFiles
2375
2886
  });
2376
- import { promises as fs3 } from "node:fs";
2377
- import os3 from "node:os";
2378
- import path3 from "node:path";
2887
+ import { promises as fs4 } from "node:fs";
2888
+ import os4 from "node:os";
2889
+ import path4 from "node:path";
2379
2890
  function cacheStats() {
2380
2891
  return claudeCodeCacheStats();
2381
2892
  }
2382
2893
  function clearCaches() {
2383
2894
  clearClaudeCodeCaches();
2384
2895
  clearCodexCaches();
2896
+ clearGeminiCaches();
2385
2897
  }
2386
2898
  function invalidateFile(fullPath) {
2387
2899
  invalidateClaudeCodeFile(fullPath);
@@ -2410,7 +2922,7 @@ async function getAnySession(id) {
2410
2922
  async function loadUsageByDay(start, end) {
2411
2923
  let raw;
2412
2924
  try {
2413
- raw = await fs3.readFile(USAGE_LOG, "utf8");
2925
+ raw = await fs4.readFile(USAGE_LOG, "utf8");
2414
2926
  } catch {
2415
2927
  return { by_day: [] };
2416
2928
  }
@@ -2455,7 +2967,7 @@ async function loadUsageByDay(start, end) {
2455
2967
  async function loadCalibrationSnapshots() {
2456
2968
  let raw;
2457
2969
  try {
2458
- raw = await fs3.readFile(USAGE_LOG, "utf8");
2970
+ raw = await fs4.readFile(USAGE_LOG, "utf8");
2459
2971
  } catch {
2460
2972
  return [];
2461
2973
  }
@@ -2613,7 +3125,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
2613
3125
  ]);
2614
3126
  return buildCalibrationCurve(events, snapshots, tier, granularityMin);
2615
3127
  }
2616
- var codexSource, agentSources, USAGE_LOG;
3128
+ var codexSource, geminiSource, agentSources, USAGE_LOG;
2617
3129
  var init_fs = __esm({
2618
3130
  "../parser/dist/fs.js"() {
2619
3131
  "use strict";
@@ -2622,8 +3134,10 @@ var init_fs = __esm({
2622
3134
  init_calibration();
2623
3135
  init_claude_code();
2624
3136
  init_codex();
3137
+ init_gemini();
2625
3138
  init_claude_code();
2626
3139
  init_codex();
3140
+ init_gemini();
2627
3141
  codexSource = {
2628
3142
  ...CODEX_METADATA,
2629
3143
  defaultRoot: DEFAULT_CODEX_ROOT,
@@ -2645,8 +3159,18 @@ var init_fs = __esm({
2645
3159
  };
2646
3160
  }
2647
3161
  };
2648
- agentSources = [claudeCodeSource, codexSource];
2649
- USAGE_LOG = path3.join(os3.homedir(), ".cclens", "usage.jsonl");
3162
+ geminiSource = {
3163
+ ...GEMINI_METADATA,
3164
+ defaultRoot: DEFAULT_GEMINI_ROOT,
3165
+ async listSessions(opts) {
3166
+ return listGeminiSessions(opts);
3167
+ },
3168
+ async getSession(id) {
3169
+ return getGeminiSession(id);
3170
+ }
3171
+ };
3172
+ agentSources = [claudeCodeSource, codexSource, geminiSource];
3173
+ USAGE_LOG = path4.join(os4.homedir(), ".cclens", "usage.jsonl");
2650
3174
  }
2651
3175
  });
2652
3176
 
@@ -3051,6 +3575,7 @@ var dist_exports = {};
3051
3575
  __export(dist_exports, {
3052
3576
  CLAUDE_CODE_METADATA: () => CLAUDE_CODE_METADATA,
3053
3577
  CODEX_METADATA: () => CODEX_METADATA,
3578
+ GEMINI_METADATA: () => GEMINI_METADATA,
3054
3579
  PRICES: () => PRICES,
3055
3580
  RATE_PER_PCT: () => RATE_PER_PCT,
3056
3581
  RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
@@ -3144,9 +3669,9 @@ function readFromCredentialsFile() {
3144
3669
  join(homedir(), ".claude", ".credentials.json"),
3145
3670
  join(homedir(), ".config", "claude", "credentials.json")
3146
3671
  ];
3147
- for (const path4 of candidates) {
3672
+ for (const path5 of candidates) {
3148
3673
  try {
3149
- const blob = readFileSync(path4, "utf8");
3674
+ const blob = readFileSync(path5, "utf8");
3150
3675
  const creds = extractCredentials(blob);
3151
3676
  if (creds) return creds;
3152
3677
  } catch {
@@ -3610,6 +4135,7 @@ async function buildCyclePeaksForPush(planTier, loadCurve) {
3610
4135
  const HOUR = 36e5;
3611
4136
  const nowMs = Date.now();
3612
4137
  const peaksFor = (cycleKey, realKey, predKey, maxCycles) => {
4138
+ const TOLERANCE_MS = cycleKey === "cycle_end_7d" ? 12 * HOUR : 0;
3613
4139
  const byCycle = /* @__PURE__ */ new Map();
3614
4140
  for (const p of dump.curve) {
3615
4141
  const k = p[cycleKey];
@@ -3621,8 +4147,18 @@ async function buildCyclePeaksForPush(planTier, loadCurve) {
3621
4147
  arr.push(p);
3622
4148
  byCycle.set(bucket, arr);
3623
4149
  }
3624
- const out = [];
4150
+ const merged = [];
3625
4151
  for (const [endMs, points] of Array.from(byCycle.entries()).sort((a, b) => a[0] - b[0])) {
4152
+ const last = merged[merged.length - 1];
4153
+ if (last && endMs - last.endMs <= TOLERANCE_MS) {
4154
+ last.endMs = endMs;
4155
+ last.points.push(...points);
4156
+ } else {
4157
+ merged.push({ endMs, points: [...points] });
4158
+ }
4159
+ }
4160
+ const out = [];
4161
+ for (const { endMs, points } of merged) {
3626
4162
  let peak = 0;
3627
4163
  let source = "predicted";
3628
4164
  for (const p of points) {
@@ -3953,7 +4489,7 @@ function viewEvent(ev) {
3953
4489
  cwd: rawCwd
3954
4490
  };
3955
4491
  }
3956
- var IDLE_GAP_MS2 = 3 * 60 * 1e3;
4492
+ var IDLE_GAP_MS3 = 3 * 60 * 1e3;
3957
4493
  var INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
3958
4494
  var PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
3959
4495
  var BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
@@ -4065,7 +4601,7 @@ function closeTurn(t, closed, cwd) {
4065
4601
  let active = 0;
4066
4602
  for (let i = 1; i < ts.length; i++) {
4067
4603
  const dt = ts[i] - ts[i - 1];
4068
- if (dt < IDLE_GAP_MS2)
4604
+ if (dt < IDLE_GAP_MS3)
4069
4605
  active += dt;
4070
4606
  }
4071
4607
  closed.push({
@@ -4241,7 +4777,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
4241
4777
  let activeMs2 = 0;
4242
4778
  for (let i = 1; i < tsSorted.length; i++) {
4243
4779
  const dt = tsSorted[i] - tsSorted[i - 1];
4244
- if (dt < IDLE_GAP_MS2)
4780
+ if (dt < IDLE_GAP_MS3)
4245
4781
  activeMs2 += dt;
4246
4782
  }
4247
4783
  const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
@@ -5256,8 +5792,8 @@ function getErrorMap() {
5256
5792
 
5257
5793
  // ../../node_modules/zod/v3/helpers/parseUtil.js
5258
5794
  var makeIssue = (params) => {
5259
- const { data, path: path4, errorMaps, issueData } = params;
5260
- const fullPath = [...path4, ...issueData.path || []];
5795
+ const { data, path: path5, errorMaps, issueData } = params;
5796
+ const fullPath = [...path5, ...issueData.path || []];
5261
5797
  const fullIssue = {
5262
5798
  ...issueData,
5263
5799
  path: fullPath
@@ -5373,11 +5909,11 @@ var errorUtil;
5373
5909
 
5374
5910
  // ../../node_modules/zod/v3/types.js
5375
5911
  var ParseInputLazyPath = class {
5376
- constructor(parent, value, path4, key) {
5912
+ constructor(parent, value, path5, key) {
5377
5913
  this._cachedPath = [];
5378
5914
  this.parent = parent;
5379
5915
  this.data = value;
5380
- this._path = path4;
5916
+ this._path = path5;
5381
5917
  this._key = key;
5382
5918
  }
5383
5919
  get path() {
@@ -8947,15 +9483,15 @@ function newRunId(kind) {
8947
9483
  function tracePath(runId) {
8948
9484
  return join9(RUNS_DIR, `${runId}.jsonl`);
8949
9485
  }
8950
- function safeAppend(path4, line) {
9486
+ function safeAppend(path5, line) {
8951
9487
  try {
8952
- appendFileSync3(path4, line);
9488
+ appendFileSync3(path5, line);
8953
9489
  } catch {
8954
9490
  }
8955
9491
  }
8956
- function safeWrite(path4, line) {
9492
+ function safeWrite(path5, line) {
8957
9493
  try {
8958
- writeFileSync7(path4, line);
9494
+ writeFileSync7(path5, line);
8959
9495
  } catch {
8960
9496
  }
8961
9497
  }
@@ -9591,7 +10127,7 @@ function rollupOutcomeDay(entries) {
9591
10127
  return "exploratory";
9592
10128
  return "trivial";
9593
10129
  }
9594
- function truncate3(s, max) {
10130
+ function truncate4(s, max) {
9595
10131
  if (s.length <= max)
9596
10132
  return s;
9597
10133
  return s.slice(0, max - 1).trimEnd() + "\u2026";
@@ -9647,7 +10183,7 @@ function computeDaySignals(entries) {
9647
10183
  type,
9648
10184
  count: v.count,
9649
10185
  sample_description: v.sample_description,
9650
- sample_prompt_preview: truncate3(v.sample_prompt_preview, 200)
10186
+ sample_prompt_preview: truncate4(v.sample_prompt_preview, 200)
9651
10187
  }));
9652
10188
  const frameCounts = /* @__PURE__ */ new Map();
9653
10189
  for (const s of signalsList) {
@@ -9666,7 +10202,7 @@ function computeDaySignals(entries) {
9666
10202
  if ((e.first_user ?? "").length > 0)
9667
10203
  verbosity_distribution[s.verbosity] += 1;
9668
10204
  for (const ref of s.external_refs) {
9669
- external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate3(ref.preview, 200) });
10205
+ external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate4(ref.preview, 200) });
9670
10206
  }
9671
10207
  const ints = e.numbers.interrupts ?? 0;
9672
10208
  interrupts += ints;
@@ -10509,7 +11045,7 @@ function computeInteractionModes(entries) {
10509
11045
  date: entry.local_day,
10510
11046
  project_display: prettyProject3(entry.project),
10511
11047
  type: sa.type,
10512
- prompt_preview: truncate4(sa.prompt_preview, 200)
11048
+ prompt_preview: truncate5(sa.prompt_preview, 200)
10513
11049
  });
10514
11050
  }
10515
11051
  const skillExamples = [];
@@ -10526,7 +11062,7 @@ function computeInteractionModes(entries) {
10526
11062
  skillExamples.push({
10527
11063
  date: e.local_day,
10528
11064
  skill,
10529
- first_user_preview: truncate4(e.first_user, 200)
11065
+ first_user_preview: truncate5(e.first_user, 200)
10530
11066
  });
10531
11067
  }
10532
11068
  }
@@ -10543,7 +11079,7 @@ function computeInteractionModes(entries) {
10543
11079
  project_display: prettyProject3(longestTurnEntry.project),
10544
11080
  active_min: longestTurnEntry.numbers.active_min,
10545
11081
  top_tools: longestTurnEntry.top_tools.slice(0, 5),
10546
- first_user_preview: truncate4(longestTurnEntry.first_user, 200)
11082
+ first_user_preview: truncate5(longestTurnEntry.first_user, 200)
10547
11083
  } : null;
10548
11084
  const tools_per_turn = turn_count > 0 ? tools_total / turn_count : 0;
10549
11085
  const label = tools_per_turn < 5 ? "rapid" : tools_per_turn < 15 ? "mixed" : "batch";
@@ -10574,7 +11110,7 @@ function computeInteractionModes(entries) {
10574
11110
  }
10575
11111
  };
10576
11112
  }
10577
- function truncate4(s, max) {
11113
+ function truncate5(s, max) {
10578
11114
  if (s.length <= max)
10579
11115
  return s;
10580
11116
  return s.slice(0, max - 1).trimEnd() + "\u2026";
@@ -10631,7 +11167,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
10631
11167
  evidence_subagent = {
10632
11168
  type: sa.type,
10633
11169
  description: sa.description,
10634
- prompt_preview: truncate4(sa.prompt_preview, 200)
11170
+ prompt_preview: truncate5(sa.prompt_preview, 200)
10635
11171
  };
10636
11172
  }
10637
11173
  const project_display = repEntry ? prettyProject3(repEntry.project) : dd.projects[0]?.display_name ?? "";
@@ -10642,7 +11178,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
10642
11178
  outcome: dayOutcome.get(dd.key) ?? null,
10643
11179
  helpfulness: dayHelp.get(dd.key) ?? null,
10644
11180
  evidence_subagent,
10645
- evidence_first_user: repEntry?.first_user ? truncate4(repEntry.first_user, 200) : null,
11181
+ evidence_first_user: repEntry?.first_user ? truncate5(repEntry.first_user, 200) : null,
10646
11182
  day_signature: dd.day_signature ?? null
10647
11183
  };
10648
11184
  });
@@ -10717,7 +11253,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
10717
11253
  date: day,
10718
11254
  session_id: ref.session_id,
10719
11255
  ref_kind: ref.kind,
10720
- preview: truncate4(ref.preview, 200)
11256
+ preview: truncate5(ref.preview, 200)
10721
11257
  });
10722
11258
  }
10723
11259
  total_interrupts += signals.comm_style.steering.interrupts;
@@ -10789,7 +11325,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
10789
11325
  count: v.count,
10790
11326
  days: [...v.days].sort(),
10791
11327
  sample_description: v.sample_description,
10792
- sample_prompt_preview: truncate4(v.sample_prompt_preview, 200)
11328
+ sample_prompt_preview: truncate5(v.sample_prompt_preview, 200)
10793
11329
  })),
10794
11330
  threads,
10795
11331
  communication_style: {
@@ -11089,7 +11625,7 @@ var MonthDigestResponseSchema = external_exports.object({
11089
11625
  }).passthrough();
11090
11626
 
11091
11627
  // ../entries/dist/top-sessions.js
11092
- var IDLE_GAP_MS3 = 3 * 60 * 1e3;
11628
+ var IDLE_GAP_MS4 = 3 * 60 * 1e3;
11093
11629
  var LONG_AUTONOMOUS_MIN = 20;
11094
11630
  var N_USER = 150;
11095
11631
  var N_FIRST_AGENT = 150;
@@ -11120,7 +11656,7 @@ function activeMs(timestamps) {
11120
11656
  let active = 0;
11121
11657
  for (let i = 1; i < ts.length; i++) {
11122
11658
  const dt = ts[i] - ts[i - 1];
11123
- if (dt < IDLE_GAP_MS3)
11659
+ if (dt < IDLE_GAP_MS4)
11124
11660
  active += dt;
11125
11661
  }
11126
11662
  return active;
@@ -11294,7 +11830,7 @@ function buildSessionSlice(entry, events, daySignature) {
11294
11830
  let intEnd = sortedTs[0];
11295
11831
  for (let i = 1; i < sortedTs.length; i++) {
11296
11832
  const dt = sortedTs[i] - intEnd;
11297
- if (dt >= IDLE_GAP_MS3) {
11833
+ if (dt >= IDLE_GAP_MS4) {
11298
11834
  intervals.push({
11299
11835
  start_min: fmtMin(intStart - sliceStartMs),
11300
11836
  end_min: fmtMin(intEnd - sliceStartMs)