Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
53a552e
Stream git status updates over WebSocket (#1763)
juliusmarminge Apr 6, 2026
340dbbb
fix(web): unwrap windows shell command wrappers (#1719)
justsomelegs Apr 6, 2026
c6f57a1
Rename "Chat" to "Build" in interaction mode toggle (#1769)
heysonder Apr 6, 2026
226ed99
Assign default capabilities to Codex custom models (#1793)
juliusmarminge Apr 6, 2026
a221542
Add project rename support in the sidebar (#1798)
juliusmarminge Apr 6, 2026
11d456f
Support multi-select pending user inputs (#1797)
juliusmarminge Apr 6, 2026
afc3924
Add Zed support to Open actions via editor command aliases (#1303)
AdemBenAbdallah Apr 6, 2026
8244fb8
Closes #1795 - Support building and developing in a devcontainer (#1791)
Spitfire1900 Apr 7, 2026
b1934b9
Add explicit timeouts to CI and release workflows (#1825)
juliusmarminge Apr 7, 2026
28e481e
fix(web): distinguish singular/plural in pending action submit label …
jvzijp Apr 7, 2026
1ec346c
Refactor web stores into atomic slices ready to split ChatView (#1708)
justsomelegs Apr 9, 2026
72b7f90
Add VSCode Insiders and VSCodium icons (#1847)
Spitfire1900 Apr 9, 2026
b96308f
Prepare datamodel for multi-environment (#1765)
juliusmarminge Apr 9, 2026
b7559c4
Implement server auth bootstrap and pairing flow (#1768)
juliusmarminge Apr 9, 2026
5b3b31b
Use dev proxy for loopback auth and environment requests (#1853)
juliusmarminge Apr 9, 2026
2aa7398
Refresh local git status on turn completion (#1821)
juliusmarminge Apr 9, 2026
d9ded65
fix(desktop): add Copy Link action for chat links (#1835)
Klemencina Apr 9, 2026
7372184
fix: map runtime modes to correct permission levels (#1587)
oski646 Apr 9, 2026
386eb18
Fix persisted composer image hydration typo (#1831)
noxire-dev Apr 9, 2026
7b3cdc6
Clarify environment and workspace picker labels (#1854)
juliusmarminge Apr 9, 2026
b547fee
Scope git toast state by thread ref (#1855)
juliusmarminge Apr 9, 2026
9847e9b
fix build (#1859)
juliusmarminge Apr 9, 2026
70f5dfc
Stabilize keybindings toast stream setup (#1860)
juliusmarminge Apr 9, 2026
9bedd71
Debounce reconnect disconnect logging (#1862)
juliusmarminge Apr 9, 2026
869789b
Extract ChatComposer to fix composer keystroke re-renders (#1857)
juliusmarminge Apr 9, 2026
528bb2a
[codex] Harden WebSocket reconnect recovery (#1864)
juliusmarminge Apr 10, 2026
66d76b5
Fix composer footer focus ring overflow (#1865)
juliusmarminge Apr 10, 2026
592c234
fix: make file uri links clickable (#1867)
Yash-Singh1 Apr 10, 2026
7c0849f
fix(web): harmonize typography in chat messages and code blocks (#1861)
jvzijp Apr 10, 2026
65d797c
feat(web): add surround selection in composer (#1502)
mbuvarp Apr 10, 2026
abb84c0
fix: use different bundle ID for dev runner (#1806)
nmggithub Apr 10, 2026
5d9eb18
fix: don't let un-updateable builds check for an update (#1808)
nmggithub Apr 10, 2026
e32077c
Persist client settings and saved environment secrets (#1868)
juliusmarminge Apr 10, 2026
ea9e61b
Align chat composer and toolbar widths (#1869)
juliusmarminge Apr 10, 2026
e82b987
Select desktop backend port by sequential scan (#1870)
juliusmarminge Apr 10, 2026
cf9f236
Add headless `t3 serve` pairing output (#1871)
juliusmarminge Apr 10, 2026
1a05d8c
Document remote server network access setup (#1872)
juliusmarminge Apr 10, 2026
1cba2f6
Harden workspace git indexing against repo-configured fsmonitor execu…
juliusmarminge Apr 10, 2026
3405a64
bump effect to latest beta (#1866)
juliusmarminge Apr 10, 2026
2028d57
Fix server publish check for bin entrypoint (#1885)
juliusmarminge Apr 10, 2026
a3f2927
chore(release): prepare v0.0.16
t3-code[bot] Apr 10, 2026
9385314
Persist changed-files expansion state per thread (#1858)
Marve10s Apr 10, 2026
e3004ae
Harden secret store and resolve catalog overrides (#1891)
juliusmarminge Apr 10, 2026
a3dadf3
chore(release): prepare v0.0.17
t3-code[bot] Apr 10, 2026
678f827
Remove Claude subscription-based model adjustment (#1899)
juliusmarminge Apr 10, 2026
e231681
Fix worktree base branch updates for active draft (#1900)
juliusmarminge Apr 10, 2026
12c3af7
feat(desktop): add "Copy Image" to right-click context menu (#1052)
GuilhermeVieiraDev Apr 10, 2026
5fa09fa
[codex] fix composer footer compact layout (#1894)
shivamhwp Apr 10, 2026
4ae9de3
Stabilize auth session cookies per server mode (#1898)
juliusmarminge Apr 10, 2026
58e5f71
Add provider skill discovery (#1905)
juliusmarminge Apr 11, 2026
e0e01b4
Handle deleted git directories as non-repositories (#1907)
juliusmarminge Apr 11, 2026
b80e847
Memoize derived thread reads (#1908)
juliusmarminge Apr 11, 2026
97880e8
fix(web): resolve logical-to-physical key mismatch in project drag re…
mwolson Apr 11, 2026
26cc1ff
Add assistant message copy action and harden related test/storage fal…
shivamhwp Apr 11, 2026
1f4a3f6
Fix opening urls wrapped across lines in the terminal (#1913)
ElSargo Apr 11, 2026
5467d11
fix(web): prevent number-key shortcuts from hijacking input in focuse…
D3OXY Apr 11, 2026
934037c
feat(web): add extensible command palette (#1103)
binbandit Apr 11, 2026
f9372a4
chore(desktop): separate dev AppUserModelID on Windows (#1934)
adammansfield Apr 12, 2026
f9019cd
Coalesce status refreshes by remote (#1940)
juliusmarminge Apr 12, 2026
2fce84a
fix: quote editor launch args on Windows to support paths with spaces…
D3OXY Apr 12, 2026
f59ee36
fix(web): allow concurrent browser tests to retry ports (#1951)
ashvinnihalani Apr 12, 2026
7a00846
fix: Align token usage metrics for both Claude and Codex (#1943)
ashvinnihalani Apr 12, 2026
94d13a2
Preserve live stream subscriptions across explicit reconnects (#1972)
juliusmarminge Apr 13, 2026
96c9306
Migrate chat scrolling and branch lists to LegendList (#1953)
juliusmarminge Apr 13, 2026
dff8784
window controls overlay (windows&linux) (#1969)
tarik02 Apr 13, 2026
850c912
fix(desktop): increase backend readiness timeout from 10s to 30s (#1979)
rowalth Apr 13, 2026
57d7746
fix(web): replace turn strip overlay gradients with mask-image fade (…
GuilhermeVieiraDev Apr 13, 2026
f7fa62a
Add shell snapshot queries for orchestration state (#1973)
juliusmarminge Apr 13, 2026
1bf048e
fix: avoid copy button overlapping long code blocks (#1985)
barrymichaeldoyle Apr 13, 2026
f2205bd
Pad composer model picker to prevent ring clipping (#1992)
juliusmarminge Apr 13, 2026
801b83e
Allow empty server threads to bootstrap new worktrees (#1936)
juliusmarminge Apr 13, 2026
77fcad3
Prevent live thread branches from regressing to temp worktree names (…
juliusmarminge Apr 13, 2026
047a0a6
fix: add pointer cursor to the permissions mode select trigger (#1997)
UtkarshUsername Apr 13, 2026
9b29be9
docs: Document environment prep before local development (#1975)
ashvinnihalani Apr 13, 2026
5f7becf
feat: Add Kiro editor support to open picker (#1974)
ashvinnihalani Apr 13, 2026
cadd708
feat: show full thread title in a tooltip when hovering sidebar threa…
UtkarshUsername Apr 13, 2026
f5ecca4
Clear tracked RPCs on reconnect (#2000)
juliusmarminge Apr 13, 2026
6f69934
Use latest user message time for thread timestamps (#1996)
juliusmarminge Apr 13, 2026
d18e43b
fix: lost provider session recovery (#1938)
ashvinnihalani Apr 13, 2026
33dadb5
Fix thread timeline autoscroll and simplify branch state (#2002)
juliusmarminge Apr 13, 2026
569fea8
Warm sidebar thread detail subscriptions (#2001)
juliusmarminge Apr 13, 2026
5f7ec73
Fix new-thread draft reuse for worktree defaults (#2003)
juliusmarminge Apr 13, 2026
9dcea68
Refresh git status after branch rename and worktree setup (#2005)
juliusmarminge Apr 13, 2026
008ac5c
Cache provider status and gate desktop startup (#1962)
juliusmarminge Apr 13, 2026
2e42f3f
Improve shell PATH hydration and fallback detection (#1799)
juliusmarminge Apr 13, 2026
c9b07d6
Backfill projected shell summaries and stale approval cleanup (#2004)
juliusmarminge Apr 14, 2026
0d28026
fix(claude): emit plan events for TodoWrite during input streaming (#…
TimCrooker Apr 14, 2026
409ff90
Nightly release channel (#2012)
juliusmarminge Apr 15, 2026
9ff31f8
Fix nightly desktop product name (#2025)
juliusmarminge Apr 15, 2026
44afe78
Add filesystem browse API and command palette project picker (#2024)
Noojuno Apr 15, 2026
7968f27
Fix terminal Cmd+Backspace on macOS (#2027)
SAKETH11111 Apr 15, 2026
28cb9db
feat(web): add tooltip to composer file mention pill (#1944)
GuilhermeVieiraDev Apr 15, 2026
68061af
Improve markdown file link UX (#1956)
justsomelegs Apr 15, 2026
5e1dd56
feat: add Launch Args setting for Claude provider (#1971)
akarabach Apr 15, 2026
f9580ff
Default nightly desktop builds to the nightly update channel (#2049)
juliusmarminge Apr 16, 2026
5e13f53
fix: remove trailing newline from CLAUDE.md symlink (#2052)
marcusgrando Apr 16, 2026
d22c6f5
fix: prevent user-input activities from leaking into pending approval…
marcusgrando Apr 16, 2026
6fc7d22
Support Claude Opus 4.7 in Claude provider
Marve10s Apr 16, 2026
39831ad
Schema.is
juliusmarminge Apr 16, 2026
d0421bb
refactor: rename ClaudeCodeEffort to ClaudeAgentEffort across multipl…
juliusmarminge Apr 16, 2026
dafa03f
fxi codex text gen
juliusmarminge Apr 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "T3 Code Dev",
"image": "debian:bookworm",
"features": {
"ghcr.io/devcontainers-extra/features/bun:1": {},
"ghcr.io/devcontainers/features/node:1": {
"version": "24",
"nodeGypDependencies": true
},
"ghcr.io/devcontainers/features/python:1": {
"version": "3.12"
}
},
"postCreateCommand": {
"bun-install": "bun install --backend=copyfile --frozen-lockfile"
},
"customizations": {
"vscode": {
"extensions": ["oxc.oxc-vscode"]
}
}
}
302 changes: 302 additions & 0 deletions .docs/remote-architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
# Remote Architecture

This document describes the target architecture for first-class remote environments in T3 Code.

It is intentionally architecture-first. It does not define a complete implementation plan or user-facing rollout checklist. The goal is to establish the core model so remote support can be added without another broad rewrite.

## Goals

- Treat remote environments as first-class product primitives, not special cases.
- Support multiple ways to reach the same environment.
- Keep the T3 server as the execution boundary.
- Let desktop, mobile, and web all share the same conceptual model.
- Avoid introducing a local control plane unless product pressure proves it is necessary.

## Non-goals

- Replacing the existing WebSocket server boundary with a custom transport protocol.
- Making SSH the only remote story.
- Syncing provider auth across machines.
- Shipping every access method in the first iteration.

## High-level architecture

T3 already has a clean runtime boundary: the client talks to a T3 server over HTTP/WebSocket, and the server owns orchestration, providers, terminals, git, and filesystem operations.

Remote support should preserve that boundary.

```text
┌──────────────────────────────────────────────┐
│ Client (desktop / mobile / web) │
│ │
│ - known environments │
│ - connection manager │
│ - environment-aware routing │
└───────────────┬──────────────────────────────┘
│ resolves one access endpoint
┌───────────────▼──────────────────────────────┐
│ Access method │
│ │
│ - direct ws / wss │
│ - tunneled ws / wss │
│ - desktop-managed ssh bootstrap + forward │
└───────────────┬──────────────────────────────┘
│ connects to one T3 server
┌───────────────▼──────────────────────────────┐
│ Execution environment = one T3 server │
│ │
│ - environment identity │
│ - provider state │
│ - projects / threads / terminals │
│ - git / filesystem / process runtime │
└──────────────────────────────────────────────┘
```

The important decision is that remoteness is expressed at the environment connection layer, not by splitting the T3 runtime itself.

## Domain model

### ExecutionEnvironment

An `ExecutionEnvironment` is one running T3 server instance.

It is the unit that owns:

- provider availability and auth state
- model availability
- projects and threads
- terminal processes
- filesystem access
- git operations
- server settings

It is identified by a stable `environmentId`.

This is the shared cross-client primitive. Desktop, mobile, and web should all reason about the same concept here.

### KnownEnvironment

A `KnownEnvironment` is a client-side saved entry for an environment the client knows how to reach.

It is not server-authored. It is local to a device or client profile.

Examples:

- a saved LAN URL
- a saved public `wss://` endpoint
- a desktop-managed SSH host entry
- a saved tunneled environment

A known environment may or may not know the target `environmentId` before first successful connect.

### AccessEndpoint

An `AccessEndpoint` is one concrete way to reach a known environment.

This is the key abstraction that keeps SSH from taking over the model.

A single environment may have many endpoints:

- `wss://t3.example.com`
- `ws://10.0.0.25:3773`
- a tunneled relay URL
- a desktop-managed SSH tunnel that resolves to a local forwarded WebSocket URL

The environment stays the same. Only the access path changes.

### RepositoryIdentity

`RepositoryIdentity` remains a best-effort logical repo grouping mechanism across environments.

It is not used for routing. It is only used for UI grouping and correlation between local and remote clones of the same repository.

### Workspace / Project

The current `Project` model remains environment-local.

That means:

- a local clone and a remote clone are different projects
- they may share a `RepositoryIdentity`
- threads still bind to one project in one environment

## Access methods

Access methods answer one question:

How does the client speak WebSocket to a T3 server?

They do not answer:

- how the server got started
- who manages the server process
- whether the environment is local or remote

### 1. Direct WebSocket access

Examples:

- `ws://10.0.0.15:3773`
- `wss://t3.example.com`

This is the base model and should be the first-class default.

Benefits:

- works for desktop, mobile, and web
- no client-specific process management required
- best fit for hosted or self-managed remote T3 deployments

### 2. Tunneled WebSocket access

Examples:

- public relay URLs
- private network relay URLs
- local tunnel products such as pipenet

This is still direct WebSocket access from the client's perspective. The difference is that the route is mediated by a tunnel or relay.

For T3, tunnels are best modeled as another `AccessEndpoint`, not as a different kind of environment.

This is especially useful when:

- the host is behind NAT
- inbound ports are unavailable
- mobile must reach a desktop-hosted environment
- a machine should be reachable without exposing raw LAN or public ports

### 3. Desktop-managed SSH access

SSH is an access and launch helper, not a separate environment type.

The desktop main process can use SSH to:

- reach a machine
- probe it
- launch or reuse a remote T3 server
- establish a local port forward

After that, the renderer should still connect using an ordinary WebSocket URL against the forwarded local port.

This keeps the renderer transport model consistent with every other access method.

## Launch methods

Launch methods answer a different question:

How does a T3 server come to exist on the target machine?

Launch and access should stay separate in the design.

### 1. Pre-existing server

The simplest launch method is no launch at all.

The user or operator already runs T3 on the target machine, and the client connects through a direct or tunneled WebSocket endpoint.

This should be the first remote mode shipped because it validates the environment model with minimal extra machinery.

### 2. Desktop-managed remote launch over SSH

This is the main place where Zed is a useful reference.

Useful ideas to borrow from Zed:

- remote probing
- platform detection
- session directories with pid/log metadata
- reconnect-friendly launcher behavior
- desktop-owned connection UX

What should be different in T3:

- no custom stdio/socket proxy protocol between renderer and remote runtime
- no attempt to make the remote runtime look like an editor transport
- keep the final client-to-server connection as WebSocket

The recommended T3 flow is:

1. Desktop connects over SSH.
2. Desktop probes the remote machine and verifies T3 availability.
3. Desktop launches or reuses a remote T3 server.
4. Desktop establishes local port forwarding.
5. Renderer connects to the forwarded WebSocket endpoint as a normal environment.

### 3. Client-managed local publish

This is the inverse of remote launch: a local T3 server is already running, and the client publishes it through a tunnel.

This is useful for:

- exposing a desktop-hosted environment to mobile
- temporary remote access without changing router or firewall settings

This is still a launch concern, not a new environment kind.

## Why access and launch must stay separate

These concerns are easy to conflate, but separating them prevents architectural drift.

Examples:

- A manually hosted T3 server might be reached through direct `wss`.
- The same server might also be reachable through a tunnel.
- An SSH-managed server might be launched over SSH but then reached through forwarded WebSocket.
- A local desktop server might be published through a tunnel for mobile.

In all of those cases, the `ExecutionEnvironment` is the same kind of thing.

Only the launch and access paths differ.

## Security model

Remote support must assume that some environments will be reachable over untrusted networks.

That means:

- remote-capable environments should require explicit authentication
- tunnel exposure should not rely on obscurity
- client-saved endpoints should carry enough auth metadata to reconnect safely

T3 already supports a WebSocket auth token on the server. That should become a first-class part of environment access rather than remaining an incidental query parameter convention.

For publicly reachable environments, authenticated access should be treated as required.

## Relationship to Zed

Zed is a useful reference implementation for managed remote launch and reconnect behavior.

The relevant lessons are:

- remote bootstrap should be explicit
- reconnect should be first-class
- connection UX belongs in the client shell
- runtime ownership should stay clearly on the remote host

The important mismatch is transport shape.

Zed needs a custom proxy/server protocol because its remote boundary sits below the editor and project runtime.

T3 should not copy that part.

T3 already has the right runtime boundary:

- one T3 server per environment
- ordinary HTTP/WebSocket between client and environment

So T3 should borrow Zed's launch discipline, not its transport protocol.

## Recommended rollout

1. First-class known environments and access endpoints.
2. Direct `ws` / `wss` remote environments.
3. Authenticated tunnel-backed environments.
4. Desktop-managed SSH launch and forwarding.
5. Multi-environment UI improvements after the base runtime path is proven.

This ordering keeps the architecture network-first and transport-agnostic while still leaving room for richer managed remote flows.
7 changes: 6 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
quality:
name: Format, Lint, Typecheck, Test, Browser Test, Build
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
Expand Down Expand Up @@ -71,11 +72,12 @@ jobs:
- name: Verify preload bundle output
run: |
test -f apps/desktop/dist-electron/preload.js
grep -nE "desktopBridge|getWsUrl|PICK_FOLDER_CHANNEL|wsUrl" apps/desktop/dist-electron/preload.js
grep -nE "desktopBridge|getLocalEnvironmentBootstrap|PICK_FOLDER_CHANNEL|wsUrl" apps/desktop/dist-electron/preload.js

release_smoke:
name: Release Smoke
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
Expand All @@ -90,5 +92,8 @@ jobs:
with:
node-version-file: package.json

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Exercise release-only workflow steps
run: node scripts/release-smoke.ts
Loading
Loading