cograph 0.1.15 → 0.1.17

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.
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  Client,
4
4
  CographError
5
- } from "./chunk-K45ZTU6U.js";
5
+ } from "./chunk-ZGWB54YO.js";
6
6
  import "./chunk-7VVBEUZQ.js";
7
7
 
8
8
  // src/shell.ts
@@ -60,6 +60,10 @@ function showCommands() {
60
60
  ["/types [query]", "List types in the current KG (with entity counts)"],
61
61
  ["/type <name>", "Drill into one type \u2014 attributes, relationships, samples"],
62
62
  ["/type <name> --system", "\u2026also include auto-attached system attributes"],
63
+ ["/enrich <Type> <attr> ...", "Plan + run an enrichment job (interactive)"],
64
+ ["/enrich watch <job_id>", "Live progress for a running job"],
65
+ ["/enrich jobs", "List recent enrichment jobs"],
66
+ ["/enrich review <job_id>", "Walk through conflicts and accept/reject"],
63
67
  ["/login", "Re-authenticate (browser)"],
64
68
  ["/status", "Show graph stats"],
65
69
  ["/reset", "Clear the current KG"],
@@ -487,12 +491,321 @@ async function cmdType(client, kg, rl, input) {
487
491
  }
488
492
  stdout.write("\n");
489
493
  }
