<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>cat/012</title>
<subtitle>a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary</subtitle>
<id>https://src.rest/cat/012/</id>
<link href="https://src.rest/cat/012/"/>
<updated>2026-10-17T16:38:12-06:00</updated><entry>
<id>4fc5b3bdd7a747c732750df94eaa6e8ffeee4e22</id>
<title>Module: the import path is src.rest/cat/012</title>
<link href="https://src.rest/cat/012/commit/4fc5b3bdd7a747c732750df94eaa6e8ffeee4e22/"/>
<author><name>cat</name></author>
<updated>2026-10-17T16:38:12-06:00</updated>
<content type="text">The forge answers go-get for src.rest/&lt;owner&gt;/&lt;repo&gt;/... with the repo&#39;s
https clone, so go install src.rest/cat/012/cmd/012@latest fetches from
src.rest. Links to the GitHub repository stay as they are.</content>
</entry>
<entry>
<id>02f429a61b69db900df872543731509f7c8eb229</id>
<title>Nushell: read the error nu marks with an ASCII x</title>
<link href="https://src.rest/cat/012/commit/02f429a61b69db900df872543731509f7c8eb229/"/>
<author><name>Dami</name></author>
<updated>2026-10-17T16:31:21-06:00</updated>
<content type="text">When its output isn&#39;t a terminal, nu 0.116 draws the mark before the message
as x rather than ×, so Message fell back to the header line,
nu::shell::column_not_found, and lost what was wrong. The x counts only after
nu&#39;s Error: header.</content>
</entry>
<entry>
<id>c2d6922b906295b88b644cf5a2c72b156e6368cd</id>
<title>Lint: staticcheck 2026.2.2, which reads Go 1.27.2&#39;s export data</title>
<link href="https://src.rest/cat/012/commit/c2d6922b906295b88b644cf5a2c72b156e6368cd/"/>
<author><name>Dami</name></author>
<updated>2026-10-17T16:28:10-06:00</updated>
<content type="text">2026.2.1 failed every package with &quot;export data version 5 is greater than
maximum supported version 4&quot; under Go 1.27.2.</content>
</entry>
<entry>
<id>9131f06da03e78f229adcf74b3d46f03b39b12e4</id>
<title>CI: make check runs on your machine for src.rest</title>
<link href="https://src.rest/cat/012/commit/9131f06da03e78f229adcf74b3d46f03b39b12e4/"/>
<author><name>Dami</name></author>
<updated>2026-10-17T16:28:10-06:00</updated>
<content type="text">forge attest runs .forge/ci in a clean worktree of each commit and signs the
result into refs/notes/ci; forge push sends it with the branch. Build deps
(libghostty, stress data) live in ~/.cache/012/deps, outside the worktree,
so runs don&#39;t rebuild them from source.</content>
</entry>
<entry>
<id>a63f866f8565d95d9d77880d47360f3bbb6f6f54</id>
<title>Site: build under a path when forge deploys it</title>
<link href="https://src.rest/cat/012/commit/a63f866f8565d95d9d77880d47360f3bbb6f6f54/"/>
<author><name>Dami</name></author>
<updated>2026-10-17T16:15:29-06:00</updated>
<content type="text">forge site deploy sets FORGE_SITE_URL and FORGE_SITE_BASE; without them the
site still builds for the root of 012.dev.site. .forge/sites declares the docs
site so it deploys to https://pages.src.rest/sites/cat/012/docs/.</content>
</entry>
<entry>
<id>26dd53cc8d74359b261688fea7990b35ba0efff4</id>
<title>Docs: make quick for iterating, make check once at the end</title>
<link href="https://src.rest/cat/012/commit/26dd53cc8d74359b261688fea7990b35ba0efff4/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:11:40-06:00</updated>
<content type="text">Testing says what make quick covers and what make check runs at once
and alone, that e2e sessions run in parallel and wait rather than
sleep, and when a golden screen is captured. The speed gate&#39;s section
names the timed tests beside it; CLAUDE.md asks for one make check, at
the end.</content>
</entry>
<entry>
<id>35f0f368feac91fef17b7dd52ae8f0ed5d7558cd</id>
<title>Merge main</title>
<link href="https://src.rest/cat/012/commit/35f0f368feac91fef17b7dd52ae8f0ed5d7558cd/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:10:56-06:00</updated>
<content type="text"></content>
</entry>
<entry>
<id>2dd41e8ba6f12602e9e15e54e360404c027ab50d</id>
<title>Check: make quick, the checks of what changed</title>
<link href="https://src.rest/cat/012/commit/2dd41e8ba6f12602e9e15e54e360404c027ab50d/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:10:49-06:00</updated>
<content type="text">make quick lints and tests the packages changed since the branch left
main (or PKGS), runs the oracle when it changed, and the e2e tests and
golden screens defined in changed e2e files, or all of e2e when the
harness changed or with E2E=1.</content>
</entry>
<entry>
<id>7029177e1daee9a7603d1922c96e393cd07dad70</id>
<title>Site: the hero leads with the first-steps recording</title>
<link href="https://src.rest/cat/012/commit/7029177e1daee9a7603d1922c96e393cd07dad70/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:10:49-06:00</updated>
<content type="text"></content>
</entry>
<entry>
<id>05c0cd4c91b29fd6735acbf31a8823f2ee9682bb</id>
<title>Check: lint, tests, oracle and e2e at once, then timed tests alone</title>
<link href="https://src.rest/cat/012/commit/05c0cd4c91b29fd6735acbf31a8823f2ee9682bb/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:10:48-06:00</updated>
<content type="text">scripts/check.sh runs make lint, test, oracle and e2e together, each
into a log printed whole with its time when it ends, then make speed on
its own. The tests that time frames against fixed bounds
(TestSharedEditWithinAFrame, TestStreamGridAtFrameSpeed,
TestScrollsAtFrameSpeed) move from make test to make speed beside the
speed gate, so none of them shares the CPU with the e2e sessions.</content>
</entry>
<entry>
<id>159a874b6ebf0f5541cc8382607f0eae2e1b3894</id>
<title>Lint: the checks run at once, vet once with the stress tag</title>
<link href="https://src.rest/cat/012/commit/159a874b6ebf0f5541cc8382607f0eae2e1b3894/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:08:46-06:00</updated>
<content type="text">scripts/lint.sh starts gofmt, vet, staticcheck in each module, the
shape limits, the tracked-file check, doclint and doccheck together
and prints each one&#39;s findings whole when it ends. go vet -tags stress
sees every file plain vet does, so make lint runs it alone and make
check no longer vets twice. File sizes are read with one wc rather than
one per file. Given directories, the Go checks look only at them.</content>
</entry>
<entry>
<id>bfd41781fe92182fff11732aaabf34bc54e7f1cb</id>
<title>E2E: sessions run in parallel, golden screens wait to match</title>
<link href="https://src.rest/cat/012/commit/bfd41781fe92182fff11732aaabf34bc54e7f1cb/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:08:22-06:00</updated>
<content type="text">Every session is its own process, pty, temp directory, config home and
fake services, so the tests and the golden screens&#39; subtests call
t.Parallel and run up to GOMAXPROCS at a time. TestScreens stays serial
at the top, so TestStills reads the goldens it has just written under
-update, and TestStressKeyLatency stays serial as it times keys.

