import { type Router as ExpressRouter } from "express"; import type { StudioRailLaunchEdgesResponse } from "../shared/types.js"; export declare const STUDIO_RAIL_FILE = "studio-rail.json"; /** * A stored arrangement is a handful of ids, labels and absolute paths. The cap * is a backstop against a client (or a hand edit) turning a preferences file * into a place to park a megabyte, not a real limit on how many groups a * project may have. */ export declare const MAX_STUDIO_RAIL_BYTES: number; export interface StudioRailDeps { /** * Every project root the studio knows about — recentDirs, the configured * project root, and the cwd of every live session. The client's project rows * come from the same three sources, so a root that can be shown is a root * that can be written to, and nothing else is. */ listKnownRoots: () => string[] | Promise; /** * The registered agents whose sources are scanned for launch calls. A call's * target need not be registered: the client joins detected target slugs to * its own project membership and ignores unmatched edges. */ listWorkflows: () => Array<{ name: string; path: string; }>; } /** `/.sapiom/studio-rail.json`, or null if that escapes `root`. */ export declare function studioRailPath(root: string): string | null; /** * The stored blob, or null. * * An absent file, an unreadable directory and an oversized file all read as * null — "nothing stored", which the model turns into the derived groups. A * rail that throws on a bad preferences file is a rail you cannot open in order * to fix it. */ export declare function readStudioRailFile(root: string): Promise; /** Writes the blob verbatim, creating `.sapiom/` if it is not there yet. */ export declare function writeStudioRailFile(root: string, raw: string): Promise; /** * Removes the file. Missing is success: "there is no stored arrangement" is the * requested end state, and DELETE is how an un-materialized state — including * the one `Reset to detected` produces — reaches disk. Skipping the write * instead would let the old arrangement outlive the reset. */ export declare function removeStudioRailFile(root: string): Promise; /** * Launch edges across every registered agent, as parent-name to child-slug. * * Uses the shared syntax-only extractor (`@sapiom/mcp/map`) — * the same detector the canvas and system graph use for direct agent invocations. A * second edge detector would be a second answer to "what does this launch", * and the Group axis and system graph are supposed to read one graph. * * `knownStepIds` is empty on purpose: that argument exists so a capability chip * can be attributed to the step it sits in, and a group does not care which * step launched the child, only that the launch exists. * * `child` is the `definition` slug as written at the call site. Matching it to * an agent is the client's job (a slug can name an agent by `definitionSlug` or * by folder name); the client ignores an unmatched slug. */ export declare function detectLaunchEdges(workflows: ReadonlyArray<{ name: string; path: string; }>): Promise; /** * GET /api/studio-rail?root=abs -> { root, raw: string | null } * PUT /api/studio-rail?root=abs { raw } -> { ok: true } * DELETE /api/studio-rail?root=abs -> { ok: true } * GET /api/studio-rail/launch-edges -> { edges: [{ parent, child }] } */ export declare function createStudioRailRouter(deps: StudioRailDeps): ExpressRouter; //# sourceMappingURL=studio-rail.d.ts.map