@curviate/cli 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,7 +6,29 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
  Versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html):
7
7
  a new command or flag is a minor; a breaking command/flag/exit-code change is a major; a fix is a patch.
8
8
 
9
- ## [Unreleased]
9
+ ## [0.12.0] - 2026-07-05
10
+
11
+ ### Added
12
+
13
+ - **`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>`).
14
+ - **`company posts <id>`** — list the company's posts (facade over post search). Pagination flags apply; post `text` prints verbatim.
15
+ - **`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.
16
+ - **`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).
17
+ - All four new subcommands support `--all` (NDJSON page streaming) alongside the existing pagination flags, and reject `--preview` (exit `2`) like every other read command.
18
+ - `--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.
19
+ - **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.
20
+
21
+ ### Changed (BREAKING)
22
+
23
+ - **`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.
24
+ - 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.
25
+ - `@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).
26
+ - **`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>`.
27
+ - 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).
28
+
29
+ ### Fixed
30
+
31
+ - **`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`.
10
32
 
11
33
  ## [0.11.0] - 2026-07-04
12
34
 
package/README.md CHANGED
@@ -172,13 +172,44 @@ curviate search jobs --keywords "founding engineer" --location "Berlin" --accoun
172
172
  curviate job get "https://www.linkedin.com/jobs/view/4428113858" --account acc_1
173
173
  ```
174
174
 
175
+ ## Company
176
+
177
+ Company commands (`curviate company ...`) are Core-tier reads. `company <id>` accepts a public
178
+ handle (the slug in `linkedin.com/company/<handle>`) or a numeric id; the four sub-resource
179
+ commands require the company's **numeric provider id** — the `id` field `company <id>` returns.
180
+ `--account` (or a configured default account) is required on all of them.
181
+
182
+ ### 1. Retrieve a company, then list its employees
183
+
184
+ ```bash
185
+ curviate company t-systems --account acc_1 --json | jq -r '.id' \
186
+ | xargs -I{} curviate company employees {} --keywords "engineer" --limit 10 --account acc_1 --json
187
+ ```
188
+
189
+ ### 2. Page through a company's posts and jobs
190
+
191
+ ```bash
192
+ curviate company posts 112013061 --limit 5 --account acc_1 --json
193
+ curviate company jobs 112013061 --all --account acc_1 --json # streams every page
194
+ ```
195
+
196
+ ### 3. List a company's followers (page admins only)
197
+
198
+ Followers are only retrievable for a company page the acting account **administers** — a
199
+ non-administered company returns a `RESOURCE_NOT_FOUND` error (exit code `4`), the same shape as
200
+ an unknown company.
201
+
202
+ ```bash
203
+ curviate company followers 112013061 --limit 25 --account acc_1 --json
204
+ ```
205
+
175
206
  ## Sales Navigator
176
207
 
177
208
  Sales Navigator commands (`curviate sales-nav ...`) require an account with the Sales Navigator
178
209
  add-on tier attached. A call against an account without it fails with **exit code `5`** and a
179
210
  `TIER_NOT_ACTIVE` error body naming the required tier (`sales_nav`) — branch on the exit code the
180
- same way as example 4 above. Write commands (`save-lead`, `message new`) accept `--preview` to
181
- render the request without sending it.
211
+ same way as example 4 above. Write commands (`save-lead`, `save-account`, `message new`) accept
212
+ `--preview` to render the request without sending it.
182
213
 
183
214
  ### 1. Search Sales Navigator profiles, then get one full profile
184
215
 
@@ -193,15 +224,15 @@ curviate sales-nav search people \
193
224
 
194
225
  ### 2. Save a lead to a specific lead list
195
226
 
196
- Preview first, then send:
227
+ Preview first, then send. `--list` is required — the save always targets a specific list.
197
228
 
198
229
  ```bash
199
230
  curviate sales-nav save-lead ACwAAA1234567 \
200
231
  --account acc_1 \
201
- --list-id 987654 \
232
+ --list 987654 \
202
233
  --preview
203
234
 
204
- curviate sales-nav save-lead ACwAAA1234567 --account acc_1 --list-id 987654
235
+ curviate sales-nav save-lead ACwAAA1234567 --account acc_1 --list 987654
205
236
  ```
206
237
 
207
238
  ### 3. Start a new Sales Navigator chat
@@ -223,6 +254,45 @@ curviate sales-nav search companies \
223
254
  | jq -r '.items[] | "\(.id)\t\(.name)"'
