@themoltnet/cli 1.26.0 → 1.27.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.
- package/bin/moltnet.js +27 -5
- package/install.js +63 -116
- package/package.json +13 -5
package/bin/moltnet.js
CHANGED
|
@@ -6,13 +6,35 @@ const fs = require('fs');
|
|
|
6
6
|
const { execFileSync } = require('child_process');
|
|
7
7
|
|
|
8
8
|
const binaryName = process.platform === 'win32' ? 'moltnet.exe' : 'moltnet';
|
|
9
|
-
const binaryPath = path.join(__dirname, binaryName);
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
function findBinary() {
|
|
11
|
+
const pkgName = `@themoltnet/cli-${process.platform}-${process.arch}`;
|
|
12
|
+
try {
|
|
13
|
+
const pkgDir = path.dirname(require.resolve(`${pkgName}/package.json`));
|
|
14
|
+
const pkgPath = path.join(pkgDir, 'bin', binaryName);
|
|
15
|
+
if (fs.existsSync(pkgPath)) {
|
|
16
|
+
return pkgPath;
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
// Platform package not installed
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const localPath = path.join(__dirname, binaryName);
|
|
23
|
+
if (fs.existsSync(localPath)) {
|
|
24
|
+
return localPath;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const binaryPath = findBinary();
|
|
31
|
+
|
|
32
|
+
if (!binaryPath) {
|
|
12
33
|
console.error(
|
|
13
|
-
`moltnet binary not found
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
`moltnet binary not found for ${process.platform}-${process.arch}\n` +
|
|
35
|
+
`Install the platform package manually:\n` +
|
|
36
|
+
` npm install @themoltnet/cli-${process.platform}-${process.arch}\n` +
|
|
37
|
+
`Or reinstall @themoltnet/cli to trigger the postinstall fallback.`
|
|
16
38
|
);
|
|
17
39
|
process.exit(1);
|
|
18
40
|
}
|
package/install.js
CHANGED
|
@@ -4,44 +4,34 @@
|
|
|
4
4
|
const https = require('https');
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
7
|
-
const crypto = require('crypto');
|
|
8
7
|
const zlib = require('zlib');
|
|
9
8
|
const { execFileSync } = require('child_process');
|
|
10
9
|
|
|
11
10
|
const VERSION = require('./package.json').version;
|
|
12
|
-
const REPO = 'getlarge/themoltnet';
|
|
13
|
-
const TAG = `cli-v${VERSION}`;
|
|
14
|
-
const BASE_URL = `https://github.com/${REPO}/releases/download/${TAG}`;
|
|
15
|
-
|
|
16
|
-
const PLATFORM_MAP = {
|
|
17
|
-
darwin: 'darwin',
|
|
18
|
-
linux: 'linux',
|
|
19
|
-
win32: 'windows',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const ARCH_MAP = {
|
|
23
|
-
x64: 'amd64',
|
|
24
|
-
arm64: 'arm64',
|
|
25
|
-
};
|
|
26
11
|
|
|
27
12
|
function getBinaryName() {
|
|
28
13
|
return process.platform === 'win32' ? 'moltnet.exe' : 'moltnet';
|
|
29
14
|
}
|
|
30
15
|
|
|
31
|
-
function
|
|
32
|
-
return
|
|
16
|
+
function getPlatformPackageName() {
|
|
17
|
+
return `@themoltnet/cli-${process.platform}-${process.arch}`;
|
|
33
18
|
}
|
|
34
19
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
20
|
+
// Case 1 (happy path): the platform package was installed via
|
|
21
|
+
// optionalDependencies. bin/moltnet.js resolves the binary in place at
|
|
22
|
+
// runtime, so install.js has nothing to do.
|
|
23
|
+
function tryPlatformPackage() {
|
|
24
|
+
const pkgName = getPlatformPackageName();
|
|
25
|
+
try {
|
|
26
|
+
const pkgDir = path.dirname(require.resolve(`${pkgName}/package.json`));
|
|
27
|
+
const binaryPath = path.join(pkgDir, 'bin', getBinaryName());
|
|
28
|
+
if (fs.existsSync(binaryPath)) {
|
|
29
|
+
return binaryPath;
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// Platform package not installed (e.g. --no-optional, yarn v1 optional bug)
|
|
42
33
|
}
|
|
43
|
-
|
|
44
|
-
return `moltnet_${VERSION}_${os}_${arch}.${ext}`;
|
|
34
|
+
return null;
|
|
45
35
|
}
|
|
46
36
|
|
|
47
37
|
function fetch(url, maxRedirects = 5) {
|
|
@@ -51,13 +41,15 @@ function fetch(url, maxRedirects = 5) {
|
|
|
51
41
|
}
|
|
52
42
|
https
|
|
53
43
|
.get(url, { headers: { 'User-Agent': 'themoltnet-cli' } }, (res) => {
|
|
54
|
-
if (
|
|
44
|
+
if (
|
|
45
|
+
res.statusCode >= 300 &&
|
|
46
|
+
res.statusCode < 400 &&
|
|
47
|
+
res.headers.location
|
|
48
|
+
) {
|
|
55
49
|
return resolve(fetch(res.headers.location, maxRedirects - 1));
|
|
56
50
|
}
|
|
57
51
|
if (res.statusCode !== 200) {
|
|
58
|
-
return reject(
|
|
59
|
-
new Error(`HTTP ${res.statusCode} fetching ${url}`)
|
|
60
|
-
);
|
|
52
|
+
return reject(new Error(`HTTP ${res.statusCode} fetching ${url}`));
|
|
61
53
|
}
|
|
62
54
|
const chunks = [];
|
|
63
55
|
res.on('data', (chunk) => chunks.push(chunk));
|
|
@@ -68,106 +60,61 @@ function fetch(url, maxRedirects = 5) {
|
|
|
68
60
|
});
|
|
69
61
|
}
|
|
70
62
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
// Case 2 (fallback): fetch the platform package tarball directly from the npm
|
|
64
|
+
// registry and extract the binary into local bin/. The registry is reachable
|
|
65
|
+
// in most sandboxed environments where github.com is not.
|
|
66
|
+
async function downloadFromNpm() {
|
|
67
|
+
const pkgName = getPlatformPackageName();
|
|
68
|
+
const bareName = pkgName.split('/')[1];
|
|
69
|
+
const tarballUrl = `https://registry.npmjs.org/${pkgName}/-/${bareName}-${VERSION}.tgz`;
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
`Checksum not found for ${archiveName} in checksums.txt`
|
|
80
|
-
);
|
|
81
|
-
}
|
|
71
|
+
console.log(`Downloading moltnet binary from ${tarballUrl}`);
|
|
72
|
+
const tarball = await fetch(tarballUrl);
|
|
73
|
+
const gunzipped = zlib.gunzipSync(tarball);
|
|
82
74
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
.createHash('sha256')
|
|
86
|
-
.update(archiveBuffer)
|
|
87
|
-
.digest('hex');
|
|
88
|
-
|
|
89
|
-
if (actualHash !== expectedHash) {
|
|
90
|
-
throw new Error(
|
|
91
|
-
`Checksum mismatch for ${archiveName}:\n expected: ${expectedHash}\n actual: ${actualHash}`
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function extractTarGz(buffer, destDir) {
|
|
97
|
-
const tmpDir = path.join(__dirname, '.tmp');
|
|
98
|
-
const tmpFile = path.join(tmpDir, 'archive.tar.gz');
|
|
75
|
+
const tmpDir = path.join(__dirname, '.install-tmp');
|
|
76
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
99
77
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
execFileSync('tar', ['xzf', tmpFile, '-C', destDir], {
|
|
103
|
-
stdio: 'pipe',
|
|
104
|
-
});
|
|
105
|
-
} finally {
|
|
106
|
-
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
107
|
-
}
|
|
108
|
-
}
|
|
78
|
+
const tmpTar = path.join(tmpDir, 'archive.tar');
|
|
79
|
+
fs.writeFileSync(tmpTar, gunzipped);
|
|
109
80
|
|
|
110
|
-
function extractZip(buffer, destDir) {
|
|
111
|
-
const tmpDir = path.join(__dirname, '.tmp');
|
|
112
|
-
const tmpFile = path.join(tmpDir, 'archive.zip');
|
|
113
|
-
fs.mkdirSync(tmpDir, { recursive: true });
|
|
114
|
-
fs.writeFileSync(tmpFile, buffer);
|
|
115
81
|
try {
|
|
116
|
-
execFileSync(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
);
|
|
82
|
+
execFileSync('tar', ['xf', tmpTar, '-C', tmpDir], { stdio: 'pipe' });
|
|
83
|
+
|
|
84
|
+
const extractedBinary = path.join(tmpDir, 'package', 'bin', getBinaryName());
|
|
85
|
+
if (!fs.existsSync(extractedBinary)) {
|
|
86
|
+
throw new Error(`Binary not found in tarball: ${extractedBinary}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const targetBinDir = path.join(__dirname, 'bin');
|
|
90
|
+
fs.mkdirSync(targetBinDir, { recursive: true });
|
|
91
|
+
const targetPath = path.join(targetBinDir, getBinaryName());
|
|
92
|
+
fs.copyFileSync(extractedBinary, targetPath);
|
|
93
|
+
if (process.platform !== 'win32') {
|
|
94
|
+
fs.chmodSync(targetPath, 0o755);
|
|
95
|
+
}
|
|
96
|
+
return targetPath;
|
|
125
97
|
} finally {
|
|
126
98
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
127
99
|
}
|
|
128
100
|
}
|
|
129
101
|
|
|
130
102
|
async function main() {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
if (fs.existsSync(binaryPath)) {
|
|
134
|
-
console.log(`moltnet binary already exists at ${binaryPath}, skipping download.`);
|
|
103
|
+
if (tryPlatformPackage()) {
|
|
135
104
|
return;
|
|
136
105
|
}
|
|
137
106
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const binDir = path.join(__dirname, 'bin');
|
|
150
|
-
fs.mkdirSync(binDir, { recursive: true });
|
|
151
|
-
|
|
152
|
-
console.log('Extracting...');
|
|
153
|
-
if (process.platform === 'win32') {
|
|
154
|
-
extractZip(archiveBuffer, binDir);
|
|
155
|
-
} else {
|
|
156
|
-
extractTarGz(archiveBuffer, binDir);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (process.platform !== 'win32') {
|
|
160
|
-
fs.chmodSync(binaryPath, 0o755);
|
|
107
|
+
try {
|
|
108
|
+
const binaryPath = await downloadFromNpm();
|
|
109
|
+
console.log(`Installed moltnet ${VERSION} to ${binaryPath}`);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
console.warn(`Warning: Failed to install moltnet binary: ${err.message}`);
|
|
112
|
+
console.warn(
|
|
113
|
+
`You can install the platform package manually:\n` +
|
|
114
|
+
` npm install ${getPlatformPackageName()}@${VERSION}`
|
|
115
|
+
);
|
|
116
|
+
// Exit 0 so postinstall doesn't break install for the whole project
|
|
161
117
|
}
|
|
162
|
-
|
|
163
|
-
console.log(`Installed moltnet ${VERSION} to ${binaryPath}`);
|
|
164
118
|
}
|
|
165
119
|
|
|
166
|
-
main()
|
|
167
|
-
console.warn(`Warning: Failed to install moltnet binary: ${err.message}`);
|
|
168
|
-
console.warn(
|
|
169
|
-
`\nYou can download it manually from:\n ${BASE_URL}/`
|
|
170
|
-
);
|
|
171
|
-
// Exit 0 so postinstall doesn't break `pnpm install` for the whole monorepo
|
|
172
|
-
process.exit(0);
|
|
173
|
-
});
|
|
120
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@themoltnet/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.0",
|
|
4
4
|
"description": "CLI for MoltNet — AI agent identity and autonomy network",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -12,14 +12,22 @@
|
|
|
12
12
|
"bin": {
|
|
13
13
|
"moltnet": "bin/moltnet.js"
|
|
14
14
|
},
|
|
15
|
-
"scripts": {
|
|
16
|
-
"postinstall": "node install.js"
|
|
17
|
-
},
|
|
18
15
|
"files": [
|
|
19
16
|
"bin/moltnet.js",
|
|
20
17
|
"install.js"
|
|
21
18
|
],
|
|
22
19
|
"engines": {
|
|
23
20
|
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"optionalDependencies": {
|
|
23
|
+
"@themoltnet/cli-darwin-arm64": "1.27.0",
|
|
24
|
+
"@themoltnet/cli-linux-x64": "1.27.0",
|
|
25
|
+
"@themoltnet/cli-darwin-x64": "1.27.0",
|
|
26
|
+
"@themoltnet/cli-win32-arm64": "1.27.0",
|
|
27
|
+
"@themoltnet/cli-linux-arm64": "1.27.0",
|
|
28
|
+
"@themoltnet/cli-win32-x64": "1.27.0"
|
|
29
|
+
},
|
|
30
|
+
"scripts": {
|
|
31
|
+
"postinstall": "node install.js"
|
|
24
32
|
}
|
|
25
|
-
}
|
|
33
|
+
}
|