@taotao7/braincode 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/LICENSE +21 -0
- package/README.md +26 -0
- package/bin/braincode.js +21 -0
- package/install.js +152 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 taotao7
|
|
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
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @taotao7/braincode
|
|
2
|
+
|
|
3
|
+
Coding-first AI agent with user-selectable Brain Model that routes sub-tasks to different LLMs.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i -g @taotao7/braincode
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
A `postinstall` step downloads the platform-specific binary from the matching GitHub release. Supported platforms: macOS arm64/x64, Linux x64/arm64.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
braincode # interactive TUI
|
|
17
|
+
braincode config # open browser configuration
|
|
18
|
+
braincode run "..." # one-shot task
|
|
19
|
+
braincode help
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Sources
|
|
23
|
+
|
|
24
|
+
- Repository: <https://github.com/taotao7/braincode>
|
|
25
|
+
- Issues: <https://github.com/taotao7/braincode/issues>
|
|
26
|
+
- Releases: <https://github.com/taotao7/braincode/releases>
|
package/bin/braincode.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict"
|
|
3
|
+
|
|
4
|
+
const path = require("node:path")
|
|
5
|
+
const fs = require("node:fs")
|
|
6
|
+
const { spawnSync } = require("node:child_process")
|
|
7
|
+
|
|
8
|
+
const bin = path.join(__dirname, "braincode-bin")
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(bin)) {
|
|
11
|
+
console.error("[braincode] binary not found at", bin)
|
|
12
|
+
console.error("[braincode] try reinstalling: npm i -g @taotao7/braincode")
|
|
13
|
+
process.exit(1)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" })
|
|
17
|
+
if (result.error) {
|
|
18
|
+
console.error("[braincode] failed to launch binary:", result.error.message)
|
|
19
|
+
process.exit(1)
|
|
20
|
+
}
|
|
21
|
+
process.exit(result.status ?? 1)
|
package/install.js
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict"
|
|
3
|
+
|
|
4
|
+
const fs = require("node:fs")
|
|
5
|
+
const os = require("node:os")
|
|
6
|
+
const path = require("node:path")
|
|
7
|
+
const https = require("node:https")
|
|
8
|
+
const crypto = require("node:crypto")
|
|
9
|
+
const zlib = require("node:zlib")
|
|
10
|
+
const { spawnSync } = require("node:child_process")
|
|
11
|
+
|
|
12
|
+
const REPO = "taotao7/braincode"
|
|
13
|
+
const BIN_NAME = "braincode-bin"
|
|
14
|
+
|
|
15
|
+
function detectTarget() {
|
|
16
|
+
const platform = os.platform()
|
|
17
|
+
const arch = os.arch()
|
|
18
|
+
|
|
19
|
+
let target
|
|
20
|
+
if (platform === "darwin" && arch === "arm64") target = "darwin-arm64"
|
|
21
|
+
else if (platform === "darwin" && arch === "x64") target = "darwin-x64"
|
|
22
|
+
else if (platform === "linux" && arch === "x64") target = "linux-x64"
|
|
23
|
+
else if (platform === "linux" && arch === "arm64") target = "linux-arm64"
|
|
24
|
+
|
|
25
|
+
if (!target) {
|
|
26
|
+
const supported = "darwin-arm64, darwin-x64, linux-x64, linux-arm64"
|
|
27
|
+
throw new Error(`Unsupported platform ${platform}/${arch}. Supported: ${supported}.`)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return target
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function get(url) {
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
https
|
|
36
|
+
.get(url, { headers: { "user-agent": "braincode-npm-installer" } }, (res) => {
|
|
37
|
+
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
38
|
+
res.resume()
|
|
39
|
+
resolve(get(res.headers.location))
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if (res.statusCode !== 200) {
|
|
43
|
+
reject(new Error(`HTTP ${res.statusCode} for ${url}`))
|
|
44
|
+
res.resume()
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
resolve(res)
|
|
48
|
+
})
|
|
49
|
+
.on("error", reject)
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function fetchBuffer(url) {
|
|
54
|
+
const res = await get(url)
|
|
55
|
+
const chunks = []
|
|
56
|
+
for await (const chunk of res) chunks.push(chunk)
|
|
57
|
+
return Buffer.concat(chunks)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function sha256(buf) {
|
|
61
|
+
return crypto.createHash("sha256").update(buf).digest("hex")
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function parseShaSums(text, name) {
|
|
65
|
+
for (const line of text.split(/\r?\n/)) {
|
|
66
|
+
const trimmed = line.trim()
|
|
67
|
+
if (!trimmed) continue
|
|
68
|
+
const [hash, file] = trimmed.split(/\s+/)
|
|
69
|
+
if (file === name || file === `*${name}`) return hash
|
|
70
|
+
}
|
|
71
|
+
return null
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function untarGz(buffer, destDir) {
|
|
75
|
+
const data = zlib.gunzipSync(buffer)
|
|
76
|
+
let offset = 0
|
|
77
|
+
let extracted = null
|
|
78
|
+
|
|
79
|
+
while (offset + 512 <= data.length) {
|
|
80
|
+
const header = data.subarray(offset, offset + 512)
|
|
81
|
+
const nameRaw = header.subarray(0, 100).toString("utf8")
|
|
82
|
+
const name = nameRaw.replace(/\0.*$/, "")
|
|
83
|
+
if (!name) break
|
|
84
|
+
|
|
85
|
+
const sizeOctal = header.subarray(124, 124 + 12).toString("utf8").replace(/\0/g, "").trim()
|
|
86
|
+
const size = parseInt(sizeOctal, 8) || 0
|
|
87
|
+
const typeflag = header.subarray(156, 157).toString("utf8")
|
|
88
|
+
|
|
89
|
+
offset += 512
|
|
90
|
+
|
|
91
|
+
if (typeflag === "" || typeflag === "0") {
|
|
92
|
+
const body = data.subarray(offset, offset + size)
|
|
93
|
+
const target = path.join(destDir, path.basename(name))
|
|
94
|
+
fs.writeFileSync(target, body)
|
|
95
|
+
fs.chmodSync(target, 0o755)
|
|
96
|
+
extracted = target
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
offset += Math.ceil(size / 512) * 512
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!extracted) throw new Error("Tarball contained no files")
|
|
103
|
+
return extracted
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
async function main() {
|
|
107
|
+
if (process.env.BRAINCODE_SKIP_DOWNLOAD === "1") {
|
|
108
|
+
console.log("[braincode] BRAINCODE_SKIP_DOWNLOAD=1, skipping binary download.")
|
|
109
|
+
return
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "package.json"), "utf8"))
|
|
113
|
+
const version = pkg.version
|
|
114
|
+
const target = detectTarget()
|
|
115
|
+
const binDir = path.join(__dirname, "bin")
|
|
116
|
+
fs.mkdirSync(binDir, { recursive: true })
|
|
117
|
+
|
|
118
|
+
const tarballName = `braincode-${target}.tar.gz`
|
|
119
|
+
const releaseBase = `https://github.com/${REPO}/releases/download/v${version}`
|
|
120
|
+
const tarballUrl = `${releaseBase}/${tarballName}`
|
|
121
|
+
const shasumsUrl = `${releaseBase}/SHA256SUMS`
|
|
122
|
+
|
|
123
|
+
console.log(`[braincode] downloading ${tarballName} from release v${version}…`)
|
|
124
|
+
|
|
125
|
+
const [tarball, shasumsBuf] = await Promise.all([fetchBuffer(tarballUrl), fetchBuffer(shasumsUrl)])
|
|
126
|
+
const expected = parseShaSums(shasumsBuf.toString("utf8"), tarballName)
|
|
127
|
+
if (!expected) throw new Error(`SHA256SUMS missing entry for ${tarballName}`)
|
|
128
|
+
const actual = sha256(tarball)
|
|
129
|
+
if (actual !== expected) throw new Error(`sha256 mismatch for ${tarballName}: expected ${expected}, got ${actual}`)
|
|
130
|
+
|
|
131
|
+
const extracted = untarGz(tarball, binDir)
|
|
132
|
+
const finalPath = path.join(binDir, BIN_NAME)
|
|
133
|
+
if (extracted !== finalPath) {
|
|
134
|
+
fs.renameSync(extracted, finalPath)
|
|
135
|
+
}
|
|
136
|
+
fs.chmodSync(finalPath, 0o755)
|
|
137
|
+
|
|
138
|
+
const result = spawnSync(finalPath, ["help"], { stdio: "ignore" })
|
|
139
|
+
if (result.status !== 0) {
|
|
140
|
+
console.warn("[braincode] post-install smoke test exited with non-zero status; the binary may still work.")
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log(`[braincode] installed ${target} binary -> ${finalPath}`)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
main().catch((err) => {
|
|
147
|
+
console.error("[braincode] install failed:", err.message || err)
|
|
148
|
+
console.error("[braincode] you can manually download the binary from:")
|
|
149
|
+
console.error(` https://github.com/${REPO}/releases`)
|
|
150
|
+
console.error("[braincode] then place it at:", path.join(__dirname, "bin", BIN_NAME))
|
|
151
|
+
process.exit(1)
|
|
152
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@taotao7/braincode",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Coding-first AI agent with user-selectable Brain Model that routes sub-tasks to different LLMs",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "taotao7",
|
|
7
|
+
"homepage": "https://github.com/taotao7/braincode",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/taotao7/braincode.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/taotao7/braincode/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"ai",
|
|
17
|
+
"agent",
|
|
18
|
+
"cli",
|
|
19
|
+
"llm",
|
|
20
|
+
"tui"
|
|
21
|
+
],
|
|
22
|
+
"bin": {
|
|
23
|
+
"braincode": "bin/braincode.js"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"bin/",
|
|
27
|
+
"install.js",
|
|
28
|
+
"README.md",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"postinstall": "node install.js"
|
|
33
|
+
},
|
|
34
|
+
"engines": {
|
|
35
|
+
"node": ">=18"
|
|
36
|
+
},
|
|
37
|
+
"os": [
|
|
38
|
+
"darwin",
|
|
39
|
+
"linux"
|
|
40
|
+
],
|
|
41
|
+
"cpu": [
|
|
42
|
+
"x64",
|
|
43
|
+
"arm64"
|
|
44
|
+
]
|
|
45
|
+
}
|