fleetlens 0.16.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) 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]/events/route.js.nft.json +1 -1
  16. package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/api/agent/chats/[id]/route.js.nft.json +1 -1
  18. package/app/apps/web/.next/server/app/api/agent/chats/[id]/stop/route.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/api/agent/chats/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +1 -1
  23. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  25. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  27. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  29. package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
  31. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
  33. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  34. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  35. package/app/apps/web/.next/server/app/api/runs/route.js.nft.json +1 -1
  36. package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -1
  37. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  38. package/app/apps/web/.next/server/app/api/team/autostart/route.js.nft.json +1 -1
  39. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js.nft.json +1 -1
  40. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js.nft.json +1 -1
  41. package/app/apps/web/.next/server/app/api/workflow-agent/route.js.nft.json +1 -1
  42. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  44. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  45. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  46. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  47. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.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.js.nft.json +1 -1
  51. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  52. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  53. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  54. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  55. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  56. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  58. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  59. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  60. package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
  61. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  62. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  63. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  64. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  65. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  66. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  67. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  68. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  69. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  70. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  71. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  72. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  73. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  74. package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
  75. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  76. package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
  77. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  78. package/app/apps/web/.next/server/app/usage/page.js +2 -1
  79. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  80. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  81. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
  82. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  83. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  84. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0f3q8gt._.js +3 -0
  85. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__11xp-1u._.js +3 -0
  86. package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
  87. package/app/apps/web/.next/server/chunks/ssr/apps_web_0epqfet._.js +3 -0
  88. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0x014hn._.js +1 -1
  89. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
  90. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  91. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  92. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
  93. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  94. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  95. package/app/apps/web/.next/server/pages/500.html +1 -1
  96. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  97. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  98. package/app/apps/web/.next/static/chunks/0at6brbse8wn2.js +14 -0
  99. package/app/apps/web/.next/static/chunks/{0_0~~ipv90vm3.js → 0rrcj195v1nd..js} +1 -1
  100. package/app/apps/web/app/usage/page.tsx +166 -2
  101. package/app/apps/web/components/agent-badge.tsx +3 -0
  102. package/app/apps/web/components/agent-icon.tsx +42 -4
  103. package/app/apps/web/components/menubar-install-banner.tsx +2 -1
  104. package/app/apps/web/components/usage-charts-dashboard.tsx +9 -1
  105. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  106. package/app/apps/web/package.json +1 -1
  107. package/app/apps/web/public/agent-icons/grok.svg +8 -0
  108. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  109. package/dist/daemon-worker.js +1037 -110
  110. package/dist/index.js +1094 -154
  111. package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
  112. package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
  113. package/menubar/FleetlensMenubar.app/Contents/Resources/grok.svg +8 -0
  114. package/menubar/FleetlensMenubar.app/Contents/_CodeSignature/CodeResources +11 -0
  115. package/package.json +1 -1
  116. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ns6ydi._.js +0 -3
  117. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +0 -3
  118. package/app/apps/web/.next/static/chunks/0mry~475v0fa3.js +0 -14
  119. /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → d1mwRtSMG-R7wb8o9KxM3}/_buildManifest.js +0 -0
  120. /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → d1mwRtSMG-R7wb8o9KxM3}/_clientMiddlewareManifest.js +0 -0
  121. /package/app/apps/web/.next/static/{bTww6lPxII4wde65VQDrF → d1mwRtSMG-R7wb8o9KxM3}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -675,7 +675,7 @@ function getAgentMetadata(kind) {
675
675
  function isAgentKind(s) {
676
676
  return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
677
677
  }
678
- var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
678
+ var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, GROK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
679
679
  var init_agent_metadata = __esm({
680
680
  "../parser/dist/agent-metadata.js"() {
681
681
  "use strict";
@@ -721,13 +721,22 @@ var init_agent_metadata = __esm({
721
721
  accentColor: "rgb(59, 130, 246)",
722
722
  iconChar: "Z"
723
723
  };
724
+ GROK_METADATA = {
725
+ kind: "grok",
726
+ displayName: "Grok Build",
727
+ shortLabel: "Grok",
728
+ // Slate-400 — visible on dark Fleetlens chrome and still fine on light.
729
+ accentColor: "rgb(100, 116, 139)",
730
+ iconChar: "\u25C8"
731
+ };
724
732
  agentMetadata = [
725
733
  CLAUDE_CODE_METADATA,
726
734
  CODEX_METADATA,
727
735
  GEMINI_METADATA,
728
736
  ANTIGRAVITY_METADATA,
729
737
  COWORK_METADATA,
730
- ZAI_METADATA
738
+ ZAI_METADATA,
739
+ GROK_METADATA
731
740
  ];
732
741
  KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
733
742
  }
@@ -1584,11 +1593,11 @@ function defaultBranch(commonDir) {
1584
1593
  }
1585
1594
  return void 0;
1586
1595
  }
1587
- function readGitFolder(path7) {
1588
- if (!existsSync(path7))
1596
+ function readGitFolder(path9) {
1597
+ if (!existsSync(path9))
1589
1598
  return { exists: false, isWorktree: false };
1590
1599
  try {
1591
- const git = nearestDotGit(realpathOrSelf(path7));
1600
+ const git = nearestDotGit(realpathOrSelf(path9));
1592
1601
  if (!git)
1593
1602
  return { exists: true, isWorktree: false };
1594
1603
  const projectRoot = projectRootFromCommonDir(git.commonDir);
@@ -4469,6 +4478,672 @@ var init_cowork = __esm({
4469
4478
  }
4470
4479
  });
4471
4480
 
4481
+ // ../parser/dist/grok.js
4482
+ import { promises as fs6 } from "node:fs";
4483
+ import os6 from "node:os";
4484
+ import path6 from "node:path";
4485
+ function resolveDefaultGrokRoot() {
4486
+ const home = process.env.GROK_HOME || path6.join(os6.homedir(), ".grok");
4487
+ return path6.join(home, "sessions");
4488
+ }
4489
+ async function safeReaddir5(p) {
4490
+ return fs6.readdir(p).catch(() => []);
4491
+ }
4492
+ async function safeReadJson(p) {
4493
+ const raw = await fs6.readFile(p, "utf8").catch(() => null);
4494
+ if (raw == null)
4495
+ return null;
4496
+ try {
4497
+ return JSON.parse(raw);
4498
+ } catch {
4499
+ return null;
4500
+ }
4501
+ }
4502
+ async function resolveEncodedCwd(groupDir, encoded) {
4503
+ const cwdFile = path6.join(groupDir, ".cwd");
4504
+ const fromFile = await fs6.readFile(cwdFile, "utf8").catch(() => null);
4505
+ if (fromFile && fromFile.trim())
4506
+ return fromFile.trim();
4507
+ try {
4508
+ return decodeURIComponent(encoded);
4509
+ } catch {
4510
+ return encoded;
4511
+ }
4512
+ }
4513
+ async function listSessionDirs(root) {
4514
+ const out = [];
4515
+ const groups = await safeReaddir5(root);
4516
+ for (const group of groups) {
4517
+ if (group === "session_search.sqlite" || group.startsWith("."))
4518
+ continue;
4519
+ const groupDir = path6.join(root, group);
4520
+ const groupStat = await fs6.stat(groupDir).catch(() => null);
4521
+ if (!groupStat?.isDirectory())
4522
+ continue;
4523
+ const decodedCwd = await resolveEncodedCwd(groupDir, group);
4524
+ const entries2 = await safeReaddir5(groupDir);
4525
+ for (const entry of entries2) {
4526
+ if (entry === "prompt_history.jsonl" || entry.startsWith("."))
4527
+ continue;
4528
+ const dirPath = path6.join(groupDir, entry);
4529
+ const summaryPath = path6.join(dirPath, "summary.json");
4530
+ const updatesPath = path6.join(dirPath, "updates.jsonl");
4531
+ const signalsCandidate = path6.join(dirPath, "signals.json");
4532
+ const [summaryStat, updatesStat, signalsStat] = await Promise.all([
4533
+ fs6.stat(summaryPath).catch(() => null),
4534
+ fs6.stat(updatesPath).catch(() => null),
4535
+ fs6.stat(signalsCandidate).catch(() => null)
4536
+ ]);
4537
+ if (!summaryStat?.isFile())
4538
+ continue;
4539
+ const mtimeMs = Math.max(summaryStat.mtimeMs, updatesStat?.mtimeMs ?? 0);
4540
+ const sizeBytes = (updatesStat?.size ?? 0) + summaryStat.size;
4541
+ out.push({
4542
+ dirPath,
4543
+ updatesPath,
4544
+ summaryPath,
4545
+ signalsPath: signalsStat?.isFile() ? signalsCandidate : null,
4546
+ sessionId: entry,
4547
+ groupName: group,
4548
+ decodedCwd,
4549
+ mtimeMs,
4550
+ sizeBytes
4551
+ });
4552
+ }
4553
+ }
4554
+ return out;
4555
+ }
4556
+ function emptyUsage4() {
4557
+ return { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
4558
+ }
4559
+ function previewOf4(text) {
4560
+ return text.replace(/\s+/g, " ").trim().slice(0, 200);
4561
+ }
4562
+ function truncate5(s, n) {
4563
+ return s.length <= n ? s : s.slice(0, n - 1) + "\u2026";
4564
+ }
4565
+ function textFromContent2(content) {
4566
+ if (!content)
4567
+ return "";
4568
+ if (typeof content === "string")
4569
+ return content;
4570
+ if (typeof content.text === "string")
4571
+ return content.text;
4572
+ return "";
4573
+ }
4574
+ function toolResultText(update2) {
4575
+ const items = update2.content;
4576
+ if (Array.isArray(items)) {
4577
+ const parts = [];
4578
+ for (const item of items) {
4579
+ if (!item || typeof item !== "object")
4580
+ continue;
4581
+ if (typeof item.text === "string" && item.text) {
4582
+ parts.push(item.text);
4583
+ continue;
4584
+ }
4585
+ const inner = item.content;
4586
+ if (typeof inner === "string" && inner)
4587
+ parts.push(inner);
4588
+ else if (inner && typeof inner === "object" && typeof inner.text === "string") {
4589
+ parts.push(inner.text);
4590
+ }
4591
+ }
4592
+ if (parts.length)
4593
+ return parts.join("\n");
4594
+ }
4595
+ const raw = update2.rawOutput;
4596
+ if (raw == null)
4597
+ return "";
4598
+ if (typeof raw === "string")
4599
+ return raw;
4600
+ if (typeof raw === "object") {
4601
+ const r = raw;
4602
+ if (typeof r.output_for_prompt === "string")
4603
+ return r.output_for_prompt;
4604
+ if (typeof r.summary_for_prompt === "string")
4605
+ return r.summary_for_prompt;
4606
+ if (r.Content && typeof r.Content === "object") {
4607
+ const c = r.Content;
4608
+ if (typeof c.content === "string")
4609
+ return c.content;
4610
+ }
4611
+ if (r.TodosUpdated && typeof r.TodosUpdated === "object") {
4612
+ const t = r.TodosUpdated;
4613
+ if (typeof t.summary_for_prompt === "string")
4614
+ return t.summary_for_prompt;
4615
+ }
4616
+ if (Array.isArray(r.stdout) || Array.isArray(r.output)) {
4617
+ try {
4618
+ return JSON.stringify({
4619
+ type: r.type,
4620
+ exit_code: r.exit_code,
4621
+ note: "binary/stdout omitted"
4622
+ });
4623
+ } catch {
4624
+ return "";
4625
+ }
4626
+ }
4627
+ try {
4628
+ return JSON.stringify(raw);
4629
+ } catch {
4630
+ return "";
4631
+ }
4632
+ }
4633
+ return String(raw);
4634
+ }
4635
+ function toolNameOf(update2) {
4636
+ const meta = update2._meta;
4637
+ if (meta && typeof meta === "object") {
4638
+ const xai = meta["x.ai/tool"];
4639
+ if (xai && typeof xai === "object") {
4640
+ const name = xai.name;
4641
+ if (typeof name === "string" && name)
4642
+ return name;
4643
+ }
4644
+ }
4645
+ if (typeof update2.title === "string" && update2.title) {
4646
+ if (!update2.title.includes(" ") && !update2.title.includes("`"))
4647
+ return update2.title;
4648
+ return update2.title;
4649
+ }
4650
+ return "tool";
4651
+ }
4652
+ function statusOf(update2) {
4653
+ const s = update2.status;
4654
+ if (typeof s === "string")
4655
+ return s;
4656
+ if (s && typeof s === "object" && typeof s.status === "string")
4657
+ return s.status;
4658
+ return void 0;
4659
+ }
4660
+ function lineTimestampIso(line) {
4661
+ const meta = line.params?._meta;
4662
+ const agentMs = meta && typeof meta.agentTimestampMs === "number" ? meta.agentTimestampMs : void 0;
4663
+ if (agentMs != null && Number.isFinite(agentMs)) {
4664
+ return new Date(agentMs).toISOString();
4665
+ }
4666
+ const ts = line.timestamp;
4667
+ if (typeof ts === "number" && Number.isFinite(ts)) {
4668
+ const ms = ts > 1e12 ? ts : ts * 1e3;
4669
+ return new Date(ms).toISOString();
4670
+ }
4671
+ return void 0;
4672
+ }
4673
+ function computeActiveSegments5(tsMs) {
4674
+ if (tsMs.length === 0)
4675
+ return [];
4676
+ const sorted = [...tsMs].sort((a, b) => a - b);
4677
+ const out = [];
4678
+ let segStart = sorted[0];
4679
+ let segEnd = sorted[0];
4680
+ for (let i = 1; i < sorted.length; i++) {
4681
+ const t = sorted[i];
4682
+ if (t - segEnd > IDLE_GAP_MS4) {
4683
+ out.push({ startMs: segStart, endMs: segEnd });
4684
+ segStart = t;
4685
+ }
4686
+ segEnd = t;
4687
+ }
4688
+ out.push({ startMs: segStart, endMs: segEnd });
4689
+ return out;
4690
+ }
4691
+ async function parseSession3(dir) {
4692
+ const [summary, signals, updatesRaw] = await Promise.all([
4693
+ safeReadJson(dir.summaryPath),
4694
+ dir.signalsPath ? safeReadJson(dir.signalsPath) : Promise.resolve(null),
4695
+ fs6.readFile(dir.updatesPath, "utf8").catch(() => "")
4696
+ ]);
4697
+ const sessionId = summary?.info?.id ?? dir.sessionId;
4698
+ const cwd = summary?.info?.cwd ?? dir.decodedCwd;
4699
+ let model = summary?.current_model_id ?? signals?.primaryModelId ?? signals?.modelsUsed?.[0];
4700
+ const events = [];
4701
+ const totalUsage = emptyUsage4();
4702
+ if (signals?.contextTokensUsed && signals.contextTokensUsed > 0) {
4703
+ totalUsage.input = signals.contextTokensUsed;
4704
+ }
4705
+ let firstTimestamp;
4706
+ let lastTimestamp;
4707
+ let toolCallCount = 0;
4708
+ let turnCount = 0;
4709
+ let firstUserPreview;
4710
+ let lastUserPreview;
4711
+ let lastAgentPreview;
4712
+ const tsMs = [];
4713
+ let idx = 0;
4714
+ const completedToolResults = /* @__PURE__ */ new Set();
4715
+ let maxTotalTokens = 0;
4716
+ function noteTs(ts, role) {
4717
+ if (!ts || role === "meta")
4718
+ return;
4719
+ if (!firstTimestamp)
4720
+ firstTimestamp = ts;
4721
+ lastTimestamp = ts;
4722
+ const ms = Date.parse(ts);
4723
+ if (Number.isFinite(ms))
4724
+ tsMs.push(ms);
4725
+ }
4726
+ function pushEvent(e) {
4727
+ events.push(e);
4728
+ noteTs(e.timestamp, e.role);
4729
+ }
4730
+ let buf = null;
4731
+ function flushBuf() {
4732
+ if (!buf)
4733
+ return;
4734
+ const text = buf.texts.join("");
4735
+ const preview = previewOf4(text);
4736
+ if (buf.kind === "user") {
4737
+ const isHidden = !text || isFrameworkInjectedUserInput(text);
4738
+ if (text && !isHidden) {
4739
+ if (!firstUserPreview)
4740
+ firstUserPreview = preview;
4741
+ lastUserPreview = preview;
4742
+ turnCount += 1;
4743
+ }
4744
+ if (text) {
4745
+ pushEvent({
4746
+ index: idx++,
4747
+ timestamp: buf.firstTs,
4748
+ role: "user",
4749
+ rawType: "grok/user_message",
4750
+ preview,
4751
+ blocks: [{ type: "text", text }],
4752
+ messageId: buf.promptId,
4753
+ raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
4754
+ });
4755
+ }
4756
+ } else if (buf.kind === "agent") {
4757
+ if (text)
4758
+ lastAgentPreview = preview;
4759
+ if (text) {
4760
+ pushEvent({
4761
+ index: idx++,
4762
+ timestamp: buf.firstTs,
4763
+ role: "agent",
4764
+ rawType: "grok/agent_message",
4765
+ preview,
4766
+ blocks: [{ type: "text", text }],
4767
+ messageId: buf.promptId,
4768
+ model: buf.model ?? model,
4769
+ raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
4770
+ });
4771
+ }
4772
+ } else if (buf.kind === "thought") {
4773
+ if (text) {
4774
+ pushEvent({
4775
+ index: idx++,
4776
+ timestamp: buf.firstTs,
4777
+ role: "agent-thinking",
4778
+ rawType: "grok/agent_thought",
4779
+ preview,
4780
+ blocks: [{ type: "thinking", thinking: text }],
4781
+ messageId: buf.promptId,
4782
+ model: buf.model ?? model,
4783
+ raw: buf.raw.length === 1 ? buf.raw[0] : buf.raw
4784
+ });
4785
+ }
4786
+ }
4787
+ buf = null;
4788
+ }
4789
+ function appendChunk(kind, text, ts, promptId, modelId, raw) {
4790
+ if (!text && kind === "user")
4791
+ return;
4792
+ if (buf && buf.kind !== kind)
4793
+ flushBuf();
4794
+ if (!buf) {
4795
+ buf = {
4796
+ kind,
4797
+ texts: [],
4798
+ firstTs: ts,
4799
+ lastTs: ts,
4800
+ model: modelId,
4801
+ promptId,
4802
+ raw: []
4803
+ };
4804
+ }
4805
+ if (text)
4806
+ buf.texts.push(text);
4807
+ buf.lastTs = ts ?? buf.lastTs;
4808
+ if (modelId)
4809
+ buf.model = modelId;
4810
+ if (promptId)
4811
+ buf.promptId = promptId;
4812
+ buf.raw.push(raw);
4813
+ }
4814
+ const lines = updatesRaw.split("\n");
4815
+ for (const line of lines) {
4816
+ const trimmed = line.trim();
4817
+ if (!trimmed)
4818
+ continue;
4819
+ let obj;
4820
+ try {
4821
+ obj = JSON.parse(trimmed);
4822
+ } catch {
4823
+ continue;
4824
+ }
4825
+ const update2 = obj.params?.update;
4826
+ if (!update2 || typeof update2 !== "object")
4827
+ continue;
4828
+ const st = update2.sessionUpdate;
4829
+ if (!st)
4830
+ continue;
4831
+ const ts = lineTimestampIso(obj);
4832
+ const lineMeta = obj.params?._meta ?? {};
4833
+ const updateMeta = update2._meta ?? {};
4834
+ const promptId = typeof lineMeta.promptId === "string" && lineMeta.promptId || typeof updateMeta.promptId === "string" && updateMeta.promptId || void 0;
4835
+ const modelId = typeof updateMeta.modelId === "string" && updateMeta.modelId || typeof lineMeta.modelId === "string" && lineMeta.modelId || void 0;
4836
+ if (modelId)
4837
+ model = modelId;
4838
+ const totalTok = lineMeta.totalTokens;
4839
+ if (typeof totalTok === "number" && totalTok > maxTotalTokens) {
4840
+ maxTotalTokens = totalTok;
4841
+ }
4842
+ if (st === "user_message_chunk") {
4843
+ const text = textFromContent2(update2.content);
4844
+ appendChunk("user", text, ts, promptId, modelId, obj);
4845
+ continue;
4846
+ }
4847
+ if (st === "agent_message_chunk") {
4848
+ const text = textFromContent2(update2.content);
4849
+ appendChunk("agent", text, ts, promptId, modelId, obj);
4850
+ continue;
4851
+ }
4852
+ if (st === "agent_thought_chunk") {
4853
+ const text = textFromContent2(update2.content);
4854
+ appendChunk("thought", text, ts, promptId, modelId, obj);
4855
+ continue;
4856
+ }
4857
+ flushBuf();
4858
+ if (st === "tool_call") {
4859
+ const toolCallId = typeof update2.toolCallId === "string" ? update2.toolCallId : `grok-${idx}`;
4860
+ const name = toolNameOf(update2);
4861
+ const input = update2.rawInput ?? {};
4862
+ const argsStr = input ? JSON.stringify(input) : "";
4863
+ toolCallCount += 1;
4864
+ pushEvent({
4865
+ index: idx++,
4866
+ timestamp: ts,
4867
+ role: "tool-call",
4868
+ rawType: "grok/tool_call",
4869
+ preview: `${name}(${truncate5(argsStr, 80)})`,
4870
+ blocks: [{ type: "tool_use", id: toolCallId, name, input }],
4871
+ toolName: name,
4872
+ toolUseId: toolCallId,
4873
+ model,
4874
+ raw: obj
4875
+ });
4876
+ continue;
4877
+ }
4878
+ if (st === "tool_call_update") {
4879
+ const status2 = statusOf(update2);
4880
+ if (status2 !== "completed" && status2 !== "failed" && status2 !== "error" && status2 !== "cancelled") {
4881
+ continue;
4882
+ }
4883
+ const toolCallId = typeof update2.toolCallId === "string" ? update2.toolCallId : "";
4884
+ if (toolCallId && completedToolResults.has(toolCallId))
4885
+ continue;
4886
+ if (toolCallId)
4887
+ completedToolResults.add(toolCallId);
4888
+ const resultText = toolResultText(update2);
4889
+ const isError = status2 === "failed" || status2 === "error" || status2 === "cancelled";
4890
+ pushEvent({
4891
+ index: idx++,
4892
+ timestamp: ts,
4893
+ role: "tool-result",
4894
+ rawType: "grok/tool_result",
4895
+ preview: previewOf4(resultText),
4896
+ blocks: [
4897
+ {
4898
+ type: "tool_result",
4899
+ tool_use_id: toolCallId,
4900
+ content: resultText,
4901
+ is_error: isError || void 0
4902
+ }
4903
+ ],
4904
+ toolUseId: toolCallId || void 0,
4905
+ toolResult: resultText,
4906
+ raw: obj
4907
+ });
4908
+ continue;
4909
+ }
4910
+ if (st === "turn_completed") {
4911
+ continue;
4912
+ }
4913
+ }
4914
+ flushBuf();
4915
+ if (totalUsage.input === 0 && maxTotalTokens > 0) {
4916
+ totalUsage.input = maxTotalTokens;
4917
+ }
4918
+ if (!firstTimestamp && summary?.created_at)
4919
+ firstTimestamp = summary.created_at;
4920
+ if (!lastTimestamp) {
4921
+ lastTimestamp = summary?.last_active_at ?? summary?.updated_at ?? firstTimestamp;
4922
+ }
4923
+ if (signals?.toolCallCount != null && signals.toolCallCount > toolCallCount) {
4924
+ toolCallCount = signals.toolCallCount;
4925
+ }
4926
+ if (signals?.turnCount != null && signals.turnCount > turnCount) {
4927
+ turnCount = signals.turnCount;
4928
+ }
4929
+ const startMs = firstTimestamp ? Date.parse(firstTimestamp) : void 0;
4930
+ if (startMs !== void 0 && Number.isFinite(startMs)) {
4931
+ let prevMs;
4932
+ for (const ev of events) {
4933
+ if (!ev.timestamp)
4934
+ continue;
4935
+ const ms = Date.parse(ev.timestamp);
4936
+ if (!Number.isFinite(ms))
4937
+ continue;
4938
+ ev.tOffsetMs = Math.max(0, ms - startMs);
4939
+ if (prevMs !== void 0)
4940
+ ev.gapMs = Math.max(0, ms - prevMs);
4941
+ prevMs = ms;
4942
+ }
4943
+ }
4944
+ const activeSegments = computeActiveSegments5(tsMs);
4945
+ const airTimeMs = activeSegments.reduce((acc, s) => acc + (s.endMs - s.startMs), 0);
4946
+ const durationMs = firstTimestamp && lastTimestamp ? Date.parse(lastTimestamp) - Date.parse(firstTimestamp) : void 0;
4947
+ const project = cwd ? resolveProjectIdentity(cwd) : void 0;
4948
+ const projectName = project?.projectName ?? cwd ?? dir.decodedCwd;
4949
+ const projectDir = dir.groupName || (cwd ? encodeURIComponent(cwd) : "(unknown)");
4950
+ if (!firstUserPreview) {
4951
+ const title = summary?.generated_title || summary?.session_summary;
4952
+ if (title)
4953
+ firstUserPreview = previewOf4(title);
4954
+ }
4955
+ const spawnedAgentCount = await countSubagentChildren(dir.dirPath);
4956
+ const meta = {
4957
+ agent: "grok",
4958
+ id: sessionId,
4959
+ filePath: dir.updatesPath,
4960
+ projectName,
4961
+ worktreeName: project?.worktreeName,
4962
+ repoName: project?.repoName,
4963
+ projectDir,
4964
+ sessionId,
4965
+ firstTimestamp,
4966
+ lastTimestamp,
4967
+ lastActivityMs: lastTimestamp ? Date.parse(lastTimestamp) : void 0,
4968
+ durationMs: durationMs && Number.isFinite(durationMs) ? durationMs : void 0,
4969
+ eventCount: events.length,
4970
+ model,
4971
+ cwd,
4972
+ gitBranch: summary?.head_branch,
4973
+ agentName: summary?.agent_name,
4974
+ totalUsage,
4975
+ status: "idle",
4976
+ firstUserPreview,
4977
+ lastUserPreview,
4978
+ lastAgentPreview,
4979
+ toolCallCount,
4980
+ turnCount,
4981
+ linesAdded: signals?.agentLinesAdded,
4982
+ linesRemoved: signals?.agentLinesRemoved,
4983
+ airTimeMs,
4984
+ activeSegments,
4985
+ ...spawnedAgentCount > 0 ? { spawnedAgentCount } : {}
4986
+ };
4987
+ return { meta, events, sessionKind: summary?.session_kind };
4988
+ }
4989
+ async function countSubagentChildren(dirPath) {
4990
+ const subRoot = path6.join(dirPath, "subagents");
4991
+ const entries2 = await safeReaddir5(subRoot);
4992
+ let n = 0;
4993
+ for (const e of entries2) {
4994
+ const st = await fs6.stat(path6.join(subRoot, e)).catch(() => null);
4995
+ if (st?.isDirectory())
4996
+ n += 1;
4997
+ }
4998
+ return n;
4999
+ }
5000
+ async function loadGrokSubagents(parentDir, parentStartMs) {
5001
+ const subRoot = path6.join(parentDir.dirPath, "subagents");
5002
+ const entries2 = await safeReaddir5(subRoot);
5003
+ const groupDir = path6.dirname(parentDir.dirPath);
5004
+ const runs2 = [];
5005
+ for (const entry of entries2) {
5006
+ const metaPath = path6.join(subRoot, entry, "meta.json");
5007
+ const meta = await safeReadJson(metaPath);
5008
+ if (!meta)
5009
+ continue;
5010
+ const childId = meta.child_session_id ?? meta.subagent_id ?? entry;
5011
+ const childDir = path6.join(groupDir, childId);
5012
+ const [childSummary, childSignals] = await Promise.all([
5013
+ safeReadJson(path6.join(childDir, "summary.json")),
5014
+ safeReadJson(path6.join(childDir, "signals.json"))
5015
+ ]);
5016
+ const startMs = childSummary?.created_at ? Date.parse(childSummary.created_at) : void 0;
5017
+ const endIso = childSummary?.last_active_at ?? childSummary?.updated_at;
5018
+ const endMs = endIso ? Date.parse(endIso) : void 0;
5019
+ const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
5020
+ const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
5021
+ const usage2 = emptyUsage4();
5022
+ if (childSignals?.contextTokensUsed)
5023
+ usage2.input = childSignals.contextTokensUsed;
5024
+ runs2.push({
5025
+ agentId: childId,
5026
+ agentType: meta.subagent_type ?? childSummary?.agent_name ?? "subagent",
5027
+ description: meta.description && meta.description.trim() || childSummary?.generated_title || childSummary?.session_summary || childId,
5028
+ startMs: startOk,
5029
+ endMs: endOk,
5030
+ durationMs: startOk !== void 0 && endOk !== void 0 ? Math.max(0, endOk - startOk) : void 0,
5031
+ startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
5032
+ endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
5033
+ eventCount: childSummary?.num_messages ?? childSummary?.num_chat_messages ?? 0,
5034
+ totalUsage: usage2,
5035
+ prompt: typeof meta.prompt === "string" ? meta.prompt : void 0,
5036
+ model: childSummary?.current_model_id ?? childSignals?.primaryModelId,
5037
+ toolCallCount: childSignals?.toolCallCount
5038
+ });
5039
+ }
5040
+ runs2.sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
5041
+ return runs2;
5042
+ }
5043
+ function clearGrokCaches() {
5044
+ metaCache6.clear();
5045
+ detailCache6.clear();
5046
+ }
5047
+ async function listGrokSessions(opts = {}) {
5048
+ const root = opts.root ?? resolveDefaultGrokRoot();
5049
+ const dirs = await listSessionDirs(root);
5050
+ const out = [];
5051
+ for (const dir of dirs) {
5052
+ const summaryPeek = await safeReadJson(dir.summaryPath);
5053
+ if (summaryPeek?.session_kind === "subagent")
5054
+ continue;
5055
+ const cached = metaCache6.get(dir.dirPath);
5056
+ if (cached && cached.mtimeMs === dir.mtimeMs && cached.sizeBytes === dir.sizeBytes) {
5057
+ out.push(cached.meta);
5058
+ continue;
5059
+ }
5060
+ try {
5061
+ const { meta, sessionKind } = await parseSession3(dir);
5062
+ if (sessionKind === "subagent")
5063
+ continue;
5064
+ metaCache6.set(dir.dirPath, {
5065
+ meta,
5066
+ mtimeMs: dir.mtimeMs,
5067
+ sizeBytes: dir.sizeBytes
5068
+ });
5069
+ out.push(meta);
5070
+ } catch {
5071
+ }
5072
+ }
5073
+ out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
5074
+ if (opts.limit !== void 0)
5075
+ return out.slice(0, opts.limit);
5076
+ return out;
5077
+ }
5078
+ async function getGrokSession(id, opts = {}) {
5079
+ const root = opts.root ?? resolveDefaultGrokRoot();
5080
+ const dirs = await listSessionDirs(root);
5081
+ const chosen = dirs.find((d) => d.sessionId === id);
5082
+ if (!chosen) {
5083
+ for (const dir of dirs) {
5084
+ try {
5085
+ const { meta: meta2, events: events2 } = await parseSession3(dir);
5086
+ if (meta2.id === id) {
5087
+ const detail2 = { ...meta2, events: events2 };
5088
+ detailCache6.set(dir.dirPath, {
5089
+ detail: detail2,
5090
+ mtimeMs: dir.mtimeMs,
5091
+ sizeBytes: dir.sizeBytes
5092
+ });
5093
+ return detail2;
5094
+ }
5095
+ } catch {
5096
+ }
5097
+ }
5098
+ return null;
5099
+ }
5100
+ const cached = detailCache6.get(chosen.dirPath);
5101
+ if (cached && cached.mtimeMs === chosen.mtimeMs && cached.sizeBytes === chosen.sizeBytes) {
5102
+ return cached.detail;
5103
+ }
5104
+ const { meta, events } = await parseSession3(chosen);
5105
+ const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
5106
+ const subagents = await loadGrokSubagents(chosen, parentStartMs !== void 0 && Number.isFinite(parentStartMs) ? parentStartMs : void 0);
5107
+ const detail = {
5108
+ ...meta,
5109
+ events,
5110
+ ...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
5111
+ };
5112
+ detailCache6.set(chosen.dirPath, {
5113
+ detail,
5114
+ mtimeMs: chosen.mtimeMs,
5115
+ sizeBytes: chosen.sizeBytes
5116
+ });
5117
+ metaCache6.set(chosen.dirPath, {
5118
+ meta: {
5119
+ ...meta,
5120
+ ...subagents.length > 0 ? { spawnedAgentCount: subagents.length } : {}
5121
+ },
5122
+ mtimeMs: chosen.mtimeMs,
5123
+ sizeBytes: chosen.sizeBytes
5124
+ });
5125
+ return detail;
5126
+ }
5127
+ function grokSessionLocalDay(meta) {
5128
+ if (!meta.firstTimestamp)
5129
+ return void 0;
5130
+ const ms = Date.parse(meta.firstTimestamp);
5131
+ return Number.isFinite(ms) ? toLocalDay(ms) : void 0;
5132
+ }
5133
+ var DEFAULT_GROK_ROOT, IDLE_GAP_MS4, metaCache6, detailCache6;
5134
+ var init_grok = __esm({
5135
+ "../parser/dist/grok.js"() {
5136
+ "use strict";
5137
+ init_analytics();
5138
+ init_git_project();
5139
+ init_user_input();
5140
+ DEFAULT_GROK_ROOT = path6.join(os6.homedir(), ".grok", "sessions");
5141
+ IDLE_GAP_MS4 = 3 * 60 * 1e3;
5142
+ metaCache6 = /* @__PURE__ */ new Map();
5143
+ detailCache6 = /* @__PURE__ */ new Map();
5144
+ }
5145
+ });
5146
+
4472
5147
  // ../parser/dist/team-config.js
4473
5148
  import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, renameSync } from "node:fs";
4474
5149
  import { join as join2 } from "node:path";
@@ -4528,6 +5203,7 @@ __export(fs_exports, {
4528
5203
  DEFAULT_CODEX_ROOT: () => DEFAULT_CODEX_ROOT,
4529
5204
  DEFAULT_COWORK_ROOT: () => DEFAULT_COWORK_ROOT,
4530
5205
  DEFAULT_GEMINI_ROOT: () => DEFAULT_GEMINI_ROOT,
5206
+ DEFAULT_GROK_ROOT: () => DEFAULT_GROK_ROOT,
4531
5207
  DEFAULT_ROOT: () => DEFAULT_ROOT,
4532
5208
  RICH_ROLLUP_SCHEMA_VERSION: () => RICH_ROLLUP_SCHEMA_VERSION,
4533
5209
  agentSources: () => agentSources,
@@ -4538,6 +5214,7 @@ __export(fs_exports, {
4538
5214
  cclensHome: () => cclensHome,
4539
5215
  cclensPath: () => cclensPath,
4540
5216
  clearCaches: () => clearCaches,
5217
+ clearGrokCaches: () => clearGrokCaches,
4541
5218
  clearTeamConfig: () => clearTeamConfig,
4542
5219
  codexSessionLocalDay: () => codexSessionLocalDay,
4543
5220
  decodeProjectName: () => decodeProjectName,
@@ -4549,8 +5226,10 @@ __export(fs_exports, {
4549
5226
  getCodexSession: () => getCodexSession,
4550
5227
  getCoworkSession: () => getCoworkSession,
4551
5228
  getGeminiSession: () => getGeminiSession,
5229
+ getGrokSession: () => getGrokSession,
4552
5230
  getLatestCodexUsage: () => getLatestCodexUsage,
4553
5231
  getSession: () => getSession,
5232
+ grokSessionLocalDay: () => grokSessionLocalDay,
4554
5233
  invalidateFile: () => invalidateFile,
4555
5234
  isFleetlensRuntimeDir: () => isFleetlensRuntimeDir,
4556
5235
  listAllSessions: () => listAllSessions,
@@ -4558,6 +5237,7 @@ __export(fs_exports, {
4558
5237
  listCodexSessions: () => listCodexSessions,
4559
5238
  listCoworkSessions: () => listCoworkSessions,
4560
5239
  listGeminiSessions: () => listGeminiSessions,
5240
+ listGrokSessions: () => listGrokSessions,
4561
5241
  listProjects: () => listProjects,
4562
5242
  listSessions: () => listSessions,
4563
5243
  loadCalibrationCurve: () => loadCalibrationCurve,
@@ -4570,20 +5250,21 @@ __export(fs_exports, {
4570
5250
  readGitFolder: () => readGitFolder,
4571
5251
  readJsonlFile: () => readJsonlFile,
4572
5252
  readTeamConfig: () => readTeamConfig,
5253
+ resolveDefaultGrokRoot: () => resolveDefaultGrokRoot,
4573
5254
  resolveProjectIdentity: () => resolveProjectIdentity,
4574
5255
  sessionIdFromFileName: () => sessionIdFromFileName,
4575
5256
  shouldSyncProject: () => shouldSyncProject,
4576
5257
  walkJsonlFiles: () => walkJsonlFiles,
4577
5258
  writeTeamConfig: () => writeTeamConfig
4578
5259
  });
4579
- import { promises as fs6, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
4580
- import os6 from "node:os";
4581
- import path6 from "node:path";
5260
+ import { promises as fs7, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync3 } from "node:fs";
5261
+ import os7 from "node:os";
5262
+ import path7 from "node:path";
4582
5263
  function cclensHome() {
4583
- return process.env.CCLENS_HOME || path6.join(os6.homedir(), ".cclens");
5264
+ return process.env.CCLENS_HOME || path7.join(os7.homedir(), ".cclens");
4584
5265
  }
4585
5266
  function cclensPath(...parts) {
4586
- return path6.join(cclensHome(), ...parts);
5267
+ return path7.join(cclensHome(), ...parts);
4587
5268
  }
4588
5269
  function cacheStats() {
4589
5270
  return claudeCodeCacheStats();
@@ -4594,6 +5275,7 @@ function clearCaches() {
4594
5275
  clearGeminiCaches();
4595
5276
  clearAntigravityCaches();
4596
5277
  clearCoworkCaches();
5278
+ clearGrokCaches();
4597
5279
  }
4598
5280
  function invalidateFile(fullPath) {
4599
5281
  invalidateClaudeCodeFile(fullPath);
@@ -4624,7 +5306,7 @@ function usageLogPath() {
4624
5306
  }
4625
5307
  function appendUsageSnapshot(snapshot) {
4626
5308
  const p = usageLogPath();
4627
- mkdirSync3(path6.dirname(p), { recursive: true });
5309
+ mkdirSync3(path7.dirname(p), { recursive: true });
4628
5310
  appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
4629
5311
  }
4630
5312
  function pruneUsageAgent(agent) {
@@ -4640,13 +5322,13 @@ function pruneUsageAgent(agent) {
4640
5322
  return true;
4641
5323
  }
4642
5324
  });
4643
- mkdirSync3(path6.dirname(p), { recursive: true });
5325
+ mkdirSync3(path7.dirname(p), { recursive: true });
4644
5326
  writeFileSync3(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
4645
5327
  }
4646
5328
  async function loadUsageByDay(start2, end) {
4647
5329
  let raw;
4648
5330
  try {
4649
- raw = await fs6.readFile(usageLogPath(), "utf8");
5331
+ raw = await fs7.readFile(usageLogPath(), "utf8");
4650
5332
  } catch {
4651
5333
  return { by_day: [] };
4652
5334
  }
@@ -4691,7 +5373,7 @@ async function loadUsageByDay(start2, end) {
4691
5373
  async function loadCalibrationSnapshots() {
4692
5374
  let raw;
4693
5375
  try {
4694
- raw = await fs6.readFile(usageLogPath(), "utf8");
5376
+ raw = await fs7.readFile(usageLogPath(), "utf8");
4695
5377
  } catch {
4696
5378
  return [];
4697
5379
  }
@@ -4855,7 +5537,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
4855
5537
  ]);
4856
5538
  return buildCalibrationCurve(events, snapshots, tier, granularityMin);
4857
5539
  }
4858
- var codexSource, geminiSource, antigravitySource, coworkSource, agentSources;
5540
+ var codexSource, geminiSource, antigravitySource, coworkSource, grokSource, agentSources;
4859
5541
  var init_fs = __esm({
4860
5542
  "../parser/dist/fs.js"() {
4861
5543
  "use strict";
@@ -4867,12 +5549,14 @@ var init_fs = __esm({
4867
5549
  init_gemini();
4868
5550
  init_antigravity();
4869
5551
  init_cowork();
5552
+ init_grok();
4870
5553
  init_claude_code();
4871
5554
  init_git_project();
4872
5555
  init_codex();
4873
5556
  init_gemini();
4874
5557
  init_antigravity();
4875
5558
  init_cowork();
5559
+ init_grok();
4876
5560
  init_team_config();
4877
5561
  init_team_wire();
4878
5562
  codexSource = {
@@ -4926,12 +5610,24 @@ var init_fs = __esm({
4926
5610
  return getCoworkSession(id);
4927
5611
  }
4928
5612
  };
5613
+ grokSource = {
5614
+ ...GROK_METADATA,
5615
+ // Display default; list/get re-resolve GROK_HOME at call time internally.
5616
+ defaultRoot: DEFAULT_GROK_ROOT,
5617
+ async listSessions(opts) {
5618
+ return listGrokSessions(opts);
5619
+ },
5620
+ async getSession(id, opts) {
5621
+ return getGrokSession(id, opts);
5622
+ }
5623
+ };
4929
5624
  agentSources = [
4930
5625
  claudeCodeSource,
4931
5626
  codexSource,
4932
5627
  geminiSource,
4933
5628
  antigravitySource,
4934
- coworkSource
5629
+ coworkSource,
5630
+ grokSource
4935
5631
  ];
4936
5632
  }
4937
5633
  });
@@ -4967,9 +5663,9 @@ function onDiskVersion() {
4967
5663
  try {
4968
5664
  const here = dirname3(fileURLToPath(import.meta.url));
4969
5665
  const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
4970
- return pkg.version ?? "0.16.0";
5666
+ return pkg.version ?? "0.16.1";
4971
5667
  } catch {
4972
- return "0.16.0";
5668
+ return "0.16.1";
4973
5669
  }
4974
5670
  }
4975
5671
  function getServerStatus() {
@@ -4981,7 +5677,7 @@ function getServerStatus() {
4981
5677
  return { running: false };
4982
5678
  }
4983
5679
  function isServerStale(status2) {
4984
- return status2.running === true && status2.version !== "0.16.0";
5680
+ return status2.running === true && status2.version !== "0.16.1";
4985
5681
  }
4986
5682
  async function ensureCurrentServer(opts = {}) {
4987
5683
  const status2 = getServerStatus();
@@ -5420,9 +6116,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
5420
6116
  console.warn(
5421
6117
  ` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
5422
6118
  );
5423
- } else if (verify.installedVersion !== "0.16.0") {
6119
+ } else if (verify.installedVersion !== "0.16.1") {
5424
6120
  console.log(
5425
- ` \u2192 This process is still running ${"0.16.0"}. Next invocation will use ${verify.installedVersion}.`
6121
+ ` \u2192 This process is still running ${"0.16.1"}. Next invocation will use ${verify.installedVersion}.`
5426
6122
  );
5427
6123
  }
5428
6124
  }
@@ -5457,14 +6153,14 @@ async function getUpdateAvailability() {
5457
6153
  if (isDevMode()) return null;
5458
6154
  const latest = await fetchLatestVersion();
5459
6155
  if (latest === null) return {
5460
- current: "0.16.0",
6156
+ current: "0.16.1",
5461
6157
  latest: null,
5462
6158
  updateAvailable: false
5463
6159
  };
5464
6160
  return {
5465
- current: "0.16.0",
6161
+ current: "0.16.1",
5466
6162
  latest,
5467
- updateAvailable: shouldUpdate("0.16.0", latest)
6163
+ updateAvailable: shouldUpdate("0.16.1", latest)
5468
6164
  };
5469
6165
  }
5470
6166
  async function checkForUpdate() {
@@ -5554,7 +6250,7 @@ async function restartServices(state) {
5554
6250
  }
5555
6251
  async function forceUpdate() {
5556
6252
  const latest = await fetchLatestVersion();
5557
- const current = "0.16.0";
6253
+ const current = "0.16.1";
5558
6254
  if (latest === null) {
5559
6255
  console.error("Could not reach npm registry. Check your network.");
5560
6256
  process.exit(1);
@@ -5967,7 +6663,7 @@ async function status() {
5967
6663
  console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
5968
6664
  if (isServerStale(server)) {
5969
6665
  console.log(
5970
- ` \u26A0 serving stale ${ver} (CLI is ${"0.16.0"}) \u2014 run 'fleetlens start' to restart on the current version`
6666
+ ` \u26A0 serving stale ${ver} (CLI is ${"0.16.1"}) \u2014 run 'fleetlens start' to restart on the current version`
5971
6667
  );
5972
6668
  }
5973
6669
  } else {
@@ -6006,7 +6702,7 @@ async function web(args2) {
6006
6702
  const open = args2.includes("--open");
6007
6703
  const positional = args2.filter((a) => !a.startsWith("--"));
6008
6704
  const rawPath = positional[0] ?? "";
6009
- const path7 = rawPath.startsWith("/") ? rawPath : rawPath ? `/${rawPath}` : "";
6705
+ const path9 = rawPath.startsWith("/") ? rawPath : rawPath ? `/${rawPath}` : "";
6010
6706
  let result;
6011
6707
  try {
6012
6708
  result = await ensureCurrentServer({});
@@ -6014,7 +6710,7 @@ async function web(args2) {
6014
6710
  console.error(`Failed to start: ${err.message}`);
6015
6711
  process.exit(1);
6016
6712
  }
6017
- const url = `http://localhost:${result.port}${path7}`;
6713
+ const url = `http://localhost:${result.port}${path9}`;
6018
6714
  if (result.restarted) {
6019
6715
  console.log(`fleetlens restarted on http://localhost:${result.port} (PID ${result.pid}) \u2014 replaced stale ${result.previousVersion ?? "unknown"} server`);
6020
6716
  }
@@ -6075,9 +6771,9 @@ function readFromCredentialsFile() {
6075
6771
  join7(homedir4(), ".claude", ".credentials.json"),
6076
6772
  join7(homedir4(), ".config", "claude", "credentials.json")
6077
6773
  ];
6078
- for (const path7 of candidates) {
6774
+ for (const path9 of candidates) {
6079
6775
  try {
6080
- const blob = readFileSync10(path7, "utf8");
6776
+ const blob = readFileSync10(path9, "utf8");
6081
6777
  const creds = extractCredentials(blob);
6082
6778
  if (creds) return creds;
6083
6779
  } catch {
@@ -6199,6 +6895,224 @@ var init_api = __esm({
6199
6895
  }
6200
6896
  });
6201
6897
 
6898
+ // src/usage/grok.ts
6899
+ import { existsSync as existsSync8, readFileSync as readFileSync11 } from "node:fs";
6900
+ import os8 from "node:os";
6901
+ import path8 from "node:path";
6902
+ function grokHome() {
6903
+ return process.env.GROK_HOME || path8.join(os8.homedir(), ".grok");
6904
+ }
6905
+ function authPath() {
6906
+ return path8.join(grokHome(), "auth.json");
6907
+ }
6908
+ function loadAuthEntry() {
6909
+ const p = authPath();
6910
+ if (!existsSync8(p)) {
6911
+ throw new GrokApiError("Grok not logged in. Run `grok login`.", "no_auth");
6912
+ }
6913
+ let raw;
6914
+ try {
6915
+ raw = JSON.parse(readFileSync11(p, "utf8"));
6916
+ } catch {
6917
+ throw new GrokApiError("Grok auth.json is unreadable. Run `grok login`.", "no_auth");
6918
+ }
6919
+ for (const [entryKey2, entry] of Object.entries(raw)) {
6920
+ const token = typeof entry?.key === "string" ? entry.key.trim() : "";
6921
+ if (token) return { token, entry, entryKey: entryKey2 };
6922
+ }
6923
+ throw new GrokApiError("Grok auth has no access token. Run `grok login`.", "no_auth");
6924
+ }
6925
+ function needsRefresh(entry) {
6926
+ const exp = entry.expires_at;
6927
+ if (!exp) return false;
6928
+ const ms = Date.parse(exp);
6929
+ if (!Number.isFinite(ms)) return false;
6930
+ return Date.now() >= ms - REFRESH_BUFFER_MS;
6931
+ }
6932
+ async function refreshAccessToken(entry) {
6933
+ const refresh = entry.refresh_token?.trim();
6934
+ if (!refresh) return null;
6935
+ const clientId = entry.oidc_client_id?.trim() || DEFAULT_CLIENT_ID;
6936
+ const body = new URLSearchParams({
6937
+ grant_type: "refresh_token",
6938
+ client_id: clientId,
6939
+ refresh_token: refresh
6940
+ });
6941
+ let res;
6942
+ try {
6943
+ res = await fetch(REFRESH_URL, {
6944
+ method: "POST",
6945
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
6946
+ body: body.toString()
6947
+ });
6948
+ } catch {
6949
+ return null;
6950
+ }
6951
+ if (!res.ok) return null;
6952
+ try {
6953
+ const j = await res.json();
6954
+ if (typeof j.access_token !== "string" || !j.access_token) return null;
6955
+ try {
6956
+ const p = authPath();
6957
+ const raw = JSON.parse(readFileSync11(p, "utf8"));
6958
+ for (const key of Object.keys(raw)) {
6959
+ if (raw[key]?.key === entry.key || raw[key]?.refresh_token === refresh) {
6960
+ raw[key] = {
6961
+ ...raw[key],
6962
+ key: j.access_token,
6963
+ refresh_token: j.refresh_token ?? raw[key].refresh_token,
6964
+ expires_at: typeof j.expires_in === "number" ? new Date(Date.now() + j.expires_in * 1e3).toISOString() : raw[key].expires_at
6965
+ };
6966
+ break;
6967
+ }
6968
+ }
6969
+ const { writeFileSync: writeFileSync17 } = await import("node:fs");
6970
+ writeFileSync17(p, JSON.stringify(raw, null, 2), "utf8");
6971
+ } catch {
6972
+ }
6973
+ return j.access_token;
6974
+ } catch {
6975
+ return null;
6976
+ }
6977
+ }
6978
+ function authHeaders(token) {
6979
+ return {
6980
+ Authorization: `Bearer ${token.trim()}`,
6981
+ "X-XAI-Token-Auth": TOKEN_AUTH,
6982
+ Accept: "application/json",
6983
+ "User-Agent": "fleetlens"
6984
+ };
6985
+ }
6986
+ function parseGrokCreditsConfig(body) {
6987
+ if (!body || typeof body !== "object") {
6988
+ throw new GrokApiError("Grok billing response missing body", "parse");
6989
+ }
6990
+ const config = body.config;
6991
+ if (!config || typeof config !== "object") {
6992
+ throw new GrokApiError("Grok billing response missing config", "parse");
6993
+ }
6994
+ const period = config.currentPeriod;
6995
+ if (!period || typeof period !== "object") {
6996
+ throw new GrokApiError("Grok billing response missing currentPeriod", "parse");
6997
+ }
6998
+ const periodType = typeof period.type === "string" ? period.type.trim() : "";
6999
+ if (!periodType) {
7000
+ throw new GrokApiError("Grok billing period type missing", "parse");
7001
+ }
7002
+ let utilization = 0;
7003
+ if (config.creditUsagePercent !== void 0 && config.creditUsagePercent !== null) {
7004
+ const n = Number(config.creditUsagePercent);
7005
+ if (!Number.isFinite(n)) {
7006
+ throw new GrokApiError("Grok creditUsagePercent is not a number", "parse");
7007
+ }
7008
+ utilization = Math.min(100, Math.max(0, n));
7009
+ }
7010
+ const end = typeof period.end === "string" && period.end ? new Date(period.end).toISOString() : null;
7011
+ let onDemandCap = 0;
7012
+ const cap = config.onDemandCap;
7013
+ if (cap && typeof cap === "object" && "val" in cap) {
7014
+ const v = Number(cap.val);
7015
+ if (Number.isFinite(v)) onDemandCap = v;
7016
+ }
7017
+ return {
7018
+ utilization,
7019
+ resets_at: end && !Number.isNaN(Date.parse(end)) ? end : null,
7020
+ period_type: periodType,
7021
+ on_demand_cap: onDemandCap
7022
+ };
7023
+ }
7024
+ async function fetchJson(url, token) {
7025
+ let res;
7026
+ try {
7027
+ res = await fetch(url, { headers: authHeaders(token) });
7028
+ } catch (err) {
7029
+ throw new GrokApiError(
7030
+ `Network error reaching Grok billing: ${err.message}`,
7031
+ "network"
7032
+ );
7033
+ }
7034
+ let body = null;
7035
+ try {
7036
+ body = await res.json();
7037
+ } catch {
7038
+ }
7039
+ return { status: res.status, body };
7040
+ }
7041
+ async function fetchGrokUsage() {
7042
+ const loaded = loadAuthEntry();
7043
+ const entry = loaded.entry;
7044
+ let token = loaded.token;
7045
+ if (needsRefresh(entry)) {
7046
+ const refreshed = await refreshAccessToken(entry);
7047
+ if (refreshed) token = refreshed;
7048
+ }
7049
+ let { status: status2, body } = await fetchJson(CREDITS_URL, token);
7050
+ if (status2 === 401 || status2 === 403) {
7051
+ const refreshed = await refreshAccessToken(entry);
7052
+ if (refreshed) {
7053
+ token = refreshed;
7054
+ ({ status: status2, body } = await fetchJson(CREDITS_URL, token));
7055
+ }
7056
+ }
7057
+ if (status2 < 200 || status2 >= 300) {
7058
+ throw new GrokApiError(
7059
+ `Grok billing returned HTTP ${status2}`,
7060
+ status2 === 401 || status2 === 403 ? "no_auth" : "http"
7061
+ );
7062
+ }
7063
+ const credits = parseGrokCreditsConfig(body);
7064
+ if (credits.period_type !== WEEKLY_PERIOD) {
7065
+ throw new GrokApiError(
7066
+ `Grok period is ${credits.period_type}, not weekly`,
7067
+ "not_weekly"
7068
+ );
7069
+ }
7070
+ let planType = null;
7071
+ try {
7072
+ const settings = await fetchJson(SETTINGS_URL, token);
7073
+ if (settings.status >= 200 && settings.status < 300 && settings.body && typeof settings.body === "object") {
7074
+ const tier = settings.body.subscription_tier_display;
7075
+ if (typeof tier === "string" && tier.trim()) planType = tier.trim();
7076
+ }
7077
+ } catch {
7078
+ }
7079
+ return {
7080
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
7081
+ agent: "grok",
7082
+ // No 5-hour window — menubar / strip show "—" on the top line.
7083
+ five_hour: { utilization: null, resets_at: null },
7084
+ seven_day: {
7085
+ utilization: credits.utilization,
7086
+ resets_at: credits.resets_at
7087
+ },
7088
+ seven_day_opus: null,
7089
+ seven_day_sonnet: null,
7090
+ seven_day_oauth_apps: null,
7091
+ seven_day_cowork: null,
7092
+ extra_usage: null,
7093
+ plan_type: planType
7094
+ };
7095
+ }
7096
+ var CREDITS_URL, SETTINGS_URL, REFRESH_URL, TOKEN_AUTH, DEFAULT_CLIENT_ID, WEEKLY_PERIOD, REFRESH_BUFFER_MS, GrokApiError;
7097
+ var init_grok2 = __esm({
7098
+ "src/usage/grok.ts"() {
7099
+ "use strict";
7100
+ CREDITS_URL = "https://cli-chat-proxy.grok.com/v1/billing?format=credits";
7101
+ SETTINGS_URL = "https://cli-chat-proxy.grok.com/v1/settings";
7102
+ REFRESH_URL = "https://auth.x.ai/oauth2/token";
7103
+ TOKEN_AUTH = "xai-grok-cli";
7104
+ DEFAULT_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
7105
+ WEEKLY_PERIOD = "USAGE_PERIOD_TYPE_WEEKLY";
7106
+ REFRESH_BUFFER_MS = 5 * 60 * 1e3;
7107
+ GrokApiError = class extends Error {
7108
+ constructor(message, code) {
7109
+ super(message);
7110
+ this.code = code;
7111
+ }
7112
+ };
7113
+ }
7114
+ });
7115
+
6202
7116
  // src/usage/format.ts
6203
7117
  function formatUsage(snapshot) {
6204
7118
  const rows = [
@@ -6558,6 +7472,30 @@ Usage:
6558
7472
  const snapshot = await fetchUsage();
6559
7473
  if (save) appendSnapshot(USAGE_LOG2, snapshot);
6560
7474
  process.stdout.write(formatUsage(snapshot));
7475
+ if (save) {
7476
+ for (const source of agentSources) {
7477
+ if (source.kind === "claude-code" || !source.usagePoller) continue;
7478
+ try {
7479
+ const partial = await source.usagePoller();
7480
+ if (!partial) continue;
7481
+ appendSnapshot(USAGE_LOG2, {
7482
+ ...partial,
7483
+ seven_day_opus: null,
7484
+ seven_day_sonnet: null,
7485
+ seven_day_oauth_apps: null,
7486
+ seven_day_cowork: null,
7487
+ extra_usage: null
7488
+ });
7489
+ } catch {
7490
+ }
7491
+ }
7492
+ try {
7493
+ appendSnapshot(USAGE_LOG2, await fetchGrokUsage());
7494
+ } catch (err) {
7495
+ if (!(err instanceof GrokApiError && err.code === "no_auth")) {
7496
+ }
7497
+ }
7498
+ }
6561
7499
  process.stdout.write("\n (tip: run with --history for the daily token/cost table)\n");
6562
7500
  } catch (err) {
6563
7501
  if (err instanceof UsageApiError) {
@@ -6572,6 +7510,7 @@ var init_usage = __esm({
6572
7510
  "src/commands/usage.ts"() {
6573
7511
  "use strict";
6574
7512
  init_api();
7513
+ init_grok2();
6575
7514
  init_format();
6576
7515
  init_storage();
6577
7516
  init_fs();
@@ -7068,6 +8007,7 @@ __export(dist_exports, {
7068
8007
  CODEX_METADATA: () => CODEX_METADATA,
7069
8008
  COWORK_METADATA: () => COWORK_METADATA,
7070
8009
  GEMINI_METADATA: () => GEMINI_METADATA,
8010
+ GROK_METADATA: () => GROK_METADATA,
7071
8011
  PRICES: () => PRICES,
7072
8012
  RATE_PER_PCT: () => RATE_PER_PCT,
7073
8013
  RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
@@ -7481,7 +8421,7 @@ function closeTurn(t, closed, cwd) {
7481
8421
  let active = 0;
7482
8422
  for (let i = 1; i < ts.length; i++) {
7483
8423
  const dt = ts[i] - ts[i - 1];
7484
- if (dt < IDLE_GAP_MS4)
8424
+ if (dt < IDLE_GAP_MS5)
7485
8425
  active += dt;
7486
8426
  }
7487
8427
  closed.push({
@@ -7678,7 +8618,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
7678
8618
  let activeMs2 = 0;
7679
8619
  for (let i = 1; i < tsSorted.length; i++) {
7680
8620
  const dt = tsSorted[i] - tsSorted[i - 1];
7681
- if (dt < IDLE_GAP_MS4)
8621
+ if (dt < IDLE_GAP_MS5)
7682
8622
  activeMs2 += dt;
7683
8623
  }
7684
8624
  const tsSortedStrings = dayEvents.map((e) => e.timestamp).filter((t) => !!t).sort();
@@ -7865,7 +8805,7 @@ function buildEntries(sessionDetail) {
7865
8805
  entries2.sort((a, b) => a.local_day.localeCompare(b.local_day));
7866
8806
  return entries2;
7867
8807
  }
7868
- var IDLE_GAP_MS4, INTERRUPT_RE2, PR_TITLE_RE, BASH_CHAIN_SPLIT_RE, SHELL_NOISE, IMAGE_BLOCK_RE;
8808
+ var IDLE_GAP_MS5, INTERRUPT_RE2, PR_TITLE_RE, BASH_CHAIN_SPLIT_RE, SHELL_NOISE, IMAGE_BLOCK_RE;
7869
8809
  var init_build = __esm({
7870
8810
  "../entries/dist/build.js"() {
7871
8811
  "use strict";
@@ -7873,7 +8813,7 @@ var init_build = __esm({
7873
8813
  init_types();
7874
8814
  init_signals();
7875
8815
  init_trivial();
7876
- IDLE_GAP_MS4 = 3 * 60 * 1e3;
8816
+ IDLE_GAP_MS5 = 3 * 60 * 1e3;
7877
8817
  INTERRUPT_RE2 = /\[request interrupted|interrupted by user/i;
7878
8818
  PR_TITLE_RE = /--title\s+["']([^"']+)["']/;
7879
8819
  BASH_CHAIN_SPLIT_RE = /\|\||&&|;|\|/;
@@ -7902,11 +8842,11 @@ var init_dist2 = __esm({
7902
8842
  });
7903
8843
 
7904
8844
  // ../entries/dist/digest-fs.js
7905
- import { readFileSync as readFileSync11, readdirSync, writeFileSync as writeFileSync6, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync6, existsSync as existsSync8 } from "node:fs";
8845
+ import { readFileSync as readFileSync12, readdirSync, writeFileSync as writeFileSync6, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync6, existsSync as existsSync9 } from "node:fs";
7906
8846
  import { dirname as dirname8, join as join8 } from "node:path";
7907
- function parseDigestFile(path7, expectedVersion) {
8847
+ function parseDigestFile(path9, expectedVersion) {
7908
8848
  try {
7909
- const parsed = JSON.parse(readFileSync11(path7, "utf8"));
8849
+ const parsed = JSON.parse(readFileSync12(path9, "utf8"));
7910
8850
  if (!parsed || typeof parsed !== "object")
7911
8851
  return null;
7912
8852
  if (parsed.version !== expectedVersion)
@@ -7925,11 +8865,11 @@ function digestsDir() {
7925
8865
  digestsDirCached = envOverride ?? cclensPath("digests");
7926
8866
  return digestsDirCached;
7927
8867
  }
7928
- function __setDigestsDirForTest(path7) {
7929
- digestsDirCached = path7;
7930
- mkdirSync6(join8(path7, "day"), { recursive: true });
7931
- mkdirSync6(join8(path7, "week"), { recursive: true });
7932
- mkdirSync6(join8(path7, "month"), { recursive: true });
8868
+ function __setDigestsDirForTest(path9) {
8869
+ digestsDirCached = path9;
8870
+ mkdirSync6(join8(path9, "day"), { recursive: true });
8871
+ mkdirSync6(join8(path9, "week"), { recursive: true });
8872
+ mkdirSync6(join8(path9, "month"), { recursive: true });
7933
8873
  }
7934
8874
  function dayDigestPath(date) {
7935
8875
  return join8(digestsDir(), "day", `${date}.json`);
@@ -7955,7 +8895,7 @@ function writeDayDigest(digest2) {
7955
8895
  }
7956
8896
  function readDayDigest(date) {
7957
8897
  const p = dayDigestPath(date);
7958
- if (!existsSync8(p))
8898
+ if (!existsSync9(p))
7959
8899
  return null;
7960
8900
  return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
7961
8901
  }
@@ -7991,13 +8931,13 @@ function writeWeekDigest(digest2) {
7991
8931
  }
7992
8932
  function readWeekDigest(monday) {
7993
8933
  const p = weekDigestPath(monday);
7994
- if (!existsSync8(p))
8934
+ if (!existsSync9(p))
7995
8935
  return null;
7996
8936
  return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
7997
8937
  }
7998
8938
  function listWeekDigestKeys() {
7999
8939
  const dir = join8(digestsDir(), "week");
8000
- if (!existsSync8(dir))
8940
+ if (!existsSync9(dir))
8001
8941
  return [];
8002
8942
  return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}-\d{2}$/.test(k));
8003
8943
  }
@@ -8028,13 +8968,13 @@ function writeMonthDigest(digest2) {
8028
8968
  }
8029
8969
  function readMonthDigest(yearMonth) {
8030
8970
  const p = monthDigestPath(yearMonth);
8031
- if (!existsSync8(p))
8971
+ if (!existsSync9(p))
8032
8972
  return null;
8033
8973
  return parseDigestFile(p, CURRENT_MONTH_DIGEST_SCHEMA_VERSION);
8034
8974
  }
8035
8975
  function listMonthDigestKeys() {
8036
8976
  const dir = join8(digestsDir(), "month");
8037
- if (!existsSync8(dir))
8977
+ if (!existsSync9(dir))
8038
8978
  return [];
8039
8979
  return readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length)).filter((k) => /^\d{4}-\d{2}$/.test(k));
8040
8980
  }
@@ -8096,7 +9036,7 @@ __export(fs_exports2, {
8096
9036
  writeMonthDigest: () => writeMonthDigest,
8097
9037
  writeWeekDigest: () => writeWeekDigest
8098
9038
  });
8099
- import { readFileSync as readFileSync12, readdirSync as readdirSync2, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync9 } from "node:fs";
9039
+ import { readFileSync as readFileSync13, readdirSync as readdirSync2, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, renameSync as renameSync3, existsSync as existsSync10 } from "node:fs";
8100
9040
  import { randomBytes } from "node:crypto";
8101
9041
  import { join as join9 } from "node:path";
8102
9042
  function entriesDir() {
@@ -8106,9 +9046,9 @@ function entriesDir() {
8106
9046
  entriesDirCached = envOverride ?? cclensPath("entries");
8107
9047
  return entriesDirCached;
8108
9048
  }
8109
- function __setEntriesDirForTest(path7) {
8110
- entriesDirCached = path7;
8111
- mkdirSync7(path7, { recursive: true });
9049
+ function __setEntriesDirForTest(path9) {
9050
+ entriesDirCached = path9;
9051
+ mkdirSync7(path9, { recursive: true });
8112
9052
  }
8113
9053
  function pathFor(sessionId, localDay2) {
8114
9054
  return join9(entriesDir(), `${entryKey(sessionId, localDay2)}.json`);
@@ -8155,17 +9095,17 @@ function writeEntryPreservingEnrichment(fresh) {
8155
9095
  }
8156
9096
  function readEntry(sessionId, localDay2) {
8157
9097
  const p = pathFor(sessionId, localDay2);
8158
- if (!existsSync9(p))
9098
+ if (!existsSync10(p))
8159
9099
  return null;
8160
- const raw = readFileSync12(p, "utf8");
9100
+ const raw = readFileSync13(p, "utf8");
8161
9101
  return JSON.parse(raw);
8162
9102
  }
8163
9103
  function entryExists(sessionId, localDay2) {
8164
- return existsSync9(pathFor(sessionId, localDay2));
9104
+ return existsSync10(pathFor(sessionId, localDay2));
8165
9105
  }
8166
9106
  function listEntryKeys() {
8167
9107
  const dir = entriesDir();
8168
- if (!existsSync9(dir))
9108
+ if (!existsSync10(dir))
8169
9109
  return [];
8170
9110
  return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
8171
9111
  }
@@ -8647,8 +9587,8 @@ var init_parseUtil = __esm({
8647
9587
  init_errors();
8648
9588
  init_en();
8649
9589
  makeIssue = (params) => {
8650
- const { data, path: path7, errorMaps, issueData } = params;
8651
- const fullPath = [...path7, ...issueData.path || []];
9590
+ const { data, path: path9, errorMaps, issueData } = params;
9591
+ const fullPath = [...path9, ...issueData.path || []];
8652
9592
  const fullIssue = {
8653
9593
  ...issueData,
8654
9594
  path: fullPath
@@ -8956,11 +9896,11 @@ var init_types3 = __esm({
8956
9896
  init_parseUtil();
8957
9897
  init_util();
8958
9898
  ParseInputLazyPath = class {
8959
- constructor(parent, value, path7, key) {
9899
+ constructor(parent, value, path9, key) {
8960
9900
  this._cachedPath = [];
8961
9901
  this.parent = parent;
8962
9902
  this.data = value;
8963
- this._path = path7;
9903
+ this._path = path9;
8964
9904
  this._key = key;
8965
9905
  }
8966
9906
  get path() {
@@ -12444,7 +13384,7 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
12444
13384
  });
12445
13385
 
12446
13386
  // ../entries/dist/tmux-runner.js
12447
- import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, existsSync as existsSync10, readdirSync as readdirSync3, realpathSync as realpathSync5, readFileSync as readFileSync13, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
13387
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync8, existsSync as existsSync11, readdirSync as readdirSync3, realpathSync as realpathSync5, readFileSync as readFileSync14, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
12448
13388
  import { join as join10 } from "node:path";
12449
13389
  import { homedir as homedir5 } from "node:os";
12450
13390
  import { spawnSync as spawnSync2 } from "node:child_process";
@@ -12463,7 +13403,7 @@ function tmuxRunnerAvailable() {
12463
13403
  }
12464
13404
  function runtimeCwd() {
12465
13405
  const dir = join10(homedir5(), ".cclens", "runtime");
12466
- if (!existsSync10(dir))
13406
+ if (!existsSync11(dir))
12467
13407
  mkdirSync8(dir, { recursive: true });
12468
13408
  return realpathSync5(dir);
12469
13409
  }
@@ -12471,7 +13411,7 @@ function ensureRuntimeCwdTrusted(cwd) {
12471
13411
  const cfgPath = join10(homedir5(), ".claude.json");
12472
13412
  let cfg;
12473
13413
  try {
12474
- cfg = JSON.parse(readFileSync13(cfgPath, "utf8"));
13414
+ cfg = JSON.parse(readFileSync14(cfgPath, "utf8"));
12475
13415
  } catch {
12476
13416
  return;
12477
13417
  }
@@ -12618,10 +13558,10 @@ function snapshotAllTranscripts() {
12618
13558
  }
12619
13559
  return out;
12620
13560
  }
12621
- function readJsonlCwd(path7, maxLines = 8) {
13561
+ function readJsonlCwd(path9, maxLines = 8) {
12622
13562
  let raw;
12623
13563
  try {
12624
- raw = readFileSync13(path7, "utf8");
13564
+ raw = readFileSync14(path9, "utf8");
12625
13565
  } catch {
12626
13566
  return void 0;
12627
13567
  }
@@ -12675,10 +13615,10 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
12675
13615
  }
12676
13616
  throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
12677
13617
  }
12678
- function parseTranscript2(path7, defaultModel) {
13618
+ function parseTranscript2(path9, defaultModel) {
12679
13619
  let raw;
12680
13620
  try {
12681
- raw = readFileSync13(path7, "utf8");
13621
+ raw = readFileSync14(path9, "utf8");
12682
13622
  } catch {
12683
13623
  return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
12684
13624
  }
@@ -12772,11 +13712,11 @@ var init_tmux_runner = __esm({
12772
13712
 
12773
13713
  // ../entries/dist/llm-runner.js
12774
13714
  import { spawn as spawn3 } from "node:child_process";
12775
- import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync9, existsSync as existsSync11 } from "node:fs";
13715
+ import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync9, existsSync as existsSync12 } from "node:fs";
12776
13716
  import { join as join11 } from "node:path";
12777
13717
  import { randomUUID } from "node:crypto";
12778
13718
  function ensureRunsDir() {
12779
- if (!existsSync11(RUNS_DIR)) {
13719
+ if (!existsSync12(RUNS_DIR)) {
12780
13720
  try {
12781
13721
  mkdirSync9(RUNS_DIR, { recursive: true });
12782
13722
  } catch {
@@ -12807,15 +13747,15 @@ function newRunId(kind) {
12807
13747
  function tracePath(runId) {
12808
13748
  return join11(RUNS_DIR, `${runId}.jsonl`);
12809
13749
  }
12810
- function safeAppend(path7, line) {
13750
+ function safeAppend(path9, line) {
12811
13751
  try {
12812
- appendFileSync3(path7, line);
13752
+ appendFileSync3(path9, line);
12813
13753
  } catch {
12814
13754
  }
12815
13755
  }
12816
- function safeWrite(path7, line) {
13756
+ function safeWrite(path9, line) {
12817
13757
  try {
12818
- writeFileSync9(path7, line);
13758
+ writeFileSync9(path9, line);
12819
13759
  } catch {
12820
13760
  }
12821
13761
  }
@@ -13221,7 +14161,7 @@ var init_enrich2 = __esm({
13221
14161
  });
13222
14162
 
13223
14163
  // ../entries/dist/budget.js
13224
- import { appendFileSync as appendFileSync4, readFileSync as readFileSync14, existsSync as existsSync12, mkdirSync as mkdirSync10 } from "node:fs";
14164
+ import { appendFileSync as appendFileSync4, readFileSync as readFileSync15, existsSync as existsSync13, mkdirSync as mkdirSync10 } from "node:fs";
13225
14165
  import { dirname as dirname9 } from "node:path";
13226
14166
  function spendPath() {
13227
14167
  if (spendPathCached)
@@ -13229,8 +14169,8 @@ function spendPath() {
13229
14169
  spendPathCached = cclensPath("llm-spend.jsonl");
13230
14170
  return spendPathCached;
13231
14171
  }
13232
- function __setSpendPathForTest(path7) {
13233
- spendPathCached = path7;
14172
+ function __setSpendPathForTest(path9) {
14173
+ spendPathCached = path9;
13234
14174
  }
13235
14175
  function appendSpend(record) {
13236
14176
  const p = spendPath();
@@ -13239,12 +14179,12 @@ function appendSpend(record) {
13239
14179
  }
13240
14180
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
13241
14181
  const p = spendPath();
13242
- if (!existsSync12(p))
14182
+ if (!existsSync13(p))
13243
14183
  return 0;
13244
14184
  const year = now.getUTCFullYear();
13245
14185
  const month2 = now.getUTCMonth();
13246
14186
  let total = 0;
13247
- const raw = readFileSync14(p, "utf8");
14187
+ const raw = readFileSync15(p, "utf8");
13248
14188
  for (const line of raw.split("\n")) {
13249
14189
  if (!line)
13250
14190
  continue;
@@ -13273,15 +14213,15 @@ var init_budget = __esm({
13273
14213
  });
13274
14214
 
13275
14215
  // ../entries/dist/pipeline-lock.js
13276
- import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, existsSync as existsSync13, readFileSync as readFileSync15, statSync as statSync3 } from "node:fs";
14216
+ import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, existsSync as existsSync14, readFileSync as readFileSync16, statSync as statSync3 } from "node:fs";
13277
14217
  function lockPath() {
13278
14218
  if (lockPathCached)
13279
14219
  return lockPathCached;
13280
14220
  lockPathCached = cclensPath("llm-interactive.lock");
13281
14221
  return lockPathCached;
13282
14222
  }
13283
- function __setInteractiveLockPathForTest(path7) {
13284
- lockPathCached = path7;
14223
+ function __setInteractiveLockPathForTest(path9) {
14224
+ lockPathCached = path9;
13285
14225
  }
13286
14226
  function touchLock() {
13287
14227
  writeFileSync10(lockPath(), String(process.pid), "utf8");
@@ -13318,13 +14258,13 @@ function pidAlive(pid) {
13318
14258
  }
13319
14259
  function interactiveLockFresh(nowMs) {
13320
14260
  const p = lockPath();
13321
- if (!existsSync13(p))
14261
+ if (!existsSync14(p))
13322
14262
  return false;
13323
14263
  try {
13324
14264
  const mtime = statSync3(p).mtimeMs;
13325
14265
  if (nowMs - mtime > STALE_MS)
13326
14266
  return false;
13327
- const pid = Number(readFileSync15(p, "utf8").trim());
14267
+ const pid = Number(readFileSync16(p, "utf8").trim());
13328
14268
  if (!Number.isFinite(pid) || pid <= 0)
13329
14269
  return false;
13330
14270
  if (!pidAlive(pid))
@@ -13430,7 +14370,7 @@ var init_queue = __esm({
13430
14370
  });
13431
14371
 
13432
14372
  // ../entries/dist/settings.js
13433
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync11, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync14 } from "node:fs";
14373
+ import { readFileSync as readFileSync17, writeFileSync as writeFileSync11, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync15 } from "node:fs";
13434
14374
  import { dirname as dirname10 } from "node:path";
13435
14375
  function settingsPath() {
13436
14376
  if (settingsPathCached)
@@ -13438,8 +14378,8 @@ function settingsPath() {
13438
14378
  settingsPathCached = cclensPath("settings.json");
13439
14379
  return settingsPathCached;
13440
14380
  }
13441
- function __setSettingsPathForTest(path7) {
13442
- settingsPathCached = path7;
14381
+ function __setSettingsPathForTest(path9) {
14382
+ settingsPathCached = path9;
13443
14383
  }
13444
14384
  function toDisk(s) {
13445
14385
  return {
@@ -13466,10 +14406,10 @@ function fromDisk(d) {
13466
14406
  }
13467
14407
  function readSettings() {
13468
14408
  const p = settingsPath();
13469
- if (!existsSync14(p))
14409
+ if (!existsSync15(p))
13470
14410
  return DEFAULT_SETTINGS;
13471
14411
  try {
13472
- const raw = readFileSync16(p, "utf8");
14412
+ const raw = readFileSync17(p, "utf8");
13473
14413
  return fromDisk(JSON.parse(raw));
13474
14414
  } catch {
13475
14415
  return DEFAULT_SETTINGS;
@@ -13676,7 +14616,7 @@ function rollupOutcomeDay(entries2) {
13676
14616
  return "exploratory";
13677
14617
  return "trivial";
13678
14618
  }
13679
- function truncate5(s, max) {
14619
+ function truncate6(s, max) {
13680
14620
  if (s.length <= max)
13681
14621
  return s;
13682
14622
  return s.slice(0, max - 1).trimEnd() + "\u2026";
@@ -13732,7 +14672,7 @@ function computeDaySignals(entries2) {
13732
14672
  type,
13733
14673
  count: v.count,
13734
14674
  sample_description: v.sample_description,
13735
- sample_prompt_preview: truncate5(v.sample_prompt_preview, 200)
14675
+ sample_prompt_preview: truncate6(v.sample_prompt_preview, 200)
13736
14676
  }));
13737
14677
  const frameCounts = /* @__PURE__ */ new Map();
13738
14678
  for (const s of signalsList) {
@@ -13751,7 +14691,7 @@ function computeDaySignals(entries2) {
13751
14691
  if ((e.first_user ?? "").length > 0)
13752
14692
  verbosity_distribution[s.verbosity] += 1;
13753
14693
  for (const ref of s.external_refs) {
13754
- external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate5(ref.preview, 200) });
14694
+ external_refs.push({ session_id: e.session_id, kind: ref.kind, preview: truncate6(ref.preview, 200) });
13755
14695
  }
13756
14696
  const ints = e.numbers.interrupts ?? 0;
13757
14697
  interrupts += ints;
@@ -14624,7 +15564,7 @@ function computeInteractionModes(entries2) {
14624
15564
  date: entry.local_day,
14625
15565
  project_display: prettyProject3(entry.project),
14626
15566
  type: sa.type,
14627
- prompt_preview: truncate6(sa.prompt_preview, 200)
15567
+ prompt_preview: truncate7(sa.prompt_preview, 200)
14628
15568
  });
14629
15569
  }
14630
15570
  const skillExamples = [];
@@ -14641,7 +15581,7 @@ function computeInteractionModes(entries2) {
14641
15581
  skillExamples.push({
14642
15582
  date: e.local_day,
14643
15583
  skill,
14644
- first_user_preview: truncate6(e.first_user, 200)
15584
+ first_user_preview: truncate7(e.first_user, 200)
14645
15585
  });
14646
15586
  }
14647
15587
  }
@@ -14658,7 +15598,7 @@ function computeInteractionModes(entries2) {
14658
15598
  project_display: prettyProject3(longestTurnEntry.project),
14659
15599
  active_min: longestTurnEntry.numbers.active_min,
14660
15600
  top_tools: longestTurnEntry.top_tools.slice(0, 5),
14661
- first_user_preview: truncate6(longestTurnEntry.first_user, 200)
15601
+ first_user_preview: truncate7(longestTurnEntry.first_user, 200)
14662
15602
  } : null;
14663
15603
  const tools_per_turn = turn_count > 0 ? tools_total / turn_count : 0;
14664
15604
  const label = tools_per_turn < 5 ? "rapid" : tools_per_turn < 15 ? "mixed" : "batch";
@@ -14689,7 +15629,7 @@ function computeInteractionModes(entries2) {
14689
15629
  }
14690
15630
  };
14691
15631
  }
14692
- function truncate6(s, max) {
15632
+ function truncate7(s, max) {
14693
15633
  if (s.length <= max)
14694
15634
  return s;
14695
15635
  return s.slice(0, max - 1).trimEnd() + "\u2026";
@@ -14736,7 +15676,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
14736
15676
  evidence_subagent = {
14737
15677
  type: sa.type,
14738
15678
  description: sa.description,
14739
- prompt_preview: truncate6(sa.prompt_preview, 200)
15679
+ prompt_preview: truncate7(sa.prompt_preview, 200)
14740
15680
  };
14741
15681
  }
14742
15682
  const project_display = repEntry ? prettyProject3(repEntry.project) : dd.projects[0]?.display_name ?? "";
@@ -14747,7 +15687,7 @@ function computeWorkingShapes(dayDigests, entriesByDay = /* @__PURE__ */ new Map
14747
15687
  outcome: dayOutcome.get(dd.key) ?? null,
14748
15688
  helpfulness: dayHelp.get(dd.key) ?? null,
14749
15689
  evidence_subagent,
14750
- evidence_first_user: repEntry?.first_user ? truncate6(repEntry.first_user, 200) : null,
15690
+ evidence_first_user: repEntry?.first_user ? truncate7(repEntry.first_user, 200) : null,
14751
15691
  day_signature: dd.day_signature ?? null
14752
15692
  };
14753
15693
  });
@@ -14822,7 +15762,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
14822
15762
  date: day2,
14823
15763
  session_id: ref.session_id,
14824
15764
  ref_kind: ref.kind,
14825
- preview: truncate6(ref.preview, 200)
15765
+ preview: truncate7(ref.preview, 200)
14826
15766
  });
14827
15767
  }
14828
15768
  total_interrupts += signals.comm_style.steering.interrupts;
@@ -14894,7 +15834,7 @@ function computeInteractionGrammar(dayDigests, entriesByDay = /* @__PURE__ */ ne
14894
15834
  count: v.count,
14895
15835
  days: [...v.days].sort(),
14896
15836
  sample_description: v.sample_description,
14897
- sample_prompt_preview: truncate6(v.sample_prompt_preview, 200)
15837
+ sample_prompt_preview: truncate7(v.sample_prompt_preview, 200)
14898
15838
  })),
14899
15839
  threads,
14900
15840
  communication_style: {
@@ -15542,7 +16482,7 @@ function activeMs(timestamps) {
15542
16482
  let active = 0;
15543
16483
  for (let i = 1; i < ts.length; i++) {
15544
16484
  const dt = ts[i] - ts[i - 1];
15545
- if (dt < IDLE_GAP_MS5)
16485
+ if (dt < IDLE_GAP_MS6)
15546
16486
  active += dt;
15547
16487
  }
15548
16488
  return active;
@@ -15713,7 +16653,7 @@ function buildSessionSlice(entry, events, daySignature) {
15713
16653
  let intEnd = sortedTs[0];
15714
16654
  for (let i = 1; i < sortedTs.length; i++) {
15715
16655
  const dt = sortedTs[i] - intEnd;
15716
- if (dt >= IDLE_GAP_MS5) {
16656
+ if (dt >= IDLE_GAP_MS6) {
15717
16657
  intervals.push({
15718
16658
  start_min: fmtMin(intStart - sliceStartMs),
15719
16659
  end_min: fmtMin(intEnd - sliceStartMs)
@@ -16110,14 +17050,14 @@ async function generateTopSession(slice, opts = {}) {
16110
17050
  void lastModel;
16111
17051
  }
16112
17052
  }
16113
- var IDLE_GAP_MS5, LONG_AUTONOMOUS_MIN, N_USER, N_FIRST_AGENT, N_LAST_AGENT, N_USER_TURN1, N_SUBAGENT, SHELL_NOISE2, INTERRUPT_RE3, PR_TITLE_RE2, PinResponseSchema, TopSessionResponseSchema, SYSTEM_PROMPT5, TOP_SESSION_SYSTEM_PROMPT, DEFAULT_MODEL5, defaultCallLLMTopSession, validateTopSession;
17053
+ var IDLE_GAP_MS6, LONG_AUTONOMOUS_MIN, N_USER, N_FIRST_AGENT, N_LAST_AGENT, N_USER_TURN1, N_SUBAGENT, SHELL_NOISE2, INTERRUPT_RE3, PR_TITLE_RE2, PinResponseSchema, TopSessionResponseSchema, SYSTEM_PROMPT5, TOP_SESSION_SYSTEM_PROMPT, DEFAULT_MODEL5, defaultCallLLMTopSession, validateTopSession;
16114
17054
  var init_top_sessions = __esm({
16115
17055
  "../entries/dist/top-sessions.js"() {
16116
17056
  "use strict";
16117
17057
  init_zod();
16118
17058
  init_signals();
16119
17059
  init_llm_runner();
16120
- IDLE_GAP_MS5 = 3 * 60 * 1e3;
17060
+ IDLE_GAP_MS6 = 3 * 60 * 1e3;
16121
17061
  LONG_AUTONOMOUS_MIN = 20;
16122
17062
  N_USER = 150;
16123
17063
  N_FIRST_AGENT = 150;
@@ -16659,7 +17599,7 @@ var init_digest_month_pipeline = __esm({
16659
17599
  });
16660
17600
 
16661
17601
  // ../entries/dist/credentials.js
16662
- import { writeFileSync as writeFileSync12, readFileSync as readFileSync17, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync15, unlinkSync as unlinkSync5 } from "node:fs";
17602
+ import { writeFileSync as writeFileSync12, readFileSync as readFileSync18, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync16, unlinkSync as unlinkSync5 } from "node:fs";
16663
17603
  import { dirname as dirname11 } from "node:path";
16664
17604
  async function fetchZaiUsage(candidate) {
16665
17605
  const key = candidate.trim();
@@ -16730,10 +17670,10 @@ function credentialsPath() {
16730
17670
  }
16731
17671
  function readCredentials() {
16732
17672
  const p = credentialsPath();
16733
- if (!existsSync15(p))
17673
+ if (!existsSync16(p))
16734
17674
  return {};
16735
17675
  try {
16736
- const raw = readFileSync17(p, "utf8");
17676
+ const raw = readFileSync18(p, "utf8");
16737
17677
  return JSON.parse(raw);
16738
17678
  } catch {
16739
17679
  return {};
@@ -17363,7 +18303,7 @@ var menubar_exports = {};
17363
18303
  __export(menubar_exports, {
17364
18304
  menubar: () => menubar
17365
18305
  });
17366
- import { existsSync as existsSync16, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync13, realpathSync as realpathSync6 } from "node:fs";
18306
+ import { existsSync as existsSync17, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync13, realpathSync as realpathSync6 } from "node:fs";
17367
18307
  import { homedir as homedir6 } from "node:os";
17368
18308
  import { join as join12, dirname as dirname12 } from "node:path";
17369
18309
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -17405,8 +18345,8 @@ async function isRunning() {
17405
18345
  return false;
17406
18346
  }
17407
18347
  }
17408
- async function launchApp(path7) {
17409
- await execFileAsync2("open", ["-a", path7]);
18348
+ async function launchApp(path9) {
18349
+ await execFileAsync2("open", ["-a", path9]);
17410
18350
  }
17411
18351
  async function quitApp() {
17412
18352
  await execFileAsync2("osascript", ["-e", `tell application "${BUNDLE_EXEC}" to quit`]).catch(
@@ -17427,7 +18367,7 @@ async function installMenubar(opts) {
17427
18367
  return;
17428
18368
  }
17429
18369
  const src = bundledAppPath();
17430
- if (!existsSync16(src)) {
18370
+ if (!existsSync17(src)) {
17431
18371
  console.error(
17432
18372
  `Bundled widget not found at ${src}.
17433
18373
  This install was probably built without the menubar artifact. Run \`node apps/menubar/build-app.sh && cp -R apps/menubar/dist/FleetlensMenubar.app packages/cli/menubar/\` and rebuild.`
@@ -17469,7 +18409,7 @@ async function uninstallMenubar() {
17469
18409
  await new Promise((r) => setTimeout(r, 300));
17470
18410
  }
17471
18411
  const dest = installedAppPath();
17472
- if (existsSync16(dest)) {
18412
+ if (existsSync17(dest)) {
17473
18413
  rmSync2(dest, { recursive: true, force: true });
17474
18414
  console.log(`Removed ${dest}`);
17475
18415
  } else {
@@ -17483,7 +18423,7 @@ async function openMenubar() {
17483
18423
  return;
17484
18424
  }
17485
18425
  const dest = installedAppPath();
17486
- if (!existsSync16(dest)) {
18426
+ if (!existsSync17(dest)) {
17487
18427
  console.log("Widget not installed yet. Run `fleetlens menubar install` first.");
17488
18428
  return;
17489
18429
  }
@@ -17500,9 +18440,9 @@ async function statusMenubar() {
17500
18440
  return;
17501
18441
  }
17502
18442
  const dest = installedAppPath();
17503
- const installed = existsSync16(dest);
18443
+ const installed = existsSync17(dest);
17504
18444
  const running = await isRunning();
17505
- const bundled = existsSync16(bundledAppPath());
18445
+ const bundled = existsSync17(bundledAppPath());
17506
18446
  console.log(`Menu bar widget: ${installed ? "installed" : "not installed"}${installed ? ` (${dest})` : ""}`);
17507
18447
  console.log(`Running: ${running ? "yes" : "no"}`);
17508
18448
  console.log(`Bundled in CLI: ${bundled ? "yes" : "no \u2014 this build ships without the widget"}`);
@@ -17591,7 +18531,7 @@ var init_config = __esm({
17591
18531
  });
17592
18532
 
17593
18533
  // src/perception/build-entries.ts
17594
- import { statSync as statSync4, readFileSync as readFileSync18 } from "node:fs";
18534
+ import { statSync as statSync4, readFileSync as readFileSync19 } from "node:fs";
17595
18535
  import { basename as basename2, dirname as dirname13 } from "node:path";
17596
18536
  function decodeProjectDirName(projectDir) {
17597
18537
  if (projectDir.startsWith("-")) {
@@ -17601,7 +18541,7 @@ function decodeProjectDirName(projectDir) {
17601
18541
  }
17602
18542
  function buildEntriesForFile(filePath) {
17603
18543
  const stat = statSync4(filePath);
17604
- const raw = readFileSync18(filePath, "utf8");
18544
+ const raw = readFileSync19(filePath, "utf8");
17605
18545
  const rawLines = raw.split("\n").filter(Boolean).map((l) => {
17606
18546
  try {
17607
18547
  return JSON.parse(l);
@@ -17866,7 +18806,7 @@ function buildIngestPayload(inputs) {
17866
18806
  return {
17867
18807
  ingestId: randomUUID2(),
17868
18808
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
17869
- cliVersion: "0.16.0",
18809
+ cliVersion: "0.16.1",
17870
18810
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
17871
18811
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
17872
18812
  ...richRollup ? { richRollup } : {},
@@ -17907,7 +18847,7 @@ var init_push = __esm({
17907
18847
  });
17908
18848
 
17909
18849
  // src/team/git-remote.ts
17910
- import { existsSync as existsSync17, readFileSync as readFileSync19, statSync as statSync5 } from "node:fs";
18850
+ import { existsSync as existsSync18, readFileSync as readFileSync20, statSync as statSync5 } from "node:fs";
17911
18851
  import { dirname as dirname14, isAbsolute as isAbsolute2, join as join13, resolve as resolve2 } from "node:path";
17912
18852
  function parseGithubRemote(url) {
17913
18853
  const m = url.trim().match(GITHUB_URL_RE);
@@ -17932,12 +18872,12 @@ function gitConfigPathFor(dir) {
17932
18872
  const st = statSync5(dotGit, { throwIfNoEntry: false });
17933
18873
  if (!st) return null;
17934
18874
  if (st.isDirectory()) return join13(dotGit, "config");
17935
- const m = readFileSync19(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
18875
+ const m = readFileSync20(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
17936
18876
  if (!m) return null;
17937
18877
  const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
17938
18878
  const commondirFile = join13(gd, "commondir");
17939
- if (existsSync17(commondirFile)) {
17940
- const common = readFileSync19(commondirFile, "utf8").trim();
18879
+ if (existsSync18(commondirFile)) {
18880
+ const common = readFileSync20(commondirFile, "utf8").trim();
17941
18881
  return join13(isAbsolute2(common) ? common : resolve2(gd, common), "config");
17942
18882
  }
17943
18883
  return join13(gd, "config");
@@ -17952,8 +18892,8 @@ function createRepoResolver() {
17952
18892
  try {
17953
18893
  for (let d = dir; ; d = dirname14(d)) {
17954
18894
  const config = gitConfigPathFor(d);
17955
- if (config && existsSync17(config)) {
17956
- const url = originUrl2(readFileSync19(config, "utf8"));
18895
+ if (config && existsSync18(config)) {
18896
+ const url = originUrl2(readFileSync20(config, "utf8"));
17957
18897
  repo = url ? parseGithubRemote(url) : null;
17958
18898
  break;
17959
18899
  }
@@ -17975,7 +18915,7 @@ var init_git_remote = __esm({
17975
18915
  });
17976
18916
 
17977
18917
  // src/team/queue.ts
17978
- import { readFileSync as readFileSync20, writeFileSync as writeFileSync14, appendFileSync as appendFileSync5, statSync as statSync6, mkdirSync as mkdirSync14 } from "node:fs";
18918
+ import { readFileSync as readFileSync21, writeFileSync as writeFileSync14, appendFileSync as appendFileSync5, statSync as statSync6, mkdirSync as mkdirSync14 } from "node:fs";
17979
18919
  import { dirname as dirname15 } from "node:path";
17980
18920
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
17981
18921
  mkdirSync14(dirname15(queuePath), { recursive: true });
@@ -17992,7 +18932,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
17992
18932
  function dequeuePayloads(queuePath = QUEUE_PATH) {
17993
18933
  let lines;
17994
18934
  try {
17995
- lines = readFileSync20(queuePath, "utf8").trim().split("\n").filter(Boolean);
18935
+ lines = readFileSync21(queuePath, "utf8").trim().split("\n").filter(Boolean);
17996
18936
  } catch {
17997
18937
  return [];
17998
18938
  }
@@ -18013,7 +18953,7 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
18013
18953
  function pruneOldest(queuePath) {
18014
18954
  let lines;
18015
18955
  try {
18016
- lines = readFileSync20(queuePath, "utf8").trim().split("\n").filter(Boolean);
18956
+ lines = readFileSync21(queuePath, "utf8").trim().split("\n").filter(Boolean);
18017
18957
  } catch {
18018
18958
  return;
18019
18959
  }
@@ -18032,7 +18972,7 @@ var init_queue2 = __esm({
18032
18972
  });
18033
18973
 
18034
18974
  // src/usage/profile.ts
18035
- import { existsSync as existsSync18, mkdirSync as mkdirSync15, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
18975
+ import { existsSync as existsSync19, mkdirSync as mkdirSync15, readFileSync as readFileSync22, writeFileSync as writeFileSync15 } from "node:fs";
18036
18976
  import { dirname as dirname16 } from "node:path";
18037
18977
  function mapRateLimitTier(rateLimitTier) {
18038
18978
  switch (rateLimitTier) {
@@ -18073,9 +19013,9 @@ async function fetchProfile(nowMs = Date.now()) {
18073
19013
  };
18074
19014
  }
18075
19015
  function readCachedProfile(cachePath) {
18076
- if (!existsSync18(cachePath)) return null;
19016
+ if (!existsSync19(cachePath)) return null;
18077
19017
  try {
18078
- const raw = JSON.parse(readFileSync21(cachePath, "utf8"));
19018
+ const raw = JSON.parse(readFileSync22(cachePath, "utf8"));
18079
19019
  if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
18080
19020
  return raw;
18081
19021
  } catch {
@@ -18264,11 +19204,11 @@ var init_backfill = __esm({
18264
19204
  });
18265
19205
 
18266
19206
  // src/team/sync-log.ts
18267
- import { readFileSync as readFileSync22 } from "node:fs";
19207
+ import { readFileSync as readFileSync23 } from "node:fs";
18268
19208
  function readPendingSyncLog(watermark) {
18269
19209
  let raw;
18270
19210
  try {
18271
- raw = readFileSync22(cclensPath("daemon.log"), "utf8");
19211
+ raw = readFileSync23(cclensPath("daemon.log"), "utf8");
18272
19212
  } catch {
18273
19213
  return { lines: [] };
18274
19214
  }
@@ -18332,7 +19272,7 @@ __export(file_probe_exports, {
18332
19272
  probeArtifactSignals: () => probeArtifactSignals
18333
19273
  });
18334
19274
  import { createHash } from "node:crypto";
18335
- import { existsSync as existsSync19, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
19275
+ import { existsSync as existsSync20, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
18336
19276
  import { homedir as homedir7 } from "node:os";
18337
19277
  import { join as join15, relative, resolve as resolve3, sep } from "node:path";
18338
19278
  import { execFileSync as execFileSync3 } from "node:child_process";
@@ -18342,15 +19282,15 @@ function pathHash(relPath) {
18342
19282
  function defaultScanRoots(extraRoots = []) {
18343
19283
  const roots = [];
18344
19284
  const home = join15(homedir7(), ".claude");
18345
- if (existsSync19(home)) roots.push({ root: home, label: "user" });
19285
+ if (existsSync20(home)) roots.push({ root: home, label: "user" });
18346
19286
  for (const e of extraRoots) {
18347
19287
  const r = resolve3(e, ".claude");
18348
- if (existsSync19(r) && r !== home) roots.push({ root: r, label: "project" });
19288
+ if (existsSync20(r) && r !== home) roots.push({ root: r, label: "project" });
18349
19289
  }
18350
19290
  return roots;
18351
19291
  }
18352
19292
  function listMarkdownFiles(dir) {
18353
- if (!existsSync19(dir)) return [];
19293
+ if (!existsSync20(dir)) return [];
18354
19294
  const out = [];
18355
19295
  let entries2;
18356
19296
  try {
@@ -18420,7 +19360,7 @@ function scanAuthored(roots, subdir, day2) {
18420
19360
  const out = [];
18421
19361
  for (const r of roots) {
18422
19362
  const dir = join15(r.root, subdir);
18423
- if (!existsSync19(dir)) continue;
19363
+ if (!existsSync20(dir)) continue;
18424
19364
  for (const f of listMarkdownFiles(dir)) {
18425
19365
  const firstSeen = firstSeenDateOf(f);
18426
19366
  if (firstSeen !== day2) continue;
@@ -18434,7 +19374,7 @@ function scanEdited(roots, day2) {
18434
19374
  const out = [];
18435
19375
  for (const r of roots) {
18436
19376
  const dir = join15(r.root, "skills");
18437
- if (!existsSync19(dir)) continue;
19377
+ if (!existsSync20(dir)) continue;
18438
19378
  for (const f of listMarkdownFiles(dir)) {
18439
19379
  const firstSeen = firstSeenDateOf(f);
18440
19380
  if (firstSeen === day2) continue;
@@ -18457,10 +19397,10 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
18457
19397
  const candidates = [];
18458
19398
  for (const e of extraRoots) {
18459
19399
  const f = resolve3(e, "CLAUDE.md");
18460
- if (existsSync19(f)) candidates.push(f);
19400
+ if (existsSync20(f)) candidates.push(f);
18461
19401
  }
18462
19402
  const homeClaudeMd = join15(homedir7(), "CLAUDE.md");
18463
- if (existsSync19(homeClaudeMd)) candidates.push(homeClaudeMd);
19403
+ if (existsSync20(homeClaudeMd)) candidates.push(homeClaudeMd);
18464
19404
  for (const file of candidates) {
18465
19405
  try {
18466
19406
  const out = execFileSync3(
@@ -19350,11 +20290,11 @@ var logs_exports = {};
19350
20290
  __export(logs_exports, {
19351
20291
  teamLogs: () => teamLogs
19352
20292
  });
19353
- import { readFileSync as readFileSync23 } from "node:fs";
20293
+ import { readFileSync as readFileSync24 } from "node:fs";
19354
20294
  async function teamLogs() {
19355
20295
  const logPath = cclensPath("daemon.log");
19356
20296
  try {
19357
- const lines = readFileSync23(logPath, "utf8").trim().split("\n");
20297
+ const lines = readFileSync24(logPath, "utf8").trim().split("\n");
19358
20298
  const teamLines = lines.filter((l) => l.includes("[sync] ") || l.includes("team "));
19359
20299
  if (teamLines.length === 0) {
19360
20300
  console.log("No team-related log entries found.");
@@ -19482,7 +20422,7 @@ __export(runs_exports, {
19482
20422
  runs: () => runs
19483
20423
  });
19484
20424
  import { execSync as execSync2 } from "node:child_process";
19485
- import { existsSync as existsSync20, readFileSync as readFileSync24, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
20425
+ import { existsSync as existsSync21, readFileSync as readFileSync25, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
19486
20426
  import { join as join16 } from "node:path";
19487
20427
  async function runs(args2) {
19488
20428
  const json = args2.includes("--json");
@@ -19567,8 +20507,8 @@ function listActiveRuns() {
19567
20507
  return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
19568
20508
  }
19569
20509
  function readSpend(sinceMs) {
19570
- if (!existsSync20(SPEND_PATH)) return [];
19571
- const lines = readFileSync24(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
20510
+ if (!existsSync21(SPEND_PATH)) return [];
20511
+ const lines = readFileSync25(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
19572
20512
  const out = [];
19573
20513
  for (const line of lines) {
19574
20514
  try {
@@ -19689,23 +20629,23 @@ function ageLabel(ms) {
19689
20629
  return `${Math.floor(ms / 864e5)}d`;
19690
20630
  }
19691
20631
  function listTraceFiles() {
19692
- if (!existsSync20(RUNS_DIR2)) return [];
20632
+ if (!existsSync21(RUNS_DIR2)) return [];
19693
20633
  const entries2 = readdirSync6(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
19694
20634
  return entries2.map((f) => {
19695
- const path7 = join16(RUNS_DIR2, f);
19696
- const st = statSync8(path7);
19697
- return { runId: f.replace(/\.jsonl$/, ""), path: path7, mtimeMs: st.mtimeMs };
20635
+ const path9 = join16(RUNS_DIR2, f);
20636
+ const st = statSync8(path9);
20637
+ return { runId: f.replace(/\.jsonl$/, ""), path: path9, mtimeMs: st.mtimeMs };
19698
20638
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
19699
20639
  }
19700
20640
  function resolveRunId(arg) {
19701
- if (!existsSync20(RUNS_DIR2)) return null;
20641
+ if (!existsSync21(RUNS_DIR2)) return null;
19702
20642
  if (arg === "latest") {
19703
20643
  const all2 = listTraceFiles();
19704
20644
  if (all2.length === 0) return null;
19705
20645
  return { runId: all2[0].runId, path: all2[0].path };
19706
20646
  }
19707
20647
  const exact = join16(RUNS_DIR2, `${arg}.jsonl`);
19708
- if (existsSync20(exact)) return { runId: arg, path: exact };
20648
+ if (existsSync21(exact)) return { runId: arg, path: exact };
19709
20649
  const all = listTraceFiles();
19710
20650
  const matches = all.filter((r) => r.runId.includes(arg));
19711
20651
  if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
@@ -19716,8 +20656,8 @@ function resolveRunId(arg) {
19716
20656
  }
19717
20657
  return null;
19718
20658
  }
19719
- function readTrace(path7) {
19720
- return readFileSync24(path7, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
20659
+ function readTrace(path9) {
20660
+ return readFileSync25(path9, "utf-8").split("\n").filter((l) => l.trim()).map((l) => {
19721
20661
  try {
19722
20662
  return JSON.parse(l);
19723
20663
  } catch {
@@ -19729,7 +20669,7 @@ async function inspect(arg, follow, json) {
19729
20669
  const r = resolveRunId(arg);
19730
20670
  if (!r) {
19731
20671
  console.error(`run not found: ${arg}`);
19732
- if (existsSync20(RUNS_DIR2)) {
20672
+ if (existsSync21(RUNS_DIR2)) {
19733
20673
  const all = listTraceFiles().slice(0, 5);
19734
20674
  if (all.length > 0) {
19735
20675
  console.error(`
@@ -19909,7 +20849,7 @@ async function main() {
19909
20849
  case "version":
19910
20850
  case "--version":
19911
20851
  case "-v":
19912
- console.log(`fleetlens ${"0.16.0"}`);
20852
+ console.log(`fleetlens ${"0.16.1"}`);
19913
20853
  break;
19914
20854
  case "help":
19915
20855
  case "--help":
@@ -19936,7 +20876,7 @@ Advanced:
19936
20876
  start --no-daemon Start only the web server (no daemon)
19937
20877
  daemon <start|stop|status|logs> Manage the usage daemon by itself
19938
20878
  autostart <install|uninstall|status> Run the usage daemon at login (macOS launchd)
19939
- menubar <install|uninstall|open|status> Native macOS menu bar widget (Claude/Codex/Z.ai usage)
20879
+ menubar <install|uninstall|open|status> Native macOS menu bar widget (Claude/Codex/Z.ai plan usage; Grok sessions on the dashboard)
19940
20880
 
19941
20881
  Team:
19942
20882
  team join <url> <token> Pair with a team server (browser setup)