refactor(settings): scope the settings project selector to settings
Picking a project in Settings called setActiveProject, which relocates the chat, the session list, the file tree and the Git surface. Reading another project's MCP servers or agents moved the user's whole app. It had to, because the configuration stores resolved the directory themselves from the active project and held one flat list. Each of them now takes an explicit directory — omitted still means the active project, so every caller outside Settings is unchanged — and keys loaded data by directory next to a flat mirror of the active project. Chat, autocompletes and pickers keep reading that mirror; a load for another directory writes only the map. A failed load restores that directory's previous list. Settings resolves its own directory through useSettingsDirectory, backed by a session-local settingsProjectPath that follows the active project until the user picks something else.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { cn, getModifierLabel } from '@/lib/utils';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useSettingsDirectory } from '@/hooks/useSettingsDirectory';
|
||||
import { useProjectsStore } from '@/stores/useProjectsStore';
|
||||
import { useAgentsStore } from '@/stores/useAgentsStore';
|
||||
import { useCommandsStore } from '@/stores/useCommandsStore';
|
||||
@@ -254,23 +255,24 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
||||
}, [visiblePages]);
|
||||
|
||||
const activeProjectId = useProjectsStore((state) => state.activeProjectId);
|
||||
const settingsDirectory = useSettingsDirectory();
|
||||
|
||||
// Load stores when project changes or when a page becomes active.
|
||||
// Load stores when the settings project changes or a page becomes active.
|
||||
React.useEffect(() => {
|
||||
if (!isSettingsDialogOpen && !runtimeCtx.isVSCode && !isWindowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (settingsSlug === 'agents') {
|
||||
void useAgentsStore.getState().loadAgents();
|
||||
void useAgentsStore.getState().loadAgents(settingsDirectory);
|
||||
return;
|
||||
}
|
||||
if (settingsSlug === 'commands') {
|
||||
void useCommandsStore.getState().loadCommands();
|
||||
void useCommandsStore.getState().loadCommands(settingsDirectory);
|
||||
return;
|
||||
}
|
||||
if (settingsSlug === 'mcp') {
|
||||
void useMcpConfigStore.getState().loadMcpConfigs();
|
||||
void useMcpConfigStore.getState().loadMcpConfigs({ directory: settingsDirectory });
|
||||
return;
|
||||
}
|
||||
if (settingsSlug === 'plugins') {
|
||||
@@ -278,13 +280,15 @@ export const SettingsView: React.FC<SettingsViewProps> = ({ onClose, forceMobile
|
||||
return;
|
||||
}
|
||||
if (settingsSlug === 'skills.installed' || settingsSlug === 'skills.catalog') {
|
||||
void useSkillsStore.getState().loadSkills();
|
||||
void useSkillsStore.getState().loadSkills(settingsDirectory);
|
||||
void useSkillsCatalogStore.getState().loadCatalog();
|
||||
}
|
||||
if (settingsSlug === 'snippets') {
|
||||
void useSnippetsStore.getState().loadSnippets();
|
||||
}
|
||||
}, [activeProjectId, isSettingsDialogOpen, isWindowed, runtimeCtx.isVSCode, settingsSlug]);
|
||||
// `activeProjectId` still matters: the settings directory follows the active
|
||||
// project until the user picks another one in the Settings selector.
|
||||
}, [activeProjectId, isSettingsDialogOpen, isWindowed, runtimeCtx.isVSCode, settingsDirectory, settingsSlug]);
|
||||
|
||||
const openPage = React.useCallback((slug: SettingsPageSlug) => {
|
||||
setSettingsPage(slug);
|
||||
|
||||
Reference in New Issue
Block a user