@pikaa-ai/pikaa 0.1.9 → 0.2.1

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/bin/pikaa.js CHANGED
@@ -1,17 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  /**
4
- * Universal Cross-Platform Dispatcher for Pikaa / Groupy Agent.
4
+ * Universal Native Launcher for Pikaa Agent CLI.
5
5
  *
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
6
+ * Automatically detects platform (macOS, Linux, Windows) and architecture (arm64, x64).
7
+ * If the native binary is already present, runs it with 0ms startup time.
8
+ * If not present (e.g. postinstall script skipped by npm allow-scripts), automatically
9
+ * downloads the native binary from GitHub Releases to ~/.pikaa/bin/ and executes it.
10
+ *
11
+ * Zero external dependencies required. Does NOT require Bun or compilation tools.
9
12
  */
10
13
 
11
14
  import { spawnSync } from "node:child_process";
12
- import { existsSync, chmodSync } from "node:fs";
15
+ import { existsSync, chmodSync, mkdirSync, createWriteStream, readFileSync } from "node:fs";
13
16
  import { fileURLToPath } from "node:url";
14
17
  import { dirname, join } from "node:path";
18
+ import { homedir } from "node:os";
19
+ import { pipeline } from "node:stream/promises";
20
+ import https from "node:https";
15
21
 
16
22
  const __filename = fileURLToPath(import.meta.url);
17
23
  const __dirname = dirname(__filename);
@@ -27,47 +33,105 @@ function getBinaryName() {
27
33
  return null;
28
34
  }
29
35
 
30
- // --- 1. Native binary (postinstall should have placed it here) ---
31
36
  const binaryName = getBinaryName();
