@graphit/cli 0.1.4 → 0.1.6

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.
Files changed (68) hide show
  1. package/dist/api/client.d.ts +16 -0
  2. package/dist/api/client.js +67 -0
  3. package/dist/api/client.js.map +1 -0
  4. package/dist/auth/credentials.d.ts +15 -0
  5. package/dist/auth/credentials.js +34 -0
  6. package/dist/auth/credentials.js.map +1 -0
  7. package/dist/auth/login.d.ts +2 -0
  8. package/dist/auth/login.js +230 -0
  9. package/dist/auth/login.js.map +1 -0
  10. package/dist/auth/token.d.ts +5 -0
  11. package/dist/auth/token.js +42 -0
  12. package/dist/auth/token.js.map +1 -0
  13. package/dist/commands/auth.d.ts +2 -0
  14. package/dist/commands/auth.js +68 -0
  15. package/dist/commands/auth.js.map +1 -0
  16. package/dist/commands/connector.d.ts +2 -0
  17. package/dist/commands/connector.js +97 -0
  18. package/dist/commands/connector.js.map +1 -0
  19. package/dist/commands/dashboard.d.ts +2 -0
  20. package/dist/commands/dashboard.js +124 -0
  21. package/dist/commands/dashboard.js.map +1 -0
  22. package/dist/commands/ds.d.ts +2 -0
  23. package/dist/commands/ds.js +53 -0
  24. package/dist/commands/ds.js.map +1 -0
  25. package/dist/commands/kb.d.ts +2 -0
  26. package/dist/commands/kb.js +505 -0
  27. package/dist/commands/kb.js.map +1 -0
  28. package/dist/commands/query.d.ts +2 -0
  29. package/dist/commands/query.js +61 -0
  30. package/dist/commands/query.js.map +1 -0
  31. package/dist/commands/setup.d.ts +2 -0
  32. package/dist/commands/setup.js +173 -0
  33. package/dist/commands/setup.js.map +1 -0
  34. package/dist/config.d.ts +4 -0
  35. package/dist/config.js +9 -0
  36. package/dist/config.js.map +1 -0
  37. package/dist/index.d.ts +2 -0
  38. package/dist/index.js +27 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/output/format.d.ts +8 -0
  41. package/dist/output/format.js +30 -0
  42. package/dist/output/format.js.map +1 -0
  43. package/dist/output/json.d.ts +1 -0
  44. package/dist/output/json.js +4 -0
  45. package/dist/output/json.js.map +1 -0
  46. package/dist/output/table.d.ts +2 -0
  47. package/dist/output/table.js +17 -0
  48. package/dist/output/table.js.map +1 -0
  49. package/dist/update-check.d.ts +3 -0
  50. package/dist/update-check.js +78 -0
  51. package/dist/update-check.js.map +1 -0
  52. package/package.json +1 -1
  53. package/skills/graphit/SKILL.md +84 -8
  54. package/skills/graphit/cursor/graphit-kb-actions.mdc +101 -0
  55. package/skills/graphit/cursor/graphit-kb-awareness.mdc +88 -0
  56. package/skills/graphit/cursor/graphit-kb-explanation.mdc +56 -0
  57. package/skills/graphit/cursor/graphit-kb-exploration.mdc +7 -13
  58. package/skills/graphit/cursor/graphit-kb-graph-structure.mdc +61 -0
  59. package/skills/graphit/cursor/graphit-kb-traversal.mdc +64 -0
  60. package/skills/graphit/cursor/graphit-parameterized-metrics.mdc +95 -0
  61. package/skills/graphit/graphit.mdc +12 -1
  62. package/skills/graphit/references/kb-actions.md +95 -0
  63. package/skills/graphit/references/kb-awareness.md +82 -0
  64. package/skills/graphit/references/kb-explanation.md +50 -0
  65. package/skills/graphit/references/kb-exploration.md +7 -13
  66. package/skills/graphit/references/kb-graph-structure.md +55 -0
  67. package/skills/graphit/references/kb-traversal.md +58 -0
  68. package/skills/graphit/references/parameterized-metrics.md +89 -0
