CI finished on main.
All-in-one terminal for long-running agentslive artifactsvertical tabsworktreesreading the transcriptarchitecture diagramsmultiplexing workAll-in-one terminal for long-running agents
qmux is a terminal for CLI agents with visual transcripts, artifacts, cross-agent queues, and more.
- Claude Code
- Codex
- OpenCode
- Grok
- Muse
- Pi
- Cursor
- Devin
qmux · landing preview
Interactive session mock
14 sessions rendered
qmux · interactive visualization
Recent activity design
Research / Recent activity
No prompt matches.
Published the draft.
No notifications yet
<INSTRUCTIONS>
<environment_context>
add a qmux group above porffor, have that open by default, draw the transcript from this conversation, and make sure a visible image embed renders in the right pane
I'll make qmux the default project, excerpt this landing-page iteration into a real session, and add an inline image item to the mock transcript renderer. The active replay will start with existing output and run long enough to visibly scroll.
The current transcript union only handles paragraphs and activity summaries. I'll add a typed image block, render the bundled qmux capture with fixed dimensions, and keep Porffor available as a collapsed secondary group.
The new qmux session is now the server-rendered default. Its first completed inspection is visible immediately, while later edits, checks, and the image arrive through the working-session replay.
The rendered document now contains fourteen terminal sessions, one inline transcript image, and an active qmux timeline. Completed sessions still bypass replay and show their full history immediately.
The capture is a bundled asset rather than a temporary clipboard path, so it remains visible in production and obeys the landing page's self-only image policy.
Everything is passing. The static capture remains embedded, and the interactive design reference now renders as a native attachment that opens in qmux's browser:

