Skip to content

v2.1.54

Latest

Choose a tag to compare

@github-actions github-actions released this 01 Aug 20:46
Immutable release. Only release title and notes can be modified.
62bd444

Rollup release covering v2.1.18 through v2.1.54 — everything merged since the v2.1.17 tag.

  • [BREAKING] iMessage unified into one imessage channel with two backends via /add-imessage: Local (this Mac's chat.db via the Chat SDK) or Hosted (native Photon via spectrum-ts, no Mac relay). Backend chosen at install or via IMESSAGE_BACKEND=local|hosted. The legacy Chat-SDK remote mode (IMESSAGE_SERVER_URL/IMESSAGE_API_KEY) and the separate imessage-cloud channel + /add-imessage-cloud skill are removed. See docs/imessage.md.
  • [BREAKING] Provider-agnostic memory. All providers now share one OKF v0.1-compatible memory/ tree, while persona lives in instructions.prepend.md; startup, clear, and compact reload memory automatically. Existing groups with legacy memory must run /migrate-memory before use. See memory and provider migration.
  • New groups can inherit an instance-wide default provider. DEFAULT_AGENT_PROVIDER sets the provider used when a new agent group is created without an explicit provider. Each group's stored provider still overrides it, and existing groups are unchanged.
  • [BREAKING] Channel install skills are now the single source of truth. The setup wizard installs channels by applying the same /add-<channel> SKILL.md a coding agent would follow — a deterministic engine executes the skill's mechanical steps directly from the document, so wizard and skill cannot drift, and anything the engine cannot do falls back to an agent reading the prose. Migration: the bespoke non-interactive channel installers (setup/add-<channel>.sh, setup/install-<channel>.sh) and per-channel wizard flows (setup/channels/<channel>.ts) are deleted. Anything that invoked them should apply the skill instead: interactively via /add-<channel> or the setup wizard, or programmatically via skill directives.
  • One guard for privileged actions. Every privileged action crossing the container or channel boundary now passes through guard() before execution: allow, hold, or deny. Approved replays carry the approval row as a grant and re-run checks against current state; forged, consumed, mismatched, or newly unauthorized grants fail closed. Guarded delivery actions can no longer be re-registered without their guard specification.
  • [BREAKING] whatsapp-formatting and slack-formatting moved from trunk to the channels branch. They now install with their channel, so installations without those channels no longer carry channel-specific formatting instructions in every agent's context. Migration — only if the channel is installed: re-run /add-whatsapp or /add-slack after updating. Do not run an add-skill preemptively; it installs the full adapter.
  • [BREAKING] Scheduled tasks moved from MCP tools to ncl tasks. Agents and operators now manage tasks with ncl tasks list/get/create/update/cancel/pause/resume/delete/run/append-log; task sessions are isolated from the chat session that created them. Migration: follow the scheduled-task migration guide.
  • [BREAKING] Task delivery is explicit and uses one door. Every send_message and send_file call requires a named to destination; task-session final output becomes the run summary, while only explicitly addressed tool calls deliver. Migration: rebuild the agent image, restart NanoClaw, update custom instructions that omit to, and clear or compact existing sessions. Failed pre-task scripts now back their recurring series off and auto-pause after eight consecutive failures instead of spinning.
  • [BREAKING] Chat SDK and channel adapters are pinned to 4.29.0. The bridge and adapter must use the same ChatInstance type, so exact pins replace caret ranges. Core installations without a channel are unaffected. Migration: if a channel is installed, re-run its /add-<channel> skill after updating.
  • Hardened agent images are available as an opt-in setup path. A digest-pinned, multi-architecture image can be fetched from the NanoClaw registry and retagged to the same local name used by builds; architecture, lockfile, provenance, size, and optional publisher-signature checks fail closed. Local builds remain the default and require no account. See hardened images.
  • Agent containers now start with safer defaults. New spawns always drop all Linux capabilities, set no-new-privileges, and use Docker's init process; these controls have no per-group override. A PID limit defaults to 2048 and can be changed installation-wide with CONTAINER_PIDS_LIMIT (0 disables it). The Vercel CLI is now opt-in instead of being baked into every image.
  • Agent containers can have installation-wide resource caps. CONTAINER_CPU_LIMIT and CONTAINER_MEMORY_LIMIT pass --cpus and --memory to Docker for every agent container. Both remain empty by default, so existing installations keep their current behavior.
  • Per-agent-group timezones. ncl groups config update --timezone <IANA> overrides the install timezone for that group's scheduling, run-log display, and container TZ; "" clears the override. Host-side operator display remains in the install timezone.
  • Agent templates and reusable skills expanded. Local templates can stamp persona, context, MCP configuration, and skills through ncl groups create --template; templates can also seed scheduled tasks and timezone. /learn distills a reusable skill from an existing workflow, and /add-clidash installs a read-only CLI-derived dashboard.
  • A clearer, safer ncl control plane. Verbs now declare and validate their arguments, generate deep help, preserve dashed IDs, render human-readable output on the host, and flush large responses before exit. Creating groups and wirings now provisions their required companion rows transactionally, fixing first-spawn failures and silently dropped replies.
  • Approval and agent-to-agent controls are more expressive. Connected agents can require per-message approval; rejection reasons reach the requester; OneCLI approval cards use the gateway's structured summary; and shared-channel cards retain who approved or rejected an action.
  • Delivery and provider failures stop disappearing. Missing adapters route messages into retry instead of marking them delivered, agent image builds no longer block the host, and Claude rate-limit telemetry only aborts a turn when the SDK reports a rejection. Billing exhaustion and transient rate limits remain distinct.
  • Setup and update recovery improved. Setup can parse wrapped Claude OAuth captures, offer Slack Socket Mode, and reap dead peer-service registrations. Re-applying an updated skill rebuilds the container when needed, and a missing session folder is re-provisioned so the documented reset path works.
  • Security fixes. Inbox attachment writes reject symlink escapes, approved CLI calls preserve the original caller context, command-gate checks no longer fail open, mount allowlists honor readOnly, and stale v1 secret/config mirrors were removed.
  • Documentation was refreshed across architecture, database schemas, security boundaries, provider configuration, SDK behavior, skills, and registry-branch maintenance. A Korean README is now available.

New Contributors

Contributors

Thanks to everyone who landed work in this release:

  • fix(setup): parse Claude OAuth token from wrapped PTY capture by @amit-shafnir in #2805
  • docs: add Korean README by @arkjun in #2806
  • refactor: remove dead resolveGroupIpcPath by @sturdy4days in #2803
  • refactor: mirror .claude skills + CLAUDE.md into .agents via symlinks by @Koshkoshinsk in #2810
  • feat(agent-to-agent): per-message approval policies on connected agents by @moshe-nanoco in #2793
  • fix(setup): allow env-selected agent provider by @amit-shafnir in #2811
  • chore(deps): move chat SDK + channel-adapter pins to 4.29.0 by @gabi-simons in #2834
  • fix(update-skills): nudge into skill updates, rebuild container on re-apply by @Koshkoshinsk in #2826
  • fix(setup): reap dead peer service registrations whose binary is gone by @amit-shafnir in #2830
  • feat(container): per-container CPU/memory limits (opt-in) by @omri-maya in #2856
  • feat: add /learn skill — distill or refine a reusable skill from anything by @robbyczgw-cla in #2843
  • feat(approvals): reject with reason by @moshe-nanoco in #2832
  • fix(migrate-v2): don't SELECT is_main from v1 registered_groups by @cben0ist in #2859
  • fix(ncl): default messaging-groups create instance to channel_type by @omri-maya in #2882
  • fix(security): contain inbox symlink escapes in attachment writes (#2828) by @johnmathews in #2880
  • fix(setup): offer Slack Socket Mode in the guided setup flow by @thisdotrob in #2885
  • feat(templates): local template loader, ncl --template, and docs by @amit-shafnir in #2890
  • [security] fix(cli): preserve caller context after approval by @Hinotoi-agent in #2611
  • Unregister the mock provider from the production container barrel by @gavrielc in #2927
  • Remove the dead /workspace/global mount and untrack v1 group seed files by @gavrielc in #2928
  • feat(approvals): render OneCLI approval requests from the gateway's structured summary by @gavrielc in #2929
  • command-gate: restore the /start filter and remove the fail-open admin check by @gavrielc in #2930
  • Fix ncl positional IDs for generated (dashed) identifiers by @gavrielc in #2932
  • feat: add /add-clidash — read-only CLI-derived dashboard skill by @leetwito in #2795
  • feat(approvals): colored buttons on approval cards (Slack primary/danger) by @gavrielc in #2933
  • Make the security-perimeter env vars reachable under the shipped service by @gavrielc in #2934
  • Delete dead v1 config knobs and the broken pnpm auth script by @gavrielc in #2935
  • Clean up dead ncl CLI protocol vocabulary by @gavrielc in #2936
  • Re-provision a missing session folder so the documented reset works by @gavrielc in #2937
  • Delete one-DB-era @deprecated shims and dead exports by @gavrielc in #2940
  • Fix the agent-to-agent in_reply_to stamp (cross-process no-op) by @gavrielc in #2942
  • Mount allowlist: honor the readOnly key and stop caching parse errors by @gavrielc in #2943
  • Rewrite the security docs to match the v2 perimeter by @gavrielc in #2945
  • Remove the dead data/env/env secrets mirror by @gavrielc in #2946
  • Fix stale architecture, scheduling, provider-config, and overlay docs by @gavrielc in #2948
  • Build agent images asynchronously instead of blocking the host by @gavrielc in #2931
  • docs: correct stale mount topology row + removed env var by @glifocat in #2953
  • docs: fix stale claims across README, CONTRIBUTING, CLAUDE.md and operational docs by @glifocat in #2961
  • docs: sync DB schema and entity docs with migrations 010-018 by @glifocat in #2962
  • docs: rewrite architecture.md and agent-runner-details.md to match current code by @glifocat in #2963
  • docs: update SDK deep-dive from 0.2.x to 0.3.197 by @glifocat in #2964
  • fix(agent-runner): match rate_limit_event as a top-level SDK message type by @glifocat in #2965
  • Wizard UX + add-slack Socket Mode fixes by @Koshkoshinsk in #2972
  • ncl CLI: verb-level args, deep help, server-rendered human view by @omri-maya in #2980
  • ci: auto-label PRs from core team members by @gabi-simons in #2978
  • Scheduled tasks: ncl tasks control plane, isolated sessions, script gate by @omri-maya in #2981
  • fix(cli): provision companion rows on ncl groups create and ncl wirings create by @glifocat in #2416
  • fix: stamp task rows with ISO timestamps by @gavrielc in #3005
  • fix: ISO storage + local-time display for all timestamps by @gavrielc in #3006
  • docs(agent-browser): require bounded waits for custom conditions by @Shufel83 in #3003
  • Move channel formatting skills (whatsapp, slack) from trunk to the channels branch by @gavrielc in #3009
  • feat: adapter-declared channel defaults (engage mode, threading, sender policy) by @gavrielc in #3010
  • add-teams: Teams-CLI-first credentials flow in SSF directive grammar by @Koshkoshinsk in #2958
  • Warn before connecting a shared WhatsApp number by @Koshkoshinsk in #3021
  • Guard seam: one decision function for every privileged action (guarded-actions phase 2) by @moshe-nanoco in #2986
  • feat: lean harness defaults for new agent groups by @gabi-simons in #3031
  • Tasks: one-door delivery — send_message is the only path out of a task session by @omri-maya in #2988
  • fix(agent-runner): log when an errored batch is acked completed by @glifocat in #2966
  • fix(delivery): route missing-adapter messages into the retry path by @glifocat in #2996
  • fix(container): warn when a real entry blocks a shared skill symlink by @glifocat in #3002
  • Structured skill format: setup installs channels by applying the SKILL.md by @gavrielc in #3035
  • feat: instance-wide default agent provider for new groups by @Koshkoshinsk in #2906
  • fix(self-mod): render full MCP server payload on the approval card by @glifocat in #2998
  • feat: support scheduled tasks in templates by @amit-shafnir in #3022
  • fix(skills): switch Telegram deep-link from t.me to telegram.me by @amit-shafnir in #3043
  • feat(memory): add provider-agnostic persistent memory by @amit-shafnir in #3012
  • docs(add-whatsapp-cloud): document webhook route + state-namespace migration for instance key by @glifocat in #2914
  • docs(changelog): drop duplicated Unreleased bullets by @glifocat in #3063
  • fix(agent-runner): compact_boundary must not surface as a result by @gavrielc in #3083
  • test(runner): drop temporary diagnostics from the /clear-abort test by @gavrielc in #3084
  • fix(claude): only abort on a rejected rate_limit_event; split rate_limit vs quota by @javexed in #3077
  • docs: rewrite branch maintenance guide for the registry-branch model by @glifocat in #3095
  • security: harden agent containers (cap-drop, no-new-privileges, pids-limit) by @boazdori in #2748
  • feat: per-agent-group timezone override by @Koshkoshinsk in #3125
  • setup: fetch a hardened agent image instead of building it by @gavrielc in #3150
  • container: make the Vercel CLI opt-in rather than baked into every image by @gavrielc in #3159
  • versions: repin the agent image to hardened-2026-07-30 by @gavrielc in #3160
  • fix(release): restore the v2.1.54 release path by @glifocat in #3163
  • Hosted iMessage (Photon): supersede #2999 with a working registration flow by @glifocat in #3164
  • fix(release): close post-merge safety gaps by @glifocat in #3168

Full Changelog: v2.1.17...v2.1.54