Files
gridcraft/ROADMAP.md
T
Pranav e1a12fa337 UI: theme tokens with a contrast test, ribbon overflow arrows and split button, multi-line formula bar, code editor widget (#456)
* UI: theme tokens for icon, reference and sheet-control colours; WCAG contrast test

Tokens gains the colours the chrome was hard-coding, each with a light
and a dark value: on_accent (text on an accent fill), an eight-colour
category palette (theme::Cat), the paper colour inside icons, reference
colours for the formula bar and for the sheet, the message box warning
disc, the tab bar scroll thumb, and sheet_control_* colours that follow
the sheet and so stay light in both themes.

What now comes from the tokens:
- icons: paper (white pages glared in dark mode) and the accent
  constants; icons placed on the sheet use icons::paint_on_sheet, which
  keeps the light colours;
- reference colours (editor::REF_COLORS), which were hard to read on the
  dark formula field;
- white text on the accent in OK, Solve, slicer tiles and the AutoSave
  switch, 2:1 on the dark accent;
- the comments pane (a white card with light text in dark mode), gallery
  hover and swatch outlines, the message box disc, the tab bar thumb,
  chart selection frames, and the sheet's filter and validation buttons.

A unit test (theme::contrast_tests) checks every token pair used by the
ribbon, popups, dialogs, panes, formula bar, status bar and sheet in
both themes against WCAG 2: 4.5:1 for text and 3:1 for glyphs. It caught
the dark danger red (3.5:1 on hover) and the selected header text (4.1:1
light), which are adjusted.

* UI: ribbon scroll arrows, large split button for Formulas › AutoSum

- widgets::big_split_button: the icon runs the default action, the
  label and its arrow open the menu. It returns both responses, with
  accessible names ("AutoSum" and "AutoSum options"). big_button shares
  its label layout.
- Formulas › AutoSum uses it: the icon inserts SUM as before, and the
  arrow, which used to do the same, opens the Sum / Average / Count /
  Max / Min / More Functions menu that Home › AutoSum already had
  (shared as autosum_menu). Its keytip is unchanged.
- When a tab's groups are wider than the window, arrows at the card's
  edges scroll them; before, only the mouse wheel did and nothing showed
  that the tab went on. ribbon::RibbonOverflow records the groups' and
  the card's sizes each frame.
- A test checks every tab fits the card's three rows. It found View ›
  Show stacking four checkboxes, with Headings cut off; Show is now two
  columns (Ruler, Gridlines / Formula Bar, Headings).

Tests: tests/ribbon_layout.rs (the split button's two parts, AutoSum's
icon and menu, the scroll arrows, the card height).

* UI: formula bar grows from one to five lines; code editor widget

The formula bar is a top-aligned row: the Name Box and the cancel,
enter and fx buttons stay on the first line while the field grows. Its
height is the content's laid-out line count (Alt+Enter or wrapped text)
times the font's row height, from one line (30 px, as before) to five,
then the field scrolls with the caret in view. This holds while editing
and while viewing a cell. The height eases over 120 ms when the line
count changes, and the chevron pins it at five lines (it used to give a
fixed 72 px). The in-cell editor likewise stops at five lines and
scrolls. formula_bar::BarLayout records where the parts went, for tests.

widgets::code_editor(ui, id, &mut text, Lang, max_lines) is a small
code editor for features that edit code: the monospace font, syntax
colours from Tokens::syntax (new, with light and dark values in the
contrast test) for Python (keywords, strings including triple-quoted
ones, numbers, comments and builtins) and LaTeX (commands, scripts and
comments), Tab inserting four spaces (or indenting every selected line,
Shift+Tab dedenting), Enter keeping the line's indentation (one level
more after a Python colon), and a scroll area that follows the caret.
The tokenizer and the edits are pure functions with tests, including
hostile input that must keep spans on char boundaries.

kittest (tests/formula_bar.rs) covers Alt+Enter up to eight lines with
the Name Box and buttons fixed and the caret visible, the commit,
viewing the committed cell, the chevron, the ease, the in-cell cap and
the code editor's Tab and Enter.

* UI: Shift+Tab in the code editor dedents instead of indenting

The editor consumed plain Tab before Shift+Tab, and egui's key match ignores Shift
when the pattern lacks it, so a Shift+Tab was taken as Tab and indented the line.
Shift+Tab is now consumed first; a plain Tab still inserts spaces.

* UI: the ribbon card stays inside a narrow window, so its right scroll arrow is on screen

The row above the ribbon can be wider than a narrow window, and the card took that width, so the
right scroll arrow was drawn past the window's edge and couldn't be clicked: below about 640 px on
macOS, and at 700 px with Linux's wider default fonts, where CI's ribbon test failed. The card is
now kept within the window with the same margin it has on the left.

* UI: each ribbon tab keeps a scroll offset of its own

The ribbon's scroll area used one identity for every tab, so scrolling an overflowing tab and
switching to another overflowing one hid that tab's first groups. Each tab now has its own scroll
state: a tab opened after another was scrolled starts at its left edge, and a tab keeps its offset
while others are used.

