@curviate/cli 0.17.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,36 @@ 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.18.1] - 2026-07-18
12
+
13
+ A patch aligning `company reply` with the company-inbox chat-id cutover. No breaking changes, built against `@curviate/sdk` 0.18.1.
14
+
15
+ ### Fixed
16
+
17
+ - **`company reply <id> <chat_id> "<text>"`** now takes the normal `2-…` conversation
18
+ id that `company chats` returns; the endpoint resolves the page mailbox internally from
19
+ the company identifier, so the earlier `COMPANY_` chat-id requirement is gone. `--preview`
20
+ now always prints a "Will send as company page `<id>`" notice derived from the resolved
21
+ identifier (previously it went silent for a bare `2-…` id). Reply-only and admin-gated,
22
+ otherwise unchanged.
23
+
24
+ ## [0.18.0] - 2026-07-17
25
+
26
+ A minor release adding the `company reply` command. No breaking changes, built against `@curviate/sdk` 0.18.0.
27
+
28
+ ### Added
29
+
30
+ - **`company reply <id> <chat_id> "<text>" [--attach <file>…]`** (write, admin-gated,
31
+ `--preview` accepted). Replies to an existing company-inbox conversation as the page,
32
+ via the SDK's `companies.sendMessage`. `<chat_id>` must be a `COMPANY_` chat id from
33
+ `inboxes chats`, not the `2-…` id the `company` reads return; it passes through verbatim
34
+ (no client-side pre-check) and a non-`COMPANY_` id is rejected by the API with a guiding
35
+ 400 naming the fix. Reply-only: it cannot start a new conversation on the page's behalf.
36
+ `<id>` accepts a URL, slug, or numeric id, resolved to the numeric id first (including
37
+ under `--preview`, so the preview renders the request that would be sent). Pass `-` as
38
+ the text to read the reply body from stdin. See also `inboxes chats` and `message send`
39
+ (the personal equivalent, which also accepts a `COMPANY_` chat id).
40
+
11
41
  ## [0.17.0] - 2026-07-17
12
42
 
13
43
  A minor release adding the `company follow-invite` and `company invitable-followers`
@@ -693,15 +693,18 @@ var messageCommand = defineCommand({
693
693
  await runMessageSend(client, { ...flags, account: flags.account ?? cfg.account }, out);
694
694
  }
695
695
  });
696
+
696
697
  export {
697
- messageCommand,
698
- runMessageAttachment,
699
- runMessageDelete,
700
- runMessageEdit,
698
+ sentAsNotice,
699
+ willSendAsNotice,
700
+ runMessageNew,
701
+ runMessageSend,
701
702
  runMessageGet,
703
+ runMessageEdit,
704
+ runMessageDelete,
705
+ runMessageReact,
706
+ runMessageAttachment,
702
707
  runMessageInMail,
703
708
  runMessageInMailBalance,
704
- runMessageNew,
705
- runMessageReact,
706
- runMessageSend
709
+ messageCommand
707
710
  };
