social-autoposter 1.6.41 → 1.6.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/setup/SKILL.md +48 -226
package/package.json
CHANGED
package/setup/SKILL.md
CHANGED
|
@@ -1,271 +1,93 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: social-autoposter-setup
|
|
3
|
-
description: "Set up social-autoposter for a new user.
|
|
3
|
+
description: "Set up social-autoposter for a new user. Configures the product (website, ICP, voice, search topics), seeds search topics into the backend, connects X/Twitter (auto-detecting the real handle), and verifies with a draft cycle. Use when: 'set up social autoposter', 'install social autoposter', 'configure social posting'."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Social Autoposter Setup
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Set up social-autoposter for a new user. Walk them through it conversationally — don't dump a form.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Architecture (read this first)
|
|
11
11
|
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
12
|
+
- **Config**: `~/social-autoposter/config.json` — `projects[]` (what to post about) and `accounts` (where to post).
|
|
13
|
+
- **Data + stats**: a backend HTTP API (`https://s4l.ai`), scoped by a **stable per-install identity** auto-created in `identity.json`. There is **NO local Postgres and no `DATABASE_URL`** to configure — that was the old architecture; ignore any reference to psycopg2 / `SELECT ... FROM posts`.
|
|
14
|
+
- **Search topics**: the X cycle's search queries live in the DB table `project_search_topics`, **seeded from each project's `search_topics`** at setup. A project with no seeded topics has nothing to scan and the draft cycle returns empty — so topics are required.
|
|
15
15
|
|
|
16
|
-
##
|
|
16
|
+
## Which path to use
|
|
17
17
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
- A browser automation tool (Playwright MCP, Selenium, etc.) for platform login verification
|
|
18
|
+
- **If the social-autoposter MCP is connected** (you can see the tools `setup`, `draft_cycle`, `autopilot`, `get_stats`): use the MCP tools. They write config, **seed topics into the DB**, and **auto-detect the X handle** for you. Do NOT hand-edit `config.json`. This is the primary path — follow "MCP path" below.
|
|
19
|
+
- **If only the CLI/skill is installed** (no MCP tools): use the "CLI fallback" at the end.
|
|
21
20
|
|
|
22
21
|
---
|
|
23
22
|
|
|
24
|
-
##
|
|
23
|
+
## MCP path (primary)
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
### Step 1: Interview the user, one question at a time
|
|
27
26
|
|
|
28
|
-
|
|
27
|
+
Gather the fields the `setup` tool needs. Ask conversationally, wait for each answer.
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
1. **Website** — "What's the product's website?"
|
|
30
|
+
2. **Description** — "In 1-3 sentences, what does it do?"
|
|
31
|
+
3. **ICP** — "Who's the ideal customer you want to engage on X?"
|
|
32
|
+
4. **Voice** — "What tone should replies have? Any words/claims to avoid?"
|
|
33
|
+
5. **Differentiator** (recommended) — "What makes it different from the alternatives?"
|
|
34
|
+
6. **Search topics** (required) — "What phrases or keywords do your buyers actually tweet about? Give me 5-15, comma-separated." These become the literal X searches the cycle runs. **Without them there is nothing to scan**, so don't skip this.
|
|
35
|
+
7. **Get-started link** (recommended) — "Primary call-to-action link (signup / get started)?"
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
ls ~/social-autoposter/schema-postgres.sql 2>/dev/null && echo "FOUND" || echo "NOT_FOUND"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
If NOT_FOUND, install:
|
|
37
|
-
```bash
|
|
38
|
-
npx social-autoposter init
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
This copies all scripts, skill files, and config templates to `~/social-autoposter/`. It also:
|
|
42
|
-
- Creates `config.json` from `config.example.json` (if missing)
|
|
43
|
-
- Creates `.env` from `.env.example` (if missing) — includes pre-filled `DATABASE_URL`
|
|
44
|
-
- Installs `psycopg2-binary` (Python driver for Postgres)
|
|
45
|
-
- Symlinks `~/.claude/skills/social-autoposter` → `~/social-autoposter/skill`
|
|
46
|
-
|
|
47
|
-
To update scripts later without touching config/data:
|
|
48
|
-
```bash
|
|
49
|
-
npx social-autoposter update
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Set `SKILL_DIR=~/social-autoposter` for the rest of this wizard.
|
|
37
|
+
For the voice/angle, it helps to draft a short first-person `voice`/`differentiator` from their answers and confirm it reads like them before saving. Aim for specific (names tools, numbers, real experience), not generic.
|
|
53
38
|
|
|
54
|
-
### Step 2:
|
|
39
|
+
### Step 2: Create the project with `setup`
|
|
55
40
|
|
|
56
|
-
|
|
41
|
+
Call the `setup` tool with a short slug `name` plus the fields above. Pass `search_topics` as a comma-separated string or array. You can fill fields incrementally across calls — it merges and reports what's still missing. A project is **ready** only once it has name, website, description, icp, voice, **and search_topics**.
|
|
57
42
|
|
|
58
|
-
|
|
59
|
-
source "$SKILL_DIR/.env"
|
|
60
|
-
python3 -c "
|
|
61
|
-
import psycopg2, os
|
|
62
|
-
conn = psycopg2.connect(os.environ['DATABASE_URL'])
|
|
63
|
-
cur = conn.cursor()
|
|
64
|
-
cur.execute(\"SELECT COUNT(*) FROM posts\")
|
|
65
|
-
print('Connected. Posts in DB:', cur.fetchone()[0])
|
|
66
|
-
conn.close()
|
|
67
|
-
"
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Expected: `Connected. Posts in DB: <number>` (any number is fine, including 0).
|
|
71
|
-
|
|
72
|
-
If psycopg2 is missing: `pip3 install psycopg2-binary`
|
|
73
|
-
|
|
74
|
-
If the connection fails, check that `DATABASE_URL` is set in `$SKILL_DIR/.env`.
|
|
43
|
+
When the project becomes ready, `setup` **automatically seeds its `search_topics` into the DB** (`project_search_topics`) and tells you how many it seeded. You do not run any seed script by hand.
|
|
75
44
|
|
|
76
|
-
### Step 3:
|
|
45
|
+
### Step 3: Connect X/Twitter
|
|
77
46
|
|
|
78
|
-
`
|
|
47
|
+
Call `setup` with `action:'connect_x'` (no `confirm`) first — it returns an explanation of what will happen (it imports your x.com/twitter.com cookies into the autoposter's managed Chrome). Relay that to the user, get their OK, then call again with `action:'connect_x', confirm:true`.
|
|
79
48
|
|
|
80
|
-
|
|
49
|
+
This imports the session **and auto-detects + records your real `@handle`** into `config.json` (`accounts.twitter.handle`). That handle scopes attribution, own-reply skipping, and account-keyed operations — so do not hand-edit it to a placeholder.
|
|
81
50
|
|
|
82
|
-
|
|
83
|
-
- "What's your Reddit username?" → set `accounts.reddit.username`
|
|
84
|
-
- Login method is always `browser` (Reddit has no public posting API)
|
|
51
|
+
### Step 4: Verify with a draft cycle
|
|
85
52
|
|
|
86
|
-
**
|
|
87
|
-
- "What's your X handle?" → set `accounts.twitter.handle`
|
|
88
|
-
- Login method is always `browser`
|
|
53
|
+
Run the `draft_cycle` tool. It scans X, drafts replies, and shows them for your approval — it **posts nothing** until you approve. If it comes back empty with a clear reason (e.g. "no search topics"), fix that (re-run `setup` with topics) and try again. A non-empty review form means the pipeline is healthy end-to-end.
|
|
89
54
|
|
|
90
|
-
|
|
91
|
-
- "What's your LinkedIn name?" → set `accounts.linkedin.name`
|
|
92
|
-
- Login method is always `browser`
|
|
55
|
+
### Step 5 (optional): Autopilot
|
|
93
56
|
|
|
94
|
-
|
|
95
|
-
- "Do you want to set up Moltbook? (y/n)"
|
|
96
|
-
- If yes: "What's your Moltbook username?" and "What's your Moltbook API key?"
|
|
97
|
-
- Edit `$SKILL_DIR/.env` and set `MOLTBOOK_API_KEY=<key>` (the file already exists from init)
|
|
98
|
-
- Set `accounts.moltbook.username` and `accounts.moltbook.api_key_env` in `config.json`
|
|
99
|
-
|
|
100
|
-
### Step 4: Configure content
|
|
101
|
-
|
|
102
|
-
This step is the most important one. Take your time. The quality of every future post depends on it.
|
|
57
|
+
If the user wants hands-free posting, call `autopilot` with `action:'enable'` — it loads the background cycle and daily auto-updates. `action:'status'` reports whether it's loaded; `action:'disable'` turns it off (manual `draft_cycle` still works).
|
|
103
58
|
|
|
104
59
|
---
|
|
105
60
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
Ask: "Which subreddits do you want to post in? (comma-separated, or press enter for defaults)"
|
|
109
|
-
|
|
110
|
-
Default suggestion: `ClaudeAI, ClaudeCode, programming, webdev, devops`
|
|
111
|
-
|
|
112
|
-
Write the list to `config.json` under `subreddits`.
|
|
113
|
-
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
**4b. Content angle — interview the user**
|
|
117
|
-
|
|
118
|
-
Don't just ask for a one-liner. Run a short interview to understand who they are, then write the angle for them.
|
|
119
|
-
|
|
120
|
-
Ask these questions one at a time. Wait for each answer before asking the next.
|
|
121
|
-
|
|
122
|
-
**Question 1:** "What are you currently working on or building? Be specific — what does it actually do?"
|
|
123
|
-
|
|
124
|
-
**Question 2:** "What's your technical background? What languages, tools, or domains do you know well?"
|
|
125
|
-
|
|
126
|
-
**Question 3:** "What's something you've learned recently from your work that most people in your field don't know yet — or that surprised you?"
|
|
127
|
-
|
|
128
|
-
**Question 4:** "What's a recurring frustration or problem you've run into that you think others in your community also face?"
|
|
129
|
-
|
|
130
|
-
**Question 5:** "Do you have any unusual setup or workflow? (e.g. running multiple AI agents, building on niche platforms, working solo on something usually done by teams)"
|
|
131
|
-
|
|
132
|
-
After collecting all answers, synthesize them into a `content_angle` that:
|
|
133
|
-
- Is 2-4 sentences
|
|
134
|
-
- Is written in first person
|
|
135
|
-
- Names specific tools, numbers, and experiences (not generic claims)
|
|
136
|
-
- Captures what makes their perspective genuinely different from a typical developer
|
|
61
|
+
## CLI fallback (no MCP)
|
|
137
62
|
|
|
138
|
-
|
|
139
|
-
> "Here's the content angle I'll use to write comments in your voice:
|
|
140
|
-
> [DRAFT]
|
|
141
|
-
> Does this sound like you? Want to change anything?"
|
|
63
|
+
Only if the MCP tools aren't available.
|
|
142
64
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
**
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
**
|
|
149
|
-
> "Building a macOS desktop AI agent that controls the browser and writes code via voice. Running 5 Claude agents in parallel on the same codebase — learned the hard way that they need zero file overlap or everything breaks. API costs hit $800/month before I got aggressive about caching."
|
|
65
|
+
1. **Install**: `npx social-autoposter init` (creates `config.json` from the template and `.env`; symlinks the skill). Update later with `npx social-autoposter update`.
|
|
66
|
+
2. **Configure the project**: edit `~/social-autoposter/config.json` `projects[]` with `name`, `website`, `description`, `icp`, `voice`, and `search_topics` (array). Leave `accounts.twitter.handle` empty — it's filled on connect.
|
|
67
|
+
3. **Seed topics into the DB** (the cycle reads the DB, not config): `python3 scripts/seed_search_topics.py --project <name>`.
|
|
68
|
+
4. **Connect X**: `python3 scripts/setup_twitter_auth.py connect` — imports the session and records the real handle.
|
|
69
|
+
5. **Verify**: `DRAFT_ONLY=1 TWITTER_PAGE_GEN_RATE=0 bash skill/run-twitter-cycle.sh` — drafts without posting; it prints `DRAFT_ONLY_PLAN=<path>` on success.
|
|
70
|
+
6. **Automation** (optional): on macOS, symlink + load the launchd plists in `skill/launchd/`; on Linux, add the matching cron entries.
|
|
150
71
|
|
|
151
72
|
---
|
|
152
73
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
Ask: "Do you have any open source projects or products you'd want to mention naturally when the topic comes up? (y/n)"
|
|
156
|
-
|
|
157
|
-
If yes, for each project run through:
|
|
158
|
-
- "What's the name?"
|
|
159
|
-
- "One sentence: what does it do?"
|
|
160
|
-
- "Website URL? (or leave blank)"
|
|
161
|
-
- "GitHub URL? (or leave blank)"
|
|
162
|
-
- "What topics or keywords would make it relevant to mention? (e.g. 'desktop automation, macOS, accessibility APIs')"
|
|
163
|
-
|
|
164
|
-
After each project, ask: "Any more projects to add? (y/n)"
|
|
165
|
-
|
|
166
|
-
Store each under `config.json` → `projects` array with fields: `name`, `description`, `website`, `github`, `topics` (array of strings).
|
|
167
|
-
|
|
168
|
-
The `topics` keywords are what trigger natural mentions — when someone in a thread mentions one of these topics, the agent knows this project is relevant to bring up.
|
|
169
|
-
|
|
170
|
-
### Step 5: Verify browser logins
|
|
171
|
-
|
|
172
|
-
For each configured platform, verify the user is logged in:
|
|
173
|
-
|
|
174
|
-
**Reddit:**
|
|
175
|
-
- Navigate to `https://old.reddit.com` using browser automation
|
|
176
|
-
- Check if a username appears in the top-right (logged in) or a "login" link (not logged in)
|
|
177
|
-
- If not logged in: "Please log into Reddit in your browser, then say 'done'"
|
|
178
|
-
- Re-check after they confirm
|
|
179
|
-
|
|
180
|
-
**X/Twitter:**
|
|
181
|
-
- Navigate to `https://x.com/home`
|
|
182
|
-
- Check if the home timeline loads (logged in) or a login page appears
|
|
183
|
-
- Same flow if not logged in
|
|
184
|
-
|
|
185
|
-
**LinkedIn:**
|
|
186
|
-
- Navigate to `https://www.linkedin.com/feed/`
|
|
187
|
-
- Check if the feed loads or a login page appears
|
|
188
|
-
|
|
189
|
-
**Moltbook:**
|
|
190
|
-
- Source the env file and test the API key:
|
|
191
|
-
```bash
|
|
192
|
-
source ~/social-autoposter/.env
|
|
193
|
-
curl -s -H "Authorization: Bearer $MOLTBOOK_API_KEY" "https://www.moltbook.com/api/v1/posts?limit=1"
|
|
194
|
-
```
|
|
195
|
-
- Check for a successful response (not an auth error)
|
|
196
|
-
|
|
197
|
-
Report which platforms are ready and which need attention.
|
|
74
|
+
## Summary to show the user
|
|
198
75
|
|
|
199
|
-
### Step 6: Test run (dry run)
|
|
200
|
-
|
|
201
|
-
Run the thread finder to verify everything works:
|
|
202
|
-
```bash
|
|
203
|
-
python3 "$SKILL_DIR/scripts/find_threads.py" --limit 3
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
Show the user the candidate threads found. Don't post anything — just verify the pipeline works.
|
|
207
|
-
|
|
208
|
-
### Step 7: Set up automation (optional)
|
|
209
|
-
|
|
210
|
-
Ask: "Do you want posts to run automatically on a schedule? (y/n)"
|
|
211
|
-
|
|
212
|
-
If yes, and on macOS:
|
|
213
|
-
- The launchd plists are already in `$SKILL_DIR/launchd/` (one per platform: reddit-search, reddit-threads, twitter-cycle, linkedin, moltbook, github, plus system jobs: stats, engage, audit, octolens, scan-*, dm-replies-*, link-edit-*)
|
|
214
|
-
- Symlink and load all of them:
|
|
215
|
-
```bash
|
|
216
|
-
for plist in "$SKILL_DIR"/launchd/com.m13v.social-*.plist; do
|
|
217
|
-
ln -sf "$plist" ~/Library/LaunchAgents/
|
|
218
|
-
launchctl load ~/Library/LaunchAgents/$(basename "$plist")
|
|
219
|
-
done
|
|
220
|
-
```
|
|
221
|
-
- Cadences: Twitter cycle every 20 min, Reddit search every 30 min, Reddit threads 4x/day, reply scans 2x/day, engage loop every 4 h, stats refresh 4x/day, DM outreach and link-edit 4x/day.
|
|
222
|
-
|
|
223
|
-
If yes, and on Linux:
|
|
224
|
-
- Generate crontab entries (pick the platforms you use):
|
|
225
|
-
```
|
|
226
|
-
*/20 * * * * cd ~/social-autoposter && bash skill/run-twitter-cycle.sh
|
|
227
|
-
*/30 * * * * cd ~/social-autoposter && bash skill/run-reddit-search.sh
|
|
228
|
-
10 */6 * * * cd ~/social-autoposter && bash skill/run-reddit-threads.sh
|
|
229
|
-
0 */6 * * * cd ~/social-autoposter && bash skill/stats.sh
|
|
230
|
-
0 */4 * * * cd ~/social-autoposter && bash skill/engage.sh
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
If no: "You can run manually anytime with `/social-autoposter`"
|
|
234
|
-
|
|
235
|
-
### Step 8: Summary
|
|
236
|
-
|
|
237
|
-
Read `config.json` accounts and compute each platform's stats URL:
|
|
238
|
-
- Twitter/X handle (strip leading `@`): `https://s4l.ai/stats/HANDLE`
|
|
239
|
-
- Reddit username: `https://s4l.ai/stats/USERNAME`
|
|
240
|
-
- LinkedIn name (URL-encoded spaces as `%20`): `https://s4l.ai/stats/NAME`
|
|
241
|
-
- Moltbook username: `https://s4l.ai/stats/MOLTBOOK_USERNAME`
|
|
242
|
-
|
|
243
|
-
Print a summary with real values substituted:
|
|
244
76
|
```
|
|
245
77
|
Social Autoposter Setup Complete
|
|
246
78
|
|
|
247
|
-
Installed: ~/social-autoposter (
|
|
248
|
-
Database: Postgres (DATABASE_URL in .env)
|
|
79
|
+
Installed: ~/social-autoposter (via npm)
|
|
249
80
|
Config: ~/social-autoposter/config.json
|
|
250
|
-
|
|
251
|
-
Skill: ~/.claude/skills/social-autoposter
|
|
252
|
-
|
|
253
|
-
Platforms:
|
|
254
|
-
Reddit: u/USERNAME ✓
|
|
255
|
-
X/Twitter: @HANDLE ✓
|
|
256
|
-
LinkedIn: NAME ✓
|
|
257
|
-
Moltbook: USERNAME ✓
|
|
258
|
-
|
|
259
|
-
Automation: launchd (hourly post, 6h stats, 2h engage)
|
|
81
|
+
Backend: s4l.ai HTTP API (per-install identity; no local DB)
|
|
260
82
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
LinkedIn: https://s4l.ai/stats/NAME
|
|
265
|
-
Moltbook: https://s4l.ai/stats/MOLTBOOK_USERNAME
|
|
83
|
+
Project: NAME — ready
|
|
84
|
+
Search topics seeded: N
|
|
85
|
+
X/Twitter: @HANDLE (auto-detected on connect)
|
|
266
86
|
|
|
267
|
-
|
|
87
|
+
Verify: draft_cycle (drafts for review, posts nothing)
|
|
88
|
+
Autopilot: autopilot action:'enable' (hands-free)
|
|
89
|
+
Stats: https://s4l.ai/stats/HANDLE
|
|
268
90
|
Update: npx social-autoposter update
|
|
269
91
|
```
|
|
270
92
|
|
|
271
|
-
Tell the user
|
|
93
|
+
Tell the user their stats page (`https://s4l.ai/stats/<handle>`) populates after the first real post.
|