@graphit/cli 0.2.259 → 0.2.270

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 (46) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/bin/graphit +1 -1
  5. package/bin/graphit.ps1 +1 -1
  6. package/dist/commands/ds/api.d.ts +19 -0
  7. package/dist/commands/ds/api.js +74 -0
  8. package/dist/commands/ds/api.js.map +1 -0
  9. package/dist/commands/ds/polling.d.ts +13 -0
  10. package/dist/commands/ds/polling.js +189 -0
  11. package/dist/commands/ds/polling.js.map +1 -0
  12. package/dist/commands/ds/render.d.ts +15 -0
  13. package/dist/commands/ds/render.js +88 -0
  14. package/dist/commands/ds/render.js.map +1 -0
  15. package/dist/commands/ds/types.d.ts +65 -0
  16. package/dist/commands/ds/types.js +31 -0
  17. package/dist/commands/ds/types.js.map +1 -0
  18. package/dist/commands/ds/ui-only.d.ts +15 -0
  19. package/dist/commands/ds/ui-only.js +29 -0
  20. package/dist/commands/ds/ui-only.js.map +1 -0
  21. package/dist/commands/ds-config.d.ts +1 -0
  22. package/dist/commands/ds-config.js +25 -2
  23. package/dist/commands/ds-config.js.map +1 -1
  24. package/dist/commands/ds.js +10 -355
  25. package/dist/commands/ds.js.map +1 -1
  26. package/dist/commands/kb-create.js +11 -6
  27. package/dist/commands/kb-create.js.map +1 -1
  28. package/dist/commands/kb-delete.js +10 -2
  29. package/dist/commands/kb-delete.js.map +1 -1
  30. package/dist/commands/kb-read.js +6 -2
  31. package/dist/commands/kb-read.js.map +1 -1
  32. package/dist/commands/kb-shared.d.ts +16 -1
  33. package/dist/commands/kb-shared.js +28 -0
  34. package/dist/commands/kb-shared.js.map +1 -1
  35. package/dist/commands/kb-update.js +11 -5
  36. package/dist/commands/kb-update.js.map +1 -1
  37. package/package.json +1 -1
  38. package/scripts/sync-plugin-marketplace.sh +134 -0
  39. package/skills/graphit/SKILL.md +7 -7
  40. package/skills/graphit/VERSION.json +1 -1
  41. package/skills/graphit/references/data-sources.md +8 -6
  42. package/skills/graphit/references/kb-discovery.md +1 -1
  43. package/skills/graphit/references/kb-scope.md +23 -0
  44. package/skills/graphit/references/kb-structure.md +3 -1
  45. package/skills/graphit/references/kb-traversal.md +1 -4
  46. package/skills/graphit/references/onboarding.md +12 -3
@@ -7,7 +7,7 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "Graphit CLI plugin for AI coding assistants",
10
- "version": "0.2.259"
10
+ "version": "0.2.270"
11
11
  },
