xlsx-for-ai 1.5.2 → 1.5.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 +12 -3
- package/WHY.md +0 -1
- package/index.js +10 -37
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 👋 **New here? Not a programmer?** → [Read WHY.md for the plain-English version](WHY.md). The README below is the technical reference.
|
|
4
4
|
|
|
5
|
-
**The bidirectional bridge between spreadsheets and AI agents.** Reads `.xlsx` (
|
|
5
|
+
**The bidirectional bridge between spreadsheets and AI agents.** Reads `.xlsx` (plus `.csv`, `.tsv`) into the formats LLMs actually consume — markdown, JSON, text, SQL — and writes spreadsheets back out from AI-generated specs. Same tool, both directions.
|
|
6
6
|
|
|
7
7
|
AI tools — Claude, Cursor, Copilot, ChatGPT, and other LLM coding agents — can read text files but **not** `.xlsx` binaries. This CLI closes the loop:
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ AI tools — Claude, Cursor, Copilot, ChatGPT, and other LLM coding agents — c
|
|
|
10
10
|
|
|
11
11
|
**✍️ Write mode (`xlsx-for-ai write`)** — turn an AI-generated JSON or markdown spec into a real `.xlsx` file. Closes the round-trip so an agent that *reviews* your spreadsheet can also *deliver the corrected file*. The output includes a `_xlsx-for-ai` review tab explaining every structural change the round-trip made (with risks, tradeoffs, and overrides) — the supervisor model: AI does the work, the human stays in control of every decision. Verified lossless on 29/30 real workbooks.
|
|
12
12
|
|
|
13
|
-
**Input formats:** `.xlsx` `.xls` `.xlsb` `.ods` `.
|
|
13
|
+
**Input formats:** `.xlsx` `.csv` `.tsv` (legacy `.xls` / `.xlsb` / `.ods` removed in 1.5.4 — convert to `.xlsx` first; see [#26](https://github.com/senoff/xlsx-for-ai/issues/26))
|
|
14
14
|
|
|
15
15
|
**Output modes:** text dump, markdown tables (best LLM comprehension per token), JSON, SQL `CREATE TABLE`+`INSERT`, inferred schema, workbook diff, real `.xlsx` (write mode).
|
|
16
16
|
|
|
@@ -315,7 +315,16 @@ The CLI install (`npm install -g xlsx-for-ai`) is clean — no deprecation warni
|
|
|
315
315
|
|
|
316
316
|
Run `rm -rf node_modules package-lock.json && npm install` and the warnings will clear. xlsx-for-ai's tests pass against these versions, so the upgrade is safe.
|
|
317
317
|
|
|
318
|
-
|
|
318
|
+
`patch-package` is in `devDependencies` for authoring patches. The postinstall hook is *not* wired today — no patches exist, and a hook that tries to invoke a missing dev-only binary would break consumer installs. When the first patch lands, the hook is added in the same commit as the patch file.
|
|
319
|
+
|
|
320
|
+
### Audit findings on install
|
|
321
|
+
|
|
322
|
+
As of 1.5.4, `npm install xlsx-for-ai` finds **no inherited audit advisories**. The previous `xlsx` (sheetJS) and `uuid` findings were closed by:
|
|
323
|
+
|
|
324
|
+
- **`xlsx` removed in 1.5.4** — see [#26](https://github.com/senoff/xlsx-for-ai/issues/26). The legacy `.xls` / `.xlsb` / `.ods` input path that depended on it is no longer supported; the modern `@protobi/exceljs` engine handles `.xlsx` (and CSV / TSV continue to use `papaparse`).
|
|
325
|
+
- **`uuid` bumped to ^14 via `overrides`** — clears the `GHSA-w5hq-g745-h8pq` advisory inherited transitively from ExcelJS. Mirrors the upstream protobi/exceljs gift PR locally.
|
|
326
|
+
|
|
327
|
+
The triage workflow lives in [`.github/audit-allowlist.json`](.github/audit-allowlist.json) (currently empty) and `audit.yml` for whenever a future advisory needs accepting.
|
|
319
328
|
|
|
320
329
|
## Reporting bugs
|
|
321
330
|
|
package/WHY.md
CHANGED
|
@@ -30,7 +30,6 @@ A few examples people find useful:
|
|
|
30
30
|
- **Compare two versions of the same spreadsheet** ("what changed between V11 and V14?") and get a list of every cell that moved.
|
|
31
31
|
- **Turn a CSV export from QuickBooks into a clean SQL database table** in one command, with the column types figured out automatically.
|
|
32
32
|
- **Walk through a 50-tab model someone else built** and have the AI explain how the sheets reference each other.
|
|
33
|
-
- **Process a folder of legacy `.xls` files** that won't even open in modern Excel without complaint.
|
|
34
33
|
|
|
35
34
|
But the biggest unlock is the next thing.
|
|
36
35
|
|
package/index.js
CHANGED
|
@@ -31,8 +31,7 @@ const engine = require('./lib/engine');
|
|
|
31
31
|
|
|
32
32
|
// Lazy-load heavy deps only when their feature is used (keeps cold start fast
|
|
33
33
|
// for the common --stdout / --json / --md path that needs none of them).
|
|
34
|
-
let
|
|
35
|
-
const lazyXlsx = () => (_xlsxLib ??= require('xlsx'));
|
|
34
|
+
let _papaLib, _formulaJsLib, _tokenizerLib;
|
|
36
35
|
const lazyPapa = () => (_papaLib ??= require('papaparse'));
|
|
37
36
|
const lazyFormulaJs = () => (_formulaJsLib ??= require('@formulajs/formulajs'));
|
|
38
37
|
const lazyTokenizer = () => (_tokenizerLib ??= require('gpt-tokenizer'));
|
|
@@ -108,7 +107,7 @@ coding agents can read. Preserves values, formulas, formatting, layout.
|
|
|
108
107
|
The 'write' sub-command does the reverse: takes a JSON or markdown spec and
|
|
109
108
|
produces an .xlsx file. Run 'xlsx-for-ai write --help' for details.
|
|
110
109
|
|
|
111
|
-
Input formats: .xlsx .
|
|
110
|
+
Input formats: .xlsx .csv .tsv
|
|
112
111
|
|
|
113
112
|
Output modes (mutually exclusive; default = text):
|
|
114
113
|
--md Markdown tables — best LLM comprehension per token
|
|
@@ -1081,40 +1080,14 @@ async function loadAnyWorkbook(filePath) {
|
|
|
1081
1080
|
return wb;
|
|
1082
1081
|
}
|
|
1083
1082
|
if (ext === '.xls' || ext === '.xlsb' || ext === '.ods') {
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
// workbook representation so the rest of the code (dump/markdown/json/sql/
|
|
1091
|
-
// schema) works unchanged. Loses some formatting; preserves values + formulas.
|
|
1092
|
-
function loadViaSheetJS(filePath) {
|
|
1093
|
-
const XLSX = lazyXlsx();
|
|
1094
|
-
const sheetJsWb = XLSX.readFile(filePath, { cellFormula: true, cellDates: true });
|
|
1095
|
-
const wb = engine.createWorkbook();
|
|
1096
|
-
for (const name of sheetJsWb.SheetNames) {
|
|
1097
|
-
const sjsSheet = sheetJsWb.Sheets[name];
|
|
1098
|
-
const ws = wb.addWorksheet(name);
|
|
1099
|
-
if (!sjsSheet['!ref']) continue;
|
|
1100
|
-
const range = XLSX.utils.decode_range(sjsSheet['!ref']);
|
|
1101
|
-
for (let r = range.s.r; r <= range.e.r; r++) {
|
|
1102
|
-
for (let c = range.s.c; c <= range.e.c; c++) {
|
|
1103
|
-
const addr = XLSX.utils.encode_cell({ r, c });
|
|
1104
|
-
const cell = sjsSheet[addr];
|
|
1105
|
-
if (!cell) continue;
|
|
1106
|
-
const target = ws.getRow(r + 1).getCell(c + 1);
|
|
1107
|
-
if (cell.f) {
|
|
1108
|
-
target.value = { formula: cell.f, result: cell.v };
|
|
1109
|
-
} else if (cell.t === 'd') {
|
|
1110
|
-
target.value = cell.v instanceof Date ? cell.v : new Date(cell.v);
|
|
1111
|
-
} else {
|
|
1112
|
-
target.value = cell.v;
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1083
|
+
throw new Error(
|
|
1084
|
+
`Legacy format ${ext} is no longer supported. Convert to .xlsx first ` +
|
|
1085
|
+
`(e.g. open in Excel/LibreOffice and Save As .xlsx). See ` +
|
|
1086
|
+
`https://github.com/senoff/xlsx-for-ai/issues/26 for the discussion of ` +
|
|
1087
|
+
`whether to restore native support.`
|
|
1088
|
+
);
|
|
1116
1089
|
}
|
|
1117
|
-
|
|
1090
|
+
throw new Error(`Unsupported extension: ${ext}. Supported: .xlsx .csv .tsv`);
|
|
1118
1091
|
}
|
|
1119
1092
|
|
|
1120
1093
|
// ---------------------------------------------------------------------------
|
|
@@ -1938,7 +1911,7 @@ async function main() {
|
|
|
1938
1911
|
}
|
|
1939
1912
|
// Min 22 bytes (zip EOCD) only meaningful for binary formats; CSV/TSV can be smaller.
|
|
1940
1913
|
const ext = path.extname(filePath).toLowerCase();
|
|
1941
|
-
const isBinary = ext === '.xlsx'
|
|
1914
|
+
const isBinary = ext === '.xlsx';
|
|
1942
1915
|
if (isBinary && stat.size < 22) {
|
|
1943
1916
|
console.error(`File is too small (${stat.size} bytes) to be a valid spreadsheet: ${filePath}`);
|
|
1944
1917
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xlsx-for-ai",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"description": "CLI that converts .xlsx files into rich text or JSON dumps that AI coding agents (Claude, Cursor, Copilot, ChatGPT, etc.) can read — preserving values, formulas, formatting, colors, column widths, frozen panes, named ranges, tables, and more.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -51,8 +51,7 @@
|
|
|
51
51
|
"@protobi/exceljs": "^4.4.0-protobi.9",
|
|
52
52
|
"gpt-tokenizer": "^3.4.0",
|
|
53
53
|
"jszip": "^3.10.1",
|
|
54
|
-
"papaparse": "^5.5.3"
|
|
55
|
-
"xlsx": "^0.18.5"
|
|
54
|
+
"papaparse": "^5.5.3"
|
|
56
55
|
},
|
|
57
56
|
"devDependencies": {
|
|
58
57
|
"patch-package": "^8.0.1"
|
|
@@ -61,6 +60,7 @@
|
|
|
61
60
|
"glob": "^13.0.0",
|
|
62
61
|
"rimraf": "^5.0.10",
|
|
63
62
|
"unzipper": "^0.12.3",
|
|
64
|
-
"fast-csv": "^5.0.2"
|
|
63
|
+
"fast-csv": "^5.0.2",
|
|
64
|
+
"uuid": "^14.0.0"
|
|
65
65
|
}
|
|
66
66
|
}
|