- Operator-driven provider selection in setup — the installer can select, install, and authenticate a non-default agent provider, then set it on the first agent before its first spawn. A provider registry feeds the picker and a vault-only auth walkthrough; default (Claude) installs are unaffected
- Per-group provider choice — the provider is a per-group database property, not an install-wide default:
ncl groups config update --id <group-id> --provider <name>then restart. Group creation stays provider-agnostic - Memory migrates via
/migrate-memory, never at runtime — each provider keeps its own store, so a fresh group on a different provider never inherits staleCLAUDE.*files - Container boot failures now log the last stderr lines at
warnon a non-zero exit instead of looping silently
- Container global CLIs (
@anthropic-ai/claude-code,agent-browser,vercel) are now data-driven fromcontainer/cli-tools.json, each pinned to an exact version — a skill adds a CLI by appending to the manifest instead of editing the Dockerfile
- [BREAKING]
@onecli-sh/sdk0.5.0 → 2.2.1 — now requires a OneCLI gateway with the/v1API; gateways that predate it answer404to every vault call. Sanctioned component versions are pinned inversions.jsonand theoneclisetup step enforces them. Migration:docs/onecli-upgrades.md - Slash commands now interrupt an in-flight turn instead of waiting it out
- New
onExchangeCompleteprovider hook — providers whose harness keeps no on-disk transcript can archive each exchange themselves
- Agent-surfaces capability seam (
providesAgentSurfaces) — a provider can declare it owns the composed project doc, skill links, and state dir, and the host skips its default surfaces
- Opt-in persistent memory scaffold (
usesMemoryScaffold) — providers without native memory get an idempotentmemory/tree in the agent’s host-backed workspace at boot
- Webhook raw-route registry — modules register non–Chat SDK webhooks (GitHub, payment providers, health checks) with
registerWebhookHandler()on the shared server instead of opening a second port
- Open
outbound.dbread-write inwriteOutboundDirectso direct outbound writes aren’t blocked
- Approval-resolved callback registry — modules can observe when an approval is resolved (e.g. to clear an “awaiting approval” indicator)
- Grace period for freshly-woken containers with stale processing claims — skips SLA enforcement on the tick that wakes a container, preventing a spawn-kill loop
- Record the acting user on resolved approval cards
- Add a read side (
getDeliveryAction) to the delivery action registry so module registrations can be behavior-tested
- Multi-instance adapters — run several adapters of one platform at once (e.g. three Slack apps in one workspace). A new
messaging_groups.instancedimension (migration 016) keys the adapter registry, per-instance Chat SDK state namespaces and webhook routes, and threads the instance through the router, delivery, and typing indicators. Single-instance installs are unchanged (instance defaults to the channel type) - Interactive uninstaller —
bash nanoclaw.sh --uninstallremoves one NanoClaw copy (service, containers, data, OneCLI agents) with a scan → confirm → execute flow,--dry-runand--yesflags, and per-checkout install-slug scoping. See Uninstall NanoClaw
- Egress lockdown (opt-in) — an agent group’s outbound network is forced through the OneCLI gateway, so a compromised agent can’t reach arbitrary hosts (v2.1.1). See Hardening
- v2.1.2–v2.1.4 were rapid patch follow-ups with no user-facing changes
- [BREAKING] Startup now requires an upgrade marker. The host refuses to boot unless
data/upgrade-state.jsonrecords that the install reached its version through a sanctioned path (/setup,/update-nanoclaw,/migrate-nanoclaw). Stamp it withpnpm exec tsx scripts/upgrade-state.ts set— the same command clears a tripped marker. See Upgrading - Skills retrofit — channel, provider, and tool skills made v2-conformant (minimal integration surface, a test per integration point); four skills broken on v2 were dropped
/upload-trace— upload a session trace to Hugging Face for sharing or debugging- Session-transcript rotation before resume — oversized or aged transcripts are rotated so a cold resume can’t wedge the container
/add-rtktoken-efficient CLI-proxy skill, and awhatsapp-formattingcontainer skill- Fixes: signal-cli 0.13+
listAccounts, the Photon remote-iMessage URL, channel-approval target scoping, and per-groupCLAUDE.local.mdloading
ncl destinations add/removethrough the approval flow now reach the receiver immediately — an approved destination no longer failssend_messagewithunknown destinationuntil the next container restart
Rollup release covering v2.0.55–v2.0.63; per-bump GitHub Releases begin here.
- [BREAKING] Service names are now per-install — the launchd label and systemd unit are slugged to your project root (
com.nanoclaw.<sha1(projectRoot)[:8]>,nanoclaw-<slug>.service). The oldcom.nanoclaw/nanoclaw.servicenames no longer match; find yours withsource setup/lib/install-slug.sh && launchd_label(macOS) orsystemd_unit(Linux) - Stronger
<message>-wrapping enforcement; MCP servers added viaadd_mcp_serverinherit OneCLI gateway routing; CLI-scope hardening (scopeFieldfails closed,sessions getguarded against cross-group access);/add-gmail-tooland/add-gcal-toolaligned with the v2 container-config model;qwibitai/nanoclaw→nanocoai/nanoclawswept across code and docs
- Per-group model and effort overrides —
ncl groups config update --model <model> --effort <level>, falling back to the host-configured model when unset - Container
claude-codebumped to 2.1.128
- Container config moved to the database — per-group runtime config (provider, model, packages, MCP servers, mounts, skills) lives in the
container_configstable instead ofgroups/<folder>/container.json; filesystem configs are backfilled on startup ncl groups restartwith--rebuild/--message— config edits no longer auto-kill containers; on-wake messages are picked up only by a fresh container’s first poll- Per-group
cli_scope(disabled/group/global, defaultgroup) — controls what the agent can reach vianclfrom inside its container, with cross-group result filtering
- The
ncladmin CLI — query and modify the central DB (agent groups, messaging groups, wirings, users, roles, members, destinations, sessions, approvals, dropped messages). Host transport over a Unix socket; container-side writes go through the approval flow - v1 → v2 migration —
bash migrate-v2.shfinds your v1 install, merges.env, seeds the v2 DB, copies group folders (CLAUDE.md→CLAUDE.local.md) and session data, ports tasks and channels, then hands off to/migrate-from-v1. See Migrate from v1
- Post-rewrite stabilization — roughly 44 rapid patch releases over two weeks, before the per-release changelog discipline began at v2.0.63. Not individually documented upstream; see the GitHub releases for raw notes
- Ground-up architectural rewrite with new entity model (users, roles, messaging groups, agent groups, wirings)
- Two-database session model —
inbound.db(host writes) andoutbound.db(container writes) eliminate cross-mount SQLite contention - Agent-runner moved from Node.js to Bun — runs TypeScript directly without compilation
- Shared-source agent-runner —
/app/srcis a read-only bind mount, source changes never require image rebuild tinias PID 1 for proper signal forwarding- Three-level channel isolation model with
unknown_sender_policy(strict, request_approval, public) - Per-wiring engage modes:
pattern,mention,mention-sticky - Sender scope enforcement per wiring (
allorknown) - Channel and sender approval flows with interactive cards
- Tasks stored as
messages_inrows with cron-based recurrence and series tracking - Delivery system with two-poll architecture (active 1s, sweep 60s)
- Module system for permissions, scheduling, agent-to-agent, approvals, and self-modification
- OneCLI Agent Vault is the sole credential path
- Channels moved to separate branches (trunk ships no adapters)
- Per-agent-group custom Docker images with additional packages
- Updated token count to 43.8k tokens (22% of context window)
- Added
.claude/settings.jsonwith default SDK configuration - Added
ONECLI_API_KEYconfiguration option for OneCLI gateway authentication
- Fixed Gmail OneCLI credential mode detection — properly detects when running under OneCLI Agent Vault
- Reduced setup friction and improved diagnostics output
- Added
.npmrcwith 7-day minimum release age for dependency safety
- Fixed writable global memory mount for main agent — corrected the path in container
CLAUDE.md - Fixed three issues in the Karpathy wiki skill
- Updated
init-onecliskill to useONECLI_URLvariable
- Lowered auto-compact threshold to 165k tokens for better context fidelity
- Added
/add-karpathy-llm-wikiskill — persistent wiki knowledge base per group, based on Karpathy’s LLM Wiki pattern - Added
/migrate-nanoclawskill — intent-based upgrade that extracts customizations into a migration guide and reapplies them on a clean upstream base - Added
/migrate-from-openclawskill — guided migration from OpenClaw installations - NanoClaw now suggests
/migrate-nanoclawwhen the user’s fork is far behind upstream
- Added automatic session artifact pruning on startup and daily — cleans up stale session JSONLs (7 days), debug logs (3 days), todo files (3 days), and telemetry (7 days) while preserving active sessions
- Upgraded agent SDK to 0.2.92 with auto-compact at 165k tokens
- Main agent now has direct read-write access to the SQLite database —
store/is mounted separately at/workspace/project/storeso the main group can query and write data directly - Added
requiresTriggerparameter to theregister_groupMCP tool (defaults tofalse) — controls whether messages must start with the trigger word for the group to respond
- Added reply/quoted message context support — channels can now pass
reply_to_message_id,reply_to_message_content, andreply_to_sender_namefields with messages - Reply context is rendered as
<quoted_message>XML in agent prompts, giving agents full awareness of which message a user is responding to - Database migration adds reply context columns to the messages table (nullable for backward compatibility)
- Added
/add-macos-statusbarutility skill — macOS menu bar status indicator with start/stop/restart controls - Added Telegram channel contributors (contributed by @cschmidt, @leonalfredbot-ship-it, @moktamd, @gurixs-carson)
- Auto-recover from stale Claude Code session IDs instead of retrying infinitely — detects missing session transcripts and clears the broken session for a fresh retry
- Removed built-in Ollama MCP server from core — Ollama integration is now exclusively available via the
/add-ollama-toolskill - Fixed npm audit dependency errors
- Setup skill now routes credential system by container runtime: Docker uses OneCLI Agent Vault, Apple Container uses native credential proxy
- Marked Apple Container as experimental
- Migrated
x-integrationhost.ts from pino to built-in logger (follow-up to v1.2.36 cleanup) - Fixed
stopContainer()test compatibility — mocked container-runtime so tests don’t require Docker - Cleared stale Telegram token from
.env.example
- Fixed message history overflow: when
lastAgentTimestampwas missing, all 200 messages were sent to the agent instead of respectingMAX_MESSAGES_PER_PROMPT(default 10). Added cursor recovery from last bot reply.
- Security fixes: command injection prevention in
stopContainer(name validation), mount path colon rejection, allowlist caching fix (contributed by @foxsky)
- Fixed
isMainflag preservation onregister_groupIPC updates — prevents accidental privilege stripping (contributed by @snw35)
- Fixed
.envparser crash on single-character values (contributed by @foxsky)
- [BREAKING] Replaced
pinologger with built-in logger module — removes 2 runtime dependencies. WhatsApp users must re-merge the WhatsApp fork to pick up the Baileys logger compatibility fix:git fetch whatsapp main && git merge whatsapp/main. If thewhatsappremote is not configured:git remote add whatsapp https://github.com/nanocoai/nanoclaw-whatsapp.git - Removed
yamlandzoddependencies — core runtime now uses only 3 packages - Updated Ollama skill with admin model management tools
- Channel-formatting text-style fixes for WhatsApp and Telegram (contributed by @kenbolton)
- [BREAKING] OneCLI Agent Vault replaces the built-in credential proxy. Check your runtime:
grep CONTAINER_RUNTIME_BIN src/container-runtime.ts— if it shows'container'you are on Apple Container, if'docker'you are on Docker. Docker users: run/init-oneclito install OneCLI and migrate.envcredentials to the vault. Apple Container users: re-merge the skill branch (git fetch upstream skill/apple-container && git merge upstream/skill/apple-container) then run/convert-to-apple-container— do NOT run/init-onecli(it requires Docker). The legacy credential proxy is available as an opt-in skill via/use-native-credential-proxy. - Channel tokens (Telegram, Slack, Discord) remain in
.env— only container-facing credentials (Anthropic, OpenAI, etc.) are migrated to the vault.
- Added
/add-emacschannel skill (contributed by @kenbolton) - Fixed mount-allowlist preservation —
/setupno longer overwrites existingmount-allowlist.json(contributed by @akasha-scheuermann) - Fixed Telegram migration backfill to default chats as direct messages instead of groups (contributed by @RichardCao)
- Fixed CI workflows to skip
bump-versionandupdate-tokenson forks (contributed by @shawnyeager)
- Fixed container mounts to include group folder and sessions directory (contributed by @kenbolton)
- Added
/channel-formattingskill — channel-aware text formatting for WhatsApp, Telegram, Slack, and Signal - Fixed per-group trigger pattern matching — each group can now define its own trigger word (contributed by @mrbob-git)
- Fixed
loginctl enable-lingerso systemd user service survives SSH logout (contributed by @IYENTeam) - Clarified WhatsApp phone number prompt to prevent auth failures (contributed by @ingyukoh)
- Added Telegram forum topics contributor (contributed by @flobo3)
- Fixed
isMain-based CLAUDE.md template selection during runtime group registration
- Fixed CLAUDE.md template copy when registering groups via IPC (contributed by @ingyukoh)
- Fixed diagnostics to use explicit Read tool directive for pickup instructions (contributed by @Koshkoshinsk)
- Added task scripts — scheduled tasks can now run a pre-execution bash script that conditionally wakes the agent via
wakeAgentJSON contract (contributed by @gabi-simons)
- Fixed agent-runner source cache to refresh based on file modification time instead of copying once at startup
- Removed accidentally merged Telegram channel code from main
- Removed Grammy dependency and pinned
better-sqlite3@11.10.0andcron-parser@5.5.0 - Removed auto-sync GitHub Actions
- Enabled
loginctl lingerduring setup so systemd user service survives SSH logout - Clarified WhatsApp phone number prompt format (digits only, no
+prefix) - Added CLAUDE.md template copy during IPC group registration
- Fixed timezone validation to prevent crash on POSIX-style TZ values — now validates IANA identifiers and falls back to UTC
- Expanded fork sync auto-resolve patterns and added missing forks to dispatch list
- Fixed diagnostics prompt not being shown to user (contributed by @Koshkoshinsk)
- Added auto-resolve for
package-lock.json, badge, and version conflicts during fork sync
- Added
/use-native-credential-proxyskill — opt-in restoration of the built-in.env-based credential proxy for users who prefer it over OneCLI - Removed dead
src/credential-proxy.tscode (unused since v1.2.22) - Updated token count to 39.8k tokens (20% of context window)
- Upgraded Zod dependency from v3 to v4 (
^4.3.6)
- Replaced credential proxy with OneCLI Agent Vault for container credential injection
- Updated token count to 40.7k tokens (20% of context window)
- Added opt-in diagnostics via PostHog — collects anonymous system info (OS, architecture, version, selected channels) during
/setupand/update-nanoclawwith explicit user consent - Three-option prompt: Yes (send once), No (skip), Never ask again (permanently opt out)
- No runtime telemetry — diagnostics run only in skill workflows, not in the application itself
- Added ESLint configuration with error-handling rules across the codebase
- Reduced
docker stoptimeout for faster container restarts (-t 1flag — containers are stateless)
- Added read-only
/capabilitiesand/statuscontainer-agent skills
- Tasks snapshot now refreshes immediately after IPC task mutations (contributed by @mbravorus)
- Fixed remote-control prompt auto-accept to prevent immediate exit
- Added
KillMode=processso remote-control survives service restarts (contributed by @gabi-simons)
- Added
/remote-controlcommand for host-level Claude Code access from within containers
Major architecture change: skills are now git branches, channels are separate fork repos.
Features
- Skills live as
skill/*git branches merged viagit merge— no more marketplace or plugin system - Added Docker Sandboxes announcement and manual setup guide
- Added
nanoclaw-docker-sandboxesto fork dispatch list
Breaking
- Skills are no longer installed via marketplace or plugin commands — use
git mergeworkflow
Fixes
- Fixed setup registration to use
initDatabase/setRegisteredGroupwith correct CLI commands - Auto-resolve
package-lockconflicts when merging forks - Bumped
claude-agent-sdkto ^0.2.76
Features
- PDF reader skill: Read and analyze PDF attachments
- Image vision skill: Image analysis for WhatsApp
- WhatsApp reactions skill: Emoji reactions and status tracker
Fixes
- Fixed task container to close promptly when agent uses IPC-only messaging
- Fixed WhatsApp pairing code written to file for immediate access
- Fixed WhatsApp DM-with-bot registration to use sender’s JID
- Added
LIMITto unbounded message history queries for better performance
- Fixed misleading
send_messagetool description for scheduled tasks
- Added
/add-ollamaskill for local model inference - Added
update_tasktool and return task ID fromschedule_task
- Updated
claude-agent-sdkto 0.2.68
- CI formatting fix
- Fixed
_chatJidrename tochatJidinonMessagecallback
- Added sender allowlist for per-chat access control to restrict who can interact with the agent
- Version bump (no functional changes)
Major release introducing multi-channel architecture. WhatsApp is no longer hardcoded — all channels self-register via a channel registry.
Features
- Channel registry: Channels self-register at module load time via
registerChannel()factory pattern isMainflag: Explicit boolean replaces folder-name-based main group detection- Channel-prefixed group folders: Groups use
whatsapp_main,telegram_family-chatconvention to prevent cross-channel collisions - Unconfigured channels now emit WARN logs naming the exact missing variable
Breaking
- WhatsApp moved to skill: No longer part of core — apply with
/add-whatsapp ENABLED_CHANNELSremoved: Orchestrator usesgetRegisteredChannelNames(); channels detected by credential presence- All channel skills simplified: No more
*_ONLYflags — all use self-registration pattern
Fixes
- Prevent scheduled tasks from executing twice when container runtime exceeds poll interval
Migration
Existing WhatsApp users: run/add-whatsapp in Claude Code CLI after updating.- Added CJK font support (
fonts-noto-cjk) for Chromium screenshots (contributed by @neocode24)
- Fixed wrapped WhatsApp message normalization before reading content
- Added third-party model support — use models beyond Claude
- Added
/update-nanoclawskill for syncing customized installs with upstream (replaces old/update) - Added Husky and
format:fixscript for consistent formatting
Biggest pre-1.2 release — added Slack channel, refactored Gmail, and improved CI.
Features
- Added
/add-slackskill - Restructured add-gmail skill for new architecture with graceful startup when credentials missing
- Removed deterministic caching from skills engine
- Added
.nvmrcspecifying Node 22 - CI optimization, logging improvements, and codebase formatting
- Added CONTRIBUTORS.md and CODEOWNERS
Fixes
- Fixed WhatsApp QR data handling
- Rebased core skills (Telegram, Discord, voice) to latest main
- Improved error handling for WhatsApp Web version fetch (follow-up to v1.1.1)
Features
- Added
/updateskill to pull upstream changes from within Claude Code - Replaced ‘ask the user’ with
AskUserQuestiontool in skills
Security
- Fixed critical skills path-remap root escape (including symlink traversal)
Fixes
- Fixed empty messages from polling queries
- Fixed fallback name from ‘AssistantNameMissing’ to ‘Assistant’