Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .docs/provider-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The web app communicates with the server via WebSocket using a simple JSON-RPC-s

Push channels: `server.welcome`, `server.configUpdated`, `terminal.event`, `orchestration.domainEvent`. Payloads are schema-validated at the transport boundary (`wsTransport.ts`). Decode failures produce structured `WsDecodeDiagnostic` with `code`, `reason`, and path info.

Methods mirror the `NativeApi` interface defined in `@t3tools/contracts`:
Methods mirror the `NativeApi` interface defined in `@tero/contracts`:

- `providers.startSession`, `providers.sendTurn`, `providers.interruptTurn`
- `providers.respondToRequest`, `providers.stopSession`
Expand Down
2 changes: 1 addition & 1 deletion .docs/workspace-layout.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
- `/apps/web`: React + Vite UI. Session control, conversation, and provider event rendering. Connects to the server via WebSocket.
- `/apps/desktop`: Electron shell. Spawns a desktop-scoped `t3` backend process and loads the shared web app.
- `/packages/contracts`: Shared effect/Schema schemas and TypeScript contracts for provider events, WebSocket protocol, and model/session types.
- `/packages/shared`: Shared runtime utilities consumed by both server and web. Uses explicit subpath exports (e.g. `@t3tools/shared/git`, `@t3tools/shared/DrainableWorker`) — no barrel index.
- `/packages/shared`: Shared runtime utilities consumed by both server and web. Uses explicit subpath exports (e.g. `@tero/shared/git`, `@tero/shared/DrainableWorker`) — no barrel index.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ jobs:
run: node scripts/update-release-package-versions.ts "${{ needs.preflight.outputs.version }}"

- name: Build CLI package
run: bun run build --filter=@t3tools/web --filter=t3
run: bun run build --filter=@tero/web --filter=t3

