# T3 Code fork: technical notes The detail behind https://t3.thatmike1.dev. Fork: https://github.com/thatmike1/t3code, built on T3 Code 0.1.9 (branch `v2-stable-on-0.1.9`). Paths are relative to the repository root. Commit ids are on that branch and change with each rebase onto a new upstream release; search the log by subject when one does not resolve. Written 11 November 2026. ## Thread switcher (Ctrl+Tab) and settle (Ctrl+W) - Hold Ctrl, press Tab: a "Recent threads" list opens with the previous thread selected. Tab and Shift+Tab move, releasing Ctrl opens the selection, Esc cancels, a click on a row opens it, a click outside dismisses it. - The list is most recent first, includes unsent new-thread drafts, and is stored in localStorage (`t3code:thread-switcher:recent`), so it survives a restart. Settled threads stay in it for an hour after they were settled or last looked at; snoozed threads never show. - Ctrl+W settles the open thread and moves to the most recently visited thread that is still open: drafts, settled, snoozed, archived and deleted threads are skipped, and with none left it goes to the start screen. A thread that is still working is not settled: the server refuses, a toast gives the reason and the thread stays. With the right panel open Ctrl+W closes the panel instead, and with the terminal focused it closes the terminal. It never closes the window. - Clicking the sidebar row of the thread you are already in goes back to the previous one. - The desktop shell catches Ctrl+Tab at the window and hands it to the page (`ThreadSwitcherInput.ts`). - Files: `apps/web/src/components/ThreadSwitcher.tsx`, `apps/web/src/thread-switcher.logic.ts`, `apps/desktop/src/window/ThreadSwitcherInput.ts`, `apps/web/src/components/chat/useThreadLifecycle.tsx`, `apps/web/src/components/ChatView.tsx` (the `rightPanel.close` command). - Commits: `f0b1dd7a49` (switcher), `162619fdc4` (Ctrl+W), `479ac90686` (mouse, drafts, persistence), `d38fb23de3` (click to go back). ## Claude usage meter - A number in the sidebar footer, after Settings, Pull requests and Usage: Claude's five-hour use in percent. Its tooltip reads "Claude 5-hour: 62% used, checked 3m ago". - Click for a popup with three rows: Codex weekly, Claude 5-hour (with the time left until it resets), Claude weekly, and a Refresh button. Opening the popup re-reads when the last reading is older than five minutes. - Readings come from the provider usage limits T3 Code already collects for signed-in Claude and Codex accounts. One source per provider: the primary machine first, then connected ones. - A reading older than 15 minutes, or from a machine that is offline, is dimmed (the footer number at half opacity, the row value muted). A window that has reset since the last reading shows as reset, not as zero measured. A failed refresh shows a notice instead of claiming success; it does not dim a reading that is still recent. - Files: `apps/web/src/components/sidebar/SidebarUsageMeter.tsx`, `SidebarUsageMeter.logic.ts`, `apps/server/src/provider/ProviderRegistry.ts`. - Commits: `790a97c983`, `067ee6c5fe` (honest refresh results), `03979cc44c` (time to reset). ## Files by path - Paste an absolute or `~/` path into the file panel's path field, or into Ctrl+P, where it appears as "Open file by path". The file opens in the right panel for editing even when it is outside the project. A missing file offers "Create empty file". - Absolute and `~/` paths written in plain chat text become the same file link an inline-code path gets. Words like `and/or` and URLs are not paths. - A folder opened this way shows an "Open in Files" button (Finder on macOS, File Explorer on Windows) next to its breadcrumbs. - Writes through this path refuse four places: the server's secrets directory, its SQLite state files (names containing `.sqlite`, directly in the state directory), `/dev/fd`, and git metadata. Other files under the state directory can be written. - Files: `apps/web/src/components/files/FilePreviewPanel.tsx`, `apps/web/src/components/files/ProjectFilePicker.tsx`, `apps/web/src/markdown-path-links.ts`, `apps/server/src/workspace/WorkspaceFileSystem.ts`, `apps/server/src/auth/serverInternalPaths.ts`. - Commits: `25e3d46330`, `ca2380de58` (create missing files), `3fbcdbc308` (paths in chat), `1d162392e4` (file manager), `8bb289c04e` (write guard). ## Model shortcuts - Nine commands, "Model shortcut 1" to "Model shortcut 9" (`composer.model.slot1` to `slot9`). In Settings, Keybindings each row shows its key and, beside it, a picker for the model it selects; the clear arrow empties the slot. Models are saved per client, separately from the keys. - A key picks the model for a new thread and leaves started threads alone. An empty slot shows a hint when pressed ("Model shortcut 2 has no model yet"). A slot whose saved model is no longer offered by a ready provider selects nothing until you pick another. A new install starts with every slot empty. - Default keys: Alt+1, 3, 4, 6, 7, 8 and 9. Slots 2 and 5 start unbound, which leaves Alt+2 and Alt+5 free to bind to effort yourself. T3 Code binds neither: its Increase Effort and Decrease Effort commands have no default key. - Builds before the slots had named commands (`composer.model.opus`, `.sol`, `.fable`, `.astra`, `.luna`); updating moves each into the slot of the same digit with the model it picked (`apps/server/src/fork-model-slot-keybindings.ts`). - Files: `apps/web/src/quick-model-shortcuts.ts`, `apps/web/src/components/settings/fork-model-slots.tsx`, `packages/contracts/src/keybindings.ts`, `packages/shared/src/keybindings.ts`, `docs/user/keybindings.md`. - Commits: `33ebac2d8b` (slots) and `115064f7d3` (migration fills missing slots, every slot gets a row), both on `v2-stable-on-0.1.9` since 11 Nov 2026, on top of `17cc68f083`, `6bc9e55829`, `9384a1e318`. ## Smaller things - **Chat on the left.** Settings, Appearance: chat alignment (centre or left) and a left gutter. `apps/web/src/components/ChatAlignmentSync.tsx`, `AppearanceSettingsPanel.tsx`. Commits `a362d30f81`, `e2a664dc48`, `2cff7a4647`, `656b0f0d8a` (overlays follow the column). - **Line under pinned threads.** 1px at sidebar-foreground 20%, hidden while dragging. `apps/web/src/components/Sidebar.tsx`, `sidebar/SidebarListMarkers.tsx`. Commits `bcd7c5e221`, `9d7826bf30`. - **Where a fork came from.** A GitFork glyph before the title of a user-forked thread; tooltip "Forked from ", click opens the parent. An archived parent reads "Forked from (archived)" and a deleted one "Forked from deleted thread"; neither opens. Archived parents are looked up on hover. Contributed by MetrPikeska. `apps/web/src/components/sidebar/SidebarForkOrigin.tsx`. Commit `51b76933fa`. - **Home project.** `chat.newHome` on Ctrl+Alt+Shift+N opens a new thread in the project marked as home. `apps/web/src/hooks/useHomeProject.ts`. Commit `288151a35e`. - **Machine filter.** Sidebar filter by connected machine. Commit `3bb98f8cb5`. - **Working section.** Where a finished thread returns (top or its old place) and which machines' running threads shelve. Commit `9d4430df08`. - **Actions without the terminal.** A per-action checkbox in project actions. `apps/web/src/projectScripts.ts`. Commit `ba26275f14`. - **Missed scheduled tasks.** A fixed-time task can run later the same day when the machine was off at its time. `apps/server/src/scheduledTasks/Schedule.ts`. Commit `b9fffd6639`. - **Middle-click paste.** Linux only; reads the primary selection through the desktop shell. `apps/desktop/src/ipc/methods/primary-selection.ts`. Commit `2aa91b3f03`. - **Thread in the window title.** For time trackers such as ActivityWatch. `apps/web/src/documentTitle.ts`, `DocumentThreadTitle.tsx`. Commit `2ee5f2c357`. - **Artwork.** Settings, Appearance, Fork artwork: MS Paint, Bonsai, Scribble or Off. Changes the sidebar header strip and the send button. Only Bonsai has its own app icon; MS Paint, Scribble and Off all use the Paint icon (`apps/desktop/src/app/DesktopAssets.ts`). Assets in `apps/web/public/fork-artwork/` and `assets/fork/`. Commits `9991399f4c`, `3cb55fd82e`, `6f7faaccd5`, `8acd4f548b`, `8ed083c449` (fork mark). - **About shows the build version.** `apps/web/src/components/settings/AboutVersionTitle.tsx`. Commit `67144fa42f`. ## Wired to my own setup These ship in every build, and each needs the program it talks to. Read aloud shows its controls either way, as its line says. - **Sidebar icons from scripts.** The server watches `~/.t3/userdata/widgets/` and renders each `*.json` file as an icon in the sidebar footer: `id`, `icon` (circle, terminal, mic, activity, list-checks, bell, server, clock, zap, folder), `state` (ok, attention, off, error), optional `label`, `tooltip`, `rows` for a click popup, `order`, and `staleAfterSeconds` (120 by default; older files grey out). Contract: `packages/contracts/src/widgets.ts`. Commits `f5115762f7`, `af9e562bc8`, `51fddba9ba`. - **Issue links.** Bead ids in messages become chips that open the issue on beadside at `127.0.0.1:1338`. Short ids link only when beadside knows them; with beadside stopped, full ids still link. The chip has a context menu and can open in T3's own browser. Which projects link to which board is set in Settings. `apps/web/src/markdown-bead-links.ts`, `components/chat/BeadChip.tsx`. Commits `ae79f357b0`, `8523cd297c`, `6bc9e55829`, `5c10f2c663`, `f9a24cf998`. - **Tab colours.** The server reads Firefox's default profile session file and the colour Sidebery stores per tab; a thread that opened a tab gets a stripe in that colour. Clicking it opens the URL with `#t3-focus`, which a Firefox AutoConfig hook (not part of the fork) turns into focusing the open tab. Commits `963b5466f6`, `9ecdb4ad88`. - **Read aloud.** A speaker button on every finished reply and a live-voice switch per thread in the chat header. Both are visible in every build; they call a speech service at `http://127.0.0.1:1357`, and without one a click ends in a single error toast. `apps/web/src/lib/claudeVoice.ts`, `claudeVoicePlayer.ts`. Commits `eee859eb39`, `9ed7b7a625`, `9ff27bf0e9`. ## Not on the page - Memory captures show as a readable work-log line (`0f8305d7c4`): only meaningful with a memory helper nobody else runs. - Grouping fixes: ssh alias remotes grouped with github.com, repo-name labels (`aa4641457b`, `52ca501435`); the project picker stays open behind its context menu (`bedde50d2d`). ## No longer in the fork - Threads started by agents: part of T3 Code now. - Effort keys (the fork's own Alt+2 and Alt+5): dropped for T3 Code's effort commands (`982929c7a1`). - Favourite projects: replaced by T3 Code's project pinning. ## Install and updates Releases: https://github.com/thatmike1/t3code/releases. Linux gets an x86_64 AppImage, Windows an x64 installer. Asset names carry the version (`T3-Code--x86_64.AppImage`, `T3-Code--x64.exe`), so link to the releases page rather than a file. Both builds read `latest-linux.yml` or `latest.yml` from the fork's releases and update themselves.