Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ This repository contains AI agent skills for Typefully - markdown files that giv

## Repository Structure

- `skills/typefully/SKILL.md` - The main skill definition file with frontmatter metadata and usage instructions
- `skills/typefully/SKILL.md` - The main skill definition file with frontmatter metadata, the every-session workflow, and the full command reference. Keep it focused; move occasional or platform-specific detail into `references/`.
- `skills/typefully/references/` - On-demand reference guides linked from SKILL.md: `setup.md`, `comments.md`, `local-development.md`, and `platforms/` (`x.md`, `linkedin.md`, `x-articles.md`). Put setup, comment-workflow, local-dev, and platform-specific instructions here so they load only when needed.
- `skills/typefully/CHANGELOG.md` - User-facing changelog for the Typefully skill/CLI
- `skills/typefully/scripts/typefully.js` - JavaScript CLI for the Typefully API v2 (zero dependencies, Node.js 18+)
- `.claude-plugin/marketplace.json` - Claude Code plugin marketplace configuration
Expand Down
15 changes: 15 additions & 0 deletions skills/typefully/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ The format is based on Keep a Changelog.

### Added

- `--api-base-url <url>` global CLI option to override the API base URL for one command; `/v2` is appended when omitted.
- Per-draft comment-thread CRUD:
- `comments:list <draft_id>` — list threads with `--platform`, `--status` (`unresolved` / `resolved` / `all`), `--limit`, `--offset` filters.
- `comments:create <draft_id> --post-index <n> --selected-text "..." --text "..."` — create a thread anchored on a span. Optional `--platform`, `--occurrence`.
Expand All @@ -28,6 +29,20 @@ The format is based on Keep a Changelog.
- `analytics:posts:list` now matches the backend analytics default: replies are excluded unless you explicitly pass `--include-replies`.
- Analytics docs and examples now explain X post analytics, X follower analytics, and the explicit reply-inclusion workflow.

## [2026-07-07]

### Added

- X Article draft support via `drafts:create` and `drafts:update` with `--platform x_article`.
- `--content-markdown <markdown>` for X Article content.
- `--cover-media-id <media_id|null>` for X Article cover images; pass the literal `null` on update to remove an existing cover.
- `X_ARTICLES.md` guide with detailed X Article payload examples, supported markdown blocks, embeds, covers, and comment workflows.
- `comments:create --platform x_article --selected-text "..." --text "..."` for comments anchored on visible X Article text without `--post-index`.

### Changed

- `--all` remains limited to connected post platforms and does not include standalone X Articles.

## [2026-03-17]

### Added
Expand Down
677 changes: 148 additions & 529 deletions skills/typefully/SKILL.md

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions skills/typefully/references/comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Comments on Drafts

> Script paths are relative to the skill root (where `SKILL.md` lives). For X Article comment specifics, see `references/platforms/x-articles.md`.

Drafts can have comment threads anchored to a selected span or to a whole paragraph. `drafts:get` returns `posts[*].text` (and X Article `content_markdown`) with inline `<typ:comment-thread>` anchors by default so you can preserve them during edits.

## Core rules

1. **Preserve every comment anchor when patching draft text.** Span anchors wrap selected text; self-closing anchors at the start of a paragraph are live comments on the whole following paragraph (not empty/resolved). When rewriting, move each anchor to the most semantically equivalent span or paragraph — never silently strip or drop anchors.
2. **Do not resolve or delete comments without explicit user instruction.** After editing text that may address feedback, ask whether to resolve the specific thread(s). "Clean up" / "tidy" / "looks addressed" never means resolve or delete.
3. **Talk about comments in plain English, not marker syntax** — e.g. "comment on the word 'constraint'". Only mention marker syntax when explaining a marker-related API error or when the user asks how anchors work.

## Default edit flow

1. `drafts:get` with anchors enabled (default).
2. Rewrite while preserving/repositioning every anchor.
3. Patch with `drafts:update --text ...` (posts) or `drafts:update --platform x_article --content-markdown ...` (X Articles), without force flags.
4. Ask whether to resolve any addressed comments.

Use `comments:list <draft_id> --status all` when you need thread ids, comment bodies, authors, or resolved status. Use `drafts:get --exclude-comment-markers` only for display, LLM context, export, or preview text that will **not** be patched back.

