Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
beab688
fix(web): import dependency-heavy Open VSX themes (#7642)
t3-code[bot] Aug 20, 2026
8824f8f
fix(web): retry failed thread bootstraps with a fresh id (#7664)
SunkenInTime Aug 20, 2026
21e80a0
fix(web): copy terminal selection instead of a blank clipboard (#7678)
sethwebster Aug 20, 2026
aa17ec6
revert(web): restore sparse hourly usage breakdown (#7718)
t3-code[bot] Aug 20, 2026
0929907
fix(server): reconcile orphaned provider sessions (#7719)
t3-code[bot] Aug 20, 2026
490f48e
fix(web): fix subagent row left border being cut off (#7207)
sameerr03 Aug 20, 2026
cd14b3e
fix(web): unify composer control rounding (#5957)
kototok903 Aug 20, 2026
5ff5f73
fix(web): show pointer on add project button (#5545)
incognitojam Aug 20, 2026
730ce9e
fix(server): enable the Cursor provider by default like every other p…
Rishet11 Aug 20, 2026
1afe554
fix(web): fix thread jumping after reorder (#7103)
ipanasenko Aug 20, 2026
4bdbd8c
fix(server): keep Daybreak models out of legacy models (#7659)
cn0ss Aug 20, 2026
fe87502
fix(contracts): reconcile provider default tests (#7725)
t3-code[bot] Aug 20, 2026
f0fb83a
fix(web): polish theme library buttons, search, and import dialog (#7…
UtkarshUsername Aug 20, 2026
7107a98
chore: vouch Seth Webster and pcstyle (#7728)
t3dotgg Aug 20, 2026
68966c1
fix(web): add space above composer task tabs (#7740)
Bil0000 Aug 21, 2026
e723501
feat(composer): list skills with slash commands (#7737)
maria-rcks Aug 21, 2026
6d3bf01
fix(web): show the full path in file link tooltips (#7741)
s243a Aug 21, 2026
820e563
fix(server): serve html assets with utf-8 charset (#6409)
talkingdonkeyz Aug 21, 2026
12c4970
fix(vcs): give `git worktree add` a longer timeout on large repos (#6…
ChamaruAmasara Aug 21, 2026
9167622
chore: move implementation plans out of repository (#7665)
t3-code[bot] Aug 21, 2026
45a2c4b
Update user count in AGENTS.md (#7658)
saphid Aug 21, 2026
20e5a33
fix(desktop): restrict editor deep links (#7697)
Lucenx9 Aug 21, 2026
6d5c6c4
fix(web): prevent pinned threads reshuffling after drop (#7676)
tarik02 Aug 21, 2026
18f6d03
fix(web): encode shifted characters correctly in the terminal (#7485)
chrisdeeming Aug 21, 2026
f3fcfe1
fix(web): resolve sidebar provider icons from the thread's own enviro…
vitalyiegorov Aug 21, 2026
ce8ca5b
fix(web): hide thread jump hints while the terminal is focused (#7277)
lnieuwenhuis Aug 21, 2026
e2697d6
fix(web): keep following the stream after scrolling back to the live …
lnieuwenhuis Aug 21, 2026
d7b9a68
perf(ci): parallelize the test suite and split out Rust checks (#7286)
t3dotgg Aug 21, 2026
8f7da3b
ci: only boot the macOS native lint runner when native sources change…
t3dotgg Aug 21, 2026
9f12eab
chore: stop committing pull request assets (#7762)
t3-code[bot] Aug 21, 2026
549201f
fix(clients): default GitHub clones to HTTPS (#7760)
t3-code[bot] Aug 21, 2026
be7d35a
perf(web): stop preview loading rerenders (#7561)
Bil0000 Aug 21, 2026
0a46daa
fix(web): keep messages clear of composer banners (#7792)
Bil0000 Aug 21, 2026
2c08834
Merge remote-tracking branch 'upstream/main' into yordis/chore-sync-u…
yordis Aug 21, 2026
49c1d5b
fix(server): the 1Password secret test typechecks again
yordis Aug 21, 2026
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
21 changes: 14 additions & 7 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,39 @@
#
# Keep entries sorted alphabetically.
github:adityavardhansharma
github:bil0000
github:binbandit
github:chrisdeeming
github:chuks-qua
github:cursoragent
github:eggfriedrice24
github:gbarros-dev
github:gfsaaser24
github:github-actions[bot]
github:gsimone
github:hwanseoc
github:jamesx0416
github:jappyjan
github:jasonLaster
github:JoeEverest
github:justsomelegs
github:mackinleysmith
github:maria-rcks
github:nmggithub
github:Noojuno
github:notkainoa
github:PatrickBauer
github:pc-style
github:RakshithBhat03
github:realAhmedRoach
github:Rishet11
github:saphid
github:sethwebster
github:shiroyasha9
github:shivamhwp
github:StiensWout
github:SunkenInTime
github:tarik02
github:UtkarshUsername
github:Yash-Singh1
github:eggfriedrice24
github:Ymit24
github:shivamhwp
github:jappyjan
github:justsomelegs
github:UtkarshUsername
github:SunkenInTime
github:bil0000
1 change: 0 additions & 1 deletion .github/pr-assets/6424-after.svg

This file was deleted.

1 change: 0 additions & 1 deletion .github/pr-assets/6424-before.svg

This file was deleted.

1 change: 0 additions & 1 deletion .github/pr-assets/6503-after.svg

This file was deleted.

183 changes: 169 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,21 @@ jobs:
!/.repos/
sparse-checkout-cone-mode: false

- name: Reject repository-owned PR assets
run: |
files="$(git ls-files .github/pr-assets)"
if test -n "$files"; then
printf 'PR evidence must be uploaded to GitHub, not committed:\n%s\n' "$files" >&2
exit 1
fi

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Ensure Electron runtime is installed
run: vp run --filter @t3tools/desktop ensure:electron

Expand All @@ -45,9 +48,6 @@ jobs:
- name: Typecheck
run: vpr typecheck

- name: Check resource monitor formatting
run: cargo fmt --manifest-path native/resource-monitor/Cargo.toml -- --check

- name: Build desktop pipeline
run: vp run build:desktop

Expand All @@ -57,6 +57,11 @@ jobs:
grep -nE "desktopBridge|getLocalEnvironmentBootstrap|PICK_FOLDER_CHANNEL|wsUrl" apps/desktop/dist-electron/preload.cjs
grep -n "__clerk_internal_electron_passkeys" apps/desktop/dist-electron/preload.cjs

# Everything except `t3` (apps/server). `--parallel` drops the package
# dependency ordering that `vp run` applies by default: these `test` tasks
# declare no `dependsOn` and resolve workspace deps from source, so ordering
# only bought us idle runners between dependency layers. The concurrency
# limit stays at the default 4 so peak load per runner is unchanged.
test:
name: Test
runs-on: blacksmith-8vcpu-ubuntu-2404
Expand All @@ -77,20 +82,65 @@ jobs:
cache: true
run-install: true

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable

- name: Ensure Electron runtime is installed
run: vp run --filter @t3tools/desktop ensure:electron

- name: Test
run: vp run --parallel --concurrency-limit 4 --filter '!t3' --filter '!@t3tools/monorepo' test

# apps/server sets `fileParallelism: false`, so its 239 files run strictly
# one at a time. Sharding spreads them over separate runners instead of
# separate workers, so no two server test files ever share a machine and the
# isolation that flag buys is preserved exactly.
test_server:
name: Test Server ${{ matrix.shard }}
runs-on: blacksmith-8vcpu-ubuntu-2404
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3]
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Vite+
uses: voidzero-dev/setup-vp@v1
with:
node-version-file: package.json
cache: true
run-install: true

# No Electron setup here: `t3` (apps/server) has no Electron dependency
# and none of its tests touch the runtime. Only the non-server `test`
# job, which covers @t3tools/desktop, needs the download.
- name: Test
env:
T3CODE_TRANSFER_BUDGET_REPORT_PATH: ${{ runner.temp }}/t3code-transfer-budget.md
T3CODE_TRANSFER_BUDGET_RESULT_PATH: ${{ runner.temp }}/thread-transfer-result.json
run: vp run test
run: vp run --filter t3 test --shard ${{ matrix.shard }}/${{ strategy.job-total }}

- name: Publish transfer budget report
# src/server.test.ts writes the budget report, so exactly one shard
# produces these files. Gating the upload on their presence keeps a
# single `thread-transfer-results` artifact per run, which is the name
# thread-transfer-report.yml resolves.
- name: Detect transfer budget report
id: transfer_budget
if: always()
run: |
if test -f "${{ runner.temp }}/thread-transfer-result.json"; then
echo "present=true" >> "$GITHUB_OUTPUT"
else
echo "present=false" >> "$GITHUB_OUTPUT"
fi

- name: Publish transfer budget report
if: always() && steps.transfer_budget.outputs.present == 'true'
run: |
if test -f "${{ runner.temp }}/t3code-transfer-budget.md"; then
tee -a "$GITHUB_STEP_SUMMARY" < "${{ runner.temp }}/t3code-transfer-budget.md"
Expand All @@ -99,19 +149,124 @@ jobs:
fi

- name: Upload thread transfer result
if: always()
if: always() && steps.transfer_budget.outputs.present == 'true'
uses: actions/upload-artifact@v7
with:
name: thread-transfer-results
path: ${{ runner.temp }}/thread-transfer-result.json
if-no-files-found: ignore
retention-days: 30

# Split out of Check and Test: both paid ~7-9s to install a Rust toolchain
# for checks that take under 3s, on the critical path of every PR.
rust:
name: Rust
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v6
with:
sparse-checkout: |
/*
!/.repos/
sparse-checkout-cone-mode: false

- name: Setup Rust
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt

- name: Check resource monitor formatting
run: cargo fmt --manifest-path native/resource-monitor/Cargo.toml -- --check

- name: Test resource monitor
run: cargo test --locked --manifest-path native/resource-monitor/Cargo.toml

# The static analysis below needs a macOS runner, which bills ~6.7x a Linux
# minute, so gate it on the native sources it actually lints instead of paying
# for it on every push. Detection is API-only (no checkout) and fails open: if
# the diff cannot be resolved, the lint runs.
mobile_native_changes:
name: Mobile Native Changes
runs-on: blacksmith-2vcpu-ubuntu-2404
timeout-minutes: 5
permissions:
contents: read
pull-requests: read
outputs:
changed: ${{ steps.detect.outputs.changed }}
steps:
- name: Detect mobile native changes
id: detect
env:
GH_TOKEN: ${{ github.token }}
PR_NUMBER: ${{ github.event.pull_request.number }}
BEFORE_SHA: ${{ github.event.before }}
run: |
set -uo pipefail

fail_open() {
echo "$* Running native static analysis."
echo "changed=true" >> "$GITHUB_OUTPUT"
exit 0
}

count_rows() {
printf '%s\n' "$1" | grep -c . || true
}

# One row per changed file, holding the new path and, for a rename,
# the path it replaced: renaming a matched file out of the matched
# paths removes a lint input just like editing it.
row='[.filename, (.previous_filename // empty)] | @tsv'

if [[ -n "${PR_NUMBER}" ]]; then
# The PR files endpoint stops at 3000 files and pagination cannot
# extend it, so cross-check against the count the PR itself reports.
expected=$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" --jq '.changed_files') \
|| fail_open "Could not read the pull request."
rows=$(gh api "repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}/files" --paginate --jq ".[] | ${row}") \
|| fail_open "Could not resolve changed files."

listed=$(count_rows "$rows")
if [[ "$listed" -lt "$expected" ]]; then
fail_open "GitHub listed only ${listed} of ${expected} changed files."
fi
else
rows=$(gh api "repos/${GITHUB_REPOSITORY}/compare/${BEFORE_SHA}...${GITHUB_SHA}" --jq ".files[]? | ${row}") \
|| fail_open "Could not resolve changed files."

# The compare endpoint reports at most 300 files and pagination does
# not extend that list, so a full list may be hiding native changes.
listed=$(count_rows "$rows")
if [[ "$listed" -ge 300 ]]; then
fail_open "GitHub listed ${listed} changed files, the compare endpoint maximum."
fi
fi

paths=$(tr '\t' '\n' <<< "$rows")

# Sources scripts/mobile-native-static-check.ts lints, plus the tool
# and rule configuration that decides how it lints them, plus the
# root package.json that defines the lint:mobile command.
pattern='^apps/mobile/.*\.(swift|kt|kts)$|^apps/mobile/(\.swiftlint\.yml|detekt\.yml|\.editorconfig|Brewfile)$|^scripts/mobile-native-static-check\.ts$|^package\.json$|^\.github/workflows/ci\.yml$'

if grep -qE "$pattern" <<< "$paths"; then
echo "Native sources or lint configuration changed:"
grep -E "$pattern" <<< "$paths"
echo "changed=true" >> "$GITHUB_OUTPUT"
else
echo "No mobile native sources or lint configuration changed."
echo "changed=false" >> "$GITHUB_OUTPUT"
fi

mobile_native_static_analysis:
name: Mobile Native Static Analysis
needs: mobile_native_changes
# 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
timeout-minutes: 10
steps:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ __screenshots__/
squashfs-root/
.vercel
.gstack/
.plans/
dist-electron/
.electron-runtime/
.showcase/
apps/mobile/.showcase/
artifacts/app-store/screenshots/
.github/pr-assets/
native/**/target/
node_modules/
.alchemy/
Expand Down
1 change: 1 addition & 0 deletions .macroscope/check-run-agents/effect-service-conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Review changed TypeScript and directly affected call sites for the conventions b
- Export direct schema predicates such as `export const isFoo = Schema.is(Foo)`. Flag a private `Schema.is` constant wrapped by a redundant function with the same signature.
- Do not introduce a large `switch` or lookup table in an error's `message` getter to model failures that deserve separate error classes.
- Catch statically known tagged failures with `Effect.catchTags({ ... })`, including when handling only one tag. Do not use `catchIf` with a schema predicate merely to recover one or more known `_tag` variants, and do not use `catchTag`. `Effect.catch` is appropriate when the entire error channel is intentionally handled; `catchIf` remains appropriate for genuinely structural predicates such as inspecting an underlying platform error code.
- For startup reconciliation that repairs multiple independent entities, preserve interruption rather than reducing it to a warning. Retry a transient per-entity repair before readiness, then isolate a persistent failure so one bad entity cannot abort global startup or prevent later entities from being repaired. Require tests for both the retry-success path and persistent-failure continuation.
- Do not add a helper whose only behavior is `(...args) => new SomeError({ ...args })`, including curried aliases used once with `mapError`. Construct the error at the failure boundary so its attributes and cause remain visible. Keep a mapper only when it performs real normalization, passes through existing domain errors, or adds reusable context/control flow.
- When a reusable error-to-error translation clearly belongs to the target error type, prefer a descriptive static factory on that error class over a detached production-side switch. Do not force a static method for one-off inline mappings.

Expand Down
49 changes: 0 additions & 49 deletions .plans/01-shared-model-normalization.md

This file was deleted.

Loading
Loading