@luchenglong/cli-bridge 0.2.5 → 0.2.7
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/CHANGELOG.md +58 -0
- package/dynamic/codebuddy.host.js +466 -143
- package/dynamic/mimo.host.js +514 -616
- package/dynamic/opencode.host.js +584 -628
- package/mcp/cli-bridge-mcp.mjs +2 -1
- package/package.json +3 -1
- package/providers/codebuddy-catalog.mjs +232 -65
- package/providers/codebuddy-consts.mjs +72 -0
- package/providers/codebuddy-models-tool.mjs +106 -0
- package/providers/codebuddy-schemas.mjs +46 -0
- package/providers/codebuddy.mjs +61 -124
- package/providers/mimo-pure.mjs +111 -0
- package/providers/mimo.mjs +517 -618
- package/providers/opencode-exe.mjs +63 -0
- package/providers/opencode.mjs +587 -629
- package/scripts/build.mjs +262 -253
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// providers/opencode-exe.mjs — opencode 可执行探测与模型列表解析(无宿主依赖)。
|
|
2
|
+
//
|
|
3
|
+
// 从 providers/opencode.mjs 拆出,让两个文件都留在 600 行红线内(规则 §26)。
|
|
4
|
+
// build 会把 providers/opencode-*.mjs 全部内联进 dynamic 沙箱同一作用域。
|
|
5
|
+
// ⚠️ 注释里绝不写出口令标记字面量(build 全局替换会把注释劈开)。
|
|
6
|
+
|
|
7
|
+
import { clampInt } from '../core/bridge-kit.mjs'
|
|
8
|
+
|
|
9
|
+
// Node 内建守卫(沙箱可能没有 fs/path;读不到返回 null,调用方退到保守值)。
|
|
10
|
+
function schedBuiltin(name) {
|
|
11
|
+
try {
|
|
12
|
+
const proc = globalThis.process
|
|
13
|
+
return (proc && typeof proc.getBuiltinModule === 'function') ? proc.getBuiltinModule(name) : null
|
|
14
|
+
} catch (e) { return null }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 二进制名是 opencode-cli.exe(V2 桌面版),不做 opencode.exe 兜底(V1/V2 不能并存)。
|
|
18
|
+
export const EXE_BASENAMES = ['opencode-cli', 'opencode']
|
|
19
|
+
export const DESKTOP_CLI_REL = ['ai.opencode.desktop', 'cli']
|
|
20
|
+
// 桌面版目录形如 ...\ai.opencode.desktop\cli\<ver>-<arch>\opencode-cli.exe。
|
|
21
|
+
// 沙箱内可能没有 fs —— 全部读取走 typeof 守卫,读不到就返回空数组(退回 PATH 查找)。
|
|
22
|
+
|
|
23
|
+
export function candidateExePaths(env) {
|
|
24
|
+
const e = env || {}
|
|
25
|
+
const out = []
|
|
26
|
+
const fs = schedBuiltin('node:fs')
|
|
27
|
+
const path = schedBuiltin('node:path')
|
|
28
|
+
if (!fs || typeof fs.readdirSync !== 'function' || !path || typeof path.join !== 'function') return out
|
|
29
|
+
const roots = []
|
|
30
|
+
for (const k of ['APPDATA', 'LOCALAPPDATA', 'PROGRAMFILES']) if (e[k]) roots.push(String(e[k]))
|
|
31
|
+
const home = e.HOME || e.USERPROFILE
|
|
32
|
+
if (home && !roots.length) roots.push(String(home))
|
|
33
|
+
for (const root of roots) {
|
|
34
|
+
const cliDir = path.join.apply(path, [root].concat(DESKTOP_CLI_REL))
|
|
35
|
+
let versions = []
|
|
36
|
+
try { versions = fs.readdirSync(cliDir, { withFileTypes: true }) } catch (err) { continue }
|
|
37
|
+
// 版本目录按 semver 降序(新版本优先);解析失败的排末尾。
|
|
38
|
+
const dirs = versions.filter((d) => d && d.isDirectory && d.isDirectory()).map((d) => d.name)
|
|
39
|
+
const key = (n) => {
|
|
40
|
+
const m = String(n).match(/(\d+)\.(\d+)\.(\d+)/)
|
|
41
|
+
return m ? [Number(m[1]), Number(m[2]), Number(m[3])] : [-1, -1, -1]
|
|
42
|
+
}
|
|
43
|
+
dirs.sort((a, b) => {
|
|
44
|
+
const ka = key(a), kb = key(b)
|
|
45
|
+
for (let i = 0; i < 3; i++) if (ka[i] !== kb[i]) return kb[i] - ka[i]
|
|
46
|
+
return 0
|
|
47
|
+
})
|
|
48
|
+
for (const d of dirs) {
|
|
49
|
+
for (const base of EXE_BASENAMES) {
|
|
50
|
+
const exe = path.join(cliDir, d, base + (String(e.OS || '').toLowerCase().startsWith('win') || e.APPDATA ? '.exe' : ''))
|
|
51
|
+
try { if (fs.existsSync(exe)) out.push(exe) } catch (err) { }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return out
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* 解析本次调用使用的 exe 前缀(数组或字符串)。
|
|
60
|
+
* 优先级:binPath 设置 > env OPENCODE_BIN/OPENCODE_CLI > 桌面版探测 > PATH 名字。
|
|
61
|
+
* @param {object} env
|
|
62
|
+
* @param {string} [binPath] 设置面板里的显式路径(可空)
|
|
63
|
+
*/
|