@curviate/cli 0.18.0 → 0.19.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
@@ -8,6 +8,47 @@ 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.19.0] - 2026-07-29
12
+
13
+ A minor release closing the remaining SDK-parity gap: 25 new commands across seven
14
+ existing command groups plus three brand-new command groups. No breaking changes,
15
+ built against `@curviate/sdk` 0.18.1 (unchanged; every new command was already
16
+ covered by the published SDK, so no SDK bump was required).
17
+
18
+ ### Added
19
+
20
+ - **`inbox search`** — search chats via `messaging.searchChats`.
21
+ - **`search groups`, `search services`, `search service-parameters`** — new search
22
+ surfaces for groups, services, and service search parameters.
23
+ - **`post saved`, `post save`, `post unsave`** — list, save, and unsave posts.
24
+ - **`company managed`, `company followers`, `company chats`, `company chat`,
25
+ `company messages`, `company message`, `company search-chats`** — company-inbox
26
+ and managed-company read/write surface.
27
+ - **`profile subscription`, `profile analytics`, `profile visitors`, `profile ssi`**
28
+ — account-scoped profile insight subcommands (subscription status, post/profile
29
+ analytics, visitor list, Social Selling Index).
30
+ - **`group` command group** — new top-level group closing the LinkedIn Groups gap.
31
+ - **`feed`, `feed home`** — new command group to read the connected account's
32
+ LinkedIn home feed as agent-actionable posts.
33
+ - **`notification`, `notification list`, `notification delete`,
34
+ `notification show-less`** — new command group to read and act on LinkedIn
35
+ notification cards.
36
+
37
+ Parity with the SDK surface is now 145/0 (no known gaps).
38
+
39
+ ## [0.18.1] - 2026-07-18
40
+
41
+ A patch aligning `company reply` with the company-inbox chat-id cutover. No breaking changes, built against `@curviate/sdk` 0.18.1.
42
+
43
+ ### Fixed
44
+
45
+ - **`company reply <id> <chat_id> "<text>"`** now takes the normal `2-…` conversation
46
+ id that `company chats` returns; the endpoint resolves the page mailbox internally from
47
+ the company identifier, so the earlier `COMPANY_` chat-id requirement is gone. `--preview`
48
+ now always prints a "Will send as company page `<id>`" notice derived from the resolved
49
+ identifier (previously it went silent for a bare `2-…` id). Reply-only and admin-gated,
50
+ otherwise unchanged.
51
+
11
52
  ## [0.18.0] - 2026-07-17
12
53
 
13
54
  A minor release adding the `company reply` command. No breaking changes, built against `@curviate/sdk` 0.18.0.
package/dist/cli.js CHANGED
@@ -42,9 +42,6 @@ var REMOVED_COMMANDS = {
42
42
  },
43
43
  webhook: {
44
44
  "state-diff": "`webhook state-diff` was removed with no replacement."
45
- },
46
- company: {
47
- followers: "`company followers` was removed with no replacement."
48
45
  }
49
46
  };
