failproofai 0.0.14 → 0.0.15-beta.1
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/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +6 -6
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +2 -2
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
- 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 +2 -2
- 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/build-manifest.json +3 -3
- 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 +2 -2
- 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 +1 -1
- 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 +1 -1
- 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 +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 +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 +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 +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 +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 +1 -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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js +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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js +2 -2
- 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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +20 -8
- package/.next/standalone/.next/server/app/policies/page.js +2 -2
- 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/build-manifest.json +3 -3
- 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 +4 -4
- 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/build-manifest.json +3 -3
- 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 +4 -4
- 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/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js +3 -3
- 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-219ec._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0hv08mx._.js → [root-of-the-server]__0-dh5jy._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__04_h-a5._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__06cuf1y._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0obaznk._.js → [root-of-the-server]__0h3lfmp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0jnjf2t._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0xvsnvt._.js → [root-of-the-server]__0l4vuqm._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0longh-._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0sb_5m8._.js +4 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xuaoik._.js +6 -4
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1hkdkmz._.js → [root-of-the-server]__10oa-v9._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__16le-kd._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1i9rknc._.js → [root-of-the-server]__18d-9oi._.js} +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.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]__1is3glr._.js +3 -0
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_17k9e3w.js +6 -6
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +1 -1
- package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +1 -1
- 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]__0hdsupo._.js → [root-of-the-server]__0114ewg._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01od0m6._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lpvwqm._.js +21 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ynf7tx._.js → [root-of-the-server]__0qucxyj._.js} +3 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0uno39i._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1s2b6h0._.js → [root-of-the-server]__0x3anhr._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0y4wf1u._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +10 -10
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00cz9as._.js → [root-of-the-server]__1apb7k_._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1nq7ivq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1py795m._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.js +4 -0
- package/.next/standalone/.next/server/chunks/ssr/_077y5np._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1-3unkg._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1e19atl._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/_1m_p7pi._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_components_project-list_tsx_1ke6anr._.js +3 -0
- 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 +2 -2
- package/.next/standalone/.next/server/chunks/ssr/lib_0xkhw_v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_hermes-projects_ts_05b8-it._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_openclaw-projects_ts_0qxq3bp._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{node_modules_html-to-image_es_index_0gkzjaa.js → node_modules_html-to-image_es_index_1wnt2ya.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
- 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 +22 -10
- package/.next/standalone/.next/static/chunks/{29o4j32z643_a.js → 05h7pau8d3rpj.js} +1 -1
- package/.next/standalone/.next/static/chunks/0oos4ntyvkmjl.js +1 -0
- package/.next/standalone/.next/static/chunks/0tuwf_7uhfn2y.js +6 -0
- package/.next/standalone/.next/static/chunks/1hdhteui932bq.js +1 -0
- package/.next/standalone/.next/static/chunks/1l6q2-8m0gk19.js +1 -0
- package/.next/standalone/.next/static/chunks/2geqsiz0n8e3w.js +1 -0
- package/.next/standalone/.next/static/chunks/{3-ogr79xqbw0h.js → 2mazwb1qmur1p.js} +1 -1
- package/.next/standalone/.next/static/chunks/2pujpnfx4pws6.css +2 -0
- package/.next/standalone/.next/static/chunks/{1ua5armwfph8o.js → 31fmsp1soxi07.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3s8aaig91937v.js → 37-so-zy208k7.js} +1 -1
- package/.next/standalone/.next/static/chunks/3a_o5v_sl858j.js +1 -0
- package/.next/standalone/.next/static/chunks/{02jcotghcxrbu.js → 3kmwfieo15mr2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2uh_4k4m296z5.js → 3p66lo2y-ezfr.js} +1 -1
- package/.next/standalone/.next/static/chunks/{06z_ex1ts3n4s.js → 412ajx6jkb5_i.js} +1 -1
- package/.next/standalone/.next/static/chunks/{turbopack-10hj8t5pf33tu.js → turbopack-1lsv92x7klwrn.js} +1 -1
- package/.next/standalone/app/actions/get-hooks-config.ts +125 -8
- package/.next/standalone/app/actions/update-hooks-config.ts +38 -1
- package/.next/standalone/app/components/project-list.tsx +229 -42
- package/.next/standalone/app/policies/hooks-client.tsx +149 -27
- package/.next/standalone/app/project/[name]/page.tsx +12 -2
- package/.next/standalone/integration-suite/README.md +43 -1
- package/.next/standalone/integration-suite/ci-entrypoint.sh +21 -6
- package/.next/standalone/integration-suite/install-clis.sh +58 -13
- package/.next/standalone/integration-suite/probe-cli.sh +51 -11
- package/.next/standalone/integration-suite/report.js +52 -6
- package/.next/standalone/integration-suite/run.sh +55 -3
- package/.next/standalone/lib/hermes-profiles.ts +156 -0
- package/.next/standalone/lib/hermes-projects.ts +91 -25
- package/.next/standalone/lib/hermes-sessions.ts +65 -10
- package/.next/standalone/lib/openclaw-projects.ts +111 -18
- package/.next/standalone/lib/openclaw-sessions.ts +20 -0
- package/.next/standalone/lib/paths.ts +36 -0
- package/.next/standalone/lib/project-tree.ts +193 -0
- package/.next/standalone/lib/projects.ts +22 -0
- package/.next/standalone/node_modules/@next/env/package.json +1 -1
- package/.next/standalone/node_modules/next/dist/build/next-config-ts/transpile-config.js +3 -114
- package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
- package/.next/standalone/node_modules/next/dist/cli/next-test.js +2 -1
- package/.next/standalone/node_modules/next/dist/compiled/http-proxy/index.js +5 -5
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +11 -10
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +11 -10
- package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route-turbo.runtime.prod.js +2 -2
- package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +9 -9
- package/.next/standalone/node_modules/next/dist/lib/install-dependencies.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
- package/.next/standalone/node_modules/next/dist/lib/typescript/loadTsConfig.js +181 -0
- package/.next/standalone/node_modules/next/dist/lib/typescript/missingDependencyError.js +1 -1
- package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeCheckCli.js +53 -0
- package/.next/standalone/node_modules/next/dist/lib/typescript/runTypeScriptCli.js +256 -0
- package/.next/standalone/node_modules/next/dist/lib/verify-typescript-setup.js +97 -56
- package/.next/standalone/node_modules/next/dist/server/app-render/action-handler.js +129 -34
- package/.next/standalone/node_modules/next/dist/server/app-render/manifests-singleton.js +52 -4
- package/.next/standalone/node_modules/next/dist/server/config-schema.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/config-shared.js +1 -2
- package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
- package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +8 -27
- package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/lib/incremental-cache/index.js +90 -53
- package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +15 -2
- package/.next/standalone/node_modules/next/dist/server/lib/router-utils/proxy-request.js +4 -0
- package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
- package/.next/standalone/node_modules/next/dist/server/web/spec-extension/unstable-cache.js +1 -1
- package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
- package/.next/standalone/node_modules/next/dist/shared/lib/router/utils/prepare-destination.js +2 -1
- package/.next/standalone/node_modules/next/dist/shared/lib/server-reference-info.js +12 -0
- package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
- package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
- package/.next/standalone/node_modules/next/package.json +10 -10
- package/.next/standalone/package.json +7 -6
- package/.next/standalone/pi-extension/index.ts +38 -5
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +14 -13
- package/dist/cli.mjs +789 -399
- package/lib/hermes-profiles.ts +156 -0
- package/lib/hermes-projects.ts +91 -25
- package/lib/hermes-sessions.ts +65 -10
- package/lib/openclaw-projects.ts +111 -18
- package/lib/openclaw-sessions.ts +20 -0
- package/lib/paths.ts +36 -0
- package/lib/project-tree.ts +193 -0
- package/lib/projects.ts +22 -0
- package/package.json +7 -6
- package/pi-extension/index.ts +38 -5
- package/scripts/launch.ts +7 -0
- package/src/audit/cli-adapters/hermes.ts +6 -3
- package/src/audit/cli-adapters/openclaw.ts +17 -13
- package/src/hooks/configure-wizard.ts +24 -2
- package/src/hooks/custom-hooks-loader.ts +90 -13
- package/src/hooks/enforcement-capability.ts +266 -0
- package/src/hooks/handler.ts +20 -3
- package/src/hooks/hook-activity-store.ts +14 -0
- package/src/hooks/hooks-config.ts +90 -6
- package/src/hooks/integrations.ts +123 -19
- package/src/hooks/manager.ts +206 -75
- package/src/hooks/policy-evaluator.ts +59 -7
- package/src/hooks/policy-types.ts +31 -0
- package/src/hooks/types.ts +50 -2
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0q2nbsl._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1d9qen3._.js +0 -3
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mrihkj._.js +0 -3
- package/.next/standalone/.next/server/chunks/lib_openclaw-projects_ts_0gc-p24._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__015_i4t._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__030k0c6._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__03lv-pe._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__042d3cd._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__09q1168._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qeuy9c._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s89hoe._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0zf8xlq._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__17ai7sy._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1d8omgc._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1fax1sl._.js +0 -19
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tkjqka._.js +0 -4
- package/.next/standalone/.next/server/chunks/ssr/_05whahf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_0_9_ytf._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1kje4fm._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/_1p0-leb._.js +0 -3
- package/.next/standalone/.next/static/chunks/0o0ut0ugd0_-s.js +0 -1
- package/.next/standalone/.next/static/chunks/0xl97x-874k-u.js +0 -1
- package/.next/standalone/.next/static/chunks/19d7hqx8udopz.js +0 -1
- package/.next/standalone/.next/static/chunks/36j05kb2x323i.css +0 -2
- package/.next/standalone/.next/static/chunks/370sj2lgkw5ey.js +0 -1
- package/.next/standalone/.next/static/chunks/3w7g0n0iwwnbs.js +0 -1
- package/.next/standalone/.next/static/chunks/42oeva1-w0z2d.js +0 -6
- /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{WQRKgSfFekLcC_pvyzp4S → nhn6Tt0--xZKdgVGIqR6E}/_ssgManifest.js +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// package.json
|
|
22
|
-
var version2 = "0.0.
|
|
22
|
+
var version2 = "0.0.15-beta.1";
|
|
23
23
|
var init_package = () => {};
|
|
24
24
|
|
|
25
25
|
// src/posthog-key.ts
|
|
@@ -156,7 +156,7 @@ var init_telemetry_id = __esm(() => {
|
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
// src/hooks/types.ts
|
|
159
|
-
var HOOK_SCOPES, INTEGRATION_TYPES, CODEX_HOOK_SCOPES, CODEX_HOOK_EVENT_TYPES, CODEX_EVENT_MAP, CODEX_TOOL_MAP, HERMES_TOOL_MAP, HERMES_TOOL_INPUT_MAP, HERMES_HOOK_SCOPES, HERMES_HOOK_EVENT_TYPES, HERMES_EVENT_MAP, COPILOT_HOOK_SCOPES, COPILOT_HOOK_EVENT_TYPES, COPILOT_TOOL_MAP, COPILOT_TOOL_INPUT_MAP, CURSOR_HOOK_SCOPES, CURSOR_HOOK_EVENT_TYPES, CURSOR_EVENT_MAP, CURSOR_TOOL_MAP, OPENCODE_HOOK_SCOPES, OPENCODE_HOOK_EVENT_TYPES, OPENCODE_TOOL_MAP, OPENCODE_TOOL_INPUT_MAP, PI_HOOK_SCOPES, PI_HOOK_EVENT_TYPES, PI_EVENT_MAP, PI_TOOL_MAP, PI_TOOL_INPUT_MAP, OPENCLAW_HOOK_SCOPES, OPENCLAW_HOOK_EVENT_TYPES, OPENCLAW_EVENT_MAP, OPENCLAW_TOOL_MAP, OPENCLAW_TOOL_INPUT_MAP, FACTORY_HOOK_SCOPES, FACTORY_HOOK_EVENT_TYPES, FACTORY_TOOL_MAP, DEVIN_HOOK_SCOPES, DEVIN_HOOK_EVENT_TYPES, DEVIN_TOOL_MAP, ANTIGRAVITY_HOOK_SCOPES, ANTIGRAVITY_HOOK_EVENT_TYPES, ANTIGRAVITY_EVENT_MAP, ANTIGRAVITY_TOOL_MAP, ANTIGRAVITY_TOOL_INPUT_MAP, GOOSE_HOOK_SCOPES, GOOSE_HOOK_EVENT_TYPES, GOOSE_TOOL_MAP, GOOSE_TOOL_INPUT_MAP, HOOK_EVENT_TYPES, FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
|
|
159
|
+
var HOOK_SCOPES, INTEGRATION_TYPES, CODEX_HOOK_SCOPES, CODEX_HOOK_EVENT_TYPES, CODEX_EVENT_MAP, CODEX_TOOL_MAP, HERMES_TOOL_MAP, HERMES_TOOL_INPUT_MAP, HERMES_HOOK_SCOPES, HERMES_HOOK_EVENT_TYPES, HERMES_EVENT_MAP, COPILOT_HOOK_SCOPES, COPILOT_HOOK_EVENT_TYPES, COPILOT_TOOL_MAP, COPILOT_TOOL_INPUT_MAP, CURSOR_HOOK_SCOPES, CURSOR_HOOK_EVENT_TYPES, CURSOR_EVENT_MAP, CURSOR_TOOL_MAP, OPENCODE_HOOK_SCOPES, OPENCODE_HOOK_EVENT_TYPES, OPENCODE_TOOL_MAP, OPENCODE_TOOL_INPUT_MAP, PI_HOOK_SCOPES, PI_HOOK_EVENT_TYPES, PI_EVENT_MAP, PI_TOOL_MAP, PI_TOOL_INPUT_MAP, OPENCLAW_HOOK_SCOPES, OPENCLAW_HOOK_EVENT_TYPES, OPENCLAW_EVENT_MAP, OPENCLAW_TOOL_MAP, OPENCLAW_TOOL_INPUT_MAP, FACTORY_HOOK_SCOPES, FACTORY_HOOK_EVENT_TYPES, FACTORY_TOOL_MAP, DEVIN_HOOK_SCOPES, DEVIN_HOOK_EVENT_TYPES, DEVIN_TOOL_MAP, ANTIGRAVITY_HOOK_SCOPES, ANTIGRAVITY_HOOK_EVENT_TYPES, ANTIGRAVITY_EVENT_MAP, ANTIGRAVITY_TOOL_MAP, ANTIGRAVITY_TOOL_INPUT_MAP, GOOSE_HOOK_SCOPES, GOOSE_HOOK_EVENT_TYPES, GOOSE_TOOL_MAP, GOOSE_TOOL_INPUT_MAP, HOOK_EVENT_TYPES, CLAUDE_INSTALL_EVENT_TYPES, FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
|
|
160
160
|
var init_types = __esm(() => {
|
|
161
161
|
HOOK_SCOPES = ["user", "project", "local"];
|
|
162
162
|
INTEGRATION_TYPES = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "hermes", "openclaw", "factory", "devin", "antigravity", "goose"];
|
|
@@ -516,6 +516,7 @@ var init_types = __esm(() => {
|
|
|
516
516
|
"PostToolBatch",
|
|
517
517
|
"Setup"
|
|
518
518
|
];
|
|
519
|
+
CLAUDE_INSTALL_EVENT_TYPES = HOOK_EVENT_TYPES.filter((e) => e !== "WorktreeCreate");
|
|
519
520
|
});
|
|
520
521
|
|
|
521
522
|
// src/hooks/tool-name-canonicalize.ts
|
|
@@ -668,6 +669,9 @@ var init_hook_logger = __esm(() => {
|
|
|
668
669
|
import { readFileSync, writeFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, statSync as statSync2 } from "node:fs";
|
|
669
670
|
import { resolve, dirname } from "node:path";
|
|
670
671
|
import { homedir as homedir2 } from "node:os";
|
|
672
|
+
function configuredCustomPolicyPaths(config) {
|
|
673
|
+
return config.customPoliciesPaths ?? (config.customPoliciesPath ? [config.customPoliciesPath] : []);
|
|
674
|
+
}
|
|
671
675
|
function readConfigAt(path2) {
|
|
672
676
|
if (!existsSync2(path2))
|
|
673
677
|
return {};
|
|
@@ -718,12 +722,20 @@ function readMergedHooksConfig(cwd) {
|
|
|
718
722
|
}
|
|
719
723
|
}
|
|
720
724
|
}
|
|
721
|
-
const
|
|
725
|
+
const customPoliciesPaths = [project, local, global_].map((scope) => scope.customPoliciesPaths !== undefined ? scope.customPoliciesPaths : scope.customPoliciesPath !== undefined ? [scope.customPoliciesPath] : undefined).find((paths) => paths !== undefined);
|
|
726
|
+
const disabledCustomPolicies = new Set([
|
|
727
|
+
...project.disabledCustomPolicies ?? [],
|
|
728
|
+
...local.disabledCustomPolicies ?? [],
|
|
729
|
+
...global_.disabledCustomPolicies ?? []
|
|
730
|
+
]);
|
|
731
|
+
const customPoliciesEnabled = project.customPoliciesEnabled ?? local.customPoliciesEnabled ?? global_.customPoliciesEnabled;
|
|
722
732
|
const llm = project.llm ?? local.llm ?? global_.llm;
|
|
723
733
|
return {
|
|
724
734
|
enabledPolicies: [...enabledSet],
|
|
725
735
|
...Object.keys(mergedParams).length > 0 ? { policyParams: mergedParams } : {},
|
|
726
|
-
...
|
|
736
|
+
...customPoliciesPaths !== undefined ? { customPoliciesPaths } : {},
|
|
737
|
+
...disabledCustomPolicies.size ? { disabledCustomPolicies: [...disabledCustomPolicies] } : {},
|
|
738
|
+
...customPoliciesEnabled !== undefined ? { customPoliciesEnabled } : {},
|
|
727
739
|
...llm !== undefined ? { llm } : {}
|
|
728
740
|
};
|
|
729
741
|
}
|
|
@@ -775,6 +787,31 @@ function writeScopedHooksConfig(config, scope, cwd) {
|
|
|
775
787
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + `
|
|
776
788
|
`, "utf8");
|
|
777
789
|
}
|
|
790
|
+
function syncConventionPolicies(entries, scope, cwd) {
|
|
791
|
+
const configPath = getConfigPathForScope(scope, cwd);
|
|
792
|
+
if (!existsSync2(configPath) && entries.length === 0)
|
|
793
|
+
return false;
|
|
794
|
+
if (existsSync2(configPath)) {
|
|
795
|
+
try {
|
|
796
|
+
JSON.parse(readFileSync(configPath, "utf8"));
|
|
797
|
+
} catch {
|
|
798
|
+
hookLogWarn(`not recording convention policies: ${configPath} is not valid JSON — ` + `fix the syntax error and re-run. Nothing was written.`);
|
|
799
|
+
return false;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
const config = readScopedHooksConfig(scope, cwd);
|
|
803
|
+
const sorted = [...entries].sort((a, b) => a.file.localeCompare(b.file));
|
|
804
|
+
const next = { ...config };
|
|
805
|
+
if (sorted.length === 0)
|
|
806
|
+
delete next.conventionPolicies;
|
|
807
|
+
else
|
|
808
|
+
next.conventionPolicies = sorted;
|
|
809
|
+
if (JSON.stringify(next.conventionPolicies ?? null) === JSON.stringify(config.conventionPolicies ?? null)) {
|
|
810
|
+
return false;
|
|
811
|
+
}
|
|
812
|
+
writeScopedHooksConfig(next, scope, cwd);
|
|
813
|
+
return true;
|
|
814
|
+
}
|
|
778
815
|
var init_hooks_config = __esm(() => {
|
|
779
816
|
init_hook_logger();
|
|
780
817
|
});
|
|
@@ -2752,6 +2789,16 @@ You MUST complete the above action NOW. Do NOT ask the user for confirmation —
|
|
|
2752
2789
|
decision: "deny"
|
|
2753
2790
|
};
|
|
2754
2791
|
}
|
|
2792
|
+
if (eventType === "UserPromptSubmit") {
|
|
2793
|
+
return {
|
|
2794
|
+
exitCode: 0,
|
|
2795
|
+
stdout: JSON.stringify({ continue: false, user_message: blockedMessage }),
|
|
2796
|
+
stderr: "",
|
|
2797
|
+
policyName: policy.name,
|
|
2798
|
+
reason,
|
|
2799
|
+
decision: "deny"
|
|
2800
|
+
};
|
|
2801
|
+
}
|
|
2755
2802
|
const response = {
|
|
2756
2803
|
permission: "deny",
|
|
2757
2804
|
user_message: blockedMessage,
|
|
@@ -2928,6 +2975,28 @@ You MUST complete the above action NOW. Do NOT ask the user for confirmation —
|
|
|
2928
2975
|
decision: "deny"
|
|
2929
2976
|
};
|
|
2930
2977
|
}
|
|
2978
|
+
if (session?.cli === "copilot") {
|
|
2979
|
+
if (eventType === "UserPromptSubmit") {
|
|
2980
|
+
return {
|
|
2981
|
+
exitCode: 0,
|
|
2982
|
+
stdout: JSON.stringify({ decision: "block", reason: blockedMessage }),
|
|
2983
|
+
stderr: "",
|
|
2984
|
+
policyName: policy.name,
|
|
2985
|
+
reason,
|
|
2986
|
+
decision: "deny"
|
|
2987
|
+
};
|
|
2988
|
+
}
|
|
2989
|
+
if (eventType === "PermissionRequest") {
|
|
2990
|
+
return {
|
|
2991
|
+
exitCode: 0,
|
|
2992
|
+
stdout: JSON.stringify({ behavior: "deny", message: blockedMessage }),
|
|
2993
|
+
stderr: "",
|
|
2994
|
+
policyName: policy.name,
|
|
2995
|
+
reason,
|
|
2996
|
+
decision: "deny"
|
|
2997
|
+
};
|
|
2998
|
+
}
|
|
2999
|
+
}
|
|
2931
3000
|
if (eventType === "PermissionRequest") {
|
|
2932
3001
|
const response = {
|
|
2933
3002
|
hookSpecificOutput: {
|
|
@@ -3528,7 +3597,7 @@ async function loadSingleFile(absPath, opts) {
|
|
|
3528
3597
|
const distUrl = distIndex ? pathToFileURL2(distIndex).href : null;
|
|
3529
3598
|
tmpFiles = await rewriteFileTree(absPath, distUrl, distIndex);
|
|
3530
3599
|
const entryTmp = absPath + TMP_SUFFIX;
|
|
3531
|
-
const fileUrl = pathToFileURL2(entryTmp).href
|
|
3600
|
+
const fileUrl = `${pathToFileURL2(entryTmp).href}?v=${++loadSequence}`;
|
|
3532
3601
|
await import(fileUrl);
|
|
3533
3602
|
} catch (err) {
|
|
3534
3603
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -3561,6 +3630,12 @@ async function loadCustomHooks(customPoliciesPath, opts) {
|
|
|
3561
3630
|
await loadSingleFile(absPath, opts);
|
|
3562
3631
|
return getCustomHooks();
|
|
3563
3632
|
}
|
|
3633
|
+
function customPolicyId(file, name) {
|
|
3634
|
+
return `custom:${file}:${name}`;
|
|
3635
|
+
}
|
|
3636
|
+
function conventionPolicyId(scope, file, name) {
|
|
3637
|
+
return `convention:${scope}:${file}:${name}`;
|
|
3638
|
+
}
|
|
3564
3639
|
function warnSkippedPolicyFiles(dir, scope) {
|
|
3565
3640
|
const skipped = findSkippedPolicyFiles(dir);
|
|
3566
3641
|
if (skipped.length === 0)
|
|
@@ -3568,28 +3643,40 @@ function warnSkippedPolicyFiles(dir, scope) {
|
|
|
3568
3643
|
const suggest = (n) => n.replace(/\.(js|mjs|ts)$/, "-policies.$1");
|
|
3569
3644
|
hookLogWarn(`${scope} policies: ${skipped.length} file(s) in ${dir} are NOT loaded — ` + `the convention only loads names ending in "policies.js|mjs|ts". ` + skipped.map((n) => `${n} → rename to ${suggest(n)}`).join("; "));
|
|
3570
3645
|
}
|
|
3571
|
-
async function loadAllCustomHooks(
|
|
3646
|
+
async function loadAllCustomHooks(customPoliciesPaths, opts) {
|
|
3572
3647
|
clearCustomHooks();
|
|
3573
3648
|
const conventionSources = [];
|
|
3574
3649
|
const projectRoot = findProjectConfigDir(opts?.sessionCwd ?? process.cwd());
|
|
3575
3650
|
const conventionEnabled = opts?.customPoliciesEnabled !== false;
|
|
3576
|
-
|
|
3577
|
-
|
|
3651
|
+
const loadedPaths = new Set;
|
|
3652
|
+
for (const customPoliciesPath of typeof customPoliciesPaths === "string" ? [customPoliciesPaths] : customPoliciesPaths ?? []) {
|
|
3653
|
+
const absPath = resolve4(projectRoot, customPoliciesPath);
|
|
3578
3654
|
if (existsSync3(absPath)) {
|
|
3579
|
-
|
|
3655
|
+
if (!loadedPaths.has(absPath)) {
|
|
3656
|
+
loadedPaths.add(absPath);
|
|
3657
|
+
const hooksBefore = getCustomHooks().length;
|
|
3658
|
+
await loadSingleFile(absPath);
|
|
3659
|
+
for (const hook of getCustomHooks().slice(hooksBefore)) {
|
|
3660
|
+
hook.__policyId = customPolicyId(absPath, hook.name);
|
|
3661
|
+
}
|
|
3662
|
+
}
|
|
3580
3663
|
} else {
|
|
3581
|
-
hookLogWarn(`
|
|
3664
|
+
hookLogWarn(`custom policy path not found: ${absPath}`);
|
|
3582
3665
|
}
|
|
3583
3666
|
}
|
|
3584
3667
|
const hooksBeforeConvention = getCustomHooks().length;
|
|
3585
3668
|
const projectDir = resolve4(projectRoot, ".failproofai", "policies");
|
|
3586
3669
|
if (conventionEnabled)
|
|
3587
3670
|
warnSkippedPolicyFiles(projectDir, "project");
|
|
3588
|
-
const projectFiles = conventionEnabled ? discoverPolicyFiles(projectDir) : [];
|
|
3671
|
+
const projectFiles = conventionEnabled ? discoverPolicyFiles(projectDir).filter((f) => !loadedPaths.has(f)) : [];
|
|
3589
3672
|
for (const file of projectFiles) {
|
|
3673
|
+
loadedPaths.add(file);
|
|
3590
3674
|
const hooksBefore = getCustomHooks().length;
|
|
3591
3675
|
await loadSingleFile(file, { conventionScope: "project" });
|
|
3592
3676
|
const newHooks = getCustomHooks().slice(hooksBefore);
|
|
3677
|
+
for (const hook of newHooks) {
|
|
3678
|
+
hook.__policyId = conventionPolicyId("project", basename(file), hook.name);
|
|
3679
|
+
}
|
|
3593
3680
|
if (newHooks.length > 0) {
|
|
3594
3681
|
conventionSources.push({
|
|
3595
3682
|
scope: "project",
|
|
@@ -3599,13 +3686,17 @@ async function loadAllCustomHooks(customPoliciesPath, opts) {
|
|
|
3599
3686
|
}
|
|
3600
3687
|
}
|
|
3601
3688
|
const userDir = resolve4(homedir4(), ".failproofai", "policies");
|
|
3602
|
-
if (conventionEnabled)
|
|
3689
|
+
if (conventionEnabled && userDir !== projectDir)
|
|
3603
3690
|
warnSkippedPolicyFiles(userDir, "user");
|
|
3604
|
-
const userFiles = conventionEnabled ? discoverPolicyFiles(userDir) : [];
|
|
3691
|
+
const userFiles = conventionEnabled && userDir !== projectDir ? discoverPolicyFiles(userDir).filter((f) => !loadedPaths.has(f)) : [];
|
|
3605
3692
|
for (const file of userFiles) {
|
|
3693
|
+
loadedPaths.add(file);
|
|
3606
3694
|
const hooksBefore = getCustomHooks().length;
|
|
3607
3695
|
await loadSingleFile(file, { conventionScope: "user" });
|
|
3608
3696
|
const newHooks = getCustomHooks().slice(hooksBefore);
|
|
3697
|
+
for (const hook of newHooks) {
|
|
3698
|
+
hook.__policyId = conventionPolicyId("user", basename(file), hook.name);
|
|
3699
|
+
}
|
|
3609
3700
|
if (newHooks.length > 0) {
|
|
3610
3701
|
conventionSources.push({
|
|
3611
3702
|
scope: "user",
|
|
@@ -3638,7 +3729,7 @@ async function loadAllCustomHooks(customPoliciesPath, opts) {
|
|
|
3638
3729
|
}
|
|
3639
3730
|
return { hooks: allHooks, conventionSources };
|
|
3640
3731
|
}
|
|
3641
|
-
var LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__", CONVENTION_FILE_RE, LOADABLE_EXT_RE;
|
|
3732
|
+
var LOADING_KEY = "__FAILPROOFAI_LOADING_HOOKS__", CONVENTION_FILE_RE, loadSequence = 0, LOADABLE_EXT_RE;
|
|
3642
3733
|
var init_custom_hooks_loader = __esm(() => {
|
|
3643
3734
|
init_hook_logger();
|
|
3644
3735
|
init_custom_hooks_registry();
|
|
@@ -4856,6 +4947,65 @@ async function openSqliteReadonly(dbPath) {
|
|
|
4856
4947
|
var sqlPromise = null;
|
|
4857
4948
|
var init_sqlite_reader = () => {};
|
|
4858
4949
|
|
|
4950
|
+
// lib/hermes-profiles.ts
|
|
4951
|
+
import { readdirSync as readdirSync3 } from "node:fs";
|
|
4952
|
+
import { homedir as homedir11 } from "node:os";
|
|
4953
|
+
import { basename as basename2, dirname as dirname3, join as join9, resolve as resolve5 } from "node:path";
|
|
4954
|
+
function hermesRoot() {
|
|
4955
|
+
const env = (process.env.HERMES_HOME || "").trim();
|
|
4956
|
+
if (env) {
|
|
4957
|
+
const home = resolve5(env);
|
|
4958
|
+
const parent = dirname3(home);
|
|
4959
|
+
if (basename2(parent) === PROFILES_DIR)
|
|
4960
|
+
return dirname3(parent);
|
|
4961
|
+
return home;
|
|
4962
|
+
}
|
|
4963
|
+
return join9(homedir11(), ".hermes");
|
|
4964
|
+
}
|
|
4965
|
+
function listHermesProfiles() {
|
|
4966
|
+
const root = hermesRoot();
|
|
4967
|
+
const out = [{ name: HERMES_DEFAULT_PROFILE, home: root }];
|
|
4968
|
+
const seen = new Set([HERMES_DEFAULT_PROFILE]);
|
|
4969
|
+
let names;
|
|
4970
|
+
try {
|
|
4971
|
+
names = readdirSync3(join9(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
4972
|
+
} catch {
|
|
4973
|
+
return out;
|
|
4974
|
+
}
|
|
4975
|
+
for (const name of names) {
|
|
4976
|
+
if (seen.has(name))
|
|
4977
|
+
continue;
|
|
4978
|
+
seen.add(name);
|
|
4979
|
+
out.push({ name, home: join9(root, PROFILES_DIR, name) });
|
|
4980
|
+
}
|
|
4981
|
+
return out;
|
|
4982
|
+
}
|
|
4983
|
+
function hermesProjectName(profile, source) {
|
|
4984
|
+
return `hermes-${profile}-${source}`;
|
|
4985
|
+
}
|
|
4986
|
+
function hermesProjectPath(profile, source) {
|
|
4987
|
+
return `hermes:${profile}:${source}`;
|
|
4988
|
+
}
|
|
4989
|
+
function hermesProjectNameCandidates(name) {
|
|
4990
|
+
if (!name.startsWith("hermes-"))
|
|
4991
|
+
return [];
|
|
4992
|
+
const rest = name.slice("hermes-".length);
|
|
4993
|
+
if (!rest)
|
|
4994
|
+
return [];
|
|
4995
|
+
const out = [];
|
|
4996
|
+
const profiles = listHermesProfiles().map((p) => p.name).sort((a, b) => b.length - a.length);
|
|
4997
|
+
for (const profile of profiles) {
|
|
4998
|
+
const prefix = `${profile}-`;
|
|
4999
|
+
if (rest.startsWith(prefix) && rest.length > prefix.length) {
|
|
5000
|
+
out.push({ profile, source: rest.slice(prefix.length) });
|
|
5001
|
+
}
|
|
5002
|
+
}
|
|
5003
|
+
out.push({ profile: HERMES_DEFAULT_PROFILE, source: rest });
|
|
5004
|
+
return out;
|
|
5005
|
+
}
|
|
5006
|
+
var PROFILES_DIR = "profiles", HERMES_DEFAULT_PROFILE = "default";
|
|
5007
|
+
var init_hermes_profiles = () => {};
|
|
5008
|
+
|
|
4859
5009
|
// lib/format-duration.ts
|
|
4860
5010
|
function formatDuration(ms) {
|
|
4861
5011
|
if (ms < 1000)
|
|
@@ -4877,10 +5027,15 @@ function formatDuration(ms) {
|
|
|
4877
5027
|
}
|
|
4878
5028
|
|
|
4879
5029
|
// lib/hermes-sessions.ts
|
|
4880
|
-
import {
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
|
|
5030
|
+
import { join as join10 } from "node:path";
|
|
5031
|
+
function hermesDbPaths() {
|
|
5032
|
+
const override = process.env.HERMES_DB_PATH;
|
|
5033
|
+
if (override)
|
|
5034
|
+
return [{ profile: HERMES_DEFAULT_PROFILE, dbPath: override }];
|
|
5035
|
+
return listHermesProfiles().map((p) => ({
|
|
5036
|
+
profile: p.name,
|
|
5037
|
+
dbPath: join10(p.home, "state.db")
|
|
5038
|
+
}));
|
|
4884
5039
|
}
|
|
4885
5040
|
function epochToMs(value) {
|
|
4886
5041
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -5011,7 +5166,15 @@ function hermesRowsToLogEntries(rows, source = "session") {
|
|
|
5011
5166
|
async function getHermesSessionLog(sessionId) {
|
|
5012
5167
|
if (!sessionId || !/^[A-Za-z0-9_-]+$/.test(sessionId))
|
|
5013
5168
|
return null;
|
|
5014
|
-
const
|
|
5169
|
+
for (const { profile, dbPath } of hermesDbPaths()) {
|
|
5170
|
+
const found = await loadFromDb(dbPath, profile, sessionId);
|
|
5171
|
+
if (found)
|
|
5172
|
+
return found;
|
|
5173
|
+
}
|
|
5174
|
+
return null;
|
|
5175
|
+
}
|
|
5176
|
+
async function loadFromDb(dbPath, profile, sessionId) {
|
|
5177
|
+
const db = await openSqliteReadonly(dbPath);
|
|
5015
5178
|
if (!db)
|
|
5016
5179
|
return null;
|
|
5017
5180
|
try {
|
|
@@ -5021,12 +5184,13 @@ async function getHermesSessionLog(sessionId) {
|
|
|
5021
5184
|
const { source, cwd: realCwd } = sessionRows[0];
|
|
5022
5185
|
const msgRows = db.query("SELECT id, role, content, tool_call_id, tool_calls, tool_name, timestamp " + "FROM messages WHERE session_id = ? ORDER BY timestamp ASC", [sessionId]);
|
|
5023
5186
|
const entries = hermesRowsToLogEntries(msgRows, "session");
|
|
5024
|
-
const cwd = realCwd && realCwd.length > 0 ? realCwd : source ?
|
|
5187
|
+
const cwd = realCwd && realCwd.length > 0 ? realCwd : source ? hermesProjectPath(profile, source) : undefined;
|
|
5025
5188
|
return {
|
|
5026
5189
|
entries,
|
|
5027
5190
|
rawLines: msgRows,
|
|
5028
5191
|
cwd,
|
|
5029
|
-
filePath: `hermes://${sessionId}
|
|
5192
|
+
filePath: `hermes://${sessionId}`,
|
|
5193
|
+
profile
|
|
5030
5194
|
};
|
|
5031
5195
|
} catch {
|
|
5032
5196
|
return null;
|
|
@@ -5037,6 +5201,7 @@ async function getHermesSessionLog(sessionId) {
|
|
|
5037
5201
|
var getCachedHermesSessionLog;
|
|
5038
5202
|
var init_hermes_sessions = __esm(() => {
|
|
5039
5203
|
init_sqlite_reader();
|
|
5204
|
+
init_hermes_profiles();
|
|
5040
5205
|
init_log_entries();
|
|
5041
5206
|
getCachedHermesSessionLog = runtimeCache((sessionId) => getHermesSessionLog(sessionId), 2, { maxSize: 50 });
|
|
5042
5207
|
});
|
|
@@ -5052,13 +5217,22 @@ __export(exports_hermes_projects, {
|
|
|
5052
5217
|
getCachedHermesProjects: () => getCachedHermesProjects
|
|
5053
5218
|
});
|
|
5054
5219
|
async function getHermesSessions() {
|
|
5055
|
-
const
|
|
5220
|
+
const out = [];
|
|
5221
|
+
for (const { profile, dbPath } of hermesDbPaths()) {
|
|
5222
|
+
out.push(...await readSessionsFromDb(dbPath, profile));
|
|
5223
|
+
}
|
|
5224
|
+
out.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
5225
|
+
return out;
|
|
5226
|
+
}
|
|
5227
|
+
async function readSessionsFromDb(dbPath, profile) {
|
|
5228
|
+
const db = await openSqliteReadonly(dbPath);
|
|
5056
5229
|
if (!db)
|
|
5057
5230
|
return [];
|
|
5058
5231
|
try {
|
|
5059
5232
|
const rows = db.query("SELECT s.id, s.source, s.cwd, s.title, s.user_id, s.chat_id, s.chat_type, " + "s.started_at, s.ended_at, s.message_count, lm.last_activity " + "FROM sessions s " + "LEFT JOIN (SELECT session_id, MAX(timestamp) AS last_activity FROM messages GROUP BY session_id) lm " + "ON lm.session_id = s.id " + "ORDER BY lm.last_activity DESC");
|
|
5060
5233
|
return rows.map((r) => ({
|
|
5061
5234
|
sessionId: r.id,
|
|
5235
|
+
profile,
|
|
5062
5236
|
source: r.source ?? undefined,
|
|
5063
5237
|
cwd: r.cwd ?? undefined,
|
|
5064
5238
|
title: r.title ?? undefined,
|
|
@@ -5077,36 +5251,58 @@ async function getHermesSessions() {
|
|
|
5077
5251
|
}
|
|
5078
5252
|
async function getHermesProjects() {
|
|
5079
5253
|
const sessions = await getHermesSessions();
|
|
5080
|
-
const
|
|
5254
|
+
const groups = new Map;
|
|
5081
5255
|
for (const s of sessions) {
|
|
5082
5256
|
if (s.messageCount <= 0 && !s.hasMessages)
|
|
5083
5257
|
continue;
|
|
5084
|
-
const
|
|
5085
|
-
|
|
5258
|
+
const profile = s.profile || HERMES_DEFAULT_PROFILE;
|
|
5259
|
+
const source = s.source ?? "unknown";
|
|
5260
|
+
const key = JSON.stringify([profile, source]);
|
|
5261
|
+
const prev = groups.get(key);
|
|
5262
|
+
if (prev) {
|
|
5263
|
+
prev.latest = Math.max(prev.latest, s.mtimeMs);
|
|
5264
|
+
prev.count += 1;
|
|
5265
|
+
} else {
|
|
5266
|
+
groups.set(key, { profile, source, latest: s.mtimeMs, count: 1 });
|
|
5267
|
+
}
|
|
5086
5268
|
}
|
|
5087
5269
|
const out = [];
|
|
5088
|
-
for (const
|
|
5270
|
+
for (const { profile, source, latest, count } of groups.values()) {
|
|
5089
5271
|
const lastModified = new Date(latest);
|
|
5090
5272
|
out.push({
|
|
5091
|
-
name:
|
|
5092
|
-
path:
|
|
5273
|
+
name: hermesProjectName(profile, source),
|
|
5274
|
+
path: hermesProjectPath(profile, source),
|
|
5093
5275
|
isDirectory: true,
|
|
5094
5276
|
lastModified,
|
|
5095
5277
|
lastModifiedFormatted: formatDate(lastModified),
|
|
5096
|
-
cli: ["hermes"]
|
|
5278
|
+
cli: ["hermes"],
|
|
5279
|
+
sessionCount: count
|
|
5097
5280
|
});
|
|
5098
5281
|
}
|
|
5099
5282
|
out.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
5100
5283
|
return out;
|
|
5101
5284
|
}
|
|
5102
5285
|
async function getHermesSessionsByEncodedName(name) {
|
|
5103
|
-
|
|
5286
|
+
const candidates = hermesProjectNameCandidates(name);
|
|
5287
|
+
if (candidates.length === 0)
|
|
5104
5288
|
return { cwd: null, sessions: [] };
|
|
5105
|
-
const source = name.slice("hermes-".length);
|
|
5106
5289
|
const sessions = await getHermesSessions();
|
|
5107
|
-
const
|
|
5290
|
+
const matching = (split) => sessions.filter((s) => (s.messageCount > 0 || s.hasMessages) && (s.profile || HERMES_DEFAULT_PROFILE) === split.profile && (s.source ?? "unknown") === split.source);
|
|
5291
|
+
let chosen = candidates[0];
|
|
5292
|
+
let matched = matching(chosen);
|
|
5293
|
+
if (matched.length === 0) {
|
|
5294
|
+
for (const candidate of candidates.slice(1)) {
|
|
5295
|
+
const hits = matching(candidate);
|
|
5296
|
+
if (hits.length > 0) {
|
|
5297
|
+
chosen = candidate;
|
|
5298
|
+
matched = hits;
|
|
5299
|
+
break;
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
}
|
|
5303
|
+
const { profile, source } = chosen;
|
|
5108
5304
|
return {
|
|
5109
|
-
cwd:
|
|
5305
|
+
cwd: hermesProjectPath(profile, source),
|
|
5110
5306
|
sessions: matched.map((s) => {
|
|
5111
5307
|
const lastModified = new Date(s.mtimeMs);
|
|
5112
5308
|
return {
|
|
@@ -5127,6 +5323,7 @@ var getCachedHermesSessions, getCachedHermesProjects, getCachedHermesSessionsByE
|
|
|
5127
5323
|
var init_hermes_projects = __esm(() => {
|
|
5128
5324
|
init_sqlite_reader();
|
|
5129
5325
|
init_hermes_sessions();
|
|
5326
|
+
init_hermes_profiles();
|
|
5130
5327
|
getCachedHermesSessions = runtimeCache(getHermesSessions, 2);
|
|
5131
5328
|
getCachedHermesProjects = runtimeCache(getHermesProjects, 2);
|
|
5132
5329
|
getCachedHermesSessionsByEncodedName = runtimeCache((name) => getHermesSessionsByEncodedName(name), 2, { maxSize: 50 });
|
|
@@ -5134,11 +5331,11 @@ var init_hermes_projects = __esm(() => {
|
|
|
5134
5331
|
|
|
5135
5332
|
// lib/openclaw-sessions.ts
|
|
5136
5333
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
5137
|
-
import { readdirSync as
|
|
5334
|
+
import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
|
|
5138
5335
|
import { homedir as homedir12 } from "node:os";
|
|
5139
|
-
import { join as
|
|
5336
|
+
import { join as join11 } from "node:path";
|
|
5140
5337
|
function openclawHome() {
|
|
5141
|
-
return process.env.OPENCLAW_HOME ||
|
|
5338
|
+
return process.env.OPENCLAW_HOME || join11(homedir12(), ".openclaw");
|
|
5142
5339
|
}
|
|
5143
5340
|
function isPlainObject2(v) {
|
|
5144
5341
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -5251,20 +5448,27 @@ function openclawLinesToLogEntries(lines, source = "session") {
|
|
|
5251
5448
|
entries.sort((a, b) => a.timestampMs - b.timestampMs);
|
|
5252
5449
|
return entries;
|
|
5253
5450
|
}
|
|
5451
|
+
function listOpenClawAgents() {
|
|
5452
|
+
try {
|
|
5453
|
+
return readdirSync4(join11(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
|
|
5454
|
+
} catch {
|
|
5455
|
+
return [];
|
|
5456
|
+
}
|
|
5457
|
+
}
|
|
5254
5458
|
function listOpenClawTranscripts() {
|
|
5255
|
-
const agentsDir =
|
|
5459
|
+
const agentsDir = join11(openclawHome(), "agents");
|
|
5256
5460
|
const out = [];
|
|
5257
5461
|
let agentIds;
|
|
5258
5462
|
try {
|
|
5259
|
-
agentIds =
|
|
5463
|
+
agentIds = readdirSync4(agentsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
5260
5464
|
} catch {
|
|
5261
5465
|
return out;
|
|
5262
5466
|
}
|
|
5263
5467
|
for (const agentId of agentIds) {
|
|
5264
|
-
const sessionsDir =
|
|
5468
|
+
const sessionsDir = join11(agentsDir, agentId, "sessions");
|
|
5265
5469
|
let files;
|
|
5266
5470
|
try {
|
|
5267
|
-
files =
|
|
5471
|
+
files = readdirSync4(sessionsDir);
|
|
5268
5472
|
} catch {
|
|
5269
5473
|
continue;
|
|
5270
5474
|
}
|
|
@@ -5274,7 +5478,7 @@ function listOpenClawTranscripts() {
|
|
|
5274
5478
|
const sessionId = file.slice(0, -".jsonl".length);
|
|
5275
5479
|
if (!OPENCLAW_SESSION_ID_RE.test(sessionId))
|
|
5276
5480
|
continue;
|
|
5277
|
-
const transcriptPath =
|
|
5481
|
+
const transcriptPath = join11(sessionsDir, file);
|
|
5278
5482
|
try {
|
|
5279
5483
|
const st = statSync4(transcriptPath);
|
|
5280
5484
|
out.push({ agentId, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
|
|
@@ -5323,6 +5527,10 @@ var init_openclaw_sessions = __esm(() => {
|
|
|
5323
5527
|
// lib/openclaw-projects.ts
|
|
5324
5528
|
var exports_openclaw_projects = {};
|
|
5325
5529
|
__export(exports_openclaw_projects, {
|
|
5530
|
+
parseOpenClawProjectName: () => parseOpenClawProjectName,
|
|
5531
|
+
openClawProjectPath: () => openClawProjectPath,
|
|
5532
|
+
openClawProjectNameCandidates: () => openClawProjectNameCandidates,
|
|
5533
|
+
openClawProjectName: () => openClawProjectName,
|
|
5326
5534
|
getOpenClawSessionsByEncodedName: () => getOpenClawSessionsByEncodedName,
|
|
5327
5535
|
getOpenClawSessions: () => getOpenClawSessions,
|
|
5328
5536
|
getOpenClawProjects: () => getOpenClawProjects,
|
|
@@ -5331,13 +5539,13 @@ __export(exports_openclaw_projects, {
|
|
|
5331
5539
|
getCachedOpenClawProjects: () => getCachedOpenClawProjects
|
|
5332
5540
|
});
|
|
5333
5541
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
5334
|
-
import { join as
|
|
5542
|
+
import { join as join12 } from "node:path";
|
|
5335
5543
|
function str(v) {
|
|
5336
5544
|
return typeof v === "string" && v.length > 0 ? v : undefined;
|
|
5337
5545
|
}
|
|
5338
5546
|
function readSessionsIndex(agentId) {
|
|
5339
5547
|
const out = new Map;
|
|
5340
|
-
const indexPath =
|
|
5548
|
+
const indexPath = join12(openclawHome(), "agents", agentId, "sessions", "sessions.json");
|
|
5341
5549
|
let raw;
|
|
5342
5550
|
try {
|
|
5343
5551
|
raw = JSON.parse(readFileSync4(indexPath, "utf-8"));
|
|
@@ -5383,6 +5591,7 @@ async function getOpenClawSessions() {
|
|
|
5383
5591
|
label: meta?.label,
|
|
5384
5592
|
chatType: meta?.chatType,
|
|
5385
5593
|
chatId: meta?.chatId,
|
|
5594
|
+
transcriptPath: t.transcriptPath,
|
|
5386
5595
|
mtimeMs: meta?.lastMs ?? t.mtimeMs,
|
|
5387
5596
|
sizeBytes: t.sizeBytes
|
|
5388
5597
|
});
|
|
@@ -5390,35 +5599,82 @@ async function getOpenClawSessions() {
|
|
|
5390
5599
|
refs.sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
5391
5600
|
return refs;
|
|
5392
5601
|
}
|
|
5602
|
+
function openClawProjectName(agentId, channel) {
|
|
5603
|
+
return `openclaw-${agentId}-${channel}`;
|
|
5604
|
+
}
|
|
5605
|
+
function openClawProjectPath(agentId, channel) {
|
|
5606
|
+
return `openclaw:${agentId}:${channel}`;
|
|
5607
|
+
}
|
|
5608
|
+
function openClawProjectNameCandidates(name) {
|
|
5609
|
+
if (!name.startsWith("openclaw-"))
|
|
5610
|
+
return [];
|
|
5611
|
+
const rest = name.slice("openclaw-".length);
|
|
5612
|
+
if (!rest)
|
|
5613
|
+
return [];
|
|
5614
|
+
const out = [];
|
|
5615
|
+
const agents = listOpenClawAgents().sort((a, b) => b.length - a.length);
|
|
5616
|
+
for (const agentId of agents) {
|
|
5617
|
+
const prefix = `${agentId}-`;
|
|
5618
|
+
if (rest.startsWith(prefix) && rest.length > prefix.length) {
|
|
5619
|
+
out.push({ agentId, channel: rest.slice(prefix.length) });
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5622
|
+
out.push({ agentId: null, channel: rest });
|
|
5623
|
+
return out;
|
|
5624
|
+
}
|
|
5625
|
+
function parseOpenClawProjectName(name) {
|
|
5626
|
+
return openClawProjectNameCandidates(name)[0] ?? null;
|
|
5627
|
+
}
|
|
5393
5628
|
async function getOpenClawProjects() {
|
|
5394
5629
|
const sessions = await getOpenClawSessions();
|
|
5395
|
-
const
|
|
5630
|
+
const groups = new Map;
|
|
5396
5631
|
for (const s of sessions) {
|
|
5397
|
-
|
|
5632
|
+
const key = JSON.stringify([s.agentId, s.channel]);
|
|
5633
|
+
const prev = groups.get(key);
|
|
5634
|
+
if (prev) {
|
|
5635
|
+
prev.latest = Math.max(prev.latest, s.mtimeMs);
|
|
5636
|
+
prev.count += 1;
|
|
5637
|
+
} else {
|
|
5638
|
+
groups.set(key, { agentId: s.agentId, channel: s.channel, latest: s.mtimeMs, count: 1 });
|
|
5639
|
+
}
|
|
5398
5640
|
}
|
|
5399
5641
|
const out = [];
|
|
5400
|
-
for (const
|
|
5642
|
+
for (const { agentId, channel, latest, count } of groups.values()) {
|
|
5401
5643
|
const lastModified = new Date(latest);
|
|
5402
5644
|
out.push({
|
|
5403
|
-
name:
|
|
5404
|
-
path:
|
|
5645
|
+
name: openClawProjectName(agentId, channel),
|
|
5646
|
+
path: openClawProjectPath(agentId, channel),
|
|
5405
5647
|
isDirectory: true,
|
|
5406
5648
|
lastModified,
|
|
5407
5649
|
lastModifiedFormatted: formatDate(lastModified),
|
|
5408
|
-
cli: ["openclaw"]
|
|
5650
|
+
cli: ["openclaw"],
|
|
5651
|
+
sessionCount: count
|
|
5409
5652
|
});
|
|
5410
5653
|
}
|
|
5411
5654
|
out.sort((a, b) => b.lastModified.getTime() - a.lastModified.getTime());
|
|
5412
5655
|
return out;
|
|
5413
5656
|
}
|
|
5414
5657
|
async function getOpenClawSessionsByEncodedName(name) {
|
|
5415
|
-
|
|
5658
|
+
const candidates = openClawProjectNameCandidates(name);
|
|
5659
|
+
if (candidates.length === 0)
|
|
5416
5660
|
return { cwd: null, sessions: [] };
|
|
5417
|
-
const channel = name.slice("openclaw-".length);
|
|
5418
5661
|
const sessions = await getOpenClawSessions();
|
|
5419
|
-
const
|
|
5662
|
+
const matching = (split) => sessions.filter((s) => s.channel === split.channel && (split.agentId === null || s.agentId === split.agentId));
|
|
5663
|
+
let chosen = candidates[0];
|
|
5664
|
+
let matched = matching(chosen);
|
|
5665
|
+
if (matched.length === 0) {
|
|
5666
|
+
for (const candidate of candidates.slice(1)) {
|
|
5667
|
+
const hits = matching(candidate);
|
|
5668
|
+
if (hits.length > 0) {
|
|
5669
|
+
chosen = candidate;
|
|
5670
|
+
matched = hits;
|
|
5671
|
+
break;
|
|
5672
|
+
}
|
|
5673
|
+
}
|
|
5674
|
+
}
|
|
5675
|
+
const { agentId, channel } = chosen;
|
|
5420
5676
|
return {
|
|
5421
|
-
cwd: `openclaw:${channel}
|
|
5677
|
+
cwd: agentId === null ? `openclaw:${channel}` : openClawProjectPath(agentId, channel),
|
|
5422
5678
|
sessions: matched.map((s) => {
|
|
5423
5679
|
const lastModified = new Date(s.mtimeMs);
|
|
5424
5680
|
return {
|
|
@@ -5444,14 +5700,14 @@ var init_openclaw_projects = __esm(() => {
|
|
|
5444
5700
|
|
|
5445
5701
|
// lib/factory-sessions.ts
|
|
5446
5702
|
import { readFile as readFile7 } from "node:fs/promises";
|
|
5447
|
-
import { readdirSync as
|
|
5703
|
+
import { readdirSync as readdirSync5, statSync as statSync5 } from "node:fs";
|
|
5448
5704
|
import { homedir as homedir13 } from "node:os";
|
|
5449
|
-
import { join as
|
|
5705
|
+
import { join as join13 } from "node:path";
|
|
5450
5706
|
function factoryHome() {
|
|
5451
|
-
return process.env.FACTORY_HOME ||
|
|
5707
|
+
return process.env.FACTORY_HOME || join13(homedir13(), ".factory");
|
|
5452
5708
|
}
|
|
5453
5709
|
function factorySessionsRoot() {
|
|
5454
|
-
return
|
|
5710
|
+
return join13(factoryHome(), "sessions");
|
|
5455
5711
|
}
|
|
5456
5712
|
function isPlainObject3(v) {
|
|
5457
5713
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -5590,17 +5846,17 @@ function listFactoryTranscripts() {
|
|
|
5590
5846
|
const out = [];
|
|
5591
5847
|
let projectDirs;
|
|
5592
5848
|
try {
|
|
5593
|
-
projectDirs =
|
|
5849
|
+
projectDirs = readdirSync5(root, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
5594
5850
|
} catch {
|
|
5595
5851
|
return out;
|
|
5596
5852
|
}
|
|
5597
5853
|
for (const dir of projectDirs) {
|
|
5598
5854
|
const projectName = dir.name;
|
|
5599
5855
|
const cwd = decodeFolderName(projectName);
|
|
5600
|
-
const projectPath =
|
|
5856
|
+
const projectPath = join13(root, projectName);
|
|
5601
5857
|
let files;
|
|
5602
5858
|
try {
|
|
5603
|
-
files =
|
|
5859
|
+
files = readdirSync5(projectPath);
|
|
5604
5860
|
} catch {
|
|
5605
5861
|
continue;
|
|
5606
5862
|
}
|
|
@@ -5610,7 +5866,7 @@ function listFactoryTranscripts() {
|
|
|
5610
5866
|
const sessionId = file.slice(0, -".jsonl".length);
|
|
5611
5867
|
if (!FACTORY_SESSION_ID_RE.test(sessionId))
|
|
5612
5868
|
continue;
|
|
5613
|
-
const transcriptPath =
|
|
5869
|
+
const transcriptPath = join13(projectPath, file);
|
|
5614
5870
|
try {
|
|
5615
5871
|
const st = statSync5(transcriptPath);
|
|
5616
5872
|
out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
|
|
@@ -5737,12 +5993,12 @@ var init_factory_projects = __esm(() => {
|
|
|
5737
5993
|
|
|
5738
5994
|
// lib/devin-sessions.ts
|
|
5739
5995
|
import { homedir as homedir14 } from "node:os";
|
|
5740
|
-
import { join as
|
|
5996
|
+
import { join as join14 } from "node:path";
|
|
5741
5997
|
function devinHome() {
|
|
5742
|
-
return process.env.DEVIN_HOME ||
|
|
5998
|
+
return process.env.DEVIN_HOME || join14(homedir14(), ".local", "share", "devin");
|
|
5743
5999
|
}
|
|
5744
6000
|
function devinDbPath() {
|
|
5745
|
-
return process.env.DEVIN_DB_PATH ||
|
|
6001
|
+
return process.env.DEVIN_DB_PATH || join14(devinHome(), "cli", "sessions.db");
|
|
5746
6002
|
}
|
|
5747
6003
|
function devinEpochToMs(value) {
|
|
5748
6004
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -6039,17 +6295,17 @@ var init_devin_projects = __esm(() => {
|
|
|
6039
6295
|
|
|
6040
6296
|
// lib/antigravity-sessions.ts
|
|
6041
6297
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
6042
|
-
import { readdirSync as
|
|
6298
|
+
import { readdirSync as readdirSync6, statSync as statSync6 } from "node:fs";
|
|
6043
6299
|
import { homedir as homedir15 } from "node:os";
|
|
6044
|
-
import { join as
|
|
6300
|
+
import { join as join15 } from "node:path";
|
|
6045
6301
|
function antigravityHome() {
|
|
6046
|
-
return process.env.ANTIGRAVITY_HOME ||
|
|
6302
|
+
return process.env.ANTIGRAVITY_HOME || join15(homedir15(), ".gemini", "antigravity-cli");
|
|
6047
6303
|
}
|
|
6048
6304
|
function antigravityBrainRoot() {
|
|
6049
|
-
return
|
|
6305
|
+
return join15(antigravityHome(), "brain");
|
|
6050
6306
|
}
|
|
6051
6307
|
function antigravityTranscriptRelPath() {
|
|
6052
|
-
return
|
|
6308
|
+
return join15(".system_generated", "logs", "transcript_full.jsonl");
|
|
6053
6309
|
}
|
|
6054
6310
|
function isPlainObject5(v) {
|
|
6055
6311
|
return !!v && typeof v === "object" && !Array.isArray(v);
|
|
@@ -6164,7 +6420,7 @@ function listAntigravityTranscripts() {
|
|
|
6164
6420
|
const out = [];
|
|
6165
6421
|
let convoDirs;
|
|
6166
6422
|
try {
|
|
6167
|
-
convoDirs =
|
|
6423
|
+
convoDirs = readdirSync6(root, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
6168
6424
|
} catch {
|
|
6169
6425
|
return out;
|
|
6170
6426
|
}
|
|
@@ -6172,7 +6428,7 @@ function listAntigravityTranscripts() {
|
|
|
6172
6428
|
const conversationId = dir.name;
|
|
6173
6429
|
if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
|
|
6174
6430
|
continue;
|
|
6175
|
-
const transcriptPath =
|
|
6431
|
+
const transcriptPath = join15(root, conversationId, rel);
|
|
6176
6432
|
try {
|
|
6177
6433
|
const st = statSync6(transcriptPath);
|
|
6178
6434
|
if (!st.isFile())
|
|
@@ -6185,7 +6441,7 @@ function listAntigravityTranscripts() {
|
|
|
6185
6441
|
function findAntigravityTranscript(conversationId) {
|
|
6186
6442
|
if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
|
|
6187
6443
|
return null;
|
|
6188
|
-
const transcriptPath =
|
|
6444
|
+
const transcriptPath = join15(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
|
|
6189
6445
|
try {
|
|
6190
6446
|
if (statSync6(transcriptPath).isFile())
|
|
6191
6447
|
return transcriptPath;
|
|
@@ -6225,9 +6481,9 @@ __export(exports_antigravity_projects, {
|
|
|
6225
6481
|
getAntigravityIndex: () => getAntigravityIndex,
|
|
6226
6482
|
antigravitySummariesDbPath: () => antigravitySummariesDbPath
|
|
6227
6483
|
});
|
|
6228
|
-
import { join as
|
|
6484
|
+
import { join as join16 } from "node:path";
|
|
6229
6485
|
function antigravitySummariesDbPath() {
|
|
6230
|
-
return
|
|
6486
|
+
return join16(antigravityHome(), "conversation_summaries.db");
|
|
6231
6487
|
}
|
|
6232
6488
|
function parseWorkspaceCwd(raw) {
|
|
6233
6489
|
if (!raw)
|
|
@@ -6371,15 +6627,15 @@ var init_antigravity_projects = __esm(() => {
|
|
|
6371
6627
|
|
|
6372
6628
|
// lib/goose-sessions.ts
|
|
6373
6629
|
import { homedir as homedir16 } from "node:os";
|
|
6374
|
-
import { join as
|
|
6630
|
+
import { join as join17 } from "node:path";
|
|
6375
6631
|
function gooseHome() {
|
|
6376
6632
|
if (process.env.GOOSE_HOME)
|
|
6377
6633
|
return process.env.GOOSE_HOME;
|
|
6378
6634
|
const xdg = process.env.XDG_DATA_HOME;
|
|
6379
|
-
return
|
|
6635
|
+
return join17(xdg && xdg.length > 0 ? xdg : join17(homedir16(), ".local", "share"), "goose");
|
|
6380
6636
|
}
|
|
6381
6637
|
function gooseDbPath() {
|
|
6382
|
-
return process.env.GOOSE_DB_PATH ||
|
|
6638
|
+
return process.env.GOOSE_DB_PATH || join17(gooseHome(), "sessions", "sessions.db");
|
|
6383
6639
|
}
|
|
6384
6640
|
function gooseTimestampToMs(value) {
|
|
6385
6641
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
@@ -6647,7 +6903,7 @@ var init_goose_projects = __esm(() => {
|
|
|
6647
6903
|
|
|
6648
6904
|
// lib/projects.ts
|
|
6649
6905
|
import { readdir as readdir5, stat as stat5 } from "node:fs/promises";
|
|
6650
|
-
import { join as
|
|
6906
|
+
import { join as join18, resolve as resolve6, sep } from "node:path";
|
|
6651
6907
|
async function getMtime(path3, label) {
|
|
6652
6908
|
try {
|
|
6653
6909
|
return (await stat5(path3)).mtime;
|
|
@@ -6673,7 +6929,7 @@ async function getClaudeProjectFolders() {
|
|
|
6673
6929
|
if (!entries)
|
|
6674
6930
|
return [];
|
|
6675
6931
|
const settled = await batchAll(entries.filter((entry) => entry.isDirectory()).map((entry) => async () => {
|
|
6676
|
-
const folderPath =
|
|
6932
|
+
const folderPath = join18(projectsPath, entry.name);
|
|
6677
6933
|
const mtime = await getMtime(folderPath, entry.name);
|
|
6678
6934
|
return {
|
|
6679
6935
|
name: entry.name,
|
|
@@ -6710,7 +6966,8 @@ function mergeProjectFolders(...sources) {
|
|
|
6710
6966
|
...existing,
|
|
6711
6967
|
cli: mergedCli,
|
|
6712
6968
|
lastModified: newer.lastModified,
|
|
6713
|
-
lastModifiedFormatted: newer.lastModifiedFormatted
|
|
6969
|
+
lastModifiedFormatted: newer.lastModifiedFormatted,
|
|
6970
|
+
sessionCount: existing.sessionCount === undefined && f.sessionCount === undefined ? undefined : (existing.sessionCount ?? 0) + (f.sessionCount ?? 0)
|
|
6714
6971
|
});
|
|
6715
6972
|
}
|
|
6716
6973
|
}
|
|
@@ -6798,8 +7055,8 @@ function resolveProjectPath(projectName) {
|
|
|
6798
7055
|
throw new RangeError("Empty project name");
|
|
6799
7056
|
if (/^[/\\]/.test(projectName))
|
|
6800
7057
|
throw new RangeError("Absolute project name");
|
|
6801
|
-
const projectsPath =
|
|
6802
|
-
const candidate =
|
|
7058
|
+
const projectsPath = resolve6(getClaudeProjectsPath());
|
|
7059
|
+
const candidate = resolve6(join18(projectsPath, projectName));
|
|
6803
7060
|
if (!candidate.startsWith(projectsPath + sep)) {
|
|
6804
7061
|
throw new RangeError("Project path escapes root");
|
|
6805
7062
|
}
|
|
@@ -6817,7 +7074,7 @@ async function getSessionFiles(projectPath) {
|
|
|
6817
7074
|
return [];
|
|
6818
7075
|
const jsonlEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl") && extractSessionId2(entry.name));
|
|
6819
7076
|
const settled = await batchAll(jsonlEntries.map((entry) => async () => {
|
|
6820
|
-
const filePath =
|
|
7077
|
+
const filePath = join18(projectPath, entry.name);
|
|
6821
7078
|
const mtime = await getMtime(filePath, entry.name);
|
|
6822
7079
|
return {
|
|
6823
7080
|
name: entry.name,
|
|
@@ -6846,13 +7103,13 @@ var init_projects = __esm(() => {
|
|
|
6846
7103
|
|
|
6847
7104
|
// lib/resolve-subagent-path.ts
|
|
6848
7105
|
import { access as access2 } from "fs/promises";
|
|
6849
|
-
import { join as
|
|
7106
|
+
import { join as join19, relative as relative2 } from "path";
|
|
6850
7107
|
async function resolveSubagentPath(projectsPath, projectName, sessionId, agentId) {
|
|
6851
7108
|
const fileName = `agent-${agentId}.jsonl`;
|
|
6852
7109
|
const candidatePaths = [
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
7110
|
+
join19(projectsPath, projectName, fileName),
|
|
7111
|
+
join19(projectsPath, projectName, sessionId, fileName),
|
|
7112
|
+
join19(projectsPath, projectName, sessionId, "subagents", fileName)
|
|
6856
7113
|
];
|
|
6857
7114
|
for (const candidatePath of candidatePaths) {
|
|
6858
7115
|
if (relative2(projectsPath, candidatePath).startsWith("..")) {
|
|
@@ -6874,7 +7131,7 @@ var init_resolve_subagent_path = () => {};
|
|
|
6874
7131
|
|
|
6875
7132
|
// lib/log-entries.ts
|
|
6876
7133
|
import { readFile as readFile9 } from "fs/promises";
|
|
6877
|
-
import { join as
|
|
7134
|
+
import { join as join20 } from "path";
|
|
6878
7135
|
function formatTimestamp(date) {
|
|
6879
7136
|
const base = formatDate(date);
|
|
6880
7137
|
const ms = date.getMilliseconds().toString().padStart(3, "0");
|
|
@@ -7072,7 +7329,7 @@ async function parseLogContent(fileContent, source = "session") {
|
|
|
7072
7329
|
async function parseSessionLog(projectName, sessionId) {
|
|
7073
7330
|
const projectDir = resolveProjectPath(projectName);
|
|
7074
7331
|
const projectsPath = getClaudeProjectsPath();
|
|
7075
|
-
const filePath =
|
|
7332
|
+
const filePath = join20(projectDir, `${sessionId}.jsonl`);
|
|
7076
7333
|
const fileContent = await readFile9(filePath, "utf-8");
|
|
7077
7334
|
const { entries: sessionEntries, rawLines: sessionRawLines, subagentIds } = await parseFileContent(fileContent, "session");
|
|
7078
7335
|
if (subagentIds.length === 0) {
|
|
@@ -7109,9 +7366,9 @@ var init_log_entries = __esm(() => {
|
|
|
7109
7366
|
});
|
|
7110
7367
|
|
|
7111
7368
|
// lib/codex-sessions.ts
|
|
7112
|
-
import { readFileSync as readFileSync5, readdirSync as
|
|
7369
|
+
import { readFileSync as readFileSync5, readdirSync as readdirSync7, existsSync as existsSync6, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4, statSync as statSync7 } from "node:fs";
|
|
7113
7370
|
import { readFile as readFile10 } from "node:fs/promises";
|
|
7114
|
-
import { dirname as
|
|
7371
|
+
import { dirname as dirname4, join as join21 } from "node:path";
|
|
7115
7372
|
import { homedir as homedir17 } from "node:os";
|
|
7116
7373
|
function readCache() {
|
|
7117
7374
|
try {
|
|
@@ -7124,7 +7381,7 @@ function readCache() {
|
|
|
7124
7381
|
}
|
|
7125
7382
|
function writeCacheEntry(sessionId, path3) {
|
|
7126
7383
|
try {
|
|
7127
|
-
mkdirSync4(
|
|
7384
|
+
mkdirSync4(dirname4(CACHE_PATH), { recursive: true });
|
|
7128
7385
|
const cache = readCache();
|
|
7129
7386
|
cache[sessionId] = path3;
|
|
7130
7387
|
writeFileSync3(CACHE_PATH, JSON.stringify(cache), "utf-8");
|
|
@@ -7132,9 +7389,9 @@ function writeCacheEntry(sessionId, path3) {
|
|
|
7132
7389
|
}
|
|
7133
7390
|
function dirSearch(dir, sessionId) {
|
|
7134
7391
|
try {
|
|
7135
|
-
for (const f of
|
|
7392
|
+
for (const f of readdirSync7(dir, { withFileTypes: true })) {
|
|
7136
7393
|
if (f.isFile() && f.name.includes(sessionId) && f.name.endsWith(".jsonl")) {
|
|
7137
|
-
return
|
|
7394
|
+
return join21(dir, f.name);
|
|
7138
7395
|
}
|
|
7139
7396
|
}
|
|
7140
7397
|
} catch {}
|
|
@@ -7145,14 +7402,14 @@ function findCodexTranscript(sessionId) {
|
|
|
7145
7402
|
const cached = cache[sessionId];
|
|
7146
7403
|
if (cached && existsSync6(cached))
|
|
7147
7404
|
return cached;
|
|
7148
|
-
const root =
|
|
7405
|
+
const root = join21(homedir17(), ".codex", "sessions");
|
|
7149
7406
|
const today = new Date;
|
|
7150
7407
|
const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
|
|
7151
7408
|
const datedDirs = [today, yesterday].map((d) => {
|
|
7152
7409
|
const y = String(d.getUTCFullYear());
|
|
7153
7410
|
const m = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
7154
7411
|
const day = String(d.getUTCDate()).padStart(2, "0");
|
|
7155
|
-
return
|
|
7412
|
+
return join21(root, y, m, day);
|
|
7156
7413
|
});
|
|
7157
7414
|
for (const dir of datedDirs) {
|
|
7158
7415
|
const hit = dirSearch(dir, sessionId);
|
|
@@ -7162,16 +7419,16 @@ function findCodexTranscript(sessionId) {
|
|
|
7162
7419
|
}
|
|
7163
7420
|
}
|
|
7164
7421
|
try {
|
|
7165
|
-
for (const y of
|
|
7422
|
+
for (const y of readdirSync7(root, { withFileTypes: true })) {
|
|
7166
7423
|
if (!y.isDirectory())
|
|
7167
7424
|
continue;
|
|
7168
|
-
for (const m of
|
|
7425
|
+
for (const m of readdirSync7(join21(root, y.name), { withFileTypes: true })) {
|
|
7169
7426
|
if (!m.isDirectory())
|
|
7170
7427
|
continue;
|
|
7171
|
-
for (const d of
|
|
7428
|
+
for (const d of readdirSync7(join21(root, y.name, m.name), { withFileTypes: true })) {
|
|
7172
7429
|
if (!d.isDirectory())
|
|
7173
7430
|
continue;
|
|
7174
|
-
const hit = dirSearch(
|
|
7431
|
+
const hit = dirSearch(join21(root, y.name, m.name, d.name), sessionId);
|
|
7175
7432
|
if (hit) {
|
|
7176
7433
|
writeCacheEntry(sessionId, hit);
|
|
7177
7434
|
return hit;
|
|
@@ -7391,7 +7648,7 @@ async function getCodexSessionLog(sessionId) {
|
|
|
7391
7648
|
var CACHE_PATH, getCachedCodexSessionLog;
|
|
7392
7649
|
var init_codex_sessions = __esm(() => {
|
|
7393
7650
|
init_log_entries();
|
|
7394
|
-
CACHE_PATH =
|
|
7651
|
+
CACHE_PATH = join21(homedir17(), ".failproofai", "cache", "codex-session-paths.json");
|
|
7395
7652
|
getCachedCodexSessionLog = runtimeCache((sessionId) => getCodexSessionLog(sessionId), 60, { maxSize: 50 });
|
|
7396
7653
|
});
|
|
7397
7654
|
|
|
@@ -7436,21 +7693,21 @@ var init_resolve_permission_mode = __esm(() => {
|
|
|
7436
7693
|
});
|
|
7437
7694
|
|
|
7438
7695
|
// lib/copilot-sessions.ts
|
|
7439
|
-
import { readFileSync as readFileSync7, readdirSync as
|
|
7696
|
+
import { readFileSync as readFileSync7, readdirSync as readdirSync8, existsSync as existsSync7, statSync as statSync8 } from "node:fs";
|
|
7440
7697
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
7441
|
-
import { join as
|
|
7698
|
+
import { join as join22, resolve as resolve7, sep as sep2 } from "node:path";
|
|
7442
7699
|
import { homedir as homedir18 } from "node:os";
|
|
7443
7700
|
function getCopilotHome() {
|
|
7444
|
-
return process.env.COPILOT_HOME ||
|
|
7701
|
+
return process.env.COPILOT_HOME || join22(homedir18(), ".copilot");
|
|
7445
7702
|
}
|
|
7446
7703
|
function getCopilotSessionStateRoot2() {
|
|
7447
|
-
return
|
|
7704
|
+
return join22(getCopilotHome(), "session-state");
|
|
7448
7705
|
}
|
|
7449
7706
|
function getCopilotSessionDir(sessionId) {
|
|
7450
7707
|
if (!sessionId)
|
|
7451
7708
|
return null;
|
|
7452
|
-
const root =
|
|
7453
|
-
const candidate =
|
|
7709
|
+
const root = resolve7(getCopilotSessionStateRoot2());
|
|
7710
|
+
const candidate = resolve7(root, sessionId);
|
|
7454
7711
|
if (candidate === root || !candidate.startsWith(`${root}${sep2}`))
|
|
7455
7712
|
return null;
|
|
7456
7713
|
return candidate;
|
|
@@ -7459,7 +7716,7 @@ function resolveSessionFile(sessionId, filename) {
|
|
|
7459
7716
|
const dir = getCopilotSessionDir(sessionId);
|
|
7460
7717
|
if (!dir)
|
|
7461
7718
|
return null;
|
|
7462
|
-
return
|
|
7719
|
+
return join22(dir, filename);
|
|
7463
7720
|
}
|
|
7464
7721
|
function findCopilotTranscript(sessionId) {
|
|
7465
7722
|
const candidate = resolveSessionFile(sessionId, "events.jsonl");
|
|
@@ -7653,35 +7910,35 @@ var init_copilot_sessions = __esm(() => {
|
|
|
7653
7910
|
});
|
|
7654
7911
|
|
|
7655
7912
|
// lib/cursor-sessions.ts
|
|
7656
|
-
import { readFileSync as readFileSync8, readdirSync as
|
|
7913
|
+
import { readFileSync as readFileSync8, readdirSync as readdirSync9, existsSync as existsSync8, statSync as statSync9 } from "node:fs";
|
|
7657
7914
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
7658
|
-
import { basename as
|
|
7915
|
+
import { basename as basename3, join as join23, resolve as resolve8, sep as sep3 } from "node:path";
|
|
7659
7916
|
import { homedir as homedir19 } from "node:os";
|
|
7660
7917
|
function getCursorHome2() {
|
|
7661
|
-
return process.env.CURSOR_HOME ||
|
|
7918
|
+
return process.env.CURSOR_HOME || join23(homedir19(), ".cursor");
|
|
7662
7919
|
}
|
|
7663
7920
|
function getCursorSessionDir(sessionId) {
|
|
7664
7921
|
if (!sessionId)
|
|
7665
7922
|
return null;
|
|
7666
|
-
const home =
|
|
7667
|
-
const projectsRoot =
|
|
7923
|
+
const home = resolve8(getCursorHome2());
|
|
7924
|
+
const projectsRoot = resolve8(home, NEW_PROJECTS_DIR2);
|
|
7668
7925
|
let projectEntries = [];
|
|
7669
7926
|
try {
|
|
7670
|
-
projectEntries =
|
|
7927
|
+
projectEntries = readdirSync9(projectsRoot, { withFileTypes: true });
|
|
7671
7928
|
} catch {}
|
|
7672
7929
|
for (const entry of projectEntries) {
|
|
7673
7930
|
if (!entry.isDirectory())
|
|
7674
7931
|
continue;
|
|
7675
|
-
const candidate =
|
|
7676
|
-
const transcriptRoot =
|
|
7932
|
+
const candidate = resolve8(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2, sessionId);
|
|
7933
|
+
const transcriptRoot = resolve8(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
|
|
7677
7934
|
if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
|
|
7678
7935
|
continue;
|
|
7679
7936
|
if (existsSync8(candidate))
|
|
7680
7937
|
return candidate;
|
|
7681
7938
|
}
|
|
7682
7939
|
for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
|
|
7683
|
-
const root =
|
|
7684
|
-
const candidate =
|
|
7940
|
+
const root = resolve8(home, sub);
|
|
7941
|
+
const candidate = resolve8(root, sessionId);
|
|
7685
7942
|
if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
|
|
7686
7943
|
continue;
|
|
7687
7944
|
if (existsSync8(candidate))
|
|
@@ -7693,11 +7950,11 @@ function findCursorTranscript(sessionId) {
|
|
|
7693
7950
|
const dir = getCursorSessionDir(sessionId);
|
|
7694
7951
|
if (!dir)
|
|
7695
7952
|
return null;
|
|
7696
|
-
const newCandidate =
|
|
7953
|
+
const newCandidate = join23(dir, `${basename3(dir)}.jsonl`);
|
|
7697
7954
|
if (existsSync8(newCandidate))
|
|
7698
7955
|
return newCandidate;
|
|
7699
7956
|
for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
|
|
7700
|
-
const candidate =
|
|
7957
|
+
const candidate = join23(dir, name);
|
|
7701
7958
|
if (existsSync8(candidate))
|
|
7702
7959
|
return candidate;
|
|
7703
7960
|
}
|
|
@@ -7909,12 +8166,12 @@ var init_cursor_sessions = __esm(() => {
|
|
|
7909
8166
|
});
|
|
7910
8167
|
|
|
7911
8168
|
// lib/pi-sessions.ts
|
|
7912
|
-
import { readFileSync as readFileSync9, readdirSync as
|
|
8169
|
+
import { readFileSync as readFileSync9, readdirSync as readdirSync10, existsSync as existsSync9, statSync as statSync10 } from "node:fs";
|
|
7913
8170
|
import { readFile as readFile13 } from "node:fs/promises";
|
|
7914
|
-
import { join as
|
|
8171
|
+
import { join as join24, resolve as resolve9, sep as sep4 } from "node:path";
|
|
7915
8172
|
import { homedir as homedir20 } from "node:os";
|
|
7916
8173
|
function getPiSessionStateRoot() {
|
|
7917
|
-
return process.env.PI_SESSIONS_DIR ||
|
|
8174
|
+
return process.env.PI_SESSIONS_DIR || join24(homedir20(), ".pi", "agent", "sessions");
|
|
7918
8175
|
}
|
|
7919
8176
|
function isSafeSessionId(sessionId) {
|
|
7920
8177
|
return UUID_RE.test(sessionId);
|
|
@@ -7922,20 +8179,20 @@ function isSafeSessionId(sessionId) {
|
|
|
7922
8179
|
function findPiTranscript(sessionId) {
|
|
7923
8180
|
if (!isSafeSessionId(sessionId))
|
|
7924
8181
|
return null;
|
|
7925
|
-
const root =
|
|
8182
|
+
const root = resolve9(getPiSessionStateRoot());
|
|
7926
8183
|
let cwdDirs;
|
|
7927
8184
|
try {
|
|
7928
|
-
cwdDirs =
|
|
8185
|
+
cwdDirs = readdirSync10(root);
|
|
7929
8186
|
} catch {
|
|
7930
8187
|
return null;
|
|
7931
8188
|
}
|
|
7932
8189
|
for (const cwdDir of cwdDirs) {
|
|
7933
|
-
const cwdPath =
|
|
8190
|
+
const cwdPath = resolve9(root, cwdDir);
|
|
7934
8191
|
if (!cwdPath.startsWith(`${root}${sep4}`))
|
|
7935
8192
|
continue;
|
|
7936
8193
|
let files;
|
|
7937
8194
|
try {
|
|
7938
|
-
files =
|
|
8195
|
+
files = readdirSync10(cwdPath);
|
|
7939
8196
|
} catch {
|
|
7940
8197
|
continue;
|
|
7941
8198
|
}
|
|
@@ -7943,7 +8200,7 @@ function findPiTranscript(sessionId) {
|
|
|
7943
8200
|
const m = SESSION_FILE_RE2.exec(f);
|
|
7944
8201
|
if (!m || m[1].toLowerCase() !== sessionId.toLowerCase())
|
|
7945
8202
|
continue;
|
|
7946
|
-
const candidate =
|
|
8203
|
+
const candidate = resolve9(cwdPath, f);
|
|
7947
8204
|
if (!candidate.startsWith(`${cwdPath}${sep4}`))
|
|
7948
8205
|
continue;
|
|
7949
8206
|
if (existsSync9(candidate))
|
|
@@ -8187,7 +8444,7 @@ async function handleHookEvent(eventType, cli = "claude") {
|
|
|
8187
8444
|
let payload = "";
|
|
8188
8445
|
let stdinOversized = false;
|
|
8189
8446
|
try {
|
|
8190
|
-
payload = await new Promise((
|
|
8447
|
+
payload = await new Promise((resolve10, reject) => {
|
|
8191
8448
|
const chunks = [];
|
|
8192
8449
|
let totalBytes = 0;
|
|
8193
8450
|
process.stdin.setEncoding("utf8");
|
|
@@ -8197,15 +8454,15 @@ async function handleHookEvent(eventType, cli = "claude") {
|
|
|
8197
8454
|
hookLogWarn(`stdin payload exceeds 1 MB for ${eventType}, discarding`);
|
|
8198
8455
|
stdinOversized = true;
|
|
8199
8456
|
process.stdin.destroy();
|
|
8200
|
-
|
|
8457
|
+
resolve10("");
|
|
8201
8458
|
return;
|
|
8202
8459
|
}
|
|
8203
8460
|
chunks.push(chunk);
|
|
8204
8461
|
});
|
|
8205
|
-
process.stdin.on("end", () =>
|
|
8462
|
+
process.stdin.on("end", () => resolve10(chunks.join("")));
|
|
8206
8463
|
process.stdin.on("error", reject);
|
|
8207
8464
|
if (process.stdin.readableEnded)
|
|
8208
|
-
|
|
8465
|
+
resolve10("");
|
|
8209
8466
|
});
|
|
8210
8467
|
} catch (err) {
|
|
8211
8468
|
hookLogWarn(`stdin read failed for ${eventType}`);
|
|
@@ -8293,13 +8550,17 @@ async function handleHookEvent(eventType, cli = "claude") {
|
|
|
8293
8550
|
const config = readMergedHooksConfig(session.cwd);
|
|
8294
8551
|
clearPolicies();
|
|
8295
8552
|
registerBuiltinPolicies(config.enabledPolicies);
|
|
8296
|
-
const loadResult = await loadAllCustomHooks(config.customPoliciesPath, {
|
|
8553
|
+
const loadResult = await loadAllCustomHooks(config.customPoliciesPaths ?? config.customPoliciesPath, {
|
|
8297
8554
|
sessionCwd: session.cwd,
|
|
8298
8555
|
customPoliciesEnabled: config.customPoliciesEnabled
|
|
8299
8556
|
});
|
|
8300
8557
|
const customHooksList = loadResult.hooks;
|
|
8558
|
+
const disabledCustomPolicies = new Set(config.disabledCustomPolicies ?? []);
|
|
8301
8559
|
const conventionHookNames = new Set(loadResult.conventionSources.flatMap((s) => s.hookNames));
|
|
8302
8560
|
for (const hook of customHooksList) {
|
|
8561
|
+
const policyId = hook.__policyId;
|
|
8562
|
+
if (policyId && disabledCustomPolicies.has(policyId))
|
|
8563
|
+
continue;
|
|
8303
8564
|
const hookName = hook.name;
|
|
8304
8565
|
const conventionScope = hook.__conventionScope;
|
|
8305
8566
|
const isConvention = !!conventionScope;
|
|
@@ -8356,6 +8617,7 @@ async function handleHookEvent(eventType, cli = "claude") {
|
|
|
8356
8617
|
if (result.stderr) {
|
|
8357
8618
|
process.stderr.write(result.stderr);
|
|
8358
8619
|
}
|
|
8620
|
+
const matchedPolicies = getPoliciesForEvent(canonicalEventType, parsed.tool_name).map((p) => p.name);
|
|
8359
8621
|
const activityEntry = {
|
|
8360
8622
|
timestamp: Date.now(),
|
|
8361
8623
|
eventType: canonicalEventType,
|
|
@@ -8363,6 +8625,7 @@ async function handleHookEvent(eventType, cli = "claude") {
|
|
|
8363
8625
|
toolName: parsed.tool_name ?? null,
|
|
8364
8626
|
policyName: result.policyName,
|
|
8365
8627
|
policyNames: result.policyNames,
|
|
8628
|
+
matchedPolicies,
|
|
8366
8629
|
decision: result.decision,
|
|
8367
8630
|
reason: result.reason,
|
|
8368
8631
|
durationMs,
|
|
@@ -8424,13 +8687,13 @@ import { createHmac, randomUUID } from "node:crypto";
|
|
|
8424
8687
|
import { execSync as execSync4 } from "node:child_process";
|
|
8425
8688
|
import { readFileSync as readFileSync10, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "node:fs";
|
|
8426
8689
|
import { homedir as homedir21, platform, arch, hostname, cpus } from "node:os";
|
|
8427
|
-
import { join as
|
|
8690
|
+
import { join as join25 } from "node:path";
|
|
8428
8691
|
function hashToId3(raw) {
|
|
8429
8692
|
return createHmac("sha256", NAMESPACE3).update(raw).digest("hex");
|
|
8430
8693
|
}
|
|
8431
8694
|
function getInstanceId3() {
|
|
8432
|
-
const idDir =
|
|
8433
|
-
const idFile =
|
|
8695
|
+
const idDir = join25(homedir21(), ".failproofai");
|
|
8696
|
+
const idFile = join25(idDir, "instance-id");
|
|
8434
8697
|
try {
|
|
8435
8698
|
const existing = readFileSync10(idFile, "utf-8").trim();
|
|
8436
8699
|
if (existing)
|
|
@@ -8511,14 +8774,14 @@ __export(exports_install_check, {
|
|
|
8511
8774
|
checkHooks: () => checkHooks
|
|
8512
8775
|
});
|
|
8513
8776
|
import { existsSync as existsSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync5, mkdirSync as mkdirSync6 } from "node:fs";
|
|
8514
|
-
import { resolve as
|
|
8777
|
+
import { resolve as resolve10 } from "node:path";
|
|
8515
8778
|
import { platform as platform2, arch as arch2, release, homedir as homedir22, hostname as hostname2 } from "node:os";
|
|
8516
8779
|
import { createHmac as createHmac2 } from "node:crypto";
|
|
8517
8780
|
function hashToId4(raw) {
|
|
8518
8781
|
return createHmac2("sha256", NAMESPACE4).update(raw).digest("hex");
|
|
8519
8782
|
}
|
|
8520
8783
|
function lastVersionPath() {
|
|
8521
|
-
return
|
|
8784
|
+
return resolve10(homedir22(), ".failproofai", "last-version");
|
|
8522
8785
|
}
|
|
8523
8786
|
function compareSemver(a, b) {
|
|
8524
8787
|
const parse = (v) => {
|
|
@@ -8565,7 +8828,7 @@ function compareSemver(a, b) {
|
|
|
8565
8828
|
return 0;
|
|
8566
8829
|
}
|
|
8567
8830
|
function checkHooks() {
|
|
8568
|
-
const hooksConfigPath =
|
|
8831
|
+
const hooksConfigPath = resolve10(homedir22(), ".failproofai", "policies-config.json");
|
|
8569
8832
|
if (!existsSync10(hooksConfigPath)) {
|
|
8570
8833
|
return { configured: false, registered: false, policyCount: 0 };
|
|
8571
8834
|
}
|
|
@@ -8579,7 +8842,7 @@ function checkHooks() {
|
|
|
8579
8842
|
return { configured: false, registered: false, policyCount: 0 };
|
|
8580
8843
|
}
|
|
8581
8844
|
const policyCount = config.enabledPolicies.length;
|
|
8582
|
-
const settingsPath =
|
|
8845
|
+
const settingsPath = resolve10(homedir22(), ".claude", "settings.json");
|
|
8583
8846
|
if (!existsSync10(settingsPath))
|
|
8584
8847
|
return { configured: true, registered: false, policyCount };
|
|
8585
8848
|
let settings;
|
|
@@ -8644,7 +8907,7 @@ async function maybeReportInstall(version3) {
|
|
|
8644
8907
|
enabled_policy_count: hooks.policyCount
|
|
8645
8908
|
}, { version: version3, timeoutMs: REPORT_TIMEOUT_MS }));
|
|
8646
8909
|
try {
|
|
8647
|
-
mkdirSync6(
|
|
8910
|
+
mkdirSync6(resolve10(homedir22(), ".failproofai"), { recursive: true });
|
|
8648
8911
|
writeFileSync5(versionFile, version3, "utf8");
|
|
8649
8912
|
} catch {}
|
|
8650
8913
|
await Promise.all(events.map((p) => p.catch(() => {})));
|
|
@@ -15648,7 +15911,7 @@ var init_dist = __esm(() => {
|
|
|
15648
15911
|
// src/hooks/integrations.ts
|
|
15649
15912
|
import { execSync as execSync5 } from "node:child_process";
|
|
15650
15913
|
import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync7, unlinkSync as unlinkSync2 } from "node:fs";
|
|
15651
|
-
import { resolve as
|
|
15914
|
+
import { resolve as resolve11, dirname as dirname5 } from "node:path";
|
|
15652
15915
|
import { fileURLToPath } from "node:url";
|
|
15653
15916
|
import { homedir as homedir23 } from "node:os";
|
|
15654
15917
|
function readJsonFile(path3) {
|
|
@@ -15658,7 +15921,7 @@ function readJsonFile(path3) {
|
|
|
15658
15921
|
return JSON.parse(raw);
|
|
15659
15922
|
}
|
|
15660
15923
|
function writeJsonFile(path3, data) {
|
|
15661
|
-
mkdirSync7(
|
|
15924
|
+
mkdirSync7(dirname5(path3), { recursive: true });
|
|
15662
15925
|
writeFileSync6(path3, JSON.stringify(data, null, 2) + `
|
|
15663
15926
|
`, "utf8");
|
|
15664
15927
|
}
|
|
@@ -15670,7 +15933,7 @@ function readYamlDoc(path3) {
|
|
|
15670
15933
|
}
|
|
15671
15934
|
}
|
|
15672
15935
|
function writeYamlDoc(path3, doc) {
|
|
15673
|
-
mkdirSync7(
|
|
15936
|
+
mkdirSync7(dirname5(path3), { recursive: true });
|
|
15674
15937
|
writeFileSync6(path3, doc.toString(), "utf8");
|
|
15675
15938
|
}
|
|
15676
15939
|
function isMarkedHook(hook) {
|
|
@@ -15698,6 +15961,10 @@ function binaryExists(name) {
|
|
|
15698
15961
|
return false;
|
|
15699
15962
|
}
|
|
15700
15963
|
}
|
|
15964
|
+
function settingsPathsFor(integration, scope, cwd) {
|
|
15965
|
+
const paths = integration.getSettingsPaths?.(scope, cwd);
|
|
15966
|
+
return paths && paths.length > 0 ? paths : [integration.getSettingsPath(scope, cwd)];
|
|
15967
|
+
}
|
|
15701
15968
|
function isMarkedCopilotHook(hook) {
|
|
15702
15969
|
if (hook[FAILPROOFAI_HOOK_MARKER] === true)
|
|
15703
15970
|
return true;
|
|
@@ -15710,7 +15977,7 @@ function isMarkedCopilotHook(hook) {
|
|
|
15710
15977
|
return false;
|
|
15711
15978
|
}
|
|
15712
15979
|
function opencodePluginFilePath(settingsPath) {
|
|
15713
|
-
return
|
|
15980
|
+
return resolve11(dirname5(settingsPath), "plugins", "failproofai.mjs");
|
|
15714
15981
|
}
|
|
15715
15982
|
function buildOpenCodePluginShim(binaryPath, scope) {
|
|
15716
15983
|
const useNpx = scope === "project";
|
|
@@ -15925,8 +16192,8 @@ export default async function failproofaiPlugin({ client, directory }) {
|
|
|
15925
16192
|
function getPiExtensionPath() {
|
|
15926
16193
|
const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
|
|
15927
16194
|
if (fromEnv)
|
|
15928
|
-
return
|
|
15929
|
-
return
|
|
16195
|
+
return resolve11(fromEnv, "pi-extension");
|
|
16196
|
+
return resolve11(fileURLToPath(import.meta.url), "..", "..", "..", "pi-extension");
|
|
15930
16197
|
}
|
|
15931
16198
|
function isFailproofaiPiEntry(source) {
|
|
15932
16199
|
if (typeof source !== "string")
|
|
@@ -15937,19 +16204,38 @@ function isFailproofaiPiEntry(source) {
|
|
|
15937
16204
|
}
|
|
15938
16205
|
function makePiProjectRelativeEntry(extPath) {
|
|
15939
16206
|
const cwd = process.cwd();
|
|
15940
|
-
const cwdResolved =
|
|
15941
|
-
const extResolved =
|
|
16207
|
+
const cwdResolved = resolve11(cwd);
|
|
16208
|
+
const extResolved = resolve11(extPath);
|
|
15942
16209
|
if (extResolved.startsWith(cwdResolved + "/") || extResolved === cwdResolved) {
|
|
15943
16210
|
const fromSettingsDir = "../" + extResolved.slice(cwdResolved.length + 1);
|
|
15944
16211
|
return fromSettingsDir;
|
|
15945
16212
|
}
|
|
15946
16213
|
return extResolved;
|
|
15947
16214
|
}
|
|
16215
|
+
function hermesConfigHasHooks(settingsPath) {
|
|
16216
|
+
if (!existsSync11(settingsPath))
|
|
16217
|
+
return false;
|
|
16218
|
+
try {
|
|
16219
|
+
const doc = readYamlDoc(settingsPath);
|
|
16220
|
+
const js = doc.toJS() ?? {};
|
|
16221
|
+
const hooks = js.hooks;
|
|
16222
|
+
if (!hooks || typeof hooks !== "object")
|
|
16223
|
+
return false;
|
|
16224
|
+
for (const entries of Object.values(hooks)) {
|
|
16225
|
+
if (Array.isArray(entries) && entries.some((h) => isMarkedHook(h)))
|
|
16226
|
+
return true;
|
|
16227
|
+
}
|
|
16228
|
+
} catch {}
|
|
16229
|
+
return false;
|
|
16230
|
+
}
|
|
16231
|
+
function unhookedHermesProfiles() {
|
|
16232
|
+
return listHermesProfiles().filter((p) => existsSync11(p.home)).filter((p) => !hermesConfigHasHooks(resolve11(p.home, "config.yaml"))).map((p) => p.name);
|
|
16233
|
+
}
|
|
15948
16234
|
function getOpenClawPluginPath() {
|
|
15949
16235
|
const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
|
|
15950
16236
|
if (fromEnv)
|
|
15951
|
-
return
|
|
15952
|
-
return
|
|
16237
|
+
return resolve11(fromEnv, "openclaw-plugin");
|
|
16238
|
+
return resolve11(fileURLToPath(import.meta.url), "..", "..", "..", "openclaw-plugin");
|
|
15953
16239
|
}
|
|
15954
16240
|
function isFailproofaiOpenClawPath(p) {
|
|
15955
16241
|
if (typeof p !== "string")
|
|
@@ -15978,21 +16264,22 @@ function detectInstalledClis() {
|
|
|
15978
16264
|
var claudeCode, codex, copilot, cursor, OPENCODE_PLUGIN_REL_PATH = "./plugins/failproofai.mjs", opencode, pi, hermes, OPENCLAW_PLUGIN_ID = "failproofai", openclaw, factory, devin, ANTIGRAVITY_HOOK_NAME = "failproofai", ANTIGRAVITY_TOOL_EVENTS, antigravity, goose, INTEGRATIONS;
|
|
15979
16265
|
var init_integrations = __esm(() => {
|
|
15980
16266
|
init_dist();
|
|
16267
|
+
init_hermes_profiles();
|
|
15981
16268
|
init_types();
|
|
15982
16269
|
claudeCode = {
|
|
15983
16270
|
id: "claude",
|
|
15984
16271
|
displayName: "Claude Code",
|
|
15985
16272
|
scopes: HOOK_SCOPES,
|
|
15986
|
-
eventTypes:
|
|
16273
|
+
eventTypes: CLAUDE_INSTALL_EVENT_TYPES,
|
|
15987
16274
|
getSettingsPath(scope, cwd) {
|
|
15988
|
-
const base = cwd ?
|
|
16275
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
15989
16276
|
switch (scope) {
|
|
15990
16277
|
case "user":
|
|
15991
|
-
return
|
|
16278
|
+
return resolve11(homedir23(), ".claude", "settings.json");
|
|
15992
16279
|
case "project":
|
|
15993
|
-
return
|
|
16280
|
+
return resolve11(base, ".claude", "settings.json");
|
|
15994
16281
|
case "local":
|
|
15995
|
-
return
|
|
16282
|
+
return resolve11(base, ".claude", "settings.local.json");
|
|
15996
16283
|
}
|
|
15997
16284
|
},
|
|
15998
16285
|
readSettings(settingsPath) {
|
|
@@ -16015,7 +16302,31 @@ var init_integrations = __esm(() => {
|
|
|
16015
16302
|
const s = settings;
|
|
16016
16303
|
if (!s.hooks)
|
|
16017
16304
|
s.hooks = {};
|
|
16018
|
-
|
|
16305
|
+
const installed = new Set(CLAUDE_INSTALL_EVENT_TYPES);
|
|
16306
|
+
for (const eventType of Object.keys(s.hooks)) {
|
|
16307
|
+
if (installed.has(eventType))
|
|
16308
|
+
continue;
|
|
16309
|
+
const matchers = s.hooks[eventType];
|
|
16310
|
+
if (!Array.isArray(matchers))
|
|
16311
|
+
continue;
|
|
16312
|
+
const kept = [];
|
|
16313
|
+
for (const matcher of matchers) {
|
|
16314
|
+
if (!matcher || !Array.isArray(matcher.hooks)) {
|
|
16315
|
+
if (matcher)
|
|
16316
|
+
kept.push(matcher);
|
|
16317
|
+
continue;
|
|
16318
|
+
}
|
|
16319
|
+
const before = matcher.hooks.length;
|
|
16320
|
+
matcher.hooks = matcher.hooks.filter((h) => !isMarkedHook(h));
|
|
16321
|
+
const weEmptiedIt = matcher.hooks.length === 0 && before > 0;
|
|
16322
|
+
if (!weEmptiedIt)
|
|
16323
|
+
kept.push(matcher);
|
|
16324
|
+
}
|
|
16325
|
+
s.hooks[eventType] = kept;
|
|
16326
|
+
if (kept.length === 0)
|
|
16327
|
+
delete s.hooks[eventType];
|
|
16328
|
+
}
|
|
16329
|
+
for (const eventType of CLAUDE_INSTALL_EVENT_TYPES) {
|
|
16019
16330
|
const hookEntry = this.buildHookEntry(binaryPath, eventType, scope);
|
|
16020
16331
|
if (!s.hooks[eventType])
|
|
16021
16332
|
s.hooks[eventType] = [];
|
|
@@ -16093,14 +16404,14 @@ var init_integrations = __esm(() => {
|
|
|
16093
16404
|
scopes: CODEX_HOOK_SCOPES,
|
|
16094
16405
|
eventTypes: CODEX_HOOK_EVENT_TYPES,
|
|
16095
16406
|
getSettingsPath(scope, cwd) {
|
|
16096
|
-
const base = cwd ?
|
|
16407
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16097
16408
|
switch (scope) {
|
|
16098
16409
|
case "user":
|
|
16099
|
-
return
|
|
16410
|
+
return resolve11(homedir23(), ".codex", "hooks.json");
|
|
16100
16411
|
case "project":
|
|
16101
|
-
return
|
|
16412
|
+
return resolve11(base, ".codex", "hooks.json");
|
|
16102
16413
|
case "local":
|
|
16103
|
-
return
|
|
16414
|
+
return resolve11(base, ".codex", "hooks.json");
|
|
16104
16415
|
}
|
|
16105
16416
|
},
|
|
16106
16417
|
readSettings(settingsPath) {
|
|
@@ -16209,14 +16520,14 @@ var init_integrations = __esm(() => {
|
|
|
16209
16520
|
scopes: COPILOT_HOOK_SCOPES,
|
|
16210
16521
|
eventTypes: COPILOT_HOOK_EVENT_TYPES,
|
|
16211
16522
|
getSettingsPath(scope, cwd) {
|
|
16212
|
-
const base = cwd ?
|
|
16523
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16213
16524
|
switch (scope) {
|
|
16214
16525
|
case "user":
|
|
16215
|
-
return
|
|
16526
|
+
return resolve11(homedir23(), ".copilot", "hooks", "failproofai.json");
|
|
16216
16527
|
case "project":
|
|
16217
|
-
return
|
|
16528
|
+
return resolve11(base, ".github", "hooks", "failproofai.json");
|
|
16218
16529
|
case "local":
|
|
16219
|
-
return
|
|
16530
|
+
return resolve11(base, ".github", "hooks", "failproofai.json");
|
|
16220
16531
|
}
|
|
16221
16532
|
},
|
|
16222
16533
|
readSettings(settingsPath) {
|
|
@@ -16323,14 +16634,14 @@ var init_integrations = __esm(() => {
|
|
|
16323
16634
|
scopes: CURSOR_HOOK_SCOPES,
|
|
16324
16635
|
eventTypes: CURSOR_HOOK_EVENT_TYPES,
|
|
16325
16636
|
getSettingsPath(scope, cwd) {
|
|
16326
|
-
const base = cwd ?
|
|
16637
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16327
16638
|
switch (scope) {
|
|
16328
16639
|
case "user":
|
|
16329
|
-
return
|
|
16640
|
+
return resolve11(homedir23(), ".cursor", "hooks.json");
|
|
16330
16641
|
case "project":
|
|
16331
|
-
return
|
|
16642
|
+
return resolve11(base, ".cursor", "hooks.json");
|
|
16332
16643
|
case "local":
|
|
16333
|
-
return
|
|
16644
|
+
return resolve11(base, ".cursor", "hooks.json");
|
|
16334
16645
|
}
|
|
16335
16646
|
},
|
|
16336
16647
|
readSettings(settingsPath) {
|
|
@@ -16422,14 +16733,14 @@ var init_integrations = __esm(() => {
|
|
|
16422
16733
|
scopes: OPENCODE_HOOK_SCOPES,
|
|
16423
16734
|
eventTypes: OPENCODE_HOOK_EVENT_TYPES,
|
|
16424
16735
|
getSettingsPath(scope, cwd) {
|
|
16425
|
-
const base = cwd ?
|
|
16736
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16426
16737
|
switch (scope) {
|
|
16427
16738
|
case "user":
|
|
16428
|
-
return
|
|
16739
|
+
return resolve11(homedir23(), ".config", "opencode", "opencode.json");
|
|
16429
16740
|
case "project":
|
|
16430
|
-
return
|
|
16741
|
+
return resolve11(base, ".opencode", "opencode.json");
|
|
16431
16742
|
case "local":
|
|
16432
|
-
return
|
|
16743
|
+
return resolve11(base, ".opencode", "opencode.json");
|
|
16433
16744
|
}
|
|
16434
16745
|
},
|
|
16435
16746
|
readSettings(settingsPath) {
|
|
@@ -16440,7 +16751,7 @@ var init_integrations = __esm(() => {
|
|
|
16440
16751
|
},
|
|
16441
16752
|
buildHookEntry(_binaryPath, _eventType, scope) {
|
|
16442
16753
|
if (scope === "user") {
|
|
16443
|
-
const abs =
|
|
16754
|
+
const abs = resolve11(homedir23(), ".config", "opencode", "plugins", "failproofai.mjs");
|
|
16444
16755
|
return { spec: `file://${abs}`, [FAILPROOFAI_HOOK_MARKER]: true };
|
|
16445
16756
|
}
|
|
16446
16757
|
return { spec: OPENCODE_PLUGIN_REL_PATH, [FAILPROOFAI_HOOK_MARKER]: true };
|
|
@@ -16455,9 +16766,9 @@ var init_integrations = __esm(() => {
|
|
|
16455
16766
|
writeHookEntries(settings, binaryPath, scope) {
|
|
16456
16767
|
const s = settings;
|
|
16457
16768
|
const effectiveScope = scope ?? "project";
|
|
16458
|
-
const settingsPath = effectiveScope === "user" ?
|
|
16769
|
+
const settingsPath = effectiveScope === "user" ? resolve11(homedir23(), ".config", "opencode", "opencode.json") : resolve11(process.cwd(), ".opencode", "opencode.json");
|
|
16459
16770
|
const pluginPath = opencodePluginFilePath(settingsPath);
|
|
16460
|
-
mkdirSync7(
|
|
16771
|
+
mkdirSync7(dirname5(pluginPath), { recursive: true });
|
|
16461
16772
|
writeFileSync6(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope), "utf8");
|
|
16462
16773
|
if (!Array.isArray(s.plugin))
|
|
16463
16774
|
s.plugin = [];
|
|
@@ -16523,14 +16834,14 @@ var init_integrations = __esm(() => {
|
|
|
16523
16834
|
scopes: PI_HOOK_SCOPES,
|
|
16524
16835
|
eventTypes: PI_HOOK_EVENT_TYPES,
|
|
16525
16836
|
getSettingsPath(scope, cwd) {
|
|
16526
|
-
const base = cwd ?
|
|
16837
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16527
16838
|
switch (scope) {
|
|
16528
16839
|
case "user":
|
|
16529
|
-
return
|
|
16840
|
+
return resolve11(homedir23(), ".pi", "agent", "settings.json");
|
|
16530
16841
|
case "project":
|
|
16531
|
-
return
|
|
16842
|
+
return resolve11(base, ".pi", "settings.json");
|
|
16532
16843
|
case "local":
|
|
16533
|
-
return
|
|
16844
|
+
return resolve11(base, ".pi", "settings.json");
|
|
16534
16845
|
}
|
|
16535
16846
|
},
|
|
16536
16847
|
readSettings(settingsPath) {
|
|
@@ -16608,7 +16919,10 @@ var init_integrations = __esm(() => {
|
|
|
16608
16919
|
scopes: HERMES_HOOK_SCOPES,
|
|
16609
16920
|
eventTypes: HERMES_HOOK_EVENT_TYPES,
|
|
16610
16921
|
getSettingsPath() {
|
|
16611
|
-
return
|
|
16922
|
+
return resolve11(hermesRoot(), "config.yaml");
|
|
16923
|
+
},
|
|
16924
|
+
getSettingsPaths() {
|
|
16925
|
+
return listHermesProfiles().map((p) => resolve11(p.home, "config.yaml"));
|
|
16612
16926
|
},
|
|
16613
16927
|
readSettings(settingsPath) {
|
|
16614
16928
|
return readYamlDoc(settingsPath);
|
|
@@ -16675,21 +16989,8 @@ var init_integrations = __esm(() => {
|
|
|
16675
16989
|
return removed;
|
|
16676
16990
|
},
|
|
16677
16991
|
hooksInstalledInSettings(scope, cwd) {
|
|
16678
|
-
const
|
|
16679
|
-
|
|
16680
|
-
return false;
|
|
16681
|
-
try {
|
|
16682
|
-
const doc = readYamlDoc(settingsPath);
|
|
16683
|
-
const js = doc.toJS() ?? {};
|
|
16684
|
-
const hooks = js.hooks;
|
|
16685
|
-
if (!hooks || typeof hooks !== "object")
|
|
16686
|
-
return false;
|
|
16687
|
-
for (const entries of Object.values(hooks)) {
|
|
16688
|
-
if (Array.isArray(entries) && entries.some((h) => isMarkedHook(h)))
|
|
16689
|
-
return true;
|
|
16690
|
-
}
|
|
16691
|
-
} catch {}
|
|
16692
|
-
return false;
|
|
16992
|
+
const paths = settingsPathsFor(this, scope, cwd);
|
|
16993
|
+
return paths.length > 0 && paths.every((p) => hermesConfigHasHooks(p));
|
|
16693
16994
|
},
|
|
16694
16995
|
detectInstalled() {
|
|
16695
16996
|
return binaryExists("hermes");
|
|
@@ -16701,7 +17002,7 @@ var init_integrations = __esm(() => {
|
|
|
16701
17002
|
scopes: OPENCLAW_HOOK_SCOPES,
|
|
16702
17003
|
eventTypes: OPENCLAW_HOOK_EVENT_TYPES,
|
|
16703
17004
|
getSettingsPath() {
|
|
16704
|
-
return
|
|
17005
|
+
return resolve11(homedir23(), ".openclaw", "openclaw.json");
|
|
16705
17006
|
},
|
|
16706
17007
|
readSettings(settingsPath) {
|
|
16707
17008
|
return readJsonFile(settingsPath);
|
|
@@ -16797,14 +17098,14 @@ var init_integrations = __esm(() => {
|
|
|
16797
17098
|
scopes: FACTORY_HOOK_SCOPES,
|
|
16798
17099
|
eventTypes: FACTORY_HOOK_EVENT_TYPES,
|
|
16799
17100
|
getSettingsPath(scope, cwd) {
|
|
16800
|
-
const base = cwd ?
|
|
17101
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16801
17102
|
switch (scope) {
|
|
16802
17103
|
case "user":
|
|
16803
|
-
return
|
|
17104
|
+
return resolve11(homedir23(), ".factory", "hooks.json");
|
|
16804
17105
|
case "project":
|
|
16805
|
-
return
|
|
17106
|
+
return resolve11(base, ".factory", "hooks.json");
|
|
16806
17107
|
case "local":
|
|
16807
|
-
return
|
|
17108
|
+
return resolve11(base, ".factory", "hooks.json");
|
|
16808
17109
|
}
|
|
16809
17110
|
},
|
|
16810
17111
|
readSettings(settingsPath) {
|
|
@@ -16899,14 +17200,14 @@ var init_integrations = __esm(() => {
|
|
|
16899
17200
|
scopes: DEVIN_HOOK_SCOPES,
|
|
16900
17201
|
eventTypes: DEVIN_HOOK_EVENT_TYPES,
|
|
16901
17202
|
getSettingsPath(scope, cwd) {
|
|
16902
|
-
const base = cwd ?
|
|
17203
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
16903
17204
|
switch (scope) {
|
|
16904
17205
|
case "user":
|
|
16905
|
-
return
|
|
17206
|
+
return resolve11(homedir23(), ".config", "devin", "config.json");
|
|
16906
17207
|
case "project":
|
|
16907
|
-
return
|
|
17208
|
+
return resolve11(base, ".devin", "config.json");
|
|
16908
17209
|
case "local":
|
|
16909
|
-
return
|
|
17210
|
+
return resolve11(base, ".devin", "config.json");
|
|
16910
17211
|
}
|
|
16911
17212
|
},
|
|
16912
17213
|
readSettings(settingsPath) {
|
|
@@ -17008,14 +17309,14 @@ var init_integrations = __esm(() => {
|
|
|
17008
17309
|
scopes: ANTIGRAVITY_HOOK_SCOPES,
|
|
17009
17310
|
eventTypes: ANTIGRAVITY_HOOK_EVENT_TYPES,
|
|
17010
17311
|
getSettingsPath(scope, cwd) {
|
|
17011
|
-
const base = cwd ?
|
|
17312
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
17012
17313
|
switch (scope) {
|
|
17013
17314
|
case "user":
|
|
17014
|
-
return
|
|
17315
|
+
return resolve11(homedir23(), ".gemini", "config", "hooks.json");
|
|
17015
17316
|
case "project":
|
|
17016
|
-
return
|
|
17317
|
+
return resolve11(base, ".agents", "hooks.json");
|
|
17017
17318
|
case "local":
|
|
17018
|
-
return
|
|
17319
|
+
return resolve11(base, ".agents", "hooks.json");
|
|
17019
17320
|
}
|
|
17020
17321
|
},
|
|
17021
17322
|
readSettings(settingsPath) {
|
|
@@ -17149,14 +17450,14 @@ var init_integrations = __esm(() => {
|
|
|
17149
17450
|
scopes: GOOSE_HOOK_SCOPES,
|
|
17150
17451
|
eventTypes: GOOSE_HOOK_EVENT_TYPES,
|
|
17151
17452
|
getSettingsPath(scope, cwd) {
|
|
17152
|
-
const base = cwd ?
|
|
17453
|
+
const base = cwd ? resolve11(cwd) : process.cwd();
|
|
17153
17454
|
switch (scope) {
|
|
17154
17455
|
case "user":
|
|
17155
|
-
return
|
|
17456
|
+
return resolve11(homedir23(), ".agents", "plugins", "failproofai", "hooks", "hooks.json");
|
|
17156
17457
|
case "project":
|
|
17157
|
-
return
|
|
17458
|
+
return resolve11(base, ".agents", "plugins", "failproofai", "hooks", "hooks.json");
|
|
17158
17459
|
case "local":
|
|
17159
|
-
return
|
|
17460
|
+
return resolve11(base, ".agents", "plugins", "failproofai", "hooks", "hooks.json");
|
|
17160
17461
|
}
|
|
17161
17462
|
},
|
|
17162
17463
|
readSettings(settingsPath) {
|
|
@@ -17491,7 +17792,7 @@ function runPrompt(p) {
|
|
|
17491
17792
|
`${c.dim(BAR)} ${c.dim(p.summaryFor(result))}`
|
|
17492
17793
|
]);
|
|
17493
17794
|
};
|
|
17494
|
-
return new Promise((
|
|
17795
|
+
return new Promise((resolve12) => {
|
|
17495
17796
|
hideCursor(stdout);
|
|
17496
17797
|
repaint(stdout, region, build());
|
|
17497
17798
|
readline.emitKeypressEvents(stdin);
|
|
@@ -17507,7 +17808,7 @@ function runPrompt(p) {
|
|
|
17507
17808
|
const finish = (result) => {
|
|
17508
17809
|
cleanup();
|
|
17509
17810
|
collapse(result);
|
|
17510
|
-
|
|
17811
|
+
resolve12(result);
|
|
17511
17812
|
};
|
|
17512
17813
|
function onKey(_s, key) {
|
|
17513
17814
|
if (!key)
|
|
@@ -17808,7 +18109,7 @@ async function promptPolicySelection(preSelected, options = {}) {
|
|
|
17808
18109
|
`);
|
|
17809
18110
|
lastLineCount = lines.length;
|
|
17810
18111
|
}
|
|
17811
|
-
return new Promise((
|
|
18112
|
+
return new Promise((resolve12) => {
|
|
17812
18113
|
render();
|
|
17813
18114
|
process.stdin.setRawMode(true);
|
|
17814
18115
|
process.stdin.resume();
|
|
@@ -17845,7 +18146,7 @@ async function promptPolicySelection(preSelected, options = {}) {
|
|
|
17845
18146
|
${dim(STEP_DONE)} Policies
|
|
17846
18147
|
${dim(BAR)} ${dim(`${selected.length} selected`)}
|
|
17847
18148
|
`);
|
|
17848
|
-
|
|
18149
|
+
resolve12(selected);
|
|
17849
18150
|
} else if (key.name === "escape") {
|
|
17850
18151
|
search = "";
|
|
17851
18152
|
cursor2 = 0;
|
|
@@ -17908,7 +18209,7 @@ __export(exports_manager, {
|
|
|
17908
18209
|
});
|
|
17909
18210
|
import { execSync as execSync6 } from "node:child_process";
|
|
17910
18211
|
import { existsSync as existsSync12 } from "node:fs";
|
|
17911
|
-
import { resolve as
|
|
18212
|
+
import { resolve as resolve12, basename as basename4 } from "node:path";
|
|
17912
18213
|
import { homedir as homedir24, platform as platform3, arch as arch3, release as release2, hostname as hostname3 } from "node:os";
|
|
17913
18214
|
function getSettingsPath(scope, cwd) {
|
|
17914
18215
|
return claudeCode.getSettingsPath(scope, cwd);
|
|
@@ -18014,34 +18315,45 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
|
|
|
18014
18315
|
const configToWrite = { ...previousConfig, enabledPolicies: selectedPolicies };
|
|
18015
18316
|
if (removeCustomHooks) {
|
|
18016
18317
|
delete configToWrite.customPoliciesPath;
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
|
|
18022
|
-
|
|
18023
|
-
|
|
18024
|
-
|
|
18025
|
-
|
|
18026
|
-
|
|
18027
|
-
|
|
18028
|
-
|
|
18029
|
-
|
|
18030
|
-
console.error(`Error: ${msg}`);
|
|
18031
|
-
process.exit(1);
|
|
18032
|
-
}
|
|
18033
|
-
if (validatedHooks.length === 0) {
|
|
18318
|
+
delete configToWrite.customPoliciesPaths;
|
|
18319
|
+
} else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
|
|
18320
|
+
const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path3) => resolve12(path3));
|
|
18321
|
+
const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path3) => resolve12(path3)).filter((path3) => {
|
|
18322
|
+
if (existsSync12(path3))
|
|
18323
|
+
return true;
|
|
18324
|
+
console.log(`Dropping custom policies path (file no longer exists): ${path3}`);
|
|
18325
|
+
return false;
|
|
18326
|
+
});
|
|
18327
|
+
configToWrite.customPoliciesPaths = replace ? [...new Set(incoming)] : [...new Set([...carried, ...incoming])];
|
|
18328
|
+
delete configToWrite.customPoliciesPath;
|
|
18329
|
+
for (const path3 of incoming) {
|
|
18330
|
+
let validatedHooks = [];
|
|
18034
18331
|
try {
|
|
18035
|
-
await
|
|
18036
|
-
|
|
18037
|
-
|
|
18038
|
-
|
|
18039
|
-
|
|
18040
|
-
|
|
18041
|
-
|
|
18332
|
+
validatedHooks = await loadCustomHooks(path3, { strict: true });
|
|
18333
|
+
} catch (err) {
|
|
18334
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
18335
|
+
try {
|
|
18336
|
+
await trackHookEvent2(getInstanceId2(), "custom_policy_validation_failed", {
|
|
18337
|
+
scope,
|
|
18338
|
+
error_type: /not found/i.test(msg) ? "file_not_found" : "load_error"
|
|
18339
|
+
});
|
|
18340
|
+
} catch {}
|
|
18341
|
+
console.error(`Error: ${msg}`);
|
|
18342
|
+
process.exit(1);
|
|
18343
|
+
}
|
|
18344
|
+
if (validatedHooks.length === 0) {
|
|
18345
|
+
try {
|
|
18346
|
+
await trackHookEvent2(getInstanceId2(), "custom_policy_validation_failed", {
|
|
18347
|
+
scope,
|
|
18348
|
+
error_type: "no_hooks_registered"
|
|
18349
|
+
});
|
|
18350
|
+
} catch {}
|
|
18351
|
+
console.error(`Error: no hooks registered in ${path3}. ` + `Make sure your file calls customPolicies.add(...) at least once.`);
|
|
18352
|
+
process.exit(1);
|
|
18353
|
+
}
|
|
18354
|
+
console.log(`
|
|
18355
|
+
Validated ${validatedHooks.length} custom hook(s) from ${path3}: ${validatedHooks.map((h) => h.name).join(", ")}`);
|
|
18042
18356
|
}
|
|
18043
|
-
console.log(`
|
|
18044
|
-
Validated ${validatedHooks.length} custom hook(s): ${validatedHooks.map((h) => h.name).join(", ")}`);
|
|
18045
18357
|
}
|
|
18046
18358
|
writeScopedHooksConfig(configToWrite, scope, cwd);
|
|
18047
18359
|
console.log(`
|
|
@@ -18049,18 +18361,21 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
|
|
|
18049
18361
|
`);
|
|
18050
18362
|
if (removeCustomHooks) {
|
|
18051
18363
|
console.log("Custom hooks path cleared.");
|
|
18052
|
-
} else if (configToWrite.customPoliciesPath) {
|
|
18053
|
-
|
|
18364
|
+
} else if (configToWrite.customPoliciesPaths?.length || configToWrite.customPoliciesPath) {
|
|
18365
|
+
const paths = configToWrite.customPoliciesPaths ?? [configToWrite.customPoliciesPath];
|
|
18366
|
+
console.log(`Custom hooks paths: ${paths.join(", ")}`);
|
|
18054
18367
|
}
|
|
18055
18368
|
const writtenSettingsPaths = [];
|
|
18056
18369
|
for (const cliId of selectedClis) {
|
|
18057
18370
|
const integration = getIntegration(cliId);
|
|
18058
|
-
const
|
|
18371
|
+
const settingsPaths = settingsPathsFor(integration, scope, cwd);
|
|
18059
18372
|
try {
|
|
18060
|
-
const
|
|
18061
|
-
|
|
18062
|
-
|
|
18063
|
-
|
|
18373
|
+
for (const settingsPath of settingsPaths) {
|
|
18374
|
+
const settings = integration.readSettings(settingsPath);
|
|
18375
|
+
integration.writeHookEntries(settings, binaryPath, scope);
|
|
18376
|
+
integration.writeSettings(settingsPath, settings);
|
|
18377
|
+
writtenSettingsPaths.push({ cli: cliId, path: settingsPath });
|
|
18378
|
+
}
|
|
18064
18379
|
} catch (err) {
|
|
18065
18380
|
const errorType = err instanceof Error && /EACCES|EPERM/.test(err.message) ? "permission_denied" : err instanceof Error && /ENOENT|ENOTDIR/.test(err.message) ? "path_not_found" : "write_error";
|
|
18066
18381
|
try {
|
|
@@ -18091,7 +18406,7 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
|
|
|
18091
18406
|
arch: arch3(),
|
|
18092
18407
|
os_release: release2(),
|
|
18093
18408
|
hostname_hash: hashToId2(hostname3()),
|
|
18094
|
-
has_custom_hooks_path: !!configToWrite.customPoliciesPath,
|
|
18409
|
+
has_custom_hooks_path: !!(configToWrite.customPoliciesPaths?.length || configToWrite.customPoliciesPath),
|
|
18095
18410
|
has_policy_params: !!(configToWrite.policyParams && Object.keys(configToWrite.policyParams).length > 0),
|
|
18096
18411
|
param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
|
|
18097
18412
|
command_format: scope === "project" ? "npx" : "absolute"
|
|
@@ -18146,6 +18461,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
|
|
|
18146
18461
|
if (opts?.removeCustomHooks) {
|
|
18147
18462
|
const config = readScopedHooksConfig(configScope, cwd);
|
|
18148
18463
|
delete config.customPoliciesPath;
|
|
18464
|
+
delete config.customPoliciesPaths;
|
|
18149
18465
|
writeScopedHooksConfig(config, configScope, cwd);
|
|
18150
18466
|
console.log("Custom hooks path cleared.");
|
|
18151
18467
|
}
|
|
@@ -18194,25 +18510,30 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
|
|
|
18194
18510
|
const integration = getIntegration(cliId);
|
|
18195
18511
|
const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
|
|
18196
18512
|
for (const s of scopesToRemove) {
|
|
18197
|
-
const
|
|
18198
|
-
|
|
18513
|
+
const settingsPaths = settingsPathsFor(integration, s, cwd);
|
|
18514
|
+
const existing = settingsPaths.filter((p) => existsSync12(p));
|
|
18515
|
+
if (existing.length === 0) {
|
|
18199
18516
|
if (scope !== "all" && selectedClis.length === 1) {
|
|
18200
18517
|
console.log("No settings file found. Nothing to remove.");
|
|
18201
18518
|
nothingToReport = true;
|
|
18202
18519
|
}
|
|
18203
18520
|
continue;
|
|
18204
18521
|
}
|
|
18205
|
-
|
|
18206
|
-
|
|
18522
|
+
let removedHere = 0;
|
|
18523
|
+
for (const settingsPath of existing) {
|
|
18524
|
+
const removed = integration.removeHooksFromFile(settingsPath);
|
|
18525
|
+
removedHere += removed;
|
|
18526
|
+
if (removed > 0 && scope !== "all") {
|
|
18527
|
+
console.log(`Removed ${removed} failproofai hook(s) from ${integration.displayName} settings.`);
|
|
18528
|
+
console.log(`Settings: ${settingsPath}`);
|
|
18529
|
+
}
|
|
18530
|
+
}
|
|
18531
|
+
if (removedHere === 0 && scope !== "all" && selectedClis.length === 1) {
|
|
18207
18532
|
console.log("No hooks found in settings. Nothing to remove.");
|
|
18208
18533
|
nothingToReport = true;
|
|
18209
18534
|
continue;
|
|
18210
18535
|
}
|
|
18211
|
-
totalRemoved +=
|
|
18212
|
-
if (scope !== "all") {
|
|
18213
|
-
console.log(`Removed ${removed} failproofai hook(s) from ${integration.displayName} settings.`);
|
|
18214
|
-
console.log(`Settings: ${settingsPath}`);
|
|
18215
|
-
}
|
|
18536
|
+
totalRemoved += removedHere;
|
|
18216
18537
|
}
|
|
18217
18538
|
}
|
|
18218
18539
|
if (nothingToReport && totalRemoved === 0)
|
|
@@ -18222,7 +18543,9 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
|
|
|
18222
18543
|
for (const cliId of selectedClis) {
|
|
18223
18544
|
const integration = getIntegration(cliId);
|
|
18224
18545
|
for (const s of integration.scopes) {
|
|
18225
|
-
|
|
18546
|
+
for (const p of settingsPathsFor(integration, s, cwd)) {
|
|
18547
|
+
console.log(` ${integration.displayName} / ${s}: ${p}`);
|
|
18548
|
+
}
|
|
18226
18549
|
}
|
|
18227
18550
|
}
|
|
18228
18551
|
}
|
|
@@ -18244,20 +18567,21 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
|
|
|
18244
18567
|
if (scope === "all") {
|
|
18245
18568
|
for (const s of HOOK_SCOPES) {
|
|
18246
18569
|
const existing = readScopedHooksConfig(s, cwd);
|
|
18247
|
-
if (existing.enabledPolicies.length > 0 || existing.customPoliciesPath || existing.policyParams) {
|
|
18248
|
-
const { customPoliciesPath: _drop, policyParams: _dropParams, ...rest } = existing;
|
|
18570
|
+
if (existing.enabledPolicies.length > 0 || existing.customPoliciesPaths?.length || existing.customPoliciesPath || existing.policyParams) {
|
|
18571
|
+
const { customPoliciesPath: _drop, customPoliciesPaths: _dropMany, policyParams: _dropParams, ...rest } = existing;
|
|
18249
18572
|
writeScopedHooksConfig({ ...rest, enabledPolicies: [] }, s, cwd);
|
|
18250
18573
|
}
|
|
18251
18574
|
}
|
|
18252
18575
|
} else if (!HOOK_SCOPES.some((s) => hooksInstalledInSettings(s, cwd))) {
|
|
18253
18576
|
const existing = readScopedHooksConfig(configScope, cwd);
|
|
18254
|
-
const { customPoliciesPath: _drop, policyParams: _dropParams, ...rest } = existing;
|
|
18577
|
+
const { customPoliciesPath: _drop, customPoliciesPaths: _dropMany, policyParams: _dropParams, ...rest } = existing;
|
|
18255
18578
|
writeScopedHooksConfig({ ...rest, enabledPolicies: [] }, configScope, cwd);
|
|
18256
18579
|
}
|
|
18257
18580
|
}
|
|
18258
18581
|
async function listHooks(cwd) {
|
|
18259
18582
|
const config = readMergedHooksConfig(cwd);
|
|
18260
18583
|
const enabledSet = new Set(config.enabledPolicies);
|
|
18584
|
+
const disabledCustomSet = new Set(config.disabledCustomPolicies ?? []);
|
|
18261
18585
|
const uniqueScopes = deduplicateScopes(HOOK_SCOPES, cwd);
|
|
18262
18586
|
const installedScopes = uniqueScopes.filter((s) => hooksInstalledInSettings(s, cwd));
|
|
18263
18587
|
const regularPolicies = BUILTIN_POLICIES.filter((p) => !p.beta);
|
|
@@ -18381,53 +18705,86 @@ Failproof AI Hook Policies
|
|
|
18381
18705
|
} catch {}
|
|
18382
18706
|
}
|
|
18383
18707
|
}
|
|
18384
|
-
|
|
18708
|
+
const explicitPaths = configuredCustomPolicyPaths(config);
|
|
18709
|
+
if (explicitPaths.length > 0) {
|
|
18385
18710
|
console.log(`
|
|
18386
|
-
── Custom Policies
|
|
18387
|
-
|
|
18388
|
-
|
|
18389
|
-
|
|
18390
|
-
|
|
18711
|
+
── Custom Policies ───────────────────────`);
|
|
18712
|
+
for (const path3 of explicitPaths) {
|
|
18713
|
+
const absPath = resolve12(findProjectConfigDir(cwd ?? process.cwd()), path3);
|
|
18714
|
+
console.log(` ${absPath}`);
|
|
18715
|
+
if (!existsSync12(absPath)) {
|
|
18716
|
+
console.log(` \x1B[31m✗ File not found: ${absPath}\x1B[0m`);
|
|
18717
|
+
continue;
|
|
18718
|
+
}
|
|
18719
|
+
const hooks = await loadCustomHooks(absPath);
|
|
18391
18720
|
if (hooks.length === 0) {
|
|
18392
18721
|
console.log(` \x1B[31m✗ ERR failed to load (check ~/.failproofai/logs/hooks.log)\x1B[0m`);
|
|
18393
18722
|
} else {
|
|
18394
18723
|
const descColWidth = nameColWidth;
|
|
18395
18724
|
for (const hook of hooks) {
|
|
18396
|
-
|
|
18725
|
+
const disabled = disabledCustomSet.has(`custom:${absPath}:${hook.name}`);
|
|
18726
|
+
const status = disabled ? "\x1B[2m OFF\x1B[0m" : "\x1B[32m✓ ON\x1B[0m";
|
|
18727
|
+
console.log(` ${status} ${hook.name.padEnd(descColWidth)}${hook.description ?? ""}`);
|
|
18397
18728
|
}
|
|
18398
18729
|
}
|
|
18399
18730
|
}
|
|
18400
18731
|
console.log();
|
|
18401
18732
|
}
|
|
18402
|
-
const base =
|
|
18733
|
+
const base = findProjectConfigDir(cwd ?? process.cwd());
|
|
18734
|
+
const projectDir = resolve12(base, ".failproofai", "policies");
|
|
18735
|
+
const userDir = resolve12(homedir24(), ".failproofai", "policies");
|
|
18736
|
+
const sameDir = userDir === projectDir;
|
|
18403
18737
|
const conventionDirs = [
|
|
18404
|
-
{ label: "Project"
|
|
18405
|
-
{ label: "User", dir:
|
|
18738
|
+
{ label: sameDir ? "Project + User" : "Project", dir: projectDir },
|
|
18739
|
+
...sameDir ? [] : [{ label: "User", dir: userDir }]
|
|
18406
18740
|
];
|
|
18741
|
+
const discovered = {
|
|
18742
|
+
project: [],
|
|
18743
|
+
user: []
|
|
18744
|
+
};
|
|
18407
18745
|
for (const { label, dir } of conventionDirs) {
|
|
18408
18746
|
const files = discoverPolicyFiles(dir);
|
|
18409
18747
|
if (files.length === 0)
|
|
18410
18748
|
continue;
|
|
18749
|
+
const targets = dir === projectDir && dir === userDir ? ["project", "user"] : dir === projectDir ? ["project"] : ["user"];
|
|
18750
|
+
const policyScope = dir === projectDir ? "project" : "user";
|
|
18751
|
+
const record = (file, hooks) => {
|
|
18752
|
+
for (const t of targets)
|
|
18753
|
+
discovered[t].push({ file, hooks });
|
|
18754
|
+
};
|
|
18411
18755
|
console.log(`
|
|
18412
18756
|
── Convention Policies — ${label} (${dir}) ──────────`);
|
|
18757
|
+
const colWidth = Math.max(nameColWidth, ...files.map((f) => basename4(f).length + 2));
|
|
18413
18758
|
for (const file of files) {
|
|
18414
18759
|
try {
|
|
18415
18760
|
const hooks = await loadCustomHooks(file);
|
|
18761
|
+
const filename = basename4(file);
|
|
18762
|
+
record(filename, hooks.map((h) => h.name));
|
|
18416
18763
|
if (hooks.length === 0) {
|
|
18417
|
-
|
|
18418
|
-
console.log(` \x1B[31m✗\x1B[0m ${filename.padEnd(nameColWidth)}\x1B[31mfailed to load\x1B[0m`);
|
|
18764
|
+
console.log(` \x1B[31m✗\x1B[0m ${filename.padEnd(colWidth)}\x1B[31mfailed to load\x1B[0m`);
|
|
18419
18765
|
} else {
|
|
18420
|
-
const
|
|
18421
|
-
|
|
18422
|
-
|
|
18766
|
+
const hookStates = hooks.map((hook) => ({
|
|
18767
|
+
hook,
|
|
18768
|
+
disabled: disabledCustomSet.has(`convention:${policyScope}:${filename}:${hook.name}`)
|
|
18769
|
+
}));
|
|
18770
|
+
const disabledCount = hookStates.filter((entry) => entry.disabled).length;
|
|
18771
|
+
const status = disabledCount === 0 ? "\x1B[32m✓ ON\x1B[0m" : disabledCount === hooks.length ? "\x1B[2m OFF\x1B[0m" : "\x1B[33m◐ MIXED\x1B[0m";
|
|
18772
|
+
const hookSummary = hookStates.map(({ hook, disabled }) => `${hook.name}${disabled ? " (OFF)" : ""}`).join(", ");
|
|
18773
|
+
console.log(` ${status} ${filename.padEnd(colWidth)}${hooks.length} hook(s): ${hookSummary}`);
|
|
18423
18774
|
}
|
|
18424
18775
|
} catch {
|
|
18425
|
-
const filename =
|
|
18426
|
-
|
|
18776
|
+
const filename = basename4(file);
|
|
18777
|
+
record(filename, []);
|
|
18778
|
+
console.log(` \x1B[31m✗\x1B[0m ${filename.padEnd(colWidth)}\x1B[31merror\x1B[0m`);
|
|
18427
18779
|
}
|
|
18428
18780
|
}
|
|
18429
18781
|
console.log();
|
|
18430
18782
|
}
|
|
18783
|
+
try {
|
|
18784
|
+
syncConventionPolicies(discovered.user, "user");
|
|
18785
|
+
} catch (err) {
|
|
18786
|
+
hookLogWarn(`could not record convention policies in config: ${err instanceof Error ? err.message : String(err)}`);
|
|
18787
|
+
}
|
|
18431
18788
|
}
|
|
18432
18789
|
var VALID_POLICY_NAMES;
|
|
18433
18790
|
var init_manager = __esm(() => {
|
|
@@ -18440,6 +18797,7 @@ var init_manager = __esm(() => {
|
|
|
18440
18797
|
init_hook_telemetry2();
|
|
18441
18798
|
init_telemetry_id2();
|
|
18442
18799
|
init_cli_error();
|
|
18800
|
+
init_hook_logger();
|
|
18443
18801
|
VALID_POLICY_NAMES = new Set(BUILTIN_POLICIES.map((p) => p.name));
|
|
18444
18802
|
});
|
|
18445
18803
|
|
|
@@ -18604,7 +18962,7 @@ async function promptCliTargetSelection(detected, action = "install") {
|
|
|
18604
18962
|
lastLineCount = lines.length;
|
|
18605
18963
|
}
|
|
18606
18964
|
const itemCount = options.length;
|
|
18607
|
-
return new Promise((
|
|
18965
|
+
return new Promise((resolve13) => {
|
|
18608
18966
|
render();
|
|
18609
18967
|
readline3.emitKeypressEvents(process.stdin);
|
|
18610
18968
|
const wasRaw = process.stdin.isRaw;
|
|
@@ -18637,7 +18995,7 @@ async function promptCliTargetSelection(detected, action = "install") {
|
|
|
18637
18995
|
cleanup();
|
|
18638
18996
|
process.stdout.write(`
|
|
18639
18997
|
`);
|
|
18640
|
-
|
|
18998
|
+
resolve13(options[cursor2].value);
|
|
18641
18999
|
}
|
|
18642
19000
|
}
|
|
18643
19001
|
process.stdin.on("keypress", onKey);
|
|
@@ -18790,7 +19148,7 @@ async function promptPolicySelection2(preSelected, options = {}) {
|
|
|
18790
19148
|
`);
|
|
18791
19149
|
lastLineCount = lines.length;
|
|
18792
19150
|
}
|
|
18793
|
-
return new Promise((
|
|
19151
|
+
return new Promise((resolve13) => {
|
|
18794
19152
|
render();
|
|
18795
19153
|
process.stdin.setRawMode(true);
|
|
18796
19154
|
process.stdin.resume();
|
|
@@ -18827,7 +19185,7 @@ async function promptPolicySelection2(preSelected, options = {}) {
|
|
|
18827
19185
|
${dim(STEP_DONE)} Policies
|
|
18828
19186
|
${dim(BAR)} ${dim(`${selected.length} selected`)}
|
|
18829
19187
|
`);
|
|
18830
|
-
|
|
19188
|
+
resolve13(selected);
|
|
18831
19189
|
} else if (key.name === "escape") {
|
|
18832
19190
|
search = "";
|
|
18833
19191
|
cursor2 = 0;
|
|
@@ -19014,12 +19372,12 @@ import {
|
|
|
19014
19372
|
statSync as statSync11,
|
|
19015
19373
|
writeFileSync as writeFileSync7
|
|
19016
19374
|
} from "node:fs";
|
|
19017
|
-
import { dirname as
|
|
19375
|
+
import { dirname as dirname6 } from "node:path";
|
|
19018
19376
|
import { randomBytes } from "node:crypto";
|
|
19019
19377
|
function writeJsonAtomically(filePath, value, opts = {}) {
|
|
19020
19378
|
const mode = opts.mode ?? 384;
|
|
19021
19379
|
const dirMode = opts.dirMode ?? 448;
|
|
19022
|
-
const dir =
|
|
19380
|
+
const dir = dirname6(filePath);
|
|
19023
19381
|
if (!existsSync13(dir))
|
|
19024
19382
|
mkdirSync8(dir, { recursive: true, mode: dirMode });
|
|
19025
19383
|
const tmp = `${filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
|
|
@@ -19046,15 +19404,15 @@ var init_atomic_write = () => {};
|
|
|
19046
19404
|
// lib/auth/auth-store.ts
|
|
19047
19405
|
import { existsSync as existsSync14, readFileSync as readFileSync13, rmSync as rmSync2 } from "node:fs";
|
|
19048
19406
|
import { homedir as homedir25 } from "node:os";
|
|
19049
|
-
import { join as
|
|
19407
|
+
import { join as join26 } from "node:path";
|
|
19050
19408
|
function getAuthDir() {
|
|
19051
19409
|
const override = process.env.FAILPROOFAI_AUTH_DIR;
|
|
19052
19410
|
if (override)
|
|
19053
19411
|
return override;
|
|
19054
|
-
return
|
|
19412
|
+
return join26(homedir25(), ".failproofai");
|
|
19055
19413
|
}
|
|
19056
19414
|
function getAuthFilePath() {
|
|
19057
|
-
return
|
|
19415
|
+
return join26(getAuthDir(), "auth.json");
|
|
19058
19416
|
}
|
|
19059
19417
|
function readAuth() {
|
|
19060
19418
|
const p = getAuthFilePath();
|
|
@@ -19162,13 +19520,13 @@ function prompt(question, opts = {}) {
|
|
|
19162
19520
|
orig(s);
|
|
19163
19521
|
};
|
|
19164
19522
|
}
|
|
19165
|
-
return new Promise((
|
|
19523
|
+
return new Promise((resolve13) => {
|
|
19166
19524
|
rl.question(question, (answer) => {
|
|
19167
19525
|
rl.close();
|
|
19168
19526
|
if (opts.hidden && process.stdin.isTTY)
|
|
19169
19527
|
process.stdout.write(`
|
|
19170
19528
|
`);
|
|
19171
|
-
|
|
19529
|
+
resolve13(answer.trim());
|
|
19172
19530
|
});
|
|
19173
19531
|
});
|
|
19174
19532
|
}
|
|
@@ -19417,8 +19775,8 @@ EXAMPLES
|
|
|
19417
19775
|
});
|
|
19418
19776
|
|
|
19419
19777
|
// lib/claude-sessions.ts
|
|
19420
|
-
import { readdirSync as
|
|
19421
|
-
import { join as
|
|
19778
|
+
import { readdirSync as readdirSync11, statSync as statSync12, existsSync as existsSync15 } from "node:fs";
|
|
19779
|
+
import { join as join27, basename as basename5 } from "node:path";
|
|
19422
19780
|
function getClaudeProjectsRoot() {
|
|
19423
19781
|
return getClaudeProjectsPath();
|
|
19424
19782
|
}
|
|
@@ -19426,21 +19784,21 @@ function listClaudeProjects() {
|
|
|
19426
19784
|
const root = getClaudeProjectsRoot();
|
|
19427
19785
|
let entries;
|
|
19428
19786
|
try {
|
|
19429
|
-
entries =
|
|
19787
|
+
entries = readdirSync11(root, { withFileTypes: true });
|
|
19430
19788
|
} catch {
|
|
19431
19789
|
return [];
|
|
19432
19790
|
}
|
|
19433
19791
|
return entries.filter((e) => e.isDirectory()).map((e) => ({
|
|
19434
19792
|
name: e.name,
|
|
19435
19793
|
cwd: decodeFolderName(e.name),
|
|
19436
|
-
path:
|
|
19794
|
+
path: join27(root, e.name)
|
|
19437
19795
|
}));
|
|
19438
19796
|
}
|
|
19439
19797
|
function listClaudeTranscripts(project) {
|
|
19440
19798
|
const out = [];
|
|
19441
19799
|
let entries;
|
|
19442
19800
|
try {
|
|
19443
|
-
entries =
|
|
19801
|
+
entries = readdirSync11(project.path, { withFileTypes: true });
|
|
19444
19802
|
} catch {
|
|
19445
19803
|
return out;
|
|
19446
19804
|
}
|
|
@@ -19449,7 +19807,7 @@ function listClaudeTranscripts(project) {
|
|
|
19449
19807
|
const sessionId = entry.name.slice(0, -".jsonl".length);
|
|
19450
19808
|
if (!UUID_RE2.test(sessionId))
|
|
19451
19809
|
continue;
|
|
19452
|
-
const transcriptPath =
|
|
19810
|
+
const transcriptPath = join27(project.path, entry.name);
|
|
19453
19811
|
try {
|
|
19454
19812
|
const s = statSync12(transcriptPath);
|
|
19455
19813
|
out.push({
|
|
@@ -19463,12 +19821,12 @@ function listClaudeTranscripts(project) {
|
|
|
19463
19821
|
});
|
|
19464
19822
|
} catch {}
|
|
19465
19823
|
} else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
|
|
19466
|
-
const subDir =
|
|
19824
|
+
const subDir = join27(project.path, entry.name, "subagents");
|
|
19467
19825
|
if (!existsSync15(subDir))
|
|
19468
19826
|
continue;
|
|
19469
19827
|
let subEntries;
|
|
19470
19828
|
try {
|
|
19471
|
-
subEntries =
|
|
19829
|
+
subEntries = readdirSync11(subDir, { withFileTypes: true });
|
|
19472
19830
|
} catch {
|
|
19473
19831
|
continue;
|
|
19474
19832
|
}
|
|
@@ -19476,7 +19834,7 @@ function listClaudeTranscripts(project) {
|
|
|
19476
19834
|
if (!sub.isFile() || !sub.name.endsWith(".jsonl"))
|
|
19477
19835
|
continue;
|
|
19478
19836
|
const agentId = sub.name.slice(0, -".jsonl".length);
|
|
19479
|
-
const transcriptPath =
|
|
19837
|
+
const transcriptPath = join27(subDir, sub.name);
|
|
19480
19838
|
try {
|
|
19481
19839
|
const s = statSync12(transcriptPath);
|
|
19482
19840
|
out.push({
|
|
@@ -20051,7 +20409,7 @@ async function listHermesTranscriptMetadata(opts = {}) {
|
|
|
20051
20409
|
continue;
|
|
20052
20410
|
out.push({
|
|
20053
20411
|
cli: "hermes",
|
|
20054
|
-
projectName: s.source ? `hermes:${s.
|
|
20412
|
+
projectName: s.source ? hermesProjectPath(s.profile, s.source) : `hermes:${s.profile}`,
|
|
20055
20413
|
sessionId: s.sessionId,
|
|
20056
20414
|
transcriptPath: `hermes://${s.sessionId}`,
|
|
20057
20415
|
mtimeMs: s.mtimeMs,
|
|
@@ -20073,6 +20431,7 @@ async function streamHermesEvents(meta) {
|
|
|
20073
20431
|
}
|
|
20074
20432
|
var init_hermes = __esm(() => {
|
|
20075
20433
|
init_hermes_projects();
|
|
20434
|
+
init_hermes_profiles();
|
|
20076
20435
|
init_hermes_sessions();
|
|
20077
20436
|
init_shared();
|
|
20078
20437
|
});
|
|
@@ -20083,16 +20442,16 @@ async function listOpenClawTranscriptMetadata(opts = {}) {
|
|
|
20083
20442
|
return [];
|
|
20084
20443
|
const sinceMs = opts.sinceMs ?? 0;
|
|
20085
20444
|
const out = [];
|
|
20086
|
-
for (const
|
|
20087
|
-
if (
|
|
20445
|
+
for (const s of await getOpenClawSessions()) {
|
|
20446
|
+
if (s.mtimeMs < sinceMs)
|
|
20088
20447
|
continue;
|
|
20089
20448
|
out.push({
|
|
20090
20449
|
cli: "openclaw",
|
|
20091
|
-
projectName:
|
|
20092
|
-
sessionId:
|
|
20093
|
-
transcriptPath:
|
|
20094
|
-
mtimeMs:
|
|
20095
|
-
sizeBytes:
|
|
20450
|
+
projectName: openClawProjectPath(s.agentId, s.channel),
|
|
20451
|
+
sessionId: s.sessionId,
|
|
20452
|
+
transcriptPath: s.transcriptPath,
|
|
20453
|
+
mtimeMs: s.mtimeMs,
|
|
20454
|
+
sizeBytes: s.sizeBytes
|
|
20096
20455
|
});
|
|
20097
20456
|
}
|
|
20098
20457
|
return out;
|
|
@@ -20109,6 +20468,7 @@ async function streamOpenClawEvents(meta) {
|
|
|
20109
20468
|
});
|
|
20110
20469
|
}
|
|
20111
20470
|
var init_openclaw = __esm(() => {
|
|
20471
|
+
init_openclaw_projects();
|
|
20112
20472
|
init_openclaw_sessions();
|
|
20113
20473
|
init_shared();
|
|
20114
20474
|
});
|
|
@@ -20731,7 +21091,7 @@ var init_features = __esm(() => {
|
|
|
20731
21091
|
// src/audit/cache.ts
|
|
20732
21092
|
import { createHash } from "node:crypto";
|
|
20733
21093
|
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readFileSync as readFileSync14, writeFileSync as writeFileSync8, chmodSync as chmodSync2 } from "node:fs";
|
|
20734
|
-
import { join as
|
|
21094
|
+
import { join as join28 } from "node:path";
|
|
20735
21095
|
import { homedir as homedir26 } from "node:os";
|
|
20736
21096
|
function getEngineVersion() {
|
|
20737
21097
|
if (cachedEngineVersion)
|
|
@@ -20750,9 +21110,9 @@ function getDetectorVersion() {
|
|
|
20750
21110
|
return cachedDetectorVersion;
|
|
20751
21111
|
}
|
|
20752
21112
|
function getCachePathFor(transcriptPath) {
|
|
20753
|
-
const root =
|
|
21113
|
+
const root = join28(homedir26(), ".failproofai", "cache", "audit");
|
|
20754
21114
|
const key = createHash("sha1").update(transcriptPath).digest("hex");
|
|
20755
|
-
return
|
|
21115
|
+
return join28(root, `${key}.json`);
|
|
20756
21116
|
}
|
|
20757
21117
|
function readCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes) {
|
|
20758
21118
|
if (sizeBytes === 0)
|
|
@@ -20785,7 +21145,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result)
|
|
|
20785
21145
|
return;
|
|
20786
21146
|
const cachePath = getCachePathFor(transcriptPath);
|
|
20787
21147
|
try {
|
|
20788
|
-
mkdirSync9(
|
|
21148
|
+
mkdirSync9(join28(homedir26(), ".failproofai", "cache", "audit"), { recursive: true });
|
|
20789
21149
|
const entry = {
|
|
20790
21150
|
schemaVersion: CACHE_SCHEMA_VERSION,
|
|
20791
21151
|
cachedAt: Date.now(),
|
|
@@ -21157,10 +21517,10 @@ var init_audit = __esm(() => {
|
|
|
21157
21517
|
});
|
|
21158
21518
|
|
|
21159
21519
|
// src/audit/dashboard-cache.ts
|
|
21160
|
-
import { join as
|
|
21520
|
+
import { join as join29 } from "node:path";
|
|
21161
21521
|
import { homedir as homedir27 } from "node:os";
|
|
21162
21522
|
function getCachePath() {
|
|
21163
|
-
return
|
|
21523
|
+
return join29(homedir27(), ".failproofai", "audit-dashboard.json");
|
|
21164
21524
|
}
|
|
21165
21525
|
function writeDashboardCache(params, result) {
|
|
21166
21526
|
try {
|
|
@@ -21250,14 +21610,14 @@ var POLL_INTERVAL_MS = 150, POLL_TIMEOUT_MS = 30000;
|
|
|
21250
21610
|
var init_open_browser = () => {};
|
|
21251
21611
|
|
|
21252
21612
|
// scripts/parse-script-args.ts
|
|
21253
|
-
import { resolve as
|
|
21613
|
+
import { resolve as resolve13 } from "path";
|
|
21254
21614
|
function parseStringFlag(flagName, errorLabel, inlineValue, args, index, options) {
|
|
21255
21615
|
const raw = inlineValue ?? args[index + 1];
|
|
21256
21616
|
if (raw === undefined || inlineValue === null && raw.startsWith("-")) {
|
|
21257
21617
|
console.error(`Error: ${flagName} requires ${errorLabel}`);
|
|
21258
21618
|
process.exit(1);
|
|
21259
21619
|
}
|
|
21260
|
-
const value = options?.resolve ?
|
|
21620
|
+
const value = options?.resolve ? resolve13(raw) : raw;
|
|
21261
21621
|
return { value, spliceCount: inlineValue !== null ? 1 : 2 };
|
|
21262
21622
|
}
|
|
21263
21623
|
function parseScriptArgs(argv) {
|
|
@@ -21306,17 +21666,17 @@ var init_parse_script_args = () => {};
|
|
|
21306
21666
|
|
|
21307
21667
|
// scripts/install-diagnosis.mjs
|
|
21308
21668
|
import { existsSync as existsSync17, readFileSync as readFileSync15, realpathSync } from "node:fs";
|
|
21309
|
-
import { dirname as
|
|
21669
|
+
import { dirname as dirname7, resolve as resolve14 } from "node:path";
|
|
21310
21670
|
import { homedir as homedir28, platform as platform4 } from "node:os";
|
|
21311
21671
|
import { spawnSync } from "node:child_process";
|
|
21312
21672
|
function findPackageRoot(start) {
|
|
21313
21673
|
try {
|
|
21314
21674
|
let dir = realpathSync(start);
|
|
21315
|
-
if (existsSync17(dir) && !existsSync17(
|
|
21316
|
-
dir =
|
|
21675
|
+
if (existsSync17(dir) && !existsSync17(resolve14(dir, "package.json"))) {
|
|
21676
|
+
dir = dirname7(dir);
|
|
21317
21677
|
}
|
|
21318
21678
|
while (true) {
|
|
21319
|
-
const pkgPath =
|
|
21679
|
+
const pkgPath = resolve14(dir, "package.json");
|
|
21320
21680
|
if (existsSync17(pkgPath)) {
|
|
21321
21681
|
try {
|
|
21322
21682
|
const pkg = JSON.parse(readFileSync15(pkgPath, "utf8"));
|
|
@@ -21324,7 +21684,7 @@ function findPackageRoot(start) {
|
|
|
21324
21684
|
return dir;
|
|
21325
21685
|
} catch {}
|
|
21326
21686
|
}
|
|
21327
|
-
const parent =
|
|
21687
|
+
const parent = dirname7(dir);
|
|
21328
21688
|
if (parent === dir)
|
|
21329
21689
|
return null;
|
|
21330
21690
|
dir = parent;
|
|
@@ -21337,7 +21697,7 @@ function readPackageVersion(packageRoot) {
|
|
|
21337
21697
|
if (!packageRoot)
|
|
21338
21698
|
return null;
|
|
21339
21699
|
try {
|
|
21340
|
-
const pkg = JSON.parse(readFileSync15(
|
|
21700
|
+
const pkg = JSON.parse(readFileSync15(resolve14(packageRoot, "package.json"), "utf8"));
|
|
21341
21701
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
21342
21702
|
} catch {
|
|
21343
21703
|
return null;
|
|
@@ -21363,16 +21723,16 @@ function locateNpmGlobal() {
|
|
|
21363
21723
|
const root = (res.stdout || "").trim();
|
|
21364
21724
|
if (!root)
|
|
21365
21725
|
return null;
|
|
21366
|
-
const candidate =
|
|
21367
|
-
return existsSync17(
|
|
21726
|
+
const candidate = resolve14(root, PKG_NAME);
|
|
21727
|
+
return existsSync17(resolve14(candidate, "package.json")) ? candidate : null;
|
|
21368
21728
|
} catch {
|
|
21369
21729
|
return null;
|
|
21370
21730
|
}
|
|
21371
21731
|
}
|
|
21372
21732
|
function locateBunGlobal() {
|
|
21373
21733
|
try {
|
|
21374
|
-
const candidate =
|
|
21375
|
-
return existsSync17(
|
|
21734
|
+
const candidate = resolve14(homedir28(), ".bun", "install", "global", "node_modules", PKG_NAME);
|
|
21735
|
+
return existsSync17(resolve14(candidate, "package.json")) ? candidate : null;
|
|
21376
21736
|
} catch {
|
|
21377
21737
|
return null;
|
|
21378
21738
|
}
|
|
@@ -21380,8 +21740,8 @@ function locateBunGlobal() {
|
|
|
21380
21740
|
function buildRecommendation(pathFirstBin) {
|
|
21381
21741
|
if (!pathFirstBin)
|
|
21382
21742
|
return null;
|
|
21383
|
-
const bunBinPrefix =
|
|
21384
|
-
const bunGlobalPrefix =
|
|
21743
|
+
const bunBinPrefix = resolve14(homedir28(), ".bun", "bin") + "/";
|
|
21744
|
+
const bunGlobalPrefix = resolve14(homedir28(), ".bun", "install", "global") + "/";
|
|
21385
21745
|
const isBun = pathFirstBin.startsWith(bunBinPrefix) || pathFirstBin.startsWith(bunGlobalPrefix);
|
|
21386
21746
|
if (isBun) {
|
|
21387
21747
|
return `rm -f ~/.bun/bin/${PKG_NAME} && rm -rf ~/.bun/install/global/node_modules/${PKG_NAME}`;
|
|
@@ -21462,7 +21822,7 @@ __export(exports_launch, {
|
|
|
21462
21822
|
});
|
|
21463
21823
|
import { spawn as spawn2 } from "child_process";
|
|
21464
21824
|
import { realpathSync as realpathSync2, existsSync as existsSync18 } from "node:fs";
|
|
21465
|
-
import { resolve as
|
|
21825
|
+
import { resolve as resolve15, dirname as dirname8 } from "node:path";
|
|
21466
21826
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
21467
21827
|
import { createInterface as createInterface2 } from "node:readline";
|
|
21468
21828
|
function launch(mode) {
|
|
@@ -21477,8 +21837,8 @@ function launch(mode) {
|
|
|
21477
21837
|
process.env.PORT = port;
|
|
21478
21838
|
process.env.HOSTNAME = "0.0.0.0";
|
|
21479
21839
|
cmd = "node";
|
|
21480
|
-
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ??
|
|
21481
|
-
const serverJsPath =
|
|
21840
|
+
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve15(dirname8(realpathSync2(fileURLToPath2(import.meta.url))), "..");
|
|
21841
|
+
const serverJsPath = resolve15(packageRoot, ".next/standalone/server.js");
|
|
21482
21842
|
if (!existsSync18(serverJsPath)) {
|
|
21483
21843
|
let shadowMessage = null;
|
|
21484
21844
|
try {
|
|
@@ -21517,6 +21877,7 @@ Error: Cannot find server.js at:
|
|
|
21517
21877
|
stdio: filterLogs ? ["inherit", "pipe", "pipe"] : "inherit",
|
|
21518
21878
|
env: {
|
|
21519
21879
|
...process.env,
|
|
21880
|
+
FAILPROOFAI_LAUNCH_CWD: process.env.FAILPROOFAI_LAUNCH_CWD ?? process.cwd(),
|
|
21520
21881
|
...filterLogs ? { FORCE_COLOR: process.env.FORCE_COLOR ?? "1" } : {},
|
|
21521
21882
|
...loggingLevel ? { FAILPROOFAI_LOG_LEVEL: loggingLevel } : {},
|
|
21522
21883
|
...disableTelemetry ? { FAILPROOFAI_TELEMETRY_DISABLED: "1" } : {},
|
|
@@ -21830,7 +22191,8 @@ WHAT IT DOES
|
|
|
21830
22191
|
|
|
21831
22192
|
// src/hooks/manager.ts
|
|
21832
22193
|
import { execSync as execSync7 } from "node:child_process";
|
|
21833
|
-
import {
|
|
22194
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
22195
|
+
import { resolve as resolve16, basename as basename6 } from "node:path";
|
|
21834
22196
|
import { homedir as homedir29, platform as platform5, arch as arch4, release as release3, hostname as hostname4 } from "node:os";
|
|
21835
22197
|
function getSettingsPath2(scope, cwd) {
|
|
21836
22198
|
return claudeCode.getSettingsPath(scope, cwd);
|
|
@@ -21936,34 +22298,45 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
|
|
|
21936
22298
|
const configToWrite = { ...previousConfig, enabledPolicies: selectedPolicies };
|
|
21937
22299
|
if (removeCustomHooks) {
|
|
21938
22300
|
delete configToWrite.customPoliciesPath;
|
|
21939
|
-
|
|
21940
|
-
|
|
21941
|
-
|
|
21942
|
-
|
|
21943
|
-
|
|
21944
|
-
|
|
21945
|
-
|
|
21946
|
-
|
|
21947
|
-
|
|
21948
|
-
|
|
21949
|
-
|
|
21950
|
-
|
|
21951
|
-
|
|
21952
|
-
console.error(`Error: ${msg}`);
|
|
21953
|
-
process.exit(1);
|
|
21954
|
-
}
|
|
21955
|
-
if (validatedHooks.length === 0) {
|
|
22301
|
+
delete configToWrite.customPoliciesPaths;
|
|
22302
|
+
} else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
|
|
22303
|
+
const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path3) => resolve16(path3));
|
|
22304
|
+
const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path3) => resolve16(path3)).filter((path3) => {
|
|
22305
|
+
if (existsSync19(path3))
|
|
22306
|
+
return true;
|
|
22307
|
+
console.log(`Dropping custom policies path (file no longer exists): ${path3}`);
|
|
22308
|
+
return false;
|
|
22309
|
+
});
|
|
22310
|
+
configToWrite.customPoliciesPaths = replace ? [...new Set(incoming)] : [...new Set([...carried, ...incoming])];
|
|
22311
|
+
delete configToWrite.customPoliciesPath;
|
|
22312
|
+
for (const path3 of incoming) {
|
|
22313
|
+
let validatedHooks = [];
|
|
21956
22314
|
try {
|
|
21957
|
-
await
|
|
21958
|
-
|
|
21959
|
-
|
|
21960
|
-
|
|
21961
|
-
|
|
21962
|
-
|
|
21963
|
-
|
|
22315
|
+
validatedHooks = await loadCustomHooks(path3, { strict: true });
|
|
22316
|
+
} catch (err) {
|
|
22317
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
22318
|
+
try {
|
|
22319
|
+
await trackHookEvent2(getInstanceId2(), "custom_policy_validation_failed", {
|
|
22320
|
+
scope,
|
|
22321
|
+
error_type: /not found/i.test(msg) ? "file_not_found" : "load_error"
|
|
22322
|
+
});
|
|
22323
|
+
} catch {}
|
|
22324
|
+
console.error(`Error: ${msg}`);
|
|
22325
|
+
process.exit(1);
|
|
22326
|
+
}
|
|
22327
|
+
if (validatedHooks.length === 0) {
|
|
22328
|
+
try {
|
|
22329
|
+
await trackHookEvent2(getInstanceId2(), "custom_policy_validation_failed", {
|
|
22330
|
+
scope,
|
|
22331
|
+
error_type: "no_hooks_registered"
|
|
22332
|
+
});
|
|
22333
|
+
} catch {}
|
|
22334
|
+
console.error(`Error: no hooks registered in ${path3}. ` + `Make sure your file calls customPolicies.add(...) at least once.`);
|
|
22335
|
+
process.exit(1);
|
|
22336
|
+
}
|
|
22337
|
+
console.log(`
|
|
22338
|
+
Validated ${validatedHooks.length} custom hook(s) from ${path3}: ${validatedHooks.map((h) => h.name).join(", ")}`);
|
|
21964
22339
|
}
|
|
21965
|
-
console.log(`
|
|
21966
|
-
Validated ${validatedHooks.length} custom hook(s): ${validatedHooks.map((h) => h.name).join(", ")}`);
|
|
21967
22340
|
}
|
|
21968
22341
|
writeScopedHooksConfig(configToWrite, scope, cwd);
|
|
21969
22342
|
console.log(`
|
|
@@ -21971,18 +22344,21 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
|
|
|
21971
22344
|
`);
|
|
21972
22345
|
if (removeCustomHooks) {
|
|
21973
22346
|
console.log("Custom hooks path cleared.");
|
|
21974
|
-
} else if (configToWrite.customPoliciesPath) {
|
|
21975
|
-
|
|
22347
|
+
} else if (configToWrite.customPoliciesPaths?.length || configToWrite.customPoliciesPath) {
|
|
22348
|
+
const paths = configToWrite.customPoliciesPaths ?? [configToWrite.customPoliciesPath];
|
|
22349
|
+
console.log(`Custom hooks paths: ${paths.join(", ")}`);
|
|
21976
22350
|
}
|
|
21977
22351
|
const writtenSettingsPaths = [];
|
|
21978
22352
|
for (const cliId of selectedClis) {
|
|
21979
22353
|
const integration = getIntegration(cliId);
|
|
21980
|
-
const
|
|
22354
|
+
const settingsPaths = settingsPathsFor(integration, scope, cwd);
|
|
21981
22355
|
try {
|
|
21982
|
-
const
|
|
21983
|
-
|
|
21984
|
-
|
|
21985
|
-
|
|
22356
|
+
for (const settingsPath of settingsPaths) {
|
|
22357
|
+
const settings = integration.readSettings(settingsPath);
|
|
22358
|
+
integration.writeHookEntries(settings, binaryPath, scope);
|
|
22359
|
+
integration.writeSettings(settingsPath, settings);
|
|
22360
|
+
writtenSettingsPaths.push({ cli: cliId, path: settingsPath });
|
|
22361
|
+
}
|
|
21986
22362
|
} catch (err) {
|
|
21987
22363
|
const errorType = err instanceof Error && /EACCES|EPERM/.test(err.message) ? "permission_denied" : err instanceof Error && /ENOENT|ENOTDIR/.test(err.message) ? "path_not_found" : "write_error";
|
|
21988
22364
|
try {
|
|
@@ -22013,7 +22389,7 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
|
|
|
22013
22389
|
arch: arch4(),
|
|
22014
22390
|
os_release: release3(),
|
|
22015
22391
|
hostname_hash: hashToId2(hostname4()),
|
|
22016
|
-
has_custom_hooks_path: !!configToWrite.customPoliciesPath,
|
|
22392
|
+
has_custom_hooks_path: !!(configToWrite.customPoliciesPaths?.length || configToWrite.customPoliciesPath),
|
|
22017
22393
|
has_policy_params: !!(configToWrite.policyParams && Object.keys(configToWrite.policyParams).length > 0),
|
|
22018
22394
|
param_policy_names: configToWrite.policyParams ? Object.keys(configToWrite.policyParams) : [],
|
|
22019
22395
|
command_format: scope === "project" ? "npx" : "absolute"
|
|
@@ -22073,6 +22449,7 @@ var init_manager2 = __esm(() => {
|
|
|
22073
22449
|
init_hook_telemetry2();
|
|
22074
22450
|
init_telemetry_id2();
|
|
22075
22451
|
init_cli_error();
|
|
22452
|
+
init_hook_logger();
|
|
22076
22453
|
VALID_POLICY_NAMES2 = new Set(BUILTIN_POLICIES.map((p) => p.name));
|
|
22077
22454
|
});
|
|
22078
22455
|
|
|
@@ -22411,9 +22788,9 @@ __export(exports_configure_wizard, {
|
|
|
22411
22788
|
buildPresetChoices: () => buildPresetChoices,
|
|
22412
22789
|
buildAgentChoices: () => buildAgentChoices
|
|
22413
22790
|
});
|
|
22414
|
-
import { existsSync as
|
|
22791
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync10, writeFileSync as writeFileSync9, readFileSync as readFileSync16 } from "node:fs";
|
|
22415
22792
|
import { homedir as homedir30 } from "node:os";
|
|
22416
|
-
import { resolve as
|
|
22793
|
+
import { resolve as resolve17, sep as sep5 } from "node:path";
|
|
22417
22794
|
async function emit(event, props) {
|
|
22418
22795
|
try {
|
|
22419
22796
|
await trackHookEvent2(getInstanceId2(), event, props);
|
|
@@ -22470,12 +22847,21 @@ function buildAgentChoices(scope, cwd) {
|
|
|
22470
22847
|
} catch {
|
|
22471
22848
|
installedHere = false;
|
|
22472
22849
|
}
|
|
22850
|
+
let partialHint;
|
|
22851
|
+
if (id === "hermes" && !installedHere) {
|
|
22852
|
+
try {
|
|
22853
|
+
const unhooked = unhookedHermesProfiles();
|
|
22854
|
+
if (unhooked.length > 0) {
|
|
22855
|
+
partialHint = `${unhooked.length} unhooked profile(s): ${unhooked.join(", ")}`;
|
|
22856
|
+
}
|
|
22857
|
+
} catch {}
|
|
22858
|
+
}
|
|
22473
22859
|
return {
|
|
22474
22860
|
label: integration.displayName,
|
|
22475
22861
|
value: id,
|
|
22476
22862
|
checked: isDetected || installedHere,
|
|
22477
22863
|
section: isDetected ? "Detected" : "Not installed · set up ahead of time",
|
|
22478
|
-
hint: installedHere ? "already configured" : isDetected ? undefined : "not on PATH"
|
|
22864
|
+
hint: installedHere ? "already configured" : partialHint ?? (isDetected ? undefined : "not on PATH")
|
|
22479
22865
|
};
|
|
22480
22866
|
});
|
|
22481
22867
|
}
|
|
@@ -22525,7 +22911,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
|
|
|
22525
22911
|
const path3 = getConfigPathForScope(scope, cwd);
|
|
22526
22912
|
let config = {};
|
|
22527
22913
|
try {
|
|
22528
|
-
if (
|
|
22914
|
+
if (existsSync20(path3))
|
|
22529
22915
|
config = JSON.parse(readFileSync16(path3, "utf8"));
|
|
22530
22916
|
} catch {
|
|
22531
22917
|
return;
|
|
@@ -22545,8 +22931,8 @@ function describeCustomPolicies(cwd) {
|
|
|
22545
22931
|
const scopes = [];
|
|
22546
22932
|
let fileCount = 0;
|
|
22547
22933
|
const dirs = [
|
|
22548
|
-
{ dir:
|
|
22549
|
-
{ dir:
|
|
22934
|
+
{ dir: resolve17(cwd, ".failproofai", "policies"), label: "project" },
|
|
22935
|
+
{ dir: resolve17(homedir30(), ".failproofai", "policies"), label: "global" }
|
|
22550
22936
|
];
|
|
22551
22937
|
for (const { dir, label } of dirs) {
|
|
22552
22938
|
const found = discoverPolicyFiles(dir);
|
|
@@ -22556,7 +22942,7 @@ function describeCustomPolicies(cwd) {
|
|
|
22556
22942
|
fileCount += found.length;
|
|
22557
22943
|
}
|
|
22558
22944
|
for (const name of findSkippedPolicyFiles(dir)) {
|
|
22559
|
-
warnings.push(`! ${homeify(
|
|
22945
|
+
warnings.push(`! ${homeify(resolve17(dir, name))} is NOT loaded — rename to ` + `${name.replace(/\.(js|mjs|ts)$/, "-policies.$1")}`);
|
|
22560
22946
|
}
|
|
22561
22947
|
}
|
|
22562
22948
|
return { active, warnings, fileCount, scopes };
|
|
@@ -22579,20 +22965,22 @@ function reviewLines(state) {
|
|
|
22579
22965
|
lines.push(" This will update:");
|
|
22580
22966
|
for (const cli of clis) {
|
|
22581
22967
|
const integration = getIntegration(cli);
|
|
22582
|
-
|
|
22968
|
+
for (const p of settingsPathsFor(integration, scope, cwd)) {
|
|
22969
|
+
lines.push(` ${homeify(p)} ${integration.displayName} hooks`);
|
|
22970
|
+
}
|
|
22583
22971
|
}
|
|
22584
22972
|
lines.push(` ${homeify(getConfigPathForScope(scope, cwd))} ${policies.length} policies`);
|
|
22585
22973
|
return lines;
|
|
22586
22974
|
}
|
|
22587
22975
|
function firstRunMarkerPath() {
|
|
22588
|
-
return
|
|
22976
|
+
return resolve17(homedir30(), ".failproofai", ".launcher-configured");
|
|
22589
22977
|
}
|
|
22590
22978
|
function hasSeenLauncher() {
|
|
22591
|
-
return
|
|
22979
|
+
return existsSync20(firstRunMarkerPath());
|
|
22592
22980
|
}
|
|
22593
22981
|
function markLauncherSeen() {
|
|
22594
22982
|
try {
|
|
22595
|
-
mkdirSync10(
|
|
22983
|
+
mkdirSync10(resolve17(homedir30(), ".failproofai"), { recursive: true });
|
|
22596
22984
|
writeFileSync9(firstRunMarkerPath(), "1", "utf8");
|
|
22597
22985
|
} catch {}
|
|
22598
22986
|
}
|
|
@@ -22742,8 +23130,8 @@ __export(exports_launch2, {
|
|
|
22742
23130
|
launch: () => launch2
|
|
22743
23131
|
});
|
|
22744
23132
|
import { spawn as spawn3 } from "child_process";
|
|
22745
|
-
import { realpathSync as realpathSync3, existsSync as
|
|
22746
|
-
import { resolve as
|
|
23133
|
+
import { realpathSync as realpathSync3, existsSync as existsSync21 } from "node:fs";
|
|
23134
|
+
import { resolve as resolve18, dirname as dirname9 } from "node:path";
|
|
22747
23135
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
22748
23136
|
import { createInterface as createInterface3 } from "node:readline";
|
|
22749
23137
|
function launch2(mode) {
|
|
@@ -22758,9 +23146,9 @@ function launch2(mode) {
|
|
|
22758
23146
|
process.env.PORT = port;
|
|
22759
23147
|
process.env.HOSTNAME = "0.0.0.0";
|
|
22760
23148
|
cmd = "node";
|
|
22761
|
-
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ??
|
|
22762
|
-
const serverJsPath =
|
|
22763
|
-
if (!
|
|
23149
|
+
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve18(dirname9(realpathSync3(fileURLToPath3(import.meta.url))), "..");
|
|
23150
|
+
const serverJsPath = resolve18(packageRoot, ".next/standalone/server.js");
|
|
23151
|
+
if (!existsSync21(serverJsPath)) {
|
|
22764
23152
|
let shadowMessage = null;
|
|
22765
23153
|
try {
|
|
22766
23154
|
const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
|
|
@@ -22798,6 +23186,7 @@ Error: Cannot find server.js at:
|
|
|
22798
23186
|
stdio: filterLogs ? ["inherit", "pipe", "pipe"] : "inherit",
|
|
22799
23187
|
env: {
|
|
22800
23188
|
...process.env,
|
|
23189
|
+
FAILPROOFAI_LAUNCH_CWD: process.env.FAILPROOFAI_LAUNCH_CWD ?? process.cwd(),
|
|
22801
23190
|
...filterLogs ? { FORCE_COLOR: process.env.FORCE_COLOR ?? "1" } : {},
|
|
22802
23191
|
...loggingLevel ? { FAILPROOFAI_LOG_LEVEL: loggingLevel } : {},
|
|
22803
23192
|
...disableTelemetry ? { FAILPROOFAI_TELEMETRY_DISABLED: "1" } : {},
|
|
@@ -22854,17 +23243,17 @@ var init_cli_error2 = __esm(() => {
|
|
|
22854
23243
|
|
|
22855
23244
|
// bin/failproofai.mjs
|
|
22856
23245
|
import { realpathSync as realpathSync4 } from "fs";
|
|
22857
|
-
import { dirname as
|
|
23246
|
+
import { dirname as dirname10, resolve as resolve19 } from "path";
|
|
22858
23247
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
22859
23248
|
// package.json
|
|
22860
|
-
var version = "0.0.
|
|
23249
|
+
var version = "0.0.15-beta.1";
|
|
22861
23250
|
|
|
22862
23251
|
// bin/failproofai.mjs
|
|
22863
23252
|
if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
|
|
22864
|
-
process.env.FAILPROOFAI_PACKAGE_ROOT =
|
|
23253
|
+
process.env.FAILPROOFAI_PACKAGE_ROOT = resolve19(dirname10(realpathSync4(fileURLToPath4(import.meta.url))), "..");
|
|
22865
23254
|
}
|
|
22866
23255
|
if (!process.env.FAILPROOFAI_DIST_PATH) {
|
|
22867
|
-
process.env.FAILPROOFAI_DIST_PATH =
|
|
23256
|
+
process.env.FAILPROOFAI_DIST_PATH = resolve19(dirname10(realpathSync4(fileURLToPath4(import.meta.url))), "..", "dist");
|
|
22868
23257
|
}
|
|
22869
23258
|
var args = process.argv.slice(2);
|
|
22870
23259
|
if (args[0] === "p")
|
|
@@ -22951,7 +23340,7 @@ COMMANDS
|
|
|
22951
23340
|
--scope user|project|local Config scope to write to (default: user)
|
|
22952
23341
|
(Codex / Copilot / Cursor / OpenCode / Pi support user|project only)
|
|
22953
23342
|
--beta Include beta policies
|
|
22954
|
-
--custom, -c <path>
|
|
23343
|
+
--custom, -c <path> Custom policy file (repeat for multiple files)
|
|
22955
23344
|
|
|
22956
23345
|
policies --uninstall, -u Disable policies or remove hooks
|
|
22957
23346
|
[names...] Specific policy names to disable
|
|
@@ -22959,7 +23348,7 @@ COMMANDS
|
|
|
22959
23348
|
Agent CLI(s) to uninstall from
|
|
22960
23349
|
--scope user|project|local|all Config scope to remove from (default: user)
|
|
22961
23350
|
--beta Remove only beta policies
|
|
22962
|
-
--custom, -c Clear
|
|
23351
|
+
--custom, -c Clear all explicit custom policy paths
|
|
22963
23352
|
|
|
22964
23353
|
policies --help, -h Show this help for the policies command
|
|
22965
23354
|
|
|
@@ -23043,7 +23432,7 @@ OPTIONS (install)
|
|
|
23043
23432
|
--scope user|project|local Config scope to write to (default: user)
|
|
23044
23433
|
(Codex / Copilot / Cursor / OpenCode / Pi support user|project only)
|
|
23045
23434
|
--beta Include beta policies
|
|
23046
|
-
--custom, -c <path>
|
|
23435
|
+
--custom, -c <path> Custom policy file (repeat for multiple files)
|
|
23047
23436
|
(skips interactive prompt; validates file first)
|
|
23048
23437
|
|
|
23049
23438
|
OPTIONS (uninstall)
|
|
@@ -23052,7 +23441,7 @@ OPTIONS (uninstall)
|
|
|
23052
23441
|
Agent CLI(s) to uninstall from
|
|
23053
23442
|
--scope user|project|local|all Config scope to remove from (default: user)
|
|
23054
23443
|
--beta Remove only beta policies
|
|
23055
|
-
--custom, -c Clear
|
|
23444
|
+
--custom, -c Clear all explicit custom policy paths
|
|
23056
23445
|
|
|
23057
23446
|
EXAMPLES
|
|
23058
23447
|
failproofai policies
|
|
@@ -23067,6 +23456,7 @@ EXAMPLES
|
|
|
23067
23456
|
failproofai policies --install --cli devin --scope project
|
|
23068
23457
|
failproofai policies --install --cli claude codex copilot cursor opencode pi hermes openclaw factory devin antigravity goose
|
|
23069
23458
|
failproofai policies --install --custom ./my-policies.js
|
|
23459
|
+
failproofai policies --install --custom ./security.js --custom ./workflow.js
|
|
23070
23460
|
failproofai policies -i -c ./my-policies.js
|
|
23071
23461
|
failproofai policies --uninstall block-sudo
|
|
23072
23462
|
failproofai policies --uninstall --cli codex
|
|
@@ -23091,9 +23481,9 @@ EXAMPLES
|
|
|
23091
23481
|
if (scopeIdx >= 0 && !["user", "project", "local"].includes(scope)) {
|
|
23092
23482
|
throw new CliError3(`Invalid scope: ${scope}. Valid values: user, project, local`);
|
|
23093
23483
|
}
|
|
23094
|
-
const
|
|
23095
|
-
const
|
|
23096
|
-
if (
|
|
23484
|
+
const customIdxs = subArgs.map((arg, index) => arg === "--custom" || arg === "-c" ? index : -1).filter((index) => index >= 0);
|
|
23485
|
+
const customPoliciesPaths = customIdxs.map((index) => subArgs[index + 1]);
|
|
23486
|
+
if (customPoliciesPaths.some((path3) => !path3 || path3.startsWith("-"))) {
|
|
23097
23487
|
throw new CliError3(`Missing path after --custom/-c
|
|
23098
23488
|
Usage: --custom <path> (e.g. --custom ./my-policies.js)`);
|
|
23099
23489
|
}
|
|
@@ -23121,7 +23511,7 @@ Usage: --custom <path> (e.g. --custom ./my-policies.js)`);
|
|
|
23121
23511
|
const consumedIdxs = new Set;
|
|
23122
23512
|
if (scopeIdx >= 0)
|
|
23123
23513
|
consumedIdxs.add(scopeIdx + 1);
|
|
23124
|
-
|
|
23514
|
+
for (const customIdx of customIdxs)
|
|
23125
23515
|
consumedIdxs.add(customIdx + 1);
|
|
23126
23516
|
for (const i of cliConsumedIdxs)
|
|
23127
23517
|
consumedIdxs.add(i);
|
|
@@ -23132,16 +23522,16 @@ Usage: --custom <path> (e.g. --custom ./my-policies.js)`);
|
|
|
23132
23522
|
Run \`failproofai policies --help\` for usage.`);
|
|
23133
23523
|
}
|
|
23134
23524
|
const explicitPolicyNames = subArgs.filter((a, idx) => !a.startsWith("-") && !consumedIdxs.has(idx));
|
|
23135
|
-
const policyNames = explicitPolicyNames.length > 0 ? explicitPolicyNames :
|
|
23525
|
+
const policyNames = explicitPolicyNames.length > 0 ? explicitPolicyNames : customPoliciesPaths.length > 0 ? [] : undefined;
|
|
23136
23526
|
const cli = await resolveTargetClis2(cliFlagValues.length > 0 ? cliFlagValues : undefined, "install");
|
|
23137
|
-
await installHooks3(policyNames, scope, undefined, includeBeta, undefined,
|
|
23527
|
+
await installHooks3(policyNames, scope, undefined, includeBeta, undefined, customPoliciesPaths.length > 0 ? customPoliciesPaths : undefined, false, cli);
|
|
23138
23528
|
await track("cli_install_success", {
|
|
23139
23529
|
scope,
|
|
23140
23530
|
cli,
|
|
23141
23531
|
cli_count: cli.length,
|
|
23142
23532
|
explicit_policies: explicitPolicyNames.length > 0,
|
|
23143
23533
|
include_beta: includeBeta,
|
|
23144
|
-
has_custom_path:
|
|
23534
|
+
has_custom_path: customPoliciesPaths.length > 0
|
|
23145
23535
|
});
|
|
23146
23536
|
process.exit(0);
|
|
23147
23537
|
}
|