failproofai 1.0.9-beta.0 → 1.0.9-beta.2

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 (145) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/index.html +1 -1
  36. package/.next/standalone/.next/server/app/index.rsc +14 -14
  37. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  38. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +1 -1
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  59. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  63. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  70. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_01r25oi._.js +2 -2
  71. package/.next/standalone/.next/server/chunks/node_modules_posthog-node_dist_entrypoints_index_node_mjs_09z9-p7._.js +2 -2
  72. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12e7nhs._.js → [root-of-the-server]__1-bm5zf._.js} +1 -1
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +2 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.js +2 -2
  81. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0tmz862._.js → [root-of-the-server]__1ox4w55._.js} +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1pprgri._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1q4p5b8._.js +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/_042cgl1._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  86. package/.next/standalone/.next/server/chunks/ssr/_0bqoto4._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/{_1p3iz2d._.js → _0n6zrjv._.js} +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/{_0n0lja6._.js → _1pa3k5k._.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 +2 -2
  92. package/.next/standalone/.next/server/chunks/ssr/app_actions_get-scheduled-audit_ts_0ei9sni._.js +1 -1
  93. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/app_settings_02tf1h4._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/node_modules_posthog-node_dist_entrypoints_index_node_mjs_11bnuzn._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/src_hooks_effective-reviewers_ts_1h4wtvo._.js +1 -1
  99. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  100. package/.next/standalone/.next/server/pages/404.html +1 -1
  101. package/.next/standalone/.next/server/pages/500.html +1 -1
  102. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  103. package/.next/standalone/.next/server/server-reference-manifest.json +23 -23
  104. package/.next/standalone/.next/static/chunks/{06jxjnw8bfczc.js → 0542cuk_va8g1.js} +1 -1
  105. package/.next/standalone/.next/static/chunks/{1h0if8ky362as.js → 0h--izcpk__m9.js} +1 -1
  106. package/.next/standalone/.next/static/chunks/{0snylg3y1i47a.js → 1srecm9k-z_i1.js} +1 -1
  107. package/.next/standalone/.next/static/chunks/{03001k9jy-kst.js → 28cmd5molgwa3.js} +1 -1
  108. package/.next/standalone/.next/static/chunks/{06k7gsfnb7jkh.js → 2b59i-n9l-4of.js} +1 -1
  109. package/.next/standalone/.next/static/chunks/{42m0f2hh8vfb1.js → 2k5vhij_w1g82.js} +1 -1
  110. package/.next/standalone/.next/static/chunks/2o1fy-waqn1he.js +6 -0
  111. package/.next/standalone/.next/static/chunks/{3rq7fjj9we0v3.js → 30z-240_lrczt.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/38gpf5tb_rd0m.js +1 -0
  113. package/.next/standalone/.next/static/chunks/3nyf50dub1vuk.js +1 -0
  114. package/.next/standalone/.next/static/chunks/{0qejem4-zt-hy.js → 42-l25bbfo0ec.js} +1 -1
  115. package/.next/standalone/.next/static/chunks/{turbopack-38nzuvp95_2rv.js → turbopack-11dn2pegmg9_9.js} +1 -1
  116. package/.next/standalone/fp-cloud-cli/uv.lock +3 -3
  117. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  118. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  119. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +1 -1
  120. package/.next/standalone/node_modules/next/dist/lib/patch-incorrect-lockfile.js +3 -3
  121. package/.next/standalone/node_modules/next/dist/server/config.js +1 -1
  122. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +2 -2
  123. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  124. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  125. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  126. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  127. package/.next/standalone/node_modules/next/dist/telemetry/events/swc-load-failure.js +1 -1
  128. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  129. package/.next/standalone/node_modules/next/package.json +10 -10
  130. package/.next/standalone/package.json +11 -11
  131. package/.next/standalone/sdk/python/uv.lock +18 -18
  132. package/.next/standalone/server.js +1 -1
  133. package/dist/cli.mjs +932 -725
  134. package/dist/worker.mjs +4 -1
  135. package/package.json +11 -11
  136. package/src/hooks/integrations.ts +152 -22
  137. package/src/hooks/jev-activity.ts +5 -0
  138. package/src/hooks/policy-reviewability.ts +4 -2
  139. package/src/hooks/safe-config-write.ts +119 -0
  140. package/.next/standalone/.next/static/chunks/0247hc9ath5t-.js +0 -1
  141. package/.next/standalone/.next/static/chunks/2qsrrrl2maqsb.js +0 -1
  142. package/.next/standalone/.next/static/chunks/3ns-egfh8i8i5.js +0 -6
  143. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → D1BjwOkHNPetPo47DhV4_}/_buildManifest.js +0 -0
  144. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → D1BjwOkHNPetPo47DhV4_}/_clientMiddlewareManifest.js +0 -0
  145. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → D1BjwOkHNPetPo47DhV4_}/_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.9-beta.0", package_default;
32
+ var version2 = "1.0.9-beta.2", package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "failproofai",
@@ -114,14 +114,14 @@ var init_package = __esm(() => {
114
114
  access: "public"
115
115
  },
116
116
  devDependencies: {
117
- "@anthropic-ai/sdk": "^0.127.0",
117
+ "@anthropic-ai/sdk": "^0.128.0",
118
118
  "@mdx-js/mdx": "^3.1.1",
119
119
  "@tailwindcss/postcss": "^4.3.1",
120
120
  "@tanstack/react-virtual": "^3.14.10",
121
121
  "@testing-library/jest-dom": "^7.0.0",
122
122
  "@testing-library/react": "^16.3.2",
123
123
  "@testing-library/user-event": "^14.6.5",
124
- "@types/node": "26.6.1",
124
+ "@types/node": "26.6.2",
125
125
  "@types/react": "19.3.0",
126
126
  "@types/react-dom": "^19.2.3",
127
127
  "@vitejs/plugin-react": "^6.1.0",
@@ -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.9-beta.0",
159
- "@failproofai/failproofaid-linux-arm64": "1.0.9-beta.0",
160
- "@failproofai/failproofaid-darwin-x64": "1.0.9-beta.0",
161
- "@failproofai/failproofaid-darwin-arm64": "1.0.9-beta.0"
158
+ "@failproofai/failproofaid-linux-x64": "1.0.9-beta.2",
159
+ "@failproofai/failproofaid-linux-arm64": "1.0.9-beta.2",
160
+ "@failproofai/failproofaid-darwin-x64": "1.0.9-beta.2",
161
+ "@failproofai/failproofaid-darwin-arm64": "1.0.9-beta.2"
162
162
  },
163
163
  failproofaidBinaries: {
164
- "linux-x64": "044b6619007227b8aa1fc1095b8c61a17bd90e11da53183ac1f5adecdcae6839",
165
- "linux-arm64": "479450d7d15c52a59bd1a8cf4c7086be9210e8d31ad4f98d99b123f571e944bd",
166
- "darwin-x64": "11562912ff726195bfb966ed24a774ffea38d01acc3edc1f9bfa3ea9c298977f",
167
- "darwin-arm64": "5bbaee1ec89d2d8032b7f16e502fb96891fbc6aa2ee6c861f43a64a0a60e61ba"
164
+ "linux-x64": "cd0a7124ae94ae78753cda6ffad985ba30be80443d8bc93d617ce507ba04e211",
165
+ "linux-arm64": "925446186bbfa827275356a9dc80b7d5351a6dcce9d926731419bbd91c1f98ba",
166
+ "darwin-x64": "cd35a6549f402b6c04848772074edb110a54a242fe7488792e59f8e8a00af475",
167
+ "darwin-arm64": "587b045accada4947a556e1bc1d748780a846c2ef95cf8dafb973a23fdbcb173"
168
168
  }
169
169
  };
170
170
  });
