Changelog
What changed in each brothy release.
Changelog
All notable changes to this project are documented here. The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
Unreleased
Added
- Heading styles:
#cyclesclassic(the default) →bars(a level-colored█ ▌ ┃ │ ┆ ┊prefix) →ladder(shade glyphs██ ▓▓▓ ▒▒▒▒ …that thin with the level) →rules(H1 and H2 run a rule to the end of the measure, H3 gets╌╌, H4–H6 are bold color only) and saves it asheadingsinconfig.json. It applies to the document, zen, thectrl+ppeek and the theme picker sample; Source is unchanged. - A docs site (Astro Starlight,
site/) at https://jackmort.github.io/brothy/, drawn as brothy’s own screen: the top line, the ¹Files ²Outline ³Info panel (a drawer on phones), the 80-column measure, key hints and a progress line, and brothy’s keys on the page (j k [ ] / 1 2 3 t ^b ?). The front page is the welcome page (wordmark, bowl and steam from the app’s own art) with the recorded tour playing in a frosted window (on a phone a tap opens it full screen, turned sideways); then install, and pages for every feature, the keys, themes, config and AI, built from the README and changelog and deployed by.github/workflows/pages.yml. Screenshots come in dark and light and follow the site’s theme. It uses only thebrothy/brothy-lightpalettes, one face (IBM Plex Mono) and a new bowl-and-steam icon, also at the top of the README. (In the repository’s Pages settings choose GitHub Actions as the source.) bun run cast(scripts/cast.ts) records the demo assite/public/casts/tour-{dark,light}.castby playing a scripted tour of the real UI headlessly.- The recorded tour (docs site casts and README videos) shows the AI features too: TL;DR, ask,
Don a live reload and the zen gloss, answered offline by a stand-in model (scripts/fakeai.ts) so recording needs no network or key;examples/notes/stock.mdis the note they work on. The README showsdocs/demo.mp4(the gif is its fallback), and the videos are staged like the site demo: the same wallpaper behind a frosted glass window.
Changed
- The TL;DR is a footnote:
*and the whole summary (up to 14 rows, then⏎ moreon its rule) closed by a rule signedTL;DR · <model>. While the model works the block saysasking <model> · 3 s, and regenerating keeps the old summary dimmed under the caret until the first words arrive; an outdated one saysedited since · a refresh. A failed request leaves its error in the block witha retry. A*after the title in the top line marks a note with a TL;DR, the document footer offersa summarizeuntil it is fresh, a summary that lands out of sight toastsTL;DR ready · 3 to read, and thectrl+ppeek shows it the same way. - Zen gloss: the note is a footnote, a short rule then
¹and the text with a hanging indent, and the section’s heading carries the¹. From 140 columns (at the default measure) notes sit in the right margin beside their headings, the other sections’ glosses dimmed and numbered by row. While the model works the rule saysasking <model> · N s · a cancel. A cached gloss shows after a 600 ms pause in its section, an outdated one too, dimmed withedited since · a refresh.aon a gloss on screen shows more or less of a long one (it used to ask again);Aasks again. A reply past 400 characters keeps its finished sentences instead of failinggloss too long. - Ask (
?inctrl+p) reads as a list you can trust:Matcheswith the word that matched on the right until the model has picked, thenAnswersmarked¹ ² ³with the model’s reasons as footnotes under a rule, so a reason never cuts a heading. While a request runs,▍ asking llama3.2 · 3 s(orranking 12 excerpts) sits where the results will appear, and the pane shows exactly what was sent; before that it explains what⏎sends. The footer follows each step, Go to says? asks your noteswhen AI is on, and nothing found or a failure ends in next steps (whether the question left, what to check). Opening an answer marks its heading and names it in the running head, with its reason on the footer line;ctrl+pthen reopens the question with its answers without asking again, and a renamed heading lands on the matched word instead of giving up. - What changed on disk: after a live reload each changed section is numbered after its heading (
¹ ² ³, a removed one in the margin where it was), the running head says³ changedand the toastreloaded · ³ sections changed, with AI on or off. Info’sChanged since 09:23block numbers its rows (added saysnew, removed is struck through), saysD explain/D cancel/D retryat its right end, waits with▍ asking <model> · 3 s, wraps the summary to 5 rows and each note to 2, keeps a failure in place (✗ …) and the last explanation dimmed underEarlier; past 8 rows+ n more sectionsopens the rest (it was a dead+ 1 more sectionsrow).⏎on a change goes there and shows its note in a footnote (¹ of 3 · ] next);[]walk the changes,eschides it. Below 100 columnsDlands on the first change instead of opening the drawer; with the panel hidden and room in the margin the notes sit beside their headings. The prompt asks for at most 8 words per section. - What changed on disk, the Proof sheet:
⏎on theChangedlabel in Info opens What changed, a popup with each changed section’s real lines (−removed,+added, context,…between hunks, long lines cut around the change), the summary and notes onceDhas explained them.↑↓move between sections,⏎goes to one,Dexplains in place,esccloses. It works without anaiblock. The label is now the first stop in Info’s Changed block. - Development: Biome formats and lints the code (
bun run lint,bun run format) and knip finds unused files, exports and dependencies (bun run knip); CI runs both. - New wordmark: a chunky 3×36 block-letter
brothy(the U+2580 block family) on the welcome page, the?sheet,--version, the docs site and the videos; the welcome art is as wide as the wordmark (36 columns, the bowl centred under it) and gives way to the text below that. - New default palette, Hōjicha:
brothyandbrothy-lightmove from teal / gold / coral to roasted-tea neutrals with one persimmon signature colour (H1, focus, the bowl), sand and dusty-plum H2 / H3, muted lavender links. Body text sits near 14:1, every content colour reaches 4.5:1 on the page, the side panel and code blocks, borders are easier to see, and error callouts no longer share the tip / H3 colour. The docs site, favicon and logo follow.
0.2.0 - 2026-10-28
Added
brothy -(orbrothywith a pipe and no path) reads Markdown from stdin: one document titledstdin, keys from/dev/tty; no Files tree, watcher or project record, and links resolve against the current folder’s notes, scanned in the background after the first frame (or on first link use). The panel has only Outline and Info (12), also after following a link and coming back withH. Input over 5 MB stops withbrothy: input too large (limit 5 MB)before the rest is read.eopens the note in$VISUAL/$EDITOR(fallbackvi) at the line at the top of the view (exact in Source, from the nearest heading in Preview); VS Code, VSCodium and Cursor get-g path:lineand Sublime Textpath:lineinstead of+line. The reader resumes and reloads when the editor exits, and says so when it exits with an error; on a note followed from piped input the editor reads keys from/dev/tty.- Selecting text with the mouse copies it to the clipboard (OSC 52) and says how much.
- Opt-in AI, only on a key press, through an
aiblock inconfig.json(OpenAI, OpenRouter, Anthropic, Gemini, Ollama, LM Studio or any OpenAI-compatible endpoint; keys come from the environment). Up to 3 requests run at once.rre-reads the block. AbaseURLwith a query (?api-version=…) keeps it.asummarizes the current note into a TL;DR at the top of the Info tab;aagain cancels. Summaries are cached in~/.cache/brothy/summaries.jsonand shown again for free. In stdin mode the summary lasts for the run and is not cached.- Zen gloss:
ain zen explains the section under the reading line in one or two sentences on a muted sheet (nothing is inserted into the text);eschides it. A gloss already made for an unchanged section shows by itself when you reach it again; an outdated one needsa.ai.glosspicks the style:explain,simplifyortranslate:<tag>. Glosses are cached in~/.cache/brothy/glosses.json. Dexplains what changed on disk since the note was opened: only the changed hunks are sent, and the reply (one or two sentences plus a few words per section) appears underChangedin the Info tab;⏎on a changed section jumps to it. Past the size cap later sections are listed by heading while they fit, then counted (… and 12 more sections); a reply that runs long keeps its summary and the section notes it finished. An explanation is dropped once a reload is too large to compare.?in thectrl+pswitcher asks your vault a question:⏎sends only the question and the model returns search terms; the answers are sections brothy finds itself, and⏎opens one at its first matching line (also under a heading with no letters, such as## ★). A separate↻ rerank with excerptsrow (cost shown first) sends up to 12 candidate excerpts to order them.
- A live reload lists the changed sections in the Info tab (
Changed, with+added −removedcounts) and the toast says how many (reloaded · 2 sections changed). The list is local and works without AI; the baseline is the text the note had when opened, kept in memory only. A reload over 2 MB, or one that rewrites too many lines to compare quickly (a formatter run over a long note), saystoo large to compareinstead of freezing the reader. - Braille minimap at the right edge from 110 columns, in Preview and Source: headings stand out, the part on screen sits on a band, and find hits show in a lane beside it. Click to jump;
mtoggles it (saved asminimap). Wide (CJK) characters count by their width. ctrl+ppeek pane from 100 columns: the highlighted note’s path and length, its outline around the hit, its TL;DR when a fresh one is cached (the pane never sends a request), and its first lines; only the part shown is rendered, so a note of several MB peeks quickly.- The keys sheet (
?twice) groups the keys under Global, Document, Zen, Panel and AI chips, in two columns from 100 columns. - Welcome page while no note is open (a folder with no Markdown): the wordmark over a bowl of broth with rising steam, the keys to start, and recent projects you can open with
↑↓⏎or a click. The panel,a,s,w,zandZkeys wait for a note. - Panel tabs carry their key number (
¹Files ²Outline ³Info), also in the compact strip; the rule under the open tab is accent while the panel has focus. motioninconfig.json(defaulttrue):falsedraws the welcome page still (no ink-in, no rising steam).- Nine theme families from their upstream palettes (MIT): ayu, cyberdream, iceberg, melange, nightfox (light: dayfox), nightowl (light: Light Owl) and oxocarbon with a dark theme and a
-lighttwin, and the dark-only synthwave84 and vesper; 42 themes in 22 families. Roles that missed the contrast floors were nudged in lightness only; oxocarbon-light leads with the dark theme’s teal, with a blue secondary, pink errors and orange warnings. --themeandthemeinconfig.jsontake a family name too (one,ayu): its dark theme, or its only one;--helplists the families instead of all 42 names.- The theme picker handles a family with only one mode: its missing cell on the board and the missing side of the switch are muted and struck through,
tab/←→and a click there do nothing, and the pane shows the family’s own theme whatever mode you asked for; the next pair shows that mode again.
Changed
- The theme picker (
t) lists the 22 families once, with a query to filter them (letters now type, sojkgGno longer move;↑↓andctrl+nctrl+pdo) and a dark / light switch (tab,←→). From 100 columns a pane renders a sample note (marks, links, code, a callout, tasks, a table) in the highlighted theme on its own background. The app no longer re-themes while you move:⏎applies and saves,esccloses with nothing changed. - The theme picker’s list is a board: a
darkand alightcolumn under a header, each cell a specimen (Aaand the primary, secondary and accent dots) in that theme’s own colours on its own background, so both twins show without flipping. The cursor is one cell framed in the app’s primary (↑↓family,←→ortabmode; the footer says←→ dark/light), the theme in use keeps a thin muted frame, and a click on a cell applies that theme; hovering does not scroll the board. The list is 41 columns wide and the pane 58 at 120 columns.
Fixed
- A
themeinconfig.jsonthat names no theme ("one"before family names, or a removed one) is reported at start instead of opening brothy without a word.
Security
- AI requests go only to the endpoint in your
aiblock: HTTP redirects are refused (AI: <host> redirects · set baseURL to the final URL), and neither the key nor customai.headersis sent over plainhttp:except to localhost. Key and header values are redacted from error toasts. - Front matter (other than the
titleused as the note name) and%%comments%%are never sent. Cache files are private (0700folder,0600files).
0.1.1
Fixed
- Sinhala, Malayalam and Devanagari text keeps its zero-width joiners (
ශ්රී, chillu letters, half-forms) instead of showing�; a lone or leading joiner and bidi controls are still replaced. - A paragraph underlined with a single
-is a heading in the Source outline and thectrl+pswitcher too, so heading hits jump to the right place. - The empty-folder message shows the folder name with control characters replaced.
0.1.0
First public release. Renamed to brothy: the command, binary and repo are brothy, and config lives in ~/.config/brothy.
Added
- Terminal Markdown reader: folder tree (fuzzy filter, folder counts), Preview and Source views, a tabbed Files / Outline / Info panel (a drawer below 100 columns), find in document, live reload, mouse support.
- Layout at an 80-column measure (
wfor full width) with a running-head top line, ghost hints and a progress line. - Pre-wrapped rendering: tables that shrink to fit, task lists, code blocks with tree-sitter highlighting for JS/TS/JSX/TSX/Zig and a fallback for other languages.
- Obsidian syntax: wikilinks and embeds, callouts,
==highlights==,%%comments%%, collapseddataview/tasksblocks, known HTML tags. - Navigation: note switcher across the vault (
ctrl+p: notes, headings, text), project opener (o), link labels (f), back/forward history (H/L). - 26 themes (13 dark/light pairs) with a live-preview picker, transparent background (
T,--transparent). - Zen mode (
z, settingsZ): centered text, scroll or pages flow, spotlight, typewriter, teleprompter. - Prebuilt binaries for Linux and macOS (x64, arm64).