@onebrain-ai/cli 2.3.3 → 3.0.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.
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @onebrain-ai/cli shim — execs the platform-native onebrain binary that
4
+ * `postinstall.js` extracted into this directory. Uniform across darwin,
5
+ * linux, and win32 so npm consumers get a single `onebrain` command name.
6
+ *
7
+ * Exit code is propagated from the child; if the binary is missing (e.g.
8
+ * postinstall was skipped via ONEBRAIN_CLI_SKIP_POSTINSTALL or failed),
9
+ * we print a helpful pointer and exit 127 (sysexits "command not found").
10
+ */
11
+ 'use strict';
12
+
13
+ const path = require('node:path');
14
+ const fs = require('node:fs');
15
+ const { spawnSync } = require('node:child_process');
16
+
17
+ const isWin = process.platform === 'win32';
18
+ const binaryName = isWin ? 'onebrain.exe' : 'onebrain';
19
+ const binaryPath = path.join(__dirname, binaryName);
20
+
21
+ if (!fs.existsSync(binaryPath)) {
22
+ console.error(`[@onebrain-ai/cli] Binary not found at ${binaryPath}`);
23
+ console.error('Re-run `npm install -g @onebrain-ai/cli` to download it,');
24
+ console.error('or visit https://github.com/onebrain-ai/onebrain-cli/releases/latest');
25
+ process.exit(127);
26
+ }
27
+
28
+ const child = spawnSync(binaryPath, process.argv.slice(2), { stdio: 'inherit' });
29
+ if (child.error) {
30
+ console.error('[@onebrain-ai/cli] Failed to exec:', child.error.message);
31
+ process.exit(1);
32
+ }
33
+ process.exit(child.status ?? 1);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@onebrain-ai/cli",
3
- "version": "2.3.3",
4
- "description": "CLI for OneBrain — personal AI OS for Obsidian with persistent memory, 24+ skills, and Claude Code integration",
3
+ "version": "3.0.0",
4
+ "description": "Local-first Rust CLI for OneBrain — personal AI OS for Obsidian. Downloads the matching platform binary from GitHub Releases on install.",
5
5
  "keywords": [
6
6
  "onebrain",
7
7
  "obsidian",
@@ -9,41 +9,41 @@
9
9
  "cli",
10
10
  "memory",
11
11
  "knowledge-management",
12
- "claude",
12
+ "claude-code",
13
13
  "agent",
14
14
  "pkm",
15
- "productivity",
16
- "vault"
15
+ "rust"
17
16
  ],
18
17
  "homepage": "https://onebrain.run",
18
+ "bugs": "https://github.com/onebrain-ai/onebrain-cli/issues",
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "git+https://github.com/onebrain-ai/onebrain.git"
21
+ "url": "git+https://github.com/onebrain-ai/onebrain-cli.git"
22
22
  },
23
- "bugs": "https://github.com/onebrain-ai/onebrain/issues",
24
- "license": "MIT",
25
- "type": "module",
23
+ "license": "AGPL-3.0-only",
24
+ "author": "OneBrain Contributors",
26
25
  "bin": {
27
- "onebrain": "dist/onebrain"
26
+ "onebrain": "bin/onebrain.js"
28
27
  },
29
- "files": ["dist/onebrain", "dist/postinstall.js"],
28
+ "files": [
29
+ "bin/",
30
+ "postinstall.js",
31
+ "README.md",
32
+ "LICENSE"
33
+ ],
30
34
  "scripts": {
31
- "build": "bun build src/index.ts --outfile dist/onebrain --target bun",
32
- "build:postinstall": "bun build src/scripts/postinstall.ts --outfile dist/postinstall.js --target node",
33
- "postinstall": "node dist/postinstall.js",
34
- "test": "bun test --pass-with-no-tests src/",
35
- "typecheck": "tsc --noEmit"
35
+ "postinstall": "node postinstall.js"
36
36
  },
37
- "dependencies": {
38
- "@clack/prompts": "^0.9",
39
- "commander": "^12",
40
- "picocolors": "^1",
41
- "yaml": "^2"
37
+ "engines": {
38
+ "node": ">=18"
42
39
  },
43
- "devDependencies": {
44
- "@biomejs/biome": "^1.9",
45
- "@types/bun": "latest",
46
- "@types/node": "^20",
47
- "typescript": "^5.7"
48
- }
40
+ "os": [
41
+ "darwin",
42
+ "linux",
43
+ "win32"
44
+ ],
45
+ "cpu": [
46
+ "x64",
47
+ "arm64"
48
+ ]
49
49
  }
