Files
orca/src/main/opencode/opencode-startup-prompt-runtime-identity.test.ts
T
e8310d5a4f fix(opencode): submit admitted native startup briefs without overwriting input (#24762)
* fix: wait for OpenCode worker composer before first dispatch

Reuse captured composer readiness on local and paired execution hosts and revoke launching-shell paste anchors.

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>

* feat(opencode): probe execution-host CLI capabilities

* fix(opencode): select plugin default for execution host loader

* fix(opencode): limit prompt prefill capability to verified release

* feat(opencode): probe launch capabilities on the execution host

* fix(opencode): select plugin loader for the launched host binary

* fix(opencode): match WSL probe cwd and declared guest environment

* fix(opencode): preserve launch environment deletion boundaries

* wip(opencode): authorize native startup prompt intent at execution owner

* fix(opencode): atomically replace status plugin entrypoints

* fix(opencode): retain plugin permissions across restrictive umasks

* test(opencode): resolve permission fixture from primary cwd

* feat(opencode): install startup prompt plugin independently of status hooks

* fix(opencode): wait for admitted startup intent and preserve failed-launch briefs

* fix(opencode): unsubscribe hook settings during async host shutdown

* STRICT launch CI contract correction

* CAPS launch CI contract correction

* INTENT launch CI contract correction

* test: initialize Claude prompt state in output retention fixture

* Wait for OpenCode location hydration in intent startup

* Bind OpenCode startup readiness to the current location in intent startup

* Retry interrupted OpenCode startup prompt claims

---------

Co-authored-by: Brennan Benson <79079362+brennanb2025@users.noreply.github.com>
Co-authored-by: Ahmed Nagy <ahmednagy25t@gmail.com>
Co-authored-by: Orca startup hydration review <agents@stably.ai>
Co-authored-by: Orca <dev@stably.ai>
2026-10-04 01:41:01 -07:00

81 lines
3.2 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { OpenCodeStartupPromptClaims } from './opencode-startup-prompt-claims'
import {
createTranscriptPane,
TRANSCRIPT_PANE_PTY_ID
} from '../runtime/agent-transcript-pane-test-harness'
vi.mock('electron', () => ({
BrowserWindow: { fromId: vi.fn(() => null) },
webContents: { fromId: vi.fn(() => null) },
ipcMain: { on: vi.fn(), removeListener: vi.fn() },
app: { getPath: vi.fn(() => '/tmp') }
}))
async function fixture(launchAgent?: 'opencode' | 'opencode2' | 'zcode') {
const { runtime } = await createTranscriptPane({
paneTitle: 'Terminal',
foregroundProcess: null,
data: '',
...(launchAgent ? { launchAgent } : {})
})
runtime.terminalRunFacts.recordSpawnCommit({ id: TRANSCRIPT_PANE_PTY_ID, incarnationId: 'inc-1' })
const read = (
ptyId = TRANSCRIPT_PANE_PTY_ID,
incarnation = 'inc-1',
token = 'transcript-launch'
) => runtime.readOpenCodeStartupPromptOwner(ptyId, incarnation, token)
return { runtime, read }
}
describe('runtime-owned startup prompt identity', () => {
it('keeps launch admission pending before runtime identity is assigned', async () => {
const f = await fixture()
expect(f.read()).toBe('pending')
expect(f.read('missing')).toBeNull()
expect(f.read(TRANSCRIPT_PANE_PTY_ID, 'previous-incarnation')).toBeNull()
})
it.each(['opencode', 'opencode2'] as const)(
'reads only the admitted %s launch',
async (agent) => {
const f = await fixture(agent)
expect(f.read()).toEqual({ freshSpawn: true, firstUserInputAt: null })
expect(f.read(TRANSCRIPT_PANE_PTY_ID, 'inc-1', 'another-launch')).toBeNull()
expect(f.read(TRANSCRIPT_PANE_PTY_ID, 'previous-incarnation')).toBeNull()
f.runtime.terminalRunFacts.recordInput(TRANSCRIPT_PANE_PTY_ID, 'driving', 'x', 123)
expect(f.read()).toEqual({ freshSpawn: true, firstUserInputAt: 123 })
}
)
it('denies another agent even with the exact incarnation and launch token', async () => {
expect((await fixture('zcode')).read()).toBeNull()
})
it('refuses same-ID replay after the execution owner or launch token changes', async () => {
const f = await fixture('opencode2')
const claims = new OpenCodeStartupPromptClaims()
claims.register('owned-operation', 'digest', () => f.read())
const body = { nonce: 'owned-operation', digest: 'digest', requestId: 'stable-operation' }
expect(claims.claim(body)).toBe(true)
expect(claims.claim(body)).toBe(true)
await f.runtime.onPtyExit(TRANSCRIPT_PANE_PTY_ID, 0, 'inc-1')
f.runtime.registerPty(TRANSCRIPT_PANE_PTY_ID, 'wt-1', null, {
tabId: 'tab-1',
leafId: '11111111-1111-4111-8111-111111111111',
incarnationId: 'inc-2',
agentLaunchAuthority: { launchToken: 'replacement-launch', launchAgent: 'opencode2' }
})
f.runtime.terminalRunFacts.recordSpawnCommit({
id: TRANSCRIPT_PANE_PTY_ID,
incarnationId: 'inc-2'
})
expect(f.read(TRANSCRIPT_PANE_PTY_ID, 'inc-2', 'replacement-launch')).toEqual({
freshSpawn: true,
firstUserInputAt: null
})
expect(f.read(TRANSCRIPT_PANE_PTY_ID, 'inc-2', 'transcript-launch')).toBeNull()
expect(claims.claim(body)).toBe(false)
claims.clear()
})
})