failproofai 1.0.6-beta.0 → 1.0.6
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 +3 -3
- 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/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/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 +4 -4
- 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/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/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/server-reference-manifest.json +14 -14
- package/.next/standalone/.next/server/app/policies/page.js +6 -5
- 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/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/server/app/project/[name]/page.js +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/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 +1 -1
- 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/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/server-reference-manifest.json +4 -4
- package/.next/standalone/.next/server/app/settings/page.js +3 -2
- 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/[root-of-the-server]__0zlqo2t._.js +1 -1
- package/.next/standalone/.next/server/chunks/{[root-of-the-server]__112b4go._.js → [root-of-the-server]__1_r2rbg._.js} +4 -4
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1anxb5k._.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/package_json_[json]_cjs_1nxcc4v._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0-_ki57._.js +4 -0
- 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]__0576iuy._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__0bym1os._.js → [root-of-the-server]__0cg-bgc._.js} +2 -2
- 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]__0p-5p8u._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__00y9ww2._.js → [root-of-the-server]__0u3w0ll._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1b2dbet._.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]__1py795m._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1i26dsw._.js → [root-of-the-server]__1svlq8e._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1v185mo._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_06imw3p._.js +5 -0
- package/.next/standalone/.next/server/chunks/ssr/_08x1r5t._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_09hs6ms._.js → _0do6d26._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0lbwa8m._.js → _17o744m._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{_14c6q09._.js → _1_qswah._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_1es2j7i._.js +1 -1
- 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 +12 -11
- 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/middleware-build-manifest.js +3 -3
- 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/0bepqeawy72n6.js +1 -0
- package/.next/standalone/.next/static/chunks/{17pjz_h45j10c.js → 0h-gz8e00478q.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3d3hzhcnns6ww.js → 25m8mg7bosgip.js} +1 -1
- package/.next/standalone/.next/static/chunks/{44_cj1_i_aa2z.js → 2y4ycwcwfjv4k.js} +1 -1
- package/.next/standalone/.next/static/chunks/3-6zhytp6adkk.js +1 -0
- package/.next/standalone/.next/static/chunks/{0vanab2g65op_.js → 319c_91le7-h_.js} +1 -1
- package/.next/standalone/.next/static/chunks/35m53kix7uaii.js +6 -0
- package/.next/standalone/.next/static/chunks/{1so_3s0q4c4j1.js → 35pw7zxhh76n7.js} +1 -1
- package/.next/standalone/.next/static/chunks/3xacd7qmuqlvs.js +1 -0
- package/.next/standalone/.next/static/chunks/{03n_qjih7-w6q.js → 40-wncjnguy4e.js} +1 -1
- package/.next/standalone/hermes-plugin/README.md +6 -1
- package/.next/standalone/hermes-plugin/client.py +22 -6
- package/.next/standalone/lib/hermes-profiles.ts +67 -19
- package/.next/standalone/lib/hermes-sessions.ts +3 -2
- package/.next/standalone/package.json +9 -9
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +380 -266
- package/dist/worker.mjs +62 -32
- package/hermes-plugin/README.md +6 -1
- package/hermes-plugin/client.py +22 -6
- package/lib/hermes-profiles.ts +67 -19
- package/lib/hermes-sessions.ts +3 -2
- package/package.json +9 -9
- package/src/hooks/daemon-client.ts +128 -50
- package/src/hooks/daemon-service.ts +30 -0
- package/src/hooks/integrations.ts +8 -0
- package/src/hooks/manager.ts +24 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0oa1lav._.js +0 -3
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0s740oi._.js +0 -6
- package/.next/standalone/.next/static/chunks/1ekh-hj_iom84.js +0 -1
- package/.next/standalone/.next/static/chunks/2u0kol_boahtv.js +0 -1
- package/.next/standalone/.next/static/chunks/3_vesf83-0903.js +0 -1
- package/.next/standalone/.next/static/chunks/3iasus89n8mg1.js +0 -6
- /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{-7OT2NwGPxAu-skEL_Xee → LzR_etPlaZV9JZH09lEp3}/_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.6
|
|
3486
|
+
var version = "1.0.6";
|
|
3487
3487
|
var init_package = () => {};
|
|
3488
3488
|
|
|
3489
3489
|
// src/posthog-key.ts
|
|
@@ -6388,36 +6388,66 @@ var init_pi_projects = __esm(() => {
|
|
|
6388
6388
|
});
|
|
6389
6389
|
|
|
6390
6390
|
// lib/hermes-profiles.ts
|
|
6391
|
-
import { readdirSync as readdirSync3 } from "node:fs";
|
|
6391
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3 } from "node:fs";
|
|
6392
6392
|
import { homedir as homedir10 } from "node:os";
|
|
6393
6393
|
import { basename as basename2, dirname as dirname3, join as join11, resolve as resolve8 } from "node:path";
|
|
6394
6394
|
function hermesRoot() {
|
|
6395
6395
|
const env = (process.env.HERMES_HOME || "").trim();
|
|
6396
6396
|
if (env) {
|
|
6397
|
-
|
|
6397
|
+
let home = resolve8(env);
|
|
6398
6398
|
const parent = dirname3(home);
|
|
6399
6399
|
if (basename2(parent) === PROFILES_DIR)
|
|
6400
|
-
|
|
6400
|
+
home = dirname3(parent);
|
|
6401
|
+
const base = basename2(home);
|
|
6402
|
+
if (base === STANDARD_HOME || base.startsWith(SIBLING_HOME_PREFIX)) {
|
|
6403
|
+
return join11(dirname3(home), STANDARD_HOME);
|
|
6404
|
+
}
|
|
6401
6405
|
return home;
|
|
6402
6406
|
}
|
|
6403
|
-
return join11(homedir10(),
|
|
6407
|
+
return join11(homedir10(), STANDARD_HOME);
|
|
6408
|
+
}
|
|
6409
|
+
function uniqueProfileName(preferred, seen) {
|
|
6410
|
+
if (!seen.has(preferred))
|
|
6411
|
+
return preferred;
|
|
6412
|
+
const base = `${preferred}-home`;
|
|
6413
|
+
if (!seen.has(base))
|
|
6414
|
+
return base;
|
|
6415
|
+
let suffix = 2;
|
|
6416
|
+
while (seen.has(`${base}-${suffix}`))
|
|
6417
|
+
suffix += 1;
|
|
6418
|
+
return `${base}-${suffix}`;
|
|
6404
6419
|
}
|
|
6405
6420
|
function listHermesProfiles() {
|
|
6406
6421
|
const root = hermesRoot();
|
|
6407
6422
|
const out = [{ name: HERMES_DEFAULT_PROFILE, home: root }];
|
|
6408
6423
|
const seen = new Set([HERMES_DEFAULT_PROFILE]);
|
|
6409
|
-
let names;
|
|
6424
|
+
let names = [];
|
|
6410
6425
|
try {
|
|
6411
6426
|
names = readdirSync3(join11(root, PROFILES_DIR), { withFileTypes: true }).filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
6412
|
-
} catch {
|
|
6413
|
-
return out;
|
|
6414
|
-
}
|
|
6427
|
+
} catch {}
|
|
6415
6428
|
for (const name of names) {
|
|
6416
6429
|
if (seen.has(name))
|
|
6417
6430
|
continue;
|
|
6418
6431
|
seen.add(name);
|
|
6419
6432
|
out.push({ name, home: join11(root, PROFILES_DIR, name) });
|
|
6420
6433
|
}
|
|
6434
|
+
if (basename2(root) !== STANDARD_HOME)
|
|
6435
|
+
return out;
|
|
6436
|
+
let siblings = [];
|
|
6437
|
+
const parent = dirname3(root);
|
|
6438
|
+
try {
|
|
6439
|
+
siblings = readdirSync3(parent, { withFileTypes: true }).filter((entry) => (entry.isDirectory() || entry.isSymbolicLink()) && entry.name.startsWith(SIBLING_HOME_PREFIX) && entry.name.length > SIBLING_HOME_PREFIX.length && existsSync9(join11(parent, entry.name, "config.yaml"))).map((entry) => ({
|
|
6440
|
+
name: entry.name.slice(SIBLING_HOME_PREFIX.length),
|
|
6441
|
+
home: join11(parent, entry.name)
|
|
6442
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
6443
|
+
} catch {
|
|
6444
|
+
return out;
|
|
6445
|
+
}
|
|
6446
|
+
for (const sibling of siblings) {
|
|
6447
|
+
const name = uniqueProfileName(sibling.name, seen);
|
|
6448
|
+
seen.add(name);
|
|
6449
|
+
out.push({ name, home: sibling.home });
|
|
6450
|
+
}
|
|
6421
6451
|
return out;
|
|
6422
6452
|
}
|
|
6423
6453
|
function hermesProjectName(profile, source) {
|
|
@@ -6443,7 +6473,7 @@ function hermesProjectNameCandidates(name) {
|
|
|
6443
6473
|
out.push({ profile: HERMES_DEFAULT_PROFILE, source: rest });
|
|
6444
6474
|
return out;
|
|
6445
6475
|
}
|
|
6446
|
-
var PROFILES_DIR = "profiles", HERMES_DEFAULT_PROFILE = "default";
|
|
6476
|
+
var PROFILES_DIR = "profiles", STANDARD_HOME = ".hermes", SIBLING_HOME_PREFIX = ".hermes-", HERMES_DEFAULT_PROFILE = "default";
|
|
6447
6477
|
var init_hermes_profiles = () => {};
|
|
6448
6478
|
|
|
6449
6479
|
// lib/format-duration.ts
|
|
@@ -6765,7 +6795,7 @@ var init_hermes_projects = __esm(() => {
|
|
|
6765
6795
|
});
|
|
6766
6796
|
|
|
6767
6797
|
// lib/openclaw-db.ts
|
|
6768
|
-
import { existsSync as
|
|
6798
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
6769
6799
|
import { join as join13 } from "node:path";
|
|
6770
6800
|
function str(value) {
|
|
6771
6801
|
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
@@ -6785,7 +6815,7 @@ function listOpenClawDatabases(home, agentIds) {
|
|
|
6785
6815
|
const out = [];
|
|
6786
6816
|
for (const agentId of agentIds) {
|
|
6787
6817
|
const dbPath = join13(home, "agents", agentId, "agent", DB_NAME);
|
|
6788
|
-
if (
|
|
6818
|
+
if (existsSync10(dbPath))
|
|
6789
6819
|
out.push({ agentId, dbPath });
|
|
6790
6820
|
}
|
|
6791
6821
|
return out;
|
|
@@ -8962,13 +8992,13 @@ var init_log_entries = __esm(() => {
|
|
|
8962
8992
|
});
|
|
8963
8993
|
|
|
8964
8994
|
// lib/codex-sessions.ts
|
|
8965
|
-
import { readFileSync as readFileSync8, readdirSync as readdirSync7, existsSync as
|
|
8995
|
+
import { readFileSync as readFileSync8, readdirSync as readdirSync7, existsSync as existsSync11, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5, statSync as statSync10 } from "node:fs";
|
|
8966
8996
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
8967
8997
|
import { dirname as dirname4, join as join24 } from "node:path";
|
|
8968
8998
|
import { homedir as homedir16 } from "node:os";
|
|
8969
8999
|
function readCache() {
|
|
8970
9000
|
try {
|
|
8971
|
-
if (!
|
|
9001
|
+
if (!existsSync11(CACHE_PATH))
|
|
8972
9002
|
return {};
|
|
8973
9003
|
return JSON.parse(readFileSync8(CACHE_PATH, "utf-8"));
|
|
8974
9004
|
} catch {
|
|
@@ -8996,7 +9026,7 @@ function dirSearch(dir, sessionId) {
|
|
|
8996
9026
|
function findCodexTranscript(sessionId) {
|
|
8997
9027
|
const cache = readCache();
|
|
8998
9028
|
const cached = cache[sessionId];
|
|
8999
|
-
if (cached &&
|
|
9029
|
+
if (cached && existsSync11(cached))
|
|
9000
9030
|
return cached;
|
|
9001
9031
|
const root = join24(homedir16(), ".codex", "sessions");
|
|
9002
9032
|
const today = new Date;
|
|
@@ -9290,7 +9320,7 @@ var init_resolve_permission_mode = __esm(() => {
|
|
|
9290
9320
|
});
|
|
9291
9321
|
|
|
9292
9322
|
// lib/copilot-sessions.ts
|
|
9293
|
-
import { readFileSync as readFileSync10, readdirSync as readdirSync8, existsSync as
|
|
9323
|
+
import { readFileSync as readFileSync10, readdirSync as readdirSync8, existsSync as existsSync12, statSync as statSync11 } from "node:fs";
|
|
9294
9324
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
9295
9325
|
import { join as join25, resolve as resolve10, sep as sep2 } from "node:path";
|
|
9296
9326
|
import { homedir as homedir17 } from "node:os";
|
|
@@ -9319,13 +9349,13 @@ function findCopilotTranscript(sessionId) {
|
|
|
9319
9349
|
const candidate = resolveSessionFile(sessionId, "events.jsonl");
|
|
9320
9350
|
if (!candidate)
|
|
9321
9351
|
return null;
|
|
9322
|
-
return
|
|
9352
|
+
return existsSync12(candidate) ? candidate : null;
|
|
9323
9353
|
}
|
|
9324
9354
|
function findCopilotWorkspace(sessionId) {
|
|
9325
9355
|
const candidate = resolveSessionFile(sessionId, "workspace.yaml");
|
|
9326
9356
|
if (!candidate)
|
|
9327
9357
|
return null;
|
|
9328
|
-
return
|
|
9358
|
+
return existsSync12(candidate) ? candidate : null;
|
|
9329
9359
|
}
|
|
9330
9360
|
function readYamlScalar(path, key) {
|
|
9331
9361
|
try {
|
|
@@ -9507,7 +9537,7 @@ var init_copilot_sessions = __esm(() => {
|
|
|
9507
9537
|
});
|
|
9508
9538
|
|
|
9509
9539
|
// lib/cursor-sessions.ts
|
|
9510
|
-
import { readFileSync as readFileSync11, readdirSync as readdirSync9, existsSync as
|
|
9540
|
+
import { readFileSync as readFileSync11, readdirSync as readdirSync9, existsSync as existsSync13, statSync as statSync12 } from "node:fs";
|
|
9511
9541
|
import { readFile as readFile13 } from "node:fs/promises";
|
|
9512
9542
|
import { basename as basename3, join as join26, resolve as resolve11, sep as sep3 } from "node:path";
|
|
9513
9543
|
import { homedir as homedir18 } from "node:os";
|
|
@@ -9530,7 +9560,7 @@ function getCursorSessionDir(sessionId) {
|
|
|
9530
9560
|
const transcriptRoot = resolve11(projectsRoot, entry.name, NEW_AGENT_TRANSCRIPTS_DIR2);
|
|
9531
9561
|
if (candidate === transcriptRoot || !candidate.startsWith(`${transcriptRoot}${sep3}`))
|
|
9532
9562
|
continue;
|
|
9533
|
-
if (
|
|
9563
|
+
if (existsSync13(candidate))
|
|
9534
9564
|
return candidate;
|
|
9535
9565
|
}
|
|
9536
9566
|
for (const sub of LEGACY_SESSION_ROOT_CANDIDATES2) {
|
|
@@ -9538,7 +9568,7 @@ function getCursorSessionDir(sessionId) {
|
|
|
9538
9568
|
const candidate = resolve11(root, sessionId);
|
|
9539
9569
|
if (candidate === root || !candidate.startsWith(`${root}${sep3}`))
|
|
9540
9570
|
continue;
|
|
9541
|
-
if (
|
|
9571
|
+
if (existsSync13(candidate))
|
|
9542
9572
|
return candidate;
|
|
9543
9573
|
}
|
|
9544
9574
|
return null;
|
|
@@ -9548,11 +9578,11 @@ function findCursorTranscript(sessionId) {
|
|
|
9548
9578
|
if (!dir)
|
|
9549
9579
|
return null;
|
|
9550
9580
|
const newCandidate = join26(dir, `${basename3(dir)}.jsonl`);
|
|
9551
|
-
if (
|
|
9581
|
+
if (existsSync13(newCandidate))
|
|
9552
9582
|
return newCandidate;
|
|
9553
9583
|
for (const name of LEGACY_TRANSCRIPT_FILE_CANDIDATES2) {
|
|
9554
9584
|
const candidate = join26(dir, name);
|
|
9555
|
-
if (
|
|
9585
|
+
if (existsSync13(candidate))
|
|
9556
9586
|
return candidate;
|
|
9557
9587
|
}
|
|
9558
9588
|
return null;
|
|
@@ -9763,7 +9793,7 @@ var init_cursor_sessions = __esm(() => {
|
|
|
9763
9793
|
});
|
|
9764
9794
|
|
|
9765
9795
|
// lib/pi-sessions.ts
|
|
9766
|
-
import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as
|
|
9796
|
+
import { readFileSync as readFileSync12, readdirSync as readdirSync10, existsSync as existsSync14, statSync as statSync13 } from "node:fs";
|
|
9767
9797
|
import { readFile as readFile14 } from "node:fs/promises";
|
|
9768
9798
|
import { join as join27, resolve as resolve12, sep as sep4 } from "node:path";
|
|
9769
9799
|
import { homedir as homedir19 } from "node:os";
|
|
@@ -9800,7 +9830,7 @@ function findPiTranscript(sessionId) {
|
|
|
9800
9830
|
const candidate = resolve12(cwdPath, f);
|
|
9801
9831
|
if (!candidate.startsWith(`${cwdPath}${sep4}`))
|
|
9802
9832
|
continue;
|
|
9803
|
-
if (
|
|
9833
|
+
if (existsSync14(candidate))
|
|
9804
9834
|
return candidate;
|
|
9805
9835
|
}
|
|
9806
9836
|
}
|
|
@@ -10160,7 +10190,7 @@ var init_pack_failclosed = __esm(() => {
|
|
|
10160
10190
|
var init_atomic_write = () => {};
|
|
10161
10191
|
|
|
10162
10192
|
// src/hooks/session-pause.ts
|
|
10163
|
-
import { existsSync as
|
|
10193
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync6, readdirSync as readdirSync11, readFileSync as readFileSync13, rmSync as rmSync2 } from "node:fs";
|
|
10164
10194
|
import { createHash as createHash5 } from "node:crypto";
|
|
10165
10195
|
import { join as join28, resolve as resolve13 } from "node:path";
|
|
10166
10196
|
function pauseStateDir() {
|
|
@@ -10200,7 +10230,7 @@ function readActivePause(sessionId, now = Date.now()) {
|
|
|
10200
10230
|
return null;
|
|
10201
10231
|
try {
|
|
10202
10232
|
const path = pauseFilePath(sessionId);
|
|
10203
|
-
if (!
|
|
10233
|
+
if (!existsSync15(path))
|
|
10204
10234
|
return null;
|
|
10205
10235
|
const stored = parseStored(JSON.parse(readFileSync13(path, "utf8")));
|
|
10206
10236
|
if (!stored)
|
|
@@ -10241,7 +10271,7 @@ var init_daemon_service = __esm(() => {
|
|
|
10241
10271
|
// src/hooks/fp-reset.ts
|
|
10242
10272
|
import {
|
|
10243
10273
|
copyFileSync,
|
|
10244
|
-
existsSync as
|
|
10274
|
+
existsSync as existsSync16,
|
|
10245
10275
|
mkdirSync as mkdirSync7,
|
|
10246
10276
|
readFileSync as readFileSync14,
|
|
10247
10277
|
readdirSync as readdirSync12,
|
|
@@ -10258,7 +10288,7 @@ function layoutWarningForHook() {
|
|
|
10258
10288
|
if (state.kind === "future") {
|
|
10259
10289
|
return `[failproofai] this directory was written by a newer version (layout ${state.found} vs ${LAYOUT_VERSION}) — policies are NOT being enforced. ` + `Upgrade failproofai.`;
|
|
10260
10290
|
}
|
|
10261
|
-
if (
|
|
10291
|
+
if (existsSync16(globalPolicyConfigFile()))
|
|
10262
10292
|
return null;
|
|
10263
10293
|
return `[failproofai] setup predates this version — global policies are NOT being enforced. ` + `Run \`failproofai config\` to re-create it.`;
|
|
10264
10294
|
}
|
|
@@ -10648,7 +10678,7 @@ var init_handler = __esm(() => {
|
|
|
10648
10678
|
|
|
10649
10679
|
// src/hooks/worker-server.ts
|
|
10650
10680
|
import { createConnection, createServer } from "node:net";
|
|
10651
|
-
import { existsSync as
|
|
10681
|
+
import { existsSync as existsSync17, unlinkSync as unlinkSync2 } from "node:fs";
|
|
10652
10682
|
function isWorkerHookRequest(msg) {
|
|
10653
10683
|
if (!msg || typeof msg !== "object")
|
|
10654
10684
|
return false;
|
|
@@ -10782,14 +10812,14 @@ function requestExistingWorkerShutdown(socketPath) {
|
|
|
10782
10812
|
function startWorkerServer(socketPath, shutdown) {
|
|
10783
10813
|
const server = createServer((socket) => handleConnection(socket, shutdown ?? (() => server.close())));
|
|
10784
10814
|
const listen = () => {
|
|
10785
|
-
if (
|
|
10815
|
+
if (existsSync17(socketPath)) {
|
|
10786
10816
|
try {
|
|
10787
10817
|
unlinkSync2(socketPath);
|
|
10788
10818
|
} catch {}
|
|
10789
10819
|
}
|
|
10790
10820
|
server.listen(socketPath);
|
|
10791
10821
|
};
|
|
10792
|
-
if (!
|
|
10822
|
+
if (!existsSync17(socketPath))
|
|
10793
10823
|
listen();
|
|
10794
10824
|
else
|
|
10795
10825
|
requestExistingWorkerShutdown(socketPath).then(listen, (err) => server.emit("error", err));
|
package/hermes-plugin/README.md
CHANGED
|
@@ -10,7 +10,12 @@ manifest v2 fields, `PluginContext` methods/state, and keyword hook payloads.
|
|
|
10
10
|
|
|
11
11
|
## Installation
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Hermes policy evaluation requires a configured, healthy local `failproofaid`
|
|
14
|
+
daemon. If this machine has not been configured yet, run `failproofai config`
|
|
15
|
+
first. The standalone installer refuses to enable the fail-closed plugin until
|
|
16
|
+
the daemon answers an end-to-end health probe.
|
|
17
|
+
|
|
18
|
+
Then run:
|
|
14
19
|
|
|
15
20
|
```bash
|
|
16
21
|
failproofai policies --install --cli hermes --scope user
|
package/hermes-plugin/client.py
CHANGED
|
@@ -6,6 +6,7 @@ import json
|
|
|
6
6
|
import os
|
|
7
7
|
import socket
|
|
8
8
|
import struct
|
|
9
|
+
import time
|
|
9
10
|
from dataclasses import dataclass
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from typing import Any, Mapping, Sequence
|
|
@@ -38,11 +39,22 @@ def daemon_socket_path() -> Path:
|
|
|
38
39
|
return home / "run" / "failproofaid.sock"
|
|
39
40
|
|
|
40
41
|
|
|
41
|
-
def
|
|
42
|
+
def _remaining_timeout(deadline: float) -> float:
|
|
43
|
+
remaining = deadline - time.monotonic()
|
|
44
|
+
if remaining <= 0:
|
|
45
|
+
raise EvaluationError("failproofaid evaluation timed out")
|
|
46
|
+
return remaining
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _read_exact(sock: socket.socket, length: int, deadline: float) -> bytes:
|
|
42
50
|
chunks: list[bytes] = []
|
|
43
51
|
remaining = length
|
|
44
52
|
while remaining:
|
|
45
|
-
|
|
53
|
+
sock.settimeout(_remaining_timeout(deadline))
|
|
54
|
+
try:
|
|
55
|
+
chunk = sock.recv(remaining)
|
|
56
|
+
except TimeoutError as exc:
|
|
57
|
+
raise EvaluationError("failproofaid evaluation timed out") from exc
|
|
46
58
|
if not chunk:
|
|
47
59
|
raise EvaluationError("failproofaid closed the connection before returning a verdict")
|
|
48
60
|
chunks.append(chunk)
|
|
@@ -90,12 +102,16 @@ def evaluate_policy(
|
|
|
90
102
|
with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
|
|
91
103
|
sock.settimeout(max(connect_timeout_ms, 1) / 1000)
|
|
92
104
|
sock.connect(str(daemon_socket_path()))
|
|
93
|
-
|
|
94
|
-
sock.
|
|
95
|
-
|
|
105
|
+
deadline = time.monotonic() + max(evaluation_timeout_ms, 1) / 1000
|
|
106
|
+
sock.settimeout(_remaining_timeout(deadline))
|
|
107
|
+
try:
|
|
108
|
+
sock.sendall(struct.pack(">I", len(body)) + body)
|
|
109
|
+
except TimeoutError as exc:
|
|
110
|
+
raise EvaluationError("failproofaid evaluation timed out") from exc
|
|
111
|
+
declared_length = struct.unpack(">I", _read_exact(sock, 4, deadline))[0]
|
|
96
112
|
if declared_length > MAX_FRAME_BYTES:
|
|
97
113
|
raise EvaluationError("failproofaid response exceeds the 16 MiB limit")
|
|
98
|
-
response = json.loads(_read_exact(sock, declared_length).decode("utf-8"))
|
|
114
|
+
response = json.loads(_read_exact(sock, declared_length, deadline).decode("utf-8"))
|
|
99
115
|
except EvaluationError:
|
|
100
116
|
raise
|
|
101
117
|
except (OSError, UnicodeError, ValueError, struct.error) as exc:
|
package/lib/hermes-profiles.ts
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* A Hermes "profile" is not a column or a flag: it is a whole separate Hermes
|
|
5
5
|
* home directory, each with its own `config.yaml`, `.env`, `SOUL.md`, and
|
|
6
|
-
* `state.db`. The default profile lives at `~/.hermes`;
|
|
7
|
-
* `~/.hermes/profiles/<name
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* `state.db`. The default profile lives at `~/.hermes`; upstream named profiles
|
|
7
|
+
* live at `~/.hermes/profiles/<name>/`, while older/custom multi-install setups
|
|
8
|
+
* may use sibling homes such as `~/.hermes-work`. Selection is `hermes -p
|
|
9
|
+
* <name>`, a generated `~/.local/bin/<name>` alias that exports `HERMES_HOME`,
|
|
10
|
+
* or a sticky default recorded in `<root>/active_profile`.
|
|
10
11
|
*
|
|
11
12
|
* Upstream's own contributor guide warns that hardcoding `~/.hermes` breaks
|
|
12
13
|
* profiles — which is exactly what both pillars used to do:
|
|
@@ -21,12 +22,14 @@
|
|
|
21
22
|
* Home override: set `HERMES_HOME` (Hermes's own env var — respected here so a
|
|
22
23
|
* profile-scoped shell and failproofai agree on what "all profiles" means).
|
|
23
24
|
*/
|
|
24
|
-
import { readdirSync } from "node:fs";
|
|
25
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
25
26
|
import { homedir } from "node:os";
|
|
26
27
|
import { basename, dirname, join, resolve } from "node:path";
|
|
27
28
|
|
|
28
29
|
/** Directory under the Hermes root that holds non-default profiles. */
|
|
29
30
|
const PROFILES_DIR = "profiles";
|
|
31
|
+
const STANDARD_HOME = ".hermes";
|
|
32
|
+
const SIBLING_HOME_PREFIX = ".hermes-";
|
|
30
33
|
|
|
31
34
|
/** Name we give the root home (`~/.hermes`), which Hermes itself leaves unnamed. */
|
|
32
35
|
export const HERMES_DEFAULT_PROFILE = "default";
|
|
@@ -41,28 +44,45 @@ export interface HermesProfile {
|
|
|
41
44
|
/**
|
|
42
45
|
* The Hermes ROOT home — the directory that owns `profiles/`.
|
|
43
46
|
*
|
|
44
|
-
* `HERMES_HOME` may point AT
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
47
|
+
* `HERMES_HOME` may point AT an upstream profile (`<root>/profiles/<name>`) or
|
|
48
|
+
* at a sibling installation (`~/.hermes-<name>`). We normalize either standard
|
|
49
|
+
* layout back to `~/.hermes` so discovery covers every installation. A custom
|
|
50
|
+
* non-standard path remains authoritative; scanning arbitrary sibling paths
|
|
51
|
+
* would risk treating backups and unrelated directories as live agents.
|
|
48
52
|
*/
|
|
49
53
|
export function hermesRoot(): string {
|
|
50
54
|
const env = (process.env.HERMES_HOME || "").trim();
|
|
51
55
|
if (env) {
|
|
52
|
-
|
|
56
|
+
let home = resolve(env);
|
|
53
57
|
const parent = dirname(home);
|
|
54
|
-
if (basename(parent) === PROFILES_DIR)
|
|
58
|
+
if (basename(parent) === PROFILES_DIR) home = dirname(parent);
|
|
59
|
+
const base = basename(home);
|
|
60
|
+
if (base === STANDARD_HOME || base.startsWith(SIBLING_HOME_PREFIX)) {
|
|
61
|
+
return join(dirname(home), STANDARD_HOME);
|
|
62
|
+
}
|
|
55
63
|
return home;
|
|
56
64
|
}
|
|
57
|
-
return join(homedir(),
|
|
65
|
+
return join(homedir(), STANDARD_HOME);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function uniqueProfileName(preferred: string, seen: Set<string>): string {
|
|
69
|
+
if (!seen.has(preferred)) return preferred;
|
|
70
|
+
const base = `${preferred}-home`;
|
|
71
|
+
if (!seen.has(base)) return base;
|
|
72
|
+
let suffix = 2;
|
|
73
|
+
while (seen.has(`${base}-${suffix}`)) suffix += 1;
|
|
74
|
+
return `${base}-${suffix}`;
|
|
58
75
|
}
|
|
59
76
|
|
|
60
77
|
/**
|
|
61
78
|
* Every Hermes profile on disk: the root home first (as `"default"`), then each
|
|
62
|
-
* `<root>/profiles/<name
|
|
79
|
+
* `<root>/profiles/<name>/`, then valid `~/.hermes-<name>` sibling homes, in
|
|
80
|
+
* name order within each layout.
|
|
63
81
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
82
|
+
* A sibling home counts only when it contains `config.yaml`, matching OpenClaw
|
|
83
|
+
* discovery and avoiding arbitrary `.hermes-*` backup directories. Upstream
|
|
84
|
+
* `profiles/` directories are authoritative and remain discoverable before
|
|
85
|
+
* their config is first written.
|
|
66
86
|
*
|
|
67
87
|
* A profile directory literally named `default` would collide with the root's
|
|
68
88
|
* reserved name; the root wins and the directory is skipped (dedup by name keeps
|
|
@@ -73,22 +93,50 @@ export function listHermesProfiles(): HermesProfile[] {
|
|
|
73
93
|
const out: HermesProfile[] = [{ name: HERMES_DEFAULT_PROFILE, home: root }];
|
|
74
94
|
const seen = new Set<string>([HERMES_DEFAULT_PROFILE]);
|
|
75
95
|
|
|
76
|
-
let names: string[];
|
|
96
|
+
let names: string[] = [];
|
|
77
97
|
try {
|
|
78
98
|
names = readdirSync(join(root, PROFILES_DIR), { withFileTypes: true })
|
|
79
99
|
// Symlinked profile dirs are legitimate, and `isDirectory()` is false for them.
|
|
80
100
|
.filter((e) => (e.isDirectory() || e.isSymbolicLink()) && !e.name.startsWith("."))
|
|
81
101
|
.map((e) => e.name)
|
|
82
102
|
.sort();
|
|
83
|
-
} catch {
|
|
84
|
-
return out;
|
|
85
|
-
}
|
|
103
|
+
} catch {}
|
|
86
104
|
|
|
87
105
|
for (const name of names) {
|
|
88
106
|
if (seen.has(name)) continue;
|
|
89
107
|
seen.add(name);
|
|
90
108
|
out.push({ name, home: join(root, PROFILES_DIR, name) });
|
|
91
109
|
}
|
|
110
|
+
|
|
111
|
+
// Only the standard ~/.hermes layout defines `.hermes-*` sibling homes.
|
|
112
|
+
// A custom HERMES_HOME is intentionally not used as a prefix convention.
|
|
113
|
+
if (basename(root) !== STANDARD_HOME) return out;
|
|
114
|
+
|
|
115
|
+
let siblings: HermesProfile[] = [];
|
|
116
|
+
const parent = dirname(root);
|
|
117
|
+
try {
|
|
118
|
+
siblings = readdirSync(parent, { withFileTypes: true })
|
|
119
|
+
.filter(
|
|
120
|
+
(entry) =>
|
|
121
|
+
(entry.isDirectory() || entry.isSymbolicLink()) &&
|
|
122
|
+
entry.name.startsWith(SIBLING_HOME_PREFIX) &&
|
|
123
|
+
entry.name.length > SIBLING_HOME_PREFIX.length &&
|
|
124
|
+
existsSync(join(parent, entry.name, "config.yaml")),
|
|
125
|
+
)
|
|
126
|
+
.map((entry) => ({
|
|
127
|
+
name: entry.name.slice(SIBLING_HOME_PREFIX.length),
|
|
128
|
+
home: join(parent, entry.name),
|
|
129
|
+
}))
|
|
130
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
131
|
+
} catch {
|
|
132
|
+
return out;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (const sibling of siblings) {
|
|
136
|
+
const name = uniqueProfileName(sibling.name, seen);
|
|
137
|
+
seen.add(name);
|
|
138
|
+
out.push({ name, home: sibling.home });
|
|
139
|
+
}
|
|
92
140
|
return out;
|
|
93
141
|
}
|
|
94
142
|
|
package/lib/hermes-sessions.ts
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
*
|
|
15
15
|
* PROFILES: Hermes profiles are separate home dirs, each with its OWN state.db
|
|
16
16
|
* (`~/.hermes/state.db` for the default, `~/.hermes/profiles/<name>/state.db`
|
|
17
|
-
*
|
|
18
|
-
* profiles
|
|
17
|
+
* for upstream profiles, and `~/.hermes-<name>/state.db` for sibling homes) —
|
|
18
|
+
* see lib/hermes-profiles.ts. So every read here fans out across profiles
|
|
19
|
+
* instead of assuming one DB.
|
|
19
20
|
*
|
|
20
21
|
* DB path override: set `HERMES_DB_PATH` (used by tests and to point at a copied
|
|
21
22
|
* or remote state.db) — it collapses discovery to that single file. Set
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.6
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "Observability and enforcement for AI agent harnesses. 39 built-in policies hooked into 12 of them — Claude Code, Codex, Cursor, Hermes, OpenClaw and more — blocking the tool call before it runs. Local dashboard included, no account needed.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
@@ -122,15 +122,15 @@
|
|
|
122
122
|
"browserslist": "4.28.8"
|
|
123
123
|
},
|
|
124
124
|
"optionalDependencies": {
|
|
125
|
-
"@failproofai/failproofaid-linux-x64": "1.0.6
|
|
126
|
-
"@failproofai/failproofaid-linux-arm64": "1.0.6
|
|
127
|
-
"@failproofai/failproofaid-darwin-x64": "1.0.6
|
|
128
|
-
"@failproofai/failproofaid-darwin-arm64": "1.0.6
|
|
125
|
+
"@failproofai/failproofaid-linux-x64": "1.0.6",
|
|
126
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.6",
|
|
127
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.6",
|
|
128
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.6"
|
|
129
129
|
},
|
|
130
130
|
"failproofaidBinaries": {
|
|
131
|
-
"linux-x64": "
|
|
132
|
-
"linux-arm64": "
|
|
133
|
-
"darwin-x64": "
|
|
134
|
-
"darwin-arm64": "
|
|
131
|
+
"linux-x64": "e075f24a3a0950b631979d9370b665da2c3e2920decfb917ff0831d1f17c9740",
|
|
132
|
+
"linux-arm64": "b90ce8c642f2685719f4915695615219860daf3155a9c07344cf1e10395028c3",
|
|
133
|
+
"darwin-x64": "51dd95e9b85226e4f1888c7edaa56ec4464e91eb645d39c5cb7cede16d2da2f1",
|
|
134
|
+
"darwin-arm64": "f6a1b9d63363e8805e0d72b4fa168fde661bdbbd4125b54047f7de8948ea0f39"
|
|
135
135
|
}
|
|
136
136
|
}
|