Original release notes
Rollup release covering v2.1.1 through v2.1.17 - every package.json bump merged since the v2.1.0 tag.
Changes
- [BREAKING]
@onecli-sh/sdk0.5.0 2.2.1 - requires a OneCLI server with the/v1API. Older servers 404 every SDK call. The sanctioned gateway and CLI versions are now pinned inversions.json, and theoneclisetup step enforces them. The gateway is a separate component - updating NanoClaw does not upgrade it for you:/update-nanoclawupgrades the gateway when its pin moves, otherwise upgrade manually. See docs/onecli-upgrades.md. - New agent provider: Codex (OpenAI) - run
/add-codex. Full runtime viacodex app-server(planning, MCP tools, server-side history, resume). Trunk ships the seams and the skill; the payload installs from theprovidersbranch - via the skill, the setup picker, or--step provider-auth codex. Auth is vault-only; no credential ever enters a container. - Setup can now select, install, and authenticate a non-default agent provider. A provider registry feeds the setup picker, an installer pulls the provider's payload from its branch, a vault auth walkthrough runs (
--step provider-auth), and the picked provider is set on the first agent - a DB property - before its first spawn. Default Claude installs are unaffected: picking Claude changes nothing. - Provider choice is explicit per group - no install-wide default. Provider is a DB property set via
ncl groups config update --providerplus a restart; group creation is provider-agnostic. /migrate-memoryruns the cross-provider memory move; runtime never touches it. Each provider keeps its own memory store, so fresh groups on a surfaces-owning provider see no staleCLAUDE.*files left over from another provider's writes. See docs/provider-migration.md./update-nanoclawnow upgrades the OneCLI gateway when its pinned version moves. Pairs with the OneCLI SDK 2.2.1 BREAKING above: the gateway upgrade that used to require a manual step is folded into the standard/update-nanoclawflow when the pin inversions.jsonshifts. Hosts whose gateway pin hasn't moved are unaffected.- Budget/billing-exhausted turns now reach the user instead of being silently dropped. When a turn ends in a non-retryable provider error - for example an Anthropic
403 billing_error- with no<message>wrapping, the agent-runner now delivers the provider's notice to the originating channel and stops re-nudging the failing gateway.providers/claude.tssurfaces the SDK'sis_errorflag and the error subtype'serrors[]text;poll-loop.tsdelivers that text and skips the re-wrap retry. Fixes the case where a spend-limit notice produced silence plus a turn-after-turn retry loop. - Command-gate denials now reach the sender.
writeOutboundDirectwas opening the session's outbound DB through the readonly opener, so the INSERT it ran threwSQLITE_READONLYon every call - the router'sPermission deniedresponse never delivered and the throw aborted further routing for that inbound event. Switched to the read-write opener (openOutboundDbRw, DELETE journal, busy_timeout); the host-side write stays even-seq, the container stays odd-seq, no contention. - Slash commands now interrupt an in-flight turn. A runner-handled command (
/clear,/compact,/cost, ...) arriving mid-turn aborts the active stream and runs immediately instead of waiting for the turn to finish. - Container boot failures now say why. A 10-line stderr tail is kept per spawn and surfaced at
warnlevel on a non-zero exit (code !== null && code !== 0). Previously, a container that died at boot - unknown provider, missing binary, bad config - logged only atdebug, which is below the default level, so the failure vanished into a silent crash loop. - Egress lockdown (opt-in). Containers can be pinned to an allowlisted egress set via
ncl groups config update --egress-lockdown; outbound network calls outside the allowlist fail closed. Off by default. See docs/egress-lockdown.md. - Channel instances as a first-class dimension. A single channel kind - WhatsApp, Slack, ... - can now run multiple independent instances per install, each with its own credentials, Chat SDK state, and webhook routes. Existing single-instance installs are preserved; the dispatcher falls back to
channelTypewhen noinstanceis set. - Native uninstaller.
bash uninstall.shfrom a checkout, ornanoclaw.sh --uninstallfrom the installed launcher, removes the service, the data directory, and the host registration in one step - no more manuallaunchctl bootout/systemctl --user disable. Includes--dry-runand a confirmation prompt; OneCLI agent registration is cleaned up alongside. - Interactive setup handoffs auto-submit context as Claude's first prompt. Mid-flow
?escapes and on-failure handoffs used to drop their context into--append-system-promptwith no user message, leaving Claude at an empty REPL while the operator re-explained themselves. Context now goes in as the first user message; handoffs in a single setup run also share a session-id (--session-idon the first spawn,--resumeon the next), so the conversation thread survives across mid-flow escapes. - Raw-route webhook registry. Channels register raw HTTP routes through a registry instead of patching the host's route table directly, so a new channel can be added without touching core. The non-Chat-SDK webhook suite kept its own file path to make the diff reviewable.
- Delivery-action getter. Channels expose a typed
getDeliveryActionso the host can route a message to the right send / edit / react path without channel-side branching at the call site. Read side of the action registry; the write side stays in the channel adapters. - Approval-resolved callback registry. Channels can register a callback that fires when an approval resolves - approved or rejected - used for in-channel acknowledgment cards and audit-trail edits.
- Per-exchange archiving is provider-owned. The
onExchangeCompletehook fires per turn; the markdown writer ships with the provider that needs it (codex payload), and the runner stops archiving on a provider's behalf. Dormant for the default Claude provider. - [security] A2A symlink guard. Inbound A2A payload resolution now fails closed on any symlink escape from the per-group sandbox - the resolver rejects forwarded attachments that traverse out via a symlink.
- [security] Approval admin authorization tightened. Approval response endpoints now require admin status and check the approver's scope against the request's group before executing - no cross-scope approvals.
- [security]
create_agenthost-side authorization. Agent creation is now authorized on the host side as well as the API edge: for confined groups, host-side approval is required, so a compromised channel can't spawn agents it isn't entitled to. host-sweepnow respects a per-group wake grace so it doesn't tear down a container that just woke and still has a stale processing claim.- Global agent-container CLI installs are data-driven via
container/cli-tools.json- skills add a CLI by appending a{name, version}JSON entry instead of patching the Dockerfile.agent-browseris now pinned to 0.27.1 (whatlatestlast resolved to); the rest is byte-for-byte unchanged. - Four skills retired (broken on v2 architecture):
claw,x-integration,add-parallel,convert-to-apple-container. References cleaned up inREADME.md,docs/SPEC.md,CONTRIBUTING.md, andCLAUDE.md. - Skills install model documented; see docs/skills-as-branches.md.
- Twelve skills retrofitted to the current skill contract:
add-dashboard,add-atomic-chat-tool,add-deltachat,add-slack,add-ollama-tool,migrate-from-openclaw,channel-family,opencodeprovider,codexprovider,mcp,capability,use-native-credential-proxy. - Ollama docs guide added for making the Ollama prompt cache hit on the Claude-Code Ollama path: a small proxy filters the per-request
cch=<hash>the Claude Agent SDK prepends; in a 31B-on-Apple-Silicon setup, follow-up replies went ~80 s ~4 s. Numbers vary by model. See docs/ollama.md. chat-sdk-bridgerecords the acting user on resolved approval/question cards in shared channels - appends a- <userName>byline to the edited card so the audit trail of who clicked Approve or Reject survives the button removal.@anthropic-ai/claude-code2.1.170 and@anthropic-ai/claude-agent-sdk0.3.170.
New Contributors
First NanoClaw PRs from @omri-maya, @markbala, @amit-shafnir, and @assapin landed in this release - welcome all four:
- @omri-maya - https://github.com/nanocoai/nanoclaw/pull/2713
- @markbala - https://github.com/nanocoai/nanoclaw/pull/2710
- @amit-shafnir - https://github.com/nanocoai/nanoclaw/pull/2719
- @assapin - https://github.com/nanocoai/nanoclaw/pull/2759
Want to be in the next one? Anyone can open a PR - pick up a good first issue or propose your own change directly. Discord is there if you want a hand getting started.
Contributors
Thanks to everyone who landed work in this release:
- @gavrielc - #2698, #2707, #2720, #2721, #2733, #2734, #2735, #2736, #2737, #2738, #2739, #2741, #2758
- @omri-maya - #2713, #2745, #2746, #2754, #2756
- @Koshkoshinsk - #2769, #2773, #2774, #2775
- @Hinotoi-agent - #2468, #2478
- @amit-shafnir - #2719
- @markbala - #2710
- @assapin - #2759
- @glifocat - #2764
Full Changelog: https://github.com/nanocoai/nanoclaw/compare/v2.1.0...v2.1.17

