(cwd: string)
| 84 | } |
| 85 | |
| 86 | async function runOpencodeProbe(cwd: string): Promise<ListOpencodeModelsForCwdResponse> { |
| 87 | const transport = new AcpStdioTransport({ |
| 88 | command: 'opencode', |
| 89 | args: ['acp'] |
| 90 | }); |
| 91 | |
| 92 | try { |
| 93 | const initResponse = await transport.sendRequest('initialize', { |
| 94 | protocolVersion: 1, |
| 95 | clientCapabilities: { |
| 96 | fs: { readTextFile: false, writeTextFile: false }, |
| 97 | terminal: false |
| 98 | }, |
| 99 | clientInfo: { |
| 100 | name: 'hapi-opencode-models', |
| 101 | version: packageJson.version |
| 102 | } |
| 103 | }, { timeoutMs: PROBE_TIMEOUT_MS }); |
| 104 | |
| 105 | if (!isObject(initResponse) || typeof initResponse.protocolVersion !== 'number') { |
| 106 | return { success: false, error: 'Invalid initialize response from opencode acp' }; |
| 107 | } |
| 108 | |
| 109 | const newResponse = await transport.sendRequest('session/new', { |
| 110 | cwd, |
| 111 | mcpServers: [] |
| 112 | }, { timeoutMs: PROBE_TIMEOUT_MS }); |
| 113 | |
| 114 | const { availableModels, currentModelId } = extractModelsFromResponse(newResponse); |
| 115 | |
| 116 | return { |
| 117 | success: true, |
| 118 | availableModels, |
| 119 | currentModelId |
| 120 | }; |
| 121 | } finally { |
| 122 | await transport.close().catch(() => undefined); |
| 123 | } |
| 124 | } |
| 125 | |
| 126 | /** |
| 127 | * Discover available OpenCode models for a given working directory by spawning |
no test coverage detected