When the user asks to accept/apply/address a comment: fetch with anchors, edit only that anchor's text (or the paragraph after a self-closing paragraph anchor), preserve every other anchor and unrelated text, then `drafts:update` without force flags. Ask before resolving. If feedback is open-ended, propose wording or ask — don't invent silently. For "accept all comments", batch only changes whose anchors can all be preserved.

## Force overwrite (destructive)

`--force-overwrite-comments` resolves and strips **every** unresolved thread whose anchor is missing from the submitted text, including unrelated threads. Default: **do not use it.** If a PATCH fails because anchors don't match, re-fetch with anchors, preserve every `<typ:comment-thread>`, and patch again without force.

Only use it when anchors truly cannot be preserved (a user-requested wholesale rewrite, or an anchor with no reasonable new location). Before using it:

1. Run `comments:list <draft_id> --status unresolved`.
2. Tell the user which threads will be resolved and stripped (selected text + top comment).
3. State that this cannot be undone via the API.
4. Wait for an explicit "yes, proceed" — do not confirm and PATCH in the same turn.

## Commands

| Command | Purpose |
|---------|---------|
| `comments:list <draft_id>` | List threads. Filters: `--platform`, `--status` (`unresolved` default / `resolved` / `all`), `--limit`, `--offset` |
| `comments:create <draft_id> --post-index <n> --selected-text "..." --text "..."` | Create a thread anchored on exact post text. Optional: `--platform`, `--occurrence` |
| `comments:create <draft_id> --platform x_article --selected-text "..." --text "..."` | Create a thread on visible X Article text; omit `--post-index` |
| `comments:reply <draft_id> <thread_id> --text "..."` | Add a reply |
| `comments:resolve <draft_id> <thread_id>` | Resolve a thread — only after explicit user confirmation |
| `comments:update <draft_id> <thread_id> <comment_id> --text "..."` | Edit a comment's text (comment-author only) |
| `comments:delete <draft_id> <thread_id> [comment_id]` | Delete a thread or one comment — only after explicit user instruction |

`comments:create` requires `selected_text` to exactly match the post text (or visible X Article text with `--platform x_article`). If it repeats, pass zero-based `--occurrence`. Pass `--platform` when the draft has multiple commentable platforms or when commenting on an X Article. For LinkedIn mentions, select the entire `@[Name](urn:li:...)` substring or stay outside it.
22 changes: 22 additions & 0 deletions skills/typefully/references/local-development.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Local Development

Use this only when testing the Typefully CLI against a non-production API.

## API base override

Pass `--api-base-url <url>` to any command to target another API base for that invocation. If the URL does not end in `/v2`, the CLI appends `/v2`.

```bash
./scripts/typefully.js me:get --api-base-url http://localhost:8000
./scripts/typefully.js drafts:list --api-base-url https://localhost:8000/v2
```

## Local TLS failures

If a local HTTPS server returns `fetch failed` or `UNABLE_TO_VERIFY_LEAF_SIGNATURE`, use one of these development-only fixes:

- Trust the local certificate in the OS or development CA store.
- Use the local server's HTTP URL if it supports one.
- Keep any TLS bypass setting local to the current shell and remove it before running production API commands.

Do not commit local API URLs, API keys, or TLS bypass settings.
28 changes: 28 additions & 0 deletions skills/typefully/references/platforms/linkedin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# LinkedIn

> Script paths are relative to the skill root (where `SKILL.md` lives). Character limit: 3000.

## Mentions

LinkedIn mentions use text syntax inside post content:

```text
@[Company Name](urn:li:organization:123456)
```

Resolve a public LinkedIn organization/school URL into ready-to-paste mention syntax with `linkedin:organizations:resolve`:

```bash
./scripts/typefully.js linkedin:organizations:resolve --organization-url "https://www.linkedin.com/company/typefullycom/"
# Returns mention_text like: @[Typefully](urn:li:organization:86779668)
```

Then include the returned `mention_text` in the draft:

```bash
./scripts/typefully.js drafts:create --platform linkedin --text "Thanks @[Typefully](urn:li:organization:86779668) for the support."
```

`linkedin:organizations:resolve [social_set_id] --organization-url <url>` returns `mention_text` and `urn`.

> When commenting on text that contains a mention, select the entire `@[Name](urn:li:...)` substring or stay fully outside it.
Loading
Loading