superx-cli 0.3.0 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.0 (2026-09-11)
4
+
5
+ - Playbooks: a new `PLAYBOOKS.md` ships with the package, holding 28 goal-shaped recipes, one per SuperX skill (weekly recap, week of posts, queue reshuffle, reply sprint, lead hunt, audience export, warm outreach and the rest). Each entry gives the CLI chain in order, the equivalent MCP tool chain, and where the chain STOPS: the four that stop short of a send say so in the entry, because no reply is posted and no DM is delivered from here. `SKILL.md` gains a `## Playbooks` index so an agent can pick a recipe by goal before opening the file
6
+ - DM campaigns: `dm:campaign --recipients <file>` (or `--recipients=-` for stdin) `--message` queues direct messages to up to 100 X users, `dm:campaign-status <id>` shows the counts per status, `dm:queue` lists the whole queue (`--status`, `--campaign`), `dm:cancel <id>` removes a campaign's unsent messages and `dm:limits` shows the account's allowances. NOTHING IS SENT BY THESE COMMANDS: the messages go into the account's own DM queue and the SuperX app's scheduler sends them within its daily and monthly DM limits, so the reply is counts, not deliveries. People messaged in the last 24 hours are skipped, the account never messages itself, `[name]` / `[first]` / `[handle]` are filled per recipient, and `--spread` places what today's allowance cannot hold over the coming days. Costs no AI credits
7
+ - Auto DM on scheduled posts: `scheduled:create` and `scheduled:update` gain `--auto-dm-message`, `--auto-dm-triggers reply,repost`, `--auto-dm-max`, `--auto-dm-batch` and `--no-auto-dm`. The DM goes to the people who reply to or repost the post once it is live. Omit the flags and the post keeps inheriting your Default Post Settings; your plan caps how many posts a month may carry one, and when that cap strips it the post is still created and the response carries `auto_dm_skipped: true`
8
+
9
+ - Reply drafts: `engage:reply-draft` writes ONE reply to a post in your own voice, using the same engine and voice settings as the Generate Reply button in the app. Name the post with `--post <id>` (read live, so the draft sees the real text and author) or paste it yourself with `--text` (plus `--author`, `--handle`); `--thoughts` says what the reply should convey and `--tone` sets the register. The draft is TEXT: nothing is posted or sent, a person reviews it and posts it. Costs AI credits (measured, typically 2: the reply write plus the shared post-editor pass); `--post` also spends one live X lookup
10
+ - Remix: `posts:remix --text --closeness 0-100` rewrites a post in your voice, from a loose reinterpretation (0) to very close to the original wording (100), with optional `--instructions`. Returns TEXT only: save it with `posts:draft` or `scheduled:create` when you are happy with it. Costs AI credits (measured, typically 2)
11
+ - Composer tools: `tools:inline-edit --text [--full] [--instruction] [--type]` edits one selected piece of a post while keeping the surrounding style, `tools:rephrase --type --text` applies one preset rewrite (the style presets use your voice, the mechanical ones do not), `tools:factcheck --text` checks a statement against a web search and reports true, false or unknown with its sources, and `tools:predict --a --b` scores two versions of a post against what the timeline tends to reward. All four return TEXT and post nothing; each costs AI credits (measured, typically 1)
12
+ - Style guide: `context:regenerate-style-guide` rebuilds the account's GENERATED style guide from its recent posts, the guide every writing command reads. FREE (no AI credits) and limited to once an hour per account. Your manual overrides (`context:set --style-audience` / `--style-vocabulary`) are untouched and keep outranking it, so clear them first if you want the new guide to show. An account with fewer than 5 recent posts stored has them read live, under the platform fair-use ceiling; still too few returns 400 `not_enough_posts`
13
+ - Product refresh: `context:scrape-product <id>` re-reads a saved product's page and refreshes its stored name, description and details. The url comes from the SAVED product, so fix a moved url with `context:products:set --id` first. FREE, on the account's 20 page reads a day shared with the SuperX app; a page that cannot be read returns 422 `scrape_failed`
14
+ - Signal agent prefill: `signals:suggest-keywords --icp` turns an audience description into 2 or 3 keyword-watch ideas, and `signals:expand-icp (--text | --url)` builds the rubric the scorer reads an ICP as. Both are FREE and create nothing: pass a suggestion to `signals:create-agent --keyword`, and use the rubric to sharpen the `--icp` text (there is no field to save it into). `--url` reads a website and also returns an `icp_description` you can pass straight to `--icp`, on the same 20 page reads a day
15
+ - Article covers: `articles:cover` now costs a FLAT 25 AI credits per generation on the API, whatever the render actually costs, and the response carries `X-Credits-Charged: 25` plus `meta.credits_charged`. The account's daily and monthly cover caps are unchanged. A generation that times out keeps the charge because the cover may well have landed, so read the article before retrying; a generation that fails outright is refunded in full
16
+ - Lead search: `signals:search --keywords --icp` runs ONE live keyword search over X now, scored against the ideal customer profile, and returns the leads inline (`--precision high|discovery`, `--max` 1-30). It CREATES NOTHING: no signal agent, no stored leads, so keep what you need from the response and use `signals:create-agent` when the user wants leads to keep arriving. It still needs a key with the `write` scope, like every non-GET API route. Takes up to a minute, costs AI credits (measured, at least 1 for a search that reaches X) plus one of the plan's daily lead searches
17
+ - Profile research: `datasets:research` turns people into outreach briefs saved as a dataset - exactly one of `--handles` (comma list, max 25), `--list`, `--agent` or `--dataset`, with `--max` 1-25, `--focus` and `--title`. Every hook QUOTES one of the person's real posts (proposed quotes that fail the verbatim check are dropped server-side). Costs a flat 1 AI credit per profile actually researched, the rest returned, plus one of the plan's daily research runs; more than 5 profiles run in the background, so pass `--wait` to poll until they are ready
18
+ - Outreach drafts: `datasets:outreach-drafts <id> --format` writes one personalized message per person in a research dataset, following the user's template or example (`--instructions` for extra steer). The drafts are TEXT: they are stored on the dataset (read them with `datasets:rows`) and a person sends them from the SuperX app. Nothing in the CLI sends a DM. `[name]`, `[first]` and `[handle]` tokens are kept for per-recipient fill-in at send time, a brief with no usable hook gets an honest generic message, and a draft naming a different recipient is discarded and counted in `contaminated`
19
+ - Dataset refinement: `datasets:refine <id> --criterion` filters a dataset by what each person WROTE into a NEW dataset (`--no-keep` inverts, `--sort followers|likes|none`, `--limit`, `--title`, `--wait`). The source dataset is untouched, rows the classifier cannot judge are KEPT and counted as `unclear`, and only datasets whose rows carry text (repliers, quoters) can be refined. It creates a dataset, so it counts against the same 10 collections a day, and costs AI credits (measured)
20
+ - Action limits: `429 ai_action_limited` now carries `scope` and `reset_at`. `scope: "account"` is your plan's own daily cap for that action; `scope: "platform"` is a fair-use ceiling on live-data actions shared by every SuperX account, so your own allowance is untouched and the fix is to wait for `reset_at` and retry
21
+
22
+ - Audience lists: `audience:list <kind>` reads a page of your `followers`, `following`, `repliers` or `reposters` from SuperX's synced snapshot (`--limit` 1-100, `--cursor`, `--account`). These are the four system lists in the app's Contacts tab, which `lists:members` does not serve. Paging is by CURSOR, not page number: pass `pagination.next_cursor` back as `--cursor`. There is no `total` - `meta.synced_count` is the size of the whole list, and `meta` also carries the sync `status`, the plan's `backfill_cap` and `is_capped` (follow lists) or `window_days: 90` (repliers and reposters, a rolling window someone ages out of)
23
+ - Mentions: `engage:mentions` reads the posts @-mentioning you right now, newest first (`--sort top` ranks by engagement), each with the post it replies to and one further level of ancestry. `mention_type` separates a direct reply to one of your posts from any other @-mention, and `--include-replied` keeps mentions you already answered on X, flagged `replied`. One call costs 3 of the daily feed fetches, so read a page and work from it rather than polling; page with `--cursor`. The app's Mentions tab also hides posts you skipped or blocked there - that is an app preference and is not applied here
24
+ - Audience collection: `datasets:collect --source repliers|quoters|reposters|list_members|my_posts|my_replies` builds a new dataset (`--target` the post or X list, `--title`, `--max-rows`, filters `--keywords`, `--bio-keywords`, `--min-followers`, `--require-website`, `--require-can-dm`, `--since-days`, `--sort`). A small collection finishes in the call; a big one comes back with `status: "collecting"` and keeps running in the background, so pass `--wait` to poll `datasets:get` every 5 seconds until it is ready (up to 15 minutes). Costs one of 10 collections a day shared with the collections Ask SuperX runs in the app (429 `collection_quota_exceeded`), plus enrichment for the pages walked; `my_posts` and `my_replies` cost no enrichment. One background collection per account (409 `collection_in_progress`), and nothing matching means no dataset is created
25
+ - Publish now: `posts:publish` publishes a post or thread to X immediately (same content, media and advanced-settings flags as `scheduled:create`, minus `--at`/`--title`/`--scratchpad`). `--idempotency-key` is REQUIRED because publishing cannot be undone: reuse the same key on a retry and the original result comes back instead of a second post, and a retry that lands while the first attempt is still publishing returns 409 `idempotency_in_flight` with a `Retry-After`. The result carries `status: "sent"`, `posted_at`, `x_post_id` and `url`, and advanced settings and Auto DM inherit the account's Default Post Settings exactly like a scheduled post
26
+ - Bulk queue operations: `scheduled:bulk-retime --moves-json` moves up to 500 queued posts in one transaction, `scheduled:bulk-auto-retweet --ids --auto-retweet <h> [--auto-retweet-remove <h>]` turns Auto Retweet on for up to 100 posts that do not already have it, and `scheduled:bulk-delete --ids` deletes up to 100 queued posts and refunds their post quota. All three touch QUEUED posts only: drafts, sent posts and error rows are counted as skipped, so the returned counts can be lower than the number of ids sent
27
+ - Engage feed writes: `engage:feeds:create --name` with one source (`--keyword`, repeatable, `--x-list` for a public X list id or link, or `--list-id` for one of your contact lists), `engage:feeds:update <feedId>` to rename or point a feed somewhere else (one source at a time; a feed may change type and keeps its id), and `engage:feeds:delete <feedId>`. A feed you create does NOT become the feed the SuperX app has open, up to 8 feeds per account, and an X list source is looked up live so those calls also draw on the enrichment allowance (public lists only)
28
+ - Signal agent edits: `signals:update-agent <id>` changes `--name`, `--icp`, `--precision`, `--list-id` or `--status` (leads already found keep their scores). `signals:add-signal <id> --type` adds one thing to watch (`keyword_watch --query`, `profile_watch`/`follower_watch --handle`, `list_watch --list`) and `signals:remove-signal <id> <signalId>` removes one. `signals:create-agent` gains repeatable `--signal "type:target"` for the non-keyword types, combined with `--keyword` to at most 5 entries; entries that fail come back in `warnings` and the agent is still created
29
+ - Lead feedback: `signals:feedback <leadId> --fit|--not-fit|--clear` records your verdict on one lead (the numeric id from `signals:leads`, not an X user id). The verdict trains the scorer and is mirrored onto the person's row in the agent's destination list, so record it on leads you actually reviewed
30
+ - Article cover styles: `articles:cover-styles` lists the cover styles saved in the app, and `articles:cover <id> --style-id <id>` renders in one of them (not with `--style`, which stays the one-off description form)
31
+ - Sent replies: `replies:list` page 1 now also lists replies sent from the SuperX app's Engage tab in the last 4 hours, which previously took hours to appear. Those items carry `metrics_pending: true` and zero metrics until X reports them, and page 1 can hold slightly more items than `--limit`; later pages and `--since`/`--until` queries are unchanged
32
+ - Credits: `superx status` now prints a `credits` block (`remaining`, `pool`, `period`, `period_end`, `bonus`) alongside plan and rate limits, so you can check the AI credit pool before running a paid command. Paid responses also carry `X-Credits-Charged`, `X-Credits-Remaining` and `X-Credits-Reset` headers, and an exhausted pool returns `429 ai_credits_exhausted` with `credits_required`, `credits_remaining` and `reset_at`
33
+ - Drafting: `posts:draft` writes post drafts in your own voice from a brief (`--brief` required, `--count` 1-3, `--voice mine|creator|hybrid` with `--creator @handle`, `--mirror` the text of a proven post whose shape to copy, `--collection` to bias the picked shape, `--instructions`, `--account`). Nothing is scheduled and nothing is saved: the text comes back for you to review, then pass the final version to `scheduled:create`. Each draft costs AI credits and failed drafts are refunded
34
+ - Contacts: `contacts:get <id>` shows one person's stored profile, follower counts and the lists they are in (`--refresh` refreshes a stale profile from X and counts against the tighter enrichment limit). `contacts:notes <id>`, `contacts:notes:add <id> --body`, `contacts:notes:update <id> <noteId> --body` and `contacts:notes:delete <id> <noteId>` manage the private notes on a contact; notes live inside SuperX, are never posted, and are attributed to the account you wrote as
35
+ - Contact list writes: `lists:create --name`, `lists:rename <id> --name` and `lists:delete <id>` manage the lists themselves (system lists stay read-only; deleting a list stops any signal agent depositing into it until it is repointed in the app). `lists:add-members <id> --x-user-ids a,b,c` adds up to 500 people in one call and `lists:remove-members <id> --member-ids a,b` removes up to 500. Bulk add does no live lookup, so it costs one write and no enrichment: ids SuperX has never seen come back in `not_found` and are NOT added - add those with `lists:add-member --handle`
36
+ - Products: `context:products:replace --json '[...]'` replaces the WHOLE product list (max 5). CAUTION: any product whose url is missing from the array is removed; use `context:products:set` to change one product in place
37
+ - Datasets: `datasets:list` shows the audience collections Ask SuperX built in the app (repliers, quoters, reposters, list members, your own posts or replies, research briefs), `datasets:get <id>` reads one dataset's status, counts and coverage, `datasets:rows <id>` pages its rows exactly as they were collected, `datasets:export <id>` downloads it as CSV (`--out` for the file, `--out -` to stream to stdout; XLSX stays an in-app download), and `datasets:add-to-list <id> --list-id` copies the people in one into a contact list you created (one write, no enrichment, deduped by X account id; rows without one come back in `skipped_without_id`). Datasets are kept for 30 days and are created in the SuperX app for now; rows, export and add-to-list need `status: "ready"` and otherwise return `409 dataset_not_ready`
38
+ - Live X lookups: `x:post <id|url>` reads one public post live (`--quotes` also fetches a page of the posts quoting it), `x:replies <id|url>` returns the best-liked direct replies from up to 3 relevance-ranked pages (`--limit` 1-20; a sample, never the full reply list, and the account owner's own replies are NOT filtered out), `x:user <handle>` reads one public profile live, and `x:user-posts <handle>` returns one live timeline page newest first (`--limit`, `--no-reposts`). These cost the tighter enrichment allowance (1 unit each, 3 for `x:replies`, 2 for `x:post --quotes` or an `x:user-posts` handle SuperX has never seen) and share an allowance of 300 live lookups a day with Ask SuperX in the app, returning `429 lookup_quota_exceeded` over it. Repeats within 15 minutes may come from a server-side cache
39
+ - Inspiration media: `inspiration:media [query]` searches the cross-platform media index behind the app's Inspiration > Media tab (`--platforms`, `--time-filter`, `--media-type`, `--content-type`, `--limit`). With no query it browses the newest media instead of searching, and unlike the app it is not personalised. No media file URLs are returned: `source_url` opens the original post on its own platform. Costs no enrichment
40
+ - Skill layout: removed the duplicate `skills/superx/SKILL.md`; the root `SKILL.md` is the single skill entrypoint for `npx skills add`, the Claude plugin manifests and the npm package, so hosts that discover skills recursively no longer list SuperX twice (thanks @lukemaj, #1)
41
+
3
42
  ## 0.3.0 (2026-09-05)
4
43
 
5
44
  - Engage feeds: `engage:feeds` lists the keyword and list feeds saved in the app (with `type`, `active`, and `fetch_units`), and `engage:posts <feedId>` fetches one feed's candidate posts for review (`--account`, `--limit` 1-50, `--mode top|latest`, `--fresh`, `--include-replied`, `--exclude` comma list of post ids to page with). Read-only by design: replies are written and sent by a person in the SuperX app, so there is no reply command. `--limit` applies to keyword feeds; list feeds return one page per fetch and are paged with `--exclude`. Feed fetches have their own per-plan daily allowance and a list feed that rotates its members counts as 3
@@ -26,5 +65,3 @@ Initial release.
26
65
  - Clean JSON on stdout for every data command; human messages go to stderr
27
66
  - Idempotency-Key support on `scheduled:create` with replay detection
28
67
  - Agent skill (`SKILL.md`) and growth strategy guide (`PLAYBOOK.md`)
29
-
30
- Maintainer note: `SKILL.md` and `skills/superx/SKILL.md` must stay byte-identical. Edit the root file, then copy it over the nested one.
package/PLAYBOOK.md CHANGED
@@ -86,5 +86,5 @@ Verify state with `superx scheduled:list --status draft,scheduled` after every p
86
86
 
87
87
  - Drafts first when confidence is low; a human (or a later `scheduled:update --status scheduled`) can promote a draft after review. Use `--scratchpad` to leave the reasoning behind a draft where the human will see it.
88
88
  - Never fabricate metrics, quotes, or claims in content. Use real data from the CLI or say nothing.
89
- - Respect the write constraints: main account only, images only via `media:upload` (no video), UTC timestamps with explicit offset (see SKILL.md Rule 3).
89
+ - Respect the write constraints: writes work on your main account or any linked account (pass the same `--account` you used to read it), accounts other people shared with you are read-only, images only via `media:upload` (no video), UTC timestamps with explicit offset (see SKILL.md Rule 3).
90
90
  - Quality over volume, always. One post a stranger would reply to beats five posts nobody finishes reading.
package/PLAYBOOKS.md ADDED
@@ -0,0 +1,523 @@
1
+ # SuperX Playbooks
2
+
3
+ Twenty-eight goal-shaped recipes, one per SuperX skill. Each is the same job the
4
+ in-app skill of that name does, run from the CLI or from the hosted MCP server.
5
+ Pick by goal, run the chain in order, hand the result to the person.
6
+
7
+ Three rules hold in every playbook, no exceptions:
8
+
9
+ 1. **Drafts unless the person says otherwise.** `scheduled:create` without `--at` is a draft and nothing publishes.
10
+ 2. **Nothing here sends a reply or a DM.** Reply drafts are text a person posts. `dm:campaign` enqueues; the SuperX app sends.
11
+ 3. **`posts:publish` and `articles:publish` are immediate and irreversible.** Confirm the exact text with the person first, and note that `posts:publish` REQUIRES `--idempotency-key` so a retry cannot post twice.
12
+
13
+ `--account <account-id>` acts on a linked account (`superx accounts` lists the
14
+ ids). It is shown once, in the first playbook, and applies the same way to the
15
+ **account-scoped** commands: the posts, scheduled, replies, contacts, lists,
16
+ engage, signals, dm, context, queue and articles families, plus the dataset
17
+ commands that WRITE for an account (`datasets:collect`, `datasets:refine`,
18
+ `datasets:research`, `datasets:outreach-drafts`, `datasets:add-to-list`).
19
+
20
+ Some commands are **owner-scoped** and the CLI is strict, so passing `--account`
21
+ to one is an error, not a no-op. Nothing about them is per-X-account: the live
22
+ lookups `x:post`, `x:replies`, `x:user` and `x:user-posts`, the inspiration
23
+ searches `inspiration:search` and `inspiration:media`, and the dataset reads
24
+ `datasets:list`, `datasets:get`, `datasets:rows` and `datasets:export`. A few
25
+ id-addressed subcommands inside the account families are owner-scoped for the
26
+ same reason (the id already names the account), among them `articles:publish`,
27
+ `scheduled:delete` and `lists:remove-member`. When a chain here does not show
28
+ `--account`, that is deliberate; `superx <command> --help` is the check.
29
+
30
+ Accounts other people shared with you are read-only. Ids in angle brackets are
31
+ placeholders you fill from the previous step's JSON.
32
+
33
+ ---
34
+
35
+ ## Recaps and analytics
36
+
37
+ ### Weekly Growth Recap
38
+
39
+ Your week in review: follower change, the posts that worked, new leads, one pattern to repeat and one focus for next week.
40
+
41
+ ```bash
42
+ SINCE=$(date -u -v-7d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "7 days ago" +"%Y-%m-%dT00:00:00Z")
43
+ superx posts:analytics --since "$SINCE" --account <account-id>
44
+ superx posts:list --sort likes --since "$SINCE" --limit 10
45
+ superx signals:leads --since "$SINCE" --limit 20
46
+ superx replies:received --sort recent --limit 20
47
+ ```
48
+
49
+ There is no recap command: write the recap yourself from those four responses.
50
+
51
+ MCP: `get_account_overview` -> `get_post_analytics` -> `get_signal_leads` -> `get_audience_replies`
52
+
53
+ Stops at: the recap text in chat. Reads only, no AI credits.
54
+
55
+ ### Growth Plan Builder
56
+
57
+ A multi-week plan tied to the account's real numbers: cadence, a reply target, and the format to repeat.
58
+
59
+ ```bash
60
+ SINCE=$(date -u -v-90d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "90 days ago" +"%Y-%m-%dT00:00:00Z")
61
+ superx posts:analytics --since "$SINCE"
62
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 25
63
+ superx replies:list --limit 25
64
+ superx queue:get
65
+ ```
66
+
67
+ Read PLAYBOOK.md before writing the plan: the numbers say what happened, the strategy guide says what to do about it.
68
+
69
+ MCP: `get_account_overview` -> `get_post_analytics` -> `get_my_replies` -> `get_queue_settings`
70
+
71
+ Stops at: the written plan. Reads only, no AI credits. Nothing is scheduled by this playbook.
72
+
73
+ ### Post Post-Mortem
74
+
75
+ Why one post overperformed or flopped, measured against the account's own baseline.
76
+
77
+ ```bash
78
+ SINCE=$(date -u -v-30d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "30 days ago" +"%Y-%m-%dT00:00:00Z")
79
+ superx posts:list --sort posted_at --since "$SINCE" --limit 25
80
+ superx posts:analytics --since "$SINCE"
81
+ superx x:user-posts <peer-handle> --no-reposts --limit 20
82
+ ```
83
+
84
+ The third call is optional: use it only when the person names a peer account to compare against.
85
+
86
+ MCP: `get_post_analytics` -> `get_account_overview` -> `get_x_user_posts`
87
+
88
+ Stops at: the explanation in chat. Reads only. The live lookup draws on the shared 300-a-day allowance for `x:*`.
89
+
90
+ ### Top Performers Breakdown
91
+
92
+ The ranked winners, the shape they share, and what to write more of.
93
+
94
+ ```bash
95
+ SINCE=$(date -u -v-30d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "30 days ago" +"%Y-%m-%dT00:00:00Z")
96
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 25
97
+ superx posts:analytics --since "$SINCE"
98
+ ```
99
+
100
+ MCP: `get_post_analytics` -> `get_account_overview`
101
+
102
+ Stops at: the pattern read in chat. Reads only, no AI credits.
103
+
104
+ ### My Replies Report
105
+
106
+ Which of the account's replies actually earned attention, and the pattern behind them.
107
+
108
+ ```bash
109
+ superx replies:list --limit 25
110
+ ```
111
+
112
+ Page-one rows can carry `metrics_pending`: replies sent from the app in the last 4 hours have no numbers yet, so leave them out of the ranking.
113
+
114
+ MCP: `get_my_replies`
115
+
116
+ Stops at: the ranked list plus a pattern read. Reads only, no AI credits.
117
+
118
+ ---
119
+
120
+ ## Content
121
+
122
+ ### Daily Post Ideas
123
+
124
+ Two or three drafts for today, written in the account's voice and ready to schedule.
125
+
126
+ ```bash
127
+ SINCE=$(date -u -v-60d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "60 days ago" +"%Y-%m-%dT00:00:00Z")
128
+ superx scheduled:list --status draft,scheduled --limit 100
129
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 10
130
+ superx posts:draft --brief "<the angle, data or notes to write from>" --count 3
131
+ superx scheduled:create --text "<the draft the person picked>" --idempotency-key "ideas-<date>-1"
132
+ ```
133
+
134
+ `posts:draft` saves nothing. Show the drafts, let the person pick and edit, then pass the final wording to `scheduled:create`.
135
+
136
+ MCP: `get_scheduled_posts` -> `get_post_analytics` -> `draft_post` -> `schedule_post`
137
+
138
+ Stops at: a draft in the SuperX app for the person to review. Costs 3 AI credits per draft written, so ask how many they want.
139
+
140
+ ### Week of Posts
141
+
142
+ A week of varied drafts, spread across the week, one approval per post.
143
+
144
+ ```bash
145
+ SINCE=$(date -u -v-60d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "60 days ago" +"%Y-%m-%dT00:00:00Z")
146
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 10
147
+ superx queue:get
148
+ superx posts:draft --brief "<theme for the week>" --count 3
149
+ superx scheduled:create --text "<approved text>" --at "<UTC ISO-8601 with Z>" --idempotency-key "week-<n>-1"
150
+ superx scheduled:list --status scheduled --limit 100
151
+ ```
152
+
153
+ Read the queue first so the new times land on the account's real slots instead of on top of what is already there. Reuse the same `--idempotency-key` on a retry.
154
+
155
+ MCP: `get_post_analytics` -> `get_queue_settings` -> `draft_post` -> `schedule_post` -> `get_scheduled_posts`
156
+
157
+ Stops at: a queued week the person can still edit. 3 AI credits per draft written.
158
+
159
+ ### Thread Builder
160
+
161
+ An idea or rough notes turned into a thread of up to 25 parts, ready to schedule.
162
+
163
+ ```bash
164
+ superx posts:draft --brief "<the idea or notes, plus the target length>" --count 1
165
+ superx scheduled:create --part "<1/ hook>" --part "<2/ detail>" --part "<3/ close>" --idempotency-key "thread-<slug>-1"
166
+ ```
167
+
168
+ Max 25 parts and 25,000 characters in total. Repeat `--part` in posting order.
169
+
170
+ MCP: `draft_post` -> `schedule_post`
171
+
172
+ Stops at: a thread draft in the app. 3 AI credits per draft written.
173
+
174
+ ### Repurpose a Winner
175
+
176
+ The account's best post, reworked into fresh angles.
177
+
178
+ ```bash
179
+ SINCE=$(date -u -v-90d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "90 days ago" +"%Y-%m-%dT00:00:00Z")
180
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 5
181
+ superx posts:remix --text "<the winning post's text>" --closeness 70
182
+ superx scheduled:create --text "<the remix the person picked>" --idempotency-key "repurpose-<slug>-1"
183
+ ```
184
+
185
+ Standalone posts only. `--closeness 0` keeps just the idea, `100` stays very close to the original wording.
186
+
187
+ MCP: `get_post_analytics` -> `remix_post` -> `schedule_post`
188
+
189
+ Stops at: remixed text the person approves before anything is saved. A remix typically costs 2 AI credits (measured).
190
+
191
+ ### Viral Format Remix
192
+
193
+ Proven hooks and structures from a library of 50M+ high-performing posts, rewritten in the account's voice.
194
+
195
+ ```bash
196
+ superx inspiration:search "<topic>" --sort outlier --min-likes 500 --limit 10
197
+ superx posts:draft --brief "<what this account would say on that topic>" --mirror "<the reference post's text>" --count 2
198
+ superx scheduled:create --text "<approved text>" --idempotency-key "remix-<slug>-1"
199
+ ```
200
+
201
+ `--mirror` copies the SHAPE of a proven post, not its words. Pick a reference with room for the account's own facts.
202
+
203
+ MCP: `find_inspiration` -> `draft_post` -> `schedule_post`
204
+
205
+ Stops at: reference posts plus drafts, for the person to pick from. 3 AI credits per draft written.
206
+
207
+ ### Trending Now Scan
208
+
209
+ High-performing posts in the account's niche from the last 48 hours, with angles to take.
210
+
211
+ ```bash
212
+ SINCE=$(date -u -v-48H +"%Y-%m-%dT%H:00:00Z" 2>/dev/null || date -u -d "48 hours ago" +"%Y-%m-%dT%H:00:00Z")
213
+ superx inspiration:search "<topic phrase>" --since "$SINCE" --sort likes --limit 10
214
+ ```
215
+
216
+ Run it once per topic phrase rather than sweeping the whole niche.
217
+
218
+ MCP: `find_inspiration`
219
+
220
+ Stops at: the posts and the suggested angles in chat. Reads only, no AI credits.
221
+
222
+ ---
223
+
224
+ ## Queue
225
+
226
+ ### Cadence & Queue Audit
227
+
228
+ Gaps and pile-ups in the queue, a cadence verdict, and the reschedules to make.
229
+
230
+ ```bash
231
+ superx queue:get
232
+ superx scheduled:list --status scheduled --limit 100
233
+ SINCE=$(date -u -v-30d +"%Y-%m-%dT00:00:00Z" 2>/dev/null || date -u -d "30 days ago" +"%Y-%m-%dT00:00:00Z")
234
+ superx posts:list --type posts --sort likes --since "$SINCE" --limit 25
235
+ superx scheduled:update <post-id> --at "<UTC ISO-8601 with Z>"
236
+ ```
237
+
238
+ `--at` on its own never promotes a draft: add `--status scheduled` for that. The audit never deletes posts.
239
+
240
+ MCP: `get_queue_settings` -> `get_scheduled_posts` -> `get_post_analytics` -> `update_scheduled_post`
241
+
242
+ Stops at: the proposed moves, applied one at a time after the person agrees. Reads and one write, no AI credits.
243
+
244
+ ### Queue Reshuffle
245
+
246
+ Move and rewrite scheduled posts by asking, up to 500 in one transaction.
247
+
248
+ ```bash
249
+ superx scheduled:list --status scheduled --limit 100
250
+ superx scheduled:bulk-retime --moves-json '[{"id":"<post-id>","scheduled_for":"<UTC ISO-8601 with Z>"}]'
251
+ superx scheduled:update <post-id> --text "<new wording>"
252
+ ```
253
+
254
+ `bulk-retime` only touches QUEUED posts and answers with counts, so compare against `scheduled:list` rather than assuming every id moved. `scheduled:update --text` without `--media` drops the post's images: re-list the current `object_key`s to keep them.
255
+
256
+ MCP: `get_scheduled_posts` -> `bulk_retime_scheduled_posts` -> `update_scheduled_post`
257
+
258
+ Stops at: the retimed queue, one confirmation per change. No AI credits.
259
+
260
+ ---
261
+
262
+ ## Replies (these stop at a draft, by design)
263
+
264
+ ### Reply Sprint
265
+
266
+ The replies the account's posts got, each with a ready-to-post draft.
267
+
268
+ ```bash
269
+ superx replies:received --sort recent --limit 5
270
+ superx engage:reply-draft --text "<the reply's text>" --handle "<their handle, no @>" --thoughts "<what to convey>" --tone concise
271
+ ```
272
+
273
+ MCP: `get_audience_replies` -> `draft_reply`
274
+
275
+ Stops at: reply TEXT. **The person posts the reply**: nothing in the CLI, the API or MCP posts a reply to X. Each draft typically costs 2 AI credits (measured).
276
+
277
+ ### Reply to Any Post
278
+
279
+ Any post's context, what its top replies already said, and one strong reply draft.
280
+
281
+ ```bash
282
+ superx x:post <post-url-or-id>
283
+ superx x:replies <post-url-or-id> --limit 20
284
+ superx engage:reply-draft --post <post-id> --thoughts "<what to convey>" --tone engaging
285
+ ```
286
+
287
+ `x:replies` is a sample of the best-liked direct replies, not every reply, and it does not exclude the author's own.
288
+
289
+ MCP: `lookup_x_post` -> `get_x_post_replies` -> `draft_reply`
290
+
291
+ Stops at: reply TEXT. **The person posts the reply.** The lookups draw on the shared 300-a-day `x:*` allowance: `x:replies` spends 3 enrichment units and moves that daily counter once per page it fetches, up to 3. A reply draft named by `--post` spends one more lookup, plus typically 2 AI credits (measured).
292
+
293
+ ---
294
+
295
+ ## Leads
296
+
297
+ ### Who Is This Person?
298
+
299
+ A fast read on a public account, plus the history the SuperX account already has with them.
300
+
301
+ ```bash
302
+ superx x:user <handle>
303
+ superx x:user-posts <handle> --no-reposts --limit 20
304
+ superx contacts:get <x-user-id>
305
+ superx contacts:replies <x-user-id> --sort recent --limit 5
306
+ ```
307
+
308
+ `contacts:get` covers known contacts only: engagers, contact-list members and scored leads. A 404 there means the person is not one of them yet, not that the lookup failed.
309
+
310
+ MCP: `lookup_x_user` -> `get_x_user_posts` -> `get_contact` -> `get_contact_history`
311
+
312
+ Stops at: the profile read in chat. Reads only, on the shared 300-a-day `x:*` allowance.
313
+
314
+ ### Your Warmest Leads
315
+
316
+ The people already engaging most, ranked, with who to follow up with first.
317
+
318
+ ```bash
319
+ superx contacts:list --sort engagement --limit 50
320
+ superx contacts:replies <contact-id> --sort recent --limit 5
321
+ ```
322
+
323
+ Covers a rolling 90 days.
324
+
325
+ MCP: `get_top_contacts` -> `get_contact_history`
326
+
327
+ Stops at: the ranked list plus a suggested order. Reads only, no AI credits.
328
+
329
+ ### Instant Lead Hunt
330
+
331
+ A live search of X right now for people matching the audience described, scored, saving nothing.
332
+
333
+ ```bash
334
+ superx signals:suggest-keywords --icp "<who you want to reach>"
335
+ superx signals:search --keywords "<phrase>,<phrase>" --icp "<who you want to reach>" --max 30
336
+ ```
337
+
338
+ The search creates no agent and stores no leads, so keep what the person needs from that one response.
339
+
340
+ MCP: `suggest_keywords` -> `search_leads`
341
+
342
+ Stops at: up to 30 scored leads in chat. Costs at least 1 AI credit plus one of the plan's daily lead searches, and draws on a fair-use ceiling shared by every SuperX account. Takes up to a minute.
343
+
344
+ ### Standing Lead Agent
345
+
346
+ An agent that keeps finding leads while the person is away.
347
+
348
+ ```bash
349
+ superx signals:expand-icp --text "<who you want to reach>"
350
+ superx signals:suggest-keywords --icp "<the sharpened description>"
351
+ superx signals:create-agent --name "<agent name>" --icp "<the sharpened description>" --keyword "<phrase>" --idempotency-key "agent-<slug>-1"
352
+ superx signals:agents
353
+ superx signals:leads --agent <agent-id> --deposited false --limit 25
354
+ ```
355
+
356
+ Agent creation returns the agent, not leads: they arrive over the following minutes and days. Read `warnings` before telling the person what the agent watches, and omit `--list-id` only if you are happy with an auto-created `Leads: ...` contact list.
357
+
358
+ MCP: `expand_icp` -> `suggest_keywords` -> `create_signal_agent` -> `list_signal_agents` -> `get_signal_leads`
359
+
360
+ Stops at: the agent proposal, created only after the person approves it. The helpers are free; the agent itself costs nothing to set up. Editing or pausing later happens in Signals or with `signals:update-agent`.
361
+
362
+ ### Lead Review
363
+
364
+ The leads the agents found, prioritized, with the top few activity-checked.
365
+
366
+ ```bash
367
+ superx signals:agents
368
+ superx signals:leads --agent <agent-id> --deposited false --limit 25
369
+ superx x:user-posts <lead-handle> --no-reposts --limit 10
370
+ superx signals:feedback <lead-id> --fit
371
+ ```
372
+
373
+ The feedback id is the numeric LEAD id, not an X user id, and it trains the scorer: ask the person for the verdict rather than inferring one.
374
+
375
+ MCP: `list_signal_agents` -> `get_signal_leads` -> `get_x_user_posts` -> `set_lead_feedback`
376
+
377
+ Stops at: the prioritized list plus recorded verdicts. Reads plus one small write; the activity check spends the shared 300-a-day `x:*` allowance.
378
+
379
+ ---
380
+
381
+ ## Audiences, research and DMs
382
+
383
+ ### Profile Research Briefs
384
+
385
+ Structured briefs on a list of people, exportable as CSV.
386
+
387
+ ```bash
388
+ superx datasets:research --handles "<handle>,<handle>" --max 25 --focus "<what to look for>" --title "<briefs title>" --wait
389
+ superx datasets:rows <dataset-id> --limit 25
390
+ superx datasets:export <dataset-id> --out briefs.csv
391
+ ```
392
+
393
+ Over 5 profiles the run goes to the background, so never quote a brief count from a `collecting` result: pass `--wait` or poll `datasets:get`.
394
+
395
+ MCP: `research_profiles` -> `get_dataset` -> `get_dataset_rows`
396
+
397
+ Stops at: the briefs in chat plus a CSV on disk. Costs 1 AI credit per profile ACTUALLY researched (unresolved handles are refunded), max 25 a run, plus one of the plan's daily research runs. CSV export is CLI only; XLSX stays in the SuperX app.
398
+
399
+ ### DM-Ready Audience Builder
400
+
401
+ A clean, DM-able audience built from any post or public X list, with a path into a contact list.
402
+
403
+ ```bash
404
+ superx datasets:collect --source repliers --target <post-url> --require-can-dm --max-rows 500 --title "<audience title>" --wait
405
+ superx datasets:get <dataset-id>
406
+ superx lists:create --name "<list name>"
407
+ superx datasets:add-to-list <dataset-id> --list-id <list-id>
408
+ ```
409
+
410
+ `--source` also takes `quoters`, `reposters` and `list_members` (with a public X list URL as `--target`). Adding to a list dedupes by person and skips rows with no usable X account id, so `added + duplicates` can be lower than the row count.
411
+
412
+ MCP: `collect_audience` -> `get_dataset` -> `create_contact_list` -> `add_dataset_to_contact_list`
413
+
414
+ Stops at: a filtered dataset and, if the person wants it, a contact list. Costs one of 10 collections a day shared with the SuperX app. No AI credits.
415
+
416
+ ### Sentiment Slice
417
+
418
+ Keep only the people who said the thing you are looking for.
419
+
420
+ ```bash
421
+ superx datasets:list
422
+ superx datasets:refine <dataset-id> --criterion "<what a matching row says>" --sort followers --limit 100 --wait
423
+ superx datasets:rows <new-dataset-id> --limit 50
424
+ ```
425
+
426
+ The source dataset is untouched. Only datasets whose rows carry text (repliers, quoters) can be refined. Rows the classifier cannot judge are KEPT and counted as unclear, so report the unclear count honestly.
427
+
428
+ MCP: `list_datasets` -> `refine_dataset` -> `get_dataset_rows`
429
+
430
+ Stops at: the new dataset with its matched and unclear counts. A refinement creates a dataset, so it spends one of the same 10 collections a day, plus a small AI cost. Ask before running it.
431
+
432
+ ### Audience Export
433
+
434
+ Everyone who engaged a post, as a spreadsheet, no filters.
435
+
436
+ ```bash
437
+ superx datasets:collect --source repliers --target <post-url> --max-rows 1000 --title "<export title>" --wait
438
+ superx datasets:get <dataset-id>
439
+ superx datasets:export <dataset-id> --out audience.csv
440
+ ```
441
+
442
+ MCP: `collect_audience` -> `get_dataset`
443
+
444
+ Stops at: a CSV file on disk, up to 1000 rows. **CSV only**: there is no export tool on MCP and XLSX stays in the SuperX app, so send the person there when they need the spreadsheet format. Costs one of 10 collections a day. No AI credits.
445
+
446
+ ### My Content Export
447
+
448
+ The account's own posts or replies, as a spreadsheet.
449
+
450
+ ```bash
451
+ superx datasets:collect --source my_posts --since-days 90 --sort likes --max-rows 200 --wait
452
+ superx datasets:get <dataset-id>
453
+ superx datasets:export <dataset-id> --out my-content.csv
454
+ ```
455
+
456
+ `--source my_replies` does the same for replies. Small exports finish instantly.
457
+
458
+ MCP: `collect_audience` -> `get_dataset`
459
+
460
+ Stops at: a CSV file on disk. **CSV only**, same as Audience Export: XLSX is app-only. Costs one of 10 collections a day. No AI credits.
461
+
462
+ ### Warm Outreach Pipeline
463
+
464
+ Research a list, get one personalized message per person, and queue them only after the person approves every message.
465
+
466
+ ```bash
467
+ HANDLES=$(superx contacts:list --sort engagement --limit 25 | jq -r '[.data[].username] | join(",")')
468
+ superx datasets:research --handles "$HANDLES" --max 25 --focus "<what to look for>" --wait
469
+ superx datasets:outreach-drafts <dataset-id> --format "<the template or an example message>"
470
+ superx datasets:rows <dataset-id> --limit 25
471
+ superx dm:limits
472
+ superx dm:campaign --recipients recipients.json --idempotency-key "outreach-<slug>-1"
473
+ superx dm:campaign-status <campaign-id>
474
+ ```
475
+
476
+ `--handles`, `--list`, `--agent` and `--dataset` are alternative sources for the research step: give exactly one. `contacts:list` returns people, not a list id, so its output feeds `--handles` through the `jq` above; `--list` takes a contact-list id from `lists:list` instead, which is the other way into this playbook. Both cap at 25 profiles. Build `recipients.json` from the dataset rows as `[{"x_user_id":"...","handle":"...","name":"...","message":"..."}]`, one entry per person, each carrying its own approved message. Ask the person for the `--format`; never invent one.
477
+
478
+ MCP: `get_top_contacts` -> `research_profiles` -> `draft_outreach_dms` -> `get_dataset_rows` -> `get_dm_limits` -> `queue_dm_campaign` -> `get_dm_campaign`
479
+
480
+ Stops at: **a queued campaign, not delivered messages.** `dm:campaign` is an ENQUEUE: the SuperX app sends the messages later, within the account's daily and monthly DM limits, so report counts and never say anything was sent. `dm:campaign-status` and `dm:queue` show what actually went out; `dm:cancel` cancels the unsent ones. Research costs 1 AI credit per profile researched, max 100 recipients per campaign, and the person is responsible for these messages under X's automation rules.
481
+
482
+ ### Reply-to-DM Campaign
483
+
484
+ DM the people who replied to one of the account's posts.
485
+
486
+ ```bash
487
+ superx datasets:collect --source repliers --target <post-url> --keywords "<optional filter>" --require-can-dm --max-rows 100 --wait
488
+ superx datasets:refine <dataset-id> --criterion "<who to keep>" --wait
489
+ superx datasets:rows <new-dataset-id> --limit 100
490
+ superx dm:limits
491
+ superx dm:campaign --recipients recipients.json --message "Hey [name], ..." --idempotency-key "campaign-<slug>-1"
492
+ superx dm:campaign-status <campaign-id>
493
+ ```
494
+
495
+ Build `recipients.json` from `datasets:rows` in the same shape as Warm Outreach Pipeline, `[{"x_user_id":"...","handle":"...","name":"...","message":"..."}]`, except that here `--message` carries the shared wording and only `x_user_id` is required per row; a row's own `message` overrides the shared one. `[name]`, `[first]` and `[handle]` are filled per recipient. People messaged in the last 24 hours are skipped and counted in `duplicates`, and the account never messages itself.
496
+
497
+ MCP: `collect_audience` -> `refine_dataset` -> `get_dataset_rows` -> `get_dm_limits` -> `queue_dm_campaign` -> `get_dm_campaign`
498
+
499
+ Stops at: **a queued campaign, not delivered messages.** The enqueue rule is the same one as Warm Outreach Pipeline: the SuperX app sends, nothing here does, and the response is counts. Max 100 per campaign, 10 dataset ops a day, no AI credits on the DM side. Confirm the recipient list and the exact wording with the person first.
500
+
501
+ ---
502
+
503
+ ## Settings
504
+
505
+ ### Teach SuperX Your Rules
506
+
507
+ Standing rules the AI follows on every drafting surface.
508
+
509
+ ```bash
510
+ superx context:get
511
+ superx context:set --rules "<the rule, in plain words>"
512
+ superx context:get
513
+ ```
514
+
515
+ Saving REPLACES the whole rule set, capped at 500 characters, so read the current rules first and send them back plus the new one. These settings steer all future AI output on the account: confirm the final wording before saving.
516
+
517
+ MCP: `get_context` -> `update_context`
518
+
519
+ Stops at: the updated rule set, read back so the person can see exactly what is stored. Free, no AI credits.
520
+
521
+ ---
522
+
523
+ Command reference and gotchas: [SKILL.md](./SKILL.md). Strategy: [PLAYBOOK.md](./PLAYBOOK.md).
package/README.md CHANGED
@@ -11,7 +11,7 @@ npx skills add superx-so/superx-agent
11
11
  Two things ship in this repo:
12
12
 
13
13
  - `superx-cli`, an npm package installing the `superx` binary (a thin client for `api.superx.so/v1`)
14
- - An agent skill (`SKILL.md`) plus a growth strategy guide (`PLAYBOOK.md`) so agents do not just schedule posts, they follow a strategy that works
14
+ - An agent skill (`SKILL.md`) plus a growth strategy guide (`PLAYBOOK.md`) and 28 goal-shaped recipes (`PLAYBOOKS.md`) so agents do not just schedule posts, they follow a strategy that works
15
15
 
16
16
  ---
17
17
 
@@ -344,6 +344,7 @@ superx docs # Prints the API quickstart as markdown; works without auth
344
344
 
345
345
  - **Skill included**: `npx skills add superx-so/superx-agent` installs [SKILL.md](./SKILL.md), a complete agent reference with hard rules, workflows, and gotchas.
346
346
  - **Strategy included**: [PLAYBOOK.md](./PLAYBOOK.md) distills the SuperX growth methodology (action hierarchy, out-of-network discovery, the 3-3-3 engagement loop, weekly operating system) into directives an agent can execute with this CLI. The skill instructs agents to read it before creating content.
347
+ - **Playbooks included**: [PLAYBOOKS.md](./PLAYBOOKS.md) holds 28 goal-shaped recipes, one per SuperX skill, each with its CLI chain, the matching MCP tool chain, and the point where the agent hands the result back to a person.
347
348
  - **Clean JSON stdout**: no decoration to strip; every data command is `jq`-safe.
348
349
  - **Idempotent writes**: agents can retry `scheduled:create` safely with `--idempotency-key`.
349
350
  - **Self-describing**: `superx docs` fetches the current API quickstart at runtime.
@@ -505,8 +506,6 @@ src/
505
506
  └── docs.ts # docs
506
507
  ```
507
508
 
508
- Maintainer note: `SKILL.md` (repo root) and `skills/superx/SKILL.md` must stay byte-identical. Edit the root file and copy it over the nested one.
509
-
510
509
  ---
511
510
 
512
511
  ## Quick reference