batch4: chats-in-sessions, force-send, /compact, right-rail file browser

Session 1:N Chat data model with backfill. Workspace switches to client-side
multi-tab pane management. Right-rail file browser with float-over viewer and
click-drag line selection replaces FileBrowserPane. Adds /compact streaming
summarizer (respects compact markers in context builder), force-send (cancels
in-flight, persists partial as 'cancelled', awaits cancellation completion via
deferred Promise + 5s timeout), message queue, stop generation, chat
auto-rename, session archive/unarchive with Closed Sessions section on repo
landing page. CHECK constraints on sessions.status, messages.role,
messages.status with KEEP IN SYNC comments tying to MESSAGE_ROLES /
MESSAGE_STATUSES const arrays. Deletes dead pane routes/hook and the
api.panes.* client block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-15 20:39:48 +00:00
parent 6d9515b8a5
commit c35ec65fc4
37 changed files with 3290 additions and 1012 deletions

View File

@@ -2,7 +2,8 @@
// across hooks (e.g. AI rename arriving via WS in the session view needs to
// also refresh the sidebar's session list).
import type { Project, Session } from '@/api/types';
import type { Chat, Project, Session } from '@/api/types';
import type { Attachment } from '@/lib/attachments';
export interface SessionRenamedEvent {
type: 'session_renamed';
@@ -51,6 +52,37 @@ export interface OpenFileInBrowserEvent {
path: string; // project-relative
}
export interface AttachChatFileEvent {
type: 'attach_chat_file';
attachment: Omit<Attachment, 'id'>;
}
export interface SessionArchivedEvent {
type: 'session_archived';
session_id: string;
project_id: string;
}
export interface ChatCreatedEvent {
type: 'chat_created';
chat: Chat;
session_id: string;
}
export interface ChatUpdatedEvent {
type: 'chat_updated';
chat_id: string;
session_id: string;
name: string | null;
updated_at: string;
}
export interface ChatClosedEvent {
type: 'chat_closed';
chat_id: string;
session_id: string;
}
export type SessionEvent =
| SessionRenamedEvent
| ProjectCreatedEvent
@@ -59,7 +91,12 @@ export type SessionEvent =
| SessionDeletedEvent
| SessionUpdatedEvent
| SessionLoadedEvent
| OpenFileInBrowserEvent;
| OpenFileInBrowserEvent
| AttachChatFileEvent
| SessionArchivedEvent
| ChatCreatedEvent
| ChatUpdatedEvent
| ChatClosedEvent;
type Listener = (event: SessionEvent) => void;
const listeners = new Set<Listener>();