From 211d2b587785c7b401dd9c6199c464bd5850e349 Mon Sep 17 00:00:00 2001 From: meeech <4623+meeech@users.noreply.github.com> Date: Tue, 14 Apr 2026 00:34:36 -0400 Subject: [PATCH] docs: convert all skill instructions from npm to pnpm MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Batch update 62 files across .claude/skills/ — SKILL.md, REMOVE.md, and script files. Conversions: npm run -> pnpm run, npm install -> pnpm install, npx -> pnpm exec/dlx, npm uninstall -> pnpm uninstall, package-lock.json -> pnpm-lock.yaml, shebangs updated. --- .claude/skills/add-compact/SKILL.md | 10 ++--- .claude/skills/add-discord-v2/SKILL.md | 2 +- .claude/skills/add-discord/SKILL.md | 18 ++++---- .claude/skills/add-emacs/SKILL.md | 20 ++++----- .claude/skills/add-gchat-v2/REMOVE.md | 2 +- .claude/skills/add-gchat-v2/SKILL.md | 4 +- .claude/skills/add-github-v2/REMOVE.md | 2 +- .claude/skills/add-github-v2/SKILL.md | 4 +- .claude/skills/add-gmail/SKILL.md | 26 +++++------ .claude/skills/add-image-vision/SKILL.md | 12 ++--- .claude/skills/add-imessage-v2/REMOVE.md | 2 +- .claude/skills/add-imessage-v2/SKILL.md | 4 +- .claude/skills/add-karpathy-llm-wiki/SKILL.md | 6 +-- .claude/skills/add-linear-v2/REMOVE.md | 2 +- .claude/skills/add-linear-v2/SKILL.md | 4 +- .claude/skills/add-matrix-v2/REMOVE.md | 2 +- .claude/skills/add-matrix-v2/SKILL.md | 4 +- .claude/skills/add-ollama-tool/SKILL.md | 2 +- .claude/skills/add-parallel/SKILL.md | 4 +- .claude/skills/add-pdf-reader/SKILL.md | 8 ++-- .claude/skills/add-reactions/SKILL.md | 12 ++--- .claude/skills/add-resend-v2/REMOVE.md | 2 +- .claude/skills/add-resend-v2/SKILL.md | 4 +- .claude/skills/add-slack-v2/REMOVE.md | 2 +- .claude/skills/add-slack-v2/SKILL.md | 4 +- .claude/skills/add-slack/SKILL.md | 18 ++++---- .claude/skills/add-teams-v2/REMOVE.md | 2 +- .claude/skills/add-teams-v2/SKILL.md | 4 +- .claude/skills/add-telegram-swarm/SKILL.md | 4 +- .claude/skills/add-telegram-v2/REMOVE.md | 2 +- .claude/skills/add-telegram-v2/SKILL.md | 6 +-- .claude/skills/add-telegram/SKILL.md | 28 ++++++------ .../skills/add-voice-transcription/SKILL.md | 12 ++--- .claude/skills/add-webex-v2/REMOVE.md | 2 +- .claude/skills/add-webex-v2/SKILL.md | 4 +- .../skills/add-whatsapp-cloud-v2/REMOVE.md | 2 +- .claude/skills/add-whatsapp-cloud-v2/SKILL.md | 4 +- .claude/skills/add-whatsapp/SKILL.md | 44 +++++++++---------- .claude/skills/channel-formatting/SKILL.md | 16 +++---- .../convert-to-apple-container/SKILL.md | 6 +-- .claude/skills/customize/SKILL.md | 2 +- .claude/skills/debug/SKILL.md | 4 +- .claude/skills/init-onecli/SKILL.md | 4 +- .claude/skills/manage-channels/SKILL.md | 6 +-- .../migrate-from-openclaw/MIGRATE_CRONS.md | 2 +- .claude/skills/migrate-from-openclaw/SKILL.md | 12 ++--- .../scripts/discover-openclaw.ts | 2 +- .../scripts/extract-channel-credentials.ts | 2 +- .claude/skills/migrate-nanoclaw/SKILL.md | 6 +-- .claude/skills/setup/SKILL.md | 20 ++++----- .claude/skills/update-nanoclaw/SKILL.md | 10 ++--- .claude/skills/update-skills/SKILL.md | 4 +- .claude/skills/use-local-whisper/SKILL.md | 8 ++-- .../use-native-credential-proxy/SKILL.md | 18 ++++---- .claude/skills/x-integration/SKILL.md | 22 +++++----- .claude/skills/x-integration/host.ts | 2 +- .claude/skills/x-integration/scripts/like.ts | 4 +- .claude/skills/x-integration/scripts/post.ts | 4 +- .claude/skills/x-integration/scripts/quote.ts | 4 +- .claude/skills/x-integration/scripts/reply.ts | 4 +- .../skills/x-integration/scripts/retweet.ts | 4 +- .claude/skills/x-integration/scripts/setup.ts | 4 +- 62 files changed, 232 insertions(+), 232 deletions(-) diff --git a/.claude/skills/add-compact/SKILL.md b/.claude/skills/add-compact/SKILL.md index 0c4616538..ee9674aee 100644 --- a/.claude/skills/add-compact/SKILL.md +++ b/.claude/skills/add-compact/SKILL.md @@ -39,8 +39,8 @@ This adds: ### Validate ```bash -npm test -npm run build +pnpm test +pnpm run build ``` ### Rebuild container @@ -60,7 +60,7 @@ launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS ### Integration Test -1. Start NanoClaw in dev mode: `npm run dev` +1. Start NanoClaw in dev mode: `pnpm run dev` 2. From the **main group** (self-chat), send exactly: `/compact` 3. Verify: - The agent acknowledges compaction (e.g., "Conversation compacted.") @@ -104,8 +104,8 @@ launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS git clone /tmp/nanoclaw-test cd /tmp/nanoclaw-test claude # then run /add-compact -npm run build -npm test +pnpm run build +pnpm test ./container/build.sh # Manual: send /compact from main group, verify compaction + continuation # Manual: send @ /compact from non-main as non-admin, verify denial diff --git a/.claude/skills/add-discord-v2/SKILL.md b/.claude/skills/add-discord-v2/SKILL.md index f0c077179..f4b8c97ce 100644 --- a/.claude/skills/add-discord-v2/SKILL.md +++ b/.claude/skills/add-discord-v2/SKILL.md @@ -26,7 +26,7 @@ import './discord.js'; ### Build ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-discord/SKILL.md b/.claude/skills/add-discord/SKILL.md index e46bd3ef3..9ca6f2145 100644 --- a/.claude/skills/add-discord/SKILL.md +++ b/.claude/skills/add-discord/SKILL.md @@ -40,8 +40,8 @@ git remote add discord https://github.com/qwibitai/nanoclaw-discord.git ```bash git fetch discord main git merge discord/main || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -58,9 +58,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/channels/discord.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/discord.test.ts ``` All tests must pass (including the new Discord tests) and build must be clean before proceeding. @@ -108,7 +108,7 @@ The container reads environment from `data/env/env`, not `.env` directly. ### Build and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw ``` @@ -130,18 +130,18 @@ Wait for the user to provide the channel ID (format: `dc:1234567890123456`). ### Register the channel -The channel ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags. +The channel ID, name, and folder name are needed. Use `pnpm exec tsx setup/index.ts --step register` with the appropriate flags. For a main channel (responds to all messages): ```bash -npx tsx setup/index.ts --step register -- --jid "dc:" --name " #" --folder "discord_main" --trigger "@${ASSISTANT_NAME}" --channel discord --no-trigger-required --is-main +pnpm exec tsx setup/index.ts --step register -- --jid "dc:" --name " #" --folder "discord_main" --trigger "@${ASSISTANT_NAME}" --channel discord --no-trigger-required --is-main ``` For additional channels (trigger-only): ```bash -npx tsx setup/index.ts --step register -- --jid "dc:" --name " #" --folder "discord_" --trigger "@${ASSISTANT_NAME}" --channel discord +pnpm exec tsx setup/index.ts --step register -- --jid "dc:" --name " #" --folder "discord_" --trigger "@${ASSISTANT_NAME}" --channel discord ``` ## Phase 5: Verify diff --git a/.claude/skills/add-emacs/SKILL.md b/.claude/skills/add-emacs/SKILL.md index 09bdbdd7f..8a4100e92 100644 --- a/.claude/skills/add-emacs/SKILL.md +++ b/.claude/skills/add-emacs/SKILL.md @@ -51,12 +51,12 @@ git fetch upstream skill/emacs git merge upstream/skill/emacs ``` -If there are merge conflicts on `package-lock.json`, resolve them by accepting the incoming +If there are merge conflicts on `pnpm-lock.yaml`, resolve them by accepting the incoming version and continuing: ```bash -git checkout --theirs package-lock.json -git add package-lock.json +git checkout --theirs pnpm-lock.yaml +git add pnpm-lock.yaml git merge --continue ``` @@ -73,8 +73,8 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm run build -npx vitest run src/channels/emacs.test.ts +pnpm run build +pnpm exec vitest run src/channels/emacs.test.ts ``` Build must be clean and tests must pass before proceeding. @@ -158,7 +158,7 @@ If `EMACS_CHANNEL_PORT` was changed from the default, also add: ### Restart NanoClaw ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -246,18 +246,18 @@ If NanoClaw is cloned elsewhere, update the `load`/`load-file` path in your Emac ## After Setup -If running `npm run dev` while the service is active: +If running `pnpm run dev` while the service is active: ```bash # macOS: launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist -npm run dev +pnpm run dev # When done testing: launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist # Linux: # systemctl --user stop nanoclaw -# npm run dev +# pnpm run dev # systemctl --user start nanoclaw ``` @@ -286,4 +286,4 @@ To remove the Emacs channel: 3. Remove the NanoClaw block from your Emacs config file 4. Remove Emacs registration from SQLite: `sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid = 'emacs:default'"` 5. Remove `EMACS_CHANNEL_PORT` and `EMACS_AUTH_TOKEN` from `.env` if set -6. Rebuild: `npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `npm run build && systemctl --user restart nanoclaw` (Linux) \ No newline at end of file +6. Rebuild: `pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `pnpm run build && systemctl --user restart nanoclaw` (Linux) \ No newline at end of file diff --git a/.claude/skills/add-gchat-v2/REMOVE.md b/.claude/skills/add-gchat-v2/REMOVE.md index 7bf56deb3..a88cbb213 100644 --- a/.claude/skills/add-gchat-v2/REMOVE.md +++ b/.claude/skills/add-gchat-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './gchat.js'` in `src/channels/index.ts` 2. Remove `GCHAT_CREDENTIALS` from `.env` -3. `npm uninstall @chat-adapter/gchat` +3. `ppnpm uninstall @chat-adapter/gchat` 4. Rebuild and restart diff --git a/.claude/skills/add-gchat-v2/SKILL.md b/.claude/skills/add-gchat-v2/SKILL.md index df1ab946a..6f0ed12a0 100644 --- a/.claude/skills/add-gchat-v2/SKILL.md +++ b/.claude/skills/add-gchat-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/gchat.ts` exists and the import is uncommented in `src/ch ## Install ```bash -npm install @chat-adapter/gchat +pnpm install @chat-adapter/gchat ``` Uncomment the Google Chat import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './gchat.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-github-v2/REMOVE.md b/.claude/skills/add-github-v2/REMOVE.md index 8f04e8357..9d0b05bd9 100644 --- a/.claude/skills/add-github-v2/REMOVE.md +++ b/.claude/skills/add-github-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './github.js'` in `src/channels/index.ts` 2. Remove `GITHUB_TOKEN` and `GITHUB_WEBHOOK_SECRET` from `.env` -3. `npm uninstall @chat-adapter/github` +3. `ppnpm uninstall @chat-adapter/github` 4. Rebuild and restart diff --git a/.claude/skills/add-github-v2/SKILL.md b/.claude/skills/add-github-v2/SKILL.md index 3ade91d41..99da98489 100644 --- a/.claude/skills/add-github-v2/SKILL.md +++ b/.claude/skills/add-github-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/github.ts` exists and the import is uncommented in `src/c ## Install ```bash -npm install @chat-adapter/github +pnpm install @chat-adapter/github ``` Uncomment the GitHub import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './github.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-gmail/SKILL.md b/.claude/skills/add-gmail/SKILL.md index 099ec5b9e..055d8fe7c 100644 --- a/.claude/skills/add-gmail/SKILL.md +++ b/.claude/skills/add-gmail/SKILL.md @@ -41,8 +41,8 @@ git remote add gmail https://github.com/qwibitai/nanoclaw-gmail.git ```bash git fetch gmail main git merge gmail/main || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -70,9 +70,9 @@ When you receive an email notification (messages starting with `[Email from ...` ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/channels/gmail.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/gmail.test.ts ``` All tests must pass (including the new Gmail tests) and build must be clean before proceeding. @@ -136,10 +136,10 @@ Tell the user: Run the authorization: ```bash -npx -y @gongrzhe/server-gmail-autoauth-mcp auth +pnpm dlx @gongrzhe/server-gmail-autoauth-mcp auth ``` -If that fails (some versions don't have an auth subcommand), try `timeout 60 npx -y @gongrzhe/server-gmail-autoauth-mcp || true`. Verify with `ls ~/.gmail-mcp/credentials.json`. +If that fails (some versions don't have an auth subcommand), try `timeout 60 pnpm dlx @gongrzhe/server-gmail-autoauth-mcp || true`. Verify with `ls ~/.gmail-mcp/credentials.json`. ### Build and restart @@ -158,7 +158,7 @@ cd container && ./build.sh Then compile and restart: ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -192,7 +192,7 @@ tail -f logs/nanoclaw.log Test directly: ```bash -npx -y @gongrzhe/server-gmail-autoauth-mcp +pnpm dlx @gongrzhe/server-gmail-autoauth-mcp ``` ### OAuth token expired @@ -201,7 +201,7 @@ Re-authorize: ```bash rm ~/.gmail-mcp/credentials.json -npx -y @gongrzhe/server-gmail-autoauth-mcp +pnpm dlx @gongrzhe/server-gmail-autoauth-mcp ``` ### Container can't access Gmail @@ -222,7 +222,7 @@ npx -y @gongrzhe/server-gmail-autoauth-mcp 2. Remove `gmail` MCP server and `mcp__gmail__*` from `container/agent-runner/src/index.ts` 3. Rebuild and restart 4. Clear stale agent-runner copies: `rm -r data/sessions/*/agent-runner-src 2>/dev/null || true` -5. Rebuild: `cd container && ./build.sh && cd .. && npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) +5. Rebuild: `cd container && ./build.sh && cd .. && pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) ### Channel mode @@ -230,7 +230,7 @@ npx -y @gongrzhe/server-gmail-autoauth-mcp 2. Remove `import './gmail.js'` from `src/channels/index.ts` 3. Remove `~/.gmail-mcp` mount from `src/container-runner.ts` 4. Remove `gmail` MCP server and `mcp__gmail__*` from `container/agent-runner/src/index.ts` -5. Uninstall: `npm uninstall googleapis` +5. Uninstall: `ppnpm uninstall googleapis` 6. Rebuild and restart 7. Clear stale agent-runner copies: `rm -r data/sessions/*/agent-runner-src 2>/dev/null || true` -8. Rebuild: `cd container && ./build.sh && cd .. && npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) +8. Rebuild: `cd container && ./build.sh && cd .. && pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) diff --git a/.claude/skills/add-image-vision/SKILL.md b/.claude/skills/add-image-vision/SKILL.md index 072bf7b92..4a9da26ee 100644 --- a/.claude/skills/add-image-vision/SKILL.md +++ b/.claude/skills/add-image-vision/SKILL.md @@ -33,8 +33,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp skill/image-vision git merge whatsapp/skill/image-vision || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -52,9 +52,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/image.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/image.test.ts ``` All tests must pass and build must be clean before proceeding. @@ -90,5 +90,5 @@ All tests must pass and build must be clean before proceeding. ## Troubleshooting - **"Image - download failed"**: Check WhatsApp connection stability. The download may timeout on slow connections. -- **"Image - processing failed"**: Sharp may not be installed correctly. Run `npm ls sharp` to verify. +- **"Image - processing failed"**: Sharp may not be installed correctly. Run `pnpm ls sharp` to verify. - **Agent doesn't mention image content**: Check container logs for "Loaded image" messages. If missing, ensure agent-runner source was synced to group caches. diff --git a/.claude/skills/add-imessage-v2/REMOVE.md b/.claude/skills/add-imessage-v2/REMOVE.md index 3163e858e..d9d8aefda 100644 --- a/.claude/skills/add-imessage-v2/REMOVE.md +++ b/.claude/skills/add-imessage-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './imessage.js'` in `src/channels/index.ts` 2. Remove iMessage env vars (`IMESSAGE_ENABLED`, `IMESSAGE_LOCAL`, `IMESSAGE_SERVER_URL`, `IMESSAGE_API_KEY`) from `.env` -3. `npm uninstall chat-adapter-imessage` +3. `ppnpm uninstall chat-adapter-imessage` 4. Rebuild and restart diff --git a/.claude/skills/add-imessage-v2/SKILL.md b/.claude/skills/add-imessage-v2/SKILL.md index 87cd0ce45..348519b64 100644 --- a/.claude/skills/add-imessage-v2/SKILL.md +++ b/.claude/skills/add-imessage-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/imessage.ts` exists and the import is uncommented in `src ## Install ```bash -npm install chat-adapter-imessage +pnpm install chat-adapter-imessage ``` Uncomment the iMessage import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './imessage.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-karpathy-llm-wiki/SKILL.md b/.claude/skills/add-karpathy-llm-wiki/SKILL.md index 9c728a849..12b9b37d4 100644 --- a/.claude/skills/add-karpathy-llm-wiki/SKILL.md +++ b/.claude/skills/add-karpathy-llm-wiki/SKILL.md @@ -19,7 +19,7 @@ AskUserQuestion: "Which group should have the wiki?" 2. **Dedicated group** — create a new group just for the wiki 3. **Other** — pick an existing group -If dedicated: ask which channel and chat, then register with `npx tsx setup/index.ts --step register`. +If dedicated: ask which channel and chat, then register with `pnpm exec tsx setup/index.ts --step register`. ## Step 3: Design collaboratively @@ -74,7 +74,7 @@ AskUserQuestion: "Want periodic wiki health checks?" If yes, create a NanoClaw scheduled task that runs in the wiki group. This is NOT a Claude Code cron job — it's a NanoClaw group task that runs in the agent container. Insert it into the SQLite database: ```bash -npx tsx -e " +pnpm exec tsx -e " const Database = require('better-sqlite3'); const { CronExpressionParser } = require('cron-parser'); const db = new Database('store/messages.db'); @@ -101,7 +101,7 @@ Use the group's `folder` and `chat_jid` from the registered groups table. Cron e ## Step 6: Build and restart ```bash -npm run build +pnpm run build ./container/build.sh launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw diff --git a/.claude/skills/add-linear-v2/REMOVE.md b/.claude/skills/add-linear-v2/REMOVE.md index 858c0001d..270c02cbd 100644 --- a/.claude/skills/add-linear-v2/REMOVE.md +++ b/.claude/skills/add-linear-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './linear.js'` in `src/channels/index.ts` 2. Remove `LINEAR_API_KEY` and `LINEAR_WEBHOOK_SECRET` from `.env` -3. `npm uninstall @chat-adapter/linear` +3. `ppnpm uninstall @chat-adapter/linear` 4. Rebuild and restart diff --git a/.claude/skills/add-linear-v2/SKILL.md b/.claude/skills/add-linear-v2/SKILL.md index ef3cbc65e..6e954893d 100644 --- a/.claude/skills/add-linear-v2/SKILL.md +++ b/.claude/skills/add-linear-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/linear.ts` exists and the import is uncommented in `src/c ## Install ```bash -npm install @chat-adapter/linear +pnpm install @chat-adapter/linear ``` Uncomment the Linear import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './linear.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-matrix-v2/REMOVE.md b/.claude/skills/add-matrix-v2/REMOVE.md index 0f5ca1c51..3cb67536a 100644 --- a/.claude/skills/add-matrix-v2/REMOVE.md +++ b/.claude/skills/add-matrix-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './matrix.js'` in `src/channels/index.ts` 2. Remove `MATRIX_BASE_URL`, `MATRIX_ACCESS_TOKEN`, `MATRIX_USER_ID`, `MATRIX_BOT_USERNAME` from `.env` -3. `npm uninstall @beeper/chat-adapter-matrix` +3. `ppnpm uninstall @beeper/chat-adapter-matrix` 4. Rebuild and restart diff --git a/.claude/skills/add-matrix-v2/SKILL.md b/.claude/skills/add-matrix-v2/SKILL.md index 59ea5e6cb..d2e54ba21 100644 --- a/.claude/skills/add-matrix-v2/SKILL.md +++ b/.claude/skills/add-matrix-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/matrix.ts` exists and the import is uncommented in `src/c ## Install ```bash -npm install @beeper/chat-adapter-matrix +pnpm install @beeper/chat-adapter-matrix ``` Uncomment the Matrix import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './matrix.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-ollama-tool/SKILL.md b/.claude/skills/add-ollama-tool/SKILL.md index aa692958a..8c7abcad5 100644 --- a/.claude/skills/add-ollama-tool/SKILL.md +++ b/.claude/skills/add-ollama-tool/SKILL.md @@ -87,7 +87,7 @@ done ### Validate code changes ```bash -npm run build +pnpm run build ./container/build.sh ``` diff --git a/.claude/skills/add-parallel/SKILL.md b/.claude/skills/add-parallel/SKILL.md index f4c19828e..a9dff8f2a 100644 --- a/.claude/skills/add-parallel/SKILL.md +++ b/.claude/skills/add-parallel/SKILL.md @@ -232,7 +232,7 @@ echo '{}' | docker run -i --entrypoint /bin/echo nanoclaw-agent:latest "Containe Rebuild the main app and restart: ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -286,5 +286,5 @@ To remove Parallel AI integration: 1. Remove from .env: `sed -i.bak '/PARALLEL_API_KEY/d' .env` 2. Revert changes to container-runner.ts and agent-runner/src/index.ts 3. Remove Web Research Tools section from groups/main/CLAUDE.md -4. Rebuild: `./container/build.sh && npm run build` +4. Rebuild: `./container/build.sh && pnpm run build` 5. Restart: `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) diff --git a/.claude/skills/add-pdf-reader/SKILL.md b/.claude/skills/add-pdf-reader/SKILL.md index a01e53097..aecc347b5 100644 --- a/.claude/skills/add-pdf-reader/SKILL.md +++ b/.claude/skills/add-pdf-reader/SKILL.md @@ -31,8 +31,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp skill/pdf-reader git merge whatsapp/skill/pdf-reader || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -49,8 +49,8 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate ```bash -npm run build -npx vitest run src/channels/whatsapp.test.ts +pnpm run build +pnpm exec vitest run src/channels/whatsapp.test.ts ``` ### Rebuild container diff --git a/.claude/skills/add-reactions/SKILL.md b/.claude/skills/add-reactions/SKILL.md index de867682b..435bef9c8 100644 --- a/.claude/skills/add-reactions/SKILL.md +++ b/.claude/skills/add-reactions/SKILL.md @@ -38,8 +38,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp skill/reactions git merge whatsapp/skill/reactions || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -54,14 +54,14 @@ This adds: ### Run database migration ```bash -npx tsx scripts/migrate-reactions.ts +pnpm exec tsx scripts/migrate-reactions.ts ``` ### Validate code changes ```bash -npm test -npm run build +pnpm test +pnpm run build ``` All tests must pass and build must be clean before proceeding. @@ -71,7 +71,7 @@ All tests must pass and build must be clean before proceeding. ### Build and restart ```bash -npm run build +pnpm run build ``` Linux: diff --git a/.claude/skills/add-resend-v2/REMOVE.md b/.claude/skills/add-resend-v2/REMOVE.md index 83e7a44d0..4d384146e 100644 --- a/.claude/skills/add-resend-v2/REMOVE.md +++ b/.claude/skills/add-resend-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './resend.js'` in `src/channels/index.ts` 2. Remove `RESEND_API_KEY`, `RESEND_FROM_ADDRESS`, `RESEND_FROM_NAME`, `RESEND_WEBHOOK_SECRET` from `.env` -3. `npm uninstall @resend/chat-sdk-adapter` +3. `ppnpm uninstall @resend/chat-sdk-adapter` 4. Rebuild and restart diff --git a/.claude/skills/add-resend-v2/SKILL.md b/.claude/skills/add-resend-v2/SKILL.md index eaf0e92c5..8e9ba14e0 100644 --- a/.claude/skills/add-resend-v2/SKILL.md +++ b/.claude/skills/add-resend-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/resend.ts` exists and the import is uncommented in `src/c ## Install ```bash -npm install @resend/chat-sdk-adapter +pnpm install @resend/chat-sdk-adapter ``` Uncomment the Resend import in `src/channels/index.ts`: @@ -26,7 +26,7 @@ import './resend.js'; Build: ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-slack-v2/REMOVE.md b/.claude/skills/add-slack-v2/REMOVE.md index 140fbe785..e489d4c0c 100644 --- a/.claude/skills/add-slack-v2/REMOVE.md +++ b/.claude/skills/add-slack-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './slack.js'` in `src/channels/index.ts` 2. Remove `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` from `.env` -3. `npm uninstall @chat-adapter/slack` +3. `ppnpm uninstall @chat-adapter/slack` 4. Rebuild and restart diff --git a/.claude/skills/add-slack-v2/SKILL.md b/.claude/skills/add-slack-v2/SKILL.md index dff3e556e..b18115feb 100644 --- a/.claude/skills/add-slack-v2/SKILL.md +++ b/.claude/skills/add-slack-v2/SKILL.md @@ -16,7 +16,7 @@ Check if `src/channels/slack.ts` exists and the import is uncommented in `src/ch ### Install the adapter package ```bash -npm install @chat-adapter/slack +pnpm install @chat-adapter/slack ``` ### Enable the channel @@ -30,7 +30,7 @@ import './slack.js'; ### Build ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-slack/SKILL.md b/.claude/skills/add-slack/SKILL.md index 4c86e1964..5f7fb5cf1 100644 --- a/.claude/skills/add-slack/SKILL.md +++ b/.claude/skills/add-slack/SKILL.md @@ -36,8 +36,8 @@ git remote add slack https://github.com/qwibitai/nanoclaw-slack.git ```bash git fetch slack main git merge slack/main || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -54,9 +54,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/channels/slack.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/slack.test.ts ``` All tests must pass (including the new Slack tests) and build must be clean before proceeding. @@ -98,7 +98,7 @@ The container reads environment from `data/env/env`, not `.env` directly. ### Build and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw ``` @@ -118,18 +118,18 @@ Wait for the user to provide the channel ID. ### Register the channel -The channel ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags. +The channel ID, name, and folder name are needed. Use `pnpm exec tsx setup/index.ts --step register` with the appropriate flags. For a main channel (responds to all messages): ```bash -npx tsx setup/index.ts --step register -- --jid "slack:" --name "" --folder "slack_main" --trigger "@${ASSISTANT_NAME}" --channel slack --no-trigger-required --is-main +pnpm exec tsx setup/index.ts --step register -- --jid "slack:" --name "" --folder "slack_main" --trigger "@${ASSISTANT_NAME}" --channel slack --no-trigger-required --is-main ``` For additional channels (trigger-only): ```bash -npx tsx setup/index.ts --step register -- --jid "slack:" --name "" --folder "slack_" --trigger "@${ASSISTANT_NAME}" --channel slack +pnpm exec tsx setup/index.ts --step register -- --jid "slack:" --name "" --folder "slack_" --trigger "@${ASSISTANT_NAME}" --channel slack ``` ## Phase 5: Verify diff --git a/.claude/skills/add-teams-v2/REMOVE.md b/.claude/skills/add-teams-v2/REMOVE.md index e921cfbf3..e35415cdb 100644 --- a/.claude/skills/add-teams-v2/REMOVE.md +++ b/.claude/skills/add-teams-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './teams.js'` in `src/channels/index.ts` 2. Remove `TEAMS_APP_ID` and `TEAMS_APP_PASSWORD` from `.env` -3. `npm uninstall @chat-adapter/teams` +3. `ppnpm uninstall @chat-adapter/teams` 4. Rebuild and restart diff --git a/.claude/skills/add-teams-v2/SKILL.md b/.claude/skills/add-teams-v2/SKILL.md index b7c34442b..931bc670f 100644 --- a/.claude/skills/add-teams-v2/SKILL.md +++ b/.claude/skills/add-teams-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/teams.ts` exists and the import is uncommented in `src/ch ## Install ```bash -npm install @chat-adapter/teams +pnpm install @chat-adapter/teams ``` Uncomment the Teams import in `src/channels/index.ts`: @@ -26,7 +26,7 @@ import './teams.js'; Build: ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-telegram-swarm/SKILL.md b/.claude/skills/add-telegram-swarm/SKILL.md index ac4922c49..8f6a4fc27 100644 --- a/.claude/skills/add-telegram-swarm/SKILL.md +++ b/.claude/skills/add-telegram-swarm/SKILL.md @@ -319,7 +319,7 @@ Also add `TELEGRAM_BOT_POOL` to the launchd plist (`~/Library/LaunchAgents/com.n ### Step 7: Rebuild and Restart ```bash -npm run build +pnpm run build ./container/build.sh # Required — MCP tool changed # macOS: launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist @@ -381,4 +381,4 @@ To remove Agent Swarm support while keeping basic Telegram: 5. Remove `sender` param from MCP tool in `container/agent-runner/src/ipc-mcp-stdio.ts` 6. Remove Agent Teams section from group CLAUDE.md files 7. Remove `TELEGRAM_BOT_POOL` from `.env`, `data/env/env`, and launchd plist/systemd unit -8. Rebuild: `npm run build && ./container/build.sh && launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist && launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist` (macOS) or `npm run build && ./container/build.sh && systemctl --user restart nanoclaw` (Linux) +8. Rebuild: `pnpm run build && ./container/build.sh && launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist && launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist` (macOS) or `pnpm run build && ./container/build.sh && systemctl --user restart nanoclaw` (Linux) diff --git a/.claude/skills/add-telegram-v2/REMOVE.md b/.claude/skills/add-telegram-v2/REMOVE.md index 9fd37cf6c..8d7c5b09e 100644 --- a/.claude/skills/add-telegram-v2/REMOVE.md +++ b/.claude/skills/add-telegram-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './telegram.js'` in `src/channels/index.ts` 2. Remove `TELEGRAM_BOT_TOKEN` from `.env` -3. `npm uninstall @chat-adapter/telegram` +3. `ppnpm uninstall @chat-adapter/telegram` 4. Rebuild and restart diff --git a/.claude/skills/add-telegram-v2/SKILL.md b/.claude/skills/add-telegram-v2/SKILL.md index 1b1ebec70..e4e78fe27 100644 --- a/.claude/skills/add-telegram-v2/SKILL.md +++ b/.claude/skills/add-telegram-v2/SKILL.md @@ -16,7 +16,7 @@ Check if `src/channels/telegram.ts` exists and the import is uncommented in `src ### Install the adapter package ```bash -npm install @chat-adapter/telegram +pnpm install @chat-adapter/telegram ``` ### Enable the channel @@ -30,7 +30,7 @@ import './telegram.js'; ### Build ```bash -npm run build +pnpm run build ``` ## Credentials @@ -68,7 +68,7 @@ Otherwise, run `/manage-channels` to wire this channel to an agent group. - **type**: `telegram` - **terminology**: Telegram calls them "groups" and "chats." A "group" has multiple members; a "chat" is a 1:1 conversation with the bot. -- **how-to-find-id**: Do NOT ask the user for a chat ID. Telegram registration uses pairing — run `npx tsx setup/index.ts --step pair-telegram -- --intent `, show the user the 4-digit `CODE` from the `PAIR_TELEGRAM_ISSUED` block (follow the `REMINDER_TO_ASSISTANT` line in that block), and tell them to send just the 4 digits as a message from the chat they want to register (DM the bot for `main`, post in the group otherwise). In groups with Group Privacy ON, prefix with the bot handle: `@ CODE`. Wrong guesses invalidate the code — if a `PAIR_TELEGRAM_ATTEMPT` block arrives with a mismatched `RECEIVED_CODE`, a `PAIR_TELEGRAM_NEW_CODE` block will follow automatically (up to 5 regenerations); show the new code. On `PAIR_TELEGRAM STATUS=failed ERROR=max-regenerations-exceeded`, ask the user if they want to try again and re-invoke the step — each invocation starts a fresh 5-attempt batch. Success emits `PAIR_TELEGRAM STATUS=success` with `PLATFORM_ID`, `IS_GROUP`, and `ADMIN_USER_ID`. The service must be running for this to work (the polling adapter is what observes the code). +- **how-to-find-id**: Do NOT ask the user for a chat ID. Telegram registration uses pairing — run `pnpm exec tsx setup/index.ts --step pair-telegram -- --intent `, show the user the 4-digit `CODE` from the `PAIR_TELEGRAM_ISSUED` block (follow the `REMINDER_TO_ASSISTANT` line in that block), and tell them to send just the 4 digits as a message from the chat they want to register (DM the bot for `main`, post in the group otherwise). In groups with Group Privacy ON, prefix with the bot handle: `@ CODE`. Wrong guesses invalidate the code — if a `PAIR_TELEGRAM_ATTEMPT` block arrives with a mismatched `RECEIVED_CODE`, a `PAIR_TELEGRAM_NEW_CODE` block will follow automatically (up to 5 regenerations); show the new code. On `PAIR_TELEGRAM STATUS=failed ERROR=max-regenerations-exceeded`, ask the user if they want to try again and re-invoke the step — each invocation starts a fresh 5-attempt batch. Success emits `PAIR_TELEGRAM STATUS=success` with `PLATFORM_ID`, `IS_GROUP`, and `ADMIN_USER_ID`. The service must be running for this to work (the polling adapter is what observes the code). - **supports-threads**: no - **typical-use**: Interactive chat — direct messages or small groups - **default-isolation**: Same agent group if you're the only participant across multiple chats. Separate agent group if different people are in different groups. diff --git a/.claude/skills/add-telegram/SKILL.md b/.claude/skills/add-telegram/SKILL.md index 609f39462..e95dcce38 100644 --- a/.claude/skills/add-telegram/SKILL.md +++ b/.claude/skills/add-telegram/SKILL.md @@ -40,8 +40,8 @@ git remote add telegram https://github.com/qwibitai/nanoclaw-telegram.git ```bash git fetch telegram main git merge telegram/main || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -58,9 +58,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/channels/telegram.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/telegram.test.ts ``` All tests must pass (including the new Telegram tests) and build must be clean before proceeding. @@ -114,7 +114,7 @@ Tell the user: ### Build and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -133,18 +133,18 @@ Wait for the user to provide the chat ID (format: `tg:123456789` or `tg:-1001234 ### Register the chat -The chat ID, name, and folder name are needed. Use `npx tsx setup/index.ts --step register` with the appropriate flags. +The chat ID, name, and folder name are needed. Use `pnpm exec tsx setup/index.ts --step register` with the appropriate flags. For a main chat (responds to all messages): ```bash -npx tsx setup/index.ts --step register -- --jid "tg:" --name "" --folder "telegram_main" --trigger "@${ASSISTANT_NAME}" --channel telegram --no-trigger-required --is-main +pnpm exec tsx setup/index.ts --step register -- --jid "tg:" --name "" --folder "telegram_main" --trigger "@${ASSISTANT_NAME}" --channel telegram --no-trigger-required --is-main ``` For additional chats (trigger-only): ```bash -npx tsx setup/index.ts --step register -- --jid "tg:" --name "" --folder "telegram_" --trigger "@${ASSISTANT_NAME}" --channel telegram +pnpm exec tsx setup/index.ts --step register -- --jid "tg:" --name "" --folder "telegram_" --trigger "@${ASSISTANT_NAME}" --channel telegram ``` ## Phase 5: Verify @@ -189,16 +189,16 @@ If `/chatid` doesn't work: ## After Setup -If running `npm run dev` while the service is active: +If running `pnpm run dev` while the service is active: ```bash # macOS: launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist -npm run dev +pnpm run dev # When done testing: launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist # Linux: # systemctl --user stop nanoclaw -# npm run dev +# pnpm run dev # systemctl --user start nanoclaw ``` @@ -210,5 +210,5 @@ To remove Telegram integration: 2. Remove `import './telegram.js'` from `src/channels/index.ts` 3. Remove `TELEGRAM_BOT_TOKEN` from `.env` 4. Remove Telegram registrations from SQLite: `sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE 'tg:%'"` -5. Uninstall: `npm uninstall grammy` -6. Rebuild: `npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `npm run build && systemctl --user restart nanoclaw` (Linux) +5. Uninstall: `ppnpm uninstall grammy` +6. Rebuild: `pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `pnpm run build && systemctl --user restart nanoclaw` (Linux) diff --git a/.claude/skills/add-voice-transcription/SKILL.md b/.claude/skills/add-voice-transcription/SKILL.md index 8ccec324d..cae1e4749 100644 --- a/.claude/skills/add-voice-transcription/SKILL.md +++ b/.claude/skills/add-voice-transcription/SKILL.md @@ -42,8 +42,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp skill/voice-transcription git merge whatsapp/skill/voice-transcription || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -60,9 +60,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install --legacy-peer-deps -npm run build -npx vitest run src/channels/whatsapp.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/whatsapp.test.ts ``` All tests must pass and build must be clean before proceeding. @@ -103,7 +103,7 @@ The container reads environment from `data/env/env`, not `.env` directly. ### Build and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` diff --git a/.claude/skills/add-webex-v2/REMOVE.md b/.claude/skills/add-webex-v2/REMOVE.md index 2dc5c1ffe..d2d255679 100644 --- a/.claude/skills/add-webex-v2/REMOVE.md +++ b/.claude/skills/add-webex-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './webex.js'` in `src/channels/index.ts` 2. Remove `WEBEX_BOT_TOKEN` and `WEBEX_WEBHOOK_SECRET` from `.env` -3. `npm uninstall @bitbasti/chat-adapter-webex` +3. `ppnpm uninstall @bitbasti/chat-adapter-webex` 4. Rebuild and restart diff --git a/.claude/skills/add-webex-v2/SKILL.md b/.claude/skills/add-webex-v2/SKILL.md index 830b587ba..f6e178608 100644 --- a/.claude/skills/add-webex-v2/SKILL.md +++ b/.claude/skills/add-webex-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/webex.ts` exists and the import is uncommented in `src/ch ## Install ```bash -npm install @bitbasti/chat-adapter-webex +pnpm install @bitbasti/chat-adapter-webex ``` Uncomment the Webex import in `src/channels/index.ts`: @@ -24,7 +24,7 @@ import './webex.js'; ``` ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-whatsapp-cloud-v2/REMOVE.md b/.claude/skills/add-whatsapp-cloud-v2/REMOVE.md index 12c2feb57..ab3d3690d 100644 --- a/.claude/skills/add-whatsapp-cloud-v2/REMOVE.md +++ b/.claude/skills/add-whatsapp-cloud-v2/REMOVE.md @@ -2,5 +2,5 @@ 1. Comment out `import './whatsapp-cloud.js'` in `src/channels/index.ts` 2. Remove `WHATSAPP_ACCESS_TOKEN`, `WHATSAPP_PHONE_NUMBER_ID`, `WHATSAPP_APP_SECRET`, `WHATSAPP_VERIFY_TOKEN` from `.env` -3. `npm uninstall @chat-adapter/whatsapp` +3. `ppnpm uninstall @chat-adapter/whatsapp` 4. Rebuild and restart diff --git a/.claude/skills/add-whatsapp-cloud-v2/SKILL.md b/.claude/skills/add-whatsapp-cloud-v2/SKILL.md index 4f7709ee5..2e1e37677 100644 --- a/.claude/skills/add-whatsapp-cloud-v2/SKILL.md +++ b/.claude/skills/add-whatsapp-cloud-v2/SKILL.md @@ -14,7 +14,7 @@ Check if `src/channels/whatsapp-cloud.ts` exists and the import is uncommented i ## Install ```bash -npm install @chat-adapter/whatsapp +pnpm install @chat-adapter/whatsapp ``` Uncomment the WhatsApp Cloud API import in `src/channels/index.ts`: @@ -26,7 +26,7 @@ import './whatsapp-cloud.js'; Build: ```bash -npm run build +pnpm run build ``` ## Credentials diff --git a/.claude/skills/add-whatsapp/SKILL.md b/.claude/skills/add-whatsapp/SKILL.md index cbdf00b73..0ece16961 100644 --- a/.claude/skills/add-whatsapp/SKILL.md +++ b/.claude/skills/add-whatsapp/SKILL.md @@ -63,8 +63,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp main git merge whatsapp/main || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -84,9 +84,9 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/channels/whatsapp.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/channels/whatsapp.test.ts ``` All tests must pass and build must be clean before proceeding. @@ -104,7 +104,7 @@ rm -rf store/auth/ For QR code in browser (recommended): ```bash -npx tsx setup/index.ts --step whatsapp-auth -- --method qr-browser +pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method qr-browser ``` (Bash timeout: 150000ms) @@ -120,10 +120,10 @@ Tell the user: For QR code in terminal: ```bash -npx tsx setup/index.ts --step whatsapp-auth -- --method qr-terminal +pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method qr-terminal ``` -Tell the user to run `npm run auth` in another terminal, then: +Tell the user to run `pnpm run auth` in another terminal, then: > 1. Open WhatsApp > **Settings** > **Linked Devices** > **Link a Device** > 2. Scan the QR code displayed in the terminal @@ -135,7 +135,7 @@ Tell the user to have WhatsApp open on **Settings > Linked Devices > Link a Devi Run the auth process in the background and poll `store/pairing-code.txt` for the code: ```bash -rm -f store/pairing-code.txt && npx tsx setup/index.ts --step whatsapp-auth -- --method pairing-code --phone > /tmp/wa-auth.log 2>&1 & +rm -f store/pairing-code.txt && pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method pairing-code --phone > /tmp/wa-auth.log 2>&1 & ``` Then immediately poll for the code (do NOT wait for the background command to finish): @@ -221,8 +221,8 @@ node -e "const c=JSON.parse(require('fs').readFileSync('store/auth/creds.json',' **Group (solo, existing):** Run group sync and list available groups: ```bash -npx tsx setup/index.ts --step groups -npx tsx setup/index.ts --step groups --list +pnpm exec tsx setup/index.ts --step groups +pnpm exec tsx setup/index.ts --step groups --list ``` The output shows `JID|GroupName` pairs. Present candidates as AskUserQuestion (names only, not JIDs). @@ -230,7 +230,7 @@ The output shows `JID|GroupName` pairs. Present candidates as AskUserQuestion (n ### Register the chat ```bash -npx tsx setup/index.ts --step register \ +pnpm exec tsx setup/index.ts --step register \ --jid "" \ --name "" \ --trigger "@" \ @@ -244,7 +244,7 @@ npx tsx setup/index.ts --step register \ For additional groups (trigger-required): ```bash -npx tsx setup/index.ts --step register \ +pnpm exec tsx setup/index.ts --step register \ --jid "" \ --name "" \ --trigger "@" \ @@ -257,7 +257,7 @@ npx tsx setup/index.ts --step register \ ### Build and restart ```bash -npm run build +pnpm run build ``` Restart the service: @@ -296,7 +296,7 @@ tail -f logs/nanoclaw.log QR codes expire after ~60 seconds. Re-run the auth command: ```bash -rm -rf store/auth/ && npx tsx src/whatsapp-auth.ts +rm -rf store/auth/ && pnpm exec tsx src/whatsapp-auth.ts ``` ### Pairing code not working @@ -304,7 +304,7 @@ rm -rf store/auth/ && npx tsx src/whatsapp-auth.ts Codes expire in ~60 seconds. To retry: ```bash -rm -rf store/auth/ && npx tsx src/whatsapp-auth.ts --pairing-code --phone +rm -rf store/auth/ && pnpm exec tsx src/whatsapp-auth.ts --pairing-code --phone ``` Enter the code **immediately** when it appears. Also ensure: @@ -315,7 +315,7 @@ Enter the code **immediately** when it appears. Also ensure: If pairing code keeps failing, switch to QR-browser auth instead: ```bash -rm -rf store/auth/ && npx tsx setup/index.ts --step whatsapp-auth -- --method qr-browser +rm -rf store/auth/ && pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method qr-browser ``` ### "conflict" disconnection @@ -340,25 +340,25 @@ Check: Run group metadata sync: ```bash -npx tsx setup/index.ts --step groups +pnpm exec tsx setup/index.ts --step groups ``` This fetches all group names from WhatsApp. Runs automatically every 24 hours. ## After Setup -If running `npm run dev` while the service is active: +If running `pnpm run dev` while the service is active: ```bash # macOS: launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist -npm run dev +pnpm run dev # When done testing: launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist # Linux: # systemctl --user stop nanoclaw -# npm run dev +# pnpm run dev # systemctl --user start nanoclaw ``` @@ -369,4 +369,4 @@ To remove WhatsApp integration: 1. Delete auth credentials: `rm -rf store/auth/` 2. Remove WhatsApp registrations: `sqlite3 store/messages.db "DELETE FROM registered_groups WHERE jid LIKE '%@g.us' OR jid LIKE '%@s.whatsapp.net'"` 3. Sync env: `mkdir -p data/env && cp .env data/env/env` -4. Rebuild and restart: `npm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `npm run build && systemctl --user restart nanoclaw` (Linux) +4. Rebuild and restart: `pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `pnpm run build && systemctl --user restart nanoclaw` (Linux) diff --git a/.claude/skills/channel-formatting/SKILL.md b/.claude/skills/channel-formatting/SKILL.md index 3e2334c0b..8d27ffceb 100644 --- a/.claude/skills/channel-formatting/SKILL.md +++ b/.claude/skills/channel-formatting/SKILL.md @@ -51,12 +51,12 @@ git fetch upstream skill/channel-formatting git merge upstream/skill/channel-formatting ``` -If there are merge conflicts on `package-lock.json`, resolve them by accepting the incoming +If there are merge conflicts on `pnpm-lock.yaml`, resolve them by accepting the incoming version and continuing: ```bash -git checkout --theirs package-lock.json -git add package-lock.json +git checkout --theirs pnpm-lock.yaml +git add pnpm-lock.yaml git merge --continue ``` @@ -74,9 +74,9 @@ This merge adds: ### Validate ```bash -npm install -npm run build -npx vitest run src/formatting.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/formatting.test.ts ``` All 73 tests should pass and the build should be clean before continuing. @@ -86,7 +86,7 @@ All 73 tests should pass and the build should be clean before continuing. ### Rebuild and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -133,5 +133,5 @@ git checkout upstream/main -- src/router.ts # Revert the index.ts sendMessage call sites to plain formatOutbound(rawText) # (edit manually or: git checkout upstream/main -- src/index.ts) -npm run build +pnpm run build ``` \ No newline at end of file diff --git a/.claude/skills/convert-to-apple-container/SKILL.md b/.claude/skills/convert-to-apple-container/SKILL.md index c37633c2c..af6f39e1b 100644 --- a/.claude/skills/convert-to-apple-container/SKILL.md +++ b/.claude/skills/convert-to-apple-container/SKILL.md @@ -80,8 +80,8 @@ If the merge reports conflicts, resolve them by reading the conflicted files and ### Validate code changes ```bash -npm test -npm run build +pnpm test +pnpm run build ``` All tests must pass and build must be clean before proceeding. @@ -172,7 +172,7 @@ Expected: Both operations succeed. ### Full integration test ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw ``` diff --git a/.claude/skills/customize/SKILL.md b/.claude/skills/customize/SKILL.md index 614a97931..c83bd2689 100644 --- a/.claude/skills/customize/SKILL.md +++ b/.claude/skills/customize/SKILL.md @@ -91,7 +91,7 @@ Implementation: Always tell the user: ```bash # Rebuild and restart -npm run build +pnpm run build # macOS: launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist diff --git a/.claude/skills/debug/SKILL.md b/.claude/skills/debug/SKILL.md index 03c34ded5..128b8c380 100644 --- a/.claude/skills/debug/SKILL.md +++ b/.claude/skills/debug/SKILL.md @@ -41,7 +41,7 @@ Set `LOG_LEVEL=debug` for verbose output: ```bash # For development -LOG_LEVEL=debug npm run dev +LOG_LEVEL=debug pnpm run dev # For launchd service (macOS), add to plist EnvironmentVariables: LOG_LEVEL @@ -231,7 +231,7 @@ query({ ```bash # Rebuild main app -npm run build +pnpm run build # Rebuild container (use --no-cache for clean rebuild) ./container/build.sh diff --git a/.claude/skills/init-onecli/SKILL.md b/.claude/skills/init-onecli/SKILL.md index bd37b9656..b3d441fd8 100644 --- a/.claude/skills/init-onecli/SKILL.md +++ b/.claude/skills/init-onecli/SKILL.md @@ -231,10 +231,10 @@ Ask them to let you know when done. ## Phase 4: Build and restart ```bash -npm run build +pnpm run build ``` -If build fails, diagnose and fix. Common issue: `@onecli-sh/sdk` not installed — run `npm install` first. +If build fails, diagnose and fix. Common issue: `@onecli-sh/sdk` not installed — run `pnpm install` first. Restart the service: - macOS (launchd): `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` diff --git a/.claude/skills/manage-channels/SKILL.md b/.claude/skills/manage-channels/SKILL.md index bd2f724b8..c1bca292d 100644 --- a/.claude/skills/manage-channels/SKILL.md +++ b/.claude/skills/manage-channels/SKILL.md @@ -43,7 +43,7 @@ Use the channel's `typical-use` and `default-isolation` fields to pick the recom ### Register Command ```bash -npx tsx setup/index.ts --step register -- \ +pnpm exec tsx setup/index.ts --step register -- \ --platform-id "" --name "" \ --folder "" --channel "" \ --session-mode "" \ @@ -58,10 +58,10 @@ For separate agents, also ask for a folder name and optionally a different assis When adding another group/chat on an already-configured platform (e.g. a second Telegram group): -1. **Telegram:** ask the isolation question first to determine intent (`wire-to:` for an existing agent, `new-agent:` for a fresh one). Run `npx tsx setup/index.ts --step pair-telegram -- --intent `, show the CODE (follow the `REMINDER_TO_ASSISTANT` line in the `PAIR_TELEGRAM_ISSUED` block) and tell the user to post `@ CODE` in the target group (or DM the bot for a private chat). Wait for the `PAIR_TELEGRAM` block. The inbound interceptor has already created the `messaging_groups` row with `unknown_sender_policy = 'strict'` and upserted the paired user — `register` only needs to add the wiring: +1. **Telegram:** ask the isolation question first to determine intent (`wire-to:` for an existing agent, `new-agent:` for a fresh one). Run `pnpm exec tsx setup/index.ts --step pair-telegram -- --intent `, show the CODE (follow the `REMINDER_TO_ASSISTANT` line in the `PAIR_TELEGRAM_ISSUED` block) and tell the user to post `@ CODE` in the target group (or DM the bot for a private chat). Wait for the `PAIR_TELEGRAM` block. The inbound interceptor has already created the `messaging_groups` row with `unknown_sender_policy = 'strict'` and upserted the paired user — `register` only needs to add the wiring: ```bash - npx tsx setup/index.ts --step register -- \ + pnpm exec tsx setup/index.ts --step register -- \ --platform-id "" --name "" \ --folder "" --channel "telegram" \ --session-mode "" \ diff --git a/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md b/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md index cb6ed33a0..437c6f446 100644 --- a/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md +++ b/.claude/skills/migrate-from-openclaw/MIGRATE_CRONS.md @@ -68,7 +68,7 @@ Source: `src/db.ts` Insert directly into the SQLite database. This requires groups to be registered first (Phase 1). Use the registered group's `folder` and `chat_jid`: ```bash -npx tsx -e " +pnpm exec tsx -e " const Database = require('better-sqlite3'); const { CronExpressionParser } = require('cron-parser'); const db = new Database('store/messages.db'); diff --git a/.claude/skills/migrate-from-openclaw/SKILL.md b/.claude/skills/migrate-from-openclaw/SKILL.md index c393269db..46a18f983 100644 --- a/.claude/skills/migrate-from-openclaw/SKILL.md +++ b/.claude/skills/migrate-from-openclaw/SKILL.md @@ -36,7 +36,7 @@ Keep it factual and terse — this is for machine recovery after compaction, not Run the discovery script to find and summarize the OpenClaw installation: ```bash -npx tsx ${CLAUDE_SKILL_DIR}/scripts/discover-openclaw.ts +pnpm exec tsx ${CLAUDE_SKILL_DIR}/scripts/discover-openclaw.ts ``` If the user specifies a custom path, pass it: `--state-dir ` @@ -106,7 +106,7 @@ The discovery script provides detected groups in the GROUPS field (format: `chan For each group the user wants to bring over, pre-register it: ```bash -npx tsx setup/index.ts --step register -- --jid "" --name "" --folder "_" --trigger "@" --channel --assistant-name "" +pnpm exec tsx setup/index.ts --step register -- --jid "" --name "" --folder "_" --trigger "@" --channel --assistant-name "" ``` Only pass `--assistant-name` on the first registration (it updates all CLAUDE.md templates globally). @@ -115,7 +115,7 @@ Folder naming: `_` (e.g. `whatsapp_family-chat`, `telegram_d For the first/primary group, add `--is-main --no-trigger-required`. Other groups default to requiring a trigger prefix. -**Important:** Registration requires the database to exist. If the environment step hasn't been run yet, run it first: `npx tsx setup/index.ts --step environment`. Registration also creates the group folder under `groups/` and copies the CLAUDE.md template. +**Important:** Registration requires the database to exist. If the environment step hasn't been run yet, run it first: `pnpm exec tsx setup/index.ts --step environment`. Registration also creates the group folder under `groups/` and copies the CLAUDE.md template. Register groups from all channels — including channels NanoClaw doesn't yet support (signal, matrix, etc.). The registration stores the JID and metadata in the database, ready for when that channel is added later. Groups won't receive messages until their channel code is installed, but the registration, group folder, and CLAUDE.md will be ready. @@ -295,7 +295,7 @@ For each detected plugin, present the name to the user and discuss whether to se 1. **If NanoClaw has a matching skill** — check the available NanoClaw skills list for an equivalent (e.g. `/add-voice-transcription` for whisper). If found, save the API key to `.env` and invoke that skill. -2. **If the OpenClaw plugin was an MCP server** — read its config to find the exact package name and command. Install the same MCP server (e.g. `npx -y `). Don't search for or guess at MCP packages — only install what was explicitly configured. +2. **If the OpenClaw plugin was an MCP server** — read its config to find the exact package name and command. Install the same MCP server (e.g. `pnpm dlx `). Don't search for or guess at MCP packages — only install what was explicitly configured. 3. **If the OpenClaw plugin was a CLI tool** — read the config to identify the exact tool. If it's an npm package, add it to the container's Dockerfile. Add a note to the group's CLAUDE.md that the tool is available and how to invoke it. @@ -324,7 +324,7 @@ Run the credential extraction script with `--write-env .env` so it writes creden First, run without `--write-env` to preview: ```bash -npx tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir --channel +pnpm exec tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir --channel ``` Parse the status block. Key fields: HAS_CREDENTIAL, CREDENTIAL_MASKED, NANOCLAW_ENV_VAR. @@ -339,7 +339,7 @@ If HAS_CREDENTIAL=true: Show the masked credential (`CREDENTIAL_MASKED`). AskUse If using the credential: ```bash -npx tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir --channel --write-env .env +pnpm exec tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir --channel --write-env .env ``` The script writes the credential directly to `.env` using the correct NanoClaw variable name (e.g. `TELEGRAM_BOT_TOKEN`). Check the status block for `WRITTEN_TO` and `WRITTEN_COUNT` to confirm. diff --git a/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts b/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts index e15ed3461..ec44daee8 100644 --- a/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts +++ b/.claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts @@ -1,7 +1,7 @@ /** * Discover an existing OpenClaw installation and emit a structured summary. * - * Usage: npx tsx .claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts [--state-dir ] + * Usage: pnpm exec tsx .claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts [--state-dir ] * * Checks (in order): --state-dir arg, $OPENCLAW_STATE_DIR, ~/.openclaw, ~/.clawdbot * Parses openclaw.json (JSON5-tolerant), scans workspace for identity/memory files, diff --git a/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts b/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts index b8959ba8d..b1de03f0c 100644 --- a/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts +++ b/.claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts @@ -2,7 +2,7 @@ * Extract a channel credential from an OpenClaw configuration and write it * directly to the NanoClaw .env file. * - * Usage: npx tsx .claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts \ + * Usage: pnpm exec tsx .claude/skills/migrate-from-openclaw/scripts/extract-channel-credentials.ts \ * --channel telegram --state-dir ~/.openclaw --write-env .env * * Handles OpenClaw SecretRef formats: diff --git a/.claude/skills/migrate-nanoclaw/SKILL.md b/.claude/skills/migrate-nanoclaw/SKILL.md index 68c3ae75c..82e1009cc 100644 --- a/.claude/skills/migrate-nanoclaw/SKILL.md +++ b/.claude/skills/migrate-nanoclaw/SKILL.md @@ -391,7 +391,7 @@ For behavior customizations (CLAUDE.md files): copy from the main tree. These ar ## 2.6 Validate in worktree ```bash -cd "$WORKTREE" && npm install && npm run build && npm test +cd "$WORKTREE" && pnpm install && pnpm run build && pnpm test ``` If build fails, show the error. Fix only issues caused by the migration. If unclear, ask the user. @@ -417,7 +417,7 @@ If testing live: ln -s "$PROJECT_ROOT/.env" "$WORKTREE/.env" ``` -3. Start from worktree: `cd "$WORKTREE" && npm run dev` +3. Start from worktree: `cd "$WORKTREE" && pnpm run dev` 4. Ask the user to send a test message from their phone. Wait for them to confirm it works. @@ -461,7 +461,7 @@ Do NOT use `git checkout -B` to create an intermediate branch — this caused is ## 2.9 Post-upgrade -Run `npm install && npm run build` in the main tree to confirm. +Run `npm install && pnpm run build` in the main tree to confirm. Restart the service: ```bash diff --git a/.claude/skills/setup/SKILL.md b/.claude/skills/setup/SKILL.md index 35c80a76d..9182968fa 100644 --- a/.claude/skills/setup/SKILL.md +++ b/.claude/skills/setup/SKILL.md @@ -55,7 +55,7 @@ Run `bash setup.sh` and parse the status block. ## 2. Check Environment -Run `npx tsx setup/index.ts --step environment` and parse the status block. +Run `pnpm exec tsx setup/index.ts --step environment` and parse the status block. - If HAS_AUTH=true → WhatsApp is already configured, note for step 5 - If HAS_REGISTERED_GROUPS=true → note existing config, offer to skip or reconfigure @@ -73,9 +73,9 @@ If "Migrate now": invoke `/migrate-from-openclaw`, then return here and continue ## 2a. Timezone -Run `npx tsx setup/index.ts --step timezone` and parse the status block. +Run `pnpm exec tsx setup/index.ts --step timezone` and parse the status block. -- If NEEDS_USER_INPUT=true → The system timezone could not be autodetected (e.g. POSIX-style TZ like `IST-2`). AskUserQuestion: "What is your timezone?" with common options (America/New_York, Europe/London, Asia/Jerusalem, Asia/Tokyo) and an "Other" escape. Then re-run: `npx tsx setup/index.ts --step timezone -- --tz `. +- If NEEDS_USER_INPUT=true → The system timezone could not be autodetected (e.g. POSIX-style TZ like `IST-2`). AskUserQuestion: "What is your timezone?" with common options (America/New_York, Europe/London, Asia/Jerusalem, Asia/Tokyo) and an "Other" escape. Then re-run: `pnpm exec tsx setup/index.ts --step timezone -- --tz `. - If STATUS=success and RESOLVED_TZ is `UTC` or `Etc/UTC` → confirm with the user: "Your system timezone is UTC — is that correct, or are you on a remote server?" If wrong, ask for their actual timezone and re-run with `--tz`. - If STATUS=success → Timezone is configured. Note RESOLVED_TZ for reference. @@ -91,7 +91,7 @@ Run `npx tsx setup/index.ts --step timezone` and parse the status block. ### 3b. Build and test -Run `npx tsx setup/index.ts --step container -- --runtime docker` and parse the status block. +Run `pnpm exec tsx setup/index.ts --step container -- --runtime docker` and parse the status block. **If BUILD_OK=false:** Read `logs/setup.log` tail for the build error. - Cache issue (stale layers): `docker builder prune -f`. Retry. @@ -220,7 +220,7 @@ The skill will: **After the channel skill completes**, install dependencies and rebuild — channel merges may introduce new packages: ```bash -npm install && npm run build +pnpm install && pnpm run build ``` If the build fails, read the error output and fix it (usually a missing dependency). Then continue to step 5a. @@ -230,7 +230,7 @@ If the build fails, read the error output and fix it (usually a missing dependen Set empty mount allowlist (agents only access their own workspace). Users can configure mounts later with `/manage-mounts`. ```bash -npx tsx setup/index.ts --step mounts -- --empty +pnpm exec tsx setup/index.ts --step mounts -- --empty ``` ## 7. Start Service @@ -239,7 +239,7 @@ If service already running: unload first. - macOS: `launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist` - Linux: `systemctl --user stop nanoclaw` (or `systemctl stop nanoclaw` if root) -Run `npx tsx setup/index.ts --step service` and parse the status block. +Run `pnpm exec tsx setup/index.ts --step service` and parse the status block. **If FALLBACK=wsl_no_systemd:** WSL without systemd detected. Tell user they can either enable systemd in WSL (`echo -e "[boot]\nsystemd=true" | sudo tee /etc/wsl.conf` then restart WSL) or use the generated `start-nanoclaw.sh` wrapper. @@ -287,10 +287,10 @@ If yes: invoke `/add-vercel`. ## 8. Verify -Run `npx tsx setup/index.ts --step verify` and parse the status block. +Run `pnpm exec tsx setup/index.ts --step verify` and parse the status block. **If STATUS=failed, fix each:** -- SERVICE=stopped → `npm run build`, then restart: `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) or `bash start-nanoclaw.sh` (WSL nohup) +- SERVICE=stopped → `pnpm run build`, then restart: `launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `systemctl --user restart nanoclaw` (Linux) or `bash start-nanoclaw.sh` (WSL nohup) - SERVICE=not_found → re-run step 7 - CREDENTIALS=missing → re-run step 4 (check `onecli secrets list`) - CHANNEL_AUTH shows `not_found` for any channel → re-invoke that channel's skill (e.g. `/add-telegram`) @@ -303,7 +303,7 @@ Tell user to test: send a message in their registered chat. Show: `tail -f logs/ **Container agent fails ("Claude Code process exited with code 1"):** Ensure Docker is running — `open -a Docker` (macOS) or `sudo systemctl start docker` (Linux). Check container logs in `groups/main/logs/container-*.log`. -**No response to messages:** Check trigger pattern. Main channel doesn't need prefix. Check DB: `npx tsx setup/index.ts --step verify`. Check `logs/nanoclaw.log`. +**No response to messages:** Check trigger pattern. Main channel doesn't need prefix. Check DB: `pnpm exec tsx setup/index.ts --step verify`. Check `logs/nanoclaw.log`. **Channel not connecting:** Verify the channel's credentials are set in `.env`. Channels auto-enable when their credentials are present. For WhatsApp: check `store/auth/creds.json` exists. For token-based channels: check token values in `.env`. Restart the service after any `.env` change. diff --git a/.claude/skills/update-nanoclaw/SKILL.md b/.claude/skills/update-nanoclaw/SKILL.md index cc94d66a3..aebe96e6f 100644 --- a/.claude/skills/update-nanoclaw/SKILL.md +++ b/.claude/skills/update-nanoclaw/SKILL.md @@ -30,7 +30,7 @@ Run `/update-nanoclaw` in Claude Code. **Conflict resolution**: opens only conflicted files, resolves the conflict markers, keeps your local customizations intact. -**Validation**: runs `npm run build` and `npm test`. +**Validation**: runs `pnpm run build` and `pnpm test`. **Breaking changes check**: after validation, reads CHANGELOG.md for any `[BREAKING]` entries introduced by the update. If found, shows each breaking change and offers to run the recommended skill to migrate. @@ -109,7 +109,7 @@ Show file-level impact from upstream: Bucket the upstream changed files: - **Skills** (`.claude/skills/`): unlikely to conflict unless the user edited an upstream skill - **Source** (`src/`): may conflict if user modified the same files -- **Build/config** (`package.json`, `package-lock.json`, `tsconfig*.json`, `container/`, `launchd/`): review needed +- **Build/config** (`package.json`, `pnpm-lock.yaml`, `tsconfig*.json`, `container/`, `launchd/`): review needed - **Other**: docs, tests, misc **Large drift check:** If the upstream commit count and age suggest the user has a lot of catching up to do, mention that `/migrate-nanoclaw` might be a better fit — it extracts customizations and reapplies them on clean upstream instead of merging. Offer it as an option but don't push. @@ -175,8 +175,8 @@ If it gets messy (more than 3 rounds of conflicts): # Step 5: Validation Run: -- `npm run build` -- `npm test` (do not fail the flow if tests are not configured) +- `pnpm run build` +- `pnpm test` (do not fail the flow if tests are not configured) If build fails: - Show the error. @@ -234,7 +234,7 @@ Tell the user: - Backup branch also exists: `backup/pre-update--` - Restart the service to apply changes: - If using launchd: `launchctl unload ~/Library/LaunchAgents/com.nanoclaw.plist && launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist` - - If running manually: restart `npm run dev` + - If running manually: restart `pnpm run dev` ## Diagnostics diff --git a/.claude/skills/update-skills/SKILL.md b/.claude/skills/update-skills/SKILL.md index cbbff3952..ca497adb5 100644 --- a/.claude/skills/update-skills/SKILL.md +++ b/.claude/skills/update-skills/SKILL.md @@ -110,8 +110,8 @@ If a merge fails badly (e.g., cannot resolve conflicts): # Step 4: Validation After all selected skills are merged: -- `npm run build` -- `npm test` (do not fail the flow if tests are not configured) +- `pnpm run build` +- `pnpm test` (do not fail the flow if tests are not configured) If build fails: - Show the error. diff --git a/.claude/skills/use-local-whisper/SKILL.md b/.claude/skills/use-local-whisper/SKILL.md index ec18a090e..664cafa51 100644 --- a/.claude/skills/use-local-whisper/SKILL.md +++ b/.claude/skills/use-local-whisper/SKILL.md @@ -76,8 +76,8 @@ git remote add whatsapp https://github.com/qwibitai/nanoclaw-whatsapp.git ```bash git fetch whatsapp skill/local-whisper git merge whatsapp/skill/local-whisper || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -87,7 +87,7 @@ This modifies `src/transcription.ts` to use the `whisper-cli` binary instead of ### Validate ```bash -npm run build +pnpm run build ``` ## Phase 3: Verify @@ -110,7 +110,7 @@ launchctl load ~/Library/LaunchAgents/com.nanoclaw.plist ### Build and restart ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw ``` diff --git a/.claude/skills/use-native-credential-proxy/SKILL.md b/.claude/skills/use-native-credential-proxy/SKILL.md index 71448b1b2..3b948227c 100644 --- a/.claude/skills/use-native-credential-proxy/SKILL.md +++ b/.claude/skills/use-native-credential-proxy/SKILL.md @@ -48,8 +48,8 @@ git remote add upstream https://github.com/qwibitai/nanoclaw.git ```bash git fetch upstream skill/native-credential-proxy git merge upstream/skill/native-credential-proxy || { - git checkout --theirs package-lock.json - git add package-lock.json + git checkout --theirs pnpm-lock.yaml + git add pnpm-lock.yaml git merge --continue } ``` @@ -62,7 +62,7 @@ This merges in: - Restored platform-aware proxy bind address detection - Reverted setup skill to `.env`-based credential instructions -If the merge reports conflicts beyond `package-lock.json`, resolve them by reading the conflicted files and understanding the intent of both sides. +If the merge reports conflicts beyond `pnpm-lock.yaml`, resolve them by reading the conflicted files and understanding the intent of both sides. ### Update main group CLAUDE.md @@ -77,9 +77,9 @@ with: ### Validate code changes ```bash -npm install -npm run build -npx vitest run src/credential-proxy.test.ts src/container-runner.test.ts +pnpm install +pnpm run build +pnpm exec vitest run src/credential-proxy.test.ts src/container-runner.test.ts ``` All tests must pass and build must be clean before proceeding. @@ -125,7 +125,7 @@ echo 'ANTHROPIC_API_KEY=' >> .env 1. Rebuild and restart: ```bash -npm run build +pnpm run build ``` Then restart the service: @@ -161,7 +161,7 @@ To revert to OneCLI gateway: 1. Find the merge commit: `git log --oneline --merges -5` 2. Revert it: `git revert -m 1` (undoes the skill branch merge, keeps your other changes) -3. `npm install` (re-adds `@onecli-sh/sdk`) -4. `npm run build` +3. `pnpm install` (re-adds `@onecli-sh/sdk`) +4. `pnpm run build` 5. Follow `/setup` step 4 to configure OneCLI credentials 6. Remove `ANTHROPIC_API_KEY` / `CLAUDE_CODE_OAUTH_TOKEN` from `.env` diff --git a/.claude/skills/x-integration/SKILL.md b/.claude/skills/x-integration/SKILL.md index 29a7be67a..5dc859e82 100644 --- a/.claude/skills/x-integration/SKILL.md +++ b/.claude/skills/x-integration/SKILL.md @@ -26,7 +26,7 @@ Before using this skill, ensure: 1. **NanoClaw is installed and running** - WhatsApp connected, service active 2. **Dependencies installed**: ```bash - npm ls playwright dotenv-cli || npm install playwright dotenv-cli + pnpm ls playwright dotenv-cli || pnpm install playwright dotenv-cli ``` 3. **CHROME_PATH configured** in `.env` (if Chrome is not at default location): ```bash @@ -40,7 +40,7 @@ Before using this skill, ensure: ```bash # 1. Setup authentication (interactive) -npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts +pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/setup.ts # Verify: data/x-auth.json should exist after successful login # 2. Rebuild container to include skill @@ -48,7 +48,7 @@ npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts # Verify: Output shows "COPY .claude/skills/x-integration/agent.ts" # 3. Rebuild host and restart service -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw # Verify: launchctl list | grep nanoclaw (macOS) or systemctl --user status nanoclaw (Linux) @@ -225,7 +225,7 @@ COPY container/agent-runner/package*.json ./ COPY container/agent-runner/ ./ ``` -Then add COPY line after `COPY container/agent-runner/ ./` and before `RUN npm run build`: +Then add COPY line after `COPY container/agent-runner/ ./` and before `RUN pnpm run build`: ```dockerfile # Copy skill MCP tools COPY .claude/skills/x-integration/agent.ts ./src/skills/x-integration/ @@ -247,7 +247,7 @@ echo "Chrome not found - update CHROME_PATH in .env" ### 2. Run Authentication ```bash -npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts +pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/setup.ts ``` This opens Chrome for manual X login. Session saved to `data/x-browser-profile/`. @@ -271,7 +271,7 @@ cat data/x-auth.json # Should show {"authenticated": true, ...} ### 4. Restart Service ```bash -npm run build +pnpm run build launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` @@ -317,26 +317,26 @@ ls -la data/x-browser-profile/ 2>/dev/null | head -5 ### Re-authenticate (if expired) ```bash -npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts +pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/setup.ts ``` ### Test Post (will actually post) ```bash -echo '{"content":"Test tweet - please ignore"}' | npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/post.ts +echo '{"content":"Test tweet - please ignore"}' | pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/post.ts ``` ### Test Like ```bash -echo '{"tweetUrl":"https://x.com/user/status/123"}' | npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/like.ts +echo '{"tweetUrl":"https://x.com/user/status/123"}' | pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/like.ts ``` Or export `CHROME_PATH` manually before running: ```bash export CHROME_PATH="/path/to/chrome" -echo '{"content":"Test"}' | npx tsx .claude/skills/x-integration/scripts/post.ts +echo '{"content":"Test"}' | pnpm exec tsx .claude/skills/x-integration/scripts/post.ts ``` ## Troubleshooting @@ -344,7 +344,7 @@ echo '{"content":"Test"}' | npx tsx .claude/skills/x-integration/scripts/post.ts ### Authentication Expired ```bash -npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts +pnpm exec dotenv -e .env -- pnpm exec tsx .claude/skills/x-integration/scripts/setup.ts launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS # Linux: systemctl --user restart nanoclaw ``` diff --git a/.claude/skills/x-integration/host.ts b/.claude/skills/x-integration/host.ts index 8971f640b..55a2b3a7a 100644 --- a/.claude/skills/x-integration/host.ts +++ b/.claude/skills/x-integration/host.ts @@ -22,7 +22,7 @@ async function runScript(script: string, args: object): Promise { const scriptPath = path.join(process.cwd(), '.claude', 'skills', 'x-integration', 'scripts', `${script}.ts`); return new Promise((resolve) => { - const proc = spawn('npx', ['tsx', scriptPath], { + const proc = spawn('pnpm', ['exec', 'tsx', scriptPath], { cwd: process.cwd(), env: { ...process.env, NANOCLAW_ROOT: process.cwd() }, stdio: ['pipe', 'pipe', 'pipe'] diff --git a/.claude/skills/x-integration/scripts/like.ts b/.claude/skills/x-integration/scripts/like.ts index c55b8b478..b0c60f5a9 100644 --- a/.claude/skills/x-integration/scripts/like.ts +++ b/.claude/skills/x-integration/scripts/like.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Like Tweet - * Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | npx tsx like.ts + * Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | pnpm exec tsx like.ts */ import { getBrowserContext, navigateToTweet, runScript, config, ScriptResult } from '../lib/browser.js'; diff --git a/.claude/skills/x-integration/scripts/post.ts b/.claude/skills/x-integration/scripts/post.ts index f7b47dcef..66b10905b 100644 --- a/.claude/skills/x-integration/scripts/post.ts +++ b/.claude/skills/x-integration/scripts/post.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Post Tweet - * Usage: echo '{"content":"Hello world"}' | npx tsx post.ts + * Usage: echo '{"content":"Hello world"}' | pnpm exec tsx post.ts */ import { getBrowserContext, runScript, validateContent, config, ScriptResult } from '../lib/browser.js'; diff --git a/.claude/skills/x-integration/scripts/quote.ts b/.claude/skills/x-integration/scripts/quote.ts index e0d2c3358..6c779e7a4 100644 --- a/.claude/skills/x-integration/scripts/quote.ts +++ b/.claude/skills/x-integration/scripts/quote.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Quote Tweet - * Usage: echo '{"tweetUrl":"https://x.com/user/status/123","comment":"My thoughts"}' | npx tsx quote.ts + * Usage: echo '{"tweetUrl":"https://x.com/user/status/123","comment":"My thoughts"}' | pnpm exec tsx quote.ts */ import { getBrowserContext, navigateToTweet, runScript, validateContent, config, ScriptResult } from '../lib/browser.js'; diff --git a/.claude/skills/x-integration/scripts/reply.ts b/.claude/skills/x-integration/scripts/reply.ts index e981cab5f..e4e345d0e 100644 --- a/.claude/skills/x-integration/scripts/reply.ts +++ b/.claude/skills/x-integration/scripts/reply.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Reply to Tweet - * Usage: echo '{"tweetUrl":"https://x.com/user/status/123","content":"Great post!"}' | npx tsx reply.ts + * Usage: echo '{"tweetUrl":"https://x.com/user/status/123","content":"Great post!"}' | pnpm exec tsx reply.ts */ import { getBrowserContext, navigateToTweet, runScript, validateContent, config, ScriptResult } from '../lib/browser.js'; diff --git a/.claude/skills/x-integration/scripts/retweet.ts b/.claude/skills/x-integration/scripts/retweet.ts index 05b74379e..9c51424cc 100644 --- a/.claude/skills/x-integration/scripts/retweet.ts +++ b/.claude/skills/x-integration/scripts/retweet.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Retweet - * Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | npx tsx retweet.ts + * Usage: echo '{"tweetUrl":"https://x.com/user/status/123"}' | pnpm exec tsx retweet.ts */ import { getBrowserContext, navigateToTweet, runScript, config, ScriptResult } from '../lib/browser.js'; diff --git a/.claude/skills/x-integration/scripts/setup.ts b/.claude/skills/x-integration/scripts/setup.ts index 94e5c0337..36a7c5367 100644 --- a/.claude/skills/x-integration/scripts/setup.ts +++ b/.claude/skills/x-integration/scripts/setup.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env npx tsx +#!/usr/bin/env pnpm exec tsx /** * X Integration - Authentication Setup - * Usage: npx tsx setup.ts + * Usage: pnpm exec tsx setup.ts * * Interactive script - opens browser for manual login */