Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b225dfa
Make server settings authoritative
juliusmarminge Mar 25, 2026
3f089a4
layers
juliusmarminge Mar 25, 2026
a9aa5c4
Centralize provider settings under server authority
juliusmarminge Mar 25, 2026
f942c34
mv
juliusmarminge Mar 25, 2026
14e81b9
lint
juliusmarminge Mar 25, 2026
69e5d81
Default server settings providers object
juliusmarminge Mar 25, 2026
d6099ed
fix expectation
juliusmarminge Mar 25, 2026
5b750e2
use more lenient json parse
juliusmarminge Mar 25, 2026
007bd17
kewl
juliusmarminge Mar 25, 2026
7b0c9c0
kewl
juliusmarminge Mar 25, 2026
da0eaff
rm reexport shi
juliusmarminge Mar 25, 2026
c91bd26
fix
juliusmarminge Mar 26, 2026
619fd20
mv to contract package
juliusmarminge Mar 26, 2026
6715932
mv
juliusmarminge Mar 26, 2026
57ff0ae
fix
juliusmarminge Mar 26, 2026
19f09b7
nit
juliusmarminge Mar 26, 2026
5372668
pass configured binary to health checks
juliusmarminge Mar 26, 2026
b4b3b2b
rm reexport
juliusmarminge Mar 26, 2026
7757947
Move provider settings authority into server settings
juliusmarminge Mar 26, 2026
89e7550
Make server settings test layer stateful
juliusmarminge Mar 26, 2026
9320fc8
Centralize provider checks on server settings
juliusmarminge Mar 26, 2026
e57fec3
kewl
juliusmarminge Mar 26, 2026
6f34ca0
fix race
juliusmarminge Mar 26, 2026
9934b6e
Preserve environment when launching Codex text generation
juliusmarminge Mar 26, 2026
e39cf66
Make server settings startup atomic
juliusmarminge Mar 26, 2026
37c30f5
Avoid publishing unchanged provider snapshots
juliusmarminge Mar 26, 2026
9d390e3
restrcit objects for deepMerge
juliusmarminge Mar 26, 2026
dc7465a
Add provider refresh action to settings
juliusmarminge Mar 26, 2026
11d5a70
Use server settings when generating worktree branch names
juliusmarminge Mar 26, 2026
21838dc
Clean up temp files after atomic settings writes
juliusmarminge Mar 26, 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
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
type TestProviderAdapterHarness,
} from "./TestProviderAdapter.integration.ts";
import { deriveServerPaths, ServerConfig } from "../src/config.ts";
import { ServerSettingsService } from "../src/serverSettings.ts";

