fleetlens 0.2.9 → 0.4.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 (237) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/app-path-routes-manifest.json +9 -0
  3. package/app/apps/web/.next/build-manifest.json +6 -6
  4. package/app/apps/web/.next/prerender-manifest.json +3 -3
  5. package/app/apps/web/.next/routes-manifest.json +62 -0
  6. package/app/apps/web/.next/server/app/_global-error/page/build-manifest.json +3 -3
  7. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  8. package/app/apps/web/.next/server/app/_global-error.rsc +1 -1
  9. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  12. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  13. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/app/apps/web/.next/server/app/_not-found/page/build-manifest.json +3 -3
  15. package/app/apps/web/.next/server/app/_not-found/page.js +1 -1
  16. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/app/apps/web/.next/server/app/api/ask/route.js +3 -2
  19. package/app/apps/web/.next/server/app/api/ask/route.js.nft.json +1 -1
  20. package/app/apps/web/.next/server/app/api/events/route.js +1 -0
  21. package/app/apps/web/.next/server/app/api/events/route.js.nft.json +1 -1
  22. package/app/apps/web/.next/server/app/api/insights/months-index/route/app-paths-manifest.json +3 -0
  23. package/app/apps/web/.next/server/app/api/insights/months-index/route/build-manifest.json +9 -0
  24. package/app/apps/web/.next/server/app/api/insights/months-index/route/server-reference-manifest.json +4 -0
  25. package/app/apps/web/.next/server/app/api/insights/months-index/route.js +7 -0
  26. package/app/apps/web/.next/server/app/api/insights/months-index/route.js.map +5 -0
  27. package/app/apps/web/.next/server/app/api/insights/months-index/route.js.nft.json +1 -0
  28. package/app/apps/web/.next/server/app/api/insights/months-index/route_client-reference-manifest.js +3 -0
  29. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/app-paths-manifest.json +3 -0
  30. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/build-manifest.json +9 -0
  31. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/server-reference-manifest.json +4 -0
  32. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js +6 -0
  33. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js.map +5 -0
  34. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js.nft.json +1 -0
  35. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route_client-reference-manifest.js +3 -0
  36. package/app/apps/web/.next/server/app/api/insights/route/app-paths-manifest.json +3 -0
  37. package/app/apps/web/.next/server/app/api/insights/route/build-manifest.json +9 -0
  38. package/app/apps/web/.next/server/app/api/insights/route/server-reference-manifest.json +4 -0
  39. package/app/apps/web/.next/server/app/api/insights/route.js +8 -0
  40. package/app/apps/web/.next/server/app/api/insights/route.js.map +5 -0
  41. package/app/apps/web/.next/server/app/api/insights/route.js.nft.json +1 -0
  42. package/app/apps/web/.next/server/app/api/insights/route_client-reference-manifest.js +3 -0
  43. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/app-paths-manifest.json +3 -0
  44. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/build-manifest.json +9 -0
  45. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/server-reference-manifest.json +4 -0
  46. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js +6 -0
  47. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js.map +5 -0
  48. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js.nft.json +1 -0
  49. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route_client-reference-manifest.js +3 -0
  50. package/app/apps/web/.next/server/app/api/insights/saved/route/app-paths-manifest.json +3 -0
  51. package/app/apps/web/.next/server/app/api/insights/saved/route/build-manifest.json +9 -0
  52. package/app/apps/web/.next/server/app/api/insights/saved/route/server-reference-manifest.json +4 -0
  53. package/app/apps/web/.next/server/app/api/insights/saved/route.js +6 -0
  54. package/app/apps/web/.next/server/app/api/insights/saved/route.js.map +5 -0
  55. package/app/apps/web/.next/server/app/api/insights/saved/route.js.nft.json +1 -0
  56. package/app/apps/web/.next/server/app/api/insights/saved/route_client-reference-manifest.js +3 -0
  57. package/app/apps/web/.next/server/app/api/insights/weeks-index/route/app-paths-manifest.json +3 -0
  58. package/app/apps/web/.next/server/app/api/insights/weeks-index/route/build-manifest.json +9 -0
  59. package/app/apps/web/.next/server/app/api/insights/weeks-index/route/server-reference-manifest.json +4 -0
  60. package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js +7 -0
  61. package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js.map +5 -0
  62. package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js.nft.json +1 -0
  63. package/app/apps/web/.next/server/app/api/insights/weeks-index/route_client-reference-manifest.js +3 -0
  64. package/app/apps/web/.next/server/app/insights/[key]/page/app-paths-manifest.json +3 -0
  65. package/app/apps/web/.next/server/app/insights/[key]/page/build-manifest.json +17 -0
  66. package/app/apps/web/.next/server/app/insights/[key]/page/next-font-manifest.json +6 -0
  67. package/app/apps/web/.next/server/app/insights/[key]/page/react-loadable-manifest.json +1 -0
  68. package/app/apps/web/.next/server/app/insights/[key]/page/server-reference-manifest.json +4 -0
  69. package/app/apps/web/.next/server/app/insights/[key]/page.js +16 -0
  70. package/app/apps/web/.next/server/app/insights/[key]/page.js.map +5 -0
  71. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -0
  72. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +3 -0
  73. package/app/apps/web/.next/server/app/insights/page/app-paths-manifest.json +3 -0
  74. package/app/apps/web/.next/server/app/insights/page/build-manifest.json +17 -0
  75. package/app/apps/web/.next/server/app/insights/page/next-font-manifest.json +6 -0
  76. package/app/apps/web/.next/server/app/insights/page/react-loadable-manifest.json +1 -0
  77. package/app/apps/web/.next/server/app/insights/page/server-reference-manifest.json +4 -0
  78. package/app/apps/web/.next/server/app/insights/page.js +16 -0
  79. package/app/apps/web/.next/server/app/insights/page.js.map +5 -0
  80. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -0
  81. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +3 -0
  82. package/app/apps/web/.next/server/app/insights/print/[key]/page/app-paths-manifest.json +3 -0
  83. package/app/apps/web/.next/server/app/insights/print/[key]/page/build-manifest.json +17 -0
  84. package/app/apps/web/.next/server/app/insights/print/[key]/page/next-font-manifest.json +6 -0
  85. package/app/apps/web/.next/server/app/insights/print/[key]/page/react-loadable-manifest.json +1 -0
  86. package/app/apps/web/.next/server/app/insights/print/[key]/page/server-reference-manifest.json +4 -0
  87. package/app/apps/web/.next/server/app/insights/print/[key]/page.js +16 -0
  88. package/app/apps/web/.next/server/app/insights/print/[key]/page.js.map +5 -0
  89. package/app/apps/web/.next/server/app/insights/print/[key]/page.js.nft.json +1 -0
  90. package/app/apps/web/.next/server/app/insights/print/[key]/page_client-reference-manifest.js +3 -0
  91. package/app/apps/web/.next/server/app/page/build-manifest.json +3 -3
  92. package/app/apps/web/.next/server/app/page.js +3 -3
  93. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  94. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  95. package/app/apps/web/.next/server/app/parallelism/page/build-manifest.json +3 -3
  96. package/app/apps/web/.next/server/app/parallelism/page.js +1 -1
  97. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  98. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  99. package/app/apps/web/.next/server/app/projects/[slug]/page/build-manifest.json +3 -3
  100. package/app/apps/web/.next/server/app/projects/[slug]/page.js +2 -3
  101. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  102. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  103. package/app/apps/web/.next/server/app/projects/page/build-manifest.json +3 -3
  104. package/app/apps/web/.next/server/app/projects/page.js +1 -1
  105. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  106. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  107. package/app/apps/web/.next/server/app/sessions/[id]/page/build-manifest.json +3 -3
  108. package/app/apps/web/.next/server/app/sessions/[id]/page.js +2 -2
  109. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  110. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  111. package/app/apps/web/.next/server/app/sessions/page/build-manifest.json +3 -3
  112. package/app/apps/web/.next/server/app/sessions/page.js +1 -1
  113. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  114. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  115. package/app/apps/web/.next/server/app/usage/page/build-manifest.json +3 -3
  116. package/app/apps/web/.next/server/app/usage/page.js +1 -1
  117. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  118. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  119. package/app/apps/web/.next/server/app-paths-manifest.json +9 -0
  120. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_months-index_route_actions_0~h~zci.js +3 -0
  121. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_saved_[key]_route_actions_0a5j9yw.js +3 -0
  122. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_weeks-index_route_actions_0hh-1c7.js +3 -0
  123. package/app/apps/web/.next/server/chunks/{[externals]__0rv9ct5._.js → [externals]__0_xztrf._.js} +2 -2
  124. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.hmj0z._.js +3 -0
  125. package/app/apps/web/.next/server/chunks/[root-of-the-server]__01h_g-p._.js +3 -0
  126. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh-z10._.js +3 -0
  127. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0op9af~._.js +1 -1
  128. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ri7q~r._.js +3 -0
  129. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0rr1~~x._.js +3 -0
  130. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s0gv.0._.js +3 -0
  131. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_pdf_[key]_route_actions_0lu-lnx.js +3 -0
  132. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_route_actions_0h8l5lz.js +3 -0
  133. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_saved_route_actions_13rlblw.js +3 -0
  134. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_00t2xj6.js +68 -0
  135. package/app/apps/web/.next/server/chunks/{[root-of-the-server]__0sgyieh._.js → node_modules_next_dist_esm_build_templates_app-route_0ck.78s.js} +5 -5
  136. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_0bc7ptm.js +3 -0
  137. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__00z7zlm._.js +3 -0
  138. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__08.d5ia._.js +12 -0
  139. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0b323~k._.js +8 -0
  140. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0euu8sa._.js +3 -0
  141. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gio_ck._.js +3 -0
  142. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gx-4qa._.js +3 -0
  143. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
  144. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0z45d0g._.js +49 -0
  145. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__13itnvx._.js +3 -0
  146. package/app/apps/web/.next/server/chunks/ssr/_09n75_5._.js +1 -1
  147. package/app/apps/web/.next/server/chunks/ssr/_0r~__0v._.js +12 -0
  148. package/app/apps/web/.next/server/chunks/ssr/_0xies90._.js +1 -1
  149. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_[key]_page_actions_0_z2~e_.js +3 -0
  150. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_page_actions_0zjdm~n.js +3 -0
  151. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_print_[key]_page_actions_0a853fw.js +3 -0
  152. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_06j3c.0._.js +1 -1
  153. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insight-report_tsx_13q2a-c._.js +12 -0
  154. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insights-view_tsx_11730ta._.js +6 -0
  155. package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0-lmm4p._.js +3 -0
  156. package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0nqz8dw._.js +3 -0
  157. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_0t-hj0x._.js +3 -0
  158. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0vz7_px.js +4 -0
  159. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_10cdrh2.js +4 -0
  160. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12n1lw_.js +4 -0
  161. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0-jvt~a._.js +1 -1
  162. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_analytics_0k4dgst.js +1 -1
  163. package/app/apps/web/.next/server/functions-config-manifest.json +7 -1
  164. package/app/apps/web/.next/server/middleware-build-manifest.js +6 -6
  165. package/app/apps/web/.next/server/pages/500.html +1 -1
  166. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  167. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  168. package/app/apps/web/.next/static/chunks/03.mv4y4.w-vb.js +6 -0
  169. package/app/apps/web/.next/static/chunks/03_7xtpi9sv4g.js +4 -0
  170. package/app/apps/web/.next/static/chunks/03g5dw5eskotd.js +6 -0
  171. package/app/apps/web/.next/static/chunks/063oimt30jeo9.js +10 -0
  172. package/app/apps/web/.next/static/chunks/08c1pcrocqq5s.js +6 -0
  173. package/app/apps/web/.next/static/chunks/0e-wrhqh4h3r5.js +2 -0
  174. package/app/apps/web/.next/static/chunks/0fc6dk2qtokwh.js +1 -0
  175. package/app/apps/web/.next/static/chunks/0i7er7_bfab36.js +10 -0
  176. package/app/apps/web/.next/static/chunks/0ipytyi01h0ta.js +1 -0
  177. package/app/apps/web/.next/static/chunks/137uw2-qbro07.js +31 -0
  178. package/app/apps/web/.next/static/chunks/{turbopack-17n9y8y0h4q9f.js → turbopack-169w-1._23ra_.js} +1 -1
  179. package/app/apps/web/app/api/insights/months-index/route.ts +80 -0
  180. package/app/apps/web/app/api/insights/pdf/[key]/route.ts +45 -0
  181. package/app/apps/web/app/api/insights/route.ts +508 -0
  182. package/app/apps/web/app/api/insights/saved/[key]/route.ts +11 -0
  183. package/app/apps/web/app/api/insights/saved/route.ts +9 -0
  184. package/app/apps/web/app/api/insights/weeks-index/route.ts +95 -0
  185. package/app/apps/web/app/insights/[key]/page.tsx +59 -0
  186. package/app/apps/web/app/insights/page.tsx +7 -0
  187. package/app/apps/web/app/insights/print/[key]/page.tsx +73 -0
  188. package/app/apps/web/app/layout.tsx +2 -0
  189. package/app/apps/web/app/projects/[slug]/page.tsx +2 -0
  190. package/app/apps/web/app/sessions/[id]/page.tsx +27 -1
  191. package/app/apps/web/app/sessions/[id]/session-view.tsx +372 -793
  192. package/app/apps/web/app/sessions/[id]/team-tab/adapter.ts +633 -0
  193. package/app/apps/web/app/sessions/[id]/team-tab/format.ts +20 -0
  194. package/app/apps/web/app/sessions/[id]/team-tab/team-minimap.tsx +682 -0
  195. package/app/apps/web/app/sessions/[id]/team-tab/team-tab-client.tsx +78 -0
  196. package/app/apps/web/app/sessions/[id]/team-tab/team-table.tsx +796 -0
  197. package/app/apps/web/app/sessions/[id]/team-tab/turn-drawer.tsx +805 -0
  198. package/app/apps/web/app/sessions/[id]/tool-cards.tsx +461 -0
  199. package/app/apps/web/app/sessions/[id]/turn-steps.tsx +306 -0
  200. package/app/apps/web/app/sessions/sessions-grid.tsx +36 -5
  201. package/app/apps/web/components/insight-report.tsx +1031 -0
  202. package/app/apps/web/components/insights-view.tsx +647 -0
  203. package/app/apps/web/components/live-refresher.tsx +11 -2
  204. package/app/apps/web/components/live-sessions-widget.tsx +20 -6
  205. package/app/apps/web/components/sidebar.tsx +8 -0
  206. package/app/apps/web/components/team-badge.tsx +90 -0
  207. package/app/apps/web/eslint.config.mjs +2 -0
  208. package/app/apps/web/lib/ai/chrome-pdf.ts +64 -0
  209. package/app/apps/web/lib/ai/insights-prompt.ts +71 -0
  210. package/app/apps/web/lib/ai/saved-reports.ts +83 -0
  211. package/app/apps/web/lib/date-range.ts +11 -2
  212. package/app/apps/web/lib/use-live-events.ts +7 -2
  213. package/app/apps/web/package.json +3 -2
  214. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  215. package/dist/daemon-worker.js +2765 -11
  216. package/dist/index.js +3047 -253
  217. package/package.json +5 -3
  218. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__08cr2u9._.js +0 -3
  219. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0b..h_8._.js +0 -3
  220. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0cdd~8n._.js +0 -3
  221. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ms7h0~._.js +0 -8
  222. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0~a~v00._.js +0 -3
  223. package/app/apps/web/.next/server/chunks/ssr/_0zv~jv-._.js +0 -12
  224. package/app/apps/web/.next/server/chunks/ssr/_12dtryh._.js +0 -12
  225. package/app/apps/web/.next/server/chunks/ssr/node_modules_0i2xw~e._.js +0 -3
  226. package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0.knjn.._.js +0 -3
  227. package/app/apps/web/.next/static/chunks/0257pdz1-imal.js +0 -2
  228. package/app/apps/web/.next/static/chunks/03fw7f2obcvq~.js +0 -6
  229. package/app/apps/web/.next/static/chunks/07oyxajlp3dvb.js +0 -6
  230. package/app/apps/web/.next/static/chunks/0a24elrqoqqep.js +0 -10
  231. package/app/apps/web/.next/static/chunks/0i4zodv86~~~i.js +0 -1
  232. package/app/apps/web/.next/static/chunks/0qmh881w772ef.js +0 -31
  233. package/app/apps/web/.next/static/chunks/0rbm60-qyshdm.js +0 -6
  234. package/app/apps/web/.next/static/chunks/0wdga7zbwvg70.js +0 -1
  235. /package/app/apps/web/.next/static/{2rEsiJssG30QsuNT0Lp9S → G_4ofKI9v9ARC_lb9JILZ}/_buildManifest.js +0 -0
  236. /package/app/apps/web/.next/static/{2rEsiJssG30QsuNT0Lp9S → G_4ofKI9v9ARC_lb9JILZ}/_clientMiddlewareManifest.js +0 -0
  237. /package/app/apps/web/.next/static/{2rEsiJssG30QsuNT0Lp9S → G_4ofKI9v9ARC_lb9JILZ}/_ssgManifest.js +0 -0
