Back to Freedom.Tech Back
All NanoClaw releasesAll versions
Release Wed, Jun 17, 2026 7 min read

NanoClaw 2.1.17

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/sdk 0.5.0 2.2.1 - requires a OneCLI server with the /v1 API. Older servers 404 every SDK call. The sanctioned gateway and CLI versions are now pinned in versions.json, and the onecli setup step enforces them. The gateway is a separate component - updating NanoClaw does not upgrade it for you: /update-nanoclaw upgrades the gateway when its pin moves, otherwise upgrade manually. See docs/onecli-upgrades.md.
  • New agent provider: Codex (OpenAI) - run /add-codex. Full runtime via codex app-server (planning, MCP tools, server-side history, resume). Trunk ships the seams and the skill; the payload installs from the providers branch - 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 --provider plus a restart; group creation is provider-agnostic.
  • /migrate-memory runs 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 stale CLAUDE.* files left over from another provider's writes. See docs/provider-migration.md.
  • /update-nanoclaw now 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-nanoclaw flow when the pin in versions.json shifts. 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.ts surfaces the SDK's is_error flag and the error subtype's errors[] text; poll-loop.ts delivers 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. writeOutboundDirect was opening the session's outbound DB through the readonly opener, so the INSERT it ran threw SQLITE_READONLY on every call - the router's Permission denied response 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 warn level on a non-zero exit (code !== null && code !== 0). Previously, a container that died at boot - unknown provider, missing binary, bad config - logged only at debug, 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 channelType when no instance is set.
  • Native uninstaller. bash uninstall.sh from a checkout, or nanoclaw.sh --uninstall from the installed launcher, removes the service, the data directory, and the host registration in one step - no more manual launchctl bootout / systemctl --user disable. Includes --dry-run and 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-prompt with 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-id on the first spawn, --resume on 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 getDeliveryAction so 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 onExchangeComplete hook 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_agent host-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-sweep now 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-browser is now pinned to 0.27.1 (what latest last 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 in README.md, docs/SPEC.md, CONTRIBUTING.md, and CLAUDE.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, opencode provider, codex provider, 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-bridge records 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-code 2.1.170 and @anthropic-ai/claude-agent-sdk 0.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