12
12
  "plugins": [
13
13
  {
@@ -16,9 +16,9 @@
16
16
  "source": {
17
17
  "source": "npm",
18
18
  "package": "@graphit/cli",
19
- "version": "0.2.259"
19
+ "version": "0.2.270"
20
20
  },
21
- "version": "0.2.259",
21
+ "version": "0.2.270",
22
22
  "category": "data-visualization",
23
23
  "tags": [
24
24
  "bi",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphit",
3
- "version": "0.2.259",
3
+ "version": "0.2.270",
4
4
  "description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
5
5
  "author": {
6
6
  "name": "Graphit",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphit",
3
- "version": "0.2.259",
3
+ "version": "0.2.270",
4
4
  "description": "Build custom HTML dashboards from real data using the Graphit CLI. KB-aware queries, entity wrapping, cached data sources.",
5
5
  "author": {
6
6
  "name": "Graphit",
package/bin/graphit CHANGED
@@ -14,7 +14,7 @@ if [ -z "${GRAPHIT_PLUGIN_ROOT:-}" ]; then
14
14
  fi
15
15
 
16
16
  # graphit:floor (stamped by scripts/sync-plugin-version.mjs from cli/package.json)
17
- FLOOR_VERSION="0.2.259"
17
+ FLOOR_VERSION="0.2.270"
18
18
 
19
19
  PACKAGE_NAME="@graphit/cli"
20
20
  # Strict semver: anything else is rejected so a tampered cache cannot inject.
package/bin/graphit.ps1 CHANGED
@@ -7,7 +7,7 @@ if (-not $env:GRAPHIT_PLUGIN_ROOT) {
7
7
  }
8
8
 
9
9
  # graphit:floor (stamped by scripts/sync-plugin-version.mjs from cli/package.json)
10
- $FloorVersion = "0.2.259"
10
+ $FloorVersion = "0.2.270"
11
11
 
12
12
  $PackageName = "@graphit/cli"
13
13
  # Strict semver: anything else is rejected so a tampered cache cannot inject.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Backend calls behind the `ds` commands (list, refresh trigger, scan, file create).
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { DSInfo, ScanResult } from "./types.js";
11
+ import { Command } from "commander";
12
+ export declare function fetchDSList(limit?: number): Promise<DSInfo[]>;
13
+ export declare function triggerRefresh(id: string, force?: boolean): Promise<{
14
+ id: string;
15
+ status: string;
16
+ error?: string;
17
+ }>;
18
+ export declare function scanDS(id: string, force?: boolean, acceptSchema?: boolean): Promise<ScanResult>;
19
+ export declare function createDataSourceFromFile(cmd: Command, opts: Record<string, unknown>): Promise<void>;
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Backend calls behind the `ds` commands (list, refresh trigger, scan, file create).
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { existsSync } from "node:fs";
11
+ import { readFile } from "node:fs/promises";
12
+ import { basename } from "node:path";
13
+ import { apiClient } from "../../api/client.js";
14
+ import { errorOutput, note, output } from "../../output/format.js";
15
+ import { REFRESH_TRIGGER_TIMEOUT_MS, SCAN_TIMEOUT_MS } from "./types.js";
16
+ export async function fetchDSList(limit = 200) {
17
+ const resp = await apiClient.get(`/api/v1/cli/ds?limit=${limit}`);
18
+ return resp.data_sources;
19
+ }
20
+ export async function triggerRefresh(id, force = false) {
21
+ try {
22
+ const query = force ? "?force=true" : "";
23
+ const resp = await apiClient.post(`/api/v1/cli/ds/${id}/refresh${query}`, {}, { timeoutMs: REFRESH_TRIGGER_TIMEOUT_MS });
24
+ return resp;
25
+ }
26
+ catch (err) {
27
+ const msg = err instanceof Error ? err.message : String(err.detail ?? err);
28
+ if (msg.toLowerCase().includes("timeout") || msg.toLowerCase().includes("timed out")) {
29
+ return { id, status: "refreshing", error: "trigger timed out (refresh continues server-side)" };
30
+ }
31
+ return { id, status: "error", error: msg };
32
+ }
33
+ }
34
+ export async function scanDS(id, force = false, acceptSchema = false) {
35
+ const params = new URLSearchParams();
36
+ if (force)
37
+ params.set("force", "true");
38
+ if (acceptSchema)
39
+ params.set("accept_schema", "true");
40
+ const qs = params.toString();
41
+ return apiClient.post(`/api/v1/cli/ds/${id}/scan${qs ? `?${qs}` : ""}`, {}, { timeoutMs: SCAN_TIMEOUT_MS });
42
+ }
43
+ export async function createDataSourceFromFile(cmd, opts) {
44
+ const filePath = String(opts.file);
45
+ if (!existsSync(filePath)) {
46
+ errorOutput(new Error(`File not found: ${filePath}`));
47
+ return;
48
+ }
49
+ const buf = await readFile(filePath);
50
+ const filename = basename(filePath);
51
+ const form = new FormData();
52
+ form.append("file", new Blob([buf]), filename);
53
+ if (opts.name)
54
+ form.append("name", String(opts.name));
55
+ if (opts.sheet)
56
+ form.append("sheet", String(opts.sheet));
57
+ if (opts.domain)
58
+ form.append("domain", String(opts.domain));
59
+ note(` Uploading ${filename}...`);
60
+ const resp = await apiClient.postMultipart("/api/v1/cli/ds/upload", form, { timeoutMs: 120_000 });
61
+ if (resp.domain_note)
62
+ note(` ${resp.domain_note}`);
63
+ output(cmd, resp, { keyValue: true });
64
+ }
65
+ // Data-source lifecycle actions that are deliberately UI-only. Destroying or
66
+ // re-pointing a source cascades into dashboards, KB tables and cached snapshots,
67
+ // so it stays behind the Sources Hub where the blast radius is shown before you
68
+ // commit. Creating one from the CLI is safe and stays supported.
69
+ //
70
+ // Registered as real commands rather than left to Commander's bare
71
+ // `unknown command 'delete'`: an agent that gets "unknown command" concludes the
72
+ // CLI is incomplete and goes hunting for a flag or a workaround. It needs to
73
+ // learn the boundary is intentional and where the action actually lives.
74
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/commands/ds/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Wait loops for refresh and creation, and the post-create scan summary.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { DSInfo, ScanResult } from "./types.js";
11
+ export declare function pollUntilReady(targetIds: Set<string>, targets: Map<string, DSInfo>, errors: Map<string, string>): Promise<boolean>;
12
+ export declare function pollUntilDSReady(id: string, name: string): Promise<DSInfo | null>;
13
+ export declare function scanAndPrintSummary(dsId: string, dsName: string, rowCount?: number, force?: boolean, acceptSchema?: boolean): Promise<ScanResult | null>;
@@ -0,0 +1,189 @@
1
+ /**
2
+ * Wait loops for refresh and creation, and the post-create scan summary.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { note } from "../../output/format.js";
11
+ import { NOT_FOUND_STATUS, isCreatePollTerminal, reconcilePoll } from "../ds-poll.js";
12
+ import { fetchDSList, scanDS } from "./api.js";
13
+ import { formatRowCount, printShapeWarnings, printStatusTable, printVerifySummary } from "./render.js";
14
+ import { MAX_CREATE_POLL_DURATION_MS, MAX_POLL_DURATION_MS, POLL_INTERVAL_MS } from "./types.js";
15
+ // Returns true if it gave up at the timeout, false if every target reached a
16
+ // terminal state - the caller surfaces this as `timed_out` in the JSON summary.
17
+ export async function pollUntilReady(targetIds, targets, errors) {
18
+ const isTTY = process.stderr.isTTY ?? false;
19
+ const statuses = new Map();
20
+ for (const id of targetIds)
21
+ statuses.set(id, "refreshing");
22
+ const missCounts = new Map();
23
+ let printed = false;
24
+ printStatusTable(targets, statuses, errors, false);
25
+ printed = true;
26
+ const pollStart = Date.now();
27
+ while (true) {
28
+ await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
29
+ if (Date.now() - pollStart > MAX_POLL_DURATION_MS) {
30
+ note(`\n Timed out after ${MAX_POLL_DURATION_MS / 60_000}m waiting for refresh to complete.`);
31
+ break;
32
+ }
33
+ let fresh;
34
+ try {
35
+ fresh = await fetchDSList();
36
+ }
37
+ catch {
38
+ // Issue #775: tolerate a transient network/transport blip during the wait
39
+ // instead of aborting the refresh-wait and misreporting still-refreshing
40
+ // sources as failed. Re-poll (the loop sleeps first) until the timeout cap.
41
+ continue;
42
+ }
43
+ const freshMap = new Map(fresh.map((ds) => [ds.id, ds]));
44
+ // A target absent from the fresh list (deleted mid-wait, or transiently
45
+ // omitted) is declared not_found after a couple of polls so the loop ends
46
+ // promptly instead of spinning to MAX_POLL_DURATION_MS.
47
+ const allDone = reconcilePoll(targetIds, freshMap, statuses, targets, missCounts);
48
+ if (isTTY && printed) {
49
+ printStatusTable(targets, statuses, errors, true);
50
+ }
51
+ if (allDone) {
52
+ if (!isTTY && printed) {
53
+ note("");
54
+ printStatusTable(targets, statuses, errors, false);
55
+ }
56
+ // A target only counts as refreshed if it reached "ready" AND nothing went
57
+ // wrong for it. A trigger that errored (or timed out) leaves the source at
58
+ // its previous "ready", so counting status alone reported "1/1 refreshed"
59
+ // with the error sitting in the same payload - the summary contradicting
60
+ // the data beneath it.
61
+ const readyCount = Array.from(statuses.entries()).filter(([id, s]) => s === "ready" && !errors.has(id)).length;
62
+ const errorCount = Array.from(statuses.entries()).filter(([id, s]) => s === "error" || errors.has(id)).length;
63
+ const notFoundCount = Array.from(statuses.values()).filter((s) => s === NOT_FOUND_STATUS).length;
64
+ note(`\n ${readyCount}/${targetIds.size} refreshed${errorCount > 0 ? `, ${errorCount} failed` : ""}${notFoundCount > 0 ? `, ${notFoundCount} not found` : ""}`);
65
+ return false;
66
+ }
67
+ }
68
+ return true;
69
+ }
70
+ export async function pollUntilDSReady(id, name) {
71
+ const isTTY = process.stderr.isTTY ?? false;
72
+ const start = Date.now();
73
+ if (isTTY)
74
+ process.stderr.write(` Materializing ${name}...`);
75
+ // Feature #661: creation gets the longer create-poll budget (not the 5-min
76
+ // refresh cap), so a legit large load isn't reported as timed-out while still
77
+ // materializing in the Job.
78
+ let firstPoll = true;
79
+ while (Date.now() - start < MAX_CREATE_POLL_DURATION_MS) {
80
+ // Issue #775: poll immediately on the first pass, then wait between polls.
81
+ // An inline create (Project #247) already returned a terminal status from
82
+ // the POST, so sleeping first would tax every inline `ds create --sql` a
83
+ // guaranteed ~POLL_INTERVAL_MS before it can report done. Every `continue`
84
+ // below falls back here, so later passes (and retries) still wait first.
85
+ if (!firstPoll)
86
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
87
+ firstPoll = false;
88
+ let all;
89
+ try {
90
+ all = await fetchDSList();
91
+ }
92
+ catch {
93
+ // Issue #775: a transient network/transport blip during the up-to-70-min
94
+ // create window must NOT abort the poll and misreport a still-materializing
95
+ // source as failed. Tolerate the throw and re-poll (the next pass waits the
96
+ // poll interval first, matching triggerRefresh's tolerance). A genuine
97
+ // create failure arrives as status "error" in a successful response and is
98
+ // handled below - it is never swallowed here.
99
+ continue;
100
+ }
101
+ const ds = all.find((d) => d.id === id);
102
+ if (!ds)
103
+ continue;
104
+ if (!isCreatePollTerminal(ds.status))
105
+ continue;
106
+ // Issue #775: pending_verification is a terminal SUCCESS (server-side scan
107
+ // succeeded during creation); without this branch the loop spun to the
108
+ // 70-minute create cap on every scan-succeeded SQL create.
109
+ if (ds.status === "pending_verification") {
110
+ if (isTTY)
111
+ process.stderr.write(` scanned (${formatRowCount(ds.row_count)} rows), awaiting verification\n`);
112
+ else
113
+ note(` ${name}: scanned (${formatRowCount(ds.row_count)} rows), awaiting verification`);
114
+ return ds;
115
+ }
116
+ if (ds.status === "ready") {
117
+ if (isTTY)
118
+ process.stderr.write(` ready (${formatRowCount(ds.row_count)} rows)\n`);
119
+ else
120
+ note(` ${name}: ready (${formatRowCount(ds.row_count)} rows)`);
121
+ return ds;
122
+ }
123
+ if (ds.status === "error") {
124
+ // Feature #661: surface the real, actionable failure reason (was a bare
125
+ // "error" before - useless to a foreign agent driving the CLI).
126
+ if (isTTY)
127
+ process.stderr.write(` failed\n`);
128
+ const detail = ds.last_error || "Data source creation failed.";
129
+ note(` ${name}: ${detail}`);
130
+ return ds;
131
+ }
132
+ // Issue #775: guard the #775 regression. The status is already terminal (it
133
+ // passed isCreatePollTerminal), so any status without a branch above - e.g. a
134
+ // success status later added to CREATE_SUCCESS_STATUSES - must still end the
135
+ // poll. Falling through here would spin to the 70-min cap and reintroduce the
136
+ // hang the guard and branches must not drift into.
137
+ if (isTTY)
138
+ process.stderr.write(` ${ds.status} (${formatRowCount(ds.row_count)} rows)\n`);
139
+ else
140
+ note(` ${name}: ${ds.status} (${formatRowCount(ds.row_count)} rows)`);
141
+ return ds;
142
+ }
143
+ // Feature #661: non-alarming - the Job may still be materializing server-side.
144
+ note(`\n ${name} is still materializing server-side. Check status later with: graphit ds list`);
145
+ return null;
146
+ }
147
+ // Issue #775: single copy of the "scanned, awaiting verification" call to action.
148
+ // Printed identically after a create that lands at pending_verification and after
149
+ // `ds verify` scans a warehouse/SQL source - kept in one place so the two paths
150
+ // (create action + printVerifySummary) cannot drift.
151
+ export async function scanAndPrintSummary(dsId, dsName, rowCount, force = false, acceptSchema = false) {
152
+ const isTTY = process.stderr.isTTY ?? false;
153
+ if (isTTY)
154
+ process.stderr.write(` Scanning schema...`);
155
+ try {
156
+ const scan = await scanDS(dsId, force, acceptSchema);
157
+ if (isTTY) {
158
+ const label = scan.already_scanned ? "already scanned" : "done";
159
+ process.stderr.write(` ${label} (${scan.column_count} columns)\n`);
160
+ }
161
+ else {
162
+ note(` ${dsName}: scanned (${scan.column_count} columns)`);
163
+ }
164
+ printVerifySummary(scan, dsId, rowCount);
165
+ printShapeWarnings(scan.validation);
166
+ return scan;
167
+ }
168
+ catch (err) {
169
+ if (isTTY)
170
+ process.stderr.write(` failed\n`);
171
+ const msg = err instanceof Error ? err.message : String(err.detail ?? err);
172
+ note(` Scan failed: ${msg}`);
173
+ // Project #263 Phase 13 (13.8): never advise a retry the server has already
174
+ // said cannot work. `ds verify` is a gated write, so this catch now sees
175
+ // permission denials - and offering "you can retry" on a `retryable: false`
176
+ // problem is the retry-loop bait 13.5 removed from the denial body, put back
177
+ // by the client. Read the FIELD, not the prose.
178
+ const problem = err.problem;
179
+ if (problem?.retryable === false) {
180
+ if (problem.next_step)
181
+ note(` ${problem.next_step}`);
182
+ }
183
+ else {
184
+ note(` You can retry with: graphit ds verify ${dsId}`);
185
+ }
186
+ return null;
187
+ }
188
+ }
189
+ //# sourceMappingURL=polling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polling.js","sourceRoot":"","sources":["../../../src/commands/ds/polling.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Terminal rendering for the `ds` commands - status table, verify summary, advisories.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import type { DSInfo, ScanResult, ShapeValidation } from "./types.js";
11
+ export declare function printShapeWarnings(validation?: ShapeValidation): void;
12
+ export declare function formatRowCount(n: number): string;
13
+ export declare function printStatusTable(targets: Map<string, DSInfo>, statuses: Map<string, string>, errors: Map<string, string>, clearPrevious: boolean): number;
14
+ export declare function printVerificationCTA(dsId: string): void;
15
+ export declare function printVerifySummary(scan: ScanResult, dsId: string, rowCount?: number): void;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Terminal rendering for the `ds` commands - status table, verify summary, advisories.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { getFrontendUrl } from "../../config.js";
11
+ import { note } from "../../output/format.js";
12
+ import { NOT_FOUND_STATUS } from "../ds-poll.js";
13
+ // Project #244: print soft, non-blocking shape advisories. Print-and-proceed -
14
+ // these never gate a create or verify.
15
+ export function printShapeWarnings(validation) {
16
+ if (!validation?.warnings?.length)
17
+ return;
18
+ note("");
19
+ for (const w of validation.warnings) {
20
+ note(` ! ${w}`);
21
+ }
22
+ note("");
23
+ }
24
+ export function formatRowCount(n) {
25
+ if (n >= 1_000_000)
26
+ return `${(n / 1_000_000).toFixed(1)}M`;
27
+ if (n >= 1_000)
28
+ return `${(n / 1_000).toFixed(1)}K`;
29
+ return String(n);
30
+ }
31
+ export function printStatusTable(targets, statuses, errors, clearPrevious) {
32
+ const lines = [];
33
+ const nameWidth = Math.max(4, ...Array.from(targets.values()).map((ds) => ds.name.length));
34
+ lines.push(` ${"NAME".padEnd(nameWidth)} ${"STATUS".padEnd(12)} ${"ROWS".padStart(8)}`);
35
+ lines.push(` ${"─".repeat(nameWidth)} ${"─".repeat(12)} ${"─".repeat(8)}`);
36
+ for (const [id, ds] of targets) {
37
+ const status = statuses.get(id) ?? ds.status;
38
+ const error = errors.get(id);
39
+ const icon = status === "ready" ? "+" : status === "error" ? "x" : status === NOT_FOUND_STATUS ? "?" : "*";
40
+ const rowStr = formatRowCount(ds.row_count).padStart(8);
41
+ let line = ` ${ds.name.padEnd(nameWidth)} ${icon} ${status.padEnd(10)} ${rowStr}`;
42
+ if (error)
43
+ line += ` ${error}`;
44
+ lines.push(line);
45
+ }
46
+ // Progress table is decoration -> stderr (with its in-place cursor escapes on
47
+ // the same stream), so stdout stays a clean payload.
48
+ if (clearPrevious) {
49
+ process.stderr.write(`\x1B[${lines.length + 1}A\x1B[J`);
50
+ }
51
+ note(lines.join("\n"));
52
+ return lines.length;
53
+ }
54
+ export function printVerificationCTA(dsId) {
55
+ const url = `${getFrontendUrl()}/sources?tab=sources&sub=data&id=${dsId}`;
56
+ note(`\n Scanned and awaiting verification. Review and activate in the platform:`);
57
+ note(` ${url}`);
58
+ note(`\n Or accept the AI schema as-is from the CLI:`);
59
+ note(` graphit ds verify ${dsId} --accept-schema\n`);
60
+ }
61
+ export function printVerifySummary(scan, dsId, rowCount) {
62
+ const line = "─".repeat(Math.max(scan.table_name.length, 30));
63
+ note(`\n ${scan.table_name}`);
64
+ note(` ${line}`);
65
+ const colSummary = scan.columns
66
+ .slice(0, 6)
67
+ .map((c) => `${c.name} (${c.type})`)
68
+ .join(", ");
69
+ const more = scan.columns.length > 6 ? `, +${scan.columns.length - 6} more` : "";
70
+ note(` Columns: ${colSummary}${more}`);
71
+ if (rowCount !== undefined) {
72
+ note(` Rows: ${formatRowCount(rowCount)}`);
73
+ }
74
+ // A file-upload verify (or an --accept-schema warehouse verify) activates the
75
+ // source server-side, so there is nothing left to do - say so (Issue #544/#546).
76
+ // Confirmed against the state the server reports back, not against the request
77
+ // we made: a scan that demoted the source must fall through to the CTA below.
78
+ if (scan.activated && scan.status !== "pending_verification") {
79
+ note(`\n Verified - this data source is now queryable.\n`);
80
+ return;
81
+ }
82
+ // Scanned but awaiting review (warehouse/SQL): the AI-inferred schema needs a
83
+ // human to accept it. Offer both governed paths - review in the platform wizard,
84
+ // or accept the schema as-is from the CLI (Issue #546). This is not "still
85
+ // materializing" - the data is on disk; only verification is pending.
86
+ printVerificationCTA(dsId);
87
+ }
88
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../../src/commands/ds/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,+EAA+E;AAC/E,uCAAuC;AACvC,MAAM,UAAU,kBAAkB,CAAC,UAA4B;IAC7D,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM;QAAE,OAAO;IAC1C,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAS;IACtC,IAAI,CAAC,IAAI,SAAS;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAC5D,IAAI,CAAC,IAAI,KAAK;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IACpD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,OAA4B,EAC5B,QAA6B,EAC7B,MAA2B,EAC3B,aAAsB;IAEtB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE3F,KAAK,CAAC,IAAI,CACR,KAAK,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CACjF,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEhF,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,IAAI,GACR,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAChG,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC;QACvF,IAAI,KAAK;YAAE,IAAI,IAAI,MAAM,KAAK,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,8EAA8E;IAC9E,qDAAqD;IACrD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,MAAM,GAAG,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,MAAM,GAAG,GAAG,GAAG,cAAc,EAAE,oCAAoC,IAAI,EAAE,CAAC;IAC1E,IAAI,CAAC,6EAA6E,CAAC,CAAC;IACpF,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACjB,IAAI,CAAC,iDAAiD,CAAC,CAAC;IACxD,IAAI,CAAC,uBAAuB,IAAI,oBAAoB,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAgB,EAAE,IAAY,EAAE,QAAiB;IAClF,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAC/B,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IAElB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO;SAC5B,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC;SACnC,IAAI,CAAC,IAAI,CAAC,CAAC;IACd,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,IAAI,CAAC,cAAc,UAAU,GAAG,IAAI,EAAE,CAAC,CAAC;IAExC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,8EAA8E;IAC9E,iFAAiF;IACjF,+EAA+E;IAC/E,8EAA8E;IAC9E,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,sBAAsB,EAAE,CAAC;QAC7D,IAAI,CAAC,qDAAqD,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,8EAA8E;IAC9E,iFAAiF;IACjF,2EAA2E;IAC3E,sEAAsE;IACtE,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Shared types and timeout budgets for the `ds` command family.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ export interface DSInfo {
11
+ id: string;
12
+ name: string;
13
+ status: string;
14
+ row_count: number;
15
+ source_sql: string;
16
+ verified: boolean;
17
+ connector_type: string;
18
+ last_refreshed: string;
19
+ failure_reason?: string | null;
20
+ last_error?: string | null;
21
+ }
22
+ export interface DSListResponse {
23
+ data_sources: DSInfo[];
24
+ }
25
+ export interface ShapeValidation {
26
+ status: string;
27
+ warnings?: string[];
28
+ display_instruction?: string;
29
+ }
30
+ export interface ScanResult {
31
+ data_source_id: string;
32
+ kb_table_id: string;
33
+ table_name: string;
34
+ column_count: number;
35
+ columns: {
36
+ name: string;
37
+ type: string;
38
+ description: string;
39
+ }[];
40
+ already_scanned: boolean;
41
+ activated?: boolean;
42
+ validation?: ShapeValidation;
43
+ status?: string;
44
+ verified?: boolean;
45
+ }
46
+ export declare const POLL_INTERVAL_MS = 3000;
47
+ export declare const MAX_POLL_DURATION_MS: number;
48
+ export declare const MAX_CREATE_POLL_DURATION_MS: number;
49
+ export declare const SCAN_TIMEOUT_MS = 90000;
50
+ export declare const REFRESH_TRIGGER_TIMEOUT_MS = 60000;
51
+ export declare const CREATE_TIMEOUT_MS = 120000;
52
+ export interface FileUploadResult {
53
+ id: string;
54
+ name: string;
55
+ status: string;
56
+ row_count: number;
57
+ kb_table_id: string | null;
58
+ domain: string | null;
59
+ domain_note?: string;
60
+ }
61
+ /**
62
+ * Create a data source from a local Excel/CSV file (Feature #645). Uploads the
63
+ * file as multipart; the server parses, runs the inline AI scan, encrypts, and
64
+ * (optionally) attaches the new table to a domain - all in one request.
65
+ */
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared types and timeout budgets for the `ds` command family.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ export const POLL_INTERVAL_MS = 3_000;
11
+ export const MAX_POLL_DURATION_MS = 5 * 60_000;
12
+ // Feature #661 + #665: creation runs in a durable Job whose export budget was raised
13
+ // to 60 min (Feature #665), with the worker socket timeout at ~70 min (budget + margin).
14
+ // The create poller must outlast the server-side budget so a legit large load isn't
15
+ // reported as "timed out" client-side while it's still materializing.
16
+ export const MAX_CREATE_POLL_DURATION_MS = 70 * 60_000;
17
+ export const SCAN_TIMEOUT_MS = 90_000;
18
+ export const REFRESH_TRIGGER_TIMEOUT_MS = 60_000;
19
+ // Issue #775: a small/single-table create routes INLINE (Project #247) - the POST
20
+ // itself runs the warehouse export + scan + canonical birth in-request and returns
21
+ // a terminal status, so it needs the same extended budget as the other
22
+ // warehouse-touching POSTs (upload 120s, scan 90s) instead of the 30s default,
23
+ // which a cold-connection inline export races even though the source is born fine.
24
+ // A Job-routed create returns CREATING immediately and never approaches this ceiling.
25
+ export const CREATE_TIMEOUT_MS = 120_000;
26
+ /**
27
+ * Create a data source from a local Excel/CSV file (Feature #645). Uploads the
28
+ * file as multipart; the server parses, runs the inline AI scan, encrypts, and
29
+ * (optionally) attaches the new table to a domain - all in one request.
30
+ */
31
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/ds/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA4CH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,MAAM,CAAC;AAC/C,qFAAqF;AACrF,yFAAyF;AACzF,oFAAoF;AACpF,sEAAsE;AACtE,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,GAAG,MAAM,CAAC;AACvD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AACtC,MAAM,CAAC,MAAM,0BAA0B,GAAG,MAAM,CAAC;AACjD,kFAAkF;AAClF,mFAAmF;AACnF,uEAAuE;AACvE,+EAA+E;AAC/E,mFAAmF;AACnF,sFAAsF;AACtF,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAYzC;;;;GAIG"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The `ds` actions that exist only in the web UI, registered so the CLI names them.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { Command } from "commander";
11
+ export declare const UI_ONLY_DS_ACTIONS: {
12
+ name: string;
13
+ summary: string;
14
+ }[];
15
+ export declare function registerUiOnlyDSActions(ds: Command): void;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The `ds` actions that exist only in the web UI, registered so the CLI names them.
3
+ *
4
+ * Project #272 Phase 0: extracted from `commands/ds.ts` (which crossed 800
5
+ * lines) into the existing `commands/ds/` subfolder, joining `refresh-history.ts`.
6
+ * Mechanical split - no behavior change. `registerDSCommands` stays whole in
7
+ * `ds.ts` so no Commander metadata moves and the generated command table in
8
+ * SKILL.md cannot drift.
9
+ */
10
+ import { getFrontendUrl } from "../../config.js";
11
+ import { errorOutput } from "../../output/format.js";
12
+ export const UI_ONLY_DS_ACTIONS = [
13
+ { name: "delete <id>", summary: "Delete a data source - not available on the CLI, use the Sources Hub" },
14
+ { name: "move <id>", summary: "Move a data source between domains - not available on the CLI, use the Sources Hub" },
15
+ ];
16
+ export function registerUiOnlyDSActions(ds) {
17
+ for (const action of UI_ONLY_DS_ACTIONS) {
18
+ const verb = action.name.split(" ")[0];
19
+ ds.command(action.name)
20
+ .description(action.summary)
21
+ .action(function () {
22
+ const url = `${getFrontendUrl()}/sources?tab=sources&sub=data`;
23
+ errorOutput(new Error(`\`ds ${verb}\` is not available on the CLI. Data source ${verb} runs from the ` +
24
+ `Sources Hub, which shows what the change cascades into before it happens: ${url}`));
25
+ process.exitCode = 1;
26
+ });
27
+ }
28
+ }
29
+ //# sourceMappingURL=ui-only.js.map