package/dist/cli.js CHANGED
@@ -255,20 +255,20 @@ var main = defineCommand({
255
255
  // ---------------------------------------------------------------------------
256
256
  // Noun groups — lazy-loaded on first invocation.
257
257
  // ---------------------------------------------------------------------------
258
- profile: () => import("./profile-MLSIFVDJ.js").then((m) => m.profileCommand),
259
- company: () => import("./company-CU3BEHRW.js").then((m) => m.companyCommand),
260
- job: () => import("./job-6GEPEDLS.js").then((m) => m.jobCommand),
261
- connect: () => import("./connect-DO3J5OUV.js").then((m) => m.connectCommand),
258
+ profile: () => import("./profile-XWSRUYRW.js").then((m) => m.profileCommand),
259
+ company: () => import("./company-BVXX4FGX.js").then((m) => m.companyCommand),
260
+ job: () => import("./job-EIXBJXLW.js").then((m) => m.jobCommand),
261
+ connect: () => import("./connect-6PU7QCOL.js").then((m) => m.connectCommand),
262
262
  search: () => import("./search-ZQUKLQ6T.js").then((m) => m.searchCommand),
263
- inbox: () => import("./inbox-RZOMPFDA.js").then((m) => m.inboxCommand),
263
+ inbox: () => import("./inbox-DRJ6ENXC.js").then((m) => m.inboxCommand),
264
264
  inboxes: () => import("./inboxes-MTPWLP5F.js").then((m) => m.inboxesCommand),
265
- message: () => import("./message-KOSPK33G.js").then((m) => m.messageCommand),
266
- post: () => import("./post-TSOE327K.js").then((m) => m.postCommand),
267
- comment: () => import("./comment-56VBPLGW.js").then((m) => m.commentCommand),
268
- account: () => import("./account-VDKORNPQ.js").then((m) => m.accountCommand),
265
+ message: () => import("./message-UWMRE2SJ.js").then((m) => m.messageCommand),
266
+ post: () => import("./post-N3GQDIQJ.js").then((m) => m.postCommand),
267
+ comment: () => import("./comment-VT6PO4MN.js").then((m) => m.commentCommand),
268
+ account: () => import("./account-EGJJNBXW.js").then((m) => m.accountCommand),
269
269
  webhook: () => import("./webhook-QFSZN3P2.js").then((m) => m.webhookCommand),
270
- "sales-nav": () => import("./sales-nav-GD5WQCJI.js").then((m) => m.salesNavCommand),
271
- recruiter: () => import("./recruiter-OWEQIFYG.js").then((m) => m.recruiterCommand)
270
+ "sales-nav": () => import("./sales-nav-TMXWDKSE.js").then((m) => m.salesNavCommand),
271
+ recruiter: () => import("./recruiter-MVPSTH2V.js").then((m) => m.recruiterCommand)
272
272
  },
273
273
  async run() {
274
274
  const { runMain } = await import("citty");
@@ -1,7 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- resolveIdentifier
4
- } from "./chunk-DMQZEPQE.js";
3
+ sentAsNotice
4
+ } from "./chunk-KVV6LZ7E.js";
5
+ import {
6
+ resolveTextOrStdin
7
+ } from "./chunk-U7Y4EXHT.js";
8
+ import {
9
+ AttachError,
10
+ readAttachment,
11
+ toAttachmentPayload
12
+ } from "./chunk-BGZW6B7G.js";
5
13
  import {
6
14
  reencodeInvitableFollowers,
7
15
  reencodeInviteTokenItem,
@@ -15,6 +23,10 @@ import {
15
23
  pageDelayFromFlags,
16
24
  streamAll
17
25
  } from "./chunk-EEMJDJ4W.js";
26
+ import "./chunk-UWO2D4HW.js";
27
+ import {
28
+ resolveIdentifier
29
+ } from "./chunk-DMQZEPQE.js";
18
30
  import {
19
31
  buildPreviewOutput
20
32
  } from "./chunk-R3VLWLVV.js";
@@ -63,6 +75,10 @@ function normalizeInviteeIds(invitee) {
63
75
  if (!invitee) return [];
64
76
  return Array.isArray(invitee) ? invitee : [invitee];
65
77
  }
78
+ function normalizeAttachPaths(attach) {
79
+ if (!attach) return [];
80
+ return Array.isArray(attach) ? attach : [attach];
81
+ }
66
82
  async function resolveCompanyId(ns, raw) {
67
83
  const normalized = resolveIdentifier(raw);
68
84
  if (/^\d+$/.test(normalized)) return normalized;
@@ -245,6 +261,56 @@ async function runCompanyFollowInvite(client, flags, out) {
245
261
  await handleSdkError(err, outOpts, out);
246
262
  }
247
263
  }
264
+ async function runCompanyReply(client, flags, out, _readStdin) {
265
+ const accountId = requireAccount(flags.account, out);
266
+ const ns = client.account(accountId);
267
+ const outOpts = resolveOutputOpts(flags);
268
+ const chatId = flags.chatId ?? "";
269
+ const rawText = flags.text ?? "";
270
+ const attachPaths = normalizeAttachPaths(flags.attach);
271
+ const text = await resolveTextOrStdin(rawText, out, _readStdin);
272
+ let attachBuffers = [];
273
+ try {
274
+ attachBuffers = await Promise.all(attachPaths.map((p) => readAttachment(p)));
275
+ } catch (err) {
276
+ if (err instanceof AttachError) {
277
+ out.stderr.write(`error: ${err.message}
278
+ `);
279
+ process.exit(err.exitCode);
280
+ }
281
+ throw err;
282
+ }
283
+ try {
284
+ const identifier = await resolveCompanyId(ns, flags.id ?? "");
285
+ if (flags.preview) {
286
+ const preview = buildPreviewOutput({
287
+ method: "companies.sendMessage",
288
+ args: { identifier, chat_id: chatId },
289
+ body: { text },
290
+ account: accountId,
291
+ attachments: attachBuffers.map((buf, i) => ({
292
+ name: attachPaths[i] ? attachPaths[i].split("/").pop() ?? attachPaths[i] : `attachment_${i}`,
293
+ buffer: buf
294
+ }))
295
+ });
296
+ out.stdout.write(JSON.stringify(preview) + "\n");
297
+ out.stderr.write(`Will send as company page ${identifier}
298
+ `);
299
+ return;
300
+ }
301
+ const attachmentPayloads = attachBuffers.map((buf, i) => toAttachmentPayload(attachPaths[i], buf));
302
+ const body = {
303
+ text,
304
+ ...attachmentPayloads.length > 0 ? { attachments: attachmentPayloads } : {}
305
+ };
306
+ const result = await ns.companies.sendMessage(identifier, chatId, body);
307
+ renderSuccess(result, outOpts, out);
308
+ const notice = sentAsNotice(result?.["sent_as"]);
309
+ if (notice) out.stderr.write(notice);
310
+ } catch (err) {
311
+ await handleSdkError(err, outOpts, out);
312
+ }
313
+ }
248
314
  var companyEmployeesCommand = defineCommand({
249
315
  meta: { name: "employees", description: "List people who currently work at the company." },
250
316
  args: {
@@ -378,6 +444,39 @@ var companyFollowInviteCommand = defineCommand({
378
444
  await runCompanyFollowInvite(client, { ...flags, account: flags.account ?? cfg.account }, out);
379
445
  }
380
446
  });
447
+ var companyReplyCommand = defineCommand({
448
+ meta: {
449
+ name: "reply",
450
+ 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)."
451
+ },
452
+ args: {
453
+ ...WRITE_FLAGS,
454
+ id: { type: "positional", description: "Company identifier (URL, slug, or numeric id), resolved to the numeric id first, including under --preview." },
455
+ chatId: {
456
+ type: "positional",
457
+ description: "The 2-\u2026 chat id from `company chats`, passed through verbatim (no client-side check)."
458
+ },
459
+ text: { type: "positional", description: "Reply text. Pass - to read from stdin (e.g. via heredoc or pipe)." },
460
+ attach: { type: "string", description: "File to attach (repeatable)." }
461
+ },
462
+ async run({ args }) {
463
+ const flags = args;
464
+ const cfg = await resolveEffectiveConfig({
465
+ apiKey: flags["api-key"],
466
+ baseUrl: flags["base-url"],
467
+ timeout: flags.timeout,
468
+ account: flags.account,
469
+ profile: flags.profile
470
+ });
471
+ if (!cfg.apiKey) {
472
+ process.stderr.write("error: no API key \u2014 run `curviate login` or pass --api-key.\n");
473
+ process.exit(3);
474
+ }
475
+ const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
476
+ const out = buildOutputStreams();
477
+ await runCompanyReply(client, { ...flags, account: flags.account ?? cfg.account }, out);
478
+ }
479
+ });
381
480
  var companyCommand = defineCommand({
382
481
  meta: { name: "company", description: "Fetch a company profile by URL, slug, or numeric id, and its sub-resources." },
383
482
  args: {
@@ -390,7 +489,8 @@ var companyCommand = defineCommand({
390
489
  posts: companyPostsCommand,
391
490
  jobs: companyJobsCommand,
392
491
  "invitable-followers": companyInvitableFollowersCommand,
393
- "follow-invite": companyFollowInviteCommand
492
+ "follow-invite": companyFollowInviteCommand,
493
+ reply: companyReplyCommand
394
494
  },
395
495
  async run({ args }) {
396
496
  const flags = args;
@@ -417,5 +517,6 @@ export {
417
517
  runCompanyGet,
418
518
  runCompanyInvitableFollowers,
419
519
  runCompanyJobs,
420
- runCompanyPosts
520
+ runCompanyPosts,
521
+ runCompanyReply
421
522
  };
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ messageCommand,
4
+ runMessageAttachment,
5
+ runMessageDelete,
6
+ runMessageEdit,
7
+ runMessageGet,
8
+ runMessageInMail,
9
+ runMessageInMailBalance,
10
+ runMessageNew,
11
+ runMessageReact,
12
+ runMessageSend,
13
+ sentAsNotice,
14
+ willSendAsNotice
15
+ } from "./chunk-KVV6LZ7E.js";
16
+ import "./chunk-U7Y4EXHT.js";
17
+ import "./chunk-BGZW6B7G.js";
18
+ import "./chunk-UWO2D4HW.js";
19
+ import "./chunk-DMQZEPQE.js";
20
+ import "./chunk-R3VLWLVV.js";
21
+ import "./chunk-M33MI53G.js";
22
+ import "./chunk-TMU3CSPR.js";
23
+ export {
24
+ messageCommand,
25
+ runMessageAttachment,
26
+ runMessageDelete,
27
+ runMessageEdit,
28
+ runMessageGet,
29
+ runMessageInMail,
30
+ runMessageInMailBalance,
31
+ runMessageNew,
32
+ runMessageReact,
33
+ runMessageSend,
34
+ sentAsNotice,
35
+ willSendAsNotice
36
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curviate/cli",
3
- "version": "0.17.0",
3
+ "version": "0.18.1",
4
4
  "private": false,
5
5
  "description": "Official command-line interface for the Curviate API.",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  "clean": "rm -rf dist *.tsbuildinfo"
42
42
  },
43
43
  "dependencies": {
44
- "@curviate/sdk": "^0.17.0",
44
+ "@curviate/sdk": "^0.18.1",
45
45
  "citty": "^0.1.6",
46
46
  "open": "^10.1.0"
47
47
  },
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- defaultReadStdin
4
- } from "./chunk-U7Y4EXHT.js";
5
2
  import {
6
3
  readlineSync
7
4
  } from "./chunk-H4KV7MIN.js";
8
5
  import {
9
6
  AUTH_NEEDED
10
7
  } from "./chunk-M6UDWFHX.js";
8
+ import {
9
+ defaultReadStdin
10
+ } from "./chunk-U7Y4EXHT.js";
11
11
  import {
12
12
  slimAccountGet,
13
13
  slimAccountList,
@@ -1,21 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- resolveTextOrStdin
4
- } from "./chunk-U7Y4EXHT.js";
5
2
  import {
6
3
  resolveMemberOrMeProviderId
7
4
  } from "./chunk-QJZ3LWOX.js";
5
+ import {
6
+ resolveTextOrStdin
7
+ } from "./chunk-U7Y4EXHT.js";
8
8
  import {
9
9
  AttachError,
10
10
  describeAttachment,
11
11
  readAttachment,
12
12
  toAttachmentPayload
13
13
  } from "./chunk-BGZW6B7G.js";
14
- import "./chunk-DMQZEPQE.js";
15
14
  import {
16
15
  pageDelayFromFlags,
17
16
  streamAll
18
17
  } from "./chunk-EEMJDJ4W.js";
18
+ import "./chunk-DMQZEPQE.js";
19
19
  import {
20
20
  buildPreviewOutput
21
21
  } from "./chunk-R3VLWLVV.js";
@@ -1,7 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- resolveIdentifier
4
- } from "./chunk-DMQZEPQE.js";
5
2
  import {
6
3
  slimInviteReceived,
7
4
  slimInviteReceivedItem,
@@ -12,6 +9,9 @@ import {
12
9
  pageDelayFromFlags,
13
10
  streamAll
14
11
  } from "./chunk-EEMJDJ4W.js";
12
+ import {
13
+ resolveIdentifier
14
+ } from "./chunk-DMQZEPQE.js";
15
15
  import {
16
16
  buildPreviewOutput
17
17
  } from "./chunk-R3VLWLVV.js";
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- normalizeChatId
4
- } from "./chunk-DMQZEPQE.js";
5
2
  import {
6
3
  pageDelayFromFlags,
7
4
  streamAll
8
5
  } from "./chunk-EEMJDJ4W.js";
6
+ import {
7
+ normalizeChatId
8
+ } from "./chunk-DMQZEPQE.js";
9
9
  import {
10
10
  buildPreviewOutput
11
11
  } from "./chunk-R3VLWLVV.js";
@@ -1,11 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- BinaryOutputError,
4
- writeBinaryOutput
5
- } from "./chunk-UWO2D4HW.js";
6
- import {
7
- resolveJobIdentifier
8
- } from "./chunk-DMQZEPQE.js";
9
2
  import {
10
3
  slimJob
11
4
  } from "./chunk-ROULHEFW.js";
@@ -15,6 +8,13 @@ import {
15
8
  pageDelayFromFlags,
16
9
  streamAll
17
10
  } from "./chunk-EEMJDJ4W.js";
11
+ import {
12
+ BinaryOutputError,
13
+ writeBinaryOutput
14
+ } from "./chunk-UWO2D4HW.js";
15
+ import {
16
+ resolveJobIdentifier
17
+ } from "./chunk-DMQZEPQE.js";
18
18
  import {
19
19
  buildPreviewOutput
20
20
  } from "./chunk-R3VLWLVV.js";
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- resolveTextOrStdin
4
- } from "./chunk-U7Y4EXHT.js";
5
2
  import {
6
3
  resolveMemberOrMeProviderId
7
4
  } from "./chunk-QJZ3LWOX.js";
5
+ import {
6
+ resolveTextOrStdin
7
+ } from "./chunk-U7Y4EXHT.js";
8
8
  import {
9
9
  AttachError,
10
10
  readAttachment,
11
11
  toAttachmentPayload
12
12
  } from "./chunk-BGZW6B7G.js";
13
- import "./chunk-DMQZEPQE.js";
14
13
  import {
15
14
  pageDelayFromFlags,
16
15
  streamAll
17
16
  } from "./chunk-EEMJDJ4W.js";
17
+ import "./chunk-DMQZEPQE.js";
18
18
  import {
19
19
  buildPreviewOutput
20
20
  } from "./chunk-R3VLWLVV.js";
@@ -8,9 +8,6 @@ import {
8
8
  readAttachment,
9
9
  toAttachmentPayload
10
10
  } from "./chunk-BGZW6B7G.js";
11
- import {
12
- resolveIdentifier
13
- } from "./chunk-DMQZEPQE.js";
14
11
  import {
15
12
  slimProfile,
16
13
  slimProfileMe
@@ -19,6 +16,9 @@ import {
19
16
  pageDelayFromFlags,
20
17
  streamAll
21
18
  } from "./chunk-EEMJDJ4W.js";
19
+ import {
20
+ resolveIdentifier
21
+ } from "./chunk-DMQZEPQE.js";
22
22
  import {
23
23
  buildPreviewOutput
24
24
  } from "./chunk-R3VLWLVV.js";
@@ -9,6 +9,13 @@ import {
9
9
  readAttachment,
10
10
  toAttachmentPayload
11
11
  } from "./chunk-BGZW6B7G.js";
12
+ import {
13
+ slimJob
14
+ } from "./chunk-ROULHEFW.js";
15
+ import {
16
+ pageDelayFromFlags,
17
+ streamAll
18
+ } from "./chunk-EEMJDJ4W.js";
12
19
  import {
13
20
  BinaryOutputError,
14
21
  writeBinaryOutput
@@ -17,13 +24,6 @@ import {
17
24
  resolveIdentifier,
18
25
  resolveJobIdentifier
19
26
  } from "./chunk-DMQZEPQE.js";
20
- import {
21
- slimJob
22
- } from "./chunk-ROULHEFW.js";
23
- import {
24
- pageDelayFromFlags,
25
- streamAll
26
- } from "./chunk-EEMJDJ4W.js";
27
27
  import {
28
28
  buildPreviewOutput
29
29
  } from "./chunk-R3VLWLVV.js";
@@ -10,13 +10,13 @@ import {
10
10
  readAttachment,
11
11
  toAttachmentPayload
12
12
  } from "./chunk-BGZW6B7G.js";
13
- import {
14
- resolveIdentifier
15
- } from "./chunk-DMQZEPQE.js";
16
13
  import {
17
14
  pageDelayFromFlags,
18
15
  streamAll
19
16
  } from "./chunk-EEMJDJ4W.js";
17
+ import {
18
+ resolveIdentifier
19
+ } from "./chunk-DMQZEPQE.js";
20
20
  import {
21
21
  buildPreviewOutput
22
22
  } from "./chunk-R3VLWLVV.js";