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
@@ -1,647 +0,0 @@
1
- "use client";
2
-
3
- import React, { useCallback, useEffect, useRef, useState } from "react";
4
- import { useRouter } from "next/navigation";
5
- import {
6
- CheckCircle2, ChevronRight,
7
- Circle, Loader2, Square,
8
- } from "lucide-react";
9
- import { priorCalendarWeek } from "@claude-lens/parser";
10
- import { type ReportData } from "@/components/insight-report";
11
- import type { SavedReportMeta } from "@/lib/ai/saved-reports";
12
-
13
- type RangeChoice = {
14
- /** Stable id used for the generating-state label. For picker rows, use `week-YYYY-MM-DD`. */
15
- id: string;
16
- label: string;
17
- /** Body posted to /api/insights. */
18
- body: { range_type: "prior_week" | "4weeks_completed" | "week" | "4weeks" | "custom"; since?: string; until?: string };
19
- };
20
-
21
- type WeekRow = {
22
- iso_week: number;
23
- start: string;
24
- end: string;
25
- label: string;
26
- sessions: number;
27
- in_progress: boolean;
28
- saved_key: string | null;
29
- archetype_label?: string;
30
- sessions_used?: number;
31
- prs?: number;
32
- };
33
-
34
- type PhaseId = "data" | "analyst" | "compose";
35
- type Phase = { id: PhaseId; label: string; status: "pending" | "running" | "done"; steps: string[] };
36
-
37
- type InsightsEvent =
38
- | { type: "status"; phase: PhaseId; text: string }
39
- | { type: "report"; report: ReportData }
40
- | { type: "saved"; key: string; saved_at: string }
41
- | { type: "done" }
42
- | { type: "error"; message: string };
43
-
44
- type View =
45
- | { kind: "history" }
46
- | { kind: "generating"; rangeId: string; label: string; phases: Phase[]; elapsedMs: number }
47
- | { kind: "error"; message: string };
48
-
49
- const INITIAL_PHASES: Phase[] = [
50
- { id: "data", label: "Gather data", status: "pending", steps: [] },
51
- { id: "analyst", label: "Claude analyst", status: "pending", steps: [] },
52
- { id: "compose", label: "Compose report", status: "pending", steps: [] },
53
- ];
54
-
55
- export function InsightsView() {
56
- const router = useRouter();
57
- const [view, setView] = useState<View>({ kind: "history" });
58
- const abortRef = useRef<AbortController | null>(null);
59
- const startTimerRef = useRef<number | null>(null);
60
-
61
- const openSaved = useCallback((key: string) => {
62
- router.push(`/insights/${key}`);
63
- }, [router]);
64
-
65
- const generate = useCallback(async (range: RangeChoice) => {
66
- const phases: Phase[] = INITIAL_PHASES.map((p) => ({ ...p, steps: [] }));
67
- phases[0]!.status = "running";
68
- const startMs = Date.now();
69
- // Tick only when the whole-second reading changes — avoids re-rendering
70
- // the phase tree twice a second when nothing visible moved.
71
- startTimerRef.current = window.setInterval(() => {
72
- setView((v) => {
73
- if (v.kind !== "generating") return v;
74
- const next = Date.now() - startMs;
75
- if (Math.floor(next / 1000) === Math.floor(v.elapsedMs / 1000)) return v;
76
- return { ...v, elapsedMs: next };
77
- });
78
- }, 500);
79
- setView({ kind: "generating", rangeId: range.id, label: range.label, phases, elapsedMs: 0 });
80
-
81
- const ctrl = new AbortController();
82
- abortRef.current = ctrl;
83
-
84
- try {
85
- const res = await fetch("/api/insights", {
86
- method: "POST",
87
- headers: { "Content-Type": "application/json" },
88
- body: JSON.stringify(range.body),
89
- signal: ctrl.signal,
90
- });
91
- if (!res.ok || !res.body) {
92
- setView({ kind: "error", message: await res.text() || `HTTP ${res.status}` });
93
- return;
94
- }
95
- const reader = res.body.getReader();
96
- const decoder = new TextDecoder();
97
- let buffer = "";
98
- let done = false;
99
- let savedKey: string | null = null;
100
- let report: ReportData | null = null;
101
- while (!done) {
102
- const chunk = await reader.read();
103
- if (chunk.done) break;
104
- buffer += decoder.decode(chunk.value, { stream: true });
105
- const lines = buffer.split("\n");
106
- buffer = lines.pop()!;
107
- for (const line of lines) {
108
- if (!line.startsWith("data: ")) continue;
109
- const raw = line.slice(6).trim();
110
- if (!raw) continue;
111
- let data: InsightsEvent;
112
- try { data = JSON.parse(raw); } catch { continue; }
113
-
114
- if (data.type === "status") {
115
- const { phase: ph, text: txt } = data;
116
- setView((v) => {
117
- if (v.kind !== "generating") return v;
118
- const next = { ...v, phases: v.phases.map((p) => p.id === ph ? { ...p, steps: [...p.steps] } : p) };
119
- for (const phase of next.phases) {
120
- if (phase.id === ph) {
121
- phase.status = "running";
122
- const last = phase.steps[phase.steps.length - 1];
123
- if (last && isSupersedingUpdate(last, txt)) {
124
- phase.steps[phase.steps.length - 1] = txt;
125
- } else {
126
- phase.steps.push(txt);
127
- }
128
- } else if (phaseOrder(phase.id) < phaseOrder(ph)) {
129
- phase.status = "done";
130
- }
131
- }
132
- return next;
133
- });
134
- } else if (data.type === "report") {
135
- report = data.report;
136
- } else if (data.type === "saved") {
137
- savedKey = data.key;
138
- } else if (data.type === "done") {
139
- done = true;
140
- setView((v) => v.kind === "generating"
141
- ? { ...v, phases: v.phases.map((p) => ({ ...p, status: "done" as const })) }
142
- : v);
143
- } else if (data.type === "error") {
144
- setView({ kind: "error", message: data.message });
145
- return;
146
- }
147
- }
148
- }
149
- // Successful generation of a completed period lands on the report URL.
150
- // Successful generation of a completed period lands on its saved URL.
151
- // In-progress (unsaved) generations flip back to history — the picker
152
- // will re-fetch its row counts on mount.
153
- if (report && savedKey) {
154
- router.push(`/insights/${savedKey}`);
155
- } else {
156
- setView({ kind: "history" });
157
- }
158
- } catch (err) {
159
- if ((err as Error).name !== "AbortError") {
160
- setView({ kind: "error", message: (err as Error).message });
161
- }
162
- } finally {
163
- if (startTimerRef.current) { window.clearInterval(startTimerRef.current); startTimerRef.current = null; }
164
- abortRef.current = null;
165
- }
166
- }, [router]);
167
-
168
- const stop = () => abortRef.current?.abort();
169
-
170
- // ── Render ─────────────────────────────────────────────────────
171
- if (view.kind === "error") {
172
- return (
173
- <div style={errorStyle}>
174
- <strong>Error:</strong> {view.message}
175
- <button type="button" onClick={() => setView({ kind: "history" })} style={{ ...primaryBtn, marginLeft: 12 }}>Back</button>
176
- </div>
177
- );
178
- }
179
-
180
- if (view.kind === "generating") {
181
- return <GeneratingView view={view} onStop={stop} />;
182
- }
183
-
184
- return <HistoryView onGenerate={generate} onOpen={openSaved} />;
185
- }
186
-
187
- // ──────────────────────────────────────────────────────────────────
188
- // HISTORY VIEW
189
- // ──────────────────────────────────────────────────────────────────
190
-
191
- function HistoryView({
192
- onGenerate, onOpen,
193
- }: {
194
- onGenerate: (r: RangeChoice) => void;
195
- onOpen: (key: string) => void;
196
- }) {
197
- const [tab, setTab] = useState<"weeks" | "months">("weeks");
198
- const [weeks, setWeeks] = useState<WeekRow[] | null>(null);
199
- const [includeInProgress, setIncludeInProgress] = useState(false);
200
-
201
- useEffect(() => {
202
- void fetch("/api/insights/weeks-index?count=12")
203
- .then((r) => r.json())
204
- .then((j: { weeks: WeekRow[] }) => setWeeks(j.weeks))
205
- .catch(() => setWeeks([]));
206
- }, []);
207
-
208
- return (
209
- <div style={{ maxWidth: 820, margin: "0 auto", padding: "32px 40px 64px", display: "flex", flexDirection: "column", gap: 24 }}>
210
- <header style={{ display: "flex", flexDirection: "column", gap: 6 }}>
211
- <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-0.02em", margin: 0 }}>Insights</h1>
212
- <p style={{ fontSize: 13, color: "var(--af-text-secondary)", margin: 0, lineHeight: 1.55 }}>
213
- Pick a calendar week or a 4-week rollup. If a report already exists we'll open it instantly; otherwise
214
- Claude runs the pipeline (~1–3 min) and saves the result locally.
215
- </p>
216
- </header>
217
-
218
- {/* Tabs */}
219
- <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
220
- <div style={tabGroup}>
221
- {(["weeks", "months"] as const).map((t) => (
222
- <button key={t} type="button" onClick={() => setTab(t)}
223
- style={{
224
- ...tabBtn,
225
- background: tab === t ? "var(--af-accent)" : "transparent",
226
- color: tab === t ? "white" : "var(--af-text-secondary)",
227
- }}>
228
- {t === "weeks" ? "Weeks" : "Months"}
229
- </button>
230
- ))}
231
- </div>
232
- <label style={inProgressToggle}>
233
- <input type="checkbox" checked={includeInProgress} onChange={(e) => setIncludeInProgress(e.target.checked)} />
234
- <span>Include current {tab === "weeks" ? "week" : "month"}</span>
235
- </label>
236
- </div>
237
-
238
- {/* Weeks list or month rollup */}
239
- {tab === "weeks" ? (
240
- weeks === null ? (
241
- <div style={emptyHistoryStyle}>Loading weeks…</div>
242
- ) : (
243
- <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 4 }}>
244
- {weeks
245
- .filter((w) => includeInProgress || !w.in_progress)
246
- .map((w) => (
247
- <WeekPickerRow
248
- key={w.start}
249
- w={w}
250
- onView={() => w.saved_key && onOpen(w.saved_key)}
251
- onGenerate={() => onGenerate({
252
- id: `week-${w.start}`,
253
- label: `Week of ${w.label}`,
254
- body: { range_type: "custom", since: w.start, until: w.end },
255
- })}
256
- />
257
- ))}
258
- </ul>
259
- )
260
- ) : (
261
- <MonthsView onGenerate={onGenerate} onOpen={onOpen} includeInProgress={includeInProgress} />
262
- )}
263
- <Spin />
264
- </div>
265
- );
266
- }
267
-
268
- // ──────────────────────────────────────────────────────────────────
269
- // PICKER ROWS
270
- // ──────────────────────────────────────────────────────────────────
271
-
272
- function WeekPickerRow({
273
- w, onView, onGenerate,
274
- }: {
275
- w: WeekRow;
276
- onView: () => void;
277
- onGenerate: () => void;
278
- }) {
279
- const saved = !!w.saved_key;
280
- const empty = w.sessions === 0 && !w.in_progress;
281
- return (
282
- <li style={pickerRow(saved)}>
283
- <div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0, flex: 1 }}>
284
- <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
285
- <span style={{ fontSize: 13, fontWeight: 600, color: "var(--af-text)", letterSpacing: "-0.01em" }}>
286
- W{String(w.iso_week).padStart(2, "0")} · {w.label}
287
- </span>
288
- {w.in_progress && <span style={inProgressTag}>in progress</span>}
289
- </div>
290
- <div style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)", display: "flex", gap: 8, flexWrap: "wrap" }}>
291
- <span>{w.sessions} sess</span>
292
- {saved && w.archetype_label && (
293
- <>
294
- <span>·</span>
295
- <span style={{ color: "var(--af-accent)" }}>{w.archetype_label}</span>
296
- <span>·</span>
297
- <span>{w.sessions_used} used · {w.prs} PR</span>
298
- </>
299
- )}
300
- {empty && <><span>·</span><span>no data</span></>}
301
- </div>
302
- </div>
303
- {saved ? (
304
- <button type="button" onClick={onView} style={primaryBtn}>
305
- View report <ChevronRight size={13} />
306
- </button>
307
- ) : empty ? (
308
- <span style={disabledCTA}>no data</span>
309
- ) : w.in_progress ? (
310
- <button type="button" onClick={onGenerate} style={secondaryBtn} title="Current week is partial and won't be auto-saved">
311
- Generate anyway
312
- </button>
313
- ) : (
314
- <button type="button" onClick={onGenerate} style={secondaryBtn}>
315
- Generate
316
- </button>
317
- )}
318
- </li>
319
- );
320
- }
321
-
322
- type MonthRow = {
323
- year: number;
324
- month: number;
325
- start: string;
326
- end: string;
327
- label: string;
328
- sessions: number;
329
- in_progress: boolean;
330
- saved_key: string | null;
331
- archetype_label?: string;
332
- sessions_used?: number;
333
- prs?: number;
334
- };
335
-
336
- function MonthsView({
337
- onGenerate, onOpen, includeInProgress,
338
- }: {
339
- onGenerate: (r: RangeChoice) => void;
340
- onOpen: (key: string) => void;
341
- includeInProgress: boolean;
342
- }) {
343
- const [months, setMonths] = useState<MonthRow[] | null>(null);
344
-
345
- useEffect(() => {
346
- void fetch("/api/insights/months-index?count=6")
347
- .then((r) => r.json())
348
- .then((j: { months: MonthRow[] }) => setMonths(j.months))
349
- .catch(() => setMonths([]));
350
- }, []);
351
-
352
- if (months === null) return <div style={emptyHistoryStyle}>Loading months…</div>;
353
-
354
- return (
355
- <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 4 }}>
356
- {months
357
- .filter((m) => includeInProgress || !m.in_progress)
358
- .map((m) => <MonthPickerRow key={m.start} m={m}
359
- onView={() => m.saved_key && onOpen(m.saved_key)}
360
- onGenerate={() => onGenerate({
361
- id: `month-${m.start}`,
362
- label: m.label,
363
- body: { range_type: "custom", since: m.start, until: m.end },
364
- })}
365
- />)}
366
- </ul>
367
- );
368
- }
369
-
370
- function MonthPickerRow({
371
- m, onView, onGenerate,
372
- }: {
373
- m: MonthRow;
374
- onView: () => void;
375
- onGenerate: () => void;
376
- }) {
377
- const saved = !!m.saved_key;
378
- const empty = m.sessions === 0 && !m.in_progress;
379
- return (
380
- <li style={pickerRow(saved)}>
381
- <div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0, flex: 1 }}>
382
- <div style={{ display: "flex", alignItems: "center", gap: 8, minWidth: 0 }}>
383
- <span style={{ fontSize: 13, fontWeight: 600, color: "var(--af-text)", letterSpacing: "-0.01em" }}>
384
- {m.label}
385
- </span>
386
- {m.in_progress && <span style={inProgressTag}>in progress</span>}
387
- </div>
388
- <div style={{ fontSize: 11, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)", display: "flex", gap: 8, flexWrap: "wrap" }}>
389
- <span>{m.sessions} sess</span>
390
- {saved && m.archetype_label && (
391
- <>
392
- <span>·</span>
393
- <span style={{ color: "var(--af-accent)" }}>{m.archetype_label}</span>
394
- <span>·</span>
395
- <span>{m.sessions_used} used · {m.prs} PR</span>
396
- </>
397
- )}
398
- {empty && <><span>·</span><span>no data</span></>}
399
- </div>
400
- </div>
401
- {saved ? (
402
- <button type="button" onClick={onView} style={primaryBtn}>
403
- View report <ChevronRight size={13} />
404
- </button>
405
- ) : empty ? (
406
- <span style={disabledCTA}>no data</span>
407
- ) : m.in_progress ? (
408
- <button type="button" onClick={onGenerate} style={secondaryBtn} title="Current month is partial and won't be auto-saved">
409
- Generate anyway
410
- </button>
411
- ) : (
412
- <button type="button" onClick={onGenerate} style={secondaryBtn}>
413
- Generate
414
- </button>
415
- )}
416
- </li>
417
- );
418
- }
419
-
420
- // ──────────────────────────────────────────────────────────────────
421
- // GENERATING VIEW
422
- // ──────────────────────────────────────────────────────────────────
423
-
424
- function GeneratingView({
425
- view, onStop,
426
- }: {
427
- view: Extract<View, { kind: "generating" }>;
428
- onStop: () => void;
429
- }) {
430
- const elapsedS = Math.floor(view.elapsedMs / 1000);
431
- return (
432
- <div style={{ maxWidth: 720, margin: "0 auto", padding: "60px 40px", display: "flex", flexDirection: "column", gap: 24 }}>
433
- <header style={{ display: "flex", alignItems: "baseline", justifyContent: "space-between", gap: 12, flexWrap: "wrap" }}>
434
- <div>
435
- <div style={{ fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--af-text-tertiary)", fontWeight: 600 }}>
436
- Generating
437
- </div>
438
- <h1 style={{ fontSize: 22, fontWeight: 700, letterSpacing: "-0.02em", margin: "2px 0 0" }}>{view.label}</h1>
439
- </div>
440
- <button type="button" onClick={onStop} style={secondaryBtn}>
441
- <Square size={12} /> Stop
442
- </button>
443
- </header>
444
-
445
- {/* Phase summary strip */}
446
- <div style={phaseStripStyle}>
447
- {view.phases.map((p, i) => (
448
- <div key={p.id} style={phaseChipStyle(p.status)}>
449
- <PhaseIcon status={p.status} />
450
- <span style={{ fontSize: 11, fontWeight: 600, letterSpacing: "0.02em" }}>
451
- {i + 1}. {p.label}
452
- </span>
453
- </div>
454
- ))}
455
- <div style={{ marginLeft: "auto", fontSize: 11, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)", display: "inline-flex", alignItems: "center", gap: 6 }}>
456
- <Loader2 size={11} className="af-spin" /> {elapsedS}s elapsed
457
- </div>
458
- </div>
459
-
460
- {/* Active phase detail */}
461
- {view.phases.map((p) => p.steps.length > 0 ? (
462
- <div key={p.id} style={phaseDetailStyle(p.status)}>
463
- <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
464
- <PhaseIcon status={p.status} />
465
- <span style={{ fontSize: 12, fontWeight: 600, color: p.status === "done" ? "var(--af-text-secondary)" : "var(--af-text)" }}>
466
- {p.label}
467
- </span>
468
- </div>
469
- <ol style={stepsListStyle}>
470
- {p.steps.map((s, i) => (
471
- <li key={i} style={{
472
- ...stepItemStyle,
473
- opacity: i === p.steps.length - 1 && p.status === "running" ? 1 : 0.65,
474
- }}>
475
- <span style={{ color: "var(--af-accent)", fontSize: 10, width: 10 }}>
476
- {i === p.steps.length - 1 && p.status === "running" ? "•" : "✓"}
477
- </span>
478
- {s}
479
- </li>
480
- ))}
481
- </ol>
482
- </div>
483
- ) : null)}
484
-
485
- <Spin />
486
- </div>
487
- );
488
- }
489
-
490
- // ──────────────────────────────────────────────────────────────────
491
- // Helpers
492
- // ──────────────────────────────────────────────────────────────────
493
-
494
- function phaseOrder(p: PhaseId): number {
495
- return { data: 0, analyst: 1, compose: 2 }[p];
496
- }
497
-
498
- function isSupersedingUpdate(prev: string, next: string): boolean {
499
- // e.g. "Built 7/26 capsules" → "Built 14/26 capsules" supersedes
500
- // "Claude composing… 500 chars" → "Claude composing… 1500 chars" supersedes
501
- const prefixes = ["Built ", "Claude composing", "Aggregating ", "Sending "];
502
- return prefixes.some((p) => prev.startsWith(p) && next.startsWith(p));
503
- }
504
-
505
- function isoDay(d: Date): string {
506
- const y = d.getFullYear();
507
- const m = String(d.getMonth() + 1).padStart(2, "0");
508
- const day = String(d.getDate()).padStart(2, "0");
509
- return `${y}-${m}-${day}`;
510
- }
511
-
512
- function fmtDate(d: Date): string {
513
- return d.toLocaleDateString("en-US", { month: "short", day: "numeric" });
514
- }
515
-
516
- // ──────────────────────────────────────────────────────────────────
517
- // Sub-components
518
- // ──────────────────────────────────────────────────────────────────
519
-
520
- function PhaseIcon({ status }: { status: Phase["status"] }) {
521
- if (status === "done") return <CheckCircle2 size={14} color="var(--af-accent)" />;
522
- if (status === "running") return <Loader2 size={14} color="var(--af-accent)" className="af-spin" />;
523
- return <Circle size={14} color="var(--af-text-tertiary)" />;
524
- }
525
-
526
- function Spin() {
527
- return (
528
- <style>{`
529
- @keyframes af-spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
530
- .af-spin { animation: af-spin 0.9s linear infinite; }
531
- `}</style>
532
- );
533
- }
534
-
535
- // ──────────────────────────────────────────────────────────────────
536
- // Styles
537
- // ──────────────────────────────────────────────────────────────────
538
-
539
- const centerStyle: React.CSSProperties = {
540
- padding: "80px 40px", textAlign: "center",
541
- fontSize: 13, color: "var(--af-text-secondary)",
542
- display: "inline-flex", alignItems: "center", gap: 8, justifyContent: "center", width: "100%",
543
- };
544
-
545
- const errorStyle: React.CSSProperties = {
546
- maxWidth: 720, margin: "60px auto", padding: "14px 18px", borderRadius: 10,
547
- border: "1px solid var(--af-border)", background: "var(--af-surface)",
548
- fontSize: 13, color: "var(--af-text)",
549
- };
550
-
551
- const primaryBtn: React.CSSProperties = {
552
- display: "inline-flex", alignItems: "center", gap: 6, padding: "8px 14px",
553
- border: "1px solid var(--af-accent)", borderRadius: 8,
554
- background: "var(--af-accent)", color: "white",
555
- fontSize: 12, fontWeight: 600, cursor: "pointer",
556
- };
557
-
558
- const secondaryBtn: React.CSSProperties = {
559
- display: "inline-flex", alignItems: "center", gap: 6, padding: "7px 12px",
560
- border: "1px solid var(--af-border)", borderRadius: 8,
561
- background: "var(--af-surface)", color: "var(--af-text)",
562
- fontSize: 12, fontWeight: 500, cursor: "pointer",
563
- };
564
-
565
- const tabGroup: React.CSSProperties = {
566
- display: "inline-flex", gap: 3, border: "1px solid var(--af-border)", borderRadius: 8, padding: 2,
567
- };
568
-
569
- const tabBtn: React.CSSProperties = {
570
- padding: "5px 14px", fontSize: 12, fontWeight: 600,
571
- border: "none", borderRadius: 6, cursor: "pointer",
572
- };
573
-
574
- const inProgressToggle: React.CSSProperties = {
575
- display: "inline-flex", alignItems: "center", gap: 6,
576
- fontSize: 11.5, color: "var(--af-text-secondary)",
577
- cursor: "pointer", marginLeft: "auto",
578
- };
579
-
580
- function pickerRow(saved: boolean): React.CSSProperties {
581
- return {
582
- display: "flex", alignItems: "center", justifyContent: "space-between", gap: 14,
583
- padding: "12px 16px", borderRadius: 10,
584
- border: `1px solid ${saved ? "color-mix(in srgb, var(--af-accent) 24%, var(--af-border))" : "var(--af-border-subtle)"}`,
585
- background: saved ? "color-mix(in srgb, var(--af-accent) 6%, var(--af-surface))" : "var(--af-surface)",
586
- };
587
- }
588
-
589
- const disabledCTA: React.CSSProperties = {
590
- fontSize: 11.5, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)",
591
- padding: "7px 12px",
592
- };
593
-
594
- const topNavStyle: React.CSSProperties = {
595
- maxWidth: 980, margin: "0 auto", padding: "16px 44px 0",
596
- display: "flex", alignItems: "center", gap: 12,
597
- };
598
-
599
- const inProgressTag: React.CSSProperties = {
600
- fontSize: 10, fontWeight: 500, padding: "2px 6px", borderRadius: 4,
601
- background: "color-mix(in srgb, #f5b445 18%, transparent)", color: "#c08a1f",
602
- marginLeft: 8, letterSpacing: "0.02em",
603
- };
604
-
605
- const emptyHistoryStyle: React.CSSProperties = {
606
- padding: "20px 18px", borderRadius: 10,
607
- border: "1px dashed var(--af-border)", background: "var(--af-surface)",
608
- fontSize: 12.5, color: "var(--af-text-tertiary)", lineHeight: 1.55,
609
- };
610
-
611
- const phaseStripStyle: React.CSSProperties = {
612
- display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap",
613
- padding: "10px 14px", borderRadius: 10,
614
- border: "1px solid var(--af-border-subtle)", background: "var(--af-surface)",
615
- };
616
-
617
- function phaseChipStyle(status: Phase["status"]): React.CSSProperties {
618
- return {
619
- display: "inline-flex", alignItems: "center", gap: 6,
620
- padding: "4px 10px", borderRadius: 999,
621
- background: status === "running"
622
- ? "color-mix(in srgb, var(--af-accent) 16%, transparent)"
623
- : status === "done"
624
- ? "color-mix(in srgb, var(--af-accent) 9%, transparent)"
625
- : "var(--af-surface-raised)",
626
- color: status === "pending" ? "var(--af-text-tertiary)" : "var(--af-text)",
627
- };
628
- }
629
-
630
- function phaseDetailStyle(status: Phase["status"]): React.CSSProperties {
631
- return {
632
- padding: "14px 18px", borderRadius: 10,
633
- border: "1px solid var(--af-border-subtle)",
634
- background: status === "running" ? "var(--af-surface)" : "transparent",
635
- opacity: status === "pending" ? 0.6 : 1,
636
- };
637
- }
638
-
639
- const stepsListStyle: React.CSSProperties = {
640
- listStyle: "none", padding: 0, margin: 0,
641
- display: "flex", flexDirection: "column", gap: 4,
642
- fontFamily: "var(--font-mono)", fontSize: 12, color: "var(--af-text-secondary)",
643
- };
644
-
645
- const stepItemStyle: React.CSSProperties = {
646
- display: "flex", alignItems: "baseline", gap: 8,
647
- };