mirror of
https://github.com/qwibitai/nanoclaw.git
synced 2026-06-04 10:14:47 +08:00
docs: convert all skill instructions from npm to pnpm
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.
This commit is contained in:
@@ -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 <your-fork> /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 @<assistant> /compact from non-main as non-admin, verify denial
|
||||
|
||||
@@ -26,7 +26,7 @@ import './discord.js';
|
||||
### Build
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
pnpm run build
|
||||
```
|
||||
|
||||
## Credentials
|
||||
|
||||
@@ -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:<channel-id>" --name "<server-name> #<channel-name>" --folder "discord_main" --trigger "@${ASSISTANT_NAME}" --channel discord --no-trigger-required --is-main
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "dc:<channel-id>" --name "<server-name> #<channel-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:<channel-id>" --name "<server-name> #<channel-name>" --folder "discord_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel discord
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "dc:<channel-id>" --name "<server-name> #<channel-name>" --folder "discord_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel discord
|
||||
```
|
||||
|
||||
## Phase 5: Verify
|
||||
|
||||
@@ -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)
|
||||
6. Rebuild: `pnpm run build && launchctl kickstart -k gui/$(id -u)/com.nanoclaw` (macOS) or `pnpm run build && systemctl --user restart nanoclaw` (Linux)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -87,7 +87,7 @@ done
|
||||
### Validate code changes
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
pnpm run build
|
||||
./container/build.sh
|
||||
```
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:<channel-id>" --name "<channel-name>" --folder "slack_main" --trigger "@${ASSISTANT_NAME}" --channel slack --no-trigger-required --is-main
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "slack:<channel-id>" --name "<channel-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:<channel-id>" --name "<channel-name>" --folder "slack_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel slack
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "slack:<channel-id>" --name "<channel-name>" --folder "slack_<channel-name>" --trigger "@${ASSISTANT_NAME}" --channel slack
|
||||
```
|
||||
|
||||
## Phase 5: Verify
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <main|wire-to:folder|new-agent:folder>`, 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: `@<botname> 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 <main|wire-to:folder|new-agent:folder>`, 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: `@<botname> 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.
|
||||
|
||||
@@ -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:<chat-id>" --name "<chat-name>" --folder "telegram_main" --trigger "@${ASSISTANT_NAME}" --channel telegram --no-trigger-required --is-main
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-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:<chat-id>" --name "<chat-name>" --folder "telegram_<group-name>" --trigger "@${ASSISTANT_NAME}" --channel telegram
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "tg:<chat-id>" --name "<chat-name>" --folder "telegram_<group-name>" --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)
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <their-phone-number> > /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 <their-phone-number> > /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 "<jid>" \
|
||||
--name "<chat-name>" \
|
||||
--trigger "@<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 "<group-jid>" \
|
||||
--name "<group-name>" \
|
||||
--trigger "@<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 <phone>
|
||||
rm -rf store/auth/ && pnpm exec tsx src/whatsapp-auth.ts --pairing-code --phone <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)
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
<key>LOG_LEVEL</key>
|
||||
@@ -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
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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 "<id>" --name "<name>" \
|
||||
--folder "<folder>" --channel "<type>" \
|
||||
--session-mode "<shared|agent-shared|per-thread>" \
|
||||
@@ -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:<folder>` for an existing agent, `new-agent:<folder>` for a fresh one). Run `npx tsx setup/index.ts --step pair-telegram -- --intent <intent>`, show the CODE (follow the `REMINDER_TO_ASSISTANT` line in the `PAIR_TELEGRAM_ISSUED` block) and tell the user to post `@<botname> 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:<folder>` for an existing agent, `new-agent:<folder>` for a fresh one). Run `pnpm exec tsx setup/index.ts --step pair-telegram -- --intent <intent>`, show the CODE (follow the `REMINDER_TO_ASSISTANT` line in the `PAIR_TELEGRAM_ISSUED` block) and tell the user to post `@<botname> 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 "<PLATFORM_ID>" --name "<group-name>" \
|
||||
--folder "<folder>" --channel "telegram" \
|
||||
--session-mode "<shared|agent-shared|per-thread>" \
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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 <path>`
|
||||
@@ -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 "<nanoclaw_jid>" --name "<group_name>" --folder "<channel>_<slug>" --trigger "@<confirmed_name>" --channel <channel> --assistant-name "<confirmed_name>"
|
||||
pnpm exec tsx setup/index.ts --step register -- --jid "<nanoclaw_jid>" --name "<group_name>" --folder "<channel>_<slug>" --trigger "@<confirmed_name>" --channel <channel> --assistant-name "<confirmed_name>"
|
||||
```
|
||||
|
||||
Only pass `--assistant-name` on the first registration (it updates all CLAUDE.md templates globally).
|
||||
@@ -115,7 +115,7 @@ Folder naming: `<channel>_<name-slug>` (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 <exact-package-from-config>`). 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 <exact-package-from-config>`). 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 <STATE_DIR> --channel <name>
|
||||
pnpm exec tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir <STATE_DIR> --channel <name>
|
||||
```
|
||||
|
||||
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 <STATE_DIR> --channel <name> --write-env .env
|
||||
pnpm exec tsx ${CLAUDE_SKILL_DIR}/scripts/extract-channel-credentials.ts --state-dir <STATE_DIR> --channel <name> --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.
|
||||
|
||||
@@ -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 <path>]
|
||||
* Usage: pnpm exec tsx .claude/skills/migrate-from-openclaw/scripts/discover-openclaw.ts [--state-dir <path>]
|
||||
*
|
||||
* Checks (in order): --state-dir arg, $OPENCLAW_STATE_DIR, ~/.openclaw, ~/.clawdbot
|
||||
* Parses openclaw.json (JSON5-tolerant), scans workspace for identity/memory files,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <their-answer>`.
|
||||
- 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 <their-answer>`.
|
||||
- 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.
|
||||
|
||||
|
||||
@@ -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-<HASH>-<TIMESTAMP>`
|
||||
- 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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
|
||||
@@ -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=<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 <merge-commit> -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`
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
@@ -22,7 +22,7 @@ async function runScript(script: string, args: object): Promise<SkillResult> {
|
||||
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']
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user