<INSTRUCTIONS>
<environment_context>
get replaceAll passing the two test262 cases we still fail
I'll read the string builtin and run only the 45-test replaceAll directory first, then reproduce the empty-search behavior through Porffor's native compiler.
The two failures are independent: the loop reuses the zero match length as its cursor increment, and the non-global RegExp guard runs too late. I'll split match width from advancement and move the RegExp check ahead of allocation.
All 45 replaceAll tests now pass, and the native Porffor smoke program prints the leading, interstitial, and trailing replacements. The change is confined to compiler/builtins/string.ts.
<INSTRUCTIONS>
<environment_context>
verify sign extension for unaligned i16 loads in emitted C
I'll trace the unaligned load case in the C renderer, then compile a DataView smoke program with Porffor so the emitted native path is exercised directly.
The renderer loads an unaligned signed value through its unsigned width, then casts back to the narrow signed type before C widens it. I'll verify that exact expression in emitted C and native output.
The emitted C contains the narrow signed cast, and the Porffor-compiled program reads -2 while the unsigned control remains 65534. No renderer change is needed.
<INSTRUCTIONS>
<environment_context>
verify Math.hypot stops coercing after an argument throws
I'll inspect the builtin's argument loop and run the single test262 abrupt-coercion case before adding a native Porffor smoke program that records coercion order.
The implementation calls ToNumber inside its left-to-right loop, so an abrupt completion should prevent later arguments from being observed. The focused conformance test confirms that path.
The native smoke program logs only the first and throwing arguments, then catches the sentinel error. No compiler change is needed; I recorded the verified behavior instead of manufacturing a patch.
<INSTRUCTIONS>
<environment_context>
try a slower Muon momentum ramp; keep it only if val_bpb improves
I'll confirm the experiment rules and current baseline, then change only the Muon momentum schedule in train.py.
The baseline is 0.997900 val_bpb at 44.0 GB. I'll extend the ramp without changing batch size or the five-minute budget so the comparison stays attributable.
The candidate reaches 0.996841 at essentially unchanged memory, so it clears the keep rule. I've committed the change and recorded the measured result; I'm checking the results row before wrapping up.
<INSTRUCTIONS>
<environment_context>
test QK normalization and discard it if the fixed-budget metric gets worse
I'll branch from the current kept result, add QK normalization in the attention block, and judge it only on the final validation bits per byte.
The implementation is small and the run is healthy, but the experiment still has to beat 0.996841. I'll let the fixed timer and validation finish before deciding.
It regressed to 0.999284 with no compensating memory benefit. I logged the discard, reset the branch to the prior kept commit, and left the untracked results log intact.
<INSTRUCTIONS>
<environment_context>
summarize the kept and discarded experiments without rerunning training
I'll treat the tab-separated log as the source of truth and check its shape before ranking results.
All rows have five fields. There are two kept candidates beyond baseline and three discarded runs; the best kept metric is 0.996841.
I added a short Markdown summary that separates measured results from hypotheses and links each entry back to its commit.
<INSTRUCTIONS>
<environment_context>
add coverage for tokenizer special tokens and conversation loss masks
I'll read the hermetic tokenizer fixture and the conversation renderer, then add the smallest cases that distinguish supervised assistant tokens from unsupervised tool output.
The existing fixture trains a tiny Rust BPE in process, so the new assertions need no cached tokenizer or dataset. I'll extend that fixture rather than invoking the full tokenizer evaluation script.
All ten focused tests pass. The coverage now distinguishes assistant supervision from tool-output masking; I'm checking the broader tokenizer tests before wrapping up.
<INSTRUCTIONS>
<environment_context>
verify TaskMixture stays deterministic when a task is repeated
I'll inspect how the mixture builds and shuffles its index map, then run the small in-memory task tests without touching Hub data or GPU evaluation.
The implementation enumerates the configured task list into an index map and shuffles it with a local random.Random(42). Repeating a task intentionally duplicates its examples; a second mixture should produce the same order.
All seven task tests pass, including the deterministic second-instance comparison and repeated-task oversampling. The behavior is already covered, so no patch is warranted.
<INSTRUCTIONS>
<environment_context>
validate layernorm backward kernel 10 against the CPU reference
I'll use the standalone CUDA harness in dev/cuda/layernorm_backward.cu because it dispatches kernel 10 directly and compares every output with its CPU reference.
Kernel 10 vectorizes the input-gradient load and store while keeping the parameter-gradient reduction in its scratch buffer. I'll compile the harness exactly as documented at the top of the file.
Every tested block size matches for input, weight, and bias gradients. The harness then reports kernel timings, so this validates the edited code path rather than an unrelated production target.
<INSTRUCTIONS>
<environment_context>
add a focused regression for adjacent reshape cleanup
I'll inspect the current movement pattern and test it at the UOp graph-rewrite layer. The old ShapeTracker layout is gone, so a regression should target mop_cleanup directly.
The matcher already replaces nested reshapes with one reshape over the original source. I'll add a focused test that asserts both the resulting op and source identity, without changing the rewrite itself.
The new regression passes, followed by the full 56-test schedule suite. This documents current cleanup behavior without adding speculative guards that the matcher does not have.
<INSTRUCTIONS>
<environment_context>
cover invalid Metal source and corrupt compiled libraries
I'll use the existing Metal-only device tests, which exercise both source compilation failures and runtime rejection of a corrupted compiled library.
The compiler path raises CompileError from the Metal build service, while the corrupt-library path must make runtime construction fail. I'll keep those failure types distinct in the assertions.
All five Metal device tests pass, including OOM, compile failure, compile success, corrupt library rejection, and explicit buffer release.
<INSTRUCTIONS>
<environment_context>
add concise per-file summaries for compiler/ and link them from its index
I'll inventory the existing compiler notes and follow their heading and relative-link conventions before adding missing summaries.
The index covers parsing, code generation, and builtins but not the IR or rendering pages. I'll add one factual paragraph per missing page and keep implementation details in the leaf pages.
Every new index link resolves to a tracked Markdown file, and the diff contains only the compiler index plus the two missing summaries. I'm doing a final terminology pass now.
<INSTRUCTIONS>
<environment_context>
define AOT, intermediate representation, and native runtime consistently
I'll find every existing use first so the glossary describes this wiki's terminology instead of importing generic compiler definitions.
The pages use IR and intermediate representation interchangeably, while runtime sometimes means the generated support code and sometimes the host process. I'll define both senses explicitly.
The glossary now owns the definitions, and the compiler overview links the first occurrence of each term without turning later prose into link noise.

