failproofai 1.0.0-beta.1 → 1.0.0-beta.2
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/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 +9 -9
- 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/chunks/[root-of-the-server]__0id_xf7._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__19120tr._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1fwl2mz._.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__1myjm-d._.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]__0114ewg._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__02r5bgf._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0e8sjqm._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0lkzqax._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1yo1gyz._.js → [root-of-the-server]__0nb0syg._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0qucxyj._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__0u02miy._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__170799-._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1ath6v_._.js +2 -2
- package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__1ig795d._.js → [root-of-the-server]__1psjybo._.js} +2 -2
- package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__1zqz4v8._.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/{node_modules_html-to-image_es_index_14q3-7b.js → node_modules_html-to-image_es_index_0oy_-36.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 +11 -11
- package/.next/standalone/.next/static/chunks/{07ix3lb4gib0x.js → 0fi645si-uiiq.js} +1 -1
- package/.next/standalone/.next/static/chunks/{191njgoik03fm.js → 18rvdw5v72364.js} +1 -1
- package/.next/standalone/.next/static/chunks/{2ovmv4esqalpb.js → 2j94uwkb4s3qr.js} +1 -1
- package/.next/standalone/.next/static/chunks/{35584kn409ad1.js → 2sbelanzvxvv0.js} +1 -1
- package/.next/standalone/.next/static/chunks/{24gs8ip6_spcb.js → 31feojxhjyjpl.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1b3a1scouf40o.js → 3hp8ulqknybil.js} +1 -1
- package/.next/standalone/.next/static/chunks/{1d71o1_tav721.js → 3s7myk_co0gbh.js} +1 -1
- package/.next/standalone/.next/static/chunks/{30is-6r00sbd7.js → 3vs4ay36tjds_.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0fdx7ikab08-g.js → 40k1_v4os4cw6.js} +1 -1
- package/.next/standalone/Cargo.lock +2 -2
- package/.next/standalone/Cargo.toml +1 -1
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/dist/cli.mjs +113 -30
- package/dist/worker.mjs +1 -1
- package/package.json +1 -1
- package/src/hooks/configure-wizard.ts +87 -13
- package/src/hooks/daemon-service.ts +125 -24
- /package/.next/standalone/.next/static/{avJMC2AXvrg13Pbm4QH8F → NWAjs0tHFyzk97gRGG09r}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{avJMC2AXvrg13Pbm4QH8F → NWAjs0tHFyzk97gRGG09r}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{avJMC2AXvrg13Pbm4QH8F → NWAjs0tHFyzk97gRGG09r}/_ssgManifest.js +0 -0
|
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
|
|
|
9
9
|
const hostname = process.env.HOSTNAME || '0.0.0.0'
|
|
10
10
|
|
|
11
11
|
let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
|
|
12
|
-
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.0-beta.
|
|
12
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"1.0.0-beta.2"},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/failproofai/failproofai","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"*":["node_modules/@img/**","node_modules/sharp/**"]},"turbopack":{"root":"/home/runner/work/failproofai/failproofai"},"distDirRoot":".next"}
|
|
13
13
|
|
|
14
14
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
15
15
|
|
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.2";
|
|
23
23
|
var init_package = () => {};
|
|
24
24
|
|
|
25
25
|
// src/posthog-key.ts
|
|
@@ -22763,7 +22763,15 @@ var init_daemon_download = __esm(() => {
|
|
|
22763
22763
|
});
|
|
22764
22764
|
|
|
22765
22765
|
// src/hooks/daemon-service.ts
|
|
22766
|
-
import {
|
|
22766
|
+
import {
|
|
22767
|
+
existsSync as existsSync21,
|
|
22768
|
+
mkdirSync as mkdirSync11,
|
|
22769
|
+
mkdtempSync,
|
|
22770
|
+
readFileSync as readFileSync16,
|
|
22771
|
+
writeFileSync as writeFileSync10,
|
|
22772
|
+
unlinkSync as unlinkSync3,
|
|
22773
|
+
rmSync as rmSync4
|
|
22774
|
+
} from "node:fs";
|
|
22767
22775
|
import { homedir as homedir32, tmpdir, userInfo } from "node:os";
|
|
22768
22776
|
import { resolve as resolve19, dirname as dirname9 } from "node:path";
|
|
22769
22777
|
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
@@ -22834,7 +22842,10 @@ function resolveWorkerCommand() {
|
|
|
22834
22842
|
const workerScript = resolve19(packageRoot, "dist", "worker.mjs");
|
|
22835
22843
|
if (!existsSync21(workerScript))
|
|
22836
22844
|
return null;
|
|
22837
|
-
return `${process.execPath} ${workerScript}`;
|
|
22845
|
+
return `${shellQuote(process.execPath)} ${shellQuote(workerScript)}`;
|
|
22846
|
+
}
|
|
22847
|
+
function shellQuote(value) {
|
|
22848
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
22838
22849
|
}
|
|
22839
22850
|
function serviceUser() {
|
|
22840
22851
|
return userInfo().username;
|
|
@@ -22848,17 +22859,35 @@ function systemdUnitPath(user = serviceUser()) {
|
|
|
22848
22859
|
function legacySystemdUserUnitPath() {
|
|
22849
22860
|
return resolve19(homedir32(), ".config", "systemd", "user", "failproofaid.service");
|
|
22850
22861
|
}
|
|
22851
|
-
function
|
|
22852
|
-
return
|
|
22862
|
+
function launchdLabel(user = serviceUser()) {
|
|
22863
|
+
return `ai.failproof.failproofaid.${user}`;
|
|
22864
|
+
}
|
|
22865
|
+
function launchdPlistPath(user = serviceUser()) {
|
|
22866
|
+
return `/Library/LaunchDaemons/${launchdLabel(user)}.plist`;
|
|
22853
22867
|
}
|
|
22854
22868
|
function legacyLaunchAgentPlistPath() {
|
|
22855
|
-
return resolve19(homedir32(), "Library", "LaunchAgents",
|
|
22869
|
+
return resolve19(homedir32(), "Library", "LaunchAgents", "ai.failproof.failproofaid.plist");
|
|
22870
|
+
}
|
|
22871
|
+
function legacySharedLaunchDaemonPath() {
|
|
22872
|
+
return "/Library/LaunchDaemons/ai.failproof.failproofaid.plist";
|
|
22856
22873
|
}
|
|
22857
22874
|
function daemonServiceFilePath() {
|
|
22858
22875
|
if (!isDaemonSupportedPlatform())
|
|
22859
22876
|
return null;
|
|
22860
22877
|
return process.platform === "linux" ? systemdUnitPath() : launchdPlistPath();
|
|
22861
22878
|
}
|
|
22879
|
+
function primeElevation() {
|
|
22880
|
+
if (typeof process.getuid === "function" && process.getuid() === 0)
|
|
22881
|
+
return true;
|
|
22882
|
+
if (canElevate())
|
|
22883
|
+
return true;
|
|
22884
|
+
try {
|
|
22885
|
+
execFileSync4("sudo", ["-v"], { stdio: "inherit", timeout: SUDO_PROMPT_TIMEOUT_MS });
|
|
22886
|
+
return canElevate();
|
|
22887
|
+
} catch {
|
|
22888
|
+
return false;
|
|
22889
|
+
}
|
|
22890
|
+
}
|
|
22862
22891
|
function canElevate() {
|
|
22863
22892
|
if (typeof process.getuid === "function" && process.getuid() === 0)
|
|
22864
22893
|
return true;
|
|
@@ -22875,12 +22904,13 @@ function runPrivileged(command, args) {
|
|
|
22875
22904
|
execFileSync4(cmd, argv, { stdio: "ignore", timeout: SERVICE_CMD_TIMEOUT_MS });
|
|
22876
22905
|
}
|
|
22877
22906
|
function writePrivilegedFile(destination, contents, mode = "0644") {
|
|
22878
|
-
const
|
|
22907
|
+
const stagingDir = mkdtempSync(resolve19(tmpdir(), "failproofaid-stage-"));
|
|
22908
|
+
const staging = resolve19(stagingDir, "service-definition");
|
|
22879
22909
|
try {
|
|
22880
22910
|
writeFileSync10(staging, contents, "utf8");
|
|
22881
22911
|
runPrivileged("install", ["-m", mode, staging, destination]);
|
|
22882
22912
|
} finally {
|
|
22883
|
-
rmSync4(
|
|
22913
|
+
rmSync4(stagingDir, { recursive: true, force: true });
|
|
22884
22914
|
}
|
|
22885
22915
|
}
|
|
22886
22916
|
function removeLegacyUserService() {
|
|
@@ -22903,16 +22933,23 @@ function removeLegacyUserService() {
|
|
|
22903
22933
|
});
|
|
22904
22934
|
} catch {}
|
|
22905
22935
|
} else {
|
|
22906
|
-
const
|
|
22907
|
-
if (
|
|
22908
|
-
|
|
22909
|
-
|
|
22910
|
-
|
|
22911
|
-
|
|
22912
|
-
|
|
22913
|
-
}
|
|
22914
|
-
|
|
22915
|
-
|
|
22936
|
+
const legacyAgent = legacyLaunchAgentPlistPath();
|
|
22937
|
+
if (existsSync21(legacyAgent)) {
|
|
22938
|
+
try {
|
|
22939
|
+
execFileSync4("launchctl", ["unload", "-w", legacyAgent], {
|
|
22940
|
+
stdio: "ignore",
|
|
22941
|
+
timeout: SERVICE_CMD_TIMEOUT_MS
|
|
22942
|
+
});
|
|
22943
|
+
} catch {}
|
|
22944
|
+
unlinkSync3(legacyAgent);
|
|
22945
|
+
}
|
|
22946
|
+
const legacyDaemon = legacySharedLaunchDaemonPath();
|
|
22947
|
+
if (existsSync21(legacyDaemon)) {
|
|
22948
|
+
try {
|
|
22949
|
+
runPrivileged("launchctl", ["unload", "-w", legacyDaemon]);
|
|
22950
|
+
} catch {}
|
|
22951
|
+
runPrivileged("rm", ["-f", legacyDaemon]);
|
|
22952
|
+
}
|
|
22916
22953
|
}
|
|
22917
22954
|
} catch (err) {
|
|
22918
22955
|
hookLogWarn(`could not remove the legacy user-scope daemon: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -22960,7 +22997,7 @@ function launchdPlistContents(binaryPath, logDir2, workerCmd) {
|
|
|
22960
22997
|
<plist version="1.0">
|
|
22961
22998
|
<dict>
|
|
22962
22999
|
<key>Label</key>
|
|
22963
|
-
<string>${
|
|
23000
|
+
<string>${escapeXml(launchdLabel())}</string>
|
|
22964
23001
|
<key>ProgramArguments</key>
|
|
22965
23002
|
<array>
|
|
22966
23003
|
<string>${escapeXml(binaryPath)}</string>
|
|
@@ -23009,7 +23046,7 @@ async function installDaemonService() {
|
|
|
23009
23046
|
if (!canElevate()) {
|
|
23010
23047
|
return {
|
|
23011
23048
|
installed: false,
|
|
23012
|
-
reason: "root privileges are required to install the failproofaid system service, and sudo
|
|
23049
|
+
reason: "root privileges are required to install the failproofaid system service, and sudo credentials were not available. " + "Re-run `failproofai config` and approve the sudo prompt — do NOT run the CLI itself under sudo, which would " + "configure root's account instead of yours. To install by hand: " + daemonInstallCommands(binaryPath, workerCmd).join(" && ")
|
|
23013
23050
|
};
|
|
23014
23051
|
}
|
|
23015
23052
|
removeLegacyUserService();
|
|
@@ -23073,7 +23110,7 @@ function daemonServiceStatus() {
|
|
|
23073
23110
|
return "not-installed";
|
|
23074
23111
|
try {
|
|
23075
23112
|
const root = typeof process.getuid === "function" && process.getuid() === 0;
|
|
23076
|
-
const args = ["print", `system/${
|
|
23113
|
+
const args = ["print", `system/${launchdLabel()}`];
|
|
23077
23114
|
const out = root ? execFileSync4("launchctl", args, {
|
|
23078
23115
|
stdio: ["ignore", "pipe", "ignore"],
|
|
23079
23116
|
timeout: SERVICE_CMD_TIMEOUT_MS
|
|
@@ -23086,7 +23123,7 @@ function daemonServiceStatus() {
|
|
|
23086
23123
|
return "stopped";
|
|
23087
23124
|
}
|
|
23088
23125
|
}
|
|
23089
|
-
var SERVICE_CMD_TIMEOUT_MS = 1e4, SERVICE_START_TIMEOUT_MS = 5000, SERVICE_START_POLL_MS = 100, SERVICE_SETTLE_MS = 750,
|
|
23126
|
+
var SERVICE_CMD_TIMEOUT_MS = 1e4, SERVICE_START_TIMEOUT_MS = 5000, SERVICE_START_POLL_MS = 100, SERVICE_SETTLE_MS = 750, SUDO_PROMPT_TIMEOUT_MS = 120000;
|
|
23090
23127
|
var init_daemon_service = __esm(() => {
|
|
23091
23128
|
init_hook_logger();
|
|
23092
23129
|
init_hooks_config();
|
|
@@ -23565,15 +23602,15 @@ function describeCustomPolicies(cwd) {
|
|
|
23565
23602
|
return { active, warnings, fileCount, scopes };
|
|
23566
23603
|
}
|
|
23567
23604
|
function reviewLines(state) {
|
|
23568
|
-
const { scope, clis, policies, cwd, customEnabled } = state;
|
|
23605
|
+
const { scope, clis, policies, cwd, customEnabled, installDaemon } = state;
|
|
23569
23606
|
const where = scope === "project" ? `This project (${homeify(cwd)})` : "Everywhere (global)";
|
|
23570
23607
|
const lines = [];
|
|
23571
23608
|
const assistantNames = clis.map((c3) => getIntegration(c3).displayName);
|
|
23572
23609
|
lines.push(` Where : ${where}`);
|
|
23573
23610
|
lines.push(` Assistants : ${assistantNames.length ? summarize(assistantNames, "assistants") : "(none)"}`);
|
|
23574
23611
|
lines.push(` Policies : ${policies.length} enabled`);
|
|
23575
|
-
if (
|
|
23576
|
-
lines.push(` Daemon : failproofaid
|
|
23612
|
+
if (installDaemon && isDaemonSupportedPlatform()) {
|
|
23613
|
+
lines.push(` Daemon : failproofaid, installed as a system service running as you`);
|
|
23577
23614
|
}
|
|
23578
23615
|
const custom = describeCustomPolicies(cwd);
|
|
23579
23616
|
if (custom.active.length > 0) {
|
|
@@ -23590,10 +23627,10 @@ function reviewLines(state) {
|
|
|
23590
23627
|
}
|
|
23591
23628
|
}
|
|
23592
23629
|
lines.push(` ${homeify(getConfigPathForScope(scope, cwd))} ${policies.length} policies`);
|
|
23593
|
-
if (
|
|
23630
|
+
if (installDaemon && isDaemonSupportedPlatform()) {
|
|
23594
23631
|
const servicePath = daemonServiceFilePath();
|
|
23595
23632
|
if (servicePath)
|
|
23596
|
-
lines.push(` ${homeify(servicePath)} failproofaid service`);
|
|
23633
|
+
lines.push(` ${homeify(servicePath)} failproofaid service (needs root)`);
|
|
23597
23634
|
}
|
|
23598
23635
|
return lines;
|
|
23599
23636
|
}
|
|
@@ -23654,6 +23691,15 @@ async function runConfigureWizard(io = {}) {
|
|
|
23654
23691
|
stdout.write(`failproofai config needs an interactive terminal.
|
|
23655
23692
|
Use the flag form instead, e.g.:
|
|
23656
23693
|
failproofai policies --install --scope user --cli claude
|
|
23694
|
+
`);
|
|
23695
|
+
return { applied: false };
|
|
23696
|
+
}
|
|
23697
|
+
if (typeof process.getuid === "function" && process.getuid() === 0 && process.env.SUDO_USER) {
|
|
23698
|
+
stdout.write(`Run failproofai config as ${process.env.SUDO_USER}, not under sudo.
|
|
23699
|
+
` + `Everything it configures is per-user — hooks, policies and the daemon's own
|
|
23700
|
+
` + `account — so under sudo it would set all of that up for root instead of you.
|
|
23701
|
+
` + `The one step that needs root (installing the service) asks for your password
|
|
23702
|
+
on its own.
|
|
23657
23703
|
`);
|
|
23658
23704
|
return { applied: false };
|
|
23659
23705
|
}
|
|
@@ -23663,6 +23709,43 @@ Use the flag form instead, e.g.:
|
|
|
23663
23709
|
outro("Cancelled — nothing was changed.", { ok: false }, stdout);
|
|
23664
23710
|
return { applied: false };
|
|
23665
23711
|
};
|
|
23712
|
+
let daemonWanted = false;
|
|
23713
|
+
let elevated = false;
|
|
23714
|
+
if (isDaemonSupportedPlatform()) {
|
|
23715
|
+
const choice = await selectOne({
|
|
23716
|
+
message: "Install the failproofaid background daemon?",
|
|
23717
|
+
choices: [
|
|
23718
|
+
{
|
|
23719
|
+
label: "Yes — keep policy evaluation warm",
|
|
23720
|
+
value: "install",
|
|
23721
|
+
hint: "a system service, started at boot, running as you · needs your password once"
|
|
23722
|
+
},
|
|
23723
|
+
{
|
|
23724
|
+
label: "Not now",
|
|
23725
|
+
value: "skip",
|
|
23726
|
+
hint: "policies still enforce, evaluated per hook call"
|
|
23727
|
+
}
|
|
23728
|
+
],
|
|
23729
|
+
stdin,
|
|
23730
|
+
stdout
|
|
23731
|
+
});
|
|
23732
|
+
if (choice === null)
|
|
23733
|
+
return cancel();
|
|
23734
|
+
daemonWanted = choice === "install";
|
|
23735
|
+
if (daemonWanted) {
|
|
23736
|
+
stdout.write(`
|
|
23737
|
+
Installing the failproofaid service needs root. Your password stays with sudo.
|
|
23738
|
+
`);
|
|
23739
|
+
elevated = primeElevation();
|
|
23740
|
+
if (!elevated) {
|
|
23741
|
+
stdout.write(`Could not get sudo — carrying on without the daemon.
|
|
23742
|
+
` + `Everything else still applies, and policies still enforce in-process.
|
|
23743
|
+
|
|
23744
|
+
`);
|
|
23745
|
+
daemonWanted = false;
|
|
23746
|
+
}
|
|
23747
|
+
}
|
|
23748
|
+
}
|
|
23666
23749
|
const scope = await selectOne({
|
|
23667
23750
|
message: "Where should this apply?",
|
|
23668
23751
|
choices: buildScopeChoices(cwd),
|
|
@@ -23710,7 +23793,7 @@ Use the flag form instead, e.g.:
|
|
|
23710
23793
|
const customEnabled = hasCustomFiles ? presets.includes(CUSTOM) : undefined;
|
|
23711
23794
|
const decision = await selectOne({
|
|
23712
23795
|
message: "Ready to apply?",
|
|
23713
|
-
body: reviewLines({ scope, clis, policies, cwd, customEnabled }),
|
|
23796
|
+
body: reviewLines({ scope, clis, policies, cwd, customEnabled, installDaemon: daemonWanted }),
|
|
23714
23797
|
choices: [
|
|
23715
23798
|
{ label: "Yes, apply now", value: "apply", hint: "write the config" },
|
|
23716
23799
|
{ label: "Cancel", value: "cancel", hint: "quit, no changes" }
|
|
@@ -23730,7 +23813,7 @@ Use the flag form instead, e.g.:
|
|
|
23730
23813
|
await installHooks2(policies, scope, cwd, false, "configure-wizard", undefined, false, clis, { replace: true, quiet: true });
|
|
23731
23814
|
setCustomPoliciesEnabled(scope, cwd, customEnabled);
|
|
23732
23815
|
let daemonInstalled = false;
|
|
23733
|
-
if (
|
|
23816
|
+
if (daemonWanted) {
|
|
23734
23817
|
const daemonResult = await installDaemonService();
|
|
23735
23818
|
if (daemonResult.installed) {
|
|
23736
23819
|
setDaemonConfigured(true);
|
|
@@ -23889,7 +23972,7 @@ import { realpathSync as realpathSync4 } from "fs";
|
|
|
23889
23972
|
import { dirname as dirname11, resolve as resolve22 } from "path";
|
|
23890
23973
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
23891
23974
|
// package.json
|
|
23892
|
-
var version = "1.0.0-beta.
|
|
23975
|
+
var version = "1.0.0-beta.2";
|
|
23893
23976
|
|
|
23894
23977
|
// bin/failproofai.mjs
|
|
23895
23978
|
if (!process.env.FAILPROOFAI_PACKAGE_ROOT) {
|
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.2",
|
|
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",
|
|
@@ -43,6 +43,7 @@ import {
|
|
|
43
43
|
isDaemonSupportedPlatform,
|
|
44
44
|
installDaemonService,
|
|
45
45
|
daemonServiceFilePath,
|
|
46
|
+
primeElevation,
|
|
46
47
|
setDaemonConfigured,
|
|
47
48
|
} from "./daemon-service";
|
|
48
49
|
import { hookLogWarn } from "./hook-logger";
|
|
@@ -350,8 +351,14 @@ export function reviewLines(state: {
|
|
|
350
351
|
cwd: string;
|
|
351
352
|
/** The Custom checkbox. `undefined` = nothing to toggle, leave as-is. */
|
|
352
353
|
customEnabled?: boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Step 0's answer. The daemon is machine-level, so this is a decision the
|
|
356
|
+
* user made explicitly rather than something inferred from the scope —
|
|
357
|
+
* showing it any other way would promise a service the apply won't install.
|
|
358
|
+
*/
|
|
359
|
+
installDaemon?: boolean;
|
|
353
360
|
}): string[] {
|
|
354
|
-
const { scope, clis, policies, cwd, customEnabled } = state;
|
|
361
|
+
const { scope, clis, policies, cwd, customEnabled, installDaemon } = state;
|
|
355
362
|
const where =
|
|
356
363
|
scope === "project" ? `This project (${homeify(cwd)})` : "Everywhere (global)";
|
|
357
364
|
const lines: string[] = [];
|
|
@@ -359,9 +366,9 @@ export function reviewLines(state: {
|
|
|
359
366
|
lines.push(` Where : ${where}`);
|
|
360
367
|
lines.push(` Assistants : ${assistantNames.length ? summarize(assistantNames, "assistants") : "(none)"}`);
|
|
361
368
|
lines.push(` Policies : ${policies.length} enabled`);
|
|
362
|
-
if (
|
|
369
|
+
if (installDaemon && isDaemonSupportedPlatform()) {
|
|
363
370
|
lines.push(
|
|
364
|
-
` Daemon : failproofaid
|
|
371
|
+
` Daemon : failproofaid, installed as a system service running as you`,
|
|
365
372
|
);
|
|
366
373
|
}
|
|
367
374
|
|
|
@@ -389,9 +396,9 @@ export function reviewLines(state: {
|
|
|
389
396
|
}
|
|
390
397
|
}
|
|
391
398
|
lines.push(` ${homeify(getConfigPathForScope(scope, cwd))} ${policies.length} policies`);
|
|
392
|
-
if (
|
|
399
|
+
if (installDaemon && isDaemonSupportedPlatform()) {
|
|
393
400
|
const servicePath = daemonServiceFilePath();
|
|
394
|
-
if (servicePath) lines.push(` ${homeify(servicePath)} failproofaid service`);
|
|
401
|
+
if (servicePath) lines.push(` ${homeify(servicePath)} failproofaid service (needs root)`);
|
|
395
402
|
}
|
|
396
403
|
return lines;
|
|
397
404
|
}
|
|
@@ -500,6 +507,24 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
500
507
|
return { applied: false };
|
|
501
508
|
}
|
|
502
509
|
|
|
510
|
+
// Running the wizard itself under sudo configures the WRONG ACCOUNT, and
|
|
511
|
+
// does it silently: homedir() becomes /root, so the hooks land in root's
|
|
512
|
+
// settings, `daemonConfigured` is set for root, the daemon binary downloads
|
|
513
|
+
// to /root/.failproofai/bin, and the unit is generated with User=root —
|
|
514
|
+
// exactly the elevation the design exists to avoid. SUDO_USER is set only
|
|
515
|
+
// when a real user sudo'd here, which distinguishes this mistake from a
|
|
516
|
+
// legitimately root-only environment (a container that has no other user).
|
|
517
|
+
if (typeof process.getuid === "function" && process.getuid() === 0 && process.env.SUDO_USER) {
|
|
518
|
+
stdout.write(
|
|
519
|
+
`Run failproofai config as ${process.env.SUDO_USER}, not under sudo.\n` +
|
|
520
|
+
"Everything it configures is per-user — hooks, policies and the daemon's own\n" +
|
|
521
|
+
"account — so under sudo it would set all of that up for root instead of you.\n" +
|
|
522
|
+
"The one step that needs root (installing the service) asks for your password\n" +
|
|
523
|
+
"on its own.\n",
|
|
524
|
+
);
|
|
525
|
+
return { applied: false };
|
|
526
|
+
}
|
|
527
|
+
|
|
503
528
|
// Fire-and-forget: never block the wizard's first paint on telemetry.
|
|
504
529
|
void emit("configure_started", {});
|
|
505
530
|
intro("let's set up your safety net", stdout);
|
|
@@ -509,6 +534,55 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
509
534
|
return { applied: false };
|
|
510
535
|
};
|
|
511
536
|
|
|
537
|
+
// 0 — The background daemon, before anything else.
|
|
538
|
+
//
|
|
539
|
+
// First because it is the only step that needs a password: asking here
|
|
540
|
+
// means sudo prompts on a clean terminal, before any question has drawn a
|
|
541
|
+
// screen, instead of firing from underneath a rendered TUI where the prompt
|
|
542
|
+
// is invisible and the typed password lands in a redrawn frame. `sudo -v`
|
|
543
|
+
// caches the credential for the rest of the run, so the actual install at
|
|
544
|
+
// apply time stays non-interactive.
|
|
545
|
+
//
|
|
546
|
+
// Machine-level, so it is deliberately NOT gated on the scope chosen in the
|
|
547
|
+
// next step: one daemon serves every project on this machine.
|
|
548
|
+
let daemonWanted = false;
|
|
549
|
+
let elevated = false;
|
|
550
|
+
if (isDaemonSupportedPlatform()) {
|
|
551
|
+
const choice = await selectOne<"install" | "skip">({
|
|
552
|
+
message: "Install the failproofaid background daemon?",
|
|
553
|
+
choices: [
|
|
554
|
+
{
|
|
555
|
+
label: "Yes — keep policy evaluation warm",
|
|
556
|
+
value: "install",
|
|
557
|
+
hint: "a system service, started at boot, running as you · needs your password once",
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
label: "Not now",
|
|
561
|
+
value: "skip",
|
|
562
|
+
hint: "policies still enforce, evaluated per hook call",
|
|
563
|
+
},
|
|
564
|
+
],
|
|
565
|
+
stdin,
|
|
566
|
+
stdout,
|
|
567
|
+
});
|
|
568
|
+
if (choice === null) return cancel();
|
|
569
|
+
daemonWanted = choice === "install";
|
|
570
|
+
|
|
571
|
+
if (daemonWanted) {
|
|
572
|
+
stdout.write("\nInstalling the failproofaid service needs root. Your password stays with sudo.\n");
|
|
573
|
+
elevated = primeElevation();
|
|
574
|
+
if (!elevated) {
|
|
575
|
+
// Never fatal: the rest of setup is worth applying, and a machine with
|
|
576
|
+
// no daemon is exactly the machine every release before this one had.
|
|
577
|
+
stdout.write(
|
|
578
|
+
"Could not get sudo — carrying on without the daemon.\n" +
|
|
579
|
+
"Everything else still applies, and policies still enforce in-process.\n\n",
|
|
580
|
+
);
|
|
581
|
+
daemonWanted = false;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
512
586
|
// 1 — Where?
|
|
513
587
|
const scope = await selectOne<HookScope>({
|
|
514
588
|
message: "Where should this apply?",
|
|
@@ -579,7 +653,7 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
579
653
|
// 4 — Review & apply
|
|
580
654
|
const decision = await selectOne<"apply" | "cancel">({
|
|
581
655
|
message: "Ready to apply?",
|
|
582
|
-
body: reviewLines({ scope, clis, policies, cwd, customEnabled }),
|
|
656
|
+
body: reviewLines({ scope, clis, policies, cwd, customEnabled, installDaemon: daemonWanted }),
|
|
583
657
|
choices: [
|
|
584
658
|
{ label: "Yes, apply now", value: "apply", hint: "write the config" },
|
|
585
659
|
{ label: "Cancel", value: "cancel", hint: "quit, no changes" },
|
|
@@ -615,14 +689,14 @@ export async function runConfigureWizard(io: WizardIO = {}): Promise<WizardResul
|
|
|
615
689
|
);
|
|
616
690
|
setCustomPoliciesEnabled(scope, cwd, customEnabled);
|
|
617
691
|
|
|
618
|
-
// Daemon setup —
|
|
619
|
-
//
|
|
620
|
-
//
|
|
621
|
-
//
|
|
622
|
-
//
|
|
623
|
-
//
|
|
692
|
+
// Daemon setup — driven by step 0's answer, with the sudo credential it
|
|
693
|
+
// already primed, so nothing here can stop to ask a question. A failure
|
|
694
|
+
// (binary download blocked, no service manager, a daemon that won't stay
|
|
695
|
+
// up) never fails the wizard: the rest of setup already applied, and this
|
|
696
|
+
// machine simply stays on the in-process path, since `daemonConfigured` is
|
|
697
|
+
// only set on success.
|
|
624
698
|
let daemonInstalled = false;
|
|
625
|
-
if (
|
|
699
|
+
if (daemonWanted) {
|
|
626
700
|
const daemonResult = await installDaemonService();
|
|
627
701
|
if (daemonResult.installed) {
|
|
628
702
|
setDaemonConfigured(true);
|