@components-kit/open-workbook 0.1.2 → 0.1.4
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/README.md +3 -4
- package/assets/backend/dist/runtime-service.d.ts +132 -191
- package/assets/backend/dist/runtime-service.d.ts.map +1 -1
- package/assets/backend/dist/runtime-service.js +85 -8
- package/assets/backend/dist/runtime-service.js.map +1 -1
- package/assets/excel-addin/dist/assets/icon-80.png +0 -0
- package/assets/excel-addin/dist/connection.d.ts.map +1 -1
- package/assets/excel-addin/dist/connection.js +4 -1
- package/assets/excel-addin/dist/connection.js.map +1 -1
- package/assets/excel-addin/dist/excel-executor.d.ts +7 -2
- package/assets/excel-addin/dist/excel-executor.d.ts.map +1 -1
- package/assets/excel-addin/dist/excel-executor.js +204 -40
- package/assets/excel-addin/dist/excel-executor.js.map +1 -1
- package/assets/excel-addin/dist/taskpane.bundle.js +49 -0
- package/assets/excel-addin/dist/taskpane.css +572 -0
- package/assets/excel-addin/dist/taskpane.d.ts.map +1 -1
- package/assets/excel-addin/dist/taskpane.html +28 -0
- package/assets/excel-addin/dist/taskpane.js +86 -24
- package/assets/excel-addin/dist/taskpane.js.map +1 -1
- package/assets/excel-addin/manifest.xml +24 -22
- package/assets/excel-addin/public/assets/icon-80.png +0 -0
- package/assets/excel-addin/public/taskpane.css +551 -26
- package/assets/excel-addin/public/taskpane.html +10 -17
- package/assets/excel-addin/scripts/dev-server.mjs +4 -33
- package/assets/instructions/open-workbook-excel/references/tool-selection.md +4 -2
- package/assets/instructions/open-workbook-excel/references/workflows.md +7 -4
- package/assets/mcp-server/dist/index.js +72 -7
- package/assets/mcp-server/dist/index.js.map +1 -1
- package/dist/index.js +48 -51
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { mkdir, readFile, stat, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { BackupManager, BatchCompiler, DefaultPermissionPolicy, buildFormulaDependencyGraph, attachConflictGuidance, extractFormulaReferences, hashStable, LockManager, parseA1Address, PlanManager, SnapshotManager, TaskRegistry, TemplateRegistry, TransactionManager, traceDependents, tracePrecedents } from "@components-kit/open-workbook-excel-core";
|
|
4
|
+
import { BackupManager, BatchCompiler, DefaultPermissionPolicy, buildFormulaDependencyGraph, attachConflictGuidance, extractFormulaReferences, hashStable, LockManager, formatA1Address, parseA1Address, PlanManager, SnapshotManager, TaskRegistry, TemplateRegistry, TransactionManager, traceDependents, tracePrecedents } from "@components-kit/open-workbook-excel-core";
|
|
5
5
|
import { makeRollbackConflict } from "@components-kit/open-workbook-excel-core";
|
|
6
6
|
import { getToolCatalogSummary, PromptCatalog, ResourceCatalog, makeId, runtimeError } from "@components-kit/open-workbook-protocol";
|
|
7
7
|
import { SessionRegistry } from "./session-registry.js";
|
|
8
8
|
import { NativeFileBridge } from "./native-file-bridge.js";
|
|
9
9
|
import { RuntimeStateStore } from "./state-store.js";
|
|
10
|
-
const runtimeVersion = process.env.OPEN_WORKBOOK_VERSION ?? "0.1.
|
|
10
|
+
const runtimeVersion = process.env.OPEN_WORKBOOK_VERSION ?? "0.1.4";
|
|
11
11
|
export class RuntimeService {
|
|
12
12
|
sessions = new SessionRegistry();
|
|
13
13
|
backups = new BackupManager();
|
|
@@ -2710,11 +2710,9 @@ export class RuntimeService {
|
|
|
2710
2710
|
return cleaningError(input.workbookId, "normalize_headers", target, read.error);
|
|
2711
2711
|
}
|
|
2712
2712
|
const headerRowIndex = input.headerRowIndex ?? detectHeaderCandidates(read.values, 10)[0]?.rowIndex ?? 0;
|
|
2713
|
-
const
|
|
2714
|
-
const before = values[headerRowIndex] ?? [];
|
|
2713
|
+
const before = read.values[headerRowIndex] ?? [];
|
|
2715
2714
|
const normalized = dedupeHeaders(before.map((value) => normalizeHeader(String(value ?? ""))));
|
|
2716
|
-
|
|
2717
|
-
const result = await this.writeCleanValues(target, values, "Normalize headers");
|
|
2715
|
+
const result = await this.writeCleanValues(headerRowTarget(target, headerRowIndex), [normalized], "Normalize headers");
|
|
2718
2716
|
return cleaningReport(input.workbookId, "normalize_headers", target, changedCellCount([before], [normalized]), { headerRowIndex, headers: normalized }, result);
|
|
2719
2717
|
}
|
|
2720
2718
|
async cleanTrimWhitespace(input) {
|
|
@@ -3139,6 +3137,22 @@ export class RuntimeService {
|
|
|
3139
3137
|
async resizeTable(request) {
|
|
3140
3138
|
return this.mutateTable("table.resize", request, `Before resizing table ${request.tableName}`, await this.getTableBackupRanges(request));
|
|
3141
3139
|
}
|
|
3140
|
+
async reorderTableColumns(request) {
|
|
3141
|
+
const infoResult = await this.getTableInfo(request);
|
|
3142
|
+
const info = infoResult.info;
|
|
3143
|
+
if (!info) {
|
|
3144
|
+
return {
|
|
3145
|
+
ok: false,
|
|
3146
|
+
error: runtimeError("NOT_FOUND", `Table ${request.tableName} could not be read before column reorder.`, { retryable: false }),
|
|
3147
|
+
table: infoResult
|
|
3148
|
+
};
|
|
3149
|
+
}
|
|
3150
|
+
const validation = validateTableColumnOrder(info, request.columnOrder);
|
|
3151
|
+
if (!validation.ok) {
|
|
3152
|
+
return validation;
|
|
3153
|
+
}
|
|
3154
|
+
return this.mutateTable("table.reorder_columns", request, `Before reordering columns in table ${request.tableName}`, await this.getTableBackupRanges(request));
|
|
3155
|
+
}
|
|
3142
3156
|
async appendTableRows(request) {
|
|
3143
3157
|
return this.mutateTable("table.append_rows", request, `Before appending rows to table ${request.tableName}`, await this.getTableBackupRanges(request));
|
|
3144
3158
|
}
|
|
@@ -3268,15 +3282,18 @@ export class RuntimeService {
|
|
|
3268
3282
|
workbookId: request.workbookId,
|
|
3269
3283
|
goal: reason,
|
|
3270
3284
|
scopes: tableMutationScopes(request, ranges),
|
|
3271
|
-
destructiveLevel: method.includes("resize") || method.includes("copy_structure") ? "structure" : "values"
|
|
3285
|
+
destructiveLevel: method.includes("resize") || method.includes("copy_structure") || method.includes("reorder_columns") ? "structure" : "values"
|
|
3272
3286
|
}, async () => {
|
|
3273
3287
|
const backup = await this.createWorkbookBackup({
|
|
3274
3288
|
workbookId: request.workbookId,
|
|
3275
3289
|
reason,
|
|
3276
3290
|
ranges
|
|
3277
3291
|
});
|
|
3292
|
+
if (!("backup" in backup)) {
|
|
3293
|
+
return backup;
|
|
3294
|
+
}
|
|
3278
3295
|
const result = await client.request(method, request);
|
|
3279
|
-
return { ok: true, backup, result };
|
|
3296
|
+
return { ok: true, backup: backup.backup, result };
|
|
3280
3297
|
});
|
|
3281
3298
|
}
|
|
3282
3299
|
async mutateFormulas(method, request, reason, validate) {
|
|
@@ -5338,6 +5355,58 @@ function pivotTemplateRequiredSourceFields(info) {
|
|
|
5338
5355
|
function uniqueDefined(values) {
|
|
5339
5356
|
return [...new Set(values.filter((value) => typeof value === "string" && value.length > 0))];
|
|
5340
5357
|
}
|
|
5358
|
+
function validateTableColumnOrder(info, columnOrder) {
|
|
5359
|
+
const issues = [];
|
|
5360
|
+
if (columnOrder.length !== info.columns.length) {
|
|
5361
|
+
issues.push({
|
|
5362
|
+
code: "TABLE_COLUMN_ORDER_LENGTH_MISMATCH",
|
|
5363
|
+
message: `Column order must include exactly ${info.columns.length} column(s).`,
|
|
5364
|
+
details: { expectedCount: info.columns.length, actualCount: columnOrder.length }
|
|
5365
|
+
});
|
|
5366
|
+
}
|
|
5367
|
+
const seen = new Set();
|
|
5368
|
+
for (const requested of columnOrder) {
|
|
5369
|
+
const column = typeof requested === "number"
|
|
5370
|
+
? info.columns.find((candidate) => candidate.index === requested)
|
|
5371
|
+
: info.columns.find((candidate) => candidate.name === requested);
|
|
5372
|
+
if (!column) {
|
|
5373
|
+
issues.push({
|
|
5374
|
+
code: "TABLE_COLUMN_NOT_FOUND",
|
|
5375
|
+
message: `Column ${String(requested)} is not present in table ${info.tableName}.`,
|
|
5376
|
+
details: { requested, availableColumns: info.columns.map((candidate) => candidate.name) }
|
|
5377
|
+
});
|
|
5378
|
+
continue;
|
|
5379
|
+
}
|
|
5380
|
+
if (seen.has(column.index)) {
|
|
5381
|
+
issues.push({
|
|
5382
|
+
code: "TABLE_COLUMN_ORDER_DUPLICATE",
|
|
5383
|
+
message: `Column ${column.name} appears more than once in the requested order.`,
|
|
5384
|
+
details: { requested, column }
|
|
5385
|
+
});
|
|
5386
|
+
}
|
|
5387
|
+
seen.add(column.index);
|
|
5388
|
+
}
|
|
5389
|
+
for (const column of info.columns) {
|
|
5390
|
+
if (!seen.has(column.index)) {
|
|
5391
|
+
issues.push({
|
|
5392
|
+
code: "TABLE_COLUMN_ORDER_MISSING_COLUMN",
|
|
5393
|
+
message: `Column ${column.name} is missing from the requested order.`,
|
|
5394
|
+
details: { column }
|
|
5395
|
+
});
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
if (issues.length > 0) {
|
|
5399
|
+
return {
|
|
5400
|
+
ok: false,
|
|
5401
|
+
warnings: issues,
|
|
5402
|
+
error: runtimeError("INVALID_ARGUMENT", "Table column reorder requires a complete, unique column order.", {
|
|
5403
|
+
retryable: false,
|
|
5404
|
+
details: { issues }
|
|
5405
|
+
})
|
|
5406
|
+
};
|
|
5407
|
+
}
|
|
5408
|
+
return { ok: true };
|
|
5409
|
+
}
|
|
5341
5410
|
function addExpectedPivotAxisIssues(issues, axis, expectedFields, actualFields) {
|
|
5342
5411
|
if (!expectedFields?.length) {
|
|
5343
5412
|
return;
|
|
@@ -5549,6 +5618,14 @@ function targetFromCleanInput(input) {
|
|
|
5549
5618
|
address: input.address
|
|
5550
5619
|
};
|
|
5551
5620
|
}
|
|
5621
|
+
function headerRowTarget(target, headerRowIndex) {
|
|
5622
|
+
const parsed = parseA1Address(stripSheetName(target.address));
|
|
5623
|
+
const row = parsed.startRow + headerRowIndex;
|
|
5624
|
+
return {
|
|
5625
|
+
...target,
|
|
5626
|
+
address: formatA1Address({ startColumn: parsed.startColumn, endColumn: parsed.endColumn, startRow: row, endRow: row })
|
|
5627
|
+
};
|
|
5628
|
+
}
|
|
5552
5629
|
function cleaningReport(workbookId, action, target, changedCells, data, result) {
|
|
5553
5630
|
const report = {
|
|
5554
5631
|
ok: result ? result.ok : true,
|