gogcli-mcp-slides 2.0.4 → 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.
@@ -6,16 +6,16 @@
6
6
  "email": "chris.c.hall@gmail.com"
7
7
  },
8
8
  "metadata": {
9
- "description": "Extended Google Slides for Claude via gogcli auth + full Slides support (create, edit, export, templates, markdown)",
10
- "version": "2.0.4"
9
+ "description": "Extended Google Slides for Claude via gogcli \u2014 auth + full Slides support (create, edit, export, templates, markdown)",
10
+ "version": "2.0.3"
11
11
  },
12
12
  "plugins": [
13
13
  {
14
14
  "name": "gogcli-mcp-slides",
15
15
  "displayName": "gogcli (Slides)",
16
16
  "source": "./",
17
- "description": "Extended Google Slides for Claude via gogcli auth + full Slides support (create, edit, export, templates, markdown)",
18
- "version": "2.0.4",
17
+ "description": "Extended Google Slides for Claude via gogcli \u2014 auth + full Slides support (create, edit, export, templates, markdown)",
18
+ "version": "2.0.3",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "gogcli-mcp-slides",
3
3
  "displayName": "gogcli (Slides)",
4
- "version": "2.0.4",
5
- "description": "Extended Google Slides for Claude via gogcli auth + full Slides support (create, edit, export, templates, markdown)",
4
+ "version": "2.0.3",
5
+ "description": "Extended Google Slides for Claude via gogcli \u2014 auth + full Slides support (create, edit, export, templates, markdown)",
6
6
  "author": {
7
7
  "name": "Chris Hall",
8
8
  "email": "chris.c.hall@gmail.com"
package/dist/index.js CHANGED
@@ -31068,6 +31068,64 @@ function registerSlidesTools(server2) {
31068
31068
  if (template) args.push(`--template=${template}`);
31069
31069
  return runOrDiagnose(args, { account });
31070
31070
  });
31071
+ server2.registerTool("gog_slides_copy", {
31072
+ description: "Copy a Google Slides presentation to a new presentation with the given title.",
31073
+ inputSchema: {
31074
+ presentationId: external_exports.string().describe("Presentation ID to copy"),
31075
+ title: external_exports.string().describe("Title for the new copy"),
31076
+ parent: external_exports.string().optional().describe("Destination folder ID"),
31077
+ account: accountParam
31078
+ }
31079
+ }, async ({ presentationId, title, parent, account }) => {
31080
+ const args = ["slides", "copy", presentationId, title];
31081
+ if (parent) args.push(`--parent=${parent}`);
31082
+ return runOrDiagnose(args, { account });
31083
+ });
31084
+ server2.registerTool("gog_slides_list_slides", {
31085
+ description: "List slides in a Google Slides presentation.",
31086
+ annotations: { readOnlyHint: true },
31087
+ inputSchema: {
31088
+ presentationId: external_exports.string().describe("Presentation ID"),
31089
+ account: accountParam
31090
+ }
31091
+ }, async ({ presentationId, account }) => {
31092
+ return runOrDiagnose(["slides", "list-slides", presentationId], { account });
31093
+ });
31094
+ server2.registerTool("gog_slides_read_slide", {
31095
+ description: "Read the content of a slide (text, shapes, speaker notes).",
31096
+ annotations: { readOnlyHint: true },
31097
+ inputSchema: {
31098
+ presentationId: external_exports.string().describe("Presentation ID"),
31099
+ slideId: external_exports.string().describe("Slide ID to read"),
31100
+ account: accountParam
31101
+ }
31102
+ }, async ({ presentationId, slideId, account }) => {
31103
+ return runOrDiagnose(["slides", "read-slide", presentationId, slideId], { account });
31104
+ });
31105
+ server2.registerTool("gog_slides_run", {
31106
+ description: "Run any gog slides subcommand not covered by the other tools. Run `gog slides --help` for the full list of subcommands, or `gog slides <subcommand> --help` for flags on a specific subcommand.",
31107
+ annotations: { destructiveHint: true },
31108
+ inputSchema: {
31109
+ subcommand: external_exports.string().describe("The gog slides subcommand to run"),
31110
+ args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
31111
+ account: accountParam
31112
+ }
31113
+ }, async ({ subcommand, args, account }) => {
31114
+ return runOrDiagnose(["slides", subcommand, ...args], { account });
31115
+ });
31116
+ }
31117
+
31118
+ // ../gogcli-mcp/src/server.ts
31119
+ var VERSION = true ? "2.0.5" : "0.0.0";
31120
+ function createServer(options) {
31121
+ return new McpServer({
31122
+ name: options?.name ?? "gogcli",
31123
+ version: options?.version ?? VERSION
31124
+ });
31125
+ }
31126
+
31127
+ // src/tools/slides-extra.ts
31128
+ function registerExtraSlidesTools(server2) {
31071
31129
  server2.registerTool("gog_slides_create_from_markdown", {
31072
31130
  description: "Create a new Google Slides presentation from markdown content (inline or from a file).",
31073
31131
  inputSchema: {
@@ -31109,19 +31167,6 @@ function registerSlidesTools(server2) {
31109
31167
  if (exact) args.push("--exact");
31110
31168
  return runOrDiagnose(args, { account });
31111
31169
  });
31112
- server2.registerTool("gog_slides_copy", {
31113
- description: "Copy a Google Slides presentation to a new presentation with the given title.",
31114
- inputSchema: {
31115
- presentationId: external_exports.string().describe("Presentation ID to copy"),
31116
- title: external_exports.string().describe("Title for the new copy"),
31117
- parent: external_exports.string().optional().describe("Destination folder ID"),
31118
- account: accountParam
31119
- }
31120
- }, async ({ presentationId, title, parent, account }) => {
31121
- const args = ["slides", "copy", presentationId, title];
31122
- if (parent) args.push(`--parent=${parent}`);
31123
- return runOrDiagnose(args, { account });
31124
- });
31125
31170
  server2.registerTool("gog_slides_add_slide", {
31126
31171
  description: "Add a new slide to a presentation from a local image, with optional speaker notes.",
31127
31172
  inputSchema: {
@@ -31139,16 +31184,6 @@ function registerSlidesTools(server2) {
31139
31184
  if (before) args.push(`--before=${before}`);
31140
31185
  return runOrDiagnose(args, { account });
31141
31186
  });
31142
- server2.registerTool("gog_slides_list_slides", {
31143
- description: "List slides in a Google Slides presentation.",
31144
- annotations: { readOnlyHint: true },
31145
- inputSchema: {
31146
- presentationId: external_exports.string().describe("Presentation ID"),
31147
- account: accountParam
31148
- }
31149
- }, async ({ presentationId, account }) => {
31150
- return runOrDiagnose(["slides", "list-slides", presentationId], { account });
31151
- });
31152
31187
  server2.registerTool("gog_slides_delete_slide", {
31153
31188
  description: "Delete a slide from a Google Slides presentation.",
31154
31189
  annotations: { destructiveHint: true },
@@ -31160,17 +31195,6 @@ function registerSlidesTools(server2) {
31160
31195
  }, async ({ presentationId, slideId, account }) => {
31161
31196
  return runOrDiagnose(["slides", "delete-slide", presentationId, slideId], { account });
31162
31197
  });
31163
- server2.registerTool("gog_slides_read_slide", {
31164
- description: "Read the content of a slide (text, shapes, speaker notes).",
31165
- annotations: { readOnlyHint: true },
31166
- inputSchema: {
31167
- presentationId: external_exports.string().describe("Presentation ID"),
31168
- slideId: external_exports.string().describe("Slide ID to read"),
31169
- account: accountParam
31170
- }
31171
- }, async ({ presentationId, slideId, account }) => {
31172
- return runOrDiagnose(["slides", "read-slide", presentationId, slideId], { account });
31173
- });
31174
31198
  server2.registerTool("gog_slides_update_notes", {
31175
31199
  description: "Update the speaker notes on a slide (inline text or from a file).",
31176
31200
  annotations: { destructiveHint: true },
@@ -31204,29 +31228,6 @@ function registerSlidesTools(server2) {
31204
31228
  if (notesFile) args.push(`--notes-file=${notesFile}`);
31205
31229
  return runOrDiagnose(args, { account });
31206
31230
  });
31207
- server2.registerTool("gog_slides_run", {
31208
- description: "Run any gog slides subcommand not covered by the other tools. Run `gog slides --help` for the full list of subcommands, or `gog slides <subcommand> --help` for flags on a specific subcommand.",
31209
- inputSchema: {
31210
- subcommand: external_exports.string().describe("The gog slides subcommand to run"),
31211
- args: external_exports.array(external_exports.string()).describe("Additional positional args and flags"),
31212
- account: accountParam
31213
- }
31214
- }, async ({ subcommand, args, account }) => {
31215
- return runOrDiagnose(["slides", subcommand, ...args], { account });
31216
- });
31217
- }
31218
-
31219
- // ../gogcli-mcp/src/server.ts
31220
- var VERSION = true ? "2.0.4" : "0.0.0";
31221
- function createServer(options) {
31222
- return new McpServer({
31223
- name: options?.name ?? "gogcli",
31224
- version: options?.version ?? VERSION
31225
- });
31226
- }
31227
-
31228
- // src/tools/slides-extra.ts
31229
- function registerExtraSlidesTools(_server) {
31230
31231
  }
31231
31232
 
31232
31233
  // src/index.ts
package/manifest.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "manifest_version": "0.3",
4
4
  "name": "gogcli-mcp-slides",
5
5
  "display_name": "gogcli (Slides)",
6
- "version": "2.0.4",
6
+ "version": "2.0.6",
7
7
  "description": "Extended Google Slides for Claude via gogcli — auth + full Slides support (create, edit, export, templates, markdown)",
8
8
  "author": {
9
9
  "name": "Chris Hall",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gogcli-mcp-slides",
3
- "version": "2.0.4",
3
+ "version": "2.0.6",
4
4
  "mcpName": "io.github.chrischall/gogcli-mcp-slides",
5
5
  "description": "Extended Google Slides MCP server via gogcli — auth + full Slides support",
6
6
  "author": "Claude Code (AI) <https://www.anthropic.com/claude>",
package/server.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
3
  "name": "io.github.chrischall/gogcli-mcp-slides",
4
- "description": "Google Slides via gogcli for Claude deck and slide authoring",
4
+ "description": "Google Slides via gogcli for Claude \u2014 deck and slide authoring",
5
5
  "repository": {
6
6
  "url": "https://github.com/chrischall/gogcli-mcp",
7
7
  "source": "github",
8
8
  "subfolder": "packages/gogcli-mcp-slides"
9
9
  },
10
- "version": "2.0.4",
10
+ "version": "2.0.3",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "gogcli-mcp-slides",
15
- "version": "2.0.4",
15
+ "version": "2.0.3",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  },
@@ -1,5 +1,113 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import { accountParam, runOrDiagnose } from '../../../gogcli-mcp/src/lib.js';
2
4
 
3
- export function registerExtraSlidesTools(_server: McpServer): void {
4
- /* no extras yet */
5
+ export function registerExtraSlidesTools(server: McpServer): void {
6
+ server.registerTool('gog_slides_create_from_markdown', {
7
+ description: 'Create a new Google Slides presentation from markdown content (inline or from a file).',
8
+ inputSchema: {
9
+ title: z.string().describe('Presentation title'),
10
+ content: z.string().optional().describe('Inline markdown content'),
11
+ contentFile: z.string().optional().describe('Path to a markdown file'),
12
+ parent: z.string().optional().describe('Destination folder ID'),
13
+ debug: z.boolean().optional().describe('Enable debug output'),
14
+ account: accountParam,
15
+ },
16
+ }, async ({ title, content, contentFile, parent, debug, account }) => {
17
+ const args = ['slides', 'create-from-markdown', title];
18
+ if (content) args.push(`--content=${content}`);
19
+ if (contentFile) args.push(`--content-file=${contentFile}`);
20
+ if (parent) args.push(`--parent=${parent}`);
21
+ if (debug) args.push('--debug');
22
+ return runOrDiagnose(args, { account });
23
+ });
24
+
25
+ server.registerTool('gog_slides_create_from_template', {
26
+ description: 'Create a new Google Slides presentation from a template, with optional placeholder replacements.',
27
+ inputSchema: {
28
+ templateId: z.string().describe('Template presentation ID'),
29
+ title: z.string().describe('New presentation title'),
30
+ replacements: z.record(z.string(), z.string()).optional().describe('Placeholder replacements as a key/value object (emitted as --replace=k=v for each entry)'),
31
+ replacementsFile: z.string().optional().describe('Path to a JSON file containing replacements'),
32
+ parent: z.string().optional().describe('Destination folder ID'),
33
+ exact: z.boolean().optional().describe('Require exact placeholder matches'),
34
+ account: accountParam,
35
+ },
36
+ }, async ({ templateId, title, replacements, replacementsFile, parent, exact, account }) => {
37
+ const args = ['slides', 'create-from-template', templateId, title];
38
+ if (replacements) {
39
+ for (const [k, v] of Object.entries(replacements)) {
40
+ args.push(`--replace=${k}=${v}`);
41
+ }
42
+ }
43
+ if (replacementsFile) args.push(`--replacements=${replacementsFile}`);
44
+ if (parent) args.push(`--parent=${parent}`);
45
+ if (exact) args.push('--exact');
46
+ return runOrDiagnose(args, { account });
47
+ });
48
+
49
+ server.registerTool('gog_slides_add_slide', {
50
+ description: 'Add a new slide to a presentation from a local image, with optional speaker notes.',
51
+ inputSchema: {
52
+ presentationId: z.string().describe('Presentation ID'),
53
+ image: z.string().describe('Path to the local image file'),
54
+ notes: z.string().optional().describe('Speaker notes text'),
55
+ notesFile: z.string().optional().describe('Path to a file containing speaker notes'),
56
+ before: z.string().optional().describe('Insert before this slide ID (default: append at end)'),
57
+ account: accountParam,
58
+ },
59
+ }, async ({ presentationId, image, notes, notesFile, before, account }) => {
60
+ const args = ['slides', 'add-slide', presentationId, image];
61
+ if (notes) args.push(`--notes=${notes}`);
62
+ if (notesFile) args.push(`--notes-file=${notesFile}`);
63
+ if (before) args.push(`--before=${before}`);
64
+ return runOrDiagnose(args, { account });
65
+ });
66
+
67
+ server.registerTool('gog_slides_delete_slide', {
68
+ description: 'Delete a slide from a Google Slides presentation.',
69
+ annotations: { destructiveHint: true },
70
+ inputSchema: {
71
+ presentationId: z.string().describe('Presentation ID'),
72
+ slideId: z.string().describe('Slide ID to delete'),
73
+ account: accountParam,
74
+ },
75
+ }, async ({ presentationId, slideId, account }) => {
76
+ return runOrDiagnose(['slides', 'delete-slide', presentationId, slideId], { account });
77
+ });
78
+
79
+ server.registerTool('gog_slides_update_notes', {
80
+ description: 'Update the speaker notes on a slide (inline text or from a file).',
81
+ annotations: { destructiveHint: true },
82
+ inputSchema: {
83
+ presentationId: z.string().describe('Presentation ID'),
84
+ slideId: z.string().describe('Slide ID'),
85
+ notes: z.string().optional().describe('New speaker notes text'),
86
+ notesFile: z.string().optional().describe('Path to a file containing new speaker notes'),
87
+ account: accountParam,
88
+ },
89
+ }, async ({ presentationId, slideId, notes, notesFile, account }) => {
90
+ const args = ['slides', 'update-notes', presentationId, slideId];
91
+ if (notes) args.push(`--notes=${notes}`);
92
+ if (notesFile) args.push(`--notes-file=${notesFile}`);
93
+ return runOrDiagnose(args, { account });
94
+ });
95
+
96
+ server.registerTool('gog_slides_replace_slide', {
97
+ description: 'Replace the image content of an existing slide, with optional speaker notes.',
98
+ annotations: { destructiveHint: true },
99
+ inputSchema: {
100
+ presentationId: z.string().describe('Presentation ID'),
101
+ slideId: z.string().describe('Slide ID to replace'),
102
+ image: z.string().describe('Path to the new local image file'),
103
+ notes: z.string().optional().describe('Speaker notes text'),
104
+ notesFile: z.string().optional().describe('Path to a file containing speaker notes'),
105
+ account: accountParam,
106
+ },
107
+ }, async ({ presentationId, slideId, image, notes, notesFile, account }) => {
108
+ const args = ['slides', 'replace-slide', presentationId, slideId, image];
109
+ if (notes) args.push(`--notes=${notes}`);
110
+ if (notesFile) args.push(`--notes-file=${notesFile}`);
111
+ return runOrDiagnose(args, { account });
112
+ });
5
113
  }
@@ -1,10 +1,220 @@
1
- import { describe, it, expect } from 'vitest';
2
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
2
  import { registerExtraSlidesTools } from '../../src/tools/slides-extra.js';
3
+ import * as lib from '../../../gogcli-mcp/src/lib.js';
4
+ import { setupExtrasHandlers, toText, type ToolHandler } from '../../../gogcli-mcp/tests/helpers/extras-harness.js';
4
5
 
5
- describe('registerExtraSlidesTools', () => {
6
- it('does not throw when called (no extras yet)', () => {
7
- const server = new McpServer({ name: 'test', version: '0.0.0' });
8
- expect(() => registerExtraSlidesTools(server)).not.toThrow();
6
+ vi.mock('../../../gogcli-mcp/src/lib.js', async (importOriginal) => {
7
+ const actual = await importOriginal<typeof lib>();
8
+ return {
9
+ ...actual,
10
+ runOrDiagnose: vi.fn(),
11
+ };
12
+ });
13
+
14
+ let handlers: Map<string, ToolHandler>;
15
+
16
+ beforeEach(() => {
17
+ vi.clearAllMocks();
18
+ vi.mocked(lib.runOrDiagnose).mockResolvedValue(toText('{}'));
19
+ handlers = setupExtrasHandlers(registerExtraSlidesTools);
20
+ });
21
+
22
+ describe('gog_slides_create_from_markdown', () => {
23
+ it('calls runOrDiagnose with title only', async () => {
24
+ await handlers.get('gog_slides_create_from_markdown')!({ title: 'Deck' });
25
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
26
+ ['slides', 'create-from-markdown', 'Deck'],
27
+ { account: undefined },
28
+ );
29
+ });
30
+
31
+ it('passes all optional flags', async () => {
32
+ await handlers.get('gog_slides_create_from_markdown')!({
33
+ title: 'Deck',
34
+ content: '# Slide 1',
35
+ contentFile: '/tmp/deck.md',
36
+ parent: 'folder1',
37
+ debug: true,
38
+ });
39
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
40
+ [
41
+ 'slides', 'create-from-markdown', 'Deck',
42
+ '--content=# Slide 1',
43
+ '--content-file=/tmp/deck.md',
44
+ '--parent=folder1',
45
+ '--debug',
46
+ ],
47
+ { account: undefined },
48
+ );
49
+ });
50
+
51
+ it('omits --debug when false', async () => {
52
+ await handlers.get('gog_slides_create_from_markdown')!({ title: 'Deck', debug: false });
53
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
54
+ ['slides', 'create-from-markdown', 'Deck'],
55
+ { account: undefined },
56
+ );
57
+ });
58
+ });
59
+
60
+ describe('gog_slides_create_from_template', () => {
61
+ it('calls runOrDiagnose with templateId and title only', async () => {
62
+ await handlers.get('gog_slides_create_from_template')!({ templateId: 'tpl1', title: 'Deck' });
63
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
64
+ ['slides', 'create-from-template', 'tpl1', 'Deck'],
65
+ { account: undefined },
66
+ );
67
+ });
68
+
69
+ it('passes --replace for a single replacement entry', async () => {
70
+ await handlers.get('gog_slides_create_from_template')!({
71
+ templateId: 'tpl1',
72
+ title: 'Deck',
73
+ replacements: { name: 'Alice' },
74
+ });
75
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
76
+ ['slides', 'create-from-template', 'tpl1', 'Deck', '--replace=name=Alice'],
77
+ { account: undefined },
78
+ );
79
+ });
80
+
81
+ it('passes --replace for each entry in replacements', async () => {
82
+ await handlers.get('gog_slides_create_from_template')!({
83
+ templateId: 'tpl1',
84
+ title: 'Deck',
85
+ replacements: { name: 'Alice', company: 'Acme' },
86
+ });
87
+ const call = vi.mocked(lib.runOrDiagnose).mock.calls[0]!;
88
+ expect(call[0]).toEqual(expect.arrayContaining(['--replace=name=Alice', '--replace=company=Acme']));
89
+ expect(call[1]).toEqual({ account: undefined });
90
+ });
91
+
92
+ it('passes --replacements, --parent, and --exact', async () => {
93
+ await handlers.get('gog_slides_create_from_template')!({
94
+ templateId: 'tpl1',
95
+ title: 'Deck',
96
+ replacementsFile: '/tmp/r.json',
97
+ parent: 'folder1',
98
+ exact: true,
99
+ });
100
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
101
+ [
102
+ 'slides', 'create-from-template', 'tpl1', 'Deck',
103
+ '--replacements=/tmp/r.json',
104
+ '--parent=folder1',
105
+ '--exact',
106
+ ],
107
+ { account: undefined },
108
+ );
109
+ });
110
+
111
+ it('omits --exact when false', async () => {
112
+ await handlers.get('gog_slides_create_from_template')!({
113
+ templateId: 'tpl1',
114
+ title: 'Deck',
115
+ exact: false,
116
+ });
117
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
118
+ ['slides', 'create-from-template', 'tpl1', 'Deck'],
119
+ { account: undefined },
120
+ );
121
+ });
122
+ });
123
+
124
+ describe('gog_slides_add_slide', () => {
125
+ it('calls runOrDiagnose with presentationId and image', async () => {
126
+ await handlers.get('gog_slides_add_slide')!({ presentationId: 'p1', image: '/tmp/img.png' });
127
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
128
+ ['slides', 'add-slide', 'p1', '/tmp/img.png'],
129
+ { account: undefined },
130
+ );
131
+ });
132
+
133
+ it('passes --notes, --notes-file, and --before', async () => {
134
+ await handlers.get('gog_slides_add_slide')!({
135
+ presentationId: 'p1',
136
+ image: '/tmp/img.png',
137
+ notes: 'Speaker note',
138
+ notesFile: '/tmp/notes.txt',
139
+ before: 'slide5',
140
+ });
141
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
142
+ [
143
+ 'slides', 'add-slide', 'p1', '/tmp/img.png',
144
+ '--notes=Speaker note',
145
+ '--notes-file=/tmp/notes.txt',
146
+ '--before=slide5',
147
+ ],
148
+ { account: undefined },
149
+ );
150
+ });
151
+ });
152
+
153
+ describe('gog_slides_delete_slide', () => {
154
+ it('calls runOrDiagnose with presentationId and slideId', async () => {
155
+ await handlers.get('gog_slides_delete_slide')!({ presentationId: 'p1', slideId: 's1' });
156
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
157
+ ['slides', 'delete-slide', 'p1', 's1'],
158
+ { account: undefined },
159
+ );
160
+ });
161
+ });
162
+
163
+ describe('gog_slides_update_notes', () => {
164
+ it('calls runOrDiagnose with presentationId and slideId', async () => {
165
+ await handlers.get('gog_slides_update_notes')!({ presentationId: 'p1', slideId: 's1' });
166
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
167
+ ['slides', 'update-notes', 'p1', 's1'],
168
+ { account: undefined },
169
+ );
170
+ });
171
+
172
+ it('passes --notes and --notes-file when provided', async () => {
173
+ await handlers.get('gog_slides_update_notes')!({
174
+ presentationId: 'p1',
175
+ slideId: 's1',
176
+ notes: 'speak clearly',
177
+ notesFile: '/tmp/n.txt',
178
+ });
179
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
180
+ [
181
+ 'slides', 'update-notes', 'p1', 's1',
182
+ '--notes=speak clearly',
183
+ '--notes-file=/tmp/n.txt',
184
+ ],
185
+ { account: undefined },
186
+ );
187
+ });
188
+ });
189
+
190
+ describe('gog_slides_replace_slide', () => {
191
+ it('calls runOrDiagnose with presentationId, slideId, and image', async () => {
192
+ await handlers.get('gog_slides_replace_slide')!({
193
+ presentationId: 'p1',
194
+ slideId: 's1',
195
+ image: '/tmp/img.png',
196
+ });
197
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
198
+ ['slides', 'replace-slide', 'p1', 's1', '/tmp/img.png'],
199
+ { account: undefined },
200
+ );
201
+ });
202
+
203
+ it('passes --notes and --notes-file when provided', async () => {
204
+ await handlers.get('gog_slides_replace_slide')!({
205
+ presentationId: 'p1',
206
+ slideId: 's1',
207
+ image: '/tmp/img.png',
208
+ notes: 'updated',
209
+ notesFile: '/tmp/n.txt',
210
+ });
211
+ expect(lib.runOrDiagnose).toHaveBeenCalledWith(
212
+ [
213
+ 'slides', 'replace-slide', 'p1', 's1', '/tmp/img.png',
214
+ '--notes=updated',
215
+ '--notes-file=/tmp/n.txt',
216
+ ],
217
+ { account: undefined },
218
+ );
9
219
  });
10
220
  });