@@ -0,0 +1,306 @@
1
+ import type {
2
+ PresentationRow,
3
+ PresentationRowKind,
4
+ SessionEvent,
5
+ } from "@claude-lens/parser";
6
+
7
+ export type RoleTheme = {
8
+ label: string;
9
+ bg: string;
10
+ fg: string;
11
+ mini: string;
12
+ };
13
+
14
+ /**
15
+ * Palette modeled on Claude Managed Agents' Sessions view — muted,
16
+ * desaturated tones that read cleanly against the cream background.
17
+ * `bg`/`fg` drive the in-row pill; `mini` drives the timeline block fill.
18
+ */
19
+ export const ROLE_THEMES: Record<PresentationRowKind, RoleTheme> = {
20
+ user: {
21
+ label: "User",
22
+ bg: "rgba(201, 112, 112, 0.18)",
23
+ fg: "#8B3A3A",
24
+ mini: "#C97070",
25
+ },
26
+ agent: {
27
+ label: "Agent",
28
+ bg: "rgba(92, 132, 195, 0.18)",
29
+ fg: "#2E4A7A",
30
+ mini: "#5C84C3",
31
+ },
32
+ "tool-group": {
33
+ label: "Tool",
34
+ bg: "rgba(138, 133, 128, 0.16)",
35
+ fg: "#44403C",
36
+ mini: "#8A8580",
37
+ },
38
+ interrupt: {
39
+ label: "Interrupt",
40
+ bg: "rgba(217, 119, 6, 0.14)",
41
+ fg: "#78350F",
42
+ mini: "#D97706",
43
+ },
44
+ model: {
45
+ label: "Model",
46
+ bg: "rgba(168, 85, 247, 0.12)",
47
+ fg: "#581C87",
48
+ mini: "#A855F7",
49
+ },
50
+ error: {
51
+ label: "Error",
52
+ bg: "rgba(197, 48, 48, 0.18)",
53
+ fg: "#8B1818",
54
+ mini: "#C53030",
55
+ },
56
+ "task-notification": {
57
+ label: "Task",
58
+ bg: "rgba(100, 116, 139, 0.12)",
59
+ fg: "#475569",
60
+ mini: "#64748B",
61
+ },
62
+ };
63
+
64
+ /** Max number of steps shown inline in a collapsed turn. Larger turns are
65
+ * truncated with a "+N more" line; the user can click to expand the turn
66
+ * to see everything. */
67
+ export const MAX_INLINE_STEPS = 12;
68
+
69
+ export function rowPreview(r: PresentationRow): string {
70
+ switch (r.kind) {
71
+ case "user":
72
+ return r.displayPreview ?? r.event.preview;
73
+ case "agent":
74
+ return r.event.preview;
75
+ case "tool-group":
76
+ return formatToolSummary(r.toolNames);
77
+ case "interrupt":
78
+ return "Interrupted";
79
+ case "model":
80
+ return tokenSummaryLine(r.event.usage);
81
+ case "error":
82
+ return r.message;
83
+ case "task-notification": {
84
+ const icon =
85
+ r.status === "success"
86
+ ? "✓"
87
+ : r.status === "failed"
88
+ ? "✗"
89
+ : r.status === "running"
90
+ ? "…"
91
+ : "•";
92
+ return `${icon} ${r.summary}`;
93
+ }
94
+ }
95
+ }
96
+
97
+ /** Render a compact "Bash ×3 · Read ×2 · Grep · Edit" style summary.
98
+ * Truncates after 4 unique tools with "+N more". */
99
+ export function formatToolSummary(
100
+ toolNames: { name: string; count: number }[],
101
+ ): string {
102
+ const MAX = 4;
103
+ const shown = toolNames.slice(0, MAX);
104
+ const overflow = toolNames.length - MAX;
105
+ const parts = shown.map((t) => {
106
+ const display = shortenToolName(t.name);
107
+ return t.count > 1 ? `${display} ×${t.count}` : display;
108
+ });
109
+ if (overflow > 0) parts.push(`+${overflow} more`);
110
+ return parts.join(" · ");
111
+ }
112
+
113
+ export function tokenSummaryLine(u: SessionEvent["usage"]): string {
114
+ if (!u) return "0 input · 0 output · 0 cache read · 0 cache write";
115
+ return `${u.input} input · ${u.output} output · ${u.cacheRead} cache read · ${u.cacheWrite} cache write`;
116
+ }
117
+
118
+ export function shortenToolName(name: string): string {
119
+ // mcp__plugin_linear_linear__get_issue → linear.get_issue
120
+ const m = name.match(/^mcp__(?:plugin_)?([^_]+)_(?:\1_)?(.+)$/);
121
+ if (m) return `${m[1]}.${m[2]}`;
122
+ // mcp__claude_ai_Gmail__search_threads → gmail.search_threads
123
+ const m2 = name.match(/^mcp__claude_ai_([^_]+)__(.+)$/);
124
+ if (m2) return `${m2[1].toLowerCase()}.${m2[2]}`;
125
+ return name;
126
+ }
127
+
128
+ /** Bulleted list of everything that happened in the middle of a turn.
129
+ * Each row is a one-line compact entry with role + preview. Capped at
130
+ * MAX_INLINE_STEPS items with an overflow indicator. */
131
+ export function TurnStepsList({
132
+ rows,
133
+ onStepClick,
134
+ showAll,
135
+ }: {
136
+ rows: PresentationRow[];
137
+ /** Optional: when set, each step line becomes a button. */
138
+ onStepClick?: (row: PresentationRow, index: number) => void;
139
+ /** Bypass the MAX_INLINE_STEPS cap and show every row. */
140
+ showAll?: boolean;
141
+ }) {
142
+ const cap = showAll ? rows.length : MAX_INLINE_STEPS;
143
+ const overflow = Math.max(0, rows.length - cap);
144
+ const shown = overflow > 0 ? rows.slice(-cap) : rows;
145
+ const baseIndex = overflow > 0 ? rows.length - shown.length : 0;
146
+
147
+ return (
148
+ <div
149
+ style={{
150
+ display: "flex",
151
+ flexDirection: "column",
152
+ gap: 2,
153
+ paddingLeft: 2,
154
+ borderLeft: "1px solid var(--af-border-subtle)",
155
+ paddingBlock: 2,
156
+ }}
157
+ >
158
+ {overflow > 0 && (
159
+ <div
160
+ style={{
161
+ fontSize: 11,
162
+ color: "var(--af-text-tertiary)",
163
+ fontStyle: "italic",
164
+ paddingLeft: 12,
165
+ paddingBottom: 2,
166
+ }}
167
+ >
168
+ {overflow} earlier step{overflow === 1 ? "" : "s"} …
169
+ </div>
170
+ )}
171
+ {shown.map((r, i) => {
172
+ const absoluteIndex = baseIndex + i;
173
+ return (
174
+ <TurnStepLine
175
+ key={i}
176
+ row={r}
177
+ onClick={
178
+ onStepClick ? () => onStepClick(r, absoluteIndex) : undefined
179
+ }
180
+ />
181
+ );
182
+ })}
183
+ </div>
184
+ );
185
+ }
186
+
187
+ /** One step in the middle list. Renders a small role marker + the preview
188
+ * for that row, truncated to one line. */
189
+ function TurnStepLine({
190
+ row,
191
+ onClick,
192
+ }: {
193
+ row: PresentationRow;
194
+ onClick?: () => void;
195
+ }) {
196
+ const theme = ROLE_THEMES[row.kind];
197
+ const isTeammateMsg = row.kind === "user" && !!row.event.teammateMessage;
198
+ const label = isTeammateMsg ? "Team Lead" : theme.label;
199
+ const preview = rowPreview(row);
200
+ const interactive = !!onClick;
201
+ return (
202
+ <div
203
+ role={interactive ? "button" : undefined}
204
+ tabIndex={interactive ? 0 : undefined}
205
+ onClick={onClick}
206
+ onKeyDown={
207
+ interactive
208
+ ? (e) => {
209
+ if (e.key === "Enter" || e.key === " ") {
210
+ e.preventDefault();
211
+ onClick?.();
212
+ }
213
+ }
214
+ : undefined
215
+ }
216
+ style={{
217
+ display: "grid",
218
+ gridTemplateColumns: "46px 1fr",
219
+ columnGap: 8,
220
+ fontSize: 12,
221
+ lineHeight: 1.45,
222
+ color: row.kind === "error" ? "var(--af-danger)" : "var(--af-text-secondary)",
223
+ cursor: interactive ? "pointer" : undefined,
224
+ borderRadius: interactive ? 3 : undefined,
225
+ padding: interactive ? "2px 4px" : undefined,
226
+ transition: interactive ? "background 0.1s ease" : undefined,
227
+ }}
228
+ onMouseEnter={
229
+ interactive
230
+ ? (e) => {
231
+ (e.currentTarget as HTMLDivElement).style.background =
232
+ "var(--af-surface-hover)";
233
+ }
234
+ : undefined
235
+ }
236
+ onMouseLeave={
237
+ interactive
238
+ ? (e) => {
239
+ (e.currentTarget as HTMLDivElement).style.background = "";
240
+ }
241
+ : undefined
242
+ }
243
+ >
244
+ <span
245
+ style={{
246
+ fontSize: 10,
247
+ fontWeight: 600,
248
+ background: theme.bg,
249
+ color: theme.fg,
250
+ padding: "1px 6px",
251
+ borderRadius: 3,
252
+ textAlign: "center",
253
+ justifySelf: "start",
254
+ maxWidth: "100%",
255
+ }}
256
+ >
257
+ {label}
258
+ </span>
259
+ <span
260
+ style={{
261
+ overflow: "hidden",
262
+ textOverflow: "ellipsis",
263
+ whiteSpace: "nowrap",
264
+ minWidth: 0,
265
+ }}
266
+ >
267
+ {row.kind === "tool-group" ? (
268
+ <span>
269
+ {row.toolNames.slice(0, 4).map((t, i) => (
270
+ <span key={t.name}>
271
+ {i > 0 && (
272
+ <span style={{ color: "var(--af-text-tertiary)", margin: "0 5px" }}>·</span>
273
+ )}
274
+ <b style={{ fontWeight: 600 }}>{shortenToolName(t.name)}</b>
275
+ {t.count > 1 && (
276
+ <span
277
+ style={{
278
+ color: "var(--af-text-tertiary)",
279
+ fontFamily: "var(--font-mono)",
280
+ marginLeft: 3,
281
+ }}
282
+ >
283
+ ×{t.count}
284
+ </span>
285
+ )}
286
+ </span>
287
+ ))}
288
+ {row.toolNames.length > 4 && (
289
+ <span
290
+ style={{
291
+ color: "var(--af-text-tertiary)",
292
+ marginLeft: 6,
293
+ fontSize: 10,
294
+ }}
295
+ >
296
+ +{row.toolNames.length - 4}
297
+ </span>
298
+ )}
299
+ </span>
300
+ ) : (
301
+ preview
302
+ )}
303
+ </span>
304
+ </div>
305
+ );
306
+ }
@@ -13,6 +13,7 @@ import {
13
13
  } from "@/lib/format";
