failproofai 1.0.5 → 1.0.6-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.
Files changed (204) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +5 -5
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  34. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/index.html +1 -1
  37. package/.next/standalone/.next/server/app/index.rsc +14 -14
  38. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  39. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  40. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  41. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  42. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  43. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  46. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  47. package/.next/standalone/.next/server/app/policies/page.js +6 -5
  48. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  62. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  63. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  66. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  67. package/.next/standalone/.next/server/app/settings/page.js +3 -2
  68. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  69. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/chunks/[externals]__0sds_16._.js +3 -0
  71. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zlqo2t._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__112b4go._.js → [root-of-the-server]__1_r2rbg._.js} +4 -4
  74. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1anxb5k._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +3 -3
  76. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  77. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
  79. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
  80. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0576iuy._.js +3 -0
  86. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bym1os._.js → [root-of-the-server]__0cg-bgc._.js} +2 -2
  87. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  90. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00y9ww2._.js → [root-of-the-server]__0u3w0ll._.js} +2 -2
  91. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0sz_5na._.js → [root-of-the-server]__1ouobn4._.js} +1 -1
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  93. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1py795m._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1qapotl._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__15k-dqb._.js → [root-of-the-server]__1x3j9mj._.js} +2 -2
  96. package/.next/standalone/.next/server/chunks/ssr/_0-yi74u._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
  98. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/{_0guaevg._.js → _0qlygw6._.js} +2 -2
  100. package/.next/standalone/.next/server/chunks/ssr/_0wso5d3._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/ssr/_1-3unkg._.js +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/{_1b78kcp._.js → _1_ddpm3._.js} +1 -1
  103. package/.next/standalone/.next/server/chunks/ssr/{_14c6q09._.js → _1_qswah._.js} +2 -2
  104. package/.next/standalone/.next/server/chunks/ssr/_1ddpc5g._.js +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +3 -3
  106. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  107. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  108. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +12 -11
  109. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  110. package/.next/standalone/.next/server/chunks/ssr/app_components_project-list_tsx_1ke6anr._.js +1 -1
  111. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  112. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +2 -2
  113. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  114. package/.next/standalone/.next/server/chunks/ssr/node_modules_1hl81y4._.js +3 -0
  115. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +2 -2
  116. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  117. package/.next/standalone/.next/server/pages/404.html +1 -1
  118. package/.next/standalone/.next/server/pages/500.html +1 -1
  119. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  120. package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
  121. package/.next/standalone/.next/static/chunks/{3w46euc60dx39.js → 02vwr5js1x28j.js} +1 -1
  122. package/.next/standalone/.next/static/chunks/06fjx8-0_qufs.js +1 -0
  123. package/.next/standalone/.next/static/chunks/{2zafgs90r_leq.js → 06jxjnw8bfczc.js} +1 -1
  124. package/.next/standalone/.next/static/chunks/0cbvytf8epn34.js +1 -0
  125. package/.next/standalone/.next/static/chunks/0y227_ohdqwvn.js +1 -0
  126. package/.next/standalone/.next/static/chunks/{252xreaecy80h.js → 1p4xauf-zu6zk.js} +1 -1
  127. package/.next/standalone/.next/static/chunks/{021ydrq6rhpsi.js → 1qf2uiipatr80.js} +1 -1
  128. package/.next/standalone/.next/static/chunks/1uc_s_dftgxiq.js +6 -0
  129. package/.next/standalone/.next/static/chunks/1xacnwjkbekn7.js +1 -0
  130. package/.next/standalone/.next/static/chunks/{11s_v03ub6nss.js → 27_bwbg8sv6vj.js} +1 -1
  131. package/.next/standalone/.next/static/chunks/2hg_bp8z_vm2g.js +1 -0
  132. package/.next/standalone/.next/static/chunks/{3bleyy40s99f2.js → 2x776s0x3n_tu.js} +1 -1
  133. package/.next/standalone/.next/static/chunks/{1vb33xa6j9y2q.js → 3ht0xsco46pul.js} +1 -1
  134. package/.next/standalone/.next/static/chunks/{turbopack-3p73obe0xmrxm.js → turbopack-38nzuvp95_2rv.js} +1 -1
  135. package/.next/standalone/fp-cloud-cli/uv.lock +3 -3
  136. package/.next/standalone/hermes-plugin/README.md +138 -0
  137. package/.next/standalone/hermes-plugin/__init__.py +248 -0
  138. package/.next/standalone/hermes-plugin/client.py +150 -0
  139. package/.next/standalone/hermes-plugin/ledger.py +187 -0
  140. package/.next/standalone/hermes-plugin/plugin.yaml +37 -0
  141. package/.next/standalone/lib/hermes-profiles.ts +67 -19
  142. package/.next/standalone/lib/hermes-sessions.ts +3 -2
  143. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  144. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  145. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +1 -1
  146. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +1 -1
  147. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  148. package/.next/standalone/node_modules/next/dist/server/app-render/create-component-styles-and-scripts.js +2 -1
  149. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  150. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  151. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  152. package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +14 -0
  153. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  154. package/.next/standalone/node_modules/next/dist/server/lib/disk-lru-cache.external.js +7 -1
  155. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  156. package/.next/standalone/node_modules/next/dist/server/use-cache/use-cache-wrapper.js +6 -1
  157. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  158. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  159. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  160. package/.next/standalone/node_modules/next/package.json +10 -10
  161. package/.next/standalone/node_modules/react/cjs/react.development.js +92 -46
  162. package/.next/standalone/node_modules/react/cjs/react.production.js +112 -89
  163. package/.next/standalone/node_modules/react/package.json +1 -1
  164. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.js +1165 -790
  165. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server-legacy.node.production.js +1171 -791
  166. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.browser.production.js +1294 -862
  167. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.edge.production.js +1305 -868
  168. package/.next/standalone/node_modules/react-dom/cjs/react-dom-server.node.production.js +1315 -896
  169. package/.next/standalone/node_modules/react-dom/cjs/react-dom.production.js +24 -5
  170. package/.next/standalone/node_modules/react-dom/package.json +4 -4
  171. package/.next/standalone/package.json +13 -12
  172. package/.next/standalone/sdk/python/uv.lock +18 -18
  173. package/.next/standalone/server.js +1 -1
  174. package/README.md +29 -13
  175. package/bin/failproofai.mjs +3 -1
  176. package/dist/cli.mjs +655 -360
  177. package/dist/worker.mjs +78 -34
  178. package/hermes-plugin/README.md +138 -0
  179. package/hermes-plugin/__init__.py +248 -0
  180. package/hermes-plugin/client.py +150 -0
  181. package/hermes-plugin/ledger.py +187 -0
  182. package/hermes-plugin/plugin.yaml +37 -0
  183. package/lib/hermes-profiles.ts +67 -19
  184. package/lib/hermes-sessions.ts +3 -2
  185. package/package.json +13 -12
  186. package/scripts/translate-docs/validate-translation.ts +48 -0
  187. package/src/hooks/handler.ts +29 -1
  188. package/src/hooks/integrations.ts +271 -73
  189. package/src/hooks/manager.ts +41 -7
  190. package/src/hooks/types.ts +8 -8
  191. package/src/hooks/worker-server.ts +1 -0
  192. package/.next/standalone/.next/server/chunks/[externals]__157pf8j._.js +0 -3
  193. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +0 -3
  194. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +0 -6
  195. package/.next/standalone/.next/server/chunks/ssr/node_modules_13n822a._.js +0 -3
  196. package/.next/standalone/.next/static/chunks/0y8_1s45gbqmn.js +0 -6
  197. package/.next/standalone/.next/static/chunks/14b3ezufe5411.js +0 -1
  198. package/.next/standalone/.next/static/chunks/1oskk7pdo8aon.js +0 -1
  199. package/.next/standalone/.next/static/chunks/2xycd6mjg00fb.js +0 -1
  200. package/.next/standalone/.next/static/chunks/3l36d73kj18zw.js +0 -1
  201. package/.next/standalone/.next/static/chunks/40lpt2o2b283e.js +0 -1
  202. /package/.next/standalone/.next/static/{uFpAs_vIXSo6qBzmkXPWD → QCNYz2yCxxdeggg1k0iEq}/_buildManifest.js +0 -0
  203. /package/.next/standalone/.next/static/{uFpAs_vIXSo6qBzmkXPWD → QCNYz2yCxxdeggg1k0iEq}/_clientMiddlewareManifest.js +0 -0
  204. /package/.next/standalone/.next/static/{uFpAs_vIXSo6qBzmkXPWD → QCNYz2yCxxdeggg1k0iEq}/_ssgManifest.js +0 -0
