diff --git a/.claude/settings.json b/.claude/settings.json index 2338791..9d91475 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -6,17 +6,17 @@ "allow": [ "Bash(bash setup.sh*)", "Bash(git remote *)", - "Bash(npx tsx setup/index.ts*)", - "Bash(npx tsx scripts/init-first-agent.ts*)", - "Bash(npm install @chat-adapter/*)", - "Bash(npm install chat-adapter-imessage*)", - "Bash(npm install @bitbasti/chat-adapter-webex*)", - "Bash(npm install @resend/chat-sdk-adapter*)", - "Bash(npm install @whiskeysockets/baileys*)", - "Bash(npm install @beeper/chat-adapter-matrix*)", - "Bash(npm install @nanoco/nanoclaw-dashboard*)", - "Bash(npm ci*)", - "Bash(npm run build*)", + "Bash(pnpm exec tsx setup/index.ts*)", + "Bash(pnpm exec tsx scripts/init-first-agent.ts*)", + "Bash(pnpm install @chat-adapter/*)", + "Bash(pnpm install chat-adapter-imessage*)", + "Bash(pnpm install @bitbasti/chat-adapter-webex*)", + "Bash(pnpm install @resend/chat-sdk-adapter*)", + "Bash(pnpm install @whiskeysockets/baileys*)", + "Bash(pnpm install @beeper/chat-adapter-matrix*)", + "Bash(pnpm install @nanoco/nanoclaw-dashboard*)", + "Bash(pnpm install --frozen-lockfile*)", + "Bash(pnpm run build*)", "Bash(curl -fsSL onecli.sh*)", "Bash(onecli *)", "Bash(grep -q *)", diff --git a/.claude/skills/add-dashboard/SKILL.md b/.claude/skills/add-dashboard/SKILL.md index 61fdfcb..246ac48 100644 --- a/.claude/skills/add-dashboard/SKILL.md +++ b/.claude/skills/add-dashboard/SKILL.md @@ -25,7 +25,7 @@ NanoClaw (pusher) Dashboard (npm package) ### 1. Install the npm package ```bash -npm install @nanoco/nanoclaw-dashboard +pnpm install @nanoco/nanoclaw-dashboard ``` ### 2. Copy the pusher module @@ -94,7 +94,7 @@ Generate the secret: `node -e "console.log('nc-' + require('crypto').randomBytes ### 6. Build and restart ```bash -npm run build +pnpm run build systemctl --user restart nanoclaw # Linux # or: launchctl kickstart -k gui/$(id -u)/com.nanoclaw # macOS ``` @@ -130,9 +130,9 @@ Open `http://localhost:3100/dashboard` in a browser. ## Removal ```bash -npm uninstall @nanoco/nanoclaw-dashboard +pnpm uninstall @nanoco/nanoclaw-dashboard rm src/dashboard-pusher.ts # Remove the dashboard block from src/index.ts # Remove DASHBOARD_SECRET and DASHBOARD_PORT from .env -npm run build +pnpm run build ``` diff --git a/.claude/skills/add-whatsapp-v2/SKILL.md b/.claude/skills/add-whatsapp-v2/SKILL.md index 4270187..c49a477 100644 --- a/.claude/skills/add-whatsapp-v2/SKILL.md +++ b/.claude/skills/add-whatsapp-v2/SKILL.md @@ -16,7 +16,7 @@ Check if `src/channels/whatsapp.ts` exists and the import is uncommented in `src ### Install the adapter packages ```bash -npm install @whiskeysockets/baileys@^6.7.21 pino@^9.6.0 qrcode@^1.5.4 @types/qrcode@^1.5.6 +pnpm install @whiskeysockets/baileys@^6.7.21 pino@^9.6.0 qrcode@^1.5.4 @types/qrcode@^1.5.6 ``` ### Enable the channel @@ -39,7 +39,7 @@ import './whatsapp.js'; ### Build ```bash -npm run build +pnpm run build ``` ## Credentials @@ -90,7 +90,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) @@ -106,7 +106,7 @@ 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 ``` (Bash timeout: 150000ms) @@ -123,7 +123,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): @@ -199,7 +199,7 @@ Not supported (WhatsApp linked device limitation): edit messages, delete message QR codes expire after ~60 seconds. Re-run the auth command: ```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 ``` ### Pairing code not working @@ -207,7 +207,7 @@ rm -rf store/auth/ && npx tsx setup/index.ts --step whatsapp-auth -- --method qr Codes expire in ~60 seconds. Delete auth and retry: ```bash -rm -rf store/auth/ && npx tsx setup/index.ts --step whatsapp-auth -- --method pairing-code --phone +rm -rf store/auth/ && pnpm exec tsx setup/index.ts --step whatsapp-auth -- --method pairing-code --phone ``` Ensure: digits only (no `+`), phone has internet, WhatsApp is updated. @@ -215,7 +215,7 @@ Ensure: digits only (no `+`), phone has internet, WhatsApp is updated. 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 ``` ### "waiting for this message" on reactions diff --git a/container/.dockerignore b/container/.dockerignore new file mode 100644 index 0000000..598ce19 --- /dev/null +++ b/container/.dockerignore @@ -0,0 +1,2 @@ +agent-runner/node_modules +agent-runner/dist diff --git a/container/skills/frontend-engineer/SKILL.md b/container/skills/frontend-engineer/SKILL.md index 5289ad7..ef09224 100644 --- a/container/skills/frontend-engineer/SKILL.md +++ b/container/skills/frontend-engineer/SKILL.md @@ -66,7 +66,7 @@ Every frontend task follows this sequence. Do not skip steps. Run the build and fix ALL errors: ```bash -npm run build 2>&1 +pnpm run build 2>&1 ``` If it fails, **fix it**. Do not deploy broken builds. Do not disable ESLint rules or TypeScript checks to make it pass. @@ -76,7 +76,7 @@ If it fails, **fix it**. Do not deploy broken builds. Do not disable ESLint rule Start the dev server and test in a real browser: ```bash -npm run dev & +pnpm run dev & DEV_PID=$! sleep 3 ``` diff --git a/container/skills/self-customize/SKILL.md b/container/skills/self-customize/SKILL.md index 5834dec..e1d5588 100644 --- a/container/skills/self-customize/SKILL.md +++ b/container/skills/self-customize/SKILL.md @@ -87,4 +87,4 @@ User: "Can you transcribe audio?" - **The change is for a one-off task** — just do it in your workspace, don't modify the container - **The request is ambiguous** — ask the user what they actually need before spinning up builders or requesting installs -- **You don't know if it will work** — prototype in your workspace first (`npm install` in `/workspace/agent/`), then promote to container-level install if it proves useful +- **You don't know if it will work** — prototype in your workspace first (`pnpm install` in `/workspace/agent/`), then promote to container-level install if it proves useful diff --git a/container/skills/vercel-cli/SKILL.md b/container/skills/vercel-cli/SKILL.md index 275acb3..09305a7 100644 --- a/container/skills/vercel-cli/SKILL.md +++ b/container/skills/vercel-cli/SKILL.md @@ -117,7 +117,7 @@ After sending, tell the user you've handed it off and will share the result when ## Best Practices -- Run `npm run build` locally before deploying to catch build errors early +- Run `pnpm run build` locally before deploying to catch build errors early - Use `--cwd` instead of `cd` to keep your working directory stable - For Next.js projects, `vercel deploy` auto-detects the framework — no extra config needed - Use `vercel.json` only when you need custom build settings, rewrites, or headers diff --git a/scripts/init-first-agent.ts b/scripts/init-first-agent.ts index 358ecca..90543d7 100644 --- a/scripts/init-first-agent.ts +++ b/scripts/init-first-agent.ts @@ -10,7 +10,7 @@ * channel adapters, so there's no Gateway conflict. * * Usage: - * npx tsx scripts/init-first-agent.ts \ + * pnpm exec tsx scripts/init-first-agent.ts \ * --channel discord \ * --user-id discord:1470183333427675709 \ * --platform-id discord:@me:1491573333382523708 \ diff --git a/scripts/migrate-group-claude-md.ts b/scripts/migrate-group-claude-md.ts index a1c1691..dd16faf 100644 --- a/scripts/migrate-group-claude-md.ts +++ b/scripts/migrate-group-claude-md.ts @@ -22,7 +22,7 @@ * * Idempotent — safe to re-run. * - * Usage: npx tsx scripts/migrate-group-claude-md.ts + * Usage: pnpm exec tsx scripts/migrate-group-claude-md.ts */ import fs from 'fs'; import path from 'path'; diff --git a/scripts/seed-discord.ts b/scripts/seed-discord.ts index a90c384..9aed1c5 100644 --- a/scripts/seed-discord.ts +++ b/scripts/seed-discord.ts @@ -1,7 +1,7 @@ /** * Seed the v2 central DB with a Discord agent group + messaging group. * - * Usage: npx tsx scripts/seed-discord.ts + * Usage: pnpm exec tsx scripts/seed-discord.ts */ import path from 'path'; @@ -73,4 +73,4 @@ try { } } -console.log('Done! Run: npm run build && node dist/index.js'); +console.log('Done! Run: pnpm run build && node dist/index.js'); diff --git a/scripts/test-v2-agent.ts b/scripts/test-v2-agent.ts index 0e8c020..5d4289a 100644 --- a/scripts/test-v2-agent.ts +++ b/scripts/test-v2-agent.ts @@ -2,7 +2,7 @@ * Quick integration test: create a session DB, insert a message, * run the v2 poll loop with the Claude provider, verify output. * - * Usage: npx tsx scripts/test-v2-agent.ts + * Usage: pnpm exec tsx scripts/test-v2-agent.ts */ import Database from 'better-sqlite3'; import fs from 'fs'; diff --git a/scripts/test-v2-channel-e2e.ts b/scripts/test-v2-channel-e2e.ts index ff22905..fc0a570 100644 --- a/scripts/test-v2-channel-e2e.ts +++ b/scripts/test-v2-channel-e2e.ts @@ -4,7 +4,7 @@ * Mock adapter → onInbound → router → session DB → Docker container → * agent-runner → Claude → messages_out → delivery → mock adapter.deliver() * - * Usage: npx tsx scripts/test-v2-channel-e2e.ts + * Usage: pnpm exec tsx scripts/test-v2-channel-e2e.ts */ import Database from 'better-sqlite3'; import fs from 'fs'; diff --git a/scripts/test-v2-host.ts b/scripts/test-v2-host.ts index f4421ec..b82bc99 100644 --- a/scripts/test-v2-host.ts +++ b/scripts/test-v2-host.ts @@ -6,7 +6,7 @@ * 3. Container runs v2 agent-runner, polls inbound.db, queries Claude, writes outbound.db * 4. Poll outbound.db for messages_out response * - * Usage: npx tsx scripts/test-v2-host.ts + * Usage: pnpm exec tsx scripts/test-v2-host.ts */ import Database from 'better-sqlite3'; import fs from 'fs'; diff --git a/setup/groups.ts b/setup/groups.ts index 208bd75..4c71e86 100644 --- a/setup/groups.ts +++ b/setup/groups.ts @@ -87,7 +87,7 @@ async function syncGroups(projectRoot: string): Promise { log.info('Building TypeScript'); let buildOk = false; try { - execSync('npm run build', { + execSync('pnpm run build', { cwd: projectRoot, stdio: ['ignore', 'pipe', 'pipe'], }); diff --git a/setup/index.ts b/setup/index.ts index 629d0bd..53b6fb4 100644 --- a/setup/index.ts +++ b/setup/index.ts @@ -1,6 +1,6 @@ /** * Setup CLI entry point. - * Usage: npx tsx setup/index.ts --step [args...] + * Usage: pnpm exec tsx setup/index.ts --step [args...] */ import { log } from '../src/log.js'; import { emitStatus } from './status.js'; @@ -27,7 +27,7 @@ async function main(): Promise { if (stepIdx === -1 || !args[stepIdx + 1]) { console.error( - `Usage: npx tsx setup/index.ts --step <${Object.keys(STEPS).join('|')}> [args...]`, + `Usage: pnpm exec tsx setup/index.ts --step <${Object.keys(STEPS).join('|')}> [args...]`, ); process.exit(1); } diff --git a/setup/service.ts b/setup/service.ts index 9fd14d2..bc85d16 100644 --- a/setup/service.ts +++ b/setup/service.ts @@ -31,7 +31,7 @@ export async function run(_args: string[]): Promise { // Build first log.info('Building TypeScript'); try { - execSync('npm run build', { + execSync('pnpm run build', { cwd: projectRoot, stdio: ['ignore', 'pipe', 'pipe'], });