Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
171 commits
Select commit Hold shift + click to select a range
e1d8629
fix(native-chat): one ownership index with link roles, and a chat ref…
brennanb2025 Oct 19, 2026
f7af530
fix(native-chat): hold a terminal start Orca issues until its termina…
brennanb2025 Oct 19, 2026
762a3bc
fix(terminal): an automatic pane restore never resumes a conversation…
brennanb2025 Oct 19, 2026
985ffc6
Fix saved terminal resume ownership and effective launch results
brennanb2025 Oct 20, 2026
3fb0bd6
Preserve conversation case and clear refused cold restore identity
brennanb2025 Oct 20, 2026
ef3282e
fix: publish effective terminal launch results on attachment
brennanb2025 Oct 20, 2026
772cd37
fix: preserve terminal launch callback and candidate ownership
brennanb2025 Oct 20, 2026
08a9b6a
feat(native-chat): host op and claim for switching a Codex chat to it…
brennanb2025 Oct 20, 2026
6bc5979
feat(native-chat): switch a Codex conversation between chat and termi…
brennanb2025 Oct 20, 2026
f09f7c6
test(native-chat): pin the in-place Codex switch in both directions
brennanb2025 Oct 20, 2026
5e78554
fix: keep existing terminal attachments observational
brennanb2025 Oct 20, 2026
a7d59ce
feat(native-chat): start the existing chat when a Codex terminal swit…
brennanb2025 Oct 20, 2026
cbd096a
Merge pinned main into terminal ownership admission
brennanb2025 Oct 20, 2026
84175b1
fix(native-chat): tie each switch claim to the spawn attempt that too…
brennanb2025 Oct 20, 2026
c2468c5
fix(native-chat): let the terminal host own a switch start until it p…
brennanb2025 Oct 20, 2026
96ed178
test(native-chat): expect the switch menu's in-place and fork labels
brennanb2025 Oct 20, 2026
487db36
fix: consolidate terminal launch imports
brennanb2025 Oct 20, 2026
335f3c5
Merge main into flip ownership admission
brennanb2025 Oct 20, 2026
7969c09
fix(native-chat): keep a switch start protected until its agents, not…
brennanb2025 Oct 20, 2026
0fd319b
test: document snapshot runtime fixture boundary
brennanb2025 Oct 20, 2026
839ff7f
fix(native-chat): prove a later boot on every platform and restamp a …
brennanb2025 Oct 20, 2026
406b819
fix: preserve terminal launch identity types
brennanb2025 Oct 20, 2026
e8ce630
fix(native-chat): no clock-only reboot release, host-fenced paired re…
brennanb2025 Oct 20, 2026
f852791
fix(native-chat): end an owner-lost switch on a clock-free later boot…
brennanb2025 Oct 20, 2026
d65f9cf
fix: accept reattach payload policy sessions
brennanb2025 Oct 20, 2026
3568a5c
fix: preserve terminal result validation contracts
brennanb2025 Oct 20, 2026
fb309d0
refactor: separate terminal create contract
brennanb2025 Oct 20, 2026
58d108a
test: document partial terminal runtime fixtures
brennanb2025 Oct 20, 2026
6eaa868
test: align sleeping resume store fixture
brennanb2025 Oct 20, 2026
453392e
Merge B1 (#30930) head 6eaa8684 into the Codex switch branch
brennanb2025 Oct 21, 2026
977f31d
Simplify same-conversation chat and CLI switching
brennanb2025 Oct 21, 2026
2eeb182
Complete native chat return readiness and placement contracts
brennanb2025 Oct 22, 2026
fdb0ddf
Align switch resume contracts and checked test fixtures
brennanb2025 Oct 22, 2026
ce28257
Exercise both conversation switch methods in the wire contract
brennanb2025 Oct 22, 2026
f9cb99d
Complete existing runtime and History test fixtures
brennanb2025 Oct 22, 2026
695fa19
Merge main and preserve terminal resume admission
brennanb2025 Oct 22, 2026
f4315a6
Merge updated conversation admission base and preserve switch contracts
brennanb2025 Oct 22, 2026
5d4185e
Fix terminal create type contracts
brennanb2025 Oct 22, 2026
1a37f70
Align integrated terminal types and workspace readers
brennanb2025 Oct 22, 2026
1d000de
Merge terminal create type contract correction
brennanb2025 Oct 22, 2026
043601e
Fix pinned switch placement and terminal resume fallback
brennanb2025 Oct 22, 2026
27de221
Merge main into terminal ownership admission
brennanb2025 Oct 22, 2026
e1f8e5c
Merge main into terminal ownership admission
brennanb2025 Oct 22, 2026
79bcf11
fix: return the terminal main started to its waiting view
brennanb2025 Oct 22, 2026
60cc704
fix: register reattached terminals before publishing their handles
brennanb2025 Oct 22, 2026
00da821
fix: preserve pane conversation identity after terminal agent exit
brennanb2025 Oct 22, 2026
626429d
test: check the terminal return fixture session shape
brennanb2025 Oct 22, 2026
d69cbec
test: correct terminal return transport fixture typing
brennanb2025 Oct 22, 2026
8dc0318
test: name the portable CLI resume mock contract
brennanb2025 Oct 22, 2026
7177cc1
fix: show conversation switches only with Chat UI enabled
brennanb2025 Oct 22, 2026
d5d4ea6
Merge main and preserve terminal resume outcomes
brennanb2025 Oct 22, 2026
e6716b5
Merge updated terminal ownership base and preserve conversation switc…
brennanb2025 Oct 22, 2026
9b29e7d
Check unavailable-resume test fixture types
brennanb2025 Oct 22, 2026
65339e3
Complete sidebar resume test store fixture
brennanb2025 Oct 22, 2026
af08224
Merge prerequisite test fixture corrections
brennanb2025 Oct 22, 2026
3ec89ea
Merge main and preserve terminal resume results through shared commit
brennanb2025 Oct 22, 2026
6d1fd57
fix: complete original terminal owner retirement
brennanb2025 Oct 22, 2026
f6e4560
Merge prerequisite ownership and admission updates
brennanb2025 Oct 22, 2026
e044d31
refactor: remove redundant terminal switch close logic
brennanb2025 Oct 22, 2026
658a6c9
Fix switch capability ownership and required terminal close failures
brennanb2025 Oct 22, 2026
03fc698
Verify failed renderer cleanup rejects the host close receipt
brennanb2025 Oct 22, 2026
e8e6699
Preserve existing terminal source admission alongside retained exit c…
brennanb2025 Oct 22, 2026
97c0b01
Merge main and preserve terminal saved launch results
brennanb2025 Oct 22, 2026
fd3b89e
Integrate terminal ownership updates and correct switch checks
brennanb2025 Oct 22, 2026
3c2f2b9
Merge main and preserve mobile terminal create options
brennanb2025 Oct 22, 2026
c843e12
Exercise captured terminal stop contract in continuity test
brennanb2025 Oct 22, 2026
ebcccac
Integrate updated terminal ownership prerequisite
brennanb2025 Oct 22, 2026
fca05af
Fix terminal retirement fixture types
brennanb2025 Oct 22, 2026
781ff64
Merge main into terminal resume admission branch
brennanb2025 Oct 23, 2026
6e66bba
test: bound saved resume ownership and refusal work
brennanb2025 Oct 23, 2026
f2546c5
Integrate updated terminal ownership prerequisite
brennanb2025 Oct 23, 2026
ab7f01d
Align retirement fixture with workspace sleep subscription
brennanb2025 Oct 23, 2026
bcb938b
Integrate prerequisite acquisition test contracts
brennanb2025 Oct 23, 2026
dfb4cb8
Settle refused saved resume claims from actual launch results
brennanb2025 Oct 23, 2026
9813d7d
Integrate prerequisite CI repairs and complete status fixture
brennanb2025 Oct 23, 2026
d972515
Merge origin/main and qualify saved resume result settlement
brennanb2025 Oct 23, 2026
3503905
Correct capture fixture owner facts and relocated writer accounting
brennanb2025 Oct 23, 2026
ec8b66f
Fix saved resume test type contracts
brennanb2025 Oct 23, 2026
872f199
Pin authenticated final-pane retirement through the real Store
brennanb2025 Oct 23, 2026
25094d9
Pin status identity preservation across published owner transitions
brennanb2025 Oct 23, 2026
bcb0a68
test(e2e): capture exact terminal parking diagnostics
brennanb2025 Oct 23, 2026
914747f
Restore optional terminal presentation contracts
brennanb2025 Oct 23, 2026
3b79d19
test: verify parked terminal with fresh host inventory
brennanb2025 Oct 23, 2026
8e3d6d1
fix: check close command and ordering witness types
brennanb2025 Oct 23, 2026
e09187b
Merge main into flip ownership admission
brennanb2025 Oct 23, 2026
05e87b9
Bound terminal conversation projection residency
brennanb2025 Oct 23, 2026
10ee6df
Avoid repeated conversation projection and placement scans
brennanb2025 Oct 23, 2026
c646ee0
Use an array-like receiver in retirement instrumentation
brennanb2025 Oct 24, 2026
d007f33
Correct types and fixtures in conversation contract tests
brennanb2025 Oct 24, 2026
86b0af9
Merge current main into flip ownership admission
brennanb2025 Oct 24, 2026
8eb98ce
Merge pinned ownership admission base into terminal conversation switch
brennanb2025 Oct 24, 2026
fa85b67
Test native switch visibility during Chat UI updates
brennanb2025 Oct 24, 2026
68904f7
Restore canonical terminal-view label in runtime catalog
brennanb2025 Oct 24, 2026
2ae8acc
Show one terminal control in native chat headers
brennanb2025 Oct 24, 2026
f46428b
Align test observers and capture hook timeout diagnostics
brennanb2025 Oct 24, 2026
da4b3e0
Place grouped chat terminal controls beside pane actions
brennanb2025 Oct 24, 2026
8f99fba
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
f26bdad
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
a25efaa
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
932116f
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
2321986
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
7b7c870
Merge ownership admission base into chat terminal switching
brennanb2025 Oct 25, 2026
972b35f
Merge current main into flip ownership admission
brennanb2025 Oct 25, 2026
7a688b8
Consolidate agent session imports in remote terminal transport
brennanb2025 Oct 25, 2026
686cb02
Clarify terminal conversation refusal guidance
brennanb2025 Oct 25, 2026
43a1712
Admit note-only saved conversations without hiding live writers
brennanb2025 Oct 25, 2026
71e0d77
Retain terminal writer proofs through final admission
brennanb2025 Oct 25, 2026
2ea7a1a
Merge latest ownership admission base into chat terminal switching
brennanb2025 Oct 25, 2026
c653f4c
Merge main after ownership base lands
brennanb2025 Oct 25, 2026
5906f37
test: initialize idle cursor reset in history return fixture
brennanb2025 Oct 25, 2026
4ec1e2f
Merge main to resolve switch integration conflicts
brennanb2025 Oct 25, 2026
d24a5a8
Merge main to resolve integration conflicts
brennanb2025 Oct 25, 2026
b5e75c7
Preserve typed refusals when returning conversations to chat
brennanb2025 Oct 25, 2026
00a4c50
Merge main to resolve RPC integration conflict
brennanb2025 Oct 25, 2026
4856835
Fix inherited CI file limits and test import
brennanb2025 Oct 26, 2026
62c829f
Merge origin/main to resolve conflicts
brennanb2025 Oct 26, 2026
43c53af
Merge origin/main with localization CI fix
brennanb2025 Oct 26, 2026
9003d96
Merge origin/main into brennanb2025/flip-codex-switch (resolve agent-…
brennanb2025 Oct 26, 2026
9a4c527
Make conversation switching use one bounded operation
brennanb2025 Oct 27, 2026
6cc520f
Merge main into conversation switching correction
brennanb2025 Oct 27, 2026
b5a600f
Fix switch admission and integration contracts
brennanb2025 Oct 27, 2026
5ce2b06
Merge main into switch branch
brennanb2025 Oct 27, 2026
088c8a1
Merge current main into switch branch
brennanb2025 Oct 27, 2026
302f164
Merge current main into switch branch
brennanb2025 Oct 27, 2026
b82a2bb
Fix switch execution test fixture contracts
brennanb2025 Oct 27, 2026
6d3b6c5
Consolidate switch imports and type the mobile fixture store
brennanb2025 Oct 27, 2026
1f8e943
Preserve Codex history and automatic switch placement
brennanb2025 Oct 27, 2026
47bbb63
Merge main to restore switch validation
brennanb2025 Oct 27, 2026
9f3dfe5
Merge main to restore switch validation
brennanb2025 Oct 27, 2026
23fc744
Limit wrapped Codex decoding to History imports
brennanb2025 Oct 27, 2026
85e56f9
Keep retired chats out of stale terminal-switch inventories
brennanb2025 Oct 27, 2026
a1ad066
Merge main into conversation switch correction
brennanb2025 Oct 27, 2026
eb1ecb3
Preserve filesystem spy types and use a deterministic switch test clock
brennanb2025 Oct 27, 2026
b7b716b
Merge main before final switch QA
brennanb2025 Oct 27, 2026
c3d738a
Preserve pane admission calls and expose E2E type diagnostics
brennanb2025 Oct 27, 2026
bbf0532
Account for approved fenced switch layout writers
brennanb2025 Oct 27, 2026
4342b89
Align switch regression fixtures with current owner contracts
brennanb2025 Oct 27, 2026
e8c26d5
Refresh switch catalog and handle generated-only commits
brennanb2025 Oct 27, 2026
15c7a13
Order switch startup before source shell cleanup
brennanb2025 Oct 28, 2026
9847a9c
Merge main into Codex conversation switch
brennanb2025 Oct 28, 2026
d126487
Test selected-account history adoption at rest
brennanb2025 Oct 28, 2026
975d5c5
Compose conversation switching with ordinary lifecycle owners
brennanb2025 Oct 28, 2026
467eadd
Merge main into conversation switching
brennanb2025 Oct 28, 2026
49a8068
Merge main into conversation switching
brennanb2025 Oct 29, 2026
392d9d1
Correct switch lifecycle outcomes and CI contracts
brennanb2025 Oct 29, 2026
e975cfa
Merge main into conversation switching
brennanb2025 Oct 29, 2026
ce73b46
Fix switch integration checks and test fixtures
brennanb2025 Oct 29, 2026
0a29d50
Preserve conversation switch placement through ordinary publication
brennanb2025 Oct 29, 2026
4060902
Merge main to resolve switch branch conflicts
brennanb2025 Oct 29, 2026
4cdd3fe
Fix switch placement types and count instrumentation
brennanb2025 Oct 29, 2026
76e20b8
Consolidate switch placement type imports
brennanb2025 Oct 29, 2026
f4b48f5
Align switch ownership fixtures and build compatibility
brennanb2025 Oct 29, 2026
6d0b260
Keep presentation-only terminal menu labels accurate
brennanb2025 Oct 29, 2026
51bb66b
Merge main into flip-codex-switch
brennanb2025 Oct 29, 2026
f31d395
Preserve terminal recovery and dispatch contracts
brennanb2025 Oct 29, 2026
b60da0b
Fix switch recovery fixture and declaration types
brennanb2025 Oct 29, 2026
e9ff3d9
Align switch recovery and UI test owner contracts
brennanb2025 Oct 29, 2026
8d1a2e5
Fix lifecycle handling for existing Continue actions
brennanb2025 Oct 29, 2026
82beabc
Preserve legacy import and owned Windows cleanup
brennanb2025 Oct 29, 2026
0a8a324
Match pending creation membership contract
brennanb2025 Oct 29, 2026
fd8b266
Merge main into Continue lifecycle fixes
brennanb2025 Oct 29, 2026
ad564bf
fix(continue): align sweep and imported source contracts
brennanb2025 Oct 29, 2026
4c2605e
Merge main into Continue lifecycle fixes
brennanb2025 Oct 29, 2026
48daedc
Combine terminal claim type imports
brennanb2025 Oct 30, 2026
2f5d17e
Classify own-property checks as layout reads
brennanb2025 Oct 30, 2026
cd8e4c9
Report pre-spawn failure in WSL cwd fixture
brennanb2025 Oct 30, 2026
cd7964c
Load saved CLI history without a retained source row
brennanb2025 Oct 30, 2026
3e64170
Unify same-conversation switching and preserve user selection
brennanb2025 Oct 30, 2026
78284ca
Skip unused history work during conversation switching
brennanb2025 Oct 30, 2026
40a1187
Merge lifecycle fixes into same-tab switcher
brennanb2025 Oct 30, 2026
f5f6fdc
Merge main after lifecycle fixes landed
brennanb2025 Oct 30, 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
  •  
  •  
  •  
1 change: 0 additions & 1 deletion config/flaky-test-pattern-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,6 @@
3 test-no-wall-clock:src/renderer/src/components/status-bar/status-bar-provider-menu-focus.test.tsx
1 test-no-wall-clock:src/renderer/src/components/status-bar/workspace-space-worktree-row.test.tsx
1 test-no-wall-clock:src/renderer/src/components/tab-bar/TabBarCreateEntry.history.test.tsx
2 test-no-wall-clock:src/renderer/src/components/tab-bar/cli-chat-resume-run.test.ts
1 test-no-wall-clock:src/renderer/src/components/tab-bar/open-tab-search.test.ts
4 test-no-wall-clock:src/renderer/src/components/task-page/jira/task-page-jira-cache-selectors.test.ts
1 test-no-wall-clock:src/renderer/src/components/task-page-jira-saved-filter-load-failure.test.tsx
Expand Down
4 changes: 2 additions & 2 deletions config/main-layout-writer-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
1 src/main/ipc/pty/ipc/leaf-move.ts
1 src/main/ipc/pty/pane/pane-owner-replacement.ts
3 src/main/ipc/pty/pane/stable-owner.ts
2 src/main/ipc/pty/spawn-commit-binding.ts
3 src/main/ipc/pty/spawn-commit-binding.ts # Replacement/fresh queued checks differ from recovery of an already-dispatched child.
1 src/main/ipc/renderer-shutdown-checkpoint.ts
1 src/main/ipc/runtime-environments/runtime-environment-removal-cleanup.ts
1 src/main/ipc/runtime-environments/runtime-environment-session-reconcile.ts
Expand Down Expand Up @@ -60,10 +60,10 @@
1 src/main/runtime/runtime-workspace-session-controller.ts
2 src/main/runtime/session-graph/session-graph-promotion.ts
2 src/main/runtime/session-lifecycle/projection/apply-mobile-session-tab-navigation.ts
2 src/main/runtime/session-lifecycle/projection/build-headless-mobile-session-browser-tabs.ts
2 src/main/runtime/session-tabs/headless-tab-group-moves.ts
6 src/main/runtime/session-tabs/headless-tab-properties.ts
1 src/main/runtime/session-tabs/structured-session-tab-close.ts
2 src/main/runtime/session-tabs/terminal-surface-close-commit.ts
1 src/main/runtime/session-tabs/terminal-surface-retirements.ts
2 src/main/runtime/terminal/adoption/adopt-terminal-orphans-from-inventory.ts
1 src/main/runtime/terminal/driver/terminal-driver-resources.ts
Expand Down
2 changes: 2 additions & 0 deletions config/renderer-layout-writer-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
3 src/renderer/src/components/worktree-jump-palette-status-inputs.ts
9 src/renderer/src/lib/agent-background-session-test-state.ts
1 src/renderer/src/lib/agent-hibernation-coordinator.ts
7 src/renderer/src/lib/agent-launch-pane-verdict-application.ts # Shipped window owner: fenced launch withdrawal/outcome; port when main owns layout.
8 src/renderer/src/lib/conversation-switch-projection.ts # Shipped window owner: fenced retirement/restoration; port when main owns layout.
4 src/renderer/src/lib/floating-workspace-terminal-actions.ts
1 src/renderer/src/lib/pane-manager/client-hosted-browser-row-state.ts
4 src/renderer/src/lib/session-write-subscriber.ts
Expand Down
1 change: 1 addition & 0 deletions config/scripts/check-e2e-typecheck-ratchet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function main(
console.error(`${file}: ${now} type error(s), baseline allows ${allowed}.`)
}
if (grown.length > 0) {
console.error(tscOutput)
console.error(`See the errors with: pnpm typecheck:e2e`)
}
for (const { file, now, allowed } of shrunk) {
Expand Down
35 changes: 23 additions & 12 deletions config/scripts/check-layout-writer-ratchets.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,27 @@ function isSameNameCopy(property, name) {
return ts.isPropertyAccessExpression(value) && value.name.text === name
}

/** Only the property-name argument of the standard presence read is a read. */
function isOwnPresenceRead(node) {
const call = node.parent
if (
!ts.isCallExpression(call) ||
call.questionDotToken ||
call.arguments.length !== 2 ||
call.arguments[1] !== node
) {
return false
}
const callee = call.expression
return (
ts.isPropertyAccessExpression(callee) &&
!callee.questionDotToken &&
callee.name.text === 'hasOwn' &&
ts.isIdentifier(callee.expression) &&
callee.expression.text === 'Object'
)
}

/** Layout writes in one file under one ratchet's rules. */
export function countLayoutWrites(sourceText, ratchet, fileName = 'file.tsx') {
const names = [...ratchet.writerNames, ...ratchet.assignedFields]
Expand Down Expand Up @@ -381,18 +402,8 @@ export function countLayoutWrites(sourceText, ratchet, fileName = 'file.tsx') {
!(ts.isPropertyAssignment(node.parent) && node.parent.name === node) &&
!ts.isComputedPropertyName(node.parent) &&
!(ts.isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) &&
!(
ts.isCallExpression(node.parent) &&
!node.parent.questionDotToken &&
node.parent.arguments.length === 2 &&
node.parent.arguments[1] === node &&
ts.isPropertyAccessExpression(node.parent.expression) &&
!node.parent.expression.questionDotToken &&
ts.isIdentifier(node.parent.expression.expression) &&
node.parent.expression.expression.text === 'Object' &&
node.parent.expression.name.text === 'hasOwn'
) &&
!ts.isLiteralTypeNode(node.parent)
!ts.isLiteralTypeNode(node.parent) &&
!isOwnPresenceRead(node)
) {
count += 1
}
Expand Down
3 changes: 2 additions & 1 deletion config/scripts/ci-unit-files.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ export const UNIT_INCLUDE = [
'config/scripts/**/*.test.ts',
'config/scripts/**/*.test.mjs',
'tests/tools/**/*.test.mjs',
'tests/e2e/**/*.unit.test.ts'
'tests/e2e/**/*.unit.test.ts',
'tests/e2e/**/*.unit.test.tsx'
]

export const UNIT_SETUP_FILES = [
Expand Down
50 changes: 50 additions & 0 deletions config/scripts/locale-cross-locale-key-overrides.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,54 @@
export const CROSS_LOCALE_KEY_OVERRIDES = {
'components.native-chat.resumeInNewChat.exitUnconfirmedFromTerminal': {
de: 'Orca konnte nicht bestätigen, dass {{agent}} in diesem Terminal beendet wurde. Beende {{agent}} hier und versuche diese Aktion erneut.',
es: 'Orca no pudo confirmar que {{agent}} se detuvo en esta terminal. Sal de {{agent}} aquí y vuelve a intentar esta acción.',
fr: 'Orca n’a pas pu confirmer l’arrêt de {{agent}} dans ce terminal. Quittez {{agent}} ici, puis réessayez cette action.',
ja: 'Orca は、このターミナルで {{agent}} が停止したことを確認できませんでした。ここで {{agent}} を終了してから、この操作をもう一度試してください。',
ko: 'Orca가 이 터미널에서 {{agent}}이(가) 중지되었는지 확인할 수 없습니다. 여기서 {{agent}}을(를) 종료한 다음 이 작업을 다시 시도하세요.',
pt: 'O Orca não pôde confirmar que {{agent}} parou neste terminal. Encerre {{agent}} aqui e tente esta ação novamente.',
ru: 'Orca не удалось подтвердить, что {{agent}} остановлен в этом терминале. Завершите {{agent}} здесь и повторите это действие.',
tr: 'Orca, {{agent}} uygulamasının bu terminalde durduğunu doğrulayamadı. Burada {{agent}} uygulamasından çıkın ve bu işlemi yeniden deneyin.',
zh: 'Orca 无法确认 {{agent}} 已在此终端中停止。请在此处退出 {{agent}},然后重试此操作。',
'zh-Hant':
'Orca 無法確認 {{agent}} 已在此終端機中停止。請在此處結束 {{agent}},然後重試此操作。'
},
'components.native-chat.resumeInNewChat.exitUnconfirmed': {
de: 'Orca konnte nicht bestätigen, dass {{agent}} beendet wurde. Beende {{agent}} in seinem Terminal und versuche diese Aktion erneut.',
es: 'Orca no pudo confirmar que {{agent}} se detuvo. Sal de {{agent}} en su terminal y vuelve a intentar esta acción.',
fr: 'Orca n’a pas pu confirmer l’arrêt de {{agent}}. Quittez {{agent}} dans son terminal, puis réessayez cette action.',
ja: 'Orca は {{agent}} が停止したことを確認できませんでした。{{agent}} を実行中のターミナルで終了してから、この操作をもう一度試してください。',
ko: 'Orca가 {{agent}}이(가) 중지되었는지 확인할 수 없습니다. 해당 터미널에서 {{agent}}을(를) 종료한 다음 이 작업을 다시 시도하세요.',
pt: 'O Orca não pôde confirmar que {{agent}} parou. Encerre {{agent}} no terminal em que está sendo executado e tente esta ação novamente.',
ru: 'Orca не удалось подтвердить, что {{agent}} остановлен. Завершите {{agent}} в его терминале и повторите это действие.',
tr: 'Orca, {{agent}} uygulamasının durduğunu doğrulayamadı. {{agent}} uygulamasından çalıştığı terminalde çıkın ve bu işlemi yeniden deneyin.',
zh: 'Orca 无法确认 {{agent}} 已停止。请在其所在的终端中退出 {{agent}},然后重试此操作。',
'zh-Hant':
'Orca 無法確認 {{agent}} 已停止。請在其所在的終端機中結束 {{agent}},然後重試此操作。'
},
'components.tab.bar.SortableTabContextMenu.showAsTerminal': {
de: 'Als Terminal anzeigen',
es: 'Mostrar como terminal',
fr: 'Afficher en terminal',
ja: 'ターミナルとして表示',
ko: '터미널로 표시',
pt: 'Mostrar como terminal',
ru: 'Показать как терминал',
tr: 'Terminal olarak göster',
zh: '以终端显示',
'zh-Hant': '以終端機顯示'
},
'components.tab.bar.SortableTabContextMenu.switchToTerminalView': {
de: 'Mit Terminal-Agenten fortfahren',
es: 'Continuar con el agente de terminal',
fr: 'Continuer avec l’agent de terminal',
ja: 'ターミナル Agent で続ける',
ko: '터미널 에이전트로 계속하기',
pt: 'Continuar com o agente de terminal',
ru: 'Продолжить с агентом в терминале',
tr: 'Terminal ajanıyla devam et',
zh: '使用终端智能体继续',
'zh-Hant': '使用終端機代理程式繼續'
},
// The live status describes ongoing reasoning; the composer option names the feature.
'components.native-chat.status.thinking': {
zh: '思考中',
Expand Down
1 change: 1 addition & 0 deletions config/scripts/pr-unit-support-routing.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const unitHarnesses = [
'src/renderer/src/runtime/sync-runtime-graph-test-harness.ts'
]
const supportBridges = new Set([
'src/renderer/src/components/tab-bar/tab-session-history-fixtures.test-fixture.ts',
'src/renderer/src/runtime/web-runtime-browser-creation-placement-test-rig.ts',
'src/renderer/src/components/editor/editor-model-lifetime-fixture.ts',
// Autosave suites' store rig; it takes the editor harness's tab-layout maps.
Expand Down
1 change: 1 addition & 0 deletions config/scripts/vitest-node-runtime-files.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const NODE_RUNTIME_INCLUDE = [
// Asserts an observer survives a forced collection; conservative retention would hide a lost one.
'config/scripts/happy-dom-mutation-observer-retention.test.ts',
// These reach Node SQLite through a shared helper or a dynamic import, which the scan skips.
'tests/e2e/mobile-terminal-session-switch.unit.test.ts',
'src/main/claude/claude-transcript-catch-up.test.ts',
'src/main/claude/claude-transcript-duration.test.ts',
'tests/e2e/native-chat-startup-option-pickers.unit.test.ts',
Expand Down
25 changes: 24 additions & 1 deletion src/main/agent-hooks/server-launch-resume-identity.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { assertCliConversationWritersExited } from '../runtime/structured-agent-cli-writers'
import { AgentHookServer, _internals } from './server'
import { buildBody, postHookEvent, PANE } from './server.test-fixtures'

Expand Down Expand Up @@ -129,7 +130,7 @@ describe('a resume launch seeds the pane identity', () => {
})
})

it('keeps the seeded identity across a host restart', async () => {
it('keeps the no-prompt launch identity across restart and refuses idle Codex until its shell is alone', async () => {
const server = await startServer()
server.recordLaunchResumeIdentity({
paneKey: PANE,
Expand All @@ -148,6 +149,28 @@ describe('a resume launch seeds the pane identity', () => {
providerSessionOnly: true
})
])
let shellAlone = false
const writers = {
rows: () => restarted.getStatusSnapshotForPane(PANE),
saved: () => [],
observation: (row: Parameters<AgentHookServer['readCliWriterObservation']>[0]) =>
restarted.readCliWriterObservation(row),
terminal: () => ({
pane: { ptyId: 'shell', incarnationId: 'shell-1', identity: 'shell:shell-1' }
}),
links: () => [],
sleeping: () => false,
shellAlone: async () => shellAlone
}
await expect(
assertCliConversationWritersExited(writers, 'codex', RESUMED.id)
).rejects.toMatchObject({
refusal: { details: { reason: 'conversationHeldElsewhere' } }
})
shellAlone = true
await expect(
assertCliConversationWritersExited(writers, 'codex', RESUMED.id)
).resolves.toBeUndefined()
})

it('ignores a pane key that is not a stable tab:leaf key', async () => {
Expand Down
34 changes: 29 additions & 5 deletions src/main/agent-launch/agent-launch-pane-attachment.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/** Use process-local launch state; after restart, ordinary pane attachment handles recovery. */

import type { AgentLaunchPaneVerdict } from '../../shared/agent-launch-pane-verdict'
import { parsePaneKey } from '../../shared/stable-pane-id'
import type { TerminalSurfaceCloseTarget } from '../../shared/terminal-surface-close-target'

/** Use process-local launch state; after restart, ordinary pane attachment handles recovery. */

const PROCEED: AgentLaunchPaneVerdict = { kind: 'proceed' }

export type AgentLaunchPane = { worktreeId: string; paneKey: string }
Expand All @@ -14,12 +14,13 @@ type RunningLaunch = {
settled: Promise<AgentLaunchPaneVerdict>
finished: Promise<AgentLaunchPaneVerdict>
closedByUser: boolean
superseded: boolean
}

const runningLaunchesByPane = new Map<string, RunningLaunch>()
const failedLaunchesByPane = new Map<
string,
{ pane: AgentLaunchPane; verdict: AgentLaunchPaneVerdict }
{ pane: AgentLaunchPane; verdict: AgentLaunchPaneVerdict; running?: RunningLaunch }
>()

function paneKeyOf(pane: AgentLaunchPane): string {
Expand All @@ -30,6 +31,7 @@ export type RunningAgentLaunchPane = {
/** Attach as soon as the agent binds, without waiting for prompt delivery. */
agentBound(): void
finish(verdict: AgentLaunchPaneVerdict): void
current(): boolean
closedByUser(): boolean
}

Expand All @@ -46,8 +48,10 @@ export function trackRunningAgentLaunchPane(pane: AgentLaunchPane): RunningAgent
finished: new Promise((done) => {
resolve = done
}),
superseded: false,
closedByUser: false
}
noteAgentLaunchPaneAccepted(pane.paneKey)
runningLaunchesByPane.set(key, running)
failedLaunchesByPane.delete(key)
let finished = false
Expand All @@ -62,18 +66,38 @@ export function trackRunningAgentLaunchPane(pane: AgentLaunchPane): RunningAgent
runningLaunchesByPane.delete(key)
if (
!running.closedByUser &&
(verdict.kind === 'not-started' || verdict.kind === 'unconfirmed')
(verdict.kind === 'not-started' ||
verdict.kind === 'unconfirmed' ||
verdict.kind === 'withdrawn')
) {
failedLaunchesByPane.set(key, { pane, verdict })
failedLaunchesByPane.set(key, { pane, verdict, running })
}
}
settle(verdict)
resolve(verdict)
},
current: () =>
!running.superseded &&
!running.closedByUser &&
(runningLaunchesByPane.get(key) ?? failedLaunchesByPane.get(key)?.running) === running,
closedByUser: () => running.closedByUser
}
}

/** Acceptance precedes option resolution, including callers that do not publish an early tab. */
export function noteAgentLaunchPaneAccepted(paneKey: string): void {
for (const running of runningLaunchesByPane.values()) {
if (running.pane.paneKey === paneKey) {
running.superseded = true
}
}
for (const failed of failedLaunchesByPane.values()) {
if (failed.pane.paneKey === paneKey && failed.running) {
failed.running.superseded = true
}
}
}

/** `null` targets every pane of the workspace. */
function launchesIn<T extends { pane: AgentLaunchPane }>(
launches: Map<string, T>,
Expand Down
Loading
Loading