batch3 T1: session_panes schema + Pane/UserStreamFrame types + sidebar project_id
Adds the session_panes table, Pane/PaneState/PaneCreate/PaneUpdate types, UserStreamFrame discriminated union, and extends SidebarSession with project_id (also added to the sidebar SELECT). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -18,7 +18,7 @@ export function registerSidebarRoutes(app: FastifyInstance, sql: Sql): void {
|
||||
projects.map(async (p) => {
|
||||
const [recent_sessions, countRows] = await Promise.all([
|
||||
sql<SidebarSession[]>`
|
||||
SELECT id, name, model, updated_at
|
||||
SELECT id, project_id, name, model, updated_at
|
||||
FROM sessions
|
||||
WHERE project_id = ${p.id}
|
||||
ORDER BY updated_at DESC
|
||||
|
||||
@@ -46,3 +46,14 @@ CREATE TABLE IF NOT EXISTS settings (
|
||||
);
|
||||
|
||||
INSERT INTO settings (key, value) VALUES ('default_model', '"qwen3.6-35b-a3b-mxfp4"') ON CONFLICT (key) DO NOTHING;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS session_panes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
|
||||
position INTEGER NOT NULL,
|
||||
kind TEXT NOT NULL CHECK (kind IN ('chat', 'file_browser')),
|
||||
state JSONB NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
|
||||
UNIQUE (session_id, position)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS session_panes_session_idx ON session_panes (session_id);
|
||||
|
||||
@@ -61,6 +61,7 @@ export interface ModelInfo {
|
||||
|
||||
export interface SidebarSession {
|
||||
id: string;
|
||||
project_id: string;
|
||||
name: string;
|
||||
model: string;
|
||||
updated_at: string;
|
||||
@@ -76,3 +77,68 @@ export interface SidebarProject {
|
||||
export interface SidebarResponse {
|
||||
projects: SidebarProject[];
|
||||
}
|
||||
|
||||
export type PaneKind = 'chat' | 'file_browser';
|
||||
|
||||
export interface FileBrowserPaneState {
|
||||
open_file?: string | null;
|
||||
filter?: string;
|
||||
expanded_dirs?: string[];
|
||||
}
|
||||
|
||||
// chat panes have no state for now
|
||||
export type ChatPaneState = Record<string, never>;
|
||||
|
||||
export type PaneState = ChatPaneState | FileBrowserPaneState;
|
||||
|
||||
export interface Pane {
|
||||
id: string;
|
||||
session_id: string;
|
||||
position: number;
|
||||
kind: PaneKind;
|
||||
state: PaneState;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface PaneCreateRequest {
|
||||
kind: PaneKind;
|
||||
position?: number; // optional; if omitted, append at end
|
||||
}
|
||||
|
||||
export interface PaneUpdateRequest {
|
||||
state?: PaneState;
|
||||
position?: number;
|
||||
}
|
||||
|
||||
// User-stream frames (broadcast on /ws/user channel)
|
||||
export interface ProjectCreatedFrame {
|
||||
type: 'project_created';
|
||||
project: Project;
|
||||
}
|
||||
export interface ProjectDeletedFrame {
|
||||
type: 'project_deleted';
|
||||
project_id: string;
|
||||
}
|
||||
export interface SessionCreatedFrame {
|
||||
type: 'session_created';
|
||||
session: Session;
|
||||
project_id: string;
|
||||
}
|
||||
export interface SessionDeletedFrame {
|
||||
type: 'session_deleted';
|
||||
session_id: string;
|
||||
project_id: string;
|
||||
}
|
||||
export interface SessionUpdatedFrame {
|
||||
type: 'session_updated';
|
||||
session_id: string;
|
||||
project_id: string;
|
||||
name: string;
|
||||
updated_at: string;
|
||||
}
|
||||
export type UserStreamFrame =
|
||||
| ProjectCreatedFrame
|
||||
| ProjectDeletedFrame
|
||||
| SessionCreatedFrame
|
||||
| SessionDeletedFrame
|
||||
| SessionUpdatedFrame;
|
||||
|
||||
Reference in New Issue
Block a user