fleetlens 0.4.0 → 0.6.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 (440) hide show
  1. package/app/apps/web/.next/BUILD_ID +1 -1
  2. package/app/apps/web/.next/app-path-routes-manifest.json +16 -7
  3. package/app/apps/web/.next/build-manifest.json +7 -7
  4. package/app/apps/web/.next/prerender-manifest.json +3 -3
  5. package/app/apps/web/.next/required-server-files.json +2 -1
  6. package/app/apps/web/.next/routes-manifest.json +86 -24
  7. package/app/apps/web/.next/server/app/_global-error/page/build-manifest.json +4 -4
  8. package/app/apps/web/.next/server/app/_global-error/page.js +1 -1
  9. package/app/apps/web/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/app/apps/web/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/app/apps/web/.next/server/app/_global-error.html +1 -1
  12. package/app/apps/web/.next/server/app/_global-error.rsc +7 -7
  13. package/app/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/app/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/app/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/app/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/app/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/app/apps/web/.next/server/app/_not-found/page/build-manifest.json +4 -4
  19. package/app/apps/web/.next/server/app/_not-found/page.js +5 -4
  20. package/app/apps/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  21. package/app/apps/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/app/apps/web/.next/server/app/api/digest/day/[date]/route/app-paths-manifest.json +3 -0
  23. package/app/apps/web/.next/server/app/api/digest/day/[date]/route.js +9 -0
  24. package/app/apps/web/.next/server/app/api/{insights/saved/[key] → digest/day/[date]}/route.js.nft.json +1 -1
  25. package/app/apps/web/.next/server/app/api/digest/day/[date]/route_client-reference-manifest.js +3 -0
  26. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route/app-paths-manifest.json +3 -0
  27. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js +9 -0
  28. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route.js.nft.json +1 -0
  29. package/app/apps/web/.next/server/app/api/digest/month/[yearMonth]/route_client-reference-manifest.js +3 -0
  30. package/app/apps/web/.next/server/app/api/digest/month-index/route/app-paths-manifest.json +3 -0
  31. package/app/apps/web/.next/server/app/api/digest/month-index/route.js +7 -0
  32. package/app/apps/web/.next/server/app/api/{insights/months-index → digest/month-index}/route.js.nft.json +1 -1
  33. package/app/apps/web/.next/server/app/api/{insights/pdf/[key] → digest/month-index}/route_client-reference-manifest.js +1 -1
  34. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route/app-paths-manifest.json +3 -0
  35. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js +9 -0
  36. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route.js.nft.json +1 -0
  37. package/app/apps/web/.next/server/app/api/digest/week/[startDate]/route_client-reference-manifest.js +3 -0
  38. package/app/apps/web/.next/server/app/api/digest/week-index/route/app-paths-manifest.json +3 -0
  39. package/app/apps/web/.next/server/app/api/digest/week-index/route.js +7 -0
  40. package/app/apps/web/.next/server/app/api/{insights/weeks-index → digest/week-index}/route.js.nft.json +1 -1
  41. package/app/apps/web/.next/server/app/api/digest/week-index/route_client-reference-manifest.js +3 -0
  42. package/app/apps/web/.next/server/app/api/jobs/route/app-paths-manifest.json +3 -0
  43. package/app/apps/web/.next/server/app/api/jobs/route.js +6 -0
  44. package/app/apps/web/.next/server/app/api/jobs/route.js.nft.json +1 -0
  45. package/app/apps/web/.next/server/app/api/jobs/route_client-reference-manifest.js +3 -0
  46. package/app/apps/web/.next/server/app/api/runs/[runId]/route/app-paths-manifest.json +3 -0
  47. package/app/apps/web/.next/server/app/api/runs/[runId]/route/build-manifest.json +9 -0
  48. package/app/apps/web/.next/server/app/api/runs/[runId]/route.js +6 -0
  49. package/app/apps/web/.next/server/app/api/{insights/saved → runs/[runId]}/route.js.nft.json +1 -1
  50. package/app/apps/web/.next/server/app/api/runs/[runId]/route_client-reference-manifest.js +3 -0
  51. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route/app-paths-manifest.json +3 -0
  52. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route/build-manifest.json +9 -0
  53. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route/server-reference-manifest.json +4 -0
  54. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js +6 -0
  55. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route.js.map +5 -0
  56. package/app/apps/web/.next/server/app/api/{insights/pdf/[key] → runs/[runId]/stream}/route.js.nft.json +1 -1
  57. package/app/apps/web/.next/server/app/api/runs/[runId]/stream/route_client-reference-manifest.js +3 -0
  58. package/app/apps/web/.next/server/app/api/runs/route/app-paths-manifest.json +3 -0
  59. package/app/apps/web/.next/server/app/api/runs/route/build-manifest.json +9 -0
  60. package/app/apps/web/.next/server/app/api/runs/route/server-reference-manifest.json +4 -0
  61. package/app/apps/web/.next/server/app/api/runs/route.js +6 -0
  62. package/app/apps/web/.next/server/app/api/runs/route.js.map +5 -0
  63. package/app/apps/web/.next/server/app/api/{insights → runs}/route.js.nft.json +1 -1
  64. package/app/apps/web/.next/server/app/api/runs/route_client-reference-manifest.js +3 -0
  65. package/app/apps/web/.next/server/app/api/settings/route/app-paths-manifest.json +3 -0
  66. package/app/apps/web/.next/server/app/api/settings/route/build-manifest.json +9 -0
  67. package/app/apps/web/.next/server/app/api/settings/route/server-reference-manifest.json +4 -0
  68. package/app/apps/web/.next/server/app/api/settings/route.js +10 -0
  69. package/app/apps/web/.next/server/app/api/settings/route.js.map +5 -0
  70. package/app/apps/web/.next/server/app/api/settings/route.js.nft.json +1 -0
  71. package/app/apps/web/.next/server/app/api/{insights → settings}/route_client-reference-manifest.js +1 -1
  72. package/app/apps/web/.next/server/app/day/[date]/page/app-paths-manifest.json +3 -0
  73. package/app/apps/web/.next/server/app/{insights/print/[key] → day/[date]}/page/build-manifest.json +4 -4
  74. package/app/apps/web/.next/server/app/day/[date]/page/server-reference-manifest.json +4 -0
  75. package/app/apps/web/.next/server/app/day/[date]/page.js +18 -0
  76. package/app/apps/web/.next/server/app/day/[date]/page.js.map +5 -0
  77. package/app/apps/web/.next/server/app/day/[date]/page.js.nft.json +1 -0
  78. package/app/apps/web/.next/server/app/day/[date]/page_client-reference-manifest.js +3 -0
  79. package/app/apps/web/.next/server/app/day/page/app-paths-manifest.json +3 -0
  80. package/app/apps/web/.next/server/app/day/page/build-manifest.json +17 -0
  81. package/app/apps/web/.next/server/app/day/page/next-font-manifest.json +6 -0
  82. package/app/apps/web/.next/server/app/day/page/react-loadable-manifest.json +1 -0
  83. package/app/apps/web/.next/server/app/day/page/server-reference-manifest.json +4 -0
  84. package/app/apps/web/.next/server/app/{insights/print/[key] → day}/page.js +11 -10
  85. package/app/apps/web/.next/server/app/day/page.js.map +5 -0
  86. package/app/apps/web/.next/server/app/day/page.js.nft.json +1 -0
  87. package/app/apps/web/.next/server/app/day/page_client-reference-manifest.js +3 -0
  88. package/app/apps/web/.next/server/app/digest/[date]/page/app-paths-manifest.json +3 -0
  89. package/app/apps/web/.next/server/app/digest/[date]/page/build-manifest.json +17 -0
  90. package/app/apps/web/.next/server/app/digest/[date]/page/next-font-manifest.json +6 -0
  91. package/app/apps/web/.next/server/app/digest/[date]/page/react-loadable-manifest.json +1 -0
  92. package/app/apps/web/.next/server/app/digest/[date]/page/server-reference-manifest.json +4 -0
  93. package/app/apps/web/.next/server/app/digest/[date]/page.js +17 -0
  94. package/app/apps/web/.next/server/app/digest/[date]/page.js.map +5 -0
  95. package/app/apps/web/.next/server/app/digest/[date]/page.js.nft.json +1 -0
  96. package/app/apps/web/.next/server/app/digest/[date]/page_client-reference-manifest.js +3 -0
  97. package/app/apps/web/.next/server/app/digest/page/app-paths-manifest.json +3 -0
  98. package/app/apps/web/.next/server/app/digest/page/build-manifest.json +17 -0
  99. package/app/apps/web/.next/server/app/digest/page/next-font-manifest.json +6 -0
  100. package/app/apps/web/.next/server/app/digest/page/react-loadable-manifest.json +1 -0
  101. package/app/apps/web/.next/server/app/digest/page/server-reference-manifest.json +4 -0
  102. package/app/apps/web/.next/server/app/digest/page.js +17 -0
  103. package/app/apps/web/.next/server/app/digest/page.js.map +5 -0
  104. package/app/apps/web/.next/server/app/digest/page.js.nft.json +1 -0
  105. package/app/apps/web/.next/server/app/digest/page_client-reference-manifest.js +3 -0
  106. package/app/apps/web/.next/server/app/insights/[key]/page/build-manifest.json +4 -4
  107. package/app/apps/web/.next/server/app/insights/[key]/page.js +7 -5
  108. package/app/apps/web/.next/server/app/insights/[key]/page.js.nft.json +1 -1
  109. package/app/apps/web/.next/server/app/insights/[key]/page_client-reference-manifest.js +1 -1
  110. package/app/apps/web/.next/server/app/insights/page/build-manifest.json +4 -4
  111. package/app/apps/web/.next/server/app/insights/page.js +7 -5
  112. package/app/apps/web/.next/server/app/insights/page.js.nft.json +1 -1
  113. package/app/apps/web/.next/server/app/insights/page_client-reference-manifest.js +1 -1
  114. package/app/apps/web/.next/server/app/page/build-manifest.json +4 -4
  115. package/app/apps/web/.next/server/app/page.js +7 -6
  116. package/app/apps/web/.next/server/app/page.js.nft.json +1 -1
  117. package/app/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  118. package/app/apps/web/.next/server/app/parallelism/page/build-manifest.json +4 -4
  119. package/app/apps/web/.next/server/app/parallelism/page.js +6 -5
  120. package/app/apps/web/.next/server/app/parallelism/page.js.nft.json +1 -1
  121. package/app/apps/web/.next/server/app/parallelism/page_client-reference-manifest.js +1 -1
  122. package/app/apps/web/.next/server/app/projects/[slug]/page/build-manifest.json +4 -4
  123. package/app/apps/web/.next/server/app/projects/[slug]/page.js +6 -5
  124. package/app/apps/web/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
  125. package/app/apps/web/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
  126. package/app/apps/web/.next/server/app/projects/page/build-manifest.json +4 -4
  127. package/app/apps/web/.next/server/app/projects/page.js +5 -4
  128. package/app/apps/web/.next/server/app/projects/page.js.nft.json +1 -1
  129. package/app/apps/web/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  130. package/app/apps/web/.next/server/app/runs/page/app-paths-manifest.json +3 -0
  131. package/app/apps/web/.next/server/app/runs/page/build-manifest.json +17 -0
  132. package/app/apps/web/.next/server/app/runs/page/next-font-manifest.json +6 -0
  133. package/app/apps/web/.next/server/app/runs/page/react-loadable-manifest.json +1 -0
  134. package/app/apps/web/.next/server/app/runs/page/server-reference-manifest.json +4 -0
  135. package/app/apps/web/.next/server/app/runs/page.js +17 -0
  136. package/app/apps/web/.next/server/app/runs/page.js.map +5 -0
  137. package/app/apps/web/.next/server/app/runs/page.js.nft.json +1 -0
  138. package/app/apps/web/.next/server/app/runs/page_client-reference-manifest.js +3 -0
  139. package/app/apps/web/.next/server/app/sessions/[id]/page/build-manifest.json +4 -4
  140. package/app/apps/web/.next/server/app/sessions/[id]/page.js +5 -4
  141. package/app/apps/web/.next/server/app/sessions/[id]/page.js.nft.json +1 -1
  142. package/app/apps/web/.next/server/app/sessions/[id]/page_client-reference-manifest.js +1 -1
  143. package/app/apps/web/.next/server/app/sessions/page/build-manifest.json +4 -4
  144. package/app/apps/web/.next/server/app/sessions/page.js +5 -4
  145. package/app/apps/web/.next/server/app/sessions/page.js.nft.json +1 -1
  146. package/app/apps/web/.next/server/app/sessions/page_client-reference-manifest.js +1 -1
  147. package/app/apps/web/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  148. package/app/apps/web/.next/server/app/settings/page/build-manifest.json +17 -0
  149. package/app/apps/web/.next/server/app/settings/page/next-font-manifest.json +6 -0
  150. package/app/apps/web/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  151. package/app/apps/web/.next/server/app/settings/page/server-reference-manifest.json +4 -0
  152. package/app/apps/web/.next/server/app/settings/page.js +18 -0
  153. package/app/apps/web/.next/server/app/settings/page.js.map +5 -0
  154. package/app/apps/web/.next/server/app/settings/page.js.nft.json +1 -0
  155. package/app/apps/web/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  156. package/app/apps/web/.next/server/app/usage/page/build-manifest.json +4 -4
  157. package/app/apps/web/.next/server/app/usage/page.js +6 -5
  158. package/app/apps/web/.next/server/app/usage/page.js.nft.json +1 -1
  159. package/app/apps/web/.next/server/app/usage/page_client-reference-manifest.js +1 -1
  160. package/app/apps/web/.next/server/app-paths-manifest.json +16 -7
  161. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_digest_week_[startDate]_route_actions_0klqqsh.js +3 -0
  162. package/app/apps/web/.next/server/chunks/09og__next-internal_server_app_api_digest_month_[yearMonth]_route_actions_0i4ielu.js +3 -0
  163. package/app/apps/web/.next/server/chunks/[externals]__0o43ejh._.js +3 -0
  164. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0-vgrh1._.js +3 -0
  165. package/app/apps/web/.next/server/chunks/[root-of-the-server]__00n3f9y._.js +3 -0
  166. package/app/apps/web/.next/server/chunks/[root-of-the-server]__02zukjw._.js +3 -0
  167. package/app/apps/web/.next/server/chunks/[root-of-the-server]__067~im1._.js +6 -0
  168. package/app/apps/web/.next/server/chunks/[root-of-the-server]__06b4cj-._.js +3 -0
  169. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0_8zh-i._.js +9 -0
  170. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0e8n_x4._.js +3 -0
  171. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ej_p3s._.js +9 -0
  172. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0jprdks._.js +9 -0
  173. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_digest_day_[date]_route_actions_09sxie5.js +3 -0
  174. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_digest_month-index_route_actions_0wldpbu.js +3 -0
  175. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_digest_week-index_route_actions_12c2wj2.js +3 -0
  176. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_jobs_route_actions_08kx~8-.js +3 -0
  177. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_runs_[runId]_route_actions_0dfcghc.js +3 -0
  178. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_runs_[runId]_stream_route_actions_0.8e8-k.js +3 -0
  179. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_runs_route_actions_0xyx82f.js +3 -0
  180. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_settings_route_actions_0.xv7sx.js +3 -0
  181. package/app/apps/web/.next/server/chunks/node_modules_next_036my~r._.js +49 -0
  182. package/app/apps/web/.next/server/chunks/packages_0e7q9u_._.js +3 -0
  183. package/app/apps/web/.next/server/chunks/packages_0n6p2ot._.js +3 -0
  184. package/app/apps/web/.next/server/chunks/packages_entries_dist_node_0bckr7-.js +379 -0
  185. package/app/apps/web/.next/server/chunks/packages_parser_dist_fs_0bc7ptm.js +1 -1
  186. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0-1_njm._.js +3 -0
  187. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0-94ji~._.js +3 -0
  188. package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__13xpdx0._.js → [root-of-the-server]__03uoeiw._.js} +2 -2
  189. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0_6.inc._.js +1 -1
  190. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0d~2~le._.js +8 -0
  191. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gio_ck._.js +1 -1
  192. package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__08.d5ia._.js → [root-of-the-server]__0jdyefm._.js} +10 -10
  193. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0ln9jsw._.js +3 -0
  194. package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0z45d0g._.js → [root-of-the-server]__0lz4a~g._.js} +2 -48
  195. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0o1_g.~._.js +3 -0
  196. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0r4tks8._.js +3 -0
  197. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0rvzdnx._.js +3 -0
  198. package/app/apps/web/.next/server/chunks/ssr/{[root-of-the-server]__0euu8sa._.js → [root-of-the-server]__0u39afl._.js} +2 -2
  199. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0u5d7de._.js +12 -0
  200. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0w52fbc._.js +3 -3
  201. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0wwa6gh._.js +3 -0
  202. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0xy1qim._.js +3 -0
  203. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0~_8vff._.js +3 -0
  204. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__10srpu0._.js +3 -0
  205. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__11v.eqw._.js +1 -1
  206. package/app/apps/web/.next/server/chunks/ssr/_02s1n-x._.js +8 -0
  207. package/app/apps/web/.next/server/chunks/ssr/_0fjbf--._.js +3 -0
  208. package/app/apps/web/.next/server/chunks/ssr/_0jw2sm7._.js +3 -0
  209. package/app/apps/web/.next/server/chunks/ssr/_0wj750k._.js +3 -0
  210. package/app/apps/web/.next/server/chunks/ssr/_0woap-3._.js +1 -1
  211. package/app/apps/web/.next/server/chunks/ssr/{_0xies90._.js → _0xu2pvc._.js} +2 -2
  212. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_day_[date]_page_actions_0u2kxb..js +3 -0
  213. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_day_page_actions_1042maj.js +3 -0
  214. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_digest_[date]_page_actions_0olu967.js +3 -0
  215. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_digest_page_actions_0bl.eil.js +3 -0
  216. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_runs_page_actions_0485qy7.js +3 -0
  217. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_settings_page_actions_0f6epye.js +3 -0
  218. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_day_[date]_day-view_tsx_0wjoe1u._.js +3 -0
  219. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_settings_ai-features-form_tsx_01p699p._.js +3 -0
  220. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0b-4-4j._.js +1 -1
  221. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0ly1xes._.js +6 -0
  222. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0txtsv5._.js +16 -0
  223. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0xs658s._.js +10 -0
  224. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_runs-live-board_tsx_0r6dkdq._.js +3 -0
  225. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_usage-charts-dashboard_tsx_0bgr_uv._.js +1 -1
  226. package/app/apps/web/.next/server/chunks/ssr/apps_web_lib_usage-data_ts_0xtv99n._.js +3 -0
  227. package/app/apps/web/.next/server/chunks/ssr/node_modules_0i2xw~e._.js +3 -0
  228. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_0e1izl_._.js +1 -1
  229. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0d3d4wn.js +4 -0
  230. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0edz1ko.js +4 -0
  231. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0eq.n-n.js +4 -0
  232. package/app/apps/web/.next/server/chunks/ssr/{node_modules_next_dist_esm_build_templates_app-page_0vz7_px.js → node_modules_next_dist_esm_build_templates_app-page_0hcvt-s.js} +3 -3
  233. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0nd5zu0.js +4 -0
  234. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11j1qy0.js +4 -0
  235. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12n1lw_.js +1 -1
  236. package/app/apps/web/.next/server/chunks/ssr/packages_entries_dist_node_0_271yr.js +3 -0
  237. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_0-jvt~a._.js +1 -1
  238. package/app/apps/web/.next/server/functions-config-manifest.json +11 -6
  239. package/app/apps/web/.next/server/middleware-build-manifest.js +7 -7
  240. package/app/apps/web/.next/server/pages/500.html +1 -1
  241. package/app/apps/web/.next/server/server-reference-manifest.js +1 -1
  242. package/app/apps/web/.next/server/server-reference-manifest.json +1 -1
  243. package/app/apps/web/.next/static/chunks/0-yc2_pjxwwuq.js +1 -0
  244. package/app/apps/web/.next/static/chunks/0257pdz1-imal.js +2 -0
  245. package/app/apps/web/.next/static/chunks/05m.oz3kmf1p7.js +1 -0
  246. package/app/apps/web/.next/static/chunks/{0pqt~8bl3ukh4.js → 073081qv4uyn8.js} +1 -1
  247. package/app/apps/web/.next/static/chunks/{0018dy-m-kusj.js → 07lbm-sdh9c2j.js} +1 -1
  248. package/app/apps/web/.next/static/chunks/0858bgw2i4vob.js +1 -0
  249. package/app/apps/web/.next/static/chunks/0_7303jr0sf0w.js +10 -0
  250. package/app/apps/web/.next/static/chunks/0byz8fqw.exef.js +1 -0
  251. package/app/apps/web/.next/static/chunks/0coa1800xqgfj.js +1 -0
  252. package/app/apps/web/.next/static/chunks/0fs3gxea5h0s3.css +1 -0
  253. package/app/apps/web/.next/static/chunks/0k1psab.bybh9.js +14 -0
  254. package/app/apps/web/.next/static/chunks/0k9pksi_i.odf.js +1 -0
  255. package/app/apps/web/.next/static/chunks/0m62vx92~0_0d.js +1 -0
  256. package/app/apps/web/.next/static/chunks/0mc8aa8z.0-5l.js +8 -0
  257. package/app/apps/web/.next/static/chunks/0mykrrv810ra-.js +31 -0
  258. package/app/apps/web/.next/static/chunks/0o9ayt8sknubd.js +1 -0
  259. package/app/apps/web/.next/static/chunks/0osdgl2.9cl1q.js +6 -0
  260. package/app/apps/web/.next/static/chunks/0xfu09fn_358k.js +4 -0
  261. package/app/apps/web/.next/static/chunks/171za22fv684..js +6 -0
  262. package/app/apps/web/.next/static/chunks/17u2ww8ya5dv1.js +6 -0
  263. package/app/apps/web/.next/static/chunks/{turbopack-169w-1._23ra_.js → turbopack-0_p36yduv.waj.js} +1 -1
  264. package/app/apps/web/app/api/digest/day/[date]/route.ts +152 -0
  265. package/app/apps/web/app/api/digest/month/[yearMonth]/route.ts +147 -0
  266. package/app/apps/web/app/api/digest/month-index/route.ts +103 -0
  267. package/app/apps/web/app/api/digest/week/[startDate]/route.ts +149 -0
  268. package/app/apps/web/app/api/{insights/weeks-index → digest/week-index}/route.ts +45 -33
  269. package/app/apps/web/app/api/jobs/route.ts +8 -0
  270. package/app/apps/web/app/api/runs/[runId]/route.ts +64 -0
  271. package/app/apps/web/app/api/runs/[runId]/stream/route.ts +154 -0
  272. package/app/apps/web/app/api/runs/route.ts +266 -0
  273. package/app/apps/web/app/api/settings/route.ts +35 -0
  274. package/app/apps/web/app/day/[date]/day-view.tsx +193 -0
  275. package/app/apps/web/app/day/[date]/page.tsx +175 -0
  276. package/app/apps/web/app/day/page.tsx +8 -0
  277. package/app/apps/web/app/digest/[date]/page.tsx +15 -0
  278. package/app/apps/web/app/digest/page.tsx +7 -0
  279. package/app/apps/web/app/insights/[key]/page.tsx +106 -48
  280. package/app/apps/web/app/insights/page.tsx +133 -3
  281. package/app/apps/web/app/layout.tsx +23 -3
  282. package/app/apps/web/app/page.tsx +33 -4
  283. package/app/apps/web/app/parallelism/gantt-chart.tsx +67 -1
  284. package/app/apps/web/app/parallelism/page.tsx +8 -278
  285. package/app/apps/web/app/projects/[slug]/page.tsx +153 -0
  286. package/app/apps/web/app/projects/page.tsx +49 -4
  287. package/app/apps/web/app/projects/projects-view.tsx +79 -68
  288. package/app/apps/web/app/runs/page.tsx +21 -0
  289. package/app/apps/web/app/sessions/[id]/page.tsx +12 -1
  290. package/app/apps/web/app/sessions/[id]/session-view.tsx +569 -21
  291. package/app/apps/web/app/sessions/page.tsx +19 -3
  292. package/app/apps/web/app/sessions/sessions-grid.tsx +172 -131
  293. package/app/apps/web/app/settings/ai-features-form.tsx +45 -0
  294. package/app/apps/web/app/settings/page.tsx +20 -0
  295. package/app/apps/web/app/usage/page.tsx +45 -3
  296. package/app/apps/web/components/auto-generate-yesterday.tsx +96 -0
  297. package/app/apps/web/components/backfill-drawer.tsx +309 -0
  298. package/app/apps/web/components/dashboard-view.tsx +4 -2
  299. package/app/apps/web/components/date-nav.tsx +385 -0
  300. package/app/apps/web/components/day-digest-view.tsx +180 -0
  301. package/app/apps/web/components/day-digest.tsx +489 -0
  302. package/app/apps/web/components/flag-chip.tsx +54 -0
  303. package/app/apps/web/components/goal-bar.tsx +63 -0
  304. package/app/apps/web/components/heatmap.tsx +78 -1
  305. package/app/apps/web/components/helpfulness-sparkline.tsx +82 -0
  306. package/app/apps/web/components/insights-history.tsx +211 -0
  307. package/app/apps/web/components/insights-top-bar.tsx +216 -0
  308. package/app/apps/web/components/job-queue-widget.tsx +274 -0
  309. package/app/apps/web/components/live-sessions-widget.tsx +38 -3
  310. package/app/apps/web/components/month-digest-view.tsx +138 -0
  311. package/app/apps/web/components/month-digest.tsx +216 -0
  312. package/app/apps/web/components/outcome-mix-row.tsx +37 -0
  313. package/app/apps/web/components/outcome-pill.tsx +101 -0
  314. package/app/apps/web/components/previous-cycles-trend.tsx +155 -0
  315. package/app/apps/web/components/recent-days-panel.tsx +83 -0
  316. package/app/apps/web/components/runs-live-board.tsx +513 -0
  317. package/app/apps/web/components/sidebar.tsx +38 -4
  318. package/app/apps/web/components/usage-chart-range.tsx +58 -6
  319. package/app/apps/web/components/usage-chart.tsx +94 -7
  320. package/app/apps/web/components/usage-charts-dashboard.tsx +20 -1
  321. package/app/apps/web/components/week-digest-view.tsx +226 -0
  322. package/app/apps/web/components/week-digest.tsx +2128 -0
  323. package/app/apps/web/components/yesterday-hero.tsx +110 -0
  324. package/app/apps/web/lib/auto-week-fire.ts +37 -0
  325. package/app/apps/web/lib/calibration-data.ts +171 -0
  326. package/app/apps/web/lib/entries-index.ts +174 -0
  327. package/app/apps/web/lib/entries.ts +72 -0
  328. package/app/apps/web/lib/inflight-coalesce.test.ts +43 -0
  329. package/app/apps/web/lib/inflight-coalesce.ts +19 -0
  330. package/app/apps/web/lib/jobs.ts +170 -0
  331. package/app/apps/web/lib/usage-data.ts +37 -0
  332. package/app/apps/web/lib/validate-settings.test.ts +25 -0
  333. package/app/apps/web/lib/validate-settings.ts +9 -0
  334. package/app/apps/web/next.config.ts +1 -1
  335. package/app/apps/web/package.json +4 -2
  336. package/app/apps/web/server.js +1 -1
  337. package/app/apps/web/tsconfig.tsbuildinfo +1 -1
  338. package/app/apps/web/vitest.config.ts +9 -0
  339. package/dist/daemon-worker.js +1758 -713
  340. package/dist/index.js +11308 -1888
  341. package/package.json +4 -1
  342. package/app/apps/web/.next/server/app/api/insights/months-index/route/app-paths-manifest.json +0 -3
  343. package/app/apps/web/.next/server/app/api/insights/months-index/route.js +0 -7
  344. package/app/apps/web/.next/server/app/api/insights/months-index/route_client-reference-manifest.js +0 -3
  345. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route/app-paths-manifest.json +0 -3
  346. package/app/apps/web/.next/server/app/api/insights/pdf/[key]/route.js +0 -6
  347. package/app/apps/web/.next/server/app/api/insights/route/app-paths-manifest.json +0 -3
  348. package/app/apps/web/.next/server/app/api/insights/route.js +0 -8
  349. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route/app-paths-manifest.json +0 -3
  350. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route.js +0 -6
  351. package/app/apps/web/.next/server/app/api/insights/saved/[key]/route_client-reference-manifest.js +0 -3
  352. package/app/apps/web/.next/server/app/api/insights/saved/route/app-paths-manifest.json +0 -3
  353. package/app/apps/web/.next/server/app/api/insights/saved/route.js +0 -6
  354. package/app/apps/web/.next/server/app/api/insights/saved/route_client-reference-manifest.js +0 -3
  355. package/app/apps/web/.next/server/app/api/insights/weeks-index/route/app-paths-manifest.json +0 -3
  356. package/app/apps/web/.next/server/app/api/insights/weeks-index/route.js +0 -7
  357. package/app/apps/web/.next/server/app/api/insights/weeks-index/route_client-reference-manifest.js +0 -3
  358. package/app/apps/web/.next/server/app/insights/print/[key]/page/app-paths-manifest.json +0 -3
  359. package/app/apps/web/.next/server/app/insights/print/[key]/page.js.nft.json +0 -1
  360. package/app/apps/web/.next/server/app/insights/print/[key]/page_client-reference-manifest.js +0 -3
  361. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_months-index_route_actions_0~h~zci.js +0 -3
  362. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_saved_[key]_route_actions_0a5j9yw.js +0 -3
  363. package/app/apps/web/.next/server/chunks/02dz_web__next-internal_server_app_api_insights_weeks-index_route_actions_0hh-1c7.js +0 -3
  364. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0.hmj0z._.js +0 -3
  365. package/app/apps/web/.next/server/chunks/[root-of-the-server]__01h_g-p._.js +0 -3
  366. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0nh-z10._.js +0 -3
  367. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0ri7q~r._.js +0 -3
  368. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0rr1~~x._.js +0 -3
  369. package/app/apps/web/.next/server/chunks/[root-of-the-server]__0s0gv.0._.js +0 -3
  370. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_pdf_[key]_route_actions_0lu-lnx.js +0 -3
  371. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_route_actions_0h8l5lz.js +0 -3
  372. package/app/apps/web/.next/server/chunks/apps_web__next-internal_server_app_api_insights_saved_route_actions_13rlblw.js +0 -3
  373. package/app/apps/web/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_00t2xj6.js +0 -68
  374. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0.tsxpj._.js +0 -3
  375. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__00z7zlm._.js +0 -3
  376. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__08pen0k._.js +0 -3
  377. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0b323~k._.js +0 -8
  378. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0gx-4qa._.js +0 -3
  379. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0wv27wt._.js +0 -3
  380. package/app/apps/web/.next/server/chunks/ssr/[root-of-the-server]__13itnvx._.js +0 -3
  381. package/app/apps/web/.next/server/chunks/ssr/_09n75_5._.js +0 -8
  382. package/app/apps/web/.next/server/chunks/ssr/_0r~__0v._.js +0 -12
  383. package/app/apps/web/.next/server/chunks/ssr/apps_web__next-internal_server_app_insights_print_[key]_page_actions_0a853fw.js +0 -3
  384. package/app/apps/web/.next/server/chunks/ssr/apps_web_app_parallelism_08vub.0._.js +0 -3
  385. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_06j3c.0._.js +0 -8
  386. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_0bbo_pd._.js +0 -8
  387. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insight-report_tsx_13q2a-c._.js +0 -12
  388. package/app/apps/web/.next/server/chunks/ssr/apps_web_components_insights-view_tsx_11730ta._.js +0 -6
  389. package/app/apps/web/.next/server/chunks/ssr/node_modules_lucide-react_dist_esm_icons_0nqz8dw._.js +0 -3
  390. package/app/apps/web/.next/server/chunks/ssr/node_modules_next_dist_0t-hj0x._.js +0 -3
  391. package/app/apps/web/.next/server/chunks/ssr/packages_parser_dist_analytics_0k4dgst.js +0 -3
  392. package/app/apps/web/.next/static/chunks/028_pmk40b69_.js +0 -6
  393. package/app/apps/web/.next/static/chunks/03.mv4y4.w-vb.js +0 -6
  394. package/app/apps/web/.next/static/chunks/03_7xtpi9sv4g.js +0 -4
  395. package/app/apps/web/.next/static/chunks/03g5dw5eskotd.js +0 -6
  396. package/app/apps/web/.next/static/chunks/063oimt30jeo9.js +0 -10
  397. package/app/apps/web/.next/static/chunks/08c1pcrocqq5s.js +0 -6
  398. package/app/apps/web/.next/static/chunks/0e-wrhqh4h3r5.js +0 -2
  399. package/app/apps/web/.next/static/chunks/0fc6dk2qtokwh.js +0 -1
  400. package/app/apps/web/.next/static/chunks/0i7er7_bfab36.js +0 -10
  401. package/app/apps/web/.next/static/chunks/0ipytyi01h0ta.js +0 -1
  402. package/app/apps/web/.next/static/chunks/0lsznd4_avzhv.js +0 -6
  403. package/app/apps/web/.next/static/chunks/0lty3v_i9mde7.js +0 -1
  404. package/app/apps/web/.next/static/chunks/0vekjjj4pidlz.css +0 -1
  405. package/app/apps/web/.next/static/chunks/137uw2-qbro07.js +0 -31
  406. package/app/apps/web/app/api/insights/months-index/route.ts +0 -80
  407. package/app/apps/web/app/api/insights/pdf/[key]/route.ts +0 -45
  408. package/app/apps/web/app/api/insights/route.ts +0 -508
  409. package/app/apps/web/app/api/insights/saved/[key]/route.ts +0 -11
  410. package/app/apps/web/app/api/insights/saved/route.ts +0 -9
  411. package/app/apps/web/app/insights/print/[key]/page.tsx +0 -73
  412. package/app/apps/web/components/insight-report.tsx +0 -1031
  413. package/app/apps/web/components/insights-view.tsx +0 -647
  414. package/app/apps/web/lib/ai/insights-prompt.ts +0 -71
  415. package/app/apps/web/lib/ai/saved-reports.ts +0 -83
  416. /package/app/apps/web/.next/server/app/api/{insights/months-index → digest/day/[date]}/route/build-manifest.json +0 -0
  417. /package/app/apps/web/.next/server/app/api/{insights/months-index → digest/day/[date]}/route/server-reference-manifest.json +0 -0
  418. /package/app/apps/web/.next/server/app/api/{insights/months-index → digest/day/[date]}/route.js.map +0 -0
  419. /package/app/apps/web/.next/server/app/api/{insights → digest/month/[yearMonth]}/route/build-manifest.json +0 -0
  420. /package/app/apps/web/.next/server/app/api/{insights → digest/month/[yearMonth]}/route/server-reference-manifest.json +0 -0
  421. /package/app/apps/web/.next/server/app/api/{insights → digest/month/[yearMonth]}/route.js.map +0 -0
  422. /package/app/apps/web/.next/server/app/api/{insights/pdf/[key] → digest/month-index}/route/build-manifest.json +0 -0
  423. /package/app/apps/web/.next/server/app/api/{insights/pdf/[key] → digest/month-index}/route/server-reference-manifest.json +0 -0
  424. /package/app/apps/web/.next/server/app/api/{insights/pdf/[key] → digest/month-index}/route.js.map +0 -0
  425. /package/app/apps/web/.next/server/app/api/{insights/saved → digest/week/[startDate]}/route/build-manifest.json +0 -0
  426. /package/app/apps/web/.next/server/app/api/{insights/saved → digest/week/[startDate]}/route/server-reference-manifest.json +0 -0
  427. /package/app/apps/web/.next/server/app/api/{insights/saved → digest/week/[startDate]}/route.js.map +0 -0
  428. /package/app/apps/web/.next/server/app/api/{insights/saved/[key] → digest/week-index}/route/build-manifest.json +0 -0
  429. /package/app/apps/web/.next/server/app/api/{insights/saved/[key] → digest/week-index}/route/server-reference-manifest.json +0 -0
  430. /package/app/apps/web/.next/server/app/api/{insights/saved/[key] → digest/week-index}/route.js.map +0 -0
  431. /package/app/apps/web/.next/server/app/api/{insights/weeks-index → jobs}/route/build-manifest.json +0 -0
  432. /package/app/apps/web/.next/server/app/api/{insights/weeks-index → jobs}/route/server-reference-manifest.json +0 -0
  433. /package/app/apps/web/.next/server/app/api/{insights/weeks-index → jobs}/route.js.map +0 -0
  434. /package/app/apps/web/.next/server/app/{insights/print/[key]/page → api/runs/[runId]/route}/server-reference-manifest.json +0 -0
  435. /package/app/apps/web/.next/server/app/{insights/print/[key]/page.js.map → api/runs/[runId]/route.js.map} +0 -0
  436. /package/app/apps/web/.next/server/app/{insights/print/[key] → day/[date]}/page/next-font-manifest.json +0 -0
  437. /package/app/apps/web/.next/server/app/{insights/print/[key] → day/[date]}/page/react-loadable-manifest.json +0 -0
  438. /package/app/apps/web/.next/static/{G_4ofKI9v9ARC_lb9JILZ → 8tTWPvUhtatZEoocIhamh}/_buildManifest.js +0 -0
  439. /package/app/apps/web/.next/static/{G_4ofKI9v9ARC_lb9JILZ → 8tTWPvUhtatZEoocIhamh}/_clientMiddlewareManifest.js +0 -0
  440. /package/app/apps/web/.next/static/{G_4ofKI9v9ARC_lb9JILZ → 8tTWPvUhtatZEoocIhamh}/_ssgManifest.js +0 -0
