Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .github/actions/setup-apt-mirrors/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ runs:
steps:
- shell: bash
run: |
# GitHub-hosted fork runners use their supplied APT sources.
if ! test -f /etc/apt/blacksmith-ubuntu-mirrors.txt; then
exit 0
fi

# Replace the existing Blacksmith mirror list as well as direct sources.
printf '%s\tpriority:%s\n' \
https://archive.ubuntu.com/ubuntu 1 \
Expand Down
26 changes: 17 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ concurrency:
jobs:
check:
name: Check
runs-on: blacksmith-8vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
timeout-minutes: 10
steps:
- name: Checkout
Expand Down Expand Up @@ -59,7 +59,11 @@ jobs:

- name: Install browser secret helper build libraries
run: |
sudo sed -i 's|http://|https://|g' /etc/apt/blacksmith-ubuntu-mirrors.txt /etc/apt/sources.list.d/ubuntu.sources
for source in /etc/apt/blacksmith-ubuntu-mirrors.txt /etc/apt/sources.list.d/ubuntu.sources; do
if test -f "$source"; then
sudo sed -i 's|http://|https://|g' "$source"
fi
done
sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config

- name: Build desktop pipeline
Expand All @@ -75,7 +79,7 @@ jobs:
# limit stays at the default 4 so peak load per runner is unchanged.
test:
name: Test
runs-on: blacksmith-8vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
timeout-minutes: 10
steps:
- name: Checkout
Expand All @@ -100,7 +104,11 @@ jobs:

- name: Install browser secret helper build libraries
run: |
sudo sed -i 's|http://|https://|g' /etc/apt/blacksmith-ubuntu-mirrors.txt /etc/apt/sources.list.d/ubuntu.sources
for source in /etc/apt/blacksmith-ubuntu-mirrors.txt /etc/apt/sources.list.d/ubuntu.sources; do
if test -f "$source"; then
sudo sed -i 's|http://|https://|g' "$source"
fi
done
sudo apt-get update && sudo apt-get install -y libsecret-1-dev pkg-config

- name: Test preview artifact validation
Expand All @@ -118,7 +126,7 @@ jobs:
# isolation that flag buys is preserved exactly.
test_server:
name: Test Server ${{ matrix.shard }}
runs-on: blacksmith-8vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
timeout-minutes: 10
strategy:
fail-fast: false
Expand Down Expand Up @@ -185,7 +193,7 @@ jobs:
# for checks that take under 3s, on the critical path of every PR.
rust:
name: Rust
runs-on: blacksmith-4vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-4vcpu-ubuntu-2404' }}
timeout-minutes: 10
steps:
- name: Checkout
Expand Down Expand Up @@ -219,7 +227,7 @@ jobs:
# the diff cannot be resolved, the lint runs.
mobile_native_changes:
name: Mobile Native Changes
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-2vcpu-ubuntu-2404' }}
timeout-minutes: 5
permissions:
contents: read
Expand Down Expand Up @@ -297,7 +305,7 @@ jobs:
# Skip only on an explicit "no": a gate job that failed or errored leaves the
# output empty, and that must run the lint rather than silently skip it.
if: ${{ !cancelled() && needs.mobile_native_changes.outputs.changed != 'false' }}
runs-on: blacksmith-6vcpu-macos-26
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'macos-26' || 'blacksmith-6vcpu-macos-26' }}
timeout-minutes: 10
steps:
- name: Checkout
Expand Down Expand Up @@ -325,7 +333,7 @@ jobs:

release_smoke:
name: Release Smoke
runs-on: blacksmith-8vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
timeout-minutes: 10
steps:
- name: Checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/mobile-fingerprint-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ concurrency:
jobs:
fingerprint:
name: Native fingerprint diff
runs-on: blacksmith-8vcpu-ubuntu-2404
runs-on: ${{ github.repository == 'matsvarn/t3code' && 'ubuntu-24.04' || 'blacksmith-8vcpu-ubuntu-2404' }}
permissions:
contents: read
issues: write
Expand Down
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@ The most common defect in this repo is a change that works on the path you teste

## Dev servers

