failproofai 0.0.10-beta.2 → 0.0.10-beta.4

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 (123) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  6. package/.next/standalone/.next/server/app/_global-error/page.js +2 -2
  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 +2 -2
  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/_head.segment.rsc +3 -3
  14. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
  15. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  18. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/_not-found.html +2 -2
  21. package/.next/standalone/.next/server/app/_not-found.rsc +15 -15
  22. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +15 -15
  23. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  24. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +10 -10
  25. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  26. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  27. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  28. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -2
  29. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/index.html +1 -1
  31. package/.next/standalone/.next/server/app/index.rsc +15 -15
  32. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  33. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +15 -15
  34. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
  35. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +10 -10
  36. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  38. package/.next/standalone/.next/server/app/page.js +2 -2
  39. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +8 -8
  42. package/.next/standalone/.next/server/app/policies/page.js +2 -2
  43. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  45. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  46. package/.next/standalone/.next/server/app/project/[name]/page.js +3 -3
  47. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  50. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +3 -3
  52. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  55. package/.next/standalone/.next/server/app/projects/page.js +2 -2
  56. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/chunks/[root-of-the-server]__06.arfm._.js +3 -0
  59. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0__i0h0._.js +3 -0
  60. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0dtn9lr._.js → [root-of-the-server]__0d_ob4n._.js} +2 -2
  61. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fe7_q_._.js +3 -0
  62. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fjhqi9._.js +3 -0
  63. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0fw.e.h._.js +3 -0
  64. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0kjo7d_._.js +1 -1
  65. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0pxn0e1._.js +3 -0
  66. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0xv0jh2._.js +3 -0
  67. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__010i6f5._.js → [root-of-the-server]__0z-180.._.js} +2 -2
  68. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_0z7w.hh._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0dl0kgt._.js → [root-of-the-server]__01hj~sd._.js} +3 -3
  70. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0s~gy6y._.js → [root-of-the-server]__02r6nu-._.js} +2 -2
  71. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bz245.._.js → [root-of-the-server]__04dywib._.js} +3 -3
  72. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0gmhxyo._.js → [root-of-the-server]__06sb2gn._.js} +3 -3
  73. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0tt8-uq._.js → [root-of-the-server]__092oklx._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0-2wr.c._.js → [root-of-the-server]__09jpajs._.js} +3 -3
  75. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ils1oq._.js → [root-of-the-server]__0bemgh7._.js} +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0qbpe_v._.js → [root-of-the-server]__0jm6jnh._.js} +2 -2
  77. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0709m8.._.js → [root-of-the-server]__0joez.y._.js} +3 -3
  78. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0ohb3gc._.js → [root-of-the-server]__0mi5ejy._.js} +3 -3
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u1i~9~._.js +4 -0
  80. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__09y9okz._.js → [root-of-the-server]__0x5limi._.js} +2 -2
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ymlddl._.js +5 -3
  82. package/.next/standalone/.next/server/chunks/ssr/_10lm7or._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/app_0cdqd9w._.js +1 -1
  84. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_0xerkr6._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_0q-m0y-._.js +1 -1
  86. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  87. package/.next/standalone/.next/server/pages/404.html +2 -2
  88. package/.next/standalone/.next/server/pages/500.html +1 -1
  89. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  90. package/.next/standalone/.next/server/server-reference-manifest.json +9 -9
  91. package/.next/standalone/.next/static/chunks/{0yzl~f-qji0...js → 0csfsu88oqir8.js} +2 -2
  92. package/.next/standalone/.next/static/chunks/{0y8oyen~jnjl3.js → 0fvemi0q_n349.js} +1 -1
  93. package/.next/standalone/.next/static/chunks/{0a_w-lcg.0tl7.js → 0ilx6hm27porg.js} +1 -1
  94. package/.next/standalone/.next/static/chunks/0kxi65pnos15e.js +1 -0
  95. package/.next/standalone/.next/static/chunks/{0-dltnti0ew4y.js → 12mx5dzs_vf1w.js} +1 -1
  96. package/.next/standalone/.next/static/chunks/{17o7-pn_xzt-t.js → 14p_4ajxz0ifs.js} +1 -1
  97. package/.next/standalone/.next/static/chunks/{0lscbfo_2_h14.js → 16ydic9u8kagt.js} +2 -2
  98. package/.next/standalone/.next/static/chunks/{02h_cfxpk4x9..js → 18daqyhykpw8z.js} +1 -1
  99. package/.next/standalone/app/api/download/[project]/[session]/route.ts +26 -10
  100. package/.next/standalone/app/components/session-hooks-panel.tsx +3 -0
  101. package/.next/standalone/app/policies/hooks-client.tsx +3 -0
  102. package/.next/standalone/app/project/[name]/session/[sessionId]/page.tsx +8 -10
  103. package/.next/standalone/lib/download-session.ts +92 -0
  104. package/.next/standalone/lib/opencode-sessions.ts +42 -0
  105. package/.next/standalone/package.json +1 -1
  106. package/.next/standalone/server.js +1 -1
  107. package/dist/cli.mjs +1281 -305
  108. package/lib/download-session.ts +92 -0
  109. package/lib/opencode-sessions.ts +42 -0
  110. package/package.json +1 -1
  111. package/src/hooks/builtin-policies.ts +4 -3
  112. package/src/hooks/handler.ts +22 -12
  113. package/src/hooks/integrations.ts +2 -0
  114. package/src/hooks/policy-evaluator.ts +47 -6
  115. package/src/hooks/resolve-transcript-path.ts +69 -0
  116. package/src/hooks/types.ts +73 -0
  117. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b57.gk._.js +0 -3
  118. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0z4c5dj._.js +0 -3
  119. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0.~m-w2._.js +0 -4
  120. package/.next/standalone/.next/static/chunks/16k5y9ruha2v4.js +0 -1
  121. /package/.next/standalone/.next/static/{EBbXdrT2rHib3zGLSuY7Q → Z3pK8z9QuEdJFE28LwB5Y}/_buildManifest.js +0 -0
  122. /package/.next/standalone/.next/static/{EBbXdrT2rHib3zGLSuY7Q → Z3pK8z9QuEdJFE28LwB5Y}/_clientMiddlewareManifest.js +0 -0
  123. /package/.next/standalone/.next/static/{EBbXdrT2rHib3zGLSuY7Q → Z3pK8z9QuEdJFE28LwB5Y}/_ssgManifest.js +0 -0
