zen-gitsync 2.18.20 → 2.18.22
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/package.json +4 -1
- package/src/cli/ai/agent.js +9 -2
- package/src/cli/ai/extensions.js +1 -1
- package/src/cli/ai/runtime.test.js +57 -1
- package/src/cli/ai/termui.js +11 -2
- package/src/cli/ai/tools.js +266 -5
- package/src/cli/ai/tools.test.js +81 -0
- package/src/cli/ai/transport.js +1 -1
- package/src/cli/ai/turn.js +59 -3
- package/src/config.js +60 -4
- package/src/mcp/install.js +548 -529
- package/src/ui/public/assets/AgentView-DdiyBMDD.js +26 -0
- package/src/ui/public/assets/{AgentView-BE7GD8rc.css → AgentView-_DUYxFmp.css} +1 -1
- package/src/ui/public/assets/{AppVersionBadge-86tbKU20.js → AppVersionBadge-CSEM45L4.js} +2 -2
- package/src/ui/public/assets/{BranchSelector-CsrkmTCA.js → BranchSelector-cSx2ZxYM.js} +1 -1
- package/src/ui/public/assets/ChatSilenceBadge-Dtv23ZmV.js +16 -0
- package/src/ui/public/assets/{CommitForm-DBK0GXEh.js → CommitForm-CrAsbDkq.js} +2 -2
- package/src/ui/public/assets/{CommonDialog-BkuDIWro.js → CommonDialog-BtO3uKdw.js} +1 -1
- package/src/ui/public/assets/{EditorView-CnWsMdHg.css → EditorView-B-t-nuf0.css} +1 -1
- package/src/ui/public/assets/EditorView-BesiWTV2.js +10 -0
- package/src/ui/public/assets/{FlowExecutionViewer-ClUkAmA2.js → FlowExecutionViewer-CfU9DLFG.js} +1 -1
- package/src/ui/public/assets/{FlowOrchestrationWorkspace-B3sOK3fz.js → FlowOrchestrationWorkspace-D3CSRMvG.js} +1 -1
- package/src/ui/public/assets/{LogList-6aO0-2xh.js → LogList-CT-SRIS3.js} +4 -4
- package/src/ui/public/assets/MindmapView-BCGq2zdh.js +35 -0
- package/src/ui/public/assets/MindmapView-CoUbyadF.css +1 -0
- package/src/ui/public/assets/{MonitorView-fcNrgVaU.js → MonitorView-BuBJJVhR.js} +1 -1
- package/src/ui/public/assets/{ProjectManagerView-CZfrML6A.js → ProjectManagerView-DlSfRn9N.js} +2 -2
- package/src/ui/public/assets/{ProjectStartupButton-D5MREz6F.js → ProjectStartupButton-DKZttDb3.js} +1 -1
- package/src/ui/public/assets/RemoteManagerDialog-CVrhhUPg.js +4 -0
- package/src/ui/public/assets/{RemoteRepoCard-CTnmfv2y.js → RemoteRepoCard-CmdYDF24.js} +1 -1
- package/src/ui/public/assets/{SourceMapView-B4q5qiE8.js → SourceMapView-DClgTmda.js} +1 -1
- package/src/ui/public/assets/{SvgIcon-WpEiC1rI.js → SvgIcon-D5fhBiJr.js} +1 -1
- package/src/ui/public/assets/TaskExecutorPicker-CzvWdS_K.js +1 -0
- package/src/ui/public/assets/TaskExecutorPicker-Dn8SgrTZ.css +1 -0
- package/src/ui/public/assets/{UserInputNode-Deoc3UvQ.js → UserInputNode-CNuW_Dtu.js} +1 -1
- package/src/ui/public/assets/WorkbenchView-D61DxNnn.css +1 -0
- package/src/ui/public/assets/WorkbenchView-WKNPn-oz.js +341 -0
- package/src/ui/public/assets/_plugin-vue_export-helper-E2AaPXn7.js +19 -0
- package/src/ui/public/assets/configStore-JIX2MOKo.js +1 -0
- package/src/ui/public/assets/{dagre-CpKxpMNH.js → dagre-yiQDclZv.js} +3 -3
- package/src/ui/public/assets/{element-plus-Bz6lYur-.js → element-plus-BeZBQw4X.js} +1 -1
- package/src/ui/public/assets/{flow-mindmap-cTg78Krq.js → flow-mindmap-CGjPqCv0.js} +1 -1
- package/src/ui/public/assets/{index-cDiVh_ZL.js → index-Cjv2Z6nF.js} +134 -125
- package/src/ui/public/assets/index-IjYv2goK.css +1 -0
- package/src/ui/public/assets/{monaco-CvMddat7.js → monaco-CMQow_j-.js} +1 -1
- package/src/ui/public/assets/{office-docx-VOB-i4K2.js → office-docx-nuGPI15f.js} +1 -1
- package/src/ui/public/assets/{office-excel-CJ2JvfA8.js → office-excel-CK-HOYi8.js} +1 -1
- package/src/ui/public/assets/{office-pptx-Z88k9qnx.js → office-pptx-9onMeLux.js} +1 -1
- package/src/ui/public/assets/{relativeTime-CoXAs57j.js → relativeTime-DHhE9Ihn.js} +1 -1
- package/src/ui/public/assets/taskExecutionExport-DlBMELzX.js +15 -0
- package/src/ui/public/assets/toolsStore-h5iqPyST.js +1 -0
- package/src/ui/public/assets/{useWorkbenchProjects-BS59r5Rj.js → useWorkbenchProjects-DW3vBHpK.js} +1 -1
- package/src/ui/public/assets/{vendor-CSFGMcMB.css → vendor-CAhoE06w.css} +1 -1
- package/src/ui/public/assets/{vendor-C2k0GBzj.js → vendor-KxSgeiUX.js} +303 -303
- package/src/ui/public/assets/{vue-flow-Cnxq2qrs.js → vue-flow-BMMiguH1.js} +1 -1
- package/src/ui/public/index.html +14 -14
- package/src/ui/server/routes/config.js +13 -0
- package/src/ui/server/routes/fileOpen.js +1851 -1736
- package/src/ui/server/routes/fileOpen.test.js +39 -1
- package/src/ui/server/routes/workbench/agentChat.js +48 -8
- package/src/ui/server/routes/workbench/agentChatShared.test.js +584 -496
- package/src/ui/server/routes/workbench/agentEngines.js +7 -4
- package/src/ui/server/routes/workbench/executorModels.js +25 -4
- package/src/ui/server/routes/workbench/executorModels.test.js +557 -530
- package/src/ui/server/routes/workbench/jobActivity.js +2 -2
- package/src/ui/server/routes/workbench/taskRunner.codearts.test.js +252 -0
- package/src/ui/server/routes/workbench/taskRunner.codebuddy.test.js +317 -317
- package/src/ui/server/routes/workbench/taskRunner.js +216 -7
- package/src/ui/server/routes/workbench/taskRunner.opencode.test.js +130 -130
- package/src/ui/server/routes/workbench/taskRunner.pi.test.js +298 -298
- package/src/ui/public/assets/AgentView-Du9akUeZ.js +0 -12
- package/src/ui/public/assets/ChatSilenceBadge-BBoFeSqe.js +0 -21
- package/src/ui/public/assets/EditorAgentPanel-BMUphuG0.css +0 -1
- package/src/ui/public/assets/EditorAgentPanel-KiHbQPJP.js +0 -34
- package/src/ui/public/assets/EditorView-B18B4yNJ.js +0 -13
- package/src/ui/public/assets/MindmapView-BDI3D_1h.css +0 -1
- package/src/ui/public/assets/MindmapView-aJ9TTijE.js +0 -4
- package/src/ui/public/assets/RecentDirectoriesChat-DBGoUlkn.css +0 -1
- package/src/ui/public/assets/RecentDirectoriesChat-wfkSF6NU.js +0 -3
- package/src/ui/public/assets/RemoteManagerDialog-BBwNlK9J.js +0 -4
- package/src/ui/public/assets/WorkbenchView-CVqXb__l.css +0 -1
- package/src/ui/public/assets/WorkbenchView-CijzpDWN.js +0 -360
- package/src/ui/public/assets/_plugin-vue_export-helper-BhdsvhKo.js +0 -19
- package/src/ui/public/assets/agentConversations-DaAtF1v4.js +0 -10
- package/src/ui/public/assets/configStore-Drlw8KtR.js +0 -1
- package/src/ui/public/assets/index-DSQ6mp_N.css +0 -1
- package/src/ui/public/assets/toolsStore-CnX34C96.js +0 -1
- package/src/ui/public/assets/useOrchestrator-BXmxJsRl.js +0 -1
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
import { test } from 'node:test'
|
|
20
20
|
import assert from 'node:assert/strict'
|
|
21
21
|
import fs from 'node:fs/promises'
|
|
22
|
-
import { fetchLatestVersion, findDshExecutable, getToolInstallers, parseVersionOutput, registerFileOpenRoutes } from './fileOpen.js'
|
|
22
|
+
import { fetchLatestVersion, findCodeArtsExecutable, findDshExecutable, getToolInstallers, parseVersionOutput, registerFileOpenRoutes } from './fileOpen.js'
|
|
23
23
|
|
|
24
24
|
// ── parseVersionOutput(版本号采集,2026-09-05 check-tools 增强)────────────
|
|
25
25
|
|
|
@@ -77,6 +77,44 @@ test('getToolInstallers: npm 包工具的升级变体带 @latest', () => {
|
|
|
77
77
|
}
|
|
78
78
|
})
|
|
79
79
|
|
|
80
|
+
test('getToolInstallers: codearts 只给手动安装卡片(没有 npm 包,不提供一键安装)', () => {
|
|
81
|
+
for (const platform of ['win32', 'darwin', 'linux']) {
|
|
82
|
+
const inst = getToolInstallers(platform, () => true).codearts
|
|
83
|
+
// 缺这条时前端弹窗会一直停在「正在获取安装方式」(2026-10-25 实测)
|
|
84
|
+
assert.ok(inst, `${platform} 缺 codearts 安装信息`)
|
|
85
|
+
// 官方只有 PowerShell / bash 安装脚本,代跑等于把远程脚本塞进用户终端
|
|
86
|
+
assert.equal(inst.supported, false)
|
|
87
|
+
assert.equal(inst.packageManager, 'official-script')
|
|
88
|
+
assert.match(inst.command, /codearts\/cli_tui\/install_script\/install\.(ps1|sh)/)
|
|
89
|
+
assert.equal(inst.docsUrl, 'https://codearts.huaweicloud.com/download.html')
|
|
90
|
+
// 没有升级变体:升级靠它自己的 `codearts upgrade`
|
|
91
|
+
assert.equal(inst.updateCommand, undefined)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('findCodeArtsExecutable: 按安装位置硬找,不依赖当前进程的 PATH', async () => {
|
|
96
|
+
const os = await import('node:os')
|
|
97
|
+
const path = await import('node:path')
|
|
98
|
+
const home = await fs.mkdtemp(path.join(os.tmpdir(), 'zen-codearts-inst-'))
|
|
99
|
+
const binDir = path.join(home, '.codeartsdoer', 'installers')
|
|
100
|
+
await fs.mkdir(binDir, { recursive: true })
|
|
101
|
+
const shim = path.join(binDir, 'codearts.cmd')
|
|
102
|
+
await fs.writeFile(shim, '@echo off\r\n')
|
|
103
|
+
|
|
104
|
+
const prev = process.env.USERPROFILE
|
|
105
|
+
process.env.USERPROFILE = home
|
|
106
|
+
try {
|
|
107
|
+
// 关键契约:安装脚本只改了**用户 PATH**,已运行的进程看不到 —— 必须硬找成功,
|
|
108
|
+
// 否则界面永远显示「未安装」,用户重启前怎么点都修复不了(2026-10-25 实测)
|
|
109
|
+
if (process.platform === 'win32') {
|
|
110
|
+
assert.equal(await findCodeArtsExecutable(), shim)
|
|
111
|
+
}
|
|
112
|
+
} finally {
|
|
113
|
+
if (prev === undefined) delete process.env.USERPROFILE
|
|
114
|
+
else process.env.USERPROFILE = prev
|
|
115
|
+
}
|
|
116
|
+
})
|
|
117
|
+
|
|
80
118
|
test('getToolInstallers: 各平台 vscode 升级用各自的 upgrade 动词', () => {
|
|
81
119
|
const win = getToolInstallers('win32', () => true)
|
|
82
120
|
assert.match(win.vscode.updateCommand, /^winget upgrade/)
|
|
@@ -53,7 +53,7 @@ import os from 'os';
|
|
|
53
53
|
import { logger } from './shared.js';
|
|
54
54
|
|
|
55
55
|
// 从 CLI 侧导入工具定义、执行器与 LLM 传输层(同一 monorepo,路径可达)
|
|
56
|
-
import { TOOL_DEFINITIONS, executeTool, normalizePlanSteps, summarizePlan, splitToolOutput, toolMessageContent } from '../../../../cli/ai/tools.js';
|
|
56
|
+
import { TOOL_DEFINITIONS, executeTool, normalizePlanSteps, summarizePlan, splitToolOutput, toolMessageContent, splitToolBatches, backgroundTaskRunning } from '../../../../cli/ai/tools.js';
|
|
57
57
|
import { prepareRequestMessages, measureContextUsage, resolveRequestBudget } from '../../../../cli/ai/context.js';
|
|
58
58
|
import { streamChatOnce } from '../../../../cli/ai/transport.js';
|
|
59
59
|
import { checkDangerousCommand } from '../../../../cli/ai/safety.js';
|
|
@@ -166,6 +166,8 @@ ${isWin ? `- 当前是 Windows,以下 Unix 命令**不存在**,用了必定报"
|
|
|
166
166
|
- 大文件用 offset/limit 分段读取,不要一次读爆上下文
|
|
167
167
|
- git 操作用 run_command 执行
|
|
168
168
|
- run_command 默认就在工作目录执行,不要再加 cd 前缀;默认超时 120 秒,长任务加大 timeout_seconds(最大 600)
|
|
169
|
+
- 起 dev server / watch / 监听端口这类不会自己结束的命令,用 run_in_background=true(立刻拿到 bg_N),再用 background_task 看日志或 kill;直接前台跑只会一直占着,到超时被杀
|
|
170
|
+
- 一轮里要读多个文件 / 搜多处时,把它们放进同一次响应里一起发 —— 只读工具会并发执行,比一个个来回快得多
|
|
169
171
|
- 命令在 ${shellDesc} 下执行,注意语法兼容
|
|
170
172
|
|
|
171
173
|
# 任务计划(多步任务必用)
|
|
@@ -281,6 +283,8 @@ ${isWin ? `- This is Windows. The following Unix commands do NOT exist here:
|
|
|
281
283
|
- Use offset/limit for large files
|
|
282
284
|
- git operations via run_command
|
|
283
285
|
- run_command defaults to the working directory; default timeout 120s, max 600s
|
|
286
|
+
- For processes that never exit on their own (dev server, watch, port listeners) pass run_in_background=true (you get a bg_N id immediately), then use background_task to read logs or kill it; running them in the foreground just blocks until the timeout kills them
|
|
287
|
+
- When a turn needs several files or several searches, issue them in the same response — read-only tools run concurrently, which is far faster than one round-trip each
|
|
284
288
|
- Images reach you two ways:
|
|
285
289
|
· The user attached one to a message → it arrives as an image_url part in the user message; you can see it directly
|
|
286
290
|
· The user only gave you a **path** (or you run into an image while exploring) → read it with the read_image tool, not read_file
|
|
@@ -564,8 +568,10 @@ export async function runAgentTurn({ session, model, userMessage, images = [], c
|
|
|
564
568
|
tool_calls: toolCalls
|
|
565
569
|
}));
|
|
566
570
|
|
|
567
|
-
//
|
|
568
|
-
|
|
571
|
+
// 单个工具的执行:发 tool_call_start → 执行 → 发 tool_result,返回要入历史的 tool 消息。
|
|
572
|
+
// 抽成函数是为了让"串行批"和"并发批"共用同一条路径(包括参数错误、ask_user 的
|
|
573
|
+
// interactionId 绑定这些边角),两条分支只在**什么时候 push 历史**上不同。
|
|
574
|
+
const runOneTool = async (tc) => {
|
|
569
575
|
const name = tc.function?.name || '';
|
|
570
576
|
const rawArgs = tc.function?.arguments || '';
|
|
571
577
|
const toolCallId = tc.id || name;
|
|
@@ -577,8 +583,7 @@ export async function runAgentTurn({ session, model, userMessage, images = [], c
|
|
|
577
583
|
const errResult = `错误: 工具参数不是合法 JSON: ${rawArgs.slice(0, 200)}`;
|
|
578
584
|
send({ type: 'tool_call_start', toolCallId, name, argsPreview: rawArgs.slice(0, 200), arguments: rawArgs });
|
|
579
585
|
send({ type: 'tool_result', toolCallId, name, result: errResult });
|
|
580
|
-
|
|
581
|
-
continue;
|
|
586
|
+
return { toolCallId, name, content: errResult };
|
|
582
587
|
}
|
|
583
588
|
|
|
584
589
|
// 工具参数预览(前端收起态那一行副标题)。这里截断是**故意的** ——
|
|
@@ -609,8 +614,35 @@ export async function runAgentTurn({ session, model, userMessage, images = [], c
|
|
|
609
614
|
// 直接把对象丢过去会渲染成 "[object Object]"),图片进会话历史里的
|
|
610
615
|
// 多模态 tool 消息 —— 模型看得见图,用户看到的是"已读取图片 xxx.png"。
|
|
611
616
|
const { text: outText, images: outImages } = splitToolOutput(output);
|
|
612
|
-
|
|
613
|
-
|
|
617
|
+
// 后台命令:这一轮的工具调用已经返回(模型能接着干活),但进程还活着。
|
|
618
|
+
// 带上 status 让前端别把卡片标成"完成"—— 绿勾会让人以为 dev server 跑完了。
|
|
619
|
+
const isBackground = name === 'run_command' && args?.run_in_background === true;
|
|
620
|
+
// 后台任务刚结束(进程自己退出 / 被 kill):叫前端把那张"运行中"的卡收尾
|
|
621
|
+
const endedBg = name === 'background_task' && args?.id && backgroundTaskRunning(args.id) === false
|
|
622
|
+
? args.id
|
|
623
|
+
: undefined;
|
|
624
|
+
send({
|
|
625
|
+
type: 'tool_result',
|
|
626
|
+
toolCallId,
|
|
627
|
+
name,
|
|
628
|
+
result: outText,
|
|
629
|
+
...(isBackground ? { status: 'background' } : {}),
|
|
630
|
+
...(endedBg ? { endsBackground: endedBg } : {}),
|
|
631
|
+
});
|
|
632
|
+
return { toolCallId, name, content: toolMessageContent(outText, outImages) };
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// 执行工具。连续的只读工具并发跑(分组规则与 CLI turn.js 共用 tools.js 的
|
|
636
|
+
// splitToolBatches),写类 / 命令 / 问用户仍串行 —— 它们有顺序依赖或要占住交互。
|
|
637
|
+
// 前端按 toolCallId 更新卡片,谁先完成谁先亮 "done";而**入历史**的顺序必须
|
|
638
|
+
// 与 assistant.tool_calls 一致,所以统一等这一批全部结束再按 batch 顺序 push。
|
|
639
|
+
for (const batch of splitToolBatches(toolCalls)) {
|
|
640
|
+
const results = batch.parallel
|
|
641
|
+
? await Promise.all(batch.calls.map(tc => runOneTool(tc)))
|
|
642
|
+
: [await runOneTool(batch.calls[0])];
|
|
643
|
+
for (const r of results) {
|
|
644
|
+
session.messages.push({ role: 'tool', tool_call_id: r.toolCallId, name: r.name, content: r.content });
|
|
645
|
+
}
|
|
614
646
|
}
|
|
615
647
|
// 工具结果全部入历史后继续循环,让模型基于结果决定下一步
|
|
616
648
|
}
|
|
@@ -635,7 +667,15 @@ function summarizeArgs(name, args) {
|
|
|
635
667
|
try {
|
|
636
668
|
switch (name) {
|
|
637
669
|
case 'run_command':
|
|
638
|
-
|
|
670
|
+
// 后台命令要一眼看得出来(否则和普通命令长得一样,用户以为跑完了)
|
|
671
|
+
return (args.run_in_background ? '[后台] ' : '') + String(args.command || '').slice(0, 200);
|
|
672
|
+
case 'background_task': {
|
|
673
|
+
const action = String(args.action || 'read');
|
|
674
|
+
if (action === 'list') return '列出后台任务';
|
|
675
|
+
if (action === 'kill') return `停止 ${args.id || '?'}`;
|
|
676
|
+
const wait = Number(args.wait_seconds) || 0;
|
|
677
|
+
return `${args.id || '?'}${wait ? ` · 等 ${wait}s` : ''}`;
|
|
678
|
+
}
|
|
639
679
|
case 'read_file':
|
|
640
680
|
case 'read_image':
|
|
641
681
|
case 'write_file':
|