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 — #2713
- @markbala — #2710
- @amit-shafnir — #2719
- @assapin — #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: v2.1.0...v2.1.17