fleetlens 0.16.1 → 0.16.2

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 (68) 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_client-reference-manifest.js +1 -1
  12. package/app/apps/web/.next/server/app/agent/page_client-reference-manifest.js +1 -1
  13. package/app/apps/web/.next/server/app/changelog/page_client-reference-manifest.js +1 -1
  14. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +1 -1
  15. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +1 -1
  16. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +1 -1
  17. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +1 -1
  18. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  19. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  20. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  21. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  22. package/app/apps/web/.next/server/app/print/[key]/page_client-reference-manifest.js +1 -1
  23. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  24. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  25. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +1 -1
  26. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  27. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  28. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  29. package/app/apps/web/.next/server/app/team/onboarding/page_client-reference-manifest.js +1 -1
  30. package/app/apps/web/.next/server/app/team/page_client-reference-manifest.js +1 -1
  31. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  32. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02faosk._.js +3 -3
  33. package/app/apps/web/.next/server/chunks/[root-of-the-server]__09cgmam._.js +2 -2
  34. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0tk8p3d._.js +2 -2
  35. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0u6pamj._.js +2 -2
  36. package/app/apps/web/.next/server/chunks/[root-of-the-server]__12jomao._.js +2 -2
  37. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0sr4wr_.js +1 -1
  38. package/app/apps/web/.next/server/chunks/packages_parser_dist_06d9se1._.js +1 -1
  39. package/app/apps/web/.next/server/chunks/packages_parser_dist_10ihc3~._.js +1 -1
  40. package/app/apps/web/.next/server/chunks/ssr/_0k8yioi._.js +1 -1
  41. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_[id]_session-view_tsx_0-9t5~.._.js +1 -1
  42. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_sessions_sessions-grid_tsx_0bri5x.._.js +1 -1
  43. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0n7_p1d._.js +1 -1
  44. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_changelog_ts_0nb5_-s._.js +1 -1
  45. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0mx_509._.js +1 -1
  46. package/app/apps/web/.next/server/middleware-build-manifest.js +3 -3
  47. package/app/apps/web/.next/server/middleware-manifest.json +5 -5
  48. package/app/apps/web/.next/server/pages/500.html +1 -1
  49. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  50. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  51. package/app/apps/web/.next/static/chunks/0jes0m38a9ib_.js +14 -0
  52. package/app/apps/web/.next/static/chunks/{07bzlfv97o1ig.js → 0p5ee8wje3zi~.js} +1 -1
  53. package/app/apps/web/.next/static/chunks/{0awkd5df28gvj.js → 0~uugvb4izjd2.js} +1 -1
  54. package/app/apps/web/app/sessions/[id]/session-view.tsx +6 -2
  55. package/app/apps/web/app/sessions/sessions-grid.tsx +5 -1
  56. package/app/apps/web/lib/agent/run.ts +24 -5
  57. package/app/apps/web/lib/changelog-data.generated.ts +1 -1
  58. package/app/apps/web/package.json +1 -1
  59. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  60. package/dist/daemon-worker.js +140 -17
  61. package/dist/index.js +148 -25
  62. package/menubar/FleetlensMenubar.app/Contents/Info.plist +2 -2
  63. package/menubar/FleetlensMenubar.app/Contents/MacOS/FleetlensMenubar +0 -0
  64. package/package.json +1 -1
  65. package/app/apps/web/.next/static/chunks/0at6brbse8wn2.js +0 -14
  66. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → q_fQaCe85j7F9VawBRe81}/_buildManifest.js +0 -0
  67. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → q_fQaCe85j7F9VawBRe81}/_clientMiddlewareManifest.js +0 -0
  68. /package/app/apps/web/.next/static/{d1mwRtSMG-R7wb8o9KxM3 → q_fQaCe85j7F9VawBRe81}/_ssgManifest.js +0 -0
