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 CHANGED
@@ -1,6 +1,34 @@
1
- # brein
1
+ # brein (npm)
2
2
 
3
- > Stub release reserving the name. Real package coming soon.
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
- A policy-aware MCP server for an org-wide knowledge brain.
6
- See [brein.dev](https://brein.dev) for updates.
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.1",
4
- "description": "Brein a policy-aware MCP server for an org-wide knowledge brain. Stub release reserving the name; real package coming soon.",
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.dev",
6
+ "homepage": "https://brein.sh",
7
7
  "repository": {
8
8
  "type": "git",
9
- "url": "https://github.com/brainincorp/brain-mcp.git"
9
+ "url": "git+https://github.com/brein-sh/brein.git",
10
+ "directory": "npm"
10
11
  },
11
- "keywords": ["mcp", "llm", "knowledge-base", "rag"],
12
- "main": "index.js",
13
- "files": ["index.js", "README.md"]
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
@@ -1,3 +0,0 @@
1
- // brein — stub release. Real package coming soon. See https://brein.dev
2
- console.error("brein: stub release — real package coming soon. https://brein.dev");
3
- process.exit(0);