failproofai 0.0.13-beta.2 → 0.0.14-beta.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 (285) hide show
  1. package/.next/standalone/.factory/hooks.json +112 -0
  2. package/.next/standalone/.next/BUILD_ID +1 -1
  3. package/.next/standalone/.next/build-manifest.json +3 -3
  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/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  21. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  22. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  23. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  24. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  26. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  27. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/audit/run/route.js +3 -3
  29. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +2 -1
  36. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  38. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/index.html +1 -1
  41. package/.next/standalone/.next/server/app/index.rsc +15 -15
  42. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  43. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  44. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  45. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  46. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  47. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  48. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  51. package/.next/standalone/.next/server/app/policies/page.js +1 -1
  52. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/page.js +3 -2
  56. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +5 -3
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page.js +1 -1
  65. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0--lkk6._.js +3 -0
  68. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-219ec._.js +3 -0
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +3 -0
  70. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +3 -0
  71. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08w4wmd._.js +3 -0
  72. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g6bbuw._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jllheg._.js +3 -0
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +3 -0
  75. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  76. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q0qzx1._.js +3 -0
  77. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +3 -0
  78. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rv7m0k._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +3 -3
  80. package/.next/standalone/.next/server/chunks/[root-of-the-server]__16le-kd._.js +3 -0
  81. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +1 -1
  82. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d9qen3._.js +3 -0
  83. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ffkmds._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +1 -1
  86. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qb590j._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1shcqgr._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xuedea._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/{_1z062h5._.js → _1vslkoe._.js} +2 -2
  93. package/.next/standalone/.next/server/chunks/lib_factory-projects_ts_1eo_bk-._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +24 -12
  96. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00cz9as._.js +3 -0
  100. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +2 -2
  101. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__030k0c6._.js +3 -0
  102. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +2 -2
  103. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__042d3cd._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__05r_17v._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1rlmypf._.js → [root-of-the-server]__07qfsfa._.js} +2 -2
  106. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09q1168._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e2l3c1._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__09u1pcy._.js → [root-of-the-server]__0ge8e7w._.js} +2 -2
  109. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h12me5._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hci7t3._.js +3 -0
  111. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hdsupo._.js +2 -2
  112. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p84xee._.js +3 -0
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +2 -2
  114. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +2 -2
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ynf7tx._.js +2 -2
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11rtg6s._.js +1 -1
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +1 -1
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +12 -9
  119. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +4 -0
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +1 -1
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js +1 -1
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +3 -0
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +2 -2
  124. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__212nf49._.js +1 -1
  125. package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/_0_9_ytf._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  128. package/.next/standalone/.next/server/chunks/ssr/{_0ul5rf_._.js → _1_ozgif._.js} +2 -2
  129. package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +1 -1
  130. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  132. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/lib_0xkhw_v._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/ssr/lib_antigravity-projects_ts_0_6zf11._.js +3 -0
  135. package/.next/standalone/.next/server/chunks/ssr/lib_devin-projects_ts_0a64qdy._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/lib_factory-projects_ts_1uyaahq._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/lib_goose-projects_ts_0zkscri._.js +3 -0
  138. package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +3 -0
  139. package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_09fe3kb.js → node_modules_html-to-image_es_index_0g5r64e.js} +1 -1
  140. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0-uvagv.js +1 -1
  141. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_03c7gi5.js +1 -1
  142. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_09p-8om.js +1 -1
  143. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0v-kfiu.js +1 -1
  144. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0xrgzyz.js +1 -1
  145. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1806lsc.js +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1j6dd-e.js +1 -1
  147. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1sa65r-.js +1 -1
  148. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  149. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +1 -1
  150. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +1 -1
  151. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  152. package/.next/standalone/.next/server/pages/404.html +1 -1
  153. package/.next/standalone/.next/server/pages/500.html +1 -1
  154. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  155. package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
  156. package/.next/standalone/.next/static/chunks/003uz088wbmz7.js +1 -0
  157. package/.next/standalone/.next/static/chunks/{0l2n5ftar65ox.js → 0405htbxay9vd.js} +1 -1
  158. package/.next/standalone/.next/static/chunks/0iinhn4417nk1.js +1 -0
  159. package/.next/standalone/.next/static/chunks/1374x9bv_s_vg.js +6 -0
  160. package/.next/standalone/.next/static/chunks/{06cw8nbn5c4_r.js → 17sdztgbcc0fi.js} +1 -1
  161. package/.next/standalone/.next/static/chunks/{0i0joc040j999.js → 2m_tbl39fcedn.js} +1 -1
  162. package/.next/standalone/.next/static/chunks/{25qvspmcbb_5y.js → 2o3ql0n5owqsw.js} +1 -1
  163. package/.next/standalone/.next/static/chunks/{2a-k91nsa1lgf.js → 2ufuwhv03yvtb.js} +1 -1
  164. package/.next/standalone/.next/static/chunks/35-90m9py64d4.js +1 -0
  165. package/.next/standalone/.next/static/chunks/3r--yyjkp9_7b.css +2 -0
  166. package/.next/standalone/.next/static/chunks/{23t-i9s-q--nu.js → 43weu8f59tlix.js} +1 -1
  167. package/.next/standalone/.next/static/chunks/{2oz8ok8fzxaj3.js → 454dyizqik6t9.js} +2 -2
  168. package/.next/standalone/app/api/audit/run/route.ts +2 -0
  169. package/.next/standalone/app/audit/_components/empty-state.tsx +1 -1
  170. package/.next/standalone/app/globals.css +25 -1
  171. package/.next/standalone/app/policies/hooks-client.tsx +2 -4
  172. package/.next/standalone/app/project/[name]/page.tsx +30 -10
  173. package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +71 -21
  174. package/.next/standalone/assets/logos/antigravity.svg +1 -0
  175. package/.next/standalone/assets/logos/devin.svg +1 -0
  176. package/.next/standalone/assets/logos/factory-dark.png +0 -0
  177. package/.next/standalone/assets/logos/factory-light.png +0 -0
  178. package/.next/standalone/assets/logos/goose-dark.svg +1 -0
  179. package/.next/standalone/assets/logos/goose-light.svg +1 -0
  180. package/.next/standalone/assets/logos/openclaw.svg +22 -0
  181. package/.next/standalone/components/navbar.tsx +5 -11
  182. package/.next/standalone/components/reach-developers.tsx +1 -1
  183. package/.next/standalone/lib/antigravity-projects.ts +224 -0
  184. package/.next/standalone/lib/antigravity-sessions.ts +283 -0
  185. package/.next/standalone/lib/cli-registry.ts +26 -6
  186. package/.next/standalone/lib/devin-projects.ts +141 -0
  187. package/.next/standalone/lib/devin-sessions.ts +343 -0
  188. package/.next/standalone/lib/download-session.ts +56 -5
  189. package/.next/standalone/lib/factory-projects.ts +109 -0
  190. package/.next/standalone/lib/factory-sessions.ts +312 -0
  191. package/.next/standalone/lib/goose-projects.ts +148 -0
  192. package/.next/standalone/lib/goose-sessions.ts +296 -0
  193. package/.next/standalone/lib/openclaw-projects.ts +182 -0
  194. package/.next/standalone/lib/openclaw-sessions.ts +284 -0
  195. package/.next/standalone/lib/projects.ts +33 -9
  196. package/.next/standalone/lib/telemetry-sanitize.ts +43 -0
  197. package/.next/standalone/openclaw-plugin/index.js +223 -0
  198. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +6 -0
  199. package/.next/standalone/openclaw-plugin/package.json +12 -0
  200. package/.next/standalone/package.json +4 -3
  201. package/.next/standalone/server.js +1 -1
  202. package/README.md +105 -57
  203. package/bin/failproofai.mjs +87 -29
  204. package/dist/cli.mjs +12803 -9809
  205. package/lib/antigravity-projects.ts +224 -0
  206. package/lib/antigravity-sessions.ts +283 -0
  207. package/lib/cli-registry.ts +26 -6
  208. package/lib/devin-projects.ts +141 -0
  209. package/lib/devin-sessions.ts +343 -0
  210. package/lib/download-session.ts +56 -5
  211. package/lib/factory-projects.ts +109 -0
  212. package/lib/factory-sessions.ts +312 -0
  213. package/lib/goose-projects.ts +148 -0
  214. package/lib/goose-sessions.ts +296 -0
  215. package/lib/openclaw-projects.ts +182 -0
  216. package/lib/openclaw-sessions.ts +284 -0
  217. package/lib/projects.ts +33 -9
  218. package/lib/telemetry-sanitize.ts +43 -0
  219. package/openclaw-plugin/index.js +223 -0
  220. package/openclaw-plugin/openclaw.plugin.json +6 -0
  221. package/openclaw-plugin/package.json +12 -0
  222. package/package.json +4 -3
  223. package/scripts/launch.ts +4 -8
  224. package/scripts/postinstall.mjs +3 -4
  225. package/scripts/sync-agent-cli-harnesses-prompt.md +7 -10
  226. package/scripts/translate-docs/cli.ts +73 -52
  227. package/scripts/translate-docs/config.ts +57 -13
  228. package/scripts/translate-docs/mdx-translator.ts +51 -31
  229. package/scripts/translate-docs/mintlify-nav.ts +91 -10
  230. package/scripts/translate-docs/types.ts +3 -0
  231. package/src/audit/cli-adapters/antigravity.ts +87 -0
  232. package/src/audit/cli-adapters/devin.ts +53 -0
  233. package/src/audit/cli-adapters/factory.ts +75 -0
  234. package/src/audit/cli-adapters/goose.ts +53 -0
  235. package/src/audit/cli-adapters/index.ts +30 -6
  236. package/src/audit/cli-adapters/openclaw.ts +56 -0
  237. package/src/audit/cli.ts +44 -1
  238. package/src/audit/report.ts +1 -1
  239. package/src/audit/types.ts +1 -1
  240. package/src/hooks/builtin-policies.ts +5 -5
  241. package/src/hooks/configure-wizard.ts +356 -0
  242. package/src/hooks/handler.ts +283 -218
  243. package/src/hooks/hook-telemetry.ts +43 -3
  244. package/src/hooks/install-prompt.ts +92 -173
  245. package/src/hooks/integrations.ts +739 -138
  246. package/src/hooks/manager.ts +46 -2
  247. package/src/hooks/policy-evaluator.ts +301 -121
  248. package/src/hooks/policy-presets.ts +71 -0
  249. package/src/hooks/resolve-cwd.ts +1 -1
  250. package/src/hooks/resolve-permission-mode.ts +1 -5
  251. package/src/hooks/resolve-transcript-path.ts +25 -7
  252. package/src/hooks/tool-name-canonicalize.ts +36 -3
  253. package/src/hooks/tui.ts +578 -0
  254. package/src/hooks/types.ts +447 -109
  255. package/.next/standalone/.gemini/settings.json +0 -147
  256. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cag8qd._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cefjd9._.js +0 -3
  258. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ekj92q._.js +0 -3
  259. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12v-lma._.js +0 -3
  260. package/.next/standalone/.next/server/chunks/[root-of-the-server]__136y39g._.js +0 -3
  261. package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h8pzr._.js +0 -3
  262. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hgv_75._.js +0 -3
  263. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04bqvos._.js +0 -3
  264. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0dqgs96._.js +0 -3
  265. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0q5rfxg._.js +0 -3
  266. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qukut7._.js +0 -4
  267. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ql-mch._.js +0 -3
  268. package/.next/standalone/.next/server/chunks/ssr/_11v0g3z._.js +0 -3
  269. package/.next/standalone/.next/server/chunks/ssr/lib_gemini-projects_ts_1c7bgx-._.js +0 -3
  270. package/.next/standalone/.next/static/chunks/0fa7j157kg9_d.js +0 -1
  271. package/.next/standalone/.next/static/chunks/1c8i78p7t1i-5.js +0 -1
  272. package/.next/standalone/.next/static/chunks/1sg8kx5szx42y.js +0 -6
  273. package/.next/standalone/.next/static/chunks/25s52un3k_wht.css +0 -2
  274. package/.next/standalone/.next/static/chunks/2rkvn4znvuy4o.js +0 -1
  275. package/.next/standalone/assets/logos/gemini-dark.svg +0 -13
  276. package/.next/standalone/assets/logos/gemini-light.svg +0 -13
  277. package/.next/standalone/lib/gemini-projects.ts +0 -243
  278. package/.next/standalone/lib/gemini-sessions.ts +0 -365
  279. package/lib/gemini-projects.ts +0 -243
  280. package/lib/gemini-sessions.ts +0 -365
  281. package/src/audit/cli-adapters/gemini.ts +0 -51
  282. package/src/hooks/first-run-nudge.ts +0 -146
  283. /package/.next/standalone/.next/static/{HgG0mizCfOM3XyN1EW-sL → MNJWFb2jLRrxRKGFNK6Hy}/_buildManifest.js +0 -0
  284. /package/.next/standalone/.next/static/{HgG0mizCfOM3XyN1EW-sL → MNJWFb2jLRrxRKGFNK6Hy}/_clientMiddlewareManifest.js +0 -0
  285. /package/.next/standalone/.next/static/{HgG0mizCfOM3XyN1EW-sL → MNJWFb2jLRrxRKGFNK6Hy}/_ssgManifest.js +0 -0
