Skip to content

linexcel 1.9.0

Choose a tag to compare

@github-actions github-actions released this 13 Sep 16:00
· 69 commits to main since this release

[1.9.0] — 2026-09-13

Added

  • Analysis resource ceilings can be configured through both public APIs.
    Validated limits are recorded in metadata and propagated to workbook loading,
    graph construction, recovery and external workbook reads. A targeted closure
    that exceeds its cell budget is rejected rather than silently truncated.

  • AI dossiers retain source name definitions and worksheet scope, including
    constants absent from reference-only graph nodes. Group values identify their
    representative cell, and literal AGGREGATE selectors have deterministic
    meanings. Oversized or locally scoped evidence is explicitly qualified.

  • Small-screen graph options have a dedicated keyboard-accessible dialog.
    Views stay visible while filters and layout remain reachable without covering
    nodes with a permanent legend.

  • Graph navigation uses a dedicated responsive toolbar with a labeled sheet
    selector, grouped zoom controls and a live zoom percentage, and explicit
    framing actions. Search has a visible submit action and describes its scope.

  • Local acceptance runs include both fixtures, screenshots and image analysis
    with Ollama by default.
    Each run keeps separate artifacts and a manifest
    with source/input/image hashes and per-language coverage. Partial runs and
    failed stages return a nonzero status. Contributor instructions require
    inspecting dashboard tabs, sampled nodes and AI claims against screenshots.

  • CI and documentation checks cover stacked PRs targeting codex/** branches,
    so dependent improvements are validated before their base PR reaches main.

  • The node panel can frame a node with its direct neighbors. The action
    remains accessible on mobile, where the panel leaves the graph controls
    visible. Search returns to the graph from the other dashboard tabs.

  • --target SHEET!A1 limits the analysis to the cells feeding the named
    cell.
    Repeatable, and several comma-separated cells fit in one flag; the
    library spelling is analyze(..., targets=["Sheet1!A1"]). The engine boots
    without the global evaluate_all, the upstream subgraph of the targets is
    traced (Workbook.trace) and evaluated (evaluate_cells), and its lineage
    is built with relevant defined names, VBA and Power Query context. Dynamic
    references (INDIRECT/OFFSET) or a truncated trace can cause dependencies
    to be evaluated without appearing in the graph; the report states this
    limitation. Without --target the whole workbook is evaluated, as before.

  • A warning now flags workbooks of long dependency chains. On a targeted
    run it is exact — the engine's evaluation plan (get_eval_plan) counts the
    layers of the subgraph before it is evaluated. On a full run the plan reads
    zero once everything is computed, so the measure is taken from the lineage
    itself: the longest precedent→dependent path across formula nodes, and the
    largest self-referencing group (a running-total column is one node on the
    graph but a chain as deep as it is long). Either way it is a risk
    indicator, not a duration estimate.

  • The viewer uses readable card nodes and zoom-aware labels, offers a
    differences-only filter, and initially uses flow layout for larger graphs.
    The layout choice remains available in the toolbar.

  • Browser regression tests run in CI, exercising filters, search, dense
    selections, and desktop/mobile controls in light and dark themes.

Fixed

  • Cache ceilings also apply to error overlays and styled empty columns.
    Recovery that runs out of depth does not publish an incomplete scratch result.

  • Scratch markers are unique per operation, avoiding collisions with valid
    formula results that happen to equal a former fixed marker.

  • Optional documentation parsing rejects structurally complex formulas before
    entering the native AST conversion
    , and local LET/LAMBDA bindings are not
    mistaken for workbook name references.

  • Visual preview is hidden when its content is already available in Sheets.
    Standalone image pages and descriptions without sheet context remain reachable.

  • Search feedback is cleared when the query or graph filters change.
    Searches with no matches also clear the previous selection.

  • Inline code in AI documentation preserves formula operators. Markdown
    emphasis no longer consumes multiplication signs inside code spans.

  • Empty or truncated AI responses no longer become successful documents.
    Failed calls retain their reported token usage; oversized formulas are
    explicitly omitted from bounded dossiers rather than passed as partial proof.

  • Legacy NORMSDIST and NORMDIST formulas evaluate through their native
    modern equivalents
    , preserving original formulas, coercion and error values.

  • Local LET and LAMBDA steps are not evaluated outside their scope.
    The complete calculation retains its value; unavailable inner steps state
    that local scope prevents independent evaluation.

  • Screenshot descriptions retain their image identity after HTML embedding.
    Pages without sheet context remain accessible, chartsheets preserve page
    ordering, and images can be inspected at native resolution in the viewer.

  • Narrow documentation tables preserve whole words and scroll horizontally.
    Group cards show their member count once, keeping the underlying label intact.

  • 1904 workbooks use their calendar during engine import. Formatted date
    inputs, date functions and targeted evaluation no longer inherit a 1,462-day
    shift from the engine's default 1900 calendar.

  • Circular calculations honor workbook iteration settings. Non-converged
    components and their dependents retain file caches and omit unverifiable
    breakdowns; independent formulas remain calculable. Convergence is qualified
    by the engine's criteria and does not imply a unique fixed point.

  • Self-closing XML cells cannot capture a following cell's formula. The
    quarantine scan no longer backtracks quadratically over styled empty cells.

  • AI dossiers preserve engine identity, value provenance and uncertainty. Cached or volatile
    snapshots are not labeled recalculated, disagreements and omitted neighbors
    are explicit, and useful calculation steps are retained before extra neighbor
    examples. Prompts in all nine languages reject unsupported explanations of
    discrepancies and extrapolations across sparse groups. Vision descriptions
    and overviews are labeled for checking against the original evidence.

  • Viewer Markdown handles nested lists and inline formatting in headings.
    Spreadsheet errors and unevaluated steps no longer use the successful-result
    style. Sheet context displays extraction warnings and unknown dimensions.

  • Excel time caches compare correctly with numeric day fractions. Midnight
    (0) and noon (0.5) agree with stored time values without converting plain
    text, booleans, multi-day durations or timezone-bearing values into times.
    The graph retains the numeric reading and carries its ISO time in valueDate.

  • Quarantined formulas keep honest value provenance. A stored result is
    attributed to the file, and a missing result is not treated as zero. When a
    deep formula has no cache, dependent calculations and their breakdowns remain
    uncomputed, including IFERROR/ISERROR and dynamic references. Independent
    formulas still evaluate when their independence can be established.

  • An engine rebuild preserves the deep-formula quarantine instead of
    restoring formulas that could overflow the evaluator's stack.

  • Targeted formula scans read only traced cells. Sparse targets no longer
    consume the sheet scan limit on intervening empty rows or columns, and
    unrelated defined names no longer trigger out-of-scope recalculation.

  • Long chains across distinct formula groups are detected. The previous
    traversal skipped every root; the replacement visits each node and edge once
    and handles cycles without recursion.

  • Targets support quoted sheet names containing commas and escaped quotes.
    Malformed or empty target entries fail with an actionable error.

  • Boolean and mixed-type disagreements are no longer reported as agreement.
    Numeric tolerance, equivalent date representations and Excel error values
    retain their comparison semantics; recalculated errors over stored numbers
    are differences.

  • Sheet, type and difference filters compose correctly. Searching only
    matches visible nodes, so hidden results are not selected or centered.

  • Group comparison keeps the representative cell's verdict separate from
    the worst sampled verdict.
    The difference filter includes a group when a
    sampled cell differs without falsely labeling an agreeing representative.

  • Disconnected graphs use a compact grid in flow mode, avoiding a tall
    single rank of nearly invisible cards when hundreds of nodes have no links.

Performance

  • Large sheet previews use streaming reads. Above 20 MiB of worksheet XML,
    report context avoids materializing the entire openpyxl worksheet. Omitted
    comments and layout metadata are explicitly reported; previews still work
    when worksheet dimensions are absent.
  • Batch documentation indexes graph adjacency once, instead of scanning
    every node and edge again for each requested card.
  • Formula-free XML sheets skip the quarantine scan. CLI size estimates
    describe worksheet XML rather than incorrectly calling it formula volume.
  • Selecting many search results no longer scans the whole graph per result.
    Selection updates are coalesced into one animation frame, and the selection
    collection is assembled in one pass.

Changed

  • formualizer 0.9.3 is the minimum supported engine. Parallel evaluation is
    configured explicitly and can be disabled through boot_engine(parallel=False).
  • Chartsheets are skipped with a warning so their presence does not prevent
    worksheet analysis. Over-deep formulas are quarantined before evaluation to
    avoid an evaluator stack overflow.
  • A failed quarantine retry no longer pays a third from_bytes. The
    rebuild existed because a failed evaluate_all was believed to leave the
    engine reporting no formula at all; on formualizer 0.9.3 the formula map
    survives the failure, so the engine the run already holds is kept (with the
    quarantined cells re-injected by the sweep) and the rebuild is paid only
    when a probe of one formula cell finds the map really is gone.