chirpie 1.0.40 → 1.0.42

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/README.md CHANGED
@@ -34,9 +34,11 @@ export CHIRPIE_API_KEY=chirpie_sk_...
34
34
  | `chirpie thread <post> <post> ...` | Create a 2 to 25 post thread. `-f` takes a JSON payload file |
35
35
  | `chirpie posts` | List posts. `--status`, `--account`, `--limit` |
36
36
  | `chirpie posts get <id>` | Fetch one post |
37
+ | `chirpie posts update <id>` | Edit a post that has not published yet. `--text`, `--media`, `--clear-media`, `--schedule-at`. Leaving `--schedule-at` out keeps the time it already has |
37
38
  | `chirpie posts delete <id>` | Delete a post. Deleting any post of a scheduled thread cancels the thread |
38
39
  | `chirpie accounts` | List connected accounts, active and inactive |
39
40
  | `chirpie accounts activate <id>` / `deactivate <id>` | Choose which accounts publish. Deactivating cancels that account's scheduled posts |
41
+ | `chirpie accounts disconnect <id>` | End a connection. Cancels that account's scheduled posts, frees a plan slot, and removes the stored credential, so reconnecting means authorizing again. Asks first; `-y` skips the prompt |
40
42
  | `chirpie accounts connect-x` | Start the X OAuth flow and print the URL |
41
43
  | `chirpie accounts connect-bluesky` | Connect Bluesky with an app password |
42
44
  | `chirpie accounts connect-linkedin` / `connect-mastodon` | Start that platform's OAuth flow |
package/dist/index.js CHANGED
@@ -287,7 +287,7 @@ function wantsJson(opts, cmd) {
287
287
  }
288
288
 
289
289
  // src/commands/posts.ts