50
47
  function successorHint(group, token) {
@@ -255,20 +252,23 @@ var main = defineCommand({
255
252
  // ---------------------------------------------------------------------------
256
253
  // Noun groups — lazy-loaded on first invocation.
257
254
  // ---------------------------------------------------------------------------
258
- profile: () => import("./profile-XWSRUYRW.js").then((m) => m.profileCommand),
259
- company: () => import("./company-BC72KZ5G.js").then((m) => m.companyCommand),
255
+ profile: () => import("./profile-PES67647.js").then((m) => m.profileCommand),
256
+ company: () => import("./company-XEEBBCRZ.js").then((m) => m.companyCommand),
260
257
  job: () => import("./job-EIXBJXLW.js").then((m) => m.jobCommand),
261
258
  connect: () => import("./connect-6PU7QCOL.js").then((m) => m.connectCommand),
262
- search: () => import("./search-ZQUKLQ6T.js").then((m) => m.searchCommand),
263
- inbox: () => import("./inbox-DRJ6ENXC.js").then((m) => m.inboxCommand),
259
+ search: () => import("./search-O2LACGHE.js").then((m) => m.searchCommand),
260
+ inbox: () => import("./inbox-BXCWHGWP.js").then((m) => m.inboxCommand),
264
261
  inboxes: () => import("./inboxes-MTPWLP5F.js").then((m) => m.inboxesCommand),
265
262
  message: () => import("./message-UWMRE2SJ.js").then((m) => m.messageCommand),
266
- post: () => import("./post-N3GQDIQJ.js").then((m) => m.postCommand),
263
+ post: () => import("./post-HK6HHIKV.js").then((m) => m.postCommand),
267
264
  comment: () => import("./comment-VT6PO4MN.js").then((m) => m.commentCommand),
268
265
  account: () => import("./account-EGJJNBXW.js").then((m) => m.accountCommand),
269
266
  webhook: () => import("./webhook-QFSZN3P2.js").then((m) => m.webhookCommand),
270
267
  "sales-nav": () => import("./sales-nav-TMXWDKSE.js").then((m) => m.salesNavCommand),
271
- recruiter: () => import("./recruiter-MVPSTH2V.js").then((m) => m.recruiterCommand)
268
+ recruiter: () => import("./recruiter-MVPSTH2V.js").then((m) => m.recruiterCommand),
269
+ group: () => import("./group-LPVVJ2JX.js").then((m) => m.groupCommand),
270
+ feed: () => import("./feed-KAUDRE5K.js").then((m) => m.feedCommand),
271
+ notification: () => import("./notification-RYFDHM3G.js").then((m) => m.notificationCommand)
272
272
  },
273
273
  async run() {
274
274
  const { runMain } = await import("citty");
@@ -1,7 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- sentAsNotice,
4
- willSendAsNotice
3
+ sentAsNotice
5
4
  } from "./chunk-KVV6LZ7E.js";
6
5
  import {
7
6
  resolveTextOrStdin
@@ -262,6 +261,186 @@ async function runCompanyFollowInvite(client, flags, out) {
262
261
  await handleSdkError(err, outOpts, out);
263
262
  }
264
263
  }
264
+ async function runCompanyManaged(client, flags, out) {
265
+ rejectPreviewOnRead(flags.preview, out);
266
+ const accountId = requireAccount(flags.account, out);
267
+ const ns = client.account(accountId);
268
+ const outOpts = resolveOutputOpts(flags);
269
+ const params = {};
270
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
271
+ if (flags.cursor) params["cursor"] = flags.cursor;
272
+ try {
273
+ if (flags.all) {
274
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
275
+ const fn = (p) => ns.companies.managed(p);
276
+ for await (const item of streamAll(fn, params, {
277
+ maxPages,
278
+ out,
279
+ pageDelayMs: pageDelayFromFlags(flags)
280
+ })) {
281
+ out.stdout.write(JSON.stringify(item) + "\n");
282
+ }
283
+ return;
284
+ }
285
+ const result = await ns.companies.managed(params);
286
+ renderSuccess(result, outOpts, out);
287
+ } catch (err) {
288
+ await handleSdkError(err, outOpts, out);
289
+ }
290
+ }
291
+ async function runCompanyFollowers(client, flags, out) {
292
+ rejectPreviewOnRead(flags.preview, out);
293
+ const accountId = requireAccount(flags.account, out);
294
+ const ns = client.account(accountId);
295
+ const outOpts = resolveOutputOpts(flags);
296
+ const params = {};
297
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
298
+ if (flags.cursor) params["cursor"] = flags.cursor;
299
+ try {
300
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
301
+ if (flags.all) {
302
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
303
+ const fn = (p) => ns.companies.followers(identifier, p);
304
+ for await (const item of streamAll(fn, params, {
305
+ maxPages,
306
+ out,
307
+ pageDelayMs: pageDelayFromFlags(flags)
308
+ })) {
309
+ out.stdout.write(JSON.stringify(item) + "\n");
310
+ }
311
+ return;
312
+ }
313
+ const result = await ns.companies.followers(identifier, params);
314
+ renderSuccess(result, outOpts, out);
315
+ } catch (err) {
316
+ await handleSdkError(err, outOpts, out);
317
+ }
318
+ }
319
+ async function runCompanyChats(client, flags, out) {
320
+ rejectPreviewOnRead(flags.preview, out);
321
+ const accountId = requireAccount(flags.account, out);
322
+ const ns = client.account(accountId);
323
+ const outOpts = resolveOutputOpts(flags);
324
+ const params = {};
325
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
326
+ if (flags.cursor) params["cursor"] = flags.cursor;
327
+ try {
328
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
329
+ if (flags.all) {
330
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
331
+ const fn = (p) => ns.companies.chats(identifier, p);
332
+ for await (const item of streamAll(fn, params, {
333
+ maxPages,
334
+ out,
335
+ pageDelayMs: pageDelayFromFlags(flags)
336
+ })) {
337
+ out.stdout.write(JSON.stringify(item) + "\n");
338
+ }
339
+ return;
340
+ }
341
+ const result = await ns.companies.chats(identifier, params);
342
+ renderSuccess(result, outOpts, out);
343
+ } catch (err) {
344
+ await handleSdkError(err, outOpts, out);
345
+ }
346
+ }
347
+ async function runCompanyChat(client, flags, out) {
348
+ rejectPreviewOnRead(flags.preview, out);
349
+ if (flags.all) {
350
+ out.stderr.write("error: --all is not supported on non-paginated commands.\n");
351
+ process.exit(2);
352
+ }
353
+ const accountId = requireAccount(flags.account, out);
354
+ const ns = client.account(accountId);
355
+ const outOpts = resolveOutputOpts(flags);
356
+ const chatId = flags.chatId ?? "";
357
+ try {
358
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
359
+ const result = await ns.companies.chat(identifier, chatId);
360
+ renderSuccess(result, outOpts, out);
361
+ } catch (err) {
362
+ await handleSdkError(err, outOpts, out);
363
+ }
364
+ }
365
+ async function runCompanyMessages(client, flags, out) {
366
+ rejectPreviewOnRead(flags.preview, out);
367
+ const accountId = requireAccount(flags.account, out);
368
+ const ns = client.account(accountId);
369
+ const outOpts = resolveOutputOpts(flags);
370
+ const chatId = flags.chatId ?? "";
371
+ const params = {};
372
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
373
+ if (flags.cursor) params["cursor"] = flags.cursor;
374
+ try {
375
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
376
+ if (flags.all) {
377
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
378
+ const fn = (p) => ns.companies.messages(identifier, chatId, p);
379
+ for await (const item of streamAll(fn, params, {
380
+ maxPages,
381
+ out,
382
+ pageDelayMs: pageDelayFromFlags(flags)
383
+ })) {
384
+ out.stdout.write(JSON.stringify(item) + "\n");
385
+ }
386
+ return;
387
+ }
388
+ const result = await ns.companies.messages(identifier, chatId, params);
389
+ renderSuccess(result, outOpts, out);
390
+ } catch (err) {
391
+ await handleSdkError(err, outOpts, out);
392
+ }
393
+ }
394
+ async function runCompanyMessage(client, flags, out) {
395
+ rejectPreviewOnRead(flags.preview, out);
396
+ if (flags.all) {
397
+ out.stderr.write("error: --all is not supported on non-paginated commands.\n");
398
+ process.exit(2);
399
+ }
400
+ const accountId = requireAccount(flags.account, out);
401
+ const ns = client.account(accountId);
402
+ const outOpts = resolveOutputOpts(flags);
403
+ const chatId = flags.chatId ?? "";
404
+ const messageId = flags.messageId ?? "";
405
+ try {
406
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
407
+ const result = await ns.companies.message(identifier, chatId, messageId);
408
+ renderSuccess(result, outOpts, out);
409
+ } catch (err) {
410
+ await handleSdkError(err, outOpts, out);
411
+ }
412
+ }
413
+ async function runCompanySearchChats(client, flags, out) {
414
+ rejectPreviewOnRead(flags.preview, out);
415
+ const accountId = requireAccount(flags.account, out);
416
+ const ns = client.account(accountId);
417
+ const outOpts = resolveOutputOpts(flags);
418
+ const params = {};
419
+ if (flags.query) params["query"] = flags.query;
420
+ if (flags.topic) params["topic"] = flags.topic;
421
+ if (flags.unread !== void 0) params["unread"] = flags.unread;
422
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
423
+ if (flags.cursor) params["cursor"] = flags.cursor;
424
+ try {
425
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
426
+ if (flags.all) {
427
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
428
+ const fn = (p) => ns.companies.searchChats(identifier, p);
429
+ for await (const item of streamAll(fn, params, {
430
+ maxPages,
431
+ out,
432
+ pageDelayMs: pageDelayFromFlags(flags)
433
+ })) {
434
+ out.stdout.write(JSON.stringify(item) + "\n");
435
+ }
436
+ return;
437
+ }
438
+ const result = await ns.companies.searchChats(identifier, params);
439
+ renderSuccess(result, outOpts, out);
440
+ } catch (err) {
441
+ await handleSdkError(err, outOpts, out);
442
+ }
443
+ }
265
444
  async function runCompanyReply(client, flags, out, _readStdin) {
266
445
  const accountId = requireAccount(flags.account, out);
267
446
  const ns = client.account(accountId);
@@ -295,8 +474,8 @@ async function runCompanyReply(client, flags, out, _readStdin) {
295
474
  }))
296
475
  });