@@ -0,0 +1,173 @@
1
+ import { existsSync, readdirSync } from "node:fs";
2
+ import { readFile, writeFile, mkdir, copyFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join, dirname } from "node:path";
5
+ import { execFileSync } from "node:child_process";
6
+ import { readCredentials } from "../auth/credentials.js";
7
+ function resolveSkillDir() {
8
+ const fromDist = join(dirname(new URL(import.meta.url).pathname), "..", "..", "skills", "graphit");
9
+ if (existsSync(join(fromDist, "SKILL.md")))
10
+ return fromDist;
11
+ return join(dirname(dirname(dirname(import.meta.url.replace("file://", "")))), "skills", "graphit");
12
+ }
13
+ function detectEditors() {
14
+ const editors = [];
15
+ if (existsSync(".claude") || commandExists("claude"))
16
+ editors.push("claude-code");
17
+ if (existsSync(".cursor"))
18
+ editors.push("cursor");
19
+ if (existsSync(".codex") || commandExists("codex"))
20
+ editors.push("codex");
21
+ if (existsSync(".vscode"))
22
+ editors.push("vscode");
23
+ return editors;
24
+ }
25
+ function commandExists(cmd) {
26
+ try {
27
+ execFileSync("which", [cmd], { stdio: "ignore" });
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ function getInstallTargets(editors, project, skillMd, cursorMdc) {
35
+ const targets = [];
36
+ const home = homedir();
37
+ for (const editor of editors) {
38
+ switch (editor) {
39
+ case "claude-code": {
40
+ const base = project
41
+ ? join(".claude", "skills", "graphit")
42
+ : join(home, ".claude", "skills", "graphit");
43
+ targets.push({
44
+ editor,
45
+ path: join(base, "SKILL.md"),
46
+ content: skillMd,
47
+ refsDir: join(base, "references"),
48
+ });
49
+ break;
50
+ }
51
+ case "codex": {
52
+ const base = project
53
+ ? join(".codex", "skills", "graphit")
54
+ : join(home, ".codex", "skills", "graphit");
55
+ targets.push({
56
+ editor,
57
+ path: join(base, "SKILL.md"),
58
+ content: skillMd,
59
+ refsDir: join(base, "references"),
60
+ });
61
+ break;
62
+ }
63
+ case "cursor":
64
+ targets.push({
65
+ editor,
66
+ path: project
67
+ ? join(".cursor", "rules", "graphit.mdc")
68
+ : join(home, ".cursor", "rules", "graphit.mdc"),
69
+ content: cursorMdc,
70
+ });
71
+ break;
72
+ case "vscode":
73
+ if (project) {
74
+ targets.push({ editor, path: "AGENTS.md", content: skillMd });
75
+ }
76
+ break;
77
+ }
78
+ }
79
+ return targets;
80
+ }
81
+ async function installReferences(sourceRefsDir, targetRefsDir, update) {
82
+ if (!existsSync(sourceRefsDir))
83
+ return [];
84
+ const files = readdirSync(sourceRefsDir).filter((f) => f.endsWith(".md"));
85
+ if (files.length === 0)
86
+ return [];
87
+ await mkdir(targetRefsDir, { recursive: true });
88
+ const written = [];
89
+ for (const file of files) {
90
+ const targetPath = join(targetRefsDir, file);
91
+ if (existsSync(targetPath) && !update)
92
+ continue;
93
+ if (existsSync(targetPath) && update) {
94
+ await copyFile(targetPath, `${targetPath}.bak`);
95
+ }
96
+ const content = await readFile(join(sourceRefsDir, file), "utf-8");
97
+ await writeFile(targetPath, content, "utf-8");
98
+ written.push(targetPath);
99
+ }
100
+ return written;
101
+ }
102
+ export function registerSetupCommand(program) {
103
+ program
104
+ .command("setup")
105
+ .description("Install Graphit skill for your AI coding assistant")
106
+ .option("--editor <name>", "Override editor detection (claude-code, cursor, codex, vscode)")
107
+ .option("--project", "Install at project level (in repo, committable)")
108
+ .option("--update", "Overwrite existing skill files")
109
+ .option("--dry-run", "Show what would be installed without writing")
110
+ .action(async function () {
111
+ const opts = this.opts();
112
+ const creds = await readCredentials();
113
+ if (!creds) {
114
+ console.log("Warning: Not logged in. Run `graphit auth login` first for full functionality.\n");
115
+ }
116
+ let editors;
117
+ if (opts.editor) {
118
+ editors = [opts.editor];
119
+ }
120
+ else {
121
+ editors = detectEditors();
122
+ if (editors.length === 0) {
123
+ console.error(JSON.stringify({
124
+ error: "No supported editor detected. Use --editor to specify one.",
125
+ }));
126
+ process.exit(1);
127
+ }
128
+ }
129
+ const skillDir = resolveSkillDir();
130
+ const skillMd = await readFile(join(skillDir, "SKILL.md"), "utf-8");
131
+ const cursorMdc = await readFile(join(skillDir, "graphit.mdc"), "utf-8");
132
+ const sourceRefsDir = join(skillDir, "references");
133
+ const targets = getInstallTargets(editors, !!opts.project, skillMd, cursorMdc);
134
+ if (targets.length === 0) {
135
+ console.error(JSON.stringify({ error: "No install targets found." }));
136
+ process.exit(1);
137
+ }
138
+ if (opts.dryRun) {
139
+ console.log("Dry run - would install:\n");
140
+ for (const t of targets) {
141
+ console.log(` ${t.editor}: ${t.path}`);
142
+ if (t.refsDir && existsSync(sourceRefsDir)) {
143
+ const refs = readdirSync(sourceRefsDir).filter((f) => f.endsWith(".md"));
144
+ refs.forEach((r) => console.log(` ${t.editor}: ${join(t.refsDir, r)}`));
145
+ }
146
+ }
147
+ return;
148
+ }
149
+ for (const target of targets) {
150
+ if (existsSync(target.path) && !opts.update) {
151
+ console.log(`Skill file already exists at ${target.path}. Use --update to overwrite.`);
152
+ continue;
153
+ }
154
+ if (existsSync(target.path) && opts.update) {
155
+ await copyFile(target.path, `${target.path}.bak`);
156
+ }
157
+ await mkdir(dirname(target.path), { recursive: true });
158
+ await writeFile(target.path, target.content, "utf-8");
159
+ console.log(`Written: ${target.path}`);
160
+ if (target.refsDir) {
161
+ const refFiles = await installReferences(sourceRefsDir, target.refsDir, !!opts.update);
162
+ if (refFiles.length > 0) {
163
+ console.log(`Written: ${refFiles.length} reference files to ${target.refsDir}/`);
164
+ }
165
+ }
166
+ }
167
+ const mode = opts.project ? "project" : "global";
168
+ const editorNames = editors.join(", ");
169
+ console.log(`\nGraphit skill installed for ${editorNames} (${mode}).`);
170
+ console.log('\nTry: "Explore the Graphit KB and build a revenue dashboard"');
171
+ });
172
+ }
173
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare const DEFAULT_API_BASE_URL = "https://api.graphit-app.com";
2
+ export declare const DEFAULT_FRONTEND_URL = "https://graphit-app.com";
3
+ export declare function getApiBaseUrl(): string;
4
+ export declare function getFrontendUrl(): string;
package/dist/config.js ADDED
@@ -0,0 +1,9 @@
1
+ export const DEFAULT_API_BASE_URL = "https://api.graphit-app.com";
2
+ export const DEFAULT_FRONTEND_URL = "https://graphit-app.com";
3
+ export function getApiBaseUrl() {
4
+ return process.env.GRAPHIT_API_URL || DEFAULT_API_BASE_URL;
5
+ }
6
+ export function getFrontendUrl() {
7
+ return process.env.GRAPHIT_FRONTEND_URL || DEFAULT_FRONTEND_URL;
8
+ }
9
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAClE,MAAM,CAAC,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE9D,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,oBAAoB,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,oBAAoB,CAAC;AAClE,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { registerAuthCommands } from "./commands/auth.js";
4
+ import { registerKBCommands } from "./commands/kb.js";
5
+ import { registerQueryCommands } from "./commands/query.js";
6
+ import { registerDSCommands } from "./commands/ds.js";
7
+ import { registerDashboardCommands } from "./commands/dashboard.js";
8
+ import { registerConnectorCommands } from "./commands/connector.js";
9
+ import { registerSetupCommand } from "./commands/setup.js";
10
+ import { getCurrentVersion, printUpdateBanner, fireBackgroundCheck, } from "./update-check.js";
11
+ const program = new Command();
12
+ program
13
+ .name("graphit")
14
+ .description("Graphit CLI - Build custom dashboards from any AI coding assistant")
15
+ .version(getCurrentVersion())
16
+ .option("--output <format>", "Output format: json (default) or table", "json");
17
+ registerAuthCommands(program);
18
+ registerKBCommands(program);
19
+ registerQueryCommands(program);
20
+ registerDSCommands(program);
21
+ registerDashboardCommands(program);
22
+ registerConnectorCommands(program);
23
+ registerSetupCommand(program);
24
+ printUpdateBanner();
25
+ program.parse();
26
+ fireBackgroundCheck();
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,oEAAoE,CAAC;KACjF,OAAO,CAAC,iBAAiB,EAAE,CAAC;KAC5B,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,EAAE,MAAM,CAAC,CAAC;AAEjF,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAE9B,iBAAiB,EAAE,CAAC;AACpB,OAAO,CAAC,KAAK,EAAE,CAAC;AAChB,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Command } from "commander";
2
+ export type OutputFormat = "json" | "table";
3
+ export declare function getOutputFormat(cmd: Command): OutputFormat;
4
+ export declare function output(cmd: Command, data: unknown, opts?: {
5
+ columns?: string[];
6
+ keyValue?: boolean;
7
+ }): void;
8
+ export declare function errorOutput(err: unknown): void;
@@ -0,0 +1,30 @@
1
+ import { formatJson } from "./json.js";
2
+ import { formatTable, formatKeyValue } from "./table.js";
3
+ export function getOutputFormat(cmd) {
4
+ const root = cmd.parent ?? cmd;
5
+ const format = root.opts().output;
6
+ return format === "table" ? "table" : "json";
7
+ }
8
+ export function output(cmd, data, opts) {
9
+ const format = getOutputFormat(cmd);
10
+ if (format === "json") {
11
+ console.log(formatJson(data));
12
+ return;
13
+ }
14
+ if (opts?.keyValue && !Array.isArray(data)) {
15
+ console.log(formatKeyValue(data));
16
+ return;
17
+ }
18
+ const rows = Array.isArray(data) ? data : [data];
19
+ console.log(formatTable(rows, opts?.columns));
20
+ }
21
+ export function errorOutput(err) {
22
+ const message = err instanceof Error
23
+ ? err.message
24
+ : typeof err === "object" && err !== null && "detail" in err
25
+ ? err.detail
26
+ : String(err);
27
+ console.error(JSON.stringify({ error: message }));
28
+ process.exit(1);
29
+ }
30
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/output/format.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIzD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,MAAgB,CAAC;IAC5C,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,MAAM,CACpB,GAAY,EACZ,IAAa,EACb,IAAiD;IAEjD,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9B,OAAO;IACT,CAAC;IAED,IAAI,IAAI,EAAE,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAA+B,CAAC,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,IAAiC,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,OAAO,GACX,GAAG,YAAY,KAAK;QAClB,CAAC,CAAC,GAAG,CAAC,OAAO;QACb,CAAC,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,QAAQ,IAAI,GAAG;YAC1D,CAAC,CAAE,GAA0B,CAAC,MAAM;YACpC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAEpB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function formatJson(data: unknown): string;
@@ -0,0 +1,4 @@
1
+ export function formatJson(data) {
2
+ return JSON.stringify(data, null, 2);
3
+ }
4
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../src/output/json.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function formatTable(rows: Record<string, unknown>[], columns?: string[]): string;
2
+ export declare function formatKeyValue(data: Record<string, unknown>): string;
@@ -0,0 +1,17 @@
1
+ export function formatTable(rows, columns) {
2
+ if (rows.length === 0)
3
+ return "(no results)";
4
+ const cols = columns || Object.keys(rows[0]);
5
+ const widths = cols.map((col) => Math.max(col.length, ...rows.map((r) => String(r[col] ?? "").length)));
6
+ const header = cols.map((col, i) => col.padEnd(widths[i])).join(" ");
7
+ const separator = widths.map((w) => "-".repeat(w)).join(" ");
8
+ const body = rows.map((row) => cols.map((col, i) => String(row[col] ?? "").padEnd(widths[i])).join(" "));
9
+ return [header, separator, ...body].join("\n");
10
+ }
11
+ export function formatKeyValue(data) {
12
+ const maxKeyLen = Math.max(...Object.keys(data).map((k) => k.length));
13
+ return Object.entries(data)
14
+ .map(([k, v]) => `${k.padEnd(maxKeyLen)} ${v}`)
15
+ .join("\n");
16
+ }
17
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/output/table.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CACzB,IAA+B,EAC/B,OAAkB;IAElB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC;IAE7C,MAAM,IAAI,GAAG,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC9B,IAAI,CAAC,GAAG,CACN,GAAG,CAAC,MAAM,EACV,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAChD,CACF,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAC1E,CAAC;IAEF,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA6B;IAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function getCurrentVersion(): string;
2
+ export declare function printUpdateBanner(): void;
3
+ export declare function fireBackgroundCheck(): void;
@@ -0,0 +1,78 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ import { createRequire } from "module";
5
+ const require = createRequire(import.meta.url);
6
+ const pkg = require("../package.json");
7
+ const REGISTRY_URL = "https://registry.npmjs.org/@graphit/cli/latest";
8
+ const CACHE_DIR = join(homedir(), ".graphit");
9
+ const CACHE_FILE = join(CACHE_DIR, "update-check.json");
10
+ const TTL_MS = 24 * 60 * 60 * 1000;
11
+ function readCache() {
12
+ try {
13
+ if (!existsSync(CACHE_FILE))
14
+ return null;
15
+ const raw = readFileSync(CACHE_FILE, "utf-8");
16
+ return JSON.parse(raw);
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ function writeCache(entry) {
23
+ try {
24
+ if (!existsSync(CACHE_DIR))
25
+ mkdirSync(CACHE_DIR, { recursive: true });
26
+ writeFileSync(CACHE_FILE, JSON.stringify(entry));
27
+ }
28
+ catch {
29
+ // silent - cache write failure is not critical
30
+ }
31
+ }
32
+ function isNewer(latest, current) {
33
+ const l = latest.split(".").map(Number);
34
+ const c = current.split(".").map(Number);
35
+ for (let i = 0; i < 3; i++) {
36
+ if ((l[i] ?? 0) > (c[i] ?? 0))
37
+ return true;
38
+ if ((l[i] ?? 0) < (c[i] ?? 0))
39
+ return false;
40
+ }
41
+ return false;
42
+ }
43
+ export function getCurrentVersion() {
44
+ return pkg.version;
45
+ }
46
+ export function printUpdateBanner() {
47
+ const cache = readCache();
48
+ if (!cache)
49
+ return;
50
+ const current = getCurrentVersion();
51
+ if (!isNewer(cache.latestVersion, current))
52
+ return;
53
+ process.stderr.write(`\n Update available: ${current} → ${cache.latestVersion}\n` +
54
+ ` Run \`npm update -g @graphit/cli\` to update\n\n`);
55
+ }
56
+ export function fireBackgroundCheck() {
57
+ const cache = readCache();
58
+ if (cache && Date.now() - cache.checkedAt < TTL_MS)
59
+ return;
60
+ fetch(REGISTRY_URL, { signal: AbortSignal.timeout(3000) })
61
+ .then((res) => {
62
+ if (!res.ok)
63
+ return;
64
+ return res.json();
65
+ })
66
+ .then((data) => {
67
+ if (data && typeof data === "object" && "version" in data) {
68
+ writeCache({
69
+ latestVersion: data.version,
70
+ checkedAt: Date.now(),
71
+ });
72
+ }
73
+ })
74
+ .catch(() => {
75
+ // silent - network failure is not critical
76
+ });
77
+ }
78
+ //# sourceMappingURL=update-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphit/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Graphit CLI - Build custom dashboards from any AI coding assistant",
5
5
  "type": "module",
6
6
  "bin": {
@@ -88,27 +88,97 @@ NEVER embed query results as static JS variables. The dashboard iframe provides
88
88
 
89
89
  ---
90
90
 
91
- ## Workflow
91
+ ## Workflow: Dashboard Build
92
92
 
93
93
  1. **Ask the user** what dashboard they want. Don't start querying until you know what they need.
94
- 2. **Explore KB** to understand available metrics, dimensions, tables, and rules.
94
+ 2. **Explore KB** - use `graphit kb list domains` then `graphit kb explore domain <NAME>` to traverse existing assets. Search by concept with `graphit kb search "revenue"`. See `kb-exploration.md` for KB-first discovery, `kb-traversal.md` for tool selection.
95
95
  3. **Find a data source** (`graphit ds list`) - prefer cached data sources (~100ms) over live warehouse (~10s).
96
96
  4. **Query data to validate** - run queries via the CLI to verify SQL and preview results. Show the user what you found.
97
97
  5. **Build HTML** - write `graphit.resolve()` calls for live data + `graphit.chart/table/kpi` for rendering. All CSS in `<style>`, all JS in `<script>`. Write to a local `.html` file.
98
98
  6. **Save** with `graphit dashboard update-html <id> --file <path>`.
99
99
  7. Give the user the dashboard URL so they can open it.
100
100
 
101
+ ## Workflow: KB Build / Onboarding
102
+
103
+ When the user wants to build or populate their KB (from files, schema descriptions, or scratch). Consult `kb-graph-structure.md` for the full graph model, `kb-traversal.md` for tool selection, `kb-actions.md` for the CLI command matrix, `kb-awareness.md` for when to propose asset creation, and `parameterized-metrics.md` for template metrics.
104
+
105
+ **Step 1: Audit current KB state.** Before proposing anything, traverse the existing KB:
106
+
107
+ 1. `graphit kb list domains` - get all domains (with asset counts)
108
+ 2. For each domain: `graphit kb explore domain <NAME>` - returns all tables and assets in that domain in one traversal (see `kb-traversal.md` depth guidelines)
109
+ 3. `graphit kb list synonyms` and `graphit kb list relationships` - global assets not scoped to domains
110
+
111
+ Present a tree summary of what already exists, following the Domain > Table > Topic > Asset hierarchy from `kb-graph-structure.md`.
112
+
113
+ **Step 2: Analyze input.** Read the user's files, schema, or description. Classify every concept by asset type. Use `kb-explanation.md` for asset type definitions (what is a metric vs dimension vs rule). Use `kb-awareness.md` for signals (aggregation = metric, derived grouping = dimension, business constraint = rule, colloquial term = synonym).
114
+
115
+ **Step 3: Present a tree-structured plan.** Show what will be created, organized by the KB hierarchy. Mark existing assets with (exists) so the user sees what's new vs what's already there:
116
+
117
+ ```
118
+ KB Plan:
119
+
120
+ MARKETING (domain) (exists)
121
+ MARKETING_UA (table) (exists)
122
+ ACQUISITION (topic) (exists)
123
+ - TOTAL_SPEND (metric) = SUM(APPSFLYER_COST) **NEW**
124
+ - CPI (metric) (exists)
125
+ - MEDIA_SOURCE (dimension) (exists)
126
+ - CAMPAIGN_NAME (dimension) **NEW**
127
+ ATTRIBUTION (topic) **NEW**
128
+ - ROAS_D7 (metric) = SUM(revenue_d7) / NULLIF(SUM(cost), 0) **NEW**
129
+ - ATTRIBUTION_WINDOW (dimension) **NEW**
130
+ Rules:
131
+ - EXCLUDE_ORGANIC (rule) (exists)
132
+ - ACTIVE_CAMPAIGNS_ONLY (rule) = "WHERE status = 'active'" **NEW**
133
+ MARKETING_UA_6MO (table) (exists)
134
+ (reference TOTAL_SPEND, CPI from MARKETING_UA via secondary_tables)
135
+
136
+ PRODUCT (domain) **NEW**
137
+ EVENTS (table) (exists)
138
+ RETENTION (topic) **NEW**
139
+ - DAU (metric) = COUNT(DISTINCT user_id) **NEW**
140
+ - RETENTION_D7 (metric) **NEW**
141
+
142
+ Global:
143
+ - Synonyms: GMV -> TOTAL_REVENUE (metric) **NEW**
144
+ - Relationships: MARKETING_UA.USER_ID -> EVENTS.USER_ID **NEW**
145
+
146
+ Summary: 5 new metrics, 2 new dimensions, 1 new rule, 1 new domain, 2 new topics, 1 synonym, 1 relationship
147
+ ```
148
+
149
+ For metrics with natural variant axes (D7/D30/D90, gross/net), propose parameterized templates instead of standalone metrics (see `parameterized-metrics.md`).
150
+
151
+ **Step 4: Wait for user approval.** Do not create anything until the user confirms the plan.
152
+
153
+ **Step 5: Execute top-down.** Create in dependency order (see `kb-actions.md` for full CLI command reference):
154
+ 1. Domains (`graphit kb create domain --name X`)
155
+ 2. Topics (`graphit kb create topic --name X`)
156
+ 3. Metrics and dimensions (`graphit kb create metric/dimension ... --topics "A,B"`)
157
+ 4. Rules (`graphit kb create rule`)
158
+ 5. Synonyms (`graphit kb create synonym --term X --canonical Y --type metric`)
159
+ 6. Relationships (`graphit kb create relationship`)
160
+ 7. Attachments: assign domains to tables (`graphit kb update table X --domain Y`), add secondary_tables for cross-table references (`graphit kb update metric X --secondary-tables "T1,T2"`)
161
+
162
+ **Step 6: Verify.** Re-traverse: `graphit kb explore domain <NAME>` for each domain. Show the user the final tree and confirm counts match the plan.
163
+
101
164
  ## Commands
102
165
 
103
166
  | Command | Description |
104
167
  |---------|-------------|
105
- | `graphit kb list <type>` | List metrics, dimensions, tables, rules, domains, synonyms, templates |
168
+ | `graphit kb list <type>` | List entities: metric, dimension, table, rule, domain, synonym, template, relationship, topic |
106
169
  | `graphit kb get <type> <name>` | Full entity details by name |
107
- | `graphit kb search <query>` | Search across all KB types |
170
+ | `graphit kb search <query>` | Search across all KB types (optional `--type` filter) |
108
171
  | `graphit kb explore metric <name>` | Metric -> tables -> dimensions graph |
109
- | `graphit kb create template --name X --file template.html --description "..."` | Save a reusable chart template (--file or --render-code) |
110
- | `graphit kb update template <name> --file template.html --description "..."` | Update a template (--file or --render-code) |
111
- | `graphit kb delete template <name> --yes` | Delete a template |
172
+ | `graphit kb create metric --name X --sql "..." --table T` | Create a metric |
173
+ | `graphit kb create dimension --name X --expr "..." --table T` | Create a dimension (optional `--type categorical`) |
174
+ | `graphit kb create rule --name X --sql "..." --table T` | Create a rule |
175
+ | `graphit kb create synonym --term X --canonical Y --type metric` | Create a synonym (type: metric, column, table) |
176
+ | `graphit kb create domain --name X` | Create a domain (optional `--color "#hex"`) |
177
+ | `graphit kb create relationship --name X --primary-table T --primary-column C --related-table T2 --related-column C2` | Create a JOIN relationship |
178
+ | `graphit kb create topic --name X` | Create a topic (business-concept tag) |
179
+ | `graphit kb create template --name X --file template.html` | Save a reusable chart template (--file or --render-code) |
180
+ | `graphit kb update <type> <name> --field value` | Update any entity (fields vary by type) |
181
+ | `graphit kb delete <type> <name> --yes` | Delete any entity (all types supported) |
112
182
  | `graphit ds list` | List cached data sources (use these for fast queries) |
113
183
  | `graphit query "<sql>" --ds <id>` | Query cached data source (~100ms) |
114
184
  | `graphit query "<sql>" --warehouse --connection <id>` | Query live Snowflake (~10s) |
@@ -230,7 +300,13 @@ Detailed knowledge lives in `references/`. Consult the relevant file when you ne
230
300
  |------|-------------|
231
301
  | `dashboard-planning.md` | Building a multi-chart dashboard. Covers framing the question, picking archetype, mandatory rules, metric contracts, anti-patterns. |
232
302
  | `chart-selection.md` | Choosing chart types. Full dimension/measure defaults, perception ranking, cardinality guards, hard caps. |
233
- | `kb-exploration.md` | Starting a build. KB-first discovery, metric vs dimension, naming conventions, reuse patterns, formula syntax. |
303
+ | `kb-exploration.md` | Starting a build. KB-first discovery, metric vs dimension, naming conventions, formula syntax. |
304
+ | `kb-awareness.md` | KB-first planning. When to propose KB asset creation, reuse over reinvention, cross-table referencing, topic assignment. |
305
+ | `kb-graph-structure.md` | KB graph model. 9 node types, 5 edge types, multi-membership semantics, domain cascade, tree rendering order. |
306
+ | `kb-explanation.md` | Structural Q&A. What are domains, topics, tables, relationships, memory. Why assets appear where they do. |
307
+ | `kb-traversal.md` | Graph queries. Tool selection guide (search vs explore vs read), common query patterns, depth guidelines. |
308
+ | `kb-actions.md` | Full CRUD matrix. Asset create/edit/delete, topic management, domain assignment cascade, navigation and discovery. |
309
+ | `parameterized-metrics.md` | Metric templates. ${PARAM:NAME} tokens, child variant auto-generation, editing templates, using variants in queries. |
234
310
  | `sql-reference.md` | Writing queries. DuckDB/Snowflake translation, formatting standards, gap-filling, JSON access, data source routing. |
235
311
  | `domain-lenses.md` | Data matches a business domain. Marketing, finance, product/growth, ops, sales - signals, key metrics, must-have charts, anti-patterns. |
236
312
  | `graphit-style.md` | Building the HTML. Design principles, typography scale, color system with usage rules, layout patterns (page structure, KPI cards, data tables). |