typefully 0.1.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/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "typefully",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "bin": {
6
+ "typefully": "./dist/index.js"
7
+ },
8
+ "main": "./dist/index.js",
9
+ "files": [
10
+ "dist",
11
+ "skills"
12
+ ],
13
+ "scripts": {
14
+ "dev": "tsup --watch",
15
+ "build": "tsup",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "lint": "biome check .",
19
+ "lint:fix": "biome check --write .",
20
+ "typecheck": "tsc --noEmit",
21
+ "format": "biome format --write ."
22
+ },
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "dependencies": {
27
+ "@clack/prompts": "^1.0.1",
28
+ "commander": "^14.0.3",
29
+ "ora": "^9.3.0",
30
+ "picocolors": "^1.1.1",
31
+ "zod": "^4.3.6"
32
+ },
33
+ "devDependencies": {
34
+ "@biomejs/biome": "^2.4.2",
35
+ "@types/node": "^25.2.3",
36
+ "tsup": "^8.5.1",
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^4.0.18"
39
+ }
40
+ }
@@ -0,0 +1,458 @@
1
+ ---
2
+ name: typefully
3
+ description: >
4
+ Create, schedule, and manage social media posts via Typefully. ALWAYS use this
5
+ skill when asked to draft, schedule, post, or check tweets, posts, threads, or
6
+ social media content for Twitter/X, LinkedIn, Threads, Bluesky, or Mastodon.
7
+ last-updated: 2026-02-18
8
+ allowed-tools: Bash(typefully*)
9
+ ---
10
+
11
+ # Typefully Skill
12
+
13
+ Create, schedule, and publish social media content across multiple platforms using [Typefully](https://typefully.com).
14
+
15
+ > **Freshness check**: If more than 30 days have passed since the `last-updated` date above, inform the user that this skill may be outdated and point them to the update options below.
16
+
17
+ ## Keeping This Skill Updated
18
+
19
+ **Source**: [github.com/typefully/agent-skills](https://github.com/typefully/agent-skills)
20
+ **API docs**: [typefully.com/docs/api](https://typefully.com/docs/api)
21
+
22
+ Update methods by installation type:
23
+
24
+ | Installation | How to update |
25
+ |--------------|---------------|
26
+ | CLI (`npx skills`) | `npx skills update` |
27
+ | Claude Code plugin | `/plugin update typefully@typefully-skills` |
28
+ | Cursor | Remote rules auto-sync from GitHub |
29
+ | Manual | Pull latest from repo or re-copy `skills/typefully/` |
30
+
31
+ API changes ship independently—updating the skill ensures you have the latest commands and workflows.
32
+
33
+ ## Setup
34
+
35
+ Before using this skill, ensure:
36
+
37
+ 1. **API Key**: Run the setup command to configure your API key securely
38
+ - Get your key at https://typefully.com/?settings=api
39
+ - Run: `typefully setup`
40
+ - Or set environment variable: `export TYPEFULLY_API_KEY=your_key`
41
+
42
+ 2. **Requirements**: Node.js 18+. Install the CLI with `npm install -g typefully` or run via `npx typefully`.
43
+
44
+ **Config priority** (highest to lowest):
45
+ 1. `TYPEFULLY_API_KEY` environment variable
46
+ 2. `./.typefully/config.json` (project-local, in user's working directory)
47
+ 3. `~/.config/typefully/config.json` (user-global)
48
+
49
+ ### Handling "API key not found" errors
50
+
51
+ **CRITICAL**: When you receive an "API key not found" error from the CLI:
52
+
53
+ 1. **Tell the user to run the setup command** - The setup is interactive and requires user input, so you cannot run it on their behalf:
54
+ ```bash
55
+ typefully setup
56
+ ```
57
+
58
+ 2. **Stop and wait** - After telling the user to run setup, **do not continue with the task**. You cannot create drafts, upload media, or perform any API operations without a valid API key. Wait for the user to complete setup and confirm before proceeding.
59
+
60
+ 3. **DO NOT** attempt any of the following:
61
+ - Searching for API keys in macOS Keychain, `.env` files, or other locations
62
+ - Grepping through config files or directories
63
+ - Looking in the user's Trash or other system folders
64
+ - Constructing complex shell commands to find credentials
65
+ - Drafting content or preparing posts before setup is complete
66
+
67
+ The setup command will interactively guide the user through configuration. Trust the CLI's error messages and follow their instructions.
68
+
69
+ ## Social Sets
70
+
71
+ The Typefully API uses the term "social set" to refer to what users commonly call an "account". A social set contains the connected social media platforms (X, LinkedIn, Threads, etc.) for a single identity.
72
+
73
+ **The CLI supports a default social set** - once configured, most commands work without specifying the social_set_id.
74
+
75
+ **You can pass the social set either way**:
76
+ - Positional: `typefully drafts list 123`
77
+ - Flag: `typefully drafts list --social-set-id 123`
78
+
79
+ When determining which social set to use:
80
+
81
+ 1. **Check for a configured default first** - Run `typefully config show` to see if a default is already set:
82
+ ```bash
83
+ typefully config show
84
+ ```
85
+ If `default_social_set` is configured, the CLI uses it automatically when you omit the social_set_id.
86
+
87
+ 2. **Check project context** - Look for configuration in project files like `CLAUDE.md` or `AGENTS.md`:
88
+
89
+ ```markdown
90
+ ## Typefully
91
+ Default social set ID: 12345
92
+ ```
93
+
94
+ 3. **Single social set shortcut** - If the user only has one social set and no default is configured, use it automatically
95
+
96
+ 4. **Multiple social sets, no default** - Ask the user which to use, then **offer to save their choice as the default**:
97
+ ```bash
98
+ typefully config set-default
99
+ ```
100
+ This command lists available social sets and saves the choice to the config file.
101
+
102
+ 5. **Reuse previously resolved social set** - If determined earlier in the session, use it without asking again
103
+
104
+ ## Common Actions
105
+
106
+ | User says... | Action |
107
+ |--------------|--------|
108
+ | "Draft a tweet about X" | `typefully drafts create --text "..."` (uses default social set) |
109
+ | "Post this to LinkedIn" | `typefully drafts create --platform linkedin --text "..."` |
110
+ | "Post to X and LinkedIn" (same content) | `typefully drafts create --platform x,linkedin --text "..."` |
111
+ | "X thread + LinkedIn post" (different content) | Create one draft, then `typefully drafts update` to add platform (see [Publishing to Multiple Platforms](#publishing-to-multiple-platforms)) |
112
+ | "What's scheduled?" | `typefully drafts list --status scheduled` |
113
+ | "Show my recent posts" | `typefully drafts list --status published` |
114
+ | "Schedule this for tomorrow" | `typefully drafts create ... --schedule "2025-01-21T09:00:00Z"` |
115
+ | "Post this now" | `typefully drafts create ... --schedule now` or `typefully drafts publish <draft_id> --use-default` |
116
+ | "Add notes/ideas to the draft" | `typefully drafts create ... --scratchpad "Your notes here"` |
117
+ | "Check available tags" | `typefully tags list` |
118
+
119
+ ## Workflow
120
+
121
+ Follow this workflow when creating posts:
122
+
123
+ 1. **Check if a default social set is configured**:
124
+ ```bash
125
+ typefully config show
126
+ ```
127
+ If `default_social_set` shows an ID, skip to step 3.
128
+
129
+ 2. **If no default, list social sets** to find available options:
130
+ ```bash
131
+ typefully social-sets list
132
+ ```
133
+ If multiple exist, ask the user which to use and offer to set it as default:
134
+ ```bash
135
+ typefully config set-default
136
+ ```
137
+
138
+ 3. **Create drafts** (social_set_id is optional if default is configured):
139
+ ```bash
140
+ typefully drafts create --text "Your post"
141
+ ```
142
+ Note: If `--platform` is omitted, the first connected platform is auto-selected.
143
+
144
+ **For multi-platform posts**: See [Publishing to Multiple Platforms](#publishing-to-multiple-platforms) — always use a single draft, even when content differs per platform.
145
+
146
+ 4. **Schedule or publish** as needed
147
+
148
+ ## Working with Tags
149
+
150
+ Tags help organize drafts within Typefully. **Always check existing tags before creating new ones**:
151
+
152
+ 1. **List existing tags first**:
153
+ ```bash
154
+ typefully tags list
155
+ ```
156
+
157
+ 2. **Use existing tags when available** - if a tag with the desired name already exists, use it directly when creating drafts:
158
+ ```bash
159
+ typefully drafts create --text "..." --tags existing-tag-name
160
+ ```
161
+
162
+ 3. **Only create new tags if needed** - if the tag doesn't exist, create it:
163
+ ```bash
164
+ typefully tags create --name "New Tag"
165
+ ```
166
+
167
+ **Important**: Tags are scoped to each social set. A tag created for one social set won't appear in another.
168
+
169
+ ## Publishing to Multiple Platforms
170
+
171
+ If a single draft needs to be created for different platforms, you need to make sure to create **a single draft** and not multiple drafts.
172
+
173
+ When the content is the same across platforms, create a single draft with multiple platforms:
174
+
175
+ ```bash
176
+ # Specific platforms
177
+ typefully drafts create --platform x,linkedin --text "Big announcement!"
178
+
179
+ # All connected platforms
180
+ typefully drafts create --all --text "Posting everywhere!"
181
+ ```
182
+
183
+ **IMPORTANT**: When content should be tailored (e.g., X thread with a LinkedIn post version), **still use a single draft** — create with one platform first, then update to add the other:
184
+
185
+ ```bash
186
+ # 1. Create draft with the primary platform first
187
+ typefully drafts create --platform linkedin --text "Excited to share our new feature..."
188
+ # Returns: { "id": "draft-123", ... }
189
+
190
+ # 2. Update the same draft to add another platform with different content
191
+ typefully drafts update draft-123 --platform x --text "Thread time!
192
+
193
+ ---
194
+
195
+ Here's what we shipped and why it matters..." --use-default
196
+ ```
197
+
198
+ So make sure to NEVER create multiple drafts unless the user explicitly wants separate drafts for each platform.
199
+
200
+ ## Commands Reference
201
+
202
+ ### User & Social Sets
203
+
204
+ | Command | Description |
205
+ |---------|-------------|
206
+ | `typefully me` | Get authenticated user info |
207
+ | `typefully social-sets list` | List all social sets you can access |
208
+ | `typefully social-sets get <id>` | Get social set details including connected platforms |
209
+
210
+ ### Drafts
211
+
212
+ All drafts commands support an optional `[social_set_id]` positional argument or `--social-set-id <id>` flag — if omitted, the configured default is used.
213
+ **Safety note**: For commands that take `[social_set_id] <draft_id>`, if you pass only a single argument (the draft_id) while a default social set is configured, you must add `--use-default` to confirm intent.
214
+
215
+ | Command | Description |
216
+ |---------|-------------|
217
+ | `typefully drafts list [social_set_id]` | List drafts (add `--status scheduled` to filter, `--sort` to order) |
218
+ | `typefully drafts get [social_set_id] <draft_id>` | Get a specific draft with full content (single-arg requires `--use-default` if a default is configured) |
219
+ | `typefully drafts create [social_set_id] --text "..."` | Create a new draft (auto-selects platform) |
220
+ | `typefully drafts create [social_set_id] --platform x --text "..."` | Create a draft for specific platform(s) |
221
+ | `typefully drafts create [social_set_id] --all --text "..."` | Create a draft for all connected platforms |
222
+ | `typefully drafts create [social_set_id] --file <path>` | Create draft from file content |
223
+ | `typefully drafts create ... --media <media_ids>` | Create draft with attached media |
224
+ | `typefully drafts create ... --reply-to <url>` | Reply to an existing X post |
225
+ | `typefully drafts create ... --community <id>` | Post to an X community |
226
+ | `typefully drafts create ... --share` | Generate a public share URL for the draft |
227
+ | `typefully drafts create ... --scratchpad "..."` | Add internal notes/scratchpad to the draft |
228
+ | `typefully drafts update [social_set_id] <draft_id> --text "..."` | Update an existing draft (single-arg requires `--use-default` if a default is configured) |
229
+ | `typefully drafts update [social_set_id] <draft_id> --tags "tag1,tag2"` | Update tags on an existing draft (content unchanged) |
230
+ | `typefully drafts update ... --share` | Generate a public share URL for the draft |
231
+ | `typefully drafts update ... --scratchpad "..."` | Update internal notes/scratchpad |
232
+ | `typefully drafts update [social_set_id] <draft_id> --append --text "..."` | Append to existing thread |
233
+
234
+ ### Scheduling & Publishing
235
+
236
+ **Safety note**: These commands require `--use-default` when using the default social set with a single argument (to prevent accidental operations from ambiguous syntax).
237
+
238
+ | Command | Description |
239
+ |---------|-------------|
240
+ | `typefully drafts delete <social_set_id> <draft_id>` | Delete a draft (explicit IDs) |
241
+ | `typefully drafts delete <draft_id> --use-default` | Delete using default social set |
242
+ | `typefully drafts schedule <social_set_id> <draft_id> --time next-free-slot` | Schedule to next available slot |
243
+ | `typefully drafts schedule <draft_id> --time next-free-slot --use-default` | Schedule using default social set |
244
+ | `typefully drafts publish <social_set_id> <draft_id>` | Publish immediately |
245
+ | `typefully drafts publish <draft_id> --use-default` | Publish using default social set |
246
+
247
+ ### Tags
248
+
249
+ | Command | Description |
250
+ |---------|-------------|
251
+ | `typefully tags list [social_set_id]` | List all tags |
252
+ | `typefully tags create [social_set_id] --name "Tag Name"` | Create a new tag |
253
+
254
+ ### Media
255
+
256
+ | Command | Description |
257
+ |---------|-------------|
258
+ | `typefully media upload <file_path> [social_set_id]` | Upload media, wait for processing, return ready media_id |
259
+ | `typefully media upload <file_path> --no-wait` | Upload and return immediately (use media status to poll) |
260
+ | `typefully media upload <file_path> --timeout <seconds>` | Set custom timeout (default: 60) |
261
+ | `typefully media status <media_id> [social_set_id]` | Check media upload status |
262
+
263
+ ### Setup & Configuration
264
+
265
+ | Command | Description |
266
+ |---------|-------------|
267
+ | `typefully setup` | Interactive setup - prompts for API key, storage location, and default social set |
268
+ | `typefully setup --key <key> --location <global\|local>` | Non-interactive setup for scripts/CI (auto-selects default if only one social set) |
269
+ | `typefully setup --key <key> --default-social-set <id>` | Non-interactive setup with explicit default social set |
270
+ | `typefully setup --key <key> --no-default` | Non-interactive setup, skip default social set selection |
271
+ | `typefully config show` | Show current config, API key source, and default social set |
272
+ | `typefully config set-default [social_set_id]` | Set default social set (interactive if ID omitted) |
273
+
274
+ ## Examples
275
+
276
+ ### Set up default social set
277
+ ```bash
278
+ # Check current config
279
+ typefully config show
280
+
281
+ # Set default (interactive - lists available social sets)
282
+ typefully config set-default
283
+
284
+ # Set default (non-interactive)
285
+ typefully config set-default 123 --location global
286
+ ```
287
+
288
+ ### Create a tweet (using default social set)
289
+ ```bash
290
+ typefully drafts create --text "Hello, world!"
291
+ ```
292
+
293
+ ### Create a tweet with explicit social_set_id
294
+ ```bash
295
+ # Positional
296
+ typefully drafts create 123 --text "Hello, world!"
297
+
298
+ # Flag
299
+ typefully drafts create --social-set-id 123 --text "Hello, world!"
300
+ ```
301
+
302
+ ### Create a cross-platform post (specific platforms)
303
+ ```bash
304
+ typefully drafts create --platform x,linkedin,threads --text "Big announcement!"
305
+ ```
306
+
307
+ ### Create a post on all connected platforms
308
+ ```bash
309
+ typefully drafts create --all --text "Posting everywhere!"
310
+ ```
311
+
312
+ ### Create and schedule for next slot
313
+ ```bash
314
+ typefully drafts create --text "Scheduled post" --schedule next-free-slot
315
+ ```
316
+
317
+ ### Create with tags
318
+ ```bash
319
+ typefully drafts create --text "Marketing post" --tags marketing,product
320
+ ```
321
+
322
+ ### List scheduled posts sorted by date
323
+ ```bash
324
+ typefully drafts list --status scheduled --sort scheduled_date
325
+ ```
326
+
327
+ ### Reply to a tweet
328
+ ```bash
329
+ typefully drafts create --platform x --text "Great thread!" --reply-to "https://x.com/user/status/123456"
330
+ ```
331
+
332
+ ### Post to an X community
333
+ ```bash
334
+ typefully drafts create --platform x --text "Community update" --community 1493446837214187523
335
+ ```
336
+
337
+ ### Create draft with share URL
338
+ ```bash
339
+ typefully drafts create --text "Check this out" --share
340
+ ```
341
+
342
+ ### Create draft with scratchpad notes
343
+ ```bash
344
+ typefully drafts create --text "Launching next week!" --scratchpad "Draft for product launch. Coordinate with marketing team before publishing."
345
+ ```
346
+
347
+ ### Upload media and create post with it
348
+ ```bash
349
+ # Single command handles upload + polling - returns when ready!
350
+ typefully media upload ./image.jpg
351
+ # Returns: {"media_id": "abc-123-def", "status": "ready", "message": "Media uploaded and ready"}
352
+
353
+ # Create post with the media attached
354
+ typefully drafts create --text "Check out this image!" --media abc-123-def
355
+ ```
356
+
357
+ ### Upload multiple media files
358
+ ```bash
359
+ # Upload each file (each waits for processing)
360
+ typefully media upload ./photo1.jpg # Returns media_id: id1
361
+ typefully media upload ./photo2.jpg # Returns media_id: id2
362
+
363
+ # Create post with multiple media (comma-separated)
364
+ typefully drafts create --text "Photo dump!" --media id1,id2
365
+ ```
366
+
367
+ ### Add media to an existing draft
368
+ ```bash
369
+ # Upload media
370
+ typefully media upload ./new-image.jpg # Returns media_id: xyz
371
+
372
+ # Update draft with media (456 is the draft_id)
373
+ typefully drafts update 456 --text "Updated post with image" --media xyz --use-default
374
+ ```
375
+
376
+ ### Setup (interactive)
377
+ ```bash
378
+ typefully setup
379
+ ```
380
+
381
+ ### Setup (non-interactive, for scripts/CI)
382
+ ```bash
383
+ # Auto-selects default social set if only one exists
384
+ typefully setup --key typ_xxx --location global
385
+
386
+ # With explicit default social set
387
+ typefully setup --key typ_xxx --location global --default-social-set 123
388
+
389
+ # Skip default social set selection entirely
390
+ typefully setup --key typ_xxx --no-default
391
+ ```
392
+
393
+ ## Platform Names
394
+
395
+ Use these exact names for the `--platform` option:
396
+ - `x` - X (formerly Twitter)
397
+ - `linkedin` - LinkedIn
398
+ - `threads` - Threads
399
+ - `bluesky` - Bluesky
400
+ - `mastodon` - Mastodon
401
+
402
+ ## Draft URLs
403
+
404
+ Typefully draft URLs contain the social set and draft IDs:
405
+ ```
406
+ https://typefully.com/?a=<social_set_id>&d=<draft_id>
407
+ ```
408
+
409
+ Example: `https://typefully.com/?a=12345&d=67890`
410
+ - `a=12345` → social_set_id
411
+ - `d=67890` → draft_id
412
+
413
+ ## Draft Scratchpad
414
+
415
+ **When the user explicitly asks to add notes, ideas, or anything else in the draft scratchpad, use the `--scratchpad` flag—do NOT write to local files!**
416
+
417
+ The `--scratchpad` option attaches internal notes directly to the Typefully draft. These notes:
418
+ - Are visible in the Typefully UI alongside the draft
419
+ - Stay attached to the draft permanently
420
+ - Are private and never published to social media
421
+ - Are perfect for storing thread expansion ideas, research notes, context, etc.
422
+
423
+ ```bash
424
+ # CORRECT: Notes attached to the draft in Typefully
425
+ typefully drafts create --social-set-id 123 --text "My post" --scratchpad "Ideas for expanding: 1) Add stats 2) Include quote"
426
+
427
+ # WRONG: Do NOT write notes to local files when the user wants them in Typefully
428
+ # Writing to /tmp/scratchpad/ or any local file is NOT the same thing
429
+ ```
430
+
431
+ ## Automation Guidelines
432
+
433
+ When automating posts, especially on X, follow these rules to keep accounts in good standing:
434
+
435
+ - **No duplicate content** across multiple accounts
436
+ - **No unsolicited automated replies** - only reply when explicitly requested by the user
437
+ - **No trending manipulation** - don't mass-post about trending topics
438
+ - **No fake engagement** - don't automate likes, reposts, or follows
439
+ - **Respect rate limits** - the API has rate limits, don't spam requests
440
+ - **Drafts are private** - content stays private until published or explicitly shared
441
+
442
+ When in doubt, create drafts for user review rather than publishing directly.
443
+
444
+ **Publishing confirmation**: Unless the user explicitly asks to "publish now" or "post immediately", always confirm before publishing. Creating a draft is safe; publishing is irreversible and goes public instantly.
445
+
446
+ ## Tips
447
+
448
+ - **Smart platform default**: If `--platform` is omitted, the first connected platform is auto-selected
449
+ - **All platforms**: Use `--all` to post to all connected platforms at once
450
+ - **Character limits**: X (280), LinkedIn (3000), Threads (500), Bluesky (300), Mastodon (500)
451
+ - **Thread creation**: Use `---` on its own line to split into multiple posts (thread)
452
+ - **Scheduling**: Use `next-free-slot` to let Typefully pick the optimal time
453
+ - **Cross-posting**: List multiple platforms separated by commas: `--platform x,linkedin`
454
+ - **Draft titles**: Use `--title` for internal organization (not posted to social media)
455
+ - **Draft scratchpad**: Use `--scratchpad` to attach notes to the draft in Typefully (NOT local files!) - perfect for thread ideas, research, context
456
+ - **Read from file**: Use `--file ./post.txt` instead of `--text` to read content from a file
457
+ - **Sorting drafts**: Use `--sort` with values like `created_at`, `-created_at`, `scheduled_date`, etc.
458
+ - **JSON output**: Add `--json` to any command for raw JSON output (useful for scripting)