powergrid-ai 1.2.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.
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * PowerGrid CLI — Node.js wrapper for the Python powergrid-ai package.
5
+ *
6
+ * Detects Python, ensures powergrid-ai is installed via pip, then proxies
7
+ * all CLI arguments to the Python `powergrid` command.
8
+ */
9
+
10
+ const { spawn, execSync } = require("child_process");
11
+ const path = require("path");
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Helpers
15
+ // ---------------------------------------------------------------------------
16
+
17
+ function findPython() {
18
+ const candidates =
19
+ process.platform === "win32"
20
+ ? ["python", "python3", "py"]
21
+ : ["python3", "python", "python3.12", "python3.11"];
22
+
23
+ for (const cmd of candidates) {
24
+ try {
25
+ const out = execSync(`${cmd} -c "import sys; print(sys.version_info[:2])"`, {
26
+ encoding: "utf8",
27
+ timeout: 5000,
28
+ stdio: ["pipe", "pipe", "pipe"],
29
+ }).trim();
30
+ // out looks like "(3, 12)"
31
+ const match = out.match(/\((\d+),\s*(\d+)\)/);
32
+ if (match) {
33
+ const major = parseInt(match[1], 10);
34
+ const minor = parseInt(match[2], 10);
35
+ if (major >= 3 && minor >= 11) {
36
+ return { cmd, version: `${major}.${minor}` };
37
+ }
38
+ }
39
+ } catch {
40
+ // not found or too old, try next
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+
46
+ function isPowergridInstalled(pythonCmd) {
47
+ try {
48
+ execSync(`${pythonCmd} -m powergrid --help`, {
49
+ encoding: "utf8",
50
+ timeout: 5000,
51
+ stdio: ["pipe", "pipe", "pipe"],
52
+ });
53
+ return true;
54
+ } catch {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ function installPowergrid(pythonCmd) {
60
+ console.log("powergrid-ai: Installing Python package via pip...");
61
+ try {
62
+ execSync(`${pythonCmd} -m pip install powergrid-ai --quiet`, {
63
+ encoding: "utf8",
64
+ timeout: 120000,
65
+ stdio: ["inherit", "pipe", "pipe"],
66
+ });
67
+ console.log("powergrid-ai: Installed successfully!");
68
+ return true;
69
+ } catch (e) {
70
+ console.error(`powergrid-ai: Failed to install — ${e.message}`);
71
+ console.error("powergrid-ai: Try manually: pip install powergrid-ai");
72
+ return false;
73
+ }
74
+ }
75
+
76
+ // ---------------------------------------------------------------------------
77
+ // Main
78
+ // ---------------------------------------------------------------------------
79
+
80
+ function main() {
81
+ const args = process.argv.slice(2);
82
+
83
+ // --help from the wrapper itself
84
+ if (args.includes("--version") && !args.includes("--help")) {
85
+ console.log("powergrid-ai (npm wrapper) v1.1.0");
86
+ try {
87
+ const pyVer = execSync("python -c \"import powergrid; print(powergrid.__version__)\"", {
88
+ encoding: "utf8",
89
+ timeout: 5000,
90
+ stdio: ["pipe", "pipe", "pipe"],
91
+ }).trim();
92
+ console.log(`powergrid (python) v${pyVer}`);
93
+ } catch {
94
+ console.log("powergrid (python) — not installed yet");
95
+ }
96
+ return;
97
+ }
98
+
99
+ // Find Python
100
+ const python = findPython();
101
+ if (!python) {
102
+ console.error("powergrid-ai: Python 3.11+ is required but not found.");
103
+ console.error("powergrid-ai: Install Python from https://python.org/downloads");
104
+ process.exit(1);
105
+ }
106
+
107
+ // Check if powergrid is installed, install if not
108
+ if (!isPowergridInstalled(python.cmd)) {
109
+ console.log(`powergrid-ai: Python ${python.version} found (${python.cmd})`);
110
+ if (!installPowergrid(python.cmd)) {
111
+ process.exit(1);
112
+ }
113
+ }
114
+
115
+ // Proxy to the Python CLI
116
+ const child = spawn(python.cmd, ["-m", "powergrid", ...args], {
117
+ stdio: "inherit",
118
+ cwd: process.cwd(),
119
+ env: process.env,
120
+ });
121
+
122
+ child.on("exit", (code) => {
123
+ process.exit(code ?? 0);
124
+ });
125
+
126
+ child.on("error", (e) => {
127
+ console.error(`powergrid-ai: Failed to run — ${e.message}`);
128
+ process.exit(1);
129
+ });
130
+ }
131
+
132
+ main();
package/lib/setup.js ADDED
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Post-install script — ensures the Python powergrid-ai package is installed.
5
+ * Runs automatically after `npm install powergrid-ai`.
6
+ */
7
+
8
+ const { execSync } = require("child_process");
9
+
10
+ function findPython() {
11
+ const candidates =
12
+ process.platform === "win32"
13
+ ? ["python", "python3", "py"]
14
+ : ["python3", "python", "python3.12", "python3.11"];
15
+
16
+ for (const cmd of candidates) {
17
+ try {
18
+ const out = execSync(`${cmd} -c "import sys; print(sys.version_info[:2])"`, {
19
+ encoding: "utf8",
20
+ timeout: 5000,
21
+ stdio: ["pipe", "pipe", "pipe"],
22
+ }).trim();
23
+ const match = out.match(/\((\d+),\s*(\d+)\)/);
24
+ if (match) {
25
+ const major = parseInt(match[1], 10);
26
+ const minor = parseInt(match[2], 10);
27
+ if (major >= 3 && minor >= 11) return cmd;
28
+ }
29
+ } catch {
30
+ // continue
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+
36
+ function main() {
37
+ // Skip if in CI or if --ignore-scripts
38
+ if (process.env.CI || process.env.npm_config_ignore_scripts) return;
39
+
40
+ const python = findPython();
41
+ if (!python) {
42
+ console.log("");
43
+ console.log("powergrid-ai: Python 3.11+ not found.");
44
+ console.log("powergrid-ai: Install Python from https://python.org/downloads");
45
+ console.log("powergrid-ai: Then run: pip install powergrid-ai");
46
+ console.log("");
47
+ return;
48
+ }
49
+
50
+ // Check if already installed
51
+ try {
52
+ execSync(`${python} -m powergrid --help`, {
53
+ encoding: "utf8",
54
+ timeout: 5000,
55
+ stdio: ["pipe", "pipe", "pipe"],
56
+ });
57
+ // Already installed
58
+ return;
59
+ } catch {
60
+ // Not installed, install it
61
+ }
62
+
63
+ console.log(`powergrid-ai: Python ${python} found. Installing Python package...`);
64
+ try {
65
+ execSync(`${python} -m pip install powergrid-ai --quiet`, {
66
+ encoding: "utf8",
67
+ timeout: 120000,
68
+ stdio: ["inherit", "pipe", "pipe"],
69
+ });
70
+ console.log("powergrid-ai: Ready! Run: powergrid --help");
71
+ } catch (e) {
72
+ console.log("");
73
+ console.log("powergrid-ai: Auto-install failed. Install manually:");
74
+ console.log(` ${python} -m pip install powergrid-ai`);
75
+ console.log("");
76
+ }
77
+ }
78
+
79
+ main();
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "powergrid-ai",
3
+ "version": "1.2.0",
4
+ "description": "Local-first AI routing runtime — one AI, many engines. Wraps the Python powergrid-ai package.",
5
+ "keywords": [
6
+ "ai",
7
+ "routing",
8
+ "llm",
9
+ "openai",
10
+ "local-first",
11
+ "multi-provider",
12
+ "failover",
13
+ "groq",
14
+ "gemini",
15
+ "cerebras"
16
+ ],
17
+ "author": "Michael Moses",
18
+ "license": "MIT",
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/micymike/powergrid"
22
+ },
23
+ "homepage": "https://github.com/micymike/powergrid#readme",
24
+ "bugs": {
25
+ "url": "https://github.com/micymike/powergrid/issues"
26
+ },
27
+ "bin": {
28
+ "powergrid": "bin/powergrid.js"
29
+ },
30
+ "engines": {
31
+ "node": ">=18"
32
+ },
33
+ "files": [
34
+ "bin",
35
+ "lib"
36
+ ],
37
+ "scripts": {
38
+ "postinstall": "node lib/setup.js"
39
+ }
40
+ }