@documonster/mcp 0.8.0-canary.sha.09791dab
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/LICENSE +205 -0
- package/README.md +253 -0
- package/dist/capabilities.d.ts +29 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +188 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/cli.d.ts +13 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +189 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +66 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +96 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/sandbox.d.ts +86 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +224 -0
- package/dist/sandbox.js.map +1 -0
- package/dist/server.d.ts +22 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +66 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/archive-read.d.ts +31 -0
- package/dist/tools/archive-read.d.ts.map +1 -0
- package/dist/tools/archive-read.js +315 -0
- package/dist/tools/archive-read.js.map +1 -0
- package/dist/tools/archive-write.d.ts +9 -0
- package/dist/tools/archive-write.d.ts.map +1 -0
- package/dist/tools/archive-write.js +219 -0
- package/dist/tools/archive-write.js.map +1 -0
- package/dist/tools/chart.d.ts +93 -0
- package/dist/tools/chart.d.ts.map +1 -0
- package/dist/tools/chart.js +263 -0
- package/dist/tools/chart.js.map +1 -0
- package/dist/tools/doc-convert.d.ts +13 -0
- package/dist/tools/doc-convert.d.ts.map +1 -0
- package/dist/tools/doc-convert.js +209 -0
- package/dist/tools/doc-convert.js.map +1 -0
- package/dist/tools/doc-paginate.d.ts +14 -0
- package/dist/tools/doc-paginate.d.ts.map +1 -0
- package/dist/tools/doc-paginate.js +153 -0
- package/dist/tools/doc-paginate.js.map +1 -0
- package/dist/tools/doc-read.d.ts +14 -0
- package/dist/tools/doc-read.d.ts.map +1 -0
- package/dist/tools/doc-read.js +175 -0
- package/dist/tools/doc-read.js.map +1 -0
- package/dist/tools/doc-review.d.ts +17 -0
- package/dist/tools/doc-review.d.ts.map +1 -0
- package/dist/tools/doc-review.js +249 -0
- package/dist/tools/doc-review.js.map +1 -0
- package/dist/tools/doc-search.d.ts +20 -0
- package/dist/tools/doc-search.d.ts.map +1 -0
- package/dist/tools/doc-search.js +268 -0
- package/dist/tools/doc-search.js.map +1 -0
- package/dist/tools/doc-write.d.ts +11 -0
- package/dist/tools/doc-write.d.ts.map +1 -0
- package/dist/tools/doc-write.js +81 -0
- package/dist/tools/doc-write.js.map +1 -0
- package/dist/tools/document.d.ts +74 -0
- package/dist/tools/document.d.ts.map +1 -0
- package/dist/tools/document.js +157 -0
- package/dist/tools/document.js.map +1 -0
- package/dist/tools/form-fill.d.ts +20 -0
- package/dist/tools/form-fill.d.ts.map +1 -0
- package/dist/tools/form-fill.js +270 -0
- package/dist/tools/form-fill.js.map +1 -0
- package/dist/tools/formula-evaluate.d.ts +14 -0
- package/dist/tools/formula-evaluate.d.ts.map +1 -0
- package/dist/tools/formula-evaluate.js +192 -0
- package/dist/tools/formula-evaluate.js.map +1 -0
- package/dist/tools/fs-helpers.d.ts +106 -0
- package/dist/tools/fs-helpers.d.ts.map +1 -0
- package/dist/tools/fs-helpers.js +257 -0
- package/dist/tools/fs-helpers.js.map +1 -0
- package/dist/tools/help.d.ts +227 -0
- package/dist/tools/help.d.ts.map +1 -0
- package/dist/tools/help.js +262 -0
- package/dist/tools/help.js.map +1 -0
- package/dist/tools/index.d.ts +33 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +78 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/inspect.d.ts +14 -0
- package/dist/tools/inspect.d.ts.map +1 -0
- package/dist/tools/inspect.js +463 -0
- package/dist/tools/inspect.js.map +1 -0
- package/dist/tools/pdf-edit.d.ts +26 -0
- package/dist/tools/pdf-edit.d.ts.map +1 -0
- package/dist/tools/pdf-edit.js +390 -0
- package/dist/tools/pdf-edit.js.map +1 -0
- package/dist/tools/result.d.ts +25 -0
- package/dist/tools/result.d.ts.map +1 -0
- package/dist/tools/result.js +43 -0
- package/dist/tools/result.js.map +1 -0
- package/dist/tools/sheet-edit.d.ts +16 -0
- package/dist/tools/sheet-edit.d.ts.map +1 -0
- package/dist/tools/sheet-edit.js +325 -0
- package/dist/tools/sheet-edit.js.map +1 -0
- package/dist/tools/sheet-read.d.ts +10 -0
- package/dist/tools/sheet-read.d.ts.map +1 -0
- package/dist/tools/sheet-read.js +139 -0
- package/dist/tools/sheet-read.js.map +1 -0
- package/dist/tools/sheet-write.d.ts +15 -0
- package/dist/tools/sheet-write.d.ts.map +1 -0
- package/dist/tools/sheet-write.js +290 -0
- package/dist/tools/sheet-write.js.map +1 -0
- package/dist/tools/spreadsheet.d.ts +100 -0
- package/dist/tools/spreadsheet.d.ts.map +1 -0
- package/dist/tools/spreadsheet.js +210 -0
- package/dist/tools/spreadsheet.js.map +1 -0
- package/dist/tools/template.d.ts +18 -0
- package/dist/tools/template.d.ts.map +1 -0
- package/dist/tools/template.js +209 -0
- package/dist/tools/template.js.map +1 -0
- package/dist/tools/types.d.ts +79 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +18 -0
- package/dist/tools/types.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sheet_edit` — patch an existing workbook in place.
|
|
3
|
+
*
|
|
4
|
+
* The counterpart to `sheet_write`: that one builds a file, this one changes a
|
|
5
|
+
* file someone already has. The distinction matters because the risky operation
|
|
6
|
+
* is the second — a user's real spreadsheet, whose other sheets, formatting and
|
|
7
|
+
* formulas must survive untouched.
|
|
8
|
+
*
|
|
9
|
+
* Two safeguards follow from that. Operations are applied to an in-memory copy
|
|
10
|
+
* and only written once every one of them has succeeded, so a bad op cannot
|
|
11
|
+
* leave a half-edited file. And `dryRun` reports what *would* change without
|
|
12
|
+
* writing, because a model's decision to edit is far likelier to be wrong than
|
|
13
|
+
* its ability to execute the edit.
|
|
14
|
+
*/
|
|
15
|
+
import { stat } from "node:fs/promises";
|
|
16
|
+
import { Cell, Workbook, Worksheet } from "documonster/excel";
|
|
17
|
+
import { calculateFormulas } from "documonster/excel/formula";
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { toolError } from "../errors.js";
|
|
20
|
+
import { assertWritable, resolveEditTarget, resolveInRoot } from "../sandbox.js";
|
|
21
|
+
import { addChart, chartSchema } from "./chart.js";
|
|
22
|
+
import { assertUnchanged, backupOnce, describeBackup, fingerprint, replaceAtomically } from "./fs-helpers.js";
|
|
23
|
+
import { textResult } from "./result.js";
|
|
24
|
+
import { describeWindow, normalizeFormula, parseRange, requireSheet, sheetName, toArgb } from "./spreadsheet.js";
|
|
25
|
+
import { defineTool } from "./types.js";
|
|
26
|
+
/** Cells one op may touch, so an unbounded range cannot hang the server. */
|
|
27
|
+
const MAX_OP_CELLS = 100_000;
|
|
28
|
+
const cellValue = z.union([z.string(), z.number(), z.boolean(), z.null()]);
|
|
29
|
+
/**
|
|
30
|
+
* One edit.
|
|
31
|
+
*
|
|
32
|
+
* A discriminated union keeps the schema small while still describing every
|
|
33
|
+
* operation precisely — the model sees one `op` field and only the parameters
|
|
34
|
+
* that operation needs.
|
|
35
|
+
*/
|
|
36
|
+
const opSchema = z.discriminatedUnion("op", [
|
|
37
|
+
z.object({
|
|
38
|
+
op: z.literal("set_cell"),
|
|
39
|
+
ref: z.string().describe('Cell address, e.g. "B7".'),
|
|
40
|
+
value: cellValue
|
|
41
|
+
}),
|
|
42
|
+
z.object({
|
|
43
|
+
op: z.literal("set_range"),
|
|
44
|
+
range: z.string().describe('Target range, e.g. "A2:C4".'),
|
|
45
|
+
rows: z
|
|
46
|
+
.array(z.array(cellValue))
|
|
47
|
+
.describe("Row-major values, written from the range's top-left.")
|
|
48
|
+
}),
|
|
49
|
+
z.object({
|
|
50
|
+
op: z.literal("set_formula"),
|
|
51
|
+
range: z.string().describe('Cell or range, e.g. "D2:D99".'),
|
|
52
|
+
formula: z
|
|
53
|
+
.string()
|
|
54
|
+
.describe('Formula, with or without a leading "=". Applied to every cell in the range.')
|
|
55
|
+
}),
|
|
56
|
+
z.object({
|
|
57
|
+
op: z.literal("clear"),
|
|
58
|
+
range: z.string().describe("Range whose values are removed.")
|
|
59
|
+
}),
|
|
60
|
+
z.object({
|
|
61
|
+
op: z.literal("insert_rows"),
|
|
62
|
+
at: z.number().int().positive().describe("1-based row to insert before."),
|
|
63
|
+
rows: z.array(z.array(cellValue)).min(1).describe("Rows to insert.")
|
|
64
|
+
}),
|
|
65
|
+
z.object({
|
|
66
|
+
op: z.literal("delete_rows"),
|
|
67
|
+
at: z.number().int().positive().describe("1-based first row to delete."),
|
|
68
|
+
count: z.number().int().positive().describe("How many rows to delete.")
|
|
69
|
+
}),
|
|
70
|
+
z.object({
|
|
71
|
+
op: z.literal("set_style"),
|
|
72
|
+
range: z.string(),
|
|
73
|
+
bold: z.boolean().optional(),
|
|
74
|
+
italic: z.boolean().optional(),
|
|
75
|
+
fontColor: z.string().optional().describe('Hex RGB, e.g. "C00000".'),
|
|
76
|
+
fillColor: z.string().optional().describe('Hex RGB, e.g. "FFEB3B".'),
|
|
77
|
+
numFmt: z.string().optional().describe('Number format, e.g. "#,##0.00".')
|
|
78
|
+
}),
|
|
79
|
+
z.object({
|
|
80
|
+
op: z.literal("add_sheet"),
|
|
81
|
+
name: z.string().min(1).max(31),
|
|
82
|
+
rows: z.array(z.array(cellValue)).optional()
|
|
83
|
+
}),
|
|
84
|
+
z.object({
|
|
85
|
+
op: z.literal("add_chart"),
|
|
86
|
+
chart: chartSchema
|
|
87
|
+
})
|
|
88
|
+
// Renaming is deliberately absent: the public worksheet model setter does
|
|
89
|
+
// not rewrite cross-sheet formulas/charts and can fail on merged sheets. A
|
|
90
|
+
// half-working rename silently corrupts more than it helps.
|
|
91
|
+
]);
|
|
92
|
+
export const sheetEditTool = defineTool({
|
|
93
|
+
name: "sheet_edit",
|
|
94
|
+
group: "excel",
|
|
95
|
+
title: "Edit an existing spreadsheet",
|
|
96
|
+
description: "Apply a list of edits to an existing .xlsx: set cells, ranges or formulas, clear, insert or delete rows, restyle, add a chart or add a sheet. All edits succeed or none are written. Use dryRun first to see what would change. Read the sheet with sheet_read before editing so cell references are right. Renaming is intentionally not exposed because formulas and chart references cannot be rewritten safely.",
|
|
97
|
+
inputSchema: {
|
|
98
|
+
path: z.string().min(1).describe("Workbook to edit, relative to the server root."),
|
|
99
|
+
out: z
|
|
100
|
+
.string()
|
|
101
|
+
.optional()
|
|
102
|
+
.describe("Write the edited workbook here under @output/. Required for input files unless --allow-in-place is enabled; omit when editing an @output file."),
|
|
103
|
+
sheet: z
|
|
104
|
+
.union([z.string(), z.number().int().positive()])
|
|
105
|
+
.optional()
|
|
106
|
+
.describe("Sheet the edits apply to, by name or 1-based index. Defaults to the first."),
|
|
107
|
+
ops: z.array(opSchema).min(1).describe("Edits, applied in order."),
|
|
108
|
+
dryRun: z
|
|
109
|
+
.boolean()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("Report what would change without writing. Do this first when editing a file the user cares about — a wrong edit produces a plausible-looking but incorrect document, which is worse than an error."),
|
|
112
|
+
backup: z
|
|
113
|
+
.boolean()
|
|
114
|
+
.optional()
|
|
115
|
+
.describe("Copy the original to <name>.bak before writing. Defaults to true."),
|
|
116
|
+
recalculate: z
|
|
117
|
+
.boolean()
|
|
118
|
+
.optional()
|
|
119
|
+
.describe("Re-evaluate formulas after editing so values stay consistent. Defaults to true.")
|
|
120
|
+
},
|
|
121
|
+
annotations: {
|
|
122
|
+
readOnlyHint: false,
|
|
123
|
+
destructiveHint: true,
|
|
124
|
+
idempotentHint: false,
|
|
125
|
+
openWorldHint: false
|
|
126
|
+
},
|
|
127
|
+
mutates: true,
|
|
128
|
+
handler: async (args, context) => {
|
|
129
|
+
const { config } = context;
|
|
130
|
+
assertWritable(config);
|
|
131
|
+
const resolved = await resolveInRoot(config, args.path, { mustExist: true });
|
|
132
|
+
const inputVersion = await fingerprint(resolved);
|
|
133
|
+
const stats = await stat(resolved);
|
|
134
|
+
if (stats.size > config.maxFileSize) {
|
|
135
|
+
throw toolError.tooLarge(`${args.path} is ${stats.size} bytes, over the ${config.maxFileSize} byte limit`, "Ask the user to raise --max-file-size.");
|
|
136
|
+
}
|
|
137
|
+
const wb = Workbook.create();
|
|
138
|
+
try {
|
|
139
|
+
await Workbook.readFile(wb, resolved);
|
|
140
|
+
}
|
|
141
|
+
catch (cause) {
|
|
142
|
+
throw toolError.unsupported(`could not read ${args.path} as a workbook`, "Run doc_inspect to confirm the file really is an .xlsx package.", { cause });
|
|
143
|
+
}
|
|
144
|
+
const ws = requireSheet(wb, args.sheet);
|
|
145
|
+
const target = sheetName(ws);
|
|
146
|
+
const applied = [];
|
|
147
|
+
// Every op runs against the in-memory workbook first. Nothing is written
|
|
148
|
+
// until all of them have succeeded, so a failure leaves the file untouched.
|
|
149
|
+
for (const [index, op] of args.ops.entries()) {
|
|
150
|
+
try {
|
|
151
|
+
applied.push(applyOp(wb, ws, op));
|
|
152
|
+
}
|
|
153
|
+
catch (cause) {
|
|
154
|
+
throw cause instanceof Error && cause.name === "McpToolError"
|
|
155
|
+
? cause
|
|
156
|
+
: toolError.invalidInput(`op ${index + 1} (${op.op}) failed: ${cause instanceof Error ? cause.message : String(cause)}`, "No changes were written. Fix this operation and retry.", { cause });
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const recalculate = args.recalculate ?? true;
|
|
160
|
+
let formulaNote = "formulas not re-evaluated (recalculate: false)";
|
|
161
|
+
if (recalculate) {
|
|
162
|
+
try {
|
|
163
|
+
calculateFormulas(wb);
|
|
164
|
+
formulaNote = "formulas re-evaluated";
|
|
165
|
+
}
|
|
166
|
+
catch (cause) {
|
|
167
|
+
formulaNote = `formula re-evaluation failed: ${cause instanceof Error ? cause.message : String(cause)}`;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (args.dryRun === true) {
|
|
171
|
+
return textResult(config, [
|
|
172
|
+
`**Dry run** — nothing was written to ${args.path}.`,
|
|
173
|
+
`- sheet: ${JSON.stringify(target)}`,
|
|
174
|
+
`- ${formulaNote}`,
|
|
175
|
+
"",
|
|
176
|
+
"Would apply:",
|
|
177
|
+
...applied.map((line, index) => `${index + 1}. ${line}`),
|
|
178
|
+
"",
|
|
179
|
+
"Re-run without dryRun to write these changes."
|
|
180
|
+
].join("\n"));
|
|
181
|
+
}
|
|
182
|
+
// Cheap insurance against a well-formed but wrong edit, which is the
|
|
183
|
+
// likeliest failure and the one no error message can catch.
|
|
184
|
+
await assertUnchanged(resolved, inputVersion);
|
|
185
|
+
const writeTarget = await resolveEditTarget(config, args.path, args.out);
|
|
186
|
+
const backupPath = (args.backup ?? true) ? await backupOnce(writeTarget) : undefined;
|
|
187
|
+
// Written to a sibling and renamed: the in-memory application above is only
|
|
188
|
+
// half of "atomic" — writing straight to the path would truncate the user's
|
|
189
|
+
// file before the new bytes are complete.
|
|
190
|
+
await replaceAtomically(writeTarget.path, temporary => Workbook.writeFile(wb, temporary));
|
|
191
|
+
return textResult(config, [
|
|
192
|
+
`Edited **${args.path}**, sheet ${JSON.stringify(target)} — ${applied.length} operation(s) applied.`,
|
|
193
|
+
`- ${formulaNote}`,
|
|
194
|
+
...(backupPath === undefined
|
|
195
|
+
? ["- no backup was taken (backup: false)"]
|
|
196
|
+
: describeBackup(writeTarget.display, backupPath)),
|
|
197
|
+
"",
|
|
198
|
+
...applied.map((line, index) => `${index + 1}. ${line}`),
|
|
199
|
+
"",
|
|
200
|
+
"Read it back with sheet_read to verify before reporting success to the user."
|
|
201
|
+
].join("\n"));
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
/** Apply one op, returning a human description of what it did. */
|
|
205
|
+
function applyOp(wb, ws, op) {
|
|
206
|
+
switch (op.op) {
|
|
207
|
+
case "set_cell": {
|
|
208
|
+
const ref = requireAddress(op.ref);
|
|
209
|
+
Cell.setValue(ws, ref, op.value);
|
|
210
|
+
return `set ${ref} = ${JSON.stringify(op.value)}`;
|
|
211
|
+
}
|
|
212
|
+
case "set_range": {
|
|
213
|
+
const window = boundedRange(op.range);
|
|
214
|
+
let written = 0;
|
|
215
|
+
for (const [rowOffset, row] of op.rows.entries()) {
|
|
216
|
+
for (const [colOffset, value] of row.entries()) {
|
|
217
|
+
const targetRow = window.top + rowOffset;
|
|
218
|
+
const targetCol = window.left + colOffset;
|
|
219
|
+
if (targetRow > window.bottom || targetCol > window.right) {
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
Cell.setValue(ws, targetRow, targetCol, value);
|
|
223
|
+
written += 1;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return `set ${written} cell(s) in ${op.range}`;
|
|
227
|
+
}
|
|
228
|
+
case "set_formula": {
|
|
229
|
+
const window = boundedRange(op.range);
|
|
230
|
+
const formula = normalizeFormula(op.formula);
|
|
231
|
+
const cells = (window.bottom - window.top + 1) * (window.right - window.left + 1);
|
|
232
|
+
// `fillFormula` writes a real OOXML shared formula and translates relative
|
|
233
|
+
// references per cell, which is what a caller asking for "=B2*C2 down
|
|
234
|
+
// D2:D4" means. Writing the same literal text into every cell — the
|
|
235
|
+
// obvious implementation — makes all three rows compute row 2, and looks
|
|
236
|
+
// entirely plausible in the result.
|
|
237
|
+
Worksheet.fillFormula(ws, describeWindow(window), formula);
|
|
238
|
+
return cells === 1
|
|
239
|
+
? `set formula \`=${formula}\` on ${describeWindow(window)}`
|
|
240
|
+
: `filled formula \`=${formula}\` across ${cells} cell(s) in ${describeWindow(window)}, translating relative references per cell`;
|
|
241
|
+
}
|
|
242
|
+
case "clear": {
|
|
243
|
+
const window = boundedRange(op.range);
|
|
244
|
+
let count = 0;
|
|
245
|
+
for (let row = window.top; row <= window.bottom; row += 1) {
|
|
246
|
+
for (let column = window.left; column <= window.right; column += 1) {
|
|
247
|
+
Cell.setValue(ws, row, column, null);
|
|
248
|
+
count += 1;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return `cleared ${count} cell(s) in ${op.range}`;
|
|
252
|
+
}
|
|
253
|
+
// Structural moves shift cells but do not rewrite references that point at
|
|
254
|
+
// them: a formula or chart elsewhere in the workbook keeps its old
|
|
255
|
+
// coordinates. That is a limitation of the underlying operation, not
|
|
256
|
+
// something this tool can paper over, so it is reported rather than hidden.
|
|
257
|
+
case "insert_rows":
|
|
258
|
+
Worksheet.insertRows(ws, op.at, op.rows);
|
|
259
|
+
return `inserted ${op.rows.length} row(s) before row ${op.at} — references to shifted cells elsewhere in the workbook are NOT adjusted; verify any formulas or charts that pointed below row ${op.at}`;
|
|
260
|
+
case "delete_rows":
|
|
261
|
+
Worksheet.spliceRows(ws, op.at, op.count);
|
|
262
|
+
return `deleted ${op.count} row(s) from row ${op.at} — references to those cells elsewhere in the workbook are NOT adjusted and may now be wrong; verify any formulas or charts that pointed at them`;
|
|
263
|
+
case "set_style": {
|
|
264
|
+
const window = boundedRange(op.range);
|
|
265
|
+
for (let row = window.top; row <= window.bottom; row += 1) {
|
|
266
|
+
for (let column = window.left; column <= window.right; column += 1) {
|
|
267
|
+
if (op.bold !== undefined || op.italic !== undefined || op.fontColor !== undefined) {
|
|
268
|
+
Cell.setFont(ws, row, column, {
|
|
269
|
+
...(Cell.getFont(ws, row, column) ?? {}),
|
|
270
|
+
...(op.bold === undefined ? {} : { bold: op.bold }),
|
|
271
|
+
...(op.italic === undefined ? {} : { italic: op.italic }),
|
|
272
|
+
...(op.fontColor === undefined ? {} : { color: { argb: toArgb(op.fontColor) } })
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
if (op.fillColor !== undefined) {
|
|
276
|
+
Cell.setFill(ws, row, column, {
|
|
277
|
+
type: "pattern",
|
|
278
|
+
pattern: "solid",
|
|
279
|
+
fgColor: { argb: toArgb(op.fillColor) }
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (op.numFmt !== undefined) {
|
|
283
|
+
Cell.setNumFmt(ws, row, column, op.numFmt);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return `restyled ${op.range}`;
|
|
288
|
+
}
|
|
289
|
+
case "add_sheet": {
|
|
290
|
+
if (Workbook.getWorksheet(wb, op.name) !== undefined) {
|
|
291
|
+
throw toolError.invalidInput(`a sheet named ${JSON.stringify(op.name)} already exists`, "Pick a different name. Renaming an existing sheet is not exposed because references elsewhere cannot be rewritten safely.");
|
|
292
|
+
}
|
|
293
|
+
const added = Workbook.addWorksheet(wb, op.name);
|
|
294
|
+
if (op.rows !== undefined && op.rows.length > 0) {
|
|
295
|
+
for (const [rowOffset, row] of op.rows.entries()) {
|
|
296
|
+
for (const [columnOffset, value] of row.entries()) {
|
|
297
|
+
Cell.setValue(added, rowOffset + 1, columnOffset + 1, value);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return `added sheet ${JSON.stringify(op.name)}${op.rows === undefined ? "" : ` with ${op.rows.length} row(s)`}`;
|
|
302
|
+
}
|
|
303
|
+
case "add_chart":
|
|
304
|
+
return addChart(ws, op.chart);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/** Parse a range and refuse one large enough to hang the server. */
|
|
308
|
+
function boundedRange(range) {
|
|
309
|
+
const window = parseRange(range);
|
|
310
|
+
const cells = (window.bottom - window.top + 1) * (window.right - window.left + 1);
|
|
311
|
+
if (cells > MAX_OP_CELLS) {
|
|
312
|
+
throw toolError.tooLarge(`range ${JSON.stringify(range)} covers ${cells} cells, over the ${MAX_OP_CELLS} limit`, "Target only the rows that hold data.");
|
|
313
|
+
}
|
|
314
|
+
return window;
|
|
315
|
+
}
|
|
316
|
+
function requireAddress(address) {
|
|
317
|
+
const upper = address.trim().toUpperCase();
|
|
318
|
+
if (!/^[A-Z]{1,3}[1-9][0-9]*$/.test(upper)) {
|
|
319
|
+
throw toolError.invalidInput(`${JSON.stringify(address)} is not a cell address`, 'Use A1 notation for a single cell, e.g. "B10".');
|
|
320
|
+
}
|
|
321
|
+
// Reuse the range parser for the Excel row/column bounds.
|
|
322
|
+
parseRange(upper);
|
|
323
|
+
return upper;
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=sheet-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sheet-edit.js","sourceRoot":"","sources":["../../src/tools/sheet-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sheet_read` — read a bounded window of a spreadsheet.
|
|
3
|
+
*
|
|
4
|
+
* The design constraint is context, not capability. A 340-row sheet rendered in
|
|
5
|
+
* full costs more tokens than the answer is worth, so this tool always reads a
|
|
6
|
+
* bounded window, states what it left out, and tells the caller how to continue.
|
|
7
|
+
* Reading everything is not offered.
|
|
8
|
+
*/
|
|
9
|
+
export declare const sheetReadTool: import("./types.js").AnyToolDefinition;
|
|
10
|
+
//# sourceMappingURL=sheet-read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sheet-read.d.ts","sourceRoot":"","sources":["../../src/tools/sheet-read.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA2BH,eAAO,MAAM,aAAa,wCA0HxB,CAAC"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sheet_read` — read a bounded window of a spreadsheet.
|
|
3
|
+
*
|
|
4
|
+
* The design constraint is context, not capability. A 340-row sheet rendered in
|
|
5
|
+
* full costs more tokens than the answer is worth, so this tool always reads a
|
|
6
|
+
* bounded window, states what it left out, and tells the caller how to continue.
|
|
7
|
+
* Reading everything is not offered.
|
|
8
|
+
*/
|
|
9
|
+
import { Workbook, Worksheet } from "documonster/excel";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
import { toolError } from "../errors.js";
|
|
12
|
+
import { resolveInRoot } from "../sandbox.js";
|
|
13
|
+
import { assertReadableSize } from "./fs-helpers.js";
|
|
14
|
+
import { textResult } from "./result.js";
|
|
15
|
+
import { describeWindow, parseRange, renderGrid, requireSheet, sheetName, sheetNames, usedWindow } from "./spreadsheet.js";
|
|
16
|
+
import { defineTool } from "./types.js";
|
|
17
|
+
/** Rows returned when the caller does not say. Fits a screen and a small budget. */
|
|
18
|
+
const DEFAULT_MAX_ROWS = 50;
|
|
19
|
+
/** Hard ceiling on cells per call, whatever the caller asks for. */
|
|
20
|
+
const MAX_CELLS = 20_000;
|
|
21
|
+
export const sheetReadTool = defineTool({
|
|
22
|
+
name: "sheet_read",
|
|
23
|
+
group: "excel",
|
|
24
|
+
title: "Read spreadsheet cells",
|
|
25
|
+
description: "Read a bounded window of an .xlsx/.xlsm sheet as a Markdown table with column letters and row numbers, so cells can be referenced by address afterwards. Call doc_inspect first to learn the sheet names. Reads at most 50 rows unless maxRows says otherwise, and always reports what was omitted.",
|
|
26
|
+
inputSchema: {
|
|
27
|
+
path: z.string().min(1).describe("Workbook path, relative to the server root."),
|
|
28
|
+
sheet: z
|
|
29
|
+
.union([z.string(), z.number().int().positive()])
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Sheet name, or 1-based index. Defaults to the first sheet."),
|
|
32
|
+
range: z
|
|
33
|
+
.string()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe('A1 range such as "B2:D40". Defaults to the used area, capped by maxRows.'),
|
|
36
|
+
mode: z
|
|
37
|
+
.enum(["values", "formulas", "both"])
|
|
38
|
+
.optional()
|
|
39
|
+
.describe('What each cell shows: "values" (formatted, as displayed in Excel), "formulas", or "both". Defaults to "values".'),
|
|
40
|
+
maxRows: z
|
|
41
|
+
.number()
|
|
42
|
+
.int()
|
|
43
|
+
.positive()
|
|
44
|
+
.max(5000)
|
|
45
|
+
.optional()
|
|
46
|
+
.describe(`Row cap for this call. Defaults to ${DEFAULT_MAX_ROWS}.`),
|
|
47
|
+
startRow: z
|
|
48
|
+
.number()
|
|
49
|
+
.int()
|
|
50
|
+
.positive()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("1-based row to resume from — use the value the previous call reported.")
|
|
53
|
+
},
|
|
54
|
+
annotations: { readOnlyHint: true, openWorldHint: false },
|
|
55
|
+
mutates: false,
|
|
56
|
+
handler: async (args, context) => {
|
|
57
|
+
const { config } = context;
|
|
58
|
+
const resolved = await resolveInRoot(config, args.path, { mustExist: true });
|
|
59
|
+
await assertReadableSize(config, resolved, args.path);
|
|
60
|
+
const wb = Workbook.create();
|
|
61
|
+
try {
|
|
62
|
+
await Workbook.readFile(wb, resolved);
|
|
63
|
+
}
|
|
64
|
+
catch (cause) {
|
|
65
|
+
throw toolError.unsupported(`could not read ${args.path} as a workbook`, "Run doc_inspect to confirm the file really is an .xlsx package.", { cause });
|
|
66
|
+
}
|
|
67
|
+
const ws = requireSheet(wb, args.sheet);
|
|
68
|
+
const used = usedWindow(ws);
|
|
69
|
+
if (used === undefined) {
|
|
70
|
+
return textResult(config, `# ${args.path} — ${sheetName(ws)}\n\nThe sheet is empty.\n\nSheets in this workbook: ${sheetNames(wb).join(", ")}`);
|
|
71
|
+
}
|
|
72
|
+
// Intersect with the used area: a caller asking for B2:D400 on a sheet with
|
|
73
|
+
// ten rows of data should get ten rows, not 390 blank ones padding out its
|
|
74
|
+
// context.
|
|
75
|
+
const requested = args.range === undefined ? used : intersect(parseRange(args.range), used);
|
|
76
|
+
if (requested === undefined) {
|
|
77
|
+
return textResult(config, `# ${args.path} — sheet ${JSON.stringify(sheetName(ws))}\n\nRange ${JSON.stringify(args.range)} lies entirely outside the used area (${describeWindow(used)}), so there is nothing to read.`);
|
|
78
|
+
}
|
|
79
|
+
const maxRows = args.maxRows ?? DEFAULT_MAX_ROWS;
|
|
80
|
+
const startRow = Math.max(args.startRow ?? requested.top, requested.top);
|
|
81
|
+
if (startRow > requested.bottom) {
|
|
82
|
+
throw toolError.invalidInput(`startRow ${startRow} is past the end of the range (${describeWindow(requested)})`, "There is nothing left to read; report the data you already have.");
|
|
83
|
+
}
|
|
84
|
+
const window = clamp({ ...requested, top: startRow }, maxRows, requested);
|
|
85
|
+
const table = renderGrid(ws, window, args.mode ?? "values");
|
|
86
|
+
const lines = [
|
|
87
|
+
`# ${args.path} — sheet ${JSON.stringify(sheetName(ws))}`,
|
|
88
|
+
"",
|
|
89
|
+
`- used area: **${describeWindow(used)}** (${used.bottom - used.top + 1} rows × ${used.right - used.left + 1} cols)`,
|
|
90
|
+
`- showing: **${describeWindow(window)}**`,
|
|
91
|
+
`- mode: ${args.mode ?? "values"}`
|
|
92
|
+
];
|
|
93
|
+
const merges = Worksheet.mergedRegions(ws);
|
|
94
|
+
if (merges.length > 0) {
|
|
95
|
+
// Merged cells report their value only in the top-left cell, so a model
|
|
96
|
+
// reading a blank neighbour would otherwise conclude the data is missing.
|
|
97
|
+
lines.push(`- merged regions: ${merges
|
|
98
|
+
.slice(0, 10)
|
|
99
|
+
.map(merge => `${describeWindow(merge)}`)
|
|
100
|
+
.join(", ")}${merges.length > 10 ? ` (+${merges.length - 10} more)` : ""}`);
|
|
101
|
+
}
|
|
102
|
+
const remaining = requested.bottom - window.bottom;
|
|
103
|
+
if (remaining > 0) {
|
|
104
|
+
lines.push(`- **${remaining} row(s) not shown.** Continue with \`startRow: ${window.bottom + 1}\`.`);
|
|
105
|
+
}
|
|
106
|
+
const otherSheets = sheetNames(wb).filter(name => name !== sheetName(ws));
|
|
107
|
+
if (otherSheets.length > 0) {
|
|
108
|
+
lines.push(`- other sheets: ${otherSheets.join(", ")}`);
|
|
109
|
+
}
|
|
110
|
+
lines.push("", table);
|
|
111
|
+
return textResult(config, lines.join("\n"));
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
/** Overlap of two windows, or `undefined` when they do not intersect. */
|
|
115
|
+
function intersect(a, b) {
|
|
116
|
+
const window = {
|
|
117
|
+
top: Math.max(a.top, b.top),
|
|
118
|
+
left: Math.max(a.left, b.left),
|
|
119
|
+
bottom: Math.min(a.bottom, b.bottom),
|
|
120
|
+
right: Math.min(a.right, b.right)
|
|
121
|
+
};
|
|
122
|
+
return window.top > window.bottom || window.left > window.right ? undefined : window;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Apply the row cap and the absolute cell ceiling.
|
|
126
|
+
*
|
|
127
|
+
* The cell ceiling matters independently of the row cap: 50 rows of a 500-column
|
|
128
|
+
* sheet is 25 000 cells, which blows the output budget on its own.
|
|
129
|
+
*/
|
|
130
|
+
function clamp(window, maxRows, bounds) {
|
|
131
|
+
const bottom = Math.min(window.bottom, bounds.bottom, window.top + maxRows - 1);
|
|
132
|
+
const width = Math.max(1, window.right - window.left + 1);
|
|
133
|
+
const affordableRows = Math.max(1, Math.floor(MAX_CELLS / width));
|
|
134
|
+
return {
|
|
135
|
+
...window,
|
|
136
|
+
bottom: Math.min(bottom, window.top + affordableRows - 1)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=sheet-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sheet-read.js","sourceRoot":"","sources":["../../src/tools/sheet-read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `sheet_write` — create a workbook from a declarative spec.
|
|
3
|
+
*
|
|
4
|
+
* Declarative rather than incremental for two reasons. A model driving twenty
|
|
5
|
+
* `set_cell` calls burns twenty round trips and has to hold the intermediate
|
|
6
|
+
* state; and `fromCsv` lets a source file be referenced by path so the rows
|
|
7
|
+
* never pass through the model's context at all — which is the difference
|
|
8
|
+
* between summarising three 4000-row CSVs and running out of budget trying.
|
|
9
|
+
*
|
|
10
|
+
* The schema is deliberately shallow. Every field here is sent to the model on
|
|
11
|
+
* every request, so styling is limited to the handful of options that actually
|
|
12
|
+
* change a report's usefulness; the deep option trees stay in `documonster_help`.
|
|
13
|
+
*/
|
|
14
|
+
export declare const sheetWriteTool: import("./types.js").AnyToolDefinition;
|
|
15
|
+
//# sourceMappingURL=sheet-write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sheet-write.d.ts","sourceRoot":"","sources":["../../src/tools/sheet-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAoGH,eAAO,MAAM,cAAc,wCAmFzB,CAAC"}
|