@@ -0,0 +1,385 @@
1
+ "use client";
2
+
3
+ import { useRouter } from "next/navigation";
4
+ import { useMemo, useState } from "react";
5
+ import Link from "next/link";
6
+
7
+ export type DayInfo = {
8
+ date: string;
9
+ sessions: number;
10
+ /** Total airtime across sessions that started this day. */
11
+ airTimeMs: number;
12
+ /** Total parallel burst time on this day. */
13
+ parallelMs: number;
14
+ /** Number of bursts on this day. */
15
+ burstCount: number;
16
+ /** Peak concurrency on this day (max across all its bursts). */
17
+ peakConcurrency: number;
18
+ };
19
+
20
+ /** Compact duration like "45m", "2h", "3h 20m". */
21
+ function fmtShortDur(ms: number): string {
22
+ if (ms < 60_000) return `${Math.round(ms / 1000)}s`;
23
+ const totalMin = Math.round(ms / 60_000);
24
+ if (totalMin < 60) return `${totalMin}m`;
25
+ const h = Math.floor(totalMin / 60);
26
+ const m = totalMin % 60;
27
+ return m ? `${h}h ${m}m` : `${h}h`;
28
+ }
29
+
30
+ /**
31
+ * Custom date picker with a mini-calendar popover. Each cell tints with
32
+ * intensity proportional to the day's airtime; days with concurrency
33
+ * bursts get a small purple corner dot. URL pattern is parameterized so
34
+ * the same widget works on /day/[date] and any future day-scoped surface.
35
+ */
36
+ export function DateNav({
37
+ date,
38
+ today,
39
+ prevDay,
40
+ nextDay,
41
+ dayStats,
42
+ hrefForDate = (d) => `/day/${d}`,
43
+ }: {
44
+ date: string;
45
+ today: string;
46
+ prevDay?: string;
47
+ nextDay?: string;
48
+ /** Per-day session counts for the calendar heatmap. */
49
+ dayStats: DayInfo[];
50
+ /** Build the navigation URL for a given YYYY-MM-DD date. */
51
+ hrefForDate?: (date: string) => string;
52
+ }) {
53
+ const router = useRouter();
54
+ const [calOpen, setCalOpen] = useState(false);
55
+
56
+ const [selY, selM] = useMemo(() => {
57
+ const [y, m] = date.split("-").map(Number) as [number, number, number];
58
+ return [y, m];
59
+ }, [date]);
60
+
61
+ const [viewY, setViewY] = useState(selY);
62
+ const [viewM, setViewM] = useState(selM);
63
+ const [hoverDay, setHoverDay] = useState<string | null>(null);
64
+ const [hoverPos, setHoverPos] = useState<{ x: number; y: number } | null>(null);
65
+
66
+ const statsMap = useMemo(() => {
67
+ const map = new Map<string, DayInfo>();
68
+ for (const d of dayStats) map.set(d.date, d);
69
+ return map;
70
+ }, [dayStats]);
71
+
72
+ const calDays = useMemo(() => {
73
+ const firstOfMonth = new Date(viewY, viewM - 1, 1);
74
+ const startDow = firstOfMonth.getDay();
75
+ const daysInMonth = new Date(viewY, viewM, 0).getDate();
76
+ const cells: (string | null)[] = [];
77
+ for (let i = 0; i < startDow; i++) cells.push(null);
78
+ for (let d = 1; d <= daysInMonth; d++) {
79
+ const mm = String(viewM).padStart(2, "0");
80
+ const dd = String(d).padStart(2, "0");
81
+ cells.push(`${viewY}-${mm}-${dd}`);
82
+ }
83
+ return cells;
84
+ }, [viewY, viewM]);
85
+
86
+ const maxAirTimeMs = useMemo(() => {
87
+ let max = 0;
88
+ for (const d of dayStats) if (d.airTimeMs > max) max = d.airTimeMs;
89
+ return max;
90
+ }, [dayStats]);
91
+
92
+ const monthLabel = new Date(viewY, viewM - 1).toLocaleString(undefined, {
93
+ month: "long", year: "numeric",
94
+ });
95
+
96
+ const goMonth = (delta: number) => {
97
+ let m = viewM + delta;
98
+ let y = viewY;
99
+ if (m < 1) { m = 12; y--; }
100
+ if (m > 12) { m = 1; y++; }
101
+ setViewM(m);
102
+ setViewY(y);
103
+ };
104
+
105
+ const pickDay = (d: string) => {
106
+ setCalOpen(false);
107
+ router.push(hrefForDate(d));
108
+ };
109
+
110
+ return (
111
+ <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap", position: "relative" }}>
112
+ {prevDay ? (
113
+ <Link
114
+ href={hrefForDate(prevDay)}
115
+ style={{
116
+ padding: "5px 10px",
117
+ border: "1px solid var(--af-border-subtle)",
118
+ borderRadius: 6,
119
+ fontSize: 11,
120
+ color: "var(--af-text-secondary)",
121
+ }}
122
+ >←</Link>
123
+ ) : (
124
+ <span style={{ padding: "5px 10px", opacity: 0.3, fontSize: 11, color: "var(--af-text-tertiary)" }}>←</span>
125
+ )}
126
+
127
+ <button
128
+ type="button"
129
+ onClick={() => {
130
+ setViewY(selY);
131
+ setViewM(selM);
132
+ setCalOpen((p) => !p);
133
+ }}
134
+ style={{
135
+ padding: "5px 12px",
136
+ fontSize: 12,
137
+ fontFamily: "var(--font-mono)",
138
+ border: "1px solid var(--af-border-subtle)",
139
+ borderRadius: 6,
140
+ background: calOpen ? "var(--af-accent-subtle)" : "transparent",
141
+ color: calOpen ? "var(--af-accent)" : "var(--af-text)",
142
+ cursor: "pointer",
143
+ fontWeight: 500,
144
+ minWidth: 120,
145
+ textAlign: "center",
146
+ }}
147
+ >
148
+ {date}
149
+ </button>
150
+
151
+ {nextDay ? (
152
+ <Link
153
+ href={hrefForDate(nextDay)}
154
+ style={{
155
+ padding: "5px 10px",
156
+ border: "1px solid var(--af-border-subtle)",
157
+ borderRadius: 6,
158
+ fontSize: 11,
159
+ color: "var(--af-text-secondary)",
160
+ }}
161
+ >→</Link>
162
+ ) : (
163
+ <span style={{ padding: "5px 10px", opacity: 0.3, fontSize: 11, color: "var(--af-text-tertiary)" }}>→</span>
164
+ )}
165
+
166
+ <Link
167
+ href={hrefForDate(today)}
168
+ style={{
169
+ padding: "5px 12px",
170
+ border: "1px solid var(--af-border-subtle)",
171
+ borderRadius: 6,
172
+ fontSize: 11,
173
+ color: date === today ? "var(--af-accent)" : "var(--af-text-secondary)",
174
+ background: date === today ? "var(--af-accent-subtle)" : "transparent",
175
+ fontWeight: 500,
176
+ }}
177
+ >
178
+ Today
179
+ </Link>
180
+
181
+ {calOpen && (
182
+ <div
183
+ style={{
184
+ position: "absolute",
185
+ top: "calc(100% + 8px)",
186
+ left: 0,
187
+ zIndex: 60,
188
+ background: "var(--af-surface)",
189
+ border: "1px solid var(--af-border-subtle)",
190
+ borderRadius: 10,
191
+ padding: "12px 14px",
192
+ boxShadow: "0 8px 28px rgba(0,0,0,0.18)",
193
+ minWidth: 300,
194
+ }}
195
+ >
196
+ <div style={{
197
+ display: "flex", alignItems: "center", justifyContent: "space-between",
198
+ marginBottom: 10,
199
+ }}>
200
+ <button
201
+ type="button"
202
+ onClick={() => goMonth(-1)}
203
+ style={{
204
+ background: "transparent", border: "none", cursor: "pointer",
205
+ color: "var(--af-text-secondary)", fontSize: 14, padding: "2px 8px", borderRadius: 4,
206
+ }}
207
+ >‹</button>
208
+ <span style={{ fontSize: 13, fontWeight: 600, color: "var(--af-text)" }}>{monthLabel}</span>
209
+ <button
210
+ type="button"
211
+ onClick={() => goMonth(1)}
212
+ style={{
213
+ background: "transparent", border: "none", cursor: "pointer",
214
+ color: "var(--af-text-secondary)", fontSize: 14, padding: "2px 8px", borderRadius: 4,
215
+ }}
216
+ >›</button>
217
+ </div>
218
+
219
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 2, marginBottom: 4 }}>
220
+ {["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"].map((d) => (
221
+ <div key={d} style={{
222
+ textAlign: "center", fontSize: 9, color: "var(--af-text-tertiary)",
223
+ fontWeight: 600, padding: "2px 0",
224
+ }}>{d}</div>
225
+ ))}
226
+ </div>
227
+
228
+ <div style={{ display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 2 }}>
229
+ {calDays.map((day, i) => {
230
+ if (!day) return <div key={`blank-${i}`} />;
231
+ const info = statsMap.get(day);
232
+ const airTimeMs = info?.airTimeMs ?? 0;
233
+ const burstCount = info?.burstCount ?? 0;
234
+ const isSelected = day === date;
235
+ const isToday = day === today;
236
+ const isFuture = day > today;
237
+ const intensity = airTimeMs > 0 && maxAirTimeMs > 0
238
+ ? Math.min(1, airTimeMs / maxAirTimeMs) : 0;
239
+ const dayNum = parseInt(day.split("-")[2]!, 10);
240
+
241
+ return (
242
+ <button
243
+ key={day}
244
+ type="button"
245
+ onClick={() => pickDay(day)}
246
+ disabled={isFuture}
247
+ onMouseEnter={(e) => {
248
+ if (isFuture) return;
249
+ const rect = e.currentTarget.getBoundingClientRect();
250
+ const parentRect = e.currentTarget.offsetParent?.getBoundingClientRect() ?? rect;
251
+ setHoverDay(day);
252
+ setHoverPos({
253
+ x: rect.left - parentRect.left + rect.width / 2,
254
+ y: rect.bottom - parentRect.top + 6,
255
+ });
256
+ }}
257
+ onMouseLeave={() => { setHoverDay(null); setHoverPos(null); }}
258
+ style={{
259
+ position: "relative",
260
+ width: 40, height: 40,
261
+ display: "flex", flexDirection: "column",
262
+ alignItems: "center", justifyContent: "center", gap: 1,
263
+ border: isSelected ? "2px solid var(--af-accent)"
264
+ : isToday ? "1px solid var(--af-text-tertiary)"
265
+ : "1px solid transparent",
266
+ borderRadius: 6,
267
+ background: intensity > 0
268
+ ? `rgba(45, 212, 191, ${0.08 + intensity * 0.35})`
269
+ : "transparent",
270
+ color: isFuture ? "var(--af-text-tertiary)"
271
+ : isSelected ? "var(--af-accent)"
272
+ : "var(--af-text)",
273
+ cursor: isFuture ? "not-allowed" : "pointer",
274
+ fontSize: 11,
275
+ fontWeight: isSelected ? 700 : 400,
276
+ fontFamily: "var(--font-mono)",
277
+ padding: 0,
278
+ opacity: isFuture ? 0.4 : 1,
279
+ }}
280
+ >
281
+ <span style={{ lineHeight: 1 }}>{dayNum}</span>
282
+ {airTimeMs > 0 && (
283
+ <span style={{
284
+ fontSize: 8,
285
+ color: isSelected ? "var(--af-accent)" : "var(--af-text-tertiary)",
286
+ lineHeight: 1, fontWeight: 600, marginTop: 2,
287
+ }}>{fmtShortDur(airTimeMs)}</span>
288
+ )}
289
+ {burstCount > 0 && (
290
+ <span style={{
291
+ position: "absolute", top: 3, right: 3,
292
+ width: 5, height: 5, borderRadius: "50%",
293
+ background: "rgba(167, 139, 250, 0.95)",
294
+ boxShadow: "0 0 0 1px var(--af-surface)",
295
+ }} />
296
+ )}
297
+ </button>
298
+ );
299
+ })}
300
+ </div>
301
+
302
+ <div style={{
303
+ display: "flex", alignItems: "center", justifyContent: "space-between",
304
+ gap: 10, marginTop: 10, paddingTop: 8,
305
+ borderTop: "1px solid var(--af-border-subtle)",
306
+ fontSize: 9, color: "var(--af-text-tertiary)",
307
+ }}>
308
+ <div style={{ display: "flex", alignItems: "center", gap: 5 }}>
309
+ <span>less</span>
310
+ <div style={{ display: "flex", gap: 2 }}>
311
+ {[0, 0.15, 0.3, 0.5, 0.8].map((v, i) => (
312
+ <span key={i} style={{
313
+ width: 10, height: 10, borderRadius: 2,
314
+ background: v === 0 ? "var(--af-border-subtle)" : `rgba(45, 212, 191, ${0.08 + v * 0.35})`,
315
+ }} />
316
+ ))}
317
+ </div>
318
+ <span>more active</span>
319
+ </div>
320
+ <div style={{ display: "flex", alignItems: "center", gap: 5 }} title="Days with at least one concurrency burst">
321
+ <span style={{ width: 5, height: 5, borderRadius: "50%", background: "rgba(167, 139, 250, 0.95)" }} />
322
+ parallel
323
+ </div>
324
+ </div>
325
+
326
+ {hoverDay && hoverPos && (() => {
327
+ const info = statsMap.get(hoverDay);
328
+ const sessions = info?.sessions ?? 0;
329
+ const airTimeMs = info?.airTimeMs ?? 0;
330
+ const parallelMs = info?.parallelMs ?? 0;
331
+ const burstCount = info?.burstCount ?? 0;
332
+ const peakConcurrency = info?.peakConcurrency ?? 0;
333
+ return (
334
+ <div style={{
335
+ position: "absolute",
336
+ left: Math.max(10, Math.min(hoverPos.x - 110, 290)),
337
+ top: hoverPos.y,
338
+ width: 220,
339
+ pointerEvents: "none",
340
+ background: "var(--af-surface-elevated)",
341
+ border: "1px solid var(--af-border-subtle)",
342
+ borderRadius: 8, padding: "9px 12px",
343
+ boxShadow: "0 6px 22px rgba(0,0,0,0.22)",
344
+ fontSize: 11, color: "var(--af-text)",
345
+ zIndex: 65, lineHeight: 1.5,
346
+ }}>
347
+ <div style={{ fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 11, marginBottom: 4 }}>
348
+ {hoverDay}
349
+ </div>
350
+ {sessions === 0 && airTimeMs === 0 && parallelMs === 0 ? (
351
+ <div style={{ color: "var(--af-text-tertiary)", fontSize: 10 }}>no activity</div>
352
+ ) : (
353
+ <>
354
+ <Stat label="sessions" value={String(sessions)} />
355
+ <Stat label="active time" value={airTimeMs > 0 ? fmtShortDur(airTimeMs) : "—"} />
356
+ {parallelMs > 0 && (
357
+ <>
358
+ <div style={{ marginTop: 4, paddingTop: 4, borderTop: "1px dashed var(--af-border-subtle)" }} />
359
+ <Stat label="parallel time" value={fmtShortDur(parallelMs)} />
360
+ <Stat label="peak concurrency" value={`×${peakConcurrency}`} accent />
361
+ <Stat label="bursts" value={String(burstCount)} />
362
+ </>
363
+ )}
364
+ </>
365
+ )}
366
+ </div>
367
+ );
368
+ })()}
369
+ </div>
370
+ )}
371
+ </div>
372
+ );
373
+ }
374
+
375
+ function Stat({ label, value, accent }: { label: string; value: string; accent?: boolean }) {
376
+ return (
377
+ <div style={{
378
+ display: "flex", justifyContent: "space-between",
379
+ color: "var(--af-text-secondary)", fontSize: 10,
380
+ }}>
381
+ <span>{label}</span>
382
+ <strong style={{ color: accent ? "rgba(167, 139, 250, 1)" : "var(--af-text)" }}>{value}</strong>
383
+ </div>
384
+ );
385
+ }
@@ -0,0 +1,180 @@
1
+ "use client";
2
+ import { useState, useCallback, useMemo, type ReactNode } from "react";
3
+ import { DayDigest as DayDigestRender } from "./day-digest";
4
+ import type { DayDigest as DayDigestType, Entry } from "@claude-lens/entries";
5
+
6
+ type Status = "idle" | "streaming" | "done" | "error";
7
+
8
+ export function DayDigestView({
9
+ initial, entries, date, aiEnabled,
10
+ }: {
11
+ initial: DayDigestType | null;
12
+ entries: Entry[];
13
+ date: string;
14
+ aiEnabled: boolean;
15
+ }) {
16
+ const [digest, setDigest] = useState<DayDigestType | null>(initial);
17
+ const [status, setStatus] = useState<Status>("idle");
18
+ const [progress, setProgress] = useState<string>("");
19
+
20
+ const generate = useCallback(async (force = false) => {
21
+ setStatus("streaming");
22
+ setProgress("Starting...");
23
+ const url = `/api/digest/day/${date}${force ? "?force=1" : ""}`;
24
+ const res = await fetch(url, { method: "POST" });
25
+ if (!res.ok || !res.body) {
26
+ setStatus("error");
27
+ setProgress(`Error ${res.status}`);
28
+ return;
29
+ }
30
+ const reader = res.body.getReader();
31
+ const decoder = new TextDecoder();
32
+ let buf = "";
33
+ while (true) {
34
+ const { done, value } = await reader.read();
35
+ if (done) break;
36
+ buf += decoder.decode(value, { stream: true });
37
+ const lines = buf.split("\n\n");
38
+ buf = lines.pop() ?? "";
39
+ for (const frame of lines) {
40
+ const dataLine = frame.split("\n").find(l => l.startsWith("data: "));
41
+ if (!dataLine) continue;
42
+ try {
43
+ const ev = JSON.parse(dataLine.slice(6));
44
+ if (ev.type === "status") setProgress(ev.text);
45
+ else if (ev.type === "entry") setProgress(`Enriching ${ev.index}/${ev.total}${ev.cost_usd ? ` · $${ev.cost_usd.toFixed(4)}` : ""}...`);
46
+ else if (ev.type === "progress") {
47
+ const sec = Math.round(ev.elapsed_ms / 1000);
48
+ const kb = (ev.bytes / 1024).toFixed(1);
49
+ setProgress(`Claude composing… ${ev.bytes.toLocaleString()} chars (${kb} KB · ${sec}s)`);
50
+ }
51
+ else if (ev.type === "digest") { setDigest(ev.digest); setProgress("Rendering..."); }
52
+ else if (ev.type === "saved") setProgress(`Saved.`);
53
+ else if (ev.type === "error") { setStatus("error"); setProgress(ev.message); return; }
54
+ } catch { /* skip */ }
55
+ }
56
+ }
57
+ setStatus("done");
58
+ setProgress("");
59
+ }, [date]);
60
+
61
+ const isStreaming = status === "streaming";
62
+
63
+ // A digest with a headline means synthesis ran — trust that as "fresh"
64
+ // even when a few entries are stuck in `pending` (e.g. rate-limited
65
+ // retries that didn't increment retry_count). Otherwise stuck entries
66
+ // would trap the user clicking "Generate" forever, since the pipeline
67
+ // short-circuits to the cached digest without re-enriching anyway.
68
+ // Users who want to recover stuck entries can use Re-roll narrative
69
+ // (which forces a fresh pipeline run that retries the pending capsules).
70
+ const narrativeIsFresh = !!digest?.headline;
71
+ const allTrivial = useMemo(() => {
72
+ if (entries.length === 0) return false;
73
+ return entries.every((e) => e.enrichment.status === "skipped_trivial");
74
+ }, [entries]);
75
+ const isEmpty = entries.length === 0;
76
+ const hasMissingWork = !isEmpty && !allTrivial && !narrativeIsFresh;
77
+
78
+ // Build the actions slot for the digest hero meta-row. Returns null
79
+ // when there's nothing actionable (empty / all-trivial days).
80
+ let actions: ReactNode = null;
81
+ if (!isEmpty && !allTrivial) {
82
+ if (hasMissingWork) {
83
+ actions = (
84
+ <button
85
+ onClick={() => generate(false)}
86
+ disabled={isStreaming}
87
+ style={{
88
+ padding: "4px 10px",
89
+ background: "var(--af-accent)",
90
+ color: "white",
91
+ border: "none",
92
+ borderRadius: 5,
93
+ cursor: isStreaming ? "default" : "pointer",
94
+ fontSize: 11,
95
+ fontWeight: 600,
96
+ opacity: isStreaming ? 0.6 : 1,
97
+ }}
98
+ >
99
+ {isStreaming ? "Generating..." : digest ? "Generate (catch up)" : "Generate digest"}
100
+ </button>
101
+ );
102
+ } else {
103
+ actions = (
104
+ <span
105
+ style={{
106
+ fontSize: 10,
107
+ color: "var(--af-text-tertiary)",
108
+ display: "inline-flex",
109
+ alignItems: "center",
110
+ gap: 6,
111
+ }}
112
+ >
113
+ ✓ Up to date
114
+ <button
115
+ onClick={() => generate(true)}
116
+ disabled={isStreaming}
117
+ title="Re-roll the narrative without re-enriching capsules"
118
+ style={{
119
+ padding: "2px 7px",
120
+ background: "transparent",
121
+ border: "1px solid var(--af-border-subtle)",
122
+ borderRadius: 4,
123
+ fontSize: 10,
124
+ color: "var(--af-text-secondary)",
125
+ cursor: isStreaming ? "default" : "pointer",
126
+ opacity: isStreaming ? 0.6 : 1,
127
+ }}
128
+ >
129
+ {isStreaming ? "..." : "Re-roll"}
130
+ </button>
131
+ </span>
132
+ );
133
+ }
134
+ if (progress) {
135
+ actions = (
136
+ <>
137
+ {actions}
138
+ <span style={{ fontSize: 10, color: "var(--af-text-tertiary)" }}>{progress}</span>
139
+ </>
140
+ );
141
+ }
142
+ }
143
+
144
+ if (digest) {
145
+ return <DayDigestRender digest={digest} entries={entries} aiEnabled={aiEnabled} actions={actions} />;
146
+ }
147
+
148
+ // No digest yet — render a slim row with whatever action applies, then
149
+ // a one-line empty-state hint.
150
+ return (
151
+ <>
152
+ {actions && (
153
+ <div
154
+ style={{
155
+ display: "flex",
156
+ gap: 10,
157
+ padding: "14px 40px 0",
158
+ alignItems: "center",
159
+ flexWrap: "wrap",
160
+ }}
161
+ >
162
+ {actions}
163
+ </div>
164
+ )}
165
+ {isEmpty ? (
166
+ <div style={{ padding: 28, textAlign: "center", color: "var(--af-text-tertiary)", fontSize: 13 }}>
167
+ No entries on this day.
168
+ </div>
169
+ ) : allTrivial ? (
170
+ <div style={{ padding: 28, textAlign: "center", color: "var(--af-text-tertiary)", fontSize: 13 }}>
171
+ 💤 Warm-up only — every session was under a minute. No narrative needed.
172
+ </div>
173
+ ) : (
174
+ <div style={{ padding: 28, textAlign: "center", color: "var(--af-text-secondary)", fontSize: 13 }}>
175
+ No digest generated yet — click Generate above.
176
+ </div>
177
+ )}
178
+ </>
179
+ );
180
+ }