fix(sessions): show all sessions across all projects (closes #48) (#50)

* fix(sessions): load all sessions across projects, not just active directory

Closes #48

Root cause: loadSessions() used connState.client which carries the
active connection's directory as x-opencode-directory header. The server
filters sessions by that directory, so only the current project's sessions
were visible.

Fix: call clientForDirectory(undefined) to get a no-header client.
The server then returns sessions from all projects.

The session row UI already showed a directory badge (shortDir from
session.directory), so no UI change is needed — each session already
displays its project folder name.

* fix(sessions): preserve directory when opening rows

Carry each listed session directory into the route so selection, messages, and follow-up operations use the matching project client.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Den
2026-07-16 17:33:00 -07:00
committed by GitHub
parent c1736bd426
commit 819996f5fa
3 changed files with 12 additions and 9 deletions

View File

@@ -49,7 +49,10 @@ function SessionItem({
onDelete: () => void onDelete: () => void
}) { }) {
const onPress = () => { const onPress = () => {
router.push(`/session/${session.id}`) router.push({
pathname: `/session/[id]`,
params: { id: session.id, ...(session.directory ? { directory: session.directory } : {}) },
})
} }
const onLongPress = () => { const onLongPress = () => {

View File

@@ -43,8 +43,9 @@ interface ConnectionsState {
) => Promise<{ ok: boolean; error?: string }> ) => Promise<{ ok: boolean; error?: string }>
updateConnection: (id: string, updates: Partial<ServerConnection>) => Promise<void> updateConnection: (id: string, updates: Partial<ServerConnection>) => Promise<void>
refreshProject: () => Promise<void> refreshProject: () => Promise<void>
// Create a one-off client pointing at a specific directory (for cross-project operations) // Create a one-off client pointing at a specific directory (for cross-project operations).
clientForDirectory: (directory: string) => Client | null // Pass undefined to get a directory-less client that queries the server without project scope.
clientForDirectory: (directory?: string) => Client | null
// Switch the active connection's directory and reload // Switch the active connection's directory and reload
switchDirectory: (directory?: string) => Promise<void> switchDirectory: (directory?: string) => Promise<void>
// Record a directory as recently used // Record a directory as recently used

View File

@@ -84,7 +84,9 @@ export const useSessions = create<SessionsState>((set, get) => ({
loadSessions: async () => { loadSessions: async () => {
const connState = useConnections.getState() const connState = useConnections.getState()
const client = connState.client // Use a directory-less client so the server returns sessions from ALL projects,
// not just the one matching the active connection's directory header.
const client = connState.clientForDirectory(undefined) || connState.client
if (!client) { if (!client) {
set({ error: "No active connection" }) set({ error: "No active connection" })
return return
@@ -92,11 +94,8 @@ export const useSessions = create<SessionsState>((set, get) => ({
try { try {
set({ isLoading: true, error: null }) set({ isLoading: true, error: null })
// List with the connection's default client and send no directory scope: // A directory-less list includes sessions across projects. Each row carries
// opencode-server resolves the x-opencode-directory header to a project by // its own directory into the session route so subsequent operations stay scoped.
// exact match, and $HOME maps to the empty "global" project, which hides the
// user's real workspace sessions (bug #32). The default client already carries
// the connection's explicit directory when one is configured.
const sessions = await client.session.list({ roots: true, limit: 50 }) const sessions = await client.session.list({ roots: true, limit: 50 })
set({ sessions, isLoading: false }) set({ sessions, isLoading: false })
} catch (error) { } catch (error) {