rlm-harness 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +46 -2
- package/bin/rlmh.exe +33 -0
- package/install.js +83 -0
- package/package.json +30 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rishi Jain
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,47 @@
|
|
|
1
|
-
#
|
|
1
|
+
# rlmh
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A model-agnostic harness for Recursive Language Models. The model never reads a long input directly. It writes Python against the input in a REPL, hands pieces of it to sub-calls, and submits an answer. Source, design and docs: [RishiJain905/rlm-harness](https://github.com/RishiJain905/rlm-harness).
|
|
4
|
+
|
|
5
|
+
This package installs the compiled `rlmh` binary for your platform: macOS arm64 or x64, Windows x64, or Linux x64 (glibc).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
npm i -g rlm-harness
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
bun add -g --trust rlm-harness
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- **Bun needs `--trust`.** Bun skips install scripts unless told otherwise, and on Windows `rlmh` cannot start without its install step. If you already installed without it, run `bun pm -g trust rlm-harness`.
|
|
18
|
+
- **Without Node or Bun**, use the one-line installers on the [releases page](https://github.com/RishiJain905/rlm-harness/releases/latest).
|
|
19
|
+
|
|
20
|
+
## What the install does
|
|
21
|
+
|
|
22
|
+
The install step links the binary from `@rlmh/<platform>-<arch>` into this package, so the `rlmh` command is the compiled binary itself. No Node or Bun process sits in between, so `rlmh` never loads a `.env` or a `bunfig.toml` from the folder you run it in.
|
|
23
|
+
|
|
24
|
+
On first run, `rlmh` asks before it downloads Python 3.12, through the bundled uv, into `~/.rlm-harness/python/` (or `$RLMH_HOME`). Nothing else on the machine changes.
|
|
25
|
+
|
|
26
|
+
## Uninstall
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
npm rm -g rlm-harness
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
or
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
bun rm -g rlm-harness
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This leaves `~/.rlm-harness/` in place, holding Python, the engine, settings and run logs. To remove everything:
|
|
39
|
+
|
|
40
|
+
1. Delete saved keys in `/providers` first. They live in the OS credential store, not in that folder.
|
|
41
|
+
2. Delete the folder.
|
|
42
|
+
|
|
43
|
+
## Notes
|
|
44
|
+
|
|
45
|
+
- Install from a folder you trust. `npm` and `bun` read the current folder's `.npmrc` or `bunfig.toml`, which can point them at another registry.
|
|
46
|
+
- On Windows, close `rlmh` before upgrading. A running `rlmh.exe` cannot be replaced.
|
|
47
|
+
- The binaries are not code signed. macOS ones carry an ad hoc signature only.
|
package/bin/rlmh.exe
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# rlmh: a placeholder (D-130). rlmh's postinstall (install.js) replaces this file with the compiled
|
|
2
|
+
# rlmh binary for this machine. It has no "#!" line on purpose: npm and Bun then link it to run
|
|
3
|
+
# directly, so the binary that replaces it runs with no Node or Bun in between.
|
|
4
|
+
# When the postinstall was skipped (bun add -g without --trust, or --ignore-scripts), a Unix shell
|
|
5
|
+
# or execvp runs this file with /bin/sh, and it starts the binary from the platform package. Windows
|
|
6
|
+
# cannot run it: there the postinstall is required.
|
|
7
|
+
self=$0
|
|
8
|
+
while [ -L "$self" ]; do
|
|
9
|
+
link=$(readlink "$self")
|
|
10
|
+
case $link in
|
|
11
|
+
/*) self=$link ;;
|
|
12
|
+
*) self=$(dirname "$self")/$link ;;
|
|
13
|
+
esac
|
|
14
|
+
done
|
|
15
|
+
pkg=$(cd "$(dirname "$self")/.." && pwd -P)
|
|
16
|
+
case $(uname -s) in
|
|
17
|
+
Darwin) keys="darwin-arm64 darwin-x64" ;;
|
|
18
|
+
Linux) keys="linux-x64" ;;
|
|
19
|
+
*) keys="" ;;
|
|
20
|
+
esac
|
|
21
|
+
# npm nests the platform package inside rlm-harness; Bun and pnpm put it beside rlm-harness
|
|
22
|
+
for dir in "$pkg/node_modules/@rlmh" "$pkg/../@rlmh"; do
|
|
23
|
+
for key in $keys; do
|
|
24
|
+
bin=$dir/$key/bin/rlmh
|
|
25
|
+
if [ -f "$bin" ]; then
|
|
26
|
+
echo 'rlmh: the install step did not run; "bun pm -g trust rlm-harness" makes this permanent.' >&2
|
|
27
|
+
[ -x "$bin" ] || chmod +x "$bin" 2>/dev/null
|
|
28
|
+
exec "$bin" "$@"
|
|
29
|
+
fi
|
|
30
|
+
done
|
|
31
|
+
done
|
|
32
|
+
echo "rlmh: no compiled rlmh for $(uname -sm) next to $pkg. Reinstall without --omit=optional: npm i -g rlm-harness" >&2
|
|
33
|
+
exit 1
|
package/install.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// KV cache: none
|
|
2
|
+
// rlmh's postinstall (D-130). Links this platform's compiled rlmh and uv from the optional dependency
|
|
3
|
+
// @rlmh/<platform>-<arch> over the placeholder bin/rlmh.exe and into bin/, so the `rlmh` command npm
|
|
4
|
+
// or Bun linked at install time is the compiled binary itself, with no Node or Bun in between. It runs
|
|
5
|
+
// once, at install, with the package folder as its working folder; rlmh never runs it again.
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const fs = require("node:fs");
|
|
9
|
+
const path = require("node:path");
|
|
10
|
+
|
|
11
|
+
const PLATFORMS = ["win32-x64", "darwin-arm64", "darwin-x64", "linux-x64"];
|
|
12
|
+
const UNSUPPORTED = "rlmh v0 ships macOS arm64 and x64, Windows x64 and Linux x64 (glibc).";
|
|
13
|
+
|
|
14
|
+
/** True on a musl Linux such as Alpine: its loader sits in /lib. Works under Node and under Bun as node. */
|
|
15
|
+
function isMusl() {
|
|
16
|
+
try {
|
|
17
|
+
return fs.readdirSync("/lib").some((f) => f.startsWith("ld-musl-"));
|
|
18
|
+
} catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** "<platform>-<arch>", or throws the installers' unsupported-platform message. */
|
|
24
|
+
function platformKey(platform, arch, musl) {
|
|
25
|
+
const key = `${platform}-${arch}`;
|
|
26
|
+
if (!PLATFORMS.includes(key) || (platform === "linux" && musl)) {
|
|
27
|
+
throw new Error(`${UNSUPPORTED} This machine is ${platform} ${arch}${platform === "linux" && musl ? " (musl)" : ""}.`);
|
|
28
|
+
}
|
|
29
|
+
return key;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The folder of @rlmh/<key>, or throws when npm or Bun did not install it. */
|
|
33
|
+
function packageDir(key, resolve) {
|
|
34
|
+
const name = `@rlmh/${key}`;
|
|
35
|
+
try {
|
|
36
|
+
return path.dirname(resolve(`${name}/package.json`));
|
|
37
|
+
} catch {
|
|
38
|
+
throw new Error(`${name} is not installed. Reinstall without --omit=optional or --no-optional: npm i -g rlm-harness`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Hard-links src to dest (a copy where a link fails), through a temp name so dest is never half-written. */
|
|
43
|
+
function place(src, dest) {
|
|
44
|
+
if (!fs.existsSync(src)) throw new Error(`${src} is missing from its package`);
|
|
45
|
+
const tmp = `${dest}.${process.pid}.tmp`;
|
|
46
|
+
fs.rmSync(tmp, { force: true });
|
|
47
|
+
try {
|
|
48
|
+
fs.linkSync(src, tmp);
|
|
49
|
+
} catch {
|
|
50
|
+
fs.copyFileSync(src, tmp);
|
|
51
|
+
}
|
|
52
|
+
if (process.platform !== "win32") fs.chmodSync(tmp, 0o755);
|
|
53
|
+
fs.renameSync(tmp, dest);
|
|
54
|
+
fs.rmSync(tmp, { force: true }); // rename leaves tmp when dest was already a link to the same file (a re-run)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Puts rlmh and uv from the platform package into <root>/bin. */
|
|
58
|
+
function install(opts) {
|
|
59
|
+
const key = platformKey(opts.platform, opts.arch, opts.musl);
|
|
60
|
+
const from = path.join(packageDir(key, opts.resolve), "bin");
|
|
61
|
+
const to = path.join(opts.root, "bin");
|
|
62
|
+
const exe = opts.platform === "win32" ? ".exe" : "";
|
|
63
|
+
place(path.join(from, `uv${exe}`), path.join(to, `uv${exe}`));
|
|
64
|
+
place(path.join(from, `rlmh${exe}`), path.join(to, "rlmh.exe")); // the bin target on every OS
|
|
65
|
+
return key;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { PLATFORMS, UNSUPPORTED, platformKey, packageDir, place, install };
|
|
69
|
+
|
|
70
|
+
if (require.main === module) {
|
|
71
|
+
try {
|
|
72
|
+
install({
|
|
73
|
+
platform: process.platform,
|
|
74
|
+
arch: process.arch,
|
|
75
|
+
musl: process.platform === "linux" && isMusl(),
|
|
76
|
+
resolve: require.resolve,
|
|
77
|
+
root: __dirname,
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.error(`rlmh: ${err.message}`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rlm-harness",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "RLM harness: a model-agnostic harness for Recursive Language Models. This package installs the compiled rlmh binary for your platform.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/RishiJain905/rlm-harness",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/RishiJain905/rlm-harness.git"
|
|
10
|
+
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"rlmh": "bin/rlmh.exe"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"postinstall": "node install.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/rlmh.exe",
|
|
19
|
+
"install.js",
|
|
20
|
+
"LICENSE",
|
|
21
|
+
"README.md"
|
|
22
|
+
],
|
|
23
|
+
"optionalDependencies": {
|
|
24
|
+
"@rlmh/darwin-arm64": "0.2.0",
|
|
25
|
+
"@rlmh/darwin-x64": "0.2.0",
|
|
26
|
+
"@rlmh/linux-x64": "0.2.0",
|
|
27
|
+
"@rlmh/win32-x64": "0.2.0"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=18"
|
|
31
|
+
}
|
|
32
|
+
}
|