failproofai 1.0.0-beta.2 → 1.0.0-beta.21

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 (381) 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 +6 -6
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +1 -1
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  8. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  9. package/.next/standalone/.next/server/app/_global-error/page.js +3 -1
  10. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  13. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  14. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
  15. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  16. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
  17. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  18. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
  20. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  21. package/.next/standalone/.next/server/app/_not-found/page.js +3 -1
  22. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  25. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  26. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  27. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  28. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  29. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  30. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  31. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  32. package/.next/standalone/.next/server/app/api/audit/invite/route.js +3 -2
  33. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -3
  35. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/audit/status/route.js +1 -1
  37. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/auth/login-request/route.js +3 -1
  39. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js +3 -2
  41. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/auth/logout/route.js +3 -2
  43. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/auth/reminder/route.js +3 -2
  45. package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/auth/status/route.js +3 -2
  47. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  49. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  51. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  52. package/.next/standalone/.next/server/app/audit/page.js +5 -3
  53. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/index.html +1 -1
  56. package/.next/standalone/.next/server/app/index.rsc +15 -15
  57. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  59. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  60. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  61. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  62. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  63. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  64. package/.next/standalone/.next/server/app/page.js +3 -1
  65. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  66. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  67. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  68. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +30 -18
  69. package/.next/standalone/.next/server/app/policies/page.js +5 -3
  70. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  71. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  73. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  74. package/.next/standalone/.next/server/app/project/[name]/page.js +4 -2
  75. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  78. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  79. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  80. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +6 -4
  81. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  83. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  84. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  85. package/.next/standalone/.next/server/app/projects/page.js +4 -2
  86. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  87. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  88. package/.next/standalone/.next/server/app/settings/page/app-paths-manifest.json +3 -0
  89. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +18 -0
  90. package/.next/standalone/.next/server/app/settings/page/next-font-manifest.json +6 -0
  91. package/.next/standalone/.next/server/app/settings/page/react-loadable-manifest.json +1 -0
  92. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +53 -0
  93. package/.next/standalone/.next/server/app/settings/page.js +18 -0
  94. package/.next/standalone/.next/server/app/settings/page.js.map +5 -0
  95. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -0
  96. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +3 -0
  97. package/.next/standalone/.next/server/app-paths-manifest.json +2 -1
  98. package/.next/standalone/.next/server/chunks/[externals]__0h9_83k._.js +3 -0
  99. package/.next/standalone/.next/server/chunks/{[externals]__1nl3dvw._.js → [externals]__0r-zamh._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/[externals]__1ifpkx-._.js +3 -0
  101. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0l4vuqm._.js → [root-of-the-server]__00ni9za._.js} +2 -2
  102. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06hexd0._.js +3 -0
  103. package/.next/standalone/.next/server/chunks/[root-of-the-server]__08y94xv._.js +3 -0
  104. package/.next/standalone/.next/server/chunks/[root-of-the-server]__094p1f1._.js +3 -0
  105. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0_0xu5z._.js +1 -1
  106. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ed01_d._.js +3 -0
  107. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0-dh5jy._.js → [root-of-the-server]__0effm9m._.js} +2 -2
  108. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g0vcwt._.js +3 -0
  109. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__18d-9oi._.js → [root-of-the-server]__0ix8gm7._.js} +2 -2
  110. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0h3lfmp._.js → [root-of-the-server]__0ji11a-._.js} +2 -2
  111. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__10oa-v9._.js → [root-of-the-server]__0ojwjxl._.js} +2 -2
  112. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__16le-kd._.js → [root-of-the-server]__0pbp9fe._.js} +2 -2
  113. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0vb5fl2._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0sb_5m8._.js → [root-of-the-server]__131ebum._.js} +4 -4
  116. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ibjy5x._.js +3 -0
  117. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1tvn4wf._.js +1 -1
  118. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20d06rh._.js +3 -0
  119. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +3 -0
  120. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +3 -0
  121. package/.next/standalone/.next/server/chunks/lib_telemetry_ts_0dctyyw._.js +3 -0
  122. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +5 -5
  123. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -1
  124. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -1
  125. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  126. package/.next/standalone/.next/server/chunks/ssr/[externals]__1aq139v._.js +3 -0
  127. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-wfhrp._.js +3 -0
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__06bp_fg._.js +5 -0
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__074qmkp._.js +3 -0
  130. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1apb7k_._.js → [root-of-the-server]__0_1tiya._.js} +2 -2
  131. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__170799-._.js → [root-of-the-server]__0spkm68._.js} +11 -11
  132. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0t281d4._.js +3 -0
  133. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17itmx-._.js +5 -0
  134. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__01od0m6._.js → [root-of-the-server]__1n2vcv4._.js} +2 -2
  135. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
  136. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +3 -0
  137. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tlvv9a._.js +3 -0
  138. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +4 -0
  139. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +3 -0
  140. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +3 -0
  141. package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +3 -0
  142. package/.next/standalone/.next/server/chunks/ssr/_0vo2qyt._.js +3 -0
  143. package/.next/standalone/.next/server/chunks/ssr/_0xej-0e._.js +3 -0
  144. package/.next/standalone/.next/server/chunks/ssr/_10399ge._.js +3 -0
  145. package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
  146. package/.next/standalone/.next/server/chunks/ssr/_149k9oy._.js +3 -0
  147. package/.next/standalone/.next/server/chunks/ssr/_1_hwp06._.js +3 -0
  148. package/.next/standalone/.next/server/chunks/ssr/_1ctse6u._.js +3 -0
  149. package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +1 -1
  150. package/.next/standalone/.next/server/chunks/ssr/_1mnhi_r._.js +3 -0
  151. package/.next/standalone/.next/server/chunks/ssr/_1ror7k9._.js +3 -0
  152. package/.next/standalone/.next/server/chunks/ssr/_1sdgprl._.js +5 -0
  153. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
  154. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  155. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  156. package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0dwo94s.js +4 -0
  157. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -1
  158. package/.next/standalone/.next/server/chunks/ssr/src_hooks_builtin-policies_ts_09j2ndl._.js +3 -0
  159. package/.next/standalone/.next/server/chunks/ssr/src_hooks_fp-config_ts_04t589g._.js +4 -0
  160. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  161. package/.next/standalone/.next/server/middleware.js +2 -2
  162. package/.next/standalone/.next/server/pages/404.html +1 -1
  163. package/.next/standalone/.next/server/pages/500.html +1 -1
  164. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  165. package/.next/standalone/.next/server/server-reference-manifest.json +74 -20
  166. package/.next/standalone/.next/static/chunks/{03fmihek9n986.js → 06zgzyh3wv1ig.js} +1 -1
  167. package/.next/standalone/.next/static/chunks/0km-jn9o5xyqs.css +2 -0
  168. package/.next/standalone/.next/static/chunks/{1hdhteui932bq.js → 0qmo2t50kpb30.js} +1 -1
  169. package/.next/standalone/.next/static/chunks/{2sbelanzvxvv0.js → 113g8wtal6_c4.js} +22 -22
  170. package/.next/standalone/.next/static/chunks/16p68cybetr31.js +1 -0
  171. package/.next/standalone/.next/static/chunks/18wqn0_3mzylf.js +1 -0
  172. package/.next/standalone/.next/static/chunks/1v1gqvpjk62jm.js +1 -0
  173. package/.next/standalone/.next/static/chunks/{0fi645si-uiiq.js → 1xq1m8h14tnlj.js} +1 -1
  174. package/.next/standalone/.next/static/chunks/{3hp8ulqknybil.js → 1y3vwogqb88dx.js} +1 -1
  175. package/.next/standalone/.next/static/chunks/{3vs4ay36tjds_.js → 1zmh-b0ulrqu7.js} +1 -1
  176. package/.next/standalone/.next/static/chunks/23kev26by1e4f.js +1 -0
  177. package/.next/standalone/.next/static/chunks/299lhw60e8gr6.js +1 -0
  178. package/.next/standalone/.next/static/chunks/{18rvdw5v72364.js → 2adbpdaxp5ygq.js} +1 -1
  179. package/.next/standalone/.next/static/chunks/{2j94uwkb4s3qr.js → 2kbqcw-6swmav.js} +1 -1
  180. package/.next/standalone/.next/static/chunks/2n9n5m0963pdg.js +6 -0
  181. package/.next/standalone/.next/static/chunks/2uvhw57mf9lg_.css +2 -0
  182. package/.next/standalone/.next/static/chunks/{31feojxhjyjpl.js → 30nrrpwymht5m.js} +1 -1
  183. package/.next/standalone/.next/static/chunks/31coz11ia5vc4.js +1 -0
  184. package/.next/standalone/.next/static/chunks/{turbopack-1lsv92x7klwrn.js → turbopack-3diub4ctvn1n0.js} +1 -1
  185. package/.next/standalone/SECURITY.md +8 -2
  186. package/.next/standalone/app/actions/get-active-pauses.ts +16 -0
  187. package/.next/standalone/app/actions/get-hooks-config.ts +2 -2
  188. package/.next/standalone/app/actions/get-scheduled-audit.ts +70 -0
  189. package/.next/standalone/app/actions/update-scheduled-audit.ts +44 -0
  190. package/.next/standalone/app/api/audit/run/route.ts +28 -0
  191. package/.next/standalone/app/api/audit/status/route.ts +13 -1
  192. package/.next/standalone/app/api/auth/status/route.ts +1 -1
  193. package/.next/standalone/app/audit/_components/audit-dashboard.tsx +1 -3
  194. package/.next/standalone/app/audit/_components/audit-progress-strip.tsx +1 -1
  195. package/.next/standalone/app/audit/_components/auth-dialog.css +159 -0
  196. package/.next/standalone/app/audit/_components/auth-dialog.tsx +3 -0
  197. package/.next/standalone/app/audit/_components/come-back-better-section.tsx +1 -1
  198. package/.next/standalone/app/audit/_components/empty-state.tsx +0 -1
  199. package/.next/standalone/app/audit/_components/how-to-improve-section.tsx +1 -1
  200. package/.next/standalone/app/audit/_components/quirks-section.tsx +0 -1
  201. package/.next/standalone/app/audit/_components/report-footer.tsx +0 -2
  202. package/.next/standalone/app/audit/_components/run-progress.tsx +1 -1
  203. package/.next/standalone/app/audit/_components/strengths-section.tsx +0 -1
  204. package/.next/standalone/app/audit/audit-styles.css +6 -149
  205. package/.next/standalone/app/components/pause-notices.tsx +111 -0
  206. package/.next/standalone/app/components/raw-log-viewer.tsx +1 -1
  207. package/.next/standalone/app/components/toast.tsx +1 -1
  208. package/.next/standalone/app/policies/hooks-client.tsx +84 -8
  209. package/.next/standalone/app/settings/page.tsx +31 -0
  210. package/.next/standalone/app/settings/settings-client.tsx +487 -0
  211. package/.next/standalone/components/navbar.tsx +2 -0
  212. package/.next/standalone/lib/auth/api-server-client.ts +2 -3
  213. package/.next/standalone/lib/auth/auth-store.ts +4 -5
  214. package/.next/standalone/lib/codex-sessions.ts +2 -1
  215. package/.next/standalone/lib/dashboard-host.ts +101 -0
  216. package/.next/standalone/lib/install-check.ts +22 -7
  217. package/.next/standalone/lib/pi-sessions.ts +99 -14
  218. package/.next/standalone/lib/telemetry-enabled.ts +54 -0
  219. package/.next/standalone/lib/telemetry-id.ts +52 -1
  220. package/.next/standalone/lib/telemetry.ts +8 -4
  221. package/.next/standalone/node_modules/react/cjs/react.development.js +1 -1
  222. package/.next/standalone/node_modules/react/cjs/react.production.js +1 -1
  223. package/.next/standalone/node_modules/react/package.json +3 -3
  224. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1 -1
  225. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1 -1
  226. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +3 -3
  227. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +3 -3
  228. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +3 -3
  229. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +1 -1
  230. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  231. package/.next/standalone/package.json +23 -12
  232. package/.next/standalone/proxy.ts +111 -1
  233. package/.next/standalone/server.js +1 -1
  234. package/bin/failproofai-worker.mjs +1 -1
  235. package/bin/failproofai.mjs +1041 -81
  236. package/bin/failproofaid-shim.mjs +4 -4
  237. package/dist/cli.mjs +18513 -10474
  238. package/dist/worker.mjs +1223 -299
  239. package/lib/auth/api-server-client.ts +2 -3
  240. package/lib/auth/auth-store.ts +4 -5
  241. package/lib/codex-sessions.ts +2 -1
  242. package/lib/dashboard-host.ts +101 -0
  243. package/lib/install-check.ts +22 -7
  244. package/lib/pi-sessions.ts +99 -14
  245. package/lib/telemetry-enabled.ts +54 -0
  246. package/lib/telemetry-id.ts +52 -1
  247. package/lib/telemetry.ts +8 -4
  248. package/package.json +23 -12
  249. package/scripts/build-daemon-packages.mjs +247 -0
  250. package/scripts/daemon-platforms.mjs +42 -0
  251. package/scripts/dev-hook.mjs +46 -5
  252. package/scripts/install-telemetry.mjs +8 -1
  253. package/scripts/launch.ts +25 -3
  254. package/scripts/parse-script-args.ts +27 -1
  255. package/scripts/prune-standalone.mjs +26 -0
  256. package/scripts/publish-aliases.mjs +62 -41
  257. package/scripts/repro-npm-install.sh +155 -0
  258. package/scripts/translate-docs/cache.ts +1 -1
  259. package/scripts/translate-docs/cli.ts +2 -2
  260. package/scripts/translate-docs/mintlify-nav.ts +1 -1
  261. package/scripts/translate-docs/readme-translator.ts +163 -4
  262. package/scripts/validate-mdx.ts +153 -13
  263. package/src/audit/audit-lock.ts +285 -0
  264. package/src/audit/audit-schedule.ts +111 -0
  265. package/src/audit/cache.ts +18 -5
  266. package/src/audit/cli-adapters/goose.ts +2 -1
  267. package/src/audit/cli-adapters/hermes.ts +28 -10
  268. package/src/audit/cli.ts +191 -35
  269. package/src/audit/dashboard-cache.ts +2 -3
  270. package/src/audit/report.ts +0 -1
  271. package/src/hooks/backfill-cli.ts +247 -0
  272. package/src/hooks/builtin-policies.ts +391 -3
  273. package/src/hooks/cloud-connection.ts +354 -0
  274. package/src/hooks/cloud-enrollment-cli.ts +439 -0
  275. package/src/hooks/cloud-enrollment.ts +284 -0
  276. package/src/hooks/cloud-introspect.ts +147 -0
  277. package/src/hooks/cloud-managed-policies.ts +206 -0
  278. package/src/hooks/collector-config.ts +218 -0
  279. package/src/hooks/configure-wizard.ts +1211 -233
  280. package/src/hooks/custom-hooks-loader.ts +243 -37
  281. package/src/hooks/daemon-client.ts +136 -33
  282. package/src/hooks/daemon-download.ts +264 -31
  283. package/src/hooks/daemon-service.ts +1124 -76
  284. package/src/hooks/first-run-gate.ts +50 -0
  285. package/src/hooks/flush-cli.ts +180 -0
  286. package/src/hooks/fp-config.ts +835 -0
  287. package/src/hooks/fp-home.ts +714 -0
  288. package/src/hooks/fp-reset.ts +1363 -0
  289. package/src/hooks/handler.ts +185 -6
  290. package/src/hooks/harness-cli.ts +386 -0
  291. package/src/hooks/hook-activity-store.ts +171 -24
  292. package/src/hooks/hook-logger.ts +2 -2
  293. package/src/hooks/hook-telemetry.ts +5 -1
  294. package/src/hooks/hooks-config.ts +4 -3
  295. package/src/hooks/integrations.ts +0 -1
  296. package/src/hooks/loader-utils.ts +172 -9
  297. package/src/hooks/manager.ts +41 -5
  298. package/src/hooks/migrations.ts +450 -0
  299. package/src/hooks/onboarding-attempt.ts +195 -0
  300. package/src/hooks/onboarding-lock.ts +118 -0
  301. package/src/hooks/policy-types.ts +28 -0
  302. package/src/hooks/session-pause-cli.ts +159 -0
  303. package/src/hooks/session-pause.ts +267 -0
  304. package/src/hooks/setup-state.ts +256 -0
  305. package/src/hooks/tui.ts +209 -9
  306. package/src/hooks/uninstall-cli.ts +418 -0
  307. package/src/hooks/worker-server.ts +134 -15
  308. package/.next/standalone/.next/server/chunks/[externals]__14odj07._.js +0 -3
  309. package/.next/standalone/.next/server/chunks/[externals]__1s61mel._.js +0 -3
  310. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0id_xf7._.js +0 -3
  311. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +0 -3
  312. package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +0 -3
  313. package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +0 -3
  314. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +0 -3
  315. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +0 -3
  316. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1rhmvod._.js +0 -3
  317. package/.next/standalone/.next/server/chunks/ssr/[externals]__1_g_b3t._.js +0 -3
  318. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0114ewg._.js +0 -4
  319. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +0 -4
  320. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +0 -4
  321. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +0 -4
  322. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0nb0syg._.js +0 -3
  323. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +0 -4
  324. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +0 -4
  325. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +0 -3
  326. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +0 -3
  327. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +0 -4
  328. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1psjybo._.js +0 -3
  329. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +0 -4
  330. package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +0 -3
  331. package/.next/standalone/.next/server/chunks/ssr/node_modules_html-to-image_es_index_0oy_-36.js +0 -3
  332. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +0 -5
  333. package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +0 -5
  334. package/.next/standalone/.next/static/chunks/0h7auy7hzjyhw.js +0 -1
  335. package/.next/standalone/.next/static/chunks/0zbxssxh53n-3.js +0 -1
  336. package/.next/standalone/.next/static/chunks/2mazwb1qmur1p.js +0 -1
  337. package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +0 -2
  338. package/.next/standalone/.next/static/chunks/33u59vf_8xpd-.js +0 -1
  339. package/.next/standalone/.next/static/chunks/3i27c3hcriawq.css +0 -1
  340. package/.next/standalone/.next/static/chunks/3s7myk_co0gbh.js +0 -1
  341. package/.next/standalone/.next/static/chunks/40k1_v4os4cw6.js +0 -6
  342. package/.next/standalone/Cargo.lock +0 -428
  343. package/.next/standalone/Cargo.toml +0 -9
  344. package/.next/standalone/crates/PROTOCOL.md +0 -122
  345. package/.next/standalone/crates/failproofaid/Cargo.toml +0 -18
  346. package/.next/standalone/crates/failproofaid/src/lock.rs +0 -81
  347. package/.next/standalone/crates/failproofaid/src/main.rs +0 -83
  348. package/.next/standalone/crates/failproofaid/src/paths.rs +0 -172
  349. package/.next/standalone/crates/failproofaid/src/server.rs +0 -502
  350. package/.next/standalone/crates/failproofaid/src/worker.rs +0 -400
  351. package/.next/standalone/crates/failproofaid/tests/daemon_e2e.rs +0 -241
  352. package/.next/standalone/crates/fpai-ipc/Cargo.toml +0 -16
  353. package/.next/standalone/crates/fpai-ipc/src/envelope.rs +0 -175
  354. package/.next/standalone/crates/fpai-ipc/src/framing.rs +0 -177
  355. package/.next/standalone/crates/fpai-ipc/src/lib.rs +0 -10
  356. package/.next/standalone/crates/fpai-ipc/src/peer.rs +0 -80
  357. package/.next/standalone/docker-hook-sync/Dockerfile +0 -79
  358. package/.next/standalone/docker-hook-sync/entrypoint.sh +0 -109
  359. package/.next/standalone/integration-suite/Dockerfile +0 -47
  360. package/.next/standalone/integration-suite/README.md +0 -129
  361. package/.next/standalone/integration-suite/canary-policies.mjs +0 -45
  362. package/.next/standalone/integration-suite/capture-tokens.sh +0 -48
  363. package/.next/standalone/integration-suite/ci-entrypoint.sh +0 -179
  364. package/.next/standalone/integration-suite/inject-tokens.sh +0 -44
  365. package/.next/standalone/integration-suite/install-clis.sh +0 -136
  366. package/.next/standalone/integration-suite/probe-cli.sh +0 -248
  367. package/.next/standalone/integration-suite/report.js +0 -120
  368. package/.next/standalone/integration-suite/run.sh +0 -159
  369. package/.next/standalone/openclaw-plugin/index.js +0 -223
  370. package/.next/standalone/openclaw-plugin/openclaw.plugin.json +0 -6
  371. package/.next/standalone/openclaw-plugin/package.json +0 -12
  372. package/.next/standalone/osv-scanner.toml +0 -17
  373. package/.next/standalone/pi-extension/index.ts +0 -524
  374. package/.next/standalone/pi-extension/package.json +0 -12
  375. package/.next/standalone/postcss.config.mjs +0 -8
  376. package/.next/standalone/readme-arch-hq.gif +0 -0
  377. package/.next/standalone/rust-toolchain.toml +0 -4
  378. package/src/auth/cli.ts +0 -371
  379. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_buildManifest.js +0 -0
  380. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_clientMiddlewareManifest.js +0 -0
  381. /package/.next/standalone/.next/static/{NWAjs0tHFyzk97gRGG09r → VjEdIL6W5uBsvEzknXqV9}/_ssgManifest.js +0 -0