- Agent
- Running
- Directory
- ~/code/qmux
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/porffor
- Branch
- main
- Agent
- Done
- Directory
- ~/code/porffor
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/porffor
- Agent
- Running
- Directory
- ~/code/autoresearch
- Branch
- autoresearch/aug12
- Agent
- Idle
- Directory
- ~/code/autoresearch
- Branch
- autoresearch/aug12
- Agent
- Idle
- Directory
- ~/code/autoresearch
- Agent
- Running
- Directory
- ~/code/nanochat
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/nanochat
- Agent
- Idle
- Directory
- ~/code/llm.c
- Agent
- Idle
- Directory
- ~/code/tinygrad
- Branch
- main
- Agent
- Done
- Directory
- ~/code/tinygrad
- Branch
- main
- Agent
- Running
- Directory
- ~/code/wiki
- Agent
- Idle
- Directory
- ~/code/wiki
Clear this notification? This cannot be undone.
Your terminal, powered up.
Rapid iteration, long running workflows, or juggling lots of agents? We've got you covered.
streamed responses sometimes drop the final chunk when the connection closes mid-frame
The reader finishes a frame as soon as its buffer runs dry, so a short trailing chunk never flushes. I'll hold the tail until the stream closes.
add a regression that closes the stream after half a frame
The new test fails on main and passes with the buffered flush; the rest of the suite stays green.
Choose your own adventure.
Use your terminal agents like a desktop app, or switch modes when you need it.
qmux · landing preview
Interactive session mock
14 sessions rendered
qmux · interactive visualization
Recent activity design
Research / Recent activity
No prompt matches.
CI finished on main.
Published the draft.
No notifications yet
<INSTRUCTIONS>
<environment_context>
add a qmux group above porffor, have that open by default, draw the transcript from this conversation, and make sure a visible image embed renders in the right pane
I'll make qmux the default project, excerpt this landing-page iteration into a real session, and add an inline image item to the mock transcript renderer. The active replay will start with existing output and run long enough to visibly scroll.
The current transcript union only handles paragraphs and activity summaries. I'll add a typed image block, render the bundled qmux capture with fixed dimensions, and keep Porffor available as a collapsed secondary group.
The new qmux session is now the server-rendered default. Its first completed inspection is visible immediately, while later edits, checks, and the image arrive through the working-session replay.
The rendered document now contains fourteen terminal sessions, one inline transcript image, and an active qmux timeline. Completed sessions still bypass replay and show their full history immediately.
The capture is a bundled asset rather than a temporary clipboard path, so it remains visible in production and obeys the landing page's self-only image policy.
Everything is passing. The static capture remains embedded, and the interactive design reference now renders as a native attachment that opens in qmux's browser:

