@pikaa-ai/pikaa 0.1.8 → 0.1.9

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.
File without changes
package/bin/pikaa.js CHANGED
@@ -3,10 +3,9 @@
3
3
  /**
4
4
  * Universal Cross-Platform Dispatcher for Pikaa / Groupy Agent.
5
5
  *
6
- * Priority order:
7
- * 1. Precompiled native binary (zero-dependency, instant start)
8
- * 2. Bun runtime running the bundled JS (requires Bun installed)
9
- * 3. Clear error message pointing user to install Bun
6
+ * 1. Runs precompiled native binary if present (downloaded by postinstall)
7
+ * 2. Falls back to Bun if installed (rare, for unsupported platforms)
8
+ * 3. Shows helpful install instructions if neither is available
10
9
  */
11
10
 
12
11
  import { spawnSync } from "node:child_process";
@@ -21,87 +20,54 @@ const rootDir = join(__dirname, "..");
21
20
  const platform = process.platform;
22
21
  const arch = process.arch;
23
22
 
24
- // Map OS & Arch to precompiled binary filename
25
23
  function getBinaryName() {
26
- if (platform === "win32") {
27
- return arch === "arm64" ? "pikaa-windows-arm64.exe" : "pikaa-windows-x64.exe";
28
- }
29
- if (platform === "darwin") {
30
- return arch === "arm64" ? "pikaa-darwin-arm64" : "pikaa-darwin-x64";
31
- }
32
- if (platform === "linux") {
33
- return arch === "arm64" ? "pikaa-linux-arm64" : "pikaa-linux-x64";
34
- }
24
+ if (platform === "win32") return arch === "arm64" ? "pikaa-windows-arm64.exe" : "pikaa-windows-x64.exe";
25
+ if (platform === "darwin") return arch === "arm64" ? "pikaa-darwin-arm64" : "pikaa-darwin-x64";
26
+ if (platform === "linux") return arch === "arm64" ? "pikaa-linux-arm64" : "pikaa-linux-x64";
35
27
  return null;
36
28
  }
37
29
 
38
- // --- 1. Try native binary ---
30
+ // --- 1. Native binary (postinstall should have placed it here) ---
39
31
  const binaryName = getBinaryName();
40
- let nativeBinaryPath = null;
41
-
42
32
  if (binaryName) {
43
33
  for (const p of [
44
- join(rootDir, "dist", "bin", binaryName),
45
34
  join(rootDir, "bin", binaryName),
46
- join(rootDir, binaryName),
35
+ join(rootDir, "dist", "bin", binaryName),
47
36
  ]) {
48
37
  if (existsSync(p)) {
49
- nativeBinaryPath = p;
50
- break;
38
+ if (platform !== "win32") {
39
+ try { chmodSync(p, 0o755); } catch {}
40
+ }
41
+ const r = spawnSync(p, process.argv.slice(2), { stdio: "inherit", env: process.env });
42
+ process.exit(r.status ?? (r.error ? 1 : 0));
51
43
  }
52
44
  }
53
45
  }
54
46
 
55
- if (nativeBinaryPath) {
56
- if (platform !== "win32") {
57
- try { chmodSync(nativeBinaryPath, 0o755); } catch {}
58
- }
59
- const result = spawnSync(nativeBinaryPath, process.argv.slice(2), {
60
- stdio: "inherit",
61
- env: process.env,
62
- });
63
- process.exit(result.status ?? (result.error ? 1 : 0));
64
- }
65
-
66
- // --- 2. Fallback: run via Bun (dist/cli.js is a Bun bundle) ---
47
+ // --- 2. Fallback: run via Bun ---
67
48
  const jsEntry = join(rootDir, "dist", "cli.js");
68
-
69
- if (!existsSync(jsEntry)) {
70
- console.error("pikaa: dist/cli.js not found. Please reinstall the package.");
71
- process.exit(1);
72
- }
73
-
74
- // Find Bun executable
75
- const bunCandidates = platform === "win32"
76
- ? ["bun.exe"]
77
- : ["bun"];
78
-
79
- let bunBin = null;
80
- for (const candidate of bunCandidates) {
81
- const probe = spawnSync(candidate, ["--version"], { encoding: "utf8" });
49
+ if (existsSync(jsEntry)) {
50
+ const probe = spawnSync("bun", ["--version"], { encoding: "utf8" });
82
51
  if (!probe.error) {
83
- bunBin = candidate;
84
- break;
52
+ const r = spawnSync("bun", ["run", jsEntry, ...process.argv.slice(2)], {
53
+ stdio: "inherit",
54
+ env: process.env,
55
+ });
56
+ process.exit(r.status ?? (r.error ? 1 : 0));
85
57
  }
86
58
  }
87
59
 
88
- if (!bunBin) {
89
- console.error([
90
- "",
91
- " pikaa requires Bun to run.",
92
- " Install Bun with:",
93
- "",
94
- " curl -fsSL https://bun.sh/install | bash # macOS / Linux",
95
- " powershell -c \"irm bun.sh/install.ps1 | iex\" # Windows",
96
- "",
97
- " Then re-run: pikaa",
98
- "",
99
- ].join("\n"));
100
- process.exit(1);
101
- }
102
-
103
- const result = spawnSync(bunBin, ["run", jsEntry, ...process.argv.slice(2)], {
104
- stdio: "inherit",
105
- env: process.env,
106
- });
107
- process.exit(result.status ?? (result.error ? 1 : 0));
60
+ // --- 3. Nothing worked ---
61
+ console.error([
62
+ "",
63
+ " pikaa could not start.",
64
+ " The precompiled binary may have failed to download during install.",
65
+ "",
66
+ " Try reinstalling:",
67
+ " npm install -g @pikaa-ai/pikaa",
68
+ "",
69
+ " Or install Bun as a fallback runtime:",
70
+ " curl -fsSL https://bun.sh/install | bash",
71
+ "",
72
+ ].join("\n"));
73
+ process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikaa-ai/pikaa",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "PIKAA CLI - AI coding agent that runs locally in your terminal.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -13,6 +13,7 @@
13
13
  "files": [
14
14
  "dist",
15
15
  "bin",
16
+ "scripts/postinstall.js",
16
17
  "README.md",
17
18
  "LICENSE"
18
19
  ],
@@ -24,6 +25,7 @@
24
25
  "build:exe": "bun build ./src/cli/index.ts --compile --outfile pikaa.exe",
25
26
  "build:binaries": "bun run scripts/build-binaries.ts",
26
27
  "build": "bun run build:js && bun run build:exe",
28
+ "postinstall": "node scripts/postinstall.js",
27
29
  "prepublishOnly": "bun run build:js"
28
30
  },
