gogcli-mcp-slides 4.2.5 → 4.4.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dist/index.js +454 -136
- package/manifest.json +9 -2
- package/package.json +2 -2
- package/server.json +2 -2
- package/src/tools/slides-extra.ts +54 -44
- package/tests/tools/slides-extra.test.ts +129 -85
- package/vitest.config.ts +5 -0
|
@@ -3,6 +3,7 @@ import { registerExtraSlidesTools } from '../../src/tools/slides-extra.js';
|
|
|
3
3
|
import * as lib from '../../../gogcli-mcp/src/lib.js';
|
|
4
4
|
import { createTestHarness, type TestHarness } from '@chrischall/mcp-utils/test';
|
|
5
5
|
import { rawTextResult } from '@chrischall/mcp-utils';
|
|
6
|
+
import { pos } from '../../../gogcli-mcp/src/argv.js';
|
|
6
7
|
|
|
7
8
|
vi.mock('../../../gogcli-mcp/src/lib.js', async (importOriginal) => {
|
|
8
9
|
const actual = await importOriginal<typeof lib>();
|
|
@@ -24,7 +25,7 @@ describe('gog_slides_create_from_markdown', () => {
|
|
|
24
25
|
it('calls runOrDiagnose with title only', async () => {
|
|
25
26
|
await harness.callTool('gog_slides_create_from_markdown', { title: 'Deck' });
|
|
26
27
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
27
|
-
['slides', 'create-from-markdown', 'Deck'],
|
|
28
|
+
['slides', 'create-from-markdown', pos('Deck')],
|
|
28
29
|
{ account: undefined },
|
|
29
30
|
);
|
|
30
31
|
});
|
|
@@ -39,7 +40,7 @@ describe('gog_slides_create_from_markdown', () => {
|
|
|
39
40
|
});
|
|
40
41
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
41
42
|
[
|
|
42
|
-
'slides', 'create-from-markdown', 'Deck',
|
|
43
|
+
'slides', 'create-from-markdown', pos('Deck'),
|
|
43
44
|
'--content=# Slide 1',
|
|
44
45
|
'--content-file=/tmp/deck.md',
|
|
45
46
|
'--parent=folder1',
|
|
@@ -52,7 +53,7 @@ describe('gog_slides_create_from_markdown', () => {
|
|
|
52
53
|
it('omits --debug when false', async () => {
|
|
53
54
|
await harness.callTool('gog_slides_create_from_markdown', { title: 'Deck', debug: false });
|
|
54
55
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
55
|
-
['slides', 'create-from-markdown', 'Deck'],
|
|
56
|
+
['slides', 'create-from-markdown', pos('Deck')],
|
|
56
57
|
{ account: undefined },
|
|
57
58
|
);
|
|
58
59
|
});
|
|
@@ -62,7 +63,7 @@ describe('gog_slides_create_from_template', () => {
|
|
|
62
63
|
it('calls runOrDiagnose with templateId and title only', async () => {
|
|
63
64
|
await harness.callTool('gog_slides_create_from_template', { templateId: 'tpl1', title: 'Deck' });
|
|
64
65
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
65
|
-
['slides', 'create-from-template', 'tpl1', 'Deck'],
|
|
66
|
+
['slides', 'create-from-template', pos('tpl1'), pos('Deck')],
|
|
66
67
|
{ account: undefined },
|
|
67
68
|
);
|
|
68
69
|
});
|
|
@@ -74,7 +75,7 @@ describe('gog_slides_create_from_template', () => {
|
|
|
74
75
|
replacements: { name: 'Alice' },
|
|
75
76
|
});
|
|
76
77
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
77
|
-
['slides', 'create-from-template', 'tpl1', 'Deck', '--replace=name=Alice'],
|
|
78
|
+
['slides', 'create-from-template', pos('tpl1'), pos('Deck'), '--replace=name=Alice'],
|
|
78
79
|
{ account: undefined },
|
|
79
80
|
);
|
|
80
81
|
});
|
|
@@ -100,7 +101,7 @@ describe('gog_slides_create_from_template', () => {
|
|
|
100
101
|
});
|
|
101
102
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
102
103
|
[
|
|
103
|
-
'slides', 'create-from-template', 'tpl1', 'Deck',
|
|
104
|
+
'slides', 'create-from-template', pos('tpl1'), pos('Deck'),
|
|
104
105
|
'--replacements=/tmp/r.json',
|
|
105
106
|
'--parent=folder1',
|
|
106
107
|
'--exact',
|
|
@@ -116,7 +117,7 @@ describe('gog_slides_create_from_template', () => {
|
|
|
116
117
|
exact: false,
|
|
117
118
|
});
|
|
118
119
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
119
|
-
['slides', 'create-from-template', 'tpl1', 'Deck'],
|
|
120
|
+
['slides', 'create-from-template', pos('tpl1'), pos('Deck')],
|
|
120
121
|
{ account: undefined },
|
|
121
122
|
);
|
|
122
123
|
});
|
|
@@ -131,7 +132,7 @@ describe('slides payload routing', () => {
|
|
|
131
132
|
it('routes a large create-from-markdown content to --content-file', async () => {
|
|
132
133
|
await harness.callTool('gog_slides_create_from_markdown', { title: 'Deck', content: big });
|
|
133
134
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
134
|
-
['slides', 'create-from-markdown', 'Deck',
|
|
135
|
+
['slides', 'create-from-markdown', pos('Deck'),
|
|
135
136
|
{ kind: 'file', flag: 'content-file', contents: big, ext: 'md' }],
|
|
136
137
|
{ account: undefined },
|
|
137
138
|
);
|
|
@@ -140,7 +141,7 @@ describe('slides payload routing', () => {
|
|
|
140
141
|
it('routes large add-slide notes to --notes-file', async () => {
|
|
141
142
|
await harness.callTool('gog_slides_add_slide', { presentationId: 'p1', image: '/tmp/i.png', notes: big });
|
|
142
143
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
143
|
-
['slides', 'add-slide', 'p1', '/tmp/i.png',
|
|
144
|
+
['slides', 'add-slide', pos('p1'), pos('/tmp/i.png'),
|
|
144
145
|
{ kind: 'file', flag: 'notes-file', contents: big, ext: undefined }],
|
|
145
146
|
{ account: undefined },
|
|
146
147
|
);
|
|
@@ -149,7 +150,7 @@ describe('slides payload routing', () => {
|
|
|
149
150
|
it('routes large update-notes notes to --notes-file', async () => {
|
|
150
151
|
await harness.callTool('gog_slides_update_notes', { presentationId: 'p1', slideId: 's1', notes: big });
|
|
151
152
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
152
|
-
['slides', 'update-notes', 'p1', 's1',
|
|
153
|
+
['slides', 'update-notes', pos('p1'), pos('s1'),
|
|
153
154
|
{ kind: 'file', flag: 'notes-file', contents: big, ext: undefined }],
|
|
154
155
|
{ account: undefined },
|
|
155
156
|
);
|
|
@@ -160,7 +161,7 @@ describe('slides payload routing', () => {
|
|
|
160
161
|
presentationId: 'p1', slideId: 's1', image: '/tmp/i.png', notes: big,
|
|
161
162
|
});
|
|
162
163
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
163
|
-
['slides', 'replace-slide', 'p1', 's1', '/tmp/i.png',
|
|
164
|
+
['slides', 'replace-slide', pos('p1'), pos('s1'), pos('/tmp/i.png'),
|
|
164
165
|
{ kind: 'file', flag: 'notes-file', contents: big, ext: undefined }],
|
|
165
166
|
{ account: undefined },
|
|
166
167
|
);
|
|
@@ -173,7 +174,7 @@ describe('slides payload routing', () => {
|
|
|
173
174
|
presentationId: 'p1', slideId: 's1', notes: big, notesFile: '/tmp/mine.txt',
|
|
174
175
|
});
|
|
175
176
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
176
|
-
['slides', 'update-notes', 'p1', 's1',
|
|
177
|
+
['slides', 'update-notes', pos('p1'), pos('s1'),
|
|
177
178
|
{ kind: 'file', flag: 'notes-file', contents: big, ext: undefined },
|
|
178
179
|
'--notes-file=/tmp/mine.txt'],
|
|
179
180
|
{ account: undefined },
|
|
@@ -194,7 +195,7 @@ describe('gog_slides_add_slide', () => {
|
|
|
194
195
|
it('calls runOrDiagnose with presentationId and image', async () => {
|
|
195
196
|
await harness.callTool('gog_slides_add_slide', { presentationId: 'p1', image: '/tmp/img.png' });
|
|
196
197
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
197
|
-
['slides', 'add-slide', 'p1', '/tmp/img.png'],
|
|
198
|
+
['slides', 'add-slide', pos('p1'), pos('/tmp/img.png')],
|
|
198
199
|
{ account: undefined },
|
|
199
200
|
);
|
|
200
201
|
});
|
|
@@ -209,7 +210,7 @@ describe('gog_slides_add_slide', () => {
|
|
|
209
210
|
});
|
|
210
211
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
211
212
|
[
|
|
212
|
-
'slides', 'add-slide', 'p1', '/tmp/img.png',
|
|
213
|
+
'slides', 'add-slide', pos('p1'), pos('/tmp/img.png'),
|
|
213
214
|
'--notes=Speaker note',
|
|
214
215
|
'--notes-file=/tmp/notes.txt',
|
|
215
216
|
'--before=slide5',
|
|
@@ -223,7 +224,7 @@ describe('gog_slides_delete_slide', () => {
|
|
|
223
224
|
it('calls runOrDiagnose with presentationId and slideId', async () => {
|
|
224
225
|
await harness.callTool('gog_slides_delete_slide', { presentationId: 'p1', slideId: 's1' });
|
|
225
226
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
226
|
-
['slides', 'delete-slide', 'p1', 's1', '--force'],
|
|
227
|
+
['slides', 'delete-slide', pos('p1'), pos('s1'), '--force'],
|
|
227
228
|
{ account: undefined },
|
|
228
229
|
);
|
|
229
230
|
});
|
|
@@ -233,7 +234,7 @@ describe('gog_slides_update_notes', () => {
|
|
|
233
234
|
it('calls runOrDiagnose with presentationId and slideId', async () => {
|
|
234
235
|
await harness.callTool('gog_slides_update_notes', { presentationId: 'p1', slideId: 's1' });
|
|
235
236
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
236
|
-
['slides', 'update-notes', 'p1', 's1'],
|
|
237
|
+
['slides', 'update-notes', pos('p1'), pos('s1')],
|
|
237
238
|
{ account: undefined },
|
|
238
239
|
);
|
|
239
240
|
});
|
|
@@ -247,7 +248,7 @@ describe('gog_slides_update_notes', () => {
|
|
|
247
248
|
});
|
|
248
249
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
249
250
|
[
|
|
250
|
-
'slides', 'update-notes', 'p1', 's1',
|
|
251
|
+
'slides', 'update-notes', pos('p1'), pos('s1'),
|
|
251
252
|
'--notes=speak clearly',
|
|
252
253
|
'--notes-file=/tmp/n.txt',
|
|
253
254
|
],
|
|
@@ -264,7 +265,7 @@ describe('gog_slides_replace_slide', () => {
|
|
|
264
265
|
image: '/tmp/img.png',
|
|
265
266
|
});
|
|
266
267
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
267
|
-
['slides', 'replace-slide', 'p1', 's1', '/tmp/img.png'],
|
|
268
|
+
['slides', 'replace-slide', pos('p1'), pos('s1'), pos('/tmp/img.png')],
|
|
268
269
|
{ account: undefined },
|
|
269
270
|
);
|
|
270
271
|
});
|
|
@@ -279,7 +280,7 @@ describe('gog_slides_replace_slide', () => {
|
|
|
279
280
|
});
|
|
280
281
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
281
282
|
[
|
|
282
|
-
'slides', 'replace-slide', 'p1', 's1', '/tmp/img.png',
|
|
283
|
+
'slides', 'replace-slide', pos('p1'), pos('s1'), pos('/tmp/img.png'),
|
|
283
284
|
'--notes=updated',
|
|
284
285
|
'--notes-file=/tmp/n.txt',
|
|
285
286
|
],
|
|
@@ -295,7 +296,7 @@ describe('gog_slides_insert_image', () => {
|
|
|
295
296
|
presentationId: 'p1', slideId: 's1', image: '/tmp/i.png', width: 200,
|
|
296
297
|
});
|
|
297
298
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
298
|
-
['slides', 'insert-image', 'p1', 's1', '/tmp/i.png', '--width=200'],
|
|
299
|
+
['slides', 'insert-image', pos('p1'), pos('s1'), pos('/tmp/i.png'), '--width=200'],
|
|
299
300
|
{ account: undefined },
|
|
300
301
|
);
|
|
301
302
|
});
|
|
@@ -305,7 +306,7 @@ describe('gog_slides_insert_image', () => {
|
|
|
305
306
|
presentationId: 'p1', slideId: 's1', image: '/tmp/i.png', width: 200, height: 100, x: 50, y: 60, unit: 'PT', account: 'a@b.com',
|
|
306
307
|
});
|
|
307
308
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
308
|
-
['slides', 'insert-image', 'p1', 's1', '/tmp/i.png', '--width=200', '--height=100', '--x=50', '--y=60', '--unit=PT'],
|
|
309
|
+
['slides', 'insert-image', pos('p1'), pos('s1'), pos('/tmp/i.png'), '--width=200', '--height=100', '--x=50', '--y=60', '--unit=PT'],
|
|
309
310
|
{ account: 'a@b.com' },
|
|
310
311
|
);
|
|
311
312
|
});
|
|
@@ -321,7 +322,7 @@ describe('gog_slides_insert_image url mode', () => {
|
|
|
321
322
|
presentationId: 'p1', slideId: 's1', url: 'https://x.test/i.png', width: 200, height: 100,
|
|
322
323
|
});
|
|
323
324
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
324
|
-
['slides', 'insert-image', 'p1', 's1', '--width=200', '--url=https://x.test/i.png', '--height=100'],
|
|
325
|
+
['slides', 'insert-image', pos('p1'), pos('s1'), '--width=200', '--url=https://x.test/i.png', '--height=100'],
|
|
325
326
|
{ account: undefined },
|
|
326
327
|
);
|
|
327
328
|
});
|
|
@@ -333,7 +334,7 @@ describe('gog_slides_replace_slide url mode', () => {
|
|
|
333
334
|
presentationId: 'p1', slideId: 's1', url: 'https://x.test/i.png', notes: 'n',
|
|
334
335
|
});
|
|
335
336
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
336
|
-
['slides', 'replace-slide', 'p1', 's1', '--url=https://x.test/i.png', '--notes=n'],
|
|
337
|
+
['slides', 'replace-slide', pos('p1'), pos('s1'), '--url=https://x.test/i.png', '--notes=n'],
|
|
337
338
|
{ account: undefined },
|
|
338
339
|
);
|
|
339
340
|
});
|
|
@@ -342,11 +343,11 @@ describe('gog_slides_replace_slide url mode', () => {
|
|
|
342
343
|
describe('gog_slides_raw', () => {
|
|
343
344
|
it('passes --pretty', async () => {
|
|
344
345
|
await harness.callTool('gog_slides_raw', { presentationId: 'p1', pretty: true });
|
|
345
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'raw', 'p1', '--pretty'], { account: undefined, lossless: true });
|
|
346
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'raw', pos('p1'), '--pretty'], { account: undefined, lossless: true });
|
|
346
347
|
});
|
|
347
348
|
it('bare', async () => {
|
|
348
349
|
await harness.callTool('gog_slides_raw', { presentationId: 'p1' });
|
|
349
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'raw', 'p1'], { account: undefined, lossless: true });
|
|
350
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'raw', pos('p1')], { account: undefined, lossless: true });
|
|
350
351
|
});
|
|
351
352
|
});
|
|
352
353
|
|
|
@@ -356,13 +357,13 @@ describe('gog_slides_locate', () => {
|
|
|
356
357
|
presentationId: 'p1', text: 'hi', page: 'sl1', occurrence: 2, all: true, matchCase: true, failEmpty: true,
|
|
357
358
|
});
|
|
358
359
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
359
|
-
['slides', 'locate', 'p1', 'hi', '--page=sl1', '--occurrence=2', '--all', '--match-case', '--fail-empty'],
|
|
360
|
+
['slides', 'locate', pos('p1'), pos('hi'), '--page=sl1', '--occurrence=2', '--all', '--match-case', '--fail-empty'],
|
|
360
361
|
{ account: undefined },
|
|
361
362
|
);
|
|
362
363
|
});
|
|
363
364
|
it('bare', async () => {
|
|
364
365
|
await harness.callTool('gog_slides_locate', { presentationId: 'p1', text: 'hi' });
|
|
365
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'locate', 'p1', 'hi'], { account: undefined });
|
|
366
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'locate', pos('p1'), pos('hi')], { account: undefined });
|
|
366
367
|
});
|
|
367
368
|
});
|
|
368
369
|
|
|
@@ -372,13 +373,13 @@ describe('gog_slides_thumbnail', () => {
|
|
|
372
373
|
presentationId: 'p1', slideId: 's1', format: 'png', size: 'large', out: '/tmp/t.png', overwrite: true,
|
|
373
374
|
});
|
|
374
375
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
375
|
-
['slides', 'thumbnail', 'p1', 's1', '--format=png', '--size=large', '--out=/tmp/t.png', '--overwrite'],
|
|
376
|
+
['slides', 'thumbnail', pos('p1'), pos('s1'), '--format=png', '--size=large', '--out=/tmp/t.png', '--overwrite'],
|
|
376
377
|
{ account: undefined },
|
|
377
378
|
);
|
|
378
379
|
});
|
|
379
380
|
it('bare', async () => {
|
|
380
381
|
await harness.callTool('gog_slides_thumbnail', { presentationId: 'p1', slideId: 's1' });
|
|
381
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'thumbnail', 'p1', 's1'], { account: undefined });
|
|
382
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'thumbnail', pos('p1'), pos('s1')], { account: undefined });
|
|
382
383
|
});
|
|
383
384
|
});
|
|
384
385
|
|
|
@@ -386,17 +387,17 @@ describe('gog_slides_new_slide', () => {
|
|
|
386
387
|
it('passes layout and index', async () => {
|
|
387
388
|
await harness.callTool('gog_slides_new_slide', { presentationId: 'p1', layout: 'TITLE_AND_BODY', index: 2 });
|
|
388
389
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
389
|
-
['slides', 'new-slide', 'p1', '--layout=TITLE_AND_BODY', '--index=2'],
|
|
390
|
+
['slides', 'new-slide', pos('p1'), '--layout=TITLE_AND_BODY', '--index=2'],
|
|
390
391
|
{ account: undefined },
|
|
391
392
|
);
|
|
392
393
|
});
|
|
393
394
|
it('passes layoutId', async () => {
|
|
394
395
|
await harness.callTool('gog_slides_new_slide', { presentationId: 'p1', layoutId: 'LAY1' });
|
|
395
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'new-slide', 'p1', '--layout-id=LAY1'], { account: undefined });
|
|
396
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'new-slide', pos('p1'), '--layout-id=LAY1'], { account: undefined });
|
|
396
397
|
});
|
|
397
398
|
it('bare', async () => {
|
|
398
399
|
await harness.callTool('gog_slides_new_slide', { presentationId: 'p1' });
|
|
399
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'new-slide', 'p1'], { account: undefined });
|
|
400
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'new-slide', pos('p1')], { account: undefined });
|
|
400
401
|
});
|
|
401
402
|
});
|
|
402
403
|
|
|
@@ -404,11 +405,11 @@ describe('gog_slides_duplicate_slide', () => {
|
|
|
404
405
|
it('passes --to-index', async () => {
|
|
405
406
|
await harness.callTool('gog_slides_duplicate_slide', { presentationId: 'p1', slideId: 's1', toIndex: 3 });
|
|
406
407
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
407
|
-
['slides', 'duplicate-slide', 'p1', 's1', '--to-index=3'], { account: undefined });
|
|
408
|
+
['slides', 'duplicate-slide', pos('p1'), pos('s1'), '--to-index=3'], { account: undefined });
|
|
408
409
|
});
|
|
409
410
|
it('bare', async () => {
|
|
410
411
|
await harness.callTool('gog_slides_duplicate_slide', { presentationId: 'p1', slideId: 's1' });
|
|
411
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'duplicate-slide', 'p1', 's1'], { account: undefined });
|
|
412
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'duplicate-slide', pos('p1'), pos('s1')], { account: undefined });
|
|
412
413
|
});
|
|
413
414
|
});
|
|
414
415
|
|
|
@@ -416,7 +417,7 @@ describe('gog_slides_move_slide', () => {
|
|
|
416
417
|
it('passes required --to-index', async () => {
|
|
417
418
|
await harness.callTool('gog_slides_move_slide', { presentationId: 'p1', slideId: 's1', toIndex: 0 });
|
|
418
419
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
419
|
-
['slides', 'move-slide', 'p1', 's1', '--to-index=0'], { account: undefined });
|
|
420
|
+
['slides', 'move-slide', pos('p1'), pos('s1'), '--to-index=0'], { account: undefined });
|
|
420
421
|
});
|
|
421
422
|
});
|
|
422
423
|
|
|
@@ -426,13 +427,13 @@ describe('gog_slides_insert_text', () => {
|
|
|
426
427
|
presentationId: 'p1', objectId: 'o1', text: 'hi', row: 0, col: 1, insertionIndex: 2, replace: true,
|
|
427
428
|
});
|
|
428
429
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
429
|
-
['slides', 'insert-text', 'p1', 'o1', 'hi', '--row=0', '--col=1', '--insertion-index=2', '--replace'],
|
|
430
|
+
['slides', 'insert-text', pos('p1'), pos('o1'), pos('hi'), '--row=0', '--col=1', '--insertion-index=2', '--replace'],
|
|
430
431
|
{ account: undefined },
|
|
431
432
|
);
|
|
432
433
|
});
|
|
433
434
|
it('bare', async () => {
|
|
434
435
|
await harness.callTool('gog_slides_insert_text', { presentationId: 'p1', objectId: 'o1', text: 'hi' });
|
|
435
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'insert-text', 'p1', 'o1', 'hi'], { account: undefined });
|
|
436
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'insert-text', pos('p1'), pos('o1'), pos('hi')], { account: undefined });
|
|
436
437
|
});
|
|
437
438
|
});
|
|
438
439
|
|
|
@@ -443,14 +444,14 @@ describe('gog_slides_style_text', () => {
|
|
|
443
444
|
bold: true, noBold: true, italic: true, noItalic: true, underline: true, noUnderline: true,
|
|
444
445
|
});
|
|
445
446
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
446
|
-
['slides', 'style-text', 'p1', 'o1', '--range=0:5', '--font=Arial', '--size=18', '--text-color=#ff0000',
|
|
447
|
+
['slides', 'style-text', pos('p1'), pos('o1'), '--range=0:5', '--font=Arial', '--size=18', '--text-color=#ff0000',
|
|
447
448
|
'--bold', '--no-bold', '--italic', '--no-italic', '--underline', '--no-underline'],
|
|
448
449
|
{ account: undefined },
|
|
449
450
|
);
|
|
450
451
|
});
|
|
451
452
|
it('minimal (range only)', async () => {
|
|
452
453
|
await harness.callTool('gog_slides_style_text', { presentationId: 'p1', objectId: 'o1', range: '0:5' });
|
|
453
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'style-text', 'p1', 'o1', '--range=0:5'], { account: undefined });
|
|
454
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'style-text', pos('p1'), pos('o1'), '--range=0:5'], { account: undefined });
|
|
454
455
|
});
|
|
455
456
|
});
|
|
456
457
|
|
|
@@ -458,12 +459,12 @@ describe('gog_slides_link', () => {
|
|
|
458
459
|
it('applies a url', async () => {
|
|
459
460
|
await harness.callTool('gog_slides_link', { presentationId: 'p1', objectId: 'o1', range: '0:5', url: 'https://x.test' });
|
|
460
461
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
461
|
-
['slides', 'link', 'p1', 'o1', '--range=0:5', '--url=https://x.test'], { account: undefined });
|
|
462
|
+
['slides', 'link', pos('p1'), pos('o1'), '--range=0:5', '--url=https://x.test'], { account: undefined });
|
|
462
463
|
});
|
|
463
464
|
it('clears the link', async () => {
|
|
464
465
|
await harness.callTool('gog_slides_link', { presentationId: 'p1', objectId: 'o1', range: '0:5', clear: true });
|
|
465
466
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
466
|
-
['slides', 'link', 'p1', 'o1', '--range=0:5', '--clear'], { account: undefined });
|
|
467
|
+
['slides', 'link', pos('p1'), pos('o1'), '--range=0:5', '--clear'], { account: undefined });
|
|
467
468
|
});
|
|
468
469
|
});
|
|
469
470
|
|
|
@@ -471,12 +472,12 @@ describe('gog_slides_bullets', () => {
|
|
|
471
472
|
it('turns bullets on with a preset', async () => {
|
|
472
473
|
await harness.callTool('gog_slides_bullets', { presentationId: 'p1', objectId: 'o1', range: '0:5', on: true, preset: 'BULLET_DISC_CIRCLE_SQUARE' });
|
|
473
474
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
474
|
-
['slides', 'bullets', 'p1', 'o1', '--range=0:5', '--on', '--preset=BULLET_DISC_CIRCLE_SQUARE'], { account: undefined });
|
|
475
|
+
['slides', 'bullets', pos('p1'), pos('o1'), '--range=0:5', '--on', '--preset=BULLET_DISC_CIRCLE_SQUARE'], { account: undefined });
|
|
475
476
|
});
|
|
476
477
|
it('turns bullets off', async () => {
|
|
477
478
|
await harness.callTool('gog_slides_bullets', { presentationId: 'p1', objectId: 'o1', range: '0:5', off: true });
|
|
478
479
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
479
|
-
['slides', 'bullets', 'p1', 'o1', '--range=0:5', '--off'], { account: undefined });
|
|
480
|
+
['slides', 'bullets', pos('p1'), pos('o1'), '--range=0:5', '--off'], { account: undefined });
|
|
480
481
|
});
|
|
481
482
|
});
|
|
482
483
|
|
|
@@ -484,17 +485,17 @@ describe('gog_slides_replace_text', () => {
|
|
|
484
485
|
it('scopes to a single object', async () => {
|
|
485
486
|
await harness.callTool('gog_slides_replace_text', { presentationId: 'p1', find: 'a', replacement: 'b', object: 'o1', matchCase: true });
|
|
486
487
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
487
|
-
['slides', 'replace-text', 'p1', 'a', 'b', '--object=o1', '--match-case'], { account: undefined });
|
|
488
|
+
['slides', 'replace-text', pos('p1'), pos('a'), pos('b'), '--object=o1', '--match-case'], { account: undefined });
|
|
488
489
|
});
|
|
489
490
|
it('scopes to specific pages (repeatable)', async () => {
|
|
490
491
|
await harness.callTool('gog_slides_replace_text', { presentationId: 'p1', find: 'a', replacement: 'b', pages: ['s1', 's2'] });
|
|
491
492
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
492
|
-
['slides', 'replace-text', 'p1', 'a', 'b', '--page=s1', '--page=s2'], { account: undefined });
|
|
493
|
+
['slides', 'replace-text', pos('p1'), pos('a'), pos('b'), '--page=s1', '--page=s2'], { account: undefined });
|
|
493
494
|
});
|
|
494
495
|
it('scopes to the whole presentation', async () => {
|
|
495
496
|
await harness.callTool('gog_slides_replace_text', { presentationId: 'p1', find: 'a', replacement: 'b', all: true });
|
|
496
497
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
497
|
-
['slides', 'replace-text', 'p1', 'a', 'b', '--all'], { account: undefined });
|
|
498
|
+
['slides', 'replace-text', pos('p1'), pos('a'), pos('b'), '--all'], { account: undefined });
|
|
498
499
|
});
|
|
499
500
|
});
|
|
500
501
|
|
|
@@ -504,13 +505,13 @@ describe('gog_slides_element_create_shape', () => {
|
|
|
504
505
|
presentationId: 'p1', slideId: 's1', type: 'RECTANGLE', x: 10, y: 20, width: 100, height: 50, unit: 'PT', objectId: 'shape1',
|
|
505
506
|
});
|
|
506
507
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
507
|
-
['slides', 'element', 'create-shape', 'p1', 's1', '--type=RECTANGLE', '--x=10', '--y=20', '--width=100', '--height=50', '--unit=PT', '--object-id=shape1'],
|
|
508
|
+
['slides', 'element', 'create-shape', pos('p1'), pos('s1'), '--type=RECTANGLE', '--x=10', '--y=20', '--width=100', '--height=50', '--unit=PT', '--object-id=shape1'],
|
|
508
509
|
{ account: undefined },
|
|
509
510
|
);
|
|
510
511
|
});
|
|
511
512
|
it('bare', async () => {
|
|
512
513
|
await harness.callTool('gog_slides_element_create_shape', { presentationId: 'p1', slideId: 's1' });
|
|
513
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'create-shape', 'p1', 's1'], { account: undefined });
|
|
514
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'create-shape', pos('p1'), pos('s1')], { account: undefined });
|
|
514
515
|
});
|
|
515
516
|
});
|
|
516
517
|
|
|
@@ -520,13 +521,13 @@ describe('gog_slides_element_create_line', () => {
|
|
|
520
521
|
presentationId: 'p1', slideId: 's1', category: 'BENT', x: 10, y: 20, width: 100, height: 50, unit: 'EMU', objectId: 'line1',
|
|
521
522
|
});
|
|
522
523
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
523
|
-
['slides', 'element', 'create-line', 'p1', 's1', '--category=BENT', '--x=10', '--y=20', '--width=100', '--height=50', '--unit=EMU', '--object-id=line1'],
|
|
524
|
+
['slides', 'element', 'create-line', pos('p1'), pos('s1'), '--category=BENT', '--x=10', '--y=20', '--width=100', '--height=50', '--unit=EMU', '--object-id=line1'],
|
|
524
525
|
{ account: undefined },
|
|
525
526
|
);
|
|
526
527
|
});
|
|
527
528
|
it('bare', async () => {
|
|
528
529
|
await harness.callTool('gog_slides_element_create_line', { presentationId: 'p1', slideId: 's1' });
|
|
529
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'create-line', 'p1', 's1'], { account: undefined });
|
|
530
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'create-line', pos('p1'), pos('s1')], { account: undefined });
|
|
530
531
|
});
|
|
531
532
|
});
|
|
532
533
|
|
|
@@ -537,14 +538,14 @@ describe('gog_slides_element_style', () => {
|
|
|
537
538
|
outlineColor: '#000', outlineWeight: 2, outlineDash: 'DASH', outlineTransparent: true,
|
|
538
539
|
});
|
|
539
540
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
540
|
-
['slides', 'element', 'style', 'p1', 'o1', '--kind=shape', '--fill-color=#fff', '--fill-transparent',
|
|
541
|
+
['slides', 'element', 'style', pos('p1'), pos('o1'), '--kind=shape', '--fill-color=#fff', '--fill-transparent',
|
|
541
542
|
'--outline-color=#000', '--outline-weight=2', '--outline-dash=DASH', '--outline-transparent'],
|
|
542
543
|
{ account: undefined },
|
|
543
544
|
);
|
|
544
545
|
});
|
|
545
546
|
it('bare', async () => {
|
|
546
547
|
await harness.callTool('gog_slides_element_style', { presentationId: 'p1', objectId: 'o1' });
|
|
547
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'style', 'p1', 'o1'], { account: undefined });
|
|
548
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'style', pos('p1'), pos('o1')], { account: undefined });
|
|
548
549
|
});
|
|
549
550
|
});
|
|
550
551
|
|
|
@@ -555,14 +556,14 @@ describe('gog_slides_element_transform', () => {
|
|
|
555
556
|
shearX: 0.1, shearY: 0.2, rotate: 45, applyMode: 'ABSOLUTE', unit: 'PT',
|
|
556
557
|
});
|
|
557
558
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
558
|
-
['slides', 'element', 'transform', 'p1', 'o1', '--translate-x=10', '--translate-y=20', '--scale-x=1.5', '--scale-y=2',
|
|
559
|
+
['slides', 'element', 'transform', pos('p1'), pos('o1'), '--translate-x=10', '--translate-y=20', '--scale-x=1.5', '--scale-y=2',
|
|
559
560
|
'--shear-x=0.1', '--shear-y=0.2', '--rotate=45', '--apply-mode=ABSOLUTE', '--unit=PT'],
|
|
560
561
|
{ account: undefined },
|
|
561
562
|
);
|
|
562
563
|
});
|
|
563
564
|
it('bare', async () => {
|
|
564
565
|
await harness.callTool('gog_slides_element_transform', { presentationId: 'p1', objectId: 'o1' });
|
|
565
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'transform', 'p1', 'o1'], { account: undefined });
|
|
566
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'transform', pos('p1'), pos('o1')], { account: undefined });
|
|
566
567
|
});
|
|
567
568
|
});
|
|
568
569
|
|
|
@@ -570,7 +571,7 @@ describe('gog_slides_element_z_order', () => {
|
|
|
570
571
|
it('passes the operation', async () => {
|
|
571
572
|
await harness.callTool('gog_slides_element_z_order', { presentationId: 'p1', objectId: 'o1', operation: 'BRING_TO_FRONT' });
|
|
572
573
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
573
|
-
['slides', 'element', 'z-order', 'p1', 'o1', '--operation=BRING_TO_FRONT'], { account: undefined });
|
|
574
|
+
['slides', 'element', 'z-order', pos('p1'), pos('o1'), '--operation=BRING_TO_FRONT'], { account: undefined });
|
|
574
575
|
});
|
|
575
576
|
});
|
|
576
577
|
|
|
@@ -578,12 +579,12 @@ describe('gog_slides_element_group', () => {
|
|
|
578
579
|
it('groups elements with a group id', async () => {
|
|
579
580
|
await harness.callTool('gog_slides_element_group', { presentationId: 'p1', objectIds: ['o1', 'o2', 'o3'], groupId: 'g1' });
|
|
580
581
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
581
|
-
['slides', 'element', 'group', 'p1', 'o1', 'o2', 'o3', '--group-id=g1'], { account: undefined });
|
|
582
|
+
['slides', 'element', 'group', pos('p1'), pos('o1'), pos('o2'), pos('o3'), '--group-id=g1'], { account: undefined });
|
|
582
583
|
});
|
|
583
584
|
it('groups elements without a group id', async () => {
|
|
584
585
|
await harness.callTool('gog_slides_element_group', { presentationId: 'p1', objectIds: ['o1', 'o2'] });
|
|
585
586
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
586
|
-
['slides', 'element', 'group', 'p1', 'o1', 'o2'], { account: undefined });
|
|
587
|
+
['slides', 'element', 'group', pos('p1'), pos('o1'), pos('o2')], { account: undefined });
|
|
587
588
|
});
|
|
588
589
|
});
|
|
589
590
|
|
|
@@ -591,7 +592,7 @@ describe('gog_slides_element_ungroup', () => {
|
|
|
591
592
|
it('ungroups groups', async () => {
|
|
592
593
|
await harness.callTool('gog_slides_element_ungroup', { presentationId: 'p1', groupIds: ['g1', 'g2'] });
|
|
593
594
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
594
|
-
['slides', 'element', 'ungroup', 'p1', 'g1', 'g2'], { account: undefined });
|
|
595
|
+
['slides', 'element', 'ungroup', pos('p1'), pos('g1'), pos('g2')], { account: undefined });
|
|
595
596
|
});
|
|
596
597
|
});
|
|
597
598
|
|
|
@@ -599,23 +600,23 @@ describe('gog_slides_element_alt_text', () => {
|
|
|
599
600
|
it('sets title and description', async () => {
|
|
600
601
|
await harness.callTool('gog_slides_element_alt_text', { presentationId: 'p1', objectId: 'o1', title: 'T', description: 'D' });
|
|
601
602
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
602
|
-
['slides', 'element', 'alt-text', 'p1', 'o1', '--title=T', '--description=D'], { account: undefined });
|
|
603
|
+
['slides', 'element', 'alt-text', pos('p1'), pos('o1'), '--title=T', '--description=D'], { account: undefined });
|
|
603
604
|
});
|
|
604
605
|
it('clears both fields with empty strings', async () => {
|
|
605
606
|
await harness.callTool('gog_slides_element_alt_text', { presentationId: 'p1', objectId: 'o1', title: '', description: '' });
|
|
606
607
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
607
|
-
['slides', 'element', 'alt-text', 'p1', 'o1', '--title=', '--description='], { account: undefined });
|
|
608
|
+
['slides', 'element', 'alt-text', pos('p1'), pos('o1'), '--title=', '--description='], { account: undefined });
|
|
608
609
|
});
|
|
609
610
|
it('bare leaves both untouched', async () => {
|
|
610
611
|
await harness.callTool('gog_slides_element_alt_text', { presentationId: 'p1', objectId: 'o1' });
|
|
611
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'alt-text', 'p1', 'o1'], { account: undefined });
|
|
612
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'alt-text', pos('p1'), pos('o1')], { account: undefined });
|
|
612
613
|
});
|
|
613
614
|
});
|
|
614
615
|
|
|
615
616
|
describe('gog_slides_element_delete', () => {
|
|
616
617
|
it('deletes an element', async () => {
|
|
617
618
|
await harness.callTool('gog_slides_element_delete', { presentationId: 'p1', objectId: 'o1' });
|
|
618
|
-
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'delete', 'p1', 'o1', '--force'], { account: undefined });
|
|
619
|
+
expect(lib.runOrDiagnose).toHaveBeenCalledWith(['slides', 'element', 'delete', pos('p1'), pos('o1'), '--force'], { account: undefined });
|
|
619
620
|
});
|
|
620
621
|
});
|
|
621
622
|
|
|
@@ -627,12 +628,12 @@ describe('gog_slides_table_create', () => {
|
|
|
627
628
|
it('passes rows, cols and object id', async () => {
|
|
628
629
|
await harness.callTool('gog_slides_table_create', { presentationId: 'p1', slideId: 's1', rows: 3, cols: 4, objectId: 'tbl1' });
|
|
629
630
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
630
|
-
['slides', 'table', 'create', 'p1', 's1', '--rows=3', '--cols=4', '--object-id=tbl1'], { account: undefined });
|
|
631
|
+
['slides', 'table', 'create', pos('p1'), pos('s1'), '--rows=3', '--cols=4', '--object-id=tbl1'], { account: undefined });
|
|
631
632
|
});
|
|
632
633
|
it('bare', async () => {
|
|
633
634
|
await harness.callTool('gog_slides_table_create', { presentationId: 'p1', slideId: 's1', rows: 2, cols: 2 });
|
|
634
635
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
635
|
-
['slides', 'table', 'create', 'p1', 's1', '--rows=2', '--cols=2'], { account: undefined });
|
|
636
|
+
['slides', 'table', 'create', pos('p1'), pos('s1'), '--rows=2', '--cols=2'], { account: undefined });
|
|
636
637
|
});
|
|
637
638
|
});
|
|
638
639
|
|
|
@@ -644,7 +645,7 @@ describe('gog_slides_table_cell_style', () => {
|
|
|
644
645
|
bold: true, noBold: true, italic: true, noItalic: true, underline: true, noUnderline: true,
|
|
645
646
|
});
|
|
646
647
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
647
|
-
['slides', 'table', 'cell', 'style', 'p1', 't1', '--row=0', '--col=1', '--range=0:3', '--fill-color=#eee', '--fill-transparent',
|
|
648
|
+
['slides', 'table', 'cell', 'style', pos('p1'), pos('t1'), '--row=0', '--col=1', '--range=0:3', '--fill-color=#eee', '--fill-transparent',
|
|
648
649
|
'--content-align=MIDDLE', '--font=Arial', '--size=12', '--text-color=#111',
|
|
649
650
|
'--bold', '--no-bold', '--italic', '--no-italic', '--underline', '--no-underline'],
|
|
650
651
|
{ account: undefined },
|
|
@@ -653,7 +654,7 @@ describe('gog_slides_table_cell_style', () => {
|
|
|
653
654
|
it('minimal (row/col only)', async () => {
|
|
654
655
|
await harness.callTool('gog_slides_table_cell_style', { presentationId: 'p1', tableObjectId: 't1', row: 0, col: 0 });
|
|
655
656
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
656
|
-
['slides', 'table', 'cell', 'style', 'p1', 't1', '--row=0', '--col=0'], { account: undefined });
|
|
657
|
+
['slides', 'table', 'cell', 'style', pos('p1'), pos('t1'), '--row=0', '--col=0'], { account: undefined });
|
|
657
658
|
});
|
|
658
659
|
});
|
|
659
660
|
|
|
@@ -664,7 +665,7 @@ describe('gog_slides_table_border_style', () => {
|
|
|
664
665
|
position: 'OUTER', borderColor: '#000', weight: 2, dash: 'DASH', transparent: true,
|
|
665
666
|
});
|
|
666
667
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
667
|
-
['slides', 'table', 'border', 'style', 'p1', 't1', '--row=0', '--col=0', '--row-span=2', '--col-span=2',
|
|
668
|
+
['slides', 'table', 'border', 'style', pos('p1'), pos('t1'), '--row=0', '--col=0', '--row-span=2', '--col-span=2',
|
|
668
669
|
'--position=OUTER', '--border-color=#000', '--weight=2', '--dash=DASH', '--transparent'],
|
|
669
670
|
{ account: undefined },
|
|
670
671
|
);
|
|
@@ -672,7 +673,7 @@ describe('gog_slides_table_border_style', () => {
|
|
|
672
673
|
it('minimal (row/col only)', async () => {
|
|
673
674
|
await harness.callTool('gog_slides_table_border_style', { presentationId: 'p1', tableObjectId: 't1', row: 1, col: 1 });
|
|
674
675
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
675
|
-
['slides', 'table', 'border', 'style', 'p1', 't1', '--row=1', '--col=1'], { account: undefined });
|
|
676
|
+
['slides', 'table', 'border', 'style', pos('p1'), pos('t1'), '--row=1', '--col=1'], { account: undefined });
|
|
676
677
|
});
|
|
677
678
|
});
|
|
678
679
|
|
|
@@ -680,12 +681,12 @@ describe('gog_slides_table_column_insert', () => {
|
|
|
680
681
|
it('passes count and --right', async () => {
|
|
681
682
|
await harness.callTool('gog_slides_table_column_insert', { presentationId: 'p1', tableObjectId: 't1', col: 1, count: 2, right: true });
|
|
682
683
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
683
|
-
['slides', 'table', 'column', 'insert', 'p1', 't1', '--col=1', '--count=2', '--right'], { account: undefined });
|
|
684
|
+
['slides', 'table', 'column', 'insert', pos('p1'), pos('t1'), '--col=1', '--count=2', '--right'], { account: undefined });
|
|
684
685
|
});
|
|
685
686
|
it('bare', async () => {
|
|
686
687
|
await harness.callTool('gog_slides_table_column_insert', { presentationId: 'p1', tableObjectId: 't1', col: 0 });
|
|
687
688
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
688
|
-
['slides', 'table', 'column', 'insert', 'p1', 't1', '--col=0'], { account: undefined });
|
|
689
|
+
['slides', 'table', 'column', 'insert', pos('p1'), pos('t1'), '--col=0'], { account: undefined });
|
|
689
690
|
});
|
|
690
691
|
});
|
|
691
692
|
|
|
@@ -693,7 +694,7 @@ describe('gog_slides_table_column_delete', () => {
|
|
|
693
694
|
it('deletes by column index', async () => {
|
|
694
695
|
await harness.callTool('gog_slides_table_column_delete', { presentationId: 'p1', tableObjectId: 't1', col: 2 });
|
|
695
696
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
696
|
-
['slides', 'table', 'column', 'delete', 'p1', 't1', '--col=2', '--force'], { account: undefined });
|
|
697
|
+
['slides', 'table', 'column', 'delete', pos('p1'), pos('t1'), '--col=2', '--force'], { account: undefined });
|
|
697
698
|
});
|
|
698
699
|
});
|
|
699
700
|
|
|
@@ -701,7 +702,7 @@ describe('gog_slides_table_column_size', () => {
|
|
|
701
702
|
it('sets column width', async () => {
|
|
702
703
|
await harness.callTool('gog_slides_table_column_size', { presentationId: 'p1', tableObjectId: 't1', col: 1, width: 120 });
|
|
703
704
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
704
|
-
['slides', 'table', 'column', 'size', 'p1', 't1', '--col=1', '--width=120'], { account: undefined });
|
|
705
|
+
['slides', 'table', 'column', 'size', pos('p1'), pos('t1'), '--col=1', '--width=120'], { account: undefined });
|
|
705
706
|
});
|
|
706
707
|
});
|
|
707
708
|
|
|
@@ -709,12 +710,12 @@ describe('gog_slides_table_row_insert', () => {
|
|
|
709
710
|
it('passes count and --below', async () => {
|
|
710
711
|
await harness.callTool('gog_slides_table_row_insert', { presentationId: 'p1', tableObjectId: 't1', row: 0, count: 1, below: true });
|
|
711
712
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
712
|
-
['slides', 'table', 'row', 'insert', 'p1', 't1', '--row=0', '--count=1', '--below'], { account: undefined });
|
|
713
|
+
['slides', 'table', 'row', 'insert', pos('p1'), pos('t1'), '--row=0', '--count=1', '--below'], { account: undefined });
|
|
713
714
|
});
|
|
714
715
|
it('bare', async () => {
|
|
715
716
|
await harness.callTool('gog_slides_table_row_insert', { presentationId: 'p1', tableObjectId: 't1', row: 1 });
|
|
716
717
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
717
|
-
['slides', 'table', 'row', 'insert', 'p1', 't1', '--row=1'], { account: undefined });
|
|
718
|
+
['slides', 'table', 'row', 'insert', pos('p1'), pos('t1'), '--row=1'], { account: undefined });
|
|
718
719
|
});
|
|
719
720
|
});
|
|
720
721
|
|
|
@@ -722,7 +723,7 @@ describe('gog_slides_table_row_delete', () => {
|
|
|
722
723
|
it('deletes by row index', async () => {
|
|
723
724
|
await harness.callTool('gog_slides_table_row_delete', { presentationId: 'p1', tableObjectId: 't1', row: 2 });
|
|
724
725
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
725
|
-
['slides', 'table', 'row', 'delete', 'p1', 't1', '--row=2', '--force'], { account: undefined });
|
|
726
|
+
['slides', 'table', 'row', 'delete', pos('p1'), pos('t1'), '--row=2', '--force'], { account: undefined });
|
|
726
727
|
});
|
|
727
728
|
});
|
|
728
729
|
|
|
@@ -730,7 +731,7 @@ describe('gog_slides_table_row_size', () => {
|
|
|
730
731
|
it('sets row min height', async () => {
|
|
731
732
|
await harness.callTool('gog_slides_table_row_size', { presentationId: 'p1', tableObjectId: 't1', row: 0, height: 40 });
|
|
732
733
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
733
|
-
['slides', 'table', 'row', 'size', 'p1', 't1', '--row=0', '--height=40'], { account: undefined });
|
|
734
|
+
['slides', 'table', 'row', 'size', pos('p1'), pos('t1'), '--row=0', '--height=40'], { account: undefined });
|
|
734
735
|
});
|
|
735
736
|
});
|
|
736
737
|
|
|
@@ -738,12 +739,12 @@ describe('gog_slides_table_merge', () => {
|
|
|
738
739
|
it('passes span', async () => {
|
|
739
740
|
await harness.callTool('gog_slides_table_merge', { presentationId: 'p1', tableObjectId: 't1', row: 0, col: 0, rowSpan: 2, colSpan: 3 });
|
|
740
741
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
741
|
-
['slides', 'table', 'merge', 'p1', 't1', '--row=0', '--col=0', '--row-span=2', '--col-span=3'], { account: undefined });
|
|
742
|
+
['slides', 'table', 'merge', pos('p1'), pos('t1'), '--row=0', '--col=0', '--row-span=2', '--col-span=3'], { account: undefined });
|
|
742
743
|
});
|
|
743
744
|
it('minimal', async () => {
|
|
744
745
|
await harness.callTool('gog_slides_table_merge', { presentationId: 'p1', tableObjectId: 't1', row: 0, col: 0 });
|
|
745
746
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
746
|
-
['slides', 'table', 'merge', 'p1', 't1', '--row=0', '--col=0'], { account: undefined });
|
|
747
|
+
['slides', 'table', 'merge', pos('p1'), pos('t1'), '--row=0', '--col=0'], { account: undefined });
|
|
747
748
|
});
|
|
748
749
|
});
|
|
749
750
|
|
|
@@ -751,12 +752,12 @@ describe('gog_slides_table_unmerge', () => {
|
|
|
751
752
|
it('passes span', async () => {
|
|
752
753
|
await harness.callTool('gog_slides_table_unmerge', { presentationId: 'p1', tableObjectId: 't1', row: 0, col: 0, rowSpan: 2, colSpan: 2 });
|
|
753
754
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
754
|
-
['slides', 'table', 'unmerge', 'p1', 't1', '--row=0', '--col=0', '--row-span=2', '--col-span=2'], { account: undefined });
|
|
755
|
+
['slides', 'table', 'unmerge', pos('p1'), pos('t1'), '--row=0', '--col=0', '--row-span=2', '--col-span=2'], { account: undefined });
|
|
755
756
|
});
|
|
756
757
|
it('minimal', async () => {
|
|
757
758
|
await harness.callTool('gog_slides_table_unmerge', { presentationId: 'p1', tableObjectId: 't1', row: 1, col: 1 });
|
|
758
759
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
759
|
-
['slides', 'table', 'unmerge', 'p1', 't1', '--row=1', '--col=1'], { account: undefined });
|
|
760
|
+
['slides', 'table', 'unmerge', pos('p1'), pos('t1'), '--row=1', '--col=1'], { account: undefined });
|
|
760
761
|
});
|
|
761
762
|
});
|
|
762
763
|
|
|
@@ -764,7 +765,7 @@ describe('gog_slides_skip_slide', () => {
|
|
|
764
765
|
it('calls runOrDiagnose with presentationId and slideId', async () => {
|
|
765
766
|
await harness.callTool('gog_slides_skip_slide', { presentationId: 'p1', slideId: 's1' });
|
|
766
767
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
767
|
-
['slides', 'skip-slide', 'p1', 's1'],
|
|
768
|
+
['slides', 'skip-slide', pos('p1'), pos('s1')],
|
|
768
769
|
{ account: undefined },
|
|
769
770
|
);
|
|
770
771
|
});
|
|
@@ -772,7 +773,7 @@ describe('gog_slides_skip_slide', () => {
|
|
|
772
773
|
it('passes the account through', async () => {
|
|
773
774
|
await harness.callTool('gog_slides_skip_slide', { presentationId: 'p1', slideId: 's1', account: 'me@x.com' });
|
|
774
775
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
775
|
-
['slides', 'skip-slide', 'p1', 's1'],
|
|
776
|
+
['slides', 'skip-slide', pos('p1'), pos('s1')],
|
|
776
777
|
{ account: 'me@x.com' },
|
|
777
778
|
);
|
|
778
779
|
});
|
|
@@ -782,8 +783,51 @@ describe('gog_slides_unskip_slide', () => {
|
|
|
782
783
|
it('calls runOrDiagnose with presentationId and slideId', async () => {
|
|
783
784
|
await harness.callTool('gog_slides_unskip_slide', { presentationId: 'p1', slideId: 's1' });
|
|
784
785
|
expect(lib.runOrDiagnose).toHaveBeenCalledWith(
|
|
785
|
-
['slides', 'unskip-slide', 'p1', 's1'],
|
|
786
|
-
{ account: undefined },
|
|
787
|
-
);
|
|
786
|
+
['slides', 'unskip-slide', pos('p1'), pos('s1')],
|
|
787
|
+
{ account: undefined },
|
|
788
|
+
);
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
|
|
792
|
+
// SEC-3/SEC-4: every model-supplied server path must resolve inside an
|
|
793
|
+
// operator-configured root (GOG_FILE_ROOTS). The suite runs with '/' so the
|
|
794
|
+
// arg-shape tests can use any path; these narrow it.
|
|
795
|
+
async function withFileRoots<T>(roots: string, fn: () => Promise<T>): Promise<T> {
|
|
796
|
+
const prev = process.env.GOG_FILE_ROOTS;
|
|
797
|
+
process.env.GOG_FILE_ROOTS = roots;
|
|
798
|
+
try {
|
|
799
|
+
return await fn();
|
|
800
|
+
} finally {
|
|
801
|
+
process.env.GOG_FILE_ROOTS = prev;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
describe('server paths are confined to GOG_FILE_ROOTS', () => {
|
|
806
|
+
it.each([
|
|
807
|
+
['gog_slides_create_from_markdown', {"title": "t", "contentFile": "/etc/passwd"}, 'contentFile'],
|
|
808
|
+
['gog_slides_create_from_template', {"templateId": "t", "title": "x", "replacementsFile": "/etc/passwd"}, 'replacementsFile'],
|
|
809
|
+
['gog_slides_add_slide', {"presentationId": "p", "image": "/etc/passwd"}, 'image'],
|
|
810
|
+
['gog_slides_add_slide', {"presentationId": "p", "image": "/srv/gog-files/a.png", "notesFile": "/etc/passwd"}, 'notesFile'],
|
|
811
|
+
['gog_slides_insert_image', {"presentationId": "p", "slideId": "s", "image": "/etc/passwd", "width": 10}, 'image'],
|
|
812
|
+
['gog_slides_update_notes', {"presentationId": "p", "slideId": "s", "notesFile": "/etc/passwd"}, 'notesFile'],
|
|
813
|
+
['gog_slides_replace_slide', {"presentationId": "p", "slideId": "s", "image": "/etc/passwd"}, 'image'],
|
|
814
|
+
['gog_slides_replace_slide', {"presentationId": "p", "slideId": "s", "notesFile": "/etc/passwd"}, 'notesFile'],
|
|
815
|
+
['gog_slides_thumbnail', {"presentationId": "p", "slideId": "s", "out": "/Users/me/.zshrc"}, 'out'],
|
|
816
|
+
] as Array<[string, Record<string, unknown>, string]>)('%s refuses %j outside the roots', async (tool, args, param) => {
|
|
817
|
+
const h = harness;
|
|
818
|
+
const result = await withFileRoots('/srv/gog-files', () => h.callTool(tool, args));
|
|
819
|
+
expect(result.isError).toBe(true);
|
|
820
|
+
expect(result.content[0].text).toMatch(new RegExp(`${param} ".*" is outside the directories`));
|
|
821
|
+
expect(lib.runOrDiagnose).not.toHaveBeenCalled();
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
// Clients auto-approve readOnlyHint tools; these write (and can overwrite)
|
|
825
|
+
// files on the gog host, so they must not claim to be read-only.
|
|
826
|
+
it.each(["gog_slides_thumbnail"])('%s is not advertised as read-only and is marked destructive', async (name) => {
|
|
827
|
+
const h = harness;
|
|
828
|
+
const { tools } = await h.client.listTools();
|
|
829
|
+
const tool = tools.find((t) => t.name === name)!;
|
|
830
|
+
expect(tool.annotations?.readOnlyHint).not.toBe(true);
|
|
831
|
+
expect(tool.annotations?.destructiveHint).toBe(true);
|
|
788
832
|
});
|
|
789
833
|
});
|