package/dist/cli.mjs CHANGED
@@ -29,7 +29,7 @@ var __esm = (fn, res, err) => () => {
29
29
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
30
 
31
31
  // package.json
32
- var version2 = "1.0.5", package_default;
32
+ var version2 = "1.0.6-beta.1", package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "failproofai",
@@ -45,6 +45,7 @@ var init_package = __esm(() => {
45
45
  "scripts/",
46
46
  "lib/",
47
47
  "pi-extension/",
48
+ "hermes-plugin/",
48
49
  "openclaw-plugin/",
49
50
  ".next/standalone/",
50
51
  "dist/",
@@ -113,15 +114,15 @@ var init_package = __esm(() => {
113
114
  access: "public"
114
115
  },
115
116
  devDependencies: {
116
- "@anthropic-ai/sdk": "^0.123.0",
117
+ "@anthropic-ai/sdk": "^0.125.0",
117
118
  "@mdx-js/mdx": "^3.1.1",
118
119
  "@tailwindcss/postcss": "^4.3.1",
119
120
  "@tanstack/react-virtual": "^3.14.10",
120
121
  "@testing-library/jest-dom": "^7.0.0",
121
122
  "@testing-library/react": "^16.3.2",
122
123
  "@testing-library/user-event": "^14.6.5",
123
- "@types/node": "26.4.1",
124
- "@types/react": "19.2.18",
124
+ "@types/node": "26.5.1",
125
+ "@types/react": "19.3.0",
125
126
  "@types/react-dom": "^19.2.3",
126
127
  "@vitejs/plugin-react": "^6.1.0",
127
128
  clsx: "^2.1.1",
@@ -154,16 +155,16 @@ var init_package = __esm(() => {
154
155
  browserslist: "4.28.8"
155
156
  },
156
157
  optionalDependencies: {
157
- "@failproofai/failproofaid-linux-x64": "1.0.5",
158
- "@failproofai/failproofaid-linux-arm64": "1.0.5",
159
- "@failproofai/failproofaid-darwin-x64": "1.0.5",
160
- "@failproofai/failproofaid-darwin-arm64": "1.0.5"
158
+ "@failproofai/failproofaid-linux-x64": "1.0.6-beta.1",
159
+ "@failproofai/failproofaid-linux-arm64": "1.0.6-beta.1",
160
+ "@failproofai/failproofaid-darwin-x64": "1.0.6-beta.1",
161
+ "@failproofai/failproofaid-darwin-arm64": "1.0.6-beta.1"
161
162
  },
162
163
  failproofaidBinaries: {
163
- "linux-x64": "5fb4c8a993af9279e46306803c68d6650ea57290bbd7ec92795a7f7b696bb506",
164
- "linux-arm64": "21c502073649d9c12710fc2707b9dee08b7ac1528b8544b85a755017c8fdff0e",
165
- "darwin-x64": "5e02c2f4887793c64f5553d8d00fd21507f88dce1a6869ca1aca2f6468129373",
166
- "darwin-arm64": "65be288a3485ca86869580a036e6c7e9b7b5660a6589143b375586b6c28b5c84"
164
+ "linux-x64": "b6f877cd407c3322ff8ad2f98a096b6ea15b0bd1d63de6276c689368345c1cd2",
165
+ "linux-arm64": "0da90a816b9dc707efe9b82176923cbf0f00026179c816e34eaad362ce2c0fa4",
166
+ "darwin-x64": "bcbec488353fa04a1953a87cad15054e4796117cac4fd60b17fb1c87d62b7b1e",
167
+ "darwin-arm64": "6830989a91a27642cdcc63fcfad529c69c0deb3f3abcf5ad40fd3516289b451d"
167
168
  }
168
169
  };
169
170
  });
@@ -5101,36 +5102,38 @@ var require_Alias = __commonJS(function(exports) {
5101
5102
  if (node.anchor === this.source)
5102
5103
  found = node;
5103
5104
  }
5105
+ if (found && ctx) {
5106
+ const { anchors, doc, maxAliasCount } = ctx;
5107
+ let data = anchors.get(found);
5108
+ if (!data) {
5109
+ toJS.toJS(found, null, ctx);
5110
+ data = anchors.get(found);
5111
+ }
5112
+ if (data?.res === undefined) {
5113
+ const msg = "This should not happen: Alias anchor was not resolved?";
5114
+ throw new ReferenceError(msg);
5115
+ }
5116
+ if (maxAliasCount >= 0) {
5117
+ data.count += 1;
5118
+ if (data.aliasCount === 0)
5119
+ data.aliasCount = getAliasCount(doc, found, anchors);
5120
+ if (data.count * data.aliasCount > maxAliasCount) {
5121
+ const msg = "Excessive alias count indicates a resource exhaustion attack";
5122
+ throw new ReferenceError(msg);
5123
+ }
5124
+ }
5125
+ }
5104
5126
  return found;
5105
5127
  }
5106
5128
  toJSON(_arg, ctx) {
5107
5129
  if (!ctx)
5108
5130
  return { source: this.source };
5109
- const { anchors, doc, maxAliasCount } = ctx;
5110
- const source = this.resolve(doc, ctx);
5131
+ const source = this.resolve(ctx.doc, ctx);
5111
5132
  if (!source) {
5112
5133
  const msg = `Unresolved alias (the anchor must be set before the alias): ${this.source}`;
5113
5134
  throw new ReferenceError(msg);
5114
5135
  }
5115
- let data = anchors.get(source);
5116
- if (!data) {
5117
- toJS.toJS(source, null, ctx);
5118
- data = anchors.get(source);
5119
- }
5120
- if (data?.res === undefined) {
5121
- const msg = "This should not happen: Alias anchor was not resolved?";
5122
- throw new ReferenceError(msg);
5123
- }
5124
- if (maxAliasCount >= 0) {
5125
- data.count += 1;
5126
- if (data.aliasCount === 0)
5127
- data.aliasCount = getAliasCount(doc, source, anchors);
5128
- if (data.count * data.aliasCount > maxAliasCount) {
5129
- const msg = "Excessive alias count indicates a resource exhaustion attack";
5130
- throw new ReferenceError(msg);
5131
- }
5132
- }
5133
- return data.res;
5136
+ return ctx.anchors.get(source).res;
5134
5137
  }
5135
5138
  toString(ctx, _onComment, _onChompKeep) {
5136
5139
  const src = `*${this.source}`;
@@ -8892,33 +8895,32 @@ var require_resolve_flow_scalar = __commonJS(function(exports) {
8892
8895
  }
8893
8896
  if (badChar)
8894
8897
  onError(0, "BAD_SCALAR_START", `Plain value cannot start with ${badChar}`);
8895
- return foldLines(source);
8898
+ return unfoldLines(source);
8896
8899
  }
8897
8900
  function singleQuotedValue(source, onError) {
8898
8901
  if (source[source.length - 1] !== "'" || source.length === 1)
8899
8902
  onError(source.length, "MISSING_CHAR", "Missing closing 'quote");
8900
- return foldLines(source.slice(1, -1)).replace(/''/g, "'");
8903
+ return unfoldLines(source.slice(1, -1)).replace(/''/g, "'");
8901
8904
  }
8902
- function foldLines(source) {
8903
- let first, line;
8905
+ function unfoldLines(source) {
8906
+ const line = /(.*?)\r?\n/sy;
8907
+ let match = line.exec(source);
8908
+ if (!match)
8909
+ return source;
8910
+ let trimEnd, trimBoth;
8904
8911
  try {
8905
- first = new RegExp(`(.*?)(?<![ ])[ ]*\r?
8906
- `, "sy");
8907
- line = new RegExp(`[ ]*(.*?)(?:(?<![ ])[ ]*)?\r?
8908
- `, "sy");
8912
+ trimEnd = new RegExp("(?<![ \t])[ \t]+$");
8913
+ trimBoth = new RegExp("^[ \t]+|(?<![ \t])[ \t]+$", "g");
8909
8914
  } catch {
8910
- first = /(.*?)[ \t]*\r?\n/sy;
8911
- line = /[ \t]*(.*?)[ \t]*\r?\n/sy;
8915
+ trimEnd = /[ \t]+$/;
8916
+ trimBoth = /^[ \t]+|[ \t]+$/g;
8912
8917
  }
8913
- let match = first.exec(source);
8914
- if (!match)
8915
- return source;
8916
- let res = match[1];
8918
+ let res = match[1].replace(trimEnd, "");
8917
8919
  let sep = " ";
8918
- let pos = first.lastIndex;
8919
- line.lastIndex = pos;
8920
+ let pos = line.lastIndex;
8920
8921
  while (match = line.exec(source)) {
8921
- if (match[1] === "") {
8922
+ const lm = match[1].replace(trimBoth, "");
8923
+ if (lm === "") {
8922
8924
  if (sep === `
8923
8925
  `)
8924
8926
  res += sep;
@@ -8926,7 +8928,7 @@ var require_resolve_flow_scalar = __commonJS(function(exports) {
8926
8928
  sep = `
8927
8929
  `;
8928
8930
  } else {
8929
- res += sep + match[1];
8931
+ res += sep + lm;
8930
8932
  sep = " ";
8931
8933
  }
8932
8934
  pos = line.lastIndex;
@@ -11516,36 +11518,66 @@ var init_dist = __esm(() => {
11516
11518
  });
11517
11519
 
11518
11520
  // lib/hermes-profiles.ts
11519
- import { readdirSync } from "node:fs";
11521
+ import { existsSync as existsSync6, readdirSync } from "node:fs";
11520
11522
  import { homedir as homedir4 } from "node:os";
11521
11523
  import { basename, dirname as dirname3, join as join3, resolve as resolve6 } from "node:path";
11522
11524
  function hermesRoot() {
11523
11525
  const env = (process.env.HERMES_HOME || "").trim();
11524
11526
  if (env) {
11525
- const home = resolve6(env);
11527
+ let home = resolve6(env);
11526
11528
  const parent = dirname3(home);
11527
11529
  if (basename(parent) === PROFILES_DIR)
11528
- return dirname3(parent);
11530
+ home = dirname3(parent);
11531
+ const base = basename(home);
11532
+ if (base === STANDARD_HOME || base.startsWith(SIBLING_HOME_PREFIX)) {
11533
+ return join3(dirname3(home), STANDARD_HOME);
11534
+ }
11529
11535
  return home;
11530
11536
  }
11531
- return join3(homedir4(), ".hermes");
11537
+ return join3(homedir4(), STANDARD_HOME);
11538
+ }
11539
+ function uniqueProfileName(preferred, seen) {
11540
+ if (!seen.has(preferred))
11541
+ return preferred;
11542
+ const base = `${preferred}-home`;
11543
+ if (!seen.has(base))
11544
+ return base;
11545
+ let suffix = 2;
11546
+ while (seen.has(`${base}-${suffix}`))
11547
+ suffix += 1;
11548
+ return `${base}-${suffix}`;
11532
11549
  }
11533
11550
  function listHermesProfiles() {
11534
11551
  const root = hermesRoot();
11535
11552
  const out = [{ name: HERMES_DEFAULT_PROFILE, home: root }];
11536
11553
  const seen = new Set([HERMES_DEFAULT_PROFILE]);
11537
- let names;
11554
+ let names = [];
11538
11555
  try {
11539
11556
  names = readdirSync(join3(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
11540
- } catch {
11541
- return out;
11542
- }
11557
+ } catch {}
11543
11558
  for (const name of names) {
11544
11559
  if (seen.has(name))
11545
11560
  continue;
11546
11561
  seen.add(name);
11547
11562
  out.push({ name, home: join3(root, PROFILES_DIR, name) });
11548
11563
  }
11564
+ if (basename(root) !== STANDARD_HOME)
11565
+ return out;
11566
+ let siblings = [];
11567
+ const parent = dirname3(root);
11568
+ try {
11569
+ siblings = readdirSync(parent, { withFileTypes: true }).filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(SIBLING_HOME_PREFIX) && entry.name.length > SIBLING_HOME_PREFIX.length && existsSync6(join3(parent, entry.name, "config.yaml"))).map((entry) => ({
11570
+ name: entry.name.slice(SIBLING_HOME_PREFIX.length),
11571
+ home: join3(parent, entry.name)
11572
+ })).sort((a, b) => a.name.localeCompare(b.name));
11573
+ } catch {
11574
+ return out;
11575
+ }
11576
+ for (const sibling of siblings) {
11577
+ const name = uniqueProfileName(sibling.name, seen);
11578
+ seen.add(name);
11579
+ out.push({ name, home: sibling.home });
11580
+ }
11549
11581
  return out;
11550
11582
  }
11551
11583
  function hermesProjectName(profile, source) {
@@ -11571,11 +11603,11 @@ function hermesProjectNameCandidates(name) {
11571
11603
  out.push({ profile: HERMES_DEFAULT_PROFILE, source: rest });
11572
11604
  return out;
11573
11605
  }
11574
- var PROFILES_DIR = "profiles", HERMES_DEFAULT_PROFILE = "default";
11606
+ var PROFILES_DIR = "profiles", STANDARD_HOME = ".hermes", SIBLING_HOME_PREFIX = ".hermes-", HERMES_DEFAULT_PROFILE = "default";
11575
11607
  var init_hermes_profiles = () => {};
11576
11608
 
11577
11609
  // lib/openclaw-profiles.ts
11578
- import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
11610
+ import { existsSync as existsSync7, readdirSync as readdirSync2 } from "node:fs";
11579
11611
  import { homedir as homedir5 } from "node:os";
11580
11612
  import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve7 } from "node:path";
11581
11613
  function openclawProfileHome() {
@@ -11607,7 +11639,7 @@ function listOpenClawProfiles() {
11607
11639
  } catch {
11608
11640
  return out;
11609
11641
  }
11610
- const named = entries.filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(".openclaw-") && entry.name.length > ".openclaw-".length && existsSync6(join4(parent, entry.name, "openclaw.json"))).map((entry) => ({
11642
+ const named = entries.filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(".openclaw-") && entry.name.length > ".openclaw-".length && existsSync7(join4(parent, entry.name, "openclaw.json"))).map((entry) => ({
11611
11643
  name: entry.name.slice(".openclaw-".length),
11612
11644
  home: join4(parent, entry.name)
11613
11645
  })).sort((a, b) => a.name.localeCompare(b.name));
@@ -11619,12 +11651,22 @@ var init_openclaw_profiles = () => {};
11619
11651
 
11620
11652
  // src/hooks/integrations.ts
11621
11653
  import { execSync as execSync3 } from "node:child_process";
11622
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync7, mkdirSync as mkdirSync4, unlinkSync } from "node:fs";
11654
+ import {
11655
+ cpSync,
11656
+ readFileSync as readFileSync5,
11657
+ writeFileSync as writeFileSync3,
11658
+ existsSync as existsSync8,
11659
+ lstatSync,
11660
+ mkdirSync as mkdirSync4,
11661
+ renameSync as renameSync2,
11662
+ rmSync as rmSync2,
11663
+ unlinkSync
11664
+ } from "node:fs";
11623
11665
  import { resolve as resolve8, dirname as dirname5 } from "node:path";
11624
11666
  import { fileURLToPath } from "node:url";
11625
11667
  import { homedir as homedir6 } from "node:os";
11626
11668
  function readJsonFile(path) {
11627
- if (!existsSync7(path))
11669
+ if (!existsSync8(path))
11628
11670
  return {};
11629
11671
  const raw = readFileSync5(path, "utf8");
11630
11672
  return JSON.parse(raw);
@@ -11636,7 +11678,7 @@ function writeJsonFile(path, data) {
11636
11678
  }
11637
11679
  function readYamlDoc(path) {
11638
11680
  try {
11639
- return existsSync7(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
11681
+ return existsSync8(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
11640
11682
  } catch {
11641
11683
  return $parseDocument("");
11642
11684
  }
@@ -11921,19 +11963,125 @@ function makePiProjectRelativeEntry(extPath) {
11921
11963
  }
11922
11964
  return extResolved;
11923
11965
  }
11924
- function hermesConfigHasHooks(settingsPath) {
11925
- if (!existsSync7(settingsPath))
11926
- return false;
11966
+ function getHermesPluginSourcePath() {
11967
+ const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
11968
+ if (fromEnv)
11969
+ return resolve8(fromEnv, "hermes-plugin");
11970
+ return resolve8(fileURLToPath(import.meta.url), "..", "..", "..", "hermes-plugin");
11971
+ }
11972
+ function hermesPluginPathForSettings(settingsPath) {
11973
+ return resolve8(dirname5(settingsPath), "plugins", HERMES_PLUGIN_ID);
11974
+ }
11975
+ function hasManagedHermesPlugin(settingsPath) {
11976
+ const pluginPath = hermesPluginPathForSettings(settingsPath);
11927
11977
  try {
11928
- const doc = readYamlDoc(settingsPath);
11929
- const js = doc.toJS() ?? {};
11930
- const hooks = js.hooks;
11931
- if (!hooks || typeof hooks !== "object")
11978
+ if (lstatSync(pluginPath).isSymbolicLink())
11932
11979
  return false;
11933
- for (const entries of Object.values(hooks)) {
11934
- if (Array.isArray(entries) && entries.some((h) => isMarkedHook(h)))
11935
- return true;
11980
+ if (!existsSync8(resolve8(pluginPath, HERMES_PLUGIN_MARKER)))
11981
+ return false;
11982
+ return HERMES_PLUGIN_FILES.every((file) => existsSync8(resolve8(pluginPath, file)));
11983
+ } catch {
11984
+ return false;
11985
+ }
11986
+ }
11987
+ function hasHermesPluginMarker(settingsPath) {
11988
+ const pluginPath = hermesPluginPathForSettings(settingsPath);
11989
+ try {
11990
+ return !lstatSync(pluginPath).isSymbolicLink() && existsSync8(resolve8(pluginPath, HERMES_PLUGIN_MARKER));
11991
+ } catch {
11992
+ return false;
11993
+ }
11994
+ }
11995
+ function installHermesPlugin(settingsPath) {
11996
+ const source = getHermesPluginSourcePath();
11997
+ for (const file of HERMES_PLUGIN_FILES) {
11998
+ if (!existsSync8(resolve8(source, file))) {
11999
+ throw new Error(`Hermes plugin asset is missing from the failproofai package: ${file}`);
12000
+ }
12001
+ }
12002
+ const destination = hermesPluginPathForSettings(settingsPath);
12003
+ if (existsSync8(destination)) {
12004
+ if (lstatSync(destination).isSymbolicLink() || !existsSync8(resolve8(destination, HERMES_PLUGIN_MARKER))) {
12005
+ throw new Error(`Refusing to overwrite an unmanaged Hermes plugin at ${destination}. ` + `Move it aside or install FailproofAI under a different Hermes profile.`);
12006
+ }
12007
+ }
12008
+ mkdirSync4(dirname5(destination), { recursive: true });
12009
+ const suffix = `${process.pid}-${Date.now()}`;
12010
+ const temporary = `${destination}.install-${suffix}`;
12011
+ const backup = `${destination}.backup-${suffix}`;
12012
+ let movedExisting = false;
12013
+ try {
12014
+ mkdirSync4(temporary, { recursive: true });
12015
+ for (const file of HERMES_PLUGIN_FILES) {
12016
+ cpSync(resolve8(source, file), resolve8(temporary, file));
12017
+ }
12018
+ writeFileSync3(resolve8(temporary, HERMES_PLUGIN_MARKER), "Managed by failproofai. Remove with `failproofai policies --uninstall --cli hermes`.\n", { encoding: "utf8", mode: 384 });
12019
+ if (existsSync8(destination)) {
12020
+ renameSync2(destination, backup);
12021
+ movedExisting = true;
12022
+ }
12023
+ renameSync2(temporary, destination);
12024
+ if (movedExisting)
12025
+ rmSync2(backup, { recursive: true, force: true });
12026
+ } catch (err) {
12027
+ rmSync2(temporary, { recursive: true, force: true });
12028
+ if (movedExisting && !existsSync8(destination) && existsSync8(backup)) {
12029
+ renameSync2(backup, destination);
12030
+ }
12031
+ throw err;
12032
+ }
12033
+ }
12034
+ function removeManagedHermesPlugin(settingsPath) {
12035
+ const pluginPath = hermesPluginPathForSettings(settingsPath);
12036
+ if (!hasHermesPluginMarker(settingsPath))
12037
+ return false;
12038
+ rmSync2(pluginPath, { recursive: true, force: true });
12039
+ return true;
12040
+ }
12041
+ function removeLegacyHermesHooks(doc) {
12042
+ const js = doc.toJS() ?? {};
12043
+ const hooks = js.hooks;
12044
+ let removed = 0;
12045
+ if (hooks && typeof hooks === "object") {
12046
+ for (const eventType of Object.keys(hooks)) {
12047
+ const entries = hooks[eventType];
12048
+ if (!Array.isArray(entries))
12049
+ continue;
12050
+ const before = entries.length;
12051
+ const filtered = entries.filter((hook) => !isMarkedHook(hook));
12052
+ removed += before - filtered.length;
12053
+ if (filtered.length === 0)
12054
+ delete hooks[eventType];
12055
+ else
12056
+ hooks[eventType] = filtered;
12057
+ }
12058
+ if (Object.keys(hooks).length === 0) {
12059
+ doc.delete("hooks");
12060
+ if (removed > 0)
12061
+ doc.delete("hooks_auto_accept");
12062
+ } else {
12063
+ doc.set("hooks", hooks);
11936
12064
  }
12065
+ }
12066
+ return removed;
12067
+ }
12068
+ function hermesConfigState(settingsPath) {
12069
+ if (!existsSync8(settingsPath)) {
12070
+ return { pluginEnabled: false, legacyShellHookPresent: false };
12071
+ }
12072
+ const doc = readYamlDoc(settingsPath);
12073
+ const js = doc.toJS() ?? {};
12074
+ const enabled = js.plugins?.enabled;
12075
+ const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook(entry)));
12076
+ return {
12077
+ pluginEnabled: Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID),
12078
+ legacyShellHookPresent
12079
+ };
12080
+ }
12081
+ function hermesConfigHasHooks(settingsPath) {
12082
+ try {
12083
+ const state = hermesConfigState(settingsPath);
12084
+ return state.pluginEnabled && hasManagedHermesPlugin(settingsPath) && !state.legacyShellHookPresent;
11937
12085
  } catch {}
11938
12086
  return false;
11939
12087
  }
@@ -11967,7 +12115,7 @@ function listInstallableIds() {
11967
12115
  function detectInstalledClis() {
11968
12116
  return INTEGRATION_TYPES.filter((id) => INTEGRATIONS[id]?.detectInstalled());
11969
12117
  }
11970
- 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;
12118
+ var claudeCode, codex, copilot, cursor, OPENCODE_PLUGIN_REL_PATH = "./plugins/failproofai.mjs", opencode, pi, HERMES_PLUGIN_ID = "failproofai", HERMES_PLUGIN_MARKER = ".failproofai-managed", HERMES_PLUGIN_FILES, hermes, OPENCLAW_PLUGIN_ID = "failproofai", openclaw, factory, devin, ANTIGRAVITY_HOOK_NAME = "failproofai", ANTIGRAVITY_TOOL_EVENTS, antigravity, goose, INTEGRATIONS;
11971
12119
  var init_integrations = __esm(() => {
11972
12120
  init_dist();
11973
12121
  init_hermes_profiles();
@@ -12082,7 +12230,7 @@ var init_integrations = __esm(() => {
12082
12230
  },
12083
12231
  hooksInstalledInSettings(scope, cwd) {
12084
12232
  const settingsPath = this.getSettingsPath(scope, cwd);
12085
- if (!existsSync7(settingsPath))
12233
+ if (!existsSync8(settingsPath))
12086
12234
  return false;
12087
12235
  try {
12088
12236
  const settings = this.readSettings(settingsPath);
@@ -12198,7 +12346,7 @@ var init_integrations = __esm(() => {
12198
12346
  },
12199
12347
  hooksInstalledInSettings(scope, cwd) {
12200
12348
  const settingsPath = this.getSettingsPath(scope, cwd);
12201
- if (!existsSync7(settingsPath))
12349
+ if (!existsSync8(settingsPath))
12202
12350
  return false;
12203
12351
  try {
12204
12352
  const settings = this.readSettings(settingsPath);
@@ -12312,7 +12460,7 @@ var init_integrations = __esm(() => {
12312
12460
  },
12313
12461
  hooksInstalledInSettings(scope, cwd) {
12314
12462
  const settingsPath = this.getSettingsPath(scope, cwd);
12315
- if (!existsSync7(settingsPath))
12463
+ if (!existsSync8(settingsPath))
12316
12464
  return false;
12317
12465
  try {
12318
12466
  const settings = this.readSettings(settingsPath);
@@ -12415,7 +12563,7 @@ var init_integrations = __esm(() => {
12415
12563
  },
12416
12564
  hooksInstalledInSettings(scope, cwd) {
12417
12565
  const settingsPath = this.getSettingsPath(scope, cwd);
12418
- if (!existsSync7(settingsPath))
12566
+ if (!existsSync8(settingsPath))
12419
12567
  return false;
12420
12568
  try {
12421
12569
  const settings = this.readSettings(settingsPath);
@@ -12499,7 +12647,7 @@ var init_integrations = __esm(() => {
12499
12647
  }
12500
12648
  this.writeSettings(settingsPath, settings);
12501
12649
  const pluginPath = opencodePluginFilePath(settingsPath);
12502
- if (existsSync7(pluginPath)) {
12650
+ if (existsSync8(pluginPath)) {
12503
12651
  try {
12504
12652
  const content = readFileSync5(pluginPath, "utf8");
12505
12653
  if (content.includes(FAILPROOFAI_HOOK_MARKER)) {
@@ -12513,7 +12661,7 @@ var init_integrations = __esm(() => {
12513
12661
  },
12514
12662
  hooksInstalledInSettings(scope, cwd) {
12515
12663
  const settingsPath = this.getSettingsPath(scope, cwd);
12516
- if (!existsSync7(settingsPath))
12664
+ if (!existsSync8(settingsPath))
12517
12665
  return false;
12518
12666
  try {
12519
12667
  const settings = this.readSettings(settingsPath);
@@ -12523,7 +12671,7 @@ var init_integrations = __esm(() => {
12523
12671
  if (!hasEntry)
12524
12672
  return false;
12525
12673
  const pluginPath = opencodePluginFilePath(settingsPath);
12526
- if (!existsSync7(pluginPath))
12674
+ if (!existsSync8(pluginPath))
12527
12675
  return false;
12528
12676
  const content = readFileSync5(pluginPath, "utf8");
12529
12677
  return content.includes(FAILPROOFAI_HOOK_MARKER);
@@ -12590,7 +12738,7 @@ var init_integrations = __esm(() => {
12590
12738
  }
12591
12739
  },
12592
12740
  removeHooksFromFile(settingsPath) {
12593
- if (!existsSync7(settingsPath))
12741
+ if (!existsSync8(settingsPath))
12594
12742
  return 0;
12595
12743
  const settings = this.readSettings(settingsPath);
12596
12744
  if (!Array.isArray(settings.packages))
@@ -12605,7 +12753,7 @@ var init_integrations = __esm(() => {
12605
12753
  },
12606
12754
  hooksInstalledInSettings(scope, cwd) {
12607
12755
  const settingsPath = this.getSettingsPath(scope, cwd);
12608
- if (!existsSync7(settingsPath))
12756
+ if (!existsSync8(settingsPath))
12609
12757
  return false;
12610
12758
  try {
12611
12759
  const settings = this.readSettings(settingsPath);
@@ -12620,9 +12768,11 @@ var init_integrations = __esm(() => {
12620
12768
  return binaryExists("pi");
12621
12769
  }
12622
12770
  };
12771
+ HERMES_PLUGIN_FILES = ["plugin.yaml", "__init__.py", "client.py", "ledger.py"];
12623
12772
  hermes = {
12624
12773
  id: "hermes",
12625
12774
  displayName: "Hermes",
12775
+ requiresHealthyDaemon: true,
12626
12776
  scopes: HERMES_HOOK_SCOPES,
12627
12777
  eventTypes: HERMES_HOOK_EVENT_TYPES,
12628
12778
  getSettingsPath() {
@@ -12637,62 +12787,62 @@ var init_integrations = __esm(() => {
12637
12787
  writeSettings(settingsPath, settings) {
12638
12788
  writeYamlDoc(settingsPath, settings);
12639
12789
  },
12640
- buildHookEntry(binaryPath, eventType, scope) {
12641
- const command = scope === "project" ? `npx -y failproofai --hook ${eventType} --cli hermes` : `"${binaryPath}" --hook ${eventType} --cli hermes`;
12790
+ prepareInstall(settingsPath) {
12791
+ installHermesPlugin(settingsPath);
12792
+ },
12793
+ buildHookEntry(_binaryPath, _eventType, _scope) {
12642
12794
  return {
12643
- command,
12644
- timeout: 30,
12645
- [FAILPROOFAI_HOOK_MARKER]: true
12795
+ [FAILPROOFAI_HOOK_MARKER]: true,
12796
+ _hermesPluginPath: getHermesPluginSourcePath()
12646
12797
  };
12647
12798
  },
12648
12799
  isFailproofaiHook: isMarkedHook,
12649
- writeHookEntries(settings, binaryPath, scope) {
12800
+ writeHookEntries(settings) {
12650
12801
  const doc = settings;
12802
+ removeLegacyHermesHooks(doc);
12651
12803
  const js = doc.toJS() ?? {};
12652
- const hooks = js.hooks && typeof js.hooks === "object" ? js.hooks : {};
12653
- for (const eventType of HERMES_HOOK_EVENT_TYPES) {
12654
- const entry = this.buildHookEntry(binaryPath, eventType, scope);
12655
- const arr = Array.isArray(hooks[eventType]) ? hooks[eventType] : [];
12656
- const idx = arr.findIndex((h) => isMarkedHook(h));
12657
- if (idx >= 0)
12658
- arr[idx] = entry;
12659
- else
12660
- arr.push(entry);
12661
- hooks[eventType] = arr;
12662
- }
12663
- doc.set("hooks", hooks);
12664
- doc.set("hooks_auto_accept", true);
12804
+ const plugins = js.plugins && typeof js.plugins === "object" ? js.plugins : {};
12805
+ const enabled = Array.isArray(plugins.enabled) ? [...plugins.enabled] : [];
12806
+ if (!enabled.includes(HERMES_PLUGIN_ID))
12807
+ enabled.push(HERMES_PLUGIN_ID);
12808
+ plugins.enabled = enabled;
12809
+ if (Array.isArray(plugins.disabled)) {
12810
+ plugins.disabled = plugins.disabled.filter((name) => name !== HERMES_PLUGIN_ID);
12811
+ if (plugins.disabled.length === 0)
12812
+ delete plugins.disabled;
12813
+ }
12814
+ doc.set("plugins", plugins);
12665
12815
  },
12666
12816
  removeHooksFromFile(settingsPath) {
12667
- if (!existsSync7(settingsPath))
12668
- return 0;
12669
12817
  const doc = readYamlDoc(settingsPath);
12818
+ let removed = removeLegacyHermesHooks(doc);
12670
12819
  const js = doc.toJS() ?? {};
12671
- const hooks = js.hooks;
12672
- let removed = 0;
12673
- if (hooks && typeof hooks === "object") {
12674
- for (const eventType of Object.keys(hooks)) {
12675
- const entries = hooks[eventType];
12676
- if (!Array.isArray(entries))
12677
- continue;
12678
- const before = entries.length;
12679
- const filtered = entries.filter((h) => !isMarkedHook(h));
12680
- removed += before - filtered.length;
12681
- if (filtered.length === 0)
12682
- delete hooks[eventType];
12683
- else
12684
- hooks[eventType] = filtered;
12820
+ const plugins = js.plugins;
12821
+ let configChanged = removed > 0;
12822
+ if (plugins && typeof plugins === "object") {
12823
+ if (Array.isArray(plugins.enabled)) {
12824
+ const before = plugins.enabled.length;
12825
+ plugins.enabled = plugins.enabled.filter((name) => name !== HERMES_PLUGIN_ID);
12826
+ if (plugins.enabled.length !== before) {
12827
+ removed += 1;
12828
+ configChanged = true;
12829
+ }
12830
+ if (plugins.enabled.length === 0)
12831
+ delete plugins.enabled;
12685
12832
  }
12686
- if (removed > 0) {
12687
- if (Object.keys(hooks).length === 0)
12688
- doc.delete("hooks");
12689
- else
12690
- doc.set("hooks", hooks);
12833
+ if (plugins.entries && HERMES_PLUGIN_ID in plugins.entries) {
12834
+ delete plugins.entries[HERMES_PLUGIN_ID];
12835
+ configChanged = true;
12691
12836
  }
12837
+ if (Object.keys(plugins).length === 0)
12838
+ doc.delete("plugins");
12839
+ else
12840
+ doc.set("plugins", plugins);
12692
12841
  }
12693
- const droppedAutoAccept = doc.delete("hooks_auto_accept");
12694
- if (removed > 0 || droppedAutoAccept)
12842
+ if (configChanged)
12695
12843
  writeYamlDoc(settingsPath, doc);
12844
+ if (removeManagedHermesPlugin(settingsPath))
12845
+ removed += 1;
12696
12846
  return removed;
12697
12847
  },
12698
12848
  hooksInstalledInSettings(scope, cwd) {
@@ -12757,7 +12907,7 @@ var init_integrations = __esm(() => {
12757
12907
  hooks.allowConversationAccess = true;
12758
12908
  },
12759
12909
  removeHooksFromFile(settingsPath) {
12760
- if (!existsSync7(settingsPath))
12910
+ if (!existsSync8(settingsPath))
12761
12911
  return 0;
12762
12912
  const settings = this.readSettings(settingsPath);
12763
12913
  const plugins = settings.plugins;
@@ -12787,7 +12937,7 @@ var init_integrations = __esm(() => {
12787
12937
  hooksInstalledInSettings(scope, cwd) {
12788
12938
  const settingsPaths = settingsPathsFor(this, scope, cwd);
12789
12939
  return settingsPaths.length > 0 && settingsPaths.every((settingsPath) => {
12790
- if (!existsSync7(settingsPath))
12940
+ if (!existsSync8(settingsPath))
12791
12941
  return false;
12792
12942
  try {
12793
12943
  const settings = this.readSettings(settingsPath);
@@ -12885,7 +13035,7 @@ var init_integrations = __esm(() => {
12885
13035
  },
12886
13036
  hooksInstalledInSettings(scope, cwd) {
12887
13037
  const settingsPath = this.getSettingsPath(scope, cwd);
12888
- if (!existsSync7(settingsPath))
13038
+ if (!existsSync8(settingsPath))
12889
13039
  return false;
12890
13040
  try {
12891
13041
  const settings = this.readSettings(settingsPath);
@@ -12991,7 +13141,7 @@ var init_integrations = __esm(() => {
12991
13141
  },
12992
13142
  hooksInstalledInSettings(scope, cwd) {
12993
13143
  const settingsPath = this.getSettingsPath(scope, cwd);
12994
- if (!existsSync7(settingsPath))
13144
+ if (!existsSync8(settingsPath))
12995
13145
  return false;
12996
13146
  try {
12997
13147
  const settings = this.readSettings(settingsPath);
@@ -13130,7 +13280,7 @@ var init_integrations = __esm(() => {
13130
13280
  },
13131
13281
  hooksInstalledInSettings(scope, cwd) {
13132
13282
  const settingsPath = this.getSettingsPath(scope, cwd);
13133
- if (!existsSync7(settingsPath))
13283
+ if (!existsSync8(settingsPath))
13134
13284
  return false;
13135
13285
  try {
13136
13286
  const settings = this.readSettings(settingsPath);
@@ -13236,7 +13386,7 @@ var init_integrations = __esm(() => {
13236
13386
  },
13237
13387
  hooksInstalledInSettings(scope, cwd) {
13238
13388
  const settingsPath = this.getSettingsPath(scope, cwd);
13239
- if (!existsSync7(settingsPath))
13389
+ if (!existsSync8(settingsPath))
13240
13390
  return false;
13241
13391
  try {
13242
13392
  const settings = this.readSettings(settingsPath);
@@ -13627,12 +13777,12 @@ var init_telemetry_id2 = __esm(() => {
13627
13777
  // src/hooks/custom-hooks-loader.ts
13628
13778
  import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename3 } from "node:path";
13629
13779
  import { randomUUID } from "crypto";
13630
- import { existsSync as existsSync8, readdirSync as readdirSync3 } from "node:fs";
13780
+ import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
13631
13781
  import { readFile as readFile3 } from "node:fs/promises";
13632
13782
  import { pathToFileURL as pathToFileURL2 } from "node:url";
13633
13783
  import { createHash as createHash4 } from "node:crypto";
13634
13784
  function discoverPolicyFiles(dir) {
13635
- if (!existsSync8(dir))
13785
+ if (!existsSync9(dir))
13636
13786
  return [];
13637
13787
  try {
13638
13788
  const entries = readdirSync3(dir, { withFileTypes: true });
@@ -13642,7 +13792,7 @@ function discoverPolicyFiles(dir) {
13642
13792
  }
13643
13793
  }
13644
13794
  function findSkippedPolicyFiles(dir) {
13645
- if (!existsSync8(dir))
13795
+ if (!existsSync9(dir))
13646
13796
  return [];
13647
13797
  try {
13648
13798
  return readdirSync3(dir, { withFileTypes: true }).filter((e) => e.isFile() && LOADABLE_EXT_RE.test(e.name) && !CONVENTION_FILE_RE.test(e.name) && !e.name.endsWith(".d.ts") && !isTmpArtifact(e.name)).map((e) => e.name).sort((a, b) => a.localeCompare(b));
@@ -13729,7 +13879,7 @@ async function loadCustomHooks(customPoliciesPath, opts) {
13729
13879
  if (!customPoliciesPath)
13730
13880
  return [];
13731
13881
  const absPath = isAbsolute2(customPoliciesPath) ? customPoliciesPath : resolve10(opts?.sessionCwd ?? process.cwd(), customPoliciesPath);
13732
- if (!existsSync8(absPath)) {
13882
+ if (!existsSync9(absPath)) {
13733
13883
  if (opts?.strict)
13734
13884
  throw new Error(`Custom hooks file not found: ${absPath}`);
13735
13885
  hookLogWarn(`customPoliciesPath not found: ${absPath}`);
@@ -13815,7 +13965,7 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
13815
13965
  const absPath = resolve10(projectRoot, customPoliciesPath);
13816
13966
  const cloudManaged = cloudManagedByPath.get(absPath);
13817
13967
  const pack = packByPath.get(absPath);
13818
- if (existsSync8(absPath)) {
13968
+ if (existsSync9(absPath)) {
13819
13969
  if (!loadedPaths.has(absPath)) {
13820
13970
  loadedPaths.add(absPath);
13821
13971
  const hooksBefore = getCustomHooks().length;
@@ -14883,7 +15033,7 @@ var init_pack_cli = __esm(() => {
14883
15033
 
14884
15034
  // src/hooks/pack-store.ts
14885
15035
  import { createHash as createHash5 } from "node:crypto";
14886
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync4 } from "node:fs";
15036
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
14887
15037
  import { dirname as dirname7, resolve as resolve11 } from "node:path";
14888
15038
  function baseUrl() {
14889
15039
  return (process.env.FAILPROOFAI_PACK_BASE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
@@ -15057,9 +15207,9 @@ function writeAtomic(target, bytes) {
15057
15207
  try {
15058
15208
  mkdirSync5(dirname7(target), { recursive: true });
15059
15209
  writeFileSync4(tempPath, bytes);
15060
- renameSync2(tempPath, target);
15210
+ renameSync3(tempPath, target);
15061
15211
  } catch (err) {
15062
- rmSync2(tempPath, { force: true });
15212
+ rmSync3(tempPath, { force: true });
15063
15213
  throw err;
15064
15214
  }
15065
15215
  }
@@ -15233,7 +15383,7 @@ async function addPack(source, opts) {
15233
15383
  const root = packsRoot();
15234
15384
  const artifactRel = `artifacts/${fetched.artifactDigest}.mjs`;
15235
15385
  const artifactAbs = resolve11(root, artifactRel);
15236
- if (!existsSync9(artifactAbs))
15386
+ if (!existsSync10(artifactAbs))
15237
15387
  writeAtomic(artifactAbs, fetched.artifact);
15238
15388
  try {
15239
15389
  await verifyArtifactRegisters(artifactAbs, available);
@@ -15276,7 +15426,7 @@ async function addPack(source, opts) {
15276
15426
  }
15277
15427
  function setPackPolicyEnabled(packId, name, on) {
15278
15428
  const manifestPath = resolve11(packsRoot(), "installed.json");
15279
- if (!existsSync9(manifestPath))
15429
+ if (!existsSync10(manifestPath))
15280
15430
  return { ok: false, reason: "no packs are installed" };
15281
15431
  let raw;
15282
15432
  try {
@@ -15310,7 +15460,7 @@ function bareId(value) {
15310
15460
  }
15311
15461
  function removePack(id) {
15312
15462
  const manifestPath = resolve11(packsRoot(), "installed.json");
15313
- if (!existsSync9(manifestPath))
15463
+ if (!existsSync10(manifestPath))
15314
15464
  return null;
15315
15465
  let raw;
15316
15466
  try {
@@ -15335,7 +15485,7 @@ function removePack(id) {
15335
15485
  function upsertInstalled(record, carryAbsorbedSelection = true) {
15336
15486
  const manifestPath = resolve11(packsRoot(), "installed.json");
15337
15487
  let packs = [];
15338
- if (existsSync9(manifestPath)) {
15488
+ if (existsSync10(manifestPath)) {
15339
15489
  try {
15340
15490
  const raw = JSON.parse(readFileSync6(manifestPath, "utf8"));
15341
15491
  if (Array.isArray(raw.packs))
@@ -16178,16 +16328,16 @@ import {
16178
16328
  readFileSync as readFileSync7,
16179
16329
  writeFileSync as writeFileSync5,
16180
16330
  appendFileSync as appendFileSync2,
16181
- renameSync as renameSync3,
16331
+ renameSync as renameSync4,
16182
16332
  readdirSync as readdirSync4,
16183
16333
  mkdirSync as mkdirSync6,
16184
- existsSync as existsSync10,
16334
+ existsSync as existsSync11,
16185
16335
  statSync as statSync5,
16186
16336
  unlinkSync as unlinkSync2
16187
16337
  } from "node:fs";
16188
16338
  import { join as join6 } from "node:path";
16189
16339
  function ensureDir() {
16190
- if (!existsSync10(storeDirValue())) {
16340
+ if (!existsSync11(storeDirValue())) {
16191
16341
  mkdirSync6(storeDirValue(), { recursive: true });
16192
16342
  }
16193
16343
  }
@@ -16243,7 +16393,7 @@ function persistHookActivity(entry) {
16243
16393
  function rotate(currentPath, countPath) {
16244
16394
  const archiveName = `page-${Date.now()}-${rotateSeq++}.jsonl`;
16245
16395
  const archivePath = join6(storeDirValue(), archiveName);
16246
- renameSync3(currentPath, archivePath);
16396
+ renameSync4(currentPath, archivePath);
16247
16397
  writeCount(countPath, 0);
16248
16398
  }
16249
16399
  function readCount(countPath) {
@@ -16289,7 +16439,7 @@ function writeStoredStats(s) {
16289
16439
  const tmpPath = join6(storeDirValue(), `stats.json.${process.pid}.tmp`);
16290
16440
  try {
16291
16441
  writeFileSync5(tmpPath, JSON.stringify(s), "utf-8");
16292
- renameSync3(tmpPath, join6(storeDirValue(), STATS_FILE));
16442
+ renameSync4(tmpPath, join6(storeDirValue(), STATS_FILE));
16293
16443
  return true;
16294
16444
  } catch {
16295
16445
  try {
@@ -16310,7 +16460,7 @@ function rebuildHookActivityStats() {
16310
16460
  let sawAny = false;
16311
16461
  for (const file of files) {
16312
16462
  const path = join6(storeDirValue(), file);
16313
- if (!existsSync10(path))
16463
+ if (!existsSync11(path))
16314
16464
  continue;
16315
16465
  sawAny = true;
16316
16466
  for (const entry of readJsonlFile(path))
@@ -16379,7 +16529,7 @@ var init_hook_activity_store = __esm(() => {
16379
16529
  });
16380
16530
 
16381
16531
  // src/hooks/delivery-health.ts
16382
- import { existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
16532
+ import { existsSync as existsSync12, readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
16383
16533
  import { join as join7 } from "node:path";
16384
16534
  function parseParkedName(name) {
16385
16535
  const poison = name.endsWith(POISON_SUFFIX);
@@ -16408,7 +16558,7 @@ function parseParkedName(name) {
16408
16558
  }
16409
16559
  function deliveryHealth(home, now = Date.now()) {
16410
16560
  const dir = failedDir(home);
16411
- if (!existsSync11(dir))
16561
+ if (!existsSync12(dir))
16412
16562
  return EMPTY;
16413
16563
  let entries;
16414
16564
  try {
@@ -17173,7 +17323,7 @@ var init_cursor_projects = __esm(() => {
17173
17323
  });
17174
17324
 
17175
17325
  // lib/sqlite-reader.ts
17176
- import { existsSync as existsSync12, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
17326
+ import { existsSync as existsSync13, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
17177
17327
  import initSqlJs from "sql.js/dist/sql-asm.js";
17178
17328
  async function tryNodeSqlite(dbPath) {
17179
17329
  try {
@@ -17331,7 +17481,7 @@ async function trySqlJs(dbPath) {
17331
17481
  }
17332
17482
  }
17333
17483
  async function openSqliteReadonly(dbPath, options = {}) {
17334
- if (!existsSync12(dbPath))
17484
+ if (!existsSync13(dbPath))
17335
17485
  return null;
17336
17486
  if (!options.forcePortable) {
17337
17487
  const native = await tryNodeSqlite(dbPath);
@@ -17992,7 +18142,7 @@ var init_hermes_projects = __esm(() => {
17992
18142
  });
17993
18143
 
17994
18144
  // lib/openclaw-db.ts
17995
- import { existsSync as existsSync13 } from "node:fs";
18145
+ import { existsSync as existsSync14 } from "node:fs";
17996
18146
  import { join as join15 } from "node:path";
17997
18147
  function str(value) {
17998
18148
  return typeof value === "string" && value.length > 0 ? value : undefined;
@@ -18012,7 +18162,7 @@ function listOpenClawDatabases(home, agentIds) {
18012
18162
  const out = [];
18013
18163
  for (const agentId of agentIds) {
18014
18164
  const dbPath = join15(home, "agents", agentId, "agent", DB_NAME);
18015
- if (existsSync13(dbPath))
18165
+ if (existsSync14(dbPath))
18016
18166
  out.push({ agentId, dbPath });
18017
18167
  }
18018
18168
  return out;
@@ -20198,13 +20348,13 @@ var init_log_entries = __esm(() => {
20198
20348
  });
20199
20349
 
20200
20350
  // lib/codex-sessions.ts
20201
- import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync14, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, statSync as statSync11 } from "node:fs";
20351
+ import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, statSync as statSync11 } from "node:fs";
20202
20352
  import { readFile as readFile11 } from "node:fs/promises";
20203
20353
  import { dirname as dirname8, join as join26 } from "node:path";
20204
20354
  import { homedir as homedir18 } from "node:os";
20205
20355
  function readCache() {
20206
20356
  try {
20207
- if (!existsSync14(CACHE_PATH))
20357
+ if (!existsSync15(CACHE_PATH))
20208
20358
  return {};
20209
20359
  return JSON.parse(readFileSync10(CACHE_PATH, "utf-8"));
20210
20360
  } catch {
@@ -20232,7 +20382,7 @@ function dirSearch(dir, sessionId) {
20232
20382
  function findCodexTranscript(sessionId) {
20233
20383
  const cache = readCache();
20234
20384
  const cached = cache[sessionId];
20235
- if (cached && existsSync14(cached))
20385
+ if (cached && existsSync15(cached))
20236
20386
  return cached;
20237
20387
  const root = join26(homedir18(), ".codex", "sessions");
20238
20388
  const today = new Date;
@@ -20526,7 +20676,7 @@ var init_resolve_permission_mode = __esm(() => {
20526
20676
  });
20527
20677
 
20528
20678
  // lib/copilot-sessions.ts
20529
- import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync15, statSync as statSync12 } from "node:fs";
20679
+ import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync16, statSync as statSync12 } from "node:fs";
20530
20680
  import { readFile as readFile12 } from "node:fs/promises";
20531
20681
  import { join as join27, resolve as resolve13, sep as sep2 } from "node:path";
20532
20682
  import { homedir as homedir19 } from "node:os";
@@ -20555,13 +20705,13 @@ function findCopilotTranscript(sessionId) {
20555
20705
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
20556
20706
  if (!candidate)
20557
20707
  return null;
20558
- return existsSync15(candidate) ? candidate : null;
20708
+ return existsSync16(candidate) ? candidate : null;
20559
20709
  }
20560
20710
  function findCopilotWorkspace(sessionId) {
20561
20711
  const candidate = resolveSessionFile(sessionId, "workspace.yaml");
20562
20712
  if (!candidate)
20563
20713
  return null;
20564
- return existsSync15(candidate) ? candidate : null;
20714
+ return existsSync16(candidate) ? candidate : null;
20565
20715
  }
20566
20716
  function readYamlScalar(path, key) {
20567
20717
  try {
@@ -20743,7 +20893,7 @@ var init_copilot_sessions = __esm(() => {
20743
20893
  });
20744
20894
 
20745
20895
  // lib/cursor-sessions.ts
20746
- import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync16, statSync as statSync13 } from "node:fs";
20896
+ import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync17, statSync as statSync13 } from "node:fs";
20747
20897
  import { readFile as readFile13 } from "node:fs/promises";
20748
20898
  import { basename as basename4, join as join28, resolve as resolve14, sep as sep3 } from "node:path";
20749
20899
  import { homedir as homedir20 } from "node:os";
@@ -20766,7 +20916,7 @@ function getCursorSessionDir(sessionId) {
20766
20916
  const transcriptRoot = resolve14(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
20767
20917
  if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
20768
20918
  continue;
20769
- if (existsSync16(candidate))
20919
+ if (existsSync17(candidate))
20770
20920
  return candidate;
20771
20921
  }
20772
20922
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
@@ -20774,7 +20924,7 @@ function getCursorSessionDir(sessionId) {
20774
20924
  const candidate = resolve14(root, sessionId);
20775
20925
  if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
20776
20926
  continue;
20777
- if (existsSync16(candidate))
20927
+ if (existsSync17(candidate))
20778
20928
  return candidate;
20779
20929
  }
20780
20930
  return null;
@@ -20784,11 +20934,11 @@ function findCursorTranscript(sessionId) {
20784
20934
  if (!dir)
20785
20935
  return null;
20786
20936
  const newCandidate = join28(dir, `${basename4(dir)}.jsonl`);
20787
- if (existsSync16(newCandidate))
20937
+ if (existsSync17(newCandidate))
20788
20938
  return newCandidate;
20789
20939
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
20790
20940
  const candidate = join28(dir, name);
20791
- if (existsSync16(candidate))
20941
+ if (existsSync17(candidate))
20792
20942
  return candidate;
20793
20943
  }
20794
20944
  return null;
@@ -20999,7 +21149,7 @@ var init_cursor_sessions = __esm(() => {
20999
21149
  });
21000
21150
 
21001
21151
  // lib/pi-sessions.ts
21002
- import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync17, statSync as statSync14 } from "node:fs";
21152
+ import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync18, statSync as statSync14 } from "node:fs";
21003
21153
  import { readFile as readFile14 } from "node:fs/promises";
21004
21154
  import { join as join29, resolve as resolve15, sep as sep4 } from "node:path";
21005
21155
  import { homedir as homedir21 } from "node:os";
@@ -21036,7 +21186,7 @@ function findPiTranscript(sessionId) {
21036
21186
  const candidate = resolve15(cwdPath, f);
21037
21187
  if (!candidate.startsWith(`${cwdPath}${sep4}`))
21038
21188
  continue;
21039
- if (existsSync17(candidate))
21189
+ if (existsSync18(candidate))
21040
21190
  return candidate;
21041
21191
  }
21042
21192
  }
@@ -21442,10 +21592,10 @@ var init_pack_failclosed = __esm(() => {
21442
21592
  // lib/atomic-write.ts
21443
21593
  import {
21444
21594
  chmodSync as chmodSync2,
21445
- existsSync as existsSync18,
21595
+ existsSync as existsSync19,
21446
21596
  mkdirSync as mkdirSync8,
21447
- renameSync as renameSync4,
21448
- rmSync as rmSync3,
21597
+ renameSync as renameSync5,
21598
+ rmSync as rmSync4,
21449
21599
  statSync as statSync15,
21450
21600
  writeFileSync as writeFileSync7
21451
21601
  } from "node:fs";
@@ -21455,7 +21605,7 @@ function writeJsonAtomically(filePath, value, opts = {}) {
21455
21605
  const mode = opts.mode ?? 384;
21456
21606
  const dirMode = opts.dirMode ?? 448;
21457
21607
  const dir = dirname9(filePath);
21458
- if (!existsSync18(dir))
21608
+ if (!existsSync19(dir))
21459
21609
  mkdirSync8(dir, { recursive: true, mode: dirMode });
21460
21610
  const tmp = `${filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
21461
21611
  try {
@@ -21464,14 +21614,14 @@ function writeJsonAtomically(filePath, value, opts = {}) {
21464
21614
  if ((statSync15(tmp).mode & 63) !== 0)
21465
21615
  chmodSync2(tmp, mode);
21466
21616
  } catch {}
21467
- renameSync4(tmp, filePath);
21617
+ renameSync5(tmp, filePath);
21468
21618
  try {
21469
21619
  if ((statSync15(filePath).mode & 63) !== 0)
21470
21620
  chmodSync2(filePath, mode);
21471
21621
  } catch {}
21472
21622
  } catch (err) {
21473
21623
  try {
21474
- rmSync3(tmp, { force: true });
21624
+ rmSync4(tmp, { force: true });
21475
21625
  } catch {}
21476
21626
  throw err;
21477
21627
  }
@@ -21479,7 +21629,7 @@ function writeJsonAtomically(filePath, value, opts = {}) {
21479
21629
  var init_atomic_write = () => {};
21480
21630
 
21481
21631
  // src/hooks/session-pause.ts
21482
- import { existsSync as existsSync19, mkdirSync as mkdirSync9, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync4 } from "node:fs";
21632
+ import { existsSync as existsSync20, mkdirSync as mkdirSync9, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync5 } from "node:fs";
21483
21633
  import { createHash as createHash6 } from "node:crypto";
21484
21634
  import { join as join30, resolve as resolve16 } from "node:path";
21485
21635
  function pauseStateDir() {
@@ -21546,7 +21696,7 @@ function readActivePause(sessionId, now = Date.now()) {
21546
21696
  return null;
21547
21697
  try {
21548
21698
  const path = pauseFilePath(sessionId);
21549
- if (!existsSync19(path))
21699
+ if (!existsSync20(path))
21550
21700
  return null;
21551
21701
  const stored = parseStored(JSON.parse(readFileSync15(path, "utf8")));
21552
21702
  if (!stored)
@@ -21577,10 +21727,10 @@ function writePause(opts) {
21577
21727
  }
21578
21728
  function clearPause(sessionId) {
21579
21729
  const path = pauseFilePath(sessionId);
21580
- if (!existsSync19(path))
21730
+ if (!existsSync20(path))
21581
21731
  return false;
21582
21732
  try {
21583
- rmSync4(path);
21733
+ rmSync5(path);
21584
21734
  return true;
21585
21735
  } catch {
21586
21736
  return false;
@@ -21588,7 +21738,7 @@ function clearPause(sessionId) {
21588
21738
  }
21589
21739
  function listActivePauses(now = Date.now()) {
21590
21740
  const dir = pauseStateDir();
21591
- if (!existsSync19(dir))
21741
+ if (!existsSync20(dir))
21592
21742
  return [];
21593
21743
  const out = [];
21594
21744
  let names;
@@ -21642,12 +21792,12 @@ var init_session_pause = __esm(() => {
21642
21792
  import { createHash as createHash7 } from "node:crypto";
21643
21793
  import {
21644
21794
  chmodSync as chmodSync3,
21645
- existsSync as existsSync20,
21795
+ existsSync as existsSync21,
21646
21796
  mkdirSync as mkdirSync10,
21647
21797
  readdirSync as readdirSync14,
21648
21798
  readFileSync as readFileSync16,
21649
- renameSync as renameSync5,
21650
- rmSync as rmSync5,
21799
+ renameSync as renameSync6,
21800
+ rmSync as rmSync6,
21651
21801
  statSync as statSync16,
21652
21802
  writeFileSync as writeFileSync8
21653
21803
  } from "node:fs";
@@ -21694,7 +21844,7 @@ function platformPackageBinary(dir) {
21694
21844
  return null;
21695
21845
  }
21696
21846
  const candidate = resolve17(dir, "bin", "failproofaid");
21697
- return existsSync20(candidate) ? candidate : null;
21847
+ return existsSync21(candidate) ? candidate : null;
21698
21848
  }
21699
21849
  function pruneOldDaemonBinaries(keep = 2) {
21700
21850
  const removed = [];
@@ -21706,7 +21856,7 @@ function pruneOldDaemonBinaries(keep = 2) {
21706
21856
  }).sort((a, b) => b.mtime - a.mtime);
21707
21857
  for (const stale of entries.slice(keep)) {
21708
21858
  try {
21709
- rmSync5(stale.full, { force: true });
21859
+ rmSync6(stale.full, { force: true });
21710
21860
  removed.push(stale.full);
21711
21861
  } catch {}
21712
21862
  }
@@ -21720,10 +21870,10 @@ function installBinaryBytes(binary) {
21720
21870
  mkdirSync10(daemonBinaryDir(), { recursive: true });
21721
21871
  writeFileSync8(tempPath, binary);
21722
21872
  chmodSync3(tempPath, 493);
21723
- renameSync5(tempPath, target);
21873
+ renameSync6(tempPath, target);
21724
21874
  return target;
21725
21875
  } catch (err) {
21726
- rmSync5(tempPath, { force: true });
21876
+ rmSync6(tempPath, { force: true });
21727
21877
  throw err;
21728
21878
  }
21729
21879
  }
@@ -21772,7 +21922,7 @@ function digestFor2(manifest, assetName) {
21772
21922
  }
21773
21923
  async function downloadFailproofaidBinary(key) {
21774
21924
  const target = installedBinaryPath();
21775
- if (existsSync20(target))
21925
+ if (existsSync21(target))
21776
21926
  return { path: target };
21777
21927
  if (process.env.FAILPROOFAI_NO_DOWNLOAD) {
21778
21928
  return { error: "daemon downloads are disabled (FAILPROOFAI_NO_DOWNLOAD)" };
@@ -21806,10 +21956,10 @@ var init_daemon_download = __esm(() => {
21806
21956
 
21807
21957
  // src/hooks/daemon-client.ts
21808
21958
  import { createConnection as createConnection2 } from "node:net";
21809
- import { existsSync as existsSync21 } from "node:fs";
21959
+ import { existsSync as existsSync22 } from "node:fs";
21810
21960
  function daemonSocketPresent() {
21811
21961
  try {
21812
- return existsSync21(socketPath2());
21962
+ return existsSync22(socketPath2());
21813
21963
  } catch {
21814
21964
  return false;
21815
21965
  }
@@ -21935,13 +22085,13 @@ var init_daemon_client2 = __esm(() => {
21935
22085
 
21936
22086
  // src/hooks/daemon-service.ts
21937
22087
  import {
21938
- existsSync as existsSync22,
22088
+ existsSync as existsSync23,
21939
22089
  mkdirSync as mkdirSync11,
21940
22090
  mkdtempSync,
21941
22091
  readFileSync as readFileSync17,
21942
22092
  writeFileSync as writeFileSync9,
21943
22093
  unlinkSync as unlinkSync3,
21944
- rmSync as rmSync6
22094
+ rmSync as rmSync7
21945
22095
  } from "node:fs";
21946
22096
  import { homedir as homedir22, tmpdir as tmpdir2, userInfo } from "node:os";
21947
22097
  import { resolve as resolve18 } from "node:path";
@@ -21966,13 +22116,13 @@ function resolveFailproofaidBinaryPath() {
21966
22116
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
21967
22117
  return process.env.FAILPROOFAI_DAEMON_BINARY;
21968
22118
  const downloaded = installedBinaryPath();
21969
- if (existsSync22(downloaded))
22119
+ if (existsSync23(downloaded))
21970
22120
  return downloaded;
21971
22121
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
21972
22122
  if (packageRoot) {
21973
22123
  for (const profile of ["release", "debug"]) {
21974
22124
  const candidate = resolve18(packageRoot, "target", profile, "failproofaid");
21975
- if (existsSync22(candidate))
22125
+ if (existsSync23(candidate))
21976
22126
  return candidate;
21977
22127
  }
21978
22128
  }
@@ -22003,7 +22153,7 @@ function resolveWorkerCommand() {
22003
22153
  if (!packageRoot)
22004
22154
  return null;
22005
22155
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
22006
- if (!existsSync22(workerScript))
22156
+ if (!existsSync23(workerScript))
22007
22157
  return null;
22008
22158
  return `${shellQuote(process.execPath)} ${shellQuote(workerScript)}`;
22009
22159
  }
@@ -22014,7 +22164,7 @@ function resolveCliCommand() {
22014
22164
  if (!packageRoot)
22015
22165
  return null;
22016
22166
  const cliScript = resolve18(packageRoot, "dist", "cli.mjs");
22017
- if (!existsSync22(cliScript))
22167
+ if (!existsSync23(cliScript))
22018
22168
  return null;
22019
22169
  return `${shellQuote(process.execPath)} ${shellQuote(cliScript)}`;
22020
22170
  }
@@ -22028,7 +22178,7 @@ function workerScriptPath() {
22028
22178
  if (!packageRoot)
22029
22179
  return null;
22030
22180
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
22031
- return existsSync22(workerScript) ? workerScript : null;
22181
+ return existsSync23(workerScript) ? workerScript : null;
22032
22182
  }
22033
22183
  function assertUnitSafe(value, field) {
22034
22184
  if (UNIT_UNSAFE_RE.test(value)) {
@@ -22120,14 +22270,14 @@ function writePrivilegedFile(destination, contents, mode = "0644") {
22120
22270
  writeFileSync9(staging, contents, "utf8");
22121
22271
  runPrivileged("install", ["-m", mode, staging, destination]);
22122
22272
  } finally {
22123
- rmSync6(stagingDir, { recursive: true, force: true });
22273
+ rmSync7(stagingDir, { recursive: true, force: true });
22124
22274
  }
22125
22275
  }
22126
22276
  function removeLegacyUserService() {
22127
22277
  try {
22128
22278
  if (process.platform === "linux") {
22129
22279
  const legacy = legacySystemdUserUnitPath();
22130
- if (!existsSync22(legacy))
22280
+ if (!existsSync23(legacy))
22131
22281
  return;
22132
22282
  try {
22133
22283
  execFileSync2("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -22144,7 +22294,7 @@ function removeLegacyUserService() {
22144
22294
  } catch {}
22145
22295
  } else {
22146
22296
  const legacyAgent = legacyLaunchAgentPlistPath();
22147
- if (existsSync22(legacyAgent)) {
22297
+ if (existsSync23(legacyAgent)) {
22148
22298
  try {
22149
22299
  execFileSync2("launchctl", ["unload", "-w", legacyAgent], {
22150
22300
  stdio: "ignore",
@@ -22154,7 +22304,7 @@ function removeLegacyUserService() {
22154
22304
  unlinkSync3(legacyAgent);
22155
22305
  }
22156
22306
  const legacyDaemon = legacySharedLaunchDaemonPath();
22157
- if (existsSync22(legacyDaemon)) {
22307
+ if (existsSync23(legacyDaemon)) {
22158
22308
  try {
22159
22309
  runPrivileged("launchctl", ["unload", "-w", legacyDaemon]);
22160
22310
  } catch {}
@@ -22171,7 +22321,7 @@ function systemdUnitContents(binaryPath, workerCmd, cliCmd = null) {
22171
22321
  const user = assertUnitSafe(serviceUser(), "User");
22172
22322
  assertUnitSafe(binaryPath, "ExecStart");
22173
22323
  assertUnitSafe(homedir22(), "HOME");
22174
- const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync22(p));
22324
+ const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync23(p));
22175
22325
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe(p, "ConditionPathExists")}
22176
22326
  `).join("");
22177
22327
  return `[Unit]
@@ -22366,7 +22516,7 @@ function readInstalledServiceDefinition() {
22366
22516
  if (!isDaemonSupportedPlatform())
22367
22517
  return null;
22368
22518
  const path = daemonServiceFilePath();
22369
- if (!path || !existsSync22(path))
22519
+ if (!path || !existsSync23(path))
22370
22520
  return null;
22371
22521
  try {
22372
22522
  return readFileSync17(path, "utf8");
@@ -22502,7 +22652,7 @@ async function uninstallDaemonService() {
22502
22652
  try {
22503
22653
  if (process.platform === "linux") {
22504
22654
  const unitPath = systemdUnitPath();
22505
- if (!existsSync22(unitPath))
22655
+ if (!existsSync23(unitPath))
22506
22656
  return;
22507
22657
  try {
22508
22658
  runPrivileged("systemctl", ["disable", "--now", systemdUnitName()]);
@@ -22513,7 +22663,7 @@ async function uninstallDaemonService() {
22513
22663
  } catch {}
22514
22664
  } else {
22515
22665
  const plistPath = launchdPlistPath();
22516
- if (!existsSync22(plistPath))
22666
+ if (!existsSync23(plistPath))
22517
22667
  return;
22518
22668
  try {
22519
22669
  runPrivileged("launchctl", ["unload", "-w", plistPath]);
@@ -22530,7 +22680,7 @@ function daemonVersionSkew() {
22530
22680
  const recorded = readVersionFile()?.daemon;
22531
22681
  if (!recorded)
22532
22682
  return null;
22533
- if (!existsSync22(installedBinaryPath(recorded)))
22683
+ if (!existsSync23(installedBinaryPath(recorded)))
22534
22684
  return null;
22535
22685
  return recorded === version2 ? null : { installed: recorded, expected: version2 };
22536
22686
  }
@@ -22548,7 +22698,7 @@ function daemonServiceStatus() {
22548
22698
  if (!isDaemonSupportedPlatform())
22549
22699
  return "unsupported-platform";
22550
22700
  if (process.platform === "linux") {
22551
- if (!existsSync22(systemdUnitPath()))
22701
+ if (!existsSync23(systemdUnitPath()))
22552
22702
  return "not-installed";
22553
22703
  try {
22554
22704
  const out = execFileSync2("systemctl", ["is-active", systemdUnitName()], {
@@ -22561,7 +22711,7 @@ function daemonServiceStatus() {
22561
22711
  }
22562
22712
  }
22563
22713
  const plistPath = launchdPlistPath();
22564
- if (!existsSync22(plistPath))
22714
+ if (!existsSync23(plistPath))
22565
22715
  return "not-installed";
22566
22716
  try {
22567
22717
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -22593,12 +22743,12 @@ var init_daemon_service = __esm(() => {
22593
22743
  // src/hooks/fp-reset.ts
22594
22744
  import {
22595
22745
  copyFileSync,
22596
- existsSync as existsSync23,
22746
+ existsSync as existsSync24,
22597
22747
  mkdirSync as mkdirSync12,
22598
22748
  readFileSync as readFileSync18,
22599
22749
  readdirSync as readdirSync15,
22600
- renameSync as renameSync6,
22601
- rmSync as rmSync7,
22750
+ renameSync as renameSync7,
22751
+ rmSync as rmSync8,
22602
22752
  rmdirSync,
22603
22753
  statSync as statSync17,
22604
22754
  writeFileSync as writeFileSync10
@@ -22606,7 +22756,7 @@ import {
22606
22756
  import { dirname as dirname11, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
22607
22757
  function migrateConventionPolicies() {
22608
22758
  const from = legacy.customPoliciesDir();
22609
- if (!existsSync23(from))
22759
+ if (!existsSync24(from))
22610
22760
  return [];
22611
22761
  const moved = [];
22612
22762
  const mergeInto = (dir, dest, prefix) => {
@@ -22627,9 +22777,9 @@ function migrateConventionPolicies() {
22627
22777
  const source = resolve19(dir, entry.name);
22628
22778
  const target = resolve19(dest, entry.name);
22629
22779
  const name = `${prefix}${entry.name}`;
22630
- if (!existsSync23(target)) {
22780
+ if (!existsSync24(target)) {
22631
22781
  try {
22632
- renameSync6(source, target);
22782
+ renameSync7(source, target);
22633
22783
  moved.push(name);
22634
22784
  } catch {}
22635
22785
  continue;
@@ -22654,7 +22804,7 @@ function migrateLegacySpool() {
22654
22804
  [legacy.spoolDir(), spoolDir()],
22655
22805
  [legacy.failedDir(), failedDir()]
22656
22806
  ]) {
22657
- if (!existsSync23(from))
22807
+ if (!existsSync24(from))
22658
22808
  continue;
22659
22809
  try {
22660
22810
  mkdirSync12(to, { recursive: true });
@@ -22663,10 +22813,10 @@ function migrateLegacySpool() {
22663
22813
  continue;
22664
22814
  let name = entry.name;
22665
22815
  let n = 0;
22666
- while (existsSync23(resolve19(to, name)))
22816
+ while (existsSync24(resolve19(to, name)))
22667
22817
  name = `legacy-${n++}-${entry.name}`;
22668
22818
  try {
22669
- renameSync6(resolve19(from, entry.name), resolve19(to, name));
22819
+ renameSync7(resolve19(from, entry.name), resolve19(to, name));
22670
22820
  moved.push(name);
22671
22821
  } catch {
22672
22822
  try {
@@ -22681,7 +22831,7 @@ function migrateLegacySpool() {
22681
22831
  }
22682
22832
  function migrateHookActivity() {
22683
22833
  const from = legacy.hookActivityDir();
22684
- if (!existsSync23(from))
22834
+ if (!existsSync24(from))
22685
22835
  return [];
22686
22836
  const moved = [];
22687
22837
  try {
@@ -22696,12 +22846,12 @@ function migrateHookActivity() {
22696
22846
  const source = resolve19(from, entry.name);
22697
22847
  let name = entry.name === "current.jsonl" ? `page-${stamp}-${seq++}.jsonl` : entry.name;
22698
22848
  let target = resolve19(to, name);
22699
- while (existsSync23(target)) {
22849
+ while (existsSync24(target)) {
22700
22850
  name = `page-${stamp}-${seq++}.jsonl`;
22701
22851
  target = resolve19(to, name);
22702
22852
  }
22703
22853
  try {
22704
- renameSync6(source, target);
22854
+ renameSync7(source, target);
22705
22855
  moved.push(name);
22706
22856
  } catch {
22707
22857
  try {
@@ -22736,7 +22886,7 @@ function retirePolicyConfigKeys() {
22736
22886
  delete parsed[key];
22737
22887
  try {
22738
22888
  if (Object.keys(parsed).length === 0)
22739
- rmSync7(at, { force: true });
22889
+ rmSync8(at, { force: true });
22740
22890
  else
22741
22891
  writeFileSync10(at, JSON.stringify(parsed, null, 2) + `
22742
22892
  `, "utf8");
@@ -22747,7 +22897,7 @@ function retirePolicyConfigKeys() {
22747
22897
  }
22748
22898
  function readCarriedPolicyConfig() {
22749
22899
  const from = resolve19(legacy.localPoliciesDir(), "policies-config.json");
22750
- if (!existsSync23(from))
22900
+ if (!existsSync24(from))
22751
22901
  return null;
22752
22902
  let parsed;
22753
22903
  try {
@@ -22811,7 +22961,7 @@ function writeCarriedPolicyConfig(carried) {
22811
22961
  }
22812
22962
  function readCarriedTelemetryOptOut() {
22813
22963
  const from = legacy.configToml();
22814
- if (!existsSync23(from))
22964
+ if (!existsSync24(from))
22815
22965
  return false;
22816
22966
  try {
22817
22967
  const text = readFileSync18(from, "utf8");
@@ -22866,7 +23016,7 @@ function parseLegacyToml(text) {
22866
23016
  }
22867
23017
  function readCarriedLegacyConfig() {
22868
23018
  const from = legacy.configToml();
22869
- if (!existsSync23(from))
23019
+ if (!existsSync24(from))
22870
23020
  return null;
22871
23021
  try {
22872
23022
  return projectConfig(parseLegacyToml(readFileSync18(from, "utf8")));
@@ -22876,7 +23026,7 @@ function readCarriedLegacyConfig() {
22876
23026
  }
22877
23027
  function readCarriedLegacyCredentials() {
22878
23028
  const toml = legacy.credentialsToml();
22879
- if (existsSync23(toml)) {
23029
+ if (existsSync24(toml)) {
22880
23030
  try {
22881
23031
  const creds = projectCredentials(parseLegacyToml(readFileSync18(toml, "utf8")));
22882
23032
  if (Object.keys(creds).length > 0)
@@ -22919,10 +23069,10 @@ function resetHome(from, to = LAYOUT_VERSION) {
22919
23069
  const spooled = migrateLegacySpool();
22920
23070
  const removed = [];
22921
23071
  for (const path of resettablePaths()) {
22922
- if (!existsSync23(path))
23072
+ if (!existsSync24(path))
22923
23073
  continue;
22924
23074
  try {
22925
- rmSync7(path, { recursive: true, force: true });
23075
+ rmSync8(path, { recursive: true, force: true });
22926
23076
  removed.push(path);
22927
23077
  } catch {}
22928
23078
  }
@@ -22944,7 +23094,7 @@ function layoutWarningForHook() {
22944
23094
  if (state.kind === "future") {
22945
23095
  return `[failproofai] this directory was written by a newer version (layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
22946
23096
  }
22947
- if (existsSync23(globalPolicyConfigFile()))
23097
+ if (existsSync24(globalPolicyConfigFile()))
22948
23098
  return null;
22949
23099
  return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
22950
23100
  }
@@ -23293,7 +23443,20 @@ async function evaluateHookEvent(eventType, cli = "claude", stdinPayload, opts)
23293
23443
  }
23294
23444
  } catch {}
23295
23445
  }
23296
- return { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr };
23446
+ return {
23447
+ exitCode: result.exitCode,
23448
+ stdout: result.stdout,
23449
+ stderr: result.stderr,
23450
+ evaluation: {
23451
+ decision: result.decision,
23452
+ policyName: result.policyName,
23453
+ policyNames: result.policyNames ?? (result.policyName ? [result.policyName] : []),
23454
+ reason: result.reason,
23455
+ matchedPolicies,
23456
+ durationMs,
23457
+ toolName: parsed.tool_name ?? null
23458
+ }
23459
+ };
23297
23460
  } finally {
23298
23461
  if (opts?.awaitTelemetryFlush ?? true) {
23299
23462
  await flushHookTelemetry2();
@@ -23992,14 +24155,14 @@ var init_collector_config = __esm(() => {
23992
24155
  });
23993
24156
 
23994
24157
  // src/hooks/flush-cli.ts
23995
- import { existsSync as existsSync24, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, readdirSync as readdirSync16 } from "node:fs";
24158
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, readdirSync as readdirSync16 } from "node:fs";
23996
24159
  import { dirname as dirname12, join as join31 } from "node:path";
23997
24160
  function flushRequestPath(home) {
23998
24161
  return join31(failproofaiHome(home), "state", "flush-request.json");
23999
24162
  }
24000
24163
  function spoolDirs(home) {
24001
24164
  const root = spoolDir(home);
24002
- if (!existsSync24(root))
24165
+ if (!existsSync25(root))
24003
24166
  return [];
24004
24167
  try {
24005
24168
  return readdirSync16(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join31(root, e.name));
@@ -24103,11 +24266,11 @@ var init_flush_cli = __esm(() => {
24103
24266
  import {
24104
24267
  chmodSync as chmodSync4,
24105
24268
  copyFileSync as copyFileSync2,
24106
- existsSync as existsSync25,
24269
+ existsSync as existsSync26,
24107
24270
  mkdirSync as mkdirSync14,
24108
24271
  readFileSync as readFileSync19,
24109
- renameSync as renameSync7,
24110
- rmSync as rmSync8,
24272
+ renameSync as renameSync8,
24273
+ rmSync as rmSync9,
24111
24274
  writeFileSync as writeFileSync12
24112
24275
  } from "node:fs";
24113
24276
  import { basename as basename5, dirname as dirname13, join as join32, resolve as resolve20 } from "node:path";
@@ -24126,30 +24289,30 @@ function migrateToLayout4() {
24126
24289
  }
24127
24290
  const migrated = [];
24128
24291
  for (const { from, to } of moves) {
24129
- if (!existsSync25(from))
24292
+ if (!existsSync26(from))
24130
24293
  continue;
24131
- if (existsSync25(to)) {
24132
- rmSync8(from, { force: true });
24294
+ if (existsSync26(to)) {
24295
+ rmSync9(from, { force: true });
24133
24296
  continue;
24134
24297
  }
24135
24298
  mkdirSync14(dirname13(to), { recursive: true });
24136
24299
  try {
24137
- renameSync7(from, to);
24300
+ renameSync8(from, to);
24138
24301
  } catch {
24139
24302
  try {
24140
24303
  copyFileSync2(from, to);
24141
24304
  } catch (err) {
24142
24305
  try {
24143
- rmSync8(to, { force: true });
24306
+ rmSync9(to, { force: true });
24144
24307
  } catch {}
24145
24308
  throw err;
24146
24309
  }
24147
- rmSync8(from, { force: true });
24310
+ rmSync9(from, { force: true });
24148
24311
  }
24149
24312
  migrated.push(`${basename5(from)} → audit/${basename5(to)}`);
24150
24313
  }
24151
24314
  for (const secret of [auditSessionFile()]) {
24152
- if (!existsSync25(secret))
24315
+ if (!existsSync26(secret))
24153
24316
  continue;
24154
24317
  try {
24155
24318
  chmodSync4(secret, 384);
@@ -24197,12 +24360,12 @@ function pruneMigratedCredentials(from) {
24197
24360
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
24198
24361
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS) {
24199
24362
  try {
24200
- if (!existsSync25(landsAt()))
24363
+ if (!existsSync26(landsAt()))
24201
24364
  continue;
24202
24365
  const copy = resolve20(migrationBackupDir(layout), as);
24203
- if (!existsSync25(copy))
24366
+ if (!existsSync26(copy))
24204
24367
  continue;
24205
- rmSync8(copy, { force: true });
24368
+ rmSync9(copy, { force: true });
24206
24369
  pruned.push(as);
24207
24370
  } catch {}
24208
24371
  }
@@ -24213,7 +24376,7 @@ function filesToBackUp() {
24213
24376
  const seen = new Map;
24214
24377
  for (const f of [...BACKED_UP, ...BACKED_UP_LEGACY]) {
24215
24378
  const path = f.at();
24216
- if (existsSync25(path))
24379
+ if (existsSync26(path))
24217
24380
  seen.set(path, backupNameOf(f));
24218
24381
  }
24219
24382
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -24222,7 +24385,7 @@ function backupBeforeMigrating(from) {
24222
24385
  const dir = migrationBackupDir(from);
24223
24386
  const saved = [];
24224
24387
  try {
24225
- rmSync8(dir, { recursive: true, force: true });
24388
+ rmSync9(dir, { recursive: true, force: true });
24226
24389
  mkdirSync14(dir, { recursive: true });
24227
24390
  } catch {
24228
24391
  return [];
@@ -24603,7 +24766,7 @@ var NAMESPACE3 = "failproofai-telemetry-v1", API_KEY3 = "phc_Ac1Ww1GqKc0z1SyrRWb
24603
24766
  var init_install_telemetry = () => {};
24604
24767
 
24605
24768
  // lib/install-check.ts
24606
- import { existsSync as existsSync26, readFileSync as readFileSync21, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
24769
+ import { existsSync as existsSync27, readFileSync as readFileSync21, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
24607
24770
  import { dirname as dirname14, resolve as resolve21 } from "node:path";
24608
24771
  import { platform as platform2, arch as arch2, release, homedir as homedir24, hostname as hostname2 } from "node:os";
24609
24772
  import { createHmac as createHmac2 } from "node:crypto";
@@ -24659,7 +24822,7 @@ function compareSemver(a, b) {
24659
24822
  }
24660
24823
  function checkHooks() {
24661
24824
  const hooksConfigPath = globalPolicyConfigFile();
24662
- if (!existsSync26(hooksConfigPath)) {
24825
+ if (!existsSync27(hooksConfigPath)) {
24663
24826
  return { configured: false, registered: false, policyCount: 0 };
24664
24827
  }
24665
24828
  let config;
@@ -24673,7 +24836,7 @@ function checkHooks() {
24673
24836
  }
24674
24837
  const policyCount = config.enabledPolicies.length;
24675
24838
  const settingsPath = resolve21(homedir24(), ".claude", "settings.json");
24676
- if (!existsSync26(settingsPath))
24839
+ if (!existsSync27(settingsPath))
24677
24840
  return { configured: true, registered: false, policyCount };
24678
24841
  let settings;
24679
24842
  try {
@@ -24701,7 +24864,7 @@ async function maybeReportInstall(version) {
24701
24864
  const versionFile = lastVersionPath();
24702
24865
  let previousVersion = null;
24703
24866
  try {
24704
- if (existsSync26(versionFile)) {
24867
+ if (existsSync27(versionFile)) {
24705
24868
  previousVersion = readFileSync21(versionFile, "utf8").trim() || null;
24706
24869
  }
24707
24870
  } catch {}
@@ -24789,7 +24952,7 @@ var init_cli_error = __esm(() => {
24789
24952
 
24790
24953
  // src/hooks/manager.ts
24791
24954
  import { execSync as execSync6 } from "node:child_process";
24792
- import { existsSync as existsSync27 } from "node:fs";
24955
+ import { existsSync as existsSync28 } from "node:fs";
24793
24956
  import { resolve as resolve22, basename as basename6 } from "node:path";
24794
24957
  import { platform as platform3, arch as arch3, release as release2, hostname as hostname3 } from "node:os";
24795
24958
  function getSettingsPath(scope, cwd) {
@@ -24976,8 +25139,11 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
24976
25139
  }
24977
25140
  }
24978
25141
  const selectedClis = cli && cli.length > 0 ? [...new Set(cli)] : ["claude"];
24979
- for (const cliId of selectedClis) {
24980
- const integration = getIntegration(cliId);
25142
+ const selectedIntegrations = selectedClis.map((cliId) => ({
25143
+ cliId,
25144
+ integration: getIntegration(cliId)
25145
+ }));
25146
+ for (const { cliId, integration } of selectedIntegrations) {
24981
25147
  if (!integration.scopes.includes(scope)) {
24982
25148
  try {
24983
25149
  await trackHookEvent2(getInstanceId2(), "scope_validation_failed", {
@@ -24989,6 +25155,13 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
24989
25155
  throw new CliError(`Scope "${scope}" is not supported by ${integration.displayName}. ` + `Valid scopes: ${integration.scopes.join(", ")}`);
24990
25156
  }
24991
25157
  }
25158
+ const daemonRequiredBy = selectedIntegrations.map(({ integration }) => integration).filter((integration) => integration.requiresHealthyDaemon);
25159
+ if (daemonRequiredBy.length > 0 && !await probeDaemonEndToEnd()) {
25160
+ const names = daemonRequiredBy.map((integration) => integration.displayName).join(", ");
25161
+ const verb = daemonRequiredBy.length === 1 ? "requires" : "require";
25162
+ throw new CliError(`${names} ${verb} a healthy failproofaid daemon before FailproofAI enforcement can be enabled.
25163
+ ` + "Run `failproofai config` to install and configure the daemon, then retry.");
25164
+ }
24992
25165
  const binaryPath = resolveFailproofaiBinary();
24993
25166
  const previousConfig = readScopedHooksConfig(scope, cwd);
24994
25167
  const previousEnabled = new Set(previousConfig.enabledPolicies);
@@ -25011,7 +25184,7 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
25011
25184
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
25012
25185
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve22(path));
25013
25186
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve22(path)).filter((path) => {
25014
- if (existsSync27(path))
25187
+ if (existsSync28(path))
25015
25188
  return true;
25016
25189
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
25017
25190
  return false;
@@ -25087,6 +25260,7 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
25087
25260
  const settingsPaths = settingsPathsFor(integration, scope, cwd);
25088
25261
  try {
25089
25262
  for (const settingsPath of settingsPaths) {
25263
+ integration.prepareInstall?.(settingsPath);
25090
25264
  const settings = integration.readSettings(settingsPath);
25091
25265
  integration.writeHookEntries(settings, binaryPath, scope);
25092
25266
  integration.writeSettings(settingsPath, settings);
@@ -25143,7 +25317,11 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
25143
25317
  } catch {}
25144
25318
  for (const { cli: cliId, path } of writtenSettingsPaths) {
25145
25319
  const integration = getIntegration(cliId);
25146
- console.log(`Failproof AI hooks installed for ${integration.displayName} ` + `(${integration.eventTypes.length} event types, scope: ${scope}).`);
25320
+ if (cliId === "hermes") {
25321
+ console.log(`Failproof AI native plugin installed for ${integration.displayName} ` + `(8 registered hooks, scope: ${scope}).`);
25322
+ } else {
25323
+ console.log(`Failproof AI hooks installed for ${integration.displayName} ` + `(${integration.eventTypes.length} event types, scope: ${scope}).`);
25324
+ }
25147
25325
  console.log(`Settings: ${path}`);
25148
25326
  }
25149
25327
  if (scope === "project") {
@@ -25234,7 +25412,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
25234
25412
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
25235
25413
  for (const s of scopesToRemove) {
25236
25414
  const settingsPaths = settingsPathsFor(integration, s, cwd);
25237
- const existing = settingsPaths.filter((p) => existsSync27(p));
25415
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync28(p));
25238
25416
  if (existing.length === 0) {
25239
25417
  if (scope !== "all" && selectedClis.length === 1) {
25240
25418
  console.log("No settings file found. Nothing to remove.");
@@ -25317,6 +25495,7 @@ var init_manager = __esm(() => {
25317
25495
  init_pack_store();
25318
25496
  init_pack_manifest();
25319
25497
  init_policy_evaluator();
25498
+ init_daemon_service();
25320
25499
  init_tui();
25321
25500
  VALID_POLICY_NAMES = new Set(BUILTIN_POLICIES.map((p) => p.name));
25322
25501
  });
@@ -25337,7 +25516,7 @@ var DEFAULT_FETCH_TIMEOUT_MS = 15000;
25337
25516
 
25338
25517
  // src/hooks/cloud-enrollment.ts
25339
25518
  import { randomUUID as randomUUID3 } from "node:crypto";
25340
- import { existsSync as existsSync28, readFileSync as readFileSync22, rmSync as rmSync9 } from "node:fs";
25519
+ import { existsSync as existsSync29, readFileSync as readFileSync22, rmSync as rmSync10 } from "node:fs";
25341
25520
  import { hostname as hostname4 } from "node:os";
25342
25521
  function cloudCredentialPath() {
25343
25522
  return process.env.FAILPROOFAI_CLOUD_CREDENTIALS ?? credentialsFile();
@@ -25376,7 +25555,7 @@ function readCloudCredentials() {
25376
25555
  if (!usingJsonOverride())
25377
25556
  return readCredentials().cloud ?? null;
25378
25557
  const path = cloudCredentialPath();
25379
- if (!existsSync28(path))
25558
+ if (!existsSync29(path))
25380
25559
  return null;
25381
25560
  try {
25382
25561
  const raw = JSON.parse(readFileSync22(path, "utf8"));
@@ -25418,10 +25597,10 @@ function resolveMachineLabel(explicit) {
25418
25597
  function clearCloudCredentials() {
25419
25598
  if (usingJsonOverride()) {
25420
25599
  const path = cloudCredentialPath();
25421
- if (!existsSync28(path))
25600
+ if (!existsSync29(path))
25422
25601
  return false;
25423
25602
  try {
25424
- rmSync9(path);
25603
+ rmSync10(path);
25425
25604
  return true;
25426
25605
  } catch {
25427
25606
  return false;
@@ -25669,7 +25848,7 @@ var init_cloud_connection = __esm(() => {
25669
25848
  });
25670
25849
 
25671
25850
  // src/hooks/setup-state.ts
25672
- import { existsSync as existsSync29, realpathSync as realpathSync2, statSync as statSync18 } from "node:fs";
25851
+ import { existsSync as existsSync30, realpathSync as realpathSync2, statSync as statSync18 } from "node:fs";
25673
25852
  import { dirname as dirname15, resolve as resolve23 } from "node:path";
25674
25853
  import { homedir as homedir25 } from "node:os";
25675
25854
  function globalConfigPath(home = homedir25()) {
@@ -25726,10 +25905,10 @@ function detectSetupState(cwd = process.cwd(), home = homedir25()) {
25726
25905
  cwd: resolvedCwd,
25727
25906
  home: resolvedHome,
25728
25907
  projectRoot,
25729
- hasGlobalConfig: existsSync29(globalConfigPath(resolvedHome)),
25730
- hasProjectConfig: projectRoot !== resolvedHome && existsSync29(projectConfigPath(projectRoot)),
25908
+ hasGlobalConfig: existsSync30(globalConfigPath(resolvedHome)),
25909
+ hasProjectConfig: projectRoot !== resolvedHome && existsSync30(projectConfigPath(projectRoot)),
25731
25910
  hasGlobalHooks: hasGlobalHooksInstalled(),
25732
- hasLegacyMarker: existsSync29(legacyMarkerPath(resolvedHome)),
25911
+ hasLegacyMarker: existsSync30(legacyMarkerPath(resolvedHome)),
25733
25912
  inHomeDir: resolvedCwd === resolvedHome
25734
25913
  };
25735
25914
  }
@@ -25746,11 +25925,11 @@ var init_setup_state = __esm(() => {
25746
25925
  });
25747
25926
 
25748
25927
  // src/hooks/onboarding-attempt.ts
25749
- import { existsSync as existsSync30, mkdirSync as mkdirSync17, readFileSync as readFileSync23, rmSync as rmSync10, writeFileSync as writeFileSync15 } from "node:fs";
25928
+ import { existsSync as existsSync31, mkdirSync as mkdirSync17, readFileSync as readFileSync23, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
25750
25929
  import { dirname as dirname16 } from "node:path";
25751
25930
  function readOnboardingAttempt() {
25752
25931
  const path = onboardingAttemptFile();
25753
- if (!existsSync30(path))
25932
+ if (!existsSync31(path))
25754
25933
  return null;
25755
25934
  try {
25756
25935
  const raw = JSON.parse(readFileSync23(path, "utf8"));
@@ -25785,7 +25964,7 @@ function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.no
25785
25964
  }
25786
25965
  function clearOnboardingAttempt() {
25787
25966
  try {
25788
- rmSync10(onboardingAttemptFile(), { force: true });
25967
+ rmSync11(onboardingAttemptFile(), { force: true });
25789
25968
  } catch {}
25790
25969
  }
25791
25970
  function blockerCleared(attempt, probe) {
@@ -25827,7 +26006,7 @@ var init_onboarding_attempt = __esm(() => {
25827
26006
  });
25828
26007
 
25829
26008
  // src/hooks/onboarding-lock.ts
25830
- import { mkdirSync as mkdirSync18, readFileSync as readFileSync24, rmSync as rmSync11, writeFileSync as writeFileSync16 } from "node:fs";
26009
+ import { mkdirSync as mkdirSync18, readFileSync as readFileSync24, rmSync as rmSync12, writeFileSync as writeFileSync16 } from "node:fs";
25831
26010
  import { homedir as homedir26 } from "node:os";
25832
26011
  function onboardingLockPath(home = homedir26()) {
25833
26012
  return onboardingLockFile(home);
@@ -25870,7 +26049,7 @@ function acquireOnboardingLock(home = homedir26()) {
25870
26049
  try {
25871
26050
  const current = readLock(path);
25872
26051
  if (!current || current.pid === process.pid)
25873
- rmSync11(path, { force: true });
26052
+ rmSync12(path, { force: true });
25874
26053
  } catch {}
25875
26054
  }
25876
26055
  };
@@ -25883,7 +26062,7 @@ var init_onboarding_lock = __esm(() => {
25883
26062
  });
25884
26063
 
25885
26064
  // lib/claude-sessions.ts
25886
- import { readdirSync as readdirSync17, statSync as statSync19, existsSync as existsSync31 } from "node:fs";
26065
+ import { readdirSync as readdirSync17, statSync as statSync19, existsSync as existsSync32 } from "node:fs";
25887
26066
  import { join as join34, basename as basename7 } from "node:path";
25888
26067
  function getClaudeProjectsRoot() {
25889
26068
  return getClaudeProjectsPath();
@@ -25930,7 +26109,7 @@ function listClaudeTranscripts(project) {
25930
26109
  } catch {}
25931
26110
  } else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
25932
26111
  const subDir = join34(project.path, entry.name, "subagents");
25933
- if (!existsSync31(subDir))
26112
+ if (!existsSync32(subDir))
25934
26113
  continue;
25935
26114
  let subEntries;
25936
26115
  try {
@@ -27273,7 +27452,7 @@ var init_features = __esm(() => {
27273
27452
 
27274
27453
  // src/audit/cache.ts
27275
27454
  import { createHash as createHash8 } from "node:crypto";
27276
- import { existsSync as existsSync32, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync17, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27455
+ import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync17, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27277
27456
  import { join as join35 } from "node:path";
27278
27457
  function getEngineVersion() {
27279
27458
  if (cachedEngineVersion)
@@ -27334,7 +27513,7 @@ function readCachedTranscript(transcriptPath, mtimeMs, sizeBytes) {
27334
27513
  if (sizeBytes === 0)
27335
27514
  return null;
27336
27515
  const cachePath = getCachePathFor(transcriptPath);
27337
- if (!existsSync32(cachePath))
27516
+ if (!existsSync33(cachePath))
27338
27517
  return null;
27339
27518
  try {
27340
27519
  const raw = readFileSync25(cachePath, "utf-8");
@@ -27954,7 +28133,7 @@ var init_audit_lock = __esm(() => {
27954
28133
  });
27955
28134
 
27956
28135
  // src/audit/dashboard-cache.ts
27957
- import { existsSync as existsSync33, readFileSync as readFileSync27 } from "node:fs";
28136
+ import { existsSync as existsSync34, readFileSync as readFileSync27 } from "node:fs";
27958
28137
  function getCachePath() {
27959
28138
  return auditDashboardFile();
27960
28139
  }
@@ -27974,7 +28153,7 @@ function writeDashboardCache(params, result) {
27974
28153
  }
27975
28154
  function readDashboardCacheMeta() {
27976
28155
  const cachePath = getCachePath();
27977
- if (!existsSync33(cachePath))
28156
+ if (!existsSync34(cachePath))
27978
28157
  return null;
27979
28158
  try {
27980
28159
  const raw = readFileSync27(cachePath, "utf-8");
@@ -28201,7 +28380,7 @@ var init_api_server_client = __esm(() => {
28201
28380
  });
28202
28381
 
28203
28382
  // lib/auth/auth-store.ts
28204
- import { existsSync as existsSync34, readFileSync as readFileSync28, readdirSync as readdirSync18, rmSync as rmSync12 } from "node:fs";
28383
+ import { existsSync as existsSync35, readFileSync as readFileSync28, readdirSync as readdirSync18, rmSync as rmSync13 } from "node:fs";
28205
28384
  import { join as join36, resolve as resolve24 } from "node:path";
28206
28385
  function getAuthFilePath() {
28207
28386
  const override = process.env.FAILPROOFAI_AUTH_DIR;
@@ -28209,7 +28388,7 @@ function getAuthFilePath() {
28209
28388
  }
28210
28389
  function readAuth() {
28211
28390
  const p = getAuthFilePath();
28212
- if (!existsSync34(p))
28391
+ if (!existsSync35(p))
28213
28392
  return null;
28214
28393
  try {
28215
28394
  const raw = readFileSync28(p, "utf-8");
@@ -28236,18 +28415,18 @@ function writeAuth(auth) {
28236
28415
  }
28237
28416
  function deleteAuth() {
28238
28417
  const p = getAuthFilePath();
28239
- if (existsSync34(p))
28240
- rmSync12(p, { force: true });
28418
+ if (existsSync35(p))
28419
+ rmSync13(p, { force: true });
28241
28420
  try {
28242
28421
  const root = migrationsDir();
28243
- if (!existsSync34(root))
28422
+ if (!existsSync35(root))
28244
28423
  return;
28245
28424
  for (const entry of readdirSync18(root)) {
28246
28425
  if (!entry.startsWith("backup-layout"))
28247
28426
  continue;
28248
28427
  const copy = resolve24(root, entry, "auth.json");
28249
- if (existsSync34(copy))
28250
- rmSync12(copy, { force: true });
28428
+ if (existsSync35(copy))
28429
+ rmSync13(copy, { force: true });
28251
28430
  }
28252
28431
  } catch {}
28253
28432
  }
@@ -28497,12 +28676,12 @@ var init_harm_report = __esm(() => {
28497
28676
  });
28498
28677
 
28499
28678
  // src/audit/machine-store.ts
28500
- import { existsSync as existsSync35, readFileSync as readFileSync29, rmSync as rmSync13 } from "node:fs";
28679
+ import { existsSync as existsSync36, readFileSync as readFileSync29, rmSync as rmSync14 } from "node:fs";
28501
28680
  import { hostname as hostname5 } from "node:os";
28502
28681
  import { randomUUID as randomUUID4 } from "node:crypto";
28503
28682
  function readMachineIdentity(home) {
28504
28683
  const path = auditMachineFile(home);
28505
- if (!existsSync35(path))
28684
+ if (!existsSync36(path))
28506
28685
  return null;
28507
28686
  try {
28508
28687
  const parsed = JSON.parse(readFileSync29(path, "utf8"));
@@ -28827,7 +29006,7 @@ var init_cli = __esm(() => {
28827
29006
  });
28828
29007
 
28829
29008
  // src/hooks/configure-wizard.ts
28830
- import { existsSync as existsSync36, mkdirSync as mkdirSync21, writeFileSync as writeFileSync19, readFileSync as readFileSync30 } from "node:fs";
29009
+ import { existsSync as existsSync37, mkdirSync as mkdirSync21, writeFileSync as writeFileSync19, readFileSync as readFileSync30 } from "node:fs";
28831
29010
  import { homedir as homedir28 } from "node:os";
28832
29011
  import { dirname as dirname17, resolve as resolve25, sep as sep5 } from "node:path";
28833
29012
  async function emit(event, props) {
@@ -28852,7 +29031,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
28852
29031
  const path = getConfigPathForScope(scope, cwd);
28853
29032
  let config = {};
28854
29033
  try {
28855
- if (existsSync36(path))
29034
+ if (existsSync37(path))
28856
29035
  config = JSON.parse(readFileSync30(path, "utf8"));
28857
29036
  } catch {
28858
29037
  return;
@@ -29489,14 +29668,14 @@ var init_configure_wizard = __esm(() => {
29489
29668
  });
29490
29669
 
29491
29670
  // src/hooks/flush-cli.ts
29492
- import { existsSync as existsSync37, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readdirSync as readdirSync19 } from "node:fs";
29671
+ import { existsSync as existsSync38, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readdirSync as readdirSync19 } from "node:fs";
29493
29672
  import { dirname as dirname18, join as join37 } from "node:path";
29494
29673
  function flushRequestPath2(home) {
29495
29674
  return join37(failproofaiHome(home), "state", "flush-request.json");
29496
29675
  }
29497
29676
  function spoolDirs2(home) {
29498
29677
  const root = spoolDir(home);
29499
- if (!existsSync37(root))
29678
+ if (!existsSync38(root))
29500
29679
  return [];
29501
29680
  try {
29502
29681
  return readdirSync19(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join37(root, e.name));
@@ -29597,7 +29776,7 @@ var init_flush_cli2 = __esm(() => {
29597
29776
  });
29598
29777
 
29599
29778
  // src/hooks/backfill-cli.ts
29600
- import { existsSync as existsSync38, mkdirSync as mkdirSync23, writeFileSync as writeFileSync21, readdirSync as readdirSync20, statSync as statSync24 } from "node:fs";
29779
+ import { existsSync as existsSync39, mkdirSync as mkdirSync23, writeFileSync as writeFileSync21, readdirSync as readdirSync20, statSync as statSync24 } from "node:fs";
29601
29780
  import { dirname as dirname19, join as join38 } from "node:path";
29602
29781
  function backfillRequestPath(home) {
29603
29782
  return join38(failproofaiHome(home), "state", "backfill-request.json");
@@ -29606,7 +29785,7 @@ function surveySessions(sinceMs, homeDir) {
29606
29785
  const out = [];
29607
29786
  for (const { cli, dir } of SESSION_DIRS) {
29608
29787
  const root = join38(homeDir, dir);
29609
- if (!existsSync38(root))
29788
+ if (!existsSync39(root))
29610
29789
  continue;
29611
29790
  let files = 0;
29612
29791
  let newest = 0;
@@ -29644,7 +29823,7 @@ function runBackfillCommand(opts = {}) {
29644
29823
  const now = opts.now ?? Date.now();
29645
29824
  const sinceMs = opts.sinceMs ?? now - DEFAULT_BACKFILL_DAYS * 24 * 60 * 60 * 1000;
29646
29825
  const home = failproofaiHome();
29647
- if (!existsSync38(home)) {
29826
+ if (!existsSync39(home)) {
29648
29827
  return {
29649
29828
  exitCode: 1,
29650
29829
  lines: [`No failproofai home at ${home}. Run \`failproofai config\` first.`]
@@ -29975,7 +30154,7 @@ var init_harness_cli = __esm(() => {
29975
30154
  });
29976
30155
 
29977
30156
  // src/hooks/fp-config.ts
29978
- import { chmodSync as chmodSync6, existsSync as existsSync39, mkdirSync as mkdirSync24, readFileSync as readFileSync31, statSync as statSync25, writeFileSync as writeFileSync22 } from "node:fs";
30157
+ import { chmodSync as chmodSync6, existsSync as existsSync40, mkdirSync as mkdirSync24, readFileSync as readFileSync31, statSync as statSync25, writeFileSync as writeFileSync22 } from "node:fs";
29979
30158
  function detectLayout2() {
29980
30159
  const raw = readVersionFile2();
29981
30160
  if (raw) {
@@ -29983,17 +30162,17 @@ function detectLayout2() {
29983
30162
  return { kind: "current", version: raw };
29984
30163
  return raw.layout > LAYOUT_VERSION ? { kind: "future", found: raw.layout } : { kind: "stale", found: raw.layout };
29985
30164
  }
29986
- if (existsSync39(configFile())) {
30165
+ if (existsSync40(configFile())) {
29987
30166
  const layoutThreePositions = [
29988
30167
  legacy.authJson(),
29989
30168
  legacy.nextAudit(),
29990
30169
  legacy.auditSchedule()
29991
30170
  ];
29992
- if (layoutThreePositions.some((p) => existsSync39(p)))
30171
+ if (layoutThreePositions.some((p) => existsSync40(p)))
29993
30172
  return { kind: "stale", found: 3 };
29994
30173
  return { kind: "current", version: { layout: LAYOUT_VERSION, cli: "" }, inferred: true };
29995
30174
  }
29996
- if (existsSync39(legacy.configToml()))
30175
+ if (existsSync40(legacy.configToml()))
29997
30176
  return { kind: "stale", found: 2 };
29998
30177
  const layoutOneMarkers = [
29999
30178
  legacy.policyConfig(),
@@ -30004,7 +30183,7 @@ function detectLayout2() {
30004
30183
  legacy.ingestCredentials(),
30005
30184
  legacy.auditDashboard()
30006
30185
  ];
30007
- return layoutOneMarkers.some((p) => existsSync39(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
30186
+ return layoutOneMarkers.some((p) => existsSync40(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
30008
30187
  }
30009
30188
  function readLegacyTomlVersion2(text) {
30010
30189
  const layout = Number(/^\s*layout\s*=\s*(\d+)\s*$/m.exec(text)?.[1]);
@@ -30047,11 +30226,11 @@ var init_fp_home2 = () => {};
30047
30226
  import {
30048
30227
  chmodSync as chmodSync7,
30049
30228
  copyFileSync as copyFileSync3,
30050
- existsSync as existsSync40,
30229
+ existsSync as existsSync41,
30051
30230
  mkdirSync as mkdirSync25,
30052
30231
  readFileSync as readFileSync32,
30053
- renameSync as renameSync8,
30054
- rmSync as rmSync14,
30232
+ renameSync as renameSync9,
30233
+ rmSync as rmSync15,
30055
30234
  writeFileSync as writeFileSync23
30056
30235
  } from "node:fs";
30057
30236
  import { basename as basename8, dirname as dirname20, join as join39, resolve as resolve27 } from "node:path";
@@ -30070,30 +30249,30 @@ function migrateToLayout42() {
30070
30249
  }
30071
30250
  const migrated = [];
30072
30251
  for (const { from, to } of moves) {
30073
- if (!existsSync40(from))
30252
+ if (!existsSync41(from))
30074
30253
  continue;
30075
- if (existsSync40(to)) {
30076
- rmSync14(from, { force: true });
30254
+ if (existsSync41(to)) {
30255
+ rmSync15(from, { force: true });
30077
30256
  continue;
30078
30257
  }
30079
30258
  mkdirSync25(dirname20(to), { recursive: true });
30080
30259
  try {
30081
- renameSync8(from, to);
30260
+ renameSync9(from, to);
30082
30261
  } catch {
30083
30262
  try {
30084
30263
  copyFileSync3(from, to);
30085
30264
  } catch (err) {
30086
30265
  try {
30087
- rmSync14(to, { force: true });
30266
+ rmSync15(to, { force: true });
30088
30267
  } catch {}
30089
30268
  throw err;
30090
30269
  }
30091
- rmSync14(from, { force: true });
30270
+ rmSync15(from, { force: true });
30092
30271
  }
30093
30272
  migrated.push(`${basename8(from)} → audit/${basename8(to)}`);
30094
30273
  }
30095
30274
  for (const secret of [auditSessionFile()]) {
30096
- if (!existsSync40(secret))
30275
+ if (!existsSync41(secret))
30097
30276
  continue;
30098
30277
  try {
30099
30278
  chmodSync7(secret, 384);
@@ -30141,12 +30320,12 @@ function pruneMigratedCredentials2(from) {
30141
30320
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
30142
30321
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS2) {
30143
30322
  try {
30144
- if (!existsSync40(landsAt()))
30323
+ if (!existsSync41(landsAt()))
30145
30324
  continue;
30146
30325
  const copy = resolve27(migrationBackupDir(layout), as);
30147
- if (!existsSync40(copy))
30326
+ if (!existsSync41(copy))
30148
30327
  continue;
30149
- rmSync14(copy, { force: true });
30328
+ rmSync15(copy, { force: true });
30150
30329
  pruned.push(as);
30151
30330
  } catch {}
30152
30331
  }
@@ -30157,7 +30336,7 @@ function filesToBackUp2() {
30157
30336
  const seen = new Map;
30158
30337
  for (const f of [...BACKED_UP2, ...BACKED_UP_LEGACY2]) {
30159
30338
  const path = f.at();
30160
- if (existsSync40(path))
30339
+ if (existsSync41(path))
30161
30340
  seen.set(path, backupNameOf2(f));
30162
30341
  }
30163
30342
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -30166,7 +30345,7 @@ function backupBeforeMigrating2(from) {
30166
30345
  const dir = migrationBackupDir(from);
30167
30346
  const saved = [];
30168
30347
  try {
30169
- rmSync14(dir, { recursive: true, force: true });
30348
+ rmSync15(dir, { recursive: true, force: true });
30170
30349
  mkdirSync25(dir, { recursive: true });
30171
30350
  } catch {
30172
30351
  return [];
@@ -30311,13 +30490,13 @@ var init_migrations2 = __esm(() => {
30311
30490
 
30312
30491
  // src/hooks/daemon-service.ts
30313
30492
  import {
30314
- existsSync as existsSync41,
30493
+ existsSync as existsSync42,
30315
30494
  mkdirSync as mkdirSync26,
30316
30495
  mkdtempSync as mkdtempSync2,
30317
30496
  readFileSync as readFileSync33,
30318
30497
  writeFileSync as writeFileSync24,
30319
30498
  unlinkSync as unlinkSync5,
30320
- rmSync as rmSync15
30499
+ rmSync as rmSync16
30321
30500
  } from "node:fs";
30322
30501
  import { homedir as homedir30, tmpdir as tmpdir3, userInfo as userInfo2 } from "node:os";
30323
30502
  import { resolve as resolve28 } from "node:path";
@@ -30336,13 +30515,13 @@ function resolveFailproofaidBinaryPath2() {
30336
30515
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
30337
30516
  return process.env.FAILPROOFAI_DAEMON_BINARY;
30338
30517
  const downloaded = installedBinaryPath();
30339
- if (existsSync41(downloaded))
30518
+ if (existsSync42(downloaded))
30340
30519
  return downloaded;
30341
30520
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
30342
30521
  if (packageRoot) {
30343
30522
  for (const profile of ["release", "debug"]) {
30344
30523
  const candidate = resolve28(packageRoot, "target", profile, "failproofaid");
30345
- if (existsSync41(candidate))
30524
+ if (existsSync42(candidate))
30346
30525
  return candidate;
30347
30526
  }
30348
30527
  }
@@ -30373,7 +30552,7 @@ function resolveWorkerCommand2() {
30373
30552
  if (!packageRoot)
30374
30553
  return null;
30375
30554
  const workerScript = resolve28(packageRoot, "dist", "worker.mjs");
30376
- if (!existsSync41(workerScript))
30555
+ if (!existsSync42(workerScript))
30377
30556
  return null;
30378
30557
  return `${shellQuote2(process.execPath)} ${shellQuote2(workerScript)}`;
30379
30558
  }
@@ -30384,7 +30563,7 @@ function resolveCliCommand2() {
30384
30563
  if (!packageRoot)
30385
30564
  return null;
30386
30565
  const cliScript = resolve28(packageRoot, "dist", "cli.mjs");
30387
- if (!existsSync41(cliScript))
30566
+ if (!existsSync42(cliScript))
30388
30567
  return null;
30389
30568
  return `${shellQuote2(process.execPath)} ${shellQuote2(cliScript)}`;
30390
30569
  }
@@ -30398,7 +30577,7 @@ function workerScriptPath2() {
30398
30577
  if (!packageRoot)
30399
30578
  return null;
30400
30579
  const workerScript = resolve28(packageRoot, "dist", "worker.mjs");
30401
- return existsSync41(workerScript) ? workerScript : null;
30580
+ return existsSync42(workerScript) ? workerScript : null;
30402
30581
  }
30403
30582
  function assertUnitSafe2(value, field) {
30404
30583
  if (UNIT_UNSAFE_RE2.test(value)) {
@@ -30480,14 +30659,14 @@ function writePrivilegedFile2(destination, contents, mode = "0644") {
30480
30659
  writeFileSync24(staging, contents, "utf8");
30481
30660
  runPrivileged2("install", ["-m", mode, staging, destination]);
30482
30661
  } finally {
30483
- rmSync15(stagingDir, { recursive: true, force: true });
30662
+ rmSync16(stagingDir, { recursive: true, force: true });
30484
30663
  }
30485
30664
  }
30486
30665
  function removeLegacyUserService2() {
30487
30666
  try {
30488
30667
  if (process.platform === "linux") {
30489
30668
  const legacy = legacySystemdUserUnitPath2();
30490
- if (!existsSync41(legacy))
30669
+ if (!existsSync42(legacy))
30491
30670
  return;
30492
30671
  try {
30493
30672
  execFileSync3("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -30504,7 +30683,7 @@ function removeLegacyUserService2() {
30504
30683
  } catch {}
30505
30684
  } else {
30506
30685
  const legacyAgent = legacyLaunchAgentPlistPath2();
30507
- if (existsSync41(legacyAgent)) {
30686
+ if (existsSync42(legacyAgent)) {
30508
30687
  try {
30509
30688
  execFileSync3("launchctl", ["unload", "-w", legacyAgent], {
30510
30689
  stdio: "ignore",
@@ -30514,7 +30693,7 @@ function removeLegacyUserService2() {
30514
30693
  unlinkSync5(legacyAgent);
30515
30694
  }
30516
30695
  const legacyDaemon = legacySharedLaunchDaemonPath2();
30517
- if (existsSync41(legacyDaemon)) {
30696
+ if (existsSync42(legacyDaemon)) {
30518
30697
  try {
30519
30698
  runPrivileged2("launchctl", ["unload", "-w", legacyDaemon]);
30520
30699
  } catch {}
@@ -30531,7 +30710,7 @@ function systemdUnitContents2(binaryPath, workerCmd, cliCmd = null) {
30531
30710
  const user = assertUnitSafe2(serviceUser2(), "User");
30532
30711
  assertUnitSafe2(binaryPath, "ExecStart");
30533
30712
  assertUnitSafe2(homedir30(), "HOME");
30534
- const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync41(p));
30713
+ const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync42(p));
30535
30714
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe2(p, "ConditionPathExists")}
30536
30715
  `).join("");
30537
30716
  return `[Unit]
@@ -30736,7 +30915,7 @@ function daemonServiceStatus2() {
30736
30915
  if (!isDaemonSupportedPlatform2())
30737
30916
  return "unsupported-platform";
30738
30917
  if (process.platform === "linux") {
30739
- if (!existsSync41(systemdUnitPath2()))
30918
+ if (!existsSync42(systemdUnitPath2()))
30740
30919
  return "not-installed";
30741
30920
  try {
30742
30921
  const out = execFileSync3("systemctl", ["is-active", systemdUnitName2()], {
@@ -30749,7 +30928,7 @@ function daemonServiceStatus2() {
30749
30928
  }
30750
30929
  }
30751
30930
  const plistPath = launchdPlistPath2();
30752
- if (!existsSync41(plistPath))
30931
+ if (!existsSync42(plistPath))
30753
30932
  return "not-installed";
30754
30933
  try {
30755
30934
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -30779,7 +30958,7 @@ var init_daemon_service2 = __esm(() => {
30779
30958
  });
30780
30959
 
30781
30960
  // src/hooks/uninstall-cli.ts
30782
- import { existsSync as existsSync42, rmSync as rmSync16 } from "node:fs";
30961
+ import { existsSync as existsSync43, rmSync as rmSync17 } from "node:fs";
30783
30962
  function survey(cwd) {
30784
30963
  const clis = [];
30785
30964
  for (const id of listInstallableIds()) {
@@ -30800,9 +30979,9 @@ function survey(cwd) {
30800
30979
  return {
30801
30980
  clis,
30802
30981
  servicePath,
30803
- serviceInstalled: !!servicePath && existsSync42(servicePath),
30982
+ serviceInstalled: !!servicePath && existsSync43(servicePath),
30804
30983
  daemonConfigured,
30805
- homeExists: existsSync42(failproofaiHome())
30984
+ homeExists: existsSync43(failproofaiHome())
30806
30985
  };
30807
30986
  }
30808
30987
  async function runUninstallCommand(opts = {}) {
@@ -30900,7 +31079,7 @@ async function runUninstallCommand(opts = {}) {
30900
31079
  } catch {}
30901
31080
  try {
30902
31081
  await uninstallDaemonService();
30903
- if (found.servicePath && existsSync42(found.servicePath)) {
31082
+ if (found.servicePath && existsSync43(found.servicePath)) {
30904
31083
  failures.push(`the service at ${found.servicePath} is still there (most often: no sudo). ` + `Remove it with the commands below.`);
30905
31084
  } else {
30906
31085
  lines.push(`✓ stopped and removed the daemon service`);
@@ -30912,7 +31091,7 @@ async function runUninstallCommand(opts = {}) {
30912
31091
  }
30913
31092
  if (opts.purge && found.homeExists) {
30914
31093
  try {
30915
- rmSync16(failproofaiHome(), { recursive: true, force: true });
31094
+ rmSync17(failproofaiHome(), { recursive: true, force: true });
30916
31095
  purged = true;
30917
31096
  lines.push(`✓ deleted ${failproofaiHome()}`);
30918
31097
  } catch (err) {
@@ -30923,7 +31102,7 @@ async function runUninstallCommand(opts = {}) {
30923
31102
  lines.push(``, `Not everything could be removed:`);
30924
31103
  for (const f of failures)
30925
31104
  lines.push(` ✗ ${f}`);
30926
- if (found.servicePath && existsSync42(found.servicePath)) {
31105
+ if (found.servicePath && existsSync43(found.servicePath)) {
30927
31106
  lines.push(``, `To remove the service by hand:`, ...manualServiceRemoval(found.servicePath), ``, `(\`${daemonStatusCommand()}\` shows its current state.)`);
30928
31107
  }
30929
31108
  return { exitCode: 1, lines, planLines, purged };
@@ -30957,7 +31136,7 @@ var init_uninstall_cli = __esm(() => {
30957
31136
  import { execFileSync as execFileSync4 } from "node:child_process";
30958
31137
  import { homedir as homedir31, tmpdir as tmpdir4 } from "node:os";
30959
31138
  import { createHash as createHash9 } from "node:crypto";
30960
- import { copyFileSync as copyFileSync4, existsSync as existsSync43, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync3, readFileSync as readFileSync34, readdirSync as readdirSync21, realpathSync as realpathSync3, rmSync as rmSync17, statSync as statSync26, writeFileSync as writeFileSync25 } from "node:fs";
31139
+ import { copyFileSync as copyFileSync4, existsSync as existsSync44, mkdirSync as mkdirSync27, mkdtempSync as mkdtempSync3, readFileSync as readFileSync34, readdirSync as readdirSync21, realpathSync as realpathSync3, rmSync as rmSync18, statSync as statSync26, writeFileSync as writeFileSync25 } from "node:fs";
30961
31140
  import { basename as basename9, dirname as dirname21, isAbsolute as isAbsolute4, join as join40, relative as relative5, resolve as resolve29, sep as sep6 } from "node:path";
30962
31141
  function parseList(rest, flag) {
30963
31142
  const idx = rest.findIndex((a) => a === flag || a.startsWith(`${flag}=`));
@@ -31072,7 +31251,7 @@ async function build(rest) {
31072
31251
  return fail2([err instanceof Error ? err.message : String(err)]);
31073
31252
  }
31074
31253
  const entryPath = resolve29(entry);
31075
- if (!existsSync43(entryPath))
31254
+ if (!existsSync44(entryPath))
31076
31255
  return fail2([`No such file: ${entryPath}`]);
31077
31256
  const source = readFileSync34(entryPath, "utf8");
31078
31257
  const localImport = /(?:^|\n)\s*(?:import|export)[^;\n]*from\s+["'](\.[^"']*)["']/.exec(source);
@@ -31267,7 +31446,7 @@ async function scaffold(target) {
31267
31446
  chosen = answer.trim();
31268
31447
  }
31269
31448
  const path = resolve29(withPolicyExtension(chosen ?? "my-policies"));
31270
- if (existsSync43(path)) {
31449
+ if (existsSync44(path)) {
31271
31450
  return fail2([`${path} already exists — name a different file, or edit that one.`]);
31272
31451
  }
31273
31452
  mkdirSync27(resolve29(path, ".."), { recursive: true });
@@ -31741,7 +31920,7 @@ esac
31741
31920
  return true;
31742
31921
  } finally {
31743
31922
  try {
31744
- rmSync17(dirname21(askpass), { recursive: true, force: true });
31923
+ rmSync18(dirname21(askpass), { recursive: true, force: true });
31745
31924
  } catch {}
31746
31925
  }
31747
31926
  }
@@ -32765,7 +32944,7 @@ var init_install_prompt = __esm(() => {
32765
32944
 
32766
32945
  // src/hooks/manager.ts
32767
32946
  import { execSync as execSync7 } from "node:child_process";
32768
- import { existsSync as existsSync44 } from "node:fs";
32947
+ import { existsSync as existsSync45 } from "node:fs";
32769
32948
  import { resolve as resolve30, basename as basename10 } from "node:path";
32770
32949
  import { platform as platform4, arch as arch4, release as release3, hostname as hostname6 } from "node:os";
32771
32950
  function getSettingsPath2(scope, cwd) {
@@ -32952,8 +33131,11 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
32952
33131
  }
32953
33132
  }
32954
33133
  const selectedClis = cli && cli.length > 0 ? [...new Set(cli)] : ["claude"];
32955
- for (const cliId of selectedClis) {
32956
- const integration = getIntegration(cliId);
33134
+ const selectedIntegrations = selectedClis.map((cliId) => ({
33135
+ cliId,
33136
+ integration: getIntegration(cliId)
33137
+ }));
33138
+ for (const { cliId, integration } of selectedIntegrations) {
32957
33139
  if (!integration.scopes.includes(scope)) {
32958
33140
  try {
32959
33141
  await trackHookEvent2(getInstanceId2(), "scope_validation_failed", {
@@ -32965,6 +33147,13 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
32965
33147
  throw new CliError(`Scope "${scope}" is not supported by ${integration.displayName}. ` + `Valid scopes: ${integration.scopes.join(", ")}`);
32966
33148
  }
32967
33149
  }
33150
+ const daemonRequiredBy = selectedIntegrations.map(({ integration }) => integration).filter((integration) => integration.requiresHealthyDaemon);
33151
+ if (daemonRequiredBy.length > 0 && !await probeDaemonEndToEnd()) {
33152
+ const names = daemonRequiredBy.map((integration) => integration.displayName).join(", ");
33153
+ const verb = daemonRequiredBy.length === 1 ? "requires" : "require";
33154
+ throw new CliError(`${names} ${verb} a healthy failproofaid daemon before FailproofAI enforcement can be enabled.
33155
+ ` + "Run `failproofai config` to install and configure the daemon, then retry.");
33156
+ }
32968
33157
  const binaryPath = resolveFailproofaiBinary2();
32969
33158
  const previousConfig = readScopedHooksConfig(scope, cwd);
32970
33159
  const previousEnabled = new Set(previousConfig.enabledPolicies);
@@ -32987,7 +33176,7 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
32987
33176
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
32988
33177
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve30(path));
32989
33178
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve30(path)).filter((path) => {
32990
- if (existsSync44(path))
33179
+ if (existsSync45(path))
32991
33180
  return true;
32992
33181
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
32993
33182
  return false;
@@ -33063,6 +33252,7 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
33063
33252
  const settingsPaths = settingsPathsFor(integration, scope, cwd);
33064
33253
  try {
33065
33254
  for (const settingsPath of settingsPaths) {
33255
+ integration.prepareInstall?.(settingsPath);
33066
33256
  const settings = integration.readSettings(settingsPath);
33067
33257
  integration.writeHookEntries(settings, binaryPath, scope);
33068
33258
  integration.writeSettings(settingsPath, settings);
@@ -33119,7 +33309,11 @@ Enabled ${selectedPolicies.length} policy(ies): ${selectedPolicies.join(", ")}
33119
33309
  } catch {}
33120
33310
  for (const { cli: cliId, path } of writtenSettingsPaths) {
33121
33311
  const integration = getIntegration(cliId);
33122
- console.log(`Failproof AI hooks installed for ${integration.displayName} ` + `(${integration.eventTypes.length} event types, scope: ${scope}).`);
33312
+ if (cliId === "hermes") {
33313
+ console.log(`Failproof AI native plugin installed for ${integration.displayName} ` + `(8 registered hooks, scope: ${scope}).`);
33314
+ } else {
33315
+ console.log(`Failproof AI hooks installed for ${integration.displayName} ` + `(${integration.eventTypes.length} event types, scope: ${scope}).`);
33316
+ }
33123
33317
  console.log(`Settings: ${path}`);
33124
33318
  }
33125
33319
  if (scope === "project") {
@@ -33210,7 +33404,7 @@ async function removeHooks2(policyNames, scope = "user", cwd, opts) {
33210
33404
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
33211
33405
  for (const s of scopesToRemove) {
33212
33406
  const settingsPaths = settingsPathsFor(integration, s, cwd);
33213
- const existing = settingsPaths.filter((p) => existsSync44(p));
33407
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync45(p));
33214
33408
  if (existing.length === 0) {
33215
33409
  if (scope !== "all" && selectedClis.length === 1) {
33216
33410
  console.log("No settings file found. Nothing to remove.");
@@ -33356,7 +33550,7 @@ async function listHooks(cwd) {
33356
33550
  for (const path of explicitPaths) {
33357
33551
  const absPath = resolve30(findProjectConfigDir(cwd ?? process.cwd()), path);
33358
33552
  groups.push(note(absPath, opts));
33359
- if (!existsSync44(absPath)) {
33553
+ if (!existsSync45(absPath)) {
33360
33554
  groups.push(warning([`file not found: ${absPath}`], opts));
33361
33555
  continue;
33362
33556
  }
@@ -33483,6 +33677,7 @@ var init_manager2 = __esm(() => {
33483
33677
  init_pack_store();
33484
33678
  init_pack_manifest();
33485
33679
  init_policy_evaluator();
33680
+ init_daemon_service();
33486
33681
  init_tui();
33487
33682
  VALID_POLICY_NAMES2 = new Set(BUILTIN_POLICIES.map((p) => p.name));
33488
33683
  });
@@ -33918,19 +34113,19 @@ function parseScriptArgs(argv) {
33918
34113
  var init_parse_script_args = () => {};
33919
34114
 
33920
34115
  // scripts/install-diagnosis.mjs
33921
- import { existsSync as existsSync45, readFileSync as readFileSync36, realpathSync as realpathSync4 } from "node:fs";
34116
+ import { existsSync as existsSync46, readFileSync as readFileSync36, realpathSync as realpathSync4 } from "node:fs";
33922
34117
  import { dirname as dirname22, resolve as resolve32 } from "node:path";
33923
34118
  import { homedir as homedir32, platform as platform5 } from "node:os";
33924
34119
  import { spawnSync } from "node:child_process";
33925
34120
  function findPackageRoot(start) {
33926
34121
  try {
33927
34122
  let dir = realpathSync4(start);
33928
- if (existsSync45(dir) && !existsSync45(resolve32(dir, "package.json"))) {
34123
+ if (existsSync46(dir) && !existsSync46(resolve32(dir, "package.json"))) {
33929
34124
  dir = dirname22(dir);
33930
34125
  }
33931
34126
  while (true) {
33932
34127
  const pkgPath = resolve32(dir, "package.json");
33933
- if (existsSync45(pkgPath)) {
34128
+ if (existsSync46(pkgPath)) {
33934
34129
  try {
33935
34130
  const pkg = JSON.parse(readFileSync36(pkgPath, "utf8"));
33936
34131
  if (pkg.name === PKG_NAME)
@@ -33977,7 +34172,7 @@ function locateNpmGlobal() {
33977
34172
  if (!root)
33978
34173
  return null;
33979
34174
  const candidate = resolve32(root, PKG_NAME);
33980
- return existsSync45(resolve32(candidate, "package.json")) ? candidate : null;
34175
+ return existsSync46(resolve32(candidate, "package.json")) ? candidate : null;
33981
34176
  } catch {
33982
34177
  return null;
33983
34178
  }
@@ -33985,7 +34180,7 @@ function locateNpmGlobal() {
33985
34180
  function locateBunGlobal() {
33986
34181
  try {
33987
34182
  const candidate = resolve32(homedir32(), ".bun", "install", "global", "node_modules", PKG_NAME);
33988
- return existsSync45(resolve32(candidate, "package.json")) ? candidate : null;
34183
+ return existsSync46(resolve32(candidate, "package.json")) ? candidate : null;
33989
34184
  } catch {
33990
34185
  return null;
33991
34186
  }
@@ -34088,7 +34283,7 @@ var init_dashboard_host = __esm(() => {
34088
34283
 
34089
34284
  // scripts/launch.ts
34090
34285
  import { spawn as spawn2 } from "child_process";
34091
- import { realpathSync as realpathSync5, existsSync as existsSync46 } from "node:fs";
34286
+ import { realpathSync as realpathSync5, existsSync as existsSync47 } from "node:fs";
34092
34287
  import { resolve as resolve33, dirname as dirname23 } from "node:path";
34093
34288
  import { fileURLToPath as fileURLToPath2 } from "node:url";
34094
34289
  import { createInterface } from "node:readline";
@@ -34115,7 +34310,7 @@ function launch(mode) {
34115
34310
  cmd = "node";
34116
34311
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve33(dirname23(realpathSync5(fileURLToPath2(import.meta.url))), "..");
34117
34312
  const serverJsPath = resolve33(packageRoot, ".next/standalone/server.js");
34118
- if (!existsSync46(serverJsPath)) {
34313
+ if (!existsSync47(serverJsPath)) {
34119
34314
  let shadowMessage = null;
34120
34315
  try {
34121
34316
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -34868,10 +35063,108 @@ var init_session_pause_cli = __esm(() => {
34868
35063
  init_tui();
34869
35064
  });
34870
35065
 
35066
+ // src/hooks/integrations.ts
35067
+ import {
35068
+ cpSync as cpSync2,
35069
+ readFileSync as readFileSync37,
35070
+ writeFileSync as writeFileSync26,
35071
+ existsSync as existsSync48,
35072
+ lstatSync as lstatSync2,
35073
+ mkdirSync as mkdirSync28,
35074
+ renameSync as renameSync10,
35075
+ rmSync as rmSync19,
35076
+ unlinkSync as unlinkSync6
35077
+ } from "node:fs";
35078
+ import { resolve as resolve34, dirname as dirname24 } from "node:path";
35079
+ function readYamlDoc2(path) {
35080
+ try {
35081
+ return existsSync48(path) ? $parseDocument(readFileSync37(path, "utf8")) : $parseDocument("");
35082
+ } catch {
35083
+ return $parseDocument("");
35084
+ }
35085
+ }
35086
+ function isMarkedHook2(hook) {
35087
+ if (!hook || typeof hook !== "object")
35088
+ return false;
35089
+ const h = hook;
35090
+ if (h[FAILPROOFAI_HOOK_MARKER] === true)
35091
+ return true;
35092
+ const cmd = typeof h.command === "string" ? h.command : "";
35093
+ return cmd.includes("failproofai") && cmd.includes("--hook");
35094
+ }
35095
+ function hermesPluginPathForSettings2(settingsPath) {
35096
+ return resolve34(dirname24(settingsPath), "plugins", HERMES_PLUGIN_ID2);
35097
+ }
35098
+ function hasManagedHermesPlugin2(settingsPath) {
35099
+ const pluginPath = hermesPluginPathForSettings2(settingsPath);
35100
+ try {
35101
+ if (lstatSync2(pluginPath).isSymbolicLink())
35102
+ return false;
35103
+ if (!existsSync48(resolve34(pluginPath, HERMES_PLUGIN_MARKER2)))
35104
+ return false;
35105
+ return HERMES_PLUGIN_FILES2.every((file) => existsSync48(resolve34(pluginPath, file)));
35106
+ } catch {
35107
+ return false;
35108
+ }
35109
+ }
35110
+ function hermesConfigState2(settingsPath) {
35111
+ if (!existsSync48(settingsPath)) {
35112
+ return { pluginEnabled: false, legacyShellHookPresent: false };
35113
+ }
35114
+ const doc = readYamlDoc2(settingsPath);
35115
+ const js = doc.toJS() ?? {};
35116
+ const enabled = js.plugins?.enabled;
35117
+ const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook2(entry)));
35118
+ return {
35119
+ pluginEnabled: Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID2),
35120
+ legacyShellHookPresent
35121
+ };
35122
+ }
35123
+ function hermesProfileHealth() {
35124
+ return listHermesProfiles().map((profile) => {
35125
+ const settingsPath = resolve34(profile.home, "config.yaml");
35126
+ const config = hermesConfigState2(settingsPath);
35127
+ const pluginInstalled = hasManagedHermesPlugin2(settingsPath);
35128
+ return {
35129
+ name: profile.name,
35130
+ home: profile.home,
35131
+ settingsPath,
35132
+ pluginInstalled,
35133
+ pluginEnabled: config.pluginEnabled,
35134
+ legacyShellHookPresent: config.legacyShellHookPresent,
35135
+ healthy: pluginInstalled && config.pluginEnabled && !config.legacyShellHookPresent
35136
+ };
35137
+ });
35138
+ }
35139
+ function hermesProfileStatusRows() {
35140
+ return hermesProfileHealth().filter((profile) => existsSync48(profile.home)).map((profile) => {
35141
+ const problems = [];
35142
+ if (!profile.pluginInstalled)
35143
+ problems.push("plugin files missing or incomplete");
35144
+ if (!profile.pluginEnabled)
35145
+ problems.push("plugin not enabled");
35146
+ if (profile.legacyShellHookPresent)
35147
+ problems.push("legacy shell hook also present");
35148
+ return [
35149
+ "hermes/" + profile.name,
35150
+ problems.length === 0 ? "native plugin enabled" : "UNHEALTHY — " + problems.join("; ")
35151
+ ];
35152
+ });
35153
+ }
35154
+ var HERMES_PLUGIN_ID2 = "failproofai", HERMES_PLUGIN_MARKER2 = ".failproofai-managed", HERMES_PLUGIN_FILES2, ANTIGRAVITY_TOOL_EVENTS2;
35155
+ var init_integrations2 = __esm(() => {
35156
+ init_dist();
35157
+ init_hermes_profiles();
35158
+ init_openclaw_profiles();
35159
+ init_types();
35160
+ HERMES_PLUGIN_FILES2 = ["plugin.yaml", "__init__.py", "client.py", "ledger.py"];
35161
+ ANTIGRAVITY_TOOL_EVENTS2 = new Set(["PreToolUse", "PostToolUse"]);
35162
+ });
35163
+
34871
35164
  // scripts/launch.ts
34872
35165
  import { spawn as spawn3 } from "child_process";
34873
- import { realpathSync as realpathSync6, existsSync as existsSync47 } from "node:fs";
34874
- import { resolve as resolve34, dirname as dirname24 } from "node:path";
35166
+ import { realpathSync as realpathSync6, existsSync as existsSync49 } from "node:fs";
35167
+ import { resolve as resolve35, dirname as dirname25 } from "node:path";
34875
35168
  import { fileURLToPath as fileURLToPath3 } from "node:url";
34876
35169
  import { createInterface as createInterface2 } from "node:readline";
34877
35170
  function launch2(mode) {
@@ -34895,9 +35188,9 @@ function launch2(mode) {
34895
35188
  process.env.PORT = port;
34896
35189
  process.env.HOSTNAME = bindHost;
34897
35190
  cmd = "node";
34898
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve34(dirname24(realpathSync6(fileURLToPath3(import.meta.url))), "..");
34899
- const serverJsPath = resolve34(packageRoot, ".next/standalone/server.js");
34900
- if (!existsSync47(serverJsPath)) {
35191
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve35(dirname25(realpathSync6(fileURLToPath3(import.meta.url))), "..");
35192
+ const serverJsPath = resolve35(packageRoot, ".next/standalone/server.js");
35193
+ if (!existsSync49(serverJsPath)) {
34901
35194
  let shadowMessage = null;
34902
35195
  try {
34903
35196
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -34994,17 +35287,17 @@ var init_cli_error2 = __esm(() => {
34994
35287
 
34995
35288
  // bin/failproofai.mjs
34996
35289
  import { realpathSync as realpathSync7 } from "fs";
34997
- import { dirname as dirname25, resolve as resolve35 } from "path";
35290
+ import { dirname as dirname26, resolve as resolve36 } from "path";
34998
35291
  import { fileURLToPath as fileURLToPath4 } from "url";
34999
35292
  // package.json
35000
- var version = "1.0.5";
35293
+ var version = "1.0.6-beta.1";
35001
35294
 
35002
35295
  // bin/failproofai.mjs
35003
35296
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
35004
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve35(dirname25(realpathSync7(fileURLToPath4(import.meta.url))), "..");
35297
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve36(dirname26(realpathSync7(fileURLToPath4(import.meta.url))), "..");
35005
35298
  }
35006
35299
  if (!process.env.FAILPROOFAI_DIST_PATH) {
35007
- process.env.FAILPROOFAI_DIST_PATH = resolve35(dirname25(realpathSync7(fileURLToPath4(import.meta.url))), "..", "dist");
35300
+ process.env.FAILPROOFAI_DIST_PATH = resolve36(dirname26(realpathSync7(fileURLToPath4(import.meta.url))), "..", "dist");
35008
35301
  }
35009
35302
  var args = process.argv.slice(2);
35010
35303
  if (args[0] === "p" || args[0] === "policy")
@@ -36580,7 +36873,9 @@ Run \`failproofai policies --help\` for usage.`);
36580
36873
  await Promise.resolve().then(() => init_tui2());
36581
36874
  const opts = optsFor2(process.stdout);
36582
36875
  const report = connectionStatusReport();
36583
- printBlock2(process.stdout, stack2(title2("failproofai config", versionStatusLines()[0], opts), rows2([...report.rows, ...result.rows ?? []], opts), report.warnings.length > 0 ? warning2(report.warnings, opts) : null, result.rows ? result.trailer ?? null : result.lines));
36876
+ await Promise.resolve().then(() => init_integrations2());
36877
+ const hermesRows = hermesProfileStatusRows();
36878
+ printBlock2(process.stdout, stack2(title2("failproofai config", versionStatusLines()[0], opts), rows2([...report.rows, ...hermesRows, ...result.rows ?? []], opts), report.warnings.length > 0 ? warning2(report.warnings, opts) : null, result.rows ? result.trailer ?? null : result.lines));
36584
36879
  } else {
36585
36880
  await printLines(result.lines, result.exitCode === 0);
36586
36881
  }