failproofai 0.0.11-beta.8 → 0.0.11

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 (239) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  3. package/.next/standalone/.next/build-manifest.json +6 -6
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +1 -1
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  19. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  20. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  21. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  26. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  27. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  29. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  30. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  31. package/.next/standalone/.next/server/app/api/audit/invite/route/app-paths-manifest.json +3 -0
  32. package/.next/standalone/.next/server/app/api/audit/invite/route/build-manifest.json +9 -0
  33. package/.next/standalone/.next/server/app/api/audit/invite/route/server-reference-manifest.json +4 -0
  34. package/.next/standalone/.next/server/app/api/audit/invite/route.js +7 -0
  35. package/.next/standalone/.next/server/app/api/audit/invite/route.js.map +5 -0
  36. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -0
  37. package/.next/standalone/.next/server/app/api/audit/invite/route_client-reference-manifest.js +3 -0
  38. package/.next/standalone/.next/server/app/api/audit/run/route.js +1 -1
  39. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +1 -1
  41. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +2 -2
  43. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/logout/route.js +2 -2
  45. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +2 -2
  47. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/auth/status/route.js +2 -2
  49. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  52. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  53. package/.next/standalone/.next/server/app/audit/page.js +2 -2
  54. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/index.html +1 -1
  57. package/.next/standalone/.next/server/app/index.rsc +15 -15
  58. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  59. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  60. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  61. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  62. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  63. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  64. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  65. package/.next/standalone/.next/server/app/page.js +2 -2
  66. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  67. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  69. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  70. package/.next/standalone/.next/server/app/policies/page.js +2 -2
  71. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  73. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  74. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  75. package/.next/standalone/.next/server/app/project/[name]/page.js +3 -3
  76. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  77. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  78. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  79. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  80. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  81. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +3 -3
  82. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  83. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  84. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  85. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  86. package/.next/standalone/.next/server/app/projects/page.js +3 -3
  87. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  89. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  90. package/.next/standalone/.next/server/chunks/[externals]__1_g_b3t._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0dwpg-h._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0lnenda._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13i_sva._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1_mqemn._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_audit_invite_route_actions_0-2n5sy.js +3 -0
  96. package/.next/standalone/.next/server/chunks/node_modules_0-tu4ot._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/node_modules_0ttxbz7._.js +3 -0
  98. package/.next/standalone/.next/server/chunks/node_modules_1bnh1y0._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/node_modules_1epycqa._.js +3 -0
  100. package/.next/standalone/.next/server/chunks/node_modules_1wpdcgo._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +3 -3
  102. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1d4gx_t._.js → [root-of-the-server]__00uwqi6._.js} +2 -2
  106. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0808sha._.js +4 -0
  107. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1cd25c7._.js → [root-of-the-server]__0e4-6d8._.js} +3 -3
  108. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ehe24g._.js +4 -0
  109. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1-scthx._.js → [root-of-the-server]__0f62vu9._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g253ve._.js +4 -0
  111. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0l13qf2._.js → [root-of-the-server]__0k65l27._.js} +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__15i0juc._.js → [root-of-the-server]__0kjb_s4._.js} +2 -2
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vxf0_g._.js +4 -0
  114. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__12mcauo._.js +4 -0
  115. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0989_dx._.js → [root-of-the-server]__1e-x7j4._.js} +2 -2
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1mt35_w._.js +1 -1
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pcxxwg._.js +2 -2
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1uvfwgr._.js +4 -0
  119. package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/_0il3fl1._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +49 -21
  122. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  123. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  124. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_0ihmbv4.js +3 -0
  125. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1ao30b1.js +3 -0
  126. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  127. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  128. package/.next/standalone/.next/server/pages/404.html +1 -1
  129. package/.next/standalone/.next/server/pages/500.html +1 -1
  130. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  131. package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
  132. package/.next/standalone/.next/static/chunks/{0d49wc5zca0u1.js → 02fywjt0by40a.js} +1 -1
  133. package/.next/standalone/.next/static/chunks/0f7d7hnbh4djs.js +1 -0
  134. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +1 -0
  135. package/.next/standalone/.next/static/chunks/0xdx2ehtbdoeg.js +1 -0
  136. package/.next/standalone/.next/static/chunks/{1nd1e30h8s_mc.js → 1-a5rvq67k7ed.js} +1 -1
  137. package/.next/standalone/.next/static/chunks/{1m2yj97j7f_km.js → 15csyj1_rf0-w.js} +1 -1
  138. package/.next/standalone/.next/static/chunks/1o0xa47736gi9.css +2 -0
  139. package/.next/standalone/.next/static/chunks/24cv31x607n7k.js +1 -0
  140. package/.next/standalone/.next/static/chunks/{3w8d8k_dca5rp.js → 2h0dkzyy0vocp.js} +1 -1
  141. package/.next/standalone/.next/static/chunks/2n_s8v1ae38_a.js +69 -0
  142. package/.next/standalone/.next/static/chunks/2y-jmvrjxz60x.js +6 -0
  143. package/.next/standalone/.next/static/chunks/{24z-bgbisv379.js → 3eik_d9qrvoft.js} +1 -1
  144. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +1 -0
  145. package/.next/standalone/.next/static/chunks/{0j969hb6nujdf.js → 3v61675vr6jav.js} +1 -1
  146. package/.next/standalone/.next/static/chunks/3zkg2s2vzxc3d.js +1 -0
  147. package/.next/standalone/.next/static/chunks/{turbopack-00qy7zfa7m--m.js → turbopack-3lrm4f20fz89b.js} +1 -1
  148. package/.next/standalone/app/api/audit/invite/route.ts +192 -0
  149. package/.next/standalone/app/api/audit/run/route.ts +35 -0
  150. package/.next/standalone/app/api/auth/login-request/route.ts +2 -2
  151. package/.next/standalone/app/api/auth/login-verify/route.ts +10 -2
  152. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +39 -63
  153. package/.next/standalone/app/audit/_components/audit-poster.tsx +326 -0
  154. package/.next/standalone/app/audit/_components/auth-dialog.tsx +23 -49
  155. package/.next/standalone/app/audit/_components/come-back-better-section.tsx +336 -0
  156. package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +187 -0
  157. package/.next/standalone/app/audit/_components/invite-dialog.tsx +230 -0
  158. package/.next/standalone/app/audit/_components/quirks-section.tsx +75 -0
  159. package/.next/standalone/app/audit/_components/share-templates.ts +63 -32
  160. package/.next/standalone/app/audit/_components/sigil.tsx +9 -66
  161. package/.next/standalone/app/audit/_components/strengths-section.tsx +20 -32
  162. package/.next/standalone/app/audit/audit-styles.css +778 -1786
  163. package/.next/standalone/app/components/sessions-list.tsx +77 -80
  164. package/.next/standalone/app/globals.css +241 -34
  165. package/.next/standalone/app/layout.tsx +1 -10
  166. package/.next/standalone/app/policies/hooks-client.tsx +45 -28
  167. package/.next/standalone/app/project/[name]/page.tsx +23 -79
  168. package/.next/standalone/app/projects/page.tsx +14 -23
  169. package/.next/standalone/assets/audit/poster-styles.css +1 -1
  170. package/.next/standalone/assets/audit/styles.css +11 -11
  171. package/.next/standalone/components/navbar.tsx +2 -37
  172. package/.next/standalone/components/reach-developers.tsx +10 -25
  173. package/.next/standalone/lib/auth/api-server-client.ts +28 -0
  174. package/.next/standalone/lib/client-telemetry.ts +4 -0
  175. package/.next/standalone/node_modules/@next/env/package.json +2 -2
  176. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  177. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
  178. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  179. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  180. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  181. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  182. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  183. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  184. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  185. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  186. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  187. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  188. package/.next/standalone/node_modules/next/package.json +15 -15
  189. package/.next/standalone/package.json +19 -14
  190. package/.next/standalone/server.js +1 -1
  191. package/README.md +2 -2
  192. package/bin/failproofai.mjs +24 -5
  193. package/dist/cli.mjs +2328 -381
  194. package/lib/auth/api-server-client.ts +28 -0
  195. package/lib/client-telemetry.ts +4 -0
  196. package/package.json +19 -14
  197. package/scripts/launch.ts +30 -4
  198. package/scripts/postinstall.mjs +10 -1
  199. package/scripts/skew-log-filter.ts +46 -0
  200. package/scripts/validate-mdx.ts +139 -0
  201. package/src/audit/cli.ts +330 -0
  202. package/src/audit/open-browser.ts +69 -0
  203. package/src/audit/social-proof.ts +34 -0
  204. package/src/auth/cli.ts +16 -13
  205. package/.next/standalone/.next/server/chunks/[root-of-the-server]__07tgnzi._.js +0 -3
  206. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0oeun7z._.js +0 -3
  207. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12pit4m._.js +0 -3
  208. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13ra2jq._.js +0 -3
  209. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1b9z5-i._.js +0 -3
  210. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ixjiy8._.js +0 -3
  211. package/.next/standalone/.next/server/chunks/_1-1804f._.js +0 -3
  212. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00jkjmt._.js +0 -4
  213. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013du6r._.js +0 -4
  214. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e85wxv._.js +0 -4
  215. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0gfxvb1._.js +0 -3
  216. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1hlrq6y._.js +0 -4
  217. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ihxdo5._.js +0 -4
  218. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1vvfde2._.js +0 -4
  219. package/.next/standalone/.next/server/chunks/ssr/node_modules_html2canvas_dist_html2canvas_esm_1k58rb_.js +0 -3
  220. package/.next/standalone/.next/server/chunks/ssr/node_modules_html2canvas_dist_html2canvas_esm_1n-0xws.js +0 -3
  221. package/.next/standalone/.next/static/chunks/09ueq8s1as8xs.css +0 -2
  222. package/.next/standalone/.next/static/chunks/0qassxjx1ef04.js +0 -1
  223. package/.next/standalone/.next/static/chunks/0qxb5czqxe-vu.js +0 -1
  224. package/.next/standalone/.next/static/chunks/1dh06515j265n.js +0 -41
  225. package/.next/standalone/.next/static/chunks/29gs4efgi3hme.js +0 -6
  226. package/.next/standalone/.next/static/chunks/2mni177pnjx6u.js +0 -1
  227. package/.next/standalone/.next/static/chunks/2so39wg7mjbi7.js +0 -1
  228. package/.next/standalone/.next/static/chunks/3gti1qdk5epqn.js +0 -1
  229. package/.next/standalone/.next/static/chunks/3wycox197ouus.css +0 -1
  230. package/.next/standalone/app/audit/_components/findings-section.tsx +0 -135
  231. package/.next/standalone/app/audit/_components/identity-section.tsx +0 -126
  232. package/.next/standalone/app/audit/_components/policies-section.tsx +0 -194
  233. package/.next/standalone/app/audit/_components/return-section.tsx +0 -416
  234. package/.next/standalone/app/audit/_components/score-section.tsx +0 -179
  235. package/.next/standalone/app/audit/_components/share-dock.tsx +0 -265
  236. package/.next/standalone/app/audit/_components/show-off-cta.tsx +0 -135
  237. /package/.next/standalone/.next/static/{CVv2A0hMd24t0c0x3V-W_ → P_MIRSeoE296wkbE-Icin}/_buildManifest.js +0 -0
  238. /package/.next/standalone/.next/static/{CVv2A0hMd24t0c0x3V-W_ → P_MIRSeoE296wkbE-Icin}/_clientMiddlewareManifest.js +0 -0
  239. /package/.next/standalone/.next/static/{CVv2A0hMd24t0c0x3V-W_ → P_MIRSeoE296wkbE-Icin}/_ssgManifest.js +0 -0
