Skip to content

Commit a3c8a42

Browse files
agent-relay-code[bot]claude
authored andcommitted
chore: apply pr-reviewer fixes for #140
1 parent c9cfe2a commit a3c8a42

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/main/broker.test.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@ type MockClient = {
3232
brokerPid?: number
3333
baseUrl?: string
3434
agentNames: string[]
35+
agentRuntimes: Record<string, 'pty' | 'headless'>
3536
}
3637

3738
const mock = vi.hoisted(() => {
3839
function createMockClient(agentNames: string[] = []): MockClient {
39-
const agentRuntimes = new Map<string, 'pty' | 'headless'>()
40+
const agentRuntimes = new Map<string, 'pty' | 'headless'>(agentNames.map((name) => [name, 'pty']))
4041
const client: MockClient = {
4142
agentNames: [...agentNames],
43+
agentRuntimes: Object.fromEntries(agentRuntimes) as Record<string, 'pty' | 'headless'>,
4244
getSession: vi.fn(async () => ({})),
4345
listAgents: vi.fn(async () => client.agentNames.map((name) => ({ name, runtime: agentRuntimes.get(name) ?? 'pty', channels: [] }))),
4446
getInboundDeliveryMode: vi.fn(async () => 'passthrough'),
@@ -545,6 +547,60 @@ describe('BrokerManager local + cloud coexistence', () => {
545547
await manager.shutdown()
546548
})
547549

550+
it('spawns OpenCode with headless runtime and skips PTY attach operations', async () => {
551+
const manager = new BrokerManager()
552+
const local = await startLocal(manager, [])
553+
554+
const spawned = await manager.spawnAgent(PROJECT_ID, { name: 'opencode-1', cli: 'opencode' })
555+
const attached = await manager.attachTerminal(PROJECT_ID, {
556+
name: spawned.name,
557+
mode: 'passthrough',
558+
rows: 24,
559+
cols: 80
560+
})
561+
562+
expect(spawned).toEqual({ name: 'opencode-1', runtime: 'headless' })
563+
expect(local.spawnCli).toHaveBeenCalledWith(expect.objectContaining({
564+
name: 'opencode-1',
565+
cli: expect.stringContaining('opencode'),
566+
transport: 'headless'
567+
}))
568+
expect(local.spawnPty).not.toHaveBeenCalled()
569+
expect(local.resizePty).not.toHaveBeenCalled()
570+
expect(local.snapshot).not.toHaveBeenCalled()
571+
expect(attached).toEqual({
572+
name: 'opencode-1',
573+
mode: 'auto_inject',
574+
previousMode: 'passthrough',
575+
pending: 0,
576+
runtime: 'headless'
577+
})
578+
579+
await manager.shutdown()
580+
})
581+
582+
it('remembers headless runtime from discovered agents before attaching', async () => {
583+
const manager = new BrokerManager()
584+
const local = await startLocal(manager, [])
585+
local.listAgents.mockResolvedValue([
586+
{ name: 'opencode-1', runtime: 'headless', channels: [] }
587+
])
588+
589+
const attached = await manager.attachTerminal(PROJECT_ID, {
590+
name: 'opencode-1',
591+
mode: 'passthrough',
592+
rows: 24,
593+
cols: 80
594+
})
595+
596+
expect(local.setInboundDeliveryMode).toHaveBeenCalledWith('opencode-1', 'auto_inject')
597+
expect(local.resizePty).not.toHaveBeenCalled()
598+
expect(local.snapshot).not.toHaveBeenCalled()
599+
expect(attached.runtime).toBe('headless')
600+
601+
await manager.shutdown()
602+
})
603+
548604
it('coalesces concurrent duplicate spawn requests', async () => {
549605
const manager = new BrokerManager()
550606
const local = await startLocal(manager, [])

src/main/broker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,6 +2210,7 @@ export class BrokerManager {
22102210
sessionKeys.delete(sessionKey)
22112211
if (sessionKeys.size === 0) {
22122212
this.agentSessions.delete(name)
2213+
this.agentRuntimes.delete(name)
22132214
}
22142215
}
22152216

@@ -3488,6 +3489,7 @@ export class BrokerManager {
34883489
sessionKeys.delete(sessionKey)
34893490
if (sessionKeys.size === 0) {
34903491
this.agentSessions.delete(agentName)
3492+
this.agentRuntimes.delete(agentName)
34913493
}
34923494
}
34933495
}

0 commit comments

Comments
 (0)