gogcli-mcp 2.0.2 → 2.0.6

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 (44) hide show
  1. package/.claude-plugin/marketplace.json +38 -0
  2. package/.claude-plugin/plugin.json +25 -0
  3. package/.mcp.json +14 -0
  4. package/.mcpbignore +27 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +1334 -963
  8. package/dist/lib.d.ts +6 -0
  9. package/dist/lib.d.ts.map +1 -0
  10. package/dist/lib.js +1560 -1189
  11. package/dist/runner.d.ts +12 -0
  12. package/dist/runner.d.ts.map +1 -0
  13. package/dist/server.d.ts +7 -0
  14. package/dist/server.d.ts.map +1 -0
  15. package/dist/tools/auth.d.ts +3 -0
  16. package/dist/tools/auth.d.ts.map +1 -0
  17. package/dist/tools/calendar.d.ts +3 -0
  18. package/dist/tools/calendar.d.ts.map +1 -0
  19. package/dist/tools/contacts.d.ts +3 -0
  20. package/dist/tools/contacts.d.ts.map +1 -0
  21. package/dist/tools/docs.d.ts +3 -0
  22. package/dist/tools/docs.d.ts.map +1 -0
  23. package/dist/tools/drive.d.ts +3 -0
  24. package/dist/tools/drive.d.ts.map +1 -0
  25. package/dist/tools/gmail.d.ts +3 -0
  26. package/dist/tools/gmail.d.ts.map +1 -0
  27. package/dist/tools/sheets.d.ts +3 -0
  28. package/dist/tools/sheets.d.ts.map +1 -0
  29. package/dist/tools/tasks.d.ts +3 -0
  30. package/dist/tools/tasks.d.ts.map +1 -0
  31. package/dist/tools/utils.d.ts +14 -0
  32. package/dist/tools/utils.d.ts.map +1 -0
  33. package/manifest.json +1 -101
  34. package/package.json +4 -3
  35. package/server.json +35 -0
  36. package/src/runner.ts +4 -1
  37. package/src/tools/classroom.ts +2 -297
  38. package/src/tools/contacts.ts +1 -1
  39. package/src/tools/slides.ts +1 -108
  40. package/tests/helpers/extras-harness.ts +31 -0
  41. package/tests/runner.test.ts +30 -0
  42. package/tests/tools/calendar.test.ts +1 -0
  43. package/tests/tools/classroom.test.ts +0 -352
  44. package/tests/tools/slides.test.ts +6 -278
