xlsx-for-ai 1.4.0 → 1.4.2

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.
Files changed (4) hide show
  1. package/README.md +7 -5
  2. package/WHY.md +46 -9
  3. package/index.js +38 -0
  4. package/package.json +1 -1
package/README.md CHANGED
@@ -2,15 +2,17 @@
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
- Converts spreadsheets into text, **markdown**, JSON, SQL, or schema dumps that AI coding agents can actually read.
5
+ **The bidirectional bridge between spreadsheets and AI agents.** Reads `.xlsx` (and `.xls`, `.xlsb`, `.ods`, `.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
- AI tools — Claude, Cursor, Copilot, ChatGPT, and other LLM coding agents — can read text files but **not** `.xlsx` binaries. This CLI bridges the gap.
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
 
9
- **Input formats:** `.xlsx` `.xls` `.xlsb` `.ods` `.csv` `.tsv`
9
+ **📖 Read mode (default)** turn any spreadsheet into LLM-readable output. Every formula, every named range, every merged cell, every fill color, every cross-sheet reference. No more pasting numbers and losing context.
10
+
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.
10
12
 
11
- **Output modes:** text dump, markdown tables (best LLM comprehension per token), JSON, SQL `CREATE TABLE`+`INSERT`, inferred schema, workbook diff.
13
+ **Input formats:** `.xlsx` `.xls` `.xlsb` `.ods` `.csv` `.tsv`
12
14
 
13
- **Write mode** (`xlsx-for-ai write`): builds a real `.xlsx` from a JSON or markdown spec closes the round-trip so an AI agent that reads a spreadsheet can also produce a corrected version. Supports formulas, formatting, merged cells, named ranges, frozen panes, and column widths. Verified lossless on 29/30 real workbooks (the one MINOR is a CRLF→LF cosmetic difference). See [`xlsx-for-ai write --help`](README.md#write-mode-xlsx-for-ai-write).
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).
14
16
 
15
17
  It extracts everything a human would see in Excel:
16
18
 
package/WHY.md CHANGED
@@ -27,26 +27,63 @@ That's the difference between a friend skimming the printed numbers and an analy
27
27
  A few examples people find useful:
28
28
 
29
29
  - **Have your AI find errors in a financial model** before you send it to your accountant or your board.
30
- - **Have your AI hand you back a corrected version** — not just *say* what should change, but actually produce the fixed `.xlsx` with the changes applied. The corrected file even includes a built-in review note explaining what the AI changed, why, and how to override anything you don't agree with. Same shape as having a careful editor mark up your draft.
31
30
  - **Compare two versions of the same spreadsheet** ("what changed between V11 and V14?") and get a list of every cell that moved.
32
31
  - **Turn a CSV export from QuickBooks into a clean SQL database table** in one command, with the column types figured out automatically.
33
32
  - **Walk through a 50-tab model someone else built** and have the AI explain how the sheets reference each other.
34
33
  - **Process a folder of legacy `.xls` files** that won't even open in modern Excel without complaint.
35
34
 
36
- ## How to actually use it
35
+ But the biggest unlock is the next thing.
37
36
 
38
- It's a small command-line tool. Once a programmer sets it up (one line: `npm install -g xlsx-for-ai`), you don't have to think about it again your AI tools pick it up automatically and start using it whenever they encounter a spreadsheet.
37
+ ## Now your AI can hand you back the filenot just words
39
38
 
40
- If you're the programmer doing the install, the [README](README.md) has the full reference. If you're handing this to a programmer to set up for you, that link is what they'll need.
39
+ Before, even once AI could read your spreadsheet, it could only *tell* you what to change. You'd still have to translate its advice into actual cell edits yourself. Tedious for two cells. Impossible for fifty.
40
+
41
+ Now the AI can do the editing for you. Same starting moment — you ask Claude to review your tax estimate, or update Q4 numbers in your forecast, or fix a broken cap table — but instead of describing the corrections, it builds you the actual fixed `.xlsx` and hands it back.
42
+
43
+ A real moment that gets unlocked:
44
+
45
+ > **You:** *"Here's our 2026 budget V11. Sales asked us to add a Travel line and bump Marketing to $52K each quarter. Update it."*
46
+ >
47
+ > **Claude (after a moment):** *"Done. I added a Travel row at the bottom with placeholder zeros (since you didn't give numbers), bumped Marketing to $52,000 across all four quarters, and updated the totals row to reflect the new sum. Here's V12 — I left a note in the file explaining everything I did."*
48
+
49
+ You open V12 in Excel. Marketing is updated. Travel exists. Totals are right. Then you flip to the rightmost tab — `_xlsx-for-ai` — and find what looks like a careful editor's notes on the changes.
50
+
51
+ ## What's in the review tab
52
+
53
+ It's the AI's note to you about exactly what it changed and why, written in plain English. For each kind of change, you get a small block like this:
54
+
55
+ > **Issue: Marketing line update** *(4 cells)*
56
+ >
57
+ > **What happened.** You asked to bump Marketing to $52,000 per quarter.
58
+ >
59
+ > **What we did.** Updated B12, C12, D12, E12 to $52,000 each.
60
+ >
61
+ > **Risk.** The totals row (row 20) recomputes automatically — confirm the new bottom-line totals match what you expected.
62
+ >
63
+ > **Alternative.** If you wanted Marketing scaled differently per quarter (e.g., higher in Q4), tell me and I'll redo it.
41
64
 
42
- ## How it works in plain terms
65
+ You can read the whole tab in 30 seconds. Then you either accept what the AI did, or push back on any individual item. Same shape as a careful editor marking up your draft — observation, reasoning, and a clear way to override.
43
66
 
44
- Today's AI is great at reasoning about text but blind to spreadsheet binaries. `xlsx-for-ai` is the translator in both directions:
67
+ This is on purpose. The tool is designed around the **supervisor** model: AI does the work, but the human stays in control of every decision. The review tab is what makes that real — without it, the AI would be making silent changes you'd only discover by accident later. With it, every choice the AI made is visible, named, and reversible.
45
68
 
46
- - **Reading:** turns your spreadsheet into a format the AI can fully see — every formula, every formatting cue, every relationship between sheets.
47
- - **Writing:** turns the AI's response back into a real `.xlsx` file you can open, edit, and share. The AI can now hand you a corrected workbook, not just words about it.
69
+ ## Why this matters
48
70
 
49
- When the AI delivers you a corrected file, the file itself contains a small **review tab** explaining what the AI changed about the structure, why it made each call, what the risks are, and what your alternatives are if you'd prefer a different approach. The tool's design follows the *supervisor* model — it surfaces decisions for you to review, rather than silently making changes you'd discover later.
71
+ Without the corrected file, AI is a really expensive consultant. It looks at your spreadsheet, talks for a while, and leaves you with a list of things to do yourself. No leverage on the actual work.
72
+
73
+ With the corrected file, AI is more like a junior analyst. It does the work, hands you the result, explains its reasoning, and waits for your review. Same role you've always wanted — without the hourly rate.
74
+
75
+ ## How to actually use it
76
+
77
+ You don't run anything. Your AI does.
78
+
79
+ 1. **Install once.** A programmer (or you, if you're comfortable with one terminal command) runs `npm install -g xlsx-for-ai`. Then forget about it.
80
+ 2. **Drop a file into Claude, Cursor, Copilot, or ChatGPT** (the desktop apps with code execution, or any agent setup that can run commands). The AI picks up the tool automatically when it sees a spreadsheet.
81
+ 3. **Ask whatever you want** — review, fix errors, update numbers, generate reports, compare versions, restructure.
82
+ 4. **The AI hands back** either a text answer (when that's what you asked for) or a real `.xlsx` file with the review tab (when you asked for changes).
83
+
84
+ Most users never type a command.
85
+
86
+ If you're the programmer doing the install, the [README](README.md) has the full reference. If you're handing this to a programmer to set up for you, that link is what they'll need.
50
87
 
51
88
  ## Why this didn't exist before
52
89
 
package/index.js CHANGED
@@ -599,6 +599,23 @@ function dumpSheetJSON(ws, wb, opts = {}) {
599
599
  if (col.hidden) out.hiddenColumns.push(letter);
600
600
  out.columns.push({ letter, width: col.width || null, hidden: !!col.hidden });
601
601
  }
602
+ // Some xlsx files set widths on columns past the populated range (e.g.,
603
+ // columns reserved for future data, or styling-only columns). ExcelJS's
604
+ // columnCount stops at populated cells, so a naive loop misses those widths
605
+ // and they silently drop on round-trip. Walk ws.columns directly to pick up
606
+ // any column metadata beyond endCol.
607
+ try {
608
+ const allCols = ws.columns || [];
609
+ for (let i = endCol; i < allCols.length; i++) {
610
+ const col = allCols[i];
611
+ if (!col) continue;
612
+ if (col.width != null || col.hidden) {
613
+ const letter = colLetter(i + 1);
614
+ if (col.hidden) out.hiddenColumns.push(letter);
615
+ out.columns.push({ letter, width: col.width || null, hidden: !!col.hidden });
616
+ }
617
+ }
618
+ } catch (_) {}
602
619
 
603
620
  if (ws.autoFilter) out.autoFilter = typeof ws.autoFilter === 'string' ? ws.autoFilter : (ws.autoFilter.ref || null);
604
621
  try { if (ws.pageSetup?.printArea) out.printArea = ws.pageSetup.printArea; } catch (_) {}
@@ -1294,6 +1311,20 @@ function buildWorkbook(spec) {
1294
1311
  try { ws.getColumn(colNum(letter)).width = width; } catch (_) {}
1295
1312
  }
1296
1313
  }
1314
+ // Also read widths from the `columns` array — that's the shape `--json`
1315
+ // output produces (`columns: [{letter, width, hidden}, ...]`). Without
1316
+ // this, round-tripping a workbook through `--json` → `write` silently
1317
+ // dropped all column widths, breaking the documented round-trip claim.
1318
+ if (Array.isArray(sheet.columns)) {
1319
+ for (const col of sheet.columns) {
1320
+ if (!col || !col.letter) continue;
1321
+ try {
1322
+ const c = ws.getColumn(colNum(col.letter));
1323
+ if (col.width != null) c.width = col.width;
1324
+ if (col.hidden) c.hidden = true;
1325
+ } catch (_) {}
1326
+ }
1327
+ }
1297
1328
 
1298
1329
  if (Array.isArray(sheet.cells)) {
1299
1330
  // Per-cell mode (round-trip from --json). cells: [{ref, value, ...style}, ...]
@@ -1631,6 +1662,13 @@ async function mainWrite(argv) {
1631
1662
  async function main() {
1632
1663
  const argv = process.argv.slice(2);
1633
1664
 
1665
+ // --version / -v: short-circuit before any file parsing so users can ask
1666
+ // the version without it being treated as a filename. Mirrors --help.
1667
+ if (argv[0] === '--version' || argv[0] === '-v') {
1668
+ console.log(require('./package.json').version);
1669
+ process.exit(0);
1670
+ }
1671
+
1634
1672
  // Sub-command dispatch
1635
1673
  if (argv[0] === 'write') return mainWrite(argv.slice(1));
1636
1674
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xlsx-for-ai",
3
- "version": "1.4.0",
3
+ "version": "1.4.2",
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": {