Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
36d4d71
fix(server): bound hung delegated stop effects so later runs can star…
juliusmarminge Oct 27, 2026
dc84b09
feat(mobile): add One UI navigation preference on Android (#25758)
PixPMusic Oct 27, 2026
5b15cfc
fix(mobile): center Android sheets and fit book-mode sheets in the le…
PixPMusic Oct 27, 2026
2ba1a09
fix(mobile): keep the collapsed Android rail square (#26039)
PixPMusic Oct 27, 2026
d0b81ce
fix(web): closing the last Browser tab hides the right panel again (#…
juliusmarminge Oct 27, 2026
21762b5
refactor(web): pull requests Cmd+F focuses the topbar search directly…
juliusmarminge Oct 27, 2026
6369e28
refactor(web): install draft model reconciliation at app start (#26046)
juliusmarminge Oct 27, 2026
03186e0
perf(mobile): project favicons mount their image in one commit (#26047)
juliusmarminge Oct 27, 2026
7b4c4b4
refactor(web): the upload queue alone records finished file uploads o…
juliusmarminge Oct 27, 2026
9ff0597
feat(mobile): Usage uses the width on iPad and unfolded phones (#26061)
juliusmarminge Oct 27, 2026
3a87681
fix(gitcafe): PR panel follows renumbered pull requests (#26079)
juliusmarminge Oct 27, 2026
bc1ea26
chore(infra): bump Alchemy to 2.0.0-beta.84 (#26057)
juliusmarminge Oct 27, 2026
d1c4b52
refactor(mobile): stop writing the resolved project filter back from …
juliusmarminge Oct 27, 2026
76d5ec7
fix(mobile): a pairing link fills the open Add environment form inste…
juliusmarminge Oct 27, 2026
a56ecda
fix(mobile): snooze menu times advance with the clock (#26043)
juliusmarminge Oct 27, 2026
0232932
fix(clients): prompt links find projects cloned from git.cafe (#26042)
juliusmarminge Oct 27, 2026
740de0e
fix(server): retry Codex capacity failures with empty input (#25611)
Yash-Singh1 Oct 27, 2026
07242ab
fix(server): recover handoffs when target context is exhausted (#25610)
Yash-Singh1 Oct 27, 2026
4914cdd
fix(web): chips drop their pill and stay readable on every theme (#25…
flamboh Oct 27, 2026
73acddc
fix(mobile): switching pull request tabs no longer jumps the page (#2…
flamboh Oct 27, 2026
570d4b0
feat(mobile): report crashes to Axiom with symbolicated stacks (#19093)
gabrielelpidio Oct 27, 2026
5808469
fix(web): chip palette test follows the single design (#26131)
juliusmarminge Oct 27, 2026
562c4f0
Merge upstream/main 5808469018 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
Original file line number Diff line number Diff line change
Expand Up @@ -7730,7 +7730,7 @@ describe("ClaudeAdapterV2 background wake turns", () => {
),
);

it.effect("stops background work after the turn settled", () =>
it.effect("preserves settled background work until an explicit stop", () =>
Effect.scoped(
Effect.gen(function* () {
let closes = 0;
Expand Down Expand Up @@ -7759,6 +7759,29 @@ describe("ClaudeAdapterV2 background wake turns", () => {
assert.equal(settledThread?.pendingBackgroundTasks?.[0]?.taskId, WAKE_TASK_ID);
assert.isTrue(yield* harness.hasPendingBackgroundWork);

const replacementAttempt = yield* harness.runtime
.startTurn(
makeClaudeTestTurnInput({
threadId: harness.threadId,
providerThread: {
...harness.providerThread,
nativeThreadRef: {
...harness.providerThread.nativeThreadRef!,
nativeId: "replacement-session",
},
},
now,
attemptId: RunAttemptId.make("attempt-claude-background-replacement"),
text: "Continue in a fresh session.",
attachments: [],
providerTurnOrdinal: 2,
}),
)
.pipe(Effect.result);
assert.equal(replacementAttempt._tag, "Failure");
assert.equal(closes, 0);
assert.isTrue(yield* harness.hasPendingBackgroundWork);

yield* harness.runtime.interruptTurn({
providerThread: settledThread ?? harness.providerThread,
providerTurnId: harness.terminalEvents()[0]!.providerTurnId,
Expand Down Expand Up @@ -12186,6 +12209,25 @@ describe("ClaudeAdapterV2 background wake turns", () => {
yield* changes.until(() => terminals().length === 1);
const settledTurn = terminals()[0]!;

assert.isFalse(yield* runtime.hasPendingBackgroundWorkForThread!(providerThread));
assert.isTrue(
yield* runtime.hasPendingBackgroundWorkForThread!(providerThread, {
includeSubagents: true,
}),
);
assert.isFalse(
yield* runtime.hasPendingBackgroundWorkForThread!(
{
...providerThread,
nativeThreadRef: {
...providerThread.nativeThreadRef!,
nativeId: "sibling-native-session",
},
},
{ includeSubagents: true },
),
);

const alternateModel = CLAUDE_TEST_RESTART_MODEL_SELECTION;
const switchTurn = (attempt: string) =>
runtime.startTurn(
Expand Down
16 changes: 13 additions & 3 deletions apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9615,10 +9615,11 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
return existing;
}

// Selection changes kill CLI background work; refuse until it finishes or Stop closes the process.
// Replacing this thread's process kills its background work, even with a new native identity.
if (
existing !== null &&
existing.nativeThreadId === nativeThreadId &&
(existing.nativeThreadId === nativeThreadId ||
existing.lastTurn?.input.threadId === turnInput.threadId) &&
!existing.stopping &&
(yield* liveProcessRunsBackgroundWork(existing))
) {
Expand Down Expand Up @@ -10484,11 +10485,20 @@ export const makeClaudeAdapterV2 = Effect.fn("makeClaudeAdapterV2")(function* (
}),
hasPendingBackgroundWorkForThread: Effect.fn(
"ClaudeAdapterV2.hasPendingBackgroundWorkForThread",
)(function* (providerThread) {
)(function* (providerThread, options) {
const nativeThreadId = providerThread.nativeThreadRef?.nativeId;
if (nativeThreadId === undefined || nativeThreadId === null) {
return false;
}
if (options?.includeSubagents) {
const live = yield* Ref.get(queryContext);
if (
live?.nativeThreadId === nativeThreadId &&
!live.stopping &&
(yield* liveProcessRunsBackgroundWork(live))
)
return true;
}
return (
rosterForNativeThread(
yield* Ref.get(pendingBackgroundTasksByNativeThread),
Expand Down
Loading