fleetlens 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) 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.js.nft.json +1 -1
  13. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/app/apps/web/.next/server/app/api/ask/route.js +4 -3
  15. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  16. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +2 -3
  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 +2 -3
  19. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +3 -3
  21. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +2 -3
  23. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  24. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +3 -3
  25. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  26. package/app/apps/web/.next/server/app/api/events/route.js +2 -3
  27. package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/jobs/route.js +1 -1
  29. package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js +1 -1
  31. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js +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/runs/route.js +1 -1
  35. package/app/apps/web/.next/server/app/api/runs/route.js.nft.json +1 -1
  36. package/app/apps/web/.next/server/app/api/settings/route.js +3 -4
  37. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  38. package/app/apps/web/.next/server/app/changelog/page.js +2 -2
  39. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  40. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  41. package/app/apps/web/.next/server/app/day/[date]/page.js +2 -2
  42. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  44. package/app/apps/web/.next/server/app/day/page.js +2 -2
  45. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  46. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  47. package/app/apps/web/.next/server/app/digest/[date]/page.js +2 -2
  48. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  49. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  50. package/app/apps/web/.next/server/app/digest/page.js +2 -2
  51. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  52. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  53. package/app/apps/web/.next/server/app/insights/[key]/page.js +2 -2
  54. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  55. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  56. package/app/apps/web/.next/server/app/insights/page.js +2 -2
  57. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  58. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  59. package/app/apps/web/.next/server/app/page.js +2 -2
  60. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  61. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  62. package/app/apps/web/.next/server/app/parallelism/page.js +2 -2
  63. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  64. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  65. package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -2
  66. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  67. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  68. package/app/apps/web/.next/server/app/projects/page.js +2 -2
  69. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  70. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  71. package/app/apps/web/.next/server/app/runs/page.js +2 -2
  72. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  73. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  74. package/app/apps/web/.next/server/app/sessions/[id]/page.js +2 -2
  75. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  76. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  77. package/app/apps/web/.next/server/app/sessions/page.js +2 -2
  78. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  79. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  80. package/app/apps/web/.next/server/app/settings/page.js +2 -2
  81. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  82. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  83. package/app/apps/web/.next/server/app/usage/page.js +2 -2
  84. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  85. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  86. package/app/apps/web/.next/server/chunks/[externals]__09v47rg._.js +3 -0
  87. package/app/apps/web/.next/server/chunks/{[externals]__0fpbr8-._.js → [externals]__0o43ejh._.js} +2 -2
  88. package/app/apps/web/.next/server/chunks/[root-of-the-server]__00n3f9y._.js +1 -1
  89. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02px2mk._.js +3 -0
  90. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02zukjw._.js +1 -1
  91. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0455vu3._.js +5 -0
  92. package/app/apps/web/.next/server/chunks/[root-of-the-server]__067~im1._.js +2 -2
  93. package/app/apps/web/.next/server/chunks/[root-of-the-server]__06b4cj-._.js +1 -1
  94. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0e8n_x4._.js → [root-of-the-server]__08agijy._.js} +2 -2
  95. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +3 -3
  96. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +2 -2
  97. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0-vgrh1._.js → [root-of-the-server]__0i06ito._.js} +2 -2
  98. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +2 -2
  99. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0vm_41a._.js +3 -0
  100. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js +4 -4
  101. package/app/apps/web/.next/server/chunks/packages_0c-sz9n._.js +3 -0
  102. package/app/apps/web/.next/server/chunks/packages_0wywuu.._.js +3 -0
  103. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +27 -13
  104. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0d~2~le._.js +1 -1
  105. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
  106. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s4dg1y._.js +3 -0
  107. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +1 -1
  108. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
  109. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0yv0m0q._.js +3 -0
  110. package/app/apps/web/.next/server/chunks/ssr/_0jw2sm7._.js +1 -1
  111. package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
  112. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0ly1xes._.js +1 -1
  113. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +2 -2
  114. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
  115. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +1 -1
  116. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
  117. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_12.endt._.js +3 -0
  118. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  119. package/app/apps/web/.next/server/pages/500.html +1 -1
  120. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  121. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  122. package/app/apps/web/.next/static/chunks/04a36uhu~p_z-.css +1 -0
  123. package/app/apps/web/.next/static/chunks/{0q2vd~aj.1hpz.js → 0g8ujtb0lp._9.js} +3 -3
  124. package/app/apps/web/.next/static/chunks/0l3ck.awv~4t7.js +1 -0
  125. package/app/apps/web/.next/static/chunks/{171za22fv684..js → 0lxuac2v0_gdl.js} +2 -2
  126. package/app/apps/web/.next/static/chunks/0n0n.0279ot6c.js +1 -0
  127. package/app/apps/web/.next/static/chunks/0uev~g~qvbjv9.js +4 -0
  128. package/app/apps/web/.next/static/chunks/0~n2a9f52wju9.js +14 -0
  129. package/app/apps/web/app/api/ask/route.ts +124 -111
  130. package/app/apps/web/app/api/events/route.ts +3 -4
  131. package/app/apps/web/app/api/runs/[runId]/route.ts +2 -2
  132. package/app/apps/web/app/api/runs/[runId]/stream/route.ts +3 -2
  133. package/app/apps/web/app/api/runs/route.ts +8 -4
  134. package/app/apps/web/app/sessions/[id]/session-view.tsx +31 -0
  135. package/app/apps/web/components/job-queue-widget.tsx +11 -8
  136. package/app/apps/web/components/previous-cycles-trend.tsx +26 -11
  137. package/app/apps/web/components/usage-chart.tsx +35 -37
  138. package/app/apps/web/components/usage-gauges.tsx +18 -12
  139. package/app/apps/web/components/usage-sidebar.tsx +23 -12
  140. package/app/apps/web/lib/calibration-data.ts +2 -4
  141. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  142. package/app/apps/web/lib/entries-index.ts +2 -2
  143. package/app/apps/web/lib/jobs.ts +3 -5
  144. package/app/apps/web/lib/usage-data.ts +3 -4
  145. package/app/apps/web/lib/utilization-tone.ts +74 -0
  146. package/app/apps/web/package.json +1 -1
  147. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  148. package/dist/daemon-worker.js +609 -110
  149. package/dist/index.js +5312 -4802
  150. package/package.json +1 -1
  151. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.z48ue._.js +0 -3
  152. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0dctov1._.js +0 -5
  153. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0op9af~._.js +0 -3
  154. package/app/apps/web/.next/server/chunks/packages_09hmrqx._.js +0 -3
  155. package/app/apps/web/.next/server/chunks/packages_118y1lp._.js +0 -3
  156. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +0 -3
  157. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0sp6.jt._.js +0 -3
  158. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ytdqxt._.js +0 -3
  159. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +0 -3
  160. package/app/apps/web/.next/static/chunks/05m.oz3kmf1p7.js +0 -1
  161. package/app/apps/web/.next/static/chunks/07-fq4im3pmjp.js +0 -4
  162. package/app/apps/web/.next/static/chunks/0cxyt4-24..b7.js +0 -14
  163. package/app/apps/web/.next/static/chunks/0o9ayt8sknubd.js +0 -1
  164. package/app/apps/web/.next/static/chunks/0wfbj5zr~az.z.css +0 -1
  165. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → sxcMbKfZ5XgVXYN4QHOHd}/_buildManifest.js +0 -0
  166. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → sxcMbKfZ5XgVXYN4QHOHd}/_clientMiddlewareManifest.js +0 -0
  167. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → sxcMbKfZ5XgVXYN4QHOHd}/_ssgManifest.js +0 -0
@@ -32,21 +32,37 @@ function findWorktreeMarker(projectName) {
32
32
  }
33
33
  return null;
34
34
  }
35
+ function findConductorWorkspace(projectName) {
36
+ const m = CONDUCTOR_RE.exec(projectName);
37
+ if (!m)
38
+ return null;
39
+ const workspaceName = m[1];
40
+ const trailingSlash = m[0].endsWith("/") ? 1 : 0;
41
+ const canonicalEndIdx = m.index + m[0].length - workspaceName.length - 1 - trailingSlash;
42
+ return { canonicalEndIdx, workspaceName };
43
+ }
35
44
  function canonicalProjectName(projectName) {
36
45
  const normalized = projectName.replace(/\/{2,}/g, "/");
37
- const hit = findWorktreeMarker(normalized);
38
- if (hit)
39
- return normalized.slice(0, hit.idx);
46
+ const wt = findWorktreeMarker(normalized);
47
+ if (wt)
48
+ return normalized.slice(0, wt.idx);
49
+ const cd = findConductorWorkspace(normalized);
50
+ if (cd)
51
+ return normalized.slice(0, cd.canonicalEndIdx);
40
52
  return normalized;
41
53
  }
