framework
Version:
The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.
41 lines • 2.33 kB
TypeScript
import { type IncomingMessage, type ServerResponse } from 'node:http';
/**
* The dashboard's route to an agent's browser preview (#813).
*
* The bridge itself lives in the agent (#802) on a port the OS picks per agent. The dashboard is a
* different origin, on the daemon's port, so it cannot post to that bridge directly: a JSON POST
* would need a CORS preflight, and answering it would mean letting browser origins reach the
* bridge — giving up exactly the containment #802 paid for by keeping Chrome's debug port
* unreachable from the web.
*
* So the daemon proxies. The pane talks same-origin to the daemon, the daemon talks to loopback,
* and the agent's port is never named by the client: it comes from the agent's own meta. A caller
* cannot point this at an arbitrary port, which is what keeps it from being an open relay into
* anything else listening on loopback.
*/
/** Where a proxied request is headed, once the URL has been understood. */
export interface BrowserRoute {
projectId: string;
agentId: string;
/** `stream` renders in an `<img>`; `input` carries a click or a key back. */
leg: 'stream' | 'input';
}
/** The prefix the dashboard client posts to. */
export declare const BROWSER_PROXY_PREFIX = "/browser";
/**
* Parse `/browser/<projectId>/<agentId>/stream|input`, or undefined for anything else — an
* unrecognized shape must fall through to the bundle rather than be guessed at. Ids are taken
* verbatim and only ever used to look an agent up, never as a path.
*/
export declare function parseBrowserRoute(url: string | undefined): BrowserRoute | undefined;
/** How the proxy finds the agent's bridge. Injectable so a test needs no registry and no run. */
export type BrowserPortLookup = (projectId: string, agentId: string) => Promise<number | undefined>;
/**
* Proxy one request to the agent's bridge. Returns false when the URL is not a browser route, so
* the dashboard server can carry on to the client bundle.
*
* Streams both ways rather than buffering: `/stream` is an endless `multipart/x-mixed-replace`
* body, so anything that waits for it to finish never answers.
*/
export declare function handleBrowserProxy(req: IncomingMessage, res: ServerResponse, lookup?: BrowserPortLookup): Promise<boolean>;
//# sourceMappingURL=browser-proxy.d.ts.map