failproofai 1.0.5-beta.1 → 1.0.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 (135) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +6 -6
  3. package/.next/standalone/.next/prerender-manifest.json +4 -4
  4. package/.next/standalone/.next/required-server-files.json +1 -1
  5. package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
  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 +3 -3
  15. package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  16. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  19. package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
  20. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
  21. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
  22. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
  32. package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
  33. package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/.next/server/app/index.html +1 -1
  36. package/.next/standalone/.next/server/app/index.rsc +14 -14
  37. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
  38. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
  39. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
  41. package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
  42. package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
  45. package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
  46. package/.next/standalone/.next/server/app/policies/page.js +1 -1
  47. package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
  49. package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
  50. package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
  51. package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
  53. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
  54. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
  55. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
  56. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
  59. package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
  60. package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
  61. package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/settings/page/build-manifest.json +3 -3
  63. package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
  64. package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
  65. package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/_09dz7xv._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
  70. package/.next/standalone/.next/server/chunks/_1vslkoe._.js +1 -1
  71. package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
  72. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00y9ww2._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
  74. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
  75. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
  76. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0n_lxhg._.js → [root-of-the-server]__0bym1os._.js} +1 -1
  77. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
  78. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
  79. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
  80. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
  81. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
  82. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0sz_5na._.js +1 -1
  83. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__05g1k7_._.js → [root-of-the-server]__15k-dqb._.js} +2 -2
  84. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +1 -1
  85. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
  86. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u6sn69._.js +1 -1
  87. package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
  88. package/.next/standalone/.next/server/chunks/ssr/{_17noq1a._.js → _0guaevg._.js} +2 -2
  89. package/.next/standalone/.next/server/chunks/ssr/_1_ozgif._.js +1 -1
  90. package/.next/standalone/.next/server/chunks/ssr/{_0iv28v5._.js → _1b78kcp._.js} +1 -1
  91. package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +2 -2
  92. package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
  93. package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
  94. package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
  95. package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
  96. package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
  97. package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
  98. package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
  99. package/.next/standalone/.next/server/chunks/ssr/lib_codex-projects_ts_0pqlw37._.js +1 -1
  100. package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
  101. package/.next/standalone/.next/server/pages/404.html +1 -1
  102. package/.next/standalone/.next/server/pages/500.html +1 -1
  103. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  104. package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
  105. package/.next/standalone/.next/static/chunks/{0qytob94jbzs6.js → 021ydrq6rhpsi.js} +1 -1
  106. package/.next/standalone/.next/static/chunks/{26tf_lpco5n-v.js → 0y8_1s45gbqmn.js} +1 -1
  107. package/.next/standalone/.next/static/chunks/{2b014kj28p0vz.js → 11s_v03ub6nss.js} +1 -1
  108. package/.next/standalone/.next/static/chunks/14b3ezufe5411.js +1 -0
  109. package/.next/standalone/.next/static/chunks/{3kltzmx9k_t6x.js → 1c6aptmytnu6q.js} +1 -1
  110. package/.next/standalone/.next/static/chunks/{3vjaz4hld9oo8.js → 1oskk7pdo8aon.js} +1 -1
  111. package/.next/standalone/.next/static/chunks/{074xcclgow3yh.js → 1vb33xa6j9y2q.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/{3pmi7qhtmniku.js → 252xreaecy80h.js} +1 -1
  113. package/.next/standalone/.next/static/chunks/{3_fnbc-v5r-9e.js → 2xycd6mjg00fb.js} +1 -1
  114. package/.next/standalone/.next/static/chunks/{41ejnuj2d9g7_.js → 2zafgs90r_leq.js} +1 -1
  115. package/.next/standalone/.next/static/chunks/{3q1rji38vuvr4.js → 3bleyy40s99f2.js} +1 -1
  116. package/.next/standalone/.next/static/chunks/{3qxl_gibq3bas.js → 3w46euc60dx39.js} +1 -1
  117. package/.next/standalone/.next/static/chunks/{turbopack-1xgsp63yhrdu5.js → turbopack-3p73obe0xmrxm.js} +1 -1
  118. package/.next/standalone/lib/openclaw-profiles.ts +78 -0
  119. package/.next/standalone/lib/openclaw-projects.ts +3 -3
  120. package/.next/standalone/lib/sqlite-reader.ts +165 -9
  121. package/.next/standalone/package.json +9 -9
  122. package/.next/standalone/server.js +1 -1
  123. package/dist/cli.mjs +845 -684
  124. package/dist/worker.mjs +129 -17
  125. package/lib/openclaw-profiles.ts +78 -0
  126. package/lib/openclaw-projects.ts +3 -3
  127. package/lib/sqlite-reader.ts +165 -9
  128. package/openclaw-plugin/index.js +13 -7
  129. package/openclaw-plugin/workspace-context.js +93 -0
  130. package/package.json +9 -9
  131. package/src/hooks/integrations.ts +22 -14
  132. package/.next/standalone/.next/static/chunks/25cn9xpv4r1ow.js +0 -1
  133. /package/.next/standalone/.next/static/{Qexks15mjEoPt6cN3D2jb → uFpAs_vIXSo6qBzmkXPWD}/_buildManifest.js +0 -0
  134. /package/.next/standalone/.next/static/{Qexks15mjEoPt6cN3D2jb → uFpAs_vIXSo6qBzmkXPWD}/_clientMiddlewareManifest.js +0 -0
  135. /package/.next/standalone/.next/static/{Qexks15mjEoPt6cN3D2jb → uFpAs_vIXSo6qBzmkXPWD}/_ssgManifest.js +0 -0
package/dist/worker.mjs CHANGED
@@ -3483,7 +3483,7 @@ function parsePackPolicyName(canonicalName) {
3483
3483
  }
3484
3484
 
3485
3485
  // package.json
3486
- var version = "1.0.5-beta.1";
3486
+ var version = "1.0.5";
3487
3487
  var init_package = () => {};
3488
3488
 
3489
3489
  // src/posthog-key.ts
@@ -5890,7 +5890,7 @@ var init_cursor_projects = __esm(() => {
5890
5890
  });
5891
5891
 
5892
5892
  // lib/sqlite-reader.ts
5893
- import { existsSync as existsSync8, readFileSync as readFileSync6 } from "node:fs";
5893
+ import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync6 } from "node:fs";
5894
5894
  import initSqlJs from "sql.js/dist/sql-asm.js";
