fix(opencode): preserve external host during recovery
This commit is contained in:
@@ -792,11 +792,12 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|||||||
|
|
||||||
if (state.isExternalOpenCode) {
|
if (state.isExternalOpenCode) {
|
||||||
console.log('Re-probing external OpenCode server...');
|
console.log('Re-probing external OpenCode server...');
|
||||||
const probePort = state.openCodePort || env.ENV_CONFIGURED_OPENCODE_PORT || 4096;
|
const probePort = state.openCodePort ?? env.ENV_EFFECTIVE_PORT ?? 4096;
|
||||||
const probeOrigin = state.openCodeBaseUrl ?? env.ENV_CONFIGURED_OPENCODE_HOST?.origin;
|
const probeOrigin = state.openCodeBaseUrl ?? env.ENV_CONFIGURED_OPENCODE_HOST?.origin;
|
||||||
const healthy = await probeExternalOpenCode(probePort, probeOrigin);
|
const healthy = await probeExternalOpenCode(probePort, probeOrigin);
|
||||||
if (healthy) {
|
if (healthy) {
|
||||||
console.log(`External OpenCode server on port ${probePort} is healthy`);
|
console.log(`External OpenCode server on port ${probePort} is healthy`);
|
||||||
|
state.openCodeBaseUrl = probeOrigin ?? null;
|
||||||
setOpenCodePort(probePort);
|
setOpenCodePort(probePort);
|
||||||
state.isOpenCodeReady = true;
|
state.isOpenCodeReady = true;
|
||||||
state.lastOpenCodeError = null;
|
state.lastOpenCodeError = null;
|
||||||
@@ -875,7 +876,7 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to restart OpenCode: ${error.message}`);
|
console.error(`Failed to restart OpenCode: ${error.message}`);
|
||||||
state.lastOpenCodeError = error.message;
|
state.lastOpenCodeError = error.message;
|
||||||
if (!env.ENV_CONFIGURED_OPENCODE_PORT) {
|
if (!env.ENV_EFFECTIVE_PORT) {
|
||||||
state.openCodePort = null;
|
state.openCodePort = null;
|
||||||
syncToHmrState();
|
syncToHmrState();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,6 +151,56 @@ describe('OpenCode lifecycle', () => {
|
|||||||
expect(terminalEvents).toHaveLength(1);
|
expect(terminalEvents).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('recovers an external OPENCODE_HOST connection using its configured endpoint', async () => {
|
||||||
|
const fetchMock = vi.fn(async () => ({
|
||||||
|
ok: true,
|
||||||
|
json: async () => ({ healthy: true }),
|
||||||
|
}));
|
||||||
|
globalThis.fetch = fetchMock;
|
||||||
|
const runtime = createRuntime({}, {
|
||||||
|
openCodePort: null,
|
||||||
|
openCodeBaseUrl: null,
|
||||||
|
isExternalOpenCode: true,
|
||||||
|
}, {
|
||||||
|
ENV_CONFIGURED_OPENCODE_PORT: null,
|
||||||
|
ENV_CONFIGURED_OPENCODE_HOST: { origin: 'http://seamus:4095', port: 4095 },
|
||||||
|
ENV_EFFECTIVE_PORT: 4095,
|
||||||
|
});
|
||||||
|
|
||||||
|
await runtime.restartOpenCode();
|
||||||
|
|
||||||
|
expect(fetchMock).toHaveBeenCalledWith(
|
||||||
|
'http://seamus:4095/global/health',
|
||||||
|
expect.objectContaining({ method: 'GET' }),
|
||||||
|
);
|
||||||
|
expect(runtime.testState.openCodePort).toBe(4095);
|
||||||
|
expect(runtime.testState.openCodeBaseUrl).toBe('http://seamus:4095');
|
||||||
|
expect(runtime.testState.lastOpenCodeError).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('retains the OPENCODE_HOST port after an external re-probe fails', async () => {
|
||||||
|
globalThis.fetch = vi.fn(async () => ({
|
||||||
|
ok: false,
|
||||||
|
json: async () => null,
|
||||||
|
}));
|
||||||
|
const runtime = createRuntime({}, {
|
||||||
|
openCodePort: 4095,
|
||||||
|
openCodeBaseUrl: 'http://seamus:4095',
|
||||||
|
isExternalOpenCode: true,
|
||||||
|
}, {
|
||||||
|
ENV_CONFIGURED_OPENCODE_PORT: null,
|
||||||
|
ENV_CONFIGURED_OPENCODE_HOST: { origin: 'http://seamus:4095', port: 4095 },
|
||||||
|
ENV_EFFECTIVE_PORT: 4095,
|
||||||
|
});
|
||||||
|
|
||||||
|
await expect(runtime.restartOpenCode()).rejects.toThrow(
|
||||||
|
'External OpenCode server on port 4095 is not responding',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(runtime.testState.openCodePort).toBe(4095);
|
||||||
|
expect(runtime.testState.openCodeBaseUrl).toBe('http://seamus:4095');
|
||||||
|
});
|
||||||
|
|
||||||
it('warms recently used directories after a successful bootstrap', async () => {
|
it('warms recently used directories after a successful bootstrap', async () => {
|
||||||
const fetchMock = vi.fn(async () => ({
|
const fetchMock = vi.fn(async () => ({
|
||||||
ok: true,
|
ok: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user