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,1031 +0,0 @@
1
- "use client";
2
-
3
- import { useState } from "react";
4
- import {
5
- ArrowRight,
6
- BrainCircuit,
7
- Check,
8
- ClipboardList,
9
- Compass,
10
- Download,
11
- FileText,
12
- GitCommit,
13
- Layers3,
14
- Lightbulb,
15
- Network,
16
- Repeat,
17
- Rocket,
18
- Share2,
19
- Sparkles,
20
- TrendingDown,
21
- TrendingUp,
22
- Users,
23
- Zap,
24
- } from "lucide-react";
25
-
26
- const ICON_MAP = {
27
- BrainCircuit, ClipboardList, Compass, GitCommit, Layers3, Network, Repeat,
28
- Rocket, Sparkles, TrendingDown, TrendingUp, Users, Zap,
29
- } as const;
30
- export type IconKey = keyof typeof ICON_MAP;
31
-
32
- // ──────────────────────────────────────────────────────────────────
33
- // Types
34
- // ──────────────────────────────────────────────────────────────────
35
-
36
- export type ReportData = {
37
- period_label: string; // "Week of Apr 14 — Apr 20"
38
- period_sublabel: string; // "Calendar week · in progress"
39
- range_type: "week" | "4weeks" | "month" | "custom";
40
-
41
- archetype: {
42
- label: string; // "Orchestration conductor"
43
- icon: IconKey;
44
- tagline: string; // "deep-dive + heavy subagent usage"
45
- why: string; // 1 supporting sentence
46
- vs_usual?: string; // "More orchestrated than your usual baseline"
47
- };
48
-
49
- top_skills: { name: string; count: number; vs_prior?: number }[];
50
-
51
- // Daily day-by-day strip (Mon → Sun when range=week)
52
- days: {
53
- day_name: string; // "Mon"
54
- date_label: string; // "Apr 14"
55
- agent_minutes: number;
56
- sessions: number;
57
- concurrency_peak: number; // ×N parallel
58
- has_cross_project: boolean;
59
- plan_util_pct: number; // 0..100
60
- is_partial?: boolean; // future / in-progress day
61
- }[];
62
-
63
- theme_headline: string; // "Fleetlens Team Edition sprint"
64
-
65
- projects: {
66
- name: string;
67
- display_name: string;
68
- agent_minutes: number;
69
- share_pct: number;
70
- prs: number;
71
- commits: number;
72
- }[];
73
-
74
- shipped: {
75
- title: string;
76
- project: string;
77
- duration_label: string;
78
- commits: number;
79
- subagents: number;
80
- flags: string[];
81
- summary: string;
82
- }[];
83
-
84
- patterns: {
85
- icon: IconKey;
86
- title: string;
87
- stat: string;
88
- note: string;
89
- }[];
90
-
91
- concurrency: {
92
- multi_agent_days: number;
93
- peak: number;
94
- peak_day: string;
95
- cross_project_days: number;
96
- insight: string;
97
- suggestion: string;
98
- };
99
-
100
- outliers: { label: string; detail: string; note: string }[];
101
-
102
- suggestion_headline: string;
103
- suggestion_body: string;
104
-
105
- prior_weeks: {
106
- period_label: string;
107
- archetype: string;
108
- sessions: number;
109
- prs: number;
110
- subagents: number;
111
- agent_minutes: number;
112
- }[];
113
-
114
- saved_reports: { id: string; period_label: string; note?: string; current?: boolean }[];
115
-
116
- meta: {
117
- generated_at: string;
118
- sessions_total: number;
119
- sessions_used: number;
120
- trivial_dropped: number;
121
- model: string;
122
- pipeline_ms: number;
123
- context_kb: number;
124
- };
125
- };
126
-
127
- const FLAG_TONE: Record<string, { label: string; tone: "good" | "warn" | "danger" | "neutral" }> = {
128
- fast_ship: { label: "fast ship", tone: "good" },
129
- plan_used: { label: "plan used", tone: "good" },
130
- orchestrated: { label: "orchestrated", tone: "good" },
131
- long_autonomous: { label: "long autonomous", tone: "neutral" },
132
- loop_suspected: { label: "loop suspected", tone: "warn" },
133
- high_errors: { label: "high errors", tone: "warn" },
134
- interrupt_heavy: { label: "interrupt-heavy", tone: "danger" },
135
- };
136
-
137
- // ──────────────────────────────────────────────────────────────────
138
- // Top-level component
139
- // ──────────────────────────────────────────────────────────────────
140
-
141
- export function InsightReport({ data, savedKey }: { data: ReportData; savedKey?: string | null }) {
142
- return (
143
- <>
144
- <PrintStyles />
145
- <div className="report-root" style={rootStyle}>
146
- <Toolbar data={data} savedKey={savedKey ?? null} />
147
-
148
- {/* Section 1 · ARCHETYPE */}
149
- <Section index={1} title="Who you were" kicker="Your working style, distilled" anchor="archetype">
150
- <ArchetypeHero data={data} />
151
- <SkillsStrip skills={data.top_skills} />
152
- </Section>
153
-
154
- {/* Section 2 · THE WEEK AT A GLANCE */}
155
- <Section index={2} title="The week at a glance" kicker={`${data.period_label} · ${data.theme_headline}`} anchor="glance">
156
- <DayStrip days={data.days} />
157
- <PlanUtilRow days={data.days} />
158
- </Section>
159
-
160
- {/* Section 3 · WHERE YOUR TIME WENT */}
161
- <Section index={3} title="Where your time went" kicker="Projects and shipped work" anchor="time">
162
- <ProjectBars projects={data.projects} />
163
- <ShippedList items={data.shipped} />
164
- </Section>
165
-
166
- {/* Section 4 · HOW YOU WORKED */}
167
- <Section index={4} title="How you worked" kicker="Patterns, concurrency, outliers" anchor="how">
168
- <PatternsGrid patterns={data.patterns} />
169
- <ConcurrencyBlock c={data.concurrency} />
170
- <OutliersRow outliers={data.outliers} />
171
- </Section>
172
-
173
- {/* Section 5 · WHAT TO TRY */}
174
- <Section index={5} title="What to try next" kicker="One experiment, grounded in what we saw" anchor="next">
175
- <SuggestionBlock headline={data.suggestion_headline} body={data.suggestion_body} />
176
- <PriorWeeksStrip weeks={data.prior_weeks} />
177
- </Section>
178
-
179
- <MetaFooter meta={data.meta} />
180
- </div>
181
- </>
182
- );
183
- }
184
-
185
- // ──────────────────────────────────────────────────────────────────
186
- // Sub-components
187
- // ──────────────────────────────────────────────────────────────────
188
-
189
- function Toolbar({ data, savedKey }: { data: ReportData; savedKey: string | null }) {
190
- const [copied, setCopied] = useState(false);
191
- const [pdfState, setPdfState] = useState<"idle" | "rendering" | "error">("idle");
192
-
193
- const onCopyMd = async () => {
194
- try {
195
- await navigator.clipboard.writeText(renderReportAsMarkdown(data));
196
- setCopied(true);
197
- window.setTimeout(() => setCopied(false), 1500);
198
- } catch { /* clipboard may be unavailable in insecure contexts */ }
199
- };
200
-
201
- const onSavePdf = async () => {
202
- // For unsaved (in-progress) reports, fall back to window.print() —
203
- // the backend can only render reports that exist on disk.
204
- if (!savedKey) { window.print(); return; }
205
- setPdfState("rendering");
206
- try {
207
- const res = await fetch(`/api/insights/pdf/${savedKey}`);
208
- if (!res.ok) { setPdfState("error"); window.setTimeout(() => setPdfState("idle"), 2500); return; }
209
- const blob = await res.blob();
210
- const url = URL.createObjectURL(blob);
211
- const a = document.createElement("a");
212
- a.href = url;
213
- a.download = `${savedKey}.pdf`;
214
- document.body.appendChild(a);
215
- a.click();
216
- a.remove();
217
- URL.revokeObjectURL(url);
218
- setPdfState("idle");
219
- } catch {
220
- setPdfState("error");
221
- window.setTimeout(() => setPdfState("idle"), 2500);
222
- }
223
- };
224
-
225
- return (
226
- <div className="no-print" style={toolbarStyle}>
227
- <div style={{ display: "flex", flexDirection: "column", gap: 2, marginRight: "auto" }}>
228
- <div style={{ fontSize: 11, letterSpacing: "0.08em", textTransform: "uppercase", color: "var(--af-text-tertiary)", fontWeight: 600 }}>
229
- Insight report
230
- </div>
231
- <div style={{ fontSize: 20, fontWeight: 700, letterSpacing: "-0.02em", color: "var(--af-text)" }}>
232
- {data.period_label}
233
- </div>
234
- <div style={{ fontSize: 12, color: "var(--af-text-secondary)" }}>{data.period_sublabel}</div>
235
- </div>
236
- <button type="button" style={secondaryBtn} onClick={onCopyMd}>
237
- {copied ? <Check size={12} /> : <Share2 size={12} />} {copied ? "Copied" : "Copy MD"}
238
- </button>
239
- <button type="button" style={primaryBtn} onClick={onSavePdf} disabled={pdfState === "rendering"}>
240
- <Download size={12} />{" "}
241
- {pdfState === "rendering" ? "Rendering…" : pdfState === "error" ? "Retry" : "Save as PDF"}
242
- </button>
243
- </div>
244
- );
245
- }
246
-
247
- function renderReportAsMarkdown(d: ReportData): string {
248
- const lines: string[] = [];
249
- lines.push(`# Insight report — ${d.period_label}`);
250
- lines.push(`*${d.period_sublabel}*`);
251
- lines.push("");
252
- lines.push(`## ${d.archetype.label}`);
253
- lines.push(`*${d.archetype.tagline}*`);
254
- lines.push("");
255
- lines.push(d.archetype.why);
256
- if (d.archetype.vs_usual) lines.push(`\n*vs your usual:* ${d.archetype.vs_usual}`);
257
- lines.push("");
258
- if (d.top_skills.length) {
259
- lines.push("**Skills leaned on:** " + d.top_skills.map((s) => `${s.name} (${s.count}×)`).join(", "));
260
- lines.push("");
261
- }
262
- lines.push(`## The week at a glance`);
263
- lines.push(`*${d.theme_headline}*`);
264
- lines.push("");
265
- for (const day of d.days) {
266
- const conc = day.concurrency_peak > 1 ? ` · ×${day.concurrency_peak}${day.has_cross_project ? " cross-project" : ""}` : "";
267
- const util = day.plan_util_pct > 0 ? ` · ${day.plan_util_pct}% plan` : "";
268
- lines.push(`- **${day.day_name} ${day.date_label}** — ${day.agent_minutes}m${conc}${util}`);
269
- }
270
- lines.push("");
271
- lines.push(`## Projects`);
272
- for (const p of d.projects) lines.push(`- ${p.display_name} — ${p.share_pct}% (${p.prs} PR, ${p.commits} commits)`);
273
- lines.push("");
274
- if (d.shipped.length) {
275
- lines.push(`## Shipped (${d.shipped.length})`);
276
- for (const s of d.shipped) {
277
- lines.push(`### ${s.title}`);
278
- lines.push(`${s.project} · ${s.duration_label} · ${s.commits} commits${s.subagents ? ` · ${s.subagents} subagents` : ""}`);
279
- if (s.flags.length) lines.push(`Flags: ${s.flags.join(", ")}`);
280
- lines.push("");
281
- if (s.summary) { lines.push(s.summary); lines.push(""); }
282
- }
283
- }
284
- if (d.patterns.length) {
285
- lines.push(`## Patterns`);
286
- for (const p of d.patterns) lines.push(`- **${p.title}** (${p.stat}) — ${p.note}`);
287
- lines.push("");
288
- }
289
- lines.push(`## Concurrency`);
290
- lines.push(`Peak ×${d.concurrency.peak} on ${d.concurrency.peak_day} · ${d.concurrency.multi_agent_days} multi-agent days · ${d.concurrency.cross_project_days} cross-project days`);
291
- if (d.concurrency.insight) { lines.push(""); lines.push(d.concurrency.insight); }
292
- if (d.concurrency.suggestion) { lines.push(""); lines.push(`→ ${d.concurrency.suggestion}`); }
293
- lines.push("");
294
- if (d.outliers.length) {
295
- lines.push(`## Outliers`);
296
- for (const o of d.outliers) lines.push(`- **${o.label}** — ${o.detail} · ${o.note}`);
297
- lines.push("");
298
- }
299
- lines.push(`## What to try next`);
300
- lines.push(`**${d.suggestion_headline}**`);
301
- lines.push("");
302
- lines.push(d.suggestion_body);
303
- lines.push("");
304
- lines.push(`---`);
305
- lines.push(`*${d.meta.sessions_used} substantive sessions · ${d.meta.model} · generated ${d.meta.generated_at}*`);
306
- return lines.join("\n");
307
- }
308
-
309
- function Section({
310
- index, title, kicker, anchor, children,
311
- }: { index: number; title: string; kicker: string; anchor: string; children: React.ReactNode }) {
312
- return (
313
- <section id={anchor} style={sectionStyle}>
314
- <div style={sectionHeaderStyle}>
315
- <div style={sectionIndex}>{String(index).padStart(2, "0")}</div>
316
- <div style={{ display: "flex", flexDirection: "column" }}>
317
- <div style={sectionTitle}>{title}</div>
318
- <div style={sectionKicker}>{kicker}</div>
319
- </div>
320
- </div>
321
- <div style={{ display: "flex", flexDirection: "column", gap: 18 }}>
322
- {children}
323
- </div>
324
- </section>
325
- );
326
- }
327
-
328
- function ArchetypeHero({ data }: { data: ReportData }) {
329
- const Icon = ICON_MAP[data.archetype.icon] ?? Sparkles;
330
- return (
331
- <div style={archetypeHeroStyle}>
332
- <div style={{ display: "flex", alignItems: "center", gap: 14 }}>
333
- <div style={archetypeIconWrap}><Icon size={22} color="var(--af-accent)" /></div>
334
- <div>
335
- <div style={archetypeEyebrow}>You were a</div>
336
- <h2 style={archetypeLabel}>{data.archetype.label}</h2>
337
- <div style={archetypeTagline}>{data.archetype.tagline}</div>
338
- </div>
339
- </div>
340
- <p style={archetypeWhy}>{data.archetype.why}</p>
341
- {data.archetype.vs_usual && (
342
- <div style={archetypeVsUsual}>
343
- <Compass size={12} style={{ verticalAlign: -2 }} /> <span style={{ opacity: 0.75, marginLeft: 2 }}>vs your usual:</span>{" "}
344
- <strong style={{ color: "var(--af-text)" }}>{data.archetype.vs_usual}</strong>
345
- </div>
346
- )}
347
- </div>
348
- );
349
- }
350
-
351
- function SkillsStrip({ skills }: { skills: ReportData["top_skills"] }) {
352
- const max = Math.max(1, ...skills.map((s) => s.count));
353
- return (
354
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
355
- <div style={miniSectionTitle}><Sparkles size={12} color="var(--af-accent)" style={{ marginRight: 6, verticalAlign: -1 }} />Skills you leaned on</div>
356
- <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
357
- {skills.map((s) => (
358
- <div key={s.name} style={skillRow}>
359
- <div style={skillName}>{s.name}</div>
360
- <div style={skillBarWrap}>
361
- <div style={{ ...skillBar, width: `${(s.count / max) * 100}%` }} />
362
- </div>
363
- <div style={skillCount}>
364
- {s.count}×
365
- {typeof s.vs_prior === "number" && s.vs_prior !== 0 && (
366
- <span style={{ color: s.vs_prior > 0 ? "var(--af-accent)" : "var(--af-text-tertiary)", marginLeft: 6, fontSize: 10 }}>
367
- {s.vs_prior > 0 ? "+" : ""}{s.vs_prior}
368
- </span>
369
- )}
370
- </div>
371
- </div>
372
- ))}
373
- </div>
374
- </div>
375
- );
376
- }
377
-
378
- function DayStrip({ days }: { days: ReportData["days"] }) {
379
- const max = Math.max(1, ...days.map((d) => d.agent_minutes));
380
- return (
381
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
382
- <div style={miniSectionTitle}><Layers3 size={12} color="var(--af-accent)" style={{ marginRight: 6, verticalAlign: -1 }} />Daily activity</div>
383
- <div style={dayStripStyle}>
384
- {days.map((d) => {
385
- const heightPct = max === 0 ? 0 : (d.agent_minutes / max) * 100;
386
- const empty = d.agent_minutes === 0;
387
- return (
388
- <div key={d.day_name} style={dayCol}>
389
- <div style={dayBarWrap}>
390
- <div
391
- style={{
392
- ...dayBar,
393
- height: `${heightPct}%`,
394
- opacity: empty ? 0 : 1,
395
- background: d.has_cross_project
396
- ? "linear-gradient(180deg, #a78bfa 0%, var(--af-accent) 100%)"
397
- : "var(--af-accent)",
398
- }}
399
- />
400
- </div>
401
- <div style={dayConcurrency}>
402
- {empty ? (
403
- <span style={{ opacity: 0.3 }}>—</span>
404
- ) : d.concurrency_peak > 1 ? (
405
- <span style={{ color: d.has_cross_project ? "#a78bfa" : "var(--af-accent)", fontWeight: 600 }}>
406
- ×{d.concurrency_peak}
407
- </span>
408
- ) : (
409
- <span style={{ opacity: 0.45 }}>×1</span>
410
- )}
411
- </div>
412
- <div style={dayMinutes}>{empty ? "—" : `${d.agent_minutes}m`}</div>
413
- <div style={dayName}>{d.day_name}</div>
414
- <div style={dayDate}>{d.date_label}</div>
415
- </div>
416
- );
417
- })}
418
- </div>
419
- <div style={dayLegend}>
420
- <span><span style={{ ...legendDot, background: "var(--af-accent)" }} /> same-project</span>
421
- <span><span style={{ ...legendDot, background: "#a78bfa" }} /> cross-project</span>
422
- <span style={{ opacity: 0.6 }}>× = concurrency peak</span>
423
- </div>
424
- </div>
425
- );
426
- }
427
-
428
- function PlanUtilRow({ days }: { days: ReportData["days"] }) {
429
- return (
430
- <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
431
- <div style={miniSectionTitle}>License utilization (by day)</div>
432
- <div style={planRow}>
433
- {days.map((d) => {
434
- const empty = d.plan_util_pct === 0;
435
- const tone = d.plan_util_pct >= 80 ? "#c08a1f" : d.plan_util_pct >= 50 ? "var(--af-accent)" : "var(--af-text-tertiary)";
436
- return (
437
- <div key={d.day_name} style={planCell}>
438
- <div style={{ ...planBar, background: "var(--af-border-subtle)" }}>
439
- <div style={{ width: `${d.plan_util_pct}%`, height: "100%", background: tone, borderRadius: 3 }} />
440
- </div>
441
- <div style={{ fontSize: 10, color: empty ? "var(--af-text-tertiary)" : tone, fontWeight: empty ? 400 : 600, fontFamily: "var(--font-mono)" }}>
442
- {empty ? "—" : `${d.plan_util_pct}%`}
443
- </div>
444
- </div>
445
- );
446
- })}
447
- </div>
448
- </div>
449
- );
450
- }
451
-
452
- function ProjectBars({ projects }: { projects: ReportData["projects"] }) {
453
- return (
454
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
455
- <div style={miniSectionTitle}><Users size={12} color="var(--af-accent)" style={{ marginRight: 6, verticalAlign: -1 }} />Project time share</div>
456
- <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
457
- {projects.map((p) => (
458
- <div key={p.name} style={projectRow}>
459
- <div style={projectName}>{p.display_name}</div>
460
- <div style={projectBarWrap}>
461
- <div style={{ ...projectBar, width: `${p.share_pct}%` }} />
462
- </div>
463
- <div style={projectMeta}>
464
- <span style={{ color: "var(--af-text)", fontWeight: 600, fontVariantNumeric: "tabular-nums" }}>{p.share_pct}%</span>
465
- <span style={{ opacity: 0.6, marginLeft: 8 }}>
466
- {Math.round(p.agent_minutes / 60 * 10) / 10}h · {p.prs} PR · {p.commits} commits
467
- </span>
468
- </div>
469
- </div>
470
- ))}
471
- </div>
472
- </div>
473
- );
474
- }
475
-
476
- function ShippedList({ items }: { items: ReportData["shipped"] }) {
477
- return (
478
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
479
- <div style={miniSectionTitle}><Rocket size={12} color="var(--af-accent)" style={{ marginRight: 6, verticalAlign: -1 }} />What shipped ({items.length})</div>
480
- <div style={shippedList}>
481
- {items.map((s) => (
482
- <div key={s.title} style={shippedRow}>
483
- <div style={shippedLeft}>
484
- <div style={shippedTitleStyle}>{s.title}</div>
485
- <div style={shippedSummary}>{s.summary}</div>
486
- </div>
487
- <div style={shippedRight}>
488
- <div style={shippedMetaLine}>
489
- <span style={metaChip}>{s.project}</span>
490
- <span style={metaChip}>{s.duration_label}</span>
491
- <span style={metaChip}>{s.commits} commits</span>
492
- {s.subagents > 0 && <span style={metaChip}>{s.subagents} subagents</span>}
493
- </div>
494
- <div style={shippedFlags}>
495
- {s.flags.map((f) => <FlagPill key={f} flag={f} />)}
496
- </div>
497
- </div>
498
- </div>
499
- ))}
500
- </div>
501
- </div>
502
- );
503
- }
504
-
505
- function PatternsGrid({ patterns }: { patterns: ReportData["patterns"] }) {
506
- return (
507
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
508
- <div style={miniSectionTitle}><BrainCircuit size={12} color="var(--af-accent)" style={{ marginRight: 6, verticalAlign: -1 }} />Patterns worth naming</div>
509
- <div style={patternsGridStyle}>
510
- {patterns.map((p) => {
511
- const Icon = ICON_MAP[p.icon] ?? Zap;
512
- return (
513
- <div key={p.title} style={patternCardStyle}>
514
- <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 6 }}>
515
- <div style={patternIconWrap}><Icon size={14} color="var(--af-accent)" /></div>
516
- <div style={patternTitle}>{p.title}</div>
517
- </div>
518
- <div style={patternStat}>{p.stat}</div>
519
- <div style={patternNote}>{p.note}</div>
520
- </div>
521
- );
522
- })}
523
- </div>
524
- </div>
525
- );
526
- }
527
-
528
- function ConcurrencyBlock({ c }: { c: ReportData["concurrency"] }) {
529
- return (
530
- <div style={concurrencyCard}>
531
- <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 4 }}>
532
- <div style={{ ...patternIconWrap, background: "color-mix(in srgb, #a78bfa 18%, transparent)" }}>
533
- <Network size={14} color="#a78bfa" />
534
- </div>
535
- <div style={{ ...miniSectionTitle, margin: 0, color: "#a78bfa" }}>Concurrency</div>
536
- </div>
537
- <div style={concurrencyStatRow}>
538
- <div style={concurrencyStat}><span style={concurrencyStatValue}>{c.peak}</span><span style={concurrencyStatLabel}>peak agents · {c.peak_day}</span></div>
539
- <div style={concurrencyStat}><span style={concurrencyStatValue}>{c.multi_agent_days}</span><span style={concurrencyStatLabel}>days ≥3 parallel</span></div>
540
- <div style={concurrencyStat}><span style={concurrencyStatValue}>{c.cross_project_days}</span><span style={concurrencyStatLabel}>cross-project days</span></div>
541
- </div>
542
- <p style={{ ...patternNote, margin: "12px 0 0", fontSize: 13 }}>{c.insight}</p>
543
- <div style={concurrencySuggestion}>
544
- <ArrowRight size={13} color="var(--af-accent)" style={{ flexShrink: 0, marginTop: 2 }} />
545
- <span>{c.suggestion}</span>
546
- </div>
547
- </div>
548
- );
549
- }
550
-
551
- function OutliersRow({ outliers }: { outliers: ReportData["outliers"] }) {
552
- return (
553
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
554
- <div style={miniSectionTitle}>Outliers</div>
555
- <div style={outliersGridStyle}>
556
- {outliers.map((o) => (
557
- <div key={o.label} style={outlierCard}>
558
- <div style={outlierLabel}>{o.label}</div>
559
- <div style={outlierDetail}>{o.detail}</div>
560
- <div style={outlierNote}>{o.note}</div>
561
- </div>
562
- ))}
563
- </div>
564
- </div>
565
- );
566
- }
567
-
568
- function SuggestionBlock({ headline, body }: { headline: string; body: string }) {
569
- return (
570
- <div style={suggestionCard}>
571
- <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
572
- <Lightbulb size={16} color="var(--af-accent)" />
573
- <div style={suggestionEyebrow}>Next experiment</div>
574
- </div>
575
- <div style={suggestionHeadline}>{headline}</div>
576
- <p style={suggestionBody}>{body}</p>
577
- </div>
578
- );
579
- }
580
-
581
- function PriorWeeksStrip({ weeks }: { weeks: ReportData["prior_weeks"] }) {
582
- if (!weeks.length) return null;
583
- return (
584
- <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
585
- <div style={miniSectionTitle}>You, the last 4 weeks</div>
586
- <div style={priorWeeksGrid}>
587
- {weeks.map((w) => (
588
- <div key={w.period_label} style={priorWeekCard}>
589
- <div style={priorWeekPeriod}>{w.period_label}</div>
590
- <div style={priorWeekArchetype}>{w.archetype}</div>
591
- <div style={priorWeekStats}>
592
- <span>{w.sessions} sess</span>
593
- <span>{w.prs} PR</span>
594
- <span>{w.subagents} sub</span>
595
- <span>{(w.agent_minutes / 60).toFixed(1)}h</span>
596
- </div>
597
- </div>
598
- ))}
599
- </div>
600
- </div>
601
- );
602
- }
603
-
604
- function MetaFooter({ meta }: { meta: ReportData["meta"] }) {
605
- return (
606
- <footer style={footerStyle}>
607
- <div style={{ display: "flex", gap: 18, flexWrap: "wrap" }}>
608
- <span>
609
- <FileText size={11} style={inlineIcon} /> {meta.sessions_used} substantive
610
- <span style={{ opacity: 0.6 }}> · {meta.trivial_dropped} trivial dropped from {meta.sessions_total} total</span>
611
- </span>
612
- <span>Model: {meta.model}</span>
613
- <span>Context: {meta.context_kb} KB</span>
614
- <span>Pipeline: {(meta.pipeline_ms / 1000).toFixed(1)}s</span>
615
- </div>
616
- <div style={{ opacity: 0.7 }}>{meta.generated_at}</div>
617
- </footer>
618
- );
619
- }
620
-
621
- function FlagPill({ flag }: { flag: string }) {
622
- const meta = FLAG_TONE[flag] ?? { label: flag, tone: "neutral" as const };
623
- const colors = {
624
- good: { bg: "color-mix(in srgb, var(--af-accent) 14%, transparent)", fg: "var(--af-accent)" },
625
- warn: { bg: "color-mix(in srgb, #f5b445 18%, transparent)", fg: "#c08a1f" },
626
- danger: { bg: "color-mix(in srgb, #ef6a5e 18%, transparent)", fg: "#c13f33" },
627
- neutral: { bg: "var(--af-surface-raised)", fg: "var(--af-text-secondary)" },
628
- }[meta.tone];
629
- return (
630
- <span style={{
631
- fontSize: 10.5, fontWeight: 500, padding: "3px 8px", borderRadius: 999,
632
- background: colors.bg, color: colors.fg, letterSpacing: "0.01em", whiteSpace: "nowrap",
633
- }}>
634
- {meta.label}
635
- </span>
636
- );
637
- }
638
-
639
- // ──────────────────────────────────────────────────────────────────
640
- // Styles
641
- // ──────────────────────────────────────────────────────────────────
642
-
643
- const rootStyle: React.CSSProperties = {
644
- display: "flex", flexDirection: "column", gap: 24,
645
- maxWidth: 980, padding: "28px 44px 64px", margin: "0 auto",
646
- };
647
-
648
- const toolbarStyle: React.CSSProperties = {
649
- display: "flex", alignItems: "flex-end", justifyContent: "space-between",
650
- flexWrap: "wrap", gap: 12, paddingBottom: 14,
651
- borderBottom: "1px solid var(--af-border-subtle)",
652
- };
653
-
654
- const primaryBtn: React.CSSProperties = {
655
- display: "inline-flex", alignItems: "center", gap: 5, padding: "7px 12px",
656
- border: "1px solid var(--af-accent)", borderRadius: 8,
657
- background: "var(--af-accent)", color: "white",
658
- fontSize: 11.5, fontWeight: 600, cursor: "pointer",
659
- };
660
-
661
- const secondaryBtn: React.CSSProperties = {
662
- display: "inline-flex", alignItems: "center", gap: 5, padding: "6px 11px",
663
- border: "1px solid var(--af-border)", borderRadius: 8,
664
- background: "var(--af-surface)", color: "var(--af-text)",
665
- fontSize: 11.5, fontWeight: 500, cursor: "pointer",
666
- };
667
-
668
- const sectionStyle: React.CSSProperties = {
669
- display: "flex", flexDirection: "column", gap: 18,
670
- scrollMarginTop: 20,
671
- };
672
-
673
- const sectionHeaderStyle: React.CSSProperties = {
674
- display: "flex", alignItems: "center", gap: 14,
675
- paddingBottom: 4,
676
- };
677
-
678
- const sectionIndex: React.CSSProperties = {
679
- fontSize: 11, fontWeight: 700, letterSpacing: "0.08em",
680
- color: "var(--af-accent)", fontFamily: "var(--font-mono)",
681
- padding: "2px 9px", borderRadius: 6,
682
- background: "color-mix(in srgb, var(--af-accent) 14%, transparent)",
683
- };
684
-
685
- const sectionTitle: React.CSSProperties = {
686
- fontSize: 20, fontWeight: 700, letterSpacing: "-0.02em", color: "var(--af-text)",
687
- };
688
-
689
- const sectionKicker: React.CSSProperties = {
690
- fontSize: 12, color: "var(--af-text-secondary)", marginTop: 1,
691
- };
692
-
693
- const miniSectionTitle: React.CSSProperties = {
694
- fontSize: 11, fontWeight: 600, letterSpacing: "0.06em",
695
- textTransform: "uppercase", color: "var(--af-text-tertiary)",
696
- };
697
-
698
- // Archetype hero
699
- const archetypeHeroStyle: React.CSSProperties = {
700
- padding: "26px 28px", borderRadius: 16,
701
- background: "linear-gradient(135deg, color-mix(in srgb, var(--af-accent) 10%, var(--af-surface)) 0%, var(--af-surface) 70%)",
702
- border: "1px solid color-mix(in srgb, var(--af-accent) 20%, var(--af-border))",
703
- display: "flex", flexDirection: "column", gap: 10,
704
- };
705
-
706
- const archetypeIconWrap: React.CSSProperties = {
707
- width: 48, height: 48, borderRadius: 12,
708
- background: "color-mix(in srgb, var(--af-accent) 16%, transparent)",
709
- display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0,
710
- };
711
-
712
- const archetypeEyebrow: React.CSSProperties = {
713
- fontSize: 11, color: "var(--af-text-tertiary)", letterSpacing: "0.06em", textTransform: "uppercase", fontWeight: 600,
714
- };
715
-
716
- const archetypeLabel: React.CSSProperties = {
717
- fontSize: 28, fontWeight: 700, letterSpacing: "-0.025em", color: "var(--af-text)", margin: "2px 0", lineHeight: 1.15,
718
- };
719
-
720
- const archetypeTagline: React.CSSProperties = {
721
- fontSize: 13, color: "var(--af-text-secondary)",
722
- };
723
-
724
- const archetypeWhy: React.CSSProperties = {
725
- fontSize: 14, lineHeight: 1.55, color: "var(--af-text)", margin: 0, maxWidth: 720,
726
- };
727
-
728
- const archetypeVsUsual: React.CSSProperties = {
729
- fontSize: 12, color: "var(--af-text-secondary)",
730
- };
731
-
732
- // Skills strip
733
- const skillRow: React.CSSProperties = {
734
- display: "grid", gridTemplateColumns: "minmax(200px, 40%) 1fr 80px",
735
- alignItems: "center", gap: 14,
736
- };
737
-
738
- const skillName: React.CSSProperties = {
739
- fontSize: 12.5, color: "var(--af-text)", fontFamily: "var(--font-mono)",
740
- overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
741
- };
742
-
743
- const skillBarWrap: React.CSSProperties = {
744
- height: 6, background: "var(--af-border-subtle)", borderRadius: 3,
745
- };
746
-
747
- const skillBar: React.CSSProperties = {
748
- height: "100%", background: "var(--af-accent)", borderRadius: 3,
749
- };
750
-
751
- const skillCount: React.CSSProperties = {
752
- fontSize: 12, color: "var(--af-text-secondary)", fontFamily: "var(--font-mono)",
753
- fontVariantNumeric: "tabular-nums", textAlign: "right",
754
- };
755
-
756
- // Day strip
757
- const dayStripStyle: React.CSSProperties = {
758
- display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 6,
759
- padding: "14px 10px 10px",
760
- border: "1px solid var(--af-border-subtle)", borderRadius: 12,
761
- background: "var(--af-surface)",
762
- };
763
-
764
- const dayCol: React.CSSProperties = {
765
- display: "flex", flexDirection: "column", alignItems: "center", gap: 4,
766
- };
767
-
768
- const dayBarWrap: React.CSSProperties = {
769
- width: "100%", height: 70, display: "flex", alignItems: "flex-end", justifyContent: "center",
770
- };
771
-
772
- const dayBar: React.CSSProperties = {
773
- width: "60%", borderRadius: 4, minHeight: 3,
774
- };
775
-
776
- const dayConcurrency: React.CSSProperties = {
777
- fontSize: 11, fontFamily: "var(--font-mono)",
778
- };
779
-
780
- const dayMinutes: React.CSSProperties = {
781
- fontSize: 11, color: "var(--af-text)", fontFamily: "var(--font-mono)",
782
- };
783
-
784
- const dayName: React.CSSProperties = {
785
- fontSize: 11, fontWeight: 600, color: "var(--af-text)", marginTop: 2,
786
- };
787
-
788
- const dayDate: React.CSSProperties = {
789
- fontSize: 10, color: "var(--af-text-tertiary)",
790
- };
791
-
792
- const dayLegend: React.CSSProperties = {
793
- display: "flex", gap: 18, fontSize: 10.5, color: "var(--af-text-secondary)",
794
- paddingLeft: 4,
795
- };
796
-
797
- const legendDot: React.CSSProperties = {
798
- display: "inline-block", width: 8, height: 8, borderRadius: 2, marginRight: 6, verticalAlign: 0,
799
- };
800
-
801
- // Plan utilization
802
- const planRow: React.CSSProperties = {
803
- display: "grid", gridTemplateColumns: "repeat(7, 1fr)", gap: 6,
804
- };
805
-
806
- const planCell: React.CSSProperties = {
807
- display: "flex", flexDirection: "column", alignItems: "center", gap: 4, padding: "6px 0",
808
- };
809
-
810
- const planBar: React.CSSProperties = {
811
- width: "70%", height: 6, borderRadius: 3, overflow: "hidden",
812
- };
813
-
814
- // Projects
815
- const projectRow: React.CSSProperties = {
816
- display: "grid", gridTemplateColumns: "minmax(180px, 30%) 1fr minmax(170px, auto)",
817
- alignItems: "center", gap: 14,
818
- };
819
-
820
- const projectName: React.CSSProperties = {
821
- fontSize: 13, color: "var(--af-text)", fontFamily: "var(--font-mono)",
822
- overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap",
823
- };
824
-
825
- const projectBarWrap: React.CSSProperties = {
826
- height: 14, background: "var(--af-border-subtle)", borderRadius: 4,
827
- };
828
-
829
- const projectBar: React.CSSProperties = {
830
- height: "100%",
831
- background: "linear-gradient(90deg, var(--af-accent) 0%, color-mix(in srgb, var(--af-accent) 65%, transparent) 100%)",
832
- borderRadius: 4,
833
- };
834
-
835
- const projectMeta: React.CSSProperties = {
836
- fontSize: 12, color: "var(--af-text-secondary)", fontFamily: "var(--font-mono)", textAlign: "right",
837
- };
838
-
839
- // Shipped list
840
- const shippedList: React.CSSProperties = {
841
- display: "flex", flexDirection: "column", gap: 8,
842
- };
843
-
844
- const shippedRow: React.CSSProperties = {
845
- display: "grid", gridTemplateColumns: "1fr auto", gap: 20,
846
- padding: "14px 16px",
847
- border: "1px solid var(--af-border-subtle)", borderRadius: 10,
848
- background: "var(--af-surface)",
849
- };
850
-
851
- const shippedLeft: React.CSSProperties = {
852
- display: "flex", flexDirection: "column", gap: 4, minWidth: 0,
853
- };
854
-
855
- const shippedTitleStyle: React.CSSProperties = {
856
- fontSize: 14, fontWeight: 600, color: "var(--af-text)", letterSpacing: "-0.01em",
857
- };
858
-
859
- const shippedSummary: React.CSSProperties = {
860
- fontSize: 12.5, color: "var(--af-text-secondary)", lineHeight: 1.5,
861
- };
862
-
863
- const shippedRight: React.CSSProperties = {
864
- display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 5,
865
- minWidth: 0,
866
- };
867
-
868
- const shippedMetaLine: React.CSSProperties = {
869
- display: "flex", flexWrap: "wrap", gap: 5, justifyContent: "flex-end",
870
- };
871
-
872
- const metaChip: React.CSSProperties = {
873
- fontSize: 10.5, padding: "2px 7px", background: "var(--af-surface-raised)",
874
- borderRadius: 5, color: "var(--af-text-secondary)", fontFamily: "var(--font-mono)",
875
- };
876
-
877
- const shippedFlags: React.CSSProperties = {
878
- display: "flex", flexWrap: "wrap", gap: 5, justifyContent: "flex-end",
879
- };
880
-
881
- // Patterns
882
- const patternsGridStyle: React.CSSProperties = {
883
- display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(260px, 1fr))", gap: 10,
884
- };
885
-
886
- const patternCardStyle: React.CSSProperties = {
887
- padding: "14px 16px", background: "var(--af-surface)",
888
- border: "1px solid var(--af-border-subtle)", borderRadius: 10,
889
- display: "flex", flexDirection: "column", gap: 4,
890
- };
891
-
892
- const patternIconWrap: React.CSSProperties = {
893
- width: 24, height: 24, borderRadius: 6,
894
- background: "color-mix(in srgb, var(--af-accent) 14%, transparent)",
895
- display: "flex", alignItems: "center", justifyContent: "center",
896
- };
897
-
898
- const patternTitle: React.CSSProperties = { fontSize: 13, fontWeight: 600, color: "var(--af-text)" };
899
- const patternStat: React.CSSProperties = {
900
- fontSize: 11.5, fontWeight: 600, color: "var(--af-accent)",
901
- fontFamily: "var(--font-mono)", marginBottom: 2,
902
- };
903
- const patternNote: React.CSSProperties = {
904
- fontSize: 12, lineHeight: 1.5, color: "var(--af-text-secondary)",
905
- };
906
-
907
- // Concurrency block
908
- const concurrencyCard: React.CSSProperties = {
909
- padding: "18px 22px", borderRadius: 12,
910
- background: "color-mix(in srgb, #a78bfa 6%, var(--af-surface))",
911
- border: "1px solid color-mix(in srgb, #a78bfa 28%, var(--af-border))",
912
- display: "flex", flexDirection: "column", gap: 4,
913
- };
914
-
915
- const concurrencyStatRow: React.CSSProperties = {
916
- display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 10, marginTop: 8,
917
- };
918
-
919
- const concurrencyStat: React.CSSProperties = {
920
- display: "flex", flexDirection: "column", gap: 2,
921
- };
922
-
923
- const concurrencyStatValue: React.CSSProperties = {
924
- fontSize: 24, fontWeight: 700, color: "#a78bfa",
925
- fontVariantNumeric: "tabular-nums", letterSpacing: "-0.02em",
926
- };
927
-
928
- const concurrencyStatLabel: React.CSSProperties = {
929
- fontSize: 11, color: "var(--af-text-secondary)",
930
- };
931
-
932
- const concurrencySuggestion: React.CSSProperties = {
933
- display: "flex", gap: 8, alignItems: "flex-start",
934
- padding: "10px 12px", marginTop: 10,
935
- background: "var(--af-surface-raised)", borderRadius: 8,
936
- fontSize: 12.5, lineHeight: 1.5, color: "var(--af-text)",
937
- };
938
-
939
- // Outliers
940
- const outliersGridStyle: React.CSSProperties = {
941
- display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))", gap: 8,
942
- };
943
-
944
- const outlierCard: React.CSSProperties = {
945
- padding: "10px 12px", background: "var(--af-surface)",
946
- border: "1px solid var(--af-border-subtle)", borderRadius: 8,
947
- display: "flex", flexDirection: "column", gap: 1,
948
- };
949
-
950
- const outlierLabel: React.CSSProperties = {
951
- fontSize: 10, fontWeight: 600, letterSpacing: "0.05em", textTransform: "uppercase",
952
- color: "var(--af-text-tertiary)",
953
- };
954
-
955
- const outlierDetail: React.CSSProperties = {
956
- fontSize: 16, fontWeight: 700, color: "var(--af-text)",
957
- fontVariantNumeric: "tabular-nums", letterSpacing: "-0.01em",
958
- };
959
-
960
- const outlierNote: React.CSSProperties = {
961
- fontSize: 11, color: "var(--af-text-secondary)", lineHeight: 1.35,
962
- };
963
-
964
- // Suggestion
965
- const suggestionCard: React.CSSProperties = {
966
- padding: "22px 26px", borderRadius: 14,
967
- background: "color-mix(in srgb, var(--af-accent) 10%, var(--af-surface))",
968
- border: "1px solid color-mix(in srgb, var(--af-accent) 30%, transparent)",
969
- };
970
-
971
- const suggestionEyebrow: React.CSSProperties = {
972
- fontSize: 11, fontWeight: 700, letterSpacing: "0.09em",
973
- textTransform: "uppercase", color: "var(--af-accent)",
974
- };
975
-
976
- const suggestionHeadline: React.CSSProperties = {
977
- fontSize: 18, fontWeight: 600, color: "var(--af-text)", letterSpacing: "-0.01em",
978
- marginBottom: 6, lineHeight: 1.3,
979
- };
980
-
981
- const suggestionBody: React.CSSProperties = {
982
- fontSize: 13.5, lineHeight: 1.55, color: "var(--af-text-secondary)", margin: 0, maxWidth: 720,
983
- };
984
-
985
- // Prior weeks
986
- const priorWeeksGrid: React.CSSProperties = {
987
- display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))", gap: 8,
988
- };
989
-
990
- const priorWeekCard: React.CSSProperties = {
991
- padding: "12px 14px", background: "var(--af-surface)",
992
- border: "1px solid var(--af-border-subtle)", borderRadius: 10,
993
- display: "flex", flexDirection: "column", gap: 4,
994
- };
995
-
996
- const priorWeekPeriod: React.CSSProperties = {
997
- fontSize: 11, color: "var(--af-text-tertiary)", fontFamily: "var(--font-mono)",
998
- };
999
-
1000
- const priorWeekArchetype: React.CSSProperties = {
1001
- fontSize: 13, fontWeight: 600, color: "var(--af-text)",
1002
- };
1003
-
1004
- const priorWeekStats: React.CSSProperties = {
1005
- display: "flex", gap: 10, fontSize: 11, color: "var(--af-text-secondary)",
1006
- fontFamily: "var(--font-mono)", marginTop: 2,
1007
- };
1008
-
1009
- // Footer
1010
- const footerStyle: React.CSSProperties = {
1011
- display: "flex", alignItems: "center", justifyContent: "space-between",
1012
- flexWrap: "wrap", gap: 10, fontSize: 11, color: "var(--af-text-tertiary)",
1013
- fontFamily: "var(--font-mono)", paddingTop: 18, marginTop: 8,
1014
- borderTop: "1px solid var(--af-border-subtle)",
1015
- };
1016
-
1017
- const inlineIcon: React.CSSProperties = { display: "inline", verticalAlign: -1, marginRight: 4 };
1018
-
1019
- function PrintStyles() {
1020
- return (
1021
- <style>{`
1022
- @media print {
1023
- body, html { background: white !important; }
1024
- aside, .af-sidebar, nav[data-sidebar], header[data-app-header] { display: none !important; }
1025
- .no-print { display: none !important; }
1026
- .report-root { max-width: none !important; padding: 24px !important; margin: 0 !important; color: #111 !important; }
1027
- .report-root section { page-break-inside: avoid; }
1028
- }
1029
- `}</style>
1030
- );
1031
- }