reply-maker
Draft copy-paste-ready X replies - two options per reply-worthy tweet from tracked accounts, topics, or lists (default), or ready-to-post responses to…
Skill by aeonfun
Chalk Labs
Need help deploying reply-maker?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/aeonfun-reply-maker
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/reply-maker
What's inside
- Skill name
reply-maker- Description
- Draft copy-paste-ready X replies - two options per reply-worthy tweet from tracked accounts, topics, or lists (default), or ready-to-post responses to engagement opps in recent logs (from-logs)
- License
- MIT
- Metadata
- var: empty = auto-discover reply-worthy tweets and draft two options each; @handle / numeric X list ID / topic = scope the drafting to that; from-logs (or --from-logs [@handle|project]) = turn flagged engagement opps from recent logs into ready-to-post replies · title: Reply Maker · commits: false · category: productivity
- Instructions
- 360 lines in SKILL.md · view on GitHub
Before installing
- Instructions call the network
Agent Skills spec issues
- files: referenced but missing: scripts/telegram-route.sh
Files (1)
- SKILL.md
SKILL.md (first lines)
<!-- autoresearch: variation B — sharper output via specificity gates, anti-sycophancy lint, post-write self-edit, and skip-gate for low-leverage tweets -->
> **${var}** — selects the mode and scope:
> - **empty** → **Mode A (Reply Drafting):** auto-discover reply-worthy tweets across your areas of interest (from recent logs + memory) and draft two reply options for each.
> - **`@handle` / numeric X list ID / topic** → **Mode A (Reply Drafting)** scoped to that handle, list, or topic.
> - **`from-logs`** (or **`--from-logs`**, optionally followed by an `@handle` or project name to narrow the scan) → **Mode B (From-Logs Engagement):** scan recent logs for flagged engagement opportunities and turn them into copy-paste-ready responses.
> - **`revise:<instruction>`** → **Revise branch:** reload the last drafted replies and refine them per the instruction (the Telegram force-reply shape, e.g. `revise:make them shorter`).
## Preamble (both modes)
Read `memory/MEMORY.md` for context on active projects and open engagement follow-ups.
Then read `memory/logs/` — the window depends on the mode:
- **Mode A:** the last 2 days of `memory/logs/` for recent `fetch-tweets`, `narrative-tracker`, and prior `reply-maker` outputs (used as a candidate pool and for reply de-duplication).
- **Mode B:** the last 7 days of `memory/logs/` for engagement opportunities flagged by other skills (`mention-radar`, `fetch-tweets`, `reply-maker`) or noted in MEMORY.md "Known Follow-ups".
**Parse `${var}` to pick the branch** (trim whitespace, compare case-insensitively):
- If `${var}` starts with `revise:` — run the **Revise branch** (below) and stop. This is the shape `scripts/telegram-route.sh` sends when the operator replies to a "refine these replies?" force-reply prompt; catch it before mode parsing.
- If `${var}` is `from-logs` or `--from-logs` — optionally followed by a whitespace-separated `@handle` or project name — run **Mode B (From-Logs Engagement)**. Treat any trailing token as an optional filter that narrows the opportunity scan to that handle/project.
- Otherwise run **Mode A (Reply Drafting)**, treating `${var}` as the scope: empty, `@handle`, numeric X list ID, or a topic string.
## Voice
If soul files exist (`soul/SOUL.md`, `soul/STYLE.md`, `soul/examples/`), read them and **mirror that voice in every reply**. Match sentence length, vocabulary choices, punctuation habits, and the kinds of things the operator would never say.
If no soul files exist (or the bodies are empty placeholders), write replies that are:
- Direct and substantive — no fluff, no sycophancy
- Under 280 characters each (X replies; DMs and GitHub comments may run longer — see Mode B)
- Opinionated but grounded in specifics
- The kind of reply that adds to the conversation, not noise
Either way, when responding to someone who cosigned/mentioned/attributed the operator (Mode B): **acknowledge without groveling** — no "thanks so much for the kind words!", just the actual response.
---
# Revise branch (`revise:…` — Telegram force-reply)
The operator tapped the "refine these replies?" prompt and sent a free-text revision instruction. Handle it before Mode A/B:
1. **Strip the prefix.** The instruction is `${var#revise:}` (keep any inner colons). Trim whitespace — e.g. `make them shorter`, `less formal`, `drop reply B on #2`.
2. **Load the last draft.** Read `memory/drafts/reply-maker-latest.md` — the stable path every normal run saves to (see the save steps in A4 / B6). If it's missing or empty, there's nothing to refine: send `./notify "Nothing to revise yet — run reply-maker first, then reply here to refine the drafts."` and **end the run**.
3. **Apply the instruction.** Read `soul/` for voice, then regenerate the saved replies applying the operator's instruction. Keep the same set of target tweets and the same **A/B two-option** structure (Mode A) or ready-to-post list (Mode B) — you're refining wording, not re-discovering candidates. Re-enforce the hard reply rules: ≤280 chars for X replies, no sycophancy (see **Banned sycophancy phrases**), specifics not gestures.
4. **Re-save** the revised drafts to `memory/drafts/reply-maker-latest.md` (overwrite), so a further `revise:` refines the newest version.
5. **Re-send** via `./notify` in the same format the originating mode uses, with a first line flagging it as a revision, e.g. `revised (${var#revise:}):`. Use `./notify -f <file>` for multi-line output.
6. **Re-offer** a further revision (the operator is actively iterating, so this is expected, not a nag — skip the daily dedup guard here):
```bash
./notify "Want another pass? Reply with a change and I'll revise again." \
--force-reply --placeholder "e.g. make them shorter" \
--context "reply-maker::revise"
```
7. **Log** under `### reply-maker` with `- **Mode:** revise` and the instruction (see **Log**), then **end the run** — do NOT run Mode A or B.
---
# Mode A — Reply Drafting
Generate **two reply options** for **5 reply-worthy tweets** from tracked X accounts, a list, or a topic.
### A1. Gather candidate tweets
Goal: assemble **10–15 candidates** posted in the **last 6 hours** (the high-leverage reply window — the algorithm rewards early replies, and the OP is still likely to engage back). **Recency fallback:** if the 6h window yields fewer than 3 candidates after the skip gate, widen to **12h** and retry before failing the run.
For every candidate, capture: `@handle`, full tweet text, tweet URL, `posted_at` (ISO), engagement counts (likes, replies, retweets if available), and a one-line **why-this-tweet** note.
**Path A - twitterapi.io (primary, except `list:`).** `TWITTER_API_KEY` is injected into this skill's environment (declared in `requires:`). Handle and topic scopes use structured twitterapi.io fetches (full contract in **Fetching**). twitterapi.io has **no `list:` operator**, so a numeric list ID stays on Path B (xAI) as its primary. Preflight the keys: read the "Keys set for this run" line in your run notes, never a shell test (those are refused and cost a turn). `TWITTER_API_KEY` on that line = `TW_PRESENT`, else `TW_UNSET`; `XAI_API_KEY` on it = `XAI_PRESENT`, else `XAI_UNSET`.
**Shell shape.** Each Bash call is one allowed command (pipes are fine). The run refuses a call that sets a variable (`FROM_DATE=$(date ...)`, `HTTP=$(./secretcurl ...)`, `HANDLE="${var#@}"`), uses `if` / `for` / `while`, or joins commands with `;`, `&&` or `||`, and each refusal costs a model turn. So get each date with a bare `date` call and write the printed value into later commands; write the handle, topic, list ID and dates into each command literally (the `<FROM_DAY>`, `<HANDLE>` style placeholders in the snippets), jq filters included (`>= "<FROM_DAY>"`, never `--arg` with a `$name`: refused); run one `jq` per call. A `>` redirect into a file is refused too, so the xAI body is piped straight into `./secretcurl ... --data-binary @-` and notify bodies are written with the Write tool.
Get the window dates, each `date` as its own Bash call:
```bash
date -u +%Y-%m-%dT%H:%M:%SZ
```
```bash
date -u -d '6 hours ago' +%Y-%m-%dT%H:%M:%SZ
```
```bash
date -u -d '6 hours ago' +%Y-%m-%d
```
The first prints TO_DATE, the second FROM_DATE, the third FROM_DAY.
**If `${var}` looks like a `@handle`** - pull that account's recent timeline, then filter to the 6h window client-side (`/user/last_tweets` has no server-side date filter). `createdAt` is Twitter-native; normalize with `strptime` before the compare. `<HANDLE>` is `${var}` without the leading `@`, written in literally:
```bash
./secretcurl -s -o /tmp/tw-rm.json -w 'twitterapi http=%{http_code} bytes=%{size_download}\n' --max-time 60 -G "https://api.twitterapi.io/twitter/user/last_tweets" \
--data-urlencode "userName=<HANDLE>" -H "X-API-Key: {TWITTER_API_KEY}"
```
On `HTTP=200` with a non-empty `.data.tweets[]`, parse, drop replies/RTs (`.isReply`, or text starting `RT @`), keep originals inside the window, and mark `twitterapi=ok`. FROM_DAY is written in literally:
```bash
jq -r '.data.tweets[] | select((.isReply | not) and ((try (.createdAt | strptime("%a %b %d %H:%M:%S %z %Y") | strftime("%Y-%m-%d")) catch "0000-00-00") >= "<FROM_DAY>")) | [.id, .author.userName, .text, .url, .createdAt, .likeCount, .retweetCount, .replyCount] | @tsv' /tmp/tw-rm.json
```
**If `${var}` is a topic** (or empty) - `advanced_search` with the topic (or the top 2-3 topics from `memory/MEMORY.md` when empty) and `since:<FROM_DAY>` inside the query, both written in literally. When empty, also pull tweet candidates surfaced in the last 2 days of `fetch-tweets` logs as a backup pool:
```bash
./secretcurl -s -o /tmp/tw-rm.json -w 'twitterapi http=%{http_code} bytes=%{size_download}\n' --max-time 60 -G "https://api.twitterapi.io/twitter/tweet/advanced_search" \
--data-urlencode "query=<TOPIC> since:<FROM_DAY>" --data-urlencode "queryType=Latest" \
-H "X-API-Key: {TWITTER_API_KEY}"
```
On `HTTP=200` with a non-empty `.tweets[]`, parse originals (skip replies) and mark `twitterapi=ok`:
```bash
jq -r '.tweets[] | [.id, .author.userName, .text, .url, .createdAt, .likeCount, .retweetCount, .replyCount] | @tsv' /tmp/tw-rm.json
```
Then keep only posts inside the 6h window (strptime-normalize `.createdAt`).
**If `${var}` looks like an X list ID** (numeric): skip Path A (no twitterapi `list:` operator) and go to Path B.
**Path B - xAI Grok `x_search` (fallback; primary for `list:`).** Only if Path A returned non-2xx / empty / timeout, `TWITTER_API_KEY` is unset, or `${var}` is a numeric list ID. Direct `curl` to `https://api.x.ai/v1/responses`. `x_search` searches X live and takes 30-120s - **set the Bash tool `timeout` to ≥180000 when you run this** (a slow curl is not a missing key). Build the payload per `${var}` (three shapes below) with `jq -n` and pipe it straight into the `./secretcurl` send, one call. It prints the HTTP status (secretcurl also prints an `http=... bytes=...` line on stderr).
On `HTTP=200` with a non-empty body, parse `/tmp/xai-rm.json` and mark `xai=ok`:
```bash
jq -r '.output[] | select(.type == "message") | .content[] | select(.type == "output_text") | .text' /tmp/xai-rm.json
```
**The payload depends on `${var}`.** Whichever branch matches, build it with `jq -n` (never a shell-interpolated string) and pipe it into `./secretcurl ... --data-binary @-` in the same call. Do not write it to a file first or pass values with `--arg`: a `>` redirect into a file and a jq `$name` variable are both refused in this run.
In each shape the list ID, handle or topic and both dates are written into the jq filter literally (`<LIST_ID>`, `<HANDLE>`, `<TOPIC>`, `<FROM_DATE>`, `<TO_DATE>`); a `"` inside a value becomes `\"`, and reword any `'`.
**If `${var}` looks like an X list ID** (numeric):
```bash
jq -n '{
model: "grok-4.7",
input: [{role: "user", content: "Look at X list https://x.com/i/lists/<LIST_ID>. Return the 12 most reply-worthy original posts (not retweets, not replies) by members of this list between <FROM_DATE> and <TO_DATE>. Reply-worthy = has a take, claim, question, or framing worth engaging — NOT pure self-promo, breaking news without analysis, or threads already past 500 replies. For each: @handle, full tweet text, tweet URL, posted_at ISO timestamp, like/reply/retweet counts."}],From aeonfun/aeon, MIT.
More from aeonfun/aeon
- 0.722score
anatomy
aeonfun
Build crafted, highly detailed, interactive isometric SVG figures that explain a technical idea as a real physical object (a test rig, a dial gauge, a cabinet…
SkillAFreshness: A★ 782Claude Code +9 - 0.719score
base-mcp
aeonfun
Access a Base Account via the Base MCP server (mcp.base.org) - wallet, portfolio, sending, swapping, signing, x402 payments, batched calls, and transaction…
SkillAFreshness: A★ 782Claude Code +9 - 0.718score
aeon
aeonfun
Set up and run an Aeon agent instance - get started from scratch, pick which skills to turn on or install more from packs, reschedule or change what runs…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
hunter-22
aeonfun
Scan the ClawHunter agent bounty marketplace for opportunities that genuinely match this agent's real capabilities (code, security research, writing) and…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
get-started
aeonfun
First-run setup for the Aeon plugin.
SkillAFreshness: A★ 782Claude Code +9 - 0.715score
seo-audit
aeonfun
Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
fetch-tweets
aeonfun
Search and curate X/Twitter behind one selector - keyword, topic roundup, a single or tracked-account digest, an X list, or the AI-agent buzz preset -…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
github-trending
aeonfun
Curated trending across GitHub repos and the Hugging Face Hub (models, datasets, spaces) - filtered, clustered, and labeled by momentum with a one-line…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
bd-radar
aeonfun
Business-development radar across your product family - find who's building, forking, integrating, and mentioning your products, ranked into a…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
digest
aeonfun
Generate and send a digest on a configurable topic, optionally pulling RSS/Atom feeds as an input source alongside web + X signal
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
feedback-builder
aeonfun
Point Aeon at a service's /feedback endpoint - pull what agents reported (bugs, missing features), triage and cluster it, then build the best accepted request…
SkillAFreshness: A★ 782Claude Code +9 - 0.714score
heartbeat
aeonfun
Ambient fleet-health check that surfaces anything worth attention (default), or an on-demand priority brief - the 3 things to focus on, why now, and what…
SkillAFreshness: A★ 782Claude Code +9
Signals
- Stars
- 782
- Forks
- 292
- Open issues
- 0
- Last commit (this folder)
- Oct 1, 2026 (1 month ago)
- Last release
- Jul 9, 2026 (3 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/aeonfun/aeon
- Website
- www.aeon.fun/
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from aeonfun
- 0.722score
anatomy
aeonfun
Build crafted, highly detailed, interactive isometric SVG figures that explain a technical idea as a real physical object (a test rig, a dial gauge, a cabinet…
SkillAFreshness: A★ 782Claude Code +9 - 0.719score
base-mcp
aeonfun
Access a Base Account via the Base MCP server (mcp.base.org) - wallet, portfolio, sending, swapping, signing, x402 payments, batched calls, and transaction…
SkillAFreshness: A★ 782Claude Code +9 - 0.718score
aeon
aeonfun
Set up and run an Aeon agent instance - get started from scratch, pick which skills to turn on or install more from packs, reschedule or change what runs…
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
get-started
aeonfun
First-run setup for the Aeon plugin.
SkillAFreshness: A★ 782Claude Code +9 - 0.717score
hunter-22
aeonfun
Scan the ClawHunter agent bounty marketplace for opportunities that genuinely match this agent's real capabilities (code, security research, writing) and…
SkillAFreshness: A★ 782Claude Code +9 - 0.715score
seo-audit
aeonfun
Daily on-page and technical SEO audit of every page on a site - discovers URLs from the sitemap, scores each page, adds cross-page checks (duplicate titles…
SkillAFreshness: A★ 782Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get reply-maker running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
reply-maker skill. Agent Mart. https://agentmart.dev/skills/aeonfun-reply-maker (last updated 2026-10-24)