@jacobmolz/pice 0.3.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.
Files changed (3) hide show
  1. package/bin/pice +18 -0
  2. package/index.js +135 -0
  3. package/package.json +19 -0
package/bin/pice ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execFileSync } = require("child_process");
4
+
5
+ let binaryPath;
6
+ try {
7
+ const { getBinaryPath } = require("../index.js");
8
+ binaryPath = getBinaryPath();
9
+ } catch (e) {
10
+ console.error(`pice: ${e.message}`);
11
+ process.exit(1);
12
+ }
13
+
14
+ try {
15
+ execFileSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
16
+ } catch (e) {
17
+ process.exit(e.status || 1);
18
+ }
package/index.js ADDED
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+
3
+ const path = require("path");
4
+ const { execFileSync } = require("child_process");
5
+ const fs = require("fs");
6
+
7
+ /**
8
+ * Platform/arch to npm package name mapping.
9
+ * Linux packages contain glibc-linked binaries. musl-based distros
10
+ * (Alpine, Void, etc.) are detected and rejected with a clear message.
11
+ */
12
+ const PLATFORM_MAP = {
13
+ "darwin-arm64": { pkg: "@pice/pice-darwin-arm64", bin: "pice", daemonBin: "pice-daemon" },
14
+ "darwin-x64": { pkg: "@pice/pice-darwin-x64", bin: "pice", daemonBin: "pice-daemon" },
15
+ "linux-arm64": { pkg: "@pice/pice-linux-arm64", bin: "pice", daemonBin: "pice-daemon" },
16
+ "linux-x64": { pkg: "@pice/pice-linux-x64", bin: "pice", daemonBin: "pice-daemon" },
17
+ "win32-x64": { pkg: "@pice/pice-win32-x64", bin: "pice.exe", daemonBin: "pice-daemon.exe" },
18
+ };
19
+
20
+ /**
21
+ * Detect whether the current Linux system uses musl libc.
22
+ * Uses execFileSync (no shell) with a hardcoded binary path for safety.
23
+ */
24
+ function isMusl() {
25
+ if (process.platform !== "linux") return false;
26
+ try {
27
+ // execFileSync avoids shell injection — hardcoded binary, no user input
28
+ const output = execFileSync("ldd", ["--version"], {
29
+ encoding: "utf8",
30
+ stdio: ["pipe", "pipe", "pipe"],
31
+ });
32
+ return output.toLowerCase().includes("musl");
33
+ } catch (e) {
34
+ // ldd writes to stderr on some systems; check combined output
35
+ if (e.stderr && e.stderr.toLowerCase().includes("musl")) return true;
36
+ // Fallback: check for Alpine marker file
37
+ try {
38
+ const release = fs.readFileSync("/etc/os-release", "utf8");
39
+ return release.toLowerCase().includes("alpine");
40
+ } catch {
41
+ return false;
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Returns the absolute path to the PICE binary for the current platform.
48
+ *
49
+ * @returns {string} Absolute path to the pice binary
50
+ * @throws {Error} If the current platform/arch combination is unsupported
51
+ * or if the platform-specific package is not installed
52
+ */
53
+ function getBinaryPath() {
54
+ if (isMusl()) {
55
+ throw new Error(
56
+ `PICE CLI does not currently provide musl/Alpine Linux binaries. ` +
57
+ `The npm packages contain glibc-linked binaries that will not work ` +
58
+ `on musl-based systems. Install from source instead: ` +
59
+ `cargo install pice-cli`
60
+ );
61
+ }
62
+
63
+ const key = `${process.platform}-${process.arch}`;
64
+ const entry = PLATFORM_MAP[key];
65
+
66
+ if (!entry) {
67
+ const supported = Object.keys(PLATFORM_MAP)
68
+ .map((k) => k.replace("-", "/"))
69
+ .join(", ");
70
+ throw new Error(
71
+ `Unsupported platform: ${process.platform}/${process.arch}. ` +
72
+ `PICE CLI supports: ${supported}. ` +
73
+ `If you believe this is a bug, please open an issue at ` +
74
+ `https://github.com/jacobmolz/pice/issues`
75
+ );
76
+ }
77
+
78
+ let pkgDir;
79
+ try {
80
+ const pkgJsonPath = require.resolve(`${entry.pkg}/package.json`);
81
+ pkgDir = path.dirname(pkgJsonPath);
82
+ } catch {
83
+ throw new Error(
84
+ `The platform-specific package ${entry.pkg} is not installed. ` +
85
+ `This usually means your package manager did not install the ` +
86
+ `optional dependency for your platform. ` +
87
+ `Try reinstalling with: npm install pice`
88
+ );
89
+ }
90
+
91
+ return path.join(pkgDir, entry.bin);
92
+ }
93
+
94
+ /**
95
+ * Returns the absolute path to the pice-daemon binary for the current platform.
96
+ *
97
+ * The daemon binary ships alongside the CLI in the same platform package.
98
+ * The CLI's auto-start logic uses this to locate `pice-daemon` without
99
+ * requiring it to be on the user's `$PATH`.
100
+ *
101
+ * @returns {string} Absolute path to the pice-daemon binary
102
+ * @throws {Error} If the current platform/arch combination is unsupported
103
+ * or if the platform-specific package is not installed
104
+ */
105
+ function getDaemonBinaryPath() {
106
+ if (isMusl()) {
107
+ throw new Error(
108
+ `PICE daemon does not currently provide musl/Alpine Linux binaries. ` +
109
+ `Install from source instead: cargo install pice-daemon`
110
+ );
111
+ }
112
+
113
+ const key = `${process.platform}-${process.arch}`;
114
+ const entry = PLATFORM_MAP[key];
115
+
116
+ if (!entry) {
117
+ throw new Error(
118
+ `Unsupported platform: ${process.platform}/${process.arch}.`
119
+ );
120
+ }
121
+
122
+ let pkgDir;
123
+ try {
124
+ const pkgJsonPath = require.resolve(`${entry.pkg}/package.json`);
125
+ pkgDir = path.dirname(pkgJsonPath);
126
+ } catch {
127
+ throw new Error(
128
+ `The platform-specific package ${entry.pkg} is not installed.`
129
+ );
130
+ }
131
+
132
+ return path.join(pkgDir, entry.daemonBin);
133
+ }
134
+
135
+ module.exports = { getBinaryPath, getDaemonBinaryPath };
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@jacobmolz/pice",
3
+ "version": "0.3.0",
4
+ "description": "PICE CLI — structured AI coding workflow orchestrator",
5
+ "bin": { "pice": "bin/pice" },
6
+ "main": "index.js",
7
+ "files": ["bin", "index.js"],
8
+ "optionalDependencies": {
9
+ "@pice/pice-darwin-arm64": "0.3.0",
10
+ "@pice/pice-darwin-x64": "0.3.0",
11
+ "@pice/pice-linux-arm64": "0.3.0",
12
+ "@pice/pice-linux-x64": "0.3.0",
13
+ "@pice/pice-win32-x64": "0.3.0"
14
+ },
15
+ "license": "MIT",
16
+ "repository": { "type": "git", "url": "https://github.com/jacobmolz/pice" },
17
+ "keywords": ["ai", "cli", "workflow", "coding", "evaluation"],
18
+ "engines": { "node": ">=18" }
19
+ }