* UI: the in-cell editor keeps its whole width for the text and shows every line

Merged with main, the grid's own test asked the in-cell editor to wrap its
text at the field's full width and to show every line (the editor never
scrolls); the editor widget wrapped it inside the formula bar's scroll area,
which took the bar's width off the text (168 px tall where 156 was right),
and the grid capped it at five lines. The in-cell editor now shows the text
field on its own, through the one show_edit helper the formula bar also
uses, and grows with every line; the formula bar keeps its five lines and
its caret scroll. The branch's five-line test for the cell editor becomes a
grows-with-every-line test.

* Docs: the UI building blocks' revision rows carry the date they land

The rows said 2026-10-11, older than upstream rows above them, and the
ui-parity row said the in-cell editor is capped at five lines.

* UI: the formula bar's view of a cell starts at the cell's top

The bar's read-only view kept one scroll offset for every cell, so a cell
shown after scrolling another's text started scrolled. The offset is kept
per cell now.

* UI: the editor's field does nothing with Enter on its own

The editor handles Enter (commit) and Alt+Enter (a line break) itself, and a
message box over the editor takes Enter to close. The field under it is a
multi-line TextEdit since the bar grew, whose own return key would add a
line if it ever saw Enter; return_key(None) keeps that from depending on
where focus sits. A test shows Enter over a message box adds nothing to the
entry (focus is off the field then, so it passed before too: this is
hardening, not a repair). The doc comment split by the show_edit helper is
mended.

* Docs: ui-parity says the in-cell editor shows every line, and its revision table is whole

A sentence still said the in-cell editor stops at five lines, and a blank
line between the table's separator and its first row ended the table.

* UI: the split button's tooltip carries the shortcut hint like every ribbon button's

big_split_button built its tooltip with the bare translation, so AutoSum,
which became a split button, lost its shortcut hint. It uses tip_text now;
the split-button test hovers the button and looks for the hint.

* UI: a selection that ends at the start of a line leaves that line alone

Selecting "a\n" in "a\nb" and pressing Tab also indented b, and Shift+Tab
could take its indentation: the line after the selection was counted as
touched. It is touched only when the selection reaches into it.

* UI: the code editor applies its keys in input order, with the typing around them

The editor consumed Enter, Tab and Shift+Tab before the text field saw the
frame's events, so a frame carrying typed text followed by Enter (events
gather between repaints, and under key repeat) put the newline before the
text, and two Enters in one frame made one line. The editor now walks the
frame's events in order and applies typed text, pastes, Enter, Tab,
Shift+Tab, Backspace and Delete itself, taking them from the queue; the
first event it does not handle and everything after it stay for the field,
which runs next, so the order holds either way.

* UI: the code editor keeps the input order past the keys the text field handles

The editor applied its keys up to the first event it did not handle and
left that event and everything after it to the text field, which has
its own Tab and Enter: select all followed by Tab in one frame replaced
the code with a tab character, and since the platform sends a key event
before each text event, an Enter after ordinary typing lost its
indentation.

The editor now applies its keys up to the first event the field acts on
(a caret or selection key, a key under a command modifier, IME, a click);
that event and the run after it stay for the field; from the editor's
next key on, the keyboard events are held back under the editor's id for
its next pass, where it puts them ahead of that pass's input and splits
again. They go only to the editor they were typed into, only while it
still has the focus, and only in the pass right after; otherwise they
are dropped rather than typed into another widget. Printable key presses
do not split the stream. Tab under a command or option modifier is taken
off the queue, and Enter under Shift or Option is the editor's newline,
so the field never gets a Tab or an Enter of a focused editor.

* UI: the ribbon layout and formula bar tests join the crate's integration test binary

Since #2372 the crate's integration tests are one binary built from tests/it/, one module per file; only tests that set process-wide state stay separate. These two set none.

* UI: the formula bar's one-line height follows the font, so five lines fit on Windows

One line was a fixed 30 px and the bar grew by one row height per line.
The panel's and the field's margins take 12 px of that, and rounding to
the pixel grid up to another, so a row taller than 17 px lost the last
counted line: with the Windows UI font (17.28 px rows) five lines showed
four, and bar_grows_to_five_lines_then_scrolls_with_name_box_pinned
failed there.

formula_bar::one_line(row_h) is 30 px unless the rows need more, and
every counted line fits whatever the font. The kittest heights are
computed from it rather than from 30, and a unit test checks the
arithmetic for rows of 15.6 to 20 px.

* UI: Paste Special's OK button uses the on-accent colour

It was the one OK button still drawn white on the accent: 2.14:1 in the dark theme, where every other OK uses on_accent (7.1:1).
2026-10-24 20:54:34 -06:00

32 KiB
Raw Blame History

GridCraft roadmap

Stage: alpha · next: beta, ~25 points of "ready for real work" and ~160–240 h away

