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.
- package/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +6 -6
- package/.next/standalone/.next/prerender-manifest.json +4 -4
- package/.next/standalone/.next/required-server-files.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_global-error/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +6 -6
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/.next/server/app/_not-found.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/api/audit/invite/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/run/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/audit/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-request/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/login-verify/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/auth/status/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/download/[project]/[session]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/audit/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/audit/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/audit/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/index.html +1 -1
- package/.next/standalone/.next/server/app/index.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +13 -13
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/policies/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/policies/page/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +1 -1
- package/.next/standalone/.next/server/app/policies/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/policies/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/project/[name]/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/react-loadable-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page/server-reference-manifest.json +2 -2
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/session/[sessionId]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/projects/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/projects/page/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/projects/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/settings/page/build-manifest.json +3 -3
- package/.next/standalone/.next/server/app/settings/page/server-reference-manifest.json +4 -4
- package/.next/standalone/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o07qi9._.js +1 -1
- package/.next/standalone/.next/server/chunks/_09dz7xv._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0tovk6q._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0trp3yc._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1vslkoe._.js +1 -1
- package/.next/standalone/.next/server/chunks/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__00y9ww2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__013jr2b._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__01wy8d-._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02npjtd._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0n_lxhg._.js → [root-of-the-server]__0bym1os._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0da85px._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0ftmoxc._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0p-5p8u._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0sz_5na._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__05g1k7_._.js → [root-of-the-server]__15k-dqb._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ctpynv._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1p2otjt._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u6sn69._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_17noq1a._.js → _0guaevg._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1_ozgif._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0iv28v5._.js → _1b78kcp._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1u8-lu2._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1zopuov._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_next-internal_server_app_policies_page_actions_1sp2-yo.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/app_audit__components_audit-dashboard_tsx_0p9ud47._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_global-error_tsx_1kp6l3x._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_policies_hooks-client_tsx_19dqvpc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/app_settings_settings-client_tsx_20lq-mq._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/lib_codex-projects_ts_0pqlw37._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +6 -6
- package/.next/standalone/.next/server/pages/404.html +1 -1
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +19 -19
- package/.next/standalone/.next/static/chunks/{0qytob94jbzs6.js → 021ydrq6rhpsi.js} +1 -1
- package/.next/standalone/.next/static/chunks/{26tf_lpco5n-v.js → 0y8_1s45gbqmn.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2b014kj28p0vz.js → 11s_v03ub6nss.js} +1 -1
- package/.next/standalone/.next/static/chunks/14b3ezufe5411.js +1 -0
- package/.next/standalone/.next/static/chunks/{3kltzmx9k_t6x.js → 1c6aptmytnu6q.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3vjaz4hld9oo8.js → 1oskk7pdo8aon.js} +1 -1
- package/.next/standalone/.next/static/chunks/{074xcclgow3yh.js → 1vb33xa6j9y2q.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3pmi7qhtmniku.js → 252xreaecy80h.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3_fnbc-v5r-9e.js → 2xycd6mjg00fb.js} +1 -1
- package/.next/standalone/.next/static/chunks/{41ejnuj2d9g7_.js → 2zafgs90r_leq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3q1rji38vuvr4.js → 3bleyy40s99f2.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3qxl_gibq3bas.js → 3w46euc60dx39.js} +1 -1
- package/.next/standalone/.next/static/chunks/{turbopack-1xgsp63yhrdu5.js → turbopack-3p73obe0xmrxm.js} +1 -1
- package/.next/standalone/lib/openclaw-profiles.ts +78 -0
- package/.next/standalone/lib/openclaw-projects.ts +3 -3
- package/.next/standalone/lib/sqlite-reader.ts +165 -9
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +845 -684
- package/dist/worker.mjs +129 -17
- package/lib/openclaw-profiles.ts +78 -0
- package/lib/openclaw-projects.ts +3 -3
- package/lib/sqlite-reader.ts +165 -9
- package/openclaw-plugin/index.js +13 -7
- package/openclaw-plugin/workspace-context.js +93 -0
- package/package.json +9 -9
- package/src/hooks/integrations.ts +22 -14
- package/.next/standalone/.next/static/chunks/25cn9xpv4r1ow.js +0 -1
- /package/.next/standalone/.next/static/{Qexks15mjEoPt6cN3D2jb → uFpAs_vIXSo6qBzmkXPWD}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{Qexks15mjEoPt6cN3D2jb → uFpAs_vIXSo6qBzmkXPWD}/_clientMiddlewareManifest.js +0 -0
- /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
|
|
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(
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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 (
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
+
}
|
package/lib/openclaw-projects.ts
CHANGED
|
@@ -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. "
|
|
26
|
+
/** Human-readable label from `origin.label` (e.g. "Example User (@example) id:…"). */
|
|
27
27
|
label?: string;
|
|
28
|
-
/** Chat id (e.g. "telegram:
|
|
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. "
|
|
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,
|
package/lib/sqlite-reader.ts
CHANGED
|
@@ -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.
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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(
|
|
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(
|
|
248
|
+
export async function openSqliteReadonly(
|
|
249
|
+
dbPath: string,
|
|
250
|
+
options: SqliteReaderOptions = {},
|
|
251
|
+
): Promise<SqliteReader | null> {
|
|
100
252
|
if (!existsSync(dbPath)) return null;
|
|
101
|
-
|
|
253
|
+
if (!options.forcePortable) {
|
|
254
|
+
const native = await tryNodeSqlite(dbPath);
|
|
255
|
+
if (native) return native;
|
|
256
|
+
}
|
|
257
|
+
return trySqlJs(dbPath);
|
|
102
258
|
}
|
package/openclaw-plugin/index.js
CHANGED
|
@@ -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
|
|
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")
|
|
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 },
|