Merge pull request #3090 from code-yeongyu/fix/prepublish-tmux-regressions
fix(tmux): recover isolated session regressions
This commit is contained in:
Vendored
+16
-8
@@ -1,14 +1,19 @@
|
|||||||
declare module "bun:test" {
|
declare module "bun:test" {
|
||||||
|
type AnyFunction = (...args: any[]) => any
|
||||||
|
|
||||||
interface MockMetadata<TArgs extends unknown[]> {
|
interface MockMetadata<TArgs extends unknown[]> {
|
||||||
calls: TArgs[]
|
calls: TArgs[]
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MockFunction<TArgs extends unknown[] = unknown[], TReturn = unknown> {
|
interface MockFunction<TFunction extends AnyFunction = AnyFunction> {
|
||||||
(...args: TArgs): TReturn
|
(...args: Parameters<TFunction>): ReturnType<TFunction>
|
||||||
mock: MockMetadata<TArgs>
|
mock: MockMetadata<Parameters<TFunction>>
|
||||||
|
mockClear(): void
|
||||||
mockReset(): void
|
mockReset(): void
|
||||||
mockReturnValue(value: TReturn): void
|
mockRestore(): void
|
||||||
mockResolvedValue(value: Awaited<TReturn>): void
|
mockReturnValue(value: ReturnType<TFunction>): void
|
||||||
|
mockResolvedValue(value: Awaited<ReturnType<TFunction>>): void
|
||||||
|
mockImplementation(fn: TFunction): MockFunction<TFunction>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function describe(name: string, fn: () => void): void
|
export function describe(name: string, fn: () => void): void
|
||||||
@@ -18,9 +23,12 @@ declare module "bun:test" {
|
|||||||
export function afterEach(fn: () => void | Promise<void>): void
|
export function afterEach(fn: () => void | Promise<void>): void
|
||||||
export function beforeAll(fn: () => void | Promise<void>): void
|
export function beforeAll(fn: () => void | Promise<void>): void
|
||||||
export function afterAll(fn: () => void | Promise<void>): void
|
export function afterAll(fn: () => void | Promise<void>): void
|
||||||
export function mock<TArgs extends unknown[], TReturn>(
|
export function mock<TFunction extends AnyFunction>(fn: TFunction): MockFunction<TFunction>
|
||||||
fn: (...args: TArgs) => TReturn,
|
|
||||||
): MockFunction<TArgs, TReturn>
|
export function spyOn<TObject extends object>(
|
||||||
|
object: TObject,
|
||||||
|
key: keyof TObject,
|
||||||
|
): MockFunction<AnyFunction>
|
||||||
|
|
||||||
export namespace mock {
|
export namespace mock {
|
||||||
function module(modulePath: string, factory: () => Record<string, unknown>): void
|
function module(modulePath: string, factory: () => Record<string, unknown>): void
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@ const defaultTmuxDeps: TmuxUtilDeps = {
|
|||||||
const DEFERRED_SESSION_TTL_MS = 5 * 60 * 1000
|
const DEFERRED_SESSION_TTL_MS = 5 * 60 * 1000
|
||||||
const MAX_DEFERRED_QUEUE_SIZE = 20
|
const MAX_DEFERRED_QUEUE_SIZE = 20
|
||||||
const MAX_CLOSE_RETRY_COUNT = 3
|
const MAX_CLOSE_RETRY_COUNT = 3
|
||||||
|
const MAX_ISOLATED_CONTAINER_NULL_STATE_COUNT = 2
|
||||||
|
|
||||||
export class TmuxSessionManager {
|
export class TmuxSessionManager {
|
||||||
private client: OpencodeClient
|
private client: OpencodeClient
|
||||||
@@ -60,6 +61,7 @@ export class TmuxSessionManager {
|
|||||||
private pollingManager: TmuxPollingManager
|
private pollingManager: TmuxPollingManager
|
||||||
private isolatedContainerPaneId: string | undefined
|
private isolatedContainerPaneId: string | undefined
|
||||||
private isolatedWindowPaneId: string | undefined
|
private isolatedWindowPaneId: string | undefined
|
||||||
|
private isolatedContainerNullStateCount = 0
|
||||||
constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps: TmuxUtilDeps = defaultTmuxDeps) {
|
constructor(ctx: PluginInput, tmuxConfig: TmuxConfig, deps: TmuxUtilDeps = defaultTmuxDeps) {
|
||||||
this.client = ctx.client
|
this.client = ctx.client
|
||||||
this.tmuxConfig = tmuxConfig
|
this.tmuxConfig = tmuxConfig
|
||||||
@@ -123,9 +125,22 @@ export class TmuxSessionManager {
|
|||||||
})
|
})
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
if (state) return null
|
if (state) {
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
this.isolatedContainerNullStateCount += 1
|
||||||
|
log("[tmux-session-manager] isolated container state query returned null", {
|
||||||
|
paneId: this.isolatedWindowPaneId,
|
||||||
|
nullStateCount: this.isolatedContainerNullStateCount,
|
||||||
|
maxNullStateCount: MAX_ISOLATED_CONTAINER_NULL_STATE_COUNT,
|
||||||
|
})
|
||||||
|
if (this.isolatedContainerNullStateCount < MAX_ISOLATED_CONTAINER_NULL_STATE_COUNT) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
this.isolatedContainerPaneId = undefined
|
this.isolatedContainerPaneId = undefined
|
||||||
this.isolatedWindowPaneId = undefined
|
this.isolatedWindowPaneId = undefined
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const isolation = this.tmuxConfig.isolation
|
const isolation = this.tmuxConfig.isolation
|
||||||
@@ -138,6 +153,7 @@ export class TmuxSessionManager {
|
|||||||
if (result.success && result.paneId) {
|
if (result.success && result.paneId) {
|
||||||
this.isolatedContainerPaneId = result.paneId
|
this.isolatedContainerPaneId = result.paneId
|
||||||
this.isolatedWindowPaneId = result.paneId
|
this.isolatedWindowPaneId = result.paneId
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
log("[tmux-session-manager] isolated container created", {
|
log("[tmux-session-manager] isolated container created", {
|
||||||
isolation,
|
isolation,
|
||||||
paneId: result.paneId,
|
paneId: result.paneId,
|
||||||
@@ -179,6 +195,7 @@ export class TmuxSessionManager {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
this.isolatedWindowPaneId = nextAnchor.paneId
|
this.isolatedWindowPaneId = nextAnchor.paneId
|
||||||
log("[tmux-session-manager] reassigned isolated container anchor pane", {
|
log("[tmux-session-manager] reassigned isolated container anchor pane", {
|
||||||
sessionId: nextAnchor.sessionId,
|
sessionId: nextAnchor.sessionId,
|
||||||
@@ -201,6 +218,7 @@ export class TmuxSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const isolatedContainerPaneId = this.isolatedContainerPaneId
|
const isolatedContainerPaneId = this.isolatedContainerPaneId
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
this.isolatedContainerPaneId = undefined
|
this.isolatedContainerPaneId = undefined
|
||||||
this.isolatedWindowPaneId = undefined
|
this.isolatedWindowPaneId = undefined
|
||||||
|
|
||||||
@@ -604,7 +622,8 @@ export class TmuxSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.isIsolated() && !this.isolatedWindowPaneId) {
|
if (this.isIsolated() && !this.isolatedWindowPaneId) {
|
||||||
log("[tmux-session-manager] isolated container failed, skipping inline fallback to preserve isolation", { sessionId })
|
log("[tmux-session-manager] isolated container failed, deferring session for retry", { sessionId })
|
||||||
|
this.enqueueDeferredSession(sessionId, title)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const sourcePaneId = this.getEffectiveSourcePaneId()
|
const sourcePaneId = this.getEffectiveSourcePaneId()
|
||||||
@@ -862,6 +881,7 @@ export class TmuxSessionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.retryPendingCloses()
|
await this.retryPendingCloses()
|
||||||
|
this.isolatedContainerNullStateCount = 0
|
||||||
this.isolatedContainerPaneId = undefined
|
this.isolatedContainerPaneId = undefined
|
||||||
this.isolatedWindowPaneId = undefined
|
this.isolatedWindowPaneId = undefined
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user