fix: align chat MCP tooling with session project

Resolve chat tooling from the selected session's project instead of the
separately tracked selectedProjectId so project-scoped discovered MCPs do
not appear for the wrong session. Also synchronize selectedProjectId when
a session is selected and add regression tests for both behaviors.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
David Kaya
2026-03-25 21:57:30 +01:00
co-authored by Copilot
parent e5878ba9e8
commit c8bb9d6f59
5 changed files with 112 additions and 5 deletions
@@ -224,4 +224,37 @@ describe('EryxAppService discovered tooling', () => {
},
]);
});
test('selecting a session also selects that session project', async () => {
const workspace = createWorkspaceSeed();
const pattern = workspace.patterns.find((candidate) => candidate.mode === 'single');
if (!pattern) {
throw new Error('Expected a single-agent pattern in the workspace seed.');
}
const projectAlpha = createProject({
id: 'project-alpha',
name: 'alpha',
path: 'C:\\workspace\\alpha',
});
const projectBeta = createProject({
id: 'project-beta',
name: 'beta',
path: 'C:\\workspace\\beta',
});
const session = createSession(projectBeta.id, pattern.id, {
id: 'session-beta',
});
workspace.projects = [projectAlpha, projectBeta];
workspace.sessions = [session];
workspace.selectedProjectId = projectAlpha.id;
const service = createService(workspace, pattern);
const updatedWorkspace = await service.selectSession(session.id);
expect(updatedWorkspace.selectedSessionId).toBe(session.id);
expect(updatedWorkspace.selectedProjectId).toBe(projectBeta.id);
});
});
@@ -1,8 +1,11 @@
import { describe, expect, test } from 'bun:test';
import { resolveChatToolingSettings } from '@renderer/lib/chatTooling';
import type { DiscoveredLocalMcpServer } from '@shared/domain/discoveredTooling';
import { listPendingDiscoveredMcpServers, normalizeDiscoveredToolingState, type DiscoveredToolingState } from '@shared/domain/discoveredTooling';
import type { ProjectRecord } from '@shared/domain/project';
import { resolveProjectToolingSettings, createWorkspaceSettings, type WorkspaceSettings } from '@shared/domain/tooling';
import { createWorkspaceSeed } from '@shared/domain/workspace';
function makeDiscoveredServer(
overrides: Partial<DiscoveredLocalMcpServer> & { id: string; name: string },
@@ -117,4 +120,49 @@ describe('frontend discovered tooling integration', () => {
expect(projectDiscovered).toHaveLength(1);
expect(projectDiscovered[0].name).toBe('proj-srv');
});
test('chat tooling follows the session project instead of the separately selected project', () => {
const workspace = createWorkspaceSeed();
const sessionProject: ProjectRecord = {
id: 'project-session',
name: 'session-project',
path: 'C:\\workspace\\session-project',
addedAt: '2026-03-25T00:00:00.000Z',
discoveredTooling: normalizeDiscoveredToolingState({
mcpServers: [
makeDiscoveredServer({
id: 'discovered_project_project_session_vscode_mcp_session_srv',
name: 'session-srv',
status: 'accepted',
scope: 'project',
}),
],
}),
};
const separatelySelectedProject: ProjectRecord = {
id: 'project-selected',
name: 'selected-project',
path: 'C:\\workspace\\selected-project',
addedAt: '2026-03-25T00:00:00.000Z',
discoveredTooling: normalizeDiscoveredToolingState({
mcpServers: [
makeDiscoveredServer({
id: 'discovered_project_project_selected_vscode_mcp_selected_srv',
name: 'selected-srv',
status: 'accepted',
scope: 'project',
}),
],
}),
};
workspace.projects = [sessionProject, separatelySelectedProject];
workspace.selectedProjectId = separatelySelectedProject.id;
const tooling = resolveChatToolingSettings(workspace, sessionProject);
const serverIds = tooling?.mcpServers.map((server) => server.id) ?? [];
expect(serverIds).toContain('discovered_project_project_session_vscode_mcp_session_srv');
expect(serverIds).not.toContain('discovered_project_project_selected_vscode_mcp_selected_srv');
});
});