failproofai 1.0.0-beta.4 → 1.0.0-beta.6

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 (369) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +2 -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/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page.js +3 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  10. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  14. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  15. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  16. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page.js +3 -1
  20. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  23. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  24. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  25. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  26. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  27. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  28. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  31. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
  33. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  35. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +2 -1
  37. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
  39. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
  43. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
  45. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  47. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  49. package/.next/standalone/.next/server/app/audit/page.js +5 -3
  50. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/index.html +1 -1
  53. package/.next/standalone/.next/server/app/index.rsc +15 -15
  54. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  55. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  56. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  57. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  58. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  59. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/page.js +3 -1
  61. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  62. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +10 -10
  64. package/.next/standalone/.next/server/app/policies/page.js +4 -2
  65. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  68. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -2
  69. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  70. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  71. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  72. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  73. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -4
  74. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  76. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  77. package/.next/standalone/.next/server/app/projects/page.js +4 -2
  78. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  79. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  80. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  81. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
  82. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
  83. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  84. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
  85. package/.next/standalone/.next/server/app/settings/page.js +18 -0
  86. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  87. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  88. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  89. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  90. package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
  92. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
  93. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
  95. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
  96. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ky_n0r._.js} +2 -2
  97. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0lk_935._.js} +2 -2
  98. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1p7s8-d._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
  99. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0v2fpxe._.js} +2 -2
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +3 -3
  102. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__1_ps0jw._.js} +2 -2
  103. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__1a7i2q4._.js} +1 -1
  104. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1iny24d._.js +3 -0
  106. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tyedjt._.js +3 -0
  108. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +5 -0
  109. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +5 -0
  110. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +5 -0
  111. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  112. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  113. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
  114. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0spkm68._.js +10 -10
  116. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1_a_gwn._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1a2hcb_._.js +3 -0
  118. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1e7-pa7._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rtdfof._.js → [root-of-the-server]__1rdruw4._.js} +1 -1
  120. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tyf0tc._.js +5 -0
  122. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
  123. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
  124. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rag5dg._.js → [root-of-the-server]__1yw368c._.js} +2 -2
  125. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
  126. package/.next/standalone/.next/server/chunks/ssr/_04mekdy._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/_0igtyj5._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/_0r-dsre._.js +3 -0
  129. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/_0se484m._.js +3 -0
  131. package/.next/standalone/.next/server/chunks/ssr/_0uz7o9y._.js +3 -0
  132. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  133. package/.next/standalone/.next/server/chunks/ssr/_1fahg9e._.js +3 -0
  134. package/.next/standalone/.next/server/chunks/ssr/_1gmzkwj._.js +5 -0
  135. package/.next/standalone/.next/server/chunks/ssr/_1w8sola._.js +3 -0
  136. package/.next/standalone/.next/server/chunks/ssr/_1w_6p9g._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  138. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  139. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  140. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
  141. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +5 -0
  143. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  144. package/.next/standalone/.next/server/middleware.js +2 -2
  145. package/.next/standalone/.next/server/pages/404.html +1 -1
  146. package/.next/standalone/.next/server/pages/500.html +1 -1
  147. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  148. package/.next/standalone/.next/server/server-reference-manifest.json +54 -12
  149. package/.next/standalone/.next/static/chunks/{2c90h1g6x8z8y.js → 0_2n13i94rnw5.js} +1 -1
  150. package/.next/standalone/.next/static/chunks/1bm0q12hgs22l.css +2 -0
  151. package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
  152. package/.next/standalone/.next/static/chunks/23557z4e6dtsr.js +1 -0
  153. package/.next/standalone/.next/static/chunks/28zkwzu50puki.js +1 -0
  154. package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
  155. package/.next/standalone/.next/static/chunks/3081gykdubv8b.js +1 -0
  156. package/.next/standalone/.next/static/chunks/{06jakt_xhoolk.js → 34fa65k0cldkj.js} +1 -1
  157. package/.next/standalone/.next/static/chunks/35v07j9gc1pvr.js +6 -0
  158. package/.next/standalone/.next/static/chunks/{2zb3m1tzq6h98.js → 3f_939wi3kfnx.js} +22 -22
  159. package/.next/standalone/.next/static/chunks/{31cqiv_cpgj9m.js → 3p1vpm2_-tfwm.js} +1 -1
  160. package/.next/standalone/.next/static/chunks/{0ue9ak_xexiqh.js → 3rbpw_waieafm.js} +1 -1
  161. package/.next/standalone/.next/static/chunks/40ffnfpkeyvb0.js +1 -0
  162. package/.next/standalone/app/actions/get-hooks-config.ts +2 -1
  163. package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
  164. package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
  165. package/.next/standalone/app/api/audit/run/route.ts +28 -0
  166. package/.next/standalone/app/api/audit/status/route.ts +13 -1
  167. package/.next/standalone/app/api/auth/status/route.ts +1 -1
  168. package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
  169. package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
  170. package/.next/standalone/app/audit/audit-styles.css +6 -149
  171. package/.next/standalone/app/settings/page.tsx +31 -0
  172. package/.next/standalone/app/settings/settings-client.tsx +488 -0
  173. package/.next/standalone/components/navbar.tsx +2 -0
  174. package/.next/standalone/lib/auth/api-server-client.ts +2 -3
  175. package/.next/standalone/lib/auth/auth-store.ts +4 -4
  176. package/.next/standalone/lib/codex-sessions.ts +2 -1
  177. package/.next/standalone/lib/dashboard-host.ts +101 -0
  178. package/.next/standalone/lib/install-check.ts +22 -7
  179. package/.next/standalone/lib/pi-sessions.ts +99 -14
  180. package/.next/standalone/lib/telemetry-enabled.ts +54 -0
  181. package/.next/standalone/lib/telemetry-id.ts +52 -1
  182. package/.next/standalone/lib/telemetry.ts +8 -4
  183. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  184. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  185. package/.next/standalone/node_modules/react/package.json +3 -3
  186. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  187. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  188. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  189. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  190. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  191. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  192. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  193. package/.next/standalone/package.json +7 -6
  194. package/.next/standalone/proxy.ts +89 -1
  195. package/.next/standalone/server.js +1 -1
  196. package/bin/failproofai.mjs +197 -80
  197. package/dist/cli.mjs +17699 -15345
  198. package/dist/worker.mjs +1620 -257
  199. package/lib/auth/api-server-client.ts +2 -3
  200. package/lib/auth/auth-store.ts +4 -4
  201. package/lib/codex-sessions.ts +2 -1
  202. package/lib/dashboard-host.ts +101 -0
  203. package/lib/install-check.ts +22 -7
  204. package/lib/pi-sessions.ts +99 -14
  205. package/lib/telemetry-enabled.ts +54 -0
  206. package/lib/telemetry-id.ts +52 -1
  207. package/lib/telemetry.ts +8 -4
  208. package/package.json +7 -6
  209. package/scripts/install-telemetry.mjs +8 -1
  210. package/scripts/launch.ts +25 -3
  211. package/scripts/parse-script-args.ts +17 -1
  212. package/scripts/prune-standalone.mjs +20 -0
  213. package/scripts/translate-docs/readme-translator.ts +163 -4
  214. package/scripts/validate-mdx.ts +153 -13
  215. package/src/audit/audit-lock.ts +285 -0
  216. package/src/audit/audit-schedule.ts +111 -0
  217. package/src/audit/cache.ts +18 -4
  218. package/src/audit/cli-adapters/goose.ts +2 -1
  219. package/src/audit/cli-adapters/hermes.ts +28 -10
  220. package/src/audit/cli.ts +191 -35
  221. package/src/audit/dashboard-cache.ts +2 -1
  222. package/src/hooks/builtin-policies.ts +100 -3
  223. package/src/hooks/cloud-connection.ts +163 -14
  224. package/src/hooks/cloud-enrollment-cli.ts +119 -21
  225. package/src/hooks/cloud-enrollment.ts +87 -17
  226. package/src/hooks/cloud-introspect.ts +147 -0
  227. package/src/hooks/cloud-managed-policies.ts +33 -2
  228. package/src/hooks/collector-config.ts +32 -40
  229. package/src/hooks/configure-wizard.ts +696 -318
  230. package/src/hooks/custom-hooks-loader.ts +125 -11
  231. package/src/hooks/daemon-client.ts +83 -17
  232. package/src/hooks/daemon-download.ts +54 -2
  233. package/src/hooks/daemon-service.ts +595 -27
  234. package/src/hooks/first-run-gate.ts +39 -0
  235. package/src/hooks/fp-config.ts +497 -0
  236. package/src/hooks/fp-home.ts +342 -0
  237. package/src/hooks/fp-reset.ts +332 -0
  238. package/src/hooks/handler.ts +42 -1
  239. package/src/hooks/hook-activity-store.ts +35 -20
  240. package/src/hooks/hook-logger.ts +2 -1
  241. package/src/hooks/hook-telemetry.ts +5 -1
  242. package/src/hooks/hooks-config.ts +4 -3
  243. package/src/hooks/loader-utils.ts +166 -5
  244. package/src/hooks/manager.ts +5 -4
  245. package/src/hooks/onboarding-lock.ts +119 -0
  246. package/src/hooks/policy-types.ts +0 -7
  247. package/src/hooks/session-pause-cli.ts +15 -13
  248. package/src/hooks/session-pause.ts +36 -4
  249. package/src/hooks/setup-state.ts +256 -0
  250. package/src/hooks/tui.ts +4 -4
  251. package/src/hooks/worker-server.ts +53 -1
  252. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0f8nu8d._.js +0 -3
  253. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0szqzl8._.js +0 -3
  254. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
  255. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
  256. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
  257. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
  258. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
  259. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
  260. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0cmdyn_._.js +0 -3
  261. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
  262. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
  263. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ls0gsr._.js +0 -4
  264. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n_uvv0._.js +0 -3
  265. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
  266. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0sdrz-j._.js +0 -3
  267. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
  268. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
  269. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1j4u3yd._.js +0 -4
  270. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
  271. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
  272. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_1q9xxca.js +0 -3
  273. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
  274. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
  275. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
  276. package/.next/standalone/.next/static/chunks/0oe2-hp0_2tzs.js +0 -6
  277. package/.next/standalone/.next/static/chunks/1fw3pxobk_otl.js +0 -1
  278. package/.next/standalone/.next/static/chunks/3h5_3u46gu9jx.js +0 -1
  279. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
  280. package/.next/standalone/.next/static/chunks/3zdwnnthucs_1.css +0 -2
  281. package/.next/standalone/.next/static/chunks/43a1ywqsg9bq9.js +0 -1
  282. package/.next/standalone/Cargo.lock +0 -2222
  283. package/.next/standalone/Cargo.toml +0 -9
  284. package/.next/standalone/crates/CLOUD_POLICIES.md +0 -136
  285. package/.next/standalone/crates/PROTOCOL.md +0 -122
  286. package/.next/standalone/crates/failproofaid/Cargo.toml +0 -25
  287. package/.next/standalone/crates/failproofaid/src/cloud_client.rs +0 -484
  288. package/.next/standalone/crates/failproofaid/src/cloud_policies.rs +0 -921
  289. package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
  290. package/.next/standalone/crates/failproofaid/src/main.rs +0 -532
  291. package/.next/standalone/crates/failproofaid/src/paths.rs +0 -201
  292. package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
  293. package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
  294. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
  295. package/.next/standalone/crates/fpai-collect/Cargo.toml +0 -43
  296. package/.next/standalone/crates/fpai-collect/src/config.rs +0 -412
  297. package/.next/standalone/crates/fpai-collect/src/cursor.rs +0 -520
  298. package/.next/standalone/crates/fpai-collect/src/delivery.rs +0 -472
  299. package/.next/standalone/crates/fpai-collect/src/filetail.rs +0 -484
  300. package/.next/standalone/crates/fpai-collect/src/health.rs +0 -369
  301. package/.next/standalone/crates/fpai-collect/src/lib.rs +0 -34
  302. package/.next/standalone/crates/fpai-collect/src/redact.rs +0 -516
  303. package/.next/standalone/crates/fpai-collect/src/sources/claude/mod.rs +0 -279
  304. package/.next/standalone/crates/fpai-collect/src/sources/claude/transform.rs +0 -619
  305. package/.next/standalone/crates/fpai-collect/src/sources/codex/mod.rs +0 -156
  306. package/.next/standalone/crates/fpai-collect/src/sources/codex/transform.rs +0 -715
  307. package/.next/standalone/crates/fpai-collect/src/sources/copilot/mod.rs +0 -158
  308. package/.next/standalone/crates/fpai-collect/src/sources/copilot/transform.rs +0 -512
  309. package/.next/standalone/crates/fpai-collect/src/sources/goose/mod.rs +0 -511
  310. package/.next/standalone/crates/fpai-collect/src/sources/goose/transform.rs +0 -586
  311. package/.next/standalone/crates/fpai-collect/src/sources/hermes/mod.rs +0 -318
  312. package/.next/standalone/crates/fpai-collect/src/sources/hermes/transform.rs +0 -579
  313. package/.next/standalone/crates/fpai-collect/src/sources/hooks/mod.rs +0 -310
  314. package/.next/standalone/crates/fpai-collect/src/sources/hooks/transform.rs +0 -448
  315. package/.next/standalone/crates/fpai-collect/src/sources/mod.rs +0 -23
  316. package/.next/standalone/crates/fpai-collect/src/sources/openclaw/mod.rs +0 -176
  317. package/.next/standalone/crates/fpai-collect/src/sources/openclaw/transform.rs +0 -500
  318. package/.next/standalone/crates/fpai-collect/src/sources/opencode/mod.rs +0 -315
  319. package/.next/standalone/crates/fpai-collect/src/sources/opencode/transform.rs +0 -493
  320. package/.next/standalone/crates/fpai-collect/src/sources/pi/mod.rs +0 -201
  321. package/.next/standalone/crates/fpai-collect/src/sources/pi/transform.rs +0 -533
  322. package/.next/standalone/crates/fpai-collect/src/spool.rs +0 -458
  323. package/.next/standalone/crates/fpai-collect/src/sqlitepoll.rs +0 -387
  324. package/.next/standalone/crates/fpai-collect/src/supervisor.rs +0 -423
  325. package/.next/standalone/crates/fpai-collect/src/uploader.rs +0 -600
  326. package/.next/standalone/crates/fpai-collect/tests/claude_source.rs +0 -738
  327. package/.next/standalone/crates/fpai-collect/tests/claude_subagents.rs +0 -393
  328. package/.next/standalone/crates/fpai-collect/tests/codex_source.rs +0 -975
  329. package/.next/standalone/crates/fpai-collect/tests/config.rs +0 -286
  330. package/.next/standalone/crates/fpai-collect/tests/copilot_source.rs +0 -1019
  331. package/.next/standalone/crates/fpai-collect/tests/delivery.rs +0 -281
  332. package/.next/standalone/crates/fpai-collect/tests/goose_source.rs +0 -1008
  333. package/.next/standalone/crates/fpai-collect/tests/hermes_source.rs +0 -1129
  334. package/.next/standalone/crates/fpai-collect/tests/hooks_source.rs +0 -621
  335. package/.next/standalone/crates/fpai-collect/tests/openclaw_source.rs +0 -854
  336. package/.next/standalone/crates/fpai-collect/tests/opencode_source.rs +0 -1478
  337. package/.next/standalone/crates/fpai-collect/tests/pi_source.rs +0 -1191
  338. package/.next/standalone/crates/fpai-collect/tests/supervisor.rs +0 -290
  339. package/.next/standalone/crates/fpai-collect/tests/uploader.rs +0 -506
  340. package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
  341. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
  342. package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
  343. package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
  344. package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
  345. package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
  346. package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
  347. package/.next/standalone/integration-suite/Dockerfile +0 -47
  348. package/.next/standalone/integration-suite/README.md +0 -129
  349. package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
  350. package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
  351. package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
  352. package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
  353. package/.next/standalone/integration-suite/install-clis.sh +0 -136
  354. package/.next/standalone/integration-suite/probe-cli.sh +0 -248
  355. package/.next/standalone/integration-suite/report.js +0 -120
  356. package/.next/standalone/integration-suite/run.sh +0 -159
  357. package/.next/standalone/openclaw-plugin/index.js +0 -223
  358. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
  359. package/.next/standalone/openclaw-plugin/package.json +0 -12
  360. package/.next/standalone/osv-scanner.toml +0 -17
  361. package/.next/standalone/pi-extension/index.ts +0 -524
  362. package/.next/standalone/pi-extension/package.json +0 -12
  363. package/.next/standalone/postcss.config.mjs +0 -8
  364. package/.next/standalone/readme-arch-hq.gif +0 -0
  365. package/.next/standalone/rust-toolchain.toml +0 -4
  366. package/src/auth/cli.ts +0 -371
  367. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_buildManifest.js +0 -0
  368. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_clientMiddlewareManifest.js +0 -0
  369. /package/.next/standalone/.next/static/{StV6Lay7Q1cU4ysYCFJmH → Ptn8aBQl_cnNgOd0ebyv0}/_ssgManifest.js +0 -0
package/dist/worker.mjs CHANGED
@@ -362,6 +362,37 @@ function normalizeCliPayload(cli, parsed) {
362
362
  }
363
363
  }
364
364
 
365
+ // src/hooks/fp-home.ts
366
+ import { homedir } from "node:os";
367
+ import { resolve } from "node:path";
368
+ function failproofaiHome(home) {
369
+ if (home)
370
+ return resolve(home, ".failproofai");
371
+ return process.env.FAILPROOFAI_HOME || resolve(homedir(), ".failproofai");
372
+ }
373
+ var LAYOUT_VERSION = 2, at = (...parts) => resolve(failproofaiHome(), ...parts), atHome = (home, ...parts) => home ? resolve(failproofaiHome(home), ...parts) : at(...parts), versionFile = (home) => atHome(home, "VERSION"), configFile = (home) => atHome(home, "config.toml"), policiesDir = (home) => atHome(home, "policies"), localPoliciesDir = (home) => atHome(home, "policies", "local-policies"), globalPolicyConfigFile = (home) => resolve(localPoliciesDir(home), "policies-config.json"), cloudPoliciesDir = (home) => resolve(policiesDir(home), "cloud-policies"), customPoliciesDir = (home) => resolve(policiesDir(home), "custom-policies"), hookActivityDir = (home) => atHome(home, "hook-activity"), stateDir = (home) => atHome(home, "state"), shimsDir = (home) => resolve(stateDir(home), "shims"), sessionPauseDir = () => resolve(stateDir(), "sessions"), telemetryIdFile = (home) => resolve(stateDir(home), "telemetry-id"), codexSessionPathsFile = (home) => resolve(stateDir(home), "codex-session-paths.json"), logsDir = (home) => atHome(home, "logs"), legacy;
374
+ var init_fp_home = __esm(() => {
375
+ legacy = {
376
+ policyConfig: () => at("policies-config.json"),
377
+ policyConfigLocal: () => at("policies-config.local.json"),
378
+ cloudCredentials: () => at("cloud.json"),
379
+ ingestCredentials: () => at("ingest.json"),
380
+ launcherMarker: () => at(".launcher-configured"),
381
+ lastVersion: () => at("last-version"),
382
+ auditDashboard: () => at("audit-dashboard.json"),
383
+ cacheDir: () => at("cache"),
384
+ hookActivityDir: () => at("cache", "hook-activity"),
385
+ auditCacheDir: () => at("cache", "audit"),
386
+ codexSessionPaths: () => at("cache", "codex-session-paths.json"),
387
+ spoolDir: () => at("spool"),
388
+ failedDir: () => at("failed"),
389
+ collectorHealth: () => at("collector-health.json"),
390
+ sessionPauseDir: () => at("state", "sessions"),
391
+ cloudManagedPolicies: () => at("policies", "cloud-managed"),
392
+ onboardingLock: () => at(".onboarding.lock")
393
+ };
394
+ });
395
+
365
396
  // src/hooks/hook-logger.ts
