diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 3fd5cf2..91e8e0f 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -18,6 +18,7 @@ import { router, useFocusEffect } from "expo-router" import { Ionicons } from "@expo/vector-icons" import { useSessions } from "../../src/stores/sessions" import { useConnections } from "../../src/stores/connections" +import { useCatalog } from "../../src/stores/catalog" import type BottomSheet from "@gorhom/bottom-sheet" import type { Session } from "../../src/lib/sdk" import { DirectorySwitcher } from "../../src/components/chat" @@ -123,6 +124,7 @@ export default function SessionsScreen() { addRecentDirectory, recentDirectories, } = useConnections() + const loadCatalog = useCatalog((s) => s.load) const dirSheetRef = useRef(null) const [refreshing, setRefreshing] = useState(false) @@ -131,8 +133,9 @@ export default function SessionsScreen() { await switchDirectory(dir) loadSessions() refreshProject() + loadCatalog() }, - [switchDirectory, loadSessions, refreshProject], + [switchDirectory, loadSessions, refreshProject, loadCatalog], ) useFocusEffect( @@ -157,12 +160,14 @@ export default function SessionsScreen() { const submitRename = useCallback(async () => { const title = renameText.trim() - if (!title || !renaming || !client) return - await client.session.update(renaming.id, { title }) + if (!title || !renaming) return + const renameClient = renaming.directory ? (clientForDirectory(renaming.directory) ?? client) : client + if (!renameClient) return + await renameClient.session.update(renaming.id, { title }) setRenaming(null) setRenameText("") loadSessions() - }, [renaming, renameText, client, loadSessions]) + }, [renaming, renameText, client, clientForDirectory, loadSessions]) const handleDelete = useCallback( (session: Session) => { diff --git a/app/session/[id].tsx b/app/session/[id].tsx index 118c388..9fde691 100644 --- a/app/session/[id].tsx +++ b/app/session/[id].tsx @@ -107,7 +107,13 @@ export default function SessionScreen() { const isSending = useSessions((s) => !!(currentSession && s.sending[currentSession.id])) const { authenticateForMessage } = useAuth() - const { client } = useConnections() + const { client, clientForDirectory } = useConnections() + + // Use directory-aware client for sessions that belong to a project other than the active one + const sessionClient = useMemo( + () => (currentSession?.directory ? (clientForDirectory(currentSession.directory) ?? client) : client), + [currentSession?.directory, clientForDirectory, client], + ) // Catalog const catalog = useCatalog() @@ -170,9 +176,11 @@ export default function SessionScreen() { selectSession(id, directory).then(() => { // Re-fetch pending permissions/questions from the server to recover from // missed SSE events or failed optimistic removals - if (client) refreshPending(client, id) + const connState = useConnections.getState() + const c = directory ? (connState.clientForDirectory(directory) ?? connState.client) : connState.client + if (c) refreshPending(c, id) }) - }, [id]) + }, [id, directory]) // Sync model chip from latest assistant message useEffect(() => { @@ -320,8 +328,8 @@ export default function SessionScreen() { const [cmdName, ...args] = text.split(" ") const name = cmdName.slice(1) const match = serverCommands.find((c) => c.name === name) - if (match && client && currentSession) { - client.session + if (match && sessionClient && currentSession) { + sessionClient.session .command(currentSession.id, { command: name, arguments: args.join(" "), @@ -359,7 +367,7 @@ export default function SessionScreen() { }, [loadingMore]) const handlePermissionReply = async (requestID: string, reply: "once" | "always" | "reject") => { - if (!client || !sessionID) return + if (!sessionClient || !sessionID) return // Snapshot for rollback const snapshot = useEvents.getState().permissions[sessionID] || [] // Optimistically remove from UI @@ -370,7 +378,7 @@ export default function SessionScreen() { }, })) try { - await client.permission.reply(requestID, reply) + await sessionClient.permission.reply(requestID, reply) } catch (err) { console.error("Permission reply failed:", err) // Restore the prompt so the user can retry @@ -382,7 +390,7 @@ export default function SessionScreen() { } const handleQuestionReply = async (requestID: string, answers: string[][]) => { - if (!client || !sessionID) return + if (!sessionClient || !sessionID) return const snapshot = useEvents.getState().questions[sessionID] || [] useEvents.setState((state) => ({ questions: { @@ -391,7 +399,7 @@ export default function SessionScreen() { }, })) try { - await client.question.reply(requestID, answers) + await sessionClient.question.reply(requestID, answers) } catch (err) { console.error("Question reply failed:", err) useEvents.setState((state) => ({ @@ -402,7 +410,7 @@ export default function SessionScreen() { } const handleQuestionReject = async (requestID: string) => { - if (!client || !sessionID) return + if (!sessionClient || !sessionID) return const snapshot = useEvents.getState().questions[sessionID] || [] useEvents.setState((state) => ({ questions: { @@ -411,7 +419,7 @@ export default function SessionScreen() { }, })) try { - await client.question.reject(requestID) + await sessionClient.question.reject(requestID) } catch (err) { console.error("Question reject failed:", err) useEvents.setState((state) => ({ diff --git a/src/stores/catalog.ts b/src/stores/catalog.ts index e926d64..aaf5594 100644 --- a/src/stores/catalog.ts +++ b/src/stores/catalog.ts @@ -85,16 +85,6 @@ export const useCatalog = create((set, get) => ({ .filter((p) => p.models.length > 0) : [] - console.log( - "[catalog] loaded:", - agents.length, - "agents,", - commands.length, - "commands,", - providers.length, - "providers (" + providers.reduce((n, p) => n + p.models.length, 0) + " models)", - ) - // Filter out hidden agents const visible = agents.filter((a) => !a.hidden) diff --git a/src/stores/sessions.ts b/src/stores/sessions.ts index cf6e162..b324d3d 100644 --- a/src/stores/sessions.ts +++ b/src/stores/sessions.ts @@ -193,7 +193,8 @@ export const useSessions = create((set, get) => ({ }, deleteSession: async (sessionID) => { - const client = useConnections.getState().client + const session = get().sessions.find((s) => s.id === sessionID) + const client = clientFor(session?.directory) if (!client) { set({ error: "No active connection" }) return