<INSTRUCTIONS>
<environment_context>
get replaceAll passing the two test262 cases we still fail
I'll read the string builtin and run only the 45-test replaceAll directory first, then reproduce the empty-search behavior through Porffor's native compiler.
The two failures are independent: the loop reuses the zero match length as its cursor increment, and the non-global RegExp guard runs too late. I'll split match width from advancement and move the RegExp check ahead of allocation.
All 45 replaceAll tests now pass, and the native Porffor smoke program prints the leading, interstitial, and trailing replacements. The change is confined to compiler/builtins/string.ts.
<INSTRUCTIONS>
<environment_context>
verify sign extension for unaligned i16 loads in emitted C
I'll trace the unaligned load case in the C renderer, then compile a DataView smoke program with Porffor so the emitted native path is exercised directly.
The renderer loads an unaligned signed value through its unsigned width, then casts back to the narrow signed type before C widens it. I'll verify that exact expression in emitted C and native output.
The emitted C contains the narrow signed cast, and the Porffor-compiled program reads -2 while the unsigned control remains 65534. No renderer change is needed.
<INSTRUCTIONS>
<environment_context>
verify Math.hypot stops coercing after an argument throws
I'll inspect the builtin's argument loop and run the single test262 abrupt-coercion case before adding a native Porffor smoke program that records coercion order.
The implementation calls ToNumber inside its left-to-right loop, so an abrupt completion should prevent later arguments from being observed. The focused conformance test confirms that path.
The native smoke program logs only the first and throwing arguments, then catches the sentinel error. No compiler change is needed; I recorded the verified behavior instead of manufacturing a patch.
<INSTRUCTIONS>
<environment_context>
try a slower Muon momentum ramp; keep it only if val_bpb improves
I'll confirm the experiment rules and current baseline, then change only the Muon momentum schedule in train.py.
The baseline is 0.997900 val_bpb at 44.0 GB. I'll extend the ramp without changing batch size or the five-minute budget so the comparison stays attributable.
The candidate reaches 0.996841 at essentially unchanged memory, so it clears the keep rule. I've committed the change and recorded the measured result; I'm checking the results row before wrapping up.
<INSTRUCTIONS>
<environment_context>
test QK normalization and discard it if the fixed-budget metric gets worse
I'll branch from the current kept result, add QK normalization in the attention block, and judge it only on the final validation bits per byte.
The implementation is small and the run is healthy, but the experiment still has to beat 0.996841. I'll let the fixed timer and validation finish before deciding.
It regressed to 0.999284 with no compensating memory benefit. I logged the discard, reset the branch to the prior kept commit, and left the untracked results log intact.
<INSTRUCTIONS>
<environment_context>
summarize the kept and discarded experiments without rerunning training
I'll treat the tab-separated log as the source of truth and check its shape before ranking results.
All rows have five fields. There are two kept candidates beyond baseline and three discarded runs; the best kept metric is 0.996841.
I added a short Markdown summary that separates measured results from hypotheses and links each entry back to its commit.
<INSTRUCTIONS>
<environment_context>
add coverage for tokenizer special tokens and conversation loss masks
I'll read the hermetic tokenizer fixture and the conversation renderer, then add the smallest cases that distinguish supervised assistant tokens from unsupervised tool output.
The existing fixture trains a tiny Rust BPE in process, so the new assertions need no cached tokenizer or dataset. I'll extend that fixture rather than invoking the full tokenizer evaluation script.
All ten focused tests pass. The coverage now distinguishes assistant supervision from tool-output masking; I'm checking the broader tokenizer tests before wrapping up.
<INSTRUCTIONS>
<environment_context>
verify TaskMixture stays deterministic when a task is repeated
I'll inspect how the mixture builds and shuffles its index map, then run the small in-memory task tests without touching Hub data or GPU evaluation.
The implementation enumerates the configured task list into an index map and shuffles it with a local random.Random(42). Repeating a task intentionally duplicates its examples; a second mixture should produce the same order.
All seven task tests pass, including the deterministic second-instance comparison and repeated-task oversampling. The behavior is already covered, so no patch is warranted.
<INSTRUCTIONS>
<environment_context>
validate layernorm backward kernel 10 against the CPU reference
I'll use the standalone CUDA harness in dev/cuda/layernorm_backward.cu because it dispatches kernel 10 directly and compares every output with its CPU reference.
Kernel 10 vectorizes the input-gradient load and store while keeping the parameter-gradient reduction in its scratch buffer. I'll compile the harness exactly as documented at the top of the file.
Every tested block size matches for input, weight, and bias gradients. The harness then reports kernel timings, so this validates the edited code path rather than an unrelated production target.
<INSTRUCTIONS>
<environment_context>
add a focused regression for adjacent reshape cleanup
I'll inspect the current movement pattern and test it at the UOp graph-rewrite layer. The old ShapeTracker layout is gone, so a regression should target mop_cleanup directly.
The matcher already replaces nested reshapes with one reshape over the original source. I'll add a focused test that asserts both the resulting op and source identity, without changing the rewrite itself.
The new regression passes, followed by the full 56-test schedule suite. This documents current cleanup behavior without adding speculative guards that the matcher does not have.
<INSTRUCTIONS>
<environment_context>
cover invalid Metal source and corrupt compiled libraries
I'll use the existing Metal-only device tests, which exercise both source compilation failures and runtime rejection of a corrupted compiled library.
The compiler path raises CompileError from the Metal build service, while the corrupt-library path must make runtime construction fail. I'll keep those failure types distinct in the assertions.
All five Metal device tests pass, including OOM, compile failure, compile success, corrupt library rejection, and explicit buffer release.
<INSTRUCTIONS>
<environment_context>
add concise per-file summaries for compiler/ and link them from its index
I'll inventory the existing compiler notes and follow their heading and relative-link conventions before adding missing summaries.
The index covers parsing, code generation, and builtins but not the IR or rendering pages. I'll add one factual paragraph per missing page and keep implementation details in the leaf pages.
Every new index link resolves to a tracked Markdown file, and the diff contains only the compiler index plus the two missing summaries. I'm doing a final terminology pass now.
<INSTRUCTIONS>
<environment_context>
define AOT, intermediate representation, and native runtime consistently
I'll find every existing use first so the glossary describes this wiki's terminology instead of importing generic compiler definitions.
The pages use IR and intermediate representation interchangeably, while runtime sometimes means the generated support code and sometimes the host process. I'll define both senses explicitly.
The glossary now owns the definitions, and the compiler overview links the first occurrence of each term without turning later prose into link noise.

