fleetlens 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/build-manifest.json +3 -3
  3. package/app/apps/web/.next/prerender-manifest.json +3 -3
  4. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  12. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/app/apps/web/.next/server/app/api/ask/route.js +1 -1
  14. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  15. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +3 -3
  16. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +3 -3
  18. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -1
  19. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +2 -2
  20. package/app/apps/web/.next/server/app/api/digest/month-index/route.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +3 -3
  22. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -1
  23. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +2 -2
  24. package/app/apps/web/.next/server/app/api/digest/week-index/route.js.nft.json +1 -1
  25. package/app/apps/web/.next/server/app/api/events/route.js +1 -1
  26. package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
  27. package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -1
  28. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js.nft.json +1 -1
  29. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.nft.json +1 -1
  30. package/app/apps/web/.next/server/app/api/settings/route.js +4 -4
  31. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -1
  32. package/app/apps/web/.next/server/app/changelog/page.js.nft.json +1 -1
  33. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  34. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -1
  35. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  36. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -1
  37. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  38. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -1
  39. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  40. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -1
  41. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  42. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  43. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  44. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  45. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  46. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  47. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  48. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  49. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  50. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  51. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  52. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  53. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  54. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -1
  55. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  56. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  58. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  59. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  60. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  61. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  62. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  63. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  64. package/app/apps/web/.next/server/chunks/[root-of-the-server]__07qxzx4._.js +9 -0
  65. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0fu2xfy._.js +5 -0
  66. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0gfd42k._.js +9 -0
  67. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0i.m8y0._.js +3 -0
  68. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0iy5aqy._.js +9 -0
  69. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh7-nf._.js +3 -0
  70. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nvdffv._.js +3 -0
  71. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s2~c3g._.js +3 -0
  72. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js +3 -3
  73. package/app/apps/web/.next/server/chunks/packages_09wmnv.._.js +3 -0
  74. package/app/apps/web/.next/server/chunks/packages_0o6.gpk._.js +3 -0
  75. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +13 -13
  76. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_122oe0-.js +1 -1
  77. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0d~2~le._.js +1 -1
  78. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +1 -1
  79. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0s4dg1y._.js +3 -0
  80. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0tejjy_._.js +1 -1
  81. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
  82. package/app/apps/web/.next/server/chunks/ssr/_0jw2sm7._.js +1 -1
  83. package/app/apps/web/.next/server/chunks/ssr/_0xu2pvc._.js +1 -1
  84. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0ly1xes._.js +1 -1
  85. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +1 -1
  86. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
  87. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_0m67-xi._.js +1 -1
  88. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +1 -1
  89. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_10_oegc._.js +1 -1
  90. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  91. package/app/apps/web/.next/server/pages/500.html +1 -1
  92. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  93. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  94. package/app/apps/web/.next/static/chunks/04a36uhu~p_z-.css +1 -0
  95. package/app/apps/web/.next/static/chunks/{0q2vd~aj.1hpz.js → 09--oejbzw3q-.js} +3 -3
  96. package/app/apps/web/.next/static/chunks/0l3ck.awv~4t7.js +1 -0
  97. package/app/apps/web/.next/static/chunks/{171za22fv684..js → 0lxuac2v0_gdl.js} +2 -2
  98. package/app/apps/web/.next/static/chunks/0n0n.0279ot6c.js +1 -0
  99. package/app/apps/web/.next/static/chunks/0qcu452dr~edz.js +14 -0
  100. package/app/apps/web/.next/static/chunks/0uev~g~qvbjv9.js +4 -0
  101. package/app/apps/web/components/previous-cycles-trend.tsx +26 -11
  102. package/app/apps/web/components/usage-chart.tsx +35 -37
  103. package/app/apps/web/components/usage-gauges.tsx +18 -12
  104. package/app/apps/web/components/usage-sidebar.tsx +23 -12
  105. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  106. package/app/apps/web/lib/utilization-tone.ts +74 -0
  107. package/app/apps/web/package.json +1 -1
  108. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  109. package/dist/daemon-worker.js +133 -31
  110. package/dist/index.js +988 -887
  111. package/package.json +1 -1
  112. package/app/apps/web/.next/server/chunks/[externals]__0fpbr8-._.js +0 -3
  113. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0-vgrh1._.js +0 -3
  114. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.z48ue._.js +0 -3
  115. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +0 -9
  116. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0dctov1._.js +0 -5
  117. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0e8n_x4._.js +0 -3
  118. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +0 -9
  119. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +0 -9
  120. package/app/apps/web/.next/server/chunks/packages_09hmrqx._.js +0 -3
  121. package/app/apps/web/.next/server/chunks/packages_118y1lp._.js +0 -3
  122. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ytdqxt._.js +0 -3
  123. package/app/apps/web/.next/static/chunks/05m.oz3kmf1p7.js +0 -1
  124. package/app/apps/web/.next/static/chunks/07-fq4im3pmjp.js +0 -4
  125. package/app/apps/web/.next/static/chunks/0cxyt4-24..b7.js +0 -14
  126. package/app/apps/web/.next/static/chunks/0o9ayt8sknubd.js +0 -1
  127. package/app/apps/web/.next/static/chunks/0wfbj5zr~az.z.css +0 -1
  128. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → L0Dy1hOQrZjV9l0TNulvk}/_buildManifest.js +0 -0
  129. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → L0Dy1hOQrZjV9l0TNulvk}/_clientMiddlewareManifest.js +0 -0
  130. /package/app/apps/web/.next/static/{u6-8f8u1tspYCacGAz53R → L0Dy1hOQrZjV9l0TNulvk}/_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
  };
