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.
116 lines • 6.21 kB
TypeScript
import { type PreferencesStore } from '../registry.js';
import type { DiscordCredentialsStore } from '../discord-credentials.js';
import { type QuotaSource } from './quota.js';
import type { AutoPmReporter } from '../auto-pm.js';
import type { ProjectErrorsReader } from '../project-errors.js';
import type { AddProjectResult, StartAgentKind, StartAgentOptions, StartAgentResult } from './types.js';
import type { EventsSource, RemoteAgents } from './rpc-serve.js';
/** Options for {@link startDashboard}. */
export interface DashboardOptions {
/** Port to bind. Default `4200`; pass `0` for an ephemeral port. */
port?: number;
/** Host to bind. Default `127.0.0.1` (localhost only). */
host?: string;
/**
* Called when the browser starts a session (#345): the `sendStart` RPC reaches this through the
* wired dashboard context. Wire it to spawn the session; return `busy: true` to refuse because
* one is already active.
*/
onStart: (prompt: string, kind: StartAgentKind, options: StartAgentOptions, projectId?: string) => StartAgentResult | Promise<StartAgentResult>;
/**
* Called when the browser adds a project (#396): the `sendAddProject` RPC reaches this through
* the wired dashboard context. Wire it to install the repo (or every git repo under a
* directory) and register it.
*/
onAddProject: (path: string, directory: boolean) => Promise<AddProjectResult> | AddProjectResult;
/**
* The user-preferences store (#410): the `onPreferences` / `savePreferences` RPCs read and
* write it through the wired dashboard context.
*/
preferences: PreferencesStore;
/**
* The Discord credentials store (#1095): `onNotifyChannels` reports what it holds and
* `saveDiscordCredentials` writes through it. The daemon passes one that also reloads its
* Discord services, so a pasted token takes effect with no restart.
*/
discord: DiscordCredentialsStore;
/** Where the usage panel reads the quota from (#533). */
quota: QuotaSource;
/** What auto PM last decided (#1161), for the line under the panel's toggle. */
autoPm: AutoPmReporter;
/**
* Fire an auto PM sweep now instead of waiting out the interval (#1210). Resolves when the
* sweep does (#1433), so the trigger RPC can await it.
*/
autoPmSweep: (opts?: {
drainOnly?: boolean;
}) => void | Promise<void>;
/** What a project currently suffers from (#1500), for the project list to carry. */
projectErrors: ProjectErrorsReader;
/**
* Serve the new dashboard bundle (#405) from this directory — the built SPA
* (`index.html` + `assets/**`). The daemon also mounts the dashboard's RPC surface
* at `/_rpc` (the calls + the live-event stream). Omit only for a broken install with
* no built bundle, where the server reports the bundle is missing.
*/
clientBundleDir?: string;
/**
* The shared token that guards a non-loopback bind (#1051): with it set, every route (static
* bundle, `/_rpc`, `/browser`, `/_relay`) needs a valid `fw_daemon` cookie or a matching
* `?token=`, else 401. Omit for a loopback bind, where the guard is a no-op and local UX is
* byte-identical. A separate concern from the CSRF origin check in rpc-serve.ts.
*/
token?: string;
/**
* The live-events source for a session this daemon is relaying from a connected device (#1067):
* a stream for such a session, else undefined so `onEvents` tails the on-disk log.
*/
eventsSource: EventsSource;
/**
* The relayed-agent lookup the read RPCs consult (#1067 slice 2). A run-scoped RPC uses it to
* forward a remote agent's read/steer/handoff to the device that owns it.
*/
remote: RemoteAgents;
/**
* Serve a relay-started agent's events back to the daemon that relayed it here (#1067): the
* `/_relay/*` endpoints (start + events, plus the slice-2 `rpc`). All are fronted by the same
* `token` guard above, so a device without the cookie cannot start or read an agent.
*/
relay?: {
tailEvents: (agentId: string, onEvent: (event: import('../events.js').FrameworkEvent) => void) => () => void;
/** Run one whitelisted run-scoped RPC against this daemon's own checkout (#1067 slice 2). */
rpc?: (fn: string, args: unknown[]) => Promise<unknown>;
};
/**
* The browser bridge (#1237): the token a Claude web extension presents to report the question
* its cloud session is parked on. Absent leaves every `/_bridge/*` route 404, which is default.
*
* Deliberately not {@link token}. That one guards a non-loopback bind and is absent on a normal
* loopback daemon, where what keeps other origins out of `/_rpc` is the same-origin check.
* The bridge is the one route meant to be reached from another origin, so neither protects it
* and it authenticates on its own.
*/
bridgeToken?: string;
/**
* The cloud sessions the browser bridge should have a tab open for (#1237). Only the daemon
* wires one, since it is the process that can see every project's runs.
*/
bridgeSessions?: () => Promise<import('./bridge-endpoints.js').BridgeSession[]>;
}
/** A running localhost dashboard: the built SPA + its RPC mount. */
export interface Dashboard {
/** The URL to open. */
readonly url: string;
/** Stop the server. Idempotent. */
close(): Promise<void>;
}
/**
* Start the localhost dashboard: a tiny `node:http` server that serves the built SPA (#405) and
* mounts its RPC surface at `/_rpc` — the calls and the live-event stream. The dashboard reads the
* agent's `.the-framework/events.jsonl` over that stream and steers it through `control.jsonl`, so
* there is no in-process event stream here; the server is a static-bundle + RPC host. The RPCs run
* in the daemon's own process, so `sendStart` / `sendAddProject` call the daemon's own closures via
* {@link DashboardOptions.onStart} / {@link DashboardOptions.onAddProject}.
*/
export declare function startDashboard(opts: DashboardOptions): Promise<Dashboard>;
//# sourceMappingURL=server.d.ts.map