/** * template-catalog — the Studio's template gallery, read from the Sapiom CORE * surface so it can never disagree with the dashboard's Template library. * * WHY this replaced a hardcoded list: the Studio used to ship a pinned copy of * two registry entries (`web/src/lib/templates.ts`, pinned at harness 0.1.4 / * f0e3406) because — as that module's header said — "no listing API, MCP tool, * or CLI command exposes the gallery to any client today". That is no longer * true: core serves `GET /v1/workflows/templates` and * `GET /v1/workflows/templates/:id`, which is exactly what the dashboard's * gallery renders. Reading the same endpoint is what keeps the two surfaces from * drifting; re-deriving the list from `registry.json` would just recreate the * drift with extra steps (core also merges each example's `template.json` and * derives the complexity band from the declared shape). * * Two non-obvious contract details, both verified against a local backend: * * - **The core surface authenticates with `Authorization: Bearer`, NOT the * `x-sapiom-api-key` header the AGENTS surface takes.** The same key sent as * `x-sapiom-api-key` to `/v1/workflows/templates` returns 401. Don't copy the * header from `run-state.ts` / `definition-slug-resolver.ts` — those talk to * `tools.*`, this talks to `api.*`. * - **The path is prefixed `/v1`** (the backend's `GLOBAL_API_PREFIX`); a bare * `/workflows/templates` 404s. * * The key stays server-side and is never forwarded to the browser (same rule as * the runs router). A 401/403 triggers exactly one credential refresh + retry, * mirroring `run-state.ts`, so a rotated key recovers in place. */ import type { TemplateDetailView, TemplateListResponse } from "../shared/types.js"; import { type ApiKeyProvider } from "./api-key-provider.js"; export interface TemplateCatalog { /** The gallery list. Never throws: falls back to `source: "fallback"` with an * empty list when signed out or core is unreachable, so the dialog can say * what happened instead of rendering silence. */ list(): Promise; /** One template's detail, or null when the id is unknown / unreachable. */ detail(id: string): Promise; } export declare function createTemplateCatalog(opts: { /** Accepts a provider (preferred — enables refresh-on-401) or a bare key. */ apiKey: string | null | ApiKeyProvider; /** Override the core base URL (resolved from env by default). Test seam. */ baseUrl?: string; /** Injectable fetch. Test seam, mirroring the resolver suite. */ fetchImpl?: typeof fetch; }): TemplateCatalog; //# sourceMappingURL=template-catalog.d.ts.map