fix(app): terminal cloning without retry (#17354)

This commit is contained in:
Adam
2026-03-13 08:56:48 -05:00
committed by GitHub
parent b88b323049
commit c9e9dbeee1
5 changed files with 258 additions and 89 deletions

View File

@@ -2,21 +2,28 @@ export const terminalAttr = "data-pty-id"
export type TerminalProbeState = {
connected: boolean
connects: number
rendered: string
settled: number
}
type TerminalProbeControl = {
disconnect?: VoidFunction
}
export type E2EWindow = Window & {
__opencode_e2e?: {
terminal?: {
enabled?: boolean
terminals?: Record<string, TerminalProbeState>
controls?: Record<string, TerminalProbeControl>
}
}
}
const seed = (): TerminalProbeState => ({
connected: false,
connects: 0,
rendered: "",
settled: 0,
})
@@ -25,15 +32,28 @@ const root = () => {
if (typeof window === "undefined") return
const state = (window as E2EWindow).__opencode_e2e?.terminal
if (!state?.enabled) return
return state
}
const terms = () => {
const state = root()
if (!state) return
state.terminals ??= {}
return state.terminals
}
const controls = () => {
const state = root()
if (!state) return
state.controls ??= {}
return state.controls
}
export const terminalProbe = (id: string) => {
const set = (next: Partial<TerminalProbeState>) => {
const terms = root()
if (!terms) return
terms[id] = { ...(terms[id] ?? seed()), ...next }
const state = terms()
if (!state) return
state[id] = { ...(state[id] ?? seed()), ...next }
}
return {
@@ -41,24 +61,37 @@ export const terminalProbe = (id: string) => {
set(seed())
},
connect() {
set({ connected: true })
const state = terms()
if (!state) return
const prev = state[id] ?? seed()
state[id] = {
...prev,
connected: true,
connects: prev.connects + 1,
}
},
render(data: string) {
const terms = root()
if (!terms) return
const prev = terms[id] ?? seed()
terms[id] = { ...prev, rendered: prev.rendered + data }
const state = terms()
if (!state) return
const prev = state[id] ?? seed()
state[id] = { ...prev, rendered: prev.rendered + data }
},
settle() {
const terms = root()
if (!terms) return
const prev = terms[id] ?? seed()
terms[id] = { ...prev, settled: prev.settled + 1 }
const state = terms()
if (!state) return
const prev = state[id] ?? seed()
state[id] = { ...prev, settled: prev.settled + 1 }
},
control(next: Partial<TerminalProbeControl>) {
const state = controls()
if (!state) return
state[id] = { ...(state[id] ?? {}), ...next }
},
drop() {
const terms = root()
if (!terms) return
delete terms[id]
const state = terms()
if (state) delete state[id]
const control = controls()
if (control) delete control[id]
},
}
}