[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H3TYSDKA9E5WWQYC12E374":3,"skill-same:01M6H3TYSDKA9E5WWQYC12E374":71},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":53,"repositoryHtmlUrl":54,"repositoryHomepageUrl":54,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":56,"install":57,"resources":70},"01M6H3TYSDKA9E5WWQYC12E374","debug",null,"Debug container agent issues. Use when things aren't working, container fails, authentication problems, or to understand how the container system works. Covers logs, environment variables, mounts, and common issues.","sliamh11\u002FDeus","sliamh11","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F68326628?v=4","01M6H3PPFXQ6C98QV1RJA5W72S","Liam Steiner","01M6H3PPM81GJC6KYCNTY9A3AT",51,"MIT","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdebug\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[5,32,33,34,35,36,37,38,39,40,41,42,43,44],"authentication","issues","logs","how","system","common","environment","use","container","environment variables","understand","Variables","things","2026-11-10 10:12:30",false,"---\nname: debug\ndescription: Debug container agent issues. Use when things aren't working, container fails, authentication problems, or to understand how the container system works. Covers logs, environment variables, mounts, and common issues.\n---\n\n# Deus Container Debugging\n\nThis guide covers debugging the containerized agent execution system.\n\n## Architecture Overview\n\n```\nHost (macOS)                          Container (Linux VM)\n─────────────────────────────────────────────────────────────\nsrc\u002Fcontainer-runner.ts               container\u002Fagent-runner\u002F\n    │                                      │\n    │ spawns container                      │ runs Claude Agent SDK\n    │ with volume mounts                   │ with MCP servers\n    │                                      │\n    ├── data\u002Fenv\u002Fenv ──────────────> \u002Fworkspace\u002Fenv-dir\u002Fenv\n    ├── groups\u002F{folder} ───────────> \u002Fworkspace\u002Fgroup\n    ├── data\u002Fipc\u002F{folder} ────────> \u002Fworkspace\u002Fipc\n    ├── data\u002Fsessions\u002F{folder}\u002F.claude\u002F ──> \u002Fhome\u002Fnode\u002F.claude\u002F (isolated per-group)\n    └── (main only) project root ──> \u002Fworkspace\u002Fproject\n```\n\n**Important:** The container runs as user `node` with `HOME=\u002Fhome\u002Fnode`. Session files must be mounted to `\u002Fhome\u002Fnode\u002F.claude\u002F` (not `\u002Froot\u002F.claude\u002F`) for session resumption to work.\n\n## Log Locations\n\n| Log | Location | Content |\n|-----|----------|---------|\n| **Main app logs** | `logs\u002Fdeus.log` | Host-side WhatsApp, routing, container spawning |\n| **Main app errors** | `logs\u002Fdeus.error.log` | Host-side errors |\n| **Container run logs** | `groups\u002F{folder}\u002Flogs\u002Fcontainer-*.log` | Per-run: input, mounts, stderr, stdout |\n| **Claude sessions** | `~\u002F.claude\u002Fprojects\u002F` | Claude Code session history |\n\n## Enabling Debug Logging\n\nSet `LOG_LEVEL=debug` for verbose output:\n\n```bash\n# For development\nLOG_LEVEL=debug npm run dev\n\n# For launchd service (macOS), add to plist EnvironmentVariables:\n\u003Ckey>LOG_LEVEL\u003C\u002Fkey>\n\u003Cstring>debug\u003C\u002Fstring>\n# For systemd service (Linux), add to unit [Service] section:\n# Environment=LOG_LEVEL=debug\n```\n\nDebug level shows:\n- Full mount configurations\n- Container command arguments\n- Real-time container stderr\n\n## Common Issues\n\n### 1. \"Claude Code process exited with code 1\"\n\n**Check the container log file** in `groups\u002F{folder}\u002Flogs\u002Fcontainer-*.log`\n\nCommon causes:\n\n#### Missing Authentication\n```\nInvalid API key · Please run \u002Flogin\n```\n**Fix:** Ensure `.env` file exists with either OAuth token or API key:\n```bash\ncat .env  # Should show one of:\n# CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...  (subscription)\n# ANTHROPIC_API_KEY=sk-ant-api03-...        (pay-per-use)\n```\n\n#### Root User Restriction\n```\n--dangerously-skip-permissions cannot be used with root\u002Fsudo privileges\n```\n**Fix:** Container must run as non-root user. Check Dockerfile has `USER node`.\n\n### 2. Environment Variables Not Passing\n\n**Runtime note:** Environment variables passed via `-e` may be lost when using `-i` (interactive\u002Fpiped stdin).\n\n**Workaround:** The system extracts only authentication variables (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`) from `.env` and mounts them for sourcing inside the container. Other env vars are not exposed.\n\nTo verify env vars are reaching the container:\n```bash\necho '{}' | docker run -i \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  --entrypoint \u002Fbin\u002Fbash deus-agent:latest \\\n  -c 'export $(cat \u002Fworkspace\u002Fenv-dir\u002Fenv | xargs); echo \"OAuth: ${#CLAUDE_CODE_OAUTH_TOKEN} chars, API: ${#ANTHROPIC_API_KEY} chars\"'\n```\n\n### 3. Mount Issues\n\n**Container mount notes:**\n- Docker supports both `-v` and `--mount` syntax\n- Use `:ro` suffix for readonly mounts:\n  ```bash\n  # Readonly\n  -v \u002Fpath:\u002Fcontainer\u002Fpath:ro\n\n  # Read-write\n  -v \u002Fpath:\u002Fcontainer\u002Fpath\n  ```\n\nTo check what's mounted inside a container:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c 'ls -la \u002Fworkspace\u002F'\n```\n\nExpected structure:\n```\n\u002Fworkspace\u002F\n├── env-dir\u002Fenv           # Environment file (CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY)\n├── group\u002F                # Current group folder (cwd)\n├── project\u002F              # Project root (main channel only)\n├── global\u002F               # Global CLAUDE.md (non-main only)\n├── ipc\u002F                  # Inter-process communication\n│   ├── messages\u002F         # Outgoing WhatsApp messages\n│   ├── tasks\u002F            # Scheduled task commands\n│   ├── current_tasks.json    # Read-only: scheduled tasks visible to this group\n│   └── available_groups.json # Read-only: WhatsApp groups for activation (main only)\n└── extra\u002F                # Additional custom mounts\n```\n\n### 4. Permission Issues\n\nThe container runs as user `node` (uid 1000). Check ownership:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c '\n  whoami\n  ls -la \u002Fworkspace\u002F\n  ls -la \u002Fapp\u002F\n'\n```\n\nAll of `\u002Fworkspace\u002F` and `\u002Fapp\u002F` should be owned by `node`.\n\n### 5. Session Not Resuming \u002F \"Claude Code process exited with code 1\"\n\nIf sessions aren't being resumed (new session ID every time), or Claude Code exits with code 1 when resuming:\n\n**Root cause:** The SDK looks for sessions at `$HOME\u002F.claude\u002Fprojects\u002F`. Inside the container, `HOME=\u002Fhome\u002Fnode`, so it looks at `\u002Fhome\u002Fnode\u002F.claude\u002Fprojects\u002F`.\n\n**Check the mount path:**\n```bash\n# In container-runner.ts, verify mount is to \u002Fhome\u002Fnode\u002F.claude\u002F, NOT \u002Froot\u002F.claude\u002F\ngrep -A3 \"Claude sessions\" src\u002Fcontainer-runner.ts\n```\n\n**Verify sessions are accessible:**\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash \\\n  -v ~\u002F.claude:\u002Fhome\u002Fnode\u002F.claude \\\n  deus-agent:latest -c '\necho \"HOME=$HOME\"\nls -la $HOME\u002F.claude\u002Fprojects\u002F 2>&1 | head -5\n'\n```\n\n**Fix:** Ensure `container-runner.ts` mounts to `\u002Fhome\u002Fnode\u002F.claude\u002F`:\n```typescript\nmounts.push({\n  hostPath: claudeDir,\n  containerPath: '\u002Fhome\u002Fnode\u002F.claude',  \u002F\u002F NOT \u002Froot\u002F.claude\n  readonly: false\n});\n```\n\n### 6. MCP Server Failures\n\nIf an MCP server fails to start, the agent may exit. Check the container logs for MCP initialization errors.\n\n## Manual Container Testing\n\n### Test the full agent flow:\n```bash\n# Set up env file\nmkdir -p data\u002Fenv groups\u002Ftest\ncp .env data\u002Fenv\u002Fenv\n\n# Run test query\necho '{\"prompt\":\"What is 2+2?\",\"groupFolder\":\"test\",\"chatJid\":\"test@g.us\",\"isMain\":false}' | \\\n  docker run -i \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  -v $(pwd)\u002Fgroups\u002Ftest:\u002Fworkspace\u002Fgroup \\\n  -v $(pwd)\u002Fdata\u002Fipc:\u002Fworkspace\u002Fipc \\\n  deus-agent:latest\n```\n\n### Test Claude Code directly:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  deus-agent:latest -c '\n  export $(cat \u002Fworkspace\u002Fenv-dir\u002Fenv | xargs)\n  claude -p \"Say hello\" --dangerously-skip-permissions --allowedTools \"\"\n'\n```\n\n### Interactive shell in container:\n```bash\ndocker run --rm -it --entrypoint \u002Fbin\u002Fbash deus-agent:latest\n```\n\n## SDK Options Reference\n\nThe agent-runner uses these Claude Agent SDK options:\n\n```typescript\nquery({\n  prompt: input.prompt,\n  options: {\n    cwd: '\u002Fworkspace\u002Fgroup',\n    allowedTools: ['Bash', 'Read', 'Write', ...],\n    permissionMode: 'bypassPermissions',\n    allowDangerouslySkipPermissions: true,  \u002F\u002F Required with bypassPermissions\n    settingSources: ['project'],\n    mcpServers: { ... }\n  }\n})\n```\n\n**Important:** `allowDangerouslySkipPermissions: true` is required when using `permissionMode: 'bypassPermissions'`. Without it, Claude Code exits with code 1.\n\n## Rebuilding After Changes\n\n```bash\n# Rebuild main app\nnpm run build\n\n# Rebuild container (use --no-cache for clean rebuild)\n.\u002Fcontainer\u002Fbuild.sh\n\n# Or force full rebuild\ndocker builder prune -af\n.\u002Fcontainer\u002Fbuild.sh\n```\n\n## Checking Container Image\n\n```bash\n# List images\ndocker images\n\n# Check what's in the image\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c '\n  echo \"=== Node version ===\"\n  node --version\n\n  echo \"=== Claude Code version ===\"\n  claude --version\n\n  echo \"=== Installed packages ===\"\n  ls \u002Fapp\u002Fnode_modules\u002F\n'\n```\n\n## Session Persistence\n\nClaude sessions are stored per-group in `data\u002Fsessions\u002F{group}\u002F.claude\u002F` for security isolation. Each group has its own session directory, preventing cross-group access to conversation history.\n\n**Critical:** The mount path must match the container user's HOME directory:\n- Container user: `node`\n- Container HOME: `\u002Fhome\u002Fnode`\n- Mount target: `\u002Fhome\u002Fnode\u002F.claude\u002F` (NOT `\u002Froot\u002F.claude\u002F`)\n\nTo clear sessions:\n\n```bash\n# Clear all sessions for all groups\nrm -rf data\u002Fsessions\u002F\n\n# Clear sessions for a specific group\nrm -rf data\u002Fsessions\u002F{groupFolder}\u002F.claude\u002F\n\n# Also clear the session ID from Deus's tracking (stored in SQLite)\nsqlite3 store\u002Fmessages.db \"DELETE FROM sessions WHERE group_folder = '{groupFolder}'\"\n```\n\nTo verify session resumption is working, check the logs for the same session ID across messages:\n```bash\ngrep \"Session initialized\" logs\u002Fdeus.log | tail -5\n# Should show the SAME session ID for consecutive messages in the same group\n```\n\n## IPC Debugging\n\nThe container communicates back to the host via files in `\u002Fworkspace\u002Fipc\u002F`:\n\n```bash\n# Check pending messages\nls -la data\u002Fipc\u002Fmessages\u002F\n\n# Check pending task operations\nls -la data\u002Fipc\u002Ftasks\u002F\n\n# Read a specific IPC file\ncat data\u002Fipc\u002Fmessages\u002F*.json\n\n# Check available groups (main channel only)\ncat data\u002Fipc\u002Fmain\u002Favailable_groups.json\n\n# Check current tasks snapshot\ncat data\u002Fipc\u002F{groupFolder}\u002Fcurrent_tasks.json\n```\n\n**IPC file types:**\n- `messages\u002F*.json` - Agent writes: outgoing WhatsApp messages\n- `tasks\u002F*.json` - Agent writes: task operations (schedule, pause, resume, cancel, refresh_groups)\n- `current_tasks.json` - Host writes: read-only snapshot of scheduled tasks\n- `available_groups.json` - Host writes: read-only list of WhatsApp groups (main only)\n\n## Quick Diagnostic Script\n\nRun this to check common issues:\n\n```bash\necho \"=== Checking Deus Container Setup ===\"\n\necho -e \"\\n1. Authentication configured?\"\n[ -f .env ] && (grep -q \"CLAUDE_CODE_OAUTH_TOKEN=sk-\" .env || grep -q \"ANTHROPIC_API_KEY=sk-\" .env) && echo \"OK\" || echo \"MISSING - add CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY to .env\"\n\necho -e \"\\n2. Env file copied for container?\"\n[ -f data\u002Fenv\u002Fenv ] && echo \"OK\" || echo \"MISSING - will be created on first run\"\n\necho -e \"\\n3. Container runtime running?\"\ndocker info &>\u002Fdev\u002Fnull && echo \"OK\" || echo \"NOT RUNNING - start Docker Desktop (macOS) or sudo systemctl start docker (Linux)\"\n\necho -e \"\\n4. Container image exists?\"\necho '{}' | docker run -i --entrypoint \u002Fbin\u002Fecho deus-agent:latest \"OK\" 2>\u002Fdev\u002Fnull || echo \"MISSING - run .\u002Fcontainer\u002Fbuild.sh\"\n\necho -e \"\\n5. Session mount path correct?\"\ngrep -q \"\u002Fhome\u002Fnode\u002F.claude\" src\u002Fcontainer-runner.ts 2>\u002Fdev\u002Fnull && echo \"OK\" || echo \"WRONG - should mount to \u002Fhome\u002Fnode\u002F.claude\u002F, not \u002Froot\u002F.claude\u002F\"\n\necho -e \"\\n6. Groups directory?\"\nls -la groups\u002F 2>\u002Fdev\u002Fnull || echo \"MISSING - run setup\"\n\necho -e \"\\n7. Recent container logs?\"\nls -t groups\u002F*\u002Flogs\u002Fcontainer-*.log 2>\u002Fdev\u002Fnull | head -3 || echo \"No container logs yet\"\n\necho -e \"\\n8. Session continuity working?\"\nSESSIONS=$(grep \"Session initialized\" logs\u002Fdeus.log 2>\u002Fdev\u002Fnull | tail -5 | awk '{print $NF}' | sort -u | wc -l)\n[ \"$SESSIONS\" -le 2 ] && echo \"OK (recent sessions reusing IDs)\" || echo \"CHECK - multiple different session IDs, may indicate resumption issues\"\n```\n","# Deus Container Debugging\n\nThis guide covers debugging the containerized agent execution system.\n\n## Architecture Overview\n\n```\nHost (macOS)                          Container (Linux VM)\n─────────────────────────────────────────────────────────────\nsrc\u002Fcontainer-runner.ts               container\u002Fagent-runner\u002F\n    │                                      │\n    │ spawns container                      │ runs Claude Agent SDK\n    │ with volume mounts                   │ with MCP servers\n    │                                      │\n    ├── data\u002Fenv\u002Fenv ──────────────> \u002Fworkspace\u002Fenv-dir\u002Fenv\n    ├── groups\u002F{folder} ───────────> \u002Fworkspace\u002Fgroup\n    ├── data\u002Fipc\u002F{folder} ────────> \u002Fworkspace\u002Fipc\n    ├── data\u002Fsessions\u002F{folder}\u002F.claude\u002F ──> \u002Fhome\u002Fnode\u002F.claude\u002F (isolated per-group)\n    └── (main only) project root ──> \u002Fworkspace\u002Fproject\n```\n\n**Important:** The container runs as user `node` with `HOME=\u002Fhome\u002Fnode`. Session files must be mounted to `\u002Fhome\u002Fnode\u002F.claude\u002F` (not `\u002Froot\u002F.claude\u002F`) for session resumption to work.\n\n## Log Locations\n\n| Log | Location | Content |\n|-----|----------|---------|\n| **Main app logs** | `logs\u002Fdeus.log` | Host-side WhatsApp, routing, container spawning |\n| **Main app errors** | `logs\u002Fdeus.error.log` | Host-side errors |\n| **Container run logs** | `groups\u002F{folder}\u002Flogs\u002Fcontainer-*.log` | Per-run: input, mounts, stderr, stdout |\n| **Claude sessions** | `~\u002F.claude\u002Fprojects\u002F` | Claude Code session history |\n\n## Enabling Debug Logging\n\nSet `LOG_LEVEL=debug` for verbose output:\n\n```bash\n# For development\nLOG_LEVEL=debug npm run dev\n\n# For launchd service (macOS), add to plist EnvironmentVariables:\n\u003Ckey>LOG_LEVEL\u003C\u002Fkey>\n\u003Cstring>debug\u003C\u002Fstring>\n# For systemd service (Linux), add to unit [Service] section:\n# Environment=LOG_LEVEL=debug\n```\n\nDebug level shows:\n- Full mount configurations\n- Container command arguments\n- Real-time container stderr\n\n## Common Issues\n\n### 1. \"Claude Code process exited with code 1\"\n\n**Check the container log file** in `groups\u002F{folder}\u002Flogs\u002Fcontainer-*.log`\n\nCommon causes:\n\n#### Missing Authentication\n```\nInvalid API key · Please run \u002Flogin\n```\n**Fix:** Ensure `.env` file exists with either OAuth token or API key:\n```bash\ncat .env  # Should show one of:\n# CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...  (subscription)\n# ANTHROPIC_API_KEY=sk-ant-api03-...        (pay-per-use)\n```\n\n#### Root User Restriction\n```\n--dangerously-skip-permissions cannot be used with root\u002Fsudo privileges\n```\n**Fix:** Container must run as non-root user. Check Dockerfile has `USER node`.\n\n### 2. Environment Variables Not Passing\n\n**Runtime note:** Environment variables passed via `-e` may be lost when using `-i` (interactive\u002Fpiped stdin).\n\n**Workaround:** The system extracts only authentication variables (`CLAUDE_CODE_OAUTH_TOKEN`, `ANTHROPIC_API_KEY`) from `.env` and mounts them for sourcing inside the container. Other env vars are not exposed.\n\nTo verify env vars are reaching the container:\n```bash\necho '{}' | docker run -i \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  --entrypoint \u002Fbin\u002Fbash deus-agent:latest \\\n  -c 'export $(cat \u002Fworkspace\u002Fenv-dir\u002Fenv | xargs); echo \"OAuth: ${#CLAUDE_CODE_OAUTH_TOKEN} chars, API: ${#ANTHROPIC_API_KEY} chars\"'\n```\n\n### 3. Mount Issues\n\n**Container mount notes:**\n- Docker supports both `-v` and `--mount` syntax\n- Use `:ro` suffix for readonly mounts:\n  ```bash\n  # Readonly\n  -v \u002Fpath:\u002Fcontainer\u002Fpath:ro\n\n  # Read-write\n  -v \u002Fpath:\u002Fcontainer\u002Fpath\n  ```\n\nTo check what's mounted inside a container:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c 'ls -la \u002Fworkspace\u002F'\n```\n\nExpected structure:\n```\n\u002Fworkspace\u002F\n├── env-dir\u002Fenv           # Environment file (CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY)\n├── group\u002F                # Current group folder (cwd)\n├── project\u002F              # Project root (main channel only)\n├── global\u002F               # Global CLAUDE.md (non-main only)\n├── ipc\u002F                  # Inter-process communication\n│   ├── messages\u002F         # Outgoing WhatsApp messages\n│   ├── tasks\u002F            # Scheduled task commands\n│   ├── current_tasks.json    # Read-only: scheduled tasks visible to this group\n│   └── available_groups.json # Read-only: WhatsApp groups for activation (main only)\n└── extra\u002F                # Additional custom mounts\n```\n\n### 4. Permission Issues\n\nThe container runs as user `node` (uid 1000). Check ownership:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c '\n  whoami\n  ls -la \u002Fworkspace\u002F\n  ls -la \u002Fapp\u002F\n'\n```\n\nAll of `\u002Fworkspace\u002F` and `\u002Fapp\u002F` should be owned by `node`.\n\n### 5. Session Not Resuming \u002F \"Claude Code process exited with code 1\"\n\nIf sessions aren't being resumed (new session ID every time), or Claude Code exits with code 1 when resuming:\n\n**Root cause:** The SDK looks for sessions at `$HOME\u002F.claude\u002Fprojects\u002F`. Inside the container, `HOME=\u002Fhome\u002Fnode`, so it looks at `\u002Fhome\u002Fnode\u002F.claude\u002Fprojects\u002F`.\n\n**Check the mount path:**\n```bash\n# In container-runner.ts, verify mount is to \u002Fhome\u002Fnode\u002F.claude\u002F, NOT \u002Froot\u002F.claude\u002F\ngrep -A3 \"Claude sessions\" src\u002Fcontainer-runner.ts\n```\n\n**Verify sessions are accessible:**\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash \\\n  -v ~\u002F.claude:\u002Fhome\u002Fnode\u002F.claude \\\n  deus-agent:latest -c '\necho \"HOME=$HOME\"\nls -la $HOME\u002F.claude\u002Fprojects\u002F 2>&1 | head -5\n'\n```\n\n**Fix:** Ensure `container-runner.ts` mounts to `\u002Fhome\u002Fnode\u002F.claude\u002F`:\n```typescript\nmounts.push({\n  hostPath: claudeDir,\n  containerPath: '\u002Fhome\u002Fnode\u002F.claude',  \u002F\u002F NOT \u002Froot\u002F.claude\n  readonly: false\n});\n```\n\n### 6. MCP Server Failures\n\nIf an MCP server fails to start, the agent may exit. Check the container logs for MCP initialization errors.\n\n## Manual Container Testing\n\n### Test the full agent flow:\n```bash\n# Set up env file\nmkdir -p data\u002Fenv groups\u002Ftest\ncp .env data\u002Fenv\u002Fenv\n\n# Run test query\necho '{\"prompt\":\"What is 2+2?\",\"groupFolder\":\"test\",\"chatJid\":\"test@g.us\",\"isMain\":false}' | \\\n  docker run -i \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  -v $(pwd)\u002Fgroups\u002Ftest:\u002Fworkspace\u002Fgroup \\\n  -v $(pwd)\u002Fdata\u002Fipc:\u002Fworkspace\u002Fipc \\\n  deus-agent:latest\n```\n\n### Test Claude Code directly:\n```bash\ndocker run --rm --entrypoint \u002Fbin\u002Fbash \\\n  -v $(pwd)\u002Fdata\u002Fenv:\u002Fworkspace\u002Fenv-dir:ro \\\n  deus-agent:latest -c '\n  export $(cat \u002Fworkspace\u002Fenv-dir\u002Fenv | xargs)\n  claude -p \"Say hello\" --dangerously-skip-permissions --allowedTools \"\"\n'\n```\n\n### Interactive shell in container:\n```bash\ndocker run --rm -it --entrypoint \u002Fbin\u002Fbash deus-agent:latest\n```\n\n## SDK Options Reference\n\nThe agent-runner uses these Claude Agent SDK options:\n\n```typescript\nquery({\n  prompt: input.prompt,\n  options: {\n    cwd: '\u002Fworkspace\u002Fgroup',\n    allowedTools: ['Bash', 'Read', 'Write', ...],\n    permissionMode: 'bypassPermissions',\n    allowDangerouslySkipPermissions: true,  \u002F\u002F Required with bypassPermissions\n    settingSources: ['project'],\n    mcpServers: { ... }\n  }\n})\n```\n\n**Important:** `allowDangerouslySkipPermissions: true` is required when using `permissionMode: 'bypassPermissions'`. Without it, Claude Code exits with code 1.\n\n## Rebuilding After Changes\n\n```bash\n# Rebuild main app\nnpm run build\n\n# Rebuild container (use --no-cache for clean rebuild)\n.\u002Fcontainer\u002Fbuild.sh\n\n# Or force full rebuild\ndocker builder prune -af\n.\u002Fcontainer\u002Fbuild.sh\n```\n\n## Checking Container Image\n\n```bash\n# List images\ndocker images\n\n# Check what's in the image\ndocker run --rm --entrypoint \u002Fbin\u002Fbash deus-agent:latest -c '\n  echo \"=== Node version ===\"\n  node --version\n\n  echo \"=== Claude Code version ===\"\n  claude --version\n\n  echo \"=== Installed packages ===\"\n  ls \u002Fapp\u002Fnode_modules\u002F\n'\n```\n\n## Session Persistence\n\nClaude sessions are stored per-group in `data\u002Fsessions\u002F{group}\u002F.claude\u002F` for security isolation. Each group has its own session directory, preventing cross-group access to conversation history.\n\n**Critical:** The mount path must match the container user's HOME directory:\n- Container user: `node`\n- Container HOME: `\u002Fhome\u002Fnode`\n- Mount target: `\u002Fhome\u002Fnode\u002F.claude\u002F` (NOT `\u002Froot\u002F.claude\u002F`)\n\nTo clear sessions:\n\n```bash\n# Clear all sessions for all groups\nrm -rf data\u002Fsessions\u002F\n\n# Clear sessions for a specific group\nrm -rf data\u002Fsessions\u002F{groupFolder}\u002F.claude\u002F\n\n# Also clear the session ID from Deus's tracking (stored in SQLite)\nsqlite3 store\u002Fmessages.db \"DELETE FROM sessions WHERE group_folder = '{groupFolder}'\"\n```\n\nTo verify session resumption is working, check the logs for the same session ID across messages:\n```bash\ngrep \"Session initialized\" logs\u002Fdeus.log | tail -5\n# Should show the SAME session ID for consecutive messages in the same group\n```\n\n## IPC Debugging\n\nThe container communicates back to the host via files in `\u002Fworkspace\u002Fipc\u002F`:\n\n```bash\n# Check pending messages\nls -la data\u002Fipc\u002Fmessages\u002F\n\n# Check pending task operations\nls -la data\u002Fipc\u002Ftasks\u002F\n\n# Read a specific IPC file\ncat data\u002Fipc\u002Fmessages\u002F*.json\n\n# Check available groups (main channel only)\ncat data\u002Fipc\u002Fmain\u002Favailable_groups.json\n\n# Check current tasks snapshot\ncat data\u002Fipc\u002F{groupFolder}\u002Fcurrent_tasks.json\n```\n\n**IPC file types:**\n- `messages\u002F*.json` - Agent writes: outgoing WhatsApp messages\n- `tasks\u002F*.json` - Agent writes: task operations (schedule, pause, resume, cancel, refresh_groups)\n- `current_tasks.json` - Host writes: read-only snapshot of scheduled tasks\n- `available_groups.json` - Host writes: read-only list of WhatsApp groups (main only)\n\n## Quick Diagnostic Script\n\nRun this to check common issues:\n\n```bash\necho \"=== Checking Deus Container Setup ===\"\n\necho -e \"\\n1. Authentication configured?\"\n[ -f .env ] && (grep -q \"CLAUDE_CODE_OAUTH_TOKEN=sk-\" .env || grep -q \"ANTHROPIC_API_KEY=sk-\" .env) && echo \"OK\" || echo \"MISSING - add CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY to .env\"\n\necho -e \"\\n2. Env file copied for container?\"\n[ -f data\u002Fenv\u002Fenv ] && echo \"OK\" || echo \"MISSING - will be created on first run\"\n\necho -e \"\\n3. Container runtime running?\"\ndocker info &>\u002Fdev\u002Fnull && echo \"OK\" || echo \"NOT RUNNING - start Docker Desktop (macOS) or sudo systemctl start docker (Linux)\"\n\necho -e \"\\n4. Container image exists?\"\necho '{}' | docker run -i --entrypoint \u002Fbin\u002Fecho deus-agent:latest \"OK\" 2>\u002Fdev\u002Fnull || echo \"MISSING - run .\u002Fcontainer\u002Fbuild.sh\"\n\necho -e \"\\n5. Session mount path correct?\"\ngrep -q \"\u002Fhome\u002Fnode\u002F.claude\" src\u002Fcontainer-runner.ts 2>\u002Fdev\u002Fnull && echo \"OK\" || echo \"WRONG - should mount to \u002Fhome\u002Fnode\u002F.claude\u002F, not \u002Froot\u002F.claude\u002F\"\n\necho -e \"\\n6. Groups directory?\"\nls -la groups\u002F 2>\u002Fdev\u002Fnull || echo \"MISSING - run setup\"\n\necho -e \"\\n7. Recent container logs?\"\nls -t groups\u002F*\u002Flogs\u002Fcontainer-*.log 2>\u002Fdev\u002Fnull | head -3 || echo \"No container logs yet\"\n\necho -e \"\\n8. Session continuity working?\"\nSESSIONS=$(grep \"Session initialized\" logs\u002Fdeus.log 2>\u002Fdev\u002Fnull | tail -5 | awk '{print $NF}' | sort -u | wc -l)\n[ \"$SESSIONS\" -le 2 ] && echo \"OK (recent sessions reusing IDs)\" || echo \"CHECK - multiple different session IDs, may indicate resumption issues\"\n```\n",{"name":5,"description":7},"main","2f24c38a2ae42d3161492f0729975b286452f4b4",".claude\u002Fskills\u002Fdebug",7,"https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus","https:\u002F\u002Fgithub.com\u002Fsliamh11","2026-11-13 20:39:27",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add sliamh11\u002FDeus --skill debug",{"tool":63,"command":64},"bunx","bunx skills add sliamh11\u002FDeus --skill debug",{"tool":66,"command":67},"pnpm","pnpm dlx skills add sliamh11\u002FDeus --skill debug","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fdebug\u002FSKILL.md",true,[],[72,96,113,127,137,152],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":78,"publishedAt":45},"01M6H3ZC87AJDM8566RP3CQ6BF","status","Quick read-only health check — session context, workspace mounts, tool availability, and task snapshot. Use when the user asks for system status or runs \u002Fstatus.","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fstatus\u002FSKILL.md",[],[74,79,80,81,82,83,84,85,86,87,88,39,89,90,91,92,93,94,95,36],"health","snapshot","for","read-only","quick","availability","session context","task","health check","only","session","user","context","read","check","workspace","tool",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":105,"publishedAt":45},"01M6H3Z8SK38PVH2B0W7NBP6ZP","resume","Load context from permanent memory and recent session logs. Tiered loading — CLAUDE.md full, session logs frontmatter-only by default.","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fresume\u002FSKILL.md",[102],{"categoryNo":103,"categoryName":104,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000038","人力资源",[98,106,107,108,109,110,111,88,89,91,34,112],"memory","load","loading","full","session logs","default","frontmatter",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":45},"01M6H3Z56ZBPKX77THMWSSHZCW","preserve","Scan the current conversation and silently save anything worth permanent memory to CLAUDE.md. Keeps the file compact — structured key:value, no prose.","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fpreserve\u002FSKILL.md",[],[115,120,121,122,123,124,125,126,106],"structured","compact","scan","conversation","prose","save","file",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":45},"01M6H3Z1AKK58CWWY762YD3X9A","compress","Save the current session to the vault. Writes a compact session log with a TL;DR frontmatter (always) and full details below (when useful).","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fcompress\u002FSKILL.md",[],[129,134,112,109,121,135,89,125,136],"with","log","vault",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":45},"01M6H3YX6STE1ZJC06EKWMY0M6","capabilities","Show what this Deus instance can do — installed skills, available tools, and system info. Read-only. Use when the user asks what the bot can do, what's installed, or runs \u002Fcapabilities.","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fcapabilities\u002FSKILL.md",[],[139,144,145,36,82,146,147,148,149,150,151,88,39,90,92],"Tools","bot","can","system info","info","what the","do","show",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":156,"categories":157,"keywords":159,"publishedAt":45},"01M6H3YSNXYAR7NC1TZPFCANZN","agent-browser","Browse the web for any task — research topics, read articles, interact with web apps, fill forms, take screenshots, extract data, and test web pages. Use whenever a browser would be useful, not just when the user explicitly asks.","https:\u002F\u002Fgithub.com\u002Fsliamh11\u002FDeus\u002Fblob\u002Fmain\u002Fcontainer\u002Fskills\u002Fagent-browser\u002FSKILL.md",[158],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[160,161,162,81,134,163,164,165,86,166,39,92,167,168,169,170,171,172,173,174],"agent browser","browser","take","apps","pages","forms","test web","just","Bash","browse","data","web","test","research","screenshots"]