366
397
  import {
367
398
  appendFileSync,
@@ -371,7 +402,6 @@ import {
371
402
  statSync
372
403
  } from "node:fs";
373
404
  import { join } from "node:path";
374
- import { homedir } from "node:os";
375
405
  function ensureResolved() {
376
406
  if (resolved)
377
407
  return;
@@ -443,15 +473,16 @@ function hookLogError(msg) {
443
473
  }
444
474
  var LEVEL_ORDER, MAX_FILE_SIZE, LOG_FILENAME = "hooks.log", DEFAULT_LOG_DIR, resolved = false, currentLevel = "warn", fileLoggingEnabled = false, logDir;
445
475
  var init_hook_logger = __esm(() => {
476
+ init_fp_home();
446
477
  LEVEL_ORDER = { info: 0, warn: 1, error: 2 };
447
478
  MAX_FILE_SIZE = 512 * 1024;
448
- DEFAULT_LOG_DIR = join(homedir(), ".failproofai", "logs");
479
+ DEFAULT_LOG_DIR = logsDir();
449
480
  logDir = DEFAULT_LOG_DIR;
450
481
  });
451
482
 
452
483
  // src/hooks/hooks-config.ts
453
484
  import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, statSync as statSync2 } from "node:fs";
454
- import { resolve, dirname } from "node:path";
485
+ import { resolve as resolve2, dirname } from "node:path";
455
486
  import { homedir as homedir2 } from "node:os";
456
487
  function readConfigAt(path) {
457
488
  if (!existsSync2(path))
@@ -466,9 +497,9 @@ function readConfigAt(path) {
466
497
  }
467
498
  function findProjectConfigDir(start) {
468
499
  const home = homedir2();
469
- let dir = resolve(start);
500
+ let dir = resolve2(start);
470
501
  while (dir !== home) {
471
- const marker = resolve(dir, ".failproofai");
502
+ const marker = resolve2(dir, ".failproofai");
472
503
  try {
473
504
  if (statSync2(marker).isDirectory())
474
505
  return dir;
@@ -478,13 +509,13 @@ function findProjectConfigDir(start) {
478
509
  break;
479
510
  dir = parent;
480
511
  }
481
- return resolve(start);
512
+ return resolve2(start);
482
513
  }
483
514
  function readMergedHooksConfig(cwd) {
484
515
  const base = findProjectConfigDir(cwd ?? process.cwd());
485
- const projectPath = resolve(base, ".failproofai", "policies-config.json");
486
- const localPath = resolve(base, ".failproofai", "policies-config.local.json");
487
- const globalPath = resolve(homedir2(), ".failproofai", "policies-config.json");
516
+ const projectPath = resolve2(base, ".failproofai", "policies-config.json");
517
+ const localPath = resolve2(base, ".failproofai", "policies-config.local.json");
518
+ const globalPath = globalPolicyConfigFile();
488
519
  const project = readConfigAt(projectPath);
489
520
  const local = readConfigAt(localPath);
490
521
  const global_ = readConfigAt(globalPath);
@@ -522,6 +553,7 @@ function readMergedHooksConfig(cwd) {
522
553
  }
523
554
  var init_hooks_config = __esm(() => {
524
555
  init_hook_logger();
556
+ init_fp_home();
525
557
  });
526
558
 
527
559
  // src/hooks/policy-helpers.ts
@@ -596,7 +628,7 @@ function clearPolicies() {
596
628
  var REGISTRY_KEY = "__FAILPROOFAI_POLICY_REGISTRY__", INDEX_CACHE_KEY = "__FAILPROOFAI_POLICY_INDEX_CACHE__", DEFAULT_POLICY_NAMESPACE = "failproofai";
597
629
 
598
630
  // src/hooks/builtin-policies.ts
599
- import { resolve as resolve2, join as join2 } from "node:path";
631
+ import { resolve as resolve3, join as join2 } from "node:path";
600
632
  import { statSync as statSync3 } from "node:fs";
601
633
  import { readFile, writeFile } from "node:fs/promises";
602
634
  import { execSync, execFileSync } from "node:child_process";
@@ -655,6 +687,30 @@ function getFilePath(ctx) {
655
687
  function parseArgvTokens(cmd) {
656
688
  return cmd.trim().split(/\s+/).map((t) => t.replace(/^['"]|['"]$/g, ""));
657
689
  }
690
+ function namesSelfPause(command) {
691
+ for (const segment of command.split(SEGMENT_SEPARATORS)) {
692
+ const tokens = segment.split(/\s+/).filter(Boolean);
693
+ let i = 0;
694
+ while (i < tokens.length) {
695
+ const token = tokens[i];
696
+ const isSkippable = ENV_ASSIGNMENT_RE.test(token) || token.startsWith("-") || token.startsWith(">") || token.startsWith("<") || RUNNER_OPERAND_RE.test(token) || COMMAND_PREFIX_TOKENS.has(token.slice(token.lastIndexOf("/") + 1));
697
+ if (!isSkippable)
698
+ break;
699
+ i++;
700
+ }
701
+ if (i >= tokens.length)
702
+ continue;
703
+ if (!SELF_BINARY_TOKEN_RE.test(tokens[i]))
704
+ continue;
705
+ const args = tokens.slice(i + 1);
706
+ const configAt = args.findIndex((a) => CONFIG_SUBCOMMAND_RE.test(a));
707
+ if (configAt === -1)
708
+ continue;
709
+ if (args.slice(configAt + 1).some((a) => PAUSE_FLAG_RE.test(a)))
710
+ return true;
711
+ }
712
+ return false;
713
+ }
658
714
  function decodeAnsiC(body) {
659
715
  return body.replace(/\\(x[0-9A-Fa-f]{1,2}|u[0-9A-Fa-f]{1,4}|U[0-9A-Fa-f]{1,8}|[0-7]{1,3}|.)/g, (_, seq) => {
660
716
  try {
@@ -956,7 +1012,7 @@ function blockSelfPause(ctx) {
956
1012
  if (ctx.toolName !== "Bash")
957
1013
  return allow();
958
1014
  const cmd = getCommand(ctx);
959
- if (SELF_PAUSE_RE.test(cmd) || SELF_PAUSE_RE.test(stripShellQuoting(cmd))) {
1015
+ if (namesSelfPause(cmd) || namesSelfPause(stripShellQuoting(cmd))) {
960
1016
  return deny("Pausing failproofai enforcement is a human action, not an agent one. " + "If a policy is blocking legitimate work, say so and let the operator decide.");
961
1017
  }
962
1018
  return allow();
@@ -1186,7 +1242,7 @@ function blockReadOutsideCwd(ctx) {
1186
1242
  const paths = extractAbsolutePaths(cmd);
1187
1243
  const cwdWithSep2 = cwd.endsWith("/") ? cwd : cwd + "/";
1188
1244
  for (const p of paths) {
1189
- const resolved3 = resolve2(cwd, p);
1245
+ const resolved3 = resolve3(cwd, p);
1190
1246
  if (isClaudeSettingsFile(resolved3)) {
1191
1247
  return deny(`Reading agent settings file blocked: ${resolved3}`);
1192
1248
  }
@@ -1207,7 +1263,7 @@ function blockReadOutsideCwd(ctx) {
1207
1263
  const target = filePath || searchPath;
1208
1264
  if (!target)
1209
1265
  return allow();
1210
- const resolved2 = resolve2(cwd, target);
1266
+ const resolved2 = resolve3(cwd, target);
1211
1267
  if (isClaudeSettingsFile(resolved2)) {
1212
1268
  return deny(`Reading agent settings file blocked: ${resolved2}`);
1213
1269
  }
@@ -1698,7 +1754,7 @@ function registerBuiltinPolicies(enabledNames) {
1698
1754
  }
1699
1755
  }
1700
1756
  }
1701
- var isClaudeInternalPath, isClaudeSettingsFile, SHELL_OPERATORS, SHELL_METACHAR_RE, JWT_RE, API_KEY_PATTERNS, CONNECTION_STRING_RE, PRIVATE_KEY_RE, BEARER_TOKEN_RE, SQL_TOOL_RE, DESTRUCTIVE_SQL_RE, DELETE_NO_WHERE_RE, SQL_WHERE_RE, SCHEMA_ALTER_RE, PUBLISH_CMD_RE, ENV_PRINTENV_RE, ECHO_ENV_RE, EXPORT_RE, PS_ENV_VAR_RE, PS_CHILDITEM_ENV_RE, DOTNET_GETENV_RE, CMD_ECHO_ENV_RE, ENV_FILE_PATH_RE, ENV_CMD_RE, SUDO_RE, PS_ELEVATION_RE, RUNAS_RE, CURL_PIPE_SH_RE, SELF_PAUSE_RE, PS_WEB_PIPE_RE, SHORT_FLAG_BUNDLE_RE, SAFE_FORCE_PREFIXES, SECRET_FILE_RE, SECRET_FILE_ID_RSA_RE, SECRET_FILE_CREDENTIALS_RE, GIT_COMMIT_MERGE_RE, FAILPROOFAI_CLI_RE, FAILPROOFAI_UNINSTALL_RE, GIT_AMEND_RE, GIT_STASH_DROP_RE, GIT_ADD_ALL_RE, NPM_GLOBAL_RE, YARN_GLOBAL_RE, PNPM_GLOBAL_RE, BUN_GLOBAL_RE, CARGO_INSTALL_RE, PIP_SYSTEM_RE, PKG_MANAGER_DETECTORS, NOHUP_RE, SCREEN_DETACH_RE, TMUX_DETACH_RE, DISOWN_RE, BACKGROUND_AMPERSAND_RE, KUBECTL_RE, TERRAFORM_RE, AWS_CLI_RE, GCLOUD_RE, AZ_CLI_RE, HELM_RE, GH_PIPELINE_RE, gitBranchCache, GIT_BRANCH_CACHE_MAX_ENTRIES = 500, HOME_PREFIX_RE, RM_CMD_RE, FIND_CMD_RE, FIND_EXEC_RE, FIND_GLOBAL_OPT_RE, FIND_EXPR_START_RE, SCRATCH_ROOTS, CATASTROPHIC_DEPTH = 2, READ_LIKE_CMDS, TOOL_CALL_TRACKER_MAX_BYTES = 65536, SEGMENT_SPLIT_RE, BUILTIN_POLICIES;
1757
+ var isClaudeInternalPath, isClaudeSettingsFile, SHELL_OPERATORS, SHELL_METACHAR_RE, JWT_RE, API_KEY_PATTERNS, CONNECTION_STRING_RE, PRIVATE_KEY_RE, BEARER_TOKEN_RE, SQL_TOOL_RE, DESTRUCTIVE_SQL_RE, DELETE_NO_WHERE_RE, SQL_WHERE_RE, SCHEMA_ALTER_RE, PUBLISH_CMD_RE, ENV_PRINTENV_RE, ECHO_ENV_RE, EXPORT_RE, PS_ENV_VAR_RE, PS_CHILDITEM_ENV_RE, DOTNET_GETENV_RE, CMD_ECHO_ENV_RE, ENV_FILE_PATH_RE, ENV_CMD_RE, SUDO_RE, PS_ELEVATION_RE, RUNAS_RE, CURL_PIPE_SH_RE, SEGMENT_SEPARATORS, COMMAND_PREFIX_TOKENS, SELF_BINARY_TOKEN_RE, CONFIG_SUBCOMMAND_RE, PAUSE_FLAG_RE, ENV_ASSIGNMENT_RE, RUNNER_OPERAND_RE, PS_WEB_PIPE_RE, SHORT_FLAG_BUNDLE_RE, SAFE_FORCE_PREFIXES, SECRET_FILE_RE, SECRET_FILE_ID_RSA_RE, SECRET_FILE_CREDENTIALS_RE, GIT_COMMIT_MERGE_RE, FAILPROOFAI_CLI_RE, FAILPROOFAI_UNINSTALL_RE, GIT_AMEND_RE, GIT_STASH_DROP_RE, GIT_ADD_ALL_RE, NPM_GLOBAL_RE, YARN_GLOBAL_RE, PNPM_GLOBAL_RE, BUN_GLOBAL_RE, CARGO_INSTALL_RE, PIP_SYSTEM_RE, PKG_MANAGER_DETECTORS, NOHUP_RE, SCREEN_DETACH_RE, TMUX_DETACH_RE, DISOWN_RE, BACKGROUND_AMPERSAND_RE, KUBECTL_RE, TERRAFORM_RE, AWS_CLI_RE, GCLOUD_RE, AZ_CLI_RE, HELM_RE, GH_PIPELINE_RE, gitBranchCache, GIT_BRANCH_CACHE_MAX_ENTRIES = 500, HOME_PREFIX_RE, RM_CMD_RE, FIND_CMD_RE, FIND_EXEC_RE, FIND_GLOBAL_OPT_RE, FIND_EXPR_START_RE, SCRATCH_ROOTS, CATASTROPHIC_DEPTH = 2, READ_LIKE_CMDS, TOOL_CALL_TRACKER_MAX_BYTES = 65536, SEGMENT_SPLIT_RE, BUILTIN_POLICIES;
1702
1758
  var init_builtin_policies = __esm(() => {
1703
1759
  init_hook_logger();
1704
1760
  isClaudeInternalPath = isAgentInternalPath;
@@ -1739,7 +1795,45 @@ var init_builtin_policies = __esm(() => {
1739
1795
  PS_ELEVATION_RE = /Start-Process\s+.*-Verb\s+RunAs/i;
1740
1796
  RUNAS_RE = /(?:^|;|&&|\|\|)\s*runas\s/i;
1741
1797
  CURL_PIPE_SH_RE = /(?:curl|wget)\s.*\|\s*(?:sh|bash|zsh|dash|ksh|csh|tcsh|fish|ash)\b/;
1742
- SELF_PAUSE_RE = /failproofai[^\s]*(?:\s+\S+)*?\s+(?:config|configure|setup)\b(?:\s+\S+)*?\s+--pause\b/;
1798
+ SEGMENT_SEPARATORS = /[;&|\n\r(){}`]+/;
1799
+ COMMAND_PREFIX_TOKENS = new Set([
1800
+ "npx",
1801
+ "bunx",
1802
+ "pnpx",
1803
+ "npm",
1804
+ "pnpm",
1805
+ "yarn",
1806
+ "dlx",
1807
+ "exec",
1808
+ "run",
1809
+ "node",
1810
+ "bun",
1811
+ "deno",
1812
+ "env",
1813
+ "command",
1814
+ "builtin",
1815
+ "nohup",
1816
+ "setsid",
1817
+ "time",
1818
+ "timeout",
1819
+ "nice",
1820
+ "stdbuf",
1821
+ "xargs",
1822
+ "sudo",
1823
+ "doas",
1824
+ "sh",
1825
+ "bash",
1826
+ "zsh",
1827
+ "dash",
1828
+ "ksh",
1829
+ "fish",
1830
+ "ash"
1831
+ ]);
1832
+ SELF_BINARY_TOKEN_RE = /(?:^|\/)failproofai[^/]*$/;
1833
+ CONFIG_SUBCOMMAND_RE = /^(?:config|configure|setup)$/;
1834
+ PAUSE_FLAG_RE = /^--pause(?:=|$)/;
1835
+ ENV_ASSIGNMENT_RE = /^[A-Za-z_][A-Za-z0-9_]*=/;
1836
+ RUNNER_OPERAND_RE = /^\d+[a-z]*$/i;
1743
1837
  PS_WEB_PIPE_RE = /(?:Invoke-WebRequest|iwr|Invoke-RestMethod|irm)\s+.*\|\s*(?:Invoke-Expression|iex)/i;
1744
1838
  SHORT_FLAG_BUNDLE_RE = /^-[a-zA-Z]*f[a-zA-Z]*$/;
1745
1839
  SAFE_FORCE_PREFIXES = ["--force-with-lease", "--force-if-includes"];
@@ -2340,12 +2434,1080 @@ var init_builtin_policies = __esm(() => {
2340
2434
  });
2341
2435
 
2342
2436
  // package.json
2343
- var version = "1.0.0-beta.4";
2437
+ var version = "1.0.0-beta.6";
2344
2438
  var init_package = () => {};
2345
2439
 
2346
2440
  // src/posthog-key.ts
2347
2441
  var POSTHOG_API_KEY = "phc_Ac1Ww1GqKc0z1SyrRWbmatEeQdlOQIsDEEdP8l8JRgX", POSTHOG_PRODUCT = "failproofai-oss";
2348
2442
 
2443
+ // node_modules/smol-toml/dist/date.js
2444
+ var DATE_TIME_RE, TomlDate;
2445
+ var init_date = __esm(() => {
2446
+ /*!
2447
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2448
+ * SPDX-License-Identifier: BSD-3-Clause
2449
+ *
2450
+ * Redistribution and use in source and binary forms, with or without
2451
+ * modification, are permitted provided that the following conditions are met:
2452
+ *
2453
+ * 1. Redistributions of source code must retain the above copyright notice, this
2454
+ * list of conditions and the following disclaimer.
2455
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2456
+ * this list of conditions and the following disclaimer in the
2457
+ * documentation and/or other materials provided with the distribution.
2458
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2459
+ * may be used to endorse or promote products derived from this software without
2460
+ * specific prior written permission.
2461
+ *
2462
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2463
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2464
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2465
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2466
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2467
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2468
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2469
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2470
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2471
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2472
+ */
2473
+ DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
2474
+ TomlDate = class TomlDate extends Date {
2475
+ #hasDate = false;
2476
+ #hasTime = false;
2477
+ #offset = null;
2478
+ constructor(date) {
2479
+ let hasDate = true;
2480
+ let hasTime = true;
2481
+ let offset = "Z";
2482
+ if (typeof date === "string") {
2483
+ let match = date.match(DATE_TIME_RE);
2484
+ if (match) {
2485
+ if (!match[1]) {
2486
+ hasDate = false;
2487
+ date = `0000-01-01T${date}`;
2488
+ }
2489
+ hasTime = !!match[2];
2490
+ hasTime && date[10] === " " && (date = date.replace(" ", "T"));
2491
+ if (match[2] && +match[2] > 23) {
2492
+ date = "";
2493
+ } else {
2494
+ offset = match[3] || null;
2495
+ date = date.toUpperCase();
2496
+ if (!offset && hasTime)
2497
+ date += "Z";
2498
+ }
2499
+ } else {
2500
+ date = "";
2501
+ }
2502
+ }
2503
+ super(date);
2504
+ if (!isNaN(this.getTime())) {
2505
+ this.#hasDate = hasDate;
2506
+ this.#hasTime = hasTime;
2507
+ this.#offset = offset;
2508
+ }
2509
+ }
2510
+ isDateTime() {
2511
+ return this.#hasDate && this.#hasTime;
2512
+ }
2513
+ isLocal() {
2514
+ return !this.#hasDate || !this.#hasTime || !this.#offset;
2515
+ }
2516
+ isDate() {
2517
+ return this.#hasDate && !this.#hasTime;
2518
+ }
2519
+ isTime() {
2520
+ return this.#hasTime && !this.#hasDate;
2521
+ }
2522
+ isValid() {
2523
+ return this.#hasDate || this.#hasTime;
2524
+ }
2525
+ toISOString() {
2526
+ let iso = super.toISOString();
2527
+ if (this.isDate())
2528
+ return iso.slice(0, 10);
2529
+ if (this.isTime())
2530
+ return iso.slice(11, 23);
2531
+ if (this.#offset === null)
2532
+ return iso.slice(0, -1);
2533
+ if (this.#offset === "Z")
2534
+ return iso;
2535
+ let offset = +this.#offset.slice(1, 3) * 60 + +this.#offset.slice(4, 6);
2536
+ offset = this.#offset[0] === "-" ? offset : -offset;
2537
+ let offsetDate = new Date(this.getTime() - offset * 60000);
2538
+ return offsetDate.toISOString().slice(0, -1) + this.#offset;
2539
+ }
2540
+ static wrapAsOffsetDateTime(jsDate, offset = "Z") {
2541
+ let date = new TomlDate(jsDate);
2542
+ date.#offset = offset;
2543
+ return date;
2544
+ }
2545
+ static wrapAsLocalDateTime(jsDate) {
2546
+ let date = new TomlDate(jsDate);
2547
+ date.#offset = null;
2548
+ return date;
2549
+ }
2550
+ static wrapAsLocalDate(jsDate) {
2551
+ let date = new TomlDate(jsDate);
2552
+ date.#hasTime = false;
2553
+ date.#offset = null;
2554
+ return date;
2555
+ }
2556
+ static wrapAsLocalTime(jsDate) {
2557
+ let date = new TomlDate(jsDate);
2558
+ date.#hasDate = false;
2559
+ date.#offset = null;
2560
+ return date;
2561
+ }
2562
+ };
2563
+ });
2564
+
2565
+ // node_modules/smol-toml/dist/error.js
2566
+ function getLineColFromPtr(string, ptr) {
2567
+ let lines = string.slice(0, ptr).split(/\r\n|\n|\r/g);
2568
+ return [lines.length, lines.pop().length + 1];
2569
+ }
2570
+ function makeCodeBlock(string, line, column) {
2571
+ let lines = string.split(/\r\n|\n|\r/g);
2572
+ let codeblock = "";
2573
+ let numberLen = (Math.log10(line + 1) | 0) + 1;
2574
+ for (let i = line - 1;i <= line + 1; i++) {
2575
+ let l = lines[i - 1];
2576
+ if (!l)
2577
+ continue;
2578
+ codeblock += i.toString().padEnd(numberLen, " ");
2579
+ codeblock += ": ";
2580
+ codeblock += l;
2581
+ codeblock += `
2582
+ `;
2583
+ if (i === line) {
2584
+ codeblock += " ".repeat(numberLen + column + 2);
2585
+ codeblock += `^
2586
+ `;
2587
+ }
2588
+ }
2589
+ return codeblock;
2590
+ }
2591
+ var TomlError;
2592
+ var init_error = __esm(() => {
2593
+ /*!
2594
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2595
+ * SPDX-License-Identifier: BSD-3-Clause
2596
+ *
2597
+ * Redistribution and use in source and binary forms, with or without
2598
+ * modification, are permitted provided that the following conditions are met:
2599
+ *
2600
+ * 1. Redistributions of source code must retain the above copyright notice, this
2601
+ * list of conditions and the following disclaimer.
2602
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2603
+ * this list of conditions and the following disclaimer in the
2604
+ * documentation and/or other materials provided with the distribution.
2605
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2606
+ * may be used to endorse or promote products derived from this software without
2607
+ * specific prior written permission.
2608
+ *
2609
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2610
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2611
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2612
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2613
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2614
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2615
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2616
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2617
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2618
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2619
+ */
2620
+ TomlError = class TomlError extends Error {
2621
+ line;
2622
+ column;
2623
+ codeblock;
2624
+ constructor(message, options) {
2625
+ const [line, column] = getLineColFromPtr(options.toml, options.ptr);
2626
+ const codeblock = makeCodeBlock(options.toml, line, column);
2627
+ super(`Invalid TOML document: ${message}
2628
+
2629
+ ${codeblock}`, options);
2630
+ this.line = line;
2631
+ this.column = column;
2632
+ this.codeblock = codeblock;
2633
+ }
2634
+ };
2635
+ });
2636
+
2637
+ // node_modules/smol-toml/dist/primitive.js
2638
+ function parseString(str, ptr) {
2639
+ let c = str[ptr++];
2640
+ let first = c;
2641
+ let isLiteral = c === "'";
2642
+ let isMultiline = c === str[ptr] && c === str[ptr + 1];
2643
+ if (isMultiline) {
2644
+ if (str[ptr += 2] === `
2645
+ `)
2646
+ ptr++;
2647
+ else if (str[ptr] === "\r" && str[ptr + 1] === `
2648
+ `)
2649
+ ptr += 2;
2650
+ }
2651
+ let parsed = "";
2652
+ let sliceStart = ptr;
2653
+ let state = 0;
2654
+ for (let i = ptr;i < str.length; i++) {
2655
+ c = str[i];
2656
+ if (isMultiline && (c === `
2657
+ ` || c === "\r" && str[i + 1] === `
2658
+ `)) {
2659
+ state = state && 3;
2660
+ } else if (c < " " && c !== "\t" || c === "") {
2661
+ throw new TomlError("control characters are not allowed in strings", {
2662
+ toml: str,
2663
+ ptr: i
2664
+ });
2665
+ } else if ((!state || state === 3) && c === first && (!isMultiline || str[i + 1] === first && str[i + 2] === first)) {
2666
+ if (isMultiline) {
2667
+ if (str[i + 3] === first)
2668
+ i++;
2669
+ if (str[i + 3] === first)
2670
+ i++;
2671
+ }
2672
+ return [
2673
+ state ? parsed : parsed + str.slice(sliceStart, i),
2674
+ i + (isMultiline ? 3 : 1)
2675
+ ];
2676
+ } else if (!state) {
2677
+ if (!isLiteral && c === "\\") {
2678
+ parsed += str.slice(sliceStart, sliceStart = i);
2679
+ state = 1;
2680
+ }
2681
+ } else if (state === 1) {
2682
+ if (c === "x" || c === "u" || c === "U") {
2683
+ let value = 0;
2684
+ let len = c === "x" ? 2 : c === "u" ? 4 : 8;
2685
+ for (let j = 0;j < len; j++, i++) {
2686
+ let hex = str.charCodeAt(i + 1);
2687
+ let digit = hex >= 48 && hex <= 57 ? hex - 48 : hex >= 65 && hex <= 70 ? hex - 65 + 10 : hex >= 97 && hex <= 102 ? hex - 97 + 10 : -1;
2688
+ if (digit < 0)
2689
+ throw new TomlError("invalid non-hex character in unicode escape", { toml: str, ptr: i + 1 });
2690
+ value = value << 4 | digit;
2691
+ }
2692
+ if (value < 0 || value > 1114111 || value >= 55296 && value <= 57343) {
2693
+ throw new TomlError("invalid unicode escape", { toml: str, ptr: i });
2694
+ }
2695
+ parsed += String.fromCodePoint(value);
2696
+ sliceStart = i + 1;
2697
+ state = 0;
2698
+ } else if (c === " " || c === "\t") {
2699
+ state = 2;
2700
+ } else {
2701
+ if (c === "b")
2702
+ parsed += "\b";
2703
+ else if (c === "t")
2704
+ parsed += "\t";
2705
+ else if (c === "n")
2706
+ parsed += `
2707
+ `;
2708
+ else if (c === "f")
2709
+ parsed += "\f";
2710
+ else if (c === "r")
2711
+ parsed += "\r";
2712
+ else if (c === "e")
2713
+ parsed += "\x1B";
2714
+ else if (c === '"')
2715
+ parsed += '"';
2716
+ else if (c === "\\")
2717
+ parsed += "\\";
2718
+ else
2719
+ throw new TomlError("unrecognized escape sequence", { toml: str, ptr: i });
2720
+ sliceStart = i + 1;
2721
+ state = 0;
2722
+ }
2723
+ } else if (c !== " " && c !== "\t") {
2724
+ if (state === 2) {
2725
+ throw new TomlError("invalid escape: only line-ending whitespace may be escaped", {
2726
+ toml: str,
2727
+ ptr: sliceStart
2728
+ });
2729
+ }
2730
+ state = !isLiteral && c === "\\" ? 1 : 0;
2731
+ sliceStart = i;
2732
+ }
2733
+ }
2734
+ throw new TomlError("unfinished string", { toml: str, ptr });
2735
+ }
2736
+ function parseValue(value, toml, ptr, integersAsBigInt) {
2737
+ if (value === "true")
2738
+ return true;
2739
+ if (value === "false")
2740
+ return false;
2741
+ if (value === "-inf")
2742
+ return -Infinity;
2743
+ if (value === "inf" || value === "+inf")
2744
+ return Infinity;
2745
+ if (value === "nan" || value === "+nan" || value === "-nan")
2746
+ return NaN;
2747
+ if (value === "-0")
2748
+ return integersAsBigInt ? 0n : 0;
2749
+ let isInt = INT_REGEX.test(value);
2750
+ if (isInt || FLOAT_REGEX.test(value)) {
2751
+ if (LEADING_ZERO.test(value)) {
2752
+ throw new TomlError("leading zeroes are not allowed", {
2753
+ toml,
2754
+ ptr
2755
+ });
2756
+ }
2757
+ value = value.replace(/_/g, "");
2758
+ let numeric = +value;
2759
+ if (isNaN(numeric)) {
2760
+ throw new TomlError("invalid number", {
2761
+ toml,
2762
+ ptr
2763
+ });
2764
+ }
2765
+ if (isInt) {
2766
+ if ((isInt = !Number.isSafeInteger(numeric)) && !integersAsBigInt) {
2767
+ throw new TomlError("integer value cannot be represented losslessly", {
2768
+ toml,
2769
+ ptr
2770
+ });
2771
+ }
2772
+ if (isInt || integersAsBigInt === true)
2773
+ numeric = BigInt(value);
2774
+ }
2775
+ return numeric;
2776
+ }
2777
+ const date = new TomlDate(value);
2778
+ if (!date.isValid()) {
2779
+ throw new TomlError("invalid value", {
2780
+ toml,
2781
+ ptr
2782
+ });
2783
+ }
2784
+ return date;
2785
+ }
2786
+ var INT_REGEX, FLOAT_REGEX, LEADING_ZERO;
2787
+ var init_primitive = __esm(() => {
2788
+ init_date();
2789
+ init_error();
2790
+ /*!
2791
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2792
+ * SPDX-License-Identifier: BSD-3-Clause
2793
+ *
2794
+ * Redistribution and use in source and binary forms, with or without
2795
+ * modification, are permitted provided that the following conditions are met:
2796
+ *
2797
+ * 1. Redistributions of source code must retain the above copyright notice, this
2798
+ * list of conditions and the following disclaimer.
2799
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2800
+ * this list of conditions and the following disclaimer in the
2801
+ * documentation and/or other materials provided with the distribution.
2802
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2803
+ * may be used to endorse or promote products derived from this software without
2804
+ * specific prior written permission.
2805
+ *
2806
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2807
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2808
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2809
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2810
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2811
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2812
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2813
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2814
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2815
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2816
+ */
2817
+ INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
2818
+ FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
2819
+ LEADING_ZERO = /^[+-]?0[0-9_]/;
2820
+ });
2821
+
2822
+ // node_modules/smol-toml/dist/util.js
2823
+ function indexOfNewline(str, start = 0, end = str.length) {
2824
+ let idx = str.indexOf(`
2825
+ `, start);
2826
+ if (str[idx - 1] === "\r")
2827
+ idx--;
2828
+ return idx <= end ? idx : -1;
2829
+ }
2830
+ function skipComment(str, ptr) {
2831
+ for (let i = ptr;i < str.length; i++) {
2832
+ let c = str[i];
2833
+ if (c === `
2834
+ `)
2835
+ return i;
2836
+ if (c === "\r" && str[i + 1] === `
2837
+ `)
2838
+ return i + 1;
2839
+ if (c < " " && c !== "\t" || c === "") {
2840
+ throw new TomlError("control characters are not allowed in comments", {
2841
+ toml: str,
2842
+ ptr
2843
+ });
2844
+ }
2845
+ }
2846
+ return str.length;
2847
+ }
2848
+ function skipVoid(str, ptr, banNewLines, banComments) {
2849
+ let c;
2850
+ while (true) {
2851
+ while ((c = str[ptr]) === " " || c === "\t" || !banNewLines && (c === `
2852
+ ` || c === "\r" && str[ptr + 1] === `
2853
+ `))
2854
+ ptr++;
2855
+ if (banComments || c !== "#")
2856
+ break;
2857
+ ptr = skipComment(str, ptr);
2858
+ }
2859
+ return ptr;
2860
+ }
2861
+ function skipUntil(str, ptr, sep, end, banNewLines = false) {
2862
+ if (!end) {
2863
+ ptr = indexOfNewline(str, ptr);
2864
+ return ptr < 0 ? str.length : ptr;
2865
+ }
2866
+ for (let i = ptr;i < str.length; i++) {
2867
+ let c = str[i];
2868
+ if (c === "#") {
2869
+ i = indexOfNewline(str, i);
2870
+ if (i < 0)
2871
+ break;
2872
+ } else if (c === sep) {
2873
+ return i + 1;
2874
+ } else if (c === end || banNewLines && (c === `
2875
+ ` || c === "\r" && str[i + 1] === `
2876
+ `)) {
2877
+ return i;
2878
+ }
2879
+ }
2880
+ throw new TomlError("cannot find end of structure", {
2881
+ toml: str,
2882
+ ptr
2883
+ });
2884
+ }
2885
+ var init_util = __esm(() => {
2886
+ init_error();
2887
+ /*!
2888
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2889
+ * SPDX-License-Identifier: BSD-3-Clause
2890
+ *
2891
+ * Redistribution and use in source and binary forms, with or without
2892
+ * modification, are permitted provided that the following conditions are met:
2893
+ *
2894
+ * 1. Redistributions of source code must retain the above copyright notice, this
2895
+ * list of conditions and the following disclaimer.
2896
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2897
+ * this list of conditions and the following disclaimer in the
2898
+ * documentation and/or other materials provided with the distribution.
2899
+ * 3. Neither the name of the copyright holder nor the names of its contributors
2900
+ * may be used to endorse or promote products derived from this software without
2901
+ * specific prior written permission.
2902
+ *
2903
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2904
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2905
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2906
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2907
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2908
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2909
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2910
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2911
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2912
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2913
+ */
2914
+ });
2915
+
2916
+ // node_modules/smol-toml/dist/extract.js
2917
+ function sliceAndTrimEndOf(str, startPtr, endPtr) {
2918
+ let value = str.slice(startPtr, endPtr);
2919
+ let commentIdx = value.indexOf("#");
2920
+ if (commentIdx > -1) {
2921
+ skipComment(str, commentIdx);
2922
+ value = value.slice(0, commentIdx);
2923
+ }
2924
+ return [value.trimEnd(), commentIdx];
2925
+ }
2926
+ function extractValue(str, ptr, end, depth, integersAsBigInt) {
2927
+ if (depth === 0) {
2928
+ throw new TomlError("document contains excessively nested structures. aborting.", {
2929
+ toml: str,
2930
+ ptr
2931
+ });
2932
+ }
2933
+ let c = str[ptr];
2934
+ if (c === "[" || c === "{") {
2935
+ let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
2936
+ if (end) {
2937
+ endPtr2 = skipVoid(str, endPtr2);
2938
+ if (str[endPtr2] === ",")
2939
+ endPtr2++;
2940
+ else if (str[endPtr2] !== end) {
2941
+ throw new TomlError("expected comma or end of structure", {
2942
+ toml: str,
2943
+ ptr: endPtr2
2944
+ });
2945
+ }
2946
+ }
2947
+ return [value, endPtr2];
2948
+ }
2949
+ if (c === '"' || c === "'") {
2950
+ let [parsed, endPtr2] = parseString(str, ptr);
2951
+ if (end) {
2952
+ endPtr2 = skipVoid(str, endPtr2);
2953
+ if (str[endPtr2] && str[endPtr2] !== "," && str[endPtr2] !== end && str[endPtr2] !== `
2954
+ ` && str[endPtr2] !== "\r") {
2955
+ throw new TomlError("unexpected character encountered", {
2956
+ toml: str,
2957
+ ptr: endPtr2
2958
+ });
2959
+ }
2960
+ if (str[endPtr2] === ",")
2961
+ endPtr2++;
2962
+ }
2963
+ return [parsed, endPtr2];
2964
+ }
2965
+ let endPtr = skipUntil(str, ptr, ",", end);
2966
+ let slice = sliceAndTrimEndOf(str, ptr, endPtr - (str[endPtr - 1] === "," ? 1 : 0));
2967
+ if (!slice[0]) {
2968
+ throw new TomlError("incomplete key-value declaration: no value specified", {
2969
+ toml: str,
2970
+ ptr
2971
+ });
2972
+ }
2973
+ if (end && slice[1] > -1) {
2974
+ endPtr = skipVoid(str, ptr + slice[1]);
2975
+ if (str[endPtr] === ",")
2976
+ endPtr++;
2977
+ }
2978
+ return [
2979
+ parseValue(slice[0], str, ptr, integersAsBigInt),
2980
+ endPtr
2981
+ ];
2982
+ }
2983
+ var init_extract = __esm(() => {
2984
+ init_primitive();
2985
+ init_struct();
2986
+ init_util();
2987
+ init_error();
2988
+ /*!
2989
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
2990
+ * SPDX-License-Identifier: BSD-3-Clause
2991
+ *
2992
+ * Redistribution and use in source and binary forms, with or without
2993
+ * modification, are permitted provided that the following conditions are met:
2994
+ *
2995
+ * 1. Redistributions of source code must retain the above copyright notice, this
2996
+ * list of conditions and the following disclaimer.
2997
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
2998
+ * this list of conditions and the following disclaimer in the
2999
+ * documentation and/or other materials provided with the distribution.
3000
+ * 3. Neither the name of the copyright holder nor the names of its contributors
3001
+ * may be used to endorse or promote products derived from this software without
3002
+ * specific prior written permission.
3003
+ *
3004
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3005
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3006
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3007
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
3008
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3009
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3010
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3011
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3012
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3013
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3014
+ */
3015
+ });
3016
+
3017
+ // node_modules/smol-toml/dist/struct.js
3018
+ function parseKey(str, ptr, end = "=") {
3019
+ let dot = ptr - 1;
3020
+ let parsed = [];
3021
+ let endPtr = str.indexOf(end, ptr);
3022
+ if (endPtr < 0) {
3023
+ throw new TomlError("incomplete key-value: cannot find end of key", {
3024
+ toml: str,
3025
+ ptr
3026
+ });
3027
+ }
3028
+ do {
3029
+ let c = str[ptr = ++dot];
3030
+ if (c !== " " && c !== "\t") {
3031
+ if (c === '"' || c === "'") {
3032
+ if (c === str[ptr + 1] && c === str[ptr + 2]) {
3033
+ throw new TomlError("multiline strings are not allowed in keys", {
3034
+ toml: str,
3035
+ ptr
3036
+ });
3037
+ }
3038
+ let [part, eos] = parseString(str, ptr);
3039
+ dot = str.indexOf(".", eos);
3040
+ let strEnd = str.slice(eos, dot < 0 || dot > endPtr ? endPtr : dot);
3041
+ let newLine = indexOfNewline(strEnd);
3042
+ if (newLine > -1) {
3043
+ throw new TomlError("newlines are not allowed in keys", {
3044
+ toml: str,
3045
+ ptr: ptr + dot + newLine
3046
+ });
3047
+ }
3048
+ if (strEnd.trimStart()) {
3049
+ throw new TomlError("found extra tokens after the string part", {
3050
+ toml: str,
3051
+ ptr: eos
3052
+ });
3053
+ }
3054
+ if (endPtr < eos) {
3055
+ endPtr = str.indexOf(end, eos);
3056
+ if (endPtr < 0) {
3057
+ throw new TomlError("incomplete key-value: cannot find end of key", {
3058
+ toml: str,
3059
+ ptr
3060
+ });
3061
+ }
3062
+ }
3063
+ parsed.push(part);
3064
+ } else {
3065
+ dot = str.indexOf(".", ptr);
3066
+ let part = str.slice(ptr, dot < 0 || dot > endPtr ? endPtr : dot);
3067
+ if (!KEY_PART_RE.test(part)) {
3068
+ throw new TomlError("only letter, numbers, dashes and underscores are allowed in keys", {
3069
+ toml: str,
3070
+ ptr
3071
+ });
3072
+ }
3073
+ parsed.push(part.trimEnd());
3074
+ }
3075
+ }
3076
+ } while (dot + 1 && dot < endPtr);
3077
+ return [parsed, skipVoid(str, endPtr + 1, true, true)];
3078
+ }
3079
+ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
3080
+ let res = {};
3081
+ let seen = new Set;
3082
+ let c;
3083
+ ptr++;
3084
+ while ((c = str[ptr++]) !== "}" && c) {
3085
+ if (c === ",") {
3086
+ throw new TomlError("expected value, found comma", {
3087
+ toml: str,
3088
+ ptr: ptr - 1
3089
+ });
3090
+ } else if (c === "#")
3091
+ ptr = skipComment(str, ptr);
3092
+ else if (c !== " " && c !== "\t" && c !== `
3093
+ ` && c !== "\r") {
3094
+ let k;
3095
+ let t = res;
3096
+ let hasOwn = false;
3097
+ let [key, keyEndPtr] = parseKey(str, ptr - 1);
3098
+ for (let i = 0;i < key.length; i++) {
3099
+ if (i)
3100
+ t = hasOwn ? t[k] : t[k] = {};
3101
+ k = key[i];
3102
+ if ((hasOwn = Object.hasOwn(t, k)) && (typeof t[k] !== "object" || seen.has(t[k]))) {
3103
+ throw new TomlError("trying to redefine an already defined value", {
3104
+ toml: str,
3105
+ ptr
3106
+ });
3107
+ }
3108
+ if (!hasOwn && k === "__proto__") {
3109
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
3110
+ }
3111
+ }
3112
+ if (hasOwn) {
3113
+ throw new TomlError("trying to redefine an already defined value", {
3114
+ toml: str,
3115
+ ptr
3116
+ });
3117
+ }
3118
+ let [value, valueEndPtr] = extractValue(str, keyEndPtr, "}", depth - 1, integersAsBigInt);
3119
+ seen.add(value);
3120
+ t[k] = value;
3121
+ ptr = valueEndPtr;
3122
+ }
3123
+ }
3124
+ if (!c) {
3125
+ throw new TomlError("unfinished table encountered", {
3126
+ toml: str,
3127
+ ptr
3128
+ });
3129
+ }
3130
+ return [res, ptr];
3131
+ }
3132
+ function parseArray(str, ptr, depth, integersAsBigInt) {
3133
+ let res = [];
3134
+ let c;
3135
+ ptr++;
3136
+ while ((c = str[ptr++]) !== "]" && c) {
3137
+ if (c === ",") {
3138
+ throw new TomlError("expected value, found comma", {
3139
+ toml: str,
3140
+ ptr: ptr - 1
3141
+ });
3142
+ } else if (c === "#")
3143
+ ptr = skipComment(str, ptr);
3144
+ else if (c !== " " && c !== "\t" && c !== `
3145
+ ` && c !== "\r") {
3146
+ let e = extractValue(str, ptr - 1, "]", depth - 1, integersAsBigInt);
3147
+ res.push(e[0]);
3148
+ ptr = e[1];
3149
+ }
3150
+ }
3151
+ if (!c) {
3152
+ throw new TomlError("unfinished array encountered", {
3153
+ toml: str,
3154
+ ptr
3155
+ });
3156
+ }
3157
+ return [res, ptr];
3158
+ }
3159
+ var KEY_PART_RE;
3160
+ var init_struct = __esm(() => {
3161
+ init_primitive();
3162
+ init_extract();
3163
+ init_util();
3164
+ init_error();
3165
+ /*!
3166
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
3167
+ * SPDX-License-Identifier: BSD-3-Clause
3168
+ *
3169
+ * Redistribution and use in source and binary forms, with or without
3170
+ * modification, are permitted provided that the following conditions are met:
3171
+ *
3172
+ * 1. Redistributions of source code must retain the above copyright notice, this
3173
+ * list of conditions and the following disclaimer.
3174
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
3175
+ * this list of conditions and the following disclaimer in the
3176
+ * documentation and/or other materials provided with the distribution.
3177
+ * 3. Neither the name of the copyright holder nor the names of its contributors
3178
+ * may be used to endorse or promote products derived from this software without
3179
+ * specific prior written permission.
3180
+ *
3181
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3182
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3183
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3184
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
3185
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3186
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3187
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3188
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3189
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3190
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3191
+ */
3192
+ KEY_PART_RE = /^[a-zA-Z0-9-_]+[ \t]*$/;
3193
+ });
3194
+
3195
+ // node_modules/smol-toml/dist/parse.js
3196
+ function peekTable(key, table, meta, type) {
3197
+ let t = table;
3198
+ let m = meta;
3199
+ let k;
3200
+ let hasOwn = false;
3201
+ let state;
3202
+ for (let i = 0;i < key.length; i++) {
3203
+ if (i) {
3204
+ t = hasOwn ? t[k] : t[k] = {};
3205
+ m = (state = m[k]).c;
3206
+ if (type === 0 && (state.t === 1 || state.t === 2)) {
3207
+ return null;
3208
+ }
3209
+ if (state.t === 2) {
3210
+ let l = t.length - 1;
3211
+ t = t[l];
3212
+ m = m[l].c;
3213
+ }
3214
+ }
3215
+ k = key[i];
3216
+ if ((hasOwn = Object.hasOwn(t, k)) && m[k]?.t === 0 && m[k]?.d) {
3217
+ return null;
3218
+ }
3219
+ if (!hasOwn) {
3220
+ if (k === "__proto__") {
3221
+ Object.defineProperty(t, k, { enumerable: true, configurable: true, writable: true });
3222
+ Object.defineProperty(m, k, { enumerable: true, configurable: true, writable: true });
3223
+ }
3224
+ m[k] = {
3225
+ t: i < key.length - 1 && type === 2 ? 3 : type,
3226
+ d: false,
3227
+ i: 0,
3228
+ c: {}
3229
+ };
3230
+ }
3231
+ }
3232
+ state = m[k];
3233
+ if (state.t !== type && !(type === 1 && state.t === 3)) {
3234
+ return null;
3235
+ }
3236
+ if (type === 2) {
3237
+ if (!state.d) {
3238
+ state.d = true;
3239
+ t[k] = [];
3240
+ }
3241
+ t[k].push(t = {});
3242
+ state.c[state.i++] = state = { t: 1, d: false, i: 0, c: {} };
3243
+ }
3244
+ if (state.d) {
3245
+ return null;
3246
+ }
3247
+ state.d = true;
3248
+ if (type === 1) {
3249
+ t = hasOwn ? t[k] : t[k] = {};
3250
+ } else if (type === 0 && hasOwn) {
3251
+ return null;
3252
+ }
3253
+ return [k, t, state.c];
3254
+ }
3255
+ function parse(toml, { maxDepth = 1000, integersAsBigInt } = {}) {
3256
+ let res = {};
3257
+ let meta = {};
3258
+ let tbl = res;
3259
+ let m = meta;
3260
+ for (let ptr = skipVoid(toml, 0);ptr < toml.length; ) {
3261
+ if (toml[ptr] === "[") {
3262
+ let isTableArray = toml[++ptr] === "[";
3263
+ let k = parseKey(toml, ptr += +isTableArray, "]");
3264
+ if (isTableArray) {
3265
+ if (toml[k[1] - 1] !== "]") {
3266
+ throw new TomlError("expected end of table declaration", {
3267
+ toml,
3268
+ ptr: k[1] - 1
3269
+ });
3270
+ }
3271
+ k[1]++;
3272
+ }
3273
+ let p = peekTable(k[0], res, meta, isTableArray ? 2 : 1);
3274
+ if (!p) {
3275
+ throw new TomlError("trying to redefine an already defined table or value", {
3276
+ toml,
3277
+ ptr
3278
+ });
3279
+ }
3280
+ m = p[2];
3281
+ tbl = p[1];
3282
+ ptr = k[1];
3283
+ } else {
3284
+ let k = parseKey(toml, ptr);
3285
+ let p = peekTable(k[0], tbl, m, 0);
3286
+ if (!p) {
3287
+ throw new TomlError("trying to redefine an already defined table or value", {
3288
+ toml,
3289
+ ptr
3290
+ });
3291
+ }
3292
+ let v = extractValue(toml, k[1], undefined, maxDepth, integersAsBigInt);
3293
+ p[1][p[0]] = v[0];
3294
+ ptr = v[1];
3295
+ }
3296
+ ptr = skipVoid(toml, ptr, true);
3297
+ if (toml[ptr] && toml[ptr] !== `
3298
+ ` && toml[ptr] !== "\r") {
3299
+ throw new TomlError("each key-value declaration must be followed by an end-of-line", {
3300
+ toml,
3301
+ ptr
3302
+ });
3303
+ }
3304
+ ptr = skipVoid(toml, ptr);
3305
+ }
3306
+ return res;
3307
+ }
3308
+ var init_parse = __esm(() => {
3309
+ init_struct();
3310
+ init_extract();
3311
+ init_util();
3312
+ init_error();
3313
+ /*!
3314
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
3315
+ * SPDX-License-Identifier: BSD-3-Clause
3316
+ *
3317
+ * Redistribution and use in source and binary forms, with or without
3318
+ * modification, are permitted provided that the following conditions are met:
3319
+ *
3320
+ * 1. Redistributions of source code must retain the above copyright notice, this
3321
+ * list of conditions and the following disclaimer.
3322
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
3323
+ * this list of conditions and the following disclaimer in the
3324
+ * documentation and/or other materials provided with the distribution.
3325
+ * 3. Neither the name of the copyright holder nor the names of its contributors
3326
+ * may be used to endorse or promote products derived from this software without
3327
+ * specific prior written permission.
3328
+ *
3329
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3330
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3331
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3332
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
3333
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3334
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3335
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3336
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3337
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3338
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3339
+ */
3340
+ });
3341
+
3342
+ // node_modules/smol-toml/dist/stringify.js
3343
+ var init_stringify = __esm(() => {
3344
+ /*!
3345
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
3346
+ * SPDX-License-Identifier: BSD-3-Clause
3347
+ *
3348
+ * Redistribution and use in source and binary forms, with or without
3349
+ * modification, are permitted provided that the following conditions are met:
3350
+ *
3351
+ * 1. Redistributions of source code must retain the above copyright notice, this
3352
+ * list of conditions and the following disclaimer.
3353
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
3354
+ * this list of conditions and the following disclaimer in the
3355
+ * documentation and/or other materials provided with the distribution.
3356
+ * 3. Neither the name of the copyright holder nor the names of its contributors
3357
+ * may be used to endorse or promote products derived from this software without
3358
+ * specific prior written permission.
3359
+ *
3360
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3361
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3362
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3363
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
3364
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3365
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3366
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3367
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3368
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3369
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3370
+ */
3371
+ });
3372
+
3373
+ // node_modules/smol-toml/dist/index.js
3374
+ var init_dist = __esm(() => {
3375
+ init_parse();
3376
+ init_stringify();
3377
+ init_date();
3378
+ init_error();
3379
+ /*!
3380
+ * Copyright (c) Squirrel Chat et al., All rights reserved.
3381
+ * SPDX-License-Identifier: BSD-3-Clause
3382
+ *
3383
+ * Redistribution and use in source and binary forms, with or without
3384
+ * modification, are permitted provided that the following conditions are met:
3385
+ *
3386
+ * 1. Redistributions of source code must retain the above copyright notice, this
3387
+ * list of conditions and the following disclaimer.
3388
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
3389
+ * this list of conditions and the following disclaimer in the
3390
+ * documentation and/or other materials provided with the distribution.
3391
+ * 3. Neither the name of the copyright holder nor the names of its contributors
3392
+ * may be used to endorse or promote products derived from this software without
3393
+ * specific prior written permission.
3394
+ *
3395
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
3396
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
3397
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
3398
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
3399
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3400
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
3401
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
3402
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3403
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3404
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3405
+ */
3406
+ });
3407
+
3408
+ // src/hooks/fp-config.ts
3409
+ import { chmodSync, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, statSync as statSync4, writeFileSync as writeFileSync2 } from "node:fs";
3410
+ function detectLayout() {
3411
+ const raw = readVersionFile();
3412
+ if (raw) {
3413
+ if (raw.layout === LAYOUT_VERSION)
3414
+ return { kind: "current", version: raw };
3415
+ return raw.layout > LAYOUT_VERSION ? { kind: "future", found: raw.layout } : { kind: "stale", found: raw.layout };
3416
+ }
3417
+ const layoutOneMarkers = [
3418
+ legacy.policyConfig(),
3419
+ legacy.cacheDir(),
3420
+ legacy.launcherMarker(),
3421
+ legacy.lastVersion(),
3422
+ legacy.cloudCredentials(),
3423
+ legacy.ingestCredentials(),
3424
+ legacy.auditDashboard()
3425
+ ];
3426
+ return layoutOneMarkers.some((p) => existsSync3(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
3427
+ }
3428
+ function readVersionFile() {
3429
+ try {
3430
+ const parsed = parse(readFileSync2(versionFile(), "utf8"));
3431
+ const layout = Number(parsed.layout);
3432
+ if (!Number.isFinite(layout))
3433
+ return null;
3434
+ return {
3435
+ layout,
3436
+ cli: typeof parsed.cli === "string" ? parsed.cli : "",
3437
+ daemon: typeof parsed.daemon === "string" ? parsed.daemon : undefined
3438
+ };
3439
+ } catch {
3440
+ return null;
3441
+ }
3442
+ }
3443
+ function readIntervalDays(raw) {
3444
+ if (typeof raw !== "number" || !Number.isFinite(raw))
3445
+ return DEFAULT_AUDIT_INTERVAL_DAYS;
3446
+ const days = Math.floor(raw);
3447
+ if (days < MIN_AUDIT_INTERVAL_DAYS)
3448
+ return DEFAULT_AUDIT_INTERVAL_DAYS;
3449
+ return Math.min(days, MAX_AUDIT_INTERVAL_DAYS);
3450
+ }
3451
+ function readConfig() {
3452
+ try {
3453
+ const parsed = parse(readFileSync2(configFile(), "utf8"));
3454
+ const mode = parsed.mode?.kind;
3455
+ const daemon = parsed.daemon ?? {};
3456
+ const collector = parsed.collector ?? {};
3457
+ const telemetry = parsed.telemetry ?? {};
3458
+ const audit = parsed.audit ?? {};
3459
+ return {
3460
+ mode: mode === "cloud" ? "cloud" : "oss",
3461
+ daemon: { configured: daemon.configured === true },
3462
+ collector: {
3463
+ sessions: collector.sessions === true,
3464
+ hooks: collector.hooks !== false,
3465
+ hooksVerbosity: collector.hooks_verbosity === "all" || collector.hooks_verbosity === "off" ? collector.hooks_verbosity : "decisions",
3466
+ redact: collector.redact === "off" ? "off" : "minimal",
3467
+ environment: typeof collector.environment === "string" ? collector.environment : "local",
3468
+ machineId: typeof collector.machine_id === "string" ? collector.machine_id : undefined
3469
+ },
3470
+ telemetry: { enabled: telemetry.enabled !== false },
3471
+ audit: { auto: audit.auto === true, intervalDays: readIntervalDays(audit.interval_days) }
3472
+ };
3473
+ } catch {
3474
+ return structuredClone(DEFAULT_CONFIG);
3475
+ }
3476
+ }
3477
+ var DEFAULT_AUDIT_INTERVAL_DAYS = 7, MIN_AUDIT_INTERVAL_DAYS = 1, MAX_AUDIT_INTERVAL_DAYS = 90, DEFAULT_CONFIG;
3478
+ var init_fp_config = __esm(() => {
3479
+ init_dist();
3480
+ init_package();
3481
+ init_fp_home();
3482
+ DEFAULT_CONFIG = {
3483
+ mode: "oss",
3484
+ daemon: { configured: false },
3485
+ collector: {
3486
+ sessions: false,
3487
+ hooks: true,
3488
+ hooksVerbosity: "decisions",
3489
+ redact: "minimal",
3490
+ environment: "local"
3491
+ },
3492
+ telemetry: { enabled: true },
3493
+ audit: { auto: false, intervalDays: DEFAULT_AUDIT_INTERVAL_DAYS }
3494
+ };
3495
+ });
3496
+
3497
+ // lib/telemetry-enabled.ts
3498
+ function isTelemetryEnabled() {
3499
+ if (process.env.FAILPROOFAI_TELEMETRY_DISABLED === "1")
3500
+ return false;
3501
+ try {
3502
+ return readConfig().telemetry.enabled;
3503
+ } catch {
3504
+ return true;
3505
+ }
3506
+ }
3507
+ var init_telemetry_enabled = __esm(() => {
3508
+ init_fp_config();
3509
+ });
3510
+
2349
3511
  // src/hooks/hook-telemetry.ts
2350
3512
  async function sendEvent(distinctId, event, properties) {
2351
3513
  const body = JSON.stringify({
@@ -2364,7 +3526,7 @@ async function sendEvent(distinctId, event, properties) {
2364
3526
  } catch {}
2365
3527
  }
2366
3528
  async function trackHookEvent(distinctId, event, properties) {
2367
- if (process.env.FAILPROOFAI_TELEMETRY_DISABLED === "1")
3529
+ if (!isTelemetryEnabled())
2368
3530
  return;
2369
3531
  const p = sendEvent(distinctId, event, properties);
2370
3532
  pending.add(p);
@@ -2379,6 +3541,7 @@ async function flushHookTelemetry() {
2379
3541
  var API_KEY, CAPTURE_URL = "https://us.i.posthog.com/capture/", pending;
2380
3542
  var init_hook_telemetry = __esm(() => {
2381
3543
  init_package();
3544
+ init_telemetry_enabled();
2382
3545
  API_KEY = POSTHOG_API_KEY;
2383
3546
  pending = new Set;
2384
3547
  });
@@ -2442,24 +3605,48 @@ function getFileBasedId() {
2442
3605
  } catch {}
2443
3606
  return id;
2444
3607
  }
3608
+ function publishInstanceId(id) {
3609
+ let target;
3610
+ try {
3611
+ target = telemetryIdFile();
3612
+ if (fs.readFileSync(target, "utf-8").trim() === id)
3613
+ return;
3614
+ } catch {
3615
+ try {
3616
+ target = telemetryIdFile();
3617
+ } catch {
3618
+ return;
3619
+ }
3620
+ }
3621
+ try {
3622
+ fs.mkdirSync(path.dirname(target), { recursive: true });
3623
+ const tmp = `${target}.${process.pid}.tmp`;
3624
+ fs.writeFileSync(tmp, id, { encoding: "utf-8", mode: 384 });
3625
+ fs.renameSync(tmp, target);
3626
+ } catch {}
3627
+ }
2445
3628
  function getInstanceId() {
2446
3629
  if (cachedId)
2447
3630
  return cachedId;
2448
3631
  const machineId = getPlatformMachineId();
2449
3632
  if (machineId) {
2450
3633
  cachedId = hashToId(machineId);
3634
+ publishInstanceId(cachedId);
2451
3635
  return cachedId;
2452
3636
  }
2453
3637
  const sysProps = getSystemPropertiesId();
2454
3638
  if (sysProps) {
2455
3639
  cachedId = hashToId(sysProps);
3640
+ publishInstanceId(cachedId);
2456
3641
  return cachedId;
2457
3642
  }
2458
3643
  cachedId = getFileBasedId();
3644
+ publishInstanceId(cachedId);
2459
3645
  return cachedId;
2460
3646
  }
2461
3647
  var NAMESPACE = "failproofai-telemetry-v1", ID_DIR, ID_FILE, cachedId;
2462
3648
  var init_telemetry_id = __esm(() => {
3649
+ init_fp_home();
2463
3650
  ID_DIR = path.join(os.homedir(), ".failproofai");
2464
3651
  ID_FILE = path.join(ID_DIR, "instance-id");
2465
3652
  });
@@ -3223,9 +4410,33 @@ var init_custom_hooks_registry = __esm(() => {
3223
4410
  });
3224
4411
 
3225
4412
  // src/hooks/loader-utils.ts
3226
- import { readFile as readFile2, writeFile as writeFile2, unlink, access } from "fs/promises";
3227
- import { resolve as resolve3, dirname as dirname2, relative } from "path";
4413
+ import { readFile as readFile2, writeFile as writeFile2, unlink, access, mkdir, lstat } from "fs/promises";
4414
+ import { tmpdir } from "os";
4415
+ import { resolve as resolve4, dirname as dirname2, relative, join as join3 } from "path";
3228
4416
  import { pathToFileURL } from "url";
4417
+ import { createHash } from "crypto";
4418
+ function isTmpArtifact(name) {
4419
+ return TMP_ARTIFACT_RE.test(name);
4420
+ }
4421
+ async function sweepStaleTmpArtifacts(dir, now = Date.now()) {
4422
+ let removed = 0;
4423
+ try {
4424
+ const { readdir, stat: stat2 } = await import("fs/promises");
4425
+ for (const name of await readdir(dir)) {
4426
+ if (!isTmpArtifact(name))
4427
+ continue;
4428
+ const path2 = resolve4(dir, name);
4429
+ try {
4430
+ const info = await stat2(path2);
4431
+ if (now - info.mtimeMs < TMP_SWEEP_MIN_AGE_MS)
4432
+ continue;
4433
+ await unlink(path2);
4434
+ removed++;
4435
+ } catch {}
4436
+ }
4437
+ } catch {}
4438
+ return removed;
4439
+ }
3229
4440
  async function fileExists(path2) {
3230
4441
  try {
3231
4442
  await access(path2);
@@ -3237,14 +4448,14 @@ async function fileExists(path2) {
3237
4448
  async function findDistIndex() {
3238
4449
  const distPath = process.env.FAILPROOFAI_DIST_PATH;
3239
4450
  if (distPath) {
3240
- const candidate = resolve3(distPath, "index.js");
4451
+ const candidate = resolve4(distPath, "index.js");
3241
4452
  if (await fileExists(candidate))
3242
4453
  return candidate;
3243
4454
  }
3244
4455
  const candidates = [
3245
- resolve3(dirname2(process.execPath), "..", "assets", "dist", "index.js"),
3246
- resolve3(process.cwd(), "dist", "index.js"),
3247
- resolve3(process.cwd(), "node_modules", "failproofai", "dist", "index.js")
4456
+ resolve4(dirname2(process.execPath), "..", "assets", "dist", "index.js"),
4457
+ resolve4(process.cwd(), "dist", "index.js"),
4458
+ resolve4(process.cwd(), "node_modules", "failproofai", "dist", "index.js")
3248
4459
  ];
3249
4460
  for (const c of candidates) {
3250
4461
  if (await fileExists(c))
@@ -3253,16 +4464,24 @@ async function findDistIndex() {
3253
4464
  return null;
3254
4465
  }
3255
4466
  async function resolveLocalImport(fromDir, specifier) {
3256
- const base = resolve3(fromDir, specifier);
3257
- const candidates = [base, `${base}.js`, `${base}.mjs`, `${base}.ts`, resolve3(base, "index.js")];
4467
+ const base = resolve4(fromDir, specifier);
4468
+ const candidates = [base, `${base}.js`, `${base}.mjs`, `${base}.ts`, resolve4(base, "index.js")];
3258
4469
  for (const c of candidates) {
3259
4470
  if (await fileExists(c))
3260
4471
  return c;
3261
4472
  }
3262
4473
  return null;
3263
4474
  }
4475
+ async function writeShim(dir, name, code, exclusive) {
4476
+ const shimPath = join3(dir, name);
4477
+ await writeFile2(shimPath, code, {
4478
+ encoding: "utf-8",
4479
+ mode: 384,
4480
+ ...exclusive ? { flag: "wx" } : {}
4481
+ });
4482
+ return shimPath;
4483
+ }
3264
4484
  async function createEsmShim(distIndex, distUrl, tmpSuffix = TMP_SUFFIX) {
3265
- const shimPath = `${distIndex}${tmpSuffix}.shim.mjs`;
3266
4485
  const shimCode = [
3267
4486
  `import _cjs from '${distUrl}';`,
3268
4487
  `export const customPolicies = _cjs.customPolicies;`,
@@ -3274,10 +4493,24 @@ async function createEsmShim(distIndex, distUrl, tmpSuffix = TMP_SUFFIX) {
3274
4493
  `export default _cjs;`
3275
4494
  ].join(`
3276
4495
  `);
3277
- await writeFile2(shimPath, shimCode, "utf-8");
4496
+ const name = `failproofai-dist${tmpSuffix}.shim.mjs`;
4497
+ try {
4498
+ const dir = shimsDir();
4499
+ await mkdir(dir, { recursive: true, mode: 448 });
4500
+ const st = await lstat(dir);
4501
+ const uid = typeof process.getuid === "function" ? process.getuid() : null;
4502
+ if (!st.isDirectory() || st.isSymbolicLink() || uid !== null && st.uid !== uid || st.mode & 63) {
4503
+ throw new Error(`${dir} is not a private directory owned by this user`);
4504
+ }
4505
+ const shimPath2 = await writeShim(dir, name, shimCode, false);
4506
+ return { shimPath: shimPath2, shimUrl: pathToFileURL(shimPath2).href };
4507
+ } catch (err) {
4508
+ hookLogWarn(`policy shim directory unusable (${err instanceof Error ? err.message : String(err)}); falling back to ${tmpdir()}`);
4509
+ }
4510
+ const shimPath = await writeShim(tmpdir(), name, shimCode, true);
3278
4511
  return { shimPath, shimUrl: pathToFileURL(shimPath).href };
3279
4512
  }
3280
- async function rewriteFileTree(entryPath, distUrl, distIndex, tmpSuffix = TMP_SUFFIX) {
4513
+ async function rewriteFileTree(entryPath, distUrl, distIndex, tmpSuffix = TMP_SUFFIX, entrySha256) {
3281
4514
  const queue = [entryPath];
3282
4515
  const visited = new Set;
3283
4516
  const tmpFiles = [];
@@ -3292,7 +4525,17 @@ async function rewriteFileTree(entryPath, distUrl, distIndex, tmpSuffix = TMP_SU
3292
4525
  if (visited.has(filePath))
3293
4526
  continue;
3294
4527
  visited.add(filePath);
3295
- let code = await readFile2(filePath, "utf-8");
4528
+ let code;
4529
+ if (entrySha256 && filePath === entryPath) {
4530
+ const buf = await readFile2(filePath);
4531
+ const actual = createHash("sha256").update(buf).digest("hex");
4532
+ if (actual !== entrySha256) {
4533
+ throw new Error(`cloud-managed policy failed integrity re-verification at load: expected ${entrySha256}, got ${actual}`);
4534
+ }
4535
+ code = buf.toString("utf-8");
4536
+ } else {
4537
+ code = await readFile2(filePath, "utf-8");
4538
+ }
3296
4539
  if (esmShimUrl) {
3297
4540
  code = code.replace(/from\s+(['"])(?:claudeye|failproofai)\1/g, `from '${esmShimUrl}'`);
3298
4541
  }
@@ -3340,38 +4583,61 @@ async function cleanupTmpFiles(tmpFiles) {
3340
4583
  } catch {}
3341
4584
  }
3342
4585
  }
3343
- var TMP_SUFFIX = ".__failproofai_tmp__.mjs", LOCAL_IMPORT_RE, LOCAL_REQUIRE_RE;
4586
+ var TMP_SUFFIX = ".__failproofai_tmp__.mjs", TMP_ARTIFACT_RE, TMP_SWEEP_MIN_AGE_MS = 60000, LOCAL_IMPORT_RE, LOCAL_REQUIRE_RE;
3344
4587
  var init_loader_utils = __esm(() => {
4588
+ init_fp_home();
4589
+ init_hook_logger();
4590
+ TMP_ARTIFACT_RE = /\.__failproofai_tmp__\./;
3345
4591
  LOCAL_IMPORT_RE = /(?:import\s+(?:[\s\S]*?\s+from\s+)?|export\s+(?:[\s\S]*?\s+from\s+))(['"])(\.\.?\/[^'"]+)\1/g;
3346
4592
  LOCAL_REQUIRE_RE = /require\s*\(\s*(['"])(\.\.?\/[^'"]+)\1\s*\)/g;
3347
4593
  });
3348
4594
 
3349
4595
  // src/hooks/custom-hooks-loader.ts
3350
- import { resolve as resolve4, isAbsolute, basename } from "node:path";
3351
- import { existsSync as existsSync3, readdirSync } from "node:fs";
4596
+ import { resolve as resolve5, isAbsolute, basename } from "node:path";
4597
+ import { randomUUID } from "crypto";
4598
+ import { existsSync as existsSync4, readdirSync } from "node:fs";
3352
4599
  import { readFile as readFile3 } from "node:fs/promises";
3353
4600
  import { pathToFileURL as pathToFileURL2 } from "node:url";
3354
- import { homedir as homedir4 } from "node:os";
3355
- import { createHash } from "node:crypto";
4601
+ import { createHash as createHash2 } from "node:crypto";
3356
4602
  function discoverPolicyFiles(dir) {
3357
- if (!existsSync3(dir))
4603
+ if (!existsSync4(dir))
3358
4604
  return [];
3359
4605
  try {
3360
4606
  const entries = readdirSync(dir, { withFileTypes: true });
3361
- return entries.filter((e) => e.isFile() && CONVENTION_FILE_RE.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) => resolve4(dir, e.name));
4607
+ return entries.filter((e) => e.isFile() && CONVENTION_FILE_RE.test(e.name)).sort((a, b) => a.name.localeCompare(b.name)).map((e) => resolve5(dir, e.name));
3362
4608
  } catch {
3363
4609
  return [];
3364
4610
  }
3365
4611
  }
3366
4612
  function findSkippedPolicyFiles(dir) {
3367
- if (!existsSync3(dir))
4613
+ if (!existsSync4(dir))
3368
4614
  return [];
3369
4615
  try {
3370
- return readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && LOADABLE_EXT_RE.test(e.name) && !CONVENTION_FILE_RE.test(e.name) && !e.name.endsWith(".d.ts")).map((e) => e.name).sort((a, b) => a.localeCompare(b));
4616
+ return readdirSync(dir, { withFileTypes: true }).filter((e) => e.isFile() && LOADABLE_EXT_RE.test(e.name) && !CONVENTION_FILE_RE.test(e.name) && !e.name.endsWith(".d.ts") && !isTmpArtifact(e.name)).map((e) => e.name).sort((a, b) => a.localeCompare(b));
3371
4617
  } catch {
3372
4618
  return [];
3373
4619
  }
3374
4620
  }
4621
+ function moduleLoadTimeoutMs() {
4622
+ const override = Number(process.env.FAILPROOFAI_POLICY_LOAD_TIMEOUT_MS);
4623
+ return Number.isFinite(override) && override > 0 ? override : 1e4;
4624
+ }
4625
+ async function importWithDeadline(fileUrl) {
4626
+ const budget = moduleLoadTimeoutMs();
4627
+ let timer;
4628
+ try {
4629
+ await Promise.race([
4630
+ import(fileUrl),
4631
+ new Promise((_, reject) => {
4632
+ timer = setTimeout(() => reject(new Error(`timed out loading module after ${budget}ms`)), budget);
4633
+ timer.unref?.();
4634
+ })
4635
+ ]);
4636
+ } finally {
4637
+ if (timer)
4638
+ clearTimeout(timer);
4639
+ }
4640
+ }
3375
4641
  async function loadSingleFile(absPath, opts) {
3376
4642
  const g = globalThis;
3377
4643
  g[LOADING_KEY] = true;
@@ -3380,8 +4646,8 @@ async function loadSingleFile(absPath, opts) {
3380
4646
  const distIndex = await findDistIndex();
3381
4647
  const distUrl = distIndex ? pathToFileURL2(distIndex).href : null;
3382
4648
  const sequence = ++loadSequence;
3383
- const tmpSuffix = `${TMP_SUFFIX}.${process.pid}.${sequence}.mjs`;
3384
- tmpFiles = await rewriteFileTree(absPath, distUrl, distIndex, tmpSuffix);
4649
+ const tmpSuffix = `${TMP_SUFFIX}.${process.pid}.${sequence}.${randomUUID()}.mjs`;
4650
+ tmpFiles = await rewriteFileTree(absPath, distUrl, distIndex, tmpSuffix, opts?.verifyEntrySha);
3385
4651
  const fingerprint = await fingerprintTemporaryTree(tmpFiles, tmpSuffix);
3386
4652
  const cached = policyModuleCache.get(absPath);
3387
4653
  if (cached?.fingerprint === fingerprint) {
@@ -3392,14 +4658,16 @@ async function loadSingleFile(absPath, opts) {
3392
4658
  const entryTmp = absPath + tmpSuffix;
3393
4659
  const fileUrl = pathToFileURL2(entryTmp).href;
3394
4660
  const hooksBefore = getCustomHooks().length;
3395
- await import(fileUrl);
4661
+ await importWithDeadline(fileUrl);
4662
+ if (policyModuleCache.size >= POLICY_MODULE_CACHE_MAX_ENTRIES)
4663
+ policyModuleCache.clear();
3396
4664
  policyModuleCache.set(absPath, {
3397
4665
  fingerprint,
3398
4666
  hooks: getCustomHooks().slice(hooksBefore).map((hook) => ({ ...hook }))
3399
4667
  });
3400
4668
  } catch (err) {
3401
4669
  const msg = err instanceof Error ? err.message : String(err);
3402
- const errorType = /Cannot find module|MODULE_NOT_FOUND|ENOENT/i.test(msg) ? "module_not_found" : /SyntaxError|Unexpected token/i.test(msg) ? "syntax_error" : "runtime_error";
4670
+ const errorType = /Cannot find module|MODULE_NOT_FOUND|ENOENT/i.test(msg) ? "module_not_found" : /SyntaxError|Unexpected token/i.test(msg) ? "syntax_error" : /timed out loading module/i.test(msg) ? "load_timeout" : "runtime_error";
3403
4671
  trackHookEvent(getInstanceId(), "custom_hooks_load_error", {
3404
4672
  error_type: errorType,
3405
4673
  is_convention: !!opts?.conventionScope,
@@ -3415,7 +4683,7 @@ async function loadSingleFile(absPath, opts) {
3415
4683
  }
3416
4684
  }
3417
4685
  async function fingerprintTemporaryTree(tmpFiles, tmpSuffix) {
3418
- const hash = createHash("sha256");
4686
+ const hash = createHash2("sha256");
3419
4687
  for (const tmpFile of [...tmpFiles].sort()) {
3420
4688
  hash.update(tmpFile.replaceAll(tmpSuffix, TMP_SUFFIX));
3421
4689
  const contents = await readFile3(tmpFile, "utf8");
@@ -3442,14 +4710,16 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
3442
4710
  const projectRoot = findProjectConfigDir(opts?.sessionCwd ?? process.cwd());
3443
4711
  const conventionEnabled = opts?.customPoliciesEnabled !== false;
3444
4712
  const loadedPaths = new Set;
3445
- const cloudManagedByPath = new Map((opts?.cloudManagedPolicies ?? []).map((policy) => [resolve4(policy.path), policy]));
4713
+ const cloudManagedByPath = new Map((opts?.cloudManagedPolicies ?? []).map((policy) => [resolve5(policy.path), policy]));
3446
4714
  for (const customPoliciesPath of typeof customPoliciesPaths === "string" ? [customPoliciesPaths] : customPoliciesPaths ?? []) {
3447
- const absPath = resolve4(projectRoot, customPoliciesPath);
3448
- if (existsSync3(absPath)) {
4715
+ const absPath = resolve5(projectRoot, customPoliciesPath);
4716
+ if (existsSync4(absPath)) {
3449
4717
  if (!loadedPaths.has(absPath)) {
3450
4718
  loadedPaths.add(absPath);
3451
4719
  const hooksBefore = getCustomHooks().length;
3452
- await loadSingleFile(absPath);
4720
+ await loadSingleFile(absPath, {
4721
+ verifyEntrySha: cloudManagedByPath.get(absPath)?.sha256
4722
+ });
3453
4723
  for (const hook of getCustomHooks().slice(hooksBefore)) {
3454
4724
  const cloudManaged = cloudManagedByPath.get(absPath);
3455
4725
  const tagged = hook;
@@ -3466,9 +4736,12 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
3466
4736
  }
3467
4737
  }
3468
4738
  const hooksBeforeConvention = getCustomHooks().length;
3469
- const projectDir = resolve4(projectRoot, ".failproofai", "policies");
3470
- if (conventionEnabled)
4739
+ const projectDir = resolve5(projectRoot, ".failproofai", "policies");
4740
+ if (conventionEnabled) {
4741
+ sweepStaleTmpArtifacts(projectDir);
3471
4742
  warnSkippedPolicyFiles(projectDir, "project");
4743
+ }
4744
+ sweepStaleTmpArtifacts(shimsDir());
3472
4745
  const projectFiles = conventionEnabled ? discoverPolicyFiles(projectDir).filter((f) => !loadedPaths.has(f)) : [];
3473
4746
  for (const file of projectFiles) {
3474
4747
  loadedPaths.add(file);
@@ -3486,9 +4759,11 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
3486
4759
  });
3487
4760
  }
3488
4761
  }
3489
- const userDir = resolve4(homedir4(), ".failproofai", "policies");
3490
- if (conventionEnabled && userDir !== projectDir)
4762
+ const userDir = customPoliciesDir();
4763
+ if (conventionEnabled && userDir !== projectDir) {
4764
+ sweepStaleTmpArtifacts(userDir);
3491
4765
  warnSkippedPolicyFiles(userDir, "user");
4766
+ }
3492
4767
  const userFiles = conventionEnabled && userDir !== projectDir ? discoverPolicyFiles(userDir).filter((f) => !loadedPaths.has(f)) : [];
3493
4768
  for (const file of userFiles) {
3494
4769
  loadedPaths.add(file);
@@ -3530,7 +4805,7 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
3530
4805
  }
3531
4806
  return { hooks: allHooks, conventionSources };
3532
4807
  }
3533
- var LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__", CONVENTION_FILE_RE, loadSequence = 0, policyModuleCache, LOADABLE_EXT_RE;
4808
+ var LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__", CONVENTION_FILE_RE, loadSequence = 0, policyModuleCache, POLICY_MODULE_CACHE_MAX_ENTRIES = 500, LOADABLE_EXT_RE;
3534
4809
  var init_custom_hooks_loader = __esm(() => {
3535
4810
  init_hook_logger();
3536
4811
  init_custom_hooks_registry();
@@ -3538,6 +4813,7 @@ var init_custom_hooks_loader = __esm(() => {
3538
4813
  init_hooks_config();
3539
4814
  init_hook_telemetry();
3540
4815
  init_telemetry_id();
4816
+ init_fp_home();
3541
4817
  CONVENTION_FILE_RE = /policies\.(js|mjs|ts)$/;
3542
4818
  policyModuleCache = new Map;
3543
4819
  LOADABLE_EXT_RE = /\.(js|mjs|ts)$/;
@@ -3545,38 +4821,37 @@ var init_custom_hooks_loader = __esm(() => {
3545
4821
 
3546
4822
  // src/hooks/hook-activity-store.ts
3547
4823
  import {
3548
- readFileSync as readFileSync2,
3549
- writeFileSync as writeFileSync2,
4824
+ readFileSync as readFileSync3,
4825
+ writeFileSync as writeFileSync3,
3550
4826
  appendFileSync as appendFileSync2,
3551
4827
  renameSync as renameSync2,
3552
4828
  readdirSync as readdirSync2,
3553
- mkdirSync as mkdirSync3,
3554
- existsSync as existsSync4,
3555
- statSync as statSync4,
4829
+ mkdirSync as mkdirSync4,
4830
+ existsSync as existsSync5,
4831
+ statSync as statSync5,
3556
4832
  unlinkSync
3557
4833
  } from "node:fs";
3558
- import { join as join3 } from "node:path";
3559
- import { homedir as homedir5 } from "node:os";
4834
+ import { join as join4 } from "node:path";
3560
4835
  function ensureDir() {
3561
- if (!existsSync4(storeDir)) {
3562
- mkdirSync3(storeDir, { recursive: true });
4836
+ if (!existsSync5(storeDirValue())) {
4837
+ mkdirSync4(storeDirValue(), { recursive: true });
3563
4838
  }
3564
4839
  }
3565
4840
  function acquireLock() {
3566
4841
  ensureDir();
3567
- const lockPath = join3(storeDir, LOCK_FILE);
4842
+ const lockPath = join4(storeDirValue(), LOCK_FILE);
3568
4843
  const deadline = Date.now() + LOCK_STALE_MS;
3569
4844
  while (Date.now() < deadline) {
3570
4845
  try {
3571
- writeFileSync2(lockPath, String(process.pid), { flag: "wx" });
4846
+ writeFileSync3(lockPath, String(process.pid), { flag: "wx" });
3572
4847
  return;
3573
4848
  } catch (e) {
3574
4849
  if (e.code !== "EEXIST")
3575
4850
  return;
3576
4851
  try {
3577
- const s = statSync4(lockPath);
4852
+ const s = statSync5(lockPath);
3578
4853
  if (Date.now() - s.mtimeMs > LOCK_STALE_MS) {
3579
- writeFileSync2(lockPath, String(process.pid), "utf-8");
4854
+ writeFileSync3(lockPath, String(process.pid), "utf-8");
3580
4855
  return;
3581
4856
  }
3582
4857
  } catch {}
@@ -3585,15 +4860,15 @@ function acquireLock() {
3585
4860
  }
3586
4861
  function releaseLock() {
3587
4862
  try {
3588
- unlinkSync(join3(storeDir, LOCK_FILE));
4863
+ unlinkSync(join4(storeDirValue(), LOCK_FILE));
3589
4864
  } catch {}
3590
4865
  }
3591
4866
  function persistHookActivity(entry) {
3592
4867
  ensureDir();
3593
4868
  acquireLock();
3594
4869
  try {
3595
- const currentPath = join3(storeDir, CURRENT_FILE);
3596
- const countPath = join3(storeDir, COUNT_FILE);
4870
+ const currentPath = join4(storeDirValue(), CURRENT_FILE);
4871
+ const countPath = join4(storeDirValue(), COUNT_FILE);
3597
4872
  const lineCount = readCount(countPath);
3598
4873
  if (lineCount >= PAGE_SIZE) {
3599
4874
  try {
@@ -3613,13 +4888,13 @@ function persistHookActivity(entry) {
3613
4888
  }
3614
4889
  function rotate(currentPath, countPath) {
3615
4890
  const archiveName = `page-${Date.now()}-${rotateSeq++}.jsonl`;
3616
- const archivePath = join3(storeDir, archiveName);
4891
+ const archivePath = join4(storeDirValue(), archiveName);
3617
4892
  renameSync2(currentPath, archivePath);
3618
4893
  writeCount(countPath, 0);
3619
4894
  }
3620
4895
  function readCount(countPath) {
3621
4896
  try {
3622
- const n = parseInt(readFileSync2(countPath, "utf-8"), 10);
4897
+ const n = parseInt(readFileSync3(countPath, "utf-8"), 10);
3623
4898
  return isNaN(n) ? 0 : n;
3624
4899
  } catch {
3625
4900
  return 0;
@@ -3627,12 +4902,12 @@ function readCount(countPath) {
3627
4902
  }
3628
4903
  function writeCount(countPath, n) {
3629
4904
  try {
3630
- writeFileSync2(countPath, String(n), "utf-8");
4905
+ writeFileSync3(countPath, String(n), "utf-8");
3631
4906
  } catch {}
3632
4907
  }
3633
4908
  function readStoredStats() {
3634
4909
  try {
3635
- return JSON.parse(readFileSync2(join3(storeDir, STATS_FILE), "utf-8"));
4910
+ return JSON.parse(readFileSync3(join4(storeDirValue(), STATS_FILE), "utf-8"));
3636
4911
  } catch {
3637
4912
  return { totalEvents: 0, denyCount: 0, policyMap: {} };
3638
4913
  }
@@ -3649,20 +4924,19 @@ function updateStats(entry) {
3649
4924
  } else if (entry.policyName) {
3650
4925
  s.policyMap[entry.policyName] = (s.policyMap[entry.policyName] ?? 0) + 1;
3651
4926
  }
3652
- const tmpPath = join3(storeDir, `stats.json.${process.pid}.tmp`);
4927
+ const tmpPath = join4(storeDirValue(), `stats.json.${process.pid}.tmp`);
3653
4928
  try {
3654
- writeFileSync2(tmpPath, JSON.stringify(s), "utf-8");
3655
- renameSync2(tmpPath, join3(storeDir, STATS_FILE));
4929
+ writeFileSync3(tmpPath, JSON.stringify(s), "utf-8");
4930
+ renameSync2(tmpPath, join4(storeDirValue(), STATS_FILE));
3656
4931
  } catch {
3657
4932
  try {
3658
4933
  unlinkSync(tmpPath);
3659
4934
  } catch {}
3660
4935
  }
3661
4936
  }
3662
- var PAGE_SIZE = 25, DEFAULT_STORE_DIR, CURRENT_FILE = "current.jsonl", COUNT_FILE = "current.count", STATS_FILE = "stats.json", LOCK_FILE = "current.lock", LOCK_STALE_MS = 2000, storeDir, rotateSeq = 0;
4937
+ var PAGE_SIZE = 25, defaultStoreDir = () => hookActivityDir(), CURRENT_FILE = "current.jsonl", COUNT_FILE = "current.count", STATS_FILE = "stats.json", LOCK_FILE = "current.lock", LOCK_STALE_MS = 2000, storeDirOverride = null, storeDirValue = () => storeDirOverride ?? defaultStoreDir(), rotateSeq = 0;
3663
4938
  var init_hook_activity_store = __esm(() => {
3664
- DEFAULT_STORE_DIR = join3(homedir5(), ".failproofai", "cache", "hook-activity");
3665
- storeDir = DEFAULT_STORE_DIR;
4939
+ init_fp_home();
3666
4940
  });
3667
4941
 
3668
4942
  // src/hooks/resolve-cwd.ts
@@ -3711,10 +4985,10 @@ function runtimeCache(fn, revalidateSeconds, options) {
3711
4985
  }
3712
4986
 
3713
4987
  // lib/paths.ts
3714
- import { homedir as homedir6 } from "os";
3715
- import { join as join4 } from "path";
4988
+ import { homedir as homedir4 } from "os";
4989
+ import { join as join5 } from "path";
3716
4990
  function getDefaultClaudeProjectsPath() {
3717
- return join4(homedir6(), ".claude", "projects");
4991
+ return join5(homedir4(), ".claude", "projects");
3718
4992
  }
3719
4993
  function decodeFolderName(name) {
3720
4994
  if (/^[A-Za-z]--/.test(name)) {
@@ -3808,8 +5082,8 @@ __export(exports_codex_projects, {
3808
5082
  getCachedCodexProjects: () => getCachedCodexProjects
3809
5083
  });
3810
5084
  import { open as open2, readdir } from "node:fs/promises";
3811
- import { homedir as homedir7 } from "node:os";
3812
- import { join as join5 } from "node:path";
5085
+ import { homedir as homedir5 } from "node:os";
5086
+ import { join as join6 } from "node:path";
3813
5087
  async function safeReaddir(dir) {
3814
5088
  try {
3815
5089
  return await readdir(dir, { withFileTypes: true });
@@ -3857,7 +5131,7 @@ async function listJsonlFiles(dir) {
3857
5131
  const entries = await safeReaddir(dir);
3858
5132
  if (!entries)
3859
5133
  return [];
3860
- return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join5(dir, e.name));
5134
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join6(dir, e.name));
3861
5135
  }
3862
5136
  async function scanCodexSessions() {
3863
5137
  const yearDirs = await safeReaddir(CODEX_SESSIONS_ROOT);
@@ -3867,19 +5141,19 @@ async function scanCodexSessions() {
3867
5141
  for (const y of yearDirs) {
3868
5142
  if (!y.isDirectory())
3869
5143
  continue;
3870
- const monthDirs = await safeReaddir(join5(CODEX_SESSIONS_ROOT, y.name));
5144
+ const monthDirs = await safeReaddir(join6(CODEX_SESSIONS_ROOT, y.name));
3871
5145
  if (!monthDirs)
3872
5146
  continue;
3873
5147
  for (const m of monthDirs) {
3874
5148
  if (!m.isDirectory())
3875
5149
  continue;
3876
- const dayDirs = await safeReaddir(join5(CODEX_SESSIONS_ROOT, y.name, m.name));
5150
+ const dayDirs = await safeReaddir(join6(CODEX_SESSIONS_ROOT, y.name, m.name));
3877
5151
  if (!dayDirs)
3878
5152
  continue;
3879
5153
  for (const d of dayDirs) {
3880
5154
  if (!d.isDirectory())
3881
5155
  continue;
3882
- const dayPath = join5(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
5156
+ const dayPath = join6(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
3883
5157
  filePaths.push(...await listJsonlFiles(dayPath));
3884
5158
  }
3885
5159
  }
@@ -3987,7 +5261,7 @@ var CODEX_SESSIONS_ROOT, SESSION_ID_RE, FIRST_LINE_CHUNK_BYTES, cachedScan, getC
3987
5261
  var init_codex_projects = __esm(() => {
3988
5262
  init_paths();
3989
5263
  init_logger();
3990
- CODEX_SESSIONS_ROOT = join5(homedir7(), ".codex", "sessions");
5264
+ CODEX_SESSIONS_ROOT = join6(homedir5(), ".codex", "sessions");
3991
5265
  SESSION_ID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
3992
5266
  FIRST_LINE_CHUNK_BYTES = 256 * 1024;
3993
5267
  cachedScan = runtimeCache(scanCodexSessions, 30);
@@ -4007,10 +5281,10 @@ __export(exports_copilot_projects, {
4007
5281
  getCachedCopilotProjects: () => getCachedCopilotProjects
4008
5282
  });
4009
5283
  import { readdir as readdir2, readFile as readFile4, stat as stat2 } from "node:fs/promises";
4010
- import { homedir as homedir8 } from "node:os";
4011
- import { join as join6 } from "node:path";
5284
+ import { homedir as homedir6 } from "node:os";
5285
+ import { join as join7 } from "node:path";
4012
5286
  function getCopilotSessionStateRoot() {
4013
- return join6(process.env.COPILOT_HOME || join6(homedir8(), ".copilot"), "session-state");
5287
+ return join7(process.env.COPILOT_HOME || join7(homedir6(), ".copilot"), "session-state");
4014
5288
  }
4015
5289
  async function safeReaddir2(dir) {
4016
5290
  try {
@@ -4039,8 +5313,8 @@ async function scanCopilotSessions() {
4039
5313
  return [];
4040
5314
  const candidates = entries.filter((e) => e.isDirectory()).map((e) => ({
4041
5315
  sessionId: e.name,
4042
- workspacePath: join6(root, e.name, "workspace.yaml"),
4043
- eventsPath: join6(root, e.name, "events.jsonl")
5316
+ workspacePath: join7(root, e.name, "workspace.yaml"),
5317
+ eventsPath: join7(root, e.name, "events.jsonl")
4044
5318
  }));
4045
5319
  const settled = await batchAll(candidates.map((c) => async () => {
4046
5320
  let workspaceText;
@@ -4155,10 +5429,10 @@ __export(exports_cursor_projects, {
4155
5429
  getCachedCursorProjects: () => getCachedCursorProjects
4156
5430
  });
4157
5431
  import { readdir as readdir3, readFile as readFile5, stat as stat3 } from "node:fs/promises";
4158
- import { homedir as homedir9 } from "node:os";
4159
- import { join as join7 } from "node:path";
5432
+ import { homedir as homedir7 } from "node:os";
5433
+ import { join as join8 } from "node:path";
4160
5434
  function getCursorHome() {
4161
- return process.env.CURSOR_HOME || join7(homedir9(), ".cursor");
5435
+ return process.env.CURSOR_HOME || join8(homedir7(), ".cursor");
4162
5436
  }
4163
5437
  async function safeReaddir3(dir) {
4164
5438
  try {
@@ -4190,7 +5464,7 @@ function parseCwdFromMetaText(text) {
4190
5464
  }
4191
5465
  async function findFirstUsableMeta(dir, candidates) {
4192
5466
  for (const name of candidates) {
4193
- const path2 = join7(dir, name);
5467
+ const path2 = join8(dir, name);
4194
5468
  if (await statMtime2(path2) === null)
4195
5469
  continue;
4196
5470
  let text;
@@ -4207,7 +5481,7 @@ async function findFirstUsableMeta(dir, candidates) {
4207
5481
  }
4208
5482
  async function findFirstExistingPath(dir, candidates) {
4209
5483
  for (const name of candidates) {
4210
- const path2 = join7(dir, name);
5484
+ const path2 = join8(dir, name);
4211
5485
  if (await statMtime2(path2) !== null)
4212
5486
  return path2;
4213
5487
  }
@@ -4217,7 +5491,7 @@ async function scanCursorSessions() {
4217
5491
  const home = getCursorHome();
4218
5492
  const newCandidates = [];
4219
5493
  const legacyCandidates = [];
4220
- const projectsRoot = join7(home, NEW_PROJECTS_DIR);
5494
+ const projectsRoot = join8(home, NEW_PROJECTS_DIR);
4221
5495
  const projectEntries = await safeReaddir3(projectsRoot);
4222
5496
  if (projectEntries) {
4223
5497
  for (const proj of projectEntries) {
@@ -4225,7 +5499,7 @@ async function scanCursorSessions() {
4225
5499
  continue;
4226
5500
  const decoded = decodeFolderName(proj.name);
4227
5501
  const cwd = decoded.startsWith("/") || /^[A-Za-z]:\//.test(decoded) ? decoded : `/${decoded}`;
4228
- const transcriptsRoot = join7(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
5502
+ const transcriptsRoot = join8(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
4229
5503
  const sessionDirs = await safeReaddir3(transcriptsRoot);
4230
5504
  if (!sessionDirs)
4231
5505
  continue;
@@ -4234,28 +5508,28 @@ async function scanCursorSessions() {
4234
5508
  continue;
4235
5509
  newCandidates.push({
4236
5510
  sessionId: sd.name,
4237
- dir: join7(transcriptsRoot, sd.name),
5511
+ dir: join8(transcriptsRoot, sd.name),
4238
5512
  cwd
4239
5513
  });
4240
5514
  }
4241
5515
  }
4242
5516
  }
4243
5517
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES) {
4244
- const root = join7(home, sub);
5518
+ const root = join8(home, sub);
4245
5519
  const entries = await safeReaddir3(root);
4246
5520
  if (!entries)
4247
5521
  continue;
4248
5522
  for (const e of entries) {
4249
5523
  if (!e.isDirectory())
4250
5524
  continue;
4251
- legacyCandidates.push({ sessionId: e.name, dir: join7(root, e.name) });
5525
+ legacyCandidates.push({ sessionId: e.name, dir: join8(root, e.name) });
4252
5526
  }
4253
5527
  }
4254
5528
  if (newCandidates.length === 0 && legacyCandidates.length === 0)
4255
5529
  return [];
4256
5530
  const settled = await batchAll([
4257
5531
  ...newCandidates.map((c) => async () => {
4258
- const transcriptPath = join7(c.dir, `${c.sessionId}.jsonl`);
5532
+ const transcriptPath = join8(c.dir, `${c.sessionId}.jsonl`);
4259
5533
  const transcriptMtime = await statMtime2(transcriptPath);
4260
5534
  if (!transcriptMtime)
4261
5535
  return null;
@@ -4528,10 +5802,10 @@ __export(exports_pi_projects, {
4528
5802
  getCachedPiProjects: () => getCachedPiProjects
4529
5803
  });
4530
5804
  import { readdir as readdir4, readFile as readFile6, stat as stat4 } from "node:fs/promises";
4531
- import { homedir as homedir10 } from "node:os";
4532
- import { join as join8 } from "node:path";
5805
+ import { homedir as homedir8 } from "node:os";
5806
+ import { join as join9 } from "node:path";
4533
5807
  function getPiSessionsRoot() {
4534
- return process.env.PI_SESSIONS_DIR || join8(homedir10(), ".pi", "agent", "sessions");
5808
+ return process.env.PI_SESSIONS_DIR || join9(homedir8(), ".pi", "agent", "sessions");
4535
5809
  }
4536
5810
  async function safeReaddir4(dir) {
4537
5811
  try {
@@ -4579,7 +5853,7 @@ async function scanPiSessions() {
4579
5853
  for (const cwdDir of cwdDirs) {
4580
5854
  if (!cwdDir.isDirectory())
4581
5855
  continue;
4582
- const cwdPath = join8(root, cwdDir.name);
5856
+ const cwdPath = join9(root, cwdDir.name);
4583
5857
  const sessionFiles = await safeReaddir4(cwdPath);
4584
5858
  if (!sessionFiles)
4585
5859
  continue;
@@ -4589,7 +5863,7 @@ async function scanPiSessions() {
4589
5863
  const m = SESSION_FILE_RE.exec(f.name);
4590
5864
  if (!m)
4591
5865
  continue;
4592
- candidates.push({ sessionId: m[1], filePath: join8(cwdPath, f.name) });
5866
+ candidates.push({ sessionId: m[1], filePath: join9(cwdPath, f.name) });
4593
5867
  }
4594
5868
  }
4595
5869
  if (candidates.length === 0)
@@ -4691,7 +5965,7 @@ var init_pi_projects = __esm(() => {
4691
5965
  });
4692
5966
 
4693
5967
  // lib/sqlite-reader.ts
4694
- import { existsSync as existsSync5, readFileSync as readFileSync3 } from "node:fs";
5968
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "node:fs";
4695
5969
  import initSqlJs from "sql.js/dist/sql-asm.js";
4696
5970
  async function tryNodeSqlite(dbPath) {
4697
5971
  try {
@@ -4718,7 +5992,7 @@ function loadSqlJs() {
4718
5992
  async function trySqlJs(dbPath) {
4719
5993
  try {
4720
5994
  const SQL = await loadSqlJs();
4721
- const db = new SQL.Database(readFileSync3(dbPath));
5995
+ const db = new SQL.Database(readFileSync4(dbPath));
4722
5996
  return {
4723
5997
  query(sql, params) {
4724
5998
  const stmt = db.prepare(sql);
@@ -4742,7 +6016,7 @@ async function trySqlJs(dbPath) {
4742
6016
  }
4743
6017
  }
4744
6018
  async function openSqliteReadonly(dbPath) {
4745
- if (!existsSync5(dbPath))
6019
+ if (!existsSync6(dbPath))
4746
6020
  return null;
4747
6021
  return await tryNodeSqlite(dbPath) ?? await trySqlJs(dbPath);
4748
6022
  }
@@ -4751,18 +6025,18 @@ var init_sqlite_reader = () => {};
4751
6025
 
4752
6026
  // lib/hermes-profiles.ts
4753
6027
  import { readdirSync as readdirSync3 } from "node:fs";
4754
- import { homedir as homedir11 } from "node:os";
4755
- import { basename as basename2, dirname as dirname3, join as join9, resolve as resolve5 } from "node:path";
6028
+ import { homedir as homedir9 } from "node:os";
6029
+ import { basename as basename2, dirname as dirname3, join as join10, resolve as resolve6 } from "node:path";
4756
6030
  function hermesRoot() {
4757
6031
  const env = (process.env.HERMES_HOME || "").trim();
4758
6032
  if (env) {
4759
- const home = resolve5(env);
6033
+ const home = resolve6(env);
4760
6034
  const parent = dirname3(home);
4761
6035
  if (basename2(parent) === PROFILES_DIR)
4762
6036
  return dirname3(parent);
4763
6037
  return home;
4764
6038
  }
4765
- return join9(homedir11(), ".hermes");
6039
+ return join10(homedir9(), ".hermes");
4766
6040
  }
4767
6041
  function listHermesProfiles() {
4768
6042
  const root = hermesRoot();
@@ -4770,7 +6044,7 @@ function listHermesProfiles() {
4770
6044
  const seen = new Set([HERMES_DEFAULT_PROFILE]);
4771
6045
  let names;
4772
6046
  try {
4773
- names = readdirSync3(join9(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
6047
+ names = readdirSync3(join10(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
4774
6048
  } catch {
4775
6049
  return out;
4776
6050
  }
@@ -4778,7 +6052,7 @@ function listHermesProfiles() {
4778
6052
  if (seen.has(name))
4779
6053
  continue;
4780
6054
  seen.add(name);
4781
- out.push({ name, home: join9(root, PROFILES_DIR, name) });
6055
+ out.push({ name, home: join10(root, PROFILES_DIR, name) });
4782
6056
  }
4783
6057
  return out;
4784
6058
  }
@@ -4829,14 +6103,14 @@ function formatDuration(ms) {
4829
6103
  }
4830
6104
 
4831
6105
  // lib/hermes-sessions.ts
4832
- import { join as join10 } from "node:path";
6106
+ import { join as join11 } from "node:path";
4833
6107
  function hermesDbPaths() {
4834
6108
  const override = process.env.HERMES_DB_PATH;
4835
6109
  if (override)
4836
6110
  return [{ profile: HERMES_DEFAULT_PROFILE, dbPath: override }];
4837
6111
  return listHermesProfiles().map((p) => ({
4838
6112
  profile: p.name,
4839
- dbPath: join10(p.home, "state.db")
6113
+ dbPath: join11(p.home, "state.db")
4840
6114
  }));
4841
6115
  }
4842
6116
  function epochToMs(value) {
@@ -5133,11 +6407,11 @@ var init_hermes_projects = __esm(() => {
5133
6407
 
5134
6408
  // lib/openclaw-sessions.ts
5135
6409
  import { readFile as readFile7 } from "node:fs/promises";
5136
- import { readdirSync as readdirSync4, statSync as statSync5 } from "node:fs";
5137
- import { homedir as homedir12 } from "node:os";
5138
- import { join as join11 } from "node:path";
6410
+ import { readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
6411
+ import { homedir as homedir10 } from "node:os";
6412
+ import { join as join12 } from "node:path";
5139
6413
  function openclawHome() {
5140
- return process.env.OPENCLAW_HOME || join11(homedir12(), ".openclaw");
6414
+ return process.env.OPENCLAW_HOME || join12(homedir10(), ".openclaw");
5141
6415
  }
5142
6416
  function isPlainObject2(v) {
5143
6417
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -5252,13 +6526,13 @@ function openclawLinesToLogEntries(lines, source = "session") {
5252
6526
  }
5253
6527
  function listOpenClawAgents() {
5254
6528
  try {
5255
- return readdirSync4(join11(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
6529
+ return readdirSync4(join12(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
5256
6530
  } catch {
5257
6531
  return [];
5258
6532
  }
5259
6533
  }
5260
6534
  function listOpenClawTranscripts() {
5261
- const agentsDir = join11(openclawHome(), "agents");
6535
+ const agentsDir = join12(openclawHome(), "agents");
5262
6536
  const out = [];
5263
6537
  let agentIds;
5264
6538
  try {
@@ -5267,7 +6541,7 @@ function listOpenClawTranscripts() {
5267
6541
  return out;
5268
6542
  }
5269
6543
  for (const agentId of agentIds) {
5270
- const sessionsDir = join11(agentsDir, agentId, "sessions");
6544
+ const sessionsDir = join12(agentsDir, agentId, "sessions");
5271
6545
  let files;
5272
6546
  try {
5273
6547
  files = readdirSync4(sessionsDir);
@@ -5280,9 +6554,9 @@ function listOpenClawTranscripts() {
5280
6554
  const sessionId = file.slice(0, -".jsonl".length);
5281
6555
  if (!OPENCLAW_SESSION_ID_RE.test(sessionId))
5282
6556
  continue;
5283
- const transcriptPath = join11(sessionsDir, file);
6557
+ const transcriptPath = join12(sessionsDir, file);
5284
6558
  try {
5285
- const st = statSync5(transcriptPath);
6559
+ const st = statSync6(transcriptPath);
5286
6560
  out.push({ agentId, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
5287
6561
  } catch {}
5288
6562
  }
@@ -5340,17 +6614,17 @@ __export(exports_openclaw_projects, {
5340
6614
  getCachedOpenClawSessions: () => getCachedOpenClawSessions,
5341
6615
  getCachedOpenClawProjects: () => getCachedOpenClawProjects
5342
6616
  });
5343
- import { readFileSync as readFileSync4 } from "node:fs";
5344
- import { join as join12 } from "node:path";
6617
+ import { readFileSync as readFileSync5 } from "node:fs";
6618
+ import { join as join13 } from "node:path";
5345
6619
  function str(v) {
5346
6620
  return typeof v === "string" && v.length > 0 ? v : undefined;
5347
6621
  }
5348
6622
  function readSessionsIndex(agentId) {
5349
6623
  const out = new Map;
5350
- const indexPath = join12(openclawHome(), "agents", agentId, "sessions", "sessions.json");
6624
+ const indexPath = join13(openclawHome(), "agents", agentId, "sessions", "sessions.json");
5351
6625
  let raw;
5352
6626
  try {
5353
- raw = JSON.parse(readFileSync4(indexPath, "utf-8"));
6627
+ raw = JSON.parse(readFileSync5(indexPath, "utf-8"));
5354
6628
  } catch {
5355
6629
  return out;
5356
6630
  }
@@ -5502,14 +6776,14 @@ var init_openclaw_projects = __esm(() => {
5502
6776
 
5503
6777
  // lib/factory-sessions.ts
5504
6778
  import { readFile as readFile8 } from "node:fs/promises";
5505
- import { readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
5506
- import { homedir as homedir13 } from "node:os";
5507
- import { join as join13 } from "node:path";
6779
+ import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
6780
+ import { homedir as homedir11 } from "node:os";
6781
+ import { join as join14 } from "node:path";
5508
6782
  function factoryHome() {
5509
- return process.env.FACTORY_HOME || join13(homedir13(), ".factory");
6783
+ return process.env.FACTORY_HOME || join14(homedir11(), ".factory");
5510
6784
  }
5511
6785
  function factorySessionsRoot() {
5512
- return join13(factoryHome(), "sessions");
6786
+ return join14(factoryHome(), "sessions");
5513
6787
  }
5514
6788
  function isPlainObject3(v) {
5515
6789
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -5655,7 +6929,7 @@ function listFactoryTranscripts() {
5655
6929
  for (const dir of projectDirs) {
5656
6930
  const projectName = dir.name;
5657
6931
  const cwd = decodeFolderName(projectName);
5658
- const projectPath = join13(root, projectName);
6932
+ const projectPath = join14(root, projectName);
5659
6933
  let files;
5660
6934
  try {
5661
6935
  files = readdirSync5(projectPath);
@@ -5668,9 +6942,9 @@ function listFactoryTranscripts() {
5668
6942
  const sessionId = file.slice(0, -".jsonl".length);
5669
6943
  if (!FACTORY_SESSION_ID_RE.test(sessionId))
5670
6944
  continue;
5671
- const transcriptPath = join13(projectPath, file);
6945
+ const transcriptPath = join14(projectPath, file);
5672
6946
  try {
5673
- const st = statSync6(transcriptPath);
6947
+ const st = statSync7(transcriptPath);
5674
6948
  out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
5675
6949
  } catch {}
5676
6950
  }
@@ -5794,13 +7068,13 @@ var init_factory_projects = __esm(() => {
5794
7068
  });
5795
7069
 
5796
7070
  // lib/devin-sessions.ts
5797
- import { homedir as homedir14 } from "node:os";
5798
- import { join as join14 } from "node:path";
7071
+ import { homedir as homedir12 } from "node:os";
7072
+ import { join as join15 } from "node:path";
5799
7073
  function devinHome() {
5800
- return process.env.DEVIN_HOME || join14(homedir14(), ".local", "share", "devin");
7074
+ return process.env.DEVIN_HOME || join15(homedir12(), ".local", "share", "devin");
5801
7075
  }
5802
7076
  function devinDbPath() {
5803
- return process.env.DEVIN_DB_PATH || join14(devinHome(), "cli", "sessions.db");
7077
+ return process.env.DEVIN_DB_PATH || join15(devinHome(), "cli", "sessions.db");
5804
7078
  }
5805
7079
  function devinEpochToMs(value) {
5806
7080
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -6097,17 +7371,17 @@ var init_devin_projects = __esm(() => {
6097
7371
 
6098
7372
  // lib/antigravity-sessions.ts
6099
7373
  import { readFile as readFile9 } from "node:fs/promises";
6100
- import { readdirSync as readdirSync6, statSync as statSync7 } from "node:fs";
6101
- import { homedir as homedir15 } from "node:os";
6102
- import { join as join15 } from "node:path";
7374
+ import { readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
7375
+ import { homedir as homedir13 } from "node:os";
7376
+ import { join as join16 } from "node:path";
6103
7377
  function antigravityHome() {
6104
- return process.env.ANTIGRAVITY_HOME || join15(homedir15(), ".gemini", "antigravity-cli");
7378
+ return process.env.ANTIGRAVITY_HOME || join16(homedir13(), ".gemini", "antigravity-cli");
6105
7379
  }
6106
7380
  function antigravityBrainRoot() {
6107
- return join15(antigravityHome(), "brain");
7381
+ return join16(antigravityHome(), "brain");
6108
7382
  }
6109
7383
  function antigravityTranscriptRelPath() {
6110
- return join15(".system_generated", "logs", "transcript_full.jsonl");
7384
+ return join16(".system_generated", "logs", "transcript_full.jsonl");
6111
7385
  }
6112
7386
  function isPlainObject5(v) {
6113
7387
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -6230,9 +7504,9 @@ function listAntigravityTranscripts() {
6230
7504
  const conversationId = dir.name;
6231
7505
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
6232
7506
  continue;
6233
- const transcriptPath = join15(root, conversationId, rel);
7507
+ const transcriptPath = join16(root, conversationId, rel);
6234
7508
  try {
6235
- const st = statSync7(transcriptPath);
7509
+ const st = statSync8(transcriptPath);
6236
7510
  if (!st.isFile())
6237
7511
  continue;
6238
7512
  out.push({ conversationId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -6243,9 +7517,9 @@ function listAntigravityTranscripts() {
6243
7517
  function findAntigravityTranscript(conversationId) {
6244
7518
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
6245
7519
  return null;
6246
- const transcriptPath = join15(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
7520
+ const transcriptPath = join16(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
6247
7521
  try {
6248
- if (statSync7(transcriptPath).isFile())
7522
+ if (statSync8(transcriptPath).isFile())
6249
7523
  return transcriptPath;
6250
7524
  } catch {}
6251
7525
  return null;
@@ -6283,9 +7557,9 @@ __export(exports_antigravity_projects, {
6283
7557
  getAntigravityIndex: () => getAntigravityIndex,
6284
7558
  antigravitySummariesDbPath: () => antigravitySummariesDbPath
6285
7559
  });
6286
- import { join as join16 } from "node:path";
7560
+ import { join as join17 } from "node:path";
6287
7561
  function antigravitySummariesDbPath() {
6288
- return join16(antigravityHome(), "conversation_summaries.db");
7562
+ return join17(antigravityHome(), "conversation_summaries.db");
6289
7563
  }
6290
7564
  function parseWorkspaceCwd(raw) {
6291
7565
  if (!raw)
@@ -6428,16 +7702,16 @@ var init_antigravity_projects = __esm(() => {
6428
7702
  });
6429
7703
 
6430
7704
  // lib/goose-sessions.ts
6431
- import { homedir as homedir16 } from "node:os";
6432
- import { join as join17 } from "node:path";
7705
+ import { homedir as homedir14 } from "node:os";
7706
+ import { join as join18 } from "node:path";
6433
7707
  function gooseHome() {
6434
7708
  if (process.env.GOOSE_HOME)
6435
7709
  return process.env.GOOSE_HOME;
6436
7710
  const xdg = process.env.XDG_DATA_HOME;
6437
- return join17(xdg && xdg.length > 0 ? xdg : join17(homedir16(), ".local", "share"), "goose");
7711
+ return join18(xdg && xdg.length > 0 ? xdg : join18(homedir14(), ".local", "share"), "goose");
6438
7712
  }
6439
7713
  function gooseDbPath() {
6440
- return process.env.GOOSE_DB_PATH || join17(gooseHome(), "sessions", "sessions.db");
7714
+ return process.env.GOOSE_DB_PATH || join18(gooseHome(), "sessions", "sessions.db");
6441
7715
  }
6442
7716
  function gooseTimestampToMs(value) {
6443
7717
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -6705,7 +7979,7 @@ var init_goose_projects = __esm(() => {
6705
7979
 
6706
7980
  // lib/projects.ts
6707
7981
  import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
6708
- import { join as join18, resolve as resolve6, sep } from "node:path";
7982
+ import { join as join19, resolve as resolve7, sep } from "node:path";
6709
7983
  async function getMtime(path2, label) {
6710
7984
  try {
6711
7985
  return (await stat5(path2)).mtime;
@@ -6731,7 +8005,7 @@ async function getClaudeProjectFolders() {
6731
8005
  if (!entries)
6732
8006
  return [];
6733
8007
  const settled = await batchAll(entries.filter((entry) => entry.isDirectory()).map((entry) => async () => {
6734
- const folderPath = join18(projectsPath, entry.name);
8008
+ const folderPath = join19(projectsPath, entry.name);
6735
8009
  const mtime = await getMtime(folderPath, entry.name);
6736
8010
  return {
6737
8011
  name: entry.name,
@@ -6857,8 +8131,8 @@ function resolveProjectPath(projectName) {
6857
8131
  throw new RangeError("Empty project name");
6858
8132
  if (/^[/\\]/.test(projectName))
6859
8133
  throw new RangeError("Absolute project name");
6860
- const projectsPath = resolve6(getClaudeProjectsPath());
6861
- const candidate = resolve6(join18(projectsPath, projectName));
8134
+ const projectsPath = resolve7(getClaudeProjectsPath());
8135
+ const candidate = resolve7(join19(projectsPath, projectName));
6862
8136
  if (!candidate.startsWith(projectsPath + sep)) {
6863
8137
  throw new RangeError("Project path escapes root");
6864
8138
  }
@@ -6876,7 +8150,7 @@ async function getSessionFiles(projectPath) {
6876
8150
  return [];
6877
8151
  const jsonlEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl") && extractSessionId2(entry.name));
6878
8152
  const settled = await batchAll(jsonlEntries.map((entry) => async () => {
6879
- const filePath = join18(projectPath, entry.name);
8153
+ const filePath = join19(projectPath, entry.name);
6880
8154
  const mtime = await getMtime(filePath, entry.name);
6881
8155
  return {
6882
8156
  name: entry.name,
@@ -6905,13 +8179,13 @@ var init_projects = __esm(() => {
6905
8179
 
6906
8180
  // lib/resolve-subagent-path.ts
6907
8181
  import { access as access2 } from "fs/promises";
6908
- import { join as join19, relative as relative2 } from "path";
8182
+ import { join as join20, relative as relative2 } from "path";
6909
8183
  async function resolveSubagentPath(projectsPath, projectName, sessionId, agentId) {
6910
8184
  const fileName = `agent-${agentId}.jsonl`;
6911
8185
  const candidatePaths = [
6912
- join19(projectsPath, projectName, fileName),
6913
- join19(projectsPath, projectName, sessionId, fileName),
6914
- join19(projectsPath, projectName, sessionId, "subagents", fileName)
8186
+ join20(projectsPath, projectName, fileName),
8187
+ join20(projectsPath, projectName, sessionId, fileName),
8188
+ join20(projectsPath, projectName, sessionId, "subagents", fileName)
6915
8189
  ];
6916
8190
  for (const candidatePath of candidatePaths) {
6917
8191
  if (relative2(projectsPath, candidatePath).startsWith("..")) {
@@ -6933,7 +8207,7 @@ var init_resolve_subagent_path = () => {};
6933
8207
 
6934
8208
  // lib/log-entries.ts
6935
8209
  import { readFile as readFile10 } from "fs/promises";
6936
- import { join as join20 } from "path";
8210
+ import { join as join21 } from "path";
6937
8211
  function formatTimestamp(date) {
6938
8212
  const base = formatDate(date);
6939
8213
  const ms = date.getMilliseconds().toString().padStart(3, "0");
@@ -7127,7 +8401,7 @@ async function parseFileContent(fileContent, source) {
7127
8401
  async function parseSessionLog(projectName, sessionId) {
7128
8402
  const projectDir = resolveProjectPath(projectName);
7129
8403
  const projectsPath = getClaudeProjectsPath();
7130
- const filePath = join20(projectDir, `${sessionId}.jsonl`);
8404
+ const filePath = join21(projectDir, `${sessionId}.jsonl`);
7131
8405
  const fileContent = await readFile10(filePath, "utf-8");
7132
8406
  const { entries: sessionEntries, rawLines: sessionRawLines, subagentIds } = await parseFileContent(fileContent, "session");
7133
8407
  if (subagentIds.length === 0) {
@@ -7164,32 +8438,32 @@ var init_log_entries = __esm(() => {
7164
8438
  });
7165
8439
 
7166
8440
  // lib/codex-sessions.ts
7167
- import { readFileSync as readFileSync5, readdirSync as readdirSync7, existsSync as existsSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, statSync as statSync8 } from "node:fs";
8441
+ import { readFileSync as readFileSync6, readdirSync as readdirSync7, existsSync as existsSync7, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, statSync as statSync9 } from "node:fs";
7168
8442
  import { readFile as readFile11 } from "node:fs/promises";
7169
- import { dirname as dirname4, join as join21 } from "node:path";
7170
- import { homedir as homedir17 } from "node:os";
8443
+ import { dirname as dirname4, join as join22 } from "node:path";
8444
+ import { homedir as homedir15 } from "node:os";
7171
8445
  function readCache() {
7172
8446
  try {
7173
- if (!existsSync6(CACHE_PATH))
8447
+ if (!existsSync7(CACHE_PATH))
7174
8448
  return {};
7175
- return JSON.parse(readFileSync5(CACHE_PATH, "utf-8"));
8449
+ return JSON.parse(readFileSync6(CACHE_PATH, "utf-8"));
7176
8450
  } catch {
7177
8451
  return {};
7178
8452
  }
7179
8453
  }
7180
8454
  function writeCacheEntry(sessionId, path2) {
7181
8455
  try {
7182
- mkdirSync4(dirname4(CACHE_PATH), { recursive: true });
8456
+ mkdirSync5(dirname4(CACHE_PATH), { recursive: true });
7183
8457
  const cache = readCache();
7184
8458
  cache[sessionId] = path2;
7185
- writeFileSync3(CACHE_PATH, JSON.stringify(cache), "utf-8");
8459
+ writeFileSync4(CACHE_PATH, JSON.stringify(cache), "utf-8");
7186
8460
  } catch {}
7187
8461
  }
7188
8462
  function dirSearch(dir, sessionId) {
7189
8463
  try {
7190
8464
  for (const f of readdirSync7(dir, { withFileTypes: true })) {
7191
8465
  if (f.isFile() && f.name.includes(sessionId) && f.name.endsWith(".jsonl")) {
7192
- return join21(dir, f.name);
8466
+ return join22(dir, f.name);
7193
8467
  }
7194
8468
  }
7195
8469
  } catch {}
@@ -7198,16 +8472,16 @@ function dirSearch(dir, sessionId) {
7198
8472
  function findCodexTranscript(sessionId) {
7199
8473
  const cache = readCache();
7200
8474
  const cached = cache[sessionId];
7201
- if (cached && existsSync6(cached))
8475
+ if (cached && existsSync7(cached))
7202
8476
  return cached;
7203
- const root = join21(homedir17(), ".codex", "sessions");
8477
+ const root = join22(homedir15(), ".codex", "sessions");
7204
8478
  const today = new Date;
7205
8479
  const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
7206
8480
  const datedDirs = [today, yesterday].map((d) => {
7207
8481
  const y = String(d.getUTCFullYear());
7208
8482
  const m = String(d.getUTCMonth() + 1).padStart(2, "0");
7209
8483
  const day = String(d.getUTCDate()).padStart(2, "0");
7210
- return join21(root, y, m, day);
8484
+ return join22(root, y, m, day);
7211
8485
  });
7212
8486
  for (const dir of datedDirs) {
7213
8487
  const hit = dirSearch(dir, sessionId);
@@ -7220,13 +8494,13 @@ function findCodexTranscript(sessionId) {
7220
8494
  for (const y of readdirSync7(root, { withFileTypes: true })) {
7221
8495
  if (!y.isDirectory())
7222
8496
  continue;
7223
- for (const m of readdirSync7(join21(root, y.name), { withFileTypes: true })) {
8497
+ for (const m of readdirSync7(join22(root, y.name), { withFileTypes: true })) {
7224
8498
  if (!m.isDirectory())
7225
8499
  continue;
7226
- for (const d of readdirSync7(join21(root, y.name, m.name), { withFileTypes: true })) {
8500
+ for (const d of readdirSync7(join22(root, y.name, m.name), { withFileTypes: true })) {
7227
8501
  if (!d.isDirectory())
7228
8502
  continue;
7229
- const hit = dirSearch(join21(root, y.name, m.name, d.name), sessionId);
8503
+ const hit = dirSearch(join22(root, y.name, m.name, d.name), sessionId);
7230
8504
  if (hit) {
7231
8505
  writeCacheEntry(sessionId, hit);
7232
8506
  return hit;
@@ -7446,12 +8720,13 @@ async function getCodexSessionLog(sessionId) {
7446
8720
  var CACHE_PATH, getCachedCodexSessionLog;
7447
8721
  var init_codex_sessions = __esm(() => {
7448
8722
  init_log_entries();
7449
- CACHE_PATH = join21(homedir17(), ".failproofai", "cache", "codex-session-paths.json");
8723
+ init_fp_home();
8724
+ CACHE_PATH = codexSessionPathsFile();
7450
8725
  getCachedCodexSessionLog = runtimeCache((sessionId) => getCodexSessionLog(sessionId), 60, { maxSize: 50 });
7451
8726
  });
7452
8727
 
7453
8728
  // src/hooks/resolve-permission-mode.ts
7454
- import { readFileSync as readFileSync6 } from "node:fs";
8729
+ import { readFileSync as readFileSync7 } from "node:fs";
7455
8730
  function resolvePermissionMode(integration, parsed, sessionId) {
7456
8731
  if (integration === "claude") {
7457
8732
  return parsed.permission_mode ?? "default";
@@ -7466,7 +8741,7 @@ function resolveCodexMode(sessionId) {
7466
8741
  const path2 = findCodexTranscript(sessionId);
7467
8742
  if (!path2)
7468
8743
  return;
7469
- for (const line of readFileSync6(path2, "utf-8").split(`
8744
+ for (const line of readFileSync7(path2, "utf-8").split(`
7470
8745
  `)) {
7471
8746
  if (!line.includes("turn_context"))
7472
8747
  continue;
@@ -7491,21 +8766,21 @@ var init_resolve_permission_mode = __esm(() => {
7491
8766
  });
7492
8767
 
7493
8768
  // lib/copilot-sessions.ts
7494
- import { readFileSync as readFileSync7, readdirSync as readdirSync8, existsSync as existsSync7, statSync as statSync9 } from "node:fs";
8769
+ import { readFileSync as readFileSync8, readdirSync as readdirSync8, existsSync as existsSync8, statSync as statSync10 } from "node:fs";
7495
8770
  import { readFile as readFile12 } from "node:fs/promises";
7496
- import { join as join22, resolve as resolve7, sep as sep2 } from "node:path";
7497
- import { homedir as homedir18 } from "node:os";
8771
+ import { join as join23, resolve as resolve8, sep as sep2 } from "node:path";
8772
+ import { homedir as homedir16 } from "node:os";
7498
8773
  function getCopilotHome() {
7499
- return process.env.COPILOT_HOME || join22(homedir18(), ".copilot");
8774
+ return process.env.COPILOT_HOME || join23(homedir16(), ".copilot");
7500
8775
  }
7501
8776
  function getCopilotSessionStateRoot2() {
7502
- return join22(getCopilotHome(), "session-state");
8777
+ return join23(getCopilotHome(), "session-state");
7503
8778
  }
7504
8779
  function getCopilotSessionDir(sessionId) {
7505
8780
  if (!sessionId)
7506
8781
  return null;
7507
- const root = resolve7(getCopilotSessionStateRoot2());
7508
- const candidate = resolve7(root, sessionId);
8782
+ const root = resolve8(getCopilotSessionStateRoot2());
8783
+ const candidate = resolve8(root, sessionId);
7509
8784
  if (candidate === root || !candidate.startsWith(`${root}${sep2}`))
7510
8785
  return null;
7511
8786
  return candidate;
@@ -7514,23 +8789,23 @@ function resolveSessionFile(sessionId, filename) {
7514
8789
  const dir = getCopilotSessionDir(sessionId);
7515
8790
  if (!dir)
7516
8791
  return null;
7517
- return join22(dir, filename);
8792
+ return join23(dir, filename);
7518
8793
  }
7519
8794
  function findCopilotTranscript(sessionId) {
7520
8795
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
7521
8796
  if (!candidate)
7522
8797
  return null;
7523
- return existsSync7(candidate) ? candidate : null;
8798
+ return existsSync8(candidate) ? candidate : null;
7524
8799
  }
7525
8800
  function findCopilotWorkspace(sessionId) {
7526
8801
  const candidate = resolveSessionFile(sessionId, "workspace.yaml");
7527
8802
  if (!candidate)
7528
8803
  return null;
7529
- return existsSync7(candidate) ? candidate : null;
8804
+ return existsSync8(candidate) ? candidate : null;
7530
8805
  }
7531
8806
  function readYamlScalar(path2, key) {
7532
8807
  try {
7533
- const text = readFileSync7(path2, "utf-8");
8808
+ const text = readFileSync8(path2, "utf-8");
7534
8809
  const re = new RegExp(`^${key}\\s*:\\s*(.+?)\\s*$`, "m");
7535
8810
  const m = text.match(re);
7536
8811
  if (!m)
@@ -7708,18 +8983,18 @@ var init_copilot_sessions = __esm(() => {
7708
8983
  });
7709
8984
 
7710
8985
  // lib/cursor-sessions.ts
7711
- import { readFileSync as readFileSync8, readdirSync as readdirSync9, existsSync as existsSync8, statSync as statSync10 } from "node:fs";
8986
+ import { readFileSync as readFileSync9, readdirSync as readdirSync9, existsSync as existsSync9, statSync as statSync11 } from "node:fs";
7712
8987
  import { readFile as readFile13 } from "node:fs/promises";
7713
- import { basename as basename3, join as join23, resolve as resolve8, sep as sep3 } from "node:path";
7714
- import { homedir as homedir19 } from "node:os";
8988
+ import { basename as basename3, join as join24, resolve as resolve9, sep as sep3 } from "node:path";
8989
+ import { homedir as homedir17 } from "node:os";
7715
8990
  function getCursorHome2() {
7716
- return process.env.CURSOR_HOME || join23(homedir19(), ".cursor");
8991
+ return process.env.CURSOR_HOME || join24(homedir17(), ".cursor");
7717
8992
  }
7718
8993
  function getCursorSessionDir(sessionId) {
7719
8994
  if (!sessionId)
7720
8995
  return null;
7721
- const home = resolve8(getCursorHome2());
7722
- const projectsRoot = resolve8(home, NEW_PROJECTS_DIR2);
8996
+ const home = resolve9(getCursorHome2());
8997
+ const projectsRoot = resolve9(home, NEW_PROJECTS_DIR2);
7723
8998
  let projectEntries = [];
7724
8999
  try {
7725
9000
  projectEntries = readdirSync9(projectsRoot, { withFileTypes: true });
@@ -7727,19 +9002,19 @@ function getCursorSessionDir(sessionId) {
7727
9002
  for (const entry of projectEntries) {
7728
9003
  if (!entry.isDirectory())
7729
9004
  continue;
7730
- const candidate = resolve8(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2, sessionId);
7731
- const transcriptRoot = resolve8(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
9005
+ const candidate = resolve9(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2, sessionId);
9006
+ const transcriptRoot = resolve9(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
7732
9007
  if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
7733
9008
  continue;
7734
- if (existsSync8(candidate))
9009
+ if (existsSync9(candidate))
7735
9010
  return candidate;
7736
9011
  }
7737
9012
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
7738
- const root = resolve8(home, sub);
7739
- const candidate = resolve8(root, sessionId);
9013
+ const root = resolve9(home, sub);
9014
+ const candidate = resolve9(root, sessionId);
7740
9015
  if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
7741
9016
  continue;
7742
- if (existsSync8(candidate))
9017
+ if (existsSync9(candidate))
7743
9018
  return candidate;
7744
9019
  }
7745
9020
  return null;
@@ -7748,12 +9023,12 @@ function findCursorTranscript(sessionId) {
7748
9023
  const dir = getCursorSessionDir(sessionId);
7749
9024
  if (!dir)
7750
9025
  return null;
7751
- const newCandidate = join23(dir, `${basename3(dir)}.jsonl`);
7752
- if (existsSync8(newCandidate))
9026
+ const newCandidate = join24(dir, `${basename3(dir)}.jsonl`);
9027
+ if (existsSync9(newCandidate))
7753
9028
  return newCandidate;
7754
9029
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
7755
- const candidate = join23(dir, name);
7756
- if (existsSync8(candidate))
9030
+ const candidate = join24(dir, name);
9031
+ if (existsSync9(candidate))
7757
9032
  return candidate;
7758
9033
  }
7759
9034
  return null;
@@ -7964,12 +9239,12 @@ var init_cursor_sessions = __esm(() => {
7964
9239
  });
7965
9240
 
7966
9241
  // lib/pi-sessions.ts
7967
- import { readFileSync as readFileSync9, readdirSync as readdirSync10, existsSync as existsSync9, statSync as statSync11 } from "node:fs";
9242
+ import { readFileSync as readFileSync10, readdirSync as readdirSync10, existsSync as existsSync10, statSync as statSync12 } from "node:fs";
7968
9243
  import { readFile as readFile14 } from "node:fs/promises";
7969
- import { join as join24, resolve as resolve9, sep as sep4 } from "node:path";
7970
- import { homedir as homedir20 } from "node:os";
9244
+ import { join as join25, resolve as resolve10, sep as sep4 } from "node:path";
9245
+ import { homedir as homedir18 } from "node:os";
7971
9246
  function getPiSessionStateRoot() {
7972
- return process.env.PI_SESSIONS_DIR || join24(homedir20(), ".pi", "agent", "sessions");
9247
+ return process.env.PI_SESSIONS_DIR || join25(homedir18(), ".pi", "agent", "sessions");
7973
9248
  }
7974
9249
  function isSafeSessionId(sessionId) {
7975
9250
  return UUID_RE.test(sessionId);
@@ -7977,7 +9252,7 @@ function isSafeSessionId(sessionId) {
7977
9252
  function findPiTranscript(sessionId) {
7978
9253
  if (!isSafeSessionId(sessionId))
7979
9254
  return null;
7980
- const root = resolve9(getPiSessionStateRoot());
9255
+ const root = resolve10(getPiSessionStateRoot());
7981
9256
  let cwdDirs;
7982
9257
  try {
7983
9258
  cwdDirs = readdirSync10(root);
@@ -7985,7 +9260,7 @@ function findPiTranscript(sessionId) {
7985
9260
  return null;
7986
9261
  }
7987
9262
  for (const cwdDir of cwdDirs) {
7988
- const cwdPath = resolve9(root, cwdDir);
9263
+ const cwdPath = resolve10(root, cwdDir);
7989
9264
  if (!cwdPath.startsWith(`${root}${sep4}`))
7990
9265
  continue;
7991
9266
  let files;
@@ -7998,10 +9273,10 @@ function findPiTranscript(sessionId) {
7998
9273
  const m = SESSION_FILE_RE2.exec(f);
7999
9274
  if (!m || m[1].toLowerCase() !== sessionId.toLowerCase())
8000
9275
  continue;
8001
- const candidate = resolve9(cwdPath, f);
9276
+ const candidate = resolve10(cwdPath, f);
8002
9277
  if (!candidate.startsWith(`${cwdPath}${sep4}`))
8003
9278
  continue;
8004
- if (existsSync9(candidate))
9279
+ if (existsSync10(candidate))
8005
9280
  return candidate;
8006
9281
  }
8007
9282
  }
@@ -8019,7 +9294,7 @@ function extractMessageText(content) {
8019
9294
 
8020
9295
  `);
8021
9296
  }
8022
- function buildAssistantContent(content) {
9297
+ function buildAssistantContent(content, onToolUse) {
8023
9298
  if (!Array.isArray(content))
8024
9299
  return [];
8025
9300
  const blocks = [];
@@ -8030,6 +9305,14 @@ function buildAssistantContent(content) {
8030
9305
  if (block?.type === "thinking" && typeof block.thinking === "string" && block.thinking.length > 0) {
8031
9306
  blocks.push({ type: "text", text: `[thinking] ${block.thinking}` });
8032
9307
  }
9308
+ if (block?.type === "toolCall") {
9309
+ const id = typeof block.id === "string" && block.id.length > 0 ? block.id : `${typeof block.name === "string" ? block.name : "tool"}-${blocks.length}`;
9310
+ const name = typeof block.name === "string" ? block.name : "tool";
9311
+ const input = block.arguments && typeof block.arguments === "object" && !Array.isArray(block.arguments) ? block.arguments : {};
9312
+ const toolUse = { type: "tool_use", id, name, input };
9313
+ blocks.push(toolUse);
9314
+ onToolUse?.(toolUse);
9315
+ }
8033
9316
  }
8034
9317
  return blocks;
8035
9318
  }
@@ -8040,6 +9323,8 @@ async function parsePiLog(fileContent, source = "session") {
8040
9323
  const rawLines = [];
8041
9324
  let cwd;
8042
9325
  let seenSessionStart = false;
9326
+ const toolUseById = new Map;
9327
+ const toolUseStartMs = new Map;
8043
9328
  for (let i = 0;i < lines.length; i++) {
8044
9329
  if (i > 0 && i % 200 === 0)
8045
9330
  await new Promise((r) => setImmediate(r));
@@ -8087,7 +9372,10 @@ async function parsePiLog(fileContent, source = "session") {
8087
9372
  continue;
8088
9373
  }
8089
9374
  if (role === "assistant") {
8090
- const blocks = buildAssistantContent(content);
9375
+ const blocks = buildAssistantContent(content, (block) => {
9376
+ toolUseById.set(block.id, block);
9377
+ toolUseStartMs.set(block.id, date.getTime());
9378
+ });
8091
9379
  if (blocks.length === 0) {
8092
9380
  entries.push({
8093
9381
  type: "system",
@@ -8103,6 +9391,22 @@ async function parsePiLog(fileContent, source = "session") {
8103
9391
  });
8104
9392
  continue;
8105
9393
  }
9394
+ if (role === "toolResult") {
9395
+ const callId = raw.message.toolCallId;
9396
+ const block = typeof callId === "string" ? toolUseById.get(callId) : undefined;
9397
+ if (block) {
9398
+ const startMs = typeof callId === "string" && toolUseStartMs.get(callId) || date.getTime();
9399
+ const durationMs = Math.max(0, date.getTime() - startMs);
9400
+ block.result = {
9401
+ timestamp,
9402
+ timestampFormatted: formatTimestamp(date),
9403
+ content: extractMessageText(content),
9404
+ durationMs,
9405
+ durationFormatted: formatDuration(durationMs)
9406
+ };
9407
+ continue;
9408
+ }
9409
+ }
8106
9410
  entries.push({
8107
9411
  type: "system",
8108
9412
  ...baseEntry(rawCopy, timestamp, date, source),
@@ -8197,12 +9501,11 @@ var init_resolve_transcript_path = __esm(() => {
8197
9501
  init_antigravity_sessions();
8198
9502
  });
8199
9503
  // src/hooks/cloud-managed-policies.ts
8200
- import { createHash as createHash2 } from "node:crypto";
8201
- import { existsSync as existsSync10, readFileSync as readFileSync10, realpathSync } from "node:fs";
8202
- import { homedir as homedir21 } from "node:os";
8203
- import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve10 } from "node:path";
9504
+ import { createHash as createHash3 } from "node:crypto";
9505
+ import { existsSync as existsSync11, readFileSync as readFileSync11, realpathSync, rmSync } from "node:fs";
9506
+ import { isAbsolute as isAbsolute2, relative as relative3, resolve as resolve11 } from "node:path";
8204
9507
  function cloudManagedPolicyRoot() {
8205
- return process.env.FAILPROOFAI_CLOUD_POLICY_DIR ?? resolve10(homedir21(), ".failproofai", "policies", "cloud-managed");
9508
+ return process.env.FAILPROOFAI_CLOUD_POLICY_DIR ?? cloudPoliciesDir();
8206
9509
  }
8207
9510
  function parseManifest(value) {
8208
9511
  if (!value || typeof value !== "object")
@@ -8221,7 +9524,7 @@ function parseManifest(value) {
8221
9524
  function resolveManagedPath(root, candidate) {
8222
9525
  if (!candidate || isAbsolute2(candidate))
8223
9526
  throw new Error(`unsafe managed policy path ${JSON.stringify(candidate)}`);
8224
- const absolute = resolve10(root, candidate);
9527
+ const absolute = resolve11(root, candidate);
8225
9528
  const lexicalRelative = relative3(root, absolute);
8226
9529
  if (lexicalRelative.startsWith("..") || isAbsolute2(lexicalRelative)) {
8227
9530
  throw new Error(`managed policy path escapes its root: ${JSON.stringify(candidate)}`);
@@ -8236,12 +9539,12 @@ function resolveManagedPath(root, candidate) {
8236
9539
  }
8237
9540
  function readActiveCloudManagedPolicies() {
8238
9541
  const root = cloudManagedPolicyRoot();
8239
- const activePath = resolve10(root, "active.json");
8240
- if (!existsSync10(activePath))
9542
+ const activePath = resolve11(root, "active.json");
9543
+ if (!existsSync11(activePath))
8241
9544
  return [];
8242
9545
  let raw;
8243
9546
  try {
8244
- raw = JSON.parse(readFileSync10(activePath, "utf8"));
9547
+ raw = JSON.parse(readFileSync11(activePath, "utf8"));
8245
9548
  } catch (err) {
8246
9549
  throw new Error(`failed to read cloud-managed active manifest: ${err instanceof Error ? err.message : String(err)}`);
8247
9550
  }
@@ -8261,8 +9564,8 @@ function readActiveCloudManagedPolicies() {
8261
9564
  throw new Error(`duplicate cloud-managed policy id ${policy.id}`);
8262
9565
  seen.add(policy.id);
8263
9566
  const path2 = resolveManagedPath(root, policy.path);
8264
- const bytes = readFileSync10(path2);
8265
- const actual = createHash2("sha256").update(bytes).digest("hex");
9567
+ const bytes = readFileSync11(path2);
9568
+ const actual = createHash3("sha256").update(bytes).digest("hex");
8266
9569
  if (actual !== policy.sha256) {
8267
9570
  throw new Error(`cloud-managed policy ${policy.id} failed integrity verification: expected ${policy.sha256}, got ${actual}`);
8268
9571
  }
@@ -8281,6 +9584,7 @@ function readActiveCloudManagedPolicies() {
8281
9584
  }
8282
9585
  var ACTIVE_SCHEMA_VERSION = 1, SHA256_RE, POLICY_ID_RE;
8283
9586
  var init_cloud_managed_policies = __esm(() => {
9587
+ init_fp_home();
8284
9588
  SHA256_RE = /^[a-f0-9]{64}$/;
8285
9589
  POLICY_ID_RE = /^[A-Za-z0-9._-]{1,128}$/;
8286
9590
  });
@@ -8289,19 +9593,18 @@ var init_cloud_managed_policies = __esm(() => {
8289
9593
  var init_atomic_write = () => {};
8290
9594
 
8291
9595
  // src/hooks/session-pause.ts
8292
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readdirSync as readdirSync11, readFileSync as readFileSync11, rmSync } from "node:fs";
8293
- import { homedir as homedir22 } from "node:os";
8294
- import { createHash as createHash3 } from "node:crypto";
8295
- import { join as join25, resolve as resolve11 } from "node:path";
9596
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readdirSync as readdirSync11, readFileSync as readFileSync12, rmSync as rmSync2 } from "node:fs";
9597
+ import { createHash as createHash4 } from "node:crypto";
9598
+ import { join as join26, resolve as resolve12 } from "node:path";
8296
9599
  function pauseStateDir() {
8297
9600
  const override = process.env.FAILPROOFAI_STATE_DIR;
8298
9601
  if (override)
8299
- return resolve11(override, "sessions");
8300
- return join25(homedir22(), ".failproofai", "state", "sessions");
9602
+ return resolve12(override, "sessions");
9603
+ return sessionPauseDir();
8301
9604
  }
8302
9605
  function pauseFilePath(sessionId) {
8303
- const digest = createHash3("sha256").update(sessionId).digest("hex").slice(0, 32);
8304
- return join25(pauseStateDir(), `${digest}.json`);
9606
+ const digest = createHash4("sha256").update(sessionId).digest("hex").slice(0, 32);
9607
+ return join26(pauseStateDir(), `${digest}.json`);
8305
9608
  }
8306
9609
  function parseStored(raw) {
8307
9610
  if (!raw || typeof raw !== "object")
@@ -8313,11 +9616,14 @@ function parseStored(raw) {
8313
9616
  return null;
8314
9617
  if (!Number.isFinite(p.pausedAt) || !Number.isFinite(p.expiresAt))
8315
9618
  return null;
9619
+ const pausedAt = p.pausedAt;
9620
+ const firstPausedAt = Number.isFinite(p.firstPausedAt) ? p.firstPausedAt : pausedAt;
8316
9621
  return {
8317
9622
  schemaVersion: SCHEMA_VERSION,
8318
9623
  sessionId: p.sessionId,
8319
- pausedAt: p.pausedAt,
8320
- expiresAt: p.expiresAt,
9624
+ pausedAt,
9625
+ firstPausedAt,
9626
+ expiresAt: Math.min(p.expiresAt, firstPausedAt + PAUSE_CEILING_MS),
8321
9627
  setBy: typeof p.setBy === "string" ? p.setBy : "unknown",
8322
9628
  ...typeof p.cwd === "string" ? { cwd: p.cwd } : {}
8323
9629
  };
@@ -8327,9 +9633,9 @@ function readActivePause(sessionId, now = Date.now()) {
8327
9633
  return null;
8328
9634
  try {
8329
9635
  const path2 = pauseFilePath(sessionId);
8330
- if (!existsSync11(path2))
9636
+ if (!existsSync12(path2))
8331
9637
  return null;
8332
- const stored = parseStored(JSON.parse(readFileSync11(path2, "utf8")));
9638
+ const stored = parseStored(JSON.parse(readFileSync12(path2, "utf8")));
8333
9639
  if (!stored)
8334
9640
  return null;
8335
9641
  if (stored.expiresAt <= now)
@@ -8344,10 +9650,42 @@ var SCHEMA_VERSION = 1, PAUSE_DEFAULT_MS, PAUSE_CEILING_MS;
8344
9650
  var init_session_pause = __esm(() => {
8345
9651
  init_atomic_write();
8346
9652
  init_hook_activity_store();
9653
+ init_fp_home();
8347
9654
  PAUSE_DEFAULT_MS = 30 * 60000;
8348
9655
  PAUSE_CEILING_MS = 8 * 60 * 60000;
8349
9656
  });
8350
9657
 
9658
+ // src/hooks/daemon-download.ts
9659
+ var init_daemon_download = __esm(() => {
9660
+ init_package();
9661
+ init_fp_home();
9662
+ });
9663
+
9664
+ // src/hooks/daemon-service.ts
9665
+ var init_daemon_service = __esm(() => {
9666
+ init_hook_logger();
9667
+ init_daemon_download();
9668
+ init_fp_home();
9669
+ init_package();
9670
+ init_fp_config();
9671
+ });
9672
+
9673
+ // src/hooks/fp-reset.ts
9674
+ function layoutWarningForHook() {
9675
+ const state = detectLayout();
9676
+ if (state.kind === "current" || state.kind === "absent")
9677
+ return null;
9678
+ if (state.kind === "future") {
9679
+ return `[failproofai] this directory was written by a newer version ` + `(layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
9680
+ }
9681
+ return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
9682
+ }
9683
+ var init_fp_reset = __esm(() => {
9684
+ init_fp_home();
9685
+ init_fp_config();
9686
+ init_daemon_service();
9687
+ });
9688
+
8351
9689
  // src/hooks/handler.ts
8352
9690
  function canonicalizeEventType(raw, cli) {
8353
9691
  if (cli === "codex") {
@@ -8402,6 +9740,9 @@ async function runObserved(hook, ctx, hookName, eventType, cli) {
8402
9740
  }
8403
9741
  async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts) {
8404
9742
  const startTime = performance.now();
9743
+ const layoutWarning = layoutWarningForHook();
9744
+ if (layoutWarning)
9745
+ hookLogWarn(layoutWarning);
8405
9746
  try {
8406
9747
  let parsed = {};
8407
9748
  if (stdinPayload) {
@@ -8455,7 +9796,17 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
8455
9796
  clearPolicies();
8456
9797
  activePause = readActivePause(session.sessionId);
8457
9798
  registerBuiltinPolicies(activePause ? [] : config.enabledPolicies);
8458
- const cloudManagedPolicies = readActiveCloudManagedPolicies();
9799
+ let cloudManagedPolicies = [];
9800
+ try {
9801
+ cloudManagedPolicies = readActiveCloudManagedPolicies();
9802
+ } catch (err) {
9803
+ const msg = err instanceof Error ? err.message : String(err);
9804
+ hookLogWarn(`[failproofai] cloud-managed policies could NOT be loaded and are not being enforced: ${msg}. ` + `Local policies are unaffected. Run \`failproofai config --status\` to check this machine's enrolment.`);
9805
+ trackHookEvent(getInstanceId(), "cloud_managed_load_error", {
9806
+ event_type: eventType,
9807
+ cli
9808
+ });
9809
+ }
8459
9810
  cloudGeneration = cloudManagedPolicies[0]?.generation;
8460
9811
  const configuredCustomPaths = config.customPoliciesPaths ?? config.customPoliciesPath;
8461
9812
  const allExplicitPaths = cloudManagedPolicies.length === 0 ? configuredCustomPaths : [
@@ -8628,6 +9979,7 @@ var init_handler = __esm(() => {
8628
9979
  init_hook_logger();
8629
9980
  init_cloud_managed_policies();
8630
9981
  init_session_pause();
9982
+ init_fp_reset();
8631
9983
  });
8632
9984
 
8633
9985
  // src/hooks/worker-server.ts
@@ -8636,7 +9988,7 @@ __export(exports_worker_server, {
8636
9988
  startWorkerServer: () => startWorkerServer
8637
9989
  });
8638
9990
  import { createServer } from "node:net";
8639
- import { existsSync as existsSync12, unlinkSync as unlinkSync2 } from "node:fs";
9991
+ import { existsSync as existsSync13, unlinkSync as unlinkSync2 } from "node:fs";
8640
9992
  function isWorkerHookRequest(msg) {
8641
9993
  if (!msg || typeof msg !== "object")
8642
9994
  return false;
@@ -8650,7 +10002,18 @@ function encodeFrame(value) {
8650
10002
  return Buffer.concat([header, body]);
8651
10003
  }
8652
10004
  function enqueue(task) {
8653
- processingChain = processingChain.then(task).catch(() => {});
10005
+ processingChain = processingChain.then(() => new Promise((settle) => {
10006
+ const timer = setTimeout(() => {
10007
+ hookLogWarn(`worker: a request did not settle within ${TASK_DEADLINE_MS}ms; ` + `exiting so the supervisor can respawn a clean worker`);
10008
+ process.exit(WEDGED_EXIT_CODE);
10009
+ }, TASK_DEADLINE_MS);
10010
+ timer.unref?.();
10011
+ const done = () => {
10012
+ clearTimeout(timer);
10013
+ settle();
10014
+ };
10015
+ task().then(done, done);
10016
+ })).catch(() => {});
8654
10017
  }
8655
10018
  function handleConnection(socket) {
8656
10019
  let recvBuf = Buffer.alloc(0);
@@ -8708,7 +10071,7 @@ function handleConnection(socket) {
8708
10071
  socket.on("error", () => {});
8709
10072
  }
8710
10073
  function startWorkerServer(socketPath) {
8711
- if (existsSync12(socketPath)) {
10074
+ if (existsSync13(socketPath)) {
8712
10075
  try {
8713
10076
  unlinkSync2(socketPath);
8714
10077
  } catch {}
@@ -8717,7 +10080,7 @@ function startWorkerServer(socketPath) {
8717
10080
  server.listen(socketPath);
8718
10081
  return server;
8719
10082
  }
8720
- var MAX_FRAME_LEN, processingChain;
10083
+ var MAX_FRAME_LEN, TASK_DEADLINE_MS = 60000, WEDGED_EXIT_CODE = 75, processingChain;
8721
10084
  var init_worker_server = __esm(() => {
8722
10085
  init_handler();
8723
10086
  init_hook_logger();
@@ -8727,13 +10090,13 @@ var init_worker_server = __esm(() => {
8727
10090
 
8728
10091
  // bin/failproofai-worker.mjs
8729
10092
  import { realpathSync as realpathSync2 } from "node:fs";
8730
- import { dirname as dirname5, resolve as resolve12 } from "node:path";
10093
+ import { dirname as dirname5, resolve as resolve13 } from "node:path";
8731
10094
  import { fileURLToPath } from "node:url";
8732
10095
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
8733
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve12(dirname5(realpathSync2(fileURLToPath(import.meta.url))), "..");
10096
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve13(dirname5(realpathSync2(fileURLToPath(import.meta.url))), "..");
8734
10097
  }
8735
10098
  if (!process.env.FAILPROOFAI_DIST_PATH) {
8736
- process.env.FAILPROOFAI_DIST_PATH = resolve12(dirname5(realpathSync2(fileURLToPath(import.meta.url))), "..", "dist");
10099
+ process.env.FAILPROOFAI_DIST_PATH = resolve13(dirname5(realpathSync2(fileURLToPath(import.meta.url))), "..", "dist");
8737
10100
  }
8738
10101
  var socketPath = process.env.FAILPROOFAI_WORKER_SOCKET;
8739
10102
  if (!socketPath) {