failproofai 1.0.6-beta.0 → 1.0.6

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 (136) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  10. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  11. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  18. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  19. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  20. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
  23. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  31. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/index.html +1 -1
  34. package/.next/standalone/.next/server/app/index.rsc +14 -14
  35. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  36. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  37. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  38. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  39. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  42. package/.next/standalone/.next/server/app/policies/page.js +6 -5
  43. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/page.js +1 -1
  47. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  57. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  58. package/.next/standalone/.next/server/app/settings/page.js +3 -2
  59. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  62. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zlqo2t._.js +1 -1
  63. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__112b4go._.js → [root-of-the-server]__1_r2rbg._.js} +4 -4
  64. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1anxb5k._.js +1 -1
  65. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
  69. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  70. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0576iuy._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bym1os._.js → [root-of-the-server]__0cg-bgc._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00y9ww2._.js → [root-of-the-server]__0u3w0ll._.js} +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1b2dbet._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1py795m._.js +1 -1
  81. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1i26dsw._.js → [root-of-the-server]__1svlq8e._.js} +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +1 -1
  83. package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
  84. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/{_09hs6ms._.js → _0do6d26._.js} +1 -1
  86. package/.next/standalone/.next/server/chunks/ssr/{_0lbwa8m._.js → _17o744m._.js} +2 -2
  87. package/.next/standalone/.next/server/chunks/ssr/{_14c6q09._.js → _1_qswah._.js} +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +1 -1
  89. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  91. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +12 -11
  92. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  93. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  96. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  97. package/.next/standalone/.next/server/pages/404.html +1 -1
  98. package/.next/standalone/.next/server/pages/500.html +1 -1
  99. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  100. package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
  101. package/.next/standalone/.next/static/chunks/0bepqeawy72n6.js +1 -0
  102. package/.next/standalone/.next/static/chunks/{17pjz_h45j10c.js → 0h-gz8e00478q.js} +1 -1
  103. package/.next/standalone/.next/static/chunks/{3d3hzhcnns6ww.js → 25m8mg7bosgip.js} +1 -1
  104. package/.next/standalone/.next/static/chunks/{44_cj1_i_aa2z.js → 2y4ycwcwfjv4k.js} +1 -1
  105. package/.next/standalone/.next/static/chunks/3-6zhytp6adkk.js +1 -0
  106. package/.next/standalone/.next/static/chunks/{0vanab2g65op_.js → 319c_91le7-h_.js} +1 -1
  107. package/.next/standalone/.next/static/chunks/35m53kix7uaii.js +6 -0
  108. package/.next/standalone/.next/static/chunks/{1so_3s0q4c4j1.js → 35pw7zxhh76n7.js} +1 -1
  109. package/.next/standalone/.next/static/chunks/3xacd7qmuqlvs.js +1 -0
  110. package/.next/standalone/.next/static/chunks/{03n_qjih7-w6q.js → 40-wncjnguy4e.js} +1 -1
  111. package/.next/standalone/hermes-plugin/README.md +6 -1
  112. package/.next/standalone/hermes-plugin/client.py +22 -6
  113. package/.next/standalone/lib/hermes-profiles.ts +67 -19
  114. package/.next/standalone/lib/hermes-sessions.ts +3 -2
  115. package/.next/standalone/package.json +9 -9
  116. package/.next/standalone/server.js +1 -1
  117. package/dist/cli.mjs +380 -266
  118. package/dist/worker.mjs +62 -32
  119. package/hermes-plugin/README.md +6 -1
  120. package/hermes-plugin/client.py +22 -6
  121. package/lib/hermes-profiles.ts +67 -19
  122. package/lib/hermes-sessions.ts +3 -2
  123. package/package.json +9 -9
  124. package/src/hooks/daemon-client.ts +128 -50
  125. package/src/hooks/daemon-service.ts +30 -0
  126. package/src/hooks/integrations.ts +8 -0
  127. package/src/hooks/manager.ts +24 -2
  128. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +0 -3
  129. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +0 -6
  130. package/.next/standalone/.next/static/chunks/1ekh-hj_iom84.js +0 -1
  131. package/.next/standalone/.next/static/chunks/2u0kol_boahtv.js +0 -1
  132. package/.next/standalone/.next/static/chunks/3_vesf83-0903.js +0 -1
  133. package/.next/standalone/.next/static/chunks/3iasus89n8mg1.js +0 -6
  134. /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_buildManifest.js +0 -0
  135. /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_clientMiddlewareManifest.js +0 -0
  136. /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_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.6-beta.0", package_default;
32
+ var version2 = "1.0.6", package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "failproofai",
@@ -155,16 +155,16 @@ var init_package = __esm(() => {
155
155
  browserslist: "4.28.8"
156
156
  },
157
157
  optionalDependencies: {
158
- "@failproofai/failproofaid-linux-x64": "1.0.6-beta.0",
159
- "@failproofai/failproofaid-linux-arm64": "1.0.6-beta.0",
160
- "@failproofai/failproofaid-darwin-x64": "1.0.6-beta.0",
161
- "@failproofai/failproofaid-darwin-arm64": "1.0.6-beta.0"
158
+ "@failproofai/failproofaid-linux-x64": "1.0.6",
159
+ "@failproofai/failproofaid-linux-arm64": "1.0.6",
160
+ "@failproofai/failproofaid-darwin-x64": "1.0.6",
161
+ "@failproofai/failproofaid-darwin-arm64": "1.0.6"
162
162
  },
163
163
  failproofaidBinaries: {
164
- "linux-x64": "38637a91db9a0e5683bbfbfffbba3d65e421960c3135510f23541df5f9d60478",
165
- "linux-arm64": "b9a2d9126fb9816b7743ec5b068d36d6515fa3a93fc2e3801fbe3a7a1b2143bf",
166
- "darwin-x64": "a06675cd28b3d2f54d45a28f527643841a69006dd68f989dad654806b190948b",
167
- "darwin-arm64": "6ef65b956ebff944c38cf2d65b6dc1066384aba7952d7d19c4805c1f1ba593ba"
164
+ "linux-x64": "e075f24a3a0950b631979d9370b665da2c3e2920decfb917ff0831d1f17c9740",
165
+ "linux-arm64": "b90ce8c642f2685719f4915695615219860daf3155a9c07344cf1e10395028c3",
166
+ "darwin-x64": "51dd95e9b85226e4f1888c7edaa56ec4464e91eb645d39c5cb7cede16d2da2f1",
167
+ "darwin-arm64": "f6a1b9d63363e8805e0d72b4fa168fde661bdbbd4125b54047f7de8948ea0f39"
168
168
  }
169
169
  };
170
170
  });
@@ -809,7 +809,7 @@ function encodeFrame(value) {
809
809
  header.writeUInt32BE(body.length, 0);
810
810
  return Buffer.concat([header, body]);
811
811
  }
