failproofai 1.0.9-beta.0 → 1.0.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) 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]__0tmz862._.js → [root-of-the-server]__03m2iw6._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__04usis8._.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__056wjo4._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0n0xg95._.js +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0rwtwpm._.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__12e7nhs._.js → [root-of-the-server]__1-bm5zf._.js} +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__11mayhe._.js +2 -2
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__15578wp._.js +2 -2
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1m_svbe._.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 → _11ilmst._.js} +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/_1gb0ifp._.js +3 -3
  89. package/.next/standalone/.next/server/chunks/ssr/{_0n0lja6._.js → _1jatlmf._.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/{2qsrrrl2maqsb.js → 08ckontevw-0w.js} +1 -1
  106. package/.next/standalone/.next/static/chunks/{42m0f2hh8vfb1.js → 0pefjgvu4x-sx.js} +1 -1
  107. package/.next/standalone/.next/static/chunks/{0snylg3y1i47a.js → 1-d48e9k-7e1a.js} +1 -1
  108. package/.next/standalone/.next/static/chunks/{03001k9jy-kst.js → 1r74hmr1wm_sd.js} +1 -1
  109. package/.next/standalone/.next/static/chunks/{0qejem4-zt-hy.js → 1uec0n0lcx5h1.js} +1 -1
  110. package/.next/standalone/.next/static/chunks/21-pqc3-l9ak2.js +6 -0
  111. package/.next/standalone/.next/static/chunks/{1h0if8ky362as.js → 21qlo00jis4w-.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/{3rq7fjj9we0v3.js → 2n00c3zqyloy9.js} +1 -1
  113. package/.next/standalone/.next/static/chunks/{0247hc9ath5t-.js → 3tv107_for_n7.js} +1 -1
  114. package/.next/standalone/.next/static/chunks/{06k7gsfnb7jkh.js → 3vp54x0dyrrm6.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 +911 -719
  134. package/dist/worker.mjs +4 -1
  135. package/package.json +11 -11
  136. package/src/hooks/integrations.ts +128 -18
  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/3ns-egfh8i8i5.js +0 -6
  141. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → ozuWoyIwOTqeUUjKqOKiH}/_buildManifest.js +0 -0
  142. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → ozuWoyIwOTqeUUjKqOKiH}/_clientMiddlewareManifest.js +0 -0
  143. /package/.next/standalone/.next/static/{z1C0kJVF0NCtWn5R88hW3 → ozuWoyIwOTqeUUjKqOKiH}/_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.1", 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.1",
159
+ "@failproofai/failproofaid-linux-arm64": "1.0.9-beta.1",
160
+ "@failproofai/failproofaid-darwin-x64": "1.0.9-beta.1",
161
+ "@failproofai/failproofaid-darwin-arm64": "1.0.9-beta.1"
162
162
  },
