Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8298664
fix(server,cursor,opencode): refresh provider usage when a turn hits …
maria-rcks Oct 29, 2026
fe219c4
fix(web): keep tool groups collapsed after a usage-limit pause (#24937)
shivamhwp Oct 29, 2026
7632c3d
fix(mobile): photo-library PNGs no longer fail after resizing (#26522)
shivamhwp Oct 29, 2026
ab1e221
fix(server): guest links no longer return file diffs (#26538)
nexxeln Oct 29, 2026
eb565e1
fix(claude): Open diff shows Claude edits as a diff instead of raw JS…
nexxeln Oct 29, 2026
dac8b11
chore: vouch nexxeln (#26812)
t3dotgg Oct 29, 2026
f855f01
chore(release): prepare v0.1.4
t3-code-bot[bot] Oct 29, 2026
310c128
feat(web): Labs toggle keeps 5h, weekly, and context limits in view (…
t3dotgg Oct 29, 2026
6d82a22
fix(desktop): bump Electron to 44.10.0 for the Node.js Brotli fix (CV…
nabettu Oct 29, 2026
da1eab0
chore: make agent mistakes fail early (#26167)
t3dotgg Oct 29, 2026
ccaa3ad
feat(marketing): hero shows four agents running at once (#26875)
t3dotgg Oct 29, 2026
35b298a
fix(web): undo notice moves to the sidebar footer so it never covers …
t3dotgg Oct 29, 2026
58e60bf
feat: turn a No project thread into a project (#26767)
t3dotgg Oct 29, 2026
4432fbe
feat(antigravity): Claude and GPT models, thinking levels, and diff e…
t3dotgg Oct 29, 2026
d7935f1
feat(web): choose what the thread details card shows (#26904)
t3dotgg Oct 29, 2026
f2943ee
feat(updates): switch your whole fleet between Stable and Nightly in …
t3dotgg Oct 29, 2026
c1876b5
fix(antigravity): file reads no longer show unrelated errors (#26910)
t3dotgg Oct 29, 2026
b5fc7be
feat(release): release notes and the update popover open with a short…
t3dotgg Oct 29, 2026
48247dd
fix(cli): t3 starts on a fresh Ubuntu server without libatomic (#26912)
t3dotgg Oct 29, 2026
e6ca170
fix(web): update everything no longer waits on npm for service hosts …
t3dotgg Oct 29, 2026
3748c5c
test(web): pin the npm wait floor for update everything (#26921)
t3dotgg Oct 29, 2026
7f55281
fix(antigravity): served reads stop spinning and duplicate model name…
t3dotgg Oct 29, 2026
9acb769
fix(server): queue Copilot follow-ups without killing background agen…
shivamhwp Oct 29, 2026
4453f53
fix(web): Antigravity effort no longer shows a speedometer in the com…
t3dotgg Oct 29, 2026
6d450a4
fix(release): Linux CLI archives build on runners without package doc…
t3dotgg Oct 29, 2026
6d7931e
Merge tag 'v0.1.5-nightly.20261029.3877' into custom-nightly
chamaquita-d3[bot] Oct 29, 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
1 change: 1 addition & 0 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ github:myacoub91
github:naMqe-h
github:nateEc
github:naveed949
github:nexxeln
github:nmggithub
github:Noojuno
github:notkainoa
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/agent-context-budget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ jobs:
echo "Accepted by the agent-context-increase label."
exit 0
fi
echo "::error file=$BUDGET::Agent context grew compared to main. Cut the added text, or ask a maintainer to add the agent-context-increase label."
echo "::error file=$BUDGET::Agent context grew compared to main. Cut the added text and rerun the evals that cover it (evals/README.md), or ask a maintainer to add the agent-context-increase label."
exit 1
12 changes: 9 additions & 3 deletions .github/workflows/release-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,15 @@ jobs:
mkdir -p "$target_dir"
cp "native/resource-monitor/target/${{ inputs.rust_target }}/release/${binary_name}" "$target_dir/$binary_name"

- uses: ./.github/actions/setup-apt-mirrors
if: inputs.platform == 'linux'

# The Linux archive ships libatomic.so.1 and points t3's RUNPATH at it.
- name: Install patchelf
if: inputs.cli_archive && inputs.platform == 'linux'
shell: bash
run: command -v patchelf || { sudo apt-get update && sudo apt-get install -y patchelf; }

- name: Build CLI archive
if: inputs.cli_archive
shell: bash
Expand Down Expand Up @@ -433,9 +442,6 @@ jobs:
path: release-cli/*
if-no-files-found: error

- uses: ./.github/actions/setup-apt-mirrors
if: inputs.platform == 'linux'

- name: Install Linux desktop build libraries
if: inputs.platform == 'linux'
shell: bash
Expand Down
43 changes: 41 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -762,11 +762,16 @@ jobs:
timeout-minutes: 30
permissions:
contents: write
# Release notes read PR bodies and authors.
pull-requests: read
steps:
- name: Checkout
uses: actions/checkout@v6
with:
ref: ${{ needs.preflight.outputs.ref }}
# Release notes need history back to the previous tag, not file contents.
fetch-depth: 0
filter: blob:none
sparse-checkout: |
/*
!/.repos/
Expand Down Expand Up @@ -892,6 +897,27 @@ jobs:
echo 'EOF'
} >> "$GITHUB_OUTPUT"

# A short model summary over GitHub's full list. Without a notes file, the
# release falls back to GitHub's generated notes.
- name: Write release notes
if: needs.preflight.outputs.release_channel != 'preview' && needs.preflight.outputs.previous_tag != ''
continue-on-error: true
timeout-minutes: 5
env:
GH_TOKEN: ${{ github.token }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
node scripts/generate-release-notes.ts \
--repository "${{ github.repository }}" \
--tag "${{ needs.preflight.outputs.tag }}" \
--ref "${{ needs.preflight.outputs.ref }}" \
--previous-tag "${{ needs.preflight.outputs.previous_tag }}" \
--version "${{ needs.preflight.outputs.version }}" \
--output release-notes.md
if [[ -f release-notes.md ]]; then
cat release-notes.md >> "$GITHUB_STEP_SUMMARY"
fi

# A preview release gets a warning instead of generated notes. Generated
# notes would list every commit since the previous preview, which is
# unmerged branch history no one should read as a changelog, and would
Expand All @@ -917,10 +943,11 @@ jobs:
tag_name: ${{ needs.preflight.outputs.tag }}
target_commitish: ${{ needs.preflight.outputs.ref }}
name: ${{ needs.preflight.outputs.release_name }}
generate_release_notes: ${{ needs.preflight.outputs.release_channel != 'preview' }}
body_path: ${{ needs.preflight.outputs.release_channel == 'preview' && 'release-notes.md' || '' }}
generate_release_notes: ${{ hashFiles('release-notes.md') == '' }}
body_path: ${{ hashFiles('release-notes.md') != '' && 'release-notes.md' || '' }}
previous_tag: ${{ needs.preflight.outputs.previous_tag }}
prerelease: ${{ needs.preflight.outputs.is_prerelease }}
draft: ${{ needs.preflight.outputs.is_prerelease }}
make_latest: ${{ needs.preflight.outputs.make_latest }}
files: ${{ steps.release_files.outputs.files }}
fail_on_unmatched_files: true
Expand All @@ -936,11 +963,23 @@ jobs:
generate_release_notes: ${{ needs.preflight.outputs.release_channel != 'preview' }}
body_path: ${{ needs.preflight.outputs.release_channel == 'preview' && 'release-notes.md' || '' }}
prerelease: ${{ needs.preflight.outputs.is_prerelease }}
draft: ${{ needs.preflight.outputs.is_prerelease }}
make_latest: ${{ needs.preflight.outputs.make_latest }}
files: ${{ steps.release_files.outputs.files }}
fail_on_unmatched_files: true
token: ${{ github.token }}

# The action keeps a stable release a draft until its assets finish uploading, but publishes a
# prerelease first. Desktop clients update connected servers from the CLI archives as soon as
# they see the release, so a prerelease also goes public only once every asset is attached.
- name: Publish prerelease
if: needs.preflight.outputs.is_prerelease == 'true'
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
RELEASE_TAG: ${{ needs.preflight.outputs.tag }}
run: gh release edit "$RELEASE_TAG" --draft=false

# The `t3` npm package is a launcher that downloads this version's CLI
# archive from the GitHub Release, so it publishes only once that release
# exists. Preview publishes too, under the `preview` dist-tag, which
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ An empty database is a bad test. Seed your worktree's `.t3` with a copy of real

## Verifying

- Before you push, run `vp run check:changed`. It runs CI's fast checks for changed files: format, lint, knip, typecheck of affected packages and dependents, and tests beside changes. CI still runs the full test suites.
- Before you push, run `vp run check:changed`. It runs CI's fast checks for changed files: format, lint, knip, typecheck of affected packages and dependents, tests beside changes, and the cross-file checks those miss. CI still runs the full test suites.
- While you iterate, run `vp test run <files>`. For big files, add `-t "<name>"`.
- Use `vp run typecheck`, not `npx tsc`; it caches per package. Both run tsc-rs (`typescript` is the `@tsc-rs/typescript` drop-in).
- Run `node -e` snippets from `apps/server` or the owning package. `effect` does not resolve from the repo root.
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@t3tools/desktop",
"version": "0.1.3",
"version": "0.1.4",
"private": true,
"type": "module",
"main": "dist-electron/boot.cjs",
Expand All @@ -22,7 +22,7 @@
"@t3tools/tailscale": "workspace:*",
"dbus-next": "0.10.2",
"effect": "catalog:",
"electron": "44.9.3",
"electron": "44.10.0",
"electron-store": "^8.2.0",
"electron-updater": "^6.8.9",
"electron-webauthn": "catalog:",
Expand Down
18 changes: 12 additions & 6 deletions apps/desktop/src/ipc/methods/updates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ export const getUpdateState = DesktopIpc.makeIpcMethod({

export const setUpdateChannel = DesktopIpc.makeIpcMethod({
channel: IpcChannels.UPDATE_SET_CHANNEL_CHANNEL,
payload: DesktopUpdateChannelSchema,
payload: Schema.Struct({
channel: DesktopUpdateChannelSchema,
minimumVersion: Schema.optional(Schema.String),
}),
result: DesktopUpdateStateSchema,
handler: Effect.fn("desktop.ipc.updates.setChannel")(function* (channel) {
handler: Effect.fn("desktop.ipc.updates.setChannel")(function* ({ channel, minimumVersion }) {
const updates = yield* DesktopUpdates.DesktopUpdates;
return yield* updates.setChannel(channel);
return yield* updates.setChannel(channel, { minimumVersion });
}),
});

Expand All @@ -43,11 +46,14 @@ export const downloadUpdate = DesktopIpc.makeIpcMethod({

export const installUpdate = DesktopIpc.makeIpcMethod({
channel: IpcChannels.UPDATE_INSTALL_CHANNEL,
payload: Schema.Void,
/** A version installs only that downloaded build, never one that replaced it. */
payload: Schema.UndefinedOr(Schema.String),
result: DesktopUpdateActionResultSchema,
handler: Effect.fn("desktop.ipc.updates.install")(function* () {
handler: Effect.fn("desktop.ipc.updates.install")(function* (expectedVersion) {
const updates = yield* DesktopUpdates.DesktopUpdates;
return yield* updates.install;
if (expectedVersion === undefined) return yield* updates.install;
const { accepted, completed, state } = yield* updates.installPrepared(expectedVersion);
return { accepted, completed, state };
}),
});

Expand Down
7 changes: 4 additions & 3 deletions apps/desktop/src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,11 +293,12 @@ contextBridge.exposeInMainWorld("desktopBridge", {
};
},
getUpdateState: () => ipcRenderer.invoke(IpcChannels.UPDATE_GET_STATE_CHANNEL),
setUpdateChannel: (channel) =>
ipcRenderer.invoke(IpcChannels.UPDATE_SET_CHANNEL_CHANNEL, channel),
setUpdateChannel: (channel, minimumVersion) =>
ipcRenderer.invoke(IpcChannels.UPDATE_SET_CHANNEL_CHANNEL, { channel, minimumVersion }),
checkForUpdate: () => ipcRenderer.invoke(IpcChannels.UPDATE_CHECK_CHANNEL),
downloadUpdate: () => ipcRenderer.invoke(IpcChannels.UPDATE_DOWNLOAD_CHANNEL),
installUpdate: () => ipcRenderer.invoke(IpcChannels.UPDATE_INSTALL_CHANNEL),
installUpdate: (expectedVersion) =>
ipcRenderer.invoke(IpcChannels.UPDATE_INSTALL_CHANNEL, expectedVersion),
cliCommand: {
getState: () => ipcRenderer.invoke(IpcChannels.CLI_COMMAND_GET_STATE_CHANNEL),
install: () => ipcRenderer.invoke(IpcChannels.CLI_COMMAND_INSTALL_CHANNEL),
Expand Down
4 changes: 2 additions & 2 deletions apps/desktop/src/settings/DesktopAppSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
normalizeLinuxPasswordStorePreference,
type LinuxPasswordStorePreference,
} from "../linuxSecretStorage.ts";
import { resolveDefaultDesktopUpdateChannel } from "../updates/updateChannels.ts";
import { desktopUpdateChannelOf } from "@t3tools/shared/cliRelease";
import { isValidDistroName } from "../wsl/wslPathParsing.ts";

export interface DesktopSettings {
Expand Down Expand Up @@ -180,7 +180,7 @@ export class DesktopAppSettings extends Context.Service<
export function resolveDefaultDesktopSettings(appVersion: string): DesktopSettings {
return {
...DEFAULT_DESKTOP_SETTINGS,
updateChannel: resolveDefaultDesktopUpdateChannel(appVersion),
updateChannel: desktopUpdateChannelOf(appVersion),
};
}

Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/settings/DesktopClientSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ const clientSettings: ClientSettings = {
sidebarThreadSortOrder: "created_at",
boringSidebarEnabled: false,
boringSidebarMultilineRows: false,
threadDetailsUsageEnabled: false,
threadDetailsItems: {},
legacySidebarEnabled: false,
sidebarWorkingShelfEnabled: false,
loadBalancingEnabled: false,
Expand Down
Loading
Loading