chirpie 1.0.47 → 1.0.48

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.
Files changed (3) hide show
  1. package/README.md +12 -3
  2. package/dist/index.js +30 -6
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -30,12 +30,13 @@ export CHIRPIE_API_KEY=chirpie_sk_...
30
30
  | Command | What it does |
31
31
  |---------|--------------|
32
32
  | `chirpie login` / `logout` / `auth` / `whoami` | Manage credentials |
33
- | `chirpie post <text>` | Create a post. `-a` account (repeat it for several accounts), `-m` media files or URLs, `--alt` descriptions, `--config` per-account overrides, `-s` schedule, `--draft` save without sending |
34
- | `chirpie thread <post> <post> ...` | Create a 2 to 25 post thread, or 1 to 25 with `--draft`. `-a` is repeatable, `--config` takes per-account posts, `-f` takes a JSON payload file |
33
+ | `chirpie post <text>` | Create a post. `-a` account (repeat it for several accounts), `-m` media files or URLs, `--alt` descriptions, `--config` per-account overrides, `--first-comment` a comment published under the post as soon as it goes out, `-s` schedule, `--draft` save without sending |
34
+ | `chirpie thread <post> <post> ...` | Create a 2 to 25 post thread, or 1 to 25 with `--draft`. `-a` is repeatable, `--config` takes per-account posts, `--first-comment` posts a comment under the last part, `-f` takes a JSON payload file |
35
35
  | `chirpie posts` | List posts. `--status`, `--account`, `--group`, `--limit`, `--include-hidden` |
36
36
  | `chirpie posts get <id>` | Fetch one post |
37
- | `chirpie posts update <id>` | Edit a post that has not published yet, or finish a draft. `--text`, `--media`, `--alt`, `--clear-media`, `--schedule-at`, `--keep-draft`. Leaving `--schedule-at` out keeps the time it already has |
37
+ | `chirpie posts update <id>` | Edit a post that has not published yet, or finish a draft. `--text`, `--media`, `--alt`, `--clear-media`, `--first-comment` (`""` removes it), `--schedule-at`, `--keep-draft`. Leaving `--schedule-at` out keeps the time it already has |
38
38
  | `chirpie posts publish <id>` | Send a saved draft now. `-t` sets the final text first |
39
+ | `chirpie posts first-comment <id>` | Post a first comment that failed, again. It re-sends the text the post already carries |
39
40
  | `chirpie posts delete <id>` | Take a post down from the platform. Chirpie keeps it, marked deleted. Deleting any post of a scheduled thread cancels the thread. Instagram and TikTok offer no delete API and refuse with `delete_unsupported` |
40
41
  | `chirpie posts hide <id>` / `unhide <id>` | Hide a post from your Chirpie listings, or show it again. Nothing reaches the platform |
41
42
  | `chirpie accounts` | List connected accounts, active and inactive |
@@ -70,6 +71,14 @@ chirpie thread "One" "Two" "Three" -a 550e8400-e29b-41d4-a716-446655440000
70
71
 
71
72
  # What is queued
72
73
  chirpie posts --status scheduled
