diff --git a/src/renderer/src/components/sessions/FileMentionPopover.tsx b/src/renderer/src/components/sessions/FileMentionPopover.tsx
index eaab654f..374d6493 100644
--- a/src/renderer/src/components/sessions/FileMentionPopover.tsx
+++ b/src/renderer/src/components/sessions/FileMentionPopover.tsx
@@ -82,7 +82,7 @@ export function FileMentionPopover({
) : (
suggestions.map((file, index) => (
| null>(null)
- // Flat file index for file mentions and search — keyed by worktree path.
- // Uses git ls-files for a complete, gitignore-respecting file list.
- // Ensure the index is loaded when worktreePath is resolved — SessionView cannot
- // rely on the FileTree sidebar component having already populated the store
- // (sidebar may be collapsed, on a different tab, or targeting a different worktree).
- const fileIndex = useFileTreeStore((state) =>
- worktreePath
- ? (state.fileIndexByWorktree.get(worktreePath) ?? EMPTY_FILE_INDEX)
- : EMPTY_FILE_INDEX
+ // Connection path resolution error state
+ const [connectionPathError, setConnectionPathError] = useState
(null)
+
+ // Flat file index for file mentions and search.
+ // For worktree sessions: use worktreePath as key
+ // For connection sessions: use `connection:${connectionId}` as key and aggregate from all members
+ const fileIndex = useFileTreeStore((state) => {
+ if (worktreeId) {
+ // Regular worktree session
+ return worktreePath
+ ? (state.fileIndexByWorktree.get(worktreePath) ?? EMPTY_FILE_INDEX)
+ : EMPTY_FILE_INDEX
+ } else if (connectionId) {
+ // Connection session - use connectionId as key
+ const cacheKey = `connection:${connectionId}`
+ return state.fileIndexByWorktree.get(cacheKey) ?? EMPTY_FILE_INDEX
+ }
+ return EMPTY_FILE_INDEX
+ })
+
+ // Subscribe to connection data for connection sessions
+ const activeConnection = useConnectionStore((state) =>
+ connectionId ? state.connections.find((c) => c.id === connectionId) : undefined
)
+
useEffect(() => {
- if (worktreePath && fileIndex === EMPTY_FILE_INDEX) {
+ if (worktreeId && worktreePath && fileIndex === EMPTY_FILE_INDEX) {
+ // Regular worktree session - load from single worktree
+ console.log('[SessionView] Loading file index for worktree:', worktreePath)
useFileTreeStore.getState().loadFileIndex(worktreePath)
+ } else if (connectionId && fileIndex === EMPTY_FILE_INDEX) {
+ // Connection session - load from all member worktrees
+ // Use the subscribed activeConnection instead of imperative getState()
+ if (activeConnection && activeConnection.members.length > 0) {
+ const members = activeConnection.members.map((m) => ({
+ symlinkName: m.symlink_name,
+ worktreePath: m.worktree_path
+ }))
+ console.log(
+ '[SessionView] Loading file index for connection:',
+ connectionId,
+ 'from',
+ members.length,
+ 'members'
+ )
+ useFileTreeStore.getState().loadFileIndexForConnection(connectionId, members)
+ } else if (!activeConnection) {
+ console.warn('[SessionView] Connection not found for file index loading', {
+ sessionId,
+ connectionId
+ })
+ } else {
+ console.warn('[SessionView] Connection has no members - file mentions disabled', {
+ sessionId,
+ connectionId
+ })
+ }
}
- }, [worktreePath, fileIndex])
+ }, [worktreeId, worktreePath, connectionId, fileIndex, sessionId, activeConnection])
// File mentions hook
const fileMentions = useFileMentions(inputValue, cursorPosition, fileIndex)
@@ -1903,16 +1947,28 @@ export function SessionView({ sessionId }: SessionViewProps): React.JSX.Element
} else if (session.connection_id) {
// Connection session: resolve the connection folder path
setConnectionId(session.connection_id)
+ setConnectionPathError(null) // Clear any previous error
try {
const connResult = await window.connectionOps.get(session.connection_id)
if (shouldAbortInit()) return
+
if (connResult.success && connResult.connection) {
wtPath = connResult.connection.path
setWorktreePath(wtPath)
transcriptSourceRef.current.worktreePath = wtPath
+ setConnectionPathError(null) // Explicitly clear on success
+ } else {
+ // Connection lookup failed or returned no connection
+ const errorMsg = connResult.error || 'Connection not found'
+ console.error('Failed to resolve connection path:', errorMsg, 'connectionId:', session.connection_id)
+ setConnectionPathError(errorMsg)
+ toast.error(`Failed to load connection: ${errorMsg}`)
}
- } catch {
- console.warn('Failed to resolve connection path for session')
+ } catch (error) {
+ const errorMsg = error instanceof Error ? error.message : 'Unknown error'
+ console.error('Exception resolving connection path:', error, 'connectionId:', session.connection_id)
+ setConnectionPathError(errorMsg)
+ toast.error(`Failed to load connection: ${errorMsg}`)
}
}
@@ -4029,6 +4085,30 @@ export function SessionView({ sessionId }: SessionViewProps): React.JSX.Element
{/* Attachment previews */}
+ {/* Connection error banner */}
+ {connectionPathError && (
+
+
+
+
Connection Error
+
+ Failed to load connection path: {connectionPathError}. File mentions (@) will not work.
+
+
+
+
+ )}
+
{/* Middle: textarea */}