@@ -1,524 +0,0 @@
1
- /**
2
- * failproofai policy bridge for Pi (pi-coding-agent).
3
- *
4
- * This extension is loaded by Pi at startup and registered via
5
- * `pi install <abs-path-to-this-dir> [-l]` (or by hand-authoring an entry in
6
- * `<scope>/.pi/settings.json`). It subscribes to Pi's `tool_call`, `user_bash`,
7
- * `input`, and `session_start` events and forwards them to the failproofai
8
- * binary as `failproofai --hook <Event> --cli pi`. failproofai prints a
9
- * decision JSON to stdout; this shim parses it and translates into Pi's
10
- * `{ block: true, reason }` return shape so policy `deny` decisions cancel
11
- * tool execution.
12
- *
13
- * Marker comment for failproofai's installer detection (do not remove):
14
- * __failproofai_hook__: true
15
- *
16
- * Binary resolution. failproofai ships two entrypoints:
17
- * • dist/cli.mjs — bundled, node-compatible (production npm install)
18
- * • bin/failproofai.mjs — source, requires `bun` (dev / monorepo)
19
- *
20
- * dist/cli.mjs is preferred because spawning `node bin/failproofai.mjs`
21
- * fails with ERR_IMPORT_ATTRIBUTE_MISSING (the source `import package.json`
22
- * needs `with { type: "json" }` under node, which bun handles transparently
23
- * but the build:cli step transpiles away in dist/cli.mjs). When dist/cli.mjs
24
- * isn't present, fall back to running bin/failproofai.mjs with `bun`. Pi
25
- * spawns extensions with an undefined cwd contract, so paths are resolved
26
- * relative to this file via `import.meta.url`, NOT process.cwd().
27
- */
28
- import { spawnSync } from "node:child_process";
29
- import { resolve, dirname, join } from "node:path";
30
- import { fileURLToPath } from "node:url";
31
- import { existsSync, readdirSync, statSync } from "node:fs";
32
- import { homedir } from "node:os";
33
-
34
- const HERE = dirname(fileURLToPath(import.meta.url));
35
- const DIST_BIN = resolve(HERE, "..", "dist", "cli.mjs");
36
- const SRC_BIN = resolve(HERE, "..", "bin", "failproofai.mjs");
37
- // Prefer the bundled dist/cli.mjs (node-compatible); fall back to source +
38
- // bun for dev workflows where dist/ hasn't been built yet.
39
- function resolveSpawn(): { cmd: string; args: string[] } {
40
- if (process.env.FAILPROOFAI_BINARY_OVERRIDE) {
41
- return { cmd: "node", args: [process.env.FAILPROOFAI_BINARY_OVERRIDE] };
42
- }
43
- if (existsSync(DIST_BIN)) {
44
- return { cmd: "node", args: [DIST_BIN] };
45
- }
46
- return { cmd: "bun", args: [SRC_BIN] };
47
- }
48
-
49
- interface PolicyDecision {
50
- permission?: "allow" | "deny";
51
- reason?: string;
52
- }
53
-
54
- /**
55
- * Spawn `failproofai --hook <eventName> --cli pi`, write the JSON payload to
56
- * stdin, and parse the flat `{permission, reason}` JSON we expect failproofai
57
- * to print on stdout. Fail-open on any subprocess / parse error.
58
- */
59
- /** Optional stderr trace for debugging the shim. Enabled with
60
- * FAILPROOFAI_PI_DEBUG=1; silent otherwise. */
61
- function debug(msg: string): void {
62
- if (process.env.FAILPROOFAI_PI_DEBUG === "1") {
63
- process.stderr.write(`[failproofai-pi-shim] ${msg}\n`);
64
- }
65
- }
66
-
67
- function callPolicy(eventName: string, payload: unknown): { block: boolean; reason: string } {
68
- const { cmd, args } = resolveSpawn();
69
- debug(`callPolicy event=${eventName} cmd=${cmd}`);
70
- try {
71
- const result = spawnSync(
72
- cmd,
73
- [...args, "--hook", eventName, "--cli", "pi"],
74
- {
75
- input: JSON.stringify(payload),
76
- encoding: "utf8",
77
- timeout: 60_000,
78
- },
79
- );
80
- if (result.status !== 0) return { block: false, reason: "" };
81
- const stdout = (result.stdout || "").trim();
82
- if (!stdout) return { block: false, reason: "" };
83
- const parsed = JSON.parse(stdout) as PolicyDecision;
84
- if (parsed.permission === "deny") {
85
- debug(`DENY reason=${parsed.reason}`);
86
- return { block: true, reason: parsed.reason ?? "Blocked by failproofai" };
87
- }
88
- } catch (err) {
89
- debug(`EXCEPTION ${err instanceof Error ? err.message : String(err)}`);
90
- // Fail-open: never block tool execution because of an infra failure.
91
- }
92
- return { block: false, reason: "" };
93
- }
94
-
95
- interface PiToolCallEvent {
96
- type?: string;
97
- toolName?: string;
98
- toolCallId?: string;
99
- input?: Record<string, unknown>;
100
- cwd?: string;
101
- sessionId?: string;
102
- }
103
-
104
- /**
105
- * Pi emits tool names in lowercase (`bash`, `read`, `edit`, `write`, `glob`,
106
- * `grep`). failproofai's builtin policies match on Claude PascalCase
107
- * (`Bash`, `Read`, `Edit`, `Write`, `Glob`, `Grep`) via case-sensitive
108
- * `Array.includes` in policy-registry.ts. Map between the two so existing
109
- * tool-name match clauses fire on Pi sessions.
110
- *
111
- * Keys must stay in sync with PI_TOOL_MAP in src/hooks/types.ts (this shim is
112
- * loaded in-process by Pi and must be self-contained — no imports from the
113
- * failproofai package). Update both whenever Pi adds a tool ID we care about.
114
- *
115
- * Unknown tools (anything not in this map) pass through unchanged so custom
116
- * policies that match on raw Pi tool IDs still work.
117
- */
118
- const PI_TOOL_MAP: Record<string, string> = {
119
- bash: "Bash",
120
- read: "Read",
121
- write: "Write",
122
- edit: "Edit",
123
- glob: "Glob",
124
- grep: "Grep",
125
- };
126
-
127
- function canonicalizeToolName(piToolName: string | undefined): string | undefined {
128
- if (!piToolName) return undefined;
129
- return PI_TOOL_MAP[piToolName] ?? piToolName;
130
- }
131
-
132
- /**
133
- * Per-tool input-key translation. Pi's Read / Write / Edit tools deliver
134
- * `path` (not `file_path`); failproofai's `block-env-files` and
135
- * `block-secrets-write` builtins only read `file_path`, so without this map
136
- * they silently no-op on Pi. `block-read-outside-cwd` already has a `path`
137
- * fallback so it works either way. Pi's Edit tool nests `edits[{oldText,
138
- * newText}]` which doesn't translate flatly to Claude's `{old_string,
139
- * new_string}` — we only map the top-level `path`; the nested array stays
140
- * Pi-shape (no current builtin reads it).
141
- *
142
- * Keep in sync with PI_TOOL_INPUT_MAP in src/hooks/types.ts.
143
- */
144
- const PI_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
145
- Read: { path: "file_path" },
146
- Write: { path: "file_path" },
147
- Edit: { path: "file_path" },
148
- };
149
-
150
- function canonicalizeToolInput(
151
- canonicalToolName: string | undefined,
152
- args: Record<string, unknown> | undefined,
153
- ): Record<string, unknown> | undefined {
154
- if (!args || typeof args !== "object" || !canonicalToolName) return args;
155
- const map = PI_TOOL_INPUT_MAP[canonicalToolName];
156
- if (!map) return args;
157
- const out: Record<string, unknown> = {};
158
- for (const k of Object.keys(args)) out[map[k] ?? k] = args[k];
159
- return out;
160
- }
161
-
162
- /** Resolve the cwd for the policy payload. Pi events don't include cwd, so
163
- * fall back to the extension's process.cwd() — which is where Pi was
164
- * launched and where `.failproofai/` config lives. */
165
- function resolveCwd(eventCwd: string | undefined): string {
166
- return eventCwd ?? process.cwd();
167
- }
168
-
169
- /**
170
- * Pi (verified empirically against pi-coding-agent v0.71.1) does NOT
171
- * populate `event.sessionId` on any of its events — `session_start`,
172
- * `tool_call`, `user_bash`, `input`, `tool_result`, `agent_end`,
173
- * `session_shutdown` all leave it undefined. Without help the shim can't
174
- * tag activity records with a session id, so the dashboard renders
175
- * `Session ID: —` for every Pi row.
176
- *
177
- * What Pi DOES do: at session start it creates a JSONL transcript at
178
- * `~/.pi/agent/sessions/<encodedCwd>/<isoTimestamp>_<uuid>.jsonl` where
179
- * the filename encodes the sessionId. We discover ours by scanning the
180
- * encoded-cwd directory for the most-recently-modified matching file.
181
- *
182
- * Strategy: scan once and cache. Pi runs one session per process so the
183
- * cache is per-process and lives for the session's lifetime. If Pi ever
184
- * multiplexes, we'd need a keyed map.
185
- */
186
- const PI_FILE_RE = /^[\d-]+T[\d-]+Z_([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
187
-
188
- /** Encode a cwd into Pi's on-disk session-dir name. Pi strips the leading
189
- * `/` before replacing remaining slashes with `-`, e.g.
190
- * `/home/u/repo` → `--home-u-repo--`. */
191
- function piEncodeCwd(cwd: string): string {
192
- const inner = cwd.replace(/^\/+/, "").replace(/\//g, "-");
193
- return `--${inner}--`;
194
- }
195
-
196
- /** Process start boundary — files older than this aren't from the current
197
- * Pi session. Captured at module load so cold-start in a cwd with stale
198
- * transcripts doesn't pin a previous session's UUID. We allow a small
199
- * tolerance below `processStartMs` because mtime resolution and clock
200
- * skew can put a "current" file's mtime a few hundred ms before module
201
- * load on slow startup. */
202
- const PROCESS_START_MS = Date.now();
203
- const STALE_TOLERANCE_MS = 2_000;
204
-
205
- /** Find the newest `<ts>_<uuid>.jsonl` file under `~/.pi/agent/sessions/<encodedCwd>/`
206
- * whose mtime indicates it belongs to the CURRENT Pi process (≥ process
207
- * start, with a small tolerance). Files older than that are stale
208
- * transcripts from prior sessions in the same cwd — caching their UUID
209
- * would cross-attribute every event of the new session.
210
- * Returns undefined when the dir doesn't exist, has no matching file, or
211
- * every matching file is stale. */
212
- function discoverPiSessionId(cwd: string): string | undefined {
213
- const root = process.env.PI_SESSIONS_DIR || join(homedir(), ".pi", "agent", "sessions");
214
- const dir = join(root, piEncodeCwd(cwd));
215
- let entries: string[];
216
- try { entries = readdirSync(dir); } catch { return undefined; }
217
- const boundary = PROCESS_START_MS - STALE_TOLERANCE_MS;
218
- let best: { sessionId: string; mtime: number } | undefined;
219
- for (const name of entries) {
220
- const m = PI_FILE_RE.exec(name);
221
- if (!m) continue;
222
- let mtime: number;
223
- try { mtime = statSync(join(dir, name)).mtimeMs; } catch { continue; }
224
- if (mtime < boundary) continue;
225
- if (!best || mtime > best.mtime) best = { sessionId: m[1], mtime };
226
- }
227
- return best?.sessionId;
228
- }
229
-
230
- /** sessionId cache, keyed by cwd. Per-cwd so a multi-cwd Pi (extension running
231
- * across multiple workspace roots) can't cross-attribute. Cleared on
232
- * session_shutdown reasons `new`/`resume`/`fork` (Pi reuses the process). */
233
- const cachedSessionIdByCwd = new Map<string, string>();
234
-
235
- /** Pending Stop-policy deny reason from agent_end, keyed by sessionId.
236
- * Drained by before_agent_start on the next user turn in the same Pi
237
- * process. Cleared on every session_shutdown.
238
- *
239
- * Why this exists: Pi's agent_end has no Result type — the agent loop
240
- * has already exited when it fires, so a deny return cannot keep Pi
241
- * running the way Claude's exit-2-from-Stop does. The closest analog
242
- * is to capture the deny here and re-inject it as a MANDATORY ACTION
243
- * system-prompt addition on the NEXT before_agent_start, which fires
244
- * after the user submits a prompt but before the agent loop runs.
245
- * Best-effort: bounded by the Pi process lifetime — same bound Claude
246
- * has on exit-2-from-Stop (kill the agent and the gate is missed).
247
- *
248
- * Why per-session not per-cwd: a Pi process can host multiple sessions
249
- * via /resume and /fork; per-cwd would cross-attribute a stale block
250
- * from a prior session into a fresh one. */
251
- const pendingStopBlockBySession = new Map<string, string>();
252
- function resolveSessionId(eventSessionId: string | undefined, cwd: string): string | undefined {
253
- if (eventSessionId) {
254
- cachedSessionIdByCwd.set(cwd, eventSessionId);
255
- return eventSessionId;
256
- }
257
- const cached = cachedSessionIdByCwd.get(cwd);
258
- if (cached) return cached;
259
- // Pi v0.71.1 never sets sessionId — discover from disk.
260
- const discovered = discoverPiSessionId(cwd);
261
- if (discovered) cachedSessionIdByCwd.set(cwd, discovered);
262
- return discovered;
263
- }
264
- /** Clear the cached sessionId for a cwd. Called on session_shutdown reasons
265
- * that indicate a new session is starting in the same process (`new`,
266
- * `resume`, `fork`). Without this, the next session would inherit the prior
267
- * sessionId until disk discovery refreshed it. */
268
- function resetSessionIdCache(cwd: string): void {
269
- cachedSessionIdByCwd.delete(cwd);
270
- }
271
-
272
- interface PiUserBashEvent {
273
- type?: string;
274
- command?: string;
275
- cwd?: string;
276
- sessionId?: string;
277
- }
278
-
279
- interface PiInputEvent {
280
- type?: string;
281
- text?: string;
282
- source?: string;
283
- cwd?: string;
284
- sessionId?: string;
285
- }
286
-
287
- interface PiSessionStartEvent {
288
- type?: string;
289
- reason?: string;
290
- cwd?: string;
291
- sessionId?: string;
292
- }
293
-
294
- interface PiSessionShutdownEvent {
295
- type?: string;
296
- /** "quit" | "reload" | "new" | "resume" | "fork" per pi-coding-agent v0.72.1 */
297
- reason?: string;
298
- targetSessionFile?: string;
299
- cwd?: string;
300
- sessionId?: string;
301
- }
302
-
303
- interface PiToolResultEvent {
304
- type?: string;
305
- toolCallId?: string;
306
- toolName?: string;
307
- input?: Record<string, unknown>;
308
- /** TextContent | ImageContent — opaque to us; forwarded as-is. */
309
- content?: unknown[];
310
- isError?: boolean;
311
- cwd?: string;
312
- sessionId?: string;
313
- }
314
-
315
- interface PiAgentEndEvent {
316
- type?: string;
317
- /** AgentMessage[] — opaque; not forwarded (Stop policies don't need it). */
318
- messages?: unknown[];
319
- cwd?: string;
320
- sessionId?: string;
321
- }
322
-
323
- /** Pi v0.73.x before_agent_start event payload. Fires once per turn,
324
- * after the user submits a prompt but before the agent loop runs. */
325
- interface PiBeforeAgentStartEvent {
326
- type?: string;
327
- prompt?: string;
328
- /** The fully assembled system prompt for this turn — we append to it. */
329
- systemPrompt?: string;
330
- cwd?: string;
331
- sessionId?: string;
332
- }
333
-
334
- interface PiExtensionApi {
335
- on(event: string, handler: (event: unknown) => unknown): void;
336
- }
337
-
338
- export default function failproofaiBridge(pi: PiExtensionApi) {
339
- // tool_call → PreToolUse. Block tool execution when failproofai denies.
340
- pi.on("tool_call", (event: unknown): unknown => {
341
- const e = event as PiToolCallEvent;
342
- const canonicalTool = canonicalizeToolName(e.toolName);
343
- const decision = callPolicy("tool_call", {
344
- tool_name: canonicalTool,
345
- tool_input: canonicalizeToolInput(canonicalTool, e.input),
346
- session_id: resolveSessionId(e.sessionId, resolveCwd(e.cwd)),
347
- cwd: resolveCwd(e.cwd),
348
- hook_event_name: "PreToolUse",
349
- });
350
- // `ToolCallEventResult` is `{block?, reason?}` (extensions/types.d.ts:766).
351
- // agent-loop.ts branches on `beforeResult?.block`, so this is the shape that
352
- // stops the tool. Do NOT put the user_bash full-replacement shape here — it
353
- // has no `block` field, so the call would sail straight through.
354
- if (decision.block) return { block: true, reason: decision.reason };
355
- return undefined;
356
- });
357
-
358
- // user_bash → PreToolUse with synthesized toolName=Bash.
359
- pi.on("user_bash", (event: unknown): unknown => {
360
- const e = event as PiUserBashEvent;
361
- const decision = callPolicy("user_bash", {
362
- tool_name: "Bash",
363
- tool_input: { command: e.command },
364
- session_id: resolveSessionId(e.sessionId, resolveCwd(e.cwd)),
365
- cwd: resolveCwd(e.cwd),
366
- hook_event_name: "PreToolUse",
367
- });
368
- // `UserBashEventResult` is `{operations?, result?: BashResult}` — there is
369
- // no `block` field, so the `{block:true}` we used to return matched nothing
370
- // and the command ran anyway. The supported way to stop it is a FULL
371
- // REPLACEMENT result: the extension declares it handled execution, so Pi
372
- // uses this instead of running the command. Verified against the installed
373
- // pi-coding-agent d.ts (extensions/types.d.ts:772, core/bash-executor.d.ts:15).
374
- if (decision.block) {
375
- return {
376
- result: {
377
- output: decision.reason ?? "Blocked by failproofai",
378
- exitCode: 1,
379
- cancelled: false,
380
- truncated: false,
381
- },
382
- };
383
- }
384
- return undefined;
385
- });
386
-
387
- // input → UserPromptSubmit.
388
- //
389
- // `InputEventResult` is `{action:"continue"|"transform"|"handled"}`
390
- // (extensions/types.d.ts:629) — there is NO `block` field, so the
391
- // `{block:true}` we used to return matched neither branch and every prompt
392
- // was submitted regardless of the verdict. `{action:"handled"}` is the only
393
- // stop: it tells Pi an extension consumed the input, so nothing is sent to
394
- // the model.
395
- //
396
- // Known UX limitation: `handled` drops the prompt silently — Pi shows the
397
- // user nothing. We log the reason to stderr so it is at least recoverable
398
- // from the session output. Pi has no first-class channel for explaining a
399
- // refusal at this event; if one appears, prefer it over the silent drop.
400
- pi.on("input", (event: unknown): unknown => {
401
- const e = event as PiInputEvent;
402
- const decision = callPolicy("input", {
403
- prompt: e.text,
404
- session_id: resolveSessionId(e.sessionId, resolveCwd(e.cwd)),
405
- cwd: resolveCwd(e.cwd),
406
- hook_event_name: "UserPromptSubmit",
407
- });
408
- if (decision.block) {
409
- console.error(`[failproofai] prompt blocked: ${decision.reason ?? "blocked by policy"}`);
410
- return { action: "handled" };
411
- }
412
- return { action: "continue" };
413
- });
414
-
415
- // session_start → SessionStart. Observe-only; we still forward so the
416
- // activity feed records the session and any UserPromptSubmit policies that
417
- // need session_id continuity see the metadata.
418
- pi.on("session_start", (event: unknown): unknown => {
419
- const e = event as PiSessionStartEvent;
420
- callPolicy("session_start", {
421
- session_id: resolveSessionId(e.sessionId, resolveCwd(e.cwd)),
422
- cwd: resolveCwd(e.cwd),
423
- reason: e.reason,
424
- hook_event_name: "SessionStart",
425
- });
426
- return undefined;
427
- });
428
-
429
- // tool_result → PostToolUse. Observation-only on Pi: ToolResultEventResult
430
- // exposes {content, details, isError} for mutation but no `block`. We
431
- // forward to the failproofai binary so PostToolUse builtins (sanitize-jwt,
432
- // sanitize-api-keys, sanitize-connection-strings, sanitize-private-key-
433
- // content, sanitize-bearer-tokens) run and get their decisions logged to
434
- // the activity store + stderr — but Pi keeps the original tool result.
435
- pi.on("tool_result", (event: unknown): unknown => {
436
- const e = event as PiToolResultEvent;
437
- const canonicalTool = canonicalizeToolName(e.toolName);
438
- callPolicy("tool_result", {
439
- tool_name: canonicalTool,
440
- tool_input: canonicalizeToolInput(canonicalTool, e.input) ?? {},
441
- tool_response: { content: e.content, isError: e.isError },
442
- session_id: resolveSessionId(e.sessionId, resolveCwd(e.cwd)),
443
- cwd: resolveCwd(e.cwd),
444
- hook_event_name: "PostToolUse",
445
- });
446
- return undefined;
447
- });
448
-
449
- // agent_end → Stop. Pi cannot veto agent_end (the agent loop has already
450
- // exited when this fires — see the AgentEndEvent typedef in pi-coding-agent
451
- // which has NO Result type). Instead we capture any deny reason and stash
452
- // it keyed by sessionId for the next before_agent_start handler to drain.
453
- // The 5 require-*-before-stop builtins thus enforce by gating the NEXT
454
- // user turn's system prompt rather than by retrying the same loop. If the
455
- // user kills Pi between turns, the gate is missed — same bound Claude has.
456
- pi.on("agent_end", (event: unknown): unknown => {
457
- const e = event as PiAgentEndEvent;
458
- const cwd = resolveCwd(e.cwd);
459
- const sessionId = resolveSessionId(e.sessionId, cwd);
460
- const decision = callPolicy("agent_end", {
461
- session_id: sessionId,
462
- cwd,
463
- hook_event_name: "Stop",
464
- });
465
- if (decision.block && decision.reason && sessionId) {
466
- pendingStopBlockBySession.set(sessionId, decision.reason);
467
- debug(`agent_end deny stored for session=${sessionId}`);
468
- }
469
- return undefined;
470
- });
471
-
472
- // before_agent_start → drain any pending Stop-policy deny captured at
473
- // agent_end. This is Pi's only first-class channel to influence the next
474
- // turn before the LLM call: the result type accepts a `systemPrompt`
475
- // replacement (chained across extensions) and an optional injected
476
- // CustomMessage. We only return systemPrompt — sufficient for the LLM to
477
- // see the MANDATORY ACTION directive immediately, and avoids polluting the
478
- // visible conversation history with framework chrome. The reason text
479
- // already carries the policy-attributed MANDATORY ACTION wording from
480
- // policy-evaluator's Pi-Stop branch.
481
- pi.on("before_agent_start", (event: unknown): unknown => {
482
- const e = event as PiBeforeAgentStartEvent;
483
- const cwd = resolveCwd(e.cwd);
484
- const sessionId = resolveSessionId(e.sessionId, cwd);
485
- if (!sessionId) return undefined;
486
- const pending = pendingStopBlockBySession.get(sessionId);
487
- if (!pending) return undefined;
488
- pendingStopBlockBySession.delete(sessionId);
489
- debug(`before_agent_start drains stop-block for session=${sessionId}`);
490
- const base = e.systemPrompt ?? "";
491
- return { systemPrompt: `${base}\n\n${pending}` };
492
- });
493
-
494
- // session_shutdown → SessionEnd. Observation-only; emits a SessionEnd
495
- // record so per-session telemetry has a clean close. Reset the per-cwd
496
- // sessionId cache for shutdown reasons that mean "Pi is starting a new
497
- // session in the same process" — without the reset, the next session's
498
- // events would inherit the prior session's id until disk discovery
499
- // refreshed it.
500
- pi.on("session_shutdown", (event: unknown): unknown => {
501
- const e = event as PiSessionShutdownEvent;
502
- const cwd = resolveCwd(e.cwd);
503
- callPolicy("session_shutdown", {
504
- session_id: resolveSessionId(e.sessionId, cwd),
505
- cwd,
506
- reason: e.reason,
507
- hook_event_name: "SessionEnd",
508
- });
509
- // Capture sessionId BEFORE the cache reset so we delete the pending
510
- // entry under the just-ending session's id. After resetSessionIdCache,
511
- // a subsequent resolveSessionId would re-discover from disk and could
512
- // bind to a different (stale) file — wrong key for the cleanup below.
513
- const sessionId = resolveSessionId(e.sessionId, cwd);
514
- if (e.reason === "new" || e.reason === "resume" || e.reason === "fork") {
515
- resetSessionIdCache(cwd);
516
- }
517
- // Drop any pending Stop-policy deny for this session on every shutdown
518
- // reason — `quit` ends the session for good (don't leak the entry into
519
- // GC); `new`/`resume`/`fork` start a different session in the same
520
- // process and must not inherit the prior session's gate.
521
- if (sessionId) pendingStopBlockBySession.delete(sessionId);
522
- return undefined;
523
- });
524
- }
@@ -1,12 +0,0 @@
1
- {
2
- "name": "@failproofai/pi-extension",
3
- "version": "0.0.1",
4
- "description": "failproofai policy bridge for Pi (pi-coding-agent)",
5
- "type": "module",
6
- "main": "./index.ts",
7
- "private": true,
8
- "keywords": [
9
- "pi-extension",
10
- "failproofai"
11
- ]
12
- }
@@ -1,8 +0,0 @@
1
- /** @type {import('postcss-load-config').Config} */
2
- const config = {
3
- plugins: {
4
- '@tailwindcss/postcss': {},
5
- },
6
- };
7
-
8
- export default config;
Binary file
@@ -1,4 +0,0 @@
1
- [toolchain]
2
- channel = "1.97.1"
3
- components = ["rustfmt", "clippy"]
4
- profile = "minimal"