A screen is captured once it holds still and shows its golden, or after
five seconds of not showing it: nu&#39;s highlighting can reach a busy
screen after two captures matched, which parallel runs exposed.</content>
</entry>
<entry>
<id>4e51e8b033d23f9db13a8b6098f5f9c2a87f9695</id>
<title>Site: a sidebar per section; the homepage drops its headline; A1 holds a short label</title>
<link href="https://src.rest/cat/012/commit/4e51e8b033d23f9db13a8b6098f5f9c2a87f9695/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T22:08:18-06:00</updated>
<content type="text">The navbar picks a section and the sidebar lists that section&#39;s pages,
so the two no longer show the same list. The hero&#39;s headline and the
page title&#39;s tagline go (the logomark names 012; a hidden h1 keeps the
outline), and the install line is the install script.</content>
</entry>
<entry>
<id>74484903cfa991ae61b050e23f7d74247ce28c8b</id>
<title>File fixtures: v0.8.0</title>
<link href="https://src.rest/cat/012/commit/74484903cfa991ae61b050e23f7d74247ce28c8b/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:52:41-06:00</updated>
<content type="text"></content>
</entry>
<entry>
<id>3551fc18a8a9b65b8b2bb4067f07241838b61601</id>
<title>Docs: the recordings show charts as the sixel images 012 draws</title>
<link href="https://src.rest/cat/012/commit/3551fc18a8a9b65b8b2bb4067f07241838b61601/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:45:36-06:00</updated>
<content type="text">VHS&#39;s xterm.js has its image addon on, and its recordings include the
images, so the notes saying they show only the text chart were wrong.</content>
</entry>
<entry>
<id>95de7f84b855e19db7670386162781de13de3591</id>
<title>HTML export: pages and views embed JetBrains Mono</title>
<link href="https://src.rest/cat/012/commit/95de7f84b855e19db7670386162781de13de3591/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:45:16-06:00</updated>
<content type="text">The same font as the docs, their pictures and the site, in place of IBM
Plex Mono: regular, semibold and italic, Latin subset, from
@fontsource/jetbrains-mono 5.3.0. The binary grows by 16 KB.</content>
</entry>
<entry>
<id>39424e0d51b05a4c836e0a6e6fdbc789dddfd37d</id>
<title>Site: the navbar lists the docs&#39; sections, and the landing page leads with what 012 is</title>
<link href="https://src.rest/cat/012/commit/39424e0d51b05a4c836e0a6e6fdbc789dddfd37d/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:26:00-06:00</updated>
<content type="text">The navbar has Getting started, Sheets, Formulas, Files, Nushell, Agents
and Terminal, and Reference as a menu of its pages, sized to fit down to
the width Docusaurus collapses it at. The landing page&#39;s control panel
lists the same sections, so the navbar leaves them to it there. The hero
heading says what 012 is rather than repeating the name the logomark
shows, the title&#39;s cursor is gone so the control panel&#39;s is the only
one, and A1 at rest holds a link to the guides.</content>
</entry>
<entry>
<id>fbbdcb816f326eeece8066c3bceda554cc664400</id>
<title>Docs media: the recordings in JetBrains Mono and their pages&#39; color schemes</title>
<link href="https://src.rest/cat/012/commit/fbbdcb816f326eeece8066c3bceda554cc664400/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:24:45-06:00</updated>
<content type="text">Rendered again with make demos. layout.gif and sources.gif are reduced to
32 colors to stay under 1 MB.</content>
</entry>
<entry>
<id>a043ee9acf2d8fe2d057ca001b15267b3e0bc1f0</id>
<title>Pictures: one font, JetBrains Mono, and color families by page</title>
<link href="https://src.rest/cat/012/commit/a043ee9acf2d8fe2d057ca001b15267b3e0bc1f0/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:03:00-06:00</updated>
<content type="text">Every picture of 012 is set in JetBrains Mono, VHS&#39;s and Ghostty&#39;s
default: the stills draw from the TTFs in e2e/testdata/fonts (Go Mono
only for characters it lacks), make demos serves ttyd&#39;s page with them
added so VHS needs nothing installed, and the site bundles
@fontsource/jetbrains-mono, with the system&#39;s sans for body text.

