@luchenglong/cli-bridge 0.0.0-stage → 0.2.3
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 +191 -0
- package/LICENSE +21 -0
- package/MCP-POLICY.md +53 -0
- package/PROVIDER-CONTRACT.md +235 -0
- package/README.en.md +98 -0
- package/README.md +151 -2
- package/assets/indicator-states.svg +62 -0
- package/bin/agy-quota.mjs +223 -0
- package/core/bridge-kit.mjs +549 -0
- package/core/scheduling.mjs +149 -0
- package/docs/ARCHITECTURE.md +117 -0
- package/docs/FALLBACK-AND-INDICATOR.md +93 -0
- package/docs/HANDOVER.md +226 -0
- package/docs/INSTALL.md +118 -0
- package/docs/MCP-POLICY.zh.md +49 -0
- package/docs/MIGRATION.md +43 -0
- package/docs/RELEASE-SOP.md +80 -0
- package/docs/history/agy/CHANGELOG.md +326 -0
- package/docs/history/codebuddy/CHANGELOG.md +668 -0
- package/docs/history/mimo/CHANGELOG.md +346 -0
- package/dynamic/agy.host.js +1237 -0
- package/dynamic/agy.host.template.mjs +140 -0
- package/dynamic/codebuddy.host.js +1787 -0
- package/dynamic/codebuddy.host.template.mjs +162 -0
- package/dynamic/mimo.host.js +1732 -0
- package/dynamic/mimo.host.template.mjs +169 -0
- package/dynamic/opencode.host.js +1443 -0
- package/dynamic/opencode.host.template.mjs +125 -0
- package/home-plugin/cli-bridge-indicator/cordis.patch.yml +31 -0
- package/home-plugin/cli-bridge-indicator/lib/client.js +606 -0
- package/home-plugin/cli-bridge-indicator/lib/index.mjs +420 -0
- package/home-plugin/cli-bridge-indicator/lib/preset-declarations.mjs +137 -0
- package/home-plugin/cli-bridge-indicator/lib/settings.mjs +300 -0
- package/mcp/agy-mcp-server.mjs +6 -0
- package/mcp/cli-bridge-mcp.mjs +185 -0
- package/mcp/codebuddy-mcp-server.mjs +6 -0
- package/mcp/mimo-mcp-server.mjs +6 -0
- package/mcp/providers/agy.mjs +254 -0
- package/mcp/providers/codebuddy.mjs +397 -0
- package/mcp/providers/mimo.mjs +290 -0
- package/mcp/providers/opencode.mjs +236 -0
- package/package.json +89 -4
- package/preset/agy-first/agent.cordis.yml +141 -0
- package/preset/agy-first/cli-bridge.mjs +169 -0
- package/preset/agy-first/plugin-list.mjs +26 -0
- package/preset/agy-first/preset.yml +3 -0
- package/preset/codebuddy-first/agent.cordis.yml +141 -0
- package/preset/codebuddy-first/cli-bridge.mjs +188 -0
- package/preset/codebuddy-first/plugin-list.mjs +20 -0
- package/preset/codebuddy-first/preset.yml +3 -0
- package/preset/mimo-first/agent.cordis.yml +143 -0
- package/preset/mimo-first/cli-bridge.mjs +236 -0
- package/preset/mimo-first/plugin-list.mjs +39 -0
- package/preset/mimo-first/preset.yml +3 -0
- package/preset/opencode-first/agent.cordis.yml +141 -0
- package/preset/opencode-first/cli-bridge.mjs +147 -0
- package/preset/opencode-first/plugin-list.mjs +26 -0
- package/preset/opencode-first/preset.yml +3 -0
- package/preset/standard-base.mjs +102 -0
- package/providers/agy.mjs +398 -0
- package/providers/codebuddy.mjs +926 -0
- package/providers/mimo.mjs +864 -0
- package/providers/opencode.mjs +619 -0
- package/providers/registry.mjs +39 -0
- package/scripts/build.mjs +235 -0
- package/scripts/deploy.mjs +61 -0
- package/scripts/verify.mjs +148 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// dynamic/codebuddy.host.template.mjs — codebuddy 动态沙箱宿主模板(cordis_define code.host 源)。
|
|
2
|
+
//
|
|
3
|
+
// 构建(node scripts/build.mjs --only=codebuddy)把 core/bridge-kit.mjs 与
|
|
4
|
+
// providers/codebuddy.mjs 分别内联进下方两个占位标记行(各占一行、行内仅此标记),
|
|
5
|
+
// 生成 dynamic/codebuddy.host.js。注意:标记字面量绝不能出现在本注释里 —— 构建做全局
|
|
6
|
+
// 替换,注释中出现同样会被替换成正文代码而炸掉语法。
|
|
7
|
+
// 沙箱纪律(旧仓 dynamic/host.js 头注 verbatim 精神):
|
|
8
|
+
// - 禁 import/require、无 TypeScript;无 AbortController/process 裸引用/Buffer/原生
|
|
9
|
+
// 定时器 —— process 只经 typeof 守卫探测;宿主能力全部来自注入的 harness.*/ctx。
|
|
10
|
+
// - 顶层 return { inject, apply } 为动态宿主约定形态(生成物是 .js/CJS 包装,顶层
|
|
11
|
+
// return 合法;本模板文件是 .mjs,不要直接 node --check 模板本身,只 check 生成物)。
|
|
12
|
+
// - 无 ctx.emit:状态经 ctx.get('cliBridgeCollector').mergeSnapshot('codebuddy', snap)
|
|
13
|
+
// 推给家级灯(旧 codebuddyCollector 服务名在 keystone 里保留别名);动态形态不宣告
|
|
14
|
+
// mode(旧语义:普通模式灯仅在调用 codebuddy 时临时显示)。
|
|
15
|
+
// - exe 解析保持旧动态三面语义(各产品面登录互斥、不跨面回退):workbuddy /
|
|
16
|
+
// codebuddy-en 用各自的 Program Files 候选(WORKBUDDY_BIN / CODEBUDDY_EN_BIN 覆盖);
|
|
17
|
+
// npm 面走 CODEBUDDY_BIN > subprocess.resolveExecutable(PATH) > npm 全局 bin 脚本。
|
|
18
|
+
// - 设置:沙箱经 getBuiltinModule('node:fs') 读一次统一设置文件(apply 时一次,
|
|
19
|
+
// 旧 dynamic 语义);不可得时回退旧扁平文件,再不可得用默认值。EN 面无凭据且
|
|
20
|
+
// 无 fs(descriptor 的 dsh-store 通道缺席)→ preflight 确定性 abort 给提示即可。
|
|
21
|
+
/*__KIT__*/
|
|
22
|
+
/*__PROVIDER__*/
|
|
23
|
+
/*__SCHED__*/
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
inject: ['tools', 'subprocess', 'systemPrompt', 'timer'],
|
|
27
|
+
apply(ctx) {
|
|
28
|
+
// 调度门禁(0.2.0):设置面板关掉 codebuddy → 本形态不注册工具/政策段;fail-open。
|
|
29
|
+
if (!isBridgeEnabled('codebuddy', SCHED_ALL_IDS)) return
|
|
30
|
+
const subprocess = ctx.subprocess
|
|
31
|
+
const planMode = ctx.get('planMode')
|
|
32
|
+
const sandboxPolicy = ctx.get('sandboxPolicy')
|
|
33
|
+
// 沙箱可能运行在无 process 的环境:typeof 守卫读 env(旧仓 dynamic 的等价面)。
|
|
34
|
+
const env = (typeof process !== 'undefined' && process.env) ? process.env : {}
|
|
35
|
+
|
|
36
|
+
const provider = defineProvider({ env })
|
|
37
|
+
|
|
38
|
+
function publish(snapshot) {
|
|
39
|
+
try {
|
|
40
|
+
const collector = ctx.get('cliBridgeCollector')
|
|
41
|
+
if (collector && typeof collector.mergeSnapshot === 'function') { collector.mergeSnapshot('codebuddy', snapshot); return }
|
|
42
|
+
} catch (e) { /* fall through to legacy alias */ }
|
|
43
|
+
try {
|
|
44
|
+
const legacy = ctx.get('codebuddyCollector')
|
|
45
|
+
if (legacy && typeof legacy.mergeSnapshot === 'function') legacy.mergeSnapshot(snapshot)
|
|
46
|
+
} catch (e) { /* 灯数据尽力而为 */ }
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 设置快照(apply 时一次,旧 dynamic 语义):统一文件 codebuddy 分区 >
|
|
50
|
+
// 旧扁平文件(字段级迁移的只读兜底)> 默认。全程容错,失败不炸 apply。
|
|
51
|
+
const settingsSnapshot = (function () {
|
|
52
|
+
const def = provider.normalizeSettings(null)
|
|
53
|
+
try {
|
|
54
|
+
const proc = (typeof process !== 'undefined') ? process : null
|
|
55
|
+
const nodeFs = proc && typeof proc.getBuiltinModule === 'function' ? proc.getBuiltinModule('node:fs') : null
|
|
56
|
+
const nodePath = proc && typeof proc.getBuiltinModule === 'function' ? proc.getBuiltinModule('node:path') : null
|
|
57
|
+
if (!nodeFs || typeof nodeFs.readFileSync !== 'function') return def
|
|
58
|
+
const join = nodePath ? nodePath.join.bind(nodePath) : ((...p) => p.join('/'))
|
|
59
|
+
const readJson = (p) => { try { return JSON.parse(nodeFs.readFileSync(p, 'utf8')) } catch (e) { return null } }
|
|
60
|
+
const unifiedFile = env.CLI_BRIDGE_SETTINGS_FILE || (env.DSH_HOME ? join(env.DSH_HOME, 'cli-bridge-settings.json') : null)
|
|
61
|
+
const unified = unifiedFile ? readJson(unifiedFile) : null
|
|
62
|
+
if (unified && unified.codebuddy && typeof unified.codebuddy === 'object') return provider.normalizeSettings(unified.codebuddy)
|
|
63
|
+
const legacyFile = env.CODEBUDDY_SETTINGS_FILE || (env.DSH_HOME ? join(env.DSH_HOME, 'codebuddy-bridge-settings.json') : null)
|
|
64
|
+
const legacy = legacyFile ? readJson(legacyFile) : null
|
|
65
|
+
if (legacy && typeof legacy === 'object') return provider.normalizeSettings(legacy)
|
|
66
|
+
} catch (e) { /* 无 fs:默认值,端点走 CLI 自身 */ }
|
|
67
|
+
return def
|
|
68
|
+
})()
|
|
69
|
+
|
|
70
|
+
// exe:旧动态三面候选 verbatim(nodeExe 仅在有 process 时有真值,否则退回
|
|
71
|
+
// 字符串 'node' —— 旧 dynamic 同款守卫)。
|
|
72
|
+
async function resolveExe(backend, signal) {
|
|
73
|
+
const nodeExe = (typeof process !== 'undefined' && process.execPath) || 'node'
|
|
74
|
+
if (backend === 'workbuddy') {
|
|
75
|
+
return [nodeExe, env.WORKBUDDY_BIN || 'C:\\Program Files\\WorkBuddy\\resources\\app.asar.unpacked\\cli\\bin\\codebuddy']
|
|
76
|
+
}
|
|
77
|
+
if (backend === 'codebuddy-en') {
|
|
78
|
+
return [nodeExe, env.CODEBUDDY_EN_BIN || 'C:\\Program Files\\WorkBuddyAI\\resources\\app.asar.unpacked\\cli\\bin\\codebuddy']
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const exe = await subprocess.resolveExecutable('codebuddy', undefined, signal)
|
|
82
|
+
if (!/\.(cmd|bat)$/i.test(exe)) return exe
|
|
83
|
+
} catch (e) {}
|
|
84
|
+
const binPath = env.CODEBUDDY_BIN || ((env.APPDATA || 'C:\\Users\\lcl\\AppData\\Roaming') + '\\npm\\node_modules\\@tencent-ai\\codebuddy-code\\bin\\codebuddy')
|
|
85
|
+
return [nodeExe, binPath]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 旧仓 CWD_FALLBACK 硬编码机器绝对路径:本形态保持旧 dynamic verbatim 行为
|
|
89
|
+
// (Lead 定案:与旧 dynamic 逐字一致;CODEBUDDY_MCP_CWD 优先仅为 MCP 面语义,
|
|
90
|
+
// 旧 dynamic 不读它)。
|
|
91
|
+
function getCwdFallback() {
|
|
92
|
+
if (sandboxPolicy && typeof sandboxPolicy.workspaceRoot === 'string' && sandboxPolicy.workspaceRoot) return sandboxPolicy.workspaceRoot
|
|
93
|
+
if (typeof process !== 'undefined' && typeof process.cwd === 'function') { try { return process.cwd() } catch (e) {} }
|
|
94
|
+
return 'C:\\Users\\lcl\\Desktop\\codebuddy-bridge'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function planActiveFor(exec) {
|
|
98
|
+
try {
|
|
99
|
+
if (planMode && exec && exec.agent) {
|
|
100
|
+
const st = planMode.get(exec.agent)
|
|
101
|
+
return !!(st && st.active)
|
|
102
|
+
}
|
|
103
|
+
} catch (e) {}
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
provider.attach({
|
|
108
|
+
ctx,
|
|
109
|
+
subprocess,
|
|
110
|
+
resolveExe,
|
|
111
|
+
getCwdFallback,
|
|
112
|
+
getPreferredBackend: function () { return settingsSnapshot.preferredBackend || provider.defaultBackend },
|
|
113
|
+
getSettings: function () { return settingsSnapshot },
|
|
114
|
+
planActiveFor,
|
|
115
|
+
publish
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
const OUTPUT_SCHEMA = { type: 'object', additionalProperties: true }
|
|
119
|
+
|
|
120
|
+
harness.registerTool(ctx, harness.defineTool({
|
|
121
|
+
name: provider.tools.run.name,
|
|
122
|
+
description: provider.tools.run.description,
|
|
123
|
+
parameters: provider.tools.run.inputSchema,
|
|
124
|
+
output: { schema: OUTPUT_SCHEMA, render: function (args, value) { return renderResult(value, provider) } },
|
|
125
|
+
execute: function (args, exec) { return provider.runToolLogic(args, exec) }
|
|
126
|
+
}))
|
|
127
|
+
harness.registerTool(ctx, harness.defineTool({
|
|
128
|
+
name: provider.tools.continue.name,
|
|
129
|
+
description: provider.tools.continue.description,
|
|
130
|
+
parameters: provider.tools.continue.inputSchema,
|
|
131
|
+
output: { schema: OUTPUT_SCHEMA, render: function (args, value) { return renderResult(value, provider) } },
|
|
132
|
+
execute: function (args, exec) { return provider.continueToolLogic(args, exec) }
|
|
133
|
+
}))
|
|
134
|
+
harness.registerTool(ctx, harness.defineTool({
|
|
135
|
+
name: provider.tools.status.name,
|
|
136
|
+
description: provider.tools.status.description,
|
|
137
|
+
parameters: provider.tools.status.inputSchema,
|
|
138
|
+
output: { schema: OUTPUT_SCHEMA, render: function (args, value) { return renderStatus(value, provider) } },
|
|
139
|
+
execute: function (args) { return provider.statusToolLogic(args) }
|
|
140
|
+
}))
|
|
141
|
+
for (const et of provider.extraTools) {
|
|
142
|
+
harness.registerTool(ctx, harness.defineTool({
|
|
143
|
+
name: et.name,
|
|
144
|
+
description: et.description,
|
|
145
|
+
parameters: et.inputSchema,
|
|
146
|
+
output: { schema: OUTPUT_SCHEMA, render: function (args, value) { return et.render ? et.render(value) : renderResult(value, provider) } },
|
|
147
|
+
execute: function (args, exec) { return et.logic(args, exec) }
|
|
148
|
+
}))
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 浏览器指示灯轮询的 RPC 面(旧 dynamic/handle('codebuddy_status') 语义)。
|
|
152
|
+
harness.handle('codebuddy_status', function () { return provider.statusToolLogic({}) })
|
|
153
|
+
|
|
154
|
+
// 旧 policy 文案 verbatim(提示词连续性红线;name/order 沿用旧 preset 的 5,
|
|
155
|
+
// 动态与 preset 两形态注入同一段全文,provider.policyText 单源)。
|
|
156
|
+
ctx.systemPrompt.section({
|
|
157
|
+
name: 'codebuddy:policy',
|
|
158
|
+
order: 5,
|
|
159
|
+
text: provider.policyText
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
}
|