package/dist/cli.mjs CHANGED
@@ -16,7 +16,7 @@ var __export = (target, all) => {
16
16
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
17
 
18
18
  // src/hooks/types.ts
19
- var HOOK_SCOPES, INTEGRATION_TYPES, CODEX_HOOK_SCOPES, CODEX_HOOK_EVENT_TYPES, CODEX_EVENT_MAP, COPILOT_HOOK_SCOPES, COPILOT_HOOK_EVENT_TYPES, COPILOT_TOOL_MAP, CURSOR_HOOK_SCOPES, CURSOR_HOOK_EVENT_TYPES, CURSOR_EVENT_MAP, OPENCODE_HOOK_SCOPES, OPENCODE_HOOK_EVENT_TYPES, PI_HOOK_SCOPES, PI_HOOK_EVENT_TYPES, PI_EVENT_MAP, GEMINI_HOOK_SCOPES, GEMINI_HOOK_EVENT_TYPES, GEMINI_EVENT_MAP, GEMINI_TOOL_MAP, HOOK_EVENT_TYPES, FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
19
+ var HOOK_SCOPES, INTEGRATION_TYPES, CODEX_HOOK_SCOPES, CODEX_HOOK_EVENT_TYPES, CODEX_EVENT_MAP, CODEX_TOOL_MAP, COPILOT_HOOK_SCOPES, COPILOT_HOOK_EVENT_TYPES, COPILOT_TOOL_MAP, CURSOR_HOOK_SCOPES, CURSOR_HOOK_EVENT_TYPES, CURSOR_EVENT_MAP, CURSOR_TOOL_MAP, OPENCODE_HOOK_SCOPES, OPENCODE_HOOK_EVENT_TYPES, PI_HOOK_SCOPES, PI_HOOK_EVENT_TYPES, PI_EVENT_MAP, GEMINI_HOOK_SCOPES, GEMINI_HOOK_EVENT_TYPES, GEMINI_EVENT_MAP, GEMINI_TOOL_MAP, HOOK_EVENT_TYPES, FAILPROOFAI_HOOK_MARKER = "__failproofai_hook__";
20
20
  var init_types = __esm(() => {
21
21
  HOOK_SCOPES = ["user", "project", "local"];
22
22
  INTEGRATION_TYPES = ["claude", "codex", "copilot", "cursor", "opencode", "pi", "gemini"];
@@ -37,6 +37,10 @@ var init_types = __esm(() => {
37
37
  user_prompt_submit: "UserPromptSubmit",
38
38
  stop: "Stop"
39
39
  };
40
+ CODEX_TOOL_MAP = {
41
+ apply_patch: "Edit",
42
+ write_stdin: "Bash"
43
+ };
40
44
  COPILOT_HOOK_SCOPES = ["user", "project"];
41
45
  COPILOT_HOOK_EVENT_TYPES = [
42
46
  "SessionStart",
@@ -44,17 +48,33 @@ var init_types = __esm(() => {
44
48
  "UserPromptSubmit",
45
49
  "PreToolUse",
46
50
  "PostToolUse",
47
- "Stop"
51
+ "Stop",
52
+ "SubagentStop"
48
53
  ];
49
54
  COPILOT_TOOL_MAP = {
50
55
  bash: "Bash",
56
+ powershell: "Bash",
57
+ list_bash: "Bash",
58
+ read_bash: "Bash",
59
+ stop_bash: "Bash",
60
+ write_bash: "Bash",
61
+ list_powershell: "Bash",
62
+ read_powershell: "Bash",
63
+ stop_powershell: "Bash",
64
+ write_powershell: "Bash",
51
65
  read: "Read",
66
+ view: "Read",
67
+ show_file: "Read",
52
68
  write: "Write",
69
+ create: "Write",
53
70
  edit: "Edit",
71
+ apply_patch: "Edit",
54
72
  str_replace_editor: "Edit",
55
73
  glob: "Glob",
56
74
  grep: "Grep",
57
- ls: "LS"
75
+ rg: "Grep",
76
+ ls: "LS",
77
+ web_fetch: "WebFetch"
58
78
  };
59
79
  CURSOR_HOOK_SCOPES = ["user", "project"];
60
80
  CURSOR_HOOK_EVENT_TYPES = [
@@ -73,6 +93,9 @@ var init_types = __esm(() => {
73
93
  postToolUse: "PostToolUse",
74
94
  stop: "Stop"
75
95
  };
96
+ CURSOR_TOOL_MAP = {
97
+ Shell: "Bash"
98
+ };
76
99
  OPENCODE_HOOK_SCOPES = ["user", "project"];
77
100
  OPENCODE_HOOK_EVENT_TYPES = [
78
101
  "tool.execute.before",
@@ -956,7 +979,8 @@ function blockWorkOnMain(ctx) {
956
979
  if (ctx.toolName !== "Bash")
957
980
  return allow();
958
981
  const cmd = getCommand(ctx);
959
- if (!GIT_COMMIT_MERGE_RE.test(cmd))
982
+ const match = cmd.match(GIT_COMMIT_MERGE_RE);
983
+ if (!match)
960
984
  return allow();
961
985
  const cwd = ctx.session?.cwd;
962
986
  if (!cwd)
@@ -966,7 +990,7 @@ function blockWorkOnMain(ctx) {
966
990
  return allow();
967
991
  const protectedBranches = ctx.params?.protectedBranches ?? ["main", "master"];
968
992
  if (protectedBranches.includes(branch)) {
969
- return deny(`Git ${cmd.match(/git\s+(\S+)/)?.[1] ?? "operation"} on ${branch} is blocked. Create a feature branch first.`);
993
+ return deny(`Git ${match[1]} on ${branch} is blocked. Create a feature branch first.`);
970
994
  }
971
995
  return allow();
972
996
  }
@@ -1459,7 +1483,7 @@ var init_builtin_policies = __esm(() => {
1459
1483
  SECRET_FILE_RE = /\.(?:pem|key)$/;
1460
1484
  SECRET_FILE_ID_RSA_RE = /id_rsa/;
1461
1485
  SECRET_FILE_CREDENTIALS_RE = /credentials/;
1462
- GIT_COMMIT_MERGE_RE = /git\s+(?:commit|merge|rebase|cherry-pick)\b/;
1486
+ GIT_COMMIT_MERGE_RE = /git\s+(commit|merge|rebase|cherry-pick)\b/;
1463
1487
  FAILPROOFAI_CLI_RE = /(?:^|;|&&|\|\||\|)\s*failproofai(?:\s|$)/;
1464
1488
  FAILPROOFAI_UNINSTALL_RE = /(?:npm\s+(?:uninstall|remove|un|r)\s.*failproofai|bun\s+remove\s.*failproofai|yarn\s+global\s+remove\s+failproofai|pnpm\s+(?:remove|uninstall|un)\s.*failproofai)/;
1465
1489
  GIT_AMEND_RE = /\bgit\s+commit\b.*--amend\b/;
@@ -2138,13 +2162,24 @@ You MUST complete the above action NOW. Do NOT ask the user for confirmation —
2138
2162
  decision: "deny"
2139
2163
  };
2140
2164
  }
2141
- if (eventType === "Stop") {
2165
+ if (eventType === "Stop" || eventType === "SubagentStop") {
2166
+ const reasonText = `MANDATORY ACTION REQUIRED from failproofai (policy: ${policy.name}): ${reason}
2167
+
2168
+ You MUST complete the above action NOW. Do NOT ask the user for confirmation — execute the required action, then attempt to finish your task again.`;
2169
+ if (session?.cli === "copilot") {
2170
+ return {
2171
+ exitCode: 0,
2172
+ stdout: JSON.stringify({ decision: "block", reason: reasonText }),
2173
+ stderr: "",
2174
+ policyName: policy.name,
2175
+ reason,
2176
+ decision: "deny"
2177
+ };
2178
+ }
2142
2179
  return {
2143
2180
  exitCode: 2,
2144
2181
  stdout: "",
2145
- stderr: `MANDATORY ACTION REQUIRED from failproofai (policy: ${policy.name}): ${reason}
2146
-
2147
- You MUST complete the above action NOW. Do NOT ask the user for confirmation — execute the required action, then attempt to finish your task again.`,
2182
+ stderr: reasonText,
2148
2183
  policyName: policy.name,
2149
2184
  reason,
2150
2185
  decision: "deny"
@@ -2264,14 +2299,26 @@ You MUST complete the above action(s) NOW. Do NOT ask the user for confirmation
2264
2299
  decision: "instruct"
2265
2300
  };
2266
2301
  }
2267
- if (eventType === "Stop") {
2302
+ if (eventType === "Stop" || eventType === "SubagentStop") {
2268
2303
  const policyAttribution = policyNames.length === 1 ? `policy: ${policyNames[0]}` : `policies: ${policyNames.join(", ")}`;
2304
+ const reasonText = `MANDATORY ACTION REQUIRED from failproofai (${policyAttribution}): ${combined}
2305
+
2306
+ You MUST complete the above action(s) NOW. Do NOT ask the user for confirmation — execute the required action(s), then attempt to finish your task again.`;
2307
+ if (session?.cli === "copilot") {
2308
+ return {
2309
+ exitCode: 0,
2310
+ stdout: JSON.stringify({ decision: "block", reason: reasonText }),
2311
+ stderr: "",
2312
+ policyName: policyNames[0],
2313
+ policyNames,
2314
+ reason: combined,
2315
+ decision: "instruct"
2316
+ };
2317
+ }
2269
2318
  return {
2270
2319
  exitCode: 2,
2271
2320
  stdout: "",
2272
- stderr: `MANDATORY ACTION REQUIRED from failproofai (${policyAttribution}): ${combined}
2273
-
2274
- You MUST complete the above action(s) NOW. Do NOT ask the user for confirmation — execute the required action(s), then attempt to finish your task again.`,
2321
+ stderr: reasonText,
2275
2322
  policyName: policyNames[0],
2276
2323
  policyNames,
2277
2324
  reason: combined,
@@ -2770,7 +2817,7 @@ var init_hook_activity_store = __esm(() => {
2770
2817
  });
2771
2818
 
2772
2819
  // package.json
2773
- var version2 = "0.0.10-beta.2";
2820
+ var version2 = "0.0.10-beta.4";
2774
2821
  var init_package = () => {};
2775
2822
 
2776
2823
  // src/posthog-key.ts
@@ -4713,161 +4760,1085 @@ var init_resolve_permission_mode = __esm(() => {
4713
4760
  init_codex_sessions();
4714
4761
  });
4715
4762
 
4716
- // lib/telemetry-id.ts
4717
- import fs from "node:fs";
4718
- import path from "node:path";
4719
- import os from "node:os";
4720
- import crypto from "node:crypto";
4721
- import { execSync as execSync2 } from "node:child_process";
4722
- function hashToId(raw) {
4723
- return crypto.createHmac("sha256", NAMESPACE).update(raw).digest("hex");
4763
+ // lib/copilot-sessions.ts
4764
+ import { readFileSync as readFileSync5, readdirSync as readdirSync4, existsSync as existsSync6, statSync as statSync5 } from "node:fs";
4765
+ import { readFile as readFile9 } from "node:fs/promises";
4766
+ import { join as join14, resolve as resolve6, sep as sep2 } from "node:path";
4767
+ import { homedir as homedir13 } from "node:os";
4768
+ function getCopilotHome() {
4769
+ return process.env.COPILOT_HOME || join14(homedir13(), ".copilot");
4724
4770
  }
4725
- function getPlatformMachineId() {
4771
+ function getCopilotSessionStateRoot2() {
4772
+ return join14(getCopilotHome(), "session-state");
4773
+ }
4774
+ function getCopilotSessionDir(sessionId) {
4775
+ if (!sessionId)
4776
+ return null;
4777
+ const root = resolve6(getCopilotSessionStateRoot2());
4778
+ const candidate = resolve6(root, sessionId);
4779
+ if (candidate === root || !candidate.startsWith(`${root}${sep2}`))
4780
+ return null;
4781
+ return candidate;
4782
+ }
4783
+ function resolveSessionFile(sessionId, filename) {
4784
+ const dir = getCopilotSessionDir(sessionId);
4785
+ if (!dir)
4786
+ return null;
4787
+ return join14(dir, filename);
4788
+ }
4789
+ function findCopilotTranscript(sessionId) {
4790
+ const candidate = resolveSessionFile(sessionId, "events.jsonl");
4791
+ if (!candidate)
4792
+ return null;
4793
+ return existsSync6(candidate) ? candidate : null;
4794
+ }
4795
+ function findCopilotWorkspace(sessionId) {
4796
+ const candidate = resolveSessionFile(sessionId, "workspace.yaml");
4797
+ if (!candidate)
4798
+ return null;
4799
+ return existsSync6(candidate) ? candidate : null;
4800
+ }
4801
+ function readYamlScalar(path, key) {
4726
4802
  try {
4727
- const platform = os.platform();
4728
- if (platform === "linux") {
4729
- for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
4730
- try {
4731
- const id = fs.readFileSync(p, "utf-8").trim();
4732
- if (id)
4733
- return id;
4734
- } catch {}
4803
+ const text = readFileSync5(path, "utf-8");
4804
+ const re = new RegExp(`^${key}\\s*:\\s*(.+?)\\s*$`, "m");
4805
+ const m = text.match(re);
4806
+ if (!m)
4807
+ return;
4808
+ return m[1].replace(/^['"]|['"]$/g, "");
4809
+ } catch {
4810
+ return;
4811
+ }
4812
+ }
4813
+ function readCopilotWorkspaceCwd(sessionId) {
4814
+ const path = findCopilotWorkspace(sessionId);
4815
+ if (!path)
4816
+ return;
4817
+ return readYamlScalar(path, "cwd");
4818
+ }
4819
+ async function parseCopilotLog(fileContent, source = "session") {
4820
+ const lines = fileContent.split(`
4821
+ `).filter((line) => line.trim() !== "");
4822
+ const entries = [];
4823
+ const rawLines = [];
4824
+ const toolUseById = new Map;
4825
+ const toolUseStartMs = new Map;
4826
+ let cwd;
4827
+ let seenSessionStart = false;
4828
+ for (let i = 0;i < lines.length; i++) {
4829
+ if (i > 0 && i % 200 === 0)
4830
+ await new Promise((r) => setImmediate(r));
4831
+ const line = lines[i];
4832
+ let raw;
4833
+ try {
4834
+ raw = JSON.parse(line);
4835
+ } catch {
4836
+ continue;
4837
+ }
4838
+ const rawCopy = { ...raw, _source: source };
4839
+ rawLines.push(rawCopy);
4840
+ const timestampStr = raw.timestamp;
4841
+ if (!timestampStr)
4842
+ continue;
4843
+ const date = new Date(timestampStr);
4844
+ if (Number.isNaN(date.getTime()))
4845
+ continue;
4846
+ const timestamp = date.toISOString();
4847
+ const recType = raw.type;
4848
+ const data = raw.data ?? {};
4849
+ if (recType === "session.start") {
4850
+ const ctx = data.context;
4851
+ const c = ctx?.cwd;
4852
+ if (typeof c === "string" && !cwd)
4853
+ cwd = c;
4854
+ const label = seenSessionStart ? "Session Resumed" : "Session Started";
4855
+ seenSessionStart = true;
4856
+ entries.push({
4857
+ type: "queue-operation",
4858
+ ...baseEntry(rawCopy, timestamp, date, source),
4859
+ label
4860
+ });
4861
+ continue;
4862
+ }
4863
+ if (recType === "user.message") {
4864
+ const text = data.content ?? "";
4865
+ if (!text)
4866
+ continue;
4867
+ entries.push({
4868
+ type: "user",
4869
+ ...baseEntry(rawCopy, timestamp, date, source),
4870
+ message: { role: "user", content: text }
4871
+ });
4872
+ continue;
4873
+ }
4874
+ if (recType === "system.message") {
4875
+ entries.push({
4876
+ type: "system",
4877
+ ...baseEntry(rawCopy, timestamp, date, source),
4878
+ raw: rawCopy
4879
+ });
4880
+ continue;
4881
+ }
4882
+ if (recType === "assistant.message") {
4883
+ const text = data.content ?? "";
4884
+ if (!text) {
4885
+ entries.push({
4886
+ type: "system",
4887
+ ...baseEntry(rawCopy, timestamp, date, source),
4888
+ raw: rawCopy
4889
+ });
4890
+ continue;
4735
4891
  }
4736
- } else if (platform === "darwin") {
4737
- const out = execSync2("ioreg -rd1 -c IOPlatformExpertDevice", {
4738
- encoding: "utf-8",
4739
- timeout: 3000
4892
+ const blocks = [{ type: "text", text }];
4893
+ entries.push({
4894
+ type: "assistant",
4895
+ ...baseEntry(rawCopy, timestamp, date, source),
4896
+ message: { role: "assistant", content: blocks }
4740
4897
  });
4741
- const m = out.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
4742
- if (m?.[1])
4743
- return m[1];
4744
- } else if (platform === "win32") {
4745
- const out = execSync2('reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid', { encoding: "utf-8", timeout: 3000 });
4746
- const m = out.match(/MachineGuid\s+REG_SZ\s+(\S+)/);
4747
- if (m?.[1])
4748
- return m[1];
4898
+ continue;
4749
4899
  }
4750
- } catch {}
4751
- return;
4752
- }
4753
- function getSystemPropertiesId() {
4754
- return [
4755
- os.hostname(),
4756
- os.homedir(),
4757
- os.platform(),
4758
- os.arch(),
4759
- os.cpus()[0]?.model ?? ""
4760
- ].join(":");
4900
+ if (recType === "tool.execution_start") {
4901
+ const callId = data.toolCallId;
4902
+ const name = data.toolName ?? "tool";
4903
+ const args = data.arguments ?? {};
4904
+ const id = callId ?? `${date.getTime()}-${name}`;
4905
+ const toolUse = {
4906
+ type: "tool_use",
4907
+ id,
4908
+ name,
4909
+ input: args
4910
+ };
4911
+ const entry = {
4912
+ type: "assistant",
4913
+ ...baseEntry(rawCopy, timestamp, date, source),
4914
+ message: { role: "assistant", content: [toolUse] }
4915
+ };
4916
+ entries.push(entry);
4917
+ if (callId) {
4918
+ toolUseById.set(callId, toolUse);
4919
+ toolUseStartMs.set(callId, date.getTime());
4920
+ }
4921
+ continue;
4922
+ }
4923
+ if (recType === "tool.execution_complete") {
4924
+ const callId = data.toolCallId;
4925
+ const block = callId ? toolUseById.get(callId) : undefined;
4926
+ if (block) {
4927
+ const startMs = toolUseStartMs.get(callId) ?? date.getTime();
4928
+ const result = data.result ?? {};
4929
+ const telemetry = data.toolTelemetry ?? {};
4930
+ const reportedMs = telemetry.metrics?.commandTimeMs ?? telemetry.metrics?.durationMs ?? null;
4931
+ const durationMs = typeof reportedMs === "number" && reportedMs >= 0 ? reportedMs : Math.max(0, date.getTime() - startMs);
4932
+ const content = result.detailedContent ?? result.content ?? "";
4933
+ block.result = {
4934
+ timestamp,
4935
+ timestampFormatted: formatTimestamp(date),
4936
+ content: typeof content === "string" ? content : JSON.stringify(content),
4937
+ durationMs,
4938
+ durationFormatted: formatDuration(durationMs)
4939
+ };
4940
+ continue;
4941
+ }
4942
+ entries.push({
4943
+ type: "system",
4944
+ ...baseEntry(rawCopy, timestamp, date, source),
4945
+ raw: rawCopy
4946
+ });
4947
+ continue;
4948
+ }
4949
+ entries.push({
4950
+ type: "system",
4951
+ ...baseEntry(rawCopy, timestamp, date, source),
4952
+ raw: rawCopy
4953
+ });
4954
+ }
4955
+ if (entries.length > 500)
4956
+ await new Promise((r) => setImmediate(r));
4957
+ entries.sort((a, b) => a.timestampMs - b.timestampMs);
4958
+ return { entries, rawLines, cwd };
4761
4959
  }
4762
- function getFileBasedId() {
4763
- try {
4764
- const existing = fs.readFileSync(ID_FILE, "utf-8").trim();
4765
- if (existing)
4766
- return existing;
4767
- } catch {}
4768
- const id = crypto.randomUUID();
4960
+ async function getCopilotSessionLog(sessionId) {
4961
+ const filePath = findCopilotTranscript(sessionId);
4962
+ if (!filePath)
4963
+ return null;
4964
+ let fileContent;
4769
4965
  try {
4770
- fs.mkdirSync(ID_DIR, { recursive: true });
4771
- fs.writeFileSync(ID_FILE, id, "utf-8");
4772
- } catch {}
4773
- return id;
4774
- }
4775
- function getInstanceId() {
4776
- if (cachedId)
4777
- return cachedId;
4778
- const machineId = getPlatformMachineId();
4779
- if (machineId) {
4780
- cachedId = hashToId(machineId);
4781
- return cachedId;
4782
- }
4783
- const sysProps = getSystemPropertiesId();
4784
- if (sysProps) {
4785
- cachedId = hashToId(sysProps);
4786
- return cachedId;
4966
+ fileContent = await readFile9(filePath, "utf-8");
4967
+ } catch {
4968
+ return null;
4787
4969
  }
4788
- cachedId = getFileBasedId();
4789
- return cachedId;
4970
+ const { entries, rawLines, cwd } = await parseCopilotLog(fileContent, "session");
4971
+ const resolvedCwd = cwd ?? readCopilotWorkspaceCwd(sessionId);
4972
+ return { entries, rawLines, cwd: resolvedCwd, filePath };
4790
4973
  }
4791
- var NAMESPACE = "failproofai-telemetry-v1", ID_DIR, ID_FILE, cachedId;
4792
- var init_telemetry_id = __esm(() => {
4793
- ID_DIR = path.join(os.homedir(), ".failproofai");
4794
- ID_FILE = path.join(ID_DIR, "instance-id");
4974
+ var getCachedCopilotSessionLog;
4975
+ var init_copilot_sessions = __esm(() => {
4976
+ init_log_entries();
4977
+ getCachedCopilotSessionLog = runtimeCache((sessionId) => getCopilotSessionLog(sessionId), 60, { maxSize: 50 });
4795
4978
  });
4796
4979
 
4797
- // src/auth/token-store.ts
4798
- import {
4799
- readFileSync as readFileSync5,
4800
- writeFileSync as writeFileSync4,
4801
- existsSync as existsSync6,
4802
- mkdirSync as mkdirSync5,
4803
- unlinkSync as unlinkSync2,
4804
- renameSync as renameSync3,
4805
- openSync,
4806
- closeSync
4807
- } from "node:fs";
4808
- import { join as join14 } from "node:path";
4809
- import { homedir as homedir13 } from "node:os";
4810
- function ensureAuthDir() {
4811
- if (!existsSync6(AUTH_DIR))
4812
- mkdirSync5(AUTH_DIR, { recursive: true, mode: 448 });
4980
+ // lib/cursor-sessions.ts
4981
+ import { readFileSync as readFileSync6, readdirSync as readdirSync5, existsSync as existsSync7, statSync as statSync6 } from "node:fs";
4982
+ import { readFile as readFile10 } from "node:fs/promises";
4983
+ import { basename as basename3, join as join15, resolve as resolve7, sep as sep3 } from "node:path";
4984
+ import { homedir as homedir14 } from "node:os";
4985
+ function getCursorHome2() {
4986
+ return process.env.CURSOR_HOME || join15(homedir14(), ".cursor");
4813
4987
  }
4814
- function readTokens() {
4815
- if (!existsSync6(AUTH_FILE))
4988
+ function getCursorSessionDir(sessionId) {
4989
+ if (!sessionId)
4816
4990
  return null;
4991
+ const home = resolve7(getCursorHome2());
4992
+ const projectsRoot = resolve7(home, NEW_PROJECTS_DIR2);
4993
+ let projectEntries = [];
4817
4994
  try {
4818
- const raw = readFileSync5(AUTH_FILE, "utf8");
4819
- return JSON.parse(raw);
4820
- } catch {
4821
- return null;
4995
+ projectEntries = readdirSync5(projectsRoot, { withFileTypes: true });
4996
+ } catch {}
4997
+ for (const entry of projectEntries) {
4998
+ if (!entry.isDirectory())
4999
+ continue;
5000
+ const candidate = resolve7(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2, sessionId);
5001
+ const transcriptRoot = resolve7(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
5002
+ if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
5003
+ continue;
5004
+ if (existsSync7(candidate))
5005
+ return candidate;
4822
5006
  }
4823
- }
4824
- function writeTokens(tokens) {
4825
- ensureAuthDir();
4826
- const tmpPath = `${AUTH_FILE}.tmp`;
4827
- const fd = openSync(tmpPath, "w", 384);
4828
- try {
4829
- writeFileSync4(fd, JSON.stringify(tokens, null, 2));
4830
- } finally {
4831
- closeSync(fd);
5007
+ for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
5008
+ const root = resolve7(home, sub);
5009
+ const candidate = resolve7(root, sessionId);
5010
+ if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
5011
+ continue;
5012
+ if (existsSync7(candidate))
5013
+ return candidate;
4832
5014
  }
4833
- renameSync3(tmpPath, AUTH_FILE);
4834
- }
4835
- function clearTokens() {
4836
- if (existsSync6(AUTH_FILE))
4837
- unlinkSync2(AUTH_FILE);
5015
+ return null;
4838
5016
  }
4839
- function isLoggedIn() {
4840
- return existsSync6(AUTH_FILE);
5017
+ function findCursorTranscript(sessionId) {
5018
+ const dir = getCursorSessionDir(sessionId);
5019
+ if (!dir)
5020
+ return null;
5021
+ const newCandidate = join15(dir, `${basename3(dir)}.jsonl`);
5022
+ if (existsSync7(newCandidate))
5023
+ return newCandidate;
5024
+ for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
5025
+ const candidate = join15(dir, name);
5026
+ if (existsSync7(candidate))
5027
+ return candidate;
5028
+ }
5029
+ return null;
4841
5030
  }
4842
- var AUTH_DIR, AUTH_FILE;
4843
- var init_token_store = __esm(() => {
4844
- AUTH_DIR = join14(homedir13(), ".failproofai");
4845
- AUTH_FILE = join14(AUTH_DIR, "auth.json");
4846
- });
4847
-
4848
- // src/relay/queue.ts
4849
- var exports_queue = {};
4850
- __export(exports_queue, {
4851
- readProcessingFile: () => readProcessingFile,
4852
- queueSizeBytes: () => queueSizeBytes,
4853
- findOrphanProcessingFiles: () => findOrphanProcessingFiles,
4854
- deleteProcessingFile: () => deleteProcessingFile,
4855
- claimPendingBatch: () => claimPendingBatch,
4856
- appendToServerQueue: () => appendToServerQueue
4857
- });
4858
- import {
5031
+ async function parseCursorLog(fileContent, source = "session") {
5032
+ const lines = fileContent.split(`
5033
+ `).filter((line) => line.trim() !== "");
5034
+ const entries = [];
5035
+ const rawLines = [];
5036
+ const toolUseById = new Map;
5037
+ const toolUseStartMs = new Map;
5038
+ let cwd;
5039
+ let seenSessionStart = false;
5040
+ const SYNTH_T0 = Date.now();
5041
+ for (let i = 0;i < lines.length; i++) {
5042
+ if (i > 0 && i % 200 === 0)
5043
+ await new Promise((r) => setImmediate(r));
5044
+ const line = lines[i];
5045
+ let raw;
5046
+ try {
5047
+ raw = JSON.parse(line);
5048
+ } catch {
5049
+ continue;
5050
+ }
5051
+ const rawCopy = { ...raw, _source: source };
5052
+ rawLines.push(rawCopy);
5053
+ if (!raw.type && raw.role && raw.message?.content) {
5054
+ const synthDate = new Date(SYNTH_T0 + i);
5055
+ const synthTs = synthDate.toISOString();
5056
+ const textParts = raw.message.content.filter((c) => c?.type === "text" && typeof c.text === "string").map((c) => c.text).join("");
5057
+ if (raw.role === "user") {
5058
+ const queryMatch = /<user_query>\s*([\s\S]*?)\s*<\/user_query>/.exec(textParts);
5059
+ const text = queryMatch ? queryMatch[1] : textParts;
5060
+ if (text) {
5061
+ entries.push({
5062
+ type: "user",
5063
+ ...baseEntry(rawCopy, synthTs, synthDate, source),
5064
+ message: { role: "user", content: text }
5065
+ });
5066
+ }
5067
+ continue;
5068
+ }
5069
+ if (raw.role === "assistant") {
5070
+ const blocks = textParts ? [{ type: "text", text: textParts }] : [];
5071
+ if (blocks.length === 0) {
5072
+ entries.push({
5073
+ type: "system",
5074
+ ...baseEntry(rawCopy, synthTs, synthDate, source),
5075
+ raw: rawCopy
5076
+ });
5077
+ } else {
5078
+ entries.push({
5079
+ type: "assistant",
5080
+ ...baseEntry(rawCopy, synthTs, synthDate, source),
5081
+ message: { role: "assistant", content: blocks }
5082
+ });
5083
+ }
5084
+ continue;
5085
+ }
5086
+ entries.push({
5087
+ type: "system",
5088
+ ...baseEntry(rawCopy, synthTs, synthDate, source),
5089
+ raw: rawCopy
5090
+ });
5091
+ continue;
5092
+ }
5093
+ const timestampStr = raw.timestamp;
5094
+ if (!timestampStr)
5095
+ continue;
5096
+ const date = new Date(timestampStr);
5097
+ if (Number.isNaN(date.getTime()))
5098
+ continue;
5099
+ const timestamp = date.toISOString();
5100
+ const recType = raw.type;
5101
+ const data = raw.data ?? {};
5102
+ if (recType === "session.start" || recType === "sessionStart" || recType === "session_start") {
5103
+ const ctx = data.context ?? data;
5104
+ const c = ctx.cwd;
5105
+ if (typeof c === "string" && !cwd)
5106
+ cwd = c;
5107
+ if (!cwd && Array.isArray(ctx.workspace_roots) && typeof ctx.workspace_roots[0] === "string") {
5108
+ cwd = ctx.workspace_roots[0];
5109
+ }
5110
+ const label = seenSessionStart ? "Session Resumed" : "Session Started";
5111
+ seenSessionStart = true;
5112
+ entries.push({
5113
+ type: "queue-operation",
5114
+ ...baseEntry(rawCopy, timestamp, date, source),
5115
+ label
5116
+ });
5117
+ continue;
5118
+ }
5119
+ if (recType === "user.message" || recType === "userMessage") {
5120
+ const text = typeof data.content === "string" ? data.content : typeof data.text === "string" ? data.text : "";
5121
+ if (!text)
5122
+ continue;
5123
+ entries.push({
5124
+ type: "user",
5125
+ ...baseEntry(rawCopy, timestamp, date, source),
5126
+ message: { role: "user", content: text }
5127
+ });
5128
+ continue;
5129
+ }
5130
+ if (recType === "system.message" || recType === "systemMessage") {
5131
+ entries.push({
5132
+ type: "system",
5133
+ ...baseEntry(rawCopy, timestamp, date, source),
5134
+ raw: rawCopy
5135
+ });
5136
+ continue;
5137
+ }
5138
+ if (recType === "assistant.message" || recType === "assistantMessage") {
5139
+ const text = typeof data.content === "string" ? data.content : typeof data.text === "string" ? data.text : "";
5140
+ if (!text) {
5141
+ entries.push({
5142
+ type: "system",
5143
+ ...baseEntry(rawCopy, timestamp, date, source),
5144
+ raw: rawCopy
5145
+ });
5146
+ continue;
5147
+ }
5148
+ const blocks = [{ type: "text", text }];
5149
+ entries.push({
5150
+ type: "assistant",
5151
+ ...baseEntry(rawCopy, timestamp, date, source),
5152
+ message: { role: "assistant", content: blocks }
5153
+ });
5154
+ continue;
5155
+ }
5156
+ if (recType === "tool.execution_start" || recType === "tool.executionStart" || recType === "preToolUse") {
5157
+ const callId = data.toolCallId ?? data.tool_use_id;
5158
+ const name = data.toolName ?? data.tool_name ?? "tool";
5159
+ const args = data.arguments ?? data.tool_input ?? {};
5160
+ const id = callId ?? `${date.getTime()}-${name}`;
5161
+ const toolUse = {
5162
+ type: "tool_use",
5163
+ id,
5164
+ name,
5165
+ input: args
5166
+ };
5167
+ const entry = {
5168
+ type: "assistant",
5169
+ ...baseEntry(rawCopy, timestamp, date, source),
5170
+ message: { role: "assistant", content: [toolUse] }
5171
+ };
5172
+ entries.push(entry);
5173
+ if (callId) {
5174
+ toolUseById.set(callId, toolUse);
5175
+ toolUseStartMs.set(callId, date.getTime());
5176
+ }
5177
+ continue;
5178
+ }
5179
+ if (recType === "tool.execution_complete" || recType === "tool.executionComplete" || recType === "postToolUse") {
5180
+ const callId = data.toolCallId ?? data.tool_use_id;
5181
+ const block = callId ? toolUseById.get(callId) : undefined;
5182
+ if (block) {
5183
+ const startMs = toolUseStartMs.get(callId) ?? date.getTime();
5184
+ const result = data.result ?? {};
5185
+ const reportedMs = data.duration;
5186
+ const durationMs = typeof reportedMs === "number" && reportedMs >= 0 ? reportedMs : Math.max(0, date.getTime() - startMs);
5187
+ const content = result.detailedContent ?? result.content ?? data.tool_output ?? "";
5188
+ block.result = {
5189
+ timestamp,
5190
+ timestampFormatted: formatTimestamp(date),
5191
+ content: typeof content === "string" ? content : JSON.stringify(content),
5192
+ durationMs,
5193
+ durationFormatted: formatDuration(durationMs)
5194
+ };
5195
+ continue;
5196
+ }
5197
+ entries.push({
5198
+ type: "system",
5199
+ ...baseEntry(rawCopy, timestamp, date, source),
5200
+ raw: rawCopy
5201
+ });
5202
+ continue;
5203
+ }
5204
+ entries.push({
5205
+ type: "system",
5206
+ ...baseEntry(rawCopy, timestamp, date, source),
5207
+ raw: rawCopy
5208
+ });
5209
+ }
5210
+ if (entries.length > 500)
5211
+ await new Promise((r) => setImmediate(r));
5212
+ entries.sort((a, b) => a.timestampMs - b.timestampMs);
5213
+ return { entries, rawLines, cwd };
5214
+ }
5215
+ async function getCursorSessionLog(sessionId) {
5216
+ const filePath = findCursorTranscript(sessionId);
5217
+ if (!filePath)
5218
+ return null;
5219
+ let fileContent;
5220
+ try {
5221
+ fileContent = await readFile10(filePath, "utf-8");
5222
+ } catch {
5223
+ return null;
5224
+ }
5225
+ const { entries, rawLines, cwd } = await parseCursorLog(fileContent, "session");
5226
+ return { entries, rawLines, cwd, filePath };
5227
+ }
5228
+ var LEGACY_SESSION_ROOT_CANDIDATES2, LEGACY_TRANSCRIPT_FILE_CANDIDATES2, NEW_PROJECTS_DIR2 = "projects", NEW_AGENT_TRANSCRIPTS_DIR2 = "agent-transcripts", getCachedCursorSessionLog;
5229
+ var init_cursor_sessions = __esm(() => {
5230
+ init_log_entries();
5231
+ LEGACY_SESSION_ROOT_CANDIDATES2 = ["agent-sessions", "conversations", "sessions"];
5232
+ LEGACY_TRANSCRIPT_FILE_CANDIDATES2 = ["events.jsonl", "transcript.jsonl", "messages.jsonl"];
5233
+ getCachedCursorSessionLog = runtimeCache((sessionId) => getCursorSessionLog(sessionId), 60, { maxSize: 50 });
5234
+ });
5235
+
5236
+ // lib/pi-sessions.ts
5237
+ import { readFileSync as readFileSync7, readdirSync as readdirSync6, existsSync as existsSync8, statSync as statSync7 } from "node:fs";
5238
+ import { readFile as readFile11 } from "node:fs/promises";
5239
+ import { join as join16, resolve as resolve8, sep as sep4 } from "node:path";
5240
+ import { homedir as homedir15 } from "node:os";
5241
+ function getPiSessionStateRoot() {
5242
+ return process.env.PI_SESSIONS_DIR || join16(homedir15(), ".pi", "agent", "sessions");
5243
+ }
5244
+ function isSafeSessionId(sessionId) {
5245
+ return UUID_RE.test(sessionId);
5246
+ }
5247
+ function findPiTranscript(sessionId) {
5248
+ if (!isSafeSessionId(sessionId))
5249
+ return null;
5250
+ const root = resolve8(getPiSessionStateRoot());
5251
+ let cwdDirs;
5252
+ try {
5253
+ cwdDirs = readdirSync6(root);
5254
+ } catch {
5255
+ return null;
5256
+ }
5257
+ for (const cwdDir of cwdDirs) {
5258
+ const cwdPath = resolve8(root, cwdDir);
5259
+ if (!cwdPath.startsWith(`${root}${sep4}`))
5260
+ continue;
5261
+ let files;
5262
+ try {
5263
+ files = readdirSync6(cwdPath);
5264
+ } catch {
5265
+ continue;
5266
+ }
5267
+ for (const f of files) {
5268
+ const m = SESSION_FILE_RE3.exec(f);
5269
+ if (!m || m[1].toLowerCase() !== sessionId.toLowerCase())
5270
+ continue;
5271
+ const candidate = resolve8(cwdPath, f);
5272
+ if (!candidate.startsWith(`${cwdPath}${sep4}`))
5273
+ continue;
5274
+ if (existsSync8(candidate))
5275
+ return candidate;
5276
+ }
5277
+ }
5278
+ return null;
5279
+ }
5280
+ function extractMessageText(content) {
5281
+ if (!Array.isArray(content))
5282
+ return "";
5283
+ const parts = [];
5284
+ for (const block of content) {
5285
+ if (block?.type === "text" && typeof block.text === "string")
5286
+ parts.push(block.text);
5287
+ }
5288
+ return parts.join(`
5289
+
5290
+ `);
5291
+ }
5292
+ function buildAssistantContent(content) {
5293
+ if (!Array.isArray(content))
5294
+ return [];
5295
+ const blocks = [];
5296
+ for (const block of content) {
5297
+ if (block?.type === "text" && typeof block.text === "string" && block.text.length > 0) {
5298
+ blocks.push({ type: "text", text: block.text });
5299
+ }
5300
+ if (block?.type === "thinking" && typeof block.thinking === "string" && block.thinking.length > 0) {
5301
+ blocks.push({ type: "text", text: `[thinking] ${block.thinking}` });
5302
+ }
5303
+ }
5304
+ return blocks;
5305
+ }
5306
+ async function parsePiLog(fileContent, source = "session") {
5307
+ const lines = fileContent.split(`
5308
+ `).filter((line) => line.trim() !== "");
5309
+ const entries = [];
5310
+ const rawLines = [];
5311
+ let cwd;
5312
+ let seenSessionStart = false;
5313
+ for (let i = 0;i < lines.length; i++) {
5314
+ if (i > 0 && i % 200 === 0)
5315
+ await new Promise((r) => setImmediate(r));
5316
+ const line = lines[i];
5317
+ let raw;
5318
+ try {
5319
+ raw = JSON.parse(line);
5320
+ } catch {
5321
+ continue;
5322
+ }
5323
+ const rawCopy = { ...raw, _source: source };
5324
+ rawLines.push(rawCopy);
5325
+ const timestampStr = raw.timestamp;
5326
+ if (!timestampStr)
5327
+ continue;
5328
+ const date = new Date(timestampStr);
5329
+ if (Number.isNaN(date.getTime()))
5330
+ continue;
5331
+ const timestamp = date.toISOString();
5332
+ const recType = raw.type;
5333
+ if (recType === "session") {
5334
+ if (typeof raw.cwd === "string" && !cwd)
5335
+ cwd = raw.cwd;
5336
+ const label = seenSessionStart ? "Session Resumed" : "Session Started";
5337
+ seenSessionStart = true;
5338
+ entries.push({
5339
+ type: "queue-operation",
5340
+ ...baseEntry(rawCopy, timestamp, date, source),
5341
+ label
5342
+ });
5343
+ continue;
5344
+ }
5345
+ if (recType === "message" && raw.message && typeof raw.message === "object") {
5346
+ const role = raw.message.role;
5347
+ const content = raw.message.content;
5348
+ if (role === "user") {
5349
+ const text = extractMessageText(content);
5350
+ if (!text)
5351
+ continue;
5352
+ entries.push({
5353
+ type: "user",
5354
+ ...baseEntry(rawCopy, timestamp, date, source),
5355
+ message: { role: "user", content: text }
5356
+ });
5357
+ continue;
5358
+ }
5359
+ if (role === "assistant") {
5360
+ const blocks = buildAssistantContent(content);
5361
+ if (blocks.length === 0) {
5362
+ entries.push({
5363
+ type: "system",
5364
+ ...baseEntry(rawCopy, timestamp, date, source),
5365
+ raw: rawCopy
5366
+ });
5367
+ continue;
5368
+ }
5369
+ entries.push({
5370
+ type: "assistant",
5371
+ ...baseEntry(rawCopy, timestamp, date, source),
5372
+ message: { role: "assistant", content: blocks }
5373
+ });
5374
+ continue;
5375
+ }
5376
+ entries.push({
5377
+ type: "system",
5378
+ ...baseEntry(rawCopy, timestamp, date, source),
5379
+ raw: rawCopy
5380
+ });
5381
+ continue;
5382
+ }
5383
+ entries.push({
5384
+ type: "system",
5385
+ ...baseEntry(rawCopy, timestamp, date, source),
5386
+ raw: rawCopy
5387
+ });
5388
+ }
5389
+ if (entries.length > 500)
5390
+ await new Promise((r) => setImmediate(r));
5391
+ entries.sort((a, b) => a.timestampMs - b.timestampMs);
5392
+ return { entries, rawLines, cwd };
5393
+ }
5394
+ async function getPiSessionLog(sessionId) {
5395
+ const filePath = findPiTranscript(sessionId);
5396
+ if (!filePath)
5397
+ return null;
5398
+ let fileContent;
5399
+ try {
5400
+ fileContent = await readFile11(filePath, "utf-8");
5401
+ } catch {
5402
+ return null;
5403
+ }
5404
+ let parsed;
5405
+ try {
5406
+ parsed = await parsePiLog(fileContent, "session");
5407
+ } catch {
5408
+ return null;
5409
+ }
5410
+ return {
5411
+ entries: parsed.entries,
5412
+ rawLines: parsed.rawLines,
5413
+ cwd: parsed.cwd,
5414
+ filePath
5415
+ };
5416
+ }
5417
+ var UUID_RE, SESSION_FILE_RE3, getCachedPiSessionLog;
5418
+ var init_pi_sessions = __esm(() => {
5419
+ init_log_entries();
5420
+ UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5421
+ SESSION_FILE_RE3 = /^[\d-]+T[\d-]+Z_([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/i;
5422
+ getCachedPiSessionLog = runtimeCache((sessionId) => getPiSessionLog(sessionId), 60, { maxSize: 50 });
5423
+ });
5424
+
5425
+ // lib/gemini-sessions.ts
5426
+ import { closeSync, openSync, readFileSync as readFileSync8, readSync, readdirSync as readdirSync7, existsSync as existsSync9, statSync as statSync8 } from "node:fs";
5427
+ import { readFile as readFile12 } from "node:fs/promises";
5428
+ import { join as join17, resolve as resolve9, sep as sep5 } from "node:path";
5429
+ import { homedir as homedir16 } from "node:os";
5430
+ function getGeminiSessionStateRoot() {
5431
+ return process.env.GEMINI_SESSIONS_DIR || join17(homedir16(), ".gemini", "tmp");
5432
+ }
5433
+ function isSafeSessionId2(sessionId) {
5434
+ return UUID_RE2.test(sessionId);
5435
+ }
5436
+ function readFirstLineSync(path) {
5437
+ let fd;
5438
+ try {
5439
+ fd = openSync(path, "r");
5440
+ } catch {
5441
+ return null;
5442
+ }
5443
+ try {
5444
+ const buf = Buffer.alloc(4096);
5445
+ const bytesRead = readSync(fd, buf, 0, buf.length, 0);
5446
+ if (bytesRead === 0)
5447
+ return null;
5448
+ const text = buf.subarray(0, bytesRead).toString("utf-8");
5449
+ const nl = text.indexOf(`
5450
+ `);
5451
+ return nl >= 0 ? text.slice(0, nl) : text;
5452
+ } catch {
5453
+ return null;
5454
+ } finally {
5455
+ try {
5456
+ closeSync(fd);
5457
+ } catch {}
5458
+ }
5459
+ }
5460
+ function findGeminiTranscript(sessionId) {
5461
+ if (!isSafeSessionId2(sessionId))
5462
+ return null;
5463
+ const root = resolve9(getGeminiSessionStateRoot());
5464
+ const wantPrefix = sessionId.slice(0, 8).toLowerCase();
5465
+ let projectDirs;
5466
+ try {
5467
+ projectDirs = readdirSync7(root);
5468
+ } catch {
5469
+ return null;
5470
+ }
5471
+ for (const projectDir of projectDirs) {
5472
+ const projectPath = resolve9(root, projectDir);
5473
+ if (!projectPath.startsWith(`${root}${sep5}`))
5474
+ continue;
5475
+ const chatsDir = resolve9(projectPath, "chats");
5476
+ let files;
5477
+ try {
5478
+ files = readdirSync7(chatsDir);
5479
+ } catch {
5480
+ continue;
5481
+ }
5482
+ for (const f of files) {
5483
+ const m = SESSION_FILE_RE4.exec(f);
5484
+ if (!m || m[2].toLowerCase() !== wantPrefix)
5485
+ continue;
5486
+ const candidate = resolve9(chatsDir, f);
5487
+ if (!candidate.startsWith(`${chatsDir}${sep5}`))
5488
+ continue;
5489
+ if (!existsSync9(candidate))
5490
+ continue;
5491
+ const firstLine = readFirstLineSync(candidate);
5492
+ if (!firstLine)
5493
+ continue;
5494
+ try {
5495
+ const meta = JSON.parse(firstLine);
5496
+ if (typeof meta.sessionId === "string" && meta.sessionId.toLowerCase() === sessionId.toLowerCase()) {
5497
+ return candidate;
5498
+ }
5499
+ } catch {
5500
+ continue;
5501
+ }
5502
+ }
5503
+ }
5504
+ return null;
5505
+ }
5506
+ function extractMessageText2(content) {
5507
+ if (!Array.isArray(content))
5508
+ return "";
5509
+ const parts = [];
5510
+ for (const block of content) {
5511
+ if (typeof block?.text === "string")
5512
+ parts.push(block.text);
5513
+ }
5514
+ return parts.join(`
5515
+
5516
+ `);
5517
+ }
5518
+ function buildAssistantContent2(content) {
5519
+ if (!Array.isArray(content))
5520
+ return [];
5521
+ const blocks = [];
5522
+ for (const block of content) {
5523
+ if (typeof block?.text === "string" && block.text.length > 0) {
5524
+ blocks.push({ type: "text", text: block.text });
5525
+ }
5526
+ }
5527
+ return blocks;
5528
+ }
5529
+ async function parseGeminiLog(fileContent, source = "session", cwdHint) {
5530
+ const lines = fileContent.split(`
5531
+ `).filter((line) => line.trim() !== "");
5532
+ const entries = [];
5533
+ const rawLines = [];
5534
+ let cwd = cwdHint;
5535
+ let seenStart = false;
5536
+ for (let i = 0;i < lines.length; i++) {
5537
+ if (i > 0 && i % 200 === 0)
5538
+ await new Promise((r) => setImmediate(r));
5539
+ const line = lines[i];
5540
+ let raw;
5541
+ try {
5542
+ raw = JSON.parse(line);
5543
+ } catch {
5544
+ continue;
5545
+ }
5546
+ const rawCopy = { ...raw, _source: source };
5547
+ rawLines.push(rawCopy);
5548
+ if (typeof raw.sessionId === "string" && typeof raw.startTime === "string") {
5549
+ const date2 = new Date(raw.startTime);
5550
+ if (!Number.isNaN(date2.getTime())) {
5551
+ const label = seenStart ? "Session Resumed" : "Session Started";
5552
+ seenStart = true;
5553
+ entries.push({
5554
+ type: "queue-operation",
5555
+ ...baseEntry(rawCopy, date2.toISOString(), date2, source),
5556
+ label
5557
+ });
5558
+ }
5559
+ continue;
5560
+ }
5561
+ if (raw.$set)
5562
+ continue;
5563
+ const timestampStr = raw.timestamp;
5564
+ if (!timestampStr)
5565
+ continue;
5566
+ const date = new Date(timestampStr);
5567
+ if (Number.isNaN(date.getTime()))
5568
+ continue;
5569
+ const timestamp = date.toISOString();
5570
+ const recType = raw.type;
5571
+ if (recType === "user") {
5572
+ const text = extractMessageText2(raw.content);
5573
+ if (!text)
5574
+ continue;
5575
+ entries.push({
5576
+ type: "user",
5577
+ ...baseEntry(rawCopy, timestamp, date, source),
5578
+ message: { role: "user", content: text }
5579
+ });
5580
+ continue;
5581
+ }
5582
+ if (recType === "assistant" || recType === "model") {
5583
+ const blocks = buildAssistantContent2(raw.content);
5584
+ if (blocks.length === 0) {
5585
+ entries.push({
5586
+ type: "system",
5587
+ ...baseEntry(rawCopy, timestamp, date, source),
5588
+ raw: rawCopy
5589
+ });
5590
+ continue;
5591
+ }
5592
+ entries.push({
5593
+ type: "assistant",
5594
+ ...baseEntry(rawCopy, timestamp, date, source),
5595
+ message: { role: "assistant", content: blocks }
5596
+ });
5597
+ continue;
5598
+ }
5599
+ entries.push({
5600
+ type: "system",
5601
+ ...baseEntry(rawCopy, timestamp, date, source),
5602
+ raw: rawCopy
5603
+ });
5604
+ }
5605
+ if (entries.length > 500)
5606
+ await new Promise((r) => setImmediate(r));
5607
+ entries.sort((a, b) => a.timestampMs - b.timestampMs);
5608
+ return { entries, rawLines, cwd };
5609
+ }
5610
+ function readSiblingProjectRoot(transcriptPath) {
5611
+ const chatsDir = resolve9(transcriptPath, "..");
5612
+ const projectDir = resolve9(chatsDir, "..");
5613
+ const rootFile = join17(projectDir, ".project_root");
5614
+ try {
5615
+ const text = readFileSync8(rootFile, "utf-8").trim();
5616
+ return text.length > 0 ? text : undefined;
5617
+ } catch {
5618
+ return;
5619
+ }
5620
+ }
5621
+ async function getGeminiSessionLog(sessionId) {
5622
+ const filePath = findGeminiTranscript(sessionId);
5623
+ if (!filePath)
5624
+ return null;
5625
+ let fileContent;
5626
+ try {
5627
+ fileContent = await readFile12(filePath, "utf-8");
5628
+ } catch {
5629
+ return null;
5630
+ }
5631
+ const cwdHint = readSiblingProjectRoot(filePath);
5632
+ let parsed;
5633
+ try {
5634
+ parsed = await parseGeminiLog(fileContent, "session", cwdHint);
5635
+ } catch {
5636
+ return null;
5637
+ }
5638
+ return {
5639
+ entries: parsed.entries,
5640
+ rawLines: parsed.rawLines,
5641
+ cwd: parsed.cwd,
5642
+ filePath
5643
+ };
5644
+ }
5645
+ var UUID_RE2, SESSION_FILE_RE4, getCachedGeminiSessionLog;
5646
+ var init_gemini_sessions = __esm(() => {
5647
+ init_log_entries();
5648
+ UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
5649
+ SESSION_FILE_RE4 = /^session-(.+)-([0-9a-f]{8})\.jsonl$/i;
5650
+ getCachedGeminiSessionLog = runtimeCache((sessionId) => getGeminiSessionLog(sessionId), 60, { maxSize: 50 });
5651
+ });
5652
+
5653
+ // src/hooks/resolve-transcript-path.ts
5654
+ function resolveTranscriptPath(integration, parsed, sessionId) {
5655
+ const stdinPath = typeof parsed.transcript_path === "string" ? parsed.transcript_path : undefined;
5656
+ if (stdinPath)
5657
+ return stdinPath;
5658
+ if (typeof sessionId !== "string" || sessionId.length === 0)
5659
+ return;
5660
+ switch (integration) {
5661
+ case "claude":
5662
+ return;
5663
+ case "codex":
5664
+ return findCodexTranscript(sessionId) ?? undefined;
5665
+ case "copilot":
5666
+ return findCopilotTranscript(sessionId) ?? undefined;
5667
+ case "cursor":
5668
+ return findCursorTranscript(sessionId) ?? undefined;
5669
+ case "pi":
5670
+ return findPiTranscript(sessionId) ?? undefined;
5671
+ case "gemini":
5672
+ return findGeminiTranscript(sessionId) ?? undefined;
5673
+ case "opencode":
5674
+ return `opencode-db://${sessionId}`;
5675
+ default:
5676
+ return;
5677
+ }
5678
+ }
5679
+ var init_resolve_transcript_path = __esm(() => {
5680
+ init_codex_sessions();
5681
+ init_copilot_sessions();
5682
+ init_cursor_sessions();
5683
+ init_pi_sessions();
5684
+ init_gemini_sessions();
5685
+ });
5686
+
5687
+ // lib/telemetry-id.ts
5688
+ import fs from "node:fs";
5689
+ import path from "node:path";
5690
+ import os from "node:os";
5691
+ import crypto from "node:crypto";
5692
+ import { execSync as execSync2 } from "node:child_process";
5693
+ function hashToId(raw) {
5694
+ return crypto.createHmac("sha256", NAMESPACE).update(raw).digest("hex");
5695
+ }
5696
+ function getPlatformMachineId() {
5697
+ try {
5698
+ const platform = os.platform();
5699
+ if (platform === "linux") {
5700
+ for (const p of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
5701
+ try {
5702
+ const id = fs.readFileSync(p, "utf-8").trim();
5703
+ if (id)
5704
+ return id;
5705
+ } catch {}
5706
+ }
5707
+ } else if (platform === "darwin") {
5708
+ const out = execSync2("ioreg -rd1 -c IOPlatformExpertDevice", {
5709
+ encoding: "utf-8",
5710
+ timeout: 3000
5711
+ });
5712
+ const m = out.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
5713
+ if (m?.[1])
5714
+ return m[1];
5715
+ } else if (platform === "win32") {
5716
+ const out = execSync2('reg query "HKLM\\SOFTWARE\\Microsoft\\Cryptography" /v MachineGuid', { encoding: "utf-8", timeout: 3000 });
5717
+ const m = out.match(/MachineGuid\s+REG_SZ\s+(\S+)/);
5718
+ if (m?.[1])
5719
+ return m[1];
5720
+ }
5721
+ } catch {}
5722
+ return;
5723
+ }
5724
+ function getSystemPropertiesId() {
5725
+ return [
5726
+ os.hostname(),
5727
+ os.homedir(),
5728
+ os.platform(),
5729
+ os.arch(),
5730
+ os.cpus()[0]?.model ?? ""
5731
+ ].join(":");
5732
+ }
5733
+ function getFileBasedId() {
5734
+ try {
5735
+ const existing = fs.readFileSync(ID_FILE, "utf-8").trim();
5736
+ if (existing)
5737
+ return existing;
5738
+ } catch {}
5739
+ const id = crypto.randomUUID();
5740
+ try {
5741
+ fs.mkdirSync(ID_DIR, { recursive: true });
5742
+ fs.writeFileSync(ID_FILE, id, "utf-8");
5743
+ } catch {}
5744
+ return id;
5745
+ }
5746
+ function getInstanceId() {
5747
+ if (cachedId)
5748
+ return cachedId;
5749
+ const machineId = getPlatformMachineId();
5750
+ if (machineId) {
5751
+ cachedId = hashToId(machineId);
5752
+ return cachedId;
5753
+ }
5754
+ const sysProps = getSystemPropertiesId();
5755
+ if (sysProps) {
5756
+ cachedId = hashToId(sysProps);
5757
+ return cachedId;
5758
+ }
5759
+ cachedId = getFileBasedId();
5760
+ return cachedId;
5761
+ }
5762
+ var NAMESPACE = "failproofai-telemetry-v1", ID_DIR, ID_FILE, cachedId;
5763
+ var init_telemetry_id = __esm(() => {
5764
+ ID_DIR = path.join(os.homedir(), ".failproofai");
5765
+ ID_FILE = path.join(ID_DIR, "instance-id");
5766
+ });
5767
+
5768
+ // src/auth/token-store.ts
5769
+ import {
5770
+ readFileSync as readFileSync9,
5771
+ writeFileSync as writeFileSync4,
5772
+ existsSync as existsSync10,
5773
+ mkdirSync as mkdirSync5,
5774
+ unlinkSync as unlinkSync2,
5775
+ renameSync as renameSync3,
5776
+ openSync as openSync2,
5777
+ closeSync as closeSync2
5778
+ } from "node:fs";
5779
+ import { join as join18 } from "node:path";
5780
+ import { homedir as homedir17 } from "node:os";
5781
+ function ensureAuthDir() {
5782
+ if (!existsSync10(AUTH_DIR))
5783
+ mkdirSync5(AUTH_DIR, { recursive: true, mode: 448 });
5784
+ }
5785
+ function readTokens() {
5786
+ if (!existsSync10(AUTH_FILE))
5787
+ return null;
5788
+ try {
5789
+ const raw = readFileSync9(AUTH_FILE, "utf8");
5790
+ return JSON.parse(raw);
5791
+ } catch {
5792
+ return null;
5793
+ }
5794
+ }
5795
+ function writeTokens(tokens) {
5796
+ ensureAuthDir();
5797
+ const tmpPath = `${AUTH_FILE}.tmp`;
5798
+ const fd = openSync2(tmpPath, "w", 384);
5799
+ try {
5800
+ writeFileSync4(fd, JSON.stringify(tokens, null, 2));
5801
+ } finally {
5802
+ closeSync2(fd);
5803
+ }
5804
+ renameSync3(tmpPath, AUTH_FILE);
5805
+ }
5806
+ function clearTokens() {
5807
+ if (existsSync10(AUTH_FILE))
5808
+ unlinkSync2(AUTH_FILE);
5809
+ }
5810
+ function isLoggedIn() {
5811
+ return existsSync10(AUTH_FILE);
5812
+ }
5813
+ var AUTH_DIR, AUTH_FILE;
5814
+ var init_token_store = __esm(() => {
5815
+ AUTH_DIR = join18(homedir17(), ".failproofai");
5816
+ AUTH_FILE = join18(AUTH_DIR, "auth.json");
5817
+ });
5818
+
5819
+ // src/relay/queue.ts
5820
+ var exports_queue = {};
5821
+ __export(exports_queue, {
5822
+ readProcessingFile: () => readProcessingFile,
5823
+ queueSizeBytes: () => queueSizeBytes,
5824
+ findOrphanProcessingFiles: () => findOrphanProcessingFiles,
5825
+ deleteProcessingFile: () => deleteProcessingFile,
5826
+ claimPendingBatch: () => claimPendingBatch,
5827
+ appendToServerQueue: () => appendToServerQueue
5828
+ });
5829
+ import {
4859
5830
  appendFileSync as appendFileSync3,
4860
5831
  mkdirSync as mkdirSync6,
4861
- existsSync as existsSync7,
4862
- readFileSync as readFileSync6,
4863
- statSync as statSync5,
5832
+ existsSync as existsSync11,
5833
+ readFileSync as readFileSync10,
5834
+ statSync as statSync9,
4864
5835
  renameSync as renameSync4,
4865
5836
  unlinkSync as unlinkSync3,
4866
- readdirSync as readdirSync4,
5837
+ readdirSync as readdirSync8,
4867
5838
  chmodSync
4868
5839
  } from "node:fs";
4869
- import { join as join15 } from "node:path";
4870
- import { homedir as homedir14 } from "node:os";
5840
+ import { join as join19 } from "node:path";
5841
+ import { homedir as homedir18 } from "node:os";
4871
5842
  import { createHash, randomUUID } from "node:crypto";
4872
5843
  function hashCwd(cwd) {
4873
5844
  if (!cwd)
@@ -4897,7 +5868,7 @@ function sanitize(entry) {
4897
5868
  };
4898
5869
  }
4899
5870
  function ensureDir2() {
4900
- if (!existsSync7(QUEUE_DIR)) {
5871
+ if (!existsSync11(QUEUE_DIR)) {
4901
5872
  mkdirSync6(QUEUE_DIR, { recursive: true, mode: 448 });
4902
5873
  }
4903
5874
  }
@@ -4906,7 +5877,7 @@ function appendToServerQueue(entry) {
4906
5877
  return;
4907
5878
  ensureDir2();
4908
5879
  try {
4909
- if (existsSync7(PENDING_FILE) && statSync5(PENDING_FILE).size > MAX_QUEUE_BYTES) {
5880
+ if (existsSync11(PENDING_FILE) && statSync9(PENDING_FILE).size > MAX_QUEUE_BYTES) {
4910
5881
  return;
4911
5882
  }
4912
5883
  } catch {}
@@ -4919,23 +5890,23 @@ function appendToServerQueue(entry) {
4919
5890
  }
4920
5891
  function queueSizeBytes() {
4921
5892
  try {
4922
- return statSync5(PENDING_FILE).size;
5893
+ return statSync9(PENDING_FILE).size;
4923
5894
  } catch {
4924
5895
  return 0;
4925
5896
  }
4926
5897
  }
4927
5898
  function claimPendingBatch() {
4928
- if (!existsSync7(PENDING_FILE))
5899
+ if (!existsSync11(PENDING_FILE))
4929
5900
  return null;
4930
5901
  try {
4931
- const size = statSync5(PENDING_FILE).size;
5902
+ const size = statSync9(PENDING_FILE).size;
4932
5903
  if (size === 0)
4933
5904
  return null;
4934
5905
  } catch {
4935
5906
  return null;
4936
5907
  }
4937
5908
  const seq = `${Date.now()}-${process.pid}`;
4938
- const processingFile = join15(QUEUE_DIR, `${PROCESSING_PREFIX}${seq}.jsonl`);
5909
+ const processingFile = join19(QUEUE_DIR, `${PROCESSING_PREFIX}${seq}.jsonl`);
4939
5910
  try {
4940
5911
  renameSync4(PENDING_FILE, processingFile);
4941
5912
  try {
@@ -4952,15 +5923,15 @@ function claimPendingBatch() {
4952
5923
  function findOrphanProcessingFiles() {
4953
5924
  ensureDir2();
4954
5925
  try {
4955
- return readdirSync4(QUEUE_DIR).filter((n) => n.startsWith(PROCESSING_PREFIX) && n.endsWith(".jsonl")).map((n) => join15(QUEUE_DIR, n)).sort();
5926
+ return readdirSync8(QUEUE_DIR).filter((n) => n.startsWith(PROCESSING_PREFIX) && n.endsWith(".jsonl")).map((n) => join19(QUEUE_DIR, n)).sort();
4956
5927
  } catch {
4957
5928
  return [];
4958
5929
  }
4959
5930
  }
4960
5931
  function readProcessingFile(path2) {
4961
- if (!existsSync7(path2))
5932
+ if (!existsSync11(path2))
4962
5933
  return [];
4963
- const content = readFileSync6(path2, "utf8");
5934
+ const content = readFileSync10(path2, "utf8");
4964
5935
  const out = [];
4965
5936
  for (const line of content.split(`
4966
5937
  `)) {
@@ -4981,20 +5952,20 @@ function deleteProcessingFile(path2) {
4981
5952
  var QUEUE_DIR, PENDING_FILE, PROCESSING_PREFIX = "processing-", MAX_QUEUE_BYTES;
4982
5953
  var init_queue = __esm(() => {
4983
5954
  init_token_store();
4984
- QUEUE_DIR = join15(homedir14(), ".failproofai", "cache", "server-queue");
4985
- PENDING_FILE = join15(QUEUE_DIR, "pending.jsonl");
5955
+ QUEUE_DIR = join19(homedir18(), ".failproofai", "cache", "server-queue");
5956
+ PENDING_FILE = join19(QUEUE_DIR, "pending.jsonl");
4986
5957
  MAX_QUEUE_BYTES = 50 * 1024 * 1024;
4987
5958
  });
4988
5959
 
4989
5960
  // src/relay/pid.ts
4990
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, existsSync as existsSync8, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7 } from "node:fs";
4991
- import { join as join16, dirname as dirname4 } from "node:path";
4992
- import { homedir as homedir15 } from "node:os";
5961
+ import { readFileSync as readFileSync11, writeFileSync as writeFileSync5, existsSync as existsSync12, unlinkSync as unlinkSync4, mkdirSync as mkdirSync7 } from "node:fs";
5962
+ import { join as join20, dirname as dirname4 } from "node:path";
5963
+ import { homedir as homedir19 } from "node:os";
4993
5964
  function readPid() {
4994
- if (!existsSync8(PID_FILE))
5965
+ if (!existsSync12(PID_FILE))
4995
5966
  return null;
4996
5967
  try {
4997
- const raw = readFileSync7(PID_FILE, "utf8").trim();
5968
+ const raw = readFileSync11(PID_FILE, "utf8").trim();
4998
5969
  const pid = parseInt(raw, 10);
4999
5970
  if (Number.isNaN(pid) || pid <= 0)
5000
5971
  return null;
@@ -5005,12 +5976,12 @@ function readPid() {
5005
5976
  }
5006
5977
  function writePid(pid) {
5007
5978
  const dir = dirname4(PID_FILE);
5008
- if (!existsSync8(dir))
5979
+ if (!existsSync12(dir))
5009
5980
  mkdirSync7(dir, { recursive: true, mode: 448 });
5010
5981
  writeFileSync5(PID_FILE, String(pid));
5011
5982
  }
5012
5983
  function clearPid() {
5013
- if (existsSync8(PID_FILE))
5984
+ if (existsSync12(PID_FILE))
5014
5985
  unlinkSync4(PID_FILE);
5015
5986
  }
5016
5987
  function isProcessAlive(pid) {
@@ -5042,7 +6013,7 @@ function stopRelay() {
5042
6013
  }
5043
6014
  var PID_FILE;
5044
6015
  var init_pid = __esm(() => {
5045
- PID_FILE = join16(homedir15(), ".failproofai", "relay.pid");
6016
+ PID_FILE = join20(homedir19(), ".failproofai", "relay.pid");
5046
6017
  });
5047
6018
 
5048
6019
  // src/relay/daemon.ts
@@ -5054,9 +6025,9 @@ __export(exports_daemon, {
5054
6025
  ensureRelayRunning: () => ensureRelayRunning
5055
6026
  });
5056
6027
  import { spawn } from "node:child_process";
5057
- import { existsSync as existsSync9 } from "node:fs";
5058
- import { join as join17 } from "node:path";
5059
- import { homedir as homedir16 } from "node:os";
6028
+ import { existsSync as existsSync13 } from "node:fs";
6029
+ import { join as join21 } from "node:path";
6030
+ import { homedir as homedir20 } from "node:os";
5060
6031
  import { randomUUID as randomUUID2 } from "node:crypto";
5061
6032
  function ensureRelayRunning() {
5062
6033
  if (!isLoggedIn())
@@ -5136,16 +6107,16 @@ class Relay {
5136
6107
  try {
5137
6108
  const msg = JSON.parse(data);
5138
6109
  if (msg.ack && this.pendingAcks.has(msg.ack)) {
5139
- const resolve6 = this.pendingAcks.get(msg.ack);
6110
+ const resolve10 = this.pendingAcks.get(msg.ack);
5140
6111
  this.pendingAcks.delete(msg.ack);
5141
- resolve6(true);
6112
+ resolve10(true);
5142
6113
  }
5143
6114
  } catch {}
5144
6115
  }
5145
6116
  handleClose() {
5146
6117
  this.closed = true;
5147
- for (const [, resolve6] of this.pendingAcks) {
5148
- resolve6(false);
6118
+ for (const [, resolve10] of this.pendingAcks) {
6119
+ resolve10(false);
5149
6120
  }
5150
6121
  this.pendingAcks.clear();
5151
6122
  }
@@ -5161,11 +6132,11 @@ class Relay {
5161
6132
  if (this.closed)
5162
6133
  return false;
5163
6134
  const batchId = randomUUID2();
5164
- const ackPromise = new Promise((resolve6) => {
5165
- this.pendingAcks.set(batchId, resolve6);
6135
+ const ackPromise = new Promise((resolve10) => {
6136
+ this.pendingAcks.set(batchId, resolve10);
5166
6137
  setTimeout(() => {
5167
6138
  if (this.pendingAcks.delete(batchId))
5168
- resolve6(false);
6139
+ resolve10(false);
5169
6140
  }, ACK_TIMEOUT_MS);
5170
6141
  });
5171
6142
  try {
@@ -5183,7 +6154,7 @@ async function connect(wsUrl, token) {
5183
6154
  throw new Error("WebSocket not available in this Node version. Requires Node 22+.");
5184
6155
  }
5185
6156
  const ws = new WSCtor(wsUrl);
5186
- await new Promise((resolve6, reject) => {
6157
+ await new Promise((resolve10, reject) => {
5187
6158
  let settled = false;
5188
6159
  const timeout = setTimeout(() => {
5189
6160
  if (settled)
@@ -5201,7 +6172,7 @@ async function connect(wsUrl, token) {
5201
6172
  clearTimeout(timeout);
5202
6173
  try {
5203
6174
  ws.send(token);
5204
- resolve6();
6175
+ resolve10();
5205
6176
  } catch (e) {
5206
6177
  reject(e);
5207
6178
  }
@@ -5273,7 +6244,7 @@ async function runDaemon() {
5273
6244
  }
5274
6245
  relay.close();
5275
6246
  } catch {}
5276
- if (existsSync9(QUEUE_DIR2)) {}
6247
+ if (existsSync13(QUEUE_DIR2)) {}
5277
6248
  await new Promise((r) => setTimeout(r, reconnectDelay));
5278
6249
  reconnectDelay = Math.min(reconnectDelay * 2, RECONNECT_MAX_MS);
5279
6250
  }
@@ -5323,7 +6294,7 @@ var init_daemon = __esm(() => {
5323
6294
  init_token_store();
5324
6295
  init_pid();
5325
6296
  init_queue();
5326
- QUEUE_DIR2 = join17(homedir16(), ".failproofai", "cache", "server-queue");
6297
+ QUEUE_DIR2 = join21(homedir20(), ".failproofai", "cache", "server-queue");
5327
6298
  });
5328
6299
 
5329
6300
  // src/hooks/handler.ts
@@ -5357,12 +6328,14 @@ function canonicalizeEventType(raw, cli) {
5357
6328
  function canonicalizeToolName(raw, cli) {
5358
6329
  if (!raw)
5359
6330
  return raw;
5360
- if (cli === "copilot") {
6331
+ if (cli === "copilot")
5361
6332
  return COPILOT_TOOL_MAP[raw] ?? raw;
5362
- }
5363
- if (cli === "gemini") {
6333
+ if (cli === "cursor")
6334
+ return CURSOR_TOOL_MAP[raw] ?? raw;
6335
+ if (cli === "codex")
6336
+ return CODEX_TOOL_MAP[raw] ?? raw;
6337
+ if (cli === "gemini")
5364
6338
  return GEMINI_TOOL_MAP[raw] ?? raw;
5365
- }
5366
6339
  return raw;
5367
6340
  }
5368
6341
  async function handleHookEvent(eventType, cli = "claude") {
@@ -5370,7 +6343,7 @@ async function handleHookEvent(eventType, cli = "claude") {
5370
6343
  const MAX_STDIN_BYTES = 1048576;
5371
6344
  let payload = "";
5372
6345
  try {
5373
- payload = await new Promise((resolve6, reject) => {
6346
+ payload = await new Promise((resolve10, reject) => {
5374
6347
  const chunks = [];
5375
6348
  let totalBytes = 0;
5376
6349
  process.stdin.setEncoding("utf8");
@@ -5379,15 +6352,15 @@ async function handleHookEvent(eventType, cli = "claude") {
5379
6352
  if (totalBytes > MAX_STDIN_BYTES) {
5380
6353
  hookLogWarn(`stdin payload exceeds 1 MB for ${eventType}, discarding`);
5381
6354
  process.stdin.destroy();
5382
- resolve6("");
6355
+ resolve10("");
5383
6356
  return;
5384
6357
  }
5385
6358
  chunks.push(chunk);
5386
6359
  });
5387
- process.stdin.on("end", () => resolve6(chunks.join("")));
6360
+ process.stdin.on("end", () => resolve10(chunks.join("")));
5388
6361
  process.stdin.on("error", reject);
5389
6362
  if (process.stdin.readableEnded)
5390
- resolve6("");
6363
+ resolve10("");
5391
6364
  });
5392
6365
  } catch {
5393
6366
  hookLogWarn(`stdin read failed for ${eventType}`);
@@ -5409,7 +6382,7 @@ async function handleHookEvent(eventType, cli = "claude") {
5409
6382
  const sessionId = parsed.session_id;
5410
6383
  const session = {
5411
6384
  sessionId,
5412
- transcriptPath: parsed.transcript_path,
6385
+ transcriptPath: resolveTranscriptPath(cli, parsed, sessionId),
5413
6386
  cwd: parsed.cwd,
5414
6387
  permissionMode: resolvePermissionMode(cli, parsed, sessionId),
5415
6388
  hookEventName: parsed.hook_event_name,
@@ -5541,6 +6514,7 @@ var init_handler = __esm(() => {
5541
6514
  init_hook_activity_store();
5542
6515
  init_hook_telemetry();
5543
6516
  init_resolve_permission_mode();
6517
+ init_resolve_transcript_path();
5544
6518
  init_telemetry_id();
5545
6519
  init_hook_logger();
5546
6520
  });
@@ -5554,9 +6528,9 @@ __export(exports_daemon2, {
5554
6528
  ensureRelayRunning: () => ensureRelayRunning2
5555
6529
  });
5556
6530
  import { spawn as spawn2 } from "node:child_process";
5557
- import { existsSync as existsSync10 } from "node:fs";
5558
- import { join as join18 } from "node:path";
5559
- import { homedir as homedir17 } from "node:os";
6531
+ import { existsSync as existsSync14 } from "node:fs";
6532
+ import { join as join22 } from "node:path";
6533
+ import { homedir as homedir21 } from "node:os";
5560
6534
  import { randomUUID as randomUUID3 } from "node:crypto";
5561
6535
  function ensureRelayRunning2() {
5562
6536
  if (!isLoggedIn())
@@ -5636,16 +6610,16 @@ class Relay2 {
5636
6610
  try {
5637
6611
  const msg = JSON.parse(data);
5638
6612
  if (msg.ack && this.pendingAcks.has(msg.ack)) {
5639
- const resolve6 = this.pendingAcks.get(msg.ack);
6613
+ const resolve10 = this.pendingAcks.get(msg.ack);
5640
6614
  this.pendingAcks.delete(msg.ack);
5641
- resolve6(true);
6615
+ resolve10(true);
5642
6616
  }
5643
6617
  } catch {}
5644
6618
  }
5645
6619
  handleClose() {
5646
6620
  this.closed = true;
5647
- for (const [, resolve6] of this.pendingAcks) {
5648
- resolve6(false);
6621
+ for (const [, resolve10] of this.pendingAcks) {
6622
+ resolve10(false);
5649
6623
  }
5650
6624
  this.pendingAcks.clear();
5651
6625
  }
@@ -5661,11 +6635,11 @@ class Relay2 {
5661
6635
  if (this.closed)
5662
6636
  return false;
5663
6637
  const batchId = randomUUID3();
5664
- const ackPromise = new Promise((resolve6) => {
5665
- this.pendingAcks.set(batchId, resolve6);
6638
+ const ackPromise = new Promise((resolve10) => {
6639
+ this.pendingAcks.set(batchId, resolve10);
5666
6640
  setTimeout(() => {
5667
6641
  if (this.pendingAcks.delete(batchId))
5668
- resolve6(false);
6642
+ resolve10(false);
5669
6643
  }, ACK_TIMEOUT_MS2);
5670
6644
  });
5671
6645
  try {
@@ -5683,7 +6657,7 @@ async function connect2(wsUrl, token) {
5683
6657
  throw new Error("WebSocket not available in this Node version. Requires Node 22+.");
5684
6658
  }
5685
6659
  const ws = new WSCtor(wsUrl);
5686
- await new Promise((resolve6, reject) => {
6660
+ await new Promise((resolve10, reject) => {
5687
6661
  let settled = false;
5688
6662
  const timeout = setTimeout(() => {
5689
6663
  if (settled)
@@ -5701,7 +6675,7 @@ async function connect2(wsUrl, token) {
5701
6675
  clearTimeout(timeout);
5702
6676
  try {
5703
6677
  ws.send(token);
5704
- resolve6();
6678
+ resolve10();
5705
6679
  } catch (e) {
5706
6680
  reject(e);
5707
6681
  }
@@ -5773,7 +6747,7 @@ async function runDaemon2() {
5773
6747
  }
5774
6748
  relay.close();
5775
6749
  } catch {}
5776
- if (existsSync10(QUEUE_DIR3)) {}
6750
+ if (existsSync14(QUEUE_DIR3)) {}
5777
6751
  await new Promise((r) => setTimeout(r, reconnectDelay));
5778
6752
  reconnectDelay = Math.min(reconnectDelay * 2, RECONNECT_MAX_MS2);
5779
6753
  }
@@ -5823,19 +6797,19 @@ var init_daemon2 = __esm(() => {
5823
6797
  init_token_store();
5824
6798
  init_pid();
5825
6799
  init_queue();
5826
- QUEUE_DIR3 = join18(homedir17(), ".failproofai", "cache", "server-queue");
6800
+ QUEUE_DIR3 = join22(homedir21(), ".failproofai", "cache", "server-queue");
5827
6801
  });
5828
6802
 
5829
6803
  // src/hooks/integrations.ts
5830
6804
  import { execSync as execSync3 } from "node:child_process";
5831
- import { readFileSync as readFileSync8, writeFileSync as writeFileSync6, existsSync as existsSync11, mkdirSync as mkdirSync8, unlinkSync as unlinkSync5 } from "node:fs";
5832
- import { resolve as resolve6, dirname as dirname5 } from "node:path";
6805
+ import { readFileSync as readFileSync12, writeFileSync as writeFileSync6, existsSync as existsSync15, mkdirSync as mkdirSync8, unlinkSync as unlinkSync5 } from "node:fs";
6806
+ import { resolve as resolve10, dirname as dirname5 } from "node:path";
5833
6807
  import { fileURLToPath } from "node:url";
5834
- import { homedir as homedir18 } from "node:os";
6808
+ import { homedir as homedir22 } from "node:os";
5835
6809
  function readJsonFile(path2) {
5836
- if (!existsSync11(path2))
6810
+ if (!existsSync15(path2))
5837
6811
  return {};
5838
- const raw = readFileSync8(path2, "utf8");
6812
+ const raw = readFileSync12(path2, "utf8");
5839
6813
  return JSON.parse(raw);
5840
6814
  }
5841
6815
  function writeJsonFile(path2, data) {
@@ -5873,7 +6847,7 @@ function isMarkedCopilotHook(hook) {
5873
6847
  return false;
5874
6848
  }
5875
6849
  function opencodePluginFilePath(settingsPath) {
5876
- return resolve6(dirname5(settingsPath), "plugins", "failproofai.mjs");
6850
+ return resolve10(dirname5(settingsPath), "plugins", "failproofai.mjs");
5877
6851
  }
5878
6852
  function buildOpenCodePluginShim(binaryPath, scope) {
5879
6853
  const useNpx = scope === "project";
@@ -5906,10 +6880,12 @@ const TOOL_NAME_MAP = {
5906
6880
  read: "Read",
5907
6881
  write: "Write",
5908
6882
  edit: "Edit",
6883
+ apply_patch: "Edit",
5909
6884
  glob: "Glob",
5910
6885
  grep: "Grep",
5911
6886
  list: "LS",
5912
6887
  webfetch: "WebFetch",
6888
+ websearch: "WebSearch",
5913
6889
  todowrite: "TodoWrite",
5914
6890
  todoread: "TodoRead",
5915
6891
  };
@@ -6053,8 +7029,8 @@ export default async function failproofaiPlugin({ client, directory }) {
6053
7029
  function getPiExtensionPath() {
6054
7030
  const fromEnv = process.env.FAILPROOFAI_PACKAGE_ROOT;
6055
7031
  if (fromEnv)
6056
- return resolve6(fromEnv, "pi-extension");
6057
- return resolve6(fileURLToPath(import.meta.url), "..", "..", "..", "pi-extension");
7032
+ return resolve10(fromEnv, "pi-extension");
7033
+ return resolve10(fileURLToPath(import.meta.url), "..", "..", "..", "pi-extension");
6058
7034
  }
6059
7035
  function isFailproofaiPiEntry(source) {
6060
7036
  if (typeof source !== "string")
@@ -6065,8 +7041,8 @@ function isFailproofaiPiEntry(source) {
6065
7041
  }
6066
7042
  function makePiProjectRelativeEntry(extPath) {
6067
7043
  const cwd = process.cwd();
6068
- const cwdResolved = resolve6(cwd);
6069
- const extResolved = resolve6(extPath);
7044
+ const cwdResolved = resolve10(cwd);
7045
+ const extResolved = resolve10(extPath);
6070
7046
  if (extResolved.startsWith(cwdResolved + "/") || extResolved === cwdResolved) {
6071
7047
  const fromSettingsDir = "../" + extResolved.slice(cwdResolved.length + 1);
6072
7048
  return fromSettingsDir;
@@ -6092,14 +7068,14 @@ var init_integrations = __esm(() => {
6092
7068
  scopes: HOOK_SCOPES,
6093
7069
  eventTypes: HOOK_EVENT_TYPES,
6094
7070
  getSettingsPath(scope, cwd) {
6095
- const base = cwd ? resolve6(cwd) : process.cwd();
7071
+ const base = cwd ? resolve10(cwd) : process.cwd();
6096
7072
  switch (scope) {
6097
7073
  case "user":
6098
- return resolve6(homedir18(), ".claude", "settings.json");
7074
+ return resolve10(homedir22(), ".claude", "settings.json");
6099
7075
  case "project":
6100
- return resolve6(base, ".claude", "settings.json");
7076
+ return resolve10(base, ".claude", "settings.json");
6101
7077
  case "local":
6102
- return resolve6(base, ".claude", "settings.local.json");
7078
+ return resolve10(base, ".claude", "settings.local.json");
6103
7079
  }
6104
7080
  },
6105
7081
  readSettings(settingsPath) {
@@ -6171,7 +7147,7 @@ var init_integrations = __esm(() => {
6171
7147
  },
6172
7148
  hooksInstalledInSettings(scope, cwd) {
6173
7149
  const settingsPath = this.getSettingsPath(scope, cwd);
6174
- if (!existsSync11(settingsPath))
7150
+ if (!existsSync15(settingsPath))
6175
7151
  return false;
6176
7152
  try {
6177
7153
  const settings = this.readSettings(settingsPath);
@@ -6200,14 +7176,14 @@ var init_integrations = __esm(() => {
6200
7176
  scopes: CODEX_HOOK_SCOPES,
6201
7177
  eventTypes: CODEX_HOOK_EVENT_TYPES,
6202
7178
  getSettingsPath(scope, cwd) {
6203
- const base = cwd ? resolve6(cwd) : process.cwd();
7179
+ const base = cwd ? resolve10(cwd) : process.cwd();
6204
7180
  switch (scope) {
6205
7181
  case "user":
6206
- return resolve6(homedir18(), ".codex", "hooks.json");
7182
+ return resolve10(homedir22(), ".codex", "hooks.json");
6207
7183
  case "project":
6208
- return resolve6(base, ".codex", "hooks.json");
7184
+ return resolve10(base, ".codex", "hooks.json");
6209
7185
  case "local":
6210
- return resolve6(base, ".codex", "hooks.json");
7186
+ return resolve10(base, ".codex", "hooks.json");
6211
7187
  }
6212
7188
  },
6213
7189
  readSettings(settingsPath) {
@@ -6285,7 +7261,7 @@ var init_integrations = __esm(() => {
6285
7261
  },
6286
7262
  hooksInstalledInSettings(scope, cwd) {
6287
7263
  const settingsPath = this.getSettingsPath(scope, cwd);
6288
- if (!existsSync11(settingsPath))
7264
+ if (!existsSync15(settingsPath))
6289
7265
  return false;
6290
7266
  try {
6291
7267
  const settings = this.readSettings(settingsPath);
@@ -6314,14 +7290,14 @@ var init_integrations = __esm(() => {
6314
7290
  scopes: COPILOT_HOOK_SCOPES,
6315
7291
  eventTypes: COPILOT_HOOK_EVENT_TYPES,
6316
7292
  getSettingsPath(scope, cwd) {
6317
- const base = cwd ? resolve6(cwd) : process.cwd();
7293
+ const base = cwd ? resolve10(cwd) : process.cwd();
6318
7294
  switch (scope) {
6319
7295
  case "user":
6320
- return resolve6(homedir18(), ".copilot", "hooks", "failproofai.json");
7296
+ return resolve10(homedir22(), ".copilot", "hooks", "failproofai.json");
6321
7297
  case "project":
6322
- return resolve6(base, ".github", "hooks", "failproofai.json");
7298
+ return resolve10(base, ".github", "hooks", "failproofai.json");
6323
7299
  case "local":
6324
- return resolve6(base, ".github", "hooks", "failproofai.json");
7300
+ return resolve10(base, ".github", "hooks", "failproofai.json");
6325
7301
  }
6326
7302
  },
6327
7303
  readSettings(settingsPath) {
@@ -6399,7 +7375,7 @@ var init_integrations = __esm(() => {
6399
7375
  },
6400
7376
  hooksInstalledInSettings(scope, cwd) {
6401
7377
  const settingsPath = this.getSettingsPath(scope, cwd);
6402
- if (!existsSync11(settingsPath))
7378
+ if (!existsSync15(settingsPath))
6403
7379
  return false;
6404
7380
  try {
6405
7381
  const settings = this.readSettings(settingsPath);
@@ -6428,14 +7404,14 @@ var init_integrations = __esm(() => {
6428
7404
  scopes: CURSOR_HOOK_SCOPES,
6429
7405
  eventTypes: CURSOR_HOOK_EVENT_TYPES,
6430
7406
  getSettingsPath(scope, cwd) {
6431
- const base = cwd ? resolve6(cwd) : process.cwd();
7407
+ const base = cwd ? resolve10(cwd) : process.cwd();
6432
7408
  switch (scope) {
6433
7409
  case "user":
6434
- return resolve6(homedir18(), ".cursor", "hooks.json");
7410
+ return resolve10(homedir22(), ".cursor", "hooks.json");
6435
7411
  case "project":
6436
- return resolve6(base, ".cursor", "hooks.json");
7412
+ return resolve10(base, ".cursor", "hooks.json");
6437
7413
  case "local":
6438
- return resolve6(base, ".cursor", "hooks.json");
7414
+ return resolve10(base, ".cursor", "hooks.json");
6439
7415
  }
6440
7416
  },
6441
7417
  readSettings(settingsPath) {
@@ -6502,7 +7478,7 @@ var init_integrations = __esm(() => {
6502
7478
  },
6503
7479
  hooksInstalledInSettings(scope, cwd) {
6504
7480
  const settingsPath = this.getSettingsPath(scope, cwd);
6505
- if (!existsSync11(settingsPath))
7481
+ if (!existsSync15(settingsPath))
6506
7482
  return false;
6507
7483
  try {
6508
7484
  const settings = this.readSettings(settingsPath);
@@ -6527,14 +7503,14 @@ var init_integrations = __esm(() => {
6527
7503
  scopes: OPENCODE_HOOK_SCOPES,
6528
7504
  eventTypes: OPENCODE_HOOK_EVENT_TYPES,
6529
7505
  getSettingsPath(scope, cwd) {
6530
- const base = cwd ? resolve6(cwd) : process.cwd();
7506
+ const base = cwd ? resolve10(cwd) : process.cwd();
6531
7507
  switch (scope) {
6532
7508
  case "user":
6533
- return resolve6(homedir18(), ".config", "opencode", "opencode.json");
7509
+ return resolve10(homedir22(), ".config", "opencode", "opencode.json");
6534
7510
  case "project":
6535
- return resolve6(base, ".opencode", "opencode.json");
7511
+ return resolve10(base, ".opencode", "opencode.json");
6536
7512
  case "local":
6537
- return resolve6(base, ".opencode", "opencode.json");
7513
+ return resolve10(base, ".opencode", "opencode.json");
6538
7514
  }
6539
7515
  },
6540
7516
  readSettings(settingsPath) {
@@ -6545,7 +7521,7 @@ var init_integrations = __esm(() => {
6545
7521
  },
6546
7522
  buildHookEntry(_binaryPath, _eventType, scope) {
6547
7523
  if (scope === "user") {
6548
- const abs = resolve6(homedir18(), ".config", "opencode", "plugins", "failproofai.mjs");
7524
+ const abs = resolve10(homedir22(), ".config", "opencode", "plugins", "failproofai.mjs");
6549
7525
  return { spec: `file://${abs}`, [FAILPROOFAI_HOOK_MARKER]: true };
6550
7526
  }
6551
7527
  return { spec: OPENCODE_PLUGIN_REL_PATH, [FAILPROOFAI_HOOK_MARKER]: true };
@@ -6560,7 +7536,7 @@ var init_integrations = __esm(() => {
6560
7536
  writeHookEntries(settings, binaryPath, scope) {
6561
7537
  const s = settings;
6562
7538
  const effectiveScope = scope ?? "project";
6563
- const settingsPath = effectiveScope === "user" ? resolve6(homedir18(), ".config", "opencode", "opencode.json") : resolve6(process.cwd(), ".opencode", "opencode.json");
7539
+ const settingsPath = effectiveScope === "user" ? resolve10(homedir22(), ".config", "opencode", "opencode.json") : resolve10(process.cwd(), ".opencode", "opencode.json");
6564
7540
  const pluginPath = opencodePluginFilePath(settingsPath);
6565
7541
  mkdirSync8(dirname5(pluginPath), { recursive: true });
6566
7542
  writeFileSync6(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope), "utf8");
@@ -6586,9 +7562,9 @@ var init_integrations = __esm(() => {
6586
7562
  }
6587
7563
  this.writeSettings(settingsPath, settings);
6588
7564
  const pluginPath = opencodePluginFilePath(settingsPath);
6589
- if (existsSync11(pluginPath)) {
7565
+ if (existsSync15(pluginPath)) {
6590
7566
  try {
6591
- const content = readFileSync8(pluginPath, "utf8");
7567
+ const content = readFileSync12(pluginPath, "utf8");
6592
7568
  if (content.includes(FAILPROOFAI_HOOK_MARKER)) {
6593
7569
  unlinkSync5(pluginPath);
6594
7570
  if (removed === 0)
@@ -6600,7 +7576,7 @@ var init_integrations = __esm(() => {
6600
7576
  },
6601
7577
  hooksInstalledInSettings(scope, cwd) {
6602
7578
  const settingsPath = this.getSettingsPath(scope, cwd);
6603
- if (!existsSync11(settingsPath))
7579
+ if (!existsSync15(settingsPath))
6604
7580
  return false;
6605
7581
  try {
6606
7582
  const settings = this.readSettings(settingsPath);
@@ -6610,9 +7586,9 @@ var init_integrations = __esm(() => {
6610
7586
  if (!hasEntry)
6611
7587
  return false;
6612
7588
  const pluginPath = opencodePluginFilePath(settingsPath);
6613
- if (!existsSync11(pluginPath))
7589
+ if (!existsSync15(pluginPath))
6614
7590
  return false;
6615
- const content = readFileSync8(pluginPath, "utf8");
7591
+ const content = readFileSync12(pluginPath, "utf8");
6616
7592
  return content.includes(FAILPROOFAI_HOOK_MARKER);
6617
7593
  } catch {
6618
7594
  return false;
@@ -6628,14 +7604,14 @@ var init_integrations = __esm(() => {
6628
7604
  scopes: PI_HOOK_SCOPES,
6629
7605
  eventTypes: PI_HOOK_EVENT_TYPES,
6630
7606
  getSettingsPath(scope, cwd) {
6631
- const base = cwd ? resolve6(cwd) : process.cwd();
7607
+ const base = cwd ? resolve10(cwd) : process.cwd();
6632
7608
  switch (scope) {
6633
7609
  case "user":
6634
- return resolve6(homedir18(), ".pi", "agent", "settings.json");
7610
+ return resolve10(homedir22(), ".pi", "agent", "settings.json");
6635
7611
  case "project":
6636
- return resolve6(base, ".pi", "settings.json");
7612
+ return resolve10(base, ".pi", "settings.json");
6637
7613
  case "local":
6638
- return resolve6(base, ".pi", "settings.json");
7614
+ return resolve10(base, ".pi", "settings.json");
6639
7615
  }
6640
7616
  },
6641
7617
  readSettings(settingsPath) {
@@ -6677,7 +7653,7 @@ var init_integrations = __esm(() => {
6677
7653
  }
6678
7654
  },
6679
7655
  removeHooksFromFile(settingsPath) {
6680
- if (!existsSync11(settingsPath))
7656
+ if (!existsSync15(settingsPath))
6681
7657
  return 0;
6682
7658
  const settings = this.readSettings(settingsPath);
6683
7659
  if (!Array.isArray(settings.packages))
@@ -6692,7 +7668,7 @@ var init_integrations = __esm(() => {
6692
7668
  },
6693
7669
  hooksInstalledInSettings(scope, cwd) {
6694
7670
  const settingsPath = this.getSettingsPath(scope, cwd);
6695
- if (!existsSync11(settingsPath))
7671
+ if (!existsSync15(settingsPath))
6696
7672
  return false;
6697
7673
  try {
6698
7674
  const settings = this.readSettings(settingsPath);
@@ -6713,14 +7689,14 @@ var init_integrations = __esm(() => {
6713
7689
  scopes: GEMINI_HOOK_SCOPES,
6714
7690
  eventTypes: GEMINI_HOOK_EVENT_TYPES,
6715
7691
  getSettingsPath(scope, cwd) {
6716
- const base = cwd ? resolve6(cwd) : process.cwd();
7692
+ const base = cwd ? resolve10(cwd) : process.cwd();
6717
7693
  switch (scope) {
6718
7694
  case "user":
6719
- return resolve6(homedir18(), ".gemini", "settings.json");
7695
+ return resolve10(homedir22(), ".gemini", "settings.json");
6720
7696
  case "project":
6721
- return resolve6(base, ".gemini", "settings.json");
7697
+ return resolve10(base, ".gemini", "settings.json");
6722
7698
  case "local":
6723
- return resolve6(base, ".gemini", "settings.json");
7699
+ return resolve10(base, ".gemini", "settings.json");
6724
7700
  }
6725
7701
  },
6726
7702
  readSettings(settingsPath) {
@@ -6792,7 +7768,7 @@ var init_integrations = __esm(() => {
6792
7768
  },
6793
7769
  hooksInstalledInSettings(scope, cwd) {
6794
7770
  const settingsPath = this.getSettingsPath(scope, cwd);
6795
- if (!existsSync11(settingsPath))
7771
+ if (!existsSync15(settingsPath))
6796
7772
  return false;
6797
7773
  try {
6798
7774
  const settings = this.readSettings(settingsPath);
@@ -7014,7 +7990,7 @@ async function promptPolicySelection(preSelected, options = {}) {
7014
7990
  process.stdout.write(output);
7015
7991
  lastLineCount = lines.length;
7016
7992
  }
7017
- return new Promise((resolve7) => {
7993
+ return new Promise((resolve11) => {
7018
7994
  render();
7019
7995
  process.stdin.setRawMode(true);
7020
7996
  process.stdin.resume();
@@ -7056,7 +8032,7 @@ async function promptPolicySelection(preSelected, options = {}) {
7056
8032
  const selected = items.filter((i) => i.selected).map((i) => i.name);
7057
8033
  process.stdout.write(`
7058
8034
  `);
7059
- resolve7(selected);
8035
+ resolve11(selected);
7060
8036
  } else if (key.name === "backspace" || key.name === "delete") {
7061
8037
  if (search.length > 0) {
7062
8038
  search = search.slice(0, -1);
@@ -7106,9 +8082,9 @@ __export(exports_manager, {
7106
8082
  getSettingsPath: () => getSettingsPath
7107
8083
  });
7108
8084
  import { execSync as execSync4 } from "node:child_process";
7109
- import { existsSync as existsSync12 } from "node:fs";
7110
- import { resolve as resolve7, basename as basename3 } from "node:path";
7111
- import { homedir as homedir19, platform, arch, release, hostname } from "node:os";
8085
+ import { existsSync as existsSync16 } from "node:fs";
8086
+ import { resolve as resolve11, basename as basename4 } from "node:path";
8087
+ import { homedir as homedir23, platform, arch, release, hostname } from "node:os";
7112
8088
  function getSettingsPath(scope, cwd) {
7113
8089
  return claudeCode.getSettingsPath(scope, cwd);
7114
8090
  }
@@ -7194,7 +8170,7 @@ async function installHooks(policyNames, scope = "user", cwd, includeBeta = fals
7194
8170
  if (removeCustomHooks) {
7195
8171
  delete configToWrite.customPoliciesPath;
7196
8172
  } else if (customPoliciesPath) {
7197
- configToWrite.customPoliciesPath = resolve7(customPoliciesPath);
8173
+ configToWrite.customPoliciesPath = resolve11(customPoliciesPath);
7198
8174
  let validatedHooks = [];
7199
8175
  try {
7200
8176
  validatedHooks = await loadCustomHooks(configToWrite.customPoliciesPath, { strict: true });
@@ -7329,7 +8305,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
7329
8305
  const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
7330
8306
  for (const s of scopesToRemove) {
7331
8307
  const settingsPath = integration.getSettingsPath(s, cwd);
7332
- if (!existsSync12(settingsPath)) {
8308
+ if (!existsSync16(settingsPath)) {
7333
8309
  if (scope !== "all" && selectedClis.length === 1) {
7334
8310
  console.log("No settings file found. Nothing to remove.");
7335
8311
  nothingToReport = true;
@@ -7508,7 +8484,7 @@ Failproof AI Hook Policies
7508
8484
  if (config.customPoliciesPath) {
7509
8485
  console.log(`
7510
8486
  ── Custom Policies (${config.customPoliciesPath}) ───────────────────────`);
7511
- if (!existsSync12(config.customPoliciesPath)) {
8487
+ if (!existsSync16(config.customPoliciesPath)) {
7512
8488
  console.log(` \x1B[31m✗ File not found: ${config.customPoliciesPath}\x1B[0m`);
7513
8489
  } else {
7514
8490
  const hooks = await loadCustomHooks(config.customPoliciesPath);
@@ -7523,10 +8499,10 @@ Failproof AI Hook Policies
7523
8499
  }
7524
8500
  console.log();
7525
8501
  }
7526
- const base = cwd ? resolve7(cwd) : process.cwd();
8502
+ const base = cwd ? resolve11(cwd) : process.cwd();
7527
8503
  const conventionDirs = [
7528
- { label: "Project", dir: resolve7(base, ".failproofai", "policies") },
7529
- { label: "User", dir: resolve7(homedir19(), ".failproofai", "policies") }
8504
+ { label: "Project", dir: resolve11(base, ".failproofai", "policies") },
8505
+ { label: "User", dir: resolve11(homedir23(), ".failproofai", "policies") }
7530
8506
  ];
7531
8507
  for (const { label, dir } of conventionDirs) {
7532
8508
  const files = discoverPolicyFiles(dir);
@@ -7538,15 +8514,15 @@ Failproof AI Hook Policies
7538
8514
  try {
7539
8515
  const hooks = await loadCustomHooks(file);
7540
8516
  if (hooks.length === 0) {
7541
- const filename = basename3(file);
8517
+ const filename = basename4(file);
7542
8518
  console.log(` \x1B[31m✗\x1B[0m ${filename.padEnd(nameColWidth)}\x1B[31mfailed to load\x1B[0m`);
7543
8519
  } else {
7544
- const filename = basename3(file);
8520
+ const filename = basename4(file);
7545
8521
  const hookSummary = hooks.map((h) => h.name).join(", ");
7546
8522
  console.log(` \x1B[32m✓\x1B[0m ${filename.padEnd(nameColWidth)}${hooks.length} hook(s): ${hookSummary}`);
7547
8523
  }
7548
8524
  } catch {
7549
- const filename = basename3(file);
8525
+ const filename = basename4(file);
7550
8526
  console.log(` \x1B[31m✗\x1B[0m ${filename.padEnd(nameColWidth)}\x1B[31merror\x1B[0m`);
7551
8527
  }
7552
8528
  }
@@ -7675,7 +8651,7 @@ async function promptCliTargetSelection(detected, action = "install") {
7675
8651
  process.stdout.write(output);
7676
8652
  lastLineCount = lines.length;
7677
8653
  }
7678
- return new Promise((resolve8) => {
8654
+ return new Promise((resolve12) => {
7679
8655
  render();
7680
8656
  readline2.emitKeypressEvents(process.stdin);
7681
8657
  const wasRaw = process.stdin.isRaw;
@@ -7708,7 +8684,7 @@ async function promptCliTargetSelection(detected, action = "install") {
7708
8684
  cleanup();
7709
8685
  process.stdout.write(`
7710
8686
  `);
7711
- resolve8(options[cursor2].value);
8687
+ resolve12(options[cursor2].value);
7712
8688
  }
7713
8689
  }
7714
8690
  process.stdin.on("keypress", onKey);
@@ -7900,7 +8876,7 @@ async function promptPolicySelection2(preSelected, options = {}) {
7900
8876
  process.stdout.write(output);
7901
8877
  lastLineCount = lines.length;
7902
8878
  }
7903
- return new Promise((resolve8) => {
8879
+ return new Promise((resolve12) => {
7904
8880
  render();
7905
8881
  process.stdin.setRawMode(true);
7906
8882
  process.stdin.resume();
@@ -7942,7 +8918,7 @@ async function promptPolicySelection2(preSelected, options = {}) {
7942
8918
  const selected = items.filter((i) => i.selected).map((i) => i.name);
7943
8919
  process.stdout.write(`
7944
8920
  `);
7945
- resolve8(selected);
8921
+ resolve12(selected);
7946
8922
  } else if (key.name === "backspace" || key.name === "delete") {
7947
8923
  if (search.length > 0) {
7948
8924
  search = search.slice(0, -1);
@@ -8104,14 +9080,14 @@ __export(exports_pid, {
8104
9080
  isProcessAlive: () => isProcessAlive2,
8105
9081
  clearPid: () => clearPid2
8106
9082
  });
8107
- import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, existsSync as existsSync13, unlinkSync as unlinkSync6, mkdirSync as mkdirSync9 } from "node:fs";
8108
- import { join as join19, dirname as dirname6 } from "node:path";
8109
- import { homedir as homedir20 } from "node:os";
9083
+ import { readFileSync as readFileSync13, writeFileSync as writeFileSync7, existsSync as existsSync17, unlinkSync as unlinkSync6, mkdirSync as mkdirSync9 } from "node:fs";
9084
+ import { join as join23, dirname as dirname6 } from "node:path";
9085
+ import { homedir as homedir24 } from "node:os";
8110
9086
  function readPid2() {
8111
- if (!existsSync13(PID_FILE2))
9087
+ if (!existsSync17(PID_FILE2))
8112
9088
  return null;
8113
9089
  try {
8114
- const raw = readFileSync9(PID_FILE2, "utf8").trim();
9090
+ const raw = readFileSync13(PID_FILE2, "utf8").trim();
8115
9091
  const pid = parseInt(raw, 10);
8116
9092
  if (Number.isNaN(pid) || pid <= 0)
8117
9093
  return null;
@@ -8122,12 +9098,12 @@ function readPid2() {
8122
9098
  }
8123
9099
  function writePid2(pid) {
8124
9100
  const dir = dirname6(PID_FILE2);
8125
- if (!existsSync13(dir))
9101
+ if (!existsSync17(dir))
8126
9102
  mkdirSync9(dir, { recursive: true, mode: 448 });
8127
9103
  writeFileSync7(PID_FILE2, String(pid));
8128
9104
  }
8129
9105
  function clearPid2() {
8130
- if (existsSync13(PID_FILE2))
9106
+ if (existsSync17(PID_FILE2))
8131
9107
  unlinkSync6(PID_FILE2);
8132
9108
  }
8133
9109
  function isProcessAlive2(pid) {
@@ -8165,18 +9141,18 @@ function relayStatus() {
8165
9141
  }
8166
9142
  var PID_FILE2;
8167
9143
  var init_pid2 = __esm(() => {
8168
- PID_FILE2 = join19(homedir20(), ".failproofai", "relay.pid");
9144
+ PID_FILE2 = join23(homedir24(), ".failproofai", "relay.pid");
8169
9145
  });
8170
9146
 
8171
9147
  // scripts/parse-script-args.ts
8172
- import { resolve as resolve8 } from "path";
9148
+ import { resolve as resolve12 } from "path";
8173
9149
  function parseStringFlag(flagName, errorLabel, inlineValue, args, index, options) {
8174
9150
  const raw = inlineValue ?? args[index + 1];
8175
9151
  if (raw === undefined || inlineValue === null && raw.startsWith("-")) {
8176
9152
  console.error(`Error: ${flagName} requires ${errorLabel}`);
8177
9153
  process.exit(1);
8178
9154
  }
8179
- const value = options?.resolve ? resolve8(raw) : raw;
9155
+ const value = options?.resolve ? resolve12(raw) : raw;
8180
9156
  return { value, spliceCount: inlineValue !== null ? 1 : 2 };
8181
9157
  }
8182
9158
  function parseScriptArgs(argv) {
@@ -8232,21 +9208,21 @@ function parseScriptArgs(argv) {
8232
9208
  var init_parse_script_args = () => {};
8233
9209
 
8234
9210
  // scripts/install-diagnosis.mjs
8235
- import { existsSync as existsSync14, readFileSync as readFileSync10, realpathSync } from "node:fs";
8236
- import { dirname as dirname7, resolve as resolve9 } from "node:path";
8237
- import { homedir as homedir21, platform as platform3 } from "node:os";
9211
+ import { existsSync as existsSync18, readFileSync as readFileSync14, realpathSync } from "node:fs";
9212
+ import { dirname as dirname7, resolve as resolve13 } from "node:path";
9213
+ import { homedir as homedir25, platform as platform3 } from "node:os";
8238
9214
  import { spawnSync } from "node:child_process";
8239
9215
  function findPackageRoot(start) {
8240
9216
  try {
8241
9217
  let dir = realpathSync(start);
8242
- if (existsSync14(dir) && !existsSync14(resolve9(dir, "package.json"))) {
9218
+ if (existsSync18(dir) && !existsSync18(resolve13(dir, "package.json"))) {
8243
9219
  dir = dirname7(dir);
8244
9220
  }
8245
9221
  while (true) {
8246
- const pkgPath = resolve9(dir, "package.json");
8247
- if (existsSync14(pkgPath)) {
9222
+ const pkgPath = resolve13(dir, "package.json");
9223
+ if (existsSync18(pkgPath)) {
8248
9224
  try {
8249
- const pkg = JSON.parse(readFileSync10(pkgPath, "utf8"));
9225
+ const pkg = JSON.parse(readFileSync14(pkgPath, "utf8"));
8250
9226
  if (pkg.name === PKG_NAME)
8251
9227
  return dir;
8252
9228
  } catch {}
@@ -8264,7 +9240,7 @@ function readPackageVersion(packageRoot) {
8264
9240
  if (!packageRoot)
8265
9241
  return null;
8266
9242
  try {
8267
- const pkg = JSON.parse(readFileSync10(resolve9(packageRoot, "package.json"), "utf8"));
9243
+ const pkg = JSON.parse(readFileSync14(resolve13(packageRoot, "package.json"), "utf8"));
8268
9244
  return typeof pkg.version === "string" ? pkg.version : null;
8269
9245
  } catch {
8270
9246
  return null;
@@ -8290,16 +9266,16 @@ function locateNpmGlobal() {
8290
9266
  const root = (res.stdout || "").trim();
8291
9267
  if (!root)
8292
9268
  return null;
8293
- const candidate = resolve9(root, PKG_NAME);
8294
- return existsSync14(resolve9(candidate, "package.json")) ? candidate : null;
9269
+ const candidate = resolve13(root, PKG_NAME);
9270
+ return existsSync18(resolve13(candidate, "package.json")) ? candidate : null;
8295
9271
  } catch {
8296
9272
  return null;
8297
9273
  }
8298
9274
  }
8299
9275
  function locateBunGlobal() {
8300
9276
  try {
8301
- const candidate = resolve9(homedir21(), ".bun", "install", "global", "node_modules", PKG_NAME);
8302
- return existsSync14(resolve9(candidate, "package.json")) ? candidate : null;
9277
+ const candidate = resolve13(homedir25(), ".bun", "install", "global", "node_modules", PKG_NAME);
9278
+ return existsSync18(resolve13(candidate, "package.json")) ? candidate : null;
8303
9279
  } catch {
8304
9280
  return null;
8305
9281
  }
@@ -8307,8 +9283,8 @@ function locateBunGlobal() {
8307
9283
  function buildRecommendation(pathFirstBin) {
8308
9284
  if (!pathFirstBin)
8309
9285
  return null;
8310
- const bunBinPrefix = resolve9(homedir21(), ".bun", "bin") + "/";
8311
- const bunGlobalPrefix = resolve9(homedir21(), ".bun", "install", "global") + "/";
9286
+ const bunBinPrefix = resolve13(homedir25(), ".bun", "bin") + "/";
9287
+ const bunGlobalPrefix = resolve13(homedir25(), ".bun", "install", "global") + "/";
8312
9288
  const isBun = pathFirstBin.startsWith(bunBinPrefix) || pathFirstBin.startsWith(bunGlobalPrefix);
8313
9289
  if (isBun) {
8314
9290
  return `rm -f ~/.bun/bin/${PKG_NAME} && rm -rf ~/.bun/install/global/node_modules/${PKG_NAME}`;
@@ -8369,8 +9345,8 @@ __export(exports_launch, {
8369
9345
  launch: () => launch
8370
9346
  });
8371
9347
  import { spawn as spawn4 } from "child_process";
8372
- import { realpathSync as realpathSync2, existsSync as existsSync15 } from "node:fs";
8373
- import { resolve as resolve10, dirname as dirname8 } from "node:path";
9348
+ import { realpathSync as realpathSync2, existsSync as existsSync19 } from "node:fs";
9349
+ import { resolve as resolve14, dirname as dirname8 } from "node:path";
8374
9350
  import { fileURLToPath as fileURLToPath2 } from "node:url";
8375
9351
  function launch(mode) {
8376
9352
  const { claudeProjectsPath: parsedPath, loggingLevel, disableTelemetry, allowedDevOrigins, remainingArgs } = parseScriptArgs(process.argv.slice(2));
@@ -8402,9 +9378,9 @@ function launch(mode) {
8402
9378
  process.env.PORT = port;
8403
9379
  process.env.HOSTNAME = "0.0.0.0";
8404
9380
  cmd = "node";
8405
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve10(dirname8(realpathSync2(fileURLToPath2(import.meta.url))), "..");
8406
- const serverJsPath = resolve10(packageRoot, ".next/standalone/server.js");
8407
- if (!existsSync15(serverJsPath)) {
9381
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve14(dirname8(realpathSync2(fileURLToPath2(import.meta.url))), "..");
9382
+ const serverJsPath = resolve14(packageRoot, ".next/standalone/server.js");
9383
+ if (!existsSync19(serverJsPath)) {
8408
9384
  let shadowMessage = null;
8409
9385
  try {
8410
9386
  const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
@@ -8481,17 +9457,17 @@ var init_cli_error2 = __esm(() => {
8481
9457
 
8482
9458
  // bin/failproofai.mjs
8483
9459
  import { realpathSync as realpathSync3 } from "fs";
8484
- import { dirname as dirname9, resolve as resolve11 } from "path";
9460
+ import { dirname as dirname9, resolve as resolve15 } from "path";
8485
9461
  import { fileURLToPath as fileURLToPath3 } from "url";
8486
9462
  // package.json
8487
- var version = "0.0.10-beta.2";
9463
+ var version = "0.0.10-beta.4";
8488
9464
 
8489
9465
  // bin/failproofai.mjs
8490
9466
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
8491
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve11(dirname9(realpathSync3(fileURLToPath3(import.meta.url))), "..");
9467
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve15(dirname9(realpathSync3(fileURLToPath3(import.meta.url))), "..");
8492
9468
  }
8493
9469
  if (!process.env.FAILPROOFAI_DIST_PATH) {
8494
- process.env.FAILPROOFAI_DIST_PATH = resolve11(dirname9(realpathSync3(fileURLToPath3(import.meta.url))), "..", "dist");
9470
+ process.env.FAILPROOFAI_DIST_PATH = resolve15(dirname9(realpathSync3(fileURLToPath3(import.meta.url))), "..", "dist");
8495
9471
  }
8496
9472
  var args = process.argv.slice(2);
8497
9473
  if (args[0] === "p")