@@ -6,8 +6,12 @@ import { getCachedCopilotSessionsByEncodedName } from "@/lib/copilot-projects";
6
6
  import { getCachedCursorSessionsByEncodedName } from "@/lib/cursor-projects";
7
7
  import { getCachedOpenCodeSessionsByEncodedName } from "@/lib/opencode-projects";
8
8
  import { getCachedPiSessionsByEncodedName } from "@/lib/pi-projects";
9
- import { getCachedGeminiSessionsByEncodedName } from "@/lib/gemini-projects";
10
9
  import { getCachedHermesSessionsByEncodedName } from "@/lib/hermes-projects";
10
+ import { getCachedOpenClawSessionsByEncodedName } from "@/lib/openclaw-projects";
11
+ import { getCachedFactorySessionsByEncodedName } from "@/lib/factory-projects";
12
+ import { getCachedDevinSessionsByEncodedName } from "@/lib/devin-projects";
13
+ import { getCachedAntigravitySessionsByEncodedName } from "@/lib/antigravity-projects";
14
+ import { getCachedGooseSessionsByEncodedName } from "@/lib/goose-projects";
11
15
  import { logWarn } from "@/lib/logger";
12
16
  import { decodeFolderName } from "@/lib/paths";
13
17
  import { notFound } from "next/navigation";
