cograph 0.1.27 → 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.
- package/dist/{chunk-PE2EOIGT.js → chunk-BJAFJGFV.js} +190 -2
- package/dist/chunk-BJAFJGFV.js.map +1 -0
- package/dist/cli.js +63 -8
- package/dist/cli.js.map +1 -1
- package/dist/{shell-A5UU33YS.js → shell-PSKIKRXO.js} +62 -4
- package/dist/shell-PSKIKRXO.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-PE2EOIGT.js.map +0 -1
- package/dist/shell-A5UU33YS.js.map +0 -1
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"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
Client,
|
|
4
|
-
CographError
|
|
5
|
-
|
|
4
|
+
CographError,
|
|
5
|
+
renderAgentResult
|
|
6
|
+
} from "./chunk-BJAFJGFV.js";
|
|
6
7
|
import {
|
|
7
8
|
writeConfig
|
|
8
9
|
} from "./chunk-7VVBEUZQ.js";
|
|
@@ -10,6 +11,7 @@ import {
|
|
|
10
11
|
// src/shell.ts
|
|
11
12
|
import * as readline from "readline";
|
|
12
13
|
import { stdin, stdout } from "process";
|
|
14
|
+
import { randomUUID } from "crypto";
|
|
13
15
|
var CYAN = "\x1B[36m";
|
|
14
16
|
var CYAN_BOLD = "\x1B[1;36m";
|
|
15
17
|
var DIM = "\x1B[2m";
|
|
@@ -55,6 +57,7 @@ function showCommands() {
|
|
|
55
57
|
const rows = [
|
|
56
58
|
["/ingest <file> ...", "Ingest a CSV/JSON/text file"],
|
|
57
59
|
["/ask <question>", "Ask in natural language"],
|
|
60
|
+
["/agent <message>", "Unified Ask-AI agent \u2014 answers, plans, runs actions"],
|
|
58
61
|
["/kg list", "List your knowledge graphs"],
|
|
59
62
|
["/kg switch <name>", "Switch to a different KG"],
|
|
60
63
|
["/kg create <name>", "Create a new KG and switch to it"],
|
|
@@ -237,6 +240,49 @@ async function cmdAsk(client, kg, question) {
|
|
|
237
240
|
else printError(err instanceof Error ? err.message : String(err));
|
|
238
241
|
}
|
|
239
242
|
}
|
|
243
|
+
async function cmdAgent(client, kg, rl, sessionId, message) {
|
|
244
|
+
const msg = message.trim();
|
|
245
|
+
if (!msg) {
|
|
246
|
+
stdout.write(` ${YELLOW}Usage:${RESET} /agent <your message>
|
|
247
|
+
`);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
const context = { kgName: kg, sessionId };
|
|
251
|
+
const sp = startSpinner("Thinking...");
|
|
252
|
+
let result;
|
|
253
|
+
try {
|
|
254
|
+
result = await client.agent({ message: msg, ...context });
|
|
255
|
+
} catch (err) {
|
|
256
|
+
sp.stop();
|
|
257
|
+
if (err instanceof CographError) printError(err.message);
|
|
258
|
+
else printError(err instanceof Error ? err.message : String(err));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
sp.stop();
|
|
262
|
+
renderAgentResult(result);
|
|
263
|
+
if (result.kind === "plan") {
|
|
264
|
+
const planId = typeof result.plan_id === "string" ? result.plan_id : void 0;
|
|
265
|
+
if (!planId) return;
|
|
266
|
+
const ans = (await ask(rl, ` ${YELLOW}Confirm & run?${RESET} [y/N]: `)).trim().toLowerCase();
|
|
267
|
+
if (ans !== "y" && ans !== "yes") {
|
|
268
|
+
stdout.write(` ${DIM}Not run. Plan ${planId} kept.${RESET}
|
|
269
|
+
`);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const sp2 = startSpinner("Running plan...");
|
|
273
|
+
let executed;
|
|
274
|
+
try {
|
|
275
|
+
executed = await client.agent({ confirmPlanId: planId, ...context });
|
|
276
|
+
} catch (err) {
|
|
277
|
+
sp2.stop();
|
|
278
|
+
if (err instanceof CographError) printError(err.message);
|
|
279
|
+
else printError(err instanceof Error ? err.message : String(err));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
sp2.stop();
|
|
283
|
+
renderAgentResult(executed);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
240
286
|
async function cmdStatus(client, kg) {
|
|
241
287
|
try {
|
|
242
288
|
const info = await fetchKg(client, kg);
|
|
@@ -875,6 +921,7 @@ async function runShell(opts) {
|
|
|
875
921
|
`
|
|
876
922
|
);
|
|
877
923
|
}
|
|
924
|
+
const agentSessionId = randomUUID();
|
|
878
925
|
let kg = opts.kg;
|
|
879
926
|
if (!kg) {
|
|
880
927
|
const picked = await selectKg(client, rl);
|
|
@@ -935,6 +982,17 @@ async function runShell(opts) {
|
|
|
935
982
|
await cmdAsk(client, kg, line.slice("/ask ".length));
|
|
936
983
|
} else if (line === "/ask") {
|
|
937
984
|
await cmdAsk(client, kg, "");
|
|
985
|
+
} else if (line.startsWith("/agent ")) {
|
|
986
|
+
await cmdAgent(
|
|
987
|
+
client,
|
|
988
|
+
kg,
|
|
989
|
+
rl,
|
|
990
|
+
agentSessionId,
|
|
991
|
+
line.slice("/agent ".length)
|
|
992
|
+
);
|
|
993
|
+
await refresh();
|
|
994
|
+
} else if (line === "/agent") {
|
|
995
|
+
await cmdAgent(client, kg, rl, agentSessionId, "");
|
|
938
996
|
} else if (line === "/types" || line.startsWith("/types ")) {
|
|
939
997
|
const query = line === "/types" ? "" : line.slice("/types ".length);
|
|
940
998
|
await cmdTypes(client, kg, query);
|
|
@@ -1143,7 +1201,7 @@ async function runShell(opts) {
|
|
|
1143
1201
|
}
|
|
1144
1202
|
} else if (line.startsWith("/")) {
|
|
1145
1203
|
stdout.write(
|
|
1146
|
-
` ${YELLOW}Unknown command.${RESET} Try /ingest, /ask, /kg, /types, /type, /enrich, /login, /status, /reset, /help, /quit
|
|
1204
|
+
` ${YELLOW}Unknown command.${RESET} Try /ingest, /ask, /agent, /kg, /types, /type, /enrich, /login, /status, /reset, /help, /quit
|
|
1147
1205
|
`
|
|
1148
1206
|
);
|
|
1149
1207
|
} else {
|
|
@@ -1159,4 +1217,4 @@ async function runShell(opts) {
|
|
|
1159
1217
|
export {
|
|
1160
1218
|
runShell
|
|
1161
1219
|
};
|
|
1162
|
-
//# sourceMappingURL=shell-
|
|
1220
|
+
//# sourceMappingURL=shell-PSKIKRXO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/shell.ts"],"sourcesContent":["import * as readline from \"node:readline\";\nimport { stdin, stdout } from \"node:process\";\nimport { randomUUID } from \"node:crypto\";\nimport {\n Client,\n CographError,\n type TypeCount,\n type EnrichJob,\n type ConflictReview,\n type JobSummary,\n} from \"./client.js\";\nimport { renderAgentResult } from \"./agentRender.js\";\nimport { writeConfig } from \"./config.js\";\n\nconst CYAN = \"\\x1b[36m\";\nconst CYAN_BOLD = \"\\x1b[1;36m\";\nconst DIM = \"\\x1b[2m\";\nconst RED = \"\\x1b[31m\";\nconst GREEN = \"\\x1b[32m\";\nconst YELLOW = \"\\x1b[33m\";\nconst BOLD = \"\\x1b[1m\";\nconst RESET = \"\\x1b[0m\";\n\nfunction fmtNum(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\nfunction canRenderBlockArt(): boolean {\n // Apple_Terminal (macOS Terminal.app) treats the block-shade chars (▀█░)\n // we use in the banner as East Asian Ambiguous Width = 2 cells, so each\n // 28-char banner row renders as ~56 cells and wraps mid-letter. iTerm,\n // WezTerm, Kitty, VS Code, Cursor, etc. all treat them as 1 cell and\n // render the art correctly. Skip the banner on Apple_Terminal and show\n // a plain header instead. Force on/off via COGRAPH_BANNER=on|off.\n const force = process.env.COGRAPH_BANNER;\n if (force === \"on\") return true;\n if (force === \"off\") return false;\n if (!process.stdout.isTTY) return false;\n if (process.env.TERM_PROGRAM === \"Apple_Terminal\") return false;\n return true;\n}\n\nfunction showBanner(): void {\n if (canRenderBlockArt()) {\n const lines = [\n \"\",\n `${CYAN} ░█▀▀░█▀█░█▀▀░█▀▄░█▀█░█▀█░█░█${RESET}`,\n `${CYAN} ░█░░░█░█░█░█░█▀▄░█▀█░█▀▀░█▀█${RESET}`,\n `${CYAN} ░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░▀░░░▀░▀${RESET}`,\n \"\",\n `${DIM} The object graph for AI agents${RESET}`,\n \"\",\n ];\n for (const l of lines) stdout.write(l + \"\\n\");\n } else {\n stdout.write(`\\n ${CYAN_BOLD}cograph${RESET}\\n`);\n stdout.write(` ${DIM}The object graph for AI agents${RESET}\\n\\n`);\n }\n showCommands();\n}\n\nfunction showCommands(): void {\n const rows: Array<[string, string]> = [\n [\"/ingest <file> ...\", \"Ingest a CSV/JSON/text file\"],\n [\"/ask <question>\", \"Ask in natural language\"],\n [\"/agent <message>\", \"Unified Ask-AI agent — answers, plans, runs actions\"],\n [\"/kg list\", \"List your knowledge graphs\"],\n [\"/kg switch <name>\", \"Switch to a different KG\"],\n [\"/kg create <name>\", \"Create a new KG and switch to it\"],\n [\"/kg delete <name>\", \"Delete a KG (irreversible)\"],\n [\"/tenant list\", \"List tenants you can access\"],\n [\"/tenant use <id>\", \"Switch tenant (then pick a KG)\"],\n [\"/types [query]\", \"List types in the current KG (with entity counts)\"],\n [\"/type <name>\", \"Drill into one type — attributes, relationships, samples\"],\n [\"/type <name> --system\", \"…also include auto-attached system attributes\"],\n [\"/enrich <Type> <attr> ...\", \"Plan + run an enrichment job (interactive)\"],\n [\"/enrich watch <job_id>\", \"Live progress for a running job\"],\n [\"/enrich jobs\", \"List recent enrichment jobs\"],\n [\"/enrich review <job_id>\", \"Walk through conflicts and accept/reject\"],\n [\"/login\", \"Re-authenticate (browser)\"],\n [\"/status\", \"Show graph stats\"],\n [\"/reset\", \"Clear the current KG\"],\n [\"/help\", \"Show this command list\"],\n [\"/quit\", \"Exit\"],\n ];\n const colWidth = Math.max(...rows.map((r) => r[0].length));\n for (const [cmd, desc] of rows) {\n const pad = \" \".repeat(colWidth - cmd.length);\n stdout.write(` ${CYAN_BOLD}${cmd}${RESET}${pad} ${DIM}${desc}${RESET}\\n`);\n }\n stdout.write(\"\\n\");\n}\n\nfunction printError(msg: string): void {\n stdout.write(` ${RED}✗${RESET} ${msg}\\n`);\n}\n\ninterface KgInfo {\n name: string;\n triple_count: number;\n}\n\nasync function fetchKg(client: Client, name: string): Promise<KgInfo | null> {\n try {\n const kgs = await client.listKgs();\n const found = kgs.find((k) => (k as { name?: string }).name === name);\n if (!found) return null;\n const tc = (found as { triple_count?: number }).triple_count ?? 0;\n return { name, triple_count: typeof tc === \"number\" ? tc : 0 };\n } catch {\n return null;\n }\n}\n\nfunction ask(rl: readline.Interface, prompt: string): Promise<string> {\n return new Promise((resolve) => {\n rl.question(prompt, (answer) => resolve(answer));\n });\n}\n\nasync function selectKg(\n client: Client,\n rl: readline.Interface,\n): Promise<string | null> {\n let kgs: Array<Record<string, unknown>> = [];\n try {\n kgs = await client.listKgs();\n } catch (err) {\n printError(\n `Could not list knowledge graphs: ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n\n if (kgs.length === 0) {\n stdout.write(\n ` ${DIM}No knowledge graphs found. Enter a name to create your first KG.${RESET}\\n`,\n );\n const name = (await ask(rl, \" KG name: \")).trim();\n if (!name) return null;\n // Persist immediately. Without this, the name only existed as a local\n // string until the user ran /ingest, so quitting before ingesting lost\n // the KG entirely — and the next shell session showed \"No KGs found\"\n // again.\n try {\n await client.createKg(name);\n stdout.write(` ${GREEN}✓${RESET} Created ${BOLD}${name}${RESET}\\n`);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n // 409 / \"already exists\" is fine — someone created it between listKgs\n // and now, or the user retried. Anything else is a real failure.\n if (!/already exists|409/i.test(msg)) {\n printError(`Could not create knowledge graph: ${msg}`);\n return null;\n }\n }\n return name;\n }\n\n if (kgs.length === 1) {\n const only = (kgs[0] as { name?: string }).name;\n if (only) {\n stdout.write(` ${DIM}Using only available KG: ${BOLD}${only}${RESET}\\n`);\n return only;\n }\n }\n\n stdout.write(` ${BOLD}Available knowledge graphs:${RESET}\\n`);\n kgs.forEach((kg, i) => {\n const n = (kg as { name?: string }).name ?? \"?\";\n const tc = (kg as { triple_count?: number }).triple_count ?? 0;\n stdout.write(` ${CYAN}${i + 1}${RESET}. ${n} ${DIM}(${fmtNum(tc)} triples)${RESET}\\n`);\n });\n const pick = (await ask(rl, \" Select KG [1]: \")).trim() || \"1\";\n const idx = Number.parseInt(pick, 10);\n if (Number.isFinite(idx) && idx >= 1 && idx <= kgs.length) {\n const name = (kgs[idx - 1] as { name?: string }).name;\n if (name) return name;\n }\n // Allow typing a name directly\n if (pick && !/^\\d+$/.test(pick)) return pick;\n printError(\"Invalid selection.\");\n return null;\n}\n\n/**\n * Tiny live-line spinner. Returns handles to update the trailing text and\n * stop. We use \\r + clear-line escape so the line redraws in place.\n */\nfunction startSpinner(initial: string): {\n setText: (text: string) => void;\n stop: () => void;\n} {\n const frames = [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"];\n let frame = 0;\n let text = initial;\n let stopped = false;\n\n const draw = (): void => {\n if (stopped) return;\n // \\x1b[2K = clear entire line; \\r = carriage return\n stdout.write(`\\r\\x1b[2K ${CYAN}${frames[frame]}${RESET} ${text}`);\n frame = (frame + 1) % frames.length;\n };\n draw();\n const tick = setInterval(draw, 80);\n\n return {\n setText(t: string) {\n text = t;\n },\n stop() {\n stopped = true;\n clearInterval(tick);\n stdout.write(\"\\r\\x1b[2K\");\n },\n };\n}\n\nasync function cmdIngest(\n client: Client,\n kg: string,\n args: string[],\n): Promise<void> {\n if (args.length === 0) {\n stdout.write(` ${YELLOW}Usage:${RESET} /ingest <file> [<file>...]\\n`);\n return;\n }\n for (const file of args) {\n const sp = startSpinner(`Inferring schema from ${file}...`);\n try {\n const result = await client.ingest(file, {\n kg,\n onProgress: ({\n rowsProcessed,\n totalRows,\n entitiesResolved,\n triplesInserted,\n }) => {\n const pct = Math.round((rowsProcessed / totalRows) * 100);\n sp.setText(\n `Ingesting ${file} ${DIM}·${RESET} ${BOLD}${pct}%${RESET} ` +\n `${DIM}(${fmtNum(rowsProcessed)}/${fmtNum(totalRows)} rows · ` +\n `${fmtNum(entitiesResolved)} entities · ${fmtNum(triplesInserted)} triples)${RESET}`,\n );\n },\n });\n sp.stop();\n const ents =\n (result as { entities_resolved?: number }).entities_resolved ?? 0;\n const trip =\n (result as { triples_inserted?: number }).triples_inserted ?? 0;\n stdout.write(\n ` ${GREEN}✓${RESET} ${file} ${DIM}·${RESET} ${fmtNum(ents)} entities · ${fmtNum(trip)} triples\\n`,\n );\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n }\n }\n}\n\nasync function cmdAsk(\n client: Client,\n kg: string,\n question: string,\n): Promise<void> {\n const q = question.trim();\n if (!q) {\n stdout.write(` ${YELLOW}Usage:${RESET} /ask <your question>\\n`);\n return;\n }\n try {\n const result = await client.ask(q, { kg });\n const answer =\n (result as { narrative_answer?: string }).narrative_answer ||\n (result as { answer?: string }).answer ||\n \"No answer generated.\";\n stdout.write(\"\\n\");\n stdout.write(` ${answer}\\n`);\n stdout.write(\"\\n\");\n } catch (err) {\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n }\n}\n\n/**\n * `/agent <message>` — one turn of the unified Ask-AI agent inside the REPL.\n *\n * Sends the message (threading the per-session `sessionId` for multi-turn\n * continuity), renders the kind-tagged response with the shared renderer, and —\n * because the shell IS interactive — when the response is a `plan`, prompts\n * `Confirm & run? [y/N]`. On `y` it confirms the plan (the only mutating path)\n * and renders the `result`. Mirrors the cli.ts agent command, but the confirm\n * is an inline prompt rather than --yes/--confirm.\n */\nasync function cmdAgent(\n client: Client,\n kg: string,\n rl: readline.Interface,\n sessionId: string,\n message: string,\n): Promise<void> {\n const msg = message.trim();\n if (!msg) {\n stdout.write(` ${YELLOW}Usage:${RESET} /agent <your message>\\n`);\n return;\n }\n const context = { kgName: kg, sessionId };\n const sp = startSpinner(\"Thinking...\");\n let result;\n try {\n result = await client.agent({ message: msg, ...context });\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n renderAgentResult(result);\n\n // Only a plan awaits confirmation. Prompt inline; on \"y\", confirm + execute.\n if (result.kind === \"plan\") {\n const planId =\n typeof result.plan_id === \"string\" ? result.plan_id : undefined;\n if (!planId) return;\n const ans = (await ask(rl, ` ${YELLOW}Confirm & run?${RESET} [y/N]: `))\n .trim()\n .toLowerCase();\n if (ans !== \"y\" && ans !== \"yes\") {\n stdout.write(` ${DIM}Not run. Plan ${planId} kept.${RESET}\\n`);\n return;\n }\n const sp2 = startSpinner(\"Running plan...\");\n let executed;\n try {\n executed = await client.agent({ confirmPlanId: planId, ...context });\n } catch (err) {\n sp2.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp2.stop();\n renderAgentResult(executed);\n }\n}\n\nasync function cmdStatus(client: Client, kg: string): Promise<void> {\n try {\n const info = await fetchKg(client, kg);\n stdout.write(\"\\n\");\n stdout.write(` ${BOLD}KG${RESET} ${kg}\\n`);\n if (info) {\n stdout.write(` ${BOLD}Triples${RESET} ${fmtNum(info.triple_count)}\\n`);\n } else {\n stdout.write(` ${BOLD}Triples${RESET} ${DIM}(empty)${RESET}\\n`);\n }\n try {\n const types = await client.ontologyTypes();\n const names = types\n .map((t) => (t as { name?: string }).name)\n .filter((n): n is string => Boolean(n));\n if (names.length > 0) {\n stdout.write(` ${BOLD}Types${RESET} ${names.join(\", \")}\\n`);\n } else {\n stdout.write(` ${BOLD}Types${RESET} ${DIM}(none)${RESET}\\n`);\n }\n } catch (err) {\n printError(\n `Could not list ontology types: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n stdout.write(\"\\n\");\n } catch (err) {\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n }\n}\n\nasync function cmdReset(\n client: Client,\n kg: string,\n rl: readline.Interface,\n): Promise<boolean> {\n const confirm = (\n await ask(rl, ` ${YELLOW}Delete KG \"${kg}\"?${RESET} [y/N]: `)\n )\n .trim()\n .toLowerCase();\n if (confirm !== \"y\" && confirm !== \"yes\") {\n stdout.write(` ${DIM}Cancelled.${RESET}\\n`);\n return false;\n }\n try {\n await client.deleteKg(kg);\n stdout.write(` ${GREEN}✓${RESET} Graph cleared.\\n`);\n return true;\n } catch (err) {\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return false;\n }\n}\n\nasync function cmdTypes(\n client: Client,\n kg: string,\n query: string,\n): Promise<void> {\n const sp = startSpinner(\n query ? `Searching types matching \"${query}\"...` : \"Loading types...\",\n );\n let types: TypeCount[];\n try {\n types = await client.typeCounts(kg);\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n\n const q = query.trim().toLowerCase();\n const filtered = q\n ? types.filter((t) => t.name.toLowerCase().includes(q))\n : types;\n\n if (filtered.length === 0) {\n if (types.length === 0) {\n stdout.write(\n ` ${DIM}No types yet in ${BOLD}${kg}${RESET}${DIM}. Try ${RESET}/ingest <file>${DIM} first.${RESET}\\n`,\n );\n } else {\n stdout.write(\n ` ${DIM}No types match \"${query}\". Try ${RESET}/types${DIM} for the full list.${RESET}\\n`,\n );\n }\n return;\n }\n\n // Right-align counts; leave room for the longest name we'll print.\n const nameWidth = Math.max(\n \"Type\".length,\n ...filtered.map((t) => t.name.length),\n );\n const countWidth = Math.max(\n \"Entities\".length,\n ...filtered.map((t) => fmtNum(t.entity_count).length),\n );\n stdout.write(\"\\n\");\n stdout.write(\n ` ${BOLD}${\"Type\".padEnd(nameWidth)} ${\"Entities\".padStart(countWidth)}${RESET}\\n`,\n );\n let total = 0;\n for (const t of filtered) {\n total += t.entity_count;\n stdout.write(\n ` ${CYAN}${t.name.padEnd(nameWidth)}${RESET} ${fmtNum(t.entity_count).padStart(countWidth)}\\n`,\n );\n }\n stdout.write(\"\\n\");\n const summary = q\n ? `${filtered.length} match${filtered.length === 1 ? \"\" : \"es\"}.`\n : `${filtered.length} type${filtered.length === 1 ? \"\" : \"s\"}, ${fmtNum(total)} entities total.`;\n stdout.write(` ${DIM}${summary}${RESET}\\n`);\n stdout.write(\n ` ${DIM}Drill in: ${RESET}/type <name>${DIM} Filter: ${RESET}/types <query>${DIM}${RESET}\\n\\n`,\n );\n}\n\n/**\n * Resolve a user-supplied type name to a canonical type. Case-insensitive\n * exact match wins; otherwise we fall back to prefix match. If multiple\n * types share a prefix, prompt the user to pick from a numbered list.\n */\nasync function resolveTypeName(\n client: Client,\n kg: string,\n rl: readline.Interface,\n input: string,\n): Promise<string | null> {\n const types = await client.typeCounts(kg);\n if (types.length === 0) {\n printError(`No types in ${kg} yet. Try /ingest <file> first.`);\n return null;\n }\n const q = input.trim().toLowerCase();\n const exact = types.find((t) => t.name.toLowerCase() === q);\n if (exact) return exact.name;\n const prefix = types.filter((t) => t.name.toLowerCase().startsWith(q));\n const matches = prefix.length > 0\n ? prefix\n : types.filter((t) => t.name.toLowerCase().includes(q));\n if (matches.length === 0) {\n printError(\n `No type matches \"${input}\". Try /types to see what's available.`,\n );\n return null;\n }\n if (matches.length === 1) return matches[0]!.name;\n stdout.write(` ${DIM}Multiple types match \"${input}\":${RESET}\\n`);\n matches.forEach((t, i) => {\n stdout.write(\n ` ${CYAN}${i + 1}${RESET}. ${BOLD}${t.name}${RESET} ${DIM}(${fmtNum(t.entity_count)} entities)${RESET}\\n`,\n );\n });\n const pick = (await ask(rl, ` Pick [1]: `)).trim() || \"1\";\n const idx = Number.parseInt(pick, 10);\n if (Number.isFinite(idx) && idx >= 1 && idx <= matches.length) {\n return matches[idx - 1]!.name;\n }\n printError(\"Invalid selection.\");\n return null;\n}\n\nasync function cmdType(\n client: Client,\n kg: string,\n rl: readline.Interface,\n input: string,\n): Promise<void> {\n // Pull off any --system flag so the rest can be treated as the type name.\n // Conservative parse: only the literal flag, anywhere in the input.\n const tokens = splitArgs(input.trim());\n const includeSystem = tokens.includes(\"--system\");\n const nameTokens = tokens.filter((t) => t !== \"--system\");\n const nameInput = nameTokens.join(\" \").trim();\n if (!nameInput) {\n stdout.write(` ${YELLOW}Usage:${RESET} /type <name> [--system]\\n`);\n return;\n }\n const name = await resolveTypeName(client, kg, rl, nameInput);\n if (!name) return;\n\n const sp = startSpinner(`Loading ${name}...`);\n let usage;\n try {\n usage = await client.typeUsage(kg, name, { includeSystem });\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n\n const total = usage.entity_count;\n const pct = (n: number): string =>\n total > 0 ? `${Math.round((n / total) * 100).toString().padStart(3)}%` : \" —\";\n\n // Dedup: when the resolver produces both a literal attribute and a typed\n // relationship for the same column (e.g. .title literal + .title→JobTitle),\n // we collapse to a single relationship row and surface the literal count\n // as a \"(+775 string)\" annotation. The relationship row \"wins\" because\n // its count is the union upper bound (every entity with a typed link)\n // and it's the richer fact. Pure literals and pure relationships are\n // unaffected.\n const relNames = new Set(usage.relationships.map((r) => r.name));\n const attrLitByName = new Map(usage.attributes.map((a) => [a.name, a]));\n const litOnlyAttrs = usage.attributes.filter((a) => !relNames.has(a.name));\n\n stdout.write(\"\\n\");\n stdout.write(\n ` ${BOLD}${usage.name}${RESET} ${DIM}${fmtNum(total)} entities${RESET}\\n`,\n );\n if (usage.description) {\n stdout.write(` ${DIM}${usage.description}${RESET}\\n`);\n }\n if (usage.parent_type) {\n stdout.write(` ${DIM}subClassOf ${usage.parent_type}${RESET}\\n`);\n }\n\n if (litOnlyAttrs.length > 0) {\n stdout.write(\n `\\n ${BOLD}Attributes (${litOnlyAttrs.length})${RESET}\\n`,\n );\n const nameW = Math.max(\n ...litOnlyAttrs.map((a) => a.name.length + 1),\n 8,\n );\n const typeW = Math.max(\n ...litOnlyAttrs.map((a) => a.datatype.length),\n 8,\n );\n const cntW = Math.max(\n ...litOnlyAttrs.map((a) => fmtNum(a.count).length),\n 4,\n );\n for (const a of litOnlyAttrs) {\n const dotName = `.${a.name}`;\n stdout.write(\n ` ${CYAN}${dotName.padEnd(nameW)}${RESET} ${DIM}${a.datatype.padEnd(typeW)}${RESET} ${fmtNum(a.count).padStart(cntW)} ${DIM}(${pct(a.count)})${RESET}\\n`,\n );\n }\n }\n\n if (usage.relationships.length > 0) {\n stdout.write(\n `\\n ${BOLD}Relationships (${usage.relationships.length})${RESET}\\n`,\n );\n const nameW = Math.max(\n ...usage.relationships.map((r) => r.name.length + 1),\n 8,\n );\n const tgtW = Math.max(\n ...usage.relationships.map((r) => (r.target_type ?? \"?\").length),\n 6,\n );\n for (const r of usage.relationships) {\n const dotName = `.${r.name}`;\n const tgt = r.target_type ?? \"?\";\n const lit = attrLitByName.get(r.name);\n const litNote = lit\n ? ` ${DIM}(+${fmtNum(lit.count)} ${lit.datatype})${RESET}`\n : \"\";\n stdout.write(\n ` ${CYAN}${dotName.padEnd(nameW)}${RESET} ${DIM}→${RESET} ${BOLD}${tgt.padEnd(tgtW)}${RESET} ${fmtNum(r.count).padStart(6)} ${DIM}(${pct(r.count)})${RESET}${litNote}\\n`,\n );\n }\n }\n\n if (usage.samples.length > 0) {\n stdout.write(`\\n ${BOLD}Sample entities${RESET}\\n`);\n usage.samples.forEach((s, i) => {\n const label = s.label || s.uri.split(\"/\").pop() || s.uri;\n stdout.write(` ${DIM}${i + 1}.${RESET} ${label}\\n`);\n });\n }\n\n if (\n usage.attributes.length === 0 &&\n usage.relationships.length === 0 &&\n total === 0\n ) {\n stdout.write(\n `\\n ${DIM}Type defined in the ontology but no instances yet in ${kg}.${RESET}\\n`,\n );\n }\n stdout.write(\"\\n\");\n}\n\nfunction lastUriSegment(uri: string): string {\n if (!uri) return uri;\n const hash = uri.lastIndexOf(\"#\");\n if (hash >= 0 && hash < uri.length - 1) return uri.slice(hash + 1);\n const slash = uri.lastIndexOf(\"/\");\n if (slash >= 0 && slash < uri.length - 1) return uri.slice(slash + 1);\n return uri;\n}\n\nfunction relativeTime(iso: string | null | undefined): string {\n if (!iso) return \"—\";\n const t = Date.parse(iso);\n if (!Number.isFinite(t)) return \"—\";\n const diffMs = Date.now() - t;\n const s = Math.max(0, Math.floor(diffMs / 1000));\n if (s < 60) return `${s}s ago`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ago`;\n const h = Math.floor(m / 60);\n if (h < 24) return `${h}h ago`;\n const d = Math.floor(h / 24);\n return `${d}d ago`;\n}\n\nfunction progressBar(processed: number, total: number, width = 20): string {\n if (!total || total <= 0) return \"[\" + \" \".repeat(width) + \"]\";\n const ratio = Math.max(0, Math.min(1, processed / total));\n const filled = Math.round(ratio * width);\n return \"[\" + \"█\".repeat(filled) + \"░\".repeat(width - filled) + \"]\";\n}\n\nfunction statusColor(status: string): string {\n switch (status) {\n case \"applied\":\n return GREEN;\n case \"failed\":\n return RED;\n case \"review\":\n return YELLOW;\n case \"cancelled\":\n return DIM;\n default:\n return CYAN;\n }\n}\n\nasync function cmdEnrichRun(\n client: Client,\n kg: string,\n rl: readline.Interface,\n args: string[],\n): Promise<void> {\n if (args.length < 2) {\n stdout.write(\n ` ${YELLOW}Usage:${RESET} /enrich <Type> <attr1> [<attr2> ...]\\n`,\n );\n return;\n }\n const typeInput = args[0]!;\n const attrs = args.slice(1).map((a) => a.replace(/^\\./, \"\"));\n const typeName = await resolveTypeName(client, kg, rl, typeInput);\n if (!typeName) return;\n\n const tier: \"lite\" = \"lite\";\n const policy: \"stage\" = \"stage\";\n stdout.write(\n `\\n ${BOLD}Plan:${RESET} enrich ${CYAN}${typeName}${RESET}.${attrs\n .map((a) => `${CYAN}${a}${RESET}`)\n .join(`, .`)} in ${BOLD}${kg}${RESET} ${DIM}·${RESET} tier: ${tier} ${DIM}·${RESET} policy: ${policy}\\n\\n`,\n );\n\n const sp = startSpinner(`Queueing enrichment for ${typeName}...`);\n let created;\n try {\n created = await client.enrichRun({\n type_name: typeName,\n attributes: attrs,\n tier,\n kg_name: kg,\n conflict_policy: policy,\n });\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n\n const cost = (created.estimated_cost_usd ?? 0).toFixed(4);\n stdout.write(\n ` ${GREEN}✓${RESET} Job queued: ${CYAN_BOLD}${created.job_id}${RESET} ${DIM}·${RESET} estimated cost ${BOLD}$${cost}${RESET} ${DIM}·${RESET} ${fmtNum(created.total_entities ?? 0)} entities\\n`,\n );\n\n const watch = (await ask(rl, ` Watch progress? [Y/n]: `)).trim().toLowerCase();\n if (watch === \"\" || watch === \"y\" || watch === \"yes\") {\n await watchJob(client, created.job_id);\n } else {\n stdout.write(\n ` ${DIM}Tip: /enrich watch ${created.job_id} to follow it.${RESET}\\n`,\n );\n }\n}\n\nasync function watchJob(client: Client, jobId: string): Promise<void> {\n const startedAt = Date.now();\n let lastJob: EnrichJob | null = null;\n // Render in place\n const draw = (job: EnrichJob): void => {\n const p = job.progress;\n const bar = progressBar(p.processed, p.total);\n const elapsed = Math.max(1, Math.floor((Date.now() - startedAt) / 1000));\n const rate = p.processed / elapsed;\n let etaStr = \"—\";\n if (rate > 0 && p.total > p.processed) {\n const remaining = Math.ceil((p.total - p.processed) / rate);\n etaStr =\n remaining < 60\n ? `${remaining}s`\n : remaining < 3600\n ? `${Math.floor(remaining / 60)}m`\n : `${Math.floor(remaining / 3600)}h`;\n }\n const sc = statusColor(job.status);\n stdout.write(\n `\\r\\x1b[2K ${sc}${job.status}${RESET} ${bar} ${fmtNum(p.processed)}/${fmtNum(p.total)} ` +\n `${DIM}·${RESET} filled ${GREEN}${fmtNum(p.filled)}${RESET} ` +\n `${DIM}·${RESET} verified ${CYAN}${fmtNum(p.verified)}${RESET} ` +\n `${DIM}·${RESET} conflicts ${YELLOW}${fmtNum(p.conflicts)}${RESET} ` +\n `${DIM}·${RESET} ETA ${etaStr}`,\n );\n };\n\n while (true) {\n let job: EnrichJob;\n try {\n job = await client.enrichJob(jobId);\n } catch (err) {\n stdout.write(\"\\r\\x1b[2K\");\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n lastJob = job;\n draw(job);\n if (job.status !== \"running\" && job.status !== \"queued\") break;\n await new Promise((r) => setTimeout(r, 1500));\n }\n\n // Final newline after the live line.\n stdout.write(\"\\n\");\n if (!lastJob) return;\n const p = lastJob.progress;\n if (lastJob.status === \"review\") {\n stdout.write(\n ` ${YELLOW}✦${RESET} ${fmtNum(p.conflicts)} conflict${p.conflicts === 1 ? \"\" : \"s\"} need review. ` +\n `${DIM}Run${RESET} /enrich review ${lastJob.id}${DIM} to walk through them.${RESET}\\n`,\n );\n } else if (lastJob.status === \"applied\") {\n stdout.write(\n ` ${GREEN}✓${RESET} Applied ${DIM}·${RESET} filled ${fmtNum(p.filled)}, verified ${fmtNum(p.verified)}, skipped ${fmtNum(p.skipped)}\\n`,\n );\n } else if (lastJob.status === \"failed\") {\n printError(`Job failed: ${lastJob.error ?? \"(no error message)\"}`);\n } else if (lastJob.status === \"cancelled\") {\n stdout.write(` ${DIM}Job cancelled.${RESET}\\n`);\n }\n}\n\nasync function cmdEnrichJobs(client: Client): Promise<void> {\n const sp = startSpinner(\"Loading enrichment jobs...\");\n let jobs: JobSummary[];\n try {\n jobs = await client.enrichJobs();\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n\n if (jobs.length === 0) {\n stdout.write(` ${DIM}No enrichment jobs yet.${RESET}\\n`);\n return;\n }\n\n const truncAttrs = (attrs: string[]): string => {\n const max = 30;\n const joined = attrs.join(\", \");\n if (joined.length <= max) return joined;\n return joined.slice(0, max - 1) + \"…\";\n };\n\n const rows = jobs.map((j) => ({\n id: j.id,\n type: j.type_name,\n attrs: truncAttrs(j.attributes ?? []),\n status: j.status,\n progress: `${fmtNum(j.progress?.processed ?? 0)}/${fmtNum(j.progress?.total ?? 0)}`,\n created: relativeTime(j.created_at),\n }));\n\n const w = {\n id: Math.max(\"ID\".length, ...rows.map((r) => r.id.length)),\n type: Math.max(\"Type\".length, ...rows.map((r) => r.type.length)),\n attrs: Math.max(\"Attrs\".length, ...rows.map((r) => r.attrs.length)),\n status: Math.max(\"Status\".length, ...rows.map((r) => r.status.length)),\n progress: Math.max(\"Progress\".length, ...rows.map((r) => r.progress.length)),\n };\n\n stdout.write(\"\\n\");\n stdout.write(\n ` ${BOLD}${\"ID\".padEnd(w.id)} ${\"Type\".padEnd(w.type)} ${\"Attrs\".padEnd(w.attrs)} ${\"Status\".padEnd(w.status)} ${\"Progress\".padEnd(w.progress)} Created${RESET}\\n`,\n );\n for (const r of rows) {\n const sc = statusColor(r.status);\n stdout.write(\n ` ${CYAN}${r.id.padEnd(w.id)}${RESET} ${r.type.padEnd(w.type)} ${DIM}${r.attrs.padEnd(w.attrs)}${RESET} ${sc}${r.status.padEnd(w.status)}${RESET} ${r.progress.padEnd(w.progress)} ${DIM}${r.created}${RESET}\\n`,\n );\n }\n stdout.write(\"\\n\");\n}\n\nasync function cmdEnrichReview(\n client: Client,\n rl: readline.Interface,\n jobId: string,\n): Promise<void> {\n if (!jobId) {\n stdout.write(` ${YELLOW}Usage:${RESET} /enrich review <job_id>\\n`);\n return;\n }\n const sp = startSpinner(`Loading conflicts for ${jobId}...`);\n let conflicts: ConflictReview[];\n try {\n conflicts = await client.enrichConflicts(jobId);\n } catch (err) {\n sp.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n return;\n }\n sp.stop();\n\n if (conflicts.length === 0) {\n stdout.write(` ${DIM}No conflicts to review.${RESET}\\n`);\n return;\n }\n\n const decisions: ConflictReview[] = [];\n let acceptAll = false;\n let quitEarly = false;\n\n for (let i = 0; i < conflicts.length; i++) {\n const c = conflicts[i]!;\n const entity = lastUriSegment(c.entity_uri);\n const conf = (c.proposed?.confidence ?? 0).toFixed(2);\n stdout.write(\"\\n\");\n stdout.write(\n ` ${DIM}[${i + 1}/${conflicts.length}]${RESET} ${BOLD}${entity}${RESET}.${CYAN}${c.attribute}${RESET}\\n`,\n );\n stdout.write(\n ` ${DIM}existing →${RESET} ${c.existing_value}\\n` +\n ` ${DIM}proposed →${RESET} ${BOLD}${c.proposed?.value ?? \"\"}${RESET} ${DIM}(conf ${conf}, src ${c.proposed?.source ?? \"?\"})${RESET}\\n`,\n );\n if (c.proposed?.source_url) {\n stdout.write(` ${DIM}url →${RESET} ${c.proposed.source_url}\\n`);\n }\n\n let decision: \"accept\" | \"reject\" | \"skip\";\n if (acceptAll) {\n decision = \"accept\";\n stdout.write(` ${GREEN}auto-accepted${RESET}\\n`);\n } else {\n const ans = (\n await ask(\n rl,\n ` [a]ccept / [r]eject / [s]kip / [A]ccept all remaining / [q]uit (saves progress) [s]: `,\n )\n ).trim();\n if (ans === \"A\") {\n acceptAll = true;\n decision = \"accept\";\n } else if (ans === \"a\") {\n decision = \"accept\";\n } else if (ans === \"r\") {\n decision = \"reject\";\n } else if (ans === \"q\") {\n quitEarly = true;\n break;\n } else {\n decision = \"skip\";\n }\n }\n decisions.push({ ...c, decision });\n }\n\n if (quitEarly) {\n if (decisions.length === 0) {\n stdout.write(` ${DIM}No decisions made — nothing to save.${RESET}\\n`);\n return;\n }\n const save = (\n await ask(rl, ` Save ${decisions.length} decision(s) so far? [Y/n]: `)\n )\n .trim()\n .toLowerCase();\n if (save !== \"\" && save !== \"y\" && save !== \"yes\") {\n stdout.write(` ${DIM}Discarded.${RESET}\\n`);\n return;\n }\n }\n\n if (decisions.length === 0) {\n stdout.write(` ${DIM}No decisions to apply.${RESET}\\n`);\n return;\n }\n\n const sp2 = startSpinner(`Applying ${decisions.length} decision(s)...`);\n try {\n const res = await client.enrichApply(jobId, decisions);\n sp2.stop();\n stdout.write(\n ` ${GREEN}✓${RESET} Applied ${BOLD}${fmtNum(res.applied)}${RESET} change${res.applied === 1 ? \"\" : \"s\"}.\\n`,\n );\n } catch (err) {\n sp2.stop();\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n }\n}\n\nfunction urlHost(url: string): string {\n try {\n return new URL(url).host;\n } catch {\n return url.replace(/^https?:\\/\\//, \"\").replace(/\\/+$/, \"\");\n }\n}\n\nfunction makePrompt(\n kg: string,\n triples: number,\n mode: \"cloud\" | \"self-hosted\" = \"cloud\",\n baseUrl?: string,\n): string {\n const kgPart = `${DIM}(${kg})${RESET}`;\n const triplePart = triples > 0 ? `${DIM}[${fmtNum(triples)}]${RESET} ` : \"\";\n if (mode === \"self-hosted\" && baseUrl) {\n const host = urlHost(baseUrl);\n return ` ${CYAN_BOLD}cograph${RESET}${DIM}@${host}${RESET} ${kgPart} ${triplePart}${CYAN_BOLD}▸${RESET} `;\n }\n return ` ${CYAN_BOLD}cograph${RESET} ${kgPart} ${triplePart}${CYAN_BOLD}▸${RESET} `;\n}\n\n/**\n * Split a command-line style argument string. Supports double-quoted args.\n */\nfunction splitArgs(s: string): string[] {\n const out: string[] = [];\n let cur = \"\";\n let inQ = false;\n for (let i = 0; i < s.length; i++) {\n const c = s[i];\n if (inQ) {\n if (c === '\"') inQ = false;\n else cur += c;\n } else {\n if (c === '\"') inQ = true;\n else if (c === \" \" || c === \"\\t\") {\n if (cur) {\n out.push(cur);\n cur = \"\";\n }\n } else cur += c;\n }\n }\n if (cur) out.push(cur);\n return out;\n}\n\nexport async function runShell(opts: {\n kg?: string;\n local?: boolean;\n noLogin?: boolean;\n}): Promise<void> {\n const CLOUD_DEFAULT = \"https://api.cograph.cloud\";\n // Detection precedence: --local > --no-login > COGRAPH_API_URL pointing\n // anywhere besides the cloud default. When self-hosted we never trigger\n // login and tenant defaults to \"default\" (open-access backend behavior).\n const envUrl = process.env.COGRAPH_API_URL || process.env.OMNIX_API_URL;\n const envIsSelfHosted = !!envUrl && envUrl !== CLOUD_DEFAULT;\n const selfHostedHint = !!opts.local || !!opts.noLogin || envIsSelfHosted;\n\n // `let` rather than `const` so /login can swap in a fresh Client after\n // ~/.cograph/config.json is rewritten with the new key.\n let client = opts.local\n ? new Client({ baseUrl: \"http://localhost:8000\", tenant: \"default\" })\n : selfHostedHint\n ? new Client({ tenant: \"default\" })\n : new Client();\n\n // Probe the backend before deciding whether to trigger login. This lets\n // us distinguish \"cloud, needs auth\" from \"self-hosted, open access\" and\n // also surfaces an unreachable server with a clear error rather than a\n // confusing browser-login attempt.\n const health = await client.healthCheck();\n if (!health.ok) {\n printError(\n `Could not reach ${health.url}. Is the server running?`,\n );\n return;\n }\n\n const selfHosted = selfHostedHint || !health.requiresAuth;\n const mode: \"cloud\" | \"self-hosted\" = selfHosted ? \"self-hosted\" : \"cloud\";\n\n // Cloud / auth-required path: behave as before — if no key, log in.\n if (!selfHosted && health.requiresAuth && !client.apiKey) {\n stdout.write(\n `\\n ${DIM}Not signed in — opening your browser to log in...${RESET}\\n`,\n );\n const { runLogin } = await import(\"./login.js\");\n await runLogin();\n client = new Client();\n if (!client.apiKey) {\n // runLogin already exits the process on hard failures, so reaching\n // here means it returned without writing a key (rare). Bail rather\n // than continue into a broken shell.\n printError(\"Login did not produce an API key. Aborting.\");\n return;\n }\n }\n const rl = readline.createInterface({\n input: stdin,\n output: stdout,\n terminal: true,\n });\n\n showBanner();\n\n if (selfHosted) {\n stdout.write(\n `${DIM} Self-hosted mode · ${client.baseUrl} · tenant=${client.tenant}${RESET}\\n\\n`,\n );\n }\n\n // One agent session id per shell session — threaded across every /agent turn\n // for multi-turn continuity (the server keys conversation state on it).\n const agentSessionId = randomUUID();\n\n let kg = opts.kg;\n if (!kg) {\n const picked = await selectKg(client, rl);\n if (!picked) {\n rl.close();\n return;\n }\n kg = picked;\n }\n\n let triples = 0;\n const info = await fetchKg(client, kg);\n if (info && info.triple_count > 0) {\n triples = info.triple_count;\n stdout.write(\n ` ${DIM}Connected to${RESET} ${BOLD}${kg}${RESET}${DIM}: ${fmtNum(triples)} triples${RESET}\\n\\n`,\n );\n } else {\n stdout.write(\n ` ${DIM}Connected — ${kg} is empty (use /ingest to add data)${RESET}\\n\\n`,\n );\n }\n\n const refresh = async (): Promise<void> => {\n const fresh = await fetchKg(client, kg!);\n triples = fresh?.triple_count ?? 0;\n };\n\n let running = true;\n rl.on(\"close\", () => {\n running = false;\n });\n\n while (running) {\n let line: string;\n try {\n line = (\n await ask(rl, makePrompt(kg, triples, mode, client.baseUrl))\n ).trim();\n } catch {\n break;\n }\n if (!running) break;\n if (!line) continue;\n\n if (line === \"/quit\" || line === \"/exit\" || line === \"/q\") {\n stdout.write(` ${DIM}Bye.${RESET}\\n`);\n break;\n }\n\n if (line === \"/help\") {\n showCommands();\n continue;\n }\n\n try {\n if (line.startsWith(\"/ingest\")) {\n const args = splitArgs(line.slice(\"/ingest\".length).trim());\n await cmdIngest(client, kg, args);\n await refresh();\n } else if (line.startsWith(\"/ask \")) {\n await cmdAsk(client, kg, line.slice(\"/ask \".length));\n } else if (line === \"/ask\") {\n await cmdAsk(client, kg, \"\");\n } else if (line.startsWith(\"/agent \")) {\n await cmdAgent(\n client,\n kg,\n rl,\n agentSessionId,\n line.slice(\"/agent \".length),\n );\n await refresh();\n } else if (line === \"/agent\") {\n await cmdAgent(client, kg, rl, agentSessionId, \"\");\n } else if (line === \"/types\" || line.startsWith(\"/types \")) {\n const query = line === \"/types\" ? \"\" : line.slice(\"/types \".length);\n await cmdTypes(client, kg, query);\n } else if (line.startsWith(\"/type \") || line === \"/type\") {\n const arg = line === \"/type\" ? \"\" : line.slice(\"/type \".length);\n await cmdType(client, kg, rl, arg);\n } else if (line === \"/enrich\" || line.startsWith(\"/enrich \")) {\n const args = splitArgs(line.slice(\"/enrich\".length).trim());\n if (args.length === 0) {\n stdout.write(\n ` ${YELLOW}Usage:${RESET} /enrich <Type> <attr> ... | /enrich watch <id> | /enrich jobs | /enrich review <id>\\n`,\n );\n } else if (args[0] === \"jobs\") {\n await cmdEnrichJobs(client);\n } else if (args[0] === \"watch\") {\n const jid = args[1];\n if (!jid) {\n stdout.write(` ${YELLOW}Usage:${RESET} /enrich watch <job_id>\\n`);\n } else {\n await watchJob(client, jid);\n }\n } else if (args[0] === \"review\") {\n await cmdEnrichReview(client, rl, args[1] ?? \"\");\n } else {\n await cmdEnrichRun(client, kg, rl, args);\n await refresh();\n }\n } else if (line === \"/status\") {\n await cmdStatus(client, kg);\n await refresh();\n } else if (line === \"/reset\") {\n const did = await cmdReset(client, kg, rl);\n if (did) await refresh();\n } else if (line === \"/login\") {\n const { runLogin } = await import(\"./login.js\");\n await runLogin();\n // Pick up the new key from ~/.cograph/config.json for subsequent calls.\n client = new Client();\n await refresh();\n } else if (line === \"/tenant\" || line.startsWith(\"/tenant \")) {\n const args = splitArgs(line.slice(\"/tenant\".length).trim());\n const sub = args[0] ?? \"list\";\n const target = args.slice(1).join(\" \");\n\n if (sub === \"use\" || sub === \"switch\") {\n if (!target) {\n stdout.write(` ${YELLOW}Usage:${RESET} /tenant use <id>\\n`);\n } else {\n writeConfig({ tenant: target });\n // Rebuild the client so it picks up the new tenant; preserve the\n // current base URL (self-hosted/local) and key.\n client = new Client({ baseUrl: client.baseUrl });\n stdout.write(\n ` ${GREEN}✓${RESET} Switched to tenant ${BOLD}${target}${RESET}\\n`,\n );\n // KGs are per-tenant — the old current KG may not exist here, so\n // pick one from the new tenant.\n const picked = await selectKg(client, rl);\n if (picked) {\n kg = picked;\n } else {\n stdout.write(\n ` ${DIM}No KGs in ${target} yet — /kg create <name>${RESET}\\n`,\n );\n }\n await refresh();\n }\n } else if (sub === \"current\") {\n stdout.write(` ${BOLD}${client.tenant}${RESET}\\n`);\n } else {\n try {\n const tenants = await client.listTenants();\n if (!tenants.length) {\n stdout.write(` ${DIM}No tenants found for your account.${RESET}\\n`);\n } else {\n for (const t of tenants) {\n const marker =\n t.id === client.tenant ? `${CYAN_BOLD}*${RESET}` : \" \";\n stdout.write(\n ` ${marker} ${BOLD}${t.id}${RESET} ${DIM}${t.label}${RESET}\\n`,\n );\n }\n stdout.write(` ${DIM}/tenant use <id> to switch${RESET}\\n`);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (err instanceof CographError && err.status === 501) {\n printError(\"Tenant management isn't configured on this backend.\");\n } else {\n printError(msg);\n }\n }\n }\n } else if (line === \"/kg\" || line.startsWith(\"/kg \")) {\n const args = splitArgs(line.slice(\"/kg\".length).trim());\n const sub = args[0] ?? \"list\";\n const target = args.slice(1).join(\" \");\n\n if (sub === \"list\") {\n const list = await client.listKgs();\n if (!list.length) {\n stdout.write(\n ` ${DIM}No knowledge graphs yet. /kg create <name>${RESET}\\n`,\n );\n } else {\n for (const k of list) {\n const n = String((k as { name?: string }).name ?? \"?\");\n const tc = Number((k as { triple_count?: number }).triple_count ?? 0);\n const marker = n === kg ? `${CYAN_BOLD}*${RESET}` : \" \";\n stdout.write(\n ` ${marker} ${BOLD}${n}${RESET} ${DIM}(${fmtNum(tc)} triples)${RESET}\\n`,\n );\n }\n }\n } else if (sub === \"switch\") {\n if (!target) {\n stdout.write(` ${YELLOW}Usage:${RESET} /kg switch <name>\\n`);\n } else {\n const list = await client.listKgs();\n const found = list.find(\n (k) => (k as { name?: string }).name === target,\n );\n if (!found) {\n printError(`KG not found: ${target}. Try /kg list.`);\n } else {\n kg = target;\n triples = Number(\n (found as { triple_count?: number }).triple_count ?? 0,\n );\n stdout.write(\n ` ${GREEN}✓${RESET} Switched to ${BOLD}${kg}${RESET}\\n`,\n );\n }\n }\n } else if (sub === \"create\") {\n if (!target) {\n stdout.write(` ${YELLOW}Usage:${RESET} /kg create <name>\\n`);\n } else {\n try {\n await client.createKg(target);\n kg = target;\n triples = 0;\n stdout.write(\n ` ${GREEN}✓${RESET} Created and switched to ${BOLD}${kg}${RESET}\\n`,\n );\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n if (/already exists|409/i.test(msg)) {\n kg = target;\n await refresh();\n stdout.write(\n ` ${DIM}${target} already exists — switched to it.${RESET}\\n`,\n );\n } else {\n printError(`Could not create: ${msg}`);\n }\n }\n }\n } else if (sub === \"delete\") {\n if (!target) {\n stdout.write(` ${YELLOW}Usage:${RESET} /kg delete <name>\\n`);\n } else {\n const isActive = target === kg;\n const tag = isActive ? \" (the active KG)\" : \"\";\n const confirm = (\n await ask(\n rl,\n ` ${YELLOW}Delete KG \"${target}\"${tag}?${RESET} [y/N]: `,\n )\n )\n .trim()\n .toLowerCase();\n if (confirm === \"y\" || confirm === \"yes\") {\n try {\n await client.deleteKg(target);\n stdout.write(` ${GREEN}✓${RESET} Deleted ${BOLD}${target}${RESET}\\n`);\n if (isActive) {\n // Active KG is gone; let the user pick (or create) a new one\n // before any further commands try to use it.\n const picked = await selectKg(client, rl);\n if (!picked) {\n running = false;\n break;\n }\n kg = picked;\n await refresh();\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n printError(`Could not delete: ${msg}`);\n }\n } else {\n stdout.write(` ${DIM}Cancelled.${RESET}\\n`);\n }\n }\n } else {\n stdout.write(\n ` ${YELLOW}Unknown /kg subcommand: ${sub}.${RESET} Try /kg list, /kg switch <name>, /kg create <name>, /kg delete <name>.\\n`,\n );\n }\n } else if (line.startsWith(\"/\")) {\n stdout.write(\n ` ${YELLOW}Unknown command.${RESET} Try /ingest, /ask, /agent, /kg, /types, /type, /enrich, /login, /status, /reset, /help, /quit\\n`,\n );\n } else {\n // Bare line — auto-route to /ask\n await cmdAsk(client, kg, line);\n }\n } catch (err) {\n if (err instanceof CographError) printError(err.message);\n else printError(err instanceof Error ? err.message : String(err));\n }\n }\n\n rl.close();\n}\n"],"mappings":"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","names":["p"]}
|