web: React+Vite SPA — sessions, streaming chat, task panel, spawn flow (build clean)
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
// Typed mirror of PROTOCOL.md v1.
|
||||
|
||||
export const PROTOCOL_VERSION: 1 = 1;
|
||||
|
||||
/** Event types emitted by the plugin, carried in the envelope `type` field. */
|
||||
export const EventType = {
|
||||
Hello: "hello",
|
||||
MessageStart: "message_start",
|
||||
MessageUpdate: "message_update",
|
||||
MessageEnd: "message_end",
|
||||
ToolExecutionStart: "tool_execution_start",
|
||||
ToolExecutionUpdate: "tool_execution_update",
|
||||
ToolExecutionEnd: "tool_execution_end",
|
||||
AgentStart: "agent_start",
|
||||
AgentEnd: "agent_end",
|
||||
AgentSettled: "agent_settled",
|
||||
SessionInfo: "session_info",
|
||||
Bye: "bye",
|
||||
} as const;
|
||||
export type EventType = (typeof EventType)[keyof typeof EventType];
|
||||
|
||||
/** REST routes (base `/api`, bearer auth). */
|
||||
export const Route = {
|
||||
Sessions: "/api/sessions",
|
||||
SessionEvents: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/events`,
|
||||
SessionPrompt: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/prompt`,
|
||||
SessionAbort: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/abort`,
|
||||
SessionContainer: (id: string): string => `/api/sessions/${encodeURIComponent(id)}/container`,
|
||||
Spawn: "/api/spawn",
|
||||
SpawnStatus: "/api/spawn/status",
|
||||
GitlabStatus: "/api/gitlab/status",
|
||||
GitlabConnect: "/api/gitlab/connect",
|
||||
GitlabRepos: "/api/gitlab/repos",
|
||||
} as const;
|
||||
|
||||
/** Session snapshot, carried by `hello`/`session_info` and REST session list. */
|
||||
export interface SessionInfo {
|
||||
id: string;
|
||||
name: string | null;
|
||||
cwd: string;
|
||||
model: string;
|
||||
provider: string;
|
||||
/** true if spawned-by-daemon container session */
|
||||
agent: boolean;
|
||||
repo: string | null;
|
||||
startedAt: number;
|
||||
}
|
||||
|
||||
/** Session list row (REST `GET /api/sessions` + WS `session_list`). */
|
||||
export interface SessionListItem extends SessionInfo {
|
||||
online: boolean;
|
||||
lastEventAt: number | null;
|
||||
}
|
||||
|
||||
export type MessageRole = "user" | "assistant" | "toolResult" | "system";
|
||||
|
||||
export interface ToolCall {
|
||||
id: string;
|
||||
name: string;
|
||||
argsJson: string;
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
role: MessageRole;
|
||||
id: string;
|
||||
text: string;
|
||||
thinking: string | null;
|
||||
toolCalls: ToolCall[];
|
||||
/** toolResult messages: which call this answers */
|
||||
toolCallId: string | null;
|
||||
}
|
||||
|
||||
/** Persisted event envelope + flattened payload. */
|
||||
export interface EventFrame {
|
||||
v: 1;
|
||||
sessionId: string;
|
||||
/** monotonic per-session, plugin-assigned, starts at 1 */
|
||||
seq: number;
|
||||
/** unix ms */
|
||||
ts: number;
|
||||
type: EventType | string;
|
||||
// ---- payload fields (union, present depending on `type`) ----
|
||||
session?: SessionInfo;
|
||||
message?: Message;
|
||||
delta?: string;
|
||||
toolCallId?: string;
|
||||
toolName?: string;
|
||||
args?: string;
|
||||
partial?: string;
|
||||
isError?: boolean;
|
||||
resultPreview?: string;
|
||||
usage?: { inputTokens?: number; outputTokens?: number; totalCost?: number };
|
||||
reason?: string;
|
||||
}
|
||||
|
||||
/** Query params + response shapes for REST routes. */
|
||||
export interface PromptBody {
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface PromptResponse {
|
||||
ok: boolean;
|
||||
}
|
||||
|
||||
export interface AbortResponse {
|
||||
ok: boolean;
|
||||
}
|
||||
|
||||
export interface ContainerResponse {
|
||||
ok: boolean;
|
||||
}
|
||||
|
||||
export interface SpawnBody {
|
||||
repo: string;
|
||||
branch?: string;
|
||||
}
|
||||
|
||||
export interface SpawnResponse {
|
||||
sessionId: string;
|
||||
containerId: string;
|
||||
}
|
||||
|
||||
export interface SpawnJob {
|
||||
repo: string;
|
||||
state: string;
|
||||
containerId?: string;
|
||||
sessionId?: string;
|
||||
}
|
||||
|
||||
export interface GitlabStatus {
|
||||
connected: boolean;
|
||||
baseUrl: string;
|
||||
username?: string;
|
||||
}
|
||||
|
||||
export interface GitlabConnectResponse {
|
||||
username: string;
|
||||
}
|
||||
|
||||
export interface Repo {
|
||||
path: string;
|
||||
name: string;
|
||||
namespace: string;
|
||||
lastActivityAt: string;
|
||||
webUrl: string;
|
||||
defaultBranch: string;
|
||||
}
|
||||
|
||||
/** ---- WS transport 3 (browser → daemon) ---- */
|
||||
|
||||
export type ServerFrame =
|
||||
| { type: "session_list"; sessions: SessionListItem[] }
|
||||
| { type: "events"; sessionId: string; after: number; events: EventFrame[] }
|
||||
| { type: "spawn_status"; jobs: SpawnJob[] };
|
||||
|
||||
export type ClientFrame =
|
||||
| { type: "subscribe"; sessionId: string }
|
||||
| { type: "unsubscribe"; sessionId: string };
|
||||
Reference in New Issue
Block a user