@tiwater/office-mcp 0.16.13 → 0.16.15

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.
@@ -41,14 +41,10 @@
41
41
  "sourceTableRef": { "type": "string", "pattern": "^dox1_[0-9a-f]{64}$" },
42
42
  "sourceRows": {
43
43
  "type": "object",
44
- "description": "Contiguous source business-row range. Do not begin on an unlabeled continuation row from an excluded business group. If another column's visible merge began before the range, the provider carries its origin value into a new merge start.",
44
+ "description": "Exact contiguous source rows to copy. Select only wanted rows; the range cannot begin or end inside a vertical merge.",
45
45
  "properties": {
46
46
  "firstRef": { "type": "string", "pattern": "^dox1_[0-9a-f]{64}$" },
47
- "lastRef": { "type": "string", "pattern": "^dox1_[0-9a-f]{64}$" },
48
- "excludeRefs": {
49
- "type": "array",
50
- "items": { "type": "string", "pattern": "^dox1_[0-9a-f]{64}$" }
51
- }
47
+ "lastRef": { "type": "string", "pattern": "^dox1_[0-9a-f]{64}$" }
52
48
  },
53
49
  "required": ["firstRef", "lastRef"],
54
50
  "additionalProperties": false
@@ -18,7 +18,7 @@
18
18
  "pattern": "^docx-rev-v1-[0-9a-f]{64}$"
19
19
  },
20
20
  "kinds": {
21
- "description": "Object kinds required by the next operation. The response returns only matching descendant identities; the artifact retains the complete object.",
21
+ "description": "Object kinds required by the next operation. Both the response and artifact contain only matching descendant identities.",
22
22
  "type": "array",
23
23
  "items": {
24
24
  "type": "string",
@@ -38,7 +38,7 @@
38
38
  "output": {
39
39
  "type": "string",
40
40
  "minLength": 1,
41
- "description": "Absolute path for a new JSON artifact containing the complete native object observation.",
41
+ "description": "Absolute path for a new JSON artifact containing the selected native object and only the requested descendant kinds.",
42
42
  "x-tiwater-file-role": "write"
43
43
  }
44
44
  },
@@ -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.16.13"
5
+ "version": "0.16.15"
6
6
  },
