Claude Code engine, image viewer, colour tags, checks per turn and more
- Claude Code as an engine: chats on a "claude-code/<alias>" model run through the claude CLI (stream-json); tool approvals go through our permission system. Sign in from the web UI (URL + pasted code), CLI version and update from Settings; the Docker image contains the CLI. - Small models (8k context) for side tasks: input is cut to the model's context window; one-line chat status, "What does this do?" on approvals, "Plan as automation" (job draft from a chat). - Mobile: top bar no longer widens the page, image viewer (zoom, swipe, mark up, use in message), jump to previous own message, message menu, time under every message. - Approvals: push actions (allow/reject), "always allow in this project" (never for dangerous commands) with revoke. - Per turn: changed files with diffs and rollback; project check command with a green/red badge and "let the agent fix it". - Colour tags for chats in the colours of the active theme. - Project defaults for new chats, project page (timeline), offline queue. Tested in a throwaway container with a mock model (8k small model): 26 API checks passed (permissions, diffs, checks, defaults, job draft, side-task budget, Claude Code status/login URL, unsigned-in chat). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
084452abf6
commit
62fe5bf467
42 files changed
+3734
-55
No files matched your search
@@ -9,6 +9,7 @@ import type {
|
||||
PermissionRequest,
|
||||
QuestionRequest,
|
||||
ServerEvent,
|
||||
TurnCheckInfo,
|
||||
Session,
|
||||
} from "./types";
|
||||
|
||||
@@ -51,6 +52,8 @@ export interface State {
|
||||
waiting: Record<string, string | undefined>;
|
||||
/** Compaction running in a session (auto = context nearly full). */
|
||||
compacting: Record<string, { auto: boolean; tokens: number | null; limit: number | null; since: number } | undefined>;
|
||||
/** Check results per session, by the id of the turn's last answer. */
|
||||
checks: Record<string, Record<string, TurnCheckInfo> | undefined>;
|
||||
}
|
||||
|
||||
let state: State = {
|
||||
@@ -73,6 +76,7 @@ let state: State = {
|
||||
steps: {},
|
||||
waiting: {},
|
||||
compacting: {},
|
||||
checks: {},
|
||||
};
|
||||
|
||||
const listeners = new Set<() => void>();
|
||||
@@ -203,6 +207,11 @@ export function applyEvent(ev: ServerEvent) {
|
||||
},
|
||||
}));
|
||||
break;
|
||||
case "check_result": {
|
||||
const info: TurnCheckInfo = { message_id: ev.message_id, status: ev.status, exit_code: ev.exit_code, duration_ms: ev.duration_ms, output: ev.output };
|
||||
setState((s) => ({ checks: { ...s.checks, [ev.session_id]: { ...s.checks[ev.session_id], [ev.message_id]: info } } }));
|
||||
break;
|
||||
}
|
||||
case "mcp_status":
|
||||
setState(() => ({ mcp: ev.servers }));
|
||||
break;
|
||||
@@ -259,6 +268,12 @@ export async function loadSession(id: string) {
|
||||
}));
|
||||
}
|
||||
|
||||
/** Check results of a chat (badges on its turns). */
|
||||
export async function loadChecks(id: string) {
|
||||
const list = await get<TurnCheckInfo[]>(`/sessions/${id}/checks`).catch(() => [] as TurnCheckInfo[]);
|
||||
setState((s) => ({ checks: { ...s.checks, [id]: { ...Object.fromEntries(list.map((c) => [c.message_id, c])), ...s.checks[id] } } }));
|
||||
}
|
||||
|
||||
/** Older messages before the loaded ones (scrolling up). Returns how many came. */
|
||||
export async function loadOlder(id: string, stopAtSummary = true): Promise<number> {
|
||||
const first = getState().messages[id]?.[0];
|
||||
|
||||
Reference in new issue
Block a user