@pgsage/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/format.d.ts +21 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +153 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# @pgsage/cli
|
|
2
|
+
|
|
3
|
+
Command-line interface for pgsage. Wraps `@pgsage/core` and formats results for terminal output.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pgsage query <question> [options]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Options
|
|
14
|
+
|
|
15
|
+
| Flag | Description | Default |
|
|
16
|
+
|------|-------------|---------|
|
|
17
|
+
| `--json` | Output the full response as JSON | — |
|
|
18
|
+
| `--sql` | Output only the generated SQL | — |
|
|
19
|
+
| `--raw` | Output result rows as a JSON array | — |
|
|
20
|
+
| `--model <m>` | Planner/explainer model | `anthropic/claude-sonnet-4-6` |
|
|
21
|
+
| `--top-k <n>` | Schema chunks to retrieve | `10` |
|
|
22
|
+
| `--row-limit <n>` | Maximum rows to return | `500` |
|
|
23
|
+
| `-v, --version` | Show version | — |
|
|
24
|
+
| `-h, --help` | Show help | — |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Examples
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
# Simple lookup — default table output
|
|
32
|
+
pgsage query "What is the median household income in Providence County, RI?"
|
|
33
|
+
|
|
34
|
+
# Ranking
|
|
35
|
+
pgsage query "Top 10 counties by total population"
|
|
36
|
+
|
|
37
|
+
# Cross-category filter
|
|
38
|
+
pgsage query "Counties with median income above \$100k and homeownership below 60%"
|
|
39
|
+
|
|
40
|
+
# Ambiguous question — surfaces planner assumptions
|
|
41
|
+
pgsage query "Where do rich people live?"
|
|
42
|
+
|
|
43
|
+
# Pipe SQL to psql
|
|
44
|
+
pgsage query "Top 5 states by Gini index" --sql | psql $DATABASE_URL
|
|
45
|
+
|
|
46
|
+
# Parse rows with jq
|
|
47
|
+
pgsage query "Median rent in California counties" --raw | jq '.[0]'
|
|
48
|
+
|
|
49
|
+
# Full structured response
|
|
50
|
+
pgsage query "Which state has the lowest poverty rate?" --json | jq '.answer'
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Output Formats
|
|
56
|
+
|
|
57
|
+
| Flag | What you get |
|
|
58
|
+
|------|-------------|
|
|
59
|
+
| _(default)_ | Coloured table with answer, assumptions, SQL, and row data |
|
|
60
|
+
| `--json` | Complete `QueryResponse` as pretty-printed JSON |
|
|
61
|
+
| `--sql` | Just the generated SQL — pipe-friendly |
|
|
62
|
+
| `--raw` | Result rows as a JSON array — jq-friendly |
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Environment
|
|
67
|
+
|
|
68
|
+
Reads from `.env` at the repo root via `--env-file=../../.env` (set in the binary wrapper). Required variables:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
DATABASE_URL=postgres://...
|
|
72
|
+
DATABASE_READONLY_URL=postgres://...
|
|
73
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
74
|
+
VOYAGE_API_KEY=pa-...
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Testing
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
pnpm --filter @pgsage/cli test
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
16 unit tests covering all four formatters (`formatTable`, `formatJson`, `formatSql`, `formatRaw`).
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI configuration loader.
|
|
3
|
+
*
|
|
4
|
+
* Reads connection strings and API keys from environment variables,
|
|
5
|
+
* constructs pg pools and a VoyageEmbeddingProvider, and returns a
|
|
6
|
+
* ready-to-use OrchestratorConfig.
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* DATABASE_URL — required. read-write connection string.
|
|
10
|
+
* DATABASE_READONLY_URL — optional. read-only connection string.
|
|
11
|
+
* Falls back to DATABASE_URL if not set.
|
|
12
|
+
* VOYAGE_API_KEY — required. Voyage AI API key.
|
|
13
|
+
* ANTHROPIC_API_KEY — required. Anthropic API key (read by Mastra).
|
|
14
|
+
*/
|
|
15
|
+
import { type OrchestratorConfig } from "@pgsage/core";
|
|
16
|
+
export interface CliConfig {
|
|
17
|
+
agentConfig: OrchestratorConfig;
|
|
18
|
+
/** Close both pools when done. */
|
|
19
|
+
cleanup: () => Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export interface CliOptions {
|
|
22
|
+
model?: string;
|
|
23
|
+
topK?: number;
|
|
24
|
+
rowLimit?: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Load CLI configuration from environment variables.
|
|
28
|
+
* Throws with a human-readable message if a required variable is missing.
|
|
29
|
+
*/
|
|
30
|
+
export declare function loadConfig(options?: CliOptions): CliConfig;
|
|
31
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,cAAc,CAAC;AAEtB,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,kBAAkB,CAAC;IAChC,kCAAkC;IAClC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,UAAe,GAAG,SAAS,CAyB9D"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI configuration loader.
|
|
3
|
+
*
|
|
4
|
+
* Reads connection strings and API keys from environment variables,
|
|
5
|
+
* constructs pg pools and a VoyageEmbeddingProvider, and returns a
|
|
6
|
+
* ready-to-use OrchestratorConfig.
|
|
7
|
+
*
|
|
8
|
+
* Environment variables:
|
|
9
|
+
* DATABASE_URL — required. read-write connection string.
|
|
10
|
+
* DATABASE_READONLY_URL — optional. read-only connection string.
|
|
11
|
+
* Falls back to DATABASE_URL if not set.
|
|
12
|
+
* VOYAGE_API_KEY — required. Voyage AI API key.
|
|
13
|
+
* ANTHROPIC_API_KEY — required. Anthropic API key (read by Mastra).
|
|
14
|
+
*/
|
|
15
|
+
import { createPool, createReadonlyPool, VoyageEmbeddingProvider, } from "@pgsage/core";
|
|
16
|
+
/**
|
|
17
|
+
* Load CLI configuration from environment variables.
|
|
18
|
+
* Throws with a human-readable message if a required variable is missing.
|
|
19
|
+
*/
|
|
20
|
+
export function loadConfig(options = {}) {
|
|
21
|
+
const databaseUrl = requireEnv("DATABASE_URL");
|
|
22
|
+
const readonlyUrl = process.env["DATABASE_READONLY_URL"] ?? databaseUrl;
|
|
23
|
+
const voyageApiKey = requireEnv("VOYAGE_API_KEY");
|
|
24
|
+
requireEnv("ANTHROPIC_API_KEY"); // validated here; Mastra reads it from env
|
|
25
|
+
const pool = createPool(databaseUrl, { max: 3 });
|
|
26
|
+
const readonlyPool = createReadonlyPool(readonlyUrl, { max: 3 });
|
|
27
|
+
const embedder = new VoyageEmbeddingProvider({ apiKey: voyageApiKey });
|
|
28
|
+
const agentConfig = {
|
|
29
|
+
pool,
|
|
30
|
+
readonlyPool,
|
|
31
|
+
embedder,
|
|
32
|
+
model: options.model,
|
|
33
|
+
topK: options.topK,
|
|
34
|
+
rowLimit: options.rowLimit,
|
|
35
|
+
};
|
|
36
|
+
const cleanup = async () => {
|
|
37
|
+
await Promise.allSettled([pool.end(), readonlyPool.end()]);
|
|
38
|
+
};
|
|
39
|
+
return { agentConfig, cleanup };
|
|
40
|
+
}
|
|
41
|
+
function requireEnv(name) {
|
|
42
|
+
const val = process.env[name];
|
|
43
|
+
if (!val) {
|
|
44
|
+
throw new Error(`Missing required environment variable: ${name}\n` +
|
|
45
|
+
`Set it in your shell or in a .env file and use --env-file.`);
|
|
46
|
+
}
|
|
47
|
+
return val;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,UAAU,EACV,kBAAkB,EAClB,uBAAuB,GAExB,MAAM,cAAc,CAAC;AActB;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAAsB,EAAE;IACjD,MAAM,WAAW,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,WAAW,CAAC;IACxE,MAAM,YAAY,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAClD,UAAU,CAAC,mBAAmB,CAAC,CAAC,CAAC,2CAA2C;IAE5E,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,kBAAkB,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAEjE,MAAM,QAAQ,GAAG,IAAI,uBAAuB,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAEvE,MAAM,WAAW,GAAuB;QACtC,IAAI;QACJ,YAAY;QACZ,QAAQ;QACR,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,IAAmB,EAAE;QACxC,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,0CAA0C,IAAI,IAAI;YAChD,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters for the pgsage CLI.
|
|
3
|
+
*
|
|
4
|
+
* Four output modes:
|
|
5
|
+
* table — default. coloured table with assumptions + SQL footer.
|
|
6
|
+
* json — full QueryResponse serialised as pretty-printed JSON.
|
|
7
|
+
* sql — only the generated SQL, suitable for piping to psql.
|
|
8
|
+
* raw — rows as a JSON array, suitable for jq.
|
|
9
|
+
*/
|
|
10
|
+
import type { QueryResponse } from "@pgsage/core";
|
|
11
|
+
export declare function formatTable(response: QueryResponse): string;
|
|
12
|
+
export declare function formatJson(response: QueryResponse): string;
|
|
13
|
+
export declare function formatSql(response: QueryResponse): string;
|
|
14
|
+
export declare function formatRaw(response: QueryResponse): string;
|
|
15
|
+
export declare function formatError(message: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Writes a status message to stderr (so it doesn't pollute stdout piped output).
|
|
18
|
+
* Returns a stop function that clears the line.
|
|
19
|
+
*/
|
|
20
|
+
export declare function startSpinner(message: string): () => void;
|
|
21
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAoBlD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAiE3D;AAoCD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAE1D;AAMD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAEzD;AAMD,wBAAgB,SAAS,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAEzD;AAMD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,IAAI,CAmBxD"}
|
package/dist/format.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatters for the pgsage CLI.
|
|
3
|
+
*
|
|
4
|
+
* Four output modes:
|
|
5
|
+
* table — default. coloured table with assumptions + SQL footer.
|
|
6
|
+
* json — full QueryResponse serialised as pretty-printed JSON.
|
|
7
|
+
* sql — only the generated SQL, suitable for piping to psql.
|
|
8
|
+
* raw — rows as a JSON array, suitable for jq.
|
|
9
|
+
*/
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Helpers
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
/** Safely stringify any primitive DB value without triggering no-base-to-string. */
|
|
15
|
+
function primitiveString(val) {
|
|
16
|
+
if (val === null || val === undefined)
|
|
17
|
+
return "";
|
|
18
|
+
if (typeof val === "string")
|
|
19
|
+
return val;
|
|
20
|
+
if (typeof val === "number" || typeof val === "boolean" || typeof val === "bigint") {
|
|
21
|
+
return String(val);
|
|
22
|
+
}
|
|
23
|
+
return JSON.stringify(val);
|
|
24
|
+
}
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Table output (default)
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
export function formatTable(response) {
|
|
29
|
+
const lines = [];
|
|
30
|
+
if (response.rowCount === 0) {
|
|
31
|
+
lines.push(chalk.yellow(" No results returned."));
|
|
32
|
+
appendFooter(lines, response);
|
|
33
|
+
return lines.join("\n");
|
|
34
|
+
}
|
|
35
|
+
// Build column widths
|
|
36
|
+
const fields = response.fields.length > 0
|
|
37
|
+
? response.fields
|
|
38
|
+
: Object.keys(response.rows[0] ?? {});
|
|
39
|
+
const widths = fields.map((f) => f.length);
|
|
40
|
+
for (const row of response.rows) {
|
|
41
|
+
fields.forEach((f, i) => {
|
|
42
|
+
const val = primitiveString(row[f]);
|
|
43
|
+
if (val.length > widths[i])
|
|
44
|
+
widths[i] = val.length;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Cap column widths at 40 chars for readability
|
|
48
|
+
const cappedWidths = widths.map((w) => Math.min(w, 40));
|
|
49
|
+
const sep = "─".repeat(cappedWidths.reduce((s, w) => s + w + 3, 1));
|
|
50
|
+
// Header
|
|
51
|
+
lines.push(chalk.dim(" " + sep));
|
|
52
|
+
const headerCells = fields
|
|
53
|
+
.map((f, i) => chalk.bold(f.padEnd(cappedWidths[i])))
|
|
54
|
+
.join(chalk.dim(" │ "));
|
|
55
|
+
lines.push(chalk.dim(" │ ") + headerCells + chalk.dim(" │"));
|
|
56
|
+
lines.push(chalk.dim(" " + sep));
|
|
57
|
+
// Rows
|
|
58
|
+
for (const row of response.rows) {
|
|
59
|
+
const cells = fields
|
|
60
|
+
.map((f, i) => {
|
|
61
|
+
const cellVal = row[f];
|
|
62
|
+
const val = cellVal === null || cellVal === undefined
|
|
63
|
+
? chalk.dim("null")
|
|
64
|
+
: primitiveString(cellVal);
|
|
65
|
+
const truncated = val.length > 40 ? val.slice(0, 37) + "..." : val;
|
|
66
|
+
return truncated.padEnd(cappedWidths[i]);
|
|
67
|
+
})
|
|
68
|
+
.join(chalk.dim(" │ "));
|
|
69
|
+
lines.push(chalk.dim(" │ ") + cells + chalk.dim(" │"));
|
|
70
|
+
}
|
|
71
|
+
lines.push(chalk.dim(" " + sep));
|
|
72
|
+
// Row count / truncation notice
|
|
73
|
+
if (response.truncated) {
|
|
74
|
+
lines.push(chalk.yellow(`\n Showing first ${response.rowCount} rows (result truncated — increase --row-limit to see more).`));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
lines.push(chalk.dim(`\n ${response.rowCount} row${response.rowCount === 1 ? "" : "s"}`));
|
|
78
|
+
}
|
|
79
|
+
appendFooter(lines, response);
|
|
80
|
+
return lines.join("\n");
|
|
81
|
+
}
|
|
82
|
+
function appendFooter(lines, response) {
|
|
83
|
+
// Assumptions
|
|
84
|
+
if (response.assumptions.length > 0) {
|
|
85
|
+
lines.push("");
|
|
86
|
+
lines.push(chalk.cyan(" Assumptions:"));
|
|
87
|
+
for (const a of response.assumptions) {
|
|
88
|
+
lines.push(chalk.dim(" · ") + a);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Self-correction notice
|
|
92
|
+
if (response.attempts.length > 0) {
|
|
93
|
+
lines.push("");
|
|
94
|
+
lines.push(chalk.dim(` (Self-corrected after ${response.attempts.length} failed attempt${response.attempts.length === 1 ? "" : "s"}.)`));
|
|
95
|
+
}
|
|
96
|
+
// SQL
|
|
97
|
+
lines.push("");
|
|
98
|
+
lines.push(chalk.cyan(" SQL:"));
|
|
99
|
+
const indented = response.sql
|
|
100
|
+
.split("\n")
|
|
101
|
+
.map((l) => chalk.dim(" ") + chalk.green(l))
|
|
102
|
+
.join("\n");
|
|
103
|
+
lines.push(indented);
|
|
104
|
+
}
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// JSON output
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
export function formatJson(response) {
|
|
109
|
+
return JSON.stringify(response, null, 2);
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// SQL-only output
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
export function formatSql(response) {
|
|
115
|
+
return response.sql;
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Raw rows output (JSON array)
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
export function formatRaw(response) {
|
|
121
|
+
return JSON.stringify(response.rows, null, 2);
|
|
122
|
+
}
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Error output
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
export function formatError(message) {
|
|
127
|
+
return chalk.red(" Error: ") + message;
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// Spinner helpers (simple dots — no ora dependency)
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Writes a status message to stderr (so it doesn't pollute stdout piped output).
|
|
134
|
+
* Returns a stop function that clears the line.
|
|
135
|
+
*/
|
|
136
|
+
export function startSpinner(message) {
|
|
137
|
+
const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
138
|
+
let i = 0;
|
|
139
|
+
const isTTY = process.stderr.isTTY;
|
|
140
|
+
if (!isTTY) {
|
|
141
|
+
process.stderr.write(message + "\n");
|
|
142
|
+
return () => { };
|
|
143
|
+
}
|
|
144
|
+
const timer = setInterval(() => {
|
|
145
|
+
process.stderr.write(`\r${chalk.cyan(frames[i % frames.length])} ${message}`);
|
|
146
|
+
i++;
|
|
147
|
+
}, 80);
|
|
148
|
+
return () => {
|
|
149
|
+
clearInterval(timer);
|
|
150
|
+
process.stderr.write("\r\x1b[K"); // clear line
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* pgsage CLI — thin wrapper over the @pgsage/core SDK.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* pgsage query "What is the median household income in Rhode Island?"
|
|
7
|
+
* pgsage query "Top 10 counties by population" --json
|
|
8
|
+
* pgsage query "Show unemployment in Wayne County, MI" --sql
|
|
9
|
+
* pgsage query "Counties with high income and low homeownership" --raw
|
|
10
|
+
*
|
|
11
|
+
* Environment variables (set in shell or .env file):
|
|
12
|
+
* DATABASE_URL — required
|
|
13
|
+
* DATABASE_READONLY_URL — optional (falls back to DATABASE_URL)
|
|
14
|
+
* VOYAGE_API_KEY — required
|
|
15
|
+
* ANTHROPIC_API_KEY — required
|
|
16
|
+
*/
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* pgsage CLI — thin wrapper over the @pgsage/core SDK.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* pgsage query "What is the median household income in Rhode Island?"
|
|
7
|
+
* pgsage query "Top 10 counties by population" --json
|
|
8
|
+
* pgsage query "Show unemployment in Wayne County, MI" --sql
|
|
9
|
+
* pgsage query "Counties with high income and low homeownership" --raw
|
|
10
|
+
*
|
|
11
|
+
* Environment variables (set in shell or .env file):
|
|
12
|
+
* DATABASE_URL — required
|
|
13
|
+
* DATABASE_READONLY_URL — optional (falls back to DATABASE_URL)
|
|
14
|
+
* VOYAGE_API_KEY — required
|
|
15
|
+
* ANTHROPIC_API_KEY — required
|
|
16
|
+
*/
|
|
17
|
+
import { Command } from "commander";
|
|
18
|
+
import chalk from "chalk";
|
|
19
|
+
import { createAgent } from "@pgsage/core";
|
|
20
|
+
import { loadConfig } from "./config.js";
|
|
21
|
+
import { formatTable, formatJson, formatSql, formatRaw, formatError, startSpinner, } from "./format.js";
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Version (read from package.json at startup)
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Using a hardcoded version avoids needing JSON import assertions,
|
|
26
|
+
// which have inconsistent support across Node/TS versions.
|
|
27
|
+
const VERSION = "0.1.0";
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Program definition
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
const program = new Command();
|
|
32
|
+
program
|
|
33
|
+
.name("pgsage")
|
|
34
|
+
.description("Schema-aware SQL agent — ask natural-language questions against your Postgres database.")
|
|
35
|
+
.version(VERSION, "-v, --version");
|
|
36
|
+
program
|
|
37
|
+
.command("query <question>")
|
|
38
|
+
.description("Ask a natural-language question and get SQL results.")
|
|
39
|
+
.option("--json", "Output the full response as JSON (overrides other format flags)")
|
|
40
|
+
.option("--sql", "Output only the generated SQL — no execution, no results")
|
|
41
|
+
.option("--raw", "Output result rows as a JSON array")
|
|
42
|
+
.option("--model <model>", "Planner model to use (default: anthropic/claude-sonnet-4-6)")
|
|
43
|
+
.option("--top-k <n>", "Number of schema chunks to retrieve (default: 10)", parseInt)
|
|
44
|
+
.option("--row-limit <n>", "Maximum rows to return (default: 500)", parseInt)
|
|
45
|
+
.action(async (question, opts) => {
|
|
46
|
+
let cleanup;
|
|
47
|
+
try {
|
|
48
|
+
// Load config (validates env vars)
|
|
49
|
+
const config = loadConfig({
|
|
50
|
+
model: opts.model,
|
|
51
|
+
topK: opts.topK,
|
|
52
|
+
rowLimit: opts.rowLimit,
|
|
53
|
+
});
|
|
54
|
+
cleanup = config.cleanup;
|
|
55
|
+
// If --sql flag: plan only, don't execute
|
|
56
|
+
if (opts.sql) {
|
|
57
|
+
const stop = startSpinner("Planning query…");
|
|
58
|
+
try {
|
|
59
|
+
const agent = createAgent(config.agentConfig);
|
|
60
|
+
// We can't get SQL-only from the current agent interface (it always
|
|
61
|
+
// executes), so we run the full query but only print the SQL.
|
|
62
|
+
const response = await agent.query(question);
|
|
63
|
+
stop();
|
|
64
|
+
process.stdout.write(formatSql(response) + "\n");
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
stop();
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Full query
|
|
73
|
+
const stop = startSpinner("Thinking…");
|
|
74
|
+
try {
|
|
75
|
+
const agent = createAgent(config.agentConfig);
|
|
76
|
+
const response = await agent.query(question);
|
|
77
|
+
stop();
|
|
78
|
+
if (opts.json) {
|
|
79
|
+
process.stdout.write(formatJson(response) + "\n");
|
|
80
|
+
}
|
|
81
|
+
else if (opts.raw) {
|
|
82
|
+
process.stdout.write(formatRaw(response) + "\n");
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
process.stdout.write("\n" + formatTable(response) + "\n\n");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
stop();
|
|
90
|
+
throw err;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
95
|
+
process.stderr.write(formatError(message) + "\n");
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
await cleanup?.();
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
// Help output styling
|
|
104
|
+
// ---------------------------------------------------------------------------
|
|
105
|
+
program.addHelpText("after", `
|
|
106
|
+
${chalk.bold("Examples:")}
|
|
107
|
+
${chalk.dim("$")} pgsage query "What is the median household income in Providence County, RI?"
|
|
108
|
+
${chalk.dim("$")} pgsage query "Top 10 counties by population" --json
|
|
109
|
+
${chalk.dim("$")} pgsage query "Show unemployment in Wayne County, Michigan" --sql
|
|
110
|
+
${chalk.dim("$")} pgsage query "Counties with income above $100k and homeownership below 60%" --raw
|
|
111
|
+
|
|
112
|
+
${chalk.bold("Environment variables:")}
|
|
113
|
+
DATABASE_URL Read-write Postgres connection string (required)
|
|
114
|
+
DATABASE_READONLY_URL Read-only connection string (optional, falls back to DATABASE_URL)
|
|
115
|
+
VOYAGE_API_KEY Voyage AI API key (required)
|
|
116
|
+
ANTHROPIC_API_KEY Anthropic API key (required)
|
|
117
|
+
|
|
118
|
+
${chalk.bold("Tip:")}
|
|
119
|
+
Put your env vars in a .env file and run with:
|
|
120
|
+
${chalk.dim("$")} node --env-file=.env $(which pgsage) query "..."
|
|
121
|
+
`);
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Parse and run
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
program.parse();
|
|
126
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pgsage/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI wrapper for the pgsage SDK: npx pgsage query \"...\"",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"pgsage": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/hownowbrowncow/pgsage.git",
|
|
24
|
+
"directory": "packages/cli"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/hownowbrowncow/pgsage/tree/main/packages/cli",
|
|
27
|
+
"bugs": "https://github.com/hownowbrowncow/pgsage/issues",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"postgres",
|
|
30
|
+
"sql",
|
|
31
|
+
"ai",
|
|
32
|
+
"cli",
|
|
33
|
+
"pgsage",
|
|
34
|
+
"natural-language",
|
|
35
|
+
"text-to-sql"
|
|
36
|
+
],
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"chalk": "^6.0.0",
|
|
42
|
+
"commander": "^15.0.0",
|
|
43
|
+
"pg": "8.23.0",
|
|
44
|
+
"@pgsage/core": "0.1.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@types/node": "26.2.0",
|
|
48
|
+
"@types/pg": "8.23.1",
|
|
49
|
+
"typescript": "6.0.3",
|
|
50
|
+
"vitest": "4.1.11"
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsc -p tsconfig.json",
|
|
54
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
55
|
+
"lint": "eslint .",
|
|
56
|
+
"test": "vitest run --passWithNoTests"
|
|
57
|
+
}
|
|
58
|
+
}
|