elendirna 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 +46 -0
- package/bin/elendirna.js +92 -0
- package/binaries/darwin-arm64/elf +0 -0
- package/binaries/darwin-x64/elf +0 -0
- package/binaries/linux-arm64/elf +0 -0
- package/binaries/linux-x64/elf +0 -0
- package/binaries/win32-arm64/elf.exe +0 -0
- package/binaries/win32-x64/elf.exe +0 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# elendirna
|
|
2
|
+
|
|
3
|
+
AI-friendly knowledge vault — `elf` CLI + MCP server, distributed as a prebuilt binary via npm (no Rust toolchain required).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
# one-off, no install
|
|
9
|
+
npx -y elendirna --help
|
|
10
|
+
|
|
11
|
+
# or install globally (provides both `elendirna` and `eln` commands)
|
|
12
|
+
npm i -g elendirna
|
|
13
|
+
elendirna --help
|
|
14
|
+
eln --help
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The npm package bundles prebuilt `elf` binaries for all supported platforms and a
|
|
18
|
+
thin Node launcher that selects the right one at run time. No `postinstall` script,
|
|
19
|
+
and no network access at install or run time.
|
|
20
|
+
|
|
21
|
+
**Supported platforms:** linux / macOS / Windows × x64 / arm64. Linux builds target
|
|
22
|
+
glibc ≥ 2.35 (Ubuntu 22.04 baseline); musl/Alpine is not yet shipped — use
|
|
23
|
+
`cargo install eln-cli` there.
|
|
24
|
+
|
|
25
|
+
## MCP server
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
# print a Claude Desktop / .claude/mcp.json snippet for stdio transport
|
|
29
|
+
elendirna serve
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
When launched through this npm wrapper, the snippet's `command` is the stable
|
|
33
|
+
`elendirna` (on PATH after a global install) rather than a `node_modules` path.
|
|
34
|
+
For an npx-only setup, use:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{ "mcpServers": { "elendirna": {
|
|
38
|
+
"command": "npx",
|
|
39
|
+
"args": ["-y", "elendirna", "serve", "--mcp", "--transport", "stdio", "--vault", "/path/to/vault"]
|
|
40
|
+
} } }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Source
|
|
44
|
+
|
|
45
|
+
Rust source, issues, and docs: <https://github.com/elen-labs/elendirna>.
|
|
46
|
+
Also published to crates.io as `eln-cli` (`cargo install eln-cli`).
|
package/bin/elendirna.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// elendirna npm launcher — 패키지에 동봉된(binaries/<os>-<cpu>/) prebuilt `elf` 바이너리를
|
|
3
|
+
// 런타임에 선택해 spawn한다. (N0097 v0.8 cut, 매커니즘 = 단일 패키지 + 전 바이너리 동봉:
|
|
4
|
+
// postinstall 없음·설치 시 네트워크 없음·플랫폼 패키지 없음 → npm 스팸 탐지 회피.)
|
|
5
|
+
//
|
|
6
|
+
// 이 shim은 일회성 CLI(`elf query …`)와 장수명 stdio MCP 서버(`elf serve --mcp`) 둘 다를
|
|
7
|
+
// 기동하므로 spawnSync가 아닌 async spawn을 쓴다 — 부모가 받은 SIGINT/SIGTERM을 자식에
|
|
8
|
+
// 전달해야 서버가 고아 프로세스로 남지 않는다 (서버는 stdin EOF 또는 시그널로 종료).
|
|
9
|
+
"use strict";
|
|
10
|
+
|
|
11
|
+
const { spawn } = require("node:child_process");
|
|
12
|
+
const path = require("node:path");
|
|
13
|
+
const fs = require("node:fs");
|
|
14
|
+
|
|
15
|
+
function binaryPath() {
|
|
16
|
+
const os = process.platform; // linux | darwin | win32
|
|
17
|
+
const cpu = process.arch; // x64 | arm64
|
|
18
|
+
const exe = os === "win32" ? "elf.exe" : "elf";
|
|
19
|
+
// 런처는 bin/ 에, 바이너리는 자매 디렉터리 binaries/<os>-<cpu>/ 에 동봉된다.
|
|
20
|
+
const p = path.join(__dirname, "..", "binaries", `${os}-${cpu}`, exe);
|
|
21
|
+
return fs.existsSync(p) ? p : null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const bin = binaryPath();
|
|
25
|
+
if (!bin) {
|
|
26
|
+
const os = process.platform;
|
|
27
|
+
const cpu = process.arch;
|
|
28
|
+
process.stderr.write(
|
|
29
|
+
`elendirna: no prebuilt binary bundled for ${os}-${cpu}.\n` +
|
|
30
|
+
`Supported platforms: linux / darwin / win32 × x64 / arm64.\n` +
|
|
31
|
+
`If your platform is in that set, the install may be corrupted — reinstall (npm i elendirna).\n` +
|
|
32
|
+
`Otherwise build from source: cargo install eln-cli\n`
|
|
33
|
+
);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// `serve`가 출력하는 MCP config 스니펫이 node_modules 내부 절대경로 대신 안정 PATH 명령을
|
|
38
|
+
// emit하도록, 사용자가 호출한 bin 이름(elendirna|eln)을 env로 넘긴다 (serve.rs resolve_elf_bin).
|
|
39
|
+
const invoked = path
|
|
40
|
+
.basename(process.argv[1] || "elendirna")
|
|
41
|
+
.replace(/\.js$/, "");
|
|
42
|
+
const launcherCmd = invoked === "eln" ? "eln" : "elendirna";
|
|
43
|
+
|
|
44
|
+
const child = spawn(bin, process.argv.slice(2), {
|
|
45
|
+
stdio: "inherit",
|
|
46
|
+
env: { ...process.env, ELN_LAUNCHER_CMD: launcherCmd },
|
|
47
|
+
windowsHide: false,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// 부모가 받은 종료 시그널을 장수명 서버 자식에게 전달 (Windows: SIGBREAK).
|
|
51
|
+
for (const sig of ["SIGINT", "SIGTERM", "SIGHUP", "SIGBREAK"]) {
|
|
52
|
+
process.on(sig, () => {
|
|
53
|
+
if (!child.killed) {
|
|
54
|
+
try {
|
|
55
|
+
child.kill(sig);
|
|
56
|
+
} catch {
|
|
57
|
+
/* 자식이 이미 종료 */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 부모가 다른 경로로 죽어도 자식을 고아로 남기지 않는다.
|
|
64
|
+
process.on("exit", () => {
|
|
65
|
+
if (!child.killed) {
|
|
66
|
+
try {
|
|
67
|
+
child.kill();
|
|
68
|
+
} catch {
|
|
69
|
+
/* noop */
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
child.on("error", (err) => {
|
|
75
|
+
process.stderr.write(`elendirna: failed to launch binary: ${err.message}\n`);
|
|
76
|
+
process.exit(126);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// exit code와 시그널을 정확히 전파 (`elf --version`, 일회성 CLI, 서버 종료 모두 올바른 상태).
|
|
80
|
+
child.on("close", (code, signal) => {
|
|
81
|
+
if (signal) {
|
|
82
|
+
// POSIX는 부모 종료 상태에 시그널을 반영(re-raise). Windows는 POSIX 시그널 re-raise를
|
|
83
|
+
// 제대로 지원하지 않으므로 non-zero exit code로 대체한다.
|
|
84
|
+
if (process.platform === "win32") {
|
|
85
|
+
process.exit(1);
|
|
86
|
+
} else {
|
|
87
|
+
process.kill(process.pid, signal);
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
process.exit(code === null ? 1 : code);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "elendirna",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "elendirna — AI-friendly knowledge vault CLI & MCP server (elf binary, npm-wrapped)",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"elendirna",
|
|
7
|
+
"elf",
|
|
8
|
+
"mcp",
|
|
9
|
+
"vault",
|
|
10
|
+
"knowledge-base",
|
|
11
|
+
"cli"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/elen-labs/elendirna",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/elen-labs/elendirna.git"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"bin": {
|
|
20
|
+
"elendirna": "bin/elendirna.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"bin/",
|
|
24
|
+
"binaries/",
|
|
25
|
+
"README.md"
|
|
26
|
+
],
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
}
|
|
30
|
+
}
|