Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
5cf83ff
fix(release): use configured node for smoke manifest merge (#2364)
juliusmarminge Apr 27, 2026
dbebc38
Ignore stale WebSocket lifecycle events after reconnect (#2372)
juliusmarminge Apr 27, 2026
3582288
Stop OpenCode refresh from leaking serve processes
joshmeads Apr 27, 2026
08e6d4c
feat: Multi-Provider support (#2277)
juliusmarminge Apr 29, 2026
7da6522
fix: updated UI "add project" icon to match the command pallete icon …
zurielbm Apr 29, 2026
fe2fde5
Add OpenCode to README (#2154)
pompydev Apr 29, 2026
22b7d8c
[codex] Fix visited timestamp under clock skew (#2408)
juliusmarminge Apr 30, 2026
02903f2
[codex] fix terminal dimension validation (#2411)
juliusmarminge Apr 30, 2026
44b39fe
fix(server): key AskUserQuestion answers by question text (#2404)
basmilius Apr 30, 2026
9acf46a
fix(web): prevent iOS Safari auto-zoom on input focus (#1652)
bergholmm Apr 30, 2026
69d9a65
fix(git): hide stale merged/closed PRs on the default branch (#1966)
GuilhermeVieiraDev Apr 30, 2026
86c94b4
fix(web): allow closing diff panel in non-git projects (#2413)
pedrokpp Apr 30, 2026
a4298f1
fix(web): hide mobile sidebar after thread selection or creation (#1293)
murataslan1 Apr 30, 2026
9e2f712
fix(web): make new thread button always visible on mobile (#2419)
jappyjan Apr 30, 2026
532a1d8
fix(web): make thread archive button always visible on mobile (#2423)
jappyjan Apr 30, 2026
e25ce07
Add new GitHub users to VOUCHED.td (#2425)
juliusmarminge Apr 30, 2026
f54f438
Narrow the right sidebar and update task panel and diff panel (#2409)
shivamhwp Apr 30, 2026
d649ccf
fix(web): respect iOS safe areas across mobile chrome & other mobile …
jappyjan Apr 30, 2026
c07ac59
fix: bump `electron` version to v40.9.3 and add it to our trusted dep…
nmggithub May 1, 2026
4ef361d
fix(mobile): enable touch scrolling in file picker modal (#2420)
jappyjan May 1, 2026
1eb6fce
fix: opencode is not on PATH on Windows (#2183)
adammansfield May 1, 2026
a480f07
Add Discord release announcements (#2429)
juliusmarminge May 1, 2026
e5c7ac5
Optimize release workflow job execution (#2430)
juliusmarminge May 1, 2026
17b4396
Add structured Discord webhook logging for release notifications (#2431)
juliusmarminge May 1, 2026
7a3f21e
[codex] fix Discord release version flag (#2449)
juliusmarminge May 1, 2026
7bbb595
sync: merge upstream/main + multi-provider PR #2277
aaditagrawal May 2, 2026
e1e3c8e
sync: align fork files with upstream's contracts
aaditagrawal May 2, 2026
9f57ad4
feat: add stub drivers for fork providers (Amp/Copilot/GeminiCli/Kilo)
aaditagrawal May 2, 2026
ec68079
feat(ui): add fork driver options to providerDriverMeta
aaditagrawal May 2, 2026
a6706a5
feat(provider): port fork adapters (Amp/Copilot/GeminiCli/Kilo) to Pr…
aaditagrawal May 2, 2026
f129969
test(server): adjust migration test bounds for fork renumbering
aaditagrawal May 2, 2026
f4c4444
test(server): fix Codex native log regex typo
aaditagrawal May 2, 2026
9348f88
test(server): include fork providers in cursor-disabled assertion
aaditagrawal May 2, 2026
46e2ab7
fix(marketing): bypass vite optimizer to work around astro/rolldown bug
aaditagrawal May 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .github/VOUCHED.td
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ github:Yash-Singh1
github:eggfriedrice24
github:Ymit24
github:shivamhwp
github:jappyjan
github:justsomelegs
github:UtkarshUsername
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ apps/web/src/components/__screenshots__
__screenshots__/
.tanstack
squashfs-root/
.scratch/
7 changes: 2 additions & 5 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
},
"dependencies": {
"effect": "catalog:",
"electron": "40.8.5",
"electron": "40.9.3",
"electron-updater": "^6.6.2"
},
"devDependencies": {
Expand All @@ -28,8 +28,5 @@
"typescript": "catalog:",
"vitest": "catalog:"
},
"productName": "T3 Code (Alpha)",
"trustedDependencies": [
"electron"
]
"productName": "T3 Code (Alpha)"
}
1 change: 1 addition & 0 deletions apps/desktop/src/clientPersistence.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const clientSettings: ClientSettings = {
confirmThreadDelete: false,
diffWordWrap: true,
favorites: [],
providerModelPreferences: {},
sidebarProjectGroupingMode: "repository_path",
sidebarProjectGroupingOverrides: {
"environment-1:/tmp/project-a": "separate",
Expand Down
16 changes: 16 additions & 0 deletions apps/marketing/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,20 @@ export default defineConfig({
server: {
port: Number(process.env.PORT ?? 4173),
},
// Workaround: Astro 6.2.1's `astro:dev-toolbar` plugin registers an esbuild
// plugin via `optimizeDeps.esbuildOptions` whose `onEnd` callback reads
// `result.metafile`. Vite 8.0.10's Rolldown-based esbuild compatibility shim
// proxies that result and throws "Not implemented" on any property access,
// crashing dep prebundling (and `astro check`). Setting `disabled: true`
// bypasses the optimizer entirely; this is a static marketing site with no
// client deps that benefit from prebundling. Vite warns that `disabled` is
// deprecated and suggests `noDiscovery: true` + empty `include`, but astro's
// dev-toolbar plugin force-injects entries into `include`, so noDiscovery is
// not sufficient. Remove this once vite/rolldown shims `metafile` (or astro
// migrates the dev-toolbar plugin to `rolldownOptions`).
vite: {
optimizeDeps: {
disabled: true,
},
},
});
44 changes: 22 additions & 22 deletions apps/server/integration/OrchestrationEngineHarness.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { execFileSync } from "node:child_process";
import * as NodeServices from "@effect/platform-node/NodeServices";
import {
ApprovalRequestId,
ProviderKind,
CodexSettings,
ProviderDriverKind,
type OrchestrationEvent,
type OrchestrationThread,
} from "@t3tools/contracts";
Expand Down Expand Up @@ -36,13 +37,16 @@ import { ProviderSessionRuntimeRepositoryLive } from "../src/persistence/Layers/
import { makeSqlitePersistenceLive } from "../src/persistence/Layers/Sqlite.ts";
import { ProjectionCheckpointRepository } from "../src/persistence/Services/ProjectionCheckpoints.ts";
import { ProjectionPendingApprovalRepository } from "../src/persistence/Services/ProjectionPendingApprovals.ts";
import { ProviderUnsupportedError } from "../src/provider/Errors.ts";
import { makeAdapterRegistryMock } from "../src/provider/testUtils/providerAdapterRegistryMock.ts";
import { ProviderAdapterRegistry } from "../src/provider/Services/ProviderAdapterRegistry.ts";
import { ProviderSessionDirectoryLive } from "../src/provider/Layers/ProviderSessionDirectory.ts";
import { ServerSettingsService } from "../src/serverSettings.ts";
import { makeProviderServiceLive } from "../src/provider/Layers/ProviderService.ts";
import { makeCodexAdapterLive } from "../src/provider/Layers/CodexAdapter.ts";
import { CodexAdapter } from "../src/provider/Services/CodexAdapter.ts";
import { makeCodexAdapter } from "../src/provider/Layers/CodexAdapter.ts";
import {
NoOpProviderEventLoggers,
ProviderEventLoggers,
} from "../src/provider/Layers/ProviderEventLoggers.ts";
import { ProviderService } from "../src/provider/Services/ProviderService.ts";
import { AnalyticsService } from "../src/telemetry/Services/AnalyticsService.ts";
import { CheckpointReactorLive } from "../src/orchestration/Layers/CheckpointReactor.ts";
Expand Down Expand Up @@ -214,7 +218,7 @@ export interface OrchestrationIntegrationHarness {
}

interface MakeOrchestrationIntegrationHarnessOptions {
readonly provider?: ProviderKind;
readonly provider?: ProviderDriverKind;
readonly realCodex?: boolean;
}

Expand All @@ -225,21 +229,18 @@ export const makeOrchestrationIntegrationHarness = (
const path = yield* Path.Path;
const fileSystem = yield* FileSystem.FileSystem;

const provider = options?.provider ?? "codex";
const provider = options?.provider ?? ProviderDriverKind.make("codex");
const useRealCodex = options?.realCodex === true;
const adapterHarness = useRealCodex
? null
: yield* makeTestProviderAdapterHarness({
provider,
});
const fakeRegistry = adapterHarness
? Layer.succeed(ProviderAdapterRegistry, {
getByProvider: (resolvedProvider) =>
resolvedProvider === adapterHarness.provider
? Effect.succeed(adapterHarness.adapter)
: Effect.fail(new ProviderUnsupportedError({ provider: resolvedProvider })),
listProviders: () => Effect.succeed([adapterHarness.provider]),
} as typeof ProviderAdapterRegistry.Service)
? Layer.succeed(
ProviderAdapterRegistry,
makeAdapterRegistryMock({ [adapterHarness.provider]: adapterHarness.adapter }),
)
: null;
const rootDir = yield* fileSystem.makeTempDirectoryScoped({
prefix: "t3-orchestration-integration-",
Expand All @@ -264,31 +265,30 @@ export const makeOrchestrationIntegrationHarness = (
const realCodexRegistry = Layer.effect(
ProviderAdapterRegistry,
Effect.gen(function* () {
const codexAdapter = yield* CodexAdapter;
return {
getByProvider: (resolvedProvider) =>
resolvedProvider === "codex"
? Effect.succeed(codexAdapter)
: Effect.fail(new ProviderUnsupportedError({ provider: resolvedProvider })),
listProviders: () => Effect.succeed(["codex"] as const),
} as typeof ProviderAdapterRegistry.Service;
const codexSettings = Schema.decodeSync(CodexSettings)({});
const codexAdapter = yield* makeCodexAdapter(codexSettings);
return makeAdapterRegistryMock({
[ProviderDriverKind.make("codex")]: codexAdapter,
});
}),
).pipe(
Layer.provide(makeCodexAdapterLive()),
Layer.provideMerge(ServerConfig.layerTest(workspaceDir, rootDir)),
Layer.provideMerge(NodeServices.layer),
Layer.provideMerge(providerSessionDirectoryLayer),
);
const providerEventLoggersLayer = Layer.succeed(ProviderEventLoggers, NoOpProviderEventLoggers);
const providerLayer = useRealCodex
? makeProviderServiceLive().pipe(
Layer.provide(providerSessionDirectoryLayer),
Layer.provide(realCodexRegistry),
Layer.provide(AnalyticsService.layerTest),
Layer.provide(providerEventLoggersLayer),
)
: makeProviderServiceLive().pipe(
Layer.provide(providerSessionDirectoryLayer),
Layer.provide(fakeRegistry!),
Layer.provide(AnalyticsService.layerTest),
Layer.provide(providerEventLoggersLayer),
);

const checkpointStoreLayer = CheckpointStoreLive.pipe(Layer.provide(GitCoreLive));
Expand Down
22 changes: 13 additions & 9 deletions apps/server/integration/TestProviderAdapter.integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ProviderTurnStartResult,
ThreadId,
TurnId,
ProviderKind,
ProviderDriverKind,
} from "@t3tools/contracts";
import { Effect, Queue, Stream } from "effect";

Expand All @@ -24,7 +24,6 @@ import type {
ProviderThreadSnapshot,
ProviderThreadTurnSnapshot,
} from "../src/provider/Services/ProviderAdapter.ts";
import { getProviderCapabilities } from "../src/provider/Services/ProviderAdapter.ts";

export interface TestTurnResponse {
readonly events: ReadonlyArray<FixtureProviderRuntimeEvent>;
Expand All @@ -37,7 +36,7 @@ export interface TestTurnResponse {
export type FixtureProviderRuntimeEvent = {
readonly type: string;
readonly eventId: EventId;
readonly provider: ProviderKind;
readonly provider: ProviderDriverKind;
readonly createdAt: string;
readonly threadId: string;
readonly turnId?: string | undefined;
Expand Down Expand Up @@ -179,7 +178,7 @@ function normalizeFixtureEvent(rawEvent: Record<string, unknown>): ProviderRunti

export interface TestProviderAdapterHarness {
readonly adapter: ProviderAdapterShape<ProviderAdapterError>;
readonly provider: ProviderKind;
readonly provider: ProviderDriverKind;
readonly queueTurnResponse: (
threadId: ThreadId,
response: TestTurnResponse,
Expand All @@ -199,15 +198,15 @@ export interface TestProviderAdapterHarness {
}

interface MakeTestProviderAdapterHarnessOptions {
readonly provider?: ProviderKind;
readonly provider?: ProviderDriverKind;
}

function nowIso(): string {
return new Date().toISOString();
}

function sessionNotFound(
provider: ProviderKind,
provider: ProviderDriverKind,
threadId: ThreadId,
): ProviderAdapterSessionNotFoundError {
return new ProviderAdapterSessionNotFoundError({
Expand All @@ -217,15 +216,15 @@ function sessionNotFound(
}

function missingSessionEffect(
provider: ProviderKind,
provider: ProviderDriverKind,
threadId: ThreadId,
): Effect.Effect<never, ProviderAdapterError> {
return Effect.fail(sessionNotFound(provider, threadId));
}

export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapterHarnessOptions) =>
Effect.gen(function* () {
const provider = options?.provider ?? "codex";
const provider = options?.provider ?? ProviderDriverKind.make("codex");
const runtimeEvents = yield* Queue.unbounded<ProviderRuntimeEvent>();
let sessionCount = 0;
const sessions = new Map<ThreadId, SessionState>();
Expand Down Expand Up @@ -258,6 +257,9 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter

const session: ProviderSession = {
provider,
...(input.providerInstanceId !== undefined
? { providerInstanceId: input.providerInstanceId }
: {}),
status: "ready",
runtimeMode: input.runtimeMode,
threadId,
Expand Down Expand Up @@ -475,7 +477,9 @@ export const makeTestProviderAdapterHarness = (options?: MakeTestProviderAdapter

const adapter: ProviderAdapterShape<ProviderAdapterError> = {
provider,
capabilities: getProviderCapabilities(provider),
capabilities: {
sessionModelSwitch: "in-session",
},
startSession,
sendTurn,
interruptTurn,
Expand Down
4 changes: 2 additions & 2 deletions apps/server/integration/fixtures/providerRuntime.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EventId, RuntimeRequestId } from "@t3tools/contracts";
import { EventId, ProviderDriverKind, RuntimeRequestId } from "@t3tools/contracts";
import type { LegacyProviderRuntimeEvent } from "../TestProviderAdapter.integration.ts";

const PROVIDER = "codex" as const;
const PROVIDER = ProviderDriverKind.make("codex");
const SESSION_ID = "fixture-session";
const THREAD_ID = "fixture-thread";
const TURN_ID = "fixture-turn";
Expand Down
Loading
Loading