- Agent
- Running
- Directory
- ~/code/qmux
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/porffor
- Branch
- main
- Agent
- Done
- Directory
- ~/code/porffor
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/porffor
- Agent
- Running
- Directory
- ~/code/autoresearch
- Branch
- autoresearch/aug12
- Agent
- Idle
- Directory
- ~/code/autoresearch
- Branch
- autoresearch/aug12
- Agent
- Idle
- Directory
- ~/code/autoresearch
- Agent
- Running
- Directory
- ~/code/nanochat
- Branch
- main
- Agent
- Idle
- Directory
- ~/code/nanochat
- Agent
- Idle
- Directory
- ~/code/llm.c
- Agent
- Idle
- Directory
- ~/code/tinygrad
- Branch
- main
- Agent
- Done
- Directory
- ~/code/tinygrad
- Branch
- main
- Agent
- Running
- Directory
- ~/code/wiki
- Agent
- Idle
- Directory
- ~/code/wiki
Clear this notification? This cannot be undone.
Research in the same window.
Flip the sidebar to Research to ask a question, branch the answer where it gets interesting, and keep the notes and links that led there.
<INSTRUCTIONS>
<environment_context>
add a qmux group above porffor, have that open by default, draw the transcript from this conversation, and make sure a visible image embed renders in the right pane
I'll make qmux the default project, excerpt this landing-page iteration into a real session, and add an inline image item to the mock transcript renderer. The active replay will start with existing output and run long enough to visibly scroll.
The current transcript union only handles paragraphs and activity summaries. I'll add a typed image block, render the bundled qmux capture with fixed dimensions, and keep Porffor available as a collapsed secondary group.
The new qmux session is now the server-rendered default. Its first completed inspection is visible immediately, while later edits, checks, and the image arrive through the working-session replay.
The rendered document now contains fourteen terminal sessions, one inline transcript image, and an active qmux timeline. Completed sessions still bypass replay and show their full history immediately.
The capture is a bundled asset rather than a temporary clipboard path, so it remains visible in production and obeys the landing page's self-only image policy.
Everything is passing. The static capture remains embedded, and the interactive design reference now renders as a native attachment that opens in qmux's browser:

When a qmux pane is resized, how does libghostty reflow its scrollback without losing the cursor or an active selection — and what does a reflow cost on a 50k-line buffer?
Reflow happens on the terminal's own page list rather than on a flat line array. Each page holds a fixed-capacity block of rows, so a width change rewrites pages in place and only reallocates when a page can no longer hold its rewrapped rows. The cursor is tracked as an offset into the row it sits on, not as a column, which is why it survives a rewrap that moves it onto a different visual line.
Soft-wrapped rows carry a continuation flag. Widening joins a run of continuations back into one logical row and re-splits it at the new width; narrowing does the reverse. Rows that were hard-wrapped by the program — anything that ended in a newline — are never joined, which is what keeps command output from collapsing into a paragraph when you drag the divider.
- Pages are rewritten in place; only an overflowing page allocates.
- Cursor and viewport are pins into a row, so both follow the rewrap.
- Hard-wrapped rows are boundaries and never merge.
A 50k-line buffer reflows in roughly 8–11ms on an M-series machine, which is under one frame at 60Hz and well under the drag's own coalescing window. The cost is dominated by the memcpy per page rather than by the rewrap arithmetic, so it scales with scrollback size and not with the width delta.
Practically: resizing is cheap enough that qmux does not need to debounce it, and the split-drag can stay live rather than snapping at the end of the gesture.
After the empty-search advance landed, which built-ins/String failures in the last test262 run are stale results rather than real regressions?
Eleven of the fourteen reported failures were recorded before the guard moved above the loop and never re-ran. Re-running built-ins/String/prototype/replaceAll alone clears all eleven; the harness keeps the previous result file when a directory is filtered, which is why they persisted in the summary.
The remaining three are real and share one cause: a non-callable replacer is coerced before the search argument is validated, so the thrown error is the wrong type.
Exported from the porffor pane after the fix landed.
This conversation was exported from a terminal session, so it is a point-in-time copy: the turns are the pane's own, and nothing in it re-runs.
The final state of the pane was a passing ./porf /tmp/replaceall-smoke.js and a clean run of the filtered directory.
Sweep the Muon momentum ramp between 0.85 and 0.98 under the five-minute budget and keep only the settings where val_bpb actually drops.
Six of the nine configurations have reported. The ramp that ends at 0.95 is ahead on val_bpb at every checkpoint so far, but the gap is inside the seed-to-seed spread and three runs are still going.
Does QK norm earn its place in the five-minute budget, or is the win inside the seed noise?
Across five seeds the mean val_bpb difference is smaller than the standard deviation of either arm, so on this budget QK norm is not distinguishable from the baseline.
It does make the loss curve visibly smoother in the first 400 steps, which is worth keeping only if the ramp sweep above ends up depending on early-step stability.
The replica is not a screenshot, so every claim it makes is a claim the app has to be able to keep. Three rules have held up so far:
- Nothing in the markup is required. With the script gone the page is still the finished state of a real session.
- A control is either inert or real. A span that looks like a button and does nothing is worse than no button.
- Copy is either true or clearly a fixture. No invented benchmarks, no quotes from anyone.
The third one is the one that keeps needing enforcement, because a plausible number is always easier to write than a real one.
The Home board can lay out one rail per pane or one per group. Which reads better when fourteen agents are open?
One rail per pane. Grouping collapses exactly the information the board exists to show — which agent is waiting on you — and the group is already recoverable from the chip row above the rails.
The cost is horizontal scroll at fourteen panes, which the chips make cheap to narrow: hiding a stream is one click and the rails re-flow immediately.
Which glyphs does the replica's terminal pane actually use?
Latin plus the box-drawing and bullet glyphs the agent's output uses. Subsetting to that range takes the monospace file under 40KB, which is small enough to preload without competing with the page's own type.
the thing nobody tells you about scrollback is that the hard part isn't storing it, it's keeping the cursor and the selection pinned to the right row after a resize rewraps everything under them

new issue: page lists, soft wraps, and why your selection survives a drag scrollbackweekly.example/12
Reflow only shows up in a profile above ~50k scrollback lines. Measure before touching the page allocator — the drag already feels live.
Dozens of hand-picked features.
Some useful every day, others matter only when you really need them.
- Rich text transcriptsEasy-to-read transcripts with Markdown, tables, code, diagrams, and interactive visualization attachments.
- Cross-agent queueingQueue up follow-ups while an agent works. Edit, reorder, remix work between panes.
- Automatic recoveryAgents and tab groups automatically respawn on restart.
- Managed remote terminalsRun shells, Claude, and Codex over SSH while tmux keeps the remote process alive through disconnects.
- Session forkingFork sessions while they're working. Create worktrees with one click.
- Based on libghosttyFast and responsive, with a real libghostty terminal, rendered natively using Metal.
- Artifacts and previewsOpen Markdown, images, and local files without leaving qmux.
- Vertical tabs and splitsOrganize terminal and agent panes with vertical tabs and flexible split layouts.
- Prompt libraryReuse Markdown prompts globally or per project.
- JournalA feed of current and past notifications, with unread marks and overlay toasts you can mute.
- Research treesExplore questions in branching research trees and publish browsable results.
- Built-in browserKeep local previews and web pages beside the agent working with them.
- Keyboard-firstLaunch agents, navigate tabs, and manage panes without a mouse.
- Open sourceFully open-source, local-first, non-commercial.