From the coding agent that runs your experiments to the scientific paper you submit — one window for the whole thing. An agentic coding workbench (per-folder terminals, a live file panel, change tracking with one-click rollback, a lightweight editor) with a document viewer bolted to the same window: your .tex shown as the page it compiles to, your PDFs as real pages, and the figures and data your code just produced next to both.
Run claude, codex, gemini — any terminal agent — each in its own folder, side by side, and watch what they do: the file panel updates as they write, the Changes panel lists every file they touched and reverts any of it, and the viewer renders whatever they produced — code, a chart, a CSV, a manuscript.
Written in pure Rust. No Electron, no TeX installation, and no webview under the UI — the panes rasterize themselves. The only web engine is the system WebKit view the HTML Rendered mode parks over the viewer, and nothing else uses it. ~10 MB binary, ~40 MB RAM, and a paper opens the moment you click it.
Above: the whole loop in one window — the manuscript folder in the panel on the left, paperIEE.tex set on the two-column page its \documentclass produces (page 12, figures, captions and justified columns, straight from the source with no LaTeX run), and the agent that wrote it running underneath, one preset click away.
One folder, one window, the whole cycle — the agent never leaves the terminal, and you never leave the app to look at what came out:
| Stage | What you do | What Tigriden gives you |
|---|---|---|
| 1. Code | claude / codex / gemini in the project folder writes and runs the experiment |
A real terminal per folder, extra tabs for pytest, git or a second agent, and a file panel that updates as files appear |
| 2. Check | Read what the run produced before trusting it | results.csv as an aligned table, loss.png or a vector PDF plot as an image, the agent's Markdown notes typeset on a page |
| 3. Keep or undo | Decide what survives the run | The Changes panel lists every file touched, diffs each one, and reverts a file — or the whole run — with git or with invisible snapshots when there is no repo |
| 4. Write | Ask the agent to draft or revise the manuscript in the same folder | paper.tex opens typeset on the page your \documentclass produces: two-column IEEE, single-column arXiv, equations, tables, figures — no compile |
| 5. Iterate | Reread, re-prompt, discard what missed | The typeset page re-renders the instant the agent saves; rollback is one right-click |
| 6. Submit | Build the real artifact | latexmk in a second terminal tab, then open the produced paper.pdf in the same viewer — pages, text selection, side-by-side with the source |
Nothing in steps 2–5 costs a LaTeX run or a second application.
Agentic coding means running several agents in several folders and checking in on them. A full IDE is overkill for that; a bare terminal multiplexer gives you no file browser, no diff, no editor. Tigriden is the minimal middle: one session per folder — agent, files, editor and change tracking together.
Writing with an agent has the same shape, plus a document. Today that means three apps — a terminal for the agent, Overleaf or a PDF viewer to see what the text actually looks like, and Finder to move figures around — and every look at the page costs a full LaTeX compile. Tigriden puts the typeset page in the same window: the paper size, margins and column grid your \documentclass asks for, rendered by a built-in typesetter, so it appears instantly and works on a machine with no TeX distribution. Compile when you are ready to submit, not to read a paragraph.
- One-click agents — preset buttons type the agent command into the terminal for you (
claude,codex,gemini,opencode, or your own, fully configurable). - A real terminal — VTE-compliant (alacritty_terminal + a real PTY), so
vim,topand the Claude Code TUI just work: bracketed paste, truecolor, mouse selection, right-click Copy / Paste / Select All, and a wheel that scrolls inside full-screen apps as well as through history (Shift+PgUp/PgDn/Home/End/↑/↓ page the scrollback). Drop a file from Finder on the terminal and its shell-quoted path is typed in, ready to attach to a prompt. Marks stay on the letters they belong to (0.1.9) — a cell's zero-width vowels, tones and accents are drawn as the one stack they are, soสวัสดีครับkeeps its Thai vowels and tone marks instead of thinning to bare consonants. Ctrl and ⌘ work on a non-Latin layout (0.2.0) — on a Thai keyboard Ctrl+O typed Ctrl+ญ, which matches no shortcut and encodes no control byte, so^Onever reachednanoand the app's own ⌘ keys went dead. A combo is now resolved through the key's position on a Latin layout, the way macOS resolves its own shortcuts; plain typing, Dvorak, AZERTY, arrows and F-keys are untouched. - Multiple terminals per folder —
+spawns extra shells in the same workspace, so an agent can run while you use a second tab for git, tests, or another agent. - Every file the agent touched, and an undo (0.1.1) — File ▸ Show Changes Panel lists modified/added/deleted files within ~1 s of a write, with a syntax-highlighted diff per file. Discard Changes… reverts one file, ↺ reverts the whole run, both behind a confirmation. Git folders compare against the last commit; folders without git get invisible shadow snapshots, so a scratch project or a manuscript folder is just as safe. Snapshots skip bulk data (0.2.0) — a directory over 200 MB or a single file over 5 MB stays out, both sizes settable in Settings, so a training set or a PDF corpus does not end up copied into the snapshot store.
- Several projects at once — one session per folder with its own shell, tree and open file; switching is instant. File ▸ New Window runs independent windows in parallel, and named
[[teams]]give each window its own agent buttons. Windows no longer stall each other (0.2.0) — they share one event loop, so closing a terminal, opening a PDF, scanning fonts or watching a folder with git now happens off it. - A file panel that manages files (0.1.6) — gitignore-aware and live as the agent works. Drag files in from Finder, Cut/Copy/Paste through the system pasteboard in both directions, Delete to the Trash behind a confirmation, rename/duplicate/reveal from the keyboard or the context menu.
- Built-in editor — syntax highlighting for 40+ languages (cosmic-text + syntect), Cmd+S to save. When the agent rewrites the file you have open, it reloads automatically (or asks, if you have unsaved edits).
- Settings, themes, persistence (0.1.2) — File ▸ Settings… (⌘,): six themes, accent color, a font and a text size for the editor and for the terminal, each picked on its own (0.1.8), scrollback, the snapshot size limits (0.2.0), applied live to every window. The pickers list the monospaced families your machine really has, and a configured family it does not have is swapped for one it does — never for the platform's proportional interface font. A native menu bar (Add Folder ⌘O, New Terminal ⌘T, Open Recent, New Window ▸ team, Save ⌘S, Close ⌘W) routes to whichever pane has focus, and folders, layout and the recent list come back on relaunch.
- Small on purpose — no Electron, no webview under the UI, no C regex libraries; a Slint shell with both panes rasterized straight to pixel buffers, which is where the ~10 MB binary and the instant startup come from.
- LaTeX on the page, not in a text dump (0.1.7) — the viewer reads
\documentclass(andgeometry) and sets the file on that page: letter or A4, the class's margins, two columns for the journal classes (IEEEtran, ACM/SIG, RevTeX,[twocolumn]). It is paginated — numbered sheets, paragraphs continuing into the next column, headings kept with their text,figure*/table*spanning both columns at a page top, and a float that will not fit moving to the top of the next column while the text flows past it. - The parts a paper is made of —
\maketitlefront matter (spanning title block,\thanksas the affiliation footnote, raised\textsuperscriptmarkers, Abstract and Index Terms), the class's own section numbering (1.1 or I, A, 1),\citeprinted as the number its\bibitemwill carry, captions labelled "Figure 1:" or "Fig. 1." as the class does, cross-references resolved to numbers even when they point forward. - Real math, with TeX's metrics (0.1.8) — display equations get box layout: stacked fractions, radicals with an overline,
\sum/\intcarrying their limits, matrices andcases, every row of analignnumbered on its own.\left(…\right)fences are sized to the ink they enclose, by TeX's delimiter factor, so nesting them keeps one paren size instead of growing a size a level; scripts, roots and accents measure against ink the same way, and atom spacing sets operators, relations and punctuation apart as TeX does. Inline math is set inline, with true raised and lowered scripts (V_S, x², R^{d_model}) instead of spelled-out_S. - Figures and tables of real manuscripts —
\graphicspathsearched, vector PDF plots rasterized, pictures scaled by theminipagethey sit in;tabular/tabularx/longtableset booktabs style. Preamble noise, package options and unknown commands never leak onto the page. - PDFs as actual pages — the compiled paper, a reference you are citing, a datasheet. Select and copy text straight off the page, with two-column papers copying one column at a time instead of zig-zagging across the gutter.
- Markdown on the same white page, with the same typeset math — for notes, READMEs and agent-written summaries.
- HTML two ways (0.2.0) — Rendered is a real WebKit view over the pane (macOS; elsewhere the file opens in Reader), so a site looks and behaves as it does in Safari: stylesheets apply, scripts run, the page you are building is the page you see. Reader sets the same file as a typeset document on the white sheet — headings, lists, tables,
<pre>blocks and local<img>figures, entities decoded, script and style left out — which is what an agent's HTML report wants. The header chip cycles Rendered / Reader / Source. - Everything else in the folder — images (png/jpg/gif/webp/bmp/tiff) and CSV/TSV as an aligned table, so a plot or a results file the agent just wrote is one click away.
- Fast, because nothing compiles — no
pdflatexrun to see a change; PDF pages rasterize and images decode on background threads with the next page prefetched, so scrolling and zooming never stall. Cmd+= / Cmd+- / Cmd+0 zoom, and the LaTeX page re-typesets at the new size.
Everything the LaTeX view understands (the long list)
Paper and margins from \documentclass options and geometry; one or two columns; pagination with page numbers, column breaks inside paragraphs, keep-with-next headings, [H]-pinned versus floating figures and tables. \maketitle title blocks, \thanks footnotes, \textsuperscript, abstract and IEEEkeywords labels (bold run-in for journals, centered over an inset block for articles). Section numbering per class, \setcounter{secnumdepth}, \parindent/\parskip paragraph shape, center/flushleft/\centering, \LARGE down to \scriptsize — each scoped to its group. equation/align/gather, \[…\], $$…$$ and starred forms, each align row numbered on its own; a display too wide for its column is set a size smaller. Variables italic, operators and min/tanh/log upright, \mathbb/\mathcal letters, fences and radicals sized to the ink they enclose. \ref/\eqref/\autoref/\Cref resolved by a two-pass parse; \cite numbered from \bibitem; \captionsetup{labelformat=empty} respected. \includegraphics with \graphicspath, width=…\linewidth and minipage scaling, including vector PDF figures. tabular, tabularx, longtable and array in booktabs style; itemize/enumerate/description; verbatim/lstlisting/minted on a code panel; quote and article abstracts inset from both margins; \href/\url as links. Unknown commands, package options ([leftmargin=…], [htbp], natbib's [][]) and the whole preamble stay off the page.
No Rust needed — grab the prebuilt app from the latest release:
-
Download
Tigriden-0.2.0-macos-universal.app.zip(one download for both Apple Silicon and Intel). -
Unzip and drag Tigriden.app into /Applications.
-
First launch only: the app isn't notarized, so right-click → Open → Open, or run:
xattr -d com.apple.quarantine /Applications/Tigriden.app
Prefer a bare binary? The release also ships tigriden-0.2.0-macos-arm64.tar.gz (Apple Silicon) and tigriden-0.2.0-macos-x86_64.tar.gz (Intel) — untar and run ./tigriden.
Windows builds on the same release: unzip tigriden-0.2.0-windows-x86_64.zip and run tigriden.exe. It is built by CI on every tag rather than tested by hand — macOS is still the primary target — but the last three releases fixed what made it look broken on sight. 0.1.8: a config naming a font Windows does not have (Menlo, say) rendered the terminal in Segoe UI, the platform's proportional interface font. 0.1.9's mark stacking is platform-neutral code, and Windows falls back to Leelawadee UI for Thai — an OpenType face with real mark attachment, so tone marks sit slightly better there than under the Ayuthaya macOS reaches for. 0.2.0's Latin-layout fallback for Ctrl and ⌘ combos reads the physical key through winit, so it applies there as well. One thing in 0.2.0 is macOS only: Rendered HTML needs WKWebView, so on Windows an HTML file opens in Reader. Terminal teardown still runs off the event loop there, with Child::kill in place of the process-group signals Unix gets.
Build from source (stable Rust required)
git clone https://github.com/Sompote/Tigriden.git
cd Tigriden
cargo build --release
./target/release/tigriden # or ./bundle/make-app.sh for dist/Tigriden.appmacOS is the primary target; Linux/Windows are untested but the stack is cross-platform.
- Click + Add folder and pick a project directory — a login shell opens there.
- Click a preset button (e.g. claude) to launch the agent, or type any command.
- Watch the file panel update as the agent works; click any file to read or edit it.
- Click + in the terminal tab strip for more shells in the same folder (each tab is its own shell; ✕ on hover closes one).
- Add more folders to run more agents in parallel; switch by clicking a session in the sidebar. The ✕ on a session header removes the folder (its shells stop; the folder stays in Recent).
- Click ⟳ (bottom of the sidebar) to reopen any previously added folder without the file dialog.
- + Add folder → pick the manuscript folder (the one with
paper.texandfigures/). A login shell opens there. - File ▸ Show Changes Panel, so every file the agent touches is listed and revertible before it types a word.
- Click claude (or type any agent command) and ask for what you want: "tighten Section 3 to 400 words", "make the notation consistent with Table 2", "add a limitations paragraph".
- Click
paper.texin the panel — it opens typeset, on the page your class produces, so you can read the revision as a reader will see it. No compile, nolatexmkwatch. - Not convinced? Right-click the file in Changes ▸ Discard Changes… to put it back, or ↺ to revert the whole run, then ask again.
- Ready to submit? Run
latexmk(or your build) in a second terminal tab with +, and open the resultingpaper.pdfin the same viewer to check the real thing.
Everything else works the same way: drop new figures in from Finder, click a .csv the agent generated to read it as a table, open a reference PDF and copy a quotation straight off the page.
- File ▸ Show Changes Panel — a Changes (N) section appears under each folder in the sidebar (off by default; it always starts off on launch).
- Tracking mode is chosen automatically per folder:
- Git folders compare against the last commit — commit in the terminal to accept work and reset the list to zero.
- Folders without git get an invisible shadow snapshot taken the moment you enable the panel (stored under
~/Library/Application Support/tigriden/snapshots/; no.gitappears in your project). Re-enabling the panel re-snapshots "now".
- As the agent works, changed files appear within ~1 s as
M(modified) /A(added) /D(deleted) rows — the count is files, not edits. - Click a row to see the accumulated diff against the baseline; the File chip jumps to the editable file.
- Don't like a change? Right-click the row ▸ Discard Changes… restores that file to the baseline (new files are deleted, deleted files come back). The ↺ button on the Changes header — or right-click ▸ Discard All Changes… — reverts the whole run. Both ask for confirmation first.
Detection is watcher-driven (no polling): bursts of writes are coalesced for 250 ms, git status runs on a background thread, and nothing at all runs while the panel is off or the agent is idle.
| Context | Keys |
|---|---|
| Terminal | everything a terminal expects: Ctrl+C/Z/D/R…, arrows, F1–F12, TUIs; drag to select (double-click = word), Cmd+C copies, Cmd+V pastes (bracketed), right-click for Copy / Paste / Select All; wheel scrolls history — and scrolls inside full-screen apps (Claude Code, vim, less) too — Shift+PgUp/PgDn pages it, Shift+Home/End jump to the ends, Shift+↑/↓ go line by line |
| File panel | ↑/↓ walk the rows, ←/→ collapse / expand (or step to the parent), Return opens, F2 or ⌘R renames, ⌘D duplicates, ⌘X / ⌘C / ⌘V cut, copy and paste files through the system pasteboard, Delete or ⌘⌫ moves to the Trash (after a confirmation); right-click for the full menu |
| Editor | typing, arrows / Home / End / PgUp / PgDn (+Shift selects, +Alt jumps words), Cmd+A / C / X / V, Cmd+S saves, right-click for Copy / Paste / Select All |
| Viewer | wheel scrolls, right-edge scrollbar drags or click-jumps, PgUp/PgDn page, Home/End jump to the ends, ↑/↓ step; drag to select text — including on PDF pages (double-click = word), Cmd+A selects all, Cmd+C / Cmd+X copy, Esc clears, right-click for the menu; Cmd+C with nothing selected copies a whole PDF; on images, PDFs and the LaTeX page: Cmd+= / Cmd+- zoom, Cmd+0 resets, Ctrl/Cmd+wheel zooms, and a zoomed view pans horizontally |
Most of it is editable in File ▸ Settings… (⌘,), where the editor and the
terminal take their own font and their own size; the file is
~/Library/Application Support/tigriden/config.toml, created on first run:
# Theme: classic-|minimal-|vivid- × -dark|-light ("dark"/"light" still work).
theme = "classic-dark"
accent = "" # "" = theme accent, or "#rrggbb"
font_family = "Menlo" # editor, viewer + code blocks
term_font_family = "Menlo" # terminal, on its own ("" = follow font_family)
font_size = 13.0 # editor + viewer (8-28)
term_font_size = 13.0 # terminal, sized on its own (8-28)
ui_font_size = 13.0 # sidebar, tabs, dialogs (10-18)
scrollback = 10000
show_changes = false # start new windows with the Changes panel on
[[presets]]
label = "claude"
command = "claude"
send_enter = true
[[presets]]
label = "codex"
command = "codex"
[[presets]]
label = "gemini"
command = "gemini"
[[presets]]
label = "opencode"
command = "opencode"
# Optional: named preset groups for File ▸ New Window ▸ <team>.
[[teams]]
name = "reviewers"
[[teams.presets]]
label = "claude-review"
command = "claude /review"
send_enter = trueBoth families are checked against the font database at startup: one this machine
does not have is replaced by the first installed fallback for the platform
(Menlo on macOS, Cascadia Mono on Windows, DejaVu Sans Mono elsewhere) and
written back, so what the file says and what you see agree. A config from before
0.1.8 has no term_font_family and keeps one family for both until you pick a
terminal font.
Presets and teams are file-only — the Settings dialog links to config.toml for those. Saving from Settings rewrites the whole file, so comments you add by hand are not preserved.
When a release adds an agent button, a config still holding an older build's stock list picks it up once, recorded as presets_version. Add or remove a single preset and the list becomes yours: later releases leave it alone.
Runtime state (restored folders, split position) lives next to it in state.toml; shadow snapshots for the Changes panel live in snapshots/.
A folder without its own git repository is tracked by a hidden snapshot repo
under ~/Library/Application Support/tigriden/snapshots/. Two limits keep that
store from growing past the projects it tracks, both in Settings ▸ Changes
panel and in config.toml:
snapshot_file_mb = 5 # a file this big or bigger is not snapshotted
snapshot_dir_mb = 200 # a directory subtree this big is excluded whole0 on either means no limit. The directory rule is the one that matters: the
mass in a research folder is rarely one huge file, it is thousands of medium
ones. A folder of 4602 harvested PDFs averaging 1.7 MB snapshots to 100 MB at
these values, and a 7638-image training set to 39 MB, while a 415 MB book
folder keeps 128 MB and every source file in it. Excluded files are not listed
in the Changes panel and cannot be rolled back from it.
Limits apply when a baseline is taken. Turn the Changes panel off and on again to re-take one for the folders already open.
Slint provides only the chrome (sidebar, layout, splitter). The two hard parts are custom-rendered pixel panes on the CPU:
| Pane | Engine | Rendering |
|---|---|---|
| Terminal | headless alacritty_terminal grid fed by portable-pty |
glyphs rasterized per cell via cosmic-text's swash cache |
| Editor | cosmic-text SyntaxEditor (syntect highlighting) |
draws itself into the same pixel-buffer canvas |
The file viewer paints into the same kind of pixel buffer: Markdown/CSV/LaTeX layout via cosmic-text, PDF pages rasterized by hayro, and images decoded/resampled by the image crate — both on per-document worker threads, so the UI thread never waits on them. LaTeX runs through a built-in parser in src/tex.rs, which turns math into a tree that src/mathlayout.rs measures and positions as boxes — no TeX install needed. The page itself is a second pass: src/tex.rs reads the class options into a page geometry (paper, margins, columns), and the viewer packs the blocks into that grid column by column and sheet by sheet, splitting a paragraph at a line boundary when it runs off the bottom and holding full-width floats over to the top of the next page. Because the type size is derived from the page width, resizing the pane re-typesets the document rather than reflowing it, while a zoom step magnifies the page already typeset: every derived length comes off the page scale unrounded, so the proportions, line breaks and pagination hold at any zoom. Markdown shares both: it renders on the same white sheet and sends its $…$ bodies through that same parser and box layout, so a formula looks the same whichever file it came from. Only the pages in (or next to) the viewport are kept in memory, requests coalesce so a zoom gesture renders just the final size, and a nearest-neighbor preview covers the gap until each full-quality bitmap arrives.
Because the panes paint themselves, a theme is one definition in src/theme.rs feeding three consumers: the Slint Theme global (chrome), the ANSI 0-15 palette (terminal, shared with the PTY threads for OSC color queries), and a syntect theme name (editor).
Only the PTY reader threads and the viewer's rasterizer/decoder workers run in the background; rendering and editing happen on the UI thread with coalesced, throttled repaints.
src/mac.rs holds the AppKit calls neither Slint nor winit exposes: the pasteboard's file list (so the panel's ⌘C/⌘V interoperate with Finder) and the pointer location during an external drag, since winit's drop events carry a path but no coordinates.
vendor/cosmic-text/ is a verbatim copy of cosmic-text 0.19 with one change: its syntect dependency uses the pure-Rust fancy-regex engine instead of the oniguruma C library (smaller binary, no C build dependency).
cargo build --features framedump, then run with TIGRIDEN_DUMP=/tmp/frames to dump both panes as PNGs. TIGRIDEN_TEST_INPUT='claude\r', TIGRIDEN_TEST_OPEN=path, TIGRIDEN_TEST_SETTINGS='style=vivid,font-size-step=2', TIGRIDEN_TEST_CHANGES=1 (reports the Changes panel's tracking mode and contents around a write), TIGRIDEN_TEST_CTXMENU=1 (runs the right-click menu's Copy and Select All against the terminal and reports what reached the clipboard), TIGRIDEN_TEST_SCROLLBACK=up|down (wheels the terminal and reports the mode, history size and resulting screen — the way to tell scrollback from alternate-screen scrolling) and TIGRIDEN_TEST_WHEEL_UI=1 (dispatches a real scroll event through Slint's hit-testing, to prove wheel input still reaches the terminal) script the first session for headless testing. For the typeset LaTeX page there is a faster loop that needs no window: TEX_DUMP=paper.tex TEX_DUMP_OUT=/tmp/tex TEX_DUMP_PAGES=3 TEX_DUMP_FROM=0 cargo test tex_sheet_dump -- --nocapture writes one PNG per page.
-
0.2.0 — HTML in the viewer, a window that stays responsive, and a snapshot store that stays small.
A snapshot no longer copies the data it sits next to. The store had reached 17 GB across 40 folders. Two folders held 13 of it. Nothing capped, packed or deleted anything, ever.
A per-file cap does not fix that on its own. The mass is never in the giants. One folder carried 4602 harvested PDFs averaging 1.7 MB, a literature corpus. Another held 7638 JPGs averaging 0.65 MB, a training set. Both sit under any per-file cap worth setting. A 5 MB cap caught 3.0 GB of the first folder and 1.6 GB of the second, and left the rest.
What marks those files is the directory they sit in. A manuscript folder does not hold 4600 PDFs. A subtree of 200 MB or more is now excluded whole, at the shallowest point over the line, and a single file of 5 MB or more is excluded wherever it sits. The root is never excluded, so a big folder still tracks its own small files. Measured against the real folders: 8.1 GB becomes 100 MB, 6.5 GB becomes 39 MB, and a 415 MB book folder keeps 128 MB with every source file in it.
Both sizes are settings. Settings ▸ Changes panel takes folders at 100 MB, 200 MB, 500 MB, 2 GB or no limit, and files at 1, 5, 20, 100 MB or no limit.
config.tomlcalls themsnapshot_file_mbandsnapshot_dir_mb. The git workers run on their own threads, so the values cross as two atomics rather than through the thread-local config.An exclude only holds back a file git is not already tracking. A file that grew past the cap since the last baseline is dropped from the index too, which the next commit records as a deletion. The file itself is untouched. Baselines also run
git gcnow: one repo held 5499 loose objects and 6.91 GiB with nothing in a pack, because git's default threshold is 6700 and no baseline ever asked. And a folder whose every file is excluded commits an empty baseline. Without a commit there was no baseline, so every refresh walked the whole tree again trying to take one.HTML opens as a document, two ways. Reader sets an
.htmlfile on the same white sheet Markdown and LaTeX use. It gives you headings, justified paragraphs, blockquotes, lists, tables as real grids,<pre>kept as a code block and a local<img>as a figure.<sup>and<sub>reuse the math painter's script tags. HTML 4 entities are decoded, and the bodies of<script>and<style>are dropped.src/html.rsis a small tokenizer, not the HTML5 tree algorithm. It does close what real pages leave open:<p>at the next block,<li>at the next item,<td>and<tr>at the next cell and row. That suits an agent's report. It does not suit a site, whose content the page often builds at load time. A project'sindex.htmlarrives as empty containers thatdata.jsfills in. So Rendered is a real WKWebView parked over the pane. It loads the file withloadFileURL:allowingReadAccess, so the page's own stylesheets, scripts and images resolve beside it. This is a browser view. A page can reach the network exactly as it would in Safari. The header chip cycles Rendered / Reader / Source. The view stands down for another tab, the editor or a dialog.⌘ and Ctrl combos resolve through a Latin layout. On a Thai layout, Ctrl+O typed Ctrl+ญ. No shortcut matched that and no control byte encoded it. So
^Onever reachednano, and every ⌘ key in the app went dead. The physical key is now read from the winit event, which still knows its position. Its US-layout character is substituted only when Ctrl or ⌘ is held and the typed character is a single non-ASCII one. Plain Thai typing, Dvorak and AZERTY letters, arrows and F-keys pass through untouched.Six waits came off the shared event loop. Every window runs on one Slint event loop, so anything that blocks it freezes them all. Two windows made that plain: work started in one stopped the other. Terminal teardown called
Child::kill, which signals the shell alone and sleeps up to 250 ms before escalating, thenChild::wait. A shell wedged on its way out heldwait4for over two minutes in testing. Teardown now signals the shell's process group and the tty's foreground group, then hands the child to a thread that escalates and reaps. Two windows on one folder shared its snapshot repository, and each re-took the baseline. That discarded changes the first window still offered to roll back. An existing baseline is now left alone, andhas_baselineasks git for a commit rather than trusting theHEADfile. Git ran a thread per 250 ms batch of file system events. An agent writing files left a full-treegit statusrunning every quarter second. Each session now has one thread with a coalescing queue and a per-folder lock. Font scanning built aFontSystemper window; one is shared now. Opening a PDF parsed it on the event loop, and Cmd+C on a PDF ran the text extraction there too. That extraction took 11.8 s on a 1.3 MB paper in a debug build. The worker opens the document and extracts its text when the file opens, so the copy is a field read. -
0.1.9 — Thai in the terminal, marks and all. A Thai syllable is one grid cell holding a consonant plus zero-width vowels and tone marks: alacritty stacks those marks onto the cell rather than giving them columns of their own, and the renderer only ever read the cell's base character. Every mark was dropped on the way to the screen, so
สวัสดีครับ ที่นี่arrived asสวสดครบ ทน— consonants standing, vowels and tones gone, which is the same thing as being unable to type Thai. A cell's whole stack is now shaped as one cluster, which is also what puts each mark over the right part of the letter instead of beside it; a cell carrying nothing but a mark draws instead of being skipped as blank, and a syllable under the block cursor keeps its marks rather than dropping to a bare consonant. Every mark a terminal stores this way travels the same path — Lao vowels and tones, Hebrew niqqud, Arabic harakat, a combining accent on a Vietnamese or Greek letter — and an emoji written with a variation selector now gets its emoji form. Copying always carried the marks — only the drawing was losing them. -
0.1.8 — Display math set the way TeX sets it.
\left(…\right)delimiters were scaled to the body's line box, which carries leading no glyph reaches into, so every fence came out oversized and each nesting level multiplied the last —LN(ReLU(Wf + b))in four different paren sizes. Fences are now measured against the body's ink either side of the math axis and grown by TeX's delimiter factor, whose slack is exactly what stops the cascade. Scripts, roots and accents measure the same way, so a superscript sits on the base it belongs to and a radical over a fraction stays a radical. Atom spacing grew a left and a right side: punctuation takes its space on the right only, and a named operator is followed by the thin space that the\!of\LN\!\left(is written to cancel.alignkeeps every row — the math parser stopped at\\and the block-level code never split there, so all but the first row vanished; each row is now its own numbered equation, breaks nested in amatrixare left alone, and a\labelbinds to the row carrying it. Plus\mathbband\mathcalletters, a real minus sign, spacing accents in place of combining marks that shape to nothing, a second script level for inline math (R^{d_{model}}no longer reads as R^d_(model)), and a wide equation nudged clear of its own number.The terminal gets a font of its own. Settings now has an Editor font and a Terminal font, each picked separately — a grid of cells and a page of prose do not want the same face. Both lists are built from the families the font database really holds, and both names are checked at startup: a family this machine lacks is swapped for the first installed fallback and written back to
config.toml. That is the Windows fix — cosmic-text answers a family it cannot find with the platform's interface font, so a config carried from a Mac drew the terminal in proportional Segoe UI. The picker also opens inline in the dialog instead of in a popup, which was placed from its unscrolled position and could open outside the window once the dialog had been scrolled, swallowing the click. A config written before the split keeps one family for both until you choose a terminal font, and a settings change that only touches the terminal no longer re-typesets the open document. -
0.1.7 — LaTeX is set on the page its class asks for. The viewer reads
\documentclass(and ageometrycall) and lays the document out on that page — letter or A4, the class's margins, two columns for the journal classes (IEEEtran, ACM/SIG, RevTeX,[twocolumn]) — then paginates it: numbered sheets, paragraphs continuing into the next column, headings kept with their text, full-widthfigure*/table*at the top of a page, and any float that will not fit moving to the top of the next column while the text flows past it ([H]stays pinned). The type size follows the page, so a paper reads at page size rather than editor size, and Cmd+= / Cmd+- magnify that page — same line breaks, same sheets, figures growing with the text, the way zooming a PDF does. Front matter comes out as\maketitlesets it — spanning title block,\thanksas the affiliation footnote, raised\textsuperscriptmarkers,Abstract/Index Termslabels — sections carry the class's own numbering (1.1 or I, A, 1, or none undersecnumdepth),\citeprints the number its\bibitemwill carry, and captions are labelled the way the class labels them. Inline math is finally inline: real raised and lowered scripts (V_S, km s⁻¹) instead of spelled-out_S; a display too wide for its column is set a size smaller.\graphicspathfigures resolve (vector PDF plots included) and scale with theminipagearound them,tabularxjoinstabularas a booktabs-style table,center/\centeringand the\LARGE…\scriptsizesizes apply — and stop at the end of their group, which is what kept leaking a table's\scriptsizeinto the rest of a paper. -
0.1.6 — the left panel becomes a file manager. Drag files in from Finder and they are copied into the folder you drop on, with the target row highlighted as you drag (winit hands over the dropped paths but no coordinates, so the pointer is read from AppKit and hit-tested against the row list); drop on the terminal instead and you still get the shell-quoted path. Cut / Copy / Paste use the system pasteboard, so files move both directions between Tigriden and Finder — Cut+Paste moves, Copy+Paste copies, and a name clash takes a
" 2"suffix rather than overwriting. Delete / ⌘⌫ moves to the Trash behind a confirmation, which the context menu's Move to Trash now asks for too. Rows carry a selection and the keyboard drives it: ↑/↓ walk and scroll into view, ←/→ collapse, expand or step to the parent, Return opens, F2 or ⌘R renames, ⌘D duplicates. Markdown is set on the same white page as LaTeX — serif, justified columns, paper margins — and its math is typeset, not dumped:$…$and$$…$$go through the same box layout a .tex file gets, so fractions stack,\sum/\intcarry their limits, and\tag{1}is set flush right as the equation number (mathcode fences work too). The terminal has its own text size, split from the editor and viewer; a config written before the split keeps one size for both until you move it. -
0.1.5 — copying text, everywhere it was missing. Select text in the viewer: drag across Markdown paragraphs, code blocks, CSV tables and the glyphs of rendered PDF pages, double-click for a word, Cmd+A for all, Esc to clear, Cmd+C / Cmd+X to copy. PDF selection builds a real text layer from the same content stream the renderer draws, so highlights sit on the glyphs — on cropped and rotated pages too — and two-column papers copy one column at a time instead of zig-zagging across the gutter; Cmd+C with nothing selected still copies the whole document. Right-click the terminal, editor or viewer for Copy / Paste / Select All — Copy greys out with nothing selected, Paste is hidden on read-only views, and the right-click no longer clears the selection you just made. The mouse wheel now scrolls inside full-screen apps: TUIs run on the alternate screen, which keeps no scrollback of its own, so the wheel did nothing at all in Claude Code, vim or less; apps that asked for mouse reporting now get real wheel events at the pointer's cell, and the rest get arrow keys, xterm's alternate-scroll behaviour. Plus an opencode preset button, which configs still carrying the stock three take on once.
-
0.1.4 — viewer performance and polish: PDFs rasterize and images decode on background threads (scrolling and zooming no longer stall the UI), pages prefetch ahead of the scroll, wheel repaints are throttled; a scrollbar on the right of the viewer (draggable thumb, click-to-jump) plus PageUp/PageDown, Home/End and ↑/↓ keys; ⌘ detection for wheel zoom and shortcuts now reads the modifier state straight from the OS; scrollback limit changes apply to already-running terminals.
-
0.1.3 — viewer zoom for images and PDFs (Cmd+=/-/0, Ctrl/Cmd+wheel, header magnifier buttons, panning), PDFs rendered as actual pages, Markdown tables drawn as real grids, terminal scrollback keys (Shift+PageUp/PageDown/Home/End/↑/↓).
-
0.1.2 — Settings UI (⌘,): 6 themes, accent colors, fonts and sizes, scrollback, all applied live to every window.
-
0.1.1 — file change tracking with per-file/all rollback (git or invisible shadow snapshots), multiple windows with per-window agent teams.
-
0.1.0 — first release: per-folder sessions with terminal, file tree, editor, viewers, presets.
The LaTeX view is a fast reader's approximation of the page, not a TeX engine — for the final artifact, compile:
- Line breaking is TeX-like but not TeX: no hyphenation and no paragraph-wide optimum, so line breaks and page breaks differ from the compiled PDF.
- Side-by-side
minipagepanels stack vertically, each at its declared width. - Macros you
\newcommandare not expanded;\input/\includefiles are not pulled in (open them directly). - A journal's affiliation footnote is set under the byline rather than at the foot of the first column.
Elsewhere:
- Editor undo
- Mouse reporting to TUIs
- IME / dead-key composition
- Editor tabs (currently one open file per session)
- PDF page rendering (done in 0.1.3)
- LaTeX typeset on the class's own page (done in 0.1.7)
- Linux / Windows testing
MIT