14
14
  import { Search, Wrench, MessagesSquare, Clock } from "lucide-react";
15
15
  import { LiveBadge } from "@/components/live-badge";
16
+ import { TeamBadge } from "@/components/team-badge";
16
17
  import { DataTable, type Column } from "@/components/data-table";
17
18
  import { useViewToggle } from "@/components/view-toggle";
18
19
 
@@ -41,10 +42,13 @@ export function SessionsGrid({ sessions }: { sessions: SessionMeta[] }) {
41
42
  s.projectName.toLowerCase().includes(q),
42
43
  );
43
44
  }
44
- // "Longest" uses active time (airTimeMs), not wall-clock duration.
45
- // Otherwise a session that sat idle for 14 days with one message
46
- // would out-rank a session that was actively coding for 4 hours.
47
- if (sortBy === "longest")
45
+ if (sortBy === "newest")
46
+ rows.sort(
47
+ (a, b) =>
48
+ (b.firstTimestamp ? Date.parse(b.firstTimestamp) : 0) -
49
+ (a.firstTimestamp ? Date.parse(a.firstTimestamp) : 0),
50
+ );
51
+ else if (sortBy === "longest")
48
52
  rows.sort(
49
53
  (a, b) =>
50
54
  (b.airTimeMs ?? b.durationMs ?? 0) - (a.airTimeMs ?? a.durationMs ?? 0),
@@ -169,7 +173,19 @@ const sessionTableColumns: Column<SessionMeta>[] = [
169
173
  }}
