Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --- Build: pass | Tests: pass — Tests 414 passed | 10 skipped (424) |
||
|---|---|---|
| .agent/skills | ||
| .github | ||
| .web-staging | ||
| assets | ||
| bootstrap | ||
| config-examples | ||
| docs | ||
| examples/astro-cv | ||
| groups | ||
| hooks | ||
| html | ||
| infra | ||
| jail | ||
| launchd | ||
| repo-tokens | ||
| scripts | ||
| setup | ||
| skills-engine | ||
| src | ||
| .env.example | ||
| .gitignore | ||
| .mcp.json | ||
| .nvmrc | ||
| .prettierrc | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| CONTRIBUTORS.md | ||
| LICENSE | ||
| package-lock.json | ||
| package.json | ||
| README-CLAWDIE.md | ||
| README.md | ||
| README_zh.md | ||
| RELEASE-0.3.0.md | ||
| setup.sh | ||
| start-clawdie.sh | ||
| stop-clawdie.sh | ||
| tsconfig.json | ||
| vitest.config.ts | ||
🦞 Clawdie
Personal AI Assistant on FreeBSD
A lean, secure AI assistant running on FreeBSD 15 with native jail isolation.
Documentation • Website • Codeberg • Discord
38.4k tokens · 19% of context window • built-in knowledge · preloaded
Overview
Clawdie is a FreeBSD-first personal AI assistant with a host-side Node.js orchestrator and jailed agent execution. The core repo stays small, Telegram is built in, and additional channels or integrations are added through skills instead of being hard-wired into core.
Current Release
v0.6.0 — FreeBSD Runtime Unification
Highlights:
- FreeBSD-native onboarding on current
main - assistant-first identity with derived
AGENT_NAME - split-brain PostgreSQL bootstrap is now mandatory
cmsjail is now a first-class setup path- internal naming moved to
home.arpaby default - public and internal domains are now separated
- Stripe is built into core runtime and can be configured during onboarding
Key Features:
- 🏠 Native FreeBSD - No Linux emulation, native jail isolation
- 🔒 Jail Isolation - Secure OS-level containers with ZFS snapshots
- ⚡ Better Performance - Single layer: FreeBSD → Jail → Node.js
- 💾 ZFS Integration - Snapshots, quotas, compression
- 🔧 CNC Ready - clawdie-cnc for CNC machine control (in development)
- 📊 Online Documentation - Live docs at docs.clawdie.si
Why Clawdie?
Why Jails Instead of Docker?
| Aspect | Docker on FreeBSD | FreeBSD Jails |
|---|---|---|
| Performance | Good (emulation overhead) | Excellent (native) |
| Layers | FreeBSD → Linux → Docker | FreeBSD → Jail |
| Security | Good | Excellent |
| Networking | Docker bridge | Native IP |
| Complexity | High | Low |
| ZFS Integration | Manual | Native |
Result: Simpler, faster, more secure.
Why Clawdie?
NanoClaw by Gavriel is the upstream line we still track, and NanoClaw itself follows the broader OpenClaw direction opened by Peter Steinberger. Clawdie takes that line onto FreeBSD for operators who want:
- Native performance without Linux emulation
- ZFS integration for snapshots and quotas
- Simpler architecture (fewer layers)
- CNC machine integration for manufacturing
Architecture
Telegram + scheduled tasks + IPC
↓
SQLite state and routing data
↓
Host orchestrator (Node.js)
↓
FreeBSD worker jail(s)
↓
Agent response
Single Node.js process. Agents execute in isolated FreeBSD jails with filesystem isolation via nullfs mounts. Only mounted directories are accessible. Per-group message queue with concurrency control. PostgreSQL in a dedicated db jail provides split-brain memory: agent-system skills (preloaded, read-only) and user/agent memory (dynamic, grows with use). Both databases are required.
Key Files
src/index.ts- Orchestrator: state, message loop, agent invocationsrc/channels/telegram.ts- Built-in Telegram channelsrc/ipc.ts- IPC watcher and task processingsrc/router.ts- Message formatting and outbound routingsrc/group-queue.ts- Per-group queue with global concurrency limitsrc/jail-runner.ts- Spawns jailed agent processes and streams outputsrc/jail-runtime.ts- FreeBSD jail detection and managementsrc/jail-config.ts- Jail configuration generationsrc/task-scheduler.ts- Runs scheduled taskssrc/db.ts- SQLite operations (messages, groups, sessions, state)setup/*.ts- Modular setup entrypoints (environment,pi-config,jails, etc.)groups/*/AGENTS.md- Per-group memory
What It Supports
- Telegram-first core - Built-in Telegram channel plus headless/background operation.
- Isolated group context - Each group has its own
AGENTS.mdmemory, isolated filesystem, and runs in its own jail sandbox with only that filesystem mounted. - Main channel - Your private channel (self-chat) for admin control; every group is completely isolated.
- Scheduled tasks - Recurring jobs that run the AI agent and can message you back.
- Jail isolation - Agents are sandboxed in FreeBSD jails with ZFS snapshots.
- Split-brain memory - Dedicated
dbjail runs PostgreSQL with two databases: agent-system skills (preloaded knowledge) and user/agent memory (grows with conversations). - Built-in payments, optional extras - Stripe ships in core and is ready when configured; other channels and integrations can still be layered through skills.
Installation
Prerequisites
- FreeBSD 15.0-RELEASE
- ZFS root installation
- Root access or sudo
- Internet access for
pkgandnpm bashandgitavailable before first run
Recommended explicit host baseline before first run:
sudo pkg install -y bash git bsddialog bastille node24 npm tmux python311 uv ripgrep fd rsync postgresql17-client py311-pillow dejavu
If fd-find is already installed on the host, pkg will replace it with
fd. That conflict resolution is expected on current FreeBSD ports.
The host baseline also includes py311-pillow and dejavu so tmux screenshot
capture works without a separate uv pip install Pillow step.
If the host still has both Python 3.11 and 3.12 installed, pin uv to 3.11
explicitly until the generic python3 path is cleaned up:
uv venv --python 3.11
uv run --python 3.11 <command>
Quick Start
# 1. Install the recommended FreeBSD host baseline
sudo pkg install -y bash git bsddialog bastille node24 npm tmux python311 uv ripgrep fd rsync postgresql17-client py311-pillow dejavu
# 2. Clone the repository
git clone https://codeberg.org/Clawdie/Clawdie-AI.git /home/clawdie/clawdie-ai
cd /home/clawdie/clawdie-ai
# 3. Bootstrap repo dependencies and native modules
./setup.sh
# 4. Install the default PI runtime if it is still missing
pi --version >/dev/null 2>&1 || npm install -g @mariozechner/pi-coding-agent
# 5. If setup.sh did not launch onboarding automatically, start it manually
npm run wizard
# 6. Review .env — wizard already wrote AGENT_NAME, PI_TUI_PROFILE, and Stripe key (if configured)
# Add your AI provider API key if it was not prompted during onboarding
# 7. Run the modular setup steps that exist on current main
npm run setup -- --step environment
npm run setup -- --step pi-config
npm run setup -- --step jails --create
npm run setup -- --step db
npm run setup -- --step git
npm run setup -- --step cms
npm run setup -- --step hosts
npm run setup -- --step mounts
npm run setup -- --step telegram-auth
npm run setup -- --step service
npm run setup -- --step verify
# 8. One-command host validation bundle for the on-host agent
npm run preflight-check
# 9. Optional: include onboarding and capture the password-generation phase
# Requires a real interactive TTY because wizard uses bsddialog
npm run preflight-check -- --with-onboarding --capture-password-step
# 10. Optional: force a manual re-import of built-in knowledge
npm run setup -- --step skills-memory --import
If pkg reports that fd conflicts with fd-find, that is expected:
fd is the current package Clawdie uses on FreeBSD.
Current main now has an early FreeBSD onboarding entrypoint plus the explicit modular steps. Available step entrypoints live in setup/index.ts and currently include:
onboardingprofileenvironmentpi-configjailsdbgitcmshostsgroupsregistermountstelegram-authserviceverifypreflightupstreamskills-memory
PI Profiles
pi-tui now supports a single PI_TUI_PROFILE selector for common runtime
scenarios:
setup— onboarding and exact setup actionsoperator— normal daily runtimestatus— read-only health/status summariespayments— Stripe-safe support flowdocs— docs and release copycms— Astro/Strapi publishing workgit— local git mirror and upstream syncmemory— split-brain and PostgreSQL memory worklocal— Ollama/offline fallbackcnc— CNC machine operation and G-code work
Check the resolved profile state with:
npm run setup -- --step pi-config
List all built-in profiles with:
npm run setup -- --step pi-config --list-profiles
The split-brain database path is now mandatory. Current setup generates or
preserves the PostgreSQL and future Strapi secrets in .env, then keeps
SKILLS_DB_URL and MEMORY_DB_URL aligned with AGENT_NAME, subnet, and
passwords. The db step now applies two distinct schema tracks:
- built-in knowledge tables in the skills DB
- dynamic hybrid-memory tables in the user/agent memory DB
The db step also imports the shipped built-in knowledge artifact by default.
skills-memory --import remains available as a manual re-import path.
At runtime, the host now queries the local skills DB before each jail run and
prepends the top built-in references to the prompt when relevant.
The active mandatory pieces are:
POSTGRES_ADMIN_PASSWORDSKILLS_DB_PASSWORDMEMORY_DB_PASSWORD
For PostgreSQL identifiers, Clawdie derives a DB-safe namespace from
AGENT_NAME. Example: clawdie-ai becomes clawdie_ai_reader,
clawdie_ai_skills, and clawdie_ai_brain.
STRAPI_DB_PASSWORD and the STRAPI_* app secrets now feed the default
internal Strapi bootstrap inside the cms jail. They are generated
automatically if missing and should stay private to the CMS layer.
Onboarding now also generates SCREENSHOTS_USER and SCREENSHOTS_PASSWORD
when they are missing. The cms step installs nginx basic auth for
/screenshots/ inside the cms jail. npm run preflight-check writes a full
host validation bundle into tmp/preflight/<stamp>/, including summary.json
and summary.env for the on-host agent. It now includes telegram-auth in the
default sequence; groups and register remain post-deployment follow-up work
and no longer block base install verification on a fresh host.
Current main also provisions local code hosting by default through the
dedicated git jail. The default mode is:
CODE_HOSTING_MODE=gitFEATURE_GIT=YESWARDEN_GIT_IP=<subnet>.4
The git step creates ${AGENT_NAME}-git, installs the git jail baseline,
creates /srv/git, and mirrors the current repository into a bare repository.
Default IP Layout
The active 10.0.0.x slot map on current main is:
.1gateway onwarden0.2reserved compatibility slot, intentionally unused.3db.4git.5cms.6ollama.101+workers.150browser/gui
This keeps foundational services low in the range while leaving room for multiple workers and avoiding overlap with host-facing web services. The CMS stack stays on the private jail network instead of assuming control of host nginx, which is the main reason the low fixed service slots matter.
Naming and Local DNS
Current main separates public and internal naming:
AGENT_DOMAINis the public-facing site/API domainAGENT_INTERNAL_DOMAINis the internal jail/service zone written into/etc/hosts
Fresh installs should use:
AGENT_DOMAIN=<agent>.invaliduntil you set a real public domainAGENT_INTERNAL_DOMAIN=<agent>.home.arpa
Why this changed:
.localis reserved for mDNS and is a bad default for private service naminghome.arpais the safer standards-based internal namespace- keeping public and internal names separate avoids accidentally treating a non-public jail hostname as if it were externally routable
FreeBSD Milestone
Diagnostic screenshot captured by tmux-screenshot skill — auto-detects failure and success signatures
Current main centers on:
- host-side orchestration in
src/index.ts AGENT_NAME-derived Bastille worker jails fromsrc/jail-config.ts- step-based setup entrypoints from
setup/index.ts - mandatory DB bootstrap with built-in knowledge import by default
Simple Onboarding Flow
./setup.sh
-> npm run wizard
-> detect locale + timezone from FreeBSD
-> confirm or override locale
-> confirm or override timezone
-> ask ASSISTANT_NAME
-> derive AGENT_NAME
-> optional AGENT_NAME override
-> select PI profile (operator, setup, payments, cnc, …)
-> configure Stripe now? (or skip)
-> write .env (AGENT_NAME, PI_TUI_PROFILE, STRIPE_SECRET_KEY, …)
-> npm run setup -- --step environment
-> npm run setup -- --step pi-config
-> npm run setup -- --step jails --create
-> npm run setup -- --step db
-> npm run setup -- --step git
-> npm run setup -- --step cms
-> npm run setup -- --step hosts
-> npm run setup -- --step mounts
-> npm run setup -- --step telegram-auth
-> npm run setup -- --step service
-> npm run setup -- --step verify
groups and register remain explicit follow-up steps after auth/state are
present; they are not part of the minimal first-boot path.
Stripe Flow
onboarding
-> configure Stripe now? (or skip)
-> write STRIPE_SECRET_KEY into .env
host jail-runner
-> reads STRIPE_SECRET_KEY from .env
-> passes it to jailed runtime in stdin JSON secrets payload
jailed agent runner
-> merges secret into SDK env only
-> registers Stripe MCP tools
agent chat
-> can use payment, customer, invoice, and subscription tools
Web Serving Direction
Current checked-in HTML docs still use a transitional host deployment path. The target first-deployment model is different:
- the
cmsjail should own nginx, Astro, and docs serving - the same
cmsjail should own the internal Strapi content layer and seed it from repo-owned defaults on first install - Clawdie should not require taking over host nginx
- public exposure should work through an existing reverse proxy, a host PF redirect, or a direct jail IP
- Strapi admin stays internal-only by default
- first Astro deployment should stay minimal and avoid
sharpimage optimization on FreeBSD
That keeps onboarding simpler for operators who already run other host web services.
Operational docs for this milestone:
- Bastille on FreeBSD 15
- Jail Networking Strategy
- PostgreSQL Memory Plan
- Monitoring Model
- Manual Reset and pi-tui Rebootstrap
Usage
Talk to your assistant with the trigger word (default: @Clawdie):
@Clawdie send an overview of the sales pipeline every weekday morning at 9am
@Clawdie review the git history for the past week each Friday and update the README
@Clawdie every Monday at 8am, compile news on AI developments and message me a briefing
Run npm run doctor to check system health (runtime, jails, networking, services, split-brain DB/artifact status).
From the main channel (your self-chat), you can manage groups and tasks:
@Clawdie list all scheduled tasks across groups
@Clawdie pause the Monday briefing task
@Clawdie join the Family Chat group
Customizing
Clawdie doesn't use configuration files. To make changes, just tell the AI agent what you want:
- "Change the trigger word to @Assistant"
- "Remember in the future to make responses shorter and more direct"
- "Add a custom greeting when I say good morning"
- "Store conversation summaries weekly"
Or run /customize for guided changes.
The codebase is small enough that the AI agent can safely modify it.
Philosophy
Small enough to understand. One process, a few source files, no microservices. If you want to understand the full Clawdie codebase, ask the AI agent to walk you through it.
Secure by isolation. Agents run in FreeBSD jails with filesystem isolation via nullfs mounts. They can only access explicitly mounted directories. Bash access is safe because commands run inside the jail, not on your host.
Built for the individual user. Clawdie isn't a monolithic framework; it's software that fits each user's exact needs. You make your own fork and have the AI agent modify it to match your requirements.
Customization = code changes. No configuration sprawl. Want different behavior? Modify the code. The codebase is small enough that it's safe to make changes.
AI-native.
- FreeBSD installs can start with
npm run wizardforbsdinstall/bsddialogstyle locale, timezone, and assistant-first onboarding. - The rest of setup remains modular and scriptable through
npm run setup -- --step .... - No monitoring dashboard; ask the AI what's happening.
- No debugging tools; describe the problem and the AI fixes it.
Skills over features. Instead of adding features (e.g., support for Telegram) to the codebase, contributors submit skills like /add-telegram that transform your fork. You end up with clean code that does exactly what you need.
Clawdie Ecosystem
| Component | Description | Status |
|---|---|---|
{AGENT_NAME}-worker |
Default Bastille worker jail profile | Current |
| skills-memory bootstrap | Precomputed pgvector import for the skills DB | Current |
| clawdie-cnc | CNC machine control | Development |
| browser-vm | Browser automation profile in jail config | Planned |
| docs.clawdie.si | Documentation site (public) | Live |
CNC (clawdie-cnc)
Clawdie-cnc is the control system for the CNC machine — an open source machine designed to manufacture geodesic dome components. It translates dome designs from OSA into G-code, manages the build sequence, and logs everything to persistent memory.
See clawdie-cnc/README.md for details.
Contributing
Don't add features. Add skills.
If you want to add Slack support, don't create a PR that adds Slack alongside Telegram. Instead, contribute a skill file (.agent/skills/add-slack/SKILL.md) that teaches the AI agent how to transform a Clawdie installation to use Slack.
Users then run /add-slack on their fork and get clean code that does exactly what they need, not a bloated system trying to support every use case.
Available Skills (36)
Channels: add-telegram, add-discord, add-gmail, add-slack, add-voice-transcription, x-integration
Jail & Infrastructure: warden-bootstrap, warden-pf, warden-zfs, warden-health, bastille-network, browser-vm, freebsd-admin, sanoid
Operations: nginx, nginx-glasspane, telegram-admin, tmux-screenshot, postgres-memory
Frontend & CMS: astro, strapi
Agent: coding-agent, add-telegram-swarm, add-parallel
Utility: setup, update, customize, debug, get-qodo-rules, qodo-pr-resolver
Skills Structure
.agent/skills/add-telegram/
├── SKILL.md # Skill documentation and instructions
├── manifest.yaml # Skill metadata
├── add/ # Files to add
│ └── src/channels/telegram.ts
├── modify/ # Files to modify
│ └── src/config.ts
└── tests/ # Skill tests
└── telegram.test.ts
Requirements
- FreeBSD 15.0-RELEASE
- Node.js 24+
- Python 3.11+ (for voice transcription, screenshots, and other features)
- ZFS (recommended)
- Optional: Telegram bot token, provider API key, PostgreSQL URLs for memory/skills DB
Security
Agents run in FreeBSD jails with filesystem isolation, not behind application-level permission checks. They can only access explicitly mounted directories. The codebase is small enough that you can review it. See docs/SECURITY.md for the full security model.
Documentation
- docs.clawdie.si - Complete documentation
- docs/HOST-OPERATOR-MODEL.md - Host-first operator model and service-jail layout
- AGENTS.md - Agent development guidelines
Community
Questions? Ideas? Join the Discord.
Acknowledgments
Clawdie is built on giants' shoulders. Peter Steinberger created OpenClaw, which set the broader project line. NanoClaw by Gavriel distilled that line into a minimal personal-assistant upstream. Clawdie is the FreeBSD-first fork in that lineage.
We keep NanoClaw as an upstream reference where it helps, then carry the design into native jails, ZFS, PF, and the wider OSA mission.
License
BSD 3-Clause License
Copyright (c) 2026, Sam (Samo Blatnik)
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions, and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions, and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
See LICENSE for full text.
Clawdie · Personal AI Assistant on FreeBSD
clawdie.si · docs.clawdie.si
Built on giants' shoulders · FreeBSD-first