brein 0.0.1 → 0.1.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 +32 -4
- package/bin/brein.js +149 -0
- package/package.json +22 -7
- package/index.js +0 -3
package/README.md
CHANGED
|
@@ -1,6 +1,34 @@
|
|
|
1
|
-
# brein
|
|
1
|
+
# brein (npm)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Thin Node wrapper for [brein](https://github.com/brein-sh/brein) — the MCP server for a company memory that lives in git.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
## Quickstart
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx brein init
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Verifies Python 3.11+ and [`uv`](https://docs.astral.sh/uv/), installs the brein Python package via `uv tool install`, then runs the setup wizard.
|
|
12
|
+
|
|
13
|
+
After install, the wrapper forwards subcommands to the real CLI:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npx brein doctor
|
|
17
|
+
npx brein mcp claude
|
|
18
|
+
npx brein setup mcp
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or use the installed binary directly (`brein`, `brain-mcp`, `brain-eval`).
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
- Node 18+
|
|
26
|
+
- Python 3.11+
|
|
27
|
+
- [`uv`](https://docs.astral.sh/uv/) (single static binary, no Python prereq for install)
|
|
28
|
+
- `git`
|
|
29
|
+
|
|
30
|
+
The wrapper prints actionable install hints if anything is missing.
|
|
31
|
+
|
|
32
|
+
## License
|
|
33
|
+
|
|
34
|
+
MIT.
|
package/bin/brein.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Thin Node shim. Verifies python3 + uv, installs the brein Python package
|
|
3
|
+
// from git, then execs the real `brein` CLI. No deps.
|
|
4
|
+
|
|
5
|
+
const { spawnSync, spawn } = require("node:child_process");
|
|
6
|
+
const { platform } = require("node:os");
|
|
7
|
+
|
|
8
|
+
const REPO_URL = "git+https://github.com/brein-sh/brein.git";
|
|
9
|
+
const MIN_PY = [3, 11];
|
|
10
|
+
|
|
11
|
+
const C = {
|
|
12
|
+
dim: (s) => `\x1b[2m${s}\x1b[0m`,
|
|
13
|
+
red: (s) => `\x1b[31m${s}\x1b[0m`,
|
|
14
|
+
yellow: (s) => `\x1b[33m${s}\x1b[0m`,
|
|
15
|
+
green: (s) => `\x1b[32m${s}\x1b[0m`,
|
|
16
|
+
bold: (s) => `\x1b[1m${s}\x1b[0m`,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function which(cmd) {
|
|
20
|
+
const r = spawnSync(platform() === "win32" ? "where" : "which", [cmd], {
|
|
21
|
+
encoding: "utf8",
|
|
22
|
+
});
|
|
23
|
+
return r.status === 0 ? r.stdout.trim().split(/\r?\n/)[0] : null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function pythonVersion(bin) {
|
|
27
|
+
const r = spawnSync(bin, ["-c", "import sys; print(sys.version_info[0], sys.version_info[1])"], { encoding: "utf8" });
|
|
28
|
+
if (r.status !== 0) return null;
|
|
29
|
+
const [maj, min] = r.stdout.trim().split(/\s+/).map(Number);
|
|
30
|
+
return [maj, min];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function findPython() {
|
|
34
|
+
for (const cmd of ["python3.13", "python3.12", "python3.11", "python3", "python"]) {
|
|
35
|
+
if (!which(cmd)) continue;
|
|
36
|
+
const v = pythonVersion(cmd);
|
|
37
|
+
if (!v) continue;
|
|
38
|
+
if (v[0] > MIN_PY[0] || (v[0] === MIN_PY[0] && v[1] >= MIN_PY[1])) {
|
|
39
|
+
return { bin: cmd, version: v };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function pythonInstallHint() {
|
|
46
|
+
const p = platform();
|
|
47
|
+
if (p === "darwin") return "brew install python@3.12 # or visit https://www.python.org/downloads/";
|
|
48
|
+
if (p === "linux") return "sudo apt install python3.12 # or your distro's equivalent";
|
|
49
|
+
if (p === "win32") return "winget install Python.Python.3.12 # or https://www.python.org/downloads/";
|
|
50
|
+
return "Install Python 3.11+ from https://www.python.org/downloads/";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function uvInstallHint() {
|
|
54
|
+
if (platform() === "win32") return "powershell -c \"irm https://astral.sh/uv/install.ps1 | iex\"";
|
|
55
|
+
return "curl -LsSf https://astral.sh/uv/install.sh | sh";
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function run(cmd, args, opts = {}) {
|
|
59
|
+
const r = spawnSync(cmd, args, { stdio: "inherit", ...opts });
|
|
60
|
+
return r.status === 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function execReplace(cmd, args) {
|
|
64
|
+
// No exec() in Node; spawn with inherited stdio and forward the exit code.
|
|
65
|
+
const child = spawn(cmd, args, { stdio: "inherit" });
|
|
66
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function preflight() {
|
|
70
|
+
const py = findPython();
|
|
71
|
+
if (!py) {
|
|
72
|
+
console.error(C.red("✗") + " Python " + MIN_PY.join(".") + "+ not found.");
|
|
73
|
+
console.error(" → " + pythonInstallHint());
|
|
74
|
+
process.exit(2);
|
|
75
|
+
}
|
|
76
|
+
console.log(C.green("✓") + ` python ${py.version.join(".")} (${py.bin})`);
|
|
77
|
+
|
|
78
|
+
const uv = which("uv");
|
|
79
|
+
if (!uv) {
|
|
80
|
+
console.error(C.red("✗") + " uv not found.");
|
|
81
|
+
console.error(" → " + uvInstallHint());
|
|
82
|
+
console.error(" (uv is a single static binary, no Python prereq.)");
|
|
83
|
+
process.exit(2);
|
|
84
|
+
}
|
|
85
|
+
console.log(C.green("✓") + ` uv (${uv})`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function installBrein(branch) {
|
|
89
|
+
const url = branch ? `${REPO_URL}@${branch}` : REPO_URL;
|
|
90
|
+
console.log(C.bold("\nInstalling brein from") + " " + C.dim(url));
|
|
91
|
+
const ok = run("uv", ["tool", "install", "--force", url]);
|
|
92
|
+
if (!ok) {
|
|
93
|
+
console.error(C.red("\nuv tool install failed."));
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function ensureOnPath() {
|
|
99
|
+
if (!which("brein")) {
|
|
100
|
+
console.error(C.yellow("!") + " `brein` not on PATH after install.");
|
|
101
|
+
console.error(" → run: " + C.bold("uv tool update-shell") + " (then restart your shell)");
|
|
102
|
+
console.error(" or add ~/.local/bin to PATH manually.");
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function usage() {
|
|
108
|
+
console.log(`brein — npm wrapper for the brein MCP server
|
|
109
|
+
|
|
110
|
+
Usage:
|
|
111
|
+
npx brein init [--branch <name>] Install Python package + run setup wizard
|
|
112
|
+
npx brein <subcommand> [args...] Forward to the installed brein CLI
|
|
113
|
+
(setup | doctor | mcp | config)
|
|
114
|
+
|
|
115
|
+
Examples:
|
|
116
|
+
npx brein init
|
|
117
|
+
npx brein doctor
|
|
118
|
+
npx brein mcp claude
|
|
119
|
+
`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function main() {
|
|
123
|
+
const [, , cmd, ...rest] = process.argv;
|
|
124
|
+
|
|
125
|
+
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
126
|
+
usage();
|
|
127
|
+
process.exit(cmd ? 0 : 1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (cmd === "init") {
|
|
131
|
+
const branchIdx = rest.indexOf("--branch");
|
|
132
|
+
const branch = branchIdx >= 0 ? rest[branchIdx + 1] : null;
|
|
133
|
+
preflight();
|
|
134
|
+
installBrein(branch);
|
|
135
|
+
ensureOnPath();
|
|
136
|
+
console.log(C.bold("\nRunning ") + C.bold("brein setup") + C.bold("...\n"));
|
|
137
|
+
execReplace("brein", ["setup"]);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Forward anything else to the installed CLI.
|
|
142
|
+
if (!which("brein")) {
|
|
143
|
+
console.error(C.red("✗") + " brein is not installed. Run: npx brein init");
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
execReplace("brein", [cmd, ...rest]);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,14 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brein",
|
|
3
|
-
"version": "0.0
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "npx wrapper for brein — installs the Python MCP server and runs the setup wizard.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"homepage": "https://brein.
|
|
6
|
+
"homepage": "https://brein.sh",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/
|
|
9
|
+
"url": "git+https://github.com/brein-sh/brein.git",
|
|
10
|
+
"directory": "npm"
|
|
10
11
|
},
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
"bin": {
|
|
13
|
+
"brein": "bin/brein.js"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"bin/",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=18"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"llm",
|
|
25
|
+
"knowledge-base",
|
|
26
|
+
"rag",
|
|
27
|
+
"brain"
|
|
28
|
+
]
|
|
14
29
|
}
|
package/index.js
DELETED