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
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `failproofai config` — the interactive setup launcher.
|
|
3
|
+
*
|
|
4
|
+
* A single guided flow that sets up the whole failproofai ecosystem, hiding the
|
|
5
|
+
* scope / cli / two-layer machinery behind three plain questions:
|
|
6
|
+
* 1. Where? global (user) vs this project
|
|
7
|
+
* 2. Assistants? multi-select of agent CLIs (detected + install-ahead)
|
|
8
|
+
* 3. Policies? multi-select of themed presets (combine any) or Everything
|
|
9
|
+
* …then a Review screen that shows exactly which files change, and Apply.
|
|
10
|
+
*
|
|
11
|
+
* Selections REPLACE the enabled set at the chosen scope (the picker pre-checks
|
|
12
|
+
* whatever is already enabled, so unticking removes). Reuses the tested
|
|
13
|
+
* install/uninstall manager and the existing searchable policy picker.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { resolve, sep } from "node:path";
|
|
18
|
+
|
|
19
|
+
import { selectOne, multiSelect, intro, outro, summarize, type TTYIn, type TTYOut } from "./tui";
|
|
20
|
+
import {
|
|
21
|
+
detectInstalledClis,
|
|
22
|
+
getIntegration,
|
|
23
|
+
} from "./integrations";
|
|
24
|
+
import { INTEGRATION_TYPES, type IntegrationType, type HookScope } from "./types";
|
|
25
|
+
import { installHooks } from "./manager";
|
|
26
|
+
import { getConfigPathForScope } from "./hooks-config";
|
|
27
|
+
import { POLICY_PRESETS, resolvePreset, resolveEverything } from "./policy-presets";
|
|
28
|
+
import { trackHookEvent } from "./hook-telemetry";
|
|
29
|
+
import { getInstanceId } from "../../lib/telemetry-id";
|
|
30
|
+
|
|
31
|
+
export interface WizardIO {
|
|
32
|
+
stdin?: TTYIn;
|
|
33
|
+
stdout?: TTYOut;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface WizardResult {
|
|
37
|
+
applied: boolean;
|
|
38
|
+
scope?: HookScope;
|
|
39
|
+
clis?: IntegrationType[];
|
|
40
|
+
policies?: string[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function emit(event: string, props: Record<string, unknown>): Promise<void> {
|
|
44
|
+
try {
|
|
45
|
+
await trackHookEvent(getInstanceId(), event, props);
|
|
46
|
+
} catch {
|
|
47
|
+
// best-effort — never break the wizard
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** Replace ~ prefix with the literal home dir path for readable review output. */
|
|
52
|
+
function homeify(p: string): string {
|
|
53
|
+
const home = homedir();
|
|
54
|
+
// Require a path boundary so `/home/alice-work` isn't collapsed to `~-work`
|
|
55
|
+
// for a home of `/home/alice`.
|
|
56
|
+
if (p === home) return "~";
|
|
57
|
+
if (p.startsWith(home + sep)) return "~" + p.slice(home.length);
|
|
58
|
+
return p;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// ── Pure builders (exported for tests) ───────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
export function buildScopeChoices(cwd: string) {
|
|
64
|
+
return [
|
|
65
|
+
{
|
|
66
|
+
label: "Everywhere I code",
|
|
67
|
+
value: "user" as HookScope,
|
|
68
|
+
hint: "global · applies in every project on this machine",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
label: "Just this project",
|
|
72
|
+
value: "project" as HookScope,
|
|
73
|
+
hint: homeify(cwd),
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function buildAgentChoices(scope: HookScope, cwd: string) {
|
|
79
|
+
const detected = new Set(detectInstalledClis());
|
|
80
|
+
// Detected first, then the rest as "install ahead of time".
|
|
81
|
+
const ordered = [
|
|
82
|
+
...INTEGRATION_TYPES.filter((id) => detected.has(id)),
|
|
83
|
+
...INTEGRATION_TYPES.filter((id) => !detected.has(id)),
|
|
84
|
+
];
|
|
85
|
+
return ordered.map((id) => {
|
|
86
|
+
const integration = getIntegration(id);
|
|
87
|
+
const isDetected = detected.has(id);
|
|
88
|
+
let installedHere = false;
|
|
89
|
+
try {
|
|
90
|
+
installedHere = integration.hooksInstalledInSettings(scope, cwd);
|
|
91
|
+
} catch {
|
|
92
|
+
installedHere = false;
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
label: integration.displayName,
|
|
96
|
+
value: id,
|
|
97
|
+
checked: isDetected || installedHere,
|
|
98
|
+
section: isDetected ? "Detected" : "Not installed · set up ahead of time",
|
|
99
|
+
hint: installedHere ? "already configured" : isDetected ? undefined : "not on PATH",
|
|
100
|
+
};
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const EVERYTHING = "__everything__";
|
|
105
|
+
const ALL_CLIS = "__all_clis__";
|
|
106
|
+
|
|
107
|
+
/** The themed preset bundles for the wizard's multi-select, plus an "Everything"
|
|
108
|
+
* option that enables the full builtin policy set. */
|
|
109
|
+
export function buildPresetChoices() {
|
|
110
|
+
const choices: Array<{ label: string; value: string; hint: string }> = POLICY_PRESETS.map(
|
|
111
|
+
(p) => ({ label: p.label, value: p.id, hint: p.description }),
|
|
112
|
+
);
|
|
113
|
+
choices.push({
|
|
114
|
+
label: "Everything",
|
|
115
|
+
value: EVERYTHING,
|
|
116
|
+
hint: `all ${resolveEverything().length} policies`,
|
|
117
|
+
});
|
|
118
|
+
return choices;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Resolve the ticked options to a concrete policy set. Presets are additive —
|
|
123
|
+
* the deduped union of every selected preset's policies — while "Everything"
|
|
124
|
+
* enables the full policy set and wins over any presets.
|
|
125
|
+
*/
|
|
126
|
+
export function resolvePresetSelection(values: string[]): string[] {
|
|
127
|
+
if (values.includes(EVERYTHING)) return resolveEverything();
|
|
128
|
+
return [...new Set(values.flatMap((id) => resolvePreset(id)))];
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function reviewLines(
|
|
132
|
+
state: { scope: HookScope; clis: IntegrationType[]; policies: string[]; cwd: string },
|
|
133
|
+
): string[] {
|
|
134
|
+
const { scope, clis, policies, cwd } = state;
|
|
135
|
+
const where =
|
|
136
|
+
scope === "project" ? `This project (${homeify(cwd)})` : "Everywhere (global)";
|
|
137
|
+
const lines: string[] = [];
|
|
138
|
+
const assistantNames = clis.map((c) => getIntegration(c).displayName);
|
|
139
|
+
lines.push(` Where : ${where}`);
|
|
140
|
+
lines.push(` Assistants : ${assistantNames.length ? summarize(assistantNames, "assistants") : "(none)"}`);
|
|
141
|
+
lines.push(` Policies : ${policies.length} enabled`);
|
|
142
|
+
lines.push("");
|
|
143
|
+
lines.push(" This will update:");
|
|
144
|
+
for (const cli of clis) {
|
|
145
|
+
const integration = getIntegration(cli);
|
|
146
|
+
lines.push(` ${homeify(integration.getSettingsPath(scope, cwd))} ${integration.displayName} hooks`);
|
|
147
|
+
}
|
|
148
|
+
lines.push(` ${homeify(getConfigPathForScope(scope, cwd))} ${policies.length} policies`);
|
|
149
|
+
return lines;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ── First-run redirect ───────────────────────────────────────────────────────
|
|
153
|
+
|
|
154
|
+
function firstRunMarkerPath(): string {
|
|
155
|
+
return resolve(homedir(), ".failproofai", ".launcher-configured");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function hasSeenLauncher(): boolean {
|
|
159
|
+
return existsSync(firstRunMarkerPath());
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function markLauncherSeen(): void {
|
|
163
|
+
try {
|
|
164
|
+
mkdirSync(resolve(homedir(), ".failproofai"), { recursive: true });
|
|
165
|
+
writeFileSync(firstRunMarkerPath(), "1", "utf8");
|
|
166
|
+
} catch {
|
|
167
|
+
// best-effort
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Whether failproofai is already set up GLOBALLY (user scope) for any agent.
|
|
173
|
+
* Deliberately ignores project scope: project-scoped hooks in whatever repo the
|
|
174
|
+
* user happens to be in shouldn't suppress the one-time global welcome. The
|
|
175
|
+
* marker file is the primary "seen" gate; this is the "already set up" shortcut.
|
|
176
|
+
*/
|
|
177
|
+
function anyHooksInstalledGlobally(): boolean {
|
|
178
|
+
for (const id of INTEGRATION_TYPES) {
|
|
179
|
+
try {
|
|
180
|
+
if (getIntegration(id).hooksInstalledInSettings("user")) return true;
|
|
181
|
+
} catch {
|
|
182
|
+
// ignore broken settings files
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* On the FIRST bare `failproofai` invocation, redirect the user into the
|
|
190
|
+
* configure wizard instead of the dashboard. Returns true when it handled the
|
|
191
|
+
* turn (caller should exit rather than launch the dashboard).
|
|
192
|
+
*
|
|
193
|
+
* • FAILPROOFAI_NO_FIRST_RUN=1 → never redirect
|
|
194
|
+
* • already seen the launcher → never redirect again
|
|
195
|
+
* • hooks already installed → mark seen, go to dashboard (already set up)
|
|
196
|
+
* • non-TTY (CI/pipe) → print a one-line hint, go to dashboard
|
|
197
|
+
* • fresh + TTY → mark seen, run the wizard, done
|
|
198
|
+
*/
|
|
199
|
+
export async function maybeFirstRunConfigure(io: WizardIO = {}): Promise<boolean> {
|
|
200
|
+
if (process.env.FAILPROOFAI_NO_FIRST_RUN === "1") return false;
|
|
201
|
+
if (hasSeenLauncher()) return false;
|
|
202
|
+
|
|
203
|
+
const stdin: TTYIn = io.stdin ?? process.stdin;
|
|
204
|
+
const stdout: TTYOut = io.stdout ?? process.stdout;
|
|
205
|
+
|
|
206
|
+
if (anyHooksInstalledGlobally()) {
|
|
207
|
+
markLauncherSeen();
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
212
|
+
stdout.write(
|
|
213
|
+
`\n[failproofai] Not set up yet — run \`failproofai config\` to get started.\n\n`,
|
|
214
|
+
);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Fire-and-forget: never block the wizard's first paint on telemetry.
|
|
219
|
+
void emit("first_run_configure_shown", {});
|
|
220
|
+
// runConfigureWizard marks the launcher as seen only if the user completes an
|
|
221
|
+
// apply — so cancelling keeps redirecting here on the next bare run, and only
|
|
222
|
+
// a finished setup sends the user to the dashboard afterwards.
|
|
223
|
+
const result = await runConfigureWizard(io);
|
|
224
|
+
|
|
225
|
+
// Onboarding-only: after a completed first-run setup, run the audit pipeline
|
|
226
|
+
// (scan + cache warm) before the caller boots the dashboard. The explicit
|
|
227
|
+
// `failproofai config` command does NOT do this — only this first-run path.
|
|
228
|
+
// Lazy-imported + best-effort; opt out with FAILPROOFAI_NO_AUTO_AUDIT=1.
|
|
229
|
+
if (result.applied) {
|
|
230
|
+
try {
|
|
231
|
+
const { runPostSetupAudit } = await import("../audit/cli");
|
|
232
|
+
await runPostSetupAudit();
|
|
233
|
+
} catch {
|
|
234
|
+
// the audit is a bonus — never let it break onboarding or the dashboard.
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// ── The wizard ───────────────────────────────────────────────────────────────
|
|
241
|
+
|
|
242
|
+
export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResult> {
|
|
243
|
+
const stdin: TTYIn = io.stdin ?? process.stdin;
|
|
244
|
+
const stdout: TTYOut = io.stdout ?? process.stdout;
|
|
245
|
+
const cwd = process.cwd();
|
|
246
|
+
|
|
247
|
+
if (!stdin.isTTY || !stdout.isTTY) {
|
|
248
|
+
stdout.write(
|
|
249
|
+
"failproofai config needs an interactive terminal.\n" +
|
|
250
|
+
"Use the flag form instead, e.g.:\n" +
|
|
251
|
+
" failproofai policies --install --scope user --cli claude\n",
|
|
252
|
+
);
|
|
253
|
+
return { applied: false };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Fire-and-forget: never block the wizard's first paint on telemetry.
|
|
257
|
+
void emit("configure_started", {});
|
|
258
|
+
intro("let's set up your safety net", stdout);
|
|
259
|
+
|
|
260
|
+
const cancel = (): WizardResult => {
|
|
261
|
+
outro("Cancelled — nothing was changed.", { ok: false }, stdout);
|
|
262
|
+
return { applied: false };
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// 1 — Where?
|
|
266
|
+
const scope = await selectOne<HookScope>({
|
|
267
|
+
message: "Where should this apply?",
|
|
268
|
+
choices: buildScopeChoices(cwd),
|
|
269
|
+
stdin,
|
|
270
|
+
stdout,
|
|
271
|
+
});
|
|
272
|
+
if (scope === null) return cancel();
|
|
273
|
+
|
|
274
|
+
// 2 — Which assistants? An "Everything available" row protects every supported
|
|
275
|
+
// CLI (detected + set-up-ahead); when ticked it wins over the individual boxes.
|
|
276
|
+
const clisSel = await multiSelect<string>({
|
|
277
|
+
message: "Which AI assistants should it protect?",
|
|
278
|
+
choices: [
|
|
279
|
+
{
|
|
280
|
+
label: "Everything available",
|
|
281
|
+
value: ALL_CLIS,
|
|
282
|
+
hint: `protect all ${INTEGRATION_TYPES.length} supported CLIs`,
|
|
283
|
+
},
|
|
284
|
+
...buildAgentChoices(scope, cwd),
|
|
285
|
+
],
|
|
286
|
+
minSelected: 1,
|
|
287
|
+
summaryNoun: "assistants",
|
|
288
|
+
hint: "detected CLIs are pre-selected · space toggles · ctrl+a all · ↵ confirm",
|
|
289
|
+
stdin,
|
|
290
|
+
stdout,
|
|
291
|
+
});
|
|
292
|
+
if (clisSel === null) return cancel();
|
|
293
|
+
const clis: IntegrationType[] = clisSel.includes(ALL_CLIS)
|
|
294
|
+
? [...INTEGRATION_TYPES]
|
|
295
|
+
: (clisSel.filter((v) => v !== ALL_CLIS) as IntegrationType[]);
|
|
296
|
+
|
|
297
|
+
// 3 — Which policies? Multi-select of themed presets — additive, so the
|
|
298
|
+
// enabled set is the union of every ticked bundle.
|
|
299
|
+
const presets = await multiSelect<string>({
|
|
300
|
+
message: "What should we guard against?",
|
|
301
|
+
choices: buildPresetChoices(),
|
|
302
|
+
minSelected: 1,
|
|
303
|
+
summaryNoun: "bundles",
|
|
304
|
+
hint: "space toggles · combine presets · ↵ confirm",
|
|
305
|
+
stdin,
|
|
306
|
+
stdout,
|
|
307
|
+
});
|
|
308
|
+
if (presets === null) return cancel();
|
|
309
|
+
const policies = resolvePresetSelection(presets);
|
|
310
|
+
|
|
311
|
+
// 4 — Review & apply
|
|
312
|
+
const decision = await selectOne<"apply" | "cancel">({
|
|
313
|
+
message: "Ready to apply?",
|
|
314
|
+
body: reviewLines({ scope, clis, policies, cwd }),
|
|
315
|
+
choices: [
|
|
316
|
+
{ label: "Yes, apply now", value: "apply", hint: "write the config" },
|
|
317
|
+
{ label: "Cancel", value: "cancel", hint: "quit, no changes" },
|
|
318
|
+
],
|
|
319
|
+
stdin,
|
|
320
|
+
stdout,
|
|
321
|
+
});
|
|
322
|
+
if (decision !== "apply") return cancel();
|
|
323
|
+
|
|
324
|
+
// Apply — REPLACE the enabled set at this scope.
|
|
325
|
+
// Telemetry runs concurrently with the install (never rejects, 5s-bounded) so
|
|
326
|
+
// it doesn't add dead time between "apply" and the config actually writing,
|
|
327
|
+
// while still being awaited before the process can exit.
|
|
328
|
+
const applied = emit("configure_applied", {
|
|
329
|
+
scope,
|
|
330
|
+
cli: clis,
|
|
331
|
+
cli_count: clis.length,
|
|
332
|
+
policy_count: policies.length,
|
|
333
|
+
source: presets.join("+"),
|
|
334
|
+
});
|
|
335
|
+
// quiet: the wizard renders its own outro; replace: the chosen set becomes
|
|
336
|
+
// the full enabled set at this scope (unticking removes).
|
|
337
|
+
await installHooks(
|
|
338
|
+
policies,
|
|
339
|
+
scope,
|
|
340
|
+
cwd,
|
|
341
|
+
/* includeBeta */ false,
|
|
342
|
+
"configure-wizard",
|
|
343
|
+
/* customPoliciesPath */ undefined,
|
|
344
|
+
/* removeCustomHooks */ false,
|
|
345
|
+
clis,
|
|
346
|
+
{ replace: true, quiet: true },
|
|
347
|
+
);
|
|
348
|
+
await applied;
|
|
349
|
+
// Only now — a completed apply — is the launcher considered "seen", so the
|
|
350
|
+
// first-run bare invocation stops redirecting here and opens the dashboard.
|
|
351
|
+
markLauncherSeen();
|
|
352
|
+
|
|
353
|
+
const agentNames = clis.map((c) => getIntegration(c).displayName).join(", ");
|
|
354
|
+
outro(`Setup complete — ${policies.length} policies guarding ${agentNames}.`, { ok: true }, stdout);
|
|
355
|
+
return { applied: true, scope, clis, policies };
|
|
356
|
+
}
|