42
54
  function worktreeName(projectName) {
43
55
  const normalized = projectName.replace(/\/{2,}/g, "/");
44
- const hit = findWorktreeMarker(normalized);
45
- if (!hit)
46
- return null;
47
- const tail = normalized.slice(hit.idx + hit.marker.length);
48
- const slash = tail.indexOf("/");
49
- return slash >= 0 ? tail.slice(0, slash) : tail;
56
+ const wt = findWorktreeMarker(normalized);
57
+ if (wt) {
58
+ const tail = normalized.slice(wt.idx + wt.marker.length);
59
+ const slash = tail.indexOf("/");
60
+ return slash >= 0 ? tail.slice(0, slash) : tail;
61
+ }
62
+ const cd = findConductorWorkspace(normalized);
63
+ if (cd)
64
+ return cd.workspaceName;
65
+ return null;
50
66
  }
51
67
  function makeDay(date) {
52
68
  return {
@@ -515,7 +531,7 @@ function groupByProject(sessions) {
515
531
  }
516
532
  return Array.from(map.values()).sort((a, b) => (b.lastActiveMs ?? 0) - (a.lastActiveMs ?? 0));
517
533
  }
518
- var BLANK_USAGE, WORKTREE_MARKERS, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
534
+ var BLANK_USAGE, WORKTREE_MARKERS, CONDUCTOR_RE, PR_CREATE_RE, PR_NUMBER_RE, TITLE_FLAG_RE;
519
535
  var init_analytics = __esm({
520
536
  "../parser/dist/analytics.js"() {
521
537
  "use strict";
@@ -525,6 +541,7 @@ var init_analytics = __esm({
525
541
  "/.worktrees/",
526
542
  "/claude/worktrees/"
527
543
  ];
544
+ CONDUCTOR_RE = /\/conductor\/workspaces\/[^/]+\/([^/]+)(?:\/|$)/;
528
545
  PR_CREATE_RE = /gh\s+pr\s+create\b/i;
529
546
  PR_NUMBER_RE = /#(\d+)/;
530
547
  TITLE_FLAG_RE = /--title\s+["']([^"']+)["']/;
@@ -757,10 +774,64 @@ var init_calibration = __esm({
757
774
  }
758
775
  });
759
776
 
777
+ // ../parser/dist/user-input.js
778
+ function stripFrameworkBoilerplate(rawText) {
779
+ if (!rawText)
780
+ return rawText;
781
+ let out = rawText;
782
+ for (const re of STRIPPABLE_WRAPPERS) {
783
+ out = out.replace(re, "");
784
+ }
785
+ return out.trim();
786
+ }
787
+ function isFrameworkInjectedUserInput(rawText) {
788
+ if (!rawText)
789
+ return false;
790
+ const stripped = stripFrameworkBoilerplate(rawText);
791
+ if (!stripped)
792
+ return true;
793
+ for (const prefix of ENTIRELY_INJECTED_PREFIXES) {
794
+ if (stripped.startsWith(prefix))
795
+ return true;
796
+ }
797
+ return false;
798
+ }
799
+ var STRIPPABLE_WRAPPERS, ENTIRELY_INJECTED_PREFIXES;
800
+ var init_user_input = __esm({
801
+ "../parser/dist/user-input.js"() {
802
+ "use strict";
803
+ STRIPPABLE_WRAPPERS = [
804
+ /<system_instruction\b[^>]*>[\s\S]*?<\/system_instruction>\s*/gi
805
+ ];
806
+ ENTIRELY_INJECTED_PREFIXES = [
807
+ "<command-name>",
808
+ "<local-command-stdout>",
809
+ "<local-command-caveat>",
810
+ "<task-notification>",
811
+ "Base directory for this skill:"
812
+ ];
813
+ }
814
+ });
815
+
760
816
  // ../parser/dist/parser.js
761
817
  function cleanText(s) {
762
818
  return s.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim();
763
819
  }
820
+ function extractRawUserText(rawMsg) {
821
+ const c = rawMsg?.content;
822
+ if (typeof c === "string")
823
+ return c;
824
+ if (Array.isArray(c)) {
825
+ for (const block of c) {
826
+ if (block && typeof block === "object") {
827
+ const b = block;
828
+ if (b.type === "text" && typeof b.text === "string")
829
+ return b.text;
830
+ }
831
+ }
832
+ }
833
+ return "";
834
+ }
764
835
  function truncate(s, n = 200) {
765
836
  const one = cleanText(s);
766
837
  return one.length > n ? one.slice(0, n - 1) + "\u2026" : one;
@@ -859,7 +930,8 @@ function toEvent(raw, index) {
859
930
  const msg = r.message ?? {};
860
931
  const c = msg.content;
861
932
  if (typeof c === "string") {
862
- const tm = classifyTeammateMessage(c);
933
+ const cleaned = stripFrameworkBoilerplate(c);
934
+ const tm = classifyTeammateMessage(cleaned);
863
935
  return {
864
936
  index,
865
937
  uuid,
@@ -867,8 +939,8 @@ function toEvent(raw, index) {
867
939
  timestamp,
868
940
  role: "user",
869
941
  rawType,
870
- preview: truncate(c, 200),
871
- blocks: [{ type: "text", text: c }],
942
+ preview: truncate(cleaned, 200),
943
+ blocks: cleaned ? [{ type: "text", text: cleaned }] : [],
872
944
  raw,
873
945
  teammateMessage: tm
874
946
  };
@@ -892,7 +964,9 @@ function toEvent(raw, index) {
892
964
  };
893
965
  }
894
966
  const textBlock = c.find((b) => b?.type === "text");
895
- const tm = textBlock ? classifyTeammateMessage(textBlock.text) : void 0;
967
+ const cleanedText = textBlock ? stripFrameworkBoilerplate(textBlock.text) : "";
968
+ const cleanedBlocks = textBlock ? c.map((b) => b === textBlock ? { type: "text", text: cleanedText } : b) : c;
969
+ const tm = cleanedText ? classifyTeammateMessage(cleanedText) : void 0;
896
970
  return {
897
971
  index,
898
972
  uuid,
@@ -900,8 +974,8 @@ function toEvent(raw, index) {
900
974
  timestamp,
901
975
  role: "user",
902
976
  rawType,
903
- preview: textBlock ? truncate(textBlock.text, 200) : truncate(JSON.stringify(c), 200),
904
- blocks: c,
977
+ preview: cleanedText ? truncate(cleanedText, 200) : truncate(JSON.stringify(c), 200),
978
+ blocks: cleanedBlocks,
905
979
  raw,
906
980
  teammateMessage: tm
907
981
  };
@@ -1078,6 +1152,7 @@ function parseTranscript(rawLines) {
1078
1152
  let sessionId = "";
1079
1153
  let cwd;
1080
1154
  let gitBranch;
1155
+ let entrypoint;
1081
1156
  let teamName;
1082
1157
  let agentName;
1083
1158
  let hasTeamCreate = false;
@@ -1121,8 +1196,8 @@ function parseTranscript(rawLines) {
1121
1196
  }
1122
1197
  if (e.role === "user") {
1123
1198
  const rawMsg = e.raw?.message;
1124
- const rawContent = typeof rawMsg?.content === "string" ? rawMsg.content : "";
1125
- const isHidden = rawContent.startsWith("<command-name>") || rawContent.startsWith("<local-command-caveat>") || rawContent.startsWith("Base directory for this skill:") || rawContent.startsWith("<task-notification>");
1199
+ const rawContent = extractRawUserText(rawMsg);
1200
+ const isHidden = isFrameworkInjectedUserInput(rawContent);
1126
1201
  const isTeamNoise = e.teammateMessage !== void 0 && !agentName;
1127
1202
  if (!isHidden && !isTeamNoise) {
1128
1203
  if (!firstUserPreview) {
@@ -1146,6 +1221,8 @@ function parseTranscript(rawLines) {
1146
1221
  cwd = o.cwd;
1147
1222
  if (typeof o.gitBranch === "string" && !gitBranch)
1148
1223
  gitBranch = o.gitBranch;
1224
+ if (typeof o.entrypoint === "string" && !entrypoint)
1225
+ entrypoint = o.entrypoint;
1149
1226
  if (typeof o.teamName === "string" && !teamName)
1150
1227
  teamName = o.teamName;
1151
1228
  if (typeof o.agentName === "string" && !agentName)
@@ -1183,6 +1260,7 @@ function parseTranscript(rawLines) {
1183
1260
  model,
1184
1261
  cwd,
1185
1262
  gitBranch,
1263
+ entrypoint,
1186
1264
  totalUsage,
1187
1265
  status: "idle",
1188
1266
  firstUserPreview,
@@ -1207,6 +1285,7 @@ var BLANK_USAGE2, TEAMMATE_MSG_RE;
1207
1285
  var init_parser = __esm({
1208
1286
  "../parser/dist/parser.js"() {
1209
1287
  "use strict";
1288
+ init_user_input();
1210
1289
  BLANK_USAGE2 = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
1211
1290
  TEAMMATE_MSG_RE = /^\s*<teammate-message\s+teammate_id="([^"]+)"[^>]*>([\s\S]*?)<\/teammate-message>/;
1212
1291
  }
@@ -2025,7 +2104,8 @@ function parseRollout(file, lines) {
2025
2104
  if (type === "event_msg" && subtype === "user_message") {
2026
2105
  const text = typeof payload.message === "string" ? payload.message : "";
2027
2106
  const preview = previewOf(text);
2028
- if (text) {
2107
+ const isHidden = isFrameworkInjectedUserInput(text);
2108
+ if (text && !isHidden) {
2029
2109
  if (!firstUserPreview)
2030
2110
  firstUserPreview = preview;
2031
2111
  lastUserPreview = preview;
@@ -2342,6 +2422,7 @@ var init_codex = __esm({
2342
2422
  "../parser/dist/codex.js"() {
2343
2423
  "use strict";
2344
2424
  init_analytics();
2425
+ init_user_input();
2345
2426
  DEFAULT_CODEX_ROOT = path2.join(os2.homedir(), ".codex", "sessions");
2346
2427
  ROLLOUT_RE = /^rollout-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})-([0-9a-f-]+)\.jsonl$/;
2347
2428
  IDLE_GAP_MS = 3 * 60 * 1e3;
@@ -2564,7 +2645,8 @@ async function parseSession(file) {
2564
2645
  if (msg.type === "user") {
2565
2646
  const text = flattenContent(msg.displayContent ?? msg.content);
2566
2647
  const preview = previewOf2(text);
2567
- if (text) {
2648
+ const isHidden = isFrameworkInjectedUserInput(text);
2649
+ if (text && !isHidden) {
2568
2650
  if (!firstUserPreview)
2569
2651
  firstUserPreview = preview;
2570
2652
  lastUserPreview = preview;
@@ -2839,6 +2921,7 @@ var init_gemini = __esm({
2839
2921
  "../parser/dist/gemini.js"() {
2840
2922
  "use strict";
2841
2923
  init_analytics();
2924
+ init_user_input();
2842
2925
  DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
2843
2926
  GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
2844
2927
  SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
@@ -2858,6 +2941,8 @@ __export(fs_exports, {
2858
2941
  agentSources: () => agentSources,
2859
2942
  buildCalibrationCurve: () => buildCalibrationCurve,
2860
2943
  cacheStats: () => cacheStats,
2944
+ cclensHome: () => cclensHome,
2945
+ cclensPath: () => cclensPath,
2861
2946
  clearCaches: () => clearCaches,
2862
2947
  codexSessionLocalDay: () => codexSessionLocalDay,
2863
2948
  decodeProjectName: () => decodeProjectName,
@@ -2887,6 +2972,12 @@ __export(fs_exports, {
2887
2972
  import { promises as fs4 } from "node:fs";
2888
2973
  import os4 from "node:os";
2889
2974
  import path4 from "node:path";
2975
+ function cclensHome() {
2976
+ return process.env.CCLENS_HOME || path4.join(os4.homedir(), ".cclens");
2977
+ }
2978
+ function cclensPath(...parts) {
2979
+ return path4.join(cclensHome(), ...parts);
2980
+ }
2890
2981
  function cacheStats() {
2891
2982
  return claudeCodeCacheStats();
2892
2983
  }
@@ -2919,10 +3010,13 @@ async function getAnySession(id) {
2919
3010
  }
2920
3011
  return null;
2921
3012
  }
3013
+ function usageLogPath() {
3014
+ return cclensPath("usage.jsonl");
3015
+ }
2922
3016
  async function loadUsageByDay(start, end) {
2923
3017
  let raw;
2924
3018
  try {
2925
- raw = await fs4.readFile(USAGE_LOG, "utf8");
3019
+ raw = await fs4.readFile(usageLogPath(), "utf8");
2926
3020
  } catch {
2927
3021
  return { by_day: [] };
2928
3022
  }
@@ -2967,7 +3061,7 @@ async function loadUsageByDay(start, end) {
2967
3061
  async function loadCalibrationSnapshots() {
2968
3062
  let raw;
2969
3063
  try {
2970
- raw = await fs4.readFile(USAGE_LOG, "utf8");
3064
+ raw = await fs4.readFile(usageLogPath(), "utf8");
2971
3065
  } catch {
2972
3066
  return [];
2973
3067
  }
@@ -3125,7 +3219,7 @@ async function loadCalibrationCurve(tier = "pro-max-20x", root = DEFAULT_ROOT, g
3125
3219
  ]);
3126
3220
  return buildCalibrationCurve(events, snapshots, tier, granularityMin);
3127
3221
  }
3128
- var codexSource, geminiSource, agentSources, USAGE_LOG;
3222
+ var codexSource, geminiSource, agentSources;
3129
3223
  var init_fs = __esm({
3130
3224
  "../parser/dist/fs.js"() {
3131
3225
  "use strict";
@@ -3170,7 +3264,6 @@ var init_fs = __esm({
3170
3264
  }
3171
3265
  };
3172
3266
  agentSources = [claudeCodeSource, codexSource, geminiSource];
3173
- USAGE_LOG = path4.join(os4.homedir(), ".cclens", "usage.jsonl");
3174
3267
  }
3175
3268
  });
3176
3269
 
@@ -3339,7 +3432,13 @@ function buildPresentation(events) {
3339
3432
  return false;
3340
3433
  if (e.role === "user") {
3341
3434
  const txt = firstTextOfBlocks(e.blocks) ?? "";
3342
- if (SKILL_CONTENT_RE.test(txt))
3435
+ if (e.blocks.length === 0 || !txt.trim())
3436
+ return false;
3437
+ if (SLASH_COMMAND_RE.test(txt))
3438
+ return true;
3439
+ if (TASK_NOTIFICATION_RE.test(txt))
3440
+ return true;
3441
+ if (isFrameworkInjectedUserInput(txt))
3343
3442
  return false;
3344
3443
  }
3345
3444
  return true;
@@ -3467,13 +3566,13 @@ function buildPresentation(events) {
3467
3566
  }
3468
3567
  return rows;
3469
3568
  }
3470
- var INTERRUPT_RE, RATE_LIMIT_RE, SKILL_CONTENT_RE, SLASH_COMMAND_RE, TASK_NOTIFICATION_RE;
3569
+ var INTERRUPT_RE, RATE_LIMIT_RE, SLASH_COMMAND_RE, TASK_NOTIFICATION_RE;
3471
3570
  var init_presentation = __esm({
3472
3571
  "../parser/dist/presentation.js"() {
3473
3572
  "use strict";
3573
+ init_user_input();
3474
3574
  INTERRUPT_RE = /\[request interrupted|interrupted by user/i;
3475
3575
  RATE_LIMIT_RE = /rate.?limit|overloaded_error|api error|Error sending message/i;
3476
- SKILL_CONTENT_RE = /^Base directory for this skill:/;
3477
3576
  SLASH_COMMAND_RE = /<command-name>(\/[^<\s]+)<\/command-name>(?:[\s\S]*?<command-args>([\s\S]*?)<\/command-args>)?/;
3478
3577
  TASK_NOTIFICATION_RE = /<task-notification>/;
3479
3578
  }
@@ -3607,6 +3706,7 @@ __export(dist_exports, {
3607
3706
  groupSnapsByCycle: () => groupSnapsByCycle,
3608
3707
  highLevelMetrics: () => highLevelMetrics,
3609
3708
  isAgentKind: () => isAgentKind,
3709
+ isFrameworkInjectedUserInput: () => isFrameworkInjectedUserInput,
3610
3710
  last4CompletedWeeks: () => last4CompletedWeeks,
3611
3711
  modelFamily: () => modelFamily,
3612
3712
  parseTranscript: () => parseTranscript,
@@ -3617,6 +3717,7 @@ __export(dist_exports, {
3617
3717
  rowPrimaryIndex: () => rowPrimaryIndex,
3618
3718
  sessionAirTimeMs: () => sessionAirTimeMs,
3619
3719
  sessionDay: () => sessionDay,
3720
+ stripFrameworkBoilerplate: () => stripFrameworkBoilerplate,
3620
3721
  summarizeBursts: () => summarizeBursts,
3621
3722
  toLocalDay: () => toLocalDay,
3622
3723
  userSoloRate: () => userSoloRate,
@@ -3627,6 +3728,7 @@ var init_dist = __esm({
3627
3728
  "use strict";
3628
3729
  init_types();
3629
3730
  init_parser();
3731
+ init_user_input();
3630
3732
  init_presentation();
3631
3733
  init_analytics();
3632
3734
  init_aggregate();
@@ -3637,9 +3739,8 @@ var init_dist = __esm({
3637
3739
  });
3638
3740
 
3639
3741
  // src/daemon-worker.ts
3640
- import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync11 } from "node:fs";
3641
- import { dirname as dirname9, join as join13 } from "node:path";
3642
- import { homedir as homedir13 } from "node:os";
3742
+ import { appendFileSync as appendFileSync5, mkdirSync as mkdirSync12 } from "node:fs";
3743
+ import { dirname as dirname8 } from "node:path";
3643
3744
 
3644
3745
  // src/usage/token.ts
3645
3746
  import { execFileSync } from "node:child_process";
@@ -3799,9 +3900,13 @@ function readSnapshots(filePath) {
3799
3900
  }
3800
3901
  return snapshots;
3801
3902
  }
3802
- function latestSnapshot(filePath) {
3903
+ function latestClaudeCodeSnapshot(filePath) {
3803
3904
  const all = readSnapshots(filePath);
3804
- return all.length > 0 ? all[all.length - 1] : null;
3905
+ for (let i = all.length - 1; i >= 0; i--) {
3906
+ const s = all[i];
3907
+ if (!s.agent || s.agent === "claude-code") return s;
3908
+ }
3909
+ return null;
3805
3910
  }
3806
3911
 
3807
3912
  // src/daemon-worker.ts
@@ -3816,26 +3921,23 @@ function nextIntervalMs(current, outcome) {
3816
3921
  return Math.min(Math.max(current, BASE_INTERVAL_MS) * 2, MAX_INTERVAL_MS);
3817
3922
  }
3818
3923
 
3819
- // src/team/sync.ts
3820
- import { homedir as homedir4 } from "node:os";
3821
- import { join as join4 } from "node:path";
3822
-
3823
3924
  // src/team/config.ts
3925
+ init_fs();
3824
3926
  import { readFileSync as readFileSync3, writeFileSync, unlinkSync, mkdirSync as mkdirSync2 } from "node:fs";
3825
3927
  import { join as join2 } from "node:path";
3826
- import { homedir as homedir2 } from "node:os";
3827
- var DEFAULT_DIR = join2(homedir2(), ".cclens");
3828
3928
  var CONFIG_FILE = "team.json";
3829
- function readTeamConfig(dir = DEFAULT_DIR) {
3929
+ function readTeamConfig(dir) {
3930
+ const d = dir ?? cclensHome();
3830
3931
  try {
3831
- return JSON.parse(readFileSync3(join2(dir, CONFIG_FILE), "utf8"));
3932
+ return JSON.parse(readFileSync3(join2(d, CONFIG_FILE), "utf8"));
3832
3933
  } catch {
3833
3934
  return null;
3834
3935
  }
3835
3936
  }
3836
- function writeTeamConfig(config, dir = DEFAULT_DIR) {
3837
- mkdirSync2(dir, { recursive: true });
3838
- writeFileSync(join2(dir, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
3937
+ function writeTeamConfig(config, dir) {
3938
+ const d = dir ?? cclensHome();
3939
+ mkdirSync2(d, { recursive: true });
3940
+ writeFileSync(join2(d, CONFIG_FILE), JSON.stringify(config, null, 2), { mode: 384 });
3839
3941
  }
3840
3942
 
3841
3943
  // src/team/push.ts
@@ -3843,7 +3945,7 @@ init_dist();
3843
3945
  import { randomUUID } from "node:crypto";
3844
3946
  var SNAPSHOT_FRESHNESS_MS = 10 * 60 * 1e3;
3845
3947
  function readLatestUsageSnapshotForWire(filePath, nowMs = Date.now()) {
3846
- const raw = latestSnapshot(filePath);
3948
+ const raw = latestClaudeCodeSnapshot(filePath);
3847
3949
  if (!raw) return null;
3848
3950
  const capturedMs = Date.parse(raw.captured_at);
3849
3951
  if (Number.isNaN(capturedMs)) return null;
@@ -3911,10 +4013,10 @@ async function pushToTeamServer(config, payload) {
3911
4013
  }
3912
4014
 
3913
4015
  // src/team/queue.ts
4016
+ init_fs();
3914
4017
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync2, appendFileSync as appendFileSync2, statSync, mkdirSync as mkdirSync3 } from "node:fs";
3915
- import { join as join3, dirname as dirname2 } from "node:path";
3916
- import { homedir as homedir3 } from "node:os";
3917
- var QUEUE_PATH = join3(homedir3(), ".cclens", "ingest-queue.jsonl");
4018
+ import { dirname as dirname2 } from "node:path";
4019
+ var QUEUE_PATH = cclensPath("ingest-queue.jsonl");
3918
4020
  var MAX_SIZE_BYTES = 10 * 1024 * 1024;
3919
4021
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
3920
4022
  function enqueuePayload(payload, queuePath = QUEUE_PATH) {
@@ -4037,8 +4139,9 @@ async function getPlanTier(cachePath, nowMs = Date.now(), fetcher = fetchProfile
4037
4139
  }
4038
4140
 
4039
4141
  // src/team/sync.ts
4040
- var USAGE_LOG2 = join4(homedir4(), ".cclens", "usage.jsonl");
4041
- var PROFILE_CACHE = join4(homedir4(), ".cclens", "profile.json");
4142
+ init_fs();
4143
+ var USAGE_LOG = cclensPath("usage.jsonl");
4144
+ var PROFILE_CACHE = cclensPath("profile.json");
4042
4145
  var noopLog = () => {
4043
4146
  };
4044
4147
  async function runTeamSync(log3 = noopLog, configOverride) {
@@ -4050,7 +4153,7 @@ async function runTeamSync(log3 = noopLog, configOverride) {
4050
4153
  const today = toLocalDay3(Date.now());
4051
4154
  const sessions = await listSessions2({ limit: 1e4 });
4052
4155
  const rollups = buildRollupsForRange(sessions, config.lastSyncedDay);
4053
- const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG2) ?? void 0;
4156
+ const usageSnapshot = readLatestUsageSnapshotForWire(USAGE_LOG) ?? void 0;
4054
4157
  const planTier = await getPlanTier(PROFILE_CACHE).catch(() => null) ?? void 0;
4055
4158
  const cyclePeaks = await buildCyclePeaksForPush(planTier, loadCalibrationCurve2);
4056
4159
  if (rollups.length === 0) {
@@ -4264,17 +4367,21 @@ var PROMPT_FRAME_ORIGIN = {
4264
4367
  };
4265
4368
 
4266
4369
  // ../entries/dist/signals.js
4370
+ init_dist();
4267
4371
  var TEAMMATE_RE = /^<teammate-message\b/;
4268
4372
  var SKILL_LOAD_RE = /^Base directory for this skill:/;
4269
4373
  var SLASH_COMMAND_RE2 = /^<command-name>|^<local-command-stdout>/;
4270
4374
  function classifyUserInputSource(text) {
4271
4375
  if (!text)
4272
4376
  return "human";
4273
- if (TEAMMATE_RE.test(text))
4377
+ const stripped = stripFrameworkBoilerplate(text);
4378
+ if (!stripped)
4379
+ return "system_instruction";
4380
+ if (TEAMMATE_RE.test(stripped))
4274
4381
  return "teammate";
4275
- if (SKILL_LOAD_RE.test(text))
4382
+ if (SKILL_LOAD_RE.test(stripped))
4276
4383
  return "skill_load";
4277
- if (SLASH_COMMAND_RE2.test(text))
4384
+ if (SLASH_COMMAND_RE2.test(stripped))
4278
4385
  return "slash_command";
4279
4386
  return "human";
4280
4387
  }
@@ -4663,7 +4770,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
4663
4770
  closeTurn(cur, closed, eventCwd);
4664
4771
  }
4665
4772
  cur = newTurn(tsMs, text);
4666
- if (!firstUser && text && !text.startsWith("<command-name>")) {
4773
+ if (!firstUser && text && classifyUserInputSource(text) === "human") {
4667
4774
  firstUser = text;
4668
4775
  }
4669
4776
  } else {
@@ -4907,7 +5014,13 @@ function buildEntries(sessionDetail) {
4907
5014
  return classifyUserInputSource(text) === "human";
4908
5015
  }).map((ev) => blockText(ev.blocks) || ev.preview || "").join("\n");
4909
5016
  const satisfaction_signals = countSatisfactionSignals(humanText);
4910
- const user_input_sources = { human: 0, teammate: 0, skill_load: 0, slash_command: 0 };
5017
+ const user_input_sources = {
5018
+ human: 0,
5019
+ teammate: 0,
5020
+ skill_load: 0,
5021
+ slash_command: 0,
5022
+ system_instruction: 0
5023
+ };
4911
5024
  for (const ev of dayEvents) {
4912
5025
  const v = viewEvent(ev);
4913
5026
  if (v.rawType !== "user")
@@ -4955,28 +5068,28 @@ function buildEntries(sessionDetail) {
4955
5068
  }
4956
5069
 
4957
5070
  // ../entries/dist/fs.js
5071
+ init_fs();
4958
5072
  import { readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6, renameSync as renameSync2, existsSync as existsSync4 } from "node:fs";
4959
5073
  import { randomBytes } from "node:crypto";
4960
- import { join as join6 } from "node:path";
4961
- import { homedir as homedir6 } from "node:os";
5074
+ import { join as join4 } from "node:path";
4962
5075
 
4963
5076
  // ../entries/dist/digest-fs.js
5077
+ init_fs();
4964
5078
  import { readFileSync as readFileSync6, readdirSync, writeFileSync as writeFileSync4, renameSync, chmodSync, mkdirSync as mkdirSync5, existsSync as existsSync3 } from "node:fs";
4965
- import { dirname as dirname4, join as join5 } from "node:path";
4966
- import { homedir as homedir5 } from "node:os";
5079
+ import { dirname as dirname4, join as join3 } from "node:path";
4967
5080
  var digestsDirCached = null;
4968
5081
  function digestsDir() {
4969
5082
  if (digestsDirCached)
4970
5083
  return digestsDirCached;
4971
5084
  const envOverride = process.env.CCLENS_DIGESTS_DIR;
4972
- digestsDirCached = envOverride ?? join5(homedir5(), ".cclens", "digests");
5085
+ digestsDirCached = envOverride ?? cclensPath("digests");
4973
5086
  return digestsDirCached;
4974
5087
  }
4975
5088
  function dayDigestPath(date) {
4976
- return join5(digestsDir(), "day", `${date}.json`);
5089
+ return join3(digestsDir(), "day", `${date}.json`);
4977
5090
  }
4978
5091
  function weekDigestPath(monday) {
4979
- return join5(digestsDir(), "week", `${monday}.json`);
5092
+ return join3(digestsDir(), "week", `${monday}.json`);
4980
5093
  }
4981
5094
  function writeDayDigest(digest) {
4982
5095
  const final = dayDigestPath(digest.key);
@@ -5060,11 +5173,11 @@ function entriesDir() {
5060
5173
  if (entriesDirCached)
5061
5174
  return entriesDirCached;
5062
5175
  const envOverride = process.env.CCLENS_ENTRIES_DIR;
5063
- entriesDirCached = envOverride ?? join6(homedir6(), ".cclens", "entries");
5176
+ entriesDirCached = envOverride ?? cclensPath("entries");
5064
5177
  return entriesDirCached;
5065
5178
  }
5066
5179
  function pathFor(sessionId, localDay) {
5067
- return join6(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
5180
+ return join4(entriesDir(), `${entryKey(sessionId, localDay)}.json`);
5068
5181
  }
5069
5182
  function tmpPathFor(final) {
5070
5183
  return `${final}.tmp.${process.pid}.${randomBytes(4).toString("hex")}`;
@@ -5137,14 +5250,14 @@ function listEntriesForDay(localDay) {
5137
5250
  }
5138
5251
 
5139
5252
  // src/perception/state.ts
5253
+ init_fs();
5140
5254
  import { existsSync as existsSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, renameSync as renameSync3 } from "node:fs";
5141
- import { dirname as dirname5, join as join7 } from "node:path";
5142
- import { homedir as homedir7 } from "node:os";
5255
+ import { dirname as dirname5 } from "node:path";
5143
5256
  var STALE_MS = 15 * 60 * 1e3;
5144
5257
  var pathCached = null;
5145
5258
  function statePath() {
5146
5259
  if (pathCached) return pathCached;
5147
- pathCached = join7(homedir7(), ".cclens", "perception-state.json");
5260
+ pathCached = cclensPath("perception-state.json");
5148
5261
  return pathCached;
5149
5262
  }
5150
5263
  function readState() {
@@ -5194,17 +5307,17 @@ function updateCheckpoint(jsonlPath, cp) {
5194
5307
 
5195
5308
  // src/perception/scan.ts
5196
5309
  import { readdirSync as readdirSync3 } from "node:fs";
5197
- import { join as join8 } from "node:path";
5198
- import { homedir as homedir8 } from "node:os";
5310
+ import { join as join5 } from "node:path";
5311
+ import { homedir as homedir2 } from "node:os";
5199
5312
  async function listAllSessionJsonls(root) {
5200
- const projectsRoot = root ?? join8(homedir8(), ".claude", "projects");
5313
+ const projectsRoot = root ?? join5(homedir2(), ".claude", "projects");
5201
5314
  const out = [];
5202
5315
  try {
5203
5316
  for (const project of readdirSync3(projectsRoot)) {
5204
- const dir = join8(projectsRoot, project);
5317
+ const dir = join5(projectsRoot, project);
5205
5318
  try {
5206
5319
  for (const f of readdirSync3(dir)) {
5207
- if (f.endsWith(".jsonl")) out.push(join8(dir, f));
5320
+ if (f.endsWith(".jsonl")) out.push(join5(dir, f));
5208
5321
  }
5209
5322
  } catch {
5210
5323
  }
@@ -9445,16 +9558,332 @@ ${turns || "(none \u2014 the user text was filtered out as non-human)"}`;
9445
9558
  var ENRICHMENT_SYSTEM_PROMPT = SYSTEM_PROMPT;
9446
9559
 
9447
9560
  // ../entries/dist/llm-runner.js
9561
+ init_fs();
9448
9562
  import { spawn } from "node:child_process";
9449
- import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync3, writeFileSync as writeFileSync7, existsSync as existsSync6 } from "node:fs";
9450
- import { homedir as homedir9 } from "node:os";
9451
- import { join as join9 } from "node:path";
9563
+ import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync3, writeFileSync as writeFileSync8, existsSync as existsSync7 } from "node:fs";
9564
+ import { join as join7 } from "node:path";
9452
9565
  import { randomUUID as randomUUID2 } from "node:crypto";
9453
- var RUNS_DIR = join9(homedir9(), ".cclens", "llm-runs");
9566
+
9567
+ // ../entries/dist/tmux-runner.js
9568
+ import { mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, existsSync as existsSync6, readdirSync as readdirSync4, realpathSync, readFileSync as readFileSync10, unlinkSync as unlinkSync2, renameSync as renameSync4 } from "node:fs";
9569
+ import { join as join6 } from "node:path";
9570
+ import { homedir as homedir3 } from "node:os";
9571
+ import { spawnSync } from "node:child_process";
9572
+ var TmuxUnavailableError = class extends Error {
9573
+ constructor(message) {
9574
+ super(message);
9575
+ this.name = "TmuxUnavailableError";
9576
+ }
9577
+ };
9578
+ var TmuxRunError = class extends Error {
9579
+ constructor(message) {
9580
+ super(message);
9581
+ this.name = "TmuxRunError";
9582
+ }
9583
+ };
9584
+ function which(bin) {
9585
+ const r = spawnSync("/usr/bin/env", ["which", bin], { encoding: "utf8" });
9586
+ if (r.status === 0)
9587
+ return r.stdout.trim() || void 0;
9588
+ return void 0;
9589
+ }
9590
+ function tmuxRunnerAvailable() {
9591
+ if (!which("tmux"))
9592
+ return { ok: false, reason: "tmux not on PATH" };
9593
+ if (!which("claude"))
9594
+ return { ok: false, reason: "claude not on PATH" };
9595
+ return { ok: true };
9596
+ }
9597
+ function runtimeCwd() {
9598
+ const dir = join6(homedir3(), ".cclens", "runtime");
9599
+ if (!existsSync6(dir))
9600
+ mkdirSync8(dir, { recursive: true });
9601
+ return realpathSync(dir);
9602
+ }
9603
+ function ensureRuntimeCwdTrusted(cwd) {
9604
+ const cfgPath = join6(homedir3(), ".claude.json");
9605
+ let cfg;
9606
+ try {
9607
+ cfg = JSON.parse(readFileSync10(cfgPath, "utf8"));
9608
+ } catch {
9609
+ return;
9610
+ }
9611
+ const projects = cfg.projects ?? {};
9612
+ const cur = projects[cwd];
9613
+ if (cur && cur.hasTrustDialogAccepted === true)
9614
+ return;
9615
+ projects[cwd] = {
9616
+ ...cur ?? {},
9617
+ hasTrustDialogAccepted: true
9618
+ };
9619
+ cfg.projects = projects;
9620
+ const tmp = `${cfgPath}.cclens-tmp-${process.pid}`;
9621
+ try {
9622
+ writeFileSync7(tmp, JSON.stringify(cfg, null, 2));
9623
+ renameSync4(tmp, cfgPath);
9624
+ } catch {
9625
+ try {
9626
+ unlinkSync2(tmp);
9627
+ } catch {
9628
+ }
9629
+ }
9630
+ }
9631
+ var mutex = Promise.resolve();
9632
+ function runClaudeUnderTmux(args) {
9633
+ const next = mutex.then(() => runClaudeUnderTmuxImpl(args));
9634
+ mutex = next.catch(() => void 0);
9635
+ return next;
9636
+ }
9637
+ async function runClaudeUnderTmuxImpl(args) {
9638
+ const tmuxBin = args.tmuxBin ?? which("tmux");
9639
+ if (!tmuxBin)
9640
+ throw new TmuxUnavailableError("tmux not on PATH");
9641
+ const claudeBin = args.claudeBin ?? which("claude");
9642
+ if (!claudeBin)
9643
+ throw new TmuxUnavailableError("claude not on PATH");
9644
+ if (args.signal?.aborted)
9645
+ throw new TmuxRunError("aborted before spawn");
9646
+ const cwd = runtimeCwd();
9647
+ ensureRuntimeCwdTrusted(cwd);
9648
+ const runId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
9649
+ const sessionName = `cclens-${runId}`;
9650
+ const systemFile = join6(cwd, `system-${runId}.txt`);
9651
+ const userFile = join6(cwd, `user-${runId}.txt`);
9652
+ const wrapper = join6(cwd, `run-${runId}.sh`);
9653
+ writeFileSync7(systemFile, args.systemPrompt);
9654
+ writeFileSync7(userFile, args.reminder ? `${args.userPrompt}
9655
+
9656
+ ---
9657
+
9658
+ ${args.reminder}` : args.userPrompt);
9659
+ writeFileSync7(wrapper, `#!/bin/bash
9660
+ SYS="$(cat ${shellEscape(systemFile)})"
9661
+ USR="$(cat ${shellEscape(userFile)})"
9662
+ exec ${shellEscape(claudeBin)} \\
9663
+ --model ${shellEscape(args.model)} \\
9664
+ --strict-mcp-config --mcp-config '{"mcpServers":{}}' \\
9665
+ --disable-slash-commands \\
9666
+ --effort medium \\
9667
+ --append-system-prompt "$SYS" \\
9668
+ "$USR"
9669
+ `, { mode: 493 });
9670
+ const existingBefore = snapshotAllTranscripts();
9671
+ const spawn2 = spawnSync(tmuxBin, ["new-session", "-d", "-s", sessionName, "-x", "140", "-y", "50", "-c", cwd, wrapper], { encoding: "utf8" });
9672
+ if (spawn2.status !== 0) {
9673
+ cleanup(cwd, runId, tmuxBin, sessionName);
9674
+ throw new TmuxRunError(`tmux new-session failed: ${spawn2.stderr.trim()}`);
9675
+ }
9676
+ const onAbort = () => {
9677
+ try {
9678
+ spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
9679
+ } catch {
9680
+ }
9681
+ };
9682
+ args.signal?.addEventListener("abort", onAbort, { once: true });
9683
+ const startMs = Date.now();
9684
+ const timeoutMs = args.timeoutMs ?? 12e4;
9685
+ let lastReportedKb = -1;
9686
+ let lastEmittedLength = 0;
9687
+ try {
9688
+ const transcriptPath = await discoverTranscript(cwd, existingBefore, startMs, timeoutMs, args.signal);
9689
+ while (Date.now() - startMs < timeoutMs) {
9690
+ if (args.signal?.aborted)
9691
+ throw new TmuxRunError("aborted");
9692
+ const { assembled, inputTokens, outputTokens, modelUsed, done } = parseTranscript2(transcriptPath, args.model);
9693
+ if (args.onProgress) {
9694
+ const kb = Math.floor(assembled.length / 1024);
9695
+ if (kb > lastReportedKb) {
9696
+ lastReportedKb = kb;
9697
+ args.onProgress({ bytes: assembled.length, elapsedMs: Date.now() - startMs });
9698
+ }
9699
+ }
9700
+ if (args.onDelta && assembled.length > lastEmittedLength) {
9701
+ const chunk = assembled.slice(lastEmittedLength);
9702
+ lastEmittedLength = assembled.length;
9703
+ try {
9704
+ args.onDelta(chunk);
9705
+ } catch {
9706
+ }
9707
+ }
9708
+ if (done && assembled.length > 0) {
9709
+ return {
9710
+ content: assembled,
9711
+ input_tokens: inputTokens,
9712
+ output_tokens: outputTokens,
9713
+ model: modelUsed
9714
+ };
9715
+ }
9716
+ await sleep(500);
9717
+ }
9718
+ throw new TmuxRunError(`timeout after ${timeoutMs}ms waiting for assistant turn`);
9719
+ } finally {
9720
+ args.signal?.removeEventListener("abort", onAbort);
9721
+ cleanup(cwd, runId, tmuxBin, sessionName);
9722
+ }
9723
+ }
9724
+ function num(v) {
9725
+ return typeof v === "number" ? v : 0;
9726
+ }
9727
+ function sleep(ms) {
9728
+ return new Promise((r) => setTimeout(r, ms));
9729
+ }
9730
+ var PROJECTS_ROOT = () => join6(homedir3(), ".claude", "projects");
9731
+ function snapshotAllTranscripts() {
9732
+ const out = /* @__PURE__ */ new Set();
9733
+ const root = PROJECTS_ROOT();
9734
+ let subs;
9735
+ try {
9736
+ subs = readdirSync4(root);
9737
+ } catch {
9738
+ return out;
9739
+ }
9740
+ for (const sub of subs) {
9741
+ const dir = join6(root, sub);
9742
+ let files;
9743
+ try {
9744
+ files = readdirSync4(dir);
9745
+ } catch {
9746
+ continue;
9747
+ }
9748
+ for (const f of files) {
9749
+ if (f.endsWith(".jsonl"))
9750
+ out.add(join6(dir, f));
9751
+ }
9752
+ }
9753
+ return out;
9754
+ }
9755
+ function readJsonlCwd(path5, maxLines = 8) {
9756
+ let raw;
9757
+ try {
9758
+ raw = readFileSync10(path5, "utf8");
9759
+ } catch {
9760
+ return void 0;
9761
+ }
9762
+ let count = 0;
9763
+ for (const line of raw.split("\n")) {
9764
+ const t = line.trim();
9765
+ if (!t)
9766
+ continue;
9767
+ count++;
9768
+ try {
9769
+ const o = JSON.parse(t);
9770
+ if (typeof o.cwd === "string")
9771
+ return o.cwd;
9772
+ } catch {
9773
+ }
9774
+ if (count >= maxLines)
9775
+ break;
9776
+ }
9777
+ return void 0;
9778
+ }
9779
+ async function discoverTranscript(targetCwd, existingBefore, startMs, timeoutMs, signal) {
9780
+ while (Date.now() - startMs < timeoutMs) {
9781
+ if (signal?.aborted)
9782
+ throw new TmuxRunError("aborted");
9783
+ const root = PROJECTS_ROOT();
9784
+ let subs;
9785
+ try {
9786
+ subs = readdirSync4(root);
9787
+ } catch {
9788
+ subs = [];
9789
+ }
9790
+ for (const sub of subs) {
9791
+ const dir = join6(root, sub);
9792
+ let files;
9793
+ try {
9794
+ files = readdirSync4(dir);
9795
+ } catch {
9796
+ continue;
9797
+ }
9798
+ for (const f of files) {
9799
+ if (!f.endsWith(".jsonl"))
9800
+ continue;
9801
+ const full = join6(dir, f);
9802
+ if (existingBefore.has(full))
9803
+ continue;
9804
+ if (readJsonlCwd(full) === targetCwd)
9805
+ return full;
9806
+ }
9807
+ }
9808
+ await sleep(300);
9809
+ }
9810
+ throw new TmuxRunError(`timeout waiting for claude to create the session transcript (cwd: ${targetCwd})`);
9811
+ }
9812
+ function parseTranscript2(path5, defaultModel) {
9813
+ let raw;
9814
+ try {
9815
+ raw = readFileSync10(path5, "utf8");
9816
+ } catch {
9817
+ return { assembled: "", inputTokens: 0, outputTokens: 0, modelUsed: defaultModel, done: false };
9818
+ }
9819
+ let assembled = "";
9820
+ let inputTokens = 0;
9821
+ let outputTokens = 0;
9822
+ let modelUsed = defaultModel;
9823
+ let done = false;
9824
+ for (const line of raw.split("\n")) {
9825
+ const t = line.trim();
9826
+ if (!t)
9827
+ continue;
9828
+ let o;
9829
+ try {
9830
+ o = JSON.parse(t);
9831
+ } catch {
9832
+ continue;
9833
+ }
9834
+ if (o.type !== "assistant")
9835
+ continue;
9836
+ const m = o.message;
9837
+ if (!m)
9838
+ continue;
9839
+ const mm = m.model;
9840
+ if (mm)
9841
+ modelUsed = mm;
9842
+ const content = m.content;
9843
+ if (Array.isArray(content)) {
9844
+ for (const block of content) {
9845
+ if (block.type === "text" && typeof block.text === "string") {
9846
+ assembled += block.text;
9847
+ }
9848
+ }
9849
+ }
9850
+ const usage = m.usage;
9851
+ if (usage) {
9852
+ inputTokens = num(usage.input_tokens) + num(usage.cache_creation_input_tokens) + num(usage.cache_read_input_tokens);
9853
+ outputTokens = num(usage.output_tokens);
9854
+ }
9855
+ if (m.stop_reason === "end_turn") {
9856
+ done = true;
9857
+ }
9858
+ }
9859
+ return { assembled, inputTokens, outputTokens, modelUsed, done };
9860
+ }
9861
+ function cleanup(cwd, runId, tmuxBin, sessionName) {
9862
+ try {
9863
+ spawnSync(tmuxBin, ["kill-session", "-t", sessionName], { stdio: "ignore" });
9864
+ } catch {
9865
+ }
9866
+ if (process.env.FLEETLENS_TMUX_KEEP_WRAPPER !== "1") {
9867
+ for (const f of [`system-${runId}.txt`, `user-${runId}.txt`, `run-${runId}.sh`]) {
9868
+ try {
9869
+ unlinkSync2(join6(cwd, f));
9870
+ } catch {
9871
+ }
9872
+ }
9873
+ }
9874
+ }
9875
+ function shellEscape(s) {
9876
+ if (/^[A-Za-z0-9_./-]+$/.test(s))
9877
+ return s;
9878
+ return `'${s.replace(/'/g, `'"'"'`)}'`;
9879
+ }
9880
+
9881
+ // ../entries/dist/llm-runner.js
9882
+ var RUNS_DIR = cclensPath("llm-runs");
9454
9883
  function ensureRunsDir() {
9455
- if (!existsSync6(RUNS_DIR)) {
9884
+ if (!existsSync7(RUNS_DIR)) {
9456
9885
  try {
9457
- mkdirSync8(RUNS_DIR, { recursive: true });
9886
+ mkdirSync9(RUNS_DIR, { recursive: true });
9458
9887
  } catch {
9459
9888
  }
9460
9889
  }
@@ -9481,7 +9910,7 @@ function newRunId(kind) {
9481
9910
  return `${ts}_${kind}_${short}`;
9482
9911
  }
9483
9912
  function tracePath(runId) {
9484
- return join9(RUNS_DIR, `${runId}.jsonl`);
9913
+ return join7(RUNS_DIR, `${runId}.jsonl`);
9485
9914
  }
9486
9915
  function safeAppend(path5, line) {
9487
9916
  try {
@@ -9491,11 +9920,84 @@ function safeAppend(path5, line) {
9491
9920
  }
9492
9921
  function safeWrite(path5, line) {
9493
9922
  try {
9494
- writeFileSync7(path5, line);
9923
+ writeFileSync8(path5, line);
9495
9924
  } catch {
9496
9925
  }
9497
9926
  }
9498
- function runClaudeSubprocess(args) {
9927
+ async function runClaudeSubprocess(args) {
9928
+ if (process.env.FLEETLENS_FORCE_PRINT_MODE !== "1") {
9929
+ const avail = tmuxRunnerAvailable();
9930
+ if (avail.ok) {
9931
+ const startedAt = (/* @__PURE__ */ new Date()).toISOString();
9932
+ const kind = detectKindFromSystemPrompt(args.systemPrompt);
9933
+ const runId = newRunId(kind);
9934
+ const trace = tracePath(runId);
9935
+ ensureRunsDir();
9936
+ safeWrite(trace, JSON.stringify({
9937
+ _meta: {
9938
+ type: "start",
9939
+ run_id: runId,
9940
+ kind,
9941
+ model: args.model,
9942
+ ts: startedAt,
9943
+ runtime: "tmux",
9944
+ user_prompt_chars: args.userPrompt.length,
9945
+ reminder_chars: args.reminder?.length ?? 0
9946
+ }
9947
+ }) + "\n");
9948
+ safeAppend(trace, JSON.stringify({
9949
+ _meta: {
9950
+ type: "payload",
9951
+ run_id: runId,
9952
+ system_prompt: args.systemPrompt,
9953
+ user_prompt: args.userPrompt,
9954
+ reminder: args.reminder ?? null
9955
+ }
9956
+ }) + "\n");
9957
+ try {
9958
+ const startMs = Date.now();
9959
+ const res = await runClaudeUnderTmux({
9960
+ systemPrompt: args.systemPrompt,
9961
+ model: args.model,
9962
+ userPrompt: args.userPrompt,
9963
+ reminder: args.reminder,
9964
+ onProgress: args.onProgress
9965
+ });
9966
+ safeAppend(trace, JSON.stringify({
9967
+ _meta: {
9968
+ type: "end",
9969
+ run_id: runId,
9970
+ runtime: "tmux",
9971
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
9972
+ elapsed_ms: Date.now() - startMs,
9973
+ // tmux runs have no subprocess exit code (the session is killed
9974
+ // by cleanup). Stamp 0 on success so /api/runs renders them
9975
+ // as `ok` rather than `error`.
9976
+ exit_code: 0,
9977
+ content_chars: res.content.length,
9978
+ input_tokens: res.input_tokens,
9979
+ output_tokens: res.output_tokens,
9980
+ model_used: res.model
9981
+ }
9982
+ }) + "\n");
9983
+ return res;
9984
+ } catch (err) {
9985
+ const isExpected = err instanceof TmuxUnavailableError || err instanceof TmuxRunError;
9986
+ safeAppend(trace, JSON.stringify({
9987
+ _meta: {
9988
+ type: "tmux_fallback",
9989
+ run_id: runId,
9990
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
9991
+ error: err.message,
9992
+ expected: isExpected
9993
+ }
9994
+ }) + "\n");
9995
+ }
9996
+ }
9997
+ }
9998
+ return runClaudePrintMode(args);
9999
+ }
10000
+ function runClaudePrintMode(args) {
9499
10001
  return new Promise((resolve, reject) => {
9500
10002
  ensureRunsDir();
9501
10003
  const kind = detectKindFromSystemPrompt(args.systemPrompt);
@@ -9806,29 +10308,29 @@ function applyEnrichmentError(entry, errorMessage, model, costUsd, generatedAt,
9806
10308
  }
9807
10309
 
9808
10310
  // ../entries/dist/budget.js
9809
- import { appendFileSync as appendFileSync4, readFileSync as readFileSync10, existsSync as existsSync7, mkdirSync as mkdirSync9 } from "node:fs";
9810
- import { dirname as dirname7, join as join10 } from "node:path";
9811
- import { homedir as homedir10 } from "node:os";
10311
+ init_fs();
10312
+ import { appendFileSync as appendFileSync4, readFileSync as readFileSync11, existsSync as existsSync8, mkdirSync as mkdirSync10 } from "node:fs";
10313
+ import { dirname as dirname7 } from "node:path";
9812
10314
  var spendPathCached = null;
9813
10315
  function spendPath() {
9814
10316
  if (spendPathCached)
9815
10317
  return spendPathCached;
9816
- spendPathCached = join10(homedir10(), ".cclens", "llm-spend.jsonl");
10318
+ spendPathCached = cclensPath("llm-spend.jsonl");
9817
10319
  return spendPathCached;
9818
10320
  }
9819
10321
  function appendSpend(record) {
9820
10322
  const p = spendPath();
9821
- mkdirSync9(dirname7(p), { recursive: true });
10323
+ mkdirSync10(dirname7(p), { recursive: true });
9822
10324
  appendFileSync4(p, JSON.stringify(record) + "\n", { encoding: "utf8" });
9823
10325
  }
9824
10326
  function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
9825
10327
  const p = spendPath();
9826
- if (!existsSync7(p))
10328
+ if (!existsSync8(p))
9827
10329
  return 0;
9828
10330
  const year = now.getUTCFullYear();
9829
10331
  const month = now.getUTCMonth();
9830
10332
  let total = 0;
9831
- const raw = readFileSync10(p, "utf8");
10333
+ const raw = readFileSync11(p, "utf8");
9832
10334
  for (const line of raw.split("\n")) {
9833
10335
  if (!line)
9834
10336
  continue;
@@ -9849,9 +10351,8 @@ function monthToDateSpend(now = /* @__PURE__ */ new Date()) {
9849
10351
  }
9850
10352
 
9851
10353
  // ../entries/dist/pipeline-lock.js
9852
- import { writeFileSync as writeFileSync8, unlinkSync as unlinkSync2, existsSync as existsSync8, readFileSync as readFileSync11, statSync as statSync3 } from "node:fs";
9853
- import { join as join11 } from "node:path";
9854
- import { homedir as homedir11 } from "node:os";
10354
+ init_fs();
10355
+ import { writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, existsSync as existsSync9, readFileSync as readFileSync12, statSync as statSync3 } from "node:fs";
9855
10356
  var STALE_MS2 = 60 * 1e3;
9856
10357
  var HEARTBEAT_MS = 30 * 1e3;
9857
10358
  var lockPathCached = null;
@@ -9859,11 +10360,11 @@ var heartbeat = null;
9859
10360
  function lockPath() {
9860
10361
  if (lockPathCached)
9861
10362
  return lockPathCached;
9862
- lockPathCached = join11(homedir11(), ".cclens", "llm-interactive.lock");
10363
+ lockPathCached = cclensPath("llm-interactive.lock");
9863
10364
  return lockPathCached;
9864
10365
  }
9865
10366
  function touchLock() {
9866
- writeFileSync8(lockPath(), String(process.pid), "utf8");
10367
+ writeFileSync9(lockPath(), String(process.pid), "utf8");
9867
10368
  }
9868
10369
  function writeInteractiveLock() {
9869
10370
  touchLock();
@@ -9883,7 +10384,7 @@ function removeInteractiveLock() {
9883
10384
  heartbeat = null;
9884
10385
  }
9885
10386
  try {
9886
- unlinkSync2(lockPath());
10387
+ unlinkSync3(lockPath());
9887
10388
  } catch {
9888
10389
  }
9889
10390
  }
@@ -9897,13 +10398,13 @@ function pidAlive(pid) {
9897
10398
  }
9898
10399
  function interactiveLockFresh(nowMs) {
9899
10400
  const p = lockPath();
9900
- if (!existsSync8(p))
10401
+ if (!existsSync9(p))
9901
10402
  return false;
9902
10403
  try {
9903
10404
  const mtime = statSync3(p).mtimeMs;
9904
10405
  if (nowMs - mtime > STALE_MS2)
9905
10406
  return false;
9906
- const pid = Number(readFileSync11(p, "utf8").trim());
10407
+ const pid = Number(readFileSync12(p, "utf8").trim());
9907
10408
  if (!Number.isFinite(pid) || pid <= 0)
9908
10409
  return false;
9909
10410
  if (!pidAlive(pid))
@@ -9918,9 +10419,8 @@ function interactiveLockFresh(nowMs) {
9918
10419
  var THIRTY_MIN_MS = 30 * 60 * 1e3;
9919
10420
 
9920
10421
  // ../entries/dist/settings.js
9921
- import { readFileSync as readFileSync12, writeFileSync as writeFileSync9, renameSync as renameSync4, chmodSync as chmodSync2, mkdirSync as mkdirSync10, existsSync as existsSync9 } from "node:fs";
9922
- import { dirname as dirname8, join as join12 } from "node:path";
9923
- import { homedir as homedir12 } from "node:os";
10422
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync10, renameSync as renameSync5, chmodSync as chmodSync2, mkdirSync as mkdirSync11, existsSync as existsSync10 } from "node:fs";
10423
+ init_fs();
9924
10424
  var DEFAULT_SETTINGS = {
9925
10425
  ai_features: {
9926
10426
  enabled: true,
@@ -9934,7 +10434,7 @@ var settingsPathCached = null;
9934
10434
  function settingsPath() {
9935
10435
  if (settingsPathCached)
9936
10436
  return settingsPathCached;
9937
- settingsPathCached = join12(homedir12(), ".cclens", "settings.json");
10437
+ settingsPathCached = cclensPath("settings.json");
9938
10438
  return settingsPathCached;
9939
10439
  }
9940
10440
  function fromDisk(d) {
@@ -9951,10 +10451,10 @@ function fromDisk(d) {
9951
10451
  }
9952
10452
  function readSettings() {
9953
10453
  const p = settingsPath();
9954
- if (!existsSync9(p))
10454
+ if (!existsSync10(p))
9955
10455
  return DEFAULT_SETTINGS;
9956
10456
  try {
9957
- const raw = readFileSync12(p, "utf8");
10457
+ const raw = readFileSync13(p, "utf8");
9958
10458
  return fromDisk(JSON.parse(raw));
9959
10459
  } catch {
9960
10460
  return DEFAULT_SETTINGS;
@@ -12677,11 +13177,10 @@ async function backfillYesterdayDigest(opts = {}) {
12677
13177
  }
12678
13178
 
12679
13179
  // src/daemon-worker.ts
12680
- var STATE_DIR = join13(homedir13(), ".cclens");
12681
- var USAGE_LOG3 = join13(STATE_DIR, "usage.jsonl");
12682
- var DAEMON_LOG = join13(STATE_DIR, "daemon.log");
13180
+ var USAGE_LOG2 = cclensPath("usage.jsonl");
13181
+ var DAEMON_LOG = cclensPath("daemon.log");
12683
13182
  var WATCHDOG_INTERVAL_MS = 5 * 1e3;
12684
- mkdirSync11(dirname9(USAGE_LOG3), { recursive: true });
13183
+ mkdirSync12(dirname8(USAGE_LOG2), { recursive: true });
12685
13184
  function log2(level, message) {
12686
13185
  const line = `${(/* @__PURE__ */ new Date()).toISOString()} ${level.toUpperCase()} ${message}
12687
13186
  `;
@@ -12734,7 +13233,7 @@ async function tick() {
12734
13233
  seven_day_cowork: null,
12735
13234
  extra_usage: null
12736
13235
  };
12737
- appendSnapshot(USAGE_LOG3, snapshot);
13236
+ appendSnapshot(USAGE_LOG2, snapshot);
12738
13237
  log2(
12739
13238
  "info",
12740
13239
  `${source.kind} snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
@@ -12745,7 +13244,7 @@ async function tick() {
12745
13244
  }
12746
13245
  try {
12747
13246
  const snapshot = await fetchUsage();
12748
- appendSnapshot(USAGE_LOG3, snapshot);
13247
+ appendSnapshot(USAGE_LOG2, snapshot);
12749
13248
  log2(
12750
13249
  "info",
12751
13250
  `claude-code snapshot 5h=${snapshot.five_hour.utilization}% 7d=${snapshot.seven_day.utilization}%`
@@ -12771,7 +13270,7 @@ function scheduleAfter(now, outcome) {
12771
13270
  }
12772
13271
  nextPollAtMs = now + currentIntervalMs;
12773
13272
  }
12774
- function sleep(ms) {
13273
+ function sleep2(ms) {
12775
13274
  return new Promise((resolve) => setTimeout(resolve, ms));
12776
13275
  }
12777
13276
  async function runLoop() {
@@ -12804,7 +13303,7 @@ async function runLoop() {
12804
13303
  }
12805
13304
  await runTeamSync(log2);
12806
13305
  }
12807
- await sleep(WATCHDOG_INTERVAL_MS);
13306
+ await sleep2(WATCHDOG_INTERVAL_MS);
12808
13307
  }
12809
13308
  }
12810
13309
  log2(