Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
fe0e8d4
fix(mobile): dragging a microphone or environment route now saves its…
juliusmarminge Oct 27, 2026
bbd9593
feat(web): channel artwork choice on Latest, plus nightly or dev art …
maria-rcks Oct 27, 2026
5b70d81
feat(mobile): browse ZIP attachments with the shared archive reader (…
Bil0000 Oct 27, 2026
8d94203
fix(server): Claude --settings launch args merge with T3's settings i…
t3dotgg Oct 27, 2026
a27ec88
feat(server,web): see and stop the dev servers a thread started (#22542)
t3dotgg Oct 27, 2026
f08136d
fix(web): composer no longer jumps when a second line is added (#26155)
maria-rcks Oct 27, 2026
b31de68
feat(web,mobile): queued messages show who sent them (#26159)
juliusmarminge Oct 27, 2026
8f0b729
fix(preview): agent and browser panel show the same page after a late…
t3dotgg Oct 27, 2026
1cf14a4
fix(web): pairing, connect, error, and Clerk sign-in surfaces match t…
maria-rcks Oct 27, 2026
3b22620
fix(server): parallel worktree launches no longer fail on .git/config…
juliusmarminge Oct 27, 2026
4cb5f10
fix(task-cache): the hook test waits for every flusher it starts (#26…
juliusmarminge Oct 27, 2026
33d0c96
chore(lint): every React effect states its reason at the call site (#…
juliusmarminge Oct 27, 2026
0637f87
test(server): the link-card retry test names a new MCP credential (#2…
juliusmarminge Oct 27, 2026
e66ffcc
perf(web): stop measuring table cells while replies stream (#26152)
t3dotgg Oct 27, 2026
dde3fdb
feat(desktop): add a remote server by clicking its t3code://pair link…
t3dotgg Oct 27, 2026
cb7e381
chore(mobile): e2e runner retries pool failures and reports them apar…
juliusmarminge Oct 27, 2026
867112c
fix(server): agent questions stay answerable after a server restart (…
SunkenInTime Oct 27, 2026
34ca613
chore(lint): the effect lint error walks the alternatives before the …
juliusmarminge Oct 27, 2026
4fc9e5f
fix(web): settings avatar no longer hugs the modal corner (#26180)
t3dotgg Oct 27, 2026
622bc06
fix(mobile): shared file names can no longer write outside the Androi…
juliusmarminge Oct 27, 2026
80b7b0f
fix(server): repository lookups no longer send GitHub tokens to arbit…
juliusmarminge Oct 27, 2026
f0c1da3
fix(github): long period runs no longer freeze reference autolinking …
juliusmarminge Oct 27, 2026
0b7caf2
fix(mobile): Android diff ellipsis no longer measures text quadratica…
juliusmarminge Oct 27, 2026
b88da91
fix(server): Codex works again after its app-server is killed (#26188)
t3dotgg Oct 27, 2026
3ae672f
fix(desktop): ask once per site before a preview page reads the clipb…
juliusmarminge Oct 27, 2026
294981f
fix(mobile): Windows paths in messages keep their backslashes (#21454)
juliusmarminge Oct 27, 2026
7e884b2
feat: triage an issue from the command palette, no terminal needed (#…
t3dotgg Oct 27, 2026
a846084
fix(server): Forgejo required-check globs no longer hang the event lo…
juliusmarminge Oct 27, 2026
735cc3c
fix(server): fx's version policy reaches servers with a cached model …
juliusmarminge Oct 27, 2026
c570c2c
fix(mobile): keep iPad tab bar within narrow sidebars (#26198)
juliusmarminge Oct 28, 2026
c38b265
feat(web): filter the sidebar by several projects at once (#25284)
maria-rcks Oct 28, 2026
0894156
fix(mobile): provider accounts fit each provider on one row (#25861)
saphid Oct 28, 2026
531cee6
fix(server): Claude background-task wakes start when the queue is hel…
fireboltdude1357 Oct 28, 2026
68495b6
docs(testing): new tests extend existing cases and stay at one layer …
t3dotgg Oct 28, 2026
06d4b57
fix(web): composer strip drops the folder icon next to the machine ic…
maria-rcks Oct 28, 2026
7e71392
feat(web): background work line shows the newest activity, no dots (#…
maria-rcks Oct 28, 2026
7f2dcd8
fix(mobile): dictation buttons line up with the send button on every …
juliusmarminge Oct 28, 2026
df4132b
chore(mobile): e2e runs keep Metro's output, the app's console logs, …
juliusmarminge Oct 28, 2026
2e2d86c
chore(mobile): e2e Metro serves no lazy chunks
juliusmarminge Oct 28, 2026
4ab7084
feat(web,mobile): the @ picker lists threads on linked machines (#26201)
juliusmarminge Oct 28, 2026
0affd28
feat(web,mobile): Copy thread copies a chip that works on linked mach…
juliusmarminge Oct 28, 2026
5cf49d2
fix(mobile): unclosed code fences in HTML blocks no longer freeze PR …
juliusmarminge Oct 28, 2026
b5af460
fix(opencode): apply runtime mode changes to existing OpenCode sessio…
juliusmarminge Oct 28, 2026
8251578
fix(server): Antigravity file writes cannot escape the workspace thro…
juliusmarminge Oct 28, 2026
7a059b9
chore(mobile): e2e treats a failed daemon read as a pool error
juliusmarminge Oct 28, 2026
2525252
feat(web): F6 moves between workspace areas, and the sidebar is keybo…
t3dotgg Oct 28, 2026
575a03f
chore(review): Macroscope check agents move to GPT 6.1 Sol (#26187)
t3dotgg Oct 28, 2026
e2a8ef0
feat(dev): test turns in the UI for free with a replay provider (#26207)
t3dotgg Oct 28, 2026
93a9e07
feat(threads): choose your own snooze options in settings (#26208)
t3dotgg Oct 28, 2026
c3b40b9
fix(relay): stop delivery attempts from growing the database forever …
juliusmarminge Oct 28, 2026
9638e17
fix(relay): tunnel cleanup keeps up with new idle tunnels (#26135)
juliusmarminge Oct 28, 2026
4b00290
fix(server): delegate cgroups to agent scopes (#23913)
juliusmarminge Oct 28, 2026
3b2f958
fix(server): ACP Registry searches reuse a recently fetched index (#2…
juliusmarminge Oct 28, 2026
22163d5
Merge upstream/main 3b2f958603 into coder-only
henrychu04 Oct 28, 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: 2 additions & 0 deletions apps/server/src/coderEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ export const CODER_OMITTED_CAPABILITIES = {
peerLinks: "No linked environments: they need server-to-server /mcp and pairing.",
mcpModeLimitHeader: "No /mcp HTTP server; agents reach T3 tools over the workspace file bridge.",
linkFence: "No linked environments, so no work starts here from another one.",
localServerStop: "No dev-server port discovery: the browser preview is not carried.",
triage: "No in-app triage: it clones upstream T3 Code to help file upstream issues.",
} satisfies Partial<Record<keyof ExecutionEnvironmentCapabilities, string>>;

const platformArch = (): ExecutionEnvironmentDescriptor["platform"]["arch"] => {
Expand Down
118 changes: 95 additions & 23 deletions apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,19 @@ describe("ClaudeAdapterV2 native protocol logging", () => {
assert.isUndefined(logged.hasMcpServers);
assert.notInclude(JSON.stringify(options), "secret-claude-token");
});

it("logs --settings key names without their values", () => {
const options = ClaudeAdapterV2.makeClaudeQueryOptions({
modelSelection: CLAUDE_TEST_MODEL_SELECTION,
nativeThreadId: "native-thread-claude-settings-log",
resume: false,
cwd: "/workspace",
sdkSettings: { env: { ANTHROPIC_API_KEY: "secret-settings-key" } },
});
const logged = ClaudeAdapterV2.loggedClaudeQueryOptions(options);
assert.deepEqual(logged.settingKeys, ["env", "showThinkingSummaries"]);
assert.notInclude(JSON.stringify(logged), "secret-settings-key");
});
});

describe("ClaudeAdapterV2 context usage", () => {
Expand Down Expand Up @@ -923,6 +936,34 @@ describe("ClaudeAdapterV2 append-system-prompt-file launch argument", () => {
),
);

// regression: #15073 the SDK replaced the --settings launch argument with T3's settings
it.effect.each([
`--settings '{"skillOverrides":{"lint":"off"},"showThinkingSummaries":false}'`,
"--settings user-settings.json",
])("merges %s beneath T3's settings", (launchArgs) =>
Effect.scoped(
Effect.gen(function* () {
const fileSystem = yield* FileSystem.FileSystem;
const cwd = yield* fileSystem.makeTempDirectoryScoped({ prefix: "t3-claude-settings-" });
yield* fileSystem.writeFileString(
NodePath.join(cwd, "user-settings.json"),
'{"skillOverrides":{"lint":"off"},"showThinkingSummaries":false}',
);
const { exit, opened } = yield* startTurnWithLaunchArgs(launchArgs, cwd);
assert.isTrue(Exit.isSuccess(exit));
assert.deepInclude(opened[0]!.settings, {
skillOverrides: { lint: "off" },
showThinkingSummaries: true,
});
assert.isUndefined(opened[0]!.extraArgs?.["settings"]);
}).pipe(
Effect.provide(
Layer.mergeAll(IdAllocator.layer, McpProviderSessions.layer, NodeServices.layer),
),
),
),
);

// regression: #20413 malformed append-system-prompt launch args fail before a query opens
it.effect.each([
[
Expand Down Expand Up @@ -953,6 +994,19 @@ describe("ClaudeAdapterV2 append-system-prompt-file launch argument", () => {
flag: "--append-system-prompt",
}).message,
],
[
"--settings missing.json",
(cwd: string) =>
new ClaudeAdapterV2.ClaudeSettingsLaunchArgError({
path: NodePath.join(cwd, "missing.json"),
}).message,
],
["--settings '{not json}'", () => new ClaudeAdapterV2.ClaudeSettingsLaunchArgError({}).message],
// Without a closing brace this must not become a file path that echoes the secret.
[
`--settings '{"env":{"ANTHROPIC_API_KEY":"secret-settings-key"},'`,
() => new ClaudeAdapterV2.ClaudeSettingsLaunchArgError({}).message,
],
] as const)("fails the turn before opening Claude for %s", ([launchArgs, expectedMessage]) =>
Effect.scoped(
Effect.gen(function* () {
Expand Down Expand Up @@ -3209,29 +3263,31 @@ describe("ClaudeAdapterV2 background wake turns", () => {
const home = yield* fileSystem.makeTempDirectoryScoped({ prefix: "t3-claude-remote-" });
const cwd = yield* fileSystem.makeTempDirectoryScoped({ prefix: "t3-claude-remote-cwd-" });
const remoteFile = path.join(home, "remote-settings.json");
const open = Effect.scoped(
Effect.gen(function* () {
const harness = yield* makeWakeHarnessWithOptions({
settings: { ...DEFAULT_CLAUDE_SETTINGS, homePath: home },
});
yield* harness.runtime.startTurn(
makeClaudeTestTurnInput({
threadId: harness.threadId,
providerThread: harness.providerThread,
now: yield* DateTime.now,
attemptId: RunAttemptId.make("attempt-cached-managed-policy"),
text: "Run git status.",
attachments: [],
runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({
runtimeMode: "full-access",
interactionMode: "default",
cwd,
const openWith = (launchArgs: string) =>
Effect.scoped(
Effect.gen(function* () {
const harness = yield* makeWakeHarnessWithOptions({
settings: { ...DEFAULT_CLAUDE_SETTINGS, homePath: home, launchArgs },
});
yield* harness.runtime.startTurn(
makeClaudeTestTurnInput({
threadId: harness.threadId,
providerThread: harness.providerThread,
now: yield* DateTime.now,
attemptId: RunAttemptId.make("attempt-cached-managed-policy"),
text: "Run git status.",
attachments: [],
runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({
runtimeMode: "full-access",
interactionMode: "default",
cwd,
}),
}),
}),
);
return harness.getOpenedOptions()!;
}),
);
);
return harness.getOpenedOptions()!;
}),
);
const open = openWith("");
yield* fileSystem.writeFileString(
remoteFile,
JSON.stringify({
Expand All @@ -3245,6 +3301,11 @@ describe("ClaudeAdapterV2 background wake turns", () => {
assert.isUndefined(restricted.allowDangerouslySkipPermissions);
yield* fileSystem.remove(remoteFile);
assert.equal((yield* open).permissionMode, "bypassPermissions");
const launchRestricted = yield* openWith(
`--settings '{"permissions":{"disableBypassPermissionsMode":"disable"}}'`,
);
assert.equal(launchRestricted.permissionMode, "auto");
assert.isUndefined(launchRestricted.allowDangerouslySkipPermissions);
yield* fileSystem.writeFileString(remoteFile, "{ invalid json");
assert.equal((yield* open).permissionMode, "auto");
yield* fileSystem.remove(remoteFile);
Expand Down Expand Up @@ -3681,12 +3742,13 @@ describe("ClaudeAdapterV2 background wake turns", () => {
settingsJson: string,
cwd = CLAUDE_TEST_RUNTIME_POLICY.cwd,
environment?: NodeJS.ProcessEnv,
launchArgs = "",
) =>
Effect.scoped(
Effect.gen(function* () {
yield* fileSystem.writeFileString(path.join(home, "settings.json"), settingsJson);
const harness = yield* makeWakeHarnessWithOptions({
settings: { ...DEFAULT_CLAUDE_SETTINGS, homePath: home },
settings: { ...DEFAULT_CLAUDE_SETTINGS, homePath: home, launchArgs },
...(environment === undefined ? {} : { environment }),
});
yield* harness.runtime.startTurn(
Expand All @@ -3710,6 +3772,16 @@ describe("ClaudeAdapterV2 background wake turns", () => {
assert.equal(yield* openedToolSearch('{"env":{"ENABLE_TOOL_SEARCH":"auto"}}'), "true");
assert.isUndefined(yield* openedToolSearch('{"env":{"ENABLE_TOOL_SEARCH":"false"}}'));
assert.isUndefined(yield* openedToolSearch("{}"));
// --settings beats local, project, and user settings.
assert.equal(
yield* openedToolSearch(
'{"env":{"ENABLE_TOOL_SEARCH":"auto"}}',
CLAUDE_TEST_RUNTIME_POLICY.cwd,
undefined,
`--settings '{"env":{"ENABLE_TOOL_SEARCH":"false"}}'`,
),
"false",
);

// Claude Code keeps the local file at the repository root, the main checkout's root in a
// worktree, and that file beats the user's settings.
Expand Down
90 changes: 83 additions & 7 deletions apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,18 @@ export class ClaudeAppendSystemPromptMissingValueError extends Schema.TaggedErro
}
}

export class ClaudeSettingsLaunchArgError extends Schema.TaggedError<ClaudeSettingsLaunchArgError>()(
"ClaudeSettingsLaunchArgError",
{
path: Schema.optional(Schema.String),
cause: Schema.optional(Schema.Defect()),
},
) {
override get message(): string {
return `Claude could not read the --settings launch argument${this.path === undefined ? "" : ` at ${this.path}`} as a JSON object. Fix it in the Claude launch arguments, then send the message again.`;
}
}

export interface ClaudeAgentSdkQueryRunnerShape {
readonly allocateSessionId: Effect.Effect<string, ClaudeAgentSdkQueryRunnerError>;
readonly open: (
Expand Down Expand Up @@ -654,7 +666,7 @@ export interface ClaudeAgentSdkLoggedQueryOptions {
readonly cwd?: ClaudeAgentSdkQueryOptions["cwd"];
readonly allowedTools?: ClaudeAgentSdkQueryOptions["allowedTools"];
readonly disallowedTools?: ClaudeAgentSdkQueryOptions["disallowedTools"];
readonly settings?: ClaudeAgentSdkQueryOptions["settings"];
readonly settingKeys?: ReadonlyArray<string>;
readonly effort?: ClaudeAgentSdkQueryOptions["effort"];
readonly includePartialMessages?: true;
readonly pathToClaudeCodeExecutable?: ClaudeAgentSdkQueryOptions["pathToClaudeCodeExecutable"];
Expand Down Expand Up @@ -793,7 +805,10 @@ export function loggedClaudeQueryOptions(
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
...(options.allowedTools === undefined ? {} : { allowedTools: options.allowedTools }),
...(options.disallowedTools === undefined ? {} : { disallowedTools: options.disallowedTools }),
...(options.settings === undefined ? {} : { settings: options.settings }),
// Settings can carry the user's --settings values, such as an env block with credentials.
...(typeof options.settings === "object" && options.settings !== null
? { settingKeys: Object.keys(options.settings) }
: {}),
...(options.effort === undefined ? {} : { effort: options.effort }),
...(options.includePartialMessages === true ? { includePartialMessages: true } : {}),
...(options.pathToClaudeCodeExecutable === undefined
Expand Down Expand Up @@ -876,6 +891,8 @@ export const layerQueryRunner: Layer.Layer<
Stream.toAsyncIterable,
);
// Send MCP credentials over stdin to keep them out of SDK argv and inherited command environments.
// Coder: no dev-server port discovery (#22542) runs here, since the browser preview is not
// carried, so jobs the agent starts get no thread marker and the agent is not tracked.
const { mcpServers, ...queryOptions } = input.options;
// The SDK can prepend a scope wrapper to native binaries; script entries run through node.
const binaryPath = queryOptions.pathToClaudeCodeExecutable;
Expand Down Expand Up @@ -1358,6 +1375,8 @@ export function makeClaudeQueryOptions(input: {
"dangerously-skip-permissions": launchArgSkipPermissions,
"append-system-prompt": launchArgAppendSystemPrompt,
"append-system-prompt-file": _launchArgAppendSystemPromptFile,
// The SDK replaces this flag with options.settings, so it arrives read as sdkSettings.
settings: _launchArgSettings,
...extraArgs
} = input.settings === undefined ? {} : parseCliArgs(input.settings.launchArgs).flags;
// Claude Code overwrites its CLI append text with the SDK's initialize
Expand Down Expand Up @@ -1519,6 +1538,42 @@ const readClaudeAppendSystemPromptFile = Effect.fnUntraced(function* (input: {
);
});

const decodeClaudeLaunchArgSettings = Schema.decodeUnknownEffect(
fromLenientJson(Schema.Record(Schema.String, Schema.Unknown)),
);

/**
* Reads the --settings launch argument: a value starting with a brace is inline
* JSON, anything else is a file path relative to the cwd. makeClaudeQueryOptions
* merges the result beneath T3's own settings.
*/
const readClaudeLaunchArgSettings = Effect.fn("ClaudeAdapterV2.readLaunchArgSettings")(
function* (input: {
readonly settings: ClaudeSettings | undefined;
readonly cwd: string | null;
readonly fileSystem: FileSystem.FileSystem;
readonly path: Path.Path;
}) {
if (input.settings === undefined) return undefined;
const value = parseCliArgs(input.settings.launchArgs).flags.settings;
if (value === undefined) return undefined;
const trimmed = value?.trim() ?? "";
if (trimmed.length === 0) return yield* new ClaudeSettingsLaunchArgError({});
// The CLI also wants a closing brace, but then malformed JSON, secrets included, would
// become the file path in the error message.
if (trimmed.startsWith("{")) {
return (yield* decodeClaudeLaunchArgSettings(trimmed).pipe(
Effect.mapError((cause) => new ClaudeSettingsLaunchArgError({ cause })),
)) as ClaudeSdkSettings;
}
const filePath = input.path.resolve(input.cwd ?? ".", trimmed);
return (yield* input.fileSystem.readFileString(filePath).pipe(
Effect.flatMap(decodeClaudeLaunchArgSettings),
Effect.mapError((cause) => new ClaudeSettingsLaunchArgError({ path: filePath, cause })),
)) as ClaudeSdkSettings;
},
);

export const CLAUDE_T3_MCP_TOOL_WILDCARD = "mcp__t3-code__*";

// Keep in sync with OrchestratorToolkit Tool.Readonly annotations; ClaudeAdapterV2.test.ts checks this.
Expand Down Expand Up @@ -2422,6 +2477,7 @@ const ClaudeBypassSettings = Schema.StructWithRest(
const decodeClaudeBypassSettings = Schema.decodeUnknownEffect(
fromLenientJson(ClaudeBypassSettings),
);
const decodeClaudeLaunchArgBypassSettings = Schema.decodeUnknownEffect(ClaudeBypassSettings);

const ClaudePromptCacheTtl = Schema.Literals(["5m", "1h"]);
const decodeClaudePromptCacheTtl = Schema.decodeUnknownOption(ClaudePromptCacheTtl);
Expand Down Expand Up @@ -4195,7 +4251,14 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
readBypassSettings,
{ concurrency: "unbounded" },
);
return sources.map(claudeBypassAvailability).reduce<ClaudeBypassAvailability>(
const launchArgSettings = yield* readClaudeLaunchArgSettings({
settings: adapterOptions.settings,
cwd,
fileSystem,
path,
});
const launch = yield* decodeClaudeLaunchArgBypassSettings(launchArgSettings ?? {});
return [...sources, launch].map(claudeBypassAvailability).reduce<ClaudeBypassAvailability>(
(current, source) => ({
bypassDisabled: current.bypassDisabled || source.bypassDisabled,
autoDisabled: current.autoDisabled || source.autoDisabled,
Expand Down Expand Up @@ -4280,10 +4343,13 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
if (path.dirname(directory) === directory) return cwd;
}
});
// Settings env beats the process env, local over project over user, and a local file an older
// Claude Code left in cwd applies under the root one. resolveSettings reads local from cwd only.
// Settings env beats the process env, --settings over local over project over user, and a local
// file an older Claude Code left in cwd applies under the root one. resolveSettings reads local
// from cwd only.
const resolveToolSearchOverride = Effect.fn("ClaudeAdapterV2.resolveToolSearchOverride")(
function* (cwd: string | null) {
function* (cwd: string | null, launchArgSettings: ClaudeSdkSettings | undefined) {
const launchValue = launchArgSettings?.env?.ENABLE_TOOL_SEARCH;
if (typeof launchValue === "string") return claudeToolSearchOverride(launchValue);
const localDirectory = cwd === null ? null : yield* localSettingsDirectory(cwd);
const settingsFiles = [
...(cwd === null || localDirectory === null
Expand Down Expand Up @@ -9634,6 +9700,12 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
fileSystem,
path,
});
const launchArgSettings = yield* readClaudeLaunchArgSettings({
settings: adapterOptions.settings,
cwd: turnInput.runtimePolicy.cwd,
fileSystem,
path,
});
const closedExistingNativeThreadId = existing !== null ? existing.nativeThreadId : null;
if (existing !== null) {
yield* existing.query.close.pipe(Effect.ignore);
Expand All @@ -9656,7 +9728,10 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
openedWithResume || hasPersistedProviderTurn
? undefined
: turnInput.providerThread.nativeMetadata?.claudeFork;
const toolSearchOverride = yield* resolveToolSearchOverride(turnInput.runtimePolicy.cwd);
const toolSearchOverride = yield* resolveToolSearchOverride(
turnInput.runtimePolicy.cwd,
launchArgSettings,
);
const queryOptions = makeClaudeQueryOptions({
modelSelection: turnInput.modelSelection,
nativeThreadId,
Expand All @@ -9666,6 +9741,7 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
attachmentsDir,
settings: adapterOptions.settings,
...(forkFrom === undefined ? {} : { forkFrom }),
...(launchArgSettings === undefined ? {} : { sdkSettings: launchArgSettings }),
environment: claudeQueryEnvironment(
adapterOptions.environment,
turnInput.appThread,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ vi.mock("../../provider/Drivers/ClaudeAgentSdk.ts", { spy: true });

// Coder: upstream's fork tests copy the transcript through the Agent SDK; the CLI transport
// forks natively on the fork's first query (`ClaudeAdapterV2.forkThread`), so they are not carried.
// The runner does no port-discovery agent tracking (#22542), so that test is not carried either.
const realQueryRunner = layerQueryRunner.pipe(
Layer.provide(
Layer.succeed(ProviderEventLoggers, {
Expand Down
Loading