Skip to content

feat(x): local spreadsheet create/edit tools + in-app read-only viewer - #843

Open
hrsvrn wants to merge 4 commits into
mainfrom
feat/spreadsheet-tools-and-viewer
Open

feat(x): local spreadsheet create/edit tools + in-app read-only viewer#843
hrsvrn wants to merge 4 commits into
mainfrom
feat/spreadsheet-tools-and-viewer

Conversation

@hrsvrn

@hrsvrn hrsvrn commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

What this does

Rowboat could only read spreadsheets (parseFile → CSV text) and clicking a spreadsheet file card kicked you out to the OS app. This PR adds assistant-driven editing of local spreadsheets plus a read-only in-app viewer that opens and refreshes automatically as the assistant works.

New builtin tools

  • spreadsheet-create — create .xlsx/.csv workbooks from row data (multi-sheet for xlsx, single-sheet enforced for CSV), with an overwrite guard.
  • spreadsheet-edit — an ops array applied in one atomic write: setCells (A1 → value map), setRange, appendRows, clearRange, addSheet, removeSheet, renameSheet. Sheet ops on CSV return a clear error.

Both are file-boundary gated (same permission flow as the other file-writing tools) and return an error envelope instead of throwing.

Core

  • New shared module packages/core/src/spreadsheet/ used by both the tools and the viewer IPC: SheetJS loaded via the dynamic-import pattern so esbuild can't inline it, etag-guarded read-modify-write for conflict detection, a single-entry parse cache, a 50 MB parse cap, and windowed sheet reads.
  • files.writeBuffer — binary sibling of writeText (atomic temp+rename, file lock, etag support).

Viewer

  • SpreadsheetFileViewer renders .xlsx/.xls/.csv/.tsv as a grid: sticky A/B/C column headers and row numbers, sheet tabs, 500-row pages with a pager, 100-column cap with a notice, and an "Open in system app" escape hatch (also the error fallback).
  • Data goes over a new windowed spreadsheet:load IPC channel — never the whole workbook.
  • Spreadsheet file cards in chat now open the viewer in-app (absolute paths inside the workspace are resolved; paths outside still open the OS app).
  • The viewer auto-opens when the assistant creates/edits a spreadsheet and refreshes in place via a window event dispatched from the tool-result interception (the workspace watcher only covers allowlisted roots, so workspace:didChange alone isn't enough) plus workspace:didChange where it does fire.

Known v1 limits

  • SheetJS community edition drops cell styles when writing an edited workbook (content is preserved; noted in the tool descriptions).
  • Cell values are literals — no formula authoring yet.
  • External-app edits outside watched roots refresh on reopen, not live.

Testing

  • 14 new vitest cases (spreadsheet.test.ts, files.test.ts): xlsx/CSV roundtrips incl. quoting, every op, empty-sheet append, etag conflict + cache behavior, window slicing boundaries, CSV sheet-op rejection.
  • Catalog key-order test and gated-permission audit updated in the same commit as registration.
  • npm run deps, npm run lint, npm run typecheck clean.
  • Verified end-to-end in the running app: assistant-driven create → viewer auto-opens; edit while open → refreshes in place; paging over 2k rows; sheet tabs; corrupt-file error path; CSV append from an external write.

Adds assistant-driven spreadsheet editing and an in-app grid viewer:

- New builtin tools spreadsheet-create / spreadsheet-edit (.xlsx/.csv):
  create workbooks from row data; setCells/setRange/appendRows/clearRange
  plus add/remove/rename sheets via an ops array applied in one atomic
  write. CSV enforces single-sheet semantics. file-boundary gated.
- New core module packages/core/src/spreadsheet (shared by tools and the
  spreadsheet:load IPC): SheetJS via dynamic import, etag-guarded
  read-modify-write, single-entry parse cache, 50 MB cap, windowed reads.
- files.writeBuffer: binary sibling of writeText (atomic, locked, etag).
- Read-only SpreadsheetFileViewer (xlsx/xls/csv/tsv): sheet tabs, 500-row
  pages, 100-column cap, sticky headers, error fallback to OS open.
- Chat file cards for spreadsheets open in-app; viewer auto-opens on
  assistant create/edit and refreshes in place via a spreadsheet-touched
  window event (workspace watcher only covers allowlisted roots) plus
  workspace:didChange where available.

Known v1 limits: SheetJS community write drops cell styles on edited
files; values are literals (no formula authoring); external-app edits
outside watched roots refresh on reopen, not live.
hrsvrn and others added 3 commits August 12, 2026 12:32
…s-and-viewer

# Conflicts:
#	apps/x/apps/renderer/src/App.tsx
#	apps/x/apps/renderer/src/lib/file-types.ts
#	apps/x/packages/core/src/runtime/tools/catalog.test.ts
#	apps/x/packages/core/src/runtime/tools/catalog.ts
Make spreadsheets first-class citizens in the workspace:

- Formatted display values: spreadsheet:load returns SheetJS formatted
  text alongside raw values, so dates/currency/percent render as Excel
  shows them (no more raw date serials); raw types keep numeric alignment.
- In-sheet find: new spreadsheet:find IPC scans the active sheet in the
  main process; viewer find bar (Ctrl+F) with match count, amber
  highlights, cross-page next/prev cycling and smooth scroll-to-match.
- Pinned header row (default on): row 1 rides along on every window and
  stays under the column letters while paging; body pages cover rows 2+.
- Cell selection + copy: click / shift-click range selection, Ctrl+C or
  value-bar button copies display values as TSV; the value bar shows the
  selected address and full untruncated cell content.
- Go-to-row input in the footer.
- Per-file view state (sheet/page/pin) restored on reopen (in-memory LRU).
- Workspace search covers spreadsheets: filename matching for
  xlsx/xls/csv/tsv plus content grep for csv/tsv.
- Chat @-mentions offer spreadsheets via a separate mentionable list
  (wiki links and the graph stay markdown-only); mention attachments
  carry the real spreadsheet mimeType; ensureMarkdownExtension no longer
  appends .md to media paths.
- Tree context menu: "Open in System App" for spreadsheet files.
- Fluid animations: find/value bars slide+fade in, grid cross-fades on
  page/sheet change, smooth scroll on jumps, color transitions on
  cells, buttons and tabs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s-and-viewer

# Conflicts:
#	apps/x/apps/renderer/src/App.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant