mushroomdb 0.7.2 → 0.8.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/README.md +1 -1
- package/bin/mushroomdb.js +8 -1
- package/install.js +60 -17
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ declare a relationship as a rule, once; every write after that derives the match
|
|
|
7
7
|
them, and retracts them when they stop being true.
|
|
8
8
|
|
|
9
9
|
This package is the launcher: it downloads the native `mushroomdb` binary for your platform from
|
|
10
|
-
the project's GitHub Releases and runs it. macOS
|
|
10
|
+
the project's GitHub Releases and runs it. macOS (Apple Silicon and Intel), Linux x86_64 (glibc and musl), Linux arm64 and Windows x86_64 are built.
|
|
11
11
|
|
|
12
12
|
```sh
|
|
13
13
|
npx mushroomdb install --db ./memory # give Claude Code, Cursor or Codex a memory
|
package/bin/mushroomdb.js
CHANGED
|
@@ -5,7 +5,14 @@ const { spawnSync } = require("child_process");
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
|
|
8
|
-
const bin = path.resolve(
|
|
8
|
+
const bin = path.resolve(
|
|
9
|
+
path.join(
|
|
10
|
+
__dirname,
|
|
11
|
+
"..",
|
|
12
|
+
"vendor",
|
|
13
|
+
process.platform === "win32" ? "mushroomdb.exe" : "mushroomdb",
|
|
14
|
+
),
|
|
15
|
+
);
|
|
9
16
|
|
|
10
17
|
// Two flags that answer "where is this package", so an installer can ask once
|
|
11
18
|
// instead of making every invocation pay for `npx`.
|
package/install.js
CHANGED
|
@@ -5,20 +5,39 @@ const crypto = require("crypto");
|
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const http = require("http");
|
|
7
7
|
const https = require("https");
|
|
8
|
-
const os = require("os");
|
|
9
8
|
const path = require("path");
|
|
10
|
-
const
|
|
9
|
+
const zlib = require("zlib");
|
|
11
10
|
|
|
12
11
|
const pkg = require("./package.json");
|
|
13
12
|
const SUPPORTED = [
|
|
14
13
|
"darwin-arm64 → aarch64-apple-darwin",
|
|
14
|
+
"darwin-x64 → x86_64-apple-darwin",
|
|
15
15
|
"linux-x64 → x86_64-unknown-linux-gnu",
|
|
16
|
+
"linux-x64 with musl → x86_64-unknown-linux-musl",
|
|
16
17
|
"linux-arm64 → aarch64-unknown-linux-gnu",
|
|
18
|
+
"win32-x64 → x86_64-pc-windows-msvc",
|
|
17
19
|
];
|
|
18
20
|
|
|
21
|
+
// Whether this Linux is a musl one (Alpine). Node reports the glibc it runs
|
|
22
|
+
// on; a Node built for musl reports none. MUSHROOMDB_FORCE_LIBC overrides.
|
|
23
|
+
function isMusl() {
|
|
24
|
+
const forced = process.env.MUSHROOMDB_FORCE_LIBC;
|
|
25
|
+
if (forced) return forced === "musl";
|
|
26
|
+
try {
|
|
27
|
+
const header = process.report.getReport().header;
|
|
28
|
+
return !header.glibcVersionRuntime;
|
|
29
|
+
} catch (_) {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
19
34
|
function rustTarget(platform, arch) {
|
|
20
35
|
if (platform === "darwin" && arch === "arm64") return "aarch64-apple-darwin";
|
|
21
|
-
if (platform === "
|
|
36
|
+
if (platform === "darwin" && arch === "x64") return "x86_64-apple-darwin";
|
|
37
|
+
if (platform === "win32" && arch === "x64") return "x86_64-pc-windows-msvc";
|
|
38
|
+
if (platform === "linux" && arch === "x64") {
|
|
39
|
+
return isMusl() ? "x86_64-unknown-linux-musl" : "x86_64-unknown-linux-gnu";
|
|
40
|
+
}
|
|
22
41
|
if (platform === "linux" && (arch === "arm64" || arch === "aarch64")) {
|
|
23
42
|
return "aarch64-unknown-linux-gnu";
|
|
24
43
|
}
|
|
@@ -53,6 +72,33 @@ function fetchBuffer(url) {
|
|
|
53
72
|
});
|
|
54
73
|
}
|
|
55
74
|
|
|
75
|
+
// The bytes of the top-level file named `name` in a gzipped tarball, or null.
|
|
76
|
+
//
|
|
77
|
+
// Read here and not by running `tar`: there is not always one, and where
|
|
78
|
+
// there are two — Git Bash on Windows puts GNU tar ahead of the system's —
|
|
79
|
+
// the one found first reads a path that starts `C:` as a remote host.
|
|
80
|
+
function fileFromTarball(tarball, name) {
|
|
81
|
+
// Bounded: a release binary is tens of megabytes, and the checksum that
|
|
82
|
+
// admitted this tarball came from the host that served it.
|
|
83
|
+
const tar = zlib.gunzipSync(tarball, { maxOutputLength: 512 * 1024 * 1024 });
|
|
84
|
+
for (let at = 0; at + 512 <= tar.length; ) {
|
|
85
|
+
const header = tar.subarray(at, at + 512);
|
|
86
|
+
if (header.every((b) => b === 0)) break;
|
|
87
|
+
const entry = header.subarray(0, 100).toString("utf8").replace(/\0.*$/, "");
|
|
88
|
+
const size = parseInt(header.subarray(124, 136).toString("utf8").trim(), 8) || 0;
|
|
89
|
+
const type = String.fromCharCode(header[156] || 48);
|
|
90
|
+
const body = at + 512;
|
|
91
|
+
// The top-level entry only: a file of the same name further down is not
|
|
92
|
+
// the binary.
|
|
93
|
+
if ((type === "0" || type === "\0") && (entry === name || entry === `./${name}`)) {
|
|
94
|
+
if (body + size > tar.length) return null;
|
|
95
|
+
return tar.subarray(body, body + size);
|
|
96
|
+
}
|
|
97
|
+
at = body + Math.ceil(size / 512) * 512;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
|
|
56
102
|
function checksumOf(buf) {
|
|
57
103
|
return crypto.createHash("sha256").update(buf).digest("hex");
|
|
58
104
|
}
|
|
@@ -60,7 +106,9 @@ function checksumOf(buf) {
|
|
|
60
106
|
function expectedChecksum(sums, filename) {
|
|
61
107
|
const lines = sums.split(/\r?\n/);
|
|
62
108
|
for (const line of lines) {
|
|
63
|
-
|
|
109
|
+
// `sha256sum` marks a file read in binary mode with `*` before its
|
|
110
|
+
// name, and on Windows that is every file.
|
|
111
|
+
const m = line.match(/^([0-9a-fA-F]{64})\s+\*?(\S+)$/);
|
|
64
112
|
if (m && path.basename(m[2]) === filename) return m[1].toLowerCase();
|
|
65
113
|
}
|
|
66
114
|
return null;
|
|
@@ -84,7 +132,8 @@ async function main() {
|
|
|
84
132
|
process.env.MUSHROOMDB_RELEASE_BASE ||
|
|
85
133
|
`https://github.com/${repo}/releases/download/${tag}`;
|
|
86
134
|
const vendor = path.join(__dirname, "vendor");
|
|
87
|
-
const
|
|
135
|
+
const binName = platform === "win32" ? "mushroomdb.exe" : "mushroomdb";
|
|
136
|
+
const dest = path.join(vendor, binName);
|
|
88
137
|
fs.mkdirSync(vendor, { recursive: true });
|
|
89
138
|
|
|
90
139
|
const tarUrl = `${base.replace(/\/$/, "")}/${asset}`;
|
|
@@ -100,20 +149,14 @@ async function main() {
|
|
|
100
149
|
fail(`checksum mismatch for ${asset}: got ${got} want ${want}`);
|
|
101
150
|
}
|
|
102
151
|
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const extracted = spawnSync("tar", ["-xzf", tarPath, "-C", tmp], {
|
|
107
|
-
encoding: "utf8",
|
|
108
|
-
});
|
|
109
|
-
if (extracted.status !== 0) {
|
|
110
|
-
fail(`tar extract failed: ${extracted.stderr || extracted.stdout || extracted.status}`);
|
|
152
|
+
const binary = fileFromTarball(tarball, binName);
|
|
153
|
+
if (!binary) {
|
|
154
|
+
fail(`tarball ${asset} did not contain ./${binName}`);
|
|
111
155
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
fail(`tarball ${asset} did not contain ./mushroomdb`);
|
|
156
|
+
if (binary.length === 0) {
|
|
157
|
+
fail(`tarball ${asset} holds an empty ${binName}`);
|
|
115
158
|
}
|
|
116
|
-
fs.
|
|
159
|
+
fs.writeFileSync(dest, binary);
|
|
117
160
|
fs.chmodSync(dest, 0o755);
|
|
118
161
|
process.stdout.write(`installed ${dest} (${target} ${tag})\n`);
|
|
119
162
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mushroomdb",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Embedded graph database for agents: declare a relationship as a rule, and the edges maintain themselves. This package launches the native binary.",
|
|
5
5
|
"mcpName": "io.github.MatthewSherlin/mushroomdb",
|
|
6
6
|
"homepage": "https://matthewsherlin.github.io/mushroomdb/",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
},
|
|
28
28
|
"os": [
|
|
29
29
|
"darwin",
|
|
30
|
-
"linux"
|
|
30
|
+
"linux",
|
|
31
|
+
"win32"
|
|
31
32
|
],
|
|
32
33
|
"cpu": [
|
|
33
34
|
"x64",
|