hum
Content writing and feed intelligence skill for LinkedIn and X.
Open source Open in the app JSON README (API)
About
Content writing and feed intelligence skill for LinkedIn and X.
Details
- Kind
- Plugins
- Topic
- Social & content
- Publisher
- hum-growth
- Origin
- gemini
- Category
- ferramentas
- Version
- 1.0.0
- Stars
- 4
- Last push
- 2026-05-12T12:43:55Z
- Repository state
- ativo
- Language
- Python
- License
- MIT
- Added
- 2026-08-30 14:13:39
- Updated
- 2026-08-30 14:13:39
- Origin id
hum-growth/hum
README
# Hum
AI agent skill for content writing on X and LinkedIn.
**Your AI content writer**. Hum handles the full content lifecycle: it crawls your feed sources daily and sends a ranked digest, brainstorms ideas grounded in real research across YouTube, X, Reddit, HN, and the web, then drafts posts in your voice using proven writing styles — from technical storytelling to contrarian takes. Every draft goes through a research-outline-approval loop before writing begins. Once approved, Hum publishes directly to X and LinkedIn via API connectors, and can also manage engagement by drafting replies to comments and suggesting accounts to follow.
## Installation
### Claude Code
```bash
claude /install https://github.com/hum-growth/hum
```
Or clone and add to your skills directory:
```bash
git clone https://github.com/hum-growth/hum ~/.claude/skills/hum
```
### OpenClaw / ClawHub
```bash
claw install hum-writer
```
### Codex
Copy `agents/openai.yaml` to your agents directory:
```bash
cp agents/openai.yaml ~/.codex/agents/hum.yaml
```
### Gemini CLI
```bash
gemini extensions install https://github.com/hum-growth/hum
```
## Setup
### 0. Install Python dependencies
Run `bash setup.sh` from the repo root to create a venv at `venv/` and install everything from `requirements.txt`. Activate it with `source venv/bin/activate` before running any `python3 scripts/...` command, or substitute your own Python path if you manage dependencies differently. All examples below assume `python3` resolves to the venv and the cwd is the skill folder.
### 1. Configure data directory
Set the data directory via `openclaw.json` or environment variable (defaults to `~/Documents/hum` if neither is set):
**Option A — openclaw.json** (recommended for OpenClaw users):
```json
{
"skills": {
"entries": {
"hum": {
"config": {
"hum_data_dir": "~/Documents/hum"
}
}
}
}
}
```
**Option B — environment variable:**
```bash
export HUM_DATA_DIR=~/Documents/hum
```
### 2. Configure delivery targets
Set where each loop step is delivered. Supports any channel target recognised by your agent runtime (Telegram chat ID, WhatsApp number, etc.). You can route each step to a different destination — e.g. the digest to a shared group channel and brainstorm/engage to your personal DM.
**Option A — openclaw.json** (recommended):
```json
{
"skills": {
"entries": {
"hum": {
"config": {
"hum_digest_target": "telegram:-100YOUR_GROUP_ID",
"hum_brainstorm_target": "telegram:ghost:YOUR_PERSONAL_ID",
"hum_engage_target": "telegram:ghost:YOUR_PERSONAL_ID"
}
}
}
}
}
```
**Option B — environment variables:**
```bash
export HUM_DIGEST_TARGET=telegram:-100YOUR_GROUP_ID
export HUM_BRAINSTORM_TARGET=telegram:ghost:YOUR_PERSONAL_ID
export HUM_ENGAGE_TARGET=telegram:ghost:YOUR_PERSONAL_ID
```
**Target format:** `channel:recipient` or `channel:account:recipient`. The optional `account` selects which bot account sends the message (e.g. `ghost`). When omitted the default account is used.
Any target that is not set is skipped silently — the loop step still runs, output is just not delivered.
### 3. Setup workspace and content profile
Run `/hum init` to create all required directories and template files. Then edit the generated files in your data directory to set up your voice, audience, channels, content pillars, and knowledge sources (`knowledge/index.md`).
## Commands
| Command | Description |
|---------|-------------|
| `/hum init` | Set up data directory with templates and folders |
| `/hum loop` | Run the full daily morning workflow |
| `/hum refresh-feed` | Crawl all sources (X, HN, YouTube, knowledge), rank, send digest |
| `/hum crawl` | Crawl knowledge sources (blogs, YouTube transcripts, podcasts) |
| `/hum sources` | List, add, or remove social feed sources |
| `/hum config` | Show current data_dir configuration |
| `/hum brainstorm` | Research topics and generate content ideas |
| `/hum learn` | Make improvements to content strategy |
| `/hum ideas` | Show idea pipeline |
| `/hum content` | List current drafts |
| `/hum create` | Draft a post (platform, type, idea) |
| `/hum publish` | Publish an approved draft |
| `/hum engage` | Follow accounts, suggest replies, draft responses |
| `/hum samples` | Collect writing samples from social media |
| `/hum feedback` | Upvote/downvote digest items to train the ranker |
## Daily Loop
Runs at 6am SGT via `scripts/loop.py`. Sundays include an extra strategy refresh step.
```
6:00 am ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
┌─────────────────────┐
│ 1. Digest │──── Fetch feed ---─────-┐
│ /hum refresh-feed│──── Rank feed posts ───┐│
└─────────┬───────────┘ ││
│ ││
▼ ▼▼
┌─────────────────────┐ ┌────────────────────┐
│ Send Telegram │ │ feeds.json │
│ morning digest │ │ (aggregated feed) │
└─────────────────────┘ └────────────────────┘
│
▼
┌─────────────────────┐ ┌────────────────────┐
│ 2. Engage │ │ VOICE.md │
│ /hum engage │◄─────────────│ CHANNELS.md │
└─────────┬───────────┘ └────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Draft replies + follow suggestions │
│ (presented for user approval) │
└─────────────────────────────────────┘
┌─────────────────────┐ ┌────────────────────┐
│ 3. Brainstorm │ │ CONTENT.md │
│ /hum brainstorm │◄─────────────│ (content pillars) │
| ideas.json | │ feeds.json │
└─────────┬───────────┘ └────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Top feed items + idea suggestions │
│ → "Any ideas to add?" │
│ → "Want to work on posts today?" │
└─────────────────────────────────────┘
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┐
| 4. Learn | ┌────────────────────┐
│ /hum learn │◄─────────────│ feeds.json │
| (Sundays only) │──web search──│ CHANNELS.md │
└ ─ ─ ─ ─ ┬ ─ ─ ─ ─ ─┘ └────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Analyze feed trends │
│ Research platform algorithms │
│ Update context files │
└─────────────────────────────────────┘
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
User wakes up → reviews digest, approves/edits suggestions
```
Run individual steps with `python3 scripts/loop.py --step digest|engage|brainstorm|learn`.
### Scheduling the Daily Loop
The daily loop needs a cron job or scheduler to run automatically. Setup varies by platform.
#### OpenClaw
OpenClaw has built-in scheduling. Add a `cron` entry to your `openclaw.json`:
```json
{
"skills": {
"entries": {
"hum": {
"cron": "0 6 * * *",
"config": {
"hum_data_dir": "~/Documents/hum"
}
}
}
}
}
```
This runs `/hum refresh-feed` → engage → brainstorm at 6am daily. OpenClaw handles process management, retries, and logging.
#### Claude Code
Claude Code does not have built-in scheduling. Use a system crontab to invoke the CLI in non-interactive mode:
```bash
# Edit your crontab
crontab -e
# Add this line (runs at 6am daily)
0 6 * * * cd /path/to/hum && claude -p "Run the daily hum loop: python3 scripts/loop.py" --allowedTools "Bash(command)" 2>&1 >> ~/.hum/loop.log
```
Alternatively, use the `/loop` skill if available in your Claude Code session:
```
/loop 24h /hum refresh-feed
```
> **Note:** The crontab approach requires Claude Code CLI (`claude`) to be installed and authenticated. All core feed sources (X via Bird, HN, YouTube, knowledge) run headless — no browser needed.
#### Codex
Use a system crontab to invoke the Codex CLI:
```bash
0 6 * * * cd /path/to/hum && codex -q "Run the daily hum loop: python3 scripts/loop.py" 2>&1 >> ~/.hum/loop.log
```
#### Gemini CLI
Use a system crontab to invoke the Gemini CLI:
```bash
0 6 * * * cd /path/to/hum && gemini -p "Run the daily hum loop: python3 scripts/loop.py" 2>&1 >> ~/.hum/loop.log
```
#### All platforms — manual run
You can always run the loop manually inside any agent session:
```
/hum refresh-feed
```
Or run the Python script directly:
```bash
python3 scripts/loop.py
```
## Feed
Most feed sources use direct APIs — no browser automation required. X credentials are session cookies extracted once from browser devtools.
| Source | Method | Credentials | Cost |
|--------|--------|-------------|------|
| **X home feed** | Bird API (`filter:follows`) | `AUTH_TOKEN` + `CT0` cookies | Free |
| **X profiles** | Bird API (`from:handle`) | `AUTH_TOKEN` + `CT0` cookies | Free |
| **Hacker News** | Algolia public API | None | Free |
| **YouTube** (digest) | yt-dlp (local tool) | None | Free |
| **Knowledge sources** | RSS, sitemaps, YouTube transcripts, podcasts | None | Free |
X credentials go in `~/.hum/credentials/x.json` or via `HUM_X_AUTH_TOKEN` / `HUM_X_CT0` env vars. If missing, X sources are skipped and the rest of the pipeline still runs.
Two source lists serve different purposes:
- `feed/sources.json` — Social/ephemeral sources (X feed, X profiles, HN, YouTube channels). Managed via `/hum sources`.
- `knowledge/index.md` — Long-form knowledge sources (RSS blogs, sitemaps, YouTube transcripts, podcasts). Full articles saved to `knowledge/<source_key>/`.
## Image Generation
Hum can auto-generate post images using AI. Configure a provider and Hum will generate images during the `/hum create` workflow when an `image_prompt` is set.
Set the active provider via the `HUM_IMAGE_MODEL` environment variable or `image_model` config key. Valid values: `gemini` (default), `openai`, `grok`, `minimax`.
### Providers
| Provider | Model | Env Var | Cost |
|----------|-------|---------|------|
| **gemini** (default) | gemini-2.5-flash-image | `GEMINI_API_KEY` | Free tier available |
| **openai** | gpt-image-1 | `OPENAI_API_KEY` | PAYG |
| **grok** | grok-2-image | `XAI_API_KEY` | Free with xAI tier |
| **minimax** | image-01 | `MINIMAX_API_KEY` | PAYG |
### Configuration
Set API keys as environment variables or in `openclaw.json` → `env.vars`:
```json
{
"env": {
"vars": {
"GEMINI_API_KEY": "your_key_here"
}
}
}
```
Choose the active provider in `openclaw.json` → `skills.entries.hum.config.hum_image_model`:
```json
{
"skills": {
"entries": {
"hum": {
"config": {
"hum_image_model": "gemini"
}
}
}
}
}
```
Or override with the `HUM_IMAGE_MODEL` environment variable.
### Visual Style
Add a `## Visual Style` section to your `VOICE.md` file to define your brand's visual identity. Hum appends this to every image generation prompt automatically.
### Test
```bash
python3 scripts/lib/image-gen/generate.py \
--prompt "a clean professional image for a finance tech tweet" \
--platform twitter --output /tmp/test.png
```
## Dashboard
Browse all your hum data in a local web UI — feed, knowledge articles, ideas, content drafts, loop runs, and learnings.
```bash
python3 scripts/dashboard/serve.py # http://localhost:8400
python3 scripts/dashboard/serve.py --open # auto-open browser
python3 scripts/dashboard/serve.py --port 9000 # custom port
```
The server indexes your knowledge articles at startup (cached to `knowledge/_index.json`). Use `--rebuild-index` to force a fresh scan.
## Local Development
To develop Hum locally, symlink your OpenClaw workspace to this repo:
```bash
ln -sfn ~/Code/hum ~/.openclaw/workspace/skills/hum
```
This makes both paths point to the same files. Edits you make in `~/.openclaw/workspace/skills/hum` (e.g. via OpenClaw) are immediately reflected in `~/Code/hum`, and vice versa. There's no sync step — `git status` shows your changes right away.
To ship your changes, use the `/ship` command in Claude Code, which commits, pushes, and opens a PR following conventional commit conventions. See `.claude/commands/ship.md` for details.
Once pushed, anyone can install the updated skill via `claude /install`, `claw install hum-writer`, etc.