fleetlens 1.0.2 → 1.0.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 (147) 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 +2 -2
  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 +2 -2
  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 +3 -1
  16. package/app/apps/web/.next/server/app/api/agent/chats/[id]/events/route.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js +1 -1
  18. package/app/apps/web/.next/server/app/api/agent/chats/[id]/messages/route.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/api/agent/chats/[id]/route.js +3 -1
  20. package/app/apps/web/.next/server/app/api/agent/chats/[id]/route.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/api/agent/chats/[id]/stop/route.js +3 -1
  22. package/app/apps/web/.next/server/app/api/agent/chats/[id]/stop/route.js.nft.json +1 -1
  23. package/app/apps/web/.next/server/app/api/agent/chats/route.js +3 -1
  24. package/app/apps/web/.next/server/app/api/agent/chats/route.js.nft.json +1 -1
  25. package/app/apps/web/.next/server/app/api/agent/index/route.js +1 -1
  26. package/app/apps/web/.next/server/app/api/agent/index/route.js.nft.json +1 -1
  27. package/app/apps/web/.next/server/app/api/agent/mcp/route.js +1 -1
  28. package/app/apps/web/.next/server/app/api/agent/mcp/route.js.nft.json +1 -1
  29. package/app/apps/web/.next/server/app/api/agent/suggestions/route.js +1 -1
  30. package/app/apps/web/.next/server/app/api/agent/suggestions/route.js.nft.json +1 -1
  31. package/app/apps/web/.next/server/app/api/ask/route.js +1 -1
  32. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  33. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +1 -1
  34. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  35. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +1 -1
  36. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  37. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +1 -1
  38. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  39. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +1 -1
  40. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  41. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +1 -1
  42. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js +1 -1
  44. package/app/apps/web/.next/server/app/api/pdf/[key]/route.js.nft.json +1 -1
  45. package/app/apps/web/.next/server/app/api/projects/open-folder/route.js +1 -1
  46. package/app/apps/web/.next/server/app/api/projects/open-folder/route.js.nft.json +1 -1
  47. package/app/apps/web/.next/server/app/api/settings/credentials/route.js +1 -1
  48. package/app/apps/web/.next/server/app/api/settings/credentials/route.js.nft.json +1 -1
  49. package/app/apps/web/.next/server/app/api/settings/route.js +1 -1
  50. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  51. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js +1 -1
  52. package/app/apps/web/.next/server/app/api/team/onboarding/start/route.js.nft.json +1 -1
  53. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js +1 -1
  54. package/app/apps/web/.next/server/app/api/team/sync-projects/route.js.nft.json +1 -1
  55. package/app/apps/web/.next/server/app/changelog/page.js +2 -2
  56. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  57. package/app/apps/web/.next/server/app/day/[date]/page.js +2 -2
  58. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  59. package/app/apps/web/.next/server/app/day/page.js +2 -2
  60. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  61. package/app/apps/web/.next/server/app/digest/[date]/page.js +2 -2
  62. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  63. package/app/apps/web/.next/server/app/digest/page.js +2 -2
  64. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  65. package/app/apps/web/.next/server/app/insights/[key]/page.js +2 -2
  66. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  67. package/app/apps/web/.next/server/app/insights/page.js +2 -2
  68. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  69. package/app/apps/web/.next/server/app/page.js +2 -2
  70. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  71. package/app/apps/web/.next/server/app/parallelism/page.js +2 -2
  72. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  73. package/app/apps/web/.next/server/app/print/[key]/page.js +2 -2
  74. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  75. package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
  76. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  77. package/app/apps/web/.next/server/app/projects/page.js +2 -2
  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 +2 -2
  80. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  81. package/app/apps/web/.next/server/app/sessions/[id]/page.js +2 -2
  82. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  83. package/app/apps/web/.next/server/app/sessions/page.js +2 -2
  84. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  85. package/app/apps/web/.next/server/app/settings/page.js +2 -2
  86. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  87. package/app/apps/web/.next/server/app/team/onboarding/page.js +2 -2
  88. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  89. package/app/apps/web/.next/server/app/team/page.js +2 -2
  90. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  91. package/app/apps/web/.next/server/app/usage/page.js +2 -2
  92. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  93. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__038-.1r._.js → [root-of-the-server]__0-09rjv._.js} +2 -2
  94. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0_5tf-2._.js → [root-of-the-server]__01oercw._.js} +5 -5
  95. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02.51sr._.js +1 -1
  96. package/app/apps/web/.next/server/chunks/[root-of-the-server]__057w7kr._.js +28 -0
  97. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0pirsh0._.js → [root-of-the-server]__07b5796._.js} +2 -2
  98. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__02puo0u._.js → [root-of-the-server]__07xaqv3._.js} +2 -2
  99. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__06xto5z._.js → [root-of-the-server]__08c24et._.js} +2 -2
  100. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0mvl0qn._.js → [root-of-the-server]__08m2h38._.js} +2 -2
  101. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0mx_9mb._.js → [root-of-the-server]__0c7ght_._.js} +2 -2
  102. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__12iid50._.js → [root-of-the-server]__0l5i8nk._.js} +2 -2
  103. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__04g-b-m._.js → [root-of-the-server]__0mcer3z._.js} +2 -2
  104. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0o9lsie._.js +30 -0
  105. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0367vbv._.js → [root-of-the-server]__0ozooam._.js} +2 -2
  106. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0uf_ch4._.js +28 -0
  107. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0uiom2m._.js +28 -0
  108. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__096_llw._.js → [root-of-the-server]__0usaajs._.js} +2 -2
  109. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__06irs4z._.js → [root-of-the-server]__0zyh554._.js} +2 -2
  110. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0gvw6dk._.js → [root-of-the-server]__0~4wgaf._.js} +2 -2
  111. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0~~bpcw._.js +3 -0
  112. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__01~cgp8._.js → [root-of-the-server]__10.g-w1._.js} +2 -2
  113. package/app/apps/web/.next/server/chunks/[root-of-the-server]__12vjv4c._.js +28 -0
  114. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +19 -19
  115. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  116. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  117. package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
  118. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  119. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.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/middleware-build-manifest.js +3 -3
  122. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  123. package/app/apps/web/.next/server/pages/500.html +1 -1
  124. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  125. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  126. package/app/apps/web/.next/static/chunks/0c89~zhm.xoni.js +1 -0
  127. package/app/apps/web/.next/static/chunks/0szn9z03gip~_.js +14 -0
  128. package/app/apps/web/app/api/ask/route.ts +8 -2
  129. package/app/apps/web/lib/agent/run.ts +11 -2
  130. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  131. package/app/apps/web/package.json +1 -1
  132. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  133. package/dist/daemon-worker.js +159 -55
  134. package/dist/index.js +229 -113
  135. package/menubar/Fleetlens.app/Contents/Info.plist +2 -2
  136. package/menubar/Fleetlens.app/Contents/MacOS/FleetlensMenubar +0 -0
  137. package/package.json +1 -1
  138. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02faosk._.js +0 -30
  139. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02petpy._.js +0 -3
  140. package/app/apps/web/.next/server/chunks/[root-of-the-server]__09cgmam._.js +0 -28
  141. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0tk8p3d._.js +0 -28
  142. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0u6pamj._.js +0 -28
  143. package/app/apps/web/.next/server/chunks/[root-of-the-server]__12jomao._.js +0 -28
  144. package/app/apps/web/.next/static/chunks/0dqhn7-3.038l.js +0 -14
  145. /package/app/apps/web/.next/static/{zyhoVMC9iNC5vofPFRY6z → Z2JhhQdyMdGTIYOOPolIJ}/_buildManifest.js +0 -0
  146. /package/app/apps/web/.next/static/{zyhoVMC9iNC5vofPFRY6z → Z2JhhQdyMdGTIYOOPolIJ}/_clientMiddlewareManifest.js +0 -0
  147. /package/app/apps/web/.next/static/{zyhoVMC9iNC5vofPFRY6z → Z2JhhQdyMdGTIYOOPolIJ}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -2848,6 +2848,36 @@ function emptyUsage() {
2848
2848
  function previewOf(text) {
2849
2849
  return text.replace(/\s+/g, " ").trim().slice(0, 200);
2850
2850
  }
2851
+ function stripCodexMemCitation(text) {
2852
+ const cut = text.search(/<oai-mem-citation\b/i);
2853
+ return (cut >= 0 ? text.slice(0, cut) : text).trim();
2854
+ }
2855
+ function normalizeCodexAgentBody(text) {
2856
+ return stripCodexMemCitation(text);
2857
+ }
2858
+ function agentEventText(ev) {
2859
+ for (const b of ev.blocks) {
2860
+ if (b?.type === "text" && typeof b.text === "string")
2861
+ return b.text;
2862
+ }
2863
+ return ev.preview ?? "";
2864
+ }
2865
+ function lastAgentEventIndex(events) {
2866
+ for (let i = events.length - 1; i >= 0; i--) {
2867
+ if (events[i].role === "agent")
2868
+ return i;
2869
+ }
2870
+ return -1;
2871
+ }
2872
+ function sameCodexAgentBody(a, b) {
2873
+ const na = normalizeCodexAgentBody(a);
2874
+ const nb = normalizeCodexAgentBody(b);
2875
+ if (!na && !nb)
2876
+ return true;
2877
+ if (!na || !nb)
2878
+ return false;
2879
+ return na === nb;
2880
+ }
2851
2881
  function parseRollout(file, lines) {
2852
2882
  const events = [];
2853
2883
  let firstTimestamp;
@@ -2939,6 +2969,27 @@ function parseRollout(file, lines) {
2939
2969
  if (type === "event_msg" && subtype === "agent_message") {
2940
2970
  const text = typeof payload.message === "string" ? payload.message : "";
2941
2971
  const preview = previewOf(text);
2972
+ const lastIdx = lastAgentEventIndex(events);
2973
+ if (lastIdx >= 0) {
2974
+ const prev = events[lastIdx];
2975
+ if (prev.rawType === "response_item/message" && sameCodexAgentBody(agentEventText(prev), text)) {
2976
+ events[lastIdx] = {
2977
+ ...prev,
2978
+ timestamp: ts ?? prev.timestamp,
2979
+ rawType: "event_msg/agent_message",
2980
+ preview,
2981
+ blocks: text ? [{ type: "text", text }] : [],
2982
+ model,
2983
+ raw: obj
2984
+ };
2985
+ if (text)
2986
+ lastAgentPreview = preview;
2987
+ continue;
2988
+ }
2989
+ if (prev.rawType === "event_msg/agent_message" && sameCodexAgentBody(agentEventText(prev), text)) {
2990
+ continue;
2991
+ }
2992
+ }
2942
2993
  if (text)
2943
2994
  lastAgentPreview = preview;
2944
2995
  events.push({
@@ -2971,6 +3022,10 @@ function parseRollout(file, lines) {
2971
3022
  if (type === "response_item" && subtype === "message" && payload.role === "assistant") {
2972
3023
  const items = payload.content ?? [];
2973
3024
  const text = items.map((c) => typeof c.text === "string" ? c.text : "").join("\n").trim();
3025
+ const lastIdx = lastAgentEventIndex(events);
3026
+ if (lastIdx >= 0 && sameCodexAgentBody(agentEventText(events[lastIdx]), text)) {
3027
+ continue;
3028
+ }
2974
3029
  const preview = previewOf(text);
2975
3030
  if (text)
2976
3031
  lastAgentPreview = preview;
@@ -6243,9 +6298,9 @@ function onDiskVersion() {
6243
6298
  try {
6244
6299
  const here = dirname3(fileURLToPath(import.meta.url));
6245
6300
  const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
6246
- return pkg.version ?? "1.0.2";
6301
+ return pkg.version ?? "1.0.4";
6247
6302
  } catch {
6248
- return "1.0.2";
6303
+ return "1.0.4";
6249
6304
  }
6250
6305
  }
6251
6306
  function getServerStatus() {
@@ -6257,7 +6312,7 @@ function getServerStatus() {
6257
6312
  return { running: false };
6258
6313
  }
6259
6314
  function isServerStale(status2) {
6260
- return status2.running === true && status2.version !== "1.0.2";
6315
+ return status2.running === true && status2.version !== "1.0.4";
6261
6316
  }
6262
6317
  async function ensureCurrentServer(opts = {}) {
6263
6318
  const status2 = getServerStatus();
@@ -6718,9 +6773,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
6718
6773
  console.warn(
6719
6774
  ` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
6720
6775
  );
6721
- } else if (verify.installedVersion !== "1.0.2") {
6776
+ } else if (verify.installedVersion !== "1.0.4") {
6722
6777
  console.log(
6723
- ` \u2192 This process is still running ${"1.0.2"}. Next invocation will use ${verify.installedVersion}.`
6778
+ ` \u2192 This process is still running ${"1.0.4"}. Next invocation will use ${verify.installedVersion}.`
6724
6779
  );
6725
6780
  }
6726
6781
  }
@@ -6755,14 +6810,14 @@ async function getUpdateAvailability() {
6755
6810
  if (isDevMode()) return null;
6756
6811
  const latest = await fetchLatestVersion();
6757
6812
  if (latest === null) return {
6758
- current: "1.0.2",
6813
+ current: "1.0.4",
6759
6814
  latest: null,
6760
6815
  updateAvailable: false
6761
6816
  };
6762
6817
  return {
6763
- current: "1.0.2",
6818
+ current: "1.0.4",
6764
6819
  latest,
6765
- updateAvailable: shouldUpdate("1.0.2", latest)
6820
+ updateAvailable: shouldUpdate("1.0.4", latest)
6766
6821
  };
6767
6822
  }
6768
6823
  async function checkForUpdate() {
@@ -6852,7 +6907,7 @@ async function restartServices(state) {
6852
6907
  }
6853
6908
  async function forceUpdate() {
6854
6909
  const latest = await fetchLatestVersion();
6855
- const current = "1.0.2";
6910
+ const current = "1.0.4";
6856
6911
  if (latest === null) {
6857
6912
  console.error("Could not reach npm registry. Check your network.");
6858
6913
  process.exit(1);
@@ -7273,7 +7328,7 @@ async function status() {
7273
7328
  }
7274
7329
  if (isServerStale(server)) {
7275
7330
  console.log(
7276
- ` \u26A0 serving stale ${ver} (CLI is ${"1.0.2"}) \u2014 run 'fleetlens start' to restart on the current version`
7331
+ ` \u26A0 serving stale ${ver} (CLI is ${"1.0.4"}) \u2014 run 'fleetlens start' to restart on the current version`
7277
7332
  );
7278
7333
  }
7279
7334
  } else {
@@ -14522,10 +14577,58 @@ RESPOND WITH ONLY VALID JSON (no prose, no code fence):
14522
14577
  }
14523
14578
  });
14524
14579
 
14525
- // ../entries/dist/tmux-runner.js
14526
- import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as existsSync13, readdirSync as readdirSync3, realpathSync as realpathSync5, readFileSync as readFileSync15, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
14527
- import { join as join11 } from "node:path";
14580
+ // ../entries/dist/claude-bin.js
14581
+ import { existsSync as existsSync13 } from "node:fs";
14582
+ import { join as join11, dirname as dirname10, delimiter } from "node:path";
14528
14583
  import { homedir as homedir5 } from "node:os";
14584
+ function resolveClaudeBin(opts = {}) {
14585
+ const env = opts.env ?? process.env;
14586
+ const home = opts.home ?? homedir5();
14587
+ const execPath = opts.execPath ?? process.execPath;
14588
+ const exists = opts.exists ?? existsSync13;
14589
+ for (const dir of (env.PATH ?? "").split(delimiter)) {
14590
+ if (!dir)
14591
+ continue;
14592
+ const onPath = join11(dir, "claude");
14593
+ if (exists(onPath))
14594
+ return onPath;
14595
+ }
14596
+ return [
14597
+ join11(home, ".local", "bin", "claude"),
14598
+ // native installer
14599
+ join11(home, ".claude", "local", "claude"),
14600
+ // legacy local install
14601
+ join11(dirname10(execPath), "claude"),
14602
+ // npm -g, beside the node running us
14603
+ "/opt/homebrew/bin/claude",
14604
+ "/usr/local/bin/claude"
14605
+ ].find(exists);
14606
+ }
14607
+ function claudeSpawnEnv(bin, env = process.env, execPath = process.execPath) {
14608
+ const parts = (env.PATH ?? "").split(delimiter).filter(Boolean);
14609
+ for (const dir of [dirname10(execPath), dirname10(bin)]) {
14610
+ if (!parts.includes(dir))
14611
+ parts.unshift(dir);
14612
+ }
14613
+ return { ...env, PATH: parts.join(delimiter) };
14614
+ }
14615
+ var ClaudeBinNotFoundError;
14616
+ var init_claude_bin = __esm({
14617
+ "../entries/dist/claude-bin.js"() {
14618
+ "use strict";
14619
+ ClaudeBinNotFoundError = class extends Error {
14620
+ constructor() {
14621
+ super("claude CLI not found. Looked on PATH and in ~/.local/bin, ~/.claude/local, the npm global bin, homebrew, and /usr/local/bin. Install it, or if Fleetlens was started at login, restart it from a terminal: fleetlens stop && fleetlens start");
14622
+ this.name = "ClaudeBinNotFoundError";
14623
+ }
14624
+ };
14625
+ }
14626
+ });
14627
+
14628
+ // ../entries/dist/tmux-runner.js
14629
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync9, existsSync as existsSync14, readdirSync as readdirSync3, realpathSync as realpathSync5, readFileSync as readFileSync15, unlinkSync as unlinkSync3, renameSync as renameSync4 } from "node:fs";
14630
+ import { join as join12 } from "node:path";
14631
+ import { homedir as homedir6 } from "node:os";
14529
14632
  import { spawnSync as spawnSync2 } from "node:child_process";
14530
14633
  function which(bin) {
14531
14634
  const r = spawnSync2("/usr/bin/env", ["which", bin], { encoding: "utf8" });
@@ -14536,18 +14639,18 @@ function which(bin) {
14536
14639
  function tmuxRunnerAvailable() {
14537
14640
  if (!which("tmux"))
14538
14641
  return { ok: false, reason: "tmux not on PATH" };
14539
- if (!which("claude"))
14540
- return { ok: false, reason: "claude not on PATH" };
14642
+ if (!resolveClaudeBin())
14643
+ return { ok: false, reason: "claude CLI not found" };
14541
14644
  return { ok: true };
14542
14645
  }
14543
14646
  function runtimeCwd() {
14544
- const dir = join11(homedir5(), ".cclens", "runtime");
14545
- if (!existsSync13(dir))
14647
+ const dir = join12(homedir6(), ".cclens", "runtime");
14648
+ if (!existsSync14(dir))
14546
14649
  mkdirSync8(dir, { recursive: true });
14547
14650
  return realpathSync5(dir);
14548
14651
  }
14549
14652
  function ensureRuntimeCwdTrusted(cwd) {
14550
- const cfgPath = join11(homedir5(), ".claude.json");
14653
+ const cfgPath = join12(homedir6(), ".claude.json");
14551
14654
  let cfg;
14552
14655
  try {
14553
14656
  cfg = JSON.parse(readFileSync15(cfgPath, "utf8"));
@@ -14583,18 +14686,18 @@ async function runClaudeUnderTmuxImpl(args2) {
14583
14686
  const tmuxBin = args2.tmuxBin ?? which("tmux");
14584
14687
  if (!tmuxBin)
14585
14688
  throw new TmuxUnavailableError("tmux not on PATH");
14586
- const claudeBin = args2.claudeBin ?? which("claude");
14689
+ const claudeBin = args2.claudeBin ?? resolveClaudeBin();
14587
14690
  if (!claudeBin)
14588
- throw new TmuxUnavailableError("claude not on PATH");
14691
+ throw new TmuxUnavailableError("claude CLI not found");
14589
14692
  if (args2.signal?.aborted)
14590
14693
  throw new TmuxRunError("aborted before spawn");
14591
14694
  const cwd = runtimeCwd();
14592
14695
  ensureRuntimeCwdTrusted(cwd);
14593
14696
  const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
14594
14697
  const sessionName = `cclens-${runId}`;
14595
- const systemFile = join11(cwd, `system-${runId}.txt`);
14596
- const userFile = join11(cwd, `user-${runId}.txt`);
14597
- const wrapper = join11(cwd, `run-${runId}.sh`);
14698
+ const systemFile = join12(cwd, `system-${runId}.txt`);
14699
+ const userFile = join12(cwd, `user-${runId}.txt`);
14700
+ const wrapper = join12(cwd, `run-${runId}.sh`);
14598
14701
  writeFileSync9(systemFile, args2.systemPrompt);
14599
14702
  writeFileSync9(userFile, args2.reminder ? `${args2.userPrompt}
14600
14703
 
@@ -14683,7 +14786,7 @@ function snapshotAllTranscripts() {
14683
14786
  return out;
14684
14787
  }
14685
14788
  for (const sub of subs) {
14686
- const dir = join11(root, sub);
14789
+ const dir = join12(root, sub);
14687
14790
  let files;
14688
14791
  try {
14689
14792
  files = readdirSync3(dir);
@@ -14692,7 +14795,7 @@ function snapshotAllTranscripts() {
14692
14795
  }
14693
14796
  for (const f of files) {
14694
14797
  if (f.endsWith(".jsonl"))
14695
- out.add(join11(dir, f));
14798
+ out.add(join12(dir, f));
14696
14799
  }
14697
14800
  }
14698
14801
  return out;
@@ -14733,7 +14836,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
14733
14836
  subs = [];
14734
14837
  }
14735
14838
  for (const sub of subs) {
14736
- const dir = join11(root, sub);
14839
+ const dir = join12(root, sub);
14737
14840
  let files;
14738
14841
  try {
14739
14842
  files = readdirSync3(dir);
@@ -14743,7 +14846,7 @@ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs,
14743
14846
  for (const f of files) {
14744
14847
  if (!f.endsWith(".jsonl"))
14745
14848
  continue;
14746
- const full = join11(dir, f);
14849
+ const full = join12(dir, f);
14747
14850
  if (existingBefore.has(full))
14748
14851
  continue;
14749
14852
  if (readJsonlCwd(full) === targetCwd)
@@ -14817,7 +14920,7 @@ function cleanup(cwd, runId, tmuxBin, sessionName, transcriptPath) {
14817
14920
  }
14818
14921
  for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
14819
14922
  try {
14820
- unlinkSync3(join11(cwd, f));
14923
+ unlinkSync3(join12(cwd, f));
14821
14924
  } catch {
14822
14925
  }
14823
14926
  }
@@ -14832,6 +14935,7 @@ var TmuxUnavailableError, TmuxRunError, mutex, PROJECTS_ROOT;
14832
14935
  var init_tmux_runner = __esm({
14833
14936
  "../entries/dist/tmux-runner.js"() {
14834
14937
  "use strict";
14938
+ init_claude_bin();
14835
14939
  TmuxUnavailableError = class extends Error {
14836
14940
  constructor(message) {
14837
14941
  super(message);
@@ -14845,17 +14949,17 @@ var init_tmux_runner = __esm({
14845
14949
  }
14846
14950
  };
14847
14951
  mutex = Promise.resolve();
14848
- PROJECTS_ROOT = () => join11(homedir5(), ".claude", "projects");
14952
+ PROJECTS_ROOT = () => join12(homedir6(), ".claude", "projects");
14849
14953
  }
14850
14954
  });
14851
14955
 
14852
14956
  // ../entries/dist/llm-runner.js
14853
14957
  import { spawn as spawn4 } from "node:child_process";
14854
- import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync10, existsSync as existsSync14 } from "node:fs";
14855
- import { join as join12 } from "node:path";
14958
+ import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync10, existsSync as existsSync15 } from "node:fs";
14959
+ import { join as join13 } from "node:path";
14856
14960
  import { randomUUID } from "node:crypto";
14857
14961
  function ensureRunsDir() {
14858
- if (!existsSync14(RUNS_DIR)) {
14962
+ if (!existsSync15(RUNS_DIR)) {
14859
14963
  try {
14860
14964
  mkdirSync9(RUNS_DIR, { recursive: true });
14861
14965
  } catch {
@@ -14884,7 +14988,7 @@ function newRunId(kind) {
14884
14988
  return `${ts}_${kind}_${short}`;
14885
14989
  }
14886
14990
  function tracePath(runId) {
14887
- return join12(RUNS_DIR, `${runId}.jsonl`);
14991
+ return join13(RUNS_DIR, `${runId}.jsonl`);
14888
14992
  }
14889
14993
  function safeAppend(path11, line) {
14890
14994
  try {
@@ -15027,7 +15131,14 @@ function runClaudePrintMode(args2) {
15027
15131
  "--append-system-prompt",
15028
15132
  args2.systemPrompt
15029
15133
  ];
15030
- const proc = spawn4("claude", claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: { ...process.env } });
15134
+ const claudeBin = resolveClaudeBin();
15135
+ if (!claudeBin) {
15136
+ const err = new ClaudeBinNotFoundError();
15137
+ safeAppend(trace, JSON.stringify({ _meta: { type: "spawn_error", run_id: runId, ts: (/* @__PURE__ */ new Date()).toISOString(), error: err.message } }) + "\n");
15138
+ reject(err);
15139
+ return;
15140
+ }
15141
+ const proc = spawn4(claudeBin, claudeArgs, { stdio: ["pipe", "pipe", "pipe"], env: claudeSpawnEnv(claudeBin) });
15031
15142
  safeAppend(trace, JSON.stringify({ _meta: { type: "spawned", run_id: runId, pid: proc.pid } }) + "\n");
15032
15143
  const stdinPayload = args2.reminder ? `${args2.userPrompt}
15033
15144
 
@@ -15128,6 +15239,7 @@ var init_llm_runner = __esm({
15128
15239
  "../entries/dist/llm-runner.js"() {
15129
15240
  "use strict";
15130
15241
  init_fs();
15242
+ init_claude_bin();
15131
15243
  init_tmux_runner();
15132
15244
  RUNS_DIR = cclensPath("llm-runs");
15133
15245
  }
@@ -15300,8 +15412,8 @@ var init_enrich2 = __esm({
15300
15412
  });
15301
15413
 
15302
15414
  // ../entries/dist/budget.js
15303
- import { appendFileSync as appendFileSync4, readFileSync as readFileSync16, existsSync as existsSync15, mkdirSync as mkdirSync10 } from "node:fs";
15304
- import { dirname as dirname10 } from "node:path";
15415
+ import { appendFileSync as appendFileSync4, readFileSync as readFileSync16, existsSync as existsSync16, mkdirSync as mkdirSync10 } from "node:fs";
15416
+ import { dirname as dirname11 } from "node:path";
15305
15417
  function spendPath() {
15306
15418
  if (spendPathCached)
15307
15419
  return spendPathCached;
@@ -15313,12 +15425,12 @@ function __setSpendPathForTest(path11) {
15313
15425
  }
15314
15426
  function appendSpend(record) {
15315
15427
  const p = spendPath();
15316
- mkdirSync10(dirname10(p), { recursive: true });
15428
+ mkdirSync10(dirname11(p), { recursive: true });
15317
15429
  appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
15318
15430
  }
15319
15431
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
15320
15432
  const p = spendPath();
15321
- if (!existsSync15(p))
15433
+ if (!existsSync16(p))
15322
15434
  return 0;
15323
15435
  const year = now.getUTCFullYear();
15324
15436
  const month2 = now.getUTCMonth();
@@ -15352,7 +15464,7 @@ var init_budget = __esm({
15352
15464
  });
15353
15465
 
15354
15466
  // ../entries/dist/pipeline-lock.js
15355
- import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, existsSync as existsSync16, readFileSync as readFileSync17, statSync as statSync3 } from "node:fs";
15467
+ import { writeFileSync as writeFileSync11, unlinkSync as unlinkSync4, existsSync as existsSync17, readFileSync as readFileSync17, statSync as statSync3 } from "node:fs";
15356
15468
  function lockPath() {
15357
15469
  if (lockPathCached)
15358
15470
  return lockPathCached;
@@ -15397,7 +15509,7 @@ function pidAlive(pid) {
15397
15509
  }
15398
15510
  function interactiveLockFresh(nowMs) {
15399
15511
  const p = lockPath();
15400
- if (!existsSync16(p))
15512
+ if (!existsSync17(p))
15401
15513
  return false;
15402
15514
  try {
15403
15515
  const mtime = statSync3(p).mtimeMs;
@@ -15509,8 +15621,8 @@ var init_queue = __esm({
15509
15621
  });
15510
15622
 
15511
15623
  // ../entries/dist/settings.js
15512
- import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync17 } from "node:fs";
15513
- import { dirname as dirname11 } from "node:path";
15624
+ import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync18 } from "node:fs";
15625
+ import { dirname as dirname12 } from "node:path";
15514
15626
  function settingsPath() {
15515
15627
  if (settingsPathCached)
15516
15628
  return settingsPathCached;
@@ -15545,7 +15657,7 @@ function fromDisk(d) {
15545
15657
  }
15546
15658
  function readSettings() {
15547
15659
  const p = settingsPath();
15548
- if (!existsSync17(p))
15660
+ if (!existsSync18(p))
15549
15661
  return DEFAULT_SETTINGS;
15550
15662
  try {
15551
15663
  const raw = readFileSync18(p, "utf8");
@@ -15556,7 +15668,7 @@ function readSettings() {
15556
15668
  }
15557
15669
  function writeSettings(s) {
15558
15670
  const p = settingsPath();
15559
- mkdirSync11(dirname11(p), { recursive: true });
15671
+ mkdirSync11(dirname12(p), { recursive: true });
15560
15672
  const tmp = `${p}.tmp`;
15561
15673
  writeFileSync12(tmp, JSON.stringify(toDisk(s), null, 2), { encoding: "utf8" });
15562
15674
  if (process.platform !== "win32") {
@@ -18738,8 +18850,8 @@ var init_digest_month_pipeline = __esm({
18738
18850
  });
18739
18851
 
18740
18852
  // ../entries/dist/credentials.js
18741
- import { writeFileSync as writeFileSync13, readFileSync as readFileSync19, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync18, unlinkSync as unlinkSync5 } from "node:fs";
18742
- import { dirname as dirname12 } from "node:path";
18853
+ import { writeFileSync as writeFileSync13, readFileSync as readFileSync19, renameSync as renameSync6, chmodSync as chmodSync3, mkdirSync as mkdirSync12, existsSync as existsSync19, unlinkSync as unlinkSync5 } from "node:fs";
18854
+ import { dirname as dirname13 } from "node:path";
18743
18855
  async function fetchZaiUsage(candidate) {
18744
18856
  const key = candidate.trim();
18745
18857
  if (!key)
@@ -18809,7 +18921,7 @@ function credentialsPath() {
18809
18921
  }
18810
18922
  function readCredentials() {
18811
18923
  const p = credentialsPath();
18812
- if (!existsSync18(p))
18924
+ if (!existsSync19(p))
18813
18925
  return {};
18814
18926
  try {
18815
18927
  const raw = readFileSync19(p, "utf8");
@@ -18835,7 +18947,7 @@ function writeZaiKey(apiKey) {
18835
18947
  const store = readCredentials();
18836
18948
  store.zai = { ...store.zai ?? {}, apiKey };
18837
18949
  const p = credentialsPath();
18838
- mkdirSync12(dirname12(p), { recursive: true });
18950
+ mkdirSync12(dirname13(p), { recursive: true });
18839
18951
  const tmp = `${p}.tmp`;
18840
18952
  writeFileSync13(tmp, JSON.stringify(store, null, 2), { encoding: "utf8" });
18841
18953
  if (process.platform !== "win32") {
@@ -18876,6 +18988,7 @@ var init_credentials = __esm({
18876
18988
  // ../entries/dist/node.js
18877
18989
  var node_exports = {};
18878
18990
  __export(node_exports, {
18991
+ ClaudeBinNotFoundError: () => ClaudeBinNotFoundError,
18879
18992
  DIGEST_DAY_SYSTEM_PROMPT: () => DIGEST_DAY_SYSTEM_PROMPT,
18880
18993
  DIGEST_MONTH_SYSTEM_PROMPT: () => DIGEST_MONTH_SYSTEM_PROMPT,
18881
18994
  DIGEST_WEEK_SYSTEM_PROMPT: () => DIGEST_WEEK_SYSTEM_PROMPT,
@@ -18898,6 +19011,7 @@ __export(node_exports, {
18898
19011
  buildEnrichmentUserPrompt: () => buildEnrichmentUserPrompt,
18899
19012
  buildMonthDigestUserPrompt: () => buildMonthDigestUserPrompt,
18900
19013
  buildWeekDigestUserPrompt: () => buildWeekDigestUserPrompt,
19014
+ claudeSpawnEnv: () => claudeSpawnEnv,
18901
19015
  computeCostUsd: () => computeCostUsd,
18902
19016
  computeDaySignals: () => computeDaySignals,
18903
19017
  computeInteractionGrammar: () => computeInteractionGrammar,
@@ -18927,6 +19041,7 @@ __export(node_exports, {
18927
19041
  readSettings: () => readSettings,
18928
19042
  readWeekDigest: () => readWeekDigest,
18929
19043
  removeInteractiveLock: () => removeInteractiveLock,
19044
+ resolveClaudeBin: () => resolveClaudeBin,
18930
19045
  runClaudeSubprocess: () => runClaudeSubprocess,
18931
19046
  runClaudeUnderTmux: () => runClaudeUnderTmux,
18932
19047
  runDayDigestPipeline: () => runDayDigestPipeline,
@@ -18966,6 +19081,7 @@ var init_node = __esm({
18966
19081
  init_digest_month_pipeline();
18967
19082
  init_tmux_runner();
18968
19083
  init_llm_runner();
19084
+ init_claude_bin();
18969
19085
  init_digest_fs();
18970
19086
  init_credentials();
18971
19087
  }
@@ -19442,9 +19558,9 @@ var menubar_exports = {};
19442
19558
  __export(menubar_exports, {
19443
19559
  menubar: () => menubar
19444
19560
  });
19445
- import { existsSync as existsSync19, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync14, realpathSync as realpathSync6 } from "node:fs";
19446
- import { homedir as homedir6 } from "node:os";
19447
- import { join as join13, dirname as dirname13 } from "node:path";
19561
+ import { existsSync as existsSync20, mkdirSync as mkdirSync13, cpSync, rmSync as rmSync2, readdirSync as readdirSync4, writeFileSync as writeFileSync14, realpathSync as realpathSync6 } from "node:fs";
19562
+ import { homedir as homedir7 } from "node:os";
19563
+ import { join as join14, dirname as dirname14 } from "node:path";
19448
19564
  import { fileURLToPath as fileURLToPath3 } from "node:url";
19449
19565
  import { execFile as execFile2 } from "node:child_process";
19450
19566
  import { promisify as promisify2 } from "node:util";
@@ -19452,8 +19568,8 @@ function isMac2() {
19452
19568
  return process.platform === "darwin";
19453
19569
  }
19454
19570
  function bundledAppPath() {
19455
- const here = dirname13(fileURLToPath3(import.meta.url));
19456
- return join13(here, "..", "menubar", APP_BUNDLE);
19571
+ const here = dirname14(fileURLToPath3(import.meta.url));
19572
+ return join14(here, "..", "menubar", APP_BUNDLE);
19457
19573
  }
19458
19574
  function resolveScriptPath2() {
19459
19575
  const argv1 = process.argv[1] ?? "";
@@ -19474,10 +19590,10 @@ function writeCliLaunchFile() {
19474
19590
  }
19475
19591
  }
19476
19592
  function installedAppPath() {
19477
- return join13(homedir6(), "Applications", APP_BUNDLE);
19593
+ return join14(homedir7(), "Applications", APP_BUNDLE);
19478
19594
  }
19479
19595
  function legacyInstalledAppPath() {
19480
- return join13(homedir6(), "Applications", LEGACY_APP_BUNDLE);
19596
+ return join14(homedir7(), "Applications", LEGACY_APP_BUNDLE);
19481
19597
  }
19482
19598
  async function isRunning() {
19483
19599
  try {
@@ -19516,14 +19632,14 @@ async function installMenubar(opts) {
19516
19632
  return;
19517
19633
  }
19518
19634
  const src = bundledAppPath();
19519
- if (!existsSync19(src)) {
19635
+ if (!existsSync20(src)) {
19520
19636
  console.error(
19521
19637
  `Bundled widget not found at ${src}.
19522
19638
  This install was probably built without the menubar artifact. Run \`bash apps/menubar/build-app.sh && cp -R apps/menubar/dist/Fleetlens.app packages/cli/menubar/\` and rebuild.`
19523
19639
  );
19524
19640
  process.exit(1);
19525
19641
  }
19526
- const destDir = join13(homedir6(), "Applications");
19642
+ const destDir = join14(homedir7(), "Applications");
19527
19643
  mkdirSync13(destDir, { recursive: true });
19528
19644
  const dest = installedAppPath();
19529
19645
  if (await isRunning()) {
@@ -19562,7 +19678,7 @@ async function uninstallMenubar() {
19562
19678
  await new Promise((r) => setTimeout(r, 300));
19563
19679
  }
19564
19680
  const dest = installedAppPath();
19565
- if (existsSync19(dest)) {
19681
+ if (existsSync20(dest)) {
19566
19682
  rmSync2(dest, { recursive: true, force: true });
19567
19683
  console.log(`Removed ${dest}`);
19568
19684
  } else {
@@ -19577,7 +19693,7 @@ async function openMenubar() {
19577
19693
  return;
19578
19694
  }
19579
19695
  const dest = installedAppPath();
19580
- if (!existsSync19(dest)) {
19696
+ if (!existsSync20(dest)) {
19581
19697
  console.log("Widget not installed yet. Run `fleetlens menubar install` first.");
19582
19698
  return;
19583
19699
  }
@@ -19594,15 +19710,15 @@ async function statusMenubar() {
19594
19710
  return;
19595
19711
  }
19596
19712
  const dest = installedAppPath();
19597
- const installed = existsSync19(dest);
19713
+ const installed = existsSync20(dest);
19598
19714
  const running = await isRunning();
19599
- const bundled = existsSync19(bundledAppPath());
19715
+ const bundled = existsSync20(bundledAppPath());
19600
19716
  console.log(`Menu bar widget: ${installed ? "installed" : "not installed"}${installed ? ` (${dest})` : ""}`);
19601
19717
  console.log(`Running: ${running ? "yes" : "no"}`);
19602
19718
  console.log(`Bundled in CLI: ${bundled ? "yes" : "no \u2014 this build ships without the widget"}`);
19603
19719
  if (installed) {
19604
19720
  try {
19605
- const apps = readdirSync4(join13(homedir6(), "Applications"));
19721
+ const apps = readdirSync4(join14(homedir7(), "Applications"));
19606
19722
  const ours = apps.find((a) => a === APP_BUNDLE);
19607
19723
  console.log(`App bundle: ${ours ? "present in ~/Applications" : "missing"}`);
19608
19724
  } catch {
@@ -19688,7 +19804,7 @@ var init_config = __esm({
19688
19804
 
19689
19805
  // src/perception/build-entries.ts
19690
19806
  import { statSync as statSync4, readFileSync as readFileSync20 } from "node:fs";
19691
- import { basename as basename2, dirname as dirname14 } from "node:path";
19807
+ import { basename as basename2, dirname as dirname15 } from "node:path";
19692
19808
  function decodeProjectDirName(projectDir) {
19693
19809
  if (projectDir.startsWith("-")) {
19694
19810
  return "/" + projectDir.slice(1).replace(/-/g, "/");
@@ -19708,7 +19824,7 @@ function buildEntriesForFile(filePath) {
19708
19824
  if (rawLines.length === 0) return null;
19709
19825
  const { meta, events } = parseTranscript(rawLines);
19710
19826
  const fileName = basename2(filePath);
19711
- const projectDir = basename2(dirname14(filePath));
19827
+ const projectDir = basename2(dirname15(filePath));
19712
19828
  const sessionId = fileName.replace(/\.jsonl$/, "");
19713
19829
  const sd = {
19714
19830
  ...meta,
@@ -19966,7 +20082,7 @@ function buildIngestPayload(inputs) {
19966
20082
  return {
19967
20083
  ingestId: randomUUID2(),
19968
20084
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
19969
- cliVersion: "1.0.2",
20085
+ cliVersion: "1.0.4",
19970
20086
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
19971
20087
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
19972
20088
  ...richRollup ? { richRollup } : {},
@@ -20008,8 +20124,8 @@ var init_push = __esm({
20008
20124
  });
20009
20125
 
20010
20126
  // src/team/git-remote.ts
20011
- import { existsSync as existsSync20, readFileSync as readFileSync21, statSync as statSync5 } from "node:fs";
20012
- import { dirname as dirname15, isAbsolute as isAbsolute2, join as join14, resolve as resolve2 } from "node:path";
20127
+ import { existsSync as existsSync21, readFileSync as readFileSync21, statSync as statSync5 } from "node:fs";
20128
+ import { dirname as dirname16, isAbsolute as isAbsolute2, join as join15, resolve as resolve2 } from "node:path";
20013
20129
  function parseGithubRemote(url) {
20014
20130
  const m = url.trim().match(GITHUB_URL_RE);
20015
20131
  return m ? `${m[1]}/${m[2]}`.toLowerCase() : null;
@@ -20029,19 +20145,19 @@ function originUrl2(configText) {
20029
20145
  return null;
20030
20146
  }
20031
20147
  function gitConfigPathFor(dir) {
20032
- const dotGit = join14(dir, ".git");
20148
+ const dotGit = join15(dir, ".git");
20033
20149
  const st = statSync5(dotGit, { throwIfNoEntry: false });
20034
20150
  if (!st) return null;
20035
- if (st.isDirectory()) return join14(dotGit, "config");
20151
+ if (st.isDirectory()) return join15(dotGit, "config");
20036
20152
  const m = readFileSync21(dotGit, "utf8").match(/^gitdir:\s*(.+)\s*$/m);
20037
20153
  if (!m) return null;
20038
20154
  const gd = isAbsolute2(m[1]) ? m[1] : resolve2(dir, m[1]);
20039
- const commondirFile = join14(gd, "commondir");
20040
- if (existsSync20(commondirFile)) {
20155
+ const commondirFile = join15(gd, "commondir");
20156
+ if (existsSync21(commondirFile)) {
20041
20157
  const common = readFileSync21(commondirFile, "utf8").trim();
20042
- return join14(isAbsolute2(common) ? common : resolve2(gd, common), "config");
20158
+ return join15(isAbsolute2(common) ? common : resolve2(gd, common), "config");
20043
20159
  }
20044
- return join14(gd, "config");
20160
+ return join15(gd, "config");
20045
20161
  }
20046
20162
  function createRepoResolver() {
20047
20163
  const cache = /* @__PURE__ */ new Map();
@@ -20051,14 +20167,14 @@ function createRepoResolver() {
20051
20167
  if (hit !== void 0) return hit;
20052
20168
  let repo = null;
20053
20169
  try {
20054
- for (let d = dir; ; d = dirname15(d)) {
20170
+ for (let d = dir; ; d = dirname16(d)) {
20055
20171
  const config = gitConfigPathFor(d);
20056
- if (config && existsSync20(config)) {
20172
+ if (config && existsSync21(config)) {
20057
20173
  const url = originUrl2(readFileSync21(config, "utf8"));
20058
20174
  repo = url ? parseGithubRemote(url) : null;
20059
20175
  break;
20060
20176
  }
20061
- if (d === dirname15(d)) break;
20177
+ if (d === dirname16(d)) break;
20062
20178
  }
20063
20179
  } catch {
20064
20180
  repo = null;
@@ -20077,9 +20193,9 @@ var init_git_remote = __esm({
20077
20193
 
20078
20194
  // src/team/queue.ts
20079
20195
  import { readFileSync as readFileSync22, writeFileSync as writeFileSync15, appendFileSync as appendFileSync5, statSync as statSync6, mkdirSync as mkdirSync14 } from "node:fs";
20080
- import { dirname as dirname16 } from "node:path";
20196
+ import { dirname as dirname17 } from "node:path";
20081
20197
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
20082
- mkdirSync14(dirname16(queuePath), { recursive: true });
20198
+ mkdirSync14(dirname17(queuePath), { recursive: true });
20083
20199
  const entry = { payload, enqueuedAt: (/* @__PURE__ */ new Date()).toISOString() };
20084
20200
  appendFileSync5(queuePath, JSON.stringify(entry) + "\n", "utf8");
20085
20201
  try {
@@ -20133,8 +20249,8 @@ var init_queue2 = __esm({
20133
20249
  });
20134
20250
 
20135
20251
  // src/usage/profile.ts
20136
- import { existsSync as existsSync21, mkdirSync as mkdirSync15, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
20137
- import { dirname as dirname17 } from "node:path";
20252
+ import { existsSync as existsSync22, mkdirSync as mkdirSync15, readFileSync as readFileSync23, writeFileSync as writeFileSync16 } from "node:fs";
20253
+ import { dirname as dirname18 } from "node:path";
20138
20254
  function mapRateLimitTier(rateLimitTier) {
20139
20255
  switch (rateLimitTier) {
20140
20256
  case "default_claude_pro":
@@ -20174,7 +20290,7 @@ async function fetchProfile(nowMs = Date.now()) {
20174
20290
  };
20175
20291
  }
20176
20292
  function readCachedProfile(cachePath) {
20177
- if (!existsSync21(cachePath)) return null;
20293
+ if (!existsSync22(cachePath)) return null;
20178
20294
  try {
20179
20295
  const raw = JSON.parse(readFileSync23(cachePath, "utf8"));
20180
20296
  if (typeof raw.fetchedAtMs !== "number" || !raw.profile) return null;
@@ -20184,7 +20300,7 @@ function readCachedProfile(cachePath) {
20184
20300
  }
20185
20301
  }
20186
20302
  function writeCachedProfile(cachePath, profile, nowMs = Date.now()) {
20187
- mkdirSync15(dirname17(cachePath), { recursive: true });
20303
+ mkdirSync15(dirname18(cachePath), { recursive: true });
20188
20304
  writeFileSync16(
20189
20305
  cachePath,
20190
20306
  JSON.stringify({ fetchedAtMs: nowMs, profile }, null, 2),
@@ -20398,11 +20514,11 @@ var init_sync_log = __esm({
20398
20514
 
20399
20515
  // src/team/last-push.ts
20400
20516
  import { writeFileSync as writeFileSync17, unlinkSync as unlinkSync6, mkdirSync as mkdirSync16 } from "node:fs";
20401
- import { join as join15 } from "node:path";
20517
+ import { join as join16 } from "node:path";
20402
20518
  function write(record, dir) {
20403
20519
  const d = dir ?? cclensHome();
20404
20520
  mkdirSync16(d, { recursive: true });
20405
- writeFileSync17(join15(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
20521
+ writeFileSync17(join16(d, LAST_PUSH_FILE), JSON.stringify(record, null, 2), { mode: 384 });
20406
20522
  }
20407
20523
  function writeLastPushSuccess(payload, dir) {
20408
20524
  write({ pushedAt: (/* @__PURE__ */ new Date()).toISOString(), ok: true, payload }, dir);
@@ -20413,7 +20529,7 @@ function writeLastPushFailure(payload, error, dir) {
20413
20529
  function clearLastPush(dir) {
20414
20530
  const d = dir ?? cclensHome();
20415
20531
  try {
20416
- unlinkSync6(join15(d, LAST_PUSH_FILE));
20532
+ unlinkSync6(join16(d, LAST_PUSH_FILE));
20417
20533
  } catch {
20418
20534
  }
20419
20535
  }
@@ -20433,25 +20549,25 @@ __export(file_probe_exports, {
20433
20549
  probeArtifactSignals: () => probeArtifactSignals
20434
20550
  });
20435
20551
  import { createHash } from "node:crypto";
20436
- import { existsSync as existsSync22, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
20437
- import { homedir as homedir7 } from "node:os";
20438
- import { join as join16, relative, resolve as resolve3, sep } from "node:path";
20552
+ import { existsSync as existsSync23, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
20553
+ import { homedir as homedir8 } from "node:os";
20554
+ import { join as join17, relative, resolve as resolve3, sep } from "node:path";
20439
20555
  import { execFileSync as execFileSync3 } from "node:child_process";
20440
20556
  function pathHash(relPath) {
20441
20557
  return createHash("sha256").update(relPath.split(sep).join("/")).digest("hex").slice(0, 32);
20442
20558
  }
20443
20559
  function defaultScanRoots(extraRoots = []) {
20444
20560
  const roots = [];
20445
- const home = join16(homedir7(), ".claude");
20446
- if (existsSync22(home)) roots.push({ root: home, label: "user" });
20561
+ const home = join17(homedir8(), ".claude");
20562
+ if (existsSync23(home)) roots.push({ root: home, label: "user" });
20447
20563
  for (const e of extraRoots) {
20448
20564
  const r = resolve3(e, ".claude");
20449
- if (existsSync22(r) && r !== home) roots.push({ root: r, label: "project" });
20565
+ if (existsSync23(r) && r !== home) roots.push({ root: r, label: "project" });
20450
20566
  }
20451
20567
  return roots;
20452
20568
  }
20453
20569
  function listMarkdownFiles(dir) {
20454
- if (!existsSync22(dir)) return [];
20570
+ if (!existsSync23(dir)) return [];
20455
20571
  const out = [];
20456
20572
  let entries2;
20457
20573
  try {
@@ -20461,7 +20577,7 @@ function listMarkdownFiles(dir) {
20461
20577
  }
20462
20578
  for (const name of entries2) {
20463
20579
  if (name.startsWith(".")) continue;
20464
- const full = join16(dir, name);
20580
+ const full = join17(dir, name);
20465
20581
  let stat;
20466
20582
  try {
20467
20583
  stat = statSync7(full);
@@ -20481,7 +20597,7 @@ function firstSeenDateOf(file) {
20481
20597
  const out = execFileSync3(
20482
20598
  "git",
20483
20599
  ["log", "--diff-filter=A", "--follow", "--format=%cs", "--", file],
20484
- { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname18(file) }
20600
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname19(file) }
20485
20601
  ).trim().split("\n").filter(Boolean);
20486
20602
  if (out.length > 0) return out[out.length - 1];
20487
20603
  } catch {
@@ -20493,7 +20609,7 @@ function firstSeenDateOf(file) {
20493
20609
  return todayLocal();
20494
20610
  }
20495
20611
  }
20496
- function dirname18(p) {
20612
+ function dirname19(p) {
20497
20613
  const i = p.lastIndexOf(sep);
20498
20614
  return i < 0 ? "." : p.slice(0, i);
20499
20615
  }
@@ -20520,8 +20636,8 @@ function todayLocal() {
20520
20636
  function scanAuthored(roots, subdir, day2) {
20521
20637
  const out = [];
20522
20638
  for (const r of roots) {
20523
- const dir = join16(r.root, subdir);
20524
- if (!existsSync22(dir)) continue;
20639
+ const dir = join17(r.root, subdir);
20640
+ if (!existsSync23(dir)) continue;
20525
20641
  for (const f of listMarkdownFiles(dir)) {
20526
20642
  const firstSeen = firstSeenDateOf(f);
20527
20643
  if (firstSeen !== day2) continue;
@@ -20534,8 +20650,8 @@ function scanAuthored(roots, subdir, day2) {
20534
20650
  function scanEdited(roots, day2) {
20535
20651
  const out = [];
20536
20652
  for (const r of roots) {
20537
- const dir = join16(r.root, "skills");
20538
- if (!existsSync22(dir)) continue;
20653
+ const dir = join17(r.root, "skills");
20654
+ if (!existsSync23(dir)) continue;
20539
20655
  for (const f of listMarkdownFiles(dir)) {
20540
20656
  const firstSeen = firstSeenDateOf(f);
20541
20657
  if (firstSeen === day2) continue;
@@ -20558,16 +20674,16 @@ function claudemdLineDelta(extraRoots, authorEmail, day2) {
20558
20674
  const candidates = [];
20559
20675
  for (const e of extraRoots) {
20560
20676
  const f = resolve3(e, "CLAUDE.md");
20561
- if (existsSync22(f)) candidates.push(f);
20677
+ if (existsSync23(f)) candidates.push(f);
20562
20678
  }
20563
- const homeClaudeMd = join16(homedir7(), "CLAUDE.md");
20564
- if (existsSync22(homeClaudeMd)) candidates.push(homeClaudeMd);
20679
+ const homeClaudeMd = join17(homedir8(), "CLAUDE.md");
20680
+ if (existsSync23(homeClaudeMd)) candidates.push(homeClaudeMd);
20565
20681
  for (const file of candidates) {
20566
20682
  try {
20567
20683
  const out = execFileSync3(
20568
20684
  "git",
20569
20685
  ["log", "--numstat", "--format=COMMIT %cs %ae", "--", file],
20570
- { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname18(file) }
20686
+ { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], cwd: dirname19(file) }
20571
20687
  );
20572
20688
  let currentDate = "";
20573
20689
  let currentEmail = "";
@@ -21583,8 +21699,8 @@ __export(runs_exports, {
21583
21699
  runs: () => runs
21584
21700
  });
21585
21701
  import { execSync as execSync2 } from "node:child_process";
21586
- import { existsSync as existsSync23, readFileSync as readFileSync26, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
21587
- import { join as join17 } from "node:path";
21702
+ import { existsSync as existsSync24, readFileSync as readFileSync26, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
21703
+ import { join as join18 } from "node:path";
21588
21704
  async function runs(args2) {
21589
21705
  const json = args2.includes("--json");
21590
21706
  const watch = args2.includes("--watch");
@@ -21668,7 +21784,7 @@ function listActiveRuns() {
21668
21784
  return runs2.sort((a, b) => a.elapsed_s - b.elapsed_s);
21669
21785
  }
21670
21786
  function readSpend(sinceMs) {
21671
- if (!existsSync23(SPEND_PATH)) return [];
21787
+ if (!existsSync24(SPEND_PATH)) return [];
21672
21788
  const lines = readFileSync26(SPEND_PATH, "utf-8").split("\n").filter((l) => l.trim());
21673
21789
  const out = [];
21674
21790
  for (const line of lines) {
@@ -21790,23 +21906,23 @@ function ageLabel(ms) {
21790
21906
  return `${Math.floor(ms / 864e5)}d`;
21791
21907
  }
21792
21908
  function listTraceFiles() {
21793
- if (!existsSync23(RUNS_DIR2)) return [];
21909
+ if (!existsSync24(RUNS_DIR2)) return [];
21794
21910
  const entries2 = readdirSync6(RUNS_DIR2).filter((f) => f.endsWith(".jsonl"));
21795
21911
  return entries2.map((f) => {
21796
- const path11 = join17(RUNS_DIR2, f);
21912
+ const path11 = join18(RUNS_DIR2, f);
21797
21913
  const st = statSync8(path11);
21798
21914
  return { runId: f.replace(/\.jsonl$/, ""), path: path11, mtimeMs: st.mtimeMs };
21799
21915
  }).sort((a, b) => b.mtimeMs - a.mtimeMs);
21800
21916
  }
21801
21917
  function resolveRunId(arg) {
21802
- if (!existsSync23(RUNS_DIR2)) return null;
21918
+ if (!existsSync24(RUNS_DIR2)) return null;
21803
21919
  if (arg === "latest") {
21804
21920
  const all2 = listTraceFiles();
21805
21921
  if (all2.length === 0) return null;
21806
21922
  return { runId: all2[0].runId, path: all2[0].path };
21807
21923
  }
21808
- const exact = join17(RUNS_DIR2, `${arg}.jsonl`);
21809
- if (existsSync23(exact)) return { runId: arg, path: exact };
21924
+ const exact = join18(RUNS_DIR2, `${arg}.jsonl`);
21925
+ if (existsSync24(exact)) return { runId: arg, path: exact };
21810
21926
  const all = listTraceFiles();
21811
21927
  const matches = all.filter((r) => r.runId.includes(arg));
21812
21928
  if (matches.length === 1) return { runId: matches[0].runId, path: matches[0].path };
@@ -21830,7 +21946,7 @@ async function inspect(arg, follow, json) {
21830
21946
  const r = resolveRunId(arg);
21831
21947
  if (!r) {
21832
21948
  console.error(`run not found: ${arg}`);
21833
- if (existsSync23(RUNS_DIR2)) {
21949
+ if (existsSync24(RUNS_DIR2)) {
21834
21950
  const all = listTraceFiles().slice(0, 5);
21835
21951
  if (all.length > 0) {
21836
21952
  console.error(`
@@ -22010,7 +22126,7 @@ async function main() {
22010
22126
  case "version":
22011
22127
  case "--version":
22012
22128
  case "-v":
22013
- console.log(`fleetlens ${"1.0.2"}`);
22129
+ console.log(`fleetlens ${"1.0.4"}`);
22014
22130
  break;
22015
22131
  case "help":
22016
22132
  case "--help":