cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Merge branch 'main' into worktree-agent-a329fd9933c794bac

Dami committed d5fb3b3
Notebook outputs are grids on main: the notebook stills are recorded
again from the new screens, the grid's picture is a still of its golden
in both color modes, and the page's table of marks says how a grid
worked in shows.
commit
d5fb3b30de6bb35507a2330c8a115c3127114ca8
parent
4cf4964ccaa9ec3cd0e77ba1903fd2e4d6bb5ec2
parent
0f539e254fd5a385804c43de764f4232f6e3c3cc
author
Dami <dami.etoile@gmail.com>
183 files changed, +7965 -1027
MNOTICE102+++++++++
MREADME.md7+-
MROADMAP.md31+--
Acmd/012/agentskill.go106+++++++++
Acmd/012/agentskill_test.go45++++
Acmd/012/describe.go49++++
Mcmd/012/diffcmd.go31+++-
Mcmd/012/export.go53++++-
Acmd/012/exporthtml_test.go72++++++
Mcmd/012/main.go10+-
Acmd/012/mcp.go86++++++++
Acmd/012/mcp_test.go50++++
Acmd/012/results_test.go76+++++++
Mcmd/012/scripts.go79++++++-
Acmd/012/skill/SKILL.md95++++++++
Mcmd/012/version.go25++-
Mdemos/notebook.tape39++-
Mdemos/nu-recipe.tape12+-
Mdocs/README.md3+-
Adocs/agents/README.md90++++++++
Adocs/agents/_category_.json8+
Adocs/agents/mcp.md135++++++++++++
Mdocs/contributing/_category_.json2+-
Mdocs/contributing/limits.md7+-
Mdocs/contributing/ux.md2+-
Mdocs/files/README.md29++-
Mdocs/files/scripts.md35+++-
Mdocs/media/notebook-cells-dark.pngbin
Mdocs/media/notebook-cells-light.pngbin
Adocs/media/notebook-grid-dark.pngbin
Adocs/media/notebook-grid-light.pngbin
Mdocs/media/notebook-nu-error-dark.pngbin
Mdocs/media/notebook-nu-error-light.pngbin
Mdocs/media/notebook.gifbin
Mdocs/media/nu-recipe.gifbin
Mdocs/media/palette-dark.pngbin
Mdocs/media/palette-light.pngbin
Mdocs/nushell/cookbook.md9+-
Mdocs/nushell/notebooks.md79++++++-
Mdocs/reference/README.md1+
Mdocs/reference/_category_.json2+-
Mdocs/reference/command-line.md20+-
Adocs/reference/json.md169+++++++++++++++
Mdocs/reference/keys.md21+-
Me2e/crash_test.go7+-
Me2e/jupyter_test.go33+++
Me2e/screennotebook_test.go21++-
Me2e/stills_test.go1+
Me2e/testdata/screens/docs-notebook-cells-light.html20+-
Me2e/testdata/screens/docs-notebook-cells.html20+-
Ae2e/testdata/screens/docs-notebook-grid-light.html24++
Ae2e/testdata/screens/docs-notebook-grid.html24++
Me2e/testdata/screens/docs-notebook-nu-error-light.html8+-
Me2e/testdata/screens/docs-notebook-nu-error.html8+-
Me2e/testdata/screens/docs-palette-light.html4+-
Me2e/testdata/screens/docs-palette.html4+-
Me2e/testdata/screens/menu-download.html4+-
Me2e/testdata/screens/notebook-cells-high-contrast.html20+-
Me2e/testdata/screens/notebook-cells-light.html20+-
Me2e/testdata/screens/notebook-cells.html20+-
Me2e/testdata/screens/notebook-error-high-contrast.html20+-
Me2e/testdata/screens/notebook-error-light.html20+-
Me2e/testdata/screens/notebook-error.html20+-
Ae2e/testdata/screens/notebook-grid-filter-high-contrast.html30+++
Ae2e/testdata/screens/notebook-grid-filter-light.html30+++
Ae2e/testdata/screens/notebook-grid-filter.html30+++
Ae2e/testdata/screens/notebook-grid-high-contrast.html30+++
Ae2e/testdata/screens/notebook-grid-light.html30+++
Ae2e/testdata/screens/notebook-grid.html30+++
Me2e/testdata/screens/notebook-nu-error-high-contrast.html20+-
Me2e/testdata/screens/notebook-nu-error-light.html20+-
Me2e/testdata/screens/notebook-nu-error.html20+-
Me2e/testdata/screens/notebook-nu-highlight-high-contrast.html20+-
Me2e/testdata/screens/notebook-nu-highlight-light.html20+-
Me2e/testdata/screens/notebook-nu-highlight.html20+-
Me2e/testdata/screens/notebook-output-high-contrast.html14+-
Me2e/testdata/screens/notebook-output-light.html14+-
Me2e/testdata/screens/notebook-output.html14+-
Me2e/testdata/screens/notebook-running-high-contrast.html20+-
Me2e/testdata/screens/notebook-running-light.html20+-
Me2e/testdata/screens/notebook-running.html20+-
Me2e/testdata/screens/notebook-scroll-high-contrast.html38++--
Me2e/testdata/screens/notebook-scroll-light.html38++--
Me2e/testdata/screens/notebook-scroll.html38++--
Me2e/testdata/screens/notebook-select-high-contrast.html20+-
Me2e/testdata/screens/notebook-select-light.html20+-
Me2e/testdata/screens/notebook-select.html20+-
Me2e/testdata/screens/notebook-stale-high-contrast.html20+-
Me2e/testdata/screens/notebook-stale-light.html20+-
Me2e/testdata/screens/notebook-stale.html20+-
Me2e/testdata/screens/notebook-wrap-high-contrast.html20+-
Me2e/testdata/screens/notebook-wrap-light.html20+-
Me2e/testdata/screens/notebook-wrap-narrow-high-contrast.html16+-
Me2e/testdata/screens/notebook-wrap-narrow-light.html16+-
Me2e/testdata/screens/notebook-wrap-narrow.html16+-
Me2e/testdata/screens/notebook-wrap.html20+-
Me2e/testdata/screens/palette-narrow.html2+-
Me2e/testdata/screens/palette-search-light.html2+-
Me2e/testdata/screens/palette-search.html2+-
Me2e/testdata/screens/palette-wide.html2+-
Me2e/testdata/screens/palette.html4+-
Mgo.mod7+
Mgo.sum16+
Minternal/chart/image.go23++
Minternal/chart/scatter.go4+
Ainternal/chart/svg.go311+++++++++++++++++++++++++++
Ainternal/chart/svg_test.go71++++++
Ainternal/fileio/fonts/OFL.txt93++++++++
Ainternal/fileio/fonts/ibm-plex-mono-latin-400-italic.woff2bin
Ainternal/fileio/fonts/ibm-plex-mono-latin-400-normal.woff2bin
Ainternal/fileio/fonts/ibm-plex-mono-latin-600-normal.woff2bin
Minternal/fileio/formats.go20++-
Minternal/fileio/formats_test.go22+-
Ainternal/fileio/html.go125+++++++++++
Ainternal/fileio/html_test.go139++++++++++++
Ainternal/fileio/htmlcell.go221++++++++++++++++++++
Ainternal/fileio/htmlgrid.go239+++++++++++++++++++++
Ainternal/fileio/htmlstyle.go169+++++++++++++++
Ainternal/fileio/snapdrawn.go32+++
Minternal/fileio/snapshot.go7+
Ainternal/headless/build.go151+++++++++++++
Ainternal/headless/charts.go47++++
Ainternal/headless/describe.go241+++++++++++++++++++++
Ainternal/headless/describe_test.go86++++++++
Ainternal/headless/describetext.go107+++++++++
Ainternal/headless/encode.go33+++
Minternal/headless/jev.go8+-
Ainternal/headless/ops.go182++++++++++++++++
Ainternal/headless/read.go87++++++++
Ainternal/headless/results.go108++++++++++
Ainternal/headless/runcell.go55+++++
Minternal/headless/set.go3+-
Ainternal/headless/tools.go177++++++++++++++++
Ainternal/mcp/backend.go100+++++++++
Ainternal/mcp/prompts.go60+++++
Ainternal/mcp/read.go103+++++++++
Ainternal/mcp/resources.go225++++++++++++++++++++
Ainternal/mcp/server.go96++++++++
Ainternal/mcp/server_test.go340++++++++++++++++++++++++++++++
Ainternal/mcp/views.go119+++++++++++
Ainternal/mcp/views_test.go74+++++++
Ainternal/mcp/write.go169+++++++++++++++
Ainternal/sheet/testdata/fixtures/v0.4.0/plain.01210+
Ainternal/sheet/testdata/fixtures/v0.4.0/single.01221++
Ainternal/sheet/testdata/fixtures/v0.4.0/workbook.012169+++++++++++++++
Minternal/ui/cmdline.go2+-
Minternal/ui/commands.go25++-
Minternal/ui/context.go4+-
Minternal/ui/crash.go8+-
Minternal/ui/crash_test.go7+-
Minternal/ui/filter.go19+-
Minternal/ui/grid.go5+
Minternal/ui/gridlines.go3+
Minternal/ui/menuoverlay.go4+-
Minternal/ui/model.go6+
Minternal/ui/monochrome_test.go17+-
Minternal/ui/mouse.go4+-
Minternal/ui/nbcommands.go8+-
Ainternal/ui/nbgrid.go287+++++++++++++++++++++++++
Ainternal/ui/nbgrid_test.go200++++++++++++++++++
Ainternal/ui/nbgridcmd.go215+++++++++++++++++++
Ainternal/ui/nbgridin.go275++++++++++++++++++++++++
Minternal/ui/nbrun.go4+
Minternal/ui/nbscreen.go22+-
Minternal/ui/nbview/draw.go4+-
Minternal/ui/nbview/full.go271++++--------------------
Ainternal/ui/nbview/grid.go199++++++++++++++++++
Minternal/ui/nbview/keys.go8+-
Minternal/ui/nbview/mouse.go4+
Minternal/ui/nbview/output.go158+++-----------
Minternal/ui/nbview/outwin.go113++--------
Minternal/ui/nbview/panel.go6+-
Minternal/ui/nbview/view.go7+
Minternal/ui/nbview/view_test.go108+++++++--
Minternal/ui/notebook.go8+-
Minternal/ui/panel.go22++-
Minternal/ui/pivot.go4+
Minternal/ui/sort.go7+-
Minternal/ui/speed_test.go22++
Minternal/ui/testdata/speed.json5+
Minternal/ui/view.go12+-
Moracle/go.mod5+
Moracle/go.sum10+
M NOTICE +102 -0
@@ -28,3 +28,105 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2828 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,2929 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE3030 SOFTWARE.31+32+-------------------------------------------------------------------------------33+internal/fileio/fonts/*.woff234+35+IBM Plex Mono (regular, semibold and italic, Latin subset), embedded in the36+web pages 012 writes, as packaged by Fontsource37+(https://fontsource.org/fonts/ibm-plex-mono, @fontsource/ibm-plex-mono). The38+license is also in internal/fileio/fonts/OFL.txt.39+40+Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ThinItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLight.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Light.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-LightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Regular.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Italic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Medium.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-MediumItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Bold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-BoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved.41+42+This Font Software is licensed under the SIL Open Font License, Version 1.1.43+This license is copied below, and is also available with a FAQ at:44+http://scripts.sil.org/OFL45+46+47+-----------------------------------------------------------48+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200749+-----------------------------------------------------------50+51+PREAMBLE52+The goals of the Open Font License (OFL) are to stimulate worldwide53+development of collaborative font projects, to support the font creation54+efforts of academic and linguistic communities, and to provide a free and55+open framework in which fonts may be shared and improved in partnership56+with others.57+58+The OFL allows the licensed fonts to be used, studied, modified and59+redistributed freely as long as they are not sold by themselves. The60+fonts, including any derivative works, can be bundled, embedded,61+redistributed and/or sold with any software provided that any reserved62+names are not used by derivative works. The fonts and derivatives,63+however, cannot be released under any other type of license. The64+requirement for fonts to remain under this license does not apply65+to any document created using the fonts or their derivatives.66+67+DEFINITIONS68+"Font Software" refers to the set of files released by the Copyright69+Holder(s) under this license and clearly marked as such. This may70+include source files, build scripts and documentation.71+72+"Reserved Font Name" refers to any names specified as such after the73+copyright statement(s).74+75+"Original Version" refers to the collection of Font Software components as76+distributed by the Copyright Holder(s).77+78+"Modified Version" refers to any derivative made by adding to, deleting,79+or substituting -- in part or in whole -- any of the components of the80+Original Version, by changing formats or by porting the Font Software to a81+new environment.82+83+"Author" refers to any designer, engineer, programmer, technical84+writer or other person who contributed to the Font Software.85+86+PERMISSION & CONDITIONS87+Permission is hereby granted, free of charge, to any person obtaining88+a copy of the Font Software, to use, study, copy, merge, embed, modify,89+redistribute, and sell modified and unmodified copies of the Font90+Software, subject to the following conditions:91+92+1) Neither the Font Software nor any of its individual components,93+in Original or Modified Versions, may be sold by itself.94+95+2) Original or Modified Versions of the Font Software may be bundled,96+redistributed and/or sold with any software, provided that each copy97+contains the above copyright notice and this license. These can be98+included either as stand-alone text files, human-readable headers or99+in the appropriate machine-readable metadata fields within text or100+binary files as long as those fields can be easily viewed by the user.101+102+3) No Modified Version of the Font Software may use the Reserved Font103+Name(s) unless explicit written permission is granted by the corresponding104+Copyright Holder. This restriction only applies to the primary font name as105+presented to the users.106+107+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font108+Software shall not be used to promote, endorse or advertise any109+Modified Version, except to acknowledge the contribution(s) of the110+Copyright Holder(s) and the Author(s) or with their explicit written111+permission.112+113+5) The Font Software, modified or unmodified, in part or in whole,114+must be distributed entirely under this license, and must not be115+distributed under any other license. The requirement for fonts to116+remain under this license does not apply to any document created117+using the Font Software.118+119+TERMINATION120+This license becomes null and void if any of the above conditions are121+not met.122+123+DISCLAIMER124+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,125+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF126+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT127+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE128+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,129+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL130+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING131+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM132+OTHER DEALINGS IN THE FONT SOFTWARE.
M README.md +6 -1
M ROADMAP.md +10 -21
@@ -34,7 +34,6 @@ completed by nu as they're written.
3434 3535 | Item | Result | Size |3636 |---|---|---|37-| Outputs drawn as 012's own grid rather than text: column widths and number formats by type, the active cell and selection, sort, filter and find in place, copy a range, freeze the header, a chart or pivot from the output, and formulas beside it when sent to a sheet | An output works like the data it is | M |3837 | A command's signature and description for the word at the caret, on the context line, through `nu --ide-hover` or `nu --lsp` | Writing a cell without leaving for `help` | S |3938 4039 ### 3. Toward multiplayer
@@ -50,23 +49,7 @@ log macros record. Each step is useful on its own.
5049 | Shared viewing over SSH: several `012 serve` sessions open the same workbook; one edits, the others follow live with their own cursor, scroll and theme; presence shows who is where | Watch-along and review, one writer | M |5150 | Shared editing over SSH: every session edits, the server orders operations (no CRDT needed while one server holds the workbook), per-user undo, presence and edit ownership shown in the grid, saves by the server | Multiplayer 012 over SSH | L |5251 53-### 4. Toward 1.054-55-Solid before shared: what 012 already does keeps working from release to56-release, and shared editing builds on these guarantees. These come before57-shared editing in section 3.58-59-| Item | Result | Size |60-|---|---|---|61-| A workbook of formulas where 012 matches Sheets on purpose (dates, text, rounding, errors, spills), results checked once in Sheets and asserted after; differences chosen on purpose listed in the docs | Formula results people rely on stay put | S |62-63-### 5. Around the grid64-65-| Item | Result | Size |66-|---|---|---|67-| A sheet or chart exported as a static HTML page in 012's look | Sharing a sheet with someone without 012 | S |68-69-### 6. Agents52+### 4. Agents7053 7154 Agents work on workbooks through the same operations people do (the7255 `Batch`/`Change` path), so their edits are undoable, attributed and
@@ -75,9 +58,6 @@ section 3's shared editing with an agent as one participant.
7558 7659 | Step | Result | Size |7760 |---|---|---|78-| `012 describe` (sheets, used ranges, headers, names, tables, regions, charts), `--format json` on every command, `012 set --dry-run` printing the change as a diff, an agents page in the docs and a Claude Code skill installed by 012 | Agents with a shell use 012 well | S |79-| `012 mcp` over stdio on a workbook file: tools (describe, read, write, apply operations, evaluate without writing, find, sort, filter, chart, pivot, run a notebook cell), resources (`012://book/Sheet1!A1:D40`, tables, notebook cells), prompts | Any MCP host works with workbooks | M |80-| MCP Apps views: a sheet or chart rendered as an interactive view inside the host, from the HTML export | Workbooks shown in the chat | S to M |8161 | Live mode: `012 --listen` and `012 mcp --attach`; the agent's cursor and name in the grid, its changes arriving as a suggestion (marked cells, accepted or rejected whole or by cell) unless direct edits are allowed, its own undo, a scope (sheet, range, read-only), elicitation to ask the person | Coworking with an agent in the grid | M to L |8262 8363 ## Later: other transports (shelved)
@@ -109,6 +89,7 @@ stream above rather than a design of their own.
10989 - Undo steps in the compact form: clearing a full ten-million-cell sheet holds about what the sheet does, and a step past 1 GB asks first: [Bounds of support](docs/contributing/limits.md#undo)11090 - Spilled cells and pivot results in the compact form, about 20 B each: [Bounds of support](docs/contributing/limits.md#sheet-size)11191 - Cycles found from the formulas as written, and arrays and notebook outputs in each other's way settled the same in any order, so a workbook reads the same when reopened: [Formulas](docs/formulas/README.md#values-and-errors)92+- Formula results checked against Google Sheets once and asserted after, with the differences 012 keeps on purpose listed: [Testing](docs/contributing/testing.md#the-sheets-corpus)11293 11394 **Finding and using features**11495
@@ -149,6 +130,7 @@ stream above rather than a design of their own.
149130 - The `sheet` command: a nushell module shipped in the binary (`012 nu --install-module`), so nu calls 012 without `^012` or NUON on either side: [Pipelines](docs/nushell/pipelines.md#the-sheet-command)150131 - Notebook tabs, a TUI Jupyter for nushell: code and note cells with Jupyter's keys, outputs drawn in place and opened full-screen, `$name` between cells, stale marks and a reactive mode, outputs sent to sheets as live regions (`nu.name`), saved up to a cap, and earlier notebook sheets converted on open: [Notebooks](docs/nushell/notebooks.md)151132 - Code cells highlighted, checked and completed as they're written by nu itself (`--ide-ast`, `--ide-check`, `--ide-complete`), in the background, falling back to 012's own when nu is missing, old, slow or not trusted: [Notebooks](docs/nushell/notebooks.md#writing-a-cell)133+- Table and record outputs drawn and worked as 012's own grid: formats by type, fitted and resizable columns, select, copy, sort, filter and find in place, full-screen, charts and pivots on the sheet the output is sent to: [Notebooks](docs/nushell/notebooks.md#outputs-as-grids)152134 153135 **Files**154136
@@ -158,8 +140,15 @@ stream above rather than a design of their own.
158140 - `012 diff` cell by cell, as git's diff command or textconv, and `012 merge-driver` merging cell by cell with conflicts noted on the cells: [Diff and merge in git](docs/files/git.md)159141 - Following files: a linked region follows a CSV, TSV, JSON lines or NUON file as it grows and any importable file as it's rewritten, keeping every row or the last ones, its rows arriving as the change stream: [Following files](docs/files/following.md)160142 - The `.012` format written down with a version, and each release's workbooks kept as fixtures that every later build opens and saves unchanged: [The .012 format](docs/files/format.md#versions), [Releasing](docs/contributing/releasing.md#file-fixtures)143+- Web pages in 012's look: a sheet, a range or a chart as one self-contained `.html` file, charts as SVG, from File > Download and `012 export`: [Files](docs/files/README.md#web-pages)161144 - A crash keeps unsaved work for recovery, restores the terminal and writes a report, locally and in `012 serve`: [Saving](docs/files/saving.md#if-012-crashes)162145 146+**Agents**147+148+- `012 describe`, results as JSON with stable schemas, `012 set --dry-run` as a diff, and a Claude Code skill installed by `012 agent --install-skill`: [Agents](docs/agents/README.md)149+- `012 mcp`, an MCP server on a workbook file: tools that read, evaluate, write, sort, filter, chart, pivot and run notebook cells through the same checks as `012 set`, resources and prompts: [MCP server](docs/agents/mcp.md)150+- MCP Apps views: ranges read and charts made drawn in the chat from the HTML export, where the host supports the extension: [MCP server](docs/agents/mcp.md#views-in-the-chat)151+163152 **Upkeep**164153 165154 - `make check` before every push; demo tapes (`make demos`); annotated version tags with release notes (v0.2.0 onward; v0.1.0 remains on the Go module proxy): [Testing](docs/contributing/testing.md)
A cmd/012/agentskill.go +106 -0
@@ -0,0 +1,106 @@
1+package main2+3+import (4+ "bytes"5+ _ "embed"6+ "errors"7+ "fmt"8+ "io/fs"9+ "os"10+ "path/filepath"11+ "strings"12+)13+14+// 012 agent --skill and 012 agent --install-skill: the Claude Code15+// skill that teaches agents with a shell to use 012 (see16+// docs/agents/README.md), installed as 012 nu --install-module installs17+// the nushell module.18+19+//go:embed skill/SKILL.md20+var skillSource string21+22+const agentUsage = "usage: 012 agent --skill | --install-skill [--force] [dir]"23+24+// skillHome is where Claude Code looks for a person's own skills; tests25+// replace it.26+var skillHome = func() (string, error) {27+ home, err := os.UserHomeDir()28+ if err != nil {29+ return "", fmt.Errorf("finding your home directory: %w; name the folder instead: 012 agent --install-skill path/to/skills/012", err)30+ }31+ return filepath.Join(home, ".claude", "skills", "012"), nil32+}33+34+// runAgent is 012 agent --skill (print the skill) or --install-skill35+// [--force] [dir].36+func runAgent(args []string, e env) error {37+ a, err := parseArgs(args, nil, []string{"skill", "install-skill", "force", "help"})38+ switch {39+ case err != nil:40+ return usageError(err.Error(), agentUsage)41+ case a.has("help"):42+ fmt.Fprintln(e.stdout, agentUsage)43+ return nil44+ case a.has("skill") && !a.has("install-skill") && len(a.pos) == 0:45+ _, err := fmt.Fprint(e.stdout, skillSource)46+ return err47+ case !a.has("install-skill") || a.has("skill") || len(a.pos) > 1:48+ return usageError("", agentUsage)49+ }50+ path, err := skillPath(a.pos)51+ if err != nil {52+ return err53+ }54+ wrote, err := installSkill(path, a.has("force"))55+ if err != nil {56+ return err57+ }58+ if wrote {59+ fmt.Fprintln(e.stdout, "Wrote", path)60+ } else {61+ fmt.Fprintln(e.stdout, path, "is up to date")62+ }63+ fmt.Fprintln(e.stdout, "Claude Code finds it in the next session; /skills lists it.")64+ return nil65+}66+67+// skillPath is the SKILL.md to write: in the folder given (a file named68+// there, if it ends in .md), or in ~/.claude/skills/012.69+func skillPath(given []string) (string, error) {70+ dir := ""71+ if len(given) == 1 {72+ p, err := filepath.Abs(given[0])73+ if err != nil {74+ return "", err75+ }76+ if strings.EqualFold(filepath.Ext(p), ".md") {77+ return p, nil78+ }79+ dir = p80+ } else {81+ var err error82+ if dir, err = skillHome(); err != nil {83+ return "", err84+ }85+ }86+ return filepath.Join(dir, "SKILL.md"), nil87+}88+89+// installSkill writes the skill to path, creating its folder. A file90+// already there is replaced only with force, unless it's this skill;91+// wrote is false then.92+func installSkill(path string, force bool) (wrote bool, err error) {93+ old, err := os.ReadFile(path)94+ switch {95+ case err == nil && bytes.Equal(old, []byte(skillSource)):96+ return false, nil97+ case err == nil && !force:98+ return false, fmt.Errorf("%s exists and isn't this 012's skill; --force replaces it", path)99+ case err != nil && !errors.Is(err, fs.ErrNotExist):100+ return false, err101+ }102+ if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {103+ return false, err104+ }105+ return true, os.WriteFile(path, []byte(skillSource), 0o644)106+}
A cmd/012/agentskill_test.go +45 -0
@@ -0,0 +1,45 @@
1+package main2+3+import (4+ "os"5+ "path/filepath"6+ "strings"7+ "testing"8+)9+10+func TestAgentSkill(t *testing.T) {11+ e, out, _ := scriptEnv(t)12+ if code, err := status(e, "agent", "--skill"); code != 0 || !strings.HasPrefix(out.String(), "---\nname: 012\n") {13+ t.Fatalf("--skill: %d %v %.40q", code, err, out)14+ }15+ home := filepath.Join(t.TempDir(), "skills", "012")16+ old := skillHome17+ skillHome = func() (string, error) { return home, nil }18+ t.Cleanup(func() { skillHome = old })19+20+ out.Reset()21+ if code, err := status(e, "agent", "--install-skill"); code != 0 || !strings.Contains(out.String(), "Wrote "+filepath.Join(home, "SKILL.md")) {22+ t.Fatalf("install: %d %v %q", code, err, out)23+ }24+ out.Reset()25+ if status(e, "agent", "--install-skill"); !strings.Contains(out.String(), "is up to date") {26+ t.Errorf("again: %q", out)27+ }28+ os.WriteFile(filepath.Join(home, "SKILL.md"), []byte("mine"), 0o644)29+ if _, err := status(e, "agent", "--install-skill"); err == nil || !strings.Contains(err.Error(), "--force replaces it") {30+ t.Errorf("over another file: %v", err)31+ }32+ if code, err := status(e, "agent", "--install-skill", "--force"); code != 0 {33+ t.Error(err)34+ }35+ dir := filepath.Join(t.TempDir(), "project", ".claude", "skills", "012")36+ if code, err := status(e, "agent", "--install-skill", dir); code != 0 {37+ t.Fatal(err)38+ }39+ if data, _ := os.ReadFile(filepath.Join(dir, "SKILL.md")); string(data) != skillSource {40+ t.Errorf("project skill not written")41+ }42+ if code, _ := status(e, "agent"); code != 2 {43+ t.Errorf("agent alone: status %d", code)44+ }45+}
A cmd/012/describe.go +49 -0
M cmd/012/diffcmd.go +29 -2
@@ -19,7 +19,7 @@ import (
1919 const (2020 diffUsage = "usage: 012 diff a.012 b.012 [--format text|json|nuon] [--color auto|always|never]\n" +2121 " 012 diff --textconv file.012"22- mergeUsage = "usage: 012 merge-driver base.012 ours.012 theirs.012 [path]"22+ mergeUsage = "usage: 012 merge-driver base.012 ours.012 theirs.012 [path] [--format text|json|nuon]"2323 )2424 2525 // runDiff is 012 diff: exit status 0 when the workbooks are the same, 1
@@ -156,10 +156,13 @@ func textconv(path string, w io.Writer) error {
156156 // as a conflict to resolve; on trouble it leaves ours as it was and157157 // exits 2.158158 func runMergeDriver(args []string, e env) error {159- a, err := parseArgs(args, nil, []string{"help"})159+ a, err := parseArgs(args, []string{"format"}, []string{"help"})160+ format, ferr := resultFormat(a)160161 switch {161162 case err != nil:162163 return usageError(err.Error(), mergeUsage)164+ case ferr != nil:165+ return usageError(ferr.Error(), mergeUsage)163166 case a.has("help"):164167 fmt.Fprintln(e.stdout, mergeUsage)165168 return nil
@@ -188,6 +191,11 @@ func runMergeDriver(args []string, e env) error {
188191 return &exitError{code: 2, err: err}189192 }190193 }194+ if format != "text" {195+ if err := headless.Encode(e.stdout, format, mergeResult(conflicts)); err != nil {196+ return &exitError{code: 2, err: err}197+ }198+ }191199 if len(conflicts) == 0 {192200 return nil193201 }
@@ -207,3 +215,22 @@ func fileMode(path string) fs.FileMode {
207215 }208216 return st.Mode().Perm()209217 }218+219+// mergeConflict is a conflict as merge-driver --format json lists it.220+type mergeConflict struct {221+ Where string `json:"where"`222+ Field string `json:"field"`223+ Base string `json:"base"`224+ Ours string `json:"ours"`225+ Theirs string `json:"theirs"`226+ What string `json:"what"`227+}228+229+// mergeResult is what merge-driver --format json writes.230+func mergeResult(conflicts []diff.Conflict) map[string]any {231+ out := []mergeConflict{}232+ for _, c := range conflicts {233+ out = append(out, mergeConflict{c.Where, c.Field, c.Base, c.Ours, c.Theirs, c.What})234+ }235+ return map[string]any{"conflicts": out}236+}
M cmd/012/export.go +48 -5
@@ -3,6 +3,7 @@ package main
33 import (44 "context"55 "fmt"6+ "io"67 "os"78 "path/filepath"89 "strings"
@@ -12,13 +13,13 @@ import (
1213 "github.com/FelineStateMachine/012/internal/sheet"1314 )1415 15-const exportUsage = "usage: 012 export file.012 out.csv|tsv|xlsx|json|nuon|sqlite [ref] [--format kind] [--table name] [--notebooks] [--jev] [--trust]"16+const exportUsage = "usage: 012 export file.012 out.csv|tsv|xlsx|json|nuon|sqlite|html [ref] [--format kind] [--table name] [--chart n|title] [--report json|nuon] [--notebooks] [--jev] [--trust]"1617 1718 // runExport is 012 export: a sheet, a range or (to formats holding1819 // several sheets) the whole workbook written as File > Download writes1920 // it.2021 func runExport(args []string, e env) error {21- a, err := parseArgs(args, []string{"format", "table"}, append([]string{"help"}, evalFlags...))22+ a, err := parseArgs(args, []string{"format", "table", "chart", "report"}, append([]string{"help"}, evalFlags...))2223 switch {2324 case err != nil:2425 return usageError(err.Error(), exportUsage)
@@ -33,6 +34,13 @@ func runExport(args []string, e env) error {
3334 if err != nil {3435 return usageError(err.Error(), exportUsage)3536 }37+ report := strings.ToLower(a.flags["report"])38+ if a.has("report") && report != "json" && report != "nuon" {39+ return usageError("--report "+report+": json or nuon", exportUsage)40+ }41+ if a.has("chart") && k != fileio.HTML {42+ return usageError("--chart writes a web page: name an .html file", exportUsage)43+ }3644 if same(src, out) {3745 return fmt.Errorf("%s is the workbook being exported: name another file", out)3846 }
@@ -52,20 +60,37 @@ func runExport(args []string, e env) error {
5260 if err := failed.fatal(); err != nil {5361 return err5462 }63+ if a.has("chart") {64+ if err := exportChart(out, t, a.flags["chart"]); err != nil {65+ return err66+ }67+ return exportReport(e, report, headless.ExportResult{File: out, Format: "html", Notes: []string{}}, failed)68+ }5569 snap := exportSnap(t, k, ref == "")5670 res, err := fileio.Export(context.Background(), out, k, snap, fileio.ExportOptions{Table: a.flags["table"]})5771 if err != nil {5872 return fmt.Errorf("%s: %w", out, err)5973 }60- for _, n := range res.Notes {61- fmt.Fprintln(e.stderr, "012: note: "+n)74+ return exportReport(e, report, headless.ExportResult{File: out, Format: strings.ToLower(k.String()), Rows: res.Rows,75+ Notes: append([]string{}, res.Notes...)}, failed)76+}77+78+// exportReport says what was written: its notes on standard error, or79+// with --report the whole result on standard output.80+func exportReport(e env, report string, res headless.ExportResult, failed evalFailures) error {81+ if report == "" {82+ for _, n := range res.Notes {83+ fmt.Fprintln(e.stderr, "012: note: "+n)84+ }85+ } else if err := headless.Encode(e.stdout, report, res); err != nil {86+ return err6287 }6388 return failed.err()6489 }6590 6691 // exportKind is the format to write: --format's, or out's extension's.6792 func exportKind(out, named string) (fileio.Kind, error) {68- k, ok := fileio.KindOf(out)93+ k, ok := fileio.ExportKindOf(out)6994 if named != "" {7095 k, ok = fileio.KindNamed(named)7196 if !ok {
@@ -115,3 +140,21 @@ func same(a, b string) bool {
115140 sb, err2 := os.Stat(b)116141 return err1 == nil && err2 == nil && os.SameFile(sa, sb)117142 }143+144+// exportChart is 012 export --chart: one chart of the target's sheet as145+// a web page of its own, found by its number (1 is the first) or title.146+func exportChart(out string, t headless.Target, which string) error {147+ i, err := headless.FindChart(t.Sheet, which)148+ if err != nil {149+ return err150+ }151+ c, _ := fileio.ChartSnap(t.Sheet, i)152+ err = headless.WriteAtomic(out, 0o644, func(w io.Writer) error {153+ _, err := fileio.WriteHTML(w, fileio.HTMLPage{Title: headless.ChartTitle(c.Chart), Chart: &c})154+ return err155+ })156+ if err != nil {157+ return fmt.Errorf("%s: %w", out, err)158+ }159+ return nil160+}
A cmd/012/exporthtml_test.go +72 -0
@@ -0,0 +1,72 @@
1+package main2+3+import (4+ "os"5+ "path/filepath"6+ "strings"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// chartFile writes a workbook of two columns and a chart titled Sales.13+func chartFile(t *testing.T, dir string) string {14+ t.Helper()15+ w := sheet.NewBook()16+ s := w.Sheet(0)17+ for i, in := range []string{"Month", "Jan", "Feb"} {18+ s.Set(sheet.Addr{Row: i}, in)19+ }20+ for i, in := range []string{"Sales", "10", "20"} {21+ s.Set(sheet.Addr{Col: 1, Row: i}, in)22+ }23+ s.AddChart(sheet.Chart{Type: sheet.ChartLine, Data: sheet.Rect{To: sheet.Addr{Col: 1, Row: 2}}, Header: true, Labels: true,24+ Title: "Sales", At: sheet.Addr{Col: 3}, W: 30, H: 10})25+ path := filepath.Join(dir, "book.012")26+ f, err := os.Create(path)27+ if err != nil {28+ t.Fatal(err)29+ }30+ defer f.Close()31+ if err := w.Write(f); err != nil {32+ t.Fatal(err)33+ }34+ return path35+}36+37+func TestExportHTML(t *testing.T) {38+ e, _, _ := scriptEnv(t)39+ dir := t.TempDir()40+ path := chartFile(t, dir)41+ out := filepath.Join(dir, "book.html")42+ if code, err := status(e, "export", path, out); code != 0 {43+ t.Fatal(err)44+ }45+ data, _ := os.ReadFile(out)46+ if page := string(data); !strings.Contains(page, `data-a="B3" class="r">20<`) || !strings.Contains(page, "<polyline") {47+ t.Errorf("page lacks the cells or the chart")48+ }49+ chart := filepath.Join(dir, "chart.html")50+ for _, which := range []string{"1", "sales"} {51+ os.Remove(chart)52+ if code, err := status(e, "export", path, chart, "--chart", which); code != 0 {53+ t.Fatal(err)54+ }55+ data, _ := os.ReadFile(chart)56+ if page := string(data); !strings.Contains(page, "<title>Sales</title>") || strings.Contains(page, "<table") {57+ t.Errorf("--chart %s: not the chart alone", which)58+ }59+ }60+ for _, c := range []struct {61+ args []string62+ want string63+ }{64+ {[]string{path, chart, "--chart", "2"}, "Sheet1 has 1 chart: chart 2 isn't one"},65+ {[]string{path, chart, "--chart", "Costs"}, `no chart titled "Costs" (charts: Sales)`},66+ {[]string{path, filepath.Join(dir, "x.csv"), "--chart", "1"}, "--chart writes a web page"},67+ } {68+ if _, err := status(e, append([]string{"export"}, c.args...)...); err == nil || !strings.Contains(err.Error(), c.want) {69+ t.Errorf("export %v: %v, want %q", c.args, err, c.want)70+ }71+ }72+}
M cmd/012/main.go +6 -4
@@ -80,8 +80,10 @@ func usage() error {
8080 " 012 nu [flags] [file]: the workbook's nushell notebook (see docs/nushell/notebooks.md)\n" +8181 " 012 nu --module | --install-module [--force] [path]: the nushell module with sheet (see docs/nushell/README.md)\n" +8282 " 012 serve [flags] [dir]: serve sheets in dir over SSH (see docs/terminal/ssh.md)\n" +83- " 012 get|set|recalc|export file.012 ...: read and change a workbook without the screen (see docs/files/scripts.md)\n" +83+ " 012 get|set|recalc|export|describe file.012 ...: read and change a workbook without the screen (see docs/files/scripts.md)\n" +8484 " 012 diff a.012 b.012, 012 merge-driver base ours theirs: compare and merge workbooks (see docs/files/git.md)\n" +85+ " 012 mcp file.012 [--read-only] [--force] [--notebooks [--trust]] [--jev]: an MCP server on the workbook (see docs/agents/mcp.md)\n" +86+ " 012 agent --skill | --install-skill [--force] [dir]: the Claude Code skill (see docs/agents/README.md)\n" +8587 " 012 config [path|edit|default|themes|set-key|delete-key]\n" +8688 " 012 version")8789 }
@@ -90,8 +92,8 @@ func usage() error {
9092 // opens as ./name.9193 var subcommands = map[string]func([]string, env) error{9294 "config": runConfig, "serve": runServe,93- "get": runGet, "set": runSet, "recalc": runRecalc, "export": runExport,94- "diff": runDiff, "merge-driver": runMergeDriver,95+ "get": runGet, "set": runSet, "recalc": runRecalc, "export": runExport, "describe": runDescribe,96+ "diff": runDiff, "merge-driver": runMergeDriver, "agent": runAgent, "mcp": runMCP,9597 }9698 9799 func run(args []string, e env) error {
@@ -99,7 +101,7 @@ func run(args []string, e env) error {
99101 return subcommands[args[0]](args[1:], e)100102 }101103 if len(args) > 0 && (args[0] == "version" || args[0] == "--version") {102- return runVersion(e)104+ return runVersion(args[1:], e)103105 }104106 if len(args) > 0 && args[0] == "nu" && isModuleCommand(args[1:]) {105107 return runNuModule(args[1:], e)
A cmd/012/mcp.go +86 -0
@@ -0,0 +1,86 @@
1+package main2+3+import (4+ "context"5+ "fmt"6+ "io"7+ "os"8+ "os/signal"9+ "sync"10+11+ sdk "github.com/modelcontextprotocol/go-sdk/mcp"12+13+ "github.com/FelineStateMachine/012/internal/config"14+ "github.com/FelineStateMachine/012/internal/headless"15+ "github.com/FelineStateMachine/012/internal/jev"16+ "github.com/FelineStateMachine/012/internal/mcp"17+ "github.com/FelineStateMachine/012/internal/sheet"18+)19+20+// 012 mcp: a Model Context Protocol server over standard input and21+// output on one workbook file (see docs/agents/mcp.md).22+23+const mcpUsage = "usage: 012 mcp file.012 [--read-only] [--force] [--notebooks [--trust]] [--jev]"24+25+// runMCP is 012 mcp: it serves until the client closes standard input.26+// Nothing runs a program or reaches the network unless its flag says:27+// --notebooks offers run_notebook_cell, --jev answers JEV functions.28+func runMCP(args []string, e env) error {29+ a, err := parseArgs(args, nil, []string{"read-only", "force", "notebooks", "trust", "jev", "help"})30+ switch {31+ case err != nil:32+ return usageError(err.Error(), mcpUsage)33+ case a.has("help"):34+ fmt.Fprintln(e.stdout, mcpUsage)35+ return nil36+ case len(a.pos) != 1:37+ return usageError("", mcpUsage)38+ case a.has("trust") && !a.has("notebooks"):39+ return usageError("--trust goes with --notebooks", mcpUsage)40+ }41+ path := a.pos[0]42+ if _, err := headless.Open(path, true); err != nil {43+ return err44+ }45+ cfg, err := loadConfig(e, nil)46+ if err != nil {47+ return err48+ }49+ ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)50+ defer stop()51+ b := &mcp.FileBackend{Path: path, Save: func(f *headless.File) error { return save(f, e) }}52+ if a.has("jev") {53+ b.Prepare = jevPreparer(cfg, e)54+ }55+ o := mcp.Options{Version: buildVersion(), ReadOnly: a.has("read-only"), Force: a.has("force")}56+ if a.has("notebooks") && !a.has("read-only") {57+ o.Notebooks = &headless.NotebookOptions{Runner: e.nuRunner(), Timeout: cfg.Duration("nu-timeout"), NuConfig: cfg.Bool("nu-config")}58+ o.MayRun = func(w *sheet.Workbook) error {59+ return mayRun(&headless.File{Path: path, Book: w}, cfg, a.has("trust"))60+ }61+ }62+ t := &sdk.IOTransport{Reader: io.NopCloser(e.stdin), Writer: nopWriteCloser{e.stdout}}63+ return mcp.New(b, o).Run(ctx, t)64+}65+66+// jevPreparer answers a workbook's JEV functions each time it's opened,67+// connecting once and keeping the answers, so each question is asked68+// once a session.69+func jevPreparer(cfg *config.Config, e env) func(context.Context, *headless.File) error {70+ var once sync.Once71+ var client jev.Client72+ var connErr error73+ cache := jev.NewCache()74+ return func(ctx context.Context, f *headless.File) error {75+ once.Do(func() { client, connErr = jevClient(ctx, cfg, e) })76+ if connErr != nil {77+ return connErr78+ }79+ headless.AnswerJEVFrom(ctx, f.Book, client, cache, jevTimeout)80+ return nil81+ }82+}83+84+type nopWriteCloser struct{ io.Writer }85+86+func (nopWriteCloser) Close() error { return nil }
A cmd/012/mcp_test.go +50 -0
A cmd/012/results_test.go +76 -0
@@ -0,0 +1,76 @@
1+package main2+3+import (4+ "encoding/json"5+ "os"6+ "path/filepath"7+ "strings"8+ "testing"9+10+ "github.com/FelineStateMachine/012/internal/headless"11+)12+13+// TestSetDryRun prints the change as 012 diff would and leaves the14+// file as it was.15+func TestSetDryRun(t *testing.T) {16+ e, out, _ := scriptEnv(t)17+ path := filepath.Join(t.TempDir(), "book.012")18+ status(e, "set", path, "A1", "1")19+ before, _ := os.ReadFile(path)20+ out.Reset()21+ if code, err := status(e, "set", path, "A1", "2", "B1", "=A1*2", "--dry-run"); code != 0 {22+ t.Fatal(err)23+ }24+ if got := out.String(); !strings.Contains(got, "Sheet1!A1 input 1 → 2") || !strings.Contains(got, "Sheet1!B1 input + =A1*2") {25+ t.Errorf("dry run printed %q", got)26+ }27+ if after, _ := os.ReadFile(path); string(after) != string(before) {28+ t.Errorf("dry run saved")29+ }30+ out.Reset()31+ if code, err := status(e, "set", path, "A1", "3", "--format", "json"); code != 0 {32+ t.Fatal(err)33+ }34+ var res headless.SetResult35+ if err := json.Unmarshal(out.Bytes(), &res); err != nil {36+ t.Fatalf("%v: %s", err, out)37+ }38+ if !res.Saved || len(res.Changes) == 0 || res.Changes[0].Item != "A1" || string(res.Changes[0].New) != `"3"` {39+ t.Errorf("set result %+v", res)40+ }41+ // A new file's dry run lists what it would hold, and makes no file.42+ fresh := filepath.Join(t.TempDir(), "new.012")43+ out.Reset()44+ status(e, "set", fresh, "A1", "x", "--dry-run", "--format", "nuon")45+ if _, err := os.Stat(fresh); err == nil || !strings.Contains(out.String(), "saved: false") {46+ t.Errorf("dry run on a new file: %s", out)47+ }48+}49+50+// TestResultFormats checks the other commands' --format json results.51+func TestResultFormats(t *testing.T) {52+ e, out, _ := scriptEnv(t)53+ dir := t.TempDir()54+ path := filepath.Join(dir, "book.012")55+ status(e, "set", path, "A1", "Item", "B1", "Price", "A2", "Pen", "B2", "=1/0")56+ for _, c := range []struct {57+ args []string58+ code int59+ want string60+ }{61+ {[]string{"recalc", path, "--format", "json"}, 1, `"value": "#DIV/0!"`},62+ {[]string{"describe", path, "--format", "json"}, 0, `"columns": [`},63+ {[]string{"describe", path}, 0, "Sheet1 (shown) A1:B2, 2 rows x 2 columns, 4 cells, 1 formula (1 showing errors)"},64+ {[]string{"export", path, filepath.Join(dir, "out.csv"), "--report", "json"}, 0, `"format": "csv"`},65+ {[]string{"version", "--format", "json"}, 0, `"go": "go`},66+ } {67+ out.Reset()68+ code, err := status(e, c.args...)69+ if code != c.code || !strings.Contains(out.String(), c.want) {70+ t.Errorf("%v: %d %v %s, want %q", c.args, code, err, out, c.want)71+ }72+ }73+ if code, _ := status(e, "describe", path, "--format", "csv"); code != 2 {74+ t.Errorf("describe --format csv: status %d", code)75+ }76+}
M cmd/012/scripts.go +71 -8
@@ -7,6 +7,7 @@ import (
77 "slices"88 "strings"99 10+ "github.com/FelineStateMachine/012/internal/diff"1011 "github.com/FelineStateMachine/012/internal/headless"1112 "github.com/FelineStateMachine/012/internal/notebook"1213 )
@@ -17,8 +18,8 @@ import (
1718 1819 const (1920 getUsage = "usage: 012 get file.012 [ref] [--format text|csv|tsv|json|nuon] [--input] [--no-header] [--notebooks] [--jev] [--trust]"20- setUsage = "usage: 012 set file.012 ref input [ref input ...] [--force]"21- recalcUsage = "usage: 012 recalc file.012 [--notebooks] [--jev] [--trust]"21+ setUsage = "usage: 012 set file.012 ref input [ref input ...] [--force] [--dry-run] [--format text|json|nuon]"22+ recalcUsage = "usage: 012 recalc file.012 [--format text|json|nuon] [--notebooks] [--jev] [--trust]"2223 )2324 2425 // evalFlags are the flags that let a command run a workbook's notebook
@@ -63,9 +64,10 @@ func runGet(args []string, e env) error {
6364 return failed.err()6465 }6566 66-// runSet is 012 set: type entries into cells and save.67+// runSet is 012 set: type entries into cells and save, or with68+// --dry-run print what would change, as 012 diff would, and not save.6769 func runSet(args []string, e env) error {68- a, err := parseArgs(args, nil, []string{"force", "help"})70+ a, err := parseArgs(args, []string{"format"}, []string{"force", "dry-run", "help"})6971 switch {7072 case err != nil:7173 return usageError(err.Error(), setUsage)
@@ -75,6 +77,10 @@ func runSet(args []string, e env) error {
7577 case len(a.pos) < 3 || len(a.pos)%2 == 0:7678 return usageError("", setUsage)7779 }80+ format, err := resultFormat(a)81+ if err != nil {82+ return usageError(err.Error(), setUsage)83+ }7884 f, err := headless.Open(a.pos[0], true)7985 if err != nil {8086 return err
@@ -87,16 +93,55 @@ func runSet(args []string, e env) error {
8793 if err != nil {8894 return fmt.Errorf("%w; %s is unchanged", err, f.Path)8995 }90- for _, w := range warnings {91- fmt.Fprintln(e.stderr, "012: warning: "+w)96+ res := headless.SetResult{File: f.Path, Warnings: warnings, Changes: []headless.Change{}}97+ if format == "text" {98+ for _, w := range warnings {99+ fmt.Fprintln(e.stderr, "012: warning: "+w)100+ }101+ }102+ if format != "text" || a.has("dry-run") {103+ changes, err := f.Changes()104+ if err != nil {105+ return err106+ }107+ if format == "text" {108+ color, _ := useColor("", e)109+ return diff.WriteChanges(e.stdout, changes, "text", color)110+ }111+ res.Changes = headless.Changes(changes)112+ }113+ if !a.has("dry-run") {114+ if err := save(f, e); err != nil {115+ return err116+ }117+ res.Saved = true118+ }119+ if format == "text" {120+ return nil121+ }122+ if res.Warnings == nil {123+ res.Warnings = []string{}124+ }125+ return headless.Encode(e.stdout, format, res)126+}127+128+// resultFormat is --format's form for a command's result: text, json129+// or nuon.130+func resultFormat(a cliArgs) (string, error) {131+ switch f := strings.ToLower(a.flags["format"]); f {132+ case "", "text":133+ return "text", nil134+ case "json", "nuon":135+ return f, nil136+ default:137+ return "", errors.New("--format " + f + ": text, json or nuon")92138 }93- return save(f, e)94139 }95140 96141 // runRecalc is 012 recalc: recalculate, save, and list the cells whose97142 // formulas show errors, exiting 1 when there are any.98143 func runRecalc(args []string, e env) error {99- a, err := parseArgs(args, nil, append([]string{"help"}, evalFlags...))144+ a, err := parseArgs(args, []string{"format"}, append([]string{"help"}, evalFlags...))100145 switch {101146 case err != nil:102147 return usageError(err.Error(), recalcUsage)
@@ -106,6 +151,10 @@ func runRecalc(args []string, e env) error {
106151 case len(a.pos) != 1:107152 return usageError("", recalcUsage)108153 }154+ format, err := resultFormat(a)155+ if err != nil {156+ return usageError(err.Error(), recalcUsage)157+ }109158 f, err := headless.Open(a.pos[0], false)110159 if err != nil {111160 return err
@@ -118,6 +167,14 @@ func runRecalc(args []string, e env) error {
118167 if err := save(f, e); err != nil {119168 return err120169 }170+ if format != "text" {171+ res := headless.RecalcResult{File: f.Path, Errors: headless.Problems(problems), Circular: circular,172+ NotebookFailures: append([]string{}, failed.cells...)}173+ if err := headless.Encode(e.stdout, format, res); err != nil {174+ return err175+ }176+ return problemStatus(problems, circular, failed)177+ }121178 return reportProblems(e.stdout, problems, circular, failed)122179 }123180
@@ -149,6 +206,12 @@ func reportProblems(w io.Writer, problems []headless.Problem, circular bool, fai
149206 if circular {150207 fmt.Fprintln(w, "circular reference: a formula reads its own cell, directly or through others")151208 }209+ return problemStatus(problems, circular, failed)210+}211+212+// problemStatus is recalc's exit status: 1 when cells show errors or a213+// notebook cell failed.214+func problemStatus(problems []headless.Problem, circular bool, failed evalFailures) error {152215 if len(problems) > 0 || circular {153216 return &exitError{code: 1, err: fmt.Errorf("%d %s showing errors", len(problems), plural(len(problems), "cell", "cells"))}154217 }
A cmd/012/skill/SKILL.md +95 -0
@@ -0,0 +1,95 @@
1+---2+name: 0123+description: Read, change, check and share 012 spreadsheet workbooks (.012 files) from the shell with the 012 command. Use when a task involves a .012 file, or when a spreadsheet, table of numbers or chart should be built, inspected, recalculated or exported (CSV, XLSX, JSON, NUON, SQLite, HTML).4+---5+6+# Working with 012 workbooks7+8+012 is a terminal spreadsheet. Its `.012` files are workbooks of sheets,9+formulas, tables, charts and nushell notebooks. Work on them with the10+`012` command, never by editing the file's JSON: `012 set` checks every11+entry as the screen does and saves atomically, and its changes show in12+`012 diff` like a person's.13+14+## Look before you read15+16+```sh17+012 describe book.012 # sheets, used ranges, header rows, tables, names, charts, notebooks18+012 describe book.012 --format json # the same as JSON19+```20+21+Read what describe points at rather than whole sheets.22+23+## Read24+25+```sh26+012 get book.012 B7 # one cell, as shown: $1,200.0027+012 get book.012 B7 --input # what was typed: =SUM(B2:B6)28+012 get book.012 'Q3 plan'!A1:F20 --format json # records named by the first row29+012 get book.012 Sales --format json # a table or named range by name30+012 get book.012 'Sales[Amount]' --format json # one column of a table31+```32+33+References are written as in formulas: `B7`, `A1:C9`, `A:A`, `Q3!B7`,34+`'Q3 plan'!A1:C9`, a named range, a table (`Sales`, `Sales[Amount]`) or a35+sheet name for the whole sheet. Without a sheet, the sheet shown when the36+file was saved is meant. `--no-header` names JSON columns by letter.37+38+## Change39+40+Preview first, then write:41+42+```sh43+012 set book.012 B7 '=SUM(B2:B6)' B8 1200 --dry-run # prints the change as 012 diff would; saves nothing44+012 set book.012 B7 '=SUM(B2:B6)' B8 1200 # types the entries, as one change, and saves45+012 set book.012 B7 '=SUM(B2:B6)' --format json # {file, saved, changes, warnings}46+```47+48+- Inputs are what a person types, in en-US form whatever the workbook's49+ locale: `1.5`, `=ROUND(A1, 2)`, `$1,200` (sets a currency format),50+ `12%`, `2026-09-29`. An empty input clears a cell.51+- Formulas are Google Sheets' (`SUM`, `XLOOKUP`, `FILTER`, `LET`,52+ `LAMBDA`, structured references like `Sales[Amount]`).53+- `set` refuses, and changes nothing, on the first entry a cell can't54+ take: a formula that doesn't parse, a validation rule, a protected55+ range (`--force` overrides only that), or a cell of a spill, pivot56+ table or notebook output. Read the message; it names the cell.57+- An input starting with `--` goes after `--`: `012 set book.012 -- A1 --`.58+59+## Check60+61+```sh62+012 recalc book.012 # recalculates, saves, lists cells showing errors; exit 1 if any63+012 recalc book.012 --format json # {file, errors: [{cell, value, why}], circular, notebook_failures}64+012 diff old.012 new.012 --format json65+```66+67+Run `012 recalc` after changing formulas and fix what it lists.68+69+## Share70+71+```sh72+012 export book.012 out.xlsx # every sheet, with formulas and formats73+012 export book.012 out.csv 'Q3'!A1:F20 # values as shown74+012 export book.012 report.html # a web page in 012's look, charts as SVG75+012 export book.012 chart.html --chart 1 # one chart alone, by number or title76+```77+78+## Safety79+80+Nothing runs a program or reaches the network unless a flag asks:81+`--notebooks` runs the workbook's nushell notebook cells (and82+`--trust` a workbook saved on another computer), `--jev` asks the JEV83+model service. Don't add them unless the user wants that.84+85+## Exit status86+87+0 done; 1 an error on standard error (or, for `recalc`, cells showing88+errors; for `diff`, the workbooks differ); 2 the command was used89+wrongly, with its usage. Every command's `--help` prints its usage.90+91+When the 012 MCP server (`012 mcp book.012`) is connected, its tools92+(describe, read_range, write_cells with dry_run, evaluate, list_errors)93+do the same with the same checks.94+95+The full reference: https://github.com/FelineStateMachine/012/blob/main/docs/agents/README.md
M cmd/012/version.go +23 -2
M demos/notebook.tape +24 -15
@@ -1,6 +1,7 @@
11 # Notebooks: 012 nu opens a notebook, its first cell ready to type in.22 # A code cell reads a CSV as sales, a second reads it as $sales, and its3-# output goes to a sheet (G) where a formula sums it; with the notebook3+# output, entered with Enter, is a grid to select in, and goes to a4+# sheet (G) where a formula sums it; with the notebook45 # reactive, editing sales runs both again and the sheet follows. The terminal (ttyd) sends Shift+Enter as Enter, so56 # cells run with Esc then r. Needs nu on the PATH.67 Output out/notebook.gif
@@ -12,52 +13,60 @@ Sleep 2s
1213 Show1314 1415 Sleep 800ms15-Type@25ms "sales = open data/sales.csv | where Region in [North South] | select Region Quarter Units"16+Type@15ms "sales = open data/sales.csv | where Region in [North South] | select Region Quarter Units"1617 Sleep 500ms1718 Escape1819 Type "r"19-Sleep 1.5s20+Sleep 1s2021 Type "b"2122 Enter22-Type@25ms "top = $sales | where Units > 250 | sort-by Units --reverse"23+Type@15ms "top = $sales | where Units > 250 | sort-by Units --reverse"2324 Sleep 500ms2425 Escape2526 Type "r"2627 Sleep 2s2728 Screenshot out/stills/notebook-cells.png29+Down30+Enter31+Sleep 400ms32+Ctrl+Shift+Down33+Sleep 1s34+Screenshot out/stills/notebook-grid.png35+Escape Escape36+Sleep 500ms2837 Type "G"2938 Sleep 800ms3039 Enter3140 Sleep 1.2s3241 Ctrl+K33-Type@40ms "next sh"42+Type@20ms "next sh"3443 Sleep 500ms3544 Enter36-Sleep 600ms45+Sleep 400ms3746 Right Right Right Right3847 Type "=SUM(nu.top)" Enter39-Sleep 1.5s48+Sleep 1s4049 Screenshot out/stills/notebook-sent.png4150 Ctrl+K42-Type@40ms "previous sh"51+Type@20ms "previous sh"4352 Sleep 500ms4453 Enter45-Sleep 600ms54+Sleep 400ms4655 Ctrl+K47-Type@50ms "reacti"48-Sleep 600ms56+Type@20ms "reacti"57+Sleep 400ms4958 Enter5059 Sleep 400ms51-Up Up60+Up Up Up5261 Sleep 300ms5362 Enter54-Type@30ms " | where Quarter != Q1"63+Type@20ms " | where Quarter != Q1"5564 Escape5665 Type "r"57-Sleep 2.5s66+Sleep 2s5867 Screenshot out/stills/notebook-reactive.png5968 Ctrl+K60-Type@40ms "next sh"69+Type@20ms "next sh"6170 Sleep 500ms6271 Enter6372 Sleep 2s
M demos/nu-recipe.tape +3 -9
M docs/README.md +2 -1
A docs/agents/README.md +90 -0
@@ -0,0 +1,90 @@
1+---2+title: "Agents"3+sidebar_position: 14+---5+6+# Agents7+8+Coding agents and assistants work on `.012` workbooks through the same9+operations people use: every change is typed into cells as the screen10+types it, checked by the same rules, made as one change and11+shown by [`012 diff`](../files/git.md#012-diff) like anyone's. Nothing12+agents do runs a program or reaches the network unless they were13+started with the flags that allow it, as for scripts.14+15+| Page | For |16+|---|---|17+| This page | Agents with a shell: the commands, their JSON, and the Claude Code skill |18+| [MCP server](mcp.md) | `012 mcp`, for any MCP host: tools, resources, prompts, and adding it to Claude Code and Claude Desktop |19+| [JSON output](../reference/json.md) | The schemas of what commands write with `--format json`, and what the MCP tools return |20+21+## With a shell22+23+Agents that can run commands use the ones [scripts](../files/scripts.md)24+use, in this order:25+26+```sh27+012 describe book.012 --format json # what's where28+012 get book.012 Sales --format json # read what describe pointed at29+012 set book.012 D2 '=B2*C2' D3 '=B3*C3' --dry-run # preview a change as a diff30+012 set book.012 D2 '=B2*C2' D3 '=B3*C3' # make it: one change, saved atomically31+012 recalc book.012 --format json # check no formula shows an error32+012 export book.012 report.html # share it as a web page33+```34+35+`012 describe` lists each sheet with its used range, the row that looks36+like its header and the column names in it, frozen panes, filters,37+tables, notebook outputs and linked files sent to it, and charts38+(numbered, as `012 export --chart` names them); pivot tables with their39+source; notebook tabs with their cells and whether each ran; and the40+workbook's named ranges:41+42+```43+Sales (shown) A1:F9, 9 rows x 6 columns, 54 cells, 9 formulas44+ header row 1: Date, Region, Units, Price, Total, Share45+ frozen 1 row, 0 columns46+ table Orders A1:F9 Date, Region, Units, Price, Total, Share47+ chart 1 Units by date column of A1:C9 at H248+Notebook (notebook) 2 cells49+ 1 code files = ls (ran)50+ 2 code $files | where size > 1kb (not run)51+names52+ Rate Sales!B1253+```54+55+A header row is guessed: the first row with contents, when every cell56+in it is text and the rows below hold numbers, dates, booleans or57+formulas, or when it's bold. `--format json` gives the same as the58+[schema](../reference/json.md#describe).59+60+`012 set --dry-run` checks the entries as `set` does (a formula that61+doesn't parse, a validation rule, a protected range stop it the same62+way) and prints what would change, as `012 diff` would, without saving;63+`--format json` gives the changes as records instead. Every command's64+flags are in [Command line](../reference/command-line.md).65+66+## The Claude Code skill67+68+012 carries a [Claude Code skill](https://docs.claude.com/en/docs/claude-code/skills):69+a `SKILL.md` that tells Claude when to reach for `012` and how to use70+it well (describe first, preview with `--dry-run`, `recalc` after71+changing formulas, never edit the file's JSON by hand).72+73+```sh74+012 agent --install-skill # into ~/.claude/skills/012, for every project75+012 agent --install-skill .claude/skills/012 # into this project, to commit with it76+012 agent --skill # print it77+```78+79+Installing over a file that isn't this 012's skill asks for `--force`;80+installing the same skill again says it's up to date. A newer 012 may81+carry a newer skill: install it again after upgrading.82+83+## Trust84+85+Agents get no more than scripts do. A workbook's86+[notebook](../nushell/notebooks.md) cells run only with `--notebooks`,87+and then only when the workbook was saved on this computer or88+`--trust` says so; [JEV functions](../formulas/jev.md) ask the network89+only with `--jev`. Protected ranges refuse changes unless `--force` is90+given. Leave these flags to the person asking.
A docs/agents/_category_.json +8 -0
A docs/agents/mcp.md +135 -0
@@ -0,0 +1,135 @@
1+---2+title: "MCP server"3+sidebar_position: 24+---5+6+# MCP server7+8+`012 mcp book.012` is a [Model Context Protocol](https://modelcontextprotocol.io)9+server on one workbook, over standard input and output, so any MCP host10+(Claude Code, Claude Desktop, editors) can read and change it. It is the11+same code as [the commands](README.md#with-a-shell): reads are12+`012 describe` and `012 get`, and every write is typed through the13+checks `012 set` makes, as one change, saved atomically at14+once.15+16+```mermaid17+flowchart LR18+ host[MCP host] -- "stdio: tools, resources, prompts" --> server["012 mcp book.012"]19+ server -- "open, read" --> file[(book.012)]20+ server -- "one change, Batch, atomic save" --> file21+ person["012 book.012, 012 set, git"] --> file22+```23+24+The file is opened afresh for every call, so what the screen, a script25+or git saved meanwhile is what the next call sees. A file that doesn't26+exist is an empty workbook, saved on the first change.27+28+## Adding it to a host29+30+Claude Code, for one workbook (`--scope project` writes `.mcp.json`31+to commit with the project; the default keeps it to you):32+33+```sh34+claude mcp add budget -- 012 mcp /path/to/budget.01235+claude mcp add --scope project budget -- 012 mcp budget.01236+```37+38+Claude Desktop, in `claude_desktop_config.json` (Settings > Developer >39+Edit Config), with the full paths, since Desktop doesn't start in your40+folder:41+42+```json43+{44+ "mcpServers": {45+ "budget": {46+ "command": "/usr/local/bin/012",47+ "args": ["mcp", "/Users/me/Documents/budget.012"]48+ }49+ }50+}51+```52+53+Other hosts take the same command and arguments.54+55+## Flags56+57+| Flag | Does |58+|---|---|59+| `--read-only` | Offers only the tools that read |60+| `--force` | Lets writes change [protected ranges](../sheets/notes-protection.md#protected-sheets-and-ranges), as `012 set --force` |61+| `--notebooks` | Offers `run_notebook_cell`, which runs a [notebook](../nushell/notebooks.md) cell with nu, if the workbook was saved on this computer |62+| `--trust` | With `--notebooks`, runs the cells of a workbook saved on another computer, and marks it trusted here |63+| `--jev` | Answers [JEV functions](../formulas/jev.md) over the network, each question once a session |64+65+Without them nothing runs a program or reaches the network: notebook66+outputs are read as the file keeps them, and JEV functions show `#N/A`.67+`shell = off` in the [configuration](../reference/config.md#shell) keeps68+notebook cells from running even with `--notebooks`.69+70+## Tools71+72+References are written as in formulas (`B7`, `Q3!A1:C9`,73+`'Q3 plan'!A:A`, a named range, a table, `Sales[Amount]`, a sheet's74+name), and inputs as a person types them, in en-US form. Every write75+takes `dry_run`, which returns the change without making it.76+77+| Tool | Does |78+|---|---|79+| `describe` | The workbook's sheets, used ranges, guessed header rows and column names, tables, outputs, charts, pivots, notebook cells and names, as [`012 describe`](../reference/json.md#describe) |80+| `read_range` | A range's values as rows, its formulas by cell, and with `text` each cell as shown |81+| `evaluate` | A formula's value, computed in the workbook (at `at`, or below the data) without writing it: its text, why it's an error, an array's spill |82+| `find` | Cells by what they show or, with `in_formulas`, their formulas' text, as Edit > Find |83+| `list_errors` | The formulas showing errors after recalculating, as `012 recalc` lists them, without saving |84+| `write_cells` | Entries typed into cells as one change, as `012 set` |85+| `apply_operations` | Several operations as one change: `set`, `clear`, `insert_rows`, `delete_rows`, `insert_columns`, `delete_columns`, `add_sheet`, `rename_sheet`, `delete_sheet`, `define_name`, `sort` |86+| `sort` | A range's rows sorted by columns, named by letter or header |87+| `filter` | A filter on a range by conditions (`gt`, `contains` and the rest) or values to hide, or the sheet's filter removed |88+| `create_chart` | A chart of a range, its type, title and place given or guessed as Insert > Chart guesses them |89+| `create_pivot` | A pivot table on a new sheet: rows, columns and summarized values by header |90+| `run_notebook_cell` | With `--notebooks`: one code cell run, its output kept and sent on to its sheet |91+92+A write returns `saved`, `changes` (as [`012 diff`](../reference/json.md#diff)93+lists them) and `warnings`; a refused one is an error naming the cell,94+with nothing changed. Every result's schema is in95+[JSON output](../reference/json.md#mcp-tools).96+97+## Views in the chat98+99+Hosts that support [MCP Apps](https://github.com/modelcontextprotocol/ext-apps)100+(the `io.modelcontextprotocol/ui` extension) draw what `read_range`101+read and the chart `create_chart` made beside the result, as 012 draws102+them: the [web page](../files/README.md#web-pages) export's grid, with103+its fonts, colors, styles and charts as SVG, in the host's light or104+dark theme. Clicking a cell, or the arrow keys, puts the pointer on it105+and shows what was typed in it.106+107+Both tools name the view's resource, `ui://012/view`108+(`text/html;profile=mcp-app`), in their `_meta`; the host loads it into109+a sandboxed frame, and the result's `_meta` carries what to draw, at110+most 500 rows of a range. Hosts without the extension get the same111+results without it, and the page asks for nothing from the network.112+113+## Resources114+115+Hosts that let people attach data to a conversation list these; the116+scheme is `o12` since a URI's scheme starts with a letter, and a sheet's117+name is percent-encoded:118+119+| URI | Is |120+|---|---|121+| `o12://book/Sheet1!A1:D40` | A range, as `read_range` returns it; each sheet's used range is listed |122+| `o12://book/table/Sales` | A table, header row included; each table is listed |123+| `o12://book/notebook/Notes/2` | A notebook cell's source, and its output as NUON or why it failed; each code cell is listed |124+125+The list follows the workbook: a change that adds a sheet or table126+updates it, and hosts that listen are told.127+128+## Prompts129+130+| Prompt | Asks |131+|---|---|132+| `summarize_workbook` | What each sheet holds and what its numbers say, without changing anything |133+| `fix_errors` | The formulas showing errors explained, fixes checked with `evaluate` and previewed before they're made |134+| `add_column` | A column of formulas computing something beside a range (`range`, `column`) |135+| `chart` | The chart that best answers a question about a range (`range`, `question`) |
M docs/contributing/_category_.json +1 -1
M docs/contributing/limits.md +4 -3
M docs/contributing/ux.md +1 -1
M docs/files/README.md +27 -2
@@ -27,9 +27,10 @@ it back in its format.
2727 | Lotus 1-2-3 `.wk1`, `.wks` | Numbers, labels with their alignment, formats, column widths, formulas translated (references, operators, `@SUM`, `@AVG`, `@IF`, `@ROUND`, `@PMT` and 60 more) or kept as values | |2828 | JSON `.json`, `.ndjson`, `.jsonl` | A list of records (or records one after another, as NDJSON): keys become the header row, numbers, booleans and text keep their types, nested lists and records are their text | The sheet shown as a list of records named by its first row, numbers as numbers |2929 | Nushell `.nuon` | A nushell table with its types: file sizes, durations and dates become numbers in the Size, Duration and Date time formats; see [Nushell types](../nushell/types.md) | The sheet shown as a nushell table, first row as column names, types kept by the cells' formats |30+| Web page `.html` | | The sheet shown as a page in 012's look, for someone without 012: see [Web pages](#web-pages) |3031 31-CSV, TSV, JSON and NUON downloads hold the rows a filter shows, as32-Sheets copies a filtered range; XLSX keeps every row, the hidden ones32+CSV, TSV, JSON, NUON and HTML downloads hold the rows a filter shows,33+as Sheets copies a filtered range; XLSX keeps every row, the hidden ones3334 hidden.3435 3536 Formats other than XLSX import as one sheet named after the file (or the
@@ -66,6 +67,30 @@ the context line says how many rows were left out, e.g. `only the first
6667 Data past the grid's edges is left out the same way. WK1 files keep their6768 own 8,192 by 256. See [Bounds of support](../contributing/limits.md#imports) for speeds.6869 70+## Web pages71+72+A web page download is one `.html` file that needs nothing else: its73+fonts (IBM Plex Mono), styles, charts and a few lines of script are in74+it, so it opens offline and can be mailed or put on any web server. It75+draws the sheet as 012 does: column letters and row numbers, each cell's76+text as the grid shows it at its column's width, with its bold, italic,77+alignment, wrapping, borders, merges, row heights, notes (the `▝` mark,78+the note as its tooltip), tables' header rows and bands, and what79+conditional formats and validation show (fills, color scales, data80+bars, icons, checkboxes, dropdown marks). Charts float over the cells81+at their corner, in their frames, drawn as SVG: shapes rather than82+pixels, sharp at any zoom. The colors are the 16 ANSI colors of 012's83+reference palettes, dark or light as the reader's system prefers.84+85+Clicking a cell, or moving with the arrow keys, puts the pointer on it:86+the name box shows its address and the formula bar what was typed in87+it, a formula rather than its value. A page draws at most 200,00088+cells, blank ones included, and says on standard error or the context89+line how many rows it left out.90+91+`012 export` also writes a range as a page, or one chart alone with92+`--chart` ([Scripts](scripts.md#export)).93+6994 ## More7095 7196 | Page | For |
M docs/files/scripts.md +29 -6
@@ -6,7 +6,8 @@ sidebar_position: 6
66 # Scripts77 88 Four commands read and change a `.012` workbook without the screen, for9-shell scripts, cron jobs, Makefiles and nushell pipelines:9+shell scripts, cron jobs, Makefiles, nushell pipelines and10+[agents](../agents/README.md), which also have `012 describe`:1011 1112 ```sh1213 012 get budget.012 B7 # a cell's value, as the sheet shows it
@@ -97,6 +98,18 @@ An entry a rule only marks invalid is set, with a warning on standard
9798 error. An input that starts with `--` (a flag's shape) comes after `--`:9899 `012 set budget.012 -- A1 --`.99100 101+`--dry-run` checks the entries the same way but saves nothing, and102+prints what would change as [`012 diff`](git.md#012-diff) would:103+104+```105+$ 012 set budget.012 B7 '=SUM(A1:A6)' B8 1200 --dry-run106+Sheet1!B7 input "=SUM(A1:A5)" → "=SUM(A1:A6)"107+Sheet1!B8 input + 1200108+```109+110+`--format json` writes the result, the changes as records, instead111+([JSON output](../reference/json.md#set)).112+100113 ## recalc101114 102115 `012 recalc file` recomputes every formula, saves the file (leaving it
@@ -109,14 +122,24 @@ Q3!D2 #N/A JEV functions need --jev and an API key to be answered
109122 ```110123 111124 It exits 1 when any cell shows an error or a formula reads its own cell,112-so `012 recalc budget.012 && deploy` stops on a broken sheet.125+so `012 recalc budget.012 && deploy` stops on a broken sheet. `--format126+json` writes the list as [JSON](../reference/json.md#recalc).113127 114128 ## export115129 116130 `012 export file out [ref]` writes the workbook in another format, as117131 File > Download does: the format by `out`'s extension or `--format`118-(`csv`, `tsv`, `xlsx`, `sqlite`, `json`, `nuon`). XLSX gets every sheet;119-the others get the sheet shown, or `ref`'s range or sheet. SQLite writes132+(`csv`, `tsv`, `xlsx`, `sqlite`, `json`, `nuon`, `html`). XLSX gets every133+sheet; the others get the sheet shown, or `ref`'s range or sheet. A134+[web page](README.md#web-pages) of a range draws the charts whose corner135+is in it; `--chart` writes one chart alone, found by its number on the136+sheet (1 for the first) or its title:137+138+```sh139+012 export budget.012 q3.html 'Q3 plan'!A1:F20140+012 export budget.012 spending.html Q3 --chart 'Spending by month'141+```142+ SQLite writes120143 a table named by `--table`, replacing one of that name. Formulas are121144 written as their values where the format has no formulas, and a note on122145 standard error says how many. CSV, TSV, JSON and NUON leave out the rows
@@ -150,5 +173,5 @@ things need more than the file:
150173 network, and show `#N/A` here unless `--jev` asks it, with the API key151174 from the environment, the credential store or `jev-api-key-command`.152175 153-`get`, `recalc` and `export` take these flags; `set` computes values only154-to check entries.176+`get`, `recalc`, `export` and `describe` take these flags; `set`177+computes values only to check entries.
M docs/media/notebook-cells-dark.png +0 -0

Binary file.

M docs/media/notebook-cells-light.png +0 -0

Binary file.

A docs/media/notebook-grid-dark.png +0 -0

Binary file.

A docs/media/notebook-grid-light.png +0 -0

Binary file.

M docs/media/notebook-nu-error-dark.png +0 -0

Binary file.

M docs/media/notebook-nu-error-light.png +0 -0

Binary file.

M docs/media/notebook.gif +0 -0

Binary file.

M docs/media/nu-recipe.gif +0 -0

Binary file.

M docs/media/palette-dark.png +0 -0

Binary file.

M docs/media/palette-light.png +0 -0

Binary file.

M docs/nushell/cookbook.md +5 -4
@@ -20,15 +20,16 @@ Money written as text (`"$2,252.50"`) becomes numbers in nushell, and a
2020 second cell totals it by region, sent to a sheet with a chart that2121 follows it.2222 23-![Nushell turns a CSV's money text into numbers, a second cell totals it by region, and its output, sent to a sheet, feeds a column chart](../media/nu-recipe.gif)23+![Nushell turns a CSV's money text into numbers, a second cell totals it by region, and Insert > Chart on its output's grid sends it to a sheet and charts it there](../media/nu-recipe.gif)2424 2525 ```nu2626 sales = open sales.csv | update Revenue { str replace -ar '[$,]' '' | into float }2727 totals = $sales | group-by Region --to-table | update items { get Revenue | math sum } | rename Region Revenue2828 ```2929 30-To chart it, `G` on `totals` sends its output to a new sheet; there,31-**Insert > Chart** charts the table around the pointer. Edit `sales` to30+To chart it, Enter on `totals`'s output, then **Insert > Chart**: the31+output goes to a new sheet named `totals` and the chart goes beside it32+([Outputs as grids](notebooks.md#outputs-as-grids)). Edit `sales` to3233 read another file and run it: `totals` shows `stale` until it runs too3334 (at once in a [reactive notebook](notebooks.md#stale-outputs-and-reactive-notebooks)),3435 and then the sheet and the chart follow.
@@ -89,7 +90,7 @@ http get https://api.github.com/repos/nushell/nushell/issues | select number tit
8990 Sort by comments, filter by author, or make a pivot table of issues by9091 author, in the sheet. In a notebook, the same pipeline without9192 `| sheet view` is a cell that fetches the list again each time it runs;92-Enter on its output opens it full-screen to sort and filter, and93+Enter on its output works in it as a grid, to sort, filter and chart, and9394 `nu-timeout` stops a request that hangs.9495 9596 Nushell: [`http get`](https://www.nushell.sh/commands/docs/http_get.html),
M docs/nushell/notebooks.md +67 -12
@@ -16,7 +16,7 @@ files = ls | where type == file
1616 $files | where size > 1kb | sort-by size --reverse1717 ```1818 19-![A notebook: a cell reads a CSV as sales, a second reads it as $sales, its output is sent to a sheet and summed there, and with the notebook reactive, editing sales runs both again and the sum follows](../media/notebook.gif)19+![A notebook: a cell reads a CSV as sales, a second reads it as $sales, its output is a grid to select in and is sent to a sheet and summed there, and with the notebook reactive, editing sales runs both again and the sum follows](../media/notebook.gif)2020 2121 Open one from a shell with `012 nu`, or from nushell with `sheet nu`2222 (`sheet` comes from 012's nushell module: [Install the `sheet`
@@ -40,8 +40,8 @@ The tab looks and works like Jupyter's: a toolbar over the cells, a
4040 code cell's pipeline in a box with its prompt at the left and a `▶` that4141 runs it at the right, its output under it, and note cells drawn as text.4242 43-![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a table under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-dark.png#gh-dark-mode-only)44-![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a table under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-light.png#gh-light-mode-only)43+![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a grid under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-dark.png#gh-dark-mode-only)44+![A notebook of a note and two code cells: files lists the directory, and the second cell, selected, keeps its files over 1 kB; each output is a grid under its cell, and the toolbar runs, adds and moves cells](../media/notebook-cells-light.png#gh-light-mode-only)4545 4646 ### Reading a cell4747
@@ -56,7 +56,7 @@ reads the same on a terminal without it:
5656 | The prompt | How many runs came before this one: `[2]:`, `[*]:` while it runs, `[ ]:` before it has; `Out[2]:` marks the output of that run |5757 | The box's top border | The cell's name at the left, and at the right how its run stands (below): `waiting`, `running`, ✓ and how long it took, `failed`, `stale`, or `saved` for an output read from the file |5858 | Right of the box | `▶` runs the cell, `■` stops it while it runs |59-| The output | What it is ([below](#outputs)): a table under its header, bold and underlined; `×` before an error; `output hidden`; which rows show in its window |59+| The output | What it is ([below](#outputs)): a table or a record as a grid, its column names where a sheet has letters; `×` before an error; `output hidden`; which rows show in its window. Worked in, `OUTPUT` in the mode indicator, the bar left of it green, and its pointer and selection in reverse video, as on a sheet ([Outputs as grids](#outputs-as-grids)) |6060 | The context line | What the cell reads and how others read it (`big: reads $files; read as $big, nu.big in formulas`), the keys that apply, and what nu says about the cell being written, underlined curly in the cell ([Writing a cell](#writing-a-cell)) |6161 6262 A cell's run goes through these states:
@@ -90,8 +90,8 @@ Outputs are drawn by what they are, with values formatted as cells
9090 9191 | Output | Shows |9292 |---|---|93-| A table (a list of records) | Its columns fitted to their values, numbers right-aligned, under its header |94-| A record | Its fields, one a line: `key value` |93+| A table (a list of records) | 012's grid ([Outputs as grids](#outputs-as-grids)): its columns headed by their names and fitted to their values, its rows numbered from 1 |94+| A record | The same grid of two columns, `field` and `value`, a field a row |9595 | A list | Its items, numbered from 0, as nushell numbers them |9696 | Text | Its lines, wrapped |9797 | A value | As a cell shows it: `4.2 kB`, `9/27/2026 11:27:31` |
@@ -119,11 +119,66 @@ stateDiagram-v2
119119 hidden --> window: o120120 ```121121 122-**Enter** on an output, or a double click, opens it full-screen: arrows123-(or `h` `j` `k` `l`) move, `s` sorts by the pointer's column and `S` in124-descending order (again for the output's own order), `/` keeps the rows125-holding what's typed, and Esc (or `◀ Back`) goes back. The output itself126-doesn't change.122+**Enter** on any other output, or a double click, opens it full-screen,123+its lines scrolled with the arrows; Esc (or `◀ Back`) goes back.124+125+### Outputs as grids126+127+A table or a record is drawn as 012's own grid, the one a sheet has:128+the values are the cells [sending it to a sheet](#send-to-a-sheet)129+makes, each in the format of its type (sizes as `4.2 kB`, durations,130+dates), right-aligned numbers, fitted columns and the grid's row131+numbers, with the table's column names where a sheet has letters.132+133+**Enter** on the output, or a click in it, works in it (the mode134+indicator says `OUTPUT`, and the bar left of it turns green, as for a135+cell edited): an active cell moves with the arrows, and the grid's keys,136+menus and mouse work on it as on a sheet, in its window:137+138+![The output of files worked as a grid: OUTPUT in the mode indicator, the bar left of it green, its first two rows selected and the status line counting them](../media/notebook-grid-dark.png#gh-dark-mode-only)139+![The output of files worked as a grid: OUTPUT in the mode indicator, the bar left of it green, its first two rows selected and the status line counting them](../media/notebook-grid-light.png#gh-light-mode-only)140+141+- Shift+arrows, Ctrl+A or a drag select a range, and the status line142+ shows its Sum, Avg and Count; Ctrl+C copies it, as TSV to the system143+ clipboard and with its formats for Ctrl+V on a sheet.144+- **Data > Sort sheet** (or the column's right-click menu) sorts by the145+ active column, **Data > Create a filter** puts `▾` on each column's146+ name, and Alt+Down (or a click on `▾`) opens the column's filter;147+ Ctrl+F finds.148+- Drag the right edge of a column's name, or **Format > Column width**,149+ to resize it; Shift+wheel scrolls a wide table sideways; the names150+ stay on top as the rows scroll.151+- Ctrl+Z undoes a sort, a filter or a width; typing, Del, paste and152+ formats are refused, as they'd change the output: `G` sends it to a153+ sheet, where its copy can change.154+- **Enter** shows the grid full-screen, where it all works the same;155+ **Esc** deselects, then goes back from full-screen, then back to the156+ notebook.157+158+```mermaid159+stateDiagram-v2160+ selected: output selected (NOTEBOOK)161+ window: its grid, in its window (OUTPUT)162+ full: its grid, full-screen (OUTPUT)163+ selected --> window: Enter, a click in it164+ window --> full: Enter, a double click165+ full --> window: Esc166+ window --> selected: Esc167+```168+169+Sorting and filtering act on the grid's copy: the output, what later170+cells read as `$name`, doesn't change, and running the cell again171+draws its new output afresh.172+173+**Insert > Chart**, **Data > Pivot table** and the frequency table174+(Alt+Shift+F) on the grid make them where charts and pivot tables live,175+on a sheet: the output is [sent to a sheet](#send-to-a-sheet) first (a new176+one named after the cell, unless it's on one already), and the command177+runs there on the columns selected in the grid, every row under the178+header. A chart drawn under the output would have to squeeze into the179+notebook's column and scroll with the cells; on the sheet it has room,180+its editor, images where the terminal draws them, and it follows the181+cell's next run, as the region it charts does.127182 128183 ### Note cells129184
@@ -158,7 +213,7 @@ delete, copy, cut, move, make notes or code, hide or clear outputs.
158213 | Up, Down, `j`, `k` | Move between cells, stopping at each output; on an output, scroll its window first |159214 | Shift+Up, Shift+Down, `K`, `J` | Select the cells passed over too |160215 | Home, End, PgUp, PgDn | The first cell, the last, a screen up or down |161-| Enter | Edit the cell; on an output, open it full-screen |216+| Enter | Edit the cell; on a table or record output, work in its grid; on another, open it full-screen |162217 | Shift+Enter | Run the cells and select the next, adding one at the end |163218 | Ctrl+Enter, `r` | Run the cells, staying on them |164219 | Alt+Enter | Run the cells and add a code cell under them |
M docs/reference/README.md +1 -0
M docs/reference/_category_.json +1 -1
M docs/reference/command-line.md +14 -6
@@ -25,18 +25,21 @@ The flags are the options' flags, listed in [Configuration](config.md#options).
2525 | Command | Does |2626 |---|---|2727 | `012 get file.012 [ref]` | Writes a cell's value, or a range or sheet as a table: [Scripts](../files/scripts.md#get) |28-| `012 set file.012 ref input [ref input ...]` | Types entries into cells and saves: [Scripts](../files/scripts.md#set) |28+| `012 set file.012 ref input [ref input ...]` | Types entries into cells and saves, or with `--dry-run` prints the change: [Scripts](../files/scripts.md#set) |2929 | `012 recalc file.012` | Recalculates, saves and lists the cells showing errors: [Scripts](../files/scripts.md#recalc) |3030 | `012 export file.012 out [ref]` | Writes the workbook, a sheet or a range in another format: [Scripts](../files/scripts.md#export) |31+| `012 describe file.012` | Lists the sheets and what's on them: [Agents](../agents/README.md#with-a-shell) |32+| `012 mcp file.012` | Serves the workbook to MCP hosts over standard input and output: [MCP server](../agents/mcp.md) |3133 | `012 diff a.012 b.012` | Lists what changed, cell by cell: [Diff and merge in git](../files/git.md#012-diff) |3234 | `012 diff --textconv file.012` | Writes a workbook as lines, for git's textconv: [Diff and merge in git](../files/git.md#git) |3335 | `012 merge-driver base ours theirs [path]` | Merges theirs into ours, for git: [Diff and merge in git](../files/git.md#merging) |3436 | `012 nu --module`, `012 nu --install-module [--force] [path]` | Prints or installs the nushell module: [Nushell](../nushell/README.md#install-the-sheet-command) |37+| `012 agent --skill`, `012 agent --install-skill [--force] [dir]` | Prints or installs the Claude Code skill: [Agents](../agents/README.md#the-claude-code-skill) |3538 | `012 config [path\|edit\|default\|themes\|set-key\|delete-key]` | The settings: [Configuration](config.md#commands) |36-| `012 version` | Prints the version |39+| `012 version [--format text\|json\|nuon]` | Prints the version |3740 38-`get`, `set`, `recalc`, `export`, `diff` and `merge-driver` take their39-flags anywhere after the command's name, and `--help` prints their41+`get`, `set`, `recalc`, `export`, `describe`, `mcp`, `diff`,42+`merge-driver` and `agent` take their flags anywhere after the command's name, and `--help` prints their4043 usage. `--` ends the flags, so what follows is taken as it is4144 (`012 set book.012 -- A1 --`), and an argument such as `-5` is never a4245 flag.
@@ -47,10 +50,15 @@ flag.
4750 | `--input` | `get` | What was typed (a formula) rather than its value |4851 | `--no-header` | `get` | JSON and NUON columns named by their letters, the first row a record |4952 | `--force` | `set` | Sets cells in protected ranges |53+| `--dry-run` | `set` | Prints what would change, as `012 diff` would, and saves nothing |54+| `--format text\|json\|nuon` | `set`, `recalc`, `describe`, `merge-driver`, `version` | The result as text, or as [JSON or NUON](json.md) |55+| `--report json\|nuon` | `export` | Writes what was exported as [JSON or NUON](json.md#export) |5056 | `--format kind`, `--table name` | `export` | The format when the file's extension doesn't say; SQLite's table |51-| `--notebooks` | `get`, `recalc`, `export` | Runs the notebooks' cells first, when the file is trusted here |57+| `--chart n\|title` | `export` | One chart of the sheet as a web page, by its number or title |58+| `--notebooks` | `get`, `recalc`, `export`, `describe` | Runs the notebooks' cells first, when the file is trusted here |5259 | `--trust` | with `--notebooks` | Runs the cells of a file saved on another computer |53-| `--jev` | `get`, `recalc`, `export` | Asks JEV for the JEV functions' answers first |60+| `--read-only`, `--force`, `--notebooks`, `--jev` | `mcp` | The tools offered and what they may do: [MCP server](../agents/mcp.md#flags) |61+| `--jev` | `get`, `recalc`, `export`, `describe` | Asks JEV for the JEV functions' answers first |5462 | `--format text\|json\|nuon` | `diff` | The form of the changes; text by default |5563 | `--color auto\|always\|never` | `diff` | Colors the text; auto colors on a terminal or git's pager unless `NO_COLOR` is set |5664
A docs/reference/json.md +169 -0
@@ -0,0 +1,169 @@
1+---2+title: "JSON output"3+sidebar_position: 74+---5+6+# JSON output7+8+Commands without the screen write their results as JSON with9+`--format json`, or as NUON (the same values, as nushell reads them)10+with `--format nuon`; `012 export` writes to a file, so its result11+comes with `--report json`. The schemas below are stable: a later 01212+may add fields, but never renames or removes one, or changes its type.13+Errors are not JSON: they go to standard error as text, with the exit14+statuses in [Command line](command-line.md#exit-status).15+16+## get17+18+`012 get file ref --format json` writes a cell's value alone (a number,19+a string, `true`, `null` for a blank cell), or a range as a list of20+records named by its first row (`--no-header`: by column letters), as21+[Scripts](../files/scripts.md#get) describes. Dates are strings in ISO22+8601, and in NUON dates, file sizes and durations keep their types.23+24+## set25+26+```json27+{28+ "file": "book.012",29+ "saved": true,30+ "changes": [31+ {"kind": "cell", "sheet": "Sheet1", "item": "B7", "field": "input", "old": "12", "new": "=SUM(B1:B6)"}32+ ],33+ "warnings": ["Sheet1!C2: Enter a number between 1 and 10"]34+}35+```36+37+| Field | Is |38+|---|---|39+| `file` | The workbook's path, as given |40+| `saved` | Whether the file was written: false with `--dry-run` |41+| `changes` | What changed, as [`diff`](#diff) lists it |42+| `warnings` | Entries a validation rule marks invalid but lets in |43+44+## recalc45+46+```json47+{48+ "file": "book.012",49+ "errors": [50+ {"cell": "Q3!B7", "sheet": "Q3", "addr": "B7", "value": "#DIV/0!", "why": "Division by zero in B6/C6", "jev": false}51+ ],52+ "circular": false,53+ "notebook_failures": []54+}55+```56+57+`errors` are the formulas showing errors, sheet by sheet and row by58+row; `why` is what the screen's context line says, or `""`; `jev` is59+set for a JEV function's error that `--jev` would answer. `circular` is60+set when a formula reads its own cell. `notebook_failures` are the61+lines `--notebooks` reported for cells that failed. The exit status is62+1 when there are errors, as without `--format`.63+64+## describe65+66+```json67+{68+ "sheets": [69+ {70+ "name": "Sales", "kind": "sheet", "shown": true, "hidden": false,71+ "used": "A1:F9", "rows": 9, "cols": 6, "cells": 54, "formulas": 9, "errors": 0,72+ "header_row": 1, "columns": ["Date", "Region", "Units", "Price", "Total", "Share"],73+ "frozen": [1, 0], "filter": "",74+ "tables": [{"name": "Orders", "range": "A1:F9", "columns": ["Date", "Region", "Units", "Price", "Total", "Share"]}],75+ "regions": [{"name": "files", "kind": "output", "range": "H1:J12"}],76+ "charts": [{"number": 1, "title": "Units by date", "type": "column", "data": "A1:C9", "at": "H2"}]77+ }78+ ],79+ "names": [{"name": "Rate", "range": "Sales!B12"}]80+}81+```82+83+| Field | Is |84+|---|---|85+| `kind` | `sheet`, `notebook` or `pivot` |86+| `shown`, `hidden` | The sheet shown when the file was saved; a hidden tab |87+| `used` | A1 to the last cell with contents, `""` for an empty sheet; `rows` and `cols` its size |88+| `cells`, `formulas`, `errors` | Cells with contents, formulas, and formulas showing errors; `formulas` and `errors` are -1 on sheets of over a million cells, which aren't counted |89+| `header_row`, `columns` | The row guessed to name the columns (1 for the first; 0 and `[]` when none) and its names, `""` for a blank cell |90+| `frozen` | Frozen rows and columns |91+| `filter` | The filtered range, or `""` |92+| `tables` | Named tables, header row included in `range` |93+| `regions` | Notebook outputs (`kind` `output`) and linked files (`linked`, with `file`) sent to the sheet, with the range their rows fill |94+| `charts` | Each chart's `number` (for `012 export --chart`), title (its type's name when it has none), `type`, `data` range and `at`, the cell under its top-left corner |95+| `pivot` | On a pivot table, `{"source": "Sales!A1:F9"}` |96+| `notebook_cells` | On a notebook, each cell: `number`, `kind` (`code` or `note`), `name` (its output's), `source`, and for code `state` (`ran`, `failed`, `not run`) and `error` |97+| `names` | Named ranges, `range` `#REF!` when its cells were deleted |98+99+## diff100+101+`012 diff a b --format json` writes a list of changes:102+103+| Field | Is |104+|---|---|105+| `kind` | `cell`, `sheet`, `region`, `table`, `layout` (another field of a sheet: widths, rules, charts), `name`, `macro`, `notebook` or `workbook` (its locale, its arithmetic) |106+| `sheet` | The sheet, by its name in the second workbook where it has one |107+| `item` | The cell, region, name, macro or field that changed |108+| `field` | What about it: for a cell `input`, `value`, `format` or `note`; for a sheet `added`, `removed`, `renamed` or `moved` |109+| `old`, `new` | Its values, `null` where it wasn't or isn't there |110+111+See [Diff and merge in git](../files/git.md#012-diff).112+113+## export114+115+`012 export file out --report json`:116+117+```json118+{"file": "out.csv", "format": "csv", "rows": 9, "notes": ["1 formula saved as values"]}119+```120+121+## merge-driver122+123+`012 merge-driver base ours theirs --format json` writes124+`{"conflicts": [...]}`, each with `where`, `field`, and the `base`,125+`ours` and `theirs` versions as text (`""` where it isn't there), and126+`what` for a conflict about a whole sheet. The merge and exit status127+are as without it.128+129+## MCP tools130+131+The [MCP server](../agents/mcp.md)'s tools return these, as structured132+content with the same JSON as text beside it. `describe` returns133+[describe's](#describe) schema, `list_errors` recalc's `errors` and134+`circular`.135+136+`read_range`, and the range resources:137+138+```json139+{140+ "range": "Sales!A1:C3", "rows": 3, "cols": 3,141+ "values": [["Region", "Units", "Price"], ["North", 3, 12.5], ["South", 5, null]],142+ "text": [["Region", "Units", "Price"], ["North", "3", "$12.50"], ["South", "5", ""]],143+ "formulas": {"C3": "=IF(B3>4, \"\", 9.75)"},144+ "truncated": false145+}146+```147+148+`values` are typed as [`get`](#get) types one cell (blank is `null`, an149+error its text); `text` comes only when asked for; `truncated` is set150+when the range held more cells than `max_cells`, and `rows` says how151+many came back.152+153+Writes (`write_cells`, `apply_operations`, `sort`, `filter`) return154+`{"saved", "changes", "warnings"}` as [`set`](#set) does, `saved` false155+for a dry run or a change that changed nothing; `create_chart` adds156+`"chart": {"sheet", "number", "title"}` and `create_pivot` `"sheet"`,157+the pivot's.158+159+| Tool | Returns |160+|---|---|161+| `evaluate` | `cell` where it was computed, `value`, `text` as shown, `error` explaining an error value, and `spill`, a `read_range` result, when the formula spilled |162+| `find` | `matches`, each `cell`, `text` and `input`, the first `limit` of them, and `total` |163+| `run_notebook_cell` | `notebook`, `cell`, `name`, `state` (`ran` or `failed`), `error`, `output` as NUON and `cut` when the output was longer than 64 KB |164+165+## version166+167+```json168+{"version": "v0.9.0", "go": "go1.27.1", "os": "darwin", "arch": "arm64"}169+```
M docs/reference/keys.md +15 -6
@@ -147,7 +147,7 @@ on a sheet, `!` starts an entry as any character does.
147147 | Up, Down, `j`, `k`, Home, End, PgUp, PgDn | Move between cells and their outputs; on an output, Up and Down scroll its window first |148148 | Shift+Up, Shift+Down, `K`, `J` | Select the cells passed over too, to run, delete, copy or move together |149149 | Alt+Up, Alt+Down, Ctrl+Shift+Up, Ctrl+Shift+Down | Move the selected cells up or down |150-| Enter | Edit the cell; on an output, open it full-screen |150+| Enter | Edit the cell; on a table or record output, work in its grid; on another output, open it full-screen |151151 | Shift+Enter, Ctrl+Enter, `r`, Alt+Enter | Run the cells and select the next; run them in place (`r` too); run them and add a cell under them |152152 | F9 | Run every cell |153153 | `a`, `b`, `!` | Add a code cell above, below; add one below and edit it |
@@ -167,11 +167,19 @@ on a sheet, `!` starts an entry as any character does.
167167 | Up, Down, Home, End, Ctrl+A, Ctrl+E | Move by the lines on screen; the start, the end of the line |168168 | Word keys | As [anywhere text is edited](#entering-data); Ctrl+U deletes to the start of the line, not the cell |169169 170-| Key | On an output full-screen |170+| Key | In a table's or record's output ([its grid](../nushell/notebooks.md#outputs-as-grids)) |171171 |---|---|172-| Arrows, `h`, `j`, `k`, `l`, PgUp, PgDn, `g`, `G` | Move |173-| `s`, `S` | Sort by the pointer's column, A to Z or Z to A; again for the output's order |174-| `/` | Keep the rows holding what's typed; Esc clears it |172+| Arrows, Shift+arrows, Ctrl+arrows, PgUp, PgDn, Ctrl+A | Move and select, as [on a sheet](#selecting); the status line shows Sum, Avg and Count |173+| Ctrl+C | Copy the selection, to paste on a sheet or elsewhere |174+| Ctrl+F | Find in the output |175+| Alt+Down | With a filter on (Data > Create a filter), the column's filter |176+| Ctrl+Z, Ctrl+Y | Undo, redo a sort, a filter or a column's width |177+| Enter | Show the grid full-screen |178+| Esc | Deselect; then back from full-screen, then back to the notebook |179+180+| Key | On any other output full-screen |181+|---|---|182+| Up, Down, `j`, `k`, PgUp, PgDn, `g`, `G` | Move |175183 | Esc, `q` | Back to the notebook |176184 177185 ## Keys the terminal has to tell apart
@@ -323,7 +331,8 @@ On a notebook's tab, as in JupyterLab:
323331 | Click a cell; Shift+click | Select it; select the cells between too |324332 | Click in a code cell's box; double-click a note | Edit it, the caret where you clicked |325333 | Click `▶` (`■` while it runs) | Run the cell (stop it) |326-| Click an output; double-click it | Select it; open it full-screen |334+| Click an output; double-click it | Select it (in a table's or record's grid, the cell clicked, to work in it); open it full-screen |335+| Drag in an output's grid; drag its column header's right edge | Select cells; resize the column |327336 | Click left of an output | Hide it, or show it again |328337 | Wheel over an output's window | Scroll the output, then the notebook |329338 | Click a toolbar button | Run, stop, restart, run all, add, cut, copy, paste, or pick the cell's kind |
M e2e/crash_test.go +5 -2
M e2e/jupyter_test.go +33 -0
@@ -49,6 +49,39 @@ func (s *session) codes() []string {
4949 return out5050 }5151 52+// An output is 012's grid: Enter works in it, Shift+arrows select,53+// Ctrl+C copies, the palette's sort sorts it, a click moves the active54+// cell, Enter shows it full-screen and Esc goes back a level at a time.55+func TestNotebookOutputGrid(t *testing.T) {56+ s := startWith(t, options{cols: 100, rows: 40, startsOn: "EDIT", env: fakeNu}, "nu")57+ clip := s.watchClipboard()58+ s.keys("files = ls", "<ctrl+enter>")59+ s.waitFor("Out[1]:")60+ s.keys("<esc>", "<down>", "<enter>")61+ s.waitFor("OUTPUT")62+ s.keys("<shift+down>", "<shift+right>", "<ctrl+c>")63+ s.eventually("the rows copied", func() bool { return clip.get() == "012\tfile\nCLAUDE.md\tfile" })64+ s.waitFor("name to type, rows 1 to 2")65+ s.keys("<esc>", "<right>", "<right>", "<ctrl+k>", "Sort sheet Z to A", "<enter>")66+ s.eventually("sorted by size", func() bool {67+ _, first := s.rowOf("README.md")68+ _, last := s.rowOf("go.mod")69+ return first < last && strings.Contains(s.line(first), " 1 README.md")70+ })71+ col, row := s.rowOf("demos")72+ s.leftClick(col+1, row, 0)73+ s.keys("<ctrl+c>")74+ s.eventually("the cell clicked copied", func() bool { return clip.get() == "demos" })75+ s.keys("<enter>")76+ s.waitFor("files [1], full-screen")77+ s.keys("<esc>")78+ s.eventually("back in the window", func() bool {79+ return !strings.Contains(s.screen(), "full-screen") || strings.Contains(s.screen(), "[1]:")80+ })81+ s.keys("<esc>")82+ s.waitFor("NOTEBOOK")83+}84+5285 func TestNotebookMouseAndKeys(t *testing.T) {5386 s := startWith(t, options{cols: 100, rows: 40, startsOn: "EDIT", env: fakeNu}, "nu")5487 s.keys("files = ls", "<esc>")
M e2e/screennotebook_test.go +17 -4
@@ -10,8 +10,9 @@ import (
1010 // Golden screens for notebooks: cells with a note and table outputs, a1111 // cell edited with a long pipeline wrapped (at 80 and 60 columns), a1212 // failure, nu's highlighting and a problem nu found, a cell running and13-// one waiting, stale outputs, an output full-screen, and an output sent14-// to a sheet. Each is recorded on a light terminal and in the13+// one waiting, stale outputs, an output's grid entered with a range14+// selected, its filter open, and full-screen, and an output sent to a15+// sheet. Each is recorded on a light terminal and in the1516 // high-contrast theme too. nu is testdata/nu/nu, which answers what the1617 // screens run, and what the code editor asks, with fixed outputs.1718
@@ -91,8 +92,20 @@ var notebookScreens = []screen{
9192 }},9293 {name: "notebook-output", setup: func(s *session) {9394 filesNotebook(s)94- s.keys("<up>", "<up>", "<up>", "<enter>")95- s.waitFor("full-screen")95+ s.keys("<up>", "<up>", "<up>", "<enter>", "<enter>")96+ s.waitFor("◀ Back")97+ }},98+ {name: "notebook-grid", setup: func(s *session) {99+ filesNotebook(s)100+ s.keys("<up>", "<up>", "<up>", "<enter>", "<shift+down>", "<shift+right>", "<shift+right>")101+ s.waitFor("Count 6")102+ }},103+ {name: "notebook-grid-filter", setup: func(s *session) {104+ filesNotebook(s)105+ s.keys("<up>", "<up>", "<up>", "<enter>", "<ctrl+k>", "Create a filter", "<enter>")106+ s.waitFor("▾")107+ s.keys("<right>", "<alt+down>")108+ s.waitFor("Select all")96109 }},97110 {name: "notebook-nu-highlight", setup: func(s *session) {98111 filesNotebook(s)
M e2e/stills_test.go +1 -0
M e2e/testdata/screens/docs-notebook-cells-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────╮</span>2626 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">shortcuts</span></pre>\ No newline at end of file
M e2e/testdata/screens/docs-notebook-cells.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────╮</span>2626 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">shortcuts</span></pre>\ No newline at end of file
A e2e/testdata/screens/docs-notebook-grid-light.html +24 -0
@@ -0,0 +1,24 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+ <span style="color:var(--vt-palette-0)">Output</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">───────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+F</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">find</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">full-screen</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.5+6+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>7+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>8+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>9+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B15+16+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>17+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>18+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>19+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>20+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB23+24+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-0)">Count</span> 6</pre>\ No newline at end of file
A e2e/testdata/screens/docs-notebook-grid.html +24 -0
@@ -0,0 +1,24 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+ <span style="color:var(--vt-palette-8)">Output</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">───────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+F</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">find</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">full-screen</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.5+6+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>7+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>8+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>9+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B15+16+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>17+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>18+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>19+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>20+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB23+24+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-8)">Count</span> 6</pre>\ No newline at end of file
M e2e/testdata/screens/docs-notebook-nu-error-light.html +4 -4
@@ -5,10 +5,10 @@
55 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>66 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>77 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>8- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>9- 012 file 4.2 kB10- README.md file 9.8 kB11- demos dir 3.1 kB8+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>9+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB10+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1212 1313 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>1414 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/docs-notebook-nu-error.html +4 -4
@@ -5,10 +5,10 @@
55 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>66 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>77 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>8- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>9- 012 file 4.2 kB10- README.md file 9.8 kB11- demos dir 3.1 kB8+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>9+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB10+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1212 1313 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>1414 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/docs-palette-light.html +2 -2
@@ -13,6 +13,6 @@
1313 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as SQLite <span style="color:var(--vt-palette-0)">File</span> <span style="color:var(--vt-palette-0)">›</span> <span style="color:var(--vt-palette-0)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1414 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as JSON <span style="color:var(--vt-palette-0)">File</span> <span style="color:var(--vt-palette-0)">›</span> <span style="color:var(--vt-palette-0)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as NUON <span style="color:var(--vt-palette-0)">File</span> <span style="color:var(--vt-palette-0)">›</span> <span style="color:var(--vt-palette-0)">Download</span> <span style="color:var(--vt-palette-8)">│</span>16-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">│</span> Decimal arithmetic <span style="color:var(--vt-palette-0)">File</span> <span style="color:var(--vt-palette-0)">›</span> <span style="color:var(--vt-palette-0)">Settings</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">225</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>16+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as HTML <span style="color:var(--vt-palette-0)">File</span> <span style="color:var(--vt-palette-0)">›</span> <span style="color:var(--vt-palette-0)">Download</span> <span style="color:var(--vt-palette-8)">│</span>17+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">226</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 Start a new, empty sheet <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Up/Down</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">move</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">run</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">close</span></pre>\ No newline at end of file
M e2e/testdata/screens/docs-palette.html +2 -2
@@ -13,6 +13,6 @@
1313 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as SQLite <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1414 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as JSON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as NUON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>16-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">│</span> Decimal arithmetic <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Settings</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>16+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">│</span> Download as HTML <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>17+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 Start a new, empty sheet <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Up/Down</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">move</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">run</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">close</span></pre>\ No newline at end of file
M e2e/testdata/screens/menu-download.html +2 -2
@@ -12,8 +12,8 @@
1212 <span style="color:var(--vt-palette-8)">├─────────────────────┤│</span> SQLite database (.sqlite) <span style="color:var(--vt-palette-8)">│</span>1313 <span style="color:var(--vt-palette-8)">│</span> Quit <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+Q</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">││</span> JSON list of records (.json) <span style="color:var(--vt-palette-8)">│</span>1414 <span style="color:var(--vt-palette-8)">└─────────────────────┘│</span> Nushell table (.nuon) <span style="color:var(--vt-palette-8)">│</span>15-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└──────────────────────────────────┘</span>16-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span>15+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Web page (.html) <span style="color:var(--vt-palette-8)">│</span>16+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└──────────────────────────────────┘</span>1717 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>
M e2e/testdata/screens/notebook-cells-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>1919 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-cells-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-cells.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>1919 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-error-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">failed</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>2626 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">lss</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">-a</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>
M e2e/testdata/screens/notebook-error-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3)">failed</span> <span style="color:var(--vt-palette-3)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>2626 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">lss</span> -a <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
M e2e/testdata/screens/notebook-error.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3)">failed</span> <span style="color:var(--vt-palette-3)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>2626 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-6)">lss</span> -a <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
A e2e/testdata/screens/notebook-grid-filter-high-contrast.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">FILTER</span><span style="background:#40e0ff"> </span>2+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">Files</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">What&#39;s</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">the</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">repo,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">from</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="color:#ffffff;background:#000000">.</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>9+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">▾</span><span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">type</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">▾</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">▾</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">┌─</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">Filter</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">type</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────┐</span><span style="background:#000000"> </span>12+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">If</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#3a3a3a">‹</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">None</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">›</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>13+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">├────────────────────────────────────┤</span><span style="background:#000000"> </span>14+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">›</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Search</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">values</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>15+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">├────────────────────────────────────┤</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">[x]</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">Select</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">all</span><span style="background:#40e0ff"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">[x]</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">1</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│──────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">si</span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">[x]</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>19+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────└───────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─┘──────────────────────────────╯</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>24+<span style="background:#000000"> </span>25+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>26+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>27+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>28+<span style="background:#000000"> </span>29+<span style="background:#000000"> </span>30+<span style="color:#959595;background:#1f1f1f">Type</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">to</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">the</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">values</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Space</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">check</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Tab</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">condition</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">apply</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">cancel</span><span style="background:#1f1f1f"> </span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-filter-light.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">FILTER</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">▾</span><span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">type</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">▾</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">▾</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span> 012 <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Filter</span> <span style="font-weight:bold">type</span> <span style="color:var(--vt-palette-8)">──────────────────────┐</span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">If</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">‹</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">None</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">›</span> <span style="color:var(--vt-palette-8)">│</span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos <span style="color:var(--vt-palette-8)">│</span> <span style="font-weight:bold">›</span> <span style="color:var(--vt-palette-0)">Search</span> <span style="color:var(--vt-palette-0)">values</span> <span style="color:var(--vt-palette-8)">│</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>16+ <span style="color:var(--vt-palette-8)">│</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">[x]</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">Select</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">all</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-8)">│</span>17+ <span style="color:var(--vt-palette-8)">╭──────────────────│</span> [x] dir <span style="color:var(--vt-palette-0)">1</span> <span style="color:var(--vt-palette-8)">│──────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> si<span style="color:var(--vt-palette-8)">│</span> [x] file <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────└───────────────────────────</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-8)">─┘──────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="color:var(--vt-palette-0)">Type</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">search</span> <span style="color:var(--vt-palette-0)">the</span> <span style="color:var(--vt-palette-0)">values</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Space</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">check</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Tab</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">condition</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">apply</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">cancel</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-filter.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">FILTER</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">▾</span><span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">type</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">▾</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">▾</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span> 012 <span style="color:var(--vt-palette-8)">┌─</span> <span style="font-weight:bold">Filter</span> <span style="font-weight:bold">type</span> <span style="color:var(--vt-palette-8)">──────────────────────┐</span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">If</span> <span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">‹</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">None</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">│</span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos <span style="color:var(--vt-palette-8)">│</span> <span style="font-weight:bold">›</span> <span style="color:var(--vt-palette-8)">Search</span> <span style="color:var(--vt-palette-8)">values</span> <span style="color:var(--vt-palette-8)">│</span>15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod <span style="color:var(--vt-palette-8)">├────────────────────────────────────┤</span>16+ <span style="color:var(--vt-palette-8)">│</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">[x]</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">Select</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">all</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-8)">│</span>17+ <span style="color:var(--vt-palette-8)">╭──────────────────│</span> [x] dir <span style="color:var(--vt-palette-8)">1</span> <span style="color:var(--vt-palette-8)">│──────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> si<span style="color:var(--vt-palette-8)">│</span> [x] file <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────└───────────────────────────</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">─┘──────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="color:var(--vt-palette-8)">Type</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">search</span> <span style="color:var(--vt-palette-8)">the</span> <span style="color:var(--vt-palette-8)">values</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Space</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">check</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Tab</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">condition</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">apply</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">cancel</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-high-contrast.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">OUTPUT</span><span style="background:#40e0ff"> </span>2+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Output</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+C</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">copy</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+F</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">find</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">full-screen</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">Files</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">What&#39;s</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">the</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">repo,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">from</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="color:#ffffff;background:#000000">.</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>9+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">type</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">size</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>11+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">file</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">4.2</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">kB</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>12+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">2</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">CLAUDE.md</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">file</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">1.0</span><span style="background:#0033cc"> </span><span style="color:#ffffff;background:#0033cc">kB</span><span style="background:#0033cc"> </span><span style="background:#000000"> </span>13+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>19+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>24+<span style="background:#000000"> </span>25+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>26+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>27+<span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>28+<span style="background:#000000"> </span>29+<span style="background:#000000"> </span>30+<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">name</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">to</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">size,</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">rows</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">1</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">to</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;font-weight:bold">2</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Sum</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">5200</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Avg</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">2600</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">Count</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">6</span></pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid-light.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3+ <span style="color:var(--vt-palette-0)">Output</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+C</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">copy</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+F</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">find</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">full-screen</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-4)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B16+17+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-0)">Sum</span> 5200 <span style="color:var(--vt-palette-0)">Avg</span> 2600 <span style="color:var(--vt-palette-0)">Count</span> 6</pre>\ No newline at end of file
A e2e/testdata/screens/notebook-grid.html +30 -0
@@ -0,0 +1,30 @@
1+<pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>2+ ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3+ <span style="color:var(--vt-palette-8)">Output</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+C</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">copy</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+F</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">find</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">full-screen</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4+ <span style="font-weight:bold;text-decoration:underline">Files</span>5+ What&#39;s big in the repo, from <span style="color:var(--vt-palette-6)">ls</span>.6+7+ <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>8+ <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>9+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10+<span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">type</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">size</span><span style="background:var(--vt-palette-4)"> </span>11+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">4.2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>12+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">2</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">CLAUDE.md</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">file</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">1.0</span><span style="background:var(--vt-palette-4)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-4)">kB</span><span style="background:var(--vt-palette-4)"> </span>13+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-2)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B16+17+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>18+ <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>19+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB24+25+ <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>26+ <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>27+ <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>28+29+30+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="font-weight:bold">name</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">size,</span> <span style="font-weight:bold">rows</span> <span style="font-weight:bold">1</span> <span style="font-weight:bold">to</span> <span style="font-weight:bold">2</span> <span style="color:var(--vt-palette-8)">Sum</span> 5200 <span style="color:var(--vt-palette-8)">Avg</span> 2600 <span style="color:var(--vt-palette-8)">Count</span> 6</pre>\ No newline at end of file
M e2e/testdata/screens/notebook-nu-error-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2626 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sort-by</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;text-decoration:underline wavy #ff8080">--revrse</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-nu-error-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-error.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> <span style="text-decoration:underline wavy var(--vt-palette-1)">--revrse</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-highlight-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2626 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">big</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sort-by</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">--reverse</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000;font-style:italic">#</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000;font-style:italic">largest</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-nu-highlight-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">big</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> <span style="color:var(--vt-palette-5)">size</span> <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> --reverse <span style="color:var(--vt-palette-0);font-style:italic">#</span> <span style="color:var(--vt-palette-0);font-style:italic">largest</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-nu-highlight.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- CLAUDE.md file 1.0 kB13- README.md file 9.8 kB14- demos dir 3.1 kB15- go.mod file 812 B10+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2626 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">big</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> <span style="color:var(--vt-palette-5)">size</span> <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">sort-by</span> <span style="color:var(--vt-palette-2)">size</span> --reverse <span style="color:var(--vt-palette-8);font-style:italic">#</span> <span style="color:var(--vt-palette-8);font-style:italic">largest</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-output-high-contrast.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">OUTPUT</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">◀</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Back</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">[1]</span><span style="color:#959595;background:#000000">,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">full-screen</span><span style="background:#000000"> </span>3-<span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">s</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sort</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">S</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">descending</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">/</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">filter</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span>4-<span style="background:#3a3a3a"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5-<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#000000"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Output</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Shift+arrows</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">select</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+C</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">copy</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+F</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">find</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">back</span><span style="background:#000000"> </span>4+<span style="background:#3a3a3a"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">name</span><span style="background:#40e0ff"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5+<span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">1</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff">012</span><span style="background:#40e0ff"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1010 <span style="background:#000000"> </span>1111 <span style="background:#000000"> </span>1212 <span style="background:#000000"> </span>
M e2e/testdata/screens/notebook-output-light.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>22 ◀ Back <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="font-weight:bold">files</span> <span style="font-weight:bold">[1]</span><span style="color:var(--vt-palette-0)">,</span> <span style="color:var(--vt-palette-0)">full-screen</span>3-<span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-0)">[1]</span> <span style="color:var(--vt-palette-0)">5</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">s</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">sort</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">S</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">descending</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">filter</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5-<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span> CLAUDE.md file 1.0 kB7-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span> README.md file 9.8 kB8-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span> demos dir 3.1 kB9-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span> go.mod file 812 B3+ <span style="color:var(--vt-palette-0)">Output</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Shift+arrows</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">select</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+C</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">copy</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+F</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">find</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">back</span>4+<span style="background:var(--vt-palette-7)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB7+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB8+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB9+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1010 1111 1212
M e2e/testdata/screens/notebook-output.html +7 -7
@@ -1,12 +1,12 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">OUTPUT</span><span style="background:var(--vt-palette-6)"> </span>22 ◀ Back <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="font-weight:bold">files</span> <span style="font-weight:bold">[1]</span><span style="color:var(--vt-palette-8)">,</span> <span style="color:var(--vt-palette-8)">full-screen</span>3-<span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">[1]</span> <span style="color:var(--vt-palette-8)">5</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">s</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">sort</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">S</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">descending</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">filter</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5-<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span> <span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span> CLAUDE.md file 1.0 kB7-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span> README.md file 9.8 kB8-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span> demos dir 3.1 kB9-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span> go.mod file 812 B3+ <span style="color:var(--vt-palette-8)">Output</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Shift+arrows</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">select</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+C</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">copy</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+F</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">find</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">back</span>4+<span style="background:var(--vt-palette-8)"> </span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">name</span><span style="background:var(--vt-palette-6)"> </span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5+<span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">1</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6)">012</span><span style="background:var(--vt-palette-6)"> </span> file 4.2 kB6+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB7+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB8+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB9+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1010 1111 1212
M e2e/testdata/screens/notebook-running-high-contrast.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>55 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>66 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>7-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>8-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1313 <span style="background:#000000"> </span>1414 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1515 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[4]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1616 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>17-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[4]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>18-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>19-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[4]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>18+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>19+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2121 <span style="background:#000000"> </span>2222 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">running</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>2323 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[*]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">sleep</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">10min</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">■</span>
M e2e/testdata/screens/notebook-running-light.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>55 <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>66 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>7- <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>8- 012 file 4.2 kB9- CLAUDE.md file 1.0 kB10- README.md file 9.8 kB11- demos dir 3.1 kB12- go.mod file 812 B7+ <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>8+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB9+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB10+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1313 1414 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1515 <span style="color:var(--vt-palette-0)">[4]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1616 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>17- <span style="color:var(--vt-palette-0)">Out[4]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>18- 012 file 4.2 kB19- README.md file 9.8 kB20- demos dir 3.1 kB17+ <span style="color:var(--vt-palette-0)">Out[4]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>18+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB19+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB20+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2121 2222 <span style="color:var(--vt-palette-8)">╭────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">running</span> <span style="color:var(--vt-palette-8)">─╮</span>2323 <span style="color:var(--vt-palette-0)">[*]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-4)">sleep</span> <span style="color:var(--vt-palette-1)">10min</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">■</span>
M e2e/testdata/screens/notebook-running.html +10 -10
@@ -4,20 +4,20 @@
44 <span style="color:var(--vt-palette-8)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>55 <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>66 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>7- <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>8- 012 file 4.2 kB9- CLAUDE.md file 1.0 kB10- README.md file 9.8 kB11- demos dir 3.1 kB12- go.mod file 812 B7+ <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>8+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB9+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB10+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1313 1414 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1515 <span style="color:var(--vt-palette-8)">[4]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1616 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>17- <span style="color:var(--vt-palette-8)">Out[4]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>18- 012 file 4.2 kB19- README.md file 9.8 kB20- demos dir 3.1 kB17+ <span style="color:var(--vt-palette-8)">Out[4]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>18+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB19+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB20+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2121 2222 <span style="color:var(--vt-palette-8)">╭────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">running</span> <span style="color:var(--vt-palette-8)">─╮</span>2323 <span style="color:var(--vt-palette-8)">[*]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-6)">sleep</span> <span style="color:var(--vt-palette-3)">10min</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">■</span>
M e2e/testdata/screens/notebook-scroll-high-contrast.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">NOTEBOOK</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Cut</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Copy</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Paste</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>3-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">table:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">columns</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">o</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">hide</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">O</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">whole</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">G</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sheet</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>3+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">table:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">2</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">columns</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">──────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">work</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">o</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">hide</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">O</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">whole</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">G</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">a</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">sheet</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>66 <span style="background:#000000"> </span>77 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>99 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>10+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1414 <span style="background:#000000"> </span>1515 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1..30</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">each</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">{</span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="color:#40e0ff;background:#000000">i</span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">{n:</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$i</span><span style="color:#ffffff;background:#000000">,</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">square:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">(</span><span style="color:#ff80ff;background:#000000">$i</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">*</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$i</span><span style="color:#ffffff;background:#000000">)}}</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">▶</span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>18-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">n</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">square</span><span style="background:#000000"> </span>19-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">16</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">25</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">6</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">36</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">7</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">49</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">64</span><span style="background:#000000"> </span>24-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">81</span><span style="background:#000000"> </span>25-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">100</span><span style="background:#000000"> </span>26-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">11</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">121</span><span style="background:#000000"> </span>27-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">12</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">144</span><span style="background:#000000"> </span>28-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">169</span><span style="background:#000000"> </span>29-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">…</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">(O</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">shows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">all,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Enter</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">opens</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it)</span><span style="background:#000000"> </span>18+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">n</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">square</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>19+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">16</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">5</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">25</span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">6</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">6</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">36</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">7</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">7</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">49</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">8</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">64</span><span style="background:#000000"> </span>24+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">9</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">81</span><span style="background:#000000"> </span>25+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">10</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">100</span><span style="background:#000000"> </span>26+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">11</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">11</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">121</span><span style="background:#000000"> </span>27+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">12</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">12</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">144</span><span style="background:#000000"> </span>28+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">13</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">169</span><span style="background:#000000"> </span>29+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">…</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">rows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">to</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">13</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">of</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">30</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">(O</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">shows</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">all,</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Enter</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">works</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">in</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">it)</span><span style="background:#000000"> </span>3030 <span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+K</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+/</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">shortcuts</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">F10</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-scroll-light.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>3- <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">table:</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">rows,</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">columns</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">o</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">hide</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">O</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">whole</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">G</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">sheet</span>4- demos dir 3.1 kB5- go.mod file 812 B3+ <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">table:</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">rows,</span> <span style="color:var(--vt-palette-0)">2</span> <span style="color:var(--vt-palette-0)">columns</span> <span style="color:var(--vt-palette-8)">──────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">work</span> <span style="color:var(--vt-palette-0)">in</span> <span style="color:var(--vt-palette-0)">it</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">o</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">hide</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">O</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">whole</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">G</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">a</span> <span style="color:var(--vt-palette-0)">sheet</span>4+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B66 77 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- README.md file 9.8 kB13- demos dir 3.1 kB10+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1414 1515 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1616 <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-1)">1..30</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">each</span> {<span style="font-weight:bold">|</span><span style="color:var(--vt-palette-4)">i</span><span style="font-weight:bold">|</span> {n: <span style="color:var(--vt-palette-5)">$i</span>, square: (<span style="color:var(--vt-palette-5)">$i</span> <span style="font-weight:bold">*</span> <span style="color:var(--vt-palette-5)">$i</span>)}} <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1717 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>18-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">n</span> <span style="font-weight:bold;text-decoration:underline">square</span>19-<span style="color:var(--vt-palette-4)">▌</span> 4 1620-<span style="color:var(--vt-palette-4)">▌</span> 5 2521-<span style="color:var(--vt-palette-4)">▌</span> 6 3622-<span style="color:var(--vt-palette-4)">▌</span> 7 4923-<span style="color:var(--vt-palette-4)">▌</span> 8 6424-<span style="color:var(--vt-palette-4)">▌</span> 9 8125-<span style="color:var(--vt-palette-4)">▌</span> 10 10026-<span style="color:var(--vt-palette-4)">▌</span> 11 12127-<span style="color:var(--vt-palette-4)">▌</span> 12 14428-<span style="color:var(--vt-palette-4)">▌</span> 13 16929-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">13</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">(O</span> <span style="color:var(--vt-palette-0)">shows</span> <span style="color:var(--vt-palette-0)">all,</span> <span style="color:var(--vt-palette-0)">Enter</span> <span style="color:var(--vt-palette-0)">opens</span> <span style="color:var(--vt-palette-0)">it)</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">n</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">square</span><span style="background:var(--vt-palette-7)"> </span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> 4 1620+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> 5 2521+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">6</span><span style="background:var(--vt-palette-7)"> </span> 6 3622+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">7</span><span style="background:var(--vt-palette-7)"> </span> 7 4923+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">8</span><span style="background:var(--vt-palette-7)"> </span> 8 6424+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">9</span><span style="background:var(--vt-palette-7)"> </span> 9 8125+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">10</span><span style="background:var(--vt-palette-7)"> </span> 10 10026+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">11</span><span style="background:var(--vt-palette-7)"> </span> 11 12127+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">12</span><span style="background:var(--vt-palette-7)"> </span> 12 14428+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">13</span><span style="background:var(--vt-palette-7)"> </span> 13 16929+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">…</span> <span style="color:var(--vt-palette-0)">rows</span> <span style="color:var(--vt-palette-0)">4</span> <span style="color:var(--vt-palette-0)">to</span> <span style="color:var(--vt-palette-0)">13</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">30</span> <span style="color:var(--vt-palette-0)">(O</span> <span style="color:var(--vt-palette-0)">shows</span> <span style="color:var(--vt-palette-0)">all,</span> <span style="color:var(--vt-palette-0)">Enter</span> <span style="color:var(--vt-palette-0)">works</span> <span style="color:var(--vt-palette-0)">in</span> <span style="color:var(--vt-palette-0)">it)</span>3030 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+/</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">shortcuts</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">F10</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-scroll.html +19 -19
@@ -1,30 +1,30 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ Cut ⧉ Copy <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">Paste</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>3- <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">table:</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">rows,</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">columns</span> <span style="color:var(--vt-palette-8)">──────────────────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">o</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">hide</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">O</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">whole</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">G</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">sheet</span>4- demos dir 3.1 kB5- go.mod file 812 B3+ <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">table:</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">rows,</span> <span style="color:var(--vt-palette-8)">2</span> <span style="color:var(--vt-palette-8)">columns</span> <span style="color:var(--vt-palette-8)">──────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">work</span> <span style="color:var(--vt-palette-8)">in</span> <span style="color:var(--vt-palette-8)">it</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">o</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">hide</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">O</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">whole</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">G</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">a</span> <span style="color:var(--vt-palette-8)">sheet</span>4+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B66 77 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>88 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>99 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11- 012 file 4.2 kB12- README.md file 9.8 kB13- demos dir 3.1 kB10+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1414 1515 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1616 <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-3)">1..30</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">each</span> {<span style="font-weight:bold">|</span><span style="color:var(--vt-palette-6)">i</span><span style="font-weight:bold">|</span> {n: <span style="color:var(--vt-palette-5)">$i</span>, square: (<span style="color:var(--vt-palette-5)">$i</span> <span style="font-weight:bold">*</span> <span style="color:var(--vt-palette-5)">$i</span>)}} <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1717 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>18-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">n</span> <span style="font-weight:bold;text-decoration:underline">square</span>19-<span style="color:var(--vt-palette-4)">▌</span> 4 1620-<span style="color:var(--vt-palette-4)">▌</span> 5 2521-<span style="color:var(--vt-palette-4)">▌</span> 6 3622-<span style="color:var(--vt-palette-4)">▌</span> 7 4923-<span style="color:var(--vt-palette-4)">▌</span> 8 6424-<span style="color:var(--vt-palette-4)">▌</span> 9 8125-<span style="color:var(--vt-palette-4)">▌</span> 10 10026-<span style="color:var(--vt-palette-4)">▌</span> 11 12127-<span style="color:var(--vt-palette-4)">▌</span> 12 14428-<span style="color:var(--vt-palette-4)">▌</span> 13 16929-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">13</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">(O</span> <span style="color:var(--vt-palette-8)">shows</span> <span style="color:var(--vt-palette-8)">all,</span> <span style="color:var(--vt-palette-8)">Enter</span> <span style="color:var(--vt-palette-8)">opens</span> <span style="color:var(--vt-palette-8)">it)</span>18+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">n</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">square</span><span style="background:var(--vt-palette-8)"> </span>19+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> 4 1620+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> 5 2521+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">6</span><span style="background:var(--vt-palette-8)"> </span> 6 3622+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">7</span><span style="background:var(--vt-palette-8)"> </span> 7 4923+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">8</span><span style="background:var(--vt-palette-8)"> </span> 8 6424+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">9</span><span style="background:var(--vt-palette-8)"> </span> 9 8125+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> 10 10026+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> 11 12127+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> 12 14428+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> 13 16929+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">…</span> <span style="color:var(--vt-palette-8)">rows</span> <span style="color:var(--vt-palette-8)">4</span> <span style="color:var(--vt-palette-8)">to</span> <span style="color:var(--vt-palette-8)">13</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">30</span> <span style="color:var(--vt-palette-8)">(O</span> <span style="color:var(--vt-palette-8)">shows</span> <span style="color:var(--vt-palette-8)">all,</span> <span style="color:var(--vt-palette-8)">Enter</span> <span style="color:var(--vt-palette-8)">works</span> <span style="color:var(--vt-palette-8)">in</span> <span style="color:var(--vt-palette-8)">it)</span>3030 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+/</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">shortcuts</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">F10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">menu</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-select-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">──────────────────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>99 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▎</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-select-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▎</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▎</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▎</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-select.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯</span>20-<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21-<span style="color:var(--vt-palette-4)">▎</span> 012 file 4.2 kB22-<span style="color:var(--vt-palette-4)">▎</span> README.md file 9.8 kB23-<span style="color:var(--vt-palette-4)">▎</span> demos dir 3.1 kB20+<span style="color:var(--vt-palette-4)">▎</span> <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+<span style="color:var(--vt-palette-4)">▎</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-stale-high-contrast.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭─</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">──────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">stale</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>88 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[1]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">=</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">ls</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">first</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">4</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>99 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>10-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>11-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>10+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>11+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>12+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>15+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1616 <span style="background:#000000"> </span>1717 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">stale</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000;font-style:italic">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1919 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>20-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>21-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>20+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>21+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>22+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>23+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>2424 <span style="background:#000000"> </span>2525 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────────────────────────────────╮</span><span style="background:#000000"> </span>2626 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>
M e2e/testdata/screens/notebook-stale-light.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-0)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-5);font-style:italic">stale</span> <span style="color:var(--vt-palette-5);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-4)">ls</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">first</span> <span style="color:var(--vt-palette-1)">4</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-5);font-style:italic">stale</span> <span style="color:var(--vt-palette-5);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>21+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>
M e2e/testdata/screens/notebook-stale.html +10 -10
@@ -7,20 +7,20 @@
77 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭─</span> <span style="color:var(--vt-palette-8)">files</span> <span style="color:var(--vt-palette-4)">──────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3);font-style:italic">stale</span> <span style="color:var(--vt-palette-3);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>88 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[1]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">files</span> <span style="font-weight:bold">=</span> <span style="color:var(--vt-palette-6)">ls</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">first</span> <span style="color:var(--vt-palette-3)">4</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>99 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>10-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>11-<span style="color:var(--vt-palette-4)">▌</span> 012 file 4.2 kB12-<span style="color:var(--vt-palette-4)">▌</span> CLAUDE.md file 1.0 kB13-<span style="color:var(--vt-palette-4)">▌</span> README.md file 9.8 kB14-<span style="color:var(--vt-palette-4)">▌</span> demos dir 3.1 kB15-<span style="color:var(--vt-palette-4)">▌</span> go.mod file 812 B10+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>11+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB12+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB13+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB15+<span style="color:var(--vt-palette-4)">▌</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1616 1717 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-3);font-style:italic">stale</span> <span style="color:var(--vt-palette-3);font-style:italic">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1818 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1919 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────────────────────────╯</span>20- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>21- 012 file 4.2 kB22- README.md file 9.8 kB23- demos dir 3.1 kB20+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>21+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB22+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB23+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB2424 2525 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────────────────────────────────╮</span>2626 <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>
M e2e/testdata/screens/notebook-wrap-high-contrast.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">EDIT</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Restart</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">all</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Add</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>33 <span style="color:#757575;background:#000000">────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Esc</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">done</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Tab</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">complete</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[1]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">CLAUDE.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">1.0</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>7+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>8+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>9+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>1010 <span style="background:#000000"> </span>1111 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>1212 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1313 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────────────────────────╯</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>15-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>16-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>15+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>16+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>17+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1818 <span style="background:#000000"> </span>1919 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span><span style="background:#000000"> </span>2020 <span style="color:#40e040;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">]:</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">==</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">┃</span><span style="background:#000000"> </span><span style="color:#40e040;background:#000000">▶</span>
M e2e/testdata/screens/notebook-wrap-light.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>33 <span style="color:var(--vt-palette-8)">────────────────────────────────────────────────────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Esc</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">done</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Tab</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">complete</span>4- <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>5- 012 file 4.2 kB6- CLAUDE.md file 1.0 kB7- README.md file 9.8 kB8- demos dir 3.1 kB9- go.mod file 812 B4+ <span style="color:var(--vt-palette-0)">Out[1]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB6+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> CLAUDE.md file 1.0 kB7+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB8+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB9+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B1010 1111 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1212 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1313 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>14- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>15- 012 file 4.2 kB16- README.md file 9.8 kB17- demos dir 3.1 kB14+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>15+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB16+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB17+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1818 1919 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2020 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-0)">[</span> <span style="color:var(--vt-palette-0)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> type <span style="font-weight:bold">==</span> file <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/notebook-wrap-narrow-high-contrast.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">F</span><span style="color:#ffffff;background:#1f1f1f">ile</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">E</span><span style="color:#ffffff;background:#1f1f1f">dit</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">V</span><span style="color:#ffffff;background:#1f1f1f">iew</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">I</span><span style="color:#ffffff;background:#1f1f1f">nsert</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">F</span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">o</span><span style="color:#ffffff;background:#1f1f1f">rmat</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">D</span><span style="color:#ffffff;background:#1f1f1f">ata</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f;text-decoration:underline">H</span><span style="color:#ffffff;background:#1f1f1f">elp</span><span style="background:#1f1f1f"> </span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">NOTEBOOK</span><span style="background:#40e0ff"> </span>22 <span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Run</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">■</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">Stop</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">↻</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▶▶</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">+</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">✂</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">⧉</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">⎘</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">Code</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">▾</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">nu</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">○</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">idle</span><span style="background:#000000"> </span>33 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">cell</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">4:</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">reads</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─────</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Enter</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">edit</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Shift+↑↓</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">select</span><span style="background:#000000"> </span>4-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>4+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>5+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">4</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>6+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">5</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">go.mod</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">812</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">B</span><span style="background:#000000"> </span>77 <span style="background:#000000"> </span>88 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╭──────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">─╮</span><span style="background:#000000"> </span>99 <span style="background:#000000"> </span><span style="color:#959595;background:#000000">[2]:</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#757575;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">▶</span>1010 <span style="background:#000000"> </span><span style="color:#757575;background:#000000">╰──────────────────────────────────────────────╯</span><span style="background:#000000"> </span>11-<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>12-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14-<span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>11+<span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[2]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>12+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">1</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">012</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">4.2</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>13+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">2</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">README.md</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">9.8</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>14+<span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">3</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">demos</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">dir</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">3.1</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">kB</span><span style="background:#000000"> </span>1515 <span style="background:#000000"> </span>1616 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╭──────────────────────────────────────</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">✓</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">&lt;1s</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">─╮</span><span style="background:#000000"> </span>1717 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">[3]:</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ff80ff;background:#000000">$files</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">where</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">&gt;</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">1kb</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">select</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">size</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">first</span><span style="background:#000000"> </span><span style="color:#ffe040;background:#000000">10</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span>2121 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold">|</span><span style="background:#000000"> </span><span style="color:#40e0ff;background:#000000">rename</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">file</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000">bytes</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">│</span><span style="background:#000000"> </span>2222 <span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#80a8ff;background:#000000">╰──────────────────────────────────────────────╯</span><span style="background:#000000"> </span>23-<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">name</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">type</span><span style="background:#000000"> </span><span style="color:#ffffff;background:#000000;font-weight:bold;text-decoration:underline">size</span><span style="background:#000000"> </span>23+<span style="color:#80a8ff;background:#000000">▌</span><span style="background:#000000"> </span><span style="color:#959595;background:#000000">Out[3]:</span><span style="background:#000000"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">name</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">type</span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">size</span><span style="background:#3a3a3a"> </span><span style="background:#000000"> </span>2424 <span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">❯</span><span style="background:#40e0ff"> </span><span style="color:#000000;background:#40e0ff;font-weight:bold">Notebook</span><span style="background:#40e0ff"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">+</span><span style="background:#1f1f1f"> </span><span style="color:#757575;background:#1f1f1f">│</span><span style="background:#1f1f1f"> </span><span style="color:#ffffff;background:#1f1f1f">untitled</span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">modified</span><span style="background:#1f1f1f"> </span><span style="background:#3a3a3a"> </span><span style="color:#ffffff;background:#3a3a3a">Ctrl+K</span><span style="background:#3a3a3a"> </span><span style="background:#1f1f1f"> </span><span style="color:#959595;background:#1f1f1f">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap-narrow-light.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ ▶▶ <span style="color:var(--vt-palette-8)">│</span> + ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-0)">nu</span> <span style="color:var(--vt-palette-0)">○</span> <span style="color:var(--vt-palette-0)">idle</span>33 <span style="color:var(--vt-palette-0)">cell</span> <span style="color:var(--vt-palette-0)">4:</span> <span style="color:var(--vt-palette-0)">reads</span> <span style="color:var(--vt-palette-0)">$files</span> <span style="color:var(--vt-palette-8)">─────</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Enter</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">edit</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Shift+↑↓</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">select</span>4- README.md file 9.8 kB5- demos dir 3.1 kB6- go.mod file 812 B4+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB5+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">4</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB6+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">5</span><span style="background:var(--vt-palette-7)"> </span> go.mod file 812 B77 88 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>99 <span style="color:var(--vt-palette-0)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-0)">▶</span>1010 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────╯</span>11- <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>12- 012 file 4.2 kB13- README.md file 9.8 kB14- demos dir 3.1 kB11+ <span style="color:var(--vt-palette-0)">Out[2]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>12+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">1</span><span style="background:var(--vt-palette-7)"> </span> 012 file 4.2 kB13+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">2</span><span style="background:var(--vt-palette-7)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">3</span><span style="background:var(--vt-palette-7)"> </span> demos dir 3.1 kB1515 1616 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">✓</span> <span style="color:var(--vt-palette-0)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-1)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">select</span> name size <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">first</span> <span style="color:var(--vt-palette-1)">10</span> <span style="color:var(--vt-palette-4)">│</span>2121 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-4)">rename</span> file bytes <span style="color:var(--vt-palette-4)">│</span>2222 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────╯</span>23-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>23+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-0)">Out[3]:</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">name</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">type</span><span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">size</span><span style="background:var(--vt-palette-7)"> </span>2424 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-0)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-0)">modified</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+K</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-0)">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap-narrow.html +8 -8
@@ -1,17 +1,17 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">NOTEBOOK</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ ▶▶ <span style="color:var(--vt-palette-8)">│</span> + ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>33 <span style="color:var(--vt-palette-8)">cell</span> <span style="color:var(--vt-palette-8)">4:</span> <span style="color:var(--vt-palette-8)">reads</span> <span style="color:var(--vt-palette-8)">$files</span> <span style="color:var(--vt-palette-8)">─────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">edit</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Shift+↑↓</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">select</span>4- README.md file 9.8 kB5- demos dir 3.1 kB6- go.mod file 812 B4+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB6+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B77 88 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>99 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1010 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────╯</span>11- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>12- 012 file 4.2 kB13- README.md file 9.8 kB14- demos dir 3.1 kB11+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>12+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB13+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB14+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1515 1616 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╭──────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-4)">─╮</span>1717 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">[3]:</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-4)">│</span> <span style="color:var(--vt-palette-4)">▶</span>
@@ -20,5 +20,5 @@
2020 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">select</span> name size <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">first</span> <span style="color:var(--vt-palette-3)">10</span> <span style="color:var(--vt-palette-4)">│</span>2121 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">│</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">rename</span> file bytes <span style="color:var(--vt-palette-4)">│</span>2222 <span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-4)">╰──────────────────────────────────────────────╯</span>23-<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>23+<span style="color:var(--vt-palette-4)">▌</span> <span style="color:var(--vt-palette-8)">Out[3]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>2424 <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">❯</span><span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">Notebook</span><span style="background:var(--vt-palette-6)"> </span> <span style="color:var(--vt-palette-8)">+</span> <span style="color:var(--vt-palette-8)">│</span> untitled <span style="color:var(--vt-palette-8)">modified</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+K</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">search</span></pre>\ No newline at end of file
M e2e/testdata/screens/notebook-wrap.html +10 -10
@@ -1,20 +1,20 @@
11 <pre class="screen"> <span style="text-decoration:underline">F</span>ile <span style="text-decoration:underline">E</span>dit <span style="text-decoration:underline">V</span>iew <span style="text-decoration:underline">I</span>nsert F<span style="text-decoration:underline">o</span>rmat <span style="text-decoration:underline">D</span>ata <span style="text-decoration:underline">H</span>elp <span style="background:var(--vt-palette-6)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-6);font-weight:bold">EDIT</span><span style="background:var(--vt-palette-6)"> </span>22 ▶ Run <span style="color:var(--vt-palette-8)">■</span> <span style="color:var(--vt-palette-8)">Stop</span> ↻ Restart ▶▶ Run all <span style="color:var(--vt-palette-8)">│</span> + Add ✂ ⧉ <span style="color:var(--vt-palette-8)">⎘</span> <span style="color:var(--vt-palette-8)">│</span> Code ▾ <span style="color:var(--vt-palette-8)">nu</span> <span style="color:var(--vt-palette-8)">○</span> <span style="color:var(--vt-palette-8)">idle</span>33 <span style="color:var(--vt-palette-8)">────────────────────────────────────────────────────</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">done</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Tab</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">complete</span>4- <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>5- 012 file 4.2 kB6- CLAUDE.md file 1.0 kB7- README.md file 9.8 kB8- demos dir 3.1 kB9- go.mod file 812 B4+ <span style="color:var(--vt-palette-8)">Out[1]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>5+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB6+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> CLAUDE.md file 1.0 kB7+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB8+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">4</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB9+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">5</span><span style="background:var(--vt-palette-8)"> </span> go.mod file 812 B1010 1111 <span style="color:var(--vt-palette-8)">╭──────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">✓</span> <span style="color:var(--vt-palette-8)">&lt;1s</span> <span style="color:var(--vt-palette-8)">─╮</span>1212 <span style="color:var(--vt-palette-8)">[2]:</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">▶</span>1313 <span style="color:var(--vt-palette-8)">╰──────────────────────────────────────────────────────────────────╯</span>14- <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="font-weight:bold;text-decoration:underline">name</span> <span style="font-weight:bold;text-decoration:underline">type</span> <span style="font-weight:bold;text-decoration:underline">size</span>15- 012 file 4.2 kB16- README.md file 9.8 kB17- demos dir 3.1 kB14+ <span style="color:var(--vt-palette-8)">Out[2]:</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">name</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">type</span><span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">size</span><span style="background:var(--vt-palette-8)"> </span>15+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">1</span><span style="background:var(--vt-palette-8)"> </span> 012 file 4.2 kB16+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">2</span><span style="background:var(--vt-palette-8)"> </span> README.md file 9.8 kB17+ <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">3</span><span style="background:var(--vt-palette-8)"> </span> demos dir 3.1 kB1818 1919 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-2)">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓</span>2020 <span style="color:var(--vt-palette-2)">▌</span> <span style="color:var(--vt-palette-8)">[</span> <span style="color:var(--vt-palette-8)">]:</span> <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-5)">$files</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> size <span style="font-weight:bold">&gt;</span> <span style="color:var(--vt-palette-3)">1kb</span> <span style="font-weight:bold">|</span> <span style="color:var(--vt-palette-6)">where</span> type <span style="font-weight:bold">==</span> file <span style="color:var(--vt-palette-2)">┃</span> <span style="color:var(--vt-palette-2)">▶</span>
M e2e/testdata/screens/palette-narrow.html +1 -1
@@ -12,5 +12,5 @@
1212 <span style="color:var(--vt-palette-8)">│</span> Sort <span style="color:var(--vt-palette-3);font-weight:bold">s</span>heet Z to <span style="color:var(--vt-palette-3);font-weight:bold">A</span> <span style="color:var(--vt-palette-8)">│</span>1313 <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">Ask</span> <span style="color:var(--vt-palette-8)">JEV</span> <span style="color:var(--vt-palette-8)">again</span> <span style="color:var(--vt-palette-8)">│</span>1414 <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-3);font-weight:bold">S</span>ort r<span style="color:var(--vt-palette-3);font-weight:bold">a</span>nge <span style="color:var(--vt-palette-8)">│</span>15-<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">64</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>15+<span style="color:var(--vt-palette-8)">└──────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">65</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1616 Save the sheet u… <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Up/Down</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">move</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Enter</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">run</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Esc</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">close</span></pre>\ No newline at end of file
M e2e/testdata/screens/palette-search-light.html +1 -1
@@ -14,7 +14,7 @@
1414 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">10</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> Reset <span style="color:var(--vt-palette-4);font-weight:bold">col</span>umn width <span style="color:var(--vt-palette-0)">Format</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">11</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> Insert <span style="color:var(--vt-palette-4);font-weight:bold">col</span>umns right <span style="color:var(--vt-palette-0)">Insert</span> <span style="color:var(--vt-palette-8)">│</span>1616 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">12</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span> Delete rows or <span style="color:var(--vt-palette-4);font-weight:bold">col</span>umns <span style="color:var(--vt-palette-0)">Edit</span> <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">Ctrl+Alt+-</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">13</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">48</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>17+<span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">13</span><span style="background:var(--vt-palette-7)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-0)">48</span> <span style="color:var(--vt-palette-0)">of</span> <span style="color:var(--vt-palette-0)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">14</span><span style="background:var(--vt-palette-7)"> </span>1919 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">15</span><span style="background:var(--vt-palette-7)"> </span>2020 <span style="background:var(--vt-palette-7)"> </span><span style="color:var(--vt-palette-0);background:var(--vt-palette-7)">16</span><span style="background:var(--vt-palette-7)"> </span>
M e2e/testdata/screens/palette-search.html +1 -1
@@ -14,7 +14,7 @@
1414 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Reset <span style="color:var(--vt-palette-3);font-weight:bold">col</span>umn width <span style="color:var(--vt-palette-8)">Format</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Insert <span style="color:var(--vt-palette-3);font-weight:bold">col</span>umns right <span style="color:var(--vt-palette-8)">Insert</span> <span style="color:var(--vt-palette-8)">│</span>1616 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Delete rows or <span style="color:var(--vt-palette-3);font-weight:bold">col</span>umns <span style="color:var(--vt-palette-8)">Edit</span> <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">Ctrl+Alt+-</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">48</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>17+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">48</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>2020 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">16</span><span style="background:var(--vt-palette-8)"> </span>
M e2e/testdata/screens/palette-wide.html +1 -1
@@ -14,7 +14,7 @@
1414 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-3);font-weight:bold">S</span>av<span style="color:var(--vt-palette-3);font-weight:bold">e</span> as <span style="color:var(--vt-palette-8)">Fi</span><span style="color:var(--vt-palette-3);font-weight:bold">l</span><span style="color:var(--vt-palette-8)">e</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> <span style="color:var(--vt-palette-8)">Code</span> <span style="color:var(--vt-palette-8)">Data</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Shell</span> <span style="color:var(--vt-palette-8)">y</span> <span style="color:var(--vt-palette-8)">│</span>1616 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> In<span style="color:var(--vt-palette-3);font-weight:bold">se</span>rt rows be<span style="color:var(--vt-palette-3);font-weight:bold">l</span>ow <span style="color:var(--vt-palette-8)">Insert</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">59</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>17+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└────────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">60</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>2020 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">16</span><span style="background:var(--vt-palette-8)"> </span>
M e2e/testdata/screens/palette.html +2 -2
@@ -13,8 +13,8 @@
1313 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">9</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as SQLite <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1414 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">10</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as JSON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>1515 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">11</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as NUON <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>16-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Decimal arithmetic <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Settings</span> <span style="color:var(--vt-palette-8)">│</span>17-<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">225</span> <span style="color:var(--vt-palette-8)">─┘</span>16+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">12</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">│</span> Download as HTML <span style="color:var(--vt-palette-8)">File</span> <span style="color:var(--vt-palette-8)">›</span> <span style="color:var(--vt-palette-8)">Download</span> <span style="color:var(--vt-palette-8)">│</span>17+<span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">13</span><span style="background:var(--vt-palette-8)"> </span> <span style="color:var(--vt-palette-8)">└───────────────────────────────────────────────────────────────</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">of</span> <span style="color:var(--vt-palette-8)">226</span> <span style="color:var(--vt-palette-8)">─┘</span>1818 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">14</span><span style="background:var(--vt-palette-8)"> </span>1919 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">15</span><span style="background:var(--vt-palette-8)"> </span>2020 <span style="background:var(--vt-palette-8)"> </span><span style="color:var(--vt-palette-15);background:var(--vt-palette-8)">16</span><span style="background:var(--vt-palette-8)"> </span>
M go.mod +7 -0
M go.sum +16 -0
@@ -56,8 +56,12 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
5656 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=5757 github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkvE=5858 github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk=59+github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=60+github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=5961 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=6062 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=63+github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=64+github.com/google/jsonschema-go v0.4.3/go.mod h1:r5quNTdLOYEz95Ru18zA0ydNbBuYoo9tgaYcxEYhJVE=6165 github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 h1:LMLX+LgTNWpfvCBdFebv6EsYotImrt/Ppc5cXIriCSo=6266 github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3/go.mod h1:jl5iWTm0/hd5PjEYEOuwAJ57L/CibdZfrqZ5XA5GrCk=6367 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
@@ -78,6 +82,8 @@ github.com/mattn/go-isatty v0.0.24 h1:tGZZoVgT/KiqK1c8ocVLeDS8BSWMRd47J3Lbz7vsRe
7882 github.com/mattn/go-isatty v0.0.24/go.mod h1:nMCL3Zebbrt45jsMDgnfIwz6ydEQApk5oEI3HqDio6A=7983 github.com/mattn/go-runewidth v0.0.30 h1:+KUuiDA4fF0R1p5FeueHefjDm+GIM+kWfFnDjybOPgk=8084 github.com/mattn/go-runewidth v0.0.30/go.mod h1:3qAiGCV4Koz/yuveO58qUefmUTRm8r0IGEXZ9jeHp/8=85+github.com/modelcontextprotocol/go-sdk v1.8.0 h1:KIvahhYqwtbeniWVPs3TcXEA7b8jEtwfBpOTAI+Urx4=86+github.com/modelcontextprotocol/go-sdk v1.8.0/go.mod h1:dL7u98E/zjJTGzEq+j30jQ8K2k1mb6LeAH4inEcSGts=8187 github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=8288 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=8389 github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
@@ -104,6 +110,10 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
104110 github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=105111 github.com/sahilm/fuzzy v0.1.3 h1:juByESSS32nVD81vr6tHmKmA/8zde7gE+x5CLxrzXPU=106112 github.com/sahilm/fuzzy v0.1.3/go.mod h1:au6//VbVSqu6DFrkL2CfjlJ5iURpNCPeE+1GwY3XsT8=113+github.com/segmentio/asm v1.1.3 h1:WM03sfUOENvvKexOLp+pCqgb/WDjsi7EK8gIsICtzhc=114+github.com/segmentio/asm v1.1.3/go.mod h1:Ld3L4ZXGNcSLRg4JBsZ3//1+f/TjYl0Mzen/DQy1EJg=115+github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=116+github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=107117 github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=108118 github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=109119 github.com/tiendc/go-deepcopy v1.7.2 h1:Ut2yYR7W9tWjTQitganoIue4UGxZwCcJy3orjrrIj44=
@@ -120,6 +130,8 @@ github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 h1:+C0TIdyyYmzadGaL/HBL
120130 github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=121131 github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=122132 github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=133+github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=134+github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=123135 go.starlark.net v0.0.0-20260908191801-89a6a09411d5 h1:X8HyonnLxrmAbdeMIEGEJVZ/yg6WykLZyAZmpCLSfMA=124136 go.starlark.net v0.0.0-20260908191801-89a6a09411d5/go.mod h1:Iue6g6iirlfLoVi/DYCi5/x0h/bAOuWF3dULTKpt2Vo=125137 golang.org/x/crypto v0.57.0 h1:3ZVCjf8Ggz7zneR/EHRVx68Ctf+2pmIMP2UFhh9cC6M=
@@ -132,6 +144,8 @@ golang.org/x/mod v0.41.0 h1:qJmnOUb4YB+FsEuM3HcWucdZASCPGhsX6uljO6pog0c=
132144 golang.org/x/mod v0.41.0/go.mod h1:Ek9pY8RKWXwsWvd3rQiHYtMqkjSUV+s1Rj7j4H5Ur6o=133145 golang.org/x/net v0.59.0 h1:5zfYln+w5XCxwrnMMJPufRgNoXEaGxl0wo5GqPXyues=134146 golang.org/x/net v0.59.0/go.mod h1:2DA/G1UfVbCpQPeWTmMPGY7Cs2PkBkwu743bVX5PIVg=147+golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=148+golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=135149 golang.org/x/sync v0.23.0 h1:KameEIfc1IkluZyXWLn39Wd4tURc6GbCiISGiZm2bQk=136150 golang.org/x/sync v0.23.0/go.mod h1:sUUOizhqBxiL6pEWpqNLUiaJn1ShEbZ6BBqskPbjZm0=137151 golang.org/x/sys v0.48.0 h1:bbX/i/6MgT9BVLM9RT1thmxL04yeTAhbEz4SyadbXoo=
@@ -140,6 +154,8 @@ golang.org/x/term v0.46.0 h1:3+OXuTbaKDgwk8jTi3aSLHRlmWqHEUDUtxnbFigO4YE=
140154 golang.org/x/term v0.46.0/go.mod h1:+K02xbkittuwc0Am4abfA3Fc+XRGXkvBXNO88NCXPoc=141155 golang.org/x/text v0.42.0 h1:JbOZXgfeCPU9gacVtYliJqOhD+zhrEqK4LfdpmlUZqI=142156 golang.org/x/text v0.42.0/go.mod h1:ojzP1Z+2QtioaF8DTtO8K5q7JWVVYwZKenzujK0Zd0E=157+golang.org/x/time v0.16.0 h1:vMb6ptszcQMkcwiRTAuNNU50gom6++Q/6gY2hDM6VDE=158+golang.org/x/time v0.16.0/go.mod h1:rVKOqvZeKvrDKTQiAHJ7wmwP0RzleSphoEA9RcdLA0s=143159 golang.org/x/tools v0.50.0 h1:c2ifzfcuY7L90lZ2aKd8S4K2NpASF08SZx9ZuJkHmSU=144160 golang.org/x/tools v0.50.0/go.mod h1:7ulVMw3831Mwi5EZD6RomGyffr4VFjuNYXf2BbCEAV0=145161 google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
M internal/chart/image.go +23 -0
@@ -46,6 +46,9 @@ type canvas struct {
4646 *image.RGBA4747 cw, ch float644848 pal Palette49+ // vec, when set, takes the shapes as SVG instead of pixels, and50+ // RGBA has no pixels, only its bounds (see SVG).51+ vec *vector4952 }5053 5154 // blend paints c over the pixel at x, y with coverage a.
@@ -65,6 +68,10 @@ func (cv *canvas) blend(x, y int, c color.RGBA, a float64) {
6568 6669 // rect fills x0..x1, y0..y1 in pixels, antialiasing fractional edges.6770 func (cv *canvas) rect(x0, y0, x1, y1 float64, c color.RGBA) {71+ if cv.vec != nil {72+ cv.vec.rect(x0, y0, x1, y1, c)73+ return74+ }6875 for y := int(math.Floor(y0)); float64(y) < y1; y++ {6976 cy := min(y1, float64(y+1)) - max(y0, float64(y))7077 for x := int(math.Floor(x0)); float64(x) < x1; x++ {
@@ -76,6 +83,10 @@ func (cv *canvas) rect(x0, y0, x1, y1 float64, c color.RGBA) {
7683 7784 // hline draws a one pixel horizontal line at y.7885 func (cv *canvas) hline(y int, c color.RGBA) {86+ if cv.vec != nil {87+ cv.vec.line(float64(cv.Rect.Min.X), float64(y)+0.5, float64(cv.Rect.Max.X), float64(y)+0.5, c)88+ return89+ }7990 for x := cv.Rect.Min.X; x < cv.Rect.Max.X; x++ {8091 cv.blend(x, y, c, 1)8192 }
@@ -83,6 +94,10 @@ func (cv *canvas) hline(y int, c color.RGBA) {
8394 8495 // vline draws a one pixel vertical line at x.8596 func (cv *canvas) vline(x int, c color.RGBA) {97+ if cv.vec != nil {98+ cv.vec.line(float64(x)+0.5, float64(cv.Rect.Min.Y), float64(x)+0.5, float64(cv.Rect.Max.Y), c)99+ return100+ }86101 for y := cv.Rect.Min.Y; y < cv.Rect.Max.Y; y++ {87102 cv.blend(x, y, c, 1)88103 }
@@ -91,6 +106,10 @@ func (cv *canvas) vline(x int, c color.RGBA) {
91106 // polyline strokes the points with a round-capped line width px wide.92107 // Coverage is kept per pixel, so joints aren't painted twice.93108 func (cv *canvas) polyline(pts [][2]float64, width float64, c color.RGBA) {109+ if cv.vec != nil {110+ cv.vec.polyline(pts, width, c)111+ return112+ }94113 b := cv.Rect95114 cover := make([]float64, b.Dx()*b.Dy())96115 r := width / 2
@@ -213,6 +232,10 @@ func (p *barPlan) image(cv *canvas) {
213232 214233 // image draws the pie, supersampled, with a thin gap between slices.215234 func (p *piePlan) image(cv *canvas) {235+ if cv.vec != nil {236+ p.vector(cv)237+ return238+ }216239 b := cv.Rect217240 cx, cy := float64(b.Dx())/2, float64(b.Dy())/2218241 pr := newPieRaster(p, cx, cy, min(cx, cy)-1, 1)
M internal/chart/scatter.go +4 -0
A internal/chart/svg.go +311 -0
@@ -0,0 +1,311 @@
1+package chart2+3+import (4+ "fmt"5+ "html"6+ "image"7+ "image/color"8+ "math"9+ "strings"10+11+ "github.com/FelineStateMachine/012/internal/sheet"12+)13+14+// SVG charts are the text chart and the image in one vector drawing,15+// for the HTML export: the axes, labels and legend Draw lays out, as16+// text on a grid of SVGCellW by SVGCellH pixels, and the plot area as17+// the shapes Image paints, as SVG shapes rather than pixels. Colors are18+// classes the page styles, so a chart follows the page's light or dark19+// palette:20+//21+// ct-ax, ct-lb, ct-mu text of the axes, the labels and messages22+// ct-s0 .. ct-s5 text in a series' color23+// cf-0 .. cf-5 shapes filled in a series' color24+// cs-0 .. cs-5 lines stroked in a series' color25+// cs-gl gridlines26+// cs-box axes, in their text class's color27+// cs-gap the gaps between a pie's slices28+const (29+ SVGCellW = 930+ SVGCellH = 2131+)32+33+// vecGrid and vecSeries stand for the colors in the palette a vector34+// canvas paints with, so each shape finds its class again: the red35+// channel is the series and the blue one says it's a gridline.36+var vecGrid = color.RGBA{B: 1, A: 255}37+38+func vecSeries(i int) color.RGBA { return color.RGBA{R: uint8(i), A: 255} }39+40+// SVG draws d as a chart of type t in w by h cells, as an svg element41+// of w*SVGCellW by h*SVGCellH pixels whose title is title.42+func SVG(t sheet.ChartType, d sheet.ChartData, w, h int, o Options, title string) string {43+ w, h = max(w, 0), max(h, 0)44+ o.Image, o.CellW, o.CellH = true, SVGCellW, SVGCellH45+ g := Draw(t, d, w, h, o)46+ var b strings.Builder47+ fmt.Fprintf(&b, `<svg xmlns="http://www.w3.org/2000/svg" class="chart" width="%d" height="%d" viewBox="0 0 %d %d" role="img">`,48+ w*SVGCellW, h*SVGCellH, w*SVGCellW, h*SVGCellH)49+ if title != "" {50+ b.WriteString("<title>" + html.EscapeString(title) + "</title>")51+ }52+ if !g.Plot.Empty() {53+ b.WriteString(plotSVG(t, d, w, h, o, g.Plot))54+ }55+ gridText(&b, g)56+ b.WriteString("</svg>")57+ return b.String()58+}59+60+// plotSVG is the plot area's shapes, placed over its cells.61+func plotSVG(t sheet.ChartType, d sheet.ChartData, w, h int, o Options, plot image.Rectangle) string {62+ p, _ := planFor(t, d, w, h, o)63+ pal := Palette{Grid: vecGrid}64+ for i := range pal.Series {65+ pal.Series[i] = vecSeries(i)66+ }67+ v := &vector{}68+ cv := &canvas{69+ RGBA: &image.RGBA{Rect: image.Rect(0, 0, plot.Dx()*SVGCellW, plot.Dy()*SVGCellH)},70+ cw: SVGCellW, ch: SVGCellH, pal: pal, vec: v,71+ }72+ p.image(cv)73+ v.flush()74+ return fmt.Sprintf(`<g transform="translate(%d %d)">%s</g>`, plot.Min.X*SVGCellW, plot.Min.Y*SVGCellH, v.b.String())75+}76+77+// gridText writes the text chart's cells, a run of one role at a time.78+func gridText(b *strings.Builder, g *Grid) {79+ for y := range g.H {80+ x := 081+ for x < g.W {82+ c := g.At(x, y)83+ if c.Text == " " || c.Text == "" || c.Fg == None {84+ x++85+ continue86+ }87+ if arms, ok := boxArms[c.Text]; ok {88+ boxLines(b, x, y, arms, textClass(c.Fg))89+ x++90+ continue91+ }92+ start, role := x, c.Fg93+ var run strings.Builder94+ for x < g.W && g.At(x, y).Fg == role && !isBox(g.At(x, y).Text) {95+ run.WriteString(g.At(x, y).Text)96+ x++97+ }98+ fmt.Fprintf(b, `<text x="%d" y="%.1f" class="%s" xml:space="preserve">%s</text>`, start*SVGCellW,99+ float64(y)*SVGCellH+SVGCellH*0.72, textClass(role), html.EscapeString(strings.TrimRight(run.String(), " ")))100+ }101+ }102+}103+104+// boxArms are the box-drawing characters the axes use, as the arms105+// each draws from the middle of its cell: up, down, left, right. They106+// are drawn as lines, which meet whatever font the page has.107+var boxArms = map[string][4]bool{108+ "│": {true, true, false, false}, "─": {false, false, true, true},109+ "└": {true, false, false, true}, "┘": {true, false, true, false},110+ "┌": {false, true, false, true}, "┐": {false, true, true, false},111+ "├": {true, true, false, true}, "┤": {true, true, true, false},112+ "┬": {false, true, true, true}, "┴": {true, false, true, true},113+ "┼": {true, true, true, true},114+}115+116+func isBox(s string) bool { _, ok := boxArms[s]; return ok }117+118+// boxLines draws a box-drawing character's arms in cell x, y.119+func boxLines(b *strings.Builder, x, y int, arms [4]bool, class string) {120+ cx, cy := float64(x)*SVGCellW+SVGCellW/2, float64(y)*SVGCellH+SVGCellH/2121+ ends := [4][2]float64{{cx, float64(y) * SVGCellH}, {cx, float64(y+1) * SVGCellH},122+ {float64(x) * SVGCellW, cy}, {float64(x+1) * SVGCellW, cy}}123+ for i, on := range arms {124+ if on {125+ fmt.Fprintf(b, `<line x1="%s" y1="%s" x2="%s" y2="%s" class="%s cs-box"/>`, num(cx), num(cy), num(ends[i][0]), num(ends[i][1]), class)126+ }127+ }128+}129+130+func textClass(r Role) string {131+ switch {132+ case r == Axis, r == Gridline:133+ return "ct-ax"134+ case r == Label:135+ return "ct-lb"136+ case r >= Series:137+ return fmt.Sprintf("ct-s%d", int(r-Series)%Colors)138+ }139+ return "ct-mu"140+}141+142+// vector collects a canvas's shapes as SVG. Area charts paint a pixel143+// column at a time; those columns are joined into one polygon per color144+// for as long as they run on without a gap.145+type vector struct {146+ b strings.Builder147+ strips map[color.RGBA]*strip148+ order []color.RGBA149+}150+151+// strip is a run of one-pixel columns of one color: their tops and152+// bottoms, left to right.153+type strip struct {154+ x0, x1 float64155+ top, below [][2]float64156+}157+158+func paint(c color.RGBA) (series int, grid bool, opacity string) {159+ if c.A < 255 {160+ opacity = fmt.Sprintf(` fill-opacity="%.2f"`, float64(c.A)/255)161+ }162+ return int(c.R) % Colors, c.B == 1, opacity163+}164+165+func (v *vector) rect(x0, y0, x1, y1 float64, c color.RGBA) {166+ if x1 <= x0 || y1 <= y0 {167+ return168+ }169+ if x1-x0 <= 1.001 {170+ v.column(x0, y0, x1, y1, c)171+ return172+ }173+ v.flush()174+ s, _, op := paint(c)175+ fmt.Fprintf(&v.b, `<rect x="%s" y="%s" width="%s" height="%s" class="cf-%d"%s/>`, num(x0), num(y0), num(x1-x0), num(y1-y0), s, op)176+}177+178+// column adds a pixel column to its color's strip, starting a new strip179+// when it doesn't continue the last one.180+func (v *vector) column(x0, y0, x1, y1 float64, c color.RGBA) {181+ if v.strips == nil {182+ v.strips = map[color.RGBA]*strip{}183+ }184+ st := v.strips[c]185+ if st != nil && math.Abs(st.x1-x0) > 0.001 {186+ v.emitStrip(c, st)187+ st = nil188+ }189+ if st == nil {190+ st = &strip{x0: x0}191+ v.strips[c] = st192+ v.order = append(v.order, c)193+ }194+ st.x1 = x1195+ st.top = append(st.top, [2]float64{x0, y0}, [2]float64{x1, y0})196+ st.below = append(st.below, [2]float64{x0, y1}, [2]float64{x1, y1})197+}198+199+// flush writes the strips still open, in the order they started, so200+// they're under whatever is drawn next.201+func (v *vector) flush() {202+ for _, c := range v.order {203+ if st := v.strips[c]; st != nil {204+ v.emitStrip(c, st)205+ }206+ }207+ v.order = v.order[:0]208+}209+210+func (v *vector) emitStrip(c color.RGBA, st *strip) {211+ delete(v.strips, c)212+ pts := simplify(st.top)213+ below := simplify(st.below)214+ for i := len(below) - 1; i >= 0; i-- {215+ pts = append(pts, below[i])216+ }217+ s, _, op := paint(c)218+ fmt.Fprintf(&v.b, `<polygon points="%s" class="cf-%d"%s/>`, points(pts), s, op)219+}220+221+func (v *vector) line(x0, y0, x1, y1 float64, c color.RGBA) {222+ v.flush()223+ class := "cs-gl"224+ if s, grid, _ := paint(c); !grid {225+ class = fmt.Sprintf("cs-%d", s)226+ }227+ fmt.Fprintf(&v.b, `<line x1="%s" y1="%s" x2="%s" y2="%s" class="%s"/>`, num(x0), num(y0), num(x1), num(y1), class)228+}229+230+func (v *vector) polyline(pts [][2]float64, width float64, c color.RGBA) {231+ v.flush()232+ s, _, _ := paint(c)233+ if len(pts) == 1 {234+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-%d"/>`, num(pts[0][0]), num(pts[0][1]), num(width/2), s)235+ return236+ }237+ fmt.Fprintf(&v.b, `<polyline points="%s" fill="none" stroke-width="%s" stroke-linecap="round" stroke-linejoin="round" class="cs-%d"/>`,238+ points(pts), num(width), s)239+}240+241+func (v *vector) disc(cx, cy, r float64, c color.RGBA) {242+ v.flush()243+ s, _, _ := paint(c)244+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-%d"/>`, num(cx), num(cy), num(r), s)245+}246+247+// vector draws the pie as one path a slice, with the page's background248+// stroked between them as the image leaves a gap.249+func (p *piePlan) vector(cv *canvas) {250+ v := cv.vec251+ b := cv.Rect252+ cx, cy := float64(b.Dx())/2, float64(b.Dy())/2253+ r := min(cx, cy) - 1254+ if len(p.slices) == 1 {255+ fmt.Fprintf(&v.b, `<circle cx="%s" cy="%s" r="%s" class="cf-0"/>`, num(cx), num(cy), num(r))256+ return257+ }258+ at := func(f float64) string {259+ a := f * 2 * math.Pi260+ return num(cx+r*math.Sin(a)) + " " + num(cy-r*math.Cos(a))261+ }262+ for i, s := range p.slices {263+ if s.to <= s.from {264+ continue265+ }266+ large := 0267+ if s.to-s.from > 0.5 {268+ large = 1269+ }270+ fmt.Fprintf(&v.b, `<path d="M%s %s L%s A%s %s 0 %d 1 %s Z" class="cf-%d cs-gap"/>`,271+ num(cx), num(cy), at(s.from), num(r), num(r), large, at(s.to), i%Colors)272+ }273+}274+275+// simplify drops the points of a path that lie on the line between276+// their neighbors.277+func simplify(pts [][2]float64) [][2]float64 {278+ if len(pts) < 3 {279+ return pts280+ }281+ out := [][2]float64{pts[0]}282+ for i := 1; i < len(pts)-1; i++ {283+ a, b, c := out[len(out)-1], pts[i], pts[i+1]284+ if math.Abs((b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0])) > 0.25 {285+ out = append(out, b)286+ }287+ }288+ return append(out, pts[len(pts)-1])289+}290+291+func points(pts [][2]float64) string {292+ var b strings.Builder293+ for i, p := range pts {294+ if i > 0 {295+ b.WriteByte(' ')296+ }297+ b.WriteString(num(p[0]) + "," + num(p[1]))298+ }299+ return b.String()300+}301+302+// num writes a coordinate to a tenth of a pixel, without trailing303+// zeros.304+func num(f float64) string {305+ s := fmt.Sprintf("%.1f", f)306+ s = strings.TrimSuffix(s, ".0")307+ if s == "-0" {308+ return "0"309+ }310+ return s311+}
A internal/chart/svg_test.go +71 -0
@@ -0,0 +1,71 @@
1+package chart2+3+import (4+ "encoding/xml"5+ "io"6+ "strings"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// TestSVGEveryType draws each type as SVG, checking it's well-formed13+// XML with the chart's labels as text and shapes of its own kind.14+func TestSVGEveryType(t *testing.T) {15+ cases := []struct {16+ typ sheet.ChartType17+ data sheet.ChartData18+ opts sheet.ChartOptions19+ shape string20+ }{21+ {sheet.ChartColumn, budget, sheet.ChartOptions{}, "<rect"},22+ {sheet.ChartBar, single, sheet.ChartOptions{}, "<rect"},23+ {sheet.ChartLine, budget, sheet.ChartOptions{}, "<polyline"},24+ {sheet.ChartArea, budget, sheet.ChartOptions{}, "<polygon"},25+ {sheet.ChartArea, budget, sheet.ChartOptions{Stack: sheet.StackNormal}, "<polygon"},26+ {sheet.ChartPie, single, sheet.ChartOptions{}, "<path"},27+ {sheet.ChartScatter, xy, sheet.ChartOptions{Trend: true}, "<circle"},28+ {sheet.ChartColumn, signs, sheet.ChartOptions{Stack: sheet.StackNormal}, "<rect"},29+ }30+ for _, c := range cases {31+ t.Run(c.typ.String(), func(t *testing.T) {32+ svg := SVG(c.typ, c.data, 60, 18, Options{Chart: c.opts}, "Budget & more")33+ d := xml.NewDecoder(strings.NewReader(svg))34+ for {35+ if _, err := d.Token(); err == io.EOF {36+ break37+ } else if err != nil {38+ t.Fatalf("not XML: %v\n%s", err, svg)39+ }40+ }41+ if !strings.Contains(svg, c.shape) {42+ t.Errorf("no %s in\n%s", c.shape, svg)43+ }44+ if !strings.Contains(svg, "<title>Budget &amp; more</title>") {45+ t.Errorf("no title")46+ }47+ if c.typ != sheet.ChartPie && !strings.Contains(svg, `class="ct-lb"`) {48+ t.Errorf("no labels")49+ }50+ })51+ }52+}53+54+// TestSVGAreaIsFewShapes joins an area's pixel columns into polygons.55+func TestSVGAreaIsFewShapes(t *testing.T) {56+ svg := SVG(sheet.ChartArea, single, 80, 20, Options{}, "")57+ if n := strings.Count(svg, "<polygon"); n == 0 || n > 3 {58+ t.Errorf("%d polygons", n)59+ }60+ if strings.Contains(svg, "<rect") {61+ t.Errorf("area columns drawn as rects")62+ }63+}64+65+// TestSVGNothingToPlot shows the text chart's message alone.66+func TestSVGNothingToPlot(t *testing.T) {67+ svg := SVG(sheet.ChartColumn, sheet.ChartData{}, 40, 10, Options{}, "")68+ if !strings.Contains(svg, "No numbers to chart") || strings.Contains(svg, "<g ") {69+ t.Errorf("got %s", svg)70+ }71+}
A internal/fileio/fonts/OFL.txt +93 -0
@@ -0,0 +1,93 @@
1+Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ThinItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLight.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-ExtraLightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Light.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-LightItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Regular.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Italic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Medium.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-MediumItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-SemiBoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-Bold.ttf: Copyright 2017 IBM Corp. All rights reserved. IBMPlexMono-BoldItalic.ttf: Copyright 2017 IBM Corp. All rights reserved.2+3+This Font Software is licensed under the SIL Open Font License, Version 1.1.4+This license is copied below, and is also available with a FAQ at:5+http://scripts.sil.org/OFL6+7+8+-----------------------------------------------------------9+SIL OPEN FONT LICENSE Version 1.1 - 26 February 200710+-----------------------------------------------------------11+12+PREAMBLE13+The goals of the Open Font License (OFL) are to stimulate worldwide14+development of collaborative font projects, to support the font creation15+efforts of academic and linguistic communities, and to provide a free and16+open framework in which fonts may be shared and improved in partnership17+with others.18+19+The OFL allows the licensed fonts to be used, studied, modified and20+redistributed freely as long as they are not sold by themselves. The21+fonts, including any derivative works, can be bundled, embedded,22+redistributed and/or sold with any software provided that any reserved23+names are not used by derivative works. The fonts and derivatives,24+however, cannot be released under any other type of license. The25+requirement for fonts to remain under this license does not apply26+to any document created using the fonts or their derivatives.27+28+DEFINITIONS29+"Font Software" refers to the set of files released by the Copyright30+Holder(s) under this license and clearly marked as such. This may31+include source files, build scripts and documentation.32+33+"Reserved Font Name" refers to any names specified as such after the34+copyright statement(s).35+36+"Original Version" refers to the collection of Font Software components as37+distributed by the Copyright Holder(s).38+39+"Modified Version" refers to any derivative made by adding to, deleting,40+or substituting -- in part or in whole -- any of the components of the41+Original Version, by changing formats or by porting the Font Software to a42+new environment.43+44+"Author" refers to any designer, engineer, programmer, technical45+writer or other person who contributed to the Font Software.46+47+PERMISSION & CONDITIONS48+Permission is hereby granted, free of charge, to any person obtaining49+a copy of the Font Software, to use, study, copy, merge, embed, modify,50+redistribute, and sell modified and unmodified copies of the Font51+Software, subject to the following conditions:52+53+1) Neither the Font Software nor any of its individual components,54+in Original or Modified Versions, may be sold by itself.55+56+2) Original or Modified Versions of the Font Software may be bundled,57+redistributed and/or sold with any software, provided that each copy58+contains the above copyright notice and this license. These can be59+included either as stand-alone text files, human-readable headers or60+in the appropriate machine-readable metadata fields within text or61+binary files as long as those fields can be easily viewed by the user.62+63+3) No Modified Version of the Font Software may use the Reserved Font64+Name(s) unless explicit written permission is granted by the corresponding65+Copyright Holder. This restriction only applies to the primary font name as66+presented to the users.67+68+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font69+Software shall not be used to promote, endorse or advertise any70+Modified Version, except to acknowledge the contribution(s) of the71+Copyright Holder(s) and the Author(s) or with their explicit written72+permission.73+74+5) The Font Software, modified or unmodified, in part or in whole,75+must be distributed entirely under this license, and must not be76+distributed under any other license. The requirement for fonts to77+remain under this license does not apply to any document created78+using the Font Software.79+80+TERMINATION81+This license becomes null and void if any of the above conditions are82+not met.83+84+DISCLAIMER85+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,86+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF87+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT88+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE89+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,90+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL91+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING92+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM93+OTHER DEALINGS IN THE FONT SOFTWARE.
A internal/fileio/fonts/ibm-plex-mono-latin-400-italic.woff2 +0 -0

Binary file.

A internal/fileio/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0

Binary file.

A internal/fileio/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0

Binary file.

M internal/fileio/formats.go +19 -1
@@ -19,6 +19,7 @@ const (
1919 WK12020 JSON2121 NUON22+ HTML2223 )2324 2425 // A fileFormat is everything about a Kind: its names, its extensions,
@@ -95,6 +96,10 @@ var kinds = []fileFormat{{
9596 kind: NUON, name: "NUON", noun: "NUON", label: "Nushell table (NUON)", exts: []string{".nuon"},9697 read: importNUON, write: exportNUON, menu: "Nushell table", encode: encodeNUON,9798 about: "Save the sheet as a nushell table that keeps its types, named by its first row",99+}, {100+ kind: HTML, name: "HTML", noun: "HTML", label: "Web page", exts: []string{".html", ".htm"},101+ write: exportHTML, menu: "Web page",102+ about: "Save the sheet as a web page in 012's look, with its charts, to share with anyone",98103 }}99104 100105 // unknownFormat is what an invalid Kind reports.
@@ -117,8 +122,18 @@ func Kinds() []Kind {
117122 return out118123 }119124 120-// KindOf recognizes a file's format by its extension.125+// KindOf recognizes a file 012 imports by its extension.121126 func KindOf(name string) (Kind, bool) {127+ k, ok := ExportKindOf(name)128+ if !ok || !k.CanImport() {129+ return 0, false130+ }131+ return k, true132+}133+134+// ExportKindOf recognizes a file's format by its extension, including135+// formats 012 only writes (HTML).136+func ExportKindOf(name string) (Kind, bool) {122137 ext := strings.ToLower(filepath.Ext(name))123138 for _, k := range kinds {124139 for _, e := range k.exts {
@@ -130,6 +145,9 @@ func KindOf(name string) (Kind, bool) {
130145 return 0, false131146 }132147 148+// CanImport reports whether 012 reads files of this kind.149+func (k Kind) CanImport() bool { return k.format().read != nil }150+133151 // String is the format's short name, e.g. "XLSX".134152 func (k Kind) String() string { return k.format().name }135153
M internal/fileio/formats_test.go +16 -6
A internal/fileio/html.go +125 -0
@@ -0,0 +1,125 @@
1+package fileio2+3+import (4+ "context"5+ "fmt"6+ "html"7+ "io"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// HTML exports are static pages in 012's look (see htmlstyle.go): the13+// control panel's lines above the grid, the grid with its headers and14+// charts, and a small script that puts the pointer on a cell clicked or15+// moved to with the arrow keys, showing its address in the name box and16+// what it holds in the formula bar, as the screen does. The page needs17+// nothing beyond itself: fonts, styles, SVG charts and script are in18+// the file.19+20+// HTMLPage is what an HTML page shows: a sheet or range, or one chart.21+type HTMLPage struct {22+ Title string // the page's title, and the first line's23+ Snap *Snapshot // the cells, when Chart is nil24+ Chart *SnapChart25+}26+27+// WriteHTML writes p as a page. The note, when there is one, says what28+// the page left out.29+func WriteHTML(w io.Writer, p HTMLPage) (note string, err error) {30+ body, name, where := "", "", ""31+ switch {32+ case p.Chart != nil:33+ body, name, where = HTMLChart(*p.Chart), p.Chart.Data.String(), p.Chart.Type.Title()+" chart of "+p.Chart.Data.String()34+ case p.Snap != nil:35+ body, note = HTMLGrid(p.Snap)36+ where = p.Snap.Name + "!" + p.Snap.Range.String()37+ }38+ _, err = io.WriteString(w, HTMLDocument(p.Title, HTMLPanel(p.Title, name, where)+body, ""))39+ return note, err40+}41+42+// HTMLDocument is a whole page: title, style sheet, body and script,43+// with extra added to the script (the MCP view's messages).44+func HTMLDocument(title, body, extra string) string {45+ return "<!doctype html>\n<html lang=\"en\"><head><meta charset=\"utf-8\">" +46+ "<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">" +47+ "<meta name=\"generator\" content=\"012\"><title>" + html.EscapeString(title) + "</title>\n<style>\n" +48+ HTMLStyle() + "</style></head>\n<body><div class=\"o12\">" + body +49+ "</div>\n<script>\n" + htmlScript + extra + "</script></body></html>\n"50+}51+52+// HTMLPanel is the control panel's three lines: the title with the53+// mode indicator, the name box (holding name until a cell is pointed54+// at) and formula bar, and the context line saying what the page55+// shows.56+func HTMLPanel(title, name, where string) string {57+ return fmt.Sprintf(`<header class="panel"><div><span class="book">%s</span><span class="mode">READY</span></div>`+58+ `<div><span class="namebox" id="o12-name">%s</span><span class="input" id="o12-input"></span></div>`+59+ `<div class="context" id="o12-context">%s</div></header>`, html.EscapeString(title), html.EscapeString(name), html.EscapeString(where))60+}61+62+// exportHTML writes a sheet or range as a page.63+func exportHTML(_ context.Context, name string, snap *Snapshot, _ ExportOptions) (*ExportResult, error) {64+ var note string65+ err := writeFile(name, func(w io.Writer) error {66+ var err error67+ note, err = WriteHTML(w, HTMLPage{Title: snap.Name, Snap: snap})68+ return err69+ })70+ if err != nil {71+ return nil, err72+ }73+ res := &ExportResult{Rows: snap.Range.To.Row - snap.Range.From.Row + 1}74+ if len(snap.Cells) == 0 {75+ res.Rows = 076+ }77+ if note != "" {78+ res.Notes = append(res.Notes, note)79+ }80+ return res, nil81+}82+83+// ChartSnap is chart i of s with the values it draws, for a page of84+// its own.85+func ChartSnap(s *sheet.Sheet, i int) (SnapChart, bool) {86+ charts := s.Charts()87+ if i < 0 || i >= len(charts) {88+ return SnapChart{}, false89+ }90+ return SnapChart{Chart: charts[i], Values: s.ChartData(charts[i])}, true91+}92+93+// htmlScript moves the pointer: a click or an arrow key puts it on a94+// cell, whose address goes in the name box, what was typed in it in95+// the formula bar, and whose row and column headers light up. It works96+// on grids added to the page later, as the MCP view adds them.97+const htmlScript = `(function(){98+var cur=null;99+function col(s){var n=0;for(var i=0;i<s.length;i++)n=n*26+s.charCodeAt(i)-64;return n}100+function name(n){var s="";while(n>0){n--;s=String.fromCharCode(65+n%26)+s;n=Math.floor(n/26)}return s}101+function split(a){var m=/^([A-Z]+)(\d+)$/.exec(a);return m?[col(m[1]),+m[2]]:null}102+function point(td){103+ if(cur){cur.classList.remove("ptr")}104+ document.querySelectorAll("th.on").forEach(function(t){t.classList.remove("on")});105+ cur=td;if(!td)return;106+ td.classList.add("ptr");107+ var a=td.getAttribute("data-a"),p=split(a),g=td.closest("table");108+ var nb=document.getElementById("o12-name"),inp=document.getElementById("o12-input");109+ if(nb)nb.textContent=a;110+ if(inp)inp.textContent=td.hasAttribute("data-f")?td.getAttribute("data-f"):td.textContent;111+ if(p&&g){var c=g.querySelector('th[data-c="'+name(p[0])+'"]'),r=g.querySelector('th[data-r="'+p[1]+'"]');112+ if(c)c.classList.add("on");if(r)r.classList.add("on")}113+}114+document.addEventListener("click",function(e){var td=e.target.closest&&e.target.closest("td[data-a]");if(td)point(td)});115+document.addEventListener("keydown",function(e){116+ if(!cur)return;var d={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]}[e.key];if(!d)return;117+ var p=split(cur.getAttribute("data-a")),g=cur.closest("table");if(!p||!g)return;118+ for(var k=1;k<64;k++){var n=g.querySelector('td[data-a="'+name(p[0]+d[0]*k)+(p[1]+d[1]*k)+'"]');119+ if(n){point(n);n.scrollIntoView({block:"nearest",inline:"nearest"});e.preventDefault();return}120+ if(p[0]+d[0]*k<1||p[1]+d[1]*k<1)return}121+});122+window.o12point=point;123+var first=document.querySelector("td[data-a]");if(first)point(first);124+})();125+`
A internal/fileio/html_test.go +139 -0
@@ -0,0 +1,139 @@
1+package fileio2+3+import (4+ "bytes"5+ "context"6+ "os"7+ "path/filepath"8+ "regexp"9+ "strings"10+ "testing"11+12+ "github.com/FelineStateMachine/012/internal/sheet"13+)14+15+// htmlBook is a sheet with a header, numbers, a formula, a style, a16+// merge, a note and a chart.17+func htmlBook(t *testing.T) *sheet.Sheet {18+ t.Helper()19+ s := sheet.New()20+ for a, in := range map[string]string{21+ "A1": "Month", "B1": "Sales", "A2": "Jan", "B2": "$1,200", "A3": "Feb", "B3": "900",22+ "A4": "Total", "B4": "=SUM(B2:B3)", "A6": "<b>not markup</b>",23+ } {24+ addr, _ := sheet.ParseAddr(a)25+ if err := s.Set(addr, in); err != nil {26+ t.Fatal(err)27+ }28+ }29+ s.SetStyle(sheet.Rect{To: sheet.Addr{Col: 1}}, func(st *sheet.Style) { st.Bold = true })30+ if err := s.SetNote(sheet.Addr{Row: 3}, "adds up"); err != nil {31+ t.Fatal(err)32+ }33+ if err := s.Merge(sheet.Rect{From: sheet.Addr{Row: 5}, To: sheet.Addr{Col: 1, Row: 5}}, sheet.MergeAll); err != nil {34+ t.Fatal(err)35+ }36+ s.AddChart(sheet.Chart{Type: sheet.ChartColumn, Data: sheet.Rect{To: sheet.Addr{Col: 1, Row: 2}}, Header: true, Labels: true,37+ Title: "Sales by month", At: sheet.Addr{Col: 3, Row: 1}, W: 40, H: 14})38+ return s39+}40+41+// TestHTMLPage exports a sheet as a page that holds everything it42+// needs: fonts, styles, the cells as shown, the chart as SVG.43+func TestHTMLPage(t *testing.T) {44+ s := htmlBook(t)45+ path := filepath.Join(t.TempDir(), "sales.html")46+ k, ok := ExportKindOf(path)47+ if !ok || k != HTML || k.CanImport() {48+ t.Fatalf("ExportKindOf = %v, %v", k, ok)49+ }50+ if _, ok := KindOf(path); ok {51+ t.Errorf("an HTML file is offered for import")52+ }53+ res, err := Export(context.Background(), path, HTML, Snap(s, sheet.Rect{}, "Sales"), ExportOptions{})54+ if err != nil {55+ t.Fatal(err)56+ }57+ if res.Rows != 6 || len(res.Notes) != 0 {58+ t.Errorf("rows %d, notes %q", res.Rows, res.Notes)59+ }60+ data, err := os.ReadFile(path)61+ if err != nil {62+ t.Fatal(err)63+ }64+ page := string(data)65+ for _, want := range []string{66+ "<title>Sales</title>", "@font-face{font-family:'IBM Plex Mono'", "data:font/woff2;base64,",67+ `<th data-c="A">A</th>`, `data-a="B1" class="b">Sales<`, `data-a="A2" class="clip">Jan<`, `data-a="B2" class="r">$1,200<`,68+ `data-f="=SUM(B2:B3)">$2,100<`, `class="clip note" title="adds up"`, `colspan="2" rowspan="1"`, "&lt;b&gt;not markup&lt;/b&gt;",69+ `<figure class="chart"`, "<svg", "<figcaption>Sales by month</figcaption>", `class="range">A1:B3<`,70+ "prefers-color-scheme:light", "READY",71+ } {72+ if !strings.Contains(page, want) {73+ t.Errorf("page lacks %q", want)74+ }75+ }76+ // Nothing is fetched from elsewhere.77+ if m := regexp.MustCompile(`(src|href)="?https?:`).FindString(page); m != "" {78+ t.Errorf("page loads %s", m)79+ }80+}81+82+// TestHTMLRange exports a range, with the charts anchored in it.83+func TestHTMLRange(t *testing.T) {84+ s := htmlBook(t)85+ var b bytes.Buffer86+ snap := Snap(s, sheet.Rect{From: sheet.Addr{Row: 1}, To: sheet.Addr{Col: 1, Row: 2}}, "Sales")87+ if _, err := WriteHTML(&b, HTMLPage{Title: "Sales", Snap: snap}); err != nil {88+ t.Fatal(err)89+ }90+ page := b.String()91+ if strings.Contains(page, `data-a="A1"`) || !strings.Contains(page, `data-a="B3"`) || strings.Contains(page, "<svg") {92+ t.Errorf("range page wrong:\n%s", page[strings.Index(page, "<body>"):])93+ }94+ if !strings.Contains(page, `id="o12-context">Sales!A2:B3<`) {95+ t.Errorf("context line doesn't name the range")96+ }97+}98+99+// TestHTMLChartPage draws one chart on its own page.100+func TestHTMLChartPage(t *testing.T) {101+ s := htmlBook(t)102+ c, ok := ChartSnap(s, 0)103+ if !ok {104+ t.Fatal("no chart")105+ }106+ if _, ok := ChartSnap(s, 1); ok {107+ t.Error("chart 1 found")108+ }109+ var b bytes.Buffer110+ if _, err := WriteHTML(&b, HTMLPage{Title: "Sales by month", Chart: &c}); err != nil {111+ t.Fatal(err)112+ }113+ page := b.String()114+ if !strings.Contains(page, `<figure class="chart solo"`) || !strings.Contains(page, "<rect") || strings.Contains(page, "<table") {115+ t.Errorf("chart page wrong")116+ }117+}118+119+// TestHTMLLooks draws a rule's fill and text color.120+func TestHTMLLooks(t *testing.T) {121+ s := sheet.New()122+ for i, in := range []string{"5", "50"} {123+ if err := s.Set(sheet.Addr{Row: i}, in); err != nil {124+ t.Fatal(err)125+ }126+ }127+ err := s.AddCondFormat(sheet.CondFormat{Ranges: []sheet.Rect{{To: sheet.Addr{Row: 1}}}, Op: sheet.RuleGreater, Args: [2]string{"10"},128+ Style: sheet.RuleStyle{Fill: sheet.ColorGreen, Bold: true}})129+ if err != nil {130+ t.Fatal(err)131+ }132+ grid, _ := HTMLGrid(Snap(s, sheet.Rect{}, "S"))133+ if !strings.Contains(grid, `data-a="A2" class="r b" style="background:var(--r3);color:var(--i3)"`) {134+ t.Errorf("rule not drawn:\n%s", grid)135+ }136+ if strings.Contains(grid, `data-a="A1" class="r b"`) {137+ t.Errorf("rule drawn where it doesn't apply")138+ }139+}
A internal/fileio/htmlcell.go +221 -0
@@ -0,0 +1,221 @@
1+package fileio2+3+import (4+ "fmt"5+ "html"6+ "strings"7+8+ "github.com/FelineStateMachine/012/internal/sheet"9+)10+11+// htmlCell is what a td says about its cell: classes, inline styles,12+// attributes and the text shown.13+type htmlCell struct {14+ class []string15+ style []string16+ attrs string17+ text string18+ icon string // an icon set's glyph, before the text19+}20+21+// writeCell writes the td of the cell at a: spanning a merge, with the22+// text as the grid shows it at the cell's width.23+func (l *htmlLayout) writeCell(b *strings.Builder, a sheet.Addr) {24+ snap := l.snap25+ var h htmlCell26+ width := htmlColWidth(snap, a.Col)27+ if m, ok := l.merged[a]; ok {28+ width = 029+ for col := m.From.Col; col <= m.To.Col; col++ {30+ width += htmlColWidth(snap, col)31+ }32+ h.attrs += fmt.Sprintf(` colspan="%d" rowspan="%d"`, m.To.Col-m.From.Col+1, l.visibleRows(m))33+ }34+ c, filled := snap.Cells[a]35+ if filled {36+ h.content(snap, c, width)37+ h.textStyle(c.Style)38+ h.borders(c.Style.Borders)39+ if c.Style.Wrap == sheet.WrapOverflow && h.text != "" && l.nextFilled(a) {40+ h.class = append(h.class, "clip")41+ }42+ }43+ if look, ok := snap.Looks[a]; ok {44+ h.look(look)45+ }46+ if role := l.tableRole[a]; role != "" {47+ h.class = append(h.class, role)48+ }49+ if note, ok := snap.Notes[a]; ok {50+ h.class = append(h.class, "note")51+ h.attrs += ` title="` + html.EscapeString(note) + `"`52+ }53+ fmt.Fprintf(b, `<td data-a="%s"`, a)54+ if len(h.class) > 0 {55+ b.WriteString(` class="` + strings.Join(h.class, " ") + `"`)56+ }57+ if len(h.style) > 0 {58+ b.WriteString(` style="` + html.EscapeString(strings.Join(h.style, ";")) + `"`)59+ }60+ b.WriteString(h.attrs + ">")61+ if h.icon != "" {62+ b.WriteString(h.icon)63+ }64+ b.WriteString(html.EscapeString(h.text) + "</td>")65+}66+67+// visibleRows is how many drawn rows a merge spans.68+func (l *htmlLayout) visibleRows(m sheet.Rect) int {69+ n := 070+ for row := m.From.Row; row <= m.To.Row; row++ {71+ if !l.snap.HiddenRows[row] {72+ n++73+ }74+ }75+ return max(n, 1)76+}77+78+// nextFilled reports whether the cell right of a holds something, which79+// a's text stops at rather than running on, as in Sheets.80+func (l *htmlLayout) nextFilled(a sheet.Addr) bool {81+ next := sheet.Addr{Col: a.Col + 1, Row: a.Row}82+ c, ok := l.snap.Cells[next]83+ return ok && (c.Input != "" || c.Value.Kind != sheet.Empty) || l.covered[next]84+}85+86+// content is the cell's text as the grid shows it in width columns,87+// where it goes, and what was typed when that isn't the text.88+func (h *htmlCell) content(snap *Snapshot, c SnapCell, width int) {89+ text, align := sheet.DisplayIn(c.Value, c.Format, width, snap.Locale)90+ h.text = text91+ switch c.Style.Align {92+ case sheet.AlignLeft:93+ align = sheet.AlignLeft94+ case sheet.AlignCenter:95+ align = sheet.AlignCenter96+ case sheet.AlignRight:97+ align = sheet.AlignRight98+ }99+ switch align {100+ case sheet.AlignRight:101+ h.class = append(h.class, "r")102+ case sheet.AlignCenter:103+ h.class = append(h.class, "c")104+ }105+ if c.Value.Kind == sheet.Error {106+ h.class = append(h.class, "err")107+ }108+ if c.Input != "" && c.Input != text {109+ h.attrs += ` data-f="` + html.EscapeString(c.Input) + `"`110+ }111+ switch c.Style.Wrap {112+ case sheet.WrapOn:113+ h.class = append(h.class, "wrap")114+ case sheet.WrapClip:115+ h.class = append(h.class, "clip")116+ }117+ switch c.Style.VAlign {118+ case sheet.VAlignTop:119+ h.class = append(h.class, "t")120+ case sheet.VAlignMiddle:121+ h.class = append(h.class, "m")122+ }123+}124+125+// textStyle adds bold, italic, underline and strikethrough.126+func (h *htmlCell) textStyle(st sheet.Style) {127+ for _, f := range []struct {128+ on bool129+ class string130+ }{{st.Bold, "b"}, {st.Italic, "i"}, {st.Underline, "u"}, {st.Strikethrough, "s"}} {131+ if f.on {132+ h.class = append(h.class, f.class)133+ }134+ }135+}136+137+// borders draws each edge's line in its color, or the border role's138+// when it has none.139+func (h *htmlCell) borders(b sheet.Borders) {140+ if b.IsZero() {141+ return142+ }143+ for _, e := range []struct {144+ edge sheet.Edge145+ side string146+ }{{sheet.EdgeTop, "top"}, {sheet.EdgeBottom, "bottom"}, {sheet.EdgeLeft, "left"}, {sheet.EdgeRight, "right"}} {147+ st := b.Stroke(e.edge)148+ line := ""149+ switch st.Line {150+ case sheet.LineThin:151+ line = "1px solid"152+ case sheet.LineThick:153+ line = "2px solid"154+ case sheet.LineDouble:155+ line = "3px double"156+ default:157+ continue158+ }159+ color := "var(--border)"160+ if st.Color != sheet.ColorNone {161+ color = ruleVar(st.Color)162+ }163+ h.style = append(h.style, "border-"+e.side+":"+line+" "+color)164+ }165+}166+167+func ruleVar(c sheet.Color) string { return fmt.Sprintf("var(--r%d)", int(c)) }168+func inkVar(c sheet.Color) string { return fmt.Sprintf("var(--i%d)", int(c)) }169+170+// look draws what the sheet's rules show: a conditional format's171+// colors and text style, a color scale, a data bar, an icon, a172+// checkbox, a dropdown's marker and an invalid entry's underline.173+func (h *htmlCell) look(l sheet.Look) {174+ if l.Styled {175+ h.ruleStyle(l.Style)176+ }177+ if l.Scaled {178+ pct := int(l.Pos*100 + 0.5)179+ h.style = append(h.style, fmt.Sprintf("background:color-mix(in srgb,%s %d%%,%s)", ruleVar(l.To), pct, ruleVar(l.From)))180+ ink := l.From181+ if l.Pos >= 0.5 {182+ ink = l.To183+ }184+ h.style = append(h.style, "color:"+inkVar(ink))185+ }186+ if l.Bar {187+ pct := int(l.BarLen*100 + 0.5)188+ h.style = append(h.style, fmt.Sprintf("background:linear-gradient(to right,color-mix(in srgb,%s 55%%,transparent) %d%%,transparent %d%%)",189+ ruleVar(l.BarColor), pct, pct))190+ }191+ if l.ValueHidden {192+ h.text = ""193+ }194+ if l.Icon != "" {195+ h.icon = fmt.Sprintf(`<span class="icon" style="color:%s">%s</span>`, ruleVar(l.IconColor), html.EscapeString(l.Icon))196+ }197+ switch {198+ case l.Checkbox && l.Checked:199+ h.text, h.class = "[✓]", append(h.class, "c")200+ case l.Checkbox:201+ h.text, h.class = "[ ]", append(h.class, "c")202+ case l.Dropdown:203+ h.text += " ▾"204+ }205+ if l.Invalid {206+ h.class = append(h.class, "bad")207+ }208+}209+210+// ruleStyle is a single-color rule's fill, text color and text style.211+func (h *htmlCell) ruleStyle(st sheet.RuleStyle) {212+ switch {213+ case st.Fill != sheet.ColorNone && (st.Text == sheet.ColorNone || st.Text == st.Fill):214+ h.style = append(h.style, "background:"+ruleVar(st.Fill), "color:"+inkVar(st.Fill))215+ case st.Fill != sheet.ColorNone:216+ h.style = append(h.style, "background:"+ruleVar(st.Fill), "color:"+ruleVar(st.Text))217+ case st.Text != sheet.ColorNone:218+ h.style = append(h.style, "color:"+ruleVar(st.Text))219+ }220+ h.textStyle(sheet.Style{Bold: st.Bold, Italic: st.Italic, Underline: st.Underline, Strikethrough: st.Strikethrough})221+}
A internal/fileio/htmlgrid.go +239 -0
@@ -0,0 +1,239 @@
1+package fileio2+3+import (4+ "fmt"5+ "html"6+ "sort"7+ "strconv"8+ "strings"9+10+ "github.com/FelineStateMachine/012/internal/chart"11+ "github.com/FelineStateMachine/012/internal/sheet"12+)13+14+// maxHTMLCells bounds the cells a page draws, blank ones included: a15+// browser shows a table of about this many at once without trouble.16+// Past it the page draws the first rows and says so.17+const maxHTMLCells = 200_00018+19+// htmlLayout is where the grid's rows and columns go: the columns and20+// rows drawn, in order, and the pixel offset of each from the grid's21+// top-left corner, headers included.22+type htmlLayout struct {23+ snap *Snapshot24+ cols, rows []int25+ x, y map[int]int // left edge of a column, top edge of a row26+ headW int // the row numbers' width27+ cut int // rows left out past maxHTMLCells28+ merged map[sheet.Addr]sheet.Rect29+ covered map[sheet.Addr]bool30+ tableRole map[sheet.Addr]string31+}32+33+// layout places the snapshot's range, grown to hold its charts.34+func layout(snap *Snapshot) *htmlLayout {35+ r := snap.Range36+ colsTo, rowsTo := r.To.Col, r.To.Row37+ for _, c := range snap.Charts {38+ colsTo = max(colsTo, chartEndCol(snap, c))39+ rowsTo = max(rowsTo, chartEndRow(snap, c))40+ }41+ l := &htmlLayout{snap: snap, x: map[int]int{}, y: map[int]int{}}42+ for col := r.From.Col; col <= min(colsTo, sheet.MaxCols-1); col++ {43+ l.cols = append(l.cols, col)44+ }45+ maxRows := max(maxHTMLCells/max(len(l.cols), 1), 100)46+ for row := r.From.Row; row <= min(rowsTo, sheet.MaxRows-1); row++ {47+ if snap.HiddenRows[row] {48+ continue49+ }50+ if len(l.rows) == maxRows {51+ l.cut = rowsTo - row + 152+ break53+ }54+ l.rows = append(l.rows, row)55+ }56+ last := r.From.Row + 157+ if len(l.rows) > 0 {58+ last = l.rows[len(l.rows)-1] + 159+ }60+ l.headW = (max(len(strconv.Itoa(last)), 3) + 2) * htmlCellW61+ x := l.headW62+ for _, col := range l.cols {63+ l.x[col] = x64+ x += htmlColWidth(snap, col) * htmlCellW65+ }66+ y := htmlCellH67+ for _, row := range l.rows {68+ l.y[row] = y69+ y += htmlRowHeight(snap, row) * htmlCellH70+ }71+ l.mergesAndTables()72+ return l73+}74+75+func htmlColWidth(snap *Snapshot, col int) int {76+ if w, ok := snap.Widths[col]; ok {77+ return w78+ }79+ return sheet.DefaultWidth80+}81+82+func htmlRowHeight(snap *Snapshot, row int) int {83+ if h, ok := snap.Heights[row]; ok && h > 0 {84+ return h85+ }86+ return 187+}88+89+// chartEndCol is the last column a chart covers.90+func chartEndCol(snap *Snapshot, c SnapChart) int {91+ col, w := c.At.Col, c.W92+ for w > htmlColWidth(snap, col) && col < sheet.MaxCols-1 {93+ w -= htmlColWidth(snap, col)94+ col++95+ }96+ return col97+}98+99+// chartEndRow is the last row a chart covers.100+func chartEndRow(snap *Snapshot, c SnapChart) int {101+ row, h := c.At.Row, c.H102+ for h > htmlRowHeight(snap, row) && row < sheet.MaxRows-1 {103+ h -= htmlRowHeight(snap, row)104+ row++105+ }106+ return row107+}108+109+// mergesAndTables notes the merged cells and the cells tables style.110+func (l *htmlLayout) mergesAndTables() {111+ l.merged, l.covered, l.tableRole = map[sheet.Addr]sheet.Rect{}, map[sheet.Addr]bool{}, map[sheet.Addr]string{}112+ for _, m := range l.snap.Merges {113+ l.merged[m.From] = m114+ for row := m.From.Row; row <= m.To.Row; row++ {115+ for col := m.From.Col; col <= m.To.Col; col++ {116+ if a := (sheet.Addr{Col: col, Row: row}); a != m.From {117+ l.covered[a] = true118+ }119+ }120+ }121+ }122+ for _, t := range l.snap.Tables {123+ for col := t.Range.From.Col; col <= t.Range.To.Col; col++ {124+ if t.Header {125+ l.tableRole[sheet.Addr{Col: col, Row: t.Range.From.Row}] = "th"126+ }127+ for row := t.Range.From.Row + 2; t.Banded && row <= t.Range.To.Row; row += 2 {128+ l.tableRole[sheet.Addr{Col: col, Row: row}] = "band"129+ }130+ }131+ }132+}133+134+// HTMLGrid draws the snapshot as 012's grid: column letters and row135+// numbers, the cells as they show with their styles, borders and the136+// looks of rules, and the charts over them. It returns the fragment and137+// a note when rows were left out.138+func HTMLGrid(snap *Snapshot) (string, string) {139+ l := layout(snap)140+ var b strings.Builder141+ b.WriteString(`<div class="sheet"><table class="grid"><colgroup>`)142+ fmt.Fprintf(&b, `<col style="width:%dpx">`, l.headW)143+ for _, col := range l.cols {144+ fmt.Fprintf(&b, `<col style="width:%dpx">`, htmlColWidth(snap, col)*htmlCellW)145+ }146+ b.WriteString(`</colgroup><thead><tr><th class="corner"></th>`)147+ for _, col := range l.cols {148+ fmt.Fprintf(&b, `<th data-c="%s">%s</th>`, sheet.ColName(col), sheet.ColName(col))149+ }150+ b.WriteString("</tr></thead><tbody>")151+ for _, row := range l.rows {152+ l.writeRow(&b, row)153+ }154+ b.WriteString("</tbody></table>")155+ for _, c := range snap.Charts {156+ l.writeChart(&b, c)157+ }158+ b.WriteString("</div>")159+ note := ""160+ if l.cut > 0 {161+ note = fmt.Sprintf("HTML pages show the first %d rows: %d more are left out", len(l.rows), l.cut)162+ }163+ return b.String(), note164+}165+166+func (l *htmlLayout) writeRow(b *strings.Builder, row int) {167+ style := ""168+ if h := htmlRowHeight(l.snap, row); h > 1 {169+ style = fmt.Sprintf(` style="height:%dpx"`, h*htmlCellH)170+ }171+ fmt.Fprintf(b, `<tr%s><th data-r="%d">%d</th>`, style, row+1, row+1)172+ for _, col := range l.cols {173+ a := sheet.Addr{Col: col, Row: row}174+ if l.covered[a] {175+ continue176+ }177+ l.writeCell(b, a)178+ }179+ b.WriteString("</tr>")180+}181+182+// writeChart draws a chart in its frame over the cells under it, as183+// the screen does: the title in the top border, the range in the184+// bottom one.185+func (l *htmlLayout) writeChart(b *strings.Builder, c SnapChart) {186+ x, y := l.at(c.At)187+ fmt.Fprintf(b, `<figure class="chart" style="left:%dpx;top:%dpx;width:%dpx;height:%dpx">`,188+ x, y, c.W*htmlCellW, c.H*htmlCellH)189+ writeChartBody(b, c)190+ b.WriteString("</figure>")191+}192+193+// writeChartBody is a chart's frame labels and drawing, inside its194+// figure.195+func writeChartBody(b *strings.Builder, c SnapChart) {196+ fmt.Fprintf(b, `<figcaption>%s</figcaption>`, html.EscapeString(chartTitle(c.Chart)))197+ b.WriteString(chart.SVG(c.Type, c.Values, c.W-4, c.H-2, chart.Options{Chart: c.ChartOptions}, chartTitle(c.Chart)))198+ fmt.Fprintf(b, `<span class="range">%s</span>`, c.Data.String())199+}200+201+// chartTitle is a chart's title, or its type's name when it has none.202+func chartTitle(c sheet.Chart) string {203+ if c.Title != "" {204+ return c.Title205+ }206+ return c.Type.Title() + " chart"207+}208+209+// at is the pixel offset of a cell's top-left corner; a cell in a210+// hidden row or past the drawn ones sits where the next drawn one does.211+func (l *htmlLayout) at(a sheet.Addr) (int, int) {212+ x, ok := l.x[a.Col]213+ if !ok {214+ x = l.headW215+ }216+ y, ok := l.y[a.Row]217+ if !ok {218+ i := sort.SearchInts(l.rows, a.Row)219+ switch {220+ case i < len(l.rows):221+ y = l.y[l.rows[i]]222+ case len(l.rows) > 0:223+ last := l.rows[len(l.rows)-1]224+ y = l.y[last] + htmlRowHeight(l.snap, last)*htmlCellH225+ default:226+ y = htmlCellH227+ }228+ }229+ return x, y230+}231+232+// HTMLChart draws one chart alone, in its frame.233+func HTMLChart(c SnapChart) string {234+ var b strings.Builder235+ fmt.Fprintf(&b, `<figure class="chart solo" style="width:%dpx;height:%dpx">`, c.W*htmlCellW, c.H*htmlCellH)236+ writeChartBody(&b, c)237+ b.WriteString("</figure>")238+ return b.String()239+}
A internal/fileio/htmlstyle.go +169 -0
@@ -0,0 +1,169 @@
1+package fileio2+3+import (4+ "embed"5+ "encoding/base64"6+ "fmt"7+ "math"8+ "strings"9+ "sync"10+11+ "github.com/FelineStateMachine/012/internal/chart"12+ "github.com/FelineStateMachine/012/internal/sheet"13+)14+15+// HTML pages are drawn in 012's look: the 16 ANSI colors of the16+// reference palettes the golden screens use (e2e/palette_test.go),17+// mapped to the roles the terminal theme gives them18+// (internal/ui/theme), dark or light as the reader's system prefers,19+// in IBM Plex Mono, the docs site's font, embedded so the page needs20+// nothing else. One cell is htmlCellW by htmlCellH pixels, the size of21+// a cell of an SVG chart, so charts sit on the grid as on the screen.22+23+const (24+ htmlCellW = chart.SVGCellW25+ htmlCellH = chart.SVGCellH26+)27+28+//go:embed fonts/*.woff229+var fonts embed.FS30+31+// htmlPalette is a reference palette and the roles drawn in it.32+type htmlPalette struct {33+ ansi [16]uint3234+ bg, fg uint3235+ grid uint32 // the faint lines between cells36+ // ANSI slots of the roles.37+ headerBg, headerFg, bar, muted, border, note, link int38+ series [chart.Colors]int39+}40+41+var htmlPalettes = [2]htmlPalette{{42+ ansi: [16]uint32{0x1d1f21, 0xcc6666, 0xb5bd68, 0xf0c674, 0x81a2be, 0xb294bb, 0x8abeb7, 0xc5c8c6,43+ 0x666666, 0xd54e53, 0xb9ca4a, 0xe7c547, 0x7aa6da, 0xc397d8, 0x70c0b1, 0xeaeaea},44+ bg: 0x1d1f21, fg: 0xc5c8c6, grid: 0x2c2e30,45+ headerBg: 8, headerFg: 15, bar: 6, muted: 8, border: 7, note: 3, link: 12,46+ series: [chart.Colors]int{6, 5, 3, 2, 12, 9},47+}, {48+ ansi: [16]uint32{0x1d1f21, 0xc82829, 0x718c00, 0xb58900, 0x4271ae, 0x8959a8, 0x3e999f, 0xd6d6d6,49+ 0x8e908c, 0xc82829, 0x718c00, 0xb58900, 0x4271ae, 0x8959a8, 0x3e999f, 0xffffff},50+ bg: 0xfafafa, fg: 0x1d1f21, grid: 0xe8e8e8,51+ headerBg: 7, headerFg: 0, bar: 4, muted: 0, border: 0, note: 5, link: 4,52+ series: [chart.Colors]int{4, 5, 2, 1, 6, 8},53+}}54+55+// ruleSlots are the ANSI slots of sheet.Color, as the theme maps them.56+var ruleSlots = [sheet.NumColors]int{0, 1, 3, 2, 6, 4, 5}57+58+// vars writes the palette's CSS variables.59+func (p htmlPalette) vars() string {60+ var b strings.Builder61+ hex := func(v uint32) string { return fmt.Sprintf("#%06x", v) }62+ slot := func(i int) string { return hex(p.ansi[i]) }63+ fmt.Fprintf(&b, "--bg:%s;--fg:%s;--grid:%s;--hbg:%s;--hfg:%s;--bar:%s;--muted:%s;--border:%s;--note:%s;--link:%s;--axis:%s;--acc:%s;--accfg:%s;",64+ hex(p.bg), hex(p.fg), hex(p.grid), slot(p.headerBg), slot(p.headerFg), slot(p.bar), slot(p.muted),65+ slot(p.border), slot(p.note), slot(p.link), slot(8), slot(6), slot(0))66+ for i, s := range p.series {67+ fmt.Fprintf(&b, "--s%d:%s;", i, slot(s))68+ }69+ for c := 1; c < sheet.NumColors; c++ {70+ fill := p.ansi[ruleSlots[c]]71+ fmt.Fprintf(&b, "--r%d:%s;--i%d:%s;", c, hex(fill), c, hex(p.ink(fill)))72+ }73+ return b.String()74+}75+76+// ink is black or bright white, whichever reads better on bg.77+func (p htmlPalette) ink(bg uint32) uint32 {78+ if contrast(p.ansi[0], bg) >= contrast(p.ansi[15], bg) {79+ return p.ansi[0]80+ }81+ return p.ansi[15]82+}83+84+// contrast is the WCAG contrast ratio of two colors.85+func contrast(a, b uint32) float64 {86+ la, lb := luminance(a), luminance(b)87+ return (max(la, lb) + 0.05) / (min(la, lb) + 0.05)88+}89+90+func luminance(c uint32) float64 {91+ ch := func(v uint32) float64 {92+ s := float64(v&0xff) / 25593+ if s <= 0.03928 {94+ return s / 12.9295+ }96+ return math.Pow((s+0.055)/1.055, 2.4)97+ }98+ return 0.2126*ch(c>>16) + 0.7152*ch(c>>8) + 0.0722*ch(c)99+}100+101+// htmlCSS is the style sheet every page and view shares, fonts102+// included.103+var htmlCSS = sync.OnceValue(func() string {104+ var b strings.Builder105+ for _, f := range []struct{ file, weight, style string }{106+ {"ibm-plex-mono-latin-400-normal.woff2", "400", "normal"},107+ {"ibm-plex-mono-latin-600-normal.woff2", "600", "normal"},108+ {"ibm-plex-mono-latin-400-italic.woff2", "400", "italic"},109+ } {110+ data, _ := fonts.ReadFile("fonts/" + f.file)111+ fmt.Fprintf(&b, "@font-face{font-family:'IBM Plex Mono';font-weight:%s;font-style:%s;src:url(data:font/woff2;base64,%s) format('woff2')}\n",112+ f.weight, f.style, base64.StdEncoding.EncodeToString(data))113+ }114+ dark, light := htmlPalettes[0].vars(), htmlPalettes[1].vars()115+ fmt.Fprintf(&b, ":root{%s}\n@media (prefers-color-scheme:light){:root:not(.dark){%s}}\n:root.light{%s}\n", dark, light, light)116+ b.WriteString(htmlRules)117+ return b.String()118+})119+120+// HTMLStyle is the style sheet of 012's HTML pages, for a page built121+// around HTMLGrid or HTMLChart; the root element takes the class dark122+// or light to choose a palette over the reader's preference.123+func HTMLStyle() string { return htmlCSS() }124+125+// htmlRules are the page's rules, after its fonts and palettes.126+const htmlRules = `*{box-sizing:border-box}127+html,body{margin:0;background:var(--bg);color:var(--fg)}128+body{font:15px/21px 'IBM Plex Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;font-variant-ligatures:none}129+.o12{min-width:100%;width:max-content}130+.panel{position:sticky;left:0;top:0;z-index:3;background:var(--bg);white-space:pre;width:100vw;max-width:100%}131+.panel>div{height:21px;display:flex;gap:9px;overflow:hidden}132+.panel .book{flex:1;overflow:hidden;text-overflow:ellipsis}133+.mode{background:var(--acc);color:var(--accfg);font-weight:600;padding:0 9px}134+.namebox{background:var(--hbg);color:var(--hfg);min-width:90px;padding:0 9px}135+.input{flex:1;overflow:hidden;text-overflow:ellipsis}136+.context{color:var(--muted)}137+.sheet{position:relative}138+table.grid{border-collapse:collapse;table-layout:fixed;width:max-content}139+.grid th{background:var(--hbg);color:var(--hfg);font-weight:400;height:21px;padding:0;text-align:center;position:sticky;z-index:1}140+.grid thead th{top:63px}141+.grid tbody th{left:0;text-align:right;padding-right:9px;vertical-align:bottom}142+.grid thead th.corner{left:0;z-index:2}143+.grid th.on{background:var(--acc);color:var(--accfg);font-weight:600}144+.grid td{height:21px;padding:0 4px;white-space:pre;overflow:visible;box-shadow:inset -1px -1px 0 var(--grid);vertical-align:bottom;position:relative}145+.grid td.clip{overflow:hidden}146+.grid td.wrap{white-space:pre-wrap;overflow-wrap:anywhere}147+.grid td.r{text-align:right}.grid td.c{text-align:center}.grid td.l{text-align:left}148+.grid td.t{vertical-align:top}.grid td.m{vertical-align:middle}149+.grid td.b{font-weight:600}.grid td.i{font-style:italic}150+.grid td.u{text-decoration:underline}.grid td.s{text-decoration:line-through}.grid td.u.s{text-decoration:underline line-through}151+.grid td.err{text-decoration:underline wavy var(--r1)}152+.grid td.bad{text-decoration:underline dotted var(--r2)}153+.grid td.th{font-weight:600;text-decoration:underline;color:var(--bar)}154+.grid td.band{background:var(--hbg);color:var(--hfg)}155+.grid td.note::after{content:'\259D';position:absolute;right:0;top:-3px;color:var(--note);font-size:12px}156+.grid td.ptr{outline:2px solid var(--acc);outline-offset:-2px}157+.grid a{color:var(--link)}158+.grid .icon{margin-right:9px}159+figure.chart{position:absolute;margin:0;border:1px solid var(--axis);background:var(--bg);padding:20px 17px;z-index:1}160+figure.chart figcaption{position:absolute;top:-11px;left:9px;background:var(--bg);padding:0 9px;font-weight:600;white-space:pre}161+figure.chart .range{position:absolute;bottom:-11px;right:9px;background:var(--bg);padding:0 9px;color:var(--muted);white-space:pre}162+figure.solo{position:relative;display:inline-block;margin:21px 18px}163+svg.chart{display:block;overflow:visible;font:15px 'IBM Plex Mono',ui-monospace,monospace}164+.ct-ax{fill:var(--axis);color:var(--axis)}.ct-lb{fill:var(--muted);color:var(--muted)}.ct-mu{fill:var(--muted);color:var(--muted)}165+.cs-box{stroke:currentColor;stroke-width:1}.cs-gl{stroke:var(--grid);stroke-width:1}.cs-gap{stroke:var(--bg);stroke-width:1.5}166+.ct-s0,.cf-0{fill:var(--s0)}.ct-s1,.cf-1{fill:var(--s1)}.ct-s2,.cf-2{fill:var(--s2)}.ct-s3,.cf-3{fill:var(--s3)}.ct-s4,.cf-4{fill:var(--s4)}.ct-s5,.cf-5{fill:var(--s5)}167+.cs-0{stroke:var(--s0)}.cs-1{stroke:var(--s1)}.cs-2{stroke:var(--s2)}.cs-3{stroke:var(--s3)}.cs-4{stroke:var(--s4)}.cs-5{stroke:var(--s5)}168+.status{white-space:pre;color:var(--muted);padding:0 9px;height:21px}169+`
A internal/fileio/snapdrawn.go +32 -0
M internal/fileio/snapshot.go +7 -0
A internal/headless/build.go +151 -0
@@ -0,0 +1,151 @@
1+package headless2+3+import (4+ "fmt"5+ "strings"6+7+ "github.com/FelineStateMachine/012/internal/sheet"8+)9+10+// ChartSpec is a chart to add, as Insert > Chart makes one: over Data,11+// with the header row, category labels and title guessed as Sheets12+// guesses them unless given.13+type ChartSpec struct {14+ Data string `json:"data" jsonschema:"the range to chart, e.g. Q3!A1:C9"`15+ Type string `json:"type,omitempty" jsonschema:"column, bar, line, pie, area or scatter; column when empty"`16+ Title string `json:"title,omitempty" jsonschema:"the title; guessed from the series when empty"`17+ At string `json:"at,omitempty" jsonschema:"the cell under the chart's top-left corner; right of the data when empty"`18+ Width int `json:"width,omitempty" jsonschema:"the width in terminal cells, 20 to 240; 60 when 0"`19+ Height int `json:"height,omitempty" jsonschema:"the height in terminal cells, 8 to 120; 18 when 0"`20+ ByRow bool `json:"by_row,omitempty" jsonschema:"series run along rows rather than down columns"`21+ Stack string `json:"stack,omitempty" jsonschema:"stacked or percent, for column, bar and area charts"`22+}23+24+// ChartMade says which chart AddChart made: its sheet and number, as25+// describe lists it.26+type ChartMade struct {27+ Sheet string `json:"sheet"`28+ Number int `json:"number"`29+ Title string `json:"title"`30+}31+32+// AddChart adds a chart as spec says.33+func AddChart(w *sheet.Workbook, spec ChartSpec) (ChartMade, error) {34+ t, err := Resolve(w, spec.Data)35+ if err != nil {36+ return ChartMade{}, err37+ }38+ s, r := t.Sheet, targetRect(t)39+ c := s.GuessChart(r)40+ if spec.Type != "" {41+ typ, ok := sheet.ParseChartType(spec.Type)42+ if !ok {43+ return ChartMade{}, fmt.Errorf("no chart type %q: column, bar, line, pie, area or scatter", spec.Type)44+ }45+ c.Type = typ46+ }47+ if spec.Title != "" {48+ c.Title = spec.Title49+ }50+ c.ByRow = spec.ByRow51+ if c.Stack, err = parseStack(spec.Stack); err != nil {52+ return ChartMade{}, err53+ }54+ c.W, c.H = orDefault(spec.Width, 60), orDefault(spec.Height, 18)55+ c.At = sheet.Addr{Col: min(r.To.Col+2, sheet.MaxCols-1), Row: r.From.Row}56+ if spec.At != "" {57+ cs, a, err := ResolveCell(w, spec.At)58+ if err != nil {59+ return ChartMade{}, err60+ }61+ if cs != s {62+ return ChartMade{}, fmt.Errorf("a chart sits on its data's sheet, %s", s.Name())63+ }64+ c.At = a65+ }66+ i := s.AddChart(c)67+ return ChartMade{Sheet: s.Name(), Number: i + 1, Title: ChartTitle(s.Charts()[i])}, nil68+}69+70+func parseStack(s string) (sheet.ChartStack, error) {71+ switch strings.ToLower(s) {72+ case "", "none":73+ return sheet.StackNone, nil74+ case "stacked":75+ return sheet.StackNormal, nil76+ case "percent":77+ return sheet.StackPercent, nil78+ }79+ return 0, fmt.Errorf("stack %q: stacked or percent", s)80+}81+82+func orDefault(v, d int) int {83+ if v <= 0 {84+ return d85+ }86+ return v87+}88+89+// PivotSpec is a pivot table to add, as Insert > Pivot table makes one:90+// a new sheet summarizing Source, whose first row names its columns.91+type PivotSpec struct {92+ Source string `json:"source" jsonschema:"the data, header row included, e.g. Sales!A1:F99"`93+ Name string `json:"name,omitempty" jsonschema:"the new sheet's name; Pivot Table N when empty"`94+ Rows []string `json:"rows,omitempty" jsonschema:"columns whose values become rows, by header or letter"`95+ Columns []string `json:"columns,omitempty" jsonschema:"columns whose values become columns, by header or letter"`96+ Values []PivotValue `json:"values" jsonschema:"columns to summarize"`97+ Totals bool `json:"totals,omitempty" jsonschema:"add grand totals"`98+}99+100+// PivotValue is a column to summarize, and how.101+type PivotValue struct {102+ Column string `json:"column" jsonschema:"by header or letter"`103+ Summarize string `json:"summarize,omitempty" jsonschema:"sum, counta, count, countunique, average, max or min; sum when empty"`104+}105+106+// AddPivot adds a pivot table's sheet after its source's, returning its107+// name.108+func AddPivot(w *sheet.Workbook, spec PivotSpec) (string, error) {109+ t, err := Resolve(w, spec.Source)110+ if err != nil {111+ return "", err112+ }113+ src, r := t.Sheet, targetRect(t)114+ p := sheet.Pivot{RowTotals: spec.Totals, ColumnTotals: spec.Totals}115+ for _, name := range spec.Rows {116+ col, err := columnOf(src, r, name, true)117+ if err != nil {118+ return "", err119+ }120+ p.Rows = append(p.Rows, sheet.PivotGroup{Col: col})121+ }122+ for _, name := range spec.Columns {123+ col, err := columnOf(src, r, name, true)124+ if err != nil {125+ return "", err126+ }127+ p.Columns = append(p.Columns, sheet.PivotGroup{Col: col})128+ }129+ if len(spec.Values) == 0 {130+ return "", fmt.Errorf("name a column to summarize")131+ }132+ for _, v := range spec.Values {133+ col, err := columnOf(src, r, v.Column, true)134+ if err != nil {135+ return "", err136+ }137+ sum := sheet.SumBy138+ if v.Summarize != "" {139+ var ok bool140+ if sum, ok = sheet.ParseSummarize(strings.ToLower(v.Summarize)); !ok {141+ return "", fmt.Errorf("summarize %q: sum, counta, count, countunique, average, max or min", v.Summarize)142+ }143+ }144+ p.Values = append(p.Values, sheet.PivotValue{Col: col, Summarize: sum})145+ }146+ s, err := w.CreatePivot(src, r, spec.Name, p)147+ if err != nil {148+ return "", err149+ }150+ return s.Name(), nil151+}
A internal/headless/charts.go +47 -0
A internal/headless/describe.go +241 -0
@@ -0,0 +1,241 @@
1+package headless2+3+import (4+ "github.com/FelineStateMachine/012/internal/notebook"5+ "github.com/FelineStateMachine/012/internal/sheet"6+)7+8+// Description is what a workbook holds, for 012 describe and the MCP9+// describe tool: enough for agents (or people) to know which10+// references to read and write without reading every cell. Its JSON11+// form is a stable schema (docs/reference/json.md): fields are only12+// added, never renamed or removed.13+type Description struct {14+ Sheets []SheetDescription `json:"sheets"`15+ Names []NameDescription `json:"names"`16+}17+18+// SheetDescription is one tab: a sheet or a notebook.19+type SheetDescription struct {20+ Name string `json:"name"`21+ Kind string `json:"kind"` // "sheet", "notebook" or "pivot"22+ Shown bool `json:"shown"`23+ Hidden bool `json:"hidden"`24+ // Used is the range from A1 to the last cell with contents, "" when25+ // the sheet is empty; Rows and Cols are its size.26+ Used string `json:"used"`27+ Rows int `json:"rows"`28+ Cols int `json:"cols"`29+ Cells int `json:"cells"`30+ Formulas int `json:"formulas"` // -1 on sheets too large to count them31+ Errors int `json:"errors"` // formulas showing errors; -1 when not counted32+ // Header is the row guessed to name the used range's columns, and33+ // Columns its names; 0 and none when no row looks like one.34+ Header int `json:"header_row"`35+ Columns []string `json:"columns"`36+ Frozen [2]int `json:"frozen"` // rows, columns37+ Filter string `json:"filter"` // the filtered range, or ""38+ Tables []TableDescription `json:"tables"`39+ Regions []RegionDescription `json:"regions"`40+ Charts []ChartDescription `json:"charts"`41+ Pivot *PivotDescription `json:"pivot,omitempty"`42+ Notebook []NotebookCell `json:"notebook_cells,omitempty"`43+}44+45+// NameDescription is a named range.46+type NameDescription struct {47+ Name string `json:"name"`48+ Range string `json:"range"` // with its sheet: Q3!B2:B9, or #REF!49+}50+51+// TableDescription is a named table.52+type TableDescription struct {53+ Name string `json:"name"`54+ Range string `json:"range"` // header row included55+ Columns []string `json:"columns"`56+}57+58+// RegionDescription is a linked file or a notebook cell's output sent to59+// the sheet.60+type RegionDescription struct {61+ Name string `json:"name"`62+ Kind string `json:"kind"` // "output" or "linked"63+ Range string `json:"range"`64+ File string `json:"file,omitempty"` // a linked region's file65+}66+67+// ChartDescription is a chart: Number is what 012 export --chart and68+// the MCP tools call it.69+type ChartDescription struct {70+ Number int `json:"number"`71+ Title string `json:"title"`72+ Type string `json:"type"`73+ Data string `json:"data"`74+ At string `json:"at"`75+}76+77+// PivotDescription is where a pivot table's data comes from.78+type PivotDescription struct {79+ Source string `json:"source"` // Sheet!A1:D9980+}81+82+// NotebookCell is one cell of a notebook tab.83+type NotebookCell struct {84+ Number int `json:"number"`85+ Kind string `json:"kind"` // "code" or "note"86+ Name string `json:"name,omitempty"`87+ Source string `json:"source"`88+ // State is "ran", "failed" or "not run"; Error says why it failed.89+ State string `json:"state,omitempty"`90+ Error string `json:"error,omitempty"`91+}92+93+// maxCounted is the most cells Describe counts formulas and errors on.94+const maxCounted = 1_000_00095+96+// Describe describes the workbook as it is.97+func Describe(w *sheet.Workbook) Description {98+ d := Description{Sheets: []SheetDescription{}, Names: []NameDescription{}}99+ for i, s := range w.Sheets() {100+ d.Sheets = append(d.Sheets, describeSheet(s, i == w.Active()))101+ }102+ for _, n := range w.Names() {103+ r := "#REF!"104+ if !n.Gone() {105+ r = sheet.Qualified(n.Sheet.Name(), n.Range)106+ }107+ d.Names = append(d.Names, NameDescription{Name: n.Name, Range: r})108+ }109+ return d110+}111+112+func describeSheet(s *sheet.Sheet, shown bool) SheetDescription {113+ d := SheetDescription{Name: s.Name(), Kind: "sheet", Shown: shown, Hidden: s.Hidden(), Cells: s.Len(),114+ Tables: []TableDescription{}, Regions: []RegionDescription{}, Charts: []ChartDescription{}, Columns: []string{}}115+ if used, ok := s.UsedRange(); ok {116+ d.Used, d.Rows, d.Cols = used.String(), used.To.Row+1, used.To.Col+1117+ d.Header, d.Columns = guessHeader(s, used)118+ }119+ d.Formulas, d.Errors = countFormulas(s)120+ d.Frozen[0], d.Frozen[1] = s.Frozen()121+ if f := s.Filter(); f != nil {122+ d.Filter = f.Range.String()123+ }124+ for _, t := range s.Tables() {125+ d.Tables = append(d.Tables, TableDescription{Name: t.Name, Range: t.Range.String(), Columns: append([]string{}, t.Cols...)})126+ }127+ for _, r := range s.Regions() {128+ d.Regions = append(d.Regions, describeRegion(s, r))129+ }130+ for i, c := range s.Charts() {131+ d.Charts = append(d.Charts, ChartDescription{Number: i + 1, Title: ChartTitle(c), Type: c.Type.String(),132+ Data: c.Data.String(), At: c.At.String()})133+ }134+ if p, ok := s.Pivot(); ok {135+ d.Kind, d.Pivot = "pivot", &PivotDescription{Source: sheet.Qualified(p.Source, p.Range)}136+ }137+ if s.IsNotebook() {138+ d.Kind, d.Notebook = "notebook", describeNotebook(s)139+ }140+ return d141+}142+143+// countFormulas counts the sheet's formulas and those showing errors,144+// or returns -1 for both past maxCounted cells.145+func countFormulas(s *sheet.Sheet) (formulas, errors int) {146+ if s.Len() > maxCounted {147+ return -1, -1148+ }149+ for _, a := range s.Addrs() {150+ if c := s.Cell(a); c != nil && c.IsFormula() {151+ formulas++152+ if s.Value(a).Kind == sheet.Error {153+ errors++154+ }155+ }156+ }157+ return formulas, errors158+}159+160+func describeRegion(s *sheet.Sheet, r sheet.Region) RegionDescription {161+ d := RegionDescription{Name: r.Name, Kind: "output", Range: r.At.String()}162+ if rng, ok := s.RegionTable(r.Name); ok {163+ d.Range = rng.String()164+ }165+ if r.Linked() {166+ d.Kind, d.File = "linked", r.File.Path167+ }168+ return d169+}170+171+func describeNotebook(s *sheet.Sheet) []NotebookCell {172+ out := []NotebookCell{}173+ for i, c := range s.NotebookCells() {174+ nc := NotebookCell{Number: i + 1, Kind: "code", Name: c.Name(), Source: c.Source}175+ if c.Kind != notebook.Code {176+ nc.Kind = "note"177+ out = append(out, nc)178+ continue179+ }180+ switch o := s.Book().Output(c.ID); {181+ case o == nil || o.Unsaved:182+ nc.State = "not run"183+ case o.Failed():184+ nc.State, nc.Error = "failed", o.Err185+ default:186+ nc.State = "ran"187+ }188+ out = append(out, nc)189+ }190+ return out191+}192+193+// headerLook is how many rows below a header guessHeader reads.194+const headerLook = 5195+196+// guessHeader finds the row naming the used range's columns: its first197+// row with contents, when every cell there is text and the rows below198+// hold something other than text, or the row is bold. It returns the199+// row's number (1 for the first) and the names, or 0.200+func guessHeader(s *sheet.Sheet, used sheet.Rect) (int, []string) {201+ first, ok := s.FilledBounds(used)202+ if !ok {203+ return 0, []string{}204+ }205+ row := first.From.Row206+ names := make([]string, 0, used.To.Col-used.From.Col+1)207+ bold, n := true, 0208+ for col := used.From.Col; col <= used.To.Col; col++ {209+ a := sheet.Addr{Col: col, Row: row}210+ v := s.Value(a)211+ switch v.Kind {212+ case sheet.Empty:213+ names = append(names, "")214+ continue215+ case sheet.Text:216+ default:217+ return 0, []string{}218+ }219+ names = append(names, v.Str)220+ bold = bold && s.CellStyle(a).Bold221+ n++222+ }223+ if n == 0 || row == used.To.Row || !bold && !typedBelow(s, used, row) {224+ return 0, []string{}225+ }226+ return row + 1, names227+}228+229+// typedBelow reports whether the rows below row hold a number, a date,230+// a boolean or a formula.231+func typedBelow(s *sheet.Sheet, used sheet.Rect, row int) bool {232+ for r := row + 1; r <= min(row+headerLook, used.To.Row); r++ {233+ for col := used.From.Col; col <= used.To.Col; col++ {234+ a := sheet.Addr{Col: col, Row: r}235+ if k := s.Value(a).Kind; k != sheet.Empty && k != sheet.Text {236+ return true237+ }238+ }239+ }240+ return false241+}
A internal/headless/describe_test.go +86 -0
@@ -0,0 +1,86 @@
1+package headless2+3+import (4+ "bytes"5+ "encoding/json"6+ "strings"7+ "testing"8+9+ "github.com/FelineStateMachine/012/internal/sheet"10+)11+12+// TestDescribeFixture describes the workbook of every feature the13+// release fixtures keep.14+func TestDescribeFixture(t *testing.T) {15+ f, err := Open("../sheet/testdata/fixtures/new/workbook.012", false)16+ if err != nil {17+ t.Fatal(err)18+ }19+ d := Describe(f.Book)20+ var text bytes.Buffer21+ if err := WriteDescription(&text, d); err != nil {22+ t.Fatal(err)23+ }24+ for _, want := range []string{25+ "Sales (shown) A1:J13, 13 rows x 10 columns",26+ " header row 1: Date, Region, Units, Price, Total",27+ " chart 1 Units by date column of A1:C9 at K2",28+ "Lists (hidden)",29+ " table Targets D1:E3 Region, Target",30+ " pivot table of Sales!A1:E9",31+ " output files A1:B3",32+ " linked app F2 following logs/app.csv",33+ "Notebook (notebook) 5 cells",34+ " 4 code $files | nope (failed: Command `nope` not found)",35+ " Units Sales!C2:C9",36+ } {37+ if !strings.Contains(text.String(), want) {38+ t.Errorf("text lacks %q:\n%s", want, text.String())39+ }40+ }41+ var js bytes.Buffer42+ if err := Encode(&js, "json", d); err != nil {43+ t.Fatal(err)44+ }45+ var back Description46+ if err := json.Unmarshal(js.Bytes(), &back); err != nil {47+ t.Fatal(err)48+ }49+ if len(back.Sheets) != len(d.Sheets) || back.Sheets[0].Charts[2].Type != "pie" || back.Sheets[4].Notebook[1].Name != "files" {50+ t.Errorf("JSON round trip lost something: %+v", back.Sheets[0])51+ }52+ var nu bytes.Buffer53+ if err := Encode(&nu, "nuon", d); err != nil || !strings.HasPrefix(nu.String(), "{sheets: [") {54+ t.Errorf("NUON: %v %.40s", err, nu.String())55+ }56+}57+58+// TestGuessHeader takes a first row of text over typed rows, or a bold59+// one, as a header, and not a table of text.60+func TestGuessHeader(t *testing.T) {61+ for _, c := range []struct {62+ rows [][]string63+ bold bool64+ want int65+ }{66+ {[][]string{{"Item", "Price"}, {"Apple", "1.5"}}, false, 1},67+ {[][]string{{"Item", "Kind"}, {"Apple", "fruit"}}, false, 0},68+ {[][]string{{"Item", "Kind"}, {"Apple", "fruit"}}, true, 1},69+ {[][]string{{"2024", "2025"}, {"1", "2"}}, false, 0},70+ {[][]string{{"Only", "row"}}, true, 0},71+ } {72+ s := sheet.New()73+ for r, row := range c.rows {74+ for col, in := range row {75+ s.Set(sheet.Addr{Col: col, Row: r}, in)76+ }77+ }78+ if c.bold {79+ s.SetStyle(sheet.Rect{To: sheet.Addr{Col: 1}}, func(st *sheet.Style) { st.Bold = true })80+ }81+ used, _ := s.UsedRange()82+ if got, _ := guessHeader(s, used); got != c.want {83+ t.Errorf("%v bold %v: header %d, want %d", c.rows, c.bold, got, c.want)84+ }85+ }86+}
A internal/headless/describetext.go +107 -0
@@ -0,0 +1,107 @@
1+package headless2+3+import (4+ "fmt"5+ "io"6+ "strings"7+)8+9+// WriteDescription writes d as text: a line for each sheet saying what10+// it holds, with what's on it indented below, then the named ranges.11+func WriteDescription(w io.Writer, d Description) error {12+ var b strings.Builder13+ for _, s := range d.Sheets {14+ describeSheetText(&b, s)15+ }16+ if len(d.Names) > 0 {17+ b.WriteString("names\n")18+ for _, n := range d.Names {19+ fmt.Fprintf(&b, " %s %s\n", n.Name, n.Range)20+ }21+ }22+ _, err := io.WriteString(w, b.String())23+ return err24+}25+26+func describeSheetText(b *strings.Builder, s SheetDescription) {27+ var tags []string28+ if s.Shown {29+ tags = append(tags, "shown")30+ }31+ if s.Hidden {32+ tags = append(tags, "hidden")33+ }34+ if s.Kind != "sheet" {35+ tags = append(tags, s.Kind)36+ }37+ b.WriteString(s.Name)38+ if len(tags) > 0 {39+ b.WriteString(" (" + strings.Join(tags, ", ") + ")")40+ }41+ switch {42+ case s.Kind == "notebook":43+ fmt.Fprintf(b, " %d %s\n", len(s.Notebook), plural(len(s.Notebook), "cell", "cells"))44+ case s.Used == "":45+ b.WriteString(" empty\n")46+ default:47+ fmt.Fprintf(b, " %s, %d %s x %d %s, %d %s%s\n", s.Used, s.Rows, plural(s.Rows, "row", "rows"), s.Cols,48+ plural(s.Cols, "column", "columns"), s.Cells, plural(s.Cells, "cell", "cells"), formulaCount(s))49+ }50+ describeParts(b, s)51+}52+53+// formulaCount says how many formulas there are and how many show54+// errors.55+func formulaCount(s SheetDescription) string {56+ if s.Formulas <= 0 {57+ return ""58+ }59+ out := fmt.Sprintf(", %d %s", s.Formulas, plural(s.Formulas, "formula", "formulas"))60+ if s.Errors > 0 {61+ out += fmt.Sprintf(" (%d showing errors)", s.Errors)62+ }63+ return out64+}65+66+// describeParts writes what's on a sheet, a line each.67+func describeParts(b *strings.Builder, s SheetDescription) {68+ if s.Header > 0 {69+ fmt.Fprintf(b, " header row %d: %s\n", s.Header, strings.Join(s.Columns, ", "))70+ }71+ if s.Frozen != [2]int{} {72+ fmt.Fprintf(b, " frozen %d %s, %d %s\n", s.Frozen[0], plural(s.Frozen[0], "row", "rows"), s.Frozen[1], plural(s.Frozen[1], "column", "columns"))73+ }74+ if s.Filter != "" {75+ fmt.Fprintf(b, " filter %s\n", s.Filter)76+ }77+ if s.Pivot != nil {78+ fmt.Fprintf(b, " pivot table of %s\n", s.Pivot.Source)79+ }80+ for _, t := range s.Tables {81+ fmt.Fprintf(b, " table %s %s %s\n", t.Name, t.Range, strings.Join(t.Columns, ", "))82+ }83+ for _, r := range s.Regions {84+ if r.Kind == "linked" {85+ fmt.Fprintf(b, " linked %s %s following %s\n", r.Name, r.Range, r.File)86+ } else {87+ fmt.Fprintf(b, " output %s %s\n", r.Name, r.Range)88+ }89+ }90+ for _, c := range s.Charts {91+ fmt.Fprintf(b, " chart %d %s %s of %s at %s\n", c.Number, c.Title, c.Type, c.Data, c.At)92+ }93+ for _, c := range s.Notebook {94+ line := []rune(strings.SplitN(c.Source, "\n", 2)[0])95+ if len(line) > 60 {96+ line = append(line[:57], []rune("...")...)97+ }98+ state := ""99+ switch {100+ case c.Error != "":101+ state = " (failed: " + c.Error + ")"102+ case c.State != "":103+ state = " (" + c.State + ")"104+ }105+ fmt.Fprintf(b, " %d %s %s%s\n", c.Number, c.Kind, string(line), state)106+ }107+}
A internal/headless/encode.go +33 -0
M internal/headless/jev.go +7 -1
A internal/headless/ops.go +182 -0
@@ -0,0 +1,182 @@
1+package headless2+3+import (4+ "fmt"5+ "strings"6+7+ "github.com/FelineStateMachine/012/internal/sheet"8+)9+10+// Operation is one change of an Apply: what the MCP apply_operations11+// tool takes, each the same engine call a menu command makes. Op says12+// which, and the other fields are its arguments:13+//14+// set Ref (one cell) and Input, as 012 set types it15+// clear Ref: the range's contents, keeping formats and notes16+// insert_rows before Ref's first row, Count rows (Ref's rows when 0)17+// delete_rows Ref's rows18+// insert_columns before Ref's first column, Count columns19+// delete_columns Ref's columns20+// add_sheet Name, after the last sheet21+// rename_sheet Ref (a sheet) to Name22+// delete_sheet Ref (a sheet)23+// define_name Name for the range Ref24+// sort Ref's rows by Keys, the first row left in place with Header25+type Operation struct {26+ Op string `json:"op" jsonschema:"set, clear, insert_rows, delete_rows, insert_columns, delete_columns, add_sheet, rename_sheet, delete_sheet, define_name or sort"`27+ Ref string `json:"ref,omitempty" jsonschema:"the cell, range or sheet the operation acts on, as formulas write it: B7, Q3!A1:C9, 'Q3 plan'!A:A, Q3"`28+ Input string `json:"input,omitempty" jsonschema:"for set: what to type, in en-US form (1.5, =SUM(A1:A6), 2026-09-29); empty clears the cell"`29+ Count int `json:"count,omitempty" jsonschema:"for insert_rows and insert_columns: how many; 0 inserts as many as ref spans"`30+ Name string `json:"name,omitempty" jsonschema:"for add_sheet and rename_sheet the sheet's name, for define_name the range's"`31+ Keys []SortKey `json:"keys,omitempty" jsonschema:"for sort: the columns to sort by, first first"`32+ Header bool `json:"header,omitempty" jsonschema:"for sort: the range's first row is a header and stays in place"`33+}34+35+// SortKey is a column to sort by: a letter (B) or, with a header, the36+// header's text.37+type SortKey struct {38+ Column string `json:"column" jsonschema:"a column letter (B) or the header's text"`39+ Descending bool `json:"descending,omitempty"`40+}41+42+// Apply makes ops as one change, in order, stopping at the first that43+// fails with an error naming it; the workbook should then be thrown44+// away rather than saved, as after Set.45+func Apply(w *sheet.Workbook, ops []Operation, o SetOptions) (warnings []string, err error) {46+ err = w.Batch(sheet.Change{Label: "apply operations", Sheet: w.Sheet(w.Active())}, func() error {47+ for i, op := range ops {48+ warn, err := applyOne(w, op, o)49+ if err != nil {50+ return fmt.Errorf("operation %d (%s): %w", i+1, op.Op, err)51+ }52+ if warn != "" {53+ warnings = append(warnings, warn)54+ }55+ }56+ return nil57+ })58+ return warnings, err59+}60+61+func applyOne(w *sheet.Workbook, op Operation, o SetOptions) (string, error) {62+ switch op.Op {63+ case "set":64+ return setOne(w, Entry{Ref: op.Ref, Input: op.Input}, o)65+ case "add_sheet":66+ _, err := w.AddSheet(op.Name, w.Len())67+ return "", err68+ case "define_name":69+ t, err := Resolve(w, op.Ref)70+ if err != nil {71+ return "", err72+ }73+ return "", w.DefineName(op.Name, t.Sheet, targetRect(t))74+ case "rename_sheet", "delete_sheet":75+ s := w.Lookup(strings.TrimSuffix(op.Ref, "!"))76+ if s == nil {77+ return "", noSheet(w, op.Ref)78+ }79+ if op.Op == "rename_sheet" {80+ return "", w.RenameSheet(s, op.Name)81+ }82+ return "", w.DeleteSheet(s)83+ case "sort":84+ return "", Sort(w, op.Ref, op.Keys, op.Header)85+ }86+ return "", rangeOp(w, op, o)87+}88+89+// rangeOp makes the operations on a range: clearing it, and inserting90+// and deleting its rows or columns.91+func rangeOp(w *sheet.Workbook, op Operation, o SetOptions) error {92+ t, err := Resolve(w, op.Ref)93+ if err != nil {94+ return err95+ }96+ s, r := t.Sheet, targetRect(t)97+ rows, cols := r.To.Row-r.From.Row+1, r.To.Col-r.From.Col+198+ if op.Count > 0 {99+ rows, cols = op.Count, op.Count100+ }101+ switch op.Op {102+ case "clear":103+ if p, ok := s.Protecting(r); ok && !o.Force {104+ return fmt.Errorf("%s is protected (%s): force clears it anyway", t, p.Label())105+ }106+ s.EraseRange(r)107+ return nil108+ case "insert_rows":109+ return s.InsertRows(r.From.Row, rows)110+ case "delete_rows":111+ s.DeleteRows(r.From.Row, r.To.Row-r.From.Row+1)112+ return nil113+ case "insert_columns":114+ return s.InsertCols(r.From.Col, cols)115+ case "delete_columns":116+ s.DeleteCols(r.From.Col, r.To.Col-r.From.Col+1)117+ return nil118+ }119+ return fmt.Errorf("no operation %q: set, clear, insert_rows, delete_rows, insert_columns, delete_columns, add_sheet, rename_sheet, delete_sheet, define_name or sort", op.Op)120+}121+122+// targetRect is the target's range: a whole sheet's is A1 to its last123+// cell with contents.124+func targetRect(t Target) sheet.Rect {125+ if t.Whole {126+ r, _ := t.Sheet.UsedRange()127+ return r128+ }129+ return t.Range130+}131+132+// Sort sorts the rows of the range ref names by keys, as Data > Sort133+// range does, leaving its first row in place when header is set.134+func Sort(w *sheet.Workbook, ref string, keys []SortKey, header bool) error {135+ t, err := Resolve(w, ref)136+ if err != nil {137+ return err138+ }139+ r := targetRect(t)140+ if len(keys) == 0 {141+ return fmt.Errorf("name a column to sort %s by", t)142+ }143+ var sk []sheet.SortKey144+ for _, k := range keys {145+ col, err := columnOf(t.Sheet, r, k.Column, header)146+ if err != nil {147+ return err148+ }149+ sk = append(sk, sheet.SortKey{Col: col, Desc: k.Descending})150+ }151+ if header {152+ r.From.Row++153+ }154+ if len(t.Sheet.MergesIn(r)) > 0 {155+ return fmt.Errorf("%s has merged cells, which can't be sorted", t)156+ }157+ t.Sheet.SortRange(r, sk)158+ return nil159+}160+161+// columnOf finds a column of r by its letter, or with a header row by162+// the header's text, ignoring case.163+func columnOf(s *sheet.Sheet, r sheet.Rect, name string, header bool) (int, error) {164+ if header {165+ for col := r.From.Col; col <= r.To.Col; col++ {166+ if v := s.Value(sheet.Addr{Col: col, Row: r.From.Row}); v.Kind == sheet.Text && strings.EqualFold(v.Str, name) {167+ return col, nil168+ }169+ }170+ }171+ if a, ok := sheet.ParseAddr(strings.ToUpper(name) + "1"); ok && a.Row == 0 && a.Col >= r.From.Col && a.Col <= r.To.Col {172+ return a.Col, nil173+ }174+ return 0, fmt.Errorf("%q isn't a column of %s: name it by its letter%s", name, r, headerHint(header))175+}176+177+func headerHint(header bool) string {178+ if header {179+ return " or its header"180+ }181+ return ""182+}
A internal/headless/read.go +87 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/results.go +108 -0

Not shown: this page already shows 6000 lines of diff.

A internal/headless/runcell.go +55 -0

Not shown: this page already shows 6000 lines of diff.

M internal/headless/set.go +2 -1

Not shown: this page already shows 6000 lines of diff.

A internal/headless/tools.go +177 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/backend.go +100 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/prompts.go +60 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/read.go +103 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/resources.go +225 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/server.go +96 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/server_test.go +340 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/views.go +119 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/views_test.go +74 -0

Not shown: this page already shows 6000 lines of diff.

A internal/mcp/write.go +169 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/plain.012 +10 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/single.012 +21 -0

Not shown: this page already shows 6000 lines of diff.

A internal/sheet/testdata/fixtures/v0.4.0/workbook.012 +169 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/cmdline.go +1 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/commands.go +20 -5

Not shown: this page already shows 6000 lines of diff.

M internal/ui/context.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/crash.go +4 -4

Not shown: this page already shows 6000 lines of diff.

M internal/ui/crash_test.go +6 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/filter.go +12 -7

Not shown: this page already shows 6000 lines of diff.

M internal/ui/grid.go +5 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/gridlines.go +3 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/menuoverlay.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/model.go +6 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/monochrome_test.go +10 -7

Not shown: this page already shows 6000 lines of diff.

M internal/ui/mouse.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbcommands.go +6 -2

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgrid.go +287 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgrid_test.go +200 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgridcmd.go +215 -0

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbgridin.go +275 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbrun.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbscreen.go +16 -6

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/draw.go +2 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/full.go +40 -231

Not shown: this page already shows 6000 lines of diff.

A internal/ui/nbview/grid.go +199 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/keys.go +6 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/mouse.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/output.go +33 -125

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/outwin.go +27 -86

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/panel.go +5 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/view.go +7 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/nbview/view_test.go +84 -24

Not shown: this page already shows 6000 lines of diff.

M internal/ui/notebook.go +7 -1

Not shown: this page already shows 6000 lines of diff.

M internal/ui/panel.go +20 -2

Not shown: this page already shows 6000 lines of diff.

M internal/ui/pivot.go +4 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/sort.go +4 -3

Not shown: this page already shows 6000 lines of diff.

M internal/ui/speed_test.go +22 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/testdata/speed.json +5 -0

Not shown: this page already shows 6000 lines of diff.

M internal/ui/view.go +8 -4

Not shown: this page already shows 6000 lines of diff.

M oracle/go.mod +5 -0

Not shown: this page already shows 6000 lines of diff.

M oracle/go.sum +10 -0

Not shown: this page already shows 6000 lines of diff.