74
+
75
+ # Put the link in the first comment. X, Threads, Instagram and Facebook only,
76
+ # and it counts as one post against your monthly quota.
77
+ chirpie post "We rebuilt scheduling this week." \
78
+ --first-comment "Full write-up: https://example.com/blog/scheduling"
79
+
80
+ # A first comment never fails its post. Send one that did not go out again.
81
+ chirpie posts first-comment "$POST_ID"
73
82
  ```
74
83
 
75
84
  ## Drafts
package/dist/index.js CHANGED
@@ -274,9 +274,9 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
274
274
  "-a, --account <id>",
275
275
  "Account ID. Repeat it to publish the same post to several accounts at once (up to 25)",
276
276
  collect
277
- ).option("-m, --media <files...>", MEDIA_OPTION_HELP).option("--alt <text...>", ALT_OPTION_HELP).option(
277
+ ).option("-m, --media <files...>", MEDIA_OPTION_HELP).option("--first-comment <text>", "Post this as a comment under the post, as soon as it goes out. X, Threads, Instagram and Facebook only. It counts as one post against your monthly quota").option("--alt <text...>", ALT_OPTION_HELP).option(
278
278
  "--config <json-or-file>",
279
- 'Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "text": "...", "media_urls": ["..."] } }. Every key must be an account named with --account'
279
+ 'Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "text": "...", "media_urls": ["..."], "first_comment": "..." } }. Every key must be an account named with --account, and "first_comment": "" publishes that account without the first comment the call is sending'
280
280
  ).option("-s, --schedule <datetime>", "Schedule for later. Any ISO 8601 timestamp with a timezone (2026-04-01T14:00:00Z or 2026-04-01T16:00:00+02:00). Posts publish within ~5 minutes of the scheduled time.").option(
281
281
  "--draft",
282
282
  "Save without publishing. Nothing is sent, nothing counts against your quota, and any problems are listed back"
@@ -296,6 +296,7 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
296
296
  account_ids: accountIds,
297
297
  text,
298
298
  ...media ? { media } : {},
299
+ ...opts.firstComment ? { first_comment: opts.firstComment } : {},
299
300
  ...opts.config ? {
300
301
  account_configurations: parseAccountConfigurations(
301
302
  opts.config
@@ -329,6 +330,7 @@ var postCommand = new Command3("post").description("Create a post").argument("<t
329
330
  account_id: accountIds[0],
330
331
  text,
331
332
  ...media ? { media } : {},
333
+ ...opts.firstComment ? { first_comment: opts.firstComment } : {},
332
334
  schedule_at: opts.schedule,
333
335
  ...opts.draft ? { draft: true } : {}
334
336
  });
@@ -366,7 +368,7 @@ function parseAltSpec(spec) {
366
368
  alts: m[2].split(",").map((a) => a.trim())
367
369
  };
368
370
  }
369
- var threadCommand = new Command4("thread").description("Create a thread").argument("[posts...]", "Thread posts (each argument is one post). Omit when using --file.").option(
371
+ var threadCommand = new Command4("thread").description("Create a thread").argument("[posts...]", "Thread posts (each argument is one post). Omit when using --file.").option("--first-comment <text>", "Post this as a comment under the thread's last post, as soon as it goes out. X, Threads, Instagram and Facebook only. It counts as one post against your monthly quota").option(
370
372
  "-a, --account <id>",
371
373
  "Account ID. Repeat it to publish the same thread to several accounts at once (up to 25)",
372
374
  collect
@@ -381,7 +383,7 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
381
383
  "JSON file with a full thread payload: { posts: [{ text, media_urls? }, ...], schedule_at?: string }. It may also carry account_ids and account_configurations."
382
384
  ).option(
383
385
  "--config <json-or-file>",
384
- `Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "posts": [{ "text": "one" }, { "text": "two" }] } }. An account's posts replace the whole thread for that account`
386
+ `Per-account overrides as JSON, or a path to a JSON file holding them: { "<account id>": { "posts": [{ "text": "one" }, { "text": "two" }], "first_comment": "..." } }. An account's posts replace the whole thread for that account, and "first_comment": "" publishes that account without the first comment the call is sending`
385
387
  ).option("-s, --schedule <datetime>", "Schedule for later. Any ISO 8601 timestamp with a timezone (2026-04-01T14:00:00Z or 2026-04-01T16:00:00+02:00). Threads publish within ~5 minutes of the scheduled time.").option(
386
388
  "--draft",
387
389
  "Save without publishing. Nothing is sent, nothing counts against your quota, and any problems are listed back"
@@ -459,6 +461,7 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
459
461
  const result = await client.createThread({
460
462
  account_ids: accountIds,
461
463
  posts: postPayload,
464
+ ...opts.firstComment ? { first_comment: opts.firstComment } : {},
462
465
  ...configurations ? { account_configurations: configurations } : {},
463
466
  schedule_at: scheduleAt,
464
467
  ...opts.draft ? { draft: true } : {}
@@ -487,6 +490,7 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
487
490
  const thread = await client.createThread({
488
491
  account_id: accountIds[0],
489
492
  posts: postPayload,
493
+ ...opts.firstComment ? { first_comment: opts.firstComment } : {},
490
494
  schedule_at: scheduleAt,
491
495
  ...opts.draft ? { draft: true } : {}
492
496
  });
@@ -584,6 +588,9 @@ postsCommand.command("update <id>").description(
584
588
  ).option("--alt <text...>", ALT_OPTION_HELP).option("--clear-media", "Remove the media from the post").option(
585
589
  "-s, --schedule-at <datetime>",
586
590
  "New publish time. Any ISO 8601 timestamp with a timezone (2027-04-01T14:00:00Z or 2027-04-01T16:00:00+02:00). Omit it to keep the time the post already has. Rescheduling one part of a thread moves the whole thread. On a draft this queues it, unless you also pass --keep-draft."
591
+ ).option(
592
+ "--first-comment <text>",
593
+ 'The comment to post under this one once it publishes. Pass "" to remove the one it has'
587
594
  ).option(
588
595
  "--keep-draft",
589
596
  "Keep a draft a draft, so --schedule-at only changes the time it remembers"
@@ -592,9 +599,9 @@ postsCommand.command("update <id>").description(
592
599
  error("Pass either --media or --clear-media, not both");
593
600
  process.exit(1);
594
601
  }
595
- if (!opts.text && !opts.media && !opts.clearMedia && !opts.scheduleAt && !opts.keepDraft) {
602
+ if (!opts.text && !opts.media && !opts.clearMedia && opts.firstComment === void 0 && !opts.scheduleAt && !opts.keepDraft) {
596
603
  error(
597
- "Nothing to change. Pass --text, --media, --clear-media, --schedule-at or --keep-draft"
604
+ "Nothing to change. Pass --text, --media, --clear-media, --first-comment, --schedule-at or --keep-draft"
598
605
  );
599
606
  process.exit(1);
600
607
  }
@@ -605,6 +612,7 @@ postsCommand.command("update <id>").description(
605
612
  ...opts.text !== void 0 ? { text: opts.text } : {},
606
613
  ...opts.clearMedia ? { media: [] } : {},
607
614
  ...media ? { media } : {},
615
+ ...opts.firstComment !== void 0 ? { first_comment: opts.firstComment } : {},
608
616
  ...opts.scheduleAt ? { schedule_at: opts.scheduleAt } : {},
609
617
  ...opts.keepDraft ? { draft: true } : {}
610
618
  });
@@ -664,6 +672,22 @@ postsCommand.command("delete <id>").description(
664
672
  process.exit(1);
665
673
  }
666
674
  });
675
+ postsCommand.command("first-comment <id>").description(
676
+ "Post a first comment that failed, again. Re-sends the text the post already carries"
677
+ ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
678
+ const client = getClient();
679
+ try {
680
+ const post = await client.retryFirstComment(id);
681
+ if (wantsJson(opts, cmd)) {
682
+ json(post);
683
+ } else {
684
+ success(`First comment posted on ${post.id}`);
685
+ }
686
+ } catch (err) {
687
+ apiError(err, "Failed to post the first comment");
688
+ process.exit(1);
689
+ }
690
+ });
667
691
  postsCommand.command("hide <id>").description(
668
692
  "Hide a post from your Chirpie listings (nothing reaches the platform)"
669
693
  ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chirpie",
3
- "version": "1.0.47",
3
+ "version": "1.0.48",
4
4
  "description": "Chirpie CLI: post to social media from the command line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -44,7 +44,7 @@
44
44
  ],
45
45
  "license": "MIT",
46
46
  "dependencies": {
47
- "@chirpie/sdk": "^1.0.44",
47
+ "@chirpie/sdk": "^1.0.45",
48
48
  "commander": "^13"
49
49
  },
50
50
  "devDependencies": {