Skip to content

Commit dd26794

Browse files
committed
Split content-ideas SKILL.md: extract Step 0 first-run setup to references/
Token-cache optimization. SKILL.md was 29.4KB; Step 0 (7 substeps for install-path + slug + API key + brand-profile + competitor seeding) is ~7.5KB of bootstrap content that only fires on the first run per project, not on the daily-feed common path. New: references/first-run-setup.md — full 0a-0g flow. SKILL.md: 29.4KB → 22.5KB. Saves ~7KB per daily-run fire after first run.
1 parent ae94edf commit dd26794

2 files changed

Lines changed: 173 additions & 166 deletions

File tree

skills/content-ideas/SKILL.md

Lines changed: 2 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -155,173 +155,9 @@ themselves, so a relative `research/{today}` passed to them resolves here too.
155155

156156
**Run this before anything else, even if the user gave a topic.**
157157

158-
### 0a. First-ever install — choose where files live
158+
This step has 7 substeps (0a–0g) covering: install-path choice, project-slug naming, existing-install detection, API-key collection, manual-config alternative, brand-profile bootstrap from the user's own channels, and competitor-tracker seeding.
159159

160-
If this is a **truly fresh install**`~/.config/content/.env` doesn't
161-
exist, no `<slug>.env` files exist in that dir, and `$CONTENT_IDEAS_HOME`
162-
isn't set anywhere — ask the user where they'd like content-ideas to
163-
store the brand profile, tracked accounts, and dated research history.
164-
Otherwise skip this step (an existing install already picked a path).
165-
166-
Show a short note about why this matters, then `AskUserQuestion`:
167-
168-
> Before anything else: where should content-ideas store your files?
169-
> Brand profile, tracked competitors, and the daily research/feed
170-
> outputs live here. Pick somewhere durable — this is the home for
171-
> everything the skill writes, across all projects and all daily runs.
172-
173-
Offer these options:
174-
- `~/Documents/Content/` (default, no decision needed)
175-
- `~/Content/` (top-of-home, shorter path)
176-
- `~/.local/share/content-ideas/` (XDG-compliant, hidden by default)
177-
- Other — paste a path (e.g. inside an Obsidian vault, iCloud Drive,
178-
Dropbox; great for users who already have a "second-brain" tree)
179-
180-
Expand `~` and create the dir. Write `CONTENT_IDEAS_HOME=<absolute-path>`
181-
to `~/.config/content/.env` (create the dir + file if missing). All
182-
future invocations read this; `env.py:content_ideas_home()` is the
183-
resolver.
184-
185-
This is the install-root. The skill always operates in multi-project mode
186-
from here — even users who'll only ever have one project get a clean
187-
`<install-root>/projects/<slug>/` layout that's trivial to extend later.
188-
189-
### 0b. Name the first project (slug)
190-
191-
After the path is chosen (or on any later invocation against an unknown
192-
slug), prompt for the project slug. `AskUserQuestion`:
193-
194-
> What should we call this project? Pick a short slug — lowercase,
195-
> dashes-not-spaces. This becomes the project identifier you'll pass
196-
> as `/content-ideas <slug>` to invoke this feed specifically. For a
197-
> "just one feed" install, pick whatever fits your brand/persona
198-
> ("my-brand", "my-channel", etc.) — you can rename later by moving
199-
> the dir.
200-
201-
Validate slug shape (alphanumeric + dashes/underscores; reject spaces +
202-
quotes + braces — those collide with the multi-project arg-parser). Set:
203-
204-
```
205-
CONTENT_HOME = $CONTENT_IDEAS_HOME/projects/<slug>/
206-
KEY_FILE = ~/.config/content/<slug>.env
207-
```
208-
209-
Create `$CONTENT_HOME/brand/tracked-accounts/` and seed
210-
`~/.config/content/last-project` with this slug.
211-
212-
### 0c. Existing-install / new-project detection
213-
214-
If the user invoked the skill against an **existing project**
215-
(`$CONTENT_HOME` + `$KEY_FILE` both already exist for this slug), skip
216-
0d–0g and continue to Step 1. Otherwise — fresh install OR known
217-
`CONTENT_IDEAS_HOME` but unknown slug — continue setup below.
218-
219-
Confirm the slug with the user via `AskUserQuestion` before writing
220-
anything (chance to back out or retype). Then run 0d–0g. All file writes
221-
go to the per-project paths (`$CONTENT_HOME/brand/...`, `$KEY_FILE`).
222-
After setup, continue to Step 1.
223-
224-
### 0d. Welcome + API key
225-
226-
Setup has three quick parts: an API key, **your** profile (built from your own
227-
channels), and the competitors you want to track. Only the key is required —
228-
the rest the skill bootstraps for you and you can refine any time. Nothing to
229-
install; one ScrapeCreators API key covers all four platforms — X, Instagram,
230-
TikTok, and YouTube (including transcripts).
231-
232-
Show this as a normal message, then call `AskUserQuestion` (don't repeat the
233-
welcome inside the modal):
234-
235-
> I turn your social presence into a daily For You feed: I build a profile from
236-
> your own channels, track the competitors you pick, and surface what's
237-
> performing as content ideas backed by real engagement. I just need a
238-
> ScrapeCreators API key (one key covers all four platforms; 100 free calls, no
239-
> card).
240-
241-
`AskUserQuestion` — "Add your ScrapeCreators API key?"
242-
- Open scrapecreators.com to grab a free key
243-
- I'll paste a key now
244-
- Skip for now
245-
246-
If they pick "Open scrapecreators.com", run `open https://scrapecreators.com`,
247-
then ask them to paste the key. When the user pastes a key, write to the
248-
correct path for the mode:
249-
250-
- Single-project: `~/.config/content/.env`
251-
- Multi-project: `$KEY_FILE` (= `~/.config/content/<slug>.env`)
252-
253-
(Create dirs; append, don't clobber other keys):
254-
255-
```
256-
SCRAPECREATORS_API_KEY={key}
257-
SETUP_COMPLETE=true
258-
```
259-
260-
If they skip, write only `SETUP_COMPLETE=true`. In multi-project mode also
261-
write the slug to `~/.config/content/last-project` so bare `/content-ideas`
262-
defaults to this project next time.
263-
264-
### 0e. Manual alternative
265-
266-
If they'd rather configure by hand, tell them to add those two lines to
267-
`~/.config/content/.env`. Offer to write the file if they paste the key here.
268-
269-
### 0f. Build your brand profile
270-
271-
This is what personalizes everything: ideas get framed against *your* niche,
272-
pillars, and goal, and checked against what you've already posted. Build it from
273-
the user's own presence rather than a long questionnaire.
274-
275-
Ask for their own channels (`AskUserQuestion`: "Set up your profile now?" →
276-
**I'll share my handles** / **Skip — I'll add it later**). When they share
277-
handles — free-form across any platforms (`@me` on X, a YouTube channel, a
278-
TikTok, etc.) — normalize them into the `{platform: [handle]}` shape and scrape
279-
them like competitors, but over a much wider window (`--days 90`, the max) so
280-
you characterize their work from a full quarter, not just recent posts:
281-
282-
```bash
283-
python3 "$SKILL_DIR/scripts/scrape.py" \
284-
'{"x": ["me"], "youtube": ["@mychannel"]}' \
285-
--pillars "" --days 90
286-
```
287-
288-
From the returned posts (plus comments/transcripts), draft the profile:
289-
- **Niche, Audience, Voice Notes** — infer from recurring topics, framing, tone.
290-
- **Content Pillars** — the 3–5 themes their posts actually cluster into. These
291-
drive `--pillars` on every future run, so get them right.
292-
- **My Social Profiles** — handle, follower count, bio, and a one-line content-
293-
style note per platform, taken from the scrape.
294-
- **Target Platforms / Research Channels** — the platforms they're active on.
295-
- **Search Terms** — concrete keywords from their top topics.
296-
297-
Two things you can't scrape — **ask** (`AskUserQuestion`), then fold the answers in:
298-
- **Content Goal** — why they post (lead gen / awareness / growth / thought
299-
leadership / selling…), where they drive traffic, and what they're promoting.
300-
- **Pillar confirmation** — show the 3–5 pillars you inferred and let them
301-
edit or confirm before writing.
302-
303-
Write `brand/profile.md` per the schema in `FILE-SCHEMAS.md`. If the scrape
304-
returned enough of their own posts, also write an initial `brand/my-content.md`
305-
(performance summary, what's working, topics covered, and audience requests
306-
distilled from their comments) — this powers anti-cannibalization and the "your
307-
audience is asking for" banner from day one.
308-
309-
**If they skipped** (or there's no API key yet to scrape with), don't block:
310-
build a minimal `brand/profile.md` from a 2–3 question Q&A (niche, rough
311-
pillars, goal), note that re-running setup with a key auto-enriches it, and move
312-
on.
313-
314-
### 0g. Track competitors
315-
316-
Ask who they want to track (`AskUserQuestion`: list them now / skip and use an
317-
example). If they list handles, create `brand/tracked-accounts/{platform}.md`
318-
files per the schema in the plugin's `FILE-SCHEMAS.md`. If they skip, run a
319-
small example so they see the shape, and tell them they can add real
320-
competitors later.
321-
322-
**End of first-run setup.** Then continue with the user's original request.
323-
324-
---
160+
Detection — if `~/.config/content/.env` exists AND `<slug>.env` exists for the resolved project AND `SETUP_COMPLETE=true`, skip Step 0 entirely and go to Step 1. Otherwise, **see `references/first-run-setup.md` for the full setup flow** (substeps 0a–0g + the `AskUserQuestion` prompts, slug-validation rules, and brand-profile scrape pattern).
325161

326162
## Step 1: Load context
327163

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
## Step 0: First-run setup (or new-project setup)
2+
3+
**Run this before anything else, even if the user gave a topic.**
4+
5+
### 0a. First-ever install — choose where files live
6+
7+
If this is a **truly fresh install**`~/.config/content/.env` doesn't
8+
exist, no `<slug>.env` files exist in that dir, and `$CONTENT_IDEAS_HOME`
9+
isn't set anywhere — ask the user where they'd like content-ideas to
10+
store the brand profile, tracked accounts, and dated research history.
11+
Otherwise skip this step (an existing install already picked a path).
12+
13+
Show a short note about why this matters, then `AskUserQuestion`:
14+
15+
> Before anything else: where should content-ideas store your files?
16+
> Brand profile, tracked competitors, and the daily research/feed
17+
> outputs live here. Pick somewhere durable — this is the home for
18+
> everything the skill writes, across all projects and all daily runs.
19+
20+
Offer these options:
21+
- `~/Documents/Content/` (default, no decision needed)
22+
- `~/Content/` (top-of-home, shorter path)
23+
- `~/.local/share/content-ideas/` (XDG-compliant, hidden by default)
24+
- Other — paste a path (e.g. inside an Obsidian vault, iCloud Drive,
25+
Dropbox; great for users who already have a "second-brain" tree)
26+
27+
Expand `~` and create the dir. Write `CONTENT_IDEAS_HOME=<absolute-path>`
28+
to `~/.config/content/.env` (create the dir + file if missing). All
29+
future invocations read this; `env.py:content_ideas_home()` is the
30+
resolver.
31+
32+
This is the install-root. The skill always operates in multi-project mode
33+
from here — even users who'll only ever have one project get a clean
34+
`<install-root>/projects/<slug>/` layout that's trivial to extend later.
35+
36+
### 0b. Name the first project (slug)
37+
38+
After the path is chosen (or on any later invocation against an unknown
39+
slug), prompt for the project slug. `AskUserQuestion`:
40+
41+
> What should we call this project? Pick a short slug — lowercase,
42+
> dashes-not-spaces. This becomes the project identifier you'll pass
43+
> as `/content-ideas <slug>` to invoke this feed specifically. For a
44+
> "just one feed" install, pick whatever fits your brand/persona
45+
> ("my-brand", "my-channel", etc.) — you can rename later by moving
46+
> the dir.
47+
48+
Validate slug shape (alphanumeric + dashes/underscores; reject spaces +
49+
quotes + braces — those collide with the multi-project arg-parser). Set:
50+
51+
```
52+
CONTENT_HOME = $CONTENT_IDEAS_HOME/projects/<slug>/
53+
KEY_FILE = ~/.config/content/<slug>.env
54+
```
55+
56+
Create `$CONTENT_HOME/brand/tracked-accounts/` and seed
57+
`~/.config/content/last-project` with this slug.
58+
59+
### 0c. Existing-install / new-project detection
60+
61+
If the user invoked the skill against an **existing project**
62+
(`$CONTENT_HOME` + `$KEY_FILE` both already exist for this slug), skip
63+
0d–0g and continue to Step 1. Otherwise — fresh install OR known
64+
`CONTENT_IDEAS_HOME` but unknown slug — continue setup below.
65+
66+
Confirm the slug with the user via `AskUserQuestion` before writing
67+
anything (chance to back out or retype). Then run 0d–0g. All file writes
68+
go to the per-project paths (`$CONTENT_HOME/brand/...`, `$KEY_FILE`).
69+
After setup, continue to Step 1.
70+
71+
### 0d. Welcome + API key
72+
73+
Setup has three quick parts: an API key, **your** profile (built from your own
74+
channels), and the competitors you want to track. Only the key is required —
75+
the rest the skill bootstraps for you and you can refine any time. Nothing to
76+
install; one ScrapeCreators API key covers all four platforms — X, Instagram,
77+
TikTok, and YouTube (including transcripts).
78+
79+
Show this as a normal message, then call `AskUserQuestion` (don't repeat the
80+
welcome inside the modal):
81+
82+
> I turn your social presence into a daily For You feed: I build a profile from
83+
> your own channels, track the competitors you pick, and surface what's
84+
> performing as content ideas backed by real engagement. I just need a
85+
> ScrapeCreators API key (one key covers all four platforms; 100 free calls, no
86+
> card).
87+
88+
`AskUserQuestion` — "Add your ScrapeCreators API key?"
89+
- Open scrapecreators.com to grab a free key
90+
- I'll paste a key now
91+
- Skip for now
92+
93+
If they pick "Open scrapecreators.com", run `open https://scrapecreators.com`,
94+
then ask them to paste the key. When the user pastes a key, write to the
95+
correct path for the mode:
96+
97+
- Single-project: `~/.config/content/.env`
98+
- Multi-project: `$KEY_FILE` (= `~/.config/content/<slug>.env`)
99+
100+
(Create dirs; append, don't clobber other keys):
101+
102+
```
103+
SCRAPECREATORS_API_KEY={key}
104+
SETUP_COMPLETE=true
105+
```
106+
107+
If they skip, write only `SETUP_COMPLETE=true`. In multi-project mode also
108+
write the slug to `~/.config/content/last-project` so bare `/content-ideas`
109+
defaults to this project next time.
110+
111+
### 0e. Manual alternative
112+
113+
If they'd rather configure by hand, tell them to add those two lines to
114+
`~/.config/content/.env`. Offer to write the file if they paste the key here.
115+
116+
### 0f. Build your brand profile
117+
118+
This is what personalizes everything: ideas get framed against *your* niche,
119+
pillars, and goal, and checked against what you've already posted. Build it from
120+
the user's own presence rather than a long questionnaire.
121+
122+
Ask for their own channels (`AskUserQuestion`: "Set up your profile now?" →
123+
**I'll share my handles** / **Skip — I'll add it later**). When they share
124+
handles — free-form across any platforms (`@me` on X, a YouTube channel, a
125+
TikTok, etc.) — normalize them into the `{platform: [handle]}` shape and scrape
126+
them like competitors, but over a much wider window (`--days 90`, the max) so
127+
you characterize their work from a full quarter, not just recent posts:
128+
129+
```bash
130+
python3 "$SKILL_DIR/scripts/scrape.py" \
131+
'{"x": ["me"], "youtube": ["@mychannel"]}' \
132+
--pillars "" --days 90
133+
```
134+
135+
From the returned posts (plus comments/transcripts), draft the profile:
136+
- **Niche, Audience, Voice Notes** — infer from recurring topics, framing, tone.
137+
- **Content Pillars** — the 3–5 themes their posts actually cluster into. These
138+
drive `--pillars` on every future run, so get them right.
139+
- **My Social Profiles** — handle, follower count, bio, and a one-line content-
140+
style note per platform, taken from the scrape.
141+
- **Target Platforms / Research Channels** — the platforms they're active on.
142+
- **Search Terms** — concrete keywords from their top topics.
143+
144+
Two things you can't scrape — **ask** (`AskUserQuestion`), then fold the answers in:
145+
- **Content Goal** — why they post (lead gen / awareness / growth / thought
146+
leadership / selling…), where they drive traffic, and what they're promoting.
147+
- **Pillar confirmation** — show the 3–5 pillars you inferred and let them
148+
edit or confirm before writing.
149+
150+
Write `brand/profile.md` per the schema in `FILE-SCHEMAS.md`. If the scrape
151+
returned enough of their own posts, also write an initial `brand/my-content.md`
152+
(performance summary, what's working, topics covered, and audience requests
153+
distilled from their comments) — this powers anti-cannibalization and the "your
154+
audience is asking for" banner from day one.
155+
156+
**If they skipped** (or there's no API key yet to scrape with), don't block:
157+
build a minimal `brand/profile.md` from a 2–3 question Q&A (niche, rough
158+
pillars, goal), note that re-running setup with a key auto-enriches it, and move
159+
on.
160+
161+
### 0g. Track competitors
162+
163+
Ask who they want to track (`AskUserQuestion`: list them now / skip and use an
164+
example). If they list handles, create `brand/tracked-accounts/{platform}.md`
165+
files per the schema in the plugin's `FILE-SCHEMAS.md`. If they skip, run a
166+
small example so they see the shape, and tell them they can add real
167+
competitors later.
168+
169+
**End of first-run setup.** Then continue with the user's original request.
170+
171+
---

0 commit comments

Comments
 (0)