package/postinstall.js ADDED
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @onebrain-ai/cli postinstall — downloads the matching platform binary
4
+ * from the OneBrain CLI GitHub Release tagged v${pkg.version}, extracts it
5
+ * to ./bin/, and chmods the result.
6
+ *
7
+ * No npm-side caching of binaries — every install pulls fresh from GitHub
8
+ * (matches the rustup / esbuild / swc pattern). For a faster install path,
9
+ * see the optionalDependencies-per-platform layout we may switch to in
10
+ * v3.0.x.
11
+ *
12
+ * Bypass: set ONEBRAIN_CLI_SKIP_POSTINSTALL=1 to skip the download (useful
13
+ * for CI environments that supply their own binary).
14
+ */
15
+ 'use strict';
16
+
17
+ const fs = require('node:fs');
18
+ const path = require('node:path');
19
+ const https = require('node:https');
20
+ const { execFileSync } = require('node:child_process');
21
+
22
+ if (process.env.ONEBRAIN_CLI_SKIP_POSTINSTALL) {
23
+ console.log('[@onebrain-ai/cli] ONEBRAIN_CLI_SKIP_POSTINSTALL set — skipping binary download.');
24
+ process.exit(0);
25
+ }
26
+
27
+ const pkg = require('./package.json');
28
+ const VERSION = pkg.version;
29
+
30
+ const TRIPLE_MAP = {
31
+ 'darwin-arm64': 'aarch64-apple-darwin',
32
+ 'darwin-x64': 'x86_64-apple-darwin',
33
+ 'linux-arm64': 'aarch64-unknown-linux-gnu',
34
+ 'linux-x64': 'x86_64-unknown-linux-gnu',
35
+ 'win32-arm64': 'aarch64-pc-windows-msvc',
36
+ 'win32-x64': 'x86_64-pc-windows-msvc',
37
+ };
38
+
39
+ const key = `${process.platform}-${process.arch}`;
40
+ const triple = TRIPLE_MAP[key];
41
+ if (!triple) {
42
+ console.error(`[@onebrain-ai/cli] Unsupported platform: ${key}`);
43
+ console.error('Supported: ' + Object.keys(TRIPLE_MAP).join(', '));
44
+ console.error('Manual download: https://github.com/onebrain-ai/onebrain-cli/releases/latest');
45
+ process.exit(1);
46
+ }
47
+
48
+ const isWin = process.platform === 'win32';
49
+ const archiveExt = isWin ? 'zip' : 'tar.gz';
50
+ const archiveName = `onebrain-${triple}.${archiveExt}`;
51
+ const url = `https://github.com/onebrain-ai/onebrain-cli/releases/download/v${VERSION}/${archiveName}`;
52
+
53
+ const root = __dirname;
54
+ const binDir = path.join(root, 'bin');
55
+ fs.mkdirSync(binDir, { recursive: true });
56
+ const archivePath = path.join(root, archiveName);
57
+
58
+ console.log(`[@onebrain-ai/cli] Downloading v${VERSION} for ${triple} ...`);
59
+ console.log(` ${url}`);
60
+
61
+ downloadFile(url, archivePath).then(() => {
62
+ console.log('[@onebrain-ai/cli] Extracting ...');
63
+ // `tar` ships on macOS, Linux, and Windows 10+ (bsdtar). Spawn it via
64
+ // execFileSync — argv form so the path is never shell-interpolated.
65
+ if (isWin) {
66
+ // Windows zip — bsdtar auto-detects format.
67
+ execFileSync('tar', ['-xf', archivePath, '-C', binDir], { stdio: 'inherit' });
68
+ } else {
69
+ execFileSync('tar', ['-xzf', archivePath, '-C', binDir], { stdio: 'inherit' });
70
+ }
71
+ fs.unlinkSync(archivePath);
72
+
73
+ const binaryName = isWin ? 'onebrain.exe' : 'onebrain';
74
+ const binaryPath = path.join(binDir, binaryName);
75
+ if (!fs.existsSync(binaryPath)) {
76
+ console.error(`[@onebrain-ai/cli] Extraction succeeded but ${binaryName} not found at ${binDir}`);
77
+ process.exit(1);
78
+ }
79
+ if (!isWin) {
80
+ fs.chmodSync(binaryPath, 0o755);
81
+ }
82
+ console.log(`[@onebrain-ai/cli] Installed onebrain v${VERSION} → ${binaryPath}`);
83
+ }).catch((err) => {
84
+ console.error('[@onebrain-ai/cli] Install failed:', err.message);
85
+ console.error('Manual download: https://github.com/onebrain-ai/onebrain-cli/releases/latest');
86
+ process.exit(1);
87
+ });
88
+
89
+ function downloadFile(url, dest, redirects = 5) {
90
+ return new Promise((resolve, reject) => {
91
+ https.get(url, { headers: { 'User-Agent': `onebrain-cli-postinstall/${VERSION}` } }, (res) => {
92
+ // GitHub Release downloads always redirect to S3 — follow.
93
+ if ([301, 302, 303, 307, 308].includes(res.statusCode)) {
94
+ if (redirects <= 0) {
95
+ reject(new Error('Too many redirects'));
96
+ return;
97
+ }
98
+ res.resume();
99
+ downloadFile(res.headers.location, dest, redirects - 1).then(resolve, reject);
100
+ return;
101
+ }
102
+ if (res.statusCode !== 200) {
103
+ reject(new Error(`HTTP ${res.statusCode} fetching ${url}`));
104
+ return;
105
+ }
106
+ const file = fs.createWriteStream(dest);
107
+ res.pipe(file);
108
+ file.on('finish', () => file.close(() => resolve()));
109
+ file.on('error', reject);
110
+ }).on('error', reject);
111
+ });
112
+ }