@linxiraos/main 1.1.26 → 1.1.27
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/zeta.js +101 -12
- package/package.json +3 -3
package/bin/zeta.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// zeta launcher —
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// zeta launcher — unified binary discovery, npm-form face:
|
|
3
|
+
// ① explicit env — ZETA_BIN_DIR (delimiter-separated dirs, probed first)
|
|
4
|
+
// ② PATH — a *native* zetawork/zeta binary (distro pacman install
|
|
5
|
+
// or a real .exe); PATH hits are used as-is, with no
|
|
6
|
+
// cross-component version validation
|
|
7
|
+
// ③ npm vendored — the platform-leaf binary shipped as
|
|
8
|
+
// @linxiraos/main-<platform>-<arch> (same pattern as the
|
|
9
|
+
// zeta-ide / zeta-editor launchers), then the repo
|
|
10
|
+
// target/release location for source checkouts
|
|
11
|
+
// Node-only, no Bun needed.
|
|
5
12
|
|
|
6
13
|
const fs = require("node:fs");
|
|
7
14
|
const path = require("node:path");
|
|
@@ -11,25 +18,107 @@ const { spawn } = require("node:child_process");
|
|
|
11
18
|
const PKG_PLATFORM = process.platform === "win32" ? "windows" : process.platform;
|
|
12
19
|
const PKG_PREFIX = "@linxiraos/main-";
|
|
13
20
|
const EXE = process.platform === "win32" ? "zeta.exe" : "zeta-linux-x64";
|
|
21
|
+
const NATIVE_BINS = ["zetawork", "zeta", "zeta-work"];
|
|
14
22
|
|
|
15
23
|
function die(msg) {
|
|
16
24
|
process.stderr.write(`zeta: ${msg}\n`);
|
|
17
25
|
process.exit(1);
|
|
18
26
|
}
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
/** Native-executable test so PATH probes never pick up another JS shim
|
|
29
|
+
* (npm's .cmd/.ps1/sh launchers for this very package live on PATH —
|
|
30
|
+
* re-executing them would recurse into this script). POSIX also demands
|
|
31
|
+
* the exec bit: a non-executable ELF (broken extract, cache artifact)
|
|
32
|
+
* would only die later with a raw spawn EACCES. */
|
|
33
|
+
function isNativeBinary(candidate) {
|
|
34
|
+
let stat;
|
|
35
|
+
try {
|
|
36
|
+
stat = fs.statSync(candidate);
|
|
37
|
+
} catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (!stat.isFile()) return false;
|
|
41
|
+
if (process.platform === "win32") {
|
|
42
|
+
return candidate.toLowerCase().endsWith(".exe");
|
|
43
|
+
}
|
|
44
|
+
if (!isExecutable(candidate)) return false;
|
|
45
|
+
let head;
|
|
46
|
+
try {
|
|
47
|
+
const fd = fs.openSync(candidate, "r");
|
|
48
|
+
const buf = Buffer.alloc(4);
|
|
49
|
+
const read = fs.readSync(fd, buf, 0, 4, 0);
|
|
50
|
+
fs.closeSync(fd);
|
|
51
|
+
head = read === 4 ? buf : null;
|
|
52
|
+
} catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
return head !== null && head.equals(Buffer.from([0x7f, 0x45, 0x4c, 0x46])); // \x7fELF
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** POSIX exec-bit probe; Windows access(X_OK) always succeeds, which is
|
|
59
|
+
* fine there — a named .exe is the platform's native form. */
|
|
60
|
+
function isExecutable(candidate) {
|
|
61
|
+
try {
|
|
62
|
+
fs.accessSync(candidate, fs.constants.X_OK);
|
|
63
|
+
return true;
|
|
64
|
+
} catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Native executable candidates for one bin name per directory entry:
|
|
70
|
+
* `name.exe` on Windows, the bare ELF name elsewhere. */
|
|
71
|
+
function nativeCandidates(dir, name) {
|
|
72
|
+
return process.platform === "win32" ? [path.join(dir, `${name}.exe`)] : [path.join(dir, name)];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** First native hit for the workbench bins inside `dirs`, or null. */
|
|
76
|
+
function findNativeIn(dirs) {
|
|
77
|
+
for (const dir of dirs) {
|
|
78
|
+
if (!dir) continue;
|
|
79
|
+
for (const name of NATIVE_BINS) {
|
|
80
|
+
for (const candidate of nativeCandidates(dir, name)) {
|
|
81
|
+
if (isNativeBinary(candidate)) return candidate;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function explicitDirs() {
|
|
89
|
+
const raw = process.env.ZETA_BIN_DIR;
|
|
90
|
+
if (!raw) return [];
|
|
91
|
+
return raw.split(path.delimiter).map((dir) => dir.trim()).filter((dir) => dir.length > 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Windows env blocks carry `Path`, POSIX `PATH` — accept either spelling. */
|
|
95
|
+
function pathDirs() {
|
|
96
|
+
const raw = process.env.PATH ?? process.env.Path;
|
|
97
|
+
return (raw || "").split(path.delimiter);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ① explicit env → ② PATH (native binaries only)
|
|
101
|
+
const fromNative = findNativeIn([...explicitDirs(), ...pathDirs()]);
|
|
102
|
+
|
|
103
|
+
let bin = fromNative;
|
|
104
|
+
if (!bin) {
|
|
105
|
+
// ③ npm vendored platform leaf. A resolved but non-executable leaf
|
|
106
|
+
// (broken extract, cache artifact) must fall through to the install
|
|
107
|
+
// hint instead of dying later with a raw spawn EACCES.
|
|
108
|
+
try {
|
|
109
|
+
const leaf = require.resolve(`${PKG_PREFIX}${PKG_PLATFORM}-${process.arch}/bin/${EXE}`);
|
|
110
|
+
if (process.platform === "win32" || isExecutable(leaf)) bin = leaf;
|
|
111
|
+
} catch {
|
|
112
|
+
// Fall back to a repo-layout location (dev / source checkout):
|
|
113
|
+
// <repo>/main/target/release/<exe> next to this package.
|
|
114
|
+
const local = path.join(__dirname, "..", "..", "..", "target", "release", EXE);
|
|
115
|
+
if (fs.existsSync(local) && (process.platform === "win32" || isExecutable(local))) bin = local;
|
|
116
|
+
}
|
|
28
117
|
}
|
|
29
118
|
|
|
30
119
|
if (!bin) {
|
|
31
120
|
die(
|
|
32
|
-
`no binary for ${process.platform}-${process.arch}; ` +
|
|
121
|
+
`no native zetawork/zeta on PATH and no binary for ${process.platform}-${process.arch}; ` +
|
|
33
122
|
`install @linxiraos/main (supported: windows-x64, linux-x64) ` +
|
|
34
123
|
`or build from source with \`cargo build --release\` in the main/ workspace`,
|
|
35
124
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxiraos/main",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.27",
|
|
4
4
|
"description": "zeta — the Zeta workspace: a nested-terminal workbench with tabs, panes, and the Zeta tool suite",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"README.md"
|
|
23
23
|
],
|
|
24
24
|
"optionalDependencies": {
|
|
25
|
-
"@linxiraos/main-windows-x64": "1.1.
|
|
26
|
-
"@linxiraos/main-linux-x64": "1.1.
|
|
25
|
+
"@linxiraos/main-windows-x64": "1.1.27",
|
|
26
|
+
"@linxiraos/main-linux-x64": "1.1.27"
|
|
27
27
|
},
|
|
28
28
|
"engines": {
|
|
29
29
|
"node": ">=18"
|