Scaffolda tunn vertikal slice: pnpm-monorepo (shared/daemon/server/web)
- shared: typat WebSocket-protokoll (daemon/server/web som enda sanning) - daemon: node-pty kör agenten (default gemini), strömmar pty över WS, auto-reconnect; fast pty-storlek - server: WS-mux + token-auth + session-registry + headless-xterm scrollback (SerializeAddon) + routing av input till rätt session - web: Vue 3 + Vite + xterm.js, session-lista, mobil-layout och fallback-tangentbord (piltangenter/Enter/Esc/Tab/Ctrl-C) som skickar escape-sekvenser rakt till pty:n -> styr sessionen även utan hooks - workspace: pnpm-workspace.yaml (onlyBuiltDependencies: node-pty, esbuild), tsconfig.base, .npmrc (retry-inställningar), .env.example Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
18
packages/shared/package.json
Normal file
18
packages/shared/package.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@agent-helm/shared",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc --noEmit -p tsconfig.json",
|
||||
"typecheck": "tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.7.0"
|
||||
}
|
||||
}
|
||||
125
packages/shared/src/index.ts
Normal file
125
packages/shared/src/index.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Delat WebSocket-protokoll mellan daemon, server och frontend.
|
||||
* Allt skickas som JSON-strängar. Typerna nedan är enda källan till sanning
|
||||
* för meddelandeformaten — importeras av alla tre paketen.
|
||||
*/
|
||||
|
||||
export type SessionStatus = "running" | "exited";
|
||||
|
||||
export interface SessionMeta {
|
||||
sessionId: string;
|
||||
title: string;
|
||||
status: SessionStatus;
|
||||
cols: number;
|
||||
rows: number;
|
||||
exitCode?: number;
|
||||
}
|
||||
|
||||
/* ----------------------------- Daemon -> Server ---------------------------- */
|
||||
|
||||
export interface DaemonHello {
|
||||
type: "daemon:hello";
|
||||
token: string;
|
||||
sessionId: string;
|
||||
title: string;
|
||||
cols: number;
|
||||
rows: number;
|
||||
}
|
||||
|
||||
export interface DaemonOutput {
|
||||
type: "daemon:output";
|
||||
/** Rå pty-output (utf8). */
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface DaemonExit {
|
||||
type: "daemon:exit";
|
||||
code: number;
|
||||
}
|
||||
|
||||
export type DaemonMessage = DaemonHello | DaemonOutput | DaemonExit;
|
||||
|
||||
/* ----------------------------- Server -> Daemon ---------------------------- */
|
||||
|
||||
export interface ServerInput {
|
||||
type: "server:input";
|
||||
/** Text eller escape-sekvenser som ska skrivas till pty:ns stdin. */
|
||||
data: string;
|
||||
}
|
||||
|
||||
export type ServerToDaemon = ServerInput;
|
||||
|
||||
/* ---------------------------- Frontend -> Server --------------------------- */
|
||||
|
||||
export interface WebHello {
|
||||
type: "web:hello";
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface WebSubscribe {
|
||||
type: "web:subscribe";
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
export interface WebInput {
|
||||
type: "web:input";
|
||||
sessionId: string;
|
||||
/** Text eller escape-sekvens (piltangenter, Enter, Ctrl-C ...). */
|
||||
data: string;
|
||||
}
|
||||
|
||||
export type WebMessage = WebHello | WebSubscribe | WebInput;
|
||||
|
||||
/* ---------------------------- Server -> Frontend --------------------------- */
|
||||
|
||||
export interface ServerWelcome {
|
||||
type: "server:welcome";
|
||||
}
|
||||
|
||||
export interface ServerSessions {
|
||||
type: "server:sessions";
|
||||
sessions: SessionMeta[];
|
||||
}
|
||||
|
||||
export interface ServerSnapshot {
|
||||
type: "server:snapshot";
|
||||
sessionId: string;
|
||||
/** Serialiserad terminal-state (scrollback) så en ny klient ser var den är. */
|
||||
data: string;
|
||||
meta: SessionMeta;
|
||||
}
|
||||
|
||||
export interface ServerOutput {
|
||||
type: "server:output";
|
||||
sessionId: string;
|
||||
data: string;
|
||||
}
|
||||
|
||||
export interface ServerSessionExit {
|
||||
type: "server:exit";
|
||||
sessionId: string;
|
||||
code: number;
|
||||
}
|
||||
|
||||
export interface ServerError {
|
||||
type: "server:error";
|
||||
message: string;
|
||||
}
|
||||
|
||||
export type ServerToWeb =
|
||||
| ServerWelcome
|
||||
| ServerSessions
|
||||
| ServerSnapshot
|
||||
| ServerOutput
|
||||
| ServerSessionExit
|
||||
| ServerError;
|
||||
|
||||
/* --------------------------------- Helpers --------------------------------- */
|
||||
|
||||
export function parseMessage<T>(raw: string): T | null {
|
||||
try {
|
||||
return JSON.parse(raw) as T;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
8
packages/shared/tsconfig.json
Normal file
8
packages/shared/tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2022"],
|
||||
"types": []
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user