add-anydoc
Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when agents need to read attached Word,…
Add Dial channel integration — a real phone number for SMS and AI voice calls via the Dial platform (getdial.ai). Native adapter — no Chat SDK bridge.
$ npx -y skills add nanocoai/nanoclaw --skill add-dial --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/add-dialContext preview
The summary Claude sees to decide when to auto-load this skill.
Add Dial channel integration — a real phone number for SMS and AI voice calls via the Dial platform (getdial.ai). Native adapter — no Chat SDK bridge.
name: add-dial description: Add Dial channel integration — a real phone number for SMS and AI voice calls via the Dial platform (getdial.ai). Native adapter — no Chat SDK bridge.
Adds [Dial](https://getdial.ai) — a real phone number for **SMS and AI voice calls**. Native adapter (no Chat SDK bridge): both directions go through the `dial` CLI — outbound via `dial message`, inbound via its command-target daemon. NanoClaw doesn't ship channels in trunk — this skill copies the Dial adapter, its pairing helper, and their tests in from the `channels` branch. The `pair-dial` setup step is maintained in trunk, so it is not copied here.
The mechanical steps under **Apply** carry `nc:` directive fences: an agent reads the prose and applies them, and a parser can apply them deterministically from the same document. Every directive is idempotent, so the whole skill is safe to re-run; anything a parser can't apply falls back to the prose beside it.
Fetch the `channels` branch and copy the Dial adapter, its pairing store and user-agent helper (each with its test), and the registration test into place (overwrite — the branch is canonical):
src/channels/dial.ts src/channels/dial-pairing.ts src/channels/dial-pairing.test.ts src/channels/dial-user-agent.ts src/channels/dial-user-agent.test.ts src/channels/dial-registration.test.ts src/channels/dial-grant.test.ts src/channels/dial-status.test.ts
The `dial-cli` container skill is deliberately **not** copied here. `container/skills/` is mounted read-only into *every* agent container (`src/container-runner.ts`), and a group with `skills:'all'` picks up whatever it finds there — so shipping the skill with the adapter would hand it to agents on installs that never configured Dial. It is installed only by `/add-dial-tool`, offered under *Add phone superpowers* below, which is the skill that actually provisions the CLI the skill documents.
`dial.ts` imports `dial-user-agent.js` at module scope, so omitting that helper breaks the build and every test that loads the channel barrel.
Append the self-registration import to the channel barrel (skipped if present). This one line is the skill's only reach-in into the channel core:
import './dial.js';
Add the `pair-dial` loader to the `STEPS` map in `setup/index.ts`, inside the dormant marker region (skipped if already present — `pair-dial` ships in core, so this idempotent-skips on a normal install, but is expressed for a clean-upstream rebuild). The pairing handshake below spawns this step:
'pair-dial': () => import('./pair-dial.js'),Pinned to exact versions — the supply-chain policy rejects ranges and `latest`. `qrcode` renders the scannable pairing card:
qrcode@1.5.4
The adapter needs no Dial client library: it shells out to the `dial` CLI, which this skill already requires for inbound. `@getdial/sdk` was dropped because it depends on `pubnub`, which pulls react-native, Metro and Hermes into the lockfile for what is a single send — and the CLI ships in lockstep with the Dial API, so a contract change arrives as a CLI release rather than breaking a request pinned in the adapter.
Build first: it guards the adapter's typed core calls and proves the dependency is installed.
pnpm run build
Then run the one integration test.
pnpm exec vitest run src/channels/dial-registration.test.ts
`dial-registration.test.ts` imports the real channel barrel and asserts the registry contains `dial` — it goes red if the import line drifts. End-to-end SMS/voice is verified manually once the service runs.
Dial's CLI owns the account credential (an auth file it writes on sign-in), so the setup uses the `dial` CLI here. Ensure it's installed — this installs it if it's missing (for the full onboarding/auth reference, see the `dial-cli` skill or `curl -fsSL https://getdial.ai/skills.md`):
command -v dial || curl -fsSL https://getdial.ai/install | bash
Calls this setup makes to Dial identify the install. The `dial` CLI prepends `DIAL_USER_AGENT` to its own token, so the account's requests stay attributable to this NanoClaw install in Dial's server-side logs. Resolve the token once (`nanoclaw/<version>`; an unreadable `package.json` degrades to `nanoclaw/unknown` rather than blocking the install) and prefix every `dial` command below with it:
node -p "'nanoclaw/'+(require('./package.json').version||'unknown')" 2>/dev/null || echo nanoclaw/unknownNow pin the CLI's **absolute** path into `.env`. The adapter shells out to `dial` to register its inbound command target, and it runs inside the NanoClaw service, which does not inherit your interactive shell's `PATH`. The CLI usually lands in a version-manager bin directory (`~/.nvm/versions/node/*/bin`, `~/node/bin`, …) that the service cannot see, so a bare `dial` fails with `ENOENT`, the command target is never registered, and the channel comes up connected but deaf — no inbound SMS or calls, with only a line in `logs/nanoclaw.error.log` to show for it. `DIAL_CLI_PATH` removes the guesswork; `dial.ts` already prefers it:
command -v dial
DIAL_CLI_PATH={{dial_cli_path}}Check whether you're already signed in:
DIAL_USER_AGENT={{dial_ua}} dial doctor --jsonA 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
Repo: nanocoai/nanoclaw
Add local office-document-to-Markdown conversion to NanoClaw agent containers with the pinned Firecrawl AnyDoc CLI. Use when agents need to read attached Word,…
Convert an attached Word document, presentation, spreadsheet, OpenDocument file, RTF, EPUB, CSV, or text-based PDF into local Markdown. Use when a message…
Add Atomic Chat MCP server so the container agent can call local models served by the Atomic Chat desktop app via its OpenAI-compatible API.
Add clidash — a zero-dependency, read-only web dashboard that derives its tabs and tables at runtime from any CLI that lists resources as JSON. Ships pre-wired…
Use Codex (OpenAI's codex app-server) as a full agent provider — planning, tool orchestration, MCP tools, server-side history, session resume — alongside or…
Add a monitoring dashboard to NanoClaw. Installs @nanoco/nanoclaw-dashboard and a pusher that sends periodic JSON snapshots.