490
- function makePrompt(kg, triples) {
494
+ function lastUriSegment(uri) {
495
+ if (!uri) return uri;
496
+ const hash = uri.lastIndexOf("#");
497
+ if (hash >= 0 && hash < uri.length - 1) return uri.slice(hash + 1);
498
+ const slash = uri.lastIndexOf("/");
499
+ if (slash >= 0 && slash < uri.length - 1) return uri.slice(slash + 1);
500
+ return uri;
501
+ }
502
+ function relativeTime(iso) {
503
+ if (!iso) return "\u2014";
504
+ const t = Date.parse(iso);
505
+ if (!Number.isFinite(t)) return "\u2014";
506
+ const diffMs = Date.now() - t;
507
+ const s = Math.max(0, Math.floor(diffMs / 1e3));
508
+ if (s < 60) return `${s}s ago`;
509
+ const m = Math.floor(s / 60);
510
+ if (m < 60) return `${m}m ago`;
511
+ const h = Math.floor(m / 60);
512
+ if (h < 24) return `${h}h ago`;
513
+ const d = Math.floor(h / 24);
514
+ return `${d}d ago`;
515
+ }
516
+ function progressBar(processed, total, width = 20) {
517
+ if (!total || total <= 0) return "[" + " ".repeat(width) + "]";
518
+ const ratio = Math.max(0, Math.min(1, processed / total));
519
+ const filled = Math.round(ratio * width);
520
+ return "[" + "\u2588".repeat(filled) + "\u2591".repeat(width - filled) + "]";
521
+ }
522
+ function statusColor(status) {
523
+ switch (status) {
524
+ case "applied":
525
+ return GREEN;
526
+ case "failed":
527
+ return RED;
528
+ case "review":
529
+ return YELLOW;
530
+ case "cancelled":
531
+ return DIM;
532
+ default:
533
+ return CYAN;
534
+ }
535
+ }
536
+ async function cmdEnrichRun(client, kg, rl, args) {
537
+ if (args.length < 2) {
538
+ stdout.write(
539
+ ` ${YELLOW}Usage:${RESET} /enrich <Type> <attr1> [<attr2> ...]
540
+ `
541
+ );
542
+ return;
543
+ }
544
+ const typeInput = args[0];
545
+ const attrs = args.slice(1).map((a) => a.replace(/^\./, ""));
546
+ const typeName = await resolveTypeName(client, kg, rl, typeInput);
547
+ if (!typeName) return;
548
+ const tier = "lite";
549
+ const policy = "stage";
550
+ stdout.write(
551
+ `
552
+ ${BOLD}Plan:${RESET} enrich ${CYAN}${typeName}${RESET}.${attrs.map((a) => `${CYAN}${a}${RESET}`).join(`, .`)} in ${BOLD}${kg}${RESET} ${DIM}\xB7${RESET} tier: ${tier} ${DIM}\xB7${RESET} policy: ${policy}
553
+
554
+ `
555
+ );
556
+ const sp = startSpinner(`Queueing enrichment for ${typeName}...`);
557
+ let created;
558
+ try {
559
+ created = await client.enrichRun({
560
+ type_name: typeName,
561
+ attributes: attrs,
562
+ tier,
563
+ kg_name: kg,
564
+ conflict_policy: policy
565
+ });
566
+ } catch (err) {
567
+ sp.stop();
568
+ if (err instanceof CographError) printError(err.message);
569
+ else printError(err instanceof Error ? err.message : String(err));
570
+ return;
571
+ }
572
+ sp.stop();
573
+ const cost = (created.estimated_cost_usd ?? 0).toFixed(4);
574
+ stdout.write(
575
+ ` ${GREEN}\u2713${RESET} Job queued: ${CYAN_BOLD}${created.job_id}${RESET} ${DIM}\xB7${RESET} estimated cost ${BOLD}$${cost}${RESET} ${DIM}\xB7${RESET} ${fmtNum(created.total_entities ?? 0)} entities
576
+ `
577
+ );
578
+ const watch = (await ask(rl, ` Watch progress? [Y/n]: `)).trim().toLowerCase();
579
+ if (watch === "" || watch === "y" || watch === "yes") {
580
+ await watchJob(client, created.job_id);
581
+ } else {
582
+ stdout.write(
583
+ ` ${DIM}Tip: /enrich watch ${created.job_id} to follow it.${RESET}
584
+ `
585
+ );
586
+ }
587
+ }
588
+ async function watchJob(client, jobId) {
589
+ const startedAt = Date.now();
590
+ let lastJob = null;
591
+ const draw = (job) => {
592
+ const p2 = job.progress;
593
+ const bar = progressBar(p2.processed, p2.total);
594
+ const elapsed = Math.max(1, Math.floor((Date.now() - startedAt) / 1e3));
595
+ const rate = p2.processed / elapsed;
596
+ let etaStr = "\u2014";
597
+ if (rate > 0 && p2.total > p2.processed) {
598
+ const remaining = Math.ceil((p2.total - p2.processed) / rate);
599
+ etaStr = remaining < 60 ? `${remaining}s` : remaining < 3600 ? `${Math.floor(remaining / 60)}m` : `${Math.floor(remaining / 3600)}h`;
600
+ }
601
+ const sc = statusColor(job.status);
602
+ stdout.write(
603
+ `\r\x1B[2K ${sc}${job.status}${RESET} ${bar} ${fmtNum(p2.processed)}/${fmtNum(p2.total)} ${DIM}\xB7${RESET} filled ${GREEN}${fmtNum(p2.filled)}${RESET} ${DIM}\xB7${RESET} verified ${CYAN}${fmtNum(p2.verified)}${RESET} ${DIM}\xB7${RESET} conflicts ${YELLOW}${fmtNum(p2.conflicts)}${RESET} ${DIM}\xB7${RESET} ETA ${etaStr}`
604
+ );
605
+ };
606
+ while (true) {
607
+ let job;
608
+ try {
609
+ job = await client.enrichJob(jobId);
610
+ } catch (err) {
611
+ stdout.write("\r\x1B[2K");
612
+ if (err instanceof CographError) printError(err.message);
613
+ else printError(err instanceof Error ? err.message : String(err));
614
+ return;
615
+ }
616
+ lastJob = job;
617
+ draw(job);
618
+ if (job.status !== "running" && job.status !== "queued") break;
619
+ await new Promise((r) => setTimeout(r, 1500));
620
+ }
621
+ stdout.write("\n");
622
+ if (!lastJob) return;
623
+ const p = lastJob.progress;
624
+ if (lastJob.status === "review") {
625
+ stdout.write(
626
+ ` ${YELLOW}\u2726${RESET} ${fmtNum(p.conflicts)} conflict${p.conflicts === 1 ? "" : "s"} need review. ${DIM}Run${RESET} /enrich review ${lastJob.id}${DIM} to walk through them.${RESET}
627
+ `
628
+ );
629
+ } else if (lastJob.status === "applied") {
630
+ stdout.write(
631
+ ` ${GREEN}\u2713${RESET} Applied ${DIM}\xB7${RESET} filled ${fmtNum(p.filled)}, verified ${fmtNum(p.verified)}, skipped ${fmtNum(p.skipped)}
632
+ `
633
+ );
634
+ } else if (lastJob.status === "failed") {
635
+ printError(`Job failed: ${lastJob.error ?? "(no error message)"}`);
636
+ } else if (lastJob.status === "cancelled") {
637
+ stdout.write(` ${DIM}Job cancelled.${RESET}
638
+ `);
639
+ }
640
+ }
641
+ async function cmdEnrichJobs(client) {
642
+ const sp = startSpinner("Loading enrichment jobs...");
643
+ let jobs;
644
+ try {
645
+ jobs = await client.enrichJobs();
646
+ } catch (err) {
647
+ sp.stop();
648
+ if (err instanceof CographError) printError(err.message);
649
+ else printError(err instanceof Error ? err.message : String(err));
650
+ return;
651
+ }
652
+ sp.stop();
653
+ if (jobs.length === 0) {
654
+ stdout.write(` ${DIM}No enrichment jobs yet.${RESET}
655
+ `);
656
+ return;
657
+ }
658
+ const truncAttrs = (attrs) => {
659
+ const max = 30;
660
+ const joined = attrs.join(", ");
661
+ if (joined.length <= max) return joined;
662
+ return joined.slice(0, max - 1) + "\u2026";
663
+ };
664
+ const rows = jobs.map((j) => ({
665
+ id: j.id,
666
+ type: j.type_name,
667
+ attrs: truncAttrs(j.attributes ?? []),
668
+ status: j.status,
669
+ progress: `${fmtNum(j.progress?.processed ?? 0)}/${fmtNum(j.progress?.total ?? 0)}`,
670
+ created: relativeTime(j.created_at)
671
+ }));
672
+ const w = {
673
+ id: Math.max("ID".length, ...rows.map((r) => r.id.length)),
674
+ type: Math.max("Type".length, ...rows.map((r) => r.type.length)),
675
+ attrs: Math.max("Attrs".length, ...rows.map((r) => r.attrs.length)),
676
+ status: Math.max("Status".length, ...rows.map((r) => r.status.length)),
677
+ progress: Math.max("Progress".length, ...rows.map((r) => r.progress.length))
678
+ };
679
+ stdout.write("\n");
680
+ stdout.write(
681
+ ` ${BOLD}${"ID".padEnd(w.id)} ${"Type".padEnd(w.type)} ${"Attrs".padEnd(w.attrs)} ${"Status".padEnd(w.status)} ${"Progress".padEnd(w.progress)} Created${RESET}
682
+ `
683
+ );
684
+ for (const r of rows) {
685
+ const sc = statusColor(r.status);
686
+ stdout.write(
687
+ ` ${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}
688
+ `
689
+ );
690
+ }
691
+ stdout.write("\n");
692
+ }
693
+ async function cmdEnrichReview(client, rl, jobId) {
694
+ if (!jobId) {
695
+ stdout.write(` ${YELLOW}Usage:${RESET} /enrich review <job_id>
696
+ `);
697
+ return;
698
+ }
699
+ const sp = startSpinner(`Loading conflicts for ${jobId}...`);
700
+ let conflicts;
701
+ try {
702
+ conflicts = await client.enrichConflicts(jobId);
703
+ } catch (err) {
704
+ sp.stop();
705
+ if (err instanceof CographError) printError(err.message);
706
+ else printError(err instanceof Error ? err.message : String(err));
707
+ return;
708
+ }
709
+ sp.stop();
710
+ if (conflicts.length === 0) {
711
+ stdout.write(` ${DIM}No conflicts to review.${RESET}
712
+ `);
713
+ return;
714
+ }
715
+ const decisions = [];
716
+ let acceptAll = false;
717
+ let quitEarly = false;
718
+ for (let i = 0; i < conflicts.length; i++) {
719
+ const c = conflicts[i];
720
+ const entity = lastUriSegment(c.entity_uri);
721
+ const conf = (c.proposed?.confidence ?? 0).toFixed(2);
722
+ stdout.write("\n");
723
+ stdout.write(
724
+ ` ${DIM}[${i + 1}/${conflicts.length}]${RESET} ${BOLD}${entity}${RESET}.${CYAN}${c.attribute}${RESET}
725
+ `
726
+ );
727
+ stdout.write(
728
+ ` ${DIM}existing \u2192${RESET} ${c.existing_value}
729
+ ${DIM}proposed \u2192${RESET} ${BOLD}${c.proposed?.value ?? ""}${RESET} ${DIM}(conf ${conf}, src ${c.proposed?.source ?? "?"})${RESET}
730
+ `
731
+ );
732
+ if (c.proposed?.source_url) {
733
+ stdout.write(` ${DIM}url \u2192${RESET} ${c.proposed.source_url}
734
+ `);
735
+ }
736
+ let decision;
737
+ if (acceptAll) {
738
+ decision = "accept";
739
+ stdout.write(` ${GREEN}auto-accepted${RESET}
740
+ `);
741
+ } else {
742
+ const ans = (await ask(
743
+ rl,
744
+ ` [a]ccept / [r]eject / [s]kip / [A]ccept all remaining / [q]uit (saves progress) [s]: `
745
+ )).trim();
746
+ if (ans === "A") {
747
+ acceptAll = true;
748
+ decision = "accept";
749
+ } else if (ans === "a") {
750
+ decision = "accept";
751
+ } else if (ans === "r") {
752
+ decision = "reject";
753
+ } else if (ans === "q") {
754
+ quitEarly = true;
755
+ break;
756
+ } else {
757
+ decision = "skip";
758
+ }
759
+ }
760
+ decisions.push({ ...c, decision });
761
+ }
762
+ if (quitEarly) {
763
+ if (decisions.length === 0) {
764
+ stdout.write(` ${DIM}No decisions made \u2014 nothing to save.${RESET}
765
+ `);
766
+ return;
767
+ }
768
+ const save = (await ask(rl, ` Save ${decisions.length} decision(s) so far? [Y/n]: `)).trim().toLowerCase();
769
+ if (save !== "" && save !== "y" && save !== "yes") {
770
+ stdout.write(` ${DIM}Discarded.${RESET}
771
+ `);
772
+ return;
773
+ }
774
+ }
775
+ if (decisions.length === 0) {
776
+ stdout.write(` ${DIM}No decisions to apply.${RESET}
777
+ `);
778
+ return;
779
+ }
780
+ const sp2 = startSpinner(`Applying ${decisions.length} decision(s)...`);
781
+ try {
782
+ const res = await client.enrichApply(jobId, decisions);
783
+ sp2.stop();
784
+ stdout.write(
785
+ ` ${GREEN}\u2713${RESET} Applied ${BOLD}${fmtNum(res.applied)}${RESET} change${res.applied === 1 ? "" : "s"}.
786
+ `
787
+ );
788
+ } catch (err) {
789
+ sp2.stop();
790
+ if (err instanceof CographError) printError(err.message);
791
+ else printError(err instanceof Error ? err.message : String(err));
792
+ }
793
+ }
794
+ function urlHost(url) {
795
+ try {
796
+ return new URL(url).host;
797
+ } catch {
798
+ return url.replace(/^https?:\/\//, "").replace(/\/+$/, "");
799
+ }
800
+ }
801
+ function makePrompt(kg, triples, mode = "cloud", baseUrl) {
491
802
  const kgPart = `${DIM}(${kg})${RESET}`;
492
- if (triples > 0) {
493
- return ` ${CYAN_BOLD}cograph${RESET} ${kgPart} ${DIM}[${fmtNum(triples)}]${RESET} ${CYAN_BOLD}\u25B8${RESET} `;
803
+ const triplePart = triples > 0 ? `${DIM}[${fmtNum(triples)}]${RESET} ` : "";
804
+ if (mode === "self-hosted" && baseUrl) {
805
+ const host = urlHost(baseUrl);
806
+ return ` ${CYAN_BOLD}cograph${RESET}${DIM}@${host}${RESET} ${kgPart} ${triplePart}${CYAN_BOLD}\u25B8${RESET} `;
494
807
  }
495
- return ` ${CYAN_BOLD}cograph${RESET} ${kgPart} ${CYAN_BOLD}\u25B8${RESET} `;
808
+ return ` ${CYAN_BOLD}cograph${RESET} ${kgPart} ${triplePart}${CYAN_BOLD}\u25B8${RESET} `;
496
809
  }
497
810
  function splitArgs(s) {
498
811
  const out = [];
@@ -517,8 +830,21 @@ function splitArgs(s) {
517
830
  return out;
518
831
  }
519
832
  async function runShell(opts) {
520
- let client = new Client();
521
- if (!client.apiKey) {
833
+ const CLOUD_DEFAULT = "https://api.cograph.cloud";
834
+ const envUrl = process.env.COGRAPH_API_URL || process.env.OMNIX_API_URL;
835
+ const envIsSelfHosted = !!envUrl && envUrl !== CLOUD_DEFAULT;
836
+ const selfHostedHint = !!opts.local || !!opts.noLogin || envIsSelfHosted;
837
+ let client = opts.local ? new Client({ baseUrl: "http://localhost:8000", tenant: "default" }) : selfHostedHint ? new Client({ tenant: "default" }) : new Client();
838
+ const health = await client.healthCheck();
839
+ if (!health.ok) {
840
+ printError(
841
+ `Could not reach ${health.url}. Is the server running?`
842
+ );
843
+ return;
844
+ }
845
+ const selfHosted = selfHostedHint || !health.requiresAuth;
846
+ const mode = selfHosted ? "self-hosted" : "cloud";
847
+ if (!selfHosted && health.requiresAuth && !client.apiKey) {
522
848
  stdout.write(
523
849
  `
524
850
  ${DIM}Not signed in \u2014 opening your browser to log in...${RESET}
@@ -538,6 +864,13 @@ async function runShell(opts) {
538
864
  terminal: true
539
865
  });
540
866
  showBanner();
867
+ if (selfHosted) {
868
+ stdout.write(
869
+ `${DIM} Self-hosted mode \xB7 ${client.baseUrl} \xB7 tenant=${client.tenant}${RESET}
870
+
871
+ `
872
+ );
873
+ }
541
874
  let kg = opts.kg;
542
875
  if (!kg) {
543
876
  const picked = await selectKg(client, rl);
@@ -574,7 +907,7 @@ async function runShell(opts) {
574
907
  while (running) {
575
908
  let line;
576
909
  try {
577
- line = (await ask(rl, makePrompt(kg, triples))).trim();
910
+ line = (await ask(rl, makePrompt(kg, triples, mode, client.baseUrl))).trim();
578
911
  } catch {
579
912
  break;
580
913
  }
@@ -604,6 +937,29 @@ async function runShell(opts) {
604
937
  } else if (line.startsWith("/type ") || line === "/type") {
605
938
  const arg = line === "/type" ? "" : line.slice("/type ".length);
606
939
  await cmdType(client, kg, rl, arg);
940
+ } else if (line === "/enrich" || line.startsWith("/enrich ")) {
941
+ const args = splitArgs(line.slice("/enrich".length).trim());
942
+ if (args.length === 0) {
943
+ stdout.write(
944
+ ` ${YELLOW}Usage:${RESET} /enrich <Type> <attr> ... | /enrich watch <id> | /enrich jobs | /enrich review <id>
945
+ `
946
+ );
947
+ } else if (args[0] === "jobs") {
948
+ await cmdEnrichJobs(client);
949
+ } else if (args[0] === "watch") {
950
+ const jid = args[1];
951
+ if (!jid) {
952
+ stdout.write(` ${YELLOW}Usage:${RESET} /enrich watch <job_id>
953
+ `);
954
+ } else {
955
+ await watchJob(client, jid);
956
+ }
957
+ } else if (args[0] === "review") {
958
+ await cmdEnrichReview(client, rl, args[1] ?? "");
959
+ } else {
960
+ await cmdEnrichRun(client, kg, rl, args);
961
+ await refresh();
962
+ }
607
963
  } else if (line === "/status") {
608
964
  await cmdStatus(client, kg);
609
965
  await refresh();
@@ -728,7 +1084,7 @@ async function runShell(opts) {
728
1084
  }
729
1085
  } else if (line.startsWith("/")) {
730
1086
  stdout.write(
731
- ` ${YELLOW}Unknown command.${RESET} Try /ingest, /ask, /kg, /types, /type, /login, /status, /reset, /help, /quit
1087
+ ` ${YELLOW}Unknown command.${RESET} Try /ingest, /ask, /kg, /types, /type, /enrich, /login, /status, /reset, /help, /quit
732
1088
  `
733
1089
  );
734
1090
  } else {
@@ -744,4 +1100,4 @@ async function runShell(opts) {
744
1100
  export {
745
1101
  runShell
746
1102
  };
747
- //# sourceMappingURL=shell-H2JCK5AT.js.map
1103
+ //# sourceMappingURL=shell-TP6RVSQ2.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 {\n Client,\n CographError,\n type TypeCount,\n type EnrichJob,\n type ConflictReview,\n type JobSummary,\n} from \"./client.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 [\"/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 [\"/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\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 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 === \"/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 === \"/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, /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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cograph",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Cograph SDK and CLI — knowledge graph platform for structured data",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",