failproofai 1.0.2-beta.4 → 1.0.2-beta.5

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 (147) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +5 -5
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +2 -2
  6. package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
  7. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  8. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
  11. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
  12. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
  13. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  14. package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +2 -2
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js +4 -4
  25. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js +1 -1
  32. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +2 -2
  34. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  35. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/index.html +1 -1
  38. package/.next/standalone/.next/server/app/index.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  40. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  41. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  42. package/.next/standalone/.next/server/app/page/build-manifest.json +2 -2
  43. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  44. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +2 -2
  47. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  48. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +2 -2
  51. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page.js +2 -2
  53. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  58. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js +2 -2
  59. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  60. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +2 -2
  62. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  63. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  64. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  65. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +2 -2
  66. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  67. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  68. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  69. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03r-lqq._.js +3 -0
  70. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  71. package/.next/standalone/.next/server/chunks/[root-of-the-server]__12021ot._.js +3 -0
  72. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1le9jqc._.js +3 -0
  73. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__0clqfab._.js → [root-of-the-server]__1zkek3z._.js} +2 -2
  74. package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/{_1lbh81u._.js → _12moi5-._.js} +1 -1
  76. package/.next/standalone/.next/server/chunks/_1ek68ln._.js +5 -5
  77. package/.next/standalone/.next/server/chunks/_1zuiiy3._.js +1 -1
  78. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  79. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1m84s36._.js → [root-of-the-server]__00-s7h8._.js} +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  83. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__07gm3zl._.js +3 -3
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  88. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__14muoc4._.js → [root-of-the-server]__0stn0gx._.js} +2 -2
  90. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0jzbk4_._.js → [root-of-the-server]__190won8._.js} +1 -1
  91. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +1 -1
  92. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  93. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0rsd3ll._.js → [root-of-the-server]__1sc84bb._.js} +2 -2
  94. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  95. package/.next/standalone/.next/server/chunks/ssr/_1ddpc5g._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/{_1db3-8n._.js → _1if9ixi._.js} +2 -2
  97. package/.next/standalone/.next/server/chunks/ssr/{_1dkh76z._.js → _1kesqs-._.js} +2 -2
  98. package/.next/standalone/.next/server/chunks/ssr/{_0ovx4lz._.js → _1km9-gn._.js} +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  100. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  101. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  102. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  103. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  104. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  105. package/.next/standalone/.next/server/chunks/ssr/lib_1cf5ya2._.js +3 -0
  106. package/.next/standalone/.next/server/chunks/ssr/lib_opencode-projects_ts_15bjxkm._.js +1 -1
  107. package/.next/standalone/.next/server/middleware-build-manifest.js +5 -5
  108. package/.next/standalone/.next/server/pages/404.html +1 -1
  109. package/.next/standalone/.next/server/pages/500.html +1 -1
  110. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  111. package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
  112. package/.next/standalone/.next/static/chunks/{0lshnlpy1m6bc.js → 0tyt-3a5rtzy8.js} +1 -1
  113. package/.next/standalone/.next/static/chunks/{0ds64uculrze8.js → 21r7iw3rmixf5.js} +1 -1
  114. package/.next/standalone/.next/static/chunks/{07j2u70_3qsx8.js → 26lfjhb2kzzgb.js} +1 -1
  115. package/.next/standalone/.next/static/chunks/{2dbi_x0c8n8fi.js → 2_27jraat038x.js} +1 -1
  116. package/.next/standalone/.next/static/chunks/{0d_re32wscs0b.js → 2hwc8e923g5df.js} +1 -1
  117. package/.next/standalone/.next/static/chunks/{1q76jk_1_wgjq.js → 33np9nrh1mvj9.js} +1 -1
  118. package/.next/standalone/.next/static/chunks/{0k_yvjc1yz0pq.js → 36-8i_vbkh85w.js} +1 -1
  119. package/.next/standalone/.next/static/chunks/{1o0ahew9568ls.js → 391tpdqcas7rq.js} +1 -1
  120. package/.next/standalone/.next/static/chunks/{00_t-xvc59tkb.js → 3_b73tc78jwsq.js} +1 -1
  121. package/.next/standalone/.next/static/chunks/{1oz0svxwt9574.js → 3i8rg2fv9nd6e.js} +2 -2
  122. package/.next/standalone/.next/static/chunks/{2817_8e94ah9z.js → 3jqm8ubpv3i-4.js} +1 -1
  123. package/.next/standalone/.next/static/chunks/{turbopack-17utl_jw0wj11.js → turbopack-2x-o099q64i8h.js} +1 -1
  124. package/.next/standalone/lib/opencode-db.ts +77 -0
  125. package/.next/standalone/lib/opencode-projects.ts +37 -41
  126. package/.next/standalone/lib/opencode-sessions.ts +59 -36
  127. package/.next/standalone/package.json +9 -9
  128. package/.next/standalone/server.js +1 -1
  129. package/bin/failproofai.mjs +24 -9
  130. package/dist/cli.mjs +734 -382
  131. package/dist/worker.mjs +179 -164
  132. package/lib/opencode-db.ts +77 -0
  133. package/lib/opencode-projects.ts +37 -41
  134. package/lib/opencode-sessions.ts +59 -36
  135. package/package.json +9 -9
  136. package/src/audit/cache.ts +167 -11
  137. package/src/audit/cli-adapters/claude.ts +111 -1
  138. package/src/audit/cli-adapters/index.ts +31 -1
  139. package/src/audit/index.ts +131 -11
  140. package/src/hooks/manager.ts +50 -3
  141. package/src/hooks/pack-cli.ts +237 -11
  142. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1l-khtb._.js +0 -3
  143. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1mhmdzs._.js +0 -3
  144. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1qxztj-._.js +0 -3
  145. /package/.next/standalone/.next/static/{0iNzkTsP6rh14Rj5WL17o → 59jsH11LoyXu9UBoHvgGM}/_buildManifest.js +0 -0
  146. /package/.next/standalone/.next/static/{0iNzkTsP6rh14Rj5WL17o → 59jsH11LoyXu9UBoHvgGM}/_clientMiddlewareManifest.js +0 -0
  147. /package/.next/standalone/.next/static/{0iNzkTsP6rh14Rj5WL17o → 59jsH11LoyXu9UBoHvgGM}/_ssgManifest.js +0 -0
package/dist/cli.mjs CHANGED
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
19
19
  var __require = /* @__PURE__ */ createRequire(import.meta.url);
20
20
 
21
21
  // package.json
