t3code Teardown — ideas & philosophies for TED OS
:::note Contenido en inglés Esta página del wiki se sincroniza desde la base de conocimiento en inglés y todavía no está traducida. :::
reference· tech-lead · updated 2026-06-28 · source
What this is: research/reference on
pingdotgg/t3code(MIT, v0.0.27, ~12.4k★, "very early WIP") — a web+desktop GUI for coding agents (Codex, Claude Code, OpenCode). It documents what t3code does and which patterns are worth it for TED OS. It is NOT a plan (plans live inapps/admin/src/plans/, see.claude/rules/plan-output-format.md); the "candidate adoptions" in §9 are inputs for filing issues, not a delivery contract. Why it matters: it's the external reference closest to what TED OS wants to be — an agent layer with streaming, "the client keeps the OS in their own domain", a monorepo with contracts, and "built by agents". t3code is a CLI/dev-layer (the kit's category, teams that build); TED OS is a visual/ops-layer (businesses that operate). Hence: steal philosophy and runtime patterns, not the product. Method: scanned via raw GitHub + contents API (the sandbox can't clone). Read: README, AGENTS.md, CLAUDE.md, CONTRIBUTING.md, REMOTE.md, root + every package.json,contracts/src/index.ts, the ~40 subpath exports ofshared,KeyedCoalescingWorker.ts+DrainableWorker.ts(in full), the 7 workflows in.github/workflows,VOUCHED.td, the fullscripts/,infra/, and the entire logic layer ofapps/web/src.
Legend
- [C] Confirmed — read directly in the repo.
- [I] Inferred — deduced from shape (exports/deps/names) without reading the implementation.
- [→] — mapping/idea toward TED OS (candidate, not a filed task).
1. Repo architecture [C]
Monorepo pnpm + Turbo-less (vite-plus vp as the runner) with scope @t3tools/*. Workspaces: apps/*, infra/*, packages/*, oxlint-plugin-t3code, scripts.
| Workspace | Role | Key stack |
|---|---|---|
apps/server (npm: t3) | WS server that wraps the agent CLIs; serves the web app; manages provider sessions | @anthropic-ai/claude-agent-sdk, @opencode-ai/sdk, effect-codex-app-server, effect-acp, node-pty, @effect/sql-sqlite-bun, Effect |
apps/web | React UI (sessions, streaming, state) | React 19 + react-compiler, @effect/atom-react + zustand + TanStack Query/Router/Pacer, @legendapp/list, @xterm/xterm, Lexical, @dnd-kit, @base-ui/react, Tailwind v4 |
apps/desktop | Electron packaging (brew/winget/AUR) | electron-builder, auto-updater |
apps/marketing | Site | Astro |
apps/mobile | Mobile app | Expo / EAS, React Native |
packages/contracts | Schema-only for the protocol (no runtime) | effect only; ~30 domain modules |
packages/shared | Server+client runtime utilities, strict subpath exports, no barrel | ~40 exports; @noble/*, jose, yaml |
packages/client-runtime | Platform-agnostic client code (web ↔ RN) | no UI deps |
infra/relay | Remote-connection relay | Cloudflare Workers + Alchemy + PlanetScale + Axiom |
oxlint-plugin-t3code | Custom lint plugin that enforces their conventions | oxlint |
scripts | Dev/release tooling, each script with a .test.ts | Effect, node |
Transferable structural philosophies:
- [C]
contractsschema-only is the center of the repo. The protocol is defined once and server+web both consume it. [→] TED OS has no@tedos/contractsyet. When anything real-time goes live (runs, automations, chat), apackages/contractsis born with the schemas before server and UI invent divergent shapes. - [C]
sharedhas no barrel index, explicit subpath exports. [→] Same discipline for a future@tedos/shared: real tree-shaking, small bundles. - [C] apps depend on packages, never the reverse. ✅ already aligned with
monorepo-turbo.md. - [C] separate
client-runtimewithexports.react-native. [→] If there's ever a mobile panel, it avoids duplicating logic.
2. Agent-GUI UX patterns → Agent / Automations / ChatPanel / Memory
- [C] The composer is a primitive, not a
<textarea>. Logic extracted from the editor and tested separately. [→] The ChatPanel and any "instruct an agent" flow should treat the composer as a primitive with tokens (mention client, skill, file). - [C] Event feeds = virtualized lists + terminal + markdown (
@legendapp/list,@xterm/xterm). [→] The "live activity feed" and the "run timeline" should assume thousands of streaming events → virtualization from day 1. - [C] Typed event model + recovery (
orchestrationRecovery,pendingUserInput,proposedPlan). [→] Before painting Agent, define the event schema (run.started,tool.called,output.delta,run.finished|failed) and recovery if the stream is cut. - [C]
toolActivity+agentAwarenessmodel "what the agent is doing now". [→] "Meet your employee" wins with live state ("reading Sheets…") instead of a spinner. - [C] Keyboard-first (keymap as versioned data). [→] Reinforces "⌘K instant".
- [C] DnD with
@dnd-kit/sortable. [→] Reference for the drag-snap-to-grid of Grid v2.
3. Streaming reliability — la extracción de mayor leverage
[C] "1. Performance first. 2. Reliability first. Keep behavior predictable under load and during failures (session restarts, reconnects, partial streams). Choose correctness and robustness over short-term convenience."
- [C]
KeyedCoalescingWorker— a per-key queue that keeps only the latest value; enqueues onto an active key are merged atomically;drainKey()resolves when there's no work left. [→] Coalescing updates byrunId/orgIdavoids repainting 200×/sec and zombie states. - [C]
DrainableWorker—drain()resolves when the queue is empty AND the current item has finished. [→] Deterministic testing: the QA agent waits for an "idle/drained signal", not timeouts.
Distilled principles (without Effect):
- Design for reconnection, not the happy path.
- Idempotency + per-key coalescing > processing every event.
- Failure states are part of the contract down to the runtime.
- Correctness > convenience as a written tie-breaker. [→] Candidate for a "runtime principles" ADR.
4. Testing & build tooling [C]
- [C] Massive test co-location (even build/release scripts). [→] Logic is extracted into pure testable modules → fewer Auto-Dev turns debugging.
- [C] VoidZero toolchain:
vite-plus,tsgo(TS in Go), react-compiler,@tanstack/react-pacer,msw. [→] Don't migrate tovp; adopttsgofor typecheck and react-compiler inapps/admin. - [C]
oxlint-plugin-t3code— a custom lint that enforces conventions. [→] Encodeadmin-ui-conventions,icons,color-scope,grid-systeminto anoxlint-plugin-tedos→ turns the 40 arbitrary values into an automatic gate.
5. "Built by agents" workflow [C]
- [C]
CLAUDE.md→ just points toAGENTS.md(single source). [→] "one canonical + the other a reference" avoids drift. - [C] "Task Completion Requirements" (
vp check+ typecheck MUST pass). [→] An explicit per-file "completion gate" is good for Auto-Dev. - [C]
.repos/vendored reference repos (read-only) + sync script. [→] Vendor reference repos (SDKs, Clerk/Drizzle examples) as read-only context → less hallucination. $0, aligned with local-delegate + MemPalace. - [C] CONTRIBUTING: small PRs, before/after image for UI, video for motion. [→] Idea to steal: require before/after + video on UI PRs (design-routing step 4). Candidate for the PR template.
6. Remote / pairing model → "the client keeps the OS in their own domain" [C]
- Pairing with no persistent secret: one-time owner token → authenticated session; QR + pairing URL.
- Tailscale/tailnet as the trust mesh; LAN/loopback/HTTPS/MagicDNS endpoints.
- Hosted web pairing with the token in the hash (not sent to the server).
- Security: DPoP, JWT, OAuth scope, Ed25519 (
@noble/*);t3 authrevokes sessions.
[→] The MVP uses Clerk Orgs + custom domain (perfect for web). When desktop/Tauri unpauses, token pairing + signed relay + optional Tailscale is the blueprint. DPoP and token-in-the-hash harden the tenant boundary and the invite/pairing links.
7. Workflow: CI, PRs & Deploys [C]
- [C]
vouch:*= the builder network made into CI.VOUCHED.tdtrust list; write collaborators = trusted; outsiders =unvoucheduntil added. [→] THIS is "new builder probation" (MVP §10). AdoptVOUCHED.tdto distinguish agents/José (fast-lane) from new builders. - [C]
size:*excludes tests in mixed PRs. [→]size:XL = hard stopis fairer if it doesn't penalize tests. - [C] Security in
pull_request_target(untrusted PR as passive git data — no installs/build). [→] Label fork PRs without running their code. - [C]
release.yml9-job DAG, stable + nightly channels,release-smokeon EVERY PR, Vercel deploy + alias per channel/domain, code signing (Apple + Azure Trusted Signing), npm provenance, GitHub App token, Environments for secrets, graceful degradation, concurrency discipline.- [→] Vercel deploy + alias per org = direct foundation for custom-domain-per-client.
release-smokeper PR = smoke test of the report generator + onboarding. GitHub App token fixes "GITHUB_TOKEN doesn't re-trigger workflows". Azure Trusted Signing confirmstedos-product-decisions §8.
- [→] Vercel deploy + alias per org = direct foundation for custom-domain-per-client.
8. What NOT to copy (honest mismatches)
| What t3code does | Why it doesn't fit (yet) |
|---|---|
| Effect 4 (beta) everywhere | The TED stack is React/Next/Drizzle. Steal patterns, not Effect |
| SQLite local-first | TED is multi-tenant cloud (Neon + org_id) |
| vite-plus / bun runtime | Beta. Take tsgo + react-compiler, not the runner |
infra/relay Cloudflare+Alchemy | TED's MVP is Vercel+Neon. Take channels/environments, not the stack |
@base-ui/react | You already chose shadcn |
| desktop/mobile build matrix | Desktop/Tauri paused; mobile off the roadmap |
| "Not accepting contributions" | The builder network is the opposite: curated contribution |
9. Candidate adoptions (inputs for tickets — NOT a contract)
| # | Idea | Lands in | Effort | When |
|---|---|---|---|---|
| 1 | tsgo for typecheck | package.json tc + monorepo-turbo | S | Now |
| 2 | react-compiler in apps/admin | frontend-guardrails | S | Now |
| 3 | PR template: before/after + motion video | PR template / design-routing | S | Now |
| 4 | size:* that excludes tests | pr-labeler | S | Now |
| 5 | GitHub App token for workflows | bots | S | Now |
| 6 | Runtime principles ADR (correctness>convenience, coalescing, drain, reconnection) | new ADR | S | Now |
| 7 | VOUCHED.td + vouch labels | .github/ + probation | S | Before cohort 1 |
| 8 | .repos/ vendored reference repos + sync | .claude/ + script | M | Soon ($0 anti-hallucination) |
| 9 | oxlint-plugin-tedos (tokens/HugeIcons/grid/color) | new plugin + CI | M | Pays down the 40-arbitrary debt |
| 10 | Composer with tokens (slash/@-mention) | ChatPanel / Agent | M | When ChatPanel leaves the flag |
| 11 | @tedos/contracts: run event schema | Automations / State | M | Before real runs |
| 12 | Virtualized feeds | State + Automations | M | When the feed is real |
| 13 | release-smoke on EVERY PR | CI + report generator | M | When the generator exists |
| 14 | Vercel deploy + alias per domain (custom-domain-per-client) | MVP §8 + DevOps | M | Day 0–30 |
| 15 | Live toolActivity ("reading Sheets…") | Agent screen | M | Demo polish |
| 16 | Token pairing + DPoP + Tailscale | Desktop/Tauri on unpause | L | Post-MVP |
The synthesis: "Drop" — intake/review console (dogfood-first)
A console where a submitter (Auto-Dev agent, José, or a builder) sends an artifact and the console runs checks (oxlint-plugin-tedos), streams them live (t3code run style), shows before/after + diff, and allows accept/comment/reject with provenance. José dogfoods it first by reviewing his agents' output against the design system — zero builders needed. v0 = CLI/skill (/kit-drop-check); v1 = a console in apps/admin once the first client closes.
Appendix — source
Repo: https://github.com/pingdotgg/t3code — README, AGENTS.md, CLAUDE.md, CONTRIBUTING.md, REMOTE.md, package.json (all), contracts/src/index.ts, shared KeyedCoalescingWorker/DrainableWorker, the 7 .github/workflows, VOUCHED.td, scripts/, infra/, apps/web/src.