@fomular-os/daemon
v0.2.11
Published
FomularOS daemon — connects machines to the FomularOS server and manages AI agents
Downloads
1,316
Maintainers
Readme
@fomular-os/daemon
Daemon process that connects a machine to the FomularOS server and manages AI agents (Claude Code instances).
Quick Start
npx @fomular-os/daemon --server-url wss://api.fomularos.com --key <your-machine-api-key>Install globally
npm install -g @fomular-os/daemon
fomular-daemon --server-url wss://api.fomularos.com --key <your-machine-api-key>User-prefix install (no-root fallback)
When the daemon runs as a non-root service user without write access to the
global npm prefix, in-place daemon:update falls back automatically to a
user-local install under ~/.fomular. The daemon:update:result message
reports mode: "user-prefix" so operators can confirm which install path was
used. To put the user-prefix binary on PATH for manual invocation, add:
export PATH="$HOME/.fomular/bin:$PATH"Supervisor (systemd/pm2) unit files should prefer the absolute path
$HOME/.fomular/bin/fomular-daemon when the service runs under a dedicated
account.
In-place update & self-relaunch (bare daemon)
On a successful daemon:update, the daemon double-forks a detached child
process with the same argv/env/cwd captured at startup, then exits (via the
existing 500 ms delay). The reported daemon:update:result.restart_strategy
disambiguates the two outcomes:
| restart_strategy | Meaning |
|------------------|---------|
| self | Detached relaunch spawned successfully — the new daemon process inherits the machine registration and reconnects to the server. |
| supervisor_required | Relaunch skipped or failed — the parent still exits, and an external supervisor (systemd/pm2) is expected to start a fresh process. |
Assumes the standard npm install layout (either global -g or user-prefix),
where the bin name resolves via symlink to dist/index.js and npm install
atomically replaces the target before the daemon re-execs. No wrapper script
is required.
Opting out under an external supervisor
If systemd or pm2 already manages the daemon lifecycle, self-relaunch would race with supervisor-managed restart. Set:
FOMULAR_DAEMON_NO_SELF_RELAUNCH=1The daemon then always reports restart_strategy: "supervisor_required" and
falls back to "exit, let the supervisor restart me" semantics. Recommended
for all non-bare deployments.
systemd unit (sample)
[Unit]
Description=FomularOS daemon
After=network-online.target
[Service]
Type=simple
User=fomular
ExecStart=/home/fomular/.fomular/bin/fomular-daemon \
--server-url wss://api.fomularos.com \
--key ${MACHINE_KEY}
Environment=MACHINE_KEY=...
Environment=FOMULAR_DAEMON_NO_SELF_RELAUNCH=1
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.targetpm2 ecosystem (sample)
// ecosystem.config.js
module.exports = {
apps: [
{
name: "fomular-daemon",
script: "/home/fomular/.fomular/bin/fomular-daemon",
args: "--server-url wss://api.fomularos.com --key $MACHINE_KEY",
env: {
FOMULAR_DAEMON_NO_SELF_RELAUNCH: "1",
},
autorestart: true,
max_restarts: 50,
},
],
};Bare deployment (no supervisor)
Launch once from a login shell or startup script — leave
FOMULAR_DAEMON_NO_SELF_RELAUNCH unset. The daemon will keep itself alive
across daemon:update cycles without an external watchdog.
Options
| Flag | Description | Default |
|------|-------------|---------|
| --server-url <url> | WebSocket URL of the FomularOS server | ws://localhost:3001 |
| --key <key> | Machine API key (required) | — |
Requirements
- Node.js >= 18
- Claude Code CLI installed and configured
What it does
- Connects to the FomularOS server via WebSocket
- Receives agent start/stop commands from the server
- Spawns and manages Claude Code processes for each agent
- Streams agent activity (thinking, tool use, messages) back to the server
- Handles graceful shutdown of all agents on SIGTERM/SIGINT
Publishing
cd packages/daemon
npm login # login to npm (once)
npm publish --access publicAfter publishing, verify:
npx @fomular-os/daemon --help