The pictures&#39; colors are families of a dark and a light scheme, listed
in site.md with the pages each covers: Catppuccin, Tokyo Night, Rosé
Pine, GitHub, Gruvbox and Nord. Stills draw their golden&#39;s palette in
their family&#39;s schemes with each cell held to 012&#39;s contrast minimums;
tapes set their scheme and make demos runs 012 with that theme.
TestPictureSchemes checks the schemes&#39; contrast, and doccheck that each
page&#39;s pictures are in its family.</content>
</entry>
<entry>
<id>391e1d51801fb0bc47999986efb348708336735b</id>
<title>Themes: a scheme named exactly wins over looser matches</title>
<link href="https://src.rest/cat/012/commit/391e1d51801fb0bc47999986efb348708336735b/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T21:02:28-06:00</updated>
<content type="text">&quot;tokyonight&quot; found TokyoNight, the first case-insensitive match, where
VHS&#39;s Set Theme takes the scheme of that exact name.</content>
</entry>
<entry>
<id>55928ef00d21eba0ed272fbcadf24a1ff6dbf6f1</id>
<title>File fixtures: v0.7.0</title>
<link href="https://src.rest/cat/012/commit/55928ef00d21eba0ed272fbcadf24a1ff6dbf6f1/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T20:32:48-06:00</updated>
<content type="text"></content>
</entry>
<entry>
<id>8ce86008c9f2342750eac4afc8124bc8a2d9798d</id>
<title>Notes: the hover box keeps clear of the status line, as the error box</title>
<link href="https://src.rest/cat/012/commit/8ce86008c9f2342750eac4afc8124bc8a2d9798d/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T20:19:33-06:00</updated>
<content type="text">Both boxes are placed beside their cell by one helper, besideCell, which
moves a box up rather than over the status line. A golden screen hovers
a note on the last row shown.</content>
</entry>
<entry>
<id>f4d438dc2cd7a8d8b2976f44ebe5abb834d08ad1</id>
<title>Demos: the sources recording reads a grouped count, a date and a MEDIAN</title>
<link href="https://src.rest/cat/012/commit/f4d438dc2cd7a8d8b2976f44ebe5abb834d08ad1/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T20:17:02-06:00</updated>
<content type="text">The tape&#39;s formulas on Sheet1 are a ROWS, an AVERAGEIFS, the last day
and a MEDIAN of ten million amounts, typed quickly so the GIF stays
under 1 MB.</content>
</entry>
<entry>
<id>92d47e3919d2e7825ae5cf62866acc784c439761</id>
<title>Formats: inferring one allocates no closure per formula</title>
<link href="https://src.rest/cat/012/commit/92d47e3919d2e7825ae5cf62866acc784c439761/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T20:06:06-06:00</updated>
<content type="text">The speed gate&#39;s chain and running recalculations allocated a closure
for each formula and each operand to infer their format; the sheet keeps
its paged test once per recalculation and InferFormat recurses directly.</content>
</entry>
<entry>
<id>e49ca3c3561c7992a9dbbdc480bed29a67c58e46</id>
<title>Docs: the sources&#39; formulas picture shows a working MEDIAN, formats and F1</title>
<link href="https://src.rest/cat/012/commit/e49ca3c3561c7992a9dbbdc480bed29a67c58e46/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T20:04:50-06:00</updated>
<content type="text">The trips&#39; fares are a DECIMAL(12,2), so the still shows sums with
cents, counts grouped, the last day as a date, the median and 90th
percentile answered, and a second still the explanation F1 opens over
a STDEV past max-cells. Golden screens add the cut context line at 80
columns and the box in the high-contrast theme; an e2e test reads a
cut explanation at 60 columns through F1. sources.md lists the order
statistics and ranks that stream.</content>
</entry>
<entry>
<id>1bbd3fd89ec9c7b6903714b8e90cfcb383680ec2</id>
<title>Sources: MEDIAN, PERCENTILE, QUARTILE, LARGE, SMALL and MODE stream</title>
<link href="https://src.rest/cat/012/commit/1bbd3fd89ec9c7b6903714b8e90cfcb383680ec2/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T19:53:02-06:00</updated>
<content type="text">An order statistic of one range of a linked source no longer holds the
column: the job streams its numbers into the external merge sort a
Parquet view&#39;s sort uses, made generic over its records, in runs of a
million numbers spilled to temporary files, and reads them back in
order once. RANK counts as it reads. Both work alike for Parquet and
SQLite, where ORDER BY with OFFSET took 19 s on ten million rows. On
ten million rows MEDIAN takes 1.7 s (Parquet) or 2.8 s (SQLite) in
50 MB, against 248 MB held; answers are kept as other questions&#39;.</content>
</entry>
<entry>
<id>7920678c606cb21f8a298c68c3b5886776e35af6</id>
<title>Functions: PERCENTILE, QUARTILE, their .INC and .EXC, MODE.SNGL and RANK.EQ</title>
<link href="https://src.rest/cat/012/commit/7920678c606cb21f8a298c68c3b5886776e35af6/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T19:43:43-06:00</updated>
<content type="text">MEDIAN, MODE, LARGE, SMALL and the new percentiles read their numbers
once in ascending order through one interface (Sorted), held and
sorted on a sheet, so a Book can hand them out sorted some other way.
RANK counts above and below as it reads rather than holding the range.
Excel&#39;s _xlfn. prefix is written for the dotted names.</content>
</entry>
<entry>
<id>d59b5ded81a8238b7c4169656d5857066844b4ee</id>
<title>Sources: results over a column keep its format; counts show grouped</title>
<link href="https://src.rest/cat/012/commit/d59b5ded81a8238b7c4169656d5857066844b4ee/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T19:39:29-06:00</updated>
<content type="text">Formulas over a linked source infer their format from the column&#39;s
type, as they do from a sheet&#39;s cells: SUM, AVERAGE, MIN, MAX and
lookups show a DECIMAL&#39;s decimals, a date, a timestamp, a time or a
duration. Counts over a source show as whole numbers with thousands
separators. Parquet DECIMAL columns carry their scale&#39;s decimals and
INTERVAL columns read as durations; SQLite&#39;s declared TIME, DECIMAL(p,s),
NUMERIC(p,s) and MONEY map to formats.</content>
</entry>
<entry>
<id>e12837c9408c2197df6933ec6ef3a1c981566772</id>
<title>Errors: an explanation too long for the context line says the rest on F1</title>
<link href="https://src.rest/cat/012/commit/e12837c9408c2197df6933ec6ef3a1c981566772/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T19:35:27-06:00</updated>
<content type="text">The context line cuts a long error explanation at the last sentence
that fits, with an F1 chip; F1 shows it whole in a box beside the cell
(or on a source&#39;s tab, why it can&#39;t be read). F1 elsewhere still opens
the shortcuts. The max-cells message over a source leads with the
remedy: raise max-cells to N, then what it is and what streams instead.
A test holds every explanation at 80 columns to being whole or readable
with F1.</content>
</entry>
<entry>
<id>ecffc0b3ee5f4523b8c5caf3fdb213dc0ebc0300</id>
<title>Merge branch &#39;main&#39; into worktree-agent-a44969b7ca50f8b04</title>
<link href="https://src.rest/cat/012/commit/ecffc0b3ee5f4523b8c5caf3fdb213dc0ebc0300/"/>
<author><name>Dami</name></author>
<updated>2026-09-30T08:41:00-06:00</updated>
<content type="text"># Conflicts:
#	website/package-lock.json
#	website/package.json</content>
</entry>
</feed>
