Security-first, local-first AI runtime with undoable actions, channel adapters, and SWARM workflows.
Everything the AI does is recorded and can be undone.
☁️ Want to skip the setup? Use Undoable Cloud and get started instantly.
- What Undoable Is
- Core Guarantees
- Requirements
- Install
- First Run
- 24/7 Operation
- UI and API Endpoints
- CLI Overview
- Settings Console (UI + CLI)
- Undo and Redo
- SWARM Workflows
- Skills
- Channels and Pairing
- Economy Mode and Spend Controls
- Media Reliability (Images and Audio)
- Configuration
- Manual Setup from Source
- Docker Operations
- Troubleshooting
- Development
- Project Layout
- Security
- License
Undoable is an agent runtime for people who want real execution power without losing control.
Core loop:
PLAN -> EXECUTE -> REVIEW -> APPLY -> UNDO
Undoable includes:
- A daemon API and tool runtime
- A web UI for chat, history, undo/redo, skills, channels, and SWARM/canvas
- A CLI (
nrn, aliasundoable) for onboarding, operations, and diagnostics - Persistent local state in
~/.undoable
Undo Guarantee (strict mode) is on by default.
- Every tool call is recorded
- Undoable mutations are restorable via undo/redo
- Non-undoable mutate/exec actions are blocked in strict mode
- You can switch to power mode (allow irreversible actions) when needed
Important scope boundary:
- File edits and supported tool mutations can be undone
- External side effects (for example third-party APIs, sent messages, remote systems) may not be fully reversible
- Use
undo(action:"list")/nrn undo listto inspectrecordedCount,undoable,redoable, andnonUndoableRecent
- Node.js
>=22.0.0 - pnpm
>=10 - PostgreSQL
16+(native mode) - Docker + Docker Compose (docker mode)
pnpm build enforces the Node minimum and exits early with a clear message if your version is too old.
curl -fsSL https://undoable.xyz/install.sh | bashThis installer:
- Installs prerequisites when needed (Node, pnpm, Git, PostgreSQL)
- Clones/updates the repository
- Builds project artifacts
- Bootstraps built-in skills into
~/.undoable/skills - Creates CLI wrappers:
undoable,nrn,undoable-daemon,undoable-dev - Applies DB schema unless
--skip-db
curl -fsSL https://undoable.xyz/install.sh | bash -s -- --dockerThis installer:
- Clones/updates the repository
- Builds and starts Docker services
- Applies DB schema in daemon container
- Persists Undoable home (including skills) in Docker volume
undoable-home
curl -fsSL https://undoable.xyz/install.sh | bash -s -- --helpCommon options:
--docker--git-dir <path>(or--dir <path>)--no-git-update--skip-db--dry-run--verbose
undoable start
# or
nrn startundoable start --economyundoable start --no-ui
# or
undoable-daemonFor long-running production usage, use one of these modes:
- Docker mode (
restart: unless-stopped) for server deployments - Native daemon supervisor mode (
nrn daemon start) for local/VM installs
Native daemon lifecycle:
nrn daemon start
nrn daemon status
nrn daemon mode
nrn daemon stopNotes:
nrn daemon startnow runs in supervised mode by default and auto-restarts after crashes- Use
nrn daemon start --no-superviseonly if you explicitly want direct unmanaged mode nrn daemon mode normal|drain|pausedlets you temporarily block new runs without stopping the daemon- Daemon logs are written to
~/.undoable/logs/daemon.log - Health endpoint remains
http://127.0.0.1:7433/health(or your configured port)
OS service lifecycle (recommended for native 24/7):
nrn daemon service install --port 7433
nrn daemon service status
nrn daemon service restart
nrn daemon service uninstall- macOS: uses
launchduser agent - Linux: uses
systemd --userunit - Service install expects built artifacts (
pnpm build) so it can rundist/daemon/index.mjs - On Linux, enable linger for true logout-proof 24/7 operation:
sudo loginctl enable-linger "$USER"undoable-devundoable onboard
# or
nrn onboard
# one-command guided defaults
nrn quickstart- UI:
http://localhost:5173 - API:
http://localhost:7433 - Health:
http://localhost:7433/health
Show all commands:
nrn --helpMain command groups:
setup,quickstart,onboard,start,status,doctor,daemonchat,agent,swarm,run,undoplan,shadow,apply,verify,receipt,stream,settingschannels,pairing,config,plugin
Useful daemon lifecycle commands:
nrn daemon start
nrn daemon status
nrn daemon mode paused --reason "maintenance"
nrn daemon mode normal
nrn daemon stopInteractive terminal chat:
nrn chat --economyInside chat:
/help/status/sessions/economy on|off|status/thinking on|off/abort
Undoable now has a standalone settings console at:
- UI route:
http://localhost:5173/settings - Sidebar: click
Settingsto open the full page (not modal)
Sections include Runtime, Advanced, Gateway, Config Console, Models, API Keys, Undo, Voice, and Browser.
Gateway section supports editing daemon profile values:
- bind mode (
loopback|all|custom) - host
- port
- auth mode (
open|token) + token rotate - security policy (
strict|balanced|permissive)
When a gateway change needs restart, UI shows restart required.
CLI parity:
nrn settings status
nrn settings set --preset economy
nrn settings daemon status
nrn settings daemon set --bind loopback --auth token --rotate-token
nrn settings daemon set --port 7433 --security strictCLI:
nrn undo list
nrn undo last 2
nrn undo one <action-id>
nrn undo allTool API (undo tool) supports:
listonelastallredo_oneredo_lastredo_all
redo_one can run without an id and auto-select the most recent redoable action.
Undoable supports multi-node SWARM workflows with editable nodes and edges.
CLI examples:
nrn swarm list
nrn swarm create --name "sdr-automation"
nrn swarm add-node <workflowId> --name source --prompt "Collect new leads"
nrn swarm add-node <workflowId> --name outreach --prompt "Send welcome email"
nrn swarm link <workflowId> --from <sourceNodeId> --to <outreachNodeId>Canvas and SWARM views in UI are for visual design, run tracing, and node-level edits.
Built-in skills are bootstrapped by installer/startup:
githubweb-search
Skill sources discovered by daemon include:
~/.undoable/skills~/.codex/skills~/.claude/skills~/.cursor/skills~/.cursor/skills-cursor~/.windsurf/skills~/.codeium/windsurf/skills~/.opencode/skills
If CLI-detected installed skills do not show as cards yet, use Skills Refresh and check local skill directories.
Current channel adapters:
telegramdiscordslackwhatsapp
Status/probe/capabilities/logs/resolve surfaces:
nrn channels status --details
nrn channels probe --channel telegram
nrn channels capabilities
nrn channels logs --channel slack --limit 100
nrn channels resolve --channel discord "#sales" "@owner"Pairing approval lifecycle:
nrn pairing list
nrn pairing approve --channel telegram --code ABC123
nrn pairing reject --request-id <id>
nrn pairing revoke --channel telegram --user-id <user-id>Economy mode is optional and off by default.
When enabled, Undoable reduces token usage by tightening runtime budgets and context policies while preserving core functionality.
Runtime controls:
- UI header toggle (
Economy) nrn start --economynrn chat --economy/economy on|off|statusin chat
Budget guardrails (rolling 24h):
UNDOABLE_DAILY_BUDGET_USDUNDOABLE_DAILY_BUDGET_AUTO_PAUSE
Defaults:
- Request body limit:
32MB(UNDOABLE_BODY_LIMIT_MB) - Attachment limit:
10MB(UNDOABLE_ATTACHMENT_MAX_MB) - STT audio limit:
20MB(UNDOABLE_STT_MAX_AUDIO_MB)
If uploads fail with 413:
- Increase
UNDOABLE_BODY_LIMIT_MB - Optionally increase
UNDOABLE_ATTACHMENT_MAX_MBandUNDOABLE_STT_MAX_AUDIO_MB - Restart daemon
Copy and edit:
cp .env.example .envMinimal required:
# macOS local default
DATABASE_URL=postgresql://localhost:5432/undoable
# Linux bootstrap default
# DATABASE_URL=postgresql://undoable:undoable_dev@localhost:5432/undoable
OPENAI_API_KEY=sk-...DATABASE_URL should include an explicit username (postgresql://user[:password]@host:port/db).
If username is omitted, the Postgres driver can fall back to your OS user and fail authentication.
Common server/runtime:
NRN_PORT=7433
NODE_ENV=development
UNDOABLE_ALLOW_IRREVERSIBLE_ACTIONS=0Provider keys (any one is enough to start):
OPENAI_API_KEYANTHROPIC_API_KEYGOOGLE_API_KEYDEEPSEEK_API_KEYGROQ_API_KEY
Voice keys (optional):
ELEVENLABS_API_KEYDEEPGRAM_API_KEY
Channel keys (optional):
WHATSAPP_PHONE_IDWHATSAPP_TOKENTELEGRAM_BOT_TOKENDISCORD_BOT_TOKENSLACK_BOT_TOKEN
git clone https://github.com/neurana/undoable.git
cd undoable
pnpm install
cp .env.example .envApply schema and run:
pnpm db:push
pnpm devBuild production artifacts:
pnpm build
pnpm startFrom repository root:
cd docker
./start.sh --buildOther operations:
./start.sh --check
./start.sh --logs
./start.sh --down
./start.sh --dev
./start.sh --help- Click Skills
Refresh - Confirm entries with Skills CLI panel (
list) - Check skill folders under supported directories listed in Skills
- Increase
UNDOABLE_BODY_LIMIT_MB - For voice/images also verify
UNDOABLE_STT_MAX_AUDIO_MBandUNDOABLE_ATTACHMENT_MAX_MB - Restart daemon
- Keep strict mode for safest behavior
- If you intentionally need irreversible actions, enable them in run settings or set:
UNDOABLE_ALLOW_IRREVERSIBLE_ACTIONS=1- Validate
DATABASE_URL - Run
pnpm db:push - Check daemon logs for DB initialization warnings
cd docker
./start.sh --check
./start.sh --down
./start.sh --build- Run
node -v - Install/activate Node
22+ - Retry
pnpm build
- Run
nrn daemon status - Inspect
~/.undoable/logs/daemon.log - Restart cleanly:
nrn daemon stop
nrn daemon startpnpm install
pnpm lint
pnpm test
pnpm buildDatabase helpers:
pnpm db:push
pnpm db:generate
pnpm db:migrate
pnpm db:studiopackages/
core/ # runtime engine, scheduler, undo primitives
daemon/ # API routes, services, tool runtime
cli/ # terminal command surface
shared/ # shared types/utilities
ui/ # web UI (Lit + Vite)
docker/ # compose files and launcher
install.sh # one-line installer
Undoable can execute commands, read/write files, and call external systems. Use least privilege and approvals for sensitive workflows.
Recommended posture:
- Keep
Undo Guaranteestrict by default - Keep approvals on for mutation-heavy workflows
- Use sandboxing/isolation where possible
- Review third-party skills before enabling
Find me on X/Twitter: @BrunoHenri52285
MIT