297
476
  out.stdout.write(JSON.stringify(preview) + "\n");
298
- const willSendAs = willSendAsNotice(chatId);
299
- if (willSendAs) out.stderr.write(willSendAs);
477
+ out.stderr.write(`Will send as company page ${identifier}
478
+ `);
300
479
  return;
301
480
  }
302
481
  const attachmentPayloads = attachBuffers.map((buf, i) => toAttachmentPayload(attachPaths[i], buf));
@@ -316,7 +495,7 @@ var companyEmployeesCommand = defineCommand({
316
495
  meta: { name: "employees", description: "List people who currently work at the company." },
317
496
  args: {
318
497
  ...GLOBAL_FLAGS,
319
- id: { type: "positional", description: "Company identifier (URL, slug, or numeric id) \u2014 a slug/URL is resolved to the numeric id first." },
498
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
320
499
  keywords: { type: "string", description: "Free-text keyword filter across employee profile fields." },
321
500
  location: { type: "string", description: "Opaque location id from `search parameters --type LOCATION`." }
322
501
  },
@@ -342,7 +521,7 @@ var companyPostsCommand = defineCommand({
342
521
  meta: { name: "posts", description: "List the company's posts." },
343
522
  args: {
344
523
  ...GLOBAL_FLAGS,
345
- id: { type: "positional", description: "Company identifier (URL, slug, or numeric id) \u2014 a slug/URL is resolved to the numeric id first." }
524
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." }
346
525
  },
347
526
  async run({ args }) {
348
527
  const flags = args;
@@ -366,7 +545,7 @@ var companyJobsCommand = defineCommand({
366
545
  meta: { name: "jobs", description: "List the company's open job postings." },
367
546
  args: {
368
547
  ...GLOBAL_FLAGS,
369
- id: { type: "positional", description: "Company identifier (URL, slug, or numeric id) \u2014 a slug/URL is resolved to the numeric id first." },
548
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
370
549
  keywords: { type: "string", description: "Free-text keyword filter across job postings." }
371
550
  },
372
551
  async run({ args }) {
@@ -445,17 +624,204 @@ var companyFollowInviteCommand = defineCommand({
445
624
  await runCompanyFollowInvite(client, { ...flags, account: flags.account ?? cfg.account }, out);
446
625
  }
447
626
  });
627
+ var companyManagedCommand = defineCommand({
628
+ meta: { name: "managed", description: "List the company pages the connected account administers. An empty result is valid, the account administers no pages." },
629
+ args: { ...GLOBAL_FLAGS },
630
+ async run({ args }) {
631
+ const flags = args;
632
+ const cfg = await resolveEffectiveConfig({
633
+ apiKey: flags["api-key"],
634
+ baseUrl: flags["base-url"],
635
+ timeout: flags.timeout,
636
+ account: flags.account,
637
+ profile: flags.profile
638
+ });
639
+ if (!cfg.apiKey) {
640
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
641
+ process.exit(3);
642
+ }
643
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
644
+ const out = buildOutputStreams();
645
+ await runCompanyManaged(client, { ...flags, account: flags.account ?? cfg.account }, out);
646
+ }
647
+ });
648
+ var companyFollowersCommand = defineCommand({
649
+ meta: { name: "followers", description: "List a company page's followers, newest first. Admin-gated: the account must administer the page (see `company managed`)." },
650
+ args: {
651
+ ...GLOBAL_FLAGS,
652
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." }
653
+ },
654
+ async run({ args }) {
655
+ const flags = args;
656
+ const cfg = await resolveEffectiveConfig({
657
+ apiKey: flags["api-key"],
658
+ baseUrl: flags["base-url"],
659
+ timeout: flags.timeout,
660
+ account: flags.account,
661
+ profile: flags.profile
662
+ });
663
+ if (!cfg.apiKey) {
664
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
665
+ process.exit(3);
666
+ }
667
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
668
+ const out = buildOutputStreams();
669
+ await runCompanyFollowers(client, { ...flags, account: flags.account ?? cfg.account }, out);
670
+ }
671
+ });
672
+ var companyChatsCommand = defineCommand({
673
+ meta: {
674
+ name: "chats",
675
+ description: "List the conversations in a company page's admin message inbox, newest-activity-first. Admin-gated. Beta."
676
+ },
677
+ args: {
678
+ ...GLOBAL_FLAGS,
679
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." }
680
+ },
681
+ async run({ args }) {
682
+ const flags = args;
683
+ const cfg = await resolveEffectiveConfig({
684
+ apiKey: flags["api-key"],
685
+ baseUrl: flags["base-url"],
686
+ timeout: flags.timeout,
687
+ account: flags.account,
688
+ profile: flags.profile
689
+ });
690
+ if (!cfg.apiKey) {
691
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
692
+ process.exit(3);
693
+ }
694
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
695
+ const out = buildOutputStreams();
696
+ await runCompanyChats(client, { ...flags, account: flags.account ?? cfg.account }, out);
697
+ }
698
+ });
699
+ var companyChatCommand = defineCommand({
700
+ meta: {
701
+ name: "chat",
702
+ description: "Retrieve one conversation from a company page's admin inbox. Admin-gated. Beta."
703
+ },
704
+ args: {
705
+ ...GLOBAL_FLAGS,
706
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
707
+ chatId: { type: "positional", description: "The 2-\u2026 chat id from `company chats`, passed through verbatim." }
708
+ },
709
+ async run({ args }) {
710
+ const flags = args;
711
+ const cfg = await resolveEffectiveConfig({
712
+ apiKey: flags["api-key"],
713
+ baseUrl: flags["base-url"],
714
+ timeout: flags.timeout,
715
+ account: flags.account,
716
+ profile: flags.profile
717
+ });
718
+ if (!cfg.apiKey) {
719
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
720
+ process.exit(3);
721
+ }
722
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
723
+ const out = buildOutputStreams();
724
+ await runCompanyChat(client, { ...flags, account: flags.account ?? cfg.account }, out);
725
+ }
726
+ });
727
+ var companyMessagesCommand = defineCommand({
728
+ meta: {
729
+ name: "messages",
730
+ description: "List a company-inbox conversation's messages, newest first. Admin-gated."
731
+ },
732
+ args: {
733
+ ...GLOBAL_FLAGS,
734
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
735
+ chatId: { type: "positional", description: "The 2-\u2026 chat id from `company chats`, passed through verbatim." }
736
+ },
737
+ async run({ args }) {
738
+ const flags = args;
739
+ const cfg = await resolveEffectiveConfig({
740
+ apiKey: flags["api-key"],
741
+ baseUrl: flags["base-url"],
742
+ timeout: flags.timeout,
743
+ account: flags.account,
744
+ profile: flags.profile
745
+ });
746
+ if (!cfg.apiKey) {
747
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
748
+ process.exit(3);
749
+ }
750
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
751
+ const out = buildOutputStreams();
752
+ await runCompanyMessages(client, { ...flags, account: flags.account ?? cfg.account }, out);
753
+ }
754
+ });
755
+ var companyMessageCommand = defineCommand({
756
+ meta: {
757
+ name: "message",
758
+ description: "Retrieve one message from a company-inbox conversation. Admin-gated. See also: `company reply` (send)."
759
+ },
760
+ args: {
761
+ ...GLOBAL_FLAGS,
762
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
763
+ chatId: { type: "positional", description: "The 2-\u2026 chat id from `company chats`, passed through verbatim." },
764
+ messageId: { type: "positional", description: "The message id from `company messages`, passed through verbatim." }
765
+ },
766
+ async run({ args }) {
767
+ const flags = args;
768
+ const cfg = await resolveEffectiveConfig({
769
+ apiKey: flags["api-key"],
770
+ baseUrl: flags["base-url"],
771
+ timeout: flags.timeout,
772
+ account: flags.account,
773
+ profile: flags.profile
774
+ });
775
+ if (!cfg.apiKey) {
776
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
777
+ process.exit(3);
778
+ }
779
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
780
+ const out = buildOutputStreams();
781
+ await runCompanyMessage(client, { ...flags, account: flags.account ?? cfg.account }, out);
782
+ }
783
+ });
784
+ var companySearchChatsCommand = defineCommand({
785
+ meta: {
786
+ name: "search-chats",
787
+ description: "Search or filter a company page's admin inbox. Exactly one mode per call: free-text <query>, --topic, or --unread; mutually exclusive, enforced server-side. Admin-gated."
788
+ },
789
+ args: {
790
+ ...GLOBAL_FLAGS,
791
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), a slug/URL is resolved to the numeric id first." },
792
+ query: { type: "positional", required: false, description: "Free-text term, matches participant names and message content." },
793
+ topic: { type: "string", description: "Filter mode, one inbox topic card: 1-5 or its name (Service request, Request a demo, Support, Careers, Other)." },
794
+ unread: { type: "boolean", description: "Filter mode, unread conversations only." }
795
+ },
796
+ async run({ args }) {
797
+ const flags = args;
798
+ const cfg = await resolveEffectiveConfig({
799
+ apiKey: flags["api-key"],
800
+ baseUrl: flags["base-url"],
801
+ timeout: flags.timeout,
802
+ account: flags.account,
803
+ profile: flags.profile
804
+ });
805
+ if (!cfg.apiKey) {
806
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
807
+ process.exit(3);
808
+ }
809
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
810
+ const out = buildOutputStreams();
811
+ await runCompanySearchChats(client, { ...flags, account: flags.account ?? cfg.account }, out);
812
+ }
813
+ });
448
814
  var companyReplyCommand = defineCommand({
449
815
  meta: {
450
816
  name: "reply",
451
- description: "Reply to a company-inbox conversation, as the page (write, admin-gated: the account must administer the page). Requires a COMPANY_ chat id from `inboxes chats`, not the 2-\u2026 id `company` reads return (the API rejects a non-COMPANY_ id with a guiding 400 naming the fix). Reply-only, this cannot start a new conversation on the page's behalf. See also: `inboxes chats` and `message send` (the personal equivalent, which also accepts a COMPANY_ chat id)."
817
+ description: "Reply to a company-inbox conversation, as the page (write, admin-gated: the account must administer the page). Takes the normal 2-\u2026 chat id from `company chats`; the endpoint resolves the page mailbox internally from the company id. Reply-only, this cannot start a new conversation on the page's behalf. See also: `company chats` (the read that returns the chat id) and `message send` (the personal equivalent)."
452
818
  },
453
819
  args: {
454
820
  ...WRITE_FLAGS,
455
821
  id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), resolved to the numeric id first, including under --preview." },
456
822
  chatId: {
457
823
  type: "positional",
458
- description: "COMPANY_ chat id (from `inboxes chats`), passed through verbatim, no client-side check."
824
+ description: "The 2-\u2026 chat id from `company chats`, passed through verbatim (no client-side check)."
459
825
  },
460
826
  text: { type: "positional", description: "Reply text. Pass - to read from stdin (e.g. via heredoc or pipe)." },
461
827
  attach: { type: "string", description: "File to attach (repeatable)." }
@@ -491,7 +857,14 @@ var companyCommand = defineCommand({
491
857
  jobs: companyJobsCommand,
492
858
  "invitable-followers": companyInvitableFollowersCommand,
493
859
  "follow-invite": companyFollowInviteCommand,
494
- reply: companyReplyCommand
860
+ reply: companyReplyCommand,
861
+ managed: companyManagedCommand,
862
+ followers: companyFollowersCommand,
863
+ chats: companyChatsCommand,
864
+ chat: companyChatCommand,
865
+ messages: companyMessagesCommand,
866
+ message: companyMessageCommand,
867
+ "search-chats": companySearchChatsCommand
495
868
  },
496
869
  async run({ args }) {
497
870
  const flags = args;
@@ -513,11 +886,18 @@ var companyCommand = defineCommand({
513
886
  });
514
887
  export {
515
888
  companyCommand,
889
+ runCompanyChat,
890
+ runCompanyChats,
516
891
  runCompanyEmployees,
517
892
  runCompanyFollowInvite,
893
+ runCompanyFollowers,
518
894
  runCompanyGet,
519
895
  runCompanyInvitableFollowers,
520
896
  runCompanyJobs,
897
+ runCompanyManaged,
898
+ runCompanyMessage,
899
+ runCompanyMessages,
521
900
  runCompanyPosts,
522
- runCompanyReply
901
+ runCompanyReply,
902
+ runCompanySearchChats
523
903
  };
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ pageDelayFromFlags,
4
+ streamAll
5
+ } from "./chunk-EEMJDJ4W.js";
6
+ import {
7
+ createClient,
8
+ renderError,
9
+ renderSuccess,
10
+ renderUnexpectedError,
11
+ resolveEffectiveConfig
12
+ } from "./chunk-M33MI53G.js";
13
+ import {
14
+ GLOBAL_FLAGS
15
+ } from "./chunk-TMU3CSPR.js";
16
+
17
+ // src/commands/feed.ts
18
+ import { defineCommand } from "citty";
19
+ function buildOutputStreams() {
20
+ return {
21
+ stdout: { write: (s) => process.stdout.write(s) },
22
+ stderr: { write: (s) => process.stderr.write(s) }
23
+ };
24
+ }
25
+ function requireAccount(account, out) {
26
+ if (!account) {
27
+ out.stderr.write("error: --account is required for this command. Set it via --account, CURVIATE_ACCOUNT, or `curviate config set-account`.\n");
28
+ process.exit(2);
29
+ }
30
+ return account;
31
+ }
32
+ function rejectPreviewOnRead(preview, out) {
33
+ if (preview) {
34
+ out.stderr.write("error: --preview is only valid on write commands (mutations). Reads just run.\n");
35
+ process.exit(2);
36
+ }
37
+ }
38
+ function resolveOutputOpts(flags) {
39
+ return {
40
+ json: (flags.json ?? false) || !process.stdout.isTTY,
41
+ isTTY: process.stdout.isTTY ?? false,
42
+ fields: flags.fields,
43
+ verbose: flags.verbose ?? false
44
+ };
45
+ }
46
+ async function handleSdkError(err, outOpts, out) {
47
+ const { CurviateError } = await import("@curviate/sdk");
48
+ if (err instanceof CurviateError) {
49
+ const { getExitCode } = await import("./exit-codes-63JE5GM5.js");
50
+ renderError(err, outOpts, out);
51
+ process.exit(getExitCode(err.code));
52
+ }
53
+ renderUnexpectedError(err, out);
54
+ process.exit(1);
55
+ }
56
+ async function runFeedHome(client, flags, out) {
57
+ rejectPreviewOnRead(flags.preview, out);
58
+ const accountId = requireAccount(flags.account, out);
59
+ const ns = client.account(accountId);
60
+ const outOpts = resolveOutputOpts(flags);
61
+ const all = flags.all ?? false;
62
+ const maxPages = flags["max-pages"] ? parseInt(flags["max-pages"], 10) : 100;
63
+ const params = {};
64
+ if (flags.sort) params["sort"] = flags.sort;
65
+ if (flags.limit) params["limit"] = parseInt(flags.limit, 10);
66
+ if (flags.cursor) params["cursor"] = flags.cursor;
67
+ try {
68
+ if (all) {
69
+ const fn = (p) => ns.feed.home(p);
70
+ for await (const item of streamAll(fn, params, {
71
+ maxPages,
72
+ out,
73
+ pageDelayMs: pageDelayFromFlags(flags)
74
+ })) {
75
+ out.stdout.write(JSON.stringify(item) + "\n");
76
+ }
77
+ } else {
78
+ const result = await ns.feed.home(params);
79
+ renderSuccess(result, outOpts, out);
80
+ }
81
+ } catch (err) {
82
+ await handleSdkError(err, outOpts, out);
83
+ }
84
+ }
85
+ var FEED_ARGS = {
86
+ ...GLOBAL_FLAGS,
87
+ sort: {
88
+ type: "string",
89
+ description: "Sort order: recent (default, reverse-chronological, always available) or relevant (LinkedIn's ranked 'top' feed, shared throttled budget). Ignored when --cursor is supplied."
90
+ }
91
+ };
92
+ var feedHomeCommand = defineCommand({
93
+ meta: { name: "home", description: "Read the connected account's LinkedIn home feed as agent-actionable posts." },
94
+ args: FEED_ARGS,
95
+ async run({ args }) {
96
+ const flags = args;
97
+ const cfg = await resolveEffectiveConfig({
98
+ apiKey: flags["api-key"],
99
+ baseUrl: flags["base-url"],
100
+ timeout: flags.timeout,
101
+ account: flags.account,
102
+ profile: flags.profile
103
+ });
104
+ if (!cfg.apiKey) {
105
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
106
+ process.exit(3);
107
+ }
108
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
109
+ const out = buildOutputStreams();
110
+ await runFeedHome(client, { ...flags, account: flags.account ?? cfg.account }, out);
111
+ }
112
+ });
113
+ var feedCommand = defineCommand({
114
+ meta: { name: "feed", description: "Read the connected account's LinkedIn home feed as agent-actionable posts." },
115
+ subCommands: {
116
+ home: feedHomeCommand
117
+ },
118
+ async run() {
119
+ process.stderr.write(
120
+ "Usage: curviate feed <subcommand>\n home [--sort recent|relevant] [--limit] [--cursor] [--all]\n"
121
+ );
122
+ }
123
+ });
124
+ export {
125
+ feedCommand,
126
+ runFeedHome
127
+ };