@@ -46,22 +50,30 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
46
50
  }
47
51
  // Note: decodeFolderName is lossy when cwds contain `-` (every `-` becomes `/`),
48
52
  // so each external CLI looks up sessions by re-encoding cwd and matching the slug.
49
- const [codex, copilot, cursor, opencode, pi, gemini, hermes] = await Promise.all([
53
+ const [codex, copilot, cursor, opencode, pi, hermes, openclaw, factory, devin, antigravity, goose] = await Promise.all([
50
54
  getCachedCodexSessionsByEncodedName(name),
51
55
  getCachedCopilotSessionsByEncodedName(name),
52
56
  getCachedCursorSessionsByEncodedName(name),
53
57
  getCachedOpenCodeSessionsByEncodedName(name),
54
58
  getCachedPiSessionsByEncodedName(name),
55
- getCachedGeminiSessionsByEncodedName(name),
56
59
  getCachedHermesSessionsByEncodedName(name),
60
+ getCachedOpenClawSessionsByEncodedName(name),
61
+ getCachedFactorySessionsByEncodedName(name),
62
+ getCachedDevinSessionsByEncodedName(name),
63
+ getCachedAntigravitySessionsByEncodedName(name),
64
+ getCachedGooseSessionsByEncodedName(name),
57
65
  ]);
58
66
  const codexSessions = codex.sessions;
59
67
  const copilotSessions = copilot.sessions;
60
68
  const cursorSessions = cursor.sessions;
61
69
  const opencodeSessions = opencode.sessions;
62
70
  const piSessions = pi.sessions;
63
- const geminiSessions = gemini.sessions;
64
71
  const hermesSessions = hermes.sessions;
72
+ const openclawSessions = openclaw.sessions;
73
+ const factorySessions = factory.sessions;
74
+ const devinSessions = devin.sessions;
75
+ const antigravitySessions = antigravity.sessions;
76
+ const gooseSessions = goose.sessions;
65
77
 
66
78
  if (
67
79
  !claudeExists &&
@@ -70,8 +82,12 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
70
82
  cursorSessions.length === 0 &&
71
83
  opencodeSessions.length === 0 &&
72
84
  piSessions.length === 0 &&
73
- geminiSessions.length === 0 &&
74
- hermesSessions.length === 0
85
+ hermesSessions.length === 0 &&
86
+ openclawSessions.length === 0 &&
87
+ factorySessions.length === 0 &&
88
+ devinSessions.length === 0 &&
89
+ antigravitySessions.length === 0 &&
90
+ gooseSessions.length === 0
75
91
  ) {
76
92
  notFound();
77
93
  }
@@ -79,8 +95,8 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
79
95
  // Prefer a canonical cwd recovered from any external store when available —
80
96
  // `decodeFolderName(name)` is ambiguous for cwds containing `-` (every `-`
81
97
  // becomes `/`). Each external transcript records the literal cwd, so they
82
- // round-trip correctly. First non-null wins (Codex → Copilot → Cursor → OpenCode → Pi → Gemini).
83
- const canonicalRoot = codex.cwd ?? copilot.cwd ?? cursor.cwd ?? opencode.cwd ?? pi.cwd ?? gemini.cwd ?? hermes.cwd ?? decodedName;
98
+ // round-trip correctly. First non-null wins (Codex → Copilot → Cursor → OpenCode → Pi).
99
+ const canonicalRoot = codex.cwd ?? copilot.cwd ?? cursor.cwd ?? opencode.cwd ?? pi.cwd ?? hermes.cwd ?? openclaw.cwd ?? factory.cwd ?? devin.cwd ?? antigravity.cwd ?? goose.cwd ?? decodedName;
84
100
 
85
101
  // Project header metadata
86
102
  let lastModified: Date | null = null;
@@ -94,7 +110,7 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
94
110
  logWarn(`Failed to get stats for project ${decodedName}:`, error);
95
111
  }
96
112
  }
97
- const newestExternal = [codexSessions[0], copilotSessions[0], cursorSessions[0], opencodeSessions[0], piSessions[0], geminiSessions[0], hermesSessions[0]]
113
+ const newestExternal = [codexSessions[0], copilotSessions[0], cursorSessions[0], opencodeSessions[0], piSessions[0], hermesSessions[0], openclawSessions[0], factorySessions[0], devinSessions[0], antigravitySessions[0], gooseSessions[0]]
98
114
  .filter((s): s is SessionFile => !!s)
99
115
  .map((s) => s.lastModified)
100
116
  .reduce<Date | null>((acc, d) => (!acc || d.getTime() > acc.getTime() ? d : acc), null);
@@ -110,8 +126,12 @@ export default async function ProjectPage({ params }: ProjectPageProps) {
110
126
  ...cursorSessions,
111
127
  ...opencodeSessions,
112
128
  ...piSessions,
113
- ...geminiSessions,
114
129
  ...hermesSessions,
130
+ ...openclawSessions,
131
+ ...factorySessions,
132
+ ...devinSessions,
133
+ ...antigravitySessions,
134
+ ...gooseSessions,
115
135
  ].sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
116
136
 
117
137
  // Path line: prefer the Claude storage dir if present (matches existing UX);
@@ -8,8 +8,12 @@ import { getCachedCopilotSessionLog } from "@/lib/copilot-sessions";
8
8
  import { getCachedCursorSessionLog } from "@/lib/cursor-sessions";
9
9
  import { getCachedOpenCodeSessionLog } from "@/lib/opencode-sessions";
10
10
  import { getCachedPiSessionLog } from "@/lib/pi-sessions";
11
- import { getCachedGeminiSessionLog } from "@/lib/gemini-sessions";
12
11
  import { getCachedHermesSessionLog } from "@/lib/hermes-sessions";
12
+ import { getCachedOpenClawSessionLog } from "@/lib/openclaw-sessions";
13
+ import { getCachedFactorySessionLog } from "@/lib/factory-sessions";
14
+ import { getCachedDevinSessionLog } from "@/lib/devin-sessions";
15
+ import { getCachedAntigravitySessionLog } from "@/lib/antigravity-sessions";
16
+ import { getCachedGooseSessionLog } from "@/lib/goose-sessions";
13
17
  import { decodeFolderName } from "@/lib/paths";
14
18
  import { baseSessionId } from "@/lib/utils/session-id";
