@usesocial/cli 0.6.0 → 0.7.1

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,12 +1,43 @@
1
1
  # @usesocial/cli
2
2
 
3
+ ## 0.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#32](https://github.com/usesocial/monorepo/pull/32) [`b2ca106`](https://github.com/usesocial/monorepo/commit/b2ca106f970bfe73d776f3f10225df7c6c7a1b80) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Use cursor pagination for `social linkedin posts` so the CLI matches the LinkedIn
8
+ posts provider contract.
9
+
10
+ ## 0.7.0
11
+
12
+ ### Minor Changes
13
+
14
+ - [#31](https://github.com/usesocial/monorepo/pull/31) [`dcda1ff`](https://github.com/usesocial/monorepo/commit/dcda1ff2af6fbc3595c1978dd528213ef4897c8e) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Split own-data reads from live network reads. Own-account collections now flow
15
+ through explicit `sync` plus free read-only `sql` envelopes; named read commands
16
+ are live and metered, with target-required post/tweet reads and write-only
17
+ message/request routers where applicable.
18
+
19
+ ### Patch Changes
20
+
21
+ - [#31](https://github.com/usesocial/monorepo/pull/31) [`eb53c2c`](https://github.com/usesocial/monorepo/commit/eb53c2cca95f2c708d9c8b8b920fc5b8ab080e2c) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Add cache migrations for the latest synced read schema, including LinkedIn
22
+ headline columns and removed X edit-control fields. Cache opens can now report
23
+ applied migrations so callers can surface migration notices without guessing.
24
+
25
+ - [#31](https://github.com/usesocial/monorepo/pull/31) [`a885c61`](https://github.com/usesocial/monorepo/commit/a885c619b6c67b1317d3e17d8fceb3e49e48795f) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Remove `--credits` from `social x sync` and `social linkedin sync`. Sync now
26
+ walks until the provider completes, reaches a stored checkpoint, or hits
27
+ `--since`; JSON summaries keep actual `creditsSpent` telemetry without exposing
28
+ estimate, cap, `credit-limit`, or `partial` fields.
29
+
30
+ LinkedIn sync also uses offset pagination for full account-level walks where the
31
+ provider exposes totals, and bills first-party sync reads such as connections,
32
+ request lists, chats, messages, own profile, and own posts as `owned_read`.
33
+
3
34
  ## 0.6.0
4
35
 
5
36
  ### Minor Changes
6
37
 
7
38
  - [#30](https://github.com/usesocial/monorepo/pull/30) [`7aefe83`](https://github.com/usesocial/monorepo/commit/7aefe83f716321d7fa10d52be67cb6f96b5474f0) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Per-collection sync with a confirm-by-credits gate, a local profiles mirror, and cache-first enriched reads.
8
39
 
9
- - `social x|linkedin sync <collection>` gates spend with a single `--credits {N}` flag that is both the consent and the hard cap; bare invocations auto-run cheap syncs (≤ $5) or print a credit estimate and stop. Replaces `--billing-limit`/`--yes`/the TTY prompt, and `sync` is now a visible command.
40
+ - `social x|linkedin sync <collection>` walks until provider completion, a stored checkpoint, or `--since`; `--credits` is no longer supported, and sync JSON reports actual `creditsSpent` without estimate, cap, `credit-limit`, or `partial` fields.
10
41
  - New `x_messages` DM collection (flat `/dm_events`) and a DM `includes.users` profile extractor. Syncs mirror participant profiles into the local cache (`x_profiles`/`li_profiles`) with a COALESCE merge so thin sources never clobber richer rows; the server `profiles` corpus merges the same way.
11
42
  - `x followers|following|messages` and `linkedin connections|messages|requests` now read from the local cache, enriched with the profiles mirror. They require a first sync; `followers`/`following`/`connections` then auto-refresh only when older than 15 minutes, while `messages` and `requests sent|received` refresh on every read so they always return the latest.
12
43
 
package/README.md CHANGED
@@ -8,14 +8,14 @@
8
8
  <h1 align="center">@usesocial/cli</h1>
9
9
 
10
10
  **LinkedIn & X CLI.** 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.
11
+ distribution work across X and LinkedIn: outreach, posting, audience insights,
12
+ and the follow-up loops between them from any shell.
13
13
 
14
- `social` is built for people who live in a terminal with an agent open and are on
15
- the hook for their own distribution. The work you keep meaning to do see who
16
- engaged, find the people worth reaching out to, learn from those who post better,
17
- keep the funnel warm becomes something you can hand to the agent you already
18
- trust with your code.
14
+ `social` is built for people who live in a terminal with an agent open and are
15
+ on the hook for their own distribution. The work you keep meaning to do - see
16
+ who engaged, find the people worth reaching out to, learn from those who post
17
+ better, keep the funnel warm - becomes something you can hand to the agent you
18
+ already trust with your code.
19
19
 
20
20
  Published as `@usesocial/cli` on npm; the binary is `social`.
21
21
 
@@ -28,165 +28,167 @@ curl -fsSL https://usesocial.dev/install.sh | bash
28
28
  ## Quickstart
29
29
 
30
30
  ```sh
31
- social account login # device sign-in, choose scope, set up billing
32
- social account connect linkedin # connect a LinkedIn account
31
+ social account login
32
+ social account connect linkedin
33
33
  social linkedin profile
34
- social account connect x # connect an X account
34
+ social account connect x
35
35
  social x profile
36
36
  ```
37
37
 
38
38
  ## What you can hand your agent
39
39
 
40
- Ask in plain language; the agent runs the calls and you stay the decision-maker.
41
- A few of the things the command surface supports:
42
-
43
40
  | You ask | The agent reaches for |
44
- |---|---|
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 posts`, `x timeline` |
41
+ | --- | --- |
42
+ | "Surface the ten warm contacts worth reaching out to this week." | `linkedin search people`, `linkedin reactions`, `linkedin sql` |
43
+ | "Pull everyone who reacted to my last LinkedIn post and flag the warm leads." | `linkedin posts <target>`, `linkedin reactions`, `linkedin profile` |
44
+ | "Read this creator's recent posts and break down what makes them land." | `linkedin posts <target>`, `x tweets <target>` |
45
+ | "Find what people are saying about AI agents this week and summarize the themes." | `linkedin search posts`, `x timeline` |
46
+ | "Triage my inbox and draft replies for approval." | `sync messages`, `sql`, `linkedin message`, `x message` |
49
47
  | "Draft a reply to this thread and post it once I approve." | `linkedin comment`, `x post` |
50
48
 
51
49
  ## Commands
52
50
 
53
- The main command surfaces print compact JSON by default. List commands commonly
54
- accept `--limit` plus either `--cursor` or `--offset`; LinkedIn list reads use
55
- `--offset`, while LinkedIn messages and X reads use `--cursor`. Pass `--help` on
56
- any subcommand for the full flag list, or run `social schema "<command path>"`
57
- for the machine-readable contract for a runnable command. Agents planning across
58
- many calls can run `social schema --leaves` for a manifest of runnable commands
59
- keyed by command path. For example, `social schema "linkedin requests received"`
60
- reports offset pagination, while `social schema "linkedin messages"` reports
61
- cursor pagination.
51
+ The CLI prints compact JSON. Use `social schema`, `social schema --list`, or
52
+ `social schema "<command path>"` for the machine-readable command tree.
62
53
 
63
- Commands marked **✎ write** mutate your account and require an explicit write
64
- scope (see [Account safety](#account-safety)).
54
+ Commands marked **write** mutate your account and require write scope. Commands
55
+ marked **local** update local CLI state or the local mirror.
65
56
 
66
57
  ### Targets
67
58
 
68
- Commands with `[target]` or `<target>` accept `@handle` or `@public-identifier`,
69
- a full X/LinkedIn URL, a LinkedIn URN, or a typed ID such as `profile_id:<id>`,
70
- `post_id:<id>`, `list_id:<id>`, `chat_id:<id>`, `conversation_id:<id>`, `company_id:<id>`, or `request_id:<id>`. Bare IDs are not
71
- accepted. When an optional target is omitted, the command acts on your own
72
- connected account.
59
+ Targets accept handles, profile/post/conversation/company URLs, LinkedIn URNs,
60
+ or typed IDs such as `profile_id:<id>`, `post_id:<id>`, `chat_id:<id>`,
61
+ `conversation_id:<id>`, `company_id:<id>`, and `request_id:<id>`. Bare IDs are
62
+ not accepted.
73
63
 
74
64
  ### Body text
75
65
 
76
- Commands that create a post, comment, message, or connection note read the body
77
- from **stdin** there is no text argument. Pipe it in:
66
+ Posts, comments, messages, message edits, and connection-request notes read
67
+ freeform text from stdin. There is no text positional:
78
68
 
79
69
  ```sh
80
70
  echo "gm" | social x post
81
71
  social linkedin post < draft.md
82
- social linkedin requests send @handle < note.txt # optional connection note
72
+ social linkedin requests send @handle < note.txt
73
+ ```
74
+
75
+ Pipe a JSON object for advanced payload fields.
76
+
77
+ ## Your data is local
78
+
79
+ `sync` pulls your own data down; it is explicit and costs credits. `sql` queries
80
+ that local mirror; it is free, instant, and read-only. Named read commands call
81
+ the live network and cost credits; `x tweets <target>` and
82
+ `linkedin posts <target>` require a target. Writes act.
83
+
84
+ ```sh
85
+ social x sync messages
86
+ social x sql "SELECT sender_handle, text, datetime(created_at/1000,'unixepoch') AS at FROM x_messages ORDER BY created_at DESC LIMIT 20" \
87
+ | jq '.items[]'
83
88
  ```
84
89
 
85
- On an interactive terminal with nothing piped, required body-text commands fail
86
- fast rather than hang. To send advanced payload fields, pipe a JSON object via
87
- stdin; if stdin parses as JSON but is not an object, the command rejects it.
90
+ The X inbox query gets `sender_handle` from the `x_messages` view; no extra
91
+ profile lookup is needed.
88
92
 
89
93
  ### Top level
90
94
 
91
95
  | Command | Description |
92
- |---|---|
93
- | `social account` | Show auth state and connected accounts; login, logout, connect accounts, inspect billing/usage/logs, and configure local CLI settings. |
94
- | `social schema` | Print the compact command tree, inspect one command with `social schema "<command path>"`, or emit agent command contracts with `social schema --leaves`. |
95
- | `social x <…>` | X operations (below). |
96
- | `social linkedin <…>` | LinkedIn operations (below). |
96
+ | --- | --- |
97
+ | `social account` | Auth state, connected accounts, login/logout, connect/reconnect/disconnect, billing, usage, logs, and cache config. |
98
+ | `social schema` | Print the command tree, inspect one command, emit the compact runnable index, or emit full contracts. |
99
+ | `social x <...>` | X operations. |
100
+ | `social linkedin <...>` | LinkedIn operations. |
101
+ | `social feedback bug\|feature` | Send a bug report or feature request to the maintainers (report text from stdin). |
97
102
 
98
103
  ### `social account`
99
104
 
100
105
  | Command | Description | |
101
- |---|---|---|
106
+ | --- | --- | --- |
102
107
  | `(bare)` | Show who is signed in and list connected accounts. | |
103
108
  | `login` | Device sign-in, scope selection, and billing. | |
104
109
  | `logout` | Revoke the session and clear the saved token. | |
105
- | `connect linkedin` | Open or print a LinkedIn connection URL. | write |
106
- | `connect x` | Open or print an X OAuth URL. | write |
107
- | `reconnect linkedin <account>` | Re-auth an existing LinkedIn account by opening or printing a connection URL. | write |
108
- | `reconnect x <account>` | Re-auth an existing X account by opening or printing an OAuth URL. | write |
109
- | `disconnect linkedin <account>` | Disconnect a LinkedIn account. | write |
110
- | `disconnect x <account>` | Disconnect an X account. | write |
110
+ | `connect linkedin` | Open or print a LinkedIn connection URL. | write |
111
+ | `connect x` | Open or print an X OAuth URL. | write |
112
+ | `reconnect linkedin <account>` | Re-auth an existing LinkedIn account. | write |
113
+ | `reconnect x <account>` | Re-auth an existing X account. | write |
114
+ | `disconnect linkedin <account>` | Disconnect a LinkedIn account. | write |
115
+ | `disconnect x <account>` | Disconnect an X account. | write |
111
116
  | `billing` | Show seats, subscription, and current usage billing. | |
112
117
  | `billing portal` | Open the hosted billing portal and print its URL. | |
113
- | `usage` | Aggregate proxy usage and billing stats. | |
118
+ | `usage` | Aggregate proxy calls and credits. | |
114
119
  | `logs` | Recent proxy calls. | |
115
- | `config cache mode` | Read or set the cache mode preset. | |
116
- | `config cache ttl` | Set a custom cache TTL in seconds. | |
117
-
118
- `social account` returns compact JSON with the authenticated user and connected accounts.
120
+ | `config cache mode` | Read or set the live-read proxy cache mode. | |
121
+ | `config cache ttl` | Set a live-read proxy cache TTL in seconds. | |
119
122
 
120
123
  ### `social linkedin`
121
124
 
122
125
  | Command | Description | |
123
- |---|---|---|
124
- | `post` | Create a post (body from stdin). | write |
125
- | `comment <target>` | Comment on a post (body from stdin). | write |
126
- | `react <target> [type=like]` | React to a post or comment. | ✎ write |
127
- | `requests send <target>` | Send a connection request (optional note from stdin). | ✎ write |
128
- | `requests sent` | List pending sent connection requests; supports `--limit`, `--offset`, and `-H/--header`. | |
129
- | `requests received` | List pending received connection requests; supports `--limit`, `--offset`, and `-H/--header`. | |
130
- | `requests accept request_id:<id>` | Accept a received connection request. | ✎ write |
131
- | `requests cancel request_id:<id>` | Cancel a sent request or refuse a received connection request. | ✎ write |
132
- | `posts [target]` | List a user's or company's posts; supports `--limit` and `--offset`; omit the target for your own account. | |
126
+ | --- | --- | --- |
127
+ | `profile [target]` | Fetch a profile; omit target for your own account. | |
128
+ | `posts <target>` | Live posts for a person or company; target required. Supports `--limit` and `--cursor` from `.meta.cursor`. | |
133
129
  | `comments <target>` | List a post's comments; supports `--limit` and `--offset`. | |
134
130
  | `reactions <target>` | List a post's reactions; supports `--limit` and `--offset`. | |
135
- | `profile [target]` | Fetch a profile; omit the target for your own account. | |
136
- | `connections [target]` | List connections; supports `--limit` and `--offset`; omit the target for account-level connections. | |
131
+ | `connections [target]` | Live connection graph read; omit target for your own account. Supports `--limit` and `--cursor` from `.meta.cursor`. Costs credits. | |
137
132
  | `company <target>` | Fetch a company profile. | |
138
133
  | `jobs <target>` | List a company's job postings; supports `--limit` and `--offset`. | |
139
- | `messages` | List conversations. | |
140
- | `messages <target>` | Read a conversation by `chat_id:<id>`, `@handle`, `profile_id:<id>`, profile URL, or messaging-thread URL. | |
141
- | `message <target>` | Send a message (body from stdin). | write |
142
- | `message <target> delete message_id:<id>` | Delete one of your own messages. | write |
143
- | `message <target> edit message_id:<id>` | Edit one of your own messages (new text from stdin). | write |
144
- | `messages <target> mark read` | Mark a conversation read. | write |
145
- | `messages <target> mark unread` | Mark a conversation unread. | write |
134
+ | `search people\|posts\|jobs\|companies <keywords>` | Search LinkedIn; live offset-paginated reads. | |
135
+ | `sync [collection]` | Pull your own `connections`, `posts`, `messages`, or `requests` into the local mirror; costs credits. | local |
136
+ | `sql [query]` | Query your synced local mirror with read-only SQL - free; bare `sql` prints the schema. | |
137
+ | `post` | Create a post (body from stdin). | write |
138
+ | `comment <target>` | Comment on a post (body from stdin). | write |
139
+ | `react <target>` | React to a post or comment; use `--type` for non-like reactions. | write |
140
+ | `requests send <target>` | Send a connection request (optional note from stdin). | write |
141
+ | `requests accept request_id:<id>` | Accept a received connection request. | write |
142
+ | `requests cancel request_id:<id>` | Cancel a sent request or refuse a received connection request. | write |
143
+ | `message <target>` | Send a message (body from stdin). | write |
144
+ | `message <target> delete message_id:<id>` | Delete one of your own messages. | write |
145
+ | `message <target> edit message_id:<id>` | Edit one of your own messages (new text from stdin). | write |
146
+ | `messages <target> mark read` | Mark a conversation read. | write |
147
+ | `messages <target> mark unread` | Mark a conversation unread. | write |
146
148
 
147
149
  ### `social x`
148
150
 
149
151
  | Command | Description | |
150
- |---|---|---|
151
- | `post` | Create a post (body from stdin). | write |
152
- | `delete <target>` | Delete one of your own posts. | ✎ write |
153
- | `repost <target>` · `unrepost <target>` | Repost or undo a repost. | ✎ write |
154
- | `reposters <target>` | List users who reposted a post. | |
155
- | `quotes <target>` | List quote posts of a post. | |
152
+ | --- | --- | --- |
153
+ | `profile [target]` | Fetch a profile; omit target for your own account. | |
154
+ | `tweets <target>` | Live posts for a user; target required. | |
155
+ | `timeline` | Read the home timeline. | |
156
+ | `mentions [target]` | List posts mentioning a user; omit target for your own account. | |
157
+ | `liked [target]` | List posts a user liked; omit target for your own account. | |
158
+ | `followers [target]` | Live follower graph read; omit target for your own account. Costs credits. | |
159
+ | `following [target]` | Live following graph read; omit target for your own account. Costs credits. | |
160
+ | `tweet <target>` | Fetch a single post. | |
156
161
  | `replies <target>` | List replies to a post; accepts `post_id:<id>`, `conversation_id:<id>`, or a post URL. | |
157
- | `like <target>` · `unlike <target>` | Like or unlike a post. | ✎ write |
158
- | `liked [target]` | List posts a user has liked; omit the target for your own account. | |
162
+ | `quotes <target>` | List quote posts of a post. | |
159
163
  | `likers <target>` | List users who liked a post. | |
160
- | `follow <target>` · `unfollow <target>` | Follow or unfollow a user. | ✎ write |
161
- | `followers [target]` | List a user's followers; omit the target for your own account. | |
162
- | `following [target]` | List accounts a user follows; omit the target for your own account. | |
163
- | `tweet <target>` | Fetch a single post. | |
164
- | `tweets [target]` | List a user's recent posts; omit the target for your own account. | |
165
- | `mentions [target]` | List posts mentioning a user; omit the target for your own account. | |
166
- | `profile [target]` | Fetch a profile; omit the target for your own account. | |
167
- | `timeline` | Read the home timeline. | |
168
- | `bookmarks` | List your saved bookmarks. | |
169
- | `bookmark <target>` · `unbookmark <target>` | Add or remove a bookmark. | write |
170
- | `messages` | List conversations. | |
171
- | `messages <target>` | Read a DM conversation or participant target: chat URL, `chat_id:<id>`, `@handle`, profile URL, or `profile_id:<id>`. | |
172
- | `message <recipients>` | Send a DM (body from stdin) to a chat URL, `chat_id:<id>`, `@handle`, profile URL, or `profile_id:<id>`; comma-separate profile targets for a group. | ✎ write |
164
+ | `reposters <target>` | List users who reposted a post. | |
165
+ | `sync [collection]` | Pull your own `tweets`, `followers`, `following`, `bookmarks`, or `messages` into the local mirror; costs credits. | local |
166
+ | `sql [query]` | Query your synced local mirror with read-only SQL - free; bare `sql` prints the schema. | |
167
+ | `post` | Create a post (body from stdin). | write |
168
+ | `message <recipients>` | Send a DM (body from stdin). | write |
169
+ | `like <target>` / `unlike <target>` | Like or unlike a post. | write |
170
+ | `follow <target>` / `unfollow <target>` | Follow or unfollow a user. | write |
171
+ | `repost <target>` / `unrepost <target>` | Repost or undo a repost. | write |
172
+ | `bookmark <target>` / `unbookmark <target>` | Add or remove a saved post. | write |
173
+ | `delete <target>` | Delete one of your own posts. | write |
173
174
 
174
175
  ## Built for agents
175
176
 
176
- - **Everything speaks JSON.** Pipe output through `jq`, `fzf`, or your agent's
177
- planner anything that reads stdin. Structured errors and predictable exit
178
- codes mean an agent can branch on what happened.
179
- - **Schema-backed pagination.** Use `--offset` for LinkedIn list reads,
180
- `--cursor` for LinkedIn messages and X reads, and `--limit` to bound pages.
181
- Cacheable reads also list `-H/--header` for proxy cache headers such as
182
- `Cache-Control: no-cache`.
183
- - **A skill you drop straight in.** Install the public skill repo with
184
- `npx skills add usesocial/skill`; Claude, Codex, or any other supported agent
185
- then knows the commands.
177
+ - Everything speaks JSON: success on stdout, structured errors on stderr.
178
+ - Platform reads return one envelope: lists use `.items[]`, single resources use
179
+ `.data`, metadata lives under `.meta`. `social account` service commands return
180
+ bare JSON; `account logs` returns `{ items, meta: { cursor } }`.
181
+ - Schema-backed planning: `social schema --list` is the compact runnable index.
182
+ - Local SQL is the free surface for your own synced data.
186
183
 
187
184
  ```sh
188
- # Review recent LinkedIn posts, fan out to reaction graphs, rank warm contacts.
189
- social linkedin posts --limit 25 --offset 0 > /tmp/recent-posts.json
185
+ # SQL insight: synced contacts you have never messaged.
186
+ # Run `social linkedin sync connections` and `social linkedin sync messages` first.
187
+ social linkedin sql "SELECT c.user_display_name, c.user_public_identifier, c.user_profile_url FROM li_connections c LEFT JOIN li_messages m ON m.sender_id = c.user_id WHERE m.id IS NULL ORDER BY c.created_at DESC LIMIT 100" \
188
+ | jq '.items[]'
189
+
190
+ # Live fan-out: review recent posts, fan out to reactions, rank warm contacts.
191
+ social linkedin posts profile_id:<profile-id> --limit 25 > /tmp/recent-posts.json
190
192
  jq -r '.items[].id' /tmp/recent-posts.json \
191
193
  | xargs -I{} social linkedin reactions post_id:{} --limit 100 --offset 0 \
192
194
  | jq -s '[ .[] | .items[] ]
@@ -198,125 +200,107 @@ jq -r '.items[].id' /tmp/recent-posts.json \
198
200
  ## Exit codes
199
201
 
200
202
  | Code | Meaning | Agent action |
201
- |---:|---|---|
203
+ | ---: | --- | --- |
202
204
  | `0` | Success | Continue. |
203
- | `2` | Usage or validation error | Fix the command, flags, IDs, JSON body, or local input. |
205
+ | `2` | Usage or validation error | Fix the command, flags, IDs, JSON body, or local input - server-side failures are exit 5. |
204
206
  | `3` | Not found | Check the resource ID or pick a different item. |
205
207
  | `4` | Auth or scope error | Run `social account login`, or log out and choose the needed scope. |
206
- | `5` | API or unexpected error | Retry later or surface the server error. |
207
- | `7` | Rate limited | LinkedIn retries automatically; otherwise back off, using `retryAfterSeconds` when present. |
208
+ | `5` | API, proxy, or unexpected error | Retry later or surface the server error. |
209
+ | `7` | Rate limited | Back off, using `retryAfterSeconds` when present. |
208
210
 
209
211
  ## Auth
210
212
 
211
- `social account login` runs a device-authorization flow:
212
-
213
- 1. Asks what access to grant the agent. Read and Write are both selected by
214
- default; clear Write in the prompt to grant read-only access.
215
- 2. Asks for your email address.
216
- 3. Sends a magic link to that email with the device approval screen already
217
- attached while asking for your phone number.
218
- 4. Waits until you click the magic link and approve the CLI session in the
219
- browser, then stores the returned token in your OS keyring.
220
- 5. Stores the phone number, then confirms billing checkout in the terminal when
221
- a seat is needed. If no keyring is available, credentials fall back to
222
- `~/.social/credentials.json` (mode `0600`).
223
- Non-production `SOCIAL_API_URL` values use an API-specific credential
224
- namespace so staging tests do not overwrite the production session.
225
-
226
- `social account logout` revokes the session and removes the stored token from both places.
227
- Bare `social account` prints compact JSON with the current auth state, credential
228
- namespace, verified session when available, and connected accounts.
229
- `social account login` requires an interactive terminal and is not supported from CI,
230
- background jobs, or agent-mediated setup flows.
213
+ `social account login` runs a device-authorization flow. It asks what access to
214
+ grant, sends a magic link, waits for browser approval, stores the returned token
215
+ in your OS keyring, and confirms billing checkout when a seat is needed.
216
+
217
+ `social account logout` revokes the session and removes the stored token.
218
+ `social account login` requires an interactive terminal and is not supported from
219
+ CI, background jobs, or agent-mediated setup flows.
231
220
 
232
221
  `social account billing` prints the current seat/subscription snapshot plus
233
- aggregate usage billing. `social account billing portal` opens the hosted billing
234
- portal when possible and always prints the portal URL as JSON; use the portal for
235
- payment methods, invoices, plan changes, seat changes, and cancellation.
222
+ aggregate usage billing. `social account billing portal` opens the hosted
223
+ billing portal when possible and always prints the portal URL as JSON.
236
224
 
237
225
  ## Cache config
238
226
 
239
- Allowlisted GET requests use a local proxy cache. Cacheable commands send
240
- `Cache-Control: max-age=<seconds>` from your local config:
227
+ There are two cache layers.
228
+
229
+ The proxy cache applies to live reads only. Cache hits are free; fresh upstream
230
+ reads are metered. Configure the default:
241
231
 
242
232
  ```sh
243
- social account config cache mode # read the current cache mode and TTL
244
- social account config cache mode live # 15 minutes, default
245
- social account config cache mode analytical # 24 hours
246
- social account config cache mode historical # 1 week
247
- social account config cache ttl 3600 # custom TTL in seconds
233
+ social account config cache mode
234
+ social account config cache mode live
235
+ social account config cache mode analytical
236
+ social account config cache mode historical
237
+ social account config cache ttl 3600
248
238
  ```
249
239
 
250
- Setting `ttl` switches the mode to `custom`. Config is stored at
251
- `~/.social/config.json` with mode `0600`.
252
-
253
- Use command-level request headers to override freshness for a single read when a
254
- command lists `--header` in help:
240
+ Override one live read when the command lists `--header`:
255
241
 
256
242
  ```sh
257
- social linkedin profile @handle -H "Cache-Control: no-cache" # bypass cache read, refresh cache
258
- social linkedin profile @handle -H "Cache-Control: no-store" # bypass cache read and write
259
- social linkedin profile @handle -H "Cache-Control: max-age=60" # override TTL for this request
243
+ social linkedin profile @handle -H "Cache-Control: no-cache"
244
+ social linkedin profile @handle -H "Cache-Control: no-store"
245
+ social linkedin profile @handle -H "Cache-Control: max-age=60"
260
246
  ```
261
247
 
262
- `Cache-Control` is the functional request cache surface. Cached responses may
263
- preserve validators such as `ETag` and `Last-Modified` when the upstream returns
264
- them, but the CLI does not expose conditional revalidation semantics; use
265
- `Cache-Control: no-cache` when you need a fresh upstream read.
266
-
267
- Command output exposes actual per-call cost and pagination under `meta`:
248
+ The local mirror is separate: run `sync` when you want newer local data, then
249
+ query it with `sql`. SQL reads show local freshness in `meta.cache.tables`:
268
250
 
269
251
  ```sh
270
- social linkedin reactions post_id:<post-id> --limit 100 --offset 0 \
271
- | jq '{cost: .meta.cost, totalCount: .meta.totalCount}'
272
- social linkedin messages --limit 20 | jq '{cost: .meta.cost, cursor: .meta.cursor}'
273
- social x bookmarks --limit 20 | jq '{cost: .meta.cost, cursor: .meta.cursor}'
252
+ social x sql "SELECT sender_handle, text FROM x_messages ORDER BY created_at DESC LIMIT 5" \
253
+ | jq '{cost: .meta.cost, cache: .meta.cache}'
254
+ social x timeline --limit 20 | jq '{cost: .meta.cost, cursor: .meta.cursor, cache: .meta.cache}'
274
255
  ```
275
256
 
276
- Agents should watch `.meta.cost` during high-fanout loops, use `social account billing`
277
- for the current plan snapshot, and use `social account usage` or `social account logs`
278
- after a run to summarize actual spend.
279
-
280
- ## Account safety
281
-
282
- Built so your accounts outlive your prototype.
283
-
284
- - **Read/write scope by default.** Clear Write during login when you want a
285
- read-only session that can't post, react, or request connections.
286
- - **A write never fires twice.** Rate-limit and server errors surface verbatim and
287
- writes are never retried — so a post or connection request can't double-send.
288
- - **A residential IP per account.** Each connected account runs over a dedicated
289
- residential proxy with smart rate-limiting, so the network sees a normal session.
257
+ Agents should watch `.meta.cost` during high-fanout loops, use
258
+ `social account billing` for the current plan snapshot, and use
259
+ `social account usage` or `social account logs` after a run to summarize spend.
290
260
 
291
261
  ## Examples
292
262
 
293
263
  ```sh
294
- # LinkedIn
295
- social linkedin profile
296
- social linkedin requests received --limit 25 --offset 0
297
- social linkedin requests sent --limit 25 --offset 0
264
+ # LinkedIn local mirror.
265
+ social linkedin sync messages
266
+ social linkedin sql "SELECT sender_display_name, text, datetime(timestamp/1000,'unixepoch') AS at FROM li_messages ORDER BY timestamp DESC LIMIT 20"
267
+ social linkedin sql "SELECT user_display_name, user_public_identifier FROM li_requests WHERE type='received' ORDER BY created_at DESC LIMIT 25"
298
268
 
299
- # X
300
- social x bookmarks --limit 50
301
- social x followers --limit 100
302
- social x following profile_id:<x-user-id> --limit 100
269
+ # LinkedIn live reads.
270
+ social linkedin profile
271
+ PAGE1=$(social linkedin posts profile_id:<profile-id> --limit 25)
272
+ NEXT=$(echo "$PAGE1" | jq -r '.meta.cursor // empty')
273
+ [ -n "$NEXT" ] && social linkedin posts profile_id:<profile-id> --limit 25 --cursor "$NEXT"
274
+ social linkedin reactions post_id:<post-id> --limit 100 --offset 0
275
+
276
+ # X local mirror.
277
+ social x sync messages
278
+ social x sql "SELECT sender_handle, text FROM x_messages ORDER BY created_at DESC LIMIT 20"
279
+ social x sql "SELECT text, url FROM x_bookmarks ORDER BY created_at DESC LIMIT 50"
280
+ social x sql "SELECT username, name, followers_count FROM x_followers ORDER BY followers_count DESC LIMIT 100"
281
+
282
+ # X live reads.
283
+ social x tweets profile_id:<x-user-id> --limit 30
303
284
  social x replies post_id:<post-id> --limit 25
304
- social x messages --limit 50
285
+ social x timeline --limit 50
305
286
 
306
- # Writes (body via stdin)
287
+ # Writes (body via stdin).
307
288
  echo "gm" | social x post
308
289
  social linkedin post < draft.md
290
+ echo "Loved your launch notes." | social linkedin requests send profile_id:<profile-id>
309
291
 
310
- # Usage / billing
292
+ # Usage / billing.
311
293
  social account billing
312
294
  social account billing portal
313
295
  social account usage
314
- social account logs --limit 20 --from 2026-05-01T00:00:00Z
296
+ social account logs --limit 20 --from 2026-05-01T00:00:00Z \
297
+ | jq -r '.items[] | [.createdAt, .platform, .method, .path, .responseStatus, .cacheStatus, .credits] | @tsv'
315
298
 
316
- # Command schema
299
+ # Command schema.
317
300
  social schema
301
+ social schema --list
318
302
  social schema --leaves
319
- social schema "linkedin requests received"
303
+ social schema "linkedin requests send"
320
304
  social schema "x post"
321
305
  ```
322
306