/update-nanoclaw
Transactionally update a customized NanoClaw checkout from official upstream without exposing live mounted source, with fork-safe skill refresh, mutable-state snapshots, migration gates, exact-code upgrade markers, detected service restart, health verification, and automatic
Claude Code
$ npx -y skills add nanocoai/nanoclaw --skill update-nanoclaw --agent claude-code
Codex
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a codex -y
Cursor
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a cursor -y
Gemini CLI
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a gemini-cli -y
GitHub Copilot
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a github-copilot -y
OpenCode
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a opencode -y
Windsurf
$ npx skills add nanocoai/nanoclaw --skill update-nanoclaw -a windsurf -y
SKILL.md
update-nanoclaw.SKILL.mdname: update-nanoclaw
description: Transactionally update a customized NanoClaw checkout from official upstream without exposing live mounted source, with fork-safe skill refresh, mutable-state snapshots, migration gates, exact-code upgrade markers, detected service restart, health verification, and automatic local rollback. Use for routine merge, rebase, or selective upstream updates.
Update NanoClaw
Update a customized install through an isolated, resumable transaction. The live checkout is not touched until the staged result has passed validation.
Use ordinary conversation for decisions and confirmations. Do not depend on Claude Code, Codex, OpenCode, or any provider-specific question/skill tool.
Safety contract
- Require a clean live checkout.
- Stage Git integration, dependency installation, installed-skill refresh, and
tests in a separate worktree.
- Resolve registry branches from the remote that actually carries them.
- Stop the detected service and drain this install's active containers before
changing source mounted into agent containers.
- Snapshot `.env`, `data/`, `groups/`, `store/`, and manual-service state before
cutover. Sockets and other ephemeral special files are intentionally omitted.
- Gate every breaking migration and external version-pin move.
- Stamp the exact Git commit/tree only after all required work succeeds.
- Restart through the detected launchd, user-systemd, system-systemd, or nohup
mode; require process state, `data/ncl.sock`, and `bin/ncl groups list`.
- Refuse cutover while an unmanaged `pnpm dev`/Node host is running. Stop that
process explicitly, update offline, then start it again manually.
- On build or health failure, restore Git and the mutable-state snapshot, rebuild
the previous image, restart the previous service, and health-check it.
1. Load the newest controller without changing the live tree
Confirm the live tree is clean:
git status --porcelain
Stop if it prints anything. Setup commits the files it applies as `setup: apply <skill>` commits unless `NANOCLAW_SETUP_COMMIT=0` was set. Treat anything left as part of the install: show it, ask the user to commit it as a local customization, then re-check. Never stash it, since the updater discovers installed skills from these files.
Use the official remote if one already exists. Otherwise add it as `upstream`:
if git remote get-url upstream >/dev/null 2>&1; then
upstream_remote=upstream
elif git remote get-url origin 2>/dev/null | grep -Eq '(^|[:/])nanocoai/nanoclaw(.git)?$'; then
upstream_remote=origin
else
git remote add upstream https://github.com/nanocoai/nanoclaw.git
upstream_remote=upstream
fi
git fetch "$upstream_remote" --prune
Select `main` when present, otherwise `master`:
if git show-ref --verify --quiet "refs/remotes/$upstream_remote/main"; then
upstream_ref="$upstream_remote/main"
elif git show-ref --verify --quiet "refs/remotes/$upstream_remote/master"; then
upstream_ref="$upstream_remote/master"
else
echo "Official remote has neither main nor master" >&2
exit 1
fi
Materialize the newest controller from that ref. This is the self-update seam: an older local skill still executes the newest safety code before any mutation. The controller always comes from `main`; the ref it merges follows the channel (step 2).
# pwd -P: on macOS mktemp returns a path through the /var symlink, and a
# symlinked argv defeats Node's import.meta main-module guard — the controller
# then exits 0 having done NOTHING. Canonicalize before use.
controller_dir="$(cd "$(mktemp -d)" && pwd -P)"
# Extract all of scripts/, not a hand-listed subset. These paths are a
# contract: older copies of this skill extract exactly them from the newest
# ref, so the controller must load from them alone, with no node_modules.
# scripts/update/controller-archive.test.ts enforces it.
git archive "$upstream_ref" scripts src/install-slug.ts | tar -x -C "$controller_dir"
2. Choose the channel, the Git strategy, and prepare
Channels (`NANOCLAW_UPDATE_CHANNEL` in `.env`; `--channel <name>` overrides it once): `stable` (default) = newest annotated `vX.Y.Z` tag; `beta` = newest `-beta.N` or `-rc.N` if newer than stable (beta.N < rc.N < the release); `edge` = upstream `main`. Change the default only with `set-channel` (below), never by editing `.env`.
Default to `merge`. Use `rebase` only when the user explicitly wants linear history. Use `cherry-pick` only with an explicit comma-separated commit list.
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" prepare \
--project-root "$PWD" --remote "$upstream_remote" --strategy merge
The JSON result is `nanoclaw-update/v1`. Record its `id`, `stageRoot`, backup branch/tag, changed files, and requirements. The live `HEAD` is still unchanged. Tell the user the `channel` and `upstreamRef`. Then:
- **Nothing new** (stable/beta, `phase: prepared`, `targetHead` equals
`originalHead`): say "Already on the newest release (vX.Y.Z)", still run step 3 (it refreshes installed skills), and `abandon` if `targetHead` is still unchanged.
- **Error `code: ahead-of-release`** (nothing staged): ask once, "This install
is newer than the latest release, `<tag>`. Keep getting the newest code from `main` (edge), or switch to releases and wait for the next one (stable)?" Save the answer, then on edge re-run `prepare` with `--channel edge`; on stable stop, as there is nothing to update until the next release:
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" set-channel \
--project-root "$PWD" --channel edge # or stableIf `phase` is `conflict`, resolve conflicts only inside `stageRoot`, preserving intentional local customizations. Complete the merge/rebase/cherry-pick there, commit it, then run:
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" resume \
--project-root "$PWD" --id "$id"
Never merge a lockfile (`
Read more
name: update-nanoclaw description: Transactionally update a customized NanoClaw checkout from official upstream without exposing live mounted source, with fork-safe skill refresh, mutable-state snapshots, migration gates, exact-code upgrade markers, detected service restart, health verification, and automatic local rollback. Use for routine merge, rebase, or selective upstream updates.
Update NanoClaw
Update a customized install through an isolated, resumable transaction. The live checkout is not touched until the staged result has passed validation.
Use ordinary conversation for decisions and confirmations. Do not depend on Claude Code, Codex, OpenCode, or any provider-specific question/skill tool.
Safety contract
- Require a clean live checkout.
- Stage Git integration, dependency installation, installed-skill refresh, and
tests in a separate worktree.
- Resolve registry branches from the remote that actually carries them.
- Stop the detected service and drain this install's active containers before
changing source mounted into agent containers.
- Snapshot `.env`, `data/`, `groups/`, `store/`, and manual-service state before
cutover. Sockets and other ephemeral special files are intentionally omitted.
- Gate every breaking migration and external version-pin move.
- Stamp the exact Git commit/tree only after all required work succeeds.
- Restart through the detected launchd, user-systemd, system-systemd, or nohup
mode; require process state, `data/ncl.sock`, and `bin/ncl groups list`.
- Refuse cutover while an unmanaged `pnpm dev`/Node host is running. Stop that
process explicitly, update offline, then start it again manually.
- On build or health failure, restore Git and the mutable-state snapshot, rebuild
the previous image, restart the previous service, and health-check it.
1. Load the newest controller without changing the live tree
Confirm the live tree is clean:
git status --porcelain
Stop if it prints anything. Setup commits the files it applies as `setup: apply <skill>` commits unless `NANOCLAW_SETUP_COMMIT=0` was set. Treat anything left as part of the install: show it, ask the user to commit it as a local customization, then re-check. Never stash it, since the updater discovers installed skills from these files.
Use the official remote if one already exists. Otherwise add it as `upstream`:
if git remote get-url upstream >/dev/null 2>&1; then upstream_remote=upstream elif git remote get-url origin 2>/dev/null | grep -Eq '(^|[:/])nanocoai/nanoclaw(.git)?$'; then upstream_remote=origin else git remote add upstream https://github.com/nanocoai/nanoclaw.git upstream_remote=upstream fi git fetch "$upstream_remote" --prune
Select `main` when present, otherwise `master`:
if git show-ref --verify --quiet "refs/remotes/$upstream_remote/main"; then upstream_ref="$upstream_remote/main" elif git show-ref --verify --quiet "refs/remotes/$upstream_remote/master"; then upstream_ref="$upstream_remote/master" else echo "Official remote has neither main nor master" >&2 exit 1 fi
Materialize the newest controller from that ref. This is the self-update seam: an older local skill still executes the newest safety code before any mutation. The controller always comes from `main`; the ref it merges follows the channel (step 2).
# pwd -P: on macOS mktemp returns a path through the /var symlink, and a # symlinked argv defeats Node's import.meta main-module guard — the controller # then exits 0 having done NOTHING. Canonicalize before use. controller_dir="$(cd "$(mktemp -d)" && pwd -P)" # Extract all of scripts/, not a hand-listed subset. These paths are a # contract: older copies of this skill extract exactly them from the newest # ref, so the controller must load from them alone, with no node_modules. # scripts/update/controller-archive.test.ts enforces it. git archive "$upstream_ref" scripts src/install-slug.ts | tar -x -C "$controller_dir"
2. Choose the channel, the Git strategy, and prepare
Channels (`NANOCLAW_UPDATE_CHANNEL` in `.env`; `--channel <name>` overrides it once): `stable` (default) = newest annotated `vX.Y.Z` tag; `beta` = newest `-beta.N` or `-rc.N` if newer than stable (beta.N < rc.N < the release); `edge` = upstream `main`. Change the default only with `set-channel` (below), never by editing `.env`.
Default to `merge`. Use `rebase` only when the user explicitly wants linear history. Use `cherry-pick` only with an explicit comma-separated commit list.
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" prepare \ --project-root "$PWD" --remote "$upstream_remote" --strategy merge
The JSON result is `nanoclaw-update/v1`. Record its `id`, `stageRoot`, backup branch/tag, changed files, and requirements. The live `HEAD` is still unchanged. Tell the user the `channel` and `upstreamRef`. Then:
- **Nothing new** (stable/beta, `phase: prepared`, `targetHead` equals
`originalHead`): say "Already on the newest release (vX.Y.Z)", still run step 3 (it refreshes installed skills), and `abandon` if `targetHead` is still unchanged.
- **Error `code: ahead-of-release`** (nothing staged): ask once, "This install
is newer than the latest release, `<tag>`. Keep getting the newest code from `main` (edge), or switch to releases and wait for the next one (stable)?" Save the answer, then on edge re-run `prepare` with `--channel edge`; on stable stop, as there is nothing to update until the next release:
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" set-channel \
--project-root "$PWD" --channel edge # or stableIf `phase` is `conflict`, resolve conflicts only inside `stageRoot`, preserving intentional local customizations. Complete the merge/rebase/cherry-pick there, commit it, then run:
pnpm exec tsx "$controller_dir/scripts/update-nanoclaw.ts" resume \ --project-root "$PWD" --id "$id"
Never merge a lockfile (`
A lightweight alternative to OpenClaw that runs in containers for security. Connects to WhatsApp, Telegram, Slack, Discord, Gmail and other messaging apps,, has memory, scheduled jobs, and runs directly on Anthropic's Agents SDK
Other skills on nanoclaw.
More skills from other plugins.
browser-use
Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site/app work. Also covers…
agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling…
opencli-adapter-author
Build or improve an OpenCLI JS adapter using observed site behavior, existing adapters and browser API evidence. For ad-hoc…
Questions about update-nanoclaw.
- Which coding agents can use update-nanoclaw?
- update-nanoclaw installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