@@ -1,6 +1,9 @@
1
1
  /**
2
2
  * Sessions List — displays session log files for a project with date
3
3
  * preset / custom-range filtering, session ID search, and pagination.
4
+ *
5
+ * Chrome matches the calm aesthetic on /audit: sharp 1px borders, dim
6
+ * small-caps labels, mono throughout, pink-outlined active filter chip.
4
7
  */
5
8
  "use client";
6
9
 
@@ -95,69 +98,67 @@ export default function SessionsList({ files, projectName }: SessionsListProps)
95
98
  filterPreset !== "all" || dateRange.from !== null || dateRange.to !== null || sessionIdFilter !== "";
96
99
 
97
100
  return (
98
- <div className="space-y-4">
101
+ <div className="sessions-list">
99
102
  {/* Filters */}
100
- <div className="bg-card border border-border rounded-lg p-4 flex flex-col gap-4">
101
- {/* Preset Filters + Refresh */}
102
- <div className="flex flex-wrap items-center gap-2">
103
- <span className="text-sm font-medium text-foreground">Filter by:</span>
103
+ <div className="sessions-filter-bar">
104
+ {/* Preset Filters */}
105
+ <div className="sessions-filter-row">
106
+ <span className="sessions-filter-label">filter by</span>
104
107
  {FILTER_PRESETS.map((preset) => (
105
108
  <button
106
109
  key={preset.value}
110
+ type="button"
107
111
  onClick={() => handlePresetChange(preset.value)}
108
- className={`px-3 py-1.5 text-sm rounded-md transition-colors ${
109
- filterPreset === preset.value
110
- ? "bg-primary text-primary-foreground"
111
- : "bg-muted text-muted-foreground hover:bg-muted/80"
112
- }`}
112
+ className={`sessions-chip${filterPreset === preset.value ? " on" : ""}`}
113
113
  >
114
114
  {preset.label}
115
115
  </button>
116
116
  ))}
117
-
118
117
  </div>
119
118
 
120
119
  {/* Custom Date Range */}
121
- <div className="flex flex-wrap items-center gap-4">
122
- <span className="text-sm font-medium text-foreground">Custom Range:</span>
123
- <div className="flex items-center gap-2">
124
- <DatePickerInput id="date-from" value={dateRange.from} onChange={(v) => handleDateRangeChange("from", v)} aria-label="Filter from date" />
125
- <span className="text-muted-foreground">to</span>
126
- <DatePickerInput id="date-to" value={dateRange.to} onChange={(v) => handleDateRangeChange("to", v)} aria-label="Filter to date" />
127
- </div>
120
+ <div className="sessions-filter-row">
121
+ <span className="sessions-filter-label">range</span>
122
+ <DatePickerInput id="date-from" value={dateRange.from} onChange={(v) => handleDateRangeChange("from", v)} aria-label="Filter from date" />
123
+ <span className="sessions-range-sep">to</span>
124
+ <DatePickerInput id="date-to" value={dateRange.to} onChange={(v) => handleDateRangeChange("to", v)} aria-label="Filter to date" />
128
125
  </div>
129
126
 
130
127
  {/* Session ID Search */}
131
- <div className="flex items-center gap-2">
132
- <Search className="w-4 h-4 text-muted-foreground" />
133
- <span className="text-sm font-medium text-foreground">Filter by Session ID:</span>
128
+ <div className="sessions-filter-row">
129
+ <span className="sessions-filter-label">
130
+ <Search className="sessions-filter-icon" aria-hidden="true" />
131
+ session id
132
+ </span>
134
133
  <input
135
134
  type="text"
136
135
  value={sessionIdFilter}
137
136
  onChange={(e) => setSessionIdFilter(e.target.value)}
138
- placeholder="Enter session ID (UUID)"
139
- className="px-3 py-2 text-sm bg-input border border-border rounded-md text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent transition-all hover:border-primary/50 flex-1 max-w-md"
137
+ placeholder="paste a session uuid"
138
+ className="sessions-input"
140
139
  aria-label="Filter by session ID"
141
140
  />
142
141
  {hasActiveFilters && (
143
142
  <button
143
+ type="button"
144
144
  onClick={clearFilters}
145
- className="px-3 py-2 text-sm bg-muted text-muted-foreground hover:bg-muted/80 rounded-md transition-colors"
145
+ className="sessions-chip"
146
+ style={{ marginLeft: "auto" }}
146
147
  >
147
- Clear
148
+ clear
148
149
  </button>
149
150
  )}
150
151
  </div>
151
152
 
152
153
  {/* Results Count */}
153
- <div className="text-sm text-muted-foreground">
154
+ <div className="sessions-results-count">
154
155
  {filteredFiles.length === 0 ? (
155
- "No sessions found"
156
+ <>{"// no sessions found"}</>
156
157
  ) : (
157
158
  <>
158
- Showing {startIndex + 1}-{endIndex} of {filteredFiles.length} sessions
159
+ {"// showing"} {startIndex + 1}{endIndex} of {filteredFiles.length} sessions
159
160
  {filteredFiles.length !== normalizedFiles.length && (
160
- <span className="ml-1">(filtered from {normalizedFiles.length} total)</span>
161
+ <span> · filtered from {normalizedFiles.length}</span>
161
162
  )}
162
163
  </>
163
164
  )}
@@ -165,60 +166,56 @@ export default function SessionsList({ files, projectName }: SessionsListProps)
165
166
  </div>
166
167
 
167
168
  {/* Sessions Table */}
168
- <div className="bg-card border border-border rounded-lg overflow-hidden">
169
- <div className="overflow-x-auto">
170
- <table className="w-full">
171
- <thead>
172
- <tr className="border-b border-border bg-muted/50">
173
- <th scope="col" className="px-4 py-3 text-left text-sm font-semibold text-foreground w-12">
174
- <span className="sr-only">Icon</span>
175
- </th>
176
- <th scope="col" className="px-4 py-3 text-left text-sm font-semibold text-foreground">SessionId</th>
177
- <th scope="col" className="px-4 py-3 text-left text-sm font-semibold text-foreground">Modified</th>
169
+ <div className="sessions-table-wrap">
170
+ <table className="sessions-table">
171
+ <thead>
172
+ <tr>
173
+ <th scope="col" className="sessions-th sessions-th-icon">
174
+ <span className="sr-only">Icon</span>
175
+ </th>
176
+ <th scope="col" className="sessions-th">session id</th>
177
+ <th scope="col" className="sessions-th">modified</th>
178
+ </tr>
179
+ </thead>
180
+ <tbody>
181
+ {paginatedFiles.length === 0 ? (
182
+ <tr>
183
+ <td colSpan={3} className="sessions-td sessions-empty">
184
+ {"// no sessions match the filter."}
185
+ </td>
178
186
  </tr>
179
- </thead>
180
- <tbody>
181
- {paginatedFiles.length === 0 ? (
182
- <tr>
183
- <td colSpan={3} className="px-4 py-8 text-center text-muted-foreground">
184
- No sessions found matching the filter.
187
+ ) : (
188
+ paginatedFiles.map((file) => (
189
+ <tr key={file.path} className="sessions-row">
190
+ <td className="sessions-td sessions-td-icon">
191
+ <File className="sessions-file-icon" aria-hidden="true" />
192
+ </td>
193
+ <td className="sessions-td sessions-td-name">
194
+ {file.sessionId ? (
195
+ <>
196
+ <Link
197
+ href={`/project/${encodeURIComponent(projectName)}/session/${encodeURIComponent(file.sessionId)}`}
198
+ className="sessions-link"
199
+ >
200
+ {file.name.replace(/\.jsonl$/, "")}
201
+ </Link>
202
+ <CopyButton text={file.sessionId} />
203
+ </>
204
+ ) : (
205
+ <span className="sessions-link" aria-disabled="true">
206
+ {file.name.replace(/\.jsonl$/, "")}
207
+ </span>
208
+ )}
209
+ {file.cli && <CliBadge cli={file.cli} />}
210
+ </td>
211
+ <td className="sessions-td sessions-td-date">
212
+ {file.lastModifiedFormatted || formatDate(file.lastModified)}
185
213
  </td>
186
214
  </tr>
187
- ) : (
188
- paginatedFiles.map((file) => (
189
- <tr key={file.path} className="border-b border-border hover:bg-muted/50 transition-colors">
190
- <td className="px-4 py-3">
191
- <File className="w-5 h-5 text-primary" />
192
- </td>
193
- <td className="px-4 py-3 max-w-md">
194
- <div className="flex flex-wrap items-center gap-2">
195
- {file.sessionId ? (
196
- <>
197
- <Link
198
- href={`/project/${encodeURIComponent(projectName)}/session/${encodeURIComponent(file.sessionId)}`}
199
- className="font-semibold text-foreground hover:text-primary transition-colors break-words break-all inline-block max-w-full"
200
- >
201
- {file.name.replace(/\.jsonl$/, "")}
202
- </Link>
203
- <CopyButton text={file.sessionId} />
204
- </>
205
- ) : (
206
- <span className="font-semibold text-foreground break-words break-all inline-block max-w-full">
207
- {file.name.replace(/\.jsonl$/, "")}
208
- </span>
209
- )}
210
- {file.cli && <CliBadge cli={file.cli} />}
211
- </div>
212
- </td>
213
- <td className="px-4 py-3 text-sm text-muted-foreground">
214
- {file.lastModifiedFormatted || formatDate(file.lastModified)}
215
- </td>
216
- </tr>
217
- ))
218
- )}
219
- </tbody>
220
- </table>
221
- </div>
215
+ ))
216
+ )}
217
+ </tbody>
218
+ </table>
222
219
 
223
220
  {filteredFiles.length > 0 && (
224
221
  <PaginationControls currentPage={currentPage} totalPages={totalPages} onPageChange={setCurrentPage} />
@@ -38,10 +38,10 @@
38
38
  --dim: #5e5c58;
39
39
  --line: #25252b;
40
40
  --line-2: #32323a;
41
- --accent-pink: #e4587d;
42
- --accent-pink-soft: rgba(228, 88, 125, 0.7);
41
+ --accent-pink: #e4587c;
42
+ --accent-pink-soft: rgba(228, 88, 124, 0.7);
43
43
  --accent-pink-shadow: #a83a5a;
44
- --accent-pink-bg: rgba(228, 88, 125, 0.12);
44
+ --accent-pink-bg: rgba(228, 88, 124, 0.12);
45
45
  --accent-green: #66d1b5;
46
46
  --accent-green-shadow: #3e9a82;
47
47
  --accent-green-bg: rgba(102, 209, 181, 0.10);
@@ -108,41 +108,12 @@ html, body, #root {
108
108
 
109
109
  body {
110
110
  background-color: var(--bg);
111
- background-image:
112
- radial-gradient(ellipse 1200px 800px at 70% -10%, rgba(228, 88, 125, 0.055) 0%, transparent 60%),
113
- radial-gradient(ellipse 1000px 700px at 0% 100%, rgba(102, 209, 181, 0.04) 0%, transparent 55%),
114
- radial-gradient(ellipse 100% 100% at 50% 50%, transparent 50%, rgba(0,0,0,0.45) 100%),
115
- linear-gradient(180deg, #16161a 0%, #0f0f12 100%);
116
- background-attachment: fixed;
117
111
  position: relative;
118
112
  }
119
113
 
120
114
  button { font-family: inherit; cursor: pointer; }
121
115
  a { color: inherit; }
122
116
 
123
- /* engineering-plate cross-hatch + grain — site-wide atmosphere */
124
- body::before {
125
- content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 1;
126
- background-image:
127
- linear-gradient(0deg, rgba(255,255,255,0.018) 1px, transparent 1px),
128
- linear-gradient(90deg, rgba(255,255,255,0.018) 1px, transparent 1px),
129
- linear-gradient(0deg, rgba(255,255,255,0.012) 1px, transparent 1px),
130
- linear-gradient(90deg, rgba(255,255,255,0.012) 1px, transparent 1px);
131
- background-size: 96px 96px, 96px 96px, 24px 24px, 24px 24px;
132
- opacity: 0.7;
133
- }
134
- body::after {
135
- content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 2;
136
- background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.85 0 0 0 0 0.82 0 0 0 0 0.78 0 0 0 0.16 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
137
- opacity: 0.4;
138
- mix-blend-mode: overlay;
139
- }
140
-
141
- body > * {
142
- position: relative;
143
- z-index: 3;
144
- }
145
-
146
117
  /* shrink scrollbars without breaking the dark theme */
147
118
  ::-webkit-scrollbar { width: 10px; height: 10px; }
148
119
  ::-webkit-scrollbar-track { background: var(--bg-2); }
@@ -416,8 +387,24 @@ input[type="date"] { color-scheme: dark; }
416
387
  border: 1px solid var(--line-2);
417
388
  border-top: 0;
418
389
  background: var(--bg-2);
419
- }
420
- .activity-table { width: 100%; }
390
+ /* Scroll horizontally on narrow / portrait viewports instead of letting the
391
+ fixed-layout columns collapse into each other. Themed thin scrollbar so it
392
+ reads as part of the same instrument family. */
393
+ overflow-x: auto;
394
+ overflow-y: hidden;
395
+ scrollbar-width: thin;
396
+ scrollbar-color: var(--line-2) transparent;
397
+ }
398
+ .activity-table-wrap::-webkit-scrollbar { height: 10px; }
399
+ .activity-table-wrap::-webkit-scrollbar-track { background: var(--bg-3); }
400
+ .activity-table-wrap::-webkit-scrollbar-thumb {
401
+ background: var(--line-2);
402
+ border: 2px solid var(--bg-3);
403
+ }
404
+ .activity-table-wrap::-webkit-scrollbar-thumb:hover { background: var(--accent-green); }
405
+ /* min-width keeps every column wide enough for its header/badge; below it,
406
+ the wrap scrolls instead of squeezing columns into each other. */
407
+ .activity-table { width: 100%; min-width: 1280px; }
421
408
  .activity-thead { background: var(--bg-3); }
422
409
  .activity-thead tr { border-bottom: 1px solid var(--line-2); }
423
410
  .activity-th {
@@ -428,8 +415,17 @@ input[type="date"] { color-scheme: dark; }
428
415
  font-weight: 500;
429
416
  color: var(--accent-green);
430
417
  text-align: left;
418
+ white-space: nowrap;
431
419
  }
432
420
  .activity-th.text-right { text-align: right; }
421
+ /* Data cells stay on one line and clip (with ellipsis) at their own column
422
+ edge, so a wide badge/value/header can never overlap the next column.
423
+ Scoped to data rows so the expanded detail row (colSpan) is untouched. */
424
+ .activity-data-row > td {
425
+ overflow: hidden;
426
+ text-overflow: ellipsis;
427
+ white-space: nowrap;
428
+ }
433
429
 
434
430
  /* zebra rhythm — adds ambient banding without breaking the dark feel.
435
431
  Hover overrides the stripe so rows feel responsive. */
@@ -664,3 +660,214 @@ input[type="date"] { color-scheme: dark; }
664
660
  transition: none;
665
661
  }
666
662
  }
