"Group" (group) is a subscription source'sfolder: collect already-subscribed sources (WeChat official accounts MP, websites WEBSITE, Twitter X , etc.) into custom groups for easier categorized browsing. This skill handles the CRUD and member management of groups.
And
supsub-focusdifference:groupismanual collectiona folder of subscription sources (members are sources);focusis AI aggregated by topiccontent stream (members are articles). "Put QbitAI into the AI group" → this skill; "what's in my focus points" → supsub-focus. Andsupsub-subdifference:submanages the subscription relationship itself (subscribe/unsubscribe/read articles); this skill only manages "which folder the source is placed in".sub add --group <gid>can be added directly to a group when subscribing (see supsub-sub).
Prerequisites
- Install:
curl -fsSL https://raw.githubusercontent.com/SupSub-AI/supsub-cli/master/scripts/install.sh | bash(native install, installs to~/.local, supports background auto-update); or package managernpm i -g @supsub/cli/pnpm add -g @supsub/cli - Already logged in:
supsub auth statusshows Authenticated (first use, firstsupsub auth login) - When unauthorized (exit 2 / UNAUTHORIZED), do not stop at "you are not logged in": directly run
supsub auth loginto open browser authorization for the user (the command will automatically open the browser and block waiting for authorization, please use a sufficiently long timeout, such as 10 minutes; the user only needs to click confirm in the browser, no need to enter anything in the terminal), and retry the original command after successful authorization. In a browserless / headless environment, fall back to prompting the userSUPSUB_NO_BROWSER=1 supsub auth login。
Commands
List groups (group list)
supsub group list
No parameters. Fields per line:id, name。
supsub group list
supsub group list -o json
JSON shape: {"success":true,"data":[{"id":1063,"name":"AI 周报"}, ...]}
idis currently a number, but please treat it asopaque identifierpass it back as-is (do not do math operations/format assumptions); the backend reserves the possibility of switching to string IDs.
Create a group (create group)
supsub group add <name>
Positional argument <name> is the group name (blank name reports INVALID_ARGS)。
supsub group add "AI 周报"
supsub group add 财经 -o json
JSON shape: {"success":true,"data":{"id":1182,"name":"AI 周报"}} — the return directly includes the new group id, can immediately follow with add-sub / sub add --group to use (already tested).
⚠️ Group names cannot be duplicated: when a group with the same name already exists, it reports
ResourceExists(409 → exit1),will notreturn the existing group's id.Therefore, the correct order for requests like "subscribe X and put it in the 'Efficiency' group" is:first
group listfind a group with the same name, if hit, reuse itsid, only if not hit thengroup add. Doinggroup addright away will fail once for nothing when the group already exists. Ifgroup listdoes not have that group, just create it directly (creating a group is a lossless operation, no need to ask the user back) — butbefore creating, mention in passing "The 'Efficiency' group does not exist, I'll create a new one", because the user may very likely have just misremembered the group name.
Rename a group (rename group)
supsub group rename --id <gid> --name <newName>
| Flag | Required | Description |
|---|---|---|
--id |
yes | Group ID (from group list) |
--name |
yes | New group name (non-empty) |
supsub group rename --id 1063 --name "AI 深度"
JSON shape: {"success":true,"data":{"message":"分组已重命名"}}
Remove a group(delete group)
supsub group remove --id <gid>
supsub group remove --id 1182
JSON shape: {"success":true,"data":{"message":"已删除分组"}}
⚠️ Destructive and irreversible:Before executing, you must ask the user fora second confirmation——restate the group name (taken from the
group list), and only execute after obtaining the user's explicit consent. The feeds in the group themselves will not be unsubscribed; they merely lose this folder.The CLI will not ask again:
group removeThere is no interactive confirmation prompt; it deletes as soon as it executes. Confirmation only happens between you and the user. If you hand the command to the user to execute themselves,do not say "the CLI will ask you to confirm"——truthfully state that it takes effect as soon as it runs.
List sources in a group(view group feeds)
supsub group subs --id <gid> [--all] [--type <MP|WEBSITE|X|PODCAST|NEWSLETTER>]
| Flag | Default | Description |
|---|---|---|
--id |
required | Group ID |
--all |
— | Showallfeeds (including those not in this group), with an inGroup boolean column; when omitted, only members in the group are shown |
--type |
— (all) | Filter type; compared with the sub command, it has two additional types: PODCAST(podcast) / NEWSLETTER(newsletter) (can be added from the web) |
Fields:sourceId, sourceType, name, img, description, inGroup;Default (in-group members) mode onlyEach row additionally carries unreadCount。
# 组内成员(带未读数)—— 回答「这个分组还有多少未读」
supsub group subs --id 1063
# 所有订阅源 + 是否在组(用于挑选要移入的源)
supsub group subs --id 1063 --all -o json
# 只看组内公众号
supsub group subs --id 1063 --type MP
JSON shape (default): {"success":true,"data":[{"sourceType":"MP","sourceId":143,"name":"...","img":"...","description":"...","inGroup":true,"unreadCount":4}, ...]}
--allmode backenddoes not returnunreadCount; if you want unread counts, use the default mode.
Add a source to a group(add feed to group)
supsub group add-sub --id <gid> --source-id <sid> --type <MP|WEBSITE|X>
| Flag | Required | Description |
|---|---|---|
--id |
yes | Group ID (from group list) |
--source-id |
yes | Feed ID (positive integer, from sub list / search) |
--type |
yes | MP / WEBSITE / X(Twitter)——PODCAST/NEWSLETTER cannot be added via the CLI |
supsub group add-sub --id 1063 --source-id 25 --type MP
JSON shape: {"success":true,"data":{"message":"已将订阅源加入分组"}}
Idempotent: when the source is already in the group, returns
"该订阅源已在分组中,无需重复添加"and exit 0——this is success, not an error; just relay it truthfully. The implementation is read-modify-write with full overwrite(the backend has no atomic move-in/move-out endpoints): the CLI first reads the group members and then writes the whole thing back.Do not edit the same group concurrently(multiple commands running at the same time, or simultaneous operations with the web, will overwrite each other, last-write-wins).
Remove a source from a group(remove feed from group)
supsub group remove-sub --id <gid> --source-id <sid> --type <MP|WEBSITE|X>
Flags same as add-sub. Leaving the groupwill not unsubscribethat source.
supsub group remove-sub --id 1063 --source-id 25 --type MP
JSON shape: {"success":true,"data":{"message":"已将订阅源移出分组"}}
Idempotent: when the source is not in the group, returns
"该订阅源不在分组中,无需移除"and exit 0. Concurrency warning same asadd-sub。
Agent Usage Notes
- When parsing data, always use
-o json; all JSON responses are in the{"success":true,"data":<payload>}structure. --id(group ID) the only source issupsub group list;--source-idthe only source issupsub sub list/supsub search. When the user reports a group name, firstgroup listto find the corresponding id.group removeBefore executing, you must ask the user for a second confirmation(restate the group name → explicit consent → execute); deletion is irreversible.add-sub/remove-subisread-modify-write with full overwrite: do not operate on the same group concurrently; when moving multiple sources in in batches, pleaseseriallyexecute them one by one.- When subscribing to a new source, if the target group is already known, prefer
sub add --source-id <id> --type <t> --group <gid>to do it in one step (see supsub-sub); there is no need to first subscribe and thenadd-sub。 - A group member's
sourceTypemay appear asPODCAST/NEWSLETTER(added from the web),group subs --typecan filter them out; butadd-subonly acceptsMP|WEBSITE|X。 - There is no group-level mark-as-read command. When the user says "mark this entire group as read": first
group subslist the sources in the group and their respectiveunreadCount, restate the scope and get confirmation, then one by onesub mark-read --source-id <sid> --type <t> --all(each source is irreversible). There is also no single-article mark-as-read—seesupsub-unread。 - This skill is not responsible for: subscribing/unsubscribing sources (→
supsub-sub), focus points (→supsub-focus), unread workflow (→supsub-unread)。 - Exit codes:
0OK (including idempotency hints),1business error (backend 4xx, e.g., group does not exist 404 NotFound),2UNAUTHORIZED,64INVALID_ARGS(--idempty /--typeinvalid /--source-idnot a positive integer),10network error,11server error (5xx).When branching by exit code, note:
1and11are not the same thing—分组不存在this kind of business failure is1,11only appears on backend 5xx.