# T3 Code — full corpus # LLM Wiki An open-source template for building LLM-powered knowledge bases, following [Andrej Karpathy's "LLM Wiki" pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f). You provide raw sources. The LLM reads them, writes structured wiki pages, cross-links everything, and maintains it over time. You never edit the wiki directly — you curate sources and ask questions. ## How It Works The system has three layers: ``` raw/ Sources you collect (articles, transcripts, notes, PDFs) wiki/ LLM-written & maintained pages (summaries, concepts, entities, syntheses) CLAUDE.md Schema that tells the LLM how to structure everything ``` Three operations drive the workflow: | Operation | Trigger | What happens | |-----------|---------|--------------| | **Ingest** | "ingest raw/my-source.txt" | LLM reads the source, creates a summary page, creates/updates concept and entity pages, adds cross-links, updates the index and log | | **Query** | Ask any question | LLM searches the wiki, synthesizes an answer with citations, optionally creates a synthesis page for novel insights | | **Lint** | "lint" or "health check" | LLM audits all pages for orphans, contradictions, missing links, incomplete sections, and low-confidence claims — fixes what it can, reports the rest | ## Quick Start 1. **Clone this repo** ```bash git clone https://github.com/YOUR_USERNAME/llm-wiki.git my-knowledge-base cd my-knowledge-base ``` 2. **Customize CLAUDE.md** for your domain - Update the Purpose section with your topic - Replace the placeholder tagging taxonomy with your own categories - Adjust confidence level descriptions if needed - Everything else (workflows, page formats, linking rules) works as-is 3. **Drop sources into `raw/`** - Text files, transcripts, articles, notes — any plain text - These are immutable once added; the LLM never modifies them 4. **Tell the LLM to ingest** ``` ingest raw/my-first-source.txt ``` The LLM will create summary pages, concept pages, entity pages, cross-links, and update the index. 5. **Ask questions** ``` What are the key differences between X and Y? ``` The LLM answers from the wiki, citing specific pages. 6. **Run health checks** ``` lint ``` The LLM audits the wiki and fixes issues. ## Directory Structure ``` . ├── CLAUDE.md # Schema — the LLM's instructions ├── raw/ # Your source documents (immutable) └── wiki/ ├── index.md # Master catalog of all pages ├── log.md # Append-only activity log ├── dashboard.md # Dataview dashboard (Obsidian) ├── analytics.md # Charts View analytics (Obsidian) ├── flashcards.md # Spaced repetition cards ├── summaries/ # One page per source document ├── concepts/ # Concept and framework pages ├── entities/ # People, tools, organizations, etc. ├── syntheses/ # Cross-cutting analyses and comparisons ├── journal/ # Research/session journal entries │ └── template.md # Journal entry template └── presentations/ # Marp slide decks ``` ## Enhancements This template includes several extras beyond the core wiki pattern: ### Dataview Dashboard (`wiki/dashboard.md`) Live queries that surface low-confidence pages, recent updates, concepts by tag, and pages with the most sources. Requires the [Dataview](https://github.com/blacksmithgu/obsidian-dataview) Obsidian plugin. ### Charts View Analytics (`wiki/analytics.md`) Visual analytics with pie charts, bar charts, and word clouds. Requires the [Charts View](https://github.com/caronchen/obsidian-chartsview-plugin) Obsidian plugin. ### Mermaid Diagrams Use Mermaid code blocks in any wiki page to create flowcharts, sequence diagrams, or concept maps. Native support in Obsidian and GitHub. ### Marp Slides (`wiki/presentations/`) Create slide decks from markdown using [Marp](https://marp.app/). Drop presentation files in this directory. ### Research Journal (`wiki/journal/`) Track your research sessions, experiments, or applied work with the included template. The LLM can reference journal entries when answering queries. ### Spaced Repetition (`wiki/flashcards.md`) Flashcards in the format used by the [Spaced Repetition](https://github.com/st3v3nmw/obsidian-spaced-repetition) Obsidian plugin. Ask the LLM to generate flashcards from any wiki page. ### MCP Server This repo works with Claude Code's MCP server capabilities. Point an MCP-compatible client at this repo and the LLM can read/write the wiki programmatically. ## Customizing for Your Domain The schema in `CLAUDE.md` is domain-agnostic. To adapt it: 1. **Purpose** — Describe your knowledge domain in one paragraph 2. **Tagging taxonomy** — Replace placeholder categories with your own (e.g., for a cooking KB: `cuisine`, `technique`, `ingredient`, `equipment`) 3. **Confidence levels** — Adjust the descriptions to match your domain's evidence standards 4. **Entity types** — Update the entity page description to match what entities mean in your domain (people, tools, companies, etc.) 5. **Journal template** — Customize `wiki/journal/template.md` for your workflow Everything else — page format, linking conventions, workflows, rules — is universal and works across domains. ## Example Domains This template works for any knowledge-intensive topic: - **Research notes** — papers, experiments, methodologies - **Book analysis** — themes, characters, author techniques - **Competitive analysis** — companies, products, market trends - **Course notes** — lectures, readings, key concepts - **Personal development** — frameworks, habits, book summaries - **Technical documentation** — APIs, architectures, design patterns - **Hobby deep-dives** — any subject you want to master ## License MIT # T3 Code Knowledge Base An LLM-maintained knowledge base on **T3 Code** (github.com/pingdotgg/t3code, t3.codes) — an open-source 'agent harness control surface' by Ping/Theo: control coding agents (Claude Code, Codex, Cursor, Grok Build, OpenCode) from mobile/web/desktop apps, remote-ready via T3 Connect. Pinned to 0.0.32-nightly (2026-08-05). ## Concepts - [[concepts/t3code-overview|T3 Code Overview]] - [[concepts/install-and-getting-started|Install and Getting Started]] - [[concepts/providers|Providers]] - [[concepts/permission-modes|Permission Modes]] - [[concepts/remote-access|Remote Access]] - [[concepts/t3-connect|T3 Connect]] - [[concepts/source-control|Source Control]] - [[concepts/background-service|Background Service]] - [[concepts/keybindings-and-updating|Keybindings and Updating]] - [[concepts/architecture|Architecture]] - [[concepts/terminal-renderers|Terminal Renderers]] - [[concepts/environment-auth|Environment Authentication]] - [[concepts/observability|Observability]] - [[concepts/resource-telemetry|Resource Telemetry]] - [[concepts/ci-and-release|CI and Release]] - [[concepts/testing-and-agent-skills|Testing and Agent Skills]] - [[concepts/glossary|Glossary]] - [[concepts/troubleshooting|Troubleshooting: Recurring and Confirmed Problems]] ## Agent Providers - [[entities/provider-claude-code|Claude Code (Provider)]] - [[entities/provider-codex|Codex (Provider)]] - [[entities/provider-cursor|Cursor (Provider)]] - [[entities/provider-grok-build|Grok Build (Provider)]] - [[entities/provider-opencode|OpenCode (Provider)]] ## Summaries - [[summaries/release-digest|Release Digest: T3 Code Nightly Stream (0.0.32-nightly, builds 956–1009)]] --- title: "Architecture" type: concept tags: [architecture, developer, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-overview-md.md", "raw/github_doc-docs-internals-workspace-layout-md.md", "raw/github_doc-docs-internals-connection-runtime-md.md", "raw/github_doc-agents-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Architecture ## Definition T3 Code's architecture is a **server-owned execution model**: a single server runtime (`apps/server`, published as the CLI package `t3`) owns agent sessions, workspaces, and version control, while clients (web, desktop, mobile) talk to it over one authenticated Effect RPC WebSocket connection. The server is the execution boundary — every provider process, terminal, git operation, and filesystem read happens there, never in the client. ## How It Works At the top level, the system is three layers: ``` Clients: apps/web, apps/desktop, apps/mobile shared runtime: packages/client-runtime (connection supervisor, RPC session, Atom state) │ Effect RPC over WebSocket (/ws), contract in packages/contracts apps/server orchestration engine (event-sourced), provider driver registry (5 built-in drivers), checkpointing, VCS, terminals, filesystem │ per-driver transport Agent CLIs: Codex, Claude, Cursor, Grok, OpenCode ``` **The RPC boundary.** The client/server contract is an Effect RPC group (`rpc.ts` declares `WS_METHODS`), not a hand-rolled push protocol. Streaming members such as `orchestration.subscribeShell`, `orchestration.subscribeThread`, `subscribeServerConfig`, and `terminal.attach` replace a broadcast push bus: a client subscribes to what it needs and the server pushes only on that subscription. `ws.ts` mounts `GET /ws`, authenticates the upgrade through `EnvironmentAuth.authenticateWebSocketUpgrade`, then hands the socket to `RpcServer.toHttpEffectWebsocket`. Authorization is per method — `RPC_REQUIRED_SCOPE` maps each method to a scope, enforced by `authorizeEffect`/`authorizeStream`. Holding a valid socket is not authorization to call everything on it; see [[concepts/environment-auth]]. On the client, `session.ts` opens the socket, performs one attempt with no retry, and exposes `client`, `initialConfig`, `ready`, `probe`, and `closed`. Retry, backoff, and offline policy belong to the connection supervisor, not the session. **Shared client runtime.** `packages/client-runtime` holds every non-visual client concern: connection lifecycle, authentication, RPC, cached environment data, and domain state as Atom factories. Web and mobile compose it identically (`apps/web/src/connection/runtime.ts` and `apps/mobile/src/connection/runtime.ts` mirror each other, differing only in platform-specific background-activity layers). React components never construct transports, retry loops, or RPC clients directly. The connection layer (`connection/layer.ts`) assembles `ConnectionResolver` (resolves a catalog entry into a prepared, authenticated endpoint for primary, bearer, relay, or SSH targets), `ConnectionDriver` (prepares through the resolver, opens one RPC session, reports `preparing`/`opening`/`synchronizing`), and `EnvironmentRegistry` (owns the catalog and per-environment scopes, creating one environment-scoped supervisor per environment). `EnvironmentSupervisor` is the sole retry owner: transient failures retry forever with exponential backoff capped at 16 seconds (`RETRY_DELAYS_MS`), a connection stable for 30 seconds resets accumulated backoff, and authentication/configuration failures stay blocked until an external wakeup changes the relevant input. **Orchestration is event-sourced.** The server never mutates app state directly. Clients dispatch typed commands; `OrchestrationEngine.ts` serializes processing through a single worker fiber pulling `CommandEnvelope`s off `commandQueue` one at a time (totally ordered). For each envelope: check the durable command receipt (idempotent retries) → run the pure `decideOrchestrationCommand` (`decider.ts`) to produce events → inside one SQL transaction, append events, apply them to the in-memory read model via `projector.ts`, project into persisted tables, and write the accepted receipt → after commit, swap in the new read model and publish committed events to subscribers. Because persistence and projection share a transaction, the read model cannot durably disagree with the event log. A turn is complete when its session leaves `running` status (`settledTurnStateForSessionStatus` in `projector.ts`); checkpoint work settling later does not define turn end. **Drainable workers.** Follow-up work runs asynchronously in queue-backed workers built on `DrainableWorker`: `ProviderRuntimeIngestion` normalizes provider runtime streams into orchestration commands, `ProviderCommandReactor` dispatches provider calls in response to intent events, and `CheckpointReactor` captures and reverts workspace checkpoints. `DrainableWorker` pairs a transactional queue with a transactional outstanding-item count so a test can await "queue empty and current item finished" instead of sleeping. Runtime receipts (`RuntimeReceiptBusLive`) are test-only — production publish is a no-op. **Provider drivers.** Five drivers ship built in (`BUILT_IN_DRIVERS` in `builtInDrivers.ts`): Codex, Claude, Cursor, Grok, and OpenCode. A driver declares its kind and config schema and creates a scoped adapter; `ProviderInstanceRegistry` owns live instances and `ProviderAdapterRegistry` resolves an instance to its adapter, so `ProviderService` routes session and turn operations without knowing which agent is behind them. See [[concepts/providers]]. **Checkpointing.** Each turn is bracketed by workspace checkpoints so diffs and reverts are exact. `CheckpointStore` captures state as hidden Git refs through the VCS driver's checkpoint operations; `CheckpointDiffQuery` answers turn and full-thread diff requests; `CheckpointReactor` coordinates baseline capture, completed-turn capture, diff projection, and reverting both the workspace and the provider conversation. **Startup.** `serverRuntimeStartup.ts` runs a fixed lifecycle: start keybindings, settings, and reactors → publish welcome → signal command readiness (logged as `Accepting commands`) → wait for the HTTP listener (`markHttpListening`) → publish ready → fork the heartbeat → then either print headless output or open the browser. Command readiness precedes the listener, so a socket that opens can already dispatch. **Workspace layout.** T3 Code is a pnpm workspace driven by [vite-plus](https://vite.plus) (`vp`). Apps: `apps/server` (the `t3` CLI and execution runtime; also serves the built web app), `apps/web` (`@t3tools/web`, React+Vite UI), `apps/desktop` (`@t3tools/desktop`, Electron shell that supervises a desktop-scoped `t3` backend and owns SSH-managed remote environments), `apps/mobile` (`@t3tools/mobile`, Expo/React Native), `apps/marketing` (Astro site). Packages: `packages/contracts` (shared Effect Schema definitions — RPC group, orchestration commands/events/read model, auth scopes, environment descriptors, settings), `packages/shared` (framework-agnostic utilities: `DrainableWorker`, git/source-control helpers, relay auth/signing, DPoP, semver, logging, observability), `packages/client-runtime` (connection lifecycle, authorization, RPC session, environment registry, Atom-based domain state), `packages/ssh` (SSH config, auth prompts, command execution, tunnel/environment manager behind desktop-managed SSH environments), `packages/tailscale` (Tailscale CLI wrapper including `ensureTailscaleServe`/`disableTailscaleServe`), `packages/effect-acp` (Agent Client Protocol client/agent implementation) and `packages/effect-codex-app-server` (Effect client for `codex app-server` JSON-RPC). Infra: `infra/relay` (`t3code-relay`, the hosted T3 Connect relay, deployed with Alchemy; not in the hot path — after connect, client traffic goes directly to the environment). `@t3tools/shared` and `@t3tools/client-runtime` use explicit subpath exports with no barrel index and no root export; unexported files are implementation details. ## Key Parameters - `WS_METHODS` / `WsRpcGroup` (`packages/contracts/src/rpc.ts`) — the typed RPC surface. - `RPC_REQUIRED_SCOPE` — per-method authorization mapping enforced at the WebSocket boundary. - `CommandEnvelope` / `commandQueue` / single worker fiber — total ordering guarantee for orchestration commands. - `DrainableWorker` — transactional queue + outstanding-count pairing used by all three reactors. - `BUILT_IN_DRIVERS` (5: Codex, Claude, Cursor, Grok, OpenCode) — the provider driver registry. - `RETRY_DELAYS_MS` (16-second cap) — connection supervisor backoff ceiling; 30s stable connection resets it. - `infra/relay` — the T3 Connect relay, out of the runtime hot path after connection. ## When To Use Read this page when navigating where new server-side logic belongs (decider vs. projector vs. reactor), when adding a new RPC method (and its required scope), when tracing why a turn hasn't "ended" yet, or when deciding whether new client code belongs in `packages/client-runtime` versus a platform-specific layer. ## Risks & Pitfalls - Mutating app state outside the command → decider → event → projector pipeline breaks the event-sourcing guarantee that the read model cannot durably disagree with the event log. - Treating a valid open WebSocket as sufficient authorization — every RPC method still enforces its own required scope. - Building production behavior on `RuntimeReceiptBus` receipts — the production bus is a no-op publisher; only the test layer is PubSub-backed. - Constructing RPC clients, retry loops, or transports directly from React components instead of going through the connection supervisor. - Importing from `@t3tools/shared` or `@t3tools/client-runtime` root instead of their explicit subpaths — there is no root export by design. ## Related Concepts - [[concepts/environment-auth]] — the scope model enforced at the RPC boundary described here. - [[concepts/resource-telemetry]] — a subsystem built on the same server/Electron split. - [[concepts/observability]] — how this architecture's runtime behavior is traced and measured. - [[concepts/ci-and-release]] — how this workspace layout is built, checked, and shipped. - [[concepts/terminal-renderers]] — a concrete example of the client/server split (server-owned PTY, client-owned rendering). - [[concepts/glossary]] — definitions for terms used throughout this page (turn, thread, aggregate, checkpoint, etc.). - [[concepts/t3code-overview]], [[concepts/providers]], [[concepts/remote-access]], [[concepts/t3-connect]] — sibling pages covering the product surface built on this architecture. ## Sources - raw/github_doc-docs-internals-overview-md.md - raw/github_doc-docs-internals-workspace-layout-md.md - raw/github_doc-docs-internals-connection-runtime-md.md - raw/github_doc-agents-md.md --- title: "Background Service" type: concept tags: [operations, install, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-user-background-service-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition The background service is a way to run T3 Code as a persistent process on a Linux host: it starts when the machine boots and keeps running after the user logs out, rather than only running while a foreground CLI session or desktop app is open. The background service currently requires Linux with systemd. ## How It Works Install it with the latest T3 Code release: ```sh npx t3@latest service install ``` Check whether it is installed: ```sh npx t3@latest service status ``` Update or repair it: ```sh npx t3@latest service update ``` Stop it and remove it from startup: ```sh npx t3@latest service uninstall ``` Updating restarts T3 Code briefly — active agent work and terminal commands should be allowed to finish first, and if a remote update is already in progress, a local update should wait for it to finish before retrying. Internally the systemd unit runs a small, stable launcher (see [[concepts/keybindings-and-updating]] for the update protocol this launcher implements). Exact T3 Code versions are installed separately from the launcher itself, so a failed remote update candidate can roll back to the previous version without rewriting the systemd unit. The launcher snapshots the database before a remote candidate starts, so database updates roll back together with the server version being rolled back. An older launcher may require one local `service update` before this rollback capability is available. ### Relationship to T3 Connect T3 Connect ([[concepts/t3-connect]]) may offer to install the background service during its setup flow, so the host stays reachable after the user logs out — but this is only an onboarding shortcut. The service and T3 Connect are managed independently: signing out of T3 Connect does not remove the service. `t3 service uninstall` is the explicit way to stop T3 Code from starting in the background. ## Key Parameters - **Platform requirement**: Linux with systemd only. - **Lifecycle commands**: `service install`, `service status`, `service update`, `service uninstall` (all under `npx t3@latest`). - **Independent lifecycle from T3 Connect**: installing/uninstalling one does not affect the other. ## When To Use Use the background service when a Linux machine needs to keep running T3 Code (and therefore stay reachable for [[concepts/remote-access]]) across reboots and logouts — for example, a home server or always-on workstation that mobile or web clients connect to. ## Risks & Pitfalls - Updating restarts the server; kicking off `service update` while agent work or terminal commands are still running can interrupt them. - Retrying a local `service update` while a remote update is already in progress should be avoided — wait for the in-progress update to finish first. - An older launcher may lack rollback support until one local `service update` has been run, meaning early remote updates on such a host are less safe than later ones. - Signing out of T3 Connect is not equivalent to uninstalling the background service — the service keeps running until explicitly uninstalled with `t3 service uninstall`. - The feature is Linux/systemd-only; it is not available for macOS or Windows hosts per this source. ## Related Concepts - [[concepts/t3-connect]] - [[concepts/remote-access]] - [[concepts/keybindings-and-updating]] - [[concepts/install-and-getting-started]] ## Sources - raw/github_doc-docs-user-background-service-md.md --- title: "CI and Release" type: concept tags: [operations, ci, release, developer, operator, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-ci-md.md", "raw/github_doc-docs-operations-release-md.md", "raw/github_doc-docs-internals-scripts-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # CI and Release ## Definition CI and release together are T3 Code's automated pipeline for validating every change and shipping it: a fixed set of quality gates run on every PR and push to `main`, and a single unified GitHub Actions workflow builds, signs, and publishes stable and nightly desktop, CLI, and hosted-web artifacts from tags and schedules. ## How It Works ### CI quality gates `.github/workflows/ci.yml` runs four jobs on pull requests and pushes to `main`: - **Check**: `vp check` (format and lint; this repo sets `typeCheck: false` in its lint options), then `vpr typecheck` for the workspace type check. The same job builds the desktop pipeline (`vp run build:desktop`) and verifies the preload bundle exists and still exports its expected symbols. - **Test**: `vp run test` across the workspace. - **Mobile Native Static Analysis**: `vp run lint:mobile` on macOS, wrapping `scripts/mobile-native-static-check.ts`. - **Release Smoke**: exercises release-only workflow steps through `scripts/release-smoke.ts`, so release breakage surfaces on PRs rather than at tag time. `.github/workflows/release.yml` builds macOS (`arm64` and `x64`), Linux (`x64`), and Windows (`x64`) desktop artifacts from a single `v*.*.*` tag and publishes one GitHub release. It auto-enables signing only when platform credentials are present; macOS passkey builds additionally require `APPLE_TEAM_ID` and the `MACOS_PROVISIONING_PROFILE` secret, Windows uses Azure Trusted Signing, and without the core signing credentials it still releases unsigned artifacts. ### Release workflow The same `release.yml` workflow drives both stable and nightly channels. Triggers: a pushed tag matching `v*.*.*` (stable), a scheduled nightly check every three hours, or a manual `workflow_dispatch` for either channel. It runs quality gates first (lint, typecheck, test), reads the shared production T3 Connect relay URL and Clerk client configuration, and builds four artifacts in parallel per channel: macOS arm64 DMG, macOS x64 DMG, Linux x64 AppImage, Windows x64 NSIS installer. It publishes one GitHub Release per run: stable tags with a suffix after `X.Y.Z` (e.g. `1.2.3-alpha.1`) publish as prereleases, only plain `X.Y.Z` stable releases are marked the repository's latest release, and nightly runs are always prereleases and never latest. Release notes are pinned to the previous tag in the same channel. Electron auto-update metadata (`latest*.yml`, `nightly*.yml`, `*.blockmap`) ships with release assets. The CLI package (`apps/server`, npm package `t3`) publishes via OIDC trusted publishing from the same workflow — stable to dist-tag `latest`, nightly to dist-tag `nightly`. The hosted web app deploys to Vercel only after a release publishes: stable aliases to the `latest` hosted channel, nightly to the `nightly` channel. **Stable release credentials.** Beyond platform/deployment credentials, stable releases need `RELEASE_APP_ID` and `RELEASE_APP_PRIVATE_KEY`; the finalize job uses them to commit and push aligned package versions to `main` as the Release App. GitHub Release publication uses the repository-scoped workflow token, independent of the shared Release App installation's rate limit. **T3 Connect relay deployment.** The relay is a shared control plane versioned separately from client releases — stable and nightly builds must point at the same relay so users see the same linked environments across channels. `.github/workflows/deploy-relay.yml` deploys Alchemy stage `prod` on every push to `main`; the release workflow reads the relay URL and Clerk config from the `production` GitHub Actions environment before building any client. See [[concepts/t3-connect]]. **Hosted web app deployment.** The web project disables automatic Git deployments (`git.deploymentEnabled: false` in `apps/web/vercel.ts`); `release.yml` deploys with the Vercel CLI after the GitHub Release succeeds. Users opt into a channel by visiting `/__t3code/channel?channel=latest|nightly`; the router stores a `t3code_web_channel` cookie and rewrites future requests on `app.t3.codes` to the matching channel alias. **Nightly builds.** Tag format `vX.Y.Z-nightly.YYYYMMDD.` (`nightly-v...` accepted only as a legacy previous-nightly tag); release name includes the short commit SHA; `make_latest` is always `false`. Nightly uses the next stable patch version as its base — e.g. stable `0.0.17` produces nightlies on `0.0.18-nightly.*`. Nightly publishes Electron auto-update metadata to a dedicated `nightly` updater channel and the CLI to the `nightly` npm dist-tag, and does not commit version bumps back to `main`. **Server self-update release invariant.** Connected servers update to the client's exact version, not to an npm dist-tag — every released desktop or hosted client version must have a matching `t3@` package on npm before users can receive that client. The workflow enforces ordering: `publish_cli` publishes the exact version to npm first, `release` depends on it before exposing desktop artifacts, and `deploy_web` depends on `release` before moving the hosted channel. Publishing a client before its CLI package would leave the "Update server" action targeting a nonexistent npm version. **Release validation caveat.** There is no dry-run tag path — pushing any accepted non-nightly tag, including `v0.0.0-test.1`, is classified as a real stable-channel release: it publishes `t3` to npm `latest`, creates a real GitHub Release, aliases the hosted app, and can commit a version bump to `main`. The workflow has no non-publishing `workflow_dispatch` mode; validate checks and builds with normal CI or local quality gates instead. Manual `channel=nightly` dispatch still publishes a real nightly npm package, GitHub prerelease, desktop updater release, and hosted nightly alias — it just skips stable aliases and the `main` version bump. Manual `channel=stable` with a version input is also a real stable-channel release. **Signing setup.** macOS: `CSC_LINK`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY`, `APPLE_API_KEY_ID`, `APPLE_API_ISSUER`, `MACOS_PROVISIONING_PROFILE`, plus repository variable `APPLE_TEAM_ID` — checklist covers creating an App ID with Associated Domains, a Developer ID Application certificate, exporting/base64-encoding the `.p12` and provisioning profile, and an App Store Connect API key. Windows: Azure Trusted Signing via `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TRUSTED_SIGNING_ENDPOINT`, `AZURE_TRUSTED_SIGNING_ACCOUNT_NAME`, `AZURE_TRUSTED_SIGNING_CERTIFICATE_PROFILE_NAME`, `AZURE_TRUSTED_SIGNING_PUBLISHER_NAME`. **Ongoing release checklist**: ensure `main` is green in CI → bump app version as needed → create tag `vX.Y.Z` → push tag → verify preflight, all matrix builds, `publish_cli` running before the release job, and the release job uploading expected files → smoke test downloaded artifacts. ### Scripts and dev workflow T3 Code uses [Vite+](https://viteplus.dev/guide/) (`vp`). First checkout: `curl -fsSL https://vite.plus | bash` (Windows: `irm https://vite.plus/ps1 | iex`), then `vp i`, then `vp run dev`. Node 24 is required; Bun is not — the server picks Bun adapters when it detects Bun and falls back to Node otherwise. `vp run dev` prints a one-time pairing URL that must be opened for the first authenticated browser navigation. Dev tasks: `vp run dev` (contracts + server + web in watch mode; add `--share` to publish over the tailnet, `--browser` to auto-open a browser — off by default, and setting `T3CODE_NO_BROWSER=0` has no effect since the dev runner writes that var itself from the flag), `vp run dev:server` (server only, Node `--watch src/bin.ts`), `vp run dev:web` (Vite dev server only), `vp run dev:desktop` (Electron shell against the dev server), `vp run dev:marketing` (Astro site). Dev-runner flags pass directly after the root task name, e.g. `vp run dev --home-dir /tmp/t3code-dev`. A linked git worktree defaults to its own gitignored `.t3` (state at `/.t3/userdata`), which deliberately outranks an ambient `T3CODE_HOME`; the main checkout implicitly uses `~/.t3/dev`. Build/check/test: `vp run build` (fans out over `apps/*`, `packages/*`, `oxlint-plugin-t3code`, and `scripts`), `vp run build:desktop` (desktop + server pipeline), `vp run start` (production server serving the built web app statically), `vp check` (format/lint/type checks, with `typeCheck: false` so workspace typechecking runs separately), `vp run typecheck` (strict TS checks), `vp run test` (workspace tests), `vp run lint:mobile` (mobile native static analysis), and `node apps/server/scripts/t3-sqlite-state.ts --base-dir ...` to inspect or seed an isolated T3 SQLite database (writes create a private backup first). Desktop artifacts: `vp run dist:desktop:artifact --platform --target --arch `, `vp run dist:desktop:dmg` (macOS `.dmg` into `./release`, arch defaults to host; `:arm64`/`:x64` variants or `--arch`), `vp run dist:desktop:linux` (AppImage), `vp run dist:desktop:win` (NSIS installer, `:arm64`/`:x64` variants). The default `.dmg` build is unsigned/not notarized for local sharing; desktop production windows load the bundled UI from `t3code://app/` (not a `127.0.0.1` document URL); `--keep-stage` retains staging files for debugging package contents; `--signed` enables code-signing when secrets are configured. Browser dev leaves `VITE_HTTP_URL`/`VITE_WS_URL` unset so the browser resolves the backend from `window.location.origin`; Vite proxies `/api`, `/ws`, `/oauth`, and `/.well-known` to the server, letting the same bundle work from localhost or a tailnet hostname. Running multiple dev instances: worktrees derive a preferred port offset from their path (default ports server `13773`, web `5733`, shifted `base + offset`; `T3CODE_DEV_INSTANCE=branch-a vp run dev:desktop`). Offset resolution order: `T3CODE_PORT_OFFSET` (non-negative integer, negative rejected) → `T3CODE_DEV_INSTANCE` (all-digit used directly, otherwise hashed) → worktree path hash. `dev:web` scans only the web port, `dev:server` scans only the server port, `dev`/`dev:desktop` scan and shift both together; treat the `[dev-runner]` output as authoritative since occupied ports shift. ## Key Parameters - CI jobs: Check, Test, Mobile Native Static Analysis, Release Smoke. - Release artifact matrix: macOS arm64/x64 DMG, Linux x64 AppImage, Windows x64 NSIS. - Publish ordering invariant: `publish_cli` → `release` → `deploy_web`. - Nightly tag format: `vX.Y.Z-nightly.YYYYMMDD.`, based on the next stable patch. - Signing secrets: macOS (`CSC_LINK`, `CSC_KEY_PASSWORD`, `APPLE_API_KEY*`, `MACOS_PROVISIONING_PROFILE`, `APPLE_TEAM_ID`), Windows (`AZURE_*` Trusted Signing set). - Dev ports: server `13773`, web `5733`, shifted by worktree-derived offset. - Node 24 required; Bun optional (auto-detected). ## When To Use Reach for this page when setting up release signing credentials for the first time, diagnosing a failed CI job, cutting a stable or nightly release, understanding why a desktop client's self-update didn't work, or looking up the right `vp run` command for a dev/build/test/release task. ## Risks & Pitfalls - There is no dry-run release tag — pushing any accepted non-nightly tag (even a "test" one like `v0.0.0-test.1`) triggers a real stable-channel release with real npm and GitHub Release publication. - Omitting signing secrets does not block publication; it only produces unsigned artifacts. - Breaking the `publish_cli` → `release` → `deploy_web` dependency ordering would let "Update server" target a client version whose matching `t3@` npm package doesn't exist yet. - Setting `T3CODE_NO_BROWSER=0` has no effect on `vp run dev` — the dev runner controls that variable itself from the `--browser` flag. - A worktree's local `.t3` state deliberately outranks an ambient `T3CODE_HOME`, so passing a shared home into a worktree dev server is a common footgun the design intentionally guards against. - Manual `workflow_dispatch` with `channel=nightly` is a real nightly release (real npm package, real prerelease) — only run it when that's acceptable. ## Related Concepts - [[concepts/architecture]] — the workspace layout (`apps/`, `packages/`, `infra/relay`) these scripts and pipelines build and ship. - [[concepts/t3-connect]] — the shared relay this release process deploys and depends on. - [[concepts/testing-and-agent-skills]] — the local dev-server workflows agents use alongside `vp run dev` when verifying changes before a PR. - [[summaries/release-digest]] — sibling page tracking individual nightly release notes. - [[concepts/t3code-overview]] — sibling page on the overall product this pipeline ships. ## Sources - raw/github_doc-docs-internals-ci-md.md - raw/github_doc-docs-operations-release-md.md - raw/github_doc-docs-internals-scripts-md.md --- title: "Environment Authentication" type: concept tags: [architecture, developer, operator, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-environment-auth-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Environment Authentication ## Definition Environment authentication is T3 Code's capability-based, OAuth-shaped auth profile for a single environment (one running T3 server plus the machine, filesystem, provider credentials, and state it owns). The environment server and the relay use separate credentials, issuers, and trust boundaries; they intentionally share an OAuth-shaped model so permission checks and token exchange behavior can be audited against established concepts, but an environment access token is never valid at the relay and vice versa. ## How It Works **Authorization model.** A session carries zero or more OAuth-style scope strings: | Scope | Permission | | --- | --- | | `orchestration:read` | Read snapshots, status, events, configuration, and filesystem/VCS state. | | `orchestration:operate` | Dispatch user operations and mutate environment-side workspace state. | | `terminal:operate` | Create, attach, input, resize, clear, restart, and terminate terminals. | | `review:write` | Read review diff previews used to compose review feedback. | | `access:read` | Inspect pairing links and client sessions. | | `access:write` | Create or revoke pairing links and client sessions. | | `relay:read` | Inspect managed relay connectivity. | | `relay:write` | Link, configure, or unlink managed relay connectivity. | Ordinary pairing links grant the four client-operation scopes plus relay read: `orchestration:read orchestration:operate terminal:operate review:write relay:read`. The desktop bootstrap credential and command-line administrative bootstrap credentials additionally grant `access:read access:write relay:write`. **Authentication flows.** - *Browser session*: `POST /api/auth/browser-session` consumes a one-time bootstrap credential and creates a browser session cookie — an HTTP transport adapter over the same scoped session model. The response never exposes the session secret to browser JavaScript. - *Bearer access token*: non-browser clients call `POST /oauth/token` with an `application/x-www-form-urlencoded` body using the OAuth 2.0 Token Exchange (RFC 8693) shape: ```text grant_type=urn:ietf:params:oauth:grant-type:token-exchange subject_token= subject_token_type=urn:t3:params:oauth:token-type:environment-bootstrap requested_token_type=urn:ietf:params:oauth:token-type:access_token scope=orchestration:read orchestration:operate terminal:operate review:write relay:read ``` Clients may additionally submit `client_label`, `client_device_type`, and `client_os` extension parameters so the authorized-clients UI can identify the device; these are presentation hints only — the environment derives IP address and user agent from the request itself, not from these fields. The response has the token-exchange shape: ```json { "access_token": "", "issued_token_type": "urn:ietf:params:oauth:token-type:access_token", "token_type": "Bearer", "expires_in": 2592000, "scope": "orchestration:read orchestration:operate terminal:operate review:write relay:read" } ``` Plain bearer exchanges use the store's `DEFAULT_SESSION_TTL` of 30 days. Requested scopes must be a subset of the one-time bootstrap credential's grant — an ordinary paired client cannot exchange its grant for `access:read`, `access:write`, or `relay:write`. - *DPoP-bound access token*: the same `/oauth/token` exchange supports proof-of-possession tokens. A client that sends a `DPoP` header has its proof verified by `verifyRequestDpopProof`; the resulting JWK thumbprint is stored on the session, issued with method `dpop-access-token` and a one-hour TTL (`expires_in: 3600`) instead of the bearer default. An invalid proof gets a DPoP challenge header and a credential error rather than a bearer token. `dpop-access-token` is advertised alongside `browser-session-cookie` and `bearer-access-token` in the descriptor's `sessionMethods` (`EnvironmentAuthPolicy.ts`). Relay-brokered clients use this mode so a leaked token cannot be replayed without the corresponding key. - *WebSocket ticket*: `POST /api/auth/websocket-ticket` accepts any authenticated session and returns a short-lived, single-purpose ticket via `EnvironmentAuth.issueWebSocketTicket`, five-minute default TTL. The client presents its bearer or DPoP credential in headers to get the ticket, then appends only that ticket to the socket URL as `wsTicket` — keeping long-lived tokens and browser cookies out of WebSocket URLs while letting the handshake authenticate. The ticket carries its session's scopes; each RPC method enforces `orchestration:read`, `orchestration:operate`, `terminal:operate`, `review:write`, `relay:write`, or `access:read` as appropriate via `RPC_REQUIRED_SCOPES` in `apps/server/src/auth/RpcAuthorization.ts`. Review feedback submission dispatches an orchestration operation, so clients performing it also need `orchestration:operate`. Creating a ticket is not authorization to call every RPC method. **Standards alignment.** Bearer tokens use the `Authorization: Bearer` scheme from RFC 6750. The token endpoint profiles OAuth 2.0 Token Exchange (RFC 8693) vocabulary (`subject_token`, `requested_token_type`, `access_token`, `issued_token_type`, `token_type`). Scope values follow the OAuth 2.0 scope model from RFC 6749: space-delimited, unordered, subset-checked during exchange. This is intentionally not a general-purpose OAuth authorization server — the bootstrap token type is private, the bootstrap cookie and WebSocket connection-token routes are product-specific adapters, and the API returns typed `HttpApi` errors rather than a full OAuth error surface. **Upgrade behavior.** Migration `031_AuthAuthorizationScopes` was a hard cutover from role-bearing auth records to scoped records: it deletes existing pairing links and sessions while leaving non-authentication environment state unchanged. Upgraded clients must pair again; old `owner`/`client` credentials are never silently mapped to new capabilities. **Relay boundary.** Relay-managed tunnels use their own tokens and keys. The relay can reuse scope-parsing and token-exchange conventions, but an environment access token is not a relay token and cannot be presented to the relay. ## Key Parameters - 8 scopes: `orchestration:read`, `orchestration:operate`, `terminal:operate`, `review:write`, `access:read`, `access:write`, `relay:read`, `relay:write`. - `DEFAULT_SESSION_TTL`: 30 days (bearer); DPoP-bound TTL: 1 hour (`expires_in: 3600`); WebSocket ticket TTL: 5 minutes. - `SessionStore.ts`, `EnvironmentAuth.ts`, `EnvironmentAuthPolicy.ts`, `RpcAuthorization.ts` — the implementing services. - Migration `031_AuthAuthorizationScopes` — the hard cutover point for the scope model. ## When To Use Reference this page when adding a new RPC method (map it to the correct scope), building a non-browser client integration (bearer or DPoP exchange), diagnosing "authorized but rejected" RPC errors, or reasoning about what a leaked pairing link versus a leaked desktop bootstrap credential can actually do. ## Risks & Pitfalls - Assuming a valid WebSocket ticket or session authorizes every RPC method — each method enforces its own required scope independently. - Requesting scopes beyond what the bootstrap credential grants — the exchange rejects anything not a subset of the original grant. - Presenting an environment access token to the relay, or a relay token to an environment — they are separate trust boundaries by design and are never interchangeable. - Treating the desktop bootstrap credential the same as an ordinary pairing link — it additionally grants `access:read`, `access:write`, and `relay:write`, so leaking it is materially more dangerous. - Assuming old `owner`/`client` credentials survived migration `031_AuthAuthorizationScopes` — they did not; clients must re-pair. ## Related Concepts - [[concepts/architecture]] — the RPC boundary that enforces `RPC_REQUIRED_SCOPE` on top of this auth model. - [[concepts/observability]] and [[concepts/resource-telemetry]] — diagnostics surfaces that inherit these same authorization boundaries. - [[concepts/glossary]] — "environment" and other terms used throughout this page. - [[concepts/remote-access]], [[concepts/t3-connect]] — sibling pages on relay-brokered connectivity that sits behind the boundary described here. ## Sources - raw/github_doc-docs-internals-environment-auth-md.md --- title: "Glossary" type: concept tags: [architecture, developer, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-glossary-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Glossary ## Definition The glossary is T3 Code's living reference for terminology used across the codebase and its documentation. It exists so maintainers and contributing agents share the same meaning for terms like "thread," "turn," "checkpoint," and "receipt," each grounded in a specific contract or implementation file. New vocabulary is expected to be added here as it enters the codebase. ## How It Works The glossary is organized into five groups. **Project and workspace** - **Project**: the top-level workspace record in the app. It has a `workspaceRoot` and a title in the orchestration contracts; it does not itself contain threads — `OrchestrationProject` and `OrchestrationThread` are separate arrays on the read model, and a project can have zero threads. - **Workspace root**: the root filesystem path for a project — the base directory for branches and optional worktrees. - **Worktree**: a Git worktree used as an isolated workspace for a thread. If a thread has a `worktreePath`, it runs there instead of in the main working tree. Git operations live behind the VCS driver contract (`apps/server/src/vcs/VcsDriver.ts`), implemented by `GitVcsDriverCore.ts`. **Thread timeline** - **Thread**: the main durable unit of conversation and workspace history. A thread holds messages, activities, checkpoints, and session-related state. - **Turn**: a single user-to-assistant work cycle inside a thread. It starts with user input and ends when the session leaves `running` status — `projector.ts`'s `settledTurnStateForSessionStatus` is the authoritative completion signal. Checkpoint and diff work may settle afterward without changing when the turn ended. - **Activity**: a user-visible log item attached to a thread, covering important non-message events like approvals, tool actions, and failures. **Orchestration** Orchestration is the server-side domain layer that turns runtime activity into stable app state. Main entry point: `OrchestrationEngine.ts`; core logic in `decider.ts` and `projector.ts`. - **Aggregate**: the domain object a command or event belongs to — usually `project` or `thread`. - **Command**: a typed request to change domain state, validated in `commandInvariants.ts` and turned into events by `decider.ts`. Examples: `thread.create`, `thread.turn.start`, `thread.checkpoint.revert`. - **Domain Event**: a persisted fact that something already happened — the source of truth. Examples: `thread.created`, `thread.message-sent`, `thread.turn-diff-completed`. - **Decider**: the pure orchestration logic that turns commands plus current state into events (`decider.ts`, with preconditions in `commandInvariants.ts`). - **Projection**: a read-optimized view derived from events (`projector.ts`, `ProjectionPipeline.ts`, `ProjectionSnapshotQuery.ts`). - **Projector**: the logic that applies domain events to the read model or projection tables. - **Read model**: the current materialized view of orchestration state — projects, threads, messages, activities, checkpoints, and session state. - **Reactor**: a side-effecting service that handles follow-up work after events or runtime signals. Examples: `CheckpointReactor.ts`, `ProviderCommandReactor.ts`, `ProviderRuntimeIngestion.ts`. - **Receipt**: a typed signal emitted when an async milestone completes, such as `checkpoint.baseline.captured`, `checkpoint.diff.finalized`, or `turn.processing.quiesced`. Receipts are a test-only mechanism — the production `RuntimeReceiptBusLive` publish is a no-op, and only the test layer is PubSub-backed. Do not build production behavior on them. - **Quiesced**: means a turn has gone quiet and stable — follow-up work such as `CheckpointReactor` has settled. In practice, it is something tests wait on rather than a production signal. **Provider runtime** The live backend agent implementation and its event stream. Main service: `ProviderService.ts`; adapter contract: `ProviderAdapter.ts`. - **Provider**: the backend agent runtime that actually performs work. Five drivers ship built in: Codex, Claude, Cursor, Grok, and OpenCode. - **Session**: the live provider-backed runtime attached to a thread. - **Runtime mode**: the safety/access mode for a thread or session. Four values: `approval-required`, `auto-accept-edits`, `auto`, `full-access`. See [[concepts/permission-modes]]. - **Interaction mode**: the agent interaction style for a thread. Values: `default` and `plan`. - **Assistant delivery mode**: controls how assistant text reaches the thread timeline. `streaming` updates incrementally; `buffered` accumulates text. Buffered delivery is not held until the turn completes — it spills once accumulated text would exceed 24,000 characters, and flushes at approval and user-input boundaries. - **Snapshot**: a point-in-time view of state. The word is used across orchestration, provider, and checkpointing layers. **Checkpointing** Checkpointing captures workspace state over time so the app can diff turns and restore earlier points. Main pieces: `CheckpointStore.ts`, `CheckpointDiffQuery.ts`, `CheckpointReactor.ts`. - **Checkpoint**: a saved snapshot of a thread workspace at a particular turn — in practice a hidden Git ref (`CheckpointStore.ts`) plus a projected summary (`ProjectionCheckpoints.ts`). Capture and lifecycle work happen in `CheckpointReactor.ts`. - **Checkpoint ref**: the durable identifier for a filesystem checkpoint, stored as a Git ref, constructed in `Utils.ts`. - **Checkpoint baseline**: the starting checkpoint for diffing a thread timeline, surfaced through `RuntimeReceiptBus.ts` and coordinated in `CheckpointReactor.ts`. - **Checkpoint diff**: the patch difference between two checkpoints — query logic in `CheckpointDiffQuery.ts`, diff parsing in `Diffs.ts`, finalization coordinated by `CheckpointReactor.ts`. - **Turn diff**: the file patch and changed-file summary for one turn, usually computed in `CheckpointDiffQuery.ts` and recorded into thread state by `projector.ts`. **Practical shortcuts.** If you see `requested`, think "intent recorded." If you see `completed`, think "result applied." If you see `receipt`, think "async milestone signal, for tests." If you see `checkpoint`, think "workspace snapshot for diff/restore." If you see `quiesced`, think "all relevant follow-up work has gone idle." ## Key Parameters - Five source categories: project/workspace, thread timeline, orchestration, provider runtime, checkpointing. - Four runtime modes: `approval-required`, `auto-accept-edits`, `auto`, `full-access`. - Two interaction modes: `default`, `plan`. - Two assistant delivery modes: `streaming`, `buffered` (24,000-character spill threshold for buffered). - Five built-in providers: Codex, Claude, Cursor, Grok, OpenCode. ## When To Use Consult this page whenever a term in the docs or codebase is ambiguous — especially "receipt" versus "quiesced" (both easy to mistake for production signals), or "checkpoint" versus "checkpoint baseline" versus "checkpoint diff." Also use it before introducing new vocabulary, so new terms land here rather than proliferating undocumented. ## Risks & Pitfalls - Treating a **receipt** as a production signal — it is test-only; production publish is a no-op. - Treating **quiesced** as something the app broadcasts in production — in practice it's a test-wait condition, not a live signal. - Assuming buffered assistant delivery waits for turn completion — it spills at a 24,000-character threshold and at approval/user-input boundaries. - Confusing **project** with **thread** — a project can have zero threads, and they are separate arrays on the read model, not a containment relationship. ## Related Concepts - [[concepts/architecture]] — the orchestration engine, decider, and projector this glossary's core terms describe. - [[concepts/permission-modes]] — sibling page detailing the four runtime modes referenced here. - [[concepts/providers]] — sibling page on the five provider drivers referenced here. - [[concepts/terminal-renderers]], [[concepts/environment-auth]], [[concepts/observability]], [[concepts/resource-telemetry]], [[concepts/ci-and-release]], [[concepts/testing-and-agent-skills]] — other internals pages that use this vocabulary. ## Sources - raw/github_doc-docs-internals-glossary-md.md --- title: "Install and Getting Started" type: concept tags: [install, overview, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition Getting started with T3 Code means putting a T3 Code server on the machine that will run your coding agents, then making sure at least one provider CLI is installed and authenticated so the server has something to control. There are two install paths — an install-free CLI trial and a desktop app — and both depend on the same Node.js requirement and the same provider-authentication step. ## How It Works ### Run without installing ```bash npx t3@latest ``` This starts the T3 Code server on your machine and opens the local web app. Node.js `^22.16 || ^23.11 || >=24.10` is required on the machine running the server. Use `npx t3@latest --help` for the full CLI reference. ### Desktop app Download the latest release from [GitHub Releases](https://github.com/pingdotgg/t3code/releases), or install via a package registry: Windows (`winget`): ```bash winget install T3Tools.T3Code ``` macOS (Homebrew): ```bash brew install --cask t3-code ``` Arch Linux (AUR): ```bash yay -S t3code-bin ``` ### Install and authenticate a provider T3 Code drives provider CLIs; it does not ship them. Install the CLI for each provider you want to use and authenticate it **on the machine running the T3 Code server**, not on the device you browse from: | Provider | CLI | Default binary | Log in with | | ---------- | ------------------------------------------------------ | -------------- | ----------------------- | | Codex | [Codex CLI](https://developers.openai.com/codex/cli) | `codex` | `codex login` | | Claude | [Claude Code](https://claude.com/product/claude-code) | `claude` | `claude auth login` | | Cursor | [Cursor CLI](https://cursor.com/cli) | `cursor-agent` | `agent login` | | Grok Build | [Grok Build CLI](https://x.ai/cli) | `grok` | `grok login` | | OpenCode | [OpenCode](https://opencode.ai) | `opencode` | `opencode auth login` | Note that Cursor is the one to watch: you install the Cursor CLI (which provides the `cursor-agent` binary T3 Code looks for), but you authenticate with `agent login`, not `cursor-agent login`. Each provider CLI must be on the server's `PATH`, or have an explicit binary path set in **Settings** → the provider instance → **Binary path**. Use the explicit path when a version manager or non-standard install location keeps the CLI off the `PATH` of the shell that started T3 Code. Provider auth is required before you start a session with that provider, not before you start T3 Code itself — you can install T3 Code, open it, and add providers afterwards. A provider that is not authenticated shows its status in **Settings** and fails at session start with the login command to run. See [[concepts/providers]] for the full provider system and per-provider setup, including multi-account configurations. ## Key Parameters - **Node.js requirement**: `^22.16 || ^23.11 || >=24.10` on the machine running the server (same requirement applies for SSH-launched remote servers; see [[concepts/remote-access]]). - **Try-it-out command**: `npx t3@latest` (install-free). - **Desktop installers**: GitHub Releases, `winget` (Windows), Homebrew cask (macOS), AUR (`t3code-bin`, Arch Linux). - **Minimum viable setup**: at least one authenticated provider CLI. ## When To Use Use the install-free `npx t3@latest` path to quickly try T3 Code or to run a headless/CLI server (including on a remote machine reached over SSH). Use the desktop app when you want a persistent, native GUI installation that can also serve as a host for remote clients (mobile, `app.t3.codes`). ## Risks & Pitfalls - Skipping provider authentication is a common early stumbling block: T3 Code will install and open fine, but any session start fails until the relevant provider's login command has been run on the server machine. - Authenticating a provider CLI on the wrong machine (your local browsing device instead of the server host) does not satisfy the requirement — auth must happen where the T3 Code server runs. - An unmet Node.js version range on the server machine will prevent the server from running at all (also relevant for SSH-launched remote servers). - A version manager that only initializes in an interactive shell can hide a correctly installed provider CLI or Node.js binary from the non-interactive shell T3 Code uses to launch things, producing "not found" errors even though the tool is installed. ## Related Concepts - [[concepts/t3code-overview]] - [[concepts/providers]] - [[concepts/permission-modes]] - [[concepts/remote-access]] - [[concepts/background-service]] ## Sources - raw/github_doc-readme-md.md - raw/github_doc-docs-user-install-md.md --- title: "Keybindings and Updating" type: concept tags: [operations, install, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-user-keybindings-md.md", "raw/github_doc-docs-user-updating-md.md", "raw/github_doc-docs-internals-server-updates-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition This page covers two related pieces of day-to-day T3 Code operation: how keyboard shortcuts (keybindings) are configured, and how the client and server stay in — or fall out of — version sync, plus the update mechanism that resolves that skew. ## How It Works ### Keybindings Keybindings are edited from **Settings** → **Keybindings**, which lists every command, its current shortcut, whether it's a default or user-defined, and flags conflicts. The same configuration lives in `~/.t3/userdata/keybindings.json` on the server machine for direct editing. T3 Code writes built-in defaults into that file on first run and adds new defaults on later startups, unless a user rule already claims the command or the shortcut. The file is a JSON array of rules: ```json [ { "key": "mod+g", "command": "terminal.toggle" }, { "key": "mod+shift+g", "command": "terminal.new", "when": "terminalFocus" } ] ``` Invalid rules are ignored; an entirely invalid file is ignored, and the server logs a warning. Rule shape: - `key` (required) — a shortcut string, e.g. `mod+j`, `ctrl+k`, `cmd+shift+d`. - `command` (required) — the command ID to run. - `when` (optional) — a boolean expression controlling when the shortcut is active. Modifiers: `mod` (`cmd` on macOS, `ctrl` elsewhere), `cmd`/`meta`, `ctrl`/`control`, `shift`, `alt`/`option`. Commands are IDs like `terminal.toggle`, `commandPalette.toggle`, `preview.refresh`, and `chat.new`; project scripts are addressable as `script.{id}.run` (e.g. `script.test.run`). `filePicker.toggle` (default `mod+p`) opens file search for the active project; `projectSearch.toggle` (default `mod+shift+f`) searches inside the active project's files — repeating either closes that search, and switching between them replaces the open search. The command palette itself searches active thread titles, projects, branches, user messages, and final agent responses across connected environments; message search begins after two characters and uses SQLite's ASCII case-insensitive matching. `chat.new` and `chat.newLocal` both create a thread through the same path and inherit the current project, model, and mode selections — branch, worktree, and environment mode instead come from configured defaults, not the thread being viewed (use the explicit "new thread in this worktree" action to keep a worktree). The only functional difference: with more than one project in the sidebar, `chat.new` opens a project chooser first. `when` conditions evaluate against context keys describing current UI state — currently `terminalFocus`, `terminalOpen`, `previewFocus`, `previewOpen`, and `modelPickerOpen` (an open, growing set; any key the running app doesn't supply evaluates to `false`). Operators: `!`, `&&`, `||`, and parentheses, e.g. `"terminalOpen && !terminalFocus"`. Precedence: rules are evaluated in array order; for a given key event, the **last** rule where both `key` matches and `when` evaluates true wins — across all commands, not just within the same command, so a later rule for a different command can take a key away from an earlier one. ### Updating — the user-facing flow T3 Code works best when the client (web/desktop app) and the server it connects to run the same version. A mismatch surfaces a warning above the message box in the current conversation, and beside the affected connection in **Settings** → **Connections**. Dismissing the conversation warning only hides that reminder for those two versions; it does not update the server. Before updating: let active agent work and terminal commands finish, since updating restarts the server (the connection disappears briefly and running work may be interrupted). The update does not remove saved threads, settings, or project files. The action shown depends on how the server was started: | Action | What to do | | --------------------------- | --------------------------------------------------------------------------------------------------------------------- | | **Update server** | Available for the T3 Code Linux background service ([[concepts/background-service]]). Click the button and leave T3 Code open while it downloads, installs, and reconnects. | | **Update the desktop app** | Open the desktop app on the server machine and install the app update there; reopen if needed. | | **Copy update command** | Copy `npx t3@`, open a terminal on the server machine, stop the current server, and relaunch it with that command plus any usual startup options. | An older background-service launcher may instead ask for one local `npx t3@ service update` run on the server, which installs the rollback support needed for later remote updates (including ones with database migrations). After selecting **Update server**, the warning becomes a three-step progress rail — **Download**, **Install**, **Resume** — visible in both the conversation and Connections; a failed step stays visible with its error and a retry option. `service update` installs the version of the CLI that invoked it, so `npx t3@latest service update` only resolves skew when the client is already on latest; using the exact version named in the warning always works. The update completes only after the service launcher reports the exact update committed and the replacement server is ready; a rollback is reported immediately rather than waiting for a generic reconnect timeout. ### Updating — the internal protocol Remote server updates run through one stable systemd launcher; foreground CLI processes never self-update, and a running server never edits its own systemd unit or durable service state. Under `/runtime`: `service-launcher.mjs` (the stable process systemd selects), `service-state.json` (the launcher's durable selection state, written only by the launcher itself, or replaced by `t3 service install`/`update` while the unit is stopped), and `versions/` (immutable exact-version npm installs). State holds one active version and at most one update record: `pending A → B` (retryable trial), `committed A → B` (selected for ordinary restarts), or `rolled-back A → B`/`failed A → B` (reverted to A); invalid state fails closed. Every write uses same-directory replacement plus file/directory fsync. The remote update sequence: the active server installs `t3@` into a unique staging directory; the target runs `__service-preflight` and checks the launcher supports its update protocol; the staging directory is renamed to its immutable version path only after preflight succeeds; the active child sends `request-update`, the launcher validates it, writes pending state, generates an update ID, and replies `update-accepted`; after a short grace period the launcher stops the active child; with SQLite quiescent, the launcher snapshots the database, WAL, and shared-memory files; the launcher starts the target as a trial and hands it the pending update over IPC; the trial runs migrations, acquires dependencies, binds HTTP, starts every long-running root fiber, and parks each root at an activation gate; the trial sends `prepared`, the launcher durably commits B and deletes the snapshot, then replies `committed`; the child opens the activation gate, accepts commands, and publishes lifecycle-ready with the terminal update outcome. A trial must report `prepared` within 120 seconds or the launcher stops it, restores the database snapshot, records rollback, and starts A again — a durable restore marker makes an interrupted restore resume regardless of which version was about to boot. On the client side, the update acknowledgement carries the launcher-generated update ID; after reconnecting, clients wait for a lifecycle-ready event carrying that same ID, and `committed` only completes the operation when the ready server is actually the target version (`rolled-back`/ `failed` end it immediately with the recorded reason). Older servers without an ID fall back to version-only reconnect behavior. New servers advertise remote self-update only when they have valid launcher context and a live IPC channel; desktop-managed servers instead direct the user to update the desktop app, and other process shapes provide a manual command (the old detached foreground respawn path no longer exists). ## Key Parameters - **Keybindings config file**: `~/.t3/userdata/keybindings.json` (JSON array of `{key, command, when?}` rules). - **`when` context keys (current, open set)**: `terminalFocus`, `terminalOpen`, `previewFocus`, `previewOpen`, `modelPickerOpen`. - **Default shortcuts noted**: `filePicker.toggle` → `mod+p`; `projectSearch.toggle` → `mod+shift+f`. - **Update warning locations**: above the message box in a conversation; Settings → Connections. - **Trial preparation timeout**: 120 seconds (`prepared` must be reported within this window). - **Update state values**: `pending A → B`, `committed A → B`, `rolled-back A → B`, `failed A → B`. ## When To Use Consult the keybindings section when customizing shortcuts or diagnosing a shortcut conflict (check rule order — last matching rule wins across all commands). Consult the updating section whenever a version-skew warning appears, before performing any server update, or when diagnosing a failed or rolled-back remote update. ## Risks & Pitfalls - An entirely invalid `keybindings.json` file is silently ignored (only a server warning is logged), which can look like "my custom bindings just disappeared." - Rule precedence is global, not per-command — a later rule for an unrelated command can steal a key from an earlier rule for a different command. - `npx t3@latest service update` only resolves version skew if the client happens to already be on the latest release; otherwise it can still leave (or even reintroduce) a mismatch — the exact version named in the warning should be used instead. - Starting an update while agent work or terminal commands are still running risks interrupting that work, since the server restarts as part of the update. - Retrying a local update while a remote update is already in progress is explicitly discouraged. - A trial that fails to report `prepared` within 120 seconds triggers an automatic rollback — a slow-starting migration or dependency acquisition can look like a failure when it may just need more headroom. ## Related Concepts - [[concepts/background-service]] - [[concepts/remote-access]] - [[concepts/t3-connect]] - [[concepts/permission-modes]] ## Sources - raw/github_doc-docs-user-keybindings-md.md - raw/github_doc-docs-user-updating-md.md - raw/github_doc-docs-internals-server-updates-md.md --- title: "Observability" type: concept tags: [observability, operations, developer, operator, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-operations-observability-md.md", "raw/github_doc-docs-operations-relay-observability-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Observability ## Definition Observability, in this context, is how T3 Code's maintainers watch *T3 itself* — its server and its relay — rather than a user-facing product feature. It covers pretty human-facing logs, a locally persisted NDJSON trace file, in-process metrics, optional OTLP export to a real backend (e.g. Grafana LGTM), and, for the relay, a shared Axiom-based OpenTelemetry trace pipeline. ## How It Works ### Server-side (app observability) T3 Code has one server-side observability model: pretty logs go to stdout for humans; completed spans are written as NDJSON records to a local trace file, which is the persisted source of truth for normal local launches; traces and metrics can additionally be exported over OTLP to a real backend. Normal local launches do not write a separate server log file, but SSH-managed launches also persist the remote process's stdout/stderr at `~/.t3/ssh-launch//server.log`. - **Logs**: destination stdout, format `Logger.consolePretty()`, no normal local persistence. A log message only shows up in the trace file if it's emitted inside an active span with `Effect.log...` — `Logger.tracerLogger` attaches it as a span event. - **Traces**: the trace file path (`serverTracePath`) depends on how the server starts — production/explicit homes use `/userdata/logs/server.trace.ndjson`, a linked-worktree dev run uses `/.t3/userdata/logs/server.trace.ndjson`, and an implicit dev run outside a linked worktree uses `~/.t3/dev/logs/server.trace.ndjson`. Common fields: `type` (`effect-span` or `otlp-span`), `name`, `traceId`/`spanId`/`parentSpanId`, `durationMs`, `attributes`, `events`. `effect-span` records also carry `exit` (`Success`/`Failure`/`Interrupted`); `otlp-span` records carry OTLP resource/scope/status fields instead. Schemas live in `packages/shared/src/observability.ts`. - **Metrics**: not written to a local file at all — local persistence is none, remote export is OTLP-only when configured, current definitions live in `apps/server/src/observability/Metrics.ts`. Without OTLP configured, metrics still exist in-process but leave no local artifact. - **Related artifacts**: provider event NDJSON files for provider runtime streams still exist, separate from the main server trace file. **Running instrumented.** Two modes: local-only (stdout + local trace file, always on, no env vars needed — just run `npx t3`, `node --run dev`, or `node --run dev:desktop`) or full local observability (adds OTLP export to a Grafana LGTM stack started with `docker run --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 --rm -ti grafana/otel-lgtm`, default login `admin`/`admin`). OTLP env vars (`T3CODE_OTLP_TRACES_URL`, `T3CODE_OTLP_METRICS_URL`, `T3CODE_OTLP_SERVICE_NAME`, plus optional `T3CODE_TRACE_MIN_LEVEL` and `T3CODE_TRACE_TIMING_ENABLED`) must be exported in the same shell that launches the app — packaged desktop apps must be launched from that shell (Finder/Spotlight/dock/Start-menu launches will not inherit them), and the backend must be fully restarted after any env change because observability config is read at process start. **Debugging workflows.** The local trace file is the fastest way to inspect raw span data: `tail -f "$TRACE_FILE"`, then `jq` recipes to show failed spans (`exit._tag != "Success"`), slow spans (`durationMs > 1000`), embedded log events, follow one `traceId`, filter orchestration commands (`attributes["orchestration.command_type"]`), or filter git activity (`attributes["git.operation"]`, `git.hook.started`/`git.hook.finished` events). Tempo (via Grafana Explore) is better than raw NDJSON for searching across many traces, visualizing parent/child relationships, and drilling into one failing request. Metrics answer "is this systemic?" questions using families like `t3_rpc_request_duration`, `t3_orchestration_command_duration`, `t3_orchestration_command_ack_duration`, `t3_provider_turn_duration`, `t3_git_command_duration`, plus counters `t3_rpc_requests_total`, `t3_orchestration_commands_total`, `t3_provider_turns_total`, `t3_git_commands_total`. `t3_orchestration_command_ack_duration` specifically measures server-side acknowledgment latency: from command dispatch entering the orchestration engine to the first committed domain event being published — it does not measure WebSocket transit, client receipt, or React render time. **Adding tracing to new code.** Prefer boundaries over tiny helpers (RPC methods, orchestration command handling, provider adapter calls, external process calls, persistence writes, queue handoffs) — most helpers should inherit the active span. Reuse `Effect.fn("name")`, which the codebase already uses heavily, as the first tracing boundary; for ad hoc work use `Effect.withSpan`. Put high-cardinality detail (IDs, paths) on span annotations via `Effect.annotateCurrentSpan`, and keep metric labels low-cardinality (operation kind, method name, provider kind, aggregate kind, outcome) — never raw thread/command IDs, file paths, cwd, full prompts, or unnormalized model strings. Logs inside a span become span events automatically because `Logger.tracerLogger` is installed. `withMetrics(...)` is the default pipeable way to attach a counter and timer to an effect. **Runtime wiring and env vars.** Assembled in `apps/server/src/observability/Layers/Observability.ts`, providing the pretty stdout logger, `Logger.tracerLogger`, the local NDJSON tracer, and optional OTLP trace/metrics exporters plus trace-level/timing refs. Local trace file env vars: `T3CODE_TRACE_FILE` (override path), `T3CODE_TRACE_MAX_BYTES` (rotation size, default `10485760`), `T3CODE_TRACE_MAX_FILES` (default `10`), `T3CODE_TRACE_BATCH_WINDOW_MS` (default `200`), `T3CODE_TRACE_MIN_LEVEL` (default `Info`), `T3CODE_TRACE_TIMING_ENABLED` (default `true`). OTLP export env vars: `T3CODE_OTLP_TRACES_URL`, `T3CODE_OTLP_METRICS_URL`, `T3CODE_OTLP_EXPORT_INTERVAL_MS` (default `10000`), `T3CODE_OTLP_SERVICE_NAME` (default `t3-server`). Currently instrumented: Effect RPC websocket request spans, RPC request metrics (`RpcInstrumentation.ts`), startup phases, orchestration command processing and ack latency, provider session/turn operations, git command execution and hook events, terminal session lifecycle, sqlite query execution. ### Relay-side (relay observability) The relay Alchemy stack owns a shared Axiom trace setup: `t3-code-relay-traces-prod` (the OpenTelemetry trace dataset shared by the Worker, mobile app, and first-party relay clients), `t3-code-relay-otel-ingest-prod` (dataset-scoped Worker ingest token), `t3-code-mobile-otel-ingest-prod` (mobile ingest token), `t3-code-relay-client-otel-ingest-prod` (first-party relay-client ingest token), and `t3-code-relay-recent-spans-prod` (a provisioned view of recent request/endpoint spans). Alchemy stages append their sanitized stage name to isolate resources, e.g. `t3-code-relay-traces-dev-julius` for a personal stage. Deploy from `infra/relay` with `vp run deploy`; Alchemy resolves account-level Axiom deployment credentials, and at runtime the Worker receives only its scoped ingest token — mobile and relay clients use their own separately provisioned scoped tokens. The Worker emits Effect's built-in HTTP server spans plus endpoint and database child spans, with semantic HTTP attributes stored under the `attributes.` prefix and relay-specific annotations under `attributes.custom` (`relay.operation` is one emitted custom attribute), queryable via APL, e.g.: ```apl ['t3-code-relay-traces-prod'] | where name startswith 'http.server' | extend endpoint = column_ifexists('attributes.http.route', ''), customAttributes = column_ifexists('attributes.custom', dynamic({})) | project _time, name, trace_id, duration, ['attributes.http.request.method'], ['attributes.url.path'], ['attributes.http.response.status_code'], endpoint, relayOperation = customAttributes['relay']['operation'] | order by _time desc | limit 200 ``` Agents should prefer the provisioned view or APL queries for completed incidents rather than tailing the Cloudflare Worker directly. The stack does not provision a separate query token — responders needing scripted query access use the authorized account-level `AXIOM_TOKEN` together with `AXIOM_ORG_ID`; the scoped ingest tokens remain write-only credentials for their producers. ## Key Parameters - Trace file env vars: `T3CODE_TRACE_FILE`, `T3CODE_TRACE_MAX_BYTES` (10 MiB default), `T3CODE_TRACE_MAX_FILES` (10), `T3CODE_TRACE_BATCH_WINDOW_MS` (200ms), `T3CODE_TRACE_MIN_LEVEL` (Info), `T3CODE_TRACE_TIMING_ENABLED` (true). - OTLP env vars: `T3CODE_OTLP_TRACES_URL`, `T3CODE_OTLP_METRICS_URL`, `T3CODE_OTLP_EXPORT_INTERVAL_MS` (10s), `T3CODE_OTLP_SERVICE_NAME` (`t3-server`). - Relay: `AXIOM_TOKEN` + `AXIOM_ORG_ID` for scripted query access; four scoped ingest tokens for Worker, mobile, and relay clients. - Key metric families: `t3_rpc_request_duration`, `t3_orchestration_command_duration`, `t3_orchestration_command_ack_duration`, `t3_provider_turn_duration`, `t3_git_command_duration`. ## When To Use Use the server-side model when debugging "why did this request fail," "why does the UI feel slow," "did this command take too long to acknowledge," or "are git hooks causing latency" locally or in a self-hosted deployment. Use relay observability when investigating a completed production incident in the hosted T3 Connect relay, mobile app, or first-party relay clients. ## Risks & Pitfalls - Logs emitted outside an active span are not persisted to the trace file (SSH-managed launch stdout/stderr is a partial exception, captured in its own launcher log). - Metrics are never snapshotted locally — without OTLP configured there is no local metrics artifact to inspect, only in-process values. - Changing OTLP env vars requires a full app restart; the backend reads observability config only at process start. - Launching the packaged desktop app from Finder, Spotlight, the dock, or the Start menu after setting shell env vars usually does not pick them up — launch the exact executable from the same shell. - `t3_orchestration_command_ack_duration` is a server-side-only signal; it explicitly excludes WebSocket transit, client receipt, and React render time. - For relay incidents, tailing the Cloudflare Worker is discouraged — use the provisioned Axiom view or APL, since there is no separate relay query token and ingest tokens are write-only. ## Related Concepts - [[concepts/resource-telemetry]] — a separate, purpose-built telemetry subsystem (process/power) that complements this general tracing/metrics model. - [[concepts/architecture]] — the orchestration engine, RPC boundary, and provider adapters this page's span boundaries instrument. - [[concepts/ci-and-release]] — the release pipeline that deploys the relay stack this page's relay-observability section covers. - [[concepts/t3-connect]] — sibling page on the relay this section's Axiom setup instruments. ## Sources - raw/github_doc-docs-operations-observability-md.md - raw/github_doc-docs-operations-relay-observability-md.md --- title: "Permission Modes" type: concept tags: [operations, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-user-permission-modes-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition A permission mode controls how much a coding agent does on its own inside T3 Code before stopping to ask the user for approval. The mode is set **per thread**, from the mode control in the message composer — changing it in one thread does not affect any other thread. ## How It Works There are four modes: - **Supervised** — ask before commands and file changes. The agent pauses and shows what it wants to run or edit, then waits for approval. Work outside the workspace is restricted. (Mobile labels this mode **Approve actions** instead of **Supervised**.) - **Auto-accept edits** — auto-approve edits, ask before other actions. File changes go through without prompting; commands and anything else still stop for approval. - **Auto** — routine actions proceed without the user; risky ones still ask. Enforcement is provider-dependent: Codex delegates routine approvals to an AI reviewer, Claude uses its own auto permission mode, and providers without an equivalent (such as OpenCode) fall back to asking, behaving like Supervised. - **Full access** — allow commands and edits without prompts. This is the default; the agent runs unattended until it finishes or asks a question of its own. Approvals appear inline in the conversation; approving or rejecting one lets the agent continue from there. A thread created from inside another thread keeps that parent thread's mode. Otherwise, new threads start in **Full access** unless a different mode is picked before sending. Each provider maps these four modes onto its own approval and sandbox settings — for example, Codex translates the mode into its approval policy and sandbox level, so Supervised runs the CLI with prompting enabled and a restricted workspace, while Full access disables both. The exact per-provider translation is internal and may change; see [[concepts/providers]] for the underlying provider/adapter architecture that carries these settings through (`thread.interaction-mode.set`/`thread.runtime-mode.set`, per [[concepts/providers]]). ## Key Parameters - **Scope**: set per thread, not globally. - **Default for new threads**: Full access (unless inherited from a parent thread). - **Mobile labeling difference**: Supervised → "Approve actions." - **Provider-dependent enforcement of Auto**: AI reviewer (Codex), native auto mode (Claude), fallback-to-Supervised behavior (OpenCode and other providers without an equivalent). ## When To Use - **Full access** — for work in a worktree or a disposable sandbox. - **Supervised** — on a repository where an unwanted command would be expensive, or the first time running an unfamiliar task. - **Auto-accept edits** — for refactors where the edits are the point and only shell commands need a check. - **Auto** — a middle ground when you want routine work unattended but still want risky actions flagged, and are comfortable with the provider's own definition of "risky." ## Risks & Pitfalls - **Full access** being the default for brand-new threads means an unattended agent can run commands and edit files without prompts unless the user deliberately picks a more restrictive mode first. - The exact translation of a mode into a provider's approval policy/sandbox level is internal and may change, so behavior is not guaranteed to be identical across provider versions. - Providers without a native "Auto" equivalent (e.g. OpenCode) silently behave like Supervised rather than like Auto's usual "routine actions proceed automatically" behavior — a mode label can therefore mean different things depending on the active provider. ## Related Concepts - [[concepts/providers]] - [[concepts/t3code-overview]] - [[concepts/install-and-getting-started]] ## Sources - raw/github_doc-docs-user-permission-modes-md.md --- title: "Providers" type: concept tags: [providers, architecture, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-providers-md.md", "raw/github_doc-docs-user-providers-claude-md.md", "raw/github_doc-docs-user-providers-codex-md.md", "raw/github_doc-readme-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition A **provider** is the agent runtime that does the actual work behind a T3 Code thread — Codex, Claude Code, Cursor, Grok Build, or OpenCode. T3 Code's orchestration layer is deliberately provider-agnostic: it does not know or care which provider is behind a given thread. Each provider is wired into T3 Code through a **driver** plus an **adapter** that translate that provider's native CLI protocol into T3 Code's internal command/event model. ## How It Works `builtInDrivers.ts` exports `BUILT_IN_DRIVERS` with five entries: | Driver kind | Driver source | | ------------- | ------------------------ | | `codex` | `Drivers/CodexDriver.ts` | | `claudeAgent` | `Drivers/ClaudeDriver.ts` | | `cursor` | `Drivers/CursorDriver.ts` | | `grok` | `Drivers/GrokDriver.ts` | | `opencode` | `Drivers/OpenCodeDriver.ts` | Each driver declares a `driverKind`, a `configSchema`, and a `create` function that builds an adapter in a child scope. Adapter implementations (`CodexAdapter.ts`, `ClaudeAdapter.ts`, etc.) live beside their drivers and conform to a shared `ProviderAdapter` interface. Two registries separate configuration from live processes: `ProviderInstanceRegistry` keys configured instances by `ProviderInstanceId` (looking up the driver by `driverKind`, decoding the instance's config with that driver's schema, and calling `driver.create` in a child scope), while `ProviderAdapterRegistry` resolves an instance ID to its live adapter. `ProviderService` sits on top of both, routing session and turn operations by thread rather than by agent — so callers name a thread, and the provider behind it is an implementation detail. Adding a new driver only means writing the driver plus its adapter and registering it in `BUILT_IN_DRIVERS`; no orchestration, contract, or client change is required for the common case. Clients never call a provider directly. They dispatch orchestration commands over the RPC method `orchestration.dispatchCommand` — the client-facing provider commands are `thread.turn.start`, `thread.turn.interrupt`, `thread.approval.respond`, `thread.user-input.respond`, `thread.checkpoint.revert`, `thread.session.stop`, and the mode setters `thread.runtime-mode.set` / `thread.interaction-mode.set` (the runtime-mode setter underlies [[concepts/permission-modes]]). The server persists an event for the command, and a server-side reactor performs the actual provider call; provider output comes back as internal commands (`thread.message.assistant.delta`, `thread.session.set`, etc.) that clients observe via `orchestration.subscribeThread`. Provider work flows through three queue-backed workers, each built with `makeDrainableWorker` and exposing `drain` for deterministic test synchronization: `ProviderRuntimeIngestion` (consumes provider runtime streams and emits orchestration commands), `ProviderCommandReactor` (reacts to orchestration intent events and dispatches provider calls), and `CheckpointReactor` (captures workspace checkpoints on turn start/completion and performs reverts). A thread in `buffered` assistant delivery mode accumulates assistant text instead of streaming every delta; the buffer spills as one delta if it would exceed `MAX_BUFFERED_ASSISTANT_CHARS` (24,000 characters), and also flushes at interaction boundaries (an approval opening, or user input being requested). ### Per-provider setup Install-and-login basics for each provider (see [[concepts/install-and-getting-started]] for the full table): Codex CLI + `codex login`; Claude Code + `claude auth login`; Cursor CLI (binary `cursor-agent`) + `agent login`; Grok Build CLI + `grok login`; OpenCode + `opencode auth login`. Each provider CLI must be on the T3 Code server's `PATH`, or have an explicit binary path configured in Settings. Claude and Codex both support **multi-account setups** in T3 Code: - **Claude** ([[entities/provider-claude-code]]): a single account uses the default provider with an empty `CLAUDE_CONFIG_DIR path`. Multiple accounts (e.g. work and personal) each get a dedicated `CLAUDE_CONFIG_DIR` — set via `CLAUDE_CONFIG_DIR=~/.claude_personal_home claude auth login` at login time, then a matching `CLAUDE_CONFIG_DIR path` on the provider instance in T3 Code Settings. T3 Code only offers Claude providers that share the same config directory for continuing an existing thread, since Claude Code keeps account and local state across multiple files under that directory. External/compatible setups (OpenRouter, Claude Code Router) are configured the same way: a dedicated `CLAUDE_CONFIG_DIR` plus provider-instance Environment variables (e.g. `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN` marked sensitive). - **Codex** ([[entities/provider-codex]]): a single account uses `CODEX_HOME path: ~/.codex` with an empty Shadow home path. Multiple accounts use one shared `CODEX_HOME` plus a second account's auth in a separate **Shadow home path** (e.g. `~/.codex_p`), so both accounts can see the same T3/Codex sessions and either can continue an existing thread. A third Codex provider with a completely different `CODEX_HOME path` is instead treated as a separate workspace, not offered for existing threads. Sensitive values placed in a provider's Environment variables (API keys, tokens) are stored as server secrets and are not sent back to the client app after saving. ## Key Parameters - **Five built-in driver kinds**: `codex`, `claudeAgent`, `cursor`, `grok`, `opencode`. - **Driver contract**: `driverKind`, `configSchema`, `create`. - **Provider-facing commands**: `thread.turn.start`, `thread.turn.interrupt`, `thread.approval.respond`, `thread.user-input.respond`, `thread.checkpoint.revert`, `thread.session.stop`, `thread.runtime-mode.set`, `thread.interaction-mode.set`. - **Buffered delivery threshold**: `MAX_BUFFERED_ASSISTANT_CHARS` = 24,000 characters. - **Multi-account keys**: Claude uses `CLAUDE_CONFIG_DIR`; Codex uses `CODEX_HOME` plus an optional Shadow home path. ## When To Use Consult this page when deciding which coding-agent CLI to run under T3 Code, when a provider shows as "not authenticated," when setting up more than one account for Claude or Codex, or when diagnosing why a thread does or does not offer a particular provider for continuation. ## Risks & Pitfalls - A provider CLI installed but not on the server's `PATH` (and without an explicit binary path configured) will not be detected. - Cursor authentication is a common trap: installing Cursor CLI gives you `cursor-agent`, but you must run `agent login`, not `cursor-agent login`. - Setting `HOME` instead of `CLAUDE_CONFIG_DIR` when logging in to a second Claude account writes credentials to the wrong location (`~/.claude_personal_home/.claude` instead of where T3 Code looks). - Mixing up which Codex provider has the Shadow home path set, or copying `~/.codex` wholesale into a shadow directory (rather than just `auth.json`), can make two providers appear to use the same account. - Environment variable assignments belong in a provider's Environment variables section, not in Launch arguments. ## Related Concepts - [[concepts/t3code-overview]] - [[concepts/install-and-getting-started]] - [[concepts/permission-modes]] - [[entities/provider-claude-code]] - [[entities/provider-codex]] - [[entities/provider-cursor]] - [[entities/provider-grok-build]] - [[entities/provider-opencode]] ## Sources - raw/github_doc-docs-internals-providers-md.md - raw/github_doc-docs-user-providers-claude-md.md - raw/github_doc-docs-user-providers-codex-md.md - raw/github_doc-readme-md.md --- title: "Remote Access" type: concept tags: [remote, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-user-remote-access-md.md", "raw/github_doc-docs-internals-remote-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition Remote access is the ability to connect to a T3 Code server from a different device — a phone, tablet, or separate desktop — rather than only from the machine running the server. T3 Code has a single runtime boundary: a client talks to a T3 server over HTTP and WebSocket, and the server alone owns orchestration, providers, terminals, git, and filesystem operations. Remoteness is expressed entirely at the connection layer; the runtime itself is never split. ## How It Works ### The model ```text Client (desktop / mobile / web) known environments, connection supervisor | resolves one access endpoint Access method direct ws/wss, relay tunnel, Tailscale serve, desktop-managed ssh | connects to one T3 server Execution environment = one T3 server identity, providers, projects/threads, terminals, git, filesystem ``` One running T3 server instance (an `ExecutionEnvironment`) owns provider availability/auth, model availability, projects/threads, terminal processes, filesystem access, git operations, and server settings. It is identified by a stable `environmentId` persisted at `/environment-id` and generated on first start. ### Ways to enable network access 1. **Desktop app** — Settings → Connections → toggle **Network access** on (restarts the app, binds the backend to all network interfaces). The settings panel surfaces a default reachable endpoint plus alternatives (loopback, LAN, private-network, HTTPS); **Create Link** generates a shareable pairing link. If Tailscale is detected, Tailnet endpoints (a `100.x.y.z` IP, MagicDNS name, or an HTTPS MagicDNS endpoint via Tailscale Serve) are added to the list; the HTTPS MagicDNS endpoint must be opted into via **Enable Tailscale HTTPS**. 2. **Headless server (CLI)** — `npx t3 serve --host "$(tailscale ip -4)"` starts the server without a GUI and prints a connection string, a pairing token, a pairing URL, and a QR code. Add `--tailscale-serve` to advertise an HTTPS Tailnet endpoint (default port 443, or `--tailscale-serve-port` for another port). 3. **Desktop-managed SSH launch** — Settings → Connections → Remote Environments → Add environment → SSH launch flow. The desktop app probes the host, starts or reuses a remote T3 server, opens a local port forward, and saves the environment. The remote host still owns the actual server, projects, files, git state, terminals, and provider sessions; the renderer just connects to a forwarded local endpoint. The remote host needs a Node.js version satisfying `^22.16 || ^23.11 || >=24.10` reachable from a non-interactive shell (T3 Code tries Volta, asdf, mise, fnm, nodenv, nvm if `node` isn't directly on `PATH`). ### Quick pairing For an already-running server: `npx t3 pair` mints a fresh one-time pairing token and prints it as a scannable QR code, without restarting anything. If the server is loopback-only, use `npx t3 pair --tailscale` to publish it via Tailscale Serve HTTPS first. Flags include `--tailscale-serve-port`, `--ttl` (token lifetime), and `--base-dir`. ### Connection targets and endpoints Four target tags form the real access taxonomy (`connection/model.ts`): `PrimaryConnectionTarget` (platform-managed local server — desktop backend or CLI-served web app), `BearerConnectionTarget` (any manually paired direct HTTP/WebSocket endpoint), `RelayConnectionTarget` (managed T3 Connect relay tunnels — see [[concepts/t3-connect]]), and `SshConnectionTarget` (desktop-managed SSH environments). Tailscale is not a separate target kind — a Tailscale URL is paired through the ordinary bearer path; Tailscale is an endpoint provider/transport, not a distinct runtime concept. An `AdvertisedEndpoint` is a server- or desktop-authored candidate endpoint (HTTP+WS URL pair, default/available marker, reachability hint, HTTPS-app compatibility hint); clients treat these as hints, not proof a route works — the connection attempt itself decides. ### How pairing works The remote device needs no long-lived secret up front: `t3 serve` issues a one-time owner pairing token, the remote device exchanges it with the server, and the server creates an authenticated session for that device. After pairing, access is session-based. ### Hosted web app pairing `https://app.t3.codes` can save a remote backend from a URL like `https://app.t3.codes/pair?host=https://backend.example.com:3773#token=PAIRCODE`. This only works when the backend is reachable from the browser over HTTPS/WSS — browsers block an HTTPS page from connecting to an insecure `http://`/`ws://` LAN backend. The hosted app does not proxy traffic; the browser connects directly to the backend URL in the link. Hosted pairing is a client-side convenience only: the hosted app never gets a server-side control plane or copy of session state, and keeps the token in the URL hash so it is never sent to the hosted app's own server. ### Managing access afterward `t3 auth` manages access after initial pairing: issuing additional pairing credentials, inspecting active sessions, and revoking old pairing links or sessions. For the underlying relay/pairing mechanism behind `RelayConnectionTarget`, see [[concepts/t3-connect]]. ## Key Parameters - **Recommended setup**: a trusted private network / tailnet, for a stable address, transport security, and less exposure than the open internet. - **Three network-access enablement paths**: desktop app toggle, headless `t3 serve`, or desktop-managed SSH launch. - **Four connection target kinds**: Primary, Bearer, Relay, SSH. - **WebSocket auth**: a dedicated short-lived ticket (not a query-string token), obtained via `POST /api/auth/websocket-ticket` and appended as `wsTicket`; tickets default to a five-minute TTL (`DEFAULT_WEBSOCKET_TOKEN_TTL`). - **`t3 pair` flags**: `--tailscale`, `--tailscale-serve-port`, `--ttl`, `--base-dir`. ## When To Use Use remote access whenever you want to direct an agent from a device other than the one running the T3 Code server — controlling a desktop-hosted environment from the mobile app, from `app.t3.codes`, or reaching a headless server on another machine over SSH or a tailnet. ## Risks & Pitfalls - A loopback-bound server's pairing URL is not reachable from another device; pair over Tailscale or enable network access first. - Hosted pairing links (`app.t3.codes`) do not work with plain HTTP LAN URLs due to browser mixed-content rules — use the direct pairing URL from the desktop app or CLI instead. - Pairing URLs and tokens should be treated like passwords: anyone holding a valid credential can create a session until it expires or is revoked (via `t3 auth`). - SSH launch can fail with `node: command not found` or a version-range error if a version manager only initializes from an interactive shell profile — it must be configured to work with `sh -lc "command -v node && node --version"` non-interactively. - Binding `--host` broadly (rather than to a trusted private address) increases exposure unnecessarily. ## Related Concepts - [[concepts/t3code-overview]] - [[concepts/t3-connect]] - [[concepts/background-service]] - [[concepts/permission-modes]] ## Sources - raw/github_doc-docs-user-remote-access-md.md - raw/github_doc-docs-internals-remote-md.md --- title: "Resource Telemetry" type: concept tags: [architecture, observability, developer, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-resource-telemetry-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Resource Telemetry ## Definition Resource telemetry is T3 Code's subsystem for measuring its own process CPU/memory/I/O usage and host power state for the diagnostics UI. It replaces recurring `ps`, PowerShell, `ioreg`, and `pmset` subprocess probes with two persistent, direct data sources: a standalone Rust resource-monitor executable that reads process counters through OS APIs via `sysinfo`, and Electron main-process APIs for Electron process metrics and host power state. Status: implemented. The native monitor owns bounded in-memory history; the server only merges and summarizes that history when diagnostics requests it — telemetry history is not persisted to disk or continuously copied into Node. ## How It Works **Why a standalone executable.** The monitor is intentionally not a Node native addon: no N-API, `ffi-rs`, or dynamic-library ABI is loaded into the server process, so a monitor crash cannot corrupt the Node runtime; the server can supervise, restart, version-check, and measure the monitor as a normal child process; the same protocol works for the desktop app and the published CLI; and packaging is a single platform executable instead of an addon toolchain plus Node/Electron ABI matrix. The cost is one persistent child process and NDJSON serialization — a better failure boundary than repeatedly spawning shell utilities or loading native code into Node. **Runtime topology.** On desktop: Electron main (`powerMonitor`, `app.getAppMetrics()` while diagnostics is open) exchanges telemetry/demand-control NDJSON with the Node server over inherited file descriptors, while the Node server also talks stdin/stdout NDJSON to the Rust resource monitor, feeding the `ResourceTelemetry` Effect service, a background power-policy projection, and a WebSocket RPC/subscription to the diagnostics UI. On web, headless, and remote server: Electron telemetry is unavailable — the native monitor still runs beside the server and tracks the server process tree, and power fields degrade to `unknown` instead of invoking platform shell commands. **WSL limitation**: Windows desktop packages ship the Windows resource-monitor executable, which cannot run inside the Linux WSL backend, so a WSL-only backend does not receive `resourceMonitorPath` and reports native process telemetry as unavailable (Electron host-power telemetry remains available over the inherited desktop pipe). Supporting native WSL process telemetry would require publishing a Linux sidecar per supported architecture and converting its packaged path into the selected distro; the configuration deliberately does not pass the Windows `.exe` into WSL as a false fallback. **Native monitor** (`native/resource-monitor`). Receives schema-compatible commands on stdin and emits one JSON object per line on stdout: `configure`, `setExternalProcesses`, `setSampleInterval`, `setStreaming`, `sampleNow`, `readHistory`, `shutdown`, `hello`, `snapshot`, `historyChunk`, `error`. Protocol version is `RESOURCE_MONITOR_PROTOCOL_VERSION` in `packages/contracts/src/resourceTelemetry.ts`. - *Collection*: one `sysinfo::System` instance refreshed at a power-adaptive interval, collecting PID/parent PID, process start time and run time, process name/command line, current and cumulative CPU usage, resident/virtual memory, and cumulative process I/O counters. On Linux, task/thread enumeration is disabled and command lines load only when first needed, avoiding the expensive default of walking every `/proc//task/` directory each refresh. - *Process-tree selection*: each sample scans the accessible process table, builds the PID/PPID graph, and retains the server process, every descendant of the server (including provider-spawned grandchildren such as shells, `node`, `tsgo`, language servers), Electron processes supplied as explicit external roots and their descendants, and the resource monitor itself (a server child). Process identity is `(pid, startTimeMs)`, not PID alone; Electron and native start times are matched with a two-second tolerance because native start times can have coarser platform resolution. The process list is emitted in depth-first tree order so renderer collapse/expansion preserves complete subtrees. - *Native history and streaming*: every native sample is appended to a one-hour in-memory ring bounded to 3,600 snapshots, 20,000 retained process rows, and 64 MiB of retained history bytes — the first bound reached wins, so high process counts or large process names/command lines shorten the effective history window. History stays in the sidecar until a `readHistory` request and returns in bounded chunks. Periodic snapshot streaming is disabled by default; the server enables it only while at least one diagnostics subscription is retained. `sampleNow` remains available for explicit refreshes and identity validation. Sampling adjusts without restarting the sidecar: 15 seconds when suspended, locked, or in low-power/serious-critical thermal state; 5 seconds on battery; 1 second on normal AC; 5 seconds when power is unknown/stale in the background, 1 second while live diagnostics is open. - *Sampling limits*: this is counter sampling, not syscall tracing — a process that starts and exits entirely between samples may not be observed, though cumulative CPU/I/O counters still give accurate deltas for processes that survive across samples. Exact file paths, individual write syscalls, ETW events, eBPF events, and Endpoint Security events are outside this implementation; deeper tracing systems could be added later as opt-in diagnostic modes without changing the public `ResourceTelemetry` model. **I/O semantics.** Unix-like platforms report storage I/O counters exposed by `sysinfo`; Windows reports all process I/O bytes, not only disk bytes; OS caches can prevent logical application reads/writes from appearing as physical storage bytes. The UI labels these values as I/O reads and writes and exposes a per-process `ioSemantics` value. Group totals are observed deltas since telemetry startup; per-process total columns are the OS's cumulative counters. **Electron telemetry.** Electron main owns `DesktopTelemetryPublisher`. Power events trigger an immediate snapshot. While diagnostics is closed, the server sends configured active/idle host-power intervals to Electron (30 seconds and 2 minutes in the balanced profile); during heartbeats Electron reads `powerMonitor.isOnBatteryPower()`, `getSystemIdleTime()`, `getSystemIdleState()`, and `getCurrentThermalState()`. `app.getAppMetrics()` is only called while diagnostics demand is active, at 1 second on AC, 5 seconds on battery, 15 seconds while locked/suspended/thermally constrained. It also listens for lock/unlock, suspend/resume, AC/battery transitions, thermal-state changes, and CPU speed-limit changes. Suspension stays latched across event-driven snapshots; an explicit resume clears it immediately, and a periodic heartbeat also clears a stale latch so a missed resume event cannot leave telemetry permanently constrained. Electron does not expose a cross-platform low-power-mode getter, so that field remains `unknown`. The desktop backend is spawned with fd 3 for the existing bootstrap payload, fd 4 for Electron-to-server telemetry NDJSON, and fd 5 for server-to-Electron diagnostics-demand NDJSON — private Electron-main/server pipes, not the renderer WebSocket, recreated on every backend restart. **Server Effect services** (`apps/server/src/resourceTelemetry`): `ResourceMonitorBinary` resolves an executable from, in order, `T3CODE_RESOURCE_MONITOR_PATH`, desktop bootstrap configuration, bundled CLI resources, or local Cargo build outputs (unsupported platforms/missing/non-executable binaries produce schema-backed tagged errors). `NativeTelemetryClient` owns the resource-monitor process and protocol — validates the hello/version handshake, sends configuration and external process roots, adapts the native interval from host power state, enables streaming only for scoped live subscribers, reads chunked native history on demand, exposes `sampleNow`, supervises process exit and protocol failure, restarts with bounded exponential backoff, opens a circuit after repeated failures, supports explicit retry, and publishes health changes immediately. Snapshot sequence numbers are scoped to a monitor generation (the monitor restart count), so a sequence reset after a restart cannot freeze telemetry. `DesktopTelemetryReceiver` reads fd 4, decodes schema-validated messages, stores the latest Electron snapshot, publishes desktop health, writes diagnostics demand to fd 5, and gives the first sample a 90-second startup deadline (the stale deadline afterward stays beyond the slower configured host-power interval with 30 seconds of scheduling grace, so intentional 2–10 minute idle polling doesn't oscillate the policy). `ResourceTelemetry` merges native and Electron data and owns public telemetry semantics: calculates CPU/I/O rates from cumulative native counters, preserves the last native rates during desktop-only updates, classifies backend/Electron/monitor processes, computes process depth and child relationships, tracks starts/exits/CPU time/observed I/O, projects power data, acquires native streaming and Electron process metrics only for scoped live subscribers, queries/replays native history only when requested, validates `(pid, startTimeMs)` before process signaling, and updates history health even when no further native sample arrives — Electron and monitor processes are visible but are not valid targets for the process-signal RPC. `ResourceTelemetryHistory` is a pure on-demand projection that replays raw native snapshots to derive rates, lifecycle counters, buckets, and process summaries; current Electron process metrics are intentionally excluded from historical replay so they cannot overwrite older native CPU/memory samples. `ResourceAttribution` tracks known logical application I/O separately from OS counters — current integration points record successful writes for provider native/canonical event logs and the local server trace sink; future persistence paths should call `ResourceAttribution.record` rather than adding diagnostics-specific counters. **Background policy integration.** `HostPowerMonitor` consumes `DesktopTelemetryReceiver` directly; observing host power does not retain live resource diagnostics or invoke shell probes. The monitor updates its latest timestamp on every Electron sample but only publishes semantic state changes, so increasing idle seconds alone does not cause a background-policy broadcast every second. **Public API, UI, and packaging.** The WebSocket RPC surface provides current snapshot, bounded history, explicit monitor retry, and a live snapshot subscription. The diagnostics page displays aggregate CPU/memory/I/O/process counts, backend/Electron/monitor overhead groups, power/thermal state, collector health and restart information, CPU/I/O history, a collapsible live process tree, safe process signaling for backend descendants, and instrumented logical application I/O; legacy process diagnostics RPCs are projected from the same service so they no longer start recurring process-table commands. Desktop artifact builds compile the Rust target, stage it as `resources/resource-monitor/t3-resource-monitor[.exe]`, and pass its path to the backend bootstrap. CLI release jobs upload each active platform monitor artifact into `apps/server/dist/resource-monitor/-/`; the published server package includes `dist`, so these executables ship with the CLI. Missing platform artifacts degrade native telemetry to `unavailable`; the server continues running. ## Key Parameters - `RESOURCE_MONITOR_PROTOCOL_VERSION` (`packages/contracts/src/resourceTelemetry.ts`). - Native history bounds: 3,600 snapshots / 20,000 process rows / 64 MiB, one-hour ring. - Native sampling cadence: 15s (suspended/locked/low-power/thermal), 5s (battery), 1s (normal AC), 5s/1s (unknown power, background/live). - `T3CODE_RESOURCE_MONITOR_PATH` — first-priority override in the binary-resolution order. - Electron heartbeat intervals: 30s active / 2min idle (balanced profile); `app.getAppMetrics()` cadence 1s/5s/15s. - fd 3 (bootstrap payload), fd 4 (Electron→server telemetry), fd 5 (server→Electron diagnostics demand). - Packaged artifact path: `apps/server/dist/resource-monitor/-/`. ## When To Use Reach for this page when diagnosing desktop CPU/memory spikes, investigating why power/thermal state telemetry looks wrong, deciding where new resource-attribution instrumentation belongs, or explaining why a WSL-only backend reports process telemetry as unavailable. ## Risks & Pitfalls - The Windows resource-monitor executable cannot run inside a WSL backend — this is a deliberate `unavailable` state, not a bug, and the config intentionally refuses to pass the `.exe` into WSL as a false fallback. - Counter sampling can miss very short-lived processes that start and exit entirely between samples. - Missing platform monitor artifacts degrade native telemetry to `unavailable` gracefully — the server keeps running rather than failing to start. - Electron has no cross-platform low-power-mode getter, so that field is always `unknown`, not a bug in T3's own code. - Repeated native monitor failures stop automatic restart churn until an explicit retry is issued — a stuck "unavailable" state may need a manual retry, not a restart of the whole app. - I/O byte counters mean different things per platform (Windows includes non-disk I/O; Unix reports storage I/O); don't compare raw values across platforms without accounting for `ioSemantics`. ## Related Concepts - [[concepts/observability]] — the general tracing/metrics model this specialized process/power telemetry subsystem complements. - [[concepts/architecture]] — the server/Electron split and Effect-service pattern this subsystem follows. - [[concepts/background-service]] — sibling page on background/host-power behavior this subsystem's power projection feeds. ## Sources - raw/github_doc-docs-internals-resource-telemetry-md.md --- title: "Source Control" type: concept tags: [source-control, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-user-source-control-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition T3 Code's source control integration connects to a user's Git hosting provider so they can create pull/merge requests, review code, and manage repositories without leaving the app. It supports GitHub, GitLab, Bitbucket, and Azure DevOps. ## How It Works ### Starting projects From the Command Palette (`Cmd/Ctrl + K`) → **Add Project**, a user can choose **GitHub repository**, **GitLab repository**, **Bitbucket repository**, **Azure DevOps repository**, or paste any Git URL — entering a repository path (`owner/repo`, `group/project`, `workspace/repository`, or `project/repository`) or full Git URL, picking a destination, and starting to code. A local repository without a remote can be published with the **Publish Repository** action, which creates a new hosted repository (on any of the four providers), adds it as the origin remote, and pushes — all in one flow. If the local repository has no commits yet, publishing still creates and wires up the remote, but does not push; a commit must be made first, then pushed normally. ### Code review workflow Pushing a branch and creating a pull request can be done from the Git actions controls in the toolbar; T3 Code can suggest titles and descriptions based on the branch's commits. This covers GitHub Pull Requests, GitLab Merge Requests, Bitbucket Pull Requests, and Azure DevOps Pull Requests. T3 Code also surfaces whether the current branch already has an open PR/MR, offers a one-click open-in-browser action, and supports checking out a teammate's branch to review locally. ### Status visibility The **Source Control settings** page shows which providers are authenticated and ready, what's missing and how to fix it, and which account is signed in (when available). A **Rescan** action re-checks status after setting up a new machine or changing credentials. ### Per-provider setup Authentication happens on the machine running T3 Code (the server), not the local browser used to connect to it. - **GitHub** (recommended for most users): install the GitHub CLI (`brew install gh`), then `gh auth login`. Verify under Settings → Source Control. - **GitLab**: install the GitLab CLI (`brew install glab`), then `glab auth login`. - **Bitbucket**: token-based, via environment variables on the T3 Code server machine. Either a Bitbucket access token: ```bash export T3CODE_BITBUCKET_ACCESS_TOKEN="your-access-token" ``` or an Atlassian account email plus API token with read/write access to pull requests and repositories: ```bash export T3CODE_BITBUCKET_EMAIL="you@example.com" export T3CODE_BITBUCKET_API_TOKEN="your-token" ``` If both are set, the access token wins. Restart T3 Code and verify the connection afterward. - **Azure DevOps**: install Azure CLI (`brew install azure-cli`), add the DevOps extension (`az extension add --name azure-devops`), then `az login`. `git` itself must be installed on the server, since T3 Code uses it for all local operations. ## Key Parameters - **Supported providers**: GitHub, GitLab, Bitbucket, Azure DevOps. - **Auth location**: always the T3 Code server machine, never the connecting client/browser. - **Bitbucket env vars**: `T3CODE_BITBUCKET_ACCESS_TOKEN`, or the pair `T3CODE_BITBUCKET_EMAIL` + `T3CODE_BITBUCKET_API_TOKEN` (access token takes precedence if both are set). - **Repository path formats accepted**: `owner/repo` (GitHub), `group/project` (GitLab), `workspace/repository` (Bitbucket), `project/repository` (Azure DevOps), or a full Git URL. ## When To Use Use T3 Code's source control integration to clone or publish a repository from inside the app, to open a pull/merge request without switching to a browser or separate Git client, or to check a teammate's branch for local review — for any of the four supported hosting providers. ## Risks & Pitfalls - "Provider shows Not authenticated" — the fix is to run that provider's login command in a terminal **on the server**, then Rescan in Settings; running it on the connecting device does nothing. - Bitbucket connection failures are often environment variables set in the wrong shell profile, or the server not having been restarted after setting them. - Push failures can stem from a mismatch between the Git remote URL's transport (SSH vs HTTPS) and the credentials actually authenticated — these need different credentials. - Publishing a repository with no existing commits creates and wires the remote but does not push; forgetting the follow-up commit-and-push step can look like a broken publish flow. ## Related Concepts - [[concepts/t3code-overview]] - [[concepts/permission-modes]] - [[concepts/keybindings-and-updating]] ## Sources - raw/github_doc-docs-user-source-control-md.md --- title: "T3 Connect" type: concept tags: [remote, architecture, advanced, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-internals-t3-connect-md.md", "raw/github_doc-docs-internals-connection-runtime-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition T3 Connect is T3 Code's managed relay/tunnel solution for remote access — the mechanism behind `RelayConnectionTarget` (see [[concepts/remote-access]]). It uses a single Clerk application for web, desktop, and mobile authentication, and answers the case where the host is behind NAT, inbound ports are unavailable, or a mobile client needs to reach a desktop-hosted environment without router or firewall changes. ## How It Works ### Authentication The relay verifies two kinds of bearer credential: template JWTs generated from the `t3-relay` Clerk JWT template with the shared `t3-code-relay` audience, and Clerk OAuth tokens issued to the CLI. `verifyRelayClientBearerToken` tries the template/session path first and falls back to OAuth verification, so the CLI's OAuth credential works without needing a JWT template. T3 Connect is disabled in a fresh clone; enabling it for source builds requires a repository-root `.env`/`.env.local` with `T3CODE_CLERK_PUBLISHABLE_KEY`, `T3CODE_CLERK_JWT_TEMPLATE`, `T3CODE_CLERK_CLI_OAUTH_CLIENT_ID`, and `T3CODE_RELAY_URL`. These are public identifiers, not secrets, and are statically injected into client builds; a built artifact needs no environment file at runtime. When client-facing public values are absent, cloud UI is omitted, but the `t3 connect` command group always registers — it reports the missing configuration rather than silently disappearing from help. ### The `t3 connect` command group ```sh t3 connect # default: onboarding t3 connect login t3 connect link # --publish-only t3 connect status # --json t3 connect publish # --disable t3 connect unlink t3 connect logout ``` `t3 serve` is a separate top-level command, not a connect subcommand (see [[concepts/remote-access]]). `t3 connect login` opens the Clerk authorization flow and stores the CLI credential without enabling cloud exposure. `t3 connect link` installs the pinned managed `cloudflared` binary when needed, authorizes when needed, and records durable intent to expose the environment — it works without a running T3 server; the next `t3 serve`/`t3 start` reconciles the relay link and launches the managed tunnel. `t3 connect unlink` records disabled intent immediately, stops a reachable running connector, and attempts to revoke the relay-side environment record, but keeps the stored CLI authorization so `link` can re-enable exposure without another browser flow. `t3 connect logout` does the same cleanup and also removes the stored CLI authorization. The headless CLI OAuth flow uses a separate Clerk OAuth application, configured as a **public** client with PKCE (no client secret stored by the CLI), with allowed redirect URIs for both a loopback listener (`http://127.0.0.1:34338/callback`) and a hosted out-of-band flow (`https://app.t3.codes/connect/callback`, or `$T3CODE_HOSTED_APP_URL/connect/callback` when `T3CODE_HOSTED_APP_URL` is customized). The relay is not involved in the OAuth handshake itself — it only validates the resulting Clerk bearer token when the CLI manages an environment link. When `--headless` is passed, or SSH is detected via `SSH_CONNECTION`/`SSH_TTY`, `authorizeCli` automatically selects the out-of-band flow (prints a hosted authorization URL, accepts a pasted code) instead of the loopback listener, so port forwarding is optional rather than required. ### Relay traffic path From the client's perspective, a relay-tunneled connection is still an ordinary WebSocket connection — the route is simply mediated. The relay Worker only brokers credentials and a managed endpoint; application traffic then flows over the provisioned Cloudflare tunnel hostname for the life of the connection, not through the relay Worker itself. ### Client-side handling of relay connections On the client, T3 Connect's relay path is one of the four connection target kinds resolved by the shared connection runtime (`ConnectionResolver`, `ConnectionDriver`) described in [[concepts/architecture]]. Two relay-specific behaviors are called out as required test coverage for that runtime: **relay token reuse and refresh**, and **progressive relay discovery**. Credential changes interrupt an in-flight connection establishment only for relay targets specifically, because a new credential changes what is actually being established — unlike primary, bearer, or SSH targets, where a credential change does not interrupt establishment the same way. ### Background service interaction The background service ([[concepts/background-service]]) has an independent lifecycle from T3 Connect: Connect setup may offer to install the service during onboarding, but `t3 connect logout` leaves the service running. Manage the service separately with `t3 service status`, `install`, `update`, and `uninstall`. ## Key Parameters - **Shared audience**: `t3-code-relay` (Clerk JWT template name `t3-relay`). - **Config precedence**: process/CI env vars > repository-root `.env.local` > repository-root `.env`. - **Loopback OAuth callback port**: `34338`. - **Redirect URIs**: `http://127.0.0.1:34338/callback` (loopback) and `https://app.t3.codes/connect/callback` (hosted out-of-band). - **Desktop custom URL schemes**: `t3code-dev://app/` (dev), `t3code://app/` (packaged). - **Production macOS bundle ID**: `com.t3tools.t3code`. - **Tunnel binary**: a pinned, managed `cloudflared` build, installed by `t3 connect link`. ## When To Use Reach for T3 Connect when direct WebSocket access ([[concepts/remote-access]]) isn't viable — the host is behind NAT, there's no way to open inbound ports, or you want a mobile client to reach a desktop-hosted environment without any router/firewall configuration. It's also the mechanism an operator sets up once for a self-hosted or team deployment (via the relay's own Clerk/Cloudflare configuration). ## Risks & Pitfalls - `CLERK_SECRET_KEY` must never appear in a client application environment, the desktop app, or be committed to the repository — only `infra/relay` server-side config and Alchemy secrets should hold it. - Enabling an **empty** Clerk allowlist blocks all new sign-ups — a documented footgun for closed deployments. - Clerk allowlists control sign-up only; they do not revoke an existing user's active session — banning the user in Clerk is required to end active sessions and block future sign-in. - Omitting the hosted out-of-band redirect URI breaks both headless and SSH authorization. - The `prod` Alchemy stage owns the retained PlanetScale database; deploy `prod` before creating a personal developer stage, since non-production stages reference that same database. ## Related Concepts - [[concepts/remote-access]] - [[concepts/background-service]] - [[concepts/t3code-overview]] ## Sources - raw/github_doc-docs-internals-t3-connect-md.md - raw/github_doc-docs-internals-connection-runtime-md.md --- title: "T3 Code Overview" type: concept tags: [overview, foundational, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-agents-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition T3 Code is an "agent harness control surface": open-source software (by Ping/Theo, at github.com/pingdotgg/t3code, marketing site t3.codes) that lets a user control coding agents running on their own machine — Claude Code, Codex, Cursor, Grok Build, and OpenCode — from a best-in-class mobile app, a web app, and an Electron-based desktop app. `AGENTS.md` describes it more concretely as "a minimal GUI for coding agents": a Node WebSocket server wraps provider CLIs and serves web, desktop, and mobile clients, making it a "bring-your-own-subscription" open-source alternative to apps like Claude Desktop, Codex App, Cursor Glass, and Conductor. ## How It Works A Node WebSocket server runs on the user's machine (or a remote machine) and wraps each installed provider CLI as a subprocess. Three client surfaces talk to that server: - **Mobile** — a React Native app for iOS and Android, available on the App Store and Google Play, that can connect to any T3 Code server to control work remotely. - **Web** — technically two surfaces: the publicly hosted `app.t3.codes`, and the local web app opened automatically by `npx t3@latest`. - **Desktop** — a full Electron app that bundles the server runner. It can also act as the host server, accepting remote connections from `app.t3.codes` or the mobile app. T3 Code works with the user's existing subscriptions: "If they're set up on your computer, T3 Code can control them." It does not ship or replace the provider CLIs — it drives whichever ones are installed and authenticated locally. See [[concepts/providers]] for how the driver/adapter layer maps each provider CLI's protocol into T3 Code's orchestration model, and [[concepts/remote-access]] for how a client on one device reaches a server on another. ## Key Parameters - **Supported providers**: Claude Code, Codex, Cursor, Grok Build, OpenCode. - **Install-free trial path**: `npx t3@latest`, requiring Node.js `22.16+`, `23.11+`, or `24.10+`. - **Three client surfaces**: mobile (iOS/Android), web (`app.t3.codes` and local), desktop (Electron). - **"Truly open" commitment**: the project shares its roadmap, its thinking, and all of its code, explicitly so users can fork it if the maintainers ever go the wrong direction. A large number of users reportedly run forks. - **Project maturity**: per the README, "we are very very early in this project. Expect bugs," and the maintainers are "(mostly) not accepting contributions yet." ## When To Use Use T3 Code when you already have a coding-agent subscription (Claude Code, Codex, Cursor, Grok Build, or OpenCode) set up on a machine and want a unified, remote-capable control surface for it — for example, directing an agent from your phone while away from your desk, or using one app across web, desktop, and mobile instead of each provider's own bespoke client. See [[concepts/install-and-getting-started]] for first-run steps. ## Risks & Pitfalls - Early-stage software: the README warns bugs should be expected. - Contribution model is currently closed to all but small fixes; large feature contributions are not accepted per the README. - T3 Code does not include or install the underlying provider CLIs — at least one provider must already be installed and authenticated, or there is nothing for T3 Code to control (see [[concepts/providers]]). ## Related Concepts - [[concepts/install-and-getting-started]] - [[concepts/providers]] - [[concepts/remote-access]] - [[concepts/permission-modes]] ## Sources - raw/github_doc-readme-md.md - raw/github_doc-agents-md.md --- title: "Terminal Renderers" type: concept tags: [terminal, architecture, developer, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-docs-architecture-terminal-renderers-md.md", "raw/github_doc-apps-web-src-terminal-ghostty-readme-md.md", "raw/github_doc-apps-mobile-modules-t3-terminal-readme-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Terminal Renderers ## Definition Terminal renderers are the client-side layer that turns the raw byte stream from a server-owned PTY into an on-screen terminal for each T3 Code platform. Terminal sessions remain server-owned pseudo-terminals; clients receive the existing raw byte stream and send input/resize events over the existing terminal contracts. Renderer choices never cross the wire — they are purely a client-local concern, distinct from the transport described in [[concepts/architecture]]. ## How It Works **Ghostty alignment (Android and web).** Both platforms use the official `libghostty-vt` C ABI for parsing, terminal state, grapheme boundaries, keyboard encoding, selection, and scrollback, built from the pinned revision in `native/libghostty-vt/VERSION`: - **Android** links the native shared library and converts render state into a compact JNI snapshot, rendered by an Android Canvas view; Android owns its Kotlin Canvas and touch integration. - **Web** loads a separately cached WebAssembly build and reads render state into a Canvas 2D surface. The web adapter owns browser font shaping, the hidden IME textarea, clipboard and DOM input, and its Canvas renderer, and delegates application mouse encoding, word/line selection, and OSC 8 hyperlink metadata to the official ABI. Browser conventions remain available: holding Shift bypasses application mouse capture, and the platform link modifier opens hyperlinks. React does not participate in terminal frames. The web runtime is singleton-scoped per browser tab so split terminals share one compiled module and memory; each visible terminal owns and frees its own terminal, render state, row iterator, cell iterator, key/mouse encoder, and input event handles. Restoring captured scrollback temporarily detaches the PTY callback so historical device queries cannot emit replies into the current shell. The web adapter's files (`apps/web/src/terminal/ghostty/`): `runtime.ts` owns the singleton WebAssembly instance and runtime ABI layouts; `ghostty-write-pty.wasm` is a 112-byte callback trampoline for terminal-generated PTY replies; `core.ts` owns per-terminal Ghostty handles and translates the C ABI into render snapshots; `renderer.ts` batches backgrounds and style runs into a Canvas 2D frame; `surface.ts` owns browser input, IME, selection, scrolling, sizing, links, and cursor blinking; `fonts/` vendors a symbols-only Nerd Font (MIT) registered lazily so prompt glyphs render without a locally installed Nerd Font; `vendor/` holds only reproducibly-generated artifacts (via `apps/web/scripts/build-libghostty-wasm.sh`) — the upstream pin and license live once, at `native/libghostty-vt/` at the repo root. This directory is explicitly **not** an xterm compatibility layer. **Mobile (`apps/mobile/modules/t3-terminal`).** A local Expo module owns the native terminal surface for the mobile app with a deliberately small JavaScript contract: input from the native surface is emitted as `{ data: string }`, resize as `{ cols: number, rows: number }`, and remote PTY output is delivered by the existing `WsRpcClient.terminal` RPC stream. - **iOS** uses the vendored `GhosttyKit.xcframework`, built from the Ghostty custom-I/O fork with T3's iOS 16 compatibility patch applied. `T3TerminalView` owns a `libghostty` surface with a callback I/O model: initialize libghostty once for the process → create one Ghostty app and surface per native view → feed remote output into the surface with `ghostty_surface_feed_data` → send user input back to JS with the write callback → emit Ghostty's measured terminal size through `onResize`. - **Android** implements the same view contract with upstream `libghostty-vt` for terminal state, parsing, reflow, and scrollback; an Android Canvas view renders compact snapshots produced by the JNI bridge, keeping the React Native screen and RPC code platform-neutral. Vendored Ghostty revision and license details for mobile are in `THIRD_PARTY_NOTICES.md`. **Updating Ghostty.** Update and rebuild Android first, because mobile's `VERSION` file is the single source of truth for the upstream pin (the upstream `LICENSE` lives beside it). Then run: ```sh pnpm --dir apps/web build:ghostty-wasm ``` Commit the regenerated web `wasm` artifacts. The build embeds the pinned revision into the binary as semver build metadata, and the focused web ABI test reads it back through `ghostty_build_info` and compares it against mobile's `VERSION` — so the web vendor directory holds only artifacts, drift cannot hide, and there is no second pin to keep in sync. The same test enforces the artifact budget and exercises repeated create/write/free cycles with multi-codepoint graphemes. To rebuild the iOS `GhosttyKit.xcframework`, set `GHOSTTY_SOURCE_DIR` to a clone of the [custom-I/O fork](https://github.com/Yash-Singh1/ghostty/tree/custom-io) checked out on `custom-io`, then run `apps/mobile/modules/t3-terminal/scripts/build-libghostty-ios16.sh` (Zig 0.15.2, replaces only the `ios-arm64` and `ios-arm64-simulator` slices; requires Xcode's Metal toolchain, `xcodebuild -downloadComponent MetalToolchain` if `metal` fails). To rebuild Android's libghostty-vt, set `ANDROID_NDK_HOME` and run `apps/mobile/modules/t3-terminal/scripts/build-libghostty-android.sh` (downloads Zig 0.15.2 when needed, checks out the pinned upstream revision, rebuilds all four Android ABIs with 16 KB page-size support). ## Key Parameters - `native/libghostty-vt/VERSION` — the single upstream pin, sourced from mobile. - `ghostty_build_info` — the ABI call the web test uses to verify wasm/mobile pin parity. - `GhosttyKit.xcframework` — vendored iOS build from the Ghostty custom-I/O fork with an iOS 16 compatibility patch. - `GHOSTTY_SOURCE_DIR`, `ANDROID_NDK_HOME` — env vars required by the respective rebuild scripts. - Zig 0.15.2 — the toolchain pinned for both iOS and Android native rebuilds. ## When To Use Consult this page when bumping the Ghostty version, debugging a terminal rendering discrepancy that differs between web and mobile/Android, or adding new platform-specific terminal input/selection handling. ## Risks & Pitfalls - Updating web's wasm without first updating Android's `VERSION` file inverts the source-of-truth direction; Android must move first. - Forgetting to commit regenerated web wasm artifacts after running `build:ghostty-wasm` leaves the repo out of sync with the embedded build-info pin. - Adding React state to the render loop is explicitly disallowed — React does not participate in terminal frames. - Treating this as an xterm compatibility layer; it is a direct adapter over the official `libghostty-vt` ABI, not an xterm-compatible shim. - On mobile, the JS contract is intentionally minimal — logic belongs in the native layer, not by growing the `{data}`/`{cols,rows}` bridge. ## Related Concepts - [[concepts/architecture]] — the server-owned PTY and RPC transport this rendering layer sits on top of. - [[concepts/glossary]] — for terms like thread and session used elsewhere in the terminal contract. - [[concepts/t3code-overview]] — sibling page on the product surface. ## Sources - raw/github_doc-docs-architecture-terminal-renderers-md.md - raw/github_doc-apps-web-src-terminal-ghostty-readme-md.md - raw/github_doc-apps-mobile-modules-t3-terminal-readme-md.md --- title: "Testing and Agent Skills" type: concept tags: [developer, operations, terminal, well-established] created: 2026-08-06 updated: 2026-08-06 sources: ["raw/github_doc-agents-skills-test-t3-app-skill-md.md", "raw/github_doc-agents-skills-test-t3-app-references-sqlite-fixtures-md.md", "raw/github_doc-agents-skills-test-t3-mobile-skill-md.md", "raw/github_doc-agents-skills-ios-debugger-agent-skill-md.md", "raw/github_doc-agents-skills-ios-simulator-browser-skill-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- # Testing and Agent Skills ## Definition T3 Code dogfoods agent skills to test itself: `.agents/skills/` ships four `SKILL.md` definitions (`test-t3-app`, `test-t3-mobile`, `ios-debugger-agent`, `ios-simulator-browser`) that let a coding agent working on the T3 Code repository launch, pair, and drive T3's own web and mobile clients against disposable local backends — the same product T3 Code exists to control coding agents through, used here to verify T3 Code itself. ## How It Works **`test-t3-app`** (web). Covers launching, retaining, and testing the T3 Code web app in isolated development environments. Start an isolated environment by running `vp run dev` from the repo root against a worktree-local `.t3` directory or a disposable `mktemp -d` directory (`--home-dir ` only when a different isolated directory is needed); add `--share` to open it from another tailnet device. Never pass `--browser` during automated testing — an automatically opened page can consume the one-time bootstrap pairing token before the controlled browser uses it. Authenticate the browser by waiting for the server log's `/pair#token=...` URL and opening it exactly once as the controlled browser's first navigation, preserving the fragment verbatim; pairing URLs are secrets and must never appear in final responses, screenshots, or logs. If a token is consumed or expired, recover with: ```bash T3CODE_PORT= node apps/server/src/bin.ts auth pairing create \ --base-dir \ --dev-url \ --base-url \ --ttl 15m \ --label agent-ui-test ``` Treat the overall testing/implementation loop, not one assistant turn, as the environment's lifecycle boundary — keep the dev process, ports, authenticated browser tab, registered projects, and seeded fixtures alive across turns rather than tearing down after one verification pass; reuse a healthy existing process before starting a new one. Tear down only when the user explicitly confirms the iteration is finished or the task is genuinely complete. For SQLite inspection/seeding, read the `references/sqlite-fixtures.md` reference first: use `node apps/server/scripts/t3-sqlite-state.ts query` for read-only schema checks, stop the dev server before `exec` writes and restart it afterward with the same base directory, and never write to the shared `~/.t3` directory (the helper refuses this by default and creates a backup before each mutation). Seed projection tables (`projection_projects`, `projection_threads`, `projection_thread_messages`, `projection_thread_activities`, `projection_thread_sessions`, `projection_turns`, `projection_pending_approvals`, `projection_thread_proposed_plans`) only for disposable UI fixtures — never modify `orchestration_events` directly unless specifically testing projector internals, and never use direct projection writes to claim backend business behavior works; use the app's own commands/APIs for behavior tests, and the `auth` CLI (not direct `auth_*` table edits) for pairing/session state. **`test-t3-mobile`** (iOS Simulator / Android Emulator). Runs one focused, end-to-end mobile verification pass against disposable T3 state. First select a viable platform: prefer iOS Simulator on macOS with Xcode for cross-platform changes (loading `ios-debugger-agent` and, when available, `ios-simulator-browser`), or Android Emulator when Android is the affected surface or iOS tooling is unavailable — never claim verification when neither platform's prerequisites are met. Choose the lightest launch path: reuse an installed development client (`T3 Code Dev`, bundle/package `com.t3tools.t3code.dev`, URL scheme `t3code-dev`) and start Metro for JS/TS/asset-only changes; only rebuild native code (`vp run ios:dev` / `vp run android:dev`) when native source, dependencies, entitlements, config plugins, or the generated project actually changed. Seed Git projects before starting a headless backend: ```bash node apps/server/src/bin.ts project add --base-dir --title node apps/server/src/bin.ts serve --host 127.0.0.1 --port --base-dir --no-browser ``` Client origins: iOS Simulator uses `http://127.0.0.1:`, Android Emulator uses `http://10.0.2.2:`, physical devices need the backend bound to `0.0.0.0` and the host's LAN origin. Reuse an existing healthy Metro process only when it belongs to this worktree and matches `APP_VARIANT=development`, `--dev-client`, and scheme `t3code-dev`; never kill another worktree's Metro. Pair each client once with a fresh, single-use credential (`auth pairing create --ttl 15m --label agent-mobile-`) — create a different credential per device, and issue a new one rather than retrying a failed attempt. iOS driving uses `ios-debugger-agent`'s XcodeBuildMCP session pinned to one simulator UDID; Android driving uses semantic automation where available or `adb shell uiautomator dump` plus scoped `adb shell input` actions. Clean up afterward: remove the disposable environment from T3 Code Dev, remove any `adb reverse` rule created for the test, and stop only the serve-sim/Metro/backend/emulator/log processes this test started. **`ios-debugger-agent`.** Wraps the repository-configured XcodeBuildMCP MCP server (pinned `xcodebuildmcp@2.6.2`, requiring macOS 14.5+, Xcode 16+, Node 18+) instead of a globally installed Codex plugin. Establish one simulator context: call `session_show_defaults`, then `list_sims` to select one explicit UDID (prefer an already-booted simulator; never create/download runtimes without user authorization), then `session_set_defaults` with project/workspace, scheme, Debug configuration, simulator ID, and bundle identifier — every subsequent build, launch, screenshot, log capture, and UI action stays pinned to that UDID. Choose `build_run_sim` when native source/dependencies/entitlements/config changed, `test_sim` for the smallest relevant native test target, `launch_app_sim` when a compatible app is already installed. Drive the UI semantically: `snapshot_ui` for the current accessibility hierarchy, act only on current `elementRef` values (this XcodeBuildMCP version does not accept tap coordinates), refresh `snapshot_ui` after navigation, use `wait_for_ui` instead of fixed sleeps, and capture a final `screenshot` as proof. Capture logs with `start_sim_log_cap`/`stop_sim_log_cap` scoped to the exact bundle identifier, and clean up only what this test started. Adapted from OpenAI's `build-ios-apps` plugin (MIT) and aligned with XcodeBuildMCP 2.6.2 tool names. **`ios-simulator-browser`.** Streams one explicit iOS Simulator through pinned `serve-sim@0.1.45` into T3 Code's in-app browser (or another agent browser) so a human can watch simulator verification live, while `ios-debugger-agent` continues to drive the app semantically — browser-canvas coordinates are never a substitute for missing app accessibility. Requires Apple Silicon macOS, Xcode command-line tools, Node 20+; if unsupported, fall back to XcodeBuildMCP screenshots and report streaming was unavailable. Keep serve-sim bound to `127.0.0.1` only — never expose it to a LAN or tunnel without explicit user request, since its preview includes a token-gated shell-execution route. Start one owned stream per simulator UDID, scoped so cleanup only kills that UDID's own process: ```bash SIMULATOR_ID= cleanup_serve_sim() { npx --yes serve-sim@0.1.45 --kill "$SIMULATOR_ID" >/dev/null 2>&1 || true; } trap cleanup_serve_sim EXIT INT TERM HUP cleanup_serve_sim npx --yes serve-sim@0.1.45 "$SIMULATOR_ID" ``` Never reuse another task's stream unless explicitly shared, and never run an unscoped `--kill`. Adapted from OpenAI's `build-ios-apps` plugin (MIT), invoking `serve-sim@0.1.45` under its own Apache-2.0 license without vendoring the package. **How this connects to the wider contribution workflow.** Per `AGENTS.md`, "upon request, user-visible frontend changes should get one integrated pass in a real client: `test-t3-app` for web, `test-t3-mobile` for mobile," and this is the primary agent's job — subagents do not launch their own dev servers, and computer use or spinning up browsers needs explicit user permission. Test data for these workflows should come from copying real data (`~/.t3/userdata` or `~/.t3/dev`) into the worktree's isolated `.t3`, snapshotted safely with `VACUUM INTO` rather than a live `cp` (which risks a corrupt copy if a server has the source database open). ## Key Parameters - Mobile dev identity: app `T3 Code Dev`, bundle/package `com.t3tools.t3code.dev`, URL scheme `t3code-dev`. - Pinned tool versions: `xcodebuildmcp@2.6.2`, `serve-sim@0.1.45`. - Pairing token TTL convention: 15 minutes (`--ttl 15m`). - Android Emulator backend origin: `10.0.2.2`; iOS Simulator backend origin: `127.0.0.1`. - Disposable projection tables safe for fixture seeding: `projection_projects`, `projection_threads`, `projection_thread_messages`, `projection_thread_activities`, `projection_thread_sessions`, `projection_turns`, `projection_pending_approvals`, `projection_thread_proposed_plans`. ## When To Use Use `test-t3-app` after a web UI change needs one real, human-observable verification pass; use `test-t3-mobile` (with `ios-debugger-agent` and optionally `ios-simulator-browser`) after a mobile or cross-platform UI/native change, or to reproduce a phone/tablet-specific bug. These are explicitly integration/verification tools, not a substitute for `vp run test`. ## Risks & Pitfalls - Opening a complete pairing URL more than once, or in more than one browser, consumes its one-time token — always issue a fresh credential instead of retrying. - Passing `--browser` during automated web testing risks an auto-opened page consuming the bootstrap token before the controlled browser navigates. - Never point any of these workflows at the shared `~/.t3` directory — always an isolated worktree-local `.t3` or a disposable temp directory. - Direct SQLite projection writes are fixture-only evidence of a UI state, never proof that backend business behavior works — use application commands/APIs for behavior tests. - Killing another worktree's Metro process, another task's serve-sim stream, or running an unscoped `serve-sim --kill`/emulator teardown is explicitly disallowed. - Subagents must not launch their own dev servers, and computer use/browser automation requires explicit user permission per `AGENTS.md`. - A live `cp` of `state.sqlite` while a server has it open risks a corrupt copy; use `VACUUM INTO` instead, and always bring the `-wal`/`-shm` siblings if copying directly. ## Related Concepts - [[concepts/architecture]] — the orchestration/RPC system these skills exercise end to end. - [[concepts/ci-and-release]] — the `vp run dev`/build/test scripts these skills wrap for local verification. - [[concepts/terminal-renderers]] — a client surface these skills can be used to verify visually. - [[concepts/t3code-overview]] — sibling page on the product these skills test. ## Sources - raw/github_doc-agents-skills-test-t3-app-skill-md.md - raw/github_doc-agents-skills-test-t3-app-references-sqlite-fixtures-md.md - raw/github_doc-agents-skills-test-t3-mobile-skill-md.md - raw/github_doc-agents-skills-ios-debugger-agent-skill-md.md - raw/github_doc-agents-skills-ios-simulator-browser-skill-md.md --- title: "Troubleshooting: Recurring and Confirmed Problems" type: concept tags: [troubleshooting, operations, emerging] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_issue-bug-excessive-cpu-usage-on-windows.md", "raw/github_issue-bug-high-cpu-usage-when-app-is-open-macos.md", "raw/github_issue-t3-code-desktop-0-0-23-fails-ssh-environment-pairing-due-to-.md", "raw/github_issue-bug-failed-to-fetch-remote-auth-endpoint-error-when-trying-t.md", "raw/github_issue-bug-pairing-token.md", "raw/github_issue-bug-nightly-opencode-provider-false-not-installed-not-on-pat.md", "raw/github_issue-macos-desktop-app-fails-to-detect-codex-when-login-shell-is-.md", "raw/github_issue-linux-can-t-find-codex-if-installed-via-homebrew.md", "raw/github_issue-homebrew-codex-unrecognized.md", "raw/github_issue-codex-cli-is-installed-but-failed-to-run-codex-is-not-recogn.md", "raw/github_issue-codex-cli-installed-but-codex-not-recognized.md", "raw/github_issue-could-not-verify-codex-authentication-status-timed-out-while.md", "raw/github_issue-bug-chat-splits-into-a-new-session-after-a-pause.md", "raw/github_issue-bug-session-context-get-s-lost-forgotten-if-i-leave-it-for-a.md", "raw/github_issue-bug-loss-of-context-when-the-app-is-restarted.md", "raw/github_issue-bug-claude-losing-earlier-messages-not-compacting-correctly.md", "raw/github_issue-bug-t3-code-fails-to-start-after-upgrade-from-0-0-15-to-0-0-.md", "raw/github_issue-bug-0-0-17-t3-code-failed-to-start.md", "raw/github_issue-bug-timed-out-waiting-for-backend-readiness-at-http-127-0-0-.md", "raw/github_issue-bug-after-upgrade-0-0-20-0-0-21-failed-to-launch-app.md", "raw/github_issue-not-able-to-update-on-windows-could-not-download-update-erro.md", "raw/github_issue-bug-nightly-desktop-backend-crash-loops-due-to-missing-ffi-r.md", "raw/github_issue-bug-nightly-won-t-launch-cannot-find-package-fast-check-app-.md", "raw/github_issue-error-no-such-built-in-module-node-sqlite.md", "raw/github_issue-bug-claude-code-sonnet-4-6-only-gives-api-error-rate-limit-r.md", "raw/github_issue-bug-claude-code-doesn-t-support-aws-bedrock-usage.md", "raw/github_issue-bug-context-window-calculation-wrong-for-claude-code.md", "raw/github_issue-bug-codex-update-always-failing.md", "raw/github_issue-app-crash-on-heavy-thread.md", "raw/github_issue-t3-code-v0-0-10-windows-10-26100-frequently-becomes-not-resp.md", "raw/github_issue-bug-git-commit-time-out.md", "raw/github_issue-bug-some-requests-are-slow-keeps-appearing.md", "raw/github_issue-bug-local-desktop-environment-enters-reconnecting-after-fore.md", "raw/github_issue-bug-threads-get-stuck-on-waiting-for-0s.md", "raw/github_issue-bug-pending-plan-questions-become-stuck-after-app-restart.md", "raw/github_issue-bug-unable-to-connect-from-ios-to-macbook.md", "raw/github_issue-chat-timeline-content-overlaps-assistant-text-tool-call-card.md", "raw/github_issue-desktop-v0-0-4-long-startup-multi-second-view-transitions-an.md", "raw/github_issue-error-unable-to-add-project-request-time-out-orchestration-d.md", "raw/github_issue-thread-start-failed-invalid-request.md", "raw/github_issue-rmcp-transport-worker-worker-quit-with-fatal.md", "raw/github_issue-ctrl-w-does-not-close-terminal-on-windows.md", "raw/github_issue-t3-opens-forge-mql5-io-and-wants-me-to-log-in.md", "raw/github_issue-appimage-not-working-on-linux.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Definition This page catalogs recurring and confirmed problems reported against T3 Code in its GitHub issue tracker, grouped by root-cause cluster rather than listed one issue at a time. T3 Code is very early-stage software on a nightly-only release cadence (see [[summaries/release-digest]]), so bugs here should be read as a snapshot as of the mirrored issue set, not a permanent state — some are already fixed, most are still open, and several have been "partially fixed" in ways that expose a second, deeper bug. **No fix is claimed here unless a specific issue mirror states it** (a merged PR, a maintainer confirmation, or a reporter confirming the problem is gone); where a mirror shows only a PR opened, a workaround, or continued reproduction, that is stated plainly instead. ## How It Works Each cluster below gives: the symptom, the cause (if one was identified in the mirror), and the workaround/resolution/status exactly as documented in the cited issue mirror(s). ### Windows: excessive CPU usage (open) **Symptom** (raw/github_issue-bug-excessive-cpu-usage-on-windows.md, issue #4182): T3 Code constantly spawns `powershell.exe`/`cmd.exe`/`conhost.exe` subprocesses even while idle — scripts listing all TCP connections, scripts listing all running processes, `taskkill.exe`, git commands — causing system-wide slowdown, fan noise, heat, and battery drain. **Cause**: a community investigation (posted in the issue's comments, with file/line citations against `main`) found multiple stacked Windows-only polling loops: - `apps/server/src/diagnostics/ProcessResourceMonitor.ts` runs an unconditional 5-second sampler from server start (not gated on the Diagnostics UI being open) that calls `readWindowsProcessRows()`, which does one `Get-CimInstance Win32_Process` enumeration plus one *additional* `Get-CimInstance Win32_PerfFormattedData_PerfProc_Process` call **per process** — roughly 251 WMI queries every 5 seconds on a 250-process machine. `PROCESS_QUERY_TIMEOUT_MS` is 1000ms, too short for that query, so it times out and is killed every cycle (explaining the `taskkill.exe` spam) while producing no usable data. - `apps/server/src/terminal/Manager.ts`'s `windowsInspectSubprocess()` runs a second, faster (1-second interval) full process enumeration per open terminal session. - `apps/server/src/preview/PortScanner.ts` polls `Get-NetTCPConnection -State Listen` plus a per-listener `Get-Process` lookup every 3 seconds (Windows-only branch). - Git status refreshes (`VcsStatusBroadcaster.ts`, `GitVcsDriverCore.ts`) run every 15–30 seconds via several `git.exe` spawns per project/worktree, compounded on Windows by process-creation and Defender overhead. - Provider "update checks" (5-minute interval) are a minor, already user-disableable contributor. - One commenter notes the WMI process monitoring "locks the performance-data subsystem," so other tools reading process/thread state (Task Manager, DWM) stall too. **Status**: open. Comment 5 links **PR #4727 as "potentially fixed in"** this — not confirmed merged or released in the mirror. A later comment (comment 6) still describes the problem and shares an unofficial community patch to `bin.mjs` that short-circuits the WMI sampler and a related descendant-lookup guard as a manual workaround; this is a hand patch, not an official fix, and would need reapplying after every update. ### macOS: high CPU usage (open — a different bug from the Windows one) **Symptom** (raw/github_issue-bug-high-cpu-usage-when-app-is-open-macos.md, issue #2646): `kernel_task`/`syspolicyd` CPU spikes shortly after opening the app on macOS, fans spin up, and one report cites 30GB+ system memory usage from "constantly spawning CPU-intensive node processes." **Cause**: a process snapshot traced this to the server spawning multiple Cursor ACP (`cursor-agent ... acp`) child processes, each consuming 35–84% CPU, with one of them running a recursive `rg --files --follow --max-depth 16` filesystem crawl. This ties to [[entities/provider-cursor]] model/capability discovery (`discoverCursorModelsViaAcp` / `enrichCursorSnapshot`, `CURSOR_ACP_MODEL_DISCOVERY_CONCURRENCY = 4` with per-model retries) — **a Cursor-provider probing burst, unrelated to the Windows WMI/process-monitor cause above.** **Status**: open. A maintainer comment says a PR (#2428) "should fix this high burst of cursor probes," but explicitly notes the fix depends on "new api in the agent cli they added for us" that had not yet reached general availability at the time of writing, and separately says the team is "looking into how to reduce the background processes when idle." Not confirmed resolved in the mirror. ### SSH / remote environment pairing failures (open) **Symptom** (raw/github_issue-t3-code-desktop-0-0-23-fails-ssh-environment-pairing-due-to-.md, issue #2665): adding an SSH environment fails with `Error invoking remote method 'desktop:bootstrap-ssh-bearer-session': DesktopSshRemoteApiError ... SchemaError: Expected DateTime.Utc, got ""`, even though the remote server returns HTTP 200 with a valid JSON body. **Cause**: precisely diagnosed — the desktop app decodes the `expiresAt` (and related `issuedAt`/ `createdAt`/`lastConnectedAt`) timestamp fields with `Schema.DateTimeUtc`, which expects an already-materialized DateTime value, not a JSON ISO string; it should use `Schema.DateTimeUtcFromString`. This only affects the desktop-managed SSH launch path (`DesktopSshRemoteApi.bootstrapBearerSession`) — the LAN/Tailscale/manual-pairing-URL path skips schema validation (`response.json() as T`) and is unaffected. **Status**: open across multiple versions and platforms — independently reproduced on Windows, macOS, and Linux (Fedora AppImage) on both `0.0.23` and `0.0.24`. A fix PR (#2694, `DateTimeUtc` → `DateTimeUtcFromString`) was opened and testers confirmed it worked locally, but the mirror's last comments (on `0.0.24`) still reproduce the bug and ask for "a stable release that includes it" — no merge/release is confirmed in the mirror. **Workaround** (verified in the mirror): skip the desktop-managed SSH launch flow. Start the remote server manually (`npx t3@ serve --host --base-dir ~/.t3`), copy the printed pairing URL, and use **Add environment → paste pairing URL** in the desktop app instead — this uses the non-schema-validated code path and connects without issue. Two related but distinct pairing/auth bugs, also unresolved in their mirrors: - **CORS on the remote auth endpoint** (raw/github_issue-bug-failed-to-fetch-remote-auth-endpoint-error-when-trying-t.md, issue #1928): pairing to a headless remote server (Tailscale/WSL/devcontainer) fails with `Failed to fetch remote auth endpoint .../.well-known/t3/environment (Failed to fetch)` even though the same URL works via curl/browser. Diagnosed via DevTools as the server's CORS middleware answering the OPTIONS preflight correctly but not adding `Access-Control-Allow-Origin` to the actual GET/POST response, so Chromium blocks it as cross-origin. No official fix confirmed in the mirror. Workaround: run a Caddy reverse proxy in front of the T3 server that injects the missing CORS header, and pair through the proxy URL. - **Pairing token / bootstrap 500 error** (raw/github_issue-bug-pairing-token.md, issue #1889): the app indefinitely shows "you need to pair with a pairing token"; console shows `POST http://127.0.0.1:3773/api/auth/bootstrap 500 (Internal Server Error)`. No maintainer root-cause in the thread — appears to be corrupted/stale local auth/userdata state. Workaround confirmed by two independent users: delete or rename the local `.t3/userdata` folder, which forces re-pairing and resolves it. ### Provider PATH / login-shell detection failures (open — several distinct root causes) These share a symptom — an installed, working provider CLI is reported as "not installed" / "not recognized" — but the mirror shows **at least three unrelated root causes**, so don't assume one fix covers all of them. **OpenCode false "not installed / not on PATH" on Windows** (raw/github_issue-bug-nightly-opencode-provider-false-not-installed-not-on-pat.md, issue #2163): `opencode --version` works fine in PowerShell, but T3 Code reports `OpenCode CLI ('opencode') is not installed or not on PATH.` Cause: T3 Code's version-check spawn uses `shell: process.platform === "win32"`, but the OpenCode server-startup spawn does not use a shell. npm installs of OpenCode on Windows resolve `opencode` to a `.cmd`/`.ps1` shim rather than a raw `.exe`, so the no-shell `spawn("opencode", ...)` throws `ENOENT`. **Status**: partially fixed — comment 6 reports the bug "has been partially fixed in v0.0.21-nightly.20260420.77 if the opencode installation is an `opencode.exe`" (e.g. via `bun add -g opencode-ai`), "but it is still broken ... if the opencode installation is an `opencode.cmd`" (e.g. via `npm i -g opencode-ai`); PR #2183 was updated to target the narrower `.cmd` case but is not confirmed merged in the mirror. A separate report on Arch/AUR in the same thread (provider text fields not editable, providers can't be toggled) is flagged by another commenter as likely a different bug. **Workaround**: in T3 Code Settings (or directly in `settings.json`, `providers.opencode.binaryPath`), set the OpenCode **Binary path** to the fully-resolved native executable (e.g. `%APPDATA%\npm\node_modules\opencode-ai\node_modules\opencode-windows-x64\bin\opencode.exe`) instead of the bare `opencode` command. See [[entities/provider-opencode]]. **Codex not detected — three separate causes across platforms**, all in [[entities/provider-codex]]: - **macOS, Nushell login shell** (raw/github_issue-macos-desktop-app-fails-to-detect-codex-when-login-shell-is-.md, issue #309): the PATH-bootstrap probe (`apps/desktop/src/fixPath.ts`, `apps/server/src/os-jank.ts`) runs `execFileSync(shell, ["-ilc", "echo -n $PATH"], ...)`, assuming POSIX shell syntax. Nushell's `echo` has no `-n` flag, so the probe throws `nu::parser::unknown_flag` immediately and PATH bootstrap fails entirely, leaving `spawn("codex")` unable to find the binary. Explicitly distinct from the separate fish-shell PATH-corruption issue (#218) referenced in the same thread. **Status**: open — the reporter retested on the latest version at a maintainer's request and confirmed "Still reproduces :(" as the final comment; no fix landed per this mirror. - **Linux/macOS, Homebrew install** (raw/github_issue-linux-can-t-find-codex-if-installed-via-homebrew.md, issue #234): the PATH-detection logic only sources shell profile handling for macOS, not Linux, so Homebrew-on-Linux paths (`/home/linuxbrew/.linuxbrew/bin`) are never picked up; a fish-shell macOS report appears in the same thread. **Status**: open — the manual "Binary path" override was suggested as a workaround, but a user explicitly reported back "But it does not work." A related duplicate-symptom thread (raw/github_issue-homebrew-codex-unrecognized.md, issue #301) adds a severe slowdown angle, but that specific reporter's case turned out to be user error (an x64 build installed instead of arm64), not the PATH bug — so the general Homebrew-PATH bug remains open, unrelated to that particular slowdown. - **Windows, "'codex' is not recognized"** (raw/github_issue-codex-cli-is-installed-but-failed-to-run-codex-is-not-recogn.md, issue #269; raw/github_issue-codex-cli-installed-but-codex-not-recognized.md, issue #403): no maintainer root-cause in either thread; one comment on #269 explicitly cross-references #234's known bug that "setting this option doesn't change the path" for at least one from-source Codex build. On #403, a comment states the manual Codex-path setting "is not actually respected... I can enter the wildest gibberish there and it will still complain about the exact same 'codex' is not recognized," and that only `npx t3` (web mode) "works out of the box" — implying the bug is in the desktop app's native PATH probing specifically. **Status**: unresolved in both threads. Workaround reported to work for some users: resolve the binary with `which`/`where` and paste the full path into Settings → Codex Binary path. - Also unresolved and Codex-adjacent: **auth-verification timeout** (raw/github_issue-could-not-verify-codex-authentication-status-timed-out-while.md, issue #348) — "Could not verify Codex authentication status. Timed out while running command," with a debug console error `Cannot find module '/home/XXXXX/login'`. Not conclusively root-caused; maintainer suggested `codex login` again plus a restart, and reinstalling the CLI, but the reporter tried all suggested fixes and confirmed "still the same error" in the final comment. ### Chat splits into a new session after a pause / session context loss (partially fixed, still open at a deeper layer) **Symptom** (raw/github_issue-bug-chat-splits-into-a-new-session-after-a-pause.md, issue #2188): after leaving a thread idle, the UI still shows one continuous conversation, but the agent responds with no memory of prior turns; multiple session files appear on disk for what looks like one chat. **Cause**: a detailed forensic writeup (citing exact orchestration events, SQLite projections, and `apps/server/src/provider/Layers/ClaudeAdapter.ts` line references) found that once a thread sits idle long enough for T3 Code to transition its provider session to `stopped` (observed at roughly 25 minutes after the last turn), the next user message starts a brand-new Claude Agent SDK session **without `--resume`**: `turnCount: resumeState?.turnCount ?? 0` resets to 0 because the caller that reactivates a `stopped` thread was not passing the persisted `resume_cursor_json` back in as `input.resumeCursor` — even though T3 Code's own thread/turn projections and checkpoints stayed fully intact. **Status**: partially fixed, not fully resolved. A maintainer comment says the resume-cursor bug was "fixed on main and on nightlies, will be out on latest early next week," but a later comment on the same thread reports it is *still* broken after a restart+pause on a subsequent nightly, and a maintainer follow-up states: "seems like claude is not persisting sessions at all right now, so while the bug where we didn't pass the cursor properly is fixed, that cursor is not actually pointing to anything inside Claude Code" — i.e. fixing the first bug exposed a second, deeper Claude Code session-persistence problem that was still being investigated as of the last comment (which describes one specific restart-then-follow-up test where context *was* retained). Three closely related, independently-filed issues describe the same failure class and remain unresolved in their own mirrors, with no maintainer fix confirmation in any of them: - raw/github_issue-bug-session-context-get-s-lost-forgotten-if-i-leave-it-for-a.md (issue #2256, 27 comments — the highest comment count in the tracked issue set): idle sessions (as short as ~20 minutes, reported happening "5-6 times/day" by one user) cause the model to claim "this conversation just started," across Windows, Linux Mint AppImage, and macOS. A comment links it to the same underlying commit referenced in #2188 and speculates it "has now escalated to a bug in claude code itself." Workaround: manually ask the model to read/search the current chat history or on-disk conversation files to recover context. - raw/github_issue-bug-loss-of-context-when-the-app-is-restarted.md (issue #2140): closing and reopening the app during a session loses context; logs show `provider.session.reaped` with `reason: 'inactivity_threshold'` followed by a fresh `thread/start` with `resumeThreadId: null` — consistent with the same idle-reaping mechanism, and reported happening even without a restart, on both Codex and Claude Code providers. Workaround: manually paste prior conversation history back into the chat. - raw/github_issue-bug-claude-losing-earlier-messages-not-compacting-correctly.md (issue #2121): initially framed as a failure to auto-compact at the context limit, but a comment notes it can happen well before the token limit is reached ("I assume no one is experiencing this in CC via terminal?"), suggesting it is the same session-reaping bug rather than a compaction defect. ### Backend-readiness timeout on startup / update (mixed — one confirmed fix, later regressions) **Symptom**: `Timed out waiting for backend readiness at http://127.0.0.1:3773` after an upgrade or on launch. This is the single most-reported failure-mode family in the issue set, spanning several separate files: - raw/github_issue-bug-t3-code-fails-to-start-after-upgrade-from-0-0-15-to-0-0-.md (issue #1916): root-caused to a hardcoded `DEFAULT_TIMEOUT_MS = 1e4` (10-second) startup timeout that backend startup now exceeds by 0.5–2 seconds with many projects/threads loaded, following two related refactors (replacing `wait-on` with internal polling, and a sequential port scan). The issue's own Workaround field says "None found" as an official answer; a community member posted a full manual `asar` unpack/patch/repack script raising the timeout to 60 seconds. A separate AUR packaging regression (`/opt/t3code-bin/usr/bin/t3code: No such file or directory`, affecting some Arch/Omarchy users) is explicitly called out in the same thread as "a separate issue with the aur repo," not the timeout bug itself. - raw/github_issue-bug-0-0-17-t3-code-failed-to-start.md (issue #1937): confirmed by a commenter as "the same issue as #1916." Ad hoc workarounds reported (reinstall from DMG, reboot, run as admin, switch to nightly channel) with no single official fix confirmed; that a reboot sometimes helps suggests a race condition on top of the fixed timeout. - raw/github_issue-bug-timed-out-waiting-for-backend-readiness-at-http-127-0-0-.md (issue #1998): **the clearest resolution signal in this cluster.** A comment identifies it as a duplicate of #1916 and states "#1979 is a merged PR, which should fix this issue in the next release," and a later comment confirms "should be fixed in 0.0.20." Treat the original hardcoded-timeout cause as **fixed via PR #1979, released in 0.0.20.** - raw/github_issue-bug-after-upgrade-0-0-20-0-0-21-failed-to-launch-app.md (issue #2325): the same *symptom* recurs in a **later** version, after the 0.0.20 fix. A community bisection narrowed it to one of two commits between two nightly builds; the server runs migrations successfully but never reaches its HTTP listener. Explicitly a new regression, not the same bug as #1916/#1998. **Status**: open/unresolved in the mirror; workaround is to downgrade to 0.0.20. - raw/github_issue-not-able-to-update-on-windows-could-not-download-update-erro.md (issue #1906): a related but distinct update-lifecycle failure — Windows update to `0.0.17` fails with "Could not download update," speculated in comments to involve the newly introduced Microsoft code-signing certificate. **Status**: unresolved, no fix or workaround beyond manually downloading the release directly from GitHub Releases (confirmed working by one user). ### App fails to launch due to missing packaged dependencies (open/partial) - **Missing `ffi-rs` native module** (raw/github_issue-bug-nightly-desktop-backend-crash-loops-due-to-missing-ffi-r.md, issue #3104): nightly backend crash-loops with `Cannot find module '@yuuang/ffi-rs-win32-x64-msvc'` on Windows (and the darwin-arm64 equivalent on macOS). Cause: the desktop build stages production dependencies with `--no-optional`, which strips `ffi-rs`'s required platform-native optional dependency. A fix PR (#3105, "dropping `--no-optional`") is referenced but not confirmed merged/released in the mirror. Workarounds confirmed in the thread: switch the update channel from nightly to stable, or (macOS) manually install the missing native module outside the notarized `.app` bundle and point to it via `NODE_PATH` set with `launchctl setenv`. - **Missing `fast-check` package** (raw/github_issue-bug-nightly-won-t-launch-cannot-find-package-fast-check-app-.md, issue #3789): a different missing-package failure (roughly 40 transitive prod dependencies were found missing from the packaged asar), caused by a regression in a specific merged PR (#3772) that broke desktop dependency staging. A fix PR (#3790) was opened, but the last comment reports: "Updated, it now doesn't show the error but still fails to open just without the error message" — **the fix did not fully resolve it**; it changed the failure from an explicit error to a silent one. Workaround: roll back to the last known-good nightly build. - **`node:sqlite` not found** (raw/github_issue-error-no-such-built-in-module-node-sqlite.md, issue #810): `npx t3` fails with `Error: No such built-in module: node:sqlite` on older Node versions; after upgrading Node, the error can shift to `TypeError: statement.columns is not a function`. Cause: `node:sqlite` is an experimental Node built-in gated behind newer versions, with statement API differences between versions. **Status**: unresolved for at least one reporter even after upgrading Node — pinning to `npx t3@0.0.17` was suggested but not confirmed to fix it. ### Provider, model, and billing issues (open, several PRs in progress) - **Sonnet 4.6 rate-limit errors that don't occur in the native CLI** (raw/github_issue-bug-claude-code-sonnet-4-6-only-gives-api-error-rate-limit-r.md, issue #1553): Sonnet (and for some, Opus) consistently returns "API Error: Rate Limit Reached" in T3 Code while working fine in the native Claude Code CLI; only Haiku is reliable. A comment attributes this to T3 Code defaulting to the 1M-context-window model variant even on subscriptions where that variant isn't available (Haiku lacks a 1M option, which is why it "just works"). **Status**: unresolved. Workaround: manually set the context-window option down to 200K, or use Opus/Haiku/ Codex, or fall back to the native CLI. See [[entities/provider-claude-code]]. - **Claude Code + AWS Bedrock returns "Credit balance is too low"** (raw/github_issue-bug-claude-code-doesn-t-support-aws-bedrock-usage.md, issue #1257): a Bedrock- configured Claude Code setup (`CLAUDE_CODE_USE_BEDROCK=1` and related env vars) works from the CLI directly but fails in T3 Code with a direct-Anthropic-API credit error, implying T3 Code checks Anthropic API credits rather than passing the Bedrock configuration through. A maintainer opened a PR and asked reporters to test it; the mirror shows no explicit confirmation that it was merged or resolved the reports. Workaround: launch T3 Code from a terminal using its full binary path so it inherits the shell's Bedrock environment variables. - **Context-window percentage displayed wrong for Claude Code** (raw/github_issue-bug-context-window-calculation-wrong-for-claude-code.md, issue #2034): the context meter can sit at 5% for a day then jump to 100%, while the CLI itself reports ~15% usage; Codex threads don't show the problem. A maintainer comment confirms the calculation relies on Claude emitting `task_progress` events for the compacted context window and falls back to cumulative token spend when those events don't arrive ("not great. Not sure if there's a better way?"). **Status**: open, maintainer-acknowledged, no fix decided as of the mirror. - **Codex CLI self-update always fails** (raw/github_issue-bug-codex-update-always-failing.md, issue #2765): clicking "update" for a detected newer Codex CLI version fails with a `ChildProcess.spawn` `NotFound` error on Windows, even though `npm install -g @openai/codex@latest` works fine manually — likely a PATH issue in the spawned update command. A focused fix (using `codex update` natively for Codex ≥0.128.0, with a package-manager-detection fallback otherwise) is described as implemented, with "the corresponding implementation is now open as #4065" — a PR, not confirmed merged in the mirror. ### Git worktree accumulation causing crashes and slowdowns (open) - raw/github_issue-app-crash-on-heavy-thread.md (issue #996): the app crashes/becomes unusable on large threads in monorepos, only fixable by deleting the local `.t3` folder. A deep community investigation found git worktrees under `~/.t3/worktrees/` accumulate indefinitely with no pruning or startup scan — 8GB+ from orphaned worktrees, each carrying its own `node_modules` — and that the snapshot query loads all threads/messages/events with no `deleted_at` filter, so a bloated database slows every snapshot refresh. A contributor offered to open a PR; no merge is confirmed in the mirror. - raw/github_issue-t3-code-v0-0-10-windows-10-26100-frequently-becomes-not-resp.md (issue #980): Windows app becomes "Not Responding" during long request chains (UI thread blocked in V8/cppgc work per a WinDbg dump); the reporter traced this themselves to the same excessive-worktree cause as #996 and confirmed performance improved after deleting them. A maintainer said they'd track the fix under #996 rather than fixing this one independently — treat as the same unresolved root cause, not a separately fixed bug. - raw/github_issue-bug-local-desktop-environment-enters-reconnecting-after-fore.md (issue #3553): environments flip to "Reconnecting..." ("KLB did not respond to a connection health check") after the app is foregrounded, disabling the composer. Traced to a 15-second liveness probe that is too heavy when the local database has grown very large (one investigator's local SQLite DB was 3.78GB across 915 threads and 1.5M+ orchestration events with no retention/compaction), which is slow enough to trip the timeout. Cross-referenced in the issue as related to several other issue numbers. **Status**: unresolved; a suggested "AlwaysOnTop" workaround to avoid foreground transitions was reported by a user as not actually fixing it. ## Key Parameters Quick-reference status of every cluster above, as documented in its issue mirror(s): | Cluster | Status as of mirror | |---|---| | Windows excessive CPU usage | Open; PR #4727 "potentially" fixes it, unconfirmed; unofficial community patch exists | | macOS high CPU usage (Cursor ACP probing) | Open; fix PR #2428 gated on an upstream Cursor CLI API not yet GA | | SSH environment pairing (DateTimeUtc schema) | Open across 0.0.23/0.0.24, all platforms; fix PR #2694 opened, not confirmed merged; workaround available (pairing-URL flow) | | CORS on remote auth endpoint | Open; no official fix; workaround (Caddy reverse proxy) | | Pairing token / bootstrap 500 | Open officially; workaround confirmed (delete `.t3/userdata`) | | OpenCode false "not installed" (Windows) | Partially fixed (`.exe` installs, nightly `.20260420.77`); still broken for `.cmd`/npm installs; workaround (explicit Binary path) | | Codex not detected (Nushell, Homebrew, Windows PATH) | Open in all three sub-cases; workarounds partially effective | | Chat splits into new session after pause | Partially fixed (resume-cursor bug), deeper Claude Code session-persistence issue still open | | Backend-readiness timeout on startup | Original cause fixed in 0.0.20 (PR #1979); recurred as a new regression in 0.0.21 (#2325), open | | Windows update signing failure | Open; workaround (manual download from GitHub Releases) | | Missing `ffi-rs` / `fast-check` packaging | Open/partial; fixes attempted but #3789's fix left the app still failing (silently) | | `node:sqlite` not found | Open for at least one reporter after suggested fixes | | Sonnet 4.6 rate-limit false positives | Open; workaround (lower context-window setting) | | Claude Code + Bedrock credit-balance error | Open; maintainer PR posted, unconfirmed | | Context-window percentage wrong (Claude Code) | Open; maintainer-acknowledged, no fix decided | | Codex self-update failing | Open; PR #4065 referenced, unconfirmed merged | | Git worktree accumulation (crashes, slowdowns, reconnect loops) | Open; root cause identified, no merged fix confirmed | ## When To Use Check this page before filing a new bug report or troubleshooting a live problem: match the symptom text (error strings are quoted verbatim above) to a cluster, then apply the documented workaround if one exists. Because T3 Code ships nightly (see [[summaries/release-digest]]), always note the exact build number when comparing your symptom to what is described here — several clusters above show the same symptom recurring in a later version after an earlier fix, or a fix that only covers part of the original bug. ## Risks & Pitfalls - **Don't assume "fixed" without a specific citation.** Several clusters here show a maintainer or PR claiming a fix, followed by a later comment in the same thread showing it still reproduces (chat-session-splitting, `fast-check` packaging) — a linked PR number is not the same as a confirmed, released fix. - **Symptom-alike bugs can have unrelated causes.** The Windows and macOS "high CPU" reports look identical from the outside but trace to completely different code paths (WMI/PowerShell process polling vs. a Cursor ACP probing burst); the OpenCode/Codex "not detected" reports span at least three distinct root causes (npm shim spawning, non-POSIX login shells, incomplete Linux PATH sourcing). - **Manual workarounds patch internals and won't survive updates.** The Windows CPU workaround patches `bin.mjs` directly and the backend-readiness workaround unpacks and repatches the desktop `asar` — both need to be reapplied after every update, and a nightly-cadence project (see [[summaries/release-digest]]) means "every update" is frequent. - **This page is not exhaustive.** It groups the recurring/confirmed clusters and the clearest individually-reported bugs from the mirrored issue set; feature requests and pure UX discussion threads are intentionally excluded, as are one-off reports without enough detail to identify a cause or reproducible pattern. ## Related Concepts - [[concepts/t3code-overview]] - [[concepts/providers]] - [[concepts/remote-access]] - [[summaries/release-digest]] — the nightly cadence this page's version-specific "open in X, regressed in Y" findings depend on. - [[entities/provider-codex]] - [[entities/provider-opencode]] - [[entities/provider-claude-code]] - [[entities/provider-cursor]] ## Sources All raw issue mirrors cited inline above; see this page's frontmatter `sources` field for the complete file list. --- title: "Claude Code (Provider)" type: entity tags: [providers, install, user, well-established] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md", "raw/github_doc-docs-user-providers-claude-md.md", "raw/github_doc-docs-internals-providers-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Overview Claude Code is one of the five coding-agent CLIs T3 Code can drive (alongside [[entities/provider-codex]], [[entities/provider-cursor]], [[entities/provider-grok-build]], and [[entities/provider-opencode]]). T3 Code does not ship or replace Claude Code — it wraps the locally installed, locally authenticated `claude` binary as a subprocess and exposes it through its own orchestration layer to the mobile, web, and desktop clients (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). Internally, Claude Code is registered as the `claudeAgent` driver kind, one of five entries in `BUILT_IN_DRIVERS` (`builtInDrivers.ts`). Its driver lives at `apps/server/src/provider/Drivers/ClaudeDriver.ts` and its adapter at `apps/server/src/provider/Layers/ClaudeAdapter.ts`, implementing the shared `ProviderAdapter.ts` contract that maps Claude Code's transport, config, and event shapes into T3 Code's orchestration model (raw/github_doc-docs-internals-providers-md.md). ## Characteristics - **Default binary**: `claude` (raw/github_doc-docs-user-install-md.md). - **Driver kind**: `claudeAgent`, backed by `ClaudeDriver.ts` / `ClaudeAdapter.ts` (raw/github_doc-docs-internals-providers-md.md). - **Config directory**: `CLAUDE_CONFIG_DIR`. Leaving the `CLAUDE_CONFIG_DIR path` field empty in T3 Code Settings means T3 Code uses Claude Code's normal config directory; setting it points Claude Code at that directory via the `CLAUDE_CONFIG_DIR` environment variable without touching `HOME`, so the system keychain and rest of the environment are unaffected (raw/github_doc-docs-user-providers-claude-md.md). - **Multi-account model**: each account needs its own `CLAUDE_CONFIG_DIR`, because Claude Code keeps account and local state across multiple files under that directory. T3 Code therefore keeps separate config directories fully isolated rather than sharing partial state — unlike its Codex multi-account model, which can share one `CODEX_HOME` across accounts (raw/github_doc-docs-user-providers-claude-md.md). - **Thread continuation across accounts**: generally not supported. T3 Code only offers Claude providers that use the *same* config directory for an existing thread; a different `CLAUDE_CONFIG_DIR` is treated as a different Claude environment (raw/github_doc-docs-user-providers-claude-md.md). - **External/router-compatible**: Claude Code can be pointed at OpenRouter (via `ANTHROPIC_BASE_URL`/`ANTHROPIC_AUTH_TOKEN`) or at a local Claude Code Router, configured as ordinary Claude provider instances with custom environment variables (raw/github_doc-docs-user-providers-claude-md.md). ## How to Use Install and authenticate on the machine that runs the T3 Code server (not the device you browse from): ```bash claude auth login ``` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md) Default T3 Code Settings for a single-account setup: ```text Display name: Claude Binary path: claude CLAUDE_CONFIG_DIR path: empty ``` (raw/github_doc-docs-user-providers-claude-md.md) If `claude` is not on the server's `PATH` (for example, a version manager that only initializes in an interactive shell), set an explicit **Binary path** in Settings → the provider instance (raw/github_doc-docs-user-install-md.md). For work/personal accounts, log in a second time with a separate config directory and register it as a second provider instance: ```bash mkdir -p ~/.claude_personal_home CLAUDE_CONFIG_DIR=~/.claude_personal_home claude auth login ``` ```text Display name: Claude Personal Binary path: claude CLAUDE_CONFIG_DIR path: ~/.claude_personal_home ``` Use `CLAUDE_CONFIG_DIR`, not `HOME` — setting `HOME` writes the login to `~/.claude_personal_home/.claude`, which is not where T3 Code looks (raw/github_doc-docs-user-providers-claude-md.md). To route through OpenRouter instead of a direct Anthropic login, add a Claude provider with its own `CLAUDE_CONFIG_DIR path` and set, in that provider's Environment variables: ```text ANTHROPIC_BASE_URL https://openrouter.ai/api ANTHROPIC_AUTH_TOKEN sk-or-... Sensitive ANTHROPIC_API_KEY Empty value ``` Verify with `/status` inside a Claude session — it should show the Anthropic base URL as `https://openrouter.ai/api` (raw/github_doc-docs-user-providers-claude-md.md). ## Related Entities - [[entities/provider-codex]] — the other provider with a documented multi-account setup; contrast its shared-`CODEX_HOME`-plus-shadow-home model with Claude's fully isolated per-account config directories. - [[entities/provider-cursor]] - [[entities/provider-grok-build]] - [[entities/provider-opencode]] - [[concepts/providers]] --- title: "Codex (Provider)" type: entity tags: [providers, install, user, well-established] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md", "raw/github_doc-docs-user-providers-codex-md.md", "raw/github_doc-docs-internals-providers-md.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Overview Codex is one of the five coding-agent CLIs T3 Code can drive (alongside [[entities/provider-claude-code]], [[entities/provider-cursor]], [[entities/provider-grok-build]], and [[entities/provider-opencode]]). T3 Code wraps the locally installed, locally authenticated Codex CLI as a subprocess rather than shipping or replacing it (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). Internally, Codex is registered as the `codex` driver kind, one of five entries in `BUILT_IN_DRIVERS`. Its driver lives at `apps/server/src/provider/Drivers/CodexDriver.ts` and its adapter at `apps/server/src/provider/Layers/CodexAdapter.ts`, implementing the shared `ProviderAdapter.ts` contract that maps Codex's transport, config, and event shapes into T3 Code's orchestration model (raw/github_doc-docs-internals-providers-md.md). ## Characteristics - **Default binary**: `codex` (raw/github_doc-docs-user-install-md.md). - **Driver kind**: `codex`, backed by `CodexDriver.ts` / `CodexAdapter.ts` (raw/github_doc-docs-internals-providers-md.md). - **Config directory**: `CODEX_HOME`, default `~/.codex` (raw/github_doc-docs-user-providers-codex-md.md). - **Multi-account model differs from Claude's**: Codex supports a "shared home plus shadow home" setup — both provider instances point at the *same* `CODEX_HOME` (e.g. `~/.codex`), but the second instance also sets a **Shadow home path** (e.g. `~/.codex_p`) holding a second account's auth. Both accounts can then see the same T3/Codex sessions while keeping separate logins (raw/github_doc-docs-user-providers-codex-md.md). - **Thread continuation across accounts**: possible, unlike Claude Code — two Codex providers that share the same `CODEX_HOME path` are treated as compatible for continuation, so the locked model picker can offer both for an existing thread. A third Codex provider with a wholly different `CODEX_HOME path` is treated as a separate workspace and is not offered on threads created under `~/.codex` (raw/github_doc-docs-user-providers-codex-md.md). - **Known PATH/login-shell detection issues**: multiple issue mirrors report Codex being "installed but not recognized" when installed via Homebrew or a non-default login shell, a `PATH`-detection problem also seen with OpenCode. See [[concepts/troubleshooting]] for the specifics and current status. ## How to Use Install and authenticate on the machine that runs the T3 Code server: ```bash codex login ``` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md) Default T3 Code Settings for a single-account setup: ```text Display name: Codex CODEX_HOME path: ~/.codex Shadow home path: empty ``` (raw/github_doc-docs-user-providers-codex-md.md) If `codex` is not on the server's `PATH`, set an explicit **Binary path** in Settings → the provider instance (raw/github_doc-docs-user-install-md.md). For work/personal accounts, log in a second time with a separate `CODEX_HOME` and register it as a shadow-home provider instance: ```bash mkdir -p ~/.codex_p CODEX_HOME=~/.codex_p codex login ``` ```text Display name: Codex Personal CODEX_HOME path: ~/.codex Shadow home path: ~/.codex_p ``` If two Codex providers appear to show the same account, the doc's cleanup steps are: check the authenticated email in Settings, refresh provider status, confirm the second provider actually has a **Shadow home path** set, confirm the shadow directory has its own `auth.json`, and if `~/.codex` was copied wholesale into the shadow directory, strip everything except `auth.json`: ```bash find ~/.codex_p -mindepth 1 ! -name auth.json -exec rm -rf {} + ``` (raw/github_doc-docs-user-providers-codex-md.md) Use a totally separate `CODEX_HOME path` (no shadow home) only when you actually want a fully separate Codex workspace with its own sessions (raw/github_doc-docs-user-providers-codex-md.md). ## Related Entities - [[entities/provider-claude-code]] — contrast Codex's shared-home-plus-shadow-home multi-account model with Claude's fully isolated per-account config directories. - [[entities/provider-cursor]] - [[entities/provider-grok-build]] - [[entities/provider-opencode]] — shares Codex's PATH/login-shell binary-detection failure pattern; see [[concepts/troubleshooting]]. - [[concepts/providers]] --- title: "Cursor (Provider)" type: entity tags: [providers, install, user, well-established] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md", "raw/github_doc-docs-internals-providers-md.md"] confidence: medium t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Overview Cursor is one of the five coding-agent CLIs T3 Code can drive (alongside [[entities/provider-claude-code]], [[entities/provider-codex]], [[entities/provider-grok-build]], and [[entities/provider-opencode]]). T3 Code wraps the locally installed, locally authenticated Cursor CLI as a subprocess rather than shipping or replacing it (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). **No dedicated `docs/user/providers-cursor.md` exists in the repo** (unlike Claude and Codex, which each have their own multi-account guide). Everything below comes from the README, the general install doc's provider table, and the internals provider-architecture doc — there is no Cursor-specific setup, multi-account, or troubleshooting page to draw on. Internally, Cursor is registered as the `cursor` driver kind, one of five entries in `BUILT_IN_DRIVERS`. Its driver lives at `apps/server/src/provider/Drivers/CursorDriver.ts` and its adapter at `apps/server/src/provider/Layers/CursorAdapter.ts`, implementing the shared `ProviderAdapter.ts` contract (raw/github_doc-docs-internals-providers-md.md). ## Characteristics - **Default binary**: `cursor-agent` — note this does **not** match the CLI's install name ("Cursor CLI"), which is the specific point both the README-adjacent docs call out as worth watching (raw/github_doc-docs-user-install-md.md). - **Driver kind**: `cursor`, backed by `CursorDriver.ts` / `CursorAdapter.ts` (raw/github_doc-docs-internals-providers-md.md). - **Login command mismatch**: you install "Cursor CLI" (which provides the `cursor-agent` binary), but you authenticate with `agent login`, **not** `cursor-agent login` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). - **No documented multi-account setup**: unlike Claude and Codex, there is no known equivalent of a `CLAUDE_CONFIG_DIR`/`CODEX_HOME`-style multi-account guide for Cursor in the sources gathered here. Confidence on this point is medium — a page could exist that was not among the mirrored raw sources, but the README's docs list does not include one. ## How to Use Install Cursor CLI and authenticate on the machine that runs the T3 Code server: ```bash agent login ``` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md) If `cursor-agent` is not on the server's `PATH` (for example, a version manager that only initializes in an interactive shell), set an explicit **Binary path** in Settings → the provider instance (raw/github_doc-docs-user-install-md.md). Provider auth is required before starting a session with Cursor, not before starting T3 Code itself — T3 Code can be installed and opened first, with providers added afterward. An unauthenticated Cursor provider shows its status in Settings and fails at session start with the login command to run (raw/github_doc-docs-user-install-md.md). ## Related Entities - [[entities/provider-claude-code]] - [[entities/provider-codex]] - [[entities/provider-grok-build]] - [[entities/provider-opencode]] - [[concepts/providers]] --- title: "Grok Build (Provider)" type: entity tags: [providers, install, user, well-established] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md", "raw/github_doc-docs-internals-providers-md.md"] confidence: medium t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Overview Grok Build is one of the five coding-agent CLIs T3 Code can drive (alongside [[entities/provider-claude-code]], [[entities/provider-codex]], [[entities/provider-cursor]], and [[entities/provider-opencode]]). T3 Code wraps the locally installed, locally authenticated Grok Build CLI as a subprocess rather than shipping or replacing it (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). **No dedicated `docs/user/providers-grok.md` (or similar) exists in the repo.** Everything below comes from the README, the general install doc's provider table, and the internals provider-architecture doc — there is no Grok Build-specific setup, multi-account, or troubleshooting page to draw on. Internally, Grok Build is registered as the `grok` driver kind, one of five entries in `BUILT_IN_DRIVERS`. Its driver lives at `apps/server/src/provider/Drivers/GrokDriver.ts` and its adapter at `apps/server/src/provider/Layers/GrokAdapter.ts`, implementing the shared `ProviderAdapter.ts` contract (raw/github_doc-docs-internals-providers-md.md). ## Characteristics - **Default binary**: `grok` (raw/github_doc-docs-user-install-md.md). - **Driver kind**: `grok`, backed by `GrokDriver.ts` / `GrokAdapter.ts` (raw/github_doc-docs-internals-providers-md.md). - **CLI source**: [Grok Build CLI](https://x.ai/cli) (raw/github_doc-readme-md.md). - **No documented multi-account setup**: no known equivalent of a `CLAUDE_CONFIG_DIR`/ `CODEX_HOME`-style multi-account guide for Grok Build in the sources gathered here. Confidence on this point is medium for the same reason as Cursor — no dedicated doc was found among the mirrored raw sources. ## How to Use Install Grok Build CLI and authenticate on the machine that runs the T3 Code server: ```bash grok login ``` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md) If `grok` is not on the server's `PATH` (for example, a version manager that only initializes in an interactive shell), set an explicit **Binary path** in Settings → the provider instance (raw/github_doc-docs-user-install-md.md). Provider auth is required before starting a session with Grok Build, not before starting T3 Code itself — T3 Code can be installed and opened first, with providers added afterward. An unauthenticated Grok Build provider shows its status in Settings and fails at session start with the login command to run (raw/github_doc-docs-user-install-md.md). ## Related Entities - [[entities/provider-claude-code]] - [[entities/provider-codex]] - [[entities/provider-cursor]] - [[entities/provider-opencode]] - [[concepts/providers]] --- title: "OpenCode (Provider)" type: entity tags: [providers, install, user, troubleshooting, emerging] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_doc-readme-md.md", "raw/github_doc-docs-user-install-md.md", "raw/github_doc-docs-internals-providers-md.md"] confidence: medium t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Overview OpenCode is one of the five coding-agent CLIs T3 Code can drive (alongside [[entities/provider-claude-code]], [[entities/provider-codex]], [[entities/provider-cursor]], and [[entities/provider-grok-build]]). T3 Code wraps the locally installed, locally authenticated OpenCode CLI as a subprocess rather than shipping or replacing it (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md). **No dedicated `docs/user/providers-opencode.md` exists in the repo.** Everything below comes from the README, the general install doc's provider table, and the internals provider-architecture doc — there is no OpenCode-specific setup or multi-account page to draw on. OpenCode is also the most recently added provider of the five judging by nightly release history, and it is the provider with the most active, currently-unresolved binary-detection bug in the issue tracker (see below). Internally, OpenCode is registered as the `opencode` driver kind, one of five entries in `BUILT_IN_DRIVERS`. Its driver lives at `apps/server/src/provider/Drivers/OpenCodeDriver.ts` and its adapter at `apps/server/src/provider/Layers/OpenCodeAdapter.ts`, implementing the shared `ProviderAdapter.ts` contract (raw/github_doc-docs-internals-providers-md.md). ## Characteristics - **Default binary**: `opencode` (raw/github_doc-docs-user-install-md.md). - **Driver kind**: `opencode`, backed by `OpenCodeDriver.ts` / `OpenCodeAdapter.ts` (raw/github_doc-docs-internals-providers-md.md). - **CLI source**: [OpenCode](https://opencode.ai) (raw/github_doc-readme-md.md). - **No documented multi-account setup**: no known equivalent of a `CLAUDE_CONFIG_DIR`/ `CODEX_HOME`-style multi-account guide for OpenCode in the sources gathered here. - **Known nightly PATH-detection issue**: a nightly build of T3 Code has been reported to show OpenCode as falsely "not installed" / not found on `PATH` even when the `opencode` binary is correctly installed and on the server's `PATH`. This is the same class of binary-discovery failure documented for Codex under Homebrew/non-default login shells. See [[concepts/troubleshooting]] for the specific issue mirror, its stated cause (if any), and its current open/resolved status — do not assume it is fixed without checking that page. ## How to Use Install OpenCode and authenticate on the machine that runs the T3 Code server: ```bash opencode auth login ``` (raw/github_doc-readme-md.md; raw/github_doc-docs-user-install-md.md) If `opencode` is not on the server's `PATH` — including the known false-negative nightly detection issue noted above — set an explicit **Binary path** in Settings → the provider instance as a workaround (raw/github_doc-docs-user-install-md.md; see [[concepts/troubleshooting]] for whether this fully resolves the specific reported bug). Provider auth is required before starting a session with OpenCode, not before starting T3 Code itself — T3 Code can be installed and opened first, with providers added afterward. An unauthenticated OpenCode provider shows its status in Settings and fails at session start with the login command to run (raw/github_doc-docs-user-install-md.md). ## Related Entities - [[entities/provider-claude-code]] - [[entities/provider-codex]] — shares OpenCode's PATH/login-shell binary-detection failure pattern; see [[concepts/troubleshooting]]. - [[entities/provider-cursor]] - [[entities/provider-grok-build]] - [[concepts/providers]] - [[concepts/troubleshooting]] # Change Log ## 2026-08-06 — Initial build Built from the pingdotgg/t3code repo docs + 30 release mirrors + ~42 issue mirrors. T3 Code is an open-source "agent harness control surface" (Ping/Theo): control coding agents from mobile/web/desktop, remote-ready via T3 Connect. **Pages (24):** 18 concepts + 5 provider entities + 1 summary (release digest). **Sourcing notes:** - Excluded from ingest: `.repos/` (vendored third-party deps like alchemy-effect — not t3code) and `.plans/` (internal design docs), plus third-party-notice/tweets files. - **No stable release channel yet** — all 30 releases are `v0.0.32-nightly.*` (~4 nightlies/day); pages pin to `0.0.32-nightly (2026-08-05)`. The release digest states this explicitly. - `troubleshooting` is grounded in the issue mirrors with per-issue status (open/partially-fixed/confirmed-fixed) taken from each thread, not assumed — notable open items: Windows CPU (#4182), SSH pairing (#2665), OpenCode PATH detection (#2163), chat session-split after pause (#2188). - Providers Cursor and Grok Build have no dedicated docs upstream — their entity pages are grounded in the README + install table + providers internals, and say so. - No XL tier yet: early/nightly project. The provider matrix + internals depth + issue casebook are the natural XL seed as it stabilizes. --- title: "Release Digest: T3 Code Nightly Stream (0.0.32-nightly, builds 956–1009)" type: summary tags: [operations, overview, well-established] created: 2026-08-05 updated: 2026-08-05 sources: ["raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-956-50871eb5de64.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-957-6154b46cb86b.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-958-e4829603ff70.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-959-4029b858eaaa.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-960-cb11a71d632e.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-961-df78cda8bf9c.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-963-e259dd23c7ef.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-964-894d6d68f555.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-965-964cc279014f.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-966-a041981276b4.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-968-bfc31507f848.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-969-ca72e381c64f.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-970-0ad91b6e7fc1.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-974-d3037064e61a.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-976-5192f777fe54.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260802-979-64bf0161919e.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260802-980-e60821f0e0d8.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260803-985-69dfb7f09a47.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260803-986-30c96228067b.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260803-992-6f04a5cffb8f.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-993-a261a6440ae7.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-997-2b1d4fecb859.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-999-94331c58ecda.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-1000-d7950ac153c6.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1005-9697b765e5c3.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1006-2a04db134c2d.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1008-de592a00e897.md", "raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1009-7251f1a1f14a.md"] confidence: high t3code_version: "0.0.32-nightly (2026-08-05)" --- ## Key Points ### Versioning reality: nightly-only, no stable channel **There is no stable release channel for T3 Code as of this digest.** All 30 mirrored GitHub releases carry the tag `v0.0.32-nightly..` (e.g. `v0.0.32-nightly.20260805.1009`) — no `0.0.31`, no `0.0.33`, no non-nightly tag exists anywhere in the set. The build-number counter runs from **956** (2026-07-30T12:58:58Z) through **1009** (2026-08-05T21:44:40Z), covering **7 calendar days** (2026-07-30 through 2026-08-05). That is 30 published releases across 7 days — roughly 4 nightlies per day on average, though the cadence is uneven (five releases landed on 2026-07-30 alone, between 12:58 and 22:40 UTC, while other days had one or two). Despite the "nightly" name, publish timestamps span the full day (roughly 01:00 UTC to 22:40 UTC), so this reads as a rolling/continuous build stream rather than one fixed nightly cutoff. The build-number sequence has gaps in the 30-file mirror (e.g. 962, 967, 971–973 are absent), consistent with a monotonic build counter where not every build gets its own mirrored release entry. Anyone tracking "the latest T3 Code release" should expect a new nightly tag essentially daily, with no expectation of a slower-moving stable line to fall back to. ### Terminal rendering and UI — the largest theme by volume The single most active area across the 30 releases is the terminal/chat UI surface: - A new terminal renderer backend, **libghostty-vt**, was introduced and its vendor copy moved to the repo root (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-965-964cc279014f.md). - Numerous terminal-rendering fixes followed: cursor blink restored, the held Ctrl/Cmd+W close-terminal shortcut protected, replayable terminal queries stripped from history (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-997-2b1d4fecb859.md); terminal link hover styles restored (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1005-9697b765e5c3.md); configurable fonts/sizes added under Settings → Appearance (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md), then made more reliable and given richer previews, and font size fixed to survive a terminal split (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1006-2a04db134c2d.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1008-de592a00e897.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1009-7251f1a1f14a.md); a terminal loading flash was eliminated (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1009-7251f1a1f14a.md). - General chat/UI polish: simplified chat code blocks, aligned multiline error-alert controls (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-997-2b1d4fecb859.md); tooltip z-index raised above popovers/menus (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md); a project file picker (⌘P) and project content search (⇧⌘F) were added (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-957-6154b46cb86b.md); the model picker had layout-shift and shortcut-sync fixes, and legacy models were folded into separate menus (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1006-2a04db134c2d.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260802-980-e60821f0e0d8.md). ### Sidebar, search, and thread navigation Thread pinning returned (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md); a settings sidebar search and a thread-sidebar search were both added (raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-969-ca72e381c64f.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-968-bfc31507f848.md); threads became searchable by conversation content, and sidebar-driven thread-title regeneration was added (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-956-50871eb5de64.md), later hardened so regenerated titles stay on-topic and are generated from a plaintext prompt (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md) and are durable (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-1000-d7950ac153c6.md). Threads with open PRs stopped auto-settling (raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-969-ca72e381c64f.md). ### Session/context handling and thread catch-up Server-side thread replay was bounded and full-database snapshot hydration on catch-up was eliminated — a performance/correctness fix for how a thread's history reloads (raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-969-ca72e381c64f.md). Branch drift is now followed in dedicated worktrees so PRs stay linked to their originating thread (raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-970-0ad91b6e7fc1.md), and mobile-set server/worktree/origin preferences now correctly apply to new tasks (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-963-e259dd23c7ef.md). ### Remote updates, self-update, and server lifecycle A cluster of fixes targets the update mechanism itself: remote updates now work with database migrations and were made rollback-safe (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-974-d3037064e61a.md); self-update no longer rolls itself back on restart (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-965-964cc279014f.md); `npx`-run service updates no longer silently leave an old server process running (raw/github_release-t3-code-nightly-0-0-32-nightly-20260802-979-64bf0161919e.md); and update progress is now shown through a reconnect (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-956-50871eb5de64.md). See [[concepts/troubleshooting]] for user-facing reports of failed upgrades/launches that predate some of these fixes. ### Remote access, SSH/Connect, and pairing Managed tunnel processes were isolated (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md); cloudflared relay logs were surfaced as warnings instead of debug-level (raw/github_release-t3-code-nightly-0-0-32-nightly-20260801-976-5192f777fe54.md); reboots no longer strand the T3 Connect relay link, and 403 responses now explain why (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-957-6154b46cb86b.md). On the pairing side, `npx t3 pair` was added to generate a QR code from a running server (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-965-964cc279014f.md), later made actually scannable with an endpoint choice (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1002-7b38fb5c6b0f.md), and bare-IP pairing now defaults to HTTP on mobile (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-960-cb11a71d632e.md). See [[concepts/troubleshooting]] for a still-open SSH environment-pairing failure report that this theme's fixes do not appear to directly cover. ### Provider and model support Provider icons for Grok, Cursor, and OpenCode were fixed on mobile (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-999-94331c58ecda.md); Kimi models were unblocked in OpenCode with preview tools (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1005-9697b765e5c3.md); a Cursor todo's title now falls back correctly when its content is blank (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md); and provider/config contract decoding was made forward-compatible twice, for `ServerProviders` and for growing config unions (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-997-2b1d4fecb859.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-961-df78cda8bf9c.md) — this class of fix is what lets the client keep working against server-side provider changes without a hard version lock. See [[entities/provider-opencode]] and [[entities/provider-codex]] for provider-specific detail, and [[concepts/troubleshooting]] for unresolved provider-detection bugs these releases do not appear to fix. ### Performance and stability Renderer memory growth is now contained, with recovery from renderer out-of-memory crashes on desktop and web (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-1000-d7950ac153c6.md); default-branch-name and origin-existence lookups are now cached across status refreshes (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-960-cb11a71d632e.md); and mobile environments reconnect immediately on app resume (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-956-50871eb5de64.md). None of the 30 release notes mentions a Windows-specific CPU-usage fix — see [[concepts/troubleshooting]] for that still-open issue. ### Platform-specific work: mobile, Linux, and composer/attachments Mobile (iOS/Android) saw the highest raw count of individual fixes of any platform: workspace grouping preserved, an Android thread-search crash prevented, double dividers between thread sections removed (raw/github_release-t3-code-nightly-0-0-32-nightly-20260805-1005-9697b765e5c3.md); thread snoozing and collapsible settled threads added (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-966-a041981276b4.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-968-bfc31507f848.md); plus assorted iOS scrolling, toolbar, and branding fixes and Android clipboard/drag-image support in the composer (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-956-50871eb5de64.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-960-cb11a71d632e.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-958-e4829603ff70.md). Linux/desktop work centered on the AppImage and Electron packaging: a Linux secret-storage backend for Niri/Hyprland, claiming the `t3code://` URL scheme by default on Linux at startup, and scrubbing `XDG_DATA_DIRS`/`GSETTINGS_SCHEMA_DIR` leakage from AppImage-launched terminals (raw/github_release-t3-code-nightly-0-0-32-nightly-20260803-992-6f04a5cffb8f.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260803-985-69dfb7f09a47.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md). No macOS desktop-client-specific bug fixes (distinct from cross-platform Electron/desktop items) appeared in the 30 files; the only macOS-flavored entries were iOS-Simulator/App-Store-screenshot CI tooling fixes (raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-964-894d6d68f555.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260731-965-964cc279014f.md). ### Documentation and project activity One release notes a documentation push that split user docs from maintainer/internals docs and fixed "100+ stale claims" (raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-957-6154b46cb86b.md). Several releases across the window credit first-time external contributors (`@Bil0000`, `@Brechard`, `@naMqe-h`, and a cluster of four in one release: `@arhxam`, `@skjiisa`, `@Lucenx9`, `@MaxAnderson95`), alongside `@t3dotgg` (Theo/Ping), who is the most frequent committer across the 30-release window (raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-1000-d7950ac153c6.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-997-2b1d4fecb859.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260804-998-c30a6d9b9943.md; raw/github_release-t3-code-nightly-0-0-32-nightly-20260730-960-cb11a71d632e.md). ## Relevant Concepts - [[concepts/t3code-overview]] - [[concepts/providers]] - [[concepts/remote-access]] - [[concepts/troubleshooting]] — several themes above (updates/launch fixes, remote/SSH work, provider-icon and contract-decoding fixes) touch areas where open user-reported bugs exist; this digest does not claim those bugs are resolved by any specific nightly unless a release note says so explicitly. ## Source Metadata - **Source type**: GitHub release notes (auto-generated "What's Changed" changelogs), mirrored from `https://github.com/pingdotgg/t3code/releases`. - **Count**: 30 release mirrors, spanning nightly build numbers 956 through 1009. - **Date range**: 2026-07-30 (earliest, 956, published 2026-07-30T12:58:58Z) through 2026-08-05 (latest, 1009, published 2026-08-05T21:44:40Z). - **Channel**: nightly only (`v0.0.32-nightly..`); no stable channel exists in this set. - **Repository**: `pingdotgg/t3code`. - **Full file list** (all 30, chronological by build number): see the `sources` field in this page's frontmatter.