@@ -31,9 +31,9 @@ describe('gog_slides_export', () => {
31
31
  it('passes --out and --format when provided', async () => {
32
32
  vi.mocked(runner.run).mockResolvedValue('{}');
33
33
  const handlers = setupHandlers();
34
- await handlers.get('gog_slides_export')!({ presentationId: 'p1', out: '/tmp/out.pdf', format: 'pdf' });
34
+ await handlers.get('gog_slides_export')!({ presentationId: 'p1', out: '/tmp/deck.pdf', format: 'pdf' });
35
35
  expect(runner.run).toHaveBeenCalledWith(
36
- ['slides', 'export', 'p1', '--out=/tmp/out.pdf', '--format=pdf'],
36
+ ['slides', 'export', 'p1', '--out=/tmp/deck.pdf', '--format=pdf'],
37
37
  { account: undefined },
38
38
  );
39
39
  });
@@ -66,16 +66,16 @@ describe('gog_slides_create', () => {
66
66
  it('calls run with title only', async () => {
67
67
  vi.mocked(runner.run).mockResolvedValue('{}');
68
68
  const handlers = setupHandlers();
69
- await handlers.get('gog_slides_create')!({ title: 'My Deck' });
70
- expect(runner.run).toHaveBeenCalledWith(['slides', 'create', 'My Deck'], { account: undefined });
69
+ await handlers.get('gog_slides_create')!({ title: 'Deck' });
70
+ expect(runner.run).toHaveBeenCalledWith(['slides', 'create', 'Deck'], { account: undefined });
71
71
  });
72
72
 
73
73
  it('passes --parent and --template when provided', async () => {
74
74
  vi.mocked(runner.run).mockResolvedValue('{}');
75
75
  const handlers = setupHandlers();
76
- await handlers.get('gog_slides_create')!({ title: 'My Deck', parent: 'folder1', template: 'tpl1' });
76
+ await handlers.get('gog_slides_create')!({ title: 'Deck', parent: 'folder1', template: 'tpl1' });
77
77
  expect(runner.run).toHaveBeenCalledWith(
78
- ['slides', 'create', 'My Deck', '--parent=folder1', '--template=tpl1'],
78
+ ['slides', 'create', 'Deck', '--parent=folder1', '--template=tpl1'],
79
79
  { account: undefined },
80
80
  );
81
81
  });
@@ -88,134 +88,6 @@ describe('gog_slides_create', () => {
88
88
  });
89
89
  });
90
90
 
91
- describe('gog_slides_create_from_markdown', () => {
92
- it('calls run with title only', async () => {
93
- vi.mocked(runner.run).mockResolvedValue('{}');
94
- const handlers = setupHandlers();
95
- await handlers.get('gog_slides_create_from_markdown')!({ title: 'Deck' });
96
- expect(runner.run).toHaveBeenCalledWith(
97
- ['slides', 'create-from-markdown', 'Deck'],
98
- { account: undefined },
99
- );
100
- });
101
-
102
- it('passes all optional flags', async () => {
103
- vi.mocked(runner.run).mockResolvedValue('{}');
104
- const handlers = setupHandlers();
105
- await handlers.get('gog_slides_create_from_markdown')!({
106
- title: 'Deck',
107
- content: '# Slide 1',
108
- contentFile: '/tmp/deck.md',
109
- parent: 'folder1',
110
- debug: true,
111
- });
112
- expect(runner.run).toHaveBeenCalledWith(
113
- [
114
- 'slides', 'create-from-markdown', 'Deck',
115
- '--content=# Slide 1',
116
- '--content-file=/tmp/deck.md',
117
- '--parent=folder1',
118
- '--debug',
119
- ],
120
- { account: undefined },
121
- );
122
- });
123
-
124
- it('omits --debug when false', async () => {
125
- vi.mocked(runner.run).mockResolvedValue('{}');
126
- const handlers = setupHandlers();
127
- await handlers.get('gog_slides_create_from_markdown')!({ title: 'Deck', debug: false });
128
- expect(runner.run).toHaveBeenCalledWith(
129
- ['slides', 'create-from-markdown', 'Deck'],
130
- { account: undefined },
131
- );
132
- });
133
-
134
- it('returns error text on failure', async () => {
135
- vi.mocked(runner.run).mockRejectedValue(new Error('Markdown failed'));
136
- const handlers = setupHandlers();
137
- const result = await handlers.get('gog_slides_create_from_markdown')!({ title: 'x' });
138
- expect(result.content[0].text).toBe('Error: Markdown failed');
139
- });
140
- });
141
-
142
- describe('gog_slides_create_from_template', () => {
143
- it('calls run with templateId and title only', async () => {
144
- vi.mocked(runner.run).mockResolvedValue('{}');
145
- const handlers = setupHandlers();
146
- await handlers.get('gog_slides_create_from_template')!({ templateId: 'tpl1', title: 'Deck' });
147
- expect(runner.run).toHaveBeenCalledWith(
148
- ['slides', 'create-from-template', 'tpl1', 'Deck'],
149
- { account: undefined },
150
- );
151
- });
152
-
153
- it('passes --replace for a single replacement entry', async () => {
154
- vi.mocked(runner.run).mockResolvedValue('{}');
155
- const handlers = setupHandlers();
156
- await handlers.get('gog_slides_create_from_template')!({
157
- templateId: 'tpl1',
158
- title: 'Deck',
159
- replacements: { name: 'Alice' },
160
- });
161
- expect(runner.run).toHaveBeenCalledWith(
162
- ['slides', 'create-from-template', 'tpl1', 'Deck', '--replace=name=Alice'],
163
- { account: undefined },
164
- );
165
- });
166
-
167
- it('passes --replace for each entry in replacements', async () => {
168
- vi.mocked(runner.run).mockResolvedValue('{}');
169
- const handlers = setupHandlers();
170
- await handlers.get('gog_slides_create_from_template')!({
171
- templateId: 'tpl1',
172
- title: 'Deck',
173
- replacements: { name: 'Alice', company: 'Acme' },
174
- });
175
- const call = vi.mocked(runner.run).mock.calls[0]!;
176
- expect(call[0]).toEqual(expect.arrayContaining(['--replace=name=Alice', '--replace=company=Acme']));
177
- expect(call[1]).toEqual({ account: undefined });
178
- });
179
-
180
- it('passes --replacements, --parent, and --exact', async () => {
181
- vi.mocked(runner.run).mockResolvedValue('{}');
182
- const handlers = setupHandlers();
183
- await handlers.get('gog_slides_create_from_template')!({
184
- templateId: 'tpl1',
185
- title: 'Deck',
186
- replacementsFile: '/tmp/r.json',
187
- parent: 'folder1',
188
- exact: true,
189
- });
190
- expect(runner.run).toHaveBeenCalledWith(
191
- [
192
- 'slides', 'create-from-template', 'tpl1', 'Deck',
193
- '--replacements=/tmp/r.json',
194
- '--parent=folder1',
195
- '--exact',
196
- ],
197
- { account: undefined },
198
- );
199
- });
200
-
201
- it('omits --exact when false', async () => {
202
- vi.mocked(runner.run).mockResolvedValue('{}');
203
- const handlers = setupHandlers();
204
- await handlers.get('gog_slides_create_from_template')!({ templateId: 'tpl1', title: 'Deck', exact: false });
205
- expect(runner.run).toHaveBeenCalledWith(
206
- ['slides', 'create-from-template', 'tpl1', 'Deck'],
207
- { account: undefined },
208
- );
209
- });
210
-
211
- it('returns error text on failure', async () => {
212
- vi.mocked(runner.run).mockRejectedValue(new Error('Template failed'));
213
- const handlers = setupHandlers();
214
- const result = await handlers.get('gog_slides_create_from_template')!({ templateId: 't', title: 'x' });
215
- expect(result.content[0].text).toBe('Error: Template failed');
216
- });
217
- });
218
-
219
91
  describe('gog_slides_copy', () => {
220
92
  it('calls run with presentationId and title', async () => {
221
93
  vi.mocked(runner.run).mockResolvedValue('{}');
@@ -245,46 +117,6 @@ describe('gog_slides_copy', () => {
245
117
  });
246
118
  });
247
119
 
248
- describe('gog_slides_add_slide', () => {
249
- it('calls run with presentationId and image', async () => {
250
- vi.mocked(runner.run).mockResolvedValue('{}');
251
- const handlers = setupHandlers();
252
- await handlers.get('gog_slides_add_slide')!({ presentationId: 'p1', image: '/tmp/img.png' });
253
- expect(runner.run).toHaveBeenCalledWith(
254
- ['slides', 'add-slide', 'p1', '/tmp/img.png'],
255
- { account: undefined },
256
- );
257
- });
258
-
259
- it('passes --notes, --notes-file, and --before', async () => {
260
- vi.mocked(runner.run).mockResolvedValue('{}');
261
- const handlers = setupHandlers();
262
- await handlers.get('gog_slides_add_slide')!({
263
- presentationId: 'p1',
264
- image: '/tmp/img.png',
265
- notes: 'Speaker note',
266
- notesFile: '/tmp/notes.txt',
267
- before: 'slide5',
268
- });
269
- expect(runner.run).toHaveBeenCalledWith(
270
- [
271
- 'slides', 'add-slide', 'p1', '/tmp/img.png',
272
- '--notes=Speaker note',
273
- '--notes-file=/tmp/notes.txt',
274
- '--before=slide5',
275
- ],
276
- { account: undefined },
277
- );
278
- });
279
-
280
- it('returns error text on failure', async () => {
281
- vi.mocked(runner.run).mockRejectedValue(new Error('Add failed'));
282
- const handlers = setupHandlers();
283
- const result = await handlers.get('gog_slides_add_slide')!({ presentationId: 'p', image: 'i' });
284
- expect(result.content[0].text).toBe('Error: Add failed');
285
- });
286
- });
287
-
288
120
  describe('gog_slides_list_slides', () => {
289
121
  it('calls run with presentationId', async () => {
290
122
  vi.mocked(runner.run).mockResolvedValue('{}');
@@ -301,25 +133,6 @@ describe('gog_slides_list_slides', () => {
301
133
  });
302
134
  });
303
135
 
304
- describe('gog_slides_delete_slide', () => {
305
- it('calls run with presentationId and slideId', async () => {
306
- vi.mocked(runner.run).mockResolvedValue('{}');
307
- const handlers = setupHandlers();
308
- await handlers.get('gog_slides_delete_slide')!({ presentationId: 'p1', slideId: 's1' });
309
- expect(runner.run).toHaveBeenCalledWith(
310
- ['slides', 'delete-slide', 'p1', 's1'],
311
- { account: undefined },
312
- );
313
- });
314
-
315
- it('returns error text on failure', async () => {
316
- vi.mocked(runner.run).mockRejectedValue(new Error('Delete failed'));
317
- const handlers = setupHandlers();
318
- const result = await handlers.get('gog_slides_delete_slide')!({ presentationId: 'p', slideId: 's' });
319
- expect(result.content[0].text).toBe('Error: Delete failed');
320
- });
321
- });
322
-
323
136
  describe('gog_slides_read_slide', () => {
324
137
  it('calls run with presentationId and slideId', async () => {
325
138
  vi.mocked(runner.run).mockResolvedValue('{}');
@@ -339,91 +152,6 @@ describe('gog_slides_read_slide', () => {
339
152
  });
340
153
  });
341
154
 
342
- describe('gog_slides_update_notes', () => {
343
- it('calls run with presentationId and slideId', async () => {
344
- vi.mocked(runner.run).mockResolvedValue('{}');
345
- const handlers = setupHandlers();
346
- await handlers.get('gog_slides_update_notes')!({ presentationId: 'p1', slideId: 's1' });
347
- expect(runner.run).toHaveBeenCalledWith(
348
- ['slides', 'update-notes', 'p1', 's1'],
349
- { account: undefined },
350
- );
351
- });
352
-
353
- it('passes --notes and --notes-file when provided', async () => {
354
- vi.mocked(runner.run).mockResolvedValue('{}');
355
- const handlers = setupHandlers();
356
- await handlers.get('gog_slides_update_notes')!({
357
- presentationId: 'p1',
358
- slideId: 's1',
359
- notes: 'speak clearly',
360
- notesFile: '/tmp/n.txt',
361
- });
362
- expect(runner.run).toHaveBeenCalledWith(
363
- [
364
- 'slides', 'update-notes', 'p1', 's1',
365
- '--notes=speak clearly',
366
- '--notes-file=/tmp/n.txt',
367
- ],
368
- { account: undefined },
369
- );
370
- });
371
-
372
- it('returns error text on failure', async () => {
373
- vi.mocked(runner.run).mockRejectedValue(new Error('Notes failed'));
374
- const handlers = setupHandlers();
375
- const result = await handlers.get('gog_slides_update_notes')!({ presentationId: 'p', slideId: 's' });
376
- expect(result.content[0].text).toBe('Error: Notes failed');
377
- });
378
- });
379
-
380
- describe('gog_slides_replace_slide', () => {
381
- it('calls run with presentationId, slideId, and image', async () => {
382
- vi.mocked(runner.run).mockResolvedValue('{}');
383
- const handlers = setupHandlers();
384
- await handlers.get('gog_slides_replace_slide')!({
385
- presentationId: 'p1',
386
- slideId: 's1',
387
- image: '/tmp/img.png',
388
- });
389
- expect(runner.run).toHaveBeenCalledWith(
390
- ['slides', 'replace-slide', 'p1', 's1', '/tmp/img.png'],
391
- { account: undefined },
392
- );
393
- });
394
-
395
- it('passes --notes and --notes-file when provided', async () => {
396
- vi.mocked(runner.run).mockResolvedValue('{}');
397
- const handlers = setupHandlers();
398
- await handlers.get('gog_slides_replace_slide')!({
399
- presentationId: 'p1',
400
- slideId: 's1',
401
- image: '/tmp/img.png',
402
- notes: 'updated',
403
- notesFile: '/tmp/n.txt',
404
- });
405
- expect(runner.run).toHaveBeenCalledWith(
406
- [
407
- 'slides', 'replace-slide', 'p1', 's1', '/tmp/img.png',
408
- '--notes=updated',
409
- '--notes-file=/tmp/n.txt',
410
- ],
411
- { account: undefined },
412
- );
413
- });
414
-
415
- it('returns error text on failure', async () => {
416
- vi.mocked(runner.run).mockRejectedValue(new Error('Replace failed'));
417
- const handlers = setupHandlers();
418
- const result = await handlers.get('gog_slides_replace_slide')!({
419
- presentationId: 'p',
420
- slideId: 's',
421
- image: 'i',
422
- });
423
- expect(result.content[0].text).toBe('Error: Replace failed');
424
- });
425
- });
426
-
427
155
  describe('gog_slides_run', () => {
428
156
  it('passes subcommand and args to runner', async () => {
429
157
  vi.mocked(runner.run).mockResolvedValue('{}');