@marcfargas/go-easy 0.0.1 → 0.3.0

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 (113) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/LICENSE +21 -0
  3. package/README.md +224 -0
  4. package/dist/auth-flow.d.ts +50 -0
  5. package/dist/auth-flow.d.ts.map +1 -0
  6. package/dist/auth-flow.js +219 -0
  7. package/dist/auth-flow.js.map +1 -0
  8. package/dist/auth-server.d.ts +18 -0
  9. package/dist/auth-server.d.ts.map +1 -0
  10. package/dist/auth-server.js +327 -0
  11. package/dist/auth-server.js.map +1 -0
  12. package/dist/auth-store.d.ts +81 -0
  13. package/dist/auth-store.d.ts.map +1 -0
  14. package/dist/auth-store.js +185 -0
  15. package/dist/auth-store.js.map +1 -0
  16. package/dist/auth.d.ts +47 -0
  17. package/dist/auth.d.ts.map +1 -0
  18. package/dist/auth.js +131 -0
  19. package/dist/auth.js.map +1 -0
  20. package/dist/bin/calendar.d.ts +17 -0
  21. package/dist/bin/calendar.d.ts.map +1 -0
  22. package/dist/bin/calendar.js +224 -0
  23. package/dist/bin/calendar.js.map +1 -0
  24. package/dist/bin/drive.d.ts +18 -0
  25. package/dist/bin/drive.d.ts.map +1 -0
  26. package/dist/bin/drive.js +205 -0
  27. package/dist/bin/drive.js.map +1 -0
  28. package/dist/bin/easy.d.ts +11 -0
  29. package/dist/bin/easy.d.ts.map +1 -0
  30. package/dist/bin/easy.js +140 -0
  31. package/dist/bin/easy.js.map +1 -0
  32. package/dist/bin/gmail.d.ts +25 -0
  33. package/dist/bin/gmail.d.ts.map +1 -0
  34. package/dist/bin/gmail.js +243 -0
  35. package/dist/bin/gmail.js.map +1 -0
  36. package/dist/bin/tasks.d.ts +17 -0
  37. package/dist/bin/tasks.d.ts.map +1 -0
  38. package/dist/bin/tasks.js +190 -0
  39. package/dist/bin/tasks.js.map +1 -0
  40. package/dist/calendar/helpers.d.ts +35 -0
  41. package/dist/calendar/helpers.d.ts.map +1 -0
  42. package/dist/calendar/helpers.js +178 -0
  43. package/dist/calendar/helpers.js.map +1 -0
  44. package/dist/calendar/index.d.ts +64 -0
  45. package/dist/calendar/index.d.ts.map +1 -0
  46. package/dist/calendar/index.js +210 -0
  47. package/dist/calendar/index.js.map +1 -0
  48. package/dist/calendar/types.d.ts +191 -0
  49. package/dist/calendar/types.d.ts.map +1 -0
  50. package/dist/calendar/types.js +12 -0
  51. package/dist/calendar/types.js.map +1 -0
  52. package/dist/drive/helpers.d.ts +22 -0
  53. package/dist/drive/helpers.d.ts.map +1 -0
  54. package/dist/drive/helpers.js +85 -0
  55. package/dist/drive/helpers.js.map +1 -0
  56. package/dist/drive/index.d.ts +114 -0
  57. package/dist/drive/index.d.ts.map +1 -0
  58. package/dist/drive/index.js +418 -0
  59. package/dist/drive/index.js.map +1 -0
  60. package/dist/drive/types.d.ts +91 -0
  61. package/dist/drive/types.d.ts.map +1 -0
  62. package/dist/drive/types.js +5 -0
  63. package/dist/drive/types.js.map +1 -0
  64. package/dist/errors.d.ts +58 -0
  65. package/dist/errors.d.ts.map +1 -0
  66. package/dist/errors.js +73 -0
  67. package/dist/errors.js.map +1 -0
  68. package/dist/gmail/helpers.d.ts +59 -0
  69. package/dist/gmail/helpers.d.ts.map +1 -0
  70. package/dist/gmail/helpers.js +308 -0
  71. package/dist/gmail/helpers.js.map +1 -0
  72. package/dist/gmail/index.d.ts +95 -0
  73. package/dist/gmail/index.d.ts.map +1 -0
  74. package/dist/gmail/index.js +465 -0
  75. package/dist/gmail/index.js.map +1 -0
  76. package/dist/gmail/markdown.d.ts +22 -0
  77. package/dist/gmail/markdown.d.ts.map +1 -0
  78. package/dist/gmail/markdown.js +30 -0
  79. package/dist/gmail/markdown.js.map +1 -0
  80. package/dist/gmail/types.d.ts +154 -0
  81. package/dist/gmail/types.d.ts.map +1 -0
  82. package/dist/gmail/types.js +5 -0
  83. package/dist/gmail/types.js.map +1 -0
  84. package/dist/index.d.ts +27 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +29 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/safety.d.ts +58 -0
  89. package/dist/safety.d.ts.map +1 -0
  90. package/dist/safety.js +61 -0
  91. package/dist/safety.js.map +1 -0
  92. package/dist/scopes.d.ts +16 -0
  93. package/dist/scopes.d.ts.map +1 -0
  94. package/dist/scopes.js +28 -0
  95. package/dist/scopes.js.map +1 -0
  96. package/dist/tasks/helpers.d.ts +10 -0
  97. package/dist/tasks/helpers.d.ts.map +1 -0
  98. package/dist/tasks/helpers.js +33 -0
  99. package/dist/tasks/helpers.js.map +1 -0
  100. package/dist/tasks/index.d.ts +63 -0
  101. package/dist/tasks/index.d.ts.map +1 -0
  102. package/dist/tasks/index.js +253 -0
  103. package/dist/tasks/index.js.map +1 -0
  104. package/dist/tasks/types.d.ts +79 -0
  105. package/dist/tasks/types.d.ts.map +1 -0
  106. package/dist/tasks/types.js +5 -0
  107. package/dist/tasks/types.js.map +1 -0
  108. package/package.json +73 -4
  109. package/skills/go-easy/SKILL.md +146 -0
  110. package/skills/go-easy/calendar.md +366 -0
  111. package/skills/go-easy/drive.md +309 -0
  112. package/skills/go-easy/gmail.md +478 -0
  113. package/skills/go-easy/tasks.md +260 -0
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-easy — Umbrella CLI for cross-service operations.
4
+ *
5
+ * Usage:
6
+ * go-easy auth list — List configured accounts
7
+ * go-easy auth add <email> — Add or upgrade account (Phase 2)
8
+ * go-easy auth remove <email> --confirm — Remove account (Phase 3)
9
+ */
10
+ import { listAllAccounts, clearAuthCache, } from '../auth.js';
11
+ import { readAccountStore, writeAccountStore, findAccount, removeAccount, } from '../auth-store.js';
12
+ import { authAdd as authAddFlow } from '../auth-flow.js';
13
+ import { GoEasyError } from '../errors.js';
14
+ const args = process.argv.slice(2);
15
+ function usage() {
16
+ console.log(JSON.stringify({
17
+ error: 'USAGE',
18
+ message: 'go-easy <command> [args...]',
19
+ commands: {
20
+ 'auth list': 'List configured accounts and their scopes',
21
+ 'auth add <email>': 'Add or upgrade an account (starts auth flow)',
22
+ 'auth remove <email> --confirm': 'Remove an account',
23
+ },
24
+ }));
25
+ process.exit(1);
26
+ }
27
+ /** Parse --key=value flags from args */
28
+ function parseFlags(argv) {
29
+ const flags = {};
30
+ for (const arg of argv) {
31
+ const m = arg.match(/^--([a-z-]+)(?:=(.*))?$/);
32
+ if (m)
33
+ flags[m[1]] = m[2] ?? 'true';
34
+ }
35
+ return flags;
36
+ }
37
+ /** Positional args (non-flag) */
38
+ function positionals(argv) {
39
+ return argv.filter((a) => !a.startsWith('--'));
40
+ }
41
+ async function main() {
42
+ if (args.length < 1)
43
+ usage();
44
+ const [group, subcommand, ...rest] = args;
45
+ if (group !== 'auth') {
46
+ usage();
47
+ }
48
+ switch (subcommand) {
49
+ case 'list':
50
+ await authList();
51
+ break;
52
+ case 'add':
53
+ await authAdd(rest);
54
+ break;
55
+ case 'remove':
56
+ await authRemove(rest);
57
+ break;
58
+ default:
59
+ usage();
60
+ }
61
+ }
62
+ // ─── auth list ─────────────────────────────────────────────
63
+ async function authList() {
64
+ const accounts = await listAllAccounts();
65
+ console.log(JSON.stringify({ accounts }, null, 2));
66
+ }
67
+ // ─── auth add ──────────────────────────────────────────────
68
+ async function authAdd(argv) {
69
+ const pos = positionals(argv);
70
+ const email = pos[0];
71
+ if (!email) {
72
+ console.log(JSON.stringify({
73
+ error: 'USAGE',
74
+ message: 'go-easy auth add <email>',
75
+ }));
76
+ process.exit(1);
77
+ }
78
+ const result = await authAddFlow(email);
79
+ console.log(JSON.stringify(result, null, 2));
80
+ }
81
+ // ─── auth remove ───────────────────────────────────────────
82
+ async function authRemove(argv) {
83
+ const pos = positionals(argv);
84
+ const flags = parseFlags(argv);
85
+ const email = pos[0];
86
+ if (!email) {
87
+ console.log(JSON.stringify({
88
+ error: 'USAGE',
89
+ message: 'go-easy auth remove <email> --confirm',
90
+ }));
91
+ process.exit(1);
92
+ }
93
+ const store = await readAccountStore();
94
+ if (!store) {
95
+ console.log(JSON.stringify({
96
+ error: 'AUTH_NO_ACCOUNT',
97
+ message: 'No accounts configured',
98
+ }));
99
+ process.exit(1);
100
+ }
101
+ const account = findAccount(store, email);
102
+ if (!account) {
103
+ console.log(JSON.stringify({
104
+ error: 'AUTH_NO_ACCOUNT',
105
+ message: `Account "${email}" not found`,
106
+ }));
107
+ process.exit(1);
108
+ }
109
+ // Safety gate
110
+ if (flags.confirm !== 'true') {
111
+ console.log(JSON.stringify({
112
+ blocked: true,
113
+ operation: 'go-easy.auth.remove',
114
+ description: `Remove account ${account.email} and all its tokens`,
115
+ hint: 'Add --confirm to execute',
116
+ }));
117
+ process.exit(2);
118
+ }
119
+ removeAccount(store, email);
120
+ await writeAccountStore(store);
121
+ clearAuthCache();
122
+ console.log(JSON.stringify({
123
+ ok: true,
124
+ removed: account.email,
125
+ }));
126
+ }
127
+ // ─── Main ──────────────────────────────────────────────────
128
+ main().catch((err) => {
129
+ if (err instanceof GoEasyError) {
130
+ console.error(JSON.stringify(err.toJSON()));
131
+ }
132
+ else {
133
+ console.error(JSON.stringify({
134
+ error: 'UNKNOWN',
135
+ message: err instanceof Error ? err.message : String(err),
136
+ }));
137
+ }
138
+ process.exit(1);
139
+ });
140
+ //# sourceMappingURL=easy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"easy.js","sourceRoot":"","sources":["../../src/bin/easy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-gmail — Gateway CLI for Gmail operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-gmail <account> <command> [args...]
9
+ * go-gmail marc@blegal.eu search "from:client is:unread"
10
+ * go-gmail marc@blegal.eu get <messageId>
11
+ * go-gmail marc@blegal.eu thread <threadId>
12
+ * go-gmail marc@blegal.eu labels
13
+ * go-gmail marc@blegal.eu send --to=x@y.com --subject="Hi" --body-text-file=body.txt --confirm
14
+ *
15
+ * Body content:
16
+ * --body-text-file=<path> Read plain text body from file (UTF-8)
17
+ * --body-html-file=<path> Read HTML body from file (UTF-8)
18
+ * --body-md-file=<path> Read Markdown body from file (auto-converted to HTML)
19
+ *
20
+ * Safety:
21
+ * Destructive operations (send, reply, forward, sendDraft) require --confirm flag.
22
+ * Without --confirm, the command shows what WOULD happen and exits.
23
+ */
24
+ export {};
25
+ //# sourceMappingURL=gmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.d.ts","sourceRoot":"","sources":["../../src/bin/gmail.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;GAqBG"}
@@ -0,0 +1,243 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-gmail — Gateway CLI for Gmail operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-gmail <account> <command> [args...]
9
+ * go-gmail marc@blegal.eu search "from:client is:unread"
10
+ * go-gmail marc@blegal.eu get <messageId>
11
+ * go-gmail marc@blegal.eu thread <threadId>
12
+ * go-gmail marc@blegal.eu labels
13
+ * go-gmail marc@blegal.eu send --to=x@y.com --subject="Hi" --body-text-file=body.txt --confirm
14
+ *
15
+ * Body content:
16
+ * --body-text-file=<path> Read plain text body from file (UTF-8)
17
+ * --body-html-file=<path> Read HTML body from file (UTF-8)
18
+ * --body-md-file=<path> Read Markdown body from file (auto-converted to HTML)
19
+ *
20
+ * Safety:
21
+ * Destructive operations (send, reply, forward, sendDraft) require --confirm flag.
22
+ * Without --confirm, the command shows what WOULD happen and exits.
23
+ */
24
+ import { readFileSync } from 'node:fs';
25
+ import { getAuth } from '../auth.js';
26
+ import { setSafetyContext } from '../safety.js';
27
+ import * as gmail from '../gmail/index.js';
28
+ const args = process.argv.slice(2);
29
+ function usage() {
30
+ console.log(JSON.stringify({
31
+ error: 'USAGE',
32
+ message: 'go-gmail <account> <command> [args...]',
33
+ commands: {
34
+ search: 'go-gmail <account> search "<query>" [--max=N] [--page-token=<token>]',
35
+ get: 'go-gmail <account> get <messageId>',
36
+ thread: 'go-gmail <account> thread <threadId>',
37
+ labels: 'go-gmail <account> labels',
38
+ send: 'go-gmail <account> send --to=<addr> --subject="..." --body-text-file=body.txt [--cc=<addr>] [--bcc=<addr>] [--confirm]',
39
+ reply: 'go-gmail <account> reply <messageId> --body-text-file=reply.txt [--reply-all] --confirm',
40
+ forward: 'go-gmail <account> forward <messageId> --to=<addr> [--body-text-file=note.txt] [--exclude=file1,file2] [--send-now --confirm]',
41
+ draft: 'go-gmail <account> draft --to=<addr> --subject="..." --body-text-file=body.txt [--cc=<addr>] [--bcc=<addr>] [--in-reply-to=<messageId>]',
42
+ 'send-draft': 'go-gmail <account> send-draft <draftId> [--confirm]',
43
+ drafts: 'go-gmail <account> drafts [--max=N] [--page-token=<token>]',
44
+ 'batch-label': 'go-gmail <account> batch-label --ids=id1,id2 --add=LABEL_ID --remove=LABEL_ID',
45
+ attachment: 'go-gmail <account> attachment <messageId> <attachmentId>',
46
+ profile: 'go-gmail <account> profile',
47
+ },
48
+ bodyFlags: {
49
+ '--body-text-file': 'Read plain text body from file (UTF-8)',
50
+ '--body-html-file': 'Read HTML body from file (UTF-8)',
51
+ '--body-md-file': 'Read Markdown body from file (auto-converted to HTML)',
52
+ },
53
+ }, null, 2));
54
+ process.exit(1);
55
+ }
56
+ /** Parse --key=value flags from args */
57
+ function parseFlags(args) {
58
+ const flags = {};
59
+ for (const arg of args) {
60
+ const match = arg.match(/^--([^=]+)(?:=(.*))?$/s);
61
+ if (match) {
62
+ flags[match[1]] = match[2] ?? 'true';
63
+ }
64
+ }
65
+ return flags;
66
+ }
67
+ /** Get positional args (non-flag) */
68
+ function positional(args) {
69
+ return args.filter((a) => !a.startsWith('--'));
70
+ }
71
+ /**
72
+ * Read body content from file flags.
73
+ * Returns { body?, html?, markdown? } for SendOptions.
74
+ */
75
+ function readBodyFlags(flags) {
76
+ const result = {};
77
+ if (flags['body-text-file']) {
78
+ result.body = readFileSync(flags['body-text-file'], 'utf-8');
79
+ }
80
+ if (flags['body-html-file']) {
81
+ result.html = readFileSync(flags['body-html-file'], 'utf-8');
82
+ }
83
+ if (flags['body-md-file']) {
84
+ result.markdown = readFileSync(flags['body-md-file'], 'utf-8');
85
+ }
86
+ return result;
87
+ }
88
+ async function main() {
89
+ if (args.length < 2)
90
+ usage();
91
+ const account = args[0];
92
+ const command = args[1];
93
+ const rest = args.slice(2);
94
+ const flags = parseFlags(rest);
95
+ const pos = positional(rest);
96
+ // Set up safety context: --confirm flag allows destructive ops
97
+ const hasConfirm = 'confirm' in flags;
98
+ setSafetyContext({
99
+ confirm: async (op) => {
100
+ if (!hasConfirm) {
101
+ console.log(JSON.stringify({
102
+ blocked: true,
103
+ operation: op.name,
104
+ description: op.description,
105
+ details: op.details,
106
+ hint: 'Add --confirm to execute this operation',
107
+ }, null, 2));
108
+ process.exit(2);
109
+ }
110
+ return true;
111
+ },
112
+ });
113
+ const auth = await getAuth('gmail', account);
114
+ try {
115
+ let result;
116
+ switch (command) {
117
+ case 'profile':
118
+ result = { email: await gmail.getProfile(auth) };
119
+ break;
120
+ case 'search':
121
+ result = await gmail.search(auth, {
122
+ query: pos[0] ?? '',
123
+ maxResults: flags.max ? parseInt(flags.max) : undefined,
124
+ pageToken: flags['page-token'],
125
+ });
126
+ break;
127
+ case 'get':
128
+ if (!pos[0])
129
+ usage();
130
+ result = await gmail.getMessage(auth, pos[0]);
131
+ break;
132
+ case 'thread':
133
+ if (!pos[0])
134
+ usage();
135
+ result = await gmail.getThread(auth, pos[0]);
136
+ break;
137
+ case 'labels':
138
+ result = await gmail.listLabels(auth);
139
+ break;
140
+ case 'send':
141
+ result = await gmail.send(auth, {
142
+ to: flags.to ?? '',
143
+ cc: flags.cc,
144
+ bcc: flags.bcc,
145
+ subject: flags.subject ?? '',
146
+ ...readBodyFlags(flags),
147
+ attachments: flags.attach?.split(','),
148
+ });
149
+ break;
150
+ case 'reply': {
151
+ if (!pos[0])
152
+ usage();
153
+ const origMsg = await gmail.getMessage(auth, pos[0]);
154
+ result = await gmail.reply(auth, {
155
+ threadId: origMsg.threadId,
156
+ messageId: pos[0],
157
+ ...readBodyFlags(flags),
158
+ replyAll: 'reply-all' in flags,
159
+ });
160
+ break;
161
+ }
162
+ case 'forward':
163
+ if (!pos[0])
164
+ usage();
165
+ result = await gmail.forward(auth, {
166
+ messageId: pos[0],
167
+ to: flags.to ?? '',
168
+ ...readBodyFlags(flags),
169
+ includeAttachments: flags.include ? flags.include.split(',') : true,
170
+ excludeAttachments: flags.exclude?.split(','),
171
+ sendNow: 'send-now' in flags,
172
+ keepInThread: !('no-thread' in flags),
173
+ });
174
+ break;
175
+ case 'draft': {
176
+ let threadId;
177
+ let extraHeaders;
178
+ // If --in-reply-to is provided, fetch the original message to get threadId and Message-ID
179
+ const inReplyToId = flags['in-reply-to'];
180
+ if (inReplyToId) {
181
+ const original = await gmail.getMessage(auth, inReplyToId);
182
+ threadId = original.threadId;
183
+ const messageIdRef = original.rfc822MessageId ?? `<${inReplyToId}>`;
184
+ extraHeaders = {
185
+ 'In-Reply-To': messageIdRef,
186
+ 'References': messageIdRef,
187
+ };
188
+ }
189
+ result = await gmail.createDraft(auth, {
190
+ to: flags.to ?? '',
191
+ cc: flags.cc,
192
+ bcc: flags.bcc,
193
+ subject: flags.subject ?? '',
194
+ ...readBodyFlags(flags),
195
+ threadId,
196
+ extraHeaders,
197
+ });
198
+ break;
199
+ }
200
+ case 'send-draft':
201
+ if (!pos[0])
202
+ usage();
203
+ result = await gmail.sendDraft(auth, pos[0]);
204
+ break;
205
+ case 'drafts':
206
+ result = await gmail.listDrafts(auth, flags.max ? parseInt(flags.max) : undefined, flags['page-token']);
207
+ break;
208
+ case 'batch-label':
209
+ result = await gmail.batchModifyLabels(auth, {
210
+ messageIds: (flags.ids ?? '').split(','),
211
+ addLabelIds: flags.add?.split(','),
212
+ removeLabelIds: flags.remove?.split(','),
213
+ });
214
+ break;
215
+ case 'attachment': {
216
+ if (!pos[0] || !pos[1])
217
+ usage();
218
+ const buf = await gmail.getAttachmentContent(auth, pos[0], pos[1]);
219
+ // Output base64 for binary safety
220
+ result = { data: buf.toString('base64'), size: buf.length };
221
+ break;
222
+ }
223
+ default:
224
+ usage();
225
+ }
226
+ console.log(JSON.stringify(result, null, 2));
227
+ }
228
+ catch (err) {
229
+ const e = err;
230
+ if (typeof e.toJSON === 'function') {
231
+ console.error(JSON.stringify(e.toJSON(), null, 2));
232
+ }
233
+ else {
234
+ console.error(JSON.stringify({
235
+ error: e.code ?? 'UNKNOWN',
236
+ message: e.message ?? String(err),
237
+ }, null, 2));
238
+ }
239
+ process.exit(1);
240
+ }
241
+ }
242
+ main();
243
+ //# sourceMappingURL=gmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gmail.js","sourceRoot":"","sources":["../../src/bin/gmail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-tasks — Gateway CLI for Google Tasks operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-tasks <account> <command> [args...]
9
+ * go-tasks marc@blegal.eu lists
10
+ * go-tasks marc@blegal.eu tasks <listId>
11
+ * go-tasks marc@blegal.eu add <listId> --title="Buy milk"
12
+ *
13
+ * Safety:
14
+ * Destructive operations (delete, clear) require --confirm flag.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/bin/tasks.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * go-tasks — Gateway CLI for Google Tasks operations.
4
+ *
5
+ * Always outputs JSON. Designed for agent consumption.
6
+ *
7
+ * Usage:
8
+ * go-tasks <account> <command> [args...]
9
+ * go-tasks marc@blegal.eu lists
10
+ * go-tasks marc@blegal.eu tasks <listId>
11
+ * go-tasks marc@blegal.eu add <listId> --title="Buy milk"
12
+ *
13
+ * Safety:
14
+ * Destructive operations (delete, clear) require --confirm flag.
15
+ */
16
+ import { getAuth } from '../auth.js';
17
+ import { setSafetyContext } from '../safety.js';
18
+ import * as tasks from '../tasks/index.js';
19
+ const args = process.argv.slice(2);
20
+ function usage() {
21
+ console.log(JSON.stringify({
22
+ error: 'USAGE',
23
+ message: 'go-tasks <account> <command> [args...]',
24
+ commands: {
25
+ lists: 'go-tasks <account> lists',
26
+ tasks: 'go-tasks <account> tasks <listId> [--max=N] [--page-token=<token>] [--show-completed] [--show-hidden]',
27
+ get: 'go-tasks <account> get <listId> <taskId>',
28
+ add: 'go-tasks <account> add <listId> --title="..." [--notes="..."] [--due=YYYY-MM-DD] [--parent=<taskId>]',
29
+ update: 'go-tasks <account> update <listId> <taskId> [--title="..."] [--notes="..."] [--due=YYYY-MM-DD] [--status=completed|needsAction]',
30
+ complete: 'go-tasks <account> complete <listId> <taskId>',
31
+ move: 'go-tasks <account> move <listId> <taskId> [--parent=<taskId>] [--previous=<taskId>]',
32
+ delete: 'go-tasks <account> delete <listId> <taskId> --confirm',
33
+ 'create-list': 'go-tasks <account> create-list --title="..."',
34
+ 'delete-list': 'go-tasks <account> delete-list <listId> --confirm',
35
+ clear: 'go-tasks <account> clear <listId> --confirm',
36
+ },
37
+ }, null, 2));
38
+ process.exit(1);
39
+ }
40
+ /** Parse --key=value flags from args */
41
+ function parseFlags(argv) {
42
+ const flags = {};
43
+ for (const arg of argv) {
44
+ const match = arg.match(/^--([^=]+)(?:=(.*))?$/s);
45
+ if (match) {
46
+ flags[match[1]] = match[2] ?? 'true';
47
+ }
48
+ }
49
+ return flags;
50
+ }
51
+ /** Get positional args (non-flag) */
52
+ function positional(argv) {
53
+ return argv.filter((a) => !a.startsWith('--'));
54
+ }
55
+ async function main() {
56
+ if (args.length < 2)
57
+ usage();
58
+ const account = args[0];
59
+ const command = args[1];
60
+ const rest = args.slice(2);
61
+ const flags = parseFlags(rest);
62
+ const pos = positional(rest);
63
+ // Set up safety context
64
+ const hasConfirm = 'confirm' in flags;
65
+ setSafetyContext({
66
+ confirm: async (op) => {
67
+ if (!hasConfirm) {
68
+ console.log(JSON.stringify({
69
+ blocked: true,
70
+ operation: op.name,
71
+ description: op.description,
72
+ details: op.details,
73
+ hint: 'Add --confirm to execute this operation',
74
+ }, null, 2));
75
+ process.exit(2);
76
+ }
77
+ return true;
78
+ },
79
+ });
80
+ let auth;
81
+ try {
82
+ auth = await getAuth('tasks', account);
83
+ }
84
+ catch (err) {
85
+ const e = err;
86
+ if (typeof e.toJSON === 'function') {
87
+ console.error(JSON.stringify(e.toJSON(), null, 2));
88
+ }
89
+ else {
90
+ console.error(JSON.stringify({
91
+ error: e.code ?? 'UNKNOWN',
92
+ message: e.message ?? String(err),
93
+ }, null, 2));
94
+ }
95
+ process.exit(1);
96
+ }
97
+ try {
98
+ let result;
99
+ switch (command) {
100
+ case 'lists':
101
+ result = await tasks.listTaskLists(auth);
102
+ break;
103
+ case 'tasks':
104
+ if (!pos[0])
105
+ usage();
106
+ result = await tasks.listTasks(auth, pos[0], {
107
+ maxResults: flags.max ? parseInt(flags.max) : undefined,
108
+ pageToken: flags['page-token'],
109
+ showCompleted: 'show-completed' in flags ? true : undefined,
110
+ showHidden: 'show-hidden' in flags ? true : undefined,
111
+ });
112
+ break;
113
+ case 'get':
114
+ if (!pos[0] || !pos[1])
115
+ usage();
116
+ result = await tasks.getTask(auth, pos[0], pos[1]);
117
+ break;
118
+ case 'add':
119
+ if (!pos[0])
120
+ usage();
121
+ result = await tasks.createTask(auth, pos[0], {
122
+ title: flags.title ?? '',
123
+ notes: flags.notes,
124
+ due: flags.due,
125
+ parent: flags.parent,
126
+ previous: flags.previous,
127
+ });
128
+ break;
129
+ case 'update':
130
+ if (!pos[0] || !pos[1])
131
+ usage();
132
+ result = await tasks.updateTask(auth, pos[0], pos[1], {
133
+ title: flags.title,
134
+ notes: flags.notes,
135
+ due: flags.due,
136
+ status: flags.status,
137
+ });
138
+ break;
139
+ case 'complete':
140
+ if (!pos[0] || !pos[1])
141
+ usage();
142
+ result = await tasks.completeTask(auth, pos[0], pos[1]);
143
+ break;
144
+ case 'move':
145
+ if (!pos[0] || !pos[1])
146
+ usage();
147
+ result = await tasks.moveTask(auth, pos[0], pos[1], {
148
+ parent: flags.parent,
149
+ previous: flags.previous,
150
+ });
151
+ break;
152
+ case 'delete':
153
+ if (!pos[0] || !pos[1])
154
+ usage();
155
+ result = await tasks.deleteTask(auth, pos[0], pos[1]);
156
+ break;
157
+ case 'create-list':
158
+ result = await tasks.createTaskList(auth, flags.title ?? '');
159
+ break;
160
+ case 'delete-list':
161
+ if (!pos[0])
162
+ usage();
163
+ result = await tasks.deleteTaskList(auth, pos[0]);
164
+ break;
165
+ case 'clear':
166
+ if (!pos[0])
167
+ usage();
168
+ result = await tasks.clearCompleted(auth, pos[0]);
169
+ break;
170
+ default:
171
+ usage();
172
+ }
173
+ console.log(JSON.stringify(result, null, 2));
174
+ }
175
+ catch (err) {
176
+ const e = err;
177
+ if (typeof e.toJSON === 'function') {
178
+ console.error(JSON.stringify(e.toJSON(), null, 2));
179
+ }
180
+ else {
181
+ console.error(JSON.stringify({
182
+ error: e.code ?? 'UNKNOWN',
183
+ message: e.message ?? String(err),
184
+ }, null, 2));
185
+ }
186
+ process.exit(1);
187
+ }
188
+ }
189
+ main();
190
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/bin/tasks.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,SAAS,KAAK;IACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACzB,KAAK,EAAE,OAAO;QACd,OAAO,EAAE,wCAAwC;QACjD,QAAQ,EAAE;YACR,KAAK,EAAE,0BAA0B;YACjC,KAAK,EAAE,uGAAuG;YAC9G,GAAG,EAAE,0CAA0C;YAC/C,GAAG,EAAE,sGAAsG;YAC3G,MAAM,EAAE,iIAAiI;YACzI,QAAQ,EAAE,+CAA+C;YACzD,IAAI,EAAE,qFAAqF;YAC3F,MAAM,EAAE,uDAAuD;YAC/D,aAAa,EAAE,8CAA8C;YAC7D,aAAa,EAAE,mDAAmD;YAClE,KAAK,EAAE,6CAA6C;SACrD;KACF,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,wCAAwC;AACxC,SAAS,UAAU,CAAC,IAAc;IAChC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;QACvC,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,qCAAqC;AACrC,SAAS,UAAU,CAAC,IAAc;IAChC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,EAAE,CAAC;IAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAE7B,wBAAwB;IACxB,MAAM,UAAU,GAAG,SAAS,IAAI,KAAK,CAAC;IACtC,gBAAgB,CAAC;QACf,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACpB,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;oBACzB,OAAO,EAAE,IAAI;oBACb,SAAS,EAAE,EAAE,CAAC,IAAI;oBAClB,WAAW,EAAE,EAAE,CAAC,WAAW;oBAC3B,OAAO,EAAE,EAAE,CAAC,OAAO;oBACnB,IAAI,EAAE,yCAAyC;iBAChD,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACb,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC,CAAC;IAEH,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAkE,CAAC;QAC7E,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC3B,KAAK,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;gBAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC;aAClC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,IAAI,MAAe,CAAC;QAEpB,QAAQ,OAAO,EAAE,CAAC;YAChB,KAAK,OAAO;gBACV,MAAM,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBACzC,MAAM;YAER,KAAK,OAAO;gBACV,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBACrB,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;oBAC3C,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;oBACvD,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;oBAC9B,aAAa,EAAE,gBAAgB,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;oBAC3D,UAAU,EAAE,aAAa,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;iBACtD,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,KAAK;gBACR,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnD,MAAM;YAER,KAAK,KAAK;gBACR,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBACrB,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;oBAC5C,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;oBACxB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;iBACzB,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,QAAQ;gBACX,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;oBACpD,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,KAAK,EAAE,KAAK,CAAC,KAAK;oBAClB,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,MAAM,EAAE,KAAK,CAAC,MAAiD;iBAChE,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,UAAU;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxD,MAAM;YAER,KAAK,MAAM;gBACT,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE;oBAClD,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;iBACzB,CAAC,CAAC;gBACH,MAAM;YAER,KAAK,QAAQ;gBACX,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBAChC,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,MAAM;YAER,KAAK,aAAa;gBAChB,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAC7D,MAAM;YAER,KAAK,aAAa;gBAChB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBACrB,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM;YAER,KAAK,OAAO;gBACV,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,KAAK,EAAE,CAAC;gBACrB,MAAM,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAClD,MAAM;YAER;gBACE,KAAK,EAAE,CAAC;QACZ,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,GAAkE,CAAC;QAC7E,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC3B,KAAK,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;gBAC1B,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC;aAClC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}