224
255
  ```
225
256
 
257
+ ### 5. List saved-account and saved-lead lists
258
+
259
+ ```bash
260
+ curviate sales-nav account-lists --account acc_1
261
+ curviate sales-nav lead-lists --account acc_1
262
+ ```
263
+
264
+ ### 6. Browse a saved-account list, filtered to starred accounts
265
+
266
+ ```bash
267
+ curviate sales-nav browse-account-list 987654 \
268
+ --account acc_1 \
269
+ --filter STARRED \
270
+ --sort-by NAME \
271
+ --json \
272
+ | jq -r '.items[] | "\(.id)\t\(.display_name)"'
273
+ ```
274
+
275
+ ### 7. Browse a saved-lead list, spotlighting recent job changes
276
+
277
+ ```bash
278
+ curviate sales-nav browse-lead-list 456789 \
279
+ --account acc_1 \
280
+ --spotlight RECENT_POSITION_CHANGE \
281
+ --json \
282
+ | jq -r '.items[] | "\(.id)\t\(.display_name)"'
283
+ ```
284
+
285
+ ### 8. Save a company into an account list
286
+
287
+ ```bash
288
+ curviate sales-nav save-account 112013061 \
289
+ --account acc_1 \
290
+ --list 987654 \
291
+ --preview
292
+
293
+ curviate sales-nav save-account 112013061 --account acc_1 --list 987654
294
+ ```
295
+
226
296
  ## Recruiter
227
297
 
228
298
  Recruiter commands (`curviate recruiter ...`) require an account with the Recruiter add-on tier
@@ -7,13 +7,13 @@ import {
7
7
  } from "./chunk-MKXA2LAR.js";
8
8
  import {
9
9
  AUTH_NEEDED
10
- } from "./chunk-OSQ643UW.js";
11
- import {
12
- streamAll
13
- } from "./chunk-GXTZION6.js";
10
+ } from "./chunk-HMAGEMF7.js";
14
11
  import {
15
12
  buildPreviewOutput
16
13
  } from "./chunk-R3VLWLVV.js";
14
+ import {
15
+ streamAll
16
+ } from "./chunk-GXTZION6.js";
17
17
  import {
18
18
  slimAccountGet,
19
19
  slimAccountList,
@@ -203,7 +203,7 @@ function resolveOutputOpts(flags) {
203
203
  async function handleError(err, outOpts, out) {
204
204
  const { CurviateError } = await import("@curviate/sdk");
205
205
  if (err instanceof CurviateError) {
206
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
206
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
207
207
  renderError(err, outOpts, out);
208
208
  process.exit(getExitCode(err.code));
209
209
  }
@@ -26,6 +26,7 @@ var EXIT_CODE_MAP = {
26
26
  LINKEDIN_SERVICE_UNAVAILABLE: 7,
27
27
  // Account / connection state (8)
28
28
  ACCOUNT_RESTRICTED: 8,
29
+ RESOURCE_ACCESS_RESTRICTED: 8,
29
30
  LINKEDIN_AUTH_FAILED: 8,
30
31
  LINKEDIN_COOKIE_INVALID: 8,
31
32
  CONNECTION_IN_PROGRESS: 8,
package/dist/cli.js CHANGED
@@ -144,18 +144,18 @@ var main = defineCommand({
144
144
  // ---------------------------------------------------------------------------
145
145
  // Noun groups — lazy-loaded on first invocation.
146
146
  // ---------------------------------------------------------------------------
147
- profile: () => import("./profile-TUIZZKM7.js").then((m) => m.profileCommand),
148
- company: () => import("./company-IMAVQBZL.js").then((m) => m.companyCommand),
149
- job: () => import("./job-EIXYBDF6.js").then((m) => m.jobCommand),
150
- connect: () => import("./connect-J5NPWKAQ.js").then((m) => m.connectCommand),
151
- search: () => import("./search-TF6OOEUE.js").then((m) => m.searchCommand),
152
- inbox: () => import("./inbox-5P5TB6AI.js").then((m) => m.inboxCommand),
153
- message: () => import("./message-646BIYRH.js").then((m) => m.messageCommand),
154
- post: () => import("./post-TI6KV26J.js").then((m) => m.postCommand),
155
- account: () => import("./account-P5K5UDWF.js").then((m) => m.accountCommand),
156
- webhook: () => import("./webhook-VHREWB56.js").then((m) => m.webhookCommand),
157
- "sales-nav": () => import("./sales-nav-I2KMQFFF.js").then((m) => m.salesNavCommand),
158
- recruiter: () => import("./recruiter-7K56E2QA.js").then((m) => m.recruiterCommand)
147
+ profile: () => import("./profile-DD5GMGNL.js").then((m) => m.profileCommand),
148
+ company: () => import("./company-RU2CA5DY.js").then((m) => m.companyCommand),
149
+ job: () => import("./job-FGGQEXSU.js").then((m) => m.jobCommand),
150
+ connect: () => import("./connect-QT6ZOS75.js").then((m) => m.connectCommand),
151
+ search: () => import("./search-ZGTS45BT.js").then((m) => m.searchCommand),
152
+ inbox: () => import("./inbox-DN7X7CM2.js").then((m) => m.inboxCommand),
153
+ message: () => import("./message-6K5E3CUF.js").then((m) => m.messageCommand),
154
+ post: () => import("./post-2JQZ3OSF.js").then((m) => m.postCommand),
155
+ account: () => import("./account-NZBO6Y5I.js").then((m) => m.accountCommand),
156
+ webhook: () => import("./webhook-XPWBI675.js").then((m) => m.webhookCommand),
157
+ "sales-nav": () => import("./sales-nav-QTSTJMKA.js").then((m) => m.salesNavCommand),
158
+ recruiter: () => import("./recruiter-XHVMQWK6.js").then((m) => m.recruiterCommand)
159
159
  },
160
160
  async run() {
161
161
  const { runMain } = await import("citty");
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ streamAll
4
+ } from "./chunk-GXTZION6.js";
5
+ import {
6
+ slimCompany,
7
+ slimSearchJobs,
8
+ slimSearchPeople,
9
+ slimSearchPosts
10
+ } from "./chunk-SSPILTKF.js";
11
+ import {
12
+ resolveIdentifier
13
+ } from "./chunk-DMQZEPQE.js";
14
+ import {
15
+ createClient,
16
+ renderError,
17
+ renderSuccess,
18
+ renderUnexpectedError,
19
+ resolveEffectiveConfig
20
+ } from "./chunk-JXF47TRY.js";
21
+ import {
22
+ GLOBAL_FLAGS
23
+ } from "./chunk-4JHGVY7R.js";
24
+
25
+ // src/commands/company.ts
26
+ import { defineCommand } from "citty";
27
+ function buildOutputStreams() {
28
+ return {
29
+ stdout: { write: (s) => process.stdout.write(s) },
30
+ stderr: { write: (s) => process.stderr.write(s) }
31
+ };
32
+ }
33
+ function requireAccount(account, out) {
34
+ if (!account) {
35
+ out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
36
+ process.exit(2);
37
+ }
38
+ return account;
39
+ }
40
+ function rejectPreviewOnRead(preview, out) {
41
+ if (preview) {
42
+ out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
43
+ process.exit(2);
44
+ }
45
+ }
46
+ function resolveOutputOpts(flags) {
47
+ return {
48
+ json: (flags.json ?? false) || !process.stdout.isTTY,
49
+ isTTY: process.stdout.isTTY ?? false,
50
+ fields: flags.fields,
51
+ verbose: flags.verbose ?? false
52
+ };
53
+ }
54
+ async function handleSdkError(err, outOpts, out) {
55
+ const { CurviateError } = await import("@curviate/sdk");
56
+ if (err instanceof CurviateError) {
57
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
58
+ renderError(err, outOpts, out);
59
+ process.exit(getExitCode(err.code));
60
+ }
61
+ renderUnexpectedError(err, out);
62
+ process.exit(1);
63
+ }
64
+ async function runCompanyGet(client, flags, out) {
65
+ rejectPreviewOnRead(flags.preview, out);
66
+ if (flags.all) {
67
+ out.stderr.write("error: --all is not supported on non-paginated commands.\n");
68
+ process.exit(2);
69
+ }
70
+ if (flags.sections !== void 0) {
71
+ out.stderr.write("error: --sections is not supported on company commands.\n");
72
+ process.exit(2);
73
+ }
74
+ const accountId = requireAccount(flags.account, out);
75
+ const rawId = flags.id ?? "";
76
+ const resolvedId = resolveIdentifier(rawId);
77
+ const outOpts = { ...resolveOutputOpts(flags), slim: slimCompany };
78
+ try {
79
+ const result = await client.account(accountId).companies.get(resolvedId);
80
+ renderSuccess(result, outOpts, out);
81
+ } catch (err) {
82
+ await handleSdkError(err, outOpts, out);
83
+ }
84
+ }
85
+ async function runCompanyEmployees(client, flags, out) {
86
+ rejectPreviewOnRead(flags.preview, out);
87
+ const accountId = requireAccount(flags.account, out);
88
+ const identifier = flags.id ?? "";
89
+ const ns = client.account(accountId);
90
+ const outOpts = resolveOutputOpts(flags);
91
+ const params = {};
92
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
93
+ if (flags.cursor) params["cursor"] = flags.cursor;
94
+ if (flags.keywords) params["keywords"] = flags.keywords;
95
+ if (flags.location) params["location"] = flags.location;
96
+ try {
97
+ if (flags.all) {
98
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
99
+ const fn = (p) => ns.companies.employees(identifier, p);
100
+ for await (const item of streamAll(fn, params, {
101
+ maxPages,
102
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
103
+ `)
104
+ })) {
105
+ out.stdout.write(JSON.stringify(item) + "\n");
106
+ }
107
+ return;
108
+ }
109
+ const result = await ns.companies.employees(identifier, params);
110
+ renderSuccess(result, { ...outOpts, slim: slimSearchPeople }, out);
111
+ } catch (err) {
112
+ await handleSdkError(err, outOpts, out);
113
+ }
114
+ }
115
+ async function runCompanyPosts(client, flags, out) {
116
+ rejectPreviewOnRead(flags.preview, out);
117
+ const accountId = requireAccount(flags.account, out);
118
+ const identifier = flags.id ?? "";
119
+ const ns = client.account(accountId);
120
+ const outOpts = resolveOutputOpts(flags);
121
+ const params = {};
122
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
123
+ if (flags.cursor) params["cursor"] = flags.cursor;
124
+ try {
125
+ if (flags.all) {
126
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
127
+ const fn = (p) => ns.companies.posts(identifier, p);
128
+ for await (const item of streamAll(fn, params, {
129
+ maxPages,
130
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
131
+ `)
132
+ })) {
133
+ out.stdout.write(JSON.stringify(item) + "\n");
134
+ }
135
+ return;
136
+ }
137
+ const result = await ns.companies.posts(identifier, params);
138
+ renderSuccess(result, { ...outOpts, slim: slimSearchPosts }, out);
139
+ } catch (err) {
140
+ await handleSdkError(err, outOpts, out);
141
+ }
142
+ }
143
+ async function runCompanyJobs(client, flags, out) {
144
+ rejectPreviewOnRead(flags.preview, out);
145
+ const accountId = requireAccount(flags.account, out);
146
+ const identifier = flags.id ?? "";
147
+ const ns = client.account(accountId);
148
+ const outOpts = resolveOutputOpts(flags);
149
+ const params = {};
150
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
151
+ if (flags.cursor) params["cursor"] = flags.cursor;
152
+ if (flags.keywords) params["keywords"] = flags.keywords;
153
+ try {
154
+ if (flags.all) {
155
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
156
+ const fn = (p) => ns.companies.jobs(identifier, p);
157
+ for await (const item of streamAll(fn, params, {
158
+ maxPages,
159
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
160
+ `)
161
+ })) {
162
+ out.stdout.write(JSON.stringify(item) + "\n");
163
+ }
164
+ return;
165
+ }
166
+ const result = await ns.companies.jobs(identifier, params);
167
+ renderSuccess(result, { ...outOpts, slim: slimSearchJobs }, out);
168
+ } catch (err) {
169
+ await handleSdkError(err, outOpts, out);
170
+ }
171
+ }
172
+ async function runCompanyFollowers(client, flags, out) {
173
+ rejectPreviewOnRead(flags.preview, out);
174
+ const accountId = requireAccount(flags.account, out);
175
+ const identifier = flags.id ?? "";
176
+ const ns = client.account(accountId);
177
+ const outOpts = resolveOutputOpts(flags);
178
+ const params = {};
179
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
180
+ if (flags.cursor) params["cursor"] = flags.cursor;
181
+ try {
182
+ if (flags.all) {
183
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
184
+ const fn = (p) => ns.companies.followers(identifier, p);
185
+ for await (const item of streamAll(fn, params, {
186
+ maxPages,
187
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
188
+ `)
189
+ })) {
190
+ out.stdout.write(JSON.stringify(item) + "\n");
191
+ }
192
+ return;
193
+ }
194
+ const result = await ns.companies.followers(identifier, params);
195
+ renderSuccess(result, outOpts, out);
196
+ } catch (err) {
197
+ await handleSdkError(err, outOpts, out);
198
+ }
199
+ }
200
+ var companyEmployeesCommand = defineCommand({
201
+ meta: { name: "employees", description: "List people who currently work at the company." },
202
+ args: {
203
+ ...GLOBAL_FLAGS,
204
+ id: { type: "positional", description: "The company's numeric provider_id (the id field of `company <id>`)." },
205
+ keywords: { type: "string", description: "Free-text keyword filter across employee profile fields." },
206
+ location: { type: "string", description: "Opaque location id from `search parameters --type LOCATION`." }
207
+ },
208
+ async run({ args }) {
209
+ const flags = args;
210
+ const cfg = await resolveEffectiveConfig({
211
+ apiKey: flags["api-key"],
212
+ baseUrl: flags["base-url"],
213
+ timeout: flags.timeout,
214
+ account: flags.account,
215
+ profile: flags.profile
216
+ });
217
+ if (!cfg.apiKey) {
218
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
219
+ process.exit(3);
220
+ }
221
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
222
+ const out = buildOutputStreams();
223
+ await runCompanyEmployees(client, { ...flags, account: flags.account ?? cfg.account }, out);
224
+ }
225
+ });
226
+ var companyPostsCommand = defineCommand({
227
+ meta: { name: "posts", description: "List the company's posts." },
228
+ args: {
229
+ ...GLOBAL_FLAGS,
230
+ id: { type: "positional", description: "The company's numeric provider_id (the id field of `company <id>`)." }
231
+ },
232
+ async run({ args }) {
233
+ const flags = args;
234
+ const cfg = await resolveEffectiveConfig({
235
+ apiKey: flags["api-key"],
236
+ baseUrl: flags["base-url"],
237
+ timeout: flags.timeout,
238
+ account: flags.account,
239
+ profile: flags.profile
240
+ });
241
+ if (!cfg.apiKey) {
242
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
243
+ process.exit(3);
244
+ }
245
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
246
+ const out = buildOutputStreams();
247
+ await runCompanyPosts(client, { ...flags, account: flags.account ?? cfg.account }, out);
248
+ }
249
+ });
250
+ var companyJobsCommand = defineCommand({
251
+ meta: { name: "jobs", description: "List the company's open job postings." },
252
+ args: {
253
+ ...GLOBAL_FLAGS,
254
+ id: { type: "positional", description: "The company's numeric provider_id (the id field of `company <id>`)." },
255
+ keywords: { type: "string", description: "Free-text keyword filter across job postings." }
256
+ },
257
+ async run({ args }) {
258
+ const flags = args;
259
+ const cfg = await resolveEffectiveConfig({
260
+ apiKey: flags["api-key"],
261
+ baseUrl: flags["base-url"],
262
+ timeout: flags.timeout,
263
+ account: flags.account,
264
+ profile: flags.profile
265
+ });
266
+ if (!cfg.apiKey) {
267
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
268
+ process.exit(3);
269
+ }
270
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
271
+ const out = buildOutputStreams();
272
+ await runCompanyJobs(client, { ...flags, account: flags.account ?? cfg.account }, out);
273
+ }
274
+ });
275
+ var companyFollowersCommand = defineCommand({
276
+ meta: { name: "followers", description: "List the company's followers. Requires page-admin permission." },
277
+ args: {
278
+ ...GLOBAL_FLAGS,
279
+ id: { type: "positional", description: "The company's numeric provider_id (the id field of `company <id>`)." }
280
+ },
281
+ async run({ args }) {
282
+ const flags = args;
283
+ const cfg = await resolveEffectiveConfig({
284
+ apiKey: flags["api-key"],
285
+ baseUrl: flags["base-url"],
286
+ timeout: flags.timeout,
287
+ account: flags.account,
288
+ profile: flags.profile
289
+ });
290
+ if (!cfg.apiKey) {
291
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
292
+ process.exit(3);
293
+ }
294
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
295
+ const out = buildOutputStreams();
296
+ await runCompanyFollowers(client, { ...flags, account: flags.account ?? cfg.account }, out);
297
+ }
298
+ });
299
+ var companyCommand = defineCommand({
300
+ meta: { name: "company", description: "Fetch a company profile by URL, slug, or numeric id, and its sub-resources." },
301
+ args: {
302
+ ...GLOBAL_FLAGS,
303
+ id: { type: "positional", description: "Company identifier (URL, slug, or native id)." },
304
+ sections: { type: "string", description: "Not supported on company commands \u2014 usage error (exit 2) if supplied." }
305
+ },
306
+ subCommands: {
307
+ employees: companyEmployeesCommand,
308
+ posts: companyPostsCommand,
309
+ jobs: companyJobsCommand,
310
+ followers: companyFollowersCommand
311
+ },
312
+ async run({ args }) {
313
+ const flags = args;
314
+ const cfg = await resolveEffectiveConfig({
315
+ apiKey: flags["api-key"],
316
+ baseUrl: flags["base-url"],
317
+ timeout: flags.timeout,
318
+ account: flags.account,
319
+ profile: flags.profile
320
+ });
321
+ if (!cfg.apiKey) {
322
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
323
+ process.exit(3);
324
+ }
325
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
326
+ const out = buildOutputStreams();
327
+ await runCompanyGet(client, { ...flags, account: flags.account ?? cfg.account }, out);
328
+ }
329
+ });
330
+ export {
331
+ companyCommand,
332
+ runCompanyEmployees,
333
+ runCompanyFollowers,
334
+ runCompanyGet,
335
+ runCompanyJobs,
336
+ runCompanyPosts
337
+ };
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- streamAll
4
- } from "./chunk-GXTZION6.js";
5
2
  import {
6
3
  buildPreviewOutput
7
4
  } from "./chunk-R3VLWLVV.js";
5
+ import {
6
+ streamAll
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  slimInviteReceived,
10
10
  slimInviteReceivedItem,
@@ -79,7 +79,7 @@ async function runConnectSend(client, flags, out) {
79
79
  } catch (err) {
80
80
  const { CurviateError } = await import("@curviate/sdk");
81
81
  if (err instanceof CurviateError) {
82
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
82
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
83
83
  renderError(err, outOpts, out);
84
84
  process.exit(getExitCode(err.code));
85
85
  }
@@ -117,7 +117,7 @@ async function runConnectSent(client, flags, out) {
117
117
  } catch (err) {
118
118
  const { CurviateError } = await import("@curviate/sdk");
119
119
  if (err instanceof CurviateError) {
120
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
120
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
121
121
  renderError(err, outOpts, out);
122
122
  process.exit(getExitCode(err.code));
123
123
  }
@@ -155,7 +155,7 @@ async function runConnectReceived(client, flags, out) {
155
155
  } catch (err) {
156
156
  const { CurviateError } = await import("@curviate/sdk");
157
157
  if (err instanceof CurviateError) {
158
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
158
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
159
159
  renderError(err, outOpts, out);
160
160
  process.exit(getExitCode(err.code));
161
161
  }
@@ -193,7 +193,7 @@ async function runConnectRespond(client, flags, out) {
193
193
  } catch (err) {
194
194
  const { CurviateError } = await import("@curviate/sdk");
195
195
  if (err instanceof CurviateError) {
196
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
196
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
197
197
  renderError(err, outOpts, out);
198
198
  process.exit(getExitCode(err.code));
199
199
  }
@@ -222,7 +222,7 @@ async function runConnectCancel(client, flags, out) {
222
222
  } catch (err) {
223
223
  const { CurviateError } = await import("@curviate/sdk");
224
224
  if (err instanceof CurviateError) {
225
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
225
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
226
226
  renderError(err, outOpts, out);
227
227
  process.exit(getExitCode(err.code));
228
228
  }
@@ -3,7 +3,7 @@ import {
3
3
  AUTH_NEEDED,
4
4
  EXIT_CODE_MAP,
5
5
  getExitCode
6
- } from "./chunk-OSQ643UW.js";
6
+ } from "./chunk-HMAGEMF7.js";
7
7
  export {
8
8
  AUTH_NEEDED,
9
9
  EXIT_CODE_MAP,
@@ -69,7 +69,7 @@ function validateIsoZTimestamp(value, flagName, out) {
69
69
  async function handleSdkError(err, outOpts, out) {
70
70
  const { CurviateError } = await import("@curviate/sdk");
71
71
  if (err instanceof CurviateError) {
72
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
72
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
73
73
  renderError(err, outOpts, out);
74
74
  process.exit(getExitCode(err.code));
75
75
  }
@@ -55,7 +55,7 @@ async function runJobGet(client, flags, out) {
55
55
  } catch (err) {
56
56
  const { CurviateError } = await import("@curviate/sdk");
57
57
  if (err instanceof CurviateError) {
58
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
58
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
59
59
  renderError(err, outOpts, out);
60
60
  process.exit(getExitCode(err.code));
61
61
  }
@@ -73,7 +73,7 @@ var MEMBER_PROVIDER_ID_RE = /^A[CDE][A-Za-z0-9_-]{4,}$/;
73
73
  async function handleSdkError(err, outOpts, out) {
74
74
  const { CurviateError } = await import("@curviate/sdk");
75
75
  if (err instanceof CurviateError) {
76
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
76
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
77
77
  renderError(err, outOpts, out);
78
78
  process.exit(getExitCode(err.code));
79
79
  }
@@ -6,12 +6,12 @@ import {
6
6
  import {
7
7
  resolveTextOrStdin
8
8
  } from "./chunk-U7Y4EXHT.js";
9
- import {
10
- streamAll
11
- } from "./chunk-GXTZION6.js";
12
9
  import {
13
10
  buildPreviewOutput
14
11
  } from "./chunk-R3VLWLVV.js";
12
+ import {
13
+ streamAll
14
+ } from "./chunk-GXTZION6.js";
15
15
  import {
16
16
  createClient,
17
17
  renderError,
@@ -72,7 +72,7 @@ function normalizeAttachPaths(attach) {
72
72
  async function handleSdkError(err, outOpts, out) {
73
73
  const { CurviateError } = await import("@curviate/sdk");
74
74
  if (err instanceof CurviateError) {
75
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
75
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
76
76
  renderError(err, outOpts, out);
77
77
  process.exit(getExitCode(err.code));
78
78
  }
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- streamAll
4
- } from "./chunk-GXTZION6.js";
5
2
  import {
6
3
  buildPreviewOutput
7
4
  } from "./chunk-R3VLWLVV.js";
5
+ import {
6
+ streamAll
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  slimProfile,
10
10
  slimProfileMe
@@ -141,7 +141,7 @@ async function runProfileMe(client, flags, out) {
141
141
  } catch (err) {
142
142
  const { CurviateError } = await import("@curviate/sdk");
143
143
  if (err instanceof CurviateError) {
144
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
144
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
145
145
  renderError(err, outOpts, out);
146
146
  process.exit(getExitCode(err.code));
147
147
  }
@@ -161,7 +161,7 @@ async function runProfileMe(client, flags, out) {
161
161
  } catch (err) {
162
162
  const { CurviateError } = await import("@curviate/sdk");
163
163
  if (err instanceof CurviateError) {
164
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
164
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
165
165
  renderError(err, outOpts, out);
166
166
  process.exit(getExitCode(err.code));
167
167
  }
@@ -278,7 +278,7 @@ async function runProfileGet(client, flags, out) {
278
278
  } catch (err) {
279
279
  const { CurviateError } = await import("@curviate/sdk");
280
280
  if (err instanceof CurviateError) {
281
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
281
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
282
282
  renderError(err, outOpts, out);
283
283
  process.exit(getExitCode(err.code));
284
284
  }
@@ -315,7 +315,7 @@ async function runProfileConnections(client, flags, out) {
315
315
  } catch (err) {
316
316
  const { CurviateError } = await import("@curviate/sdk");
317
317
  if (err instanceof CurviateError) {
318
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
318
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
319
319
  renderError(err, outOpts, out);
320
320
  process.exit(getExitCode(err.code));
321
321
  }
@@ -346,7 +346,7 @@ async function runProfileEndorse(client, flags, out) {
346
346
  } catch (err) {
347
347
  const { CurviateError } = await import("@curviate/sdk");
348
348
  if (err instanceof CurviateError) {
349
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
349
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
350
350
  renderError(err, outOpts, out);
351
351
  process.exit(getExitCode(err.code));
352
352
  }
@@ -12,12 +12,12 @@ import {
12
12
  AttachError,
13
13
  readAttachment
14
14
  } from "./chunk-Q43HZUN3.js";
15
- import {
16
- streamAll
17
- } from "./chunk-GXTZION6.js";
18
15
  import {
19
16
  buildPreviewOutput
20
17
  } from "./chunk-R3VLWLVV.js";
18
+ import {
19
+ streamAll
20
+ } from "./chunk-GXTZION6.js";
21
21
  import {
22
22
  slimJob
23
23
  } from "./chunk-SSPILTKF.js";
@@ -75,7 +75,7 @@ function normalizeAttachPaths(attach) {
75
75
  async function handleSdkError(err, outOpts, out) {
76
76
  const { CurviateError } = await import("@curviate/sdk");
77
77
  if (err instanceof CurviateError) {
78
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
78
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
79
79
  renderError(err, outOpts, out);
80
80
  process.exit(getExitCode(err.code));
81
81
  }
@@ -9,12 +9,12 @@ import {
9
9
  AttachError,
10
10
  readAttachment
11
11
  } from "./chunk-Q43HZUN3.js";
12
- import {
13
- streamAll
14
- } from "./chunk-GXTZION6.js";
15
12
  import {
16
13
  buildPreviewOutput
17
14
  } from "./chunk-R3VLWLVV.js";
15
+ import {
16
+ streamAll
17
+ } from "./chunk-GXTZION6.js";
18
18
  import {
19
19
  resolveIdentifier
20
20
  } from "./chunk-DMQZEPQE.js";
@@ -66,7 +66,7 @@ function normalizeAttachPaths(attach) {
66
66
  async function handleSdkError(err, outOpts, out) {
67
67
  const { CurviateError } = await import("@curviate/sdk");
68
68
  if (err instanceof CurviateError) {
69
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
69
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
70
70
  renderError(err, outOpts, out);
71
71
  process.exit(getExitCode(err.code));
72
72
  }
@@ -276,13 +276,13 @@ async function runSalesNavProfile(client, flags, out) {
276
276
  async function runSalesNavSaveLead(client, flags, out) {
277
277
  const accountId = requireAccount(flags.account, out);
278
278
  const userId = flags.userId ?? "";
279
+ const listId = flags.list ?? "";
279
280
  const outOpts = resolveOutputOpts(flags);
280
- const body = {};
281
- if (flags["list-id"]) body["list_id"] = flags["list-id"];
281
+ const body = { user_id: userId };
282
282
  if (flags.preview) {
283
283
  const preview = buildPreviewOutput({
284
284
  method: "salesNavigator.saveLead",
285
- args: { user_id: userId },
285
+ args: { list_id: listId, user_id: userId },
286
286
  body,
287
287
  account: accountId
288
288
  });
@@ -291,7 +291,153 @@ async function runSalesNavSaveLead(client, flags, out) {
291
291
  }
292
292
  const ns = client.account(accountId);
293
293
  try {
294
- const result = await ns.salesNavigator.saveLead(userId, body);
294
+ const result = await ns.salesNavigator.saveLead({ list_id: listId, user_id: userId });
295
+ renderSuccess(result, outOpts, out);
296
+ } catch (err) {
297
+ await handleSdkError(err, outOpts, out);
298
+ }
299
+ }
300
+ async function runSalesNavAccountLists(client, flags, out) {
301
+ rejectPreviewOnRead(flags.preview, out);
302
+ const accountId = requireAccount(flags.account, out);
303
+ const ns = client.account(accountId);
304
+ const outOpts = resolveOutputOpts(flags);
305
+ const all = flags.all ?? false;
306
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
307
+ const params = {};
308
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
309
+ if (flags.cursor) params["cursor"] = flags.cursor;
310
+ try {
311
+ if (all) {
312
+ const fn = (p) => ns.salesNavigator.accountLists(p);
313
+ for await (const item of streamAll(fn, params, {
314
+ maxPages,
315
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
316
+ `)
317
+ })) {
318
+ out.stdout.write(JSON.stringify(item) + "\n");
319
+ }
320
+ return;
321
+ }
322
+ const result = await ns.salesNavigator.accountLists(Object.keys(params).length > 0 ? params : void 0);
323
+ renderSuccess(result, outOpts, out);
324
+ } catch (err) {
325
+ await handleSdkError(err, outOpts, out);
326
+ }
327
+ }
328
+ async function runSalesNavLeadLists(client, flags, out) {
329
+ rejectPreviewOnRead(flags.preview, out);
330
+ const accountId = requireAccount(flags.account, out);
331
+ const ns = client.account(accountId);
332
+ const outOpts = resolveOutputOpts(flags);
333
+ const all = flags.all ?? false;
334
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
335
+ const params = {};
336
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
337
+ if (flags.cursor) params["cursor"] = flags.cursor;
338
+ try {
339
+ if (all) {
340
+ const fn = (p) => ns.salesNavigator.leadLists(p);
341
+ for await (const item of streamAll(fn, params, {
342
+ maxPages,
343
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
344
+ `)
345
+ })) {
346
+ out.stdout.write(JSON.stringify(item) + "\n");
347
+ }
348
+ return;
349
+ }
350
+ const result = await ns.salesNavigator.leadLists(Object.keys(params).length > 0 ? params : void 0);
351
+ renderSuccess(result, outOpts, out);
352
+ } catch (err) {
353
+ await handleSdkError(err, outOpts, out);
354
+ }
355
+ }
356
+ async function runSalesNavBrowseAccountList(client, flags, out) {
357
+ rejectPreviewOnRead(flags.preview, out);
358
+ const accountId = requireAccount(flags.account, out);
359
+ const listId = flags.listId ?? "";
360
+ const ns = client.account(accountId);
361
+ const outOpts = resolveOutputOpts(flags);
362
+ const all = flags.all ?? false;
363
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
364
+ const body = {};
365
+ if (flags.filter) body["filter"] = flags.filter;
366
+ if (flags["sort-by"]) body["sort_by"] = flags["sort-by"];
367
+ if (flags["sort-order"]) body["sort_order"] = flags["sort-order"];
368
+ const params = {};
369
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
370
+ if (flags.cursor) params["cursor"] = flags.cursor;
371
+ try {
372
+ if (all) {
373
+ const fn = (p) => ns.salesNavigator.browseAccountList(listId, body, p);
374
+ for await (const item of streamAll(fn, params, {
375
+ maxPages,
376
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
377
+ `)
378
+ })) {
379
+ out.stdout.write(JSON.stringify(item) + "\n");
380
+ }
381
+ return;
382
+ }
383
+ const result = await ns.salesNavigator.browseAccountList(listId, body, Object.keys(params).length > 0 ? params : void 0);
384
+ renderSuccess(result, outOpts, out);
385
+ } catch (err) {
386
+ await handleSdkError(err, outOpts, out);
387
+ }
388
+ }
389
+ async function runSalesNavBrowseLeadList(client, flags, out) {
390
+ rejectPreviewOnRead(flags.preview, out);
391
+ const accountId = requireAccount(flags.account, out);
392
+ const listId = flags.listId ?? "";
393
+ const ns = client.account(accountId);
394
+ const outOpts = resolveOutputOpts(flags);
395
+ const all = flags.all ?? false;
396
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
397
+ const body = {};
398
+ if (flags.spotlight) body["spotlight"] = flags.spotlight;
399
+ if (flags["sort-by"]) body["sort_by"] = flags["sort-by"];
400
+ if (flags["sort-order"]) body["sort_order"] = flags["sort-order"];
401
+ const params = {};
402
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
403
+ if (flags.cursor) params["cursor"] = flags.cursor;
404
+ try {
405
+ if (all) {
406
+ const fn = (p) => ns.salesNavigator.browseLeadList(listId, body, p);
407
+ for await (const item of streamAll(fn, params, {
408
+ maxPages,
409
+ onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
410
+ `)
411
+ })) {
412
+ out.stdout.write(JSON.stringify(item) + "\n");
413
+ }
414
+ return;
415
+ }
416
+ const result = await ns.salesNavigator.browseLeadList(listId, body, Object.keys(params).length > 0 ? params : void 0);
417
+ renderSuccess(result, outOpts, out);
418
+ } catch (err) {
419
+ await handleSdkError(err, outOpts, out);
420
+ }
421
+ }
422
+ async function runSalesNavSaveAccount(client, flags, out) {
423
+ const accountId = requireAccount(flags.account, out);
424
+ const listId = flags.list ?? "";
425
+ const companyId = flags.companyId ?? "";
426
+ const outOpts = resolveOutputOpts(flags);
427
+ const body = { company_id: companyId };
428
+ if (flags.preview) {
429
+ const preview = buildPreviewOutput({
430
+ method: "salesNavigator.saveAccount",
431
+ args: { list_id: listId, company_id: companyId },
432
+ body,
433
+ account: accountId
434
+ });
435
+ out.stdout.write(JSON.stringify(preview) + "\n");
436
+ return;
437
+ }
438
+ const ns = client.account(accountId);
439
+ try {
440
+ const result = await ns.salesNavigator.saveAccount({ list_id: listId, company_id: companyId });
295
441
  renderSuccess(result, outOpts, out);
296
442
  } catch (err) {
297
443
  await handleSdkError(err, outOpts, out);
@@ -489,12 +635,12 @@ var salesNavProfileCommand = defineCommand({
489
635
  }
490
636
  });
491
637
  var salesNavSaveLeadCommand = defineCommand({
492
- meta: { name: "save-lead", description: "Save a Sales Navigator member as a lead." },
638
+ meta: { name: "save-lead", description: "Save a Sales Navigator member into a lead list." },
493
639
  args: {
494
640
  // Write command: WRITE_FLAGS omits pagination/projection flags
495
641
  ...WRITE_FLAGS,
496
642
  userId: { type: "positional", description: "Sales Navigator member ID (ACw\u2026 format)." },
497
- "list-id": { type: "string", description: "Lead list ID to save the lead into." }
643
+ list: { type: "string", description: "Lead list ID to save the member into (required \u2014 the v2 save always targets a specific list).", required: true }
498
644
  },
499
645
  async run({ args }) {
500
646
  const flags = args;
@@ -514,6 +660,128 @@ var salesNavSaveLeadCommand = defineCommand({
514
660
  await runSalesNavSaveLead(client, { ...flags, account: flags.account ?? cfg.account }, out);
515
661
  }
516
662
  });
663
+ var salesNavAccountListsCommand = defineCommand({
664
+ meta: { name: "account-lists", description: "List the saved-account (company) lists on the operator's Sales Navigator seat." },
665
+ args: { ...GLOBAL_FLAGS },
666
+ async run({ args }) {
667
+ const flags = args;
668
+ const cfg = await resolveEffectiveConfig({
669
+ apiKey: flags["api-key"],
670
+ baseUrl: flags["base-url"],
671
+ timeout: flags.timeout,
672
+ account: flags.account,
673
+ profile: flags.profile
674
+ });
675
+ if (!cfg.apiKey) {
676
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
677
+ process.exit(3);
678
+ }
679
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
680
+ const out = buildOutputStreams();
681
+ await runSalesNavAccountLists(client, { ...flags, account: flags.account ?? cfg.account }, out);
682
+ }
683
+ });
684
+ var salesNavLeadListsCommand = defineCommand({
685
+ meta: { name: "lead-lists", description: "List the saved-lead (member) lists on the operator's Sales Navigator seat." },
686
+ args: { ...GLOBAL_FLAGS },
687
+ async run({ args }) {
688
+ const flags = args;
689
+ const cfg = await resolveEffectiveConfig({
690
+ apiKey: flags["api-key"],
691
+ baseUrl: flags["base-url"],
692
+ timeout: flags.timeout,
693
+ account: flags.account,
694
+ profile: flags.profile
695
+ });
696
+ if (!cfg.apiKey) {
697
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
698
+ process.exit(3);
699
+ }
700
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
701
+ const out = buildOutputStreams();
702
+ await runSalesNavLeadLists(client, { ...flags, account: flags.account ?? cfg.account }, out);
703
+ }
704
+ });
705
+ var salesNavBrowseAccountListCommand = defineCommand({
706
+ meta: { name: "browse-account-list", description: "Browse the saved accounts (companies) in one account list." },
707
+ args: {
708
+ ...GLOBAL_FLAGS,
709
+ listId: { type: "positional", description: "The account-list id (from `sales-nav account-lists`)." },
710
+ filter: { type: "string", description: "Restrict to a saved-account subset: STARRED, GROWTH_ALERTS, or RISK_ALERTS." },
711
+ "sort-by": { type: "string", description: "Sort field: DATE_ADDED or NAME. Defaults to NAME." },
712
+ "sort-order": { type: "string", description: "Sort direction: ASCENDING or DESCENDING. Defaults to ASCENDING." }
713
+ },
714
+ async run({ args }) {
715
+ const flags = args;
716
+ const cfg = await resolveEffectiveConfig({
717
+ apiKey: flags["api-key"],
718
+ baseUrl: flags["base-url"],
719
+ timeout: flags.timeout,
720
+ account: flags.account,
721
+ profile: flags.profile
722
+ });
723
+ if (!cfg.apiKey) {
724
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
725
+ process.exit(3);
726
+ }
727
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
728
+ const out = buildOutputStreams();
729
+ await runSalesNavBrowseAccountList(client, { ...flags, account: flags.account ?? cfg.account }, out);
730
+ }
731
+ });
732
+ var salesNavBrowseLeadListCommand = defineCommand({
733
+ meta: { name: "browse-lead-list", description: "Browse the saved leads (members) in one lead list." },
734
+ args: {
735
+ ...GLOBAL_FLAGS,
736
+ listId: { type: "positional", description: "The lead-list id (from `sales-nav lead-lists`)." },
737
+ spotlight: { type: "string", description: "Restrict to a spotlighted lead subset: RECENT_POSITION_CHANGE, RECENTLY_POSTED_ON_LINKEDIN, FOLLOW_YOUR_COMPANY, or SHARE_EXPERIENCE." },
738
+ "sort-by": { type: "string", description: "Sort field: DATE_ADDED, ACCOUNT, NAME, or OUTREACH_ACTIVITY. Defaults to DATE_ADDED." },
739
+ "sort-order": { type: "string", description: "Sort direction: ASCENDING or DESCENDING. Defaults to DESCENDING." }
740
+ },
741
+ async run({ args }) {
742
+ const flags = args;
743
+ const cfg = await resolveEffectiveConfig({
744
+ apiKey: flags["api-key"],
745
+ baseUrl: flags["base-url"],
746
+ timeout: flags.timeout,
747
+ account: flags.account,
748
+ profile: flags.profile
749
+ });
750
+ if (!cfg.apiKey) {
751
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
752
+ process.exit(3);
753
+ }
754
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
755
+ const out = buildOutputStreams();
756
+ await runSalesNavBrowseLeadList(client, { ...flags, account: flags.account ?? cfg.account }, out);
757
+ }
758
+ });
759
+ var salesNavSaveAccountCommand = defineCommand({
760
+ meta: { name: "save-account", description: "Save a LinkedIn company into an account list." },
761
+ args: {
762
+ // Write command: WRITE_FLAGS omits pagination/projection flags
763
+ ...WRITE_FLAGS,
764
+ companyId: { type: "positional", description: "The LinkedIn company id to save into the account list." },
765
+ list: { type: "string", description: "The target account-list id to save the company into (required).", required: true }
766
+ },
767
+ async run({ args }) {
768
+ const flags = args;
769
+ const cfg = await resolveEffectiveConfig({
770
+ apiKey: flags["api-key"],
771
+ baseUrl: flags["base-url"],
772
+ timeout: flags.timeout,
773
+ account: flags.account,
774
+ profile: flags.profile
775
+ });
776
+ if (!cfg.apiKey) {
777
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
778
+ process.exit(3);
779
+ }
780
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
781
+ const out = buildOutputStreams();
782
+ await runSalesNavSaveAccount(client, { ...flags, account: flags.account ?? cfg.account }, out);
783
+ }
784
+ });
517
785
  var salesNavCommand = defineCommand({
518
786
  meta: { name: "sales-nav", description: "Sales Navigator operations (requires the Sales Navigator add-on)." },
519
787
  args: { ...GLOBAL_FLAGS },
@@ -522,18 +790,28 @@ var salesNavCommand = defineCommand({
522
790
  message: salesNavMessageCommand,
523
791
  search: salesNavSearchCommand,
524
792
  profile: salesNavProfileCommand,
525
- "save-lead": salesNavSaveLeadCommand
793
+ "save-lead": salesNavSaveLeadCommand,
794
+ "account-lists": salesNavAccountListsCommand,
795
+ "lead-lists": salesNavLeadListsCommand,
796
+ "browse-account-list": salesNavBrowseAccountListCommand,
797
+ "browse-lead-list": salesNavBrowseLeadListCommand,
798
+ "save-account": salesNavSaveAccountCommand
526
799
  },
527
800
  async run() {
528
801
  process.stderr.write(
529
- 'Usage: curviate sales-nav sync\n curviate sales-nav search people [--keywords <k>]\n curviate sales-nav search companies [--keywords <k>]\n curviate sales-nav search parameters --type <t>\n curviate sales-nav message new --to <id> "<text>"\n curviate sales-nav profile <identifier>\n curviate sales-nav save-lead <user_id> [--list-id <id>]\n'
802
+ 'Usage: curviate sales-nav sync\n curviate sales-nav search people [--keywords <k>]\n curviate sales-nav search companies [--keywords <k>]\n curviate sales-nav search parameters --type <t>\n curviate sales-nav message new --to <id> "<text>"\n curviate sales-nav profile <identifier>\n curviate sales-nav save-lead --list <id> <user_id>\n curviate sales-nav account-lists --account <id>\n curviate sales-nav lead-lists --account <id>\n curviate sales-nav browse-account-list <list_id> --account <id>\n curviate sales-nav browse-lead-list <list_id> --account <id>\n curviate sales-nav save-account --list <id> <company_id> --account <id>\n'
530
803
  );
531
804
  }
532
805
  });
533
806
  export {
807
+ runSalesNavAccountLists,
808
+ runSalesNavBrowseAccountList,
809
+ runSalesNavBrowseLeadList,
534
810
  runSalesNavGetParameters,
811
+ runSalesNavLeadLists,
535
812
  runSalesNavMessageNew,
536
813
  runSalesNavProfile,
814
+ runSalesNavSaveAccount,
537
815
  runSalesNavSaveLead,
538
816
  runSalesNavSearchCompanies,
539
817
  runSalesNavSearchPeople,
@@ -222,7 +222,7 @@ async function runSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READ
222
222
  } catch (err) {
223
223
  const { CurviateError } = await import("@curviate/sdk");
224
224
  if (err instanceof CurviateError) {
225
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
225
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
226
226
  renderError(err, outOpts, out);
227
227
  process.exit(getExitCode(err.code));
228
228
  }
@@ -264,7 +264,7 @@ async function runSearchCompanies(client, flags, out, readers = DEFAULT_FILTER_R
264
264
  } catch (err) {
265
265
  const { CurviateError } = await import("@curviate/sdk");
266
266
  if (err instanceof CurviateError) {
267
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
267
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
268
268
  renderError(err, outOpts, out);
269
269
  process.exit(getExitCode(err.code));
270
270
  }
@@ -306,7 +306,7 @@ async function runSearchPosts(client, flags, out, readers = DEFAULT_FILTER_READE
306
306
  } catch (err) {
307
307
  const { CurviateError } = await import("@curviate/sdk");
308
308
  if (err instanceof CurviateError) {
309
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
309
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
310
310
  renderError(err, outOpts, out);
311
311
  process.exit(getExitCode(err.code));
312
312
  }
@@ -348,7 +348,7 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
348
348
  } catch (err) {
349
349
  const { CurviateError } = await import("@curviate/sdk");
350
350
  if (err instanceof CurviateError) {
351
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
351
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
352
352
  renderError(err, outOpts, out);
353
353
  process.exit(getExitCode(err.code));
354
354
  }
@@ -372,7 +372,7 @@ async function runSearchParameters(client, flags, out) {
372
372
  } catch (err) {
373
373
  const { CurviateError } = await import("@curviate/sdk");
374
374
  if (err instanceof CurviateError) {
375
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
375
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
376
376
  renderError(err, outOpts, out);
377
377
  process.exit(getExitCode(err.code));
378
378
  }
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- streamAll
4
- } from "./chunk-GXTZION6.js";
5
2
  import {
6
3
  buildPreviewOutput
7
4
  } from "./chunk-R3VLWLVV.js";
5
+ import {
6
+ streamAll
7
+ } from "./chunk-GXTZION6.js";
8
8
  import {
9
9
  createClient,
10
10
  renderError,
@@ -47,7 +47,7 @@ function resolveOutputOpts(flags) {
47
47
  async function handleError(err, outOpts, out) {
48
48
  const { CurviateError } = await import("@curviate/sdk");
49
49
  if (err instanceof CurviateError) {
50
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
50
+ const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
51
51
  renderError(err, outOpts, out);
52
52
  process.exit(getExitCode(err.code));
53
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/cli",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "private": false,
5
5
  "description": "Official command-line interface for the Curviate API.",
6
6
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "clean": "rm -rf dist *.tsbuildinfo"
41
41
  },
42
42
  "dependencies": {
43
- "@curviate/sdk": "^0.11.0",
43
+ "@curviate/sdk": "^0.12.0",
44
44
  "citty": "^0.1.6",
45
45
  "open": "^10.1.0"
46
46
  },
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- slimCompany
4
- } from "./chunk-SSPILTKF.js";
5
- import {
6
- resolveIdentifier
7
- } from "./chunk-DMQZEPQE.js";
8
- import {
9
- createClient,
10
- renderError,
11
- renderSuccess,
12
- renderUnexpectedError,
13
- resolveEffectiveConfig
14
- } from "./chunk-JXF47TRY.js";
15
- import {
16
- GLOBAL_FLAGS
17
- } from "./chunk-4JHGVY7R.js";
18
-
19
- // src/commands/company.ts
20
- import { defineCommand } from "citty";
21
- function buildOutputStreams() {
22
- return {
23
- stdout: { write: (s) => process.stdout.write(s) },
24
- stderr: { write: (s) => process.stderr.write(s) }
25
- };
26
- }
27
- async function runCompanyGet(client, flags, out) {
28
- if (flags.preview) {
29
- out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
30
- process.exit(2);
31
- }
32
- if (flags.all) {
33
- out.stderr.write("error: --all is not supported on non-paginated commands.\n");
34
- process.exit(2);
35
- }
36
- if (flags.sections !== void 0) {
37
- out.stderr.write("error: --sections is not supported on company commands.\n");
38
- process.exit(2);
39
- }
40
- const rawId = flags.id ?? "";
41
- const resolvedId = resolveIdentifier(rawId);
42
- const outOpts = {
43
- json: (flags.json ?? false) || !process.stdout.isTTY,
44
- isTTY: process.stdout.isTTY ?? false,
45
- fields: flags.fields,
46
- verbose: flags.verbose ?? false,
47
- slim: slimCompany
48
- };
49
- try {
50
- const getCompany = flags.account ? client.account(flags.account).profiles.getCompany.bind(client.account(flags.account).profiles) : client.profiles.getCompany.bind(client.profiles);
51
- const result = await getCompany(resolvedId);
52
- renderSuccess(result, outOpts, out);
53
- } catch (err) {
54
- const { CurviateError } = await import("@curviate/sdk");
55
- if (err instanceof CurviateError) {
56
- const { getExitCode } = await import("./exit-codes-2ASIFXGR.js");
57
- renderError(err, outOpts, out);
58
- process.exit(getExitCode(err.code));
59
- }
60
- renderUnexpectedError(err, out);
61
- process.exit(1);
62
- }
63
- }
64
- var companyCommand = defineCommand({
65
- meta: { name: "company", description: "Fetch a company profile by URL or slug." },
66
- args: {
67
- ...GLOBAL_FLAGS,
68
- id: { type: "positional", description: "Company identifier (URL, slug, or native id)." },
69
- sections: { type: "string", description: "Not supported on company commands \u2014 usage error (exit 2) if supplied." }
70
- },
71
- async run({ args }) {
72
- const flags = args;
73
- const cfg = await resolveEffectiveConfig({
74
- apiKey: flags["api-key"],
75
- baseUrl: flags["base-url"],
76
- timeout: flags.timeout,
77
- account: flags.account,
78
- profile: flags.profile
79
- });
80
- if (!cfg.apiKey) {
81
- process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
82
- process.exit(3);
83
- }
84
- const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
85
- const out = buildOutputStreams();
86
- await runCompanyGet(client, { ...flags, account: flags.account ?? cfg.account }, out);
87
- }
88
- });
89
- export {
90
- companyCommand,
91
- runCompanyGet
92
- };