812
- async function attemptDaemonHook(req, opts) {
812
+ async function attemptDaemonRequest(request, opts) {
813
813
  if (process.platform === "win32")
814
814
  return { ok: false, failure: "unreachable" };
815
815
  const responseBudget = opts?.responseTimeoutMs ?? DAEMON_RESPONSE_TIMEOUT_MS;
@@ -837,14 +837,7 @@ async function attemptDaemonHook(req, opts) {
837
837
  let declaredLen = null;
838
838
  socket.on("connect", () => {
839
839
  arm(responseBudget);
840
- socket.write(encodeFrame({
841
- type: "hook",
842
- protocolVersion: PROTOCOL_VERSION,
843
- hookEvent: req.hookEvent,
844
- cli: req.cli,
845
- stdin: req.stdin,
846
- cwd: req.cwd
847
- }));
840
+ socket.write(encodeFrame(request));
848
841
  });
849
842
  socket.on("data", (chunk) => {
850
843
  recvBuf = Buffer.concat([recvBuf, chunk]);
@@ -861,34 +854,52 @@ async function attemptDaemonHook(req, opts) {
861
854
  if (recvBuf.length < declaredLen)
862
855
  return;
863
856
  const body = recvBuf.subarray(0, declaredLen);
864
- let message;
857
+ let parsed;
865
858
  try {
866
- message = JSON.parse(body.toString("utf8"));
859
+ parsed = JSON.parse(body.toString("utf8"));
867
860
  } catch {
868
861
  fail("unreachable");
869
862
  return;
870
863
  }
871
- if (message.protocolVersion !== PROTOCOL_VERSION) {
872
- fail("protocol-mismatch");
864
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
865
+ fail("unreachable");
873
866
  return;
874
867
  }
875
- if (message.type === "hookResult" && typeof message.exitCode === "number" && typeof message.stdout === "string" && typeof message.stderr === "string") {
876
- finish({
877
- ok: true,
878
- response: {
879
- exitCode: message.exitCode,
880
- stdout: message.stdout,
881
- stderr: message.stderr
882
- }
883
- });
868
+ const message = parsed;
869
+ if (message.protocolVersion !== PROTOCOL_VERSION) {
870
+ fail("protocol-mismatch");
884
871
  return;
885
872
  }
886
- fail("unreachable");
873
+ finish({ ok: true, message });
887
874
  });
888
875
  socket.on("error", () => fail("unreachable"));
889
876
  socket.on("close", () => fail("unreachable"));
890
877
  });
891
878
  }
879
+ async function attemptDaemonHook(req, opts) {
880
+ const attempt = await attemptDaemonRequest({
881
+ type: "hook",
882
+ protocolVersion: PROTOCOL_VERSION,
883
+ hookEvent: req.hookEvent,
884
+ cli: req.cli,
885
+ stdin: req.stdin,
886
+ cwd: req.cwd
887
+ }, opts);
888
+ if (!attempt.ok)
889
+ return attempt;
890
+ const message = attempt.message;
891
+ if (message.type === "hookResult" && typeof message.exitCode === "number" && typeof message.stdout === "string" && typeof message.stderr === "string") {
892
+ return {
893
+ ok: true,
894
+ response: {
895
+ exitCode: message.exitCode,
896
+ stdout: message.stdout,
897
+ stderr: message.stderr
898
+ }
899
+ };
900
+ }
901
+ return { ok: false, failure: "unreachable" };
902
+ }
892
903
  var PROTOCOL_VERSION = 1, DAEMON_CONNECT_TIMEOUT_MS = 150, DAEMON_RESPONSE_TIMEOUT_MS = 30000, MAX_FRAME_LEN;
893
904
  var init_daemon_client = __esm(() => {
894
905
  init_fp_home();
@@ -11518,36 +11529,66 @@ var init_dist = __esm(() => {
11518
11529
  });
11519
11530
 
11520
11531
  // lib/hermes-profiles.ts
11521
- import { readdirSync } from "node:fs";
11532
+ import { existsSync as existsSync6, readdirSync } from "node:fs";
11522
11533
  import { homedir as homedir4 } from "node:os";
11523
11534
  import { basename, dirname as dirname3, join as join3, resolve as resolve6 } from "node:path";
11524
11535
  function hermesRoot() {
11525
11536
  const env = (process.env.HERMES_HOME || "").trim();
11526
11537
  if (env) {
11527
- const home = resolve6(env);
11538
+ let home = resolve6(env);
11528
11539
  const parent = dirname3(home);
11529
11540
  if (basename(parent) === PROFILES_DIR)
11530
- return dirname3(parent);
11541
+ home = dirname3(parent);
11542
+ const base = basename(home);
11543
+ if (base === STANDARD_HOME || base.startsWith(SIBLING_HOME_PREFIX)) {
11544
+ return join3(dirname3(home), STANDARD_HOME);
11545
+ }
11531
11546
  return home;
11532
11547
  }
11533
- return join3(homedir4(), ".hermes");
11548
+ return join3(homedir4(), STANDARD_HOME);
11549
+ }
11550
+ function uniqueProfileName(preferred, seen) {
11551
+ if (!seen.has(preferred))
11552
+ return preferred;
11553
+ const base = `${preferred}-home`;
11554
+ if (!seen.has(base))
11555
+ return base;
11556
+ let suffix = 2;
11557
+ while (seen.has(`${base}-${suffix}`))
11558
+ suffix += 1;
11559
+ return `${base}-${suffix}`;
11534
11560
  }
11535
11561
  function listHermesProfiles() {
11536
11562
  const root = hermesRoot();
11537
11563
  const out = [{ name: HERMES_DEFAULT_PROFILE, home: root }];
11538
11564
  const seen = new Set([HERMES_DEFAULT_PROFILE]);
11539
- let names;
11565
+ let names = [];
11540
11566
  try {
11541
11567
  names = readdirSync(join3(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
11542
- } catch {
11543
- return out;
11544
- }
11568
+ } catch {}
11545
11569
  for (const name of names) {
11546
11570
  if (seen.has(name))
11547
11571
  continue;
11548
11572
  seen.add(name);
11549
11573
  out.push({ name, home: join3(root, PROFILES_DIR, name) });
11550
11574
  }
11575
+ if (basename(root) !== STANDARD_HOME)
11576
+ return out;
11577
+ let siblings = [];
11578
+ const parent = dirname3(root);
11579
+ try {
11580
+ 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) => ({
11581
+ name: entry.name.slice(SIBLING_HOME_PREFIX.length),
11582
+ home: join3(parent, entry.name)
11583
+ })).sort((a, b) => a.name.localeCompare(b.name));
11584
+ } catch {
11585
+ return out;
11586
+ }
11587
+ for (const sibling of siblings) {
11588
+ const name = uniqueProfileName(sibling.name, seen);
11589
+ seen.add(name);
11590
+ out.push({ name, home: sibling.home });
11591
+ }
11551
11592
  return out;
11552
11593
  }
11553
11594
  function hermesProjectName(profile, source) {
@@ -11573,11 +11614,11 @@ function hermesProjectNameCandidates(name) {
11573
11614
  out.push({ profile: HERMES_DEFAULT_PROFILE, source: rest });
11574
11615
  return out;
11575
11616
  }
11576
- var PROFILES_DIR = "profiles", HERMES_DEFAULT_PROFILE = "default";
11617
+ var PROFILES_DIR = "profiles", STANDARD_HOME = ".hermes", SIBLING_HOME_PREFIX = ".hermes-", HERMES_DEFAULT_PROFILE = "default";
11577
11618
  var init_hermes_profiles = () => {};
11578
11619
 
11579
11620
  // lib/openclaw-profiles.ts
11580
- import { existsSync as existsSync6, readdirSync as readdirSync2 } from "node:fs";
11621
+ import { existsSync as existsSync7, readdirSync as readdirSync2 } from "node:fs";
11581
11622
  import { homedir as homedir5 } from "node:os";
11582
11623
  import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve7 } from "node:path";
11583
11624
  function openclawProfileHome() {
@@ -11609,7 +11650,7 @@ function listOpenClawProfiles() {
11609
11650
  } catch {
11610
11651
  return out;
11611
11652
  }
11612
- 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) => ({
11653
+ 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) => ({
11613
11654
  name: entry.name.slice(".openclaw-".length),
11614
11655
  home: join4(parent, entry.name)
11615
11656
  })).sort((a, b) => a.name.localeCompare(b.name));
@@ -11625,7 +11666,7 @@ import {
11625
11666
  cpSync,
11626
11667
  readFileSync as readFileSync5,
11627
11668
  writeFileSync as writeFileSync3,
11628
- existsSync as existsSync7,
11669
+ existsSync as existsSync8,
11629
11670
  lstatSync,
11630
11671
  mkdirSync as mkdirSync4,
11631
11672
  renameSync as renameSync2,
@@ -11636,7 +11677,7 @@ import { resolve as resolve8, dirname as dirname5 } from "node:path";
11636
11677
  import { fileURLToPath } from "node:url";
11637
11678
  import { homedir as homedir6 } from "node:os";
11638
11679
  function readJsonFile(path) {
11639
- if (!existsSync7(path))
11680
+ if (!existsSync8(path))
11640
11681
  return {};
11641
11682
  const raw = readFileSync5(path, "utf8");
11642
11683
  return JSON.parse(raw);
@@ -11648,7 +11689,7 @@ function writeJsonFile(path, data) {
11648
11689
  }
11649
11690
  function readYamlDoc(path) {
11650
11691
  try {
11651
- return existsSync7(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
11692
+ return existsSync8(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
11652
11693
  } catch {
11653
11694
  return $parseDocument("");
11654
11695
  }
@@ -11947,9 +11988,9 @@ function hasManagedHermesPlugin(settingsPath) {
11947
11988
  try {
11948
11989
  if (lstatSync(pluginPath).isSymbolicLink())
11949
11990
  return false;
11950
- if (!existsSync7(resolve8(pluginPath, HERMES_PLUGIN_MARKER)))
11991
+ if (!existsSync8(resolve8(pluginPath, HERMES_PLUGIN_MARKER)))
11951
11992
  return false;
11952
- return HERMES_PLUGIN_FILES.every((file) => existsSync7(resolve8(pluginPath, file)));
11993
+ return HERMES_PLUGIN_FILES.every((file) => existsSync8(resolve8(pluginPath, file)));
11953
11994
  } catch {
11954
11995
  return false;
11955
11996
  }
@@ -11957,7 +11998,7 @@ function hasManagedHermesPlugin(settingsPath) {
11957
11998
  function hasHermesPluginMarker(settingsPath) {
11958
11999
  const pluginPath = hermesPluginPathForSettings(settingsPath);
11959
12000
  try {
11960
- return !lstatSync(pluginPath).isSymbolicLink() && existsSync7(resolve8(pluginPath, HERMES_PLUGIN_MARKER));
12001
+ return !lstatSync(pluginPath).isSymbolicLink() && existsSync8(resolve8(pluginPath, HERMES_PLUGIN_MARKER));
11961
12002
  } catch {
11962
12003
  return false;
11963
12004
  }
@@ -11965,13 +12006,13 @@ function hasHermesPluginMarker(settingsPath) {
11965
12006
  function installHermesPlugin(settingsPath) {
11966
12007
  const source = getHermesPluginSourcePath();
11967
12008
  for (const file of HERMES_PLUGIN_FILES) {
11968
- if (!existsSync7(resolve8(source, file))) {
12009
+ if (!existsSync8(resolve8(source, file))) {
11969
12010
  throw new Error(`Hermes plugin asset is missing from the failproofai package: ${file}`);
11970
12011
  }
11971
12012
  }
11972
12013
  const destination = hermesPluginPathForSettings(settingsPath);
11973
- if (existsSync7(destination)) {
11974
- if (lstatSync(destination).isSymbolicLink() || !existsSync7(resolve8(destination, HERMES_PLUGIN_MARKER))) {
12014
+ if (existsSync8(destination)) {
12015
+ if (lstatSync(destination).isSymbolicLink() || !existsSync8(resolve8(destination, HERMES_PLUGIN_MARKER))) {
11975
12016
  throw new Error(`Refusing to overwrite an unmanaged Hermes plugin at ${destination}. ` + `Move it aside or install FailproofAI under a different Hermes profile.`);
11976
12017
  }
11977
12018
  }
@@ -11986,7 +12027,7 @@ function installHermesPlugin(settingsPath) {
11986
12027
  cpSync(resolve8(source, file), resolve8(temporary, file));
11987
12028
  }
11988
12029
  writeFileSync3(resolve8(temporary, HERMES_PLUGIN_MARKER), "Managed by failproofai. Remove with `failproofai policies --uninstall --cli hermes`.\n", { encoding: "utf8", mode: 384 });
11989
- if (existsSync7(destination)) {
12030
+ if (existsSync8(destination)) {
11990
12031
  renameSync2(destination, backup);
11991
12032
  movedExisting = true;
11992
12033
  }
@@ -11995,7 +12036,7 @@ function installHermesPlugin(settingsPath) {
11995
12036
  rmSync2(backup, { recursive: true, force: true });
11996
12037
  } catch (err) {
11997
12038
  rmSync2(temporary, { recursive: true, force: true });
11998
- if (movedExisting && !existsSync7(destination) && existsSync7(backup)) {
12039
+ if (movedExisting && !existsSync8(destination) && existsSync8(backup)) {
11999
12040
  renameSync2(backup, destination);
12000
12041
  }
12001
12042
  throw err;
@@ -12036,7 +12077,7 @@ function removeLegacyHermesHooks(doc) {
12036
12077
  return removed;
12037
12078
  }
12038
12079
  function hermesConfigState(settingsPath) {
12039
- if (!existsSync7(settingsPath)) {
12080
+ if (!existsSync8(settingsPath)) {
12040
12081
  return { pluginEnabled: false, legacyShellHookPresent: false };
12041
12082
  }
12042
12083
  const doc = readYamlDoc(settingsPath);
@@ -12200,7 +12241,7 @@ var init_integrations = __esm(() => {
12200
12241
  },
12201
12242
  hooksInstalledInSettings(scope, cwd) {
12202
12243
  const settingsPath = this.getSettingsPath(scope, cwd);
12203
- if (!existsSync7(settingsPath))
12244
+ if (!existsSync8(settingsPath))
12204
12245
  return false;
12205
12246
  try {
12206
12247
  const settings = this.readSettings(settingsPath);
@@ -12316,7 +12357,7 @@ var init_integrations = __esm(() => {
12316
12357
  },
12317
12358
  hooksInstalledInSettings(scope, cwd) {
12318
12359
  const settingsPath = this.getSettingsPath(scope, cwd);
12319
- if (!existsSync7(settingsPath))
12360
+ if (!existsSync8(settingsPath))
12320
12361
  return false;
12321
12362
  try {
12322
12363
  const settings = this.readSettings(settingsPath);
@@ -12430,7 +12471,7 @@ var init_integrations = __esm(() => {
12430
12471
  },
12431
12472
  hooksInstalledInSettings(scope, cwd) {
12432
12473
  const settingsPath = this.getSettingsPath(scope, cwd);
12433
- if (!existsSync7(settingsPath))
12474
+ if (!existsSync8(settingsPath))
12434
12475
  return false;
12435
12476
  try {
12436
12477
  const settings = this.readSettings(settingsPath);
@@ -12533,7 +12574,7 @@ var init_integrations = __esm(() => {
12533
12574
  },
12534
12575
  hooksInstalledInSettings(scope, cwd) {
12535
12576
  const settingsPath = this.getSettingsPath(scope, cwd);
12536
- if (!existsSync7(settingsPath))
12577
+ if (!existsSync8(settingsPath))
12537
12578
  return false;
12538
12579
  try {
12539
12580
  const settings = this.readSettings(settingsPath);
@@ -12617,7 +12658,7 @@ var init_integrations = __esm(() => {
12617
12658
  }
12618
12659
  this.writeSettings(settingsPath, settings);
12619
12660
  const pluginPath = opencodePluginFilePath(settingsPath);
12620
- if (existsSync7(pluginPath)) {
12661
+ if (existsSync8(pluginPath)) {
12621
12662
  try {
12622
12663
  const content = readFileSync5(pluginPath, "utf8");
12623
12664
  if (content.includes(FAILPROOFAI_HOOK_MARKER)) {
@@ -12631,7 +12672,7 @@ var init_integrations = __esm(() => {
12631
12672
  },
12632
12673
  hooksInstalledInSettings(scope, cwd) {
12633
12674
  const settingsPath = this.getSettingsPath(scope, cwd);
12634
- if (!existsSync7(settingsPath))
12675
+ if (!existsSync8(settingsPath))
12635
12676
  return false;
12636
12677
  try {
12637
12678
  const settings = this.readSettings(settingsPath);
@@ -12641,7 +12682,7 @@ var init_integrations = __esm(() => {
12641
12682
  if (!hasEntry)
12642
12683
  return false;
12643
12684
  const pluginPath = opencodePluginFilePath(settingsPath);
12644
- if (!existsSync7(pluginPath))
12685
+ if (!existsSync8(pluginPath))
12645
12686
  return false;
12646
12687
  const content = readFileSync5(pluginPath, "utf8");
12647
12688
  return content.includes(FAILPROOFAI_HOOK_MARKER);
@@ -12708,7 +12749,7 @@ var init_integrations = __esm(() => {
12708
12749
  }
12709
12750
  },
12710
12751
  removeHooksFromFile(settingsPath) {
12711
- if (!existsSync7(settingsPath))
12752
+ if (!existsSync8(settingsPath))
12712
12753
  return 0;
12713
12754
  const settings = this.readSettings(settingsPath);
12714
12755
  if (!Array.isArray(settings.packages))
@@ -12723,7 +12764,7 @@ var init_integrations = __esm(() => {
12723
12764
  },
12724
12765
  hooksInstalledInSettings(scope, cwd) {
12725
12766
  const settingsPath = this.getSettingsPath(scope, cwd);
12726
- if (!existsSync7(settingsPath))
12767
+ if (!existsSync8(settingsPath))
12727
12768
  return false;
12728
12769
  try {
12729
12770
  const settings = this.readSettings(settingsPath);
@@ -12742,6 +12783,7 @@ var init_integrations = __esm(() => {
12742
12783
  hermes = {
12743
12784
  id: "hermes",
12744
12785
  displayName: "Hermes",
12786
+ requiresHealthyDaemon: true,
12745
12787
  scopes: HERMES_HOOK_SCOPES,
12746
12788
  eventTypes: HERMES_HOOK_EVENT_TYPES,
12747
12789
  getSettingsPath() {
@@ -12876,7 +12918,7 @@ var init_integrations = __esm(() => {
12876
12918
  hooks.allowConversationAccess = true;
12877
12919
  },
12878
12920
  removeHooksFromFile(settingsPath) {
12879
- if (!existsSync7(settingsPath))
12921
+ if (!existsSync8(settingsPath))
12880
12922
  return 0;
12881
12923
  const settings = this.readSettings(settingsPath);
12882
12924
  const plugins = settings.plugins;
@@ -12906,7 +12948,7 @@ var init_integrations = __esm(() => {
12906
12948
  hooksInstalledInSettings(scope, cwd) {
12907
12949
  const settingsPaths = settingsPathsFor(this, scope, cwd);
12908
12950
  return settingsPaths.length > 0 && settingsPaths.every((settingsPath) => {
12909
- if (!existsSync7(settingsPath))
12951
+ if (!existsSync8(settingsPath))
12910
12952
  return false;
12911
12953
  try {
12912
12954
  const settings = this.readSettings(settingsPath);
@@ -13004,7 +13046,7 @@ var init_integrations = __esm(() => {
13004
13046
  },
13005
13047
  hooksInstalledInSettings(scope, cwd) {
13006
13048
  const settingsPath = this.getSettingsPath(scope, cwd);
13007
- if (!existsSync7(settingsPath))
13049
+ if (!existsSync8(settingsPath))
13008
13050
  return false;
13009
13051
  try {
13010
13052
  const settings = this.readSettings(settingsPath);
@@ -13110,7 +13152,7 @@ var init_integrations = __esm(() => {
13110
13152
  },
13111
13153
  hooksInstalledInSettings(scope, cwd) {
13112
13154
  const settingsPath = this.getSettingsPath(scope, cwd);
13113
- if (!existsSync7(settingsPath))
13155
+ if (!existsSync8(settingsPath))
13114
13156
  return false;
13115
13157
  try {
13116
13158
  const settings = this.readSettings(settingsPath);
@@ -13249,7 +13291,7 @@ var init_integrations = __esm(() => {
13249
13291
  },
13250
13292
  hooksInstalledInSettings(scope, cwd) {
13251
13293
  const settingsPath = this.getSettingsPath(scope, cwd);
13252
- if (!existsSync7(settingsPath))
13294
+ if (!existsSync8(settingsPath))
13253
13295
  return false;
13254
13296
  try {
13255
13297
  const settings = this.readSettings(settingsPath);
@@ -13355,7 +13397,7 @@ var init_integrations = __esm(() => {
13355
13397
  },
13356
13398
  hooksInstalledInSettings(scope, cwd) {
13357
13399
  const settingsPath = this.getSettingsPath(scope, cwd);
13358
- if (!existsSync7(settingsPath))
13400
+ if (!existsSync8(settingsPath))
13359
13401
  return false;
13360
13402
  try {
13361
13403
  const settings = this.readSettings(settingsPath);
@@ -13746,12 +13788,12 @@ var init_telemetry_id2 = __esm(() => {
13746
13788
  // src/hooks/custom-hooks-loader.ts
13747
13789
  import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename3 } from "node:path";
13748
13790
  import { randomUUID } from "crypto";
13749
- import { existsSync as existsSync8, readdirSync as readdirSync3 } from "node:fs";
13791
+ import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
13750
13792
  import { readFile as readFile3 } from "node:fs/promises";
13751
13793
  import { pathToFileURL as pathToFileURL2 } from "node:url";
13752
13794
  import { createHash as createHash4 } from "node:crypto";
13753
13795
  function discoverPolicyFiles(dir) {
13754
- if (!existsSync8(dir))
13796
+ if (!existsSync9(dir))
13755
13797
  return [];
13756
13798
  try {
13757
13799
  const entries = readdirSync3(dir, { withFileTypes: true });
@@ -13761,7 +13803,7 @@ function discoverPolicyFiles(dir) {
13761
13803
  }
13762
13804
  }
13763
13805
  function findSkippedPolicyFiles(dir) {
13764
- if (!existsSync8(dir))
13806
+ if (!existsSync9(dir))
13765
13807
  return [];
13766
13808
  try {
13767
13809
  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));
@@ -13848,7 +13890,7 @@ async function loadCustomHooks(customPoliciesPath, opts) {
13848
13890
  if (!customPoliciesPath)
13849
13891
  return [];
13850
13892
  const absPath = isAbsolute2(customPoliciesPath) ? customPoliciesPath : resolve10(opts?.sessionCwd ?? process.cwd(), customPoliciesPath);
13851
- if (!existsSync8(absPath)) {
13893
+ if (!existsSync9(absPath)) {
13852
13894
  if (opts?.strict)
13853
13895
  throw new Error(`Custom hooks file not found: ${absPath}`);
13854
13896
  hookLogWarn(`customPoliciesPath not found: ${absPath}`);
@@ -13934,7 +13976,7 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
13934
13976
  const absPath = resolve10(projectRoot, customPoliciesPath);
13935
13977
  const cloudManaged = cloudManagedByPath.get(absPath);
13936
13978
  const pack = packByPath.get(absPath);
13937
- if (existsSync8(absPath)) {
13979
+ if (existsSync9(absPath)) {
13938
13980
  if (!loadedPaths.has(absPath)) {
13939
13981
  loadedPaths.add(absPath);
13940
13982
  const hooksBefore = getCustomHooks().length;
@@ -15002,7 +15044,7 @@ var init_pack_cli = __esm(() => {
15002
15044
 
15003
15045
  // src/hooks/pack-store.ts
15004
15046
  import { createHash as createHash5 } from "node:crypto";
15005
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
15047
+ import { existsSync as existsSync10, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
15006
15048
  import { dirname as dirname7, resolve as resolve11 } from "node:path";
15007
15049
  function baseUrl() {
15008
15050
  return (process.env.FAILPROOFAI_PACK_BASE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
@@ -15352,7 +15394,7 @@ async function addPack(source, opts) {
15352
15394
  const root = packsRoot();
15353
15395
  const artifactRel = `artifacts/${fetched.artifactDigest}.mjs`;
15354
15396
  const artifactAbs = resolve11(root, artifactRel);
15355
- if (!existsSync9(artifactAbs))
15397
+ if (!existsSync10(artifactAbs))
15356
15398
  writeAtomic(artifactAbs, fetched.artifact);
15357
15399
  try {
15358
15400
  await verifyArtifactRegisters(artifactAbs, available);
@@ -15395,7 +15437,7 @@ async function addPack(source, opts) {
15395
15437
  }
15396
15438
  function setPackPolicyEnabled(packId, name, on) {
15397
15439
  const manifestPath = resolve11(packsRoot(), "installed.json");
15398
- if (!existsSync9(manifestPath))
15440
+ if (!existsSync10(manifestPath))
15399
15441
  return { ok: false, reason: "no packs are installed" };
15400
15442
  let raw;
15401
15443
  try {
@@ -15429,7 +15471,7 @@ function bareId(value) {
15429
15471
  }
15430
15472
  function removePack(id) {
15431
15473
  const manifestPath = resolve11(packsRoot(), "installed.json");
15432
- if (!existsSync9(manifestPath))
15474
+ if (!existsSync10(manifestPath))
15433
15475
  return null;
15434
15476
  let raw;
15435
15477
  try {
@@ -15454,7 +15496,7 @@ function removePack(id) {
15454
15496
  function upsertInstalled(record, carryAbsorbedSelection = true) {
15455
15497
  const manifestPath = resolve11(packsRoot(), "installed.json");
15456
15498
  let packs = [];
15457
- if (existsSync9(manifestPath)) {
15499
+ if (existsSync10(manifestPath)) {
15458
15500
  try {
15459
15501
  const raw = JSON.parse(readFileSync6(manifestPath, "utf8"));
15460
15502
  if (Array.isArray(raw.packs))
@@ -16300,13 +16342,13 @@ import {
16300
16342
  renameSync as renameSync4,
16301
16343
  readdirSync as readdirSync4,
16302
16344
  mkdirSync as mkdirSync6,
16303
- existsSync as existsSync10,
16345
+ existsSync as existsSync11,
16304
16346
  statSync as statSync5,
16305
16347
  unlinkSync as unlinkSync2
16306
16348
  } from "node:fs";
16307
16349
  import { join as join6 } from "node:path";
16308
16350
  function ensureDir() {
16309
- if (!existsSync10(storeDirValue())) {
16351
+ if (!existsSync11(storeDirValue())) {
16310
16352
  mkdirSync6(storeDirValue(), { recursive: true });
16311
16353
  }
16312
16354
  }
@@ -16429,7 +16471,7 @@ function rebuildHookActivityStats() {
16429
16471
  let sawAny = false;
16430
16472
  for (const file of files) {
16431
16473
  const path = join6(storeDirValue(), file);
16432
- if (!existsSync10(path))
16474
+ if (!existsSync11(path))
16433
16475
  continue;
16434
16476
  sawAny = true;
16435
16477
  for (const entry of readJsonlFile(path))
@@ -16498,7 +16540,7 @@ var init_hook_activity_store = __esm(() => {
16498
16540
  });
16499
16541
 
16500
16542
  // src/hooks/delivery-health.ts
16501
- import { existsSync as existsSync11, readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
16543
+ import { existsSync as existsSync12, readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
16502
16544
  import { join as join7 } from "node:path";
16503
16545
  function parseParkedName(name) {
16504
16546
  const poison = name.endsWith(POISON_SUFFIX);
@@ -16527,7 +16569,7 @@ function parseParkedName(name) {
16527
16569
  }
16528
16570
  function deliveryHealth(home, now = Date.now()) {
16529
16571
  const dir = failedDir(home);
16530
- if (!existsSync11(dir))
16572
+ if (!existsSync12(dir))
16531
16573
  return EMPTY;
16532
16574
  let entries;
16533
16575
  try {
@@ -17292,7 +17334,7 @@ var init_cursor_projects = __esm(() => {
17292
17334
  });
17293
17335
 
17294
17336
  // lib/sqlite-reader.ts
17295
- import { existsSync as existsSync12, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
17337
+ import { existsSync as existsSync13, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
17296
17338
  import initSqlJs from "sql.js/dist/sql-asm.js";
17297
17339
  async function tryNodeSqlite(dbPath) {
17298
17340
  try {
@@ -17450,7 +17492,7 @@ async function trySqlJs(dbPath) {
17450
17492
  }
17451
17493
  }
17452
17494
  async function openSqliteReadonly(dbPath, options = {}) {
17453
- if (!existsSync12(dbPath))
17495
+ if (!existsSync13(dbPath))
17454
17496
  return null;
17455
17497
  if (!options.forcePortable) {
17456
17498
  const native = await tryNodeSqlite(dbPath);
@@ -18111,7 +18153,7 @@ var init_hermes_projects = __esm(() => {
18111
18153
  });
18112
18154
 
18113
18155
  // lib/openclaw-db.ts
18114
- import { existsSync as existsSync13 } from "node:fs";
18156
+ import { existsSync as existsSync14 } from "node:fs";
18115
18157
  import { join as join15 } from "node:path";
18116
18158
  function str(value) {
18117
18159
  return typeof value === "string" && value.length > 0 ? value : undefined;
@@ -18131,7 +18173,7 @@ function listOpenClawDatabases(home, agentIds) {
18131
18173
  const out = [];
18132
18174
  for (const agentId of agentIds) {
18133
18175
  const dbPath = join15(home, "agents", agentId, "agent", DB_NAME);
18134
- if (existsSync13(dbPath))
18176
+ if (existsSync14(dbPath))
18135
18177
  out.push({ agentId, dbPath });
18136
18178
  }
18137
18179
  return out;
@@ -20317,13 +20359,13 @@ var init_log_entries = __esm(() => {
20317
20359
  });
20318
20360
 
20319
20361
  // lib/codex-sessions.ts
20320
- import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync14, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, statSync as statSync11 } from "node:fs";
20362
+ import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync15, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, statSync as statSync11 } from "node:fs";
20321
20363
  import { readFile as readFile11 } from "node:fs/promises";
20322
20364
  import { dirname as dirname8, join as join26 } from "node:path";
20323
20365
  import { homedir as homedir18 } from "node:os";
20324
20366
  function readCache() {
20325
20367
  try {
20326
- if (!existsSync14(CACHE_PATH))
20368
+ if (!existsSync15(CACHE_PATH))
20327
20369
  return {};
20328
20370
  return JSON.parse(readFileSync10(CACHE_PATH, "utf-8"));
20329
20371
  } catch {
@@ -20351,7 +20393,7 @@ function dirSearch(dir, sessionId) {
20351
20393
  function findCodexTranscript(sessionId) {
20352
20394
  const cache = readCache();
20353
20395
  const cached = cache[sessionId];
20354
- if (cached && existsSync14(cached))
20396
+ if (cached && existsSync15(cached))
20355
20397
  return cached;
20356
20398
  const root = join26(homedir18(), ".codex", "sessions");
20357
20399
  const today = new Date;
@@ -20645,7 +20687,7 @@ var init_resolve_permission_mode = __esm(() => {
20645
20687
  });
20646
20688
 
20647
20689
  // lib/copilot-sessions.ts
20648
- import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync15, statSync as statSync12 } from "node:fs";
20690
+ import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync16, statSync as statSync12 } from "node:fs";
20649
20691
  import { readFile as readFile12 } from "node:fs/promises";
20650
20692
  import { join as join27, resolve as resolve13, sep as sep2 } from "node:path";
20651
20693
  import { homedir as homedir19 } from "node:os";
@@ -20674,13 +20716,13 @@ function findCopilotTranscript(sessionId) {
20674
20716
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
20675
20717
  if (!candidate)
20676
20718
  return null;
20677
- return existsSync15(candidate) ? candidate : null;
20719
+ return existsSync16(candidate) ? candidate : null;
20678
20720
  }
20679
20721
  function findCopilotWorkspace(sessionId) {
20680
20722
  const candidate = resolveSessionFile(sessionId, "workspace.yaml");
20681
20723
  if (!candidate)
20682
20724
  return null;
20683
- return existsSync15(candidate) ? candidate : null;
20725
+ return existsSync16(candidate) ? candidate : null;
20684
20726
  }
20685
20727
  function readYamlScalar(path, key) {
20686
20728
  try {
@@ -20862,7 +20904,7 @@ var init_copilot_sessions = __esm(() => {
20862
20904
  });
20863
20905
 
20864
20906
  // lib/cursor-sessions.ts
20865
- import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync16, statSync as statSync13 } from "node:fs";
20907
+ import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync17, statSync as statSync13 } from "node:fs";
20866
20908
  import { readFile as readFile13 } from "node:fs/promises";
20867
20909
  import { basename as basename4, join as join28, resolve as resolve14, sep as sep3 } from "node:path";
20868
20910
  import { homedir as homedir20 } from "node:os";
@@ -20885,7 +20927,7 @@ function getCursorSessionDir(sessionId) {
20885
20927
  const transcriptRoot = resolve14(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
20886
20928
  if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
20887
20929
  continue;
20888
- if (existsSync16(candidate))
20930
+ if (existsSync17(candidate))
20889
20931
  return candidate;
20890
20932
  }
20891
20933
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
@@ -20893,7 +20935,7 @@ function getCursorSessionDir(sessionId) {
20893
20935
  const candidate = resolve14(root, sessionId);
20894
20936
  if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
20895
20937
  continue;
20896
- if (existsSync16(candidate))
20938
+ if (existsSync17(candidate))
20897
20939
  return candidate;
20898
20940
  }
20899
20941
  return null;
@@ -20903,11 +20945,11 @@ function findCursorTranscript(sessionId) {
20903
20945
  if (!dir)
20904
20946
  return null;
20905
20947
  const newCandidate = join28(dir, `${basename4(dir)}.jsonl`);
20906
- if (existsSync16(newCandidate))
20948
+ if (existsSync17(newCandidate))
20907
20949
  return newCandidate;
20908
20950
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
20909
20951
  const candidate = join28(dir, name);
20910
- if (existsSync16(candidate))
20952
+ if (existsSync17(candidate))
20911
20953
  return candidate;
20912
20954
  }
20913
20955
  return null;
@@ -21118,7 +21160,7 @@ var init_cursor_sessions = __esm(() => {
21118
21160
  });
21119
21161
 
21120
21162
  // lib/pi-sessions.ts
21121
- import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync17, statSync as statSync14 } from "node:fs";
21163
+ import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync18, statSync as statSync14 } from "node:fs";
21122
21164
  import { readFile as readFile14 } from "node:fs/promises";
21123
21165
  import { join as join29, resolve as resolve15, sep as sep4 } from "node:path";
21124
21166
  import { homedir as homedir21 } from "node:os";
@@ -21155,7 +21197,7 @@ function findPiTranscript(sessionId) {
21155
21197
  const candidate = resolve15(cwdPath, f);
21156
21198
  if (!candidate.startsWith(`${cwdPath}${sep4}`))
21157
21199
  continue;
21158
- if (existsSync17(candidate))
21200
+ if (existsSync18(candidate))
21159
21201
  return candidate;
21160
21202
  }
21161
21203
  }
@@ -21561,7 +21603,7 @@ var init_pack_failclosed = __esm(() => {
21561
21603
  // lib/atomic-write.ts
21562
21604
  import {
21563
21605
  chmodSync as chmodSync2,
21564
- existsSync as existsSync18,
21606
+ existsSync as existsSync19,
21565
21607
  mkdirSync as mkdirSync8,
21566
21608
  renameSync as renameSync5,
21567
21609
  rmSync as rmSync4,
@@ -21574,7 +21616,7 @@ function writeJsonAtomically(filePath, value, opts = {}) {
21574
21616
  const mode = opts.mode ?? 384;
21575
21617
  const dirMode = opts.dirMode ?? 448;
21576
21618
  const dir = dirname9(filePath);
21577
- if (!existsSync18(dir))
21619
+ if (!existsSync19(dir))
21578
21620
  mkdirSync8(dir, { recursive: true, mode: dirMode });
21579
21621
  const tmp = `${filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
21580
21622
  try {
@@ -21598,7 +21640,7 @@ function writeJsonAtomically(filePath, value, opts = {}) {
21598
21640
  var init_atomic_write = () => {};
21599
21641
 
21600
21642
  // src/hooks/session-pause.ts
21601
- import { existsSync as existsSync19, mkdirSync as mkdirSync9, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync5 } from "node:fs";
21643
+ import { existsSync as existsSync20, mkdirSync as mkdirSync9, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync5 } from "node:fs";
21602
21644
  import { createHash as createHash6 } from "node:crypto";
21603
21645
  import { join as join30, resolve as resolve16 } from "node:path";
21604
21646
  function pauseStateDir() {
@@ -21665,7 +21707,7 @@ function readActivePause(sessionId, now = Date.now()) {
21665
21707
  return null;
21666
21708
  try {
21667
21709
  const path = pauseFilePath(sessionId);
21668
- if (!existsSync19(path))
21710
+ if (!existsSync20(path))
21669
21711
  return null;
21670
21712
  const stored = parseStored(JSON.parse(readFileSync15(path, "utf8")));
21671
21713
  if (!stored)
@@ -21696,7 +21738,7 @@ function writePause(opts) {
21696
21738
  }
21697
21739
  function clearPause(sessionId) {
21698
21740
  const path = pauseFilePath(sessionId);
21699
- if (!existsSync19(path))
21741
+ if (!existsSync20(path))
21700
21742
  return false;
21701
21743
  try {
21702
21744
  rmSync5(path);
@@ -21707,7 +21749,7 @@ function clearPause(sessionId) {
21707
21749
  }
21708
21750
  function listActivePauses(now = Date.now()) {
21709
21751
  const dir = pauseStateDir();
21710
- if (!existsSync19(dir))
21752
+ if (!existsSync20(dir))
21711
21753
  return [];
21712
21754
  const out = [];
21713
21755
  let names;
@@ -21761,7 +21803,7 @@ var init_session_pause = __esm(() => {
21761
21803
  import { createHash as createHash7 } from "node:crypto";
21762
21804
  import {
21763
21805
  chmodSync as chmodSync3,
21764
- existsSync as existsSync20,
21806
+ existsSync as existsSync21,
21765
21807
  mkdirSync as mkdirSync10,
21766
21808
  readdirSync as readdirSync14,
21767
21809
  readFileSync as readFileSync16,
@@ -21813,7 +21855,7 @@ function platformPackageBinary(dir) {
21813
21855
  return null;
21814
21856
  }
21815
21857
  const candidate = resolve17(dir, "bin", "failproofaid");
21816
- return existsSync20(candidate) ? candidate : null;
21858
+ return existsSync21(candidate) ? candidate : null;
21817
21859
  }
21818
21860
  function pruneOldDaemonBinaries(keep = 2) {
21819
21861
  const removed = [];
@@ -21891,7 +21933,7 @@ function digestFor2(manifest, assetName) {
21891
21933
  }
21892
21934
  async function downloadFailproofaidBinary(key) {
21893
21935
  const target = installedBinaryPath();
21894
- if (existsSync20(target))
21936
+ if (existsSync21(target))
21895
21937
  return { path: target };
21896
21938
  if (process.env.FAILPROOFAI_NO_DOWNLOAD) {
21897
21939
  return { error: "daemon downloads are disabled (FAILPROOFAI_NO_DOWNLOAD)" };
@@ -21925,10 +21967,10 @@ var init_daemon_download = __esm(() => {
21925
21967
 
21926
21968
  // src/hooks/daemon-client.ts
21927
21969
  import { createConnection as createConnection2 } from "node:net";
21928
- import { existsSync as existsSync21 } from "node:fs";
21970
+ import { existsSync as existsSync22 } from "node:fs";
21929
21971
  function daemonSocketPresent() {
21930
21972
  try {
21931
- return existsSync21(socketPath2());
21973
+ return existsSync22(socketPath2());
21932
21974
  } catch {
21933
21975
  return false;
21934
21976
  }
@@ -21965,7 +22007,7 @@ function encodeFrame2(value) {
21965
22007
  header.writeUInt32BE(body.length, 0);
21966
22008
  return Buffer.concat([header, body]);
21967
22009
  }
21968
- async function attemptDaemonHook2(req, opts) {
22010
+ async function attemptDaemonRequest2(request, opts) {
21969
22011
  if (process.platform === "win32")
21970
22012
  return { ok: false, failure: "unreachable" };
21971
22013
  const responseBudget = opts?.responseTimeoutMs ?? DAEMON_RESPONSE_TIMEOUT_MS2;
@@ -21993,14 +22035,7 @@ async function attemptDaemonHook2(req, opts) {
21993
22035
  let declaredLen = null;
21994
22036
  socket.on("connect", () => {
21995
22037
  arm(responseBudget);
21996
- socket.write(encodeFrame2({
21997
- type: "hook",
21998
- protocolVersion: PROTOCOL_VERSION2,
21999
- hookEvent: req.hookEvent,
22000
- cli: req.cli,
22001
- stdin: req.stdin,
22002
- cwd: req.cwd
22003
- }));
22038
+ socket.write(encodeFrame2(request));
22004
22039
  });
22005
22040
  socket.on("data", (chunk) => {
22006
22041
  recvBuf = Buffer.concat([recvBuf, chunk]);
@@ -22017,34 +22052,73 @@ async function attemptDaemonHook2(req, opts) {
22017
22052
  if (recvBuf.length < declaredLen)
22018
22053
  return;
22019
22054
  const body = recvBuf.subarray(0, declaredLen);
22020
- let message;
22055
+ let parsed;
22021
22056
  try {
22022
- message = JSON.parse(body.toString("utf8"));
22057
+ parsed = JSON.parse(body.toString("utf8"));
22023
22058
  } catch {
22024
22059
  fail("unreachable");
22025
22060
  return;
22026
22061
  }
22027
- if (message.protocolVersion !== PROTOCOL_VERSION2) {
22028
- fail("protocol-mismatch");
22062
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
22063
+ fail("unreachable");
22029
22064
  return;
22030
22065
  }
22031
- if (message.type === "hookResult" && typeof message.exitCode === "number" && typeof message.stdout === "string" && typeof message.stderr === "string") {
22032
- finish({
22033
- ok: true,
22034
- response: {
22035
- exitCode: message.exitCode,
22036
- stdout: message.stdout,
22037
- stderr: message.stderr
22038
- }
22039
- });
22066
+ const message = parsed;
22067
+ if (message.protocolVersion !== PROTOCOL_VERSION2) {
22068
+ fail("protocol-mismatch");
22040
22069
  return;
22041
22070
  }
22042
- fail("unreachable");
22071
+ finish({ ok: true, message });
22043
22072
  });
22044
22073
  socket.on("error", () => fail("unreachable"));
22045
22074
  socket.on("close", () => fail("unreachable"));
22046
22075
  });
22047
22076
  }
22077
+ async function attemptDaemonHook2(req, opts) {
22078
+ const attempt = await attemptDaemonRequest2({
22079
+ type: "hook",
22080
+ protocolVersion: PROTOCOL_VERSION2,
22081
+ hookEvent: req.hookEvent,
22082
+ cli: req.cli,
22083
+ stdin: req.stdin,
22084
+ cwd: req.cwd
22085
+ }, opts);
22086
+ if (!attempt.ok)
22087
+ return attempt;
22088
+ const message = attempt.message;
22089
+ if (message.type === "hookResult" && typeof message.exitCode === "number" && typeof message.stdout === "string" && typeof message.stderr === "string") {
22090
+ return {
22091
+ ok: true,
22092
+ response: {
22093
+ exitCode: message.exitCode,
22094
+ stdout: message.stdout,
22095
+ stderr: message.stderr
22096
+ }
22097
+ };
22098
+ }
22099
+ return { ok: false, failure: "unreachable" };
22100
+ }
22101
+ function isStringArray(value) {
22102
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
22103
+ }
22104
+ async function attemptDaemonPolicyEvaluation(req, opts) {
22105
+ const attempt = await attemptDaemonRequest2({
22106
+ type: "policyEvaluation",
22107
+ protocolVersion: PROTOCOL_VERSION2,
22108
+ integration: req.integration,
22109
+ event: req.event,
22110
+ payload: req.payload,
22111
+ cwd: req.cwd
22112
+ }, opts);
22113
+ if (!attempt.ok)
22114
+ return attempt;
22115
+ const message = attempt.message;
22116
+ const validOptionalString = (value) => value === null || value === undefined || typeof value === "string";
22117
+ if (message.type === "policyResult" && (message.decision === "allow" || message.decision === "deny" || message.decision === "instruct") && isStringArray(message.policyNames) && validOptionalString(message.reason) && isStringArray(message.matchedPolicies) && typeof message.durationMs === "number" && Number.isInteger(message.durationMs) && message.durationMs >= 0 && validOptionalString(message.toolName)) {
22118
+ return { ok: true };
22119
+ }
22120
+ return { ok: false, failure: "unreachable" };
22121
+ }
22048
22122
  var PROTOCOL_VERSION2 = 1, DAEMON_CONNECT_TIMEOUT_MS2 = 150, DAEMON_RESPONSE_TIMEOUT_MS2 = 30000, MAX_FRAME_LEN2;
22049
22123
  var init_daemon_client2 = __esm(() => {
22050
22124
  init_fp_home();
@@ -22054,7 +22128,7 @@ var init_daemon_client2 = __esm(() => {
22054
22128
 
22055
22129
  // src/hooks/daemon-service.ts
22056
22130
  import {
22057
- existsSync as existsSync22,
22131
+ existsSync as existsSync23,
22058
22132
  mkdirSync as mkdirSync11,
22059
22133
  mkdtempSync,
22060
22134
  readFileSync as readFileSync17,
@@ -22085,13 +22159,13 @@ function resolveFailproofaidBinaryPath() {
22085
22159
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
22086
22160
  return process.env.FAILPROOFAI_DAEMON_BINARY;
22087
22161
  const downloaded = installedBinaryPath();
22088
- if (existsSync22(downloaded))
22162
+ if (existsSync23(downloaded))
22089
22163
  return downloaded;
22090
22164
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
22091
22165
  if (packageRoot) {
22092
22166
  for (const profile of ["release", "debug"]) {
22093
22167
  const candidate = resolve18(packageRoot, "target", profile, "failproofaid");
22094
- if (existsSync22(candidate))
22168
+ if (existsSync23(candidate))
22095
22169
  return candidate;
22096
22170
  }
22097
22171
  }
@@ -22122,7 +22196,7 @@ function resolveWorkerCommand() {
22122
22196
  if (!packageRoot)
22123
22197
  return null;
22124
22198
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
22125
- if (!existsSync22(workerScript))
22199
+ if (!existsSync23(workerScript))
22126
22200
  return null;
22127
22201
  return `${shellQuote(process.execPath)} ${shellQuote(workerScript)}`;
22128
22202
  }
@@ -22133,7 +22207,7 @@ function resolveCliCommand() {
22133
22207
  if (!packageRoot)
22134
22208
  return null;
22135
22209
  const cliScript = resolve18(packageRoot, "dist", "cli.mjs");
22136
- if (!existsSync22(cliScript))
22210
+ if (!existsSync23(cliScript))
22137
22211
  return null;
22138
22212
  return `${shellQuote(process.execPath)} ${shellQuote(cliScript)}`;
22139
22213
  }
@@ -22147,7 +22221,7 @@ function workerScriptPath() {
22147
22221
  if (!packageRoot)
22148
22222
  return null;
22149
22223
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
22150
- return existsSync22(workerScript) ? workerScript : null;
22224
+ return existsSync23(workerScript) ? workerScript : null;
22151
22225
  }
22152
22226
  function assertUnitSafe(value, field) {
22153
22227
  if (UNIT_UNSAFE_RE.test(value)) {
@@ -22246,7 +22320,7 @@ function removeLegacyUserService() {
22246
22320
  try {
22247
22321
  if (process.platform === "linux") {
22248
22322
  const legacy = legacySystemdUserUnitPath();
22249
- if (!existsSync22(legacy))
22323
+ if (!existsSync23(legacy))
22250
22324
  return;
22251
22325
  try {
22252
22326
  execFileSync2("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -22263,7 +22337,7 @@ function removeLegacyUserService() {
22263
22337
  } catch {}
22264
22338
  } else {
22265
22339
  const legacyAgent = legacyLaunchAgentPlistPath();
22266
- if (existsSync22(legacyAgent)) {
22340
+ if (existsSync23(legacyAgent)) {
22267
22341
  try {
22268
22342
  execFileSync2("launchctl", ["unload", "-w", legacyAgent], {
22269
22343
  stdio: "ignore",
@@ -22273,7 +22347,7 @@ function removeLegacyUserService() {
22273
22347
  unlinkSync3(legacyAgent);
22274
22348
  }
22275
22349
  const legacyDaemon = legacySharedLaunchDaemonPath();
22276
- if (existsSync22(legacyDaemon)) {
22350
+ if (existsSync23(legacyDaemon)) {
22277
22351
  try {
22278
22352
  runPrivileged("launchctl", ["unload", "-w", legacyDaemon]);
22279
22353
  } catch {}
@@ -22290,7 +22364,7 @@ function systemdUnitContents(binaryPath, workerCmd, cliCmd = null) {
22290
22364
  const user = assertUnitSafe(serviceUser(), "User");
22291
22365
  assertUnitSafe(binaryPath, "ExecStart");
22292
22366
  assertUnitSafe(homedir22(), "HOME");
22293
- const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync22(p));
22367
+ const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync23(p));
22294
22368
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe(p, "ConditionPathExists")}
22295
22369
  `).join("");
22296
22370
  return `[Unit]
@@ -22457,6 +22531,24 @@ async function daemonAcceptsConnectionsQuietly() {
22457
22531
  async function probeDaemonEndToEnd() {
22458
22532
  return (await probeDaemon()).ok;
22459
22533
  }
22534
+ async function probeDaemonPolicyEvaluation() {
22535
+ if (!await probeDaemonEndToEnd())
22536
+ return false;
22537
+ try {
22538
+ await Promise.resolve().then(() => init_daemon_client2());
22539
+ const attempt = await attemptDaemonPolicyEvaluation({
22540
+ integration: "hermes",
22541
+ event: "on_session_start",
22542
+ payload: {
22543
+ hook_event_name: "on_session_start",
22544
+ source: "failproofai-native-policy-health-probe"
22545
+ }
22546
+ }, { responseTimeoutMs: DAEMON_PROBE_TIMEOUT_MS });
22547
+ return attempt.ok;
22548
+ } catch {
22549
+ return false;
22550
+ }
22551
+ }
22460
22552
  async function waitForDaemonRunning(deps = {}) {
22461
22553
  const status = deps.status ?? daemonServiceStatus;
22462
22554
  const accepts = deps.accepts ?? daemonAcceptsConnectionsQuietly;
@@ -22485,7 +22577,7 @@ function readInstalledServiceDefinition() {
22485
22577
  if (!isDaemonSupportedPlatform())
22486
22578
  return null;
22487
22579
  const path = daemonServiceFilePath();
22488
- if (!path || !existsSync22(path))
22580
+ if (!path || !existsSync23(path))
22489
22581
  return null;
22490
22582
  try {
22491
22583
  return readFileSync17(path, "utf8");
@@ -22621,7 +22713,7 @@ async function uninstallDaemonService() {
22621
22713
  try {
22622
22714
  if (process.platform === "linux") {
22623
22715
  const unitPath = systemdUnitPath();
22624
- if (!existsSync22(unitPath))
22716
+ if (!existsSync23(unitPath))
22625
22717
  return;
22626
22718
  try {
22627
22719
  runPrivileged("systemctl", ["disable", "--now", systemdUnitName()]);
@@ -22632,7 +22724,7 @@ async function uninstallDaemonService() {
22632
22724
  } catch {}
22633
22725
  } else {
22634
22726
  const plistPath = launchdPlistPath();
22635
- if (!existsSync22(plistPath))
22727
+ if (!existsSync23(plistPath))
22636
22728
  return;
22637
22729
  try {
22638
22730
  runPrivileged("launchctl", ["unload", "-w", plistPath]);
@@ -22649,7 +22741,7 @@ function daemonVersionSkew() {
22649
22741
  const recorded = readVersionFile()?.daemon;
22650
22742
  if (!recorded)
22651
22743
  return null;
22652
- if (!existsSync22(installedBinaryPath(recorded)))
22744
+ if (!existsSync23(installedBinaryPath(recorded)))
22653
22745
  return null;
22654
22746
  return recorded === version2 ? null : { installed: recorded, expected: version2 };
22655
22747
  }
@@ -22667,7 +22759,7 @@ function daemonServiceStatus() {
22667
22759
  if (!isDaemonSupportedPlatform())
22668
22760
  return "unsupported-platform";
22669
22761
  if (process.platform === "linux") {
22670
- if (!existsSync22(systemdUnitPath()))
22762
+ if (!existsSync23(systemdUnitPath()))
22671
22763
  return "not-installed";
22672
22764
  try {
22673
22765
  const out = execFileSync2("systemctl", ["is-active", systemdUnitName()], {
@@ -22680,7 +22772,7 @@ function daemonServiceStatus() {
22680
22772
  }
22681
22773
  }
22682
22774
  const plistPath = launchdPlistPath();
22683
- if (!existsSync22(plistPath))
22775
+ if (!existsSync23(plistPath))
22684
22776
  return "not-installed";
22685
22777
  try {
22686
22778
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -22712,7 +22804,7 @@ var init_daemon_service = __esm(() => {
22712
22804
  // src/hooks/fp-reset.ts
22713
22805
  import {
22714
22806
  copyFileSync,
22715
- existsSync as existsSync23,
22807
+ existsSync as existsSync24,
22716
22808
  mkdirSync as mkdirSync12,
22717
22809
  readFileSync as readFileSync18,
22718
22810
  readdirSync as readdirSync15,
@@ -22725,7 +22817,7 @@ import {
22725
22817
  import { dirname as dirname11, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
22726
22818
  function migrateConventionPolicies() {
22727
22819
  const from = legacy.customPoliciesDir();
22728
- if (!existsSync23(from))
22820
+ if (!existsSync24(from))
22729
22821
  return [];
22730
22822
  const moved = [];
22731
22823
  const mergeInto = (dir, dest, prefix) => {
@@ -22746,7 +22838,7 @@ function migrateConventionPolicies() {
22746
22838
  const source = resolve19(dir, entry.name);
22747
22839
  const target = resolve19(dest, entry.name);
22748
22840
  const name = `${prefix}${entry.name}`;
22749
- if (!existsSync23(target)) {
22841
+ if (!existsSync24(target)) {
22750
22842
  try {
22751
22843
  renameSync7(source, target);
22752
22844
  moved.push(name);
@@ -22773,7 +22865,7 @@ function migrateLegacySpool() {
22773
22865
  [legacy.spoolDir(), spoolDir()],
22774
22866
  [legacy.failedDir(), failedDir()]
22775
22867
  ]) {
22776
- if (!existsSync23(from))
22868
+ if (!existsSync24(from))
22777
22869
  continue;
22778
22870
  try {
22779
22871
  mkdirSync12(to, { recursive: true });
@@ -22782,7 +22874,7 @@ function migrateLegacySpool() {
22782
22874
  continue;
22783
22875
  let name = entry.name;
22784
22876
  let n = 0;
22785
- while (existsSync23(resolve19(to, name)))
22877
+ while (existsSync24(resolve19(to, name)))
22786
22878
  name = `legacy-${n++}-${entry.name}`;
22787
22879
  try {
22788
22880
  renameSync7(resolve19(from, entry.name), resolve19(to, name));
@@ -22800,7 +22892,7 @@ function migrateLegacySpool() {
22800
22892
  }
22801
22893
  function migrateHookActivity() {
22802
22894
  const from = legacy.hookActivityDir();
22803
- if (!existsSync23(from))
22895
+ if (!existsSync24(from))
22804
22896
  return [];
22805
22897
  const moved = [];
22806
22898
  try {
@@ -22815,7 +22907,7 @@ function migrateHookActivity() {
22815
22907
  const source = resolve19(from, entry.name);
22816
22908
  let name = entry.name === "current.jsonl" ? `page-${stamp}-${seq++}.jsonl` : entry.name;
22817
22909
  let target = resolve19(to, name);
22818
- while (existsSync23(target)) {
22910
+ while (existsSync24(target)) {
22819
22911
  name = `page-${stamp}-${seq++}.jsonl`;
22820
22912
  target = resolve19(to, name);
22821
22913
  }
@@ -22866,7 +22958,7 @@ function retirePolicyConfigKeys() {
22866
22958
  }
22867
22959
  function readCarriedPolicyConfig() {
22868
22960
  const from = resolve19(legacy.localPoliciesDir(), "policies-config.json");
22869
- if (!existsSync23(from))
22961
+ if (!existsSync24(from))
22870
22962
  return null;
22871
22963
  let parsed;
22872
22964
  try {
@@ -22930,7 +23022,7 @@ function writeCarriedPolicyConfig(carried) {
22930
23022
  }
22931
23023
  function readCarriedTelemetryOptOut() {
22932
23024
  const from = legacy.configToml();
22933
- if (!existsSync23(from))
23025
+ if (!existsSync24(from))
22934
23026
  return false;
22935
23027
  try {
22936
23028
  const text = readFileSync18(from, "utf8");
@@ -22985,7 +23077,7 @@ function parseLegacyToml(text) {
22985
23077
  }
22986
23078
  function readCarriedLegacyConfig() {
22987
23079
  const from = legacy.configToml();
22988
- if (!existsSync23(from))
23080
+ if (!existsSync24(from))
22989
23081
  return null;
22990
23082
  try {
22991
23083
  return projectConfig(parseLegacyToml(readFileSync18(from, "utf8")));
@@ -22995,7 +23087,7 @@ function readCarriedLegacyConfig() {
22995
23087
  }
22996
23088
  function readCarriedLegacyCredentials() {
22997
23089
  const toml = legacy.credentialsToml();
22998
- if (existsSync23(toml)) {
23090
+ if (existsSync24(toml)) {
22999
23091
  try {
23000
23092
  const creds = projectCredentials(parseLegacyToml(readFileSync18(toml, "utf8")));
23001
23093
  if (Object.keys(creds).length > 0)
@@ -23038,7 +23130,7 @@ function resetHome(from, to = LAYOUT_VERSION) {
23038
23130
  const spooled = migrateLegacySpool();
23039
23131
  const removed = [];
23040
23132
  for (const path of resettablePaths()) {
23041
- if (!existsSync23(path))
23133
+ if (!existsSync24(path))
23042
23134
  continue;
23043
23135
  try {
23044
23136
  rmSync8(path, { recursive: true, force: true });
@@ -23063,7 +23155,7 @@ function layoutWarningForHook() {
23063
23155
  if (state.kind === "future") {
23064
23156
  return `[failproofai] this directory was written by a newer version (layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
23065
23157
  }
23066
- if (existsSync23(globalPolicyConfigFile()))
23158
+ if (existsSync24(globalPolicyConfigFile()))
23067
23159
  return null;
23068
23160
  return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
23069
23161
  }
@@ -24124,14 +24216,14 @@ var init_collector_config = __esm(() => {
24124
24216
  });
24125
24217
 
24126
24218
  // src/hooks/flush-cli.ts
24127
- import { existsSync as existsSync24, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, readdirSync as readdirSync16 } from "node:fs";
24219
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, writeFileSync as writeFileSync11, readdirSync as readdirSync16 } from "node:fs";
24128
24220
  import { dirname as dirname12, join as join31 } from "node:path";
24129
24221
  function flushRequestPath(home) {
24130
24222
  return join31(failproofaiHome(home), "state", "flush-request.json");
24131
24223
  }
24132
24224
  function spoolDirs(home) {
24133
24225
  const root = spoolDir(home);
24134
- if (!existsSync24(root))
24226
+ if (!existsSync25(root))
24135
24227
  return [];
24136
24228
  try {
24137
24229
  return readdirSync16(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join31(root, e.name));
@@ -24235,7 +24327,7 @@ var init_flush_cli = __esm(() => {
24235
24327
  import {
24236
24328
  chmodSync as chmodSync4,
24237
24329
  copyFileSync as copyFileSync2,
24238
- existsSync as existsSync25,
24330
+ existsSync as existsSync26,
24239
24331
  mkdirSync as mkdirSync14,
24240
24332
  readFileSync as readFileSync19,
24241
24333
  renameSync as renameSync8,
@@ -24258,9 +24350,9 @@ function migrateToLayout4() {
24258
24350
  }
24259
24351
  const migrated = [];
24260
24352
  for (const { from, to } of moves) {
24261
- if (!existsSync25(from))
24353
+ if (!existsSync26(from))
24262
24354
  continue;
24263
- if (existsSync25(to)) {
24355
+ if (existsSync26(to)) {
24264
24356
  rmSync9(from, { force: true });
24265
24357
  continue;
24266
24358
  }
@@ -24281,7 +24373,7 @@ function migrateToLayout4() {
24281
24373
  migrated.push(`${basename5(from)} → audit/${basename5(to)}`);
24282
24374
  }
24283
24375
  for (const secret of [auditSessionFile()]) {
24284
- if (!existsSync25(secret))
24376
+ if (!existsSync26(secret))
24285
24377
  continue;
24286
24378
  try {
24287
24379
  chmodSync4(secret, 384);
@@ -24329,10 +24421,10 @@ function pruneMigratedCredentials(from) {
24329
24421
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
24330
24422
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS) {
24331
24423
  try {
24332
- if (!existsSync25(landsAt()))
24424
+ if (!existsSync26(landsAt()))
24333
24425
  continue;
24334
24426
  const copy = resolve20(migrationBackupDir(layout), as);
24335
- if (!existsSync25(copy))
24427
+ if (!existsSync26(copy))
24336
24428
  continue;
24337
24429
  rmSync9(copy, { force: true });
24338
24430
  pruned.push(as);
@@ -24345,7 +24437,7 @@ function filesToBackUp() {
24345
24437
  const seen = new Map;
24346
24438
  for (const f of [...BACKED_UP, ...BACKED_UP_LEGACY]) {
24347
24439
  const path = f.at();
24348
- if (existsSync25(path))
24440
+ if (existsSync26(path))
24349
24441
  seen.set(path, backupNameOf(f));
24350
24442
  }
24351
24443
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -24735,7 +24827,7 @@ var NAMESPACE3 = "failproofai-telemetry-v1", API_KEY3 = "phc_Ac1Ww1GqKc0z1SyrRWb
24735
24827
  var init_install_telemetry = () => {};
24736
24828
 
24737
24829
  // lib/install-check.ts
24738
- import { existsSync as existsSync26, readFileSync as readFileSync21, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
24830
+ import { existsSync as existsSync27, readFileSync as readFileSync21, writeFileSync as writeFileSync14, mkdirSync as mkdirSync16 } from "node:fs";
24739
24831
  import { dirname as dirname14, resolve as resolve21 } from "node:path";
24740
24832
  import { platform as platform2, arch as arch2, release, homedir as homedir24, hostname as hostname2 } from "node:os";
24741
24833
  import { createHmac as createHmac2 } from "node:crypto";
@@ -24791,7 +24883,7 @@ function compareSemver(a, b) {
24791
24883
  }
24792
24884
  function checkHooks() {
24793
24885
  const hooksConfigPath = globalPolicyConfigFile();
24794
- if (!existsSync26(hooksConfigPath)) {
24886
+ if (!existsSync27(hooksConfigPath)) {
24795
24887
  return { configured: false, registered: false, policyCount: 0 };
24796
24888
  }
24797
24889
  let config;
@@ -24805,7 +24897,7 @@ function checkHooks() {
24805
24897
  }
24806
24898
  const policyCount = config.enabledPolicies.length;
24807
24899
  const settingsPath = resolve21(homedir24(), ".claude", "settings.json");
24808
- if (!existsSync26(settingsPath))
24900
+ if (!existsSync27(settingsPath))
24809
24901
  return { configured: true, registered: false, policyCount };
24810
24902
  let settings;
24811
24903
  try {
@@ -24833,7 +24925,7 @@ async function maybeReportInstall(version) {
24833
24925
  const versionFile = lastVersionPath();
24834
24926
  let previousVersion = null;
24835
24927
  try {
24836
- if (existsSync26(versionFile)) {
24928
+ if (existsSync27(versionFile)) {
24837
24929
  previousVersion = readFileSync21(versionFile, "utf8").trim() || null;
24838
24930
  }
24839
24931
  } catch {}
@@ -24921,7 +25013,7 @@ var init_cli_error = __esm(() => {
24921
25013
 
24922
25014
  // src/hooks/manager.ts
24923
25015
  import { execSync as execSync6 } from "node:child_process";
24924
- import { existsSync as existsSync27 } from "node:fs";
25016
+ import { existsSync as existsSync28 } from "node:fs";
24925
25017
  import { resolve as resolve22, basename as basename6 } from "node:path";
24926
25018
  import { platform as platform3, arch as arch3, release as release2, hostname as hostname3 } from "node:os";
24927
25019
  function getSettingsPath(scope, cwd) {
@@ -25108,8 +25200,11 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
25108
25200
  }
25109
25201
  }
25110
25202
  const selectedClis = cli && cli.length > 0 ? [...new Set(cli)] : ["claude"];
25111
- for (const cliId of selectedClis) {
25112
- const integration = getIntegration(cliId);
25203
+ const selectedIntegrations = selectedClis.map((cliId) => ({
25204
+ cliId,
25205
+ integration: getIntegration(cliId)
25206
+ }));
25207
+ for (const { cliId, integration } of selectedIntegrations) {
25113
25208
  if (!integration.scopes.includes(scope)) {
25114
25209
  try {
25115
25210
  await trackHookEvent2(getInstanceId2(), "scope_validation_failed", {
@@ -25121,6 +25216,13 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
25121
25216
  throw new CliError(`Scope "${scope}" is not supported by ${integration.displayName}. ` + `Valid scopes: ${integration.scopes.join(", ")}`);
25122
25217
  }
25123
25218
  }
25219
+ const daemonRequiredBy = selectedIntegrations.map(({ integration }) => integration).filter((integration) => integration.requiresHealthyDaemon);
25220
+ if (daemonRequiredBy.length > 0 && !await probeDaemonPolicyEvaluation()) {
25221
+ const names = daemonRequiredBy.map((integration) => integration.displayName).join(", ");
25222
+ const verb = daemonRequiredBy.length === 1 ? "requires" : "require";
25223
+ throw new CliError(`${names} ${verb} a compatible failproofaid daemon with native policy evaluation before FailproofAI enforcement can be enabled.
25224
+ ` + "Run `failproofai config` to install or update the daemon, then retry.");
25225
+ }
25124
25226
  const binaryPath = resolveFailproofaiBinary();
25125
25227
  const previousConfig = readScopedHooksConfig(scope, cwd);
25126
25228
  const previousEnabled = new Set(previousConfig.enabledPolicies);
@@ -25143,7 +25245,7 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
25143
25245
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
25144
25246
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve22(path));
25145
25247
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve22(path)).filter((path) => {
25146
- if (existsSync27(path))
25248
+ if (existsSync28(path))
25147
25249
  return true;
25148
25250
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
25149
25251
  return false;
@@ -25371,7 +25473,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
25371
25473
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
25372
25474
  for (const s of scopesToRemove) {
25373
25475
  const settingsPaths = settingsPathsFor(integration, s, cwd);
25374
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync27(p));
25476
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync28(p));
25375
25477
  if (existing.length === 0) {
25376
25478
  if (scope !== "all" && selectedClis.length === 1) {
25377
25479
  console.log("No settings file found. Nothing to remove.");
@@ -25454,6 +25556,7 @@ var init_manager = __esm(() => {
25454
25556
  init_pack_store();
25455
25557
  init_pack_manifest();
25456
25558
  init_policy_evaluator();
25559
+ init_daemon_service();
25457
25560
  init_tui();
25458
25561
  VALID_POLICY_NAMES = new Set(BUILTIN_POLICIES.map((p) => p.name));
25459
25562
  });
@@ -25474,7 +25577,7 @@ var DEFAULT_FETCH_TIMEOUT_MS = 15000;
25474
25577
 
25475
25578
  // src/hooks/cloud-enrollment.ts
25476
25579
  import { randomUUID as randomUUID3 } from "node:crypto";
25477
- import { existsSync as existsSync28, readFileSync as readFileSync22, rmSync as rmSync10 } from "node:fs";
25580
+ import { existsSync as existsSync29, readFileSync as readFileSync22, rmSync as rmSync10 } from "node:fs";
25478
25581
  import { hostname as hostname4 } from "node:os";
25479
25582
  function cloudCredentialPath() {
25480
25583
  return process.env.FAILPROOFAI_CLOUD_CREDENTIALS ?? credentialsFile();
@@ -25513,7 +25616,7 @@ function readCloudCredentials() {
25513
25616
  if (!usingJsonOverride())
25514
25617
  return readCredentials().cloud ?? null;
25515
25618
  const path = cloudCredentialPath();
25516
- if (!existsSync28(path))
25619
+ if (!existsSync29(path))
25517
25620
  return null;
25518
25621
  try {
25519
25622
  const raw = JSON.parse(readFileSync22(path, "utf8"));
@@ -25555,7 +25658,7 @@ function resolveMachineLabel(explicit) {
25555
25658
  function clearCloudCredentials() {
25556
25659
  if (usingJsonOverride()) {
25557
25660
  const path = cloudCredentialPath();
25558
- if (!existsSync28(path))
25661
+ if (!existsSync29(path))
25559
25662
  return false;
25560
25663
  try {
25561
25664
  rmSync10(path);
@@ -25806,7 +25909,7 @@ var init_cloud_connection = __esm(() => {
25806
25909
  });
25807
25910
 
25808
25911
  // src/hooks/setup-state.ts
25809
- import { existsSync as existsSync29, realpathSync as realpathSync2, statSync as statSync18 } from "node:fs";
25912
+ import { existsSync as existsSync30, realpathSync as realpathSync2, statSync as statSync18 } from "node:fs";
25810
25913
  import { dirname as dirname15, resolve as resolve23 } from "node:path";
25811
25914
  import { homedir as homedir25 } from "node:os";
25812
25915
  function globalConfigPath(home = homedir25()) {
@@ -25863,10 +25966,10 @@ function detectSetupState(cwd = process.cwd(), home = homedir25()) {
25863
25966
  cwd: resolvedCwd,
25864
25967
  home: resolvedHome,
25865
25968
  projectRoot,
25866
- hasGlobalConfig: existsSync29(globalConfigPath(resolvedHome)),
25867
- hasProjectConfig: projectRoot !== resolvedHome && existsSync29(projectConfigPath(projectRoot)),
25969
+ hasGlobalConfig: existsSync30(globalConfigPath(resolvedHome)),
25970
+ hasProjectConfig: projectRoot !== resolvedHome && existsSync30(projectConfigPath(projectRoot)),
25868
25971
  hasGlobalHooks: hasGlobalHooksInstalled(),
25869
- hasLegacyMarker: existsSync29(legacyMarkerPath(resolvedHome)),
25972
+ hasLegacyMarker: existsSync30(legacyMarkerPath(resolvedHome)),
25870
25973
  inHomeDir: resolvedCwd === resolvedHome
25871
25974
  };
25872
25975
  }
@@ -25883,11 +25986,11 @@ var init_setup_state = __esm(() => {
25883
25986
  });
25884
25987
 
25885
25988
  // src/hooks/onboarding-attempt.ts
25886
- import { existsSync as existsSync30, mkdirSync as mkdirSync17, readFileSync as readFileSync23, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
25989
+ import { existsSync as existsSync31, mkdirSync as mkdirSync17, readFileSync as readFileSync23, rmSync as rmSync11, writeFileSync as writeFileSync15 } from "node:fs";
25887
25990
  import { dirname as dirname16 } from "node:path";
25888
25991
  function readOnboardingAttempt() {
25889
25992
  const path = onboardingAttemptFile();
25890
- if (!existsSync30(path))
25993
+ if (!existsSync31(path))
25891
25994
  return null;
25892
25995
  try {
25893
25996
  const raw = JSON.parse(readFileSync23(path, "utf8"));
@@ -26020,7 +26123,7 @@ var init_onboarding_lock = __esm(() => {
26020
26123
  });
26021
26124
 
26022
26125
  // lib/claude-sessions.ts
26023
- import { readdirSync as readdirSync17, statSync as statSync19, existsSync as existsSync31 } from "node:fs";
26126
+ import { readdirSync as readdirSync17, statSync as statSync19, existsSync as existsSync32 } from "node:fs";
26024
26127
  import { join as join34, basename as basename7 } from "node:path";
26025
26128
  function getClaudeProjectsRoot() {
26026
26129
  return getClaudeProjectsPath();
@@ -26067,7 +26170,7 @@ function listClaudeTranscripts(project) {
26067
26170
  } catch {}
26068
26171
  } else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
26069
26172
  const subDir = join34(project.path, entry.name, "subagents");
26070
- if (!existsSync31(subDir))
26173
+ if (!existsSync32(subDir))
26071
26174
  continue;
26072
26175
  let subEntries;
26073
26176
  try {
@@ -27410,7 +27513,7 @@ var init_features = __esm(() => {
27410
27513
 
27411
27514
  // src/audit/cache.ts
27412
27515
  import { createHash as createHash8 } from "node:crypto";
27413
- import { existsSync as existsSync32, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync17, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27516
+ import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync25, writeFileSync as writeFileSync17, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27414
27517
  import { join as join35 } from "node:path";
27415
27518
  function getEngineVersion() {
27416
27519
  if (cachedEngineVersion)
@@ -27471,7 +27574,7 @@ function readCachedTranscript(transcriptPath, mtimeMs, sizeBytes) {
27471
27574
  if (sizeBytes === 0)
27472
27575
  return null;
27473
27576
  const cachePath = getCachePathFor(transcriptPath);
27474
- if (!existsSync32(cachePath))
27577
+ if (!existsSync33(cachePath))
27475
27578
  return null;
27476
27579
  try {
27477
27580
  const raw = readFileSync25(cachePath, "utf-8");
@@ -28091,7 +28194,7 @@ var init_audit_lock = __esm(() => {
28091
28194
  });
28092
28195
 
28093
28196
  // src/audit/dashboard-cache.ts
28094
- import { existsSync as existsSync33, readFileSync as readFileSync27 } from "node:fs";
28197
+ import { existsSync as existsSync34, readFileSync as readFileSync27 } from "node:fs";
28095
28198
  function getCachePath() {
28096
28199
  return auditDashboardFile();
28097
28200
  }
@@ -28111,7 +28214,7 @@ function writeDashboardCache(params, result) {
28111
28214
  }
28112
28215
  function readDashboardCacheMeta() {
28113
28216
  const cachePath = getCachePath();
28114
- if (!existsSync33(cachePath))
28217
+ if (!existsSync34(cachePath))
28115
28218
  return null;
28116
28219
  try {
28117
28220
  const raw = readFileSync27(cachePath, "utf-8");
@@ -28338,7 +28441,7 @@ var init_api_server_client = __esm(() => {
28338
28441
  });
28339
28442
 
28340
28443
  // lib/auth/auth-store.ts
28341
- import { existsSync as existsSync34, readFileSync as readFileSync28, readdirSync as readdirSync18, rmSync as rmSync13 } from "node:fs";
28444
+ import { existsSync as existsSync35, readFileSync as readFileSync28, readdirSync as readdirSync18, rmSync as rmSync13 } from "node:fs";
28342
28445
  import { join as join36, resolve as resolve24 } from "node:path";
28343
28446
  function getAuthFilePath() {
28344
28447
  const override = process.env.FAILPROOFAI_AUTH_DIR;
@@ -28346,7 +28449,7 @@ function getAuthFilePath() {
28346
28449
  }
28347
28450
  function readAuth() {
28348
28451
  const p = getAuthFilePath();
28349
- if (!existsSync34(p))
28452
+ if (!existsSync35(p))
28350
28453
  return null;
28351
28454
  try {
28352
28455
  const raw = readFileSync28(p, "utf-8");
@@ -28373,17 +28476,17 @@ function writeAuth(auth) {
28373
28476
  }
28374
28477
  function deleteAuth() {
28375
28478
  const p = getAuthFilePath();
28376
- if (existsSync34(p))
28479
+ if (existsSync35(p))
28377
28480
  rmSync13(p, { force: true });
28378
28481
  try {
28379
28482
  const root = migrationsDir();
28380
- if (!existsSync34(root))
28483
+ if (!existsSync35(root))
28381
28484
  return;
28382
28485
  for (const entry of readdirSync18(root)) {
28383
28486
  if (!entry.startsWith("backup-layout"))
28384
28487
  continue;
28385
28488
  const copy = resolve24(root, entry, "auth.json");
28386
- if (existsSync34(copy))
28489
+ if (existsSync35(copy))
28387
28490
  rmSync13(copy, { force: true });
28388
28491
  }
28389
28492
  } catch {}
@@ -28634,12 +28737,12 @@ var init_harm_report = __esm(() => {
28634
28737
  });
28635
28738
 
28636
28739
  // src/audit/machine-store.ts
28637
- import { existsSync as existsSync35, readFileSync as readFileSync29, rmSync as rmSync14 } from "node:fs";
28740
+ import { existsSync as existsSync36, readFileSync as readFileSync29, rmSync as rmSync14 } from "node:fs";
28638
28741
  import { hostname as hostname5 } from "node:os";
28639
28742
  import { randomUUID as randomUUID4 } from "node:crypto";
28640
28743
  function readMachineIdentity(home) {
28641
28744
  const path = auditMachineFile(home);
28642
- if (!existsSync35(path))
28745
+ if (!existsSync36(path))
28643
28746
  return null;
28644
28747
  try {
28645
28748
  const parsed = JSON.parse(readFileSync29(path, "utf8"));
@@ -28964,7 +29067,7 @@ var init_cli = __esm(() => {
28964
29067
  });
28965
29068
 
28966
29069
  // src/hooks/configure-wizard.ts
28967
- import { existsSync as existsSync36, mkdirSync as mkdirSync21, writeFileSync as writeFileSync19, readFileSync as readFileSync30 } from "node:fs";
29070
+ import { existsSync as existsSync37, mkdirSync as mkdirSync21, writeFileSync as writeFileSync19, readFileSync as readFileSync30 } from "node:fs";
28968
29071
  import { homedir as homedir28 } from "node:os";
28969
29072
  import { dirname as dirname17, resolve as resolve25, sep as sep5 } from "node:path";
28970
29073
  async function emit(event, props) {
@@ -28989,7 +29092,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
28989
29092
  const path = getConfigPathForScope(scope, cwd);
28990
29093
  let config = {};
28991
29094
  try {
28992
- if (existsSync36(path))
29095
+ if (existsSync37(path))
28993
29096
  config = JSON.parse(readFileSync30(path, "utf8"));
28994
29097
  } catch {
28995
29098
  return;
@@ -29626,14 +29729,14 @@ var init_configure_wizard = __esm(() => {
29626
29729
  });
29627
29730
 
29628
29731
  // src/hooks/flush-cli.ts
29629
- import { existsSync as existsSync37, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readdirSync as readdirSync19 } from "node:fs";
29732
+ import { existsSync as existsSync38, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readdirSync as readdirSync19 } from "node:fs";
29630
29733
  import { dirname as dirname18, join as join37 } from "node:path";
29631
29734
  function flushRequestPath2(home) {
29632
29735
  return join37(failproofaiHome(home), "state", "flush-request.json");
29633
29736
  }
29634
29737
  function spoolDirs2(home) {
29635
29738
  const root = spoolDir(home);
29636
- if (!existsSync37(root))
29739
+ if (!existsSync38(root))
29637
29740
  return [];
29638
29741
  try {
29639
29742
  return readdirSync19(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join37(root, e.name));
@@ -29734,7 +29837,7 @@ var init_flush_cli2 = __esm(() => {
29734
29837
  });
29735
29838
 
29736
29839
  // src/hooks/backfill-cli.ts
29737
- import { existsSync as existsSync38, mkdirSync as mkdirSync23, writeFileSync as writeFileSync21, readdirSync as readdirSync20, statSync as statSync24 } from "node:fs";
29840
+ import { existsSync as existsSync39, mkdirSync as mkdirSync23, writeFileSync as writeFileSync21, readdirSync as readdirSync20, statSync as statSync24 } from "node:fs";
29738
29841
  import { dirname as dirname19, join as join38 } from "node:path";
29739
29842
  function backfillRequestPath(home) {
29740
29843
  return join38(failproofaiHome(home), "state", "backfill-request.json");
@@ -29743,7 +29846,7 @@ function surveySessions(sinceMs, homeDir) {
29743
29846
  const out = [];
29744
29847
  for (const { cli, dir } of SESSION_DIRS) {
29745
29848
  const root = join38(homeDir, dir);
29746
- if (!existsSync38(root))
29849
+ if (!existsSync39(root))
29747
29850
  continue;
29748
29851
  let files = 0;
29749
29852
  let newest = 0;
@@ -29781,7 +29884,7 @@ function runBackfillCommand(opts = {}) {
29781
29884
  const now = opts.now ?? Date.now();
29782
29885
  const sinceMs = opts.sinceMs ?? now - DEFAULT_BACKFILL_DAYS * 24 * 60 * 60 * 1000;
29783
29886
  const home = failproofaiHome();
29784
- if (!existsSync38(home)) {
29887
+ if (!existsSync39(home)) {
29785
29888
  return {
29786
29889
  exitCode: 1,
29787
29890
  lines: [`No failproofai home at ${home}. Run \`failproofai config\` first.`]
@@ -30112,7 +30215,7 @@ var init_harness_cli = __esm(() => {
30112
30215
  });
30113
30216
 
30114
30217
  // src/hooks/fp-config.ts
30115
- import { chmodSync as chmodSync6, existsSync as existsSync39, mkdirSync as mkdirSync24, readFileSync as readFileSync31, statSync as statSync25, writeFileSync as writeFileSync22 } from "node:fs";
30218
+ import { chmodSync as chmodSync6, existsSync as existsSync40, mkdirSync as mkdirSync24, readFileSync as readFileSync31, statSync as statSync25, writeFileSync as writeFileSync22 } from "node:fs";
30116
30219
  function detectLayout2() {
30117
30220
  const raw = readVersionFile2();
30118
30221
  if (raw) {
@@ -30120,17 +30223,17 @@ function detectLayout2() {
30120
30223
  return { kind: "current", version: raw };
30121
30224
  return raw.layout > LAYOUT_VERSION ? { kind: "future", found: raw.layout } : { kind: "stale", found: raw.layout };
30122
30225
  }
30123
- if (existsSync39(configFile())) {
30226
+ if (existsSync40(configFile())) {
30124
30227
  const layoutThreePositions = [
30125
30228
  legacy.authJson(),
30126
30229
  legacy.nextAudit(),
30127
30230
  legacy.auditSchedule()
30128
30231
  ];
30129
- if (layoutThreePositions.some((p) => existsSync39(p)))
30232
+ if (layoutThreePositions.some((p) => existsSync40(p)))
30130
30233
  return { kind: "stale", found: 3 };
30131
30234
  return { kind: "current", version: { layout: LAYOUT_VERSION, cli: "" }, inferred: true };
30132
30235
  }
30133
- if (existsSync39(legacy.configToml()))
30236
+ if (existsSync40(legacy.configToml()))
30134
30237
  return { kind: "stale", found: 2 };
30135
30238
  const layoutOneMarkers = [
30136
30239
  legacy.policyConfig(),
@@ -30141,7 +30244,7 @@ function detectLayout2() {
30141
30244
  legacy.ingestCredentials(),
30142
30245
  legacy.auditDashboard()
30143
30246
  ];
30144
- return layoutOneMarkers.some((p) => existsSync39(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
30247
+ return layoutOneMarkers.some((p) => existsSync40(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
30145
30248
  }
30146
30249
  function readLegacyTomlVersion2(text) {
30147
30250
  const layout = Number(/^\s*layout\s*=\s*(\d+)\s*$/m.exec(text)?.[1]);
@@ -30184,7 +30287,7 @@ var init_fp_home2 = () => {};
30184
30287
  import {
30185
30288
  chmodSync as chmodSync7,
30186
30289
  copyFileSync as copyFileSync3,
30187
- existsSync as existsSync40,
30290
+ existsSync as existsSync41,
30188
30291
  mkdirSync as mkdirSync25,
30189
30292
  readFileSync as readFileSync32,
30190
30293
  renameSync as renameSync9,
@@ -30207,9 +30310,9 @@ function migrateToLayout42() {
30207
30310
  }
30208
30311
  const migrated = [];
30209
30312
  for (const { from, to } of moves) {
30210
- if (!existsSync40(from))
30313
+ if (!existsSync41(from))
30211
30314
  continue;
30212
- if (existsSync40(to)) {
30315
+ if (existsSync41(to)) {
30213
30316
  rmSync15(from, { force: true });
30214
30317
  continue;
30215
30318
  }
@@ -30230,7 +30333,7 @@ function migrateToLayout42() {
30230
30333
  migrated.push(`${basename8(from)} → audit/${basename8(to)}`);
30231
30334
  }
30232
30335
  for (const secret of [auditSessionFile()]) {
30233
- if (!existsSync40(secret))
30336
+ if (!existsSync41(secret))
30234
30337
  continue;
30235
30338
  try {
30236
30339
  chmodSync7(secret, 384);
@@ -30278,10 +30381,10 @@ function pruneMigratedCredentials2(from) {
30278
30381
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
30279
30382
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS2) {
30280
30383
  try {
30281
- if (!existsSync40(landsAt()))
30384
+ if (!existsSync41(landsAt()))
30282
30385
  continue;
30283
30386
  const copy = resolve27(migrationBackupDir(layout), as);
30284
- if (!existsSync40(copy))
30387
+ if (!existsSync41(copy))
30285
30388
  continue;
30286
30389
  rmSync15(copy, { force: true });
30287
30390
  pruned.push(as);
@@ -30294,7 +30397,7 @@ function filesToBackUp2() {
30294
30397
  const seen = new Map;
30295
30398
  for (const f of [...BACKED_UP2, ...BACKED_UP_LEGACY2]) {
30296
30399
  const path = f.at();
30297
- if (existsSync40(path))
30400
+ if (existsSync41(path))
30298
30401
  seen.set(path, backupNameOf2(f));
30299
30402
  }
30300
30403
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -30448,7 +30551,7 @@ var init_migrations2 = __esm(() => {
30448
30551
 
30449
30552
  // src/hooks/daemon-service.ts
30450
30553
  import {
30451
- existsSync as existsSync41,
30554
+ existsSync as existsSync42,
30452
30555
  mkdirSync as mkdirSync26,
30453
30556
  mkdtempSync as mkdtempSync2,
30454
30557
  readFileSync as readFileSync33,
@@ -30473,13 +30576,13 @@ function resolveFailproofaidBinaryPath2() {
30473
30576
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
30474
30577
  return process.env.FAILPROOFAI_DAEMON_BINARY;
30475
30578
  const downloaded = installedBinaryPath();
30476
- if (existsSync41(downloaded))
30579
+ if (existsSync42(downloaded))
30477
30580
  return downloaded;
30478
30581
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
30479
30582
  if (packageRoot) {
30480
30583
  for (const profile of ["release", "debug"]) {
30481
30584
  const candidate = resolve28(packageRoot, "target", profile, "failproofaid");
30482
- if (existsSync41(candidate))
30585
+ if (existsSync42(candidate))
30483
30586
  return candidate;
30484
30587
  }
30485
30588
  }
@@ -30510,7 +30613,7 @@ function resolveWorkerCommand2() {
30510
30613
  if (!packageRoot)
30511
30614
  return null;
30512
30615
  const workerScript = resolve28(packageRoot, "dist", "worker.mjs");
30513
- if (!existsSync41(workerScript))
30616
+ if (!existsSync42(workerScript))
30514
30617
  return null;
30515
30618
  return `${shellQuote2(process.execPath)} ${shellQuote2(workerScript)}`;
30516
30619
  }
@@ -30521,7 +30624,7 @@ function resolveCliCommand2() {
30521
30624
  if (!packageRoot)
30522
30625
  return null;
30523
30626
  const cliScript = resolve28(packageRoot, "dist", "cli.mjs");
30524
- if (!existsSync41(cliScript))
30627
+ if (!existsSync42(cliScript))
30525
30628
  return null;
30526
30629
  return `${shellQuote2(process.execPath)} ${shellQuote2(cliScript)}`;
30527
30630
  }
@@ -30535,7 +30638,7 @@ function workerScriptPath2() {
30535
30638
  if (!packageRoot)
30536
30639
  return null;
30537
30640
  const workerScript = resolve28(packageRoot, "dist", "worker.mjs");
30538
- return existsSync41(workerScript) ? workerScript : null;
30641
+ return existsSync42(workerScript) ? workerScript : null;
30539
30642
  }
30540
30643
  function assertUnitSafe2(value, field) {
30541
30644
  if (UNIT_UNSAFE_RE2.test(value)) {
@@ -30624,7 +30727,7 @@ function removeLegacyUserService2() {
30624
30727
  try {
30625
30728
  if (process.platform === "linux") {
30626
30729
  const legacy = legacySystemdUserUnitPath2();
30627
- if (!existsSync41(legacy))
30730
+ if (!existsSync42(legacy))
30628
30731
  return;
30629
30732
  try {
30630
30733
  execFileSync3("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -30641,7 +30744,7 @@ function removeLegacyUserService2() {
30641
30744
  } catch {}
30642
30745
  } else {
30643
30746
  const legacyAgent = legacyLaunchAgentPlistPath2();
30644
- if (existsSync41(legacyAgent)) {
30747
+ if (existsSync42(legacyAgent)) {
30645
30748
  try {
30646
30749
  execFileSync3("launchctl", ["unload", "-w", legacyAgent], {
30647
30750
  stdio: "ignore",
@@ -30651,7 +30754,7 @@ function removeLegacyUserService2() {
30651
30754
  unlinkSync5(legacyAgent);
30652
30755
  }
30653
30756
  const legacyDaemon = legacySharedLaunchDaemonPath2();
30654
- if (existsSync41(legacyDaemon)) {
30757
+ if (existsSync42(legacyDaemon)) {
30655
30758
  try {
30656
30759
  runPrivileged2("launchctl", ["unload", "-w", legacyDaemon]);
30657
30760
  } catch {}
@@ -30668,7 +30771,7 @@ function systemdUnitContents2(binaryPath, workerCmd, cliCmd = null) {
30668
30771
  const user = assertUnitSafe2(serviceUser2(), "User");
30669
30772
  assertUnitSafe2(binaryPath, "ExecStart");
30670
30773
  assertUnitSafe2(homedir30(), "HOME");
30671
- const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync41(p));
30774
+ const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync42(p));
30672
30775
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe2(p, "ConditionPathExists")}
30673
30776
  `).join("");
30674
30777
  return `[Unit]
@@ -30873,7 +30976,7 @@ function daemonServiceStatus2() {
30873
30976
  if (!isDaemonSupportedPlatform2())
30874
30977
  return "unsupported-platform";
30875
30978
  if (process.platform === "linux") {
30876
- if (!existsSync41(systemdUnitPath2()))
30979
+ if (!existsSync42(systemdUnitPath2()))
30877
30980
  return "not-installed";
30878
30981
  try {
30879
30982
  const out = execFileSync3("systemctl", ["is-active", systemdUnitName2()], {
@@ -30886,7 +30989,7 @@ function daemonServiceStatus2() {
30886
30989
  }
30887
30990
  }
30888
30991
  const plistPath = launchdPlistPath2();
30889
- if (!existsSync41(plistPath))
30992
+ if (!existsSync42(plistPath))
30890
30993
  return "not-installed";
30891
30994
  try {
30892
30995
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -30916,7 +31019,7 @@ var init_daemon_service2 = __esm(() => {
30916
31019
  });
30917
31020
 
30918
31021
  // src/hooks/uninstall-cli.ts
30919
- import { existsSync as existsSync42, rmSync as rmSync17 } from "node:fs";
31022
+ import { existsSync as existsSync43, rmSync as rmSync17 } from "node:fs";
30920
31023
  function survey(cwd) {
30921
31024
  const clis = [];
30922
31025
  for (const id of listInstallableIds()) {
@@ -30937,9 +31040,9 @@ function survey(cwd) {
30937
31040
  return {
30938
31041
  clis,
30939
31042
  servicePath,
30940
- serviceInstalled: !!servicePath && existsSync42(servicePath),
31043
+ serviceInstalled: !!servicePath && existsSync43(servicePath),
30941
31044
  daemonConfigured,
30942
- homeExists: existsSync42(failproofaiHome())
31045
+ homeExists: existsSync43(failproofaiHome())
30943
31046
  };
30944
31047
  }
30945
31048
  async function runUninstallCommand(opts = {}) {
@@ -31037,7 +31140,7 @@ async function runUninstallCommand(opts = {}) {
31037
31140
  } catch {}
31038
31141
  try {
31039
31142
  await uninstallDaemonService();
31040
- if (found.servicePath && existsSync42(found.servicePath)) {
31143
+ if (found.servicePath && existsSync43(found.servicePath)) {
31041
31144
  failures.push(`the service at ${found.servicePath} is still there (most often: no sudo). ` + `Remove it with the commands below.`);
31042
31145
  } else {
31043
31146
  lines.push(`✓ stopped and removed the daemon service`);
@@ -31060,7 +31163,7 @@ async function runUninstallCommand(opts = {}) {
31060
31163
  lines.push(``, `Not everything could be removed:`);
31061
31164
  for (const f of failures)
31062
31165
  lines.push(` ✗ ${f}`);
31063
- if (found.servicePath && existsSync42(found.servicePath)) {
31166
+ if (found.servicePath && existsSync43(found.servicePath)) {
31064
31167
  lines.push(``, `To remove the service by hand:`, ...manualServiceRemoval(found.servicePath), ``, `(\`${daemonStatusCommand()}\` shows its current state.)`);
31065
31168
  }
31066
31169
  return { exitCode: 1, lines, planLines, purged };
@@ -31094,7 +31197,7 @@ var init_uninstall_cli = __esm(() => {
31094
31197
  import { execFileSync as execFileSync4 } from "node:child_process";
31095
31198
  import { homedir as homedir31, tmpdir as tmpdir4 } from "node:os";
31096
31199
  import { createHash as createHash9 } from "node:crypto";
31097
- import { copyFileSync as copyFileSync4, existsSync as existsSync43, 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";
31200
+ 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";
31098
31201
  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";
31099
31202
  function parseList(rest, flag) {
31100
31203
  const idx = rest.findIndex((a) => a === flag || a.startsWith(`${flag}=`));
@@ -31209,7 +31312,7 @@ async function build(rest) {
31209
31312
  return fail2([err instanceof Error ? err.message : String(err)]);
31210
31313
  }
31211
31314
  const entryPath = resolve29(entry);
31212
- if (!existsSync43(entryPath))
31315
+ if (!existsSync44(entryPath))
31213
31316
  return fail2([`No such file: ${entryPath}`]);
31214
31317
  const source = readFileSync34(entryPath, "utf8");
31215
31318
  const localImport = /(?:^|\n)\s*(?:import|export)[^;\n]*from\s+["'](\.[^"']*)["']/.exec(source);
@@ -31404,7 +31507,7 @@ async function scaffold(target) {
31404
31507
  chosen = answer.trim();
31405
31508
  }
31406
31509
  const path = resolve29(withPolicyExtension(chosen ?? "my-policies"));
31407
- if (existsSync43(path)) {
31510
+ if (existsSync44(path)) {
31408
31511
  return fail2([`${path} already exists — name a different file, or edit that one.`]);
31409
31512
  }
31410
31513
  mkdirSync27(resolve29(path, ".."), { recursive: true });
@@ -32902,7 +33005,7 @@ var init_install_prompt = __esm(() => {
32902
33005
 
32903
33006
  // src/hooks/manager.ts
32904
33007
  import { execSync as execSync7 } from "node:child_process";
32905
- import { existsSync as existsSync44 } from "node:fs";
33008
+ import { existsSync as existsSync45 } from "node:fs";
32906
33009
  import { resolve as resolve30, basename as basename10 } from "node:path";
32907
33010
  import { platform as platform4, arch as arch4, release as release3, hostname as hostname6 } from "node:os";
32908
33011
  function getSettingsPath2(scope, cwd) {
@@ -33089,8 +33192,11 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
33089
33192
  }
33090
33193
  }
33091
33194
  const selectedClis = cli && cli.length > 0 ? [...new Set(cli)] : ["claude"];
33092
- for (const cliId of selectedClis) {
33093
- const integration = getIntegration(cliId);
33195
+ const selectedIntegrations = selectedClis.map((cliId) => ({
33196
+ cliId,
33197
+ integration: getIntegration(cliId)
33198
+ }));
33199
+ for (const { cliId, integration } of selectedIntegrations) {
33094
33200
  if (!integration.scopes.includes(scope)) {
33095
33201
  try {
33096
33202
  await trackHookEvent2(getInstanceId2(), "scope_validation_failed", {
@@ -33102,6 +33208,13 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
33102
33208
  throw new CliError(`Scope "${scope}" is not supported by ${integration.displayName}. ` + `Valid scopes: ${integration.scopes.join(", ")}`);
33103
33209
  }
33104
33210
  }
33211
+ const daemonRequiredBy = selectedIntegrations.map(({ integration }) => integration).filter((integration) => integration.requiresHealthyDaemon);
33212
+ if (daemonRequiredBy.length > 0 && !await probeDaemonPolicyEvaluation()) {
33213
+ const names = daemonRequiredBy.map((integration) => integration.displayName).join(", ");
33214
+ const verb = daemonRequiredBy.length === 1 ? "requires" : "require";
33215
+ throw new CliError(`${names} ${verb} a compatible failproofaid daemon with native policy evaluation before FailproofAI enforcement can be enabled.
33216
+ ` + "Run `failproofai config` to install or update the daemon, then retry.");
33217
+ }
33105
33218
  const binaryPath = resolveFailproofaiBinary2();
33106
33219
  const previousConfig = readScopedHooksConfig(scope, cwd);
33107
33220
  const previousEnabled = new Set(previousConfig.enabledPolicies);
@@ -33124,7 +33237,7 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
33124
33237
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
33125
33238
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve30(path));
33126
33239
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve30(path)).filter((path) => {
33127
- if (existsSync44(path))
33240
+ if (existsSync45(path))
33128
33241
  return true;
33129
33242
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
33130
33243
  return false;
@@ -33352,7 +33465,7 @@ async function removeHooks2(policyNames, scope = "user", cwd, opts) {
33352
33465
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
33353
33466
  for (const s of scopesToRemove) {
33354
33467
  const settingsPaths = settingsPathsFor(integration, s, cwd);
33355
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync44(p));
33468
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync45(p));
33356
33469
  if (existing.length === 0) {
33357
33470
  if (scope !== "all" && selectedClis.length === 1) {
33358
33471
  console.log("No settings file found. Nothing to remove.");
@@ -33498,7 +33611,7 @@ async function listHooks(cwd) {
33498
33611
  for (const path of explicitPaths) {
33499
33612
  const absPath = resolve30(findProjectConfigDir(cwd ?? process.cwd()), path);
33500
33613
  groups.push(note(absPath, opts));
33501
- if (!existsSync44(absPath)) {
33614
+ if (!existsSync45(absPath)) {
33502
33615
  groups.push(warning([`file not found: ${absPath}`], opts));
33503
33616
  continue;
33504
33617
  }
@@ -33625,6 +33738,7 @@ var init_manager2 = __esm(() => {
33625
33738
  init_pack_store();
33626
33739
  init_pack_manifest();
33627
33740
  init_policy_evaluator();
33741
+ init_daemon_service();
33628
33742
  init_tui();
33629
33743
  VALID_POLICY_NAMES2 = new Set(BUILTIN_POLICIES.map((p) => p.name));
33630
33744
  });
@@ -34060,19 +34174,19 @@ function parseScriptArgs(argv) {
34060
34174
  var init_parse_script_args = () => {};
34061
34175
 
34062
34176
  // scripts/install-diagnosis.mjs
34063
- import { existsSync as existsSync45, readFileSync as readFileSync36, realpathSync as realpathSync4 } from "node:fs";
34177
+ import { existsSync as existsSync46, readFileSync as readFileSync36, realpathSync as realpathSync4 } from "node:fs";
34064
34178
  import { dirname as dirname22, resolve as resolve32 } from "node:path";
34065
34179
  import { homedir as homedir32, platform as platform5 } from "node:os";
34066
34180
  import { spawnSync } from "node:child_process";
34067
34181
  function findPackageRoot(start) {
34068
34182
  try {
34069
34183
  let dir = realpathSync4(start);
34070
- if (existsSync45(dir) && !existsSync45(resolve32(dir, "package.json"))) {
34184
+ if (existsSync46(dir) && !existsSync46(resolve32(dir, "package.json"))) {
34071
34185
  dir = dirname22(dir);
34072
34186
  }
34073
34187
  while (true) {
34074
34188
  const pkgPath = resolve32(dir, "package.json");
34075
- if (existsSync45(pkgPath)) {
34189
+ if (existsSync46(pkgPath)) {
34076
34190
  try {
34077
34191
  const pkg = JSON.parse(readFileSync36(pkgPath, "utf8"));
34078
34192
  if (pkg.name === PKG_NAME)
@@ -34119,7 +34233,7 @@ function locateNpmGlobal() {
34119
34233
  if (!root)
34120
34234
  return null;
34121
34235
  const candidate = resolve32(root, PKG_NAME);
34122
- return existsSync45(resolve32(candidate, "package.json")) ? candidate : null;
34236
+ return existsSync46(resolve32(candidate, "package.json")) ? candidate : null;
34123
34237
  } catch {
34124
34238
  return null;
34125
34239
  }
@@ -34127,7 +34241,7 @@ function locateNpmGlobal() {
34127
34241
  function locateBunGlobal() {
34128
34242
  try {
34129
34243
  const candidate = resolve32(homedir32(), ".bun", "install", "global", "node_modules", PKG_NAME);
34130
- return existsSync45(resolve32(candidate, "package.json")) ? candidate : null;
34244
+ return existsSync46(resolve32(candidate, "package.json")) ? candidate : null;
34131
34245
  } catch {
34132
34246
  return null;
34133
34247
  }
@@ -34230,7 +34344,7 @@ var init_dashboard_host = __esm(() => {
34230
34344
 
34231
34345
  // scripts/launch.ts
34232
34346
  import { spawn as spawn2 } from "child_process";
34233
- import { realpathSync as realpathSync5, existsSync as existsSync46 } from "node:fs";
34347
+ import { realpathSync as realpathSync5, existsSync as existsSync47 } from "node:fs";
34234
34348
  import { resolve as resolve33, dirname as dirname23 } from "node:path";
34235
34349
  import { fileURLToPath as fileURLToPath2 } from "node:url";
34236
34350
  import { createInterface } from "node:readline";
@@ -34257,7 +34371,7 @@ function launch(mode) {
34257
34371
  cmd = "node";
34258
34372
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve33(dirname23(realpathSync5(fileURLToPath2(import.meta.url))), "..");
34259
34373
  const serverJsPath = resolve33(packageRoot, ".next/standalone/server.js");
34260
- if (!existsSync46(serverJsPath)) {
34374
+ if (!existsSync47(serverJsPath)) {
34261
34375
  let shadowMessage = null;
34262
34376
  try {
34263
34377
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -35015,7 +35129,7 @@ import {
35015
35129
  cpSync as cpSync2,
35016
35130
  readFileSync as readFileSync37,
35017
35131
  writeFileSync as writeFileSync26,
35018
- existsSync as existsSync47,
35132
+ existsSync as existsSync48,
35019
35133
  lstatSync as lstatSync2,
35020
35134
  mkdirSync as mkdirSync28,
35021
35135
  renameSync as renameSync10,
@@ -35025,7 +35139,7 @@ import {
35025
35139
  import { resolve as resolve34, dirname as dirname24 } from "node:path";
35026
35140
  function readYamlDoc2(path) {
35027
35141
  try {
35028
- return existsSync47(path) ? $parseDocument(readFileSync37(path, "utf8")) : $parseDocument("");
35142
+ return existsSync48(path) ? $parseDocument(readFileSync37(path, "utf8")) : $parseDocument("");
35029
35143
  } catch {
35030
35144
  return $parseDocument("");
35031
35145
  }
@@ -35047,15 +35161,15 @@ function hasManagedHermesPlugin2(settingsPath) {
35047
35161
  try {
35048
35162
  if (lstatSync2(pluginPath).isSymbolicLink())
35049
35163
  return false;
35050
- if (!existsSync47(resolve34(pluginPath, HERMES_PLUGIN_MARKER2)))
35164
+ if (!existsSync48(resolve34(pluginPath, HERMES_PLUGIN_MARKER2)))
35051
35165
  return false;
35052
- return HERMES_PLUGIN_FILES2.every((file) => existsSync47(resolve34(pluginPath, file)));
35166
+ return HERMES_PLUGIN_FILES2.every((file) => existsSync48(resolve34(pluginPath, file)));
35053
35167
  } catch {
35054
35168
  return false;
35055
35169
  }
35056
35170
  }
35057
35171
  function hermesConfigState2(settingsPath) {
35058
- if (!existsSync47(settingsPath)) {
35172
+ if (!existsSync48(settingsPath)) {
35059
35173
  return { pluginEnabled: false, legacyShellHookPresent: false };
35060
35174
  }
35061
35175
  const doc = readYamlDoc2(settingsPath);
@@ -35084,7 +35198,7 @@ function hermesProfileHealth() {
35084
35198
  });
35085
35199
  }
35086
35200
  function hermesProfileStatusRows() {
35087
- return hermesProfileHealth().filter((profile) => existsSync47(profile.home)).map((profile) => {
35201
+ return hermesProfileHealth().filter((profile) => existsSync48(profile.home)).map((profile) => {
35088
35202
  const problems = [];
35089
35203
  if (!profile.pluginInstalled)
35090
35204
  problems.push("plugin files missing or incomplete");
@@ -35110,7 +35224,7 @@ var init_integrations2 = __esm(() => {
35110
35224
 
35111
35225
  // scripts/launch.ts
35112
35226
  import { spawn as spawn3 } from "child_process";
35113
- import { realpathSync as realpathSync6, existsSync as existsSync48 } from "node:fs";
35227
+ import { realpathSync as realpathSync6, existsSync as existsSync49 } from "node:fs";
35114
35228
  import { resolve as resolve35, dirname as dirname25 } from "node:path";
35115
35229
  import { fileURLToPath as fileURLToPath3 } from "node:url";
35116
35230
  import { createInterface as createInterface2 } from "node:readline";
@@ -35137,7 +35251,7 @@ function launch2(mode) {
35137
35251
  cmd = "node";
35138
35252
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve35(dirname25(realpathSync6(fileURLToPath3(import.meta.url))), "..");
35139
35253
  const serverJsPath = resolve35(packageRoot, ".next/standalone/server.js");
35140
- if (!existsSync48(serverJsPath)) {
35254
+ if (!existsSync49(serverJsPath)) {
35141
35255
  let shadowMessage = null;
35142
35256
  try {
35143
35257
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -35237,7 +35351,7 @@ import { realpathSync as realpathSync7 } from "fs";
35237
35351
  import { dirname as dirname26, resolve as resolve36 } from "path";
35238
35352
  import { fileURLToPath as fileURLToPath4 } from "url";
35239
35353
  // package.json
35240
- var version = "1.0.6-beta.0";
35354
+ var version = "1.0.6";
35241
35355
 
35242
35356
  // bin/failproofai.mjs
35243
35357
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {