@nerslm/prisel 0.0.0-stage → 0.10.4

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/prisel.exe ADDED
@@ -0,0 +1,13 @@
1
+ printf '%s\n' \
2
+ 'prisel: the native binary for this platform is not installed.' \
3
+ '' \
4
+ 'Either the postinstall step did not run (--ignore-scripts, or some pnpm' \
5
+ 'configurations), or the platform-specific optional dependency was not' \
6
+ 'downloaded (--omit=optional, or a failed download).' \
7
+ '' \
8
+ 'Run the postinstall manually — adjust the path for a local install:' \
9
+ ' node "$(npm root -g)/@nerslm/prisel/install.cjs"' \
10
+ '' \
11
+ 'Or reinstall without --ignore-scripts / --omit=optional:' \
12
+ ' npm install -g @nerslm/prisel' >&2
13
+ exit 1
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ // Fallback launcher for when postinstall could not place the native binary.
3
+ //
4
+ // Resolves the platform package at run time and spawns it. Slower than the
5
+ // direct exec bin/prisel.exe normally provides, because a Node process stays
6
+ // resident, but it works wherever the optional dependency did get installed.
7
+
8
+ const { spawnSync } = require("child_process");
9
+ const path = require("path");
10
+ const { PLATFORMS, PLATFORM_KEY, isMusl } = require("./platforms.cjs");
11
+
12
+ const platformKey = PLATFORM_KEY();
13
+ const info = PLATFORMS[platformKey];
14
+
15
+ if (!info) {
16
+ console.error(`prisel: unsupported platform ${process.platform} ${process.arch}`);
17
+ console.error(` Supported: ${Object.keys(PLATFORMS).join(", ")}`);
18
+ process.exit(1);
19
+ }
20
+
21
+ if (isMusl()) {
22
+ console.error("prisel: the linux binaries require glibc and will not run on musl (Alpine).");
23
+ process.exit(1);
24
+ }
25
+
26
+ let binaryPath;
27
+ try {
28
+ binaryPath = path.join(path.dirname(require.resolve(`${info.pkg}/package.json`)), info.bin);
29
+ } catch {
30
+ console.error(`prisel: native package "${info.pkg}" is not installed.`);
31
+ console.error(" Reinstall without --omit=optional: npm install -g @nerslm/prisel");
32
+ process.exit(1);
33
+ }
34
+
35
+ const result = spawnSync(binaryPath, process.argv.slice(2), { stdio: "inherit" });
36
+
37
+ if (result.error) {
38
+ console.error(`prisel: could not run ${binaryPath}: ${result.error.message}`);
39
+ process.exit(1);
40
+ }
41
+ if (result.signal) {
42
+ // Report the signal the way a shell would, so callers see the real cause.
43
+ process.exit(128 + (require("os").constants.signals[result.signal] ?? 0));
44
+ }
45
+ process.exit(result.status ?? 1);
package/install.cjs ADDED
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env node
2
+ // Postinstall for the prisel wrapper package.
3
+ //
4
+ // Detects the platform, finds the matching native binary among the optional
5
+ // dependencies, and places it over the bin/prisel.exe stub. After this runs,
6
+ // `prisel` execs the native binary directly with no Node process in between.
7
+ //
8
+ // Failure is never fatal: the stub stays and explains what to do, and
9
+ // cli-wrapper.cjs still works via require.resolve + spawn.
10
+
11
+ const { copyFileSync, linkSync, unlinkSync, chmodSync, readFileSync, writeFileSync, statSync } = require("fs");
12
+ const path = require("path");
13
+ const { PACKAGE_PREFIX, PLATFORMS, PLATFORM_KEY, isMusl } = require("./platforms.cjs");
14
+
15
+ const WRAPPER_NAME = require("./package.json").name;
16
+ const log = (message) => console.error(`[${WRAPPER_NAME} postinstall] ${message}`);
17
+
18
+ function placeBinary(src, dest) {
19
+ // Hardlink first: instant, and costs no extra disk for a ~100 MB binary.
20
+ // Attempted before touching dest, so a missing src leaves the stub intact.
21
+ try {
22
+ linkSync(src, dest);
23
+ } catch (err) {
24
+ if (err.code === "EEXIST") {
25
+ // Keep the stub in memory so a failed replace can restore it. Only when
26
+ // dest is still stub-sized — on reinstall dest is the real binary.
27
+ const stub = statSync(dest).size < 4096 ? readFileSync(dest) : null;
28
+ unlinkSync(dest);
29
+ try {
30
+ linkSync(src, dest);
31
+ } catch {
32
+ try {
33
+ copyFileSync(src, dest);
34
+ } catch (copyErr) {
35
+ if (stub) {
36
+ try {
37
+ writeFileSync(dest, stub, { mode: 0o755 });
38
+ } catch {
39
+ // Restoring the stub is best effort; report the original failure.
40
+ }
41
+ }
42
+ throw copyErr;
43
+ }
44
+ }
45
+ } else if (err.code === "EXDEV" || err.code === "EPERM") {
46
+ // Different filesystem, or no permission to link.
47
+ copyFileSync(src, dest);
48
+ } else {
49
+ throw err;
50
+ }
51
+ }
52
+ if (process.platform !== "win32") {
53
+ chmodSync(dest, 0o755);
54
+ }
55
+ }
56
+
57
+ function main() {
58
+ const platformKey = PLATFORM_KEY();
59
+ const info = PLATFORMS[platformKey];
60
+
61
+ if (!info) {
62
+ log(`Unsupported platform: ${process.platform} ${process.arch}`);
63
+ log(` Supported: ${Object.keys(PLATFORMS).join(", ")}`);
64
+ return;
65
+ }
66
+
67
+ if (isMusl()) {
68
+ log("The linux binaries are built against glibc and will not run on musl (Alpine).");
69
+ log(" Run Prisel on a glibc distribution, or build it from source:");
70
+ log(" https://github.com/nerslm/prisel");
71
+ return;
72
+ }
73
+
74
+ const optionalDeps = require("./package.json").optionalDependencies || {};
75
+ if (!optionalDeps[info.pkg]) {
76
+ log(`No native binary is published for ${platformKey} in this release.`);
77
+ log(` Available: ${Object.keys(optionalDeps).map((name) => name.replace(`${PACKAGE_PREFIX}-`, "")).join(", ")}`);
78
+ return;
79
+ }
80
+
81
+ let src;
82
+ try {
83
+ src = path.join(path.dirname(require.resolve(`${info.pkg}/package.json`)), info.bin);
84
+ } catch {
85
+ log(`Native package "${info.pkg}" not found.`);
86
+ if (platformKey === "darwin-arm64" && process.arch === "x64") {
87
+ log(" You are running x64 Node under Rosetta 2. Install an arm64 Node and reinstall.");
88
+ return;
89
+ }
90
+ log(" This happens with --omit=optional, or when the download failed.");
91
+ log(` Fallback: node ${path.join(__dirname, "cli-wrapper.cjs")}`);
92
+ return;
93
+ }
94
+
95
+ // bin points here unconditionally. The .exe suffix on a stub with no shebang
96
+ // makes npm's cmd-shim — generated before postinstall — emit a direct exec on
97
+ // Windows; Unix ignores the extension.
98
+ const dest = path.join(__dirname, "bin", "prisel.exe");
99
+ try {
100
+ placeBinary(src, dest);
101
+ } catch (err) {
102
+ log(`Could not install the native binary: ${err.message}`);
103
+ log(` Fallback: node ${path.join(__dirname, "cli-wrapper.cjs")}`);
104
+ }
105
+
106
+ // ripgrep sits beside the binary because that is where prisel looks for it.
107
+ // Its absence costs file completion and `rg` in shell commands, not startup.
108
+ try {
109
+ placeBinary(path.join(path.dirname(src), info.rg), path.join(__dirname, "bin", info.rg));
110
+ } catch (err) {
111
+ log(`Could not install the bundled ripgrep: ${err.message}`);
112
+ log(" File completion and `rg` fall back to a system ripgrep if one is installed.");
113
+ }
114
+ }
115
+
116
+ main();
package/package.json CHANGED
@@ -1,6 +1,111 @@
1
1
  {
2
- "name": "@nerslm/prisel",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@nerslm/prisel",
3
+ "version": "0.10.4",
4
+ "description": "Prisel, an agent on your own computer: terminal, browser and phone attach to the same session",
5
+ "type": "module",
6
+ "priselConfig": {
7
+ "name": "prisel",
8
+ "configDir": ".prisel",
9
+ "userConfigDir": ".prisel"
10
+ },
11
+ "bin": {
12
+ "prisel": "bin/prisel.exe"
13
+ },
14
+ "files": [
15
+ "bin/prisel.exe",
16
+ "install.cjs",
17
+ "cli-wrapper.cjs",
18
+ "platforms.cjs",
19
+ "LICENSE",
20
+ "THIRD_PARTY_NOTICES.txt"
21
+ ],
22
+ "scripts": {
23
+ "clean": "node ../../scripts/build-files.mjs clean coding-agent",
24
+ "build": "node ../../scripts/generate-embedded-docs.mjs && node ../../scripts/generate-embedded-assets.mjs && tsgo -p tsconfig.build.json && node ../../scripts/build-files.mjs chmod-cli",
25
+ "build:binary": "node ../../scripts/build-binaries.mjs --platform=linux-x64",
26
+ "test": "node ../../scripts/test.mjs coding-agent",
27
+ "prepublishOnly": "node -e \"if (!process.env.PRISEL_PUBLISH) { console.error(\\\"Publish through: npm run publish (from the repo root)\\\"); process.exit(1) }\"",
28
+ "pretest": "node ../../scripts/generate-embedded-docs.mjs && node ../../scripts/generate-embedded-assets.mjs",
29
+ "build:binaries": "node ../../scripts/build-binaries.mjs",
30
+ "postinstall": "node install.cjs"
31
+ },
32
+ "overrides": {
33
+ "rimraf": "6.1.2",
34
+ "gaxios": {
35
+ "rimraf": "6.1.2"
36
+ }
37
+ },
38
+ "optionalDependencies": {
39
+ "prisel-darwin-arm64": "0.10.4",
40
+ "prisel-darwin-x64": "0.10.4",
41
+ "prisel-linux-arm64": "0.10.4",
42
+ "prisel-linux-x64": "0.10.4",
43
+ "prisel-windows-x64": "0.10.4"
44
+ },
45
+ "devDependencies": {
46
+ "@libp2p/crypto": "5.1.23",
47
+ "@libp2p/interface": "3.3.0",
48
+ "@libp2p/noise": "17.0.3",
49
+ "@libp2p/peer-id": "6.0.15",
50
+ "@libp2p/utils": "7.4.1",
51
+ "uint8arraylist": "3.0.2",
52
+ "@silvia-odwyer/photon-node": "0.3.4",
53
+ "@types/cross-spawn": "6.0.6",
54
+ "@types/diff": "7.0.2",
55
+ "@types/hosted-git-info": "3.0.5",
56
+ "@types/ms": "2.1.0",
57
+ "@types/node": "24.12.4",
58
+ "@types/proper-lockfile": "4.1.4",
59
+ "@types/semver": "7.7.1",
60
+ "@types/turndown": "5.0.6",
61
+ "@types/ws": "8.18.2",
62
+ "@vscode/ripgrep": "1.18.0",
63
+ "chalk": "5.6.2",
64
+ "cross-spawn": "7.0.6",
65
+ "diff": "8.0.4",
66
+ "glob": "13.0.6",
67
+ "highlight.js": "10.7.3",
68
+ "hosted-git-info": "9.0.3",
69
+ "ignore": "7.0.5",
70
+ "jiti": "2.7.0",
71
+ "jose": "6.2.12",
72
+ "minimatch": "10.2.6",
73
+ "prisel-agent": "^0.10.4",
74
+ "prisel-ai": "^0.10.4",
75
+ "prisel-tui": "^0.10.4",
76
+ "proper-lockfile": "4.1.2",
77
+ "semver": "7.8.0",
78
+ "turndown": "7.2.4",
79
+ "typebox": "1.1.38",
80
+ "typescript": "5.9.3",
81
+ "undici": "8.11.2",
82
+ "uqr": "0.1.3",
83
+ "vitest": "4.1.11",
84
+ "ws": "8.22.0",
85
+ "yaml": "2.9.0"
86
+ },
87
+ "keywords": [
88
+ "coding-agent",
89
+ "ai",
90
+ "llm",
91
+ "cli",
92
+ "tui",
93
+ "agent"
94
+ ],
95
+ "author": "nerslm",
96
+ "license": "SEE LICENSE IN LICENSE",
97
+ "engines": {
98
+ "node": ">=22.19.0"
99
+ },
100
+ "contributors": [
101
+ "Mario Zechner (original author of pi, which Prisel is forked from)"
102
+ ],
103
+ "repository": {
104
+ "type": "git",
105
+ "url": "git+https://github.com/nerslm/prisel-release.git"
106
+ },
107
+ "homepage": "https://prisel.app",
108
+ "bugs": {
109
+ "url": "https://github.com/nerslm/prisel-release/issues"
110
+ }
111
+ }
package/platforms.cjs ADDED
@@ -0,0 +1,52 @@
1
+ // Platform detection shared by install.cjs and cli-wrapper.cjs.
2
+
3
+ const { arch } = require("os");
4
+
5
+ const PACKAGE_PREFIX = "prisel";
6
+ const BINARY_NAME = "prisel";
7
+
8
+ // `rg` ships inside each platform package and is placed next to the binary, so
9
+ // the file completer and shell commands find ripgrep with nothing to download.
10
+ const PLATFORMS = {
11
+ "darwin-arm64": { pkg: `${PACKAGE_PREFIX}-darwin-arm64`, bin: BINARY_NAME, rg: "rg" },
12
+ "darwin-x64": { pkg: `${PACKAGE_PREFIX}-darwin-x64`, bin: BINARY_NAME, rg: "rg" },
13
+ "linux-x64": { pkg: `${PACKAGE_PREFIX}-linux-x64`, bin: BINARY_NAME, rg: "rg" },
14
+ "linux-arm64": { pkg: `${PACKAGE_PREFIX}-linux-arm64`, bin: BINARY_NAME, rg: "rg" },
15
+ // Named "windows" rather than "win32": npm rejects unscoped *-win32-x64 names.
16
+ "win32-x64": { pkg: `${PACKAGE_PREFIX}-windows-x64`, bin: `${BINARY_NAME}.exe`, rg: "rg.exe" },
17
+ };
18
+
19
+ /**
20
+ * The linux binaries link against glibc, so musl systems (Alpine) must be told
21
+ * rather than handed a binary that dies with a confusing loader error.
22
+ * process.report is available on Node >= 12; glibcVersionRuntime is absent on musl.
23
+ */
24
+ function isMusl() {
25
+ if (process.platform !== "linux") return false;
26
+ try {
27
+ return !process.report?.getReport()?.header?.glibcVersionRuntime;
28
+ } catch {
29
+ return false;
30
+ }
31
+ }
32
+
33
+ function getPlatformKey() {
34
+ let cpu = arch();
35
+ // Rosetta 2: an x64 Node on Apple Silicon reports arch() === "x64".
36
+ if (process.platform === "darwin" && cpu === "x64" && isRosetta()) {
37
+ cpu = "arm64";
38
+ }
39
+ return `${process.platform}-${cpu}`;
40
+ }
41
+
42
+ function isRosetta() {
43
+ try {
44
+ const { spawnSync } = require("child_process");
45
+ const result = spawnSync("sysctl", ["-n", "sysctl.proc_translated"], { encoding: "utf8" });
46
+ return result.stdout?.trim() === "1";
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+
52
+ module.exports = { PACKAGE_PREFIX, BINARY_NAME, PLATFORMS, PLATFORM_KEY: getPlatformKey, isMusl };