32
- if (binaryName) {
33
- for (const p of [
37
+ const userBinDir = join(homedir(), ".pikaa", "bin");
38
+ const userBinaryPath = binaryName ? join(userBinDir, binaryName) : null;
39
+
40
+ // Look in package directory or user cache directory
41
+ function findExistingBinary() {
42
+ if (!binaryName) return null;
43
+ const candidates = [
34
44
  join(rootDir, "bin", binaryName),
35
45
  join(rootDir, "dist", "bin", binaryName),
36
- ]) {
37
- if (existsSync(p)) {
38
- if (platform !== "win32") {
39
- try { chmodSync(p, 0o755); } catch {}
46
+ userBinaryPath,
47
+ ];
48
+ for (const c of candidates) {
49
+ if (c && existsSync(c)) return c;
50
+ }
51
+ return null;
52
+ }
53
+
54
+ async function downloadBinary(url, dest, redirects = 0) {
55
+ if (redirects > 5) throw new Error("Too many redirects");
56
+
57
+ await new Promise((resolve, reject) => {
58
+ const file = createWriteStream(dest);
59
+ https.get(url, { headers: { "User-Agent": "pikaa-cli-launcher" } }, (res) => {
60
+ if (res.statusCode === 301 || res.statusCode === 302) {
61
+ file.close();
62
+ resolve(downloadBinary(res.headers.location, dest, redirects + 1));
63
+ return;
40
64
  }
41
- const r = spawnSync(p, process.argv.slice(2), { stdio: "inherit", env: process.env });
42
- process.exit(r.status ?? (r.error ? 1 : 0));
43
- }
65
+ if (res.statusCode !== 200) {
66
+ file.close();
67
+ reject(new Error(`HTTP ${res.statusCode} from ${url}`));
68
+ return;
69
+ }
70
+ pipeline(res, file).then(resolve).catch(reject);
71
+ }).on("error", reject);
72
+ });
73
+ }
74
+
75
+ function launchBinary(binPath) {
76
+ if (platform !== "win32") {
77
+ try { chmodSync(binPath, 0o755); } catch {}
44
78
  }
79
+ const r = spawnSync(binPath, process.argv.slice(2), {
80
+ stdio: "inherit",
81
+ env: process.env,
82
+ });
83
+ process.exit(r.status ?? (r.error ? 1 : 0));
45
84
  }
46
85
 
47
- // --- 2. Fallback: run via Bun ---
48
- const jsEntry = join(rootDir, "dist", "cli.js");
49
- if (existsSync(jsEntry)) {
50
- const probe = spawnSync("bun", ["--version"], { encoding: "utf8" });
51
- if (!probe.error) {
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));
86
+ async function main() {
87
+ const existing = findExistingBinary();
88
+ if (existing) {
89
+ launchBinary(existing);
90
+ return;
91
+ }
92
+
93
+ if (!binaryName || !userBinaryPath) {
94
+ console.error(`[pikaa] Platform not supported: ${platform}/${arch}`);
95
+ process.exit(1);
96
+ }
97
+
98
+ // Auto-download binary on first run
99
+ let version = "0.2.0";
100
+ try {
101
+ const pkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8"));
102
+ version = pkg.version;
103
+ } catch {}
104
+
105
+ const downloadUrl = `https://github.com/Neural-Forge-AMD/agent-cli/releases/download/v${version}/${binaryName}`;
106
+
107
+ try {
108
+ mkdirSync(userBinDir, { recursive: true });
109
+ process.stderr.write(`\x1b[36m⚡ [pikaa] First-time setup: Downloading native binary for ${platform}/${arch}...\x1b[0m\n`);
110
+ await downloadBinary(downloadUrl, userBinaryPath);
111
+ if (platform !== "win32") {
112
+ chmodSync(userBinaryPath, 0o755);
113
+ }
114
+ process.stderr.write(`\x1b[32m✓ Setup complete!\x1b[0m\n\n`);
115
+ launchBinary(userBinaryPath);
116
+ } catch (err) {
117
+ process.stderr.write(`\x1b[33mWarning: Failed to download native binary: ${err.message}\x1b[0m\n`);
118
+
119
+ // Try bun fallback if available
120
+ const jsEntry = join(rootDir, "dist", "cli.js");
121
+ if (existsSync(jsEntry)) {
122
+ const probe = spawnSync("bun", ["--version"], { encoding: "utf8" });
123
+ if (!probe.error) {
124
+ const r = spawnSync("bun", ["run", jsEntry, ...process.argv.slice(2)], {
125
+ stdio: "inherit",
126
+ env: process.env,
127
+ });
128
+ process.exit(r.status ?? (r.error ? 1 : 0));
129
+ }
130
+ }
131
+
132
+ console.error(`\nPlease check your internet connection or install Bun (https://bun.sh) and retry.`);
133
+ process.exit(1);
57
134
  }
58
135
  }
59
136
 
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);
137
+ main();
package/dist/cli.js CHANGED
@@ -4098,12 +4098,12 @@ class CliFormatter {
4098
4098
  console.log();
4099
4099
  console.log(` ${b} \u2584\u2584\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584\u2584${r}`);
4100
4100
  console.log(` ${b} \u2584\u2588\u2588\u2588\u2580\u2580 \u2580\u2580\u2588\u2588\u2588\u2584${r}`);
4101
- console.log(` ${b} \u2584\u2588\u2588\u2580 \u2580\u2588\u2588\u2584${r} ${t}GROUPY AGENT${r} ${g}(v0.1.0)${r}`);
4101
+ console.log(` ${b} \u2584\u2588\u2588\u2580 \u2580\u2588\u2588\u2584${r} ${t}PIKAA AGENT${r}`);
4102
4102
  console.log(` ${b} \u2588\u2588\u2588 \u2584\u2584\u2588\u2588\u2588\u2588\u2584\u2584 \u2588\u2588\u2588${r} ${g}Autonomous Coding Engine${r}`);
4103
- console.log(` ${b}\u2588\u2588\u2588 \u2584\u2588\u2588\u2580 \u2580\u2588\u2588\u2584 \u2580\u2580${r} ${g}Codex Core Architecture in TypeScript & Bun${r}`);
4104
- console.log(` ${b}\u2588\u2588\u2588 \u2588\u2588\u258C \u2588\u2588 \u2590\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584${r} ${style.dim("Model:")} ${style.brand(info.model)}`);
4105
- console.log(` ${b}\u2588\u2588\u2588 \u2588\u2588\u258C \u2588\u2588 \u2590\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2580${r} ${style.dim("Role:")} ${style.yellow(info.role)}`);
4106
- console.log(` ${b}\u2588\u2588\u2588 \u2580\u2588\u2588\u2584 \u2584\u2588\u2588\u2580 \u2584\u2584${r} ${style.dim("Dir:")} ${style.dim(info.cwd)}`);
4103
+ console.log(` ${b}\u2588\u2588\u2588 \u2584\u2588\u2588\u2580 \u2580\u2588\u2588\u2584 \u2580\u2580${r} ${style.dim("Model:")} ${style.brand(info.model)}`);
4104
+ console.log(` ${b}\u2588\u2588\u2588 \u2588\u2588\u258C \u2588\u2588 \u2590\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2584${r} ${style.dim("Role:")} ${style.yellow(info.role)}`);
4105
+ console.log(` ${b}\u2588\u2588\u2588 \u2588\u2588\u258C \u2588\u2588 \u2590\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2580${r} ${style.dim("Dir:")} ${style.dim(info.cwd)}`);
4106
+ console.log(` ${b}\u2588\u2588\u2588 \u2580\u2588\u2588\u2584 \u2584\u2588\u2588\u2580 \u2584\u2584${r}`);
4107
4107
  console.log(` ${b} \u2588\u2588\u2588 \u2580\u2580\u2588\u2588\u2588\u2588\u2580\u2580 \u2588\u2588\u2588${r}`);
4108
4108
  console.log(` ${b} \u2580\u2588\u2588\u2584 \u2584\u2588\u2588\u2580${r}`);
4109
4109
  console.log(` ${b} \u2580\u2588\u2588\u2588\u2584\u2584 \u2584\u2584\u2588\u2588\u2588\u2580${r}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikaa-ai/pikaa",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
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,7 +13,6 @@
13
13
  "files": [
14
14
  "dist",
15
15
  "bin",
16
- "scripts/postinstall.js",
17
16
  "README.md",
18
17
  "LICENSE"
19
18
  ],
@@ -25,7 +24,6 @@
25
24
  "build:exe": "bun build ./src/cli/index.ts --compile --outfile pikaa.exe",
26
25
  "build:binaries": "bun run scripts/build-binaries.ts",
27
26
  "build": "bun run build:js && bun run build:exe",
28
- "postinstall": "node scripts/postinstall.js",
29
27
  "prepublishOnly": "bun run build:js"
30
28
  },
31
29
  "keywords": [
File without changes
@@ -1,89 +0,0 @@
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
- }