Files
orca/src/main/opencode/opencode-startup-prompt-installer.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

83 lines
3.2 KiB
TypeScript

import { OpenCodeHookService, openCodeHookService, openCode2HookService } from './hook-service'
import { OPENCODE_STARTUP_PROMPT_PLUGIN_DIRECTORY } from '../../shared/opencode-startup-prompt-install'
import { join } from 'node:path'
import { resolveOpenCodeConfigDirectory } from '../../shared/opencode-config-directory'
import { isOverlayOpenCodePluginCurrent } from '../../shared/opencode-installed-plugin'
import { getOpenCodeStartupPromptSource } from './opencode-startup-prompt-source'
import { resolveOpenCodeSourceConfigDir } from '../ipc/pty/host-env/pi-agent'
import {
OPENCODE_STARTUP_PROMPT_NONCE_ENV,
OPENCODE_STARTUP_PROMPT_SHA256_ENV,
OPENCODE_STARTUP_PROMPT_BODY_ENV,
OPENCODE_STARTUP_PROMPT_ENDPOINT_ENV
} from '../../shared/opencode-startup-prompt'
export function createOpenCodeStartupPromptInstaller(source: () => string): OpenCodeHookService {
return new OpenCodeHookService({
pluginFileName: `${OPENCODE_STARTUP_PROMPT_PLUGIN_DIRECTORY}.js`,
legacyHooksDir: 'opencode-startup-prompt-hooks',
overlayDir: 'opencode-startup-prompt-overlays',
pluginSource: source,
tuiOnlyDirectory: OPENCODE_STARTUP_PROMPT_PLUGIN_DIRECTORY
})
}
const installer = createOpenCodeStartupPromptInstaller(getOpenCodeStartupPromptSource)
export function installOpenCodeStartupPromptForLaunch(
env: Record<string, string>,
restoreAfterShellStartup = true,
sourceEnvironment: NodeJS.ProcessEnv = { ...process.env, ...env }
): boolean {
const nonce = env[OPENCODE_STARTUP_PROMPT_NONCE_ENV]
if (!nonce || env.ORCA_OPENCODE_PLUGIN_API !== 'v2') {
return false
}
const source =
resolveOpenCodeSourceConfigDir(env, sourceEnvironment) ||
resolveOpenCodeConfigDirectory(sourceEnvironment)
const statusOwner =
env.ORCA_OPENCODE_AGENT === 'opencode2' ? openCode2HookService : openCodeHookService
const existing =
env.OPENCODE_CONFIG_DIR && env.OPENCODE_CONFIG_DIR === env.ORCA_OPENCODE_CONFIG_DIR
? installer.installIntoSourceOverlay(env.OPENCODE_CONFIG_DIR, source, statusOwner)
: 'unmatched'
const overlay =
existing === 'installed'
? env.OPENCODE_CONFIG_DIR
: existing === 'failed'
? undefined
: installer.buildPtyEnv(nonce, source).OPENCODE_CONFIG_DIR
if (
!overlay ||
!isOverlayOpenCodePluginCurrent(
join(overlay, 'plugins', OPENCODE_STARTUP_PROMPT_PLUGIN_DIRECTORY, 'tui.js'),
getOpenCodeStartupPromptSource()
)
) {
for (const key of [
OPENCODE_STARTUP_PROMPT_NONCE_ENV,
OPENCODE_STARTUP_PROMPT_SHA256_ENV,
OPENCODE_STARTUP_PROMPT_BODY_ENV,
OPENCODE_STARTUP_PROMPT_ENDPOINT_ENV
]) {
delete env[key]
}
return false
}
env.OPENCODE_CONFIG_DIR = overlay
env.ORCA_OPENCODE_SOURCE_CONFIG_DIR = source
if (restoreAfterShellStartup || existing === 'installed') {
env.ORCA_OPENCODE_CONFIG_DIR = overlay
} else {
delete env.ORCA_OPENCODE_CONFIG_DIR
}
return true
}
export function ensureOpenCodeStartupPromptForLaunch(env: Record<string, string>): void {
if (env[OPENCODE_STARTUP_PROMPT_NONCE_ENV] && !installOpenCodeStartupPromptForLaunch(env)) {
throw new Error('Cannot prepare OpenCode startup prompt; launch was canceled.')
}
}