Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
6b3050e
Migrate TypeScript checks to Effect TSGo (#2851)
juliusmarminge May 28, 2026
3126894
Extract collection performance refactors from mobile stack (#2854)
juliusmarminge May 28, 2026
cf07d06
Extract independent web cleanup from mobile stack (#2855)
t3dotgg May 28, 2026
e3accd6
Ensure Electron runtime is installed in release workflow (#2861)
juliusmarminge May 29, 2026
b3e8c03
T3 Code Mobile [WIP] (#2013)
juliusmarminge May 30, 2026
e3f1405
chore: add vendored reference repo subtree sync tooling (#2902)
juliusmarminge Jun 2, 2026
a04c09a
Use HttpApi for Environment APIs & standardize authn/authz (#2858)
juliusmarminge Jun 2, 2026
bd851c0
chore: add Alchemy reference repo subtree (#2918)
juliusmarminge Jun 3, 2026
f0116e4
fix(desktop): Include standard Linux AppImage icons for Niri/Noctalia…
mwolson Jun 3, 2026
d78e02c
Probe Cursor models via list_available_models (#2428)
juliusmarminge Jun 3, 2026
b440dd1
Migrate workspace to Vite+ and pnpm (#2899)
juliusmarminge Jun 3, 2026
6e61632
test(web): CI stability - prebundle react-dom client for browser test…
mwolson Jun 4, 2026
f5849f7
fix(ssh): Surface redacted stdout for failed commands (#2920)
mwolson Jun 4, 2026
4956415
fix(desktop): Preserve SSH HTTP auth status (#2923)
mwolson Jun 4, 2026
e4643ec
fix: build web before desktop release packaging (#2934)
juliusmarminge Jun 4, 2026
30d36b8
ci: let setup-vp install dependencies (#2936)
juliusmarminge Jun 4, 2026
1288909
fix(release): surface desktop packaging subprocess output (#2937)
juliusmarminge Jun 4, 2026
dca93d0
chore: setup eas ci (#2911)
Yash-Singh1 Jun 4, 2026
6a1c4da
fix(release): use workspace electron-builder for desktop packaging (#…
juliusmarminge Jun 4, 2026
37bf0f0
[codex] remove duplicated pnpm root config (#2939)
juliusmarminge Jun 4, 2026
4f3d00f
fix(release): install dependency closures in partial jobs (#2941)
juliusmarminge Jun 4, 2026
4c262c4
[codex] split ci workflow jobs (#2940)
juliusmarminge Jun 4, 2026
80b40ce
[codex] fix mobile native static analysis source discovery (#2942)
juliusmarminge Jun 4, 2026
52ae8e8
fix(release): preserve desktop artifact arch (#2943)
juliusmarminge Jun 4, 2026
203f58e
[codex] Fix desktop packaging patched dependencies (#2944)
juliusmarminge Jun 4, 2026
a6edad1
[codex] Filter staged desktop patched dependencies (#2945)
juliusmarminge Jun 4, 2026
9fc485a
fix(release): install hosted web workspace closure (#2949)
juliusmarminge Jun 4, 2026
348a914
fix(cli): bundle patched diff parser dependency (#2957)
juliusmarminge Jun 4, 2026
b0fa60a
Prevent settings layout shifts with scrollbar gutters (#2960)
juliusmarminge Jun 4, 2026
dfdb5a4
[codex] fix release finalize install (#2961)
juliusmarminge Jun 4, 2026
49c1b64
fix(source-control): handle self-hosted GitLab, multi-account GitHub …
GuilhermeVieiraDev Jun 4, 2026
a74dfd4
[codex] Avoid shell for Node executable spawns (#2952)
juliusmarminge Jun 4, 2026
6ce6f67
[codex] Avoid shell for Windows environment probe (#2951)
juliusmarminge Jun 4, 2026
53042f4
fix(composer): support spaces in file mentions (#2625)
GuilhermeVieiraDev Jun 4, 2026
300f7fd
[codex] Avoid shell for system executables (#2950)
juliusmarminge Jun 4, 2026
5ae77c0
feat(relay): Add managed relay tunnels and APN service (#2837)
juliusmarminge Jun 5, 2026
ec18938
Restructure documentation into topical folders (#2963)
juliusmarminge Jun 5, 2026
b5a6250
move
juliusmarminge Jun 5, 2026
295b9db
dont fail if env-file is unspecified
juliusmarminge Jun 5, 2026
769bdd2
fallback to None when RELAY_DOMAIN is unset
juliusmarminge Jun 5, 2026
969e6d2
implicit install from vp
juliusmarminge Jun 5, 2026
af3dfd2
forward args directly
juliusmarminge Jun 5, 2026
3579005
bump alchemy to fix absolute drizzle schema out
juliusmarminge Jun 5, 2026
eda163c
bump alchemy to fix drizzle schema out attempt 2
juliusmarminge Jun 5, 2026
f60def2
Migrate tests to vite-plus test APIs (#2964)
juliusmarminge Jun 5, 2026
113b9d8
remove `vp staged`
juliusmarminge Jun 5, 2026
94fc117
publish deploy status on relay deploy workflow
juliusmarminge Jun 5, 2026
e1cb19b
Use pnpm for server publish workflow (#2966)
juliusmarminge Jun 5, 2026
b870a6e
Rename function for publishing arguments to vp pm (#2967)
juliusmarminge Jun 5, 2026
a084fbb
Remove duplicate 'publish' argument in CLI script
juliusmarminge Jun 5, 2026
9da430c
Refactor recoverable Effect fallbacks to orElseSucceed (#2968)
juliusmarminge Jun 5, 2026
c04d15d
document vp instead of mise
juliusmarminge Jun 5, 2026
5b26bd4
link
juliusmarminge Jun 5, 2026
6f42bd9
cleanup
juliusmarminge Jun 5, 2026
8ab58a0
tip
juliusmarminge Jun 5, 2026
0d6e9e9
we support cursor, duhhh
juliusmarminge Jun 5, 2026
92be60e
include @latest
juliusmarminge Jun 5, 2026
602148f
fix(cloud): use Electron fetch for proxying Clerk IPC requests (#2973)
juliusmarminge Jun 5, 2026
e1ce9f8
fix: handle Claude Agent SDK 0.3.x system messages to stop runtime-wa…
imabdulazeez Jun 5, 2026
75257d6
"claude system message" instead of "runtime warning" when using 4.8 f…
Aprillion Jun 5, 2026
b76f161
fix(desktop): stop looping macOS TCC permission prompts (#2745)
D3OXY Jun 5, 2026
a56496c
Annotate relay error spans with schema fields (#2976)
juliusmarminge Jun 5, 2026
3ea6adf
[codex] Enrich relay authorization diagnostics (#2977)
juliusmarminge Jun 6, 2026
0e4a435
[codex] Extract infrastructure, telemetry, and test tooling (#2994)
juliusmarminge Jun 8, 2026
38ea6d4
feat(grok): add Grok CLI provider via ACP (#2809)
Jaaneek Jun 9, 2026
8e6f422
[codex] Fix main CI Effect test runtimes (#3008)
juliusmarminge Jun 9, 2026
de58ec8
Add Claude Fable 5 model (#3009)
juliusmarminge Jun 9, 2026
983a8c7
chore(release): prepare v0.0.26
t3-code[bot] Jun 9, 2026
22f9f30
[codex] Rebrand T3 Cloud as T3 Connect (#3011)
juliusmarminge Jun 9, 2026
a3422a9
Fix Clerk browser test mock (#3013)
juliusmarminge Jun 9, 2026
483bfaa
Merge upstream T3 Code v0.0.27
dbalders Jun 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
2 changes: 1 addition & 1 deletion apps/mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"react-native-image-viewing": "^0.2.2",
"react-native-keyboard-controller": "1.21.6",
"react-native-nitro-markdown": "^0.5.0",
"react-native-nitro-modules": "^0.35.4",
"react-native-nitro-modules": "0.35.9",
"react-native-reanimated": "4.3.1",
"react-native-safe-area-context": "~5.7.0",
"react-native-screens": "4.25.2",
Expand Down
9 changes: 9 additions & 0 deletions apps/mobile/src/app/settings/waitlist.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { ScrollView } from "react-native";
import { CloudWaitlistEnrollment } from "../../features/cloud/CloudWaitlistEnrollment";
import { useClerkSettingsSheetDetent } from "../../features/cloud/ClerkSettingsSheetDetent";
import { hasCloudPublicConfig } from "../../features/cloud/publicConfig";
import { useNativeClerkAuthModal } from "../../features/cloud/useNativeClerkAuthModal";

export default function SettingsWaitlistRouteScreen() {
return hasCloudPublicConfig() ? (
Expand All @@ -18,6 +19,7 @@ export default function SettingsWaitlistRouteScreen() {
function ConfiguredSettingsWaitlistRouteScreen() {
const { isLoaded, isSignedIn } = useAuth({ treatPendingAsSignedOut: false });
const { expand } = useClerkSettingsSheetDetent();
const { isAvailable: isNativeAuthAvailable, presentAuth } = useNativeClerkAuthModal();
const router = useRouter();

useFocusEffect(
Expand Down Expand Up @@ -45,6 +47,13 @@ function ConfiguredSettingsWaitlistRouteScreen() {
>
<CloudWaitlistEnrollment
onSignIn={() => {
if (isNativeAuthAvailable) {
void presentAuth().catch(() => {
expand();
router.push("/settings/auth");
});
return;
}
expand();
router.push("/settings/auth");
}}
Expand Down
150 changes: 150 additions & 0 deletions apps/mobile/src/features/cloud/useNativeClerkAuthModal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { getClerkInstance } from "@clerk/expo";
import { tokenCache } from "@clerk/expo/token-cache";
import * as Data from "effect/Data";
import { useCallback, useRef } from "react";
import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

const CLERK_CLIENT_JWT_KEY = "__clerk_client_jwt";

interface NativeClerkModule extends TurboModule {
readonly getClientToken?: () => Promise<string | null>;
readonly presentAuth?: (options: {
readonly dismissable: boolean;
readonly mode: "signInOrUp";
}) => Promise<NativeAuthResult | null>;
}

interface NativeAuthResult {
readonly cancelled?: boolean;
readonly session?: {
readonly id?: string;
};
readonly sessionId?: string;
}

interface ClerkWithNativeSync {
readonly __internal_reloadInitialResources?: () => Promise<void>;
readonly setActive?: (params: { readonly session: string }) => Promise<void>;
}

interface TokenCacheWithClear {
readonly deleteToken?: (key: string) => Promise<void>;
readonly saveToken?: (key: string, token: string) => Promise<void>;
}

const NativeClerk = TurboModuleRegistry.get<NativeClerkModule>("ClerkExpo");

class NativeClerkAuthError extends Data.TaggedError("NativeClerkAuthError")<{
readonly message: string;
readonly cause?: unknown;
}> {}

async function syncNativeSession(sessionId: string): Promise<void> {
const getClientToken = NativeClerk?.getClientToken;
let nativeClientToken: string | null = null;
if (getClientToken) {
try {
nativeClientToken = await getClientToken();
} catch (cause) {
throw new NativeClerkAuthError({
message: "Could not read native Clerk client token.",
cause,
});
}
}
const cache = tokenCache as TokenCacheWithClear | null | undefined;
if (nativeClientToken) {
const saveToken = cache?.saveToken;
if (saveToken) {
try {
await saveToken(CLERK_CLIENT_JWT_KEY, nativeClientToken);
} catch (cause) {
throw new NativeClerkAuthError({
message: "Could not save native Clerk client token.",
cause,
});
}
}
} else if (cache?.deleteToken) {
try {
await cache.deleteToken(CLERK_CLIENT_JWT_KEY);
} catch (cause) {
throw new NativeClerkAuthError({
message: "Could not clear native Clerk client token.",
cause,
});
}
}

const clerk = getClerkInstance();
const clerkWithNativeSync = clerk as ClerkWithNativeSync;
const reloadInitialResources = clerkWithNativeSync.__internal_reloadInitialResources;
if (reloadInitialResources) {
try {
await reloadInitialResources();
} catch (cause) {
throw new NativeClerkAuthError({
message: "Could not reload Clerk resources after native auth.",
cause,
});
}
}
const setActive = clerkWithNativeSync.setActive;
if (setActive) {
try {
await setActive({ session: sessionId });
} catch (cause) {
throw new NativeClerkAuthError({
message: "Could not activate native Clerk session.",
cause,
});
}
}
}

export function useNativeClerkAuthModal() {
const presentingRef = useRef(false);

const presentAuth = useCallback(async (): Promise<void> => {
if (presentingRef.current || !NativeClerk?.presentAuth) {
return;
}

presentingRef.current = true;
const presentNativeAuth = NativeClerk.presentAuth;
try {
// Clerk's iOS AuthView is not inline. It presents this same native modal
// internally; call the presenter directly so Expo Router does not render
// an empty formSheet behind it.
let result: NativeAuthResult | null;
try {
result = await presentNativeAuth({
dismissable: true,
mode: "signInOrUp",
});
} catch (cause) {
throw new NativeClerkAuthError({
message: "Native Clerk auth presentation failed.",
cause,
});
}
const sessionId = result?.sessionId ?? result?.session?.id ?? null;
if (sessionId && !result?.cancelled) {
await syncNativeSession(sessionId);
}
} catch (error) {
if (__DEV__) {
console.error("[useNativeClerkAuthModal] presentAuth failed:", error);
}
throw error;
} finally {
presentingRef.current = false;
}
}, []);

return {
isAvailable: !!NativeClerk?.presentAuth,
presentAuth,
};
}
5 changes: 5 additions & 0 deletions apps/server/src/provider/Layers/ProviderRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,11 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsService.layerTest(), T
assert.strictEqual(initialCodex?.installed, false);
assert.deepStrictEqual(spawnedCommands, [firstMissing]);

// The rebuilt instance may re-probe synchronously during the
// settings update. Advance the TestClock first so `checkedAt`
// can safely act as the fresh-probe marker this assertion uses.
yield* TestClock.adjust("1 second");

// Drive a settings change. The Hydration layer's
// `SettingsWatcherLive` consumes this via `streamChanges`,
// calls `reconcile`, which rebuilds the codex instance (the
Expand Down
2 changes: 1 addition & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading