fleetlens 0.15.3 → 0.15.4

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 (155) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/app-path-routes-manifest.json +2 -0
  3. package/app/apps/web/.next/build-manifest.json +3 -3
  4. package/app/apps/web/.next/prerender-manifest.json +3 -3
  5. package/app/apps/web/.next/routes-manifest.json +12 -0
  6. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
  14. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  18. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/menubar/route/app-paths-manifest.json +3 -0
  23. package/app/apps/web/.next/server/app/api/menubar/route/build-manifest.json +9 -0
  24. package/app/apps/web/.next/server/app/api/menubar/route/server-reference-manifest.json +4 -0
  25. package/app/apps/web/.next/server/app/api/menubar/route.js +6 -0
  26. package/app/apps/web/.next/server/app/api/menubar/route.js.map +5 -0
  27. package/app/apps/web/.next/server/app/api/menubar/route.js.nft.json +1 -0
  28. package/app/apps/web/.next/server/app/api/menubar/route_client-reference-manifest.js +3 -0
  29. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js +1 -1
  30. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
  31. package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  33. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  34. package/app/apps/web/.next/server/app/api/settings/credentials/route/app-paths-manifest.json +3 -0
  35. package/app/apps/web/.next/server/app/api/settings/credentials/route/build-manifest.json +9 -0
  36. package/app/apps/web/.next/server/app/api/settings/credentials/route/server-reference-manifest.json +4 -0
  37. package/app/apps/web/.next/server/app/api/settings/credentials/route.js +10 -0
  38. package/app/apps/web/.next/server/app/api/settings/credentials/route.js.map +5 -0
  39. package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -0
  40. package/app/apps/web/.next/server/app/api/settings/credentials/route_client-reference-manifest.js +3 -0
  41. package/app/apps/web/.next/server/app/api/settings/route.js +4 -4
  42. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/changelog/page.js +1 -1
  44. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  45. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  46. package/app/apps/web/.next/server/app/day/[date]/page.js +1 -1
  47. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  48. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  49. package/app/apps/web/.next/server/app/day/page.js +1 -1
  50. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  51. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  52. package/app/apps/web/.next/server/app/digest/[date]/page.js +1 -1
  53. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  54. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  55. package/app/apps/web/.next/server/app/digest/page.js +1 -1
  56. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  58. package/app/apps/web/.next/server/app/insights/[key]/page.js +1 -1
  59. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  60. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  61. package/app/apps/web/.next/server/app/insights/page.js +1 -1
  62. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  63. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  64. package/app/apps/web/.next/server/app/page.js +1 -1
  65. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  66. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
  68. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  69. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  70. package/app/apps/web/.next/server/app/print/[key]/page.js +1 -1
  71. package/app/apps/web/.next/server/app/print/[key]/page.js.nft.json +1 -1
  72. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  73. package/app/apps/web/.next/server/app/projects/[slug]/page.js +1 -1
  74. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  75. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  76. package/app/apps/web/.next/server/app/projects/page.js +1 -1
  77. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  78. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  79. package/app/apps/web/.next/server/app/runs/page.js +1 -1
  80. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  81. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  82. package/app/apps/web/.next/server/app/sessions/[id]/page.js +1 -1
  83. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  84. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  85. package/app/apps/web/.next/server/app/sessions/page.js +1 -1
  86. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  87. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  88. package/app/apps/web/.next/server/app/settings/page.js +2 -2
  89. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  90. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  91. package/app/apps/web/.next/server/app/team/onboarding/page.js +1 -1
  92. package/app/apps/web/.next/server/app/team/onboarding/page.js.nft.json +1 -1
  93. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  94. package/app/apps/web/.next/server/app/team/page.js +1 -1
  95. package/app/apps/web/.next/server/app/team/page.js.nft.json +1 -1
  96. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  97. package/app/apps/web/.next/server/app/usage/page.js +1 -1
  98. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  99. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  100. package/app/apps/web/.next/server/app-paths-manifest.json +2 -0
  101. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_settings_credentials_route_actions_04an_i2.js +3 -0
  102. package/app/apps/web/.next/server/chunks/[root-of-the-server]__05z0pcw._.js +3 -0
  103. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_nle98._.js +3 -0
  104. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0b5r~-1._.js +3 -0
  105. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0a0~7d6._.js → [root-of-the-server]__0t7i-hy._.js} +2 -2
  106. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_menubar_route_actions_0xep8_i.js +3 -0
  107. package/app/apps/web/.next/server/chunks/{node_modules_next_036my~r._.js → node_modules_next_04~_e52._.js} +5 -5
  108. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +14 -14
  109. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  110. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  111. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0g-tomj._.js +1 -1
  112. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0nr2~y1._.js +3 -0
  113. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
  114. package/app/apps/web/.next/server/chunks/ssr/{_0xu2pvc._.js → _0k8yioi._.js} +2 -2
  115. package/app/apps/web/.next/server/chunks/ssr/apps_web_0~aj0~u._.js +3 -0
  116. package/app/apps/web/.next/server/chunks/ssr/{apps_web_components_0txtsv5._.js → apps_web_components_0x014hn._.js} +2 -2
  117. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  118. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  119. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
  120. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
  121. package/app/apps/web/.next/server/functions-config-manifest.json +2 -0
  122. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  123. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  124. package/app/apps/web/.next/server/pages/500.html +1 -1
  125. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  126. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  127. package/app/apps/web/.next/static/chunks/0-z49mtd-zwgv.js +1 -0
  128. package/app/apps/web/.next/static/chunks/043slkg3juwck.js +1 -0
  129. package/app/apps/web/.next/static/chunks/{0_ujxc0.z66xb.js → 0g0hv.dt-de9g.js} +3 -3
  130. package/app/apps/web/.next/static/chunks/0t2on1dhydyb2.css +1 -0
  131. package/app/apps/web/app/api/menubar/route.ts +66 -0
  132. package/app/apps/web/app/api/settings/credentials/route.ts +45 -0
  133. package/app/apps/web/app/layout.tsx +2 -0
  134. package/app/apps/web/app/settings/page.tsx +26 -0
  135. package/app/apps/web/app/usage/page.tsx +80 -0
  136. package/app/apps/web/components/menubar-install-banner.tsx +117 -0
  137. package/app/apps/web/components/menubar-install.tsx +107 -0
  138. package/app/apps/web/components/zai-credentials-form.tsx +116 -0
  139. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  140. package/app/apps/web/lib/menubar-data.ts +50 -0
  141. package/app/apps/web/lib/usage-data.ts +4 -0
  142. package/app/apps/web/package.json +1 -1
  143. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  144. package/dist/daemon-worker.js +321 -152
  145. package/dist/index.js +597 -173
  146. package/package.json +3 -2
  147. package/app/apps/web/.next/server/chunks/[root-of-the-server]__065lib8._.js +0 -3
  148. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0c00i76._.js +0 -3
  149. package/app/apps/web/.next/server/chunks/ssr/apps_web_0q2x4a~._.js +0 -3
  150. package/app/apps/web/.next/static/chunks/00a9oyw~h5i1p.js +0 -1
  151. package/app/apps/web/.next/static/chunks/040s42ypidk7s.css +0 -1
  152. package/app/apps/web/.next/static/chunks/0bhwd68o~-xc_.js +0 -1
  153. /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_buildManifest.js +0 -0
  154. /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_clientMiddlewareManifest.js +0 -0
  155. /package/app/apps/web/.next/static/{lIz-6F0SEIL9sgFO3XTJp → nmAGY0LiBgXuibWTKZ1RD}/_ssgManifest.js +0 -0
@@ -8,40 +8,6 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // src/usage/storage.ts
12
- import { appendFileSync, mkdirSync, readFileSync as readFileSync2, existsSync } from "node:fs";
13
- import { dirname } from "node:path";
14
- function appendSnapshot(filePath, snapshot) {
15
- mkdirSync(dirname(filePath), { recursive: true });
16
- appendFileSync(filePath, JSON.stringify(snapshot) + "\n", "utf8");
17
- }
18
- function readSnapshots(filePath) {
19
- if (!existsSync(filePath)) return [];
20
- const content = readFileSync2(filePath, "utf8");
21
- const snapshots = [];
22
- for (const line of content.split("\n")) {
23
- if (!line.trim()) continue;
24
- try {
25
- snapshots.push(JSON.parse(line));
26
- } catch {
27
- }
28
- }
29
- return snapshots;
30
- }
31
- function latestClaudeCodeSnapshot(filePath) {
32
- const all = readSnapshots(filePath);
33
- for (let i = all.length - 1; i >= 0; i--) {
34
- const s = all[i];
35
- if (!s.agent || s.agent === "claude-code") return s;
36
- }
37
- return null;
38
- }
39
- var init_storage = __esm({
40
- "src/usage/storage.ts"() {
41
- "use strict";
42
- }
43
- });
44
-
45
11
  // ../parser/dist/analytics.js
