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

@@ -6,7 +6,6 @@ import type { Sql } from '../db.js';
import type { Config } from '../config.js';
import type { Broker } from '../services/broker.js';
import type { Project, AvailableProject } from '../types/api.js';
import { requireUser } from '../auth.js';
import { resolveProjectRoot, PathScopeError } from '../services/path_guard.js';
import { listDir, viewFile } from '../services/file_ops.js';
import { getProjectFiles } from '../services/file_index.js';
@@ -77,7 +76,7 @@ export function registerProjectRoutes(
VALUES (${name}, ${resolved.real})
RETURNING id, name, path, added_at, last_session_id
`;
broker.publishUser(requireUser(req), { type: 'project_created', project: row as unknown as Project });
broker.publishUser('default', { type: 'project_created', project: row as unknown as Project });
reply.code(201);
return row;
} catch (err) {
@@ -96,7 +95,7 @@ export function registerProjectRoutes(
reply.code(404);
return { error: 'not found' };
}
broker.publishUser(requireUser(req), { type: 'project_deleted', project_id: id });
broker.publishUser('default', { type: 'project_deleted', project_id: id });
reply.code(204);
return null;
});