Skip to content

Commit 5d04153

Browse files
Merge upstream main into main
2 parents cba912b + ed44f25 commit 5d04153

289 files changed

Lines changed: 12224 additions & 7613 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/scripts/ci-changes.cjs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ const RUST = /^native\/(resource-monitor|kde-snap-shot|hyprland-snap-shot|projec
3333

3434
// These tests read other packages without declaring dependencies.
3535
const TEST_ONLY_DEPS = {
36+
// Evals import the server's source to test its real model-facing text.
37+
"@t3tools/evals": ["t3"],
3638
"@t3tools/provider-pi": ["@t3tools/client-runtime"],
3739
"@t3tools/scripts": [
3840
"@t3tools/desktop",

‎AGENTS.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@ An empty database is a bad test. Seed your worktree's `.t3` with a copy of real
136136

137137
For authorized mobile verification, a missing or outdated native client is an install step, not a blocker. Run `vp run mobile:install <ios|android> [device-id]` on the device host before starting Metro; it targets the only booted simulator or connected Android device when the id is omitted. It installs the dev client for this checkout's native fingerprint from the shared cache in seconds and builds only when no machine has built it yet, so prefer it over `expo run:*`, `xcodebuild`, or `gradlew`, which rebuild from scratch. Its stdout is one JSON line; build output goes to the log it names. See `test-t3-mobile` for the full workflow.
138138

139+
## Evals
140+
141+
`evals/` checks how real models behave with T3 Code's model-facing text: agent instructions, MCP tool descriptions and schemas, and generated titles. Before you change that text, read [evals/README.md](evals/README.md) and run the evals it names. When you fix a model behavior bug, add a case that fails before the fix.
142+
139143
## Pull requests
140144

141145
- Never make a PR unless the developer explicitly asks you to do so.

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ We are (mostly) not accepting contributions yet. Small fixes may be considered.
9494

9595
Full docs live in [docs/](./docs). There's no docs site yet.
9696

97+
- [FAQ](./docs/user/faq.md)
9798
- [Install and first run](./docs/user/install.md)
9899
- [Permission modes](./docs/user/permission-modes.md)
99100
- [Keyboard shortcuts](./docs/user/keybindings.md)

‎apps/desktop/src/backend/DesktopBackendPool.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export const layer = Layer.effect(
132132
});
133133
yield* electronDialog.showErrorBox(
134134
"WSL backend couldn't start",
135-
`${reason}\n\nFalling back to the Windows backend so T3 Code can open. Re-enable the WSL backend from Settings > Connections once the WSL distro is fixed.`,
135+
`${reason}\n\nFalling back to the Windows backend so T3 Code can open. Re-enable the WSL backend from Settings > Sharing & access once the WSL distro is fixed.`,
136136
);
137137
// Clear wslOnly too so enabling WSL cannot restore a failed mode.
138138
// Keep the in-memory fallback if persistence fails.

‎apps/mobile/src/App.tsx‎

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { installPermissionUpdateNotice } from "./features/connection/permissionUpdateNotice";
2+
import { installComposerAttachmentUploads } from "./state/composer-attachment-uploads";
3+
import { installThreadOutboxDelivery } from "./state/threadOutboxDelivery";
24
import * as Linking from "expo-linking";
35
import * as SplashScreen from "expo-splash-screen";
46
import { useEffect } from "react";
@@ -40,7 +42,6 @@ import {
4042
import { useMobileNavigationTheme } from "./lib/useMobileNavigationTheme";
4143
import { useUiRuntimeMemoryWarningGc } from "./lib/useUiRuntimeMemoryWarningGc";
4244
import { SubscriptionUsageCoordinator } from "./widgets/SubscriptionUsageCoordinator";
43-
import { VoiceInputProvider } from "./features/voice-input/VoiceInputProvider";
4445
import { GlobalVoiceInputControl } from "./features/voice-input/GlobalVoiceInputControl";
4546
import { restoreSettingsLinkState } from "./features/settings/settings-navigation";
4647
import {
@@ -87,11 +88,14 @@ const navigationRef = createNavigationContainerRef();
8788

8889
declare const module: { readonly hot?: FoundationHotModule } | undefined;
8990

90-
const disposePermissionUpdateNotice = installPermissionUpdateNotice();
91-
disposeOnFoundationReplace(
92-
typeof module === "undefined" ? undefined : module.hot,
93-
disposePermissionUpdateNotice,
94-
);
91+
const appServiceDisposers = [
92+
installPermissionUpdateNotice(),
93+
installThreadOutboxDelivery(),
94+
installComposerAttachmentUploads(),
95+
];
96+
disposeOnFoundationReplace(typeof module === "undefined" ? undefined : module.hot, () => {
97+
for (const dispose of appServiceDisposers) dispose();
98+
});
9599

96100
function SplashScreenCoordinator() {
97101
const { isReady } = useAppearancePreferences();
@@ -138,27 +142,25 @@ function AppContent() {
138142
<GestureHandlerRootView className="flex-1">
139143
<KeyboardProvider statusBarTranslucent>
140144
<SafeAreaProvider>
141-
<VoiceInputProvider>
142-
<StatusBar barStyle={themeAppearance === "dark" ? "light-content" : "dark-content"} />
143-
{/* native-stack needs the theme's dark flag to select dark native headers. */}
144-
<GlobalVoiceInputControl>
145-
<NativeLayoutMetricsProvider>
146-
<IncomingShareProvider>
147-
<Navigation
148-
ref={navigationRef}
149-
linking={appLinking}
150-
onReady={() => recordWorkspaceSelections(navigationRef.getRootState())}
151-
theme={navigationTheme}
152-
onStateChange={recordWorkspaceSelections}
153-
/>
154-
</IncomingShareProvider>
155-
<Dialog.Host />
156-
<ThreadArrangementHost />
157-
<ProjectChipIconRasterizer />
158-
</NativeLayoutMetricsProvider>
159-
</GlobalVoiceInputControl>
160-
<OverlayPortalHost />
161-
</VoiceInputProvider>
145+
<StatusBar barStyle={themeAppearance === "dark" ? "light-content" : "dark-content"} />
146+
{/* native-stack needs the theme's dark flag to select dark native headers. */}
147+
<GlobalVoiceInputControl>
148+
<NativeLayoutMetricsProvider>
149+
<IncomingShareProvider>
150+
<Navigation
151+
ref={navigationRef}
152+
linking={appLinking}
153+
onReady={() => recordWorkspaceSelections(navigationRef.getRootState())}
154+
theme={navigationTheme}
155+
onStateChange={recordWorkspaceSelections}
156+
/>
157+
</IncomingShareProvider>
158+
<Dialog.Host />
159+
<ThreadArrangementHost />
160+
<ProjectChipIconRasterizer />
161+
</NativeLayoutMetricsProvider>
162+
</GlobalVoiceInputControl>
163+
<OverlayPortalHost />
162164
</SafeAreaProvider>
163165
</KeyboardProvider>
164166
</GestureHandlerRootView>

‎apps/mobile/src/Stack.tsx‎

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ import { SettingsEnvironmentDetailRouteScreen } from "./features/settings/Settin
9999
import { SettingsEnvironmentsRouteScreen } from "./features/settings/SettingsEnvironmentsRouteScreen";
100100
import { SettingsFollowUpRouteScreen } from "./features/settings/SettingsFollowUpRouteScreen";
101101
import {
102-
SettingsEnvironmentAgentBehaviorRouteScreen,
103102
SettingsEnvironmentMaintenanceRouteScreen,
104-
SettingsEnvironmentNewThreadsRouteScreen,
103+
SettingsThreadsRouteScreen,
104+
SettingsWorktreesRouteScreen,
105105
SettingsEnvironmentSourceControlRouteScreen,
106106
} from "./features/settings/SettingsServerControlsRouteScreen";
107107
import {
@@ -127,7 +127,7 @@ import { UsageRouteScreen } from "./features/usage/UsageRouteScreen";
127127
import { SettingsAboutRouteScreen } from "./features/settings/SettingsAboutRouteScreen";
128128
import { SettingsNotificationsRouteScreen } from "./features/settings/SettingsNotificationsRouteScreen";
129129
import { SettingsRouteScreen } from "./features/settings/SettingsRouteScreen";
130-
import { SettingsThreadsRouteScreen } from "./features/settings/SettingsThreadsRouteScreen";
130+
import { SettingsLabsRouteScreen } from "./features/settings/ThreadSettingsSections";
131131
import { SettingsEnvironmentFilterProvider } from "./features/settings/settings-environment-filter";
132132
import { openSettings, settingsOpenIn } from "./features/settings/settings-navigation";
133133
import { DEFAULT_SETTINGS_PAGE } from "./features/workspace/workspace-tab-navigation";
@@ -151,8 +151,6 @@ import { deriveLayout } from "./lib/layout";
151151
import { useNativeLayoutMetrics } from "./native/native-layout-metrics";
152152
import { nativeHeaderScrollEdgeEffects } from "./native/StackHeader";
153153
import { HORIZONTAL_FORM_SHEET_OPTIONS, formSheetDetents } from "./native/sheet-surface";
154-
import { useThreadOutboxDrain } from "./state/use-thread-outbox-drain";
155-
import { useComposerAttachmentUploadWorker } from "./state/composer-attachment-uploads";
156154
import {
157155
selectWorkspaceDetail,
158156
workspaceDetailRouter,
@@ -265,25 +263,36 @@ const SETTINGS_SCREENS = {
265263
linking: "settings/environments/:environmentId",
266264
options: { ...SETTINGS_PAGE_OPTIONS, title: "Environment" },
267265
}),
266+
// Old links to New threads and Agent behavior open Threads, which absorbed them.
268267
SettingsEnvironmentNewThreads: createNativeStackScreen({
269-
screen: SettingsEnvironmentNewThreadsRouteScreen,
268+
screen: SettingsThreadsRouteScreen,
270269
linking: "settings/new-threads",
271-
options: { ...SETTINGS_PAGE_OPTIONS, title: "New threads" },
270+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Threads" },
272271
}),
273272
SettingsEnvironmentSourceControl: createNativeStackScreen({
274273
screen: SettingsEnvironmentSourceControlRouteScreen,
275274
linking: "settings/source-control",
276275
options: { ...SETTINGS_PAGE_OPTIONS, title: "Source control" },
277276
}),
278277
SettingsEnvironmentAgentBehavior: createNativeStackScreen({
279-
screen: SettingsEnvironmentAgentBehaviorRouteScreen,
278+
screen: SettingsThreadsRouteScreen,
280279
linking: "settings/agent-behavior",
281-
options: { ...SETTINGS_PAGE_OPTIONS, title: "Agent behavior" },
280+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Threads" },
281+
}),
282+
SettingsWorktrees: createNativeStackScreen({
283+
screen: SettingsWorktreesRouteScreen,
284+
linking: "settings/worktrees",
285+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Worktrees" },
286+
}),
287+
SettingsLabs: createNativeStackScreen({
288+
screen: SettingsLabsRouteScreen,
289+
linking: "settings/labs",
290+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Labs" },
282291
}),
283292
SettingsProviderAccounts: createNativeStackScreen({
284293
screen: SettingsProviderAccountsRouteScreen,
285294
linking: "settings/provider-accounts",
286-
options: { ...SETTINGS_PAGE_OPTIONS, title: "Provider accounts" },
295+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Providers" },
287296
}),
288297
SettingsEnvironmentMaintenance: createNativeStackScreen({
289298
screen: SettingsEnvironmentMaintenanceRouteScreen,
@@ -298,12 +307,12 @@ const SETTINGS_SCREENS = {
298307
SettingsThreads: createNativeStackScreen({
299308
screen: SettingsThreadsRouteScreen,
300309
linking: "settings/thread-preferences",
301-
options: { ...SETTINGS_PAGE_OPTIONS, title: "Thread behavior" },
310+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Threads" },
302311
}),
303312
SettingsAbout: createNativeStackScreen({
304313
screen: SettingsAboutRouteScreen,
305314
linking: "settings/about",
306-
options: { ...SETTINGS_PAGE_OPTIONS, title: "About T3 Code" },
315+
options: { ...SETTINGS_PAGE_OPTIONS, title: "About" },
307316
}),
308317
SettingsEnvironmentNew: createNativeStackScreen({
309318
screen: ConnectionsNewRouteScreen,
@@ -318,7 +327,7 @@ const SETTINGS_SCREENS = {
318327
linking: "settings/archive",
319328
options: {
320329
...SETTINGS_PAGE_OPTIONS,
321-
title: "Archived Threads",
330+
title: "Archive",
322331
},
323332
}),
324333
SettingsNavigation: createNativeStackScreen({
@@ -339,21 +348,21 @@ const SETTINGS_SCREENS = {
339348
linking: "settings/project-grouping",
340349
options: {
341350
...SETTINGS_PAGE_OPTIONS,
342-
title: "Organization",
351+
title: "General",
343352
},
344353
}),
345354
SettingsOrganization: createNativeStackScreen({
346355
screen: SettingsProjectGroupingRouteScreen,
347356
linking: "settings/organization",
348357
options: {
349358
...SETTINGS_PAGE_OPTIONS,
350-
title: "Organization",
359+
title: "General",
351360
},
352361
}),
353362
SettingsProjectOverview: createNativeStackScreen({
354363
screen: SettingsProjectOverviewRouteScreen,
355364
linking: "settings/project",
356-
options: { ...SETTINGS_PAGE_OPTIONS, title: "Project overview" },
365+
options: { ...SETTINGS_PAGE_OPTIONS, title: "Projects" },
357366
}),
358367
SettingsKeyboard: createNativeStackScreen({
359368
screen: SettingsKeyboardRouteScreen,
@@ -376,15 +385,15 @@ const SETTINGS_SCREENS = {
376385
linking: "settings/follow-ups",
377386
options: {
378387
...SETTINGS_PAGE_OPTIONS,
379-
title: "Follow-ups",
388+
title: "Chat",
380389
},
381390
}),
382391
SettingsScheduledTasks: createNativeStackScreen({
383392
screen: SettingsScheduledTasksRouteScreen,
384393
linking: "settings/scheduled-tasks",
385394
options: {
386395
...SETTINGS_PAGE_OPTIONS,
387-
title: "Scheduled Tasks",
396+
title: "Scheduled tasks",
388397
headerTitleStyle: { fontSize: 16, fontWeight: "800" },
389398
},
390399
}),
@@ -487,13 +496,6 @@ function workspaceLocationFromState(state: NavigationState) {
487496
};
488497
}
489498

490-
// Isolate subscriptions so streaming updates cannot re-render RootStackLayout and every screen.
491-
function ThreadOutboxDrainWorker() {
492-
useThreadOutboxDrain();
493-
useComposerAttachmentUploadWorker();
494-
return null;
495-
}
496-
497499
function RootStackLayout(props: {
498500
readonly children: React.ReactNode;
499501
readonly state: NavigationState;
@@ -511,16 +513,11 @@ function RootStackLayout(props: {
511513
);
512514
const draftRoute = props.state.routes.findLast((route) => route.name === "Thread");
513515
const draftParams = (
514-
draftRoute?.params as
515-
| { draft?: { draftId?: string | string[]; pendingTaskId?: string | string[] } }
516-
| undefined
516+
draftRoute?.params as { draft?: { draftId?: string | string[] } } | undefined
517517
)?.draft;
518518
const routeDraftId = Array.isArray(draftParams?.draftId)
519519
? draftParams.draftId[0]
520520
: draftParams?.draftId;
521-
const routePendingTaskId = Array.isArray(draftParams?.pendingTaskId)
522-
? draftParams.pendingTaskId[0]
523-
: draftParams?.pendingTaskId;
524521
useAgentNotificationNavigation(workspaceLocation.pathname);
525522
useConnectOnboardingNavigation();
526523
useAppShortcuts(props.state);
@@ -542,13 +539,8 @@ function RootStackLayout(props: {
542539
}, [navigation, pendingShare, props.state]);
543540

544541
return (
545-
<NewTaskFlowProvider
546-
active={isDraftThreadRoute(draftRoute)}
547-
routeDraftId={routeDraftId}
548-
routePendingTaskId={routePendingTaskId}
549-
>
542+
<NewTaskFlowProvider active={isDraftThreadRoute(draftRoute)} routeDraftId={routeDraftId}>
550543
<HardwareKeyboardCommandProvider pathname={pathname}>
551-
<ThreadOutboxDrainWorker />
552544
<ShowcaseCaptureCoordinator pathname={pathname} />
553545
<SettingsEnvironmentFilterProvider open={settingsOpen}>
554546
<WorkspaceConnectionStatusProvider>

‎apps/mobile/src/components/ui/ListChoiceRow.tsx‎

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ export function ListChoiceRow(props: {
2626
onPress={props.onPress}
2727
android_ripple={{ color: rippleStyle.backgroundColor }}
2828
unstable_pressDelay={Platform.OS === "android" ? 50 : undefined}
29-
className={cn(
30-
props.selected ? "bg-subtle" : "bg-grouped-card",
31-
props.separated && "border-t border-border-subtle",
32-
)}
29+
// Like UIKit and Material lists, only the checkmark or radio marks the selected row.
30+
className={cn("bg-grouped-card", props.separated && "border-t border-border-subtle")}
3331
>
3432
<ListRowLayout
3533
label={props.label}

‎apps/mobile/src/features/pull-requests/PullRequestFilterMenuContext.tsx‎

Lines changed: 0 additions & 50 deletions
This file was deleted.

0 commit comments

Comments
 (0)