163
163
  failproofaidBinaries: {
164
- "linux-x64": "044b6619007227b8aa1fc1095b8c61a17bd90e11da53183ac1f5adecdcae6839",
165
- "linux-arm64": "479450d7d15c52a59bd1a8cf4c7086be9210e8d31ad4f98d99b123f571e944bd",
166
- "darwin-x64": "11562912ff726195bfb966ed24a774ffea38d01acc3edc1f9bfa3ea9c298977f",
167
- "darwin-arm64": "5bbaee1ec89d2d8032b7f16e502fb96891fbc6aa2ee6c861f43a64a0a60e61ba"
164
+ "linux-x64": "a0db1ad28bc0584bb4554b1dc60b55353fad9d982354880f9cc1e1ee567e5d36",
165
+ "linux-arm64": "b8d2797db8d93ce0deec86707093dd22ecd2d3fe2b137944938f4851d31718f1",
166
+ "darwin-x64": "94dc7ea33121c884736eadafc8281b0b752824b5c7fbe1726745bd1fa2b2a577",
167
+ "darwin-arm64": "8da18bbede18b8c112e8c46b6f0de798e84445c163a91a80edeef6d9e21da8ad"
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;
12747
+ try {
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) {
12655
12761
  try {
12656
- return existsSync9(path) ? $parseDocument(readFileSync5(path, "utf8")) : $parseDocument("");
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,10 +13242,12 @@ function removeLegacyHermesHooks(doc) {
13122
13242
  return removed;
13123
13243
  }
13124
13244
  function hermesConfigState(settingsPath) {
13125
- if (!existsSync9(settingsPath)) {
13245
+ if (!existsSync10(settingsPath)) {
13126
13246
  return { pluginEnabled: false, legacyShellHookPresent: false };
13127
13247
  }
13128
- const doc = readYamlDoc(settingsPath);
13248
+ const doc = inspectYamlDoc(settingsPath);
13249
+ if (!doc)
13250
+ return { pluginEnabled: false, legacyShellHookPresent: false, unreadable: true };
13129
13251
  const js = doc.toJS() ?? {};
13130
13252
  const enabled = js.plugins?.enabled;
13131
13253
  const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook(entry)));
@@ -13153,7 +13275,7 @@ async function migrateHermesProfiles(opts) {
13153
13275
  const results = [];
13154
13276
  let daemonOk;
13155
13277
  for (const profile of listHermesProfiles()) {
13156
- if (!existsSync9(profile.home))
13278
+ if (!existsSync10(profile.home))
13157
13279
  continue;
13158
13280
  const settingsPath = resolve8(profile.home, "config.yaml");
13159
13281
  const pluginPath = hermesPluginPathForSettings(settingsPath);
@@ -13162,6 +13284,22 @@ async function migrateHermesProfiles(opts) {
13162
13284
  const ours = plugin.kind === "link" || plugin.kind === "copy";
13163
13285
  const base = { name: profile.name, home: profile.home };
13164
13286
  const legacy = config.legacyShellHookPresent;
13287
+ if (config.unreadable) {
13288
+ let raw = "";
13289
+ try {
13290
+ raw = readFileSync5(settingsPath, "utf8");
13291
+ } catch {
13292
+ raw = "";
13293
+ }
13294
+ const mentionsUs = ours || raw.includes(FAILPROOFAI_HOOK_MARKER) || /failproofai/.test(raw);
13295
+ results.push(mentionsUs ? {
13296
+ ...base,
13297
+ status: "failed",
13298
+ detail: `${settingsPath} does not parse as YAML; left untouched`,
13299
+ legacyShellHooksRemain: /--hook\s+\S+\s+--cli\s+hermes|__failproofai_hook__/.test(raw)
13300
+ } : { ...base, status: "untouched", detail: "no failproofai integration", legacyShellHooksRemain: false });
13301
+ continue;
13302
+ }
13165
13303
  if (!legacy && !ours && !config.pluginEnabled) {
13166
13304
  results.push({ ...base, status: "untouched", detail: "no failproofai integration", legacyShellHooksRemain: false });
13167
13305
  continue;
@@ -13179,7 +13317,7 @@ async function migrateHermesProfiles(opts) {
13179
13317
  });
13180
13318
  continue;
13181
13319
  }
13182
- if (existsSync9(settingsPath)) {
13320
+ if (existsSync10(settingsPath)) {
13183
13321
  const errors = $parseDocument(readFileSync5(settingsPath, "utf8")).errors;
13184
13322
  if (errors.length > 0) {
13185
13323
  results.push({
@@ -13258,12 +13396,21 @@ function listInstallableIds() {
13258
13396
  function detectInstalledClis() {
13259
13397
  return INTEGRATION_TYPES.filter((id) => INTEGRATIONS[id]?.detectInstalled());
13260
13398
  }
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;
13399
+ 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
13400
  var init_integrations = __esm(() => {
13263
13401
  init_dist();
13402
+ init_safe_config_write();
13264
13403
  init_hermes_profiles();
13265
13404
  init_openclaw_profiles();
13266
13405
  init_types();
13406
+ UnreadableAgentConfigError = class UnreadableAgentConfigError extends Error {
13407
+ path;
13408
+ constructor(path, reason) {
13409
+ super(`Refusing to modify ${path}: ${reason}. ` + `failproofai never rewrites a config it could not parse — fix or move the file, then retry.`);
13410
+ this.path = path;
13411
+ this.name = "UnreadableAgentConfigError";
13412
+ }
13413
+ };
13267
13414
  claudeCode = {
13268
13415
  id: "claude",
13269
13416
  displayName: "Claude Code",
@@ -13373,7 +13520,7 @@ var init_integrations = __esm(() => {
13373
13520
  },
13374
13521
  hooksInstalledInSettings(scope, cwd) {
13375
13522
  const settingsPath = this.getSettingsPath(scope, cwd);
13376
- if (!existsSync9(settingsPath))
13523
+ if (!existsSync10(settingsPath))
13377
13524
  return false;
13378
13525
  try {
13379
13526
  const settings = this.readSettings(settingsPath);
@@ -13489,7 +13636,7 @@ var init_integrations = __esm(() => {
13489
13636
  },
13490
13637
  hooksInstalledInSettings(scope, cwd) {
13491
13638
  const settingsPath = this.getSettingsPath(scope, cwd);
13492
- if (!existsSync9(settingsPath))
13639
+ if (!existsSync10(settingsPath))
13493
13640
  return false;
13494
13641
  try {
13495
13642
  const settings = this.readSettings(settingsPath);
@@ -13603,7 +13750,7 @@ var init_integrations = __esm(() => {
13603
13750
  },
13604
13751
  hooksInstalledInSettings(scope, cwd) {
13605
13752
  const settingsPath = this.getSettingsPath(scope, cwd);
13606
- if (!existsSync9(settingsPath))
13753
+ if (!existsSync10(settingsPath))
13607
13754
  return false;
13608
13755
  try {
13609
13756
  const settings = this.readSettings(settingsPath);
@@ -13706,7 +13853,7 @@ var init_integrations = __esm(() => {
13706
13853
  },
13707
13854
  hooksInstalledInSettings(scope, cwd) {
13708
13855
  const settingsPath = this.getSettingsPath(scope, cwd);
13709
- if (!existsSync9(settingsPath))
13856
+ if (!existsSync10(settingsPath))
13710
13857
  return false;
13711
13858
  try {
13712
13859
  const settings = this.readSettings(settingsPath);
@@ -13766,8 +13913,8 @@ var init_integrations = __esm(() => {
13766
13913
  const effectiveScope = scope ?? "project";
13767
13914
  const settingsPath = effectiveScope === "user" ? resolve8(homedir6(), ".config", "opencode", "opencode.json") : resolve8(process.cwd(), ".opencode", "opencode.json");
13768
13915
  const pluginPath = opencodePluginFilePath(settingsPath);
13769
- mkdirSync4(dirname5(pluginPath), { recursive: true });
13770
- writeFileSync3(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope), "utf8");
13916
+ mkdirSync5(dirname6(pluginPath), { recursive: true });
13917
+ writeConfigFileAtomic(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope));
13771
13918
  if (!Array.isArray(s.plugin))
13772
13919
  s.plugin = [];
13773
13920
  const desired = effectiveScope === "user" ? `file://${pluginPath}` : OPENCODE_PLUGIN_REL_PATH;
@@ -13790,7 +13937,7 @@ var init_integrations = __esm(() => {
13790
13937
  }
13791
13938
  this.writeSettings(settingsPath, settings);
13792
13939
  const pluginPath = opencodePluginFilePath(settingsPath);
13793
- if (existsSync9(pluginPath)) {
13940
+ if (existsSync10(pluginPath)) {
13794
13941
  try {
13795
13942
  const content = readFileSync5(pluginPath, "utf8");
13796
13943
  if (content.includes(FAILPROOFAI_HOOK_MARKER)) {
@@ -13804,7 +13951,7 @@ var init_integrations = __esm(() => {
13804
13951
  },
13805
13952
  hooksInstalledInSettings(scope, cwd) {
13806
13953
  const settingsPath = this.getSettingsPath(scope, cwd);
13807
- if (!existsSync9(settingsPath))
13954
+ if (!existsSync10(settingsPath))
13808
13955
  return false;
13809
13956
  try {
13810
13957
  const settings = this.readSettings(settingsPath);
@@ -13814,7 +13961,7 @@ var init_integrations = __esm(() => {
13814
13961
  if (!hasEntry)
13815
13962
  return false;
13816
13963
  const pluginPath = opencodePluginFilePath(settingsPath);
13817
- if (!existsSync9(pluginPath))
13964
+ if (!existsSync10(pluginPath))
13818
13965
  return false;
13819
13966
  const content = readFileSync5(pluginPath, "utf8");
13820
13967
  return content.includes(FAILPROOFAI_HOOK_MARKER);
@@ -13881,7 +14028,7 @@ var init_integrations = __esm(() => {
13881
14028
  }
13882
14029
  },
13883
14030
  removeHooksFromFile(settingsPath) {
13884
- if (!existsSync9(settingsPath))
14031
+ if (!existsSync10(settingsPath))
13885
14032
  return 0;
13886
14033
  const settings = this.readSettings(settingsPath);
13887
14034
  if (!Array.isArray(settings.packages))
@@ -13896,7 +14043,7 @@ var init_integrations = __esm(() => {
13896
14043
  },
13897
14044
  hooksInstalledInSettings(scope, cwd) {
13898
14045
  const settingsPath = this.getSettingsPath(scope, cwd);
13899
- if (!existsSync9(settingsPath))
14046
+ if (!existsSync10(settingsPath))
13900
14047
  return false;
13901
14048
  try {
13902
14049
  const settings = this.readSettings(settingsPath);
@@ -14037,7 +14184,7 @@ var init_integrations = __esm(() => {
14037
14184
  hooks.allowConversationAccess = true;
14038
14185
  },
14039
14186
  removeHooksFromFile(settingsPath) {
14040
- if (!existsSync9(settingsPath))
14187
+ if (!existsSync10(settingsPath))
14041
14188
  return 0;
14042
14189
  const settings = this.readSettings(settingsPath);
14043
14190
  const plugins = settings.plugins;
@@ -14067,7 +14214,7 @@ var init_integrations = __esm(() => {
14067
14214
  hooksInstalledInSettings(scope, cwd) {
14068
14215
  const settingsPaths = settingsPathsFor(this, scope, cwd);
14069
14216
  return settingsPaths.length > 0 && settingsPaths.every((settingsPath) => {
14070
- if (!existsSync9(settingsPath))
14217
+ if (!existsSync10(settingsPath))
14071
14218
  return false;
14072
14219
  try {
14073
14220
  const settings = this.readSettings(settingsPath);
@@ -14165,7 +14312,7 @@ var init_integrations = __esm(() => {
14165
14312
  },
14166
14313
  hooksInstalledInSettings(scope, cwd) {
14167
14314
  const settingsPath = this.getSettingsPath(scope, cwd);
14168
- if (!existsSync9(settingsPath))
14315
+ if (!existsSync10(settingsPath))
14169
14316
  return false;
14170
14317
  try {
14171
14318
  const settings = this.readSettings(settingsPath);
@@ -14271,7 +14418,7 @@ var init_integrations = __esm(() => {
14271
14418
  },
14272
14419
  hooksInstalledInSettings(scope, cwd) {
14273
14420
  const settingsPath = this.getSettingsPath(scope, cwd);
14274
- if (!existsSync9(settingsPath))
14421
+ if (!existsSync10(settingsPath))
14275
14422
  return false;
14276
14423
  try {
14277
14424
  const settings = this.readSettings(settingsPath);
@@ -14410,7 +14557,7 @@ var init_integrations = __esm(() => {
14410
14557
  },
14411
14558
  hooksInstalledInSettings(scope, cwd) {
14412
14559
  const settingsPath = this.getSettingsPath(scope, cwd);
14413
- if (!existsSync9(settingsPath))
14560
+ if (!existsSync10(settingsPath))
14414
14561
  return false;
14415
14562
  try {
14416
14563
  const settings = this.readSettings(settingsPath);
@@ -14516,7 +14663,7 @@ var init_integrations = __esm(() => {
14516
14663
  },
14517
14664
  hooksInstalledInSettings(scope, cwd) {
14518
14665
  const settingsPath = this.getSettingsPath(scope, cwd);
14519
- if (!existsSync9(settingsPath))
14666
+ if (!existsSync10(settingsPath))
14520
14667
  return false;
14521
14668
  try {
14522
14669
  const settings = this.readSettings(settingsPath);
@@ -16877,7 +17024,7 @@ var init_custom_hooks_registry = __esm(() => {
16877
17024
  // src/hooks/loader-utils.ts
16878
17025
  import { readFile as readFile2, writeFile as writeFile2, unlink, access, mkdir, lstat } from "fs/promises";
16879
17026
  import { tmpdir } from "os";
16880
- import { resolve as resolve9, dirname as dirname6, relative as relative2, join as join5 } from "path";
17027
+ import { resolve as resolve9, dirname as dirname7, relative as relative2, join as join6 } from "path";
16881
17028
  import { pathToFileURL } from "url";
16882
17029
  import { createHash as createHash3 } from "crypto";
16883
17030
  function isTmpArtifact(name) {
@@ -16918,7 +17065,7 @@ async function findDistIndex() {
16918
17065
  return candidate;
16919
17066
  }
16920
17067
  const candidates = [
16921
- resolve9(dirname6(process.execPath), "..", "assets", "dist", "index.js"),
17068
+ resolve9(dirname7(process.execPath), "..", "assets", "dist", "index.js"),
16922
17069
  resolve9(process.cwd(), "dist", "index.js"),
16923
17070
  resolve9(process.cwd(), "node_modules", "failproofai", "dist", "index.js")
16924
17071
  ];
@@ -16938,7 +17085,7 @@ async function resolveLocalImport(fromDir, specifier) {
16938
17085
  return null;
16939
17086
  }
16940
17087
  async function writeShim(dir, name, code, exclusive) {
16941
- const shimPath = join5(dir, name);
17088
+ const shimPath = join6(dir, name);
16942
17089
  await writeFile2(shimPath, code, {
16943
17090
  encoding: "utf-8",
16944
17091
  mode: 384,
@@ -17009,7 +17156,7 @@ async function rewriteFileTree(entryPath, distUrl, distIndex, tmpSuffix = TMP_SU
17009
17156
  if (distIndex) {
17010
17157
  code = code.replace(/require\s*\(\s*(['"])(?:claudeye|failproofai)\1\s*\)/g, `require('${distIndex.replace(/\\/g, "\\\\")}')`);
17011
17158
  }
17012
- const dir = dirname6(filePath);
17159
+ const dir = dirname7(filePath);
17013
17160
  const rewrites = new Map;
17014
17161
  for (const re of [LOCAL_IMPORT_RE, LOCAL_REQUIRE_RE]) {
17015
17162
  const freshRe = new RegExp(re.source, re.flags);
@@ -17230,14 +17377,14 @@ var init_telemetry_id2 = __esm(() => {
17230
17377
  });
17231
17378
 
17232
17379
  // src/hooks/custom-hooks-loader.ts
17233
- import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename4 } from "node:path";
17380
+ import { resolve as resolve10, isAbsolute as isAbsolute2, basename as basename5 } from "node:path";
17234
17381
  import { randomUUID } from "crypto";
17235
- import { existsSync as existsSync10, readdirSync as readdirSync3 } from "node:fs";
17382
+ import { existsSync as existsSync11, readdirSync as readdirSync3 } from "node:fs";
17236
17383
  import { readFile as readFile3 } from "node:fs/promises";
17237
17384
  import { pathToFileURL as pathToFileURL2 } from "node:url";
17238
17385
  import { createHash as createHash4 } from "node:crypto";
17239
17386
  function discoverPolicyFiles(dir) {
17240
- if (!existsSync10(dir))
17387
+ if (!existsSync11(dir))
17241
17388
  return [];
17242
17389
  try {
17243
17390
  const entries = readdirSync3(dir, { withFileTypes: true });
@@ -17247,7 +17394,7 @@ function discoverPolicyFiles(dir) {
17247
17394
  }
17248
17395
  }
17249
17396
  function findSkippedPolicyFiles(dir) {
17250
- if (!existsSync10(dir))
17397
+ if (!existsSync11(dir))
17251
17398
  return [];
17252
17399
  try {
17253
17400
  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 +17447,7 @@ async function loadSingleFile(absPath, opts) {
17300
17447
  const ignored = getSemanticRegistrations().slice(semanticBefore).map((d) => d?.name);
17301
17448
  if (opts?.outsidePack && ignored.length > 0 && !warnedSemanticOutsidePack.has(absPath)) {
17302
17449
  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`);
17450
+ 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
17451
  }
17305
17452
  if (policyModuleCache.size >= POLICY_MODULE_CACHE_MAX_ENTRIES)
17306
17453
  policyModuleCache.clear();
@@ -17316,7 +17463,7 @@ async function loadSingleFile(absPath, opts) {
17316
17463
  error_type: errorType,
17317
17464
  is_convention: !!opts?.conventionScope,
17318
17465
  convention_scope: opts?.conventionScope ?? null,
17319
- file_basename: basename4(absPath)
17466
+ file_basename: basename5(absPath)
17320
17467
  });
17321
17468
  if (opts?.strict)
17322
17469
  throw new Error(`Failed to load custom hooks from ${absPath}: ${msg}`);
@@ -17340,7 +17487,7 @@ async function loadCustomHooks(customPoliciesPath, opts) {
17340
17487
  if (!customPoliciesPath)
17341
17488
  return [];
17342
17489
  const absPath = isAbsolute2(customPoliciesPath) ? customPoliciesPath : resolve10(opts?.sessionCwd ?? process.cwd(), customPoliciesPath);
17343
- if (!existsSync10(absPath)) {
17490
+ if (!existsSync11(absPath)) {
17344
17491
  if (opts?.strict)
17345
17492
  throw new Error(`Custom hooks file not found: ${absPath}`);
17346
17493
  hookLogWarn(`customPoliciesPath not found: ${absPath}`);
@@ -17455,7 +17602,7 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17455
17602
  const absPath = resolve10(projectRoot, customPoliciesPath);
17456
17603
  const cloudManaged = cloudManagedByPath.get(absPath);
17457
17604
  const pack = packByPath.get(absPath);
17458
- if (existsSync10(absPath)) {
17605
+ if (existsSync11(absPath)) {
17459
17606
  if (!loadedPaths.has(absPath)) {
17460
17607
  loadedPaths.add(absPath);
17461
17608
  const hooksBefore = getCustomHooks().length;
@@ -17505,12 +17652,12 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17505
17652
  await loadSingleFile(file, { conventionScope: projectScope, outsidePack: true });
17506
17653
  const newHooks = getCustomHooks().slice(hooksBefore);
17507
17654
  for (const hook of newHooks) {
17508
- hook.__policyId = conventionPolicyId(projectScope, basename4(file), hook.name);
17655
+ hook.__policyId = conventionPolicyId(projectScope, basename5(file), hook.name);
17509
17656
  }
17510
17657
  if (newHooks.length > 0) {
17511
17658
  conventionSources.push({
17512
17659
  scope: projectScope,
17513
- file: basename4(file),
17660
+ file: basename5(file),
17514
17661
  hookNames: newHooks.map((h) => h.name)
17515
17662
  });
17516
17663
  }
@@ -17527,12 +17674,12 @@ async function loadAllCustomHooks(customPoliciesPaths, opts) {
17527
17674
  await loadSingleFile(file, { conventionScope: "user", outsidePack: true });
17528
17675
  const newHooks = getCustomHooks().slice(hooksBefore);
17529
17676
  for (const hook of newHooks) {
17530
- hook.__policyId = conventionPolicyId("user", basename4(file), hook.name);
17677
+ hook.__policyId = conventionPolicyId("user", basename5(file), hook.name);
17531
17678
  }
17532
17679
  if (newHooks.length > 0) {
17533
17680
  conventionSources.push({
17534
17681
  scope: "user",
17535
- file: basename4(file),
17682
+ file: basename5(file),
17536
17683
  hookNames: newHooks.map((h) => h.name)
17537
17684
  });
17538
17685
  }
@@ -18533,8 +18680,8 @@ var init_pack_cli = __esm(() => {
18533
18680
 
18534
18681
  // src/hooks/pack-store.ts
18535
18682
  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";
18683
+ import { existsSync as existsSync12, mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync4 } from "node:fs";
18684
+ import { dirname as dirname8, resolve as resolve11 } from "node:path";
18538
18685
  function baseUrl() {
18539
18686
  return (process.env.FAILPROOFAI_PACK_BASE_URL || DEFAULT_BASE_URL).replace(/\/+$/, "");
18540
18687
  }
@@ -18705,11 +18852,11 @@ function sha256(bytes) {
18705
18852
  function writeAtomic(target, bytes) {
18706
18853
  const tempPath = `${target}.${process.pid}.tmp`;
18707
18854
  try {
18708
- mkdirSync5(dirname7(target), { recursive: true });
18855
+ mkdirSync6(dirname8(target), { recursive: true });
18709
18856
  writeFileSync4(tempPath, bytes);
18710
- renameSync3(tempPath, target);
18857
+ renameSync4(tempPath, target);
18711
18858
  } catch (err) {
18712
- rmSync3(tempPath, { force: true });
18859
+ rmSync4(tempPath, { force: true });
18713
18860
  throw err;
18714
18861
  }
18715
18862
  }
@@ -18935,7 +19082,7 @@ async function addPack(source, opts) {
18935
19082
  const root = packsRoot();
18936
19083
  const artifactRel = `artifacts/${fetched.artifactDigest}.mjs`;
18937
19084
  const artifactAbs = resolve11(root, artifactRel);
18938
- if (!existsSync11(artifactAbs))
19085
+ if (!existsSync12(artifactAbs))
18939
19086
  writeAtomic(artifactAbs, fetched.artifact);
18940
19087
  try {
18941
19088
  await verifyArtifactRegisters(artifactAbs, available);
@@ -18984,7 +19131,7 @@ async function addPack(source, opts) {
18984
19131
  }
18985
19132
  function setPackPolicyEnabled(packId, name, on) {
18986
19133
  const manifestPath = resolve11(packsRoot(), "installed.json");
18987
- if (!existsSync11(manifestPath))
19134
+ if (!existsSync12(manifestPath))
18988
19135
  return { ok: false, reason: "no packs are installed" };
18989
19136
  let raw;
18990
19137
  try {
@@ -19018,7 +19165,7 @@ function bareId(value) {
19018
19165
  }
19019
19166
  function removePack(id) {
19020
19167
  const manifestPath = resolve11(packsRoot(), "installed.json");
19021
- if (!existsSync11(manifestPath))
19168
+ if (!existsSync12(manifestPath))
19022
19169
  return null;
19023
19170
  let raw;
19024
19171
  try {
@@ -19043,7 +19190,7 @@ function removePack(id) {
19043
19190
  function upsertInstalled(record, carryAbsorbedSelection = true) {
19044
19191
  const manifestPath = resolve11(packsRoot(), "installed.json");
19045
19192
  let packs = [];
19046
- if (existsSync11(manifestPath)) {
19193
+ if (existsSync12(manifestPath)) {
19047
19194
  try {
19048
19195
  const raw = JSON.parse(readFileSync6(manifestPath, "utf8"));
19049
19196
  if (Array.isArray(raw.packs))
@@ -20041,22 +20188,22 @@ import {
20041
20188
  readFileSync as readFileSync7,
20042
20189
  writeFileSync as writeFileSync5,
20043
20190
  appendFileSync as appendFileSync2,
20044
- renameSync as renameSync4,
20191
+ renameSync as renameSync5,
20045
20192
  readdirSync as readdirSync4,
20046
- mkdirSync as mkdirSync6,
20047
- existsSync as existsSync12,
20048
- statSync as statSync5,
20193
+ mkdirSync as mkdirSync7,
20194
+ existsSync as existsSync13,
20195
+ statSync as statSync6,
20049
20196
  unlinkSync as unlinkSync2
20050
20197
  } from "node:fs";
20051
- import { join as join6 } from "node:path";
20198
+ import { join as join7 } from "node:path";
20052
20199
  function ensureDir() {
20053
- if (!existsSync12(storeDirValue())) {
20054
- mkdirSync6(storeDirValue(), { recursive: true });
20200
+ if (!existsSync13(storeDirValue())) {
20201
+ mkdirSync7(storeDirValue(), { recursive: true });
20055
20202
  }
20056
20203
  }
20057
20204
  function acquireLock() {
20058
20205
  ensureDir();
20059
- const lockPath = join6(storeDirValue(), LOCK_FILE);
20206
+ const lockPath = join7(storeDirValue(), LOCK_FILE);
20060
20207
  const deadline = Date.now() + LOCK_STALE_MS;
20061
20208
  while (Date.now() < deadline) {
20062
20209
  try {
@@ -20066,7 +20213,7 @@ function acquireLock() {
20066
20213
  if (e.code !== "EEXIST")
20067
20214
  return;
20068
20215
  try {
20069
- const s = statSync5(lockPath);
20216
+ const s = statSync6(lockPath);
20070
20217
  if (Date.now() - s.mtimeMs > LOCK_STALE_MS) {
20071
20218
  writeFileSync5(lockPath, String(process.pid), "utf-8");
20072
20219
  return;
@@ -20077,7 +20224,7 @@ function acquireLock() {
20077
20224
  }
20078
20225
  function releaseLock() {
20079
20226
  try {
20080
- unlinkSync2(join6(storeDirValue(), LOCK_FILE));
20227
+ unlinkSync2(join7(storeDirValue(), LOCK_FILE));
20081
20228
  } catch {}
20082
20229
  }
20083
20230
  function persistHookActivity(input) {
@@ -20085,8 +20232,8 @@ function persistHookActivity(input) {
20085
20232
  ensureDir();
20086
20233
  acquireLock();
20087
20234
  try {
20088
- const currentPath = join6(storeDirValue(), CURRENT_FILE);
20089
- const countPath = join6(storeDirValue(), COUNT_FILE);
20235
+ const currentPath = join7(storeDirValue(), CURRENT_FILE);
20236
+ const countPath = join7(storeDirValue(), COUNT_FILE);
20090
20237
  const lineCount = readCount(countPath);
20091
20238
  if (lineCount >= PAGE_SIZE) {
20092
20239
  try {
@@ -20106,8 +20253,8 @@ function persistHookActivity(input) {
20106
20253
  }
20107
20254
  function rotate(currentPath, countPath) {
20108
20255
  const archiveName = `page-${Date.now()}-${rotateSeq++}.jsonl`;
20109
- const archivePath = join6(storeDirValue(), archiveName);
20110
- renameSync4(currentPath, archivePath);
20256
+ const archivePath = join7(storeDirValue(), archiveName);
20257
+ renameSync5(currentPath, archivePath);
20111
20258
  writeCount(countPath, 0);
20112
20259
  }
20113
20260
  function readCount(countPath) {
@@ -20132,7 +20279,7 @@ function readFileSafe(filePath) {
20132
20279
  }
20133
20280
  function readStoredStats() {
20134
20281
  try {
20135
- return JSON.parse(readFileSync7(join6(storeDirValue(), STATS_FILE), "utf-8"));
20282
+ return JSON.parse(readFileSync7(join7(storeDirValue(), STATS_FILE), "utf-8"));
20136
20283
  } catch {
20137
20284
  return { totalEvents: 0, denyCount: 0, policyMap: {} };
20138
20285
  }
@@ -20150,10 +20297,10 @@ function foldEntry(s, entry) {
20150
20297
  }
20151
20298
  }
20152
20299
  function writeStoredStats(s) {
20153
- const tmpPath = join6(storeDirValue(), `stats.json.${process.pid}.tmp`);
20300
+ const tmpPath = join7(storeDirValue(), `stats.json.${process.pid}.tmp`);
20154
20301
  try {
20155
20302
  writeFileSync5(tmpPath, JSON.stringify(s), "utf-8");
20156
- renameSync4(tmpPath, join6(storeDirValue(), STATS_FILE));
20303
+ renameSync5(tmpPath, join7(storeDirValue(), STATS_FILE));
20157
20304
  return true;
20158
20305
  } catch {
20159
20306
  try {
@@ -20173,8 +20320,8 @@ function rebuildHookActivityStats() {
20173
20320
  const s = { totalEvents: 0, denyCount: 0, policyMap: {} };
20174
20321
  let sawAny = false;
20175
20322
  for (const file of files) {
20176
- const path = join6(storeDirValue(), file);
20177
- if (!existsSync12(path))
20323
+ const path = join7(storeDirValue(), file);
20324
+ if (!existsSync13(path))
20178
20325
  continue;
20179
20326
  sawAny = true;
20180
20327
  for (const entry of readJsonlFile(path))
@@ -20186,12 +20333,12 @@ function rebuildHookActivityStats() {
20186
20333
  }
20187
20334
  function getAllHookActivityEntries() {
20188
20335
  ensureDir();
20189
- const currentPath = join6(storeDirValue(), CURRENT_FILE);
20336
+ const currentPath = join7(storeDirValue(), CURRENT_FILE);
20190
20337
  const currentEntries = readJsonlFile(currentPath).reverse();
20191
20338
  const archives = getArchiveFiles();
20192
20339
  const archiveEntries = [];
20193
20340
  for (const file of archives) {
20194
- const entries = readJsonlFile(join6(storeDirValue(), file));
20341
+ const entries = readJsonlFile(join7(storeDirValue(), file));
20195
20342
  archiveEntries.push(...entries.reverse());
20196
20343
  }
20197
20344
  return [...currentEntries, ...archiveEntries];
@@ -20202,7 +20349,7 @@ function getHookActivityEntriesSince(sinceMs) {
20202
20349
  const inWindow = (e) => typeof e.timestamp === "number" && e.timestamp >= sinceMs;
20203
20350
  const listedBefore = new Set(getArchiveFiles());
20204
20351
  sinceReadProbe?.("before-current");
20205
- const current = readJsonlFile(join6(dir, CURRENT_FILE));
20352
+ const current = readJsonlFile(join7(dir, CURRENT_FILE));
20206
20353
  sinceReadProbe?.("after-current");
20207
20354
  const readFromCurrent = new Map;
20208
20355
  for (const e of current) {
@@ -20222,7 +20369,7 @@ function getHookActivityEntriesSince(sinceMs) {
20222
20369
  const rotatedAt = parseInt(file.slice(5, -6).split("-")[0], 10);
20223
20370
  if (Number.isFinite(rotatedAt) && rotatedAt < sinceMs - ROTATION_CLOCK_SLACK_MS)
20224
20371
  break;
20225
- let entries = readJsonlFile(join6(dir, file));
20372
+ let entries = readJsonlFile(join7(dir, file));
20226
20373
  if (!listedBefore.has(file))
20227
20374
  entries = entries.filter(notReadYet);
20228
20375
  out.push(...entries.reverse().filter(inWindow));
@@ -20278,8 +20425,8 @@ var init_hook_activity_store = __esm(() => {
20278
20425
  });
20279
20426
 
20280
20427
  // 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";
20428
+ import { existsSync as existsSync14, readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
20429
+ import { join as join8 } from "node:path";
20283
20430
  function parseParkedName(name) {
20284
20431
  const poison = name.endsWith(POISON_SUFFIX);
20285
20432
  const withoutPoison = poison ? name.slice(0, -POISON_SUFFIX.length) : name;
@@ -20307,7 +20454,7 @@ function parseParkedName(name) {
20307
20454
  }
20308
20455
  function deliveryHealth(home, now = Date.now()) {
20309
20456
  const dir = failedDir(home);
20310
- if (!existsSync13(dir))
20457
+ if (!existsSync14(dir))
20311
20458
  return EMPTY;
20312
20459
  let entries;
20313
20460
  try {
@@ -20332,7 +20479,7 @@ function deliveryHealth(home, now = Date.now()) {
20332
20479
  credentialRejected += 1;
20333
20480
  }
20334
20481
  try {
20335
- const mtime = statSync6(join7(dir, name)).mtimeMs;
20482
+ const mtime = statSync7(join8(dir, name)).mtimeMs;
20336
20483
  if (oldestMtime === undefined || mtime < oldestMtime)
20337
20484
  oldestMtime = mtime;
20338
20485
  } catch {}
@@ -20427,9 +20574,9 @@ function runtimeCache(fn, revalidateSeconds, options) {
20427
20574
 
20428
20575
  // lib/paths.ts
20429
20576
  import { homedir as homedir7 } from "os";
20430
- import { join as join8 } from "path";
20577
+ import { join as join9 } from "path";
20431
20578
  function getDefaultClaudeProjectsPath() {
20432
- return join8(homedir7(), ".claude", "projects");
20579
+ return join9(homedir7(), ".claude", "projects");
20433
20580
  }
20434
20581
  function decodeFolderName(name) {
20435
20582
  if (/^[A-Za-z]--/.test(name)) {
@@ -20520,7 +20667,7 @@ __export(exports_codex_projects, {
20520
20667
  });
20521
20668
  import { open, readdir } from "node:fs/promises";
20522
20669
  import { homedir as homedir8 } from "node:os";
20523
- import { join as join9 } from "node:path";
20670
+ import { join as join10 } from "node:path";
20524
20671
  async function safeReaddir(dir) {
20525
20672
  try {
20526
20673
  return await readdir(dir, { withFileTypes: true });
@@ -20568,7 +20715,7 @@ async function listJsonlFiles(dir) {
20568
20715
  const entries = await safeReaddir(dir);
20569
20716
  if (!entries)
20570
20717
  return [];
20571
- return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join9(dir, e.name));
20718
+ return entries.filter((e) => e.isFile() && e.name.endsWith(".jsonl")).map((e) => join10(dir, e.name));
20572
20719
  }
20573
20720
  async function scanCodexSessions() {
20574
20721
  const yearDirs = await safeReaddir(CODEX_SESSIONS_ROOT);
@@ -20578,19 +20725,19 @@ async function scanCodexSessions() {
20578
20725
  for (const y of yearDirs) {
20579
20726
  if (!y.isDirectory())
20580
20727
  continue;
20581
- const monthDirs = await safeReaddir(join9(CODEX_SESSIONS_ROOT, y.name));
20728
+ const monthDirs = await safeReaddir(join10(CODEX_SESSIONS_ROOT, y.name));
20582
20729
  if (!monthDirs)
20583
20730
  continue;
20584
20731
  for (const m of monthDirs) {
20585
20732
  if (!m.isDirectory())
20586
20733
  continue;
20587
- const dayDirs = await safeReaddir(join9(CODEX_SESSIONS_ROOT, y.name, m.name));
20734
+ const dayDirs = await safeReaddir(join10(CODEX_SESSIONS_ROOT, y.name, m.name));
20588
20735
  if (!dayDirs)
20589
20736
  continue;
20590
20737
  for (const d of dayDirs) {
20591
20738
  if (!d.isDirectory())
20592
20739
  continue;
20593
- const dayPath = join9(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
20740
+ const dayPath = join10(CODEX_SESSIONS_ROOT, y.name, m.name, d.name);
20594
20741
  filePaths.push(...await listJsonlFiles(dayPath));
20595
20742
  }
20596
20743
  }
@@ -20698,7 +20845,7 @@ var CODEX_SESSIONS_ROOT, SESSION_ID_RE, FIRST_LINE_CHUNK_BYTES, cachedScan, getC
20698
20845
  var init_codex_projects = __esm(() => {
20699
20846
  init_paths();
20700
20847
  init_logger();
20701
- CODEX_SESSIONS_ROOT = join9(homedir8(), ".codex", "sessions");
20848
+ CODEX_SESSIONS_ROOT = join10(homedir8(), ".codex", "sessions");
20702
20849
  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
20850
  FIRST_LINE_CHUNK_BYTES = 256 * 1024;
20704
20851
  cachedScan = runtimeCache(scanCodexSessions, 30);
@@ -20715,9 +20862,9 @@ __export(exports_copilot_projects, {
20715
20862
  });
20716
20863
  import { readdir as readdir2, readFile as readFile4, stat } from "node:fs/promises";
20717
20864
  import { homedir as homedir9 } from "node:os";
20718
- import { join as join10 } from "node:path";
20865
+ import { join as join11 } from "node:path";
20719
20866
  function getCopilotSessionStateRoot() {
20720
- return join10(process.env.COPILOT_HOME || join10(homedir9(), ".copilot"), "session-state");
20867
+ return join11(process.env.COPILOT_HOME || join11(homedir9(), ".copilot"), "session-state");
20721
20868
  }
20722
20869
  async function safeReaddir2(dir) {
20723
20870
  try {
@@ -20746,8 +20893,8 @@ async function scanCopilotSessions() {
20746
20893
  return [];
20747
20894
  const candidates = entries.filter((e) => e.isDirectory()).map((e) => ({
20748
20895
  sessionId: e.name,
20749
- workspacePath: join10(root, e.name, "workspace.yaml"),
20750
- eventsPath: join10(root, e.name, "events.jsonl")
20896
+ workspacePath: join11(root, e.name, "workspace.yaml"),
20897
+ eventsPath: join11(root, e.name, "events.jsonl")
20751
20898
  }));
20752
20899
  const settled = await batchAll(candidates.map((c) => async () => {
20753
20900
  let workspaceText;
@@ -20859,9 +21006,9 @@ __export(exports_cursor_projects, {
20859
21006
  });
20860
21007
  import { readdir as readdir3, readFile as readFile5, stat as stat2 } from "node:fs/promises";
20861
21008
  import { homedir as homedir10 } from "node:os";
20862
- import { join as join11 } from "node:path";
21009
+ import { join as join12 } from "node:path";
20863
21010
  function getCursorHome() {
20864
- return process.env.CURSOR_HOME || join11(homedir10(), ".cursor");
21011
+ return process.env.CURSOR_HOME || join12(homedir10(), ".cursor");
20865
21012
  }
20866
21013
  async function safeReaddir3(dir) {
20867
21014
  try {
@@ -20893,7 +21040,7 @@ function parseCwdFromMetaText(text) {
20893
21040
  }
20894
21041
  async function findFirstUsableMeta(dir, candidates) {
20895
21042
  for (const name of candidates) {
20896
- const path = join11(dir, name);
21043
+ const path = join12(dir, name);
20897
21044
  if (await statMtime2(path) === null)
20898
21045
  continue;
20899
21046
  let text;
@@ -20910,7 +21057,7 @@ async function findFirstUsableMeta(dir, candidates) {
20910
21057
  }
20911
21058
  async function findFirstExistingPath(dir, candidates) {
20912
21059
  for (const name of candidates) {
20913
- const path = join11(dir, name);
21060
+ const path = join12(dir, name);
20914
21061
  if (await statMtime2(path) !== null)
20915
21062
  return path;
20916
21063
  }
@@ -20920,7 +21067,7 @@ async function scanCursorSessions() {
20920
21067
  const home = getCursorHome();
20921
21068
  const newCandidates = [];
20922
21069
  const legacyCandidates = [];
20923
- const projectsRoot = join11(home, NEW_PROJECTS_DIR);
21070
+ const projectsRoot = join12(home, NEW_PROJECTS_DIR);
20924
21071
  const projectEntries = await safeReaddir3(projectsRoot);
20925
21072
  if (projectEntries) {
20926
21073
  for (const proj of projectEntries) {
@@ -20928,7 +21075,7 @@ async function scanCursorSessions() {
20928
21075
  continue;
20929
21076
  const decoded = decodeFolderName(proj.name);
20930
21077
  const cwd = decoded.startsWith("/") || /^[A-Za-z]:\//.test(decoded) ? decoded : `/${decoded}`;
20931
- const transcriptsRoot = join11(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
21078
+ const transcriptsRoot = join12(projectsRoot, proj.name, NEW_AGENT_TRANSCRIPTS_DIR);
20932
21079
  const sessionDirs = await safeReaddir3(transcriptsRoot);
20933
21080
  if (!sessionDirs)
20934
21081
  continue;
@@ -20937,28 +21084,28 @@ async function scanCursorSessions() {
20937
21084
  continue;
20938
21085
  newCandidates.push({
20939
21086
  sessionId: sd.name,
20940
- dir: join11(transcriptsRoot, sd.name),
21087
+ dir: join12(transcriptsRoot, sd.name),
20941
21088
  cwd
20942
21089
  });
20943
21090
  }
20944
21091
  }
20945
21092
  }
20946
21093
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES) {
20947
- const root = join11(home, sub);
21094
+ const root = join12(home, sub);
20948
21095
  const entries = await safeReaddir3(root);
20949
21096
  if (!entries)
20950
21097
  continue;
20951
21098
  for (const e of entries) {
20952
21099
  if (!e.isDirectory())
20953
21100
  continue;
20954
- legacyCandidates.push({ sessionId: e.name, dir: join11(root, e.name) });
21101
+ legacyCandidates.push({ sessionId: e.name, dir: join12(root, e.name) });
20955
21102
  }
20956
21103
  }
20957
21104
  if (newCandidates.length === 0 && legacyCandidates.length === 0)
20958
21105
  return [];
20959
21106
  const settled = await batchAll([
20960
21107
  ...newCandidates.map((c) => async () => {
20961
- const transcriptPath = join11(c.dir, `${c.sessionId}.jsonl`);
21108
+ const transcriptPath = join12(c.dir, `${c.sessionId}.jsonl`);
20962
21109
  const transcriptMtime = await statMtime2(transcriptPath);
20963
21110
  if (!transcriptMtime)
20964
21111
  return null;
@@ -21072,7 +21219,7 @@ var init_cursor_projects = __esm(() => {
21072
21219
  });
21073
21220
 
21074
21221
  // lib/sqlite-reader.ts
21075
- import { existsSync as existsSync14, readFileSync as readFileSync8, statSync as statSync7 } from "node:fs";
21222
+ import { existsSync as existsSync15, readFileSync as readFileSync8, statSync as statSync8 } from "node:fs";
21076
21223
  import initSqlJs from "sql.js/dist/sql-asm.js";
21077
21224
  async function tryNodeSqlite(dbPath) {
21078
21225
  try {
@@ -21097,7 +21244,7 @@ function loadSqlJs() {
21097
21244
  return sqlPromise;
21098
21245
  }
21099
21246
  function fileVersion(path) {
21100
- const stat = statSync7(path);
21247
+ const stat = statSync8(path);
21101
21248
  return { size: stat.size, mtimeMs: stat.mtimeMs, ctimeMs: stat.ctimeMs };
21102
21249
  }
21103
21250
  function sameVersion(a, b) {
@@ -21230,7 +21377,7 @@ async function trySqlJs(dbPath) {
21230
21377
  }
21231
21378
  }
21232
21379
  async function openSqliteReadonly(dbPath, options = {}) {
21233
- if (!existsSync14(dbPath))
21380
+ if (!existsSync15(dbPath))
21234
21381
  return null;
21235
21382
  if (!options.forcePortable) {
21236
21383
  const native = await tryNodeSqlite(dbPath);
@@ -21244,12 +21391,12 @@ var init_sqlite_reader = () => {};
21244
21391
 
21245
21392
  // lib/opencode-db.ts
21246
21393
  import { homedir as homedir11 } from "node:os";
21247
- import { join as join12 } from "node:path";
21394
+ import { join as join13 } from "node:path";
21248
21395
  function opencodeDbPath() {
21249
21396
  if (process.env.OPENCODE_DB_PATH)
21250
21397
  return process.env.OPENCODE_DB_PATH;
21251
- const home = process.env.OPENCODE_HOME ?? join12(homedir11(), ".local", "share", "opencode");
21252
- return join12(home, "opencode.db");
21398
+ const home = process.env.OPENCODE_HOME ?? join13(homedir11(), ".local", "share", "opencode");
21399
+ return join13(home, "opencode.db");
21253
21400
  }
21254
21401
  async function withOpenCodeDb(fn) {
21255
21402
  const db = await openSqliteReadonly(opencodeDbPath());
@@ -21410,9 +21557,9 @@ __export(exports_pi_projects, {
21410
21557
  });
21411
21558
  import { readdir as readdir4, readFile as readFile6, stat as stat3 } from "node:fs/promises";
21412
21559
  import { homedir as homedir12 } from "node:os";
21413
- import { join as join13 } from "node:path";
21560
+ import { join as join14 } from "node:path";
21414
21561
  function getPiSessionsRoot() {
21415
- return process.env.PI_SESSIONS_DIR || join13(homedir12(), ".pi", "agent", "sessions");
21562
+ return process.env.PI_SESSIONS_DIR || join14(homedir12(), ".pi", "agent", "sessions");
21416
21563
  }
21417
21564
  async function safeReaddir4(dir) {
21418
21565
  try {
@@ -21460,7 +21607,7 @@ async function scanPiSessions() {
21460
21607
  for (const cwdDir of cwdDirs) {
21461
21608
  if (!cwdDir.isDirectory())
21462
21609
  continue;
21463
- const cwdPath = join13(root, cwdDir.name);
21610
+ const cwdPath = join14(root, cwdDir.name);
21464
21611
  const sessionFiles = await safeReaddir4(cwdPath);
21465
21612
  if (!sessionFiles)
21466
21613
  continue;
@@ -21470,7 +21617,7 @@ async function scanPiSessions() {
21470
21617
  const m = SESSION_FILE_RE.exec(f.name);
21471
21618
  if (!m)
21472
21619
  continue;
21473
- candidates.push({ sessionId: m[1], filePath: join13(cwdPath, f.name) });
21620
+ candidates.push({ sessionId: m[1], filePath: join14(cwdPath, f.name) });
21474
21621
  }
21475
21622
  }
21476
21623
  if (candidates.length === 0)
@@ -21592,14 +21739,14 @@ function formatDuration(ms) {
21592
21739
  }
21593
21740
 
21594
21741
  // lib/hermes-sessions.ts
21595
- import { join as join14 } from "node:path";
21742
+ import { join as join15 } from "node:path";
21596
21743
  function hermesDbPaths() {
21597
21744
  const override = process.env.HERMES_DB_PATH;
21598
21745
  if (override)
21599
21746
  return [{ profile: HERMES_DEFAULT_PROFILE, dbPath: override }];
21600
21747
  return listHermesProfiles().map((p) => ({
21601
21748
  profile: p.name,
21602
- dbPath: join14(p.home, "state.db")
21749
+ dbPath: join15(p.home, "state.db")
21603
21750
  }));
21604
21751
  }
21605
21752
  function epochToMs(value) {
@@ -21891,8 +22038,8 @@ var init_hermes_projects = __esm(() => {
21891
22038
  });
21892
22039
 
21893
22040
  // lib/openclaw-db.ts
21894
- import { existsSync as existsSync15 } from "node:fs";
21895
- import { join as join15 } from "node:path";
22041
+ import { existsSync as existsSync16 } from "node:fs";
22042
+ import { join as join16 } from "node:path";
21896
22043
  function str(value) {
21897
22044
  return typeof value === "string" && value.length > 0 ? value : undefined;
21898
22045
  }
@@ -21910,8 +22057,8 @@ function syntheticPath(agentId, sessionId) {
21910
22057
  function listOpenClawDatabases(home, agentIds) {
21911
22058
  const out = [];
21912
22059
  for (const agentId of agentIds) {
21913
- const dbPath = join15(home, "agents", agentId, "agent", DB_NAME);
21914
- if (existsSync15(dbPath))
22060
+ const dbPath = join16(home, "agents", agentId, "agent", DB_NAME);
22061
+ if (existsSync16(dbPath))
21915
22062
  out.push({ agentId, dbPath });
21916
22063
  }
21917
22064
  return out;
@@ -22048,11 +22195,11 @@ var init_openclaw_db = __esm(() => {
22048
22195
 
22049
22196
  // lib/openclaw-sessions.ts
22050
22197
  import { readFile as readFile7 } from "node:fs/promises";
22051
- import { readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
22198
+ import { readdirSync as readdirSync6, statSync as statSync9 } from "node:fs";
22052
22199
  import { homedir as homedir13 } from "node:os";
22053
- import { join as join16 } from "node:path";
22200
+ import { join as join17 } from "node:path";
22054
22201
  function openclawHome() {
22055
- return process.env.OPENCLAW_STATE_DIR || process.env.OPENCLAW_HOME || join16(homedir13(), ".openclaw");
22202
+ return process.env.OPENCLAW_STATE_DIR || process.env.OPENCLAW_HOME || join17(homedir13(), ".openclaw");
22056
22203
  }
22057
22204
  function isPlainObject3(v) {
22058
22205
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -22171,13 +22318,13 @@ function openclawLinesToLogEntries(lines, source = "session") {
22171
22318
  }
22172
22319
  function listOpenClawAgents() {
22173
22320
  try {
22174
- return readdirSync6(join16(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
22321
+ return readdirSync6(join17(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
22175
22322
  } catch {
22176
22323
  return [];
22177
22324
  }
22178
22325
  }
22179
22326
  function listOpenClawTranscripts() {
22180
- const agentsDir = join16(openclawHome(), "agents");
22327
+ const agentsDir = join17(openclawHome(), "agents");
22181
22328
  const out = [];
22182
22329
  let agentIds;
22183
22330
  try {
@@ -22186,7 +22333,7 @@ function listOpenClawTranscripts() {
22186
22333
  return out;
22187
22334
  }
22188
22335
  for (const agentId of agentIds) {
22189
- const sessionsDir = join16(agentsDir, agentId, "sessions");
22336
+ const sessionsDir = join17(agentsDir, agentId, "sessions");
22190
22337
  let files;
22191
22338
  try {
22192
22339
  files = readdirSync6(sessionsDir);
@@ -22199,9 +22346,9 @@ function listOpenClawTranscripts() {
22199
22346
  const sessionId = file.slice(0, -".jsonl".length);
22200
22347
  if (!OPENCLAW_SESSION_ID_RE.test(sessionId))
22201
22348
  continue;
22202
- const transcriptPath = join16(sessionsDir, file);
22349
+ const transcriptPath = join17(sessionsDir, file);
22203
22350
  try {
22204
- const st = statSync8(transcriptPath);
22351
+ const st = statSync9(transcriptPath);
22205
22352
  out.push({
22206
22353
  agentId,
22207
22354
  sessionId,
@@ -22279,13 +22426,13 @@ __export(exports_openclaw_projects, {
22279
22426
  openClawProjectPath: () => openClawProjectPath
22280
22427
  });
22281
22428
  import { readFileSync as readFileSync9 } from "node:fs";
22282
- import { join as join17 } from "node:path";
22429
+ import { join as join18 } from "node:path";
22283
22430
  function str2(v) {
22284
22431
  return typeof v === "string" && v.length > 0 ? v : undefined;
22285
22432
  }
22286
22433
  function readSessionsIndex(agentId) {
22287
22434
  const out = new Map;
22288
- const indexPath = join17(openclawHome(), "agents", agentId, "sessions", "sessions.json");
22435
+ const indexPath = join18(openclawHome(), "agents", agentId, "sessions", "sessions.json");
22289
22436
  let raw;
22290
22437
  try {
22291
22438
  raw = JSON.parse(readFileSync9(indexPath, "utf-8"));
@@ -22446,14 +22593,14 @@ var init_openclaw_projects = __esm(() => {
22446
22593
 
22447
22594
  // lib/factory-sessions.ts
22448
22595
  import { readFile as readFile8 } from "node:fs/promises";
22449
- import { readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
22596
+ import { readdirSync as readdirSync7, statSync as statSync10 } from "node:fs";
22450
22597
  import { homedir as homedir14 } from "node:os";
22451
- import { join as join18 } from "node:path";
22598
+ import { join as join19 } from "node:path";
22452
22599
  function factoryHome() {
22453
- return process.env.FACTORY_HOME || join18(homedir14(), ".factory");
22600
+ return process.env.FACTORY_HOME || join19(homedir14(), ".factory");
22454
22601
  }
22455
22602
  function factorySessionsRoot() {
22456
- return join18(factoryHome(), "sessions");
22603
+ return join19(factoryHome(), "sessions");
22457
22604
  }
22458
22605
  function isPlainObject4(v) {
22459
22606
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -22599,7 +22746,7 @@ function listFactoryTranscripts() {
22599
22746
  for (const dir of projectDirs) {
22600
22747
  const projectName = dir.name;
22601
22748
  const cwd = decodeFolderName(projectName);
22602
- const projectPath = join18(root, projectName);
22749
+ const projectPath = join19(root, projectName);
22603
22750
  let files;
22604
22751
  try {
22605
22752
  files = readdirSync7(projectPath);
@@ -22612,9 +22759,9 @@ function listFactoryTranscripts() {
22612
22759
  const sessionId = file.slice(0, -".jsonl".length);
22613
22760
  if (!FACTORY_SESSION_ID_RE.test(sessionId))
22614
22761
  continue;
22615
- const transcriptPath = join18(projectPath, file);
22762
+ const transcriptPath = join19(projectPath, file);
22616
22763
  try {
22617
- const st = statSync9(transcriptPath);
22764
+ const st = statSync10(transcriptPath);
22618
22765
  out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
22619
22766
  } catch {}
22620
22767
  }
@@ -22736,12 +22883,12 @@ var init_factory_projects = __esm(() => {
22736
22883
 
22737
22884
  // lib/devin-sessions.ts
22738
22885
  import { homedir as homedir15 } from "node:os";
22739
- import { join as join19 } from "node:path";
22886
+ import { join as join20 } from "node:path";
22740
22887
  function devinHome() {
22741
- return process.env.DEVIN_HOME || join19(homedir15(), ".local", "share", "devin");
22888
+ return process.env.DEVIN_HOME || join20(homedir15(), ".local", "share", "devin");
22742
22889
  }
22743
22890
  function devinDbPath() {
22744
- return process.env.DEVIN_DB_PATH || join19(devinHome(), "cli", "sessions.db");
22891
+ return process.env.DEVIN_DB_PATH || join20(devinHome(), "cli", "sessions.db");
22745
22892
  }
22746
22893
  function devinEpochToMs(value) {
22747
22894
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -23034,17 +23181,17 @@ var init_devin_projects = __esm(() => {
23034
23181
 
23035
23182
  // lib/antigravity-sessions.ts
23036
23183
  import { readFile as readFile9 } from "node:fs/promises";
23037
- import { readdirSync as readdirSync8, statSync as statSync10 } from "node:fs";
23184
+ import { readdirSync as readdirSync8, statSync as statSync11 } from "node:fs";
23038
23185
  import { homedir as homedir16 } from "node:os";
23039
- import { join as join20 } from "node:path";
23186
+ import { join as join21 } from "node:path";
23040
23187
  function antigravityHome() {
23041
- return process.env.ANTIGRAVITY_HOME || join20(homedir16(), ".gemini", "antigravity-cli");
23188
+ return process.env.ANTIGRAVITY_HOME || join21(homedir16(), ".gemini", "antigravity-cli");
23042
23189
  }
23043
23190
  function antigravityBrainRoot() {
23044
- return join20(antigravityHome(), "brain");
23191
+ return join21(antigravityHome(), "brain");
23045
23192
  }
23046
23193
  function antigravityTranscriptRelPath() {
23047
- return join20(".system_generated", "logs", "transcript_full.jsonl");
23194
+ return join21(".system_generated", "logs", "transcript_full.jsonl");
23048
23195
  }
23049
23196
  function isPlainObject6(v) {
23050
23197
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -23167,9 +23314,9 @@ function listAntigravityTranscripts() {
23167
23314
  const conversationId = dir.name;
23168
23315
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
23169
23316
  continue;
23170
- const transcriptPath = join20(root, conversationId, rel);
23317
+ const transcriptPath = join21(root, conversationId, rel);
23171
23318
  try {
23172
- const st = statSync10(transcriptPath);
23319
+ const st = statSync11(transcriptPath);
23173
23320
  if (!st.isFile())
23174
23321
  continue;
23175
23322
  out.push({ conversationId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -23180,9 +23327,9 @@ function listAntigravityTranscripts() {
23180
23327
  function findAntigravityTranscript(conversationId) {
23181
23328
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
23182
23329
  return null;
23183
- const transcriptPath = join20(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
23330
+ const transcriptPath = join21(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
23184
23331
  try {
23185
- if (statSync10(transcriptPath).isFile())
23332
+ if (statSync11(transcriptPath).isFile())
23186
23333
  return transcriptPath;
23187
23334
  } catch {}
23188
23335
  return null;
@@ -23216,9 +23363,9 @@ __export(exports_antigravity_projects, {
23216
23363
  getAntigravityIndex: () => getAntigravityIndex,
23217
23364
  getAntigravityProjects: () => getAntigravityProjects
23218
23365
  });
23219
- import { join as join21 } from "node:path";
23366
+ import { join as join22 } from "node:path";
23220
23367
  function antigravitySummariesDbPath() {
23221
- return join21(antigravityHome(), "conversation_summaries.db");
23368
+ return join22(antigravityHome(), "conversation_summaries.db");
23222
23369
  }
23223
23370
  function parseWorkspaceCwd(raw) {
23224
23371
  if (!raw)
@@ -23362,15 +23509,15 @@ var init_antigravity_projects = __esm(() => {
23362
23509
 
23363
23510
  // lib/goose-sessions.ts
23364
23511
  import { homedir as homedir17 } from "node:os";
23365
- import { join as join22 } from "node:path";
23512
+ import { join as join23 } from "node:path";
23366
23513
  function gooseHome() {
23367
23514
  if (process.env.GOOSE_HOME)
23368
23515
  return process.env.GOOSE_HOME;
23369
23516
  const xdg = process.env.XDG_DATA_HOME;
23370
- return join22(xdg && xdg.length > 0 ? xdg : join22(homedir17(), ".local", "share"), "goose");
23517
+ return join23(xdg && xdg.length > 0 ? xdg : join23(homedir17(), ".local", "share"), "goose");
23371
23518
  }
23372
23519
  function gooseDbPath() {
23373
- return process.env.GOOSE_DB_PATH || join22(gooseHome(), "sessions", "sessions.db");
23520
+ return process.env.GOOSE_DB_PATH || join23(gooseHome(), "sessions", "sessions.db");
23374
23521
  }
23375
23522
  function gooseTimestampToMs(value) {
23376
23523
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -23634,7 +23781,7 @@ var init_goose_projects = __esm(() => {
23634
23781
 
23635
23782
  // lib/projects.ts
23636
23783
  import { readdir as readdir5, stat as stat4 } from "node:fs/promises";
23637
- import { join as join23, resolve as resolve12, sep } from "node:path";
23784
+ import { join as join24, resolve as resolve12, sep } from "node:path";
23638
23785
  async function getMtime(path, label) {
23639
23786
  try {
23640
23787
  return (await stat4(path)).mtime;
@@ -23660,7 +23807,7 @@ async function getClaudeProjectFolders() {
23660
23807
  if (!entries)
23661
23808
  return [];
23662
23809
  const settled = await batchAll(entries.filter((entry) => entry.isDirectory()).map((entry) => async () => {
23663
- const folderPath = join23(projectsPath, entry.name);
23810
+ const folderPath = join24(projectsPath, entry.name);
23664
23811
  const mtime = await getMtime(folderPath, entry.name);
23665
23812
  return {
23666
23813
  name: entry.name,
@@ -23787,7 +23934,7 @@ function resolveProjectPath(projectName) {
23787
23934
  if (/^[/\\]/.test(projectName))
23788
23935
  throw new RangeError("Absolute project name");
23789
23936
  const projectsPath = resolve12(getClaudeProjectsPath());
23790
- const candidate = resolve12(join23(projectsPath, projectName));
23937
+ const candidate = resolve12(join24(projectsPath, projectName));
23791
23938
  if (!candidate.startsWith(projectsPath + sep)) {
23792
23939
  throw new RangeError("Project path escapes root");
23793
23940
  }
@@ -23805,7 +23952,7 @@ async function getSessionFiles(projectPath) {
23805
23952
  return [];
23806
23953
  const jsonlEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl") && extractSessionId2(entry.name));
23807
23954
  const settled = await batchAll(jsonlEntries.map((entry) => async () => {
23808
- const filePath = join23(projectPath, entry.name);
23955
+ const filePath = join24(projectPath, entry.name);
23809
23956
  const mtime = await getMtime(filePath, entry.name);
23810
23957
  return {
23811
23958
  name: entry.name,
@@ -23834,13 +23981,13 @@ var init_projects = __esm(() => {
23834
23981
 
23835
23982
  // lib/resolve-subagent-path.ts
23836
23983
  import { access as access2 } from "fs/promises";
23837
- import { join as join24, relative as relative3 } from "path";
23984
+ import { join as join25, relative as relative3 } from "path";
23838
23985
  async function resolveSubagentPath(projectsPath, projectName, sessionId, agentId) {
23839
23986
  const fileName = `agent-${agentId}.jsonl`;
23840
23987
  const candidatePaths = [
23841
- join24(projectsPath, projectName, fileName),
23842
- join24(projectsPath, projectName, sessionId, fileName),
23843
- join24(projectsPath, projectName, sessionId, "subagents", fileName)
23988
+ join25(projectsPath, projectName, fileName),
23989
+ join25(projectsPath, projectName, sessionId, fileName),
23990
+ join25(projectsPath, projectName, sessionId, "subagents", fileName)
23844
23991
  ];
23845
23992
  for (const candidatePath of candidatePaths) {
23846
23993
  if (relative3(projectsPath, candidatePath).startsWith("..")) {
@@ -23862,7 +24009,7 @@ var init_resolve_subagent_path = () => {};
23862
24009
 
23863
24010
  // lib/log-entries.ts
23864
24011
  import { readFile as readFile10 } from "fs/promises";
23865
- import { join as join25 } from "path";
24012
+ import { join as join26 } from "path";
23866
24013
  function formatTimestamp(date) {
23867
24014
  const base = formatDate(date);
23868
24015
  const ms = date.getMilliseconds().toString().padStart(3, "0");
@@ -24060,7 +24207,7 @@ async function parseLogContent(fileContent, source = "session") {
24060
24207
  async function parseSessionLog(projectName, sessionId) {
24061
24208
  const projectDir = resolveProjectPath(projectName);
24062
24209
  const projectsPath = getClaudeProjectsPath();
24063
- const filePath = join25(projectDir, `${sessionId}.jsonl`);
24210
+ const filePath = join26(projectDir, `${sessionId}.jsonl`);
24064
24211
  const fileContent = await readFile10(filePath, "utf-8");
24065
24212
  const { entries: sessionEntries, rawLines: sessionRawLines, subagentIds } = await parseFileContent(fileContent, "session");
24066
24213
  if (subagentIds.length === 0) {
@@ -24097,13 +24244,13 @@ var init_log_entries = __esm(() => {
24097
24244
  });
24098
24245
 
24099
24246
  // 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";
24247
+ import { readFileSync as readFileSync10, readdirSync as readdirSync9, existsSync as existsSync17, writeFileSync as writeFileSync6, mkdirSync as mkdirSync8, statSync as statSync12 } from "node:fs";
24101
24248
  import { readFile as readFile11 } from "node:fs/promises";
24102
- import { dirname as dirname8, join as join26 } from "node:path";
24249
+ import { dirname as dirname9, join as join27 } from "node:path";
24103
24250
  import { homedir as homedir18 } from "node:os";
24104
24251
  function readCache() {
24105
24252
  try {
24106
- if (!existsSync16(CACHE_PATH))
24253
+ if (!existsSync17(CACHE_PATH))
24107
24254
  return {};
24108
24255
  return JSON.parse(readFileSync10(CACHE_PATH, "utf-8"));
24109
24256
  } catch {
@@ -24112,7 +24259,7 @@ function readCache() {
24112
24259
  }
24113
24260
  function writeCacheEntry(sessionId, path) {
24114
24261
  try {
24115
- mkdirSync7(dirname8(CACHE_PATH), { recursive: true });
24262
+ mkdirSync8(dirname9(CACHE_PATH), { recursive: true });
24116
24263
  const cache = readCache();
24117
24264
  cache[sessionId] = path;
24118
24265
  writeFileSync6(CACHE_PATH, JSON.stringify(cache), "utf-8");
@@ -24122,7 +24269,7 @@ function dirSearch(dir, sessionId) {
24122
24269
  try {
24123
24270
  for (const f of readdirSync9(dir, { withFileTypes: true })) {
24124
24271
  if (f.isFile() && f.name.includes(sessionId) && f.name.endsWith(".jsonl")) {
24125
- return join26(dir, f.name);
24272
+ return join27(dir, f.name);
24126
24273
  }
24127
24274
  }
24128
24275
  } catch {}
@@ -24131,16 +24278,16 @@ function dirSearch(dir, sessionId) {
24131
24278
  function findCodexTranscript(sessionId) {
24132
24279
  const cache = readCache();
24133
24280
  const cached = cache[sessionId];
24134
- if (cached && existsSync16(cached))
24281
+ if (cached && existsSync17(cached))
24135
24282
  return cached;
24136
- const root = join26(homedir18(), ".codex", "sessions");
24283
+ const root = join27(homedir18(), ".codex", "sessions");
24137
24284
  const today = new Date;
24138
24285
  const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
24139
24286
  const datedDirs = [today, yesterday].map((d) => {
24140
24287
  const y = String(d.getUTCFullYear());
24141
24288
  const m = String(d.getUTCMonth() + 1).padStart(2, "0");
24142
24289
  const day = String(d.getUTCDate()).padStart(2, "0");
24143
- return join26(root, y, m, day);
24290
+ return join27(root, y, m, day);
24144
24291
  });
24145
24292
  for (const dir of datedDirs) {
24146
24293
  const hit = dirSearch(dir, sessionId);
@@ -24153,13 +24300,13 @@ function findCodexTranscript(sessionId) {
24153
24300
  for (const y of readdirSync9(root, { withFileTypes: true })) {
24154
24301
  if (!y.isDirectory())
24155
24302
  continue;
24156
- for (const m of readdirSync9(join26(root, y.name), { withFileTypes: true })) {
24303
+ for (const m of readdirSync9(join27(root, y.name), { withFileTypes: true })) {
24157
24304
  if (!m.isDirectory())
24158
24305
  continue;
24159
- for (const d of readdirSync9(join26(root, y.name, m.name), { withFileTypes: true })) {
24306
+ for (const d of readdirSync9(join27(root, y.name, m.name), { withFileTypes: true })) {
24160
24307
  if (!d.isDirectory())
24161
24308
  continue;
24162
- const hit = dirSearch(join26(root, y.name, m.name, d.name), sessionId);
24309
+ const hit = dirSearch(join27(root, y.name, m.name, d.name), sessionId);
24163
24310
  if (hit) {
24164
24311
  writeCacheEntry(sessionId, hit);
24165
24312
  return hit;
@@ -24425,15 +24572,15 @@ var init_resolve_permission_mode = __esm(() => {
24425
24572
  });
24426
24573
 
24427
24574
  // lib/copilot-sessions.ts
24428
- import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync17, statSync as statSync12 } from "node:fs";
24575
+ import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync18, statSync as statSync13 } from "node:fs";
24429
24576
  import { readFile as readFile12 } from "node:fs/promises";
24430
- import { join as join27, resolve as resolve13, sep as sep2 } from "node:path";
24577
+ import { join as join28, resolve as resolve13, sep as sep2 } from "node:path";
24431
24578
  import { homedir as homedir19 } from "node:os";
24432
24579
  function getCopilotHome() {
24433
- return process.env.COPILOT_HOME || join27(homedir19(), ".copilot");
24580
+ return process.env.COPILOT_HOME || join28(homedir19(), ".copilot");
24434
24581
  }
24435
24582
  function getCopilotSessionStateRoot2() {
24436
- return join27(getCopilotHome(), "session-state");
24583
+ return join28(getCopilotHome(), "session-state");
24437
24584
  }
24438
24585
  function getCopilotSessionDir(sessionId) {
24439
24586
  if (!sessionId)
@@ -24448,19 +24595,19 @@ function resolveSessionFile(sessionId, filename) {
24448
24595
  const dir = getCopilotSessionDir(sessionId);
24449
24596
  if (!dir)
24450
24597
  return null;
24451
- return join27(dir, filename);
24598
+ return join28(dir, filename);
24452
24599
  }
24453
24600
  function findCopilotTranscript(sessionId) {
24454
24601
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
24455
24602
  if (!candidate)
24456
24603
  return null;
24457
- return existsSync17(candidate) ? candidate : null;
24604
+ return existsSync18(candidate) ? candidate : null;
24458
24605
  }
24459
24606
  function findCopilotWorkspace(sessionId) {
24460
24607
  const candidate = resolveSessionFile(sessionId, "workspace.yaml");
24461
24608
  if (!candidate)
24462
24609
  return null;
24463
- return existsSync17(candidate) ? candidate : null;
24610
+ return existsSync18(candidate) ? candidate : null;
24464
24611
  }
24465
24612
  function readYamlScalar(path, key) {
24466
24613
  try {
@@ -24642,12 +24789,12 @@ var init_copilot_sessions = __esm(() => {
24642
24789
  });
24643
24790
 
24644
24791
  // lib/cursor-sessions.ts
24645
- import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync18, statSync as statSync13 } from "node:fs";
24792
+ import { readFileSync as readFileSync13, readdirSync as readdirSync11, existsSync as existsSync19, statSync as statSync14 } from "node:fs";
24646
24793
  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";
24794
+ import { basename as basename6, join as join29, resolve as resolve14, sep as sep3 } from "node:path";
24648
24795
  import { homedir as homedir20 } from "node:os";
24649
24796
  function getCursorHome2() {
24650
- return process.env.CURSOR_HOME || join28(homedir20(), ".cursor");
24797
+ return process.env.CURSOR_HOME || join29(homedir20(), ".cursor");
24651
24798
  }
24652
24799
  function getCursorSessionDir(sessionId) {
24653
24800
  if (!sessionId)
@@ -24665,7 +24812,7 @@ function getCursorSessionDir(sessionId) {
24665
24812
  const transcriptRoot = resolve14(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
24666
24813
  if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
24667
24814
  continue;
24668
- if (existsSync18(candidate))
24815
+ if (existsSync19(candidate))
24669
24816
  return candidate;
24670
24817
  }
24671
24818
  for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
@@ -24673,7 +24820,7 @@ function getCursorSessionDir(sessionId) {
24673
24820
  const candidate = resolve14(root, sessionId);
24674
24821
  if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
24675
24822
  continue;
24676
- if (existsSync18(candidate))
24823
+ if (existsSync19(candidate))
24677
24824
  return candidate;
24678
24825
  }
24679
24826
  return null;
@@ -24682,12 +24829,12 @@ function findCursorTranscript(sessionId) {
24682
24829
  const dir = getCursorSessionDir(sessionId);
24683
24830
  if (!dir)
24684
24831
  return null;
24685
- const newCandidate = join28(dir, `${basename5(dir)}.jsonl`);
24686
- if (existsSync18(newCandidate))
24832
+ const newCandidate = join29(dir, `${basename6(dir)}.jsonl`);
24833
+ if (existsSync19(newCandidate))
24687
24834
  return newCandidate;
24688
24835
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
24689
- const candidate = join28(dir, name);
24690
- if (existsSync18(candidate))
24836
+ const candidate = join29(dir, name);
24837
+ if (existsSync19(candidate))
24691
24838
  return candidate;
24692
24839
  }
24693
24840
  return null;
@@ -24898,12 +25045,12 @@ var init_cursor_sessions = __esm(() => {
24898
25045
  });
24899
25046
 
24900
25047
  // lib/pi-sessions.ts
24901
- import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync19, statSync as statSync14 } from "node:fs";
25048
+ import { readFileSync as readFileSync14, readdirSync as readdirSync12, existsSync as existsSync20, statSync as statSync15 } from "node:fs";
24902
25049
  import { readFile as readFile14 } from "node:fs/promises";
24903
- import { join as join29, resolve as resolve15, sep as sep4 } from "node:path";
25050
+ import { join as join30, resolve as resolve15, sep as sep4 } from "node:path";
24904
25051
  import { homedir as homedir21 } from "node:os";
24905
25052
  function getPiSessionStateRoot() {
24906
- return process.env.PI_SESSIONS_DIR || join29(homedir21(), ".pi", "agent", "sessions");
25053
+ return process.env.PI_SESSIONS_DIR || join30(homedir21(), ".pi", "agent", "sessions");
24907
25054
  }
24908
25055
  function isSafeSessionId(sessionId) {
24909
25056
  return UUID_RE.test(sessionId);
@@ -24935,7 +25082,7 @@ function findPiTranscript(sessionId) {
24935
25082
  const candidate = resolve15(cwdPath, f);
24936
25083
  if (!candidate.startsWith(`${cwdPath}${sep4}`))
24937
25084
  continue;
24938
- if (existsSync19(candidate))
25085
+ if (existsSync20(candidate))
24939
25086
  return candidate;
24940
25087
  }
24941
25088
  }
@@ -25342,37 +25489,37 @@ var init_pack_failclosed = __esm(() => {
25342
25489
 
25343
25490
  // lib/atomic-write.ts
25344
25491
  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,
25492
+ chmodSync as chmodSync3,
25493
+ existsSync as existsSync21,
25494
+ mkdirSync as mkdirSync9,
25495
+ renameSync as renameSync6,
25496
+ rmSync as rmSync5,
25497
+ statSync as statSync16,
25351
25498
  writeFileSync as writeFileSync7
25352
25499
  } from "node:fs";
25353
- import { dirname as dirname9 } from "node:path";
25354
- import { randomBytes } from "node:crypto";
25500
+ import { dirname as dirname10 } from "node:path";
25501
+ import { randomBytes as randomBytes2 } from "node:crypto";
25355
25502
  function writeJsonAtomically(filePath, value, opts = {}) {
25356
25503
  const mode = opts.mode ?? 384;
25357
25504
  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`;
25505
+ const dir = dirname10(filePath);
25506
+ if (!existsSync21(dir))
25507
+ mkdirSync9(dir, { recursive: true, mode: dirMode });
25508
+ const tmp = `${filePath}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
25362
25509
  try {
25363
25510
  writeFileSync7(tmp, JSON.stringify(value, null, 2), { mode });
25364
25511
  try {
25365
- if ((statSync15(tmp).mode & 63) !== 0)
25366
- chmodSync2(tmp, mode);
25512
+ if ((statSync16(tmp).mode & 63) !== 0)
25513
+ chmodSync3(tmp, mode);
25367
25514
  } catch {}
25368
- renameSync5(tmp, filePath);
25515
+ renameSync6(tmp, filePath);
25369
25516
  try {
25370
- if ((statSync15(filePath).mode & 63) !== 0)
25371
- chmodSync2(filePath, mode);
25517
+ if ((statSync16(filePath).mode & 63) !== 0)
25518
+ chmodSync3(filePath, mode);
25372
25519
  } catch {}
25373
25520
  } catch (err) {
25374
25521
  try {
25375
- rmSync4(tmp, { force: true });
25522
+ rmSync5(tmp, { force: true });
25376
25523
  } catch {}
25377
25524
  throw err;
25378
25525
  }
@@ -25380,9 +25527,9 @@ function writeJsonAtomically(filePath, value, opts = {}) {
25380
25527
  var init_atomic_write = () => {};
25381
25528
 
25382
25529
  // 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";
25530
+ import { existsSync as existsSync22, mkdirSync as mkdirSync10, readdirSync as readdirSync13, readFileSync as readFileSync15, rmSync as rmSync6 } from "node:fs";
25384
25531
  import { createHash as createHash6 } from "node:crypto";
25385
- import { join as join30, resolve as resolve16 } from "node:path";
25532
+ import { join as join31, resolve as resolve16 } from "node:path";
25386
25533
  function pauseStateDir() {
25387
25534
  const override = process.env.FAILPROOFAI_STATE_DIR;
25388
25535
  if (override)
@@ -25391,7 +25538,7 @@ function pauseStateDir() {
25391
25538
  }
25392
25539
  function pauseFilePath(sessionId) {
25393
25540
  const digest = createHash6("sha256").update(sessionId).digest("hex").slice(0, 32);
25394
- return join30(pauseStateDir(), `${digest}.json`);
25541
+ return join31(pauseStateDir(), `${digest}.json`);
25395
25542
  }
25396
25543
  function parsePauseDuration(input, ceilingMs = PAUSE_CEILING_MS) {
25397
25544
  if (input === undefined || input === "")
@@ -25447,7 +25594,7 @@ function readActivePause(sessionId, now = Date.now()) {
25447
25594
  return null;
25448
25595
  try {
25449
25596
  const path = pauseFilePath(sessionId);
25450
- if (!existsSync21(path))
25597
+ if (!existsSync22(path))
25451
25598
  return null;
25452
25599
  const stored = parseStored(JSON.parse(readFileSync15(path, "utf8")));
25453
25600
  if (!stored)
@@ -25472,16 +25619,16 @@ function writePause(opts) {
25472
25619
  setBy: opts.setBy ?? "cli",
25473
25620
  ...opts.cwd ? { cwd: opts.cwd } : {}
25474
25621
  };
25475
- mkdirSync9(pauseStateDir(), { recursive: true, mode: 448 });
25622
+ mkdirSync10(pauseStateDir(), { recursive: true, mode: 448 });
25476
25623
  writeJsonAtomically(pauseFilePath(opts.sessionId), { schemaVersion: SCHEMA_VERSION, ...pause });
25477
25624
  return pause;
25478
25625
  }
25479
25626
  function clearPause(sessionId) {
25480
25627
  const path = pauseFilePath(sessionId);
25481
- if (!existsSync21(path))
25628
+ if (!existsSync22(path))
25482
25629
  return false;
25483
25630
  try {
25484
- rmSync5(path);
25631
+ rmSync6(path);
25485
25632
  return true;
25486
25633
  } catch {
25487
25634
  return false;
@@ -25489,7 +25636,7 @@ function clearPause(sessionId) {
25489
25636
  }
25490
25637
  function listActivePauses(now = Date.now()) {
25491
25638
  const dir = pauseStateDir();
25492
- if (!existsSync21(dir))
25639
+ if (!existsSync22(dir))
25493
25640
  return [];
25494
25641
  const out = [];
25495
25642
  let names;
@@ -25502,7 +25649,7 @@ function listActivePauses(now = Date.now()) {
25502
25649
  if (!name.endsWith(".json"))
25503
25650
  continue;
25504
25651
  try {
25505
- const stored = parseStored(JSON.parse(readFileSync15(join30(dir, name), "utf8")));
25652
+ const stored = parseStored(JSON.parse(readFileSync15(join31(dir, name), "utf8")));
25506
25653
  if (!stored || stored.expiresAt <= now)
25507
25654
  continue;
25508
25655
  const { schemaVersion: _ignored, ...pause } = stored;
@@ -25542,18 +25689,18 @@ var init_session_pause = __esm(() => {
25542
25689
  // src/hooks/daemon-download.ts
25543
25690
  import { createHash as createHash7 } from "node:crypto";
25544
25691
  import {
25545
- chmodSync as chmodSync3,
25546
- existsSync as existsSync22,
25547
- mkdirSync as mkdirSync10,
25692
+ chmodSync as chmodSync4,
25693
+ existsSync as existsSync23,
25694
+ mkdirSync as mkdirSync11,
25548
25695
  readdirSync as readdirSync14,
25549
25696
  readFileSync as readFileSync16,
25550
- renameSync as renameSync6,
25551
- rmSync as rmSync6,
25552
- statSync as statSync16,
25697
+ renameSync as renameSync7,
25698
+ rmSync as rmSync7,
25699
+ statSync as statSync17,
25553
25700
  writeFileSync as writeFileSync8
25554
25701
  } from "node:fs";
25555
25702
  import { createRequire as createRequire2 } from "node:module";
25556
- import { dirname as dirname10, resolve as resolve17 } from "node:path";
25703
+ import { dirname as dirname11, resolve as resolve17 } from "node:path";
25557
25704
  import { gunzipSync } from "node:zlib";
25558
25705
  function baseUrl2() {
25559
25706
  return (process.env.FAILPROOFAI_DAEMON_BASE_URL || DEFAULT_BASE_URL2).replace(/\/+$/, "");
@@ -25580,7 +25727,7 @@ function npmPlatformBinaryPath(key) {
25580
25727
  const name = platformPackageName(key);
25581
25728
  try {
25582
25729
  const requireFromRoot = createRequire2(resolve17(packageRoot, "package.json"));
25583
- const found = platformPackageBinary(dirname10(requireFromRoot.resolve(`${name}/package.json`)));
25730
+ const found = platformPackageBinary(dirname11(requireFromRoot.resolve(`${name}/package.json`)));
25584
25731
  if (found)
25585
25732
  return found;
25586
25733
  } catch {}
@@ -25595,7 +25742,7 @@ function platformPackageBinary(dir) {
25595
25742
  return null;
25596
25743
  }
25597
25744
  const candidate = resolve17(dir, "bin", "failproofaid");
25598
- return existsSync22(candidate) ? candidate : null;
25745
+ return existsSync23(candidate) ? candidate : null;
25599
25746
  }
25600
25747
  function pruneOldDaemonBinaries(keep = 2) {
25601
25748
  const removed = [];
@@ -25603,11 +25750,11 @@ function pruneOldDaemonBinaries(keep = 2) {
25603
25750
  const dir = daemonBinaryDir();
25604
25751
  const entries = readdirSync14(dir).filter((f) => f.startsWith("failproofaid-") && !f.endsWith(".tmp")).map((f) => {
25605
25752
  const full = resolve17(dir, f);
25606
- return { full, mtime: statSync16(full).mtimeMs };
25753
+ return { full, mtime: statSync17(full).mtimeMs };
25607
25754
  }).sort((a, b) => b.mtime - a.mtime);
25608
25755
  for (const stale of entries.slice(keep)) {
25609
25756
  try {
25610
- rmSync6(stale.full, { force: true });
25757
+ rmSync7(stale.full, { force: true });
25611
25758
  removed.push(stale.full);
25612
25759
  } catch {}
25613
25760
  }
@@ -25618,13 +25765,13 @@ function installBinaryBytes(binary) {
25618
25765
  const target = installedBinaryPath();
25619
25766
  const tempPath = `${target}.${process.pid}.tmp`;
25620
25767
  try {
25621
- mkdirSync10(daemonBinaryDir(), { recursive: true });
25768
+ mkdirSync11(daemonBinaryDir(), { recursive: true });
25622
25769
  writeFileSync8(tempPath, binary);
25623
- chmodSync3(tempPath, 493);
25624
- renameSync6(tempPath, target);
25770
+ chmodSync4(tempPath, 493);
25771
+ renameSync7(tempPath, target);
25625
25772
  return target;
25626
25773
  } catch (err) {
25627
- rmSync6(tempPath, { force: true });
25774
+ rmSync7(tempPath, { force: true });
25628
25775
  throw err;
25629
25776
  }
25630
25777
  }
@@ -25673,7 +25820,7 @@ function digestFor2(manifest, assetName) {
25673
25820
  }
25674
25821
  async function downloadFailproofaidBinary(key) {
25675
25822
  const target = installedBinaryPath();
25676
- if (existsSync22(target))
25823
+ if (existsSync23(target))
25677
25824
  return { path: target };
25678
25825
  if (process.env.FAILPROOFAI_NO_DOWNLOAD) {
25679
25826
  return { error: "daemon downloads are disabled (FAILPROOFAI_NO_DOWNLOAD)" };
@@ -25707,10 +25854,10 @@ var init_daemon_download = __esm(() => {
25707
25854
 
25708
25855
  // src/hooks/daemon-client.ts
25709
25856
  import { createConnection as createConnection2 } from "node:net";
25710
- import { existsSync as existsSync23 } from "node:fs";
25857
+ import { existsSync as existsSync24 } from "node:fs";
25711
25858
  function daemonSocketPresent() {
25712
25859
  try {
25713
- return existsSync23(socketPath2());
25860
+ return existsSync24(socketPath2());
25714
25861
  } catch {
25715
25862
  return false;
25716
25863
  }
@@ -25868,13 +26015,13 @@ var init_daemon_client2 = __esm(() => {
25868
26015
 
25869
26016
  // src/hooks/daemon-service.ts
25870
26017
  import {
25871
- existsSync as existsSync24,
25872
- mkdirSync as mkdirSync11,
26018
+ existsSync as existsSync25,
26019
+ mkdirSync as mkdirSync12,
25873
26020
  mkdtempSync,
25874
26021
  readFileSync as readFileSync17,
25875
26022
  writeFileSync as writeFileSync9,
25876
26023
  unlinkSync as unlinkSync3,
25877
- rmSync as rmSync7
26024
+ rmSync as rmSync8
25878
26025
  } from "node:fs";
25879
26026
  import { homedir as homedir22, tmpdir as tmpdir2, userInfo } from "node:os";
25880
26027
  import { resolve as resolve18 } from "node:path";
@@ -25899,13 +26046,13 @@ function resolveFailproofaidBinaryPath() {
25899
26046
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
25900
26047
  return process.env.FAILPROOFAI_DAEMON_BINARY;
25901
26048
  const downloaded = installedBinaryPath();
25902
- if (existsSync24(downloaded))
26049
+ if (existsSync25(downloaded))
25903
26050
  return downloaded;
25904
26051
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
25905
26052
  if (packageRoot) {
25906
26053
  for (const profile of ["release", "debug"]) {
25907
26054
  const candidate = resolve18(packageRoot, "target", profile, "failproofaid");
25908
- if (existsSync24(candidate))
26055
+ if (existsSync25(candidate))
25909
26056
  return candidate;
25910
26057
  }
25911
26058
  }
@@ -25936,7 +26083,7 @@ function resolveWorkerCommand() {
25936
26083
  if (!packageRoot)
25937
26084
  return null;
25938
26085
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
25939
- if (!existsSync24(workerScript))
26086
+ if (!existsSync25(workerScript))
25940
26087
  return null;
25941
26088
  return `${shellQuote(process.execPath)} ${shellQuote(workerScript)}`;
25942
26089
  }
@@ -25947,7 +26094,7 @@ function resolveCliCommand() {
25947
26094
  if (!packageRoot)
25948
26095
  return null;
25949
26096
  const cliScript = resolve18(packageRoot, "dist", "cli.mjs");
25950
- if (!existsSync24(cliScript))
26097
+ if (!existsSync25(cliScript))
25951
26098
  return null;
25952
26099
  return `${shellQuote(process.execPath)} ${shellQuote(cliScript)}`;
25953
26100
  }
@@ -25961,7 +26108,7 @@ function workerScriptPath() {
25961
26108
  if (!packageRoot)
25962
26109
  return null;
25963
26110
  const workerScript = resolve18(packageRoot, "dist", "worker.mjs");
25964
- return existsSync24(workerScript) ? workerScript : null;
26111
+ return existsSync25(workerScript) ? workerScript : null;
25965
26112
  }
25966
26113
  function assertUnitSafe(value, field) {
25967
26114
  if (UNIT_UNSAFE_RE.test(value)) {
@@ -26053,14 +26200,14 @@ function writePrivilegedFile(destination, contents, mode = "0644") {
26053
26200
  writeFileSync9(staging, contents, "utf8");
26054
26201
  runPrivileged("install", ["-m", mode, staging, destination]);
26055
26202
  } finally {
26056
- rmSync7(stagingDir, { recursive: true, force: true });
26203
+ rmSync8(stagingDir, { recursive: true, force: true });
26057
26204
  }
26058
26205
  }
26059
26206
  function removeLegacyUserService() {
26060
26207
  try {
26061
26208
  if (process.platform === "linux") {
26062
26209
  const legacy = legacySystemdUserUnitPath();
26063
- if (!existsSync24(legacy))
26210
+ if (!existsSync25(legacy))
26064
26211
  return;
26065
26212
  try {
26066
26213
  execFileSync2("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -26077,7 +26224,7 @@ function removeLegacyUserService() {
26077
26224
  } catch {}
26078
26225
  } else {
26079
26226
  const legacyAgent = legacyLaunchAgentPlistPath();
26080
- if (existsSync24(legacyAgent)) {
26227
+ if (existsSync25(legacyAgent)) {
26081
26228
  try {
26082
26229
  execFileSync2("launchctl", ["unload", "-w", legacyAgent], {
26083
26230
  stdio: "ignore",
@@ -26087,7 +26234,7 @@ function removeLegacyUserService() {
26087
26234
  unlinkSync3(legacyAgent);
26088
26235
  }
26089
26236
  const legacyDaemon = legacySharedLaunchDaemonPath();
26090
- if (existsSync24(legacyDaemon)) {
26237
+ if (existsSync25(legacyDaemon)) {
26091
26238
  try {
26092
26239
  runPrivileged("launchctl", ["unload", "-w", legacyDaemon]);
26093
26240
  } catch {}
@@ -26104,7 +26251,7 @@ function systemdUnitContents(binaryPath, workerCmd, cliCmd = null) {
26104
26251
  const user = assertUnitSafe(serviceUser(), "User");
26105
26252
  assertUnitSafe(binaryPath, "ExecStart");
26106
26253
  assertUnitSafe(homedir22(), "HOME");
26107
- const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync24(p));
26254
+ const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync25(p));
26108
26255
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe(p, "ConditionPathExists")}
26109
26256
  `).join("");
26110
26257
  return `[Unit]
@@ -26213,7 +26360,7 @@ async function installDaemonService() {
26213
26360
  } else {
26214
26361
  const plistPath = launchdPlistPath();
26215
26362
  const logDir = logsDir();
26216
- mkdirSync11(logDir, { recursive: true });
26363
+ mkdirSync12(logDir, { recursive: true });
26217
26364
  try {
26218
26365
  runPrivileged("launchctl", ["unload", plistPath]);
26219
26366
  } catch {}
@@ -26317,7 +26464,7 @@ function readInstalledServiceDefinition() {
26317
26464
  if (!isDaemonSupportedPlatform())
26318
26465
  return null;
26319
26466
  const path = daemonServiceFilePath();
26320
- if (!path || !existsSync24(path))
26467
+ if (!path || !existsSync25(path))
26321
26468
  return null;
26322
26469
  try {
26323
26470
  return readFileSync17(path, "utf8");
@@ -26429,7 +26576,7 @@ async function ensureDaemonServiceCurrent() {
26429
26576
  restartSystemdUnit();
26430
26577
  } else {
26431
26578
  const plistPath = launchdPlistPath();
26432
- mkdirSync11(logDir, { recursive: true });
26579
+ mkdirSync12(logDir, { recursive: true });
26433
26580
  previous = definition;
26434
26581
  try {
26435
26582
  runPrivileged("launchctl", ["unload", plistPath]);
@@ -26453,7 +26600,7 @@ async function uninstallDaemonService() {
26453
26600
  try {
26454
26601
  if (process.platform === "linux") {
26455
26602
  const unitPath = systemdUnitPath();
26456
- if (!existsSync24(unitPath))
26603
+ if (!existsSync25(unitPath))
26457
26604
  return;
26458
26605
  try {
26459
26606
  runPrivileged("systemctl", ["disable", "--now", systemdUnitName()]);
@@ -26464,7 +26611,7 @@ async function uninstallDaemonService() {
26464
26611
  } catch {}
26465
26612
  } else {
26466
26613
  const plistPath = launchdPlistPath();
26467
- if (!existsSync24(plistPath))
26614
+ if (!existsSync25(plistPath))
26468
26615
  return;
26469
26616
  try {
26470
26617
  runPrivileged("launchctl", ["unload", "-w", plistPath]);
@@ -26481,7 +26628,7 @@ function daemonVersionSkew() {
26481
26628
  const recorded = readVersionFile()?.daemon;
26482
26629
  if (!recorded)
26483
26630
  return null;
26484
- if (!existsSync24(installedBinaryPath(recorded)))
26631
+ if (!existsSync25(installedBinaryPath(recorded)))
26485
26632
  return null;
26486
26633
  return recorded === version2 ? null : { installed: recorded, expected: version2 };
26487
26634
  }
@@ -26499,7 +26646,7 @@ function daemonServiceStatus() {
26499
26646
  if (!isDaemonSupportedPlatform())
26500
26647
  return "unsupported-platform";
26501
26648
  if (process.platform === "linux") {
26502
- if (!existsSync24(systemdUnitPath()))
26649
+ if (!existsSync25(systemdUnitPath()))
26503
26650
  return "not-installed";
26504
26651
  try {
26505
26652
  const out = execFileSync2("systemctl", ["is-active", systemdUnitName()], {
@@ -26512,7 +26659,7 @@ function daemonServiceStatus() {
26512
26659
  }
26513
26660
  }
26514
26661
  const plistPath = launchdPlistPath();
26515
- if (!existsSync24(plistPath))
26662
+ if (!existsSync25(plistPath))
26516
26663
  return "not-installed";
26517
26664
  try {
26518
26665
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -26543,21 +26690,21 @@ var init_daemon_service = __esm(() => {
26543
26690
 
26544
26691
  // src/hooks/fp-reset.ts
26545
26692
  import {
26546
- copyFileSync,
26547
- existsSync as existsSync25,
26548
- mkdirSync as mkdirSync12,
26693
+ copyFileSync as copyFileSync2,
26694
+ existsSync as existsSync26,
26695
+ mkdirSync as mkdirSync13,
26549
26696
  readFileSync as readFileSync18,
26550
26697
  readdirSync as readdirSync15,
26551
- renameSync as renameSync7,
26552
- rmSync as rmSync8,
26698
+ renameSync as renameSync8,
26699
+ rmSync as rmSync9,
26553
26700
  rmdirSync,
26554
- statSync as statSync17,
26701
+ statSync as statSync18,
26555
26702
  writeFileSync as writeFileSync10
26556
26703
  } from "node:fs";
26557
- import { dirname as dirname11, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
26704
+ import { dirname as dirname12, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve19 } from "node:path";
26558
26705
  function migrateConventionPolicies() {
26559
26706
  const from = legacy.customPoliciesDir();
26560
- if (!existsSync25(from))
26707
+ if (!existsSync26(from))
26561
26708
  return [];
26562
26709
  const moved = [];
26563
26710
  const mergeInto = (dir, dest, prefix) => {
@@ -26570,7 +26717,7 @@ function migrateConventionPolicies() {
26570
26717
  if (entries.length === 0)
26571
26718
  return;
26572
26719
  try {
26573
- mkdirSync12(dest, { recursive: true });
26720
+ mkdirSync13(dest, { recursive: true });
26574
26721
  } catch {
26575
26722
  return;
26576
26723
  }
@@ -26578,14 +26725,14 @@ function migrateConventionPolicies() {
26578
26725
  const source = resolve19(dir, entry.name);
26579
26726
  const target = resolve19(dest, entry.name);
26580
26727
  const name = `${prefix}${entry.name}`;
26581
- if (!existsSync25(target)) {
26728
+ if (!existsSync26(target)) {
26582
26729
  try {
26583
- renameSync7(source, target);
26730
+ renameSync8(source, target);
26584
26731
  moved.push(name);
26585
26732
  } catch {}
26586
26733
  continue;
26587
26734
  }
26588
- if (entry.isDirectory() && statSync17(target).isDirectory()) {
26735
+ if (entry.isDirectory() && statSync18(target).isDirectory()) {
26589
26736
  mergeInto(source, target, `${name}/`);
26590
26737
  try {
26591
26738
  rmdirSync(source);
@@ -26605,23 +26752,23 @@ function migrateLegacySpool() {
26605
26752
  [legacy.spoolDir(), spoolDir()],
26606
26753
  [legacy.failedDir(), failedDir()]
26607
26754
  ]) {
26608
- if (!existsSync25(from))
26755
+ if (!existsSync26(from))
26609
26756
  continue;
26610
26757
  try {
26611
- mkdirSync12(to, { recursive: true });
26758
+ mkdirSync13(to, { recursive: true });
26612
26759
  for (const entry of readdirSync15(from, { withFileTypes: true })) {
26613
26760
  if (!entry.isFile())
26614
26761
  continue;
26615
26762
  let name = entry.name;
26616
26763
  let n = 0;
26617
- while (existsSync25(resolve19(to, name)))
26764
+ while (existsSync26(resolve19(to, name)))
26618
26765
  name = `legacy-${n++}-${entry.name}`;
26619
26766
  try {
26620
- renameSync7(resolve19(from, entry.name), resolve19(to, name));
26767
+ renameSync8(resolve19(from, entry.name), resolve19(to, name));
26621
26768
  moved.push(name);
26622
26769
  } catch {
26623
26770
  try {
26624
- copyFileSync(resolve19(from, entry.name), resolve19(to, name));
26771
+ copyFileSync2(resolve19(from, entry.name), resolve19(to, name));
26625
26772
  moved.push(name);
26626
26773
  } catch {}
26627
26774
  }
@@ -26632,7 +26779,7 @@ function migrateLegacySpool() {
26632
26779
  }
26633
26780
  function migrateHookActivity() {
26634
26781
  const from = legacy.hookActivityDir();
26635
- if (!existsSync25(from))
26782
+ if (!existsSync26(from))
26636
26783
  return [];
26637
26784
  const moved = [];
26638
26785
  try {
@@ -26640,23 +26787,23 @@ function migrateHookActivity() {
26640
26787
  if (entries.length === 0)
26641
26788
  return [];
26642
26789
  const to = hookActivityDir();
26643
- mkdirSync12(to, { recursive: true });
26790
+ mkdirSync13(to, { recursive: true });
26644
26791
  const stamp = Date.now();
26645
26792
  let seq = 0;
26646
26793
  for (const entry of entries) {
26647
26794
  const source = resolve19(from, entry.name);
26648
26795
  let name = entry.name === "current.jsonl" ? `page-${stamp}-${seq++}.jsonl` : entry.name;
26649
26796
  let target = resolve19(to, name);
26650
- while (existsSync25(target)) {
26797
+ while (existsSync26(target)) {
26651
26798
  name = `page-${stamp}-${seq++}.jsonl`;
26652
26799
  target = resolve19(to, name);
26653
26800
  }
26654
26801
  try {
26655
- renameSync7(source, target);
26802
+ renameSync8(source, target);
26656
26803
  moved.push(name);
26657
26804
  } catch {
26658
26805
  try {
26659
- copyFileSync(source, target);
26806
+ copyFileSync2(source, target);
26660
26807
  moved.push(name);
26661
26808
  } catch {}
26662
26809
  }
@@ -26687,7 +26834,7 @@ function retirePolicyConfigKeys() {
26687
26834
  delete parsed[key];
26688
26835
  try {
26689
26836
  if (Object.keys(parsed).length === 0)
26690
- rmSync8(at, { force: true });
26837
+ rmSync9(at, { force: true });
26691
26838
  else
26692
26839
  writeFileSync10(at, JSON.stringify(parsed, null, 2) + `
26693
26840
  `, "utf8");
@@ -26698,7 +26845,7 @@ function retirePolicyConfigKeys() {
26698
26845
  }
26699
26846
  function readCarriedPolicyConfig() {
26700
26847
  const from = resolve19(legacy.localPoliciesDir(), "policies-config.json");
26701
- if (!existsSync25(from))
26848
+ if (!existsSync26(from))
26702
26849
  return null;
26703
26850
  let parsed;
26704
26851
  try {
@@ -26752,7 +26899,7 @@ function writeCarriedPolicyConfig(carried) {
26752
26899
  }
26753
26900
  } catch {}
26754
26901
  try {
26755
- mkdirSync12(dirname11(to), { recursive: true });
26902
+ mkdirSync13(dirname12(to), { recursive: true });
26756
26903
  writeFileSync10(to, JSON.stringify({ ...existing, ...carried }, null, 2) + `
26757
26904
  `, "utf8");
26758
26905
  } catch {
@@ -26762,7 +26909,7 @@ function writeCarriedPolicyConfig(carried) {
26762
26909
  }
26763
26910
  function readCarriedTelemetryOptOut() {
26764
26911
  const from = legacy.configToml();
26765
- if (!existsSync25(from))
26912
+ if (!existsSync26(from))
26766
26913
  return false;
26767
26914
  try {
26768
26915
  const text = readFileSync18(from, "utf8");
@@ -26817,7 +26964,7 @@ function parseLegacyToml(text) {
26817
26964
  }
26818
26965
  function readCarriedLegacyConfig() {
26819
26966
  const from = legacy.configToml();
26820
- if (!existsSync25(from))
26967
+ if (!existsSync26(from))
26821
26968
  return null;
26822
26969
  try {
26823
26970
  return projectConfig(parseLegacyToml(readFileSync18(from, "utf8")));
@@ -26827,7 +26974,7 @@ function readCarriedLegacyConfig() {
26827
26974
  }
26828
26975
  function readCarriedLegacyCredentials() {
26829
26976
  const toml = legacy.credentialsToml();
26830
- if (existsSync25(toml)) {
26977
+ if (existsSync26(toml)) {
26831
26978
  try {
26832
26979
  const creds = projectCredentials(parseLegacyToml(readFileSync18(toml, "utf8")));
26833
26980
  if (Object.keys(creds).length > 0)
@@ -26870,10 +27017,10 @@ function resetHome(from, to = LAYOUT_VERSION) {
26870
27017
  const spooled = migrateLegacySpool();
26871
27018
  const removed = [];
26872
27019
  for (const path of resettablePaths()) {
26873
- if (!existsSync25(path))
27020
+ if (!existsSync26(path))
26874
27021
  continue;
26875
27022
  try {
26876
- rmSync8(path, { recursive: true, force: true });
27023
+ rmSync9(path, { recursive: true, force: true });
26877
27024
  removed.push(path);
26878
27025
  } catch {}
26879
27026
  }
@@ -26895,7 +27042,7 @@ function layoutWarningForHook() {
26895
27042
  if (state.kind === "future") {
26896
27043
  return `[failproofai] this directory was written by a newer version (layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
26897
27044
  }
26898
- if (existsSync25(globalPolicyConfigFile()))
27045
+ if (existsSync26(globalPolicyConfigFile()))
26899
27046
  return null;
26900
27047
  return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
26901
27048
  }
@@ -26909,8 +27056,8 @@ var init_fp_reset = __esm(() => {
26909
27056
  });
26910
27057
 
26911
27058
  // 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";
27059
+ import { closeSync as closeSync3, constants as fsConstants2, fstatSync as fstatSync2, openSync as openSync3, readSync as readSync2, statSync as statSync19 } from "node:fs";
27060
+ import { dirname as dirname13 } from "node:path";
26914
27061
  function parseJevMode(raw) {
26915
27062
  return raw === "off" || raw === "observe" || raw === "enforce" ? raw : null;
26916
27063
  }
@@ -27178,7 +27325,7 @@ function looseConfigDirMode(path) {
27178
27325
  if (!modesAreMeaningful())
27179
27326
  return null;
27180
27327
  try {
27181
- const mode = statSync18(dirname12(path)).mode & 511;
27328
+ const mode = statSync19(dirname13(path)).mode & 511;
27182
27329
  return (mode & DIR_WRITABLE_BY_OTHERS2) !== 0 ? mode : null;
27183
27330
  } catch {
27184
27331
  return null;
@@ -27191,7 +27338,7 @@ function inspectJevConfig() {
27191
27338
  const path = jevConfigPath();
27192
27339
  let fd;
27193
27340
  try {
27194
- fd = openSync2(path, OPEN_FLAGS);
27341
+ fd = openSync3(path, OPEN_FLAGS);
27195
27342
  } catch (err) {
27196
27343
  const code = err.code;
27197
27344
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -27239,8 +27386,8 @@ function inspectJevConfig() {
27239
27386
  path,
27240
27387
  mode,
27241
27388
  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)}`
27389
+ 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)})`,
27390
+ fix: `chmod 700 ${dirname13(path)}`
27244
27391
  };
27245
27392
  }
27246
27393
  if (st.size > MAX_CONFIG_BYTES)
@@ -27250,7 +27397,7 @@ function inspectJevConfig() {
27250
27397
  return { status: "refused", path, mode, reason: "unreadable", problem: `cannot read it (${err.code ?? "error"})` };
27251
27398
  } finally {
27252
27399
  try {
27253
- closeSync2(fd);
27400
+ closeSync3(fd);
27254
27401
  } catch {}
27255
27402
  }
27256
27403
  let parsed;
@@ -27346,7 +27493,7 @@ function readJevConfigFileForUpdate() {
27346
27493
  const path = jevConfigPath();
27347
27494
  let fd;
27348
27495
  try {
27349
- fd = openSync2(path, OPEN_FLAGS);
27496
+ fd = openSync3(path, OPEN_FLAGS);
27350
27497
  } catch {
27351
27498
  return null;
27352
27499
  }
@@ -27373,7 +27520,7 @@ function readJevConfigFileForUpdate() {
27373
27520
  return null;
27374
27521
  } finally {
27375
27522
  try {
27376
- closeSync2(fd);
27523
+ closeSync3(fd);
27377
27524
  } catch {}
27378
27525
  }
27379
27526
  }
@@ -27404,9 +27551,9 @@ var init_jev_config = __esm(() => {
27404
27551
  });
27405
27552
 
27406
27553
  // src/hooks/semantic/facts.ts
27407
- import { existsSync as existsSync26, readFileSync as readFileSync19, statSync as statSync19 } from "node:fs";
27554
+ import { existsSync as existsSync27, readFileSync as readFileSync19, statSync as statSync20 } from "node:fs";
27408
27555
  import { homedir as homedir23 } from "node:os";
27409
- import { dirname as dirname13, isAbsolute as isAbsolute4, resolve as resolve20 } from "node:path";
27556
+ import { dirname as dirname14, isAbsolute as isAbsolute4, resolve as resolve20 } from "node:path";
27410
27557
  function classifyTool(toolName) {
27411
27558
  if (SHELL_TOOLS.has(toolName))
27412
27559
  return { toolClass: "shell", toolIsKnown: true };
@@ -27631,9 +27778,9 @@ function findGitDir(start) {
27631
27778
  let dir = start;
27632
27779
  for (let i = 0;i < 40; i++) {
27633
27780
  const candidate = resolve20(dir, ".git");
27634
- if (existsSync26(candidate))
27781
+ if (existsSync27(candidate))
27635
27782
  return candidate;
27636
- const parent = dirname13(dir);
27783
+ const parent = dirname14(dir);
27637
27784
  if (parent === dir)
27638
27785
  return null;
27639
27786
  dir = parent;
@@ -27644,7 +27791,7 @@ function findProjectRoot(cwd) {
27644
27791
  if (!cwd)
27645
27792
  return null;
27646
27793
  const gitDir = findGitDir(cwd);
27647
- return gitDir ? dirname13(gitDir) : cwd;
27794
+ return gitDir ? dirname14(gitDir) : cwd;
27648
27795
  }
27649
27796
  function readCurrentBranch(cwd) {
27650
27797
  if (!cwd)
@@ -27654,12 +27801,12 @@ function readCurrentBranch(cwd) {
27654
27801
  if (!gitPath)
27655
27802
  return null;
27656
27803
  let headFile = resolve20(gitPath, "HEAD");
27657
- if (statSync19(gitPath).isFile()) {
27804
+ if (statSync20(gitPath).isFile()) {
27658
27805
  const pointer = readFileSync19(gitPath, "utf8").trim();
27659
27806
  const m = /^gitdir:\s*(.+)$/.exec(pointer);
27660
27807
  if (!m)
27661
27808
  return null;
27662
- headFile = resolve20(dirname13(gitPath), m[1], "HEAD");
27809
+ headFile = resolve20(dirname14(gitPath), m[1], "HEAD");
27663
27810
  }
27664
27811
  const head = readFileSync19(headFile, "utf8").trim();
27665
27812
  const ref = /^ref:\s*refs\/heads\/(.+)$/.exec(head);
@@ -28049,19 +28196,19 @@ __export(exports_intent, {
28049
28196
  readIntent: () => readIntent
28050
28197
  });
28051
28198
  import {
28052
- chmodSync as chmodSync4,
28053
- closeSync as closeSync3,
28054
- mkdirSync as mkdirSync13,
28055
- openSync as openSync3,
28199
+ chmodSync as chmodSync5,
28200
+ closeSync as closeSync4,
28201
+ mkdirSync as mkdirSync14,
28202
+ openSync as openSync4,
28056
28203
  readdirSync as readdirSync16,
28057
28204
  readFileSync as readFileSync20,
28058
28205
  readSync as readSync3,
28059
- renameSync as renameSync8,
28060
- statSync as statSync20,
28206
+ renameSync as renameSync9,
28207
+ statSync as statSync21,
28061
28208
  unlinkSync as unlinkSync4,
28062
28209
  writeFileSync as writeFileSync11
28063
28210
  } from "node:fs";
28064
- import { dirname as dirname14, resolve as resolve21 } from "node:path";
28211
+ import { dirname as dirname15, resolve as resolve21 } from "node:path";
28065
28212
  function modesAreMeaningful2() {
28066
28213
  return process.platform !== "win32";
28067
28214
  }
@@ -28073,7 +28220,7 @@ function storeDirChain() {
28073
28220
  chain.push(dir);
28074
28221
  if (dir === home)
28075
28222
  break;
28076
- const parent = dirname14(dir);
28223
+ const parent = dirname15(dir);
28077
28224
  if (parent === dir)
28078
28225
  break;
28079
28226
  dir = parent;
@@ -28086,15 +28233,15 @@ function looseIntentStoreDir() {
28086
28233
  for (const dir of storeDirChain()) {
28087
28234
  let mode;
28088
28235
  try {
28089
- mode = statSync20(dir).mode & 511;
28236
+ mode = statSync21(dir).mode & 511;
28090
28237
  } catch {
28091
28238
  continue;
28092
28239
  }
28093
28240
  if ((mode & DIR_WRITABLE_BY_OTHERS3) === 0)
28094
28241
  continue;
28095
28242
  try {
28096
- chmodSync4(dir, mode & ~DIR_WRITABLE_BY_OTHERS3);
28097
- if ((statSync20(dir).mode & DIR_WRITABLE_BY_OTHERS3) !== 0)
28243
+ chmodSync5(dir, mode & ~DIR_WRITABLE_BY_OTHERS3);
28244
+ if ((statSync21(dir).mode & DIR_WRITABLE_BY_OTHERS3) !== 0)
28098
28245
  return dir;
28099
28246
  } catch {
28100
28247
  return dir;
@@ -28117,12 +28264,12 @@ function appendPrompt(sessionId, entry) {
28117
28264
  const kept = last && last.text === entry.text ? file.prompts.slice(0, -1) : file.prompts;
28118
28265
  file.prompts = [...kept, entry].slice(-MAX_RECORDED_PROMPTS);
28119
28266
  const dir = sessionsDir();
28120
- mkdirSync13(dir, { recursive: true, mode: 448 });
28267
+ mkdirSync14(dir, { recursive: true, mode: 448 });
28121
28268
  const target = intentFile(sessionId);
28122
28269
  const isNew = !fileExists2(target);
28123
28270
  const tmp = `${target}.${process.pid}.tmp`;
28124
28271
  writeFileSync11(tmp, JSON.stringify(file), { mode: 384 });
28125
- renameSync8(tmp, target);
28272
+ renameSync9(tmp, target);
28126
28273
  if (isNew)
28127
28274
  pruneExpiredSessions(entry.at);
28128
28275
  return true;
@@ -28132,7 +28279,7 @@ function appendPrompt(sessionId, entry) {
28132
28279
  }
28133
28280
  function fileExists2(path) {
28134
28281
  try {
28135
- statSync20(path);
28282
+ statSync21(path);
28136
28283
  return true;
28137
28284
  } catch {
28138
28285
  return false;
@@ -28147,7 +28294,7 @@ function pruneExpiredSessions(now = Date.now()) {
28147
28294
  continue;
28148
28295
  const path = resolve21(dir, name);
28149
28296
  try {
28150
- const st = statSync20(path);
28297
+ const st = statSync21(path);
28151
28298
  if (st.isFile() && now - st.mtimeMs > INTENT_MAX_AGE_MS) {
28152
28299
  unlinkSync4(path);
28153
28300
  removed++;
@@ -28456,10 +28603,10 @@ function visitLinesBackwards(transcriptPath, maxBytes, visit) {
28456
28603
  return;
28457
28604
  let fd;
28458
28605
  try {
28459
- const st = statSync20(path);
28606
+ const st = statSync21(path);
28460
28607
  if (!st.isFile() || st.size === 0)
28461
28608
  return;
28462
- fd = openSync3(path, "r");
28609
+ fd = openSync4(path, "r");
28463
28610
  let end = st.size;
28464
28611
  let consumed = 0;
28465
28612
  let partial = Buffer.alloc(0);
@@ -28494,7 +28641,7 @@ function visitLinesBackwards(transcriptPath, maxBytes, visit) {
28494
28641
  } catch {} finally {
28495
28642
  if (fd !== undefined) {
28496
28643
  try {
28497
- closeSync3(fd);
28644
+ closeSync4(fd);
28498
28645
  } catch {}
28499
28646
  }
28500
28647
  }
@@ -29084,7 +29231,7 @@ var init_jev_client = __esm(() => {
29084
29231
 
29085
29232
  // src/hooks/semantic/evaluator.ts
29086
29233
  import { createHash as createHash8 } from "node:crypto";
29087
- import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync14, renameSync as renameSync9, statSync as statSync21 } from "node:fs";
29234
+ import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync15, renameSync as renameSync10, statSync as statSync22 } from "node:fs";
29088
29235
  import { resolve as resolve22 } from "node:path";
29089
29236
  function storeCut(message) {
29090
29237
  return typeof message === "string" && message.length >= MAX_USER_MESSAGE_CHARS - STORE_CUT_SLACK && OMISSION_MARK.test(message);
@@ -29256,10 +29403,10 @@ function verdictLogRow(input, outcome, meta) {
29256
29403
  function appendVerdictLog(row) {
29257
29404
  try {
29258
29405
  const file = verdictLogFile();
29259
- mkdirSync14(semanticDir(), { recursive: true, mode: 448 });
29406
+ mkdirSync15(semanticDir(), { recursive: true, mode: 448 });
29260
29407
  try {
29261
- if (statSync21(file).size > VERDICT_LOG_MAX_BYTES)
29262
- renameSync9(file, `${file}.1`);
29408
+ if (statSync22(file).size > VERDICT_LOG_MAX_BYTES)
29409
+ renameSync10(file, `${file}.1`);
29263
29410
  } catch {}
29264
29411
  appendFileSync3(file, JSON.stringify(row) + `
29265
29412
  `, { mode: 384 });
@@ -29489,7 +29636,7 @@ var init_jev_throttle = __esm(() => {
29489
29636
  });
29490
29637
 
29491
29638
  // 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";
29639
+ import { mkdirSync as mkdirSync16, readdirSync as readdirSync17, readFileSync as readFileSync21, statSync as statSync23, unlinkSync as unlinkSync5, writeFileSync as writeFileSync12 } from "node:fs";
29493
29640
  import { isAbsolute as isAbsolute5, resolve as resolve23 } from "node:path";
29494
29641
  function validRoot(v) {
29495
29642
  return typeof v === "string" && isAbsolute5(v) && resolve23(v) === v && v !== "/";
@@ -29500,7 +29647,7 @@ function storeIsOurs() {
29500
29647
  if (looseIntentStoreDir() !== null)
29501
29648
  return false;
29502
29649
  try {
29503
- const mode = statSync22(rootsDir()).mode & 511;
29650
+ const mode = statSync23(rootsDir()).mode & 511;
29504
29651
  return (mode & DIR_WRITABLE_BY_OTHERS4) === 0;
29505
29652
  } catch {
29506
29653
  return true;
@@ -29523,7 +29670,7 @@ function pruneSessionRoots(now = Date.now()) {
29523
29670
  continue;
29524
29671
  const path = resolve23(dir, name);
29525
29672
  try {
29526
- const st = statSync22(path);
29673
+ const st = statSync23(path);
29527
29674
  if (st.isFile() && now - st.mtimeMs > SESSION_ROOT_MAX_AGE_MS) {
29528
29675
  unlinkSync5(path);
29529
29676
  removed++;
@@ -29547,7 +29694,7 @@ function sessionProjectRoot(sessionId, cwd, now = Date.now()) {
29547
29694
  return pinned;
29548
29695
  if (!validRoot(live))
29549
29696
  return live;
29550
- mkdirSync15(rootsDir(), { recursive: true, mode: 448 });
29697
+ mkdirSync16(rootsDir(), { recursive: true, mode: 448 });
29551
29698
  writeFileSync12(rootFile(sessionId), JSON.stringify({ root: live, at: now }), { mode: 384, flag: "wx" });
29552
29699
  pruneSessionRoots(now);
29553
29700
  } catch {}
@@ -29873,7 +30020,7 @@ var init_enforcement_capability = __esm(() => {
29873
30020
  });
29874
30021
 
29875
30022
  // src/hooks/handler.ts
29876
- import { existsSync as existsSync27 } from "node:fs";
30023
+ import { existsSync as existsSync28 } from "node:fs";
29877
30024
  function canonicalizeEventType(raw, cli) {
29878
30025
  if (cli === "codex") {
29879
30026
  const mapped = CODEX_EVENT_MAP[raw];
@@ -29933,7 +30080,7 @@ function jevForcedOff(opts) {
29933
30080
  }
29934
30081
  async function readJevConfig() {
29935
30082
  try {
29936
- if (!existsSync27(jevConfigFile()))
30083
+ if (!existsSync28(jevConfigFile()))
29937
30084
  return null;
29938
30085
  await Promise.resolve().then(() => init_jev_config());
29939
30086
  const config = loadJevConfig();
@@ -31045,18 +31192,18 @@ var init_collector_config = __esm(() => {
31045
31192
  });
31046
31193
 
31047
31194
  // 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";
31195
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, writeFileSync as writeFileSync13, readdirSync as readdirSync18 } from "node:fs";
31196
+ import { dirname as dirname16, join as join32 } from "node:path";
31050
31197
  function flushRequestPath(home) {
31051
- return join31(failproofaiHome(home), "state", "flush-request.json");
31198
+ return join32(failproofaiHome(home), "state", "flush-request.json");
31052
31199
  }
31053
31200
  function spoolDirs(home) {
31054
31201
  const root = spoolDir(home);
31055
31202
  const dirs = [root, customAgentsEventsDir(home)];
31056
- if (!existsSync28(root))
31203
+ if (!existsSync29(root))
31057
31204
  return dirs;
31058
31205
  try {
31059
- return dirs.concat(readdirSync18(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join31(root, e.name)));
31206
+ return dirs.concat(readdirSync18(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join32(root, e.name)));
31060
31207
  } catch {
31061
31208
  return dirs;
31062
31209
  }
@@ -31134,7 +31281,7 @@ async function runFlushCommand(opts = {}) {
31134
31281
  return { exitCode: 0, pending: 0, lines: nothing };
31135
31282
  }
31136
31283
  const path = flushRequestPath(home);
31137
- mkdirSync16(dirname15(path), { recursive: true });
31284
+ mkdirSync17(dirname16(path), { recursive: true });
31138
31285
  writeFileSync13(path, `${JSON.stringify({ requestedAtMs: Date.now() }, null, 2)}
31139
31286
  `, {
31140
31287
  mode: 384
@@ -31169,16 +31316,16 @@ var init_flush_cli = __esm(() => {
31169
31316
 
31170
31317
  // src/hooks/migrations.ts
31171
31318
  import {
31172
- chmodSync as chmodSync5,
31173
- copyFileSync as copyFileSync2,
31174
- existsSync as existsSync29,
31175
- mkdirSync as mkdirSync17,
31319
+ chmodSync as chmodSync6,
31320
+ copyFileSync as copyFileSync3,
31321
+ existsSync as existsSync30,
31322
+ mkdirSync as mkdirSync18,
31176
31323
  readFileSync as readFileSync22,
31177
- renameSync as renameSync10,
31178
- rmSync as rmSync9,
31324
+ renameSync as renameSync11,
31325
+ rmSync as rmSync10,
31179
31326
  writeFileSync as writeFileSync14
31180
31327
  } from "node:fs";
31181
- import { basename as basename6, dirname as dirname16, join as join32, resolve as resolve24 } from "node:path";
31328
+ import { basename as basename7, dirname as dirname17, join as join33, resolve as resolve24 } from "node:path";
31182
31329
  function migrateToLayout4() {
31183
31330
  const moves = [
31184
31331
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -31187,40 +31334,40 @@ function migrateToLayout4() {
31187
31334
  ];
31188
31335
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
31189
31336
  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")
31337
+ moves.push({ from: join33(authDirOverride, "auth.json"), to: join33(authDirOverride, "session.json") }, {
31338
+ from: join33(authDirOverride, "next-audit.json"),
31339
+ to: join33(authDirOverride, "reminder.json")
31193
31340
  });
31194
31341
  }
31195
31342
  const migrated = [];
31196
31343
  for (const { from, to } of moves) {
31197
- if (!existsSync29(from))
31344
+ if (!existsSync30(from))
31198
31345
  continue;
31199
- if (existsSync29(to)) {
31200
- rmSync9(from, { force: true });
31346
+ if (existsSync30(to)) {
31347
+ rmSync10(from, { force: true });
31201
31348
  continue;
31202
31349
  }
31203
- mkdirSync17(dirname16(to), { recursive: true });
31350
+ mkdirSync18(dirname17(to), { recursive: true });
31204
31351
  try {
31205
- renameSync10(from, to);
31352
+ renameSync11(from, to);
31206
31353
  } catch {
31207
31354
  try {
31208
- copyFileSync2(from, to);
31355
+ copyFileSync3(from, to);
31209
31356
  } catch (err) {
31210
31357
  try {
31211
- rmSync9(to, { force: true });
31358
+ rmSync10(to, { force: true });
31212
31359
  } catch {}
31213
31360
  throw err;
31214
31361
  }
31215
- rmSync9(from, { force: true });
31362
+ rmSync10(from, { force: true });
31216
31363
  }
31217
- migrated.push(`${basename6(from)} → audit/${basename6(to)}`);
31364
+ migrated.push(`${basename7(from)} → audit/${basename7(to)}`);
31218
31365
  }
31219
31366
  for (const secret of [auditSessionFile()]) {
31220
- if (!existsSync29(secret))
31367
+ if (!existsSync30(secret))
31221
31368
  continue;
31222
31369
  try {
31223
- chmodSync5(secret, 384);
31370
+ chmodSync6(secret, 384);
31224
31371
  } catch {}
31225
31372
  }
31226
31373
  writeVersionFile({ layout: 4 });
@@ -31251,26 +31398,26 @@ function readLedger() {
31251
31398
  }
31252
31399
  function appendLedger(entry) {
31253
31400
  try {
31254
- mkdirSync17(migrationsDir(), { recursive: true });
31401
+ mkdirSync18(migrationsDir(), { recursive: true });
31255
31402
  const all = [...readLedger(), entry];
31256
31403
  writeFileSync14(migrationLedgerFile(), `${JSON.stringify(all, null, 2)}
31257
31404
  `, "utf8");
31258
31405
  } catch {}
31259
31406
  }
31260
31407
  function backupNameOf(f) {
31261
- return f.as ?? basename6(f.at());
31408
+ return f.as ?? basename7(f.at());
31262
31409
  }
31263
31410
  function pruneMigratedCredentials(from) {
31264
31411
  const pruned = [];
31265
31412
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
31266
31413
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS) {
31267
31414
  try {
31268
- if (!existsSync29(landsAt()))
31415
+ if (!existsSync30(landsAt()))
31269
31416
  continue;
31270
31417
  const copy = resolve24(migrationBackupDir(layout), as);
31271
- if (!existsSync29(copy))
31418
+ if (!existsSync30(copy))
31272
31419
  continue;
31273
- rmSync9(copy, { force: true });
31420
+ rmSync10(copy, { force: true });
31274
31421
  pruned.push(as);
31275
31422
  } catch {}
31276
31423
  }
@@ -31281,7 +31428,7 @@ function filesToBackUp() {
31281
31428
  const seen = new Map;
31282
31429
  for (const f of [...BACKED_UP, ...BACKED_UP_LEGACY]) {
31283
31430
  const path = f.at();
31284
- if (existsSync29(path))
31431
+ if (existsSync30(path))
31285
31432
  seen.set(path, backupNameOf(f));
31286
31433
  }
31287
31434
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -31290,14 +31437,14 @@ function backupBeforeMigrating(from) {
31290
31437
  const dir = migrationBackupDir(from);
31291
31438
  const saved = [];
31292
31439
  try {
31293
- rmSync9(dir, { recursive: true, force: true });
31294
- mkdirSync17(dir, { recursive: true });
31440
+ rmSync10(dir, { recursive: true, force: true });
31441
+ mkdirSync18(dir, { recursive: true });
31295
31442
  } catch {
31296
31443
  return [];
31297
31444
  }
31298
31445
  for (const { path: source, as } of filesToBackUp()) {
31299
31446
  try {
31300
- copyFileSync2(source, resolve24(dir, as));
31447
+ copyFileSync3(source, resolve24(dir, as));
31301
31448
  saved.push(as);
31302
31449
  } catch {}
31303
31450
  }
@@ -31407,7 +31554,7 @@ var init_migrations = __esm(() => {
31407
31554
  { at: legacy.auditSchedule }
31408
31555
  ];
31409
31556
  PRUNED_AFTER_SUCCESS = [
31410
- { as: basename6(legacy.authJson()), landsAt: auditSessionFile }
31557
+ { as: basename7(legacy.authJson()), landsAt: auditSessionFile }
31411
31558
  ];
31412
31559
  });
31413
31560
 
@@ -31587,15 +31734,15 @@ var init_fp_reset2 = __esm(() => {
31587
31734
  // scripts/install-telemetry.mjs
31588
31735
  import { createHmac, randomUUID as randomUUID2 } from "node:crypto";
31589
31736
  import { execSync as execSync5 } from "node:child_process";
31590
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, mkdirSync as mkdirSync18 } from "node:fs";
31737
+ import { readFileSync as readFileSync23, writeFileSync as writeFileSync15, mkdirSync as mkdirSync19 } from "node:fs";
31591
31738
  import { homedir as homedir24, platform, arch, hostname, cpus } from "node:os";
31592
- import { join as join33 } from "node:path";
31739
+ import { join as join34 } from "node:path";
31593
31740
  function hashToId3(raw) {
31594
31741
  return createHmac("sha256", NAMESPACE3).update(raw).digest("hex");
31595
31742
  }
31596
31743
  function getInstanceId3() {
31597
- const idDir = join33(homedir24(), ".failproofai");
31598
- const idFile = join33(idDir, "instance-id");
31744
+ const idDir = join34(homedir24(), ".failproofai");
31745
+ const idFile = join34(idDir, "instance-id");
31599
31746
  try {
31600
31747
  const existing = readFileSync23(idFile, "utf-8").trim();
31601
31748
  if (existing)
@@ -31638,7 +31785,7 @@ function getInstanceId3() {
31638
31785
  } catch {}
31639
31786
  const id = randomUUID2();
31640
31787
  try {
31641
- mkdirSync18(idDir, { recursive: true });
31788
+ mkdirSync19(idDir, { recursive: true });
31642
31789
  writeFileSync15(idFile, id, "utf-8");
31643
31790
  } catch {}
31644
31791
  return id;
@@ -31671,8 +31818,8 @@ var NAMESPACE3 = "failproofai-telemetry-v1", API_KEY3 = "phc_Ac1Ww1GqKc0z1SyrRWb
31671
31818
  var init_install_telemetry = () => {};
31672
31819
 
31673
31820
  // 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";
31821
+ import { existsSync as existsSync31, readFileSync as readFileSync24, writeFileSync as writeFileSync16, mkdirSync as mkdirSync20 } from "node:fs";
31822
+ import { dirname as dirname18, resolve as resolve25 } from "node:path";
31676
31823
  import { platform as platform2, arch as arch2, release, homedir as homedir25, hostname as hostname2 } from "node:os";
31677
31824
  import { createHmac as createHmac2 } from "node:crypto";
31678
31825
  function hashToId4(raw) {
@@ -31727,7 +31874,7 @@ function compareSemver2(a, b) {
31727
31874
  }
31728
31875
  function checkHooks() {
31729
31876
  const hooksConfigPath = globalPolicyConfigFile();
31730
- if (!existsSync30(hooksConfigPath)) {
31877
+ if (!existsSync31(hooksConfigPath)) {
31731
31878
  return { configured: false, registered: false, policyCount: 0 };
31732
31879
  }
31733
31880
  let config;
@@ -31741,7 +31888,7 @@ function checkHooks() {
31741
31888
  }
31742
31889
  const policyCount = config.enabledPolicies.length;
31743
31890
  const settingsPath = resolve25(homedir25(), ".claude", "settings.json");
31744
- if (!existsSync30(settingsPath))
31891
+ if (!existsSync31(settingsPath))
31745
31892
  return { configured: true, registered: false, policyCount };
31746
31893
  let settings;
31747
31894
  try {
@@ -31769,7 +31916,7 @@ async function maybeReportInstall(version) {
31769
31916
  const versionFile = lastVersionPath();
31770
31917
  let previousVersion = null;
31771
31918
  try {
31772
- if (existsSync30(versionFile)) {
31919
+ if (existsSync31(versionFile)) {
31773
31920
  previousVersion = readFileSync24(versionFile, "utf8").trim() || null;
31774
31921
  }
31775
31922
  } catch {}
@@ -31806,7 +31953,7 @@ async function maybeReportInstall(version) {
31806
31953
  enabled_policy_count: hooks.policyCount
31807
31954
  }, { version, timeoutMs: REPORT_TIMEOUT_MS, enabled: telemetryEnabled }));
31808
31955
  try {
31809
- mkdirSync19(dirname17(versionFile), { recursive: true });
31956
+ mkdirSync20(dirname18(versionFile), { recursive: true });
31810
31957
  writeFileSync16(versionFile, version, "utf8");
31811
31958
  } catch {}
31812
31959
  await Promise.all(events.map((p) => p.catch(() => {})));
@@ -31858,8 +32005,8 @@ var init_cli_error = __esm(() => {
31858
32005
 
31859
32006
  // src/hooks/manager.ts
31860
32007
  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";
32008
+ import { existsSync as existsSync32 } from "node:fs";
32009
+ import { resolve as resolve26, basename as basename8 } from "node:path";
31863
32010
  import { platform as platform3, arch as arch3, release as release2, hostname as hostname3 } from "node:os";
31864
32011
  function getSettingsPath(scope, cwd) {
31865
32012
  return claudeCode.getSettingsPath(scope, cwd);
@@ -32090,7 +32237,7 @@ async function installHooksImpl(policyNames, scope = "user", cwd, includeBeta =
32090
32237
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
32091
32238
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve26(path));
32092
32239
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve26(path)).filter((path) => {
32093
- if (existsSync31(path))
32240
+ if (existsSync32(path))
32094
32241
  return true;
32095
32242
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
32096
32243
  return false;
@@ -32322,7 +32469,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
32322
32469
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
32323
32470
  for (const s of scopesToRemove) {
32324
32471
  const settingsPaths = settingsPathsFor(integration, s, cwd);
32325
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync31(p));
32472
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync32(p));
32326
32473
  if (existing.length === 0) {
32327
32474
  if (scope !== "all" && selectedClis.length === 1) {
32328
32475
  console.log("No settings file found. Nothing to remove.");
@@ -32427,7 +32574,7 @@ var DEFAULT_FETCH_TIMEOUT_MS = 15000;
32427
32574
 
32428
32575
  // src/hooks/cloud-enrollment.ts
32429
32576
  import { randomUUID as randomUUID3 } from "node:crypto";
32430
- import { existsSync as existsSync32, readFileSync as readFileSync25, rmSync as rmSync10 } from "node:fs";
32577
+ import { existsSync as existsSync33, readFileSync as readFileSync25, rmSync as rmSync11 } from "node:fs";
32431
32578
  import { hostname as hostname4 } from "node:os";
32432
32579
  function cloudCredentialPath() {
32433
32580
  return process.env.FAILPROOFAI_CLOUD_CREDENTIALS ?? credentialsFile();
@@ -32466,7 +32613,7 @@ function readCloudCredentials() {
32466
32613
  if (!usingJsonOverride())
32467
32614
  return readCredentials().cloud ?? null;
32468
32615
  const path = cloudCredentialPath();
32469
- if (!existsSync32(path))
32616
+ if (!existsSync33(path))
32470
32617
  return null;
32471
32618
  try {
32472
32619
  const raw = JSON.parse(readFileSync25(path, "utf8"));
@@ -32508,10 +32655,10 @@ function resolveMachineLabel(explicit) {
32508
32655
  function clearCloudCredentials() {
32509
32656
  if (usingJsonOverride()) {
32510
32657
  const path = cloudCredentialPath();
32511
- if (!existsSync32(path))
32658
+ if (!existsSync33(path))
32512
32659
  return false;
32513
32660
  try {
32514
- rmSync10(path);
32661
+ rmSync11(path);
32515
32662
  return true;
32516
32663
  } catch {
32517
32664
  return false;
@@ -32631,25 +32778,25 @@ var INTROSPECT_PATH = "/v1/auth/introspect", PERMISSION_EVENTS = "events:add", P
32631
32778
 
32632
32779
  // src/hooks/jev-cloud-connection.ts
32633
32780
  import {
32634
- chmodSync as chmodSync6,
32635
- closeSync as closeSync4,
32781
+ chmodSync as chmodSync7,
32782
+ closeSync as closeSync5,
32636
32783
  constants as fsConstants3,
32637
- existsSync as existsSync33,
32784
+ existsSync as existsSync34,
32638
32785
  fstatSync as fstatSync3,
32639
32786
  linkSync,
32640
- lstatSync as lstatSync2,
32641
- mkdirSync as mkdirSync20,
32642
- openSync as openSync4,
32787
+ lstatSync as lstatSync3,
32788
+ mkdirSync as mkdirSync21,
32789
+ openSync as openSync5,
32643
32790
  readFileSync as readFileSync26,
32644
32791
  readSync as readSync4,
32645
- renameSync as renameSync11,
32646
- rmSync as rmSync11,
32647
- statSync as statSync23,
32792
+ renameSync as renameSync12,
32793
+ rmSync as rmSync12,
32794
+ statSync as statSync24,
32648
32795
  unlinkSync as unlinkSync6,
32649
32796
  writeFileSync as writeFileSync17
32650
32797
  } from "node:fs";
32651
- import { dirname as dirname18 } from "node:path";
32652
- import { randomBytes as randomBytes2 } from "node:crypto";
32798
+ import { dirname as dirname19 } from "node:path";
32799
+ import { randomBytes as randomBytes3 } from "node:crypto";
32653
32800
  function writeCloudJevConfigIfAbsent(cloudBase) {
32654
32801
  const path = jevConfigPath();
32655
32802
  let baseUrl;
@@ -32658,17 +32805,17 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32658
32805
  } catch {
32659
32806
  return { status: "error", path, problem: "the FailproofAI Cloud URL is not a URL" };
32660
32807
  }
32661
- if (existsSync33(path))
32808
+ if (existsSync34(path))
32662
32809
  return kept(path, cloudBase);
32663
32810
  const body = `${JSON.stringify({ provider: JEV_CLOUD_PROVIDER, baseUrl, mode: CLOUD_JEV_INITIAL_MODE }, null, 2)}
32664
32811
  `;
32665
- const dir = dirname18(path);
32666
- const tmp = `${path}.${process.pid}.${randomBytes2(6).toString("hex")}.tmp`;
32812
+ const dir = dirname19(path);
32813
+ const tmp = `${path}.${process.pid}.${randomBytes3(6).toString("hex")}.tmp`;
32667
32814
  try {
32668
- if (!existsSync33(dir))
32669
- mkdirSync20(dir, { recursive: true, mode: 448 });
32815
+ if (!existsSync34(dir))
32816
+ mkdirSync21(dir, { recursive: true, mode: 448 });
32670
32817
  writeFileSync17(tmp, body, { mode: 384, flag: "wx" });
32671
- chmodSync6(tmp, 384);
32818
+ chmodSync7(tmp, 384);
32672
32819
  try {
32673
32820
  linkSync(tmp, path);
32674
32821
  } catch (err) {
@@ -32680,7 +32827,7 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32680
32827
  return { status: "error", path, problem: `could not write ${path} (${err.code ?? "error"})` };
32681
32828
  } finally {
32682
32829
  try {
32683
- rmSync11(tmp, { force: true });
32830
+ rmSync12(tmp, { force: true });
32684
32831
  } catch {}
32685
32832
  }
32686
32833
  tightenDir(dir);
@@ -32688,7 +32835,7 @@ function writeCloudJevConfigIfAbsent(cloudBase) {
32688
32835
  }
32689
32836
  function existingJevConfig(cloudBase) {
32690
32837
  const path = jevConfigPath();
32691
- return existsSync33(path) ? kept(path, cloudBase) : null;
32838
+ return existsSync34(path) ? kept(path, cloudBase) : null;
32692
32839
  }
32693
32840
  function cloudJevRunningMode() {
32694
32841
  try {
@@ -32727,16 +32874,16 @@ function tightenDir(dir) {
32727
32874
  if (process.platform === "win32")
32728
32875
  return;
32729
32876
  try {
32730
- const before = statSync23(dir).mode & 511;
32877
+ const before = statSync24(dir).mode & 511;
32731
32878
  if ((before & 18) !== 0)
32732
- chmodSync6(dir, before & ~18);
32879
+ chmodSync7(dir, before & ~18);
32733
32880
  } catch {}
32734
32881
  }
32735
32882
  function removeCloudJevConfig() {
32736
32883
  const path = jevConfigPath();
32737
32884
  let st;
32738
32885
  try {
32739
- st = lstatSync2(path);
32886
+ st = lstatSync3(path);
32740
32887
  } catch (err) {
32741
32888
  const code = err.code;
32742
32889
  if (code === "ENOENT" || code === "ENOTDIR")
@@ -32745,9 +32892,9 @@ function removeCloudJevConfig() {
32745
32892
  }
32746
32893
  if (!st.isFile())
32747
32894
  return { status: "kept", path, provider: null };
32748
- const aside = `${path}.${process.pid}.${randomBytes2(6).toString("hex")}.disconnecting`;
32895
+ const aside = `${path}.${process.pid}.${randomBytes3(6).toString("hex")}.disconnecting`;
32749
32896
  try {
32750
- renameSync11(path, aside);
32897
+ renameSync12(path, aside);
32751
32898
  } catch (err) {
32752
32899
  const code = err.code;
32753
32900
  if (code === "ENOENT")
@@ -32788,12 +32935,12 @@ function putBack(aside, path, mode) {
32788
32935
  let created = false;
32789
32936
  try {
32790
32937
  const bytes = readFileSync26(aside);
32791
- const fd = openSync4(path, "wx", mode);
32938
+ const fd = openSync5(path, "wx", mode);
32792
32939
  created = true;
32793
32940
  try {
32794
32941
  writeFileSync17(fd, bytes);
32795
32942
  } finally {
32796
- closeSync4(fd);
32943
+ closeSync5(fd);
32797
32944
  }
32798
32945
  discard(aside);
32799
32946
  return "restored";
@@ -32804,14 +32951,14 @@ function putBack(aside, path, mode) {
32804
32951
  return { code: codeOf(err) };
32805
32952
  }
32806
32953
  try {
32807
- lstatSync2(path);
32954
+ lstatSync3(path);
32808
32955
  return "occupied";
32809
32956
  } catch (err) {
32810
32957
  if (codeOf(err) !== "ENOENT")
32811
32958
  return { code: codeOf(err) };
32812
32959
  }
32813
32960
  try {
32814
- renameSync11(aside, path);
32961
+ renameSync12(aside, path);
32815
32962
  return "restored";
32816
32963
  } catch (err) {
32817
32964
  return { code: codeOf(err) };
@@ -32826,7 +32973,7 @@ function fieldsOf(file) {
32826
32973
  const none = { provider: null, off: false };
32827
32974
  let fd;
32828
32975
  try {
32829
- fd = openSync4(file, fsConstants3.O_RDONLY | (fsConstants3.O_NONBLOCK ?? 0) | (fsConstants3.O_NOFOLLOW ?? 0));
32976
+ fd = openSync5(file, fsConstants3.O_RDONLY | (fsConstants3.O_NONBLOCK ?? 0) | (fsConstants3.O_NOFOLLOW ?? 0));
32830
32977
  } catch {
32831
32978
  return none;
32832
32979
  }
@@ -32849,7 +32996,7 @@ function fieldsOf(file) {
32849
32996
  return none;
32850
32997
  } finally {
32851
32998
  try {
32852
- closeSync4(fd);
32999
+ closeSync5(fd);
32853
33000
  } catch {}
32854
33001
  }
32855
33002
  }
@@ -33067,8 +33214,8 @@ var init_cloud_connection = __esm(() => {
33067
33214
  });
33068
33215
 
33069
33216
  // 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";
33217
+ import { existsSync as existsSync35, realpathSync as realpathSync4, statSync as statSync25 } from "node:fs";
33218
+ import { dirname as dirname20, resolve as resolve27 } from "node:path";
33072
33219
  import { homedir as homedir26 } from "node:os";
33073
33220
  function globalConfigPath(home = homedir26()) {
33074
33221
  return globalPolicyConfigFile(home);
@@ -33081,7 +33228,7 @@ function legacyMarkerPath(home) {
33081
33228
  }
33082
33229
  function isDir(path) {
33083
33230
  try {
33084
- return statSync24(path).isDirectory();
33231
+ return statSync25(path).isDirectory();
33085
33232
  } catch {
33086
33233
  return false;
33087
33234
  }
@@ -33092,7 +33239,7 @@ function findProjectRoot2(start, home = homedir26()) {
33092
33239
  while (dir !== resolvedHome) {
33093
33240
  if (isDir(resolve27(dir, ".failproofai")))
33094
33241
  return dir;
33095
- const parent = dirname19(dir);
33242
+ const parent = dirname20(dir);
33096
33243
  if (parent === dir)
33097
33244
  break;
33098
33245
  dir = parent;
@@ -33111,7 +33258,7 @@ function hasGlobalHooksInstalled() {
33111
33258
  function realResolve(path) {
33112
33259
  const lexical = resolve27(path);
33113
33260
  try {
33114
- return realpathSync3(lexical);
33261
+ return realpathSync4(lexical);
33115
33262
  } catch {
33116
33263
  return lexical;
33117
33264
  }
@@ -33124,10 +33271,10 @@ function detectSetupState(cwd = process.cwd(), home = homedir26()) {
33124
33271
  cwd: resolvedCwd,
33125
33272
  home: resolvedHome,
33126
33273
  projectRoot,
33127
- hasGlobalConfig: existsSync34(globalConfigPath(resolvedHome)),
33128
- hasProjectConfig: projectRoot !== resolvedHome && existsSync34(projectConfigPath(projectRoot)),
33274
+ hasGlobalConfig: existsSync35(globalConfigPath(resolvedHome)),
33275
+ hasProjectConfig: projectRoot !== resolvedHome && existsSync35(projectConfigPath(projectRoot)),
33129
33276
  hasGlobalHooks: hasGlobalHooksInstalled(),
33130
- hasLegacyMarker: existsSync34(legacyMarkerPath(resolvedHome)),
33277
+ hasLegacyMarker: existsSync35(legacyMarkerPath(resolvedHome)),
33131
33278
  inHomeDir: resolvedCwd === resolvedHome
33132
33279
  };
33133
33280
  }
@@ -33144,11 +33291,11 @@ var init_setup_state = __esm(() => {
33144
33291
  });
33145
33292
 
33146
33293
  // 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";
33294
+ import { existsSync as existsSync36, mkdirSync as mkdirSync22, readFileSync as readFileSync27, rmSync as rmSync13, writeFileSync as writeFileSync18 } from "node:fs";
33295
+ import { dirname as dirname21 } from "node:path";
33149
33296
  function readOnboardingAttempt() {
33150
33297
  const path = onboardingAttemptFile();
33151
- if (!existsSync35(path))
33298
+ if (!existsSync36(path))
33152
33299
  return null;
33153
33300
  try {
33154
33301
  const raw = JSON.parse(readFileSync27(path, "utf8"));
@@ -33170,7 +33317,7 @@ function readOnboardingAttempt() {
33170
33317
  function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.now()) {
33171
33318
  try {
33172
33319
  const path = onboardingAttemptFile();
33173
- mkdirSync21(dirname20(path), { recursive: true });
33320
+ mkdirSync22(dirname21(path), { recursive: true });
33174
33321
  const record = {
33175
33322
  schemaVersion: SCHEMA_VERSION3,
33176
33323
  reason,
@@ -33183,7 +33330,7 @@ function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.no
33183
33330
  }
33184
33331
  function clearOnboardingAttempt() {
33185
33332
  try {
33186
- rmSync12(onboardingAttemptFile(), { force: true });
33333
+ rmSync13(onboardingAttemptFile(), { force: true });
33187
33334
  } catch {}
33188
33335
  }
33189
33336
  function blockerCleared(attempt, probe) {
@@ -33225,7 +33372,7 @@ var init_onboarding_attempt = __esm(() => {
33225
33372
  });
33226
33373
 
33227
33374
  // src/hooks/onboarding-lock.ts
33228
- import { mkdirSync as mkdirSync22, readFileSync as readFileSync28, rmSync as rmSync13, writeFileSync as writeFileSync19 } from "node:fs";
33375
+ import { mkdirSync as mkdirSync23, readFileSync as readFileSync28, rmSync as rmSync14, writeFileSync as writeFileSync19 } from "node:fs";
33229
33376
  import { homedir as homedir27 } from "node:os";
33230
33377
  function onboardingLockPath(home = homedir27()) {
33231
33378
  return onboardingLockFile(home);
@@ -33256,7 +33403,7 @@ function acquireOnboardingLock(home = homedir27()) {
33256
33403
  const held = readLock(path);
33257
33404
  if (held && held.pid !== process.pid && processAlive(held.pid))
33258
33405
  return null;
33259
- mkdirSync22(stateDir(home), { recursive: true });
33406
+ mkdirSync23(stateDir(home), { recursive: true });
33260
33407
  const body = { pid: process.pid, startedAt: Date.now() };
33261
33408
  writeFileSync19(path, JSON.stringify(body), "utf8");
33262
33409
  let released = false;
@@ -33268,7 +33415,7 @@ function acquireOnboardingLock(home = homedir27()) {
33268
33415
  try {
33269
33416
  const current = readLock(path);
33270
33417
  if (!current || current.pid === process.pid)
33271
- rmSync13(path, { force: true });
33418
+ rmSync14(path, { force: true });
33272
33419
  } catch {}
33273
33420
  }
33274
33421
  };
@@ -33281,8 +33428,8 @@ var init_onboarding_lock = __esm(() => {
33281
33428
  });
33282
33429
 
33283
33430
  // 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";
33431
+ import { readdirSync as readdirSync19, statSync as statSync26, existsSync as existsSync37 } from "node:fs";
33432
+ import { join as join35, basename as basename9 } from "node:path";
33286
33433
  function getClaudeProjectsRoot() {
33287
33434
  return getClaudeProjectsPath();
33288
33435
  }
@@ -33297,7 +33444,7 @@ function listClaudeProjects() {
33297
33444
  return entries.filter((e) => e.isDirectory()).map((e) => ({
33298
33445
  name: e.name,
33299
33446
  cwd: decodeFolderName(e.name),
33300
- path: join34(root, e.name)
33447
+ path: join35(root, e.name)
33301
33448
  }));
33302
33449
  }
33303
33450
  function listClaudeTranscripts(project) {
@@ -33313,9 +33460,9 @@ function listClaudeTranscripts(project) {
33313
33460
  const sessionId = entry.name.slice(0, -".jsonl".length);
33314
33461
  if (!UUID_RE2.test(sessionId))
33315
33462
  continue;
33316
- const transcriptPath = join34(project.path, entry.name);
33463
+ const transcriptPath = join35(project.path, entry.name);
33317
33464
  try {
33318
- const s = statSync25(transcriptPath);
33465
+ const s = statSync26(transcriptPath);
33319
33466
  out.push({
33320
33467
  projectName: project.name,
33321
33468
  cwd: project.cwd,
@@ -33327,8 +33474,8 @@ function listClaudeTranscripts(project) {
33327
33474
  });
33328
33475
  } catch {}
33329
33476
  } else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
33330
- const subDir = join34(project.path, entry.name, "subagents");
33331
- if (!existsSync36(subDir))
33477
+ const subDir = join35(project.path, entry.name, "subagents");
33478
+ if (!existsSync37(subDir))
33332
33479
  continue;
33333
33480
  let subEntries;
33334
33481
  try {
@@ -33340,9 +33487,9 @@ function listClaudeTranscripts(project) {
33340
33487
  if (!sub.isFile() || !sub.name.endsWith(".jsonl"))
33341
33488
  continue;
33342
33489
  const agentId = sub.name.slice(0, -".jsonl".length);
33343
- const transcriptPath = join34(subDir, sub.name);
33490
+ const transcriptPath = join35(subDir, sub.name);
33344
33491
  try {
33345
- const s = statSync25(transcriptPath);
33492
+ const s = statSync26(transcriptPath);
33346
33493
  out.push({
33347
33494
  projectName: project.name,
33348
33495
  cwd: project.cwd,
@@ -33558,7 +33705,7 @@ var init_claude = __esm(() => {
33558
33705
  });
33559
33706
 
33560
33707
  // src/audit/cli-adapters/codex.ts
33561
- import { statSync as statSync26 } from "node:fs";
33708
+ import { statSync as statSync27 } from "node:fs";
33562
33709
  async function listCodexTranscriptMetadata(opts = {}) {
33563
33710
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33564
33711
  const sinceMs = opts.sinceMs ?? 0;
@@ -33575,7 +33722,7 @@ async function listCodexTranscriptMetadata(opts = {}) {
33575
33722
  continue;
33576
33723
  let sizeBytes = 0;
33577
33724
  try {
33578
- sizeBytes = statSync26(s.path).size;
33725
+ sizeBytes = statSync27(s.path).size;
33579
33726
  } catch {}
33580
33727
  if (!s.sessionId)
33581
33728
  continue;
@@ -33609,7 +33756,7 @@ var init_codex = __esm(() => {
33609
33756
  });
33610
33757
 
33611
33758
  // src/audit/cli-adapters/copilot.ts
33612
- import { statSync as statSync27 } from "node:fs";
33759
+ import { statSync as statSync28 } from "node:fs";
33613
33760
  async function listCopilotTranscriptMetadata(opts = {}) {
33614
33761
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33615
33762
  const sinceMs = opts.sinceMs ?? 0;
@@ -33626,7 +33773,7 @@ async function listCopilotTranscriptMetadata(opts = {}) {
33626
33773
  continue;
33627
33774
  let sizeBytes = 0;
33628
33775
  try {
33629
- sizeBytes = statSync27(s.path).size;
33776
+ sizeBytes = statSync28(s.path).size;
33630
33777
  } catch {}
33631
33778
  if (!s.sessionId)
33632
33779
  continue;
@@ -33660,7 +33807,7 @@ var init_copilot = __esm(() => {
33660
33807
  });
33661
33808
 
33662
33809
  // src/audit/cli-adapters/cursor.ts
33663
- import { statSync as statSync28 } from "node:fs";
33810
+ import { statSync as statSync29 } from "node:fs";
33664
33811
  async function listCursorTranscriptMetadata(opts = {}) {
33665
33812
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33666
33813
  const sinceMs = opts.sinceMs ?? 0;
@@ -33677,7 +33824,7 @@ async function listCursorTranscriptMetadata(opts = {}) {
33677
33824
  continue;
33678
33825
  let sizeBytes = 0;
33679
33826
  try {
33680
- sizeBytes = statSync28(s.path).size;
33827
+ sizeBytes = statSync29(s.path).size;
33681
33828
  } catch {}
33682
33829
  if (!s.sessionId)
33683
33830
  continue;
@@ -33918,7 +34065,7 @@ var init_opencode = __esm(() => {
33918
34065
  });
33919
34066
 
33920
34067
  // src/audit/cli-adapters/pi.ts
33921
- import { statSync as statSync29 } from "node:fs";
34068
+ import { statSync as statSync30 } from "node:fs";
33922
34069
  async function listPiTranscriptMetadata(opts = {}) {
33923
34070
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
33924
34071
  const sinceMs = opts.sinceMs ?? 0;
@@ -33935,7 +34082,7 @@ async function listPiTranscriptMetadata(opts = {}) {
33935
34082
  continue;
33936
34083
  let sizeBytes = 0;
33937
34084
  try {
33938
- sizeBytes = statSync29(s.path).size;
34085
+ sizeBytes = statSync30(s.path).size;
33939
34086
  } catch {}
33940
34087
  if (!s.sessionId)
33941
34088
  continue;
@@ -34671,8 +34818,8 @@ var init_features = __esm(() => {
34671
34818
 
34672
34819
  // src/audit/cache.ts
34673
34820
  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";
34821
+ 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";
34822
+ import { join as join36 } from "node:path";
34676
34823
  function getEngineVersion() {
34677
34824
  if (cachedEngineVersion)
34678
34825
  return cachedEngineVersion;
@@ -34692,7 +34839,7 @@ function getDetectorVersion() {
34692
34839
  function getCachePathFor(transcriptPath) {
34693
34840
  const root = auditCacheDir();
34694
34841
  const key = createHash10("sha1").update(transcriptPath).digest("hex");
34695
- return join35(root, `${key}.json`);
34842
+ return join36(root, `${key}.json`);
34696
34843
  }
34697
34844
  function encodeDetectorState(state) {
34698
34845
  return JSON.stringify(state, (_k, v) => v instanceof Map ? { __map: [...v.entries()] } : v);
@@ -34711,7 +34858,7 @@ function anchorHashFor(transcriptPath, upTo) {
34711
34858
  return null;
34712
34859
  let fd = null;
34713
34860
  try {
34714
- fd = openSync5(transcriptPath, "r");
34861
+ fd = openSync6(transcriptPath, "r");
34715
34862
  const head = Buffer.alloc(Math.min(ANCHOR_WINDOW, upTo));
34716
34863
  readSync5(fd, head, 0, head.length, 0);
34717
34864
  const tailLen = Math.min(ANCHOR_WINDOW, upTo);
@@ -34723,7 +34870,7 @@ function anchorHashFor(transcriptPath, upTo) {
34723
34870
  } finally {
34724
34871
  if (fd !== null) {
34725
34872
  try {
34726
- closeSync5(fd);
34873
+ closeSync6(fd);
34727
34874
  } catch {}
34728
34875
  }
34729
34876
  }
@@ -34732,7 +34879,7 @@ function readCachedTranscript(transcriptPath, mtimeMs, sizeBytes) {
34732
34879
  if (sizeBytes === 0)
34733
34880
  return null;
34734
34881
  const cachePath = getCachePathFor(transcriptPath);
34735
- if (!existsSync37(cachePath))
34882
+ if (!existsSync38(cachePath))
34736
34883
  return null;
34737
34884
  try {
34738
34885
  const raw = readFileSync29(cachePath, "utf-8");
@@ -34774,7 +34921,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result,
34774
34921
  return;
34775
34922
  const cachePath = getCachePathFor(transcriptPath);
34776
34923
  try {
34777
- mkdirSync23(auditCacheDir(), { recursive: true });
34924
+ mkdirSync24(auditCacheDir(), { recursive: true });
34778
34925
  const entry = {
34779
34926
  schemaVersion: CACHE_SCHEMA_VERSION,
34780
34927
  cachedAt: Date.now(),
@@ -34794,7 +34941,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result,
34794
34941
  }
34795
34942
  writeFileSync20(cachePath, JSON.stringify(entry), { encoding: "utf-8", mode: 384 });
34796
34943
  try {
34797
- chmodSync7(cachePath, 384);
34944
+ chmodSync8(cachePath, 384);
34798
34945
  } catch {}
34799
34946
  } catch {}
34800
34947
  }
@@ -35229,14 +35376,14 @@ var init_audit = __esm(() => {
35229
35376
 
35230
35377
  // src/audit/audit-lock.ts
35231
35378
  import {
35232
- closeSync as closeSync6,
35379
+ closeSync as closeSync7,
35233
35380
  linkSync as linkSync2,
35234
- mkdirSync as mkdirSync24,
35235
- openSync as openSync6,
35381
+ mkdirSync as mkdirSync25,
35382
+ openSync as openSync7,
35236
35383
  readFileSync as readFileSync30,
35237
35384
  unlinkSync as unlinkSync7,
35238
35385
  writeFileSync as writeFileSync21,
35239
- writeSync
35386
+ writeSync as writeSync2
35240
35387
  } from "node:fs";
35241
35388
  function acquireAuditLock(source, now = Date.now()) {
35242
35389
  const path = auditLockFile();
@@ -35330,22 +35477,22 @@ function writeLockExclusive(path, info) {
35330
35477
  function createThenWrite(path, body) {
35331
35478
  let fd;
35332
35479
  try {
35333
- fd = openSync6(path, "wx", 384);
35334
- writeSync(fd, body);
35480
+ fd = openSync7(path, "wx", 384);
35481
+ writeSync2(fd, body);
35335
35482
  return true;
35336
35483
  } catch {
35337
35484
  return false;
35338
35485
  } finally {
35339
35486
  if (fd !== undefined) {
35340
35487
  try {
35341
- closeSync6(fd);
35488
+ closeSync7(fd);
35342
35489
  } catch {}
35343
35490
  }
35344
35491
  }
35345
35492
  }
35346
35493
  function ensureRunDir() {
35347
- mkdirSync24(failproofaiHome(), { recursive: true });
35348
- mkdirSync24(runDir(), { recursive: true, mode: 448 });
35494
+ mkdirSync25(failproofaiHome(), { recursive: true });
35495
+ mkdirSync25(runDir(), { recursive: true, mode: 448 });
35349
35496
  }
35350
35497
  var AUDIT_LOCK_MAX_AGE_MS;
35351
35498
  var init_audit_lock = __esm(() => {
@@ -35354,7 +35501,7 @@ var init_audit_lock = __esm(() => {
35354
35501
  });
35355
35502
 
35356
35503
  // src/audit/dashboard-cache.ts
35357
- import { existsSync as existsSync38, readFileSync as readFileSync31 } from "node:fs";
35504
+ import { existsSync as existsSync39, readFileSync as readFileSync31 } from "node:fs";
35358
35505
  function getCachePath() {
35359
35506
  return auditDashboardFile();
35360
35507
  }
@@ -35374,7 +35521,7 @@ function writeDashboardCache(params, result) {
35374
35521
  }
35375
35522
  function readDashboardCacheMeta() {
35376
35523
  const cachePath = getCachePath();
35377
- if (!existsSync38(cachePath))
35524
+ if (!existsSync39(cachePath))
35378
35525
  return null;
35379
35526
  try {
35380
35527
  const raw = readFileSync31(cachePath, "utf-8");
@@ -35601,15 +35748,15 @@ var init_api_server_client = __esm(() => {
35601
35748
  });
35602
35749
 
35603
35750
  // 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";
35751
+ import { existsSync as existsSync40, readFileSync as readFileSync32, readdirSync as readdirSync20, rmSync as rmSync15 } from "node:fs";
35752
+ import { join as join37, resolve as resolve28 } from "node:path";
35606
35753
  function getAuthFilePath() {
35607
35754
  const override = process.env.FAILPROOFAI_AUTH_DIR;
35608
- return override ? join36(override, "session.json") : auditSessionFile();
35755
+ return override ? join37(override, "session.json") : auditSessionFile();
35609
35756
  }
35610
35757
  function readAuth() {
35611
35758
  const p = getAuthFilePath();
35612
- if (!existsSync39(p))
35759
+ if (!existsSync40(p))
35613
35760
  return null;
35614
35761
  try {
35615
35762
  const raw = readFileSync32(p, "utf-8");
@@ -35636,18 +35783,18 @@ function writeAuth(auth) {
35636
35783
  }
35637
35784
  function deleteAuth() {
35638
35785
  const p = getAuthFilePath();
35639
- if (existsSync39(p))
35640
- rmSync14(p, { force: true });
35786
+ if (existsSync40(p))
35787
+ rmSync15(p, { force: true });
35641
35788
  try {
35642
35789
  const root = migrationsDir();
35643
- if (!existsSync39(root))
35790
+ if (!existsSync40(root))
35644
35791
  return;
35645
35792
  for (const entry of readdirSync20(root)) {
35646
35793
  if (!entry.startsWith("backup-layout"))
35647
35794
  continue;
35648
35795
  const copy = resolve28(root, entry, "auth.json");
35649
- if (existsSync39(copy))
35650
- rmSync14(copy, { force: true });
35796
+ if (existsSync40(copy))
35797
+ rmSync15(copy, { force: true });
35651
35798
  }
35652
35799
  } catch {}
35653
35800
  }
@@ -35897,12 +36044,12 @@ var init_harm_report = __esm(() => {
35897
36044
  });
35898
36045
 
35899
36046
  // src/audit/machine-store.ts
35900
- import { existsSync as existsSync40, readFileSync as readFileSync33, rmSync as rmSync15 } from "node:fs";
36047
+ import { existsSync as existsSync41, readFileSync as readFileSync33, rmSync as rmSync16 } from "node:fs";
35901
36048
  import { hostname as hostname5 } from "node:os";
35902
36049
  import { randomUUID as randomUUID4 } from "node:crypto";
35903
36050
  function readMachineIdentity(home) {
35904
36051
  const path = auditMachineFile(home);
35905
- if (!existsSync40(path))
36052
+ if (!existsSync41(path))
35906
36053
  return null;
35907
36054
  try {
35908
36055
  const parsed = JSON.parse(readFileSync33(path, "utf8"));
@@ -36227,9 +36374,9 @@ var init_cli = __esm(() => {
36227
36374
  });
36228
36375
 
36229
36376
  // src/hooks/configure-wizard.ts
36230
- import { existsSync as existsSync41, mkdirSync as mkdirSync25, writeFileSync as writeFileSync22, readFileSync as readFileSync34 } from "node:fs";
36377
+ import { existsSync as existsSync42, mkdirSync as mkdirSync26, writeFileSync as writeFileSync22, readFileSync as readFileSync34 } from "node:fs";
36231
36378
  import { homedir as homedir29 } from "node:os";
36232
- import { dirname as dirname21, resolve as resolve29, sep as sep5 } from "node:path";
36379
+ import { dirname as dirname22, resolve as resolve29, sep as sep5 } from "node:path";
36233
36380
  async function emit(event, props) {
36234
36381
  try {
36235
36382
  await trackHookEvent2(getInstanceId2(), event, props);
@@ -36252,7 +36399,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
36252
36399
  const path = getConfigPathForScope(scope, cwd);
36253
36400
  let config = {};
36254
36401
  try {
36255
- if (existsSync41(path))
36402
+ if (existsSync42(path))
36256
36403
  config = JSON.parse(readFileSync34(path, "utf8"));
36257
36404
  } catch {
36258
36405
  return;
@@ -36397,7 +36544,7 @@ function firstRunMarkerPath() {
36397
36544
  }
36398
36545
  function markLauncherSeen() {
36399
36546
  try {
36400
- mkdirSync25(dirname21(firstRunMarkerPath()), { recursive: true });
36547
+ mkdirSync26(dirname22(firstRunMarkerPath()), { recursive: true });
36401
36548
  writeFileSync22(firstRunMarkerPath(), "1", "utf8");
36402
36549
  } catch {}
36403
36550
  }
@@ -36896,18 +37043,18 @@ var init_configure_wizard = __esm(() => {
36896
37043
  });
36897
37044
 
36898
37045
  // 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";
37046
+ import { existsSync as existsSync43, mkdirSync as mkdirSync27, writeFileSync as writeFileSync23, readdirSync as readdirSync21 } from "node:fs";
37047
+ import { dirname as dirname23, join as join38 } from "node:path";
36901
37048
  function flushRequestPath2(home) {
36902
- return join37(failproofaiHome(home), "state", "flush-request.json");
37049
+ return join38(failproofaiHome(home), "state", "flush-request.json");
36903
37050
  }
36904
37051
  function spoolDirs2(home) {
36905
37052
  const root = spoolDir(home);
36906
37053
  const dirs = [root, customAgentsEventsDir(home)];
36907
- if (!existsSync42(root))
37054
+ if (!existsSync43(root))
36908
37055
  return dirs;
36909
37056
  try {
36910
- return dirs.concat(readdirSync21(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join37(root, e.name)));
37057
+ return dirs.concat(readdirSync21(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join38(root, e.name)));
36911
37058
  } catch {
36912
37059
  return dirs;
36913
37060
  }
@@ -36985,7 +37132,7 @@ async function runFlushCommand2(opts = {}) {
36985
37132
  return { exitCode: 0, pending: 0, lines: nothing };
36986
37133
  }
36987
37134
  const path = flushRequestPath2(home);
36988
- mkdirSync26(dirname22(path), { recursive: true });
37135
+ mkdirSync27(dirname23(path), { recursive: true });
36989
37136
  writeFileSync23(path, `${JSON.stringify({ requestedAtMs: Date.now() }, null, 2)}
36990
37137
  `, {
36991
37138
  mode: 384
@@ -37019,16 +37166,16 @@ var init_flush_cli2 = __esm(() => {
37019
37166
  });
37020
37167
 
37021
37168
  // 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";
37169
+ import { existsSync as existsSync44, mkdirSync as mkdirSync28, writeFileSync as writeFileSync24, readdirSync as readdirSync22, statSync as statSync31 } from "node:fs";
37170
+ import { dirname as dirname24, join as join39 } from "node:path";
37024
37171
  function backfillRequestPath(home) {
37025
- return join38(failproofaiHome(home), "state", "backfill-request.json");
37172
+ return join39(failproofaiHome(home), "state", "backfill-request.json");
37026
37173
  }
37027
37174
  function surveySessions(sinceMs, homeDir) {
37028
37175
  const out = [];
37029
37176
  for (const { cli, dir } of SESSION_DIRS) {
37030
- const root = join38(homeDir, dir);
37031
- if (!existsSync43(root))
37177
+ const root = join39(homeDir, dir);
37178
+ if (!existsSync44(root))
37032
37179
  continue;
37033
37180
  let files = 0;
37034
37181
  let newest = 0;
@@ -37042,13 +37189,13 @@ function surveySessions(sinceMs, homeDir) {
37042
37189
  return;
37043
37190
  }
37044
37191
  for (const e of entries) {
37045
- const p = join38(d, e.name);
37192
+ const p = join39(d, e.name);
37046
37193
  if (e.isDirectory()) {
37047
37194
  walk(p, depth + 1);
37048
37195
  continue;
37049
37196
  }
37050
37197
  try {
37051
- const st = statSync30(p);
37198
+ const st = statSync31(p);
37052
37199
  if (st.mtimeMs >= sinceMs) {
37053
37200
  files += 1;
37054
37201
  newest = Math.max(newest, st.mtimeMs);
@@ -37066,7 +37213,7 @@ function runBackfillCommand(opts = {}) {
37066
37213
  const now = opts.now ?? Date.now();
37067
37214
  const sinceMs = opts.sinceMs ?? now - DEFAULT_BACKFILL_DAYS * 24 * 60 * 60 * 1000;
37068
37215
  const home = failproofaiHome();
37069
- if (!existsSync43(home)) {
37216
+ if (!existsSync44(home)) {
37070
37217
  return {
37071
37218
  exitCode: 1,
37072
37219
  lines: [`No failproofai home at ${home}. Run \`failproofai config\` first.`]
@@ -37098,7 +37245,7 @@ function runBackfillCommand(opts = {}) {
37098
37245
  ]
37099
37246
  };
37100
37247
  }
37101
- const found = surveySessions(sinceMs, dirname23(home));
37248
+ const found = surveySessions(sinceMs, dirname24(home));
37102
37249
  const totalFiles = found.reduce((n, f) => n + f.files, 0);
37103
37250
  const sinceLabel = new Date(sinceMs).toISOString().slice(0, 10);
37104
37251
  const lines = [
@@ -37121,7 +37268,7 @@ function runBackfillCommand(opts = {}) {
37121
37268
  }
37122
37269
  try {
37123
37270
  const path = backfillRequestPath();
37124
- mkdirSync27(dirname23(path), { recursive: true });
37271
+ mkdirSync28(dirname24(path), { recursive: true });
37125
37272
  writeFileSync24(path, `${JSON.stringify({ sinceMs, requestedAtMs: now }, null, 2)}
37126
37273
  `, {
37127
37274
  mode: 384
@@ -37413,7 +37560,7 @@ function surveyReviewableCoverage(cwd) {
37413
37560
  let packsInstalled = false;
37414
37561
  let reviewers;
37415
37562
  try {
37416
- packsInstalled = hasInstalledPacks();
37563
+ packsInstalled = hasInstalledRegexPacks();
37417
37564
  const packs = readInstalledPacks().packs;
37418
37565
  for (const pack of packs) {
37419
37566
  const selected = pack.enabled;
@@ -37602,8 +37749,8 @@ var init_jev_stats = __esm(() => {
37602
37749
  });
37603
37750
 
37604
37751
  // 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";
37752
+ import { chmodSync as chmodSync9, existsSync as existsSync45, statSync as statSync32, unlinkSync as unlinkSync8 } from "node:fs";
37753
+ import { dirname as dirname25 } from "node:path";
37607
37754
  function unknownOption(arg) {
37608
37755
  return OPTION_SHAPE.test(arg) ? `Unknown option: ${arg}` : "Unknown option (not repeated here, in case it carries a key).";
37609
37756
  }
@@ -38155,16 +38302,16 @@ async function setupRun(argv, deps, opts) {
38155
38302
  }
38156
38303
  let fileMode = null;
38157
38304
  try {
38158
- fileMode = statSync31(path).mode & 511;
38305
+ fileMode = statSync32(path).mode & 511;
38159
38306
  } catch {}
38160
- const dir = dirname24(path);
38307
+ const dir = dirname25(path);
38161
38308
  let tightenedDir = null;
38162
38309
  if (process.platform !== "win32") {
38163
38310
  try {
38164
- const before = statSync31(dir).mode & 511;
38311
+ const before = statSync32(dir).mode & 511;
38165
38312
  if ((before & 18) !== 0) {
38166
38313
  const after = before & -19;
38167
- chmodSync8(dir, after);
38314
+ chmodSync9(dir, after);
38168
38315
  tightenedDir = { path: dir, to: after.toString(8).padStart(4, "0") };
38169
38316
  }
38170
38317
  } catch {}
@@ -38283,15 +38430,15 @@ async function cloudSetup(values, bools, opts) {
38283
38430
  }
38284
38431
  if (process.platform !== "win32") {
38285
38432
  try {
38286
- const dir = dirname24(path);
38287
- const before = statSync31(dir).mode & 511;
38433
+ const dir = dirname25(path);
38434
+ const before = statSync32(dir).mode & 511;
38288
38435
  if ((before & 18) !== 0)
38289
- chmodSync8(dir, before & -19);
38436
+ chmodSync9(dir, before & -19);
38290
38437
  } catch {}
38291
38438
  }
38292
38439
  let fileMode = null;
38293
38440
  try {
38294
- fileMode = statSync31(path).mode & 511;
38441
+ fileMode = statSync32(path).mode & 511;
38295
38442
  } catch {}
38296
38443
  const cfg = checked.value;
38297
38444
  const route = jevRoute(cfg);
@@ -38730,7 +38877,7 @@ function remove(argv, opts) {
38730
38877
  if (parsed.positionals.length > 0)
38731
38878
  return fail2([STRAY_ARGUMENT, "", ...JEV_USAGE]);
38732
38879
  const path = jevConfigPath();
38733
- if (!existsSync44(path)) {
38880
+ if (!existsSync45(path)) {
38734
38881
  return ok2(stack(title("failproofai jev remove", "nothing to do", opts), note(`There is no ${path}; Jev is already off.`, opts)));
38735
38882
  }
38736
38883
  try {
@@ -38797,16 +38944,16 @@ var init_jev_cli = __esm(() => {
38797
38944
 
38798
38945
  // src/hooks/fp-config.ts
38799
38946
  import {
38800
- chmodSync as chmodSync9,
38801
- closeSync as closeSync7,
38947
+ chmodSync as chmodSync10,
38948
+ closeSync as closeSync8,
38802
38949
  constants as fsConstants4,
38803
- existsSync as existsSync45,
38950
+ existsSync as existsSync46,
38804
38951
  fstatSync as fstatSync4,
38805
- mkdirSync as mkdirSync28,
38806
- openSync as openSync7,
38952
+ mkdirSync as mkdirSync29,
38953
+ openSync as openSync8,
38807
38954
  readFileSync as readFileSync35,
38808
38955
  readSync as readSync6,
38809
- statSync as statSync32,
38956
+ statSync as statSync33,
38810
38957
  writeFileSync as writeFileSync25
38811
38958
  } from "node:fs";
38812
38959
  function detectLayout2() {
@@ -38816,17 +38963,17 @@ function detectLayout2() {
38816
38963
  return { kind: "current", version: raw };
38817
38964
  return raw.layout > LAYOUT_VERSION ? { kind: "future", found: raw.layout } : { kind: "stale", found: raw.layout };
38818
38965
  }
38819
- if (existsSync45(configFile())) {
38966
+ if (existsSync46(configFile())) {
38820
38967
  const layoutThreePositions = [
38821
38968
  legacy.authJson(),
38822
38969
  legacy.nextAudit(),
38823
38970
  legacy.auditSchedule()
38824
38971
  ];
38825
- if (layoutThreePositions.some((p) => existsSync45(p)))
38972
+ if (layoutThreePositions.some((p) => existsSync46(p)))
38826
38973
  return { kind: "stale", found: 3 };
38827
38974
  return { kind: "current", version: { layout: LAYOUT_VERSION, cli: "" }, inferred: true };
38828
38975
  }
38829
- if (existsSync45(legacy.configToml()))
38976
+ if (existsSync46(legacy.configToml()))
38830
38977
  return { kind: "stale", found: 2 };
38831
38978
  const layoutOneMarkers = [
38832
38979
  legacy.policyConfig(),
@@ -38837,7 +38984,7 @@ function detectLayout2() {
38837
38984
  legacy.ingestCredentials(),
38838
38985
  legacy.auditDashboard()
38839
38986
  ];
38840
- return layoutOneMarkers.some((p) => existsSync45(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
38987
+ return layoutOneMarkers.some((p) => existsSync46(p)) ? { kind: "stale", found: 1 } : { kind: "absent" };
38841
38988
  }
38842
38989
  function readLegacyTomlVersion2(text) {
38843
38990
  const layout = Number(/^\s*layout\s*=\s*(\d+)\s*$/m.exec(text)?.[1]);
@@ -38880,16 +39027,16 @@ var init_fp_home2 = () => {};
38880
39027
 
38881
39028
  // src/hooks/migrations.ts
38882
39029
  import {
38883
- chmodSync as chmodSync10,
38884
- copyFileSync as copyFileSync3,
38885
- existsSync as existsSync46,
38886
- mkdirSync as mkdirSync29,
39030
+ chmodSync as chmodSync11,
39031
+ copyFileSync as copyFileSync4,
39032
+ existsSync as existsSync47,
39033
+ mkdirSync as mkdirSync30,
38887
39034
  readFileSync as readFileSync36,
38888
- renameSync as renameSync12,
38889
- rmSync as rmSync16,
39035
+ renameSync as renameSync13,
39036
+ rmSync as rmSync17,
38890
39037
  writeFileSync as writeFileSync26
38891
39038
  } from "node:fs";
38892
- import { basename as basename9, dirname as dirname25, join as join39, resolve as resolve32 } from "node:path";
39039
+ import { basename as basename10, dirname as dirname26, join as join40, resolve as resolve32 } from "node:path";
38893
39040
  function migrateToLayout42() {
38894
39041
  const moves = [
38895
39042
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -38898,40 +39045,40 @@ function migrateToLayout42() {
38898
39045
  ];
38899
39046
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
38900
39047
  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")
39048
+ moves.push({ from: join40(authDirOverride, "auth.json"), to: join40(authDirOverride, "session.json") }, {
39049
+ from: join40(authDirOverride, "next-audit.json"),
39050
+ to: join40(authDirOverride, "reminder.json")
38904
39051
  });
38905
39052
  }
38906
39053
  const migrated = [];
38907
39054
  for (const { from, to } of moves) {
38908
- if (!existsSync46(from))
39055
+ if (!existsSync47(from))
38909
39056
  continue;
38910
- if (existsSync46(to)) {
38911
- rmSync16(from, { force: true });
39057
+ if (existsSync47(to)) {
39058
+ rmSync17(from, { force: true });
38912
39059
  continue;
38913
39060
  }
38914
- mkdirSync29(dirname25(to), { recursive: true });
39061
+ mkdirSync30(dirname26(to), { recursive: true });
38915
39062
  try {
38916
- renameSync12(from, to);
39063
+ renameSync13(from, to);
38917
39064
  } catch {
38918
39065
  try {
38919
- copyFileSync3(from, to);
39066
+ copyFileSync4(from, to);
38920
39067
  } catch (err) {
38921
39068
  try {
38922
- rmSync16(to, { force: true });
39069
+ rmSync17(to, { force: true });
38923
39070
  } catch {}
38924
39071
  throw err;
38925
39072
  }
38926
- rmSync16(from, { force: true });
39073
+ rmSync17(from, { force: true });
38927
39074
  }
38928
- migrated.push(`${basename9(from)} → audit/${basename9(to)}`);
39075
+ migrated.push(`${basename10(from)} → audit/${basename10(to)}`);
38929
39076
  }
38930
39077
  for (const secret of [auditSessionFile()]) {
38931
- if (!existsSync46(secret))
39078
+ if (!existsSync47(secret))
38932
39079
  continue;
38933
39080
  try {
38934
- chmodSync10(secret, 384);
39081
+ chmodSync11(secret, 384);
38935
39082
  } catch {}
38936
39083
  }
38937
39084
  writeVersionFile({ layout: 4 });
@@ -38962,26 +39109,26 @@ function readLedger2() {
38962
39109
  }
38963
39110
  function appendLedger2(entry) {
38964
39111
  try {
38965
- mkdirSync29(migrationsDir(), { recursive: true });
39112
+ mkdirSync30(migrationsDir(), { recursive: true });
38966
39113
  const all = [...readLedger2(), entry];
38967
39114
  writeFileSync26(migrationLedgerFile(), `${JSON.stringify(all, null, 2)}
38968
39115
  `, "utf8");
38969
39116
  } catch {}
38970
39117
  }
38971
39118
  function backupNameOf2(f) {
38972
- return f.as ?? basename9(f.at());
39119
+ return f.as ?? basename10(f.at());
38973
39120
  }
38974
39121
  function pruneMigratedCredentials2(from) {
38975
39122
  const pruned = [];
38976
39123
  for (let layout = from;layout < LAYOUT_VERSION; layout++) {
38977
39124
  for (const { as, landsAt } of PRUNED_AFTER_SUCCESS2) {
38978
39125
  try {
38979
- if (!existsSync46(landsAt()))
39126
+ if (!existsSync47(landsAt()))
38980
39127
  continue;
38981
39128
  const copy = resolve32(migrationBackupDir(layout), as);
38982
- if (!existsSync46(copy))
39129
+ if (!existsSync47(copy))
38983
39130
  continue;
38984
- rmSync16(copy, { force: true });
39131
+ rmSync17(copy, { force: true });
38985
39132
  pruned.push(as);
38986
39133
  } catch {}
38987
39134
  }
@@ -38992,7 +39139,7 @@ function filesToBackUp2() {
38992
39139
  const seen = new Map;
38993
39140
  for (const f of [...BACKED_UP2, ...BACKED_UP_LEGACY2]) {
38994
39141
  const path = f.at();
38995
- if (existsSync46(path))
39142
+ if (existsSync47(path))
38996
39143
  seen.set(path, backupNameOf2(f));
38997
39144
  }
38998
39145
  return [...seen].map(([path, as]) => ({ path, as }));
@@ -39001,14 +39148,14 @@ function backupBeforeMigrating2(from) {
39001
39148
  const dir = migrationBackupDir(from);
39002
39149
  const saved = [];
39003
39150
  try {
39004
- rmSync16(dir, { recursive: true, force: true });
39005
- mkdirSync29(dir, { recursive: true });
39151
+ rmSync17(dir, { recursive: true, force: true });
39152
+ mkdirSync30(dir, { recursive: true });
39006
39153
  } catch {
39007
39154
  return [];
39008
39155
  }
39009
39156
  for (const { path: source, as } of filesToBackUp2()) {
39010
39157
  try {
39011
- copyFileSync3(source, resolve32(dir, as));
39158
+ copyFileSync4(source, resolve32(dir, as));
39012
39159
  saved.push(as);
39013
39160
  } catch {}
39014
39161
  }
@@ -39140,19 +39287,19 @@ var init_migrations2 = __esm(() => {
39140
39287
  { at: legacy.auditSchedule }
39141
39288
  ];
39142
39289
  PRUNED_AFTER_SUCCESS2 = [
39143
- { as: basename9(legacy.authJson()), landsAt: auditSessionFile }
39290
+ { as: basename10(legacy.authJson()), landsAt: auditSessionFile }
39144
39291
  ];
39145
39292
  });
39146
39293
 
39147
39294
  // src/hooks/daemon-service.ts
39148
39295
  import {
39149
- existsSync as existsSync47,
39150
- mkdirSync as mkdirSync30,
39296
+ existsSync as existsSync48,
39297
+ mkdirSync as mkdirSync31,
39151
39298
  mkdtempSync as mkdtempSync2,
39152
39299
  readFileSync as readFileSync37,
39153
39300
  writeFileSync as writeFileSync27,
39154
39301
  unlinkSync as unlinkSync9,
39155
- rmSync as rmSync17
39302
+ rmSync as rmSync18
39156
39303
  } from "node:fs";
39157
39304
  import { homedir as homedir31, tmpdir as tmpdir3, userInfo as userInfo2 } from "node:os";
39158
39305
  import { resolve as resolve33 } from "node:path";
@@ -39171,13 +39318,13 @@ function resolveFailproofaidBinaryPath2() {
39171
39318
  if (process.env.FAILPROOFAI_DAEMON_BINARY)
39172
39319
  return process.env.FAILPROOFAI_DAEMON_BINARY;
39173
39320
  const downloaded = installedBinaryPath();
39174
- if (existsSync47(downloaded))
39321
+ if (existsSync48(downloaded))
39175
39322
  return downloaded;
39176
39323
  const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT;
39177
39324
  if (packageRoot) {
39178
39325
  for (const profile of ["release", "debug"]) {
39179
39326
  const candidate = resolve33(packageRoot, "target", profile, "failproofaid");
39180
- if (existsSync47(candidate))
39327
+ if (existsSync48(candidate))
39181
39328
  return candidate;
39182
39329
  }
39183
39330
  }
@@ -39208,7 +39355,7 @@ function resolveWorkerCommand2() {
39208
39355
  if (!packageRoot)
39209
39356
  return null;
39210
39357
  const workerScript = resolve33(packageRoot, "dist", "worker.mjs");
39211
- if (!existsSync47(workerScript))
39358
+ if (!existsSync48(workerScript))
39212
39359
  return null;
39213
39360
  return `${shellQuote2(process.execPath)} ${shellQuote2(workerScript)}`;
39214
39361
  }
@@ -39219,7 +39366,7 @@ function resolveCliCommand2() {
39219
39366
  if (!packageRoot)
39220
39367
  return null;
39221
39368
  const cliScript = resolve33(packageRoot, "dist", "cli.mjs");
39222
- if (!existsSync47(cliScript))
39369
+ if (!existsSync48(cliScript))
39223
39370
  return null;
39224
39371
  return `${shellQuote2(process.execPath)} ${shellQuote2(cliScript)}`;
39225
39372
  }
@@ -39233,7 +39380,7 @@ function workerScriptPath2() {
39233
39380
  if (!packageRoot)
39234
39381
  return null;
39235
39382
  const workerScript = resolve33(packageRoot, "dist", "worker.mjs");
39236
- return existsSync47(workerScript) ? workerScript : null;
39383
+ return existsSync48(workerScript) ? workerScript : null;
39237
39384
  }
39238
39385
  function assertUnitSafe2(value, field) {
39239
39386
  if (UNIT_UNSAFE_RE2.test(value)) {
@@ -39315,14 +39462,14 @@ function writePrivilegedFile2(destination, contents, mode = "0644") {
39315
39462
  writeFileSync27(staging, contents, "utf8");
39316
39463
  runPrivileged2("install", ["-m", mode, staging, destination]);
39317
39464
  } finally {
39318
- rmSync17(stagingDir, { recursive: true, force: true });
39465
+ rmSync18(stagingDir, { recursive: true, force: true });
39319
39466
  }
39320
39467
  }
39321
39468
  function removeLegacyUserService2() {
39322
39469
  try {
39323
39470
  if (process.platform === "linux") {
39324
39471
  const legacy = legacySystemdUserUnitPath2();
39325
- if (!existsSync47(legacy))
39472
+ if (!existsSync48(legacy))
39326
39473
  return;
39327
39474
  try {
39328
39475
  execFileSync3("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
@@ -39339,7 +39486,7 @@ function removeLegacyUserService2() {
39339
39486
  } catch {}
39340
39487
  } else {
39341
39488
  const legacyAgent = legacyLaunchAgentPlistPath2();
39342
- if (existsSync47(legacyAgent)) {
39489
+ if (existsSync48(legacyAgent)) {
39343
39490
  try {
39344
39491
  execFileSync3("launchctl", ["unload", "-w", legacyAgent], {
39345
39492
  stdio: "ignore",
@@ -39349,7 +39496,7 @@ function removeLegacyUserService2() {
39349
39496
  unlinkSync9(legacyAgent);
39350
39497
  }
39351
39498
  const legacyDaemon = legacySharedLaunchDaemonPath2();
39352
- if (existsSync47(legacyDaemon)) {
39499
+ if (existsSync48(legacyDaemon)) {
39353
39500
  try {
39354
39501
  runPrivileged2("launchctl", ["unload", "-w", legacyDaemon]);
39355
39502
  } catch {}
@@ -39366,7 +39513,7 @@ function systemdUnitContents2(binaryPath, workerCmd, cliCmd = null) {
39366
39513
  const user = assertUnitSafe2(serviceUser2(), "User");
39367
39514
  assertUnitSafe2(binaryPath, "ExecStart");
39368
39515
  assertUnitSafe2(homedir31(), "HOME");
39369
- const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync47(p));
39516
+ const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync48(p));
39370
39517
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe2(p, "ConditionPathExists")}
39371
39518
  `).join("");
39372
39519
  return `[Unit]
@@ -39472,7 +39619,7 @@ async function installDaemonService2() {
39472
39619
  } else {
39473
39620
  const plistPath = launchdPlistPath2();
39474
39621
  const logDir = logsDir();
39475
- mkdirSync30(logDir, { recursive: true });
39622
+ mkdirSync31(logDir, { recursive: true });
39476
39623
  try {
39477
39624
  runPrivileged2("launchctl", ["unload", plistPath]);
39478
39625
  } catch {}
@@ -39620,7 +39767,7 @@ function daemonServiceStatus2() {
39620
39767
  if (!isDaemonSupportedPlatform2())
39621
39768
  return "unsupported-platform";
39622
39769
  if (process.platform === "linux") {
39623
- if (!existsSync47(systemdUnitPath2()))
39770
+ if (!existsSync48(systemdUnitPath2()))
39624
39771
  return "not-installed";
39625
39772
  try {
39626
39773
  const out = execFileSync3("systemctl", ["is-active", systemdUnitName2()], {
@@ -39633,7 +39780,7 @@ function daemonServiceStatus2() {
39633
39780
  }
39634
39781
  }
39635
39782
  const plistPath = launchdPlistPath2();
39636
- if (!existsSync47(plistPath))
39783
+ if (!existsSync48(plistPath))
39637
39784
  return "not-installed";
39638
39785
  try {
39639
39786
  const root = typeof process.getuid === "function" && process.getuid() === 0;
@@ -39701,7 +39848,7 @@ var init_hermes_update = __esm(() => {
39701
39848
  });
39702
39849
 
39703
39850
  // src/hooks/uninstall-cli.ts
39704
- import { existsSync as existsSync48, rmSync as rmSync18 } from "node:fs";
39851
+ import { existsSync as existsSync49, rmSync as rmSync19 } from "node:fs";
39705
39852
  function survey(cwd) {
39706
39853
  const clis = [];
39707
39854
  for (const id of listInstallableIds()) {
@@ -39722,9 +39869,9 @@ function survey(cwd) {
39722
39869
  return {
39723
39870
  clis,
39724
39871
  servicePath,
39725
- serviceInstalled: !!servicePath && existsSync48(servicePath),
39872
+ serviceInstalled: !!servicePath && existsSync49(servicePath),
39726
39873
  daemonConfigured,
39727
- homeExists: existsSync48(failproofaiHome())
39874
+ homeExists: existsSync49(failproofaiHome())
39728
39875
  };
39729
39876
  }
39730
39877
  async function runUninstallCommand(opts = {}) {
@@ -39822,7 +39969,7 @@ async function runUninstallCommand(opts = {}) {
39822
39969
  } catch {}
39823
39970
  try {
39824
39971
  await uninstallDaemonService();
39825
- if (found.servicePath && existsSync48(found.servicePath)) {
39972
+ if (found.servicePath && existsSync49(found.servicePath)) {
39826
39973
  failures.push(`the service at ${found.servicePath} is still there (most often: no sudo). ` + `Remove it with the commands below.`);
39827
39974
  } else {
39828
39975
  lines.push(`✓ stopped and removed the daemon service`);
@@ -39834,7 +39981,7 @@ async function runUninstallCommand(opts = {}) {
39834
39981
  }
39835
39982
  if (opts.purge && found.homeExists) {
39836
39983
  try {
39837
- rmSync18(failproofaiHome(), { recursive: true, force: true });
39984
+ rmSync19(failproofaiHome(), { recursive: true, force: true });
39838
39985
  purged = true;
39839
39986
  lines.push(`✓ deleted ${failproofaiHome()}`);
39840
39987
  } catch (err) {
@@ -39845,7 +39992,7 @@ async function runUninstallCommand(opts = {}) {
39845
39992
  lines.push(``, `Not everything could be removed:`);
39846
39993
  for (const f of failures)
39847
39994
  lines.push(` ✗ ${f}`);
39848
- if (found.servicePath && existsSync48(found.servicePath)) {
39995
+ if (found.servicePath && existsSync49(found.servicePath)) {
39849
39996
  lines.push(``, `To remove the service by hand:`, ...manualServiceRemoval(found.servicePath), ``, `(\`${daemonStatusCommand()}\` shows its current state.)`);
39850
39997
  }
39851
39998
  return { exitCode: 1, lines, planLines, purged };
@@ -39879,8 +40026,8 @@ var init_uninstall_cli = __esm(() => {
39879
40026
  import { execFileSync as execFileSync4 } from "node:child_process";
39880
40027
  import { homedir as homedir32, tmpdir as tmpdir4 } from "node:os";
39881
40028
  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";
40029
+ 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";
40030
+ 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
40031
  function parseList(rest, ...flags) {
39885
40032
  let found = false;
39886
40033
  const out = [];
@@ -40016,7 +40163,7 @@ async function build(rest) {
40016
40163
  return fail3([err instanceof Error ? err.message : String(err)]);
40017
40164
  }
40018
40165
  const entryPath = resolve34(entry);
40019
- if (!existsSync49(entryPath))
40166
+ if (!existsSync50(entryPath))
40020
40167
  return fail3([`No such file: ${entryPath}`]);
40021
40168
  const source = readFileSync38(entryPath, "utf8");
40022
40169
  const localImport = firstRelativeSpecifier(source);
@@ -40137,11 +40284,11 @@ async function build(rest) {
40137
40284
  ...semantic.length > 0 ? { semantic } : {}
40138
40285
  }, null, 2) + `
40139
40286
  `;
40140
- mkdirSync31(outDir, { recursive: true });
40287
+ mkdirSync32(outDir, { recursive: true });
40141
40288
  const manifestPath = resolve34(outDir, PACK_MANIFEST_ASSET);
40142
40289
  const entryOut = resolve34(outDir, PACK_ENTRY_ASSET);
40143
40290
  writeFileSync28(manifestPath, manifest, "utf8");
40144
- copyFileSync4(entryPath, entryOut);
40291
+ copyFileSync5(entryPath, entryOut);
40145
40292
  const sha = (bytes) => createHash11("sha256").update(bytes).digest("hex");
40146
40293
  writeFileSync28(resolve34(outDir, PACK_CHECKSUMS_ASSET), `${sha(manifest)} ${PACK_MANIFEST_ASSET}
40147
40294
  ${sha(readFileSync38(entryOut))} ${PACK_ENTRY_ASSET}
@@ -40285,10 +40432,10 @@ async function scaffold(target) {
40285
40432
  chosen = answer.trim();
40286
40433
  }
40287
40434
  const path = resolve34(withPolicyExtension(chosen ?? "my-policies"));
40288
- if (existsSync49(path)) {
40435
+ if (existsSync50(path)) {
40289
40436
  return fail3([`${path} already exists — name a different file, or edit that one.`]);
40290
40437
  }
40291
- mkdirSync31(resolve34(path, ".."), { recursive: true });
40438
+ mkdirSync32(resolve34(path, ".."), { recursive: true });
40292
40439
  writeFileSync28(path, `import { customPolicies, allow, deny } from "failproofai";
40293
40440
 
40294
40441
  // One file, no relative imports: only this entry is digest-pinned, so a pack
@@ -40387,7 +40534,7 @@ function porcelainEntries(status) {
40387
40534
  }
40388
40535
  function realOrSelf(path) {
40389
40536
  try {
40390
- return realpathSync4(path);
40537
+ return realpathSync5(path);
40391
40538
  } catch {
40392
40539
  return path;
40393
40540
  }
@@ -40479,7 +40626,7 @@ function findEntry(dir) {
40479
40626
  continue;
40480
40627
  const full = resolve34(dir, name);
40481
40628
  try {
40482
- if (statSync33(full).size > 512 * 1024)
40629
+ if (statSync34(full).size > 512 * 1024)
40483
40630
  continue;
40484
40631
  const text = readFileSync38(full, "utf8");
40485
40632
  if (/from\s+["']failproofai["']/.test(text) && /(?:customPolicies|semanticPolicies)\s*\.\s*add\s*\(/.test(text)) {
@@ -40498,7 +40645,7 @@ function withLocalImports(sources) {
40498
40645
  const file = queue.shift();
40499
40646
  let text;
40500
40647
  try {
40501
- if (statSync33(file).size > 512 * 1024)
40648
+ if (statSync34(file).size > 512 * 1024)
40502
40649
  continue;
40503
40650
  text = readFileSync38(file, "utf8");
40504
40651
  } catch {
@@ -40506,13 +40653,13 @@ function withLocalImports(sources) {
40506
40653
  }
40507
40654
  for (const re of LOCAL_IMPORT_RES) {
40508
40655
  for (const match of text.matchAll(re)) {
40509
- const base = resolve34(dirname26(file), match[1]);
40656
+ const base = resolve34(dirname27(file), match[1]);
40510
40657
  for (const ext of LOCAL_IMPORT_EXTENSIONS) {
40511
40658
  const candidate = base + ext;
40512
40659
  if (seen.has(candidate))
40513
40660
  break;
40514
40661
  try {
40515
- if (!statSync33(candidate).isFile())
40662
+ if (!statSync34(candidate).isFile())
40516
40663
  continue;
40517
40664
  } catch {
40518
40665
  continue;
@@ -40737,7 +40884,7 @@ function pushExistingHistory(dir, owner, name, token) {
40737
40884
  const branch = git(["rev-parse", "--abbrev-ref", "HEAD"]);
40738
40885
  if (!branch || branch === "HEAD" || !git(["rev-parse", "--verify", "HEAD"]))
40739
40886
  return false;
40740
- const askpass = join40(mkdtempSync3(join40(tmpdir4(), "fpai-askpass-")), "askpass.sh");
40887
+ const askpass = join41(mkdtempSync3(join41(tmpdir4(), "fpai-askpass-")), "askpass.sh");
40741
40888
  try {
40742
40889
  writeFileSync28(askpass, `#!/bin/sh
40743
40890
  case "$1" in
@@ -40759,7 +40906,7 @@ esac
40759
40906
  return true;
40760
40907
  } finally {
40761
40908
  try {
40762
- rmSync19(dirname26(askpass), { recursive: true, force: true });
40909
+ rmSync20(dirname27(askpass), { recursive: true, force: true });
40763
40910
  } catch {}
40764
40911
  }
40765
40912
  }
@@ -40810,7 +40957,7 @@ function bundleEntry(sources, outDir) {
40810
40957
  ]
40811
40958
  };
40812
40959
  }
40813
- mkdirSync31(outDir, { recursive: true });
40960
+ mkdirSync32(outDir, { recursive: true });
40814
40961
  const entry = resolve34(outDir, ".entry.generated.mjs");
40815
40962
  writeFileSync28(entry, sources.map((f) => `import ${JSON.stringify(f.startsWith("/") ? f : resolve34(f))};`).join(`
40816
40963
  `) + `
@@ -40942,12 +41089,12 @@ async function publish(rest) {
40942
41089
  if (askingWhere) {
40943
41090
  const found = discovered.length > 0 ? discovered : [entry];
40944
41091
  process.stdout.write(`
40945
- ${found.length} policy ${found.length === 1 ? "file" : "files"}: ` + `${found.map((f) => basename10(f)).join(", ")}
41092
+ ${found.length} policy ${found.length === 1 ? "file" : "files"}: ` + `${found.map((f) => basename11(f)).join(", ")}
40946
41093
 
40947
41094
  `);
40948
41095
  const token = githubToken();
40949
41096
  const login = token ? await credentialLogin(token) : null;
40950
- const folder = basename10(resolve34(entry, ".."));
41097
+ const folder = basename11(resolve34(entry, ".."));
40951
41098
  const answered = await askWhereToPublish(`${login ?? "your-account"}/${folder}`, { stdin: process.stdin, stdout: process.stdout });
40952
41099
  if (answered === null)
40953
41100
  return ok3(["Nothing was published."]);
@@ -40958,7 +41105,7 @@ async function publish(rest) {
40958
41105
  let versionFromSha = false;
40959
41106
  const dryRun = rest.includes("--dry-run") || !repo;
40960
41107
  const allowPrivate = rest.includes("--allow-private");
40961
- const id = flag("id") ?? repo ?? (dryRun && entry ? `local/${basename10(resolve34(entry, ".."))}` : undefined);
41108
+ const id = flag("id") ?? repo ?? (dryRun && entry ? `local/${basename11(resolve34(entry, ".."))}` : undefined);
40962
41109
  const [owner, name] = (repo ?? "/").split("/");
40963
41110
  if (repo && (!owner || !name || repo.split("/").length !== 2)) {
40964
41111
  return fail3([`--repo must be <owner>/<repo>, got ${JSON.stringify(repo)}`]);
@@ -41905,8 +42052,8 @@ var init_install_prompt = __esm(() => {
41905
42052
 
41906
42053
  // src/hooks/manager.ts
41907
42054
  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";
42055
+ import { existsSync as existsSync51 } from "node:fs";
42056
+ import { resolve as resolve35, basename as basename12 } from "node:path";
41910
42057
  import { platform as platform4, arch as arch4, release as release3, hostname as hostname6 } from "node:os";
41911
42058
  function getSettingsPath2(scope, cwd) {
41912
42059
  return claudeCode.getSettingsPath(scope, cwd);
@@ -42137,7 +42284,7 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
42137
42284
  } else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
42138
42285
  const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path) => resolve35(path));
42139
42286
  const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path) => resolve35(path)).filter((path) => {
42140
- if (existsSync50(path))
42287
+ if (existsSync51(path))
42141
42288
  return true;
42142
42289
  console.log(`Dropping custom policies path (file no longer exists): ${path}`);
42143
42290
  return false;
@@ -42369,7 +42516,7 @@ async function removeHooks2(policyNames, scope = "user", cwd, opts) {
42369
42516
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
42370
42517
  for (const s of scopesToRemove) {
42371
42518
  const settingsPaths = settingsPathsFor(integration, s, cwd);
42372
- const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync50(p));
42519
+ const existing = cliId === "hermes" ? settingsPaths : settingsPaths.filter((p) => existsSync51(p));
42373
42520
  if (existing.length === 0) {
42374
42521
  if (scope !== "all" && selectedClis.length === 1) {
42375
42522
  console.log("No settings file found. Nothing to remove.");
@@ -42522,7 +42669,7 @@ async function listHooks(cwd) {
42522
42669
  for (const path of explicitPaths) {
42523
42670
  const absPath = resolve35(findProjectConfigDir(cwd ?? process.cwd()), path);
42524
42671
  groups.push(note(absPath, opts));
42525
- if (!existsSync50(absPath)) {
42672
+ if (!existsSync51(absPath)) {
42526
42673
  groups.push(warning([`file not found: ${absPath}`], opts));
42527
42674
  continue;
42528
42675
  }
@@ -42567,7 +42714,7 @@ async function listHooks(cwd) {
42567
42714
  groups.push(note(dir, opts));
42568
42715
  const rows = [];
42569
42716
  for (const file of files) {
42570
- const filename = basename11(file);
42717
+ const filename = basename12(file);
42571
42718
  try {
42572
42719
  const hooks = await loadCustomHooks(file);
42573
42720
  record(filename, hooks.map((h) => h.name));
@@ -43091,26 +43238,26 @@ function parseScriptArgs(argv) {
43091
43238
  var init_parse_script_args = () => {};
43092
43239
 
43093
43240
  // 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";
43241
+ import { existsSync as existsSync52, readFileSync as readFileSync40, realpathSync as realpathSync6 } from "node:fs";
43242
+ import { dirname as dirname28, resolve as resolve37 } from "node:path";
43096
43243
  import { homedir as homedir33, platform as platform5 } from "node:os";
43097
43244
  import { spawnSync } from "node:child_process";
43098
43245
  function findPackageRoot(start) {
43099
43246
  try {
43100
- let dir = realpathSync5(start);
43101
- if (existsSync51(dir) && !existsSync51(resolve37(dir, "package.json"))) {
43102
- dir = dirname27(dir);
43247
+ let dir = realpathSync6(start);
43248
+ if (existsSync52(dir) && !existsSync52(resolve37(dir, "package.json"))) {
43249
+ dir = dirname28(dir);
43103
43250
  }
43104
43251
  while (true) {
43105
43252
  const pkgPath = resolve37(dir, "package.json");
43106
- if (existsSync51(pkgPath)) {
43253
+ if (existsSync52(pkgPath)) {
43107
43254
  try {
43108
43255
  const pkg = JSON.parse(readFileSync40(pkgPath, "utf8"));
43109
43256
  if (pkg.name === PKG_NAME)
43110
43257
  return dir;
43111
43258
  } catch {}
43112
43259
  }
43113
- const parent = dirname27(dir);
43260
+ const parent = dirname28(dir);
43114
43261
  if (parent === dir)
43115
43262
  return null;
43116
43263
  dir = parent;
@@ -43150,7 +43297,7 @@ function locateNpmGlobal() {
43150
43297
  if (!root)
43151
43298
  return null;
43152
43299
  const candidate = resolve37(root, PKG_NAME);
43153
- return existsSync51(resolve37(candidate, "package.json")) ? candidate : null;
43300
+ return existsSync52(resolve37(candidate, "package.json")) ? candidate : null;
43154
43301
  } catch {
43155
43302
  return null;
43156
43303
  }
@@ -43158,7 +43305,7 @@ function locateNpmGlobal() {
43158
43305
  function locateBunGlobal() {
43159
43306
  try {
43160
43307
  const candidate = resolve37(homedir33(), ".bun", "install", "global", "node_modules", PKG_NAME);
43161
- return existsSync51(resolve37(candidate, "package.json")) ? candidate : null;
43308
+ return existsSync52(resolve37(candidate, "package.json")) ? candidate : null;
43162
43309
  } catch {
43163
43310
  return null;
43164
43311
  }
@@ -43177,7 +43324,7 @@ function buildRecommendation(pathFirstBin) {
43177
43324
  function diagnoseShadow(self) {
43178
43325
  const selfPackageRoot = (() => {
43179
43326
  try {
43180
- return self?.selfPackageRoot ? realpathSync5(self.selfPackageRoot) : null;
43327
+ return self?.selfPackageRoot ? realpathSync6(self.selfPackageRoot) : null;
43181
43328
  } catch {
43182
43329
  return self?.selfPackageRoot ?? null;
43183
43330
  }
@@ -43261,8 +43408,8 @@ var init_dashboard_host = __esm(() => {
43261
43408
 
43262
43409
  // scripts/launch.ts
43263
43410
  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";
43411
+ import { realpathSync as realpathSync7, existsSync as existsSync53 } from "node:fs";
43412
+ import { resolve as resolve38, dirname as dirname29 } from "node:path";
43266
43413
  import { fileURLToPath as fileURLToPath2 } from "node:url";
43267
43414
  import { createInterface } from "node:readline";
43268
43415
  function launch(mode) {
@@ -43286,9 +43433,9 @@ function launch(mode) {
43286
43433
  process.env.PORT = port;
43287
43434
  process.env.HOSTNAME = bindHost;
43288
43435
  cmd = "node";
43289
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve38(dirname28(realpathSync6(fileURLToPath2(import.meta.url))), "..");
43436
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve38(dirname29(realpathSync7(fileURLToPath2(import.meta.url))), "..");
43290
43437
  const serverJsPath = resolve38(packageRoot, ".next/standalone/server.js");
43291
- if (!existsSync52(serverJsPath)) {
43438
+ if (!existsSync53(serverJsPath)) {
43292
43439
  let shadowMessage = null;
43293
43440
  try {
43294
43441
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -44063,23 +44210,40 @@ import {
44063
44210
  cpSync as cpSync2,
44064
44211
  readFileSync as readFileSync41,
44065
44212
  writeFileSync as writeFileSync29,
44066
- existsSync as existsSync53,
44067
- lstatSync as lstatSync3,
44068
- mkdirSync as mkdirSync32,
44213
+ existsSync as existsSync54,
44214
+ lstatSync as lstatSync4,
44215
+ mkdirSync as mkdirSync33,
44069
44216
  readlinkSync as readlinkSync2,
44070
- realpathSync as realpathSync7,
44071
- renameSync as renameSync13,
44072
- rmSync as rmSync20,
44217
+ realpathSync as realpathSync8,
44218
+ renameSync as renameSync14,
44219
+ rmSync as rmSync21,
44073
44220
  symlinkSync as symlinkSync2,
44074
44221
  unlinkSync as unlinkSync10
44075
44222
  } from "node:fs";
44076
- import { resolve as resolve39, dirname as dirname29, basename as basename12 } from "node:path";
44223
+ import { resolve as resolve39, dirname as dirname30, basename as basename13 } from "node:path";
44077
44224
  import { fileURLToPath as fileURLToPath3 } from "node:url";
44078
44225
  function readYamlDoc2(path) {
44226
+ if (!existsSync54(path))
44227
+ return $parseDocument("");
44228
+ let text;
44229
+ try {
44230
+ text = readFileSync41(path, "utf8");
44231
+ } catch (err) {
44232
+ throw new UnreadableAgentConfigError2(path, `it could not be read (${err instanceof Error ? err.message : String(err)})`);
44233
+ }
44234
+ const doc = $parseDocument(text);
44235
+ if (doc.errors.length > 0) {
44236
+ const first = doc.errors[0]?.message.split(`
44237
+ `)[0] ?? "syntax error";
44238
+ throw new UnreadableAgentConfigError2(path, `it does not parse as YAML (${first})`);
44239
+ }
44240
+ return doc;
44241
+ }
44242
+ function inspectYamlDoc2(path) {
44079
44243
  try {
44080
- return existsSync53(path) ? $parseDocument(readFileSync41(path, "utf8")) : $parseDocument("");
44244
+ return readYamlDoc2(path);
44081
44245
  } catch {
44082
- return $parseDocument("");
44246
+ return null;
44083
44247
  }
44084
44248
  }
44085
44249
  function isMarkedHook2(hook) {
@@ -44095,18 +44259,31 @@ function getHermesPluginSourcePath2() {
44095
44259
  const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
44096
44260
  if (fromEnv)
44097
44261
  return resolve39(fromEnv, HERMES_PLUGIN_SOURCE_DIR2);
44098
- return resolve39(fileURLToPath3(import.meta.url), "..", "..", "..", HERMES_PLUGIN_SOURCE_DIR2);
44262
+ return findHermesPluginSourcePath2(dirname30(fileURLToPath3(import.meta.url)));
44263
+ }
44264
+ function findHermesPluginSourcePath2(startDir) {
44265
+ let dir = resolve39(startDir);
44266
+ for (let i = 0;i < 8; i++) {
44267
+ const candidate = resolve39(dir, HERMES_PLUGIN_SOURCE_DIR2);
44268
+ if (existsSync54(resolve39(candidate, "plugin.yaml")))
44269
+ return candidate;
44270
+ const parent = dirname30(dir);
44271
+ if (parent === dir)
44272
+ break;
44273
+ dir = parent;
44274
+ }
44275
+ return resolve39(startDir, "..", "..", HERMES_PLUGIN_SOURCE_DIR2);
44099
44276
  }
44100
44277
  function hermesPluginPathForSettings2(settingsPath) {
44101
- return resolve39(dirname29(settingsPath), "plugins", HERMES_PLUGIN_ID2);
44278
+ return resolve39(dirname30(settingsPath), "plugins", HERMES_PLUGIN_ID2);
44102
44279
  }
44103
44280
  function hasAllHermesPluginFiles2(dir) {
44104
- return HERMES_PLUGIN_FILES2.every((file) => existsSync53(resolve39(dir, file)));
44281
+ return HERMES_PLUGIN_FILES2.every((file) => existsSync54(resolve39(dir, file)));
44105
44282
  }
44106
44283
  function isFailproofaiHermesPluginSource2(dir) {
44107
- if (basename12(dir) !== HERMES_PLUGIN_SOURCE_DIR2)
44284
+ if (basename13(dir) !== HERMES_PLUGIN_SOURCE_DIR2)
44108
44285
  return false;
44109
- if (!existsSync53(dir))
44286
+ if (!existsSync54(dir))
44110
44287
  return true;
44111
44288
  try {
44112
44289
  const manifest = readFileSync41(resolve39(dir, "plugin.yaml"), "utf8");
@@ -44119,7 +44296,7 @@ function samePath2(a, b) {
44119
44296
  if (resolve39(a) === resolve39(b))
44120
44297
  return true;
44121
44298
  try {
44122
- return realpathSync7(a) === realpathSync7(b);
44299
+ return realpathSync8(a) === realpathSync8(b);
44123
44300
  } catch {
44124
44301
  return false;
44125
44302
  }
@@ -44129,7 +44306,7 @@ function hermesPluginState2(settingsPath) {
44129
44306
  let isLink;
44130
44307
  let isDirectory;
44131
44308
  try {
44132
- const stat = lstatSync3(pluginPath);
44309
+ const stat = lstatSync4(pluginPath);
44133
44310
  isLink = stat.isSymbolicLink();
44134
44311
  isDirectory = stat.isDirectory();
44135
44312
  } catch {
@@ -44138,7 +44315,7 @@ function hermesPluginState2(settingsPath) {
44138
44315
  if (isLink) {
44139
44316
  let target;
44140
44317
  try {
44141
- target = resolve39(dirname29(pluginPath), readlinkSync2(pluginPath));
44318
+ target = resolve39(dirname30(pluginPath), readlinkSync2(pluginPath));
44142
44319
  } catch {
44143
44320
  return { kind: "foreign" };
44144
44321
  }
@@ -44151,16 +44328,18 @@ function hermesPluginState2(settingsPath) {
44151
44328
  current: samePath2(target, getHermesPluginSourcePath2())
44152
44329
  };
44153
44330
  }
44154
- if (isDirectory && existsSync53(resolve39(pluginPath, HERMES_PLUGIN_MARKER2))) {
44331
+ if (isDirectory && existsSync54(resolve39(pluginPath, HERMES_PLUGIN_MARKER2))) {
44155
44332
  return { kind: "copy", complete: hasAllHermesPluginFiles2(pluginPath) };
44156
44333
  }
44157
44334
  return { kind: "foreign" };
44158
44335
  }
44159
44336
  function hermesConfigState2(settingsPath) {
44160
- if (!existsSync53(settingsPath)) {
44337
+ if (!existsSync54(settingsPath)) {
44161
44338
  return { pluginEnabled: false, legacyShellHookPresent: false };
44162
44339
  }
44163
- const doc = readYamlDoc2(settingsPath);
44340
+ const doc = inspectYamlDoc2(settingsPath);
44341
+ if (!doc)
44342
+ return { pluginEnabled: false, legacyShellHookPresent: false, unreadable: true };
44164
44343
  const js = doc.toJS() ?? {};
44165
44344
  const enabled = js.plugins?.enabled;
44166
44345
  const legacyShellHookPresent = !!js.hooks && typeof js.hooks === "object" && Object.values(js.hooks).some((entries) => Array.isArray(entries) && entries.some((entry) => isMarkedHook2(entry)));
@@ -44185,13 +44364,17 @@ function hermesProfileHealth() {
44185
44364
  pluginEnabled: config.pluginEnabled,
44186
44365
  legacyShellHookPresent: config.legacyShellHookPresent,
44187
44366
  cronUnchecked: config.legacyShellHookPresent && !pluginWorks,
44188
- healthy: pluginWorks && !config.legacyShellHookPresent
44367
+ configUnreadable: config.unreadable === true,
44368
+ healthy: pluginWorks && !config.legacyShellHookPresent && config.unreadable !== true
44189
44369
  };
44190
44370
  });
44191
44371
  }
44192
44372
  function hermesProfileStatusRows() {
44193
- return hermesProfileHealth().filter((profile) => existsSync53(profile.home)).map((profile) => {
44373
+ return hermesProfileHealth().filter((profile) => existsSync54(profile.home)).map((profile) => {
44194
44374
  const label = "hermes/" + profile.name;
44375
+ if (profile.configUnreadable) {
44376
+ return [label, `UNHEALTHY — ${profile.settingsPath} does not parse; failproofai leaves it untouched until it is fixed`];
44377
+ }
44195
44378
  if (profile.cronUnchecked) {
44196
44379
  return [
44197
44380
  label,
@@ -44213,20 +44396,29 @@ function hermesProfileStatusRows() {
44213
44396
  ];
44214
44397
  });
44215
44398
  }
44216
- var HERMES_PLUGIN_ID2 = "failproofai", HERMES_PLUGIN_MARKER2 = ".failproofai-managed", HERMES_PLUGIN_FILES2, HERMES_PLUGIN_SOURCE_DIR2 = "hermes-plugin", ANTIGRAVITY_TOOL_EVENTS2;
44399
+ var UnreadableAgentConfigError2, HERMES_PLUGIN_ID2 = "failproofai", HERMES_PLUGIN_MARKER2 = ".failproofai-managed", HERMES_PLUGIN_FILES2, HERMES_PLUGIN_SOURCE_DIR2 = "hermes-plugin", ANTIGRAVITY_TOOL_EVENTS2;
44217
44400
  var init_integrations2 = __esm(() => {
44218
44401
  init_dist();
44402
+ init_safe_config_write();
44219
44403
  init_hermes_profiles();
44220
44404
  init_openclaw_profiles();
44221
44405
  init_types();
44406
+ UnreadableAgentConfigError2 = class UnreadableAgentConfigError2 extends Error {
44407
+ path;
44408
+ constructor(path, reason) {
44409
+ super(`Refusing to modify ${path}: ${reason}. ` + `failproofai never rewrites a config it could not parse — fix or move the file, then retry.`);
44410
+ this.path = path;
44411
+ this.name = "UnreadableAgentConfigError";
44412
+ }
44413
+ };
44222
44414
  HERMES_PLUGIN_FILES2 = ["plugin.yaml", "__init__.py", "client.py", "ledger.py"];
44223
44415
  ANTIGRAVITY_TOOL_EVENTS2 = new Set(["PreToolUse", "PostToolUse"]);
44224
44416
  });
44225
44417
 
44226
44418
  // scripts/launch.ts
44227
44419
  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";
44420
+ import { realpathSync as realpathSync9, existsSync as existsSync55 } from "node:fs";
44421
+ import { resolve as resolve40, dirname as dirname31 } from "node:path";
44230
44422
  import { fileURLToPath as fileURLToPath4 } from "node:url";
44231
44423
  import { createInterface as createInterface2 } from "node:readline";
44232
44424
  function launch2(mode) {
@@ -44250,9 +44442,9 @@ function launch2(mode) {
44250
44442
  process.env.PORT = port;
44251
44443
  process.env.HOSTNAME = bindHost;
44252
44444
  cmd = "node";
44253
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve40(dirname30(realpathSync8(fileURLToPath4(import.meta.url))), "..");
44445
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve40(dirname31(realpathSync9(fileURLToPath4(import.meta.url))), "..");
44254
44446
  const serverJsPath = resolve40(packageRoot, ".next/standalone/server.js");
44255
- if (!existsSync54(serverJsPath)) {
44447
+ if (!existsSync55(serverJsPath)) {
44256
44448
  let shadowMessage = null;
44257
44449
  try {
44258
44450
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -44348,18 +44540,18 @@ var init_cli_error2 = __esm(() => {
44348
44540
  });
44349
44541
 
44350
44542
  // bin/failproofai.mjs
44351
- import { realpathSync as realpathSync9 } from "fs";
44352
- import { dirname as dirname31, resolve as resolve41 } from "path";
44543
+ import { realpathSync as realpathSync10 } from "fs";
44544
+ import { dirname as dirname32, resolve as resolve41 } from "path";
44353
44545
  import { fileURLToPath as fileURLToPath5 } from "url";
44354
44546
  // package.json
44355
- var version = "1.0.9-beta.0";
44547
+ var version = "1.0.9-beta.1";
44356
44548
 
44357
44549
  // bin/failproofai.mjs
44358
44550
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
44359
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve41(dirname31(realpathSync9(fileURLToPath5(import.meta.url))), "..");
44551
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve41(dirname32(realpathSync10(fileURLToPath5(import.meta.url))), "..");
44360
44552
  }
44361
44553
  if (!process.env.FAILPROOFAI_DIST_PATH) {
44362
- process.env.FAILPROOFAI_DIST_PATH = resolve41(dirname31(realpathSync9(fileURLToPath5(import.meta.url))), "..", "dist");
44554
+ process.env.FAILPROOFAI_DIST_PATH = resolve41(dirname32(realpathSync10(fileURLToPath5(import.meta.url))), "..", "dist");
44363
44555
  }
44364
44556
  var args = process.argv.slice(2);
44365
44557
  if (args[0] === "p" || args[0] === "policy")