- `vp i` installs. Worktrees get this from the t3.json setup script; if module resolution looks broken, it probably did not run.
- `bash scripts/setup.sh` installs through `vp i --frozen-lockfile` and warms the web dependency cache on macOS and Linux. Import the `t3.json` actions for each project/environment. Setup Worktree waits before the agent starts. It does not start servers or link credentials.
- `vp run dev` starts server and web. In a worktree, state defaults to that worktree's gitignored `.t3`, which deliberately outranks an ambient `T3CODE_HOME` so you cannot land on shared state by accident. An explicit `--home-dir` still wins.
- Ports derive from the worktree path and are stable across restarts, but read the real ones from the `[dev-runner]` line since occupied ports shift.
- Sharing over the tailnet is three steps: run `vp run dev --share` in the background, wait for the `pairingUrl:` line in its output, then give that full URL to an unpaired browser. Do not wire up `tailscale serve` by hand, open the URL yourself, or consume the user's pairing link. A browser with the reusable dev cookie can use the bare origin. If a normal one-time token was consumed, mint a fresh one with `node apps/server/src/bin.ts pair`. It carries standard scopes, while the startup URL carries admin scopes needed for Connections settings.
- To reuse web dev auth across worktrees, configure one fixed `T3CODE_DEV_AUTH_TOKEN` in the main checkout's gitignored `.env`. The `t3.json` setup links that file into worktrees. Never commit or publish the token or a startup URL. See [Reusable dev credential](docs/operations/development.md#reusable-dev-credential).
- Reusable web dev auth is an explicit opt-in. Automatic setup leaves `.env` and relay credentials alone. Configure the environment for that checkout only when needed, and never commit or publish a token or startup URL. See [Reusable dev credential](docs/operations/development.md#reusable-dev-credential).
- Give independent work separate branches and worktrees. Keep dependencies, state and test outputs in each checkout. Transfer commits across machines with Git; project grouping does not synchronize files. The manual Check setup and dev isolation action runs the scripts typecheck and dev-runner tests; CI owns the full suite.
- Stop what you started, by the PID you tracked. See rule 1.

## Test data
Expand Down
15 changes: 10 additions & 5 deletions docs/operations/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
## First checkout

Install `vp` using the [root README](../../README.md#install-vp). The checkout requires Node 24;
Bun is optional. From the repository root:
Bun is optional. Linux also needs C/C++ build tools and Python 3 for node-pty. On Ubuntu or Debian, install them once with `sudo apt-get install build-essential python3`. Setup reports missing tools and never runs sudo. From the repository root:

```sh
vp i
bash scripts/setup.sh
vp run dev
```

Setup also recognizes the standard Vite+ install paths when an IDE has an older PATH. Install the host tool separately with the README command; setup never installs it for you.

Setup uses the frozen native lockfile and warms each checkout's web cache. It leaves credentials and databases alone. Import `t3.json` actions into each project/environment to run Setup Worktree automatically and wait before the agent starts. The existing Windows setup remains a manual action and has not been verified here.

Open the pairing URL printed by the dev runner. The bare origin does not authenticate
a new browser.

Expand Down Expand Up @@ -76,9 +80,10 @@ Put that value in the main checkout's gitignored `.env`:
T3CODE_DEV_AUTH_TOKEN=<the value generated above>
```

The `t3.json` Setup Worktree commands on Unix and Windows link that file to each worktree's
`.env`. The dev runner reads repository env files at startup. `.env.local` and inherited process
environment values override `.env`, so no per-worktree export is needed after setup.
Automatic Unix setup does not link this file or relay credentials. Reusing credentials
requires an explicit per-checkout choice. The manual Windows action retains its existing
links. The dev runner reads repository env files at startup; `.env.local` and inherited
process environment values override `.env`.

For a manual worktree or launcher without that link, export the same fixed value instead:

Expand Down
28 changes: 28 additions & 0 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

if ! command -v vp >/dev/null 2>&1; then
export PATH="$HOME/.local/share/vite-plus/bin:$HOME/.vite-plus/bin:$PATH"
fi

if ! command -v vp >/dev/null 2>&1; then
echo "Vite+ is required. Install it with: curl -fsSL https://vite.plus | bash" >&2
echo "Then open a new terminal and run bash scripts/setup.sh again." >&2
exit 1
fi

if [[ "$(uname -s)" == "Linux" ]]; then
for tool in make g++ python3; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "Linux node-pty requires make, g++ and Python 3." >&2
echo "Ubuntu/Debian: sudo apt-get install build-essential python3" >&2
echo "Install host prerequisites separately, then run setup again." >&2
exit 1
fi
done
fi

vp i --frozen-lockfile
node apps/web/scripts/warm-dep-cache.ts
16 changes: 12 additions & 4 deletions t3.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@
"scripts": [
{
"name": "Setup Worktree",
"command": "vp i && ln -sf $T3CODE_PROJECT_ROOT/.env .env && ln -sf $T3CODE_PROJECT_ROOT/infra/relay/.env infra/relay/.env && node apps/web/scripts/warm-dep-cache.ts",
"command": "bash scripts/setup.sh",
"icon": "configure",
"runOnWorktreeCreate": true
"runOnWorktreeCreate": true,
"async": false
},
{
"name": "Setup Worktree (Windows)",
"command": "vp i && New-Item -ItemType SymbolicLink -Path .env -Target \"$env:T3CODE_PROJECT_ROOT\\.env\" -Force && New-Item -ItemType SymbolicLink -Path \"infra\\relay\\.env\" -Target \"$env:T3CODE_PROJECT_ROOT\\infra\\relay\\.env\" -Force && node apps\\web\\scripts\\warm-dep-cache.ts",
"icon": "configure",
"runOnWorktreeCreate": true
"runOnWorktreeCreate": false
},
{
"name": "Check setup and dev isolation",
"command": "export PATH=\"$HOME/.local/share/vite-plus/bin:$HOME/.vite-plus/bin:$PATH\"; vp run --filter @t3tools/scripts typecheck && vp test run scripts/dev-runner.test.ts",
"icon": "test",
"runOnWorktreeCreate": false
}
]
],
"defaultThreadEnvMode": "worktree"
}
Loading