failproofai 0.0.10 → 0.0.11-beta.2

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 (279) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +7 -7
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +4 -4
  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 +4 -4
  8. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  13. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  14. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +4 -4
  18. package/.next/standalone/.next/server/app/_not-found/page/next-font-manifest.json +1 -1
  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 +4 -4
  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/download/[project]/[session]/route.js +1 -1
  32. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/index.html +1 -1
  34. package/.next/standalone/.next/server/app/index.rsc +16 -16
  35. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  36. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +16 -16
  37. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  38. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  39. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +3 -3
  40. package/.next/standalone/.next/server/app/page/build-manifest.json +4 -4
  41. package/.next/standalone/.next/server/app/page/next-font-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  43. package/.next/standalone/.next/server/app/page.js +4 -4
  44. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +4 -4
  47. package/.next/standalone/.next/server/app/policies/page/next-font-manifest.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  49. package/.next/standalone/.next/server/app/policies/page.js +4 -4
  50. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +4 -4
  53. package/.next/standalone/.next/server/app/project/[name]/page/next-font-manifest.json +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 +4 -4
  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/build-manifest.json +4 -4
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/next-font-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  61. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  62. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +4 -4
  63. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +4 -4
  66. package/.next/standalone/.next/server/app/projects/page/next-font-manifest.json +1 -1
  67. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  68. package/.next/standalone/.next/server/app/projects/page.js +4 -4
  69. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d_ob4n._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__044xt9.._.js → [root-of-the-server]__0fwb7ao._.js} +2 -2
  73. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g48iv.._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0j8-xkl._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0bdfoky.js +1 -1
  76. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_05pz9._._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-wn51s._.js +4 -0
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01as125._.js +3 -0
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__098zro9._.js +19 -0
  81. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__02r.cjq._.js → [root-of-the-server]__09v.ljl._.js} +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0agrcb8._.js +4 -0
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0b7hkr~._.js +3 -0
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ehh6vp._.js +4 -0
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0g8l0tu._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0j4l6hl._.js +3 -0
  87. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ye1w50._.js → [root-of-the-server]__0k5n2kz._.js} +3 -3
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lp08ll._.js +3 -0
  89. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0yaqw._.js +4 -0
  90. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0o21f.o._.js +3 -0
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t8juvy._.js +4 -0
  92. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__10xgshr._.js → [root-of-the-server]__0tcyn68._.js} +2 -2
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ts150~._.js +3 -0
  94. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0podumr._.js → [root-of-the-server]__0uylufv._.js} +3 -3
  95. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ymlddl._.js +5 -5
  96. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0~03grs._.js +3 -0
  97. package/.next/standalone/.next/server/chunks/ssr/app_0cdqd9w._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/lib_utils_ts_068jk73._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/ssr/node_modules_0ttbz1~._.js +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_06u0kr8._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_0h9llsw._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0a_7sdg.js +2 -2
  105. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0ef3uwk.js +2 -2
  106. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0j79~gv.js +2 -2
  107. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0pbja1x.js +2 -2
  108. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0r6o0i2.js +2 -2
  109. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_11y81~_.js +2 -2
  110. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_12or2kf.js +2 -2
  111. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_0mebn66._.js +1 -1
  112. package/.next/standalone/.next/server/functions-config-manifest.json +2 -2
  113. package/.next/standalone/.next/server/middleware-build-manifest.js +7 -7
  114. package/.next/standalone/.next/server/next-font-manifest.js +1 -1
  115. package/.next/standalone/.next/server/next-font-manifest.json +6 -6
  116. package/.next/standalone/.next/server/pages/404.html +1 -1
  117. package/.next/standalone/.next/server/pages/500.html +1 -1
  118. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  120. package/.next/standalone/.next/static/chunks/07kpqoo7kuckx.js +6 -0
  121. package/.next/standalone/.next/static/chunks/0a40sy4tk8ioe.js +1 -0
  122. package/.next/standalone/.next/static/chunks/{12l2t63hkyo2q.js → 0azb~vy9ds_uy.js} +1 -1
  123. package/.next/standalone/.next/static/chunks/{0j171xiqge4rv.js → 0bke.~atnsbeb.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/{0lt8ko3lw.5yt.js → 0bv1oyxspkpkb.js} +1 -1
  125. package/.next/standalone/.next/static/chunks/{179yytvmam0ug.js → 0dvhi-prcsh3~.js} +1 -1
  126. package/.next/standalone/.next/static/chunks/0f5p9plm.aqlp.css +2 -0
  127. package/.next/standalone/.next/static/chunks/0ffvlbgzgnlw7.js +2 -0
  128. package/.next/standalone/.next/static/chunks/{150i0n26fnvso.js → 0n1n67imq.udf.js} +1 -1
  129. package/.next/standalone/.next/static/chunks/0spktq7xqab9h.js +1 -0
  130. package/.next/standalone/.next/static/chunks/{14lii11wmo450.js → 118q3uljozd5z.js} +1 -1
  131. package/.next/standalone/.next/static/chunks/{0pkl..xgo-qox.js → 11w14gnqzprir.js} +1 -1
  132. package/.next/standalone/.next/static/chunks/{0rnqmir4cd5p9.js → 17mubwtqwijpu.js} +1 -1
  133. package/.next/standalone/.next/static/chunks/{turbopack-05z7a19q43zfq.js → turbopack-0nh.aopesgj~5.js} +1 -1
  134. package/.next/standalone/.next/static/media/4fa387ec64143e14-s.0.qu-9752pffj.woff2 +0 -0
  135. package/.next/standalone/.next/static/media/5ce348bf30bf5439-s.0ee55_hj9qcer.woff2 +0 -0
  136. package/.next/standalone/.next/static/media/6306c77e7c8268e4-s.0mao5jbfbduzp.woff2 +0 -0
  137. package/.next/standalone/.next/static/media/797e433ab948586e-s.p.09zddjkbdep5a.woff2 +0 -0
  138. package/.next/standalone/.next/static/media/7d817b4c03b0c5f1-s.0uzt.a6d44yda.woff2 +0 -0
  139. package/.next/standalone/.next/static/media/bbc41e54d2fcbd21-s.0mvwgmnhv29no.woff2 +0 -0
  140. package/.next/standalone/.next/static/{dAuQps6jUwCz9X1Q5FFOO → tGVQM5SE3NvbVu0gbAJm7}/_clientMiddlewareManifest.js +2 -2
  141. package/.next/standalone/app/policies/hooks-client.tsx +111 -14
  142. package/.next/standalone/components/navbar.tsx +1 -1
  143. package/.next/standalone/components/reach-developers.tsx +2 -2
  144. package/.next/standalone/lib/claude-sessions.ts +181 -0
  145. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  146. package/.next/standalone/node_modules/next/dist/build/static-paths/app.js +2 -1
  147. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  148. package/.next/standalone/node_modules/next/dist/build/utils.js +2 -1
  149. package/.next/standalone/node_modules/next/dist/client/components/router-reducer/fetch-server-response.js +2 -2
  150. package/.next/standalone/node_modules/next/dist/client/components/router-reducer/set-cache-busting-search-param.js +8 -2
  151. package/.next/standalone/node_modules/next/dist/client/route-params.js +23 -6
  152. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +13 -13
  153. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +11 -11
  154. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +2 -2
  155. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +10 -10
  156. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  157. package/.next/standalone/node_modules/next/dist/server/app-render/action-handler.js +3 -6
  158. package/.next/standalone/node_modules/next/dist/server/app-render/app-render.js +62 -9
  159. package/.next/standalone/node_modules/next/dist/server/app-render/collect-segment-data.js +16 -0
  160. package/.next/standalone/node_modules/next/dist/server/app-render/create-component-tree.js +49 -19
  161. package/.next/standalone/node_modules/next/dist/server/app-render/get-script-nonce-from-header.js +8 -20
  162. package/.next/standalone/node_modules/next/dist/server/app-render/metadata-insertion/create-server-inserted-metadata.js +8 -7
  163. package/.next/standalone/node_modules/next/dist/server/app-render/use-flight-response.js +2 -2
  164. package/.next/standalone/node_modules/next/dist/server/async-storage/work-store.js +2 -1
  165. package/.next/standalone/node_modules/next/dist/server/base-server.js +13 -5
  166. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  167. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  168. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  169. package/.next/standalone/node_modules/next/dist/server/dev/static-paths-worker.js +2 -1
  170. package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +22 -2
  171. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  172. package/.next/standalone/node_modules/next/dist/server/lib/is-rsc-request.js +18 -0
  173. package/.next/standalone/node_modules/next/dist/server/lib/mock-request.js +30 -5
  174. package/.next/standalone/node_modules/next/dist/server/lib/patch-set-header.js +7 -0
  175. package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +6 -3
  176. package/.next/standalone/node_modules/next/dist/server/lib/router-utils/resolve-routes.js +18 -4
  177. package/.next/standalone/node_modules/next/dist/server/lib/server-ipc/utils.js +3 -1
  178. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  179. package/.next/standalone/node_modules/next/dist/server/next-server.js +1 -1
  180. package/.next/standalone/node_modules/next/dist/server/request/fallback-params.js +27 -1
  181. package/.next/standalone/node_modules/next/dist/server/route-modules/app-route/module.js +1 -0
  182. package/.next/standalone/node_modules/next/dist/server/route-modules/route-module.js +11 -1
  183. package/.next/standalone/node_modules/next/dist/server/server-utils.js +19 -2
  184. package/.next/standalone/node_modules/next/dist/server/stream-utils/node-web-streams-helper.js +5 -5
  185. package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +1 -1
  186. package/.next/standalone/node_modules/next/dist/server/web/adapter.js +4 -1
  187. package/.next/standalone/node_modules/next/dist/server/web/edge-route-module-wrapper.js +2 -1
  188. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  189. package/.next/standalone/node_modules/next/dist/{server → shared/lib}/htmlescape.js +15 -0
  190. package/.next/standalone/node_modules/next/dist/shared/lib/router/routes/app.js +13 -1
  191. package/.next/standalone/node_modules/next/dist/shared/lib/router/utils/cache-busting-search-param.js +56 -10
  192. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  193. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  194. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  195. package/.next/standalone/node_modules/next/package.json +15 -15
  196. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  197. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  198. package/.next/standalone/node_modules/react/package.json +1 -1
  199. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  200. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  201. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  202. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  203. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  204. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  205. package/.next/standalone/node_modules/react-dom/package.json +2 -2
  206. package/.next/standalone/package.json +5 -5
  207. package/.next/standalone/proxy.ts +1 -1
  208. package/.next/standalone/server.js +1 -1
  209. package/README.md +4 -4
  210. package/bin/failproofai.mjs +230 -73
  211. package/dist/cli.mjs +3028 -1453
  212. package/lib/claude-sessions.ts +181 -0
  213. package/package.json +5 -5
  214. package/scripts/launch.ts +1 -1
  215. package/scripts/postinstall.mjs +89 -1
  216. package/src/audit/cache.ts +113 -0
  217. package/src/audit/cli-adapters/claude.ts +97 -0
  218. package/src/audit/cli-adapters/codex.ts +56 -0
  219. package/src/audit/cli-adapters/copilot.ts +51 -0
  220. package/src/audit/cli-adapters/cursor.ts +51 -0
  221. package/src/audit/cli-adapters/gemini.ts +51 -0
  222. package/src/audit/cli-adapters/index.ts +70 -0
  223. package/src/audit/cli-adapters/opencode.ts +52 -0
  224. package/src/audit/cli-adapters/pi.ts +51 -0
  225. package/src/audit/cli-adapters/shared.ts +85 -0
  226. package/src/audit/detectors/find-from-root.ts +27 -0
  227. package/src/audit/detectors/git-commit-no-verify.ts +22 -0
  228. package/src/audit/detectors/index.ts +33 -0
  229. package/src/audit/detectors/prefer-edit-over-read-cat.ts +31 -0
  230. package/src/audit/detectors/prefer-edit-over-sed-awk.ts +27 -0
  231. package/src/audit/detectors/prefer-write-over-heredoc.ts +36 -0
  232. package/src/audit/detectors/redundant-cd-cwd.ts +28 -0
  233. package/src/audit/detectors/reread-after-edit.ts +58 -0
  234. package/src/audit/detectors/sleep-polling-loop.ts +34 -0
  235. package/src/audit/index.ts +369 -0
  236. package/src/audit/replay.ts +121 -0
  237. package/src/audit/report.ts +349 -0
  238. package/src/audit/telemetry.ts +113 -0
  239. package/src/audit/types.ts +193 -0
  240. package/src/hooks/builtin-policies.ts +79 -1
  241. package/src/hooks/custom-hooks-loader.ts +19 -3
  242. package/src/hooks/first-run-nudge.ts +146 -0
  243. package/src/hooks/handler.ts +21 -102
  244. package/src/hooks/install-prompt.ts +34 -4
  245. package/src/hooks/manager.ts +72 -5
  246. package/src/hooks/policy-evaluator.ts +19 -4
  247. package/src/hooks/policy-registry.ts +1 -1
  248. package/src/hooks/policy-types.ts +9 -0
  249. package/src/hooks/tool-name-canonicalize.ts +65 -0
  250. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0609ezh._.js +0 -3
  251. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07_-mkc._.js +0 -3
  252. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09z7o2x._.js +0 -19
  253. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0_sh2n0._.js +0 -3
  254. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e9o9ri._.js +0 -4
  255. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0l6swv1._.js +0 -3
  256. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0logebz._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0mi5ejy._.js +0 -4
  258. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0odijkc._.js +0 -3
  259. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rkxer-._.js +0 -3
  260. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rl2kwi._.js +0 -4
  261. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0vg0uey._.js +0 -4
  262. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0x5limi._.js +0 -3
  263. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__10._f0s._.js +0 -4
  264. package/.next/standalone/.next/static/chunks/01q52wg_amm60.js +0 -2
  265. package/.next/standalone/.next/static/chunks/0kqar56yl~41o.js +0 -6
  266. package/.next/standalone/.next/static/chunks/0ml1.ck_5t36i.js +0 -1
  267. package/.next/standalone/.next/static/chunks/0zig0fh30t6ou.js +0 -1
  268. package/.next/standalone/.next/static/chunks/17rm86uz2nd5a.css +0 -2
  269. package/.next/standalone/.next/static/media/4fa387ec64143e14-s.0q3udbd2bu5yp.woff2 +0 -0
  270. package/.next/standalone/.next/static/media/797e433ab948586e-s.p.0.q-h669a_dqa.woff2 +0 -0
  271. package/.next/standalone/.next/static/media/bbc41e54d2fcbd21-s.0gw~uztddq1df.woff2 +0 -0
  272. package/src/auth/login.ts +0 -104
  273. package/src/auth/logout.ts +0 -50
  274. package/src/auth/token-store.ts +0 -64
  275. package/src/relay/daemon.ts +0 -362
  276. package/src/relay/pid.ts +0 -76
  277. package/src/relay/queue.ts +0 -225
  278. /package/.next/standalone/.next/static/{dAuQps6jUwCz9X1Q5FFOO → tGVQM5SE3NvbVu0gbAJm7}/_buildManifest.js +0 -0
  279. /package/.next/standalone/.next/static/{dAuQps6jUwCz9X1Q5FFOO → tGVQM5SE3NvbVu0gbAJm7}/_ssgManifest.js +0 -0
@@ -19,15 +19,8 @@ import {
19
19
  CURSOR_EVENT_MAP,
20
20
  PI_EVENT_MAP,
21
21
  GEMINI_EVENT_MAP,
22
- GEMINI_TOOL_MAP,
23
- COPILOT_TOOL_MAP,
24
- CURSOR_TOOL_MAP,
25
- CODEX_TOOL_MAP,
26
- OPENCODE_TOOL_MAP,
27
- OPENCODE_TOOL_INPUT_MAP,
28
- PI_TOOL_MAP,
29
- PI_TOOL_INPUT_MAP,
30
22
  } from "./types";
23
+ import { canonicalizeToolName, canonicalizeToolInput } from "./tool-name-canonicalize";
31
24
  import type { PolicyFunction, PolicyResult } from "./policy-types";
32
25
  import { readMergedHooksConfig } from "./hooks-config";
33
26
  import { registerBuiltinPolicies } from "./builtin-policies";
@@ -77,80 +70,6 @@ function canonicalizeEventType(raw: string, cli: IntegrationType): HookEventType
77
70
  return raw as HookEventType;
78
71
  }
