chirpie 1.0.27 → 1.0.29
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 +98 -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,81 +506,110 @@ 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);
|
|
554
588
|
}
|
|
555
589
|
});
|
|
556
|
-
accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").
|
|
590
|
+
accountsCommand.command("connect-facebook").description("Connect a Facebook Page via Facebook Login (OAuth)").option(
|
|
591
|
+
"--reconnect",
|
|
592
|
+
"Re-run the flow for an already authorized Facebook account, asking again about anything turned down last time"
|
|
593
|
+
).option("--json", "Output raw JSON").action(async (opts, cmd) => {
|
|
557
594
|
const client = getClient();
|
|
558
595
|
try {
|
|
559
|
-
const result = await client.connectFacebookAccount(
|
|
560
|
-
|
|
561
|
-
|
|
596
|
+
const result = await client.connectFacebookAccount({
|
|
597
|
+
reconnect: opts.reconnect === true
|
|
598
|
+
});
|
|
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(`
|
|
562
604
|
${result.authorization_url}
|
|
563
605
|
`);
|
|
606
|
+
}
|
|
564
607
|
} catch (err) {
|
|
565
608
|
error(err instanceof Error ? err.message : "Failed to start Facebook connection");
|
|
566
609
|
process.exit(1);
|
|
567
610
|
}
|
|
568
611
|
});
|
|
569
|
-
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) => {
|
|
570
613
|
const client = getClient();
|
|
571
614
|
try {
|
|
572
615
|
let botToken = opts.botToken;
|
|
@@ -598,14 +641,18 @@ accountsCommand.command("connect-telegram").description("Connect a Telegram bot
|
|
|
598
641
|
bot_token: botToken,
|
|
599
642
|
chat_id: chatId
|
|
600
643
|
});
|
|
601
|
-
|
|
644
|
+
if (wantsJson(opts, cmd)) {
|
|
645
|
+
json(result);
|
|
646
|
+
} else {
|
|
647
|
+
info(`Connected Telegram bot: ${result.username} (${result.platform_user_id})`);
|
|
648
|
+
}
|
|
602
649
|
} catch (err) {
|
|
603
650
|
error(err instanceof Error ? err.message : "Failed to connect Telegram bot");
|
|
604
651
|
process.exit(1);
|
|
605
652
|
}
|
|
606
653
|
});
|
|
607
654
|
var xKeysCommand = accountsCommand.command("x-keys").description("Manage your own X developer app used to connect X accounts");
|
|
608
|
-
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) => {
|
|
609
656
|
const client = getClient();
|
|
610
657
|
try {
|
|
611
658
|
let clientSecret = opts.clientSecret;
|
|
@@ -621,7 +668,7 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
|
|
|
621
668
|
client_secret: clientSecret,
|
|
622
669
|
...opts.label ? { label: opts.label } : {}
|
|
623
670
|
});
|
|
624
|
-
if (opts
|
|
671
|
+
if (wantsJson(opts, cmd)) {
|
|
625
672
|
json(result);
|
|
626
673
|
} else {
|
|
627
674
|
success("X developer keys saved.");
|
|
@@ -634,11 +681,11 @@ xKeysCommand.command("set").description("Set or replace your own X developer app
|
|
|
634
681
|
process.exit(1);
|
|
635
682
|
}
|
|
636
683
|
});
|
|
637
|
-
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) => {
|
|
638
685
|
const client = getClient();
|
|
639
686
|
try {
|
|
640
687
|
const status = await client.getXKeysStatus();
|
|
641
|
-
if (opts
|
|
688
|
+
if (wantsJson(opts, cmd)) {
|
|
642
689
|
json(status);
|
|
643
690
|
} else if (!status.configured) {
|
|
644
691
|
info("No X developer app configured. X accounts connect through Chirpie's app.");
|
|
@@ -654,11 +701,11 @@ xKeysCommand.command("status").description("Show whether your own X developer ap
|
|
|
654
701
|
process.exit(1);
|
|
655
702
|
}
|
|
656
703
|
});
|
|
657
|
-
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) => {
|
|
658
705
|
const client = getClient();
|
|
659
706
|
try {
|
|
660
707
|
const result = await client.removeXKeys();
|
|
661
|
-
if (opts
|
|
708
|
+
if (wantsJson(opts, cmd)) {
|
|
662
709
|
json(result);
|
|
663
710
|
} else {
|
|
664
711
|
success(result.message);
|
|
@@ -708,11 +755,11 @@ var analyticsCommand = new Command7("analytics").description("Get analytics for
|
|
|
708
755
|
|
|
709
756
|
// src/commands/keys.ts
|
|
710
757
|
import { Command as Command8 } from "commander";
|
|
711
|
-
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) => {
|
|
712
759
|
const client = getClient();
|
|
713
760
|
try {
|
|
714
761
|
const keys = await client.listKeys();
|
|
715
|
-
if (opts
|
|
762
|
+
if (wantsJson(opts, cmd)) {
|
|
716
763
|
json(keys);
|
|
717
764
|
} else {
|
|
718
765
|
table(
|
|
@@ -732,11 +779,11 @@ var keysCommand = new Command8("keys").description("Manage API keys").option("--
|
|
|
732
779
|
process.exit(1);
|
|
733
780
|
}
|
|
734
781
|
});
|
|
735
|
-
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) => {
|
|
736
783
|
const client = getClient();
|
|
737
784
|
try {
|
|
738
785
|
const key = await client.createKey(opts.name);
|
|
739
|
-
if (opts
|
|
786
|
+
if (wantsJson(opts, cmd)) {
|
|
740
787
|
json(key);
|
|
741
788
|
} else {
|
|
742
789
|
success("API key created. Save it now; you won't see it again.");
|
|
@@ -749,11 +796,15 @@ keysCommand.command("create").description("Create a new API key").option("-n, --
|
|
|
749
796
|
process.exit(1);
|
|
750
797
|
}
|
|
751
798
|
});
|
|
752
|
-
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) => {
|
|
753
800
|
const client = getClient();
|
|
754
801
|
try {
|
|
755
802
|
await client.revokeKey(id);
|
|
756
|
-
|
|
803
|
+
if (wantsJson(opts, cmd)) {
|
|
804
|
+
json({ id, revoked: true });
|
|
805
|
+
} else {
|
|
806
|
+
success(`Key ${id} revoked`);
|
|
807
|
+
}
|
|
757
808
|
} catch (err) {
|
|
758
809
|
error(err instanceof Error ? err.message : "Failed to revoke key");
|
|
759
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.29",
|
|
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.26",
|
|
48
48
|
"commander": "^13"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|