Last reviewed: 2026-10-11 · Last updated: 2026-10-23 · Change: minor (accounting negatives such as $(1,234) read as numbers; INDEX with one index on a 2-D reference is #REF! as in Excel; earlier: Page Setup paper sizes: JIS B4/B5/B6, the Japanese postcards and envelopes, and A6; long flat operator chains up to Excel's formula limit) · Target: Microsoft Excel (Microsoft 365)

GridCraft aims at full Microsoft Excel parity, and at being better in places: faster, open (XLSX is the native format), fully scriptable by agents (MCP, control channel, CLI), and on the web. This page is the summary. The detail is in:

Headline numbers

Number Value Kind
2026-10-14 Editing a cell with text that would read back as a number, boolean, date or formula (entered with a leading apostrophe) shows the apostrophe in the editor and formula bar, so Enter unchanged keeps it text (#1362)
Feature breadth (weighted) ~75% estimated, anchored on two measurements: ribbon catalog 274 / 290 (94.5%), worksheet functions 513 / 523 (98.1%; 504 working, 96.4%)
Ready for real work ~50% estimated from written weights (51.6); target-app-parity.md
Mainstream practitioner ~50% estimated: typical analyst/finance user, weekly features, × 0.90 interaction × 0.92 stability × 0.88 file exchange; method
Essentials user ~63% estimated: core features only, × 0.92 launch/stability × 0.95 clarity × 0.90 opening sent files; method
Remaining to beta ~160–240 Opus 5.5 agent-hours estimated; itemized in roadmap.md
Remaining to full parity ~700–1,100 Opus 5.5 agent-hours estimated; sum of the dimension rows below
Audience Ready % Opus 5.5 agent wall-clock hours to ~95% Work that dominates
Full target (ready for real work) ~50% ~650–1,050 Get & Transform and the data model, localization (twelve languages), charts depth, file fidelity (.xls, corpus, pass-through), PivotTables, collaboration, mobile
Mainstream practitioner ~50% ~200–310 File exchange with Excel users (corpus and Excel verification, pass-through, large files, .xls, encryption: 63–97 h), common-chart depth (30–45 h), PivotTables (20–30 h), keyboard and interaction (18–28 h), calc correctness and functions (20–33 h)
Essentials user ~63% ~60–100 Opening files people send (.xls import and saving with a password 24–36 h; macOS Finder open 2–4 h), launch stability (6–10 h), basic chart resize and polish (6–10 h), print and Page Layout (8–12 h), small editing and UI fixes (10–16 h)

Each tier is a subset of the one above, so its hours are too. Calibrated as in Effort and calibration (~6–10 h per readiness point for the remaining, verification-heavy work; single features measured from PRs #66, #100, #101). Parallelism: the full and mainstream work splits ~65–70% across 4–6 agents by area; the essentials work is mostly small fixes plus one long .xls track, so about half parallelizes (≈30–50 wall-clock hours with three agents).

Why alpha: all six core workflows in the alpha gate pass end to end on macOS with save and reopen, and the core workflow works end to end (open an XLSX, enter formulas and data, format, sort and filter, chart, pivot, print to PDF, save XLSX), but users still hit blocking gaps on real files: 100 MB workbooks don't open (#175), there's no .xls (#121), Arabic and Devanagari text isn't shaped (Chinese text still reported in #142), charts lose their type and options on round trip, and nobody has yet confirmed that Excel opens our output without a repair prompt across a real corpus. Beta needs those closed (see beta gates).

The 2026-10-07 numbers (catalog 89%, "feature depth ~65%", "~215 h to full parity") were re-measured. Catalog and function counts held or rose; the depth and hours moved because of new evidence: 82 issues filed by users and contributors in the repo's first five days, and scope the old estimate left out (localization, legacy .xls, Power Query and the data model, collaboration, mobile, AI).

By dimension

Dimension Ready for real work Hours to parity Doc
Features (13 areas, table below) ~59% (breadth ~75%) 300–485 target-app-parity.md
UI/UX fidelity ~55% 50–80 ui-parity.md
File formats ~50% 80–120 file-format-parity.md
Performance ~35% 35–55 target-app-parity.md
Stability ~60% 15–25 gaps.md
Localization ~10% (ribbon in 6 languages) 100–165 localization-parity.md
Hardware (multi-core calc, GPU, pen, multi-window) ~40% 25–40 hardware-parity.md
Platforms ~80% (no iOS/Android; ahead on Linux, BSD, RISC-V) 30–60 target-app-parity.md
Ecosystem / add-ins ~10% (VBA out of scope; own scripts, MCP, CLI) 25–40 target-app-parity.md
AI features ~15% (agent control strong; no in-app assistant) 30–50 target-app-parity.md
Total ~50% ~700–1,100

Features

Area Breadth Ready Hours Doc
Formula language and calculation ~92% ~72% 20–30 target-app-parity.md
Worksheet functions 96.6% measured ~82% 16–26 function-parity.md
Editing, navigation, clipboard, fill ~90% ~70% 15–25 ui-parity.md
Cell formatting, styles, conditional formatting ~95% ~80% 8–14 target-app-parity.md
Sort, filter, tables, validation, outline ~82% ~70% 10–16 target-app-parity.md
PivotTables ~65% ~45% 25–40 target-app-parity.md
Charts and sparklines ~50% ~30% 40–60 chart-parity.md
Page layout, print, PDF ~80% ~55% 12–20 target-app-parity.md
What-if and analysis (Goal Seek, Solver, ToolPak, Forecast) ~50% ~40% 22–35 target-app-parity.md
Get & Transform, external data, data model ~15% ~10% 60–100 target-app-parity.md
Insert objects (pictures, shapes, ink, SmartArt, equations) ~55% ~45% 25–40 target-app-parity.md
Review, comments, protection, collaboration ~55% ~40% 35–55 target-app-parity.md
Automation (recorded scripts; no VBA) ~30% ~20% 12–20 target-app-parity.md

Languages

The ribbon is translated into Japanese, Simplified Chinese, Korean, Brazilian Portuguese, Russian and German (266–268 labels each, ~12% of ~2,200 strings; merged 10-10 in #31, #104, #82, German added 10-11), the interface follows the system language, and CJK, Thai and Hebrew text falls back to system fonts (#38). Japanese (10-17) and Brazilian Portuguese also translate the dialog titles and labels, message boxes, Backstage/File-view items, template names and native menus: 943 strings each, ~43%. The remaining dialogs, menus and messages are English; formulas and number formats are en-US only. Localized German formulas and numbers are in PR #163. Detail: localization-parity.md.

Language Code Status UI strings
English en full (source language) 100%
Simplified Chinese zh-Hans menus only ~12%
Spanish es none 0%
Hindi hi none 0%
Arabic ar none (no RTL layout, no shaping) 0%
French fr none 0%
Portuguese pt-BR menus, File view, dialogs ~43%
Indonesian id none 0%
Japanese ja menus, File view, dialogs, messages ~43%
German de menus only ~12%
Korean ko menus only ~12%
Vietnamese vi none 0%

Other shipped languages: 3 (Russian and German, menus only, ~12%; Dutch, menus, File view and dialog titles, ~24%).

Upcoming

Ranked; estimates in Opus 5.5 agent-hours. Detail and the full beta-gate list in docs/roadmap.md.

  1. Land the open PR queue (50 open PRs on 2026-10-10, many fixing listed gaps: recalc and spill correctness, chart kind round-trip, CJK font fallback, macOS Finder open, German and Chinese UI). Review and merge: 8–15 h.
  2. XLSX fidelity on a real-world corpus, with Excel opening our output without repair: 25–35 h.
  3. Large workbooks and recalc speed: 100 MB XLSX, 1M rows, multi-threaded recalc: 40–60 h.
  4. Charts depth: kinds and options round-trip, axes, trendlines, error bars: 25–35 h.
  5. Text in every script (CJK, Thai, Arabic, Devanagari) in cells and PDF: 12–20 h.
  6. Legacy .xls import and password-protected workbooks: 20–30 h.
  7. Localization: extend the catalog past the ribbon, then the twelve languages: 100–165 h.

Progress log

Date What landed
2026-10-23 Accounting negatives in text: $(1,234), $ (5) and (5)% read as negative numbers when typed, coerced by arithmetic or passed to VALUE, like Excel 365; (-5), ((5)), $5% and dates or times in parentheses stay text
2026-10-23 Calc: INDEX(A1:C3,2) (one index on a reference of several rows and columns) is #REF! as in Excel, instead of the whole row; INDEX(A1:C3,2,) still gives the row
2026-10-22 Formula hardening: digits too many for a finite number are text, so "1 <400 digits>/<400 digits>" no longer coerces to NaN; a NaN column index in VLOOKUP, HLOOKUP and the D-functions is #VALUE! instead of an index underflow; REGEXREPLACE stops building a result as soon as it can only be too long (a worst case went from 1 GB to 7 MB) (#2163, #2162)
2026-10-21 Page Setup paper sizes match Japanese Excel: B4/B5/B6 are the JIS sizes (ISO B4/B5/B6 stay reachable by name), so a Japanese B5 worksheet prints at 182×257 mm; Japanese Postcard (100×148 mm), Double Postcard (148×200 mm), Envelope #3/#4 (120×235/90×205 mm), Kaku #2/#3 (240×332/216×277 mm) and A6 are added, both sizes reach the PDF page (file.exportPdf/file.print MediaBox) and the size survives an XLSX round-trip; the Page Layout Size menu lists them. B4/B5 used to be the ISO sizes, which is changed here
2026-10-20 Japanese interface catalog covers every key the Brazilian Portuguese catalog translates: the 398-label shared core plus 545 dialog, message, Backstage and menu strings (943 total, ~43% of ~2,200). A test parses pt.rs's source, so the two catalogs stay in step
2026-10-20 Interface translated into Dutch (518 labels: ribbon, context menus, File view, dialog titles, Options); nl, nl-NL, nl-BE locale tags resolve to Dutch
2026-10-19 Long flat operator chains (=A1+A2+…) up to Excel's 8,192-character limit (4,096 operands): entering, filling, inserting rows, undo, Evaluate Formula and XLSX save no longer overflow the stack; chains past 64 operands are saved as plain formulas, not dynamic arrays; Spanish formula entry accepts chains past 256 operands (#916)
2026-10-19 Linux: "Use system setting" for the theme keeps following the desktop when the XDG Desktop Portal stops answering: each read gives up after 2 s and the next poll reconnects, where one unanswered call stalled the watcher for the rest of the session
2026-10-16 Memory: undo steps share a sheet's picture bytes and the workbook's VBA project instead of copying them: 50 edits on a sheet with a 20 MB picture keep 22 MB instead of 992 MB
2026-10-16 Memory: floating pictures are decoded at about the size they are drawn, with limits, into a cache bounded by bytes and dropped with their workbook, instead of at full size into one that never let go; two open workbooks no longer show each other's picture. 12 large pictures scrolled through keep 40 MB of textures instead of 258 MB, and none once the workbook closes
2026-10-16 The web app keeps its preferences between visits (#1562): theme (dark mode), interface size, language, editing options and the rest of what the desktop app saves in ui.json and prefs.json are kept in the browser's localStorage, written as soon as they change
2026-10-16 Memory: the interface and script fallback fonts are read once per run and shared with egui instead of copied into it: an empty workbook settles at 158 MB instead of 258 MB on macOS
2026-10-15 Function help follows the interface language: argument hints, autocomplete, Insert Function (search and readable categories) and the Formulas-tab menus read per-language tables of descriptions and argument names; Spanish keeps its 10 functions in the new format
2026-10-15 Row auto-fit counts a cell's line breaks only when the cell wraps, as Excel does: a file whose unwrapped cells hold multi-line text no longer opens with tall rows (typing a break still turns wrap on and grows the row)
2026-10-14 Lookups (MATCH, XMATCH, VLOOKUP, HLOOKUP, XLOOKUP, LOOKUP) compare numbers exactly like Excel, so a computed key such as =0.1+0.2 no longer finds 0.3; = and COUNTIF/SUMIF keep their 15-digit comparison
2026-10-14 Functions: EOMONTH, EDATE, WORKDAY, NETWORKDAYS, YEARFRAC, WEEKNUM, the bond and coupon functions, DISC, BIN2DEC, IM* and the other Analysis ToolPak functions give #VALUE! for a reference to more than one cell in a value argument, as Excel 365 does, instead of spilling; array constants and computed arrays still lift
2026-10-14 Protect Sheet on a protected sheet: Home › Format, its keytips (HOP, RPS) and the tab menu now read Unprotect Sheet… and unprotect (straight away without a password); a protected sheet that forbids selecting locked (or unlocked) cells is enforced for clicks, arrows and Go To, and the Protect Sheet dialog has the select options (#1346)
2026-10-14 XLSX: formulas opened with dynamic-array metadata (cm) keep it on save, with xl/metadata.xml. Before, a formula returning one value lost it (11 of 40 corpus files that have the part lost it entirely), and Excel recalculated some of them with implicit intersection (SUMPRODUCT(IFERROR(...)) changed value)
2026-10-14 Recalculation: a dynamic array's anchor given a new formula that reads its old spill area (A1 was =SEQUENCE(3), becomes =SUM(A2:A3)+1 or =SEQUENCE(1,A2+1)) sees that area empty instead of the old values
2026-10-14 Recalculation: when two arrays of one recalculation want the same empty cells, the formulas that read the one laid out second (at its anchor or over the cells it would have spilled into) read #SPILL! and empty cells instead of its values
2026-10-14 Border keytips: each Alt, H, B letter applies the preset Excel's Borders menu gives it (H,B,O bottom, H,B,B bottom double, H,B,N no border, H,B,A all borders and the rest); they all drew a bottom border before. H,B,M opens Format Cells on the Border tab
2026-10-13 Formula-entry Command/Ctrl-click inserts another reference with the locale's argument separator; Shift-click extends from a stable, sheet-aware anchor. Pointer tests cover repeated clicks, reversed ranges, ordinary replacement, typed separators, Spanish syntax, sheet switches and keyboard continuation. Readiness estimates unchanged.
2026-10-13 formulas.evaluate (gridcraft-cli eval, MCP evaluate_formula) refuses what entering the formula in a cell refuses, with the reason (=SUM(1;2): "expected , or )"), instead of #NAME? for any formula that doesn't parse
2026-10-13 Colour menus: Fill Color, Font Color and the Format Cells pickers end with Recent Colors (the last ten custom colours) and More Colors… (hue/saturation area, RGB, hex box, preview, OK/Cancel) (#928)
2026-10-13 Multi-level category axes: a category range two or more columns wide beside a column of values (year beside month, Excel's multiLvlStrRef) draws its innermost labels across the plot and the outer levels in rows under them with group separators (columns beside the labels in bar charts), instead of flattening the two columns into twice as many categories; saving writes the reference back as multiLvlStrRef with Excel's level caches, so the axis survives a round trip
2026-10-13 Charts: a huge trendline forecast no longer collapses the chart: on a category axis it adds at most four times the data in empty slots (at least 32), the line is sampled over the plot only, and forecasts read from XLSX or set by command are clamped, NaN and infinity becoming 0 (#1148)
2026-10-13 XLSX export writes a picture used on several sheets once, as one xl/media part every drawing points to (it wrote a copy per drawing: a 16-sheet workbook with one 112 KB logo grew from 0.4 to 1.9 MB) (#985)
2026-10-13 XLSX: [Content_Types].xml, _rels/.rels, the workbook rels and xl/workbook.xml are the first zip entries (document properties last), so libmagic and PHP finfo detect the file type even with large properties (#1090)
2026-10-13 Conditional formatting: a rule gathers range statistics only when it reads them (top/bottom, above average, duplicates, scales, bars, icons) and borrows them instead of copying them per cell, so the per-frame lookup of an expression or cell-value rule no longer visits its whole range (#1098, part 1)
2026-10-12 Next/previous sheet navigation stops at the first/last visible worksheet instead of activating a hidden boundary sheet; the current selection is retained
2026-10-12 Rows auto-fit oversized fonts: opening a file and whole-row/column formatting grow non-custom rows to their tallest font (#833)
2026-10-12 Number formats: parsing a format code is linear in its length (long runs of [, , or / no longer take quadratic time), and an unclosed [ is a literal when splitting sections as well as when tokenizing (#810)
2026-10-12 Number formats: a fraction denominator with 65,536 zeros no longer crashes; format codes are capped at 255 characters like Excel (longer codes display as General, TEXT gives #VALUE!) (#807)
2026-10-12 Security: cell hyperlinks open only http, https and mailto, after a confirmation; other schemes (file:, smb:, UNC, custom handlers) are refused (#777, part 1)
2026-10-12 Deleting several Ctrl-selected rows or columns removes them all in one undo step (#758)
2026-10-12 XLSX chart sheets are kept on open and save: the sheet, its drawing and chart (with style and colours) are written back unchanged in their place among the worksheets, and left out when the sheet they plot is deleted or renamed or a worksheet took their name (#727)
2026-10-12 CSV and tab-separated export is capped at 512 MiB: a sheet whose used range would expand to more (two cells far apart, such as A1 and XFD1048576, are 16 GiB of commas) is refused with the rows, columns and limit, before anything is allocated or written (#528)
2026-10-12 PDF writer hardening: text width cannot overflow, all-zero dash arrays and negative or NaN stroke widths are sanitised, non-finite sizes and positions draw nothing (#812)
2026-10-12 PDF export writes the document title and author as UTF-16BE when they are not ASCII, so viewers show accents, currency signs and non-Latin text correctly (#813)
2026-10-12 TEXT() over a range and chart labels parse each number format code once instead of once per value (#806)
2026-10-12 SUBTOTAL(109) over hidden rows recalculates after Row Height, AutoFit Row Height and Ungroup reveal rows (found by the command-sequence fuzz)
2026-10-12 Page Layout view: drag the margin edges on the rulers to set the page margins (resize cursor, live preview, value tooltip, one undo step, Esc cancels) (#792)
2026-10-12 Forecast Sheet gets Forecast Start: begin the forecast inside the history to compare it with the actuals (#785)
2026-10-12 Ink strokes save as unfilled DrawingML paths and reopen as editable ink with their points, colour and width; icons in #551 remain a follow-up
2026-10-12 The selection outline stays visible when extended to the last row (Ctrl+Shift+Down): its sides are cut to the viewport instead of stroking a 20-million-point rectangle (#687)
2026-10-12 File › Print selects a system printer, copies, duplex and grayscale, submits PDF jobs through craft-print on a worker and shows spooler errors; browser printing and PDF export remain available
2026-10-11 UI building blocks: theme tokens with a WCAG contrast test over both themes (icons and reference colours follow dark mode); ribbon scroll arrows and a large split button (Formulas › AutoSum opens its menu); the formula bar grows from one to five lines, then scrolls; a code editor widget with Python and LaTeX colouring
2026-10-11 Command-sequence fuzzing: random command sequences checked against undo/redo, XLSX round-trip and full recalculation; fixes for the table, legacy-array, spill, AutoSum, Watch Window and sheet-copy bugs it found
2026-10-11 Password-protected workbooks open: GridCraft asks for the password and decrypts Agile and Standard encryption (#11)
2026-10-11 Text boxes keep their formatting: run size, bold, italic, typeface, text colour and outline, alignment, vertical anchor and "no outline" (#377)
2026-10-11 Desktop printing opens the print PDF in the system viewer; Save As offers CSV, web page and PDF; macOS File › Properties opens File › Info (#370, #343)
2026-10-11 Windows: DirectX 12 shaders compile with FXC, so a missing or stray dxcompiler.dll no longer stops the app at start (#339, #354)
2026-10-11 Merged cells draw their whole outline: right and bottom edges come from the last column's and last row's cells (#376)
2026-10-11 Shrink to fit draws too-wide text and numbers in a smaller font inside the cell or merged area (#375)
2026-10-11 Shift+Space and Ctrl+Space select the row / column without starting an edit; Control+Space on Mac (#338)
2026-10-11 Workbooks reopen at their saved scroll position (topLeftCell, also with frozen panes) and save the current one back (#378)
2026-10-11 Protect Sheet passwords use Excel-compatible hashes and round-trip in XLSX sheetProtection (imported passwords verify instead of being dropped)
2026-10-11 Review › Protect Workbook opens a dialog with an optional password (Excel-compatible hash, kept in XLSX workbookProtection); unprotecting verifies it (#345)
2026-10-11 Formula bar, name box and dialogs fall back to the cell font: Hebrew (and any script cells can show) no longer turns into boxes there (#349)
2026-10-11 Headers and footers: first-page and odd/even variants are read, kept, printed and edited in Page Layout view; Insert › Header & Footer edits the header in place (#344)
2026-10-11 Legacy Excel 97-2003 .xls (BIFF8) import with formulas, number formats, merges, sizes and names (#121)
2026-10-11 XLSX pass-through: custom XML, external links, connections, query tables, printer settings, form/ActiveX controls and OLE objects are kept on save (#330, #324)
2026-10-11 Data › Forecast › Forecast Sheet: a new sheet with the history, FORECAST.ETS forecast, confidence bounds, statistics and a chart (#322)
2026-10-11 Startup no longer panics on a system font egui can't parse: fonts are validated and skipped (#226)
2026-10-11 Ctrl+drag on the fill handle swaps copying and extending a series (#264)
2026-10-11 Odd-period bond functions ODDFPRICE, ODDFYIELD, ODDLPRICE, ODDLYIELD: Financial 55 / 55 (#275)
2026-10-11 PERCENTOF and EUROCONVERT worksheet functions (#279)
2026-10-11 BAHTTEXT: amounts in Thai words with Baht and Satang (#291)
2026-10-11 TRIMRANGE: ranges and arrays without blank outer rows and columns (#296)
2026-10-11 Selected charts, pictures and shapes can be deleted from the keyboard (#213)
2026-10-11 Ribbon translated into German (266 labels; de, de-DE, de-AT, de-CH locale tags resolve to German)
2026-10-11 View › Interface size: a saved 75–200 % scale for the whole window (#230)
2026-10-11 View › Formula Bar and Zoom 100% reachable from the CLI and MCP (#289)
2026-10-11 Freeze panes by dragging the freeze handles on the header edges (#195)
2026-10-11 XLSX: threaded comments (replies, resolved, timestamps) and note visibility survive a save (#300)
2026-10-11 Cell checkboxes: Insert › Checkbox on the ribbon, Excel's Delete and value rules, XLSX round trip as Excel cell controls (#196)
2026-10-11 Review › Allow Edit Ranges with Excel-compatible password hashes, kept in XLSX (#307)
2026-10-11 PivotTable calculated fields (pivot.calculatedField), evaluated on sums like Excel, with XLSX round-trip (#304)
2026-10-11 PivotCharts (insert.pivotChart): charts bound to a PivotTable's report, following refreshes and layout changes (#311)
2026-10-11 FORECAST.ETS, FORECAST.ETS.CONFINT, FORECAST.ETS.SEASONALITY, FORECAST.ETS.STAT: AAA exponential smoothing forecasts (#314)
2026-10-11 File tab Backstage view (Home, New, Open, Info, Save As, Print preview, Export, Options) and file.options (#174)
2026-10-10 Ribbon translated into Japanese, Chinese, Korean, Brazilian Portuguese and Russian with system-language default (#31, #104, #82); CJK/Thai/Hebrew font fallback (#38); clear messages for encrypted and .xls files (#17); smooth line charts (#62). Progress docs restructured to the craftrules standard; full re-measure (this page). Initial ribbon key tips (#43), in-place text box editing (#84), copy as HTML table (#36). ODS and XLSB data import (#100, #101); recalc linear in the number of range formulas (#66); RISC-V Linux build; Flatpak repository on Pages; web cell-commit trap fixed
2026-10-09 Community fixes: spill range operator A1#, sheet-scoped names, protection refuses locked-cell edits, Insert/Delete Cells adjust references, DATE(1900,2,29), SUMIF sizing, ROUND at 15 digits, _xlpm. LAMBDA parameters in XLSX, vertical scrollbar, system appearance, border previews; v0.4.0
2026-10-08 v0.2.0 and v0.3.0 releases; Flatpak, AppImage zsync, branded DMG; desktop log file; DirectX 12 default on Windows
2026-10-07 About window with contributor and model credits; macOS release runner
2026-10-06 M0–M13 first pass: engine, 478 functions, XLSX/CSV, egui UI, charts, PivotTables with XLSX round-trip, PDF and printing, what-if, spelling, Draw, task panes, MCP, CLI, web build, release packaging
2026-10-05 Repository created

Revision history

Date Change Summary
2026-10-23 minor Progress log: accounting negatives in number text
2026-10-23 minor Progress log: INDEX with one index on a 2-D reference is #REF!
2026-10-22 trivial Progress log: formula hardening (#2163, #2162)
2026-10-21 minor Page Setup paper sizes: JIS B4/B5/B6 (ISO by name), Japanese postcards and envelopes, A6; PDF page size follows, XLSX round-trips
2026-10-20 minor Dutch (nl) listed under other shipped languages; progress log row
2026-10-19 minor Progress log: long flat operator chains (#916)
2026-10-19 trivial Progress log: desktop theme portal read timeout
2026-10-16 minor Progress log: undo steps share picture and macro bytes
2026-10-16 minor Progress log: floating pictures' textures bounded and kept per workbook
2026-10-16 trivial Progress log: web preferences kept between visits (#1562)
2026-10-16 minor Progress log: interface fonts held once instead of twice
2026-10-14 minor Progress log: lookups compare numbers exactly
2026-10-14 minor Progress log: Analysis ToolPak value arguments reject multi-cell references
2026-10-14 minor XLSX dynamic-array cm metadata kept on save; progress log row
2026-10-14 minor Progress log: spill anchor reading its old spill area
2026-10-14 minor Progress log: formulas reading an array that loses a spill conflict
2026-10-13 trivial Progress log: More Colors… and Recent Colors in the colour menus (#928)
2026-10-13 minor Multi-level category axes (read, drawn, written); progress log row
2026-10-13 trivial Progress log: shared pictures written once on XLSX export (#985)
2026-10-13 minor Progress log: conditional-format lookups no longer scan the range for rules without statistics (#1098)
2026-10-12 minor Progress log: hidden-sheet navigation at workbook boundaries
2026-10-12 minor Rows auto-fit oversized fonts on open and whole-row/column formatting (#833); progress log row
2026-10-12 minor Progress log: multi-area row/column delete (#758)
2026-10-12 trivial Progress log: XLSX chart sheets kept on save (#727)
2026-10-12 trivial Progress log: CSV export size cap (#528)
2026-10-12 minor Progress log: margins dragged on the Page Layout rulers (#792)
2026-10-12 minor Ink preservation across XLSX save/reopen (ink portion of #551)
2026-10-12 minor Desktop File > Print now discovers printers and submits PDF jobs through pinned craft-print with printer choice, copies, duplex and grayscale; browser printing and PDF export remain available. Remaining print parity includes page ranges and driver-specific tray/options UI; physical printer fidelity needs hardware validation.
2026-10-11 minor UI building blocks; progress log row
2026-10-11 minor Password-encrypted workbooks open (#11); progress log row
2026-10-11 minor Forecast Sheet (#322); progress log row
2026-10-11 minor Worksheet functions 505 / 523 (ODD* bond functions); progress log row
2026-10-11 minor Worksheet functions 503 / 523 (PERCENTOF, EUROCONVERT); progress log row
2026-10-11 minor Worksheet functions 502 / 523 (BAHTTEXT); progress log row
2026-10-11 minor Worksheet functions 502 / 523 (TRIMRANGE); progress log row
2026-10-11 minor Selected objects can be deleted from the keyboard (#213)
2026-10-11 minor Catalog 258 → 260 / 290: View › Formula Bar and Zoom 100% (#289)
2026-10-11 minor Progress log: XLSX threaded comments round trip (#300)
2026-10-11 minor Catalog 258 → 259 / 290: Allow Edit Ranges (#307)
2026-10-11 minor Worksheet functions 505 / 523 (FORECAST.ETS family); progress log row
2026-10-11 minor Czech (cs) listed under other shipped languages: ribbon only, ~12%
2026-10-10 minor Readiness-by-audience table with hours to ~95% per audience; full number unchanged (additive weighted sum)
2026-10-10 minor Added Mainstream practitioner (~50%) and Essentials user (~63%); languages updated for the 10-10 merges (ribbon in ja, zh, ko, pt-BR, ru); localization 5%→10%; full number re-checked (51.6, unchanged)
2026-10-10 minor Checked against the alpha gate (six core workflows pass): stays alpha
2026-10-10 major Re-measured against Excel for Mac 16.113.4: stage alpha, breadth ~75%, ready ~50%, ~160–240 h to beta, ~700–1,100 h to full parity; restructured to the progress-docs standard; detail moved to docs/
2026-10-07 major First estimates: catalog 89%, functions ~93%, depth ~65%, ~35 h to alpha, ~215 h to full parity