# Handoff — 2026-08-31 — terminal windows ## State **Terminal windows are done and green.** `F8`, or **Window ▸ New terminal**, opens a window running a real shell in a real pseudo-terminal. Ticket 0007. - New package `internal/terminal`: `Session` (pty + process), `Parser` + `Screen` (VT/ANSI emulation, scrollback, alternate screen), `Encode` (keys → terminal bytes), `View` (the `ui` widget). Coverage 95.7 %. - Wired into `app` via `terminals.go`; `app` coverage went from ~71 % to 82.8 %. - Two theme keys added, `terminal.text` and `terminal.cursor`, set in all three shipped themes. The theme suite fails if a shipped theme misses one, so that is enforced rather than remembered. - Whole suite green under `-race` across eight consecutive full runs. - Quality gate **PASS**: 0 errors, 0 warnings, 0 smells, complexity 1023. - Docs complete in EN and FR — three new pages each, six existing pages updated each. `docs/diagrams/packages.drawio` was regenerated and then **checked against `go list` programmatically**: it matches the real import graph edge for edge. - Ticket `0015` created for the Windows/ConPTY port. **Nothing has been committed.** The working tree carries the whole feature, the docs, the memory update and the new ticket. ## In flight Nothing. The feature is finished through Phase 8 of `methodical-dev`. ## Next steps 1. **Commit.** Suggested message and file list are in the session's final summary; `git status` shows `.tickets/`, `.vscode/` and `kits/` as untracked from before this work — decide what belongs in the repository before staging everything. 2. **Try a terminal window on a real terminal.** Everything here was verified against a real pty, but nobody has yet opened one inside a running `turbo-go` on a physical terminal emulator and run `vim` or `htop`. That is the check most likely to find something. 3. **Decide about ticket 0007.** It is the terminal-window ticket and is still `state: open`; closing it was left to the user. ## Open questions / blockers - **Should `F1`…`F12` be reachable inside a terminal?** They are currently reserved by the editor, so `htop`'s function-key menu cannot be used. The reasoning is written up in `docs/*/explanation/terminal-windows.md`; if the user disagrees, the change is one predicate — `editorOwnedKey` in `internal/app/app.go`. - **`internal/terminal/pty_darwin.go` has never been run.** It compiles and passes `go vet`, and uses the documented `TIOCPTYGRANT` / `TIOCPTYUNLK` / `TIOCPTYGNAME` ioctls, but this sandbox is Linux. The first Mac run is the test. - **The tickets' `tasks:` schema is unknown.** Every existing ticket has `tasks: []`, so `0015`'s checklist went into the `body` rather than into an invented task shape. If IssueSpec defines one, move it. ## Watch out for - **A pseudo-terminal echoes the command line.** A test that types `echo red` and waits for `red` on screen passes *before* the shell has run anything — it matched the echo. Wait for something only the output can produce: a colour, or a string the typed line spells differently (`echo turbo''-go-works` produces `turbo-go-works`). This is the same class of mistake as the gopls-answers-from-disk trap from 2026-08-30. - **Never assert on a screen cell while a live shell is writing to it.** A drawing test doing that passed by luck and was hiding a real fault: the cell it sampled, (0,0), is where the *cursor* is drawn on a fresh screen, not the text. `newOfflineView` in `view_test.go` builds a `View` with no session behind it — `Draw` needs none — and is the deterministic way to test drawing. - **`tcell.KeyCtrlC` is 67, not 3.** tcell reports a control byte as `KeyCtrlSpace + b`, and `KeyCtrlSpace` is 64. Code testing `key < 0x20` for a control key matches nothing, silently, and every Ctrl-key would send no bytes at all. - **The routing order in `App.keyLayers()` is load-bearing.** A focused terminal deliberately sits *above* the global shortcuts. Move it below and `Ctrl-W` closes the window instead of deleting a word — there is a test for exactly that, `TestAFocusedTerminalKeepsTheKeysAShellNeeds`. - **`terminal.*` theme keys do not fall back to `editor.*`.** Dotted fallback runs along the dots and stops at `default`. A new theme must set both groups. - **`internal/app/README.md`'s file table was stale** — it listed an `actions.go` that has not existed for some time. It is corrected now; the lesson is that a table of files rots silently.