forkfeed-mcp 1.0.15 → 1.2.0
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/dist/guide-content.js +86 -220
- package/dist/image-catalog.d.ts +232 -230
- package/dist/image-catalog.js +238 -230
- package/dist/index.js +492 -125
- package/package.json +1 -1
package/dist/guide-content.js
CHANGED
|
@@ -6,143 +6,88 @@
|
|
|
6
6
|
export const GUIDE_CONTENT = `
|
|
7
7
|
# Forkfeed Content Guide - "The Fuck I Pushed"
|
|
8
8
|
|
|
9
|
-
Turn GitHub commits into swipeable card content. One fork per repo, one feed per commit, 8 cards per feed
|
|
9
|
+
Turn GitHub commits into swipeable card content. One fork per repo, one feed per commit, 8 cards per feed.
|
|
10
10
|
|
|
11
|
-
**
|
|
11
|
+
**Process exactly ONE commit at a time, never multiple.**
|
|
12
12
|
|
|
13
13
|
## Quick start
|
|
14
14
|
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
4.
|
|
15
|
+
1. Call **forkfeed_guide** and **forkfeed_commits()** in parallel
|
|
16
|
+
2. Show commits table, ask which ONE to process
|
|
17
|
+
3. Call **forkfeed_commits(sha)** to get diff, stats, and pre-filtered images
|
|
18
|
+
4. Generate simplified content JSON (see format below)
|
|
19
|
+
5. Call **forkfeed_build** with the content (push defaults to true)
|
|
19
20
|
|
|
20
21
|
---
|
|
21
22
|
|
|
22
|
-
##
|
|
23
|
+
## Simplified content format (for forkfeed_build)
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
The builder handles UUIDs, full image URLs, cover variants, type wrappers, feedId/order, and fork/feed boilerplate. You only provide creative content.
|
|
25
26
|
|
|
26
|
-
Process exactly one commit per run. If the user didn't specify, use the latest commit. If they ask for multiple commits, process only the first and tell them to run again for the next.
|
|
27
|
-
|
|
28
|
-
Use **IT Scenes** images. Call **forkfeed_images** to get the full catalog (200 scene images + 30 backgrounds). Match images to content by tags and semantic similarity. Do not ask about image style.
|
|
29
|
-
|
|
30
|
-
---
|
|
31
|
-
|
|
32
|
-
## Phase 2: Fetch commit data
|
|
33
|
-
|
|
34
|
-
### GitHub repos
|
|
35
|
-
\`\`\`bash
|
|
36
|
-
# Verify access
|
|
37
|
-
gh api repos/{owner}/{repo} --jq '.full_name'
|
|
38
|
-
|
|
39
|
-
# Metadata
|
|
40
|
-
gh api repos/{owner}/{repo}/commits/{sha} --jq '{sha: .sha, shortSha: (.sha[:7]), message: .commit.message, author: .commit.author.name, date: .commit.author.date, additions: .stats.additions, deletions: .stats.deletions, totalFiles: (.files | length)}'
|
|
41
|
-
|
|
42
|
-
# Full diff
|
|
43
|
-
gh api repos/{owner}/{repo}/commits/{sha} -H "Accept: application/vnd.github.v3.diff"
|
|
44
|
-
|
|
45
|
-
# README for fork title/description
|
|
46
|
-
gh api repos/{owner}/{repo} --jq '.description'
|
|
47
|
-
\`\`\`
|
|
48
|
-
|
|
49
|
-
### Local repos
|
|
50
|
-
\`\`\`bash
|
|
51
|
-
git -C "{path}" log -1 --format='{"sha":"%H","shortSha":"%h","message":"%s","author":"%an","date":"%aI"}' {sha}
|
|
52
|
-
git -C "{path}" diff --stat {sha}^..{sha}
|
|
53
|
-
git -C "{path}" diff {sha}^..{sha}
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
Skip merge commits (>1 parent) unless it's the only commit.
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Phase 3: Generate manifest
|
|
61
|
-
|
|
62
|
-
### ID conventions
|
|
63
|
-
- Fork: \`tfip-{owner}-{repo}\` or \`tfip-local-{dirname}\`
|
|
64
|
-
- Feed: \`tfip-{owner}-{repo}-{7char-sha}\`
|
|
65
|
-
- Card: UUID v4 (generate upfront with \`node -e "for(let i=0;i<N;i++) process.stdout.write(require('crypto').randomUUID()+'\\n')"\`)
|
|
66
|
-
|
|
67
|
-
All IDs must match \`/^[a-z0-9-]+$/\` (except card UUIDs).
|
|
68
|
-
|
|
69
|
-
### JSON structure
|
|
70
27
|
\`\`\`json
|
|
71
28
|
{
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
|
|
84
|
-
"description": "Mon DD: one-line impact summary",
|
|
85
|
-
"imageSrc": "same as card 0 cover image",
|
|
86
|
-
"mode": "sequential",
|
|
87
|
-
"scrollDirection": "vertical",
|
|
88
|
-
"engagement": true
|
|
89
|
-
}],
|
|
29
|
+
"owner": "owner-or-local",
|
|
30
|
+
"repo": "repo-name",
|
|
31
|
+
"sha": "7char",
|
|
32
|
+
"feedTitle": "Max 60 chars headline",
|
|
33
|
+
"feedDescription": "Mon DD: one-line impact summary",
|
|
34
|
+
"forkTitle": "Project Name",
|
|
35
|
+
"forkDescription": "What the project IS",
|
|
36
|
+
"actionUrl": "https://github.com/owner/repo",
|
|
37
|
+
"existingFeedIds": [],
|
|
38
|
+
"images": {
|
|
39
|
+
"bg": ["bg10", "bg11", "bg20", "bg25", "bg9", "bg12", "bg30", "bg18"]
|
|
40
|
+
},
|
|
90
41
|
"cards": [
|
|
91
42
|
{
|
|
92
|
-
"_id": "uuid-v4",
|
|
93
|
-
"feedId": "tfip-owner-repo-abc1234",
|
|
94
|
-
"order": 0,
|
|
95
43
|
"variants": [
|
|
96
|
-
{ "
|
|
97
|
-
{ "
|
|
44
|
+
{ "blocks": [{ "img": "img47", "sizing": "wide" }, { "title": "Section heading" }, { "text": "Paragraph content..." }] },
|
|
45
|
+
{ "blocks": [{ "title": "Another section" }, { "text": "More content..." }] }
|
|
98
46
|
]
|
|
99
47
|
}
|
|
100
48
|
]
|
|
101
49
|
}
|
|
102
50
|
\`\`\`
|
|
103
51
|
|
|
104
|
-
###
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
|
109
|
-
|
|
110
|
-
|
|
|
111
|
-
|
|
|
112
|
-
|
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
|
|
|
116
|
-
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
{ type: "CONTENT_TITLE", title: "Feature detection pattern" }
|
|
52
|
+
### Block types (inferred from fields)
|
|
53
|
+
|
|
54
|
+
| Write this | Becomes | Notes |
|
|
55
|
+
|------------|---------|-------|
|
|
56
|
+
| \`{ "img": "img47" }\` | CONTENT_IMAGE | sizing defaults to "wide". Options: automatic, wide, portrait, square, small_portrait |
|
|
57
|
+
| \`{ "img": "img47", "sizing": "square" }\` | CONTENT_IMAGE | With explicit sizing |
|
|
58
|
+
| \`{ "title": "Heading" }\` | CONTENT_TITLE | Required in every detail variant, sentence case |
|
|
59
|
+
| \`{ "text": "Paragraph..." }\` | CONTENT_TEXT | 50-200 words, use \\\\n\\\\n for breaks |
|
|
60
|
+
| \`{ "code": "const x = 1", "lang": "typescript" }\` | CONTENT_CODE | Real code from diff, 5-20 lines, strip +/- prefixes |
|
|
61
|
+
| \`{ "subtext": "Pro tip..." }\` | CONTENT_SUBTEXT | Aside or protip |
|
|
62
|
+
| \`{ "name": "Chad", "subtitle": "10x Engineer", "avatar": "img98", "source": "linkedin" }\` | CONTENT_SOCIAL | Cards 2-3 only. source: x, linkedin, threads, etc. |
|
|
63
|
+
| \`{ "question": "What does X do?", "options": [{"label": "A", "correct": false}, {"label": "B", "correct": true}], "explanation": "Because..." }\` | CONTENT_QUIZ | Card 7 only. 4 options recommended, min 2, one correct, always include explanation |
|
|
64
|
+
| \`{ "label": "Google it", "action": "url", "target": "https://google.com/search?q=topic" }\` | CONTENT_BUTTON | Card 5 only, MUST be last block in every detail variant |
|
|
65
|
+
|
|
66
|
+
### What the builder does automatically
|
|
67
|
+
- Generates UUID v4 for each card ID
|
|
68
|
+
- Resolves short image IDs (img47, bg10) to full CDN URLs
|
|
69
|
+
- Adds FULL_IMAGE cover variant with fixed title/subtitle per card type
|
|
70
|
+
- Sets backgroundSrc on all CONTENT variants from images.bg[cardIndex]
|
|
71
|
+
- Sets feedId and order on each card
|
|
72
|
+
- Builds fork and feed objects with correct IDs and metadata
|
|
73
|
+
- Validates the assembled manifest before pushing
|
|
127
74
|
|
|
128
|
-
|
|
129
|
-
{ type: "CONTENT_TEXT", text: "..." }
|
|
130
|
-
|
|
131
|
-
// CONTENT_CODE - code snippet (real from diff, 5-20 lines, strip +/- prefixes)
|
|
132
|
-
{ type: "CONTENT_CODE", code: "...", language: "typescript" }
|
|
133
|
-
|
|
134
|
-
// CONTENT_SOCIAL - persona post (Cards 2-3 only, replaces IMAGE)
|
|
135
|
-
{ type: "CONTENT_SOCIAL", avatarSrc: "url", name: "Chad Gitpush", subtitle: "10x Engineer", source: "linkedin" }
|
|
75
|
+
---
|
|
136
76
|
|
|
137
|
-
|
|
138
|
-
{ type: "CONTENT_SUBTEXT", text: "..." }
|
|
77
|
+
## The 8 cards
|
|
139
78
|
|
|
140
|
-
|
|
141
|
-
{ type: "CONTENT_QUIZ", question: "...", options: [{ label: "A", correct: false }, ...], explanation: "..." }
|
|
79
|
+
Each card = array of detail variants (cover is auto-generated). Provide 1+ variants per card.
|
|
142
80
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
81
|
+
| # | Section | Detail variants | Block pattern | Tone |
|
|
82
|
+
|---|---------|----------------|---------------|------|
|
|
83
|
+
| 0 | Explain like I'm 5 | 3-6 | img -> title -> text | Playful, zero jargon |
|
|
84
|
+
| 1 | The roast | 3-6 | img -> title -> text, optional subtext | Maximum cheekiness, swearing ok |
|
|
85
|
+
| 2 | Commit message, decoded | 2-4 | social -> title -> text -> optional code | Escalating absurdity |
|
|
86
|
+
| 3 | The LinkedIn post | 2-4 | social -> title -> text -> subtext | Peak LinkedIn parody |
|
|
87
|
+
| 4 | Statistics | 3-5 | img -> title -> code | Deadpan data humor |
|
|
88
|
+
| 5 | Learning moment | 3-8 | img -> title -> text -> optional code -> button(last) | Teach with personality |
|
|
89
|
+
| 6 | Alternatives | 3-6 | img -> title -> text -> optional code | Constructive snark |
|
|
90
|
+
| 7 | Quiz | 10-15 | title -> quiz (no img blocks) | Quiz show energy |
|
|
146
91
|
|
|
147
92
|
### Card 2 personas (Decoded)
|
|
148
93
|
- "What you meant" (source: "x" or "threads")
|
|
@@ -154,127 +99,48 @@ Each card: variant[0] = FULL_IMAGE cover, variant[1+] = CONTENT details.
|
|
|
154
99
|
- Alexandra Middleware: "VP of Forward Thinking at TechCorp"
|
|
155
100
|
- Dave 'Shipping' Johnson: "Just a humble engineer doing humble things"
|
|
156
101
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Key rules
|
|
105
|
+
|
|
106
|
+
- Exactly 8 cards in the cards array (one per section above)
|
|
107
|
+
- images.bg must have 8 unique background IDs
|
|
108
|
+
- 12-20 unique scene images (img*) across the feed, no duplicate within same card
|
|
161
109
|
- Cards 0-5: code must be REAL from the diff (never fabricated)
|
|
162
110
|
- Card 6: synthesized code IS allowed
|
|
163
|
-
- Card 7: no
|
|
164
|
-
- Card 5: every detail variant MUST end with
|
|
165
|
-
-
|
|
111
|
+
- Card 7: no img blocks, quiz blocks only (with title per variant)
|
|
112
|
+
- Card 5: every detail variant MUST end with a button block
|
|
113
|
+
- Cards 2-3: first block should be social (not img)
|
|
114
|
+
- CONTENT_QUIZ: 4 options recommended (min 2), exactly one correct, always include explanation
|
|
166
115
|
- No em dashes, smart quotes, or non-ASCII characters
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
### IT Scenes images
|
|
170
|
-
|
|
171
|
-
Call **forkfeed_images** to get the full catalog. 200 scene images (img1-img200) for covers and inline images, 30 backgrounds (bg1-bg30) for card backgrounds.
|
|
116
|
+
- Feed title max 60 chars
|
|
172
117
|
|
|
173
|
-
|
|
174
|
-
1. Identify commit tags from the diff: deploy, git, disaster, debug, hype, victory, beginner, language, lifestyle, workplace, sarcastic, general
|
|
175
|
-
2. Filter images by tag overlap
|
|
176
|
-
3. Rank by semantic similarity to card content (title, text, code topics)
|
|
177
|
-
4. Assign best match, remove from pool (no duplicates)
|
|
118
|
+
### Images
|
|
178
119
|
|
|
179
|
-
**
|
|
180
|
-
- 8 unique scene images for FULL_IMAGE covers (one per card)
|
|
181
|
-
- Detail CONTENT_IMAGE must differ from the card's cover
|
|
182
|
-
- No two detail variants in the same card share a CONTENT_IMAGE
|
|
183
|
-
- 8 unique bg* images for backgroundSrc (one per card)
|
|
184
|
-
- Pick 16-25 unique images per feed
|
|
120
|
+
Images are pre-filtered by **forkfeed_commits(sha)**. Pick from the suggested list.
|
|
185
121
|
|
|
186
|
-
**BG preferences
|
|
187
|
-
- ELI5 (0): bg10, bg27 | Roast (1): bg11, bg1 | Decoded (2): bg20, bg11
|
|
188
|
-
- LinkedIn (3): bg25, bg24 | Statistics (4): bg9, bg3 | Learning (5): match tech
|
|
189
|
-
- Alternatives (6): bg25, bg30 | Quiz (7): bg18, bg5
|
|
190
|
-
|
|
191
|
-
**Fork/feed imageSrc** = Card 0's FULL_IMAGE imageSrc
|
|
122
|
+
**BG preferences:** ELI5: bg10/bg27 | Roast: bg11/bg1 | Decoded: bg20/bg11 | LinkedIn: bg25/bg24 | Stats: bg9/bg3 | Learning: match tech | Alts: bg25/bg30 | Quiz: bg18/bg5
|
|
192
123
|
|
|
193
124
|
### Tone
|
|
194
|
-
Casual, cheeky, technically accurate.
|
|
195
|
-
- Use "you" directly
|
|
196
|
-
- Short paragraphs
|
|
197
|
-
- Contractions
|
|
198
|
-
- Swear occasionally for emphasis
|
|
199
|
-
- Humor is the default
|
|
125
|
+
Casual, cheeky, technically accurate. Use "you," contractions, short paragraphs, occasional swearing. Humor is the default.
|
|
200
126
|
|
|
201
127
|
### Incremental updates
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
- **New commit**: Generate only the new feed and cards. The fork's feedIds must include ALL existing feed IDs plus the new one. Missing old IDs causes them to be deleted.
|
|
205
|
-
- **Existing commit**: Warn the user that this commit already has a feed. Only regenerate if they confirm. The old cards will be replaced.
|
|
206
|
-
- **One commit per run**: Never process multiple commits at once. If the user wants more, they run the command again.
|
|
207
|
-
|
|
208
|
-
### Parallel card generation
|
|
209
|
-
|
|
210
|
-
Generate all 8 cards simultaneously using the Agent tool. This is critical for speed.
|
|
128
|
+
**forkfeed_commits()** (list mode) shows which commits have published feeds and lists existing feed IDs.
|
|
211
129
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
3. Output the skeleton (fork, feed, image assignments, UUIDs) so it's visible.
|
|
216
|
-
|
|
217
|
-
**Agent prompts** (launch ALL 8 in a single message):
|
|
218
|
-
Each agent generates exactly one card. The agent prompt must include:
|
|
219
|
-
- Card number and section name (e.g., "Card 1: The roast")
|
|
220
|
-
- The section rules from this guide: variant count range, block pattern, tone
|
|
221
|
-
- The full commit diff and stats
|
|
222
|
-
- Assigned cover imageSrc (img*), backgroundSrc (bg*), and the pool of available inline images for this card
|
|
223
|
-
- The card UUID (\`_id\`) and feed ID (\`feedId\`)
|
|
224
|
-
- "Return ONLY the raw JSON card object, no markdown, no explanation. Do NOT use any tools, scripts, or commands - just output the JSON directly."
|
|
225
|
-
|
|
226
|
-
Example agent prompt structure:
|
|
227
|
-
\`\`\`
|
|
228
|
-
Generate Card 2 (Commit message, decoded) for forkfeed.
|
|
229
|
-
|
|
230
|
-
Card JSON structure: { "_id": "{uuid}", "feedId": "{feedId}", "order": 2, "variants": [...] }
|
|
231
|
-
|
|
232
|
-
Rules: 2-4 detail variants. Pattern: SOCIAL -> TITLE -> TEXT -> optional CODE. Escalating absurdity.
|
|
233
|
-
Personas: "What you meant" (source: "x"), "Corporate speak" (source: "linkedin").
|
|
234
|
-
|
|
235
|
-
Cover: { "type": "FULL_IMAGE", "imageSrc": "{assigned-cover}", "title": "...", "subtitle": "..." }
|
|
236
|
-
Background for all CONTENT variants: "{assigned-bg}"
|
|
237
|
-
Available inline images: {pool}
|
|
238
|
-
|
|
239
|
-
Commit diff:
|
|
240
|
-
{diff}
|
|
241
|
-
|
|
242
|
-
Return ONLY the JSON object. No markdown fences, no explanation.
|
|
243
|
-
Do NOT use any tools, scripts, or commands. Just output the JSON directly as text.
|
|
244
|
-
\`\`\`
|
|
245
|
-
|
|
246
|
-
**Assembly** (main context, after agents complete):
|
|
247
|
-
Collect 8 card JSONs, combine with fork and feed into the manifest, validate against the checklist, and push.
|
|
130
|
+
- **New commit**: Include ALL existing feed IDs in existingFeedIds. Missing old IDs causes deletion.
|
|
131
|
+
- **Existing commit**: Warn the user. Only regenerate if they confirm.
|
|
132
|
+
- **One commit per run**: Never process multiple commits at once.
|
|
248
133
|
|
|
249
134
|
---
|
|
250
135
|
|
|
251
|
-
##
|
|
136
|
+
## Advanced: direct push with full manifest (forkfeed_push)
|
|
252
137
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
138
|
+
If you need full control, you can build the manifest manually and use forkfeed_push directly. The full manifest requires:
|
|
139
|
+
- Fork/feed objects with all fields (mode, scrollDirection, engagement, etc.)
|
|
140
|
+
- FULL_IMAGE cover variant[0] per card with fixed titles/subtitles
|
|
141
|
+
- CONTENT variants with type field, full image URLs, backgroundSrc
|
|
142
|
+
- UUID v4 card IDs, feedId and order on each card
|
|
257
143
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
---
|
|
261
|
-
|
|
262
|
-
## Validation checklist (verify before pushing)
|
|
263
|
-
|
|
264
|
-
- [ ] Fork/feed IDs match /^[a-z0-9-]+$/
|
|
265
|
-
- [ ] Card IDs are valid UUID v4
|
|
266
|
-
- [ ] Every card.feedId matches an actual feed._id
|
|
267
|
-
- [ ] Fork.feedIds match actual feed._id values
|
|
268
|
-
- [ ] Top-level key is "forks" (plural array)
|
|
269
|
-
- [ ] Card order values are sequential 0-7
|
|
270
|
-
- [ ] Each card has >= 2 variants
|
|
271
|
-
- [ ] variant[0] is FULL_IMAGE with imageSrc, title, subtitle
|
|
272
|
-
- [ ] variant[1+] are CONTENT with backgroundSrc and blocks
|
|
273
|
-
- [ ] FULL_IMAGE subtitle max 200 chars
|
|
274
|
-
- [ ] Feed title max 60 chars
|
|
275
|
-
- [ ] Feed mode: "sequential", scrollDirection: "vertical", engagement: true
|
|
276
|
-
- [ ] CONTENT_QUIZ: exactly 4 options, one correct, explanation required
|
|
277
|
-
- [ ] Card 5 detail variants end with CONTENT_BUTTON
|
|
278
|
-
- [ ] 8 unique cover images, 8 unique backgrounds
|
|
279
|
-
- [ ] No em dashes or smart quotes
|
|
144
|
+
ID conventions: Fork: \`tfip-{owner}-{repo}\`, Feed: \`tfip-{owner}-{repo}-{7char-sha}\`, Card: UUID v4
|
|
145
|
+
All IDs must match \`/^[a-z0-9-]+$/\` (except card UUIDs).
|
|
280
146
|
`.trim();
|