663
+
664
+ /* ============================================================
665
+ /project/[name] sessions list — calm filter bar + table.
666
+ Sharp 1px borders, no rounded corners, mono throughout,
667
+ dim small-caps labels. Mirrors the audit page's voice.
668
+ ============================================================ */
669
+
670
+ .sessions-list { display: flex; flex-direction: column; gap: 16px; font-family: var(--font-mono); }
671
+
672
+ .sessions-filter-bar {
673
+ display: flex; flex-direction: column;
674
+ gap: 12px;
675
+ padding: 16px 18px;
676
+ border: 1px solid var(--line-2);
677
+ background: var(--bg-2);
678
+ }
679
+
680
+ .sessions-filter-row {
681
+ display: flex; flex-wrap: wrap; align-items: center;
682
+ gap: 8px;
683
+ }
684
+
685
+ .sessions-filter-label {
686
+ display: inline-flex; align-items: center; gap: 6px;
687
+ font-size: 10px;
688
+ letter-spacing: 0.22em;
689
+ text-transform: uppercase;
690
+ color: var(--dim);
691
+ margin-right: 4px;
692
+ }
693
+ .sessions-filter-icon { width: 12px; height: 12px; }
694
+
695
+ .sessions-chip {
696
+ font-family: var(--font-mono);
697
+ font-size: 11px;
698
+ letter-spacing: 0.04em;
699
+ color: var(--ink-2);
700
+ background: transparent;
701
+ border: 1px solid var(--line-2);
702
+ padding: 5px 10px;
703
+ cursor: pointer;
704
+ transition: border-color 140ms ease, color 140ms ease, background-color 140ms ease;
705
+ }
706
+ .sessions-chip:hover {
707
+ border-color: var(--accent-pink);
708
+ color: var(--accent-pink);
709
+ }
710
+ .sessions-chip.on {
711
+ border-color: var(--accent-pink);
712
+ color: var(--accent-pink);
713
+ background: var(--accent-pink-bg);
714
+ }
715
+ .sessions-chip:focus-visible {
716
+ outline: 2px solid var(--accent-pink);
717
+ outline-offset: 2px;
718
+ }
719
+
720
+ .sessions-input {
721
+ flex: 1 1 280px;
722
+ min-width: 220px;
723
+ font-family: var(--font-mono);
724
+ font-size: 12px;
725
+ letter-spacing: 0.01em;
726
+ color: var(--ink);
727
+ background: var(--bg);
728
+ border: 1px solid var(--line-2);
729
+ padding: 7px 10px;
730
+ outline: none;
731
+ transition: border-color 140ms ease;
732
+ }
733
+ .sessions-input:focus { border-color: var(--accent-pink); }
734
+ .sessions-input::placeholder { color: var(--dim); }
735
+
736
+ .sessions-range-sep {
737
+ font-size: 11px; color: var(--dim);
738
+ letter-spacing: 0.04em;
739
+ }
740
+
741
+ .sessions-results-count {
742
+ font-family: var(--font-mono);
743
+ font-size: 11px;
744
+ color: var(--dim);
745
+ letter-spacing: 0.02em;
746
+ margin-top: 4px;
747
+ }
748
+
749
+ .sessions-table-wrap {
750
+ border: 1px solid var(--line-2);
751
+ background: var(--bg-2);
752
+ overflow-x: auto;
753
+ }
754
+ .sessions-table { width: 100%; border-collapse: collapse; }
755
+ .sessions-th {
756
+ font-family: var(--font-mono);
757
+ font-size: 10px;
758
+ letter-spacing: 0.2em;
759
+ text-transform: uppercase;
760
+ color: var(--dim);
761
+ font-weight: 500;
762
+ text-align: left;
763
+ padding: 10px 16px;
764
+ border-bottom: 1px solid var(--line);
765
+ background: var(--bg);
766
+ }
767
+ .sessions-th-icon { width: 36px; }
768
+
769
+ .sessions-row { border-bottom: 1px solid var(--line); transition: background-color 140ms ease; }
770
+ .sessions-row:last-child { border-bottom: none; }
771
+ .sessions-row:hover { background: rgba(228, 88, 124, 0.03); }
772
+
773
+ .sessions-td {
774
+ font-family: var(--font-mono);
775
+ font-size: 12px;
776
+ color: var(--ink-2);
777
+ padding: 12px 16px;
778
+ vertical-align: middle;
779
+ }
780
+ .sessions-td-icon { width: 36px; }
781
+ .sessions-file-icon { width: 14px; height: 14px; color: var(--dim); }
782
+
783
+ .sessions-td-name {
784
+ display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
785
+ max-width: 520px;
786
+ }
787
+ .sessions-link {
788
+ color: var(--ink);
789
+ font-size: 13px;
790
+ letter-spacing: 0.01em;
791
+ text-decoration: none;
792
+ word-break: break-all;
793
+ }
794
+ .sessions-link:hover { color: var(--accent-pink); }
795
+ .sessions-link[aria-disabled="true"] { color: var(--ink-2); cursor: default; }
796
+
797
+ .sessions-td-date { font-size: 11px; color: var(--dim); white-space: nowrap; }
798
+
799
+ .sessions-empty {
800
+ text-align: center;
801
+ font-size: 12px;
802
+ color: var(--dim);
803
+ padding: 32px 16px;
804
+ }
805
+
806
+ /* ============================================================
807
+ /project/[name] page header — back link, project title, meta.
808
+ ============================================================ */
809
+
810
+ .project-page-back {
811
+ display: inline-flex; align-items: center; gap: 6px;
812
+ font-family: var(--font-mono);
813
+ font-size: 11px;
814
+ letter-spacing: 0.06em;
815
+ color: var(--ink-2);
816
+ text-decoration: none;
817
+ padding: 6px 12px;
818
+ border: 1px solid var(--line-2);
819
+ background: transparent;
820
+ transition: border-color 140ms ease, color 140ms ease;
821
+ }
822
+ .project-page-back:hover {
823
+ border-color: var(--accent-pink);
824
+ color: var(--accent-pink);
825
+ }
826
+ .project-page-back .arrow { color: var(--dim); font-size: 12px; }
827
+
828
+ .project-page-title {
829
+ font-family: var(--font-mono);
830
+ font-size: 22px;
831
+ font-weight: 600;
832
+ letter-spacing: -0.01em;
833
+ color: var(--ink);
834
+ margin: 16px 0 8px;
835
+ word-break: break-word;
836
+ line-height: 1.3;
837
+ }
838
+
839
+ .project-page-meta {
840
+ font-family: var(--font-mono);
841
+ font-size: 11px;
842
+ color: var(--dim);
843
+ letter-spacing: 0.02em;
844
+ margin: 0 0 32px;
845
+ }
846
+ .project-page-meta .label { color: var(--ink-2); margin-right: 6px; }
847
+ .project-page-meta .sep { margin: 0 12px; color: var(--line-2); }
848
+ .project-page-meta .path { color: var(--ink-2); word-break: break-all; }
849
+
850
+ .project-page-sessions-head {
851
+ font-family: var(--font-mono);
852
+ font-size: 10px;
853
+ letter-spacing: 0.22em;
854
+ text-transform: uppercase;
855
+ color: var(--accent-green);
856
+ margin-bottom: 16px;
857
+ }
858
+
859
+ .project-page-empty {
860
+ padding: 48px 32px;
861
+ border: 1px solid var(--line-2);
862
+ background: var(--bg-2);
863
+ text-align: center;
864
+ font-family: var(--font-mono);
865
+ font-size: 13px;
866
+ color: var(--ink-2);
867
+ }
868
+ .project-page-empty .hint {
869
+ font-size: 11px;
870
+ color: var(--dim);
871
+ margin-top: 8px;
872
+ letter-spacing: 0.02em;
873
+ }
@@ -10,7 +10,6 @@ import { GlobalErrorListeners } from "@/app/components/global-error-listeners";
10
10
  import { AutoRefreshProvider } from "@/contexts/AutoRefreshContext";