290
- var postsCommand = new Command5("posts").description("List, get, or delete posts").option("--status <status>", "Filter by status").option("--account <id>", "Filter by account").option("--limit <n>", "Limit results", "20").option("--json", "Output raw JSON").action(async (opts, cmd) => {
290
+ var postsCommand = new Command5("posts").description("List, get, update, or delete posts").option("--status <status>", "Filter by status").option("--account <id>", "Filter by account").option("--limit <n>", "Limit results", "20").option("--json", "Output raw JSON").action(async (opts, cmd) => {
291
291
  const client = getClient();
292
292
  try {
293
293
  const posts = await client.listPosts({
@@ -332,6 +332,47 @@ postsCommand.command("get <id>").description("Get a post by ID").option("--json"
332
332
  process.exit(1);
333
333
  }
334
334
  });
335
+ postsCommand.command("update <id>").description(
336
+ "Edit a post that has not published yet. Leaving --schedule-at out keeps the time it already has"
337
+ ).option("-t, --text <text>", "Replacement post text").option(
338
+ "-m, --media <urls...>",
339
+ "Replacement image or video URLs, following the same per-platform rules as creating a post. Pass --clear-media to remove the media instead."
340
+ ).option("--clear-media", "Remove the media from the post").option(
341
+ "-s, --schedule-at <datetime>",
342
+ "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."
343
+ ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
344
+ if (opts.media && opts.clearMedia) {
345
+ error("Pass either --media or --clear-media, not both");
346
+ process.exit(1);
347
+ }
348
+ if (!opts.text && !opts.media && !opts.clearMedia && !opts.scheduleAt) {
349
+ error("Nothing to change. Pass --text, --media, --clear-media or --schedule-at");
350
+ process.exit(1);
351
+ }
352
+ const client = getClient();
353
+ try {
354
+ const post = await client.updatePost(id, {
355
+ ...opts.text !== void 0 ? { text: opts.text } : {},
356
+ ...opts.clearMedia ? { media_urls: [] } : {},
357
+ ...opts.media ? { media_urls: opts.media } : {},
358
+ ...opts.scheduleAt ? { schedule_at: opts.scheduleAt } : {}
359
+ });
360
+ if (wantsJson(opts, cmd)) {
361
+ json(post);
362
+ } else {
363
+ const moved = post.rescheduled_post_ids ?? [];
364
+ success(`Post ${post.id} updated`);
365
+ if (opts.scheduleAt) {
366
+ success(
367
+ moved.length > 1 ? `Thread rescheduled for ${post.scheduled_at} (${moved.length} posts)` : `Scheduled for ${post.scheduled_at}`
368
+ );
369
+ }
370
+ }
371
+ } catch (err) {
372
+ apiError(err, "Failed to update post");
373
+ process.exit(1);
374
+ }
375
+ });
335
376
  postsCommand.command("delete <id>").description(
336
377
  "Delete a post (deleting any post of a scheduled thread cancels the thread)"
337
378
  ).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
@@ -475,6 +516,45 @@ accountsCommand.command("deactivate").argument("<id>", "Account ID (from `chirpi
475
516
  process.exit(1);
476
517
  }
477
518
  });
519
+ accountsCommand.command("disconnect").argument("<id>", "Account ID (from `chirpie accounts`)").description(
520
+ "Disconnect a connected account (stops publishing, frees a plan slot, cancels its scheduled posts)"
521
+ ).option("-y, --yes", "Skip the confirmation prompt").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
522
+ if (!opts.yes && !await confirm(`Disconnect account ${id}?`)) {
523
+ error("Cancelled");
524
+ process.exit(1);
525
+ }
526
+ const client = getClient();
527
+ try {
528
+ const result = await client.disconnectAccount(id);
529
+ if (wantsJson(opts, cmd)) {
530
+ json(result);
531
+ } else {
532
+ success(`Disconnected account ${id}`);
533
+ if (result.canceled_posts > 0) {
534
+ success(
535
+ `Cancelled ${result.canceled_posts} scheduled post${result.canceled_posts === 1 ? "" : "s"} and returned them to your monthly quota. They are not restored if you connect the account again.`
536
+ );
537
+ }
538
+ }
539
+ } catch (err) {
540
+ error(err instanceof Error ? err.message : "Failed to disconnect account");
541
+ process.exit(1);
542
+ }
543
+ });
544
+ async function confirm(question) {
545
+ if (!process.stdin.isTTY) return false;
546
+ const readline = await import("readline");
547
+ const rl = readline.createInterface({
548
+ input: process.stdin,
549
+ output: process.stderr
550
+ });
551
+ return new Promise((resolve) => {
552
+ rl.question(`${question} [y/N] `, (answer) => {
553
+ rl.close();
554
+ resolve(answer.trim().toLowerCase() === "y");
555
+ });
556
+ });
557
+ }
478
558
  accountsCommand.command("connect-x").description("Connect a new X/Twitter account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
479
559
  const client = getClient();
480
560
  try {
@@ -832,7 +912,7 @@ commentsCommand.command("hide").description("Hide a comment, or show it again wi
832
912
  }
833
913
  });
834
914
  commentsCommand.command("delete").description("Delete a comment from the platform").argument("<post_id>", "Post ID").argument("<comment_id>", "Comment ID from `chirpie comments list`").option("-y, --yes", "Skip the confirmation prompt").option("--json", "Output raw JSON").action(async (postId, commentId, opts, cmd) => {
835
- if (!opts.yes && !await confirm(`Delete comment ${commentId}?`)) {
915
+ if (!opts.yes && !await confirm2(`Delete comment ${commentId}?`)) {
836
916
  error("Cancelled");
837
917
  process.exit(1);
838
918
  }
@@ -849,7 +929,7 @@ commentsCommand.command("delete").description("Delete a comment from the platfor
849
929
  process.exit(1);
850
930
  }
851
931
  });
852
- async function confirm(question) {
932
+ async function confirm2(question) {
853
933
  if (!process.stdin.isTTY) return false;
854
934
  const readline = await import("readline");
855
935
  const rl = readline.createInterface({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chirpie",
3
- "version": "1.0.40",
3
+ "version": "1.0.42",
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.37",
47
+ "@chirpie/sdk": "^1.0.39",
48
48
  "commander": "^13"
49
49
  },
50
50
  "devDependencies": {