Repository navigation
feat: add --no-daemon flag and fix Windows dev server execution #879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
40e6e15
cedc019
e8f0465
265ff63
5ea96cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -134,6 +134,17 @@ export interface WizardAnswers { | |
| machineLabel?: string; | ||
| /** Record decisions only, no session transcripts. */ | ||
| noTranscripts?: boolean; | ||
| /** | ||
| * Skip daemon installation entirely. | ||
| * | ||
| * Containers, rootless environments and CI machines that cannot install a | ||
| * system service use this. Hooks are wired and policies enforced in-process; | ||
| * `daemonConfigured` is explicitly set to false so the hook path stays in | ||
| * in-process mode rather than failing closed against a socket nothing listens | ||
| * on. `--no-daemon` is not allowed on platforms where the daemon is | ||
| * unsupported (Windows) — those abort before this flag is ever read. | ||
| */ | ||
| noDaemon?: boolean; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -784,6 +795,12 @@ export async function runConfigureWizard( | |
| // single prompt is asked: completing setup anyway used to leave e.g. a | ||
| // Windows machine reading as configured while enforcing in-process with no | ||
| // fail-closed guarantee, which is worse than not being set up at all. | ||
| // | ||
| // --no-daemon is NOT an escape hatch for unsupported platforms: the platform | ||
| // gate is a hard invariant about what the binary can do, not about which | ||
| // steps the caller wants to run. A container user on Linux who cannot install | ||
| // a service is the target; a Windows host where failproofaid simply does not | ||
| // exist is a different category and keeps aborting. | ||
| if (!isDaemonSupportedPlatform()) { | ||
| stdout.write( | ||
| `failproofai requires failproofaid, its background policy daemon, which runs on\n` + | ||
|
|
@@ -872,15 +889,28 @@ export async function runConfigureWizard( | |
| * unloads before it writes. | ||
| */ | ||
| const daemonBroken = daemonState === "running" && daemonSkew === null && !daemonAnswers; | ||
| let daemonWanted = daemonSupported && !daemonAlreadyRunning; | ||
| // --no-daemon: the caller has opted out of service installation for this | ||
| // machine (containers, rootless CI, privilege-less environments). We skip | ||
| // every daemon step and leave daemonConfigured at false so the hook path | ||
| // stays in in-process mode. An already-running daemon is left untouched — | ||
| // "don't install" is not "tear down what is there". | ||
| const skipDaemon = answers.noDaemon === true; | ||
| let daemonWanted = daemonSupported && !daemonAlreadyRunning && !skipDaemon; | ||
|
Comment on lines
+897
to
+898
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Apply When a healthy daemon has an older service definition, 🤖 Prompt for AI Agents |
||
| // A healthy daemon can still be running a service definition written before | ||
| // FAILPROOFAI_CLI_CMD existed, and nothing else on the machine will ever | ||
| // rewrite it: upgrading the npm package does not touch /etc/systemd/system. | ||
| // Re-running setup is the one moment a user asks for their configuration to | ||
| // be brought up to date, so it is the moment to do it. | ||
| let daemonUnitStale = daemonAlreadyRunning && daemonServiceNeedsUpgrade(); | ||
|
|
||
| if (daemonWanted) { | ||
| if (skipDaemon && !daemonAlreadyRunning) { | ||
| // --no-daemon acknowledged: no service will be installed. Hooks will | ||
| // enforce in-process. Cloud-managed policies still work — the daemon | ||
| // is only needed for the background audit schedule and fail-closed mode. | ||
| stdout.write( | ||
| "Skipping daemon installation (--no-daemon). Hooks will enforce in-process.\n\n", | ||
| ); | ||
| } else if (daemonWanted) { | ||
| // Say what is about to happen. Nothing else. | ||
| // | ||
| // This block explained the warm-worker architecture to somebody who is | ||
|
|
@@ -910,6 +940,7 @@ export async function runConfigureWizard( | |
| stdout.write( | ||
| "\nCould not get root, so setup stopped before changing anything.\n\n" + | ||
| " Re-run once you can use sudo: failproofai config\n" + | ||
| ` Or skip daemon install: failproofai config --no-daemon\n` + | ||
| ` Check what it needs: ${daemonStatusCommand() ?? "n/a"}\n\n`, | ||
| ); | ||
| void emit("configure_aborted", { reason: "needs_root" }); | ||
|
|
@@ -1453,6 +1484,12 @@ export async function runConfigureWizard( | |
| // longer referenced by anything. Keeps the previous version for an | ||
| // offline rollback. | ||
| pruneOldDaemonBinaries(); | ||
| } else if (skipDaemon) { | ||
| // Explicitly mark daemon as NOT configured so the hook path stays in | ||
| // in-process mode rather than reading a stale daemonConfigured: true from | ||
| // a previous install and failing closed against a socket nobody is | ||
| // listening on. | ||
| setDaemonConfigured(false); | ||
| } | ||
|
|
||
| // Telemetry runs concurrently with the install (never rejects, 5s-bounded) so | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: FailproofAI/failproofai
Length of output: 15439
🏁 Script executed:
Repository: FailproofAI/failproofai
Length of output: 8973
Launch an executable, not
next.cmd, on Windows.spawnis imported from Node'schild_processmodule. On Windows,launch("dev")passesnext.cmdtospawnwithout enabling a shell. Node cannot launch.cmdfiles directly, so the development server can fail before Next.js starts.Use an executable launch path, or invoke the wrapper through
cmd.exewith correctly quoted arguments.🤖 Prompt for AI Agents
Source: Learnings