@@ -820,8 +820,11 @@ function sanitizeJevActivity(entry) {
820
820
  drop("evaluator");
821
821
  if (!(typeof out.jevDecision === "string" && DECISIONS.has(out.jevDecision)))
822
822
  drop("jevDecision");
823
+ const unknownMode = out.jevMode !== undefined && !(typeof out.jevMode === "string" && MODES.has(out.jevMode));
823
824
  if (!(typeof out.jevMode === "string" && MODES.has(out.jevMode)))
824
825
  drop("jevMode");
826
+ if (unknownMode)
827
+ drop("jevCleared");
825
828
  if (Array.isArray(out.jevCleared)) {
826
829
  const names = [
827
830
  ...new Set(out.jevCleared.filter(isJevPolicyName))
@@ -12489,24 +12492,95 @@ var init_dist = __esm(() => {
12489
12492
  $visitAsync = visit.visitAsync;
12490
12493
  });
12491
12494
 
12495
+ // src/hooks/safe-config-write.ts
12496
+ import {
12497
+ chmodSync as chmodSync2,
12498
+ closeSync as closeSync2,
12499
+ copyFileSync,
12500
+ existsSync as existsSync7,
12501
+ fsyncSync,
12502
+ lstatSync,
12503
+ mkdirSync as mkdirSync4,
12504
+ openSync as openSync2,
12505
+ realpathSync as realpathSync2,
12506
+ renameSync as renameSync2,
12507
+ rmSync as rmSync2,
12508
+ statSync as statSync5,
12509
+ writeSync
12510
+ } from "node:fs";
12511
+ import { randomBytes } from "node:crypto";
12512
+ import { basename, dirname as dirname3, join as join3 } from "node:path";
12513
+ function resolveWriteTarget(path) {
12514
+ try {
12515
+ if (lstatSync(path).isSymbolicLink())
12516
+ return realpathSync2(path);
12517
+ } catch {}
12518
+ return path;
12519
+ }
12520
+ function writeConfigFileAtomic(path, content, deps = {}) {
12521
+ const target = resolveWriteTarget(path);
12522
+ const dir = dirname3(target);
12523
+ mkdirSync4(dir, { recursive: true });
12524
+ let mode;
12525
+ try {
12526
+ mode = statSync5(target).mode & 511;
12527
+ } catch {
12528
+ mode = undefined;
12529
+ }
12530
+ const temporary = join3(dir, `.${basename(target)}.failproofai-${process.pid}-${randomBytes(4).toString("hex")}.tmp`);
12531
+ let fd;
12532
+ try {
12533
+ fd = openSync2(temporary, "wx", mode ?? 438);
12534
+ const bytes = Buffer.from(content, "utf8");
12535
+ let written = 0;
12536
+ while (written < bytes.length)
12537
+ written += writeSync(fd, bytes, written, bytes.length - written);
12538
+ fsyncSync(fd);
12539
+ closeSync2(fd);
12540
+ fd = undefined;
12541
+ if (mode !== undefined)
12542
+ chmodSync2(temporary, mode);
12543
+ if (existsSync7(target))
12544
+ copyFileSync(target, `${target}.failproofai-backup`);
12545
+ (deps.rename ?? renameSync2)(temporary, target);
12546
+ } catch (err) {
12547
+ if (fd !== undefined) {
12548
+ try {
12549
+ closeSync2(fd);
12550
+ } catch {}
12551
+ }
12552
+ rmSync2(temporary, { force: true });
12553
+ throw err;
12554
+ }
12555
+ try {
12556
+ const dirFd = openSync2(dir, "r");
12557
+ try {
12558
+ fsyncSync(dirFd);
12559
+ } finally {
12560
+ closeSync2(dirFd);
12561
+ }
12562
+ } catch {}
12563
+ }
12564
+ var init_safe_config_write = () => {};
12565
+
12492
12566
  // lib/hermes-profiles.ts
12493
- import { existsSync as existsSync7, readdirSync } from "node:fs";
12567
+ import { existsSync as existsSync8, readdirSync } from "node:fs";
12494
12568
  import { homedir as homedir4 } from "node:os";
12495
- import { basename, dirname as dirname3, join as join3, resolve as resolve6 } from "node:path";
12569
+ import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve6 } from "node:path";
12496
12570
  function hermesRoot() {
12497
12571
  const env = (process.env.HERMES_HOME || "").trim();
12498
12572
  if (env) {
12499
12573
  let home = resolve6(env);
12500
- const parent = dirname3(home);
12501
- if (basename(parent) === PROFILES_DIR)
12502
- home = dirname3(parent);
12503
- const base = basename(home);
12574
+ const parent = dirname4(home);
12575
+ if (basename2(parent) === PROFILES_DIR)
12576
+ home = dirname4(parent);
12577
+ const base = basename2(home);
12504
12578
  if (base === STANDARD_HOME || base.startsWith(SIBLING_HOME_PREFIX)) {
12505
- return join3(dirname3(home), STANDARD_HOME);
12579
+ return join4(dirname4(home), STANDARD_HOME);
12506
12580
  }
12507
12581
  return home;
12508
12582
  }
12509
- return join3(homedir4(), STANDARD_HOME);
12583
+ return join4(homedir4(), STANDARD_HOME);
12510
12584
  }
12511
12585
  function uniqueProfileName(preferred, seen) {
12512
12586
  if (!seen.has(preferred))
@@ -12525,22 +12599,22 @@ function listHermesProfiles() {
12525
12599
  const seen = new Set([HERMES_DEFAULT_PROFILE]);
12526
12600
  let names = [];
12527
12601
  try {
12528
- names = readdirSync(join3(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
12602
+ names = readdirSync(join4(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
12529
12603
  } catch {}
12530
12604
  for (const name of names) {
12531
12605
  if (seen.has(name))
12532
12606
  continue;
12533
12607
  seen.add(name);
12534
- out.push({ name, home: join3(root, PROFILES_DIR, name) });
12608
+ out.push({ name, home: join4(root, PROFILES_DIR, name) });
12535
12609
  }
12536
- if (basename(root) !== STANDARD_HOME)
12610
+ if (basename2(root) !== STANDARD_HOME)
12537
12611
  return out;
12538
12612
  let siblings = [];
12539
- const parent = dirname3(root);
12613
+ const parent = dirname4(root);
12540
12614
  try {
12541
- siblings = readdirSync(parent, { withFileTypes: true }).filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(SIBLING_HOME_PREFIX) && entry.name.length > SIBLING_HOME_PREFIX.length && existsSync7(join3(parent, entry.name, "config.yaml"))).map((entry) => ({
12615
+ siblings = readdirSync(parent, { withFileTypes: true }).filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(SIBLING_HOME_PREFIX) && entry.name.length > SIBLING_HOME_PREFIX.length && existsSync8(join4(parent, entry.name, "config.yaml"))).map((entry) => ({
12542
12616
  name: entry.name.slice(SIBLING_HOME_PREFIX.length),
12543
- home: join3(parent, entry.name)
12617
+ home: join4(parent, entry.name)
12544
12618
  })).sort((a, b) => a.name.localeCompare(b.name));
12545
12619
  } catch {
12546
12620
  return out;
@@ -12579,9 +12653,9 @@ var PROFILES_DIR = "profiles", STANDARD_HOME = ".hermes", SIBLING_HOME_PREFIX =
12579
12653
  var init_hermes_profiles = () => {};
12580
12654
 
12581
12655
  // lib/openclaw-profiles.ts
12582
- import { existsSync as existsSync8, readdirSync as readdirSync2 } from "node:fs";
12656
+ import { existsSync as existsSync9, readdirSync as readdirSync2 } from "node:fs";
12583
12657
  import { homedir as homedir5 } from "node:os";
12584
- import { basename as basename2, dirname as dirname4, join as join4, resolve as resolve7 } from "node:path";
12658
+ import { basename as basename3, dirname as dirname5, join as join5, resolve as resolve7 } from "node:path";
12585
12659
  function openclawProfileHome() {
12586
12660
  const stateDir = (process.env.OPENCLAW_STATE_DIR ?? "").trim();
12587
12661
  if (stateDir)
@@ -12591,17 +12665,17 @@ function openclawProfileHome() {
12591
12665
  return resolve7(openclawHome);
12592
12666
  const configPath = (process.env.OPENCLAW_CONFIG_PATH || "").trim();
12593
12667
  if (configPath)
12594
- return dirname4(resolve7(configPath));
12595
- return join4(homedir5(), ".openclaw");
12668
+ return dirname5(resolve7(configPath));
12669
+ return join5(homedir5(), ".openclaw");
12596
12670
  }
12597
12671
  function listOpenClawProfiles() {
12598
12672
  const activeHome = openclawProfileHome();
12599
- const activeBase = basename2(activeHome);
12673
+ const activeBase = basename3(activeHome);
12600
12674
  if (activeBase !== ".openclaw" && !activeBase.startsWith(".openclaw-")) {
12601
12675
  return [{ name: OPENCLAW_DEFAULT_PROFILE, home: activeHome }];
12602
12676
  }
12603
- const parent = dirname4(activeHome);
12604
- const defaultHome = join4(parent, ".openclaw");
12677
+ const parent = dirname5(activeHome);
12678
+ const defaultHome = join5(parent, ".openclaw");
12605
12679
  const out = [
12606
12680
  { name: OPENCLAW_DEFAULT_PROFILE, home: defaultHome }
12607
12681
  ];
@@ -12611,9 +12685,9 @@ function listOpenClawProfiles() {
12611
12685
  } catch {
12612
12686
  return out;
12613
12687
  }
12614
- const named = entries.filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(".openclaw-") && entry.name.length > ".openclaw-".length && existsSync8(join4(parent, entry.name, "openclaw.json"))).map((entry) => ({
12688
+ const named = entries.filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(".openclaw-") && entry.name.length > ".openclaw-".length && existsSync9(join5(parent, entry.name, "openclaw.json"))).map((entry) => ({
12615
12689
  name: entry.name.slice(".openclaw-".length),
12616
- home: join4(parent, entry.name)
12690
+ home: join5(parent, entry.name)
12617
12691
  })).sort((a, b) => a.name.localeCompare(b.name));
12618
12692
  out.push(...named);
12619
12693
  return out;
@@ -12627,40 +12701,71 @@ import {
12627
12701
  cpSync,
12628
12702
  readFileSync as readFileSync5,
12629
12703
  writeFileSync as writeFileSync3,
12630
- existsSync as existsSync9,
12631
- lstatSync,
12632
- mkdirSync as mkdirSync4,
12704
+ existsSync as existsSync10,
12705
+ lstatSync as lstatSync2,
12706
+ mkdirSync as mkdirSync5,
12633
12707
  readlinkSync,
12634
- realpathSync as realpathSync2,
12635
- renameSync as renameSync2,
12636
- rmSync as rmSync2,
12708
+ realpathSync as realpathSync3,
12709
+ renameSync as renameSync3,
12710
+ rmSync as rmSync3,
12637
12711
  symlinkSync,
12638
12712
  unlinkSync
12639
12713
  } from "node:fs";
12640
- import { resolve as resolve8, dirname as dirname5, basename as basename3 } from "node:path";
12714
+ import { resolve as resolve8, dirname as dirname6, basename as basename4 } from "node:path";
12641
12715
  import { fileURLToPath } from "node:url";
12642
12716
  import { homedir as homedir6 } from "node:os";
12643
12717
  function readJsonFile(path) {
12644
- if (!existsSync9(path))
12718
+ if (!existsSync10(path))
12645
12719
  return {};
12646
- const raw = readFileSync5(path, "utf8");
12647
- return JSON.parse(raw);
12720
+ let raw;
12721
+ try {
12722
+ raw = readFileSync5(path, "utf8");
12723
+ } catch (err) {
12724
+ throw new UnreadableAgentConfigError(path, `it could not be read (${err instanceof Error ? err.message : String(err)})`);
12725
+ }
12726
+ if (raw.trim() === "")
12727
+ return {};
12728
+ let parsed;
12729
+ try {
12730
+ parsed = JSON.parse(raw);
12731
+ } catch (err) {
12732
+ throw new UnreadableAgentConfigError(path, `it is not valid JSON (${err instanceof Error ? err.message : String(err)})`);
12733
+ }
12734
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
12735
+ throw new UnreadableAgentConfigError(path, "its top level is not a JSON object");
12736
+ }
12737
+ return parsed;
12648
12738
  }
12649
12739
  function writeJsonFile(path, data) {
12650
- mkdirSync4(dirname5(path), { recursive: true });
12651
- writeFileSync3(path, JSON.stringify(data, null, 2) + `
12652
- `, "utf8");
12740
+ writeConfigFileAtomic(path, JSON.stringify(data, null, 2) + `
12741
+ `);
12653
12742
  }
12654
12743
  function readYamlDoc(path) {
12744
+ if (!existsSync10(path))
12745
+ return $parseDocument("");
12746
+ let text;
12655
12747
  try {
12656
- return existsSync9(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
12748
+ text = readFileSync5(path, "utf8");
12749
+ } catch (err) {
12750
+ throw new UnreadableAgentConfigError(path, `it could not be read (${err instanceof Error ? err.message : String(err)})`);
12751
+ }
12752
+ const doc = $parseDocument(text);
12753
+ if (doc.errors.length > 0) {
12754
+ const first = doc.errors[0]?.message.split(`
12755
+ `)[0] ?? "syntax error";
12756
+ throw new UnreadableAgentConfigError(path, `it does not parse as YAML (${first})`);
12757
+ }
12758
+ return doc;
12759
+ }
12760
+ function inspectYamlDoc(path) {
12761
+ try {
12762
+ return readYamlDoc(path);
12657
12763
  } catch {
12658
- return $parseDocument("");
12764
+ return null;
12659
12765
  }
12660
12766
  }
12661
12767
  function writeYamlDoc(path, doc) {
12662
- mkdirSync4(dirname5(path), { recursive: true });
12663
- writeFileSync3(path, doc.toString(), "utf8");
12768
+ writeConfigFileAtomic(path, doc.toString());
12664
12769
  }
12665
12770
  function isMarkedHook(hook) {
12666
12771
  if (!hook || typeof hook !== "object")
@@ -12703,7 +12808,7 @@ function isMarkedCopilotHook(hook) {
12703
12808
  return false;
12704
12809
  }
12705
12810
  function opencodePluginFilePath(settingsPath) {
12706
- return resolve8(dirname5(settingsPath), "plugins", "failproofai.mjs");
12811
+ return resolve8(dirname6(settingsPath), "plugins", "failproofai.mjs");
12707
12812
  }
12708
12813
  function buildOpenCodePluginShim(binaryPath, scope) {
12709
12814
  const useNpx = scope === "project";
@@ -12942,26 +13047,39 @@ function getHermesPluginSourcePath() {
12942
13047
  const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
12943
13048
  if (fromEnv)
12944
13049
  return resolve8(fromEnv, HERMES_PLUGIN_SOURCE_DIR);
12945
- return resolve8(fileURLToPath(import.meta.url), "..", "..", "..", HERMES_PLUGIN_SOURCE_DIR);
13050
+ return findHermesPluginSourcePath(dirname6(fileURLToPath(import.meta.url)));
13051
+ }
13052
+ function findHermesPluginSourcePath(startDir) {
13053
+ let dir = resolve8(startDir);
13054
+ for (let i = 0;i < 8; i++) {
13055
+ const candidate = resolve8(dir, HERMES_PLUGIN_SOURCE_DIR);
13056
+ if (existsSync10(resolve8(candidate, "plugin.yaml")))
13057
+ return candidate;
13058
+ const parent = dirname6(dir);
13059
+ if (parent === dir)
13060
+ break;
13061
+ dir = parent;
13062
+ }
13063
+ return resolve8(startDir, "..", "..", HERMES_PLUGIN_SOURCE_DIR);
12946
13064
  }
12947
13065
  function hermesPluginPathForSettings(settingsPath) {
12948
- return resolve8(dirname5(settingsPath), "plugins", HERMES_PLUGIN_ID);
13066
+ return resolve8(dirname6(settingsPath), "plugins", HERMES_PLUGIN_ID);
12949
13067
  }
12950
13068
  function pathPresent(path) {
12951
13069
  try {
12952
- lstatSync(path);
13070
+ lstatSync2(path);
12953
13071
  return true;
12954
13072
  } catch {
12955
13073
  return false;
12956
13074
  }
12957
13075
  }
12958
13076
  function hasAllHermesPluginFiles(dir) {
12959
- return HERMES_PLUGIN_FILES.every((file) => existsSync9(resolve8(dir, file)));
13077
+ return HERMES_PLUGIN_FILES.every((file) => existsSync10(resolve8(dir, file)));
12960
13078
  }
12961
13079
  function isFailproofaiHermesPluginSource(dir) {
12962
- if (basename3(dir) !== HERMES_PLUGIN_SOURCE_DIR)
13080
+ if (basename4(dir) !== HERMES_PLUGIN_SOURCE_DIR)
12963
13081
  return false;
12964
- if (!existsSync9(dir))
13082
+ if (!existsSync10(dir))
12965
13083
  return true;
12966
13084
  try {
12967
13085
  const manifest = readFileSync5(resolve8(dir, "plugin.yaml"), "utf8");
@@ -12974,7 +13092,7 @@ function samePath(a, b) {
12974
13092
  if (resolve8(a) === resolve8(b))
12975
13093
  return true;
12976
13094
  try {
12977
- return realpathSync2(a) === realpathSync2(b);
13095
+ return realpathSync3(a) === realpathSync3(b);
12978
13096
  } catch {
12979
13097
  return false;
12980
13098
  }
@@ -12984,7 +13102,7 @@ function hermesPluginState(settingsPath) {
12984
13102
  let isLink;
12985
13103
  let isDirectory;
12986
13104
  try {
12987
- const stat = lstatSync(pluginPath);
13105
+ const stat = lstatSync2(pluginPath);
12988
13106
  isLink = stat.isSymbolicLink();
12989
13107
  isDirectory = stat.isDirectory();
12990
13108
  } catch {
@@ -12993,7 +13111,7 @@ function hermesPluginState(settingsPath) {
12993
13111
  if (isLink) {
12994
13112
  let target;
12995
13113
  try {
12996
- target = resolve8(dirname5(pluginPath), readlinkSync(pluginPath));
13114
+ target = resolve8(dirname6(pluginPath), readlinkSync(pluginPath));
12997
13115
  } catch {
12998
13116
  return { kind: "foreign" };
12999
13117
  }
@@ -13006,7 +13124,7 @@ function hermesPluginState(settingsPath) {
13006
13124
  current: samePath(target, getHermesPluginSourcePath())
13007
13125
  };
13008
13126
  }
13009
- if (isDirectory && existsSync9(resolve8(pluginPath, HERMES_PLUGIN_MARKER))) {
13127
+ if (isDirectory && existsSync10(resolve8(pluginPath, HERMES_PLUGIN_MARKER))) {
13010
13128
  return { kind: "copy", complete: hasAllHermesPluginFiles(pluginPath) };
13011
13129
  }
13012
13130
  return { kind: "foreign" };
@@ -13021,7 +13139,7 @@ function defaultHermesSymlink(target, path) {
13021
13139
  function installHermesPlugin(settingsPath, deps = {}) {
13022
13140
  const source = getHermesPluginSourcePath();
13023
13141
  for (const file of HERMES_PLUGIN_FILES) {
13024
- if (!existsSync9(resolve8(source, file))) {
13142
+ if (!existsSync10(resolve8(source, file))) {
13025
13143
  throw new Error(`Hermes plugin asset is missing from the failproofai package: ${file}`);
13026
13144
  }
13027
13145
  }
@@ -13032,7 +13150,7 @@ function installHermesPlugin(settingsPath, deps = {}) {
13032
13150
  }
13033
13151
  if (existing.kind === "link" && existing.current)
13034
13152
  return "unchanged";
13035
- mkdirSync4(dirname5(destination), { recursive: true });
13153
+ mkdirSync5(dirname6(destination), { recursive: true });
13036
13154
  const suffix = `${process.pid}-${Date.now()}`;
13037
13155
  const temporary = `${destination}.install-${suffix}`;
13038
13156
  let linked = false;
@@ -13040,43 +13158,45 @@ function installHermesPlugin(settingsPath, deps = {}) {
13040
13158
  (deps.symlink ?? defaultHermesSymlink)(source, temporary);
13041
13159
  linked = true;
13042
13160
  } catch {
13043
- rmSync2(temporary, { recursive: true, force: true });
13161
+ rmSync3(temporary, { recursive: true, force: true });
13044
13162
  }
13045
13163
  if (!linked) {
13046
- mkdirSync4(temporary, { recursive: true });
13164
+ mkdirSync5(temporary, { recursive: true });
13047
13165
  try {
13048
13166
  for (const file of HERMES_PLUGIN_FILES) {
13049
13167
  cpSync(resolve8(source, file), resolve8(temporary, file));
13050
13168
  }
13051
13169
  writeFileSync3(resolve8(temporary, HERMES_PLUGIN_MARKER), "Managed by failproofai. Remove with `failproofai policies --uninstall --cli hermes`.\n", { encoding: "utf8", mode: 384 });
13052
13170
  } catch (err) {
13053
- rmSync2(temporary, { recursive: true, force: true });
13171
+ rmSync3(temporary, { recursive: true, force: true });
13054
13172
  throw err;
13055
13173
  }
13056
13174
  }
13057
13175
  if (linked && (existing.kind === "absent" || existing.kind === "link")) {
13058
13176
  try {
13059
- renameSync2(temporary, destination);
13177
+ renameSync3(temporary, destination);
13178
+ return "linked";
13060
13179
  } catch (err) {
13061
- rmSync2(temporary, { force: true });
13062
- throw err;
13180
+ if (existing.kind !== "link") {
13181
+ rmSync3(temporary, { force: true });
13182
+ throw err;
13183
+ }
13063
13184
  }
13064
- return "linked";
13065
13185
  }
13066
13186
  const backup = `${destination}.backup-${suffix}`;
13067
13187
  let movedExisting = false;
13068
13188
  try {
13069
13189
  if (pathPresent(destination)) {
13070
- renameSync2(destination, backup);
13190
+ renameSync3(destination, backup);
13071
13191
  movedExisting = true;
13072
13192
  }
13073
- renameSync2(temporary, destination);
13193
+ renameSync3(temporary, destination);
13074
13194
  if (movedExisting)
13075
- rmSync2(backup, { recursive: true, force: true });
13195
+ rmSync3(backup, { recursive: true, force: true });
13076
13196
  } catch (err) {
13077
- rmSync2(temporary, { recursive: true, force: true });
13197
+ rmSync3(temporary, { recursive: true, force: true });
13078
13198
  if (movedExisting && !pathPresent(destination) && pathPresent(backup)) {
13079
- renameSync2(backup, destination);
13199
+ renameSync3(backup, destination);
13080
13200
  }
13081
13201
  throw err;
13082
13202
  }
@@ -13091,7 +13211,7 @@ function removeManagedHermesPlugin(settingsPath) {
13091
13211
  }
13092
13212
  if (state.kind !== "copy")
13093
13213
  return false;
13094
- rmSync2(pluginPath, { recursive: true, force: true });
13214
+ rmSync3(pluginPath, { recursive: true, force: true });
13095
13215
  return true;
13096
13216
  }
13097
13217
  function removeLegacyHermesHooks(doc) {
@@ -13122,15 +13242,23 @@ function removeLegacyHermesHooks(doc) {
13122
13242
  return removed;
13123
13243
  }
13124
13244
  function hermesConfigState(settingsPath) {
13125
- if (!existsSync9(settingsPath)) {
13126
- return { pluginEnabled: false, legacyShellHookPresent: false };
13245
+ if (!existsSync10(settingsPath)) {
13246
+ return { pluginEnabled: false, pluginListed: false, pluginDisabled: false, legacyShellHookPresent: false };
13247
+ }
13248
+ const doc = inspectYamlDoc(settingsPath);
13249
+ if (!doc) {
13250
+ return { pluginEnabled: false, pluginListed: false, pluginDisabled: false, legacyShellHookPresent: false, unreadable: true };
13127
13251
  }
13128
- const doc = readYamlDoc(settingsPath);
13129
13252
  const js = doc.toJS() ?? {};
13130
13253
  const enabled = js.plugins?.enabled;
13254
+ const disabled = js.plugins?.disabled;
13131
13255
  const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook(entry)));
13256
+ const pluginListed = Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID);
13257
+ const pluginDisabled = Array.isArray(disabled) && disabled.includes(HERMES_PLUGIN_ID);
13132
13258
  return {
13133
- pluginEnabled: Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID),
13259
+ pluginEnabled: pluginListed && !pluginDisabled,
13260
+ pluginListed,
13261
+ pluginDisabled,
13134
13262
  legacyShellHookPresent
13135
13263
  };
13136
13264
  }
@@ -13153,7 +13281,7 @@ async function migrateHermesProfiles(opts) {
13153
13281
  const results = [];
13154
13282
  let daemonOk;
13155
13283
  for (const profile of listHermesProfiles()) {
13156
- if (!existsSync9(profile.home))
13284
+ if (!existsSync10(profile.home))
13157
13285
  continue;
13158
13286
  const settingsPath = resolve8(profile.home, "config.yaml");
13159
13287
  const pluginPath = hermesPluginPathForSettings(settingsPath);
@@ -13162,7 +13290,23 @@ async function migrateHermesProfiles(opts) {
13162
13290
  const ours = plugin.kind === "link" || plugin.kind === "copy";
13163
13291
  const base = { name: profile.name, home: profile.home };
13164
13292
  const legacy = config.legacyShellHookPresent;
13165
- if (!legacy && !ours && !config.pluginEnabled) {
13293
+ if (config.unreadable) {
13294
+ let raw = "";
13295
+ try {
13296
+ raw = readFileSync5(settingsPath, "utf8");
13297
+ } catch {
13298
+ raw = "";
13299
+ }
13300
+ const mentionsUs = ours || raw.includes(FAILPROOFAI_HOOK_MARKER) || /failproofai/.test(raw);
13301
+ results.push(mentionsUs ? {
13302
+ ...base,
13303
+ status: "failed",
13304
+ detail: `${settingsPath} does not parse as YAML; left untouched`,
13305
+ legacyShellHooksRemain: /--hook\s+\S+\s+--cli\s+hermes|__failproofai_hook__/.test(raw)
13306
+ } : { ...base, status: "untouched", detail: "no failproofai integration", legacyShellHooksRemain: false });
13307
+ continue;
13308
+ }
13309
+ if (!legacy && !ours && !config.pluginListed && !config.pluginDisabled) {
13166
13310
  results.push({ ...base, status: "untouched", detail: "no failproofai integration", legacyShellHooksRemain: false });
13167
13311
  continue;
13168
13312
  }
@@ -13179,7 +13323,7 @@ async function migrateHermesProfiles(opts) {
13179
13323
  });
13180
13324
  continue;
13181
13325
  }
13182
- if (existsSync9(settingsPath)) {
13326
+ if (existsSync10(settingsPath)) {
13183
13327
  const errors = $parseDocument(readFileSync5(settingsPath, "utf8")).errors;
13184
13328
  if (errors.length > 0) {
13185
13329
  results.push({
@@ -13258,12 +13402,21 @@ function listInstallableIds() {
13258
13402
  function detectInstalledClis() {
13259
13403
  return INTEGRATION_TYPES.filter((id) => INTEGRATIONS[id]?.detectInstalled());
13260
13404
  }
13261
- var claudeCode, codex, copilot, cursor, OPENCODE_PLUGIN_REL_PATH = "./plugins/failproofai.mjs", opencode, pi, HERMES_PLUGIN_ID = "failproofai", HERMES_PLUGIN_MARKER = ".failproofai-managed", HERMES_PLUGIN_FILES, HERMES_PLUGIN_SOURCE_DIR = "hermes-plugin", hermes, OPENCLAW_PLUGIN_ID = "failproofai", openclaw, factory, devin, ANTIGRAVITY_HOOK_NAME = "failproofai", ANTIGRAVITY_TOOL_EVENTS, antigravity, goose, INTEGRATIONS;
13405
+ var UnreadableAgentConfigError, claudeCode, codex, copilot, cursor, OPENCODE_PLUGIN_REL_PATH = "./plugins/failproofai.mjs", opencode, pi, HERMES_PLUGIN_ID = "failproofai", HERMES_PLUGIN_MARKER = ".failproofai-managed", HERMES_PLUGIN_FILES, HERMES_PLUGIN_SOURCE_DIR = "hermes-plugin", hermes, OPENCLAW_PLUGIN_ID = "failproofai", openclaw, factory, devin, ANTIGRAVITY_HOOK_NAME = "failproofai", ANTIGRAVITY_TOOL_EVENTS, antigravity, goose, INTEGRATIONS;
13262
13406
  var init_integrations = __esm(() => {
13263
13407
  init_dist();
13408
+ init_safe_config_write();
13264
13409
  init_hermes_profiles();
13265
13410
  init_openclaw_profiles();
13266
13411
  init_types();
13412
+ UnreadableAgentConfigError = class UnreadableAgentConfigError extends Error {
13413
+ path;
13414
+ constructor(path, reason) {
13415
+ super(`Refusing to modify ${path}: ${reason}. ` + `failproofai never rewrites a config it could not parse — fix or move the file, then retry.`);
13416
+ this.path = path;
13417
+ this.name = "UnreadableAgentConfigError";
13418
+ }
13419
+ };
13267
13420
  claudeCode = {
13268
13421
  id: "claude",
13269
13422
  displayName: "Claude Code",
@@ -13373,7 +13526,7 @@ var init_integrations = __esm(() => {
13373
13526
  },
13374
13527
  hooksInstalledInSettings(scope, cwd) {
13375
13528
  const settingsPath = this.getSettingsPath(scope, cwd);
13376
- if (!existsSync9(settingsPath))
13529
+ if (!existsSync10(settingsPath))
13377
13530
  return false;
13378
13531
  try {
13379
13532
  const settings = this.readSettings(settingsPath);
@@ -13489,7 +13642,7 @@ var init_integrations = __esm(() => {
13489
13642
  },
13490
13643
  hooksInstalledInSettings(scope, cwd) {
13491
13644
  const settingsPath = this.getSettingsPath(scope, cwd);
13492
- if (!existsSync9(settingsPath))
13645
+ if (!existsSync10(settingsPath))
13493
13646
  return false;
13494
13647
  try {
13495
13648
  const settings = this.readSettings(settingsPath);
@@ -13603,7 +13756,7 @@ var init_integrations = __esm(() => {
13603
13756
  },
13604
13757
  hooksInstalledInSettings(scope, cwd) {
13605
13758
  const settingsPath = this.getSettingsPath(scope, cwd);
13606
- if (!existsSync9(settingsPath))
13759
+ if (!existsSync10(settingsPath))
13607
13760
  return false;
13608
13761
  try {
13609
13762
  const settings = this.readSettings(settingsPath);
@@ -13706,7 +13859,7 @@ var init_integrations = __esm(() => {
13706
13859
  },
13707
13860
  hooksInstalledInSettings(scope, cwd) {
13708
13861
  const settingsPath = this.getSettingsPath(scope, cwd);
13709
- if (!existsSync9(settingsPath))
13862
+ if (!existsSync10(settingsPath))
13710
13863
  return false;
13711
13864
  try {
13712
13865
  const settings = this.readSettings(settingsPath);
@@ -13766,8 +13919,8 @@ var init_integrations = __esm(() => {
13766
13919
  const effectiveScope = scope ?? "project";
13767
13920
  const settingsPath = effectiveScope === "user" ? resolve8(homedir6(), ".config", "opencode", "opencode.json") : resolve8(process.cwd(), ".opencode", "opencode.json");
13768
13921
  const pluginPath = opencodePluginFilePath(settingsPath);
13769
- mkdirSync4(dirname5(pluginPath), { recursive: true });
13770
- writeFileSync3(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope), "utf8");
13922
+ mkdirSync5(dirname6(pluginPath), { recursive: true });
13923
+ writeConfigFileAtomic(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope));
13771
13924
  if (!Array.isArray(s.plugin))
13772
13925
  s.plugin = [];
13773
13926
  const desired = effectiveScope === "user" ? `file://${pluginPath}` : OPENCODE_PLUGIN_REL_PATH;
@@ -13790,7 +13943,7 @@ var init_integrations = __esm(() => {
13790
13943
  }
13791
13944
  this.writeSettings(settingsPath, settings);
13792
13945
  const pluginPath = opencodePluginFilePath(settingsPath);
13793
- if (existsSync9(pluginPath)) {
13946
+ if (existsSync10(pluginPath)) {
13794
13947
  try {
13795
13948
  const content = readFileSync5(pluginPath, "utf8");
13796
13949
  if (content.includes(FAILPROOFAI_HOOK_MARKER)) {
@@ -13804,7 +13957,7 @@ var init_integrations = __esm(() => {
13804
13957
  },
13805
13958
  hooksInstalledInSettings(scope, cwd) {
13806
13959
  const settingsPath = this.getSettingsPath(scope, cwd);
13807
- if (!existsSync9(settingsPath))
13960
+ if (!existsSync10(settingsPath))
13808
13961
  return false;
13809
13962
  try {
13810
13963
  const settings = this.readSettings(settingsPath);
@@ -13814,7 +13967,7 @@ var init_integrations = __esm(() => {
13814
13967
  if (!hasEntry)
13815
13968
  return false;
13816
13969
  const pluginPath = opencodePluginFilePath(settingsPath);
13817
- if (!existsSync9(pluginPath))
13970
+ if (!existsSync10(pluginPath))
13818
13971
  return false;
13819
13972
  const content = readFileSync5(pluginPath, "utf8");
13820
13973
  return content.includes(FAILPROOFAI_HOOK_MARKER);
@@ -13881,7 +14034,7 @@ var init_integrations = __esm(() => {
13881
14034
  }
13882
14035
  },
13883
14036
  removeHooksFromFile(settingsPath) {
13884
- if (!existsSync9(settingsPath))
14037
+ if (!existsSync10(settingsPath))
13885
14038
  return 0;
13886
14039
  const settings = this.readSettings(settingsPath);
13887
14040
  if (!Array.isArray(settings.packages))
@@ -13896,7 +14049,7 @@ var init_integrations = __esm(() => {
13896
14049
  },
13897
14050
  hooksInstalledInSettings(scope, cwd) {
13898
14051
  const settingsPath = this.getSettingsPath(scope, cwd);
13899
- if (!existsSync9(settingsPath))
14052
+ if (!existsSync10(settingsPath))
13900
14053
  return false;
13901
14054
  try {
13902
14055
  const settings = this.readSettings(settingsPath);
@@ -14037,7 +14190,7 @@ var init_integrations = __esm(() => {
14037
14190
  hooks.allowConversationAccess = true;
14038
14191
  },
14039
14192
  removeHooksFromFile(settingsPath) {
14040
- if (!existsSync9(settingsPath))
14193
+ if (!existsSync10(settingsPath))
14041
14194
  return 0;
14042
14195
  const settings = this.readSettings(settingsPath);
14043
14196
  const plugins = settings.plugins;
@@ -14067,7 +14220,7 @@ var init_integrations = __esm(() => {
14067
14220
  hooksInstalledInSettings(scope, cwd) {
14068
14221
  const settingsPaths = settingsPathsFor(this, scope, cwd);
14069
14222
  return settingsPaths.length > 0 && settingsPaths.every((settingsPath) => {
14070
- if (!existsSync9(settingsPath))
14223
+ if (!existsSync10(settingsPath))
14071
14224
  return false;
14072
14225
  try {
14073
14226
  const settings = this.readSettings(settingsPath);
@@ -14165,7 +14318,7 @@ var init_integrations = __esm(() => {
14165
14318
  },
14166
14319
  hooksInstalledInSettings(scope, cwd) {
14167
14320
  const settingsPath = this.getSettingsPath(scope, cwd);
14168
- if (!existsSync9(settingsPath))
14321
+ if (!existsSync10(settingsPath))
14169
14322
  return false;
14170
14323
  try {
14171
14324
  const settings = this.readSettings(settingsPath);
@@ -14271,7 +14424,7 @@ var init_integrations = __esm(() => {
14271
14424
  },
14272
14425
  hooksInstalledInSettings(scope, cwd) {
14273
14426
  const settingsPath = this.getSettingsPath(scope, cwd);
14274
- if (!existsSync9(settingsPath))
14427
+ if (!existsSync10(settingsPath))
14275
14428
  return false;
14276
14429
  try {
14277
14430
  const settings = this.readSettings(settingsPath);
@@ -14410,7 +14563,7 @@ var init_integrations = __esm(() => {
14410
14563
  },
14411
14564
  hooksInstalledInSettings(scope, cwd) {
14412
14565
  const settingsPath = this.getSettingsPath(scope, cwd);
14413
- if (!existsSync9(settingsPath))
14566
+ if (!existsSync10(settingsPath))
14414
14567
  return false;
14415
14568
  try {
14416
14569
  const settings = this.readSettings(settingsPath);
@@ -14516,7 +14669,7 @@ var init_integrations = __esm(() => {
14516
14669
  },
14517
14670
  hooksInstalledInSettings(scope, cwd) {
14518
14671
  const settingsPath = this.getSettingsPath(scope, cwd);
14519
- if (!existsSync9(settingsPath))
14672
+ if (!existsSync10(settingsPath))
14520
14673
  return false;
14521
14674
  try {
14522
14675
  const settings = this.readSettings(settingsPath);
@@ -16877,7 +17030,7 @@ var init_custom_hooks_registry = __esm(() => {
16877
17030
  // src/hooks/loader-utils.ts
16878
17031
  import { readFile as readFile2, writeFile as writeFile2, unlink, access, mkdir, lstat } from "fs/promises";
16879
17032
  import { tmpdir } from "os";
16880
- import { resolve as resolve9, dirname as dirname6, relative as relative2, join as join5 } from "path";
17033
+ import { resolve as resolve9, dirname as dirname7, relative as relative2, join as join6 } from "path";
16881
17034
  import { pathToFileURL } from "url";
16882
17035
  import { createHash as createHash3 } from "crypto";
16883
17036
  function isTmpArtifact(name) {
@@ -16918,7 +17071,7 @@ async function findDistIndex() {
16918
17071
  return candidate;
16919
17072
  }
16920
17073
  const candidates = [
16921
- resolve9(dirname6(process.execPath), "..", "assets", "dist", "index.js"),
17074
+ resolve9(dirname7(process.execPath), "..", "assets", "dist", "index.js"),
16922
17075
  resolve9(process.cwd(), "dist", "index.js"),
16923
17076
  resolve9(process.cwd(), "node_modules", "failproofai", "dist", "index.js")
16924
17077
  ];
@@ -16938,7 +17091,7 @@ async function resolveLocalImport(fromDir, specifier) {
16938
17091
  return null;
16939
17092
  }
16940
17093
  async function writeShim(dir, name, code, exclusive) {
16941
- const shimPath = join5(dir, name);
17094
+ const shimPath = join6(dir, name);
16942
17095
  await writeFile2(shimPath, code, {
16943
17096
  encoding: "utf-8",
16944
17097
  mode: 384,
@@ -17009,7 +17162,7 @@ async function rewriteFileTree(entryPath, distUrl, distIndex, tmpSuffix = TMP_SU
17009
17162
  if (distIndex) {
17010
17163
  code = code.replace(/require\s*\(\s*(['"])(?:claudeye|failproofai)\1\s*\)/g, `require('${distIndex.replace(/\\/g, "\\\\")}')`);
17011
17164
  }
17012
- const dir = dirname6(filePath);
17165
+ const dir = dirname7(filePath);
17013
17166
  const rewrites = new Map;
17014
17167
  for (const re of [LOCAL_IMPORT_RE, LOCAL_REQUIRE_RE]) {
17015
17168
  const freshRe = new RegExp(re.source, re.flags);
@@ -17230,14 +17383,14 @@ var init_telemetry_id2 = __esm(() => {
17230
17383
  });
17231
17384
 
17232
17385
  // src/hooks/custom-hooks-loader.ts
17233
- import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename4 } from "node:path";
17386
+ import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename5 } from "node:path";
17234
17387
  import { randomUUID } from "crypto";
17235
- import { existsSync as existsSync10, readdirSync as readdirSync3 } from "node:fs";
17388
+ import { existsSync as existsSync11, readdirSync as readdirSync3 } from "node:fs";
17236
17389
  import { readFile as readFile3 } from "node:fs/promises";
17237
17390
  import { pathToFileURL as pathToFileURL2 } from "node:url";
17238
17391
  import { createHash as createHash4 } from "node:crypto";
17239
17392
  function discoverPolicyFiles(dir) {
17240
- if (!existsSync10(dir))
17393
+ if (!existsSync11(dir))
17241
17394
  return [];
17242
17395
  try {
17243
17396
  const entries = readdirSync3(dir, { withFileTypes: true });
@@ -17247,7 +17400,7 @@ function discoverPolicyFiles(dir) {
17247
17400
  }
17248
17401
  }
17249
17402
  function findSkippedPolicyFiles(dir) {
17250
- if (!existsSync10(dir))
17403
+ if (!existsSync11(dir))
17251
17404
  return [];
17252
17405
  try {
17253
17406
  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));
@@ -17300,7 +17453,7 @@ async function loadSingleFile(absPath, opts) {
17300
17453
  const ignored = getSemanticRegistrations().slice(semanticBefore).map((d) => d?.name);
17301
17454
  if (opts?.outsidePack && ignored.length > 0 && !warnedSemanticOutsidePack.has(absPath)) {
17302
17455
  warnedSemanticOutsidePack.add(absPath);
17303
- hookLogWarn(`${basename4(absPath)}: semanticPolicies.add only takes effect in a pack published with \`failproofai publish\`; ` + `${ignored.join(", ")} ${ignored.length === 1 ? "is" : "are"} never asked here`);
17456
+ hookLogWarn(`${basename5(absPath)}: semanticPolicies.add only takes effect in a pack published with \`failproofai publish\`; ` + `${ignored.join(", ")} ${ignored.length === 1 ? "is" : "are"} never asked here`);
17304
17457
  }
17305
17458
  if (policyModuleCache.size >= POLICY_MODULE_CACHE_MAX_ENTRIES)
17306
17459
  policyModuleCache.clear();
@@ -17316,7 +17469,7 @@ async function loadSingleFile(absPath, opts) {
17316
17469
  error_type: errorType,
17317
17470
  is_convention: !!opts?.conventionScope,
17318
17471
  convention_scope: opts?.conventionScope ?? null,
17319
- file_basename: basename4(absPath)
17472
+ file_basename: basename5(absPath)
17320
17473
  });
17321
17474
  if (opts?.strict)
17322
17475
  throw new Error(`Failed to load custom hooks from ${absPath}: ${msg}`);
@@ -17340,7 +17493,7 @@ async function loadCustomHooks(customPoliciesPath, opts) {
17340
17493
  if (!customPoliciesPath)
17341
17494
  return [];
17342
17495
  const absPath = isAbsolute2(customPoliciesPath) ? customPoliciesPath : resolve10(opts?.sessionCwd ?? process.cwd(), customPoliciesPath);
17343
- if (!existsSync10(absPath)) {
17496
+ if (!existsSync11(absPath)) {
17344
17497
  if (opts?.strict)
17345
17498
  throw new Error(`Custom hooks file not found: ${absPath}`);
17346
17499
  hookLogWarn(`customPoliciesPath not found: ${absPath}`);
@@ -17455,7 +17608,7 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17455
17608
  const absPath = resolve10(projectRoot, customPoliciesPath);
17456
17609
  const cloudManaged = cloudManagedByPath.get(absPath);
17457
17610
  const pack = packByPath.get(absPath);
17458
- if (existsSync10(absPath)) {
17611
+ if (existsSync11(absPath)) {
17459
17612
  if (!loadedPaths.has(absPath)) {
17460
17613
  loadedPaths.add(absPath);
17461
17614
  const hooksBefore = getCustomHooks().length;
@@ -17505,12 +17658,12 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17505
17658
  await loadSingleFile(file, { conventionScope: projectScope, outsidePack: true });
17506
17659
  const newHooks = getCustomHooks().slice(hooksBefore);
17507
17660
  for (const hook of newHooks) {
17508
- hook.__policyId = conventionPolicyId(projectScope, basename4(file), hook.name);
17661
+ hook.__policyId = conventionPolicyId(projectScope, basename5(file), hook.name);
17509
17662
  }
17510
17663
  if (newHooks.length > 0) {
17511
17664
  conventionSources.push({
17512
17665
  scope: projectScope,
17513
- file: basename4(file),
17666
+ file: basename5(file),
17514
17667
  hookNames: newHooks.map((h) => h.name)
17515
17668
  });
17516
17669
  }
@@ -17527,12 +17680,12 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17527
17680
  await loadSingleFile(file, { conventionScope: "user", outsidePack: true });
17528
17681
  const newHooks = getCustomHooks().slice(hooksBefore);
17529
17682
  for (const hook of newHooks) {
17530
- hook.__policyId = conventionPolicyId("user", basename4(file), hook.name);
17683
+ hook.__policyId = conventionPolicyId("user", basename5(file), hook.name);
17531
17684
  }
17532
17685
  if (newHooks.length > 0) {
17533
17686
  conventionSources.push({
17534
17687
  scope: "user",
17535
- file: basename4(file),
17688
+ file: basename5(file),
17536
17689
  hookNames: newHooks.map((h) => h.name)
17537
17690
  });
17538
17691
  }
@@ -18533,8 +18686,8 @@ var init_pack_cli = __esm(() => {
18533
18686
 
18534
18687
  // src/hooks/pack-store.ts
18535
18688
  import { createHash as createHash5 } from "node:crypto";
18536
- import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "node:fs";
18537
- import { dirname as dirname7, resolve as resolve11 } from "node:path";
18689
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "node:fs";
18690
+ import { dirname as dirname8, resolve as resolve11 } from "node:path";
18538
18691
  function baseUrl() {
18539
18692
  return (process.env.FAILPROOFAI_PACK_BASE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
18540
18693
  }
@@ -18705,11 +18858,11 @@ function sha256(bytes) {
18705
18858
  function writeAtomic(target, bytes) {
18706
18859
  const tempPath = `${target}.${process.pid}.tmp`;
18707
18860
  try {
18708
- mkdirSync5(dirname7(target), { recursive: true });
18861
+ mkdirSync6(dirname8(target), { recursive: true });
18709
18862
  writeFileSync4(tempPath, bytes);
18710
- renameSync3(tempPath, target);
18863
+ renameSync4(tempPath, target);
18711
18864
  } catch (err) {
18712
- rmSync3(tempPath, { force: true });
18865
+ rmSync4(tempPath, { force: true });
18713
18866
  throw err;
18714
18867
  }
18715
18868
  }
@@ -18935,7 +19088,7 @@ async function addPack(source, opts) {
18935
19088
  const root = packsRoot();
18936
19089
  const artifactRel = `artifacts/${fetched.artifactDigest}.mjs`;
18937
19090
  const artifactAbs = resolve11(root, artifactRel);
18938
- if (!existsSync11(artifactAbs))
19091
+ if (!existsSync12(artifactAbs))
18939
19092
  writeAtomic(artifactAbs, fetched.artifact);
18940
19093
  try {
18941
19094
  await verifyArtifactRegisters(artifactAbs, available);
@@ -18984,7 +19137,7 @@ async function addPack(source, opts) {
18984
19137
  }
18985
19138
  function setPackPolicyEnabled(packId, name, on) {
18986
19139
  const manifestPath = resolve11(packsRoot(), "installed.json");
18987
- if (!existsSync11(manifestPath))
19140
+ if (!existsSync12(manifestPath))
18988
19141
  return { ok: false, reason: "no packs are installed" };
18989
19142
  let raw;
18990
19143
  try {
@@ -19018,7 +19171,7 @@ function bareId(value) {
19018
19171
  }
19019
19172
  function removePack(id) {
19020
19173
  const manifestPath = resolve11(packsRoot(), "installed.json");
19021
- if (!existsSync11(manifestPath))
19174
+ if (!existsSync12(manifestPath))
19022
19175
  return null;
19023
19176
  let raw;
19024
19177
  try {
@@ -19043,7 +19196,7 @@ function removePack(id) {
19043
19196
  function upsertInstalled(record, carryAbsorbedSelection = true) {
19044
19197
  const manifestPath = resolve11(packsRoot(), "installed.json");
19045
19198
  let packs = [];
19046
- if (existsSync11(manifestPath)) {
19199
+ if (existsSync12(manifestPath)) {
19047
19200
  try {
19048
19201
  const raw = JSON.parse(readFileSync6(manifestPath, "utf8"));
19049
19202
  if (Array.isArray(raw.packs))
@@ -20041,22 +20194,22 @@ import {
20041
20194
  readFileSync as readFileSync7,
20042
20195
  writeFileSync as writeFileSync5,
20043
20196
  appendFileSync as appendFileSync2,
20044
- renameSync as renameSync4,
20197
+ renameSync as renameSync5,
20045
20198
  readdirSync as readdirSync4,
20046
- mkdirSync as mkdirSync6,
20047
- existsSync as existsSync12,
20048
- statSync as statSync5,
20199
+ mkdirSync as mkdirSync7,
20200
+ existsSync as existsSync13,
20201
+ statSync as statSync6,
20049
20202
  unlinkSync as unlinkSync2
20050
20203
  } from "node:fs";
20051
- import { join as join6 } from "node:path";
20204
+ import { join as join7 } from "node:path";
20052
20205
  function ensureDir() {
20053
- if (!existsSync12(storeDirValue())) {
20054
- mkdirSync6(storeDirValue(), { recursive: true });
20206
+ if (!existsSync13(storeDirValue())) {
20207
+ mkdirSync7(storeDirValue(), { recursive: true });
20055
20208
  }
20056
20209
  }
20057
20210
  function acquireLock() {
20058
20211
  ensureDir();
20059
- const lockPath = join6(storeDirValue(), LOCK_FILE);
20212
+ const lockPath = join7(storeDirValue(), LOCK_FILE);
20060
20213
  const deadline = Date.now() + LOCK_STALE_MS;
20061
20214
  while (Date.now() < deadline) {
20062
20215
  try {
@@ -20066,7 +20219,7 @@ function acquireLock() {
20066
20219
  if (e.code !== "EEXIST")
20067
20220
  return;
20068
20221
  try {
20069
- const s = statSync5(lockPath);
20222
+ const s = statSync6(lockPath);
20070
20223
  if (Date.now() - s.mtimeMs > LOCK_STALE_MS) {
20071
20224
  writeFileSync5(lockPath, String(process.pid), "utf-8");
20072
20225
  return;
@@ -20077,7 +20230,7 @@ function acquireLock() {
20077
20230
  }
20078
20231
  function releaseLock() {
20079
20232
  try {
20080
- unlinkSync2(join6(storeDirValue(), LOCK_FILE));
20233
+ unlinkSync2(join7(storeDirValue(), LOCK_FILE));
20081
20234
  } catch {}
20082
20235
  }
20083
20236
  function persistHookActivity(input) {
@@ -20085,8 +20238,8 @@ function persistHookActivity(input) {
20085
20238
  ensureDir();
20086
20239
  acquireLock();
20087
20240
  try {
20088
- const currentPath = join6(storeDirValue(), CURRENT_FILE);
20089
- const countPath = join6(storeDirValue(), COUNT_FILE);
20241
+ const currentPath = join7(storeDirValue(), CURRENT_FILE);
20242
+ const countPath = join7(storeDirValue(), COUNT_FILE);
20090
20243
  const lineCount = readCount(countPath);
20091
20244
  if (lineCount >= PAGE_SIZE) {
20092
20245
  try {
@@ -20106,8 +20259,8 @@ function persistHookActivity(input) {
20106
20259
  }
20107
20260
  function rotate(currentPath, countPath) {
20108
20261
  const archiveName = `page-${Date.now()}-${rotateSeq++}.jsonl`;
20109
- const archivePath = join6(storeDirValue(), archiveName);
20110
- renameSync4(currentPath, archivePath);
20262
+ const archivePath = join7(storeDirValue(), archiveName);
20263
+ renameSync5(currentPath, archivePath);
20111
20264
  writeCount(countPath, 0);
20112
20265
  }
20113
20266
  function readCount(countPath) {
@@ -20132,7 +20285,7 @@ function readFileSafe(filePath) {
20132
20285
  }
20133
20286
  function readStoredStats() {
20134
20287
  try {
20135
- return JSON.parse(readFileSync7(join6(storeDirValue(), STATS_FILE), "utf-8"));
20288
+ return JSON.parse(readFileSync7(join7(storeDirValue(), STATS_FILE), "utf-8"));
20136
20289
  } catch {
20137
20290
  return { totalEvents: 0, denyCount: 0, policyMap: {} };
20138
20291
  }
@@ -20150,10 +20303,10 @@ function foldEntry(s, entry) {
20150
20303
  }
20151
20304
  }
20152
20305
  function writeStoredStats(s) {
20153
- const tmpPath = join6(storeDirValue(), `stats.json.${process.pid}.tmp`);
20306
+ const tmpPath = join7(storeDirValue(), `stats.json.${process.pid}.tmp`);
20154
20307
  try {
20155
20308
  writeFileSync5(tmpPath, JSON.stringify(s), "utf-8");
20156
- renameSync4(tmpPath, join6(storeDirValue(), STATS_FILE));
20309
+ renameSync5(tmpPath, join7(storeDirValue(), STATS_FILE));
20157
20310
  return true;
20158
20311
  } catch {
20159
20312
  try {
@@ -20173,8 +20326,8 @@ function rebuildHookActivityStats() {
20173
20326
  const s = { totalEvents: 0, denyCount: 0, policyMap: {} };
20174
20327
  let sawAny = false;
20175
20328
  for (const file of files) {
20176
- const path = join6(storeDirValue(), file);
20177
- if (!existsSync12(path))
20329
+ const path = join7(storeDirValue(), file);
20330
+ if (!existsSync13(path))
20178
20331
  continue;
20179
20332
  sawAny = true;
20180
20333
  for (const entry of readJsonlFile(path))
@@ -20186,12 +20339,12 @@ function rebuildHookActivityStats() {
20186
20339
  }
20187
20340
  function getAllHookActivityEntries() {
20188
20341
  ensureDir();
20189
- const currentPath = join6(storeDirValue(), CURRENT_FILE);
20342
+ const currentPath = join7(storeDirValue(), CURRENT_FILE);
20190
20343
  const currentEntries = readJsonlFile(currentPath).reverse();
20191
20344
  const archives = getArchiveFiles();
20192
20345
  const archiveEntries = [];
20193
20346
  for (const file of archives) {
20194
- const entries = readJsonlFile(join6(storeDirValue(), file));
20347
+ const entries = readJsonlFile(join7(storeDirValue(), file));
20195
20348
  archiveEntries.push(...entries.reverse());
20196
20349
  }
20197
20350
  return [...currentEntries, ...archiveEntries];
@@ -20202,7 +20355,7 @@ function getHookActivityEntriesSince(sinceMs) {
20202
20355
  const inWindow = (e) => typeof e.timestamp === "number" && e.timestamp >= sinceMs;
20203
20356
  const listedBefore = new Set(getArchiveFiles());
20204
20357
  sinceReadProbe?.("before-current");
20205
- const current = readJsonlFile(join6(dir, CURRENT_FILE));
20358
+ const current = readJsonlFile(join7(dir, CURRENT_FILE));
20206
20359
  sinceReadProbe?.("after-current");
20207
20360
  const readFromCurrent = new Map;
20208
20361
  for (const e of current) {
@@ -20222,7 +20375,7 @@ function getHookActivityEntriesSince(sinceMs) {
20222
20375
  const rotatedAt = parseInt(file.slice(5, -6).split("-")[0], 10);
20223
20376
  if (Number.isFinite(rotatedAt) && rotatedAt < sinceMs - ROTATION_CLOCK_SLACK_MS)
20224
20377
  break;
20225
- let entries = readJsonlFile(join6(dir, file));
20378
+ let entries = readJsonlFile(join7(dir, file));
20226
20379
  if (!listedBefore.has(file))
20227
20380
  entries = entries.filter(notReadYet);
20228
20381
  out.push(...entries.reverse().filter(inWindow));
@@ -20278,8 +20431,8 @@ var init_hook_activity_store = __esm(() => {
20278
20431
  });
20279
20432
 
20280
20433
  // src/hooks/delivery-health.ts
20281
- import { existsSync as existsSync13, readdirSync as readdirSync5, statSync as statSync6 } from "node:fs";
20282
- import { join as join7 } from "node:path";
20434
+ import { existsSync as existsSync14, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
20435
+ import { join as join8 } from "node:path";
20283
20436
  function parseParkedName(name) {
20284
20437
  const poison = name.endsWith(POISON_SUFFIX);
20285
20438
  const withoutPoison = poison ? name.slice(0, -POISON_SUFFIX.length) : name;
@@ -20307,7 +20460,7 @@ function parseParkedName(name) {
20307
20460
  }
20308
20461
  function deliveryHealth(home, now = Date.now()) {
20309
20462
  const dir = failedDir(home);
20310
- if (!existsSync13(dir))
20463
+ if (!existsSync14(dir))
20311
20464
  return EMPTY;
20312
20465
  let entries;
20313
20466
  try {
@@ -20332,7 +20485,7 @@ function deliveryHealth(home, now = Date.now()) {
20332
20485
  credentialRejected += 1;
20333
20486
  }
20334
20487
  try {
20335
- const mtime = statSync6(join7(dir, name)).mtimeMs;
20488
+ const mtime = statSync7(join8(dir, name)).mtimeMs;
20336
20489
  if (oldestMtime === undefined || mtime < oldestMtime)
20337
20490
  oldestMtime = mtime;
20338
20491
  } catch {}
@@ -20427,9 +20580,9 @@ function runtimeCache(fn, revalidateSeconds, options) {
20427
20580
 
20428
20581
  // lib/paths.ts
20429
20582
  import { homedir as homedir7 } from "os";
20430
- import { join as join8 } from "path";
20583
+ import { join as join9 } from "path";
20431
20584
  function getDefaultClaudeProjectsPath() {
20432
- return join8(homedir7(), ".claude", "projects");
20585
+ return join9(homedir7(), ".claude", "projects");
20433
20586
  }
20434
20587
  function decodeFolderName(name) {
20435
20588
  if (/^[A-Za-z]--/.test(name)) {
@@ -20520,7 +20673,7 @@ __export(exports_codex_projects, {
20520
20673
  });
20521
20674
  import { open, readdir } from "node:fs/promises";
20522
20675
  import { homedir as homedir8 } from "node:os";
20523
- import { join as join9 } from "node:path";
20676
+ import { join as join10 } from "node:path";
20524
20677
  async function safeReaddir(dir) {
20525
20678
  try {
20526
20679
  return await readdir(dir, { withFileTypes: true });
@@ -20568,7 +20721,7 @@ async function listJsonlFiles(dir) {
20568
20721
  const entries = await safeReaddir(dir);
20569
20722
  if (!entries)
20570
20723
  return [];
20571
- return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join9(dir, e.name));
20724
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join10(dir, e.name));
20572
20725
  }
20573
20726
  async function scanCodexSessions() {
20574
20727
  const yearDirs = await safeReaddir(CODEX_SESSIONS_ROOT);
@@ -20578,19 +20731,19 @@ async function scanCodexSessions() {
20578
20731
  for (const y of yearDirs) {
20579
20732
  if (!y.isDirectory())
20580
20733
  continue;
20581
- const monthDirs = await safeReaddir(join9(CODEX_SESSIONS_ROOT, y.name));
20734
+ const monthDirs = await safeReaddir(join10(CODEX_SESSIONS_ROOT, y.name));
20582
20735
  if (!monthDirs)
20583
20736
  continue;
20584
20737
  for (const m of monthDirs) {
20585
20738
  if (!m.isDirectory())
20586
20739
  continue;
20587
- const dayDirs = await safeReaddir(join9(CODEX_SESSIONS_ROOT, y.name, m.name));
20740
+ const dayDirs = await safeReaddir(join10(CODEX_SESSIONS_ROOT, y.name, m.name));
20588
20741
  if (!dayDirs)
20589
20742
  continue;
20590
20743
  for (const d of dayDirs) {
20591
20744
  if (!d.isDirectory())
20592
20745
  continue;
20593
- const dayPath = join9(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
20746
+ const dayPath = join10(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
20594
20747
  filePaths.push(...await listJsonlFiles(dayPath));
20595
20748
  }
20596
20749
  }
@@ -20698,7 +20851,7 @@ var CODEX_SESSIONS_ROOT, SESSION_ID_RE, FIRST_LINE_CHUNK_BYTES, cachedScan, getC
20698
20851
  var init_codex_projects = __esm(() => {
20699
20852
  init_paths();
20700
20853
  init_logger();
20701
- CODEX_SESSIONS_ROOT = join9(homedir8(), ".codex", "sessions");
20854
+ CODEX_SESSIONS_ROOT = join10(homedir8(), ".codex", "sessions");
20702
20855
  SESSION_ID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i;
20703
20856
  FIRST_LINE_CHUNK_BYTES = 256 * 1024;
20704
20857
  cachedScan = runtimeCache(scanCodexSessions, 30);
@@ -20715,9 +20868,9 @@ __export(exports_copilot_projects, {
20715
20868
  });
20716
20869
  import { readdir as readdir2, readFile as readFile4, stat } from "node:fs/promises";
20717
20870
  import { homedir as homedir9 } from "node:os";
20718
- import { join as join10 } from "node:path";
20871
+ import { join as join11 } from "node:path";
20719
20872
  function getCopilotSessionStateRoot() {
20720
- return join10(process.env.COPILOT_HOME || join10(homedir9(), ".copilot"), "session-state");
20873
+ return join11(process.env.COPILOT_HOME || join11(homedir9(), ".copilot"), "session-state");
20721
20874
  }
20722
20875
  async function safeReaddir2(dir) {
20723
20876
  try {
@@ -20746,8 +20899,8 @@ async function scanCopilotSessions() {
20746
20899
  return [];
20747
20900
  const candidates = entries.filter((e) => e.isDirectory()).map((e) => ({
20748
20901
  sessionId: e.name,
20749
- workspacePath: join10(root, e.name, "workspace.yaml"),
20750
- eventsPath: join10(root, e.name, "events.jsonl")
20902
+ workspacePath: join11(root, e.name, "workspace.yaml"),
20903
+ eventsPath: join11(root, e.name, "events.jsonl")
20751
20904
  }));
20752
20905
  const settled = await batchAll(candidates.map((c) => async () => {
20753
20906
  let workspaceText;
@@ -20859,9 +21012,9 @@ __export(exports_cursor_projects, {
20859
21012
  });
20860
21013
  import { readdir as readdir3, readFile as readFile5, stat as stat2 } from "node:fs/promises";
20861
21014
  import { homedir as homedir10 } from "node:os";
20862
- import { join as join11 } from "node:path";
21015
+ import { join as join12 } from "node:path";
20863
21016
  function getCursorHome() {
20864
- return process.env.CURSOR_HOME || join11(homedir10(), ".cursor");
21017
+ return process.env.CURSOR_HOME || join12(homedir10(), ".cursor");
20865
21018
  }
20866
21019
  async function safeReaddir3(dir) {
20867
21020
  try {
@@ -20893,7 +21046,7 @@ function parseCwdFromMetaText(text) {
20893
21046
  }
20894
21047
  async function findFirstUsableMeta(dir, candidates) {
20895
21048
  for (const name of candidates) {
20896
- const path = join11(dir, name);
21049
+ const path = join12(dir, name);
20897
21050
  if (await statMtime2(path) === null)
20898
21051
  continue;
20899
21052
  let text;
@@ -20910,7 +21063,7 @@ async function findFirstUsableMeta(dir, candidates) {
20910
21063
  }
20911
21064
  async function findFirstExistingPath(dir, candidates) {
20912
21065
  for (const name of candidates) {
20913
- const path = join11(dir, name);
21066
+ const path = join12(dir, name);
20914
21067
  if (await statMtime2(path) !== null)
20915
21068
  return path;
20916
21069
  }
@@ -20920,7 +21073,7 @@ async function scanCursorSessions() {
20920
21073
  const home = getCursorHome();
20921
21074
  const newCandidates = [];
20922
21075
  const legacyCandidates = [];
20923
- const projectsRoot = join11(home, NEW_PROJECTS_DIR);
21076
+ const projectsRoot = join12(home, NEW_PROJECTS_DIR);
20924
21077
  const projectEntries = await safeReaddir3(projectsRoot);
20925
21078
  if (projectEntries) {
20926
21079
  for (const proj of projectEntries) {
@@ -20928,7 +21081,7 @@ async function scanCursorSessions() {
20928
21081
  continue;
20929
21082
  const decoded = decodeFolderName(proj.name);
20930
21083
  const cwd = decoded.startsWith("/") || /^[A-Za-z]:\//.test(decoded) ? decoded : `/${decoded}`;
20931
- const transcriptsRoot = join11(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
21084
+ const transcriptsRoot = join12(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
20932
21085
  const sessionDirs = await safeReaddir3(transcriptsRoot);
20933
21086
  if (!sessionDirs)
20934
21087
  continue;
@@ -20937,28 +21090,28 @@ async function scanCursorSessions() {
20937
21090
  continue;
20938
21091
  newCandidates.push({
20939
21092
  sessionId: sd.name,
20940
- dir: join11(transcriptsRoot, sd.name),
21093
+ dir: join12(transcriptsRoot, sd.name),
20941
21094
  cwd
20942
21095
  });
20943
21096
  }
20944
21097
  }
20945
21098
  }
20946
21099
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES) {
20947
- const root = join11(home, sub);
21100
+ const root = join12(home, sub);
20948
21101
  const entries = await safeReaddir3(root);
20949
21102
  if (!entries)
20950
21103
  continue;
20951
21104
  for (const e of entries) {
20952
21105
  if (!e.isDirectory())
20953
21106
  continue;
20954
- legacyCandidates.push({ sessionId: e.name, dir: join11(root, e.name) });
21107
+ legacyCandidates.push({ sessionId: e.name, dir: join12(root, e.name) });
20955
21108
  }
20956
21109
  }
20957
21110
  if (newCandidates.length === 0 && legacyCandidates.length === 0)
20958
21111
  return [];
20959
21112
  const settled = await batchAll([
20960
21113
  ...newCandidates.map((c) => async () => {
20961
- const transcriptPath = join11(c.dir, `${c.sessionId}.jsonl`);
21114
+ const transcriptPath = join12(c.dir, `${c.sessionId}.jsonl`);
20962
21115
  const transcriptMtime = await statMtime2(transcriptPath);
20963
21116
  if (!transcriptMtime)
20964
21117
  return null;
@@ -21072,7 +21225,7 @@ var init_cursor_projects = __esm(() => {
21072
21225
  });
21073
21226
 
21074
21227
  // lib/sqlite-reader.ts
21075
- import { existsSync as existsSync14, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
21228
+ import { existsSync as existsSync15, readFileSync as readFileSync8, statSync as statSync8 } from "node:fs";
21076
21229
  import initSqlJs from "sql.js/dist/sql-asm.js";
21077
21230
  async function tryNodeSqlite(dbPath) {
21078
21231
  try {
@@ -21097,7 +21250,7 @@ function loadSqlJs() {
21097
21250
  return sqlPromise;
21098
21251
  }
21099
21252
  function fileVersion(path) {
21100
- const stat = statSync7(path);
21253
+ const stat = statSync8(path);
21101
21254
  return { size: stat.size, mtimeMs: stat.mtimeMs, ctimeMs: stat.ctimeMs };
21102
21255
  }
21103
21256
  function sameVersion(a, b) {
@@ -21230,7 +21383,7 @@ async function trySqlJs(dbPath) {
21230
21383
  }
21231
21384
  }
21232
21385
  async function openSqliteReadonly(dbPath, options = {}) {
21233
- if (!existsSync14(dbPath))
21386
+ if (!existsSync15(dbPath))
21234
21387
  return null;
21235
21388
  if (!options.forcePortable) {
21236
21389
  const native = await tryNodeSqlite(dbPath);
@@ -21244,12 +21397,12 @@ var init_sqlite_reader = () => {};
21244
21397
 
21245
21398
  // lib/opencode-db.ts
21246
21399
  import { homedir as homedir11 } from "node:os";
21247
- import { join as join12 } from "node:path";
21400
+ import { join as join13 } from "node:path";
21248
21401
  function opencodeDbPath() {
21249
21402
  if (process.env.OPENCODE_DB_PATH)
21250
21403
  return process.env.OPENCODE_DB_PATH;
21251
- const home = process.env.OPENCODE_HOME ?? join12(homedir11(), ".local", "share", "opencode");
21252
- return join12(home, "opencode.db");
21404
+ const home = process.env.OPENCODE_HOME ?? join13(homedir11(), ".local", "share", "opencode");
21405
+ return join13(home, "opencode.db");
21253
21406
  }
21254
21407
  async function withOpenCodeDb(fn) {
21255
21408
  const db = await openSqliteReadonly(opencodeDbPath());
@@ -21410,9 +21563,9 @@ __export(exports_pi_projects, {
21410
21563
  });
21411
21564
  import { readdir as readdir4, readFile as readFile6, stat as stat3 } from "node:fs/promises";
21412
21565
  import { homedir as homedir12 } from "node:os";
21413
- import { join as join13 } from "node:path";
21566
+ import { join as join14 } from "node:path";
21414
21567
  function getPiSessionsRoot() {
21415
- return process.env.PI_SESSIONS_DIR || join13(homedir12(), ".pi", "agent", "sessions");
21568
+ return process.env.PI_SESSIONS_DIR || join14(homedir12(), ".pi", "agent", "sessions");
21416
21569
  }
21417
21570
  async function safeReaddir4(dir) {
21418
21571
  try {
@@ -21460,7 +21613,7 @@ async function scanPiSessions() {
21460
21613
  for (const cwdDir of cwdDirs) {
21461
21614
  if (!cwdDir.isDirectory())
21462
21615
  continue;
21463
- const cwdPath = join13(root, cwdDir.name);
21616
+ const cwdPath = join14(root, cwdDir.name);
21464
21617
  const sessionFiles = await safeReaddir4(cwdPath);
21465
21618
  if (!sessionFiles)
21466
21619
  continue;
@@ -21470,7 +21623,7 @@ async function scanPiSessions() {
21470
21623
  const m = SESSION_FILE_RE.exec(f.name);
21471
21624
  if (!m)
21472
21625
  continue;
21473
- candidates.push({ sessionId: m[1], filePath: join13(cwdPath, f.name) });
21626
+ candidates.push({ sessionId: m[1], filePath: join14(cwdPath, f.name) });
21474
21627
  }
21475
21628
  }
21476
21629
  if (candidates.length === 0)
@@ -21592,14 +21745,14 @@ function formatDuration(ms) {
21592
21745
  }
21593
21746
 
21594
21747
  // lib/hermes-sessions.ts
21595
- import { join as join14 } from "node:path";
21748
+ import { join as join15 } from "node:path";
21596
21749
  function hermesDbPaths() {
21597
21750
  const override = process.env.HERMES_DB_PATH;
21598
21751
  if (override)
21599
21752
  return [{ profile: HERMES_DEFAULT_PROFILE, dbPath: override }];
21600
21753
  return listHermesProfiles().map((p) => ({
21601
21754
  profile: p.name,
21602
- dbPath: join14(p.home, "state.db")
21755
+ dbPath: join15(p.home, "state.db")
21603
21756
  }));
21604
21757
  }
21605
21758
  function epochToMs(value) {
@@ -21891,8 +22044,8 @@ var init_hermes_projects = __esm(() => {
21891
22044
  });
21892
22045
 
21893
22046
  // lib/openclaw-db.ts
21894
- import { existsSync as existsSync15 } from "node:fs";
21895
- import { join as join15 } from "node:path";
22047
+ import { existsSync as existsSync16 } from "node:fs";
22048
+ import { join as join16 } from "node:path";
21896
22049
  function str(value) {
21897
22050
  return typeof value === "string" && value.length > 0 ? value : undefined;
21898
22051
  }
@@ -21910,8 +22063,8 @@ function syntheticPath(agentId, sessionId) {
21910
22063
  function listOpenClawDatabases(home, agentIds) {
21911
22064
  const out = [];
21912
22065
  for (const agentId of agentIds) {
21913
- const dbPath = join15(home, "agents", agentId, "agent", DB_NAME);
21914
- if (existsSync15(dbPath))
22066
+ const dbPath = join16(home, "agents", agentId, "agent", DB_NAME);
22067
+ if (existsSync16(dbPath))
21915
22068
  out.push({ agentId, dbPath });
21916
22069
  }
21917
22070
  return out;
@@ -22048,11 +22201,11 @@ var init_openclaw_db = __esm(() => {
22048
22201
 
22049
22202
  // lib/openclaw-sessions.ts
22050
22203
  import { readFile as readFile7 } from "node:fs/promises";
22051
- import { readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
22204
+ import { readdirSync as readdirSync6, statSync as statSync9 } from "node:fs";
22052
22205
  import { homedir as homedir13 } from "node:os";
22053
- import { join as join16 } from "node:path";
22206
+ import { join as join17 } from "node:path";
22054
22207
  function openclawHome() {
22055
- return process.env.OPENCLAW_STATE_DIR || process.env.OPENCLAW_HOME || join16(homedir13(), ".openclaw");
22208
+ return process.env.OPENCLAW_STATE_DIR || process.env.OPENCLAW_HOME || join17(homedir13(), ".openclaw");
22056
22209
  }
22057
22210
  function isPlainObject3(v) {
22058
22211
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -22171,13 +22324,13 @@ function openclawLinesToLogEntries(lines, source = "session") {
22171
22324
  }
22172
22325
  function listOpenClawAgents() {
22173
22326
  try {
22174
- return readdirSync6(join16(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
22327
+ return readdirSync6(join17(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
22175
22328
  } catch {
22176
22329
  return [];
22177
22330
  }
22178
22331
  }
22179
22332
  function listOpenClawTranscripts() {
22180
- const agentsDir = join16(openclawHome(), "agents");
22333
+ const agentsDir = join17(openclawHome(), "agents");
22181
22334
  const out = [];
22182
22335
  let agentIds;
22183
22336
  try {
@@ -22186,7 +22339,7 @@ function listOpenClawTranscripts() {
22186
22339
  return out;
22187
22340
  }
22188
22341
  for (const agentId of agentIds) {
22189
- const sessionsDir = join16(agentsDir, agentId, "sessions");
22342
+ const sessionsDir = join17(agentsDir, agentId, "sessions");
22190
22343
  let files;
22191
22344
  try {
22192
22345
  files = readdirSync6(sessionsDir);
@@ -22199,9 +22352,9 @@ function listOpenClawTranscripts() {
22199
22352
  const sessionId = file.slice(0, -".jsonl".length);
22200
22353
  if (!OPENCLAW_SESSION_ID_RE.test(sessionId))
22201
22354
  continue;
22202
- const transcriptPath = join16(sessionsDir, file);
22355
+ const transcriptPath = join17(sessionsDir, file);
22203
22356
  try {
22204
- const st = statSync8(transcriptPath);
22357
+ const st = statSync9(transcriptPath);
22205
22358
  out.push({
22206
22359
  agentId,
22207
22360
  sessionId,
@@ -22279,13 +22432,13 @@ __export(exports_openclaw_projects, {
22279
22432
  openClawProjectPath: () => openClawProjectPath
22280
22433
  });
22281
22434
  import { readFileSync as readFileSync9 } from "node:fs";
22282
- import { join as join17 } from "node:path";
22435
+ import { join as join18 } from "node:path";
22283
22436
  function str2(v) {
22284
22437
  return typeof v === "string" && v.length > 0 ? v : undefined;
22285
22438
  }
22286
22439
  function readSessionsIndex(agentId) {
22287
22440
  const out = new Map;
22288
- const indexPath = join17(openclawHome(), "agents", agentId, "sessions", "sessions.json");
22441
+ const indexPath = join18(openclawHome(), "agents", agentId, "sessions", "sessions.json");
22289
22442
  let raw;
22290
22443
  try {
22291
22444
  raw = JSON.parse(readFileSync9(indexPath, "utf-8"));
@@ -22446,14 +22599,14 @@ var init_openclaw_projects = __esm(() => {
22446
22599
 
22447
22600
  // lib/factory-sessions.ts
22448
22601
  import { readFile as readFile8 } from "node:fs/promises";
22449
- import { readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
22602
+ import { readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
22450
22603
  import { homedir as homedir14 } from "node:os";
22451
- import { join as join18 } from "node:path";
22604
+ import { join as join19 } from "node:path";
22452
22605
  function factoryHome() {
22453
- return process.env.FACTORY_HOME || join18(homedir14(), ".factory");
22606
+ return process.env.FACTORY_HOME || join19(homedir14(), ".factory");
22454
22607
  }
22455
22608
  function factorySessionsRoot() {
22456
- return join18(factoryHome(), "sessions");
22609
+ return join19(factoryHome(), "sessions");
22457
22610
  }
22458
22611
  function isPlainObject4(v) {
22459
22612
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -22599,7 +22752,7 @@ function listFactoryTranscripts() {
22599
22752
  for (const dir of projectDirs) {
22600
22753
  const projectName = dir.name;
22601
22754
  const cwd = decodeFolderName(projectName);
22602
- const projectPath = join18(root, projectName);
22755
+ const projectPath = join19(root, projectName);
22603
22756
  let files;
22604
22757
  try {
22605
22758
  files = readdirSync7(projectPath);
@@ -22612,9 +22765,9 @@ function listFactoryTranscripts() {
22612
22765
  const sessionId = file.slice(0, -".jsonl".length);
22613
22766
  if (!FACTORY_SESSION_ID_RE.test(sessionId))
22614
22767
  continue;
22615
- const transcriptPath = join18(projectPath, file);
22768
+ const transcriptPath = join19(projectPath, file);
22616
22769
  try {
22617
- const st = statSync9(transcriptPath);
22770
+ const st = statSync10(transcriptPath);
22618
22771
  out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
22619
22772
  } catch {}
22620
22773
  }
@@ -22736,12 +22889,12 @@ var init_factory_projects = __esm(() => {
22736
22889
 
22737
22890
  // lib/devin-sessions.ts
22738
22891
  import { homedir as homedir15 } from "node:os";
22739
- import { join as join19 } from "node:path";
22892
+ import { join as join20 } from "node:path";
22740
22893
  function devinHome() {
22741
- return process.env.DEVIN_HOME || join19(homedir15(), ".local", "share", "devin");
22894
+ return process.env.DEVIN_HOME || join20(homedir15(), ".local", "share", "devin");
22742
22895
  }
22743
22896
  function devinDbPath() {
22744
- return process.env.DEVIN_DB_PATH || join19(devinHome(), "cli", "sessions.db");
22897
+ return process.env.DEVIN_DB_PATH || join20(devinHome(), "cli", "sessions.db");
22745
22898
  }
22746
22899
  function devinEpochToMs(value) {
22747
22900
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -23034,17 +23187,17 @@ var init_devin_projects = __esm(() => {
23034
23187
 
23035
23188
  // lib/antigravity-sessions.ts
23036
23189
  import { readFile as readFile9 } from "node:fs/promises";
23037
- import { readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
23190
+ import { readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
23038
23191
  import { homedir as homedir16 } from "node:os";
23039
- import { join as join20 } from "node:path";
23192
+ import { join as join21 } from "node:path";
23040
23193
  function antigravityHome() {
23041
- return process.env.ANTIGRAVITY_HOME || join20(homedir16(), ".gemini", "antigravity-cli");
23194
+ return process.env.ANTIGRAVITY_HOME || join21(homedir16(), ".gemini", "antigravity-cli");
23042
23195
  }
23043
23196
  function antigravityBrainRoot() {
23044
- return join20(antigravityHome(), "brain");
23197
+ return join21(antigravityHome(), "brain");
23045
23198
  }
23046
23199
  function antigravityTranscriptRelPath() {
23047
- return join20(".system_generated", "logs", "transcript_full.jsonl");
23200
+ return join21(".system_generated", "logs", "transcript_full.jsonl");
23048
23201
  }
23049
23202
  function isPlainObject6(v) {
23050
23203
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -23167,9 +23320,9 @@ function listAntigravityTranscripts() {
23167
23320
  const conversationId = dir.name;
23168
23321
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
23169
23322
  continue;
23170
- const transcriptPath = join20(root, conversationId, rel);
23323
+ const transcriptPath = join21(root, conversationId, rel);
23171
23324
  try {
23172
- const st = statSync10(transcriptPath);
23325
+ const st = statSync11(transcriptPath);
23173
23326
  if (!st.isFile())
23174
23327
  continue;
23175
23328
  out.push({ conversationId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -23180,9 +23333,9 @@ function listAntigravityTranscripts() {
23180
23333
  function findAntigravityTranscript(conversationId) {
23181
23334
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
23182
23335
  return null;
23183
- const transcriptPath = join20(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
23336
+ const transcriptPath = join21(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
23184
23337
  try {
23185
- if (statSync10(transcriptPath).isFile())
23338
+ if (statSync11(transcriptPath).isFile())
23186
23339
  return transcriptPath;
23187
23340
  } catch {}
23188
23341
  return null;
@@ -23216,9 +23369,9 @@ __export(exports_antigravity_projects, {
23216
23369
  getAntigravityIndex: () => getAntigravityIndex,
23217
23370
  getAntigravityProjects: () => getAntigravityProjects
23218
23371
  });
23219
- import { join as join21 } from "node:path";
23372
+ import { join as join22 } from "node:path";
23220
23373
  function antigravitySummariesDbPath() {
23221
- return join21(antigravityHome(), "conversation_summaries.db");
23374
+ return join22(antigravityHome(), "conversation_summaries.db");
23222
23375
  }
23223
23376
  function parseWorkspaceCwd(raw) {
23224
23377
  if (!raw)
@@ -23362,15 +23515,15 @@ var init_antigravity_projects = __esm(() => {
23362
23515
 
23363
23516
  // lib/goose-sessions.ts
23364
23517
  import { homedir as homedir17 } from "node:os";
23365
- import { join as join22 } from "node:path";
23518
+ import { join as join23 } from "node:path";
23366
23519
  function gooseHome() {
23367
23520
  if (process.env.GOOSE_HOME)
23368
23521
  return process.env.GOOSE_HOME;
23369
23522
  const xdg = process.env.XDG_DATA_HOME;
23370
- return join22(xdg && xdg.length > 0 ? xdg : join22(homedir17(), ".local", "share"), "goose");
23523
+ return join23(xdg && xdg.length > 0 ? xdg : join23(homedir17(), ".local", "share"), "goose");
23371
23524
  }
23372
23525
  function gooseDbPath() {
23373
- return process.env.GOOSE_DB_PATH || join22(gooseHome(), "sessions", "sessions.db");
23526
+ return process.env.GOOSE_DB_PATH || join23(gooseHome(), "sessions", "sessions.db");
23374
23527
  }
23375
23528
  function gooseTimestampToMs(value) {
23376
23529
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -23634,7 +23787,7 @@ var init_goose_projects = __esm(() => {
23634
23787
 
23635
23788
  // lib/projects.ts
23636
23789
  import { readdir as readdir5, stat as stat4 } from "node:fs/promises";
23637
- import { join as join23, resolve as resolve12, sep } from "node:path";
23790
+ import { join as join24, resolve as resolve12, sep } from "node:path";
23638
23791
  async function getMtime(path, label) {
23639
23792
  try {
23640
23793
  return (await stat4(path)).mtime;
@@ -23660,7 +23813,7 @@ async function getClaudeProjectFolders() {
23660
23813
  if (!entries)
23661
23814
  return [];
23662
23815
  const settled = await batchAll(entries.filter((entry) => entry.isDirectory()).map((entry) => async () => {
23663
- const folderPath = join23(projectsPath, entry.name);
23816
+ const folderPath = join24(projectsPath, entry.name);
23664
23817
  const mtime = await getMtime(folderPath, entry.name);
23665
23818
  return {
23666
23819
  name: entry.name,
@@ -23787,7 +23940,7 @@ function resolveProjectPath(projectName) {
23787
23940
  if (/^[/\\]/.test(projectName))
23788
23941
  throw new RangeError("Absolute project name");
23789
23942
  const projectsPath = resolve12(getClaudeProjectsPath());
23790
- const candidate = resolve12(join23(projectsPath, projectName));
23943
+ const candidate = resolve12(join24(projectsPath, projectName));
23791
23944
  if (!candidate.startsWith(projectsPath + sep)) {
23792
23945
  throw new RangeError("Project path escapes root");
23793
23946
  }
@@ -23805,7 +23958,7 @@ async function getSessionFiles(projectPath) {
23805
23958
  return [];
23806
23959
  const jsonlEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl") && extractSessionId2(entry.name));
23807
23960
  const settled = await batchAll(jsonlEntries.map((entry) => async () => {
23808
- const filePath = join23(projectPath, entry.name);
23961
+ const filePath = join24(projectPath, entry.name);
23809
23962
  const mtime = await getMtime(filePath, entry.name);
23810
23963
  return {
23811
23964
  name: entry.name,
@@ -23834,13 +23987,13 @@ var init_projects = __esm(() => {
23834
23987
 
23835
23988
  // lib/resolve-subagent-path.ts
23836
23989
  import { access as access2 } from "fs/promises";
23837
- import { join as join24, relative as relative3 } from "path";
23990
+ import { join as join25, relative as relative3 } from "path";
23838
23991
  async function resolveSubagentPath(projectsPath, projectName, sessionId, agentId) {
23839
23992
  const fileName = `agent-${agentId}.jsonl`;
23840
23993
  const candidatePaths = [
23841
- join24(projectsPath, projectName, fileName),
23842
- join24(projectsPath, projectName, sessionId, fileName),
23843
- join24(projectsPath, projectName, sessionId, "subagents", fileName)
23994
+ join25(projectsPath, projectName, fileName),
23995
+ join25(projectsPath, projectName, sessionId, fileName),
23996
+ join25(projectsPath, projectName, sessionId, "subagents", fileName)
23844
23997
  ];
23845
23998
  for (const candidatePath of candidatePaths) {
23846
23999
  if (relative3(projectsPath, candidatePath).startsWith("..")) {
@@ -23862,7 +24015,7 @@ var init_resolve_subagent_path = () => {};
23862
24015
 
23863
24016
  // lib/log-entries.ts
23864
24017
  import { readFile as readFile10 } from "fs/promises";
23865
- import { join as join25 } from "path";
24018
+ import { join as join26 } from "path";
23866
24019
  function formatTimestamp(date) {
23867
24020
  const base = formatDate(date);
23868
24021
  const ms = date.getMilliseconds().toString().padStart(3, "0");
@@ -24060,7 +24213,7 @@ async function parseLogContent(fileContent, source = "session") {
24060
24213
  async function parseSessionLog(projectName, sessionId) {
24061
24214
  const projectDir = resolveProjectPath(projectName);
24062
24215
  const projectsPath = getClaudeProjectsPath();
24063
- const filePath = join25(projectDir, `${sessionId}.jsonl`);
24216
+ const filePath = join26(projectDir, `${sessionId}.jsonl`);
24064
24217
  const fileContent = await readFile10(filePath, "utf-8");
24065
24218
  const { entries: sessionEntries, rawLines: sessionRawLines, subagentIds } = await parseFileContent(fileContent, "session");
24066
24219
  if (subagentIds.length === 0) {
@@ -24097,13 +24250,13 @@ var init_log_entries = __esm(() => {
24097
24250
  });
24098
24251
 
24099
24252
  // lib/codex-sessions.ts
24100
- import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync16, writeFileSync as writeFileSync6, mkdirSync as mkdirSync7, statSync as statSync11 } from "node:fs";
24253
+ import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync17, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8, statSync as statSync12 } from "node:fs";
24101
24254
  import { readFile as readFile11 } from "node:fs/promises";
24102
- import { dirname as dirname8, join as join26 } from "node:path";
24255
+ import { dirname as dirname9, join as join27 } from "node:path";
24103
24256
  import { homedir as homedir18 } from "node:os";
24104
24257
  function readCache() {
24105
24258
  try {
24106
- if (!existsSync16(CACHE_PATH))
24259
+ if (!existsSync17(CACHE_PATH))
24107
24260
  return {};
24108
24261
  return JSON.parse(readFileSync10(CACHE_PATH, "utf-8"));
24109
24262
  } catch {
@@ -24112,7 +24265,7 @@ function readCache() {
24112
24265
  }
24113
24266
  function writeCacheEntry(sessionId, path) {
24114
24267
  try {
24115
- mkdirSync7(dirname8(CACHE_PATH), { recursive: true });
24268
+ mkdirSync8(dirname9(CACHE_PATH), { recursive: true });
24116
24269
  const cache = readCache();
24117
24270
  cache[sessionId] = path;
24118
24271
  writeFileSync6(CACHE_PATH, JSON.stringify(cache), "utf-8");
@@ -24122,7 +24275,7 @@ function dirSearch(dir, sessionId) {
24122
24275
  try {
24123
24276
  for (const f of readdirSync9(dir, { withFileTypes: true })) {
24124
24277
  if (f.isFile() && f.name.includes(sessionId) && f.name.endsWith(".jsonl")) {
24125
- return join26(dir, f.name);
24278
+ return join27(dir, f.name);
24126
24279
  }
24127
24280
  }
24128
24281
  } catch {}
@@ -24131,16 +24284,16 @@ function dirSearch(dir, sessionId) {
24131
24284
  function findCodexTranscript(sessionId) {
24132
24285
  const cache = readCache();
24133
24286
  const cached = cache[sessionId];
24134
- if (cached && existsSync16(cached))
24287
+ if (cached && existsSync17(cached))
24135
24288
  return cached;
24136
- const root = join26(homedir18(), ".codex", "sessions");
24289
+ const root = join27(homedir18(), ".codex", "sessions");
24137
24290
  const today = new Date;
24138
24291
  const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
24139
24292
  const datedDirs = [today, yesterday].map((d) => {
24140
24293
  const y = String(d.getUTCFullYear());
24141
24294
  const m = String(d.getUTCMonth() + 1).padStart(2, "0");
24142
24295
  const day = String(d.getUTCDate()).padStart(2, "0");
24143
- return join26(root, y, m, day);
24296
+ return join27(root, y, m, day);
24144
24297
  });
24145
24298
  for (const dir of datedDirs) {
24146
24299
  const hit = dirSearch(dir, sessionId);
@@ -24153,13 +24306,13 @@ function findCodexTranscript(sessionId) {
24153
24306
  for (const y of readdirSync9(root, { withFileTypes: true })) {
24154
24307
  if (!y.isDirectory())
24155
24308
  continue;
24156
- for (const m of readdirSync9(join26(root, y.name), { withFileTypes: true })) {
24309
+ for (const m of readdirSync9(join27(root, y.name), { withFileTypes: true })) {
24157
24310
  if (!m.isDirectory())
24158
24311
  continue;
24159
- for (const d of readdirSync9(join26(root, y.name, m.name), { withFileTypes: true })) {
24312
+ for (const d of readdirSync9(join27(root, y.name, m.name), { withFileTypes: true })) {
24160
24313
  if (!d.isDirectory())
24161
24314
  continue;
24162
- const hit = dirSearch(join26(root, y.name, m.name, d.name), sessionId);
24315
+ const hit = dirSearch(join27(root, y.name, m.name, d.name), sessionId);
24163
24316
  if (hit) {
24164
24317
  writeCacheEntry(sessionId, hit);
24165
24318
  return hit;
@@ -24425,15 +24578,15 @@ var init_resolve_permission_mode = __esm(() => {
24425
24578
  });
24426
24579
 
24427
24580
  // lib/copilot-sessions.ts
24428
- import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync17, statSync as statSync12 } from "node:fs";
24581
+ import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync18, statSync as statSync13 } from "node:fs";
24429
24582
  import { readFile as readFile12 } from "node:fs/promises";
24430
- import { join as join27, resolve as resolve13, sep as sep2 } from "node:path";
24583
+ import { join as join28, resolve as resolve13, sep as sep2 } from "node:path";
24431
24584
  import { homedir as homedir19 } from "node:os";
24432
24585
  function getCopilotHome() {
24433
- return process.env.COPILOT_HOME || join27(homedir19(), ".copilot");
24586
+ return process.env.COPILOT_HOME || join28(homedir19(), ".copilot");
24434
24587
  }
24435
24588
  function getCopilotSessionStateRoot2() {
24436
- return join27(getCopilotHome(), "session-state");
24589
+ return join28(getCopilotHome(), "session-state");
24437
24590
  }
24438
24591
  function getCopilotSessionDir(sessionId) {
24439
24592
  if (!sessionId)
@@ -24448,19 +24601,19 @@ function resolveSessionFile(sessionId, filename) {
24448
24601
  const dir = getCopilotSessionDir(sessionId);
24449
24602
  if (!dir)
24450
24603
  return null;
24451
- return join27(dir, filename);
24604
+ return join28(dir, filename);
24452
24605
  }
24453
24606
  function findCopilotTranscript(sessionId) {
24454
24607
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
24455
24608
  if (!candidate)
24456
24609
  return null;
24457
- return existsSync17(candidate) ? candidate : null;
24610
+ return existsSync18(candidate) ? candidate : null;
24458
24611
  }
24459
24612
  function findCopilotWorkspace(sessionId) {
24460
24613
  const candidate = resolveSessionFile(sessionId, "workspace.yaml");
24461
24614
  if (!candidate)
24462
24615
  return null;
24463
- return existsSync17(candidate) ? candidate : null;
24616
+ return existsSync18(candidate) ? candidate : null;
24464
24617
  }
24465
24618
  function readYamlScalar(path, key) {
24466
24619
  try {
@@ -24642,12 +24795,12 @@ var init_copilot_sessions = __esm(() => {
24642
24795
  });
24643
24796
 
24644
24797
  // lib/cursor-sessions.ts
24645
- import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync18, statSync as statSync13 } from "node:fs";
24798
+ import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync19, statSync as statSync14 } from "node:fs";
24646
24799
  import { readFile as readFile13 } from "node:fs/promises";
24647
- import { basename as basename5, join as join28, resolve as resolve14, sep as sep3 } from "node:path";
24800
+ import { basename as basename6, join as join29, resolve as resolve14, sep as sep3 } from "node:path";
24648
24801
  import { homedir as homedir20 } from "node:os";
24649
24802
  function getCursorHome2() {
24650
- return process.env.CURSOR_HOME || join28(homedir20(), ".cursor");
24803
+ return process.env.CURSOR_HOME || join29(homedir20(), ".cursor");
24651
24804
  }
24652
24805
  function getCursorSessionDir(sessionId) {
24653
24806
  if (!sessionId)
@@ -24665,7 +24818,7 @@ function getCursorSessionDir(sessionId) {
24665
24818
  const transcriptRoot = resolve14(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
24666
24819
  if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
24667
24820
  continue;
24668
- if (existsSync18(candidate))
24821
+ if (existsSync19(candidate))
24669
24822
  return candidate;
24670
24823
  }
24671
24824
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
@@ -24673,7 +24826,7 @@ function getCursorSessionDir(sessionId) {
24673
24826
  const candidate = resolve14(root, sessionId);
24674
24827
  if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
24675
24828
  continue;
24676
- if (existsSync18(candidate))
24829
+ if (existsSync19(candidate))
24677
24830
  return candidate;
24678
24831
  }
24679
24832
  return null;
@@ -24682,12 +24835,12 @@ function findCursorTranscript(sessionId) {
24682
24835
  const dir = getCursorSessionDir(sessionId);
24683
24836
  if (!dir)
24684
24837
  return null;
24685
- const newCandidate = join28(dir, `${basename5(dir)}.jsonl`);
24686
- if (existsSync18(newCandidate))
24838
+ const newCandidate = join29(dir, `${basename6(dir)}.jsonl`);
24839
+ if (existsSync19(newCandidate))
24687
24840
  return newCandidate;
24688
24841
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
24689
- const candidate = join28(dir, name);
24690
- if (existsSync18(candidate))
24842
+ const candidate = join29(dir, name);
24843
+ if (existsSync19(candidate))
24691
24844
  return candidate;
24692
24845
  }
24693
24846
  return null;
@@ -24898,12 +25051,12 @@ var init_cursor_sessions = __esm(() => {
24898
25051
  });
24899
25052
 
24900
25053
  // lib/pi-sessions.ts
24901
- import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync19, statSync as statSync14 } from "node:fs";
25054
+ import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync20, statSync as statSync15 } from "node:fs";
24902
25055
  import { readFile as readFile14 } from "node:fs/promises";
24903
- import { join as join29, resolve as resolve15, sep as sep4 } from "node:path";
25056
+ import { join as join30, resolve as resolve15, sep as sep4 } from "node:path";
24904
25057
  import { homedir as homedir21 } from "node:os";
24905
25058
  function getPiSessionStateRoot() {
24906
- return process.env.PI_SESSIONS_DIR || join29(homedir21(), ".pi", "agent", "sessions");
25059
+ return process.env.PI_SESSIONS_DIR || join30(homedir21(), ".pi", "agent", "sessions");
24907
25060
  }
24908
25061
  function isSafeSessionId(sessionId) {
24909
25062
  return UUID_RE.test(sessionId);
@@ -24935,7 +25088,7 @@ function findPiTranscript(sessionId) {
24935
25088
  const candidate = resolve15(cwdPath, f);
24936
25089
  if (!candidate.startsWith(`${cwdPath}${sep4}`))
24937
25090
  continue;
24938
- if (existsSync19(candidate))
25091
+ if (existsSync20(candidate))
24939
25092
  return candidate;
24940
25093
  }
24941
25094
  }
@@ -25342,37 +25495,37 @@ var init_pack_failclosed = __esm(() => {
25342
25495
 
25343
25496
  // lib/atomic-write.ts
25344
25497
  import {
25345
- chmodSync as chmodSync2,
25346
- existsSync as existsSync20,
25347
- mkdirSync as mkdirSync8,
25348
- renameSync as renameSync5,
25349
- rmSync as rmSync4,
25350
- statSync as statSync15,
25498
+ chmodSync as chmodSync3,
25499
+ existsSync as existsSync21,
25500
+ mkdirSync as mkdirSync9,
25501
+ renameSync as renameSync6,
25502
+ rmSync as rmSync5,
25503
+ statSync as statSync16,
25351
25504
  writeFileSync as writeFileSync7
25352
25505
  } from "node:fs";
25353
- import { dirname as dirname9 } from "node:path";
25354
- import { randomBytes } from "node:crypto";
25506
+ import { dirname as dirname10 } from "node:path";
25507
+ import { randomBytes as randomBytes2 } from "node:crypto";
25355
25508
  function writeJsonAtomically(filePath, value, opts = {}) {
25356
25509
  const mode = opts.mode ?? 384;
25357
25510
  const dirMode = opts.dirMode ?? 448;
25358
- const dir = dirname9(filePath);
25359
- if (!existsSync20(dir))
25360
- mkdirSync8(dir, { recursive: true, mode: dirMode });
25361
- const tmp = `${filePath}.${process.pid}.${randomBytes(6).toString("hex")}.tmp`;
25511
+ const dir = dirname10(filePath);
25512
+ if (!existsSync21(dir))
25513
+ mkdirSync9(dir, { recursive: true, mode: dirMode });
25514
+ const tmp = `${filePath}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
25362
25515
  try {
25363
25516
  writeFileSync7(tmp, JSON.stringify(value, null, 2), { mode });
25364
25517
  try {
25365
- if ((statSync15(tmp).mode & 63) !== 0)
25366
- chmodSync2(tmp, mode);
25518
+ if ((statSync16(tmp).mode & 63) !== 0)
25519
+ chmodSync3(tmp, mode);
25367
25520
  } catch {}
25368
- renameSync5(tmp, filePath);
25521
+ renameSync6(tmp, filePath);
25369
25522
  try {
25370
- if ((statSync15(filePath).mode & 63) !== 0)
25371
- chmodSync2(filePath, mode);
25523
+ if ((statSync16(filePath).mode & 63) !== 0)
25524
+ chmodSync3(filePath, mode);
25372
25525
  } catch {}
25373
25526
  } catch (err) {
25374
25527
  try {
25375
- rmSync4(tmp, { force: true });
25528
+ rmSync5(tmp, { force: true });
25376
25529
  } catch {}
25377
25530
  throw err;
25378
25531
  }
@@ -25380,9 +25533,9 @@ function writeJsonAtomically(filePath, value, opts = {}) {
25380
25533
  var init_atomic_write = () => {};
25381
25534
 
25382
25535
  // src/hooks/session-pause.ts
25383
- import { existsSync as existsSync21, mkdirSync as mkdirSync9, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync5 } from "node:fs";
25536
+ import { existsSync as existsSync22, mkdirSync as mkdirSync10, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync6 } from "node:fs";
25384
25537
  import { createHash as createHash6 } from "node:crypto";
25385
- import { join as join30, resolve as resolve16 } from "node:path";
25538
+ import { join as join31, resolve as resolve16 } from "node:path";
25386
25539
  function pauseStateDir() {
25387
25540
  const override = process.env.FAILPROOFAI_STATE_DIR;
25388
25541
  if (override)
@@ -25391,7 +25544,7 @@ function pauseStateDir() {
25391
25544
  }
25392
25545
  function pauseFilePath(sessionId) {
25393
25546
  const digest = createHash6("sha256").update(sessionId).digest("hex").slice(0, 32);
25394
- return join30(pauseStateDir(), `${digest}.json`);
25547
+ return join31(pauseStateDir(), `${digest}.json`);
25395
25548
  }
25396
25549
  function parsePauseDuration(input, ceilingMs = PAUSE_CEILING_MS) {
25397
25550
  if (input === undefined || input === "")
@@ -25447,7 +25600,7 @@ function readActivePause(sessionId, now = Date.now()) {
25447
25600
  return null;
25448
25601
  try {
25449
25602
  const path = pauseFilePath(sessionId);
25450
- if (!existsSync21(path))
25603
+ if (!existsSync22(path))
25451
25604
  return null;
25452
25605
  const stored = parseStored(JSON.parse(readFileSync15(path, "utf8")));
25453
25606
  if (!stored)
@@ -25472,16 +25625,16 @@ function writePause(opts) {
25472
25625
  setBy: opts.setBy ?? "cli",
25473
25626
  ...opts.cwd ? { cwd: opts.cwd } : {}
25474
25627
  };
25475
- mkdirSync9(pauseStateDir(), { recursive: true, mode: 448 });
25628
+ mkdirSync10(pauseStateDir(), { recursive: true, mode: 448 });
25476
25629
  writeJsonAtomically(pauseFilePath(opts.sessionId), { schemaVersion: SCHEMA_VERSION, ...pause });
25477
25630
  return pause;
25478
25631
  }
25479
25632
  function clearPause(sessionId) {
25480
25633
  const path = pauseFilePath(sessionId);
25481
- if (!existsSync21(path))
25634
+ if (!existsSync22(path))
25482
25635
  return false;
25483
25636
  try {
25484
- rmSync5(path);
25637
+ rmSync6(path);
25485
25638
  return true;
25486
25639
  } catch {
25487
25640
  return false;
@@ -25489,7 +25642,7 @@ function clearPause(sessionId) {
25489
25642
  }
25490
25643
  function listActivePauses(now = Date.now()) {
25491
25644
  const dir = pauseStateDir();
25492
- if (!existsSync21(dir))
25645
+ if (!existsSync22(dir))
25493
25646
  return [];
25494
25647
  const out = [];
25495
25648
  let names;
@@ -25502,7 +25655,7 @@ function listActivePauses(now = Date.now()) {
25502
25655
  if (!name.endsWith(".json"))
25503
25656
  continue;
25504
25657
  try {
25505
- const stored = parseStored(JSON.parse(readFileSync15(join30(dir, name), "utf8")));
25658
+ const stored = parseStored(JSON.parse(readFileSync15(join31(dir, name), "utf8")));
25506
25659
  if (!stored || stored.expiresAt <= now)
25507
25660
  continue;
25508
25661
  const { schemaVersion: _ignored, ...pause } = stored;
@@ -25542,18 +25695,18 @@ var init_session_pause = __esm(() => {
25542
25695
  // src/hooks/daemon-download.ts
25543
25696
  import { createHash as createHash7 } from "node:crypto";
25544
25697
  import {
25545
- chmodSync as chmodSync3,
25546
- existsSync as existsSync22,
25547
- mkdirSync as mkdirSync10,
25698
+ chmodSync as chmodSync4,
25699
+ existsSync as existsSync23,
25700
+ mkdirSync as mkdirSync11,
25548
25701
  readdirSync as readdirSync14,
25549
25702
  readFileSync as readFileSync16,
25550
- renameSync as renameSync6,
25551
- rmSync as rmSync6,
25552
- statSync as statSync16,
25703
+ renameSync as renameSync7,
25704
+ rmSync as rmSync7,
25705
+ statSync as statSync17,
25553
25706
  writeFileSync as writeFileSync8
25554
25707
  } from "node:fs";
25555
25708
  import { createRequire as createRequire2 } from "node:module";
25556
- import { dirname as dirname10, resolve as resolve17 } from "node:path";
25709
+ import { dirname as dirname11, resolve as resolve17 } from "node:path";
25557
25710
  import { gunzipSync } from "node:zlib";
25558
25711
  function baseUrl2() {
25559
25712
  return (process.env.FAILPROOFAI_DAEMON_BASE_URL || DEFAULT_BASE_URL2).replace(/\/+$/, "");
@@ -25580,7 +25733,7 @@ function npmPlatformBinaryPath(key) {
25580
25733
  const name = platformPackageName(key);
25581
25734
  try {
25582
25735
  const requireFromRoot = createRequire2(resolve17(packageRoot, "package.json"));
25583
- const found = platformPackageBinary(dirname10(requireFromRoot.resolve(`${name}/package.json`)));
25736
+ const found = platformPackageBinary(dirname11(requireFromRoot.resolve(`${name}/package.json`)));
25584
25737
  if (found)
25585
25738
  return found;
25586
25739
  } catch {}
@@ -25595,7 +25748,7 @@ function platformPackageBinary(dir) {
25595
25748
  return null;
25596
25749
  }
25597
25750
  const candidate = resolve17(dir, "bin", "failproofaid");
25598
- return existsSync22(candidate) ? candidate : null;
25751
+ return existsSync23(candidate) ? candidate : null;
25599
25752
  }
25600
25753
  function pruneOldDaemonBinaries(keep = 2) {
25601
25754
  const removed = [];
@@ -25603,11 +25756,11 @@ function pruneOldDaemonBinaries(keep = 2) {
25603
25756
  const dir = daemonBinaryDir();
25604
25757
  const entries = readdirSync14(dir).filter((f) => f.startsWith("failproofaid-") && !f.endsWith(".tmp")).map((f) => {
25605
25758
  const full = resolve17(dir, f);
25606
- return { full, mtime: statSync16(full).mtimeMs };
25759
+ return { full, mtime: statSync17(full).mtimeMs };
25607
25760
  }).sort((a, b) => b.mtime - a.mtime);
25608
25761
  for (const stale of entries.slice(keep)) {
25609
25762
  try {
25610
- rmSync6(stale.full, { force: true });
25763
+ rmSync7(stale.full, { force: true });
25611
25764
  removed.push(stale.full);
25612
25765
  } catch {}
25613
25766
  }
@@ -25618,13 +25771,13 @@ function installBinaryBytes(binary) {
25618
25771
  const target = installedBinaryPath();
25619
25772
  const tempPath = `${target}.${process.pid}.tmp`;
25620
25773
  try {
25621
- mkdirSync10(daemonBinaryDir(), { recursive: true });
25774
+ mkdirSync11(daemonBinaryDir(), { recursive: true });
25622
25775
  writeFileSync8(tempPath, binary);
25623
- chmodSync3(tempPath, 493);
25624
- renameSync6(tempPath, target);
25776
+ chmodSync4(tempPath, 493);
25777
+ renameSync7(tempPath, target);
25625
25778
  return target;
25626
25779
  } catch (err) {
25627
- rmSync6(tempPath, { force: true });
25780
+ rmSync7(tempPath, { force: true });
25628
25781
  throw err;
25629
25782
  }
25630
25783
  }
@@ -25673,7 +25826,7 @@ function digestFor2(manifest, assetName) {
25673
25826
  }
25674
25827
  async function downloadFailproofaidBinary(key) {
25675
25828
  const target = installedBinaryPath();
25676
- if (existsSync22(target))
25829
+ if (existsSync23(target))
25677
25830
  return { path: target };
25678
25831
  if (process.env.FAILPROOFAI_NO_DOWNLOAD) {
25679
25832
  return { error: "daemon downloads are disabled (FAILPROOFAI_NO_DOWNLOAD)" };
@@ -25707,10 +25860,10 @@ var init_daemon_download = __esm(() => {
25707
25860
 
25708
25861
  // src/hooks/daemon-client.ts
25709
25862
  import { createConnection as createConnection2 } from "node:net";
25710
- import { existsSync as existsSync23 } from "node:fs";
25863
+ import { existsSync as existsSync24 } from "node:fs";
25711
25864
  function daemonSocketPresent() {
25712
25865
  try {
25713
- return existsSync23(socketPath2());
25866
+ return existsSync24(socketPath2());
25714
25867
  } catch {
25715
25868
  return false;
25716
25869
  }
@@ -25868,13 +26021,13 @@ var init_daemon_client2 = __esm(() => {
25868
26021
 
25869
26022
  // src/hooks/daemon-service.ts
25870
26023
  import {
25871
- existsSync as existsSync24,
25872
- mkdirSync as mkdirSync11,
26024
+ existsSync as existsSync25,
26025
+ mkdirSync as mkdirSync12,
25873
26026
  mkdtempSync,
25874
26027
  readFileSync as readFileSync17,
25875
26028
  writeFileSync as writeFileSync9,
25876
26029
  unlinkSync as unlinkSync3,
25877
- rmSync as rmSync7
26030
+ rmSync as rmSync8
25878
26031
  } from "node:fs";
25879
26032
  import { homedir as homedir22, tmpdir as tmpdir2, userInfo } from "node:os";
25880
26033
  import { resolve as resolve18 } from "node:path";
@@ -25899,13 +26052,13 @@ function resolveFailproofaidBinaryPath() {
25899
26052
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
25900
26053
  return process.env.FAILPROOFAI_DAEMON_BINARY;
25901
26054
  const downloaded = installedBinaryPath();
25902
- if (existsSync24(downloaded))
26055
+ if (existsSync25(downloaded))
25903
26056
  return downloaded;
25904
26057
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
25905
26058
  if (packageRoot) {
25906
26059
  for (const profile of ["release", "debug"]) {
25907
26060
  const candidate = resolve18(packageRoot, "target", profile, "failproofaid");
25908
- if (existsSync24(candidate))
26061
+ if (existsSync25(candidate))
25909
26062
  return candidate;
25910
26063
  }
25911
26064
  }
@@ -25936,7 +26089,7 @@ function resolveWorkerCommand() {
25936
26089
  if (!packageRoot)
25937
26090
  return null;
25938
26091
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
25939
- if (!existsSync24(workerScript))
26092
+ if (!existsSync25(workerScript))
25940
26093
  return null;
25941
26094
  return `${shellQuote(process.execPath)} ${shellQuote(workerScript)}`;
25942
26095
  }
@@ -25947,7 +26100,7 @@ function resolveCliCommand() {
25947
26100
  if (!packageRoot)
25948
26101
  return null;
25949
26102
  const cliScript = resolve18(packageRoot, "dist", "cli.mjs");
25950
- if (!existsSync24(cliScript))
26103
+ if (!existsSync25(cliScript))
25951
26104
  return null;
25952
26105
  return `${shellQuote(process.execPath)} ${shellQuote(cliScript)}`;
25953
26106
  }
@@ -25961,7 +26114,7 @@ function workerScriptPath() {
25961
26114
  if (!packageRoot)
25962
26115
  return null;
25963
26116
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
25964
- return existsSync24(workerScript) ? workerScript : null;
26117
+ return existsSync25(workerScript) ? workerScript : null;
25965
26118
  }
25966
26119
  function assertUnitSafe(value, field) {
25967
26120
  if (UNIT_UNSAFE_RE.test(value)) {
@@ -26053,14 +26206,14 @@ function writePrivilegedFile(destination, contents, mode = "0644") {
26053
26206
  writeFileSync9(staging, contents, "utf8");
26054
26207
  runPrivileged("install", ["-m", mode, staging, destination]);
26055
26208
  } finally {
26056
- rmSync7(stagingDir, { recursive: true, force: true });
26209
+ rmSync8(stagingDir, { recursive: true, force: true });
26057
26210
  }
26058
26211
  }
26059
26212
  function removeLegacyUserService() {
26060
26213
  try {
26061
26214
  if (process.platform === "linux") {
26062
26215
  const legacy = legacySystemdUserUnitPath();
26063
- if (!existsSync24(legacy))
26216
+ if (!existsSync25(legacy))
26064
26217
  return;
26065
26218
  try {
26066
26219
  execFileSync2("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -26077,7 +26230,7 @@ function removeLegacyUserService() {
26077
26230
  } catch {}
26078
26231
  } else {
26079
26232
  const legacyAgent = legacyLaunchAgentPlistPath();
26080
- if (existsSync24(legacyAgent)) {
26233
+ if (existsSync25(legacyAgent)) {
26081
26234
  try {
26082
26235
  execFileSync2("launchctl", ["unload", "-w", legacyAgent], {
26083
26236
  stdio: "ignore",
@@ -26087,7 +26240,7 @@ function removeLegacyUserService() {
26087
26240
  unlinkSync3(legacyAgent);
26088
26241
  }
26089
26242
  const legacyDaemon = legacySharedLaunchDaemonPath();
26090
- if (existsSync24(legacyDaemon)) {
26243
+ if (existsSync25(legacyDaemon)) {
26091
26244
  try {
26092
26245
  runPrivileged("launchctl", ["unload", "-w", legacyDaemon]);
26093
26246
  } catch {}
@@ -26104,7 +26257,7 @@ function systemdUnitContents(binaryPath, workerCmd, cliCmd = null) {
26104
26257
  const user = assertUnitSafe(serviceUser(), "User");
26105
26258
  assertUnitSafe(binaryPath, "ExecStart");
26106
26259
  assertUnitSafe(homedir22(), "HOME");
26107
- const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync24(p));
26260
+ const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync25(p));
26108
26261
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe(p, "ConditionPathExists")}
26109
26262
  `).join("");
26110
26263
  return `[Unit]
@@ -26213,7 +26366,7 @@ async function installDaemonService() {
26213
26366
  } else {
26214
26367
  const plistPath = launchdPlistPath();
26215
26368
  const logDir = logsDir();
26216
- mkdirSync11(logDir, { recursive: true });
26369
+ mkdirSync12(logDir, { recursive: true });
26217
26370
  try {
26218
26371
  runPrivileged("launchctl", ["unload", plistPath]);
26219
26372
  } catch {}
@@ -26317,7 +26470,7 @@ function readInstalledServiceDefinition() {
26317
26470
  if (!isDaemonSupportedPlatform())
26318
26471
  return null;
26319
26472
  const path = daemonServiceFilePath();
26320
- if (!path || !existsSync24(path))
26473
+ if (!path || !existsSync25(path))
26321
26474
  return null;
26322
26475
  try {
26323
26476
  return readFileSync17(path, "utf8");
@@ -26429,7 +26582,7 @@ async function ensureDaemonServiceCurrent() {
26429
26582
  restartSystemdUnit();
26430
26583
  } else {
26431
26584
  const plistPath = launchdPlistPath();
26432
- mkdirSync11(logDir, { recursive: true });
26585
+ mkdirSync12(logDir, { recursive: true });
26433
26586
  previous = definition;
26434
26587
  try {
26435
26588
  runPrivileged("launchctl", ["unload", plistPath]);
@@ -26453,7 +26606,7 @@ async function uninstallDaemonService() {
26453
26606
  try {
26454
26607
  if (process.platform === "linux") {
26455
26608
  const unitPath = systemdUnitPath();
26456
- if (!existsSync24(unitPath))
26609
+ if (!existsSync25(unitPath))
26457
26610
  return;
26458
26611
  try {
26459
26612
  runPrivileged("systemctl", ["disable", "--now", systemdUnitName()]);
@@ -26464,7 +26617,7 @@ async function uninstallDaemonService() {
26464
26617
  } catch {}
26465
26618
  } else {
26466
26619
  const plistPath = launchdPlistPath();
26467
- if (!existsSync24(plistPath))
26620
+ if (!existsSync25(plistPath))
26468
26621
  return;
26469
26622
  try {
26470
26623
  runPrivileged("launchctl", ["unload", "-w", plistPath]);
@@ -26481,7 +26634,7 @@ function daemonVersionSkew() {
26481
26634
  const recorded = readVersionFile()?.daemon;
26482
26635
  if (!recorded)
26483
26636
  return null;
26484
- if (!existsSync24(installedBinaryPath(recorded)))
26637
+ if (!existsSync25(installedBinaryPath(recorded)))
26485
26638
  return null;
26486
26639
  return recorded === version2 ? null : { installed: recorded, expected: version2 };
26487
26640
  }
@@ -26499,7 +26652,7 @@ function daemonServiceStatus() {
26499
26652
  if (!isDaemonSupportedPlatform())
26500
26653
  return "unsupported-platform";
26501
26654
  if (process.platform === "linux") {
26502
- if (!existsSync24(systemdUnitPath()))
26655
+ if (!existsSync25(systemdUnitPath()))
26503
26656
  return "not-installed";
26504
26657
  try {
26505
26658
  const out = execFileSync2("systemctl", ["is-active", systemdUnitName()], {
@@ -26512,7 +26665,7 @@ function daemonServiceStatus() {
26512
26665
  }
26513
26666
  }
26514
26667
  const plistPath = launchdPlistPath();
26515
- if (!existsSync24(plistPath))
26668
+ if (!existsSync25(plistPath))
26516
26669
  return "not-installed";
26517
26670
  try {
26518
26671
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -26543,21 +26696,21 @@ var init_daemon_service = __esm(() => {
26543
26696
 
26544
26697
  // src/hooks/fp-reset.ts
26545
26698
  import {
26546
- copyFileSync,
26547
- existsSync as existsSync25,
26548
- mkdirSync as mkdirSync12,
26699
+ copyFileSync as copyFileSync2,
26700
+ existsSync as existsSync26,
26701
+ mkdirSync as mkdirSync13,
26549
26702
  readFileSync as readFileSync18,
26550
26703
  readdirSync as readdirSync15,
26551
- renameSync as renameSync7,
26552
- rmSync as rmSync8,
26704
+ renameSync as renameSync8,
26705
+ rmSync as rmSync9,
26553
26706
  rmdirSync,
26554
- statSync as statSync17,
26707
+ statSync as statSync18,
26555
26708
  writeFileSync as writeFileSync10
26556
26709
  } from "node:fs";
26557
- import { dirname as dirname11, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
26710
+ import { dirname as dirname12, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
26558
26711
  function migrateConventionPolicies() {
26559
26712
  const from = legacy.customPoliciesDir();
26560
- if (!existsSync25(from))
26713
+ if (!existsSync26(from))
26561
26714
  return [];
26562
26715
  const moved = [];
26563
26716
  const mergeInto = (dir, dest, prefix) => {
@@ -26570,7 +26723,7 @@ function migrateConventionPolicies() {
26570
26723
  if (entries.length === 0)
26571
26724
  return;
26572
26725
  try {
26573
- mkdirSync12(dest, { recursive: true });
26726
+ mkdirSync13(dest, { recursive: true });
26574
26727
  } catch {
26575
26728
  return;
26576
26729
  }
@@ -26578,14 +26731,14 @@ function migrateConventionPolicies() {
26578
26731
  const source = resolve19(dir, entry.name);
26579
26732
  const target = resolve19(dest, entry.name);
26580
26733
  const name = `${prefix}${entry.name}`;
26581
- if (!existsSync25(target)) {
26734
+ if (!existsSync26(target)) {
26582
26735
  try {
26583
- renameSync7(source, target);
26736
+ renameSync8(source, target);
26584
26737
  moved.push(name);
26585
26738
  } catch {}
26586
26739
  continue;
26587
26740
  }
26588
- if (entry.isDirectory() && statSync17(target).isDirectory()) {
26741
+ if (entry.isDirectory() && statSync18(target).isDirectory()) {
26589
26742
  mergeInto(source, target, `${name}/`);
26590
26743
  try {
26591
26744
  rmdirSync(source);
@@ -26605,23 +26758,23 @@ function migrateLegacySpool() {
26605
26758
  [legacy.spoolDir(), spoolDir()],
26606
26759
  [legacy.failedDir(), failedDir()]
26607
26760
  ]) {
26608
- if (!existsSync25(from))
26761
+ if (!existsSync26(from))
26609
26762
  continue;
26610
26763
  try {
26611
- mkdirSync12(to, { recursive: true });
26764
+ mkdirSync13(to, { recursive: true });
26612
26765
  for (const entry of readdirSync15(from, { withFileTypes: true })) {
26613
26766
  if (!entry.isFile())
26614
26767
  continue;
26615
26768
  let name = entry.name;
26616
26769
  let n = 0;
26617
- while (existsSync25(resolve19(to, name)))
26770
+ while (existsSync26(resolve19(to, name)))
26618
26771
  name = `legacy-${n++}-${entry.name}`;
26619
26772
  try {
26620
- renameSync7(resolve19(from, entry.name), resolve19(to, name));
26773
+ renameSync8(resolve19(from, entry.name), resolve19(to, name));
26621
26774
  moved.push(name);
26622
26775
  } catch {
26623
26776
  try {
26624
- copyFileSync(resolve19(from, entry.name), resolve19(to, name));
26777
+ copyFileSync2(resolve19(from, entry.name), resolve19(to, name));
26625
26778
  moved.push(name);
26626
26779
  } catch {}
26627
26780
  }
@@ -26632,7 +26785,7 @@ function migrateLegacySpool() {
26632
26785
  }
26633
26786
  function migrateHookActivity() {
26634
26787
  const from = legacy.hookActivityDir();
26635
- if (!existsSync25(from))
26788
+ if (!existsSync26(from))
26636
26789
  return [];
26637
26790
  const moved = [];
26638
26791
  try {
@@ -26640,23 +26793,23 @@ function migrateHookActivity() {
26640
26793
  if (entries.length === 0)
26641
26794
  return [];
26642
26795
  const to = hookActivityDir();
26643
- mkdirSync12(to, { recursive: true });
26796
+ mkdirSync13(to, { recursive: true });
26644
26797
  const stamp = Date.now();
26645
26798
  let seq = 0;
26646
26799
  for (const entry of entries) {
26647
26800
  const source = resolve19(from, entry.name);
26648
26801
  let name = entry.name === "current.jsonl" ? `page-${stamp}-${seq++}.jsonl` : entry.name;
26649
26802
  let target = resolve19(to, name);
26650
- while (existsSync25(target)) {
26803
+ while (existsSync26(target)) {
26651
26804
  name = `page-${stamp}-${seq++}.jsonl`;
26652
26805
  target = resolve19(to, name);
26653
26806
  }
26654
26807
  try {
26655
- renameSync7(source, target);
26808
+ renameSync8(source, target);
26656
26809
  moved.push(name);
26657
26810
  } catch {
26658
26811
  try {
26659
- copyFileSync(source, target);
26812
+ copyFileSync2(source, target);
26660
26813
  moved.push(name);
26661
26814
  } catch {}
26662
26815
  }
@@ -26687,7 +26840,7 @@ function retirePolicyConfigKeys() {
26687
26840
  delete parsed[key];
26688
26841
  try {
26689
26842
  if (Object.keys(parsed).length === 0)
26690
- rmSync8(at, { force: true });
26843
+ rmSync9(at, { force: true });
26691
26844
  else
26692
26845
  writeFileSync10(at, JSON.stringify(parsed, null, 2) + `
26693
26846
  `, "utf8");
@@ -26698,7 +26851,7 @@ function retirePolicyConfigKeys() {
26698
26851
  }
26699
26852
  function readCarriedPolicyConfig() {
26700
26853
  const from = resolve19(legacy.localPoliciesDir(), "policies-config.json");
26701
- if (!existsSync25(from))
26854
+ if (!existsSync26(from))
26702
26855
  return null;
26703
26856
  let parsed;
26704
26857
  try {
@@ -26752,7 +26905,7 @@ function writeCarriedPolicyConfig(carried) {
26752
26905
  }
26753
26906
  } catch {}
26754
26907
  try {
26755
- mkdirSync12(dirname11(to), { recursive: true });
26908
+ mkdirSync13(dirname12(to), { recursive: true });
26756
26909
  writeFileSync10(to, JSON.stringify({ ...existing, ...carried }, null, 2) + `
26757
26910
  `, "utf8");
26758
26911
  } catch {
@@ -26762,7 +26915,7 @@ function writeCarriedPolicyConfig(carried) {
26762
26915
  }
26763
26916
  function readCarriedTelemetryOptOut() {
26764
26917
  const from = legacy.configToml();
26765
- if (!existsSync25(from))
26918
+ if (!existsSync26(from))
26766
26919
  return false;
26767
26920
  try {
26768
26921
  const text = readFileSync18(from, "utf8");
@@ -26817,7 +26970,7 @@ function parseLegacyToml(text) {
26817
26970
  }
26818
26971
  function readCarriedLegacyConfig() {
26819
26972
  const from = legacy.configToml();
26820
- if (!existsSync25(from))
26973
+ if (!existsSync26(from))
26821
26974
  return null;
26822
26975
  try {
26823
26976
  return projectConfig(parseLegacyToml(readFileSync18(from, "utf8")));
@@ -26827,7 +26980,7 @@ function readCarriedLegacyConfig() {
26827
26980
  }
26828
26981
  function readCarriedLegacyCredentials() {
26829
26982
  const toml = legacy.credentialsToml();
26830
- if (existsSync25(toml)) {
26983
+ if (existsSync26(toml)) {
26831
26984
  try {
26832
26985
  const creds = projectCredentials(parseLegacyToml(readFileSync18(toml, "utf8")));
26833
26986
  if (Object.keys(creds).length > 0)
@@ -26870,10 +27023,10 @@ function resetHome(from, to = LAYOUT_VERSION) {
26870
27023
  const spooled = migrateLegacySpool();
26871
27024
  const removed = [];
26872
27025
  for (const path of resettablePaths()) {
26873
- if (!existsSync25(path))
27026
+ if (!existsSync26(path))
26874
27027
  continue;
26875
27028
  try {
26876
- rmSync8(path, { recursive: true, force: true });
27029
+ rmSync9(path, { recursive: true, force: true });
26877
27030
  removed.push(path);
26878
27031
  } catch {}
26879
27032
  }
@@ -26895,7 +27048,7 @@ function layoutWarningForHook() {
26895
27048
  if (state.kind === "future") {
26896
27049
  return `[failproofai] this directory was written by a newer version (layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
26897
27050
  }
26898
- if (existsSync25(globalPolicyConfigFile()))
27051
+ if (existsSync26(globalPolicyConfigFile()))
26899
27052
  return null;
26900
27053
  return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
26901
27054
  }
@@ -26909,8 +27062,8 @@ var init_fp_reset = __esm(() => {
26909
27062
  });
26910
27063
 
26911
27064
  // src/hooks/semantic/jev-config.ts
26912
- import { closeSync as closeSync2, constants as fsConstants2, fstatSync as fstatSync2, openSync as openSync2, readSync as readSync2, statSync as statSync18 } from "node:fs";
26913
- import { dirname as dirname12 } from "node:path";
27065
+ import { closeSync as closeSync3, constants as fsConstants2, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, statSync as statSync19 } from "node:fs";
27066
+ import { dirname as dirname13 } from "node:path";
26914
27067
  function parseJevMode(raw) {
26915
27068
  return raw === "off" || raw === "observe" || raw === "enforce" ? raw : null;
26916
27069
  }
@@ -27178,7 +27331,7 @@ function looseConfigDirMode(path) {
27178
27331
  if (!modesAreMeaningful())
27179
27332
  return null;
27180
27333
  try {
27181
- const mode = statSync18(dirname12(path)).mode & 511;
27334
+ const mode = statSync19(dirname13(path)).mode & 511;
27182
27335
  return (mode & DIR_WRITABLE_BY_OTHERS2) !== 0 ? mode : null;
27183
27336
  } catch {
27184
27337
  return null;
@@ -27191,7 +27344,7 @@ function inspectJevConfig() {
27191
27344
  const path = jevConfigPath();
27192
27345
  let fd;
27193
27346
  try {
27194
- fd = openSync2(path, OPEN_FLAGS);
27347
+ fd = openSync3(path, OPEN_FLAGS);
27195
27348
  } catch (err) {
27196
27349
  const code = err.code;
27197
27350
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -27239,8 +27392,8 @@ function inspectJevConfig() {
27239
27392
  path,
27240
27393
  mode,
27241
27394
  reason: "too-open",
27242
- problem: `its directory ${dirname12(path)} is ${dirMode.toString(8).padStart(4, "0")} — other users can write there, ` + `so they can put their own config in its place; it must be owner-only (chmod 700 ${dirname12(path)})`,
27243
- fix: `chmod 700 ${dirname12(path)}`
27395
+ problem: `its directory ${dirname13(path)} is ${dirMode.toString(8).padStart(4, "0")} — other users can write there, ` + `so they can put their own config in its place; it must be owner-only (chmod 700 ${dirname13(path)})`,
27396
+ fix: `chmod 700 ${dirname13(path)}`
27244
27397
  };
27245
27398
  }
27246
27399
  if (st.size > MAX_CONFIG_BYTES)
@@ -27250,7 +27403,7 @@ function inspectJevConfig() {
27250
27403
  return { status: "refused", path, mode, reason: "unreadable", problem: `cannot read it (${err.code ?? "error"})` };
27251
27404
  } finally {
27252
27405
  try {
27253
- closeSync2(fd);
27406
+ closeSync3(fd);
27254
27407
  } catch {}
27255
27408
  }
27256
27409
  let parsed;
@@ -27346,7 +27499,7 @@ function readJevConfigFileForUpdate() {
27346
27499
  const path = jevConfigPath();
27347
27500
  let fd;
27348
27501
  try {
27349
- fd = openSync2(path, OPEN_FLAGS);
27502
+ fd = openSync3(path, OPEN_FLAGS);
27350
27503
  } catch {
27351
27504
  return null;
27352
27505
  }
@@ -27373,7 +27526,7 @@ function readJevConfigFileForUpdate() {
27373
27526
  return null;
27374
27527
  } finally {
27375
27528
  try {
27376
- closeSync2(fd);
27529
+ closeSync3(fd);
27377
27530
  } catch {}
27378
27531
  }
27379
27532
  }
@@ -27404,9 +27557,9 @@ var init_jev_config = __esm(() => {
27404
27557
  });
27405
27558
 
27406
27559
  // src/hooks/semantic/facts.ts
27407
- import { existsSync as existsSync26, readFileSync as readFileSync19, statSync as statSync19 } from "node:fs";
27560
+ import { existsSync as existsSync27, readFileSync as readFileSync19, statSync as statSync20 } from "node:fs";
27408
27561
  import { homedir as homedir23 } from "node:os";
27409
- import { dirname as dirname13, isAbsolute as isAbsolute4, resolve as resolve20 } from "node:path";
27562
+ import { dirname as dirname14, isAbsolute as isAbsolute4, resolve as resolve20 } from "node:path";
27410
27563
  function classifyTool(toolName) {
27411
27564
  if (SHELL_TOOLS.has(toolName))
27412
27565
  return { toolClass: "shell", toolIsKnown: true };
@@ -27631,9 +27784,9 @@ function findGitDir(start) {
27631
27784
  let dir = start;
27632
27785
  for (let i = 0;i < 40; i++) {
27633
27786
  const candidate = resolve20(dir, ".git");
27634
- if (existsSync26(candidate))
27787
+ if (existsSync27(candidate))
27635
27788
  return candidate;
27636
- const parent = dirname13(dir);
27789
+ const parent = dirname14(dir);
27637
27790
  if (parent === dir)
27638
27791
  return null;
27639
27792
  dir = parent;
@@ -27644,7 +27797,7 @@ function findProjectRoot(cwd) {
27644
27797
  if (!cwd)
27645
27798
  return null;
27646
27799
  const gitDir = findGitDir(cwd);
27647
- return gitDir ? dirname13(gitDir) : cwd;
27800
+ return gitDir ? dirname14(gitDir) : cwd;
27648
27801
  }
27649
27802
  function readCurrentBranch(cwd) {
27650
27803
  if (!cwd)
@@ -27654,12 +27807,12 @@ function readCurrentBranch(cwd) {
27654
27807
  if (!gitPath)
27655
27808
  return null;
27656
27809
  let headFile = resolve20(gitPath, "HEAD");
27657
- if (statSync19(gitPath).isFile()) {
27810
+ if (statSync20(gitPath).isFile()) {
27658
27811
  const pointer = readFileSync19(gitPath, "utf8").trim();
27659
27812
  const m = /^gitdir:\s*(.+)$/.exec(pointer);
27660
27813
  if (!m)
27661
27814
  return null;
27662
- headFile = resolve20(dirname13(gitPath), m[1], "HEAD");
27815
+ headFile = resolve20(dirname14(gitPath), m[1], "HEAD");
27663
27816
  }
27664
27817
  const head = readFileSync19(headFile, "utf8").trim();
27665
27818
  const ref = /^ref:\s*refs\/heads\/(.+)$/.exec(head);
@@ -28049,19 +28202,19 @@ __export(exports_intent, {
28049
28202
  readIntent: () => readIntent
28050
28203
  });
28051
28204
  import {
28052
- chmodSync as chmodSync4,
28053
- closeSync as closeSync3,
28054
- mkdirSync as mkdirSync13,
28055
- openSync as openSync3,
28205
+ chmodSync as chmodSync5,
28206
+ closeSync as closeSync4,
28207
+ mkdirSync as mkdirSync14,
28208
+ openSync as openSync4,
28056
28209
  readdirSync as readdirSync16,
28057
28210
  readFileSync as readFileSync20,
28058
28211
  readSync as readSync3,
28059
- renameSync as renameSync8,
28060
- statSync as statSync20,
28212
+ renameSync as renameSync9,
28213
+ statSync as statSync21,
28061
28214
  unlinkSync as unlinkSync4,
28062
28215
  writeFileSync as writeFileSync11
28063
28216
  } from "node:fs";
28064
- import { dirname as dirname14, resolve as resolve21 } from "node:path";
28217
+ import { dirname as dirname15, resolve as resolve21 } from "node:path";
28065
28218
  function modesAreMeaningful2() {
28066
28219
  return process.platform !== "win32";
28067
28220
  }
@@ -28073,7 +28226,7 @@ function storeDirChain() {
28073
28226
  chain.push(dir);
28074
28227
  if (dir === home)
28075
28228
  break;
28076
- const parent = dirname14(dir);
28229
+ const parent = dirname15(dir);
28077
28230
  if (parent === dir)
28078
28231
  break;
28079
28232
  dir = parent;
@@ -28086,15 +28239,15 @@ function looseIntentStoreDir() {
28086
28239
  for (const dir of storeDirChain()) {
28087
28240
  let mode;
28088
28241
  try {
28089
- mode = statSync20(dir).mode & 511;
28242
+ mode = statSync21(dir).mode & 511;
28090
28243
  } catch {
28091
28244
  continue;
28092
28245
  }
28093
28246
  if ((mode & DIR_WRITABLE_BY_OTHERS3) === 0)
28094
28247
  continue;
28095
28248
  try {
28096
- chmodSync4(dir, mode & ~DIR_WRITABLE_BY_OTHERS3);
28097
- if ((statSync20(dir).mode & DIR_WRITABLE_BY_OTHERS3) !== 0)
28249
+ chmodSync5(dir, mode & ~DIR_WRITABLE_BY_OTHERS3);
28250
+ if ((statSync21(dir).mode & DIR_WRITABLE_BY_OTHERS3) !== 0)
28098
28251
  return dir;
28099
28252
  } catch {
28100
28253
  return dir;
@@ -28117,12 +28270,12 @@ function appendPrompt(sessionId, entry) {
28117
28270
  const kept = last && last.text === entry.text ? file.prompts.slice(0, -1) : file.prompts;
28118
28271
  file.prompts = [...kept, entry].slice(-MAX_RECORDED_PROMPTS);
28119
28272
  const dir = sessionsDir();
28120
- mkdirSync13(dir, { recursive: true, mode: 448 });
28273
+ mkdirSync14(dir, { recursive: true, mode: 448 });
28121
28274
  const target = intentFile(sessionId);
28122
28275
  const isNew = !fileExists2(target);
28123
28276
  const tmp = `${target}.${process.pid}.tmp`;
28124
28277
  writeFileSync11(tmp, JSON.stringify(file), { mode: 384 });
28125
- renameSync8(tmp, target);
28278
+ renameSync9(tmp, target);
28126
28279
  if (isNew)
28127
28280
  pruneExpiredSessions(entry.at);
28128
28281
  return true;
@@ -28132,7 +28285,7 @@ function appendPrompt(sessionId, entry) {
28132
28285
  }
28133
28286
  function fileExists2(path) {
28134
28287
  try {
28135
- statSync20(path);
28288
+ statSync21(path);
28136
28289
  return true;
28137
28290
  } catch {
28138
28291
  return false;
@@ -28147,7 +28300,7 @@ function pruneExpiredSessions(now = Date.now()) {
28147
28300
  continue;
28148
28301
  const path = resolve21(dir, name);
28149
28302
  try {
28150
- const st = statSync20(path);
28303
+ const st = statSync21(path);
28151
28304
  if (st.isFile() && now - st.mtimeMs > INTENT_MAX_AGE_MS) {
28152
28305
  unlinkSync4(path);
28153
28306
  removed++;
@@ -28456,10 +28609,10 @@ function visitLinesBackwards(transcriptPath, maxBytes, visit) {
28456
28609
  return;
28457
28610
  let fd;
28458
28611
  try {
28459
- const st = statSync20(path);
28612
+ const st = statSync21(path);
28460
28613
  if (!st.isFile() || st.size === 0)
28461
28614
  return;
28462
- fd = openSync3(path, "r");
28615
+ fd = openSync4(path, "r");
28463
28616
  let end = st.size;
28464
28617
  let consumed = 0;
28465
28618
  let partial = Buffer.alloc(0);
@@ -28494,7 +28647,7 @@ function visitLinesBackwards(transcriptPath, maxBytes, visit) {
28494
28647
  } catch {} finally {
28495
28648
  if (fd !== undefined) {
28496
28649
  try {
28497
- closeSync3(fd);
28650
+ closeSync4(fd);
28498
28651
  } catch {}
28499
28652
  }
28500
28653
  }
@@ -29084,7 +29237,7 @@ var init_jev_client = __esm(() => {
29084
29237
 
29085
29238
  // src/hooks/semantic/evaluator.ts
29086
29239
  import { createHash as createHash8 } from "node:crypto";
29087
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync14, renameSync as renameSync9, statSync as statSync21 } from "node:fs";
29240
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15, renameSync as renameSync10, statSync as statSync22 } from "node:fs";
29088
29241
  import { resolve as resolve22 } from "node:path";
29089
29242
  function storeCut(message) {
29090
29243
  return typeof message === "string" && message.length >= MAX_USER_MESSAGE_CHARS - STORE_CUT_SLACK && OMISSION_MARK.test(message);
@@ -29256,10 +29409,10 @@ function verdictLogRow(input, outcome, meta) {
29256
29409
  function appendVerdictLog(row) {
29257
29410
  try {
29258
29411
  const file = verdictLogFile();
29259
- mkdirSync14(semanticDir(), { recursive: true, mode: 448 });
29412
+ mkdirSync15(semanticDir(), { recursive: true, mode: 448 });
29260
29413
  try {
29261
- if (statSync21(file).size > VERDICT_LOG_MAX_BYTES)
29262
- renameSync9(file, `${file}.1`);
29414
+ if (statSync22(file).size > VERDICT_LOG_MAX_BYTES)
29415
+ renameSync10(file, `${file}.1`);
29263
29416
  } catch {}
29264
29417
  appendFileSync3(file, JSON.stringify(row) + `
29265
29418
  `, { mode: 384 });
@@ -29489,7 +29642,7 @@ var init_jev_throttle = __esm(() => {
29489
29642
  });
29490
29643
 
29491
29644
  // src/hooks/semantic/session-root.ts
29492
- import { mkdirSync as mkdirSync15, readdirSync as readdirSync17, readFileSync as readFileSync21, statSync as statSync22, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
29645
+ import { mkdirSync as mkdirSync16, readdirSync as readdirSync17, readFileSync as readFileSync21, statSync as statSync23, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
29493
29646
  import { isAbsolute as isAbsolute5, resolve as resolve23 } from "node:path";
29494
29647
  function validRoot(v) {
29495
29648
  return typeof v === "string" && isAbsolute5(v) && resolve23(v) === v && v !== "/";
@@ -29500,7 +29653,7 @@ function storeIsOurs() {
29500
29653
  if (looseIntentStoreDir() !== null)
29501
29654
  return false;
29502
29655
  try {
29503
- const mode = statSync22(rootsDir()).mode & 511;
29656
+ const mode = statSync23(rootsDir()).mode & 511;
29504
29657
  return (mode & DIR_WRITABLE_BY_OTHERS4) === 0;
29505
29658
  } catch {
29506
29659
  return true;
@@ -29523,7 +29676,7 @@ function pruneSessionRoots(now = Date.now()) {
29523
29676
  continue;
29524
29677
  const path = resolve23(dir, name);
29525
29678
  try {
29526
- const st = statSync22(path);
29679
+ const st = statSync23(path);
29527
29680
  if (st.isFile() && now - st.mtimeMs > SESSION_ROOT_MAX_AGE_MS) {
29528
29681
  unlinkSync5(path);
29529
29682
  removed++;
@@ -29547,7 +29700,7 @@ function sessionProjectRoot(sessionId, cwd, now = Date.now()) {
29547
29700
  return pinned;
29548
29701
  if (!validRoot(live))
29549
29702
  return live;
29550
- mkdirSync15(rootsDir(), { recursive: true, mode: 448 });
29703
+ mkdirSync16(rootsDir(), { recursive: true, mode: 448 });
29551
29704
  writeFileSync12(rootFile(sessionId), JSON.stringify({ root: live, at: now }), { mode: 384, flag: "wx" });
29552
29705
  pruneSessionRoots(now);
29553
29706
  } catch {}
@@ -29873,7 +30026,7 @@ var init_enforcement_capability = __esm(() => {
29873
30026
  });
29874
30027
 
29875
30028
  // src/hooks/handler.ts
29876
- import { existsSync as existsSync27 } from "node:fs";
30029
+ import { existsSync as existsSync28 } from "node:fs";
29877
30030
  function canonicalizeEventType(raw, cli) {
29878
30031
  if (cli === "codex") {
29879
30032
  const mapped = CODEX_EVENT_MAP[raw];
@@ -29933,7 +30086,7 @@ function jevForcedOff(opts) {
29933
30086
  }
29934
30087
  async function readJevConfig() {
29935
30088
  try {
29936
- if (!existsSync27(jevConfigFile()))
30089
+ if (!existsSync28(jevConfigFile()))
29937
30090
  return null;
29938
30091
  await Promise.resolve().then(() => init_jev_config());
29939
30092
  const config = loadJevConfig();
@@ -31045,18 +31198,18 @@ var init_collector_config = __esm(() => {
31045
31198
  });
31046
31199
 
31047
31200
  // src/hooks/flush-cli.ts
31048
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, writeFileSync as writeFileSync13, readdirSync as readdirSync18 } from "node:fs";
31049
- import { dirname as dirname15, join as join31 } from "node:path";
31201
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, writeFileSync as writeFileSync13, readdirSync as readdirSync18 } from "node:fs";
31202
+ import { dirname as dirname16, join as join32 } from "node:path";
31050
31203
  function flushRequestPath(home) {
31051
- return join31(failproofaiHome(home), "state", "flush-request.json");
31204
+ return join32(failproofaiHome(home), "state", "flush-request.json");
31052
31205
  }
31053
31206
  function spoolDirs(home) {
31054
31207
  const root = spoolDir(home);
31055
31208
  const dirs = [root, customAgentsEventsDir(home)];
31056
- if (!existsSync28(root))
31209
+ if (!existsSync29(root))
31057
31210
  return dirs;
31058
31211
  try {
31059
- return dirs.concat(readdirSync18(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join31(root, e.name)));
31212
+ return dirs.concat(readdirSync18(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join32(root, e.name)));
31060
31213
  } catch {
31061
31214
  return dirs;
31062
31215
  }
@@ -31134,7 +31287,7 @@ async function runFlushCommand(opts = {}) {
31134
31287
  return { exitCode: 0, pending: 0, lines: nothing };
31135
31288
  }
31136
31289
  const path = flushRequestPath(home);
31137
- mkdirSync16(dirname15(path), { recursive: true });
31290
+ mkdirSync17(dirname16(path), { recursive: true });
31138
31291
  writeFileSync13(path, `${JSON.stringify({ requestedAtMs: Date.now() }, null, 2)}
31139
31292
  `, {
31140
31293
  mode: 384
@@ -31169,16 +31322,16 @@ var init_flush_cli = __esm(() => {
31169
31322
 
31170
31323
  // src/hooks/migrations.ts
31171
31324
  import {
31172
- chmodSync as chmodSync5,
31173
- copyFileSync as copyFileSync2,
31174
- existsSync as existsSync29,
31175
- mkdirSync as mkdirSync17,
31325
+ chmodSync as chmodSync6,
31326
+ copyFileSync as copyFileSync3,
31327
+ existsSync as existsSync30,
31328
+ mkdirSync as mkdirSync18,
31176
31329
  readFileSync as readFileSync22,
31177
- renameSync as renameSync10,
31178
- rmSync as rmSync9,
31330
+ renameSync as renameSync11,
31331
+ rmSync as rmSync10,
31179
31332
  writeFileSync as writeFileSync14
31180
31333
  } from "node:fs";
31181
- import { basename as basename6, dirname as dirname16, join as join32, resolve as resolve24 } from "node:path";
31334
+ import { basename as basename7, dirname as dirname17, join as join33, resolve as resolve24 } from "node:path";
31182
31335
  function migrateToLayout4() {
31183
31336
  const moves = [
31184
31337
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -31187,40 +31340,40 @@ function migrateToLayout4() {
31187
31340
  ];
31188
31341
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
31189
31342
  if (authDirOverride) {
31190
- moves.push({ from: join32(authDirOverride, "auth.json"), to: join32(authDirOverride, "session.json") }, {
31191
- from: join32(authDirOverride, "next-audit.json"),
31192
- to: join32(authDirOverride, "reminder.json")
31343
+ moves.push({ from: join33(authDirOverride, "auth.json"), to: join33(authDirOverride, "session.json") }, {
31344
+ from: join33(authDirOverride, "next-audit.json"),
31345
+ to: join33(authDirOverride, "reminder.json")
31193
31346
  });
31194
31347
  }
31195
31348
  const migrated = [];
31196
31349
  for (const { from, to } of moves) {
31197
- if (!existsSync29(from))
31350
+ if (!existsSync30(from))
31198
31351
  continue;
31199
- if (existsSync29(to)) {
31200
- rmSync9(from, { force: true });
31352
+ if (existsSync30(to)) {
31353
+ rmSync10(from, { force: true });
31201
31354
  continue;
31202
31355
  }
31203
- mkdirSync17(dirname16(to), { recursive: true });
31356
+ mkdirSync18(dirname17(to), { recursive: true });
31204
31357
  try {
31205
- renameSync10(from, to);
31358
+ renameSync11(from, to);
31206
31359
  } catch {
31207
31360
  try {
31208
- copyFileSync2(from, to);
31361
+ copyFileSync3(from, to);
31209
31362
  } catch (err) {
31210
31363
  try {
31211
- rmSync9(to, { force: true });
31364
+ rmSync10(to, { force: true });
31212
31365
  } catch {}
31213
31366
  throw err;
31214
31367
  }
31215
- rmSync9(from, { force: true });
31368
+ rmSync10(from, { force: true });
31216
31369
  }
31217
- migrated.push(`${basename6(from)} → audit/${basename6(to)}`);
31370
+ migrated.push(`${basename7(from)} → audit/${basename7(to)}`);
31218
31371
  }
31219
31372
  for (const secret of [auditSessionFile()]) {
31220
- if (!existsSync29(secret))
31373
+ if (!existsSync30(secret))
31221
31374
  continue;
31222
31375
  try {
31223
- chmodSync5(secret, 384);
31376
+ chmodSync6(secret, 384);
31224
31377
  } catch {}
31225
31378
  }
31226
31379
  writeVersionFile({ layout: 4 });
@@ -31251,26 +31404,26 @@ function readLedger() {
31251
31404
  }
31252
31405
  function appendLedger(entry) {
31253
31406
  try {
31254
- mkdirSync17(migrationsDir(), { recursive: true });
31407
+ mkdirSync18(migrationsDir(), { recursive: true });
31255
31408
  const all = [...readLedger(), entry];
31256
31409
  writeFileSync14(migrationLedgerFile(), `${JSON.stringify(all, null, 2)}
31257
31410
  `, "utf8");
31258
31411
  } catch {}
31259
31412
  }
31260
31413
  function backupNameOf(f) {
31261
- return f.as ?? basename6(f.at());
31414
+ return f.as ?? basename7(f.at());
31262
31415
  }
31263
31416
  function pruneMigratedCredentials(from) {
31264
31417
  const pruned = [];
31265
31418
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
31266
31419
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS) {
31267
31420
  try {
31268
- if (!existsSync29(landsAt()))
31421
+ if (!existsSync30(landsAt()))
31269
31422
  continue;
31270
31423
  const copy = resolve24(migrationBackupDir(layout), as);
31271
- if (!existsSync29(copy))
31424
+ if (!existsSync30(copy))
31272
31425
  continue;
31273
- rmSync9(copy, { force: true });
31426
+ rmSync10(copy, { force: true });
31274
31427
  pruned.push(as);
31275
31428
  } catch {}
31276
31429
  }
@@ -31281,7 +31434,7 @@ function filesToBackUp() {
31281
31434
  const seen = new Map;
31282
31435
  for (const f of [...BACKED_UP, ...BACKED_UP_LEGACY]) {
31283
31436
  const path = f.at();
31284
- if (existsSync29(path))
31437
+ if (existsSync30(path))
31285
31438
  seen.set(path, backupNameOf(f));
31286
31439
  }
31287
31440
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -31290,14 +31443,14 @@ function backupBeforeMigrating(from) {
31290
31443
  const dir = migrationBackupDir(from);
31291
31444
  const saved = [];
31292
31445
  try {
31293
- rmSync9(dir, { recursive: true, force: true });
31294
- mkdirSync17(dir, { recursive: true });
31446
+ rmSync10(dir, { recursive: true, force: true });
31447
+ mkdirSync18(dir, { recursive: true });
31295
31448
  } catch {
31296
31449
  return [];
31297
31450
  }
31298
31451
  for (const { path: source, as } of filesToBackUp()) {
31299
31452
  try {
31300
- copyFileSync2(source, resolve24(dir, as));
31453
+ copyFileSync3(source, resolve24(dir, as));
31301
31454
  saved.push(as);
31302
31455
  } catch {}
31303
31456
  }
@@ -31407,7 +31560,7 @@ var init_migrations = __esm(() => {
31407
31560
  { at: legacy.auditSchedule }
31408
31561
  ];
31409
31562
  PRUNED_AFTER_SUCCESS = [
31410
- { as: basename6(legacy.authJson()), landsAt: auditSessionFile }
31563
+ { as: basename7(legacy.authJson()), landsAt: auditSessionFile }
31411
31564
  ];
31412
31565
  });
31413
31566
 
@@ -31587,15 +31740,15 @@ var init_fp_reset2 = __esm(() => {
31587
31740
  // scripts/install-telemetry.mjs
31588
31741
  import { createHmac, randomUUID as randomUUID2 } from "node:crypto";
31589
31742
  import { execSync as execSync5 } from "node:child_process";
31590
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, mkdirSync as mkdirSync18 } from "node:fs";
31743
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, mkdirSync as mkdirSync19 } from "node:fs";
31591
31744
  import { homedir as homedir24, platform, arch, hostname, cpus } from "node:os";
31592
- import { join as join33 } from "node:path";
31745
+ import { join as join34 } from "node:path";
31593
31746
  function hashToId3(raw) {
31594
31747
  return createHmac("sha256", NAMESPACE3).update(raw).digest("hex");
31595
31748
  }
31596
31749
  function getInstanceId3() {
31597
- const idDir = join33(homedir24(), ".failproofai");
31598
- const idFile = join33(idDir, "instance-id");
31750
+ const idDir = join34(homedir24(), ".failproofai");
31751
+ const idFile = join34(idDir, "instance-id");
31599
31752
  try {
31600
31753
  const existing = readFileSync23(idFile, "utf-8").trim();
31601
31754
  if (existing)
@@ -31638,7 +31791,7 @@ function getInstanceId3() {
31638
31791
  } catch {}
31639
31792
  const id = randomUUID2();
31640
31793
  try {
31641
- mkdirSync18(idDir, { recursive: true });
31794
+ mkdirSync19(idDir, { recursive: true });
31642
31795
  writeFileSync15(idFile, id, "utf-8");
31643
31796
  } catch {}
31644
31797
  return id;
@@ -31671,8 +31824,8 @@ var NAMESPACE3 = "failproofai-telemetry-v1", API_KEY3 = "phc_Ac1Ww1GqKc0z1SyrRWb
31671
31824
  var init_install_telemetry = () => {};
31672
31825
 
31673
31826
  // lib/install-check.ts
31674
- import { existsSync as existsSync30, readFileSync as readFileSync24, writeFileSync as writeFileSync16, mkdirSync as mkdirSync19 } from "node:fs";
31675
- import { dirname as dirname17, resolve as resolve25 } from "node:path";
31827
+ import { existsSync as existsSync31, readFileSync as readFileSync24, writeFileSync as writeFileSync16, mkdirSync as mkdirSync20 } from "node:fs";
31828
+ import { dirname as dirname18, resolve as resolve25 } from "node:path";
31676
31829
  import { platform as platform2, arch as arch2, release, homedir as homedir25, hostname as hostname2 } from "node:os";
31677
31830
  import { createHmac as createHmac2 } from "node:crypto";
31678
31831
  function hashToId4(raw) {
@@ -31727,7 +31880,7 @@ function compareSemver2(a, b) {
31727
31880
  }
31728
31881
  function checkHooks() {
31729
31882
  const hooksConfigPath = globalPolicyConfigFile();
31730
- if (!existsSync30(hooksConfigPath)) {
31883
+ if (!existsSync31(hooksConfigPath)) {
31731
31884
  return { configured: false, registered: false, policyCount: 0 };
31732
31885
  }
31733
31886
  let config;
@@ -31741,7 +31894,7 @@ function checkHooks() {
31741
31894
  }
31742
31895
  const policyCount = config.enabledPolicies.length;
31743
31896
  const settingsPath = resolve25(homedir25(), ".claude", "settings.json");
31744
- if (!existsSync30(settingsPath))
31897
+ if (!existsSync31(settingsPath))
31745
31898
  return { configured: true, registered: false, policyCount };
31746
31899
  let settings;
31747
31900
  try {
@@ -31769,7 +31922,7 @@ async function maybeReportInstall(version) {
31769
31922
  const versionFile = lastVersionPath();
31770
31923
  let previousVersion = null;
31771
31924
  try {
31772
- if (existsSync30(versionFile)) {
31925
+ if (existsSync31(versionFile)) {
31773
31926
  previousVersion = readFileSync24(versionFile, "utf8").trim() || null;
31774
31927
  }
31775
31928
  } catch {}
@@ -31806,7 +31959,7 @@ async function maybeReportInstall(version) {
31806
31959
  enabled_policy_count: hooks.policyCount
31807
31960
  }, { version, timeoutMs: REPORT_TIMEOUT_MS, enabled: telemetryEnabled }));
31808
31961
  try {
31809
- mkdirSync19(dirname17(versionFile), { recursive: true });
31962
+ mkdirSync20(dirname18(versionFile), { recursive: true });
31810
31963
  writeFileSync16(versionFile, version, "utf8");
31811
31964
  } catch {}
31812
31965
  await Promise.all(events.map((p) => p.catch(() => {})));
@@ -31858,8 +32011,8 @@ var init_cli_error = __esm(() => {
31858
32011
 
31859
32012
  // src/hooks/manager.ts
31860
32013
  import { execSync as execSync6 } from "node:child_process";
31861
- import { existsSync as existsSync31 } from "node:fs";
31862
- import { resolve as resolve26, basename as basename7 } from "node:path";
32014
+ import { existsSync as existsSync32 } from "node:fs";
32015
+ import { resolve as resolve26, basename as basename8 } from "node:path";
31863
32016
  import { platform as platform3, arch as arch3, release as release2, hostname as hostname3 } from "node:os";
31864
32017
  function getSettingsPath(scope, cwd) {
31865
32018
  return claudeCode.getSettingsPath(scope, cwd);
@@ -32090,7 +32243,7 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
32090
32243
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
32091
32244
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve26(path));
32092
32245
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve26(path)).filter((path) => {
32093
- if (existsSync31(path))
32246
+ if (existsSync32(path))
32094
32247
  return true;
32095
32248
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
32096
32249
  return false;
@@ -32322,7 +32475,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
32322
32475
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
32323
32476
  for (const s of scopesToRemove) {
32324
32477
  const settingsPaths = settingsPathsFor(integration, s, cwd);
32325
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync31(p));
32478
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync32(p));
32326
32479
  if (existing.length === 0) {
32327
32480
  if (scope !== "all" && selectedClis.length === 1) {
32328
32481
  console.log("No settings file found. Nothing to remove.");
@@ -32427,7 +32580,7 @@ var DEFAULT_FETCH_TIMEOUT_MS = 15000;
32427
32580
 
32428
32581
  // src/hooks/cloud-enrollment.ts
32429
32582
  import { randomUUID as randomUUID3 } from "node:crypto";
32430
- import { existsSync as existsSync32, readFileSync as readFileSync25, rmSync as rmSync10 } from "node:fs";
32583
+ import { existsSync as existsSync33, readFileSync as readFileSync25, rmSync as rmSync11 } from "node:fs";
32431
32584
  import { hostname as hostname4 } from "node:os";
32432
32585
  function cloudCredentialPath() {
32433
32586
  return process.env.FAILPROOFAI_CLOUD_CREDENTIALS ?? credentialsFile();
@@ -32466,7 +32619,7 @@ function readCloudCredentials() {
32466
32619
  if (!usingJsonOverride())
32467
32620
  return readCredentials().cloud ?? null;
32468
32621
  const path = cloudCredentialPath();
32469
- if (!existsSync32(path))
32622
+ if (!existsSync33(path))
32470
32623
  return null;
32471
32624
  try {
32472
32625
  const raw = JSON.parse(readFileSync25(path, "utf8"));
@@ -32508,10 +32661,10 @@ function resolveMachineLabel(explicit) {
32508
32661
  function clearCloudCredentials() {
32509
32662
  if (usingJsonOverride()) {
32510
32663
  const path = cloudCredentialPath();
32511
- if (!existsSync32(path))
32664
+ if (!existsSync33(path))
32512
32665
  return false;
32513
32666
  try {
32514
- rmSync10(path);
32667
+ rmSync11(path);
32515
32668
  return true;
32516
32669
  } catch {
32517
32670
  return false;
@@ -32631,25 +32784,25 @@ var INTROSPECT_PATH = "/v1/auth/introspect", PERMISSION_EVENTS = "events:add", P
32631
32784
 
32632
32785
  // src/hooks/jev-cloud-connection.ts
32633
32786
  import {
32634
- chmodSync as chmodSync6,
32635
- closeSync as closeSync4,
32787
+ chmodSync as chmodSync7,
32788
+ closeSync as closeSync5,
32636
32789
  constants as fsConstants3,
32637
- existsSync as existsSync33,
32790
+ existsSync as existsSync34,
32638
32791
  fstatSync as fstatSync3,
32639
32792
  linkSync,
32640
- lstatSync as lstatSync2,
32641
- mkdirSync as mkdirSync20,
32642
- openSync as openSync4,
32793
+ lstatSync as lstatSync3,
32794
+ mkdirSync as mkdirSync21,
32795
+ openSync as openSync5,
32643
32796
  readFileSync as readFileSync26,
32644
32797
  readSync as readSync4,
32645
- renameSync as renameSync11,
32646
- rmSync as rmSync11,
32647
- statSync as statSync23,
32798
+ renameSync as renameSync12,
32799
+ rmSync as rmSync12,
32800
+ statSync as statSync24,
32648
32801
  unlinkSync as unlinkSync6,
32649
32802
  writeFileSync as writeFileSync17
32650
32803
  } from "node:fs";
32651
- import { dirname as dirname18 } from "node:path";
32652
- import { randomBytes as randomBytes2 } from "node:crypto";
32804
+ import { dirname as dirname19 } from "node:path";
32805
+ import { randomBytes as randomBytes3 } from "node:crypto";
32653
32806
  function writeCloudJevConfigIfAbsent(cloudBase) {
32654
32807
  const path = jevConfigPath();
32655
32808
  let baseUrl;
@@ -32658,17 +32811,17 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32658
32811
  } catch {
32659
32812
  return { status: "error", path, problem: "the FailproofAI Cloud URL is not a URL" };
32660
32813
  }
32661
- if (existsSync33(path))
32814
+ if (existsSync34(path))
32662
32815
  return kept(path, cloudBase);
32663
32816
  const body = `${JSON.stringify({ provider: JEV_CLOUD_PROVIDER, baseUrl, mode: CLOUD_JEV_INITIAL_MODE }, null, 2)}
32664
32817
  `;
32665
- const dir = dirname18(path);
32666
- const tmp = `${path}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
32818
+ const dir = dirname19(path);
32819
+ const tmp = `${path}.${process.pid}.${randomBytes3(6).toString("hex")}.tmp`;
32667
32820
  try {
32668
- if (!existsSync33(dir))
32669
- mkdirSync20(dir, { recursive: true, mode: 448 });
32821
+ if (!existsSync34(dir))
32822
+ mkdirSync21(dir, { recursive: true, mode: 448 });
32670
32823
  writeFileSync17(tmp, body, { mode: 384, flag: "wx" });
32671
- chmodSync6(tmp, 384);
32824
+ chmodSync7(tmp, 384);
32672
32825
  try {
32673
32826
  linkSync(tmp, path);
32674
32827
  } catch (err) {
@@ -32680,7 +32833,7 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32680
32833
  return { status: "error", path, problem: `could not write ${path} (${err.code ?? "error"})` };
32681
32834
  } finally {
32682
32835
  try {
32683
- rmSync11(tmp, { force: true });
32836
+ rmSync12(tmp, { force: true });
32684
32837
  } catch {}
32685
32838
  }
32686
32839
  tightenDir(dir);
@@ -32688,7 +32841,7 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32688
32841
  }
32689
32842
  function existingJevConfig(cloudBase) {
32690
32843
  const path = jevConfigPath();
32691
- return existsSync33(path) ? kept(path, cloudBase) : null;
32844
+ return existsSync34(path) ? kept(path, cloudBase) : null;
32692
32845
  }
32693
32846
  function cloudJevRunningMode() {
32694
32847
  try {
@@ -32727,16 +32880,16 @@ function tightenDir(dir) {
32727
32880
  if (process.platform === "win32")
32728
32881
  return;
32729
32882
  try {
32730
- const before = statSync23(dir).mode & 511;
32883
+ const before = statSync24(dir).mode & 511;
32731
32884
  if ((before & 18) !== 0)
32732
- chmodSync6(dir, before & ~18);
32885
+ chmodSync7(dir, before & ~18);
32733
32886
  } catch {}
32734
32887
  }
32735
32888
  function removeCloudJevConfig() {
32736
32889
  const path = jevConfigPath();
32737
32890
  let st;
32738
32891
  try {
32739
- st = lstatSync2(path);
32892
+ st = lstatSync3(path);
32740
32893
  } catch (err) {
32741
32894
  const code = err.code;
32742
32895
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -32745,9 +32898,9 @@ function removeCloudJevConfig() {
32745
32898
  }
32746
32899
  if (!st.isFile())
32747
32900
  return { status: "kept", path, provider: null };
32748
- const aside = `${path}.${process.pid}.${randomBytes2(6).toString("hex")}.disconnecting`;
32901
+ const aside = `${path}.${process.pid}.${randomBytes3(6).toString("hex")}.disconnecting`;
32749
32902
  try {
32750
- renameSync11(path, aside);
32903
+ renameSync12(path, aside);
32751
32904
  } catch (err) {
32752
32905
  const code = err.code;
32753
32906
  if (code === "ENOENT")
@@ -32788,12 +32941,12 @@ function putBack(aside, path, mode) {
32788
32941
  let created = false;
32789
32942
  try {
32790
32943
  const bytes = readFileSync26(aside);
32791
- const fd = openSync4(path, "wx", mode);
32944
+ const fd = openSync5(path, "wx", mode);
32792
32945
  created = true;
32793
32946
  try {
32794
32947
  writeFileSync17(fd, bytes);
32795
32948
  } finally {
32796
- closeSync4(fd);
32949
+ closeSync5(fd);
32797
32950
  }
32798
32951
  discard(aside);
32799
32952
  return "restored";
@@ -32804,14 +32957,14 @@ function putBack(aside, path, mode) {
32804
32957
  return { code: codeOf(err) };
32805
32958
  }
32806
32959
  try {
32807
- lstatSync2(path);
32960
+ lstatSync3(path);
32808
32961
  return "occupied";
32809
32962
  } catch (err) {
32810
32963
  if (codeOf(err) !== "ENOENT")
32811
32964
  return { code: codeOf(err) };
32812
32965
  }
32813
32966
  try {
32814
- renameSync11(aside, path);
32967
+ renameSync12(aside, path);
32815
32968
  return "restored";
32816
32969
  } catch (err) {
32817
32970
  return { code: codeOf(err) };
@@ -32826,7 +32979,7 @@ function fieldsOf(file) {
32826
32979
  const none = { provider: null, off: false };
32827
32980
  let fd;
32828
32981
  try {
32829
- fd = openSync4(file, fsConstants3.O_RDONLY | (fsConstants3.O_NONBLOCK ?? 0) | (fsConstants3.O_NOFOLLOW ?? 0));
32982
+ fd = openSync5(file, fsConstants3.O_RDONLY | (fsConstants3.O_NONBLOCK ?? 0) | (fsConstants3.O_NOFOLLOW ?? 0));
32830
32983
  } catch {
32831
32984
  return none;
32832
32985
  }
@@ -32849,7 +33002,7 @@ function fieldsOf(file) {
32849
33002
  return none;
32850
33003
  } finally {
32851
33004
  try {
32852
- closeSync4(fd);
33005
+ closeSync5(fd);
32853
33006
  } catch {}
32854
33007
  }
32855
33008
  }
@@ -33067,8 +33220,8 @@ var init_cloud_connection = __esm(() => {
33067
33220
  });
33068
33221
 
33069
33222
  // src/hooks/setup-state.ts
33070
- import { existsSync as existsSync34, realpathSync as realpathSync3, statSync as statSync24 } from "node:fs";
33071
- import { dirname as dirname19, resolve as resolve27 } from "node:path";
33223
+ import { existsSync as existsSync35, realpathSync as realpathSync4, statSync as statSync25 } from "node:fs";
33224
+ import { dirname as dirname20, resolve as resolve27 } from "node:path";
33072
33225
  import { homedir as homedir26 } from "node:os";
33073
33226
  function globalConfigPath(home = homedir26()) {
33074
33227
  return globalPolicyConfigFile(home);
@@ -33081,7 +33234,7 @@ function legacyMarkerPath(home) {
33081
33234
  }
33082
33235
  function isDir(path) {
33083
33236
  try {
33084
- return statSync24(path).isDirectory();
33237
+ return statSync25(path).isDirectory();
33085
33238
  } catch {
33086
33239
  return false;
33087
33240
  }
@@ -33092,7 +33245,7 @@ function findProjectRoot2(start, home = homedir26()) {
33092
33245
  while (dir !== resolvedHome) {
33093
33246
  if (isDir(resolve27(dir, ".failproofai")))
33094
33247
  return dir;
33095
- const parent = dirname19(dir);
33248
+ const parent = dirname20(dir);
33096
33249
  if (parent === dir)
33097
33250
  break;
33098
33251
  dir = parent;
@@ -33111,7 +33264,7 @@ function hasGlobalHooksInstalled() {
33111
33264
  function realResolve(path) {
33112
33265
  const lexical = resolve27(path);
33113
33266
  try {
33114
- return realpathSync3(lexical);
33267
+ return realpathSync4(lexical);
33115
33268
  } catch {
33116
33269
  return lexical;
33117
33270
  }
@@ -33124,10 +33277,10 @@ function detectSetupState(cwd = process.cwd(), home = homedir26()) {
33124
33277
  cwd: resolvedCwd,
33125
33278
  home: resolvedHome,
33126
33279
  projectRoot,
33127
- hasGlobalConfig: existsSync34(globalConfigPath(resolvedHome)),
33128
- hasProjectConfig: projectRoot !== resolvedHome && existsSync34(projectConfigPath(projectRoot)),
33280
+ hasGlobalConfig: existsSync35(globalConfigPath(resolvedHome)),
33281
+ hasProjectConfig: projectRoot !== resolvedHome && existsSync35(projectConfigPath(projectRoot)),
33129
33282
  hasGlobalHooks: hasGlobalHooksInstalled(),
33130
- hasLegacyMarker: existsSync34(legacyMarkerPath(resolvedHome)),
33283
+ hasLegacyMarker: existsSync35(legacyMarkerPath(resolvedHome)),
33131
33284
  inHomeDir: resolvedCwd === resolvedHome
33132
33285
  };
33133
33286
  }
@@ -33144,11 +33297,11 @@ var init_setup_state = __esm(() => {
33144
33297
  });
33145
33298
 
33146
33299
  // src/hooks/onboarding-attempt.ts
33147
- import { existsSync as existsSync35, mkdirSync as mkdirSync21, readFileSync as readFileSync27, rmSync as rmSync12, writeFileSync as writeFileSync18 } from "node:fs";
33148
- import { dirname as dirname20 } from "node:path";
33300
+ import { existsSync as existsSync36, mkdirSync as mkdirSync22, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync18 } from "node:fs";
33301
+ import { dirname as dirname21 } from "node:path";
33149
33302
  function readOnboardingAttempt() {
33150
33303
  const path = onboardingAttemptFile();
33151
- if (!existsSync35(path))
33304
+ if (!existsSync36(path))
33152
33305
  return null;
33153
33306
  try {
33154
33307
  const raw = JSON.parse(readFileSync27(path, "utf8"));
@@ -33170,7 +33323,7 @@ function readOnboardingAttempt() {
33170
33323
  function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.now()) {
33171
33324
  try {
33172
33325
  const path = onboardingAttemptFile();
33173
- mkdirSync21(dirname20(path), { recursive: true });
33326
+ mkdirSync22(dirname21(path), { recursive: true });
33174
33327
  const record = {
33175
33328
  schemaVersion: SCHEMA_VERSION3,
33176
33329
  reason,
@@ -33183,7 +33336,7 @@ function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.no
33183
33336
  }
33184
33337
  function clearOnboardingAttempt() {
33185
33338
  try {
33186
- rmSync12(onboardingAttemptFile(), { force: true });
33339
+ rmSync13(onboardingAttemptFile(), { force: true });
33187
33340
  } catch {}
33188
33341
  }
33189
33342
  function blockerCleared(attempt, probe) {
@@ -33225,7 +33378,7 @@ var init_onboarding_attempt = __esm(() => {
33225
33378
  });
33226
33379
 
33227
33380
  // src/hooks/onboarding-lock.ts
33228
- import { mkdirSync as mkdirSync22, readFileSync as readFileSync28, rmSync as rmSync13, writeFileSync as writeFileSync19 } from "node:fs";
33381
+ import { mkdirSync as mkdirSync23, readFileSync as readFileSync28, rmSync as rmSync14, writeFileSync as writeFileSync19 } from "node:fs";
33229
33382
  import { homedir as homedir27 } from "node:os";
33230
33383
  function onboardingLockPath(home = homedir27()) {
33231
33384
  return onboardingLockFile(home);
@@ -33256,7 +33409,7 @@ function acquireOnboardingLock(home = homedir27()) {
33256
33409
  const held = readLock(path);
33257
33410
  if (held && held.pid !== process.pid && processAlive(held.pid))
33258
33411
  return null;
33259
- mkdirSync22(stateDir(home), { recursive: true });
33412
+ mkdirSync23(stateDir(home), { recursive: true });
33260
33413
  const body = { pid: process.pid, startedAt: Date.now() };
33261
33414
  writeFileSync19(path, JSON.stringify(body), "utf8");
33262
33415
  let released = false;
@@ -33268,7 +33421,7 @@ function acquireOnboardingLock(home = homedir27()) {
33268
33421
  try {
33269
33422
  const current = readLock(path);
33270
33423
  if (!current || current.pid === process.pid)
33271
- rmSync13(path, { force: true });
33424
+ rmSync14(path, { force: true });
33272
33425
  } catch {}
33273
33426
  }
33274
33427
  };
@@ -33281,8 +33434,8 @@ var init_onboarding_lock = __esm(() => {
33281
33434
  });
33282
33435
 
33283
33436
  // lib/claude-sessions.ts
33284
- import { readdirSync as readdirSync19, statSync as statSync25, existsSync as existsSync36 } from "node:fs";
33285
- import { join as join34, basename as basename8 } from "node:path";
33437
+ import { readdirSync as readdirSync19, statSync as statSync26, existsSync as existsSync37 } from "node:fs";
33438
+ import { join as join35, basename as basename9 } from "node:path";
33286
33439
  function getClaudeProjectsRoot() {
33287
33440
  return getClaudeProjectsPath();
33288
33441
  }
@@ -33297,7 +33450,7 @@ function listClaudeProjects() {
33297
33450
  return entries.filter((e) => e.isDirectory()).map((e) => ({
33298
33451
  name: e.name,
33299
33452
  cwd: decodeFolderName(e.name),
33300
- path: join34(root, e.name)
33453
+ path: join35(root, e.name)
33301
33454
  }));
33302
33455
  }
33303
33456
  function listClaudeTranscripts(project) {
@@ -33313,9 +33466,9 @@ function listClaudeTranscripts(project) {
33313
33466
  const sessionId = entry.name.slice(0, -".jsonl".length);
33314
33467
  if (!UUID_RE2.test(sessionId))
33315
33468
  continue;
33316
- const transcriptPath = join34(project.path, entry.name);
33469
+ const transcriptPath = join35(project.path, entry.name);
33317
33470
  try {
33318
- const s = statSync25(transcriptPath);
33471
+ const s = statSync26(transcriptPath);
33319
33472
  out.push({
33320
33473
  projectName: project.name,
33321
33474
  cwd: project.cwd,
@@ -33327,8 +33480,8 @@ function listClaudeTranscripts(project) {
33327
33480
  });
33328
33481
  } catch {}
33329
33482
  } else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
33330
- const subDir = join34(project.path, entry.name, "subagents");
33331
- if (!existsSync36(subDir))
33483
+ const subDir = join35(project.path, entry.name, "subagents");
33484
+ if (!existsSync37(subDir))
33332
33485
  continue;
33333
33486
  let subEntries;
33334
33487
  try {
@@ -33340,9 +33493,9 @@ function listClaudeTranscripts(project) {
33340
33493
  if (!sub.isFile() || !sub.name.endsWith(".jsonl"))
33341
33494
  continue;
33342
33495
  const agentId = sub.name.slice(0, -".jsonl".length);
33343
- const transcriptPath = join34(subDir, sub.name);
33496
+ const transcriptPath = join35(subDir, sub.name);
33344
33497
  try {
33345
- const s = statSync25(transcriptPath);
33498
+ const s = statSync26(transcriptPath);
33346
33499
  out.push({
33347
33500
  projectName: project.name,
33348
33501
  cwd: project.cwd,
@@ -33558,7 +33711,7 @@ var init_claude = __esm(() => {
33558
33711
  });
33559
33712
 
33560
33713
  // src/audit/cli-adapters/codex.ts
33561
- import { statSync as statSync26 } from "node:fs";
33714
+ import { statSync as statSync27 } from "node:fs";
33562
33715
  async function listCodexTranscriptMetadata(opts = {}) {
33563
33716
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33564
33717
  const sinceMs = opts.sinceMs ?? 0;
@@ -33575,7 +33728,7 @@ async function listCodexTranscriptMetadata(opts = {}) {
33575
33728
  continue;
33576
33729
  let sizeBytes = 0;
33577
33730
  try {
33578
- sizeBytes = statSync26(s.path).size;
33731
+ sizeBytes = statSync27(s.path).size;
33579
33732
  } catch {}
33580
33733
  if (!s.sessionId)
33581
33734
  continue;
@@ -33609,7 +33762,7 @@ var init_codex = __esm(() => {
33609
33762
  });
33610
33763
 
33611
33764
  // src/audit/cli-adapters/copilot.ts
33612
- import { statSync as statSync27 } from "node:fs";
33765
+ import { statSync as statSync28 } from "node:fs";
33613
33766
  async function listCopilotTranscriptMetadata(opts = {}) {
33614
33767
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33615
33768
  const sinceMs = opts.sinceMs ?? 0;
@@ -33626,7 +33779,7 @@ async function listCopilotTranscriptMetadata(opts = {}) {
33626
33779
  continue;
33627
33780
  let sizeBytes = 0;
33628
33781
  try {
33629
- sizeBytes = statSync27(s.path).size;
33782
+ sizeBytes = statSync28(s.path).size;
33630
33783
  } catch {}
33631
33784
  if (!s.sessionId)
33632
33785
  continue;
@@ -33660,7 +33813,7 @@ var init_copilot = __esm(() => {
33660
33813
  });
33661
33814
 
33662
33815
  // src/audit/cli-adapters/cursor.ts
33663
- import { statSync as statSync28 } from "node:fs";
33816
+ import { statSync as statSync29 } from "node:fs";
33664
33817
  async function listCursorTranscriptMetadata(opts = {}) {
33665
33818
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33666
33819
  const sinceMs = opts.sinceMs ?? 0;
@@ -33677,7 +33830,7 @@ async function listCursorTranscriptMetadata(opts = {}) {
33677
33830
  continue;
33678
33831
  let sizeBytes = 0;
33679
33832
  try {
33680
- sizeBytes = statSync28(s.path).size;
33833
+ sizeBytes = statSync29(s.path).size;
33681
33834
  } catch {}
33682
33835
  if (!s.sessionId)
33683
33836
  continue;
@@ -33918,7 +34071,7 @@ var init_opencode = __esm(() => {
33918
34071
  });
33919
34072
 
33920
34073
  // src/audit/cli-adapters/pi.ts
33921
- import { statSync as statSync29 } from "node:fs";
34074
+ import { statSync as statSync30 } from "node:fs";
33922
34075
  async function listPiTranscriptMetadata(opts = {}) {
33923
34076
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33924
34077
  const sinceMs = opts.sinceMs ?? 0;
@@ -33935,7 +34088,7 @@ async function listPiTranscriptMetadata(opts = {}) {
33935
34088
  continue;
33936
34089
  let sizeBytes = 0;
33937
34090
  try {
33938
- sizeBytes = statSync29(s.path).size;
34091
+ sizeBytes = statSync30(s.path).size;
33939
34092
  } catch {}
33940
34093
  if (!s.sessionId)
33941
34094
  continue;
@@ -34671,8 +34824,8 @@ var init_features = __esm(() => {
34671
34824
 
34672
34825
  // src/audit/cache.ts
34673
34826
  import { createHash as createHash10 } from "node:crypto";
34674
- import { existsSync as existsSync37, mkdirSync as mkdirSync23, readFileSync as readFileSync29, writeFileSync as writeFileSync20, chmodSync as chmodSync7, openSync as openSync5, readSync as readSync5, closeSync as closeSync5 } from "node:fs";
34675
- import { join as join35 } from "node:path";
34827
+ import { existsSync as existsSync38, mkdirSync as mkdirSync24, readFileSync as readFileSync29, writeFileSync as writeFileSync20, chmodSync as chmodSync8, openSync as openSync6, readSync as readSync5, closeSync as closeSync6 } from "node:fs";
34828
+ import { join as join36 } from "node:path";
34676
34829
  function getEngineVersion() {
34677
34830
  if (cachedEngineVersion)
34678
34831
  return cachedEngineVersion;
@@ -34692,7 +34845,7 @@ function getDetectorVersion() {
34692
34845
  function getCachePathFor(transcriptPath) {
34693
34846
  const root = auditCacheDir();
34694
34847
  const key = createHash10("sha1").update(transcriptPath).digest("hex");
34695
- return join35(root, `${key}.json`);
34848
+ return join36(root, `${key}.json`);
34696
34849
  }
34697
34850
  function encodeDetectorState(state) {
34698
34851
  return JSON.stringify(state, (_k, v) => v instanceof Map ? { __map: [...v.entries()] } : v);
@@ -34711,7 +34864,7 @@ function anchorHashFor(transcriptPath, upTo) {
34711
34864
  return null;
34712
34865
  let fd = null;
34713
34866
  try {
34714
- fd = openSync5(transcriptPath, "r");
34867
+ fd = openSync6(transcriptPath, "r");
34715
34868
  const head = Buffer.alloc(Math.min(ANCHOR_WINDOW, upTo));
34716
34869
  readSync5(fd, head, 0, head.length, 0);
34717
34870
  const tailLen = Math.min(ANCHOR_WINDOW, upTo);
@@ -34723,7 +34876,7 @@ function anchorHashFor(transcriptPath, upTo) {
34723
34876
  } finally {
34724
34877
  if (fd !== null) {
34725
34878
  try {
34726
- closeSync5(fd);
34879
+ closeSync6(fd);
34727
34880
  } catch {}
34728
34881
  }
34729
34882
  }
@@ -34732,7 +34885,7 @@ function readCachedTranscript(transcriptPath, mtimeMs, sizeBytes) {
34732
34885
  if (sizeBytes === 0)
34733
34886
  return null;
34734
34887
  const cachePath = getCachePathFor(transcriptPath);
34735
- if (!existsSync37(cachePath))
34888
+ if (!existsSync38(cachePath))
34736
34889
  return null;
34737
34890
  try {
34738
34891
  const raw = readFileSync29(cachePath, "utf-8");
@@ -34774,7 +34927,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result,
34774
34927
  return;
34775
34928
  const cachePath = getCachePathFor(transcriptPath);
34776
34929
  try {
34777
- mkdirSync23(auditCacheDir(), { recursive: true });
34930
+ mkdirSync24(auditCacheDir(), { recursive: true });
34778
34931
  const entry = {
34779
34932
  schemaVersion: CACHE_SCHEMA_VERSION,
34780
34933
  cachedAt: Date.now(),
@@ -34794,7 +34947,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result,
34794
34947
  }
34795
34948
  writeFileSync20(cachePath, JSON.stringify(entry), { encoding: "utf-8", mode: 384 });
34796
34949
  try {
34797
- chmodSync7(cachePath, 384);
34950
+ chmodSync8(cachePath, 384);
34798
34951
  } catch {}
34799
34952
  } catch {}
34800
34953
  }
@@ -35229,14 +35382,14 @@ var init_audit = __esm(() => {
35229
35382
 
35230
35383
  // src/audit/audit-lock.ts
35231
35384
  import {
35232
- closeSync as closeSync6,
35385
+ closeSync as closeSync7,
35233
35386
  linkSync as linkSync2,
35234
- mkdirSync as mkdirSync24,
35235
- openSync as openSync6,
35387
+ mkdirSync as mkdirSync25,
35388
+ openSync as openSync7,
35236
35389
  readFileSync as readFileSync30,
35237
35390
  unlinkSync as unlinkSync7,
35238
35391
  writeFileSync as writeFileSync21,
35239
- writeSync
35392
+ writeSync as writeSync2
35240
35393
  } from "node:fs";
35241
35394
  function acquireAuditLock(source, now = Date.now()) {
35242
35395
  const path = auditLockFile();
@@ -35330,22 +35483,22 @@ function writeLockExclusive(path, info) {
35330
35483
  function createThenWrite(path, body) {
35331
35484
  let fd;
35332
35485
  try {
35333
- fd = openSync6(path, "wx", 384);
35334
- writeSync(fd, body);
35486
+ fd = openSync7(path, "wx", 384);
35487
+ writeSync2(fd, body);
35335
35488
  return true;
35336
35489
  } catch {
35337
35490
  return false;
35338
35491
  } finally {
35339
35492
  if (fd !== undefined) {
35340
35493
  try {
35341
- closeSync6(fd);
35494
+ closeSync7(fd);
35342
35495
  } catch {}
35343
35496
  }
35344
35497
  }
35345
35498
  }
35346
35499
  function ensureRunDir() {
35347
- mkdirSync24(failproofaiHome(), { recursive: true });
35348
- mkdirSync24(runDir(), { recursive: true, mode: 448 });
35500
+ mkdirSync25(failproofaiHome(), { recursive: true });
35501
+ mkdirSync25(runDir(), { recursive: true, mode: 448 });
35349
35502
  }
35350
35503
  var AUDIT_LOCK_MAX_AGE_MS;
35351
35504
  var init_audit_lock = __esm(() => {
@@ -35354,7 +35507,7 @@ var init_audit_lock = __esm(() => {
35354
35507
  });
35355
35508
 
35356
35509
  // src/audit/dashboard-cache.ts
35357
- import { existsSync as existsSync38, readFileSync as readFileSync31 } from "node:fs";
35510
+ import { existsSync as existsSync39, readFileSync as readFileSync31 } from "node:fs";
35358
35511
  function getCachePath() {
35359
35512
  return auditDashboardFile();
35360
35513
  }
@@ -35374,7 +35527,7 @@ function writeDashboardCache(params, result) {
35374
35527
  }
35375
35528
  function readDashboardCacheMeta() {
35376
35529
  const cachePath = getCachePath();
35377
- if (!existsSync38(cachePath))
35530
+ if (!existsSync39(cachePath))
35378
35531
  return null;
35379
35532
  try {
35380
35533
  const raw = readFileSync31(cachePath, "utf-8");
@@ -35601,15 +35754,15 @@ var init_api_server_client = __esm(() => {
35601
35754
  });
35602
35755
 
35603
35756
  // lib/auth/auth-store.ts
35604
- import { existsSync as existsSync39, readFileSync as readFileSync32, readdirSync as readdirSync20, rmSync as rmSync14 } from "node:fs";
35605
- import { join as join36, resolve as resolve28 } from "node:path";
35757
+ import { existsSync as existsSync40, readFileSync as readFileSync32, readdirSync as readdirSync20, rmSync as rmSync15 } from "node:fs";
35758
+ import { join as join37, resolve as resolve28 } from "node:path";
35606
35759
  function getAuthFilePath() {
35607
35760
  const override = process.env.FAILPROOFAI_AUTH_DIR;
35608
- return override ? join36(override, "session.json") : auditSessionFile();
35761
+ return override ? join37(override, "session.json") : auditSessionFile();
35609
35762
  }
35610
35763
  function readAuth() {
35611
35764
  const p = getAuthFilePath();
35612
- if (!existsSync39(p))
35765
+ if (!existsSync40(p))
35613
35766
  return null;
35614
35767
  try {
35615
35768
  const raw = readFileSync32(p, "utf-8");
@@ -35636,18 +35789,18 @@ function writeAuth(auth) {
35636
35789
  }
35637
35790
  function deleteAuth() {
35638
35791
  const p = getAuthFilePath();
35639
- if (existsSync39(p))
35640
- rmSync14(p, { force: true });
35792
+ if (existsSync40(p))
35793
+ rmSync15(p, { force: true });
35641
35794
  try {
35642
35795
  const root = migrationsDir();
35643
- if (!existsSync39(root))
35796
+ if (!existsSync40(root))
35644
35797
  return;
35645
35798
  for (const entry of readdirSync20(root)) {
35646
35799
  if (!entry.startsWith("backup-layout"))
35647
35800
  continue;
35648
35801
  const copy = resolve28(root, entry, "auth.json");
35649
- if (existsSync39(copy))
35650
- rmSync14(copy, { force: true });
35802
+ if (existsSync40(copy))
35803
+ rmSync15(copy, { force: true });
35651
35804
  }
35652
35805
  } catch {}
35653
35806
  }
@@ -35897,12 +36050,12 @@ var init_harm_report = __esm(() => {
35897
36050
  });
35898
36051
 
35899
36052
  // src/audit/machine-store.ts
35900
- import { existsSync as existsSync40, readFileSync as readFileSync33, rmSync as rmSync15 } from "node:fs";
36053
+ import { existsSync as existsSync41, readFileSync as readFileSync33, rmSync as rmSync16 } from "node:fs";
35901
36054
  import { hostname as hostname5 } from "node:os";
35902
36055
  import { randomUUID as randomUUID4 } from "node:crypto";
35903
36056
  function readMachineIdentity(home) {
35904
36057
  const path = auditMachineFile(home);
35905
- if (!existsSync40(path))
36058
+ if (!existsSync41(path))
35906
36059
  return null;
35907
36060
  try {
35908
36061
  const parsed = JSON.parse(readFileSync33(path, "utf8"));
@@ -36227,9 +36380,9 @@ var init_cli = __esm(() => {
36227
36380
  });
36228
36381
 
36229
36382
  // src/hooks/configure-wizard.ts
36230
- import { existsSync as existsSync41, mkdirSync as mkdirSync25, writeFileSync as writeFileSync22, readFileSync as readFileSync34 } from "node:fs";
36383
+ import { existsSync as existsSync42, mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, readFileSync as readFileSync34 } from "node:fs";
36231
36384
  import { homedir as homedir29 } from "node:os";
36232
- import { dirname as dirname21, resolve as resolve29, sep as sep5 } from "node:path";
36385
+ import { dirname as dirname22, resolve as resolve29, sep as sep5 } from "node:path";
36233
36386
  async function emit(event, props) {
36234
36387
  try {
36235
36388
  await trackHookEvent2(getInstanceId2(), event, props);
@@ -36252,7 +36405,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
36252
36405
  const path = getConfigPathForScope(scope, cwd);
36253
36406
  let config = {};
36254
36407
  try {
36255
- if (existsSync41(path))
36408
+ if (existsSync42(path))
36256
36409
  config = JSON.parse(readFileSync34(path, "utf8"));
36257
36410
  } catch {
36258
36411
  return;
@@ -36397,7 +36550,7 @@ function firstRunMarkerPath() {
36397
36550
  }
36398
36551
  function markLauncherSeen() {
36399
36552
  try {
36400
- mkdirSync25(dirname21(firstRunMarkerPath()), { recursive: true });
36553
+ mkdirSync26(dirname22(firstRunMarkerPath()), { recursive: true });
36401
36554
  writeFileSync22(firstRunMarkerPath(), "1", "utf8");
36402
36555
  } catch {}
36403
36556
  }
@@ -36896,18 +37049,18 @@ var init_configure_wizard = __esm(() => {
36896
37049
  });
36897
37050
 
36898
37051
  // src/hooks/flush-cli.ts
36899
- import { existsSync as existsSync42, mkdirSync as mkdirSync26, writeFileSync as writeFileSync23, readdirSync as readdirSync21 } from "node:fs";
36900
- import { dirname as dirname22, join as join37 } from "node:path";
37052
+ import { existsSync as existsSync43, mkdirSync as mkdirSync27, writeFileSync as writeFileSync23, readdirSync as readdirSync21 } from "node:fs";
37053
+ import { dirname as dirname23, join as join38 } from "node:path";
36901
37054
  function flushRequestPath2(home) {
36902
- return join37(failproofaiHome(home), "state", "flush-request.json");
37055
+ return join38(failproofaiHome(home), "state", "flush-request.json");
36903
37056
  }
36904
37057
  function spoolDirs2(home) {
36905
37058
  const root = spoolDir(home);
36906
37059
  const dirs = [root, customAgentsEventsDir(home)];
36907
- if (!existsSync42(root))
37060
+ if (!existsSync43(root))
36908
37061
  return dirs;
36909
37062
  try {
36910
- return dirs.concat(readdirSync21(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join37(root, e.name)));
37063
+ return dirs.concat(readdirSync21(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join38(root, e.name)));
36911
37064
  } catch {
36912
37065
  return dirs;
36913
37066
  }
@@ -36985,7 +37138,7 @@ async function runFlushCommand2(opts = {}) {
36985
37138
  return { exitCode: 0, pending: 0, lines: nothing };
36986
37139
  }
36987
37140
  const path = flushRequestPath2(home);
36988
- mkdirSync26(dirname22(path), { recursive: true });
37141
+ mkdirSync27(dirname23(path), { recursive: true });
36989
37142
  writeFileSync23(path, `${JSON.stringify({ requestedAtMs: Date.now() }, null, 2)}
36990
37143
  `, {
36991
37144
  mode: 384
@@ -37019,16 +37172,16 @@ var init_flush_cli2 = __esm(() => {
37019
37172
  });
37020
37173
 
37021
37174
  // src/hooks/backfill-cli.ts
37022
- import { existsSync as existsSync43, mkdirSync as mkdirSync27, writeFileSync as writeFileSync24, readdirSync as readdirSync22, statSync as statSync30 } from "node:fs";
37023
- import { dirname as dirname23, join as join38 } from "node:path";
37175
+ import { existsSync as existsSync44, mkdirSync as mkdirSync28, writeFileSync as writeFileSync24, readdirSync as readdirSync22, statSync as statSync31 } from "node:fs";
37176
+ import { dirname as dirname24, join as join39 } from "node:path";
37024
37177
  function backfillRequestPath(home) {
37025
- return join38(failproofaiHome(home), "state", "backfill-request.json");
37178
+ return join39(failproofaiHome(home), "state", "backfill-request.json");
37026
37179
  }
37027
37180
  function surveySessions(sinceMs, homeDir) {
37028
37181
  const out = [];
37029
37182
  for (const { cli, dir } of SESSION_DIRS) {
37030
- const root = join38(homeDir, dir);
37031
- if (!existsSync43(root))
37183
+ const root = join39(homeDir, dir);
37184
+ if (!existsSync44(root))
37032
37185
  continue;
37033
37186
  let files = 0;
37034
37187
  let newest = 0;
@@ -37042,13 +37195,13 @@ function surveySessions(sinceMs, homeDir) {
37042
37195
  return;
37043
37196
  }
37044
37197
  for (const e of entries) {
37045
- const p = join38(d, e.name);
37198
+ const p = join39(d, e.name);
37046
37199
  if (e.isDirectory()) {
37047
37200
  walk(p, depth + 1);
37048
37201
  continue;
37049
37202
  }
37050
37203
  try {
37051
- const st = statSync30(p);
37204
+ const st = statSync31(p);
37052
37205
  if (st.mtimeMs >= sinceMs) {
37053
37206
  files += 1;
37054
37207
  newest = Math.max(newest, st.mtimeMs);
@@ -37066,7 +37219,7 @@ function runBackfillCommand(opts = {}) {
37066
37219
  const now = opts.now ?? Date.now();
37067
37220
  const sinceMs = opts.sinceMs ?? now - DEFAULT_BACKFILL_DAYS * 24 * 60 * 60 * 1000;
37068
37221
  const home = failproofaiHome();
37069
- if (!existsSync43(home)) {
37222
+ if (!existsSync44(home)) {
37070
37223
  return {
37071
37224
  exitCode: 1,
37072
37225
  lines: [`No failproofai home at ${home}. Run \`failproofai config\` first.`]
@@ -37098,7 +37251,7 @@ function runBackfillCommand(opts = {}) {
37098
37251
  ]
37099
37252
  };
37100
37253
  }
37101
- const found = surveySessions(sinceMs, dirname23(home));
37254
+ const found = surveySessions(sinceMs, dirname24(home));
37102
37255
  const totalFiles = found.reduce((n, f) => n + f.files, 0);
37103
37256
  const sinceLabel = new Date(sinceMs).toISOString().slice(0, 10);
37104
37257
  const lines = [
@@ -37121,7 +37274,7 @@ function runBackfillCommand(opts = {}) {
37121
37274
  }
37122
37275
  try {
37123
37276
  const path = backfillRequestPath();
37124
- mkdirSync27(dirname23(path), { recursive: true });
37277
+ mkdirSync28(dirname24(path), { recursive: true });
37125
37278
  writeFileSync24(path, `${JSON.stringify({ sinceMs, requestedAtMs: now }, null, 2)}
37126
37279
  `, {
37127
37280
  mode: 384
@@ -37413,7 +37566,7 @@ function surveyReviewableCoverage(cwd) {
37413
37566
  let packsInstalled = false;
37414
37567
  let reviewers;
37415
37568
  try {
37416
- packsInstalled = hasInstalledPacks();
37569
+ packsInstalled = hasInstalledRegexPacks();
37417
37570
  const packs = readInstalledPacks().packs;
37418
37571
  for (const pack of packs) {
37419
37572
  const selected = pack.enabled;
@@ -37602,8 +37755,8 @@ var init_jev_stats = __esm(() => {
37602
37755
  });
37603
37756
 
37604
37757
  // src/hooks/jev-cli.ts
37605
- import { chmodSync as chmodSync8, existsSync as existsSync44, statSync as statSync31, unlinkSync as unlinkSync8 } from "node:fs";
37606
- import { dirname as dirname24 } from "node:path";
37758
+ import { chmodSync as chmodSync9, existsSync as existsSync45, statSync as statSync32, unlinkSync as unlinkSync8 } from "node:fs";
37759
+ import { dirname as dirname25 } from "node:path";
37607
37760
  function unknownOption(arg) {
37608
37761
  return OPTION_SHAPE.test(arg) ? `Unknown option: ${arg}` : "Unknown option (not repeated here, in case it carries a key).";
37609
37762
  }
@@ -38155,16 +38308,16 @@ async function setupRun(argv, deps, opts) {
38155
38308
  }
38156
38309
  let fileMode = null;
38157
38310
  try {
38158
- fileMode = statSync31(path).mode & 511;
38311
+ fileMode = statSync32(path).mode & 511;
38159
38312
  } catch {}
38160
- const dir = dirname24(path);
38313
+ const dir = dirname25(path);
38161
38314
  let tightenedDir = null;
38162
38315
  if (process.platform !== "win32") {
38163
38316
  try {
38164
- const before = statSync31(dir).mode & 511;
38317
+ const before = statSync32(dir).mode & 511;
38165
38318
  if ((before & 18) !== 0) {
38166
38319
  const after = before & -19;
38167
- chmodSync8(dir, after);
38320
+ chmodSync9(dir, after);
38168
38321
  tightenedDir = { path: dir, to: after.toString(8).padStart(4, "0") };
38169
38322
  }
38170
38323
  } catch {}
@@ -38283,15 +38436,15 @@ async function cloudSetup(values, bools, opts) {
38283
38436
  }
38284
38437
  if (process.platform !== "win32") {
38285
38438
  try {
38286
- const dir = dirname24(path);
38287
- const before = statSync31(dir).mode & 511;
38439
+ const dir = dirname25(path);
38440
+ const before = statSync32(dir).mode & 511;
38288
38441
  if ((before & 18) !== 0)
38289
- chmodSync8(dir, before & -19);
38442
+ chmodSync9(dir, before & -19);
38290
38443
  } catch {}
38291
38444
  }
38292
38445
  let fileMode = null;
38293
38446
  try {
38294
- fileMode = statSync31(path).mode & 511;
38447
+ fileMode = statSync32(path).mode & 511;
38295
38448
  } catch {}
38296
38449
  const cfg = checked.value;
38297
38450
  const route = jevRoute(cfg);
@@ -38730,7 +38883,7 @@ function remove(argv, opts) {
38730
38883
  if (parsed.positionals.length > 0)
38731
38884
  return fail2([STRAY_ARGUMENT, "", ...JEV_USAGE]);
38732
38885
  const path = jevConfigPath();
38733
- if (!existsSync44(path)) {
38886
+ if (!existsSync45(path)) {
38734
38887
  return ok2(stack(title("failproofai jev remove", "nothing to do", opts), note(`There is no ${path}; Jev is already off.`, opts)));
38735
38888
  }
38736
38889
  try {
@@ -38797,16 +38950,16 @@ var init_jev_cli = __esm(() => {
38797
38950
 
38798
38951
  // src/hooks/fp-config.ts
38799
38952
  import {
38800
- chmodSync as chmodSync9,
38801
- closeSync as closeSync7,
38953
+ chmodSync as chmodSync10,
38954
+ closeSync as closeSync8,
38802
38955
  constants as fsConstants4,
38803
- existsSync as existsSync45,
38956
+ existsSync as existsSync46,
38804
38957
  fstatSync as fstatSync4,
38805
- mkdirSync as mkdirSync28,
38806
- openSync as openSync7,
38958
+ mkdirSync as mkdirSync29,
38959
+ openSync as openSync8,
38807
38960
  readFileSync as readFileSync35,
38808
38961
  readSync as readSync6,
38809
- statSync as statSync32,
38962
+ statSync as statSync33,
38810
38963
  writeFileSync as writeFileSync25
38811
38964
  } from "node:fs";
38812
38965
  function detectLayout2() {
@@ -38816,17 +38969,17 @@ function detectLayout2() {
38816
38969
  return { kind: "current", version: raw };
38817
38970
  return raw.layout > LAYOUT_VERSION ? { kind: "future", found: raw.layout } : { kind: "stale", found: raw.layout };
38818
38971
  }
38819
- if (existsSync45(configFile())) {
38972
+ if (existsSync46(configFile())) {
38820
38973
  const layoutThreePositions = [
38821
38974
  legacy.authJson(),
38822
38975
  legacy.nextAudit(),
38823
38976
  legacy.auditSchedule()
38824
38977
  ];
38825
- if (layoutThreePositions.some((p) => existsSync45(p)))
38978
+ if (layoutThreePositions.some((p) => existsSync46(p)))
38826
38979
  return { kind: "stale", found: 3 };
38827
38980
  return { kind: "current", version: { layout: LAYOUT_VERSION, cli: "" }, inferred: true };
38828
38981
  }
38829
- if (existsSync45(legacy.configToml()))
38982
+ if (existsSync46(legacy.configToml()))
38830
38983
  return { kind: "stale", found: 2 };
38831
38984
  const layoutOneMarkers = [
38832
38985
  legacy.policyConfig(),
@@ -38837,7 +38990,7 @@ function detectLayout2() {
38837
38990
  legacy.ingestCredentials(),
38838
38991
  legacy.auditDashboard()
38839
38992
  ];
38840
- return layoutOneMarkers.some((p) => existsSync45(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
38993
+ return layoutOneMarkers.some((p) => existsSync46(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
38841
38994
  }
38842
38995
  function readLegacyTomlVersion2(text) {
38843
38996
  const layout = Number(/^\s*layout\s*=\s*(\d+)\s*$/m.exec(text)?.[1]);
@@ -38880,16 +39033,16 @@ var init_fp_home2 = () => {};
38880
39033
 
38881
39034
  // src/hooks/migrations.ts
38882
39035
  import {
38883
- chmodSync as chmodSync10,
38884
- copyFileSync as copyFileSync3,
38885
- existsSync as existsSync46,
38886
- mkdirSync as mkdirSync29,
39036
+ chmodSync as chmodSync11,
39037
+ copyFileSync as copyFileSync4,
39038
+ existsSync as existsSync47,
39039
+ mkdirSync as mkdirSync30,
38887
39040
  readFileSync as readFileSync36,
38888
- renameSync as renameSync12,
38889
- rmSync as rmSync16,
39041
+ renameSync as renameSync13,
39042
+ rmSync as rmSync17,
38890
39043
  writeFileSync as writeFileSync26
38891
39044
  } from "node:fs";
38892
- import { basename as basename9, dirname as dirname25, join as join39, resolve as resolve32 } from "node:path";
39045
+ import { basename as basename10, dirname as dirname26, join as join40, resolve as resolve32 } from "node:path";
38893
39046
  function migrateToLayout42() {
38894
39047
  const moves = [
38895
39048
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -38898,40 +39051,40 @@ function migrateToLayout42() {
38898
39051
  ];
38899
39052
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
38900
39053
  if (authDirOverride) {
38901
- moves.push({ from: join39(authDirOverride, "auth.json"), to: join39(authDirOverride, "session.json") }, {
38902
- from: join39(authDirOverride, "next-audit.json"),
38903
- to: join39(authDirOverride, "reminder.json")
39054
+ moves.push({ from: join40(authDirOverride, "auth.json"), to: join40(authDirOverride, "session.json") }, {
39055
+ from: join40(authDirOverride, "next-audit.json"),
39056
+ to: join40(authDirOverride, "reminder.json")
38904
39057
  });
38905
39058
  }
38906
39059
  const migrated = [];
38907
39060
  for (const { from, to } of moves) {
38908
- if (!existsSync46(from))
39061
+ if (!existsSync47(from))
38909
39062
  continue;
38910
- if (existsSync46(to)) {
38911
- rmSync16(from, { force: true });
39063
+ if (existsSync47(to)) {
39064
+ rmSync17(from, { force: true });
38912
39065
  continue;
38913
39066
  }
38914
- mkdirSync29(dirname25(to), { recursive: true });
39067
+ mkdirSync30(dirname26(to), { recursive: true });
38915
39068
  try {
38916
- renameSync12(from, to);
39069
+ renameSync13(from, to);
38917
39070
  } catch {
38918
39071
  try {
38919
- copyFileSync3(from, to);
39072
+ copyFileSync4(from, to);
38920
39073
  } catch (err) {
38921
39074
  try {
38922
- rmSync16(to, { force: true });
39075
+ rmSync17(to, { force: true });
38923
39076
  } catch {}
38924
39077
  throw err;
38925
39078
  }
38926
- rmSync16(from, { force: true });
39079
+ rmSync17(from, { force: true });
38927
39080
  }
38928
- migrated.push(`${basename9(from)} → audit/${basename9(to)}`);
39081
+ migrated.push(`${basename10(from)} → audit/${basename10(to)}`);
38929
39082
  }
38930
39083
  for (const secret of [auditSessionFile()]) {
38931
- if (!existsSync46(secret))
39084
+ if (!existsSync47(secret))
38932
39085
  continue;
38933
39086
  try {
38934
- chmodSync10(secret, 384);
39087
+ chmodSync11(secret, 384);
38935
39088
  } catch {}
38936
39089
  }
38937
39090
  writeVersionFile({ layout: 4 });
@@ -38962,26 +39115,26 @@ function readLedger2() {
38962
39115
  }
38963
39116
  function appendLedger2(entry) {
38964
39117
  try {
38965
- mkdirSync29(migrationsDir(), { recursive: true });
39118
+ mkdirSync30(migrationsDir(), { recursive: true });
38966
39119
  const all = [...readLedger2(), entry];
38967
39120
  writeFileSync26(migrationLedgerFile(), `${JSON.stringify(all, null, 2)}
38968
39121
  `, "utf8");
38969
39122
  } catch {}
38970
39123
  }
38971
39124
  function backupNameOf2(f) {
38972
- return f.as ?? basename9(f.at());
39125
+ return f.as ?? basename10(f.at());
38973
39126
  }
38974
39127
  function pruneMigratedCredentials2(from) {
38975
39128
  const pruned = [];
38976
39129
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
38977
39130
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS2) {
38978
39131
  try {
38979
- if (!existsSync46(landsAt()))
39132
+ if (!existsSync47(landsAt()))
38980
39133
  continue;
38981
39134
  const copy = resolve32(migrationBackupDir(layout), as);
38982
- if (!existsSync46(copy))
39135
+ if (!existsSync47(copy))
38983
39136
  continue;
38984
- rmSync16(copy, { force: true });
39137
+ rmSync17(copy, { force: true });
38985
39138
  pruned.push(as);
38986
39139
  } catch {}
38987
39140
  }
@@ -38992,7 +39145,7 @@ function filesToBackUp2() {
38992
39145
  const seen = new Map;
38993
39146
  for (const f of [...BACKED_UP2, ...BACKED_UP_LEGACY2]) {
38994
39147
  const path = f.at();
38995
- if (existsSync46(path))
39148
+ if (existsSync47(path))
38996
39149
  seen.set(path, backupNameOf2(f));
38997
39150
  }
38998
39151
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -39001,14 +39154,14 @@ function backupBeforeMigrating2(from) {
39001
39154
  const dir = migrationBackupDir(from);
39002
39155
  const saved = [];
39003
39156
  try {
39004
- rmSync16(dir, { recursive: true, force: true });
39005
- mkdirSync29(dir, { recursive: true });
39157
+ rmSync17(dir, { recursive: true, force: true });
39158
+ mkdirSync30(dir, { recursive: true });
39006
39159
  } catch {
39007
39160
  return [];
39008
39161
  }
39009
39162
  for (const { path: source, as } of filesToBackUp2()) {
39010
39163
  try {
39011
- copyFileSync3(source, resolve32(dir, as));
39164
+ copyFileSync4(source, resolve32(dir, as));
39012
39165
  saved.push(as);
39013
39166
  } catch {}
39014
39167
  }
@@ -39140,19 +39293,19 @@ var init_migrations2 = __esm(() => {
39140
39293
  { at: legacy.auditSchedule }
39141
39294
  ];
39142
39295
  PRUNED_AFTER_SUCCESS2 = [
39143
- { as: basename9(legacy.authJson()), landsAt: auditSessionFile }
39296
+ { as: basename10(legacy.authJson()), landsAt: auditSessionFile }
39144
39297
  ];
39145
39298
  });
39146
39299
 
39147
39300
  // src/hooks/daemon-service.ts
39148
39301
  import {
39149
- existsSync as existsSync47,
39150
- mkdirSync as mkdirSync30,
39302
+ existsSync as existsSync48,
39303
+ mkdirSync as mkdirSync31,
39151
39304
  mkdtempSync as mkdtempSync2,
39152
39305
  readFileSync as readFileSync37,
39153
39306
  writeFileSync as writeFileSync27,
39154
39307
  unlinkSync as unlinkSync9,
39155
- rmSync as rmSync17
39308
+ rmSync as rmSync18
39156
39309
  } from "node:fs";
39157
39310
  import { homedir as homedir31, tmpdir as tmpdir3, userInfo as userInfo2 } from "node:os";
39158
39311
  import { resolve as resolve33 } from "node:path";
@@ -39171,13 +39324,13 @@ function resolveFailproofaidBinaryPath2() {
39171
39324
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
39172
39325
  return process.env.FAILPROOFAI_DAEMON_BINARY;
39173
39326
  const downloaded = installedBinaryPath();
39174
- if (existsSync47(downloaded))
39327
+ if (existsSync48(downloaded))
39175
39328
  return downloaded;
39176
39329
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
39177
39330
  if (packageRoot) {
39178
39331
  for (const profile of ["release", "debug"]) {
39179
39332
  const candidate = resolve33(packageRoot, "target", profile, "failproofaid");
39180
- if (existsSync47(candidate))
39333
+ if (existsSync48(candidate))
39181
39334
  return candidate;
39182
39335
  }
39183
39336
  }
@@ -39208,7 +39361,7 @@ function resolveWorkerCommand2() {
39208
39361
  if (!packageRoot)
39209
39362
  return null;
39210
39363
  const workerScript = resolve33(packageRoot, "dist", "worker.mjs");
39211
- if (!existsSync47(workerScript))
39364
+ if (!existsSync48(workerScript))
39212
39365
  return null;
39213
39366
  return `${shellQuote2(process.execPath)} ${shellQuote2(workerScript)}`;
39214
39367
  }
@@ -39219,7 +39372,7 @@ function resolveCliCommand2() {
39219
39372
  if (!packageRoot)
39220
39373
  return null;
39221
39374
  const cliScript = resolve33(packageRoot, "dist", "cli.mjs");
39222
- if (!existsSync47(cliScript))
39375
+ if (!existsSync48(cliScript))
39223
39376
  return null;
39224
39377
  return `${shellQuote2(process.execPath)} ${shellQuote2(cliScript)}`;
39225
39378
  }
@@ -39233,7 +39386,7 @@ function workerScriptPath2() {
39233
39386
  if (!packageRoot)
39234
39387
  return null;
39235
39388
  const workerScript = resolve33(packageRoot, "dist", "worker.mjs");
39236
- return existsSync47(workerScript) ? workerScript : null;
39389
+ return existsSync48(workerScript) ? workerScript : null;
39237
39390
  }
39238
39391
  function assertUnitSafe2(value, field) {
39239
39392
  if (UNIT_UNSAFE_RE2.test(value)) {
@@ -39315,14 +39468,14 @@ function writePrivilegedFile2(destination, contents, mode = "0644") {
39315
39468
  writeFileSync27(staging, contents, "utf8");
39316
39469
  runPrivileged2("install", ["-m", mode, staging, destination]);
39317
39470
  } finally {
39318
- rmSync17(stagingDir, { recursive: true, force: true });
39471
+ rmSync18(stagingDir, { recursive: true, force: true });
39319
39472
  }
39320
39473
  }
39321
39474
  function removeLegacyUserService2() {
39322
39475
  try {
39323
39476
  if (process.platform === "linux") {
39324
39477
  const legacy = legacySystemdUserUnitPath2();
39325
- if (!existsSync47(legacy))
39478
+ if (!existsSync48(legacy))
39326
39479
  return;
39327
39480
  try {
39328
39481
  execFileSync3("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -39339,7 +39492,7 @@ function removeLegacyUserService2() {
39339
39492
  } catch {}
39340
39493
  } else {
39341
39494
  const legacyAgent = legacyLaunchAgentPlistPath2();
39342
- if (existsSync47(legacyAgent)) {
39495
+ if (existsSync48(legacyAgent)) {
39343
39496
  try {
39344
39497
  execFileSync3("launchctl", ["unload", "-w", legacyAgent], {
39345
39498
  stdio: "ignore",
@@ -39349,7 +39502,7 @@ function removeLegacyUserService2() {
39349
39502
  unlinkSync9(legacyAgent);
39350
39503
  }
39351
39504
  const legacyDaemon = legacySharedLaunchDaemonPath2();
39352
- if (existsSync47(legacyDaemon)) {
39505
+ if (existsSync48(legacyDaemon)) {
39353
39506
  try {
39354
39507
  runPrivileged2("launchctl", ["unload", "-w", legacyDaemon]);
39355
39508
  } catch {}
@@ -39366,7 +39519,7 @@ function systemdUnitContents2(binaryPath, workerCmd, cliCmd = null) {
39366
39519
  const user = assertUnitSafe2(serviceUser2(), "User");
39367
39520
  assertUnitSafe2(binaryPath, "ExecStart");
39368
39521
  assertUnitSafe2(homedir31(), "HOME");
39369
- const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync47(p));
39522
+ const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync48(p));
39370
39523
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe2(p, "ConditionPathExists")}
39371
39524
  `).join("");
39372
39525
  return `[Unit]
@@ -39472,7 +39625,7 @@ async function installDaemonService2() {
39472
39625
  } else {
39473
39626
  const plistPath = launchdPlistPath2();
39474
39627
  const logDir = logsDir();
39475
- mkdirSync30(logDir, { recursive: true });
39628
+ mkdirSync31(logDir, { recursive: true });
39476
39629
  try {
39477
39630
  runPrivileged2("launchctl", ["unload", plistPath]);
39478
39631
  } catch {}
@@ -39620,7 +39773,7 @@ function daemonServiceStatus2() {
39620
39773
  if (!isDaemonSupportedPlatform2())
39621
39774
  return "unsupported-platform";
39622
39775
  if (process.platform === "linux") {
39623
- if (!existsSync47(systemdUnitPath2()))
39776
+ if (!existsSync48(systemdUnitPath2()))
39624
39777
  return "not-installed";
39625
39778
  try {
39626
39779
  const out = execFileSync3("systemctl", ["is-active", systemdUnitName2()], {
@@ -39633,7 +39786,7 @@ function daemonServiceStatus2() {
39633
39786
  }
39634
39787
  }
39635
39788
  const plistPath = launchdPlistPath2();
39636
- if (!existsSync47(plistPath))
39789
+ if (!existsSync48(plistPath))
39637
39790
  return "not-installed";
39638
39791
  try {
39639
39792
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -39701,7 +39854,7 @@ var init_hermes_update = __esm(() => {
39701
39854
  });
39702
39855
 
39703
39856
  // src/hooks/uninstall-cli.ts
39704
- import { existsSync as existsSync48, rmSync as rmSync18 } from "node:fs";
39857
+ import { existsSync as existsSync49, rmSync as rmSync19 } from "node:fs";
39705
39858
  function survey(cwd) {
39706
39859
  const clis = [];
39707
39860
  for (const id of listInstallableIds()) {
@@ -39722,9 +39875,9 @@ function survey(cwd) {
39722
39875
  return {
39723
39876
  clis,
39724
39877
  servicePath,
39725
- serviceInstalled: !!servicePath && existsSync48(servicePath),
39878
+ serviceInstalled: !!servicePath && existsSync49(servicePath),
39726
39879
  daemonConfigured,
39727
- homeExists: existsSync48(failproofaiHome())
39880
+ homeExists: existsSync49(failproofaiHome())
39728
39881
  };
39729
39882
  }
39730
39883
  async function runUninstallCommand(opts = {}) {
@@ -39822,7 +39975,7 @@ async function runUninstallCommand(opts = {}) {
39822
39975
  } catch {}
39823
39976
  try {
39824
39977
  await uninstallDaemonService();
39825
- if (found.servicePath && existsSync48(found.servicePath)) {
39978
+ if (found.servicePath && existsSync49(found.servicePath)) {
39826
39979
  failures.push(`the service at ${found.servicePath} is still there (most often: no sudo). ` + `Remove it with the commands below.`);
39827
39980
  } else {
39828
39981
  lines.push(`✓ stopped and removed the daemon service`);
@@ -39834,7 +39987,7 @@ async function runUninstallCommand(opts = {}) {
39834
39987
  }
39835
39988
  if (opts.purge && found.homeExists) {
39836
39989
  try {
39837
- rmSync18(failproofaiHome(), { recursive: true, force: true });
39990
+ rmSync19(failproofaiHome(), { recursive: true, force: true });
39838
39991
  purged = true;
39839
39992
  lines.push(`✓ deleted ${failproofaiHome()}`);
39840
39993
  } catch (err) {
@@ -39845,7 +39998,7 @@ async function runUninstallCommand(opts = {}) {
39845
39998
  lines.push(``, `Not everything could be removed:`);
39846
39999
  for (const f of failures)
39847
40000
  lines.push(` ✗ ${f}`);
39848
- if (found.servicePath && existsSync48(found.servicePath)) {
40001
+ if (found.servicePath && existsSync49(found.servicePath)) {
39849
40002
  lines.push(``, `To remove the service by hand:`, ...manualServiceRemoval(found.servicePath), ``, `(\`${daemonStatusCommand()}\` shows its current state.)`);
39850
40003
  }
39851
40004
  return { exitCode: 1, lines, planLines, purged };
@@ -39879,8 +40032,8 @@ var init_uninstall_cli = __esm(() => {
39879
40032
  import { execFileSync as execFileSync4 } from "node:child_process";
39880
40033
  import { homedir as homedir32, tmpdir as tmpdir4 } from "node:os";
39881
40034
  import { createHash as createHash11 } from "node:crypto";
39882
- import { copyFileSync as copyFileSync4, existsSync as existsSync49, mkdirSync as mkdirSync31, mkdtempSync as mkdtempSync3, readFileSync as readFileSync38, readdirSync as readdirSync23, realpathSync as realpathSync4, rmSync as rmSync19, statSync as statSync33, writeFileSync as writeFileSync28 } from "node:fs";
39883
- import { basename as basename10, dirname as dirname26, isAbsolute as isAbsolute6, join as join40, relative as relative5, resolve as resolve34, sep as sep6 } from "node:path";
40035
+ import { copyFileSync as copyFileSync5, existsSync as existsSync50, mkdirSync as mkdirSync32, mkdtempSync as mkdtempSync3, readFileSync as readFileSync38, readdirSync as readdirSync23, realpathSync as realpathSync5, rmSync as rmSync20, statSync as statSync34, writeFileSync as writeFileSync28 } from "node:fs";
40036
+ import { basename as basename11, dirname as dirname27, isAbsolute as isAbsolute6, join as join41, relative as relative5, resolve as resolve34, sep as sep6 } from "node:path";
39884
40037
  function parseList(rest, ...flags) {
39885
40038
  let found = false;
39886
40039
  const out = [];
@@ -40016,7 +40169,7 @@ async function build(rest) {
40016
40169
  return fail3([err instanceof Error ? err.message : String(err)]);
40017
40170
  }
40018
40171
  const entryPath = resolve34(entry);
40019
- if (!existsSync49(entryPath))
40172
+ if (!existsSync50(entryPath))
40020
40173
  return fail3([`No such file: ${entryPath}`]);
40021
40174
  const source = readFileSync38(entryPath, "utf8");
40022
40175
  const localImport = firstRelativeSpecifier(source);
@@ -40137,11 +40290,11 @@ async function build(rest) {
40137
40290
  ...semantic.length > 0 ? { semantic } : {}
40138
40291
  }, null, 2) + `
40139
40292
  `;
40140
- mkdirSync31(outDir, { recursive: true });
40293
+ mkdirSync32(outDir, { recursive: true });
40141
40294
  const manifestPath = resolve34(outDir, PACK_MANIFEST_ASSET);
40142
40295
  const entryOut = resolve34(outDir, PACK_ENTRY_ASSET);
40143
40296
  writeFileSync28(manifestPath, manifest, "utf8");
40144
- copyFileSync4(entryPath, entryOut);
40297
+ copyFileSync5(entryPath, entryOut);
40145
40298
  const sha = (bytes) => createHash11("sha256").update(bytes).digest("hex");
40146
40299
  writeFileSync28(resolve34(outDir, PACK_CHECKSUMS_ASSET), `${sha(manifest)} ${PACK_MANIFEST_ASSET}
40147
40300
  ${sha(readFileSync38(entryOut))} ${PACK_ENTRY_ASSET}
@@ -40285,10 +40438,10 @@ async function scaffold(target) {
40285
40438
  chosen = answer.trim();
40286
40439
  }
40287
40440
  const path = resolve34(withPolicyExtension(chosen ?? "my-policies"));
40288
- if (existsSync49(path)) {
40441
+ if (existsSync50(path)) {
40289
40442
  return fail3([`${path} already exists — name a different file, or edit that one.`]);
40290
40443
  }
40291
- mkdirSync31(resolve34(path, ".."), { recursive: true });
40444
+ mkdirSync32(resolve34(path, ".."), { recursive: true });
40292
40445
  writeFileSync28(path, `import { customPolicies, allow, deny } from "failproofai";
40293
40446
 
40294
40447
  // One file, no relative imports: only this entry is digest-pinned, so a pack
@@ -40387,7 +40540,7 @@ function porcelainEntries(status) {
40387
40540
  }
40388
40541
  function realOrSelf(path) {
40389
40542
  try {
40390
- return realpathSync4(path);
40543
+ return realpathSync5(path);
40391
40544
  } catch {
40392
40545
  return path;
40393
40546
  }
@@ -40479,7 +40632,7 @@ function findEntry(dir) {
40479
40632
  continue;
40480
40633
  const full = resolve34(dir, name);
40481
40634
  try {
40482
- if (statSync33(full).size > 512 * 1024)
40635
+ if (statSync34(full).size > 512 * 1024)
40483
40636
  continue;
40484
40637
  const text = readFileSync38(full, "utf8");
40485
40638
  if (/from\s+["']failproofai["']/.test(text) && /(?:customPolicies|semanticPolicies)\s*\.\s*add\s*\(/.test(text)) {
@@ -40498,7 +40651,7 @@ function withLocalImports(sources) {
40498
40651
  const file = queue.shift();
40499
40652
  let text;
40500
40653
  try {
40501
- if (statSync33(file).size > 512 * 1024)
40654
+ if (statSync34(file).size > 512 * 1024)
40502
40655
  continue;
40503
40656
  text = readFileSync38(file, "utf8");
40504
40657
  } catch {
@@ -40506,13 +40659,13 @@ function withLocalImports(sources) {
40506
40659
  }
40507
40660
  for (const re of LOCAL_IMPORT_RES) {
40508
40661
  for (const match of text.matchAll(re)) {
40509
- const base = resolve34(dirname26(file), match[1]);
40662
+ const base = resolve34(dirname27(file), match[1]);
40510
40663
  for (const ext of LOCAL_IMPORT_EXTENSIONS) {
40511
40664
  const candidate = base + ext;
40512
40665
  if (seen.has(candidate))
40513
40666
  break;
40514
40667
  try {
40515
- if (!statSync33(candidate).isFile())
40668
+ if (!statSync34(candidate).isFile())
40516
40669
  continue;
40517
40670
  } catch {
40518
40671
  continue;
@@ -40737,7 +40890,7 @@ function pushExistingHistory(dir, owner, name, token) {
40737
40890
  const branch = git(["rev-parse", "--abbrev-ref", "HEAD"]);
40738
40891
  if (!branch || branch === "HEAD" || !git(["rev-parse", "--verify", "HEAD"]))
40739
40892
  return false;
40740
- const askpass = join40(mkdtempSync3(join40(tmpdir4(), "fpai-askpass-")), "askpass.sh");
40893
+ const askpass = join41(mkdtempSync3(join41(tmpdir4(), "fpai-askpass-")), "askpass.sh");
40741
40894
  try {
40742
40895
  writeFileSync28(askpass, `#!/bin/sh
40743
40896
  case "$1" in
@@ -40759,7 +40912,7 @@ esac
40759
40912
  return true;
40760
40913
  } finally {
40761
40914
  try {
40762
- rmSync19(dirname26(askpass), { recursive: true, force: true });
40915
+ rmSync20(dirname27(askpass), { recursive: true, force: true });
40763
40916
  } catch {}
40764
40917
  }
40765
40918
  }
@@ -40810,7 +40963,7 @@ function bundleEntry(sources, outDir) {
40810
40963
  ]
40811
40964
  };
40812
40965
  }
40813
- mkdirSync31(outDir, { recursive: true });
40966
+ mkdirSync32(outDir, { recursive: true });
40814
40967
  const entry = resolve34(outDir, ".entry.generated.mjs");
40815
40968
  writeFileSync28(entry, sources.map((f) => `import ${JSON.stringify(f.startsWith("/") ? f : resolve34(f))};`).join(`
40816
40969
  `) + `
@@ -40942,12 +41095,12 @@ async function publish(rest) {
40942
41095
  if (askingWhere) {
40943
41096
  const found = discovered.length > 0 ? discovered : [entry];
40944
41097
  process.stdout.write(`
40945
- ${found.length} policy ${found.length === 1 ? "file" : "files"}: ` + `${found.map((f) => basename10(f)).join(", ")}
41098
+ ${found.length} policy ${found.length === 1 ? "file" : "files"}: ` + `${found.map((f) => basename11(f)).join(", ")}
40946
41099
 
40947
41100
  `);
40948
41101
  const token = githubToken();
40949
41102
  const login = token ? await credentialLogin(token) : null;
40950
- const folder = basename10(resolve34(entry, ".."));
41103
+ const folder = basename11(resolve34(entry, ".."));
40951
41104
  const answered = await askWhereToPublish(`${login ?? "your-account"}/${folder}`, { stdin: process.stdin, stdout: process.stdout });
40952
41105
  if (answered === null)
40953
41106
  return ok3(["Nothing was published."]);
@@ -40958,7 +41111,7 @@ async function publish(rest) {
40958
41111
  let versionFromSha = false;
40959
41112
  const dryRun = rest.includes("--dry-run") || !repo;
40960
41113
  const allowPrivate = rest.includes("--allow-private");
40961
- const id = flag("id") ?? repo ?? (dryRun && entry ? `local/${basename10(resolve34(entry, ".."))}` : undefined);
41114
+ const id = flag("id") ?? repo ?? (dryRun && entry ? `local/${basename11(resolve34(entry, ".."))}` : undefined);
40962
41115
  const [owner, name] = (repo ?? "/").split("/");
40963
41116
  if (repo && (!owner || !name || repo.split("/").length !== 2)) {
40964
41117
  return fail3([`--repo must be <owner>/<repo>, got ${JSON.stringify(repo)}`]);
@@ -41905,8 +42058,8 @@ var init_install_prompt = __esm(() => {
41905
42058
 
41906
42059
  // src/hooks/manager.ts
41907
42060
  import { execSync as execSync7 } from "node:child_process";
41908
- import { existsSync as existsSync50 } from "node:fs";
41909
- import { resolve as resolve35, basename as basename11 } from "node:path";
42061
+ import { existsSync as existsSync51 } from "node:fs";
42062
+ import { resolve as resolve35, basename as basename12 } from "node:path";
41910
42063
  import { platform as platform4, arch as arch4, release as release3, hostname as hostname6 } from "node:os";
41911
42064
  function getSettingsPath2(scope, cwd) {
41912
42065
  return claudeCode.getSettingsPath(scope, cwd);
@@ -42137,7 +42290,7 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
42137
42290
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
42138
42291
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve35(path));
42139
42292
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve35(path)).filter((path) => {
42140
- if (existsSync50(path))
42293
+ if (existsSync51(path))
42141
42294
  return true;
42142
42295
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
42143
42296
  return false;
@@ -42369,7 +42522,7 @@ async function removeHooks2(policyNames, scope = "user", cwd, opts) {
42369
42522
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
42370
42523
  for (const s of scopesToRemove) {
42371
42524
  const settingsPaths = settingsPathsFor(integration, s, cwd);
42372
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync50(p));
42525
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync51(p));
42373
42526
  if (existing.length === 0) {
42374
42527
  if (scope !== "all" && selectedClis.length === 1) {
42375
42528
  console.log("No settings file found. Nothing to remove.");
@@ -42522,7 +42675,7 @@ async function listHooks(cwd) {
42522
42675
  for (const path of explicitPaths) {
42523
42676
  const absPath = resolve35(findProjectConfigDir(cwd ?? process.cwd()), path);
42524
42677
  groups.push(note(absPath, opts));
42525
- if (!existsSync50(absPath)) {
42678
+ if (!existsSync51(absPath)) {
42526
42679
  groups.push(warning([`file not found: ${absPath}`], opts));
42527
42680
  continue;
42528
42681
  }
@@ -42567,7 +42720,7 @@ async function listHooks(cwd) {
42567
42720
  groups.push(note(dir, opts));
42568
42721
  const rows = [];
42569
42722
  for (const file of files) {
42570
- const filename = basename11(file);
42723
+ const filename = basename12(file);
42571
42724
  try {
42572
42725
  const hooks = await loadCustomHooks(file);
42573
42726
  record(filename, hooks.map((h) => h.name));
@@ -43091,26 +43244,26 @@ function parseScriptArgs(argv) {
43091
43244
  var init_parse_script_args = () => {};
43092
43245
 
43093
43246
  // scripts/install-diagnosis.mjs
43094
- import { existsSync as existsSync51, readFileSync as readFileSync40, realpathSync as realpathSync5 } from "node:fs";
43095
- import { dirname as dirname27, resolve as resolve37 } from "node:path";
43247
+ import { existsSync as existsSync52, readFileSync as readFileSync40, realpathSync as realpathSync6 } from "node:fs";
43248
+ import { dirname as dirname28, resolve as resolve37 } from "node:path";
43096
43249
  import { homedir as homedir33, platform as platform5 } from "node:os";
43097
43250
  import { spawnSync } from "node:child_process";
43098
43251
  function findPackageRoot(start) {
43099
43252
  try {
43100
- let dir = realpathSync5(start);
43101
- if (existsSync51(dir) && !existsSync51(resolve37(dir, "package.json"))) {
43102
- dir = dirname27(dir);
43253
+ let dir = realpathSync6(start);
43254
+ if (existsSync52(dir) && !existsSync52(resolve37(dir, "package.json"))) {
43255
+ dir = dirname28(dir);
43103
43256
  }
43104
43257
  while (true) {
43105
43258
  const pkgPath = resolve37(dir, "package.json");
43106
- if (existsSync51(pkgPath)) {
43259
+ if (existsSync52(pkgPath)) {
43107
43260
  try {
43108
43261
  const pkg = JSON.parse(readFileSync40(pkgPath, "utf8"));
43109
43262
  if (pkg.name === PKG_NAME)
43110
43263
  return dir;
43111
43264
  } catch {}
43112
43265
  }
43113
- const parent = dirname27(dir);
43266
+ const parent = dirname28(dir);
43114
43267
  if (parent === dir)
43115
43268
  return null;
43116
43269
  dir = parent;
@@ -43150,7 +43303,7 @@ function locateNpmGlobal() {
43150
43303
  if (!root)
43151
43304
  return null;
43152
43305
  const candidate = resolve37(root, PKG_NAME);
43153
- return existsSync51(resolve37(candidate, "package.json")) ? candidate : null;
43306
+ return existsSync52(resolve37(candidate, "package.json")) ? candidate : null;
43154
43307
  } catch {
43155
43308
  return null;
43156
43309
  }
@@ -43158,7 +43311,7 @@ function locateNpmGlobal() {
43158
43311
  function locateBunGlobal() {
43159
43312
  try {
43160
43313
  const candidate = resolve37(homedir33(), ".bun", "install", "global", "node_modules", PKG_NAME);
43161
- return existsSync51(resolve37(candidate, "package.json")) ? candidate : null;
43314
+ return existsSync52(resolve37(candidate, "package.json")) ? candidate : null;
43162
43315
  } catch {
43163
43316
  return null;
43164
43317
  }
@@ -43177,7 +43330,7 @@ function buildRecommendation(pathFirstBin) {
43177
43330
  function diagnoseShadow(self) {
43178
43331
  const selfPackageRoot = (() => {
43179
43332
  try {
43180
- return self?.selfPackageRoot ? realpathSync5(self.selfPackageRoot) : null;
43333
+ return self?.selfPackageRoot ? realpathSync6(self.selfPackageRoot) : null;
43181
43334
  } catch {
43182
43335
  return self?.selfPackageRoot ?? null;
43183
43336
  }
@@ -43261,8 +43414,8 @@ var init_dashboard_host = __esm(() => {
43261
43414
 
43262
43415
  // scripts/launch.ts
43263
43416
  import { spawn as spawn2 } from "child_process";
43264
- import { realpathSync as realpathSync6, existsSync as existsSync52 } from "node:fs";
43265
- import { resolve as resolve38, dirname as dirname28 } from "node:path";
43417
+ import { realpathSync as realpathSync7, existsSync as existsSync53 } from "node:fs";
43418
+ import { resolve as resolve38, dirname as dirname29 } from "node:path";
43266
43419
  import { fileURLToPath as fileURLToPath2 } from "node:url";
43267
43420
  import { createInterface } from "node:readline";
43268
43421
  function launch(mode) {
@@ -43286,9 +43439,9 @@ function launch(mode) {
43286
43439
  process.env.PORT = port;
43287
43440
  process.env.HOSTNAME = bindHost;
43288
43441
  cmd = "node";
43289
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve38(dirname28(realpathSync6(fileURLToPath2(import.meta.url))), "..");
43442
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve38(dirname29(realpathSync7(fileURLToPath2(import.meta.url))), "..");
43290
43443
  const serverJsPath = resolve38(packageRoot, ".next/standalone/server.js");
43291
- if (!existsSync52(serverJsPath)) {
43444
+ if (!existsSync53(serverJsPath)) {
43292
43445
  let shadowMessage = null;
43293
43446
  try {
43294
43447
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -44063,23 +44216,40 @@ import {
44063
44216
  cpSync as cpSync2,
44064
44217
  readFileSync as readFileSync41,
44065
44218
  writeFileSync as writeFileSync29,
44066
- existsSync as existsSync53,
44067
- lstatSync as lstatSync3,
44068
- mkdirSync as mkdirSync32,
44219
+ existsSync as existsSync54,
44220
+ lstatSync as lstatSync4,
44221
+ mkdirSync as mkdirSync33,
44069
44222
  readlinkSync as readlinkSync2,
44070
- realpathSync as realpathSync7,
44071
- renameSync as renameSync13,
44072
- rmSync as rmSync20,
44223
+ realpathSync as realpathSync8,
44224
+ renameSync as renameSync14,
44225
+ rmSync as rmSync21,
44073
44226
  symlinkSync as symlinkSync2,
44074
44227
  unlinkSync as unlinkSync10
44075
44228
  } from "node:fs";
44076
- import { resolve as resolve39, dirname as dirname29, basename as basename12 } from "node:path";
44229
+ import { resolve as resolve39, dirname as dirname30, basename as basename13 } from "node:path";
44077
44230
  import { fileURLToPath as fileURLToPath3 } from "node:url";
44078
44231
  function readYamlDoc2(path) {
44232
+ if (!existsSync54(path))
44233
+ return $parseDocument("");
44234
+ let text;
44079
44235
  try {
44080
- return existsSync53(path) ? $parseDocument(readFileSync41(path, "utf8")) : $parseDocument("");
44236
+ text = readFileSync41(path, "utf8");
44237
+ } catch (err) {
44238
+ throw new UnreadableAgentConfigError2(path, `it could not be read (${err instanceof Error ? err.message : String(err)})`);
44239
+ }
44240
+ const doc = $parseDocument(text);
44241
+ if (doc.errors.length > 0) {
44242
+ const first = doc.errors[0]?.message.split(`
44243
+ `)[0] ?? "syntax error";
44244
+ throw new UnreadableAgentConfigError2(path, `it does not parse as YAML (${first})`);
44245
+ }
44246
+ return doc;
44247
+ }
44248
+ function inspectYamlDoc2(path) {
44249
+ try {
44250
+ return readYamlDoc2(path);
44081
44251
  } catch {
44082
- return $parseDocument("");
44252
+ return null;
44083
44253
  }
44084
44254
  }
44085
44255
  function isMarkedHook2(hook) {
@@ -44095,18 +44265,31 @@ function getHermesPluginSourcePath2() {
44095
44265
  const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
44096
44266
  if (fromEnv)
44097
44267
  return resolve39(fromEnv, HERMES_PLUGIN_SOURCE_DIR2);
44098
- return resolve39(fileURLToPath3(import.meta.url), "..", "..", "..", HERMES_PLUGIN_SOURCE_DIR2);
44268
+ return findHermesPluginSourcePath2(dirname30(fileURLToPath3(import.meta.url)));
44269
+ }
44270
+ function findHermesPluginSourcePath2(startDir) {
44271
+ let dir = resolve39(startDir);
44272
+ for (let i = 0;i < 8; i++) {
44273
+ const candidate = resolve39(dir, HERMES_PLUGIN_SOURCE_DIR2);
44274
+ if (existsSync54(resolve39(candidate, "plugin.yaml")))
44275
+ return candidate;
44276
+ const parent = dirname30(dir);
44277
+ if (parent === dir)
44278
+ break;
44279
+ dir = parent;
44280
+ }
44281
+ return resolve39(startDir, "..", "..", HERMES_PLUGIN_SOURCE_DIR2);
44099
44282
  }
44100
44283
  function hermesPluginPathForSettings2(settingsPath) {
44101
- return resolve39(dirname29(settingsPath), "plugins", HERMES_PLUGIN_ID2);
44284
+ return resolve39(dirname30(settingsPath), "plugins", HERMES_PLUGIN_ID2);
44102
44285
  }
44103
44286
  function hasAllHermesPluginFiles2(dir) {
44104
- return HERMES_PLUGIN_FILES2.every((file) => existsSync53(resolve39(dir, file)));
44287
+ return HERMES_PLUGIN_FILES2.every((file) => existsSync54(resolve39(dir, file)));
44105
44288
  }
44106
44289
  function isFailproofaiHermesPluginSource2(dir) {
44107
- if (basename12(dir) !== HERMES_PLUGIN_SOURCE_DIR2)
44290
+ if (basename13(dir) !== HERMES_PLUGIN_SOURCE_DIR2)
44108
44291
  return false;
44109
- if (!existsSync53(dir))
44292
+ if (!existsSync54(dir))
44110
44293
  return true;
44111
44294
  try {
44112
44295
  const manifest = readFileSync41(resolve39(dir, "plugin.yaml"), "utf8");
@@ -44119,7 +44302,7 @@ function samePath2(a, b) {
44119
44302
  if (resolve39(a) === resolve39(b))
44120
44303
  return true;
44121
44304
  try {
44122
- return realpathSync7(a) === realpathSync7(b);
44305
+ return realpathSync8(a) === realpathSync8(b);
44123
44306
  } catch {
44124
44307
  return false;
44125
44308
  }
@@ -44129,7 +44312,7 @@ function hermesPluginState2(settingsPath) {
44129
44312
  let isLink;
44130
44313
  let isDirectory;
44131
44314
  try {
44132
- const stat = lstatSync3(pluginPath);
44315
+ const stat = lstatSync4(pluginPath);
44133
44316
  isLink = stat.isSymbolicLink();
44134
44317
  isDirectory = stat.isDirectory();
44135
44318
  } catch {
@@ -44138,7 +44321,7 @@ function hermesPluginState2(settingsPath) {
44138
44321
  if (isLink) {
44139
44322
  let target;
44140
44323
  try {
44141
- target = resolve39(dirname29(pluginPath), readlinkSync2(pluginPath));
44324
+ target = resolve39(dirname30(pluginPath), readlinkSync2(pluginPath));
44142
44325
  } catch {
44143
44326
  return { kind: "foreign" };
44144
44327
  }
@@ -44151,21 +44334,29 @@ function hermesPluginState2(settingsPath) {
44151
44334
  current: samePath2(target, getHermesPluginSourcePath2())
44152
44335
  };
44153
44336
  }
44154
- if (isDirectory && existsSync53(resolve39(pluginPath, HERMES_PLUGIN_MARKER2))) {
44337
+ if (isDirectory && existsSync54(resolve39(pluginPath, HERMES_PLUGIN_MARKER2))) {
44155
44338
  return { kind: "copy", complete: hasAllHermesPluginFiles2(pluginPath) };
44156
44339
  }
44157
44340
  return { kind: "foreign" };
44158
44341
  }
44159
44342
  function hermesConfigState2(settingsPath) {
44160
- if (!existsSync53(settingsPath)) {
44161
- return { pluginEnabled: false, legacyShellHookPresent: false };
44343
+ if (!existsSync54(settingsPath)) {
44344
+ return { pluginEnabled: false, pluginListed: false, pluginDisabled: false, legacyShellHookPresent: false };
44345
+ }
44346
+ const doc = inspectYamlDoc2(settingsPath);
44347
+ if (!doc) {
44348
+ return { pluginEnabled: false, pluginListed: false, pluginDisabled: false, legacyShellHookPresent: false, unreadable: true };
44162
44349
  }
44163
- const doc = readYamlDoc2(settingsPath);
44164
44350
  const js = doc.toJS() ?? {};
44165
44351
  const enabled = js.plugins?.enabled;
44352
+ const disabled = js.plugins?.disabled;
44166
44353
  const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook2(entry)));
44354
+ const pluginListed = Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID2);
44355
+ const pluginDisabled = Array.isArray(disabled) && disabled.includes(HERMES_PLUGIN_ID2);
44167
44356
  return {
44168
- pluginEnabled: Array.isArray(enabled) && enabled.includes(HERMES_PLUGIN_ID2),
44357
+ pluginEnabled: pluginListed && !pluginDisabled,
44358
+ pluginListed,
44359
+ pluginDisabled,
44169
44360
  legacyShellHookPresent
44170
44361
  };
44171
44362
  }
@@ -44183,15 +44374,20 @@ function hermesProfileHealth() {
44183
44374
  pluginInstalled,
44184
44375
  pluginMode: plugin.kind === "link" || plugin.kind === "copy" ? plugin.kind : null,
44185
44376
  pluginEnabled: config.pluginEnabled,
44377
+ pluginDisabled: config.pluginDisabled,
44186
44378
  legacyShellHookPresent: config.legacyShellHookPresent,
44187
44379
  cronUnchecked: config.legacyShellHookPresent && !pluginWorks,
44188
- healthy: pluginWorks && !config.legacyShellHookPresent
44380
+ configUnreadable: config.unreadable === true,
44381
+ healthy: pluginWorks && !config.legacyShellHookPresent && config.unreadable !== true
44189
44382
  };
44190
44383
  });
44191
44384
  }
44192
44385
  function hermesProfileStatusRows() {
44193
- return hermesProfileHealth().filter((profile) => existsSync53(profile.home)).map((profile) => {
44386
+ return hermesProfileHealth().filter((profile) => existsSync54(profile.home)).map((profile) => {
44194
44387
  const label = "hermes/" + profile.name;
44388
+ if (profile.configUnreadable) {
44389
+ return [label, `UNHEALTHY — ${profile.settingsPath} does not parse; failproofai leaves it untouched until it is fixed`];
44390
+ }
44195
44391
  if (profile.cronUnchecked) {
44196
44392
  return [
44197
44393
  label,
@@ -44201,7 +44397,9 @@ function hermesProfileStatusRows() {
44201
44397
  const problems = [];
44202
44398
  if (!profile.pluginInstalled)
44203
44399
  problems.push("plugin files missing or incomplete");
44204
- if (!profile.pluginEnabled)
44400
+ if (profile.pluginDisabled)
44401
+ problems.push("plugin disabled (listed in plugins.disabled)");
44402
+ else if (!profile.pluginEnabled)
44205
44403
  problems.push("plugin not enabled");
44206
44404
  if (profile.legacyShellHookPresent)
44207
44405
  problems.push("legacy shell hook also present");
@@ -44213,20 +44411,29 @@ function hermesProfileStatusRows() {
44213
44411
  ];
44214
44412
  });
44215
44413
  }
44216
- var HERMES_PLUGIN_ID2 = "failproofai", HERMES_PLUGIN_MARKER2 = ".failproofai-managed", HERMES_PLUGIN_FILES2, HERMES_PLUGIN_SOURCE_DIR2 = "hermes-plugin", ANTIGRAVITY_TOOL_EVENTS2;
44414
+ var UnreadableAgentConfigError2, HERMES_PLUGIN_ID2 = "failproofai", HERMES_PLUGIN_MARKER2 = ".failproofai-managed", HERMES_PLUGIN_FILES2, HERMES_PLUGIN_SOURCE_DIR2 = "hermes-plugin", ANTIGRAVITY_TOOL_EVENTS2;
44217
44415
  var init_integrations2 = __esm(() => {
44218
44416
  init_dist();
44417
+ init_safe_config_write();
44219
44418
  init_hermes_profiles();
44220
44419
  init_openclaw_profiles();
44221
44420
  init_types();
44421
+ UnreadableAgentConfigError2 = class UnreadableAgentConfigError2 extends Error {
44422
+ path;
44423
+ constructor(path, reason) {
44424
+ super(`Refusing to modify ${path}: ${reason}. ` + `failproofai never rewrites a config it could not parse — fix or move the file, then retry.`);
44425
+ this.path = path;
44426
+ this.name = "UnreadableAgentConfigError";
44427
+ }
44428
+ };
44222
44429
  HERMES_PLUGIN_FILES2 = ["plugin.yaml", "__init__.py", "client.py", "ledger.py"];
44223
44430
  ANTIGRAVITY_TOOL_EVENTS2 = new Set(["PreToolUse", "PostToolUse"]);
44224
44431
  });
44225
44432
 
44226
44433
  // scripts/launch.ts
44227
44434
  import { spawn as spawn3 } from "child_process";
44228
- import { realpathSync as realpathSync8, existsSync as existsSync54 } from "node:fs";
44229
- import { resolve as resolve40, dirname as dirname30 } from "node:path";
44435
+ import { realpathSync as realpathSync9, existsSync as existsSync55 } from "node:fs";
44436
+ import { resolve as resolve40, dirname as dirname31 } from "node:path";
44230
44437
  import { fileURLToPath as fileURLToPath4 } from "node:url";
44231
44438
  import { createInterface as createInterface2 } from "node:readline";
44232
44439
  function launch2(mode) {
@@ -44250,9 +44457,9 @@ function launch2(mode) {
44250
44457
  process.env.PORT = port;
44251
44458
  process.env.HOSTNAME = bindHost;
44252
44459
  cmd = "node";
44253
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve40(dirname30(realpathSync8(fileURLToPath4(import.meta.url))), "..");
44460
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve40(dirname31(realpathSync9(fileURLToPath4(import.meta.url))), "..");
44254
44461
  const serverJsPath = resolve40(packageRoot, ".next/standalone/server.js");
44255
- if (!existsSync54(serverJsPath)) {
44462
+ if (!existsSync55(serverJsPath)) {
44256
44463
  let shadowMessage = null;
44257
44464
  try {
44258
44465
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -44348,18 +44555,18 @@ var init_cli_error2 = __esm(() => {
44348
44555
  });
44349
44556
 
44350
44557
  // bin/failproofai.mjs
44351
- import { realpathSync as realpathSync9 } from "fs";
44352
- import { dirname as dirname31, resolve as resolve41 } from "path";
44558
+ import { realpathSync as realpathSync10 } from "fs";
44559
+ import { dirname as dirname32, resolve as resolve41 } from "path";
44353
44560
  import { fileURLToPath as fileURLToPath5 } from "url";
44354
44561
  // package.json
44355
- var version = "1.0.9-beta.0";
44562
+ var version = "1.0.9-beta.2";
44356
44563
 
44357
44564
  // bin/failproofai.mjs
44358
44565
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
44359
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve41(dirname31(realpathSync9(fileURLToPath5(import.meta.url))), "..");
44566
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve41(dirname32(realpathSync10(fileURLToPath5(import.meta.url))), "..");
44360
44567
  }
44361
44568
  if (!process.env.FAILPROOFAI_DIST_PATH) {
44362
- process.env.FAILPROOFAI_DIST_PATH = resolve41(dirname31(realpathSync9(fileURLToPath5(import.meta.url))), "..", "dist");
44569
+ process.env.FAILPROOFAI_DIST_PATH = resolve41(dirname32(realpathSync10(fileURLToPath5(import.meta.url))), "..", "dist");
44363
44570
  }
44364
44571
  var args = process.argv.slice(2);
44365
44572
  if (args[0] === "p" || args[0] === "policy")