11
11
  import { Navbar } from "@/components/navbar";
12
12
  import { Toaster } from "@/app/components/toast";
13
- import { readDashboardCache } from "@/src/audit/dashboard-cache";
14
13
  import "./globals.css";
15
14
 
16
15
  // Site-wide mono font is JetBrains Mono, loaded via the Google Fonts @import
@@ -33,21 +32,13 @@ export default function RootLayout({
33
32
  }>) {
34
33
  const disabledPages = (process.env.FAILPROOFAI_DISABLE_PAGES ?? "")
35
34
  .split(",").map((s) => s.trim()).filter(Boolean);
36
- // Read the audit cache once per page request to drive the nav badge.
37
- // Cheap (single JSON file) and the cache itself returns null on miss.
38
- const auditCache = readDashboardCache();
39
- const auditSlippingCount = auditCache?.result?.results
40
- ? auditCache.result.results
41
- .filter((r) => r.source === "audit-detector" || (r.source === "builtin" && !r.enabledInConfig))
42
- .reduce((sum, r) => sum + r.hits, 0)
43
- : undefined;
44
35
  return (
45
36
  <html lang="en" className="dark">
46
37
  <body className="antialiased">
47
38
  <PostHogProvider>
48
39
  <GlobalErrorListeners />
49
40
  <AutoRefreshProvider>
50
- <Navbar disabledPages={disabledPages} auditSlippingCount={auditSlippingCount} />
41
+ <Navbar disabledPages={disabledPages} />
51
42
  {children}
52
43
  </AutoRefreshProvider>
53
44
  <Toaster />