failproofai 0.0.13 → 0.0.14-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/standalone/.factory/hooks.json +112 -0
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js +3 -3
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/reminder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +2 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
- package/.next/standalone/.next/server/app/policies/page.js +1 -1
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +3 -2
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +5 -3
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0--lkk6._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0-219ec._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__08w4wmd._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0g6bbuw._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jllheg._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q-v9z2._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q0qzx1._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0rv7m0k._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +3 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__16le-kd._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__17g9wh7._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d9qen3._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1ffkmds._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1legmza._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qb590j._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1shcqgr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1xuedea._.js +3 -0
- package/.next/standalone/.next/server/chunks/{_1z062h5._.js → _1vslkoe._.js} +2 -2
- package/.next/standalone/.next/server/chunks/lib_factory-projects_ts_1eo_bk-._.js +3 -0
- package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +3 -0
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +24 -12
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00cz9as._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__030k0c6._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__042d3cd._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__05r_17v._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__07iom4f._.js → [root-of-the-server]__07qfsfa._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09q1168._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e2l3c1._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ge8e7w._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0h12me5._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hci7t3._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0hdsupo._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p84xee._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ynf7tx._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11rtg6s._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__14dd6h8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +12 -9
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1dky4g0._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__212nf49._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0_9_ytf._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_11_p9y8._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0ul5rf_._.js → _1_ozgif._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_0xkhw_v._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_antigravity-projects_ts_0_6zf11._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_devin-projects_ts_0a64qdy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_factory-projects_ts_1uyaahq._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_goose-projects_ts_0zkscri._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_13p7zob.js → node_modules_html-to-image_es_index_0g5r64e.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0-uvagv.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_03c7gi5.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_09p-8om.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0v-kfiu.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_0xrgzyz.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1806lsc.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1j6dd-e.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_next_dist_esm_build_templates_app-page_1sa65r-.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1ezd2jf._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/src_hooks_1tnuifj._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +10 -10
- package/.next/standalone/.next/static/chunks/{23c7v2svx90dp.js → 003uz088wbmz7.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0vc0eak148vo6.js → 0405htbxay9vd.js} +1 -1
- package/.next/standalone/.next/static/chunks/0iinhn4417nk1.js +1 -0
- package/.next/standalone/.next/static/chunks/1374x9bv_s_vg.js +6 -0
- package/.next/standalone/.next/static/chunks/{30ysv-_8jj052.js → 17sdztgbcc0fi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2cejn75gug3j8.js → 2m_tbl39fcedn.js} +1 -1
- package/.next/standalone/.next/static/chunks/{36wdtkgdf0zrd.js → 2o3ql0n5owqsw.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0wtagd8a5gwq-.js → 2ufuwhv03yvtb.js} +1 -1
- package/.next/standalone/.next/static/chunks/35-90m9py64d4.js +1 -0
- package/.next/standalone/.next/static/chunks/3r--yyjkp9_7b.css +2 -0
- package/.next/standalone/.next/static/chunks/43weu8f59tlix.js +1 -0
- package/.next/standalone/.next/static/chunks/{05apzuand0c22.js → 454dyizqik6t9.js} +2 -2
- package/.next/standalone/app/api/audit/run/route.ts +2 -0
- package/.next/standalone/app/audit/_components/empty-state.tsx +1 -1
- package/.next/standalone/app/globals.css +25 -1
- package/.next/standalone/app/policies/hooks-client.tsx +2 -4
- package/.next/standalone/app/project/[name]/page.tsx +30 -10
- package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +71 -21
- package/.next/standalone/assets/logos/antigravity.svg +1 -0
- package/.next/standalone/assets/logos/devin.svg +1 -0
- package/.next/standalone/assets/logos/factory-dark.png +0 -0
- package/.next/standalone/assets/logos/factory-light.png +0 -0
- package/.next/standalone/assets/logos/goose-dark.svg +1 -0
- package/.next/standalone/assets/logos/goose-light.svg +1 -0
- package/.next/standalone/assets/logos/openclaw.svg +22 -0
- package/.next/standalone/components/navbar.tsx +5 -11
- package/.next/standalone/components/reach-developers.tsx +1 -1
- package/.next/standalone/lib/antigravity-projects.ts +224 -0
- package/.next/standalone/lib/antigravity-sessions.ts +283 -0
- package/.next/standalone/lib/cli-registry.ts +26 -6
- package/.next/standalone/lib/devin-projects.ts +141 -0
- package/.next/standalone/lib/devin-sessions.ts +343 -0
- package/.next/standalone/lib/download-session.ts +56 -5
- package/.next/standalone/lib/factory-projects.ts +109 -0
- package/.next/standalone/lib/factory-sessions.ts +312 -0
- package/.next/standalone/lib/goose-projects.ts +148 -0
- package/.next/standalone/lib/goose-sessions.ts +296 -0
- package/.next/standalone/lib/openclaw-projects.ts +182 -0
- package/.next/standalone/lib/openclaw-sessions.ts +284 -0
- package/.next/standalone/lib/projects.ts +33 -9
- package/.next/standalone/lib/telemetry-sanitize.ts +43 -0
- package/.next/standalone/openclaw-plugin/index.js +223 -0
- package/.next/standalone/openclaw-plugin/openclaw.plugin.json +6 -0
- package/.next/standalone/openclaw-plugin/package.json +12 -0
- package/.next/standalone/package.json +2 -1
- package/.next/standalone/server.js +1 -1
- package/README.md +105 -57
- package/bin/failproofai.mjs +87 -29
- package/dist/cli.mjs +12803 -9809
- package/lib/antigravity-projects.ts +224 -0
- package/lib/antigravity-sessions.ts +283 -0
- package/lib/cli-registry.ts +26 -6
- package/lib/devin-projects.ts +141 -0
- package/lib/devin-sessions.ts +343 -0
- package/lib/download-session.ts +56 -5
- package/lib/factory-projects.ts +109 -0
- package/lib/factory-sessions.ts +312 -0
- package/lib/goose-projects.ts +148 -0
- package/lib/goose-sessions.ts +296 -0
- package/lib/openclaw-projects.ts +182 -0
- package/lib/openclaw-sessions.ts +284 -0
- package/lib/projects.ts +33 -9
- package/lib/telemetry-sanitize.ts +43 -0
- package/openclaw-plugin/index.js +223 -0
- package/openclaw-plugin/openclaw.plugin.json +6 -0
- package/openclaw-plugin/package.json +12 -0
- package/package.json +2 -1
- package/scripts/launch.ts +4 -8
- package/scripts/postinstall.mjs +3 -4
- package/scripts/sync-agent-cli-harnesses-prompt.md +7 -10
- package/scripts/translate-docs/cli.ts +73 -52
- package/scripts/translate-docs/config.ts +57 -13
- package/scripts/translate-docs/mdx-translator.ts +51 -31
- package/scripts/translate-docs/mintlify-nav.ts +91 -10
- package/scripts/translate-docs/types.ts +3 -0
- package/src/audit/cli-adapters/antigravity.ts +87 -0
- package/src/audit/cli-adapters/devin.ts +53 -0
- package/src/audit/cli-adapters/factory.ts +75 -0
- package/src/audit/cli-adapters/goose.ts +53 -0
- package/src/audit/cli-adapters/index.ts +30 -6
- package/src/audit/cli-adapters/openclaw.ts +56 -0
- package/src/audit/cli.ts +44 -1
- package/src/audit/report.ts +1 -1
- package/src/audit/types.ts +1 -1
- package/src/hooks/builtin-policies.ts +5 -5
- package/src/hooks/configure-wizard.ts +356 -0
- package/src/hooks/handler.ts +283 -218
- package/src/hooks/hook-telemetry.ts +43 -3
- package/src/hooks/install-prompt.ts +92 -173
- package/src/hooks/integrations.ts +739 -138
- package/src/hooks/manager.ts +46 -2
- package/src/hooks/policy-evaluator.ts +301 -121
- package/src/hooks/policy-presets.ts +71 -0
- package/src/hooks/resolve-cwd.ts +1 -1
- package/src/hooks/resolve-permission-mode.ts +1 -5
- package/src/hooks/resolve-transcript-path.ts +25 -7
- package/src/hooks/tool-name-canonicalize.ts +36 -3
- package/src/hooks/tui.ts +578 -0
- package/src/hooks/types.ts +447 -109
- package/.next/standalone/.gemini/settings.json +0 -147
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cag8qd._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0cefjd9._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ekj92q._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__12v-lma._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__136y39g._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__13h8pzr._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1hgv_75._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04bqvos._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0dqgs96._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0q5rfxg._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qukut7._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__108slqn._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ql-mch._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_11v0g3z._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/lib_gemini-projects_ts_1c7bgx-._.js +0 -3
- package/.next/standalone/.next/static/chunks/0fa7j157kg9_d.js +0 -1
- package/.next/standalone/.next/static/chunks/0nrah-qv6smeg.js +0 -6
- package/.next/standalone/.next/static/chunks/1c8i78p7t1i-5.js +0 -1
- package/.next/standalone/.next/static/chunks/25qr0e6ez0ei0.js +0 -1
- package/.next/standalone/.next/static/chunks/25s52un3k_wht.css +0 -2
- package/.next/standalone/assets/logos/gemini-dark.svg +0 -13
- package/.next/standalone/assets/logos/gemini-light.svg +0 -13
- package/.next/standalone/lib/gemini-projects.ts +0 -243
- package/.next/standalone/lib/gemini-sessions.ts +0 -365
- package/lib/gemini-projects.ts +0 -243
- package/lib/gemini-sessions.ts +0 -365
- package/src/audit/cli-adapters/gemini.ts +0 -51
- package/src/hooks/first-run-nudge.ts +0 -146
- /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → MNJWFb2jLRrxRKGFNK6Hy}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → MNJWFb2jLRrxRKGFNK6Hy}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{kmzdjTLVs6LqsfyOaUf69 → MNJWFb2jLRrxRKGFNK6Hy}/_ssgManifest.js +0 -0
package/src/hooks/types.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Constants and interfaces for agent CLI hooks integrations (Claude Code, OpenAI Codex, GitHub Copilot, Cursor Agent, OpenCode, Pi,
|
|
2
|
+
* Constants and interfaces for agent CLI hooks integrations (Claude Code, OpenAI Codex, GitHub Copilot, Cursor Agent, OpenCode, Pi, …).
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export const HOOK_SCOPES = ["user", "project", "local"] as const;
|
|
6
6
|
export type HookScope = (typeof HOOK_SCOPES)[number];
|
|
7
7
|
|
|
8
|
-
export const INTEGRATION_TYPES = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "
|
|
8
|
+
export const INTEGRATION_TYPES = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "hermes", "openclaw", "factory", "devin", "antigravity", "goose"] as const;
|
|
9
9
|
export type IntegrationType = (typeof INTEGRATION_TYPES)[number];
|
|
10
10
|
|
|
11
11
|
export const CODEX_HOOK_SCOPES = ["user", "project"] as const;
|
|
@@ -237,6 +237,24 @@ export const COPILOT_TOOL_MAP: Record<string, string> = {
|
|
|
237
237
|
web_fetch: "WebFetch",
|
|
238
238
|
};
|
|
239
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Copilot CLI tool-input key canonicalization, keyed by CANONICAL tool name.
|
|
242
|
+
*
|
|
243
|
+
* Verified live against Copilot CLI 1.0.71: the snake_case hook events
|
|
244
|
+
* (PreToolUse/PostToolUse) deliver `tool_name` already canonical (`Bash`,
|
|
245
|
+
* `Read`, `Write`, `Edit`, `Grep`) but the file tools' input keys are
|
|
246
|
+
* Copilot's own — `path` instead of `file_path`, Write's content as
|
|
247
|
+
* `file_text`, Edit's strings as `old_str`/`new_str`. Without this map,
|
|
248
|
+
* path/content builtins (block-env-files, block-secrets-write) silently
|
|
249
|
+
* allowed Copilot file access (a live `.env` read was observed passing).
|
|
250
|
+
* Bash's `command` and Grep's `pattern` are already canonical.
|
|
251
|
+
*/
|
|
252
|
+
export const COPILOT_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
|
|
253
|
+
Read: { path: "file_path" },
|
|
254
|
+
Write: { path: "file_path", file_text: "content" },
|
|
255
|
+
Edit: { path: "file_path", old_str: "old_string", new_str: "new_string" },
|
|
256
|
+
};
|
|
257
|
+
|
|
240
258
|
// ── Cursor Agent CLI ───────────────────────────────────────────────────────
|
|
241
259
|
//
|
|
242
260
|
// Cursor delivers events under camelCase keys (`preToolUse`, `postToolUse`,
|
|
@@ -510,115 +528,435 @@ export const PI_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
|
|
|
510
528
|
Edit: { path: "file_path" },
|
|
511
529
|
};
|
|
512
530
|
|
|
513
|
-
// ──
|
|
514
|
-
//
|
|
515
|
-
// Gemini CLI's hook contract is the closest thing to a Claude Code clone we've
|
|
516
|
-
// seen: same `{matcher, hooks: [{type, command, timeout}]}` settings shape,
|
|
517
|
-
// PascalCase event names, snake_case stdin payload field names (session_id,
|
|
518
|
-
// tool_name, tool_input, hook_event_name, cwd, transcript_path), subprocess
|
|
519
|
-
// execution model, and a `$CLAUDE_PROJECT_DIR` env-var alias on top of its own
|
|
520
|
-
// `$GEMINI_PROJECT_DIR` for back-compat. The integration is modeled on
|
|
521
|
-
// claudeCode in integrations.ts; only three translation layers differ:
|
|
522
|
-
//
|
|
523
|
-
// 1. Event names — Gemini uses BeforeTool/AfterTool/BeforeAgent/AfterAgent/
|
|
524
|
-
// PreCompress/Notification/SessionStart/SessionEnd/BeforeModel/AfterModel/
|
|
525
|
-
// BeforeToolSelection. We install all 11 events but only 8 have a Claude
|
|
526
|
-
// canonical equivalent; the other 3 (BeforeModel/AfterModel/
|
|
527
|
-
// BeforeToolSelection) pass through unchanged (no policy matches today,
|
|
528
|
-
// but the binary still records activity).
|
|
529
|
-
//
|
|
530
|
-
// 2. Tool names — Gemini's tools are snake_case (run_shell_command, read_file,
|
|
531
|
-
// write_file, replace, glob, grep_search, list_directory, web_fetch,
|
|
532
|
-
// google_web_search, write_todos, save_memory, read_many_files, ask_user).
|
|
533
|
-
// The handler canonicalizes via GEMINI_TOOL_MAP (run_shell_command → Bash,
|
|
534
|
-
// read_file → Read, etc.) so existing builtin policies fire unchanged.
|
|
535
|
-
// Unknown tools (extensions, MCP `mcp_*` names) pass through.
|
|
536
|
-
//
|
|
537
|
-
// 3. Response shape — Gemini emits flat `{decision: "deny", reason}` for
|
|
538
|
-
// blocks (NOT Claude's `{hookSpecificOutput: {permissionDecision: "deny",
|
|
539
|
-
// permissionDecisionReason}}`), and `{hookSpecificOutput: {hookEventName,
|
|
540
|
-
// additionalContext}}` for context injection on BeforeAgent / AfterTool /
|
|
541
|
-
// SessionStart only. policy-evaluator.ts handles this via a `cli ===
|
|
542
|
-
// "gemini"` branch.
|
|
531
|
+
// ── OpenClaw (openclaw gateway) ─────────────────────────────────────────────
|
|
543
532
|
//
|
|
544
|
-
//
|
|
545
|
-
//
|
|
546
|
-
//
|
|
547
|
-
//
|
|
548
|
-
//
|
|
549
|
-
//
|
|
550
|
-
//
|
|
551
|
-
//
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
//
|
|
555
|
-
//
|
|
556
|
-
//
|
|
557
|
-
//
|
|
558
|
-
//
|
|
559
|
-
//
|
|
560
|
-
//
|
|
561
|
-
//
|
|
562
|
-
//
|
|
563
|
-
//
|
|
564
|
-
//
|
|
565
|
-
//
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
export
|
|
569
|
-
|
|
570
|
-
|
|
533
|
+
// OpenClaw is a self-hosted assistant gateway (23+ chat channels). Like Hermes
|
|
534
|
+
// it is a dual-pillar integration (live hooks + audit) and USER-scope only
|
|
535
|
+
// (`~/.openclaw/openclaw.json`; workspace plugins are disabled by default).
|
|
536
|
+
//
|
|
537
|
+
// Enforcement is via OpenClaw's IN-PROCESS PLUGIN hooks (its file-based
|
|
538
|
+
// "internal hooks" are observation-only and cannot block) — so failproofai
|
|
539
|
+
// ships a plugin (`openclaw-plugin/`) that async-spawns the binary and maps a
|
|
540
|
+
// flat `{permission, reason}` verdict back to each hook's native return shape.
|
|
541
|
+
// The shim forwards a Claude-shaped stdin (params→tool_input, toolName→
|
|
542
|
+
// tool_name, transcriptPath→transcript_path, stopHookActive→stop_hook_active),
|
|
543
|
+
// so the handler + builtins work unchanged; canonicalization stays binary-side
|
|
544
|
+
// via the maps below (no inline maps in the shim, unlike OpenCode/Pi).
|
|
545
|
+
//
|
|
546
|
+
// Per-hook capability (verified live against openclaw v2026.7.1):
|
|
547
|
+
// before_tool_call → PreToolUse ✅ deny ({block:true, blockReason})
|
|
548
|
+
// after_tool_call → PostToolUse observation
|
|
549
|
+
// before_agent_run → UserPromptSubmit ✅ deny ({outcome:"block", reason})
|
|
550
|
+
// before_agent_finalize → Stop ✅ revise ({action:"revise", reason});
|
|
551
|
+
// carries transcriptPath + stopHookActive (≈ Claude Stop)
|
|
552
|
+
// session_start/end → SessionStart/End observation
|
|
553
|
+
// subagent_ended → SubagentStop observation only (cannot veto)
|
|
554
|
+
// before_compaction → PreCompact observation
|
|
555
|
+
// Omitted: agent_end (would double-fire Stop); message_sending (outbound-msg
|
|
556
|
+
// cancel gate — OpenClaw-only capability, deferred).
|
|
557
|
+
export const OPENCLAW_HOOK_SCOPES = ["user"] as const;
|
|
558
|
+
export type OpenClawHookScope = (typeof OPENCLAW_HOOK_SCOPES)[number];
|
|
559
|
+
|
|
560
|
+
export const OPENCLAW_HOOK_EVENT_TYPES = [
|
|
561
|
+
"before_tool_call",
|
|
562
|
+
"after_tool_call",
|
|
563
|
+
"before_agent_run",
|
|
564
|
+
"before_agent_finalize",
|
|
565
|
+
"session_start",
|
|
566
|
+
"session_end",
|
|
567
|
+
"subagent_ended",
|
|
568
|
+
"before_compaction",
|
|
569
|
+
] as const;
|
|
570
|
+
export type OpenClawHookEventType = (typeof OPENCLAW_HOOK_EVENT_TYPES)[number];
|
|
571
|
+
|
|
572
|
+
export const OPENCLAW_EVENT_MAP: Record<OpenClawHookEventType, HookEventType> = {
|
|
573
|
+
before_tool_call: "PreToolUse",
|
|
574
|
+
after_tool_call: "PostToolUse",
|
|
575
|
+
before_agent_run: "UserPromptSubmit",
|
|
576
|
+
before_agent_finalize: "Stop",
|
|
577
|
+
session_start: "SessionStart",
|
|
578
|
+
session_end: "SessionEnd",
|
|
579
|
+
subagent_ended: "SubagentStop",
|
|
580
|
+
before_compaction: "PreCompact",
|
|
581
|
+
};
|
|
582
|
+
|
|
583
|
+
// OpenClaw native tool ids (verified against source src/agents/tool-catalog.ts
|
|
584
|
+
// and a live before_tool_call payload: tool `exec`, params `{command}`). Names
|
|
585
|
+
// with a Claude canonical are mapped so builtin policies fire; OpenClaw-specific
|
|
586
|
+
// tools (process, apply_patch, memory_*, sessions_*, browser, canvas, …) pass
|
|
587
|
+
// through unchanged so they still appear in the audit, just unmatched.
|
|
588
|
+
export const OPENCLAW_TOOL_MAP: Record<string, string> = {
|
|
589
|
+
exec: "Bash",
|
|
590
|
+
read: "Read",
|
|
591
|
+
write: "Write",
|
|
592
|
+
edit: "Edit",
|
|
593
|
+
grep: "Grep",
|
|
594
|
+
glob: "Glob",
|
|
595
|
+
web_search: "WebSearch",
|
|
596
|
+
web_fetch: "WebFetch",
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
// OpenClaw tool-INPUT key canonicalization, keyed by the *canonical* tool name
|
|
600
|
+
// (the handler canonicalizes the name before calling canonicalizeToolInput).
|
|
601
|
+
// `exec` already delivers `command` (matches Bash builtins), so no entry; the
|
|
602
|
+
// file tools deliver the path as `path`, which Claude builtins read as
|
|
603
|
+
// `file_path`. Mirrors HERMES_TOOL_INPUT_MAP / PI_TOOL_INPUT_MAP.
|
|
604
|
+
export const OPENCLAW_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
|
|
605
|
+
Read: { path: "file_path" },
|
|
606
|
+
Write: { path: "file_path" },
|
|
607
|
+
Edit: { path: "file_path" },
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
// ── Factory Droid (droid) ───────────────────────────────────────────────────
|
|
611
|
+
//
|
|
612
|
+
// Factory's droid CLI ships a Claude-compatible external-command hook system,
|
|
613
|
+
// but with two schema quirks verified LIVE against droid v0.171.0:
|
|
614
|
+
//
|
|
615
|
+
// 1. **Event names live at the TOP LEVEL of hooks.json — there is NO `"hooks"`
|
|
616
|
+
// wrapper.** The published docs are wrong; droid rejects a `{"hooks":{…}}`
|
|
617
|
+
// wrapper with `WARN Ignoring unknown hook event keys keys:["hooks"]`. The
|
|
618
|
+
// correct shape is:
|
|
619
|
+
// { "PreToolUse": [ { "matcher": "*", "hooks": [ { … } ] } ],
|
|
620
|
+
// "Stop": [ { "hooks": [ { … } ] } ] }
|
|
621
|
+
// Tool events (PreToolUse / PostToolUse) MUST carry `"matcher": "*"`
|
|
622
|
+
// (matches all tools); non-tool events omit the matcher.
|
|
623
|
+
//
|
|
624
|
+
// 2. **Deny is driven by EXIT CODE 2 + stderr, NOT a JSON decision.** droid
|
|
625
|
+
// ignores a `{decision:…}` object on tool events and blocks purely on
|
|
626
|
+
// exit code 2 (verified live: `Hook returned exit code 2, throwing
|
|
627
|
+
// ToolExecutionControlError`). The one exception is the `Stop` event,
|
|
628
|
+
// where droid does NOT support exit-2 force-retry — there we emit
|
|
629
|
+
// `{decision:"block", reason}` JSON on stdout at exit 0 (docs: "if
|
|
630
|
+
// decision is block, Droid does not stop"). Both branches live in
|
|
631
|
+
// policy-evaluator.ts's `cli === "factory"` handling.
|
|
632
|
+
//
|
|
633
|
+
// Event names are already PascalCase (matching Claude's canonical set), so
|
|
634
|
+
// there is NO FACTORY_EVENT_MAP and NO handler.ts canonicalization branch — the
|
|
635
|
+
// binary sees the events verbatim. The stdin payload is Claude snake_case
|
|
636
|
+
// (`session_id`, `transcript_path`, `cwd`, `permission_mode`, `hook_event_name`,
|
|
637
|
+
// `tool_name`, `tool_input:{command,…}`), so no payload normalization is needed
|
|
638
|
+
// either.
|
|
639
|
+
//
|
|
640
|
+
// Settings paths (verified against droid v0.171.0):
|
|
641
|
+
// user → ~/.factory/hooks.json
|
|
642
|
+
// project → <cwd>/.factory/hooks.json
|
|
643
|
+
//
|
|
644
|
+
// Audit pillar: sessions at ~/.factory/sessions/<encoded-cwd>/<sessionId>.jsonl
|
|
645
|
+
// (Claude-style encoded-cwd folders), one JSONL per session alongside a
|
|
646
|
+
// `<sessionId>.settings.json` sibling we ignore. See lib/factory-sessions.ts.
|
|
647
|
+
|
|
648
|
+
export const FACTORY_HOOK_SCOPES = ["user", "project"] as const;
|
|
649
|
+
export type FactoryHookScope = (typeof FACTORY_HOOK_SCOPES)[number];
|
|
650
|
+
|
|
651
|
+
export const FACTORY_HOOK_EVENT_TYPES = [
|
|
571
652
|
"SessionStart",
|
|
572
|
-
"
|
|
573
|
-
"
|
|
574
|
-
"
|
|
575
|
-
"BeforeModel",
|
|
576
|
-
"AfterModel",
|
|
577
|
-
"BeforeToolSelection",
|
|
578
|
-
"BeforeTool",
|
|
579
|
-
"AfterTool",
|
|
580
|
-
"PreCompress",
|
|
653
|
+
"UserPromptSubmit",
|
|
654
|
+
"PreToolUse",
|
|
655
|
+
"PostToolUse",
|
|
581
656
|
"Notification",
|
|
657
|
+
"Stop",
|
|
658
|
+
"SubagentStop",
|
|
659
|
+
"PreCompact",
|
|
660
|
+
"SessionEnd",
|
|
582
661
|
] as const;
|
|
583
|
-
export type
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
662
|
+
export type FactoryHookEventType = (typeof FACTORY_HOOK_EVENT_TYPES)[number];
|
|
663
|
+
|
|
664
|
+
/**
|
|
665
|
+
* Factory droid's tool names → Claude PascalCase canonical names so existing
|
|
666
|
+
* builtin policies (which match `toolName === "Bash"`, etc.) fire unchanged.
|
|
667
|
+
* Verified against droid v0.171.0: shell runs as `Execute`, file writes as
|
|
668
|
+
* `Create`, URL fetches as `FetchUrl`. `tool_input.command` is already the
|
|
669
|
+
* canonical Bash key, so there is NO FACTORY_TOOL_INPUT_MAP. Unknown tools
|
|
670
|
+
* (MCP, extensions) pass through unchanged via the `?? raw` fallback.
|
|
671
|
+
*/
|
|
672
|
+
export const FACTORY_TOOL_MAP: Record<string, string> = {
|
|
673
|
+
Execute: "Bash",
|
|
674
|
+
Read: "Read",
|
|
675
|
+
Edit: "Edit",
|
|
676
|
+
Create: "Write",
|
|
677
|
+
Grep: "Grep",
|
|
678
|
+
Glob: "Glob",
|
|
679
|
+
LS: "LS",
|
|
680
|
+
FetchUrl: "WebFetch",
|
|
681
|
+
WebSearch: "WebSearch",
|
|
682
|
+
TodoWrite: "TodoWrite",
|
|
683
|
+
Task: "Task",
|
|
602
684
|
};
|
|
603
685
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
686
|
+
// ── Devin CLI (devin) ───────────────────────────────────────────────────────
|
|
687
|
+
//
|
|
688
|
+
// Devin's CLI (Cognition) is a **pure Claude-clone** external-command hook
|
|
689
|
+
// system — verified LIVE against devin v3000.1.27. Unlike Factory, it uses the
|
|
690
|
+
// standard Claude `"hooks"`-wrapper schema (its config.json also holds
|
|
691
|
+
// `org_id`, `theme_mode`, etc., so writes are merge-preserving via
|
|
692
|
+
// readJsonFile/writeJsonFile). No quirks:
|
|
693
|
+
//
|
|
694
|
+
// • Config lives under a `"hooks"` key exactly like Claude's settings.json:
|
|
695
|
+
// user → ~/.config/devin/config.json (the `"hooks"` key)
|
|
696
|
+
// project → <cwd>/.devin/config.json (the `"hooks"` key)
|
|
697
|
+
// • Event names are already PascalCase (matching Claude's canonical set), so
|
|
698
|
+
// there is NO DEVIN_EVENT_MAP and NO handler.ts canonicalization branch.
|
|
699
|
+
// • The stdin payload is pure Claude snake_case (no normalization needed):
|
|
700
|
+
// PreToolUse → {hook_event_name, tool_name:"exec", tool_input:{command}, tool_use_id}
|
|
701
|
+
// PostToolUse → adds tool_response:{success, output, error}
|
|
702
|
+
// Stop → {stop_hook_active}
|
|
703
|
+
// • Deny contract = `{"decision":"block","reason"}` JSON on stdout at exit 0
|
|
704
|
+
// (VERIFIED live — it blocked and overrode `--permission-mode dangerous`).
|
|
705
|
+
// Both non-Stop and Stop use the same `{decision:"block"}` shape (Stop's
|
|
706
|
+
// reason carries the MANDATORY-ACTION force-retry wording). Devin is
|
|
707
|
+
// Claude-compatible, so instruct on context-injection events emits
|
|
708
|
+
// `{hookSpecificOutput:{hookEventName, additionalContext}}`. See
|
|
709
|
+
// policy-evaluator.ts's `cli === "devin"` branch.
|
|
710
|
+
//
|
|
711
|
+
// Audit pillar: sessions live in SQLite at
|
|
712
|
+
// ~/.local/share/devin/cli/sessions.db (tables `sessions` — one row per
|
|
713
|
+
// session WITH a `working_directory` — and `message_nodes`, whose
|
|
714
|
+
// `chat_message` column is OpenAI-style JSON `{role, content, tool_calls?,
|
|
715
|
+
// tool_call_id?}`). See lib/devin-sessions.ts. `DEVIN_HOME` overrides the home
|
|
716
|
+
// dir for tests.
|
|
717
|
+
|
|
718
|
+
export const DEVIN_HOOK_SCOPES = ["user", "project"] as const;
|
|
719
|
+
export type DevinHookScope = (typeof DEVIN_HOOK_SCOPES)[number];
|
|
720
|
+
|
|
721
|
+
export const DEVIN_HOOK_EVENT_TYPES = [
|
|
722
|
+
"SessionStart",
|
|
723
|
+
"UserPromptSubmit",
|
|
724
|
+
"PreToolUse",
|
|
725
|
+
"PostToolUse",
|
|
726
|
+
"PermissionRequest",
|
|
727
|
+
"Stop",
|
|
728
|
+
"SessionEnd",
|
|
729
|
+
] as const;
|
|
730
|
+
export type DevinHookEventType = (typeof DEVIN_HOOK_EVENT_TYPES)[number];
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* Devin's tool names → Claude PascalCase canonical names so existing builtin
|
|
734
|
+
* policies (which match `toolName === "Bash"`, etc.) fire unchanged. Verified
|
|
735
|
+
* live against devin v3000.1.27: the shell tool runs as `exec` and its
|
|
736
|
+
* `tool_input.command` is already the canonical Bash key, so there is NO
|
|
737
|
+
* DEVIN_TOOL_INPUT_MAP. All other Devin tool names pass through unchanged via
|
|
738
|
+
* the `?? raw` fallback.
|
|
739
|
+
*/
|
|
740
|
+
export const DEVIN_TOOL_MAP: Record<string, string> = {
|
|
741
|
+
exec: "Bash",
|
|
742
|
+
};
|
|
743
|
+
|
|
744
|
+
// ── Antigravity CLI (antigravity) ────────────────────────────────────────────
|
|
745
|
+
//
|
|
746
|
+
// Antigravity's `agy` CLI has its OWN hook contract — it is NOT a Claude-clone.
|
|
747
|
+
// Verified LIVE against agy v1.1.2 (shipped docs at
|
|
748
|
+
// ~/.gemini/antigravity-cli/builtin/skills/agy-customizations/docs/hooks.md):
|
|
749
|
+
//
|
|
750
|
+
// 1. **hooks.json is a NAMED-hook schema.** Each top-level key is a hook
|
|
751
|
+
// *name* ("failproofai"), whose value is an event→handlers map. Tool events
|
|
752
|
+
// (PreToolUse / PostToolUse) use a `{matcher, hooks:[…]}` wrapper;
|
|
753
|
+
// non-tool events (PreInvocation / Stop) are FLAT arrays of handler
|
|
754
|
+
// objects:
|
|
755
|
+
// { "failproofai": {
|
|
756
|
+
// "PreToolUse": [ { "matcher":"*", "hooks":[ {type,command,timeout} ] } ],
|
|
757
|
+
// "PreInvocation": [ { type, command, timeout } ],
|
|
758
|
+
// "Stop": [ { type, command, timeout } ] } }
|
|
759
|
+
// Multiple named hooks merge; `"enabled": false` disables a named hook.
|
|
760
|
+
//
|
|
761
|
+
// 2. **camelCase (protojson) stdin payload.** Antigravity pipes camelCase
|
|
762
|
+
// fields (`toolCall:{name,args}`, `conversationId`, `workspacePaths`,
|
|
763
|
+
// `transcriptPath`, `stepIdx`, `modelName`) — handler.ts normalizes these
|
|
764
|
+
// to canonical snake_case (`tool_name`, `tool_input`, `session_id`, `cwd`,
|
|
765
|
+
// `transcript_path`) right after JSON.parse. Tool `args` are PascalCase
|
|
766
|
+
// (`CommandLine`, `Cwd`) — canonicalized via ANTIGRAVITY_TOOL_INPUT_MAP.
|
|
767
|
+
//
|
|
768
|
+
// 3. **Antigravity's OWN response shapes** (policy-evaluator.ts
|
|
769
|
+
// `cli === "antigravity"` branch):
|
|
770
|
+
// • Deny (tool events) → exit 0, `{decision:"deny", reason}` on stdout.
|
|
771
|
+
// • Deny on Stop → exit 0, `{decision:"continue", reason}` —
|
|
772
|
+
// "continue" re-enters the loop (how require-*-before-stop enforces).
|
|
773
|
+
// • Instruct on UserPromptSubmit (canonical for PreInvocation) → exit 0,
|
|
774
|
+
// `{injectSteps:[{ephemeralMessage:"Instruction from failproofai: …"}]}`.
|
|
775
|
+
// • Instruct on Stop → `{decision:"continue", reason}`.
|
|
776
|
+
// • Other instruct events → stderr note only (degrade like Hermes).
|
|
777
|
+
//
|
|
778
|
+
// 4. **ANTIGRAVITY_EVENT_MAP** maps the `--hook` arg to a canonical event:
|
|
779
|
+
// PreToolUse→PreToolUse, PostToolUse→PostToolUse,
|
|
780
|
+
// PreInvocation→UserPromptSubmit, Stop→Stop.
|
|
781
|
+
//
|
|
782
|
+
// Settings paths (verified against agy v1.1.2):
|
|
783
|
+
// user → ~/.gemini/config/hooks.json
|
|
784
|
+
// project → <cwd>/.agents/hooks.json
|
|
785
|
+
//
|
|
786
|
+
// Audit pillar: plain JSONL transcripts at
|
|
787
|
+
// ~/.gemini/antigravity-cli/brain/<conversationId>/.system_generated/logs/
|
|
788
|
+
// transcript_full.jsonl (one step per line); the conversation index lives in
|
|
789
|
+
// SQLite at ~/.gemini/antigravity-cli/conversation_summaries.db. See
|
|
790
|
+
// lib/antigravity-sessions.ts + lib/antigravity-projects.ts. `ANTIGRAVITY_HOME`
|
|
791
|
+
// overrides the home dir for tests.
|
|
792
|
+
|
|
793
|
+
export const ANTIGRAVITY_HOOK_SCOPES = ["user", "project"] as const;
|
|
794
|
+
export type AntigravityHookScope = (typeof ANTIGRAVITY_HOOK_SCOPES)[number];
|
|
795
|
+
|
|
796
|
+
/** The events failproofai installs into Antigravity's hooks.json. Tool events
|
|
797
|
+
* use the `{matcher, hooks}` wrapper; PreInvocation / Stop are flat arrays. */
|
|
798
|
+
export const ANTIGRAVITY_HOOK_EVENT_TYPES = [
|
|
799
|
+
"PreToolUse",
|
|
800
|
+
"PostToolUse",
|
|
801
|
+
"PreInvocation",
|
|
802
|
+
"Stop",
|
|
803
|
+
] as const;
|
|
804
|
+
export type AntigravityHookEventType = (typeof ANTIGRAVITY_HOOK_EVENT_TYPES)[number];
|
|
805
|
+
|
|
806
|
+
/** Antigravity `--hook` arg → canonical HookEventType. PreInvocation is
|
|
807
|
+
* Antigravity's before-model event → maps to UserPromptSubmit (where instruct
|
|
808
|
+
* injects `injectSteps`). Verified against agy v1.1.2. */
|
|
809
|
+
export const ANTIGRAVITY_EVENT_MAP: Record<AntigravityHookEventType, HookEventType> = {
|
|
810
|
+
PreToolUse: "PreToolUse",
|
|
811
|
+
PostToolUse: "PostToolUse",
|
|
812
|
+
PreInvocation: "UserPromptSubmit",
|
|
813
|
+
Stop: "Stop",
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
/**
|
|
817
|
+
* Antigravity's tool names → Claude PascalCase canonical names so existing
|
|
818
|
+
* builtin policies (which match `toolName === "Bash"`, etc.) fire unchanged.
|
|
819
|
+
* Tool names VERIFIED against the agy binary's tool registry + live transcripts:
|
|
820
|
+
* the file tool is `write_to_file` (NOT `write_file`), listing is `list_dir`
|
|
821
|
+
* (NOT `list_directory`), and glob is `find_by_name` (NOT `find_filepath`) — the
|
|
822
|
+
* earlier best-effort names were wrong, so `block-env-files`/`block-secrets-write`
|
|
823
|
+
* silently no-op'd on Antigravity file writes. Unknown tools pass through via the
|
|
824
|
+
* `?? raw` fallback.
|
|
825
|
+
*/
|
|
826
|
+
export const ANTIGRAVITY_TOOL_MAP: Record<string, string> = {
|
|
827
|
+
run_command: "Bash",
|
|
828
|
+
write_to_file: "Write",
|
|
610
829
|
read_file: "Read",
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
830
|
+
view_file: "Read",
|
|
831
|
+
edit_file: "Edit",
|
|
832
|
+
replace_file_content: "Edit",
|
|
833
|
+
list_dir: "LS",
|
|
834
|
+
find_by_name: "Glob",
|
|
615
835
|
grep_search: "Grep",
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
836
|
+
read_url_content: "WebFetch",
|
|
837
|
+
search_web: "WebSearch",
|
|
838
|
+
};
|
|
839
|
+
|
|
840
|
+
/**
|
|
841
|
+
* Antigravity tool args are PascalCase. Keyed by the CANONICAL tool name
|
|
842
|
+
* (canonicalizeToolInput runs after canonicalizeToolName). VERIFIED live:
|
|
843
|
+
* `run_command` delivers `CommandLine`/`Cwd`; `write_to_file` delivers the path
|
|
844
|
+
* as `TargetFile` and body as `CodeContent`. Without the Write/Edit/Read entries
|
|
845
|
+
* the path/content builtins (`block-env-files`, `block-secrets-write`,
|
|
846
|
+
* `block-read-outside-cwd`) never saw a `file_path` and silently no-op'd on
|
|
847
|
+
* Antigravity file operations. Read/Edit path keys are best-effort within the
|
|
848
|
+
* same tool family (all file tools operate on `TargetFile`); extra keys are
|
|
849
|
+
* harmless (only remapped when present).
|
|
850
|
+
*/
|
|
851
|
+
export const ANTIGRAVITY_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
|
|
852
|
+
Bash: { CommandLine: "command", Cwd: "cwd" },
|
|
853
|
+
Write: { TargetFile: "file_path", CodeContent: "content" },
|
|
854
|
+
Edit: { TargetFile: "file_path" },
|
|
855
|
+
Read: { TargetFile: "file_path", AbsolutePath: "file_path", File: "file_path" },
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
// ── Goose (codename goose, Block) ────────────────────────────────────────────
|
|
859
|
+
//
|
|
860
|
+
// Goose is Block's open-source Rust MCP agent — a LOCAL dev-agent CLI (like
|
|
861
|
+
// Claude/Factory/Devin, NOT a gateway). Dual-pillar: external shell-hook
|
|
862
|
+
// enforcement + SQLite audit. The entire contract below was verified LIVE
|
|
863
|
+
// against goose v1.43.0.
|
|
864
|
+
//
|
|
865
|
+
// Enforcement is via Goose's "hooks" system (the cross-agent Open Plugins spec):
|
|
866
|
+
// a plugin directory whose `hooks/hooks.json` `command` runs
|
|
867
|
+
// `failproofai --hook <event> --cli goose`. Goose AUTO-DISCOVERS the dir at
|
|
868
|
+
// startup (no config edit needed) and self-registers it into config.yaml.
|
|
869
|
+
//
|
|
870
|
+
// 1. **Deny contract = `PreToolUse` ONLY** (shipped in goose ≥ v1.37.0,
|
|
871
|
+
// PR block/goose#9304). A hook blocks a tool via `{"decision":"block",
|
|
872
|
+
// "reason"}` on stdout at exit 0 (exit 2 + stderr also works); ANY other
|
|
873
|
+
// error/timeout → fail-open (allow). Verified live: the reason reaches the
|
|
874
|
+
// model and "do not retry" is appended. Goose has NO `Stop` event, so the 5
|
|
875
|
+
// `require-*-before-stop` builtins never fire (inapplicable, like Hermes).
|
|
876
|
+
// `UserPromptSubmit` deny is NOT honored (observation only). `PreToolUse`
|
|
877
|
+
// fires for the shell tool AND inside delegated subagents, so it is the
|
|
878
|
+
// single sufficient deny point.
|
|
879
|
+
//
|
|
880
|
+
// 2. **Event names are already PascalCase** (matching Claude's canonical set),
|
|
881
|
+
// so there is NO `GOOSE_EVENT_MAP` and NO handler.ts event-canonicalization
|
|
882
|
+
// branch. The stdin payload, however, uses `event` (not `hook_event_name`)
|
|
883
|
+
// and `working_dir` (not `cwd`) — handler.ts normalizes `working_dir`→`cwd`
|
|
884
|
+
// for goose so `block-read-outside-cwd` keeps its cwd. `tool_name` /
|
|
885
|
+
// `tool_input` are already the canonical field names.
|
|
886
|
+
//
|
|
887
|
+
// 3. Tool names arrive BOTH bare (`shell`, `write`, `edit`, `view`,
|
|
888
|
+
// `read_image`, `tree`, `delegate`) AND `<ext>__<tool>` namespaced
|
|
889
|
+
// (`todo__todo_write`); GOOSE_TOOL_MAP covers both forms, unknown tools
|
|
890
|
+
// pass through via the `?? raw` fallback. Path-bearing tools deliver the
|
|
891
|
+
// path as `path` (or `source` for read_image), so GOOSE_TOOL_INPUT_MAP maps
|
|
892
|
+
// it to `file_path`. Shell's `command` is already canonical.
|
|
893
|
+
//
|
|
894
|
+
// 4. **Instruct has no channel** — a non-block PreToolUse decision injects
|
|
895
|
+
// nothing (verified live), so instruct() degrades to allow + stderr note
|
|
896
|
+
// (like Factory/Hermes on non-Stop events). policy-evaluator.ts's
|
|
897
|
+
// `cli === "goose"` branch: PreToolUse deny → `{"decision":"block",reason}`
|
|
898
|
+
// JSON at exit 0; no Stop branch.
|
|
899
|
+
//
|
|
900
|
+
// Settings paths (verified against goose v1.43.0):
|
|
901
|
+
// user → ~/.agents/plugins/failproofai/hooks/hooks.json
|
|
902
|
+
// project → <cwd>/.agents/plugins/failproofai/hooks/hooks.json
|
|
903
|
+
//
|
|
904
|
+
// Audit pillar: sessions in SQLite at
|
|
905
|
+
// ~/.local/share/goose/sessions/sessions.db (schema v15). `sessions` rows carry
|
|
906
|
+
// a real `working_dir`, so `audit --project <cwd>` filters like Devin (NOT
|
|
907
|
+
// grouped-by-source like Hermes); `messages` rows hold Claude-style typed-block
|
|
908
|
+
// `content_json`. See lib/goose-sessions.ts. `GOOSE_HOME` overrides the data
|
|
909
|
+
// dir for tests.
|
|
910
|
+
|
|
911
|
+
export const GOOSE_HOOK_SCOPES = ["user", "project"] as const;
|
|
912
|
+
export type GooseHookScope = (typeof GOOSE_HOOK_SCOPES)[number];
|
|
913
|
+
|
|
914
|
+
export const GOOSE_HOOK_EVENT_TYPES = [
|
|
915
|
+
"SessionStart",
|
|
916
|
+
"UserPromptSubmit",
|
|
917
|
+
"PreToolUse",
|
|
918
|
+
"PostToolUse",
|
|
919
|
+
"SessionEnd",
|
|
920
|
+
] as const;
|
|
921
|
+
export type GooseHookEventType = (typeof GOOSE_HOOK_EVENT_TYPES)[number];
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* Goose's tool names → Claude PascalCase canonical names so existing builtin
|
|
925
|
+
* policies (which match `toolName === "Bash"`, etc.) fire unchanged. Verified
|
|
926
|
+
* live against goose v1.43.0: the developer extension exposes `shell` (Bash),
|
|
927
|
+
* `write`/`edit`/`view` (file ops), `read_image`, `glob`/`grep`, plus
|
|
928
|
+
* `tree`/`delegate`; other extensions namespace their tools (`todo__todo_write`).
|
|
929
|
+
* Unknown tools (MCP, other extensions) pass through unchanged via the `?? raw`
|
|
930
|
+
* fallback in handler.ts:canonicalizeToolName.
|
|
931
|
+
*/
|
|
932
|
+
export const GOOSE_TOOL_MAP: Record<string, string> = {
|
|
933
|
+
shell: "Bash",
|
|
934
|
+
write: "Write",
|
|
935
|
+
edit: "Edit",
|
|
936
|
+
view: "Read",
|
|
937
|
+
read_image: "Read",
|
|
938
|
+
glob: "Glob",
|
|
939
|
+
grep: "Grep",
|
|
940
|
+
tree: "LS",
|
|
941
|
+
delegate: "Task",
|
|
942
|
+
todo__todo_write: "TodoWrite",
|
|
943
|
+
};
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* Per-tool input-key translation, keyed by the *canonical* tool name (the
|
|
947
|
+
* handler canonicalizes the name before calling canonicalizeToolInput).
|
|
948
|
+
* Verified live: goose's file tools deliver the path as `path` (`read_image`
|
|
949
|
+
* uses `source`), but Claude builtins read `file_path` (block-env-files,
|
|
950
|
+
* block-secrets-write, block-read-outside-cwd) — so map it. `shell` already
|
|
951
|
+
* delivers `command` (canonical), so Bash needs no entry. `edit` delivers
|
|
952
|
+
* `before`/`after` (not `old_string`/`new_string`); only the top-level `path`
|
|
953
|
+
* is mapped (no builtin inspects the edit body), mirroring PI_TOOL_INPUT_MAP.
|
|
954
|
+
*/
|
|
955
|
+
export const GOOSE_TOOL_INPUT_MAP: Record<string, Record<string, string>> = {
|
|
956
|
+
Read: { path: "file_path", source: "file_path" },
|
|
957
|
+
Write: { path: "file_path" },
|
|
958
|
+
Edit: { path: "file_path" },
|
|
959
|
+
LS: { path: "file_path" },
|
|
622
960
|
};
|
|
623
961
|
|
|
624
962
|
export const HOOK_EVENT_TYPES = [
|
|
@@ -685,15 +1023,15 @@ export interface SessionMetadata {
|
|
|
685
1023
|
cwd?: string;
|
|
686
1024
|
permissionMode?: string;
|
|
687
1025
|
/** Read from the stdin payload's `hook_event_name` field. Carries the raw
|
|
688
|
-
* agent-emitted event name (e.g.
|
|
689
|
-
*
|
|
1026
|
+
* agent-emitted event name (e.g. Cursor's `preToolUse`, Pi's `tool_call`).
|
|
1027
|
+
* May be undefined when stdin omits it. */
|
|
690
1028
|
hookEventName?: string;
|
|
691
1029
|
/** The raw event name passed on the CLI's `--hook` flag, BEFORE any
|
|
692
|
-
* per-CLI canonicalization to PascalCase (e.g. `
|
|
693
|
-
*
|
|
694
|
-
*
|
|
1030
|
+
* per-CLI canonicalization to PascalCase (e.g. `preToolUse` for Cursor).
|
|
1031
|
+
* Use this for round-tripping the agent-side event name in response shapes
|
|
1032
|
+
* when stdin doesn't include `hook_event_name`. */
|
|
695
1033
|
rawHookEventName?: string;
|
|
696
|
-
/** Which agent CLI fired this hook (claude | codex | copilot | cursor | opencode | pi |
|
|
1034
|
+
/** Which agent CLI fired this hook (claude | codex | copilot | cursor | opencode | pi | hermes | openclaw | factory | devin | antigravity | goose). Set by handler.ts from --cli. */
|
|
697
1035
|
cli?: IntegrationType;
|
|
698
1036
|
}
|
|
699
1037
|
|