@cartanova/qgrid-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/dist/cli.js +107 -0
- package/package.json +26 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
//#region src/cli.ts
|
|
7
|
+
const QGRID_DIR = join(homedir(), ".qgrid");
|
|
8
|
+
const COMPOSE_FILE = join(QGRID_DIR, "docker-compose.yml");
|
|
9
|
+
const IMAGE = "ghcr.io/cartanova-ai/qgrid:latest";
|
|
10
|
+
function ensureDocker() {
|
|
11
|
+
try {
|
|
12
|
+
execSync("docker --version", { stdio: "ignore" });
|
|
13
|
+
} catch {
|
|
14
|
+
console.error("Error: Docker not found.");
|
|
15
|
+
console.error("Install: https://docs.docker.com/get-docker/");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function ensureQgridDir() {
|
|
20
|
+
if (!existsSync(QGRID_DIR)) mkdirSync(QGRID_DIR, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
function generateCompose(opts) {
|
|
23
|
+
const env = [
|
|
24
|
+
` DB_HOST: "${opts.dbHost ?? "postgres"}"`,
|
|
25
|
+
` DB_PORT: "${opts.dbHost ? opts.dbPort : "5432"}"`,
|
|
26
|
+
` DB_USER: "${opts.dbUser}"`,
|
|
27
|
+
` DB_PASSWORD: "${opts.dbPassword}"`,
|
|
28
|
+
` DB_NAME: "qgrid"`,
|
|
29
|
+
` HOST: "0.0.0.0"`,
|
|
30
|
+
` PORT: "${opts.port}"`
|
|
31
|
+
].join("\n");
|
|
32
|
+
let compose = `services:
|
|
33
|
+
qgrid:
|
|
34
|
+
image: ${IMAGE}
|
|
35
|
+
ports:
|
|
36
|
+
- "${opts.port}:${opts.port}"
|
|
37
|
+
environment:
|
|
38
|
+
${env}
|
|
39
|
+
restart: unless-stopped`;
|
|
40
|
+
if (!opts.dbHost) compose += `
|
|
41
|
+
depends_on:
|
|
42
|
+
postgres:
|
|
43
|
+
condition: service_healthy
|
|
44
|
+
|
|
45
|
+
postgres:
|
|
46
|
+
image: postgres:18
|
|
47
|
+
ports:
|
|
48
|
+
- "${opts.dbPort}:5432"
|
|
49
|
+
environment:
|
|
50
|
+
POSTGRES_USER: ${opts.dbUser}
|
|
51
|
+
POSTGRES_PASSWORD: ${opts.dbPassword}
|
|
52
|
+
POSTGRES_DB: qgrid
|
|
53
|
+
healthcheck:
|
|
54
|
+
test: ["CMD-SHELL", "pg_isready"]
|
|
55
|
+
interval: 3s
|
|
56
|
+
retries: 5
|
|
57
|
+
volumes:
|
|
58
|
+
- qgrid-data:/var/lib/postgresql
|
|
59
|
+
|
|
60
|
+
volumes:
|
|
61
|
+
qgrid-data:`;
|
|
62
|
+
return `${compose}\n`;
|
|
63
|
+
}
|
|
64
|
+
const program = new Command();
|
|
65
|
+
program.name("qgrid").version("0.1.0").description("Qgrid ā LLM subscription token proxy server");
|
|
66
|
+
program.command("start").description("Start Qgrid server (+ PostgreSQL if no --db-host)").option("--port <port>", "server port", "44900").option("--db-host <host>", "external DB host (skip local PostgreSQL)").option("--db-port <port>", "DB port", "44901").option("--db-user <user>", "DB user", "postgres").option("--db-password <password>", "DB password", "postgres").action((opts) => {
|
|
67
|
+
ensureDocker();
|
|
68
|
+
ensureQgridDir();
|
|
69
|
+
writeFileSync(COMPOSE_FILE, generateCompose(opts));
|
|
70
|
+
console.log(opts.dbHost ? "Starting Qgrid server (external DB)..." : "Starting Qgrid server + PostgreSQL...");
|
|
71
|
+
try {
|
|
72
|
+
execSync(`docker compose -f "${COMPOSE_FILE}" up -d`, { stdio: "inherit" });
|
|
73
|
+
console.log(`\nā Qgrid is running at http://localhost:${opts.port}`);
|
|
74
|
+
} catch {
|
|
75
|
+
console.error("Failed to start. Check Docker is running.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
program.command("stop").description("Stop Qgrid server").action(() => {
|
|
80
|
+
ensureDocker();
|
|
81
|
+
if (!existsSync(COMPOSE_FILE)) {
|
|
82
|
+
console.log("Qgrid is not running.");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
execSync(`docker compose -f "${COMPOSE_FILE}" down`, { stdio: "inherit" });
|
|
87
|
+
console.log("ā Qgrid stopped.");
|
|
88
|
+
} catch {
|
|
89
|
+
console.error("Failed to stop.");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
program.command("status").description("Show Qgrid server status").action(() => {
|
|
94
|
+
ensureDocker();
|
|
95
|
+
if (!existsSync(COMPOSE_FILE)) {
|
|
96
|
+
console.log("Qgrid is not running.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
execSync(`docker compose -f "${COMPOSE_FILE}" ps`, { stdio: "inherit" });
|
|
101
|
+
} catch {
|
|
102
|
+
console.log("Qgrid is not running.");
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
program.parse();
|
|
106
|
+
//#endregion
|
|
107
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cartanova/qgrid-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"bin": {
|
|
5
|
+
"qgrid": "./dist/cli.js"
|
|
6
|
+
},
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsdown",
|
|
13
|
+
"prepublishOnly": "pnpm run build"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"commander": "^13.0.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@types/node": "catalog:",
|
|
20
|
+
"tsdown": "catalog:",
|
|
21
|
+
"typescript": "catalog:"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20"
|
|
25
|
+
}
|
|
26
|
+
}
|