@spuentesp/zoanthrope 0.1.4 → 0.1.6
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/README.md +2 -1
- package/package.json +3 -2
- package/scripts/install.test.js +65 -0
- package/scripts/runtime.js +30 -5
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ Environment knobs:
|
|
|
18
18
|
(defaults to this package's version).
|
|
19
19
|
- `ZOANTHROPE_CACHE_DIR` — override the binary cache directory.
|
|
20
20
|
|
|
21
|
-
Prebuilt targets: Linux and macOS
|
|
21
|
+
Prebuilt targets: Linux and macOS (x86_64, aarch64) and Windows
|
|
22
|
+
(x86_64). Anything else
|
|
22
23
|
(or a failed download) gets a build-from-source message:
|
|
23
24
|
`cargo install --path .` from a clone of the repository.
|
|
24
25
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spuentesp/zoanthrope",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"mcpName": "io.github.spuentesp/zoanthrope",
|
|
5
5
|
"description": "Swarm coordination: file claims, agent presence, postboard intentions, filesystem leases, audit. MCP server + hook CLI.",
|
|
6
6
|
"keywords": [
|
|
@@ -26,7 +26,8 @@
|
|
|
26
26
|
"README.md"
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
|
-
"postinstall": "node scripts/install.js"
|
|
29
|
+
"postinstall": "node scripts/install.js",
|
|
30
|
+
"test": "node --test scripts/install.test.js"
|
|
30
31
|
},
|
|
31
32
|
"engines": {
|
|
32
33
|
"node": ">=18.0.0"
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Pure unit tests for the installer's platform mapping — no download,
|
|
4
|
+
// no OS dependency. Run with: node --test scripts/ (or `npm test`).
|
|
5
|
+
|
|
6
|
+
const test = require('node:test');
|
|
7
|
+
const assert = require('node:assert');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const { assetName, binaryPath, targetFor, tarExecutable } = require('./runtime');
|
|
11
|
+
|
|
12
|
+
test('targetFor maps win32-x64 to the MSVC target', () => {
|
|
13
|
+
assert.strictEqual(targetFor('win32', 'x64'), 'x86_64-pc-windows-msvc');
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('targetFor maps win32-arm64 to the MSVC target', () => {
|
|
17
|
+
assert.strictEqual(targetFor('win32', 'arm64'), 'aarch64-pc-windows-msvc');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('assetName resolves the windows x86_64 tarball the release ships', () => {
|
|
21
|
+
assert.strictEqual(
|
|
22
|
+
assetName(targetFor('win32', 'x64')),
|
|
23
|
+
'zoanthrope-x86_64-pc-windows-msvc.tar.gz'
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('assetName resolves the windows arm64 tarball name', () => {
|
|
28
|
+
assert.strictEqual(
|
|
29
|
+
assetName(targetFor('win32', 'arm64')),
|
|
30
|
+
'zoanthrope-aarch64-pc-windows-msvc.tar.gz'
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('binaryPath uses zoanthrope.exe on win32', () => {
|
|
35
|
+
const target = targetFor('win32', 'x64');
|
|
36
|
+
const file = binaryPath('0.1.5', target, {}, 'win32');
|
|
37
|
+
assert.strictEqual(path.basename(file), 'zoanthrope.exe');
|
|
38
|
+
assert.ok(file.includes(target));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('binaryPath stays extension-less on unix', () => {
|
|
42
|
+
const target = targetFor('linux', 'x64');
|
|
43
|
+
const file = binaryPath('0.1.5', target, {}, 'linux');
|
|
44
|
+
assert.strictEqual(path.basename(file), 'zoanthrope');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('targetFor keeps the pre-existing unix/darwin mappings', () => {
|
|
48
|
+
assert.strictEqual(targetFor('linux', 'x64'), 'x86_64-unknown-linux-gnu');
|
|
49
|
+
assert.strictEqual(targetFor('linux', 'arm64'), 'aarch64-unknown-linux-gnu');
|
|
50
|
+
assert.strictEqual(targetFor('darwin', 'x64'), 'x86_64-apple-darwin');
|
|
51
|
+
assert.strictEqual(targetFor('darwin', 'arm64'), 'aarch64-apple-darwin');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('targetFor rejects platforms with no prebuilt binary', () => {
|
|
55
|
+
assert.throws(() => targetFor('win32', 'ia32'), /No prebuilt zoanthrope binary/);
|
|
56
|
+
assert.throws(() => targetFor('freebsd', 'x64'), /No prebuilt zoanthrope binary/);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('Windows extraction uses System32 bsdtar, not the first tar on PATH', () => {
|
|
60
|
+
const env = { SystemRoot: 'C:\\Windows' };
|
|
61
|
+
assert.strictEqual(tarExecutable('win32', env, () => true), 'C:\\Windows\\System32\\tar.exe');
|
|
62
|
+
assert.strictEqual(tarExecutable('win32', env, () => false), 'tar');
|
|
63
|
+
assert.strictEqual(tarExecutable('win32', {}, () => true), 'tar');
|
|
64
|
+
assert.strictEqual(tarExecutable('linux', env, () => true), 'tar');
|
|
65
|
+
});
|
package/scripts/runtime.js
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
// Download-and-verify installer for the zoanthrope binary.
|
|
4
4
|
// Node builtins only (https, crypto, fs, child_process) — no runtime
|
|
5
5
|
// dependencies. Release assets are `zoanthrope-{target}.tar.gz` with
|
|
6
|
-
// the
|
|
7
|
-
//
|
|
6
|
+
// the platform binary at the archive root — bare `zoanthrope` on
|
|
7
|
+
// Linux/macOS, `zoanthrope.exe` on Windows; `SHA256SUMS` in the same
|
|
8
|
+
// release carries one checksum line per tarball.
|
|
8
9
|
|
|
9
10
|
const crypto = require('crypto');
|
|
10
11
|
const fs = require('fs');
|
|
@@ -25,6 +26,10 @@ function targetFor(platform = process.platform, arch = process.arch) {
|
|
|
25
26
|
'darwin-x64': 'x86_64-apple-darwin',
|
|
26
27
|
'linux-arm64': 'aarch64-unknown-linux-gnu',
|
|
27
28
|
'linux-x64': 'x86_64-unknown-linux-gnu',
|
|
29
|
+
// process.arch spells x86-64 `x64`, not `x86_64` — the tarball
|
|
30
|
+
// name comes from the rustc target triple, not the arch.
|
|
31
|
+
'win32-x64': 'x86_64-pc-windows-msvc',
|
|
32
|
+
'win32-arm64': 'aarch64-pc-windows-msvc',
|
|
28
33
|
};
|
|
29
34
|
const target = targets[`${platform}-${arch}`];
|
|
30
35
|
if (!target) throw new Error(`No prebuilt zoanthrope binary for ${platform}-${arch}. ${BUILD_FROM_SOURCE}`);
|
|
@@ -93,6 +98,21 @@ function verifyBinary(file, version) {
|
|
|
93
98
|
}
|
|
94
99
|
}
|
|
95
100
|
|
|
101
|
+
|
|
102
|
+
// On Windows the first `tar` on PATH (Git Bash's GNU tar on the shells
|
|
103
|
+
// GitHub runners use) fails on these archives with `gzip: stdin:
|
|
104
|
+
// unexpected end of file`. Windows ships bsdtar at System32\tar.exe;
|
|
105
|
+
// use it when present — same fix as the lain shim.
|
|
106
|
+
function tarExecutable(platform = process.platform, env = process.env, exists = fs.existsSync) {
|
|
107
|
+
if (platform !== 'win32') return 'tar';
|
|
108
|
+
const root = env.SystemRoot || env.SYSTEMROOT || env.windir || env.WINDIR;
|
|
109
|
+
if (root) {
|
|
110
|
+
const system = path.win32.join(root, 'System32', 'tar.exe');
|
|
111
|
+
if (exists(system)) return system;
|
|
112
|
+
}
|
|
113
|
+
return 'tar';
|
|
114
|
+
}
|
|
115
|
+
|
|
96
116
|
function download(url, destination, redirects = 5) {
|
|
97
117
|
return new Promise((resolve, reject) => {
|
|
98
118
|
const request = https.get(url, { headers: { 'User-Agent': '@spuentesp/zoanthrope' } }, (response) => {
|
|
@@ -153,9 +173,13 @@ async function ensureBinary(options = {}) {
|
|
|
153
173
|
await fetch(releaseUrl(version, 'SHA256SUMS'), sums);
|
|
154
174
|
await fetch(releaseUrl(version, asset), archive);
|
|
155
175
|
verifyArchive(archive, parseChecksum(fs.readFileSync(sums, 'utf8'), asset));
|
|
156
|
-
execFileSync(
|
|
157
|
-
|
|
158
|
-
|
|
176
|
+
execFileSync(tarExecutable(platform), ['xzf', archive, '-C', temporary], { stdio: ['ignore', 'ignore', 'inherit'] });
|
|
177
|
+
// On win32 the archive root carries `zoanthrope.exe` (spawning an
|
|
178
|
+
// extension-less file makes CreateProcess append .exe and miss the
|
|
179
|
+
// real file); everywhere else the bare name.
|
|
180
|
+
const extractedName = platform === 'win32' ? 'zoanthrope.exe' : 'zoanthrope';
|
|
181
|
+
const extracted = path.join(temporary, extractedName);
|
|
182
|
+
if (!fs.existsSync(extracted)) throw new Error(`${asset} does not contain the ${extractedName} executable at its root`);
|
|
159
183
|
if (platform !== 'win32') fs.chmodSync(extracted, 0o755);
|
|
160
184
|
verifyBinary(extracted, version);
|
|
161
185
|
try {
|
|
@@ -190,6 +214,7 @@ module.exports = {
|
|
|
190
214
|
releaseUrl,
|
|
191
215
|
selectedVersion,
|
|
192
216
|
sha256,
|
|
217
|
+
tarExecutable,
|
|
193
218
|
targetFor,
|
|
194
219
|
verifyArchive,
|
|
195
220
|
verifyBinary,
|