- name: Publish CLI package
run: node apps/server/scripts/cli.ts publish --tag latest --app-version "${{ needs.preflight.outputs.version }}" --verbose
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ packages/*/dist
build/
.logs/
release/
.t3
.tero
.idea/
apps/web/.playwright
apps/web/playwright-report
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ Long term maintainability is a core priority. If you add new functionality, firs
- `apps/server`: Node.js WebSocket server. Wraps Codex app-server (JSON-RPC over stdio), serves the React web app, and manages provider sessions.
- `apps/web`: React/Vite UI. Owns session UX, conversation/event rendering, and client-side state. Connects to the server via WebSocket.
- `packages/contracts`: Shared effect/Schema schemas and TypeScript contracts for provider events, WebSocket protocol, and model/session types. Keep this package schema-only — no runtime logic.
- `packages/shared`: Shared runtime utilities consumed by both server and web. Uses explicit subpath exports (e.g. `@t3tools/shared/git`) — no barrel index.
- `packages/shared`: Shared runtime utilities consumed by both server and web. Uses explicit subpath exports (e.g. `@tero/shared/git`) — no barrel index.

## Codex App Server (Important)

Expand Down
448 changes: 448 additions & 0 deletions CURRENT-TASK.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion KEYBINDINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

T3 Code reads keybindings from:

- `~/.t3/keybindings.json`
- `~/.tero/keybindings.json`

The file must be a JSON array of rules:

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ T3 Code is a minimal web GUI for coding agents (currently Codex and Claude, more
> You need to have [Codex CLI](https://github.com/openai/codex) installed and authorized for T3 Code to work.

```bash
npx t3
npx tero
```

You can also just install the desktop app. It's cooler.
Expand Down
12 changes: 6 additions & 6 deletions REMOTE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ The T3 Code CLI accepts the following configuration options, available either as

| CLI flag | Env var | Notes |
| ----------------------- | --------------------- | ---------------------------------- |
| `--mode <web\|desktop>` | `T3CODE_MODE` | Runtime mode. |
| `--port <number>` | `T3CODE_PORT` | HTTP/WebSocket port. |
| `--host <address>` | `T3CODE_HOST` | Bind interface/address. |
| `--base-dir <path>` | `T3CODE_HOME` | Base directory. |
| `--mode <web\|desktop>` | `TERO_MODE` | Runtime mode. |
| `--port <number>` | `TERO_PORT` | HTTP/WebSocket port. |
| `--host <address>` | `TERO_HOST` | Bind interface/address. |
| `--base-dir <path>` | `TERO_HOME` | Base directory. |
| `--dev-url <url>` | `VITE_DEV_SERVER_URL` | Dev web URL redirect/proxy target. |
| `--no-browser` | `T3CODE_NO_BROWSER` | Disable auto-open browser. |
| `--auth-token <token>` | `T3CODE_AUTH_TOKEN` | WebSocket auth token. |
| `--no-browser` | `TERO_NO_BROWSER` | Disable auto-open browser. |
| `--auth-token <token>` | `TERO_AUTH_TOKEN` | WebSocket auth token. |

> TIP: Use the `--help` flag to see all available options and their descriptions.

Expand Down
23 changes: 12 additions & 11 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# TODO

## Small things

- [ ] Submitting new messages should scroll to bottom
- [ ] Only show last 10 threads for a given project
- [ ] Thread archiving
- [ ] New projects should go on top
- [ ] Projects should be sorted by latest thread update

## Bigger things

- [ ] Queueing messages
- Fix broken runtime workspace-package resolution for local entrypoints.
- Current symptom: scripts and desktop runtime code cannot reliably import workspace packages such as `@tero/shared` at runtime in this checkout.
- Evidence:
- `scripts/dev-runner.ts` failed to resolve `@tero/shared/Net`
- desktop runtime previously failed to resolve `@tero/shared/Net` and related shared imports
- Current workaround:
- some runtime imports were switched to direct repo-relative paths
- Desired fix:
- restore a proper workspace/runtime linking story so local Node/Electron entrypoints can use workspace package imports without repo-relative fallbacks
- Why it matters:
- this is separate from the T3 Code state-poisoning issue
- it makes local dev fragile and forces temporary path hacks into runtime entrypoints
8 changes: 4 additions & 4 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@t3tools/desktop",
"name": "@tero/desktop",
"version": "0.0.14",
"private": true,
"main": "dist-electron/main.js",
Expand All @@ -19,13 +19,13 @@
"electron-updater": "^6.6.2"
},
"devDependencies": {
"@t3tools/contracts": "workspace:*",
"@t3tools/shared": "workspace:*",
"@tero/contracts": "workspace:*",
"@tero/shared": "workspace:*",
"@types/node": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:",
"wait-on": "^8.0.2"
},
"productName": "T3 Code (Alpha)"
"productName": "Tero (Alpha)"
}
7 changes: 5 additions & 2 deletions apps/desktop/scripts/dev-electron.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ await waitOn({

const childEnv = { ...process.env };
delete childEnv.ELECTRON_RUN_AS_NODE;
process.env.TERO_DESKTOP_LOCAL_DEV = "1";

let shuttingDown = false;
let restartTimer = null;
Expand All @@ -47,7 +48,7 @@ function cleanupStaleDevApps() {
return;
}

spawnSync("pkill", ["-f", "--", `--t3code-dev-root=${desktopDir}`], { stdio: "ignore" });
spawnSync("pkill", ["-f", "--", `--tero-dev-root=${desktopDir}`], { stdio: "ignore" });
}

function startApp() {
Expand All @@ -57,11 +58,13 @@ function startApp() {

const app = spawn(
resolveElectronPath(),
[`--t3code-dev-root=${desktopDir}`, "dist-electron/main.js"],
["--tero-local-dev", `--tero-dev-root=${desktopDir}`, "dist-electron/main.js"],
{
cwd: desktopDir,
env: {
...childEnv,
TERO_DESKTOP_LOCAL_DEV: "1",
TERO_DESKTOP_SERVER_EXECUTABLE: process.execPath,
VITE_DEV_SERVER_URL: devServerUrl,
},
stdio: "inherit",
Expand Down
10 changes: 7 additions & 3 deletions apps/desktop/scripts/electron-launcher.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// This file mostly exists because we want dev mode to say "T3 Code (Dev)" instead of "electron"
// This file mostly exists because we want dev mode to say "Tero (Dev)" instead of "electron"

import { spawnSync } from "node:child_process";
import {
Expand All @@ -17,8 +17,8 @@ import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const isDevelopment = Boolean(process.env.VITE_DEV_SERVER_URL);
const APP_DISPLAY_NAME = isDevelopment ? "T3 Code (Dev)" : "T3 Code (Alpha)";
const APP_BUNDLE_ID = "com.t3tools.t3code";
const APP_DISPLAY_NAME = isDevelopment ? "Tero (Dev)" : "Tero (Alpha)";
const APP_BUNDLE_ID = "com.tero.desktop";
const LAUNCHER_VERSION = 1;

const __dirname = dirname(fileURLToPath(import.meta.url));
Expand Down Expand Up @@ -140,5 +140,9 @@ export function resolveElectronPath() {
return electronBinaryPath;
}

if (process.env.TERO_DESKTOP_LOCAL_DEV === "1") {
return electronBinaryPath;
}

return buildMacLauncher(electronBinaryPath);
}
7 changes: 6 additions & 1 deletion apps/desktop/scripts/start-electron.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@ import { desktopDir, resolveElectronPath } from "./electron-launcher.mjs";

const childEnv = { ...process.env };
delete childEnv.ELECTRON_RUN_AS_NODE;
process.env.TERO_DESKTOP_LOCAL_DEV = "1";

const child = spawn(resolveElectronPath(), ["dist-electron/main.js"], {
stdio: "inherit",
cwd: desktopDir,
env: childEnv,
env: {
...childEnv,
TERO_DESKTOP_LOCAL_DEV: "1",
TERO_DESKTOP_SERVER_EXECUTABLE: process.execPath,
},
});

child.on("exit", (code, signal) => {
Expand Down
Loading