@symbiosis-lab/moss 0.12.1 → 0.15.9
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 +9 -40
- package/bin/moss.js +1 -16
- package/lib/fetch.js +60 -18
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
# @symbiosis-lab/moss
|
|
2
2
|
|
|
3
|
-
moss on your PATH. This package downloads the
|
|
4
|
-
CLI binary from [moss-releases](https://github.com/Symbiosis-Lab/moss-releases)
|
|
5
|
-
and exposes it as the `moss` command.
|
|
6
|
-
|
|
7
|
-
> **Publishing note:** the package is currently marked `"private": true` in
|
|
8
|
-
> `package.json` so it cannot ship by accident. Flip that (remove the field)
|
|
9
|
-
> at publish time — `publishConfig` is already set up.
|
|
3
|
+
moss on your PATH. This package downloads the open [moss-cli](https://github.com/Symbiosis-Lab/moss/tree/develop/crates/moss-cli) binary and exposes it as the `moss` command.
|
|
10
4
|
|
|
11
5
|
## Install
|
|
12
6
|
|
|
@@ -15,12 +9,9 @@ npm install -g @symbiosis-lab/moss
|
|
|
15
9
|
moss --version
|
|
16
10
|
```
|
|
17
11
|
|
|
18
|
-
The binary is fetched at install time (postinstall). With `--ignore-scripts`,
|
|
19
|
-
or if the download failed (e.g. offline), the first `moss` invocation fetches
|
|
20
|
-
it lazily instead.
|
|
12
|
+
The binary is fetched at install time (postinstall). With `--ignore-scripts`, or if the download failed (e.g. offline), the first `moss` invocation fetches it lazily instead.
|
|
21
13
|
|
|
22
|
-
Supported platforms: macOS (Intel and Apple Silicon, one universal binary)
|
|
23
|
-
and Linux x86_64.
|
|
14
|
+
Supported platforms: macOS (Intel and Apple Silicon, one universal binary) and Linux x86_64. The binary has no window system in its dependency graph, so it starts on a headless Linux server or inside a container with no desktop libraries to install first.
|
|
24
15
|
|
|
25
16
|
## Use
|
|
26
17
|
|
|
@@ -30,29 +21,15 @@ moss build ~/Sites/my-site
|
|
|
30
21
|
|
|
31
22
|
All arguments pass straight through to the moss binary; see `moss --help`.
|
|
32
23
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
The current Linux binary links against WebKitGTK even for headless CLI verbs.
|
|
36
|
-
If `moss` fails with `error while loading shared libraries`, install:
|
|
37
|
-
|
|
38
|
-
```sh
|
|
39
|
-
sudo apt install libwebkit2gtk-4.1-0
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
This requirement is temporary — a moss CLI build without the WebKitGTK
|
|
43
|
-
linkage is planned.
|
|
24
|
+
`moss preview` and `moss edit` need a window, which this binary doesn't have: they hand off to [moss desktop](https://mosspub.com) if it's installed, or print a one-line hint if it isn't. On macOS, `moss desktop install` fetches and installs it for you (see `moss desktop install --help`); it always asks before downloading and never runs unattended (no terminal attached, as in CI, is treated as declining). moss desktop isn't packaged for Linux or Windows yet, so `moss desktop install` there just prints where to get it.
|
|
44
25
|
|
|
45
26
|
## Checksums
|
|
46
27
|
|
|
47
|
-
Downloads are verified against the `SHA256SUMS` file published with each
|
|
48
|
-
release. Releases that predate checksum publishing install with a warning
|
|
49
|
-
instead of verification.
|
|
28
|
+
Downloads are verified against the `SHA256SUMS` file published with each release. Releases that predate checksum publishing install with a warning instead of verification.
|
|
50
29
|
|
|
51
30
|
## Versioning and overrides
|
|
52
31
|
|
|
53
|
-
The wrapper downloads the moss version matching its own package version;
|
|
54
|
-
they are released in lockstep. `MOSS_VERSION_OVERRIDE=v0.11.1` forces a
|
|
55
|
-
specific release (ops/testing escape hatch).
|
|
32
|
+
The wrapper downloads the moss version matching its own package version; they are released in lockstep. `MOSS_VERSION_OVERRIDE=v0.11.1` forces a specific release (ops/testing escape hatch).
|
|
56
33
|
|
|
57
34
|
## Controlling the download
|
|
58
35
|
|
|
@@ -62,18 +39,10 @@ specific release (ops/testing escape hatch).
|
|
|
62
39
|
| `MOSS_BINARY_PATH=/path/to/moss` | Run that binary instead of the vendored one, and skip the download entirely. |
|
|
63
40
|
| `MOSS_FORCE_BINARY_DOWNLOAD=1` | Download even where the wrapper would otherwise skip. |
|
|
64
41
|
|
|
65
|
-
Each also reads from `.npmrc` under its lowercased name (`moss_skip_binary_download=true`),
|
|
66
|
-
because npm passes config keys to lifecycle scripts as `npm_config_*`.
|
|
42
|
+
Each also reads from `.npmrc` under its lowercased name (`moss_skip_binary_download=true`), because npm passes config keys to lifecycle scripts as `npm_config_*`.
|
|
67
43
|
|
|
68
|
-
**Inside the moss repo the download is skipped automatically.** A checkout is
|
|
69
|
-
not an install: `packages/moss` sits in the workspace rather than under
|
|
70
|
-
`node_modules`, so `pnpm install` at the repo root would otherwise pull a
|
|
71
|
-
release binary that no moss developer wants — they build from source. Point
|
|
72
|
-
`MOSS_BINARY_PATH` at `src-tauri/target/release/moss` to exercise the wrapper
|
|
73
|
-
against your own build.
|
|
44
|
+
**Inside the moss repo the download is skipped automatically.** A checkout is not an install: `packages/moss` sits in the workspace rather than under `node_modules`, so `pnpm install` at the repo root would otherwise pull a release binary that no moss developer wants — they build from source. Point `MOSS_BINARY_PATH` at `target/release/moss-cli` (`cargo build --release -p moss-cli`) to exercise the wrapper against your own build.
|
|
74
45
|
|
|
75
46
|
## License
|
|
76
47
|
|
|
77
|
-
The wrapper code in this package is MIT (see LICENSE). The moss binary it
|
|
78
|
-
downloads is a separate work, distributed under its own terms via
|
|
79
|
-
[moss-releases](https://github.com/Symbiosis-Lab/moss-releases).
|
|
48
|
+
The wrapper code in this package is MIT (see LICENSE). The moss binary it downloads is a separate work, distributed under its own terms via [moss](https://github.com/Symbiosis-Lab/moss).
|
package/bin/moss.js
CHANGED
|
@@ -24,25 +24,10 @@ async function main() {
|
|
|
24
24
|
await fetchBinary();
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
// verbatim. stdin/stdout stay inherited for interactive use.
|
|
29
|
-
const result = spawnSync(binary, process.argv.slice(2), {
|
|
30
|
-
stdio: ['inherit', 'inherit', 'pipe'],
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const stderr = result.stderr ? result.stderr.toString() : '';
|
|
34
|
-
if (stderr) process.stderr.write(stderr);
|
|
27
|
+
const result = spawnSync(binary, process.argv.slice(2), { stdio: 'inherit' });
|
|
35
28
|
|
|
36
29
|
if (result.error) throw result.error;
|
|
37
30
|
|
|
38
|
-
if (stderr.includes('error while loading shared libraries')) {
|
|
39
|
-
console.error(
|
|
40
|
-
'\nmoss-npm: the moss binary currently needs the WebKitGTK runtime libraries:\n' +
|
|
41
|
-
' sudo apt install libwebkit2gtk-4.1-0\n' +
|
|
42
|
-
'This is temporary — a moss CLI build without that linkage is planned.'
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
31
|
process.exit(result.status === null ? 1 : result.status);
|
|
47
32
|
}
|
|
48
33
|
|
package/lib/fetch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Downloads the moss CLI binary for this platform from moss
|
|
1
|
+
// Downloads the moss CLI binary for this platform from moss.
|
|
2
2
|
//
|
|
3
3
|
// No dependencies: uses the global fetch that ships with Node >= 18.
|
|
4
4
|
// The version defaults to this package's own version (the wrapper is
|
|
@@ -11,10 +11,15 @@ const crypto = require('node:crypto');
|
|
|
11
11
|
const fs = require('node:fs');
|
|
12
12
|
const path = require('node:path');
|
|
13
13
|
|
|
14
|
-
const RELEASES = 'https://github.com/Symbiosis-Lab/moss
|
|
14
|
+
const RELEASES = 'https://github.com/Symbiosis-Lab/moss/releases/download';
|
|
15
15
|
|
|
16
16
|
const packageRoot = path.join(__dirname, '..');
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
// Compute the vendored binary path at use time, appending .exe on win32.
|
|
19
|
+
function vendorBinary() {
|
|
20
|
+
const name = process.platform === 'win32' ? 'moss.exe' : 'moss';
|
|
21
|
+
return path.join(packageRoot, 'vendor', name);
|
|
22
|
+
}
|
|
18
23
|
|
|
19
24
|
// npm and pnpm expose every `.npmrc` key to lifecycle scripts as `npm_config_<key>`,
|
|
20
25
|
// so one lookup covers both the environment variable and the config file. This is
|
|
@@ -58,7 +63,7 @@ function skipDownloadReason() {
|
|
|
58
63
|
// Which binary `moss` should execute. `MOSS_BINARY_PATH` wins so a developer can
|
|
59
64
|
// point the wrapper at a locally built moss (esbuild's `ESBUILD_BINARY_PATH`).
|
|
60
65
|
function resolveBinary() {
|
|
61
|
-
return process.env.MOSS_BINARY_PATH || vendorBinary;
|
|
66
|
+
return process.env.MOSS_BINARY_PATH || vendorBinary();
|
|
62
67
|
}
|
|
63
68
|
|
|
64
69
|
function resolveVersion() {
|
|
@@ -77,10 +82,13 @@ function resolveAsset() {
|
|
|
77
82
|
if (platform === 'linux' && arch === 'x64') {
|
|
78
83
|
return 'moss-linux-x86_64';
|
|
79
84
|
}
|
|
85
|
+
if (platform === 'win32' && arch === 'x64') {
|
|
86
|
+
return 'moss-windows-x86_64.exe';
|
|
87
|
+
}
|
|
80
88
|
throw new Error(
|
|
81
89
|
`moss-npm: no moss binary is published for ${platform}-${arch}.\n` +
|
|
82
|
-
'Supported: macOS (x64/arm64) and
|
|
83
|
-
'See https://github.com/Symbiosis-Lab/moss
|
|
90
|
+
'Supported: macOS (x64/arm64), Linux (x64), and Windows (x64). ' +
|
|
91
|
+
'See https://github.com/Symbiosis-Lab/moss for available builds.'
|
|
84
92
|
);
|
|
85
93
|
}
|
|
86
94
|
|
|
@@ -92,26 +100,57 @@ async function download(url) {
|
|
|
92
100
|
return Buffer.from(await res.arrayBuffer());
|
|
93
101
|
}
|
|
94
102
|
|
|
95
|
-
//
|
|
96
|
-
//
|
|
103
|
+
// The first release that published a SHA256SUMS file. Before it there is
|
|
104
|
+
// nothing to verify against; from it on, every release has one.
|
|
105
|
+
const CHECKSUMS_SINCE = [0, 11, 2];
|
|
106
|
+
|
|
107
|
+
// Must a missing checksum be fatal for this version? Anything unparseable
|
|
108
|
+
// answers yes: an unrecognised version string is not a licence to skip the
|
|
109
|
+
// only check on bytes we are about to mark executable.
|
|
110
|
+
function checksumsRequired(version) {
|
|
111
|
+
const parts = String(version).split('-')[0].split('.').map(Number);
|
|
112
|
+
if (parts.length !== 3 || parts.some((n) => !Number.isInteger(n))) return true;
|
|
113
|
+
for (let i = 0; i < 3; i += 1) {
|
|
114
|
+
if (parts[i] !== CHECKSUMS_SINCE[i]) return parts[i] > CHECKSUMS_SINCE[i];
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Verifies bytes against the release's SHA256SUMS.
|
|
120
|
+
//
|
|
121
|
+
// Every reason we might not reach a checksum — a non-200, a network error, a
|
|
122
|
+
// SHA256SUMS with no line for this asset — is reached over the same connection
|
|
123
|
+
// that just served the binary. So on a version that publishes checksums, taking
|
|
124
|
+
// any of them as permission to skip verification hands the skip to whoever
|
|
125
|
+
// controls that connection: suppress one small request and the binary installs
|
|
126
|
+
// unverified. Fail closed there, and keep the warning only for the pre-v0.11.2
|
|
127
|
+
// releases where the file genuinely does not exist.
|
|
97
128
|
async function verifyChecksum(bytes, asset, version) {
|
|
129
|
+
const unverified = (reason) => {
|
|
130
|
+
if (checksumsRequired(version)) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`moss-npm: cannot verify moss v${version} (${asset}): ${reason}.\n` +
|
|
133
|
+
' Every release from v0.11.2 on publishes SHA256SUMS, so this is either a\n' +
|
|
134
|
+
' transient network fault or a tampered download. Not installing.'
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
console.warn(`moss-npm: ${reason}; skipping checksum verification (v${version} predates SHA256SUMS)`);
|
|
138
|
+
};
|
|
139
|
+
|
|
98
140
|
let sums;
|
|
99
141
|
try {
|
|
100
142
|
const res = await fetch(`${RELEASES}/v${version}/SHA256SUMS`, { redirect: 'follow' });
|
|
101
143
|
if (!res.ok) {
|
|
102
|
-
|
|
103
|
-
return;
|
|
144
|
+
return unverified(`no SHA256SUMS published for v${version} (${res.status})`);
|
|
104
145
|
}
|
|
105
146
|
sums = await res.text();
|
|
106
147
|
} catch (err) {
|
|
107
|
-
|
|
108
|
-
return;
|
|
148
|
+
return unverified(`could not fetch SHA256SUMS (${err.message})`);
|
|
109
149
|
}
|
|
110
150
|
|
|
111
151
|
const line = sums.split('\n').find((l) => l.trim().endsWith(asset));
|
|
112
152
|
if (!line) {
|
|
113
|
-
|
|
114
|
-
return;
|
|
153
|
+
return unverified(`SHA256SUMS has no entry for ${asset}`);
|
|
115
154
|
}
|
|
116
155
|
|
|
117
156
|
const expected = line.trim().split(/\s+/)[0];
|
|
@@ -134,17 +173,20 @@ async function fetchBinary() {
|
|
|
134
173
|
const bytes = await download(url);
|
|
135
174
|
await verifyChecksum(bytes, asset, version);
|
|
136
175
|
|
|
137
|
-
|
|
138
|
-
fs.
|
|
139
|
-
|
|
140
|
-
|
|
176
|
+
const binaryPath = vendorBinary();
|
|
177
|
+
fs.mkdirSync(path.dirname(binaryPath), { recursive: true });
|
|
178
|
+
fs.writeFileSync(binaryPath, bytes, { mode: 0o755 });
|
|
179
|
+
console.log(`moss-npm: installed ${binaryPath}`);
|
|
180
|
+
return binaryPath;
|
|
141
181
|
}
|
|
142
182
|
|
|
143
183
|
module.exports = {
|
|
184
|
+
checksumsRequired,
|
|
144
185
|
fetchBinary,
|
|
145
186
|
vendorBinary,
|
|
146
187
|
resolveAsset,
|
|
147
188
|
resolveBinary,
|
|
148
189
|
resolveVersion,
|
|
149
190
|
skipDownloadReason,
|
|
191
|
+
verifyChecksum,
|
|
150
192
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbiosis-lab/moss",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "moss on your PATH — npm wrapper that installs the moss CLI binary from moss
|
|
3
|
+
"version": "0.15.9",
|
|
4
|
+
"description": "moss on your PATH — npm wrapper that installs the moss CLI binary from moss",
|
|
5
5
|
"bin": {
|
|
6
6
|
"moss": "bin/moss.js"
|
|
7
7
|
},
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
},
|
|
23
23
|
"os": [
|
|
24
24
|
"darwin",
|
|
25
|
-
"linux"
|
|
25
|
+
"linux",
|
|
26
|
+
"win32"
|
|
26
27
|
],
|
|
27
28
|
"cpu": [
|
|
28
29
|
"x64",
|
|
@@ -38,10 +39,10 @@
|
|
|
38
39
|
"license": "MIT",
|
|
39
40
|
"repository": {
|
|
40
41
|
"type": "git",
|
|
41
|
-
"url": "git+https://github.com/Symbiosis-Lab/moss
|
|
42
|
+
"url": "git+https://github.com/Symbiosis-Lab/moss.git"
|
|
42
43
|
},
|
|
43
44
|
"bugs": {
|
|
44
|
-
"url": "https://github.com/Symbiosis-Lab/moss
|
|
45
|
+
"url": "https://github.com/Symbiosis-Lab/moss/issues"
|
|
45
46
|
},
|
|
46
47
|
"homepage": "https://mosspub.com",
|
|
47
48
|
"publishConfig": {
|