failproofai 1.0.0-beta.6 → 1.0.0-beta.7
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 +3 -3
- 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 +2 -2
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +7 -7
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +3 -3
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +3 -3
- 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/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- 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/reminder/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 +2 -2
- package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +9 -9
- 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 +10 -10
- 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.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.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.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]__06hexd0._.js +1 -1
- package/.next/standalone/.next/server/chunks/_0lxbzdq._.js +1 -1
- package/.next/standalone/.next/server/chunks/_1zuiiy3._.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]__1_a_gwn._.js → [root-of-the-server]__0c_qcgp._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0kbc9bs._.js +3 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0spkm68._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1rv-sc9._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1tyf0tc._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1u-wx42._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/_04mekdy._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0r-dsre._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0rjgfln._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0se484m._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0uz7o9y._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/{_0igtyj5._.js → _194yh9u._.js} +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1fahg9e._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1w8sola._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_1w_6p9g._.js +1 -1
- 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/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 +15 -15
- package/.next/standalone/.next/static/chunks/0945ybz3fsvba.js +1 -0
- package/.next/standalone/.next/static/chunks/{3rbpw_waieafm.js → 0gr76ps8_zm26.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0_2n13i94rnw5.js → 0m-m7wgtxdoav.js} +1 -1
- package/.next/standalone/.next/static/chunks/11l6oh9cyb35a.js +1 -0
- package/.next/standalone/.next/static/chunks/166f8qnh03jqc.js +6 -0
- package/.next/standalone/.next/static/chunks/2aej0vi1fm87m.js +1 -0
- package/.next/standalone/.next/static/chunks/{3f_939wi3kfnx.js → 2bxld6-rym3ah.js} +1 -1
- package/.next/standalone/.next/static/chunks/{3p1vpm2_-tfwm.js → 2p2kz4aj1tooj.js} +1 -1
- package/.next/standalone/.next/static/chunks/{28zkwzu50puki.js → 36pc3_8fpb6ic.js} +1 -1
- package/.next/standalone/.next/static/chunks/{34fa65k0cldkj.js → 3t1wr_kx6brwc.js} +1 -1
- package/.next/standalone/package.json +5 -5
- package/.next/standalone/server.js +1 -1
- package/bin/failproofai.mjs +25 -26
- package/dist/cli.mjs +167 -62
- package/dist/worker.mjs +1 -1
- package/package.json +5 -5
- package/src/hooks/configure-wizard.ts +54 -0
- package/src/hooks/daemon-service.ts +10 -2
- package/src/hooks/fp-home.ts +13 -0
- package/src/hooks/onboarding-attempt.ts +179 -0
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1e7-pa7._.js +0 -3
- package/.next/standalone/.next/static/chunks/23557z4e6dtsr.js +0 -1
- package/.next/standalone/.next/static/chunks/3081gykdubv8b.js +0 -1
- package/.next/standalone/.next/static/chunks/35v07j9gc1pvr.js +0 -6
- package/.next/standalone/.next/static/chunks/40ffnfpkeyvb0.js +0 -1
- /package/.next/standalone/.next/static/{Ptn8aBQl_cnNgOd0ebyv0 → LUaLkKg40nSkHrIajexIk}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{Ptn8aBQl_cnNgOd0ebyv0 → LUaLkKg40nSkHrIajexIk}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{Ptn8aBQl_cnNgOd0ebyv0 → LUaLkKg40nSkHrIajexIk}/_ssgManifest.js +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// package.json
|
|
22
|
-
var version2 = "1.0.0-beta.
|
|
22
|
+
var version2 = "1.0.0-beta.7";
|
|
23
23
|
var init_package = () => {};
|
|
24
24
|
|
|
25
25
|
// src/posthog-key.ts
|
|
@@ -1025,7 +1025,7 @@ function resettablePaths() {
|
|
|
1025
1025
|
logsDir()
|
|
1026
1026
|
];
|
|
1027
1027
|
}
|
|
1028
|
-
var LAYOUT_VERSION = 2, at = (...parts) => resolve(failproofaiHome(), ...parts), atHome = (home, ...parts) => home ? resolve(failproofaiHome(home), ...parts) : at(...parts), versionFile = (home) => atHome(home, "VERSION"), configFile = (home) => atHome(home, "config.toml"), credentialsFile = (home) => atHome(home, "credentials.toml"), binDir = (home) => atHome(home, "bin"), policiesDir = (home) => atHome(home, "policies"), localPoliciesDir = (home) => atHome(home, "policies", "local-policies"), globalPolicyConfigFile = (home) => resolve(localPoliciesDir(home), "policies-config.json"), cloudPoliciesDir = (home) => resolve(policiesDir(home), "cloud-policies"), customPoliciesDir = (home) => resolve(policiesDir(home), "custom-policies"), customAgentsDir = (home) => atHome(home, "custom-agents"), auditDir = (home) => atHome(home, "audit"), auditDashboardFile = (home) => resolve(auditDir(home), "dashboard.json"), auditCacheDir = (home) => resolve(auditDir(home), "cache"), hookActivityDir = (home) => atHome(home, "hook-activity"), runDir = (home) => atHome(home, "run"), daemonSocket = () => process.env.FAILPROOFAI_DAEMON_SOCKET || resolve(runDir(), "failproofaid.sock"), auditLockFile = (home) => resolve(runDir(home), "audit.lock"), stateDir = (home) => atHome(home, "state"), shimsDir = (home) => resolve(stateDir(home), "shims"), sessionPauseDir = () => resolve(stateDir(), "sessions"), telemetryIdFile = (home) => resolve(stateDir(home), "telemetry-id"), launcherMarker = (home) => resolve(stateDir(home), "launcher-configured"), lastVersionFile = (home) => resolve(stateDir(home), "last-version"), onboardingLockFile = (home) => resolve(stateDir(home), "onboarding.lock"), codexSessionPathsFile = (home) => resolve(stateDir(home), "codex-session-paths.json"), logsDir = (home) => atHome(home, "logs"), legacy;
|
|
1028
|
+
var LAYOUT_VERSION = 2, at = (...parts) => resolve(failproofaiHome(), ...parts), atHome = (home, ...parts) => home ? resolve(failproofaiHome(home), ...parts) : at(...parts), versionFile = (home) => atHome(home, "VERSION"), configFile = (home) => atHome(home, "config.toml"), credentialsFile = (home) => atHome(home, "credentials.toml"), binDir = (home) => atHome(home, "bin"), policiesDir = (home) => atHome(home, "policies"), localPoliciesDir = (home) => atHome(home, "policies", "local-policies"), globalPolicyConfigFile = (home) => resolve(localPoliciesDir(home), "policies-config.json"), cloudPoliciesDir = (home) => resolve(policiesDir(home), "cloud-policies"), customPoliciesDir = (home) => resolve(policiesDir(home), "custom-policies"), customAgentsDir = (home) => atHome(home, "custom-agents"), auditDir = (home) => atHome(home, "audit"), auditDashboardFile = (home) => resolve(auditDir(home), "dashboard.json"), auditCacheDir = (home) => resolve(auditDir(home), "cache"), hookActivityDir = (home) => atHome(home, "hook-activity"), runDir = (home) => atHome(home, "run"), daemonSocket = () => process.env.FAILPROOFAI_DAEMON_SOCKET || resolve(runDir(), "failproofaid.sock"), auditLockFile = (home) => resolve(runDir(home), "audit.lock"), stateDir = (home) => atHome(home, "state"), shimsDir = (home) => resolve(stateDir(home), "shims"), sessionPauseDir = () => resolve(stateDir(), "sessions"), telemetryIdFile = (home) => resolve(stateDir(home), "telemetry-id"), launcherMarker = (home) => resolve(stateDir(home), "launcher-configured"), onboardingAttemptFile = (home) => resolve(stateDir(home), "onboarding-attempt.json"), lastVersionFile = (home) => resolve(stateDir(home), "last-version"), onboardingLockFile = (home) => resolve(stateDir(home), "onboarding.lock"), codexSessionPathsFile = (home) => resolve(stateDir(home), "codex-session-paths.json"), logsDir = (home) => atHome(home, "logs"), legacy;
|
|
1029
1029
|
var init_fp_home = __esm(() => {
|
|
1030
1030
|
legacy = {
|
|
1031
1031
|
policyConfig: () => at("policies-config.json"),
|
|
@@ -22438,8 +22438,87 @@ var init_setup_state = __esm(() => {
|
|
|
22438
22438
|
init_fp_home();
|
|
22439
22439
|
});
|
|
22440
22440
|
|
|
22441
|
+
// src/hooks/onboarding-attempt.ts
|
|
22442
|
+
import { existsSync as existsSync24, mkdirSync as mkdirSync14, readFileSync as readFileSync19, rmSync as rmSync8, writeFileSync as writeFileSync11 } from "node:fs";
|
|
22443
|
+
import { dirname as dirname12 } from "node:path";
|
|
22444
|
+
function readOnboardingAttempt() {
|
|
22445
|
+
const path3 = onboardingAttemptFile();
|
|
22446
|
+
if (!existsSync24(path3))
|
|
22447
|
+
return null;
|
|
22448
|
+
try {
|
|
22449
|
+
const raw = JSON.parse(readFileSync19(path3, "utf8"));
|
|
22450
|
+
if (raw.schemaVersion !== SCHEMA_VERSION3)
|
|
22451
|
+
return null;
|
|
22452
|
+
if (typeof raw.reason !== "string" || typeof raw.cliVersion !== "string")
|
|
22453
|
+
return null;
|
|
22454
|
+
return {
|
|
22455
|
+
schemaVersion: SCHEMA_VERSION3,
|
|
22456
|
+
reason: raw.reason,
|
|
22457
|
+
cliVersion: raw.cliVersion,
|
|
22458
|
+
daemonStatus: typeof raw.daemonStatus === "string" ? raw.daemonStatus : "",
|
|
22459
|
+
at: typeof raw.at === "number" ? raw.at : 0
|
|
22460
|
+
};
|
|
22461
|
+
} catch {
|
|
22462
|
+
return null;
|
|
22463
|
+
}
|
|
22464
|
+
}
|
|
22465
|
+
function recordOnboardingAttempt(reason, cliVersion, daemonStatus, now = Date.now()) {
|
|
22466
|
+
try {
|
|
22467
|
+
const path3 = onboardingAttemptFile();
|
|
22468
|
+
mkdirSync14(dirname12(path3), { recursive: true });
|
|
22469
|
+
const record = {
|
|
22470
|
+
schemaVersion: SCHEMA_VERSION3,
|
|
22471
|
+
reason,
|
|
22472
|
+
cliVersion,
|
|
22473
|
+
daemonStatus,
|
|
22474
|
+
at: now
|
|
22475
|
+
};
|
|
22476
|
+
writeFileSync11(path3, JSON.stringify(record, null, 2), "utf8");
|
|
22477
|
+
} catch {}
|
|
22478
|
+
}
|
|
22479
|
+
function clearOnboardingAttempt() {
|
|
22480
|
+
try {
|
|
22481
|
+
rmSync8(onboardingAttemptFile(), { force: true });
|
|
22482
|
+
} catch {}
|
|
22483
|
+
}
|
|
22484
|
+
function blockerCleared(attempt, probe) {
|
|
22485
|
+
switch (attempt.reason) {
|
|
22486
|
+
case "needs_root":
|
|
22487
|
+
return probe.canElevate();
|
|
22488
|
+
case "daemon_failed":
|
|
22489
|
+
return probe.daemonStatus() !== attempt.daemonStatus || probe.canElevate();
|
|
22490
|
+
case "cancelled":
|
|
22491
|
+
return probe.cliVersion !== attempt.cliVersion;
|
|
22492
|
+
case "not_a_tty":
|
|
22493
|
+
case "running_as_sudo":
|
|
22494
|
+
return true;
|
|
22495
|
+
default:
|
|
22496
|
+
return true;
|
|
22497
|
+
}
|
|
22498
|
+
}
|
|
22499
|
+
function attemptHintLines(attempt) {
|
|
22500
|
+
const why = {
|
|
22501
|
+
needs_root: "it needs root to install the failproofaid service",
|
|
22502
|
+
daemon_failed: "the failproofaid service could not be started",
|
|
22503
|
+
cancelled: "it was cancelled",
|
|
22504
|
+
not_a_tty: "there was no terminal to ask in",
|
|
22505
|
+
running_as_sudo: "it was run under sudo"
|
|
22506
|
+
};
|
|
22507
|
+
const detail = why[attempt.reason] ?? "it did not finish";
|
|
22508
|
+
return [
|
|
22509
|
+
``,
|
|
22510
|
+
`[failproofai] Setup is not finished — ${detail}.`,
|
|
22511
|
+
` Run \`failproofai config\` when you are ready.`,
|
|
22512
|
+
``
|
|
22513
|
+
];
|
|
22514
|
+
}
|
|
22515
|
+
var SCHEMA_VERSION3 = 1;
|
|
22516
|
+
var init_onboarding_attempt = __esm(() => {
|
|
22517
|
+
init_fp_home();
|
|
22518
|
+
});
|
|
22519
|
+
|
|
22441
22520
|
// src/hooks/onboarding-lock.ts
|
|
22442
|
-
import { mkdirSync as
|
|
22521
|
+
import { mkdirSync as mkdirSync15, readFileSync as readFileSync20, rmSync as rmSync9, writeFileSync as writeFileSync12 } from "node:fs";
|
|
22443
22522
|
import { homedir as homedir26 } from "node:os";
|
|
22444
22523
|
function onboardingLockPath(home = homedir26()) {
|
|
22445
22524
|
return onboardingLockFile(home);
|
|
@@ -22456,7 +22535,7 @@ function processAlive(pid) {
|
|
|
22456
22535
|
}
|
|
22457
22536
|
function readLock(path3) {
|
|
22458
22537
|
try {
|
|
22459
|
-
const parsed = JSON.parse(
|
|
22538
|
+
const parsed = JSON.parse(readFileSync20(path3, "utf8"));
|
|
22460
22539
|
if (typeof parsed.pid !== "number")
|
|
22461
22540
|
return null;
|
|
22462
22541
|
return { pid: parsed.pid, startedAt: Number(parsed.startedAt) || 0 };
|
|
@@ -22470,9 +22549,9 @@ function acquireOnboardingLock(home = homedir26()) {
|
|
|
22470
22549
|
const held = readLock(path3);
|
|
22471
22550
|
if (held && held.pid !== process.pid && processAlive(held.pid))
|
|
22472
22551
|
return null;
|
|
22473
|
-
|
|
22552
|
+
mkdirSync15(stateDir(home), { recursive: true });
|
|
22474
22553
|
const body = { pid: process.pid, startedAt: Date.now() };
|
|
22475
|
-
|
|
22554
|
+
writeFileSync12(path3, JSON.stringify(body), "utf8");
|
|
22476
22555
|
let released = false;
|
|
22477
22556
|
return {
|
|
22478
22557
|
release() {
|
|
@@ -22482,7 +22561,7 @@ function acquireOnboardingLock(home = homedir26()) {
|
|
|
22482
22561
|
try {
|
|
22483
22562
|
const current = readLock(path3);
|
|
22484
22563
|
if (!current || current.pid === process.pid)
|
|
22485
|
-
|
|
22564
|
+
rmSync9(path3, { force: true });
|
|
22486
22565
|
} catch {}
|
|
22487
22566
|
}
|
|
22488
22567
|
};
|
|
@@ -22495,7 +22574,7 @@ var init_onboarding_lock = __esm(() => {
|
|
|
22495
22574
|
});
|
|
22496
22575
|
|
|
22497
22576
|
// lib/claude-sessions.ts
|
|
22498
|
-
import { readdirSync as readdirSync14, statSync as statSync16, existsSync as
|
|
22577
|
+
import { readdirSync as readdirSync14, statSync as statSync16, existsSync as existsSync26 } from "node:fs";
|
|
22499
22578
|
import { join as join28, basename as basename5 } from "node:path";
|
|
22500
22579
|
function getClaudeProjectsRoot() {
|
|
22501
22580
|
return getClaudeProjectsPath();
|
|
@@ -22542,7 +22621,7 @@ function listClaudeTranscripts(project) {
|
|
|
22542
22621
|
} catch {}
|
|
22543
22622
|
} else if (entry.isDirectory() && UUID_RE2.test(entry.name)) {
|
|
22544
22623
|
const subDir = join28(project.path, entry.name, "subagents");
|
|
22545
|
-
if (!
|
|
22624
|
+
if (!existsSync26(subDir))
|
|
22546
22625
|
continue;
|
|
22547
22626
|
let subEntries;
|
|
22548
22627
|
try {
|
|
@@ -23817,7 +23896,7 @@ var init_features = __esm(() => {
|
|
|
23817
23896
|
|
|
23818
23897
|
// src/audit/cache.ts
|
|
23819
23898
|
import { createHash as createHash6 } from "node:crypto";
|
|
23820
|
-
import { existsSync as
|
|
23899
|
+
import { existsSync as existsSync27, mkdirSync as mkdirSync16, readFileSync as readFileSync21, writeFileSync as writeFileSync13, chmodSync as chmodSync4 } from "node:fs";
|
|
23821
23900
|
import { join as join29 } from "node:path";
|
|
23822
23901
|
function getEngineVersion() {
|
|
23823
23902
|
if (cachedEngineVersion)
|
|
@@ -23844,10 +23923,10 @@ function readCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes) {
|
|
|
23844
23923
|
if (sizeBytes === 0)
|
|
23845
23924
|
return null;
|
|
23846
23925
|
const cachePath = getCachePathFor(transcriptPath);
|
|
23847
|
-
if (!
|
|
23926
|
+
if (!existsSync27(cachePath))
|
|
23848
23927
|
return null;
|
|
23849
23928
|
try {
|
|
23850
|
-
const raw =
|
|
23929
|
+
const raw = readFileSync21(cachePath, "utf-8");
|
|
23851
23930
|
const entry = JSON.parse(raw);
|
|
23852
23931
|
if (entry.schemaVersion !== CACHE_SCHEMA_VERSION)
|
|
23853
23932
|
return null;
|
|
@@ -23871,7 +23950,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result)
|
|
|
23871
23950
|
return;
|
|
23872
23951
|
const cachePath = getCachePathFor(transcriptPath);
|
|
23873
23952
|
try {
|
|
23874
|
-
|
|
23953
|
+
mkdirSync16(auditCacheDir(), { recursive: true });
|
|
23875
23954
|
const entry = {
|
|
23876
23955
|
schemaVersion: CACHE_SCHEMA_VERSION,
|
|
23877
23956
|
cachedAt: Date.now(),
|
|
@@ -23881,7 +23960,7 @@ function writeCachedTranscriptResult(transcriptPath, mtimeMs, sizeBytes, result)
|
|
|
23881
23960
|
detectorVersion: getDetectorVersion(),
|
|
23882
23961
|
result
|
|
23883
23962
|
};
|
|
23884
|
-
|
|
23963
|
+
writeFileSync13(cachePath, JSON.stringify(entry), { encoding: "utf-8", mode: 384 });
|
|
23885
23964
|
try {
|
|
23886
23965
|
chmodSync4(cachePath, 384);
|
|
23887
23966
|
} catch {}
|
|
@@ -24247,11 +24326,11 @@ var init_audit = __esm(() => {
|
|
|
24247
24326
|
import {
|
|
24248
24327
|
closeSync,
|
|
24249
24328
|
linkSync,
|
|
24250
|
-
mkdirSync as
|
|
24329
|
+
mkdirSync as mkdirSync17,
|
|
24251
24330
|
openSync,
|
|
24252
|
-
readFileSync as
|
|
24331
|
+
readFileSync as readFileSync22,
|
|
24253
24332
|
unlinkSync as unlinkSync4,
|
|
24254
|
-
writeFileSync as
|
|
24333
|
+
writeFileSync as writeFileSync14,
|
|
24255
24334
|
writeSync
|
|
24256
24335
|
} from "node:fs";
|
|
24257
24336
|
function acquireAuditLock(source, now = Date.now()) {
|
|
@@ -24310,7 +24389,7 @@ function handleFor(path3, info) {
|
|
|
24310
24389
|
}
|
|
24311
24390
|
function readLock2(path3) {
|
|
24312
24391
|
try {
|
|
24313
|
-
const parsed = JSON.parse(
|
|
24392
|
+
const parsed = JSON.parse(readFileSync22(path3, "utf8"));
|
|
24314
24393
|
if (typeof parsed?.pid !== "number" || typeof parsed?.startedAt !== "number")
|
|
24315
24394
|
return null;
|
|
24316
24395
|
return {
|
|
@@ -24326,7 +24405,7 @@ function writeLockExclusive(path3, info) {
|
|
|
24326
24405
|
const body = JSON.stringify(info);
|
|
24327
24406
|
const staging = `${path3}.${process.pid}.tmp`;
|
|
24328
24407
|
try {
|
|
24329
|
-
|
|
24408
|
+
writeFileSync14(staging, body, { mode: 384 });
|
|
24330
24409
|
} catch {
|
|
24331
24410
|
return false;
|
|
24332
24411
|
}
|
|
@@ -24360,8 +24439,8 @@ function createThenWrite(path3, body) {
|
|
|
24360
24439
|
}
|
|
24361
24440
|
}
|
|
24362
24441
|
function ensureRunDir() {
|
|
24363
|
-
|
|
24364
|
-
|
|
24442
|
+
mkdirSync17(failproofaiHome(), { recursive: true });
|
|
24443
|
+
mkdirSync17(runDir(), { recursive: true, mode: 448 });
|
|
24365
24444
|
}
|
|
24366
24445
|
var AUDIT_LOCK_MAX_AGE_MS;
|
|
24367
24446
|
var init_audit_lock = __esm(() => {
|
|
@@ -24525,26 +24604,26 @@ function parseScriptArgs(argv) {
|
|
|
24525
24604
|
var init_parse_script_args = () => {};
|
|
24526
24605
|
|
|
24527
24606
|
// scripts/install-diagnosis.mjs
|
|
24528
|
-
import { existsSync as
|
|
24529
|
-
import { dirname as
|
|
24607
|
+
import { existsSync as existsSync28, readFileSync as readFileSync23, realpathSync as realpathSync3 } from "node:fs";
|
|
24608
|
+
import { dirname as dirname13, resolve as resolve21 } from "node:path";
|
|
24530
24609
|
import { homedir as homedir27, platform as platform4 } from "node:os";
|
|
24531
24610
|
import { spawnSync } from "node:child_process";
|
|
24532
24611
|
function findPackageRoot(start) {
|
|
24533
24612
|
try {
|
|
24534
24613
|
let dir = realpathSync3(start);
|
|
24535
|
-
if (
|
|
24536
|
-
dir =
|
|
24614
|
+
if (existsSync28(dir) && !existsSync28(resolve21(dir, "package.json"))) {
|
|
24615
|
+
dir = dirname13(dir);
|
|
24537
24616
|
}
|
|
24538
24617
|
while (true) {
|
|
24539
24618
|
const pkgPath = resolve21(dir, "package.json");
|
|
24540
|
-
if (
|
|
24619
|
+
if (existsSync28(pkgPath)) {
|
|
24541
24620
|
try {
|
|
24542
|
-
const pkg = JSON.parse(
|
|
24621
|
+
const pkg = JSON.parse(readFileSync23(pkgPath, "utf8"));
|
|
24543
24622
|
if (pkg.name === PKG_NAME)
|
|
24544
24623
|
return dir;
|
|
24545
24624
|
} catch {}
|
|
24546
24625
|
}
|
|
24547
|
-
const parent =
|
|
24626
|
+
const parent = dirname13(dir);
|
|
24548
24627
|
if (parent === dir)
|
|
24549
24628
|
return null;
|
|
24550
24629
|
dir = parent;
|
|
@@ -24557,7 +24636,7 @@ function readPackageVersion(packageRoot) {
|
|
|
24557
24636
|
if (!packageRoot)
|
|
24558
24637
|
return null;
|
|
24559
24638
|
try {
|
|
24560
|
-
const pkg = JSON.parse(
|
|
24639
|
+
const pkg = JSON.parse(readFileSync23(resolve21(packageRoot, "package.json"), "utf8"));
|
|
24561
24640
|
return typeof pkg.version === "string" ? pkg.version : null;
|
|
24562
24641
|
} catch {
|
|
24563
24642
|
return null;
|
|
@@ -24584,7 +24663,7 @@ function locateNpmGlobal() {
|
|
|
24584
24663
|
if (!root)
|
|
24585
24664
|
return null;
|
|
24586
24665
|
const candidate = resolve21(root, PKG_NAME);
|
|
24587
|
-
return
|
|
24666
|
+
return existsSync28(resolve21(candidate, "package.json")) ? candidate : null;
|
|
24588
24667
|
} catch {
|
|
24589
24668
|
return null;
|
|
24590
24669
|
}
|
|
@@ -24592,7 +24671,7 @@ function locateNpmGlobal() {
|
|
|
24592
24671
|
function locateBunGlobal() {
|
|
24593
24672
|
try {
|
|
24594
24673
|
const candidate = resolve21(homedir27(), ".bun", "install", "global", "node_modules", PKG_NAME);
|
|
24595
|
-
return
|
|
24674
|
+
return existsSync28(resolve21(candidate, "package.json")) ? candidate : null;
|
|
24596
24675
|
} catch {
|
|
24597
24676
|
return null;
|
|
24598
24677
|
}
|
|
@@ -24699,8 +24778,8 @@ __export(exports_launch, {
|
|
|
24699
24778
|
launch: () => launch
|
|
24700
24779
|
});
|
|
24701
24780
|
import { spawn as spawn2 } from "child_process";
|
|
24702
|
-
import { realpathSync as realpathSync4, existsSync as
|
|
24703
|
-
import { resolve as resolve22, dirname as
|
|
24781
|
+
import { realpathSync as realpathSync4, existsSync as existsSync29 } from "node:fs";
|
|
24782
|
+
import { resolve as resolve22, dirname as dirname14 } from "node:path";
|
|
24704
24783
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24705
24784
|
import { createInterface } from "node:readline";
|
|
24706
24785
|
function launch(mode) {
|
|
@@ -24724,9 +24803,9 @@ function launch(mode) {
|
|
|
24724
24803
|
process.env.PORT = port;
|
|
24725
24804
|
process.env.HOSTNAME = bindHost;
|
|
24726
24805
|
cmd = "node";
|
|
24727
|
-
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve22(
|
|
24806
|
+
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve22(dirname14(realpathSync4(fileURLToPath2(import.meta.url))), "..");
|
|
24728
24807
|
const serverJsPath = resolve22(packageRoot, ".next/standalone/server.js");
|
|
24729
|
-
if (!
|
|
24808
|
+
if (!existsSync29(serverJsPath)) {
|
|
24730
24809
|
let shadowMessage = null;
|
|
24731
24810
|
try {
|
|
24732
24811
|
const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
|
|
@@ -25171,9 +25250,9 @@ __export(exports_configure_wizard, {
|
|
|
25171
25250
|
buildPresetChoices: () => buildPresetChoices,
|
|
25172
25251
|
buildAgentChoices: () => buildAgentChoices
|
|
25173
25252
|
});
|
|
25174
|
-
import { existsSync as
|
|
25253
|
+
import { existsSync as existsSync30, mkdirSync as mkdirSync18, writeFileSync as writeFileSync15, readFileSync as readFileSync24 } from "node:fs";
|
|
25175
25254
|
import { homedir as homedir28 } from "node:os";
|
|
25176
|
-
import { dirname as
|
|
25255
|
+
import { dirname as dirname15, resolve as resolve23, sep as sep5 } from "node:path";
|
|
25177
25256
|
async function emit(event, props) {
|
|
25178
25257
|
try {
|
|
25179
25258
|
await trackHookEvent2(getInstanceId2(), event, props);
|
|
@@ -25280,8 +25359,8 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
|
|
|
25280
25359
|
const path3 = getConfigPathForScope(scope, cwd);
|
|
25281
25360
|
let config = {};
|
|
25282
25361
|
try {
|
|
25283
|
-
if (
|
|
25284
|
-
config = JSON.parse(
|
|
25362
|
+
if (existsSync30(path3))
|
|
25363
|
+
config = JSON.parse(readFileSync24(path3, "utf8"));
|
|
25285
25364
|
} catch {
|
|
25286
25365
|
return;
|
|
25287
25366
|
}
|
|
@@ -25290,7 +25369,7 @@ function setCustomPoliciesEnabled(scope, cwd, enabled) {
|
|
|
25290
25369
|
else
|
|
25291
25370
|
config.customPoliciesEnabled = false;
|
|
25292
25371
|
try {
|
|
25293
|
-
|
|
25372
|
+
writeFileSync15(path3, JSON.stringify(config, null, 2) + `
|
|
25294
25373
|
`, "utf8");
|
|
25295
25374
|
} catch {}
|
|
25296
25375
|
}
|
|
@@ -25390,14 +25469,33 @@ function firstRunMarkerPath() {
|
|
|
25390
25469
|
return launcherMarker();
|
|
25391
25470
|
}
|
|
25392
25471
|
function hasSeenLauncher() {
|
|
25393
|
-
return
|
|
25472
|
+
return existsSync30(firstRunMarkerPath());
|
|
25394
25473
|
}
|
|
25395
25474
|
function markLauncherSeen() {
|
|
25396
25475
|
try {
|
|
25397
|
-
|
|
25398
|
-
|
|
25476
|
+
mkdirSync18(dirname15(firstRunMarkerPath()), { recursive: true });
|
|
25477
|
+
writeFileSync15(firstRunMarkerPath(), "1", "utf8");
|
|
25399
25478
|
} catch {}
|
|
25400
25479
|
}
|
|
25480
|
+
function retryProbe() {
|
|
25481
|
+
return {
|
|
25482
|
+
canElevate: () => {
|
|
25483
|
+
try {
|
|
25484
|
+
return canElevate();
|
|
25485
|
+
} catch {
|
|
25486
|
+
return false;
|
|
25487
|
+
}
|
|
25488
|
+
},
|
|
25489
|
+
daemonStatus: () => {
|
|
25490
|
+
try {
|
|
25491
|
+
return daemonServiceStatus();
|
|
25492
|
+
} catch {
|
|
25493
|
+
return "";
|
|
25494
|
+
}
|
|
25495
|
+
},
|
|
25496
|
+
cliVersion: version2
|
|
25497
|
+
};
|
|
25498
|
+
}
|
|
25401
25499
|
async function maybeFirstRunConfigure(io = {}, opts = {}) {
|
|
25402
25500
|
if (process.env.FAILPROOFAI_NO_FIRST_RUN === "1")
|
|
25403
25501
|
return false;
|
|
@@ -25409,6 +25507,13 @@ async function maybeFirstRunConfigure(io = {}, opts = {}) {
|
|
|
25409
25507
|
markLauncherSeen();
|
|
25410
25508
|
return false;
|
|
25411
25509
|
}
|
|
25510
|
+
const attempt = opts.force ? null : readOnboardingAttempt();
|
|
25511
|
+
if (attempt && !blockerCleared(attempt, retryProbe())) {
|
|
25512
|
+
for (const line of attemptHintLines(attempt))
|
|
25513
|
+
stdout.write(`${line}
|
|
25514
|
+
`);
|
|
25515
|
+
return false;
|
|
25516
|
+
}
|
|
25412
25517
|
if (!stdin.isTTY || !stdout.isTTY) {
|
|
25413
25518
|
stdout.write(`
|
|
25414
25519
|
[failproofai] Not set up yet — run \`failproofai config\` to get started.
|
|
@@ -25427,6 +25532,9 @@ async function maybeFirstRunConfigure(io = {}, opts = {}) {
|
|
|
25427
25532
|
try {
|
|
25428
25533
|
emit("first_run_configure_shown", {});
|
|
25429
25534
|
const result = await runConfigureWizard(io);
|
|
25535
|
+
if (!result.applied && result.abort) {
|
|
25536
|
+
recordOnboardingAttempt(result.abort, version2, daemonServiceStatus());
|
|
25537
|
+
}
|
|
25430
25538
|
if (result.applied && opts.postSetupAudit !== false) {
|
|
25431
25539
|
try {
|
|
25432
25540
|
const { runPostSetupAudit: runPostSetupAudit2 } = await Promise.resolve().then(() => (init_cli(), exports_cli));
|
|
@@ -25850,6 +25958,7 @@ Hooks keep enforcing; scheduled audits stay off until it is.
|
|
|
25850
25958
|
}
|
|
25851
25959
|
await applied;
|
|
25852
25960
|
markLauncherSeen();
|
|
25961
|
+
clearOnboardingAttempt();
|
|
25853
25962
|
const customNote = customEnabled === true ? " + your custom policies" : customEnabled === false ? " · custom policies DISABLED" : "";
|
|
25854
25963
|
const daemonNote = daemonInstalled ? " · daemon on" : "";
|
|
25855
25964
|
const cloudNote = connected ? " · reporting on" : "";
|
|
@@ -25885,6 +25994,7 @@ var init_configure_wizard = __esm(() => {
|
|
|
25885
25994
|
init_fp_home();
|
|
25886
25995
|
init_daemon_download();
|
|
25887
25996
|
init_package();
|
|
25997
|
+
init_onboarding_attempt();
|
|
25888
25998
|
init_onboarding_lock();
|
|
25889
25999
|
});
|
|
25890
26000
|
|
|
@@ -25898,7 +26008,7 @@ __export(exports_manager, {
|
|
|
25898
26008
|
getSettingsPath: () => getSettingsPath2
|
|
25899
26009
|
});
|
|
25900
26010
|
import { execSync as execSync7 } from "node:child_process";
|
|
25901
|
-
import { existsSync as
|
|
26011
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
25902
26012
|
import { resolve as resolve24, basename as basename6 } from "node:path";
|
|
25903
26013
|
import { platform as platform5, arch as arch4, release as release3, hostname as hostname5 } from "node:os";
|
|
25904
26014
|
function getSettingsPath2(scope, cwd) {
|
|
@@ -26009,7 +26119,7 @@ async function installHooksImpl2(policyNames, scope = "user", cwd, includeBeta =
|
|
|
26009
26119
|
} else if (customPoliciesPath && (typeof customPoliciesPath === "string" || customPoliciesPath.length > 0)) {
|
|
26010
26120
|
const incoming = (typeof customPoliciesPath === "string" ? [customPoliciesPath] : customPoliciesPath).map((path3) => resolve24(path3));
|
|
26011
26121
|
const carried = (previousConfig.customPoliciesPaths ?? (previousConfig.customPoliciesPath ? [previousConfig.customPoliciesPath] : [])).map((path3) => resolve24(path3)).filter((path3) => {
|
|
26012
|
-
if (
|
|
26122
|
+
if (existsSync31(path3))
|
|
26013
26123
|
return true;
|
|
26014
26124
|
console.log(`Dropping custom policies path (file no longer exists): ${path3}`);
|
|
26015
26125
|
return false;
|
|
@@ -26201,7 +26311,7 @@ async function removeHooks(policyNames, scope = "user", cwd, opts) {
|
|
|
26201
26311
|
const scopesToRemove = scope === "all" ? [...integration.scopes] : integration.scopes.includes(scope) ? [scope] : [];
|
|
26202
26312
|
for (const s of scopesToRemove) {
|
|
26203
26313
|
const settingsPaths = settingsPathsFor(integration, s, cwd);
|
|
26204
|
-
const existing = settingsPaths.filter((p) =>
|
|
26314
|
+
const existing = settingsPaths.filter((p) => existsSync31(p));
|
|
26205
26315
|
if (existing.length === 0) {
|
|
26206
26316
|
if (scope !== "all" && selectedClis.length === 1) {
|
|
26207
26317
|
console.log("No settings file found. Nothing to remove.");
|
|
@@ -26402,7 +26512,7 @@ Failproof AI Hook Policies
|
|
|
26402
26512
|
for (const path3 of explicitPaths) {
|
|
26403
26513
|
const absPath = resolve24(findProjectConfigDir(cwd ?? process.cwd()), path3);
|
|
26404
26514
|
console.log(` ${absPath}`);
|
|
26405
|
-
if (!
|
|
26515
|
+
if (!existsSync31(absPath)) {
|
|
26406
26516
|
console.log(` \x1B[31m✗ File not found: ${absPath}\x1B[0m`);
|
|
26407
26517
|
continue;
|
|
26408
26518
|
}
|
|
@@ -27537,8 +27647,8 @@ __export(exports_launch2, {
|
|
|
27537
27647
|
launch: () => launch2
|
|
27538
27648
|
});
|
|
27539
27649
|
import { spawn as spawn3 } from "child_process";
|
|
27540
|
-
import { realpathSync as realpathSync5, existsSync as
|
|
27541
|
-
import { resolve as resolve25, dirname as
|
|
27650
|
+
import { realpathSync as realpathSync5, existsSync as existsSync32 } from "node:fs";
|
|
27651
|
+
import { resolve as resolve25, dirname as dirname16 } from "node:path";
|
|
27542
27652
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
27543
27653
|
import { createInterface as createInterface2 } from "node:readline";
|
|
27544
27654
|
function launch2(mode) {
|
|
@@ -27562,9 +27672,9 @@ function launch2(mode) {
|
|
|
27562
27672
|
process.env.PORT = port;
|
|
27563
27673
|
process.env.HOSTNAME = bindHost;
|
|
27564
27674
|
cmd = "node";
|
|
27565
|
-
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve25(
|
|
27675
|
+
const packageRoot = process.env.FAILPROOFAI_PACKAGE_ROOT ?? resolve25(dirname16(realpathSync5(fileURLToPath3(import.meta.url))), "..");
|
|
27566
27676
|
const serverJsPath = resolve25(packageRoot, ".next/standalone/server.js");
|
|
27567
|
-
if (!
|
|
27677
|
+
if (!existsSync32(serverJsPath)) {
|
|
27568
27678
|
let shadowMessage = null;
|
|
27569
27679
|
try {
|
|
27570
27680
|
const diag = diagnoseShadow({ selfPackageRoot: packageRoot, selfVersion: version2 });
|
|
@@ -27661,17 +27771,17 @@ var init_cli_error2 = __esm(() => {
|
|
|
27661
27771
|
|
|
27662
27772
|
// bin/failproofai.mjs
|
|
27663
27773
|
import { realpathSync as realpathSync6 } from "fs";
|
|
27664
|
-
import { dirname as
|
|
27774
|
+
import { dirname as dirname17, resolve as resolve26 } from "path";
|
|
27665
27775
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
27666
27776
|
// package.json
|
|
27667
|
-
var version = "1.0.0-beta.
|
|
27777
|
+
var version = "1.0.0-beta.7";
|
|
27668
27778
|
|
|
27669
27779
|
// bin/failproofai.mjs
|
|
27670
27780
|
if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
|
|
27671
|
-
process.env.FAILPROOFAI_PACKAGE_ROOT = resolve26(
|
|
27781
|
+
process.env.FAILPROOFAI_PACKAGE_ROOT = resolve26(dirname17(realpathSync6(fileURLToPath4(import.meta.url))), "..");
|
|
27672
27782
|
}
|
|
27673
27783
|
if (!process.env.FAILPROOFAI_DIST_PATH) {
|
|
27674
|
-
process.env.FAILPROOFAI_DIST_PATH = resolve26(
|
|
27784
|
+
process.env.FAILPROOFAI_DIST_PATH = resolve26(dirname17(realpathSync6(fileURLToPath4(import.meta.url))), "..", "dist");
|
|
27675
27785
|
}
|
|
27676
27786
|
var args = process.argv.slice(2);
|
|
27677
27787
|
if (args[0] === "p")
|
|
@@ -27731,15 +27841,10 @@ if (hookIdx >= 0) {
|
|
|
27731
27841
|
let result;
|
|
27732
27842
|
if (attempt.ok) {
|
|
27733
27843
|
result = attempt.response;
|
|
27734
|
-
} else if (attempt.failure === "protocol-mismatch") {
|
|
27735
|
-
console.error("[failproofai] failproofaid speaks a different protocol version than this CLI \u2014 " + "evaluating in-process instead (slower, identical policies). Run `failproofai config` to update the daemon.");
|
|
27736
|
-
result = await evaluateHookEvent2(eventType, cli, stdinRead.payload);
|
|
27737
27844
|
} else {
|
|
27845
|
+
const reason = attempt.failure === "protocol-mismatch" ? "failproofaid is running a different protocol version than this CLI, so it cannot evaluate this call. Run `failproofai config` to update the daemon." : "failproofaid could not be reached. This machine is configured to run hooks through it " + "\u2014 check the daemon (see `failproofai config`) rather than retrying blindly.";
|
|
27738
27846
|
result = await evaluateHookEvent2(eventType, cli, stdinRead.payload, {
|
|
27739
|
-
forceDecision: {
|
|
27740
|
-
decision: "deny",
|
|
27741
|
-
reason: "failproofaid could not be reached. This machine is configured to run hooks through it " + "\u2014 check the daemon (see `failproofai config`) rather than retrying blindly."
|
|
27742
|
-
}
|
|
27847
|
+
forceDecision: { decision: "deny", reason }
|
|
27743
27848
|
});
|
|
27744
27849
|
}
|
|
27745
27850
|
if (result.stdout)
|
package/dist/worker.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "failproofai",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.7",
|
|
4
4
|
"description": "The easiest way to manage policies that keep your AI agents reliable, on-task, and running autonomously — for Claude Code & the Agents SDK",
|
|
5
5
|
"bin": {
|
|
6
6
|
"failproofai": "./dist/cli.mjs",
|
|
@@ -114,9 +114,9 @@
|
|
|
114
114
|
"sharp": "0.35.0"
|
|
115
115
|
},
|
|
116
116
|
"optionalDependencies": {
|
|
117
|
-
"@failproofai/failproofaid-linux-x64": "1.0.0-beta.
|
|
118
|
-
"@failproofai/failproofaid-linux-arm64": "1.0.0-beta.
|
|
119
|
-
"@failproofai/failproofaid-darwin-x64": "1.0.0-beta.
|
|
120
|
-
"@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.
|
|
117
|
+
"@failproofai/failproofaid-linux-x64": "1.0.0-beta.7",
|
|
118
|
+
"@failproofai/failproofaid-linux-arm64": "1.0.0-beta.7",
|
|
119
|
+
"@failproofai/failproofaid-darwin-x64": "1.0.0-beta.7",
|
|
120
|
+
"@failproofai/failproofaid-darwin-arm64": "1.0.0-beta.7"
|
|
121
121
|
}
|
|
122
122
|
}
|
|
@@ -61,6 +61,7 @@ import { discoverPolicyFiles, findSkippedPolicyFiles } from "./custom-hooks-load
|
|
|
61
61
|
import { trackHookEvent } from "./hook-telemetry";
|
|
62
62
|
import { getInstanceId } from "../../lib/telemetry-id";
|
|
63
63
|
import {
|
|
64
|
+
canElevate,
|
|
64
65
|
isDaemonSupportedPlatform,
|
|
65
66
|
installDaemonService,
|
|
66
67
|
daemonServiceFilePath,
|
|
@@ -99,6 +100,14 @@ import {
|
|
|
99
100
|
import { customPoliciesDir, launcherMarker } from "./fp-home";
|
|
100
101
|
import { pruneOldDaemonBinaries } from "./daemon-download";
|
|
101
102
|
import { version as cliVersion } from "../../package.json";
|
|
103
|
+
import {
|
|
104
|
+
attemptHintLines,
|
|
105
|
+
blockerCleared,
|
|
106
|
+
clearOnboardingAttempt,
|
|
107
|
+
readOnboardingAttempt,
|
|
108
|
+
recordOnboardingAttempt,
|
|
109
|
+
type RetryProbe,
|
|
110
|
+
} from "./onboarding-attempt";
|
|
102
111
|
import { acquireOnboardingLock } from "./onboarding-lock";
|
|
103
112
|
|
|
104
113
|
export interface WizardIO {
|
|
@@ -552,6 +561,33 @@ export interface FirstRunOptions {
|
|
|
552
561
|
force?: boolean;
|
|
553
562
|
}
|
|
554
563
|
|
|
564
|
+
/**
|
|
565
|
+
* The live values `blockerCleared` compares an earlier attempt against.
|
|
566
|
+
*
|
|
567
|
+
* Built here rather than imported into `onboarding-attempt.ts` so that module
|
|
568
|
+
* stays pure and unit-testable without a service manager or a sudo binary.
|
|
569
|
+
*/
|
|
570
|
+
function retryProbe(): RetryProbe {
|
|
571
|
+
return {
|
|
572
|
+
canElevate: () => {
|
|
573
|
+
try {
|
|
574
|
+
return canElevate();
|
|
575
|
+
} catch {
|
|
576
|
+
// No sudo binary at all is a blocker that has not cleared.
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
daemonStatus: () => {
|
|
581
|
+
try {
|
|
582
|
+
return daemonServiceStatus();
|
|
583
|
+
} catch {
|
|
584
|
+
return "";
|
|
585
|
+
}
|
|
586
|
+
},
|
|
587
|
+
cliVersion,
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
|
|
555
591
|
export async function maybeFirstRunConfigure(
|
|
556
592
|
io: WizardIO = {},
|
|
557
593
|
opts: FirstRunOptions = {},
|
|
@@ -572,6 +608,17 @@ export async function maybeFirstRunConfigure(
|
|
|
572
608
|
return false;
|
|
573
609
|
}
|
|
574
610
|
|
|
611
|
+
// A previous attempt that ABORTED. Setup writes nothing on those paths, by
|
|
612
|
+
// design, so without this record the machine is indistinguishable from one
|
|
613
|
+
// that has never been offered setup — and the wizard relaunches on every
|
|
614
|
+
// command forever. `--force` (an explicit `failproofai config`) never reaches
|
|
615
|
+
// here, so asking for setup by name always gets it.
|
|
616
|
+
const attempt = opts.force ? null : readOnboardingAttempt();
|
|
617
|
+
if (attempt && !blockerCleared(attempt, retryProbe())) {
|
|
618
|
+
for (const line of attemptHintLines(attempt)) stdout.write(`${line}\n`);
|
|
619
|
+
return false;
|
|
620
|
+
}
|
|
621
|
+
|
|
575
622
|
if (!stdin.isTTY || !stdout.isTTY) {
|
|
576
623
|
// Never launch a wizard nobody can answer. This is the CI / piped path,
|
|
577
624
|
// and it must stay a hint rather than a failure: the command the user
|
|
@@ -600,6 +647,11 @@ export async function maybeFirstRunConfigure(
|
|
|
600
647
|
// an apply — so cancelling keeps offering setup on the next run rather
|
|
601
648
|
// than silently never mentioning it again.
|
|
602
649
|
const result = await runConfigureWizard(io);
|
|
650
|
+
// Remember WHY, so the next command can hint instead of relaunching. Only
|
|
651
|
+
// on an abort: a completed apply clears the record below.
|
|
652
|
+
if (!result.applied && result.abort) {
|
|
653
|
+
recordOnboardingAttempt(result.abort, cliVersion, daemonServiceStatus());
|
|
654
|
+
}
|
|
603
655
|
|
|
604
656
|
// Onboarding-only: after a completed first-run setup, run the audit pipeline
|
|
605
657
|
// (scan + cache warm) before the caller boots the dashboard. The explicit
|
|
@@ -1306,6 +1358,8 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
1306
1358
|
// Only now — a completed apply — is the launcher considered "seen", so
|
|
1307
1359
|
// first-run onboarding stops offering itself on every command.
|
|
1308
1360
|
markLauncherSeen();
|
|
1361
|
+
// And any record of an earlier failure is now false: this machine got set up.
|
|
1362
|
+
clearOnboardingAttempt();
|
|
1309
1363
|
|
|
1310
1364
|
// Keep this inside a standard 80-column terminal. `writeLines` truncates with
|
|
1311
1365
|
// a hard cut and no ellipsis, so an over-long line doesn't just lose its tail
|
|
@@ -450,8 +450,16 @@ export function primeElevation(): boolean {
|
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
|
|
453
|
-
/**
|
|
454
|
-
|
|
453
|
+
/**
|
|
454
|
+
* True when privileged commands can run without prompting for a password.
|
|
455
|
+
*
|
|
456
|
+
* Exported because onboarding re-checks it: `needs_root` is the most common
|
|
457
|
+
* reason setup aborts, and it is the one most likely to stop being true (the
|
|
458
|
+
* user gets sudo rights, or primes their timestamp in another terminal). One
|
|
459
|
+
* `sudo -n true`, no prompt, milliseconds — and never on the hook path, which
|
|
460
|
+
* does not reach the first-run gate at all.
|
|
461
|
+
*/
|
|
462
|
+
export function canElevate(): boolean {
|
|
455
463
|
if (typeof process.getuid === "function" && process.getuid() === 0) return true;
|
|
456
464
|
try {
|
|
457
465
|
execFileSync("sudo", ["-n", "true"], { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
|