@@ -2785,6 +2785,11 @@ function parseRollout(file, lines) {
2785
2785
  let lastUserPreview;
2786
2786
  let lastAgentPreview;
2787
2787
  const tsMs = [];
2788
+ let threadSource;
2789
+ let rootSessionId;
2790
+ let parentThreadId;
2791
+ let agentNickname;
2792
+ let agentPath;
2788
2793
  let idx = 0;
2789
2794
  for (const line of lines) {
2790
2795
  if (typeof line !== "object" || line === null)
@@ -2805,6 +2810,16 @@ function parseRollout(file, lines) {
2805
2810
  if (type === "session_meta") {
2806
2811
  if (typeof payload.cwd === "string")
2807
2812
  cwd = payload.cwd;
2813
+ if (threadSource === void 0 && typeof payload.thread_source === "string")
2814
+ threadSource = payload.thread_source;
2815
+ if (rootSessionId === void 0 && typeof payload.session_id === "string")
2816
+ rootSessionId = payload.session_id;
2817
+ if (parentThreadId === void 0 && typeof payload.parent_thread_id === "string")
2818
+ parentThreadId = payload.parent_thread_id;
2819
+ if (agentNickname === void 0 && typeof payload.agent_nickname === "string")
2820
+ agentNickname = payload.agent_nickname;
2821
+ if (agentPath === void 0 && typeof payload.agent_path === "string")
2822
+ agentPath = payload.agent_path;
2808
2823
  continue;
2809
2824
  }
2810
2825
  if (type === "turn_context") {
@@ -3008,7 +3023,7 @@ function parseRollout(file, lines) {
3008
3023
  airTimeMs,
3009
3024
  activeSegments
3010
3025
  };
3011
- return { meta, events };
3026
+ return { meta, events, threadSource, rootSessionId, parentThreadId, agentNickname, agentPath };
3012
3027
  }
3013
3028
  function numberOf(v) {
3014
3029
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
@@ -3046,28 +3061,112 @@ function clearCodexCaches() {
3046
3061
  metaCache2.clear();
3047
3062
  detailCache2.clear();
3048
3063
  }
3049
- async function listCodexSessions(opts = {}) {
3050
- const root = opts.root ?? DEFAULT_CODEX_ROOT;
3064
+ async function scanAllCodex(root) {
3051
3065
  const files = await listRolloutFiles(root);
3052
3066
  const out = [];
3053
3067
  for (const file of files) {
3054
3068
  const cached = metaCache2.get(file.filePath);
3055
3069
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3056
- out.push(cached.meta);
3070
+ out.push({
3071
+ file,
3072
+ meta: cached.meta,
3073
+ threadSource: cached.threadSource,
3074
+ rootSessionId: cached.rootSessionId,
3075
+ parentThreadId: cached.parentThreadId,
3076
+ agentNickname: cached.agentNickname,
3077
+ agentPath: cached.agentPath
3078
+ });
3057
3079
  continue;
3058
3080
  }
3059
3081
  try {
3060
3082
  const lines = await readJsonl(file.filePath);
3061
- const { meta } = parseRollout(file, lines);
3083
+ const parsed = parseRollout(file, lines);
3062
3084
  metaCache2.set(file.filePath, {
3063
- meta,
3085
+ meta: parsed.meta,
3064
3086
  mtimeMs: file.mtimeMs,
3065
- sizeBytes: file.sizeBytes
3087
+ sizeBytes: file.sizeBytes,
3088
+ threadSource: parsed.threadSource,
3089
+ rootSessionId: parsed.rootSessionId,
3090
+ parentThreadId: parsed.parentThreadId,
3091
+ agentNickname: parsed.agentNickname,
3092
+ agentPath: parsed.agentPath
3093
+ });
3094
+ out.push({
3095
+ file,
3096
+ meta: parsed.meta,
3097
+ threadSource: parsed.threadSource,
3098
+ rootSessionId: parsed.rootSessionId,
3099
+ parentThreadId: parsed.parentThreadId,
3100
+ agentNickname: parsed.agentNickname,
3101
+ agentPath: parsed.agentPath
3066
3102
  });
3067
- out.push(meta);
3068
3103
  } catch {
3069
3104
  }
3070
3105
  }
3106
+ return out;
3107
+ }
3108
+ function buildSubagentRun(entry, parentStartMs) {
3109
+ const meta = entry.meta;
3110
+ const startMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3111
+ const endMs = meta.lastTimestamp ? Date.parse(meta.lastTimestamp) : void 0;
3112
+ const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
3113
+ const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
3114
+ return {
3115
+ agentId: meta.id,
3116
+ agentType: entry.agentNickname ?? entry.agentPath ?? "subagent",
3117
+ description: entry.agentPath ?? entry.agentNickname ?? meta.id,
3118
+ startMs: startOk,
3119
+ endMs: endOk,
3120
+ durationMs: meta.durationMs,
3121
+ startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
3122
+ endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
3123
+ eventCount: meta.eventCount,
3124
+ totalUsage: meta.totalUsage,
3125
+ model: meta.model,
3126
+ toolCallCount: meta.toolCallCount,
3127
+ finalPreview: meta.lastAgentPreview
3128
+ };
3129
+ }
3130
+ async function listCodexSessions(opts = {}) {
3131
+ const root = opts.root ?? DEFAULT_CODEX_ROOT;
3132
+ const all = await scanAllCodex(root);
3133
+ const subagentsByRoot = /* @__PURE__ */ new Map();
3134
+ for (const entry of all) {
3135
+ if (entry.threadSource !== "subagent" || !entry.rootSessionId)
3136
+ continue;
3137
+ const list = subagentsByRoot.get(entry.rootSessionId);
3138
+ if (list)
3139
+ list.push(entry);
3140
+ else
3141
+ subagentsByRoot.set(entry.rootSessionId, [entry]);
3142
+ }
3143
+ const out = [];
3144
+ for (const entry of all) {
3145
+ if (entry.threadSource === "subagent")
3146
+ continue;
3147
+ const children = subagentsByRoot.get(entry.meta.id);
3148
+ if (!children || children.length === 0) {
3149
+ out.push(entry.meta);
3150
+ continue;
3151
+ }
3152
+ const merged = {
3153
+ ...entry.meta,
3154
+ spawnedAgentCount: children.length,
3155
+ totalUsage: {
3156
+ input: entry.meta.totalUsage.input + children.reduce((s, c) => s + c.meta.totalUsage.input, 0),
3157
+ output: entry.meta.totalUsage.output + children.reduce((s, c) => s + c.meta.totalUsage.output, 0),
3158
+ cacheRead: entry.meta.totalUsage.cacheRead + children.reduce((s, c) => s + c.meta.totalUsage.cacheRead, 0),
3159
+ cacheWrite: entry.meta.totalUsage.cacheWrite + children.reduce((s, c) => s + c.meta.totalUsage.cacheWrite, 0)
3160
+ },
3161
+ toolCallCount: (entry.meta.toolCallCount ?? 0) + children.reduce((s, c) => s + (c.meta.toolCallCount ?? 0), 0)
3162
+ };
3163
+ for (const c of children) {
3164
+ if (c.meta.lastTimestamp && (!merged.lastTimestamp || c.meta.lastTimestamp > merged.lastTimestamp)) {
3165
+ merged.lastTimestamp = c.meta.lastTimestamp;
3166
+ }
3167
+ }
3168
+ out.push(merged);
3169
+ }
3071
3170
  out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
3072
3171
  if (opts.limit !== void 0)
3073
3172
  return out.slice(0, opts.limit);
@@ -3075,17 +3174,41 @@ async function listCodexSessions(opts = {}) {
3075
3174
  }
3076
3175
  async function getCodexSession(id, opts = {}) {
3077
3176
  const root = opts.root ?? DEFAULT_CODEX_ROOT;
3078
- const files = await listRolloutFiles(root);
3079
- const file = files.find((f) => f.sessionId === id);
3080
- if (!file)
3081
- return null;
3177
+ const all = await scanAllCodex(root);
3178
+ const rootEntry = all.find((a) => a.meta.id === id && a.threadSource !== "subagent");
3179
+ if (!rootEntry) {
3180
+ const direct = all.find((a) => a.meta.id === id);
3181
+ if (!direct)
3182
+ return null;
3183
+ const cached2 = detailCache2.get(direct.file.filePath);
3184
+ if (cached2 && cached2.mtimeMs === direct.file.mtimeMs && cached2.sizeBytes === direct.file.sizeBytes) {
3185
+ return cached2.detail;
3186
+ }
3187
+ const lines2 = await readJsonl(direct.file.filePath);
3188
+ const { meta: meta2, events: events2 } = parseRollout(direct.file, lines2);
3189
+ const detail2 = { ...meta2, events: events2 };
3190
+ detailCache2.set(direct.file.filePath, {
3191
+ detail: detail2,
3192
+ mtimeMs: direct.file.mtimeMs,
3193
+ sizeBytes: direct.file.sizeBytes
3194
+ });
3195
+ return detail2;
3196
+ }
3197
+ const file = rootEntry.file;
3082
3198
  const cached = detailCache2.get(file.filePath);
3083
3199
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3084
3200
  return cached.detail;
3085
3201
  }
3086
3202
  const lines = await readJsonl(file.filePath);
3087
3203
  const { meta, events } = parseRollout(file, lines);
3088
- const detail = { ...meta, events };
3204
+ const children = all.filter((a) => a.threadSource === "subagent" && a.rootSessionId === id);
3205
+ const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3206
+ const subagents = children.map((c) => buildSubagentRun(c, parentStartMs)).sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
3207
+ const detail = {
3208
+ ...meta,
3209
+ events,
3210
+ ...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
3211
+ };
3089
3212
  detailCache2.set(file.filePath, {
3090
3213
  detail,
3091
3214
  mtimeMs: file.mtimeMs,
@@ -8043,7 +8166,7 @@ function buildIngestPayload(inputs) {
8043
8166
  return {
8044
8167
  ingestId: randomUUID(),
8045
8168
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
8046
- cliVersion: "0.16.1",
8169
+ cliVersion: "0.16.2",
8047
8170
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
8048
8171
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
8049
8172
  ...richRollup ? { richRollup } : {},
@@ -16977,14 +17100,14 @@ async function getUpdateAvailability() {
16977
17100
  if (isDevMode()) return null;
16978
17101
  const latest = await fetchLatestVersion();
16979
17102
  if (latest === null) return {
16980
- current: "0.16.1",
17103
+ current: "0.16.2",
16981
17104
  latest: null,
16982
17105
  updateAvailable: false
16983
17106
  };
16984
17107
  return {
16985
- current: "0.16.1",
17108
+ current: "0.16.2",
16986
17109
  latest,
16987
- updateAvailable: shouldUpdate("0.16.1", latest)
17110
+ updateAvailable: shouldUpdate("0.16.2", latest)
16988
17111
  };
16989
17112
  }
16990
17113
 
package/dist/index.js CHANGED
@@ -2853,6 +2853,11 @@ function parseRollout(file, lines) {
2853
2853
  let lastUserPreview;
2854
2854
  let lastAgentPreview;
2855
2855
  const tsMs = [];
2856
+ let threadSource;
2857
+ let rootSessionId;
2858
+ let parentThreadId;
2859
+ let agentNickname;
2860
+ let agentPath;
2856
2861
  let idx = 0;
2857
2862
  for (const line of lines) {
2858
2863
  if (typeof line !== "object" || line === null)
@@ -2873,6 +2878,16 @@ function parseRollout(file, lines) {
2873
2878
  if (type === "session_meta") {
2874
2879
  if (typeof payload.cwd === "string")
2875
2880
  cwd = payload.cwd;
2881
+ if (threadSource === void 0 && typeof payload.thread_source === "string")
2882
+ threadSource = payload.thread_source;
2883
+ if (rootSessionId === void 0 && typeof payload.session_id === "string")
2884
+ rootSessionId = payload.session_id;
2885
+ if (parentThreadId === void 0 && typeof payload.parent_thread_id === "string")
2886
+ parentThreadId = payload.parent_thread_id;
2887
+ if (agentNickname === void 0 && typeof payload.agent_nickname === "string")
2888
+ agentNickname = payload.agent_nickname;
2889
+ if (agentPath === void 0 && typeof payload.agent_path === "string")
2890
+ agentPath = payload.agent_path;
2876
2891
  continue;
2877
2892
  }
2878
2893
  if (type === "turn_context") {
@@ -3076,7 +3091,7 @@ function parseRollout(file, lines) {
3076
3091
  airTimeMs,
3077
3092
  activeSegments
3078
3093
  };
3079
- return { meta, events };
3094
+ return { meta, events, threadSource, rootSessionId, parentThreadId, agentNickname, agentPath };
3080
3095
  }
3081
3096
  function numberOf(v) {
3082
3097
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
@@ -3114,28 +3129,112 @@ function clearCodexCaches() {
3114
3129
  metaCache2.clear();
3115
3130
  detailCache2.clear();
3116
3131
  }
3117
- async function listCodexSessions(opts = {}) {
3118
- const root = opts.root ?? DEFAULT_CODEX_ROOT;
3132
+ async function scanAllCodex(root) {
3119
3133
  const files = await listRolloutFiles(root);
3120
3134
  const out = [];
3121
3135
  for (const file of files) {
3122
3136
  const cached = metaCache2.get(file.filePath);
3123
3137
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3124
- out.push(cached.meta);
3138
+ out.push({
3139
+ file,
3140
+ meta: cached.meta,
3141
+ threadSource: cached.threadSource,
3142
+ rootSessionId: cached.rootSessionId,
3143
+ parentThreadId: cached.parentThreadId,
3144
+ agentNickname: cached.agentNickname,
3145
+ agentPath: cached.agentPath
3146
+ });
3125
3147
  continue;
3126
3148
  }
3127
3149
  try {
3128
3150
  const lines = await readJsonl(file.filePath);
3129
- const { meta } = parseRollout(file, lines);
3151
+ const parsed = parseRollout(file, lines);
3130
3152
  metaCache2.set(file.filePath, {
3131
- meta,
3153
+ meta: parsed.meta,
3132
3154
  mtimeMs: file.mtimeMs,
3133
- sizeBytes: file.sizeBytes
3155
+ sizeBytes: file.sizeBytes,
3156
+ threadSource: parsed.threadSource,
3157
+ rootSessionId: parsed.rootSessionId,
3158
+ parentThreadId: parsed.parentThreadId,
3159
+ agentNickname: parsed.agentNickname,
3160
+ agentPath: parsed.agentPath
3161
+ });
3162
+ out.push({
3163
+ file,
3164
+ meta: parsed.meta,
3165
+ threadSource: parsed.threadSource,
3166
+ rootSessionId: parsed.rootSessionId,
3167
+ parentThreadId: parsed.parentThreadId,
3168
+ agentNickname: parsed.agentNickname,
3169
+ agentPath: parsed.agentPath
3134
3170
  });
3135
- out.push(meta);
3136
3171
  } catch {
3137
3172
  }
3138
3173
  }
3174
+ return out;
3175
+ }
3176
+ function buildSubagentRun(entry, parentStartMs) {
3177
+ const meta = entry.meta;
3178
+ const startMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3179
+ const endMs = meta.lastTimestamp ? Date.parse(meta.lastTimestamp) : void 0;
3180
+ const startOk = startMs !== void 0 && Number.isFinite(startMs) ? startMs : void 0;
3181
+ const endOk = endMs !== void 0 && Number.isFinite(endMs) ? endMs : void 0;
3182
+ return {
3183
+ agentId: meta.id,
3184
+ agentType: entry.agentNickname ?? entry.agentPath ?? "subagent",
3185
+ description: entry.agentPath ?? entry.agentNickname ?? meta.id,
3186
+ startMs: startOk,
3187
+ endMs: endOk,
3188
+ durationMs: meta.durationMs,
3189
+ startTOffsetMs: parentStartMs !== void 0 && startOk !== void 0 ? Math.max(0, startOk - parentStartMs) : void 0,
3190
+ endTOffsetMs: parentStartMs !== void 0 && endOk !== void 0 ? Math.max(0, endOk - parentStartMs) : void 0,
3191
+ eventCount: meta.eventCount,
3192
+ totalUsage: meta.totalUsage,
3193
+ model: meta.model,
3194
+ toolCallCount: meta.toolCallCount,
3195
+ finalPreview: meta.lastAgentPreview
3196
+ };
3197
+ }
3198
+ async function listCodexSessions(opts = {}) {
3199
+ const root = opts.root ?? DEFAULT_CODEX_ROOT;
3200
+ const all = await scanAllCodex(root);
3201
+ const subagentsByRoot = /* @__PURE__ */ new Map();
3202
+ for (const entry of all) {
3203
+ if (entry.threadSource !== "subagent" || !entry.rootSessionId)
3204
+ continue;
3205
+ const list = subagentsByRoot.get(entry.rootSessionId);
3206
+ if (list)
3207
+ list.push(entry);
3208
+ else
3209
+ subagentsByRoot.set(entry.rootSessionId, [entry]);
3210
+ }
3211
+ const out = [];
3212
+ for (const entry of all) {
3213
+ if (entry.threadSource === "subagent")
3214
+ continue;
3215
+ const children = subagentsByRoot.get(entry.meta.id);
3216
+ if (!children || children.length === 0) {
3217
+ out.push(entry.meta);
3218
+ continue;
3219
+ }
3220
+ const merged = {
3221
+ ...entry.meta,
3222
+ spawnedAgentCount: children.length,
3223
+ totalUsage: {
3224
+ input: entry.meta.totalUsage.input + children.reduce((s, c) => s + c.meta.totalUsage.input, 0),
3225
+ output: entry.meta.totalUsage.output + children.reduce((s, c) => s + c.meta.totalUsage.output, 0),
3226
+ cacheRead: entry.meta.totalUsage.cacheRead + children.reduce((s, c) => s + c.meta.totalUsage.cacheRead, 0),
3227
+ cacheWrite: entry.meta.totalUsage.cacheWrite + children.reduce((s, c) => s + c.meta.totalUsage.cacheWrite, 0)
3228
+ },
3229
+ toolCallCount: (entry.meta.toolCallCount ?? 0) + children.reduce((s, c) => s + (c.meta.toolCallCount ?? 0), 0)
3230
+ };
3231
+ for (const c of children) {
3232
+ if (c.meta.lastTimestamp && (!merged.lastTimestamp || c.meta.lastTimestamp > merged.lastTimestamp)) {
3233
+ merged.lastTimestamp = c.meta.lastTimestamp;
3234
+ }
3235
+ }
3236
+ out.push(merged);
3237
+ }
3139
3238
  out.sort((a, b) => (b.firstTimestamp ?? "").localeCompare(a.firstTimestamp ?? ""));
3140
3239
  if (opts.limit !== void 0)
3141
3240
  return out.slice(0, opts.limit);
@@ -3143,17 +3242,41 @@ async function listCodexSessions(opts = {}) {
3143
3242
  }
3144
3243
  async function getCodexSession(id, opts = {}) {
3145
3244
  const root = opts.root ?? DEFAULT_CODEX_ROOT;
3146
- const files = await listRolloutFiles(root);
3147
- const file = files.find((f) => f.sessionId === id);
3148
- if (!file)
3149
- return null;
3245
+ const all = await scanAllCodex(root);
3246
+ const rootEntry = all.find((a) => a.meta.id === id && a.threadSource !== "subagent");
3247
+ if (!rootEntry) {
3248
+ const direct = all.find((a) => a.meta.id === id);
3249
+ if (!direct)
3250
+ return null;
3251
+ const cached2 = detailCache2.get(direct.file.filePath);
3252
+ if (cached2 && cached2.mtimeMs === direct.file.mtimeMs && cached2.sizeBytes === direct.file.sizeBytes) {
3253
+ return cached2.detail;
3254
+ }
3255
+ const lines2 = await readJsonl(direct.file.filePath);
3256
+ const { meta: meta2, events: events2 } = parseRollout(direct.file, lines2);
3257
+ const detail2 = { ...meta2, events: events2 };
3258
+ detailCache2.set(direct.file.filePath, {
3259
+ detail: detail2,
3260
+ mtimeMs: direct.file.mtimeMs,
3261
+ sizeBytes: direct.file.sizeBytes
3262
+ });
3263
+ return detail2;
3264
+ }
3265
+ const file = rootEntry.file;
3150
3266
  const cached = detailCache2.get(file.filePath);
3151
3267
  if (cached && cached.mtimeMs === file.mtimeMs && cached.sizeBytes === file.sizeBytes) {
3152
3268
  return cached.detail;
3153
3269
  }
3154
3270
  const lines = await readJsonl(file.filePath);
3155
3271
  const { meta, events } = parseRollout(file, lines);
3156
- const detail = { ...meta, events };
3272
+ const children = all.filter((a) => a.threadSource === "subagent" && a.rootSessionId === id);
3273
+ const parentStartMs = meta.firstTimestamp ? Date.parse(meta.firstTimestamp) : void 0;
3274
+ const subagents = children.map((c) => buildSubagentRun(c, parentStartMs)).sort((a, b) => (a.startMs ?? 0) - (b.startMs ?? 0));
3275
+ const detail = {
3276
+ ...meta,
3277
+ events,
3278
+ ...subagents.length > 0 ? { subagents, spawnedAgentCount: subagents.length } : {}
3279
+ };
3157
3280
  detailCache2.set(file.filePath, {
3158
3281
  detail,
3159
3282
  mtimeMs: file.mtimeMs,
@@ -5663,9 +5786,9 @@ function onDiskVersion() {
5663
5786
  try {
5664
5787
  const here = dirname3(fileURLToPath(import.meta.url));
5665
5788
  const pkg = JSON.parse(readFileSync5(join3(here, "..", "package.json"), "utf8"));
5666
- return pkg.version ?? "0.16.1";
5789
+ return pkg.version ?? "0.16.2";
5667
5790
  } catch {
5668
- return "0.16.1";
5791
+ return "0.16.2";
5669
5792
  }
5670
5793
  }
5671
5794
  function getServerStatus() {
@@ -5677,7 +5800,7 @@ function getServerStatus() {
5677
5800
  return { running: false };
5678
5801
  }
5679
5802
  function isServerStale(status2) {
5680
- return status2.running === true && status2.version !== "0.16.1";
5803
+ return status2.running === true && status2.version !== "0.16.2";
5681
5804
  }
5682
5805
  async function ensureCurrentServer(opts = {}) {
5683
5806
  const status2 = getServerStatus();
@@ -6116,9 +6239,9 @@ Installed: ${PACKAGE_NAME}@${verify.installedVersion} at ${verify.installedPath
6116
6239
  console.warn(
6117
6240
  ` \u2022 reinstall in the correct Node env: 'npm install -g ${PACKAGE_NAME}@latest'`
6118
6241
  );
6119
- } else if (verify.installedVersion !== "0.16.1") {
6242
+ } else if (verify.installedVersion !== "0.16.2") {
6120
6243
  console.log(
6121
- ` \u2192 This process is still running ${"0.16.1"}. Next invocation will use ${verify.installedVersion}.`
6244
+ ` \u2192 This process is still running ${"0.16.2"}. Next invocation will use ${verify.installedVersion}.`
6122
6245
  );
6123
6246
  }
6124
6247
  }
@@ -6153,14 +6276,14 @@ async function getUpdateAvailability() {
6153
6276
  if (isDevMode()) return null;
6154
6277
  const latest = await fetchLatestVersion();
6155
6278
  if (latest === null) return {
6156
- current: "0.16.1",
6279
+ current: "0.16.2",
6157
6280
  latest: null,
6158
6281
  updateAvailable: false
6159
6282
  };
6160
6283
  return {
6161
- current: "0.16.1",
6284
+ current: "0.16.2",
6162
6285
  latest,
6163
- updateAvailable: shouldUpdate("0.16.1", latest)
6286
+ updateAvailable: shouldUpdate("0.16.2", latest)
6164
6287
  };
6165
6288
  }
6166
6289
  async function checkForUpdate() {
@@ -6250,7 +6373,7 @@ async function restartServices(state) {
6250
6373
  }
6251
6374
  async function forceUpdate() {
6252
6375
  const latest = await fetchLatestVersion();
6253
- const current = "0.16.1";
6376
+ const current = "0.16.2";
6254
6377
  if (latest === null) {
6255
6378
  console.error("Could not reach npm registry. Check your network.");
6256
6379
  process.exit(1);
@@ -6663,7 +6786,7 @@ async function status() {
6663
6786
  console.log(`Server: running on ${url} (PID ${server.pid}, v${ver})`);
6664
6787
  if (isServerStale(server)) {
6665
6788
  console.log(
6666
- ` \u26A0 serving stale ${ver} (CLI is ${"0.16.1"}) \u2014 run 'fleetlens start' to restart on the current version`
6789
+ ` \u26A0 serving stale ${ver} (CLI is ${"0.16.2"}) \u2014 run 'fleetlens start' to restart on the current version`
6667
6790
  );
6668
6791
  }
6669
6792
  } else {
@@ -18806,7 +18929,7 @@ function buildIngestPayload(inputs) {
18806
18929
  return {
18807
18930
  ingestId: randomUUID2(),
18808
18931
  observedAt: (/* @__PURE__ */ new Date()).toISOString(),
18809
- cliVersion: "0.16.1",
18932
+ cliVersion: "0.16.2",
18810
18933
  ...richRollup || inputs.enrichedExtras || inputs.artifactSignals ? { schemaVersion: RICH_ROLLUP_SCHEMA_VERSION } : {},
18811
18934
  ...inputs.rollup ? { dailyRollup: inputs.rollup } : {},
18812
18935
  ...richRollup ? { richRollup } : {},
@@ -20849,7 +20972,7 @@ async function main() {
20849
20972
  case "version":
20850
20973
  case "--version":
20851
20974
  case "-v":
20852
- console.log(`fleetlens ${"0.16.1"}`);
20975
+ console.log(`fleetlens ${"0.16.2"}`);
20853
20976
  break;
20854
20977
  case "help":
20855
20978
  case "--help":
@@ -10,8 +10,8 @@
10
10
  <key>CFBundleName</key><string>Fleetlens</string>
11
11
  <key>CFBundleDisplayName</key><string>Fleetlens Menu Bar</string>
12
12
  <key>CFBundlePackageType</key><string>APPL</string>
13
- <key>CFBundleShortVersionString</key><string>0.16.1</string>
14
- <key>CFBundleVersion</key><string>0.16.1</string>
13
+ <key>CFBundleShortVersionString</key><string>0.16.2</string>
14
+ <key>CFBundleVersion</key><string>0.16.2</string>
15
15
  <key>LSApplicationCategoryType</key><string>public.app-category.developer-tools</string>
16
16
  <key>LSMinimumSystemVersion</key><string>14.0</string>
17
17
  <key>LSUIElement</key><true/>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetlens",
3
- "version": "0.16.1",
3
+ "version": "0.16.2",
4
4
  "description": "fleetlens — local-only dashboard and usage tracker for Claude Code sessions and agent fleets",
5
5
  "license": "MIT",
6
6
  "repository": {