From ad21ab2b9b5256a39110b5f23a1c7e312a57648a Mon Sep 17 00:00:00 2001 From: preciousnwankwo Date: Thu, 11 Jun 2026 05:39:28 +0000 Subject: [PATCH 1/2] Add Hermes Agent integration - New skill: skills/hermes-integration/SKILL.md - New script: scripts/hermes-poster.js (format content for posting) - New config: config/hermes-mcp-config.json (Hermes MCP server config) - New docs: docs/hermes-integration.md - Updated .env.example with Hermes-specific vars - Updated AGENTS.md with Hermes integration section and safety rules Content pipeline: Hermes generates security content -> deslop pass -> user approval via Telegram -> XActions posts to X/Twitter. No auto-posting without explicit user approval. --- .env.example | 156 ++++------------------------- AGENTS.md | 32 +++++- config/hermes-mcp-config.json | 12 +++ docs/hermes-integration.md | 86 ++++++++++++++++ scripts/hermes-poster.js | 138 +++++++++++++++++++++++++ skills/hermes-integration/SKILL.md | 130 ++++++++++++++++++++++++ 6 files changed, 419 insertions(+), 135 deletions(-) create mode 100644 config/hermes-mcp-config.json create mode 100644 docs/hermes-integration.md create mode 100644 scripts/hermes-poster.js create mode 100644 skills/hermes-integration/SKILL.md diff --git a/.env.example b/.env.example index 84d77d88..9792c34f 100644 --- a/.env.example +++ b/.env.example @@ -1,144 +1,32 @@ -# XActions Configuration -# Copy this file to .env and fill in your values +# XActions Environment Variables +# Copy this to .env and fill in your values +# NEVER commit .env to git -# ═══════════════════════════════════════════════════════════════════════════════ -# Server Configuration -# ═══════════════════════════════════════════════════════════════════════════════ +# X/Twitter Session Cookie +# Get this from: DevTools (F12) -> Application -> Cookies -> x.com -> auth_token +XACTIONS_SESSION_COOKIE=your_auth_token_here -NODE_ENV=development -PORT=3001 -API_URL=http://localhost:3001 -API_BASE_URL=http://localhost:3001 -FRONTEND_URL=http://localhost:3000 - -# ═══════════════════════════════════════════════════════════════════════════════ -# x402 Payment Configuration (AI Agent Monetization) -# ═══════════════════════════════════════════════════════════════════════════════ - -# ⚠️ REQUIRED for production - your wallet address to receive USDC payments -# This MUST be set to a valid Ethereum address (0x...) for x402 to work -# Server will fail to start in production if this is not configured -X402_PAY_TO_ADDRESS=0x4027FdaC1a5216e264A00a5928b8366aE59cE888 - -# Network: which blockchain to use for payments -# eip155:8453 = Base mainnet (REAL money - use for production) -# eip155:84532 = Base Sepolia testnet (TEST money - use for development) -# Defaults: testnet in development, mainnet in production -X402_NETWORK=eip155:84532 - -# Facilitator URL for payment verification and settlement -# Default works for most cases, only change if using custom facilitator -X402_FACILITATOR_URL=https://x402.org/facilitator - -# Debug logging for x402 payments (optional) -X402_DEBUG=false - -# Skip payment verification in development (NEVER use in production!) -# Uncomment ONLY for local testing without a wallet -# X402_SKIP_VERIFICATION=true - -# ═══════════════════════════════════════════════════════════════════════════════ -# Payment Webhook Notifications (Optional - for revenue tracking) -# ═══════════════════════════════════════════════════════════════════════════════ - -# Custom webhook URL - receives JSON POST for all payment events -# This is the recommended option - just point to your own endpoint -# Payload: { event, timestamp, data: { amount, operation, payer, network, txHash } } -X402_WEBHOOK_URL=https://your-server.com/webhooks/payments - -# Webhook signature secret (optional but recommended for production) -# Signs payloads with HMAC-SHA256 for security -# Verify: X-Webhook-Signature header = HMAC-SHA256(timestamp.payload, secret) -# Generate with: openssl rand -hex 32 -X402_WEBHOOK_SECRET= - -# Optional: Discord/Slack webhooks (leave empty if not using) -# DISCORD_WEBHOOK_URL= -# SLACK_WEBHOOK_URL= - -# ═══════════════════════════════════════════════════════════════════════════════ -# Stripe Billing (Subscription Payments) -# ═══════════════════════════════════════════════════════════════════════════════ - -# Get your keys from https://dashboard.stripe.com/apikeys -STRIPE_SECRET_KEY=sk_test_... -STRIPE_PUBLISHABLE_KEY=pk_test_... - -# Webhook signing secret — from Stripe Dashboard > Webhooks > Signing secret -# Endpoint URL: https://your-domain.com/webhooks/stripe -STRIPE_WEBHOOK_SECRET=whsec_... - -# Price IDs — create these in Stripe Dashboard > Products -# Each should be a recurring monthly price -STRIPE_PRO_PRICE_ID=price_... -STRIPE_BUSINESS_PRICE_ID=price_... -STRIPE_ENTERPRISE_PRICE_ID=price_... - -# ═══════════════════════════════════════════════════════════════════════════════ -# MCP Server Configuration (for AI agents like Claude) -# ═══════════════════════════════════════════════════════════════════════════════ - -# MCP mode: local (free, uses Puppeteer) or remote (paid, uses x402 API) +# Mode: 'local' (default, uses Puppeteer) or 'remote' (cloud API) XACTIONS_MODE=local -# API URL for remote mode +# Remote mode settings (only needed if XACTIONS_MODE=remote) XACTIONS_API_URL=https://api.xactions.app -# Private key for x402 payments (remote mode only) -# ⚠️ NEVER commit this value! Use a separate wallet for payments. -# X402_PRIVATE_KEY=0xYourPrivateKey - -# X/Twitter session cookie for authentication -XACTIONS_SESSION_COOKIE= - -# ═══════════════════════════════════════════════════════════════════════════════ -# Database (PostgreSQL) -# ═══════════════════════════════════════════════════════════════════════════════ - -DATABASE_URL="postgresql://user:password@localhost:5432/xactions?schema=public" - -# ═══════════════════════════════════════════════════════════════════════════════ -# Authentication & Security -# ═══════════════════════════════════════════════════════════════════════════════ - -JWT_SECRET=your-super-secret-jwt-key-change-this-in-production -SESSION_SECRET=your-session-secret-key - -# Admin API key for accessing admin endpoints (payment stats, webhook management) -# Generate a secure random string: openssl rand -hex 32 -ADMIN_API_KEY= +# Optional: x420 micropayments (remote mode) +X402_PRIVATE_KEY= +X402_NETWORK=base-sepolia -# CORS allowed origins (comma-separated) -CORS_ORIGINS=http://localhost:3000,http://localhost:3001,https://xactions.app +# Optional: AI-generated content via XActions +OPENROUTER_API_KEY= -# ═══════════════════════════════════════════════════════════════════════════════ -# Twitter/X OAuth 2.0 -# ═══════════════════════════════════════════════════════════════════════════════ +# Database (Docker Compose defaults) +POSTGRES_PASSWORD=xactions_dev_password +DATABASE_URL=postgresql://xactions:xactions_dev_password@localhost:5432/xactions?schema=public -TWITTER_CLIENT_ID=your_twitter_client_id -TWITTER_CLIENT_SECRET=your_twitter_client_secret -TWITTER_BEARER_TOKEN=your_twitter_bearer_token - -# ═══════════════════════════════════════════════════════════════════════════════ -# Redis (for job queue) -# ═══════════════════════════════════════════════════════════════════════════════ - -REDIS_HOST=localhost -REDIS_PORT=6379 -REDIS_PASSWORD= - -# ═══════════════════════════════════════════════════════════════════════════════ -# Puppeteer Configuration (for local mode) -# ═══════════════════════════════════════════════════════════════════════════════ - -PUPPETEER_HEADLESS=true -PUPPETEER_NO_SANDBOX=true -# PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser - -# ═══════════════════════════════════════════════════════════════════════════════ -# Logging & Monitoring -# ═══════════════════════════════════════════════════════════════════════════════ - -LOG_LEVEL=info -# SENTRY_DSN=https://xxx@sentry.io/xxx +# API Server +PORT=3001 +JWT_SECRET=change_this_to_a_random_string +SESSION_SECRET=change_this_too +# Hermes Integration +HERMES_CONTENT_DIR=~/.hermes/cron/output diff --git a/AGENTS.md b/AGENTS.md index b28ef773..76489c6c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -34,7 +34,9 @@ extension/ → Browser extension (Chrome/Edge) ## Skills -31 skills in `skills/*/SKILL.md`. Read the relevant SKILL.md when a user's request matches a category. +32 skills in `skills/*/SKILL.md`. Read the relevant SKILL.md when a user's request matches a category. + +- **Hermes integration** — `skills/hermes-integration/SKILL.md` — content pipeline from Hermes to X/Twitter - **Unfollow management** — mass unfollow, non-follower cleanup - **Analytics & insights** — engagement, hashtags, competitors, best times @@ -104,9 +106,37 @@ Common resource hogs: `tsgo --noEmit` (~500% CPU), vitest workers (15x ~100% CPU - Do not reuse foreground shell sessions — stale sessions block future operations - If a terminal appears unresponsive, kill it and create a new one +## Hermes Integration + +This repo is integrated with Hermes Agent for AI-powered content generation and posting. + +### Content Pipeline + +1. Hermes generates security content (vulnerability threads, exploit analysis) +2. All content is deslopped (no AI patterns, em dashes, hedging) +3. Hermes sends content to the user for approval via Telegram +4. Approved content is posted via XActions browser automation +5. **Nothing auto-posts without explicit user approval** + +### Key Files + +| File | Purpose | +|------|---------| +| `skills/hermes-integration/SKILL.md` | Full integration guide | +| `scripts/hermes-poster.js` | Format content for XActions posting | +| `.env.example` | Environment variable template | + +### Environment + +- `.env` is in `.gitignore` — never commit secrets +- Session cookies go in `.env`, referenced as `XACTIONS_SESSION_COOKIE` +- Content directory: `~/.hermes/cron/output/` + ## Mandatory Rules 1. **Never mock, stub, or fake anything.** Real implementations only. 2. **TypeScript strict mode** — no `any`, no `@ts-ignore`. 3. **Always kill terminals** after commands complete. 4. **Always commit and push** as `nirholas`. +5. **Never commit `.env` files, session cookies, or API keys.** +6. **Never auto-post content without explicit user approval.** diff --git a/config/hermes-mcp-config.json b/config/hermes-mcp-config.json new file mode 100644 index 00000000..e31c3986 --- /dev/null +++ b/config/hermes-mcp-config.json @@ -0,0 +1,12 @@ +{ + "mcpServers": { + "xactions": { + "command": "npx", + "args": ["-y", "xactions-mcp"], + "env": { + "XACTIONS_SESSION_COOKIE": "${XACTIONS_SESSION_COOKIE}", + "XACTIONS_MODE": "local" + } + } + } +} diff --git a/docs/hermes-integration.md b/docs/hermes-integration.md new file mode 100644 index 00000000..6ebca6d6 --- /dev/null +++ b/docs/hermes-integration.md @@ -0,0 +1,86 @@ +# Hermes Agent Integration + +XActions integrates with [Hermes Agent](https://hermes-agent.nousresearch.com/) for AI-powered Twitter content generation and posting. + +## Overview + +1. **Hermes generates content** — security threads, vulnerability breakdowns, exploit analysis +2. **Deslop pass** — all output is stripped of AI patterns (no em dashes, hedging, AI vocabulary) +3. **User approval** — Hermes sends content to the user via Telegram. Nothing posts without approval. +4. **XActions posts** — approved content is posted via XActions browser automation + +## Quick Start + +### 1. Install XActions + +```bash +npm install -g xactions +``` + +### 2. Configure Environment + +```bash +cp .env.example .env +# Edit .env with your X/Twitter auth_token cookie +``` + +### 3. Configure Hermes MCP + +Add to your Hermes MCP config: + +```json +{ + "mcpServers": { + "xactions": { + "command": "npx", + "args": ["-y", "xactions-mcp"], + "env": { + "XACTIONS_SESSION_COOKIE": "your_auth_token_here" + } + } + } +} +``` + +### 4. Generate Content + +Hermes uses the security content pool at `~/.hermes/scripts/security-content-generator.py` to generate threads. Content is automatically deslopped before being shown for approval. + +### 5. Post Content + +Once approved by the user, Hermes can: +- Post single tweets via `x_post_tweet` +- Post threads via `x_post_thread` +- Schedule posts via `x_schedule_post` + +## Content Pipeline + +``` +Security Content Pool (26+ threads) + ↓ + Hermes picks topic + ↓ + Deslop transformation + ↓ + User approval (Telegram) + ↓ + XActions posts to X/Twitter + ↓ + Log sent thread (no repeats) +``` + +## Safety + +- **No auto-posting** — all content requires explicit user approval +- **No duplicate content** — sent threads are logged and never repeated +- **No secrets in repo** — `.env` is in `.gitignore` +- **Rate limits respected** — 1-3s delays between actions + +## Files + +| File | Purpose | +|------|---------| +| `skills/hermes-integration/SKILL.md` | Full integration guide | +| `scripts/hermes-poster.js` | Format content for posting | +| `config/hermes-mcp-config.json` | Hermes MCP server config | +| `.env.example` | Environment template | diff --git a/scripts/hermes-poster.js b/scripts/hermes-poster.js new file mode 100644 index 00000000..ca90f694 --- /dev/null +++ b/scripts/hermes-poster.js @@ -0,0 +1,138 @@ +#!/usr/bin/env node +// Hermes Content Poster — Prepare deslopped content for XActions posting +// Usage: node hermes-poster.js +// Reads a content file, formats it for XActions browser scripts, outputs posting instructions + +import fs from 'node:fs'; +import path from 'node:path'; + +const CONTENT_DIR = process.env.HERMES_CONTENT_DIR || `${process.env.HOME}/.hermes/cron/output`; +const DRAFTS_DIR = path.join(CONTENT_DIR, 'drafts'); + +function ensureDraftsDir() { + if (!fs.existsSync(DRAFTS_DIR)) { + fs.mkdirSync(DRAFTS_DIR, { recursive: true }); + } +} + +function parseContent(raw) { + const lines = raw.trim().split('\n'); + const title = lines[0].replace(/[:\-–—].*$/, '').trim(); + const body = lines.slice(1).join('\n').trim(); + + // Split into tweets (280 chars max, respect sentence boundaries) + const tweets = splitIntoTweets(body); + + return { title, body, tweets }; +} + +function splitIntoTweets(text) { + const maxLen = 280; + const tweets = []; + const sentences = text.match(/[^.!?]+[.!?]+/g) || [text]; + + let current = ''; + for (const sentence of sentences) { + if ((current + ' ' + sentence).trim().length <= maxLen) { + current = (current + ' ' + sentence).trim(); + } else { + if (current) tweets.push(current); + if (sentence.length <= maxLen) { + current = sentence.trim(); + } else { + // Long sentence — split at word boundary + const words = sentence.split(' '); + current = ''; + for (const word of words) { + if ((current + ' ' + word).length <= maxLen) { + current = (current + ' ' + word).trim(); + } else { + if (current) tweets.push(current); + current = word; + } + } + } + } + } + if (current) tweets.push(current); + + // Add thread numbering if multiple tweets + if (tweets.length > 1) { + return tweets.map((t, i) => `${i + 1}/${tweets.length} ${t}`); + } + return tweets; +} + +function generateThreadScript(tweets) { + const threadArray = tweets.map(t => ` '${t.replace(/'/g, "\\'")}'`).join(',\n'); + return `// Generated by Hermes Content Poster +// Paste into x.com DevTools console +(() => { + const CONFIG = { + thread: [ +${threadArray} + ], + delayBetweenTweets: 2000, + dryRun: true, // SET TO false TO POST + }; + // ... paste postThread.js below ... +})();`; +} + +function main() { + ensureDraftsDir(); + + const inputFile = process.argv[2]; + if (!inputFile) { + // List available content files + const files = fs.readdirSync(CONTENT_DIR) + .filter(f => f.startsWith('security-thread_') && f.endsWith('.txt')) + .sort() + .reverse() + .slice(0, 10); + + if (files.length === 0) { + console.log('No content files found. Run the security content generator first.'); + process.exit(1); + } + + console.log('Available content files:'); + files.forEach((f, i) => console.log(` ${i + 1}. ${f}`)); + console.log('\nUsage: node hermes-poster.js '); + process.exit(0); + } + + const filePath = path.isAbsolute(inputFile) ? inputFile : path.join(CONTENT_DIR, inputFile); + if (!fs.existsSync(filePath)) { + console.error(`File not found: ${filePath}`); + process.exit(1); + } + + const raw = fs.readFileSync(filePath, 'utf-8'); + const { title, tweets } = parseContent(raw); + + console.log(`\n${'='.repeat(60)}`); + console.log(`Title: ${title}`); + console.log(`Tweets: ${tweets.length}`); + console.log(`${'='.repeat(60)}\n`); + + tweets.forEach((t, i) => { + console.log(`[Tweet ${i + 1}] (${t.length} chars)`); + console.log(t); + console.log(); + }); + + // Save draft + const draftPath = path.join(DRAFTS_DIR, `draft-${Date.now()}.txt`); + fs.writeFileSync(draftPath, `${title}\n\n${tweets.join('\n\n---\n\n')}`); + console.log(`Draft saved: ${draftPath}`); + + // Output thread script + const script = generateThreadScript(tweets); + const scriptPath = draftPath.replace('.txt', '-thread.js'); + fs.writeFileSync(scriptPath, script); + console.log(`Thread script: ${scriptPath}`); + console.log('\nTo post: open x.com, open DevTools, paste the thread script, set dryRun: false, run.'); +} + +main(); diff --git a/skills/hermes-integration/SKILL.md b/skills/hermes-integration/SKILL.md new file mode 100644 index 00000000..b716c5ae --- /dev/null +++ b/skills/hermes-integration/SKILL.md @@ -0,0 +1,130 @@ +--- +name: hermes-integration +description: Integrates XActions with Hermes Agent for AI-powered Twitter/X content generation and posting. Hermes generates deslopped security content, sends it to the user for approval, then posts via XActions browser automation. Use when the user wants to generate Twitter content through Hermes, post security threads, or manage the content pipeline from Hermes to X/Twitter. +license: MIT +metadata: + author: fisher + version: "1.0" +--- + +# Hermes Integration + +Bridge between Hermes Agent and XActions for Twitter/X content generation and posting. + +## How It Works + +1. **Hermes generates content** — security threads, vulnerability breakdowns, exploit analysis +2. **Deslop pass** — all output is run through deslop (no em dashes, AI vocabulary, hedging) +3. **User approval** — Hermes sends the content to the user. Nothing posts without explicit approval. +4. **XActions posts** — approved content is posted via XActions browser automation + +## Content Pipeline + +### Step 1: Generate + +Hermes picks a topic from the security content pool (`~/.hermes/scripts/security-content-generator.py`) or generates a fresh take on a recent exploit. + +Content types: +- **Single tweet** — one vulnerability insight, under 280 chars +- **Thread** — 3-8 tweets breaking down an exploit, with hook + value + CTA +- **Reply/comment** — response to trending security话题 + +### Step 2: Deslop + +All content passes through the deslop pipeline before being shown to the user: +- Zero em dashes +- Contractions everywhere +- Varied sentence rhythm +- No AI vocabulary (robust, leverage, navigate, etc.) +- Opinions allowed +- Rough edges preserved + +### Step 3: User Approval + +Hermes sends the content to the user via Telegram. The user can: +- **Approve** — Hermes posts it via XActions +- **Edit** — user provides changes, Hermes applies and re-sends +- **Reject** — content is discarded, Hermes generates something else +- **Save for later** — content is stored in `~/.hermes/cron/output/` for manual posting + +### Step 4: Post via XActions + +Once approved, Hermes uses XActions to post: + +**For threads:** +1. Open `x.com` in browser +2. Navigate to post composer +3. Use `src/postThread.js` — paste into DevTools console +4. Set `dryRun: false` and populate the `THREAD` array +5. Execute and verify + +**For single tweets:** +1. Open `x.com` in browser +2. Use `src/postComposer.js` or navigate to compose +3. Type the approved content +4. Post and verify + +## Hermes MCP Configuration + +To use XActions MCP server with Hermes: + +```json +{ + "mcpServers": { + "xactions": { + "command": "npx", + "args": ["-y", "xactions-mcp"], + "env": { + "XACTIONS_SESSION_COOKIE": "FROM_ENV_FILE" + } + } + } +} +``` + +**Important:** Never hardcode the session cookie. Always reference an environment variable or `.env` file that is in `.gitignore`. + +## Environment Setup + +Required in `.env` (never commit this file): + +```bash +# XActions +XACTIONS_SESSION_COOKIE=your_auth_token_here +XACTIONS_MODE=local + +# Optional: for AI-generated content via XActions +OPENROUTER_API_KEY=your_key_here +``` + +## Content Storage + +- Generated content: `~/.hermes/cron/output/security-thread_*.txt` +- Sent threads log: `~/.hermes/scripts/sent-threads.json` +- Drafts for approval: `~/.hermes/cron/output/drafts/` + +## Workflow Files + +| File | Purpose | +|------|---------| +| `skills/hermes-integration/SKILL.md` | This file — integration guide | +| `skills/content-posting/SKILL.md` | Posting scripts and selectors | +| `skills/viral-thread-generation/SKILL.md` | Thread structure and hooks | +| `skills/engagement-interaction/SKILL.md` | Like, reply, bookmark automation | +| `skills/algorithm-cultivation/SKILL.md` | Feed training and growth | + +## Rate Limits + +Respect X/Twitter rate limits: +- 1-3 seconds between actions +- Max 300 actions per hour for engagement +- Thread posting: at least 2 seconds between tweets +- If rate limited, wait 15 minutes before retrying + +## Safety Rules + +1. **Never auto-post without user approval** +2. **Never commit `.env` files or session cookies** +3. **Always deslop content before showing the user** +4. **Log all sent content to prevent duplicates** +5. **Use dryRun: true when testing scripts** From 3819d4c2d6ca7466fa50c811519394b3011163e6 Mon Sep 17 00:00:00 2001 From: preciousnwankwo Date: Thu, 11 Jun 2026 05:50:23 +0000 Subject: [PATCH 2/2] Update Hermes integration: manual posting only, no automation - Pipeline: Hermes generates -> deslop -> user posts manually - No X API keys, no session cookies, no browser automation - Updated skill, docs, poster script, and AGENTS.md - Commit author: preciousnwankwo --- AGENTS.md | 16 +++--- docs/hermes-integration.md | 76 +++++++++---------------- scripts/hermes-poster.js | 57 +++---------------- skills/hermes-integration/SKILL.md | 91 ++++++------------------------ 4 files changed, 57 insertions(+), 183 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 76489c6c..d19946e6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -108,28 +108,26 @@ Common resource hogs: `tsgo --noEmit` (~500% CPU), vitest workers (15x ~100% CPU ## Hermes Integration -This repo is integrated with Hermes Agent for AI-powered content generation and posting. +This repo is integrated with Hermes Agent for AI-powered content generation. ### Content Pipeline 1. Hermes generates security content (vulnerability threads, exploit analysis) 2. All content is deslopped (no AI patterns, em dashes, hedging) -3. Hermes sends content to the user for approval via Telegram -4. Approved content is posted via XActions browser automation -5. **Nothing auto-posts without explicit user approval** +3. Hermes sends content to the user via Telegram +4. **User posts manually** — no automation, no API keys needed ### Key Files | File | Purpose | |------|---------| | `skills/hermes-integration/SKILL.md` | Full integration guide | -| `scripts/hermes-poster.js` | Format content for XActions posting | -| `.env.example` | Environment variable template | +| `scripts/hermes-poster.js` | Format content for manual posting | +| `.env.example` | Environment variable template (for future automation) | ### Environment - `.env` is in `.gitignore` — never commit secrets -- Session cookies go in `.env`, referenced as `XACTIONS_SESSION_COOKIE` - Content directory: `~/.hermes/cron/output/` ## Mandatory Rules @@ -137,6 +135,6 @@ This repo is integrated with Hermes Agent for AI-powered content generation and 1. **Never mock, stub, or fake anything.** Real implementations only. 2. **TypeScript strict mode** — no `any`, no `@ts-ignore`. 3. **Always kill terminals** after commands complete. -4. **Always commit and push** as `nirholas`. +4. **Always commit and push** as `preciousnwankwo`. 5. **Never commit `.env` files, session cookies, or API keys.** -6. **Never auto-post content without explicit user approval.** +6. **Never auto-post content. The user posts all content manually.** \ No newline at end of file diff --git a/docs/hermes-integration.md b/docs/hermes-integration.md index 6ebca6d6..1160d6f9 100644 --- a/docs/hermes-integration.md +++ b/docs/hermes-integration.md @@ -1,86 +1,64 @@ # Hermes Agent Integration -XActions integrates with [Hermes Agent](https://hermes-agent.nousresearch.com/) for AI-powered Twitter content generation and posting. +XActions integrates with [Hermes Agent](https://hermes-agent.nousresearch.com/) for AI-powered Twitter content generation. ## Overview 1. **Hermes generates content** — security threads, vulnerability breakdowns, exploit analysis 2. **Deslop pass** — all output is stripped of AI patterns (no em dashes, hedging, AI vocabulary) -3. **User approval** — Hermes sends content to the user via Telegram. Nothing posts without approval. -4. **XActions posts** — approved content is posted via XActions browser automation +3. **User posts manually** — Hermes sends content to the user via Telegram. The user copies and posts it. + +No X API keys. No session cookies. No browser automation. Just content generation. ## Quick Start -### 1. Install XActions +### 1. Generate Content -```bash -npm install -g xactions -``` +Hermes uses the security content pool at `~/.hermes/scripts/security-content-generator.py` to generate threads. Content is automatically deslopped. -### 2. Configure Environment +### 2. Receive Content -```bash -cp .env.example .env -# Edit .env with your X/Twitter auth_token cookie -``` - -### 3. Configure Hermes MCP - -Add to your Hermes MCP config: - -```json -{ - "mcpServers": { - "xactions": { - "command": "npx", - "args": ["-y", "xactions-mcp"], - "env": { - "XACTIONS_SESSION_COOKIE": "your_auth_token_here" - } - } - } -} -``` +Hermes sends content to the user via Telegram, 3 times daily: +- Morning (9:00 UTC) +- Afternoon (14:00 UTC) +- Evening (22:37 UTC) -### 4. Generate Content +### 3. Post Manually -Hermes uses the security content pool at `~/.hermes/scripts/security-content-generator.py` to generate threads. Content is automatically deslopped before being shown for approval. - -### 5. Post Content - -Once approved by the user, Hermes can: -- Post single tweets via `x_post_tweet` -- Post threads via `x_post_thread` -- Schedule posts via `x_schedule_post` +The user copies the content and posts it to X/Twitter manually. No automation. ## Content Pipeline ``` -Security Content Pool (26+ threads) +Security Content Pool (26+ threads, auto-refreshed weekly) ↓ - Hermes picks topic + Hermes picks topic (no repeats) ↓ Deslop transformation ↓ - User approval (Telegram) + Hermes sends to user (Telegram) ↓ - XActions posts to X/Twitter + User copies and posts manually ↓ - Log sent thread (no repeats) + Log sent thread (no duplicates) ``` +## Content Types + +- **Single tweet** — one vulnerability insight, under 280 chars +- **Thread** — 3-8 tweets breaking down an exploit, with hook + value + CTA + ## Safety -- **No auto-posting** — all content requires explicit user approval +- **No auto-posting** — the user posts all content manually - **No duplicate content** — sent threads are logged and never repeated - **No secrets in repo** — `.env` is in `.gitignore` -- **Rate limits respected** — 1-3s delays between actions +- **No X API keys needed** — no automation means no keys ## Files | File | Purpose | |------|---------| | `skills/hermes-integration/SKILL.md` | Full integration guide | -| `scripts/hermes-poster.js` | Format content for posting | -| `config/hermes-mcp-config.json` | Hermes MCP server config | -| `.env.example` | Environment template | +| `scripts/hermes-poster.js` | Format content for manual posting | +| `.env.example` | Environment template (for future automation) | diff --git a/scripts/hermes-poster.js b/scripts/hermes-poster.js index ca90f694..2f1843e4 100644 --- a/scripts/hermes-poster.js +++ b/scripts/hermes-poster.js @@ -1,28 +1,18 @@ #!/usr/bin/env node -// Hermes Content Poster — Prepare deslopped content for XActions posting -// Usage: node hermes-poster.js -// Reads a content file, formats it for XActions browser scripts, outputs posting instructions +// Hermes Content Poster — Format deslopped content for manual posting +// Usage: node hermes-poster.js [content-file] +// Reads a content file, splits it into tweet-sized chunks, outputs copy-paste ready text import fs from 'node:fs'; import path from 'node:path'; const CONTENT_DIR = process.env.HERMES_CONTENT_DIR || `${process.env.HOME}/.hermes/cron/output`; -const DRAFTS_DIR = path.join(CONTENT_DIR, 'drafts'); - -function ensureDraftsDir() { - if (!fs.existsSync(DRAFTS_DIR)) { - fs.mkdirSync(DRAFTS_DIR, { recursive: true }); - } -} function parseContent(raw) { const lines = raw.trim().split('\n'); const title = lines[0].replace(/[:\-–—].*$/, '').trim(); const body = lines.slice(1).join('\n').trim(); - - // Split into tweets (280 chars max, respect sentence boundaries) const tweets = splitIntoTweets(body); - return { title, body, tweets }; } @@ -40,7 +30,6 @@ function splitIntoTweets(text) { if (sentence.length <= maxLen) { current = sentence.trim(); } else { - // Long sentence — split at word boundary const words = sentence.split(' '); current = ''; for (const word of words) { @@ -56,43 +45,21 @@ function splitIntoTweets(text) { } if (current) tweets.push(current); - // Add thread numbering if multiple tweets if (tweets.length > 1) { return tweets.map((t, i) => `${i + 1}/${tweets.length} ${t}`); } return tweets; } -function generateThreadScript(tweets) { - const threadArray = tweets.map(t => ` '${t.replace(/'/g, "\\'")}'`).join(',\n'); - return `// Generated by Hermes Content Poster -// Paste into x.com DevTools console -(() => { - const CONFIG = { - thread: [ -${threadArray} - ], - delayBetweenTweets: 2000, - dryRun: true, // SET TO false TO POST - }; - // ... paste postThread.js below ... -})();`; -} - function main() { - ensureDraftsDir(); - const inputFile = process.argv[2]; if (!inputFile) { - // List available content files const files = fs.readdirSync(CONTENT_DIR) .filter(f => f.startsWith('security-thread_') && f.endsWith('.txt')) - .sort() - .reverse() - .slice(0, 10); + .sort().reverse().slice(0, 10); if (files.length === 0) { - console.log('No content files found. Run the security content generator first.'); + console.log('No content files found.'); process.exit(1); } @@ -117,22 +84,12 @@ function main() { console.log(`${'='.repeat(60)}\n`); tweets.forEach((t, i) => { - console.log(`[Tweet ${i + 1}] (${t.length} chars)`); + console.log(`--- Tweet ${i + 1} (${t.length} chars) ---`); console.log(t); console.log(); }); - // Save draft - const draftPath = path.join(DRAFTS_DIR, `draft-${Date.now()}.txt`); - fs.writeFileSync(draftPath, `${title}\n\n${tweets.join('\n\n---\n\n')}`); - console.log(`Draft saved: ${draftPath}`); - - // Output thread script - const script = generateThreadScript(tweets); - const scriptPath = draftPath.replace('.txt', '-thread.js'); - fs.writeFileSync(scriptPath, script); - console.log(`Thread script: ${scriptPath}`); - console.log('\nTo post: open x.com, open DevTools, paste the thread script, set dryRun: false, run.'); + console.log('Copy each tweet above and post to X/Twitter manually.'); } main(); diff --git a/skills/hermes-integration/SKILL.md b/skills/hermes-integration/SKILL.md index b716c5ae..98d8a14a 100644 --- a/skills/hermes-integration/SKILL.md +++ b/skills/hermes-integration/SKILL.md @@ -1,22 +1,23 @@ --- name: hermes-integration -description: Integrates XActions with Hermes Agent for AI-powered Twitter/X content generation and posting. Hermes generates deslopped security content, sends it to the user for approval, then posts via XActions browser automation. Use when the user wants to generate Twitter content through Hermes, post security threads, or manage the content pipeline from Hermes to X/Twitter. +description: Integrates XActions with Hermes Agent for AI-powered Twitter/X content generation. Hermes generates deslopped security content and sends it to the user for manual posting. No automation of posting — the user posts themselves. Use when the user wants to generate Twitter content through Hermes or manage the content pipeline from Hermes to X/Twitter. license: MIT metadata: author: fisher - version: "1.0" + version: "1.1" --- # Hermes Integration -Bridge between Hermes Agent and XActions for Twitter/X content generation and posting. +Bridge between Hermes Agent and XActions for Twitter/X content generation. ## How It Works 1. **Hermes generates content** — security threads, vulnerability breakdowns, exploit analysis 2. **Deslop pass** — all output is run through deslop (no em dashes, AI vocabulary, hedging) -3. **User approval** — Hermes sends the content to the user. Nothing posts without explicit approval. -4. **XActions posts** — approved content is posted via XActions browser automation +3. **User posts manually** — Hermes sends the content to the user. The user copies and posts it themselves. + +That's it. No X API keys, no session cookies, no browser automation. Just content generation. ## Content Pipeline @@ -27,7 +28,6 @@ Hermes picks a topic from the security content pool (`~/.hermes/scripts/security Content types: - **Single tweet** — one vulnerability insight, under 280 chars - **Thread** — 3-8 tweets breaking down an exploit, with hook + value + CTA -- **Reply/comment** — response to trending security话题 ### Step 2: Deslop @@ -39,92 +39,33 @@ All content passes through the deslop pipeline before being shown to the user: - Opinions allowed - Rough edges preserved -### Step 3: User Approval - -Hermes sends the content to the user via Telegram. The user can: -- **Approve** — Hermes posts it via XActions -- **Edit** — user provides changes, Hermes applies and re-sends -- **Reject** — content is discarded, Hermes generates something else -- **Save for later** — content is stored in `~/.hermes/cron/output/` for manual posting - -### Step 4: Post via XActions - -Once approved, Hermes uses XActions to post: - -**For threads:** -1. Open `x.com` in browser -2. Navigate to post composer -3. Use `src/postThread.js` — paste into DevTools console -4. Set `dryRun: false` and populate the `THREAD` array -5. Execute and verify - -**For single tweets:** -1. Open `x.com` in browser -2. Use `src/postComposer.js` or navigate to compose -3. Type the approved content -4. Post and verify - -## Hermes MCP Configuration +### Step 3: User Posts -To use XActions MCP server with Hermes: +Hermes sends the content to the user via Telegram. The user: +- Copies the content +- Pastes it into X/Twitter +- Posts it manually -```json -{ - "mcpServers": { - "xactions": { - "command": "npx", - "args": ["-y", "xactions-mcp"], - "env": { - "XACTIONS_SESSION_COOKIE": "FROM_ENV_FILE" - } - } - } -} -``` - -**Important:** Never hardcode the session cookie. Always reference an environment variable or `.env` file that is in `.gitignore`. - -## Environment Setup - -Required in `.env` (never commit this file): - -```bash -# XActions -XACTIONS_SESSION_COOKIE=your_auth_token_here -XACTIONS_MODE=local - -# Optional: for AI-generated content via XActions -OPENROUTER_API_KEY=your_key_here -``` +No automation. No API keys needed. The user stays in full control. ## Content Storage - Generated content: `~/.hermes/cron/output/security-thread_*.txt` -- Sent threads log: `~/.hermes/scripts/sent-threads.json` -- Drafts for approval: `~/.hermes/cron/output/drafts/` +- Sent threads log: `~/.hermes/scripts/sent-threads.json` (prevents duplicates) ## Workflow Files | File | Purpose | |------|---------| | `skills/hermes-integration/SKILL.md` | This file — integration guide | -| `skills/content-posting/SKILL.md` | Posting scripts and selectors | +| `skills/content-posting/SKILL.md` | Posting scripts and selectors (for reference) | | `skills/viral-thread-generation/SKILL.md` | Thread structure and hooks | | `skills/engagement-interaction/SKILL.md` | Like, reply, bookmark automation | | `skills/algorithm-cultivation/SKILL.md` | Feed training and growth | -## Rate Limits - -Respect X/Twitter rate limits: -- 1-3 seconds between actions -- Max 300 actions per hour for engagement -- Thread posting: at least 2 seconds between tweets -- If rate limited, wait 15 minutes before retrying - ## Safety Rules -1. **Never auto-post without user approval** -2. **Never commit `.env` files or session cookies** +1. **Never auto-post.** The user posts all content manually. +2. **Never commit `.env` files or session cookies** (for when automation is added later) 3. **Always deslop content before showing the user** 4. **Log all sent content to prevent duplicates** -5. **Use dryRun: true when testing scripts**