@usesocial/cli 0.1.0 → 0.1.3

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 ADDED
@@ -0,0 +1,9 @@
1
+ # @usesocial/cli
2
+
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [`158bf58`](https://github.com/usesocial/monorepo/commit/158bf5804d47112fa2ed941fd7e78174a53b3947) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Release the promoted account lifecycle, schema, and publishing pipeline updates.
8
+
9
+ Future release entries are managed by Changesets.
package/README.md CHANGED
@@ -1,8 +1,15 @@
1
- # @usesocial/cli
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://usesocial.dev/app-icon-dark.svg" />
4
+ <img alt="social" height="84" src="https://usesocial.dev/app-icon.svg" width="84" />
5
+ </picture>
6
+ </p>
2
7
 
3
- **Give your agent access to social networks.** One install, one login, and your
4
- agent can read, search, and graph LinkedIn and X — and post through your own
5
- account when you let it from any shell, any runtime.
8
+ <h1 align="center">@usesocial/cli</h1>
9
+
10
+ **Agent-run distribution.** One install, one login, and your agent can run
11
+ distribution work across X and LinkedIn — outreach, posting, audience insights,
12
+ and the follow-up loops between them — from any shell.
6
13
 
7
14
  `social` is built for people who live in a terminal with an agent open and are on
8
15
  the hook for their own distribution. The work you keep meaning to do — see who
@@ -15,21 +22,17 @@ Published as `@usesocial/cli` on npm; the binary is `social`.
15
22
  ## Install
16
23
 
17
24
  ```sh
18
- brew install usesocial/tap/social
19
- # or
20
- bun install -g @usesocial/cli@latest
21
- # or
22
- npm install -g @usesocial/cli
25
+ curl -fsSL https://usesocial.dev/install.sh | bash
23
26
  ```
24
27
 
25
28
  ## Quickstart
26
29
 
27
30
  ```sh
28
- social login # device sign-in, choose scope, set up billing
29
- social linkedin connect # connect a LinkedIn account
30
- social linkedin users me --pretty
31
- social x connect # connect an X account
32
- social x users me --pretty
31
+ social account login # device sign-in, choose scope, set up billing
32
+ social account connect linkedin # connect a LinkedIn account
33
+ social linkedin profile
34
+ social account connect x # connect an X account
35
+ social x profile
33
36
  ```
34
37
 
35
38
  ## What you can hand your agent
@@ -39,122 +42,203 @@ A few of the things the command surface supports:
39
42
 
40
43
  | You ask | The agent reaches for |
41
44
  |---|---|
42
- | "Surface the ten connections worth reaching out to this week." | `linkedin users connections`, `x users tweets` |
43
- | "Pull everyone who reacted to my last LinkedIn post and flag the warm leads." | `linkedin posts reactions`, `linkedin users get` |
44
- | "Read this creator's recent posts and break down what makes them land." | `linkedin users posts`, `x users tweets` |
45
- | "Find what people are saying about AI agents this week and summarize the themes." | `linkedin search posts`, `x search recent` |
46
- | "Draft a reply to this thread and post it once I approve." | `linkedin posts comment`, `x tweets post` |
45
+ | "Surface the ten connections worth reaching out to this week." | `linkedin connections`, `x tweets` |
46
+ | "Pull everyone who reacted to my last LinkedIn post and flag the warm leads." | `linkedin reactions`, `linkedin profile` |
47
+ | "Read this creator's recent posts and break down what makes them land." | `linkedin posts`, `x tweets` |
48
+ | "Find what people are saying about AI agents this week and summarize the themes." | `linkedin search posts`, `x timeline` |
49
+ | "Draft a reply to this thread and post it once I approve." | `linkedin comment`, `x post` |
47
50
 
48
51
  ## Commands
49
52
 
50
- Every command supports `--json` and `--pretty` for machine- vs. human-readable
51
- output. Most accept filters like `--limit`, `--cursor`, `--from`, and `--to`. Pass
52
- `--help` on any subcommand for the full flag list, or run `social schema` for a
53
- structured dump of every command handy as an agent manifest.
53
+ The main command surfaces print compact JSON by default. List commands commonly
54
+ accept `--limit` and `--cursor`; time windows are command-specific. Pass `--help`
55
+ on any subcommand for the full flag list, or run `social schema "<command path>"`
56
+ for the machine-readable contract for a runnable command. Agents planning across
57
+ many calls can run `social schema --leaves` for a manifest of runnable commands
58
+ keyed by command path.
54
59
 
55
60
  Commands marked **✎ write** mutate your account and require an explicit write
56
61
  scope (see [Account safety](#account-safety)).
57
62
 
63
+ ### Targets
64
+
65
+ Commands with `[target]` or `<target>` accept `@handle` or `@public-identifier`,
66
+ a full X/LinkedIn URL, a LinkedIn URN, or a typed ID such as `profile_id:<id>`,
67
+ `post_id:<id>`, `list_id:<id>`, `chat_id:<id>`, `company_id:<id>`, or `request_id:<id>`. Bare IDs are not
68
+ accepted. When an optional target is omitted, the command acts on your own
69
+ connected account.
70
+
58
71
  ### Top level
59
72
 
60
73
  | Command | Description |
61
74
  |---|---|
62
- | `social login` | Device sign-in, scope selection, billing, optional agent-skill install. |
63
- | `social logout` | Revoke the session and clear the saved token. |
64
- | `social schema` | Print the full command tree as JSON — a manifest for agents. |
65
- | `social usage` | Recent calls or an aggregate billing/usage summary. |
66
- | `social linkedin <…>` | LinkedIn operations (below). |
75
+ | `social account` | Show auth state and connected accounts; login, logout, connect accounts, inspect usage/logs, and configure local CLI settings. |
76
+ | `social schema` | Print the compact command tree, inspect one command with `social schema "<command path>"`, or emit agent command contracts with `social schema --leaves`. |
67
77
  | `social x <…>` | X operations (below). |
78
+ | `social linkedin <…>` | LinkedIn operations (below). |
79
+
80
+ ### `social account`
81
+
82
+ | Command | Description | |
83
+ |---|---|---|
84
+ | `(bare)` | Show who is signed in and list connected accounts. | |
85
+ | `login` | Device sign-in, scope selection, and billing. | |
86
+ | `logout` | Revoke the session and clear the saved token. | |
87
+ | `connect linkedin` | Connect a LinkedIn account through the browser. | ✎ write |
88
+ | `connect x` | Connect an X account through OAuth. | ✎ write |
89
+ | `reconnect linkedin <account>` | Re-auth an existing LinkedIn account. | ✎ write |
90
+ | `reconnect x <account>` | Re-auth an existing X account. | ✎ write |
91
+ | `disconnect linkedin <account>` | Disconnect a LinkedIn account. | ✎ write |
92
+ | `disconnect x <account>` | Disconnect an X account. | ✎ write |
93
+ | `usage` | Aggregate proxy usage and billing stats. | |
94
+ | `logs` | Recent proxy calls. | |
95
+ | `config cache mode` | Read or set the cache mode preset. | |
96
+ | `config cache ttl` | Set a custom cache TTL in seconds. | |
97
+
98
+ `social account` returns compact JSON with the signed-in user and connected accounts.
68
99
 
69
100
  ### `social linkedin`
70
101
 
71
102
  | Command | Description | |
72
103
  |---|---|---|
73
- | `companies get` | Fetch a company profile. | |
74
- | `companies employees` | List employees at a company. | |
75
- | `companies jobs` | List a company's job postings. | |
76
- | `posts get` | Fetch a post. | |
77
- | `posts comments` | List a post's comments. | |
78
- | `posts reactions` | List a post's reactions. | |
79
- | `posts post` | Create a post. | ✎ write |
80
- | `posts comment` | Comment on a post. | ✎ write |
81
- | `posts react` | React to a post or comment. | write |
82
- | `search people` | Search for people. | |
83
- | `search posts` | Search for posts. | |
84
- | `users get` | Fetch a profile. | |
85
- | `users connections` | List a user's connections. | |
86
- | `users posts` | List a user's or company's posts. | |
87
- | `users me` | Show the connected LinkedIn profile. | |
88
- | `users invite` | Send a connection invite. | ✎ write |
89
- | `connect` · `reconnect` · `disconnect` · `list` | Account lifecycle and listing. | |
104
+ | `post <text>` | Create a post. | ✎ write |
105
+ | `comment <target> <text>` | Comment on a post. | ✎ write |
106
+ | `react <target> [type=like]` | React to a post or comment. | ✎ write |
107
+ | `requests send <target> [message]` | Send a connection request. | ✎ write |
108
+ | `requests sent` | List pending sent connection requests; supports `--limit`, `--cursor`, `--offset`, and `-H/--header`. | |
109
+ | `requests received` | List pending received connection requests; supports `--limit`, `--cursor`, `--offset`, and `-H/--header`. | |
110
+ | `requests accept request_id:<id>` | Accept a received connection request. | ✎ write |
111
+ | `requests cancel request_id:<id>` | Cancel a sent request or refuse a received connection request. | ✎ write |
112
+ | `posts [target]` | List a user's or company's posts; omit the target for your own account. | |
113
+ | `comments <target>` | List a post's comments. | |
114
+ | `reactions <target>` | List a post's reactions. | |
115
+ | `profile [target]` | Fetch a profile; omit the target for your own account. | |
116
+ | `connections [target]` | List connections; omit the target for account-level connections. | |
117
+ | `company <target>` | Fetch a company profile. | |
118
+ | `jobs <target>` | List a company's job postings. | |
119
+ | `search people <keywords>` | Search for people. | |
120
+ | `search posts <keywords>` | Search for posts. | |
121
+ | `search jobs <keywords>` | Search for jobs. | |
122
+ | `search companies <keywords>` | Search for companies. | |
123
+ | `messages` | List conversations. | |
124
+ | `messages <target>` | Read a conversation by `chat_id:<id>`, `@handle`, `profile_id:<id>`, profile URL, or messaging-thread URL. | |
125
+ | `message <target> <text>` | Send a message. | ✎ write |
126
+ | `message <target> delete message_id:<id>` | Delete one of your own messages. | ✎ write |
127
+ | `message <target> edit message_id:<id> <text>` | Edit one of your own messages. | ✎ write |
128
+ | `messages <target> mark read` | Mark a conversation read. | ✎ write |
129
+ | `messages <target> mark unread` | Mark a conversation unread. | ✎ write |
90
130
 
91
131
  ### `social x`
92
132
 
93
133
  | Command | Description | |
94
134
  |---|---|---|
95
- | `search recent` | Search posts from the last 7 days. | |
96
- | `timelines home` | Read the home timeline. | |
97
- | `tweets list` | Fetch up to 100 posts by ID. | |
98
- | `tweets get` | Fetch a single post by ID. | |
99
- | `tweets post` | Create a post. | write |
100
- | `tweets like` · `unlike` | Like or unlike a post. | write |
101
- | `tweets repost` · `unrepost` | Repost or undo a repost. | ✎ write |
102
- | `tweets delete` | Delete a post. | write |
103
- | `users tweets` | List a user's recent posts. | |
104
- | `users me` | Show the authenticated X profile. | |
105
- | `users follow` · `unfollow` | Follow or unfollow a user. | ✎ write |
106
- | `bookmarks list` | List your saved bookmarks. | |
107
- | `bookmarks add` · `remove` | Add or remove a bookmark. | write |
108
- | `connect` · `reconnect` · `disconnect` · `list` | Account lifecycle and listing. | |
135
+ | `post <text>` | Create a post. | write |
136
+ | `repost <target>` · `unrepost <target>` | Repost or undo a repost. | ✎ write |
137
+ | `like <target>` · `unlike <target>` | Like or unlike a post. | ✎ write |
138
+ | `follow <target>` · `unfollow <target>` | Follow or unfollow a user. | ✎ write |
139
+ | `followers [target]` | List a user's followers; omit the target for your own account. | |
140
+ | `following [target]` | List accounts a user follows; omit the target for your own account. | |
141
+ | `tweet <target>` | Fetch a single post. | |
142
+ | `tweets [target]` | List a user's recent posts; omit the target for your own account. | |
143
+ | `profile [target]` | Fetch a profile; omit the target for your own account. | |
144
+ | `timeline` | Read the home timeline. | |
145
+ | `bookmark <target>` · `unbookmark <target>` | Add or remove a bookmark. | ✎ write |
146
+ | `messages` | List conversations. | |
147
+ | `messages <target>` | Read a DM conversation or participant target: chat URL, `chat_id:<id>`, `@handle`, profile URL, or `profile_id:<id>`. | |
148
+ | `message <recipients> [text]` | Send a message to a chat URL, `chat_id:<id>`, `@handle`, profile URL, or `profile_id:<id>`; comma-separate profile targets for a group. | ✎ write |
109
149
 
110
150
  ## Built for agents
111
151
 
112
- - **Everything speaks JSON.** Pass `--json` and pipe through `jq`, `fzf`, or your
113
- agent's planner — anything that reads stdin. Structured errors and predictable
114
- exit codes mean an agent can branch on what happened.
115
- - **The same flags across networks.** `--limit`, `--cursor`, `--json`,
116
- `--pretty`. Learn the surface once; reuse it on LinkedIn and X.
152
+ - **Everything speaks JSON.** Pipe output through `jq`, `fzf`, or your agent's
153
+ planner — anything that reads stdin. Structured errors and predictable exit
154
+ codes mean an agent can branch on what happened.
155
+ - **The same patterns across networks.** `--limit`, `--cursor`, and `--account`
156
+ behave consistently on LinkedIn and X. Cacheable reads also list `-H/--header`
157
+ when proxy request headers such as `Cache-Control: no-cache` can be overridden.
117
158
  - **A skill you drop straight in.** Install the public skill repo with
118
159
  `npx skills add usesocial/skill`; Claude, Codex, or any other supported agent
119
- then knows the commands. `social login` can install it for you.
160
+ then knows the commands.
120
161
 
121
162
  ```sh
122
- # Find hiring posts, fan out to reaction graphs, rank warm contacts — one pipe.
123
- social linkedin search posts "AI infra hiring" --limit 10 --json \
124
- | jq -r '.posts[].urn' \
125
- | xargs -I{} social linkedin posts reactions {} --json \
126
- | jq -s '[.[].reactions[] | {actor, type}]
127
- | group_by(.actor.id)
128
- | map({actor: .[0].actor, signals: length})
163
+ # Find hiring posts, fan out to reaction graphs, rank warm contacts.
164
+ social linkedin search posts "AI infra hiring" --limit 25 > /tmp/hiring-posts.json
165
+ jq -r '.items[].id' /tmp/hiring-posts.json \
166
+ | xargs -I{} social linkedin reactions post_id:{} \
167
+ | jq -s '[ .[] | .items[] ]
168
+ | group_by(.actor.id // .reactor.id // .profile_id)
169
+ | map({person: (.[0].actor // .[0].reactor), signals: length})
129
170
  | sort_by(-.signals) | .[0:15]'
130
171
  ```
131
172
 
173
+ ## Exit codes
174
+
175
+ | Code | Meaning | Agent action |
176
+ |---:|---|---|
177
+ | `0` | Success | Continue. |
178
+ | `2` | Usage or validation error | Fix the command, flags, IDs, JSON body, or local input. |
179
+ | `3` | Not found | Check the resource ID or pick a different item. |
180
+ | `4` | Auth or scope error | Run `social account login`, or log out and choose the needed scope. |
181
+ | `5` | API or unexpected error | Retry later or surface the server error. |
182
+ | `7` | Rate limited | Back off; JSON errors may include `retryAfterSeconds`. |
183
+
132
184
  ## Auth
133
185
 
134
- `social login` runs a device-authorization flow:
186
+ `social account login` runs a device-authorization flow:
135
187
 
136
- 1. Shows you a verification code and opens the approval page in your browser
137
- (or prints the URL if there's no TTY, or you pass `--no-open`).
138
- 2. Waits until you approve the session in the browser.
139
- 3. Stores the returned token in your OS keyring, falling back to
188
+ 1. Asks what access to grant the agent. Read and Write are both selected by
189
+ default; clear Write in the prompt to grant read-only access.
190
+ 2. Asks for your email address.
191
+ 3. Shows you a verification code and approval URL, then tries to open that URL
192
+ in your browser.
193
+ 4. Waits until you approve the session in the browser.
194
+ 5. Confirms billing checkout in the terminal when a seat is needed.
195
+ 6. Stores the returned token in your OS keyring, falling back to
140
196
  `~/.social/credentials.json` (mode `0600`) when no keyring is available.
197
+ Non-production `SOCIAL_API_URL` values use an API-specific credential
198
+ namespace so staging tests do not overwrite the production session.
199
+
200
+ `social account logout` revokes the session and removes the stored token from both places.
201
+ Bare `social account` prints compact JSON with the current auth state, credential
202
+ namespace, verified session when available, and connected accounts.
203
+ `social account login` requires an interactive terminal and is not supported from CI,
204
+ background jobs, or agent-mediated setup flows.
141
205
 
142
- `social logout` revokes the session and removes the stored token from both places.
206
+ ## Cache config
143
207
 
144
- For non-interactive use (CI, agents), pass the details up front:
208
+ Allowlisted GET requests use a local proxy cache. Cacheable commands send
209
+ `Cache-Control: max-age=<seconds>` from your local config:
145
210
 
146
211
  ```sh
147
- social login --email you@example.com --scope read,write --accept-pricing --json
212
+ social account config cache mode # read the current cache mode and TTL
213
+ social account config cache mode live # 15 minutes, default
214
+ social account config cache mode analytical # 24 hours
215
+ social account config cache mode historical # 1 week
216
+ social account config cache ttl 3600 # custom TTL in seconds
148
217
  ```
149
218
 
219
+ Setting `ttl` switches the mode to `custom`. Config is stored at
220
+ `~/.social/config.json` with mode `0600`. Use command-level
221
+ `-H "Cache-Control: no-cache"` when a command lists `--header` in help and you
222
+ need to bypass a cached read.
223
+
224
+ Command output exposes actual per-call cost and pagination under `meta`:
225
+
226
+ ```sh
227
+ social linkedin messages --limit 20 | jq '.meta.cost'
228
+ social x bookmarks --limit 20 | jq '{cost: .meta.cost, cursor: .meta.cursor}'
229
+ ```
230
+
231
+ Agents should watch `.meta.cost` during high-fanout loops and use `social account usage`
232
+ or `social account logs` after a run to summarize actual spend.
233
+
150
234
  ## Account safety
151
235
 
152
236
  Built so your accounts outlive your prototype.
153
237
 
154
- - **Read scope by default.** Writes need an explicit upgrade you can revoke. A
155
- read-only session can't post, react, or invite.
238
+ - **Read/write scope by default.** Clear Write during login when you want a
239
+ read-only session that can't post, react, or request connections.
156
240
  - **A write never fires twice.** Rate-limit and server errors surface verbatim and
157
- writes are never retried — so a post or invite can't double-send.
241
+ writes are never retried — so a post or connection request can't double-send.
158
242
  - **A residential IP per account.** Each connected account runs over a dedicated
159
243
  residential proxy with smart rate-limiting, so the network sees a normal session.
160
244
 
@@ -162,24 +246,28 @@ Built so your accounts outlive your prototype.
162
246
 
163
247
  ```sh
164
248
  # LinkedIn
165
- social linkedin search people "founder ai" --limit 10 --pretty
166
- social linkedin users me --json
249
+ social linkedin search people "founder ai"
250
+ social linkedin profile
167
251
 
168
252
  # X
169
- social x search recent "from:elonmusk" --pretty
170
- social x bookmarks list --limit 50 --json
253
+ social x bookmarks --limit 50
254
+ social x followers --limit 100
255
+ social x following profile_id:<x-user-id> --limit 100
256
+ social x messages --limit 50
171
257
 
172
258
  # Usage / billing
173
- social usage --summary --platform linkedin --pretty
174
- social usage --limit 20 --from 2026-05-01T00:00:00Z
259
+ social account usage
260
+ social account logs --limit 20 --from 2026-05-01T00:00:00Z
175
261
 
176
- # Agent manifest
177
- social schema --pretty
262
+ # Command schema
263
+ social schema
264
+ social schema --leaves
265
+ social schema "x post"
178
266
  ```
179
267
 
180
268
  ## Links
181
269
 
182
- - Pricing and limits: <https://socialcli.dev/pricing>
183
- - Terms: <https://socialcli.dev/terms> · Privacy: <https://socialcli.dev/privacy>
270
+ - Pricing and limits: <https://usesocial.dev/pricing>
271
+ - Terms: <https://usesocial.dev/terms> · Privacy: <https://usesocial.dev/privacy>
184
272
 
185
- Built by founders with the same distribution problem.
273
+ Built by founders who needed their agents to keep distribution moving.
package/bin/social.mjs CHANGED
@@ -1,10 +1,17 @@
1
1
  #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
2
3
  import { dirname, join } from "node:path";
4
+ import { loadEnvFile } from "node:process";
3
5
  import { fileURLToPath, pathToFileURL } from "node:url";
4
6
 
5
7
  const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
+ const localEnvPath = join(packageRoot, "..", "..", ".env.staging");
6
9
  const entryURL = pathToFileURL(join(packageRoot, "dist", "index.mjs")).href;
7
10
 
11
+ if (existsSync(localEnvPath)) {
12
+ loadEnvFile(localEnvPath);
13
+ }
14
+
8
15
  import(entryURL).catch((error) => {
9
16
  console.error(error);
10
17
  process.exit(1);
package/dist/index.d.mts CHANGED
@@ -1 +1,98 @@
1
- export { };
1
+ //#region ../../node_modules/.bun/citty@0.2.2/node_modules/citty/dist/index.d.mts
2
+ //#region src/types.d.ts
3
+ type ArgType = "boolean" | "string" | "enum" | "positional" | undefined;
4
+ type _ArgDef<T extends ArgType, VT extends boolean | number | string> = {
5
+ type?: T;
6
+ description?: string;
7
+ valueHint?: string;
8
+ alias?: string | string[];
9
+ default?: VT;
10
+ required?: boolean;
11
+ options?: string[];
12
+ };
13
+ type BooleanArgDef = Omit<_ArgDef<"boolean", boolean>, "options"> & {
14
+ negativeDescription?: string;
15
+ };
16
+ type StringArgDef = Omit<_ArgDef<"string", string>, "options">;
17
+ type EnumArgDef = _ArgDef<"enum", string>;
18
+ type PositionalArgDef = Omit<_ArgDef<"positional", string>, "alias" | "options">;
19
+ type ArgDef = BooleanArgDef | StringArgDef | PositionalArgDef | EnumArgDef;
20
+ type ArgsDef = Record<string, ArgDef>;
21
+ type ResolveParsedArgType<T extends ArgDef, VT> = T extends {
22
+ default?: any;
23
+ required?: boolean;
24
+ } ? T["default"] extends NonNullable<VT> ? VT : T["required"] extends true ? VT : VT | undefined : VT | undefined;
25
+ type ParsedPositionalArg<T extends ArgDef> = T extends {
26
+ type: "positional";
27
+ } ? ResolveParsedArgType<T, string> : never;
28
+ type ParsedStringArg<T extends ArgDef> = T extends {
29
+ type: "string";
30
+ } ? ResolveParsedArgType<T, string> : never;
31
+ type ParsedBooleanArg<T extends ArgDef> = T extends {
32
+ type: "boolean";
33
+ } ? ResolveParsedArgType<T, boolean> : never;
34
+ type ParsedEnumArg<T extends ArgDef> = T extends {
35
+ type: "enum";
36
+ options: infer U;
37
+ } ? U extends Array<any> ? ResolveParsedArgType<T, U[number]> : never : never;
38
+ type RawArgs = {
39
+ _: string[];
40
+ };
41
+ type ParsedArg<T extends ArgDef> = T["type"] extends "positional" ? ParsedPositionalArg<T> : T["type"] extends "boolean" ? ParsedBooleanArg<T> : T["type"] extends "string" ? ParsedStringArg<T> : T["type"] extends "enum" ? ParsedEnumArg<T> : never;
42
+ type ParsedArgs<T extends ArgsDef = ArgsDef> = RawArgs & { [K in keyof T]: ParsedArg<T[K]> } & { [K in keyof T as T[K] extends {
43
+ alias: string;
44
+ } ? T[K]["alias"] : never]: ParsedArg<T[K]> } & { [K in keyof T as T[K] extends {
45
+ alias: string[];
46
+ } ? T[K]["alias"][number] : never]: ParsedArg<T[K]> } & Record<string, string | number | boolean | string[]>;
47
+ interface CommandMeta {
48
+ name?: string;
49
+ version?: string;
50
+ description?: string;
51
+ hidden?: boolean;
52
+ alias?: string | string[];
53
+ }
54
+ type SubCommandsDef = Record<string, Resolvable<CommandDef<any>>>;
55
+ type CommandDef<T extends ArgsDef = ArgsDef> = {
56
+ meta?: Resolvable<CommandMeta>;
57
+ args?: Resolvable<T>;
58
+ default?: Resolvable<string>;
59
+ subCommands?: Resolvable<SubCommandsDef>;
60
+ plugins?: Resolvable<CittyPlugin>[];
61
+ setup?: (context: CommandContext<T>) => any | Promise<any>;
62
+ cleanup?: (context: CommandContext<T>) => any | Promise<any>;
63
+ run?: (context: CommandContext<T>) => any | Promise<any>;
64
+ };
65
+ type CommandContext<T extends ArgsDef = ArgsDef> = {
66
+ rawArgs: string[];
67
+ args: ParsedArgs<T>;
68
+ cmd: CommandDef<T>;
69
+ subCommand?: CommandDef<T>;
70
+ data?: any;
71
+ };
72
+ type CittyPlugin = {
73
+ name: string;
74
+ setup?(context: CommandContext<any>): void | Promise<void>;
75
+ cleanup?(context: CommandContext<any>): void | Promise<void>;
76
+ };
77
+ type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>); //#endregion
78
+ //#region src/command.d.ts
79
+ //#endregion
80
+ //#region src/index.d.ts
81
+ type MutableCommand = CommandDef<any> & {
82
+ args?: any;
83
+ meta?: any;
84
+ subCommands?: any;
85
+ };
86
+ /**
87
+ * Resolves the chain of matched command NAMES for analytics, e.g.
88
+ * `social x tweets get <id>` → `["x", "tweets", "get"]`. Mirrors the
89
+ * `commandForUsage` walk but collects names.
90
+ *
91
+ * PRIVACY: only tokens that resolve to a real subcommand are appended. The first
92
+ * arg that does not resolve (a positional value: tweet ID, handle, query text,
93
+ * flag value) breaks the walk and is NEVER captured. Never returns rawArgs or
94
+ * flag values.
95
+ */
96
+ declare const resolveCommandPath: (command: MutableCommand, rawArgs: string[]) => Promise<string[]>;
97
+ //#endregion
98
+ export { resolveCommandPath };