79
72
 
80
- /**
81
- * Canonicalize a per-CLI tool name to the Claude PascalCase form that builtin
82
- * policies match on (e.g. `Bash`, `Read`, `Write`, `Edit`). The registry filter
83
- * at policy-registry.ts:93-95 is case-sensitive `Array.includes`, so any
84
- * mismatch silently no-ops every Bash/Read/Write/Edit builtin.
85
- *
86
- * Per-CLI tool-name shapes (verified from in-repo evidence and vendor docs):
87
- * • Claude: PascalCase native — passthrough
88
- * • Codex: `Bash` PascalCase passthrough; `apply_patch` → `Edit`,
89
- * `write_stdin` → `Bash` via CODEX_TOOL_MAP
90
- * • Copilot: lowercase IDs (`bash`, `read`, `view`, …) — COPILOT_TOOL_MAP
91
- * • Cursor: PascalCase per Cursor docs but uses `Shell` for the bash-
92
- * equivalent — CURSOR_TOOL_MAP rewrites `Shell → Bash`; other
93
- * tool names already canonical and pass through
94
- * • OpenCode: lowercase IDs (`bash`, `read`, …) — OPENCODE_TOOL_MAP. The
95
- * OpenCode plugin shim ALSO canonicalizes inline as defense-in-
96
- * depth; both passes are idempotent. Handler-side coverage
97
- * here means a stale user-scope shim that pre-dates #337 still
98
- * gets the canonicalization, without forcing a re-install.
99
- * • Pi: lowercase IDs (`bash`, `read`, …) — PI_TOOL_MAP. Same dual-
100
- * canonicalization story as OpenCode (shim + handler).
101
- * • Gemini: snake_case — GEMINI_TOOL_MAP
102
- *
103
- * Unknown tool names (MCP `mcp_*`, third-party extensions, Skills) pass
104
- * through unchanged so non-builtin tooling isn't lost.
105
- */
106
- function canonicalizeToolName(raw: string | undefined, cli: IntegrationType): string | undefined {
107
- if (!raw) return raw;
108
- if (cli === "copilot") return COPILOT_TOOL_MAP[raw] ?? raw;
109
- if (cli === "cursor") return CURSOR_TOOL_MAP[raw] ?? raw;
110
- if (cli === "codex") return CODEX_TOOL_MAP[raw] ?? raw;
111
- if (cli === "gemini") return GEMINI_TOOL_MAP[raw] ?? raw;
112
- if (cli === "opencode") return OPENCODE_TOOL_MAP[raw] ?? raw;
113
- if (cli === "pi") return PI_TOOL_MAP[raw] ?? raw;
114
- return raw;
115
- }
116
-
117
- /**
118
- * Canonicalize per-CLI tool-input keys to the snake_case shape that builtin
119
- * policies read (e.g. `file_path`, `old_string`). OpenCode delivers args as
120
- * camelCase (`filePath`, `oldString`, `newString`, `replaceAll`); Pi delivers
121
- * `path` for Read/Write/Edit. Without translation, `getFilePath()` reads "" and
122
- * the path-checking builtins (`block-read-outside-cwd`, `block-env-files`,
123
- * `block-secrets-write`) silently no-op.
124
- *
125
- * Both CLIs' shims canonicalize inline before the JSON crosses to this binary.
126
- * Handler-side coverage here is defense-in-depth: a user-scope shim that pre-
127
- * dates #337 still passes the raw camelCase keys, and we want those installs
128
- * to start enforcing the moment failproofai upgrades — without requiring a
129
- * `failproofai policies --install --cli opencode` re-run.
130
- *
131
- * Idempotent: when the shim already canonicalized, the keys are snake_case
132
- * and the per-tool map's camelCase keys don't match, so the loop is a no-op.
133
- *
134
- * Tools outside the per-CLI map (MCP `mcp_*`, third-party extensions) pass
135
- * through unchanged so their schemas aren't corrupted.
136
- */
137
- function canonicalizeToolInput(
138
- toolName: string | undefined,
139
- rawInput: unknown,
140
- cli: IntegrationType,
141
- ): unknown {
142
- if (!toolName || !rawInput || typeof rawInput !== "object") return rawInput;
143
- let perToolMap: Record<string, string> | undefined;
144
- if (cli === "opencode") perToolMap = OPENCODE_TOOL_INPUT_MAP[toolName];
145
- else if (cli === "pi") perToolMap = PI_TOOL_INPUT_MAP[toolName];
146
- if (!perToolMap) return rawInput;
147
- const out: Record<string, unknown> = {};
148
- for (const [k, v] of Object.entries(rawInput as Record<string, unknown>)) {
149
- out[perToolMap[k] ?? k] = v;
150
- }
151
- return out;
152
- }
153
-
154
73
  export async function handleHookEvent(
155
74
  eventType: string,
156
75
  cli: IntegrationType = "claude",
@@ -160,6 +79,7 @@ export async function handleHookEvent(
160
79
  // Read stdin payload (Claude passes JSON)
161
80
  const MAX_STDIN_BYTES = 1_048_576; // 1 MB
162
81
  let payload = "";
82
+ let stdinOversized = false;
163
83
  try {
164
84
  payload = await new Promise<string>((resolve, reject) => {
165
85
  const chunks: string[] = [];
@@ -169,6 +89,7 @@ export async function handleHookEvent(
169
89
  totalBytes += Buffer.byteLength(chunk);
170
90
  if (totalBytes > MAX_STDIN_BYTES) {
171
91
  hookLogWarn(`stdin payload exceeds 1 MB for ${eventType}, discarding`);
92
+ stdinOversized = true;
172
93
  process.stdin.destroy();
173
94
  resolve("");
174
95
  return;
@@ -180,8 +101,20 @@ export async function handleHookEvent(
180
101
  // If stdin is already closed or not piped, resolve immediately
181
102
  if (process.stdin.readableEnded) resolve("");
182
103
  });
183
- } catch {
104
+ } catch (err) {
184
105
  hookLogWarn(`stdin read failed for ${eventType}`);
106
+ void trackHookEvent(getInstanceId(), "hook_stdin_error", {
107
+ event_type: eventType,
108
+ cli,
109
+ error_type: err instanceof Error ? err.name : "unknown",
110
+ });
111
+ }
112
+ if (stdinOversized) {
113
+ void trackHookEvent(getInstanceId(), "hook_stdin_error", {
114
+ event_type: eventType,
115
+ cli,
116
+ error_type: "oversized",
117
+ });
185
118
  }
186
119
 
187
120
  let parsed: Record<string, unknown> = {};
@@ -190,6 +123,11 @@ export async function handleHookEvent(
190
123
  parsed = JSON.parse(payload) as Record<string, unknown>;
191
124
  } catch {
192
125
  hookLogWarn(`payload parse failed for ${eventType} (${payload.length} bytes)`);
126
+ void trackHookEvent(getInstanceId(), "hook_payload_parse_error", {
127
+ event_type: eventType,
128
+ cli,
129
+ payload_size: payload.length,
130
+ });
193
131
  }
194
132
  }
195
133
 
@@ -340,25 +278,6 @@ export async function handleHookEvent(
340
278
  hookLogWarn("activity persistence failed");
341
279
  }
342
280
 
343
- // Enqueue for server relay — fire-and-forget, never blocks hook.
344
- // queue.ts is a no-op if the user is not logged in (no auth.json), and
345
- // sanitizes the entry before persisting (drops toolInput/transcriptPath,
346
- // hashes cwd, redacts known secret patterns in `reason`).
347
- try {
348
- const { appendToServerQueue } = await import("../relay/queue");
349
- appendToServerQueue(activityEntry);
350
- } catch {
351
- // Server queue is best-effort; fail-open
352
- }
353
-
354
- // Lazy-start relay daemon if user is logged in — ~1ms when already running
355
- try {
356
- const { ensureRelayRunning } = await import("../relay/daemon");
357
- ensureRelayRunning();
358
- } catch {
359
- // Relay is best-effort; hook must succeed regardless
360
- }
361
-
362
281
  // Fire PostHog telemetry for decisions that affect Claude's behavior
363
282
  if (result.decision === "deny" || result.decision === "instruct") {
364
283
  try {
@@ -13,6 +13,8 @@ import * as readline from "node:readline";
13
13
  import { BUILTIN_POLICIES } from "./builtin-policies";
14
14
  import { detectInstalledClis, getIntegration } from "./integrations";
15
15
  import { INTEGRATION_TYPES, type IntegrationType } from "./types";
16
+ import { trackHookEvent } from "./hook-telemetry";
17
+ import { getInstanceId } from "../../lib/telemetry-id";
16
18
 
17
19
  interface SelectItem {
18
20
  name: string;
@@ -51,9 +53,29 @@ export async function resolveTargetClis(
51
53
  explicit?: IntegrationType[],
52
54
  action: CliPromptAction = "install",
53
55
  ): Promise<IntegrationType[]> {
54
- if (explicit && explicit.length > 0) return [...new Set(explicit)];
56
+ const detected = explicit && explicit.length > 0 ? [] : detectInstalledClis();
57
+ const stdinIsTty = !!process.stdin.isTTY;
58
+ const explicitList = explicit && explicit.length > 0 ? [...new Set(explicit)] : [];
59
+
60
+ const fireDetectionEvent = (
61
+ selected: IntegrationType[],
62
+ resolutionMode: "explicit" | "single_detected" | "all_detected" | "interactive_prompt" | "defaulted_to_claude",
63
+ ): void => {
64
+ void trackHookEvent(getInstanceId(), "cli_detection_summary", {
65
+ action,
66
+ detected_clis: detected,
67
+ explicit_clis: explicitList,
68
+ selected_clis: selected,
69
+ defaulted_to_claude: resolutionMode === "defaulted_to_claude",
70
+ stdin_is_tty: stdinIsTty,
71
+ resolution_mode: resolutionMode,
72
+ });
73
+ };
55
74
 
56
- const detected = detectInstalledClis();
75
+ if (explicit && explicit.length > 0) {
76
+ fireDetectionEvent(explicitList, "explicit");
77
+ return explicitList;
78
+ }
57
79
 
58
80
  if (detected.length === 0) {
59
81
  if (action === "uninstall") {
@@ -63,12 +85,14 @@ export async function resolveTargetClis(
63
85
  "\x1B[33mWarning: no agent CLI binary found in PATH (claude, codex, copilot, cursor-agent, opencode, pi, gemini). " +
64
86
  "Defaulting to Claude Code; nothing will be removed if no settings file exists.\x1B[0m",
65
87
  );
88
+ fireDetectionEvent(["claude"], "defaulted_to_claude");
66
89
  return ["claude"];
67
90
  }
68
91
  console.log(
69
92
  "\x1B[33mWarning: no agent CLI binary found in PATH (claude, codex, copilot, cursor-agent, opencode, pi, gemini). " +
70
93
  "Defaulting to Claude Code; hooks will activate when an agent is installed.\x1B[0m",
71
94
  );
95
+ fireDetectionEvent(["claude"], "defaulted_to_claude");
72
96
  return ["claude"];
73
97
  }
74
98
 
@@ -76,13 +100,19 @@ export async function resolveTargetClis(
76
100
  const integration = getIntegration(detected[0]);
77
101
  const verb = action === "uninstall" ? "removing hooks from" : "installing hooks for";
78
102
  console.log(`Detected ${integration.displayName}; ${verb} it.`);
103
+ fireDetectionEvent(detected, "single_detected");
79
104
  return detected;
80
105
  }
81
106
 
82
107
  // Multiple detected. Prompt or default.
83
- if (!process.stdin.isTTY) return detected; // non-interactive: install/remove for all detected
108
+ if (!process.stdin.isTTY) {
109
+ fireDetectionEvent(detected, "all_detected");
110
+ return detected;
111
+ }
84
112
 
85
- return promptCliTargetSelection(detected, action);
113
+ const selected = await promptCliTargetSelection(detected, action);
114
+ fireDetectionEvent(selected, "interactive_prompt");
115
+ return selected;
86
116
  }
87
117
 
88
118
  /** Selectable row in the CLI target menu. Exported for unit tests. */
@@ -127,6 +127,13 @@ export async function installHooks(
127
127
  for (const cliId of selectedClis) {
128
128
  const integration = getIntegration(cliId);
129
129
  if (!integration.scopes.includes(scope)) {
130
+ try {
131
+ await trackHookEvent(getInstanceId(), "scope_validation_failed", {
132
+ cli: cliId,
133
+ scope,
134
+ supported_scopes: integration.scopes,
135
+ });
136
+ } catch {}
130
137
  throw new CliError(
131
138
  `Scope "${scope}" is not supported by ${integration.displayName}. ` +
132
139
  `Valid scopes: ${integration.scopes.join(", ")}`
@@ -171,10 +178,23 @@ export async function installHooks(
171
178
  try {
172
179
  validatedHooks = await loadCustomHooks(configToWrite.customPoliciesPath, { strict: true });
173
180
  } catch (err) {
174
- console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
181
+ const msg = err instanceof Error ? err.message : String(err);
182
+ try {
183
+ await trackHookEvent(getInstanceId(), "custom_policy_validation_failed", {
184
+ scope,
185
+ error_type: /not found/i.test(msg) ? "file_not_found" : "load_error",
186
+ });
187
+ } catch {}
188
+ console.error(`Error: ${msg}`);
175
189
  process.exit(1);
176
190
  }
177
191
  if (validatedHooks.length === 0) {
192
+ try {
193
+ await trackHookEvent(getInstanceId(), "custom_policy_validation_failed", {
194
+ scope,
195
+ error_type: "no_hooks_registered",
196
+ });
197
+ } catch {}
178
198
  console.error(
179
199
  `Error: no hooks registered in ${customPoliciesPath}. ` +
180
200
  `Make sure your file calls customPolicies.add(...) at least once.`,
@@ -198,10 +218,26 @@ export async function installHooks(
198
218
  for (const cliId of selectedClis) {
199
219
  const integration = getIntegration(cliId);
200
220
  const settingsPath = integration.getSettingsPath(scope, cwd);
201
- const settings = integration.readSettings(settingsPath);
202
- integration.writeHookEntries(settings, binaryPath, scope);
203
- integration.writeSettings(settingsPath, settings);
204
- writtenSettingsPaths.push({ cli: cliId, path: settingsPath });
221
+ try {
222
+ const settings = integration.readSettings(settingsPath);
223
+ integration.writeHookEntries(settings, binaryPath, scope);
224
+ integration.writeSettings(settingsPath, settings);
225
+ writtenSettingsPaths.push({ cli: cliId, path: settingsPath });
226
+ } catch (err) {
227
+ const errorType = err instanceof Error && /EACCES|EPERM/.test(err.message)
228
+ ? "permission_denied"
229
+ : err instanceof Error && /ENOENT|ENOTDIR/.test(err.message)
230
+ ? "path_not_found"
231
+ : "write_error";
232
+ try {
233
+ await trackHookEvent(getInstanceId(), "hook_write_failed", {
234
+ cli: cliId,
235
+ scope,
236
+ error_type: errorType,
237
+ });
238
+ } catch {}
239
+ throw err;
240
+ }
205
241
  }
206
242
 
207
243
  // Telemetry: track successful hook installation (with diff vs previous config)
@@ -228,6 +264,20 @@ export async function installHooks(
228
264
  param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
229
265
  command_format: scope === "project" ? "npx" : "absolute",
230
266
  });
267
+
268
+ if (includeBeta) {
269
+ const betaNames = new Set(BUILTIN_POLICIES.filter((p) => p.beta).map((p) => p.name));
270
+ const installedBeta = selectedPolicies.filter((p) => betaNames.has(p));
271
+ if (installedBeta.length > 0) {
272
+ await trackHookEvent(distinctId, "beta_policies_installed", {
273
+ scope,
274
+ cli: selectedClis,
275
+ beta_count: installedBeta.length,
276
+ beta_policy_names: installedBeta,
277
+ ...(source ? { source } : {}),
278
+ });
279
+ }
280
+ }
231
281
  } catch {
232
282
  // Telemetry is best-effort — never block the operation
233
283
  }
@@ -257,6 +307,13 @@ export async function installHooks(
257
307
  console.log(`Having hooks in multiple scopes may cause duplicate policy evaluation.`);
258
308
  console.log(`Use \`failproofai policies --uninstall --scope ${duplicates[0]}\` to remove the other installation,`);
259
309
  console.log(`or \`failproofai policies\` to see all scopes.`);
310
+ try {
311
+ await trackHookEvent(getInstanceId(), "multi_scope_warning_shown", {
312
+ new_scope: scope,
313
+ existing_scopes: duplicates,
314
+ cli: selectedClis,
315
+ });
316
+ } catch {}
260
317
  }
261
318
  }
262
319
 
@@ -558,11 +615,21 @@ export async function listHooks(cwd?: string): Promise<void> {
558
615
 
559
616
  // Warn about unknown policyParams keys
560
617
  if (config.policyParams) {
618
+ const unknownKeys: string[] = [];
561
619
  for (const key of Object.keys(config.policyParams)) {
562
620
  if (!builtinPolicyNames.has(key)) {
563
621
  console.log(` \x1B[33mWarning: unknown policyParams key "${key}" — possible typo\x1B[0m`);
622
+ unknownKeys.push(key);
564
623
  }
565
624
  }
625
+ if (unknownKeys.length > 0) {
626
+ try {
627
+ await trackHookEvent(getInstanceId(), "policy_params_validation_warning", {
628
+ unknown_keys_count: unknownKeys.length,
629
+ unknown_keys: unknownKeys,
630
+ });
631
+ } catch {}
632
+ }
566
633
  }
567
634
 
568
635
  // Custom Policies section
@@ -7,6 +7,8 @@ import type { PolicyContext, HooksConfig } from "./policy-types";
7
7
  import { BUILTIN_POLICIES } from "./builtin-policies";
8
8
  import { DEFAULT_POLICY_NAMESPACE, getPoliciesForEvent, normalizePolicyName } from "./policy-registry";
9
9
  import { hookLogInfo, hookLogWarn } from "./hook-logger";
10
+ import { trackHookEvent } from "./hook-telemetry";
11
+ import { getInstanceId } from "../../lib/telemetry-id";
10
12
 
11
13
  function appendHint(baseReason: string, hint: unknown): string {
12
14
  const base = baseReason.trim();
@@ -35,11 +37,11 @@ const POLICY_PARAMS_MAP = new Map(
35
37
  /**
36
38
  * Look up policy params for a canonical policy name in the user config,
37
39
  * tolerating either flat ("block-force-push") or qualified
38
- * ("exospherehost/block-force-push") config keys for built-in policies.
40
+ * ("failproofai/block-force-push") config keys for built-in policies.
39
41
  *
40
42
  * The flat-key fallback is intentionally limited to the default namespace
41
43
  * so namespace isolation is preserved: `policyParams.foo` only matches
42
- * `exospherehost/foo`, never `myorg/foo` or `custom/foo`.
44
+ * `failproofai/foo`, never `myorg/foo` or `custom/foo`.
43
45
  */
44
46
  function getConfigParamsFor(
45
47
  config: HooksConfig | undefined,
@@ -87,7 +89,7 @@ export async function evaluatePolicies(
87
89
 
88
90
  for (const policy of policies) {
89
91
  // Inject params: merge policyParams[policy.name] over schema defaults.
90
- // policy.name is canonical (e.g. "exospherehost/block-force-push"); user
92
+ // policy.name is canonical (e.g. "failproofai/block-force-push"); user
91
93
  // config keys may be flat or canonical — getConfigParamsFor accepts both.
92
94
  const schema = POLICY_PARAMS_MAP.get(policy.name);
93
95
  let ctx: PolicyContext;
@@ -107,7 +109,20 @@ export async function evaluatePolicies(
107
109
  try {
108
110
  result = await policy.fn(ctx);
109
111
  } catch (err) {
110
- hookLogWarn(`policy "${policy.name}" threw: ${err instanceof Error ? err.message : String(err)}`);
112
+ const msg = err instanceof Error ? err.message : String(err);
113
+ hookLogWarn(`policy "${policy.name}" threw: ${msg}`);
114
+ // Custom hooks are wrapped in handler.ts with their own try/catch that
115
+ // emits custom_hook_error. Anything reaching here is a builtin policy
116
+ // crash — track separately so we can surface regressions in builtins.
117
+ const isCustom = policy.name.startsWith("custom/") || policy.name.startsWith(".failproofai-");
118
+ if (!isCustom) {
119
+ void trackHookEvent(getInstanceId(), "policy_evaluation_error", {
120
+ policy_name: policy.name,
121
+ event_type: eventType,
122
+ cli: session?.cli ?? null,
123
+ error_type: err instanceof Error ? err.name : "unknown",
124
+ });
125
+ }
111
126
  continue;
112
127
  }
113
128
 
@@ -16,7 +16,7 @@ const INDEX_CACHE_KEY = "__FAILPROOFAI_POLICY_INDEX_CACHE__";
16
16
  * `<namespace>/` prefix. Builtins live under this namespace; custom hooks
17
17
  * loaded by the handler get their own prefixes (e.g. `custom/foo`).
18
18
  */
19
- export const DEFAULT_POLICY_NAMESPACE = "exospherehost";
19
+ export const DEFAULT_POLICY_NAMESPACE = "failproofai";
20
20
 
21
21
  /**
22
22
  * Canonicalize a policy name. If the name already contains a `/`, it is
@@ -54,6 +54,15 @@ export interface BuiltinPolicyDefinition {
54
54
  category: string;
55
55
  beta?: boolean;
56
56
  params?: PolicyParamsSchema;
57
+ /** User-facing past-tense phrase used in `failproofai audit` output.
58
+ * Frames the agent's action as something the user observes after-the-fact,
59
+ * e.g. "Tried to push to main branch" or "Redacted JWT from tool output".
60
+ * Falls back to `description` when omitted. */
61
+ displayTitle?: string;
62
+ /** One short clause describing the consequence of the action, used as a
63
+ * secondary line in the audit report. e.g. "Could leak code from neighboring
64
+ * repos to the model." */
65
+ impact?: string;
57
66
  }
58
67
 
59
68
  export interface CustomHook {
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Per-CLI canonicalization of tool names and tool-input keys.
3
+ *
4
+ * Extracted from handler.ts so the audit replay engine and the live hook
5
+ * handler share one implementation. Re-importing this module from
6
+ * `src/audit/cli-adapters/*.ts` keeps the per-CLI maps in one place.
7
+ */
8
+ import type { IntegrationType } from "./types";
9
+ import {
10
+ CODEX_TOOL_MAP,
11
+ COPILOT_TOOL_MAP,
12
+ CURSOR_TOOL_MAP,
13
+ OPENCODE_TOOL_MAP,
14
+ OPENCODE_TOOL_INPUT_MAP,
15
+ PI_TOOL_MAP,
16
+ PI_TOOL_INPUT_MAP,
17
+ GEMINI_TOOL_MAP,
18
+ } from "./types";
19
+
20
+ /**
21
+ * Canonicalize a per-CLI tool name to the Claude PascalCase form that builtin
22
+ * policies match on (e.g. `Bash`, `Read`, `Write`, `Edit`). Unknown tool names
23
+ * (MCP `mcp_*`, third-party extensions, Skills) pass through unchanged.
24
+ */
25
+ export function canonicalizeToolName(
26
+ raw: string | undefined,
27
+ cli: IntegrationType,
28
+ ): string | undefined {
29
+ if (!raw) return raw;
30
+ if (cli === "copilot") return COPILOT_TOOL_MAP[raw] ?? raw;
31
+ if (cli === "cursor") return CURSOR_TOOL_MAP[raw] ?? raw;
32
+ if (cli === "codex") return CODEX_TOOL_MAP[raw] ?? raw;
33
+ if (cli === "gemini") return GEMINI_TOOL_MAP[raw] ?? raw;
34
+ if (cli === "opencode") return OPENCODE_TOOL_MAP[raw] ?? raw;
35
+ if (cli === "pi") return PI_TOOL_MAP[raw] ?? raw;
36
+ return raw;
37
+ }
38
+
39
+ /**
40
+ * Canonicalize per-CLI tool-input keys to the snake_case shape that builtin
41
+ * policies read (e.g. `file_path`, `old_string`). OpenCode delivers args as
42
+ * camelCase; Pi delivers `path` for Read/Write/Edit. Idempotent — when already
43
+ * canonical the loop is a no-op.
44
+ */
45
+ export function canonicalizeToolInput(
46
+ toolName: string | undefined,
47
+ rawInput: unknown,
48
+ cli: IntegrationType,
49
+ ): unknown {
50
+ // Arrays are objects too — pass them through verbatim instead of letting
51
+ // Object.entries flatten them into a numeric-keyed plain object (which would
52
+ // silently corrupt array-shaped tool inputs).
53
+ if (!toolName || !rawInput || typeof rawInput !== "object" || Array.isArray(rawInput)) {
54
+ return rawInput;
55
+ }
56
+ let perToolMap: Record<string, string> | undefined;
57
+ if (cli === "opencode") perToolMap = OPENCODE_TOOL_INPUT_MAP[toolName];
58
+ else if (cli === "pi") perToolMap = PI_TOOL_INPUT_MAP[toolName];
59
+ if (!perToolMap) return rawInput;
60
+ const out: Record<string, unknown> = {};
61
+ for (const [k, v] of Object.entries(rawInput as Record<string, unknown>)) {
62
+ out[perToolMap[k] ?? k] = v;
63
+ }
64
+ return out;
65
+ }
@@ -1,3 +0,0 @@
1
- module.exports=[46786,(a,b,c)=>{b.exports=a.x("os",()=>require("os"))},12714,(a,b,c)=>{b.exports=a.x("node:fs/promises",()=>require("node:fs/promises"))},90798,a=>{"use strict";var b=a.i(46786),c=a.i(14747);a.s(["decodeFolderName",0,function(a){return/^[A-Za-z]--/.test(a)?a[0]+":/"+a.slice(3).replace(/-/g,"/"):a.replace(/-/g,"/")},"encodeFolderName",0,function(a){let b=/^([A-Za-z]):[\\/](.*)$/.exec(a);return b?b[1]+"--"+b[2].replace(/[\\/]/g,"-"):a.replace(/[\\/]/g,"-")},"getClaudeProjectsPath",0,function(){let a=process.env.CLAUDE_PROJECTS_PATH;return a||(0,c.join)((0,b.homedir)(),".claude","projects")}])},34900,a=>{"use strict";a.s(["runtimeCache",0,function(a,b,c){let d=new Map,e=new Map,f=c?.maxSize;return async(...c)=>{let g=JSON.stringify(c),h=d.get(g);if(h&&Date.now()<h.expiry)return h.data;let i=e.get(g);if(i)return i;let j=a(...c).then(a=>{if(e.delete(g),f&&d.size>=f){let a=d.keys().next().value;d.delete(a)}return d.set(g,{data:a,expiry:Date.now()+1e3*b}),a},a=>{throw e.delete(g),a});return e.set(g,j),j}}])},76668,a=>{"use strict";let b=1;function c(a){return`[failproofai${new Date().toISOString()}] ${a}`}a.s(["logError",0,function(a,b){void 0!==b?console.error(c("ERROR"),a,b):console.error(c("ERROR"),a)},"logWarn",0,function(a,d){b>=b&&(void 0!==d?console.warn(c("WARN"),a,d):console.warn(c("WARN"),a))}])},33432,a=>{"use strict";a.s(["formatDate",0,function(a){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).format(a)}])},26192,a=>{"use strict";async function b(a,b){let c=Array(a.length),d=0;async function e(){for(;d<a.length;){let b=d++;try{c[b]={status:"fulfilled",value:await a[b]()}}catch(a){c[b]={status:"rejected",reason:a}}}}let f=Array.from({length:Math.min(b,a.length)},()=>e());return await Promise.all(f),c}a.s(["batchAll",0,b])},50640,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"InvariantError",{enumerable:!0,get:function(){return d}});class d extends Error{constructor(a,b){super(`Invariant: ${a.endsWith(".")?a:a+"."} This is a bug in Next.js.`,b),this.name="InvariantError"}}},64240,(a,b,c)=>{"use strict";function d(a){if("function"!=typeof WeakMap)return null;var b=new WeakMap,c=new WeakMap;return(d=function(a){return a?c:b})(a)}c._=function(a,b){if(!b&&a&&a.__esModule)return a;if(null===a||"object"!=typeof a&&"function"!=typeof a)return{default:a};var c=d(b);if(c&&c.has(a))return c.get(a);var e={__proto__:null},f=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var g in a)if("default"!==g&&Object.prototype.hasOwnProperty.call(a,g)){var h=f?Object.getOwnPropertyDescriptor(a,g):null;h&&(h.get||h.set)?Object.defineProperty(e,g,h):e[g]=a[g]}return e.default=a,c&&c.set(a,e),e}},93695,(a,b,c)=>{b.exports=a.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},71306,(a,b,c)=>{b.exports=a.r(18622)},79847,a=>{a.n(a.i(3343))},9185,a=>{a.n(a.i(29432))},72842,a=>{a.n(a.i(75164))},54897,a=>{a.n(a.i(30106))},56157,a=>{a.n(a.i(18970))},94331,a=>{a.n(a.i(60644))},15988,a=>{a.n(a.i(56952))},25766,a=>{a.n(a.i(77341))},29725,a=>{a.n(a.i(94290))},5785,a=>{a.n(a.i(90588))},74793,a=>{a.n(a.i(33169))},85826,a=>{a.n(a.i(37111))},21565,a=>{a.n(a.i(41763))},65911,a=>{a.n(a.i(8950))},25128,a=>{a.n(a.i(91562))},40781,a=>{a.n(a.i(49670))},69411,a=>{a.n(a.i(75700))},63081,a=>{a.n(a.i(276))},62837,a=>{a.n(a.i(40795))},34607,a=>{a.n(a.i(11614))},96338,a=>{a.n(a.i(21751))},50642,a=>{a.n(a.i(12213))},32242,a=>{a.n(a.i(22693))},88530,a=>{a.n(a.i(10531))},8583,a=>{a.n(a.i(1082))},38534,a=>{a.n(a.i(98175))},70408,a=>{a.n(a.i(9095))},22922,a=>{a.n(a.i(96772))},78294,a=>{a.n(a.i(71717))},16625,a=>{a.n(a.i(85034))},88648,a=>{a.n(a.i(68113))},51914,a=>{a.n(a.i(66482))},25466,a=>{a.n(a.i(91505))},69191,a=>{"use strict";var b=a.i(12714),c=a.i(50227),d=a.i(90798),e=a.i(34900),f=a.i(26192),g=a.i(76668),h=a.i(33432);async function i(a,c){try{return(await (0,b.stat)(a)).mtime}catch(a){return(0,g.logWarn)(`Failed to stat ${c}:`,a),new Date(0)}}async function j(a){try{if(!(await (0,b.stat)(a)).isDirectory())return null;return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function k(){try{let a=(0,d.getClaudeProjectsPath)(),b=await j(a);if(!b)return[];let e=(await (0,f.batchAll)(b.filter(a=>a.isDirectory()).map(b=>async()=>{let d=(0,c.join)(a,b.name),e=await i(d,b.name);return{name:b.name,path:d,isDirectory:!0,lastModified:e,lastModifiedFormatted:(0,h.formatDate)(e),cli:["claude"]}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value);return e.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),e}catch(a){return(0,g.logError)("Error reading Claude project folders:",a),[]}}async function l(){let[{getCodexProjects:b},{getCopilotProjects:c},{getCursorProjects:d},{getOpenCodeProjects:e},{getPiProjects:f},{getGeminiProjects:h}]=await Promise.all([a.A(93658),a.A(60956),a.A(26244),a.A(2164),a.A(92351),a.A(26396)]),[i,j,l,m,n,o,p]=await Promise.all([k(),b().catch(a=>((0,g.logError)("Error reading Codex projects:",a),[])),c().catch(a=>((0,g.logError)("Error reading Copilot projects:",a),[])),d().catch(a=>((0,g.logError)("Error reading Cursor projects:",a),[])),e().catch(a=>((0,g.logError)("Error reading OpenCode projects:",a),[])),f().catch(a=>((0,g.logError)("Error reading Pi projects:",a),[])),h().catch(a=>((0,g.logError)("Error reading Gemini projects:",a),[]))]);return function(...a){let b=new Map;for(let c of a)for(let a of c){let c=b.get(a.name);if(!c){b.set(a.name,{...a,cli:[...a.cli]});continue}let d=[...c.cli];for(let b of a.cli)d.includes(b)||d.push(b);let e=a.lastModified.getTime()>c.lastModified.getTime()?a:c;b.set(a.name,{...c,cli:d,lastModified:e.lastModified,lastModifiedFormatted:e.lastModifiedFormatted})}let c=Array.from(b.values());return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}(i,j,l,m,n,o,p)}function m(a){let b=a.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);return b?b[0]:void 0}async function n(a){try{let b=await j(a);if(!b)return[];let d=b.filter(a=>a.isFile()&&a.name.endsWith(".jsonl")&&m(a.name)),e=(await (0,f.batchAll)(d.map(b=>async()=>{let d=(0,c.join)(a,b.name),e=await i(d,b.name);return{name:b.name,path:d,lastModified:e,lastModifiedFormatted:(0,h.formatDate)(e),sessionId:m(b.name),cli:"claude"}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value);return e.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),e}catch(a){return(0,g.logError)("Error reading session files:",a),[]}}let o=(0,e.runtimeCache)(l,30),p=(0,e.runtimeCache)(a=>n(a),30);a.s(["UUID_RE",0,/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,"getCachedProjectFolders",0,o,"getCachedSessionFiles",0,p,"resolveProjectPath",0,function(a){if(!a)throw RangeError("Empty project name");if(/^[/\\]/.test(a))throw RangeError("Absolute project name");let b=(0,c.resolve)((0,d.getClaudeProjectsPath)()),e=(0,c.resolve)((0,c.join)(b,a));if(!e.startsWith(b+c.sep))throw RangeError("Project path escapes root");return e}])},71224,a=>{a.v("/_next/static/media/icon.0a.gigb3_x5pd.png"+(globalThis.NEXT_CLIENT_ASSET_SUFFIX||""))},1022,a=>{"use strict";let b={src:a.i(71224).default,width:1920,height:1920};a.s(["default",0,b])},82165,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/project-list.tsx <module evaluation> from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/project-list.tsx <module evaluation>","default")},92887,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/project-list.tsx from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/project-list.tsx","default")},17048,a=>{"use strict";a.i(82165);var b=a.i(92887);a.n(b)},61594,a=>{"use strict";var b=a.i(7997),c=a.i(717);a.i(70396);var d=a.i(73727),e=a.i(69191),f=a.i(17048);async function g(){(process.env.FAILPROOFAI_DISABLE_PAGES??"").split(",").map(a=>a.trim()).filter(Boolean).includes("projects")&&(0,d.notFound)();let a=await (0,e.getCachedProjectFolders)();return(0,b.jsx)("main",{className:"min-h-screen bg-background",children:(0,b.jsx)("div",{className:"container mx-auto p-8",children:(0,b.jsxs)("div",{className:"bg-card text-card-foreground rounded-lg border border-border p-6 shadow-sm",children:[(0,b.jsx)("h2",{className:"text-2xl font-semibold mb-4",children:"Projects"}),0===a.length?(0,b.jsxs)("div",{className:"text-center py-8",children:[(0,b.jsx)("p",{className:"text-muted-foreground mb-2",children:"No projects found in the .claude/projects directory."}),(0,b.jsx)("p",{className:"text-sm text-muted-foreground",children:"Make sure the directory exists and contains project folders."})]}):(0,b.jsx)(c.Suspense,{children:(0,b.jsx)(f.default,{folders:a})})]})})})}a.s(["default",0,g,"dynamic",0,"force-dynamic"])},19057,a=>{a.n(a.i(61594))},93658,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_codex-projects_ts_0eosib~._.js"].map(b=>a.l(b))).then(()=>b(1024)))},60956,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_copilot-projects_ts_0r8xkn8._.js"].map(b=>a.l(b))).then(()=>b(88890)))},26244,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_cursor-projects_ts_0qt1scg._.js"].map(b=>a.l(b))).then(()=>b(93087)))},2164,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_opencode-projects_ts_0op9gyp._.js"].map(b=>a.l(b))).then(()=>b(64458)))},92351,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_pi-projects_ts_103tsh1._.js"].map(b=>a.l(b))).then(()=>b(2727)))},26396,a=>{a.v(b=>Promise.all(["server/chunks/ssr/lib_gemini-projects_ts_0sl~yqr._.js"].map(b=>a.l(b))).then(()=>b(62074)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__0609ezh._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[46786,(a,b,c)=>{b.exports=a.x("os",()=>require("os"))},12714,(a,b,c)=>{b.exports=a.x("node:fs/promises",()=>require("node:fs/promises"))},24868,(a,b,c)=>{b.exports=a.x("fs/promises",()=>require("fs/promises"))},90798,a=>{"use strict";var b=a.i(46786),c=a.i(14747);a.s(["decodeFolderName",0,function(a){return/^[A-Za-z]--/.test(a)?a[0]+":/"+a.slice(3).replace(/-/g,"/"):a.replace(/-/g,"/")},"encodeFolderName",0,function(a){let b=/^([A-Za-z]):[\\/](.*)$/.exec(a);return b?b[1]+"--"+b[2].replace(/[\\/]/g,"-"):a.replace(/[\\/]/g,"-")},"getClaudeProjectsPath",0,function(){let a=process.env.CLAUDE_PROJECTS_PATH;return a||(0,c.join)((0,b.homedir)(),".claude","projects")}])},34900,a=>{"use strict";a.s(["runtimeCache",0,function(a,b,c){let d=new Map,e=new Map,f=c?.maxSize;return async(...c)=>{let g=JSON.stringify(c),h=d.get(g);if(h&&Date.now()<h.expiry)return h.data;let i=e.get(g);if(i)return i;let j=a(...c).then(a=>{if(e.delete(g),f&&d.size>=f){let a=d.keys().next().value;d.delete(a)}return d.set(g,{data:a,expiry:Date.now()+1e3*b}),a},a=>{throw e.delete(g),a});return e.set(g,j),j}}])},76668,a=>{"use strict";let b=1;function c(a){return`[failproofai${new Date().toISOString()}] ${a}`}a.s(["logError",0,function(a,b){void 0!==b?console.error(c("ERROR"),a,b):console.error(c("ERROR"),a)},"logWarn",0,function(a,d){b>=b&&(void 0!==d?console.warn(c("WARN"),a,d):console.warn(c("WARN"),a))}])},33432,a=>{"use strict";a.s(["formatDate",0,function(a){return new Intl.DateTimeFormat("en-US",{month:"short",day:"numeric",year:"numeric",hour:"numeric",minute:"2-digit",hour12:!0}).format(a)}])},26192,a=>{"use strict";async function b(a,b){let c=Array(a.length),d=0;async function e(){for(;d<a.length;){let b=d++;try{c[b]={status:"fulfilled",value:await a[b]()}}catch(a){c[b]={status:"rejected",reason:a}}}}let f=Array.from({length:Math.min(b,a.length)},()=>e());return await Promise.all(f),c}a.s(["batchAll",0,b])},50640,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0}),Object.defineProperty(c,"InvariantError",{enumerable:!0,get:function(){return d}});class d extends Error{constructor(a,b){super(`Invariant: ${a.endsWith(".")?a:a+"."} This is a bug in Next.js.`,b),this.name="InvariantError"}}},64240,(a,b,c)=>{"use strict";function d(a){if("function"!=typeof WeakMap)return null;var b=new WeakMap,c=new WeakMap;return(d=function(a){return a?c:b})(a)}c._=function(a,b){if(!b&&a&&a.__esModule)return a;if(null===a||"object"!=typeof a&&"function"!=typeof a)return{default:a};var c=d(b);if(c&&c.has(a))return c.get(a);var e={__proto__:null},f=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var g in a)if("default"!==g&&Object.prototype.hasOwnProperty.call(a,g)){var h=f?Object.getOwnPropertyDescriptor(a,g):null;h&&(h.get||h.set)?Object.defineProperty(e,g,h):e[g]=a[g]}return e.default=a,c&&c.set(a,e),e}},93695,(a,b,c)=>{b.exports=a.x("next/dist/shared/lib/no-fallback-error.external.js",()=>require("next/dist/shared/lib/no-fallback-error.external.js"))},71306,(a,b,c)=>{b.exports=a.r(18622)},79847,a=>{a.n(a.i(3343))},9185,a=>{a.n(a.i(29432))},72842,a=>{a.n(a.i(75164))},54897,a=>{a.n(a.i(30106))},56157,a=>{a.n(a.i(18970))},94331,a=>{a.n(a.i(60644))},15988,a=>{a.n(a.i(56952))},25766,a=>{a.n(a.i(77341))},29725,a=>{a.n(a.i(94290))},5785,a=>{a.n(a.i(90588))},74793,a=>{a.n(a.i(33169))},85826,a=>{a.n(a.i(37111))},21565,a=>{a.n(a.i(41763))},65911,a=>{a.n(a.i(8950))},25128,a=>{a.n(a.i(91562))},40781,a=>{a.n(a.i(49670))},69411,a=>{a.n(a.i(75700))},63081,a=>{a.n(a.i(276))},62837,a=>{a.n(a.i(40795))},34607,a=>{a.n(a.i(11614))},96338,a=>{a.n(a.i(21751))},50642,a=>{a.n(a.i(12213))},32242,a=>{a.n(a.i(22693))},88530,a=>{a.n(a.i(10531))},8583,a=>{a.n(a.i(1082))},38534,a=>{a.n(a.i(98175))},70408,a=>{a.n(a.i(9095))},22922,a=>{a.n(a.i(96772))},78294,a=>{a.n(a.i(71717))},16625,a=>{a.n(a.i(85034))},88648,a=>{a.n(a.i(68113))},51914,a=>{a.n(a.i(66482))},25466,a=>{a.n(a.i(91505))},22734,(a,b,c)=>{b.exports=a.x("fs",()=>require("fs"))},88890,a=>{"use strict";var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(90798),f=a.i(34900),g=a.i(26192),h=a.i(33432),i=a.i(76668);async function j(a){try{return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function k(a){try{return(await (0,b.stat)(a)).mtime}catch{return null}}async function l(){let a=(0,d.join)(process.env.COPILOT_HOME||(0,d.join)((0,c.homedir)(),".copilot"),"session-state"),e=await j(a);if(!e)return[];let f=e.filter(a=>a.isDirectory()).map(b=>({sessionId:b.name,workspacePath:(0,d.join)(a,b.name,"workspace.yaml"),eventsPath:(0,d.join)(a,b.name,"events.jsonl")}));return(await (0,g.batchAll)(f.map(a=>async()=>{let c;try{c=await (0,b.readFile)(a.workspacePath,"utf-8")}catch{return null}let d=function(a){let b=a.match(/^cwd\s*:\s*(.+?)\s*$/m);if(b)return b[1].replace(/^['"]|['"]$/g,"")}(c);if(!d)return null;let e=await k(a.eventsPath),f=await k(a.workspacePath),g=null!==e,h=e&&f?new Date(Math.max(e.getTime(),f.getTime())):e??f??new Date(0);return{workspacePath:a.workspacePath,eventsPath:a.eventsPath,sessionId:a.sessionId,cwd:d,fileMtime:h,hasTranscript:g}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value).filter(a=>null!==a)}let m=(0,f.runtimeCache)(l,30);async function n(){let a;try{a=await m()}catch(a){return(0,i.logWarn)("Failed to scan Copilot sessions:",a),[]}let b=new Map;for(let c of a){if(!c.hasTranscript)continue;let a=b.get(c.cwd);(!a||c.fileMtime.getTime()>a.latest.getTime())&&b.set(c.cwd,{latest:c.fileMtime,cwd:c.cwd})}let c=[];for(let{cwd:a,latest:d}of b.values())c.push({name:(0,e.encodeFolderName)(a),path:a,isDirectory:!0,lastModified:d,lastModifiedFormatted:(0,h.formatDate)(d),cli:["copilot"]});return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}function o(a){let b=a.filter(a=>a.hasTranscript).map(a=>({name:a.sessionId,path:a.eventsPath,lastModified:a.fileMtime,lastModifiedFormatted:(0,h.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"copilot"}));return b.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),b}async function p(a){let b;try{b=await m()}catch(a){return(0,i.logWarn)("Failed to scan Copilot sessions:",a),[]}return o(b.filter(b=>b.cwd===a))}async function q(a){let b;try{b=await m()}catch(a){return(0,i.logWarn)("Failed to scan Copilot sessions:",a),{cwd:null,sessions:[]}}let c=b.filter(b=>b.hasTranscript&&(0,e.encodeFolderName)(b.cwd)===a);return{cwd:c[0]?.cwd??null,sessions:o(c)}}let r=(0,f.runtimeCache)(n,30),s=(0,f.runtimeCache)(a=>p(a),30,{maxSize:50}),t=(0,f.runtimeCache)(a=>q(a),30,{maxSize:50});a.s(["getCachedCopilotProjects",0,r,"getCachedCopilotSessionsByEncodedName",0,t,"getCachedCopilotSessionsForCwd",0,s,"getCopilotProjects",0,n,"getCopilotSessionsByEncodedName",0,q,"getCopilotSessionsForCwd",0,p])},1024,a=>{"use strict";var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(90798),f=a.i(34900),g=a.i(26192),h=a.i(33432),i=a.i(76668);let j=(0,d.join)((0,c.homedir)(),".codex","sessions"),k=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;async function l(a){try{return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function m(a){let c=null;try{c=await (0,b.open)(a,"r");let d=Buffer.alloc(262144),{bytesRead:e}=await c.read(d,0,262144,0);if(0===e)return null;let f=d.subarray(0,e),g=f.indexOf(10),h=-1===g?e:g;return f.subarray(0,h).toString("utf-8")}catch{return null}finally{c&&await c.close().catch(()=>{})}}async function n(a){let b=await l(a);return b?b.filter(a=>a.isFile()&&a.name.endsWith(".jsonl")).map(b=>(0,d.join)(a,b.name)):[]}async function o(){let a=await l(j);if(!a)return[];let c=[];for(let b of a){if(!b.isDirectory())continue;let a=await l((0,d.join)(j,b.name));if(a)for(let e of a){if(!e.isDirectory())continue;let a=await l((0,d.join)(j,b.name,e.name));if(a)for(let f of a){if(!f.isDirectory())continue;let a=(0,d.join)(j,b.name,e.name,f.name);c.push(...await n(a))}}}return 0===c.length?[]:(await (0,g.batchAll)(c.map(a=>async()=>{let c,d,e=(d=(a.split("/").pop()??"").match(k))?d[0]:null;if(!e)return null;let f=await m(a);if(!f)return null;let{cwd:g}=function(a){try{let b=JSON.parse(a);if("session_meta"!==b.type)return{};let c=b.payload?.cwd;if("string"!=typeof c||0===c.length)return{};return{cwd:c}}catch{return{}}}(f);if(!g)return null;try{let d=await (0,b.open)(a,"r");try{c=(await d.stat()).mtime}finally{await d.close().catch(()=>{})}}catch{c=new Date(0)}return{filePath:a,fileName:a.split("/").pop()??"",cwd:g,sessionId:e,fileMtime:c}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value).filter(a=>null!==a)}let p=(0,f.runtimeCache)(o,30);async function q(){let a;try{a=await p()}catch(a){return(0,i.logWarn)("Failed to scan Codex sessions:",a),[]}let b=new Map;for(let c of a){let a=b.get(c.cwd);(!a||c.fileMtime.getTime()>a.latest.getTime())&&b.set(c.cwd,{latest:c.fileMtime,cwd:c.cwd})}let c=[];for(let{cwd:a,latest:d}of b.values())c.push({name:(0,e.encodeFolderName)(a),path:a,isDirectory:!0,lastModified:d,lastModifiedFormatted:(0,h.formatDate)(d),cli:["codex"]});return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}function r(a){let b=a.map(a=>({name:a.fileName.replace(/\.jsonl$/,""),path:a.filePath,lastModified:a.fileMtime,lastModifiedFormatted:(0,h.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"codex"}));return b.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),b}async function s(a){let b;try{b=await p()}catch(a){return(0,i.logWarn)("Failed to scan Codex sessions:",a),[]}return r(b.filter(b=>b.cwd===a))}async function t(a){let b;try{b=await p()}catch(a){return(0,i.logWarn)("Failed to scan Codex sessions:",a),{cwd:null,sessions:[]}}let c=b.filter(b=>(0,e.encodeFolderName)(b.cwd)===a);return{cwd:c[0]?.cwd??null,sessions:r(c)}}let u=(0,f.runtimeCache)(q,30),v=(0,f.runtimeCache)(a=>s(a),30,{maxSize:50}),w=(0,f.runtimeCache)(a=>t(a),30,{maxSize:50});a.s(["getCachedCodexProjects",0,u,"getCachedCodexSessionsByEncodedName",0,w,"getCachedCodexSessionsForCwd",0,v,"getCodexProjects",0,q,"getCodexSessionsByEncodedName",0,t,"getCodexSessionsForCwd",0,s])},2727,a=>{"use strict";var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(90798),f=a.i(34900),g=a.i(26192),h=a.i(33432),i=a.i(76668);let j=/^[\d-]+T[\d-]+Z_([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;async function k(a){try{return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function l(a){try{return(await (0,b.stat)(a)).mtime}catch{return null}}async function m(a){let c;try{c=await (0,b.readFile)(a,"utf-8")}catch{return null}let d=c.indexOf("\n")>=0?c.slice(0,c.indexOf("\n")):c;if(!d)return null;try{let a=JSON.parse(d);if("session"!==a.type||"string"!=typeof a.cwd||0===a.cwd.length)return null;return a.cwd}catch{return null}}async function n(){let a=process.env.PI_SESSIONS_DIR||(0,d.join)((0,c.homedir)(),".pi","agent","sessions"),b=await k(a);if(!b)return[];let e=[];for(let c of b){if(!c.isDirectory())continue;let b=(0,d.join)(a,c.name),f=await k(b);if(f)for(let a of f){if(!a.isFile())continue;let c=j.exec(a.name);c&&e.push({sessionId:c[1],filePath:(0,d.join)(b,a.name)})}}return 0===e.length?[]:(await (0,g.batchAll)(e.map(a=>async()=>{let b=await m(a.filePath);if(!b)return null;let c=await l(a.filePath);return c?{filePath:a.filePath,sessionId:a.sessionId,cwd:b,fileMtime:c}:null}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value).filter(a=>null!==a)}let o=(0,f.runtimeCache)(n,30);async function p(){let a;try{a=await o()}catch(a){return(0,i.logWarn)("Failed to scan Pi sessions:",a),[]}let b=new Map;for(let c of a){let a=b.get(c.cwd);(!a||c.fileMtime.getTime()>a.latest.getTime())&&b.set(c.cwd,{latest:c.fileMtime,cwd:c.cwd})}let c=[];for(let{cwd:a,latest:d}of b.values())c.push({name:(0,e.encodeFolderName)(a),path:a,isDirectory:!0,lastModified:d,lastModifiedFormatted:(0,h.formatDate)(d),cli:["pi"]});return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}function q(a){let b=a.map(a=>({name:a.sessionId,path:a.filePath,lastModified:a.fileMtime,lastModifiedFormatted:(0,h.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"pi"}));return b.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),b}async function r(a){let b;try{b=await o()}catch(a){return(0,i.logWarn)("Failed to scan Pi sessions:",a),[]}return q(b.filter(b=>b.cwd===a))}async function s(a){let b;try{b=await o()}catch(a){return(0,i.logWarn)("Failed to scan Pi sessions:",a),{cwd:null,sessions:[]}}let c=b.filter(b=>(0,e.encodeFolderName)(b.cwd)===a),d=Array.from(new Set(c.map(a=>a.cwd)));return 1!==d.length?{cwd:null,sessions:[]}:{cwd:d[0],sessions:q(c)}}let t=(0,f.runtimeCache)(p,30),u=(0,f.runtimeCache)(a=>r(a),30,{maxSize:50}),v=(0,f.runtimeCache)(a=>s(a),30,{maxSize:50});a.s(["getCachedPiProjects",0,t,"getCachedPiSessionsByEncodedName",0,v,"getCachedPiSessionsForCwd",0,u,"getPiProjects",0,p,"getPiSessionsByEncodedName",0,s,"getPiSessionsForCwd",0,r])},64458,a=>{"use strict";var b=a.i(74533),c=a.i(90798),d=a.i(34900),e=a.i(33432),f=a.i(76668);function g(a){try{let c=(0,b.execFileSync)("opencode",["db","--format","json",a],{encoding:"utf8",timeout:5e3,stdio:["ignore","pipe","pipe"]});if(!c.trim())return[];let d=JSON.parse(c);if(!Array.isArray(d))return null;return d}catch{return null}}function h(){return g("SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session ORDER BY time_updated DESC LIMIT 1000")}function i(){return g("SELECT id, worktree, vcs, name, time_created, time_updated FROM project")}async function j(){let a=h(),b=i();if(null===a&&null===b)return[];let d=new Map;for(let a of b??[])d.set(a.id,a);let f=new Map;for(let b of a??[]){if(!b.project_id)continue;let a=f.get(b.project_id);a||(a={rows:[],latest:0},f.set(b.project_id,a)),a.rows.push(b),b.time_updated>a.latest&&(a.latest=b.time_updated)}let g=new Set,j=[];for(let[a,b]of f){g.add(a);let f=d.get(a),h=f?.worktree??b.rows[0]?.directory??null,i=h?(0,c.encodeFolderName)(h):a,k=h??"",l=new Date(Math.max(b.latest,f?.time_updated??0));j.push({name:i,path:k,isDirectory:!0,lastModified:l,lastModifiedFormatted:(0,e.formatDate)(l),cli:["opencode"]})}for(let a of b??[]){if(g.has(a.id))continue;let b=a.worktree??"",d=b?(0,c.encodeFolderName)(b):a.id,f=new Date(a.time_updated);j.push({name:d,path:b,isDirectory:!0,lastModified:f,lastModifiedFormatted:(0,e.formatDate)(f),cli:["opencode"]})}return j.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),j}async function k(a){let b=h();return b?b.filter(b=>b.directory===a).map(a=>{let b=new Date(a.time_updated);return{name:a.title??a.slug??a.id,path:`opencode://${a.id}`,lastModified:b,lastModifiedFormatted:(0,e.formatDate)(b),sessionId:a.id,cli:"opencode"}}):[]}async function l(a){let b,d;try{b=i(),d=h()}catch(a){return(0,f.logWarn)("Failed to read OpenCode DB:",a),{cwd:null,sessions:[]}}if(!b||!d)return{cwd:null,sessions:[]};let g=b.find(b=>b.worktree&&(0,c.encodeFolderName)(b.worktree)===a);if(!g||!g.worktree)return{cwd:null,sessions:[]};let j=d.filter(a=>a.project_id===g.id);return{cwd:g.worktree,sessions:j.map(a=>{let b=new Date(a.time_updated);return{name:a.title??a.slug??a.id,path:`opencode://${a.id}`,lastModified:b,lastModifiedFormatted:(0,e.formatDate)(b),sessionId:a.id,cli:"opencode"}})}}let m=(0,d.runtimeCache)(j,30),n=(0,d.runtimeCache)(a=>k(a),30,{maxSize:50}),o=(0,d.runtimeCache)(a=>l(a),30,{maxSize:50});a.s(["getCachedOpenCodeProjects",0,m,"getCachedOpenCodeSessionsByEncodedName",0,o,"getCachedOpenCodeSessionsForCwd",0,n,"getOpenCodeProjects",0,j,"getOpenCodeSessionsByEncodedName",0,l,"getOpenCodeSessionsForCwd",0,k])},62074,a=>{"use strict";var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(34900),f=a.i(26192),g=a.i(33432),h=a.i(90798),i=a.i(76668);let j=/^session-(\d{4}-\d{2}-\d{2}T\d{2}-\d{2})-([0-9a-f]{8})\.jsonl$/i,k=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;async function l(a){try{return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function m(a){try{return(await (0,b.stat)(a)).mtime}catch{return null}}async function n(a){let c=null;try{c=await (0,b.open)(a,"r");let d=Buffer.alloc(4096),{bytesRead:e}=await c.read(d,0,4096,0);if(0===e)return null;let f=d.subarray(0,e),g=f.indexOf(10),h=-1===g?e:g;return f.subarray(0,h).toString("utf-8")}catch{return null}finally{c&&await c.close().catch(()=>{})}}async function o(a){try{let c=(await (0,b.readFile)((0,d.join)(a,".project_root"),"utf-8")).trim();return c.length>0?c:null}catch{return null}}async function p(){let a=process.env.GEMINI_SESSIONS_DIR||(0,d.join)((0,c.homedir)(),".gemini","tmp"),b=await l(a);if(!b)return[];let e=[];return await (0,f.batchAll)(b.filter(a=>a.isDirectory()).map(b=>async()=>{let c=(0,d.join)(a,b.name),f=await o(c);if(!f)return;let g=(0,d.join)(c,"chats"),h=await l(g);if(h)for(let a of h){if(!a.isFile()||!j.test(a.name))continue;let b=(0,d.join)(g,a.name),c=await m(b);if(!c)continue;let h=function(a){if(a)try{let b=JSON.parse(a);if("string"!=typeof b.sessionId)return;return k.test(b.sessionId)?b.sessionId:void 0}catch{return}}(await n(b));e.push({filePath:b,sessionFilename:a.name,cwd:f,fileMtime:c,sessionId:h})}}),16),e}async function q(){let a=await p(),b=new Map;for(let c of a){let a=b.get(c.cwd);(!a||c.fileMtime.getTime()>a.mtime.getTime())&&b.set(c.cwd,{mtime:c.fileMtime})}let c=[...b.entries()].map(([a,{mtime:b}])=>({name:(0,h.encodeFolderName)(a),path:a,isDirectory:!0,lastModified:b,lastModifiedFormatted:(0,g.formatDate)(b),cli:["gemini"]}));return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}async function r(a){let b=(await p()).filter(b=>b.cwd===a).map(a=>({name:a.sessionFilename,path:a.filePath,lastModified:a.fileMtime,lastModifiedFormatted:(0,g.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"gemini"}));return b.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),b}async function s(a){let b;try{b=await p()}catch(a){return(0,i.logWarn)("Failed to scan Gemini sessions:",a),{cwd:null,sessions:[]}}let c=b.filter(b=>(0,h.encodeFolderName)(b.cwd)===a),d=Array.from(new Set(c.map(a=>a.cwd)));if(1!==d.length)return{cwd:null,sessions:[]};let e=c.map(a=>({name:a.sessionFilename,path:a.filePath,lastModified:a.fileMtime,lastModifiedFormatted:(0,g.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"gemini"}));return e.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),{cwd:d[0],sessions:e}}let t=(0,e.runtimeCache)(q,30),u=(0,e.runtimeCache)(a=>s(a),30,{maxSize:50});a.s(["getCachedGeminiProjects",0,t,"getCachedGeminiSessionsByEncodedName",0,u,"getGeminiProjects",0,q,"getGeminiSessionsByEncodedName",0,s,"getGeminiSessionsForCwd",0,r])},93087,a=>{"use strict";var b=a.i(12714),c=a.i(60526),d=a.i(50227),e=a.i(90798),f=a.i(34900),g=a.i(26192),h=a.i(33432),i=a.i(76668);let j=["agent-sessions","conversations","sessions"],k=["meta.json","session.json","workspace.json","workspace.yaml"],l=["events.jsonl","transcript.jsonl","messages.jsonl"];async function m(a){try{return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function n(a){try{return(await (0,b.stat)(a)).mtime}catch{return null}}async function o(a,c){for(let e of c){let c,f=(0,d.join)(a,e);if(await n(f)===null)continue;try{c=await (0,b.readFile)(f,"utf-8")}catch{continue}let g=function(a){try{let b=JSON.parse(a);if("string"==typeof b.cwd&&b.cwd.length>0)return b.cwd}catch{}let b=a.match(/^\s*cwd\s*:\s*(.+?)\s*$/m);if(b){let a=b[1].replace(/^['"]|['"]$/g,"");if(a.length>0)return a}}(c);if(g)return{path:f,cwd:g}}return null}async function p(a,b){for(let c of b){let b=(0,d.join)(a,c);if(await n(b)!==null)return b}return null}async function q(){let a=process.env.CURSOR_HOME||(0,d.join)((0,c.homedir)(),".cursor"),b=[],f=[],h=(0,d.join)(a,"projects"),i=await m(h);if(i)for(let a of i){if(!a.isDirectory())continue;let c=(0,e.decodeFolderName)(a.name),f=c.startsWith("/")||/^[A-Za-z]:\//.test(c)?c:`/${c}`,g=(0,d.join)(h,a.name,"agent-transcripts"),i=await m(g);if(i)for(let a of i)a.isDirectory()&&b.push({sessionId:a.name,dir:(0,d.join)(g,a.name),cwd:f})}for(let b of j){let c=(0,d.join)(a,b),e=await m(c);if(e)for(let a of e)a.isDirectory()&&f.push({sessionId:a.name,dir:(0,d.join)(c,a.name)})}return 0===b.length&&0===f.length?[]:(await (0,g.batchAll)([...b.map(a=>async()=>{let b=(0,d.join)(a.dir,`${a.sessionId}.jsonl`),c=await n(b);return c?{metaPath:a.dir,transcriptPath:b,sessionId:a.sessionId,cwd:a.cwd,fileMtime:c,hasTranscript:!0}:null}),...f.map(a=>async()=>{let b=await o(a.dir,k);if(!b)return null;let c=await p(a.dir,l),d=c?await n(c):null,e=await n(b.path),f=d&&e?new Date(Math.max(d.getTime(),e.getTime())):d??e??new Date(0);return{metaPath:b.path,transcriptPath:c,sessionId:a.sessionId,cwd:b.cwd,fileMtime:f,hasTranscript:null!==c}})],16)).filter(a=>"fulfilled"===a.status).map(a=>a.value).filter(a=>null!==a)}let r=(0,f.runtimeCache)(q,30);async function s(){let a;try{a=await r()}catch(a){return(0,i.logWarn)("Failed to scan Cursor sessions:",a),[]}let b=new Map;for(let c of a){if(!c.hasTranscript)continue;let a=b.get(c.cwd);(!a||c.fileMtime.getTime()>a.latest.getTime())&&b.set(c.cwd,{latest:c.fileMtime,cwd:c.cwd})}let c=[];for(let{cwd:a,latest:d}of b.values())c.push({name:(0,e.encodeFolderName)(a),path:a,isDirectory:!0,lastModified:d,lastModifiedFormatted:(0,h.formatDate)(d),cli:["cursor"]});return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}function t(a){let b=a.filter(a=>a.hasTranscript&&a.transcriptPath).map(a=>({name:a.sessionId,path:a.transcriptPath,lastModified:a.fileMtime,lastModifiedFormatted:(0,h.formatDate)(a.fileMtime),sessionId:a.sessionId,cli:"cursor"}));return b.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),b}async function u(a){let b;try{b=await r()}catch(a){return(0,i.logWarn)("Failed to scan Cursor sessions:",a),[]}return t(b.filter(b=>b.cwd===a))}async function v(a){let b;try{b=await r()}catch(a){return(0,i.logWarn)("Failed to scan Cursor sessions:",a),{cwd:null,sessions:[]}}let c=b.filter(b=>b.hasTranscript&&(0,e.encodeFolderName)(b.cwd)===a);return{cwd:c[0]?.cwd??null,sessions:t(c)}}let w=(0,f.runtimeCache)(s,30),x=(0,f.runtimeCache)(a=>u(a),30,{maxSize:50}),y=(0,f.runtimeCache)(a=>v(a),30,{maxSize:50});a.s(["getCachedCursorProjects",0,w,"getCachedCursorSessionsByEncodedName",0,y,"getCachedCursorSessionsForCwd",0,x,"getCursorProjects",0,s,"getCursorSessionsByEncodedName",0,v,"getCursorSessionsForCwd",0,u])},69191,a=>{"use strict";var b=a.i(12714),c=a.i(50227),d=a.i(90798),e=a.i(34900),f=a.i(26192),g=a.i(76668),h=a.i(33432);async function i(a,c){try{return(await (0,b.stat)(a)).mtime}catch(a){return(0,g.logWarn)(`Failed to stat ${c}:`,a),new Date(0)}}async function j(a){try{if(!(await (0,b.stat)(a)).isDirectory())return null;return await (0,b.readdir)(a,{withFileTypes:!0})}catch{return null}}async function k(){try{let a=(0,d.getClaudeProjectsPath)(),b=await j(a);if(!b)return[];let e=(await (0,f.batchAll)(b.filter(a=>a.isDirectory()).map(b=>async()=>{let d=(0,c.join)(a,b.name),e=await i(d,b.name);return{name:b.name,path:d,isDirectory:!0,lastModified:e,lastModifiedFormatted:(0,h.formatDate)(e),cli:["claude"]}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value);return e.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),e}catch(a){return(0,g.logError)("Error reading Claude project folders:",a),[]}}async function l(){let[{getCodexProjects:b},{getCopilotProjects:c},{getCursorProjects:d},{getOpenCodeProjects:e},{getPiProjects:f},{getGeminiProjects:h}]=await Promise.all([a.A(93658),a.A(60956),a.A(26244),a.A(2164),a.A(92351),a.A(26396)]),[i,j,l,m,n,o,p]=await Promise.all([k(),b().catch(a=>((0,g.logError)("Error reading Codex projects:",a),[])),c().catch(a=>((0,g.logError)("Error reading Copilot projects:",a),[])),d().catch(a=>((0,g.logError)("Error reading Cursor projects:",a),[])),e().catch(a=>((0,g.logError)("Error reading OpenCode projects:",a),[])),f().catch(a=>((0,g.logError)("Error reading Pi projects:",a),[])),h().catch(a=>((0,g.logError)("Error reading Gemini projects:",a),[]))]);return function(...a){let b=new Map;for(let c of a)for(let a of c){let c=b.get(a.name);if(!c){b.set(a.name,{...a,cli:[...a.cli]});continue}let d=[...c.cli];for(let b of a.cli)d.includes(b)||d.push(b);let e=a.lastModified.getTime()>c.lastModified.getTime()?a:c;b.set(a.name,{...c,cli:d,lastModified:e.lastModified,lastModifiedFormatted:e.lastModifiedFormatted})}let c=Array.from(b.values());return c.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),c}(i,j,l,m,n,o,p)}function m(a){let b=a.match(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i);return b?b[0]:void 0}async function n(a){try{let b=await j(a);if(!b)return[];let d=b.filter(a=>a.isFile()&&a.name.endsWith(".jsonl")&&m(a.name)),e=(await (0,f.batchAll)(d.map(b=>async()=>{let d=(0,c.join)(a,b.name),e=await i(d,b.name);return{name:b.name,path:d,lastModified:e,lastModifiedFormatted:(0,h.formatDate)(e),sessionId:m(b.name),cli:"claude"}}),16)).filter(a=>"fulfilled"===a.status).map(a=>a.value);return e.sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),e}catch(a){return(0,g.logError)("Error reading session files:",a),[]}}let o=(0,e.runtimeCache)(l,30),p=(0,e.runtimeCache)(a=>n(a),30);a.s(["UUID_RE",0,/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,"getCachedProjectFolders",0,o,"getCachedSessionFiles",0,p,"resolveProjectPath",0,function(a){if(!a)throw RangeError("Empty project name");if(/^[/\\]/.test(a))throw RangeError("Absolute project name");let b=(0,c.resolve)((0,d.getClaudeProjectsPath)()),e=(0,c.resolve)((0,c.join)(b,a));if(!e.startsWith(b+c.sep))throw RangeError("Project path escapes root");return e}])},790,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(11857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js <module evaluation>"))},84707,(a,b,c)=>{let{createClientModuleProxy:d}=a.r(11857);a.n(d("[project]/node_modules/next/dist/client/app-dir/link.js"))},97647,a=>{"use strict";a.i(790);var b=a.i(84707);a.n(b)},95936,(a,b,c)=>{"use strict";Object.defineProperty(c,"__esModule",{value:!0});var d={default:function(){return i},useLinkStatus:function(){return h.useLinkStatus}};for(var e in d)Object.defineProperty(c,e,{enumerable:!0,get:d[e]});let f=a.r(64240),g=a.r(7997),h=f._(a.r(97647));function i(a){let b=a.legacyBehavior,c="string"==typeof a.children||"number"==typeof a.children||"string"==typeof a.children?.type,d=a.children?.type?.$$typeof===Symbol.for("react.client.reference");return!b||c||d||(a.children?.type?.$$typeof===Symbol.for("react.lazy")?console.error("Using a Lazy Component as a direct child of `<Link legacyBehavior>` from a Server Component is not supported. If you need legacyBehavior, wrap your Lazy Component in a Client Component that renders the Link's `<a>` tag."):console.error("Using a Server Component as a direct child of `<Link legacyBehavior>` is not supported. If you need legacyBehavior, wrap your Server Component in a Client Component that renders the Link's `<a>` tag.")),(0,g.jsx)(h.default,{...a})}("function"==typeof c.default||"object"==typeof c.default&&null!==c.default)&&void 0===c.default.__esModule&&(Object.defineProperty(c.default,"__esModule",{value:!0}),Object.assign(c.default,c),b.exports=c.default)},8174,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/node_modules/lucide-react/dist/esm/Icon.mjs <module evaluation> from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/node_modules/lucide-react/dist/esm/Icon.mjs <module evaluation>","default")},90697,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/node_modules/lucide-react/dist/esm/Icon.mjs from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/node_modules/lucide-react/dist/esm/Icon.mjs","default")},53808,a=>{"use strict";a.i(8174);var b=a.i(90697);a.n(b)},84930,92277,a=>{"use strict";var b=a.i(717);let c=a=>{let b=a.replace(/^([A-Z])|[\s-_]+(\w)/g,(a,b,c)=>c?c.toUpperCase():b.toLowerCase());return b.charAt(0).toUpperCase()+b.slice(1)};var d=a.i(53808);let e=(a,e)=>{let f=(0,b.forwardRef)(({className:f,...g},h)=>(0,b.createElement)(d.default,{ref:h,iconNode:e,className:((...a)=>a.filter((a,b,c)=>!!a&&""!==a.trim()&&c.indexOf(a)===b).join(" ").trim())(`lucide-${c(a).replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}`,`lucide-${a}`,f),...g}));return f.displayName=c(a),f};a.s(["default",0,e],92277);let f=e("arrow-left",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);a.s(["ArrowLeft",0,f],84930)},71224,a=>{a.v("/_next/static/media/icon.0a.gigb3_x5pd.png"+(globalThis.NEXT_CLIENT_ASSET_SUFFIX||""))},1022,a=>{"use strict";let b={src:a.i(71224).default,width:1920,height:1920};a.s(["default",0,b])},34417,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/sessions-list.tsx <module evaluation> from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/sessions-list.tsx <module evaluation>","default")},46201,a=>{"use strict";a.s(["default",()=>b]);let b=(0,a.i(11857).registerClientReference)(function(){throw Error("Attempted to call the default export of [project]/app/components/sessions-list.tsx from the server, but it's on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.")},"[project]/app/components/sessions-list.tsx","default")},13853,a=>{"use strict";a.i(34417);var b=a.i(46201);a.n(b)},80776,a=>{"use strict";var b=a.i(7997),c=a.i(717),d=a.i(69191),e=a.i(1024),f=a.i(88890),g=a.i(93087),h=a.i(64458),i=a.i(2727),j=a.i(62074),k=a.i(76668),l=a.i(90798);a.i(70396);var m=a.i(73727),n=a.i(22734),o=a.i(24868),p=a.i(95936),q=a.i(84930),r=a.i(33432),s=a.i(13853);async function t({params:a}){let{name:u}=await a,v=null;try{v=(0,d.resolveProjectPath)(u)}catch{v=null}let w=(0,l.decodeFolderName)(u),x=!!v&&(0,n.existsSync)(v),y=[];x&&v&&(y=await (0,d.getCachedSessionFiles)(v));let[z,A,B,C,D,E]=await Promise.all([(0,e.getCachedCodexSessionsByEncodedName)(u),(0,f.getCachedCopilotSessionsByEncodedName)(u),(0,g.getCachedCursorSessionsByEncodedName)(u),(0,h.getCachedOpenCodeSessionsByEncodedName)(u),(0,i.getCachedPiSessionsByEncodedName)(u),(0,j.getCachedGeminiSessionsByEncodedName)(u)]),F=z.sessions,G=A.sessions,H=B.sessions,I=C.sessions,J=D.sessions,K=E.sessions;x||0!==F.length||0!==G.length||0!==H.length||0!==I.length||0!==J.length||0!==K.length||(0,m.notFound)();let L=z.cwd??A.cwd??B.cwd??C.cwd??D.cwd??E.cwd??w,M=null,N=null;if(x&&v)try{let a=await (0,o.stat)(v);M=a.mtime,N=(0,r.formatDate)(a.mtime)}catch(a){(0,k.logWarn)(`Failed to get stats for project ${w}:`,a)}let O=[F[0],G[0],H[0],I[0],J[0],K[0]].filter(a=>!!a).map(a=>a.lastModified).reduce((a,b)=>!a||b.getTime()>a.getTime()?b:a,null);O&&(!M||O.getTime()>M.getTime())&&(M=O,N=(0,r.formatDate)(O));let P=[...y,...F,...G,...H,...I,...J,...K].sort((a,b)=>b.lastModified.getTime()-a.lastModified.getTime()),Q=x&&v?v:L;return(0,b.jsx)("main",{className:"min-h-screen bg-background",children:(0,b.jsxs)("div",{className:"container mx-auto p-8",children:[(0,b.jsxs)(p.default,{href:"/projects",className:"inline-flex items-center gap-2 text-muted-foreground hover:text-foreground mb-6 transition-colors",children:[(0,b.jsx)(q.ArrowLeft,{className:"w-4 h-4"}),(0,b.jsx)("span",{children:"Back to Projects"})]}),(0,b.jsxs)("div",{className:"mb-8",children:[(0,b.jsx)("h1",{className:"text-4xl font-bold text-foreground mb-2 break-words break-all",children:L}),(0,b.jsxs)("div",{className:"space-y-1",children:[(0,b.jsxs)("p",{className:"text-muted-foreground",children:[(0,b.jsx)("span",{className:"font-medium",children:"Path:"})," ",Q]}),N&&(0,b.jsxs)("p",{className:"text-muted-foreground",children:[(0,b.jsx)("span",{className:"font-medium",children:"Modified:"})," ",N]})]})]}),(0,b.jsxs)("div",{className:"bg-card text-card-foreground rounded-lg border border-border p-6 shadow-sm",children:[(0,b.jsx)("h2",{className:"text-2xl font-semibold mb-4",children:"Sessions"}),0===P.length?(0,b.jsxs)("div",{className:"text-center py-8",children:[(0,b.jsx)("p",{className:"text-muted-foreground mb-2",children:"No .jsonl files found in this project."}),(0,b.jsx)("p",{className:"text-sm text-muted-foreground",children:"Session files will appear here once they are created."})]}):(0,b.jsx)(c.Suspense,{children:(0,b.jsx)(s.default,{files:P,projectName:u})})]})]})})}a.s(["default",0,t,"dynamic",0,"force-dynamic"])},11363,a=>{a.n(a.i(80776))},93658,a=>{a.v(a=>Promise.resolve().then(()=>a(1024)))},60956,a=>{a.v(a=>Promise.resolve().then(()=>a(88890)))},26244,a=>{a.v(a=>Promise.resolve().then(()=>a(93087)))},2164,a=>{a.v(a=>Promise.resolve().then(()=>a(64458)))},92351,a=>{a.v(a=>Promise.resolve().then(()=>a(2727)))},26396,a=>{a.v(a=>Promise.resolve().then(()=>a(62074)))}];
2
-
3
- //# sourceMappingURL=%5Broot-of-the-server%5D__07_-mkc._.js.map