@curviate/cli 0.21.0 → 0.22.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 +190 -116
- package/README.md +18 -18
- package/dist/{account-A3FOYUKC.js → account-QRGWUQXF.js} +25 -25
- package/dist/{chunk-EEMJDJ4W.js → chunk-H6XD3F66.js} +7 -0
- package/dist/{chunk-LMVDURUZ.js → chunk-JA3NNST6.js} +35 -4
- package/dist/{chunk-M6UDWFHX.js → chunk-PMRQXBCP.js} +1 -1
- package/dist/{chunk-ROULHEFW.js → chunk-RFUO2G3M.js} +4 -3
- package/dist/{chunk-Q7XG2VIF.js → chunk-T5LPGAGJ.js} +6 -6
- package/dist/cli.js +58 -26
- package/dist/{comment-RPLZHFJQ.js → comment-MCGXFMN4.js} +3 -3
- package/dist/{company-DFJK2RHM.js → company-WDDLWP7E.js} +12 -12
- package/dist/{connect-ELSSMOIC.js → connect-5OROSY5C.js} +12 -12
- package/dist/{exit-codes-63JE5GM5.js → exit-codes-KAVZN5BQ.js} +1 -1
- package/dist/{feed-23Z7OQNL.js → feed-SFVYEAYP.js} +3 -3
- package/dist/{group-52MP24W3.js → group-HSZY2IJU.js} +3 -3
- package/dist/{inbox-G6KNWWLI.js → inbox-L6JBGZIB.js} +4 -4
- package/dist/{inboxes-NTTYCQPM.js → inboxes-UIO74C5Q.js} +5 -5
- package/dist/{job-WOPIAHOR.js → job-75ML7R7I.js} +4 -4
- package/dist/{message-KJXY5RCD.js → message-DAQHRBSJ.js} +2 -2
- package/dist/{notification-MNEABNVW.js → notification-DYJN4ZHN.js} +3 -3
- package/dist/{post-A7YZWBFG.js → post-RGDOCGC4.js} +5 -5
- package/dist/{profile-XOMDIYSY.js → profile-TJS2YAZD.js} +8 -8
- package/dist/{recruiter-CCLG4PM4.js → recruiter-NSM33IEK.js} +10 -10
- package/dist/{sales-nav-5ZRE2UAQ.js → sales-nav-5O7FR57S.js} +6 -6
- package/dist/{search-NDESJC3Y.js → search-TDSLK2MB.js} +13 -13
- package/dist/{webhook-TNZF3FMN.js → webhook-7ESDSIRU.js} +9 -9
- package/package.json +4 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,80 @@ a new command or flag is a minor; a breaking command/flag/exit-code change is a
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.22.0] - 2026-08-07
|
|
12
|
+
|
|
13
|
+
Two correctness fixes for the same underlying failure: a command that answers
|
|
14
|
+
a different question than the one you asked, without saying so.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **A trailing argument a command cannot use is now an error (exit 2), not
|
|
19
|
+
something to ignore.** `curviate profile me relations` used to return your
|
|
20
|
+
own profile at exit 0 with nothing on stderr, so a caller reading `.items`
|
|
21
|
+
found nothing and concluded the account had no connections. Any unusable
|
|
22
|
+
trailing token behaved the same way, so a typo such as `profile me
|
|
23
|
+
reltaions` was swallowed just as quietly. The check now runs on the command
|
|
24
|
+
that is actually about to execute, whatever route reached it, and the
|
|
25
|
+
message names what you typed, how many positional arguments it takes, and
|
|
26
|
+
its own `--help`. When the stray token is a real sibling command, the
|
|
27
|
+
message names the form you meant, so `profile me relations` points you at
|
|
28
|
+
`profile relations`. **This can turn an invocation that used to exit 0 into
|
|
29
|
+
an exit 2.** It never turned into the answer you wanted, so a script
|
|
30
|
+
relying on it was already getting the wrong data; the fix makes that
|
|
31
|
+
visible.
|
|
32
|
+
|
|
33
|
+
- **Punctuation swept out of the published copy and the printed help.** The
|
|
34
|
+
README, this changelog, and the help and error strings in `src/` used
|
|
35
|
+
typographic characters with no plain-ASCII equivalent on the keyboard: em and
|
|
36
|
+
en dashes, the single-glyph ellipsis, arrows. An id placeholder now elides
|
|
37
|
+
with `acc_...`, a range reads `1-100`, and a mapping reads
|
|
38
|
+
`write->read`. No release note changed what it claims; the changelog's word
|
|
39
|
+
stream is byte-identical to before. Two non-ASCII characters stay on purpose:
|
|
40
|
+
the redaction mask `config list` prints, and the literal emoji that documents
|
|
41
|
+
`message react`'s own argument.
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **`notices[]` now survives projection.** 0.21.1 taught the renderer to show
|
|
46
|
+
a response's notices, but the slim projection and `--fields` both run
|
|
47
|
+
before it, and several of them rebuilt the response from a fixed list of
|
|
48
|
+
keys that never included `notices`. So on `account list`, `connect sent`,
|
|
49
|
+
`connect received`, and on any single-object response under `--fields`, the
|
|
50
|
+
array was destroyed before it could be shown. The notice is now carried
|
|
51
|
+
across projection at the single point every command's output passes
|
|
52
|
+
through, so it reaches you regardless of the command or the flags. A
|
|
53
|
+
response without notices renders exactly as before.
|
|
54
|
+
|
|
55
|
+
### Added
|
|
56
|
+
|
|
57
|
+
- **`pnpm check:copy`**, a pre-publish copy-quality gate over the npm-page copy
|
|
58
|
+
(README, changelog, package description), chained into `prepack` next to the
|
|
59
|
+
existing internal-reference scan. It fails the pack on any non-ASCII
|
|
60
|
+
typographic character and reports, without failing, wording from the generic
|
|
61
|
+
marketing register. The printed help and error strings keep their own gate,
|
|
62
|
+
`test/copy-tells.test.ts`, which walks the TypeScript AST so it judges string
|
|
63
|
+
literals and never comments; that test now covers the full character set
|
|
64
|
+
rather than the em dash alone.
|
|
65
|
+
|
|
66
|
+
## [0.21.1] - 2026-08-06
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- **A response's `notices[]` array is no longer silently dropped.** Both
|
|
71
|
+
render paths now surface it: JSON mode already passed it through, and human
|
|
72
|
+
mode now prints it above the results it qualifies, covering a filter value
|
|
73
|
+
that took the id fast path (field + value) and a page whose results are
|
|
74
|
+
anonymised upstream (no field/value). Previously a caller got an empty or
|
|
75
|
+
unexplained result set with nothing telling them why.
|
|
76
|
+
- **`--all` (NDJSON streaming) now surfaces per-page notices too.** stdout
|
|
77
|
+
stays pure one-object-per-line data; a page's notices are written to
|
|
78
|
+
stderr through the same renderer the human-mode path uses, so a long-running
|
|
79
|
+
`--all` consumer sees the same explanation a single-page call would.
|
|
80
|
+
- **`visibility` is back in the default (non-verbose) `search people` fields.**
|
|
81
|
+
It was missing from the default field allowlist even though the server
|
|
82
|
+
always sends it, so a row for a hidden or unresolved profile looked
|
|
83
|
+
identical to a normal one unless you passed `--verbose`.
|
|
84
|
+
|
|
11
85
|
## [0.21.0] - 2026-08-04
|
|
12
86
|
|
|
13
87
|
A correctness release for every argument that reads from stdin. Upgrade
|
|
@@ -150,21 +224,21 @@ covered by the published SDK, so no SDK bump was required).
|
|
|
150
224
|
|
|
151
225
|
### Added
|
|
152
226
|
|
|
153
|
-
- **`inbox search
|
|
154
|
-
- **`search groups`, `search services`, `search service-parameters
|
|
227
|
+
- **`inbox search`**: search chats via `messaging.searchChats`.
|
|
228
|
+
- **`search groups`, `search services`, `search service-parameters`**: new search
|
|
155
229
|
surfaces for groups, services, and service search parameters.
|
|
156
|
-
- **`post saved`, `post save`, `post unsave
|
|
230
|
+
- **`post saved`, `post save`, `post unsave`**: list, save, and unsave posts.
|
|
157
231
|
- **`company managed`, `company followers`, `company chats`, `company chat`,
|
|
158
|
-
`company messages`, `company message`, `company search-chats
|
|
232
|
+
`company messages`, `company message`, `company search-chats`**: company-inbox
|
|
159
233
|
and managed-company read/write surface.
|
|
160
|
-
- **`profile subscription`, `profile analytics`, `profile visitors`, `profile ssi
|
|
161
|
-
|
|
234
|
+
- **`profile subscription`, `profile analytics`, `profile visitors`, `profile ssi`**:
|
|
235
|
+
account-scoped profile insight subcommands (subscription status, post/profile
|
|
162
236
|
analytics, visitor list, Social Selling Index).
|
|
163
|
-
- **`group` command group
|
|
164
|
-
- **`feed`, `feed home
|
|
237
|
+
- **`group` command group**, new top-level group closing the LinkedIn Groups gap.
|
|
238
|
+
- **`feed`, `feed home`**: new command group to read the connected account's
|
|
165
239
|
LinkedIn home feed as agent-actionable posts.
|
|
166
240
|
- **`notification`, `notification list`, `notification delete`,
|
|
167
|
-
`notification show-less
|
|
241
|
+
`notification show-less`**: new command group to read and act on LinkedIn
|
|
168
242
|
notification cards.
|
|
169
243
|
|
|
170
244
|
Parity with the SDK surface is now 145/0 (no known gaps).
|
|
@@ -175,11 +249,11 @@ A patch aligning `company reply` with the company-inbox chat-id cutover. No brea
|
|
|
175
249
|
|
|
176
250
|
### Fixed
|
|
177
251
|
|
|
178
|
-
- **`company reply <id> <chat_id> "<text>"`** now takes the normal `2
|
|
252
|
+
- **`company reply <id> <chat_id> "<text>"`** now takes the normal `2-...` conversation
|
|
179
253
|
id that `company chats` returns; the endpoint resolves the page mailbox internally from
|
|
180
254
|
the company identifier, so the earlier `COMPANY_` chat-id requirement is gone. `--preview`
|
|
181
255
|
now always prints a "Will send as company page `<id>`" notice derived from the resolved
|
|
182
|
-
identifier (previously it went silent for a bare `2
|
|
256
|
+
identifier (previously it went silent for a bare `2-...` id). Reply-only and admin-gated,
|
|
183
257
|
otherwise unchanged.
|
|
184
258
|
|
|
185
259
|
## [0.18.0] - 2026-07-17
|
|
@@ -188,10 +262,10 @@ A minor release adding the `company reply` command. No breaking changes, built a
|
|
|
188
262
|
|
|
189
263
|
### Added
|
|
190
264
|
|
|
191
|
-
- **`company reply <id> <chat_id> "<text>" [--attach <file
|
|
265
|
+
- **`company reply <id> <chat_id> "<text>" [--attach <file>...]`** (write, admin-gated,
|
|
192
266
|
`--preview` accepted). Replies to an existing company-inbox conversation as the page,
|
|
193
267
|
via the SDK's `companies.sendMessage`. `<chat_id>` must be a `COMPANY_` chat id from
|
|
194
|
-
`inboxes chats`, not the `2
|
|
268
|
+
`inboxes chats`, not the `2-...` id the `company` reads return; it passes through verbatim
|
|
195
269
|
(no client-side pre-check) and a non-`COMPANY_` id is rejected by the API with a guiding
|
|
196
270
|
400 naming the fix. Reply-only: it cannot start a new conversation on the page's behalf.
|
|
197
271
|
`<id>` accepts a URL, slug, or numeric id, resolved to the numeric id first (including
|
|
@@ -206,7 +280,7 @@ commands. No breaking changes, built against `@curviate/sdk` 0.17.0.
|
|
|
206
280
|
|
|
207
281
|
### Added
|
|
208
282
|
|
|
209
|
-
- **`company follow-invite <id> --invitee <AC
|
|
283
|
+
- **`company follow-invite <id> --invitee <AC...> [--invitee <AC...> ...]`** (write, admin-gated,
|
|
210
284
|
`--preview` accepted). Invites the connected account's 1st-degree connections to follow an
|
|
211
285
|
administered company page. `--invitee` is repeatable, at least one required, max 50 per
|
|
212
286
|
request. All-or-nothing: for an all-valid request you get one outcome per requested invitee,
|
|
@@ -237,7 +311,7 @@ built against `@curviate/sdk` 0.16.0.
|
|
|
237
311
|
[--cursor] [--all]` lists a single inbox's conversations, cursor-paginated
|
|
238
312
|
like every other list command. Every returned chat id is send-ready: reply
|
|
239
313
|
with the existing `message send <chat_id> "<text>"`. A company inbox's
|
|
240
|
-
chat id (e.g. `COMPANY_83734124_2
|
|
314
|
+
chat id (e.g. `COMPANY_83734124_2-...`) sends AS THE PAGE, no separate flag
|
|
241
315
|
needed. Company inboxes are reply-only and cannot start a new conversation.
|
|
242
316
|
Distinct from the existing `inbox` command group (a friendlier front door
|
|
243
317
|
to the account's own message-thread inbox: `messaging.listChats`/`getChat`/
|
|
@@ -274,11 +348,11 @@ A patch release fixing an interactive-terminal hang on `account link`.
|
|
|
274
348
|
|
|
275
349
|
- **`account link --password-stdin` / `--li-at-stdin` no longer hang on an
|
|
276
350
|
interactive terminal.** These flags previously read stdin to EOF, which a
|
|
277
|
-
human paste + Enter never produces on a TTY
|
|
351
|
+
human paste + Enter never produces on a TTY; the command hung
|
|
278
352
|
indefinitely and the pasted secret echoed on-screen. The read is now
|
|
279
353
|
mode-aware: piped/redirected stdin (non-TTY) is unchanged (read to EOF,
|
|
280
354
|
trimmed); an interactive TTY now prints a single cue line, then reads one
|
|
281
|
-
no-echo line
|
|
355
|
+
no-echo line; paste + Enter resolves immediately, including a paste whose
|
|
282
356
|
clipboard content ends in a trailing newline. An empty line still falls
|
|
283
357
|
through to the normal resolution order (env var, then the password
|
|
284
358
|
prompt / `li_at` fail-fast).
|
|
@@ -296,15 +370,15 @@ streams, one back-compatible reaction-signature unification, and a
|
|
|
296
370
|
### Added
|
|
297
371
|
|
|
298
372
|
- **Successor hints for removed/renamed commands.** Reaching for a command that
|
|
299
|
-
moved or was removed in 0.15.0
|
|
373
|
+
moved or was removed in 0.15.0 (`post list`, `post comment`/`comments`,
|
|
300
374
|
`connect respond`, `profile connections`, `account connect-link`/`reconnect-link`/`reconnect`,
|
|
301
375
|
`inbox sync`/`sync-chat`, `recruiter add-candidate`/`project-jobs`/`sync`,
|
|
302
|
-
`sales-nav sync`, `webhook state-diff`, `company followers`
|
|
376
|
+
`sales-nav sync`, `webhook state-diff`, `company followers`) now prints a
|
|
303
377
|
one-line "did you mean" pointer to the replacement instead of a bare
|
|
304
378
|
"unknown command". The exit code is unchanged (2).
|
|
305
379
|
- **`--all` NDJSON-mode notice.** When `--all` streaming engages, a one-line
|
|
306
|
-
notice on stderr makes the format switch explicit (`--all` streams NDJSON
|
|
307
|
-
one object per line
|
|
380
|
+
notice on stderr makes the format switch explicit (`--all` streams NDJSON,
|
|
381
|
+
one object per line, not the `{items, cursor}` envelope), so an agent
|
|
308
382
|
pattern-matching the plain-mode shape does not mis-parse the stream.
|
|
309
383
|
- **`--page-delay <ms>` and default `--all` pacing.** `--all` now pauses a
|
|
310
384
|
modest default between page fetches, keeping a long stream under the platform
|
|
@@ -312,12 +386,12 @@ streams, one back-compatible reaction-signature unification, and a
|
|
|
312
386
|
- **`job list --state ALL`.** A best-effort client-side union across every state
|
|
313
387
|
(DRAFT/OPEN/CLOSED/REVIEW/SUSPENDED): each state is queried, re-filtered
|
|
314
388
|
against its own state, then merged and de-duplicated by id. There is no
|
|
315
|
-
unified cursor
|
|
389
|
+
unified cursor; each state is walked independently and `--max-pages` applies
|
|
316
390
|
per state.
|
|
317
391
|
- **`--fields` unknown-field warning.** Projecting a field that matches nothing
|
|
318
392
|
on the response now emits one stderr warning naming the unmatched fields and
|
|
319
393
|
listing the available keys, instead of silently returning `{}`. The output is
|
|
320
|
-
unchanged
|
|
394
|
+
unchanged; the known fields still project.
|
|
321
395
|
|
|
322
396
|
### Changed
|
|
323
397
|
|
|
@@ -345,7 +419,7 @@ streams, one back-compatible reaction-signature unification, and a
|
|
|
345
419
|
|
|
346
420
|
## [0.15.0] - 2026-07-11
|
|
347
421
|
|
|
348
|
-
Full v2 API-surface parity
|
|
422
|
+
Full v2 API-surface parity, the coupled release with `@curviate/sdk` 0.15.0. A large
|
|
349
423
|
**breaking** minor (pre-1.0): the CLI is re-pointed onto the v2-only API, drops the
|
|
350
424
|
commands whose endpoint no longer exists, relocates several verbs, and adds commands for
|
|
351
425
|
the new v2 methods. Every command noun kept its intent-shaped name; only the wiring,
|
|
@@ -355,43 +429,43 @@ removed orphans, relocations, and additions changed.
|
|
|
355
429
|
|
|
356
430
|
Commands whose underlying v2 endpoint no longer exists:
|
|
357
431
|
|
|
358
|
-
- **`account connect-link`**, **`account reconnect-link`**, **`account reconnect
|
|
432
|
+
- **`account connect-link`**, **`account reconnect-link`**, **`account reconnect`**: the hosted-link and in-place re-auth flows. Connect a new account with `account link`; poll a hosted session with `account connect-session poll`.
|
|
359
433
|
- **`company followers`**
|
|
360
|
-
- **`inbox sync`**, **`inbox sync-chat
|
|
434
|
+
- **`inbox sync`**, **`inbox sync-chat`**: message history now syncs implicitly.
|
|
361
435
|
- **`post list`**
|
|
362
436
|
- **`recruiter sync`**, **`recruiter add-applicant`**, **`recruiter reject-applicant`**, **`recruiter job checkpoint`**
|
|
363
437
|
- **`sales-nav sync`**
|
|
364
438
|
- **`webhook state-diff`**
|
|
365
439
|
|
|
366
|
-
Flags with no v2 request-side home
|
|
440
|
+
Flags with no v2 request-side home, dropped entirely (not defined, parsed, or forwarded), with no replacement:
|
|
367
441
|
|
|
368
|
-
- **`profile --notify
|
|
369
|
-
- **`message inmail --surface
|
|
370
|
-
- **`post create --video-thumbnail
|
|
371
|
-
- **`search people|companies|posts|jobs --url
|
|
442
|
+
- **`profile --notify`**: signal-a-view has no v2 request field.
|
|
443
|
+
- **`message inmail --surface`**: the v2 send-InMail body carries no surface/type discriminator.
|
|
444
|
+
- **`post create --video-thumbnail`**: v2 posts carry media only via `--attach`.
|
|
445
|
+
- **`search people|companies|posts|jobs --url`**: from-URL search is now the bare `search <url>` form.
|
|
372
446
|
|
|
373
447
|
### Changed (BREAKING)
|
|
374
448
|
|
|
375
449
|
Renames and relocations:
|
|
376
450
|
|
|
377
|
-
- **`post comment`** / **`post comments`** (and `post react --comment-id`)
|
|
378
|
-
- **`connect respond --accept` / `--decline`**
|
|
379
|
-
- **`recruiter add-candidate`**
|
|
380
|
-
- **`recruiter project-jobs`**
|
|
381
|
-
- **`recruiter job applicants`**
|
|
382
|
-
- **`profile connections`**
|
|
383
|
-
- **`profile endorse --skill`**
|
|
451
|
+
- **`post comment`** / **`post comments`** (and `post react --comment-id`) -> the new **`comment`** group (`comment add`, `comment reply`, `comment react`, and the rest). Comment threads are first-class.
|
|
452
|
+
- **`connect respond --accept` / `--decline`** -> **`connect accept <id>`** / **`connect decline <id>`**; the combined `respond` is removed.
|
|
453
|
+
- **`recruiter add-candidate`** -> **`recruiter save-candidate <project_id> --stage-id <id> --candidate-id <id>`** (full body reshape).
|
|
454
|
+
- **`recruiter project-jobs`** -> **`recruiter project-job get <project_id>`** (cardinality fix: a project has at most one attached posting; single-object read, no pagination).
|
|
455
|
+
- **`recruiter job applicants`** -> **`recruiter applicants <project_id>`** (the applicant list is project-scoped, not job-scoped; `--channel-id` still required).
|
|
456
|
+
- **`profile connections`** -> **`profile relations`**.
|
|
457
|
+
- **`profile endorse --skill`** -> **`profile endorse --endorsement-id`**, value semantics unchanged (still the target's `endorsement_id`, obtained from their skills section via `profile <id> --sections skills`); the old flag name misleadingly suggested a skill name.
|
|
384
458
|
|
|
385
459
|
CLI-visible shape changes:
|
|
386
460
|
|
|
387
461
|
- **`job publish`** now requires **`--mode`** (`FREE | PROMOTED | PROMOTED_PLUS`); `PROMOTED`/`PROMOTED_PLUS` additionally require the full `--budget-*` triple.
|
|
388
|
-
- **`recruiter job create`** now requires **`--project-name`** and takes the full v2 job body
|
|
389
|
-
- **`recruiter message new`** is now **JSON-only** (file/voice/video attachments ride the body as base64
|
|
462
|
+
- **`recruiter job create`** now requires **`--project-name`** and takes the full v2 job body; `--employment-status` replaces the pre-v2 `--employment-type` on this command, alongside the company / workplace / location flags.
|
|
463
|
+
- **`recruiter message new`** is now **JSON-only** (file/voice/video attachments ride the body as base64, no multipart) and requires **`--subject`** and **`--signature`**.
|
|
390
464
|
|
|
391
465
|
Dependency and request grammar:
|
|
392
466
|
|
|
393
467
|
- **`@curviate/sdk` bumped to `0.15.0`.**
|
|
394
|
-
- **Account-first path grammar.** Every account-scoped request now addresses the account in the URL path instead of a query/body field. This is handled entirely inside the SDK
|
|
468
|
+
- **Account-first path grammar.** Every account-scoped request now addresses the account in the URL path instead of a query/body field. This is handled entirely inside the SDK, no CLI syntax changes, but every command's underlying request moved.
|
|
395
469
|
|
|
396
470
|
### Added
|
|
397
471
|
|
|
@@ -399,7 +473,7 @@ New **`comment`** command group (the comment-thread surface):
|
|
|
399
473
|
|
|
400
474
|
- `comment list <post_id>`, `comment add`, `comment reply`, `comment edit`, `comment delete`, `comment replies`, `comment react`, `comment reactions`, `comment unreact`, `comment user`.
|
|
401
475
|
|
|
402
|
-
Job-posting management
|
|
476
|
+
Job-posting management, the **`job`** family:
|
|
403
477
|
|
|
404
478
|
- `job list`, `job create`, `job update`, `job budget`, `job publish`, `job close`, `job applicants`, `job applicant get`, and `job applicant resume` (binary résumé download via `-o`).
|
|
405
479
|
|
|
@@ -425,68 +499,68 @@ Sales Navigator:
|
|
|
425
499
|
|
|
426
500
|
Account:
|
|
427
501
|
|
|
428
|
-
- **`account link --account-id <acc_
|
|
502
|
+
- **`account link --account-id <acc_...>`** (optional, non-breaking): re-authenticate an existing account **in place** (reconnect): passing the id makes `account link` an in-place reconnect of that account; omit it for an ordinary fresh connect (unchanged, no `account_id` is sent). This is the reconnect path now that the hosted `account reconnect` / `account reconnect-link` commands are removed.
|
|
429
503
|
|
|
430
504
|
Exit-code mapping:
|
|
431
505
|
|
|
432
|
-
- **`ACCOUNT_ALREADY_LINKED`** and **`LINKEDIN_OPERATION_NOT_SUPPORTED`** are now present in `EXIT_CODE_MAP` (exit `8`, account / connection state
|
|
433
|
-
- **`CONNECTION_REQUEST_CONFLICT`** (exit `8`, account / connection state
|
|
506
|
+
- **`ACCOUNT_ALREADY_LINKED`** and **`LINKEDIN_OPERATION_NOT_SUPPORTED`** are now present in `EXIT_CODE_MAP` (exit `8`, account / connection state, grouped with `ACCOUNT_RESTRICTED`/`RESOURCE_ACCESS_RESTRICTED`); previously `ACCOUNT_ALREADY_LINKED` was already a valid SDK `ErrorCode` but had no exit-code entry, and `LINKEDIN_OPERATION_NOT_SUPPORTED` is a new SDK code (a permanent LinkedIn platform limitation for the attempted operation, e.g. listing a non-self user's following list). Both were silently falling through to the default exit `1`; the exhaustiveness test now covers them.
|
|
507
|
+
- **`CONNECTION_REQUEST_CONFLICT`** (exit `8`, account / connection state, the documented "already invited or already connected" contract on a `connect` retry) and **`RATE_LIMITED`** (exit `6`, rate-limited, a general/unscoped rate-limit signal alongside `RATE_LIMIT_ACCOUNT`/`RATE_LIMIT_TENANT`/`PLATFORM_RATE_LIMIT`/`LINKEDIN_RATE_LIMITED`) are new SDK error codes, both now present in `EXIT_CODE_MAP`. Picked up via the refreshed `@curviate/sdk` 0.15.0 tarball dependency (pnpm-lock.yaml integrity hash only).
|
|
434
508
|
|
|
435
509
|
### Fixed
|
|
436
510
|
|
|
437
|
-
- **`company <id> employees` / `company <id> posts` / `company <id> jobs` (id-first form) no longer silently returns the base company profile.** The router bound `<id>` and dropped the trailing sub-resource word, so the id-first form quietly returned the company profile with exit 0. It now routes the id-first form to the sub-resource (equivalent to `company <sub> <id>`), or exits 2 with an actionable error on a genuinely unexpected extra argument
|
|
511
|
+
- **`company <id> employees` / `company <id> posts` / `company <id> jobs` (id-first form) no longer silently returns the base company profile.** The router bound `<id>` and dropped the trailing sub-resource word, so the id-first form quietly returned the company profile with exit 0. It now routes the id-first form to the sub-resource (equivalent to `company <sub> <id>`), or exits 2 with an actionable error on a genuinely unexpected extra argument, never a silent wrong result. The guard is applied uniformly across every bare-form command group.
|
|
438
512
|
- **`company employees|posts|jobs <slug>` (or a company URL) now works.** The three sub-resources previously required the numeric company id and erred on a handle; they now auto-resolve a slug/URL to the numeric id the same way the bare `company <slug>` retrieve does (a numeric id still passes straight through; a genuinely unresolvable identifier surfaces the not-found error).
|
|
439
|
-
- **`profile follow <slug>` / `profile unfollow <slug>` (or a member URL) now work.** The follow endpoint accepts only a provider id, so a slug returned "not found"; both commands now resolve the identifier to the member's provider id first
|
|
440
|
-
- **`company posts` / `search posts` slim `--json` output no longer emits a permanently-null `post_urn`/`posted_at` and silently drops the post's own id (D13).** Both endpoints share the identical v2 item schema (`{id, share_url, text, author, reaction_count, comment_count, repost_count, is_repost, attachments, reactions, permissions}`)
|
|
441
|
-
- **`company <id>` slim `--json` output no longer emits permanently-null `employee_count`/`employee_count_range`/`followers_count`/`foundation_date`, and drops the entirely-fictitious `messaging` field.** The real v2 company-profile response nests headcount data at `insights.headcount` / `insights.headcount_range.from` (the range has no upper bound at all
|
|
513
|
+
- **`profile follow <slug>` / `profile unfollow <slug>` (or a member URL) now work.** The follow endpoint accepts only a provider id, so a slug returned "not found"; both commands now resolve the identifier to the member's provider id first, the same auto-resolution `profile`, `connect`, and `message` already do.
|
|
514
|
+
- **`company posts` / `search posts` slim `--json` output no longer emits a permanently-null `post_urn`/`posted_at` and silently drops the post's own id (D13).** Both endpoints share the identical v2 item schema (`{id, share_url, text, author, reaction_count, comment_count, repost_count, is_repost, attachments, reactions, permissions}`), `post_urn` was never a real key and `posted_at` doesn't exist on this resource at all. Slim output now surfaces the real `id`; `--fields` projects the real v2 keys. `share_url`/`repost_count`/`is_repost`/`attachments`/`reactions`/`permissions`/the full `author` object remain verbose-only.
|
|
515
|
+
- **`company <id>` slim `--json` output no longer emits permanently-null `employee_count`/`employee_count_range`/`followers_count`/`foundation_date`, and drops the entirely-fictitious `messaging` field.** The real v2 company-profile response nests headcount data at `insights.headcount` / `insights.headcount_range.from` (the range has no upper bound at all, documented open-ended-high, so no `to` is invented), the establishment date is a bare year at `establishment_year` (not a date string), the follower count key is singular, and there is no `messaging` field anywhere on this resource. Slim output now surfaces real `employee_count` / `employee_count_range` (`{from}` only) values; **`foundation_date` is renamed `establishment_year`** and **`followers_count` is renamed `follower_count`** (both now real, non-null); `messaging` is removed outright. `headquarters` (synthesized from `locations`) now reads the real `country_code`/`postal_code` location keys, the fictitious `country` key never existed and always projected null, and is renamed `country_code`; `postal_code` is added. `area` (region/state, e.g. "Washington") stays; it's real and often populated (verified live), even though the SDK's OpenAPI-generated types don't declare it for this endpoint.
|
|
442
516
|
- **`job get` / `recruiter job get` slim `--json` output no longer emits a permanently-null `company_id`/`applicants_counter`, and `job get` (Core) no longer emits a permanently-null `published_at`.** `company_id` is synthesized from the nested `company.id` (neither shape has a top-level `company_id`); `applicants_counter` is renamed to `applications_count` (the real key on both shapes); `published_at` falls back to `created_at` on the Core shape, which has no `published_at` field at all (the Recruiter shape's own `published_at` is real and unaffected).
|
|
443
|
-
- **`profile me` / `profile <id>` slim `--json` output no longer emits permanently-null `provider_id`/`network_distance`/`is_premium`/`current_position`, restores `headline` sourced from its real location, and drops the entirely-fictitious `occupation`/`organizations` fields.** Both commands are backed by the identical real v2 user-profile response
|
|
444
|
-
- **`job list --state` now re-filters returned items against their own `state` (D10).** LinkedIn's upstream state filter is best-effort
|
|
517
|
+
- **`profile me` / `profile <id>` slim `--json` output no longer emits permanently-null `provider_id`/`network_distance`/`is_premium`/`current_position`, restores `headline` sourced from its real location, and drops the entirely-fictitious `occupation`/`organizations` fields.** Both commands are backed by the identical real v2 user-profile response; there is no top-level `provider_id` (the real identifier is `id`), no top-level `network_distance`/`is_premium` (both nested under `specifics`), and no top-level `work_experience` (the real array is `specifics.experience`, which fed the `current_position` synthesis, also permanently null until now). `provider_id` now sources from `id`; `network_distance` and `is_premium` now source from `specifics.network_distance`/`specifics.is_premium`; `current_position` is synthesized from `specifics.experience[0]`. **`profile me`'s `email` is renamed `emails`** (the real field is a plural array, not a singular string). **`headline` <- `description`**: on a v2 read, LinkedIn serves the profile headline in the `description` wire field (a separate `bio` field carries the About-section paragraph); initially assumed to have no v2 source and dropped, then restored once the real source was confirmed live (3-way evidence: a written headline read back via `description` byte-for-byte, the same result from the M3 matrix probe, and `--verbose` showing headline-shaped text in `description` across live profiles). `occupation` and `organizations` are removed outright, neither has a v2 source; the real user-profile response has no occupation-summary field and no administered-organizations field of any kind. (`profile me`'s slim output drops from 10 fields to 9; `profile <id>`'s drops from 9 to 8.)
|
|
518
|
+
- **`job list --state` now re-filters returned items against their own `state` (D10).** LinkedIn's upstream state filter is best-effort; it commonly returns items whose own `state` doesn't match the request. `--json` output (and `--all` streaming) now only contains items whose own `state` actually matches (`--state OPEN` maps to the response's `LISTED`, the one value that differs between the request and response vocabularies); dropped items produce a stderr note with the count. The re-filter is page-local and never touches the pagination cursor, so `--all` still walks the same unfiltered upstream pages; it may fetch more pages than the filtered item count implies. The `--state` help text now says so.
|
|
445
519
|
|
|
446
|
-
### Notes
|
|
520
|
+
### Notes: no user action required
|
|
447
521
|
|
|
448
522
|
- **`post react --as-organization`**: unchanged at the flag level; only the internal wire key was renamed, so the flag behaves exactly as before.
|
|
449
523
|
|
|
450
524
|
## [0.14.0] - 2026-07-07
|
|
451
525
|
|
|
452
|
-
Webhooks surface cascade
|
|
526
|
+
Webhooks surface cascade, the coupled release with `@curviate/sdk` 0.14.0. Additive minor.
|
|
453
527
|
|
|
454
528
|
### Added
|
|
455
529
|
|
|
456
|
-
- **`webhook get <id
|
|
530
|
+
- **`webhook get <id>`**: get a single webhook owned by the calling tenant (`webhooks.get`). Read command; `--preview` is a usage error (nothing to mutate), matching `webhook state-diff`.
|
|
457
531
|
|
|
458
532
|
### Changed
|
|
459
533
|
|
|
460
|
-
- **`@curviate/sdk` bumped to `^0.14.0`.** The SDK's webhook event catalogue expanded 21
|
|
534
|
+
- **`@curviate/sdk` bumped to `^0.14.0`.** The SDK's webhook event catalogue expanded 21 -> 27 (`chat.updated`, `chat.deleted`, `connection.new`, `account.initial_sync.*`, and account-lifecycle renames) and its `CurviateEvent` union re-keyed to match; this CLI never imports `CurviateEvent` directly, so `webhook verify`'s offline HMAC verification is unaffected; only the dependency range changed.
|
|
461
535
|
|
|
462
536
|
## [0.13.0] - 2026-07-05
|
|
463
537
|
|
|
464
|
-
Accounts/Auth surface migration
|
|
538
|
+
Accounts/Auth surface migration, the coupled release with `@curviate/sdk` 0.13.0. This is a
|
|
465
539
|
**breaking** minor (pre-1.0): the account connection and checkpoint commands were reshaped to
|
|
466
540
|
match the new account-in-path grammar.
|
|
467
541
|
|
|
468
542
|
### Added
|
|
469
543
|
|
|
470
|
-
- **`account reconnect-link <account_id
|
|
471
|
-
- **`account update --metadata '<json>'
|
|
472
|
-
- **New connect/checkpoint response fields ride through `--json` output** (coupled with the SDK 0.13.0 connect-fix regen
|
|
473
|
-
- `recovered` (boolean) on `account link` and `account checkpoint solve` completions
|
|
544
|
+
- **`account reconnect-link <account_id>`**: mint a one-time hosted **re-authorization** link for an existing disconnected account (the hosted counterpart of `account reconnect`). Same open+wait UX as `account connect-link`: on an interactive TTY the URL auto-opens and the command waits for the account to reconnect (exit `0` resolved, `9` expired/failed, `12` on a wait-window timeout); non-interactively it prints the url + session_id and returns immediately. Optional `--expires-in-seconds` / `--redirect-url`.
|
|
545
|
+
- **`account update --metadata '<json>'`**: set the account's custom metadata (a flat JSON object that replaces the store wholesale). **`account update --clear-proxy`**: clear the custom proxy (revert to automatic proxy protection).
|
|
546
|
+
- **New connect/checkpoint response fields ride through `--json` output** (coupled with the SDK 0.13.0 connect-fix regen, the CLI duck-types the response, so the fields pass through verbatim with no code change):
|
|
547
|
+
- `recovered` (boolean) on `account link` and `account checkpoint solve` completions, `true` when the connect reclaimed a LinkedIn identity already present on the workspace rather than connecting a brand-new one.
|
|
474
548
|
- the completed-account `status` is widened to `active | reconnect_needed | restricted | disconnected` (a recovered identity often reports needing a reconnect); the CLI reads `status` as a free-form string, so the wider set is unaffected.
|
|
475
549
|
- `challenge_type` (`mobile_app_approval`) + `recovery_hint` on an `account checkpoint poll` that returns `status: "expired"` (a mobile-approval timeout).
|
|
476
|
-
Surfacing `recovered` in the human-readable (non-`--json`) success line is a deferred UX follow-up
|
|
550
|
+
Surfacing `recovered` in the human-readable (non-`--json`) success line is a deferred UX follow-up; it would need consistent treatment across the direct-link, interactive-solve, and standalone-solve completion paths.
|
|
477
551
|
|
|
478
552
|
### Changed (BREAKING)
|
|
479
553
|
|
|
480
554
|
- **Checkpoint commands are now account-in-path (positional), not `--checkpoint`.**
|
|
481
|
-
- `account checkpoint submit --checkpoint <id> --code <c>`
|
|
482
|
-
- `account checkpoint resend --checkpoint <id>`
|
|
483
|
-
- `account checkpoint poll --checkpoint <id>`
|
|
555
|
+
- `account checkpoint submit --checkpoint <id> --code <c>` -> **`account checkpoint solve <account_id> --code <c>`**.
|
|
556
|
+
- `account checkpoint resend --checkpoint <id>` -> **`account checkpoint request <account_id>`**.
|
|
557
|
+
- `account checkpoint poll --checkpoint <id>` -> **`account checkpoint poll <account_id>`** (the `--checkpoint` flag becomes the account_id positional; `--wait`/`--timeout` unchanged).
|
|
484
558
|
- Update scripts: replace `checkpoint submit --checkpoint X --code Y` with `checkpoint solve X --code Y`, `checkpoint resend --checkpoint X` with `checkpoint request X`, and `checkpoint poll --checkpoint X` with `checkpoint poll X`.
|
|
485
|
-
- **`account refresh <account_id>` removed
|
|
486
|
-
- **`account connect-link` is create-only
|
|
487
|
-
- **`account update` reshaped
|
|
488
|
-
- **`account link` / `account reconnect` require `--user-agent` for cookie auth
|
|
489
|
-
- SDK-parity manifest (`test/parity.test.ts`) repoints the checkpoint entries (`solve`/`request`/`poll`) and swaps `account refresh`
|
|
559
|
+
- **`account refresh <account_id>` removed**: accounts restart and re-sync automatically now; there is no replacement command. Status freshness comes from the account-status webhook, the nightly reconcile, and `account get`.
|
|
560
|
+
- **`account connect-link` is create-only**; the `--purpose` and `--account-id` flags are removed; it only mints a link to connect a **new** account. Use `account reconnect-link <account_id>` for hosted re-auth of an existing account.
|
|
561
|
+
- **`account update` reshaped**; the managed `--country` / `--ip` flags are removed (a managed location is now chosen at connect time). The command now takes `--metadata` and/or a custom proxy (`--proxy-*` / `--clear-proxy`).
|
|
562
|
+
- **`account link` / `account reconnect` require `--user-agent` for cookie auth**; connecting by session cookie (`--auth-method cookie`) without a `--user-agent` fails fast at exit `2` (it stays optional for `--auth-method credentials`). Under `--preview` the check is skipped (a render never exits).
|
|
563
|
+
- SDK-parity manifest (`test/parity.test.ts`) repoints the checkpoint entries (`solve`/`request`/`poll`) and swaps `account refresh` -> `account reconnect-link`; the manifest and SDK method count stay at 93 (`accounts` stays 12 methods).
|
|
490
564
|
|
|
491
565
|
### Fixed
|
|
492
566
|
|
|
@@ -494,44 +568,44 @@ match the new account-in-path grammar.
|
|
|
494
568
|
|
|
495
569
|
### Changed
|
|
496
570
|
|
|
497
|
-
- `@curviate/sdk` dependency bumped to `^0.13.0
|
|
571
|
+
- `@curviate/sdk` dependency bumped to `^0.13.0`, the coupled release carrying the reshaped `accounts` surface (see the SDK's own CHANGELOG). The CLI duck-types the SDK, so its commands are covered by the parity manifest against that release.
|
|
498
572
|
|
|
499
573
|
## [0.12.0] - 2026-07-05
|
|
500
574
|
|
|
501
575
|
### Added
|
|
502
576
|
|
|
503
|
-
- **`company employees <id
|
|
504
|
-
- **`company posts <id
|
|
505
|
-
- **`company jobs <id
|
|
506
|
-
- **`company followers <id
|
|
577
|
+
- **`company employees <id>`**: list people who currently work at the company (facade over people search with the company filter). `--keywords` and `--location` narrow the result; pagination flags apply. `<id>` must be the company's numeric provider_id (the `id` field of `company <id>`).
|
|
578
|
+
- **`company posts <id>`**: list the company's posts (facade over post search). Pagination flags apply; post `text` prints verbatim.
|
|
579
|
+
- **`company jobs <id>`**: list the company's open job postings (facade over job search). `--keywords` narrows the result. An empty list is a valid result (the company currently has no open postings), not an error.
|
|
580
|
+
- **`company followers <id>`**: list the company's followers (native, the same seam that backs `profile <id> --followers`). Requires the acting account to administer the target company page; a non-admin company returns the exit code for `RESOURCE_ACCESS_RESTRICTED` (new, see below).
|
|
507
581
|
- All four new subcommands support `--all` (NDJSON page streaming) alongside the existing pagination flags, and reject `--preview` (exit `2`) like every other read command.
|
|
508
|
-
- `--account` is now required on `company <id>` (retrieve)
|
|
509
|
-
- **Sales Navigator v2 list surface
|
|
582
|
+
- `--account` is now required on `company <id>` (retrieve); the underlying endpoint always requires `account_id`; previously the command silently fell back to an unscoped call.
|
|
583
|
+
- **Sales Navigator v2 list surface, 5 new subcommands.** `sales-nav account-lists --account <id>` and `sales-nav lead-lists --account <id>` list the operator's saved-account/saved-lead lists (`--limit`/`--cursor`/`--all` paginate). `sales-nav browse-account-list <list_id> --account <id> [--filter --sort-by --sort-order]` and `sales-nav browse-lead-list <list_id> --account <id> [--spotlight --sort-by --sort-order]` browse the saved items in one list, genuine paginated reads, so they keep all pagination flags. `sales-nav save-account <company_id> --list <id> --account <id>` saves a company into an account list (write, `--preview` supported, no pagination flags in `--help`). All five call the SDK's new `salesNavigator` methods (`accountLists`/`leadLists`/`browseAccountList`/`browseLeadList`/`saveAccount`), no re-implementation of the HTTP call.
|
|
510
584
|
|
|
511
585
|
### Changed (BREAKING)
|
|
512
586
|
|
|
513
|
-
- **`company <id>` now routes to the SDK's `companies.get()`** instead of the retired `profiles.getCompany()
|
|
514
|
-
- SDK-parity manifest (`test/parity.test.ts`) repoints `company get`
|
|
515
|
-
- `@curviate/sdk` dependency bumped to `^0.12.0
|
|
516
|
-
- **`sales-nav save-lead` re-signed for the v2 save-lead surface.** The old `save-lead <user_id> [--list-id <id>]` (list optional) is **retired, no alias
|
|
517
|
-
- SDK-parity manifest gains the 5 new `sales-nav` v2 subcommands; the manifest and SDK method count both move from 88 to 93 (`salesNavigator` 7
|
|
587
|
+
- **`company <id>` now routes to the SDK's `companies.get()`** instead of the retired `profiles.getCompany()`, an internal repoint (the hard-moved server endpoint), not a CLI UX change: flags, output shape, and slim projection are unchanged. `--account` becoming required (above) is the one user-visible behavior change.
|
|
588
|
+
- SDK-parity manifest (`test/parity.test.ts`) repoints `company get` -> `companies.get` and gains `company employees` / `company posts` / `company jobs` / `company followers`; the manifest and SDK method count both move from 84 to 88.
|
|
589
|
+
- `@curviate/sdk` dependency bumped to `^0.12.0`, the released build carrying the `companies` resource and the v2 `salesNavigator` list-surface cascade (see the SDK's own CHANGELOG).
|
|
590
|
+
- **`sales-nav save-lead` re-signed for the v2 save-lead surface.** The old `save-lead <user_id> [--list-id <id>]` (list optional) is **retired, no alias**; the v2 op always saves into a specific list. The replacement is `save-lead <user_id> --list <id>`: `--list` is now **required** and the flag is renamed from `--list-id`. Update scripts: `save-lead <id> --list-id <l>` -> `save-lead <id> --list <l>`.
|
|
591
|
+
- SDK-parity manifest gains the 5 new `sales-nav` v2 subcommands; the manifest and SDK method count both move from 88 to 93 (`salesNavigator` 7->12 methods).
|
|
518
592
|
|
|
519
593
|
### Fixed
|
|
520
594
|
|
|
521
|
-
- **`RESOURCE_ACCESS_RESTRICTED
|
|
595
|
+
- **`RESOURCE_ACCESS_RESTRICTED`**: a new SDK error code (the non-admin mapping for `company followers`) is now present in `EXIT_CODE_MAP` (exit `8`, grouped with `ACCOUNT_RESTRICTED`); the exhaustiveness test would otherwise have silently mapped it to the default `1`.
|
|
522
596
|
|
|
523
597
|
## [0.11.0] - 2026-07-04
|
|
524
598
|
|
|
525
599
|
### Added
|
|
526
600
|
|
|
527
|
-
- **Safe credential entry** for `account link` / `account reconnect` / `account update
|
|
528
|
-
- **Guided checkpoint follow-through** on `account link` / `account reconnect`. A `202 checkpoint_required` response now resolves in-process on an interactive TTY
|
|
529
|
-
- **`account checkpoint poll --wait
|
|
530
|
-
- **`account checkpoint resend --checkpoint <id
|
|
531
|
-
- **`account connect-link` browser handoff.** The command now completes the hosted-link round trip instead of only minting a URL: on an interactive TTY it auto-opens the URL and waits on the same adaptive cadence as `checkpoint poll --wait` for the account to connect (resolved
|
|
532
|
-
- **`account connect-session poll --session <id
|
|
533
|
-
- Pagination flags (`--limit`/`--cursor`/`--all`/`--max-pages`) are now suppressed on the 8 `account` subcommands that mutate or resolve exactly one resource (`link`, `connect-link`, `reconnect`, `refresh`, `update`, `disconnect`, `checkpoint submit`, `checkpoint poll`)
|
|
534
|
-
- SDK-parity manifest (`test/parity.test.ts`) gains `account checkpoint resend`
|
|
601
|
+
- **Safe credential entry** for `account link` / `account reconnect` / `account update`: env-var fallbacks (an explicit flag always wins over its env var), `--password-stdin` / `--li-at-stdin` flags to read a secret from stdin, and a masked TTY prompt with a non-TTY fail-fast when a credential is required but not supplied any other way. A 5-way conflict matrix rejects supplying the same credential through more than one channel. The four secret-bearing flags carry a shell-history/`ps`-visibility warning, and `--preview` masks credential values instead of ever rendering them in cleartext.
|
|
602
|
+
- **Guided checkpoint follow-through** on `account link` / `account reconnect`. A `202 checkpoint_required` response now resolves in-process on an interactive TTY: code prompt, retry loop on a `422`, chained-challenge follow-through, a codeless mobile-app-approval poll sub-loop, and a resend hint, instead of just printing the envelope. A non-interactive session (either stream not a TTY, or `--no-interactive`) still prints the envelope and exits with the new `12` (`AUTH_NEEDED`) code, a pending checkpoint, not an error.
|
|
603
|
+
- **`account checkpoint poll --wait`**: an adaptive-cadence loop (1000ms, then 1500ms for 30s, then 3000ms) that blocks until the checkpoint resolves (exit `0`), expires/fails (exit `9`), or the wait window elapses while still pending (exit `12`, still resolvable later). `--wait` is off by default (the single-poll behavior is unchanged). `--timeout <ms>` overrides the wall-clock bound (default: the checkpoint's own expiry) and fails fast at exit `2` on a non-numeric value, before any call. `checkpoint submit`'s one-shot path also now detects a chained `checkpoint_required` response and exits `12` instead of rendering it as a plain success.
|
|
604
|
+
- **`account checkpoint resend --checkpoint <id>`**: re-sends the pending challenge notification, mirroring `checkpoint submit` / `poll` (body-addressed, `WRITE_SINGLE_FLAGS`, `--preview` supported, no `--code` since there's nothing to submit). Exits `0` on any `200` regardless of the response's `resent` boolean; `false` is an honest answer, not a command failure.
|
|
605
|
+
- **`account connect-link` browser handoff.** The command now completes the hosted-link round trip instead of only minting a URL: on an interactive TTY it auto-opens the URL and waits on the same adaptive cadence as `checkpoint poll --wait` for the account to connect (resolved -> prints the connected account and exits `0`; expired/failed -> exit `9`; wait window elapses while still pending -> exit `12`). A non-interactive session (non-TTY, or `--no-interactive`) never opens a browser and never blocks; it prints the URL, a relay instruction, and the `session_id`, then returns immediately.
|
|
606
|
+
- **`account connect-session poll --session <id>`**: the standalone counterpart to the above: a single poll by default (prints the body, exits `0` regardless of status), or the same adaptive wait loop with `--wait`. `--open`/`--no-open` and `--wait`/`--no-wait` are TTY-adaptive; `--timeout <ms>` overrides the wait bound (default: time remaining to the session's own expiry).
|
|
607
|
+
- Pagination flags (`--limit`/`--cursor`/`--all`/`--max-pages`) are now suppressed on the 8 `account` subcommands that mutate or resolve exactly one resource (`link`, `connect-link`, `reconnect`, `refresh`, `update`, `disconnect`, `checkpoint submit`, `checkpoint poll`); they had no meaning on a one-row response. `account list` is unaffected. `link` / `reconnect` help text gains a one-line note about the checkpoint-required path.
|
|
608
|
+
- SDK-parity manifest (`test/parity.test.ts`) gains `account checkpoint resend` -> `accounts.resendCheckpoint` and `account connect-session poll` -> `accounts.getConnectSession`; both were held back pending the SDK's own `0.11.0` regen; the manifest and the SDK method count both move from 82 to 84.
|
|
535
609
|
|
|
536
610
|
### Fixed
|
|
537
611
|
|
|
@@ -545,38 +619,38 @@ match the new account-in-path grammar.
|
|
|
545
619
|
|
|
546
620
|
### Added
|
|
547
621
|
|
|
548
|
-
- `job get <url|id
|
|
549
|
-
- `recruiter job get <url|id
|
|
622
|
+
- `job get <url|id>`: a new top-level `job` command retrieving one public LinkedIn job posting's full detail. Accepts a job URL (`https://www.linkedin.com/jobs/view/<id>`) or a bare numeric id; a job URL is resolved to its numeric id client-side; anything else passes through and the API is the final validator. Slim-default output: `object`, `id`, `title`, `company`, `company_id`, `location`, `state`, `applicants_counter`, `published_at`, `description`; `description` stays in the default output since retrieving it is the point of the command. Pass `--verbose` for the full response (adds `cost`, `created_at`, `hiring_team`). An unknown job id exits with the not-found exit code. This is a read command; `--preview` is a usage error, matching every other single-object read.
|
|
623
|
+
- `recruiter job get <url|id>`: the Recruiter-lens sibling of `job get`, joining the existing `recruiter job` command group. Retrieves any public job posting (not only postings you manage), unlike `recruiter jobs`, which lists your own. Same URL/id resolution and slim/verbose projection as the top-level command; requires the Recruiter add-on tier (exit `5` without it).
|
|
550
624
|
- README gained a new numbered example chaining `search jobs` into `job get`, and a "Get any public job posting through the Recruiter lens" example in the Recruiter section.
|
|
551
625
|
|
|
552
626
|
### Changed
|
|
553
627
|
|
|
554
628
|
- `@curviate/sdk` dependency bumped to `^0.10.0`.
|
|
555
|
-
- `recruiter job get --help` does not advertise `--limit`/`--cursor`/`--all`/`--max-pages
|
|
629
|
+
- `recruiter job get --help` does not advertise `--limit`/`--cursor`/`--all`/`--max-pages`; a single-object read, consistent with the other Recruiter single-reads (`profile`, `project`, `applicant`). `--fields` and `--verbose` are unchanged and available.
|
|
556
630
|
|
|
557
631
|
## [0.9.0] - 2026-07-03
|
|
558
632
|
|
|
559
633
|
### Added
|
|
560
634
|
|
|
561
|
-
- `account list` and `account get` gain a compact **slim-default** output
|
|
562
|
-
- `account get` gains `seat_id` in its slim output (previously only `account list` carried it)
|
|
635
|
+
- `account list` and `account get` gain a compact **slim-default** output; pass `--verbose` for the full API response. Slim `account list` items: `account_id`, `status`, `auth_method`, `full_name`, `headline`, `seat_id`, `connected_at`. Slim `account get`: the same seven fields plus `last_checked_at` and `quotas`. Six cached account-detail fields (`username`, `premium_id`, `public_identifier`, `substrate_created_at`, `signatures`, `groups`) are verbose-only on both commands; they are `null`/`[]` on an account that hasn't been enriched yet, never a missing key. `--all` NDJSON streaming on `account list` applies the same slim projection per item unless `--verbose` is passed.
|
|
636
|
+
- `account get` gains `seat_id` in its slim output (previously only `account list` carried it), the seat the account occupies, `null` for an admin seatless account.
|
|
563
637
|
|
|
564
638
|
### Changed
|
|
565
639
|
|
|
566
640
|
- `@curviate/sdk` dependency bumped to `^0.9.0`.
|
|
567
|
-
- `account get --help` no longer advertises `--limit`/`--cursor`/`--all`/`--max-pages
|
|
641
|
+
- `account get --help` no longer advertises `--limit`/`--cursor`/`--all`/`--max-pages`; a single-object read, those flags never applied. `--fields` is unchanged and still available. `account list` is unaffected (a genuine list read, keeps all pagination flags).
|
|
568
642
|
|
|
569
643
|
## [0.8.0] - 2026-07-02
|
|
570
644
|
|
|
571
645
|
### Added
|
|
572
646
|
|
|
573
|
-
- `recruiter reject-applicant` gained `--message` and `--notify-at` flags. The applicant is only notified of the rejection when `--message` is provided (the prior behavior
|
|
574
|
-
- README gained dedicated "Sales Navigator" and "Recruiter" sections with numbered, runnable examples covering every in-scope command: searching and getting profiles, saving a lead, starting a chat, listing/searching Recruiter people and hiring projects, the job create
|
|
647
|
+
- `recruiter reject-applicant` gained `--message` and `--notify-at` flags. The applicant is only notified of the rejection when `--message` is provided (the prior behavior, no notification, is unchanged when both are omitted). `--notify-at` schedules the notification (a UNIX-milliseconds timestamp) and requires `--message`; passing `--notify-at` alone, or a non-numeric value, is a usage error (exit `2`).
|
|
648
|
+
- README gained dedicated "Sales Navigator" and "Recruiter" sections with numbered, runnable examples covering every in-scope command: searching and getting profiles, saving a lead, starting a chat, listing/searching Recruiter people and hiring projects, the job create -> publish -> checkpoint lifecycle, listing/getting applicants, downloading a resume, and rejecting an applicant with and without a notification.
|
|
575
649
|
|
|
576
650
|
### Changed
|
|
577
651
|
|
|
578
|
-
- **Help output cleanup:** Recruiter and Sales Navigator write commands (`add-candidate`, `add-applicant`, `reject-applicant`, `job create`/`publish`/`checkpoint`, `save-lead`, `message new`) and single-object read commands (`profile`, `project`, `applicant`, `applicant resume`) no longer advertise `--limit`/`--cursor`/`--all`/`--max-pages` in `--help
|
|
579
|
-
- Corrected the `search parameters --type` flag description on both `recruiter` and `sales-nav
|
|
652
|
+
- **Help output cleanup:** Recruiter and Sales Navigator write commands (`add-candidate`, `add-applicant`, `reject-applicant`, `job create`/`publish`/`checkpoint`, `save-lead`, `message new`) and single-object read commands (`profile`, `project`, `applicant`, `applicant resume`) no longer advertise `--limit`/`--cursor`/`--all`/`--max-pages` in `--help`; those flags only ever applied to list/search commands, which keep them unchanged. Single-object reads keep `--fields`.
|
|
653
|
+
- Corrected the `search parameters --type` flag description on both `recruiter` and `sales-nav`; it previously suggested example values (`LOCATION`, `INDUSTRY`, `TITLE`) that the API does not accept for either surface; it now lists the real accepted values.
|
|
580
654
|
- Polished the `message new --to` flag description on both surfaces with the expected provider-ID format and a note that it is not resolved from a URL or slug.
|
|
581
655
|
- Updated `@curviate/sdk` dependency to `^0.8.0`. No resource method signatures changed (per the SDK 0.8.0 changelog); Recruiter's job-lifecycle endpoints (applicant get/reject/resume, applicant list, job publish/checkpoint, Recruiter profile) are now fully implemented server-side instead of returning `501`.
|
|
582
656
|
|
|
@@ -590,7 +664,7 @@ match the new account-in-path grammar.
|
|
|
590
664
|
|
|
591
665
|
### Fixed
|
|
592
666
|
|
|
593
|
-
- `recruiter message new
|
|
667
|
+
- `recruiter message new`: the `--to` recipient ID is now sent as `attendees_ids` (plural) in the request body, matching the updated server contract. A prior version used the old `attendee_ids` (singular) field name which the API no longer accepts.
|
|
594
668
|
|
|
595
669
|
### Changed
|
|
596
670
|
|
|
@@ -600,20 +674,20 @@ match the new account-in-path grammar.
|
|
|
600
674
|
|
|
601
675
|
### Added
|
|
602
676
|
|
|
603
|
-
- `search
|
|
677
|
+
- `search`: named filter flags that previously required raw `--filters` JSON:
|
|
604
678
|
- **companies**: `--has-job-offers`, `--headcount <buckets>` (comma-separated
|
|
605
|
-
size buckets `1-10
|
|
679
|
+
size buckets `1-10 ... 5001-10000`; `10001+` reports a usage error).
|
|
606
680
|
- **jobs**: `--title <ids>`, `--presence`, `--benefits`, `--commitments`,
|
|
607
681
|
`--has-verifications`, `--under-10-applicants`, `--in-your-network`,
|
|
608
682
|
`--fair-chance-employer`, `--location-within-area <miles>`.
|
|
609
|
-
- **people**: `--connections-of`, `--followers-of` (comma-separated
|
|
683
|
+
- **people**: `--connections-of`, `--followers-of` (comma-separated -> array).
|
|
610
684
|
- **posts**: `--posted-by-member`, `--posted-by-company`, `--posted-by-me`,
|
|
611
685
|
`--mentioning-member`, `--mentioning-company`, `--author-industry`,
|
|
612
686
|
`--author-company`, `--author-keywords`.
|
|
613
687
|
|
|
614
688
|
### Fixed
|
|
615
689
|
|
|
616
|
-
- `search jobs` slim `company_name` was always `null
|
|
690
|
+
- `search jobs` slim `company_name` was always `null`, now derived from the
|
|
617
691
|
nested `company.name` (handles postings with no linked company). `--verbose`
|
|
618
692
|
still returns the raw response unchanged.
|
|
619
693
|
- `search parameters --type`, `search jobs --seniority`/`--job-type`, and
|
|
@@ -628,12 +702,12 @@ match the new account-in-path grammar.
|
|
|
628
702
|
|
|
629
703
|
### Added
|
|
630
704
|
|
|
631
|
-
- `search people --title` (
|
|
705
|
+
- `search people --title` (-> `advanced_keywords.title` keyword, nested-merged),
|
|
632
706
|
`--industry`, `--profile-language`; `--filters` deep-merge (named flags win).
|
|
633
|
-
- `search jobs --location`
|
|
707
|
+
- `search jobs --location` -> `region` (single id) + `--region` alias +
|
|
634
708
|
`--date-posted <days>` (number).
|
|
635
|
-
- `search posts --date-posted` hyphen
|
|
636
|
-
- `--all` truncation emits `{"object":"stream_truncated"
|
|
709
|
+
- `search posts --date-posted` hyphen->underscore normalize.
|
|
710
|
+
- `--all` truncation emits `{"object":"stream_truncated",...}` JSON.
|
|
637
711
|
|
|
638
712
|
### Changed
|
|
639
713
|
|
|
@@ -643,15 +717,15 @@ match the new account-in-path grammar.
|
|
|
643
717
|
|
|
644
718
|
### Added
|
|
645
719
|
|
|
646
|
-
- `inbox list --unread
|
|
720
|
+
- `inbox list --unread`: filter the inbox to chats with unread messages.
|
|
647
721
|
- `messages` now accepts `--before` and `--after` to page a conversation by
|
|
648
722
|
timestamp window.
|
|
649
|
-
- `sync-chat --wait
|
|
723
|
+
- `sync-chat --wait`: poll until a chat sync completes instead of returning
|
|
650
724
|
immediately.
|
|
651
725
|
- `message new --to` and `message inmail --to` now resolve a **LinkedIn profile
|
|
652
726
|
URL or vanity slug** (e.g. `linkedin.com/in/<slug>`) to the recipient, in
|
|
653
727
|
addition to provider ids and member URNs.
|
|
654
|
-
- Thread-URL `chat_id` normalization
|
|
728
|
+
- Thread-URL `chat_id` normalization: a pasted conversation URL is normalized to
|
|
655
729
|
the underlying chat id wherever a `chat_id` is accepted.
|
|
656
730
|
- Write commands that take a TEXT positional accept `-` to read the value from
|
|
657
731
|
stdin (pipe message bodies in).
|
|
@@ -668,10 +742,10 @@ match the new account-in-path grammar.
|
|
|
668
742
|
|
|
669
743
|
### Added
|
|
670
744
|
|
|
671
|
-
- `message inmail --surface classic
|
|
745
|
+
- `message inmail --surface classic`: send an InMail from the account's own premium
|
|
672
746
|
InMail credits (in addition to `sales_nav` and `recruiter`). Use this to reach an
|
|
673
747
|
out-of-network member from a LinkedIn Premium/Core account.
|
|
674
|
-
- `message inmail --to` now accepts a member **provider id** (`ACoAAA
|
|
748
|
+
- `message inmail --to` now accepts a member **provider id** (`ACoAAA...`) as well as a
|
|
675
749
|
member URN (`urn:li:member:<id>`). The server resolves the recipient either way.
|
|
676
750
|
|
|
677
751
|
## [0.4.1] - 2026-06-29
|
|
@@ -707,7 +781,7 @@ match the new account-in-path grammar.
|
|
|
707
781
|
### Fixed
|
|
708
782
|
|
|
709
783
|
- `company` command now exits 2 with an error when `--sections` is passed (unsupported flag for that surface).
|
|
710
|
-
- `slimProfile` work_experience field mapping corrected (`position
|
|
784
|
+
- `slimProfile` work_experience field mapping corrected (`position`->`title`, `company`->`company_name`); `is_current` now derived from `end == null`; `company_id` is always `null` (the experience-entry ID is not a company ID).
|
|
711
785
|
|
|
712
786
|
### Changed
|
|
713
787
|
|
|
@@ -731,7 +805,7 @@ match the new account-in-path grammar.
|
|
|
731
805
|
|
|
732
806
|
### Added
|
|
733
807
|
|
|
734
|
-
- Initial public release
|
|
808
|
+
- Initial public release, full SDK-surface parity CLI over the Curviate API.
|
|
735
809
|
- `curviate` root command with `--help` and `--version`.
|
|
736
810
|
- Global flags: `--account`, `--json`, `--fields`, `--limit`, `--cursor`, `--all`,
|
|
737
811
|
`--max-pages`, `--preview`, `--base-url`, `--timeout`, `--api-key`, `--profile`.
|