mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-04-13 04:04:44 +00:00
fix(app): terminal cloning without retry (#17354)
This commit is contained in:
@@ -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]
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user