fix: isolate concurrent OpenCode chat runs

This commit is contained in:
2026-08-17 22:03:37 +08:00
parent 7e8d9e3811
commit 65040730ec
29 changed files with 5207 additions and 427 deletions

View File

@@ -105,6 +105,43 @@ describe('OpencodeManager', () => {
expect(manager.getStatus()).not.toBe(status);
});
it('exposes a stable generation that rolls over only when a new runtime starts', async () => {
const { children, spawn } = createSpawnHarness();
const manager = new OpencodeManager({
port: 4351,
binPath: 'C:\\NianCode\\opencode.exe',
findPortOwner: vi.fn().mockResolvedValue(null),
spawn,
});
expect(manager.getRuntimeGeneration()).toBe(0);
const initialStart = manager.start();
await vi.waitFor(() => expect(children).toHaveLength(1));
expect(manager.getRuntimeGeneration()).toBe(1);
expect(manager.getRuntimeGenerationProvenance()).toBe('starting');
children[0].stdout.emit(
'data',
Buffer.from('opencode server listening on http://127.0.0.1:4351\n'),
);
await initialStart;
expect(manager.getRuntimeGeneration()).toBe(1);
expect(manager.getRuntimeGenerationProvenance()).toBe('fresh');
expect(manager.getRuntimeGeneration()).toBe(1);
const restart = manager.restart();
children[0].emit('exit', 0);
await vi.waitFor(() => expect(children).toHaveLength(2));
children[1].stdout.emit(
'data',
Buffer.from('opencode server listening on http://127.0.0.1:4351\n'),
);
await restart;
expect(manager.getRuntimeGeneration()).toBe(2);
expect(manager.getRuntimeGenerationProvenance()).toBe('fresh');
});
it('falls back to an ephemeral port when the preferred port has an unhealthy listener', async () => {
const { children, calls, spawn } = createSpawnHarness();
const preferredPort = 4340;
@@ -429,6 +466,7 @@ describe('OpencodeManager', () => {
port: 4329,
url: 'http://127.0.0.1:4329',
});
expect(manager.getRuntimeGenerationProvenance()).toBe('attached');
expect(logWarn).toHaveBeenCalledWith(
'[opencode-runtime] Attached to an existing server; newly generated provider config may not be active',
expect.objectContaining({