5895
5895
  async function tryNodeSqlite(dbPath) {
5896
5896
  try {
@@ -5914,10 +5914,117 @@ function loadSqlJs() {
5914
5914
  sqlPromise = initSqlJs();
5915
5915
  return sqlPromise;
5916
5916
  }
5917
+ function fileVersion(path) {
5918
+ const stat = statSync6(path);
5919
+ return { size: stat.size, mtimeMs: stat.mtimeMs, ctimeMs: stat.ctimeMs };
5920
+ }
5921
+ function sameVersion(a, b) {
5922
+ return a.size === b.size && a.mtimeMs === b.mtimeMs && a.ctimeMs === b.ctimeMs;
5923
+ }
5924
+ function sqlitePageSize(db) {
5925
+ if (db.length < 100)
5926
+ return null;
5927
+ if (Buffer.from(db.subarray(0, 16)).toString("binary") !== "SQLite format 3\x00")
5928
+ return null;
5929
+ const encoded = db[16] << 8 | db[17];
5930
+ const pageSize = encoded === 1 ? 65536 : encoded;
5931
+ return pageSize >= 512 && pageSize <= 65536 && (pageSize & pageSize - 1) === 0 ? pageSize : null;
5932
+ }
5933
+ function walChecksum(bytes, offset, length, bigEndian, initial = [0, 0]) {
5934
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
5935
+ let [sum1, sum2] = initial;
5936
+ for (let cursor = offset;cursor < offset + length; cursor += 8) {
5937
+ const first = view.getUint32(cursor, !bigEndian);
5938
+ const second = view.getUint32(cursor + 4, !bigEndian);
5939
+ sum1 = sum1 + first + sum2 >>> 0;
5940
+ sum2 = sum2 + second + sum1 >>> 0;
5941
+ }
5942
+ return [sum1, sum2];
5943
+ }
5944
+ function applyCommittedWal(db, wal) {
5945
+ const pageSize = sqlitePageSize(db);
5946
+ if (pageSize === null || wal.length < 32)
5947
+ return db;
5948
+ const view = new DataView(wal.buffer, wal.byteOffset, wal.byteLength);
5949
+ const magic = view.getUint32(0, false);
5950
+ if (magic !== 931071618 && magic !== 931071619)
5951
+ return db;
5952
+ if (view.getUint32(4, false) !== 3007000)
5953
+ return db;
5954
+ if (view.getUint32(8, false) !== pageSize)
5955
+ return db;
5956
+ const checksumBigEndian = (magic & 1) === 1;
5957
+ let checksum = walChecksum(wal, 0, 24, checksumBigEndian);
5958
+ if (view.getUint32(24, false) !== checksum[0] || view.getUint32(28, false) !== checksum[1]) {
5959
+ return db;
5960
+ }
5961
+ const salt1 = view.getUint32(16, false);
5962
+ const salt2 = view.getUint32(20, false);
5963
+ const frameSize = 24 + pageSize;
5964
+ const frameCount = Math.floor((wal.length - 32) / frameSize);
5965
+ let lastCommit = -1;
5966
+ let committedPages = 0;
5967
+ for (let index = 0;index < frameCount; index += 1) {
5968
+ const offset = 32 + index * frameSize;
5969
+ const pageNumber = view.getUint32(offset, false);
5970
+ if (pageNumber === 0 || view.getUint32(offset + 8, false) !== salt1 || view.getUint32(offset + 12, false) !== salt2) {
5971
+ break;
5972
+ }
5973
+ checksum = walChecksum(wal, offset, 8, checksumBigEndian, checksum);
5974
+ checksum = walChecksum(wal, offset + 24, pageSize, checksumBigEndian, checksum);
5975
+ if (view.getUint32(offset + 16, false) !== checksum[0] || view.getUint32(offset + 20, false) !== checksum[1]) {
5976
+ break;
5977
+ }
5978
+ const databasePages = view.getUint32(offset + 4, false);
5979
+ if (databasePages > 0) {
5980
+ lastCommit = index;
5981
+ committedPages = databasePages;
5982
+ }
5983
+ }
5984
+ if (lastCommit < 0 || committedPages === 0)
5985
+ return db;
5986
+ const targetSize = committedPages * pageSize;
5987
+ if (!Number.isSafeInteger(targetSize) || targetSize > db.length + frameCount * pageSize) {
5988
+ return db;
5989
+ }
5990
+ const snapshot = new Uint8Array(targetSize);
5991
+ snapshot.set(db.subarray(0, targetSize));
5992
+ for (let index = 0;index <= lastCommit; index += 1) {
5993
+ const offset = 32 + index * frameSize;
5994
+ const pageNumber = view.getUint32(offset, false);
5995
+ const destination = (pageNumber - 1) * pageSize;
5996
+ if (destination >= targetSize)
5997
+ continue;
5998
+ snapshot.set(wal.subarray(offset + 24, offset + frameSize), destination);
5999
+ }
6000
+ return snapshot;
6001
+ }
6002
+ function readPortableSnapshot(dbPath) {
6003
+ const walPath = `${dbPath}-wal`;
6004
+ for (let attempt = 0;attempt < 3; attempt += 1) {
6005
+ const before = fileVersion(dbPath);
6006
+ const main = readFileSync6(dbPath);
6007
+ const afterMain = fileVersion(dbPath);
6008
+ if (!sameVersion(before, afterMain))
6009
+ continue;
6010
+ let wal = null;
6011
+ try {
6012
+ wal = readFileSync6(walPath);
6013
+ } catch (error) {
6014
+ if (error.code !== "ENOENT")
6015
+ throw error;
6016
+ }
6017
+ const afterWal = fileVersion(dbPath);
6018
+ if (!sameVersion(before, afterWal))
6019
+ continue;
6020
+ return wal ? applyCommittedWal(main, wal) : main;
6021
+ }
6022
+ throw new Error(`SQLite database changed while reading: ${dbPath}`);
6023
+ }
5917
6024
  async function trySqlJs(dbPath) {
5918
6025
  try {
5919
6026
  const SQL = await loadSqlJs();
5920
- const db = new SQL.Database(readFileSync6(dbPath));
6027
+ const db = new SQL.Database(readPortableSnapshot(dbPath));
5921
6028
  return {
5922
6029
  query(sql, params) {
5923
6030
  const stmt = db.prepare(sql);
@@ -5940,10 +6047,15 @@ async function trySqlJs(dbPath) {
5940
6047
  return null;
5941
6048
  }
5942
6049
  }
5943
- async function openSqliteReadonly(dbPath) {
6050
+ async function openSqliteReadonly(dbPath, options = {}) {
5944
6051
  if (!existsSync8(dbPath))
5945
6052
  return null;
5946
- return await tryNodeSqlite(dbPath) ?? await trySqlJs(dbPath);
6053
+ if (!options.forcePortable) {
6054
+ const native = await tryNodeSqlite(dbPath);
6055
+ if (native)
6056
+ return native;
6057
+ }
6058
+ return trySqlJs(dbPath);
5947
6059
  }
5948
6060
  var sqlPromise = null;
5949
6061
  var init_sqlite_reader = () => {};
@@ -6810,7 +6922,7 @@ var init_openclaw_db = __esm(() => {
6810
6922
 
6811
6923
  // lib/openclaw-sessions.ts
6812
6924
  import { readFile as readFile7 } from "node:fs/promises";
6813
- import { readdirSync as readdirSync4, statSync as statSync6 } from "node:fs";
6925
+ import { readdirSync as readdirSync4, statSync as statSync7 } from "node:fs";
6814
6926
  import { homedir as homedir11 } from "node:os";
6815
6927
  import { join as join14 } from "node:path";
6816
6928
  function openclawHome() {
@@ -6963,7 +7075,7 @@ function listOpenClawTranscripts() {
6963
7075
  continue;
6964
7076
  const transcriptPath = join14(sessionsDir, file);
6965
7077
  try {
6966
- const st = statSync6(transcriptPath);
7078
+ const st = statSync7(transcriptPath);
6967
7079
  out.push({
6968
7080
  agentId,
6969
7081
  sessionId,
@@ -7206,7 +7318,7 @@ var init_openclaw_projects = __esm(() => {
7206
7318
 
7207
7319
  // lib/factory-sessions.ts
7208
7320
  import { readFile as readFile8 } from "node:fs/promises";
7209
- import { readdirSync as readdirSync5, statSync as statSync7 } from "node:fs";
7321
+ import { readdirSync as readdirSync5, statSync as statSync8 } from "node:fs";
7210
7322
  import { homedir as homedir12 } from "node:os";
7211
7323
  import { join as join16 } from "node:path";
7212
7324
  function factoryHome() {
@@ -7374,7 +7486,7 @@ function listFactoryTranscripts() {
7374
7486
  continue;
7375
7487
  const transcriptPath = join16(projectPath, file);
7376
7488
  try {
7377
- const st = statSync7(transcriptPath);
7489
+ const st = statSync8(transcriptPath);
7378
7490
  out.push({ projectName, cwd, sessionId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
7379
7491
  } catch {}
7380
7492
  }
@@ -7793,7 +7905,7 @@ var init_devin_projects = __esm(() => {
7793
7905
 
7794
7906
  // lib/antigravity-sessions.ts
7795
7907
  import { readFile as readFile9 } from "node:fs/promises";
7796
- import { readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
7908
+ import { readdirSync as readdirSync6, statSync as statSync9 } from "node:fs";
7797
7909
  import { homedir as homedir14 } from "node:os";
7798
7910
  import { join as join18 } from "node:path";
7799
7911
  function antigravityHome() {
@@ -7928,7 +8040,7 @@ function listAntigravityTranscripts() {
7928
8040
  continue;
7929
8041
  const transcriptPath = join18(root, conversationId, rel);
7930
8042
  try {
7931
- const st = statSync8(transcriptPath);
8043
+ const st = statSync9(transcriptPath);
7932
8044
  if (!st.isFile())
7933
8045
  continue;
7934
8046
  out.push({ conversationId, transcriptPath, mtimeMs: st.mtimeMs, sizeBytes: st.size });
@@ -7941,7 +8053,7 @@ function findAntigravityTranscript(conversationId) {
7941
8053
  return null;
7942
8054
  const transcriptPath = join18(antigravityBrainRoot(), conversationId, antigravityTranscriptRelPath());
7943
8055
  try {
7944
- if (statSync8(transcriptPath).isFile())
8056
+ if (statSync9(transcriptPath).isFile())
7945
8057
  return transcriptPath;
7946
8058
  } catch {}
7947
8059
  return null;
@@ -8850,7 +8962,7 @@ var init_log_entries = __esm(() => {
8850
8962
  });
8851
8963
 
8852
8964
  // lib/codex-sessions.ts
8853
- import { readFileSync as readFileSync8, readdirSync as readdirSync7, existsSync as existsSync10, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, statSync as statSync9 } from "node:fs";
8965
+ import { readFileSync as readFileSync8, readdirSync as readdirSync7, existsSync as existsSync10, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, statSync as statSync10 } from "node:fs";
8854
8966
  import { readFile as readFile11 } from "node:fs/promises";
8855
8967
  import { dirname as dirname4, join as join24 } from "node:path";
8856
8968
  import { homedir as homedir16 } from "node:os";
@@ -9178,7 +9290,7 @@ var init_resolve_permission_mode = __esm(() => {
9178
9290
  });
9179
9291
 
9180
9292
  // lib/copilot-sessions.ts
9181
- import { readFileSync as readFileSync10, readdirSync as readdirSync8, existsSync as existsSync11, statSync as statSync10 } from "node:fs";
9293
+ import { readFileSync as readFileSync10, readdirSync as readdirSync8, existsSync as existsSync11, statSync as statSync11 } from "node:fs";
9182
9294
  import { readFile as readFile12 } from "node:fs/promises";
9183
9295
  import { join as join25, resolve as resolve10, sep as sep2 } from "node:path";
9184
9296
  import { homedir as homedir17 } from "node:os";
@@ -9395,7 +9507,7 @@ var init_copilot_sessions = __esm(() => {
9395
9507
  });
9396
9508
 
9397
9509
  // lib/cursor-sessions.ts
9398
- import { readFileSync as readFileSync11, readdirSync as readdirSync9, existsSync as existsSync12, statSync as statSync11 } from "node:fs";
9510
+ import { readFileSync as readFileSync11, readdirSync as readdirSync9, existsSync as existsSync12, statSync as statSync12 } from "node:fs";
9399
9511
  import { readFile as readFile13 } from "node:fs/promises";
9400
9512
  import { basename as basename3, join as join26, resolve as resolve11, sep as sep3 } from "node:path";
9401
9513
  import { homedir as homedir18 } from "node:os";
@@ -9651,7 +9763,7 @@ var init_cursor_sessions = __esm(() => {
9651
9763
  });
9652
9764
 
9653
9765
  // lib/pi-sessions.ts
9654
- import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync13, statSync as statSync12 } from "node:fs";
9766
+ import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync13, statSync as statSync13 } from "node:fs";
9655
9767
  import { readFile as readFile14 } from "node:fs/promises";
9656
9768
  import { join as join27, resolve as resolve12, sep as sep4 } from "node:path";
9657
9769
  import { homedir as homedir19 } from "node:os";
@@ -10136,7 +10248,7 @@ import {
10136
10248
  renameSync as renameSync3,
10137
10249
  rmSync as rmSync3,
10138
10250
  rmdirSync,
10139
- statSync as statSync13,
10251
+ statSync as statSync14,
10140
10252
  writeFileSync as writeFileSync5
10141
10253
  } from "node:fs";
10142
10254
  function layoutWarningForHook() {
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Lightweight OpenClaw profile discovery shared by hook installation code.
3
+ *
4
+ * The default profile lives at `~/.openclaw`; named profiles selected with
5
+ * `openclaw --profile <name>` live in sibling directories named
6
+ * `~/.openclaw-<name>`. Each profile owns an independent `openclaw.json`, so
7
+ * policy enforcement must be installed into every one of them.
8
+ */
9
+ import { existsSync, readdirSync } from "node:fs";
10
+ import { homedir } from "node:os";
11
+ import { basename, dirname, join, resolve } from "node:path";
12
+
13
+ export interface OpenClawProfile {
14
+ name: string;
15
+ home: string;
16
+ }
17
+
18
+ export const OPENCLAW_DEFAULT_PROFILE = "default";
19
+
20
+ /** Active/default OpenClaw state home, respecting OpenClaw's own overrides. */
21
+ export function openclawProfileHome(): string {
22
+ const stateDir = (process.env.OPENCLAW_STATE_DIR ?? "").trim();
23
+ if (stateDir) return resolve(stateDir);
24
+
25
+ const openclawHome = (process.env.OPENCLAW_HOME ?? "").trim();
26
+ if (openclawHome) return resolve(openclawHome);
27
+
28
+ const configPath = (process.env.OPENCLAW_CONFIG_PATH || "").trim();
29
+ if (configPath) return dirname(resolve(configPath));
30
+
31
+ return join(homedir(), ".openclaw");
32
+ }
33
+
34
+ /**
35
+ * Every standard OpenClaw profile on disk, default first and named profiles in
36
+ * lexical order. A named directory counts as a profile only when it contains
37
+ * `openclaw.json`; this avoids modifying backup or unrelated `.openclaw-*`
38
+ * directories.
39
+ */
40
+ export function listOpenClawProfiles(): OpenClawProfile[] {
41
+ const activeHome = openclawProfileHome();
42
+ const activeBase = basename(activeHome);
43
+
44
+ // Non-standard OPENCLAW_STATE_DIR locations do not have a well-defined
45
+ // sibling-profile convention. Keep the explicit location authoritative.
46
+ if (activeBase !== ".openclaw" && !activeBase.startsWith(".openclaw-")) {
47
+ return [{ name: OPENCLAW_DEFAULT_PROFILE, home: activeHome }];
48
+ }
49
+
50
+ const parent = dirname(activeHome);
51
+ const defaultHome = join(parent, ".openclaw");
52
+ const out: OpenClawProfile[] = [
53
+ { name: OPENCLAW_DEFAULT_PROFILE, home: defaultHome },
54
+ ];
55
+
56
+ let entries;
57
+ try {
58
+ entries = readdirSync(parent, { withFileTypes: true });
59
+ } catch {
60
+ return out;
61
+ }
62
+
63
+ const named = entries
64
+ .filter((entry) =>
65
+ (entry.isDirectory() || entry.isSymbolicLink()) &&
66
+ entry.name.startsWith(".openclaw-") &&
67
+ entry.name.length > ".openclaw-".length &&
68
+ existsSync(join(parent, entry.name, "openclaw.json")),
69
+ )
70
+ .map((entry) => ({
71
+ name: entry.name.slice(".openclaw-".length),
72
+ home: join(parent, entry.name),
73
+ }))
74
+ .sort((a, b) => a.name.localeCompare(b.name));
75
+
76
+ out.push(...named);
77
+ return out;
78
+ }
@@ -23,9 +23,9 @@ export interface OpenClawSessionRef {
23
23
  /** Channel/source the session last ran in (from sessions.json metadata) —
24
24
  * e.g. "telegram", "slack", or "local" for a CLI session. Drives grouping. */
25
25
  channel: string;
26
- /** Human-readable label from `origin.label` (e.g. "Chetan (@chhhee10) id:…"). */
26
+ /** Human-readable label from `origin.label` (e.g. "Example User (@example) id:…"). */
27
27
  label?: string;
28
- /** Chat id (e.g. "telegram:8674922496") + type ("direct"/"group") for the
28
+ /** Chat id (e.g. "telegram:1234567890") + type ("direct"/"group") for the
29
29
  * gateway-metadata columns. */
30
30
  chatId?: string;
31
31
  chatType?: string;
@@ -248,7 +248,7 @@ export interface OpenClawProjectByName {
248
248
 
249
249
  /** Resolve the OpenClaw sessions for a synthetic project name
250
250
  * (`openclaw-<agentId>-<channel>`), for the project-detail page. Session names
251
- * use the human-readable `origin.label` (e.g. "Chetan (@chhhee10) id:…")
251
+ * use the human-readable `origin.label` (e.g. "Example User (@example) id:…")
252
252
  * rather than the raw session key. */
253
253
  export async function getOpenClawSessionsByEncodedName(
254
254
  name: string,
@@ -6,10 +6,10 @@
6
6
  * 1. `node:sqlite` — a real connection that reads main DB + WAL together, so
7
7
  * brand-new rows are visible immediately. Built into Node ≥ 22.5 (no native
8
8
  * module, no flag on recent 22.x). Preferred.
9
- * 2. `sql.js` (pure-JS/asm) — portable fallback for older Node. Reads the main
10
- * DB file's bytes only, so it reflects a snapshot up to the last WAL
11
- * checkpoint (very recent rows may lag). No native module — survives
12
- * `npm install --ignore-scripts`.
9
+ * 2. `sql.js` (pure-JS/asm) — portable fallback for older Node. Builds a
10
+ * consistent in-memory snapshot from the main DB plus committed WAL
11
+ * frames, so live rows are visible on Node 20 too. No native module —
12
+ * survives `npm install --ignore-scripts`.
13
13
  *
14
14
  * Either way: read-only, and `null` on any failure (fail-open, so an absent or
15
15
  * locked DB makes the audit skip that agent rather than crash).
@@ -17,7 +17,7 @@
17
17
  * NOTE: opencode and every CLI that already ships keep their existing CLI
18
18
  * shell-out — this layer is only for new SQLite integrations.
19
19
  */
20
- import { existsSync, readFileSync } from "node:fs";
20
+ import { existsSync, readFileSync, statSync } from "node:fs";
21
21
  import initSqlJs, { type SqlJsStatic } from "sql.js/dist/sql-asm.js";
22
22
 
23
23
  export interface SqliteReader {
@@ -26,6 +26,11 @@ export interface SqliteReader {
26
26
  close(): void;
27
27
  }
28
28
 
29
+ export interface SqliteReaderOptions {
30
+ /** Exercise the Node-20-compatible reader even when `node:sqlite` exists. */
31
+ forcePortable?: boolean;
32
+ }
33
+
29
34
  // ── Tier 1: node:sqlite (WAL-aware, Node ≥ 22.5) ──
30
35
 
31
36
  interface NodeSqliteStmt {
@@ -58,7 +63,7 @@ async function tryNodeSqlite(dbPath: string): Promise<SqliteReader | null> {
58
63
  }
59
64
  }
60
65
 
61
- // ── Tier 2: sql.js (portable snapshot) ──
66
+ // ── Tier 2: sql.js (portable, WAL-aware snapshot) ──
62
67
 
63
68
  let sqlPromise: Promise<SqlJsStatic> | null = null;
64
69
  function loadSqlJs(): Promise<SqlJsStatic> {
@@ -66,10 +71,154 @@ function loadSqlJs(): Promise<SqlJsStatic> {
66
71
  return sqlPromise;
67
72
  }
68
73
 
74
+ interface FileVersion {
75
+ size: number;
76
+ mtimeMs: number;
77
+ ctimeMs: number;
78
+ }
79
+
80
+ function fileVersion(path: string): FileVersion {
81
+ const stat = statSync(path);
82
+ return { size: stat.size, mtimeMs: stat.mtimeMs, ctimeMs: stat.ctimeMs };
83
+ }
84
+
85
+ function sameVersion(a: FileVersion, b: FileVersion): boolean {
86
+ return a.size === b.size && a.mtimeMs === b.mtimeMs && a.ctimeMs === b.ctimeMs;
87
+ }
88
+
89
+ function sqlitePageSize(db: Uint8Array): number | null {
90
+ if (db.length < 100) return null;
91
+ if (Buffer.from(db.subarray(0, 16)).toString("binary") !== "SQLite format 3\0") return null;
92
+ const encoded = (db[16] << 8) | db[17];
93
+ const pageSize = encoded === 1 ? 65_536 : encoded;
94
+ return pageSize >= 512 && pageSize <= 65_536 && (pageSize & (pageSize - 1)) === 0
95
+ ? pageSize
96
+ : null;
97
+ }
98
+
99
+ function walChecksum(
100
+ bytes: Uint8Array,
101
+ offset: number,
102
+ length: number,
103
+ bigEndian: boolean,
104
+ initial: readonly [number, number] = [0, 0],
105
+ ): [number, number] {
106
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
107
+ let [sum1, sum2] = initial;
108
+ for (let cursor = offset; cursor < offset + length; cursor += 8) {
109
+ const first = view.getUint32(cursor, !bigEndian);
110
+ const second = view.getUint32(cursor + 4, !bigEndian);
111
+ sum1 = (sum1 + first + sum2) >>> 0;
112
+ sum2 = (sum2 + second + sum1) >>> 0;
113
+ }
114
+ return [sum1, sum2];
115
+ }
116
+
117
+ /** Overlay every valid frame through the WAL's last committed transaction. */
118
+ function applyCommittedWal(db: Uint8Array, wal: Uint8Array): Uint8Array {
119
+ const pageSize = sqlitePageSize(db);
120
+ if (pageSize === null || wal.length < 32) return db;
121
+
122
+ const view = new DataView(wal.buffer, wal.byteOffset, wal.byteLength);
123
+ const magic = view.getUint32(0, false);
124
+ if (magic !== 0x377f0682 && magic !== 0x377f0683) return db;
125
+ if (view.getUint32(4, false) !== 3_007_000) return db;
126
+ if (view.getUint32(8, false) !== pageSize) return db;
127
+
128
+ const checksumBigEndian = (magic & 1) === 1;
129
+ let checksum = walChecksum(wal, 0, 24, checksumBigEndian);
130
+ if (view.getUint32(24, false) !== checksum[0] || view.getUint32(28, false) !== checksum[1]) {
131
+ return db;
132
+ }
133
+
134
+ const salt1 = view.getUint32(16, false);
135
+ const salt2 = view.getUint32(20, false);
136
+ const frameSize = 24 + pageSize;
137
+ const frameCount = Math.floor((wal.length - 32) / frameSize);
138
+ let lastCommit = -1;
139
+ let committedPages = 0;
140
+
141
+ for (let index = 0; index < frameCount; index += 1) {
142
+ const offset = 32 + index * frameSize;
143
+ const pageNumber = view.getUint32(offset, false);
144
+ if (
145
+ pageNumber === 0 ||
146
+ view.getUint32(offset + 8, false) !== salt1 ||
147
+ view.getUint32(offset + 12, false) !== salt2
148
+ ) {
149
+ break;
150
+ }
151
+ checksum = walChecksum(wal, offset, 8, checksumBigEndian, checksum);
152
+ checksum = walChecksum(wal, offset + 24, pageSize, checksumBigEndian, checksum);
153
+ if (
154
+ view.getUint32(offset + 16, false) !== checksum[0] ||
155
+ view.getUint32(offset + 20, false) !== checksum[1]
156
+ ) {
157
+ break;
158
+ }
159
+ const databasePages = view.getUint32(offset + 4, false);
160
+ if (databasePages > 0) {
161
+ lastCommit = index;
162
+ committedPages = databasePages;
163
+ }
164
+ }
165
+
166
+ if (lastCommit < 0 || committedPages === 0) return db;
167
+ const targetSize = committedPages * pageSize;
168
+ // A corrupt WAL must not be allowed to request an unbounded allocation.
169
+ if (!Number.isSafeInteger(targetSize) || targetSize > db.length + frameCount * pageSize) {
170
+ return db;
171
+ }
172
+
173
+ const snapshot = new Uint8Array(targetSize);
174
+ snapshot.set(db.subarray(0, targetSize));
175
+ for (let index = 0; index <= lastCommit; index += 1) {
176
+ const offset = 32 + index * frameSize;
177
+ const pageNumber = view.getUint32(offset, false);
178
+ const destination = (pageNumber - 1) * pageSize;
179
+ // An earlier transaction in the same WAL may have grown the database and
180
+ // a later committed transaction may have truncated it again. Frames above
181
+ // the final committed page count are valid history, but not part of the
182
+ // snapshot sql.js should open.
183
+ if (destination >= targetSize) continue;
184
+ snapshot.set(wal.subarray(offset + 24, offset + frameSize), destination);
185
+ }
186
+ return snapshot;
187
+ }
188
+
189
+ /**
190
+ * Read the main file before the WAL and verify that no checkpoint changed the
191
+ * main file in between. WAL appends are safe: only complete committed frames
192
+ * present in the bytes we read are applied. A checkpoint/reset changes the
193
+ * main file, which makes us retry instead of combining different generations.
194
+ */
195
+ function readPortableSnapshot(dbPath: string): Uint8Array {
196
+ const walPath = `${dbPath}-wal`;
197
+ for (let attempt = 0; attempt < 3; attempt += 1) {
198
+ const before = fileVersion(dbPath);
199
+ const main = readFileSync(dbPath);
200
+ const afterMain = fileVersion(dbPath);
201
+ if (!sameVersion(before, afterMain)) continue;
202
+
203
+ let wal: Uint8Array | null = null;
204
+ try {
205
+ wal = readFileSync(walPath);
206
+ } catch (error) {
207
+ // A missing WAL is an ordinary checkpointed database.
208
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;
209
+ }
210
+
211
+ const afterWal = fileVersion(dbPath);
212
+ if (!sameVersion(before, afterWal)) continue;
213
+ return wal ? applyCommittedWal(main, wal) : main;
214
+ }
215
+ throw new Error(`SQLite database changed while reading: ${dbPath}`);
216
+ }
217
+
69
218
  async function trySqlJs(dbPath: string): Promise<SqliteReader | null> {
70
219
  try {
71
220
  const SQL = await loadSqlJs();
72
- const db = new SQL.Database(readFileSync(dbPath));
221
+ const db = new SQL.Database(readPortableSnapshot(dbPath));
73
222
  return {
74
223
  query<T = Record<string, unknown>>(sql: string, params?: unknown[]): T[] {
75
224
  const stmt = db.prepare(sql);
@@ -96,7 +245,14 @@ async function trySqlJs(dbPath: string): Promise<SqliteReader | null> {
96
245
  * connection (live data), falls back to a `sql.js` snapshot. Returns `null` on
97
246
  * any failure. Always `close()` the reader when done.
98
247
  */
99
- export async function openSqliteReadonly(dbPath: string): Promise<SqliteReader | null> {
248
+ export async function openSqliteReadonly(
249
+ dbPath: string,
250
+ options: SqliteReaderOptions = {},
251
+ ): Promise<SqliteReader | null> {
100
252
  if (!existsSync(dbPath)) return null;
101
- return (await tryNodeSqlite(dbPath)) ?? (await trySqlJs(dbPath));
253
+ if (!options.forcePortable) {
254
+ const native = await tryNodeSqlite(dbPath);
255
+ if (native) return native;
256
+ }
257
+ return trySqlJs(dbPath);
102
258
  }
@@ -37,11 +37,13 @@ import { existsSync } from "node:fs";
37
37
  import { resolve, dirname } from "node:path";
38
38
  import { fileURLToPath } from "node:url";
39
39
  import { createInstructRetryGate, mapBeforeToolVerdict } from "./instruct-retry-gate.js";
40
+ import { createWorkspaceContext } from "./workspace-context.js";
40
41
 
41
42
  const HERE = dirname(fileURLToPath(import.meta.url));
42
43
  const DIST_BIN = resolve(HERE, "..", "dist", "cli.mjs");
43
44
  const SRC_BIN = resolve(HERE, "..", "bin", "failproofai.mjs");
44
45
  const instructRetryGate = createInstructRetryGate();
46
+ const workspaceContext = createWorkspaceContext();
45
47
 
46
48
  function resolveSpawn() {
47
49
  if (process.env.FAILPROOFAI_BINARY_OVERRIDE) {
@@ -117,12 +119,12 @@ function callPolicy(rawEvent, payload) {
117
119
 
118
120
  /** Claude-shaped stdin base. Extra keys are ignored by the binary's payload
119
121
  * parser; they're forwarded for future use / activity attribution. */
120
- function baseMeta(payload, ctx) {
122
+ function baseMeta(payload, ctx, config) {
121
123
  const p = payload || {};
122
124
  const c = ctx || {};
123
125
  return {
124
126
  session_id: c.sessionId ?? p.sessionId ?? c.sessionKey ?? p.sessionKey,
125
- cwd: p.cwd ?? c.workspaceDir ?? process.cwd(),
127
+ cwd: workspaceContext.resolveWorkspace(p, c, config) ?? process.cwd(),
126
128
  transcript_path: p.transcriptPath,
127
129
  stop_hook_active: p.stopHookActive === true,
128
130
  openclaw: {
@@ -148,7 +150,7 @@ export default definePluginEntry({
148
150
  async (payload, ctx) => {
149
151
  const p = payload || {};
150
152
  const verdict = await callPolicy("before_tool_call", {
151
- ...baseMeta(payload, ctx),
153
+ ...baseMeta(payload, ctx, api.config),
152
154
  tool_name: p.toolName,
153
155
  tool_input: p.params,
154
156
  hook_event_name: "before_tool_call",
@@ -163,8 +165,9 @@ export default definePluginEntry({
163
165
  "before_agent_run",
164
166
  async (payload, ctx) => {
165
167
  const p = payload || {};
168
+ workspaceContext.remember(payload, ctx);
166
169
  const verdict = await callPolicy("before_agent_run", {
167
- ...baseMeta(payload, ctx),
170
+ ...baseMeta(payload, ctx, api.config),
168
171
  prompt: p.prompt,
169
172
  hook_event_name: "before_agent_run",
170
173
  });
@@ -184,7 +187,7 @@ export default definePluginEntry({
184
187
  "before_agent_finalize",
185
188
  async (payload, ctx) => {
186
189
  const verdict = await callPolicy("before_agent_finalize", {
187
- ...baseMeta(payload, ctx),
190
+ ...baseMeta(payload, ctx, api.config),
188
191
  hook_event_name: "before_agent_finalize",
189
192
  });
190
193
  if (verdict.permission === "deny") {
@@ -210,14 +213,17 @@ export default definePluginEntry({
210
213
  async (payload, ctx) => {
211
214
  const p = payload || {};
212
215
  await callPolicy(ev, {
213
- ...baseMeta(payload, ctx),
216
+ ...baseMeta(payload, ctx, api.config),
214
217
  tool_name: p.toolName,
215
218
  tool_input: p.params,
216
219
  tool_response: p.result,
217
220
  reason: p.reason,
218
221
  hook_event_name: ev,
219
222
  });
220
- if (ev === "session_end") instructRetryGate.clear(payload, ctx);
223
+ if (ev === "session_end") {
224
+ instructRetryGate.clear(payload, ctx);
225
+ workspaceContext.clear(payload, ctx);
226
+ }
221
227
  return undefined;
222
228
  },
223
229
  { priority: 100, timeoutMs: 60_000 },