22
- var version2 = "1.0.2-beta.4", package_default;
22
+ var version2 = "1.0.2-beta.5", package_default;
23
23
  var init_package = __esm(() => {
24
24
  package_default = {
25
25
  name: "failproofai",
@@ -143,16 +143,16 @@ var init_package = __esm(() => {
143
143
  sharp: "0.35.0"
144
144
  },
145
145
  optionalDependencies: {
146
- "@failproofai/failproofaid-linux-x64": "1.0.2-beta.4",
147
- "@failproofai/failproofaid-linux-arm64": "1.0.2-beta.4",
148
- "@failproofai/failproofaid-darwin-x64": "1.0.2-beta.4",
149
- "@failproofai/failproofaid-darwin-arm64": "1.0.2-beta.4"
146
+ "@failproofai/failproofaid-linux-x64": "1.0.2-beta.5",
147
+ "@failproofai/failproofaid-linux-arm64": "1.0.2-beta.5",
148
+ "@failproofai/failproofaid-darwin-x64": "1.0.2-beta.5",
149
+ "@failproofai/failproofaid-darwin-arm64": "1.0.2-beta.5"
150
150
  },
151
151
  failproofaidBinaries: {
152
- "linux-x64": "08bc00a7f8d7c80bf898471ce59c57f4e96c1420080009cc933b2ddeb4f23750",
153
- "linux-arm64": "1167d809628cff04c38efbc0eaa83ca26ab8de2878bed0ef59ca43054173eea7",
154
- "darwin-x64": "6ed32db21af6869c4475e753e524ad8e128436674209ad778421b240a4bd5c53",
155
- "darwin-arm64": "3843de034c9d6b11f77c1f423e6201ad6a77b7eff3b3d4460ba324c5aeb62021"
152
+ "linux-x64": "e19a1cf9a254df830f205fac024b8a229c162c93ae73851b985d2794e09da035",
153
+ "linux-arm64": "fafcff01e4cce00809b5cd9ff2822705d7373acbab79444e0384cb058b6da921",
154
+ "darwin-x64": "d7bd609387e13f5e75287674d948c69d739bac8d6963aa731b93111d1bdd2ea2",
155
+ "darwin-arm64": "9a57c8eb0f23ed25328e0f7b06638a6ab7f51e1deebf479bac2c779bf9912941"
156
156
  }
157
157
  };
158
158
  });
@@ -6055,6 +6055,95 @@ var init_cursor_projects = __esm(() => {
6055
6055
  getCachedCursorSessionsByEncodedName = runtimeCache((name) => getCursorSessionsByEncodedName(name), 30, { maxSize: 50 });
6056
6056
  });
6057
6057
 
6058
+ // lib/sqlite-reader.ts
6059
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
6060
+ import initSqlJs from "sql.js/dist/sql-asm.js";
6061
+ async function tryNodeSqlite(dbPath) {
6062
+ try {
6063
+ const mod = await import("node:sqlite");
6064
+ const db = new mod.DatabaseSync(dbPath, { readOnly: true });
6065
+ return {
6066
+ query(sql, params = []) {
6067
+ const stmt = db.prepare(sql);
6068
+ return params.length ? stmt.all(...params) : stmt.all();
6069
+ },
6070
+ close() {
6071
+ db.close();
6072
+ }
6073
+ };
6074
+ } catch {
6075
+ return null;
6076
+ }
6077
+ }
6078
+ function loadSqlJs() {
6079
+ if (!sqlPromise)
6080
+ sqlPromise = initSqlJs();
6081
+ return sqlPromise;
6082
+ }
6083
+ async function trySqlJs(dbPath) {
6084
+ try {
6085
+ const SQL = await loadSqlJs();
6086
+ const db = new SQL.Database(readFileSync4(dbPath));
6087
+ return {
6088
+ query(sql, params) {
6089
+ const stmt = db.prepare(sql);
6090
+ try {
6091
+ if (params && params.length)
6092
+ stmt.bind(params);
6093
+ const rows = [];
6094
+ while (stmt.step())
6095
+ rows.push(stmt.getAsObject());
6096
+ return rows;
6097
+ } finally {
6098
+ stmt.free();
6099
+ }
6100
+ },
6101
+ close() {
6102
+ db.close();
6103
+ }
6104
+ };
6105
+ } catch {
6106
+ return null;
6107
+ }
6108
+ }
6109
+ async function openSqliteReadonly(dbPath) {
6110
+ if (!existsSync8(dbPath))
6111
+ return null;
6112
+ return await tryNodeSqlite(dbPath) ?? await trySqlJs(dbPath);
6113
+ }
6114
+ var sqlPromise = null;
6115
+ var init_sqlite_reader = () => {};
6116
+
6117
+ // lib/opencode-db.ts
6118
+ import { homedir as homedir8 } from "node:os";
6119
+ import { join as join10 } from "node:path";
6120
+ function opencodeDbPath() {
6121
+ if (process.env.OPENCODE_DB_PATH)
6122
+ return process.env.OPENCODE_DB_PATH;
6123
+ const home = process.env.OPENCODE_HOME ?? join10(homedir8(), ".local", "share", "opencode");
6124
+ return join10(home, "opencode.db");
6125
+ }
6126
+ async function withOpenCodeDb(fn) {
6127
+ const db = await openSqliteReadonly(opencodeDbPath());
6128
+ if (!db)
6129
+ return null;
6130
+ try {
6131
+ return fn(db);
6132
+ } catch {
6133
+ return null;
6134
+ } finally {
6135
+ try {
6136
+ db.close();
6137
+ } catch {}
6138
+ }
6139
+ }
6140
+ async function queryOpenCodeDb(sql, params = []) {
6141
+ return withOpenCodeDb((db) => db.query(sql, params));
6142
+ }
6143
+ var init_opencode_db = __esm(() => {
6144
+ init_sqlite_reader();
6145
+ });
6146
+
6058
6147
  // lib/opencode-projects.ts
6059
6148
  var exports_opencode_projects = {};
6060
6149
  __export(exports_opencode_projects, {
@@ -6065,33 +6154,18 @@ __export(exports_opencode_projects, {
6065
6154
  getOpenCodeSessionsByEncodedName: () => getOpenCodeSessionsByEncodedName,
6066
6155
  getOpenCodeSessionsForCwd: () => getOpenCodeSessionsForCwd
6067
6156
  });
6068
- import { execFileSync as execFileSync2 } from "node:child_process";
6069
- function runOpenCodeDb(sql) {
6070
- try {
6071
- const stdout = execFileSync2("opencode", ["db", "--format", "json", sql], {
6072
- encoding: "utf8",
6073
- timeout: 5000,
6074
- stdio: ["ignore", "pipe", "pipe"]
6075
- });
6076
- if (!stdout.trim())
6077
- return [];
6078
- const parsed = JSON.parse(stdout);
6079
- if (!Array.isArray(parsed))
6080
- return null;
6081
- return parsed;
6082
- } catch {
6083
- return null;
6084
- }
6085
- }
6086
- function readSessionRows() {
6087
- return runOpenCodeDb(`SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session ORDER BY time_updated DESC LIMIT ${SESSION_LIMIT}`);
6157
+ async function readSessionRows() {
6158
+ return queryOpenCodeDb("SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session ORDER BY time_updated DESC LIMIT ?", [SESSION_LIMIT]);
6088
6159
  }
6089
- function readProjectRows() {
6090
- return runOpenCodeDb(`SELECT id, worktree, vcs, name, time_created, time_updated FROM project`);
6160
+ async function readBothRows() {
6161
+ const rows = await withOpenCodeDb((db) => ({
6162
+ sessions: db.query("SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session ORDER BY time_updated DESC LIMIT ?", [SESSION_LIMIT]),
6163
+ projects: db.query("SELECT id, worktree, vcs, name, time_created, time_updated FROM project")
6164
+ }));
6165
+ return { sessions: rows?.sessions ?? null, projects: rows?.projects ?? null };
6091
6166
  }
6092
6167
  async function getOpenCodeProjects() {
6093
- const sessions = readSessionRows();
6094
- const projects = readProjectRows();
6168
+ const { sessions, projects } = await readBothRows();
6095
6169
  if (sessions === null && projects === null) {
6096
6170
  return [];
6097
6171
  }
@@ -6148,7 +6222,7 @@ async function getOpenCodeProjects() {
6148
6222
  return out;
6149
6223
  }
6150
6224
  async function getOpenCodeSessionsForCwd(cwd) {
6151
- const sessions = readSessionRows();
6225
+ const sessions = await readSessionRows();
6152
6226
  if (!sessions)
6153
6227
  return [];
6154
6228
  const matches = sessions.filter((s) => s.directory === cwd);
@@ -6168,8 +6242,7 @@ async function getOpenCodeSessionsByEncodedName(name) {
6168
6242
  let projects;
6169
6243
  let sessions;
6170
6244
  try {
6171
- projects = readProjectRows();
6172
- sessions = readSessionRows();
6245
+ ({ projects, sessions } = await readBothRows());
6173
6246
  } catch (error) {
6174
6247
  logWarn("Failed to read OpenCode DB:", error);
6175
6248
  return { cwd: null, sessions: [] };
@@ -6197,6 +6270,7 @@ async function getOpenCodeSessionsByEncodedName(name) {
6197
6270
  }
6198
6271
  var SESSION_LIMIT = 1000, getCachedOpenCodeProjects, getCachedOpenCodeSessionsForCwd, getCachedOpenCodeSessionsByEncodedName;
6199
6272
  var init_opencode_projects = __esm(() => {
6273
+ init_opencode_db();
6200
6274
  init_paths();
6201
6275
  init_logger();
6202
6276
  getCachedOpenCodeProjects = runtimeCache(getOpenCodeProjects, 30);
@@ -6215,10 +6289,10 @@ __export(exports_pi_projects, {
6215
6289
  getPiSessionsForCwd: () => getPiSessionsForCwd
6216
6290
  });
6217
6291
  import { readdir as readdir4, readFile as readFile6, stat as stat3 } from "node:fs/promises";
6218
- import { homedir as homedir8 } from "node:os";
6219
- import { join as join10 } from "node:path";
6292
+ import { homedir as homedir9 } from "node:os";
6293
+ import { join as join11 } from "node:path";
6220
6294
  function getPiSessionsRoot() {
6221
- return process.env.PI_SESSIONS_DIR || join10(homedir8(), ".pi", "agent", "sessions");
6295
+ return process.env.PI_SESSIONS_DIR || join11(homedir9(), ".pi", "agent", "sessions");
6222
6296
  }
6223
6297
  async function safeReaddir4(dir) {
6224
6298
  try {
@@ -6266,7 +6340,7 @@ async function scanPiSessions() {
6266
6340
  for (const cwdDir of cwdDirs) {
6267
6341
  if (!cwdDir.isDirectory())
6268
6342
  continue;
6269
- const cwdPath = join10(root, cwdDir.name);
6343
+ const cwdPath = join11(root, cwdDir.name);
6270
6344
  const sessionFiles = await safeReaddir4(cwdPath);
6271
6345
  if (!sessionFiles)
6272
6346
  continue;
@@ -6276,7 +6350,7 @@ async function scanPiSessions() {
6276
6350
  const m = SESSION_FILE_RE.exec(f.name);
6277
6351
  if (!m)
6278
6352
  continue;
6279
- candidates.push({ sessionId: m[1], filePath: join10(cwdPath, f.name) });
6353
+ candidates.push({ sessionId: m[1], filePath: join11(cwdPath, f.name) });
6280
6354
  }
6281
6355
  }
6282
6356
  if (candidates.length === 0)
@@ -6377,69 +6451,10 @@ var init_pi_projects = __esm(() => {
6377
6451
  getCachedPiSessionsByEncodedName = runtimeCache((name) => getPiSessionsByEncodedName(name), 30, { maxSize: 50 });
6378
6452
  });
6379
6453
 
6380
- // lib/sqlite-reader.ts
6381
- import { existsSync as existsSync8, readFileSync as readFileSync4 } from "node:fs";
6382
- import initSqlJs from "sql.js/dist/sql-asm.js";
6383
- async function tryNodeSqlite(dbPath) {
6384
- try {
6385
- const mod = await import("node:sqlite");
6386
- const db = new mod.DatabaseSync(dbPath, { readOnly: true });
6387
- return {
6388
- query(sql, params = []) {
6389
- const stmt = db.prepare(sql);
6390
- return params.length ? stmt.all(...params) : stmt.all();
6391
- },
6392
- close() {
6393
- db.close();
6394
- }
6395
- };
6396
- } catch {
6397
- return null;
6398
- }
6399
- }
6400
- function loadSqlJs() {
6401
- if (!sqlPromise)
6402
- sqlPromise = initSqlJs();
6403
- return sqlPromise;
6404
- }
6405
- async function trySqlJs(dbPath) {
6406
- try {
6407
- const SQL = await loadSqlJs();
6408
- const db = new SQL.Database(readFileSync4(dbPath));
6409
- return {
6410
- query(sql, params) {
6411
- const stmt = db.prepare(sql);
6412
- try {
6413
- if (params && params.length)
6414
- stmt.bind(params);
6415
- const rows = [];
6416
- while (stmt.step())
6417
- rows.push(stmt.getAsObject());
6418
- return rows;
6419
- } finally {
6420
- stmt.free();
6421
- }
6422
- },
6423
- close() {
6424
- db.close();
6425
- }
6426
- };
6427
- } catch {
6428
- return null;
6429
- }
6430
- }
6431
- async function openSqliteReadonly(dbPath) {
6432
- if (!existsSync8(dbPath))
6433
- return null;
6434
- return await tryNodeSqlite(dbPath) ?? await trySqlJs(dbPath);
6435
- }
6436
- var sqlPromise = null;
6437
- var init_sqlite_reader = () => {};
6438
-
6439
6454
  // lib/hermes-profiles.ts
6440
6455
  import { readdirSync as readdirSync4 } from "node:fs";
6441
- import { homedir as homedir9 } from "node:os";
6442
- import { basename as basename2, dirname as dirname4, join as join11, resolve as resolve6 } from "node:path";
6456
+ import { homedir as homedir10 } from "node:os";
6457
+ import { basename as basename2, dirname as dirname4, join as join12, resolve as resolve6 } from "node:path";
6443
6458
  function hermesRoot() {
6444
6459
  const env = (process.env.HERMES_HOME || "").trim();
6445
6460
  if (env) {
@@ -6449,7 +6464,7 @@ function hermesRoot() {
6449
6464
  return dirname4(parent);
6450
6465
  return home;
6451
6466
  }
6452
- return join11(homedir9(), ".hermes");
6467
+ return join12(homedir10(), ".hermes");
6453
6468
  }
6454
6469
  function listHermesProfiles() {
6455
6470
  const root = hermesRoot();
@@ -6457,7 +6472,7 @@ function listHermesProfiles() {
6457
6472
  const seen = new Set([HERMES_DEFAULT_PROFILE]);
6458
6473
  let names;
6459
6474
  try {
6460
- names = readdirSync4(join11(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
6475
+ names = readdirSync4(join12(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
6461
6476
  } catch {
6462
6477
  return out;
6463
6478
  }
@@ -6465,7 +6480,7 @@ function listHermesProfiles() {
6465
6480
  if (seen.has(name))
6466
6481
  continue;
6467
6482
  seen.add(name);
6468
- out.push({ name, home: join11(root, PROFILES_DIR, name) });
6483
+ out.push({ name, home: join12(root, PROFILES_DIR, name) });
6469
6484
  }
6470
6485
  return out;
6471
6486
  }
@@ -6516,14 +6531,14 @@ function formatDuration(ms) {
6516
6531
  }
6517
6532
 
6518
6533
  // lib/hermes-sessions.ts
6519
- import { join as join12 } from "node:path";
6534
+ import { join as join13 } from "node:path";
6520
6535
  function hermesDbPaths() {
6521
6536
  const override = process.env.HERMES_DB_PATH;
6522
6537
  if (override)
6523
6538
  return [{ profile: HERMES_DEFAULT_PROFILE, dbPath: override }];
6524
6539
  return listHermesProfiles().map((p) => ({
6525
6540
  profile: p.name,
6526
- dbPath: join12(p.home, "state.db")
6541
+ dbPath: join13(p.home, "state.db")
6527
6542
  }));
6528
6543
  }
6529
6544
  function epochToMs(value) {
@@ -6821,10 +6836,10 @@ var init_hermes_projects = __esm(() => {
6821
6836
  // lib/openclaw-sessions.ts
6822
6837
  import { readFile as readFile7 } from "node:fs/promises";
6823
6838
  import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
6824
- import { homedir as homedir10 } from "node:os";
6825
- import { join as join13 } from "node:path";
6839
+ import { homedir as homedir11 } from "node:os";
6840
+ import { join as join14 } from "node:path";
6826
6841
  function openclawHome() {
6827
- return process.env.OPENCLAW_HOME || join13(homedir10(), ".openclaw");
6842
+ return process.env.OPENCLAW_HOME || join14(homedir11(), ".openclaw");
6828
6843
  }
6829
6844
  function isPlainObject3(v) {
6830
6845
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -6939,13 +6954,13 @@ function openclawLinesToLogEntries(lines, source = "session") {
6939
6954
  }
6940
6955
  function listOpenClawAgents() {
6941
6956
  try {
6942
- return readdirSync5(join13(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
6957
+ return readdirSync5(join14(openclawHome(), "agents"), { withFileTypes: true }).filter((d) => d.isDirectory() && !d.name.startsWith(".")).map((d) => d.name).sort();
6943
6958
  } catch {
6944
6959
  return [];
6945
6960
  }
6946
6961
  }
6947
6962
  function listOpenClawTranscripts() {
6948
- const agentsDir = join13(openclawHome(), "agents");
6963
+ const agentsDir = join14(openclawHome(), "agents");
6949
6964
  const out = [];
6950
6965
  let agentIds;
6951
6966
  try {
@@ -6954,7 +6969,7 @@ function listOpenClawTranscripts() {
6954
6969
  return out;
6955
6970
  }
6956
6971
  for (const agentId of agentIds) {
6957
- const sessionsDir = join13(agentsDir, agentId, "sessions");
6972
+ const sessionsDir = join14(agentsDir, agentId, "sessions");
6958
6973
  let files;
6959
6974
  try {
6960
6975
  files = readdirSync5(sessionsDir);
@@ -6967,7 +6982,7 @@ function listOpenClawTranscripts() {
6967
6982
  const sessionId = file.slice(0, -".jsonl".length);
6968
6983
  if (!OPENCLAW_SESSION_ID_RE.test(sessionId))
6969
6984
  continue;
6970
- const transcriptPath = join13(sessionsDir, file);
6985
+ const transcriptPath = join14(sessionsDir, file);
6971
6986
  try {
6972
6987
  const st = statSync7(transcriptPath);
6973
6988
  out.push({ agentId, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -7028,13 +7043,13 @@ __export(exports_openclaw_projects, {
7028
7043
  parseOpenClawProjectName: () => parseOpenClawProjectName
7029
7044
  });
7030
7045
  import { readFileSync as readFileSync5 } from "node:fs";
7031
- import { join as join14 } from "node:path";
7046
+ import { join as join15 } from "node:path";
7032
7047
  function str(v) {
7033
7048
  return typeof v === "string" && v.length > 0 ? v : undefined;
7034
7049
  }
7035
7050
  function readSessionsIndex(agentId) {
7036
7051
  const out = new Map;
7037
- const indexPath = join14(openclawHome(), "agents", agentId, "sessions", "sessions.json");
7052
+ const indexPath = join15(openclawHome(), "agents", agentId, "sessions", "sessions.json");
7038
7053
  let raw;
7039
7054
  try {
7040
7055
  raw = JSON.parse(readFileSync5(indexPath, "utf-8"));
@@ -7190,13 +7205,13 @@ var init_openclaw_projects = __esm(() => {
7190
7205
  // lib/factory-sessions.ts
7191
7206
  import { readFile as readFile8 } from "node:fs/promises";
7192
7207
  import { readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
7193
- import { homedir as homedir11 } from "node:os";
7194
- import { join as join15 } from "node:path";
7208
+ import { homedir as homedir12 } from "node:os";
7209
+ import { join as join16 } from "node:path";
7195
7210
  function factoryHome() {
7196
- return process.env.FACTORY_HOME || join15(homedir11(), ".factory");
7211
+ return process.env.FACTORY_HOME || join16(homedir12(), ".factory");
7197
7212
  }
7198
7213
  function factorySessionsRoot() {
7199
- return join15(factoryHome(), "sessions");
7214
+ return join16(factoryHome(), "sessions");
7200
7215
  }
7201
7216
  function isPlainObject4(v) {
7202
7217
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -7342,7 +7357,7 @@ function listFactoryTranscripts() {
7342
7357
  for (const dir of projectDirs) {
7343
7358
  const projectName = dir.name;
7344
7359
  const cwd = decodeFolderName(projectName);
7345
- const projectPath = join15(root, projectName);
7360
+ const projectPath = join16(root, projectName);
7346
7361
  let files;
7347
7362
  try {
7348
7363
  files = readdirSync6(projectPath);
@@ -7355,7 +7370,7 @@ function listFactoryTranscripts() {
7355
7370
  const sessionId = file.slice(0, -".jsonl".length);
7356
7371
  if (!FACTORY_SESSION_ID_RE.test(sessionId))
7357
7372
  continue;
7358
- const transcriptPath = join15(projectPath, file);
7373
+ const transcriptPath = join16(projectPath, file);
7359
7374
  try {
7360
7375
  const st = statSync8(transcriptPath);
7361
7376
  out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -7481,13 +7496,13 @@ var init_factory_projects = __esm(() => {
7481
7496
  });
7482
7497
 
7483
7498
  // lib/devin-sessions.ts
7484
- import { homedir as homedir12 } from "node:os";
7485
- import { join as join16 } from "node:path";
7499
+ import { homedir as homedir13 } from "node:os";
7500
+ import { join as join17 } from "node:path";
7486
7501
  function devinHome() {
7487
- return process.env.DEVIN_HOME || join16(homedir12(), ".local", "share", "devin");
7502
+ return process.env.DEVIN_HOME || join17(homedir13(), ".local", "share", "devin");
7488
7503
  }
7489
7504
  function devinDbPath() {
7490
- return process.env.DEVIN_DB_PATH || join16(devinHome(), "cli", "sessions.db");
7505
+ return process.env.DEVIN_DB_PATH || join17(devinHome(), "cli", "sessions.db");
7491
7506
  }
7492
7507
  function devinEpochToMs(value) {
7493
7508
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -7785,16 +7800,16 @@ var init_devin_projects = __esm(() => {
7785
7800
  // lib/antigravity-sessions.ts
7786
7801
  import { readFile as readFile9 } from "node:fs/promises";
7787
7802
  import { readdirSync as readdirSync7, statSync as statSync9 } from "node:fs";
7788
- import { homedir as homedir13 } from "node:os";
7789
- import { join as join17 } from "node:path";
7803
+ import { homedir as homedir14 } from "node:os";
7804
+ import { join as join18 } from "node:path";
7790
7805
  function antigravityHome() {
7791
- return process.env.ANTIGRAVITY_HOME || join17(homedir13(), ".gemini", "antigravity-cli");
7806
+ return process.env.ANTIGRAVITY_HOME || join18(homedir14(), ".gemini", "antigravity-cli");
7792
7807
  }
7793
7808
  function antigravityBrainRoot() {
7794
- return join17(antigravityHome(), "brain");
7809
+ return join18(antigravityHome(), "brain");
7795
7810
  }
7796
7811
  function antigravityTranscriptRelPath() {
7797
- return join17(".system_generated", "logs", "transcript_full.jsonl");
7812
+ return join18(".system_generated", "logs", "transcript_full.jsonl");
7798
7813
  }
7799
7814
  function isPlainObject6(v) {
7800
7815
  return !!v && typeof v === "object" && !Array.isArray(v);
@@ -7917,7 +7932,7 @@ function listAntigravityTranscripts() {
7917
7932
  const conversationId = dir.name;
7918
7933
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
7919
7934
  continue;
7920
- const transcriptPath = join17(root, conversationId, rel);
7935
+ const transcriptPath = join18(root, conversationId, rel);
7921
7936
  try {
7922
7937
  const st = statSync9(transcriptPath);
7923
7938
  if (!st.isFile())
@@ -7930,7 +7945,7 @@ function listAntigravityTranscripts() {
7930
7945
  function findAntigravityTranscript(conversationId) {
7931
7946
  if (!ANTIGRAVITY_CONVERSATION_ID_RE.test(conversationId))
7932
7947
  return null;
7933
- const transcriptPath = join17(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
7948
+ const transcriptPath = join18(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
7934
7949
  try {
7935
7950
  if (statSync9(transcriptPath).isFile())
7936
7951
  return transcriptPath;
@@ -7970,9 +7985,9 @@ __export(exports_antigravity_projects, {
7970
7985
  getCachedAntigravityProjects: () => getCachedAntigravityProjects,
7971
7986
  getCachedAntigravitySessionsByEncodedName: () => getCachedAntigravitySessionsByEncodedName
7972
7987
  });
7973
- import { join as join18 } from "node:path";
7988
+ import { join as join19 } from "node:path";
7974
7989
  function antigravitySummariesDbPath() {
7975
- return join18(antigravityHome(), "conversation_summaries.db");
7990
+ return join19(antigravityHome(), "conversation_summaries.db");
7976
7991
  }
7977
7992
  function parseWorkspaceCwd(raw) {
7978
7993
  if (!raw)
@@ -8115,16 +8130,16 @@ var init_antigravity_projects = __esm(() => {
8115
8130
  });
8116
8131
 
8117
8132
  // lib/goose-sessions.ts
8118
- import { homedir as homedir14 } from "node:os";
8119
- import { join as join19 } from "node:path";
8133
+ import { homedir as homedir15 } from "node:os";
8134
+ import { join as join20 } from "node:path";
8120
8135
  function gooseHome() {
8121
8136
  if (process.env.GOOSE_HOME)
8122
8137
  return process.env.GOOSE_HOME;
8123
8138
  const xdg = process.env.XDG_DATA_HOME;
8124
- return join19(xdg && xdg.length > 0 ? xdg : join19(homedir14(), ".local", "share"), "goose");
8139
+ return join20(xdg && xdg.length > 0 ? xdg : join20(homedir15(), ".local", "share"), "goose");
8125
8140
  }
8126
8141
  function gooseDbPath() {
8127
- return process.env.GOOSE_DB_PATH || join19(gooseHome(), "sessions", "sessions.db");
8142
+ return process.env.GOOSE_DB_PATH || join20(gooseHome(), "sessions", "sessions.db");
8128
8143
  }
8129
8144
  function gooseTimestampToMs(value) {
8130
8145
  if (typeof value === "number" && Number.isFinite(value)) {
@@ -8392,7 +8407,7 @@ var init_goose_projects = __esm(() => {
8392
8407
 
8393
8408
  // lib/projects.ts
8394
8409
  import { readdir as readdir5, stat as stat4 } from "node:fs/promises";
8395
- import { join as join20, resolve as resolve7, sep } from "node:path";
8410
+ import { join as join21, resolve as resolve7, sep } from "node:path";
8396
8411
  async function getMtime(path3, label) {
8397
8412
  try {
8398
8413
  return (await stat4(path3)).mtime;
@@ -8418,7 +8433,7 @@ async function getClaudeProjectFolders() {
8418
8433
  if (!entries)
8419
8434
  return [];
8420
8435
  const settled = await batchAll(entries.filter((entry) => entry.isDirectory()).map((entry) => async () => {
8421
- const folderPath = join20(projectsPath, entry.name);
8436
+ const folderPath = join21(projectsPath, entry.name);
8422
8437
  const mtime = await getMtime(folderPath, entry.name);
8423
8438
  return {
8424
8439
  name: entry.name,
@@ -8545,7 +8560,7 @@ function resolveProjectPath(projectName) {
8545
8560
  if (/^[/\\]/.test(projectName))
8546
8561
  throw new RangeError("Absolute project name");
8547
8562
  const projectsPath = resolve7(getClaudeProjectsPath());
8548
- const candidate = resolve7(join20(projectsPath, projectName));
8563
+ const candidate = resolve7(join21(projectsPath, projectName));
8549
8564
  if (!candidate.startsWith(projectsPath + sep)) {
8550
8565
  throw new RangeError("Project path escapes root");
8551
8566
  }
@@ -8563,7 +8578,7 @@ async function getSessionFiles(projectPath) {
8563
8578
  return [];
8564
8579
  const jsonlEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl") && extractSessionId2(entry.name));
8565
8580
  const settled = await batchAll(jsonlEntries.map((entry) => async () => {
8566
- const filePath = join20(projectPath, entry.name);
8581
+ const filePath = join21(projectPath, entry.name);
8567
8582
  const mtime = await getMtime(filePath, entry.name);
8568
8583
  return {
8569
8584
  name: entry.name,
@@ -8592,13 +8607,13 @@ var init_projects = __esm(() => {
8592
8607
 
8593
8608
  // lib/resolve-subagent-path.ts
8594
8609
  import { access as access2 } from "fs/promises";
8595
- import { join as join21, relative as relative2 } from "path";
8610
+ import { join as join22, relative as relative2 } from "path";
8596
8611
  async function resolveSubagentPath(projectsPath, projectName, sessionId, agentId) {
8597
8612
  const fileName = `agent-${agentId}.jsonl`;
8598
8613
  const candidatePaths = [
8599
- join21(projectsPath, projectName, fileName),
8600
- join21(projectsPath, projectName, sessionId, fileName),
8601
- join21(projectsPath, projectName, sessionId, "subagents", fileName)
8614
+ join22(projectsPath, projectName, fileName),
8615
+ join22(projectsPath, projectName, sessionId, fileName),
8616
+ join22(projectsPath, projectName, sessionId, "subagents", fileName)
8602
8617
  ];
8603
8618
  for (const candidatePath of candidatePaths) {
8604
8619
  if (relative2(projectsPath, candidatePath).startsWith("..")) {
@@ -8620,7 +8635,7 @@ var init_resolve_subagent_path = () => {};
8620
8635
 
8621
8636
  // lib/log-entries.ts
8622
8637
  import { readFile as readFile10 } from "fs/promises";
8623
- import { join as join22 } from "path";
8638
+ import { join as join23 } from "path";
8624
8639
  function formatTimestamp(date) {
8625
8640
  const base = formatDate(date);
8626
8641
  const ms = date.getMilliseconds().toString().padStart(3, "0");
@@ -8818,7 +8833,7 @@ async function parseLogContent(fileContent, source = "session") {
8818
8833
  async function parseSessionLog(projectName, sessionId) {
8819
8834
  const projectDir = resolveProjectPath(projectName);
8820
8835
  const projectsPath = getClaudeProjectsPath();
8821
- const filePath = join22(projectDir, `${sessionId}.jsonl`);
8836
+ const filePath = join23(projectDir, `${sessionId}.jsonl`);
8822
8837
  const fileContent = await readFile10(filePath, "utf-8");
8823
8838
  const { entries: sessionEntries, rawLines: sessionRawLines, subagentIds } = await parseFileContent(fileContent, "session");
8824
8839
  if (subagentIds.length === 0) {
@@ -8857,8 +8872,8 @@ var init_log_entries = __esm(() => {
8857
8872
  // lib/codex-sessions.ts
8858
8873
  import { readFileSync as readFileSync6, readdirSync as readdirSync8, existsSync as existsSync9, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, statSync as statSync10 } from "node:fs";
8859
8874
  import { readFile as readFile11 } from "node:fs/promises";
8860
- import { dirname as dirname5, join as join23 } from "node:path";
8861
- import { homedir as homedir15 } from "node:os";
8875
+ import { dirname as dirname5, join as join24 } from "node:path";
8876
+ import { homedir as homedir16 } from "node:os";
8862
8877
  function readCache() {
8863
8878
  try {
8864
8879
  if (!existsSync9(CACHE_PATH))
@@ -8880,7 +8895,7 @@ function dirSearch(dir, sessionId) {
8880
8895
  try {
8881
8896
  for (const f of readdirSync8(dir, { withFileTypes: true })) {
8882
8897
  if (f.isFile() && f.name.includes(sessionId) && f.name.endsWith(".jsonl")) {
8883
- return join23(dir, f.name);
8898
+ return join24(dir, f.name);
8884
8899
  }
8885
8900
  }
8886
8901
  } catch {}
@@ -8891,14 +8906,14 @@ function findCodexTranscript(sessionId) {
8891
8906
  const cached = cache[sessionId];
8892
8907
  if (cached && existsSync9(cached))
8893
8908
  return cached;
8894
- const root = join23(homedir15(), ".codex", "sessions");
8909
+ const root = join24(homedir16(), ".codex", "sessions");
8895
8910
  const today = new Date;
8896
8911
  const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000);
8897
8912
  const datedDirs = [today, yesterday].map((d) => {
8898
8913
  const y = String(d.getUTCFullYear());
8899
8914
  const m = String(d.getUTCMonth() + 1).padStart(2, "0");
8900
8915
  const day = String(d.getUTCDate()).padStart(2, "0");
8901
- return join23(root, y, m, day);
8916
+ return join24(root, y, m, day);
8902
8917
  });
8903
8918
  for (const dir of datedDirs) {
8904
8919
  const hit = dirSearch(dir, sessionId);
@@ -8911,13 +8926,13 @@ function findCodexTranscript(sessionId) {
8911
8926
  for (const y of readdirSync8(root, { withFileTypes: true })) {
8912
8927
  if (!y.isDirectory())
8913
8928
  continue;
8914
- for (const m of readdirSync8(join23(root, y.name), { withFileTypes: true })) {
8929
+ for (const m of readdirSync8(join24(root, y.name), { withFileTypes: true })) {
8915
8930
  if (!m.isDirectory())
8916
8931
  continue;
8917
- for (const d of readdirSync8(join23(root, y.name, m.name), { withFileTypes: true })) {
8932
+ for (const d of readdirSync8(join24(root, y.name, m.name), { withFileTypes: true })) {
8918
8933
  if (!d.isDirectory())
8919
8934
  continue;
8920
- const hit = dirSearch(join23(root, y.name, m.name, d.name), sessionId);
8935
+ const hit = dirSearch(join24(root, y.name, m.name, d.name), sessionId);
8921
8936
  if (hit) {
8922
8937
  writeCacheEntry(sessionId, hit);
8923
8938
  return hit;
@@ -9185,13 +9200,13 @@ var init_resolve_permission_mode = __esm(() => {
9185
9200
  // lib/copilot-sessions.ts
9186
9201
  import { readFileSync as readFileSync8, readdirSync as readdirSync9, existsSync as existsSync10, statSync as statSync11 } from "node:fs";
9187
9202
  import { readFile as readFile12 } from "node:fs/promises";
9188
- import { join as join24, resolve as resolve8, sep as sep2 } from "node:path";
9189
- import { homedir as homedir16 } from "node:os";
9203
+ import { join as join25, resolve as resolve8, sep as sep2 } from "node:path";
9204
+ import { homedir as homedir17 } from "node:os";
9190
9205
  function getCopilotHome() {
9191
- return process.env.COPILOT_HOME || join24(homedir16(), ".copilot");
9206
+ return process.env.COPILOT_HOME || join25(homedir17(), ".copilot");
9192
9207
  }
9193
9208
  function getCopilotSessionStateRoot2() {
9194
- return join24(getCopilotHome(), "session-state");
9209
+ return join25(getCopilotHome(), "session-state");
9195
9210
  }
9196
9211
  function getCopilotSessionDir(sessionId) {
9197
9212
  if (!sessionId)
@@ -9206,7 +9221,7 @@ function resolveSessionFile(sessionId, filename) {
9206
9221
  const dir = getCopilotSessionDir(sessionId);
9207
9222
  if (!dir)
9208
9223
  return null;
9209
- return join24(dir, filename);
9224
+ return join25(dir, filename);
9210
9225
  }
9211
9226
  function findCopilotTranscript(sessionId) {
9212
9227
  const candidate = resolveSessionFile(sessionId, "events.jsonl");
@@ -9402,10 +9417,10 @@ var init_copilot_sessions = __esm(() => {
9402
9417
  // lib/cursor-sessions.ts
9403
9418
  import { readFileSync as readFileSync9, readdirSync as readdirSync10, existsSync as existsSync11, statSync as statSync12 } from "node:fs";
9404
9419
  import { readFile as readFile13 } from "node:fs/promises";
9405
- import { basename as basename3, join as join25, resolve as resolve9, sep as sep3 } from "node:path";
9406
- import { homedir as homedir17 } from "node:os";
9420
+ import { basename as basename3, join as join26, resolve as resolve9, sep as sep3 } from "node:path";
9421
+ import { homedir as homedir18 } from "node:os";
9407
9422
  function getCursorHome2() {
9408
- return process.env.CURSOR_HOME || join25(homedir17(), ".cursor");
9423
+ return process.env.CURSOR_HOME || join26(homedir18(), ".cursor");
9409
9424
  }
9410
9425
  function getCursorSessionDir(sessionId) {
9411
9426
  if (!sessionId)
@@ -9440,11 +9455,11 @@ function findCursorTranscript(sessionId) {
9440
9455
  const dir = getCursorSessionDir(sessionId);
9441
9456
  if (!dir)
9442
9457
  return null;
9443
- const newCandidate = join25(dir, `${basename3(dir)}.jsonl`);
9458
+ const newCandidate = join26(dir, `${basename3(dir)}.jsonl`);
9444
9459
  if (existsSync11(newCandidate))
9445
9460
  return newCandidate;
9446
9461
  for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
9447
- const candidate = join25(dir, name);
9462
+ const candidate = join26(dir, name);
9448
9463
  if (existsSync11(candidate))
9449
9464
  return candidate;
9450
9465
  }
@@ -9658,10 +9673,10 @@ var init_cursor_sessions = __esm(() => {
9658
9673
  // lib/pi-sessions.ts
9659
9674
  import { readFileSync as readFileSync10, readdirSync as readdirSync11, existsSync as existsSync12, statSync as statSync13 } from "node:fs";
9660
9675
  import { readFile as readFile14 } from "node:fs/promises";
9661
- import { join as join26, resolve as resolve10, sep as sep4 } from "node:path";
9662
- import { homedir as homedir18 } from "node:os";
9676
+ import { join as join27, resolve as resolve10, sep as sep4 } from "node:path";
9677
+ import { homedir as homedir19 } from "node:os";
9663
9678
  function getPiSessionStateRoot() {
9664
- return process.env.PI_SESSIONS_DIR || join26(homedir18(), ".pi", "agent", "sessions");
9679
+ return process.env.PI_SESSIONS_DIR || join27(homedir19(), ".pi", "agent", "sessions");
9665
9680
  }
9666
9681
  function isSafeSessionId(sessionId) {
9667
9682
  return UUID_RE.test(sessionId);
@@ -10383,7 +10398,7 @@ var init_atomic_write = () => {};
10383
10398
  // src/hooks/session-pause.ts
10384
10399
  import { existsSync as existsSync16, mkdirSync as mkdirSync7, readdirSync as readdirSync12, readFileSync as readFileSync13, rmSync as rmSync3 } from "node:fs";
10385
10400
  import { createHash as createHash5 } from "node:crypto";
10386
- import { join as join27, resolve as resolve13 } from "node:path";
10401
+ import { join as join28, resolve as resolve13 } from "node:path";
10387
10402
  function pauseStateDir() {
10388
10403
  const override = process.env.FAILPROOFAI_STATE_DIR;
10389
10404
  if (override)
@@ -10392,7 +10407,7 @@ function pauseStateDir() {
10392
10407
  }
10393
10408
  function pauseFilePath(sessionId) {
10394
10409
  const digest = createHash5("sha256").update(sessionId).digest("hex").slice(0, 32);
10395
- return join27(pauseStateDir(), `${digest}.json`);
10410
+ return join28(pauseStateDir(), `${digest}.json`);
10396
10411
  }
10397
10412
  function parsePauseDuration(input, ceilingMs = PAUSE_CEILING_MS) {
10398
10413
  if (input === undefined || input === "")
@@ -10503,7 +10518,7 @@ function listActivePauses(now = Date.now()) {
10503
10518
  if (!name.endsWith(".json"))
10504
10519
  continue;
10505
10520
  try {
10506
- const stored = parseStored(JSON.parse(readFileSync13(join27(dir, name), "utf8")));
10521
+ const stored = parseStored(JSON.parse(readFileSync13(join28(dir, name), "utf8")));
10507
10522
  if (!stored || stored.expiresAt <= now)
10508
10523
  continue;
10509
10524
  const { schemaVersion: _ignored, ...pause } = stored;
@@ -10859,9 +10874,9 @@ import {
10859
10874
  unlinkSync as unlinkSync2,
10860
10875
  rmSync as rmSync5
10861
10876
  } from "node:fs";
10862
- import { homedir as homedir19, tmpdir as tmpdir2, userInfo } from "node:os";
10877
+ import { homedir as homedir20, tmpdir as tmpdir2, userInfo } from "node:os";
10863
10878
  import { resolve as resolve15 } from "node:path";
10864
- import { execFileSync as execFileSync3 } from "node:child_process";
10879
+ import { execFileSync as execFileSync2 } from "node:child_process";
10865
10880
  function setDaemonConfigured(value, installedVersion) {
10866
10881
  try {
10867
10882
  updateConfig({ daemon: { configured: value } });
@@ -10973,7 +10988,7 @@ function systemdUnitPath(user = serviceUser()) {
10973
10988
  return resolve15(systemdUnitDir(), systemdUnitName(user));
10974
10989
  }
10975
10990
  function legacySystemdUserUnitPath() {
10976
- return resolve15(homedir19(), ".config", "systemd", "user", "failproofaid.service");
10991
+ return resolve15(homedir20(), ".config", "systemd", "user", "failproofaid.service");
10977
10992
  }
10978
10993
  function launchdLabel(user = serviceUser()) {
10979
10994
  return `ai.failproof.failproofaid.${user}`;
@@ -10982,7 +10997,7 @@ function launchdPlistPath(user = serviceUser()) {
10982
10997
  return `/Library/LaunchDaemons/${launchdLabel(user)}.plist`;
10983
10998
  }
10984
10999
  function legacyLaunchAgentPlistPath() {
10985
- return resolve15(homedir19(), "Library", "LaunchAgents", "ai.failproof.failproofaid.plist");
11000
+ return resolve15(homedir20(), "Library", "LaunchAgents", "ai.failproof.failproofaid.plist");
10986
11001
  }
10987
11002
  function legacySharedLaunchDaemonPath() {
10988
11003
  return "/Library/LaunchDaemons/ai.failproof.failproofaid.plist";
@@ -11008,7 +11023,7 @@ function primeElevation() {
11008
11023
  if (canElevate())
11009
11024
  return true;
11010
11025
  try {
11011
- execFileSync3("sudo", ["-v"], { stdio: "inherit", timeout: SUDO_PROMPT_TIMEOUT_MS });
11026
+ execFileSync2("sudo", ["-v"], { stdio: "inherit", timeout: SUDO_PROMPT_TIMEOUT_MS });
11012
11027
  return canElevate();
11013
11028
  } catch {
11014
11029
  return false;
@@ -11018,7 +11033,7 @@ function canElevate() {
11018
11033
  if (typeof process.getuid === "function" && process.getuid() === 0)
11019
11034
  return true;
11020
11035
  try {
11021
- execFileSync3("sudo", ["-n", "true"], { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
11036
+ execFileSync2("sudo", ["-n", "true"], { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
11022
11037
  return true;
11023
11038
  } catch {
11024
11039
  return false;
@@ -11027,7 +11042,7 @@ function canElevate() {
11027
11042
  function runPrivileged(command, args) {
11028
11043
  const root = typeof process.getuid === "function" && process.getuid() === 0;
11029
11044
  const [cmd, argv] = root ? [command, args] : ["sudo", ["-n", command, ...args]];
11030
- execFileSync3(cmd, argv, { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
11045
+ execFileSync2(cmd, argv, { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
11031
11046
  }
11032
11047
  function writePrivilegedFile(destination, contents, mode = "0644") {
11033
11048
  const stagingDir = mkdtempSync(resolve15(tmpdir2(), "failproofaid-stage-"));
@@ -11046,14 +11061,14 @@ function removeLegacyUserService() {
11046
11061
  if (!existsSync19(legacy2))
11047
11062
  return;
11048
11063
  try {
11049
- execFileSync3("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
11064
+ execFileSync2("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
11050
11065
  stdio: "ignore",
11051
11066
  timeout: SERVICE_CMD_TIMEOUT_MS
11052
11067
  });
11053
11068
  } catch {}
11054
11069
  unlinkSync2(legacy2);
11055
11070
  try {
11056
- execFileSync3("systemctl", ["--user", "daemon-reload"], {
11071
+ execFileSync2("systemctl", ["--user", "daemon-reload"], {
11057
11072
  stdio: "ignore",
11058
11073
  timeout: SERVICE_CMD_TIMEOUT_MS
11059
11074
  });
@@ -11062,7 +11077,7 @@ function removeLegacyUserService() {
11062
11077
  const legacyAgent = legacyLaunchAgentPlistPath();
11063
11078
  if (existsSync19(legacyAgent)) {
11064
11079
  try {
11065
- execFileSync3("launchctl", ["unload", "-w", legacyAgent], {
11080
+ execFileSync2("launchctl", ["unload", "-w", legacyAgent], {
11066
11081
  stdio: "ignore",
11067
11082
  timeout: SERVICE_CMD_TIMEOUT_MS
11068
11083
  });
@@ -11086,7 +11101,7 @@ function systemdUnitContents(binaryPath, workerCmd, cliCmd = null) {
11086
11101
  `).join("");
11087
11102
  const user = assertUnitSafe(serviceUser(), "User");
11088
11103
  assertUnitSafe(binaryPath, "ExecStart");
11089
- assertUnitSafe(homedir19(), "HOME");
11104
+ assertUnitSafe(homedir20(), "HOME");
11090
11105
  const conditionPaths = [binaryPath, workerScriptPath()].filter((p) => typeof p === "string" && existsSync19(p));
11091
11106
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe(p, "ConditionPathExists")}
11092
11107
  `).join("");
@@ -11100,7 +11115,7 @@ User=${user}
11100
11115
  # Set explicitly rather than relying on systemd deriving it from User=:
11101
11116
  # failproofaid stores per-user state and refuses to start without HOME, so this
11102
11117
  # required variable is not left to a version-dependent default.
11103
- Environment="HOME=${homedir19()}"
11118
+ Environment="HOME=${homedir20()}"
11104
11119
  ${envLines}ExecStart=${binaryPath}
11105
11120
  Restart=on-failure
11106
11121
  RestartSec=2
@@ -11452,7 +11467,7 @@ function daemonVersionSkew() {
11452
11467
  }
11453
11468
  function inactiveLinuxStatus() {
11454
11469
  try {
11455
- return interpretConditionResult(execFileSync3("systemctl", ["show", systemdUnitName(), "--property=ConditionResult", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS }).toString());
11470
+ return interpretConditionResult(execFileSync2("systemctl", ["show", systemdUnitName(), "--property=ConditionResult", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS }).toString());
11456
11471
  } catch {
11457
11472
  return "stopped";
11458
11473
  }
@@ -11467,7 +11482,7 @@ function daemonServiceStatus() {
11467
11482
  if (!existsSync19(systemdUnitPath()))
11468
11483
  return "not-installed";
11469
11484
  try {
11470
- const out = execFileSync3("systemctl", ["is-active", systemdUnitName()], {
11485
+ const out = execFileSync2("systemctl", ["is-active", systemdUnitName()], {
11471
11486
  stdio: ["ignore", "pipe", "ignore"],
11472
11487
  timeout: SERVICE_CMD_TIMEOUT_MS
11473
11488
  }).toString().trim();
@@ -11484,10 +11499,10 @@ function daemonServiceStatus() {
11484
11499
  if (!root && !canElevate())
11485
11500
  return "unknown";
11486
11501
  const args = ["print", `system/${launchdLabel()}`];
11487
- const out = root ? execFileSync3("launchctl", args, {
11502
+ const out = root ? execFileSync2("launchctl", args, {
11488
11503
  stdio: ["ignore", "pipe", "ignore"],
11489
11504
  timeout: SERVICE_CMD_TIMEOUT_MS
11490
- }).toString() : execFileSync3("sudo", ["-n", "launchctl", ...args], {
11505
+ }).toString() : execFileSync2("sudo", ["-n", "launchctl", ...args], {
11491
11506
  stdio: ["ignore", "pipe", "ignore"],
11492
11507
  timeout: SERVICE_CMD_TIMEOUT_MS
11493
11508
  }).toString();
@@ -13301,16 +13316,16 @@ __export(exports_flush_cli, {
13301
13316
  runFlushCommand: () => runFlushCommand
13302
13317
  });
13303
13318
  import { existsSync as existsSync21, mkdirSync as mkdirSync11, writeFileSync as writeFileSync9, readdirSync as readdirSync15 } from "node:fs";
13304
- import { dirname as dirname9, join as join28 } from "node:path";
13319
+ import { dirname as dirname9, join as join29 } from "node:path";
13305
13320
  function flushRequestPath(home) {
13306
- return join28(failproofaiHome(home), "state", "flush-request.json");
13321
+ return join29(failproofaiHome(home), "state", "flush-request.json");
13307
13322
  }
13308
13323
  function spoolDirs(home) {
13309
13324
  const root = spoolDir(home);
13310
13325
  if (!existsSync21(root))
13311
13326
  return [];
13312
13327
  try {
13313
- return readdirSync15(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join28(root, e.name));
13328
+ return readdirSync15(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join29(root, e.name));
13314
13329
  } catch {
13315
13330
  return [];
13316
13331
  }
@@ -13430,7 +13445,7 @@ import {
13430
13445
  rmSync as rmSync7,
13431
13446
  writeFileSync as writeFileSync10
13432
13447
  } from "node:fs";
13433
- import { basename as basename4, dirname as dirname10, join as join29, resolve as resolve17 } from "node:path";
13448
+ import { basename as basename4, dirname as dirname10, join as join30, resolve as resolve17 } from "node:path";
13434
13449
  function migrateToLayout4() {
13435
13450
  const moves = [
13436
13451
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -13439,9 +13454,9 @@ function migrateToLayout4() {
13439
13454
  ];
13440
13455
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
13441
13456
  if (authDirOverride) {
13442
- moves.push({ from: join29(authDirOverride, "auth.json"), to: join29(authDirOverride, "session.json") }, {
13443
- from: join29(authDirOverride, "next-audit.json"),
13444
- to: join29(authDirOverride, "reminder.json")
13457
+ moves.push({ from: join30(authDirOverride, "auth.json"), to: join30(authDirOverride, "session.json") }, {
13458
+ from: join30(authDirOverride, "next-audit.json"),
13459
+ to: join30(authDirOverride, "reminder.json")
13445
13460
  });
13446
13461
  }
13447
13462
  const migrated = [];
@@ -14275,14 +14290,14 @@ var init_fp_reset2 = __esm(() => {
14275
14290
  import { createHmac, randomUUID as randomUUID2 } from "node:crypto";
14276
14291
  import { execSync as execSync4 } from "node:child_process";
14277
14292
  import { readFileSync as readFileSync19, writeFileSync as writeFileSync12, mkdirSync as mkdirSync14 } from "node:fs";
14278
- import { homedir as homedir20, platform, arch, hostname, cpus } from "node:os";
14279
- import { join as join30 } from "node:path";
14293
+ import { homedir as homedir21, platform, arch, hostname, cpus } from "node:os";
14294
+ import { join as join31 } from "node:path";
14280
14295
  function hashToId3(raw) {
14281
14296
  return createHmac("sha256", NAMESPACE3).update(raw).digest("hex");
14282
14297
  }
14283
14298
  function getInstanceId3() {
14284
- const idDir = join30(homedir20(), ".failproofai");
14285
- const idFile = join30(idDir, "instance-id");
14299
+ const idDir = join31(homedir21(), ".failproofai");
14300
+ const idFile = join31(idDir, "instance-id");
14286
14301
  try {
14287
14302
  const existing = readFileSync19(idFile, "utf-8").trim();
14288
14303
  if (existing)
@@ -14316,7 +14331,7 @@ function getInstanceId3() {
14316
14331
  try {
14317
14332
  const sysProps = [
14318
14333
  hostname(),
14319
- homedir20(),
14334
+ homedir21(),
14320
14335
  platform(),
14321
14336
  arch(),
14322
14337
  cpus()[0]?.model ?? ""
@@ -14366,7 +14381,7 @@ __export(exports_install_check, {
14366
14381
  });
14367
14382
  import { existsSync as existsSync24, readFileSync as readFileSync20, writeFileSync as writeFileSync13, mkdirSync as mkdirSync15 } from "node:fs";
14368
14383
  import { dirname as dirname12, resolve as resolve19 } from "node:path";
14369
- import { platform as platform2, arch as arch2, release, homedir as homedir21, hostname as hostname2 } from "node:os";
14384
+ import { platform as platform2, arch as arch2, release, homedir as homedir22, hostname as hostname2 } from "node:os";
14370
14385
  import { createHmac as createHmac2 } from "node:crypto";
14371
14386
  function hashToId4(raw) {
14372
14387
  return createHmac2("sha256", NAMESPACE4).update(raw).digest("hex");
@@ -14433,7 +14448,7 @@ function checkHooks() {
14433
14448
  return { configured: false, registered: false, policyCount: 0 };
14434
14449
  }
14435
14450
  const policyCount = config.enabledPolicies.length;
14436
- const settingsPath = resolve19(homedir21(), ".claude", "settings.json");
14451
+ const settingsPath = resolve19(homedir22(), ".claude", "settings.json");
14437
14452
  if (!existsSync24(settingsPath))
14438
14453
  return { configured: true, registered: false, policyCount };
14439
14454
  let settings;
@@ -22364,7 +22379,7 @@ import { execSync as execSync5 } from "node:child_process";
22364
22379
  import { readFileSync as readFileSync21, writeFileSync as writeFileSync14, existsSync as existsSync25, mkdirSync as mkdirSync16, unlinkSync as unlinkSync3 } from "node:fs";
22365
22380
  import { resolve as resolve20, dirname as dirname13 } from "node:path";
22366
22381
  import { fileURLToPath } from "node:url";
22367
- import { homedir as homedir22 } from "node:os";
22382
+ import { homedir as homedir23 } from "node:os";
22368
22383
  function readJsonFile(path3) {
22369
22384
  if (!existsSync25(path3))
22370
22385
  return {};
@@ -22726,7 +22741,7 @@ var init_integrations = __esm(() => {
22726
22741
  const base = cwd ? resolve20(cwd) : process.cwd();
22727
22742
  switch (scope) {
22728
22743
  case "user":
22729
- return resolve20(homedir22(), ".claude", "settings.json");
22744
+ return resolve20(homedir23(), ".claude", "settings.json");
22730
22745
  case "project":
22731
22746
  return resolve20(base, ".claude", "settings.json");
22732
22747
  case "local":
@@ -22858,7 +22873,7 @@ var init_integrations = __esm(() => {
22858
22873
  const base = cwd ? resolve20(cwd) : process.cwd();
22859
22874
  switch (scope) {
22860
22875
  case "user":
22861
- return resolve20(homedir22(), ".codex", "hooks.json");
22876
+ return resolve20(homedir23(), ".codex", "hooks.json");
22862
22877
  case "project":
22863
22878
  return resolve20(base, ".codex", "hooks.json");
22864
22879
  case "local":
@@ -22974,7 +22989,7 @@ var init_integrations = __esm(() => {
22974
22989
  const base = cwd ? resolve20(cwd) : process.cwd();
22975
22990
  switch (scope) {
22976
22991
  case "user":
22977
- return resolve20(homedir22(), ".copilot", "hooks", "failproofai.json");
22992
+ return resolve20(homedir23(), ".copilot", "hooks", "failproofai.json");
22978
22993
  case "project":
22979
22994
  return resolve20(base, ".github", "hooks", "failproofai.json");
22980
22995
  case "local":
@@ -23088,7 +23103,7 @@ var init_integrations = __esm(() => {
23088
23103
  const base = cwd ? resolve20(cwd) : process.cwd();
23089
23104
  switch (scope) {
23090
23105
  case "user":
23091
- return resolve20(homedir22(), ".cursor", "hooks.json");
23106
+ return resolve20(homedir23(), ".cursor", "hooks.json");
23092
23107
  case "project":
23093
23108
  return resolve20(base, ".cursor", "hooks.json");
23094
23109
  case "local":
@@ -23187,7 +23202,7 @@ var init_integrations = __esm(() => {
23187
23202
  const base = cwd ? resolve20(cwd) : process.cwd();
23188
23203
  switch (scope) {
23189
23204
  case "user":
23190
- return resolve20(homedir22(), ".config", "opencode", "opencode.json");
23205
+ return resolve20(homedir23(), ".config", "opencode", "opencode.json");
23191
23206
  case "project":
23192
23207
  return resolve20(base, ".opencode", "opencode.json");
23193
23208
  case "local":
@@ -23202,7 +23217,7 @@ var init_integrations = __esm(() => {
23202
23217
  },
23203
23218
  buildHookEntry(_binaryPath, _eventType, scope) {
23204
23219
  if (scope === "user") {
23205
- const abs = resolve20(homedir22(), ".config", "opencode", "plugins", "failproofai.mjs");
23220
+ const abs = resolve20(homedir23(), ".config", "opencode", "plugins", "failproofai.mjs");
23206
23221
  return { spec: `file://${abs}`, [FAILPROOFAI_HOOK_MARKER]: true };
23207
23222
  }
23208
23223
  return { spec: OPENCODE_PLUGIN_REL_PATH, [FAILPROOFAI_HOOK_MARKER]: true };
@@ -23217,7 +23232,7 @@ var init_integrations = __esm(() => {
23217
23232
  writeHookEntries(settings, binaryPath, scope) {
23218
23233
  const s = settings;
23219
23234
  const effectiveScope = scope ?? "project";
23220
- const settingsPath = effectiveScope === "user" ? resolve20(homedir22(), ".config", "opencode", "opencode.json") : resolve20(process.cwd(), ".opencode", "opencode.json");
23235
+ const settingsPath = effectiveScope === "user" ? resolve20(homedir23(), ".config", "opencode", "opencode.json") : resolve20(process.cwd(), ".opencode", "opencode.json");
23221
23236
  const pluginPath = opencodePluginFilePath(settingsPath);
23222
23237
  mkdirSync16(dirname13(pluginPath), { recursive: true });
23223
23238
  writeFileSync14(pluginPath, buildOpenCodePluginShim(binaryPath, effectiveScope), "utf8");
@@ -23288,7 +23303,7 @@ var init_integrations = __esm(() => {
23288
23303
  const base = cwd ? resolve20(cwd) : process.cwd();
23289
23304
  switch (scope) {
23290
23305
  case "user":
23291
- return resolve20(homedir22(), ".pi", "agent", "settings.json");
23306
+ return resolve20(homedir23(), ".pi", "agent", "settings.json");
23292
23307
  case "project":
23293
23308
  return resolve20(base, ".pi", "settings.json");
23294
23309
  case "local":
@@ -23453,7 +23468,7 @@ var init_integrations = __esm(() => {
23453
23468
  scopes: OPENCLAW_HOOK_SCOPES,
23454
23469
  eventTypes: OPENCLAW_HOOK_EVENT_TYPES,
23455
23470
  getSettingsPath() {
23456
- return resolve20(homedir22(), ".openclaw", "openclaw.json");
23471
+ return resolve20(homedir23(), ".openclaw", "openclaw.json");
23457
23472
  },
23458
23473
  readSettings(settingsPath) {
23459
23474
  return readJsonFile(settingsPath);
@@ -23552,7 +23567,7 @@ var init_integrations = __esm(() => {
23552
23567
  const base = cwd ? resolve20(cwd) : process.cwd();
23553
23568
  switch (scope) {
23554
23569
  case "user":
23555
- return resolve20(homedir22(), ".factory", "hooks.json");
23570
+ return resolve20(homedir23(), ".factory", "hooks.json");
23556
23571
  case "project":
23557
23572
  return resolve20(base, ".factory", "hooks.json");
23558
23573
  case "local":
@@ -23654,7 +23669,7 @@ var init_integrations = __esm(() => {
23654
23669
  const base = cwd ? resolve20(cwd) : process.cwd();
23655
23670
  switch (scope) {
23656
23671
  case "user":
23657
- return resolve20(homedir22(), ".config", "devin", "config.json");
23672
+ return resolve20(homedir23(), ".config", "devin", "config.json");
23658
23673
  case "project":
23659
23674
  return resolve20(base, ".devin", "config.json");
23660
23675
  case "local":
@@ -23763,7 +23778,7 @@ var init_integrations = __esm(() => {
23763
23778
  const base = cwd ? resolve20(cwd) : process.cwd();
23764
23779
  switch (scope) {
23765
23780
  case "user":
23766
- return resolve20(homedir22(), ".gemini", "config", "hooks.json");
23781
+ return resolve20(homedir23(), ".gemini", "config", "hooks.json");
23767
23782
  case "project":
23768
23783
  return resolve20(base, ".agents", "hooks.json");
23769
23784
  case "local":
@@ -23904,7 +23919,7 @@ var init_integrations = __esm(() => {
23904
23919
  const base = cwd ? resolve20(cwd) : process.cwd();
23905
23920
  switch (scope) {
23906
23921
  case "user":
23907
- return resolve20(homedir22(), ".agents", "plugins", "failproofai", "hooks", "hooks.json");
23922
+ return resolve20(homedir23(), ".agents", "plugins", "failproofai", "hooks", "hooks.json");
23908
23923
  case "project":
23909
23924
  return resolve20(base, ".agents", "plugins", "failproofai", "hooks", "hooks.json");
23910
23925
  case "local":
@@ -24799,14 +24814,30 @@ function deduplicateScopes(scopes, cwd) {
24799
24814
  });
24800
24815
  }
24801
24816
  function hooksInstalledInSettings(scope, cwd) {
24802
- return INTEGRATION_TYPES.some((id) => {
24817
+ return integrationsInstalledAt(scope, cwd).length > 0;
24818
+ }
24819
+ function integrationsInstalledAt(scope, cwd) {
24820
+ return INTEGRATION_TYPES.filter((id) => {
24803
24821
  try {
24804
- return getIntegration(id).hooksInstalledInSettings(scope, cwd);
24822
+ const integration = getIntegration(id);
24823
+ if (!integration.scopes.includes(scope))
24824
+ return false;
24825
+ if (!integration.hooksInstalledInSettings(scope, cwd))
24826
+ return false;
24827
+ const here = integration.getSettingsPath(scope, cwd);
24828
+ return !HOOK_SCOPES.some((other) => other !== scope && HOOK_SCOPES.indexOf(other) < HOOK_SCOPES.indexOf(scope) && integration.scopes.includes(other) && safeSettingsPath(integration, other, cwd) === here);
24805
24829
  } catch {
24806
24830
  return false;
24807
24831
  }
24808
24832
  });
24809
24833
  }
24834
+ function safeSettingsPath(integration, scope, cwd) {
24835
+ try {
24836
+ return integration.getSettingsPath(scope, cwd);
24837
+ } catch {
24838
+ return null;
24839
+ }
24840
+ }
24810
24841
  async function installHooks(policyNames, scope = "user", cwd, includeBeta = false, source, customPoliciesPath, removeCustomHooks = false, cli, options = {}) {
24811
24842
  const { replace = false, quiet = false } = options;
24812
24843
  if (!quiet) {
@@ -25532,8 +25563,8 @@ var init_cloud_connection = __esm(() => {
25532
25563
  // src/hooks/setup-state.ts
25533
25564
  import { existsSync as existsSync29, realpathSync as realpathSync2, statSync as statSync18 } from "node:fs";
25534
25565
  import { dirname as dirname15, resolve as resolve23 } from "node:path";
25535
- import { homedir as homedir23 } from "node:os";
25536
- function globalConfigPath(home = homedir23()) {
25566
+ import { homedir as homedir24 } from "node:os";
25567
+ function globalConfigPath(home = homedir24()) {
25537
25568
  return globalPolicyConfigFile(home);
25538
25569
  }
25539
25570
  function projectConfigPath(projectRoot) {
@@ -25549,7 +25580,7 @@ function isDir(path3) {
25549
25580
  return false;
25550
25581
  }
25551
25582
  }
25552
- function findProjectRoot(start, home = homedir23()) {
25583
+ function findProjectRoot(start, home = homedir24()) {
25553
25584
  const resolvedHome = realResolve(home);
25554
25585
  let dir = realResolve(start);
25555
25586
  while (dir !== resolvedHome) {
@@ -25579,7 +25610,7 @@ function realResolve(path3) {
25579
25610
  return lexical;
25580
25611
  }
25581
25612
  }
25582
- function detectSetupState(cwd = process.cwd(), home = homedir23()) {
25613
+ function detectSetupState(cwd = process.cwd(), home = homedir24()) {
25583
25614
  const resolvedCwd = realResolve(cwd);
25584
25615
  const resolvedHome = realResolve(home);
25585
25616
  const projectRoot = findProjectRoot(resolvedCwd, resolvedHome);
@@ -25691,8 +25722,8 @@ var init_onboarding_attempt = __esm(() => {
25691
25722
 
25692
25723
  // src/hooks/onboarding-lock.ts
25693
25724
  import { mkdirSync as mkdirSync19, readFileSync as readFileSync25, rmSync as rmSync12, writeFileSync as writeFileSync17 } from "node:fs";
25694
- import { homedir as homedir24 } from "node:os";
25695
- function onboardingLockPath(home = homedir24()) {
25725
+ import { homedir as homedir25 } from "node:os";
25726
+ function onboardingLockPath(home = homedir25()) {
25696
25727
  return onboardingLockFile(home);
25697
25728
  }
25698
25729
  function processAlive(pid) {
@@ -25715,7 +25746,7 @@ function readLock(path3) {
25715
25746
  return null;
25716
25747
  }
25717
25748
  }
25718
- function acquireOnboardingLock(home = homedir24()) {
25749
+ function acquireOnboardingLock(home = homedir25()) {
25719
25750
  const path3 = onboardingLockPath(home);
25720
25751
  try {
25721
25752
  const held = readLock(path3);
@@ -25747,7 +25778,7 @@ var init_onboarding_lock = __esm(() => {
25747
25778
 
25748
25779
  // lib/claude-sessions.ts
25749
25780
  import { readdirSync as readdirSync17, statSync as statSync19, existsSync as existsSync31 } from "node:fs";
25750
- import { join as join31, basename as basename6 } from "node:path";
25781
+ import { join as join32, basename as basename6 } from "node:path";
25751
25782
  function getClaudeProjectsRoot() {
25752
25783
  return getClaudeProjectsPath();
25753
25784
  }
@@ -25762,7 +25793,7 @@ function listClaudeProjects() {
25762
25793
  return entries.filter((e) => e.isDirectory()).map((e) => ({
25763
25794
  name: e.name,
25764
25795
  cwd: decodeFolderName(e.name),
25765
- path: join31(root, e.name)
25796
+ path: join32(root, e.name)
25766
25797
  }));
25767
25798
  }
25768
25799
  function listClaudeTranscripts(project) {
@@ -25778,7 +25809,7 @@ function listClaudeTranscripts(project) {
25778
25809
  const sessionId = entry.name.slice(0, -".jsonl".length);
25779
25810
  if (!UUID_RE2.test(sessionId))
25780
25811
  continue;
25781
- const transcriptPath = join31(project.path, entry.name);
25812
+ const transcriptPath = join32(project.path, entry.name);
25782
25813
  try {
25783
25814
  const s = statSync19(transcriptPath);
25784
25815
  out.push({
@@ -25792,7 +25823,7 @@ function listClaudeTranscripts(project) {
25792
25823
  });
25793
25824
  } catch {}
25794
25825
  } else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
25795
- const subDir = join31(project.path, entry.name, "subagents");
25826
+ const subDir = join32(project.path, entry.name, "subagents");
25796
25827
  if (!existsSync31(subDir))
25797
25828
  continue;
25798
25829
  let subEntries;
@@ -25805,7 +25836,7 @@ function listClaudeTranscripts(project) {
25805
25836
  if (!sub.isFile() || !sub.name.endsWith(".jsonl"))
25806
25837
  continue;
25807
25838
  const agentId = sub.name.slice(0, -".jsonl".length);
25808
- const transcriptPath = join31(subDir, sub.name);
25839
+ const transcriptPath = join32(subDir, sub.name);
25809
25840
  try {
25810
25841
  const s = statSync19(transcriptPath);
25811
25842
  out.push({
@@ -25881,7 +25912,7 @@ var init_shared = __esm(() => {
25881
25912
  });
25882
25913
 
25883
25914
  // src/audit/cli-adapters/claude.ts
25884
- import { readFile as readFile15 } from "node:fs/promises";
25915
+ import { readFile as readFile15, open as open2 } from "node:fs/promises";
25885
25916
  async function listClaudeTranscriptMetadata(opts = {}) {
25886
25917
  const projectFilter = opts.projects ? new Set(opts.projects) : null;
25887
25918
  const sinceMs = opts.sinceMs ?? 0;
@@ -25944,6 +25975,78 @@ async function streamClaudeEvents(meta) {
25944
25975
  cwd
25945
25976
  });
25946
25977
  }
25978
+ async function streamClaudeEventsFrom(meta, fromByte) {
25979
+ if (!Number.isFinite(fromByte) || fromByte < 0)
25980
+ return null;
25981
+ let handle = null;
25982
+ let chunk;
25983
+ try {
25984
+ handle = await open2(meta.transcriptPath, "r");
25985
+ const { size } = await handle.stat();
25986
+ if (fromByte > size)
25987
+ return null;
25988
+ if (fromByte === size) {
25989
+ return { events: [], bytesConsumed: fromByte };
25990
+ }
25991
+ const buf = Buffer.alloc(size - fromByte);
25992
+ await handle.read(buf, 0, buf.length, fromByte);
25993
+ chunk = buf.toString("utf-8");
25994
+ } catch {
25995
+ return null;
25996
+ } finally {
25997
+ if (handle) {
25998
+ try {
25999
+ await handle.close();
26000
+ } catch {}
26001
+ }
26002
+ }
26003
+ const lastNewline = chunk.lastIndexOf(`
26004
+ `);
26005
+ const head = lastNewline === -1 ? "" : chunk.slice(0, lastNewline + 1);
26006
+ const tail = chunk.slice(lastNewline + 1);
26007
+ const tailIsWholeLine = tail.trim().length > 0 && (() => {
26008
+ try {
26009
+ JSON.parse(tail);
26010
+ return true;
26011
+ } catch {
26012
+ return false;
26013
+ }
26014
+ })();
26015
+ const complete = tailIsWholeLine ? head + tail : head;
26016
+ if (complete.length === 0) {
26017
+ return { events: [], bytesConsumed: fromByte };
26018
+ }
26019
+ const bytesConsumed = fromByte + Buffer.byteLength(complete, "utf-8");
26020
+ let entries;
26021
+ try {
26022
+ entries = await parseLogContent(complete, "session");
26023
+ } catch {
26024
+ return null;
26025
+ }
26026
+ let cwd = "";
26027
+ for (const line of complete.split(`
26028
+ `, 50)) {
26029
+ if (!line.trim())
26030
+ continue;
26031
+ try {
26032
+ const parsed = JSON.parse(line);
26033
+ if (typeof parsed.cwd === "string" && parsed.cwd.length > 0) {
26034
+ cwd = parsed.cwd;
26035
+ break;
26036
+ }
26037
+ } catch {}
26038
+ }
26039
+ return {
26040
+ events: logEntriesToEvents(entries, {
26041
+ cli: "claude",
26042
+ sessionId: meta.sessionId,
26043
+ transcriptPath: meta.transcriptPath,
26044
+ cwd
26045
+ }),
26046
+ bytesConsumed,
26047
+ cwd: cwd || undefined
26048
+ };
26049
+ }
25947
26050
  var init_claude = __esm(() => {
25948
26051
  init_claude_sessions();
25949
26052
  init_log_entries();
@@ -26104,20 +26207,9 @@ var init_cursor = __esm(() => {
26104
26207
  });
26105
26208
 
26106
26209
  // lib/opencode-sessions.ts
26107
- import { execFileSync as execFileSync4 } from "node:child_process";
26108
- function runOpenCodeDb2(sql) {
26210
+ function safeQuery(run) {
26109
26211
  try {
26110
- const stdout = execFileSync4("opencode", ["db", "--format", "json", sql], {
26111
- encoding: "utf8",
26112
- timeout: 5000,
26113
- stdio: ["ignore", "pipe", "pipe"]
26114
- });
26115
- if (!stdout.trim())
26116
- return [];
26117
- const parsed = JSON.parse(stdout);
26118
- if (!Array.isArray(parsed))
26119
- return null;
26120
- return parsed;
26212
+ return run();
26121
26213
  } catch {
26122
26214
  return null;
26123
26215
  }
@@ -26226,12 +26318,17 @@ function translateMessage(msgRow, partRows, source) {
26226
26318
  async function getOpenCodeSessionLog(sessionId) {
26227
26319
  if (!sessionId || !/^[A-Za-z0-9_-]+$/.test(sessionId))
26228
26320
  return null;
26229
- const sessions = runOpenCodeDb2(`SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session WHERE id = '${sessionId}'`);
26321
+ const rows3 = await withOpenCodeDb((db) => ({
26322
+ sessions: safeQuery(() => db.query("SELECT id, project_id, slug, directory, title, time_created, time_updated FROM session WHERE id = ?", [sessionId])),
26323
+ messages: safeQuery(() => db.query("SELECT id, session_id, time_created, time_updated, data FROM message WHERE session_id = ? ORDER BY time_created ASC", [sessionId])),
26324
+ parts: safeQuery(() => db.query("SELECT id, message_id, session_id, time_created, time_updated, data FROM part WHERE session_id = ? ORDER BY time_created ASC", [sessionId]))
26325
+ }));
26326
+ const sessions = rows3?.sessions ?? null;
26230
26327
  if (!sessions || sessions.length === 0)
26231
26328
  return null;
26232
26329
  const session = sessions[0];
26233
- const messages = runOpenCodeDb2(`SELECT id, session_id, time_created, time_updated, data FROM message WHERE session_id = '${sessionId}' ORDER BY time_created ASC`);
26234
- const parts = runOpenCodeDb2(`SELECT id, message_id, session_id, time_created, time_updated, data FROM part WHERE session_id = '${sessionId}' ORDER BY time_created ASC`);
26330
+ const messages = rows3?.messages ?? null;
26331
+ const parts = rows3?.parts ?? null;
26235
26332
  if (!messages)
26236
26333
  return { entries: [], rawLines: [], cwd: session.directory ?? undefined, filePath: `opencode://${sessionId}` };
26237
26334
  const partsByMessage = new Map;
@@ -26265,6 +26362,7 @@ async function getOpenCodeSessionLog(sessionId) {
26265
26362
  }
26266
26363
  var getCachedOpenCodeSessionLog;
26267
26364
  var init_opencode_sessions = __esm(() => {
26365
+ init_opencode_db();
26268
26366
  init_log_entries();
26269
26367
  getCachedOpenCodeSessionLog = runtimeCache((sessionId) => getOpenCodeSessionLog(sessionId), 30, { maxSize: 50 });
26270
26368
  });
@@ -26668,7 +26766,8 @@ var init_cli_adapters = __esm(() => {
26668
26766
  claude: {
26669
26767
  cli: "claude",
26670
26768
  listTranscripts: listClaudeTranscriptMetadata,
26671
- streamEvents: streamClaudeEvents
26769
+ streamEvents: streamClaudeEvents,
26770
+ streamEventsFrom: streamClaudeEventsFrom
26672
26771
  },
26673
26772
  codex: {
26674
26773
  cli: "codex",
@@ -27068,8 +27167,8 @@ var init_features = __esm(() => {
27068
27167
 
27069
27168
  // src/audit/cache.ts
27070
27169
  import { createHash as createHash8 } from "node:crypto";
27071
- import { existsSync as existsSync32, mkdirSync as mkdirSync20, readFileSync as readFileSync26, writeFileSync as writeFileSync18, chmodSync as chmodSync5 } from "node:fs";
27072
- import { join as join32 } from "node:path";
27170
+ import { existsSync as existsSync32, mkdirSync as mkdirSync20, readFileSync as readFileSync26, writeFileSync as writeFileSync18, chmodSync as chmodSync5, openSync, readSync, closeSync } from "node:fs";
27171
+ import { join as join33 } from "node:path";
27073
27172
  function getEngineVersion() {
27074
27173
  if (cachedEngineVersion)
27075
27174
  return cachedEngineVersion;
@@ -27089,9 +27188,43 @@ function getDetectorVersion() {
27089
27188
  function getCachePathFor(transcriptPath) {
27090
27189
  const root = auditCacheDir();
27091
27190
  const key = createHash8("sha1").update(transcriptPath).digest("hex");
27092
- return join32(root, `${key}.json`);
27191
+ return join33(root, `${key}.json`);
27192
+ }
27193
+ function encodeDetectorState(state) {
27194
+ return JSON.stringify(state, (_k, v) => v instanceof Map ? { __map: [...v.entries()] } : v);
27195
+ }
27196
+ function decodeDetectorState(raw) {
27197
+ if (!raw)
27198
+ return {};
27199
+ try {
27200
+ return JSON.parse(raw, (_k, v) => v && typeof v === "object" && Array.isArray(v.__map) ? new Map(v.__map) : v);
27201
+ } catch {
27202
+ return {};
27203
+ }
27204
+ }
27205
+ function anchorHashFor(transcriptPath, upTo) {
27206
+ if (upTo <= 0)
27207
+ return null;
27208
+ let fd = null;
27209
+ try {
27210
+ fd = openSync(transcriptPath, "r");
27211
+ const head = Buffer.alloc(Math.min(ANCHOR_WINDOW, upTo));
27212
+ readSync(fd, head, 0, head.length, 0);
27213
+ const tailLen = Math.min(ANCHOR_WINDOW, upTo);
27214
+ const tail = Buffer.alloc(tailLen);
27215
+ readSync(fd, tail, 0, tailLen, upTo - tailLen);
27216
+ return createHash8("sha1").update(String(upTo)).update(head).update(tail).digest("hex").slice(0, 32);
27217
+ } catch {
27218
+ return null;
27219
+ } finally {
27220
+ if (fd !== null) {
27221
+ try {
27222
+ closeSync(fd);
27223
+ } catch {}
27224
+ }
27225
+ }
27093
27226
  }
27094
- function readCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes) {
27227
+ function readCachedTranscript(transcriptPath, mtimeMs, sizeBytes) {
27095
27228
  if (sizeBytes === 0)
27096
27229
  return null;
27097
27230
  const cachePath = getCachePathFor(transcriptPath);
@@ -27102,22 +27235,37 @@ function readCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes) {
27102
27235
  const entry = JSON.parse(raw);
27103
27236
  if (entry.schemaVersion !== CACHE_SCHEMA_VERSION)
27104
27237
  return null;
27105
- if (entry.mtimeMs !== mtimeMs)
27106
- return null;
27107
- if (entry.sizeBytes !== sizeBytes)
27108
- return null;
27109
27238
  if (entry.engineVersion !== getEngineVersion())
27110
27239
  return null;
27111
27240
  if (entry.detectorVersion !== getDetectorVersion())
27112
27241
  return null;
27113
27242
  if (!Number.isFinite(entry.cachedAt) || Date.now() - entry.cachedAt > CACHE_TTL_MS)
27114
27243
  return null;
27115
- return entry.result ?? null;
27244
+ if (!entry.result)
27245
+ return null;
27246
+ if (entry.mtimeMs === mtimeMs && entry.sizeBytes === sizeBytes) {
27247
+ return { kind: "hit", result: entry.result };
27248
+ }
27249
+ const from = entry.bytesScanned;
27250
+ if (!Number.isFinite(from) || from <= 0)
27251
+ return null;
27252
+ if (from > sizeBytes)
27253
+ return null;
27254
+ if (!entry.anchorHash)
27255
+ return null;
27256
+ if (anchorHashFor(transcriptPath, from) !== entry.anchorHash)
27257
+ return null;
27258
+ return {
27259
+ kind: "resume",
27260
+ result: entry.result,
27261
+ fromByte: from,
27262
+ detectorState: decodeDetectorState(entry.detectorState)
27263
+ };
27116
27264
  } catch {
27117
27265
  return null;
27118
27266
  }
27119
27267
  }
27120
- function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result) {
27268
+ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result, resume) {
27121
27269
  if (sizeBytes === 0)
27122
27270
  return;
27123
27271
  const cachePath = getCachePathFor(transcriptPath);
@@ -27132,13 +27280,21 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result)
27132
27280
  detectorVersion: getDetectorVersion(),
27133
27281
  result
27134
27282
  };
27283
+ if (resume && resume.bytesScanned > 0) {
27284
+ const anchor = anchorHashFor(transcriptPath, resume.bytesScanned);
27285
+ if (anchor) {
27286
+ entry.bytesScanned = resume.bytesScanned;
27287
+ entry.anchorHash = anchor;
27288
+ entry.detectorState = encodeDetectorState(resume.detectorState);
27289
+ }
27290
+ }
27135
27291
  writeFileSync18(cachePath, JSON.stringify(entry), { encoding: "utf-8", mode: 384 });
27136
27292
  try {
27137
27293
  chmodSync5(cachePath, 384);
27138
27294
  } catch {}
27139
27295
  } catch {}
27140
27296
  }
27141
- var cachedEngineVersion = null, cachedDetectorVersion = null, CACHE_SCHEMA_VERSION = 3, CACHE_TTL_MS;
27297
+ var cachedEngineVersion = null, cachedDetectorVersion = null, CACHE_SCHEMA_VERSION = 4, ANCHOR_WINDOW = 4096, CACHE_TTL_MS;
27142
27298
  var init_cache = __esm(() => {
27143
27299
  init_builtin_policies();
27144
27300
  init_detectors();
@@ -27251,7 +27407,7 @@ function parseSinceOpt(since) {
27251
27407
  return t;
27252
27408
  throw new Error(`Invalid --since value: "${since}" (expected e.g. "7d", "30d", or "2026-04-01")`);
27253
27409
  }
27254
- async function scanOneTranscript(meta) {
27410
+ async function scanOneTranscript(meta, resume) {
27255
27411
  const empty = {
27256
27412
  transcriptPath: meta.transcriptPath,
27257
27413
  cli: meta.cli,
@@ -27265,13 +27421,30 @@ async function scanOneTranscript(meta) {
27265
27421
  examplesByName: {},
27266
27422
  rangeByName: {}
27267
27423
  };
27268
- const events = await ADAPTERS[meta.cli].streamEvents(meta);
27269
- if (events.length === 0)
27270
- return empty;
27424
+ const adapter = ADAPTERS[meta.cli];
27425
+ let events;
27426
+ let bytesScanned = 0;
27427
+ const sessionState = resume?.detectorState ?? {};
27428
+ if (adapter.streamEventsFrom) {
27429
+ const scan = await adapter.streamEventsFrom(meta, resume?.fromByte ?? 0);
27430
+ if (!scan) {
27431
+ events = await adapter.streamEvents(meta);
27432
+ bytesScanned = 0;
27433
+ } else {
27434
+ events = scan.events;
27435
+ bytesScanned = scan.bytesConsumed;
27436
+ empty.cwd = scan.cwd ?? "";
27437
+ }
27438
+ } else {
27439
+ events = await adapter.streamEvents(meta);
27440
+ bytesScanned = 0;
27441
+ }
27442
+ if (events.length === 0) {
27443
+ return { result: empty, bytesScanned, detectorState: sessionState };
27444
+ }
27271
27445
  const result = empty;
27272
27446
  result.eventsScanned = events.length;
27273
- result.cwd = events[0].cwd || "";
27274
- const sessionState = {};
27447
+ result.cwd = result.cwd || events[0].cwd || "";
27275
27448
  for (const event of events) {
27276
27449
  for (const detector of AUDIT_DETECTORS) {
27277
27450
  const hit = detector.detect(event, sessionState);
@@ -27290,7 +27463,7 @@ async function scanOneTranscript(meta) {
27290
27463
  recordHit(result, hit.policyName, event.timestamp, event.cwd, truncateExample(example));
27291
27464
  }
27292
27465
  }
27293
- return result;
27466
+ return { result, bytesScanned, detectorState: sessionState };
27294
27467
  }
27295
27468
  function formatPolicyExample(_policyName, event) {
27296
27469
  if (event.toolName === "Bash") {
@@ -27303,6 +27476,45 @@ function formatPolicyExample(_policyName, event) {
27303
27476
  return `${event.toolName} ${filePath}`;
27304
27477
  return `${event.toolName}`;
27305
27478
  }
27479
+ function mergeIncremental(cached, tail) {
27480
+ const out = {
27481
+ ...cached,
27482
+ mtimeMs: tail.mtimeMs,
27483
+ sizeBytes: tail.sizeBytes,
27484
+ cwd: cached.cwd || tail.cwd || "",
27485
+ eventsScanned: (cached.eventsScanned ?? 0) + (tail.eventsScanned ?? 0),
27486
+ hitsByName: { ...cached.hitsByName },
27487
+ examplesByName: {},
27488
+ rangeByName: { ...cached.rangeByName }
27489
+ };
27490
+ for (const [name, list] of Object.entries(cached.examplesByName)) {
27491
+ out.examplesByName[name] = [...list];
27492
+ }
27493
+ for (const [name, count] of Object.entries(tail.hitsByName)) {
27494
+ out.hitsByName[name] = (out.hitsByName[name] ?? 0) + count;
27495
+ }
27496
+ for (const [name, list] of Object.entries(tail.examplesByName)) {
27497
+ const exs = out.examplesByName[name] ?? [];
27498
+ for (const ex of list) {
27499
+ if (exs.length >= AUDIT_MAX_EXAMPLES_PER_NAME)
27500
+ break;
27501
+ exs.push(ex);
27502
+ }
27503
+ out.examplesByName[name] = exs;
27504
+ }
27505
+ for (const [name, range] of Object.entries(tail.rangeByName)) {
27506
+ const existing = out.rangeByName[name];
27507
+ if (!existing) {
27508
+ out.rangeByName[name] = { ...range };
27509
+ } else {
27510
+ if (range.first < existing.first)
27511
+ existing.first = range.first;
27512
+ if (range.last > existing.last)
27513
+ existing.last = range.last;
27514
+ }
27515
+ }
27516
+ return out;
27517
+ }
27306
27518
  function recordHit(result, name, timestamp, cwd, example) {
27307
27519
  result.hitsByName[name] = (result.hitsByName[name] ?? 0) + 1;
27308
27520
  const exs = result.examplesByName[name] ?? [];
@@ -27404,15 +27616,20 @@ async function runAuditInner(opts, startedAt) {
27404
27616
  let skipped = 0;
27405
27617
  let errors2 = 0;
27406
27618
  const tasks = allTranscripts.map((meta) => async () => {
27619
+ let resume;
27620
+ let cachedPrefix = null;
27407
27621
  if (!opts.noCache) {
27408
- const cached = readCachedTranscriptResult(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes);
27409
- if (cached)
27410
- return cached;
27622
+ const found = readCachedTranscript(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes);
27623
+ if (found?.kind === "hit")
27624
+ return found.result;
27625
+ resume = found?.kind === "resume" ? { fromByte: found.fromByte, detectorState: found.detectorState } : undefined;
27626
+ cachedPrefix = found?.kind === "resume" ? found.result : null;
27411
27627
  }
27412
27628
  try {
27413
- const fresh = await scanOneTranscript(meta);
27629
+ const scan = await scanOneTranscript(meta, resume);
27630
+ const fresh = cachedPrefix ? mergeIncremental(cachedPrefix, scan.result) : scan.result;
27414
27631
  if (!opts.noCache) {
27415
- writeCachedTranscriptResult(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes, fresh);
27632
+ writeCachedTranscriptResult(meta.transcriptPath, meta.mtimeMs, meta.sizeBytes, fresh, scan.bytesScanned > 0 ? { bytesScanned: scan.bytesScanned, detectorState: scan.detectorState } : undefined);
27416
27633
  }
27417
27634
  return fresh;
27418
27635
  } catch {
@@ -27496,10 +27713,10 @@ var init_audit = __esm(() => {
27496
27713
 
27497
27714
  // src/audit/audit-lock.ts
27498
27715
  import {
27499
- closeSync,
27716
+ closeSync as closeSync2,
27500
27717
  linkSync,
27501
27718
  mkdirSync as mkdirSync21,
27502
- openSync,
27719
+ openSync as openSync2,
27503
27720
  readFileSync as readFileSync27,
27504
27721
  unlinkSync as unlinkSync4,
27505
27722
  writeFileSync as writeFileSync19,
@@ -27597,7 +27814,7 @@ function writeLockExclusive(path3, info) {
27597
27814
  function createThenWrite(path3, body) {
27598
27815
  let fd;
27599
27816
  try {
27600
- fd = openSync(path3, "wx", 384);
27817
+ fd = openSync2(path3, "wx", 384);
27601
27818
  writeSync(fd, body);
27602
27819
  return true;
27603
27820
  } catch {
@@ -27605,7 +27822,7 @@ function createThenWrite(path3, body) {
27605
27822
  } finally {
27606
27823
  if (fd !== undefined) {
27607
27824
  try {
27608
- closeSync(fd);
27825
+ closeSync2(fd);
27609
27826
  } catch {}
27610
27827
  }
27611
27828
  }
@@ -27869,10 +28086,10 @@ var init_api_server_client = __esm(() => {
27869
28086
 
27870
28087
  // lib/auth/auth-store.ts
27871
28088
  import { existsSync as existsSync34, readFileSync as readFileSync29, readdirSync as readdirSync18, rmSync as rmSync13 } from "node:fs";
27872
- import { join as join33, resolve as resolve24 } from "node:path";
28089
+ import { join as join34, resolve as resolve24 } from "node:path";
27873
28090
  function getAuthFilePath() {
27874
28091
  const override = process.env.FAILPROOFAI_AUTH_DIR;
27875
- return override ? join33(override, "session.json") : auditSessionFile();
28092
+ return override ? join34(override, "session.json") : auditSessionFile();
27876
28093
  }
27877
28094
  function readAuth() {
27878
28095
  const p = getAuthFilePath();
@@ -27975,7 +28192,7 @@ var init_auth_store = __esm(() => {
27975
28192
  });
27976
28193
 
27977
28194
  // src/audit/redact-example.ts
27978
- import { homedir as homedir25 } from "node:os";
28195
+ import { homedir as homedir26 } from "node:os";
27979
28196
  function maskTruncatedSecret(input) {
27980
28197
  for (const [pattern, label] of SECRET_PREFIXES) {
27981
28198
  if (pattern.test(input)) {
@@ -28010,7 +28227,7 @@ function maskSecrets(input) {
28010
28227
  }
28011
28228
  return out;
28012
28229
  }
28013
- function shortenPaths(input, home = homedir25()) {
28230
+ function shortenPaths(input, home = homedir26()) {
28014
28231
  const homeRoot = home.replace(/\/+$/, "");
28015
28232
  return input.replace(ABSOLUTE_PATH_RE, (match, offset, whole) => {
28016
28233
  if (PUBLIC_PATH_ROOTS.some((root2) => match.startsWith(root2)))
@@ -28041,7 +28258,7 @@ function shortenPaths(input, home = homedir25()) {
28041
28258
  return `${root}${middle}/${tail}${trailingSlash ? "/" : ""}`;
28042
28259
  });
28043
28260
  }
28044
- function redactExample(input, home = homedir25()) {
28261
+ function redactExample(input, home = homedir26()) {
28045
28262
  const masked = maskAssignedSecrets(maskTruncatedSecret(maskSecrets(input)));
28046
28263
  const shortened = shortenPaths(masked, home);
28047
28264
  const collapsed = shortened.replace(/\s+/g, " ").trim();
@@ -28662,7 +28879,7 @@ function asScheduleError(err) {
28662
28879
  }
28663
28880
  throw err;
28664
28881
  }
28665
- var MIN_DAYS = 1, MAX_DAYS = 90, ScheduleCliError, styled = () => colorsEnabled2(process.stdout), wrap3 = (open2, s) => styled() ? `${open2}${s}${ANSI_RESET2}` : s, pink = (s) => wrap3(brandAnsi2("pink"), s), green = (s) => wrap3(brandAnsi2("guide"), s), dim = (s) => wrap3(ANSI_DIM2, s), bold = (s) => wrap3(ANSI_BOLD2, s);
28882
+ var MIN_DAYS = 1, MAX_DAYS = 90, ScheduleCliError, styled = () => colorsEnabled2(process.stdout), wrap3 = (open3, s) => styled() ? `${open3}${s}${ANSI_RESET2}` : s, pink = (s) => wrap3(brandAnsi2("pink"), s), green = (s) => wrap3(brandAnsi2("guide"), s), dim = (s) => wrap3(ANSI_DIM2, s), bold = (s) => wrap3(ANSI_BOLD2, s);
28666
28883
  var init_schedule_cli = __esm(() => {
28667
28884
  init_fp_config();
28668
28885
  init_daemon_service();
@@ -28742,7 +28959,7 @@ var init_parse_script_args = () => {};
28742
28959
  // scripts/install-diagnosis.mjs
28743
28960
  import { existsSync as existsSync36, readFileSync as readFileSync32, realpathSync as realpathSync3 } from "node:fs";
28744
28961
  import { dirname as dirname17, resolve as resolve26 } from "node:path";
28745
- import { homedir as homedir26, platform as platform4 } from "node:os";
28962
+ import { homedir as homedir27, platform as platform4 } from "node:os";
28746
28963
  import { spawnSync } from "node:child_process";
28747
28964
  function findPackageRoot(start) {
28748
28965
  try {
@@ -28806,7 +29023,7 @@ function locateNpmGlobal() {
28806
29023
  }
28807
29024
  function locateBunGlobal() {
28808
29025
  try {
28809
- const candidate = resolve26(homedir26(), ".bun", "install", "global", "node_modules", PKG_NAME);
29026
+ const candidate = resolve26(homedir27(), ".bun", "install", "global", "node_modules", PKG_NAME);
28810
29027
  return existsSync36(resolve26(candidate, "package.json")) ? candidate : null;
28811
29028
  } catch {
28812
29029
  return null;
@@ -28815,8 +29032,8 @@ function locateBunGlobal() {
28815
29032
  function buildRecommendation(pathFirstBin) {
28816
29033
  if (!pathFirstBin)
28817
29034
  return null;
28818
- const bunBinPrefix = resolve26(homedir26(), ".bun", "bin") + "/";
28819
- const bunGlobalPrefix = resolve26(homedir26(), ".bun", "install", "global") + "/";
29035
+ const bunBinPrefix = resolve26(homedir27(), ".bun", "bin") + "/";
29036
+ const bunGlobalPrefix = resolve26(homedir27(), ".bun", "install", "global") + "/";
28820
29037
  const isBun = pathFirstBin.startsWith(bunBinPrefix) || pathFirstBin.startsWith(bunGlobalPrefix);
28821
29038
  if (isBun) {
28822
29039
  return `rm -f ~/.bun/bin/${PKG_NAME} && rm -rf ~/.bun/install/global/node_modules/${PKG_NAME}`;
@@ -29461,7 +29678,7 @@ __export(exports_configure_wizard, {
29461
29678
  setCustomPoliciesEnabled: () => setCustomPoliciesEnabled
29462
29679
  });
29463
29680
  import { existsSync as existsSync38, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readFileSync as readFileSync33 } from "node:fs";
29464
- import { homedir as homedir27 } from "node:os";
29681
+ import { homedir as homedir28 } from "node:os";
29465
29682
  import { dirname as dirname19, resolve as resolve28, sep as sep5 } from "node:path";
29466
29683
  async function emit(event, props) {
29467
29684
  try {
@@ -29469,7 +29686,7 @@ async function emit(event, props) {
29469
29686
  } catch {}
29470
29687
  }
29471
29688
  function homeify(p) {
29472
- const home = homedir27();
29689
+ const home = homedir28();
29473
29690
  if (p === home)
29474
29691
  return "~";
29475
29692
  if (p.startsWith(home + sep5))
@@ -30160,16 +30377,16 @@ __export(exports_flush_cli2, {
30160
30377
  runFlushCommand: () => runFlushCommand2
30161
30378
  });
30162
30379
  import { existsSync as existsSync39, mkdirSync as mkdirSync23, writeFileSync as writeFileSync21, readdirSync as readdirSync19 } from "node:fs";
30163
- import { dirname as dirname20, join as join34 } from "node:path";
30380
+ import { dirname as dirname20, join as join35 } from "node:path";
30164
30381
  function flushRequestPath2(home) {
30165
- return join34(failproofaiHome(home), "state", "flush-request.json");
30382
+ return join35(failproofaiHome(home), "state", "flush-request.json");
30166
30383
  }
30167
30384
  function spoolDirs2(home) {
30168
30385
  const root = spoolDir(home);
30169
30386
  if (!existsSync39(root))
30170
30387
  return [];
30171
30388
  try {
30172
- return readdirSync19(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join34(root, e.name));
30389
+ return readdirSync19(root, { withFileTypes: true }).filter((e) => e.isDirectory() && e.name !== "failed").map((e) => join35(root, e.name));
30173
30390
  } catch {
30174
30391
  return [];
30175
30392
  }
@@ -30274,14 +30491,14 @@ __export(exports_backfill_cli, {
30274
30491
  runBackfillCommand: () => runBackfillCommand
30275
30492
  });
30276
30493
  import { existsSync as existsSync40, mkdirSync as mkdirSync24, writeFileSync as writeFileSync22, readdirSync as readdirSync20, statSync as statSync24 } from "node:fs";
30277
- import { dirname as dirname21, join as join35 } from "node:path";
30494
+ import { dirname as dirname21, join as join36 } from "node:path";
30278
30495
  function backfillRequestPath(home) {
30279
- return join35(failproofaiHome(home), "state", "backfill-request.json");
30496
+ return join36(failproofaiHome(home), "state", "backfill-request.json");
30280
30497
  }
30281
30498
  function surveySessions(sinceMs, homeDir) {
30282
30499
  const out = [];
30283
30500
  for (const { cli, dir } of SESSION_DIRS) {
30284
- const root = join35(homeDir, dir);
30501
+ const root = join36(homeDir, dir);
30285
30502
  if (!existsSync40(root))
30286
30503
  continue;
30287
30504
  let files = 0;
@@ -30296,7 +30513,7 @@ function surveySessions(sinceMs, homeDir) {
30296
30513
  return;
30297
30514
  }
30298
30515
  for (const e of entries) {
30299
- const p = join35(d, e.name);
30516
+ const p = join36(d, e.name);
30300
30517
  if (e.isDirectory()) {
30301
30518
  walk(p, depth + 1);
30302
30519
  continue;
@@ -30420,16 +30637,17 @@ var init_backfill_cli = __esm(() => {
30420
30637
  // src/hooks/pack-cli.ts
30421
30638
  var exports_pack_cli = {};
30422
30639
  __export(exports_pack_cli, {
30640
+ __pushExistingHistoryForTest: () => __pushExistingHistoryForTest,
30423
30641
  packAddSource: () => packAddSource,
30424
30642
  runPackCommand: () => runPackCommand,
30425
30643
  runPolicyPicker: () => runPolicyPicker,
30426
30644
  runPublishCommand: () => runPublishCommand
30427
30645
  });
30428
- import { execFileSync as execFileSync5 } from "node:child_process";
30429
- import { homedir as homedir28 } from "node:os";
30646
+ import { execFileSync as execFileSync3 } from "node:child_process";
30647
+ import { homedir as homedir29, tmpdir as tmpdir3 } from "node:os";
30430
30648
  import { createHash as createHash9 } from "node:crypto";
30431
- import { copyFileSync as copyFileSync4, existsSync as existsSync41, mkdirSync as mkdirSync25, readFileSync as readFileSync34, readdirSync as readdirSync21, statSync as statSync25, writeFileSync as writeFileSync23 } from "node:fs";
30432
- import { resolve as resolve29 } from "node:path";
30649
+ import { copyFileSync as copyFileSync4, existsSync as existsSync41, mkdirSync as mkdirSync25, mkdtempSync as mkdtempSync2, readFileSync as readFileSync34, readdirSync as readdirSync21, rmSync as rmSync15, statSync as statSync25, writeFileSync as writeFileSync23 } from "node:fs";
30650
+ import { basename as basename7, dirname as dirname22, join as join37, resolve as resolve29 } from "node:path";
30433
30651
  function parseList(rest, flag) {
30434
30652
  const idx = rest.findIndex((a) => a === flag || a.startsWith(`${flag}=`));
30435
30653
  if (idx === -1)
@@ -30622,6 +30840,9 @@ async function runPolicyPicker(action, io = {}) {
30622
30840
  lines.push(` turned off (${turnedOff.length}): ${summarise(turnedOff)}`);
30623
30841
  return ok(lines);
30624
30842
  }
30843
+ function withPolicyExtension(name) {
30844
+ return /\.(mjs|js|ts)$/.test(name) ? name : `${name}.mjs`;
30845
+ }
30625
30846
  async function scaffold(target) {
30626
30847
  let chosen = target;
30627
30848
  if (!chosen && process.stdin.isTTY && process.stdout.isTTY) {
@@ -30635,9 +30856,9 @@ async function scaffold(target) {
30635
30856
  });
30636
30857
  if (answer === null)
30637
30858
  return ok(["Nothing written."]);
30638
- chosen = `./${answer.trim().replace(/\.(mjs|js|ts)$/, "")}.mjs`;
30859
+ chosen = answer.trim();
30639
30860
  }
30640
- const path3 = resolve29(chosen ?? "./my-policies.mjs");
30861
+ const path3 = resolve29(withPolicyExtension(chosen ?? "my-policies"));
30641
30862
  if (existsSync41(path3)) {
30642
30863
  return fail([`${path3} already exists — name a different file, or edit that one.`]);
30643
30864
  }
@@ -30673,12 +30894,12 @@ customPolicies.add({
30673
30894
  " then ask your agent to force-push — it gets refused",
30674
30895
  "",
30675
30896
  "Then publish it:",
30676
- ` failproofai publish ${path3} --repo <you>/<repo> --version 1.0.0`
30897
+ " failproofai publish --repo <you>/<repo>"
30677
30898
  ]);
30678
30899
  }
30679
30900
  function inferRepo(entryPath) {
30680
30901
  try {
30681
- const url = execFileSync5("git", ["remote", "get-url", "origin"], {
30902
+ const url = execFileSync3("git", ["remote", "get-url", "origin"], {
30682
30903
  cwd: resolve29(entryPath, ".."),
30683
30904
  encoding: "utf8",
30684
30905
  stdio: ["ignore", "pipe", "ignore"],
@@ -30694,7 +30915,7 @@ function inferTaggedVersion(entryPath) {
30694
30915
  const cwd = resolve29(entryPath, "..");
30695
30916
  const git = (args) => {
30696
30917
  try {
30697
- return execFileSync5("git", args, {
30918
+ return execFileSync3("git", args, {
30698
30919
  cwd,
30699
30920
  encoding: "utf8",
30700
30921
  stdio: ["ignore", "pipe", "ignore"],
@@ -30751,7 +30972,7 @@ async function nextVersion(owner, name, token) {
30751
30972
  }
30752
30973
  return best ? `${best[0]}.${best[1]}.${best[2] + 1}` : "1.0.0";
30753
30974
  }
30754
- async function ensureRepo(owner, name, id, token) {
30975
+ async function ensureRepo(owner, name, id, token, sourceDir) {
30755
30976
  let info = await gh(`${GITHUB_API}/repos/${owner}/${name}`, token);
30756
30977
  let created = false;
30757
30978
  if (info.status === 404) {
@@ -30765,7 +30986,7 @@ async function ensureRepo(owner, name, id, token) {
30765
30986
  name,
30766
30987
  private: false,
30767
30988
  description: `failproofai policy pack — ${id}`,
30768
- auto_init: true
30989
+ auto_init: false
30769
30990
  })
30770
30991
  });
30771
30992
  if (made.status >= 400) {
@@ -30779,6 +31000,9 @@ async function ensureRepo(owner, name, id, token) {
30779
31000
  };
30780
31001
  }
30781
31002
  created = true;
31003
+ if (!(sourceDir && pushExistingHistory(sourceDir, owner, name, token))) {
31004
+ await seedDefaultBranch(owner, name, id, token);
31005
+ }
30782
31006
  info = await gh(`${GITHUB_API}/repos/${owner}/${name}`, token);
30783
31007
  }
30784
31008
  if (info.status >= 400) {
@@ -30786,17 +31010,77 @@ async function ensureRepo(owner, name, id, token) {
30786
31010
  }
30787
31011
  return { info, created };
30788
31012
  }
31013
+ function pushExistingHistory(dir, owner, name, token) {
31014
+ const git = (args, env) => {
31015
+ try {
31016
+ return execFileSync3("git", args, {
31017
+ cwd: dir,
31018
+ encoding: "utf8",
31019
+ stdio: ["ignore", "pipe", "ignore"],
31020
+ timeout: 60000,
31021
+ env: env ? { ...process.env, ...env } : process.env
31022
+ }).trim();
31023
+ } catch {
31024
+ return null;
31025
+ }
31026
+ };
31027
+ const branch = git(["rev-parse", "--abbrev-ref", "HEAD"]);
31028
+ if (!branch || branch === "HEAD" || !git(["rev-parse", "--verify", "HEAD"]))
31029
+ return false;
31030
+ const askpass = join37(mkdtempSync2(join37(tmpdir3(), "fpai-askpass-")), "askpass.sh");
31031
+ try {
31032
+ writeFileSync23(askpass, `#!/bin/sh
31033
+ case "$1" in
31034
+ *Username*) echo x-access-token ;;
31035
+ *) echo "$FPAI_GH_TOKEN" ;;
31036
+ esac
31037
+ `, { mode: 448 });
31038
+ const env = { GIT_ASKPASS: askpass, FPAI_GH_TOKEN: token, GIT_TERMINAL_PROMPT: "0" };
31039
+ const url = `${GITHUB_GIT}/${owner}/${name}.git`;
31040
+ const adopt = !git(["remote", "get-url", "origin"]);
31041
+ if (adopt)
31042
+ git(["remote", "add", "origin", url]);
31043
+ const pushed = adopt ? git(["push", "-u", "origin", `${branch}:${branch}`], env) : git(["push", url, `${branch}:${branch}`], env);
31044
+ if (pushed === null) {
31045
+ if (adopt)
31046
+ git(["remote", "remove", "origin"]);
31047
+ return false;
31048
+ }
31049
+ return true;
31050
+ } finally {
31051
+ try {
31052
+ rmSync15(dirname22(askpass), { recursive: true, force: true });
31053
+ } catch {}
31054
+ }
31055
+ }
31056
+ async function seedDefaultBranch(owner, name, id, token) {
31057
+ await gh(`${GITHUB_API}/repos/${owner}/${name}/contents/README.md`, token, {
31058
+ method: "PUT",
31059
+ contentType: "application/json",
31060
+ body: JSON.stringify({
31061
+ message: `${id}: create pack repository`,
31062
+ content: Buffer.from(`# ${name}
31063
+
31064
+ A [failproofai](https://github.com/failproofai/failproofai) policy pack.
31065
+
31066
+ \`\`\`bash
31067
+ failproofai policies add ${owner}/${name}
31068
+ \`\`\`
31069
+ `, "utf8").toString("base64")
31070
+ })
31071
+ });
31072
+ }
30789
31073
  function findBun() {
30790
31074
  const candidates = [
30791
31075
  "bun",
30792
31076
  process.env.BUN_INSTALL ? resolve29(process.env.BUN_INSTALL, "bin", "bun") : null,
30793
- resolve29(homedir28(), ".bun", "bin", "bun"),
31077
+ resolve29(homedir29(), ".bun", "bin", "bun"),
30794
31078
  "/opt/homebrew/bin/bun",
30795
31079
  "/usr/local/bin/bun"
30796
31080
  ].filter((c2) => c2 !== null);
30797
31081
  for (const candidate of candidates) {
30798
31082
  try {
30799
- execFileSync5(candidate, ["--version"], { stdio: "ignore", timeout: 5000 });
31083
+ execFileSync3(candidate, ["--version"], { stdio: "ignore", timeout: 5000 });
30800
31084
  return candidate;
30801
31085
  } catch {
30802
31086
  continue;
@@ -30823,7 +31107,7 @@ function bundleEntry(sources, outDir) {
30823
31107
  `, "utf8");
30824
31108
  const bundled = resolve29(outDir, ".bundled.mjs");
30825
31109
  try {
30826
- execFileSync5(bun, [
31110
+ execFileSync3(bun, [
30827
31111
  "build",
30828
31112
  "--target=node",
30829
31113
  "--format=esm",
@@ -30853,7 +31137,7 @@ function githubToken() {
30853
31137
  if (fromEnv)
30854
31138
  return fromEnv.trim();
30855
31139
  try {
30856
- const out = execFileSync5("gh", ["auth", "token"], {
31140
+ const out = execFileSync3("gh", ["auth", "token"], {
30857
31141
  encoding: "utf8",
30858
31142
  stdio: ["ignore", "pipe", "ignore"],
30859
31143
  timeout: 5000
@@ -30890,6 +31174,30 @@ function ghError(res) {
30890
31174
  const errors2 = Array.isArray(res.json?.errors) ? res.json.errors.map((e) => [e.field, e.code].filter(Boolean).join(" ")).filter(Boolean) : [];
30891
31175
  return errors2.length > 0 ? `${message} (${errors2.join("; ")})` : message;
30892
31176
  }
31177
+ async function askWhereToPublish(suggestion, io) {
31178
+ const answer = await promptText2({
31179
+ message: "Where should this publish?",
31180
+ hint: `${suggestion} · created if it does not exist`,
31181
+ defaultValue: suggestion,
31182
+ validate: (v) => {
31183
+ const t = v.trim();
31184
+ if (!/^[A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*$/.test(t))
31185
+ return "owner/repo";
31186
+ return null;
31187
+ },
31188
+ stdin: io.stdin,
31189
+ stdout: io.stdout
31190
+ });
31191
+ return answer === null ? null : answer.trim();
31192
+ }
31193
+ async function credentialLogin(token) {
31194
+ try {
31195
+ const me = await gh(`${GITHUB_API}/user`, token);
31196
+ return typeof me.json?.login === "string" ? me.json.login : null;
31197
+ } catch {
31198
+ return null;
31199
+ }
31200
+ }
30893
31201
  async function publish(rest) {
30894
31202
  const flag = (name2) => {
30895
31203
  const i = rest.findIndex((a) => a === `--${name2}` || a.startsWith(`--${name2}=`));
@@ -30904,11 +31212,27 @@ async function publish(rest) {
30904
31212
  const discovered = entry ? [] : findEntry(process.cwd());
30905
31213
  if (!entry && discovered.length > 0)
30906
31214
  entry = discovered[0];
30907
- const repo = flag("repo") ?? (entry ? inferRepo(entry) : null) ?? undefined;
31215
+ let repo = flag("repo") ?? (entry ? inferRepo(entry) : null) ?? undefined;
31216
+ const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
31217
+ const askingWhere = interactive && !repo && entry && !rest.includes("--dry-run");
31218
+ if (askingWhere) {
31219
+ const found = discovered.length > 0 ? discovered : [entry];
31220
+ process.stdout.write(`
31221
+ ${found.length} policy ${found.length === 1 ? "file" : "files"}: ` + `${found.map((f) => basename7(f)).join(", ")}
31222
+
31223
+ `);
31224
+ const token2 = githubToken();
31225
+ const login = token2 ? await credentialLogin(token2) : null;
31226
+ const folder = basename7(resolve29(entry, ".."));
31227
+ const answered = await askWhereToPublish(`${login ?? "your-account"}/${folder}`, { stdin: process.stdin, stdout: process.stdout });
31228
+ if (answered === null)
31229
+ return ok(["Nothing was published."]);
31230
+ repo = answered;
31231
+ }
30908
31232
  let version3 = flag("version") ?? (entry ? inferTaggedVersion(entry) : null) ?? undefined;
30909
31233
  let versionCounted = false;
30910
- const id = flag("id") ?? repo;
30911
31234
  const dryRun = rest.includes("--dry-run") || !repo;
31235
+ const id = flag("id") ?? repo ?? (dryRun && entry ? `local/${basename7(resolve29(entry, ".."))}` : undefined);
30912
31236
  const [owner, name] = (repo ?? "/").split("/");
30913
31237
  if (repo && (!owner || !name || repo.split("/").length !== 2)) {
30914
31238
  return fail([`--repo must be <owner>/<repo>, got ${JSON.stringify(repo)}`]);
@@ -30947,7 +31271,7 @@ async function publish(rest) {
30947
31271
  "It needs write access to releases on that repository, and nothing else."
30948
31272
  ]);
30949
31273
  }
30950
- const ensured = await ensureRepo(owner, name, id, token);
31274
+ const ensured = await ensureRepo(owner, name, id, token, resolve29(entry, ".."));
30951
31275
  if ("error" in ensured)
30952
31276
  return fail(ensured.error);
30953
31277
  created = ensured.created;
@@ -30988,7 +31312,7 @@ async function publish(rest) {
30988
31312
  "",
30989
31313
  ...repo ? ["Dry run — nothing was published.", `Drop --dry-run to release it on ${repo}.`] : [
30990
31314
  "Nothing was published: name a repository to release it on.",
30991
- ` failproofai publish ${entry} --repo <owner>/<repo> --version ${version3}`
31315
+ " failproofai publish --repo <owner>/<repo>"
30992
31316
  ]
30993
31317
  ]);
30994
31318
  }
@@ -31297,7 +31621,7 @@ async function runPackCommand(argv) {
31297
31621
  return fail([`Unknown pack subcommand ${JSON.stringify(sub)}`, "Try: add, remove, list, build"]);
31298
31622
  }
31299
31623
  }
31300
- var ok = (lines) => ({ lines, exitCode: 0 }), fail = (lines) => ({ lines, exitCode: 1 }), VALUE_FLAGS, PUBLISH_VALUE_FLAGS, GITHUB_API, GITHUB_UPLOADS;
31624
+ var ok = (lines) => ({ lines, exitCode: 0 }), fail = (lines) => ({ lines, exitCode: 1 }), VALUE_FLAGS, __pushExistingHistoryForTest = (dir, owner, name, token) => pushExistingHistory(dir, owner, name, token), PUBLISH_VALUE_FLAGS, GITHUB_API, GITHUB_UPLOADS, GITHUB_GIT;
31301
31625
  var init_pack_cli = __esm(() => {
31302
31626
  init_types();
31303
31627
  init_pack_manifest();
@@ -31320,6 +31644,7 @@ var init_pack_cli = __esm(() => {
31320
31644
  ]);
31321
31645
  GITHUB_API = process.env.FAILPROOFAI_GITHUB_API ?? "https://api.github.com";
31322
31646
  GITHUB_UPLOADS = process.env.FAILPROOFAI_GITHUB_UPLOADS ?? "https://uploads.github.com";
31647
+ GITHUB_GIT = process.env.FAILPROOFAI_GITHUB_GIT ?? "https://github.com";
31323
31648
  });
31324
31649
 
31325
31650
  // src/hooks/harness-cli.ts
@@ -31331,7 +31656,7 @@ __export(exports_harness_cli, {
31331
31656
  removePath: () => removePath,
31332
31657
  runHarnessCommand: () => runHarnessCommand
31333
31658
  });
31334
- import { homedir as homedir29 } from "node:os";
31659
+ import { homedir as homedir30 } from "node:os";
31335
31660
  import { resolve as resolve30 } from "node:path";
31336
31661
  function unknownHarness(name) {
31337
31662
  return fail2([
@@ -31375,7 +31700,7 @@ function comparableLabel(raw) {
31375
31700
  return raw.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
31376
31701
  }
31377
31702
  function comparablePath(raw) {
31378
- const home = homedir29();
31703
+ const home = homedir30();
31379
31704
  const expanded = raw === "~" ? home : raw.startsWith("~/") ? resolve30(home, raw.slice(2)) : raw;
31380
31705
  return expanded.replace(/\/+$/, "");
31381
31706
  }
@@ -31583,7 +31908,7 @@ __export(exports_fp_config, {
31583
31908
  writeVersionFile: () => writeVersionFile2
31584
31909
  });
31585
31910
  import { chmodSync as chmodSync6, existsSync as existsSync42, mkdirSync as mkdirSync26, readFileSync as readFileSync35, statSync as statSync26, writeFileSync as writeFileSync24 } from "node:fs";
31586
- import { dirname as dirname22 } from "node:path";
31911
+ import { dirname as dirname23 } from "node:path";
31587
31912
  function detectLayout2() {
31588
31913
  const raw = readVersionFile2();
31589
31914
  if (raw) {
@@ -31889,7 +32214,7 @@ function hasCloudCredentials() {
31889
32214
  return Boolean(c2.cloud || c2.ingest);
31890
32215
  }
31891
32216
  function writeFileAt2(path3, contents) {
31892
- mkdirSync26(dirname22(path3), { recursive: true });
32217
+ mkdirSync26(dirname23(path3), { recursive: true });
31893
32218
  writeFileSync24(path3, contents, "utf8");
31894
32219
  }
31895
32220
  var DEFAULT_AUDIT_INTERVAL_DAYS2 = 7, MIN_AUDIT_INTERVAL_DAYS2 = 1, MAX_AUDIT_INTERVAL_DAYS2 = 90, DEFAULT_CONFIG2, OWNED_CONFIG_KEYS2, isPlainObject9 = (v) => typeof v === "object" && v !== null && !Array.isArray(v), OWNED_CREDENTIAL_KEYS2;
@@ -31996,12 +32321,12 @@ __export(exports_fp_home, {
31996
32321
  versionFile: () => versionFile2,
31997
32322
  workerSocket: () => workerSocket
31998
32323
  });
31999
- import { homedir as homedir30 } from "node:os";
32324
+ import { homedir as homedir31 } from "node:os";
32000
32325
  import { resolve as resolve31 } from "node:path";
32001
32326
  function failproofaiHome2(home) {
32002
32327
  if (home)
32003
32328
  return resolve31(home, ".failproofai");
32004
- return process.env.FAILPROOFAI_HOME || resolve31(homedir30(), ".failproofai");
32329
+ return process.env.FAILPROOFAI_HOME || resolve31(homedir31(), ".failproofai");
32005
32330
  }
32006
32331
  function resettablePaths2() {
32007
32332
  return [
@@ -32119,10 +32444,10 @@ import {
32119
32444
  mkdirSync as mkdirSync27,
32120
32445
  readFileSync as readFileSync36,
32121
32446
  renameSync as renameSync9,
32122
- rmSync as rmSync15,
32447
+ rmSync as rmSync16,
32123
32448
  writeFileSync as writeFileSync25
32124
32449
  } from "node:fs";
32125
- import { basename as basename7, dirname as dirname23, join as join36, resolve as resolve32 } from "node:path";
32450
+ import { basename as basename8, dirname as dirname24, join as join38, resolve as resolve32 } from "node:path";
32126
32451
  function migrateToLayout42() {
32127
32452
  const moves = [
32128
32453
  { from: legacy.authJson(), to: auditSessionFile() },
@@ -32131,9 +32456,9 @@ function migrateToLayout42() {
32131
32456
  ];
32132
32457
  const authDirOverride = process.env.FAILPROOFAI_AUTH_DIR;
32133
32458
  if (authDirOverride) {
32134
- moves.push({ from: join36(authDirOverride, "auth.json"), to: join36(authDirOverride, "session.json") }, {
32135
- from: join36(authDirOverride, "next-audit.json"),
32136
- to: join36(authDirOverride, "reminder.json")
32459
+ moves.push({ from: join38(authDirOverride, "auth.json"), to: join38(authDirOverride, "session.json") }, {
32460
+ from: join38(authDirOverride, "next-audit.json"),
32461
+ to: join38(authDirOverride, "reminder.json")
32137
32462
  });
32138
32463
  }
32139
32464
  const migrated = [];
@@ -32141,10 +32466,10 @@ function migrateToLayout42() {
32141
32466
  if (!existsSync43(from))
32142
32467
  continue;
32143
32468
  if (existsSync43(to)) {
32144
- rmSync15(from, { force: true });
32469
+ rmSync16(from, { force: true });
32145
32470
  continue;
32146
32471
  }
32147
- mkdirSync27(dirname23(to), { recursive: true });
32472
+ mkdirSync27(dirname24(to), { recursive: true });
32148
32473
  try {
32149
32474
  renameSync9(from, to);
32150
32475
  } catch {
@@ -32152,13 +32477,13 @@ function migrateToLayout42() {
32152
32477
  copyFileSync5(from, to);
32153
32478
  } catch (err) {
32154
32479
  try {
32155
- rmSync15(to, { force: true });
32480
+ rmSync16(to, { force: true });
32156
32481
  } catch {}
32157
32482
  throw err;
32158
32483
  }
32159
- rmSync15(from, { force: true });
32484
+ rmSync16(from, { force: true });
32160
32485
  }
32161
- migrated.push(`${basename7(from)} → audit/${basename7(to)}`);
32486
+ migrated.push(`${basename8(from)} → audit/${basename8(to)}`);
32162
32487
  }
32163
32488
  for (const secret of [auditSessionFile()]) {
32164
32489
  if (!existsSync43(secret))
@@ -32222,7 +32547,7 @@ function appendLedger2(entry) {
32222
32547
  } catch {}
32223
32548
  }
32224
32549
  function backupNameOf2(f) {
32225
- return f.as ?? basename7(f.at());
32550
+ return f.as ?? basename8(f.at());
32226
32551
  }
32227
32552
  function pruneMigratedCredentials2(from) {
32228
32553
  const pruned = [];
@@ -32234,7 +32559,7 @@ function pruneMigratedCredentials2(from) {
32234
32559
  const copy = resolve32(migrationBackupDir(layout), as);
32235
32560
  if (!existsSync43(copy))
32236
32561
  continue;
32237
- rmSync15(copy, { force: true });
32562
+ rmSync16(copy, { force: true });
32238
32563
  pruned.push(as);
32239
32564
  } catch {}
32240
32565
  }
@@ -32254,7 +32579,7 @@ function backupBeforeMigrating2(from) {
32254
32579
  const dir = migrationBackupDir(from);
32255
32580
  const saved = [];
32256
32581
  try {
32257
- rmSync15(dir, { recursive: true, force: true });
32582
+ rmSync16(dir, { recursive: true, force: true });
32258
32583
  mkdirSync27(dir, { recursive: true });
32259
32584
  } catch {
32260
32585
  return [];
@@ -32360,7 +32685,7 @@ function restoreBackup2(layout) {
32360
32685
  if (!existsSync43(source))
32361
32686
  continue;
32362
32687
  try {
32363
- mkdirSync27(dirname23(target), { recursive: true });
32688
+ mkdirSync27(dirname24(target), { recursive: true });
32364
32689
  copyFileSync5(source, target);
32365
32690
  restored.push(backupNameOf2(f));
32366
32691
  } catch {}
@@ -32411,7 +32736,7 @@ var init_migrations2 = __esm(() => {
32411
32736
  { at: legacy.auditSchedule }
32412
32737
  ];
32413
32738
  PRUNED_AFTER_SUCCESS2 = [
32414
- { as: basename7(legacy.authJson()), landsAt: auditSessionFile }
32739
+ { as: basename8(legacy.authJson()), landsAt: auditSessionFile }
32415
32740
  ];
32416
32741
  });
32417
32742
 
@@ -32450,15 +32775,15 @@ __export(exports_daemon_service, {
32450
32775
  import {
32451
32776
  existsSync as existsSync44,
32452
32777
  mkdirSync as mkdirSync28,
32453
- mkdtempSync as mkdtempSync2,
32778
+ mkdtempSync as mkdtempSync3,
32454
32779
  readFileSync as readFileSync37,
32455
32780
  writeFileSync as writeFileSync26,
32456
32781
  unlinkSync as unlinkSync5,
32457
- rmSync as rmSync16
32782
+ rmSync as rmSync17
32458
32783
  } from "node:fs";
32459
- import { homedir as homedir31, tmpdir as tmpdir3, userInfo as userInfo2 } from "node:os";
32784
+ import { homedir as homedir32, tmpdir as tmpdir4, userInfo as userInfo2 } from "node:os";
32460
32785
  import { resolve as resolve33 } from "node:path";
32461
- import { execFileSync as execFileSync6 } from "node:child_process";
32786
+ import { execFileSync as execFileSync4 } from "node:child_process";
32462
32787
  function setDaemonConfigured2(value, installedVersion) {
32463
32788
  try {
32464
32789
  updateConfig({ daemon: { configured: value } });
@@ -32570,7 +32895,7 @@ function systemdUnitPath2(user = serviceUser2()) {
32570
32895
  return resolve33(systemdUnitDir2(), systemdUnitName2(user));
32571
32896
  }
32572
32897
  function legacySystemdUserUnitPath2() {
32573
- return resolve33(homedir31(), ".config", "systemd", "user", "failproofaid.service");
32898
+ return resolve33(homedir32(), ".config", "systemd", "user", "failproofaid.service");
32574
32899
  }
32575
32900
  function launchdLabel2(user = serviceUser2()) {
32576
32901
  return `ai.failproof.failproofaid.${user}`;
@@ -32579,7 +32904,7 @@ function launchdPlistPath2(user = serviceUser2()) {
32579
32904
  return `/Library/LaunchDaemons/${launchdLabel2(user)}.plist`;
32580
32905
  }
32581
32906
  function legacyLaunchAgentPlistPath2() {
32582
- return resolve33(homedir31(), "Library", "LaunchAgents", "ai.failproof.failproofaid.plist");
32907
+ return resolve33(homedir32(), "Library", "LaunchAgents", "ai.failproof.failproofaid.plist");
32583
32908
  }
32584
32909
  function legacySharedLaunchDaemonPath2() {
32585
32910
  return "/Library/LaunchDaemons/ai.failproof.failproofaid.plist";
@@ -32605,7 +32930,7 @@ function primeElevation2() {
32605
32930
  if (canElevate2())
32606
32931
  return true;
32607
32932
  try {
32608
- execFileSync6("sudo", ["-v"], { stdio: "inherit", timeout: SUDO_PROMPT_TIMEOUT_MS2 });
32933
+ execFileSync4("sudo", ["-v"], { stdio: "inherit", timeout: SUDO_PROMPT_TIMEOUT_MS2 });
32609
32934
  return canElevate2();
32610
32935
  } catch {
32611
32936
  return false;
@@ -32615,7 +32940,7 @@ function canElevate2() {
32615
32940
  if (typeof process.getuid === "function" && process.getuid() === 0)
32616
32941
  return true;
32617
32942
  try {
32618
- execFileSync6("sudo", ["-n", "true"], { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS2 });
32943
+ execFileSync4("sudo", ["-n", "true"], { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS2 });
32619
32944
  return true;
32620
32945
  } catch {
32621
32946
  return false;
@@ -32624,16 +32949,16 @@ function canElevate2() {
32624
32949
  function runPrivileged2(command, args) {
32625
32950
  const root = typeof process.getuid === "function" && process.getuid() === 0;
32626
32951
  const [cmd, argv] = root ? [command, args] : ["sudo", ["-n", command, ...args]];
32627
- execFileSync6(cmd, argv, { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS2 });
32952
+ execFileSync4(cmd, argv, { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS2 });
32628
32953
  }
32629
32954
  function writePrivilegedFile2(destination, contents, mode = "0644") {
32630
- const stagingDir = mkdtempSync2(resolve33(tmpdir3(), "failproofaid-stage-"));
32955
+ const stagingDir = mkdtempSync3(resolve33(tmpdir4(), "failproofaid-stage-"));
32631
32956
  const staging = resolve33(stagingDir, "service-definition");
32632
32957
  try {
32633
32958
  writeFileSync26(staging, contents, "utf8");
32634
32959
  runPrivileged2("install", ["-m", mode, staging, destination]);
32635
32960
  } finally {
32636
- rmSync16(stagingDir, { recursive: true, force: true });
32961
+ rmSync17(stagingDir, { recursive: true, force: true });
32637
32962
  }
32638
32963
  }
32639
32964
  function removeLegacyUserService2() {
@@ -32643,14 +32968,14 @@ function removeLegacyUserService2() {
32643
32968
  if (!existsSync44(legacy3))
32644
32969
  return;
32645
32970
  try {
32646
- execFileSync6("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
32971
+ execFileSync4("systemctl", ["--user", "disable", "--now", "failproofaid.service"], {
32647
32972
  stdio: "ignore",
32648
32973
  timeout: SERVICE_CMD_TIMEOUT_MS2
32649
32974
  });
32650
32975
  } catch {}
32651
32976
  unlinkSync5(legacy3);
32652
32977
  try {
32653
- execFileSync6("systemctl", ["--user", "daemon-reload"], {
32978
+ execFileSync4("systemctl", ["--user", "daemon-reload"], {
32654
32979
  stdio: "ignore",
32655
32980
  timeout: SERVICE_CMD_TIMEOUT_MS2
32656
32981
  });
@@ -32659,7 +32984,7 @@ function removeLegacyUserService2() {
32659
32984
  const legacyAgent = legacyLaunchAgentPlistPath2();
32660
32985
  if (existsSync44(legacyAgent)) {
32661
32986
  try {
32662
- execFileSync6("launchctl", ["unload", "-w", legacyAgent], {
32987
+ execFileSync4("launchctl", ["unload", "-w", legacyAgent], {
32663
32988
  stdio: "ignore",
32664
32989
  timeout: SERVICE_CMD_TIMEOUT_MS2
32665
32990
  });
@@ -32683,7 +33008,7 @@ function systemdUnitContents2(binaryPath, workerCmd, cliCmd = null) {
32683
33008
  `).join("");
32684
33009
  const user = assertUnitSafe2(serviceUser2(), "User");
32685
33010
  assertUnitSafe2(binaryPath, "ExecStart");
32686
- assertUnitSafe2(homedir31(), "HOME");
33011
+ assertUnitSafe2(homedir32(), "HOME");
32687
33012
  const conditionPaths = [binaryPath, workerScriptPath2()].filter((p) => typeof p === "string" && existsSync44(p));
32688
33013
  const conditionLines = conditionPaths.map((p) => `ConditionPathExists=${assertUnitSafe2(p, "ConditionPathExists")}
32689
33014
  `).join("");
@@ -32697,7 +33022,7 @@ User=${user}
32697
33022
  # Set explicitly rather than relying on systemd deriving it from User=:
32698
33023
  # failproofaid stores per-user state and refuses to start without HOME, so this
32699
33024
  # required variable is not left to a version-dependent default.
32700
- Environment="HOME=${homedir31()}"
33025
+ Environment="HOME=${homedir32()}"
32701
33026
  ${envLines}ExecStart=${binaryPath}
32702
33027
  Restart=on-failure
32703
33028
  RestartSec=2
@@ -33077,7 +33402,7 @@ function daemonVersionSkew2() {
33077
33402
  }
33078
33403
  function inactiveLinuxStatus2() {
33079
33404
  try {
33080
- return interpretConditionResult2(execFileSync6("systemctl", ["show", systemdUnitName2(), "--property=ConditionResult", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS2 }).toString());
33405
+ return interpretConditionResult2(execFileSync4("systemctl", ["show", systemdUnitName2(), "--property=ConditionResult", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS2 }).toString());
33081
33406
  } catch {
33082
33407
  return "stopped";
33083
33408
  }
@@ -33092,7 +33417,7 @@ function daemonServiceStatus2() {
33092
33417
  if (!existsSync44(systemdUnitPath2()))
33093
33418
  return "not-installed";
33094
33419
  try {
33095
- const out = execFileSync6("systemctl", ["is-active", systemdUnitName2()], {
33420
+ const out = execFileSync4("systemctl", ["is-active", systemdUnitName2()], {
33096
33421
  stdio: ["ignore", "pipe", "ignore"],
33097
33422
  timeout: SERVICE_CMD_TIMEOUT_MS2
33098
33423
  }).toString().trim();
@@ -33109,10 +33434,10 @@ function daemonServiceStatus2() {
33109
33434
  if (!root && !canElevate2())
33110
33435
  return "unknown";
33111
33436
  const args = ["print", `system/${launchdLabel2()}`];
33112
- const out = root ? execFileSync6("launchctl", args, {
33437
+ const out = root ? execFileSync4("launchctl", args, {
33113
33438
  stdio: ["ignore", "pipe", "ignore"],
33114
33439
  timeout: SERVICE_CMD_TIMEOUT_MS2
33115
- }).toString() : execFileSync6("sudo", ["-n", "launchctl", ...args], {
33440
+ }).toString() : execFileSync4("sudo", ["-n", "launchctl", ...args], {
33116
33441
  stdio: ["ignore", "pipe", "ignore"],
33117
33442
  timeout: SERVICE_CMD_TIMEOUT_MS2
33118
33443
  }).toString();
@@ -33127,7 +33452,7 @@ function daemonStartedAtMs() {
33127
33452
  if (!existsSync44(systemdUnitPath2()))
33128
33453
  return null;
33129
33454
  try {
33130
- const raw = execFileSync6("systemctl", ["show", systemdUnitName2(), "-p", "ActiveEnterTimestampMonotonic", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS2 }).toString().trim();
33455
+ const raw = execFileSync4("systemctl", ["show", systemdUnitName2(), "-p", "ActiveEnterTimestampMonotonic", "--value"], { stdio: ["ignore", "pipe", "ignore"], timeout: SERVICE_CMD_TIMEOUT_MS2 }).toString().trim();
33131
33456
  return startedAtFromMonotonic(Number(raw), Math.floor(Number(process.hrtime.bigint()) / 1000), Date.now());
33132
33457
  } catch {
33133
33458
  return null;
@@ -33159,7 +33484,7 @@ __export(exports_uninstall_cli, {
33159
33484
  runUninstallCommand: () => runUninstallCommand,
33160
33485
  serviceStateLabel: () => serviceStateLabel
33161
33486
  });
33162
- import { existsSync as existsSync45, rmSync as rmSync17 } from "node:fs";
33487
+ import { existsSync as existsSync45, rmSync as rmSync18 } from "node:fs";
33163
33488
  function survey(cwd) {
33164
33489
  const clis = [];
33165
33490
  for (const id of listInstallableIds()) {
@@ -33292,7 +33617,7 @@ async function runUninstallCommand(opts = {}) {
33292
33617
  }
33293
33618
  if (opts.purge && found.homeExists) {
33294
33619
  try {
33295
- rmSync17(failproofaiHome(), { recursive: true, force: true });
33620
+ rmSync18(failproofaiHome(), { recursive: true, force: true });
33296
33621
  purged = true;
33297
33622
  lines.push(`✓ deleted ${failproofaiHome()}`);
33298
33623
  } catch (err) {
@@ -33364,8 +33689,8 @@ __export(exports_pack_store, {
33364
33689
  slugifyCategory: () => slugifyCategory2
33365
33690
  });
33366
33691
  import { createHash as createHash10 } from "node:crypto";
33367
- import { existsSync as existsSync46, mkdirSync as mkdirSync29, readFileSync as readFileSync38, renameSync as renameSync10, rmSync as rmSync18, writeFileSync as writeFileSync27 } from "node:fs";
33368
- import { dirname as dirname24, resolve as resolve34 } from "node:path";
33692
+ import { existsSync as existsSync46, mkdirSync as mkdirSync29, readFileSync as readFileSync38, renameSync as renameSync10, rmSync as rmSync19, writeFileSync as writeFileSync27 } from "node:fs";
33693
+ import { dirname as dirname25, resolve as resolve34 } from "node:path";
33369
33694
  function baseUrl3() {
33370
33695
  return (process.env.FAILPROOFAI_PACK_BASE_URL || DEFAULT_BASE_URL3).replace(/\/+$/, "");
33371
33696
  }
@@ -33485,11 +33810,11 @@ function sha2562(bytes) {
33485
33810
  function writeAtomic2(target, bytes) {
33486
33811
  const tempPath = `${target}.${process.pid}.tmp`;
33487
33812
  try {
33488
- mkdirSync29(dirname24(target), { recursive: true });
33813
+ mkdirSync29(dirname25(target), { recursive: true });
33489
33814
  writeFileSync27(tempPath, bytes);
33490
33815
  renameSync10(tempPath, target);
33491
33816
  } catch (err) {
33492
- rmSync18(tempPath, { force: true });
33817
+ rmSync19(tempPath, { force: true });
33493
33818
  throw err;
33494
33819
  }
33495
33820
  }
@@ -34226,12 +34551,13 @@ __export(exports_manager, {
34226
34551
  getSettingsPath: () => getSettingsPath2,
34227
34552
  hooksInstalledInSettings: () => hooksInstalledInSettings2,
34228
34553
  installHooks: () => installHooks2,
34554
+ integrationsInstalledAt: () => integrationsInstalledAt2,
34229
34555
  listHooks: () => listHooks,
34230
34556
  removeHooks: () => removeHooks2
34231
34557
  });
34232
34558
  import { execSync as execSync7 } from "node:child_process";
34233
34559
  import { existsSync as existsSync47 } from "node:fs";
34234
- import { resolve as resolve35, basename as basename8 } from "node:path";
34560
+ import { resolve as resolve35, basename as basename9 } from "node:path";
34235
34561
  import { platform as platform5, arch as arch4, release as release3, hostname as hostname6 } from "node:os";
34236
34562
  function getSettingsPath2(scope, cwd) {
34237
34563
  return claudeCode.getSettingsPath(scope, cwd);
@@ -34356,14 +34682,30 @@ function deduplicateScopes2(scopes, cwd) {
34356
34682
  });
34357
34683
  }
34358
34684
  function hooksInstalledInSettings2(scope, cwd) {
34359
- return INTEGRATION_TYPES.some((id) => {
34685
+ return integrationsInstalledAt2(scope, cwd).length > 0;
34686
+ }
34687
+ function integrationsInstalledAt2(scope, cwd) {
34688
+ return INTEGRATION_TYPES.filter((id) => {
34360
34689
  try {
34361
- return getIntegration(id).hooksInstalledInSettings(scope, cwd);
34690
+ const integration = getIntegration(id);
34691
+ if (!integration.scopes.includes(scope))
34692
+ return false;
34693
+ if (!integration.hooksInstalledInSettings(scope, cwd))
34694
+ return false;
34695
+ const here = integration.getSettingsPath(scope, cwd);
34696
+ return !HOOK_SCOPES.some((other) => other !== scope && HOOK_SCOPES.indexOf(other) < HOOK_SCOPES.indexOf(scope) && integration.scopes.includes(other) && safeSettingsPath2(integration, other, cwd) === here);
34362
34697
  } catch {
34363
34698
  return false;
34364
34699
  }
34365
34700
  });
34366
34701
  }
34702
+ function safeSettingsPath2(integration, scope, cwd) {
34703
+ try {
34704
+ return integration.getSettingsPath(scope, cwd);
34705
+ } catch {
34706
+ return null;
34707
+ }
34708
+ }
34367
34709
  async function installHooks2(policyNames, scope = "user", cwd, includeBeta = false, source, customPoliciesPath, removeCustomHooks = false, cli, options = {}) {
34368
34710
  const { replace = false, quiet = false } = options;
34369
34711
  if (!quiet) {
@@ -34829,7 +35171,7 @@ async function listHooks(cwd) {
34829
35171
  groups.push(note2(dir, opts));
34830
35172
  const rows3 = [];
34831
35173
  for (const file of files) {
34832
- const filename = basename8(file);
35174
+ const filename = basename9(file);
34833
35175
  try {
34834
35176
  const hooks = await loadCustomHooks(file);
34835
35177
  record(filename, hooks.map((h) => h.name));
@@ -35680,7 +36022,7 @@ __export(exports_launch2, {
35680
36022
  });
35681
36023
  import { spawn as spawn3 } from "child_process";
35682
36024
  import { realpathSync as realpathSync5, existsSync as existsSync48 } from "node:fs";
35683
- import { resolve as resolve36, dirname as dirname25 } from "node:path";
36025
+ import { resolve as resolve36, dirname as dirname26 } from "node:path";
35684
36026
  import { fileURLToPath as fileURLToPath3 } from "node:url";
35685
36027
  import { createInterface as createInterface2 } from "node:readline";
35686
36028
  function launch2(mode) {
@@ -35704,7 +36046,7 @@ function launch2(mode) {
35704
36046
  process.env.PORT = port;
35705
36047
  process.env.HOSTNAME = bindHost;
35706
36048
  cmd = "node";
35707
- const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve36(dirname25(realpathSync5(fileURLToPath3(import.meta.url))), "..");
36049
+ const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve36(dirname26(realpathSync5(fileURLToPath3(import.meta.url))), "..");
35708
36050
  const serverJsPath = resolve36(packageRoot, ".next/standalone/server.js");
35709
36051
  if (!existsSync48(serverJsPath)) {
35710
36052
  let shadowMessage = null;
@@ -35803,17 +36145,17 @@ var init_cli_error2 = __esm(() => {
35803
36145
 
35804
36146
  // bin/failproofai.mjs
35805
36147
  import { realpathSync as realpathSync6 } from "fs";
35806
- import { dirname as dirname26, resolve as resolve37 } from "path";
36148
+ import { dirname as dirname27, resolve as resolve37 } from "path";
35807
36149
  import { fileURLToPath as fileURLToPath4 } from "url";
35808
36150
  // package.json
35809
- var version = "1.0.2-beta.4";
36151
+ var version = "1.0.2-beta.5";
35810
36152
 
35811
36153
  // bin/failproofai.mjs
35812
36154
  if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
35813
- process.env.FAILPROOFAI_PACKAGE_ROOT = resolve37(dirname26(realpathSync6(fileURLToPath4(import.meta.url))), "..");
36155
+ process.env.FAILPROOFAI_PACKAGE_ROOT = resolve37(dirname27(realpathSync6(fileURLToPath4(import.meta.url))), "..");
35814
36156
  }
35815
36157
  if (!process.env.FAILPROOFAI_DIST_PATH) {
35816
- process.env.FAILPROOFAI_DIST_PATH = resolve37(dirname26(realpathSync6(fileURLToPath4(import.meta.url))), "..", "dist");
36158
+ process.env.FAILPROOFAI_DIST_PATH = resolve37(dirname27(realpathSync6(fileURLToPath4(import.meta.url))), "..", "dist");
35817
36159
  }
35818
36160
  var args = process.argv.slice(2);
35819
36161
  if (args[0] === "p" || args[0] === "policy")
@@ -36621,7 +36963,7 @@ Run \`failproofai uninstall --help\` for usage.`);
36621
36963
  }
36622
36964
  if (args[0] === "publish") {
36623
36965
  const subArgs = args.slice(1);
36624
- if (subArgs.includes("--help") || subArgs.includes("-h") || subArgs.length === 0) {
36966
+ if (subArgs.includes("--help") || subArgs.includes("-h")) {
36625
36967
  console.log(`
36626
36968
  failproofai publish \u2014 ship your policies as a pack anyone can install
36627
36969
 
@@ -36630,8 +36972,13 @@ TWO COMMANDS, FROM NOTHING
36630
36972
  failproofai publish --init write a policy to start from
36631
36973
  failproofai publish ship it
36632
36974
 
36633
- Everything else is optional. Every flag below overrides something that is
36634
- otherwise worked out for you.
36975
+ Write your policies in a git repo, run publish, answer one question, done.
36976
+ It asks WHERE only when nothing tells it \u2014 no remote to read \u2014 and works
36977
+ the rest out: which files hold policies, what version is next, who you are.
36978
+
36979
+ Every flag below overrides something it would otherwise decide for you.
36980
+ None of them is required, and on a pipe or in CI the flags are all there
36981
+ is: nothing prompts where nobody can answer.
36635
36982
 
36636
36983
  WHAT --init DOES
36637
36984
  Asks what the pack is called, writes <name>.mjs, and stops. No network, no
@@ -36690,11 +37037,16 @@ THE REPO MUST BE PUBLIC
36690
37037
  Only the release matters. Installs read releases/download/<tag>/<asset> and
36691
37038
  never touch your git tree \u2014 pushing the source is for humans reading it.
36692
37039
 
36693
- YOUR ENTRY FILE
36694
- One file, no relative imports: only the entry is digest-pinned, so a pack
36695
- importing siblings could not honestly claim to be verified. Bundle first
36696
- (esbuild, bun build, rollup) if yours is split. Each policy may carry
36697
- category and defaultEnabled alongside the usual fields.
37040
+ YOUR POLICY FILES
37041
+ Write as many as you like \u2014 one per category reads well. Every file here
37042
+ that registers policies is found and bundled into the single artifact a
37043
+ pack has to be, because only the entry is digest-pinned and a pack
37044
+ importing siblings could not honestly claim to be verified. Bundling needs
37045
+ bun; without it, name one self-contained file.
37046
+
37047
+ Each policy may carry category and defaultEnabled alongside the usual
37048
+ fields. category is what --category selects on; defaultEnabled is what a
37049
+ bare 'policies add' switches on, and it defaults to false.
36698
37050
 
36699
37051
  OPTIONS
36700
37052
  --init [file] Write a starter policy and stop.
@@ -36741,7 +37093,7 @@ USAGE
36741
37093
  failproofai policies add Pick from what is installed here
36742
37094
  failproofai policies add <name> Turn one policy on
36743
37095
  failproofai policies add <owner>/<repo> Install someone's pack
36744
- failproofai policies add core Our pack, from this package, offline
37096
+ failproofai policies add core Our pack, fetched like any other
36745
37097
  failproofai policies remove <name> Turn one policy off
36746
37098
  failproofai policies remove <pack-id> Uninstall a pack
36747
37099
  failproofai policies show <owner>/<repo> What a pack contains, before you take it