7
7
  "tools": [
8
8
  {
@@ -42,11 +42,11 @@
42
42
  "name": "docx_copy_table_rows",
43
43
  "providerContract": {
44
44
  "source": "packages/docx-cli/contracts/mcp-input/docx_copy_table_rows.schema.json",
45
- "sha256": "f24924a80de9d9cfe619c9b4f6475d370c75fe221dcbe3af9692ad15c648d3b0"
45
+ "sha256": "17fafe8f67129220479cf39ae058c669e2b55958122c4286ce7128d7f7a0cb7d"
46
46
  },
47
47
  "inputContract": {
48
48
  "path": "office/contracts/docx_copy_table_rows.schema.json",
49
- "sha256": "f24924a80de9d9cfe619c9b4f6475d370c75fe221dcbe3af9692ad15c648d3b0"
49
+ "sha256": "17fafe8f67129220479cf39ae058c669e2b55958122c4286ce7128d7f7a0cb7d"
50
50
  }
51
51
  },
52
52
  {
@@ -119,11 +119,11 @@
119
119
  "name": "docx_read_object",
120
120
  "providerContract": {
121
121
  "source": "packages/docx-cli/contracts/mcp-input/docx_read_object.schema.json",
122
- "sha256": "d75d81f6ec62ed40e6116beacc1860b692e0307dc0da09f05599511816aa38ab"
122
+ "sha256": "9b78138005fc6f875cf9ed530b8389ec4b2a751294c9d316e8b9fc2463560a3f"
123
123
  },
124
124
  "inputContract": {
125
125
  "path": "office/contracts/docx_read_object.schema.json",
126
- "sha256": "d75d81f6ec62ed40e6116beacc1860b692e0307dc0da09f05599511816aa38ab"
126
+ "sha256": "9b78138005fc6f875cf9ed530b8389ec4b2a751294c9d316e8b9fc2463560a3f"
127
127
  }
128
128
  },
129
129
  {
package/office/index.mjs CHANGED
@@ -145,10 +145,9 @@ const docxRevision = z.object({
145
145
 
146
146
  const docxTableIndexEntry = z.object({
147
147
  ref: z.string().regex(/^dox1_[0-9a-f]{64}$/),
148
- tableIndex: z.number().int().nonnegative(),
149
- containmentPath: z.array(z.string()),
150
- parentCellAddress: z.string().nullable(),
151
- storyKind: z.string(),
148
+ parentRef: z.string().regex(/^dox1_[0-9a-f]{64}$/).nullable(),
149
+ storyPart: z.string(),
150
+ nativePath: z.string(),
152
151
  rowCount: z.number().int().nonnegative(),
153
152
  columnCount: z.number().int().nonnegative(),
154
153
  textPreview: z.string(),
@@ -167,12 +166,19 @@ const docxObjectIdentity = z.object({
167
166
  parentRef: z.string().regex(/^dox1_[0-9a-f]{64}$/).nullable(),
168
167
  kind: z.string(),
169
168
  textPreview: z.string().nullable(),
169
+ gridSpan: z.number().int().positive().nullable(),
170
+ verticalMerge: z.string().nullable(),
170
171
  }).strict();
171
172
 
173
+ const docxObjectNode = z.lazy(() => z.object({
174
+ object: docxObjectIdentity,
175
+ children: z.array(docxObjectNode),
176
+ }).strict());
177
+
172
178
  const docxReadObjectOutput = artifactOutput('docx_read_object').extend({
173
179
  revision: docxRevision,
174
180
  object: docxObjectIdentity,
175
- descendants: z.array(docxObjectIdentity),
181
+ children: z.array(docxObjectNode),
176
182
  }).strict();
177
183
 
178
184
  const tools = [
@@ -181,6 +187,7 @@ const tools = [
181
187
  description: 'Inspect one current DOCX. The response returns its revision and a bounded table identity index for the next selection; the complete observation remains in the evidence artifact.',
182
188
  inputSchema: inputContract('docx_inspect'),
183
189
  outputSchema: docxInspectionOutput('docx_inspect'),
190
+ annotations: { readOnlyHint: true, idempotentHint: true },
184
191
  handler: docxInspect,
185
192
  },
186
193
  {
@@ -199,7 +206,7 @@ const tools = [
199
206
  },
200
207
  {
201
208
  name: 'docx_read_object',
202
- description: 'Read one selected native DOCX object. Declare only the descendant kinds required by the next operation; the response returns those identities and the evidence artifact retains the complete object.',
209
+ description: 'Read one selected native DOCX object as an ordered native hierarchy. For a table, request row and cell kinds once; each row contains its ordered cells with text, grid span, and vertical merge state.',
203
210
  inputSchema: inputContract('docx_read_object'),
204
211
  outputSchema: docxReadObjectOutput,
205
212
  annotations: { readOnlyHint: true, idempotentHint: true },
@@ -406,29 +413,10 @@ function buildServer() {
406
413
  }
407
414
 
408
415
  function compactDocxTableIndex(report) {
409
- if (!report?.Revision || !Array.isArray(report.Tables)
410
- || (report.StoryTables !== null && !Array.isArray(report.StoryTables))) {
416
+ if (!report?.revision || !Array.isArray(report.tables)) {
411
417
  throw new Error('docx-table-inspection-result-invalid');
412
418
  }
413
- const tables = [...report.Tables, ...(report.StoryTables ?? [])].map(table => {
414
- const text = table.Rows.flatMap(row => row.Cells.map(cell => cell.Text))
415
- .filter(value => typeof value === 'string' && value.length > 0)
416
- .join(' ')
417
- .replace(/\s+/gu, ' ')
418
- .trim();
419
- return {
420
- ref: table.Ref,
421
- tableIndex: table.TableIndex,
422
- containmentPath: table.ContainmentPath,
423
- parentCellAddress: table.ParentCellAddress ?? null,
424
- storyKind: table.Story.Kind,
425
- rowCount: table.RowCount,
426
- columnCount: table.ColumnCount,
427
- textPreview: text.length <= 160 ? text : `${text.slice(0, 160)}...`,
428
- textLength: text.length,
429
- };
430
- });
431
- return { revision: report.Revision, tables };
419
+ return { revision: report.revision, tables: report.tables };
432
420
  }
433
421
 
434
422
  function compactDocxObjectIdentity(object) {
@@ -437,6 +425,8 @@ function compactDocxObjectIdentity(object) {
437
425
  parentRef: object.parentRef,
438
426
  kind: object.kind,
439
427
  textPreview: object.textPreview,
428
+ gridSpan: object.gridSpan,
429
+ verticalMerge: object.verticalMerge,
440
430
  };
441
431
  }
442
432
 
@@ -462,7 +452,6 @@ async function docxObservation(tool, args) {
462
452
  async function docxReadObject(args) {
463
453
  const input = path.resolve(requireString(args.input, 'input'));
464
454
  const output = requireString(args.output, 'output');
465
- const kinds = new Set(args.kinds);
466
455
  const { output: _output, ...request } = args;
467
456
  return withTempJsonFile(request, async requestPath => {
468
457
  const result = await runJsonCandidateChain(docxCandidates, ['docx_read_object', requestPath]);
@@ -473,13 +462,18 @@ async function docxReadObject(args) {
473
462
  artifact: await writeJsonArtifact(output, result.json),
474
463
  revision: result.json.receipt.revision,
475
464
  object: compactDocxObjectIdentity(result.json.observation.object),
476
- descendants: result.json.observation.descendants
477
- .filter(identity => kinds.has(identity.kind))
478
- .map(compactDocxObjectIdentity),
465
+ children: result.json.observation.children.map(compactDocxObjectNode),
479
466
  };
480
467
  });
481
468
  }
482
469
 
470
+ function compactDocxObjectNode(node) {
471
+ return {
472
+ object: compactDocxObjectIdentity(node.object),
473
+ children: node.children.map(compactDocxObjectNode),
474
+ };
475
+ }
476
+
483
477
  async function docxValidate(args) {
484
478
  const result = await runJsonCandidateChain(docxCandidates, ['validate-openxml', requireString(args.input, 'input')], { allowedExitCodes: [0, 1] });
485
479
  return { tool: 'docx_validate', runtime: commandRuntime(result), result: result.json };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiwater/office-mcp",
3
- "version": "0.16.13",
3
+ "version": "0.16.15",
4
4
  "description": "Published MCP server for Tiwater Office document capabilities",
5
5
  "type": "module",
6
6
  "license": "MIT",