@plosson/agentio 0.4.2 → 0.4.3

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.
@@ -2,6 +2,8 @@ import type { GmailMessage, GmailAttachmentInfo } from '../types/gmail';
2
2
  import type { GChatMessage, GChatSpace } from '../types/gchat';
3
3
  import type { GDocsDocument, GDocsCreateResult } from '../types/gdocs';
4
4
  import type { GDriveFile, GDriveDownloadResult, GDriveUploadResult } from '../types/gdrive';
5
+ import type { GCalCalendar, GCalEvent, GCalFreeBusyResponse } from '../types/gcal';
6
+ import type { GTaskList, GTask } from '../types/gtasks';
5
7
  import type { JiraProject, JiraIssue, JiraTransition, JiraCommentResult, JiraTransitionResult } from '../types/jira';
6
8
  import type { SlackSendResult } from '../types/slack';
7
9
  import type { RssFeed, RssArticle } from '../types/rss';
@@ -482,3 +484,506 @@ export function printGDriveUploaded(result: GDriveUploadResult): void {
482
484
  console.log(` Type: ${result.mimeType}`);
483
485
  if (result.webViewLink) console.log(` Link: ${result.webViewLink}`);
484
486
  }
487
+
488
+ // Google Calendar specific formatters
489
+ function getEventDateTime(dt: { dateTime?: string; date?: string }): string {
490
+ return dt.dateTime || dt.date || '';
491
+ }
492
+
493
+ export function printGCalCalendarList(calendars: GCalCalendar[]): void {
494
+ if (calendars.length === 0) {
495
+ console.log('No calendars found');
496
+ return;
497
+ }
498
+
499
+ console.log(`Calendars (${calendars.length})\n`);
500
+
501
+ for (let i = 0; i < calendars.length; i++) {
502
+ const cal = calendars[i];
503
+ const primaryBadge = cal.primary ? ' [primary]' : '';
504
+ console.log(`[${i + 1}] ${cal.summary}${primaryBadge}`);
505
+ console.log(` ID: ${cal.id}`);
506
+ console.log(` Role: ${cal.accessRole}`);
507
+ if (cal.timeZone) console.log(` Timezone: ${cal.timeZone}`);
508
+ if (cal.description) {
509
+ const desc = cal.description.length > 80
510
+ ? cal.description.slice(0, 80) + '...'
511
+ : cal.description;
512
+ console.log(` > ${desc}`);
513
+ }
514
+ console.log('');
515
+ }
516
+ }
517
+
518
+ export function printGCalEventList(events: GCalEvent[], nextPageToken?: string): void {
519
+ if (events.length === 0) {
520
+ console.log('No events found');
521
+ return;
522
+ }
523
+
524
+ console.log(`Events (${events.length})\n`);
525
+
526
+ for (let i = 0; i < events.length; i++) {
527
+ const event = events[i];
528
+ const start = getEventDateTime(event.start);
529
+ const end = getEventDateTime(event.end);
530
+ const title = event.summary || '(no title)';
531
+
532
+ console.log(`[${i + 1}] ${event.id}`);
533
+ console.log(` ${title}`);
534
+ console.log(` Start: ${start}`);
535
+ console.log(` End: ${end}`);
536
+ if (event.location) console.log(` Location: ${event.location}`);
537
+ if (event.attendees?.length) {
538
+ console.log(` Attendees: ${event.attendees.length}`);
539
+ }
540
+ if (event.hangoutLink) console.log(` Meet: ${event.hangoutLink}`);
541
+ console.log('');
542
+ }
543
+
544
+ if (nextPageToken) {
545
+ console.log(`(more results available, use --page ${nextPageToken})`);
546
+ }
547
+ }
548
+
549
+ export function printGCalEvent(event: GCalEvent): void {
550
+ console.log(`ID: ${event.id}`);
551
+ console.log(`Summary: ${event.summary || '(no title)'}`);
552
+
553
+ if (event.eventType && event.eventType !== 'default') {
554
+ console.log(`Type: ${event.eventType}`);
555
+ }
556
+
557
+ const start = getEventDateTime(event.start);
558
+ const end = getEventDateTime(event.end);
559
+ console.log(`Start: ${start}`);
560
+ console.log(`End: ${end}`);
561
+
562
+ if (event.start.timeZone) console.log(`Timezone: ${event.start.timeZone}`);
563
+ if (event.location) console.log(`Location: ${event.location}`);
564
+ if (event.description) console.log(`Description: ${event.description}`);
565
+
566
+ if (event.colorId) console.log(`Color: ${event.colorId}`);
567
+ if (event.visibility && event.visibility !== 'default') {
568
+ console.log(`Visibility: ${event.visibility}`);
569
+ }
570
+ if (event.transparency === 'transparent') {
571
+ console.log(`Show as: free`);
572
+ }
573
+
574
+ if (event.attendees?.length) {
575
+ console.log(`\nAttendees (${event.attendees.length}):`);
576
+ for (const a of event.attendees) {
577
+ const status = a.responseStatus || 'unknown';
578
+ const optional = a.optional ? ' (optional)' : '';
579
+ const organizer = a.organizer ? ' [organizer]' : '';
580
+ const self = a.self ? ' [you]' : '';
581
+ console.log(` ${a.email} - ${status}${optional}${organizer}${self}`);
582
+ }
583
+ }
584
+
585
+ if (event.recurrence?.length) {
586
+ console.log(`Recurrence: ${event.recurrence.join('; ')}`);
587
+ }
588
+
589
+ if (event.reminders) {
590
+ if (event.reminders.useDefault) {
591
+ console.log(`Reminders: (calendar default)`);
592
+ } else if (event.reminders.overrides?.length) {
593
+ const parts = event.reminders.overrides.map(r => `${r.method}:${r.minutes}m`);
594
+ console.log(`Reminders: ${parts.join(', ')}`);
595
+ }
596
+ }
597
+
598
+ if (event.hangoutLink) console.log(`Meet: ${event.hangoutLink}`);
599
+ if (event.conferenceData?.entryPoints?.length) {
600
+ for (const ep of event.conferenceData.entryPoints) {
601
+ if (ep.entryPointType === 'video') {
602
+ console.log(`Video: ${ep.uri}`);
603
+ }
604
+ }
605
+ }
606
+
607
+ if (event.htmlLink) console.log(`Link: ${event.htmlLink}`);
608
+ }
609
+
610
+ export function printGCalEventCreated(event: GCalEvent): void {
611
+ console.log('Event created');
612
+ console.log(`ID: ${event.id}`);
613
+ console.log(`Summary: ${event.summary || '(no title)'}`);
614
+ console.log(`Start: ${getEventDateTime(event.start)}`);
615
+ console.log(`End: ${getEventDateTime(event.end)}`);
616
+ if (event.hangoutLink) console.log(`Meet: ${event.hangoutLink}`);
617
+ if (event.htmlLink) console.log(`Link: ${event.htmlLink}`);
618
+ }
619
+
620
+ export function printGCalEventDeleted(calendarId: string, eventId: string): void {
621
+ console.log('Event deleted');
622
+ console.log(`Calendar: ${calendarId}`);
623
+ console.log(`Event ID: ${eventId}`);
624
+ }
625
+
626
+ export function printGCalFreeBusy(result: GCalFreeBusyResponse): void {
627
+ const calendars = Object.entries(result.calendars);
628
+ if (calendars.length === 0) {
629
+ console.log('No free/busy data');
630
+ return;
631
+ }
632
+
633
+ console.log('Free/Busy Information\n');
634
+
635
+ for (const [calendarId, data] of calendars) {
636
+ console.log(`Calendar: ${calendarId}`);
637
+ if (data.errors?.length) {
638
+ for (const err of data.errors) {
639
+ console.log(` Error: ${err.reason}`);
640
+ }
641
+ }
642
+ if (data.busy.length === 0) {
643
+ console.log(' (no busy periods)');
644
+ } else {
645
+ for (const b of data.busy) {
646
+ console.log(` Busy: ${b.start} - ${b.end}`);
647
+ }
648
+ }
649
+ console.log('');
650
+ }
651
+ }
652
+
653
+ // Google Tasks specific formatters
654
+ export function printGTasksList(taskLists: GTaskList[], nextPageToken?: string): void {
655
+ if (taskLists.length === 0) {
656
+ console.log('No task lists found');
657
+ return;
658
+ }
659
+
660
+ console.log(`Task Lists (${taskLists.length})\n`);
661
+
662
+ for (let i = 0; i < taskLists.length; i++) {
663
+ const tl = taskLists[i];
664
+ console.log(`[${i + 1}] ${tl.title}`);
665
+ console.log(` ID: ${tl.id}`);
666
+ if (tl.updated) console.log(` Updated: ${tl.updated}`);
667
+ console.log('');
668
+ }
669
+
670
+ if (nextPageToken) {
671
+ console.log(`(more results available)`);
672
+ }
673
+ }
674
+
675
+ export function printGTaskList(taskList: GTaskList): void {
676
+ console.log(`ID: ${taskList.id}`);
677
+ console.log(`Title: ${taskList.title}`);
678
+ if (taskList.updated) console.log(`Updated: ${taskList.updated}`);
679
+ if (taskList.selfLink) console.log(`Link: ${taskList.selfLink}`);
680
+ }
681
+
682
+ export function printGTaskListCreated(taskList: GTaskList): void {
683
+ console.log('Task list created');
684
+ console.log(`ID: ${taskList.id}`);
685
+ console.log(`Title: ${taskList.title}`);
686
+ }
687
+
688
+ export function printGTaskListDeleted(tasklistId: string): void {
689
+ console.log('Task list deleted');
690
+ console.log(`ID: ${tasklistId}`);
691
+ }
692
+
693
+ export function printGTasks(tasks: GTask[], nextPageToken?: string): void {
694
+ if (tasks.length === 0) {
695
+ console.log('No tasks found');
696
+ return;
697
+ }
698
+
699
+ console.log(`Tasks (${tasks.length})\n`);
700
+
701
+ for (let i = 0; i < tasks.length; i++) {
702
+ const task = tasks[i];
703
+ const statusIcon = task.status === 'completed' ? '[x]' : '[ ]';
704
+ const dueStr = task.due ? ` (due: ${task.due.split('T')[0]})` : '';
705
+
706
+ console.log(`[${i + 1}] ${statusIcon} ${task.title}${dueStr}`);
707
+ console.log(` ID: ${task.id}`);
708
+ console.log(` Status: ${task.status}`);
709
+ if (task.notes) {
710
+ const preview = task.notes.length > 60 ? task.notes.slice(0, 60) + '...' : task.notes;
711
+ console.log(` > ${preview}`);
712
+ }
713
+ console.log('');
714
+ }
715
+
716
+ if (nextPageToken) {
717
+ console.log(`(more results available)`);
718
+ }
719
+ }
720
+
721
+ export function printGTask(task: GTask): void {
722
+ console.log(`ID: ${task.id}`);
723
+ console.log(`Title: ${task.title}`);
724
+ console.log(`Status: ${task.status}`);
725
+ if (task.due) console.log(`Due: ${task.due}`);
726
+ if (task.completed) console.log(`Completed: ${task.completed}`);
727
+ if (task.updated) console.log(`Updated: ${task.updated}`);
728
+ if (task.parent) console.log(`Parent: ${task.parent}`);
729
+ if (task.webViewLink) console.log(`Link: ${task.webViewLink}`);
730
+ if (task.notes) {
731
+ console.log('---');
732
+ console.log(task.notes);
733
+ }
734
+ }
735
+
736
+ export function printGTaskCreated(task: GTask): void {
737
+ console.log('Task created');
738
+ console.log(`ID: ${task.id}`);
739
+ console.log(`Title: ${task.title}`);
740
+ console.log(`Status: ${task.status}`);
741
+ if (task.due) console.log(`Due: ${task.due}`);
742
+ if (task.webViewLink) console.log(`Link: ${task.webViewLink}`);
743
+ }
744
+
745
+ export function printGTaskDeleted(tasklistId: string, taskId: string): void {
746
+ console.log('Task deleted');
747
+ console.log(`Task List: ${tasklistId}`);
748
+ console.log(`Task ID: ${taskId}`);
749
+ }
750
+
751
+ export function printGTasksCleared(tasklistId: string): void {
752
+ console.log('Completed tasks cleared');
753
+ console.log(`Task List: ${tasklistId}`);
754
+ }
755
+
756
+ // Gateway inbox/outbox formatters
757
+ import type { InboundMessage, OutboundMessage } from '../gateway/types';
758
+
759
+ function formatTimestamp(ts: number): string {
760
+ return new Date(ts).toISOString().replace('T', ' ').split('.')[0];
761
+ }
762
+
763
+ export function printInboxMessageList(messages: InboundMessage[]): void {
764
+ if (messages.length === 0) {
765
+ console.log('No messages');
766
+ return;
767
+ }
768
+
769
+ console.log(`Messages (${messages.length})\n`);
770
+
771
+ for (let i = 0; i < messages.length; i++) {
772
+ const msg = messages[i];
773
+ const statusIcon = msg.status === 'pending' ? '○' : '●';
774
+ const senderDisplay = msg.senderName || msg.senderHandle || msg.senderId;
775
+
776
+ console.log(`[${i + 1}] ${statusIcon} ${msg.id.slice(0, 8)}`);
777
+ console.log(` Service: ${msg.service}:${msg.profile}`);
778
+ console.log(` From: ${senderDisplay}`);
779
+ console.log(` Chat: ${msg.conversationId}`);
780
+ console.log(` Date: ${formatTimestamp(msg.receivedAt)}`);
781
+ if (msg.content) {
782
+ const preview = msg.content.length > 100 ? msg.content.slice(0, 100) + '...' : msg.content;
783
+ console.log(` > ${preview}`);
784
+ }
785
+ if (msg.mediaType) {
786
+ console.log(` Media: ${msg.mediaType}`);
787
+ }
788
+ console.log('');
789
+ }
790
+ }
791
+
792
+ export function printInboxMessage(msg: InboundMessage): void {
793
+ console.log(`ID: ${msg.id}`);
794
+ console.log(`Service: ${msg.service}`);
795
+ console.log(`Profile: ${msg.profile}`);
796
+ console.log(`Status: ${msg.status}`);
797
+ console.log(`Conversation: ${msg.conversationId}`);
798
+ console.log(`Platform ID: ${msg.platformId}`);
799
+ console.log('');
800
+ console.log(`From: ${msg.senderName || 'Unknown'}`);
801
+ if (msg.senderHandle) console.log(`Handle: ${msg.senderHandle}`);
802
+ console.log(`Sender ID: ${msg.senderId}`);
803
+ console.log('');
804
+ console.log(`Received: ${formatTimestamp(msg.receivedAt)}`);
805
+ if (msg.doneAt) console.log(`Done: ${formatTimestamp(msg.doneAt)}`);
806
+ if (msg.replyToId) console.log(`Reply To: ${msg.replyToId}`);
807
+ if (msg.mediaType) {
808
+ console.log(`Media Type: ${msg.mediaType}`);
809
+ if (msg.mediaPath) console.log(`Media: ${msg.mediaPath}`);
810
+ }
811
+ console.log('---');
812
+ console.log(msg.content || '[No text content]');
813
+ }
814
+
815
+ export function printInboxStats(stats: { pending: number; done: number; total: number }): void {
816
+ console.log('Inbox Statistics');
817
+ console.log(` Pending: ${stats.pending}`);
818
+ console.log(` Done: ${stats.done}`);
819
+ console.log(` Total: ${stats.total}`);
820
+ }
821
+
822
+ export function printOutboxMessageList(messages: OutboundMessage[]): void {
823
+ if (messages.length === 0) {
824
+ console.log('No messages');
825
+ return;
826
+ }
827
+
828
+ console.log(`Messages (${messages.length})\n`);
829
+
830
+ for (let i = 0; i < messages.length; i++) {
831
+ const msg = messages[i];
832
+ let statusIcon = '○';
833
+ if (msg.status === 'sending') statusIcon = '◐';
834
+ else if (msg.status === 'sent') statusIcon = '●';
835
+ else if (msg.status === 'failed') statusIcon = '✗';
836
+
837
+ console.log(`[${i + 1}] ${statusIcon} ${msg.id.slice(0, 8)} [${msg.status}]`);
838
+ console.log(` Service: ${msg.service}:${msg.profile}`);
839
+ console.log(` To: ${msg.conversationId}`);
840
+ console.log(` Queued: ${formatTimestamp(msg.queuedAt)}`);
841
+ if (msg.sentAt) console.log(` Sent: ${formatTimestamp(msg.sentAt)}`);
842
+ if (msg.error) console.log(` Error: ${msg.error}`);
843
+ if (msg.content) {
844
+ const preview = msg.content.length > 80 ? msg.content.slice(0, 80) + '...' : msg.content;
845
+ console.log(` > ${preview}`);
846
+ }
847
+ console.log('');
848
+ }
849
+ }
850
+
851
+ export function printOutboxMessage(msg: OutboundMessage): void {
852
+ console.log(`ID: ${msg.id}`);
853
+ console.log(`Service: ${msg.service}`);
854
+ console.log(`Profile: ${msg.profile}`);
855
+ console.log(`Status: ${msg.status}`);
856
+ console.log(`Conversation: ${msg.conversationId}`);
857
+ console.log('');
858
+ console.log(`Queued: ${formatTimestamp(msg.queuedAt)}`);
859
+ if (msg.sentAt) console.log(`Sent: ${formatTimestamp(msg.sentAt)}`);
860
+ if (msg.platformId) console.log(`Platform ID: ${msg.platformId}`);
861
+ if (msg.error) console.log(`Error: ${msg.error}`);
862
+ if (msg.replyToPlatformId) console.log(`Reply To: ${msg.replyToPlatformId}`);
863
+ if (msg.mediaType) {
864
+ console.log(`Media Type: ${msg.mediaType}`);
865
+ if (msg.mediaPath) console.log(`Media: ${msg.mediaPath}`);
866
+ }
867
+ console.log('---');
868
+ console.log(msg.content || '[No text content]');
869
+ }
870
+
871
+ export function printOutboxSendResult(result: { id: string; status: string }): void {
872
+ console.log('Message queued');
873
+ console.log(` ID: ${result.id}`);
874
+ console.log(` Status: ${result.status}`);
875
+ }
876
+
877
+ export function printInboxAckResult(success: boolean, id: string): void {
878
+ if (success) {
879
+ console.log(`Acknowledged: ${id}`);
880
+ } else {
881
+ console.log(`Already acknowledged or not found: ${id}`);
882
+ }
883
+ }
884
+
885
+ export function printInboxReplyResult(result: { outboxId: string; status: string }): void {
886
+ console.log('Reply queued');
887
+ console.log(` Outbox ID: ${result.outboxId}`);
888
+ console.log(` Status: ${result.status}`);
889
+ }
890
+
891
+ // WhatsApp Group formatters
892
+ import type { WhatsAppGroup } from '../types/whatsapp';
893
+
894
+ export function printWhatsAppGroupList(groups: WhatsAppGroup[]): void {
895
+ if (groups.length === 0) {
896
+ console.log('No groups found');
897
+ return;
898
+ }
899
+
900
+ console.log(`Groups (${groups.length})\n`);
901
+
902
+ for (let i = 0; i < groups.length; i++) {
903
+ const group = groups[i];
904
+ const adminBadge = group.isSuperAdmin ? ' [owner]' : group.isAdmin ? ' [admin]' : '';
905
+ const flags: string[] = [];
906
+ if (group.announce) flags.push('announce');
907
+ if (group.restrict) flags.push('restricted');
908
+ const flagStr = flags.length > 0 ? ` (${flags.join(', ')})` : '';
909
+
910
+ console.log(`[${i + 1}] ${group.name}${adminBadge}${flagStr}`);
911
+ console.log(` ID: ${group.id}`);
912
+ console.log(` Participants: ${group.participantCount}`);
913
+ if (group.description) {
914
+ const desc = group.description.length > 80
915
+ ? group.description.slice(0, 80) + '...'
916
+ : group.description;
917
+ console.log(` > ${desc}`);
918
+ }
919
+ console.log('');
920
+ }
921
+ }
922
+
923
+ export function printWhatsAppGroup(group: WhatsAppGroup): void {
924
+ console.log(`Name: ${group.name}`);
925
+ console.log(`ID: ${group.id}`);
926
+
927
+ const roles: string[] = [];
928
+ if (group.isSuperAdmin) roles.push('owner');
929
+ else if (group.isAdmin) roles.push('admin');
930
+ if (roles.length > 0) console.log(`Your Role: ${roles.join(', ')}`);
931
+
932
+ console.log(`Participants: ${group.participantCount}`);
933
+
934
+ const settings: string[] = [];
935
+ if (group.announce) settings.push('only admins can send');
936
+ if (group.restrict) settings.push('only admins can edit info');
937
+ if (settings.length > 0) console.log(`Settings: ${settings.join(', ')}`);
938
+
939
+ if (group.owner) console.log(`Owner: ${group.owner}`);
940
+ if (group.creation) {
941
+ console.log(`Created: ${new Date(group.creation * 1000).toISOString().split('T')[0]}`);
942
+ }
943
+
944
+ if (group.description) {
945
+ console.log('---');
946
+ console.log(group.description);
947
+ }
948
+
949
+ if (group.participants && group.participants.length > 0) {
950
+ console.log('\nParticipants:');
951
+ for (const p of group.participants) {
952
+ const role = p.isSuperAdmin ? ' (owner)' : p.isAdmin ? ' (admin)' : '';
953
+ const name = p.name ? ` - ${p.name}` : '';
954
+ console.log(` ${p.phone}${name}${role}`);
955
+ }
956
+ }
957
+ }
958
+
959
+ export function printWhatsAppGroupCreated(group: WhatsAppGroup): void {
960
+ console.log('Group created');
961
+ console.log(` Name: ${group.name}`);
962
+ console.log(` ID: ${group.id}`);
963
+ console.log(` Participants: ${group.participantCount}`);
964
+ }
965
+
966
+ export function printWhatsAppGroupInvite(result: { inviteCode: string; inviteLink: string }): void {
967
+ console.log('Group invite link:');
968
+ console.log(` ${result.inviteLink}`);
969
+ console.log(` Code: ${result.inviteCode}`);
970
+ }
971
+
972
+ export function printWhatsAppGroupJoined(groupId: string): void {
973
+ console.log('Joined group');
974
+ console.log(` ID: ${groupId}`);
975
+ }
976
+
977
+ export function printWhatsAppGroupLeft(groupId: string): void {
978
+ console.log(`Left group: ${groupId}`);
979
+ }
980
+
981
+ export function printWhatsAppParticipantsResult(
982
+ action: string,
983
+ results: { participant: string; status: string }[]
984
+ ): void {
985
+ console.log(`Participants ${action}:`);
986
+ for (const r of results) {
987
+ console.log(` ${r.participant}: ${r.status}`);
988
+ }
989
+ }