29
31
  "keywords": [
@@ -0,0 +1,89 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall: downloads the correct precompiled pikaa binary from GitHub Releases.
5
+ * Runs automatically after `npm install -g @pikaa-ai/pikaa`.
6
+ * Uses only Node.js built-ins — no Bun required.
7
+ */
8
+
9
+ import { createWriteStream, chmodSync, existsSync, mkdirSync } from "node:fs";
10
+ import { fileURLToPath } from "node:url";
11
+ import { dirname, join } from "node:path";
12
+ import { pipeline } from "node:stream/promises";
13
+ import https from "node:https";
14
+
15
+ const __filename = fileURLToPath(import.meta.url);
16
+ const __dirname = dirname(__filename);
17
+ const rootDir = join(__dirname, "..");
18
+
19
+ const pkg = JSON.parse(
20
+ await import("node:fs").then((fs) =>
21
+ fs.readFileSync(join(rootDir, "package.json"), "utf8")
22
+ )
23
+ );
24
+ const version = pkg.version;
25
+ const REPO = "Neural-Forge-AMD/agent-cli";
26
+
27
+ function getBinaryName() {
28
+ const platform = process.platform;
29
+ const arch = process.arch;
30
+ if (platform === "win32") return arch === "arm64" ? "pikaa-windows-arm64.exe" : "pikaa-windows-x64.exe";
31
+ if (platform === "darwin") return arch === "arm64" ? "pikaa-darwin-arm64" : "pikaa-darwin-x64";
32
+ if (platform === "linux") return arch === "arm64" ? "pikaa-linux-arm64" : "pikaa-linux-x64";
33
+ return null;
34
+ }
35
+
36
+ const binaryName = getBinaryName();
37
+
38
+ if (!binaryName) {
39
+ console.warn(`[pikaa] Unsupported platform: ${process.platform}/${process.arch}. Fallback to bun required.`);
40
+ process.exit(0);
41
+ }
42
+
43
+ const binDir = join(rootDir, "bin");
44
+ const destPath = join(binDir, binaryName);
45
+
46
+ if (existsSync(destPath)) {
47
+ // Already downloaded (e.g. cached by npm)
48
+ process.exit(0);
49
+ }
50
+
51
+ mkdirSync(binDir, { recursive: true });
52
+
53
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${binaryName}`;
54
+
55
+ console.log(`[pikaa] Downloading binary for ${process.platform}/${process.arch}...`);
56
+ console.log(`[pikaa] ${url}`);
57
+
58
+ async function download(downloadUrl, dest, redirects = 0) {
59
+ if (redirects > 5) throw new Error("Too many redirects");
60
+
61
+ await new Promise((resolve, reject) => {
62
+ const file = createWriteStream(dest);
63
+ https.get(downloadUrl, { headers: { "User-Agent": "pikaa-postinstall" } }, (res) => {
64
+ if (res.statusCode === 301 || res.statusCode === 302) {
65
+ file.close();
66
+ resolve(download(res.headers.location, dest, redirects + 1));
67
+ return;
68
+ }
69
+ if (res.statusCode !== 200) {
70
+ file.close();
71
+ reject(new Error(`HTTP ${res.statusCode} from ${downloadUrl}`));
72
+ return;
73
+ }
74
+ pipeline(res, file).then(resolve).catch(reject);
75
+ }).on("error", reject);
76
+ });
77
+ }
78
+
79
+ try {
80
+ await download(url, destPath);
81
+ if (process.platform !== "win32") {
82
+ chmodSync(destPath, 0o755);
83
+ }
84
+ console.log(`[pikaa] ✓ Binary installed: ${destPath}`);
85
+ } catch (err) {
86
+ // Non-fatal: user can still run via bun if installed
87
+ console.warn(`[pikaa] Warning: could not download binary (${err.message})`);
88
+ console.warn(`[pikaa] You can install Bun as a fallback: https://bun.sh/install`);
89
+ }