Protect Sheet and Unprotect Sheet were journaled with their `password`
param, so the password showed in plain text in the journal dialog and
`engine.journal`, and a recorded script (Automate > Record Actions)
saved it in the workbook's hidden `_sc_scripts` name.
Session::execute now journals the params without secret ones
(`password`, or a name ending in `Password`). A replayed entry runs
without that param: Protect Sheet protects with the same options but no
password, and the matching Unprotect Sheet still succeeds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clicking the File tab now opens a full-window Backstage view in place of the
ribbon, formula bar, grid and sheet tabs, like Excel's. Esc or the back arrow
return to the sheet. Pages: Home (new + recent), New (blank + samples), Open
(recent + Browse), Info (location, properties, Protect Workbook), Save, Save As,
Print (page preview, scope, fit to page, Page Setup), Export (PDF, CSV, web
page), Close and Options (theme, language, formula bar, AutoSave, calculation).
Every action runs an existing command or dialog.
Adds `file.options` (reports the workbook's calculation settings and asks the
interface for the Options page) and the UI command `ui.backstage {page}`.
Keyboard shortcuts and the macOS native menu are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- view.zoom100 sets the active sheet's zoom to 100% (the ribbon's 100%
button runs it).
- view.formulaBar {on?} toggles a formulaBar preference (Prefs, saved in
prefs.json on desktop; an application option, not in the file). The UI
shows the formula bar from it; the ribbon checkbox, native menu and
ui.set {formulaBar} go through the command.
- The UI-only interceptions and their entries in engine.commands are gone,
so the CLI and MCP can run both. Parity checklist regenerated (260 / 290).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- UiState::default() is English: tests, the kittest harness and the
snapshot example no longer depend on the host's locale. The desktop app
alone starts from the system language, when ui.json names no supported
language (first run, an older file, an unknown value).
- An unknown or malformed saved language reads as English instead of
failing the whole UiState and resetting every other preference.
- app.language.set takes {"language": "ja"} (with `code` as an alias, the
name the PR description used); the View combo now uses it via
Language::code(). The app.language.* commands are listed by
engine.commands with the other UI commands and documented in
docs/control-protocol.md.
- Home's text "Orientation" (方向) and Page Layout's print "Orientation"
(印刷の向き) get separate keys through a `context|label` key form.
- Japanese: Hide Rows → 行を表示しない, Trace Dependents → 参照先のトレース;
translate the display-theme combo merged in from main.
- system_theme test: the View tab now has two combo boxes; pick the theme one.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ui-egui: title bar with QAT, full ribbon (Home/Insert/Draw/Page Layout/Formulas/Data/
Review/View/Automate + Table/Chart Design), formula bar with Name Box, virtualised grid
(frozen panes, overflow, borders, CF data bars/scales/icons, tables, sparklines, filter
buttons, charts/pictures/shapes), in-cell editor with point mode, reference colouring,
autocomplete and argument hints, sheet tabs, status bar, dialogs, control channel
- apps/sheetcraft: desktop app (control server, file dialogs, prefs, drag & drop)
- chart: toolkit-free chart layout/rendering for 25 chart kinds + sparklines + rasteriser
- mcp + sheetcraft-cli: MCP server (headless or bridged) and CLI (info/convert/eval/cat/run/mcp)
- xtask (ci/layers/assets/wasm/version/parity), release workflows, packaging, placeholder icon
- automatic row heights
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>