15
19
  import { resolveProjectPath, UUID_RE } from "@/lib/projects";
@@ -53,7 +57,7 @@ export default async function SessionPage({ params }: SessionPageProps) {
53
57
  let entries: LogEntry[] | null = null;
54
58
  let rawLines: Record<string, unknown>[] | null = null;
55
59
  let error: string | null = null;
56
- let cli: "claude" | "codex" | "copilot" | "cursor" | "opencode" | "pi" | "gemini" | "hermes" = "claude";
60
+ let cli: "claude" | "codex" | "copilot" | "cursor" | "opencode" | "pi" | "hermes" | "openclaw" | "factory" | "devin" | "antigravity" | "goose" = "claude";
57
61
  let externalCwd: string | undefined;
58
62
 
59
63
  try {
@@ -102,21 +106,53 @@ export default async function SessionPage({ params }: SessionPageProps) {
102
106
  externalCwd = pi.cwd;
103
107
  cli = "pi";
104
108
  } else {
105
- const gemini = await getCachedGeminiSessionLog(decodedSessionId);
106
- if (gemini) {
107
- entries = gemini.entries;
108
- rawLines = gemini.rawLines;
109
- externalCwd = gemini.cwd;
110
- cli = "gemini";
109
+ const hermes = await getCachedHermesSessionLog(decodedSessionId);
110
+ if (hermes) {
111
+ entries = hermes.entries;
112
+ rawLines = hermes.rawLines;
113
+ externalCwd = hermes.cwd;
114
+ cli = "hermes";
111
115
  } else {
112
- const hermes = await getCachedHermesSessionLog(decodedSessionId);
113
- if (hermes) {
114
- entries = hermes.entries;
115
- rawLines = hermes.rawLines;
116
- externalCwd = hermes.cwd;
117
- cli = "hermes";
116
+ const openclaw = await getCachedOpenClawSessionLog(decodedSessionId);
117
+ if (openclaw) {
118
+ entries = openclaw.entries;
119
+ rawLines = openclaw.rawLines;
120
+ externalCwd = openclaw.cwd;
121
+ cli = "openclaw";
118
122
  } else {
119
- error = "Session log file not found.";
123
+ const factory = await getCachedFactorySessionLog(decodedSessionId);
124
+ if (factory) {
125
+ entries = factory.entries;
126
+ rawLines = factory.rawLines;
127
+ externalCwd = factory.cwd;
128
+ cli = "factory";
129
+ } else {
130
+ const devin = await getCachedDevinSessionLog(decodedSessionId);
131
+ if (devin) {
132
+ entries = devin.entries;
133
+ rawLines = devin.rawLines;
134
+ externalCwd = devin.cwd;
135
+ cli = "devin";
136
+ } else {
137
+ const antigravity = await getCachedAntigravitySessionLog(decodedSessionId);
138
+ if (antigravity) {
139
+ entries = antigravity.entries;
140
+ rawLines = antigravity.rawLines;
141
+ externalCwd = antigravity.cwd;
142
+ cli = "antigravity";
143
+ } else {
144
+ const goose = await getCachedGooseSessionLog(decodedSessionId);
145
+ if (goose) {
146
+ entries = goose.entries;
147
+ rawLines = goose.rawLines;
148
+ externalCwd = goose.cwd;
149
+ cli = "goose";
150
+ } else {
151
+ error = "Session log file not found.";
152
+ }
153
+ }
154
+ }
155
+ }
120
156
  }
121
157
  }
122
158
  }
@@ -142,11 +178,19 @@ export default async function SessionPage({ params }: SessionPageProps) {
142
178
  ? `OpenCode${externalCwd ? ` · ${externalCwd}` : ""}`
143
179
  : cli === "pi"
144
180
  ? `Pi${externalCwd ? ` · ${externalCwd}` : ""}`
145
- : cli === "gemini"
146
- ? `Gemini CLI${externalCwd ? ` · ${externalCwd}` : ""}`
147
- : cli === "hermes"
148
- ? `Hermes${externalCwd ? ` · ${externalCwd}` : ""}`
149
- : decodedName;
181
+ : cli === "hermes"
182
+ ? `Hermes${externalCwd ? ` · ${externalCwd}` : ""}`
183
+ : cli === "openclaw"
184
+ ? `OpenClaw${externalCwd ? ` · ${externalCwd}` : ""}`
185
+ : cli === "factory"
186
+ ? `Factory Droid${externalCwd ? ` · ${externalCwd}` : ""}`
187
+ : cli === "devin"
188
+ ? `Devin CLI${externalCwd ? ` · ${externalCwd}` : ""}`
189
+ : cli === "antigravity"
190
+ ? `Antigravity CLI${externalCwd ? ` · ${externalCwd}` : ""}`
191
+ : cli === "goose"
192
+ ? `Goose${externalCwd ? ` · ${externalCwd}` : ""}`
193
+ : decodedName;
150
194
 
151
195
  return (
152
196
  <main className="min-h-screen bg-background">
@@ -216,7 +260,13 @@ export default async function SessionPage({ params }: SessionPageProps) {
216
260
  ? "Pi"
217
261
  : cli === "hermes"
218
262
  ? "Hermes"
219
- : "Gemini CLI"))
263
+ : cli === "openclaw"
264
+ ? "OpenClaw"
265
+ : cli === "factory"
266
+ ? "Factory Droid"
267
+ : cli === "devin"
268
+ ? "Devin CLI"
269
+ : "Antigravity CLI"))
220
270
  : decodedName
221
271
  }
222
272
  sessionId={decodedSessionId}
@@ -0,0 +1 @@
1
+ <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Antigravity</title><mask height="23" id="lobe-icons-antigravity-0-_R_0_" maskUnits="userSpaceOnUse" width="24" x="0" y="1"><path d="M21.751 22.607c1.34 1.005 3.35.335 1.508-1.508C17.73 15.74 18.904 1 12.037 1 5.17 1 6.342 15.74.815 21.1c-2.01 2.009.167 2.511 1.507 1.506 5.192-3.517 4.857-9.714 9.715-9.714 4.857 0 4.522 6.197 9.714 9.715z" fill="#fff"></path></mask><g mask="url(#lobe-icons-antigravity-0-_R_0_)"><g filter="url(#lobe-icons-antigravity-1-_R_0_)"><path d="M-1.018-3.992c-.408 3.591 2.686 6.89 6.91 7.37 4.225.48 7.98-2.043 8.387-5.633.408-3.59-2.686-6.89-6.91-7.37-4.225-.479-7.98 2.043-8.387 5.633z" fill="#FFE432"></path></g><g filter="url(#lobe-icons-antigravity-2-_R_0_)"><path d="M15.269 7.747c1.058 4.557 5.691 7.374 10.348 6.293 4.657-1.082 7.575-5.653 6.516-10.21-1.058-4.556-5.691-7.374-10.348-6.292-4.657 1.082-7.575 5.653-6.516 10.21z" fill="#FC413D"></path></g><g filter="url(#lobe-icons-antigravity-3-_R_0_)"><path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"></path></g><g filter="url(#lobe-icons-antigravity-4-_R_0_)"><path d="M-12.443 10.804c1.338 4.703 7.36 7.11 13.453 5.378 6.092-1.733 9.947-6.95 8.61-11.652C8.282-.173 2.26-2.58-3.833-.848-9.925.884-13.78 6.1-12.443 10.804z" fill="#00B95C"></path></g><g filter="url(#lobe-icons-antigravity-5-_R_0_)"><path d="M-7.608 14.703c3.352 3.424 9.126 3.208 12.896-.483 3.77-3.69 4.108-9.459.756-12.883C2.69-2.087-3.083-1.871-6.853 1.82c-3.77 3.69-4.108 9.458-.755 12.883z" fill="#00B95C"></path></g><g filter="url(#lobe-icons-antigravity-6-_R_0_)"><path d="M9.932 27.617c1.04 4.482 5.384 7.303 9.7 6.3 4.316-1.002 6.971-5.448 5.93-9.93-1.04-4.483-5.384-7.304-9.7-6.301-4.316 1.002-6.971 5.448-5.93 9.93z" fill="#3186FF"></path></g><g filter="url(#lobe-icons-antigravity-7-_R_0_)"><path d="M2.572-8.185C.392-3.329 2.778 2.472 7.9 4.771c5.122 2.3 11.042.227 13.222-4.63 2.18-4.855-.205-10.656-5.327-12.955-5.122-2.3-11.042-.227-13.222 4.63z" fill="#FBBC04"></path></g><g filter="url(#lobe-icons-antigravity-8-_R_0_)"><path d="M-3.267 38.686c-5.277-2.072 3.742-19.117 5.984-24.83 2.243-5.712 8.34-8.664 13.616-6.592 5.278 2.071 11.533 13.482 9.29 19.195-2.242 5.713-23.613 14.298-28.89 12.227z" fill="#3186FF"></path></g><g filter="url(#lobe-icons-antigravity-9-_R_0_)"><path d="M28.71 17.471c-1.413 1.649-5.1.808-8.236-1.878-3.135-2.687-4.531-6.201-3.118-7.85 1.412-1.649 5.1-.808 8.235 1.878s4.532 6.2 3.119 7.85z" fill="#749BFF"></path></g><g filter="url(#lobe-icons-antigravity-10-_R_0_)"><path d="M18.163 9.077c5.81 3.93 12.502 4.19 14.946.577 2.443-3.612-.287-9.727-6.098-13.658-5.81-3.931-12.502-4.19-14.946-.577-2.443 3.612.287 9.727 6.098 13.658z" fill="#FC413D"></path></g><g filter="url(#lobe-icons-antigravity-11-_R_0_)"><path d="M-.915 2.684c-1.44 3.473-.97 6.967 1.05 7.804 2.02.837 4.824-1.3 6.264-4.772 1.44-3.473.97-6.967-1.05-7.804-2.02-.837-4.824 1.3-6.264 4.772z" fill="#FFEE48"></path></g></g><defs><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="17.587" id="lobe-icons-antigravity-1-_R_0_" width="19.838" x="-3.288" y="-11.917"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="1.117"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="38.565" id="lobe-icons-antigravity-2-_R_0_" width="38.9" x="4.251" y="-13.493"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="5.4"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="lobe-icons-antigravity-3-_R_0_" width="40.955" x="-21.889" y="-10.592"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.517" id="lobe-icons-antigravity-4-_R_0_" width="40.955" x="-21.889" y="-10.592"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="36.595" id="lobe-icons-antigravity-5-_R_0_" width="36.632" x="-19.099" y="-10.278"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.591"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="34.087" id="lobe-icons-antigravity-6-_R_0_" width="33.533" x=".981" y="8.758"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="4.363"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="35.276" id="lobe-icons-antigravity-7-_R_0_" width="35.978" x="-6.143" y="-21.659"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.954"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="46.523" id="lobe-icons-antigravity-8-_R_0_" width="45.114" x="-11.96" y="-.46"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.531"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="24.054" id="lobe-icons-antigravity-9-_R_0_" width="25.094" x="10.485" y=".58"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.159"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="30.007" id="lobe-icons-antigravity-10-_R_0_" width="33.508" x="5.833" y="-12.467"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="2.669"></feGaussianBlur></filter><filter color-interpolation-filters="sRGB" filterUnits="userSpaceOnUse" height="26.151" id="lobe-icons-antigravity-11-_R_0_" width="22.194" x="-8.355" y="-8.876"><feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood><feBlend in="SourceGraphic" in2="BackgroundImageFix" result="shape"></feBlend><feGaussianBlur result="effect1_foregroundBlur_977_115" stdDeviation="3.303"></feGaussianBlur></filter></defs></svg>
@@ -0,0 +1 @@
1
+ <svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Devin</title><path d="M2.033 9.867l2.554 1.483a.589.589 0 00.592 0l2.554-1.483.01-.008a.608.608 0 00.11-.084l.013-.015a.631.631 0 00.076-.1c.003-.005.008-.01.01-.016a.558.558 0 00.052-.125l.007-.028a.611.611 0 00.019-.14V7.868c0-.572.307-1.105.8-1.392a1.595 1.595 0 011.598 0l1.277.742a.54.54 0 00.129.053l.028.01c.044.01.088.015.133.016h.006l.013-.002a.587.587 0 00.27-.074l.011-.004 2.554-1.483a.596.596 0 00.297-.516V2.253a.595.595 0 00-.297-.516L12.293.257a.587.587 0 00-.591 0L9.148 1.737l-.01.01a.609.609 0 00-.109.083l-.014.015a.632.632 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.028a.612.612 0 00-.018.14v1.483c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.603.603 0 00-.13-.053l-.028-.008a.658.658 0 00-.133-.018h-.02a.57.57 0 00-.269.074c-.003.002-.008.002-.012.005L2.033 5.872a.596.596 0 00-.297.515v2.966c0 .213.113.41.297.515z" fill="#3969CA"></path><path d="M15.943 10.607a1.596 1.596 0 011.599 0l1.276.74c.041.025.085.04.13.055l.028.008c.043.01.088.016.133.018h.005c.005 0 .01-.002.014-.003a.474.474 0 00.122-.016l.021-.005a.616.616 0 00.126-.052c.004-.002.009-.002.013-.005l2.554-1.482a.597.597 0 00.297-.516V6.383a.596.596 0 00-.297-.515l-2.552-1.483a.587.587 0 00-.592 0l-2.553 1.482-.011.008a.61.61 0 00-.108.084l-.014.016a.637.637 0 00-.076.1c-.003.005-.008.01-.01.016a.57.57 0 00-.052.124l-.007.029a.612.612 0 00-.018.14v1.482c0 .572-.307 1.105-.8 1.393a1.597 1.597 0 01-1.599 0l-1.276-.742a.584.584 0 00-.13-.053l-.028-.008a.62.62 0 00-.133-.018h-.02a.587.587 0 00-.269.074l-.012.004L9.15 10a.596.596 0 00-.296.516v2.966c0 .212.112.409.296.515l2.554 1.483s.008.002.012.005c.04.022.082.04.126.052l.02.004a.57.57 0 00.123.017l.014.002h.006c.054 0 .108-.01.16-.025a.587.587 0 00.13-.054l1.277-.741a1.597 1.597 0 012.398 1.392v1.482c0 .049.007.095.019.14l.007.028a.619.619 0 00.051.125c.004.006.008.01.01.016a.6.6 0 00.076.1l.014.015c.033.032.069.06.108.084.004.002.006.006.011.008l2.554 1.483a.59.59 0 00.593 0l2.554-1.483a.597.597 0 00.296-.516v-2.965a.595.595 0 00-.296-.516l-2.554-1.483s-.008-.002-.012-.005a.54.54 0 00-.126-.051c-.007-.003-.013-.003-.02-.005a.635.635 0 00-.125-.017h-.018a.557.557 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.595 1.595 0 01-1.598 0 1.615 1.615 0 010-2.785l-.005-.001z" fill="#21C19A"></path><path d="M14.848 18.265l-2.554-1.482-.012-.005a.526.526 0 00-.126-.052c-.007-.002-.014-.002-.02-.005a.64.64 0 00-.124-.017h-.02a.56.56 0 00-.16.026.588.588 0 00-.13.053l-1.276.742a1.594 1.594 0 01-1.598 0c-.493-.286-.8-.82-.8-1.393V14.65a.563.563 0 00-.018-.14l-.008-.028a.604.604 0 00-.051-.124l-.01-.017a.603.603 0 00-.076-.1l-.014-.015a.596.596 0 00-.109-.084c-.003-.002-.005-.006-.01-.008L5.178 12.65a.587.587 0 00-.591 0l-2.554 1.483a.596.596 0 00-.297.516v2.965c0 .213.113.41.297.516l2.554 1.483.012.004a.618.618 0 00.267.074l.016.002h.007a.55.55 0 00.16-.026.584.584 0 00.129-.053l1.277-.742a1.597 1.597 0 012.398 1.393v1.482c0 .05.007.095.019.14l.007.028c.013.044.03.085.051.125l.01.016c.022.036.047.07.076.1l.014.015c.032.032.069.06.109.084l.01.008 2.554 1.483a.587.587 0 00.593 0l2.554-1.483a.596.596 0 00.296-.515v-2.966a.596.596 0 00-.296-.516h-.002z" fill="#0294DE"></path></svg>
@@ -0,0 +1 @@
1
+ <svg fill="#ffffff" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Goose</title><path d="M21.595 23.61c1.167-.254 2.405-.944 2.405-.944l-2.167-1.784a12.124 12.124 0 01-2.695-3.131 12.127 12.127 0 00-3.97-4.049l-.794-.462a1.115 1.115 0 01-.488-.815.844.844 0 01.154-.575c.413-.582 2.548-3.115 2.94-3.44.503-.416 1.065-.762 1.586-1.159.074-.056.148-.112.221-.17.003-.002.007-.004.009-.007.167-.131.325-.272.45-.438.453-.524.563-.988.59-1.193-.061-.197-.244-.639-.753-1.148.319.02.705.272 1.056.569.235-.376.481-.773.727-1.171.165-.266-.08-.465-.086-.471h-.001V3.22c-.007-.007-.206-.25-.471-.086-.567.35-1.134.702-1.639 1.021 0 0-.597-.012-1.305.599a2.464 2.464 0 00-.438.45l-.007.009c-.058.072-.114.147-.17.221-.397.521-.743 1.083-1.16 1.587-.323.391-2.857 2.526-3.44 2.94a.842.842 0 01-.574.153 1.115 1.115 0 01-.815-.488l-.462-.794a12.123 12.123 0 00-4.049-3.97 12.133 12.133 0 01-3.13-2.695L1.332 0S.643 1.238.39 2.405c.352.428 1.27 1.49 2.34 2.302C1.58 4.167.73 3.75.06 3.4c-.103.765-.063 1.92.043 2.816.726.317 1.961.806 3.219 1.066-1.006.236-2.11.278-2.961.262.15.554.358 1.119.64 1.688.119.263.25.52.39.77.452.125 2.222.383 3.164.171l-2.51.897a27.776 27.776 0 002.544 2.726c2.031-1.092 2.494-1.241 4.018-2.238-2.467 2.008-3.108 2.828-3.8 3.67l-.483.678c-.25.351-.469.725-.65 1.117-.61 1.31-1.47 4.1-1.47 4.1-.154.486.202.842.674.674 0 0 2.79-.861 4.1-1.47.392-.182.766-.4 1.118-.65l.677-.483c.227-.187.453-.37.701-.586 0 0 1.705 2.02 3.458 3.349l.896-2.511c-.211.942.046 2.712.17 3.163.252.142.509.272.772.392.569.28 1.134.49 1.688.64-.016-.853.026-1.956.261-2.962.26 1.258.75 2.493 1.067 3.219.895.106 2.051.146 2.816.043a73.87 73.87 0 01-1.308-2.67c.811 1.07 1.874 1.988 2.302 2.34h-.001z"></path></svg>
@@ -0,0 +1 @@
1
+ <svg fill="#111111" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Goose</title><path d="M21.595 23.61c1.167-.254 2.405-.944 2.405-.944l-2.167-1.784a12.124 12.124 0 01-2.695-3.131 12.127 12.127 0 00-3.97-4.049l-.794-.462a1.115 1.115 0 01-.488-.815.844.844 0 01.154-.575c.413-.582 2.548-3.115 2.94-3.44.503-.416 1.065-.762 1.586-1.159.074-.056.148-.112.221-.17.003-.002.007-.004.009-.007.167-.131.325-.272.45-.438.453-.524.563-.988.59-1.193-.061-.197-.244-.639-.753-1.148.319.02.705.272 1.056.569.235-.376.481-.773.727-1.171.165-.266-.08-.465-.086-.471h-.001V3.22c-.007-.007-.206-.25-.471-.086-.567.35-1.134.702-1.639 1.021 0 0-.597-.012-1.305.599a2.464 2.464 0 00-.438.45l-.007.009c-.058.072-.114.147-.17.221-.397.521-.743 1.083-1.16 1.587-.323.391-2.857 2.526-3.44 2.94a.842.842 0 01-.574.153 1.115 1.115 0 01-.815-.488l-.462-.794a12.123 12.123 0 00-4.049-3.97 12.133 12.133 0 01-3.13-2.695L1.332 0S.643 1.238.39 2.405c.352.428 1.27 1.49 2.34 2.302C1.58 4.167.73 3.75.06 3.4c-.103.765-.063 1.92.043 2.816.726.317 1.961.806 3.219 1.066-1.006.236-2.11.278-2.961.262.15.554.358 1.119.64 1.688.119.263.25.52.39.77.452.125 2.222.383 3.164.171l-2.51.897a27.776 27.776 0 002.544 2.726c2.031-1.092 2.494-1.241 4.018-2.238-2.467 2.008-3.108 2.828-3.8 3.67l-.483.678c-.25.351-.469.725-.65 1.117-.61 1.31-1.47 4.1-1.47 4.1-.154.486.202.842.674.674 0 0 2.79-.861 4.1-1.47.392-.182.766-.4 1.118-.65l.677-.483c.227-.187.453-.37.701-.586 0 0 1.705 2.02 3.458 3.349l.896-2.511c-.211.942.046 2.712.17 3.163.252.142.509.272.772.392.569.28 1.134.49 1.688.64-.016-.853.026-1.956.261-2.962.26 1.258.75 2.493 1.067 3.219.895.106 2.051.146 2.816.043a73.87 73.87 0 01-1.308-2.67c.811 1.07 1.874 1.988 2.302 2.34h-.001z"></path></svg>
@@ -0,0 +1,22 @@
1
+ <svg viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <defs>
3
+ <linearGradient id="lobster-gradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" stop-color="#ff4d4d"/>
5
+ <stop offset="100%" stop-color="#991b1b"/>
6
+ </linearGradient>
7
+ </defs>
8
+ <!-- Body -->
9
+ <path d="M60 10 C30 10 15 35 15 55 C15 75 30 95 45 100 L45 110 L55 110 L55 100 C55 100 60 102 65 100 L65 110 L75 110 L75 100 C90 95 105 75 105 55 C105 35 90 10 60 10Z" fill="url(#lobster-gradient)"/>
10
+ <!-- Left Claw -->
11
+ <path d="M20 45 C5 40 0 50 5 60 C10 70 20 65 25 55 C28 48 25 45 20 45Z" fill="url(#lobster-gradient)"/>
12
+ <!-- Right Claw -->
13
+ <path d="M100 45 C115 40 120 50 115 60 C110 70 100 65 95 55 C92 48 95 45 100 45Z" fill="url(#lobster-gradient)"/>
14
+ <!-- Antenna -->
15
+ <path d="M45 15 Q35 5 30 8" stroke="#ff4d4d" stroke-width="3" stroke-linecap="round"/>
16
+ <path d="M75 15 Q85 5 90 8" stroke="#ff4d4d" stroke-width="3" stroke-linecap="round"/>
17
+ <!-- Eyes -->
18
+ <circle cx="45" cy="35" r="6" fill="#050810"/>
19
+ <circle cx="75" cy="35" r="6" fill="#050810"/>
20
+ <circle cx="46" cy="34" r="2.5" fill="#00e5cc"/>
21
+ <circle cx="76" cy="34" r="2.5" fill="#00e5cc"/>
22
+ </svg>
@@ -109,19 +109,13 @@ export const Navbar: React.FC<{
109
109
  {/* Spacer pushes version/section + actions to the right */}
110
110
  <div style={{ flex: 1 }} />
111
111
 
112
- {/* Version + section label — swapped to right of nav */}
112
+ {/* Version + section label — swapped to right of nav. `.h-meta` never
113
+ wraps mid-token and is hidden entirely on narrow viewports (it
114
+ duplicates the active tab highlight). */}
113
115
  {(process.env.NEXT_PUBLIC_APP_VERSION || sectionLabel) && (
114
- <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
116
+ <div className="h-meta">
115
117
  {process.env.NEXT_PUBLIC_APP_VERSION && (
116
- <span
117
- style={{
118
- fontFamily: "var(--font-mono)",
119
- fontSize: 10,
120
- letterSpacing: "0.18em",
121
- textTransform: "uppercase",
122
- color: "var(--dim)",
123
- }}
124
- >
118
+ <span className="h-version">
125
119
  v{process.env.NEXT_PUBLIC_APP_VERSION}
126
120
  </span>
127
121
  )}
@@ -66,7 +66,7 @@ export const ReachDevelopers: React.FC = () => {
66
66
  className="relative z-50 flex items-center gap-1.5 text-muted-foreground hover:text-foreground"
67
67
  >
68
68
  <GitBranch className="h-4 w-4" />
69
- <span className="hidden sm:inline text-xs">Reach Us</span>
69
+ <span className="hidden sm:inline text-xs whitespace-nowrap">Reach Us</span>
70
70
  <ChevronDown
71
71
  className={`h-3 w-3 transition-transform ${open ? "rotate-180" : ""}`}
72
72
  />
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Antigravity (agy) project discovery + session enumeration — AUDIT-ONLY.
3
+ *
4
+ * Antigravity keeps a SQLite index of conversations at
5
+ * `~/.gemini/antigravity-cli/conversation_summaries.db` (table
6
+ * `conversation_summaries`: conversation_id, title, preview, step_count,
7
+ * workspace_uris, project_id, last_modified_time, agent_name, …) and one
8
+ * plain-JSONL transcript per conversation under `brain/<id>/…`. Verified live
9
+ * against agy v1.1.2.
10
+ *
11
+ * The on-disk `brain/` transcripts are the source of truth for a conversation's
12
+ * EXISTENCE (the summaries DB can lag / be checkpointed empty), so we enumerate
13
+ * from disk (lib/antigravity-sessions.ts) and ENRICH each with title + cwd from
14
+ * the SQLite index when a row is present. `workspace_uris` gives the project cwd
15
+ * → per-project grouping; when absent we recover cwd from the transcript's first
16
+ * `run_command` Cwd, else fall back to a synthetic "antigravity" project.
17
+ *
18
+ * DB / home override: set `ANTIGRAVITY_HOME` (used by tests).
19
+ */
20
+ import { join } from "node:path";
21
+ import { openSqliteReadonly } from "./sqlite-reader";
22
+ import {
23
+ antigravityHome,
24
+ listAntigravityTranscripts,
25
+ getAntigravitySessionLog,
26
+ } from "./antigravity-sessions";
27
+ import { runtimeCache } from "./runtime-cache";
28
+ import type { ProjectFolder, SessionFile } from "./projects";
29
+ import { encodeFolderName, decodeFolderName } from "./paths";
30
+ import { formatDate } from "./format-date";
31
+ import { logWarn } from "./logger";
32
+
33
+ /** Absolute path to the conversation-index SQLite DB. */
34
+ export function antigravitySummariesDbPath(): string {
35
+ return join(antigravityHome(), "conversation_summaries.db");
36
+ }
37
+
38
+ interface SummaryRow {
39
+ conversation_id: string;
40
+ title: string | null;
41
+ step_count: number | null;
42
+ workspace_uris: string | null;
43
+ last_modified_time: string | number | null;
44
+ }
45
+
46
+ export interface AntigravityIndexMeta {
47
+ title?: string;
48
+ cwd?: string;
49
+ stepCount?: number;
50
+ lastMs?: number;
51
+ }
52
+
53
+ /** Parse the first workspace URI (a JSON array, or a plain string) into a cwd,
54
+ * stripping any `file://` scheme. */
55
+ function parseWorkspaceCwd(raw: string | null): string | undefined {
56
+ if (!raw) return undefined;
57
+ let first: string | undefined;
58
+ try {
59
+ const parsed = JSON.parse(raw);
60
+ if (Array.isArray(parsed) && typeof parsed[0] === "string") first = parsed[0];
61
+ else if (typeof parsed === "string") first = parsed;
62
+ } catch {
63
+ first = raw;
64
+ }
65
+ if (!first) return undefined;
66
+ const stripped = first.replace(/^file:\/\//, "");
67
+ return stripped.length > 0 ? stripped : undefined;
68
+ }
69
+
70
+ function toMs(value: string | number | null): number | undefined {
71
+ if (typeof value === "number" && Number.isFinite(value)) {
72
+ return value > 1e12 ? value : value > 1e9 ? value * 1000 : undefined;
73
+ }
74
+ if (typeof value === "string") {
75
+ const ms = Date.parse(value);
76
+ if (!Number.isNaN(ms)) return ms;
77
+ }
78
+ return undefined;
79
+ }
80
+
81
+ /** Read the conversation index → conversationId → metadata. Returns an empty
82
+ * map when the DB is missing/unreadable/empty (fail-open). */
83
+ export async function getAntigravityIndex(): Promise<Map<string, AntigravityIndexMeta>> {
84
+ const out = new Map<string, AntigravityIndexMeta>();
85
+ const db = await openSqliteReadonly(antigravitySummariesDbPath());
86
+ if (!db) return out;
87
+ try {
88
+ const rows = db.query<SummaryRow>(
89
+ "SELECT conversation_id, title, step_count, workspace_uris, last_modified_time FROM conversation_summaries",
90
+ );
91
+ for (const r of rows) {
92
+ if (!r.conversation_id) continue;
93
+ out.set(r.conversation_id, {
94
+ title: r.title ?? undefined,
95
+ cwd: parseWorkspaceCwd(r.workspace_uris),
96
+ stepCount: typeof r.step_count === "number" ? r.step_count : undefined,
97
+ lastMs: toMs(r.last_modified_time),
98
+ });
99
+ }
100
+ } catch {
101
+ // corrupt / unexpected schema — fall open with whatever we have
102
+ } finally {
103
+ db.close();
104
+ }
105
+ return out;
106
+ }
107
+
108
+ interface AntigravityConversation {
109
+ conversationId: string;
110
+ cwd: string | null;
111
+ title?: string;
112
+ mtimeMs: number;
113
+ }
114
+
115
+ /** Resolve every on-disk conversation to {cwd, title, mtime}, enriched from the
116
+ * SQLite index (cwd/title/lastMs) and, when the index lacks a cwd, from the
117
+ * transcript's first run_command Cwd. */
118
+ async function resolveConversations(): Promise<AntigravityConversation[]> {
119
+ let transcripts;
120
+ try {
121
+ transcripts = listAntigravityTranscripts();
122
+ } catch (error) {
123
+ logWarn("Failed to scan Antigravity brain dir:", error);
124
+ return [];
125
+ }
126
+ const index = await getAntigravityIndex();
127
+
128
+ const out: AntigravityConversation[] = [];
129
+ for (const t of transcripts) {
130
+ const meta = index.get(t.conversationId);
131
+ let cwd = meta?.cwd ?? null;
132
+ if (!cwd) {
133
+ // No index cwd — recover it from the transcript itself (best-effort).
134
+ try {
135
+ const log = await getAntigravitySessionLog(t.conversationId);
136
+ cwd = log?.cwd ?? null;
137
+ } catch {
138
+ cwd = null;
139
+ }
140
+ }
141
+ out.push({
142
+ conversationId: t.conversationId,
143
+ cwd,
144
+ title: meta?.title,
145
+ mtimeMs: meta?.lastMs ?? t.mtimeMs,
146
+ });
147
+ }
148
+ return out;
149
+ }
150
+
151
+ /** Synthetic project name for conversations whose cwd could not be resolved. */
152
+ const ANTIGRAVITY_UNGROUPED = "antigravity";
153
+
154
+ /** Returns one ProjectFolder per resolved cwd (grouped), plus a synthetic
155
+ * "antigravity" project for conversations without a cwd. */
156
+ export async function getAntigravityProjects(): Promise<ProjectFolder[]> {
157
+ const conversations = await resolveConversations();
158
+
159
+ const byName = new Map<string, { latest: number; path: string }>();
160
+ for (const c of conversations) {
161
+ const name = c.cwd ? encodeFolderName(c.cwd) : ANTIGRAVITY_UNGROUPED;
162
+ const path = c.cwd ?? "antigravity";
163
+ const existing = byName.get(name);
164
+ if (!existing || c.mtimeMs > existing.latest) {
165
+ byName.set(name, { latest: c.mtimeMs, path });
166
+ }
167
+ }
168
+
169
+ const folders: ProjectFolder[] = [];
170
+ for (const [name, { latest, path }] of byName) {
171
+ const lastModified = new Date(latest);
172
+ folders.push({
173
+ name,
174
+ path,
175
+ isDirectory: true,
176
+ lastModified,
177
+ lastModifiedFormatted: formatDate(lastModified),
178
+ cli: ["antigravity"],
179
+ });
180
+ }
181
+ folders.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
182
+ return folders;
183
+ }
184
+
185
+ export interface AntigravityProjectByName {
186
+ cwd: string | null;
187
+ sessions: SessionFile[];
188
+ }
189
+
190
+ /** Resolve the Antigravity conversations for a project URL slug (an encoded-cwd
191
+ * folder name, or the synthetic "antigravity" bucket). */
192
+ export async function getAntigravitySessionsByEncodedName(
193
+ name: string,
194
+ ): Promise<AntigravityProjectByName> {
195
+ const conversations = await resolveConversations();
196
+ const matched = conversations.filter((c) => {
197
+ const encoded = c.cwd ? encodeFolderName(c.cwd) : ANTIGRAVITY_UNGROUPED;
198
+ return encoded === name;
199
+ });
200
+ if (matched.length === 0) return { cwd: null, sessions: [] };
201
+
202
+ const sorted = [...matched].sort((a, b) => b.mtimeMs - a.mtimeMs);
203
+ const cwd = sorted.find((c) => c.cwd)?.cwd ?? (name === ANTIGRAVITY_UNGROUPED ? null : decodeFolderName(name));
204
+
205
+ const sessions: SessionFile[] = sorted.map((c) => {
206
+ const lastModified = new Date(c.mtimeMs);
207
+ return {
208
+ name: c.title ?? c.conversationId,
209
+ path: `antigravity://${c.conversationId}`,
210
+ lastModified,
211
+ lastModifiedFormatted: formatDate(lastModified),
212
+ sessionId: c.conversationId,
213
+ cli: "antigravity" as const,
214
+ };
215
+ });
216
+ return { cwd, sessions };
217
+ }
218
+
219
+ export const getCachedAntigravityProjects = runtimeCache(getAntigravityProjects, 30);
220
+ export const getCachedAntigravitySessionsByEncodedName = runtimeCache(
221
+ (name: string) => getAntigravitySessionsByEncodedName(name),
222
+ 30,
223
+ { maxSize: 50 },
224
+ );