/** * Contracts Route * * GET /contracts/actions.public.json - Public action contracts from all plugins */ import { Hono } from "hono"; import type { ActionContract, ActionDefinition } from "@gizmo-ai/runtime"; import type { ErrorResponse } from "../types.ts"; /** * Public contract format (filtered view of ActionContract) */ export interface PublicContract { pluginKey: string; stateKey?: string; version: string; emits: ActionDefinition[]; listensTo: ActionContract["listensTo"]; accepts: string[]; } /** * Response format for /contracts/actions.public.json */ export interface PublicContractsResponse { schemaVersion: string; contracts: PublicContract[]; } export interface ContractsRouteConfig { /** List of contracts from installed plugins */ contracts: ActionContract[]; } /** * Create the contracts route * * Serves public action contracts for discovery and documentation. */ export function createContractsRoute(config: ContractsRouteConfig): Hono { const { contracts } = config; const app = new Hono(); // GET /actions.public.json - Public contracts from all plugins app.get("/actions.public.json", (c) => { try { const publicContracts: PublicContract[] = contracts.map((contract) => ({ pluginKey: contract.pluginKey, stateKey: contract.stateKey, version: contract.pluginVersion, emits: contract.emits.filter((a) => a.visibility === "public"), listensTo: contract.listensTo, accepts: contract.accepts, })); c.header("Content-Type", "application/json"); c.header("Cache-Control", "public, max-age=300"); // Cache 5 minutes return c.json({ schemaVersion: "1.0.0", contracts: publicContracts, }); } catch (error) { return c.json( { error: `Failed to generate contracts: ${ error instanceof Error ? error.message : String(error) }`, }, 500 ); } }); return app; }