From claudeclaw
Automates X (Twitter) interactions—post tweets, like, reply, retweet, quote—via Playwright browser automation in ClaudeClaw. Useful for setup, testing, troubleshooting Twitter functionality.
npx claudepluginhub sbusso/claudeclawThis skill uses the workspace's default tool permissions.
Browser automation for X interactions via WhatsApp.
Conducts multi-round deep research on GitHub repos via API and web searches, generating markdown reports with executive summaries, timelines, metrics, and Mermaid diagrams.
Dynamically discovers and combines enabled skills into cohesive, unexpected delightful experiences like interactive HTML or themed artifacts. Activates on 'surprise me', inspiration, or boredom cues.
Generates images from structured JSON prompts via Python script execution. Supports reference images and aspect ratios for characters, scenes, products, visuals.
Browser automation for X interactions via WhatsApp.
Compatibility: ClaudeClaw v1.0.0. Directory structure may change in future versions.
| Action | Tool | Description |
|---|---|---|
| Post | x_post | Publish new tweets |
| Like | x_like | Like any tweet |
| Reply | x_reply | Reply to tweets |
| Retweet | x_retweet | Retweet without comment |
| Quote | x_quote | Quote tweet with comment |
Before using this skill, ensure:
npm ls playwright dotenv-cli || npm install playwright dotenv-cli
.env (if Chrome is not at default location):
# Find your Chrome path
mdfind "kMDItemCFBundleIdentifier == 'com.google.Chrome'" 2>/dev/null | head -1
# Add to .env
CHROME_PATH=/path/to/Google Chrome.app/Contents/MacOS/Google Chrome
Service name: Derived from the directory name:
com.claudeclaw.<dirname>(macOS) /claudeclaw-<dirname>(Linux). For example, if cwd ismy-assistant, the service iscom.claudeclaw.my-assistant. Determine the correct service name before running service commands below.
# 1. Setup authentication (interactive)
npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts
# Verify: data/x-auth.json should exist after successful login
# 2. Rebuild container to include skill
./src/runtimes/docker/build.sh
# Verify: Output shows "COPY .claude/skills/x-integration/agent.ts"
# 3. Rebuild host and restart service
# Service name: In developer mode use com.claudeclaw / claudeclaw.
# Service name derived from directory name: com.claudeclaw.<dirname> / claudeclaw-<dirname>.
npm run build
launchctl kickstart -k gui/$(id -u)/com.claudeclaw # macOS
# Linux: systemctl --user restart claudeclaw
# Verify: launchctl list | grep claudeclaw (macOS) or systemctl --user status claudeclaw (Linux)
| Variable | Default | Description |
|---|---|---|
CHROME_PATH | /Applications/Google Chrome.app/Contents/MacOS/Google Chrome | Chrome executable path |
CLAUDECLAW_ROOT | process.cwd() | Project root directory |
LOG_LEVEL | info | Logging level (debug, info, warn, error) |
Set in .env file (loaded via dotenv-cli at runtime):
# .env
CHROME_PATH=/Applications/Google Chrome.app/Contents/MacOS/Google Chrome
Edit lib/config.ts to modify defaults:
export const config = {
// Browser viewport
viewport: { width: 1280, height: 800 },
// Timeouts (milliseconds)
timeouts: {
navigation: 30000, // Page navigation
elementWait: 5000, // Wait for element
afterClick: 1000, // Delay after click
afterFill: 1000, // Delay after form fill
afterSubmit: 3000, // Delay after submit
pageLoad: 3000, // Initial page load
},
// Tweet limits
limits: {
tweetMaxLength: 280,
},
};
Paths relative to project root:
| Path | Purpose | Git |
|---|---|---|
data/x-browser-profile/ | Chrome profile with X session | Ignored |
data/x-auth.json | Auth state marker | Ignored |
logs/claudeclaw.log | Service logs (contains X operation logs) | Ignored |
┌─────────────────────────────────────────────────────────────┐
│ Container (Linux VM) │
│ └── agent.ts → MCP tool definitions (x_post, etc.) │
│ └── Writes IPC request to /workspace/ipc/tasks/ │
└──────────────────────┬──────────────────────────────────────┘
│ IPC (file system)
▼
┌─────────────────────────────────────────────────────────────┐
│ Host (macOS) │
│ └── src/orchestrator/ipc.ts → processTaskIpc() │
│ └── host.ts → handleXIpc() │
│ └── spawn subprocess → scripts/*.ts │
│ └── Playwright → Chrome → X Website │
└─────────────────────────────────────────────────────────────┘
.claude/skills/x-integration/
├── SKILL.md # This documentation
├── host.ts # Host-side IPC handler
├── agent.ts # Container-side MCP tool definitions
├── lib/
│ ├── config.ts # Centralized configuration
│ └── browser.ts # Playwright utilities
└── scripts/
├── setup.ts # Interactive login
├── post.ts # Post tweet
├── like.ts # Like tweet
├── reply.ts # Reply to tweet
├── retweet.ts # Retweet
└── quote.ts # Quote tweet
To integrate this skill into ClaudeClaw, make the following modifications:
1. Host side: src/orchestrator/ipc.ts
Add import after other local imports:
import { handleXIpc } from '../.claude/skills/x-integration/host.js';
Modify processTaskIpc function's switch statement default case:
// Find:
default:
logger.warn({ type: data.type }, 'Unknown IPC task type');
// Replace with:
default:
const handled = await handleXIpc(data, sourceGroup, isMain, DATA_DIR);
if (!handled) {
logger.warn({ type: data.type }, 'Unknown IPC task type');
}
2. Container side: agent/runner/src/ipc-mcp.ts
Add import after cron-parser import:
// @ts-ignore - Copied during Docker build from .claude/skills/x-integration/
import { createXTools } from './skills/x-integration/agent.js';
Add to the end of tools array (before the closing ]):
...createXTools({ groupFolder, isMain })
3. Build script: src/runtimes/docker/build.sh
Change build context from src/runtimes/docker/ to project root (required to access .claude/skills/):
# Find:
docker build -t "${IMAGE_NAME}:${TAG}" .
# Replace with:
cd "$SCRIPT_DIR/.."
docker build -t "${IMAGE_NAME}:${TAG}" -f src/runtimes/docker/Dockerfile .
4. Dockerfile: src/runtimes/docker/Dockerfile
First, update the build context paths (required to access .claude/skills/ from project root):
# Find:
COPY agent-runner/package*.json ./
...
COPY agent-runner/ ./
# Replace with:
COPY agent/runner/package*.json ./
...
COPY agent/runner/ ./
Then add COPY line after COPY agent/runner/ ./ and before RUN npm run build:
# Copy skill MCP tools
COPY .claude/skills/x-integration/agent.ts ./src/skills/x-integration/
All paths below are relative to project root (CLAUDECLAW_ROOT).
# Check if Chrome exists at configured path
cat .env | grep CHROME_PATH
ls -la "$(grep CHROME_PATH .env | cut -d= -f2)" 2>/dev/null || \
echo "Chrome not found - update CHROME_PATH in .env"
npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts
This opens Chrome for manual X login. Session saved to data/x-browser-profile/.
Verify success:
cat data/x-auth.json # Should show {"authenticated": true, ...}
./src/runtimes/docker/build.sh
Verify success:
./src/runtimes/docker/build.sh 2>&1 | grep -i "agent.ts" # Should show COPY line
npm run build
launchctl kickstart -k gui/$(id -u)/com.claudeclaw # macOS
# Linux: systemctl --user restart claudeclaw
Verify success:
launchctl list | grep claudeclaw # macOS — should show PID and exit code 0 or -
# Linux: systemctl --user status claudeclaw
Replace @Assistant with your configured trigger name (ASSISTANT_NAME in .env):
@Assistant post a tweet: Hello world!
@Assistant like this tweet https://x.com/user/status/123
@Assistant reply to https://x.com/user/status/123 with: Great post!
@Assistant retweet https://x.com/user/status/123
@Assistant quote https://x.com/user/status/123 with comment: Interesting
Note: Only the main group can use X tools. Other groups will receive an error.
Scripts require environment variables from .env. Use dotenv-cli to load them:
# Check if auth file exists and is valid
cat data/x-auth.json 2>/dev/null && echo "Auth configured" || echo "Auth not configured"
# Check if browser profile exists
ls -la data/x-browser-profile/ 2>/dev/null | head -5
npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts
echo '{"content":"Test tweet - please ignore"}' | npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/post.ts
echo '{"tweetUrl":"https://x.com/user/status/123"}' | npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/like.ts
Or export CHROME_PATH manually before running:
export CHROME_PATH="/path/to/chrome"
echo '{"content":"Test"}' | npx tsx .claude/skills/x-integration/scripts/post.ts
npx dotenv -e .env -- npx tsx .claude/skills/x-integration/scripts/setup.ts
launchctl kickstart -k gui/$(id -u)/com.claudeclaw # macOS
# Linux: systemctl --user restart claudeclaw
If Chrome fails to launch:
rm -f data/x-browser-profile/SingletonLock
rm -f data/x-browser-profile/SingletonSocket
rm -f data/x-browser-profile/SingletonCookie
# Host logs (relative to project root)
grep -i "x_post\|x_like\|x_reply\|handleXIpc" logs/claudeclaw.log | tail -20
# Script errors
grep -i "error\|failed" logs/claudeclaw.log | tail -20
Default timeout is 2 minutes (120s). Increase in host.ts:
const timer = setTimeout(() => {
proc.kill('SIGTERM');
resolve({ success: false, message: 'Script timed out (120s)' });
}, 120000); // ← Increase this value
If X updates their UI, selectors in scripts may break. Current selectors:
| Element | Selector |
|---|---|
| Tweet input | [data-testid="tweetTextarea_0"] |
| Post button | [data-testid="tweetButtonInline"] |
| Reply button | [data-testid="reply"] |
| Like | [data-testid="like"] |
| Unlike | [data-testid="unlike"] |
| Retweet | [data-testid="retweet"] |
| Unretweet | [data-testid="unretweet"] |
| Confirm retweet | [data-testid="retweetConfirm"] |
| Modal dialog | [role="dialog"][aria-modal="true"] |
| Modal submit | [data-testid="tweetButton"] |
If MCP tools not found in container:
# Verify build copies skill
./src/runtimes/docker/build.sh 2>&1 | grep -i skill
# Check container has the file
docker run claudeclaw-agent ls -la /app/src/skills/
data/x-browser-profile/ - Contains X session cookies (in .gitignore)data/x-auth.json - Auth state marker (in .gitignore)agent.ts and host.ts)