cograph 0.1.25 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/agentRender.ts"],"sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { extname } from \"node:path\";\nimport { readConfig } from \"./config.js\";\n\nexport class CographError extends Error {\n status?: number;\n body?: string;\n\n constructor(message: string, opts?: { status?: number; body?: string }) {\n super(message);\n this.name = \"CographError\";\n this.status = opts?.status;\n this.body = opts?.body;\n }\n}\n\nexport interface ClientOptions {\n apiKey?: string;\n baseUrl?: string;\n tenant?: string;\n}\n\nexport interface IngestOptions {\n kg?: string;\n contentType?: \"text\" | \"csv\" | \"json\" | string;\n /** Rows per batch for CSV ingest. Default 200. Larger = fewer round-trips\n * but higher per-request memory; 200 is a good balance for typical KGs. */\n batchSize?: number;\n /** Max number of batches in flight at once. Default 4. Higher saturates\n * the backend faster but risks 429s on large ingests. */\n concurrency?: number;\n /** Called after each batch completes during CSV ingest, in batch order.\n * Use for progress UI. Not invoked for text/json ingest. */\n onProgress?: (progress: IngestProgress) => void;\n /** CSV only. Called once after schema inference and BEFORE any rows are\n * written, with the inferred mapping. Return the (possibly edited/approved)\n * mapping to ingest, or `null` to cancel without writing anything. When\n * omitted the inferred mapping is applied as-is (non-interactive). This is\n * the same confirm/override gate the Explorer surfaces in its review step. */\n onSchemaInferred?: (\n mapping: Record<string, unknown>,\n info: { totalRows: number; rowsProfiled: number },\n ) => Promise<Record<string, unknown> | null>;\n}\n\nexport interface IngestProgress {\n rowsProcessed: number;\n totalRows: number;\n entitiesResolved: number;\n triplesInserted: number;\n}\n\n/** Rows sent to schema inference. Profile fidelity = decision quality, so we\n * send the whole file up to this cap, evenly strided across it (never the\n * head — head-of-file bias is exactly what evidence-grounded inference fixes).\n * Matches the Explorer's SCHEMA_SAMPLE_CAP. */\nexport const SCHEMA_SAMPLE_CAP = 5000;\n\nfunction stridedSample<T>(rows: T[], cap: number = SCHEMA_SAMPLE_CAP): T[] {\n if (rows.length <= cap) return rows;\n const out: T[] = [];\n for (let i = 0; i < cap; i++) out.push(rows[Math.floor((i * rows.length) / cap)]!);\n return out;\n}\n\nexport interface AskOptions {\n kg?: string;\n model?: string;\n}\n\nfunction envVar(name: string, fallback?: string): string | undefined {\n // Prefer COGRAPH_, fall back to OMNIX_ so old configs keep working.\n return (\n process.env[`COGRAPH_${name}`] ||\n process.env[`OMNIX_${name}`] ||\n fallback\n );\n}\n\nconst EXT_FORMAT: Record<string, string> = {\n \".csv\": \"csv\",\n \".json\": \"json\",\n \".jsonl\": \"json\",\n \".txt\": \"text\",\n};\n\n/**\n * Parse a CSV string into an array of row objects.\n *\n * Minimal RFC-4180-ish parser: handles quoted fields with commas, escaped\n * quotes (`\"\"`), CRLF/LF line endings. Does not handle BOM stripping or\n * encoding detection — we assume UTF-8 text in.\n */\nexport function parseCsv(content: string): Record<string, string>[] {\n const rows: string[][] = [];\n let cur: string[] = [];\n let field = \"\";\n let inQuotes = false;\n\n for (let i = 0; i < content.length; i++) {\n const ch = content[i];\n if (inQuotes) {\n if (ch === '\"') {\n if (content[i + 1] === '\"') {\n field += '\"';\n i++;\n } else {\n inQuotes = false;\n }\n } else {\n field += ch;\n }\n } else {\n if (ch === '\"') {\n inQuotes = true;\n } else if (ch === \",\") {\n cur.push(field);\n field = \"\";\n } else if (ch === \"\\n\") {\n cur.push(field);\n rows.push(cur);\n cur = [];\n field = \"\";\n } else if (ch === \"\\r\") {\n // swallow; handled by the following \\n in CRLF, or treat lone \\r as line end\n if (content[i + 1] !== \"\\n\") {\n cur.push(field);\n rows.push(cur);\n cur = [];\n field = \"\";\n }\n } else {\n field += ch;\n }\n }\n }\n // flush trailing field/row\n if (field.length > 0 || cur.length > 0) {\n cur.push(field);\n rows.push(cur);\n }\n\n if (rows.length === 0) return [];\n const headers = rows[0]!.map((h) => h.trim());\n const out: Record<string, string>[] = [];\n for (let r = 1; r < rows.length; r++) {\n const row = rows[r]!;\n // skip blank trailing lines\n if (row.length === 1 && row[0] === \"\") continue;\n const obj: Record<string, string> = {};\n for (let c = 0; c < headers.length; c++) {\n obj[headers[c]!] = row[c] ?? \"\";\n }\n out.push(obj);\n }\n return out;\n}\n\nexport class Client {\n apiKey: string | undefined;\n baseUrl: string;\n tenant: string;\n\n /**\n * Raw / passthrough API — one method per canonical backend operation, with\n * the path encoded inside the SDK. Each method returns the backend\n * {@link Response} VERBATIM: it does NOT throw on non-2xx and does NOT reshape\n * the body. This is the seam the webapp's proxy layer adopts so per-operation\n * paths live in one place (here) instead of being hand-rolled at each call\n * site. See {@link RawApi}. The typed methods on this class (which throw on\n * non-2xx and reshape some payloads) are left unchanged — this is additive.\n */\n readonly raw: RawApi;\n\n constructor(opts: ClientOptions = {}) {\n // Resolution order for each field: explicit opts → env var → ~/.cograph/config.json\n // (written by `cograph login`) → built-in default. Reading the config eagerly\n // is cheap (small JSON file) and lets users skip env vars entirely after login.\n const cfg = readConfig();\n this.apiKey = opts.apiKey ?? envVar(\"API_KEY\") ?? cfg.apiKey;\n const url =\n opts.baseUrl ?? envVar(\"API_URL\") ?? cfg.apiUrl ?? \"https://api.cograph.cloud\";\n this.baseUrl = url.replace(/\\/+$/, \"\");\n this.tenant = opts.tenant ?? envVar(\"TENANT\") ?? cfg.tenant ?? \"demo-tenant\";\n this.raw = new RawApi(this);\n }\n\n private headers(): Record<string, string> {\n const h: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (this.apiKey) h[\"X-API-Key\"] = this.apiKey;\n return h;\n }\n\n private base(): string {\n return `${this.baseUrl}/graphs/${this.tenant}`;\n }\n\n // --- Path builders -------------------------------------------------------- #\n // SINGLE source of truth for every canonical backend path. Both the raw API\n // and the new typed parsed methods build URLs through these, so a path lives\n // in exactly one place. Tenant-scoped paths hang off `base()`\n // (`{baseUrl}/graphs/{tenant}`); the handful of account-level paths\n // (e.g. tenant CRUD) hang off `baseUrl` directly.\n //\n // These are marked `@internal` (not part of the public SDK surface) but are\n // not `private`, so the sibling {@link RawApi} can build the same canonical\n // paths without duplicating them.\n\n /** @internal */\n pAgent(): string {\n return `${this.base()}/agent`;\n }\n /** @internal */ pAsk(): string {\n return `${this.base()}/ask`;\n }\n /** @internal */ pIngest(): string {\n return `${this.base()}/ingest`;\n }\n /** @internal */ pIngestCsvSchema(): string {\n return `${this.base()}/ingest/csv/schema`;\n }\n /** @internal */ pIngestCsvRows(): string {\n return `${this.base()}/ingest/csv/rows`;\n }\n /** @internal */ pEnrichJobs(): string {\n return `${this.base()}/enrich/jobs`;\n }\n /** @internal */ pEnrichJob(jobId: string): string {\n return `${this.base()}/enrich/jobs/${encodeURIComponent(jobId)}`;\n }\n /** @internal */ pEnrichJobConflicts(jobId: string): string {\n return `${this.pEnrichJob(jobId)}/conflicts`;\n }\n /** @internal */ pEnrichJobApply(jobId: string): string {\n return `${this.pEnrichJob(jobId)}/apply`;\n }\n /** @internal */ pOntologyTypes(): string {\n return `${this.base()}/ontology/types`;\n }\n /** @internal */ pOntologyResolve(): string {\n return `${this.base()}/ontology/resolve`;\n }\n /** @internal Targets the premium ontology-recommender route, mounted only on\n * deployments with the proprietary layer — 404s on bare OSS. */\n pOntologyRecommend(): string {\n return `${this.base()}/ontology/recommend`;\n }\n /** @internal */ pOntologyApply(): string {\n return `${this.base()}/ontology/apply`;\n }\n /** @internal */ pKgs(): string {\n return `${this.base()}/kgs`;\n }\n /** @internal */ pKg(name: string): string {\n return `${this.base()}/kgs/${encodeURIComponent(name)}`;\n }\n /** @internal */ pTypeCounts(kg: string): string {\n return `${this.pKg(kg)}/type-counts`;\n }\n /** @internal */ pExploreSummary(kg: string, typeName: string): string {\n return `${this.base()}/explore/kgs/${encodeURIComponent(kg)}/types/${encodeURIComponent(typeName)}/summary`;\n }\n /** @internal */ pExploreRecords(kg: string, typeName: string, query?: string): string {\n return `${this.base()}/explore/kgs/${encodeURIComponent(kg)}/types/${encodeURIComponent(typeName)}/records${query ?? \"\"}`;\n }\n /** @internal */ pExploreTypeEdges(kg: string): string {\n return `${this.base()}/explore/kgs/${encodeURIComponent(kg)}/type-edges`;\n }\n /** @internal */ pExploreSearch(query: string): string {\n return `${this.base()}/explore/search${query}`;\n }\n /** @internal */ pNormalizeSuggest(query: string): string {\n return `${this.base()}/normalize/suggest${query}`;\n }\n /** @internal */ pNormalizeRules(query?: string): string {\n return `${this.base()}/normalize/rules${query ?? \"\"}`;\n }\n /** @internal */ pNormalizeRule(ruleId: string, action: \"confirm\" | \"reject\" | \"apply\"): string {\n return `${this.base()}/normalize/rules/${encodeURIComponent(ruleId)}/${action}`;\n }\n /** @internal */ pTenants(): string {\n return `${this.baseUrl}/v1/me/tenants`;\n }\n /** @internal */ pTenant(tenantId: string): string {\n return `${this.baseUrl}/v1/me/tenants/${encodeURIComponent(tenantId)}`;\n }\n\n /**\n * Low-level passthrough request. Centralizes the absolute URL (already built\n * by a path-builder, so it carries the base URL + `/graphs/{tenant}` prefix),\n * the `X-API-Key` header, JSON content-type, body stringification, and a\n * timeout/abort — then returns the backend {@link Response} UNCHANGED.\n *\n * Unlike {@link request}, this does NOT inspect `res.ok` and does NOT parse or\n * reshape the body. A 4xx/5xx comes back as a resolved `Response` (the caller\n * reads `.status`/`.headers`/`.body`), NOT a thrown {@link CographError}. The\n * only rejection paths are a genuine network failure or a timeout abort —\n * exactly the cases where there is no HTTP response to hand back.\n *\n * `init.headers` is merged last so a caller can add/override headers; `init.body`,\n * when a non-string is passed, is JSON-stringified for convenience.\n */\n async requestRaw(\n method: string,\n path: string,\n init: { body?: unknown; headers?: Record<string, string>; timeoutMs?: number } = {},\n ): Promise<Response> {\n const timeoutMs = init.timeoutMs ?? 120_000;\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n // Always a string (or undefined): we stringify non-string bodies here, so we\n // never depend on the DOM `BodyInit` type (this package builds with the Node\n // lib only, no `dom` lib).\n let body: string | undefined;\n if (init.body !== undefined) {\n body = typeof init.body === \"string\" ? init.body : JSON.stringify(init.body);\n }\n\n try {\n return await fetch(path, {\n method,\n headers: { ...this.headers(), ...(init.headers ?? {}) },\n body,\n signal: controller.signal,\n });\n } catch (err) {\n // A network error or timeout abort means there is NO Response to return,\n // so this is the one case we surface as a thrown error. A non-2xx HTTP\n // status is NOT an error here — it resolves above as a Response.\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new CographError(`Request to ${path} timed out after ${timeoutMs}ms`);\n }\n throw new CographError(\n `Network error contacting ${path}: ${err instanceof Error ? err.message : String(err)}`,\n );\n } finally {\n clearTimeout(timer);\n }\n }\n\n /**\n * Probe the backend to determine reachability and whether endpoints\n * require an X-API-Key header. Used at shell startup to distinguish\n * cloud (auth required) from self-hosted open-access deployments.\n */\n async healthCheck(): Promise<{\n ok: boolean;\n requiresAuth: boolean;\n url: string;\n }> {\n const healthUrl = `${this.baseUrl}/health`;\n try {\n const res = await fetch(healthUrl, {\n signal: AbortSignal.timeout(5000),\n });\n if (!res.ok) return { ok: false, requiresAuth: false, url: this.baseUrl };\n } catch {\n return { ok: false, requiresAuth: false, url: this.baseUrl };\n }\n // Probe whether endpoints require auth by hitting /kgs without X-API-Key.\n // 401 = requires auth; 200/empty = open access; anything else = treat as\n // auth-required to be safe.\n try {\n const res = await fetch(`${this.base()}/kgs`, {\n headers: { \"Content-Type\": \"application/json\" },\n signal: AbortSignal.timeout(5000),\n });\n return {\n ok: true,\n requiresAuth: res.status === 401,\n url: this.baseUrl,\n };\n } catch {\n return { ok: true, requiresAuth: true, url: this.baseUrl };\n }\n }\n\n private async request<T = unknown>(\n method: string,\n url: string,\n body?: unknown,\n timeoutMs: number = 120_000,\n ): Promise<T> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n let res: Response;\n try {\n res = await fetch(url, {\n method,\n headers: this.headers(),\n body: body === undefined ? undefined : JSON.stringify(body),\n signal: controller.signal,\n });\n } catch (err) {\n clearTimeout(timer);\n if (err instanceof Error && err.name === \"AbortError\") {\n throw new CographError(`Request to ${url} timed out after ${timeoutMs}ms`);\n }\n throw new CographError(\n `Network error contacting ${url}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n clearTimeout(timer);\n\n if (!res.ok) {\n let text = \"\";\n try {\n text = await res.text();\n } catch {\n // ignore\n }\n throw new CographError(`HTTP ${res.status}: ${text}`, {\n status: res.status,\n body: text,\n });\n }\n\n // 204 No Content\n if (res.status === 204) return undefined as T;\n\n const ct = res.headers.get(\"content-type\") ?? \"\";\n if (ct.includes(\"application/json\")) {\n return (await res.json()) as T;\n }\n // fall back to text\n const text = await res.text();\n try {\n return JSON.parse(text) as T;\n } catch {\n return text as unknown as T;\n }\n }\n\n /**\n * Ingest a file path or raw text into a knowledge graph.\n *\n * If `pathOrText` points to an existing file, its contents are read and the\n * format is inferred from the extension (.csv, .json, .txt) unless\n * `contentType` is given. CSV files use the two-step schema-inference + row\n * mapping flow.\n */\n async ingest(\n pathOrText: string,\n opts: IngestOptions = {},\n ): Promise<Record<string, unknown>> {\n let content: string;\n let fmt: string;\n\n let isFile = false;\n try {\n isFile = existsSync(pathOrText) && statSync(pathOrText).isFile();\n } catch {\n isFile = false;\n }\n\n if (isFile) {\n const ext = extname(pathOrText).toLowerCase();\n if (ext === \".pdf\") {\n throw new CographError(\n \"PDF ingest not yet supported in the Node CLI; use the Python CLI or POST raw bytes to the API.\",\n );\n }\n content = readFileSync(pathOrText, \"utf-8\");\n fmt = opts.contentType ?? EXT_FORMAT[ext] ?? \"text\";\n if (fmt === \"csv\") {\n return this.ingestCsv(content, opts);\n }\n } else {\n content = pathOrText;\n fmt = opts.contentType ?? \"text\";\n }\n\n const body: Record<string, unknown> = {\n content,\n content_type: fmt,\n source: \"client\",\n };\n if (opts.kg) body.kg_name = opts.kg;\n return this.request(\"POST\", `${this.base()}/ingest`, body, 120_000);\n }\n\n private async ingestCsv(\n content: string,\n opts: IngestOptions,\n ): Promise<Record<string, unknown>> {\n const kgName = opts.kg;\n const batchSize = opts.batchSize ?? 200;\n const concurrency = opts.concurrency ?? 4;\n\n const rows = parseCsv(content);\n if (rows.length === 0) throw new CographError(\"CSV is empty\");\n const headers = Object.keys(rows[0]!);\n\n // Send the whole file to the profiler, evenly strided across it (never the\n // head — head-of-file bias, e.g. a key column that goes sparse later, is\n // exactly what evidence-grounded inference fixes). Profile fidelity =\n // decision quality. Mirrors the Explorer's upload flow.\n const sampleRows = stridedSample(rows);\n\n const schemaBody = {\n headers,\n sample_rows: sampleRows,\n total_rows: rows.length,\n };\n const mapping = await this.request<Record<string, unknown>>(\n \"POST\",\n `${this.base()}/ingest/csv/schema`,\n schemaBody,\n 300_000,\n );\n\n // Confirm/override gate (same contract as the Explorer's review step): the\n // caller inspects the inferred mapping and returns what to ingest, or null\n // to cancel before any rows are written. /ingest/csv/rows applies exactly\n // what we post back. When no hook is given, apply the inference as-is.\n let mappingToPost: Record<string, unknown> = mapping;\n if (opts.onSchemaInferred) {\n const reviewed = await opts.onSchemaInferred(mapping, {\n totalRows: rows.length,\n rowsProfiled: sampleRows.length,\n });\n if (reviewed == null) {\n return { cancelled: true, message: \"Ingest cancelled before any rows were written.\" };\n }\n mappingToPost = reviewed;\n }\n\n // Slice rows into batches up front so we can fire them off in a\n // bounded worker pool. Sequential 50-row batches over 891 rows took\n // ~60s end-to-end (18 round-trips); 200-row batches × 4 in flight\n // brings that to ~5s on the same backend.\n const batches: Array<Record<string, string>[]> = [];\n for (let i = 0; i < rows.length; i += batchSize) {\n batches.push(rows.slice(i, i + batchSize));\n }\n\n let totalEntities = 0;\n let totalTriples = 0;\n let rowsProcessed = 0;\n let nextBatch = 0;\n\n const postBatch = async (batch: Record<string, string>[]) => {\n const body: Record<string, unknown> = {\n mapping: mappingToPost,\n rows: batch,\n source: \"client\",\n };\n if (kgName) body.kg_name = kgName;\n const result = await this.request<{\n entities_resolved?: number;\n triples_inserted?: number;\n }>(\"POST\", `${this.base()}/ingest/csv/rows`, body, 300_000);\n return {\n entities: result.entities_resolved ?? 0,\n triples: result.triples_inserted ?? 0,\n size: batch.length,\n };\n };\n\n const worker = async (): Promise<void> => {\n while (true) {\n const idx = nextBatch++;\n if (idx >= batches.length) return;\n const r = await postBatch(batches[idx]!);\n totalEntities += r.entities;\n totalTriples += r.triples;\n rowsProcessed += r.size;\n opts.onProgress?.({\n rowsProcessed,\n totalRows: rows.length,\n entitiesResolved: totalEntities,\n triplesInserted: totalTriples,\n });\n }\n };\n\n const workers: Array<Promise<void>> = [];\n for (let i = 0; i < Math.min(concurrency, batches.length); i++) {\n workers.push(worker());\n }\n await Promise.all(workers);\n\n // All batches are in — kick off a background recompute of the Explorer\n // type-stats for this KG so type-detail views load instantly. The endpoint\n // returns immediately (the scan runs server-side in the background); this\n // is best-effort and never fails the ingest.\n if (kgName) {\n try {\n await this.request(\n \"POST\",\n `${this.base()}/explore/kgs/${encodeURIComponent(kgName)}/recompute-stats`,\n {},\n 15_000,\n );\n } catch {\n // non-fatal — stats fall back to a live scan until the next recompute\n }\n }\n\n return {\n entities_resolved: totalEntities,\n triples_inserted: totalTriples,\n mapping,\n };\n }\n\n /** Ask a natural language question and return the parsed response. */\n async ask(\n question: string,\n opts: AskOptions = {},\n ): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = { question };\n if (opts.kg) body.kg_name = opts.kg;\n if (opts.model) body.model = opts.model;\n return this.request(\"POST\", `${this.base()}/ask`, body, 60_000);\n }\n\n /**\n * One turn of the unified Ask-AI agent — the SINGLE conversational surface\n * (`POST /graphs/{tenant}/agent`, COG-118). Mirrors the HTTP contract exactly:\n *\n * - `confirmPlanId` set → the server runs `execute_plan` (the only mutating\n * path) and returns `{kind:\"result\", steps}`.\n * - otherwise → the server runs `planner.handle(message)` and returns one of\n * `{kind:\"answer\"}` / `{kind:\"clarify\"}` / `{kind:\"plan\"}`.\n *\n * The agent classifies intent server-side and drives the underlying engines\n * through its capability registry — the client never talks to `/ask`,\n * `/enrich/*` etc. for an agent turn. ENTITLEMENT for any paid step a plan\n * contains is enforced server-side at execute time (the same authorization the\n * direct paid routes apply), so confirming a plan here cannot bypass a gate the\n * direct path enforces — the gate lives behind the endpoint, not in this client.\n */\n async agent(opts: AgentTurnOptions): Promise<AgentResult> {\n const body: Record<string, unknown> = {\n message: opts.message ?? \"\",\n context: {\n kg_name: opts.kgName ?? \"\",\n type_name: opts.typeName ?? null,\n },\n };\n if (opts.sessionId) body.session_id = opts.sessionId;\n // confirm.plan_id present → the server routes to execute_plan (mutating).\n if (opts.confirmPlanId) body.confirm = { plan_id: opts.confirmPlanId };\n return this.request<AgentResult>(\n \"POST\",\n `${this.base()}/agent`,\n body,\n // Generous: a confirmed plan can kick off enrichment/dedup work, and a\n // question turn runs an LLM round-trip server-side.\n 120_000,\n );\n }\n\n /** List the tenants the authenticated user can access (GET /v1/me/tenants).\n * Keyed by the API key (X-API-Key → user), so it's independent of the active\n * tenant. Throws CographError with status 501 on deployments without a tenant\n * provider (e.g. OSS-only). */\n async listTenants(): Promise<Array<{ id: string; label: string }>> {\n return this.request<Array<{ id: string; label: string }>>(\n \"GET\",\n `${this.baseUrl}/v1/me/tenants`,\n undefined,\n 15_000,\n );\n }\n\n /** List all knowledge graphs for the current tenant. */\n async listKgs(): Promise<Array<Record<string, unknown>>> {\n const data = await this.request<unknown>(\n \"GET\",\n `${this.base()}/kgs`,\n undefined,\n 15_000,\n );\n if (Array.isArray(data)) return data as Array<Record<string, unknown>>;\n if (data && typeof data === \"object\" && \"kgs\" in data) {\n const kgs = (data as { kgs?: unknown }).kgs;\n if (Array.isArray(kgs)) return kgs as Array<Record<string, unknown>>;\n }\n return [];\n }\n\n /** Create a knowledge graph. */\n async createKg(\n name: string,\n description?: string,\n ): Promise<Record<string, unknown>> {\n const body: Record<string, unknown> = { name };\n if (description) body.description = description;\n return this.request(\"POST\", `${this.base()}/kgs`, body, 15_000);\n }\n\n /** Delete a knowledge graph by name. */\n async deleteKg(name: string): Promise<Record<string, unknown>> {\n return this.request(\n \"DELETE\",\n `${this.base()}/kgs/${encodeURIComponent(name)}`,\n undefined,\n 30_000,\n );\n }\n\n /** List ontology types. */\n async ontologyTypes(): Promise<Array<Record<string, unknown>>> {\n const data = await this.request<unknown>(\n \"GET\",\n `${this.base()}/ontology/types`,\n undefined,\n 15_000,\n );\n return Array.isArray(data) ? (data as Array<Record<string, unknown>>) : [];\n }\n\n /**\n * Resolve a natural-language ontology change against the existing ontology.\n * The caller does not need to know exact type/attribute/relationship names —\n * the server matches the plain-language `ask` to the current schema and\n * returns auto-applied changes plus proposals that need confirmation.\n */\n async ontologyResolve(\n ask: string,\n opts: { knowledge_graph?: string } = {},\n ): Promise<OntologyResolveResult> {\n const body: Record<string, unknown> = { ask };\n if (opts.knowledge_graph) body.knowledge_graph = opts.knowledge_graph;\n return this.request<OntologyResolveResult>(\n \"POST\",\n `${this.base()}/ontology/resolve`,\n body,\n 60_000,\n );\n }\n\n /**\n * Apply a single resolved ontology change — one of the `proposals` returned\n * by {@link ontologyResolve}. Pass the proposal object through unchanged.\n */\n async ontologyApply(\n proposal: ResolvedChange,\n ): Promise<OntologyApplyResult> {\n return this.request<OntologyApplyResult>(\n \"POST\",\n `${this.base()}/ontology/apply`,\n proposal,\n 60_000,\n );\n }\n\n /**\n * Second-pass entity resolution: re-run ER over an already-ingested KG to\n * collapse intra-batch fragments. Synchronous on the server; returns a\n * per-type before/after report. Generous timeout — it rewrites triples.\n */\n async erRebuild(kg: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n \"POST\",\n `${this.base()}/explore/kgs/${encodeURIComponent(kg)}/er-rebuild`,\n {},\n 300_000,\n );\n }\n\n /** Per-KG type counts: every type with ≥1 instance, sorted desc. */\n async typeCounts(kg: string): Promise<TypeCount[]> {\n const data = await this.request<unknown>(\n \"GET\",\n `${this.base()}/kgs/${encodeURIComponent(kg)}/type-counts`,\n undefined,\n 30_000,\n );\n return Array.isArray(data) ? (data as TypeCount[]) : [];\n }\n\n /** Plan + run an enrichment job. Returns immediately with the job id. */\n async enrichRun(req: EnrichRequest): Promise<EnrichJobCreate> {\n return this.request<EnrichJobCreate>(\n \"POST\",\n `${this.base()}/enrich/jobs`,\n req,\n 30_000,\n );\n }\n\n /** List recent enrichment jobs for the current tenant. */\n async enrichJobs(): Promise<JobSummary[]> {\n const data = await this.request<unknown>(\n \"GET\",\n `${this.base()}/enrich/jobs`,\n undefined,\n 15_000,\n );\n return Array.isArray(data) ? (data as JobSummary[]) : [];\n }\n\n /** Fetch a single enrichment job (with truncated results). */\n async enrichJob(jobId: string): Promise<EnrichJob> {\n return this.request<EnrichJob>(\n \"GET\",\n `${this.base()}/enrich/jobs/${encodeURIComponent(jobId)}`,\n undefined,\n 15_000,\n );\n }\n\n /** Fetch the conflict review queue for a job. */\n async enrichConflicts(jobId: string): Promise<ConflictReview[]> {\n const data = await this.request<unknown>(\n \"GET\",\n `${this.base()}/enrich/jobs/${encodeURIComponent(jobId)}/conflicts`,\n undefined,\n 30_000,\n );\n return Array.isArray(data) ? (data as ConflictReview[]) : [];\n }\n\n /** Apply a set of conflict review decisions to a job. */\n async enrichApply(\n jobId: string,\n decisions: ConflictReview[],\n ): Promise<{ applied: number }> {\n return this.request<{ applied: number }>(\n \"POST\",\n `${this.base()}/enrich/jobs/${encodeURIComponent(jobId)}/apply`,\n { decisions },\n 60_000,\n );\n }\n\n /** Cancel an enrichment job. */\n async enrichCancel(jobId: string): Promise<void> {\n await this.request<void>(\n \"DELETE\",\n `${this.base()}/enrich/jobs/${encodeURIComponent(jobId)}`,\n undefined,\n 15_000,\n );\n }\n\n /** Per-type breakdown for one type in one KG: definition + counts + samples.\n *\n * System predicates (rdfs:label, ingested_at, source) are hidden by default\n * — they're attached to every entity at 100% and drown out the columns the\n * user cares about. Pass `includeSystem: true` to see them. */\n async typeUsage(\n kg: string,\n typeName: string,\n opts: { includeSystem?: boolean } = {},\n ): Promise<TypeUsage> {\n const qs = opts.includeSystem ? \"?include_system=true\" : \"\";\n return this.request<TypeUsage>(\n \"GET\",\n `${this.base()}/kgs/${encodeURIComponent(kg)}/types/${encodeURIComponent(typeName)}/usage${qs}`,\n undefined,\n 30_000,\n );\n }\n\n /** Explorer summary for a type — like typeUsage but adds coverage_pct + avg_degree. */\n async typeSummary(kg: string, typeName: string): Promise<TypeSummary> {\n return this.request<TypeSummary>(\n \"GET\",\n `${this.base()}/explore/kgs/${encodeURIComponent(kg)}/types/${encodeURIComponent(typeName)}/summary`,\n undefined,\n 30_000,\n );\n }\n\n /** Search types or attributes by name substring within a KG. */\n async exploreSearch(\n kg: string,\n q: string,\n kind: \"type\" | \"attr\" = \"type\",\n ): Promise<Array<Record<string, unknown>>> {\n const qs = new URLSearchParams({ kg, q, kind }).toString();\n const data = await this.request<unknown>(\n \"GET\",\n this.pExploreSearch(`?${qs}`),\n undefined,\n 15_000,\n );\n return Array.isArray(data) ? (data as Array<Record<string, unknown>>) : [];\n }\n\n // --- New typed methods (COG-128) ------------------------------------------ #\n // Parsed/throwing variants of the previously-MISSING ops, sharing the same\n // path-builders as the raw API. These follow the existing typed-method\n // contract (throw on non-2xx, light reshape) — the raw equivalents under\n // `client.raw.*` are the non-throwing, non-reshaping passthrough versions.\n\n /**\n * One page of entity instances of a type for the Explorer Data table\n * (`GET /explore/kgs/{kg}/types/{type}/records`). Keyset-paginated by entity\n * URI: pass the previous page's `next_cursor` as `cursor`. `limit` is clamped\n * server-side to 1..200 (default 50).\n */\n async exploreRecords(\n kg: string,\n typeName: string,\n opts: { limit?: number; cursor?: string } = {},\n ): Promise<TypeRecordsPage> {\n const qs = new URLSearchParams();\n if (opts.limit != null) qs.set(\"limit\", String(opts.limit));\n if (opts.cursor) qs.set(\"cursor\", opts.cursor);\n const query = qs.toString() ? `?${qs.toString()}` : \"\";\n return this.request<TypeRecordsPage>(\n \"GET\",\n this.pExploreRecords(kg, typeName, query),\n undefined,\n 30_000,\n );\n }\n\n /** Undirected type→type edges for the Explorer overview graph\n * (`GET /explore/kgs/{kg}/type-edges`). Returns `[{source, target, weight}]`. */\n async exploreTypeEdges(kg: string): Promise<TypeEdge[]> {\n const data = await this.request<unknown>(\n \"GET\",\n this.pExploreTypeEdges(kg),\n undefined,\n 30_000,\n );\n return Array.isArray(data) ? (data as TypeEdge[]) : [];\n }\n\n /** Infer + persist normalization rules for a type's predicates, returned ranked\n * by confidence desc (`POST /normalize/suggest?kg&type`). */\n async normalizeSuggest(kg: string, type: string): Promise<NormalizationRule[]> {\n const qs = new URLSearchParams({ kg, type }).toString();\n const data = await this.request<unknown>(\n \"POST\",\n this.pNormalizeSuggest(`?${qs}`),\n undefined,\n 60_000,\n );\n return Array.isArray(data) ? (data as NormalizationRule[]) : [];\n }\n\n /** List stored normalization rules, optionally filtered by KG and/or status\n * (`GET /normalize/rules?kg&status`). */\n async normalizeRules(\n opts: { kg?: string; status?: string } = {},\n ): Promise<NormalizationRule[]> {\n const qs = new URLSearchParams();\n if (opts.kg) qs.set(\"kg\", opts.kg);\n if (opts.status) qs.set(\"status\", opts.status);\n const query = qs.toString() ? `?${qs.toString()}` : \"\";\n const data = await this.request<unknown>(\n \"GET\",\n this.pNormalizeRules(query),\n undefined,\n 15_000,\n );\n return Array.isArray(data) ? (data as NormalizationRule[]) : [];\n }\n\n /** Confirm a suggested normalization rule (`POST /normalize/rules/{id}/confirm`). */\n async normalizeConfirmRule(ruleId: string): Promise<NormalizationRule> {\n return this.request<NormalizationRule>(\n \"POST\",\n this.pNormalizeRule(ruleId, \"confirm\"),\n undefined,\n 15_000,\n );\n }\n\n /** Reject a suggested normalization rule (`POST /normalize/rules/{id}/reject`). */\n async normalizeRejectRule(ruleId: string): Promise<NormalizationRule> {\n return this.request<NormalizationRule>(\n \"POST\",\n this.pNormalizeRule(ruleId, \"reject\"),\n undefined,\n 15_000,\n );\n }\n\n /** Apply a confirmed normalization rule in the background; the server acks 202\n * (`POST /normalize/rules/{id}/apply`). */\n async normalizeApplyRule(ruleId: string): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n \"POST\",\n this.pNormalizeRule(ruleId, \"apply\"),\n {},\n 60_000,\n );\n }\n\n /** Recommend ontology relationships/changes for the active KG\n * (`POST /ontology/recommend`). Body shape is passed through unchanged.\n *\n * NOTE: this targets the *premium* ontology-recommender route, which is only\n * mounted on deployments carrying the proprietary layer. It 404s on a bare\n * OSS deployment. */\n async ontologyRecommend(\n body: Record<string, unknown> = {},\n ): Promise<Record<string, unknown>> {\n return this.request<Record<string, unknown>>(\n \"POST\",\n this.pOntologyRecommend(),\n body,\n 60_000,\n );\n }\n}\n\n/**\n * A single ontology change resolved against the existing schema. The same\n * shape is returned under `applied`/`proposals` by {@link Client.ontologyResolve}\n * and accepted as the request body by {@link Client.ontologyApply}.\n */\nexport interface ResolvedChange {\n kind: \"attribute\" | \"relationship\";\n subject_type: string;\n name: string;\n datatype_or_target: string;\n action: \"reuse\" | \"extend\" | \"create\";\n confidence: number;\n reason: string;\n}\n\nexport interface OntologyResolveResult {\n applied: ResolvedChange[];\n proposals: ResolvedChange[];\n summary: string;\n}\n\nexport interface OntologyApplyResult {\n applied: ResolvedChange;\n operations: number;\n summary: string;\n}\n\nexport interface TypeCount {\n name: string;\n entity_count: number;\n}\n\nexport interface AttributeUsage {\n name: string;\n datatype: string;\n count: number;\n}\n\nexport interface RelationshipUsage {\n name: string;\n target_type: string | null;\n count: number;\n}\n\nexport interface EntitySample {\n uri: string;\n label: string;\n}\n\nexport interface TypeUsage {\n name: string;\n description: string;\n parent_type: string | null;\n entity_count: number;\n attributes: AttributeUsage[];\n relationships: RelationshipUsage[];\n samples: EntitySample[];\n}\n\nexport interface AttributeSummary {\n name: string;\n predicate_uri: string;\n datatype: string;\n count: number;\n coverage_pct: number;\n}\n\nexport interface RelationshipSummary {\n name: string;\n predicate_uri: string;\n target_type: string | null;\n count: number;\n coverage_pct: number;\n avg_degree: number;\n}\n\nexport interface TypeSummary {\n name: string;\n description: string;\n parent_type: string | null;\n entity_count: number;\n attributes: AttributeSummary[];\n relationships: RelationshipSummary[];\n}\n\nexport type EnrichmentTier = \"lite\" | \"base\" | \"core\" | \"pro\";\nexport type JobStatus =\n | \"queued\"\n | \"running\"\n | \"review\"\n | \"applied\"\n | \"cancelled\"\n | \"failed\";\nexport type ConflictPolicy = \"skip\" | \"verify\" | \"overwrite\" | \"stage\";\nexport type RowAction =\n | \"filled\"\n | \"verified\"\n | \"conflict\"\n | \"skipped\"\n | \"no_match\";\nexport type ReviewDecision = \"accept\" | \"reject\" | \"skip\";\n\nexport interface EnrichRequest {\n type_name: string;\n attributes: string[];\n tier?: EnrichmentTier;\n kg_name: string;\n conflict_policy?: ConflictPolicy;\n confidence_min?: number;\n limit?: number;\n}\n\nexport interface EnrichJobCreate {\n job_id: string;\n status: JobStatus;\n estimated_cost_usd: number;\n total_entities: number;\n}\n\nexport interface Verdict {\n value: string;\n confidence: number;\n source: string;\n source_url?: string | null;\n reasoning?: string | null;\n}\n\nexport interface JobProgress {\n total: number;\n processed: number;\n filled: number;\n verified: number;\n conflicts: number;\n skipped: number;\n cache_hits: number;\n}\n\nexport interface RowResult {\n entity_uri: string;\n attribute: string;\n existing_value: string | null;\n verdict: Verdict | null;\n action: RowAction;\n}\n\nexport interface JobSummary {\n id: string;\n tenant_id: string;\n kg_name: string;\n type_name: string;\n attributes: string[];\n tier: EnrichmentTier;\n status: JobStatus;\n progress: JobProgress;\n created_at: string;\n started_at?: string | null;\n completed_at?: string | null;\n conflict_policy: ConflictPolicy;\n confidence_min: number;\n error?: string | null;\n}\n\nexport interface EnrichJob extends JobSummary {\n results?: RowResult[];\n limit?: number | null;\n}\n\nexport interface ConflictReview {\n entity_uri: string;\n attribute: string;\n existing_value: string;\n proposed: Verdict;\n decision?: ReviewDecision | null;\n}\n\n// --- Unified Ask-AI agent (COG-118 / COG-125) -------------------------------- #\n\n/** Inputs to {@link Client.agent} — mirror the `/agent` HTTP body. */\nexport interface AgentTurnOptions {\n /** The user's natural-language message. Optional when `confirmPlanId` is set\n * (a confirm turn carries no new message). */\n message?: string;\n /** Knowledge graph the turn operates within. */\n kgName?: string;\n /** Optional active type scope (needed for enrich/clean/dedup planning). */\n typeName?: string;\n /** Optional conversation/session id for multi-turn continuity. */\n sessionId?: string;\n /** When set, the server CONFIRMS + EXECUTES this previously-proposed plan\n * (the only mutating path) instead of classifying a new message. */\n confirmPlanId?: string;\n}\n\n/**\n * The kind-tagged result of one agent turn. The server returns exactly one of:\n * - `answer` — a read-only answer (questions; an ontology INSPECT) with SPARQL.\n * - `clarify` — the agent needs more detail; ask the user `question`.\n * - `plan` — a proposed (un-executed) plan with `plan_id` + `steps`; confirm\n * by calling `agent({ confirmPlanId: plan_id })`.\n * - `result` — the outcome of executing a confirmed plan, per-step.\n * - `error` — e.g. an unknown/expired plan_id on confirm.\n * Extra fields vary by kind (answer/sparql/rows; question; plan_id/steps;\n * steps), so this is intentionally open beyond the discriminant.\n */\nexport interface AgentResult {\n kind: \"answer\" | \"clarify\" | \"plan\" | \"result\" | \"error\";\n [key: string]: unknown;\n}\n\n// --- New typed shapes (COG-128) ---------------------------------------------- #\n\n/** One row in the Explorer Data table — an entity instance with its attribute\n * values. `id` is the entity URI; `name` is the display name; the remaining\n * keys are per-attribute values (all stringly-typed for display). */\nexport interface TypeRecord {\n id: string;\n name: string;\n [attr: string]: string;\n}\n\n/** A page of {@link TypeRecord}s returned by {@link Client.exploreRecords}.\n * `next_cursor` is the last entity URI of this page; pass it back as `cursor`\n * to fetch the following page, or `null` when there are no more rows. */\nexport interface TypeRecordsPage {\n columns: string[];\n rows: TypeRecord[];\n total: number;\n next_cursor: string | null;\n}\n\n/** An undirected type→type edge in the Explorer overview graph, weighted by the\n * number of instance relationships it summarizes. */\nexport interface TypeEdge {\n source: string;\n target: string;\n weight: number;\n}\n\n/** A stored normalization rule (suggested / confirmed / rejected / applied).\n * Open beyond the documented fields because the rule's `params` shape varies by\n * `rule_type` (e.g. `strip_emoji`, `list_explode`). */\nexport interface NormalizationRule {\n id: string;\n kg_name: string;\n type_name: string;\n predicate: string;\n rule_type: string;\n target_kind?: string;\n params?: Record<string, unknown>;\n confidence?: number;\n rationale?: string;\n status: \"suggested\" | \"confirmed\" | \"rejected\" | \"applied\" | string;\n created_at?: string;\n applied_at?: string | null;\n [key: string]: unknown;\n}\n\n// --- Raw / passthrough API (COG-128) ----------------------------------------- #\n\n/**\n * Raw / passthrough surface — reached via {@link Client.raw}. Each method maps\n * to ONE canonical backend operation, builds the path internally (callers pass\n * NO path string), and returns the backend {@link Response} VERBATIM:\n *\n * - it does NOT throw on a non-2xx status (a 404/500 resolves as a `Response`\n * whose `.status` the caller inspects — contrast the typed methods, which\n * throw {@link CographError}); and\n * - it does NOT parse or reshape the body (the caller gets the unread stream;\n * contrast e.g. {@link Client.listKgs}, which unwraps `{kgs:[]}`).\n *\n * Every method funnels through {@link Client.requestRaw}, so the base URL,\n * `X-API-Key`, `/graphs/{tenant}` prefix, JSON content-type and timeout are\n * centralized in exactly one place. The only rejection paths are a network\n * failure or a timeout — the cases where there is no HTTP response to return.\n *\n * @example\n * ```ts\n * const client = new Client({ apiKey, tenant });\n * // Webapp proxy pattern: forward the backend response 1:1, no reshaping.\n * const res = await client.raw.enrichJobs(); // GET …/enrich/jobs\n * return new Response(res.body, { status: res.status, headers: res.headers });\n *\n * // A non-2xx is a Response, not a throw:\n * const r = await client.raw.enrichJob(\"does-not-exist\");\n * if (r.status === 404) { ... } // no try/catch needed\n * ```\n */\nexport class RawApi {\n constructor(private readonly client: Client) {}\n\n // -- agent / ask --------------------------------------------------------- #\n\n /** `POST /graphs/{tenant}/agent` — one turn of the unified Ask-AI agent. */\n agent(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pAgent(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/ask` — natural-language question. */\n ask(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pAsk(), { body, ...init });\n }\n\n // -- ingest -------------------------------------------------------------- #\n\n /** `POST /graphs/{tenant}/ingest` — ingest text/json (or csv) content. */\n ingest(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pIngest(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/ingest/csv/schema` — infer a CSV schema mapping. */\n ingestCsvSchema(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pIngestCsvSchema(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/ingest/csv/rows` — write a batch of mapped rows. */\n ingestCsvRows(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pIngestCsvRows(), { body, ...init });\n }\n\n // -- enrich jobs --------------------------------------------------------- #\n\n /** `POST /graphs/{tenant}/enrich/jobs` — plan + run an enrichment job. */\n enrichCreateJob(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pEnrichJobs(), { body, ...init });\n }\n\n /** `GET /graphs/{tenant}/enrich/jobs` — list recent enrichment jobs. */\n enrichJobs(init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pEnrichJobs(), init);\n }\n\n /** `GET /graphs/{tenant}/enrich/jobs/{id}` — fetch a single job. */\n enrichJob(jobId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pEnrichJob(jobId), init);\n }\n\n /** `GET /graphs/{tenant}/enrich/jobs/{id}/conflicts` — conflict review queue. */\n enrichConflicts(jobId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pEnrichJobConflicts(jobId), init);\n }\n\n /** `POST /graphs/{tenant}/enrich/jobs/{id}/apply` — apply review decisions. */\n enrichApply(jobId: string, body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pEnrichJobApply(jobId), { body, ...init });\n }\n\n /** `DELETE /graphs/{tenant}/enrich/jobs/{id}` — cancel a job. */\n enrichCancel(jobId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"DELETE\", this.client.pEnrichJob(jobId), init);\n }\n\n // -- ontology ------------------------------------------------------------ #\n\n /** `GET /graphs/{tenant}/ontology/types` — list ontology types. */\n ontologyTypes(init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pOntologyTypes(), init);\n }\n\n /** `POST /graphs/{tenant}/ontology/resolve` — resolve an NL ontology change. */\n ontologyResolve(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pOntologyResolve(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/ontology/recommend` — recommend ontology changes.\n * Premium route: only mounted on deployments with the proprietary layer,\n * 404s on bare OSS. */\n ontologyRecommend(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pOntologyRecommend(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/ontology/apply` — apply one resolved change. */\n ontologyApply(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pOntologyApply(), { body, ...init });\n }\n\n // -- knowledge graphs ---------------------------------------------------- #\n\n /** `GET /graphs/{tenant}/kgs` — list knowledge graphs. */\n kgs(init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pKgs(), init);\n }\n\n /** `POST /graphs/{tenant}/kgs` — create a knowledge graph. */\n createKg(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pKgs(), { body, ...init });\n }\n\n /** `DELETE /graphs/{tenant}/kgs/{name}` — delete a knowledge graph. */\n deleteKg(name: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"DELETE\", this.client.pKg(name), init);\n }\n\n // -- explore ------------------------------------------------------------- #\n\n /** `GET /graphs/{tenant}/explore/kgs/{kg}/types/{type}/summary`. */\n exploreSummary(kg: string, typeName: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pExploreSummary(kg, typeName), init);\n }\n\n /** `GET /graphs/{tenant}/explore/kgs/{kg}/types/{type}/records?limit&cursor`. */\n exploreRecords(\n kg: string,\n typeName: string,\n opts: { limit?: number; cursor?: string } = {},\n init?: RawInit,\n ): Promise<Response> {\n const qs = new URLSearchParams();\n if (opts.limit != null) qs.set(\"limit\", String(opts.limit));\n if (opts.cursor) qs.set(\"cursor\", opts.cursor);\n const query = qs.toString() ? `?${qs.toString()}` : \"\";\n return this.client.requestRaw(\"GET\", this.client.pExploreRecords(kg, typeName, query), init);\n }\n\n /** `GET /graphs/{tenant}/explore/kgs/{kg}/type-edges`. */\n exploreTypeEdges(kg: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pExploreTypeEdges(kg), init);\n }\n\n /** `GET /graphs/{tenant}/kgs/{kg}/type-counts`. */\n typeCounts(kg: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pTypeCounts(kg), init);\n }\n\n /** `GET /graphs/{tenant}/explore/search?kg&q&kind`. */\n exploreSearch(\n kg: string,\n q: string,\n kind: \"type\" | \"attr\" = \"type\",\n init?: RawInit,\n ): Promise<Response> {\n const qs = new URLSearchParams({ kg, q, kind }).toString();\n return this.client.requestRaw(\"GET\", this.client.pExploreSearch(`?${qs}`), init);\n }\n\n // -- normalize ----------------------------------------------------------- #\n\n /** `POST /graphs/{tenant}/normalize/suggest?kg&type` — infer + persist rules. */\n normalizeSuggest(kg: string, type: string, init?: RawInit): Promise<Response> {\n const qs = new URLSearchParams({ kg, type }).toString();\n return this.client.requestRaw(\"POST\", this.client.pNormalizeSuggest(`?${qs}`), init);\n }\n\n /** `GET /graphs/{tenant}/normalize/rules?kg&status` — list stored rules. */\n normalizeRules(opts: { kg?: string; status?: string } = {}, init?: RawInit): Promise<Response> {\n const qs = new URLSearchParams();\n if (opts.kg) qs.set(\"kg\", opts.kg);\n if (opts.status) qs.set(\"status\", opts.status);\n const query = qs.toString() ? `?${qs.toString()}` : \"\";\n return this.client.requestRaw(\"GET\", this.client.pNormalizeRules(query), init);\n }\n\n /** `POST /graphs/{tenant}/normalize/rules` — create a user-authored rule. */\n normalizeCreateRule(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pNormalizeRules(), { body, ...init });\n }\n\n /** `POST /graphs/{tenant}/normalize/rules/{id}/confirm`. */\n normalizeConfirmRule(ruleId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pNormalizeRule(ruleId, \"confirm\"), init);\n }\n\n /** `POST /graphs/{tenant}/normalize/rules/{id}/reject`. */\n normalizeRejectRule(ruleId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pNormalizeRule(ruleId, \"reject\"), init);\n }\n\n /** `POST /graphs/{tenant}/normalize/rules/{id}/apply`. */\n normalizeApplyRule(ruleId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pNormalizeRule(ruleId, \"apply\"), init);\n }\n\n // -- tenants (account-level, NOT tenant-scoped) -------------------------- #\n\n /** `POST /v1/me/tenants` — create/grant a tenant for the authed user. */\n createTenant(body: unknown, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"POST\", this.client.pTenants(), { body, ...init });\n }\n\n /** `DELETE /v1/me/tenants/{id}` — remove a tenant grant. */\n deleteTenant(tenantId: string, init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"DELETE\", this.client.pTenant(tenantId), init);\n }\n\n /** `GET /v1/me/tenants` — list tenants the authed user can access. */\n tenants(init?: RawInit): Promise<Response> {\n return this.client.requestRaw(\"GET\", this.client.pTenants(), init);\n }\n}\n\n/** Per-call overrides for a {@link RawApi} method — extra/override headers and a\n * custom timeout. A `body` here is ignored by methods that take an explicit\n * body argument (they set it themselves). */\nexport interface RawInit {\n headers?: Record<string, string>;\n timeoutMs?: number;\n}\n","/**\n * Shared terminal renderer for unified Ask-AI agent turns (COG-129).\n *\n * One function — {@link renderAgentResult} — turns a kind-tagged\n * {@link AgentResult} (the response of {@link Client.agent}) into terminal\n * output, used by BOTH the non-interactive `agent` command in `cli.ts` and the\n * interactive `/agent` slash command in `shell.ts`. Keeping it here means the\n * answer/clarify/plan/result rendering lives in exactly one place and the two\n * entry points can never drift.\n *\n * The renderer writes to a caller-supplied sink (defaults to stdout) so it is\n * trivially testable: tests pass a string-collecting sink and assert on what\n * came out, without stubbing `process.stdout`.\n *\n * It treats {@link AgentResult} as the open, kind-tagged shape the SDK exports\n * (the discriminant `kind` plus loosely-typed extras), reading fields\n * defensively — a missing `sparql`/`rows`/`cost` is simply omitted, never throws.\n */\n\nimport type { AgentResult } from \"./client.js\";\n\n// --- ANSI helpers ----------------------------------------------------------- #\n// Self-contained (no dependency on cli.ts/shell.ts) so this module can be\n// imported by either. Color is gated on a TTY + NO_COLOR, matching cli.ts; a\n// caller can force-disable with `{ color: false }` (tests do this so assertions\n// are on plain text).\n\nconst ttyColor = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;\n\nfunction sgr(code: string, s: string, color: boolean): string {\n return color ? `\\x1b[${code}m${s}\\x1b[0m` : s;\n}\n\n/** Where a render writes. The default targets stdout; tests pass a collector. */\nexport interface RenderSink {\n write(s: string): void;\n}\n\nexport interface RenderOptions {\n /** Override color. Defaults to \"on when stdout is a TTY and NO_COLOR unset\". */\n color?: boolean;\n /** Output sink. Defaults to process.stdout. */\n sink?: RenderSink;\n}\n\ninterface Pen {\n bold: (s: string) => string;\n dim: (s: string) => string;\n cyan: (s: string) => string;\n green: (s: string) => string;\n red: (s: string) => string;\n yellow: (s: string) => string;\n}\n\nfunction makePen(color: boolean): Pen {\n return {\n bold: (s) => sgr(\"1\", s, color),\n dim: (s) => sgr(\"2\", s, color),\n cyan: (s) => sgr(\"36\", s, color),\n green: (s) => sgr(\"32\", s, color),\n red: (s) => sgr(\"31\", s, color),\n yellow: (s) => sgr(\"33\", s, color),\n };\n}\n\n// --- small shape helpers ---------------------------------------------------- #\n// AgentResult is intentionally open beyond `kind`, so we read fields with\n// runtime guards rather than casts that could throw on an unexpected payload.\n\nfunction str(v: unknown): string | undefined {\n return typeof v === \"string\" && v.length > 0 ? v : undefined;\n}\n\nfunction asArray(v: unknown): unknown[] {\n return Array.isArray(v) ? v : [];\n}\n\nfunction asRecord(v: unknown): Record<string, unknown> {\n return v && typeof v === \"object\" && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : {};\n}\n\n/** Indent every line of a (possibly multi-line) block by `pad` spaces. */\nfunction indent(text: string, pad: string): string {\n return text\n .split(\"\\n\")\n .map((l) => (l.length ? pad + l : l))\n .join(\"\\n\");\n}\n\n/**\n * Render a 0.0–1.0 confidence as a short bar + percentage, colored by band:\n * green ≥ 0.75, yellow ≥ 0.4, dim/red below. Returns \"\" when there's no usable\n * number so a step with no confidence renders cleanly.\n */\nfunction confidenceIndicator(value: unknown, pen: Pen): string {\n const n = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(n)) return \"\";\n const clamped = Math.max(0, Math.min(1, n));\n const filled = Math.round(clamped * 5);\n const bar = \"●\".repeat(filled) + \"○\".repeat(5 - filled);\n const pct = `${Math.round(clamped * 100)}%`;\n const label = `${bar} ${pct}`;\n if (clamped >= 0.75) return pen.green(label);\n if (clamped >= 0.4) return pen.yellow(label);\n return pen.dim(label);\n}\n\n/**\n * Render a step's cost dict. Highlights paid work — a nonzero `paid_calls` and\n * any `estimated_usd` are surfaced in yellow so a plan that will spend money\n * stands out; free work renders dim. Returns \"\" for an empty/zero cost.\n */\nfunction costIndicator(cost: unknown, pen: Pen): string {\n const c = asRecord(cost);\n const paidRaw = c.paid_calls ?? c.paidCalls;\n const usdRaw = c.estimated_usd ?? c.estimatedUsd ?? c.usd;\n const paid = typeof paidRaw === \"number\" ? paidRaw : Number(paidRaw);\n const usd = typeof usdRaw === \"number\" ? usdRaw : Number(usdRaw);\n const parts: string[] = [];\n if (Number.isFinite(paid) && paid > 0) {\n parts.push(`${paid.toLocaleString()} paid call${paid === 1 ? \"\" : \"s\"}`);\n }\n if (Number.isFinite(usd) && usd > 0) {\n parts.push(`$${usd.toFixed(usd < 0.01 ? 4 : 2)}`);\n }\n if (parts.length) return pen.yellow(parts.join(\" · \"));\n // Explicitly-free work (a cost dict present but zero) reads as \"free\".\n if (Object.keys(c).length) return pen.dim(\"free\");\n return \"\";\n}\n\n// --- table rendering (mirrors the existing CLI results-table style) --------- #\n\n/**\n * Render `rows` (array of objects) as an aligned table, columns ordered by\n * `columns` when given else by first-row key order. Mirrors the column-padding\n * style used elsewhere in the CLI (`/types`, enrich jobs). Caps at 20 rows with\n * a \"… N more\" footer so a large result set doesn't flood the terminal.\n */\nfunction renderTable(\n rows: unknown[],\n columns: string[] | undefined,\n pen: Pen,\n write: (s: string) => void,\n): void {\n const objRows = rows.map(asRecord);\n if (objRows.length === 0) return;\n const cols =\n columns && columns.length\n ? columns\n : Array.from(\n objRows.reduce<Set<string>>((set, r) => {\n for (const k of Object.keys(r)) set.add(k);\n return set;\n }, new Set<string>()),\n );\n if (cols.length === 0) return;\n\n const cell = (r: Record<string, unknown>, c: string): string => {\n const v = r[c];\n if (v == null) return \"\";\n return typeof v === \"object\" ? JSON.stringify(v) : String(v);\n };\n\n const MAX = 20;\n const shown = objRows.slice(0, MAX);\n const widths = cols.map((c) =>\n Math.max(c.length, ...shown.map((r) => cell(r, c).length)),\n );\n\n write(\n \" \" +\n pen.bold(cols.map((c, i) => c.padEnd(widths[i]!)).join(\" \")) +\n \"\\n\",\n );\n for (const r of shown) {\n write(\n \" \" + cols.map((c, i) => cell(r, c).padEnd(widths[i]!)).join(\" \") + \"\\n\",\n );\n }\n if (objRows.length > MAX) {\n write(\" \" + pen.dim(`… ${objRows.length - MAX} more row(s)`) + \"\\n\");\n }\n}\n\n// --- per-kind renderers ----------------------------------------------------- #\n\nfunction renderAnswer(\n r: AgentResult,\n pen: Pen,\n write: (s: string) => void,\n): void {\n // Prefer the narrative, then the formatted answer; either may be present.\n const narrative = str(r.narrative) ?? str(r.answer) ?? \"No answer.\";\n write(\"\\n \" + narrative + \"\\n\");\n\n const sparql = str(r.sparql);\n if (sparql) {\n write(\"\\n \" + pen.dim(\"SPARQL\") + \"\\n\");\n write(indent(pen.dim(sparql), \" \") + \"\\n\");\n }\n\n const rows = asArray(r.rows);\n if (rows.length) {\n const columns = asArray(r.columns).filter(\n (c): c is string => typeof c === \"string\",\n );\n write(\"\\n\");\n renderTable(rows, columns.length ? columns : undefined, pen, write);\n }\n write(\"\\n\");\n}\n\nfunction renderClarify(\n r: AgentResult,\n pen: Pen,\n write: (s: string) => void,\n): void {\n const q =\n str(r.question) ?? str(r.clarify) ?? \"Could you clarify what you'd like?\";\n write(\"\\n \" + pen.yellow(\"?\") + \" \" + q + \"\\n\\n\");\n}\n\nfunction renderPlan(\n r: AgentResult,\n pen: Pen,\n write: (s: string) => void,\n): void {\n const planId = str(r.plan_id) ?? str(r.planId) ?? \"?\";\n const steps = asArray(r.steps).map(asRecord);\n write(\n \"\\n \" +\n pen.bold(\"Plan\") +\n \" \" +\n pen.dim(`${steps.length} step${steps.length === 1 ? \"\" : \"s\"}`) +\n pen.dim(` · plan_id ${planId}`) +\n \"\\n\",\n );\n steps.forEach((s, i) => {\n const cap = str(s.capability) ?? \"?\";\n const action = str(s.action) ?? \"?\";\n const conf = confidenceIndicator(s.confidence, pen);\n const cost = costIndicator(s.cost, pen);\n const tags = [conf, cost].filter(Boolean).join(\" \");\n write(\n `\\n ${pen.dim(`${i + 1}.`)} ${pen.cyan(cap)} ${pen.dim(\"→\")} ${pen.bold(action)}` +\n (tags ? ` ${tags}` : \"\") +\n \"\\n\",\n );\n const rationale = str(s.rationale);\n if (rationale) write(\" \" + pen.dim(rationale) + \"\\n\");\n });\n write(\"\\n\");\n}\n\nfunction renderResult(\n r: AgentResult,\n pen: Pen,\n write: (s: string) => void,\n): void {\n const steps = asArray(r.steps).map(asRecord);\n write(\"\\n \" + pen.bold(\"Result\") + \"\\n\");\n if (steps.length === 0) {\n write(\" \" + pen.dim(\"(no steps)\") + \"\\n\\n\");\n return;\n }\n for (const s of steps) {\n // The planner stamps status \"ok\" on success, \"failed\" on a raised step, and\n // \"skipped\" for an unregistered capability.\n const status = str(s.status) ?? \"ok\";\n const ok = status === \"ok\";\n const failed = status === \"failed\";\n const mark = ok ? pen.green(\"✓\") : failed ? pen.red(\"✗\") : pen.dim(\"–\");\n const cap = str(s.capability) ?? str(s.action) ?? \"step\";\n const summary =\n str(s.message) ?? str(s.error) ?? (ok ? \"done\" : status);\n write(` ${mark} ${pen.bold(cap)} ${summary}\\n`);\n // Job reference, when the step kicked off background work.\n const jobId = str(s.job_id) ?? str(s.jobId);\n if (jobId) {\n const jobStatus = str(s.job_status) ?? str(s.jobStatus);\n write(\n \" \" +\n pen.dim(`job ${jobId}${jobStatus ? ` · ${jobStatus}` : \"\"}`) +\n \"\\n\",\n );\n }\n }\n write(\"\\n\");\n}\n\nfunction renderError(\n r: AgentResult,\n pen: Pen,\n write: (s: string) => void,\n): void {\n const msg = str(r.error) ?? \"The agent returned an error.\";\n const planId = str(r.plan_id) ?? str(r.planId);\n write(\n \"\\n \" +\n pen.red(\"✗\") +\n \" \" +\n msg +\n (planId ? pen.dim(` (plan_id ${planId})`) : \"\") +\n \"\\n\\n\",\n );\n}\n\n/**\n * Render one agent turn to the terminal. Dispatches on `result.kind`:\n * - `answer` → narrative, optional SPARQL (dim), optional rows table.\n * - `clarify` → the clarifying question.\n * - `plan` → each step (capability → action, confidence, cost, rationale)\n * plus the plan_id.\n * - `result` → per-step done/failed marker + summary + any job reference.\n * - `error` → the error message (+ plan_id if present).\n * An unknown `kind` falls back to a compact JSON dump so nothing is swallowed.\n */\nexport function renderAgentResult(\n result: AgentResult,\n opts: RenderOptions = {},\n): void {\n const color = opts.color ?? ttyColor;\n const sink = opts.sink ?? process.stdout;\n const write = (s: string): void => {\n sink.write(s);\n };\n const pen = makePen(color);\n\n switch (result.kind) {\n case \"answer\":\n return renderAnswer(result, pen, write);\n case \"clarify\":\n return renderClarify(result, pen, write);\n case \"plan\":\n return renderPlan(result, pen, write);\n case \"result\":\n return renderResult(result, pen, write);\n case \"error\":\n return renderError(result, pen, write);\n default:\n // Unknown discriminant — never throw, never silently drop. Surface it.\n write(\"\\n \" + JSON.stringify(result) + \"\\n\\n\");\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,YAAY,cAAc,gBAAgB;AACnD,SAAS,eAAe;AAGjB,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,MAA2C;AACtE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS,MAAM;AACpB,SAAK,OAAO,MAAM;AAAA,EACpB;AACF;AA0CO,IAAM,oBAAoB;AAEjC,SAAS,cAAiB,MAAW,MAAc,mBAAwB;AACzE,MAAI,KAAK,UAAU,IAAK,QAAO;AAC/B,QAAM,MAAW,CAAC;AAClB,WAAS,IAAI,GAAG,IAAI,KAAK,IAAK,KAAI,KAAK,KAAK,KAAK,MAAO,IAAI,KAAK,SAAU,GAAG,CAAC,CAAE;AACjF,SAAO;AACT;AAOA,SAAS,OAAO,MAAc,UAAuC;AAEnE,SACE,QAAQ,IAAI,WAAW,IAAI,EAAE,KAC7B,QAAQ,IAAI,SAAS,IAAI,EAAE,KAC3B;AAEJ;AAEA,IAAM,aAAqC;AAAA,EACzC,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AACV;AASO,SAAS,SAAS,SAA2C;AAClE,QAAM,OAAmB,CAAC;AAC1B,MAAI,MAAgB,CAAC;AACrB,MAAI,QAAQ;AACZ,MAAI,WAAW;AAEf,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,KAAK,QAAQ,CAAC;AACpB,QAAI,UAAU;AACZ,UAAI,OAAO,KAAK;AACd,YAAI,QAAQ,IAAI,CAAC,MAAM,KAAK;AAC1B,mBAAS;AACT;AAAA,QACF,OAAO;AACL,qBAAW;AAAA,QACb;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF,OAAO;AACL,UAAI,OAAO,KAAK;AACd,mBAAW;AAAA,MACb,WAAW,OAAO,KAAK;AACrB,YAAI,KAAK,KAAK;AACd,gBAAQ;AAAA,MACV,WAAW,OAAO,MAAM;AACtB,YAAI,KAAK,KAAK;AACd,aAAK,KAAK,GAAG;AACb,cAAM,CAAC;AACP,gBAAQ;AAAA,MACV,WAAW,OAAO,MAAM;AAEtB,YAAI,QAAQ,IAAI,CAAC,MAAM,MAAM;AAC3B,cAAI,KAAK,KAAK;AACd,eAAK,KAAK,GAAG;AACb,gBAAM,CAAC;AACP,kBAAQ;AAAA,QACV;AAAA,MACF,OAAO;AACL,iBAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,SAAS,KAAK,IAAI,SAAS,GAAG;AACtC,QAAI,KAAK,KAAK;AACd,SAAK,KAAK,GAAG;AAAA,EACf;AAEA,MAAI,KAAK,WAAW,EAAG,QAAO,CAAC;AAC/B,QAAM,UAAU,KAAK,CAAC,EAAG,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAC5C,QAAM,MAAgC,CAAC;AACvC,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,MAAM,KAAK,CAAC;AAElB,QAAI,IAAI,WAAW,KAAK,IAAI,CAAC,MAAM,GAAI;AACvC,UAAM,MAA8B,CAAC;AACrC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAI,QAAQ,CAAC,CAAE,IAAI,IAAI,CAAC,KAAK;AAAA,IAC/B;AACA,QAAI,KAAK,GAAG;AAAA,EACd;AACA,SAAO;AACT;AAEO,IAAM,SAAN,MAAa;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWS;AAAA,EAET,YAAY,OAAsB,CAAC,GAAG;AAIpC,UAAM,MAAM,WAAW;AACvB,SAAK,SAAS,KAAK,UAAU,OAAO,SAAS,KAAK,IAAI;AACtD,UAAM,MACJ,KAAK,WAAW,OAAO,SAAS,KAAK,IAAI,UAAU;AACrD,SAAK,UAAU,IAAI,QAAQ,QAAQ,EAAE;AACrC,SAAK,SAAS,KAAK,UAAU,OAAO,QAAQ,KAAK,IAAI,UAAU;AAC/D,SAAK,MAAM,IAAI,OAAO,IAAI;AAAA,EAC5B;AAAA,EAEQ,UAAkC;AACxC,UAAM,IAA4B,EAAE,gBAAgB,mBAAmB;AACvE,QAAI,KAAK,OAAQ,GAAE,WAAW,IAAI,KAAK;AACvC,WAAO;AAAA,EACT;AAAA,EAEQ,OAAe;AACrB,WAAO,GAAG,KAAK,OAAO,WAAW,KAAK,MAAM;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,SAAiB;AACf,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,OAAe;AAC9B,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,UAAkB;AACjC,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,mBAA2B;AAC1C,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,iBAAyB;AACxC,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,cAAsB;AACrC,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,WAAW,OAAuB;AACjD,WAAO,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAAA,EAChE;AAAA;AAAA,EACiB,oBAAoB,OAAuB;AAC1D,WAAO,GAAG,KAAK,WAAW,KAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EACiB,gBAAgB,OAAuB;AACtD,WAAO,GAAG,KAAK,WAAW,KAAK,CAAC;AAAA,EAClC;AAAA;AAAA,EACiB,iBAAyB;AACxC,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,mBAA2B;AAC1C,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA;AAAA,EAGA,qBAA6B;AAC3B,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,iBAAyB;AACxC,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,OAAe;AAC9B,WAAO,GAAG,KAAK,KAAK,CAAC;AAAA,EACvB;AAAA;AAAA,EACiB,IAAI,MAAsB;AACzC,WAAO,GAAG,KAAK,KAAK,CAAC,QAAQ,mBAAmB,IAAI,CAAC;AAAA,EACvD;AAAA;AAAA,EACiB,YAAY,IAAoB;AAC/C,WAAO,GAAG,KAAK,IAAI,EAAE,CAAC;AAAA,EACxB;AAAA;AAAA,EACiB,gBAAgB,IAAY,UAA0B;AACrE,WAAO,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,EAAE,CAAC,UAAU,mBAAmB,QAAQ,CAAC;AAAA,EACnG;AAAA;AAAA,EACiB,gBAAgB,IAAY,UAAkB,OAAwB;AACrF,WAAO,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,EAAE,CAAC,UAAU,mBAAmB,QAAQ,CAAC,WAAW,SAAS,EAAE;AAAA,EACzH;AAAA;AAAA,EACiB,kBAAkB,IAAoB;AACrD,WAAO,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,EAAE,CAAC;AAAA,EAC7D;AAAA;AAAA,EACiB,eAAe,OAAuB;AACrD,WAAO,GAAG,KAAK,KAAK,CAAC,kBAAkB,KAAK;AAAA,EAC9C;AAAA;AAAA,EACiB,kBAAkB,OAAuB;AACxD,WAAO,GAAG,KAAK,KAAK,CAAC,qBAAqB,KAAK;AAAA,EACjD;AAAA;AAAA,EACiB,gBAAgB,OAAwB;AACvD,WAAO,GAAG,KAAK,KAAK,CAAC,mBAAmB,SAAS,EAAE;AAAA,EACrD;AAAA;AAAA,EACiB,eAAe,QAAgB,QAAgD;AAC9F,WAAO,GAAG,KAAK,KAAK,CAAC,oBAAoB,mBAAmB,MAAM,CAAC,IAAI,MAAM;AAAA,EAC/E;AAAA;AAAA,EACiB,WAAmB;AAClC,WAAO,GAAG,KAAK,OAAO;AAAA,EACxB;AAAA;AAAA,EACiB,QAAQ,UAA0B;AACjD,WAAO,GAAG,KAAK,OAAO,kBAAkB,mBAAmB,QAAQ,CAAC;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,WACJ,QACA,MACA,OAAiF,CAAC,GAC/D;AACnB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAK5D,QAAI;AACJ,QAAI,KAAK,SAAS,QAAW;AAC3B,aAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO,KAAK,UAAU,KAAK,IAAI;AAAA,IAC7E;AAEA,QAAI;AACF,aAAO,MAAM,MAAM,MAAM;AAAA,QACvB;AAAA,QACA,SAAS,EAAE,GAAG,KAAK,QAAQ,GAAG,GAAI,KAAK,WAAW,CAAC,EAAG;AAAA,QACtD;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,KAAK;AAIZ,UAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,cAAM,IAAI,aAAa,cAAc,IAAI,oBAAoB,SAAS,IAAI;AAAA,MAC5E;AACA,YAAM,IAAI;AAAA,QACR,4BAA4B,IAAI,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACvF;AAAA,IACF,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,cAIH;AACD,UAAM,YAAY,GAAG,KAAK,OAAO;AACjC,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,WAAW;AAAA,QACjC,QAAQ,YAAY,QAAQ,GAAI;AAAA,MAClC,CAAC;AACD,UAAI,CAAC,IAAI,GAAI,QAAO,EAAE,IAAI,OAAO,cAAc,OAAO,KAAK,KAAK,QAAQ;AAAA,IAC1E,QAAQ;AACN,aAAO,EAAE,IAAI,OAAO,cAAc,OAAO,KAAK,KAAK,QAAQ;AAAA,IAC7D;AAIA,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,GAAG,KAAK,KAAK,CAAC,QAAQ;AAAA,QAC5C,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,QAAQ,YAAY,QAAQ,GAAI;AAAA,MAClC,CAAC;AACD,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,cAAc,IAAI,WAAW;AAAA,QAC7B,KAAK,KAAK;AAAA,MACZ;AAAA,IACF,QAAQ;AACN,aAAO,EAAE,IAAI,MAAM,cAAc,MAAM,KAAK,KAAK,QAAQ;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAc,QACZ,QACA,KACA,MACA,YAAoB,MACR;AACZ,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,SAAS;AAC5D,QAAI;AACJ,QAAI;AACF,YAAM,MAAM,MAAM,KAAK;AAAA,QACrB;AAAA,QACA,SAAS,KAAK,QAAQ;AAAA,QACtB,MAAM,SAAS,SAAY,SAAY,KAAK,UAAU,IAAI;AAAA,QAC1D,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,mBAAa,KAAK;AAClB,UAAI,eAAe,SAAS,IAAI,SAAS,cAAc;AACrD,cAAM,IAAI,aAAa,cAAc,GAAG,oBAAoB,SAAS,IAAI;AAAA,MAC3E;AACA,YAAM,IAAI;AAAA,QACR,4BAA4B,GAAG,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,MACtF;AAAA,IACF;AACA,iBAAa,KAAK;AAElB,QAAI,CAAC,IAAI,IAAI;AACX,UAAIA,QAAO;AACX,UAAI;AACF,QAAAA,QAAO,MAAM,IAAI,KAAK;AAAA,MACxB,QAAQ;AAAA,MAER;AACA,YAAM,IAAI,aAAa,QAAQ,IAAI,MAAM,KAAKA,KAAI,IAAI;AAAA,QACpD,QAAQ,IAAI;AAAA,QACZ,MAAMA;AAAA,MACR,CAAC;AAAA,IACH;AAGA,QAAI,IAAI,WAAW,IAAK,QAAO;AAE/B,UAAM,KAAK,IAAI,QAAQ,IAAI,cAAc,KAAK;AAC9C,QAAI,GAAG,SAAS,kBAAkB,GAAG;AACnC,aAAQ,MAAM,IAAI,KAAK;AAAA,IACzB;AAEA,UAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,QAAI;AACF,aAAO,KAAK,MAAM,IAAI;AAAA,IACxB,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,OACJ,YACA,OAAsB,CAAC,GACW;AAClC,QAAI;AACJ,QAAI;AAEJ,QAAI,SAAS;AACb,QAAI;AACF,eAAS,WAAW,UAAU,KAAK,SAAS,UAAU,EAAE,OAAO;AAAA,IACjE,QAAQ;AACN,eAAS;AAAA,IACX;AAEA,QAAI,QAAQ;AACV,YAAM,MAAM,QAAQ,UAAU,EAAE,YAAY;AAC5C,UAAI,QAAQ,QAAQ;AAClB,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,gBAAU,aAAa,YAAY,OAAO;AAC1C,YAAM,KAAK,eAAe,WAAW,GAAG,KAAK;AAC7C,UAAI,QAAQ,OAAO;AACjB,eAAO,KAAK,UAAU,SAAS,IAAI;AAAA,MACrC;AAAA,IACF,OAAO;AACL,gBAAU;AACV,YAAM,KAAK,eAAe;AAAA,IAC5B;AAEA,UAAM,OAAgC;AAAA,MACpC;AAAA,MACA,cAAc;AAAA,MACd,QAAQ;AAAA,IACV;AACA,QAAI,KAAK,GAAI,MAAK,UAAU,KAAK;AACjC,WAAO,KAAK,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,WAAW,MAAM,IAAO;AAAA,EACpE;AAAA,EAEA,MAAc,UACZ,SACA,MACkC;AAClC,UAAM,SAAS,KAAK;AACpB,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,cAAc,KAAK,eAAe;AAExC,UAAM,OAAO,SAAS,OAAO;AAC7B,QAAI,KAAK,WAAW,EAAG,OAAM,IAAI,aAAa,cAAc;AAC5D,UAAM,UAAU,OAAO,KAAK,KAAK,CAAC,CAAE;AAMpC,UAAM,aAAa,cAAc,IAAI;AAErC,UAAM,aAAa;AAAA,MACjB;AAAA,MACA,aAAa;AAAA,MACb,YAAY,KAAK;AAAA,IACnB;AACA,UAAM,UAAU,MAAM,KAAK;AAAA,MACzB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAMA,QAAI,gBAAyC;AAC7C,QAAI,KAAK,kBAAkB;AACzB,YAAM,WAAW,MAAM,KAAK,iBAAiB,SAAS;AAAA,QACpD,WAAW,KAAK;AAAA,QAChB,cAAc,WAAW;AAAA,MAC3B,CAAC;AACD,UAAI,YAAY,MAAM;AACpB,eAAO,EAAE,WAAW,MAAM,SAAS,iDAAiD;AAAA,MACtF;AACA,sBAAgB;AAAA,IAClB;AAMA,UAAM,UAA2C,CAAC;AAClD,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK,WAAW;AAC/C,cAAQ,KAAK,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC;AAAA,IAC3C;AAEA,QAAI,gBAAgB;AACpB,QAAI,eAAe;AACnB,QAAI,gBAAgB;AACpB,QAAI,YAAY;AAEhB,UAAM,YAAY,OAAO,UAAoC;AAC3D,YAAM,OAAgC;AAAA,QACpC,SAAS;AAAA,QACT,MAAM;AAAA,QACN,QAAQ;AAAA,MACV;AACA,UAAI,OAAQ,MAAK,UAAU;AAC3B,YAAM,SAAS,MAAM,KAAK,QAGvB,QAAQ,GAAG,KAAK,KAAK,CAAC,oBAAoB,MAAM,GAAO;AAC1D,aAAO;AAAA,QACL,UAAU,OAAO,qBAAqB;AAAA,QACtC,SAAS,OAAO,oBAAoB;AAAA,QACpC,MAAM,MAAM;AAAA,MACd;AAAA,IACF;AAEA,UAAM,SAAS,YAA2B;AACxC,aAAO,MAAM;AACX,cAAM,MAAM;AACZ,YAAI,OAAO,QAAQ,OAAQ;AAC3B,cAAM,IAAI,MAAM,UAAU,QAAQ,GAAG,CAAE;AACvC,yBAAiB,EAAE;AACnB,wBAAgB,EAAE;AAClB,yBAAiB,EAAE;AACnB,aAAK,aAAa;AAAA,UAChB;AAAA,UACA,WAAW,KAAK;AAAA,UAChB,kBAAkB;AAAA,UAClB,iBAAiB;AAAA,QACnB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,UAAgC,CAAC;AACvC,aAAS,IAAI,GAAG,IAAI,KAAK,IAAI,aAAa,QAAQ,MAAM,GAAG,KAAK;AAC9D,cAAQ,KAAK,OAAO,CAAC;AAAA,IACvB;AACA,UAAM,QAAQ,IAAI,OAAO;AAMzB,QAAI,QAAQ;AACV,UAAI;AACF,cAAM,KAAK;AAAA,UACT;AAAA,UACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,MAAM,CAAC;AAAA,UACxD,CAAC;AAAA,UACD;AAAA,QACF;AAAA,MACF,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,WAAO;AAAA,MACL,mBAAmB;AAAA,MACnB,kBAAkB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,IACJ,UACA,OAAmB,CAAC,GACc;AAClC,UAAM,OAAgC,EAAE,SAAS;AACjD,QAAI,KAAK,GAAI,MAAK,UAAU,KAAK;AACjC,QAAI,KAAK,MAAO,MAAK,QAAQ,KAAK;AAClC,WAAO,KAAK,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,QAAQ,MAAM,GAAM;AAAA,EAChE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,MAAM,MAAM,MAA8C;AACxD,UAAM,OAAgC;AAAA,MACpC,SAAS,KAAK,WAAW;AAAA,MACzB,SAAS;AAAA,QACP,SAAS,KAAK,UAAU;AAAA,QACxB,WAAW,KAAK,YAAY;AAAA,MAC9B;AAAA,IACF;AACA,QAAI,KAAK,UAAW,MAAK,aAAa,KAAK;AAE3C,QAAI,KAAK,cAAe,MAAK,UAAU,EAAE,SAAS,KAAK,cAAc;AACrE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA;AAAA;AAAA,MAGA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cAA6D;AACjE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,OAAO;AAAA,MACf;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,UAAmD;AACvD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,QAAI,MAAM,QAAQ,IAAI,EAAG,QAAO;AAChC,QAAI,QAAQ,OAAO,SAAS,YAAY,SAAS,MAAM;AACrD,YAAM,MAAO,KAA2B;AACxC,UAAI,MAAM,QAAQ,GAAG,EAAG,QAAO;AAAA,IACjC;AACA,WAAO,CAAC;AAAA,EACV;AAAA;AAAA,EAGA,MAAM,SACJ,MACA,aACkC;AAClC,UAAM,OAAgC,EAAE,KAAK;AAC7C,QAAI,YAAa,MAAK,cAAc;AACpC,WAAO,KAAK,QAAQ,QAAQ,GAAG,KAAK,KAAK,CAAC,QAAQ,MAAM,IAAM;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,SAAS,MAAgD;AAC7D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,QAAQ,mBAAmB,IAAI,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBAAyD;AAC7D,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAA0C,CAAC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,gBACJ,KACA,OAAqC,CAAC,GACN;AAChC,UAAM,OAAgC,EAAE,IAAI;AAC5C,QAAI,KAAK,gBAAiB,MAAK,kBAAkB,KAAK;AACtD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cACJ,UAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UAAU,IAA8C;AAC5D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,EAAE,CAAC;AAAA,MACpD,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,WAAW,IAAkC;AACjD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,QAAQ,mBAAmB,EAAE,CAAC;AAAA,MAC5C;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAAuB,CAAC;AAAA,EACxD;AAAA;AAAA,EAGA,MAAM,UAAU,KAA8C;AAC5D,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAoC;AACxC,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC;AAAA,MACd;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAAwB,CAAC;AAAA,EACzD;AAAA;AAAA,EAGA,MAAM,UAAU,OAAmC;AACjD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAAA,MACvD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,gBAAgB,OAA0C;AAC9D,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAAA,MACvD;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAA4B,CAAC;AAAA,EAC7D;AAAA;AAAA,EAGA,MAAM,YACJ,OACA,WAC8B;AAC9B,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAAA,MACvD,EAAE,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,aAAa,OAA8B;AAC/C,UAAM,KAAK;AAAA,MACT;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAAA,MACvD;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,UACJ,IACA,UACA,OAAoC,CAAC,GACjB;AACpB,UAAM,KAAK,KAAK,gBAAgB,yBAAyB;AACzD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,QAAQ,mBAAmB,EAAE,CAAC,UAAU,mBAAmB,QAAQ,CAAC,SAAS,EAAE;AAAA,MAC7F;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,YAAY,IAAY,UAAwC;AACpE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,GAAG,KAAK,KAAK,CAAC,gBAAgB,mBAAmB,EAAE,CAAC,UAAU,mBAAmB,QAAQ,CAAC;AAAA,MAC1F;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,cACJ,IACA,GACA,OAAwB,QACiB;AACzC,UAAM,KAAK,IAAI,gBAAgB,EAAE,IAAI,GAAG,KAAK,CAAC,EAAE,SAAS;AACzD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,KAAK,eAAe,IAAI,EAAE,EAAE;AAAA,MAC5B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAA0C,CAAC;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,eACJ,IACA,UACA,OAA4C,CAAC,GACnB;AAC1B,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,KAAK,SAAS,KAAM,IAAG,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AAC1D,QAAI,KAAK,OAAQ,IAAG,IAAI,UAAU,KAAK,MAAM;AAC7C,UAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK;AACpD,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,gBAAgB,IAAI,UAAU,KAAK;AAAA,MACxC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,iBAAiB,IAAiC;AACtD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,KAAK,kBAAkB,EAAE;AAAA,MACzB;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAAsB,CAAC;AAAA,EACvD;AAAA;AAAA;AAAA,EAIA,MAAM,iBAAiB,IAAY,MAA4C;AAC7E,UAAM,KAAK,IAAI,gBAAgB,EAAE,IAAI,KAAK,CAAC,EAAE,SAAS;AACtD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,KAAK,kBAAkB,IAAI,EAAE,EAAE;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAA+B,CAAC;AAAA,EAChE;AAAA;AAAA;AAAA,EAIA,MAAM,eACJ,OAAyC,CAAC,GACZ;AAC9B,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,KAAK,GAAI,IAAG,IAAI,MAAM,KAAK,EAAE;AACjC,QAAI,KAAK,OAAQ,IAAG,IAAI,UAAU,KAAK,MAAM;AAC7C,UAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK;AACpD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,KAAK,gBAAgB,KAAK;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AACA,WAAO,MAAM,QAAQ,IAAI,IAAK,OAA+B,CAAC;AAAA,EAChE;AAAA;AAAA,EAGA,MAAM,qBAAqB,QAA4C;AACrE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,eAAe,QAAQ,SAAS;AAAA,MACrC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,MAAM,oBAAoB,QAA4C;AACpE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,eAAe,QAAQ,QAAQ;AAAA,MACpC;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA,EAIA,MAAM,mBAAmB,QAAkD;AACzE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,eAAe,QAAQ,OAAO;AAAA,MACnC,CAAC;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,kBACJ,OAAgC,CAAC,GACC;AAClC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,KAAK,mBAAmB;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAiSO,IAAM,SAAN,MAAa;AAAA,EAClB,YAA6B,QAAgB;AAAhB;AAAA,EAAiB;AAAA,EAAjB;AAAA;AAAA;AAAA,EAK7B,MAAM,MAAe,MAAmC;AACtD,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,OAAO,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAC/E;AAAA;AAAA,EAGA,IAAI,MAAe,MAAmC;AACpD,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,KAAK,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAC7E;AAAA;AAAA;AAAA,EAKA,OAAO,MAAe,MAAmC;AACvD,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,QAAQ,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAChF;AAAA;AAAA,EAGA,gBAAgB,MAAe,MAAmC;AAChE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,iBAAiB,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACzF;AAAA;AAAA,EAGA,cAAc,MAAe,MAAmC;AAC9D,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,eAAe,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA,EAKA,gBAAgB,MAAe,MAAmC;AAChE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,YAAY,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACpF;AAAA;AAAA,EAGA,WAAW,MAAmC;AAC5C,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,YAAY,GAAG,IAAI;AAAA,EACtE;AAAA;AAAA,EAGA,UAAU,OAAe,MAAmC;AAC1D,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,WAAW,KAAK,GAAG,IAAI;AAAA,EAC1E;AAAA;AAAA,EAGA,gBAAgB,OAAe,MAAmC;AAChE,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,oBAAoB,KAAK,GAAG,IAAI;AAAA,EACnF;AAAA;AAAA,EAGA,YAAY,OAAe,MAAe,MAAmC;AAC3E,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,gBAAgB,KAAK,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAC7F;AAAA;AAAA,EAGA,aAAa,OAAe,MAAmC;AAC7D,WAAO,KAAK,OAAO,WAAW,UAAU,KAAK,OAAO,WAAW,KAAK,GAAG,IAAI;AAAA,EAC7E;AAAA;AAAA;AAAA,EAKA,cAAc,MAAmC;AAC/C,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,eAAe,GAAG,IAAI;AAAA,EACzE;AAAA;AAAA,EAGA,gBAAgB,MAAe,MAAmC;AAChE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,iBAAiB,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA,EAKA,kBAAkB,MAAe,MAAmC;AAClE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,mBAAmB,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAC3F;AAAA;AAAA,EAGA,cAAc,MAAe,MAAmC;AAC9D,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,eAAe,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACvF;AAAA;AAAA;AAAA,EAKA,IAAI,MAAmC;AACrC,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,KAAK,GAAG,IAAI;AAAA,EAC/D;AAAA;AAAA,EAGA,SAAS,MAAe,MAAmC;AACzD,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,KAAK,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EAC7E;AAAA;AAAA,EAGA,SAAS,MAAc,MAAmC;AACxD,WAAO,KAAK,OAAO,WAAW,UAAU,KAAK,OAAO,IAAI,IAAI,GAAG,IAAI;AAAA,EACrE;AAAA;AAAA;AAAA,EAKA,eAAe,IAAY,UAAkB,MAAmC;AAC9E,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,gBAAgB,IAAI,QAAQ,GAAG,IAAI;AAAA,EACtF;AAAA;AAAA,EAGA,eACE,IACA,UACA,OAA4C,CAAC,GAC7C,MACmB;AACnB,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,KAAK,SAAS,KAAM,IAAG,IAAI,SAAS,OAAO,KAAK,KAAK,CAAC;AAC1D,QAAI,KAAK,OAAQ,IAAG,IAAI,UAAU,KAAK,MAAM;AAC7C,UAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK;AACpD,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,gBAAgB,IAAI,UAAU,KAAK,GAAG,IAAI;AAAA,EAC7F;AAAA;AAAA,EAGA,iBAAiB,IAAY,MAAmC;AAC9D,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,kBAAkB,EAAE,GAAG,IAAI;AAAA,EAC9E;AAAA;AAAA,EAGA,WAAW,IAAY,MAAmC;AACxD,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,YAAY,EAAE,GAAG,IAAI;AAAA,EACxE;AAAA;AAAA,EAGA,cACE,IACA,GACA,OAAwB,QACxB,MACmB;AACnB,UAAM,KAAK,IAAI,gBAAgB,EAAE,IAAI,GAAG,KAAK,CAAC,EAAE,SAAS;AACzD,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,eAAe,IAAI,EAAE,EAAE,GAAG,IAAI;AAAA,EACjF;AAAA;AAAA;AAAA,EAKA,iBAAiB,IAAY,MAAc,MAAmC;AAC5E,UAAM,KAAK,IAAI,gBAAgB,EAAE,IAAI,KAAK,CAAC,EAAE,SAAS;AACtD,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,kBAAkB,IAAI,EAAE,EAAE,GAAG,IAAI;AAAA,EACrF;AAAA;AAAA,EAGA,eAAe,OAAyC,CAAC,GAAG,MAAmC;AAC7F,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,KAAK,GAAI,IAAG,IAAI,MAAM,KAAK,EAAE;AACjC,QAAI,KAAK,OAAQ,IAAG,IAAI,UAAU,KAAK,MAAM;AAC7C,UAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,GAAG,SAAS,CAAC,KAAK;AACpD,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,gBAAgB,KAAK,GAAG,IAAI;AAAA,EAC/E;AAAA;AAAA,EAGA,oBAAoB,MAAe,MAAmC;AACpE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,gBAAgB,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACxF;AAAA;AAAA,EAGA,qBAAqB,QAAgB,MAAmC;AACtE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,eAAe,QAAQ,SAAS,GAAG,IAAI;AAAA,EAC3F;AAAA;AAAA,EAGA,oBAAoB,QAAgB,MAAmC;AACrE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,eAAe,QAAQ,QAAQ,GAAG,IAAI;AAAA,EAC1F;AAAA;AAAA,EAGA,mBAAmB,QAAgB,MAAmC;AACpE,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,eAAe,QAAQ,OAAO,GAAG,IAAI;AAAA,EACzF;AAAA;AAAA;AAAA,EAKA,aAAa,MAAe,MAAmC;AAC7D,WAAO,KAAK,OAAO,WAAW,QAAQ,KAAK,OAAO,SAAS,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC;AAAA,EACjF;AAAA;AAAA,EAGA,aAAa,UAAkB,MAAmC;AAChE,WAAO,KAAK,OAAO,WAAW,UAAU,KAAK,OAAO,QAAQ,QAAQ,GAAG,IAAI;AAAA,EAC7E;AAAA;AAAA,EAGA,QAAQ,MAAmC;AACzC,WAAO,KAAK,OAAO,WAAW,OAAO,KAAK,OAAO,SAAS,GAAG,IAAI;AAAA,EACnE;AACF;;;AC17CA,IAAM,WAAW,QAAQ,QAAQ,OAAO,KAAK,KAAK,CAAC,QAAQ,IAAI;AAE/D,SAAS,IAAI,MAAc,GAAW,OAAwB;AAC5D,SAAO,QAAQ,QAAQ,IAAI,IAAI,CAAC,YAAY;AAC9C;AAuBA,SAAS,QAAQ,OAAqB;AACpC,SAAO;AAAA,IACL,MAAM,CAAC,MAAM,IAAI,KAAK,GAAG,KAAK;AAAA,IAC9B,KAAK,CAAC,MAAM,IAAI,KAAK,GAAG,KAAK;AAAA,IAC7B,MAAM,CAAC,MAAM,IAAI,MAAM,GAAG,KAAK;AAAA,IAC/B,OAAO,CAAC,MAAM,IAAI,MAAM,GAAG,KAAK;AAAA,IAChC,KAAK,CAAC,MAAM,IAAI,MAAM,GAAG,KAAK;AAAA,IAC9B,QAAQ,CAAC,MAAM,IAAI,MAAM,GAAG,KAAK;AAAA,EACnC;AACF;AAMA,SAAS,IAAI,GAAgC;AAC3C,SAAO,OAAO,MAAM,YAAY,EAAE,SAAS,IAAI,IAAI;AACrD;AAEA,SAAS,QAAQ,GAAuB;AACtC,SAAO,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AACjC;AAEA,SAAS,SAAS,GAAqC;AACrD,SAAO,KAAK,OAAO,MAAM,YAAY,CAAC,MAAM,QAAQ,CAAC,IAChD,IACD,CAAC;AACP;AAGA,SAAS,OAAO,MAAc,KAAqB;AACjD,SAAO,KACJ,MAAM,IAAI,EACV,IAAI,CAAC,MAAO,EAAE,SAAS,MAAM,IAAI,CAAE,EACnC,KAAK,IAAI;AACd;AAOA,SAAS,oBAAoB,OAAgB,KAAkB;AAC7D,QAAM,IAAI,OAAO,UAAU,WAAW,QAAQ,OAAO,KAAK;AAC1D,MAAI,CAAC,OAAO,SAAS,CAAC,EAAG,QAAO;AAChC,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAC1C,QAAM,SAAS,KAAK,MAAM,UAAU,CAAC;AACrC,QAAM,MAAM,SAAI,OAAO,MAAM,IAAI,SAAI,OAAO,IAAI,MAAM;AACtD,QAAM,MAAM,GAAG,KAAK,MAAM,UAAU,GAAG,CAAC;AACxC,QAAM,QAAQ,GAAG,GAAG,IAAI,GAAG;AAC3B,MAAI,WAAW,KAAM,QAAO,IAAI,MAAM,KAAK;AAC3C,MAAI,WAAW,IAAK,QAAO,IAAI,OAAO,KAAK;AAC3C,SAAO,IAAI,IAAI,KAAK;AACtB;AAOA,SAAS,cAAc,MAAe,KAAkB;AACtD,QAAM,IAAI,SAAS,IAAI;AACvB,QAAM,UAAU,EAAE,cAAc,EAAE;AAClC,QAAM,SAAS,EAAE,iBAAiB,EAAE,gBAAgB,EAAE;AACtD,QAAM,OAAO,OAAO,YAAY,WAAW,UAAU,OAAO,OAAO;AACnE,QAAM,MAAM,OAAO,WAAW,WAAW,SAAS,OAAO,MAAM;AAC/D,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,SAAS,IAAI,KAAK,OAAO,GAAG;AACrC,UAAM,KAAK,GAAG,KAAK,eAAe,CAAC,aAAa,SAAS,IAAI,KAAK,GAAG,EAAE;AAAA,EACzE;AACA,MAAI,OAAO,SAAS,GAAG,KAAK,MAAM,GAAG;AACnC,UAAM,KAAK,IAAI,IAAI,QAAQ,MAAM,OAAO,IAAI,CAAC,CAAC,EAAE;AAAA,EAClD;AACA,MAAI,MAAM,OAAQ,QAAO,IAAI,OAAO,MAAM,KAAK,QAAK,CAAC;AAErD,MAAI,OAAO,KAAK,CAAC,EAAE,OAAQ,QAAO,IAAI,IAAI,MAAM;AAChD,SAAO;AACT;AAUA,SAAS,YACP,MACA,SACA,KACA,OACM;AACN,QAAM,UAAU,KAAK,IAAI,QAAQ;AACjC,MAAI,QAAQ,WAAW,EAAG;AAC1B,QAAM,OACJ,WAAW,QAAQ,SACf,UACA,MAAM;AAAA,IACJ,QAAQ,OAAoB,CAAC,KAAK,MAAM;AACtC,iBAAW,KAAK,OAAO,KAAK,CAAC,EAAG,KAAI,IAAI,CAAC;AACzC,aAAO;AAAA,IACT,GAAG,oBAAI,IAAY,CAAC;AAAA,EACtB;AACN,MAAI,KAAK,WAAW,EAAG;AAEvB,QAAM,OAAO,CAAC,GAA4B,MAAsB;AAC9D,UAAM,IAAI,EAAE,CAAC;AACb,QAAI,KAAK,KAAM,QAAO;AACtB,WAAO,OAAO,MAAM,WAAW,KAAK,UAAU,CAAC,IAAI,OAAO,CAAC;AAAA,EAC7D;AAEA,QAAM,MAAM;AACZ,QAAM,QAAQ,QAAQ,MAAM,GAAG,GAAG;AAClC,QAAM,SAAS,KAAK;AAAA,IAAI,CAAC,MACvB,KAAK,IAAI,EAAE,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC;AAAA,EAC3D;AAEA;AAAA,IACE,OACE,IAAI,KAAK,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI,CAAC,IAC5D;AAAA,EACJ;AACA,aAAW,KAAK,OAAO;AACrB;AAAA,MACE,OAAO,KAAK,IAAI,CAAC,GAAG,MAAM,KAAK,GAAG,CAAC,EAAE,OAAO,OAAO,CAAC,CAAE,CAAC,EAAE,KAAK,IAAI,IAAI;AAAA,IACxE;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,KAAK;AACxB,UAAM,OAAO,IAAI,IAAI,UAAK,QAAQ,SAAS,GAAG,cAAc,IAAI,IAAI;AAAA,EACtE;AACF;AAIA,SAAS,aACP,GACA,KACA,OACM;AAEN,QAAM,YAAY,IAAI,EAAE,SAAS,KAAK,IAAI,EAAE,MAAM,KAAK;AACvD,QAAM,SAAS,YAAY,IAAI;AAE/B,QAAM,SAAS,IAAI,EAAE,MAAM;AAC3B,MAAI,QAAQ;AACV,UAAM,SAAS,IAAI,IAAI,QAAQ,IAAI,IAAI;AACvC,UAAM,OAAO,IAAI,IAAI,MAAM,GAAG,MAAM,IAAI,IAAI;AAAA,EAC9C;AAEA,QAAM,OAAO,QAAQ,EAAE,IAAI;AAC3B,MAAI,KAAK,QAAQ;AACf,UAAM,UAAU,QAAQ,EAAE,OAAO,EAAE;AAAA,MACjC,CAAC,MAAmB,OAAO,MAAM;AAAA,IACnC;AACA,UAAM,IAAI;AACV,gBAAY,MAAM,QAAQ,SAAS,UAAU,QAAW,KAAK,KAAK;AAAA,EACpE;AACA,QAAM,IAAI;AACZ;AAEA,SAAS,cACP,GACA,KACA,OACM;AACN,QAAM,IACJ,IAAI,EAAE,QAAQ,KAAK,IAAI,EAAE,OAAO,KAAK;AACvC,QAAM,SAAS,IAAI,OAAO,GAAG,IAAI,MAAM,IAAI,MAAM;AACnD;AAEA,SAAS,WACP,GACA,KACA,OACM;AACN,QAAM,SAAS,IAAI,EAAE,OAAO,KAAK,IAAI,EAAE,MAAM,KAAK;AAClD,QAAM,QAAQ,QAAQ,EAAE,KAAK,EAAE,IAAI,QAAQ;AAC3C;AAAA,IACE,SACE,IAAI,KAAK,MAAM,IACf,OACA,IAAI,IAAI,GAAG,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,GAAG,EAAE,IAC9D,IAAI,IAAI,mBAAgB,MAAM,EAAE,IAChC;AAAA,EACJ;AACA,QAAM,QAAQ,CAAC,GAAG,MAAM;AACtB,UAAM,MAAM,IAAI,EAAE,UAAU,KAAK;AACjC,UAAM,SAAS,IAAI,EAAE,MAAM,KAAK;AAChC,UAAM,OAAO,oBAAoB,EAAE,YAAY,GAAG;AAClD,UAAM,OAAO,cAAc,EAAE,MAAM,GAAG;AACtC,UAAM,OAAO,CAAC,MAAM,IAAI,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI;AACnD;AAAA,MACE;AAAA,IAAO,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,IAAI,QAAG,CAAC,IAAI,IAAI,KAAK,MAAM,CAAC,MAC7E,OAAO,MAAM,IAAI,KAAK,MACvB;AAAA,IACJ;AACA,UAAM,YAAY,IAAI,EAAE,SAAS;AACjC,QAAI,UAAW,OAAM,UAAU,IAAI,IAAI,SAAS,IAAI,IAAI;AAAA,EAC1D,CAAC;AACD,QAAM,IAAI;AACZ;AAEA,SAAS,aACP,GACA,KACA,OACM;AACN,QAAM,QAAQ,QAAQ,EAAE,KAAK,EAAE,IAAI,QAAQ;AAC3C,QAAM,SAAS,IAAI,KAAK,QAAQ,IAAI,IAAI;AACxC,MAAI,MAAM,WAAW,GAAG;AACtB,UAAM,OAAO,IAAI,IAAI,YAAY,IAAI,MAAM;AAC3C;AAAA,EACF;AACA,aAAW,KAAK,OAAO;AAGrB,UAAM,SAAS,IAAI,EAAE,MAAM,KAAK;AAChC,UAAM,KAAK,WAAW;AACtB,UAAM,SAAS,WAAW;AAC1B,UAAM,OAAO,KAAK,IAAI,MAAM,QAAG,IAAI,SAAS,IAAI,IAAI,QAAG,IAAI,IAAI,IAAI,QAAG;AACtE,UAAM,MAAM,IAAI,EAAE,UAAU,KAAK,IAAI,EAAE,MAAM,KAAK;AAClD,UAAM,UACJ,IAAI,EAAE,OAAO,KAAK,IAAI,EAAE,KAAK,MAAM,KAAK,SAAS;AACnD,UAAM,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,KAAK,OAAO;AAAA,CAAI;AAEhD,UAAM,QAAQ,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,KAAK;AAC1C,QAAI,OAAO;AACT,YAAM,YAAY,IAAI,EAAE,UAAU,KAAK,IAAI,EAAE,SAAS;AACtD;AAAA,QACE,UACE,IAAI,IAAI,OAAO,KAAK,GAAG,YAAY,SAAM,SAAS,KAAK,EAAE,EAAE,IAC3D;AAAA,MACJ;AAAA,IACF;AAAA,EACF;AACA,QAAM,IAAI;AACZ;AAEA,SAAS,YACP,GACA,KACA,OACM;AACN,QAAM,MAAM,IAAI,EAAE,KAAK,KAAK;AAC5B,QAAM,SAAS,IAAI,EAAE,OAAO,KAAK,IAAI,EAAE,MAAM;AAC7C;AAAA,IACE,SACE,IAAI,IAAI,QAAG,IACX,MACA,OACC,SAAS,IAAI,IAAI,cAAc,MAAM,GAAG,IAAI,MAC7C;AAAA,EACJ;AACF;AAYO,SAAS,kBACd,QACA,OAAsB,CAAC,GACjB;AACN,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,OAAO,KAAK,QAAQ,QAAQ;AAClC,QAAM,QAAQ,CAAC,MAAoB;AACjC,SAAK,MAAM,CAAC;AAAA,EACd;AACA,QAAM,MAAM,QAAQ,KAAK;AAEzB,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAK;AAAA,IACxC,KAAK;AACH,aAAO,cAAc,QAAQ,KAAK,KAAK;AAAA,IACzC,KAAK;AACH,aAAO,WAAW,QAAQ,KAAK,KAAK;AAAA,IACtC,KAAK;AACH,aAAO,aAAa,QAAQ,KAAK,KAAK;AAAA,IACxC,KAAK;AACH,aAAO,YAAY,QAAQ,KAAK,KAAK;AAAA,IACvC;AAEE,YAAM,SAAS,KAAK,UAAU,MAAM,IAAI,MAAM;AAAA,EAClD;AACF;","names":["text"]}
package/dist/cli.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  Client,
4
- CographError
5
- } from "./chunk-O3L4FCRY.js";
4
+ CographError,
5
+ renderAgentResult
6
+ } from "./chunk-BJAFJGFV.js";
6
7
  import {
7
8
  configPathForDisplay,
8
9
  readConfig,
@@ -11,7 +12,7 @@ import {
11
12
 
12
13
  // src/cli.ts
13
14
  import { createInterface } from "readline";
14
- import { readFileSync } from "fs";
15
+ import { readFileSync, realpathSync } from "fs";
15
16
  import { dirname, join } from "path";
16
17
  import { fileURLToPath } from "url";
17
18
  import { Command } from "commander";
@@ -191,7 +192,7 @@ program.name("cograph").description("Cograph Knowledge Graph CLI").version(pkgVe
191
192
  "--tenant <id>",
192
193
  "Target a specific tenant for this command (overrides the saved default)"
193
194
  ).action(async (opts) => {
194
- const { runShell } = await import("./shell-ILZ322LT.js");
195
+ const { runShell } = await import("./shell-PSKIKRXO.js");
195
196
  await runShell({
196
197
  local: opts.local,
197
198
  // commander's --no-login inverts: opts.login === false when flag passed.
@@ -412,6 +413,46 @@ ${"\u2500".repeat(40)}
412
413
  });
413
414
  }
414
415
  );
416
+ async function runAgentCommand(c, message, opts) {
417
+ const context = { kgName: opts.kg, typeName: opts.type };
418
+ if (opts.confirm) {
419
+ const result2 = await c.agent({ confirmPlanId: opts.confirm, ...context });
420
+ renderAgentResult(result2);
421
+ return;
422
+ }
423
+ const result = await c.agent({ message, ...context });
424
+ renderAgentResult(result);
425
+ if (result.kind === "plan") {
426
+ const planId = typeof result.plan_id === "string" ? result.plan_id : void 0;
427
+ if (!planId) return;
428
+ if (opts.yes) {
429
+ const executed = await c.agent({ confirmPlanId: planId, ...context });
430
+ renderAgentResult(executed);
431
+ } else {
432
+ const flags = [
433
+ opts.kg ? `--kg ${opts.kg}` : "",
434
+ opts.type ? `--type ${opts.type}` : ""
435
+ ].filter(Boolean).join(" ");
436
+ const hint = `cograph agent --confirm ${planId}${flags ? " " + flags : ""} ${JSON.stringify(message)}`;
437
+ process.stdout.write(
438
+ `${dim("Confirm & run:")} ${hint}
439
+ ${dim(" or re-run with --yes to execute now.")}
440
+ `
441
+ );
442
+ }
443
+ }
444
+ }
445
+ program.command("agent <message>").description("Talk to the unified Ask-AI agent (answers, plans, and runs actions)").option("--kg <name>", "Knowledge graph to operate within").option("--type <Type>", "Active type scope (for enrich/clean/dedup planning)").option(
446
+ "-y, --yes",
447
+ "Auto-confirm and execute a returned plan in the same run"
448
+ ).option(
449
+ "--confirm <planId>",
450
+ "Execute a specific previously-proposed plan id (skips planning)"
451
+ ).action(
452
+ async (message, opts) => {
453
+ await withErrors(() => runAgentCommand(client(), message, opts));
454
+ }
455
+ );
415
456
  var onto = program.command("ontology").description("View ontology");
416
457
  onto.command("types").description("List ontology types").action(async () => {
417
458
  await withErrors(async () => {
@@ -642,7 +683,7 @@ program.command("login").description("Sign in via your browser and save an API k
642
683
  program.command("shell").description("Start an interactive REPL").option("--kg <name>", "Knowledge graph to use").option("--local", "Use http://localhost:8000 and skip login (self-hosted)").option("--no-login", "Skip browser login (assume open-access backend)").action(
643
684
  async (opts) => {
644
685
  const parentOpts = program.opts();
645
- const { runShell } = await import("./shell-ILZ322LT.js");
686
+ const { runShell } = await import("./shell-PSKIKRXO.js");
646
687
  await runShell({
647
688
  kg: opts.kg,
648
689
  local: opts.local || parentOpts.local,
@@ -650,7 +691,21 @@ program.command("shell").description("Start an interactive REPL").option("--kg <
650
691
  });
651
692
  }
652
693
  );
653
- program.parseAsync(process.argv).catch((err) => {
654
- fail(`Error: ${err instanceof Error ? err.message : String(err)}`);
655
- });
694
+ function isMainModule() {
695
+ const argv1 = process.argv[1];
696
+ if (!argv1) return false;
697
+ try {
698
+ return fileURLToPath(import.meta.url) === realpathSync(argv1);
699
+ } catch {
700
+ return false;
701
+ }
702
+ }
703
+ if (isMainModule()) {
704
+ program.parseAsync(process.argv).catch((err) => {
705
+ fail(`Error: ${err instanceof Error ? err.message : String(err)}`);
706
+ });
707
+ }
708
+ export {
709
+ runAgentCommand
710
+ };
656
711
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { Client, CographError } from \"./client.js\";\nimport { readConfig, writeConfig, configPathForDisplay } from \"./config.js\";\n\n// Read version from package.json at runtime so we never drift again.\n// dist/cli.js sits next to package.json once published; in dev (`npm link`)\n// dist/cli.js sits inside packages/cograph/dist/, so the parent dir is the\n// package root either way.\nfunction pkgVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(here, \"..\", \"package.json\"), \"utf-8\"));\n return typeof pkg.version === \"string\" ? pkg.version : \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction client(): Client {\n // Honor the global flags: --tenant overrides the saved default for this\n // command; --local points at a self-hosted backend. Both fall through to\n // env / ~/.cograph/config.json when not passed.\n const g = program.opts() as { tenant?: string; local?: boolean };\n return new Client({\n ...(g.tenant ? { tenant: g.tenant } : {}),\n ...(g.local ? { baseUrl: \"http://localhost:8000\" } : {}),\n });\n}\n\nfunction printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nfunction fail(msg: string, code = 1): never {\n process.stderr.write(msg.endsWith(\"\\n\") ? msg : msg + \"\\n\");\n process.exit(code);\n}\n\nasync function withErrors<T>(fn: () => Promise<T>): Promise<T | void> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof CographError) {\n fail(`Error: ${err.message}`);\n }\n fail(`Error: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nasync function confirm(prompt: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(`${prompt} [y/N] `, (ans) => {\n rl.close();\n resolve(ans.trim().toLowerCase() === \"y\");\n });\n });\n}\n\n/** Like confirm() but defaults to yes (used for the primary \"apply\" action). */\nasync function confirmYes(prompt: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(`${prompt} [Y/n] `, (ans) => {\n rl.close();\n const a = ans.trim().toLowerCase();\n resolve(a === \"\" || a === \"y\" || a === \"yes\");\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// CSV schema review — terminal port of the Explorer's confirm/override gate.\n// The backend applies exactly what /ingest/csv/rows is given, so the client is\n// responsible for surfacing the inferred mapping and gating held-for-review\n// type extensions before any rows are written.\n// ---------------------------------------------------------------------------\n\nconst useColor = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;\nconst sgr = (code: string) => (s: string): string =>\n useColor ? `\\x1b[${code}m${s}\\x1b[0m` : s;\nconst bold = sgr(\"1\");\nconst dim = sgr(\"2\");\n\ntype Mapping = Record<string, any>;\n\ninterface EntityView {\n name: string;\n type_name: string;\n id_column?: string | null;\n id_from?: string[] | null;\n key_strategy?: string | null;\n confidence?: number | null;\n why?: string | null;\n}\n\nfunction entityViews(m: Mapping): EntityView[] {\n if (Array.isArray(m.entities) && m.entities.length > 0) {\n return m.entities.map((e: any) => ({\n name: e.name,\n type_name: e.type_name,\n id_column: e.id_column,\n id_from: e.id_from,\n key_strategy: e.key_strategy ?? null,\n confidence: e.confidence,\n why: e.why,\n }));\n }\n return [\n {\n name: m.entity_type,\n type_name: m.entity_type,\n key_strategy: m.key_strategy ?? null,\n confidence: m.confidence,\n why: m.why,\n },\n ];\n}\n\nfunction heldTypes(m: Mapping): any[] {\n const types = m.ontology_extensions?.types;\n return Array.isArray(types) ? types.filter((t: any) => t.held_for_review) : [];\n}\n\n/** Strip response-only audit fields (violations, inference_audit, profile) and\n * keep only what /ingest/csv/rows applies. Held type extensions are dropped\n * unless explicitly approved — same gate the Explorer applies on confirm. */\nfunction buildMappingForIngest(m: Mapping, approved: Set<string>): Mapping {\n const out: Mapping = { entity_type: m.entity_type, columns: m.columns };\n if (m.entities) out.entities = m.entities;\n if (m.relationships) out.relationships = m.relationships;\n const types = m.ontology_extensions?.types;\n if (Array.isArray(types)) {\n out.ontology_extensions = {\n types: types.filter(\n (t: any) => !t.held_for_review || approved.has(t.type_name),\n ),\n };\n }\n return out;\n}\n\nfunction fmtConf(v: any): string {\n if (v == null) return \"\";\n const n = Number(v);\n if (Number.isNaN(n)) return \"\";\n return dim(` (${n.toFixed(2)}${n < 0.7 ? \" !\" : \"\"})`);\n}\n\nfunction renderMapping(\n m: Mapping,\n info: { totalRows: number; rowsProfiled: number },\n): void {\n const w = (s: string) => process.stdout.write(s);\n w(\n \"\\n\" +\n bold(\"Proposed schema\") +\n dim(\n ` (profiled ${info.rowsProfiled.toLocaleString()} of ${info.totalRows.toLocaleString()} rows)`,\n ) +\n \"\\n\",\n );\n w(dim(\"Review how the data maps to the graph before any rows are written.\") + \"\\n\\n\");\n\n const ents = entityViews(m);\n const multi = Array.isArray(m.entities) && m.entities.length > 0;\n w(bold(\"Entities & keys\") + \"\\n\");\n for (const e of ents) {\n const key = e.id_column\n ? `key: ${e.id_column}`\n : e.id_from && e.id_from.length\n ? `key: ${e.id_from.join(\" + \")}`\n : e.key_strategy === \"synthetic\"\n ? \"key: (synthetic)\"\n : \"key: —\";\n w(` • ${bold(e.type_name)} ${dim(key)}${fmtConf(e.confidence)}\\n`);\n if (e.why) w(` ${dim(e.why)}\\n`);\n const cols = (m.columns ?? []).filter((col: any) =>\n multi ? col.entity === e.name : true,\n );\n for (const col of cols) {\n const role =\n col.role === \"type_id\"\n ? \"key \"\n : col.role === \"relationship\"\n ? \"edge\"\n : \"attr\";\n let detail = \"\";\n if (col.role === \"relationship\" && col.target_type)\n detail = ` → ${col.target_type}`;\n else if (\n col.role === \"attribute\" &&\n col.attribute_name &&\n col.attribute_name !== col.column_name\n )\n detail = ` as ${col.attribute_name}`;\n const dt =\n col.datatype && col.datatype !== \"string\"\n ? \" \" + dim(`[${col.datatype}]`)\n : \"\";\n w(\n ` ${dim(\"[\" + role + \"]\")} ${col.column_name}${detail}${dt}${fmtConf(col.confidence)}\\n`,\n );\n }\n }\n\n const rels = m.relationships ?? [];\n if (rels.length) {\n w(\"\\n\" + bold(\"Edges\") + \"\\n\");\n for (const r of rels)\n w(` • ${r.subject} ${dim(r.predicate)} ${r.object}${fmtConf(r.confidence)}\\n`);\n }\n\n const vio = m.violations ?? [];\n if (vio.length) {\n w(\n \"\\n\" +\n dim(\n `Refute pass corrected ${vio.length} issue${vio.length === 1 ? \"\" : \"s\"}: ${vio\n .map((v: any) => v.template)\n .join(\", \")}`,\n ) +\n \"\\n\",\n );\n }\n}\n\n/** Interactive confirm/override gate, passed to client.ingest as\n * onSchemaInferred. Returns the mapping to ingest, or null to cancel. */\nasync function reviewMapping(\n m: Mapping,\n info: { totalRows: number; rowsProfiled: number },\n): Promise<Mapping | null> {\n renderMapping(m, info);\n const approved = new Set<string>();\n const held = heldTypes(m);\n if (held.length) {\n process.stdout.write(\n \"\\n\" +\n bold(`${held.length} new type${held.length === 1 ? \"\" : \"s\"} held for review`) +\n dim(\" — approve to create, or skip to leave for later\") +\n \"\\n\",\n );\n for (const t of held) {\n const from = t.promoted_from_attribute\n ? dim(` (from \"${t.promoted_from_attribute}\")`)\n : \"\";\n process.stdout.write(` • ${t.type_name}${from}${fmtConf(t.confidence)}\\n`);\n if (await confirm(` Approve \"${t.type_name}\"?`)) approved.add(t.type_name);\n }\n }\n process.stdout.write(\"\\n\");\n const ok = await confirmYes(\n `Apply this mapping and ingest ${info.totalRows.toLocaleString()} rows?`,\n );\n if (!ok) return null;\n return buildMappingForIngest(m, approved);\n}\n\nconst program = new Command();\nprogram\n .name(\"cograph\")\n .description(\"Cograph Knowledge Graph CLI\")\n .version(pkgVersion())\n // Default action when no subcommand is given: drop into the interactive\n // shell. So `cograph` (or `npx cograph`) Just Works for the common case;\n // subcommands like `cograph ingest <file>` still route to their own\n // actions because commander dispatches subcommands first.\n .option(\"--local\", \"Use http://localhost:8000 and skip login (self-hosted)\")\n .option(\"--no-login\", \"Skip browser login (assume open-access backend)\")\n .option(\n \"--tenant <id>\",\n \"Target a specific tenant for this command (overrides the saved default)\",\n )\n .action(async (opts: { local?: boolean; login?: boolean }) => {\n const { runShell } = await import(\"./shell.js\");\n await runShell({\n local: opts.local,\n // commander's --no-login inverts: opts.login === false when flag passed.\n noLogin: opts.login === false,\n });\n });\n\n// ---------------------------------------------------------------------------\n// kg\n// ---------------------------------------------------------------------------\n\nconst kg = program.command(\"kg\").description(\"Manage knowledge graphs\");\n\nkg.command(\"list\")\n .description(\"List knowledge graphs\")\n .action(async () => {\n await withErrors(async () => {\n const kgs = await client().listKgs();\n if (!kgs.length) {\n process.stdout.write(\n \"No knowledge graphs. Create one with: cograph kg create <name>\\n\",\n );\n return;\n }\n for (const k of kgs) {\n const name = String(k.name ?? \"?\");\n const triples = Number(k.triple_count ?? 0);\n const desc = k.description ? ` — ${k.description}` : \"\";\n const padName = name.padEnd(20, \" \");\n const padTriples = String(triples).padStart(6, \" \");\n process.stdout.write(` ${padName} ${padTriples} triples${desc}\\n`);\n }\n });\n });\n\nkg.command(\"create <name>\")\n .description(\"Create a knowledge graph\")\n .option(\"-d, --description <text>\", \"Description\")\n .action(async (name: string, opts: { description?: string }) => {\n await withErrors(async () => {\n const created = await client().createKg(name, opts.description);\n process.stdout.write(`Created knowledge graph: ${created.name ?? name}\\n`);\n });\n });\n\nkg.command(\"delete <name>\")\n .description(\"Delete a knowledge graph\")\n .action(async (name: string) => {\n await withErrors(async () => {\n await client().deleteKg(name);\n process.stdout.write(`Deleted knowledge graph: ${name}\\n`);\n });\n });\n\n// ---------------------------------------------------------------------------\n// tenant\n// ---------------------------------------------------------------------------\n\nconst tenantCmd = program\n .command(\"tenant\")\n .description(\"Show or switch the active tenant\");\n\ntenantCmd\n .command(\"current\", { isDefault: true })\n .description(\"Show the active tenant\")\n .action(() => {\n const active = client().tenant;\n const saved = readConfig().tenant;\n process.stdout.write(`Active tenant: ${bold(active)}\\n`);\n process.stdout.write(\n saved\n ? dim(` saved default in ${configPathForDisplay()}\\n`)\n : dim(` (built-in default — set one with: cograph tenant use <id>)\\n`),\n );\n });\n\ntenantCmd\n .command(\"list\")\n .description(\"List the tenants you can access\")\n .action(async () => {\n await withErrors(async () => {\n const c = client();\n let tenants: Array<{ id: string; label: string }>;\n try {\n tenants = await c.listTenants();\n } catch (err) {\n if (err instanceof CographError && err.status === 501) {\n fail(\n \"This backend doesn't support tenant management (no tenant provider configured).\",\n );\n }\n throw err;\n }\n if (!tenants.length) {\n process.stdout.write(\"No tenants found for your account.\\n\");\n return;\n }\n const active = c.tenant;\n for (const t of tenants) {\n const marker = t.id === active ? \"*\" : \" \";\n process.stdout.write(` ${marker} ${t.id.padEnd(24)} ${dim(t.label)}\\n`);\n }\n process.stdout.write(dim(`\\nSwitch with: cograph tenant use <id>\\n`));\n });\n });\n\ntenantCmd\n .command(\"use <id>\")\n .description(\"Set the active tenant (saved to ~/.cograph/config.json)\")\n .action((id: string) => {\n writeConfig({ tenant: id });\n process.stdout.write(`${bold(\"✓\")} Active tenant set to ${bold(id)}\\n`);\n process.stdout.write(dim(`Saved to ${configPathForDisplay()}\\n`));\n });\n\n// ---------------------------------------------------------------------------\n// ingest\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"ingest [file]\")\n .description(\"Ingest data from a file or --text\")\n .option(\"-t, --text <text>\", \"Inline text to ingest\")\n .option(\"--kg <name>\", \"Target knowledge graph name\")\n .option(\n \"-f, --format <fmt>\",\n \"Override format detection (text|csv|json)\",\n )\n .option(\n \"-y, --yes\",\n \"Skip the CSV schema review and apply the inferred mapping non-interactively\",\n )\n .action(\n async (\n file: string | undefined,\n opts: { text?: string; kg?: string; format?: string; yes?: boolean },\n ) => {\n await withErrors(async () => {\n const c = client();\n if (opts.text) {\n process.stdout.write(\n `Ingesting text (${opts.text.length.toLocaleString()} chars)...\\n`,\n );\n const result = await c.ingest(opts.text, {\n kg: opts.kg,\n contentType: opts.format ?? \"text\",\n });\n printIngestResult(result);\n return;\n }\n if (!file) {\n fail(\"Provide a file or --text\");\n }\n // For CSV, interpose the same schema review/confirm gate the Explorer\n // shows. Interactive on a TTY unless --yes; otherwise apply the\n // inferred mapping as-is (held type extensions auto-approved, matching\n // the prior non-interactive behavior). Hook is ignored for text/json.\n const interactive =\n Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY) && !opts.yes;\n const onSchemaInferred = interactive\n ? reviewMapping\n : (m: Mapping) =>\n Promise.resolve(\n buildMappingForIngest(\n m,\n new Set(heldTypes(m).map((t: any) => t.type_name)),\n ),\n );\n // ingest() handles file reading + format detection + CSV two-step flow.\n process.stdout.write(`Ingesting ${file}...\\n`);\n const result = await c.ingest(file, {\n kg: opts.kg,\n contentType: opts.format,\n onSchemaInferred,\n });\n if ((result as Record<string, unknown>).cancelled) {\n process.stdout.write(\"Cancelled — nothing was written.\\n\");\n return;\n }\n printIngestResult(result);\n });\n },\n );\n\nfunction printIngestResult(result: Record<string, unknown>): void {\n const num = (k: string) => Number(result[k] ?? 0);\n process.stdout.write(` Entities extracted: ${num(\"entities_extracted\")}\\n`);\n process.stdout.write(` Entities resolved: ${num(\"entities_resolved\")}\\n`);\n process.stdout.write(` Triples inserted: ${num(\"triples_inserted\")}\\n`);\n const types = result.types_created;\n if (Array.isArray(types) && types.length) {\n process.stdout.write(` Types created: ${types.join(\", \")}\\n`);\n }\n const rejections = result.rejections;\n if (Array.isArray(rejections) && rejections.length) {\n process.stdout.write(` Rejections: ${rejections.length}\\n`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// ask\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"ask <question>\")\n .description(\"Ask a natural language question\")\n .option(\"--kg <name>\", \"Knowledge graph to query\")\n .option(\"-d, --debug\", \"Show SPARQL and latency breakdown\")\n .option(\"-m, --model <model>\", \"Override query model\")\n .action(\n async (\n question: string,\n opts: { kg?: string; debug?: boolean; model?: string },\n ) => {\n await withErrors(async () => {\n if (opts.model) process.stdout.write(`Model: ${opts.model}\\n`);\n process.stdout.write(`Q: ${question}\\n`);\n process.stdout.write(\"Generating answer...\\n\");\n const t0 = Date.now();\n const result = await client().ask(question, {\n kg: opts.kg,\n model: opts.model,\n });\n const roundtripMs = Date.now() - t0;\n process.stdout.write(`\\nA: ${result.answer ?? \"No answer\"}\\n`);\n if (opts.debug) {\n process.stdout.write(`\\nSPARQL:\\n${result.sparql ?? \"\"}\\n`);\n const timing = (result.timing ?? {}) as Record<string, unknown>;\n if (Object.keys(timing).length) {\n process.stdout.write(`\\n${\"─\".repeat(40)}\\n`);\n process.stdout.write(\n `${\"Stage\".padEnd(25)} ${\"Time\".padStart(10)}\\n`,\n );\n process.stdout.write(`${\"─\".repeat(40)}\\n`);\n for (const [key, val] of Object.entries(timing)) {\n if (key === \"attempts\") {\n process.stdout.write(\n `${\"Attempts\".padEnd(25)} ${String(val).padStart(10)}\\n`,\n );\n } else if (typeof val === \"string\") {\n const label = key\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n process.stdout.write(\n `${label.padEnd(25)} ${val.padStart(10)}\\n`,\n );\n } else {\n const label = key\n .replace(/_ms$/, \"\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n const num = typeof val === \"number\" ? val : Number(val);\n process.stdout.write(\n `${label.padEnd(25)} ${num.toFixed(1).padStart(8)}ms\\n`,\n );\n }\n }\n process.stdout.write(`${\"─\".repeat(40)}\\n`);\n process.stdout.write(\n `${\"Client roundtrip\".padEnd(25)} ${roundtripMs.toFixed(1).padStart(8)}ms\\n`,\n );\n }\n }\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// ontology\n// ---------------------------------------------------------------------------\n\nconst onto = program.command(\"ontology\").description(\"View ontology\");\n\nonto\n .command(\"types\")\n .description(\"List ontology types\")\n .action(async () => {\n await withErrors(async () => {\n const types = await client().ontologyTypes();\n if (!types.length) {\n process.stdout.write(\"No ontology types defined.\\n\");\n return;\n }\n for (const t of types) {\n const parent = t.parent_type\n ? ` (subClassOf ${t.parent_type})`\n : \"\";\n const desc = t.description ? ` — ${t.description}` : \"\";\n process.stdout.write(` ${t.name}${parent}${desc}\\n`);\n const attrs = (t.attributes ?? []) as Array<Record<string, unknown>>;\n for (const a of attrs) {\n process.stdout.write(\n ` .${a.name} (${a.datatype ?? \"string\"})\\n`,\n );\n }\n }\n });\n });\n\n// ---------------------------------------------------------------------------\n// er — entity resolution\n// ---------------------------------------------------------------------------\n\nconst er = program.command(\"er\").description(\"Entity resolution\");\n\ner.command(\"rebuild\")\n .description(\n \"Second pass: collapse intra-batch entity fragments in an ingested KG\",\n )\n .requiredOption(\"--kg <name>\", \"Knowledge graph to rebuild\")\n .action(async (opts: { kg: string }) => {\n await withErrors(async () => {\n process.stdout.write(`Rebuilding entity resolution for ${opts.kg}…\\n`);\n const report = await client().erRebuild(opts.kg);\n const types = (report.types ?? []) as Array<Record<string, unknown>>;\n for (const t of types) {\n const name = String(t.type ?? \"?\").padEnd(16, \" \");\n process.stdout.write(\n ` ${name} ${t.entities_before} → ${t.entities_after}` +\n ` (−${t.fragments_absorbed} fragments across ${t.clusters_merged} clusters)\\n`,\n );\n }\n process.stdout.write(\n `Done. ${report.fragments_absorbed_total ?? 0} fragments absorbed.\\n`,\n );\n });\n });\n\n// ---------------------------------------------------------------------------\n// enrich\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"enrich\")\n .description(\"Agentic enrichment — fill an attribute from web sources, with citations\")\n .requiredOption(\"--kg <name>\", \"Knowledge graph\")\n .requiredOption(\"--type <Type>\", \"Entity type to enrich\")\n .requiredOption(\"--attribute <attr>\", \"Attribute to fill (e.g. reviews, description)\")\n .option(\"--tier <tier>\", \"lite | base | core | pro (paid adapters live in core/pro)\", \"core\")\n .option(\"--limit <n>\", \"Max entities to enrich\", \"3\")\n .option(\"--apply\", \"Write results to the graph (with provenance), not just stage\")\n .action(\n async (opts: {\n kg: string;\n type: string;\n attribute: string;\n tier: string;\n limit: string;\n apply?: boolean;\n }) => {\n await withErrors(async () => {\n const c = client();\n process.stdout.write(\n `Enriching ${opts.type}.${opts.attribute} in ${opts.kg} (tier ${opts.tier})…\\n`,\n );\n const created = await c.enrichRun({\n kg_name: opts.kg,\n type_name: opts.type,\n attributes: [opts.attribute],\n tier: opts.tier as \"lite\" | \"base\" | \"core\" | \"pro\",\n limit: Number(opts.limit),\n conflict_policy: opts.apply ? \"overwrite\" : \"stage\",\n confidence_min: 0.1,\n });\n const terminal = [\"applied\", \"review\", \"failed\", \"cancelled\"];\n let job = await c.enrichJob(created.job_id);\n for (let i = 0; i < 40 && !terminal.includes(job.status); i++) {\n await new Promise((r) => setTimeout(r, 2000));\n job = await c.enrichJob(created.job_id);\n }\n const filled = (job.results ?? []).filter((r) => r.verdict);\n if (!filled.length) {\n process.stdout.write(\"No enrichment results (no source returned a value).\\n\");\n return;\n }\n for (const r of filled) {\n const v = r.verdict!;\n process.stdout.write(`\\n ${r.entity_uri.split(\"/\").pop()}\\n`);\n process.stdout.write(` ${r.attribute}: ${v.value}\\n`);\n process.stdout.write(\n ` source: ${v.source}${v.source_url ? \" \" + v.source_url : \"\"}\\n`,\n );\n if (v.reasoning) process.stdout.write(` ${v.reasoning}\\n`);\n }\n process.stdout.write(\n `\\n${opts.apply ? \"Applied to the graph (value + provenance triples).\" : \"Staged for review — re-run with --apply to write.\"}\\n`,\n );\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// vis\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"vis <type>\")\n .description(\"Visualise a type — instance count, attribute coverage, top relations\")\n .option(\"--kg <name>\", \"Knowledge graph to inspect\")\n .action(async (typeName: string, opts: { kg?: string }) => {\n await withErrors(async () => {\n const c = client();\n\n // Resolve KG: use --kg flag, or pick first available KG.\n let kg = opts.kg;\n if (!kg) {\n const kgs = await c.listKgs();\n if (!kgs.length) {\n fail(\"No knowledge graphs found. Run 'cograph ingest' first.\");\n }\n kg = String(kgs[0].name ?? \"\");\n }\n\n let summary: import(\"./client.js\").TypeSummary;\n try {\n summary = await c.typeSummary(kg, typeName);\n } catch {\n fail(`Type '${typeName}' not found in KG '${kg}'.`);\n }\n\n const { entity_count, attributes, relationships, description, parent_type } = summary;\n const header = `${typeName}${parent_type ? ` (subClassOf ${parent_type})` : \"\"} — ${entity_count.toLocaleString()} instances`;\n process.stdout.write(`\\n${header}\\n${\"─\".repeat(header.length)}\\n`);\n if (description) process.stdout.write(`${description}\\n`);\n\n // Attributes table\n if (attributes.length) {\n process.stdout.write(`\\nAttributes (${attributes.length}):\\n`);\n const sorted = [...attributes].sort((a, b) => b.coverage_pct - a.coverage_pct);\n for (const a of sorted.slice(0, 10)) {\n const bar = \"█\".repeat(Math.round(a.coverage_pct / 10));\n const pct = `${a.coverage_pct}%`.padStart(6);\n process.stdout.write(` ${a.name.padEnd(24)} ${pct} ${bar}\\n`);\n }\n if (attributes.length > 10) {\n process.stdout.write(` … and ${attributes.length - 10} more\\n`);\n }\n }\n\n // Relations table\n if (relationships.length) {\n process.stdout.write(`\\nRelationships (${relationships.length}):\\n`);\n for (const r of relationships.slice(0, 8)) {\n const target = r.target_type ? ` → ${r.target_type}` : \"\";\n const pct = `${r.coverage_pct}%`.padStart(6);\n const avg = r.avg_degree ? ` (avg ${r.avg_degree})` : \"\";\n process.stdout.write(` ${(r.name + target).padEnd(36)} ${pct}${avg}\\n`);\n }\n }\n\n const explorerUrl = `https://cograph.cloud/dashboard/explore/${encodeURIComponent(typeName)}?kg=${encodeURIComponent(kg)}`;\n process.stdout.write(`\\n→ Open visually at ${explorerUrl}\\n`);\n process.stdout.write(\" (Sign in for interactive viz, search, and click-to-enrich.)\\n\\n\");\n });\n });\n\n// ---------------------------------------------------------------------------\n// clear\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"clear\")\n .description(\"Clear data\")\n .option(\"--kg <name>\", \"Clear a specific knowledge graph\")\n .option(\n \"--include-ontology\",\n \"Also clear the ontology (only meaningful when --kg is omitted)\",\n false,\n )\n .option(\"-y, --yes\", \"Skip confirmation\", false)\n .action(\n async (opts: { kg?: string; includeOntology?: boolean; yes?: boolean }) => {\n await withErrors(async () => {\n let msg: string;\n if (opts.kg) {\n msg = `Clear KG '${opts.kg}'?`;\n } else if (opts.includeOntology) {\n msg = \"Clear EVERYTHING including ontology?\";\n } else {\n msg = \"Clear all instance data (ontology preserved)?\";\n }\n\n if (!opts.yes) {\n const ok = await confirm(msg);\n if (!ok) {\n process.stdout.write(\"Cancelled.\\n\");\n return;\n }\n }\n\n const c = client();\n if (opts.kg) {\n await c.deleteKg(opts.kg);\n process.stdout.write(`Cleared KG: ${opts.kg}\\n`);\n return;\n }\n\n // Bulk-clear via /query + DELETE /triples — same loop the Python CLI uses.\n const tenant = c.tenant;\n const baseUrl = `${c.baseUrl}/graphs/${tenant}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (c.apiKey) headers[\"X-API-Key\"] = c.apiKey;\n\n const filters = opts.includeOntology\n ? \"\"\n : `FILTER(CONTAINS(STR(?s), '/entities/') || CONTAINS(STR(?s), '/onto/') || CONTAINS(STR(?s), '/kgs/'))`;\n const query = `SELECT ?s ?p ?o FROM <https://cograph.tech/graphs/${tenant}> WHERE { ?s ?p ?o . ${filters} } LIMIT 1000`;\n\n process.stdout.write(\"Clearing...\\n\");\n let deleted = 0;\n for (let i = 0; i < 50; i++) {\n const fetchRes = await fetch(`${baseUrl}/query`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ query }),\n });\n if (!fetchRes.ok) break;\n const data = (await fetchRes.json()) as {\n bindings?: Array<Record<string, unknown>>;\n };\n const bindings = data.bindings ?? [];\n if (!bindings.length) break;\n const triples = bindings\n .filter((b) => b.s)\n .map((b) => ({\n subject: b.s,\n predicate: b.p,\n object: b.o,\n }));\n for (let j = 0; j < triples.length; j += 100) {\n await fetch(`${baseUrl}/triples`, {\n method: \"DELETE\",\n headers,\n body: JSON.stringify({ triples: triples.slice(j, j + 100) }),\n });\n }\n deleted += triples.length;\n }\n process.stdout.write(`Deleted ${deleted} triples\\n`);\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// login\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"login\")\n .description(\"Sign in via your browser and save an API key\")\n .action(async () => {\n const { runLogin } = await import(\"./login.js\");\n await runLogin();\n });\n\n// ---------------------------------------------------------------------------\n// shell\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"shell\")\n .description(\"Start an interactive REPL\")\n .option(\"--kg <name>\", \"Knowledge graph to use\")\n .option(\"--local\", \"Use http://localhost:8000 and skip login (self-hosted)\")\n .option(\"--no-login\", \"Skip browser login (assume open-access backend)\")\n .action(\n async (opts: { kg?: string; local?: boolean; login?: boolean }) => {\n // Parent program also accepts --local/--no-login (so `cograph --local`\n // works without a subcommand). When commander parses\n // `cograph shell --local`, the parent sees --local first and the\n // subcommand never gets it — so merge from program.opts() too.\n const parentOpts = program.opts() as {\n local?: boolean;\n login?: boolean;\n };\n const { runShell } = await import(\"./shell.js\");\n await runShell({\n kg: opts.kg,\n local: opts.local || parentOpts.local,\n noLogin: opts.login === false || parentOpts.login === false,\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n\nprogram.parseAsync(process.argv).catch((err) => {\n fail(`Error: ${err instanceof Error ? err.message : String(err)}`);\n});\n\n// silence unused import warning if ever needed\nvoid printJson;\n"],"mappings":"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","names":["result","kg"]}
1
+ {"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import { createInterface } from \"node:readline\";\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { Command } from \"commander\";\nimport { Client, CographError } from \"./client.js\";\nimport { renderAgentResult } from \"./agentRender.js\";\nimport { readConfig, writeConfig, configPathForDisplay } from \"./config.js\";\n\n// Read version from package.json at runtime so we never drift again.\n// dist/cli.js sits next to package.json once published; in dev (`npm link`)\n// dist/cli.js sits inside packages/cograph/dist/, so the parent dir is the\n// package root either way.\nfunction pkgVersion(): string {\n try {\n const here = dirname(fileURLToPath(import.meta.url));\n const pkg = JSON.parse(readFileSync(join(here, \"..\", \"package.json\"), \"utf-8\"));\n return typeof pkg.version === \"string\" ? pkg.version : \"0.0.0\";\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction client(): Client {\n // Honor the global flags: --tenant overrides the saved default for this\n // command; --local points at a self-hosted backend. Both fall through to\n // env / ~/.cograph/config.json when not passed.\n const g = program.opts() as { tenant?: string; local?: boolean };\n return new Client({\n ...(g.tenant ? { tenant: g.tenant } : {}),\n ...(g.local ? { baseUrl: \"http://localhost:8000\" } : {}),\n });\n}\n\nfunction printJson(data: unknown): void {\n process.stdout.write(JSON.stringify(data, null, 2) + \"\\n\");\n}\n\nfunction fail(msg: string, code = 1): never {\n process.stderr.write(msg.endsWith(\"\\n\") ? msg : msg + \"\\n\");\n process.exit(code);\n}\n\nasync function withErrors<T>(fn: () => Promise<T>): Promise<T | void> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof CographError) {\n fail(`Error: ${err.message}`);\n }\n fail(`Error: ${err instanceof Error ? err.message : String(err)}`);\n }\n}\n\nasync function confirm(prompt: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(`${prompt} [y/N] `, (ans) => {\n rl.close();\n resolve(ans.trim().toLowerCase() === \"y\");\n });\n });\n}\n\n/** Like confirm() but defaults to yes (used for the primary \"apply\" action). */\nasync function confirmYes(prompt: string): Promise<boolean> {\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n return new Promise((resolve) => {\n rl.question(`${prompt} [Y/n] `, (ans) => {\n rl.close();\n const a = ans.trim().toLowerCase();\n resolve(a === \"\" || a === \"y\" || a === \"yes\");\n });\n });\n}\n\n// ---------------------------------------------------------------------------\n// CSV schema review — terminal port of the Explorer's confirm/override gate.\n// The backend applies exactly what /ingest/csv/rows is given, so the client is\n// responsible for surfacing the inferred mapping and gating held-for-review\n// type extensions before any rows are written.\n// ---------------------------------------------------------------------------\n\nconst useColor = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;\nconst sgr = (code: string) => (s: string): string =>\n useColor ? `\\x1b[${code}m${s}\\x1b[0m` : s;\nconst bold = sgr(\"1\");\nconst dim = sgr(\"2\");\n\ntype Mapping = Record<string, any>;\n\ninterface EntityView {\n name: string;\n type_name: string;\n id_column?: string | null;\n id_from?: string[] | null;\n key_strategy?: string | null;\n confidence?: number | null;\n why?: string | null;\n}\n\nfunction entityViews(m: Mapping): EntityView[] {\n if (Array.isArray(m.entities) && m.entities.length > 0) {\n return m.entities.map((e: any) => ({\n name: e.name,\n type_name: e.type_name,\n id_column: e.id_column,\n id_from: e.id_from,\n key_strategy: e.key_strategy ?? null,\n confidence: e.confidence,\n why: e.why,\n }));\n }\n return [\n {\n name: m.entity_type,\n type_name: m.entity_type,\n key_strategy: m.key_strategy ?? null,\n confidence: m.confidence,\n why: m.why,\n },\n ];\n}\n\nfunction heldTypes(m: Mapping): any[] {\n const types = m.ontology_extensions?.types;\n return Array.isArray(types) ? types.filter((t: any) => t.held_for_review) : [];\n}\n\n/** Strip response-only audit fields (violations, inference_audit, profile) and\n * keep only what /ingest/csv/rows applies. Held type extensions are dropped\n * unless explicitly approved — same gate the Explorer applies on confirm. */\nfunction buildMappingForIngest(m: Mapping, approved: Set<string>): Mapping {\n const out: Mapping = { entity_type: m.entity_type, columns: m.columns };\n if (m.entities) out.entities = m.entities;\n if (m.relationships) out.relationships = m.relationships;\n const types = m.ontology_extensions?.types;\n if (Array.isArray(types)) {\n out.ontology_extensions = {\n types: types.filter(\n (t: any) => !t.held_for_review || approved.has(t.type_name),\n ),\n };\n }\n return out;\n}\n\nfunction fmtConf(v: any): string {\n if (v == null) return \"\";\n const n = Number(v);\n if (Number.isNaN(n)) return \"\";\n return dim(` (${n.toFixed(2)}${n < 0.7 ? \" !\" : \"\"})`);\n}\n\nfunction renderMapping(\n m: Mapping,\n info: { totalRows: number; rowsProfiled: number },\n): void {\n const w = (s: string) => process.stdout.write(s);\n w(\n \"\\n\" +\n bold(\"Proposed schema\") +\n dim(\n ` (profiled ${info.rowsProfiled.toLocaleString()} of ${info.totalRows.toLocaleString()} rows)`,\n ) +\n \"\\n\",\n );\n w(dim(\"Review how the data maps to the graph before any rows are written.\") + \"\\n\\n\");\n\n const ents = entityViews(m);\n const multi = Array.isArray(m.entities) && m.entities.length > 0;\n w(bold(\"Entities & keys\") + \"\\n\");\n for (const e of ents) {\n const key = e.id_column\n ? `key: ${e.id_column}`\n : e.id_from && e.id_from.length\n ? `key: ${e.id_from.join(\" + \")}`\n : e.key_strategy === \"synthetic\"\n ? \"key: (synthetic)\"\n : \"key: —\";\n w(` • ${bold(e.type_name)} ${dim(key)}${fmtConf(e.confidence)}\\n`);\n if (e.why) w(` ${dim(e.why)}\\n`);\n const cols = (m.columns ?? []).filter((col: any) =>\n multi ? col.entity === e.name : true,\n );\n for (const col of cols) {\n const role =\n col.role === \"type_id\"\n ? \"key \"\n : col.role === \"relationship\"\n ? \"edge\"\n : \"attr\";\n let detail = \"\";\n if (col.role === \"relationship\" && col.target_type)\n detail = ` → ${col.target_type}`;\n else if (\n col.role === \"attribute\" &&\n col.attribute_name &&\n col.attribute_name !== col.column_name\n )\n detail = ` as ${col.attribute_name}`;\n const dt =\n col.datatype && col.datatype !== \"string\"\n ? \" \" + dim(`[${col.datatype}]`)\n : \"\";\n w(\n ` ${dim(\"[\" + role + \"]\")} ${col.column_name}${detail}${dt}${fmtConf(col.confidence)}\\n`,\n );\n }\n }\n\n const rels = m.relationships ?? [];\n if (rels.length) {\n w(\"\\n\" + bold(\"Edges\") + \"\\n\");\n for (const r of rels)\n w(` • ${r.subject} ${dim(r.predicate)} ${r.object}${fmtConf(r.confidence)}\\n`);\n }\n\n const vio = m.violations ?? [];\n if (vio.length) {\n w(\n \"\\n\" +\n dim(\n `Refute pass corrected ${vio.length} issue${vio.length === 1 ? \"\" : \"s\"}: ${vio\n .map((v: any) => v.template)\n .join(\", \")}`,\n ) +\n \"\\n\",\n );\n }\n}\n\n/** Interactive confirm/override gate, passed to client.ingest as\n * onSchemaInferred. Returns the mapping to ingest, or null to cancel. */\nasync function reviewMapping(\n m: Mapping,\n info: { totalRows: number; rowsProfiled: number },\n): Promise<Mapping | null> {\n renderMapping(m, info);\n const approved = new Set<string>();\n const held = heldTypes(m);\n if (held.length) {\n process.stdout.write(\n \"\\n\" +\n bold(`${held.length} new type${held.length === 1 ? \"\" : \"s\"} held for review`) +\n dim(\" — approve to create, or skip to leave for later\") +\n \"\\n\",\n );\n for (const t of held) {\n const from = t.promoted_from_attribute\n ? dim(` (from \"${t.promoted_from_attribute}\")`)\n : \"\";\n process.stdout.write(` • ${t.type_name}${from}${fmtConf(t.confidence)}\\n`);\n if (await confirm(` Approve \"${t.type_name}\"?`)) approved.add(t.type_name);\n }\n }\n process.stdout.write(\"\\n\");\n const ok = await confirmYes(\n `Apply this mapping and ingest ${info.totalRows.toLocaleString()} rows?`,\n );\n if (!ok) return null;\n return buildMappingForIngest(m, approved);\n}\n\nconst program = new Command();\nprogram\n .name(\"cograph\")\n .description(\"Cograph Knowledge Graph CLI\")\n .version(pkgVersion())\n // Default action when no subcommand is given: drop into the interactive\n // shell. So `cograph` (or `npx cograph`) Just Works for the common case;\n // subcommands like `cograph ingest <file>` still route to their own\n // actions because commander dispatches subcommands first.\n .option(\"--local\", \"Use http://localhost:8000 and skip login (self-hosted)\")\n .option(\"--no-login\", \"Skip browser login (assume open-access backend)\")\n .option(\n \"--tenant <id>\",\n \"Target a specific tenant for this command (overrides the saved default)\",\n )\n .action(async (opts: { local?: boolean; login?: boolean }) => {\n const { runShell } = await import(\"./shell.js\");\n await runShell({\n local: opts.local,\n // commander's --no-login inverts: opts.login === false when flag passed.\n noLogin: opts.login === false,\n });\n });\n\n// ---------------------------------------------------------------------------\n// kg\n// ---------------------------------------------------------------------------\n\nconst kg = program.command(\"kg\").description(\"Manage knowledge graphs\");\n\nkg.command(\"list\")\n .description(\"List knowledge graphs\")\n .action(async () => {\n await withErrors(async () => {\n const kgs = await client().listKgs();\n if (!kgs.length) {\n process.stdout.write(\n \"No knowledge graphs. Create one with: cograph kg create <name>\\n\",\n );\n return;\n }\n for (const k of kgs) {\n const name = String(k.name ?? \"?\");\n const triples = Number(k.triple_count ?? 0);\n const desc = k.description ? ` — ${k.description}` : \"\";\n const padName = name.padEnd(20, \" \");\n const padTriples = String(triples).padStart(6, \" \");\n process.stdout.write(` ${padName} ${padTriples} triples${desc}\\n`);\n }\n });\n });\n\nkg.command(\"create <name>\")\n .description(\"Create a knowledge graph\")\n .option(\"-d, --description <text>\", \"Description\")\n .action(async (name: string, opts: { description?: string }) => {\n await withErrors(async () => {\n const created = await client().createKg(name, opts.description);\n process.stdout.write(`Created knowledge graph: ${created.name ?? name}\\n`);\n });\n });\n\nkg.command(\"delete <name>\")\n .description(\"Delete a knowledge graph\")\n .action(async (name: string) => {\n await withErrors(async () => {\n await client().deleteKg(name);\n process.stdout.write(`Deleted knowledge graph: ${name}\\n`);\n });\n });\n\n// ---------------------------------------------------------------------------\n// tenant\n// ---------------------------------------------------------------------------\n\nconst tenantCmd = program\n .command(\"tenant\")\n .description(\"Show or switch the active tenant\");\n\ntenantCmd\n .command(\"current\", { isDefault: true })\n .description(\"Show the active tenant\")\n .action(() => {\n const active = client().tenant;\n const saved = readConfig().tenant;\n process.stdout.write(`Active tenant: ${bold(active)}\\n`);\n process.stdout.write(\n saved\n ? dim(` saved default in ${configPathForDisplay()}\\n`)\n : dim(` (built-in default — set one with: cograph tenant use <id>)\\n`),\n );\n });\n\ntenantCmd\n .command(\"list\")\n .description(\"List the tenants you can access\")\n .action(async () => {\n await withErrors(async () => {\n const c = client();\n let tenants: Array<{ id: string; label: string }>;\n try {\n tenants = await c.listTenants();\n } catch (err) {\n if (err instanceof CographError && err.status === 501) {\n fail(\n \"This backend doesn't support tenant management (no tenant provider configured).\",\n );\n }\n throw err;\n }\n if (!tenants.length) {\n process.stdout.write(\"No tenants found for your account.\\n\");\n return;\n }\n const active = c.tenant;\n for (const t of tenants) {\n const marker = t.id === active ? \"*\" : \" \";\n process.stdout.write(` ${marker} ${t.id.padEnd(24)} ${dim(t.label)}\\n`);\n }\n process.stdout.write(dim(`\\nSwitch with: cograph tenant use <id>\\n`));\n });\n });\n\ntenantCmd\n .command(\"use <id>\")\n .description(\"Set the active tenant (saved to ~/.cograph/config.json)\")\n .action((id: string) => {\n writeConfig({ tenant: id });\n process.stdout.write(`${bold(\"✓\")} Active tenant set to ${bold(id)}\\n`);\n process.stdout.write(dim(`Saved to ${configPathForDisplay()}\\n`));\n });\n\n// ---------------------------------------------------------------------------\n// ingest\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"ingest [file]\")\n .description(\"Ingest data from a file or --text\")\n .option(\"-t, --text <text>\", \"Inline text to ingest\")\n .option(\"--kg <name>\", \"Target knowledge graph name\")\n .option(\n \"-f, --format <fmt>\",\n \"Override format detection (text|csv|json)\",\n )\n .option(\n \"-y, --yes\",\n \"Skip the CSV schema review and apply the inferred mapping non-interactively\",\n )\n .action(\n async (\n file: string | undefined,\n opts: { text?: string; kg?: string; format?: string; yes?: boolean },\n ) => {\n await withErrors(async () => {\n const c = client();\n if (opts.text) {\n process.stdout.write(\n `Ingesting text (${opts.text.length.toLocaleString()} chars)...\\n`,\n );\n const result = await c.ingest(opts.text, {\n kg: opts.kg,\n contentType: opts.format ?? \"text\",\n });\n printIngestResult(result);\n return;\n }\n if (!file) {\n fail(\"Provide a file or --text\");\n }\n // For CSV, interpose the same schema review/confirm gate the Explorer\n // shows. Interactive on a TTY unless --yes; otherwise apply the\n // inferred mapping as-is (held type extensions auto-approved, matching\n // the prior non-interactive behavior). Hook is ignored for text/json.\n const interactive =\n Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY) && !opts.yes;\n const onSchemaInferred = interactive\n ? reviewMapping\n : (m: Mapping) =>\n Promise.resolve(\n buildMappingForIngest(\n m,\n new Set(heldTypes(m).map((t: any) => t.type_name)),\n ),\n );\n // ingest() handles file reading + format detection + CSV two-step flow.\n process.stdout.write(`Ingesting ${file}...\\n`);\n const result = await c.ingest(file, {\n kg: opts.kg,\n contentType: opts.format,\n onSchemaInferred,\n });\n if ((result as Record<string, unknown>).cancelled) {\n process.stdout.write(\"Cancelled — nothing was written.\\n\");\n return;\n }\n printIngestResult(result);\n });\n },\n );\n\nfunction printIngestResult(result: Record<string, unknown>): void {\n const num = (k: string) => Number(result[k] ?? 0);\n process.stdout.write(` Entities extracted: ${num(\"entities_extracted\")}\\n`);\n process.stdout.write(` Entities resolved: ${num(\"entities_resolved\")}\\n`);\n process.stdout.write(` Triples inserted: ${num(\"triples_inserted\")}\\n`);\n const types = result.types_created;\n if (Array.isArray(types) && types.length) {\n process.stdout.write(` Types created: ${types.join(\", \")}\\n`);\n }\n const rejections = result.rejections;\n if (Array.isArray(rejections) && rejections.length) {\n process.stdout.write(` Rejections: ${rejections.length}\\n`);\n }\n}\n\n// ---------------------------------------------------------------------------\n// ask\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"ask <question>\")\n .description(\"Ask a natural language question\")\n .option(\"--kg <name>\", \"Knowledge graph to query\")\n .option(\"-d, --debug\", \"Show SPARQL and latency breakdown\")\n .option(\"-m, --model <model>\", \"Override query model\")\n .action(\n async (\n question: string,\n opts: { kg?: string; debug?: boolean; model?: string },\n ) => {\n await withErrors(async () => {\n if (opts.model) process.stdout.write(`Model: ${opts.model}\\n`);\n process.stdout.write(`Q: ${question}\\n`);\n process.stdout.write(\"Generating answer...\\n\");\n const t0 = Date.now();\n const result = await client().ask(question, {\n kg: opts.kg,\n model: opts.model,\n });\n const roundtripMs = Date.now() - t0;\n process.stdout.write(`\\nA: ${result.answer ?? \"No answer\"}\\n`);\n if (opts.debug) {\n process.stdout.write(`\\nSPARQL:\\n${result.sparql ?? \"\"}\\n`);\n const timing = (result.timing ?? {}) as Record<string, unknown>;\n if (Object.keys(timing).length) {\n process.stdout.write(`\\n${\"─\".repeat(40)}\\n`);\n process.stdout.write(\n `${\"Stage\".padEnd(25)} ${\"Time\".padStart(10)}\\n`,\n );\n process.stdout.write(`${\"─\".repeat(40)}\\n`);\n for (const [key, val] of Object.entries(timing)) {\n if (key === \"attempts\") {\n process.stdout.write(\n `${\"Attempts\".padEnd(25)} ${String(val).padStart(10)}\\n`,\n );\n } else if (typeof val === \"string\") {\n const label = key\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n process.stdout.write(\n `${label.padEnd(25)} ${val.padStart(10)}\\n`,\n );\n } else {\n const label = key\n .replace(/_ms$/, \"\")\n .replace(/_/g, \" \")\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n const num = typeof val === \"number\" ? val : Number(val);\n process.stdout.write(\n `${label.padEnd(25)} ${num.toFixed(1).padStart(8)}ms\\n`,\n );\n }\n }\n process.stdout.write(`${\"─\".repeat(40)}\\n`);\n process.stdout.write(\n `${\"Client roundtrip\".padEnd(25)} ${roundtripMs.toFixed(1).padStart(8)}ms\\n`,\n );\n }\n }\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// agent — unified Ask-AI agent (POST /graphs/{tenant}/agent)\n// ---------------------------------------------------------------------------\n//\n// The ONE command that reaches the unified agent the web app + MCP already use:\n// it classifies intent server-side (question | enrich | clean | dedup |\n// ontology) and either answers, asks a clarifying question, or proposes a plan\n// to confirm. The discrete commands (ask/enrich/er/ontology) stay as\n// convenient shortcuts; migrating them onto the agent is a deliberate non-goal.\n//\n// Confirm flow (non-interactive): a returned plan is NOT executed automatically.\n// Either re-run with --confirm <plan_id> (the only mutating path), or pass --yes\n// to confirm-and-execute in the same invocation.\n\n/**\n * Core of the `agent` command — extracted so it's unit-testable with a mocked\n * {@link Client} (the commander action below just builds a real client and\n * delegates). Drives the three non-interactive paths:\n * - `--confirm <id>` → execute that plan directly, render the result.\n * - default → one agent turn, render it; if it's a plan, either\n * confirm-and-execute (`--yes`) or print a confirm hint.\n *\n * Exported for tests; not part of the published SDK surface (cli.ts is the bin\n * entry, not in `package.json#exports`).\n */\nexport async function runAgentCommand(\n c: Client,\n message: string,\n opts: { kg?: string; type?: string; yes?: boolean; confirm?: string },\n): Promise<void> {\n // KG resolution mirrors `ask`: an explicit --kg wins, else the SDK's\n // saved/default kg (passing undefined lets the backend use its default).\n const context = { kgName: opts.kg, typeName: opts.type };\n\n // --confirm path: execute the named plan directly and render the result.\n if (opts.confirm) {\n const result = await c.agent({ confirmPlanId: opts.confirm, ...context });\n renderAgentResult(result);\n return;\n }\n\n const result = await c.agent({ message, ...context });\n renderAgentResult(result);\n\n // A plan is the only kind that awaits a follow-up. With --yes we confirm\n // immediately; otherwise we print how to confirm it later.\n if (result.kind === \"plan\") {\n const planId =\n typeof result.plan_id === \"string\" ? result.plan_id : undefined;\n if (!planId) return;\n if (opts.yes) {\n const executed = await c.agent({ confirmPlanId: planId, ...context });\n renderAgentResult(executed);\n } else {\n const flags = [\n opts.kg ? `--kg ${opts.kg}` : \"\",\n opts.type ? `--type ${opts.type}` : \"\",\n ]\n .filter(Boolean)\n .join(\" \");\n const hint = `cograph agent --confirm ${planId}${flags ? \" \" + flags : \"\"} ${JSON.stringify(message)}`;\n process.stdout.write(\n `${dim(\"Confirm & run:\")} ${hint}\\n` +\n `${dim(\" or re-run with --yes to execute now.\")}\\n`,\n );\n }\n }\n}\n\nprogram\n .command(\"agent <message>\")\n .description(\"Talk to the unified Ask-AI agent (answers, plans, and runs actions)\")\n .option(\"--kg <name>\", \"Knowledge graph to operate within\")\n .option(\"--type <Type>\", \"Active type scope (for enrich/clean/dedup planning)\")\n .option(\n \"-y, --yes\",\n \"Auto-confirm and execute a returned plan in the same run\",\n )\n .option(\n \"--confirm <planId>\",\n \"Execute a specific previously-proposed plan id (skips planning)\",\n )\n .action(\n async (\n message: string,\n opts: { kg?: string; type?: string; yes?: boolean; confirm?: string },\n ) => {\n await withErrors(() => runAgentCommand(client(), message, opts));\n },\n );\n\n// ---------------------------------------------------------------------------\n// ontology\n// ---------------------------------------------------------------------------\n\nconst onto = program.command(\"ontology\").description(\"View ontology\");\n\nonto\n .command(\"types\")\n .description(\"List ontology types\")\n .action(async () => {\n await withErrors(async () => {\n const types = await client().ontologyTypes();\n if (!types.length) {\n process.stdout.write(\"No ontology types defined.\\n\");\n return;\n }\n for (const t of types) {\n const parent = t.parent_type\n ? ` (subClassOf ${t.parent_type})`\n : \"\";\n const desc = t.description ? ` — ${t.description}` : \"\";\n process.stdout.write(` ${t.name}${parent}${desc}\\n`);\n const attrs = (t.attributes ?? []) as Array<Record<string, unknown>>;\n for (const a of attrs) {\n process.stdout.write(\n ` .${a.name} (${a.datatype ?? \"string\"})\\n`,\n );\n }\n }\n });\n });\n\n// ---------------------------------------------------------------------------\n// er — entity resolution\n// ---------------------------------------------------------------------------\n\nconst er = program.command(\"er\").description(\"Entity resolution\");\n\ner.command(\"rebuild\")\n .description(\n \"Second pass: collapse intra-batch entity fragments in an ingested KG\",\n )\n .requiredOption(\"--kg <name>\", \"Knowledge graph to rebuild\")\n .action(async (opts: { kg: string }) => {\n await withErrors(async () => {\n process.stdout.write(`Rebuilding entity resolution for ${opts.kg}…\\n`);\n const report = await client().erRebuild(opts.kg);\n const types = (report.types ?? []) as Array<Record<string, unknown>>;\n for (const t of types) {\n const name = String(t.type ?? \"?\").padEnd(16, \" \");\n process.stdout.write(\n ` ${name} ${t.entities_before} → ${t.entities_after}` +\n ` (−${t.fragments_absorbed} fragments across ${t.clusters_merged} clusters)\\n`,\n );\n }\n process.stdout.write(\n `Done. ${report.fragments_absorbed_total ?? 0} fragments absorbed.\\n`,\n );\n });\n });\n\n// ---------------------------------------------------------------------------\n// enrich\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"enrich\")\n .description(\"Agentic enrichment — fill an attribute from web sources, with citations\")\n .requiredOption(\"--kg <name>\", \"Knowledge graph\")\n .requiredOption(\"--type <Type>\", \"Entity type to enrich\")\n .requiredOption(\"--attribute <attr>\", \"Attribute to fill (e.g. reviews, description)\")\n .option(\"--tier <tier>\", \"lite | base | core | pro (paid adapters live in core/pro)\", \"core\")\n .option(\"--limit <n>\", \"Max entities to enrich\", \"3\")\n .option(\"--apply\", \"Write results to the graph (with provenance), not just stage\")\n .action(\n async (opts: {\n kg: string;\n type: string;\n attribute: string;\n tier: string;\n limit: string;\n apply?: boolean;\n }) => {\n await withErrors(async () => {\n const c = client();\n process.stdout.write(\n `Enriching ${opts.type}.${opts.attribute} in ${opts.kg} (tier ${opts.tier})…\\n`,\n );\n const created = await c.enrichRun({\n kg_name: opts.kg,\n type_name: opts.type,\n attributes: [opts.attribute],\n tier: opts.tier as \"lite\" | \"base\" | \"core\" | \"pro\",\n limit: Number(opts.limit),\n conflict_policy: opts.apply ? \"overwrite\" : \"stage\",\n confidence_min: 0.1,\n });\n const terminal = [\"applied\", \"review\", \"failed\", \"cancelled\"];\n let job = await c.enrichJob(created.job_id);\n for (let i = 0; i < 40 && !terminal.includes(job.status); i++) {\n await new Promise((r) => setTimeout(r, 2000));\n job = await c.enrichJob(created.job_id);\n }\n const filled = (job.results ?? []).filter((r) => r.verdict);\n if (!filled.length) {\n process.stdout.write(\"No enrichment results (no source returned a value).\\n\");\n return;\n }\n for (const r of filled) {\n const v = r.verdict!;\n process.stdout.write(`\\n ${r.entity_uri.split(\"/\").pop()}\\n`);\n process.stdout.write(` ${r.attribute}: ${v.value}\\n`);\n process.stdout.write(\n ` source: ${v.source}${v.source_url ? \" \" + v.source_url : \"\"}\\n`,\n );\n if (v.reasoning) process.stdout.write(` ${v.reasoning}\\n`);\n }\n process.stdout.write(\n `\\n${opts.apply ? \"Applied to the graph (value + provenance triples).\" : \"Staged for review — re-run with --apply to write.\"}\\n`,\n );\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// vis\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"vis <type>\")\n .description(\"Visualise a type — instance count, attribute coverage, top relations\")\n .option(\"--kg <name>\", \"Knowledge graph to inspect\")\n .action(async (typeName: string, opts: { kg?: string }) => {\n await withErrors(async () => {\n const c = client();\n\n // Resolve KG: use --kg flag, or pick first available KG.\n let kg = opts.kg;\n if (!kg) {\n const kgs = await c.listKgs();\n if (!kgs.length) {\n fail(\"No knowledge graphs found. Run 'cograph ingest' first.\");\n }\n kg = String(kgs[0].name ?? \"\");\n }\n\n let summary: import(\"./client.js\").TypeSummary;\n try {\n summary = await c.typeSummary(kg, typeName);\n } catch {\n fail(`Type '${typeName}' not found in KG '${kg}'.`);\n }\n\n const { entity_count, attributes, relationships, description, parent_type } = summary;\n const header = `${typeName}${parent_type ? ` (subClassOf ${parent_type})` : \"\"} — ${entity_count.toLocaleString()} instances`;\n process.stdout.write(`\\n${header}\\n${\"─\".repeat(header.length)}\\n`);\n if (description) process.stdout.write(`${description}\\n`);\n\n // Attributes table\n if (attributes.length) {\n process.stdout.write(`\\nAttributes (${attributes.length}):\\n`);\n const sorted = [...attributes].sort((a, b) => b.coverage_pct - a.coverage_pct);\n for (const a of sorted.slice(0, 10)) {\n const bar = \"█\".repeat(Math.round(a.coverage_pct / 10));\n const pct = `${a.coverage_pct}%`.padStart(6);\n process.stdout.write(` ${a.name.padEnd(24)} ${pct} ${bar}\\n`);\n }\n if (attributes.length > 10) {\n process.stdout.write(` … and ${attributes.length - 10} more\\n`);\n }\n }\n\n // Relations table\n if (relationships.length) {\n process.stdout.write(`\\nRelationships (${relationships.length}):\\n`);\n for (const r of relationships.slice(0, 8)) {\n const target = r.target_type ? ` → ${r.target_type}` : \"\";\n const pct = `${r.coverage_pct}%`.padStart(6);\n const avg = r.avg_degree ? ` (avg ${r.avg_degree})` : \"\";\n process.stdout.write(` ${(r.name + target).padEnd(36)} ${pct}${avg}\\n`);\n }\n }\n\n const explorerUrl = `https://cograph.cloud/dashboard/explore/${encodeURIComponent(typeName)}?kg=${encodeURIComponent(kg)}`;\n process.stdout.write(`\\n→ Open visually at ${explorerUrl}\\n`);\n process.stdout.write(\" (Sign in for interactive viz, search, and click-to-enrich.)\\n\\n\");\n });\n });\n\n// ---------------------------------------------------------------------------\n// clear\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"clear\")\n .description(\"Clear data\")\n .option(\"--kg <name>\", \"Clear a specific knowledge graph\")\n .option(\n \"--include-ontology\",\n \"Also clear the ontology (only meaningful when --kg is omitted)\",\n false,\n )\n .option(\"-y, --yes\", \"Skip confirmation\", false)\n .action(\n async (opts: { kg?: string; includeOntology?: boolean; yes?: boolean }) => {\n await withErrors(async () => {\n let msg: string;\n if (opts.kg) {\n msg = `Clear KG '${opts.kg}'?`;\n } else if (opts.includeOntology) {\n msg = \"Clear EVERYTHING including ontology?\";\n } else {\n msg = \"Clear all instance data (ontology preserved)?\";\n }\n\n if (!opts.yes) {\n const ok = await confirm(msg);\n if (!ok) {\n process.stdout.write(\"Cancelled.\\n\");\n return;\n }\n }\n\n const c = client();\n if (opts.kg) {\n await c.deleteKg(opts.kg);\n process.stdout.write(`Cleared KG: ${opts.kg}\\n`);\n return;\n }\n\n // Bulk-clear via /query + DELETE /triples — same loop the Python CLI uses.\n const tenant = c.tenant;\n const baseUrl = `${c.baseUrl}/graphs/${tenant}`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n };\n if (c.apiKey) headers[\"X-API-Key\"] = c.apiKey;\n\n const filters = opts.includeOntology\n ? \"\"\n : `FILTER(CONTAINS(STR(?s), '/entities/') || CONTAINS(STR(?s), '/onto/') || CONTAINS(STR(?s), '/kgs/'))`;\n const query = `SELECT ?s ?p ?o FROM <https://cograph.tech/graphs/${tenant}> WHERE { ?s ?p ?o . ${filters} } LIMIT 1000`;\n\n process.stdout.write(\"Clearing...\\n\");\n let deleted = 0;\n for (let i = 0; i < 50; i++) {\n const fetchRes = await fetch(`${baseUrl}/query`, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ query }),\n });\n if (!fetchRes.ok) break;\n const data = (await fetchRes.json()) as {\n bindings?: Array<Record<string, unknown>>;\n };\n const bindings = data.bindings ?? [];\n if (!bindings.length) break;\n const triples = bindings\n .filter((b) => b.s)\n .map((b) => ({\n subject: b.s,\n predicate: b.p,\n object: b.o,\n }));\n for (let j = 0; j < triples.length; j += 100) {\n await fetch(`${baseUrl}/triples`, {\n method: \"DELETE\",\n headers,\n body: JSON.stringify({ triples: triples.slice(j, j + 100) }),\n });\n }\n deleted += triples.length;\n }\n process.stdout.write(`Deleted ${deleted} triples\\n`);\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n// login\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"login\")\n .description(\"Sign in via your browser and save an API key\")\n .action(async () => {\n const { runLogin } = await import(\"./login.js\");\n await runLogin();\n });\n\n// ---------------------------------------------------------------------------\n// shell\n// ---------------------------------------------------------------------------\n\nprogram\n .command(\"shell\")\n .description(\"Start an interactive REPL\")\n .option(\"--kg <name>\", \"Knowledge graph to use\")\n .option(\"--local\", \"Use http://localhost:8000 and skip login (self-hosted)\")\n .option(\"--no-login\", \"Skip browser login (assume open-access backend)\")\n .action(\n async (opts: { kg?: string; local?: boolean; login?: boolean }) => {\n // Parent program also accepts --local/--no-login (so `cograph --local`\n // works without a subcommand). When commander parses\n // `cograph shell --local`, the parent sees --local first and the\n // subcommand never gets it — so merge from program.opts() too.\n const parentOpts = program.opts() as {\n local?: boolean;\n login?: boolean;\n };\n const { runShell } = await import(\"./shell.js\");\n await runShell({\n kg: opts.kg,\n local: opts.local || parentOpts.local,\n noLogin: opts.login === false || parentOpts.login === false,\n });\n },\n );\n\n// ---------------------------------------------------------------------------\n\n/** True when this module is the process entry point (run as `cograph …`), not\n * when it's imported (e.g. by the unit tests that exercise `runAgentCommand`).\n * Guards the auto-parse so importing the module has no side effects.\n *\n * npm installs the `bin` as a SYMLINK (node_modules/.bin/cograph →\n * dist/cli.js). Node sets import.meta.url to the *realpath* of the entry file\n * while process.argv[1] keeps the *symlink* path, so a naive href comparison\n * never matches and the CLI silently does nothing. Resolve the symlink first:\n * compare fileURLToPath(import.meta.url) against realpathSync(process.argv[1]).\n */\nfunction isMainModule(): boolean {\n const argv1 = process.argv[1];\n if (!argv1) return false;\n try {\n return fileURLToPath(import.meta.url) === realpathSync(argv1);\n } catch {\n return false;\n }\n}\n\nif (isMainModule()) {\n program.parseAsync(process.argv).catch((err) => {\n fail(`Error: ${err instanceof Error ? err.message : String(err)}`);\n });\n}\n\n// silence unused import warning if ever needed\nvoid printJson;\n"],"mappings":"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","names":["result","kg"]}