Defer OpenCode restarts for config mutations
Co-authored-by: Serhii Dziupin <makeittech@users.noreply.github.com>
This commit is contained in:
co-authored by
Serhii Dziupin
parent
824d1fbbf4
commit
775da6e9f4
@@ -52,6 +52,25 @@ afterEach(() => {
|
||||
const readJson = (filePath) => JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
|
||||
describe('VS Code config bridge plugin parity', () => {
|
||||
test('explicit config reload restarts OpenCode', async () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-vscode-reload-'));
|
||||
tempRoots.push(root);
|
||||
const ctx = createCtx(root);
|
||||
|
||||
const reloaded = await handleConfigBridgeMessage({
|
||||
id: 'reload',
|
||||
type: 'api:config/reload',
|
||||
}, ctx, deps);
|
||||
|
||||
expect(reloaded).toEqual({
|
||||
id: 'reload',
|
||||
type: 'api:config/reload',
|
||||
success: true,
|
||||
data: { restarted: true },
|
||||
});
|
||||
expect(ctx.restart).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test('removes agent fields when update payload sends null', async () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-vscode-agent-null-'));
|
||||
tempRoots.push(root);
|
||||
@@ -102,7 +121,14 @@ describe('VS Code config bridge plugin parity', () => {
|
||||
}, ctx, deps);
|
||||
|
||||
expect(created?.success).toBe(true);
|
||||
expect(ctx.restart).toHaveBeenCalledTimes(1);
|
||||
expect(created?.data).toMatchObject({
|
||||
success: true,
|
||||
requiresReload: false,
|
||||
requiresRestart: true,
|
||||
restartDeferred: true,
|
||||
message: 'Plugin entry changed. Restart OpenCode to apply.',
|
||||
});
|
||||
expect(ctx.restart).not.toHaveBeenCalled();
|
||||
|
||||
const listed = await handleConfigBridgeMessage({
|
||||
id: 'list',
|
||||
@@ -251,27 +277,36 @@ describe('VS Code config bridge plugin parity', () => {
|
||||
expect(fs.readFileSync(path.join(configDir, 'plugins', 'demo-plugin.ts'), 'utf8')).toBe('export default {}');
|
||||
});
|
||||
|
||||
test('reports plugin mutation success when restart fails after writing config', async () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-vscode-plugin-restart-'));
|
||||
test('creates MCP config with deferred restart when restart would fail', async () => {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'openchamber-vscode-mcp-deferred-'));
|
||||
tempRoots.push(root);
|
||||
const ctx = createCtx(root, async () => {
|
||||
throw new Error('restart failed');
|
||||
});
|
||||
|
||||
const created = await handleConfigBridgeMessage({
|
||||
id: 'create-restart-failure',
|
||||
type: 'api:config/plugins',
|
||||
id: 'create-mcp-deferred',
|
||||
type: 'api:config/mcp',
|
||||
payload: {
|
||||
method: 'POST',
|
||||
target: 'entry',
|
||||
name: 'mcp-deferred',
|
||||
directory: root,
|
||||
body: { scope: 'project', spec: 'plugin-restart' },
|
||||
body: { scope: 'project', type: 'local', command: ['node', 'server.js'] },
|
||||
},
|
||||
}, ctx, deps);
|
||||
|
||||
expect(created?.success).toBe(true);
|
||||
expect(created?.data).toMatchObject({ success: true, requiresReload: false, reloadFailed: true });
|
||||
expect(created?.data?.warning).toContain('restart failed');
|
||||
expect(readJson(path.join(root, '.opencode', 'opencode.json')).plugin).toEqual(['plugin-restart']);
|
||||
expect(created?.data).toMatchObject({
|
||||
success: true,
|
||||
requiresReload: false,
|
||||
requiresRestart: true,
|
||||
restartDeferred: true,
|
||||
message: 'MCP server "mcp-deferred" created. Restart OpenCode to apply.',
|
||||
});
|
||||
expect(ctx.restart).not.toHaveBeenCalled();
|
||||
expect(readJson(path.join(root, '.opencode', 'opencode.json')).mcp['mcp-deferred']).toMatchObject({
|
||||
type: 'local',
|
||||
command: ['node', 'server.js'],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user