170
174
  title={s.projectName}
171
175
  >
172
- <div style={{ fontWeight: 500 }}>{prettyProjectName(s.projectName)}</div>
176
+ <div style={{ fontWeight: 500, display: "flex", alignItems: "center", gap: 6 }}>
177
+ <span
178
+ style={{
179
+ overflow: "hidden",
180
+ textOverflow: "ellipsis",
181
+ whiteSpace: "nowrap",
182
+ minWidth: 0,
183
+ }}
184
+ >
185
+ {prettyProjectName(s.projectName)}
186
+ </span>
187
+ <TeamBadge session={s} />
188
+ </div>
173
189
  <div
174
190
  style={{
175
191
  fontSize: 10,
@@ -201,6 +217,20 @@ const sessionTableColumns: Column<SessionMeta>[] = [
201
217
  </div>
202
218
  ),
203
219
  },
220
+ {
221
+ key: "created",
222
+ header: "Created",
223
+ sortValue: (s) => (s.firstTimestamp ? Date.parse(s.firstTimestamp) : 0),
224
+ align: "right",
225
+ render: (s) => (
226
+ <span
227
+ suppressHydrationWarning
228
+ style={{ fontFamily: "var(--font-mono)", fontSize: 11 }}
229
+ >
230
+ {s.firstTimestamp ? formatRelative(s.firstTimestamp) : "—"}
231
+ </span>
232
+ ),
233
+ },
204
234
  {
205
235
  key: "lastActive",
206
236
  header: "Last active",
@@ -325,6 +355,7 @@ function SessionCard({ session: s }: { session: SessionMeta }) {
325
355
  >
326
356
  {prettyProjectName(s.projectName)}
327
357
  </span>
358
+ <TeamBadge session={s} linkable={false} />
328
359
  </div>
329
360
  <div
330
361
  style={{