function runGit(cwd: string, args: ReadonlyArray<string>) {
return execFileSync("git", args, {
Expand Down Expand Up @@ -138,7 +139,7 @@
while: (error) => error === RETRY_SIGNAL,
}),
Effect.mapError((error) =>
error === RETRY_SIGNAL ? new WaitForTimeoutError({ description }) : error,

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > forwards thread.turn.interrupt to claudeAgent provider sessions

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > forwards claudeAgent approval responses to the provider session

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > recovers claudeAgent sessions after provider stopAll using persisted resume state

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > starts a claudeAgent session on first turn when provider is requested

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > reverts to an earlier checkpoint and trims checkpoint projections + git refs

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > records failed turn runtime state and checkpoint status as error

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > tracks approval requests and resolves pending approvals on user response

{ description: "projected thread 'thread-1'", _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effec

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > runs multi-turn file edits and persists checkpoint diffs

{ description: 'runtime receipt', _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts',

Check failure on line 142 in apps/server/integration/OrchestrationEngineHarness.integration.ts

View workflow job for this annotation

GitHub Actions / Format, Lint, Typecheck, Test, Browser Test, Build

integration/orchestrationEngine.integration.test.ts > runs a single turn end-to-end and persists checkpoint state in sqlite + git

{ description: 'runtime receipt', _tag: 'WaitForTimeoutError', message: '', stack: 'Error: \n' + ' at /home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts:142:32\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:1299:96\n' + ' at ~effect/Effect/internal (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/Utils.js:74:12)\n' + ' at Object.~effect/Effect/args (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:660:53)\n' + ' at Object.~effect/Effect/evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:624:22)\n' + ' at FiberImpl.runLoop (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:439:107)\n' + ' at FiberImpl.evaluate (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:407:23)\n' + ' at file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:709:15\n' + ' at Timeout._onTimeout (file:///home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/dist/internal/effect.js:2484:39)\n' + ' at listOnTimeout (node:internal/timers:605:17)', name: 'Error', stacks: [ { method: '', file: '/home/runner/_work/t3code/t3code/apps/server/integration/OrchestrationEngineHarness.integration.ts', line: 142, column: 32 }, { line: 3131, column: 72, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: '' }, { line: 190, column: 11, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/Utils.ts', method: 'body' }, { line: 932, column: 94, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'internalCall' }, { line: 878, column: 21, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'Object.~effect/Effect/evaluate' }, { line: 626, column: 39, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'FiberImpl.runLoop' }, { line: 587, column: 22, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'runLoop' }, { line: 1018, column: 14, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts', method: 'evaluate' }, { line: 5682, column: 38, file: '/home/runner/_work/t3code/t3code/node_modules/.bun/effect@https+++pkg.pr.new+Effect-TS+effect-smol+effect@8881a9b/node_modules/effect/src/internal/effect.ts',
),
Effect.orDie,
);
Expand Down Expand Up @@ -295,8 +296,10 @@
providerLayer,
RuntimeReceiptBusLive,
);
const serverSettingsLayer = ServerSettingsService.layerTest();
const runtimeIngestionLayer = ProviderRuntimeIngestionLive.pipe(
Layer.provideMerge(runtimeServicesLayer),
Layer.provideMerge(serverSettingsLayer),
);
const gitCoreLayer = Layer.succeed(GitCore, {
renameBranch: (input: Parameters<GitCoreShape["renameBranch"]>[0]) =>
Expand All @@ -309,6 +312,7 @@
Layer.provideMerge(runtimeServicesLayer),
Layer.provideMerge(gitCoreLayer),
Layer.provideMerge(textGenerationLayer),
Layer.provideMerge(serverSettingsLayer),
);
const checkpointReactorLayer = CheckpointReactorLive.pipe(
Layer.provideMerge(runtimeServicesLayer),
Expand Down
2 changes: 1 addition & 1 deletion apps/server/src/codexAppServerManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ export class CodexAppServerManager extends EventEmitter<CodexAppServerManagerEve
};

const codexOptions = readCodexProviderOptions(input);
const codexBinaryPath = codexOptions.binaryPath ?? "codex";
const codexBinaryPath = codexOptions.binaryPath || "codex";
const codexHomePath = codexOptions.homePath;
this.assertSupportedCodexCliVersion({
binaryPath: codexBinaryPath,
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface ServerDerivedPaths {
readonly stateDir: string;
readonly dbPath: string;
readonly keybindingsConfigPath: string;
readonly settingsPath: string;
readonly worktreesDir: string;
readonly attachmentsDir: string;
readonly logsDir: string;
Expand Down Expand Up @@ -60,6 +61,7 @@ export const deriveServerPaths = Effect.fn(function* (
stateDir,
dbPath,
keybindingsConfigPath: join(stateDir, "keybindings.json"),
settingsPath: join(stateDir, "settings.json"),
worktreesDir: join(baseDir, "worktrees"),
attachmentsDir,
logsDir,
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/git/Layers/ClaudeTextGeneration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import { expect } from "vitest";
import { ServerConfig } from "../../config.ts";
import { TextGeneration } from "../Services/TextGeneration.ts";
import { ClaudeTextGenerationLive } from "./ClaudeTextGeneration.ts";
import { ServerSettingsService } from "../../serverSettings.ts";

const ClaudeTextGenerationTestLayer = ClaudeTextGenerationLive.pipe(
Layer.provideMerge(ServerSettingsService.layerTest()),
Layer.provideMerge(
ServerConfig.layerTest(process.cwd(), {
prefix: "t3code-claude-text-generation-test-",
Expand Down
9 changes: 8 additions & 1 deletion apps/server/src/git/Layers/ClaudeTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
sanitizePrTitle,
toJsonSchemaObject,
} from "../Utils.ts";
import { ServerSettingsService } from "../../serverSettings.ts";

const CLAUDE_TIMEOUT_MS = 180_000;

Expand All @@ -40,6 +41,7 @@ const ClaudeOutputEnvelope = Schema.Struct({

const makeClaudeTextGeneration = Effect.gen(function* () {
const commandSpawner = yield* ChildProcessSpawner.ChildProcessSpawner;
const serverSettingsService = yield* Effect.service(ServerSettingsService);

const readStreamAsString = <E>(
operation: string,
Expand Down Expand Up @@ -86,9 +88,14 @@ const makeClaudeTextGeneration = Effect.gen(function* () {
...(normalizedOptions?.fastMode ? { fastMode: true } : {}),
};

const claudeSettings = yield* Effect.map(
serverSettingsService.getSettings,
(settings) => settings.providers.claudeAgent,
).pipe(Effect.catch(() => Effect.undefined));

const runClaudeCommand = Effect.gen(function* () {
const command = ChildProcess.make(
"claude",
claudeSettings?.binaryPath || "claude",
[
"-p",
"--output-format",
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/git/Layers/CodexTextGeneration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { ServerConfig } from "../../config.ts";
import { CodexTextGenerationLive } from "./CodexTextGeneration.ts";
import { TextGenerationError } from "../Errors.ts";
import { TextGeneration } from "../Services/TextGeneration.ts";
import { ServerSettingsService } from "../../serverSettings.ts";

const DEFAULT_TEST_MODEL_SELECTION = {
provider: "codex" as const,
model: "gpt-5.4-mini",
};

const CodexTextGenerationTestLayer = CodexTextGenerationLive.pipe(
Layer.provideMerge(ServerSettingsService.layerTest()),
Layer.provideMerge(
ServerConfig.layerTest(process.cwd(), {
prefix: "t3code-codex-text-generation-test-",
Expand Down
10 changes: 9 additions & 1 deletion apps/server/src/git/Layers/CodexTextGeneration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
sanitizePrTitle,
toJsonSchemaObject,
} from "../Utils.ts";
import { ServerSettingsService } from "../../serverSettings.ts";

const CODEX_GIT_TEXT_GENERATION_REASONING_EFFORT = "low";
const CODEX_TIMEOUT_MS = 180_000;
Expand All @@ -35,6 +36,7 @@ const makeCodexTextGeneration = Effect.gen(function* () {
const path = yield* Path.Path;
const commandSpawner = yield* ChildProcessSpawner.ChildProcessSpawner;
const serverConfig = yield* Effect.service(ServerConfig);
const serverSettingsService = yield* Effect.service(ServerSettingsService);

type MaterializedImageAttachments = {
readonly imagePaths: ReadonlyArray<string>;
Expand Down Expand Up @@ -138,6 +140,11 @@ const makeCodexTextGeneration = Effect.gen(function* () {
);
const outputPath = yield* writeTempFile(operation, "codex-output", "");

const codexSettings = yield* Effect.map(
serverSettingsService.getSettings,
(settings) => settings.providers.codex,
).pipe(Effect.catch(() => Effect.undefined));

const runCodexCommand = Effect.gen(function* () {
const normalizedOptions = normalizeCodexModelOptions(
modelSelection.model,
Expand All @@ -146,7 +153,7 @@ const makeCodexTextGeneration = Effect.gen(function* () {
const reasoningEffort =
modelSelection.options?.reasoningEffort ?? CODEX_GIT_TEXT_GENERATION_REASONING_EFFORT;
const command = ChildProcess.make(
"codex",
codexSettings?.binaryPath || "codex",
[
"exec",
"--ephemeral",
Expand All @@ -165,6 +172,7 @@ const makeCodexTextGeneration = Effect.gen(function* () {
"-",
],
{
env: codexSettings?.homePath ? { CODEX_HOME: codexSettings.homePath } : {},
Comment thread
macroscopeapp[bot] marked this conversation as resolved.
Outdated
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
cwd,
shell: process.platform === "win32",
stdin: {
Expand Down
10 changes: 4 additions & 6 deletions apps/server/src/git/Layers/GitManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ import { GitCoreLive } from "./GitCore.ts";
import { GitCore } from "../Services/GitCore.ts";
import { makeGitManager } from "./GitManager.ts";
import { ServerConfig } from "../../config.ts";

const DEFAULT_TEST_MODEL_SELECTION = {
provider: "codex",
model: "gpt-5.4-mini",
} as const;
import { ServerSettingsService } from "../../serverSettings.ts";

interface FakeGhScenario {
prListSequence?: string[];
Expand Down Expand Up @@ -466,7 +462,6 @@ function runStackedAction(
{
...input,
actionId: input.actionId ?? "test-action-id",
modelSelection: DEFAULT_TEST_MODEL_SELECTION,
},
options,
);
Expand All @@ -493,6 +488,8 @@ function makeManager(input?: {
prefix: "t3-git-manager-test-",
});

const serverSettingsLayer = ServerSettingsService.layerTest();

const gitCoreLayer = GitCoreLive.pipe(
Layer.provideMerge(NodeServices.layer),
Layer.provideMerge(ServerConfigLayer),
Expand All @@ -502,6 +499,7 @@ function makeManager(input?: {
Layer.succeed(GitHubCli, gitHubCli),
Layer.succeed(TextGeneration, textGeneration),
gitCoreLayer,
serverSettingsLayer,
).pipe(Layer.provideMerge(NodeServices.layer));

return makeGitManager.pipe(
Expand Down
15 changes: 12 additions & 3 deletions apps/server/src/git/Layers/GitManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
import { GitCore } from "../Services/GitCore.ts";
import { GitHubCli } from "../Services/GitHubCli.ts";
import { TextGeneration } from "../Services/TextGeneration.ts";
import { ServerSettingsService } from "../../serverSettings.ts";

const COMMIT_TIMEOUT_MS = 10 * 60_000;
const MAX_PROGRESS_TEXT_LENGTH = 500;
Expand Down Expand Up @@ -358,6 +359,7 @@ export const makeGitManager = Effect.gen(function* () {
const gitCore = yield* GitCore;
const gitHubCli = yield* GitHubCli;
const textGeneration = yield* TextGeneration;
const serverSettingsService = yield* ServerSettingsService;

const createProgressEmitter = (
input: { cwd: string; action: "commit" | "commit_push" | "commit_push_pr" },
Expand Down Expand Up @@ -1173,6 +1175,13 @@ export const makeGitManager = Effect.gen(function* () {
let commitMessageForStep = input.commitMessage;
let preResolvedCommitSuggestion: CommitAndBranchSuggestion | undefined = undefined;

const modelSelection = yield* serverSettingsService.getSettings.pipe(
Effect.map((settings) => settings.textGenerationModelSelection),
Effect.mapError((cause) =>
gitManagerError("runStackedAction", "Failed to get server settings.", cause),
),
);

if (input.featureBranch) {
currentPhase = "branch";
yield* progress.emit({
Expand All @@ -1181,7 +1190,7 @@ export const makeGitManager = Effect.gen(function* () {
label: "Preparing feature branch...",
});
const result = yield* runFeatureBranchStep(
input.modelSelection,
modelSelection,
input.cwd,
initialStatus.branch,
input.commitMessage,
Expand All @@ -1198,7 +1207,7 @@ export const makeGitManager = Effect.gen(function* () {

currentPhase = "commit";
const commit = yield* runCommitStep(
input.modelSelection,
modelSelection,
input.cwd,
input.action,
currentBranch,
Expand Down Expand Up @@ -1237,7 +1246,7 @@ export const makeGitManager = Effect.gen(function* () {
Effect.flatMap(() =>
Effect.gen(function* () {
currentPhase = "pr";
return yield* runPrStep(input.modelSelection, input.cwd, currentBranch);
return yield* runPrStep(modelSelection, input.cwd, currentBranch);
}),
),
)
Expand Down
33 changes: 22 additions & 11 deletions apps/server/src/keybindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
Cache,
Cause,
Deferred,
Duration,
Effect,
Exit,
FileSystem,
Expand All @@ -42,6 +43,7 @@ import {
} from "effect";
import * as Semaphore from "effect/Semaphore";
import { ServerConfig } from "./config";
import { fromLenientJson } from "@t3tools/shared/schemaJson";

export class KeybindingsConfigError extends Schema.TaggedErrorClass<KeybindingsConfigError>()(
"KeybindingsConfigParseError",
Expand Down Expand Up @@ -408,7 +410,7 @@ function encodeWhenAst(node: KeybindingWhenNode): string {

const DEFAULT_RESOLVED_KEYBINDINGS = compileResolvedKeybindingsConfig(DEFAULT_KEYBINDINGS);

const RawKeybindingsEntries = Schema.fromJsonString(Schema.Array(Schema.Unknown));
const RawKeybindingsEntries = fromLenientJson(Schema.Array(Schema.Unknown));
const KeybindingsConfigJson = Schema.fromJsonString(KeybindingsConfig);
const PrettyJsonString = SchemaGetter.parseJson<string>().compose(
SchemaGetter.stringifyJson({ space: 2 }),
Expand Down Expand Up @@ -817,16 +819,25 @@ const makeKeybindings = Effect.gen(function* () {

const revalidateAndEmitSafely = revalidateAndEmit.pipe(Effect.ignoreCause({ log: true }));

yield* Stream.runForEach(fs.watch(keybindingsConfigDir), (event) => {
const isTargetConfigEvent =
event.path === keybindingsConfigFile ||
event.path === keybindingsConfigPath ||
path.resolve(keybindingsConfigDir, event.path) === keybindingsConfigPathResolved;
if (!isTargetConfigEvent) {
return Effect.void;
}
return revalidateAndEmitSafely;
}).pipe(Effect.ignoreCause({ log: true }), Effect.forkIn(watcherScope), Effect.asVoid);
// Debounce watch events so the file is fully written before we read it.
// Editors emit multiple events per save (truncate, write, rename) and
// `fs.watch` can fire before the content has been flushed to disk.
const debouncedKeybindingsEvents = fs.watch(keybindingsConfigDir).pipe(
Stream.filter((event) => {
return (
event.path === keybindingsConfigFile ||
event.path === keybindingsConfigPath ||
path.resolve(keybindingsConfigDir, event.path) === keybindingsConfigPathResolved
);
}),
Stream.debounce(Duration.millis(100)),
);

yield* Stream.runForEach(debouncedKeybindingsEvents, () => revalidateAndEmitSafely).pipe(
Effect.ignoreCause({ log: true }),
Effect.forkIn(watcherScope),
Effect.asVoid,
);
});

const start = Effect.gen(function* () {
Expand Down
10 changes: 10 additions & 0 deletions apps/server/src/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as ConfigProvider from "effect/ConfigProvider";
import * as Effect from "effect/Effect";
import * as FileSystem from "effect/FileSystem";
import * as Layer from "effect/Layer";
import * as Stream from "effect/Stream";
import * as Command from "effect/unstable/cli/Command";
import { FetchHttpClient } from "effect/unstable/http";
import { beforeEach } from "vitest";
Expand All @@ -16,7 +17,9 @@ import { ServerConfig, type ServerConfigShape } from "./config";
import { Open, type OpenShape } from "./open";
import { ProjectionSnapshotQuery } from "./orchestration/Services/ProjectionSnapshotQuery";
import { AnalyticsService } from "./telemetry/Services/AnalyticsService";
import { DEFAULT_SERVER_SETTINGS } from "@t3tools/contracts";
import { Server, type ServerShape } from "./wsServer";
import { ServerSettingsService, type ServerSettingsShape } from "./serverSettings";

const start = vi.fn(() => undefined);
const stop = vi.fn(() => undefined);
Expand Down Expand Up @@ -52,6 +55,13 @@ const testLayer = Layer.mergeAll(
openBrowser: (_target: string) => Effect.void,
openInEditor: () => Effect.void,
} satisfies OpenShape),
Layer.succeed(ServerSettingsService, {
start: Effect.void,
ready: Effect.void,
getSettings: Effect.succeed(DEFAULT_SERVER_SETTINGS),
updateSettings: () => Effect.succeed(DEFAULT_SERVER_SETTINGS),
streamChanges: Stream.empty,
} satisfies ServerSettingsShape),
AnalyticsService.layerTest,
FetchHttpClient.layer,
NodeServices.layer,
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { ServerLoggerLive } from "./serverLogger";
import { AnalyticsServiceLayerLive } from "./telemetry/Layers/AnalyticsService";
import { AnalyticsService } from "./telemetry/Services/AnalyticsService";
import { readBootstrapEnvelope } from "./bootstrap";
import { ServerSettingsLive } from "./serverSettings";

export class StartupError extends Data.TaggedError("StartupError")<{
readonly message: string;
Expand Down Expand Up @@ -297,6 +298,7 @@ const LayerLive = (input: CliInput) =>
Layer.provideMerge(SqlitePersistence.layerConfig),
Layer.provideMerge(ServerLoggerLive),
Layer.provideMerge(AnalyticsServiceLayerLive),
Layer.provideMerge(ServerSettingsLive),
Layer.provideMerge(ServerConfigLive(input)),
);

Expand Down
Comment thread
juliusmarminge marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { ProviderCommandReactorLive } from "./ProviderCommandReactor.ts";
import { OrchestrationEngineService } from "../Services/OrchestrationEngine.ts";
import { ProviderCommandReactor } from "../Services/ProviderCommandReactor.ts";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { ServerSettingsService } from "../../serverSettings.ts";

const asProjectId = (value: string): ProjectId => ProjectId.makeUnsafe(value);
const asApprovalRequestId = (value: string): ApprovalRequestId =>
Expand Down Expand Up @@ -214,6 +215,7 @@ describe("ProviderCommandReactor", () => {
Layer.provideMerge(
Layer.succeed(TextGeneration, { generateBranchName } as unknown as TextGenerationShape),
),
Layer.provideMerge(ServerSettingsService.layerTest()),
Layer.provideMerge(ServerConfig.layerTest(process.cwd(), baseDir)),
Layer.provideMerge(NodeServices.layer),
);
Expand Down
Loading
Loading