import { LocalSource, RemoteSource, HubSource, type ShardSource, } from "./source"; // A serializable description of a data source — the shape we persist, pass to // use_source, and rebuild a live ShardSource from. `sites` on a hub spec is a // subset allowlist of member siteIds (undefined = federate every member). export type SourceSpec = | { kind: "hub"; url: string; sites?: string[] } | { kind: "remote"; url: string } | { kind: "local"; dir: string }; // Resolve the data-source spec from flags or env. Precedence: hub > remote > // local > positional > default. All logging goes to stderr — stdout is the MCP // JSON-RPC channel and must not be polluted. // // --hub | TRANSCRIPT_HUB_URL federate over a hub's member sites // --remote | TRANSCRIPT_SITE_URL one deployed site origin // --local | TRANSCRIPT_LOCAL_DIR a composed public dir on disk // an http(s) URL → remote, otherwise a local dir // (default) ./export/public export function resolveSourceSpec(argv: string[]): SourceSpec { const flag = (name: string): string | undefined => { const i = argv.indexOf(name); return i >= 0 && i + 1 < argv.length ? argv[i + 1] : undefined; }; const hub = flag("--hub") ?? process.env.TRANSCRIPT_HUB_URL; if (hub) return { kind: "hub", url: hub }; const remote = flag("--remote") ?? flag("--url") ?? process.env.TRANSCRIPT_SITE_URL; if (remote) return { kind: "remote", url: remote }; const local = flag("--local") ?? process.env.TRANSCRIPT_LOCAL_DIR; if (local) return { kind: "local", dir: local }; const positional = argv.find((a) => !a.startsWith("-")); if (positional) { return /^https?:\/\//i.test(positional) ? { kind: "remote", url: positional } : { kind: "local", dir: positional }; } return { kind: "local", dir: "export/public" }; } // Build a live ShardSource from a spec. export function buildSource(spec: SourceSpec): ShardSource { switch (spec.kind) { case "hub": return new HubSource(spec.url, spec.sites); case "remote": return new RemoteSource(spec.url); case "local": return new LocalSource(spec.dir); } } // Thin compatibility wrapper: resolve a spec and build it in one call. export function resolveSource(argv: string[]): ShardSource { return buildSource(resolveSourceSpec(argv)); }