46
12
  function toLocalDay(ms) {
47
13
  const d = new Date(ms);
@@ -641,7 +607,7 @@ function getAgentMetadata(kind) {
641
607
  function isAgentKind(s) {
642
608
  return typeof s === "string" && KNOWN_AGENT_KINDS.has(s);
643
609
  }
644
- var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
610
+ var CLAUDE_CODE_METADATA, CODEX_METADATA, GEMINI_METADATA, ANTIGRAVITY_METADATA, COWORK_METADATA, ZAI_METADATA, agentMetadata, KNOWN_AGENT_KINDS;
645
611
  var init_agent_metadata = __esm({
646
612
  "../parser/dist/agent-metadata.js"() {
647
613
  "use strict";
@@ -680,12 +646,20 @@ var init_agent_metadata = __esm({
680
646
  accentColor: "rgb(217, 119, 87)",
681
647
  iconChar: "\u2318"
682
648
  };
649
+ ZAI_METADATA = {
650
+ kind: "zai",
651
+ displayName: "Z.ai",
652
+ shortLabel: "Z.ai",
653
+ accentColor: "rgb(59, 130, 246)",
654
+ iconChar: "Z"
655
+ };
683
656
  agentMetadata = [
684
657
  CLAUDE_CODE_METADATA,
685
658
  CODEX_METADATA,
686
659
  GEMINI_METADATA,
687
660
  ANTIGRAVITY_METADATA,
688
- COWORK_METADATA
661
+ COWORK_METADATA,
662
+ ZAI_METADATA
689
663
  ];
690
664
  KNOWN_AGENT_KINDS = new Set(agentMetadata.map((m) => m.kind));
691
665
  }
@@ -1427,9 +1401,9 @@ var init_parser = __esm({
1427
1401
  });
1428
1402
 
1429
1403
  // ../parser/dist/git-project.js
1430
- import { existsSync as existsSync2, readFileSync as readFileSync3, realpathSync, statSync } from "node:fs";
1404
+ import { existsSync, readFileSync as readFileSync2, realpathSync, statSync } from "node:fs";
1431
1405
  import { homedir as homedir2 } from "node:os";
1432
- import { basename, dirname as dirname2, isAbsolute, join as join2, resolve } from "node:path";
1406
+ import { basename, dirname, isAbsolute, join as join2, resolve } from "node:path";
1433
1407
  function resolveGitDir(root, dotGitText) {
1434
1408
  const m = dotGitText.match(/^gitdir:\s*(.+)\s*$/m);
1435
1409
  if (!m)
@@ -1439,9 +1413,9 @@ function resolveGitDir(root, dotGitText) {
1439
1413
  }
1440
1414
  function resolveCommonDir(gitDir) {
1441
1415
  const file = join2(gitDir, "commondir");
1442
- if (!existsSync2(file))
1416
+ if (!existsSync(file))
1443
1417
  return void 0;
1444
- const common = readFileSync3(file, "utf8").trim();
1418
+ const common = readFileSync2(file, "utf8").trim();
1445
1419
  if (!common)
1446
1420
  return void 0;
1447
1421
  return isAbsolute(common) ? common : resolve(gitDir, common);
@@ -1453,7 +1427,7 @@ function dotGitInfoFor(root) {
1453
1427
  return null;
1454
1428
  if (st.isDirectory())
1455
1429
  return { root, gitDir: dotGit, commonDir: dotGit };
1456
- const gitDir = resolveGitDir(root, readFileSync3(dotGit, "utf8"));
1430
+ const gitDir = resolveGitDir(root, readFileSync2(dotGit, "utf8"));
1457
1431
  if (!gitDir)
1458
1432
  return { root };
1459
1433
  return { root, gitDir, commonDir: resolveCommonDir(gitDir) };
@@ -1466,13 +1440,13 @@ function nearestDotGit(start) {
1466
1440
  if (!start || !isAbsolute(start))
1467
1441
  return null;
1468
1442
  const boundary = walkBoundary(start);
1469
- for (let dir = start.replace(/\/+$/, "") || start; ; dir = dirname2(dir)) {
1443
+ for (let dir = start.replace(/\/+$/, "") || start; ; dir = dirname(dir)) {
1470
1444
  if (dir === boundary)
1471
1445
  return null;
1472
1446
  const info = dotGitInfoFor(dir);
1473
1447
  if (info)
1474
1448
  return info;
1475
- const parent = dirname2(dir);
1449
+ const parent = dirname(dir);
1476
1450
  if (parent === dir)
1477
1451
  return null;
1478
1452
  }
@@ -1510,18 +1484,18 @@ function remoteFor(git) {
1510
1484
  if (!dir)
1511
1485
  return void 0;
1512
1486
  const config = join2(dir, "config");
1513
- if (!existsSync2(config))
1487
+ if (!existsSync(config))
1514
1488
  return void 0;
1515
- const url = originUrl(readFileSync3(config, "utf8"));
1489
+ const url = originUrl(readFileSync2(config, "utf8"));
1516
1490
  return url ? parseRemote(url) : void 0;
1517
1491
  }
1518
1492
  function headBranch(gitDir) {
1519
1493
  if (!gitDir)
1520
1494
  return void 0;
1521
1495
  const head = join2(gitDir, "HEAD");
1522
- if (!existsSync2(head))
1496
+ if (!existsSync(head))
1523
1497
  return void 0;
1524
- const t = readFileSync3(head, "utf8").trim();
1498
+ const t = readFileSync2(head, "utf8").trim();
1525
1499
  const m = t.match(/^ref:\s*refs\/heads\/(.+)$/);
1526
1500
  return m ? m[1] : `detached @ ${t.slice(0, 7)}`;
1527
1501
  }
@@ -1529,21 +1503,21 @@ function defaultBranch(commonDir) {
1529
1503
  if (!commonDir)
1530
1504
  return void 0;
1531
1505
  const head = join2(commonDir, "refs", "remotes", "origin", "HEAD");
1532
- if (existsSync2(head)) {
1533
- const m = readFileSync3(head, "utf8").trim().match(/refs\/remotes\/origin\/(.+)$/);
1506
+ if (existsSync(head)) {
1507
+ const m = readFileSync2(head, "utf8").trim().match(/refs\/remotes\/origin\/(.+)$/);
1534
1508
  if (m)
1535
1509
  return m[1];
1536
1510
  }
1537
1511
  const packed = join2(commonDir, "packed-refs");
1538
- if (existsSync2(packed)) {
1539
- const m = readFileSync3(packed, "utf8").match(/refs\/remotes\/origin\/(\S+)/);
1512
+ if (existsSync(packed)) {
1513
+ const m = readFileSync2(packed, "utf8").match(/refs\/remotes\/origin\/(\S+)/);
1540
1514
  if (m && m[1] !== "HEAD")
1541
1515
  return m[1];
1542
1516
  }
1543
1517
  return void 0;
1544
1518
  }
1545
1519
  function readGitFolder(path7) {
1546
- if (!existsSync2(path7))
1520
+ if (!existsSync(path7))
1547
1521
  return { exists: false, isWorktree: false };
1548
1522
  try {
1549
1523
  const git = nearestDotGit(realpathOrSelf(path7));
@@ -1565,7 +1539,7 @@ function readGitFolder(path7) {
1565
1539
  function projectRootFromCommonDir(commonDir) {
1566
1540
  if (!commonDir)
1567
1541
  return void 0;
1568
- return basename(commonDir) === ".git" ? dirname2(commonDir) : void 0;
1542
+ return basename(commonDir) === ".git" ? dirname(commonDir) : void 0;
1569
1543
  }
1570
1544
  function realpathOrSelf(p) {
1571
1545
  try {
@@ -3138,13 +3112,16 @@ async function getLatestCodexUsage(opts = {}) {
3138
3112
  const fiveResetUnix = numberOf(primary?.resets_at);
3139
3113
  const sevenResetUnix = numberOf(secondary?.resets_at);
3140
3114
  const planType = typeof rl.plan_type === "string" ? rl.plan_type : null;
3115
+ const nowMs = Date.now();
3116
+ const fiveExpired = fiveResetUnix !== void 0 && nowMs > fiveResetUnix * 1e3;
3117
+ const sevenExpired = sevenResetUnix !== void 0 && nowMs > sevenResetUnix * 1e3;
3141
3118
  return {
3142
3119
  five_hour: {
3143
- utilization: fivePct ?? null,
3120
+ utilization: fiveExpired ? 0 : fivePct ?? null,
3144
3121
  resets_at: fiveResetUnix !== void 0 ? new Date(fiveResetUnix * 1e3).toISOString() : null
3145
3122
  },
3146
3123
  seven_day: {
3147
- utilization: sevenPct ?? null,
3124
+ utilization: sevenExpired ? 0 : sevenPct ?? null,
3148
3125
  resets_at: sevenResetUnix !== void 0 ? new Date(sevenResetUnix * 1e3).toISOString() : null
3149
3126
  },
3150
3127
  plan_type: planType,
@@ -4420,7 +4397,7 @@ var init_cowork = __esm({
4420
4397
  });
4421
4398
 
4422
4399
  // ../parser/dist/team-config.js
4423
- import { readFileSync as readFileSync4, writeFileSync, unlinkSync, mkdirSync as mkdirSync2, renameSync } from "node:fs";
4400
+ import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync, renameSync } from "node:fs";
4424
4401
  import { join as join3 } from "node:path";
4425
4402
  function shouldSyncProject(projectKey2, sp) {
4426
4403
  if (!sp)
@@ -4434,14 +4411,14 @@ function shouldSyncProject(projectKey2, sp) {
4434
4411
  function readTeamConfig(dir) {
4435
4412
  const d = dir ?? cclensHome();
4436
4413
  try {
4437
- return JSON.parse(readFileSync4(join3(d, CONFIG_FILE), "utf8"));
4414
+ return JSON.parse(readFileSync3(join3(d, CONFIG_FILE), "utf8"));
4438
4415
  } catch {
4439
4416
  return null;
4440
4417
  }
4441
4418
  }
4442
4419
  function writeTeamConfig(config, dir) {
4443
4420
  const d = dir ?? cclensHome();
4444
- mkdirSync2(d, { recursive: true });
4421
+ mkdirSync(d, { recursive: true });
4445
4422
  const tmp = join3(d, `${CONFIG_FILE}.${process.pid}.tmp`);
4446
4423
  writeFileSync(tmp, JSON.stringify(config, null, 2), { mode: 384 });
4447
4424
  renameSync(tmp, join3(d, CONFIG_FILE));
@@ -4482,6 +4459,7 @@ __export(fs_exports, {
4482
4459
  RICH_ROLLUP_SCHEMA_VERSION: () => RICH_ROLLUP_SCHEMA_VERSION,
4483
4460
  agentSources: () => agentSources,
4484
4461
  antigravitySessionLocalDay: () => antigravitySessionLocalDay,
4462
+ appendUsageSnapshot: () => appendUsageSnapshot,
4485
4463
  buildCalibrationCurve: () => buildCalibrationCurve,
4486
4464
  cacheStats: () => cacheStats,
4487
4465
  cclensHome: () => cclensHome,
@@ -4515,6 +4493,7 @@ __export(fs_exports, {
4515
4493
  loadTeamForSession: () => loadTeamForSession,
4516
4494
  loadUsageByDay: () => loadUsageByDay,
4517
4495
  loadWorkflowAgentDetail: () => loadWorkflowAgentDetail,
4496
+ pruneUsageAgent: () => pruneUsageAgent,
4518
4497
  readGitFolder: () => readGitFolder,
4519
4498
  readJsonlFile: () => readJsonlFile,
4520
4499
  readTeamConfig: () => readTeamConfig,
@@ -4524,7 +4503,7 @@ __export(fs_exports, {
4524
4503
  walkJsonlFiles: () => walkJsonlFiles,
4525
4504
  writeTeamConfig: () => writeTeamConfig
4526
4505
  });
4527
- import { promises as fs6 } from "node:fs";
4506
+ import { promises as fs6, existsSync as existsSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync, mkdirSync as mkdirSync2 } from "node:fs";
4528
4507
  import os6 from "node:os";
4529
4508
  import path6 from "node:path";
4530
4509
  function cclensHome() {
@@ -4570,6 +4549,27 @@ async function getAnySession(id) {
4570
4549
  function usageLogPath() {
4571
4550
  return cclensPath("usage.jsonl");
4572
4551
  }
4552
+ function appendUsageSnapshot(snapshot) {
4553
+ const p = usageLogPath();
4554
+ mkdirSync2(path6.dirname(p), { recursive: true });
4555
+ appendFileSync(p, JSON.stringify(snapshot) + "\n", "utf8");
4556
+ }
4557
+ function pruneUsageAgent(agent) {
4558
+ const p = usageLogPath();
4559
+ if (!existsSync2(p))
4560
+ return;
4561
+ const kept = readFileSync4(p, "utf8").split("\n").filter((line) => {
4562
+ if (!line.trim())
4563
+ return false;
4564
+ try {
4565
+ return JSON.parse(line).agent !== agent;
4566
+ } catch {
4567
+ return true;
4568
+ }
4569
+ });
4570
+ mkdirSync2(path6.dirname(p), { recursive: true });
4571
+ writeFileSync2(p, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
4572
+ }
4573
4573
  async function loadUsageByDay(start, end) {
4574
4574
  let raw;
4575
4575
  try {
@@ -4862,6 +4862,53 @@ var init_fs = __esm({
4862
4862
  }
4863
4863
  });
4864
4864
 
4865
+ // src/usage/storage.ts
4866
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "node:fs";
4867
+ import { dirname as dirname2 } from "node:path";
4868
+ function appendSnapshot(filePath, snapshot) {
4869
+ mkdirSync3(dirname2(filePath), { recursive: true });
4870
+ appendFileSync2(filePath, JSON.stringify(snapshot) + "\n", "utf8");
4871
+ }
4872
+ function readSnapshots(filePath) {
4873
+ if (!existsSync4(filePath)) return [];
4874
+ const content = readFileSync6(filePath, "utf8");
4875
+ const snapshots = [];
4876
+ for (const line of content.split("\n")) {
4877
+ if (!line.trim()) continue;
4878
+ try {
4879
+ snapshots.push(JSON.parse(line));
4880
+ } catch {
4881
+ }
4882
+ }
4883
+ return snapshots;
4884
+ }
4885
+ function pruneAgent(filePath, agent) {
4886
+ if (!existsSync4(filePath)) return;
4887
+ const kept = readFileSync6(filePath, "utf8").split("\n").filter((line) => {
4888
+ if (!line.trim()) return false;
4889
+ try {
4890
+ return JSON.parse(line).agent !== agent;
4891
+ } catch {
4892
+ return true;
4893
+ }
4894
+ });
4895
+ mkdirSync3(dirname2(filePath), { recursive: true });
4896
+ writeFileSync3(filePath, kept.join("\n") + (kept.length ? "\n" : ""), "utf8");
4897
+ }
4898
+ function latestClaudeCodeSnapshot(filePath) {
4899
+ const all = readSnapshots(filePath);
4900
+ for (let i = all.length - 1; i >= 0; i--) {
4901
+ const s = all[i];
4902
+ if (!s.agent || s.agent === "claude-code") return s;
4903
+ }
4904
+ return null;
4905
+ }
4906
+ var init_storage = __esm({
4907
+ "src/usage/storage.ts"() {
4908
+ "use strict";
4909
+ }
4910
+ });
4911
+
4865
4912
  // ../parser/dist/types.js
4866
4913
  var init_types = __esm({
4867
4914
  "../parser/dist/types.js"() {
@@ -5279,6 +5326,7 @@ __export(dist_exports, {
5279
5326
  RATE_PER_PCT: () => RATE_PER_PCT,
5280
5327
  RATE_PER_PCT_5H: () => RATE_PER_PCT_5H,
5281
5328
  RATE_PER_PCT_7D: () => RATE_PER_PCT_7D,
5329
+ ZAI_METADATA: () => ZAI_METADATA,
5282
5330
  agentMetadata: () => agentMetadata,
5283
5331
  aggregateConcurrency: () => aggregateConcurrency,
5284
5332
  buildGanttDay: () => buildGanttDay,
@@ -5347,7 +5395,7 @@ __export(file_probe_exports, {
5347
5395
  probeArtifactSignals: () => probeArtifactSignals
5348
5396
  });
5349
5397
  import { createHash } from "node:crypto";
5350
- import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
5398
+ import { existsSync as existsSync9, readdirSync as readdirSync3, statSync as statSync5 } from "node:fs";
5351
5399
  import { homedir as homedir3 } from "node:os";
5352
5400
  import { join as join8, relative, resolve as resolve3, sep } from "node:path";
5353
5401
  import { execFileSync as execFileSync2 } from "node:child_process";
@@ -5357,15 +5405,15 @@ function pathHash(relPath) {
5357
5405
  function defaultScanRoots(extraRoots = []) {
5358
5406
  const roots = [];
5359
5407
  const home = join8(homedir3(), ".claude");
5360
- if (existsSync7(home)) roots.push({ root: home, label: "user" });
5408
+ if (existsSync9(home)) roots.push({ root: home, label: "user" });
5361
5409
  for (const e of extraRoots) {
5362
5410
  const r = resolve3(e, ".claude");
5363
- if (existsSync7(r) && r !== home) roots.push({ root: r, label: "project" });
5411
+ if (existsSync9(r) && r !== home) roots.push({ root: r, label: "project" });
5364
5412
  }
5365
5413
  return roots;
5366
5414
  }
5367
5415
  function listMarkdownFiles(dir) {
5368
- if (!existsSync7(dir)) return [];
5416
+ if (!existsSync9(dir)) return [];
5369
5417
  const out = [];
5370
5418
  let entries;
5371
5419
  try {
@@ -5435,7 +5483,7 @@ function scanAuthored(roots, subdir, day) {
5435
5483
  const out = [];
5436
5484
  for (const r of roots) {
5437
5485
  const dir = join8(r.root, subdir);
5438
- if (!existsSync7(dir)) continue;
5486
+ if (!existsSync9(dir)) continue;
5439
5487
  for (const f of listMarkdownFiles(dir)) {
5440
5488
  const firstSeen = firstSeenDateOf(f);
5441
5489
  if (firstSeen !== day) continue;
@@ -5449,7 +5497,7 @@ function scanEdited(roots, day) {
5449
5497
  const out = [];
5450
5498
  for (const r of roots) {
5451
5499
  const dir = join8(r.root, "skills");
5452
- if (!existsSync7(dir)) continue;
5500
+ if (!existsSync9(dir)) continue;
5453
5501
  for (const f of listMarkdownFiles(dir)) {
5454
5502
  const firstSeen = firstSeenDateOf(f);
5455
5503
  if (firstSeen === day) continue;
@@ -5472,10 +5520,10 @@ function claudemdLineDelta(extraRoots, authorEmail, day) {
5472
5520
  const candidates = [];
5473
5521
  for (const e of extraRoots) {
5474
5522
  const f = resolve3(e, "CLAUDE.md");
5475
- if (existsSync7(f)) candidates.push(f);
5523
+ if (existsSync9(f)) candidates.push(f);
5476
5524
  }
5477
5525
  const homeClaudeMd = join8(homedir3(), "CLAUDE.md");
5478
- if (existsSync7(homeClaudeMd)) candidates.push(homeClaudeMd);
5526
+ if (existsSync9(homeClaudeMd)) candidates.push(homeClaudeMd);
5479
5527
  for (const file of candidates) {
5480
5528
  try {
5481
5529
  const out = execFileSync2(
@@ -5532,7 +5580,7 @@ var init_file_probe = __esm({
5532
5580
 
5533
5581
  // src/daemon-worker.ts
5534
5582
  import { spawn as spawn2 } from "node:child_process";
5535
- import { closeSync, existsSync as existsSync14, mkdirSync as mkdirSync13, openSync, readFileSync as readFileSync17, writeFileSync as writeFileSync12 } from "node:fs";
5583
+ import { closeSync, existsSync as existsSync16, mkdirSync as mkdirSync14, openSync, readFileSync as readFileSync19, writeFileSync as writeFileSync14 } from "node:fs";
5536
5584
  import { dirname as dirname11, join as join12 } from "node:path";
5537
5585
  import { fileURLToPath } from "node:url";
5538
5586
 
@@ -5674,16 +5722,120 @@ function normalizeExtra(raw) {
5674
5722
  };
5675
5723
  }
5676
5724
 
5725
+ // src/usage/zai.ts
5726
+ init_fs();
5727
+ import { existsSync as existsSync3, readFileSync as readFileSync5 } from "node:fs";
5728
+ var ZAI_QUOTA_ENDPOINT = "https://api.z.ai/api/monitor/usage/quota/limit";
5729
+ var ZAI_SUBSCRIPTION_ENDPOINT = "https://api.z.ai/api/biz/subscription/list";
5730
+ var ZaiApiError = class extends Error {
5731
+ constructor(message, code) {
5732
+ super(message);
5733
+ this.code = code;
5734
+ }
5735
+ };
5736
+ function resolveApiKey() {
5737
+ try {
5738
+ const p = cclensPath("credentials.json");
5739
+ if (existsSync3(p)) {
5740
+ const store = JSON.parse(readFileSync5(p, "utf8"));
5741
+ return store.zai?.apiKey ?? null;
5742
+ }
5743
+ } catch {
5744
+ }
5745
+ return null;
5746
+ }
5747
+ function epochMsToIso(ms) {
5748
+ if (typeof ms !== "number" || Number.isNaN(ms)) return null;
5749
+ return new Date(ms).toISOString();
5750
+ }
5751
+ function windowFromLimit(limit) {
5752
+ return {
5753
+ utilization: typeof limit.percentage === "number" ? limit.percentage : null,
5754
+ resets_at: epochMsToIso(limit.nextResetTime)
5755
+ };
5756
+ }
5757
+ function zaiHeaders(key) {
5758
+ return { Authorization: key, "Accept-Language": "en-US,en" };
5759
+ }
5760
+ async function fetchZaiUsage() {
5761
+ const key = resolveApiKey();
5762
+ if (!key) {
5763
+ throw new ZaiApiError(
5764
+ "No Z.ai API key found. Set ZAI_API_KEY (or GLM_API_KEY), or write ~/.config/zai/key.json.",
5765
+ "no_key"
5766
+ );
5767
+ }
5768
+ let res;
5769
+ try {
5770
+ res = await fetch(ZAI_QUOTA_ENDPOINT, { headers: zaiHeaders(key) });
5771
+ } catch (err) {
5772
+ throw new ZaiApiError(`Network error reaching Z.ai: ${err.message}`, "network");
5773
+ }
5774
+ if (!res.ok) {
5775
+ throw new ZaiApiError(`Z.ai quota endpoint returned ${res.status} ${res.statusText}`, "http");
5776
+ }
5777
+ let body;
5778
+ try {
5779
+ body = await res.json();
5780
+ } catch (err) {
5781
+ throw new ZaiApiError(`Failed to parse Z.ai quota response: ${err.message}`, "parse");
5782
+ }
5783
+ const b = body;
5784
+ const limits = b.data?.limits ?? [];
5785
+ let fiveHour = null;
5786
+ let sevenDay = null;
5787
+ let webSearch = null;
5788
+ for (const limit of limits) {
5789
+ if (limit.type === "TIME_LIMIT") {
5790
+ const percentage = typeof limit.percentage === "number" ? limit.percentage : null;
5791
+ webSearch = {
5792
+ used: percentage,
5793
+ limit: percentage !== null ? 100 : null
5794
+ };
5795
+ continue;
5796
+ }
5797
+ const window = windowFromLimit(limit);
5798
+ if (limit.unit === 6) {
5799
+ sevenDay = sevenDay ?? window;
5800
+ } else {
5801
+ fiveHour = fiveHour ?? window;
5802
+ }
5803
+ }
5804
+ let planType = null;
5805
+ try {
5806
+ const subRes = await fetch(ZAI_SUBSCRIPTION_ENDPOINT, { headers: zaiHeaders(key) });
5807
+ if (subRes.ok) {
5808
+ const sub = await subRes.json();
5809
+ const entry = sub.data?.[0];
5810
+ planType = entry?.productName || entry?.planName || entry?.name || null;
5811
+ }
5812
+ } catch {
5813
+ }
5814
+ return {
5815
+ captured_at: (/* @__PURE__ */ new Date()).toISOString(),
5816
+ agent: "zai",
5817
+ five_hour: fiveHour ?? { utilization: null, resets_at: null },
5818
+ seven_day: sevenDay ?? { utilization: null, resets_at: null },
5819
+ seven_day_opus: null,
5820
+ seven_day_sonnet: null,
5821
+ seven_day_oauth_apps: null,
5822
+ seven_day_cowork: null,
5823
+ extra_usage: null,
5824
+ plan_type: planType,
5825
+ web_search_quota: webSearch ?? null
5826
+ };
5827
+ }
5828
+
5677
5829
  // src/daemon-worker.ts
5678
5830
  init_storage();
5679
5831
  init_fs();
5680
5832
 
5681
5833
  // src/daemon-log.ts
5682
5834
  init_fs();
5683
- import { appendFileSync as appendFileSync2 } from "node:fs";
5835
+ import { appendFileSync as appendFileSync3 } from "node:fs";
5684
5836
  function appendDaemonLogLine(level, msg) {
5685
5837
  try {
5686
- appendFileSync2(
5838
+ appendFileSync3(
5687
5839
  cclensPath("daemon.log"),
5688
5840
  `${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${msg}
5689
5841
  `,
@@ -5715,7 +5867,7 @@ import { randomUUID } from "node:crypto";
5715
5867
 
5716
5868
  // ../entries/dist/fs.js
5717
5869
  init_fs();
5718
- import { readFileSync as readFileSync6, readdirSync as readdirSync2, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, renameSync as renameSync3, existsSync as existsSync4 } from "node:fs";
5870
+ import { readFileSync as readFileSync8, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, renameSync as renameSync3, existsSync as existsSync6 } from "node:fs";
5719
5871
  import { randomBytes } from "node:crypto";
5720
5872
  import { join as join5 } from "node:path";
5721
5873
 
@@ -5790,12 +5942,12 @@ var PROMPT_FRAME_ORIGIN = {
5790
5942
 
5791
5943
  // ../entries/dist/digest-fs.js
5792
5944
  init_fs();
5793
- import { readFileSync as readFileSync5, readdirSync, writeFileSync as writeFileSync2, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync3, existsSync as existsSync3 } from "node:fs";
5945
+ import { readFileSync as readFileSync7, readdirSync, writeFileSync as writeFileSync4, renameSync as renameSync2, chmodSync, mkdirSync as mkdirSync4, existsSync as existsSync5 } from "node:fs";
5794
5946
  import { dirname as dirname3, join as join4 } from "node:path";
5795
5947
  var digestsDirCached = null;
5796
5948
  function parseDigestFile(path7, expectedVersion) {
5797
5949
  try {
5798
- const parsed = JSON.parse(readFileSync5(path7, "utf8"));
5950
+ const parsed = JSON.parse(readFileSync7(path7, "utf8"));
5799
5951
  if (!parsed || typeof parsed !== "object")
5800
5952
  return null;
5801
5953
  if (parsed.version !== expectedVersion)
@@ -5822,9 +5974,9 @@ function weekDigestPath(monday) {
5822
5974
  }
5823
5975
  function writeDayDigest(digest) {
5824
5976
  const final = dayDigestPath(digest.key);
5825
- mkdirSync3(dirname3(final), { recursive: true });
5977
+ mkdirSync4(dirname3(final), { recursive: true });
5826
5978
  const tmp = `${final}.tmp`;
5827
- writeFileSync2(tmp, JSON.stringify(digest, null, 2), "utf8");
5979
+ writeFileSync4(tmp, JSON.stringify(digest, null, 2), "utf8");
5828
5980
  if (process.platform !== "win32") {
5829
5981
  try {
5830
5982
  chmodSync(tmp, 384);
@@ -5835,7 +5987,7 @@ function writeDayDigest(digest) {
5835
5987
  }
5836
5988
  function readDayDigest(date) {
5837
5989
  const p = dayDigestPath(date);
5838
- if (!existsSync3(p))
5990
+ if (!existsSync5(p))
5839
5991
  return null;
5840
5992
  return parseDigestFile(p, CURRENT_DAY_DIGEST_SCHEMA_VERSION);
5841
5993
  }
@@ -5855,9 +6007,9 @@ function setTodayDigestInCache(date, digest, nowMs) {
5855
6007
  }
5856
6008
  function writeWeekDigest(digest) {
5857
6009
  const final = weekDigestPath(digest.key);
5858
- mkdirSync3(dirname3(final), { recursive: true });
6010
+ mkdirSync4(dirname3(final), { recursive: true });
5859
6011
  const tmp = `${final}.tmp`;
5860
- writeFileSync2(tmp, JSON.stringify(digest, null, 2), "utf8");
6012
+ writeFileSync4(tmp, JSON.stringify(digest, null, 2), "utf8");
5861
6013
  if (process.platform !== "win32") {
5862
6014
  try {
5863
6015
  chmodSync(tmp, 384);
@@ -5868,7 +6020,7 @@ function writeWeekDigest(digest) {
5868
6020
  }
5869
6021
  function readWeekDigest(monday) {
5870
6022
  const p = weekDigestPath(monday);
5871
- if (!existsSync3(p))
6023
+ if (!existsSync5(p))
5872
6024
  return null;
5873
6025
  return parseDigestFile(p, CURRENT_WEEK_DIGEST_SCHEMA_VERSION);
5874
6026
  }
@@ -5905,11 +6057,11 @@ function tmpPathFor(final) {
5905
6057
  }
5906
6058
  function writeEntry(entry) {
5907
6059
  const dir = entriesDir();
5908
- mkdirSync4(dir, { recursive: true });
6060
+ mkdirSync5(dir, { recursive: true });
5909
6061
  const final = pathFor(entry.session_id, entry.local_day);
5910
6062
  const tmp = tmpPathFor(final);
5911
6063
  const json = JSON.stringify(entry, null, 2);
5912
- writeFileSync3(tmp, json, { encoding: "utf8" });
6064
+ writeFileSync5(tmp, json, { encoding: "utf8" });
5913
6065
  renameSync3(tmp, final);
5914
6066
  }
5915
6067
  var PRESERVABLE_STATUSES = /* @__PURE__ */ new Set([
@@ -5933,7 +6085,7 @@ function enrichmentInputHash(e) {
5933
6085
  }
5934
6086
  function writeEntryPreservingEnrichment(fresh) {
5935
6087
  const dir = entriesDir();
5936
- mkdirSync4(dir, { recursive: true });
6088
+ mkdirSync5(dir, { recursive: true });
5937
6089
  const final = pathFor(fresh.session_id, fresh.local_day);
5938
6090
  const existing = readEntry(fresh.session_id, fresh.local_day);
5939
6091
  let toWrite = fresh;
@@ -5941,22 +6093,22 @@ function writeEntryPreservingEnrichment(fresh) {
5941
6093
  toWrite = { ...fresh, enrichment: existing.enrichment };
5942
6094
  }
5943
6095
  const tmp = tmpPathFor(final);
5944
- writeFileSync3(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
6096
+ writeFileSync5(tmp, JSON.stringify(toWrite, null, 2), { encoding: "utf8" });
5945
6097
  renameSync3(tmp, final);
5946
6098
  }
5947
6099
  function readEntry(sessionId, localDay2) {
5948
6100
  const p = pathFor(sessionId, localDay2);
5949
- if (!existsSync4(p))
6101
+ if (!existsSync6(p))
5950
6102
  return null;
5951
- const raw = readFileSync6(p, "utf8");
6103
+ const raw = readFileSync8(p, "utf8");
5952
6104
  return JSON.parse(raw);
5953
6105
  }
5954
6106
  function entryExists(sessionId, localDay2) {
5955
- return existsSync4(pathFor(sessionId, localDay2));
6107
+ return existsSync6(pathFor(sessionId, localDay2));
5956
6108
  }
5957
6109
  function listEntryKeys() {
5958
6110
  const dir = entriesDir();
5959
- if (!existsSync4(dir))
6111
+ if (!existsSync6(dir))
5960
6112
  return [];
5961
6113
  return readdirSync2(dir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -".json".length));
5962
6114
  }
@@ -5975,7 +6127,7 @@ function listEntriesForDay(localDay2) {
5975
6127
 
5976
6128
  // src/perception/build-entries.ts
5977
6129
  init_dist();
5978
- import { statSync as statSync2, readFileSync as readFileSync7 } from "node:fs";
6130
+ import { statSync as statSync2, readFileSync as readFileSync9 } from "node:fs";
5979
6131
  import { basename as basename2, dirname as dirname4 } from "node:path";
5980
6132
 
5981
6133
  // ../entries/dist/signals.js
@@ -6715,7 +6867,7 @@ function decodeProjectDirName(projectDir) {
6715
6867
  }
6716
6868
  function buildEntriesForFile(filePath) {
6717
6869
  const stat = statSync2(filePath);
6718
- const raw = readFileSync7(filePath, "utf8");
6870
+ const raw = readFileSync9(filePath, "utf8");
6719
6871
  const rawLines = raw.split("\n").filter(Boolean).map((l) => {
6720
6872
  try {
6721
6873
  return JSON.parse(l);
@@ -6976,7 +7128,7 @@ function buildIngestPayload(inputs) {
6976
7128
  return {
6977
7129
  ingestId: randomUUID(),
6978
7130
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
6979
- cliVersion: "0.15.3",
7131
+ cliVersion: "0.15.4",
6980
7132
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
6981
7133
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
6982
7134
  ...richRollup ? { richRollup } : {},
@@ -7003,7 +7155,7 @@ async function pushToTeamServer(config, payload) {
7003
7155
  }
7004
7156
 
7005
7157
  // src/team/git-remote.ts
7006
- import { existsSync as existsSync5, readFileSync as readFileSync8, statSync as statSync3 } from "node:fs";
7158
+ import { existsSync as existsSync7, readFileSync as readFileSync10, statSync as statSync3 } from "node:fs";
7007
7159
  import { dirname as dirname5, isAbsolute as isAbsolute2, join as join6, resolve as resolve2 } from "node:path";
7008
7160
  var GITHUB_URL_RE = /github\.com[:/]([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+?)(?:\.git)?$/;
7009
7161
  function parseGithubRemote(url) {
@@ -7029,12 +7181,12 @@ function gitConfigPathFor(dir) {
7029
7181
  const st = statSync3(dotGit, { throwIfNoEntry: false });
7030
7182
  if (!st) return null;
7031
7183
  if (st.isDirectory()) return join6(dotGit, "config");
7032
- const m = readFileSync8(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
7184
+ const m = readFileSync10(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
7033
7185
  if (!m) return null;
7034
7186
  const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
7035
7187
  const commondirFile = join6(gd, "commondir");
7036
- if (existsSync5(commondirFile)) {
7037
- const common = readFileSync8(commondirFile, "utf8").trim();
7188
+ if (existsSync7(commondirFile)) {
7189
+ const common = readFileSync10(commondirFile, "utf8").trim();
7038
7190
  return join6(isAbsolute2(common) ? common : resolve2(gd, common), "config");
7039
7191
  }
7040
7192
  return join6(gd, "config");
@@ -7049,8 +7201,8 @@ function createRepoResolver() {
7049
7201
  try {
7050
7202
  for (let d = dir; ; d = dirname5(d)) {
7051
7203
  const config = gitConfigPathFor(d);
7052
- if (config && existsSync5(config)) {
7053
- const url = originUrl2(readFileSync8(config, "utf8"));
7204
+ if (config && existsSync7(config)) {
7205
+ const url = originUrl2(readFileSync10(config, "utf8"));
7054
7206
  repo = url ? parseGithubRemote(url) : null;
7055
7207
  break;
7056
7208
  }
@@ -7066,15 +7218,15 @@ function createRepoResolver() {
7066
7218
 
7067
7219
  // src/team/queue.ts
7068
7220
  init_fs();
7069
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync4, appendFileSync as appendFileSync3, statSync as statSync4, mkdirSync as mkdirSync5 } from "node:fs";
7221
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync6, appendFileSync as appendFileSync4, statSync as statSync4, mkdirSync as mkdirSync6 } from "node:fs";
7070
7222
  import { dirname as dirname6 } from "node:path";
7071
7223
  var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
7072
7224
  var MAX_SIZE_BYTES = 10 * 1024 * 1024;
7073
7225
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
7074
7226
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
7075
- mkdirSync5(dirname6(queuePath), { recursive: true });
7227
+ mkdirSync6(dirname6(queuePath), { recursive: true });
7076
7228
  const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
7077
- appendFileSync3(queuePath, JSON.stringify(entry) + "\n", "utf8");
7229
+ appendFileSync4(queuePath, JSON.stringify(entry) + "\n", "utf8");
7078
7230
  try {
7079
7231
  const { size } = statSync4(queuePath);
7080
7232
  if (size > MAX_SIZE_BYTES) {
@@ -7086,7 +7238,7 @@ function enqueuePayload(payload, queuePath = QUEUE_PATH) {
7086
7238
  function dequeuePayloads(queuePath = QUEUE_PATH) {
7087
7239
  let lines;
7088
7240
  try {
7089
- lines = readFileSync9(queuePath, "utf8").trim().split("\n").filter(Boolean);
7241
+ lines = readFileSync11(queuePath, "utf8").trim().split("\n").filter(Boolean);
7090
7242
  } catch {
7091
7243
  return [];
7092
7244
  }
@@ -7101,18 +7253,18 @@ function dequeuePayloads(queuePath = QUEUE_PATH) {
7101
7253
  } catch {
7102
7254
  }
7103
7255
  }
7104
- writeFileSync4(queuePath, "", "utf8");
7256
+ writeFileSync6(queuePath, "", "utf8");
7105
7257
  return valid.map((e) => e.payload);
7106
7258
  }
7107
7259
  function pruneOldest(queuePath) {
7108
7260
  let lines;
7109
7261
  try {
7110
- lines = readFileSync9(queuePath, "utf8").trim().split("\n").filter(Boolean);
7262
+ lines = readFileSync11(queuePath, "utf8").trim().split("\n").filter(Boolean);
7111
7263
  } catch {
7112
7264
  return;
7113
7265
  }
7114
7266
  const keep = lines.slice(Math.floor(lines.length / 2));
7115
- writeFileSync4(queuePath, keep.join("\n") + "\n", "utf8");
7267
+ writeFileSync6(queuePath, keep.join("\n") + "\n", "utf8");
7116
7268
  }
7117
7269
 
7118
7270
  // src/team/backfill.ts
@@ -7120,7 +7272,7 @@ init_storage();
7120
7272
  import { randomUUID as randomUUID2 } from "node:crypto";
7121
7273
 
7122
7274
  // src/usage/profile.ts
7123
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "node:fs";
7275
+ import { existsSync as existsSync8, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync7 } from "node:fs";
7124
7276
  import { dirname as dirname7 } from "node:path";
7125
7277
  var PROFILE_ENDPOINT = "https://api.anthropic.com/api/oauth/profile";
7126
7278
  var BETA_HEADER2 = "oauth-2025-04-20";
@@ -7164,9 +7316,9 @@ async function fetchProfile(nowMs = Date.now()) {
7164
7316
  };
7165
7317
  }
7166
7318
  function readCachedProfile(cachePath) {
7167
- if (!existsSync6(cachePath)) return null;
7319
+ if (!existsSync8(cachePath)) return null;
7168
7320
  try {
7169
- const raw = JSON.parse(readFileSync10(cachePath, "utf8"));
7321
+ const raw = JSON.parse(readFileSync12(cachePath, "utf8"));
7170
7322
  if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
7171
7323
  return raw;
7172
7324
  } catch {
@@ -7174,8 +7326,8 @@ function readCachedProfile(cachePath) {
7174
7326
  }
7175
7327
  }
7176
7328
  function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
7177
- mkdirSync6(dirname7(cachePath), { recursive: true });
7178
- writeFileSync5(
7329
+ mkdirSync7(dirname7(cachePath), { recursive: true });
7330
+ writeFileSync7(
7179
7331
  cachePath,
7180
7332
  JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
7181
7333
  { mode: 384 }
@@ -7335,13 +7487,13 @@ async function runTeamBackfill(log3 = noopLog, filePath = USAGE_LOG, configOverr
7335
7487
 
7336
7488
  // src/team/sync-log.ts
7337
7489
  init_fs();
7338
- import { readFileSync as readFileSync11 } from "node:fs";
7490
+ import { readFileSync as readFileSync13 } from "node:fs";
7339
7491
  var MAX_LINES = 300;
7340
7492
  var MAX_MSG_CHARS = 1900;
7341
7493
  function readPendingSyncLog(watermark) {
7342
7494
  let raw;
7343
7495
  try {
7344
- raw = readFileSync11(cclensPath("daemon.log"), "utf8");
7496
+ raw = readFileSync13(cclensPath("daemon.log"), "utf8");
7345
7497
  } catch {
7346
7498
  return { lines: [] };
7347
7499
  }
@@ -7361,13 +7513,13 @@ function readPendingSyncLog(watermark) {
7361
7513
 
7362
7514
  // src/team/last-push.ts
7363
7515
  init_fs();
7364
- import { writeFileSync as writeFileSync6, unlinkSync as unlinkSync2, mkdirSync as mkdirSync7 } from "node:fs";
7516
+ import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, mkdirSync as mkdirSync8 } from "node:fs";
7365
7517
  import { join as join7 } from "node:path";
7366
7518
  var LAST_PUSH_FILE = "team-last-push.json";
7367
7519
  function write(record, dir) {
7368
7520
  const d = dir ?? cclensHome();
7369
- mkdirSync7(d, { recursive: true });
7370
- writeFileSync6(join7(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
7521
+ mkdirSync8(d, { recursive: true });
7522
+ writeFileSync8(join7(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
7371
7523
  }
7372
7524
  function writeLastPushSuccess(payload, dir) {
7373
7525
  write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
@@ -7951,7 +8103,7 @@ init_fs();
7951
8103
 
7952
8104
  // src/perception/state.ts
7953
8105
  init_fs();
7954
- import { existsSync as existsSync8, readFileSync as readFileSync12, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, renameSync as renameSync4 } from "node:fs";
8106
+ import { existsSync as existsSync10, readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync9, renameSync as renameSync4 } from "node:fs";
7955
8107
  import { dirname as dirname9 } from "node:path";
7956
8108
  var STALE_MS = 15 * 60 * 1e3;
7957
8109
  var pathCached = null;
@@ -7962,7 +8114,7 @@ function statePath() {
7962
8114
  }
7963
8115
  function readState() {
7964
8116
  const p = statePath();
7965
- if (!existsSync8(p)) {
8117
+ if (!existsSync10(p)) {
7966
8118
  return {
7967
8119
  sweep_in_progress: false,
7968
8120
  last_sweep_started_at: null,
@@ -7970,14 +8122,14 @@ function readState() {
7970
8122
  file_checkpoints: {}
7971
8123
  };
7972
8124
  }
7973
- const raw = readFileSync12(p, "utf8");
8125
+ const raw = readFileSync14(p, "utf8");
7974
8126
  return JSON.parse(raw);
7975
8127
  }
7976
8128
  function writeState(s) {
7977
8129
  const p = statePath();
7978
- mkdirSync8(dirname9(p), { recursive: true });
8130
+ mkdirSync9(dirname9(p), { recursive: true });
7979
8131
  const tmp = `${p}.tmp`;
7980
- writeFileSync7(tmp, JSON.stringify(s, null, 2), "utf8");
8132
+ writeFileSync9(tmp, JSON.stringify(s, null, 2), "utf8");
7981
8133
  renameSync4(tmp, p);
7982
8134
  }
7983
8135
  function markSweepStart() {
@@ -12233,12 +12385,12 @@ var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
12233
12385
  // ../entries/dist/llm-runner.js
12234
12386
  init_fs();
12235
12387
  import { spawn } from "node:child_process";
12236
- import { mkdirSync as mkdirSync10, appendFileSync as appendFileSync4, writeFileSync as writeFileSync9, existsSync as existsSync10 } from "node:fs";
12388
+ import { mkdirSync as mkdirSync11, appendFileSync as appendFileSync5, writeFileSync as writeFileSync11, existsSync as existsSync12 } from "node:fs";
12237
12389
  import { join as join11 } from "node:path";
12238
12390
  import { randomUUID as randomUUID4 } from "node:crypto";
12239
12391
 
12240
12392
  // ../entries/dist/tmux-runner.js
12241
- import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync8, existsSync as existsSync9, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync13, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
12393
+ import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync10, existsSync as existsSync11, readdirSync as readdirSync5, realpathSync as realpathSync2, readFileSync as readFileSync15, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
12242
12394
  import { join as join10 } from "node:path";
12243
12395
  import { homedir as homedir5 } from "node:os";
12244
12396
  import { spawnSync } from "node:child_process";
@@ -12269,15 +12421,15 @@ function tmuxRunnerAvailable() {
12269
12421
  }
12270
12422
  function runtimeCwd() {
12271
12423
  const dir = join10(homedir5(), ".cclens", "runtime");
12272
- if (!existsSync9(dir))
12273
- mkdirSync9(dir, { recursive: true });
12424
+ if (!existsSync11(dir))
12425
+ mkdirSync10(dir, { recursive: true });
12274
12426
  return realpathSync2(dir);
12275
12427
  }
12276
12428
  function ensureRuntimeCwdTrusted(cwd) {
12277
12429
  const cfgPath = join10(homedir5(), ".claude.json");
12278
12430
  let cfg;
12279
12431
  try {
12280
- cfg = JSON.parse(readFileSync13(cfgPath, "utf8"));
12432
+ cfg = JSON.parse(readFileSync15(cfgPath, "utf8"));
12281
12433
  } catch {
12282
12434
  return;
12283
12435
  }
@@ -12292,7 +12444,7 @@ function ensureRuntimeCwdTrusted(cwd) {
12292
12444
  cfg.projects = projects;
12293
12445
  const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
12294
12446
  try {
12295
- writeFileSync8(tmp, JSON.stringify(cfg, null, 2));
12447
+ writeFileSync10(tmp, JSON.stringify(cfg, null, 2));
12296
12448
  renameSync5(tmp, cfgPath);
12297
12449
  } catch {
12298
12450
  try {
@@ -12323,13 +12475,13 @@ async function runClaudeUnderTmuxImpl(args) {
12323
12475
  const systemFile = join10(cwd, `system-${runId}.txt`);
12324
12476
  const userFile = join10(cwd, `user-${runId}.txt`);
12325
12477
  const wrapper = join10(cwd, `run-${runId}.sh`);
12326
- writeFileSync8(systemFile, args.systemPrompt);
12327
- writeFileSync8(userFile, args.reminder ? `${args.userPrompt}
12478
+ writeFileSync10(systemFile, args.systemPrompt);
12479
+ writeFileSync10(userFile, args.reminder ? `${args.userPrompt}
12328
12480
 
12329
12481
  ---
12330
12482
 
12331
12483
  ${args.reminder}` : args.userPrompt);
12332
- writeFileSync8(wrapper, `#!/bin/bash
12484
+ writeFileSync10(wrapper, `#!/bin/bash
12333
12485
  SYS="$(cat ${shellEscape(systemFile)})"
12334
12486
  USR="$(cat ${shellEscape(userFile)})"
12335
12487
  exec ${shellEscape(claudeBin)} \\
@@ -12429,7 +12581,7 @@ function snapshotAllTranscripts() {
12429
12581
  function readJsonlCwd(path7, maxLines = 8) {
12430
12582
  let raw;
12431
12583
  try {
12432
- raw = readFileSync13(path7, "utf8");
12584
+ raw = readFileSync15(path7, "utf8");
12433
12585
  } catch {
12434
12586
  return void 0;
12435
12587
  }
@@ -12486,7 +12638,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
12486
12638
  function parseTranscript2(path7, defaultModel) {
12487
12639
  let raw;
12488
12640
  try {
12489
- raw = readFileSync13(path7, "utf8");
12641
+ raw = readFileSync15(path7, "utf8");
12490
12642
  } catch {
12491
12643
  return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
12492
12644
  }
@@ -12561,9 +12713,9 @@ function shellEscape(s) {
12561
12713
  // ../entries/dist/llm-runner.js
12562
12714
  var RUNS_DIR = cclensPath("llm-runs");
12563
12715
  function ensureRunsDir() {
12564
- if (!existsSync10(RUNS_DIR)) {
12716
+ if (!existsSync12(RUNS_DIR)) {
12565
12717
  try {
12566
- mkdirSync10(RUNS_DIR, { recursive: true });
12718
+ mkdirSync11(RUNS_DIR, { recursive: true });
12567
12719
  } catch {
12568
12720
  }
12569
12721
  }
@@ -12594,13 +12746,13 @@ function tracePath(runId) {
12594
12746
  }
12595
12747
  function safeAppend(path7, line) {
12596
12748
  try {
12597
- appendFileSync4(path7, line);
12749
+ appendFileSync5(path7, line);
12598
12750
  } catch {
12599
12751
  }
12600
12752
  }
12601
12753
  function safeWrite(path7, line) {
12602
12754
  try {
12603
- writeFileSync9(path7, line);
12755
+ writeFileSync11(path7, line);
12604
12756
  } catch {
12605
12757
  }
12606
12758
  }
@@ -12989,7 +13141,7 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
12989
13141
 
12990
13142
  // ../entries/dist/budget.js
12991
13143
  init_fs();
12992
- import { appendFileSync as appendFileSync5, readFileSync as readFileSync14, existsSync as existsSync11, mkdirSync as mkdirSync11 } from "node:fs";
13144
+ import { appendFileSync as appendFileSync6, readFileSync as readFileSync16, existsSync as existsSync13, mkdirSync as mkdirSync12 } from "node:fs";
12993
13145
  import { dirname as dirname10 } from "node:path";
12994
13146
  var spendPathCached = null;
12995
13147
  function spendPath() {
@@ -13000,17 +13152,17 @@ function spendPath() {
13000
13152
  }
13001
13153
  function appendSpend(record) {
13002
13154
  const p = spendPath();
13003
- mkdirSync11(dirname10(p), { recursive: true });
13004
- appendFileSync5(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
13155
+ mkdirSync12(dirname10(p), { recursive: true });
13156
+ appendFileSync6(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
13005
13157
  }
13006
13158
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
13007
13159
  const p = spendPath();
13008
- if (!existsSync11(p))
13160
+ if (!existsSync13(p))
13009
13161
  return 0;
13010
13162
  const year = now.getUTCFullYear();
13011
13163
  const month = now.getUTCMonth();
13012
13164
  let total = 0;
13013
- const raw = readFileSync14(p, "utf8");
13165
+ const raw = readFileSync16(p, "utf8");
13014
13166
  for (const line of raw.split("\n")) {
13015
13167
  if (!line)
13016
13168
  continue;
@@ -13032,7 +13184,7 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
13032
13184
 
13033
13185
  // ../entries/dist/pipeline-lock.js
13034
13186
  init_fs();
13035
- import { writeFileSync as writeFileSync10, unlinkSync as unlinkSync4, existsSync as existsSync12, readFileSync as readFileSync15, statSync as statSync7 } from "node:fs";
13187
+ import { writeFileSync as writeFileSync12, unlinkSync as unlinkSync4, existsSync as existsSync14, readFileSync as readFileSync17, statSync as statSync7 } from "node:fs";
13036
13188
  var STALE_MS2 = 60 * 1e3;
13037
13189
  var HEARTBEAT_MS = 30 * 1e3;
13038
13190
  var lockPathCached = null;
@@ -13044,7 +13196,7 @@ function lockPath() {
13044
13196
  return lockPathCached;
13045
13197
  }
13046
13198
  function touchLock() {
13047
- writeFileSync10(lockPath(), String(process.pid), "utf8");
13199
+ writeFileSync12(lockPath(), String(process.pid), "utf8");
13048
13200
  }
13049
13201
  function writeInteractiveLock() {
13050
13202
  touchLock();
@@ -13078,13 +13230,13 @@ function pidAlive(pid) {
13078
13230
  }
13079
13231
  function interactiveLockFresh(nowMs) {
13080
13232
  const p = lockPath();
13081
- if (!existsSync12(p))
13233
+ if (!existsSync14(p))
13082
13234
  return false;
13083
13235
  try {
13084
13236
  const mtime = statSync7(p).mtimeMs;
13085
13237
  if (nowMs - mtime > STALE_MS2)
13086
13238
  return false;
13087
- const pid = Number(readFileSync15(p, "utf8").trim());
13239
+ const pid = Number(readFileSync17(p, "utf8").trim());
13088
13240
  if (!Number.isFinite(pid) || pid <= 0)
13089
13241
  return false;
13090
13242
  if (!pidAlive(pid))
@@ -13099,7 +13251,7 @@ function interactiveLockFresh(nowMs) {
13099
13251
  var THIRTY_MIN_MS = 30 * 60 * 1e3;
13100
13252
 
13101
13253
  // ../entries/dist/settings.js
13102
- import { readFileSync as readFileSync16, writeFileSync as writeFileSync11, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync12, existsSync as existsSync13 } from "node:fs";
13254
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync13, renameSync as renameSync6, chmodSync as chmodSync2, mkdirSync as mkdirSync13, existsSync as existsSync15 } from "node:fs";
13103
13255
  init_fs();
13104
13256
  var DEFAULT_SETTINGS = {
13105
13257
  ai_features: {
@@ -13131,10 +13283,10 @@ function fromDisk(d) {
13131
13283
  }
13132
13284
  function readSettings() {
13133
13285
  const p = settingsPath();
13134
- if (!existsSync13(p))
13286
+ if (!existsSync15(p))
13135
13287
  return DEFAULT_SETTINGS;
13136
13288
  try {
13137
- const raw = readFileSync16(p, "utf8");
13289
+ const raw = readFileSync18(p, "utf8");
13138
13290
  return fromDisk(JSON.parse(raw));
13139
13291
  } catch {
13140
13292
  return DEFAULT_SETTINGS;
@@ -15743,6 +15895,9 @@ async function* runWeekDigestPipeline(monday, opts) {
15743
15895
  }
15744
15896
  }
15745
15897
 
15898
+ // ../entries/dist/credentials.js
15899
+ init_fs();
15900
+
15746
15901
  // src/perception/backfill.ts
15747
15902
  function toLocalDay2(ms) {
15748
15903
  const d = new Date(ms);
@@ -15891,14 +16046,14 @@ async function getUpdateAvailability() {
15891
16046
  if (isDevMode()) return null;
15892
16047
  const latest = await fetchLatestVersion();
15893
16048
  if (latest === null) return {
15894
- current: "0.15.3",
16049
+ current: "0.15.4",
15895
16050
  latest: null,
15896
16051
  updateAvailable: false
15897
16052
  };
15898
16053
  return {
15899
- current: "0.15.3",
16054
+ current: "0.15.4",
15900
16055
  latest,
15901
- updateAvailable: shouldUpdate("0.15.3", latest)
16056
+ updateAvailable: shouldUpdate("0.15.4", latest)
15902
16057
  };
15903
16058
  }
15904
16059
 
@@ -15908,7 +16063,7 @@ var DAEMON_LOG = cclensPath("daemon.log");
15908
16063
  var UPDATE_STATE = cclensPath("daemon-update.json");
15909
16064
  var WATCHDOG_INTERVAL_MS = 5 * 1e3;
15910
16065
  var AUTO_UPDATE_INTERVAL_MS = 6 * 60 * 60 * 1e3;
15911
- mkdirSync13(dirname11(USAGE_LOG3), { recursive: true });
16066
+ mkdirSync14(dirname11(USAGE_LOG3), { recursive: true });
15912
16067
  function log2(level, message) {
15913
16068
  appendDaemonLogLine(level, message);
15914
16069
  }
@@ -15946,14 +16101,14 @@ var perceptionHandle = setInterval(async () => {
15946
16101
  }, PERCEPTION_INTERVAL_MS);
15947
16102
  function readUpdateState() {
15948
16103
  try {
15949
- return JSON.parse(readFileSync17(UPDATE_STATE, "utf8"));
16104
+ return JSON.parse(readFileSync19(UPDATE_STATE, "utf8"));
15950
16105
  } catch {
15951
16106
  return null;
15952
16107
  }
15953
16108
  }
15954
16109
  function writeUpdateState(state) {
15955
16110
  try {
15956
- writeFileSync12(UPDATE_STATE, JSON.stringify(state, null, 2), { mode: 384 });
16111
+ writeFileSync14(UPDATE_STATE, JSON.stringify(state, null, 2), { mode: 384 });
15957
16112
  } catch {
15958
16113
  }
15959
16114
  }
@@ -15998,7 +16153,7 @@ async function runDaemonUpdateCheck() {
15998
16153
  return;
15999
16154
  }
16000
16155
  const entry = cliEntryPath();
16001
- if (!existsSync14(entry)) {
16156
+ if (!existsSync16(entry)) {
16002
16157
  log2("warn", `update check found ${availability.latest}, but CLI entry is missing at ${entry}`);
16003
16158
  return;
16004
16159
  }
@@ -16061,6 +16216,20 @@ async function tick() {
16061
16216
  log2("warn", `${source.kind} poll failed: ${err.message}`);
16062
16217
  }
16063
16218
  }
16219
+ try {
16220
+ const zaiSnapshot = await fetchZaiUsage();
16221
+ appendSnapshot(USAGE_LOG3, zaiSnapshot);
16222
+ log2(
16223
+ "info",
16224
+ `zai snapshot 5h=${zaiSnapshot.five_hour.utilization}% 7d=${zaiSnapshot.seven_day.utilization}%`
16225
+ );
16226
+ } catch (err) {
16227
+ if (err instanceof ZaiApiError && err.code === "no_key") {
16228
+ pruneAgent(USAGE_LOG3, "zai");
16229
+ } else {
16230
+ log2("warn", `zai poll failed: ${err.message}`);
16231
+ }
16232
+ }
16064
16233
  try {
16065
16234
  const snapshot = await fetchUsage();
16066
16235
  appendSnapshot(USAGE_LOG3, snapshot);