@tiwater/office-mcp 0.21.38 → 0.21.39
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/_shared/effect-kind.mjs +18 -2
- package/office/contracts/docx_create.schema.json +22 -0
- package/office/contracts/pptx_read_shape.schema.json +49 -0
- package/office/contracts/pptx_read_slide.schema.json +43 -0
- package/office/contracts/tiwater-office-provider-contract-manifest-v1.json +34 -1
- package/office/index.mjs +194 -0
- package/package.json +1 -1
- package/pdf/contracts/tiwater-pdf-provider-contract-manifest-v1.json +1 -1
- package/text/contracts/tiwater-text-provider-contract-manifest-v1.json +1 -1
package/_shared/effect-kind.mjs
CHANGED
|
@@ -5,6 +5,7 @@ export const effectKindSchema = 'tiwater.provider-effect-kind/v1';
|
|
|
5
5
|
export const documentRevisionRoleKey = 'x-tiwater-document-revision-role';
|
|
6
6
|
|
|
7
7
|
const effectKinds = new Set([
|
|
8
|
+
'document-create',
|
|
8
9
|
'document-mutation',
|
|
9
10
|
'source-conversion',
|
|
10
11
|
'native-render',
|
|
@@ -46,10 +47,15 @@ export function assertEffectKindToolContract(tool, expectedKind = undefined) {
|
|
|
46
47
|
if (expectedKind !== undefined && metadata.kind !== expectedKind) {
|
|
47
48
|
throw new Error(`effect-kind-mismatch:${tool?.name || 'unnamed'}:${metadata.kind}`);
|
|
48
49
|
}
|
|
49
|
-
if (!bindings.some(binding => binding.role === 'read')) {
|
|
50
|
+
if (metadata.kind !== 'document-create' && !bindings.some(binding => binding.role === 'read')) {
|
|
50
51
|
throw new Error(`effect-kind-source-binding-missing:${tool?.name || 'unnamed'}`);
|
|
51
52
|
}
|
|
52
|
-
if (metadata.kind === 'document-
|
|
53
|
+
if (metadata.kind === 'document-create') {
|
|
54
|
+
if (bindings.some(binding => binding.role === 'read')
|
|
55
|
+
|| currentDocumentBindings.length !== 0 || effectiveWrites.length !== 1) {
|
|
56
|
+
throw new Error(`document-create-bindings-invalid:${tool?.name || 'unnamed'}`);
|
|
57
|
+
}
|
|
58
|
+
} else if (metadata.kind === 'document-mutation') {
|
|
53
59
|
if (currentDocumentBindings.length !== 1) {
|
|
54
60
|
throw new Error(`document-mutation-current-binding-invalid:${tool?.name || 'unnamed'}`);
|
|
55
61
|
}
|
|
@@ -70,6 +76,16 @@ export function assertEffectKindToolContract(tool, expectedKind = undefined) {
|
|
|
70
76
|
return metadata.kind;
|
|
71
77
|
}
|
|
72
78
|
|
|
79
|
+
export function documentCreateFileArguments(tool, args) {
|
|
80
|
+
assertEffectKindToolContract(tool, 'document-create');
|
|
81
|
+
const bindings = boundFileArguments(tool?.inputSchema, args);
|
|
82
|
+
const effectiveOutput = bindings.filter(binding => binding.role === 'write' && binding.effect);
|
|
83
|
+
if (bindings.some(binding => binding.role === 'read') || effectiveOutput.length !== 1) {
|
|
84
|
+
throw new Error(`document-create-file-arguments-invalid:${tool?.name || 'unnamed'}`);
|
|
85
|
+
}
|
|
86
|
+
return { effectiveOutput: effectiveOutput[0].value };
|
|
87
|
+
}
|
|
88
|
+
|
|
73
89
|
export function documentMutationFileArguments(tool, args) {
|
|
74
90
|
assertEffectKindToolContract(tool, 'document-mutation');
|
|
75
91
|
const bindings = boundFileArguments(tool?.inputSchema, args);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "tiwater.office-mcp-input/docx_create/v1",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"output": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"minLength": 1,
|
|
9
|
+
"description": "New DOCX path. Existing files are never overwritten.",
|
|
10
|
+
"x-tiwater-file-role": "write"
|
|
11
|
+
},
|
|
12
|
+
"receiptOutput": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"minLength": 1,
|
|
15
|
+
"description": "New JSON receipt path. Existing files are never overwritten.",
|
|
16
|
+
"x-tiwater-file-role": "write",
|
|
17
|
+
"x-tiwater-file-effect": false
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"required": ["output", "receiptOutput"],
|
|
21
|
+
"additionalProperties": false
|
|
22
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "tiwater.office-mcp-input/pptx_read_shape/v1",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"input": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"minLength": 1,
|
|
9
|
+
"description": "Current PPTX presentation.",
|
|
10
|
+
"x-tiwater-file-role": "read"
|
|
11
|
+
},
|
|
12
|
+
"slideNumber": {
|
|
13
|
+
"type": "integer",
|
|
14
|
+
"minimum": 1,
|
|
15
|
+
"maximum": 9007199254740991,
|
|
16
|
+
"description": "Exact one-based slide number returned by presentation observation."
|
|
17
|
+
},
|
|
18
|
+
"shapeId": {
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"minimum": 1,
|
|
21
|
+
"maximum": 4294967295,
|
|
22
|
+
"description": "Exact native shape id returned by pptx_read_slide."
|
|
23
|
+
},
|
|
24
|
+
"offset": {
|
|
25
|
+
"type": "integer",
|
|
26
|
+
"minimum": 0,
|
|
27
|
+
"maximum": 9007199254740991,
|
|
28
|
+
"description": "Zero-based text-segment offset within the selected shape. Continue only when another segment is needed."
|
|
29
|
+
},
|
|
30
|
+
"limit": {
|
|
31
|
+
"type": "integer",
|
|
32
|
+
"minimum": 1,
|
|
33
|
+
"maximum": 4,
|
|
34
|
+
"description": "Maximum text segments in this bounded page."
|
|
35
|
+
},
|
|
36
|
+
"returnContent": {
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"description": "Return this selected technical page directly when it fits the response limit. May be combined with output."
|
|
39
|
+
},
|
|
40
|
+
"output": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"minLength": 1,
|
|
43
|
+
"description": "Optional immutable JSON artifact path for this selected technical page. May be combined with returnContent.",
|
|
44
|
+
"x-tiwater-file-role": "write"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"required": ["input", "slideNumber", "shapeId", "limit", "returnContent"],
|
|
48
|
+
"additionalProperties": false
|
|
49
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "tiwater.office-mcp-input/pptx_read_slide/v1",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"properties": {
|
|
6
|
+
"input": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"minLength": 1,
|
|
9
|
+
"description": "Current PPTX presentation.",
|
|
10
|
+
"x-tiwater-file-role": "read"
|
|
11
|
+
},
|
|
12
|
+
"slideNumber": {
|
|
13
|
+
"type": "integer",
|
|
14
|
+
"minimum": 1,
|
|
15
|
+
"maximum": 9007199254740991,
|
|
16
|
+
"description": "Exact one-based slide number returned by presentation observation."
|
|
17
|
+
},
|
|
18
|
+
"offset": {
|
|
19
|
+
"type": "integer",
|
|
20
|
+
"minimum": 0,
|
|
21
|
+
"maximum": 9007199254740991,
|
|
22
|
+
"description": "Zero-based shape offset in native z-order on the selected slide. Continue only when another selected shape is needed."
|
|
23
|
+
},
|
|
24
|
+
"limit": {
|
|
25
|
+
"type": "integer",
|
|
26
|
+
"minimum": 1,
|
|
27
|
+
"maximum": 8,
|
|
28
|
+
"description": "Maximum shapes in this bounded page."
|
|
29
|
+
},
|
|
30
|
+
"returnContent": {
|
|
31
|
+
"type": "boolean",
|
|
32
|
+
"description": "Return this selected technical page directly when it fits the response limit. May be combined with output."
|
|
33
|
+
},
|
|
34
|
+
"output": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"minLength": 1,
|
|
37
|
+
"description": "Optional immutable JSON artifact path for this selected technical page. May be combined with returnContent.",
|
|
38
|
+
"x-tiwater-file-role": "write"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"required": ["input", "slideNumber", "limit", "returnContent"],
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schema": "tiwater.office-provider-contract-manifest/v1",
|
|
3
3
|
"provider": {
|
|
4
4
|
"id": "@tiwater/office-mcp",
|
|
5
|
-
"version": "0.21.
|
|
5
|
+
"version": "0.21.39"
|
|
6
6
|
},
|
|
7
7
|
"tools": [
|
|
8
8
|
{
|
|
@@ -38,6 +38,17 @@
|
|
|
38
38
|
"sha256": "a6d59ee785d8ab3994eb6f539b48411b272565ac136219de58d39a449b3112f3"
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
|
+
{
|
|
42
|
+
"name": "docx_create",
|
|
43
|
+
"providerContract": {
|
|
44
|
+
"source": "packages/docx-cli/contracts/mcp-input/docx_create.schema.json",
|
|
45
|
+
"sha256": "1cf22a23fc5d8b27fff6f50db2672be623696eac79ea986053e703274eab5e3e"
|
|
46
|
+
},
|
|
47
|
+
"inputContract": {
|
|
48
|
+
"path": "office/contracts/docx_create.schema.json",
|
|
49
|
+
"sha256": "1cf22a23fc5d8b27fff6f50db2672be623696eac79ea986053e703274eab5e3e"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
41
52
|
{
|
|
42
53
|
"name": "docx_delete_object",
|
|
43
54
|
"providerContract": {
|
|
@@ -335,6 +346,28 @@
|
|
|
335
346
|
"sha256": "9cde8fdda335f379d44e60819367b305a2c97c6c0c8fdf2141bf460335e5da84"
|
|
336
347
|
}
|
|
337
348
|
},
|
|
349
|
+
{
|
|
350
|
+
"name": "pptx_read_shape",
|
|
351
|
+
"providerContract": {
|
|
352
|
+
"source": "packages/pptx-cli/contracts/mcp-input/pptx_read_shape.schema.json",
|
|
353
|
+
"sha256": "63bf1819f95514dad3d6f43a58795aa8b57bf9d1f7075edcfb11ddd3253b83e4"
|
|
354
|
+
},
|
|
355
|
+
"inputContract": {
|
|
356
|
+
"path": "office/contracts/pptx_read_shape.schema.json",
|
|
357
|
+
"sha256": "63bf1819f95514dad3d6f43a58795aa8b57bf9d1f7075edcfb11ddd3253b83e4"
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
"name": "pptx_read_slide",
|
|
362
|
+
"providerContract": {
|
|
363
|
+
"source": "packages/pptx-cli/contracts/mcp-input/pptx_read_slide.schema.json",
|
|
364
|
+
"sha256": "3a2aaca3fd11da490863e1a2d60bf2f120e4e24991b457e316de04b5c9cc889a"
|
|
365
|
+
},
|
|
366
|
+
"inputContract": {
|
|
367
|
+
"path": "office/contracts/pptx_read_slide.schema.json",
|
|
368
|
+
"sha256": "3a2aaca3fd11da490863e1a2d60bf2f120e4e24991b457e316de04b5c9cc889a"
|
|
369
|
+
}
|
|
370
|
+
},
|
|
338
371
|
{
|
|
339
372
|
"name": "pptx_replace_picture_image",
|
|
340
373
|
"providerContract": {
|
package/office/index.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
import { withOutputWriteLock } from '../_shared/output-write-lock.mjs';
|
|
26
26
|
import { evidenceRoleMetadata } from '../_shared/evidence-role.mjs';
|
|
27
27
|
import {
|
|
28
|
+
documentCreateFileArguments,
|
|
28
29
|
documentMutationFileArguments,
|
|
29
30
|
effectKindMetadata,
|
|
30
31
|
} from '../_shared/effect-kind.mjs';
|
|
@@ -178,6 +179,13 @@ function fixedEditOutput(tool) {
|
|
|
178
179
|
}).strict();
|
|
179
180
|
}
|
|
180
181
|
|
|
182
|
+
function fixedCreateOutput(tool) {
|
|
183
|
+
return z.object({
|
|
184
|
+
tool: z.literal(tool), runtime: runtimeIdentity, receipt: artifact, output: artifact,
|
|
185
|
+
summary: z.object({ pass: z.literal(true), operationCount: z.literal(1), appliedCount: z.literal(1) }).strict(),
|
|
186
|
+
}).strict();
|
|
187
|
+
}
|
|
188
|
+
|
|
181
189
|
function largeResultOutput(tool) {
|
|
182
190
|
return z.object({
|
|
183
191
|
tool: z.literal(tool),
|
|
@@ -288,6 +296,102 @@ const pptxInspectionSummary = z.object({
|
|
|
288
296
|
}).strict()).max(6),
|
|
289
297
|
}).strict();
|
|
290
298
|
|
|
299
|
+
const pptxSlidePageSummary = z.object({
|
|
300
|
+
schema: z.literal('tiwater.pptx-slide-page-receipt/v1'),
|
|
301
|
+
slideNumber: z.number().int().positive(),
|
|
302
|
+
slidePath: z.string().min(1),
|
|
303
|
+
masterPath: z.string().min(1).nullable(),
|
|
304
|
+
layoutPath: z.string().min(1).nullable(),
|
|
305
|
+
totalShapeCount: z.number().int().nonnegative(),
|
|
306
|
+
returnedShapeCount: z.number().int().nonnegative(),
|
|
307
|
+
remaining: z.number().int().nonnegative(),
|
|
308
|
+
nextOffset: z.number().int().nonnegative().nullable(),
|
|
309
|
+
}).strict();
|
|
310
|
+
|
|
311
|
+
const pptxShapeTextPageSummary = z.object({
|
|
312
|
+
schema: z.literal('tiwater.pptx-shape-text-page-receipt/v1'),
|
|
313
|
+
slideNumber: z.number().int().positive(),
|
|
314
|
+
shapeId: z.number().int().positive(),
|
|
315
|
+
totalSegmentCount: z.number().int().nonnegative(),
|
|
316
|
+
returnedSegmentCount: z.number().int().nonnegative(),
|
|
317
|
+
remaining: z.number().int().nonnegative(),
|
|
318
|
+
nextOffset: z.number().int().nonnegative().nullable(),
|
|
319
|
+
}).strict();
|
|
320
|
+
|
|
321
|
+
const pptxTransform = z.object({
|
|
322
|
+
x: z.number().int(),
|
|
323
|
+
y: z.number().int(),
|
|
324
|
+
cx: z.number().int(),
|
|
325
|
+
cy: z.number().int(),
|
|
326
|
+
}).strict();
|
|
327
|
+
|
|
328
|
+
const pptxSlideShapeIdentity = z.object({
|
|
329
|
+
shapeId: z.number().int().positive(),
|
|
330
|
+
name: z.string().max(120),
|
|
331
|
+
kind: z.string().min(1).max(40),
|
|
332
|
+
zOrder: z.number().int().nonnegative(),
|
|
333
|
+
placeholderType: z.string().max(120).nullable(),
|
|
334
|
+
placeholderPresent: z.boolean(),
|
|
335
|
+
placeholderIndex: z.number().int().nonnegative().nullable(),
|
|
336
|
+
mediaPartPath: z.string().max(240).nullable(),
|
|
337
|
+
mediaSha256: z.string().regex(/^[a-f0-9]{64}$/).nullable(),
|
|
338
|
+
textPreview: z.string().max(240),
|
|
339
|
+
textLength: z.number().int().nonnegative(),
|
|
340
|
+
transform: pptxTransform.nullable(),
|
|
341
|
+
paragraphCount: z.number().int().nonnegative(),
|
|
342
|
+
runCount: z.number().int().nonnegative(),
|
|
343
|
+
hasTable: z.boolean(),
|
|
344
|
+
}).strict();
|
|
345
|
+
|
|
346
|
+
const pptxSlidePage = z.object({
|
|
347
|
+
schema: z.literal('tiwater.pptx-slide-page/v1'),
|
|
348
|
+
file: z.string(),
|
|
349
|
+
inputSha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
350
|
+
slideCount: z.number().int().nonnegative(),
|
|
351
|
+
slideSize: z.object({ cx: z.number().int().nonnegative(), cy: z.number().int().nonnegative() }).strict(),
|
|
352
|
+
slide: z.object({
|
|
353
|
+
slideNumber: z.number().int().positive(),
|
|
354
|
+
path: z.string().min(1),
|
|
355
|
+
masterPath: z.string().min(1).nullable(),
|
|
356
|
+
layoutPath: z.string().min(1).nullable(),
|
|
357
|
+
shapes: z.array(pptxSlideShapeIdentity).max(8),
|
|
358
|
+
}).strict(),
|
|
359
|
+
receipt: pptxSlidePageSummary,
|
|
360
|
+
}).strict();
|
|
361
|
+
|
|
362
|
+
const boundedPptxString = z.string().max(120).nullable();
|
|
363
|
+
const pptxShapeTextSegment = z.object({
|
|
364
|
+
segmentIndex: z.number().int().nonnegative(),
|
|
365
|
+
runIndex: z.number().int().nonnegative(),
|
|
366
|
+
paragraphIndex: z.number().int().nonnegative(),
|
|
367
|
+
text: z.string().max(160),
|
|
368
|
+
textOffset: z.number().int().nonnegative(),
|
|
369
|
+
runTextLength: z.number().int().nonnegative(),
|
|
370
|
+
textContinues: z.boolean(),
|
|
371
|
+
paragraphAlignment: boundedPptxString,
|
|
372
|
+
fontFamily: boundedPptxString,
|
|
373
|
+
fontSize: z.number().positive().nullable(),
|
|
374
|
+
color: boundedPptxString,
|
|
375
|
+
bold: z.boolean().nullable(),
|
|
376
|
+
directFontFamily: boundedPptxString,
|
|
377
|
+
directFontSize: z.number().positive().nullable(),
|
|
378
|
+
directColor: boundedPptxString,
|
|
379
|
+
directBold: z.boolean().nullable(),
|
|
380
|
+
fontFamilySource: boundedPptxString,
|
|
381
|
+
fontSizeSource: boundedPptxString,
|
|
382
|
+
colorSource: boundedPptxString,
|
|
383
|
+
boldSource: boundedPptxString,
|
|
384
|
+
}).strict();
|
|
385
|
+
|
|
386
|
+
const pptxShapeTextPage = z.object({
|
|
387
|
+
schema: z.literal('tiwater.pptx-shape-text-page/v1'),
|
|
388
|
+
file: z.string(),
|
|
389
|
+
inputSha256: z.string().regex(/^[a-f0-9]{64}$/),
|
|
390
|
+
shape: pptxSlideShapeIdentity,
|
|
391
|
+
receipt: pptxShapeTextPageSummary,
|
|
392
|
+
segments: z.array(pptxShapeTextSegment).max(4),
|
|
393
|
+
}).strict();
|
|
394
|
+
|
|
291
395
|
function docxObservationOutput(tool) {
|
|
292
396
|
return z.object({
|
|
293
397
|
tool: z.literal(tool),
|
|
@@ -435,6 +539,14 @@ const docxReadObjectOutput = docxObservationOutput('docx_read_object').extend({
|
|
|
435
539
|
}).strict();
|
|
436
540
|
|
|
437
541
|
const tools = [
|
|
542
|
+
{
|
|
543
|
+
name: 'docx_create',
|
|
544
|
+
effectKind: 'document-create',
|
|
545
|
+
description: 'Create one new minimal standards-valid DOCX containing one empty paragraph. The result is a current native document that can be populated incrementally with the ordinary DOCX object operations. The provider chooses no business wording, template, layout mapping, or target structure and never overwrites an existing path.',
|
|
546
|
+
inputSchema: inputContract('docx_create'),
|
|
547
|
+
outputSchema: fixedCreateOutput('docx_create'),
|
|
548
|
+
handler: (args, tool) => fixedCreate(tool, args, docxCandidates),
|
|
549
|
+
},
|
|
438
550
|
{
|
|
439
551
|
name: 'docx_inspect',
|
|
440
552
|
evidenceRole: 'document-observation',
|
|
@@ -705,6 +817,28 @@ const tools = [
|
|
|
705
817
|
annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
|
|
706
818
|
handler: pptxExportJson,
|
|
707
819
|
},
|
|
820
|
+
{
|
|
821
|
+
name: 'pptx_read_slide',
|
|
822
|
+
description: 'List one selected PPTX slide as bounded pages of compact native shape identities in z-order. Each identity includes its shape id, kind, geometry, text preview, object counts, placeholder facts, media identity, and whether it contains a table. The receipt reports the selected slide, its layout and master paths, remaining shapes, and the next offset. Continue only when another shape on this slide is needed; use pptx_read_shape for bounded text and effective formatting of one selected shape. Set returnContent true to return the selected page when it fits the response limit. Provide output to store the same complete selected page as an immutable artifact. These channels are independent and may be used together; at least one is required. This tool does not select templates, assign business roles, infer repairs, or inspect another slide.',
|
|
823
|
+
inputSchema: inputContract('pptx_read_slide'),
|
|
824
|
+
outputSchema: largeResultOutput('pptx_read_slide').extend({
|
|
825
|
+
summary: pptxSlidePageSummary,
|
|
826
|
+
content: pptxSlidePage.optional(),
|
|
827
|
+
}).strict(),
|
|
828
|
+
annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
|
|
829
|
+
handler: pptxReadSlide,
|
|
830
|
+
},
|
|
831
|
+
{
|
|
832
|
+
name: 'pptx_read_shape',
|
|
833
|
+
description: 'Read one native PPTX shape selected from pptx_read_slide as bounded text segments. Each segment retains its run and paragraph identity, text offset, paragraph alignment, effective text formatting, direct formatting, and formatting source. Long run text is split without changing its native run identity. The receipt reports remaining segments and the next offset. Continue only when another segment of this shape is needed. Set returnContent true to return the selected page when it fits the response limit. Provide output to store the same complete selected page as an immutable artifact. These channels are independent and may be used together; at least one is required. This tool does not choose formatting, derive repairs, or inspect another shape.',
|
|
834
|
+
inputSchema: inputContract('pptx_read_shape'),
|
|
835
|
+
outputSchema: largeResultOutput('pptx_read_shape').extend({
|
|
836
|
+
summary: pptxShapeTextPageSummary,
|
|
837
|
+
content: pptxShapeTextPage.optional(),
|
|
838
|
+
}).strict(),
|
|
839
|
+
annotations: { readOnlyHint: true, idempotentHint: true, destructiveHint: false, openWorldHint: false },
|
|
840
|
+
handler: pptxReadShape,
|
|
841
|
+
},
|
|
708
842
|
{
|
|
709
843
|
name: 'pptx_apply_template',
|
|
710
844
|
effectKind: 'document-mutation',
|
|
@@ -1238,6 +1372,36 @@ async function fixedEdit(tool, args, candidates) {
|
|
|
1238
1372
|
});
|
|
1239
1373
|
}
|
|
1240
1374
|
|
|
1375
|
+
async function fixedCreate(tool, args, candidates) {
|
|
1376
|
+
const publishedContract = {
|
|
1377
|
+
name: tool.name,
|
|
1378
|
+
inputSchema: inputContractSchema(tool.name),
|
|
1379
|
+
annotations: tool.annotations,
|
|
1380
|
+
_meta: effectKindMetadata(tool.effectKind),
|
|
1381
|
+
};
|
|
1382
|
+
const bindings = documentCreateFileArguments(publishedContract, args);
|
|
1383
|
+
const output = path.resolve(bindings.effectiveOutput);
|
|
1384
|
+
const receiptOutput = path.resolve(requireString(args.receiptOutput, 'receiptOutput'));
|
|
1385
|
+
await requireNewFile(output, 'output');
|
|
1386
|
+
await requireNewFile(receiptOutput, 'receiptOutput');
|
|
1387
|
+
return withTempJsonFile(args, async requestPath => {
|
|
1388
|
+
const result = await runJsonCandidateChain(candidates, [tool.name, requestPath], { allowedExitCodes: [0, 1] });
|
|
1389
|
+
if (result.code !== 0) {
|
|
1390
|
+
const detail = result.stderr.trim() || result.stdout.trim()
|
|
1391
|
+
|| `${tool.name} failed with exit code ${result.code}`;
|
|
1392
|
+
throw new Error(detail);
|
|
1393
|
+
}
|
|
1394
|
+
if (result.json?.tool !== tool.name) throw new Error(`${tool.name} returned a mismatched tool identity`);
|
|
1395
|
+
await requireReturnedArtifact(result.json.receipt, receiptOutput, 'receipt');
|
|
1396
|
+
await requireReturnedArtifact(result.json.output, output, 'output');
|
|
1397
|
+
if (result.json.summary?.pass !== true
|
|
1398
|
+
|| result.json.summary?.operationCount !== 1 || result.json.summary?.appliedCount !== 1) {
|
|
1399
|
+
throw new Error(`${tool.name} returned invalid creation evidence`);
|
|
1400
|
+
}
|
|
1401
|
+
return { ...result.json, runtime: commandRuntime(result) };
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1241
1405
|
async function docxCompare(args) {
|
|
1242
1406
|
const baseline = path.resolve(requireString(args.baseline, 'baseline'));
|
|
1243
1407
|
const updated = path.resolve(requireString(args.updated, 'updated'));
|
|
@@ -1396,6 +1560,36 @@ async function pptxExportJson(args) {
|
|
|
1396
1560
|
return deliverLargeJsonResult({ tool: 'pptx_export_json', args, runtime: commandRuntime(result), payload: result.json, sourcePaths: [input] });
|
|
1397
1561
|
}
|
|
1398
1562
|
|
|
1563
|
+
async function pptxReadSlide(args) {
|
|
1564
|
+
const input = path.resolve(requireString(args.input, 'input'));
|
|
1565
|
+
return withTempJsonFile(args, async requestPath => {
|
|
1566
|
+
const result = await runJsonCandidateChain(pptxCandidates, ['pptx_read_slide', requestPath]);
|
|
1567
|
+
return deliverLargeJsonResult({
|
|
1568
|
+
tool: 'pptx_read_slide',
|
|
1569
|
+
args,
|
|
1570
|
+
runtime: commandRuntime(result),
|
|
1571
|
+
payload: result.json,
|
|
1572
|
+
sourcePaths: [input],
|
|
1573
|
+
summary: result.json.receipt,
|
|
1574
|
+
});
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
async function pptxReadShape(args) {
|
|
1579
|
+
const input = path.resolve(requireString(args.input, 'input'));
|
|
1580
|
+
return withTempJsonFile(args, async requestPath => {
|
|
1581
|
+
const result = await runJsonCandidateChain(pptxCandidates, ['pptx_read_shape', requestPath]);
|
|
1582
|
+
return deliverLargeJsonResult({
|
|
1583
|
+
tool: 'pptx_read_shape',
|
|
1584
|
+
args,
|
|
1585
|
+
runtime: commandRuntime(result),
|
|
1586
|
+
payload: result.json,
|
|
1587
|
+
sourcePaths: [input],
|
|
1588
|
+
summary: result.json.receipt,
|
|
1589
|
+
});
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1399
1593
|
async function pptxValidate(args) {
|
|
1400
1594
|
const input = path.resolve(requireString(args.input, 'input'));
|
|
1401
1595
|
const result = await runJsonCandidateChain(pptxCandidates, ['validate', input], { allowedExitCodes: [0, 1] });
|
package/package.json
CHANGED