chirpie 1.0.28 → 1.0.30
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/dist/index.js +93 -47
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -279,7 +279,15 @@ var threadCommand = new Command4("thread").description("Create a thread").argume
|
|
|
279
279
|
|
|
280
280
|
// src/commands/posts.ts
|
|
281
281
|
import { Command as Command5 } from "commander";
|
|
282
|
-
|
|
282
|
+
|
|
283
|
+
// src/lib/flags.ts
|
|
284
|
+
function wantsJson(opts, cmd) {
|
|
285
|
+
if (opts?.json) return true;
|
|
286
|
+
return Boolean(cmd?.optsWithGlobals?.().json);
|
|
287
|
+
}
|
|
288
|
+
|
|
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) => {
|
|
283
291
|
const client = getClient();
|
|
284
292
|
try {
|
|
285
293
|
const posts = await client.listPosts({
|
|
@@ -287,7 +295,7 @@ var postsCommand = new Command5("posts").description("List, get, or delete posts
|
|
|
287
295
|
account_id: opts.account,
|
|
288
296
|
limit: parseInt(opts.limit)
|
|
289
297
|
});
|
|
290
|
-
if (opts
|
|
298
|
+
if (wantsJson(opts, cmd)) {
|
|
291
299
|
json(posts);
|
|
292
300
|
} else {
|
|
293
301
|
table(
|
|
@@ -304,11 +312,11 @@ var postsCommand = new Command5("posts").description("List, get, or delete posts
|
|
|
304
312
|
process.exit(1);
|
|
305
313
|
}
|
|
306
314
|
});
|
|
307
|
-
postsCommand.command("get <id>").description("Get a post by ID").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
315
|
+
postsCommand.command("get <id>").description("Get a post by ID").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
|
|
308
316
|
const client = getClient();
|
|
309
317
|
try {
|
|
310
318
|
const post = await client.getPost(id);
|
|
311
|
-
if (opts
|
|
319
|
+
if (wantsJson(opts, cmd)) {
|
|
312
320
|
json(post);
|
|
313
321
|
} else {
|
|
314
322
|
console.log(`ID: ${post.id}`);
|
|
@@ -326,12 +334,14 @@ postsCommand.command("get <id>").description("Get a post by ID").option("--json"
|
|
|
326
334
|
});
|
|
327
335
|
postsCommand.command("delete <id>").description(
|
|
328
336
|
"Delete a post (deleting any post of a scheduled thread cancels the thread)"
|
|
329
|
-
).action(async (id) => {
|
|
337
|
+
).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
|
|
330
338
|
const client = getClient();
|
|
331
339
|
try {
|
|
332
340
|
const result = await client.deletePost(id);
|
|
333
341
|
const cancelled = result.cancelled_ids ?? [];
|
|
334
|
-
if (
|
|
342
|
+
if (wantsJson(opts, cmd)) {
|
|
343
|
+
json(result);
|
|
344
|
+
} else if (cancelled.length > 1) {
|
|
335
345
|
success(
|
|
336
346
|
`Scheduled thread canceled (${cancelled.length} posts): ${cancelled.join(", ")}`
|
|
337
347
|
);
|
|
@@ -394,12 +404,12 @@ async function readSecretFromStdin(prompt) {
|
|
|
394
404
|
stdin.on("data", onData);
|
|
395
405
|
});
|
|
396
406
|
}
|
|
397
|
-
var accountsCommand = new Command6("accounts").description("List connected social accounts (X, Bluesky, LinkedIn, Threads, Mastodon, Instagram, Facebook, Telegram, Pinterest, TikTok, YouTube, and Google Business Profile)").option("--json", "Output raw JSON").action(async (opts) => {
|
|
407
|
+
var accountsCommand = new Command6("accounts").description("List connected social accounts (X, Bluesky, LinkedIn, Threads, Mastodon, Instagram, Facebook, Telegram, Pinterest, TikTok, YouTube, and Google Business Profile)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
398
408
|
const client = getClient();
|
|
399
409
|
try {
|
|
400
410
|
const list = await client.listAccountsWithLimits();
|
|
401
411
|
const { accounts, accounts_limit, accounts_active } = list;
|
|
402
|
-
if (opts
|
|
412
|
+
if (wantsJson(opts, cmd)) {
|
|
403
413
|
json(list);
|
|
404
414
|
} else {
|
|
405
415
|
info(
|
|
@@ -426,11 +436,11 @@ var accountsCommand = new Command6("accounts").description("List connected socia
|
|
|
426
436
|
process.exit(1);
|
|
427
437
|
}
|
|
428
438
|
});
|
|
429
|
-
accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie accounts`)").description("Activate a connected account so it can publish").option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
439
|
+
accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie accounts`)").description("Activate a connected account so it can publish").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
|
|
430
440
|
const client = getClient();
|
|
431
441
|
try {
|
|
432
442
|
const account = await client.activateAccount(id);
|
|
433
|
-
if (opts
|
|
443
|
+
if (wantsJson(opts, cmd)) {
|
|
434
444
|
json(account);
|
|
435
445
|
} else {
|
|
436
446
|
success(`Activated ${account.display_name ?? account.username} (${account.platform})`);
|
|
@@ -442,11 +452,11 @@ accountsCommand.command("activate").argument("<id>", "Account ID (from `chirpie
|
|
|
442
452
|
});
|
|
443
453
|
accountsCommand.command("deactivate").argument("<id>", "Account ID (from `chirpie accounts`)").description(
|
|
444
454
|
"Deactivate a connected account (stays connected, frees a plan slot, cancels its scheduled posts)"
|
|
445
|
-
).option("--json", "Output raw JSON").action(async (id, opts) => {
|
|
455
|
+
).option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
|
|
446
456
|
const client = getClient();
|
|
447
457
|
try {
|
|
448
458
|
const account = await client.deactivateAccount(id);
|
|
449
|
-
if (opts
|
|
459
|
+
if (wantsJson(opts, cmd)) {
|
|
450
460
|
json(account);
|
|
451
461
|
} else {
|
|
452
462
|
success(
|
|
@@ -463,20 +473,24 @@ accountsCommand.command("deactivate").argument("<id>", "Account ID (from `chirpi
|
|
|
463
473
|
process.exit(1);
|
|
464
474
|
}
|
|
465
475
|
});
|
|
466
|
-
accountsCommand.command("connect-x").description("Connect a new X/Twitter account via OAuth").action(async () => {
|
|
476
|
+
accountsCommand.command("connect-x").description("Connect a new X/Twitter account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
467
477
|
const client = getClient();
|
|
468
478
|
try {
|
|
469
479
|
const result = await client.connectXAccount();
|
|
470
|
-
|
|
471
|
-
|
|
480
|
+
if (wantsJson(opts, cmd)) {
|
|
481
|
+
json(result);
|
|
482
|
+
} else {
|
|
483
|
+
info("Open this URL in your browser to connect your X account:");
|
|
484
|
+
console.log(`
|
|
472
485
|
${result.authorization_url}
|
|
473
486
|
`);
|
|
487
|
+
}
|
|
474
488
|
} catch (err) {
|
|
475
489
|
error(err instanceof Error ? err.message : "Failed to start connection");
|
|
476
490
|
process.exit(1);
|
|
477
491
|
}
|
|
478
492
|
});
|
|
479
|
-
accountsCommand.command("connect-bluesky").description("Connect a Bluesky account via app password").requiredOption("--handle <handle>", "Bluesky handle (e.g. user.bsky.social)").option("--app-password <password>", "App password (omit to enter securely via prompt)").action(async (opts) => {
|
|
493
|
+
accountsCommand.command("connect-bluesky").description("Connect a Bluesky account via app password").requiredOption("--handle <handle>", "Bluesky handle (e.g. user.bsky.social)").option("--app-password <password>", "App password (omit to enter securely via prompt)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
480
494
|
const client = getClient();
|
|
481
495
|
try {
|
|
482
496
|
let appPassword = opts.appPassword;
|
|
@@ -492,62 +506,82 @@ accountsCommand.command("connect-bluesky").description("Connect a Bluesky accoun
|
|
|
492
506
|
identifier: opts.handle,
|
|
493
507
|
app_password: appPassword
|
|
494
508
|
});
|
|
495
|
-
|
|
509
|
+
if (wantsJson(opts, cmd)) {
|
|
510
|
+
json(result);
|
|
511
|
+
} else {
|
|
512
|
+
info(`Connected Bluesky account: ${result.username} (${result.platform_user_id})`);
|
|
513
|
+
}
|
|
496
514
|
} catch (err) {
|
|
497
515
|
error(err instanceof Error ? err.message : "Failed to connect Bluesky account");
|
|
498
516
|
process.exit(1);
|
|
499
517
|
}
|
|
500
518
|
});
|
|
501
|
-
accountsCommand.command("connect-linkedin").description("Connect a LinkedIn account via OAuth").action(async () => {
|
|
519
|
+
accountsCommand.command("connect-linkedin").description("Connect a LinkedIn account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
502
520
|
const client = getClient();
|
|
503
521
|
try {
|
|
504
522
|
const result = await client.connectLinkedInAccount();
|
|
505
|
-
|
|
506
|
-
|
|
523
|
+
if (wantsJson(opts, cmd)) {
|
|
524
|
+
json(result);
|
|
525
|
+
} else {
|
|
526
|
+
info("Open this URL in your browser to connect your LinkedIn account:");
|
|
527
|
+
console.log(`
|
|
507
528
|
${result.authorization_url}
|
|
508
529
|
`);
|
|
530
|
+
}
|
|
509
531
|
} catch (err) {
|
|
510
532
|
error(err instanceof Error ? err.message : "Failed to start LinkedIn connection");
|
|
511
533
|
process.exit(1);
|
|
512
534
|
}
|
|
513
535
|
});
|
|
514
|
-
accountsCommand.command("connect-threads").description("Connect a Threads (Meta) account via OAuth").action(async () => {
|
|
536
|
+
accountsCommand.command("connect-threads").description("Connect a Threads (Meta) account via OAuth").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
515
537
|
const client = getClient();
|
|
516
538
|
try {
|
|
517
539
|
const result = await client.connectThreadsAccount();
|
|
518
|
-
|
|
519
|
-
|
|
540
|
+
if (wantsJson(opts, cmd)) {
|
|
541
|
+
json(result);
|
|
542
|
+
} else {
|
|
543
|
+
info("Open this URL in your browser to connect your Threads account:");
|
|
544
|
+
console.log(`
|
|
520
545
|
${result.authorization_url}
|
|
521
546
|
`);
|
|
547
|
+
}
|
|
522
548
|
} catch (err) {
|
|
523
549
|
error(err instanceof Error ? err.message : "Failed to start Threads connection");
|
|
524
550
|
process.exit(1);
|
|
525
551
|
}
|
|
526
552
|
});
|
|
527
|
-
accountsCommand.command("connect-mastodon").description("Connect a Mastodon account via OAuth").requiredOption("--instance <url>", "Mastodon instance URL (e.g. https://mastodon.social)").action(async (opts) => {
|
|
553
|
+
accountsCommand.command("connect-mastodon").description("Connect a Mastodon account via OAuth").requiredOption("--instance <url>", "Mastodon instance URL (e.g. https://mastodon.social)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
528
554
|
const client = getClient();
|
|
529
555
|
try {
|
|
530
556
|
const result = await client.connectMastodonAccount({
|
|
531
557
|
platform: "mastodon",
|
|
532
558
|
instance_url: opts.instance
|
|
533
559
|
});
|
|
534
|
-
|
|
535
|
-
|
|
560
|
+
if (wantsJson(opts, cmd)) {
|
|
561
|
+
json(result);
|
|
562
|
+
} else {
|
|
563
|
+
info("Open this URL in your browser to connect your Mastodon account:");
|
|
564
|
+
console.log(`
|
|
536
565
|
${result.authorization_url}
|
|
537
566
|
`);
|
|
567
|
+
}
|
|
538
568
|
} catch (err) {
|
|
539
569
|
error(err instanceof Error ? err.message : "Failed to start Mastodon connection");
|
|
540
570
|
process.exit(1);
|
|
541
571
|
}
|
|
542
572
|
});
|
|
543
|
-
accountsCommand.command("connect-instagram").description("Connect an Instagram account via Instagram Login (OAuth)").action(async () => {
|
|
573
|
+
accountsCommand.command("connect-instagram").description("Connect an Instagram account via Instagram Login (OAuth)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
544
574
|
const client = getClient();
|
|
545
575
|
try {
|
|
546
576
|
const result = await client.connectInstagramAccount();
|
|
547
|
-
|
|
548
|
-
|
|
577
|
+
if (wantsJson(opts, cmd)) {
|
|
578
|
+
json(result);
|
|
579
|
+
} else {
|
|
580
|
+
info("Open this URL in your browser to connect your Instagram account:");
|
|
581
|
+
console.log(`
|
|
549
582
|
${result.authorization_url}
|
|
550
583
|
`);
|
|
584
|
+
}
|
|
551
585
|
} catch (err) {
|
|
552
586
|
error(err instanceof Error ? err.message : "Failed to start Instagram connection");
|
|
553
587
|
process.exit(1);
|
|
@@ -556,22 +590,26 @@ accountsCommand.command("connect-instagram").description("Connect an Instagram a
|
|
|
556
590
|
accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").option(
|
|
557
591
|
"--reconnect",
|
|
558
592
|
"Re-run the flow for an already authorized Facebook account, asking again about anything turned down last time"
|
|
559
|
-
).action(async (
|
|
593
|
+
).option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
560
594
|
const client = getClient();
|
|
561
595
|
try {
|
|
562
596
|
const result = await client.connectFacebookAccount({
|
|
563
|
-
reconnect:
|
|
597
|
+
reconnect: opts.reconnect === true
|
|
564
598
|
});
|
|
565
|
-
|
|
566
|
-
|
|
599
|
+
if (wantsJson(opts, cmd)) {
|
|
600
|
+
json(result);
|
|
601
|
+
} else {
|
|
602
|
+
info("Open this URL in your browser to connect your Facebook Page:");
|
|
603
|
+
console.log(`
|
|
567
604
|
${result.authorization_url}
|
|
568
605
|
`);
|
|
606
|
+
}
|
|
569
607
|
} catch (err) {
|
|
570
608
|
error(err instanceof Error ? err.message : "Failed to start Facebook connection");
|
|
571
609
|
process.exit(1);
|
|
572
610
|
}
|
|
573
611
|
});
|
|
574
|
-
accountsCommand.command("connect-telegram").description("Connect a Telegram bot to a channel or group").option("--bot-token <token>", "Telegram bot token (omit to enter securely via prompt)").option("--chat-id <id>", "Telegram chat ID (omit to enter via prompt)").action(async (opts) => {
|
|
612
|
+
accountsCommand.command("connect-telegram").description("Connect a Telegram bot to a channel or group").option("--bot-token <token>", "Telegram bot token (omit to enter securely via prompt)").option("--chat-id <id>", "Telegram chat ID (omit to enter via prompt)").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
575
613
|
const client = getClient();
|
|
576
614
|
try {
|
|
577
615
|
let botToken = opts.botToken;
|
|
@@ -603,14 +641,18 @@ accountsCommand.command("connect-telegram").description("Connect a Telegram bot
|
|
|
603
641
|
bot_token: botToken,
|
|
604
642
|
chat_id: chatId
|
|
605
643
|
});
|
|
606
|
-
|
|
644
|
+
if (wantsJson(opts, cmd)) {
|
|
645
|
+
json(result);
|
|
646
|
+
} else {
|
|
647
|
+
info(`Connected Telegram bot: ${result.username} (${result.platform_user_id})`);
|
|
648
|
+
}
|
|
607
649
|
} catch (err) {
|
|
608
650
|
error(err instanceof Error ? err.message : "Failed to connect Telegram bot");
|
|
609
651
|
process.exit(1);
|
|
610
652
|
}
|
|
611
653
|
});
|
|
612
654
|
var xKeysCommand = accountsCommand.command("x-keys").description("Manage your own X developer app used to connect X accounts");
|
|
613
|
-
xKeysCommand.command("set").description("Set or replace your own X developer app credentials").requiredOption("--client-id <id>", "OAuth 2.0 Client ID from developer.x.com").option("--client-secret <secret>", "OAuth 2.0 Client Secret (omit to enter securely via prompt)").option("--label <label>", "Optional name for the app").option("--json", "Output raw JSON").action(async (opts) => {
|
|
655
|
+
xKeysCommand.command("set").description("Set or replace your own X developer app credentials").requiredOption("--client-id <id>", "OAuth 2.0 Client ID from developer.x.com").option("--client-secret <secret>", "OAuth 2.0 Client Secret (omit to enter securely via prompt)").option("--label <label>", "Optional name for the app").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
614
656
|
const client = getClient();
|
|
615
657
|
try {
|
|
616
658
|
let clientSecret = opts.clientSecret;
|
|
@@ -626,7 +668,7 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
|
|
|
626
668
|
client_secret: clientSecret,
|
|
627
669
|
...opts.label ? { label: opts.label } : {}
|
|
628
670
|
});
|
|
629
|
-
if (opts
|
|
671
|
+
if (wantsJson(opts, cmd)) {
|
|
630
672
|
json(result);
|
|
631
673
|
} else {
|
|
632
674
|
success("X developer keys saved.");
|
|
@@ -639,11 +681,11 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
|
|
|
639
681
|
process.exit(1);
|
|
640
682
|
}
|
|
641
683
|
});
|
|
642
|
-
xKeysCommand.command("status").description("Show whether your own X developer app is configured").option("--json", "Output raw JSON").action(async (opts) => {
|
|
684
|
+
xKeysCommand.command("status").description("Show whether your own X developer app is configured").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
643
685
|
const client = getClient();
|
|
644
686
|
try {
|
|
645
687
|
const status = await client.getXKeysStatus();
|
|
646
|
-
if (opts
|
|
688
|
+
if (wantsJson(opts, cmd)) {
|
|
647
689
|
json(status);
|
|
648
690
|
} else if (!status.configured) {
|
|
649
691
|
info("No X developer app configured. X accounts connect through Chirpie's app.");
|
|
@@ -659,11 +701,11 @@ xKeysCommand.command("status").description("Show whether your own X developer ap
|
|
|
659
701
|
process.exit(1);
|
|
660
702
|
}
|
|
661
703
|
});
|
|
662
|
-
xKeysCommand.command("remove").description("Remove your own X developer app credentials").option("--json", "Output raw JSON").action(async (opts) => {
|
|
704
|
+
xKeysCommand.command("remove").description("Remove your own X developer app credentials").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
663
705
|
const client = getClient();
|
|
664
706
|
try {
|
|
665
707
|
const result = await client.removeXKeys();
|
|
666
|
-
if (opts
|
|
708
|
+
if (wantsJson(opts, cmd)) {
|
|
667
709
|
json(result);
|
|
668
710
|
} else {
|
|
669
711
|
success(result.message);
|
|
@@ -713,11 +755,11 @@ var analyticsCommand = new Command7("analytics").description("Get analytics for
|
|
|
713
755
|
|
|
714
756
|
// src/commands/keys.ts
|
|
715
757
|
import { Command as Command8 } from "commander";
|
|
716
|
-
var keysCommand = new Command8("keys").description("Manage API keys").option("--json", "Output raw JSON").action(async (opts) => {
|
|
758
|
+
var keysCommand = new Command8("keys").description("Manage API keys").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
717
759
|
const client = getClient();
|
|
718
760
|
try {
|
|
719
761
|
const keys = await client.listKeys();
|
|
720
|
-
if (opts
|
|
762
|
+
if (wantsJson(opts, cmd)) {
|
|
721
763
|
json(keys);
|
|
722
764
|
} else {
|
|
723
765
|
table(
|
|
@@ -737,11 +779,11 @@ var keysCommand = new Command8("keys").description("Manage API keys").option("--
|
|
|
737
779
|
process.exit(1);
|
|
738
780
|
}
|
|
739
781
|
});
|
|
740
|
-
keysCommand.command("create").description("Create a new API key").option("-n, --name <name>", "Key name").option("--json", "Output raw JSON").action(async (opts) => {
|
|
782
|
+
keysCommand.command("create").description("Create a new API key").option("-n, --name <name>", "Key name").option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
741
783
|
const client = getClient();
|
|
742
784
|
try {
|
|
743
785
|
const key = await client.createKey(opts.name);
|
|
744
|
-
if (opts
|
|
786
|
+
if (wantsJson(opts, cmd)) {
|
|
745
787
|
json(key);
|
|
746
788
|
} else {
|
|
747
789
|
success("API key created. Save it now; you won't see it again.");
|
|
@@ -754,11 +796,15 @@ keysCommand.command("create").description("Create a new API key").option("-n, --
|
|
|
754
796
|
process.exit(1);
|
|
755
797
|
}
|
|
756
798
|
});
|
|
757
|
-
keysCommand.command("revoke <id>").description("Revoke an API key").action(async (id) => {
|
|
799
|
+
keysCommand.command("revoke <id>").description("Revoke an API key").option("--json", "Output raw JSON").action(async (id, opts, cmd) => {
|
|
758
800
|
const client = getClient();
|
|
759
801
|
try {
|
|
760
802
|
await client.revokeKey(id);
|
|
761
|
-
|
|
803
|
+
if (wantsJson(opts, cmd)) {
|
|
804
|
+
json({ id, revoked: true });
|
|
805
|
+
} else {
|
|
806
|
+
success(`Key ${id} revoked`);
|
|
807
|
+
}
|
|
762
808
|
} catch (err) {
|
|
763
809
|
error(err instanceof Error ? err.message : "Failed to revoke key");
|
|
764
810
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chirpie",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.30",
|
|
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.
|
|
47
|
+
"@chirpie/sdk": "^1.0.27",
|
|
48
48
|
"commander": "^13"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|