@curviate/cli 0.14.0 → 0.15.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.
@@ -7,17 +7,18 @@ import {
7
7
  } from "./chunk-42VUUKQ3.js";
8
8
  import {
9
9
  AttachError,
10
- readAttachment
11
- } from "./chunk-Q43HZUN3.js";
10
+ readAttachment,
11
+ toAttachmentPayload
12
+ } from "./chunk-BGZW6B7G.js";
12
13
  import {
13
14
  buildPreviewOutput
14
15
  } from "./chunk-R3VLWLVV.js";
15
- import {
16
- streamAll
17
- } from "./chunk-GXTZION6.js";
18
16
  import {
19
17
  resolveIdentifier
20
18
  } from "./chunk-DMQZEPQE.js";
19
+ import {
20
+ streamAll
21
+ } from "./chunk-DNTRQZBT.js";
21
22
  import {
22
23
  createClient,
23
24
  renderError,
@@ -66,28 +67,13 @@ function normalizeAttachPaths(attach) {
66
67
  async function handleSdkError(err, outOpts, out) {
67
68
  const { CurviateError } = await import("@curviate/sdk");
68
69
  if (err instanceof CurviateError) {
69
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
70
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
70
71
  renderError(err, outOpts, out);
71
72
  process.exit(getExitCode(err.code));
72
73
  }
73
74
  renderUnexpectedError(err, out);
74
75
  process.exit(1);
75
76
  }
76
- async function runSalesNavSync(client, flags, out) {
77
- rejectPreviewOnRead(flags.preview, out);
78
- const accountId = requireAccount(flags.account, out);
79
- const ns = client.account(accountId);
80
- const outOpts = resolveOutputOpts(flags);
81
- const params = {};
82
- if (flags.cursor) params["cursor"] = flags.cursor;
83
- if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
84
- try {
85
- const result = await ns.salesNavigator.syncMessages(params);
86
- renderSuccess(result, outOpts, out);
87
- } catch (err) {
88
- await handleSdkError(err, outOpts, out);
89
- }
90
- }
91
77
  async function runSalesNavSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READERS) {
92
78
  rejectPreviewOnRead(flags.preview, out);
93
79
  const accountId = requireAccount(flags.account, out);
@@ -125,8 +111,7 @@ async function runSalesNavSearchPeople(client, flags, out, readers = DEFAULT_FIL
125
111
  };
126
112
  for await (const item of streamAll(fn, params, {
127
113
  maxPages,
128
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
129
- `)
114
+ out
130
115
  })) {
131
116
  out.stdout.write(JSON.stringify(item) + "\n");
132
117
  }
@@ -174,8 +159,7 @@ async function runSalesNavSearchCompanies(client, flags, out, readers = DEFAULT_
174
159
  };
175
160
  for await (const item of streamAll(fn, params, {
176
161
  maxPages,
177
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
178
- `)
162
+ out
179
163
  })) {
180
164
  out.stdout.write(JSON.stringify(item) + "\n");
181
165
  }
@@ -189,13 +173,16 @@ async function runSalesNavSearchCompanies(client, flags, out, readers = DEFAULT_
189
173
  }
190
174
  async function runSalesNavGetParameters(client, flags, out) {
191
175
  rejectPreviewOnRead(flags.preview, out);
176
+ if (!flags.type) {
177
+ out.stderr.write("error: --type is required.\n");
178
+ process.exit(2);
179
+ }
192
180
  const accountId = requireAccount(flags.account, out);
193
181
  const ns = client.account(accountId);
194
182
  const outOpts = resolveOutputOpts(flags);
195
- const params = {};
196
- if (flags.type) params["type"] = flags.type;
197
- if (flags.keywords) params["keywords"] = flags.keywords;
198
- if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
183
+ const params = { type: flags.type };
184
+ if (flags.keywords) params.keywords = flags.keywords;
185
+ if (flags.limit) params.limit = parseInt(flags.limit, 10);
199
186
  try {
200
187
  const result = await ns.salesNavigator.getParameters(params);
201
188
  renderSuccess(result, outOpts, out);
@@ -203,13 +190,56 @@ async function runSalesNavGetParameters(client, flags, out) {
203
190
  await handleSdkError(err, outOpts, out);
204
191
  }
205
192
  }
193
+ async function runSalesNavSearchFromUrl(client, flags, out) {
194
+ rejectPreviewOnRead(flags.preview, out);
195
+ const accountId = requireAccount(flags.account, out);
196
+ const url = flags.url ?? "";
197
+ const ns = client.account(accountId);
198
+ const outOpts = resolveOutputOpts(flags);
199
+ const all = flags.all ?? false;
200
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
201
+ const limit = flags.limit ? parseInt(flags.limit, 10) : void 0;
202
+ const cursor = flags.cursor;
203
+ const body = { url };
204
+ const params = {};
205
+ if (limit !== void 0) params["limit"] = limit;
206
+ if (cursor) params["cursor"] = cursor;
207
+ try {
208
+ if (all) {
209
+ const fn = (p) => {
210
+ const { cursor: c, limit: l, ...restP } = p;
211
+ const callParams = {};
212
+ if (c) callParams["cursor"] = c;
213
+ if (l) callParams["limit"] = l;
214
+ void restP;
215
+ return ns.salesNavigator.searchFromUrl(body, callParams);
216
+ };
217
+ for await (const item of streamAll(fn, params, {
218
+ maxPages,
219
+ out
220
+ })) {
221
+ out.stdout.write(JSON.stringify(item) + "\n");
222
+ }
223
+ } else {
224
+ const result = await ns.salesNavigator.searchFromUrl(body, Object.keys(params).length > 0 ? params : void 0);
225
+ renderSuccess(result, outOpts, out);
226
+ }
227
+ } catch (err) {
228
+ await handleSdkError(err, outOpts, out);
229
+ }
230
+ }
206
231
  async function runSalesNavMessageNew(client, flags, out) {
207
232
  const accountId = requireAccount(flags.account, out);
208
233
  const to = flags.to ?? "";
209
234
  const text = flags.text ?? "";
235
+ const subject = flags.subject ?? "";
210
236
  const attachPaths = normalizeAttachPaths(flags.attach);
211
237
  const voicePath = flags.voice;
212
238
  const videoPath = flags.video;
239
+ if (!subject) {
240
+ out.stderr.write("error: --subject is required (v2: REQUIRED for Sales Navigator messaging).\n");
241
+ process.exit(2);
242
+ }
213
243
  let attachBuffers = [];
214
244
  let voiceBuffer;
215
245
  let videoBuffer;
@@ -225,15 +255,11 @@ async function runSalesNavMessageNew(client, flags, out) {
225
255
  }
226
256
  throw err;
227
257
  }
228
- const body = {
229
- attendees_ids: [to],
230
- text
231
- };
232
258
  if (flags.preview) {
233
259
  const preview = buildPreviewOutput({
234
260
  method: "salesNavigator.startChat",
235
261
  args: { attendees_ids: [to] },
236
- body: { ...body },
262
+ body: { attendees_ids: [to], text, subject },
237
263
  account: accountId,
238
264
  attachments: [
239
265
  ...attachBuffers.map((buf, i) => ({
@@ -247,9 +273,17 @@ async function runSalesNavMessageNew(client, flags, out) {
247
273
  out.stdout.write(JSON.stringify(preview) + "\n");
248
274
  return;
249
275
  }
250
- if (attachBuffers.length > 0) body["attachments"] = attachBuffers;
251
- if (voiceBuffer) body["voice_message"] = voiceBuffer;
252
- if (videoBuffer) body["video_message"] = videoBuffer;
276
+ const attachments = [
277
+ ...attachPaths.map((p, i) => toAttachmentPayload(p, attachBuffers[i])),
278
+ ...voiceBuffer && voicePath ? [{ ...toAttachmentPayload(voicePath, voiceBuffer), send_mode: "native" }] : [],
279
+ ...videoBuffer && videoPath ? [{ ...toAttachmentPayload(videoPath, videoBuffer), send_mode: "native" }] : []
280
+ ];
281
+ const body = {
282
+ attendees_ids: [to],
283
+ text,
284
+ subject,
285
+ ...attachments.length > 0 ? { attachments } : {}
286
+ };
253
287
  const ns = client.account(accountId);
254
288
  const outOpts = resolveOutputOpts(flags);
255
289
  try {
@@ -312,8 +346,7 @@ async function runSalesNavAccountLists(client, flags, out) {
312
346
  const fn = (p) => ns.salesNavigator.accountLists(p);
313
347
  for await (const item of streamAll(fn, params, {
314
348
  maxPages,
315
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
316
- `)
349
+ out
317
350
  })) {
318
351
  out.stdout.write(JSON.stringify(item) + "\n");
319
352
  }
@@ -340,8 +373,7 @@ async function runSalesNavLeadLists(client, flags, out) {
340
373
  const fn = (p) => ns.salesNavigator.leadLists(p);
341
374
  for await (const item of streamAll(fn, params, {
342
375
  maxPages,
343
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
344
- `)
376
+ out
345
377
  })) {
346
378
  out.stdout.write(JSON.stringify(item) + "\n");
347
379
  }
@@ -373,8 +405,7 @@ async function runSalesNavBrowseAccountList(client, flags, out) {
373
405
  const fn = (p) => ns.salesNavigator.browseAccountList(listId, body, p);
374
406
  for await (const item of streamAll(fn, params, {
375
407
  maxPages,
376
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
377
- `)
408
+ out
378
409
  })) {
379
410
  out.stdout.write(JSON.stringify(item) + "\n");
380
411
  }
@@ -406,8 +437,7 @@ async function runSalesNavBrowseLeadList(client, flags, out) {
406
437
  const fn = (p) => ns.salesNavigator.browseLeadList(listId, body, p);
407
438
  for await (const item of streamAll(fn, params, {
408
439
  maxPages,
409
- onTruncated: (n) => out.stderr.write(`Streaming truncated at ${n} page(s). Use --all --max-pages or --cursor for manual paging.
410
- `)
440
+ out
411
441
  })) {
412
442
  out.stdout.write(JSON.stringify(item) + "\n");
413
443
  }
@@ -443,27 +473,6 @@ async function runSalesNavSaveAccount(client, flags, out) {
443
473
  await handleSdkError(err, outOpts, out);
444
474
  }
445
475
  }
446
- var salesNavSyncCommand = defineCommand({
447
- meta: { name: "sync", description: "Sync Sales Navigator message history for an account." },
448
- args: { ...GLOBAL_FLAGS },
449
- async run({ args }) {
450
- const flags = args;
451
- const cfg = await resolveEffectiveConfig({
452
- apiKey: flags["api-key"],
453
- baseUrl: flags["base-url"],
454
- timeout: flags.timeout,
455
- account: flags.account,
456
- profile: flags.profile
457
- });
458
- if (!cfg.apiKey) {
459
- process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
460
- process.exit(3);
461
- }
462
- const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
463
- const out = buildOutputStreams();
464
- await runSalesNavSync(client, { ...flags, account: flags.account ?? cfg.account }, out);
465
- }
466
- });
467
476
  var salesNavMessageNewCommand = defineCommand({
468
477
  meta: { name: "new", description: "Start a new Sales Navigator chat." },
469
478
  args: {
@@ -474,6 +483,7 @@ var salesNavMessageNewCommand = defineCommand({
474
483
  description: "Recipient's LinkedIn provider ID (ACw\u2026 format, e.g. from a Sales Navigator search result or profile). Not resolved from a URL/slug \u2014 pass the provider ID directly.",
475
484
  required: true
476
485
  },
486
+ subject: { type: "string", description: "Message subject line (required for Sales Navigator messaging).", required: true },
477
487
  text: { type: "positional", description: "Opening message text." },
478
488
  attach: { type: "string", description: "File to attach (repeatable, max 7 MiB each)." },
479
489
  voice: { type: "string", description: "Voice message file (max 7 MiB)." },
@@ -596,17 +606,42 @@ var salesNavSearchParametersCommand = defineCommand({
596
606
  }
597
607
  });
598
608
  var salesNavSearchCommand = defineCommand({
599
- meta: { name: "search", description: "Sales Navigator search operations." },
600
- args: { ...GLOBAL_FLAGS },
609
+ meta: { name: "search", description: "Sales Navigator search operations. Also runs a pasted Sales Navigator search/list URL directly." },
610
+ args: {
611
+ ...GLOBAL_FLAGS,
612
+ url: {
613
+ type: "positional",
614
+ required: false,
615
+ description: "A pasted Sales Navigator search or list URL. Runs it directly (salesNavigator.searchFromUrl)."
616
+ }
617
+ },
601
618
  subCommands: {
602
619
  people: salesNavSearchPeopleCommand,
603
620
  companies: salesNavSearchCompaniesCommand,
604
621
  parameters: salesNavSearchParametersCommand
605
622
  },
606
- async run() {
607
- process.stderr.write(
608
- "Usage: curviate sales-nav search people [--keywords <k>]\n curviate sales-nav search companies [--keywords <k>]\n curviate sales-nav search parameters --type <t>\n"
609
- );
623
+ async run({ args }) {
624
+ const flags = args;
625
+ if (!flags.url) {
626
+ process.stderr.write(
627
+ "Usage: curviate sales-nav search <url>\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"
628
+ );
629
+ return;
630
+ }
631
+ const cfg = await resolveEffectiveConfig({
632
+ apiKey: flags["api-key"],
633
+ baseUrl: flags["base-url"],
634
+ timeout: flags.timeout,
635
+ account: flags.account,
636
+ profile: flags.profile
637
+ });
638
+ if (!cfg.apiKey) {
639
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
640
+ process.exit(3);
641
+ }
642
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
643
+ const out = buildOutputStreams();
644
+ await runSalesNavSearchFromUrl(client, { ...flags, account: flags.account ?? cfg.account }, out);
610
645
  }
611
646
  });
612
647
  var salesNavProfileCommand = defineCommand({
@@ -786,7 +821,6 @@ var salesNavCommand = defineCommand({
786
821
  meta: { name: "sales-nav", description: "Sales Navigator operations (requires the Sales Navigator add-on)." },
787
822
  args: { ...GLOBAL_FLAGS },
788
823
  subCommands: {
789
- sync: salesNavSyncCommand,
790
824
  message: salesNavMessageCommand,
791
825
  search: salesNavSearchCommand,
792
826
  profile: salesNavProfileCommand,
@@ -799,7 +833,7 @@ var salesNavCommand = defineCommand({
799
833
  },
800
834
  async run() {
801
835
  process.stderr.write(
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'
836
+ 'Usage: 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 search <url>\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'
803
837
  );
804
838
  }
805
839
  });
@@ -814,7 +848,7 @@ export {
814
848
  runSalesNavSaveAccount,
815
849
  runSalesNavSaveLead,
816
850
  runSalesNavSearchCompanies,
851
+ runSalesNavSearchFromUrl,
817
852
  runSalesNavSearchPeople,
818
- runSalesNavSync,
819
853
  salesNavCommand
820
854
  };
@@ -5,9 +5,6 @@ import {
5
5
  splitCsv,
6
6
  splitCsvNumbers
7
7
  } from "./chunk-42VUUKQ3.js";
8
- import {
9
- streamAll
10
- } from "./chunk-GXTZION6.js";
11
8
  import {
12
9
  slimSearchCompanies,
13
10
  slimSearchCompaniesItem,
@@ -17,7 +14,10 @@ import {
17
14
  slimSearchPeopleItem,
18
15
  slimSearchPosts,
19
16
  slimSearchPostsItem
20
- } from "./chunk-SSPILTKF.js";
17
+ } from "./chunk-45KHSWCV.js";
18
+ import {
19
+ streamAll
20
+ } from "./chunk-DNTRQZBT.js";
21
21
  import {
22
22
  createClient,
23
23
  renderError,
@@ -86,7 +86,6 @@ function resolveOutputOpts(flags) {
86
86
  }
87
87
  function applyCommonSearchFlags(body, flags) {
88
88
  if (flags.keywords) body["keywords"] = flags.keywords;
89
- if (flags.url) body["url"] = flags.url;
90
89
  if (flags.cursor) body["cursor"] = flags.cursor;
91
90
  if (flags.limit) body["limit"] = parseInt(flags.limit, 10);
92
91
  }
@@ -207,10 +206,7 @@ async function runSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READ
207
206
  const fn = (p) => ns.search.people(p);
208
207
  for await (const item of streamAll(fn, body, {
209
208
  maxPages,
210
- // Write JSON truncation sentinel to stdout as the last NDJSON line
211
- onTruncated: (pagesFetched, hasMore) => out.stdout.write(
212
- JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
213
- )
209
+ out
214
210
  })) {
215
211
  const projected = verbose ? item : slimSearchPeopleItem(item);
216
212
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -222,7 +218,7 @@ async function runSearchPeople(client, flags, out, readers = DEFAULT_FILTER_READ
222
218
  } catch (err) {
223
219
  const { CurviateError } = await import("@curviate/sdk");
224
220
  if (err instanceof CurviateError) {
225
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
221
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
226
222
  renderError(err, outOpts, out);
227
223
  process.exit(getExitCode(err.code));
228
224
  }
@@ -250,9 +246,7 @@ async function runSearchCompanies(client, flags, out, readers = DEFAULT_FILTER_R
250
246
  const fn = (p) => ns.search.companies(p);
251
247
  for await (const item of streamAll(fn, body, {
252
248
  maxPages,
253
- onTruncated: (pagesFetched, hasMore) => out.stdout.write(
254
- JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
255
- )
249
+ out
256
250
  })) {
257
251
  const projected = verbose ? item : slimSearchCompaniesItem(item);
258
252
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -264,7 +258,7 @@ async function runSearchCompanies(client, flags, out, readers = DEFAULT_FILTER_R
264
258
  } catch (err) {
265
259
  const { CurviateError } = await import("@curviate/sdk");
266
260
  if (err instanceof CurviateError) {
267
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
261
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
268
262
  renderError(err, outOpts, out);
269
263
  process.exit(getExitCode(err.code));
270
264
  }
@@ -292,9 +286,7 @@ async function runSearchPosts(client, flags, out, readers = DEFAULT_FILTER_READE
292
286
  const fn = (p) => ns.search.posts(p);
293
287
  for await (const item of streamAll(fn, body, {
294
288
  maxPages,
295
- onTruncated: (pagesFetched, hasMore) => out.stdout.write(
296
- JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
297
- )
289
+ out
298
290
  })) {
299
291
  const projected = verbose ? item : slimSearchPostsItem(item);
300
292
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -306,7 +298,7 @@ async function runSearchPosts(client, flags, out, readers = DEFAULT_FILTER_READE
306
298
  } catch (err) {
307
299
  const { CurviateError } = await import("@curviate/sdk");
308
300
  if (err instanceof CurviateError) {
309
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
301
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
310
302
  renderError(err, outOpts, out);
311
303
  process.exit(getExitCode(err.code));
312
304
  }
@@ -334,9 +326,7 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
334
326
  const fn = (p) => ns.search.jobs(p);
335
327
  for await (const item of streamAll(fn, body, {
336
328
  maxPages,
337
- onTruncated: (pagesFetched, hasMore) => out.stdout.write(
338
- JSON.stringify({ object: "stream_truncated", pages_fetched: pagesFetched, has_more: hasMore }) + "\n"
339
- )
329
+ out
340
330
  })) {
341
331
  const projected = verbose ? item : slimSearchJobsItem(item);
342
332
  out.stdout.write(JSON.stringify(projected) + "\n");
@@ -348,7 +338,7 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
348
338
  } catch (err) {
349
339
  const { CurviateError } = await import("@curviate/sdk");
350
340
  if (err instanceof CurviateError) {
351
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
341
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
352
342
  renderError(err, outOpts, out);
353
343
  process.exit(getExitCode(err.code));
354
344
  }
@@ -359,20 +349,65 @@ async function runSearchJobs(client, flags, out, readers = DEFAULT_FILTER_READER
359
349
  async function runSearchParameters(client, flags, out) {
360
350
  rejectPreviewOnRead(flags.preview, out);
361
351
  rejectAllOnNonPaginated(flags.all, out);
352
+ if (!flags.type) {
353
+ out.stderr.write("error: --type is required.\n");
354
+ process.exit(2);
355
+ }
356
+ if (!flags.keywords) {
357
+ out.stderr.write("error: --keywords is required (v2: required for every --type).\n");
358
+ process.exit(2);
359
+ }
362
360
  const accountId = requireAccount(flags.account, out);
363
361
  const ns = client.account(accountId);
364
362
  const outOpts = resolveOutputOpts(flags);
365
- const query = {};
366
- if (flags.type) query["type"] = flags.type;
367
- if (flags.keywords) query["keywords"] = flags.keywords;
368
- if (flags.limit) query["limit"] = parseInt(flags.limit, 10);
363
+ const query = {
364
+ type: flags.type,
365
+ keywords: flags.keywords
366
+ };
367
+ if (flags.limit) query.limit = parseInt(flags.limit, 10);
369
368
  try {
370
369
  const result = await ns.search.getParameters(query);
371
370
  renderSuccess(result, outOpts, out);
372
371
  } catch (err) {
373
372
  const { CurviateError } = await import("@curviate/sdk");
374
373
  if (err instanceof CurviateError) {
375
- const { getExitCode } = await import("./exit-codes-ZTY2NY3X.js");
374
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
375
+ renderError(err, outOpts, out);
376
+ process.exit(getExitCode(err.code));
377
+ }
378
+ renderUnexpectedError(err, out);
379
+ process.exit(1);
380
+ }
381
+ }
382
+ async function runSearchFromUrl(client, flags, out) {
383
+ rejectPreviewOnRead(flags.preview, out);
384
+ const accountId = requireAccount(flags.account, out);
385
+ const url = flags.url ?? "";
386
+ const ns = client.account(accountId);
387
+ const outOpts = resolveOutputOpts(flags);
388
+ const verbose = flags.verbose ?? false;
389
+ const all = flags.all ?? false;
390
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
391
+ const body = { url };
392
+ if (flags.limit) body.limit = parseInt(flags.limit, 10);
393
+ if (flags.cursor) body.cursor = flags.cursor;
394
+ try {
395
+ if (all) {
396
+ const fn = (p) => ns.search.fromUrl(p);
397
+ for await (const item of streamAll(fn, body, {
398
+ maxPages,
399
+ out
400
+ })) {
401
+ out.stdout.write(JSON.stringify(item) + "\n");
402
+ }
403
+ } else {
404
+ const result = await ns.search.fromUrl(body);
405
+ renderSuccess(result, { ...outOpts, verbose }, out);
406
+ }
407
+ } catch (err) {
408
+ const { CurviateError } = await import("@curviate/sdk");
409
+ if (err instanceof CurviateError) {
410
+ const { getExitCode } = await import("./exit-codes-SL3GQF7W.js");
376
411
  renderError(err, outOpts, out);
377
412
  process.exit(getExitCode(err.code));
378
413
  }
@@ -385,7 +420,6 @@ var searchPeopleCommand = defineCommand({
385
420
  args: {
386
421
  ...GLOBAL_FLAGS,
387
422
  keywords: { type: "string", description: "Full-text keyword search." },
388
- url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
389
423
  ...FILTER_FLAGS,
390
424
  industry: { type: "string", description: "Industry ids (comma-separated)." },
391
425
  location: { type: "string", description: "Location ids (comma-separated)." },
@@ -422,7 +456,6 @@ var searchCompaniesCommand = defineCommand({
422
456
  args: {
423
457
  ...GLOBAL_FLAGS,
424
458
  keywords: { type: "string", description: "Full-text keyword search." },
425
- url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
426
459
  ...FILTER_FLAGS,
427
460
  industry: { type: "string", description: "Industry ids (comma-separated)." },
428
461
  location: { type: "string", description: "Location ids (comma-separated)." },
@@ -456,7 +489,6 @@ var searchPostsCommand = defineCommand({
456
489
  args: {
457
490
  ...GLOBAL_FLAGS,
458
491
  keywords: { type: "string", description: "Full-text keyword search." },
459
- url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
460
492
  ...FILTER_FLAGS,
461
493
  "sort-by": { type: "string", description: "Sort order (e.g. relevance, date)." },
462
494
  "date-posted": { type: "string", description: "time window: past_day, past_week, or past_month (hyphens also accepted: past-day, past-week, past-month)" },
@@ -493,7 +525,6 @@ var searchJobsCommand = defineCommand({
493
525
  args: {
494
526
  ...GLOBAL_FLAGS,
495
527
  keywords: { type: "string", description: "Full-text keyword search." },
496
- url: { type: "string", description: "Pasted LinkedIn search URL (mutually exclusive with filters)." },
497
528
  ...FILTER_FLAGS,
498
529
  // On jobs, --location maps to the geo region filter (not a location array — different API shape for jobs vs people)
499
530
  location: { type: "string", description: "geo region id (single id; resolve via search parameters --type LOCATION); maps to region filter" },
@@ -548,7 +579,7 @@ var searchParametersCommand = defineCommand({
548
579
  description: "Parameter type: LOCATION, PEOPLE, CONNECTIONS, COMPANY, SCHOOL, INDUSTRY, SERVICE, JOB_FUNCTION, JOB_TITLE, EMPLOYMENT_TYPE, SKILL.",
549
580
  required: true
550
581
  },
551
- keywords: { type: "string", description: "Human term to resolve (not required for EMPLOYMENT_TYPE)." }
582
+ keywords: { type: "string", description: "Human term to resolve (required for every --type, incl. EMPLOYMENT_TYPE).", required: true }
552
583
  },
553
584
  async run({ args }) {
554
585
  const flags = args;
@@ -569,7 +600,15 @@ var searchParametersCommand = defineCommand({
569
600
  }
570
601
  });
571
602
  var searchCommand = defineCommand({
572
- meta: { name: "search", description: "Search people, companies, posts, and jobs." },
603
+ meta: { name: "search", description: "Search people, companies, posts, and jobs. Also runs a pasted search URL directly." },
604
+ args: {
605
+ ...GLOBAL_FLAGS,
606
+ url: {
607
+ type: "positional",
608
+ required: false,
609
+ description: "A pasted LinkedIn search, saved-search re-run, or lead-list URL. Runs it directly (search.fromUrl)."
610
+ }
611
+ },
573
612
  subCommands: {
574
613
  people: searchPeopleCommand,
575
614
  companies: searchCompaniesCommand,
@@ -577,14 +616,33 @@ var searchCommand = defineCommand({
577
616
  jobs: searchJobsCommand,
578
617
  parameters: searchParametersCommand
579
618
  },
580
- async run() {
581
- process.stderr.write(
582
- "Usage: curviate search <subcommand>\n people [--url <u>] [--keywords <k>]\n companies [--keywords <k>]\n posts [--keywords <k>]\n jobs [--keywords <k>]\n parameters --type <t> [--keywords <k>]\n"
583
- );
619
+ async run({ args }) {
620
+ const flags = args;
621
+ if (!flags.url) {
622
+ process.stderr.write(
623
+ "Usage: curviate search <url>\n curviate search people [--keywords <k>]\n curviate search companies [--keywords <k>]\n curviate search posts [--keywords <k>]\n curviate search jobs [--keywords <k>]\n curviate search parameters --type <t> --keywords <k>\n"
624
+ );
625
+ process.exit(2);
626
+ }
627
+ const cfg = await resolveEffectiveConfig({
628
+ apiKey: flags["api-key"],
629
+ baseUrl: flags["base-url"],
630
+ timeout: flags.timeout,
631
+ account: flags.account,
632
+ profile: flags.profile
633
+ });
634
+ if (!cfg.apiKey) {
635
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
636
+ process.exit(3);
637
+ }
638
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
639
+ const out = buildOutputStreams();
640
+ await runSearchFromUrl(client, { ...flags, account: flags.account ?? cfg.account }, out);
584
641
  }
585
642
  });
586
643
  export {
587
644
  runSearchCompanies,
645
+ runSearchFromUrl,
588
646
  runSearchJobs,
589
647
  runSearchParameters,
590
648
  runSearchPeople,