@@ -1121,8 +1195,8 @@ function parseTranscript(rawLines) {
1121
1195
  }
1122
1196
  if (e.role === "user") {
1123
1197
  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>");
1198
+ const rawContent = extractRawUserText(rawMsg);
1199
+ const isHidden = isFrameworkInjectedUserInput(rawContent);
1126
1200
  const isTeamNoise = e.teammateMessage !== void 0 && !agentName;
1127
1201
  if (!isHidden && !isTeamNoise) {
1128
1202
  if (!firstUserPreview) {
@@ -1207,6 +1281,7 @@ var BLANK_USAGE2, TEAMMATE_MSG_RE;
1207
1281
  var init_parser = __esm({
1208
1282
  "../parser/dist/parser.js"() {
1209
1283
  "use strict";
1284
+ init_user_input();
1210
1285
  BLANK_USAGE2 = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
1211
1286
  TEAMMATE_MSG_RE = /^\s*<teammate-message\s+teammate_id="([^"]+)"[^>]*>([\s\S]*?)<\/teammate-message>/;
1212
1287
  }
@@ -2025,7 +2100,8 @@ function parseRollout(file, lines) {
2025
2100
  if (type === "event_msg" && subtype === "user_message") {
2026
2101
  const text = typeof payload.message === "string" ? payload.message : "";
2027
2102
  const preview = previewOf(text);
2028
- if (text) {
2103
+ const isHidden = isFrameworkInjectedUserInput(text);
2104
+ if (text && !isHidden) {
2029
2105
  if (!firstUserPreview)
2030
2106
  firstUserPreview = preview;
2031
2107
  lastUserPreview = preview;
@@ -2342,6 +2418,7 @@ var init_codex = __esm({
2342
2418
  "../parser/dist/codex.js"() {
2343
2419
  "use strict";
2344
2420
  init_analytics();
2421
+ init_user_input();
2345
2422
  DEFAULT_CODEX_ROOT = path2.join(os2.homedir(), ".codex", "sessions");
2346
2423
  ROLLOUT_RE = /^rollout-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})-([0-9a-f-]+)\.jsonl$/;
2347
2424
  IDLE_GAP_MS = 3 * 60 * 1e3;
@@ -2564,7 +2641,8 @@ async function parseSession(file) {
2564
2641
  if (msg.type === "user") {
2565
2642
  const text = flattenContent(msg.displayContent ?? msg.content);
2566
2643
  const preview = previewOf2(text);
2567
- if (text) {
2644
+ const isHidden = isFrameworkInjectedUserInput(text);
2645
+ if (text && !isHidden) {
2568
2646
  if (!firstUserPreview)
2569
2647
  firstUserPreview = preview;
2570
2648
  lastUserPreview = preview;
@@ -2839,6 +2917,7 @@ var init_gemini = __esm({
2839
2917
  "../parser/dist/gemini.js"() {
2840
2918
  "use strict";
2841
2919
  init_analytics();
2920
+ init_user_input();
2842
2921
  DEFAULT_GEMINI_ROOT = path3.join(os3.homedir(), ".gemini", "tmp");
2843
2922
  GEMINI_PROJECTS_FILE = path3.join(os3.homedir(), ".gemini", "projects.json");
2844
2923
  SESSION_FILE_RE = /^session-.+\.(jsonl|json)$/;
@@ -3339,7 +3418,13 @@ function buildPresentation(events) {
3339
3418
  return false;
3340
3419
  if (e.role === "user") {
3341
3420
  const txt = firstTextOfBlocks(e.blocks) ?? "";
3342
- if (SKILL_CONTENT_RE.test(txt))
3421
+ if (e.blocks.length === 0 || !txt.trim())
3422
+ return false;
3423
+ if (SLASH_COMMAND_RE.test(txt))
3424
+ return true;
3425
+ if (TASK_NOTIFICATION_RE.test(txt))
3426
+ return true;
3427
+ if (isFrameworkInjectedUserInput(txt))
3343
3428
  return false;
3344
3429
  }
3345
3430
  return true;
@@ -3467,13 +3552,13 @@ function buildPresentation(events) {
3467
3552
  }
3468
3553
  return rows;
3469
3554
  }
3470
- var INTERRUPT_RE, RATE_LIMIT_RE, SKILL_CONTENT_RE, SLASH_COMMAND_RE, TASK_NOTIFICATION_RE;
3555
+ var INTERRUPT_RE, RATE_LIMIT_RE, SLASH_COMMAND_RE, TASK_NOTIFICATION_RE;
3471
3556
  var init_presentation = __esm({
3472
3557
  "../parser/dist/presentation.js"() {
3473
3558
  "use strict";
3559
+ init_user_input();
3474
3560
  INTERRUPT_RE = /\[request interrupted|interrupted by user/i;
3475
3561
  RATE_LIMIT_RE = /rate.?limit|overloaded_error|api error|Error sending message/i;
3476
- SKILL_CONTENT_RE = /^Base directory for this skill:/;
3477
3562
  SLASH_COMMAND_RE = /<command-name>(\/[^<\s]+)<\/command-name>(?:[\s\S]*?<command-args>([\s\S]*?)<\/command-args>)?/;
3478
3563
  TASK_NOTIFICATION_RE = /<task-notification>/;
3479
3564
  }
@@ -3607,6 +3692,7 @@ __export(dist_exports, {
3607
3692
  groupSnapsByCycle: () => groupSnapsByCycle,
3608
3693
  highLevelMetrics: () => highLevelMetrics,
3609
3694
  isAgentKind: () => isAgentKind,
3695
+ isFrameworkInjectedUserInput: () => isFrameworkInjectedUserInput,
3610
3696
  last4CompletedWeeks: () => last4CompletedWeeks,
3611
3697
  modelFamily: () => modelFamily,
3612
3698
  parseTranscript: () => parseTranscript,
@@ -3617,6 +3703,7 @@ __export(dist_exports, {
3617
3703
  rowPrimaryIndex: () => rowPrimaryIndex,
3618
3704
  sessionAirTimeMs: () => sessionAirTimeMs,
3619
3705
  sessionDay: () => sessionDay,
3706
+ stripFrameworkBoilerplate: () => stripFrameworkBoilerplate,
3620
3707
  summarizeBursts: () => summarizeBursts,
3621
3708
  toLocalDay: () => toLocalDay,
3622
3709
  userSoloRate: () => userSoloRate,
@@ -3627,6 +3714,7 @@ var init_dist = __esm({
3627
3714
  "use strict";
3628
3715
  init_types();
3629
3716
  init_parser();
3717
+ init_user_input();
3630
3718
  init_presentation();
3631
3719
  init_analytics();
3632
3720
  init_aggregate();
@@ -3799,9 +3887,13 @@ function readSnapshots(filePath) {
3799
3887
  }
3800
3888
  return snapshots;
3801
3889
  }
3802
- function latestSnapshot(filePath) {
3890
+ function latestClaudeCodeSnapshot(filePath) {
3803
3891
  const all = readSnapshots(filePath);
3804
- return all.length > 0 ? all[all.length - 1] : null;
3892
+ for (let i = all.length - 1; i >= 0; i--) {
3893
+ const s = all[i];
3894
+ if (!s.agent || s.agent === "claude-code") return s;
3895
+ }
3896
+ return null;
3805
3897
  }
3806
3898
 
3807
3899
  // src/daemon-worker.ts
@@ -3843,7 +3935,7 @@ init_dist();
3843
3935
  import { randomUUID } from "node:crypto";
3844
3936
  var SNAPSHOT_FRESHNESS_MS = 10 * 60 * 1e3;
3845
3937
  function readLatestUsageSnapshotForWire(filePath, nowMs = Date.now()) {
3846
- const raw = latestSnapshot(filePath);
3938
+ const raw = latestClaudeCodeSnapshot(filePath);
3847
3939
  if (!raw) return null;
3848
3940
  const capturedMs = Date.parse(raw.captured_at);
3849
3941
  if (Number.isNaN(capturedMs)) return null;
@@ -4264,17 +4356,21 @@ var PROMPT_FRAME_ORIGIN = {
4264
4356
  };
4265
4357
 
4266
4358
  // ../entries/dist/signals.js
4359
+ init_dist();
4267
4360
  var TEAMMATE_RE = /^<teammate-message\b/;
4268
4361
  var SKILL_LOAD_RE = /^Base directory for this skill:/;
4269
4362
  var SLASH_COMMAND_RE2 = /^<command-name>|^<local-command-stdout>/;
4270
4363
  function classifyUserInputSource(text) {
4271
4364
  if (!text)
4272
4365
  return "human";
4273
- if (TEAMMATE_RE.test(text))
4366
+ const stripped = stripFrameworkBoilerplate(text);
4367
+ if (!stripped)
4368
+ return "system_instruction";
4369
+ if (TEAMMATE_RE.test(stripped))
4274
4370
  return "teammate";
4275
- if (SKILL_LOAD_RE.test(text))
4371
+ if (SKILL_LOAD_RE.test(stripped))
4276
4372
  return "skill_load";
4277
- if (SLASH_COMMAND_RE2.test(text))
4373
+ if (SLASH_COMMAND_RE2.test(stripped))
4278
4374
  return "slash_command";
4279
4375
  return "human";
4280
4376
  }
@@ -4663,7 +4759,7 @@ function aggregateDay(dayEvents, _sessionFallbackProject) {
4663
4759
  closeTurn(cur, closed, eventCwd);
4664
4760
  }
4665
4761
  cur = newTurn(tsMs, text);
4666
- if (!firstUser && text && !text.startsWith("<command-name>")) {
4762
+ if (!firstUser && text && classifyUserInputSource(text) === "human") {
4667
4763
  firstUser = text;
4668
4764
  }
4669
4765
  } else {
@@ -4907,7 +5003,13 @@ function buildEntries(sessionDetail) {
4907
5003
  return classifyUserInputSource(text) === "human";
4908
5004
  }).map((ev) => blockText(ev.blocks) || ev.preview || "").join("\n");
4909
5005
  const satisfaction_signals = countSatisfactionSignals(humanText);
4910
- const user_input_sources = { human: 0, teammate: 0, skill_load: 0, slash_command: 0 };
5006
+ const user_input_sources = {
5007
+ human: 0,
5008
+ teammate: 0,
5009
+ skill_load: 0,
5010
+ slash_command: 0,
5011
+ system_instruction: 0
5012
+ };
4911
5013
  for (const ev of dayEvents) {
4912
5014
  const v = viewEvent(ev);
4913
5015
  if (v.rawType !== "user")