@xdxer/dingtalk-agent 0.1.5-beta.5 → 0.1.5-beta.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 +52 -0
- package/README.en.md +6 -6
- package/README.md +6 -6
- package/dist/bin/dingtalk-agent.js +406 -139
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/actions.js +3 -2
- package/dist/src/actions.js.map +1 -1
- package/dist/src/agent-audit.js +29 -25
- package/dist/src/agent-audit.js.map +1 -1
- package/dist/src/agent-definition.js +7 -3
- package/dist/src/agent-definition.js.map +1 -1
- package/dist/src/agent-enhance.js +2 -2
- package/dist/src/agent-enhance.js.map +1 -1
- package/dist/src/agent-platform.js +2 -2
- package/dist/src/agent-platform.js.map +1 -1
- package/dist/src/development-workspace.js +14 -9
- package/dist/src/development-workspace.js.map +1 -1
- package/dist/src/doctor.js +58 -7
- package/dist/src/doctor.js.map +1 -1
- package/dist/src/dws.js +2 -1
- package/dist/src/dws.js.map +1 -1
- package/dist/src/init.js +2 -1
- package/dist/src/init.js.map +1 -1
- package/dist/src/map.js +157 -0
- package/dist/src/map.js.map +1 -0
- package/dist/src/opencode-evals.js +6 -6
- package/dist/src/opencode-evals.js.map +1 -1
- package/dist/src/opencode-provider.js +2 -2
- package/dist/src/opencode-provider.js.map +1 -1
- package/dist/src/opencode-workspace.js +3 -3
- package/dist/src/opencode-workspace.js.map +1 -1
- package/dist/src/personal-event-evals.js +4 -2
- package/dist/src/personal-event-evals.js.map +1 -1
- package/dist/src/remote-semantic-state-live-evals.js +5 -4
- package/dist/src/remote-semantic-state-live-evals.js.map +1 -1
- package/dist/src/remote-state-evals.js +2 -2
- package/dist/src/remote-state-evals.js.map +1 -1
- package/dist/src/robot-evals.js +3 -3
- package/dist/src/robot-evals.js.map +1 -1
- package/dist/src/schedule-plan.js +1 -1
- package/dist/src/schedule-plan.js.map +1 -1
- package/dist/src/sessions.js +1 -1
- package/dist/src/sessions.js.map +1 -1
- package/dist/src/skill-manager.js +74 -13
- package/dist/src/skill-manager.js.map +1 -1
- package/dist/src/tui.js +369 -0
- package/dist/src/tui.js.map +1 -0
- package/dist/src/upgrade.js +113 -33
- package/dist/src/upgrade.js.map +1 -1
- package/dist/src/waits.js +2 -1
- package/dist/src/waits.js.map +1 -1
- package/dist/src/workspace.js +2 -2
- package/dist/src/workspace.js.map +1 -1
- package/docs/ARCHITECTURE.md +9 -9
- package/docs/INSTALLATION.md +6 -6
- package/docs/SELF-TEST.md +3 -3
- package/docs/schemas/project.schema.json +2 -2
- package/examples/agents/README.md +1 -1
- package/examples/agents/fde-coach/agent/AGENTS.md +1 -1
- package/examples/agents/release-manager/agent/AGENTS.md +1 -1
- package/lab/agent-eval/catalog.json +5 -5
- package/lab/agent-eval/classic-failures.json +4 -4
- package/lab/agent-eval/completion-gate-regression.json +9 -9
- package/lab/agent-eval/personal-event-live.example.json +3 -3
- package/lab/agent-eval/remote-semantic-state-live.example.json +1 -1
- package/lab/agent-eval/workspace/opencode.json +2 -2
- package/lab/project-workspace/multica-readonly.fixture.json +2 -2
- package/lab/project-workspace/opencode-provider-suite.json +2 -2
- package/lab/project-workspace/project.fixture.json +1 -1
- package/lab/robot-eval/suite.json +1 -1
- package/lab/robot-eval/workspace/AGENTS.md +1 -1
- package/lab/robot-eval/workspace/opencode.json +2 -2
- package/lab/schemas/personal-event-eval.schema.json +1 -1
- package/package.json +8 -8
- package/skills/README.md +10 -7
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/SKILL.md +8 -8
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/AGENTS.template.md +1 -1
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/hosts/opencode/opencode.template.json +2 -2
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/evals/evals.json +3 -3
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/host-loading-contract.md +1 -1
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/claude-code.md +1 -1
- package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/opencode.md +2 -2
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/SKILL.md +2 -2
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/assets/eval-catalog.template.json +1 -1
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/evals/evals.json +1 -1
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/eval-topology.md +3 -3
- package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/interactive-debug-channels.md +1 -1
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/SKILL.md +2 -2
- package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/event-to-behavior.md +1 -1
- package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/COMPLETENESS.md +1 -1
- package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/SKILL.md +2 -2
- package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/config-binding.md +1 -1
- package/skills/platforms/deap/PLATFORM.md +1 -1
- package/skills/platforms/multica-dingtalk/PLATFORM.md +4 -4
- package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/SKILL.md +3 -3
- package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/SKILL.md +5 -5
- package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/bootstrap.sh +2 -2
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/REPOSITORY.template.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.dingtalk-doc.template.json +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.local.template.json +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/role-skill.template.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/agent-definition-contract.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/drive-and-schedules.md +0 -0
- /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/storage-routing.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/evidence-contract.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/failure-to-case.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/local-connector-smoke.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/scenario-taxonomy.md +0 -0
- /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/storage-modes.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/memory-candidate-proposal.json +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/task-checkpoint.json +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/action-contract.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/memory-and-evolution.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/perception-and-gates.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/risk-authority-and-privacy.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/runtime-modes.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/task-lifecycle.md +0 -0
- /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/truth-and-recovery.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/adapters.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/assembly-guidance.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/binding.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/cold-start.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/consent-and-visibility.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/consolidation.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/event-ingest.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/guided-setup.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/model.md +0 -0
- /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/storage-port.md +0 -0
- /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/multica-deployment-contract.md +0 -0
- /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/promotion-observation-contract.md +0 -0
- /package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/multica_ext.py +0 -0
|
@@ -31,7 +31,7 @@ import { runRobotEvaluation } from '../src/robot-evals.js';
|
|
|
31
31
|
import { runOpenCodeEvaluation } from '../src/opencode-evals.js';
|
|
32
32
|
import { runStorageEvaluation } from '../src/storage-evals.js';
|
|
33
33
|
import { runPersonalEventEvaluation } from '../src/personal-event-evals.js';
|
|
34
|
-
import { doctor } from '../src/doctor.js';
|
|
34
|
+
import { CHECK_LABELS, doctor } from '../src/doctor.js';
|
|
35
35
|
import { doctorDevelopmentWorkspace, inspectAgentProject, showDevelopmentWorkspace, } from '../src/development-workspace.js';
|
|
36
36
|
import { buildScheduleShow, buildSchedulePlan } from '../src/schedule-plan.js';
|
|
37
37
|
import { applyOpenCodeWorkspace, evalOpenCodeWorkspace, planOpenCodeWorkspace, runOpenCodeWorkspace, useOpenCodeWorkspace, } from '../src/opencode-provider.js';
|
|
@@ -39,7 +39,9 @@ import { inspectMulticaWorkspace, listMulticaWorkspaceResources, planMulticaWork
|
|
|
39
39
|
import { applyMulticaDeployment, listMulticaDeployments, planMulticaDeployment, runMulticaWorkspaceIssue, statusMulticaDeployment, statusMulticaWorkspaceRun, } from '../src/multica-deploy.js';
|
|
40
40
|
import { applyObservation, applyPromotion, listPromotions, planObservation, planPromotion, statusPromotion, } from '../src/promotion.js';
|
|
41
41
|
import { setup } from '../src/setup.js';
|
|
42
|
-
import { upgradeAgent } from '../src/upgrade.js';
|
|
42
|
+
import { checkUpgrade, upgradeAgent } from '../src/upgrade.js';
|
|
43
|
+
// out/err 在本文件里改名导入:printX 的形参普遍叫 out,直接同名会被遮蔽。
|
|
44
|
+
import { configureTui, confirm, displayWidth, padRight, renderPairs, StepReporter, err as stderrUi, out as stdoutUi, } from '../src/tui.js';
|
|
43
45
|
import { checkpointTask, showTaskCheckpoint } from '../src/memory/task-checkpoints.js';
|
|
44
46
|
import { upsertOperationalMemory } from '../src/memory/operational.js';
|
|
45
47
|
import { proposeMemoryCandidate, publishMemoryCandidate, reviewMemoryCandidate, showMemoryCandidate, } from '../src/memory/candidates.js';
|
|
@@ -183,13 +185,100 @@ dingtalk-agent 已验版本晋级与反馈候选
|
|
|
183
185
|
Promotion 只接受指定 suite 的 load/hard/surface gate 与精确 W2 evidence hash,并委托 W4 deploy。
|
|
184
186
|
Observe 只写 gitignored、proposed、不可直接发布的 Eval candidate;不修改 AGENTS.md、Prompt、Skill 或 Trigger。
|
|
185
187
|
`;
|
|
188
|
+
const UPGRADE_HELP = `
|
|
189
|
+
dta upgrade —— 自升级 CLI,再重新检查完整环境
|
|
190
|
+
|
|
191
|
+
用法:
|
|
192
|
+
dta upgrade 升级到当前通道的最新版本
|
|
193
|
+
dta upgrade --check 只查有没有新版本,不安装
|
|
194
|
+
dta upgrade --dry-run 只预览将执行的命令,不安装
|
|
195
|
+
dta upgrade --channel beta 指定通道(beta | latest)
|
|
196
|
+
dta upgrade --version <x.y.z> 升级到指定版本
|
|
197
|
+
dta upgrade --version <x.y.z> --force 允许降级(两者必须同时给)
|
|
198
|
+
dta upgrade --yes 跳过确认提示(AI Agent 模式)
|
|
199
|
+
dta upgrade --json 机器通道;输出 upgrade@1,不打任何进度
|
|
200
|
+
|
|
201
|
+
参数:
|
|
202
|
+
--check 只解析升级目标并对比当前版本
|
|
203
|
+
--channel <name> beta 或 latest;不给时按当前版本是否带 - 推断
|
|
204
|
+
--version <ver> 精确版本;与 --channel 互斥
|
|
205
|
+
--prefix <dir> 安装前缀,默认 ~/.local
|
|
206
|
+
--dry-run 不安装,只回报将执行的 install/verify 命令
|
|
207
|
+
--force 强制重装当前版本;配合 --version 才允许降级
|
|
208
|
+
--yes 跳过确认;非交互环境本来就不提示
|
|
209
|
+
--json 输出 JSON,不混入任何日志
|
|
210
|
+
--no-color 关闭颜色(也支持 NO_COLOR 环境变量)
|
|
211
|
+
|
|
212
|
+
升级过程分 7 步:冻结 Skill 版本 → 解析目标 → 检查版本关系 → 安装
|
|
213
|
+
→ 定位新 CLI → 校验版本 → 复核环境。前 3 步失败不会改动机器;从第 4 步
|
|
214
|
+
(安装)起失败可能留下已更新但未复核的 CLI,此时按提示重跑 setup 或
|
|
215
|
+
用 --version <旧版本> --force 回退。
|
|
216
|
+
|
|
217
|
+
非交互环境(管道 / CI / Agent 调用)不提示确认,直接执行。
|
|
218
|
+
颜色只在终端里出现;管道里想要颜色需显式 --color。
|
|
219
|
+
`;
|
|
220
|
+
/**
|
|
221
|
+
* 帮助文本的打印时装饰。**不把 ANSI 写进常量**——常量一旦带色就没法降级,
|
|
222
|
+
* 而这里 color=false 时原样返回,NO_COLOR / 管道下与改造前逐字节相同。
|
|
223
|
+
*
|
|
224
|
+
* 只染整段连续短语:命令名从行首吃到两个以上空格为止,所以
|
|
225
|
+
* `dta setup`、`dta skill status` 这类断言目标始终完整。行数不变。
|
|
226
|
+
*/
|
|
227
|
+
function renderHelp(text) {
|
|
228
|
+
const { ctx, theme } = stdoutUi();
|
|
229
|
+
if (!ctx.color)
|
|
230
|
+
return text;
|
|
231
|
+
return text.split('\n').map((line, index) => {
|
|
232
|
+
if (index === 1 && line.trim())
|
|
233
|
+
return theme.bold(line);
|
|
234
|
+
if (/^\S.*[::]$/.test(line))
|
|
235
|
+
return theme.bold(line);
|
|
236
|
+
if (/^\s+·\s/.test(line))
|
|
237
|
+
return theme.dim(line);
|
|
238
|
+
const command = line.match(/^(\s+)((?:dta|dingtalk-agent)\s\S.*?)(\s{2,})(.*)$/);
|
|
239
|
+
if (command)
|
|
240
|
+
return `${command[1]}${theme.noun(command[2])}${command[3]}${theme.dim(command[4])}`;
|
|
241
|
+
return line;
|
|
242
|
+
}).join('\n');
|
|
243
|
+
}
|
|
186
244
|
function fail(msg, code = 1, hint = '') {
|
|
187
|
-
|
|
245
|
+
// 整行染色,绝不做 danger('错误') + ': ' + msg 这种切分——
|
|
246
|
+
// 契约 eval 断言的是 stderr.includes('错误:'),切开就再也匹配不上。
|
|
247
|
+
const { theme } = stderrUi();
|
|
248
|
+
console.error(theme.danger(`错误: ${msg}`));
|
|
188
249
|
if (hint)
|
|
189
|
-
console.error(`提示: ${hint}`);
|
|
250
|
+
console.error(theme.dim(`提示: ${hint}`));
|
|
190
251
|
process.exit(code);
|
|
191
252
|
}
|
|
192
|
-
|
|
253
|
+
// --color / --no-color 在 dispatch 前预剥:parseArgs 是 strict 模式,
|
|
254
|
+
// 想让它成为全局参数就得改 23 个 options 块,预剥只需要这一处。
|
|
255
|
+
//
|
|
256
|
+
// 三条边界:`--` 之后的 token 是 positional,一律不碰;非法取值报错而不是
|
|
257
|
+
// 静默吞掉;同一参数出现多次以最后一次为准(与 parseArgs 的口径一致)。
|
|
258
|
+
const rawArgv = process.argv.slice(2);
|
|
259
|
+
const COLOR_VALUES = new Set(['auto', 'always', 'never']);
|
|
260
|
+
const terminator = rawArgv.indexOf('--');
|
|
261
|
+
const scannable = terminator === -1 ? rawArgv : rawArgv.slice(0, terminator);
|
|
262
|
+
let colorFlag = 'auto';
|
|
263
|
+
for (const item of scannable) {
|
|
264
|
+
if (item === '--no-color')
|
|
265
|
+
colorFlag = 'never';
|
|
266
|
+
else if (item === '--color')
|
|
267
|
+
colorFlag = 'always';
|
|
268
|
+
else if (item.startsWith('--color=')) {
|
|
269
|
+
const value = item.slice('--color='.length);
|
|
270
|
+
if (!COLOR_VALUES.has(value)) {
|
|
271
|
+
console.error(`错误: --color 只接受 auto | always | never,收到 ${JSON.stringify(value)}`);
|
|
272
|
+
process.exit(1);
|
|
273
|
+
}
|
|
274
|
+
colorFlag = value;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
configureTui(colorFlag);
|
|
278
|
+
const isColorToken = (item) => item === '--color' || item === '--no-color' || item.startsWith('--color=');
|
|
279
|
+
const argv = terminator === -1
|
|
280
|
+
? rawArgv.filter((item) => !isColorToken(item))
|
|
281
|
+
: [...rawArgv.slice(0, terminator).filter((item) => !isColorToken(item)), ...rawArgv.slice(terminator)];
|
|
193
282
|
const cmd = argv[0];
|
|
194
283
|
const sub = argv[1];
|
|
195
284
|
try {
|
|
@@ -202,38 +291,38 @@ catch (e) {
|
|
|
202
291
|
}
|
|
203
292
|
async function main() {
|
|
204
293
|
if (cmd === 'help' && sub === 'runtime') {
|
|
205
|
-
console.log(RUNTIME_HELP);
|
|
294
|
+
console.log(renderHelp(RUNTIME_HELP));
|
|
206
295
|
return;
|
|
207
296
|
}
|
|
208
297
|
if (cmd === 'help' && sub === 'adapters') {
|
|
209
|
-
console.log(ADAPTER_HELP);
|
|
298
|
+
console.log(renderHelp(ADAPTER_HELP));
|
|
210
299
|
return;
|
|
211
300
|
}
|
|
212
301
|
if (cmd === 'help' && sub === 'lab') {
|
|
213
|
-
console.log(LAB_HELP);
|
|
302
|
+
console.log(renderHelp(LAB_HELP));
|
|
214
303
|
return;
|
|
215
304
|
}
|
|
216
305
|
if (cmd === 'help' && sub === 'agent') {
|
|
217
|
-
console.log(AGENT_HELP);
|
|
306
|
+
console.log(renderHelp(AGENT_HELP));
|
|
218
307
|
return;
|
|
219
308
|
}
|
|
220
309
|
if (cmd === 'help' && sub === 'workspace') {
|
|
221
|
-
console.log(WORKSPACE_HELP);
|
|
310
|
+
console.log(renderHelp(WORKSPACE_HELP));
|
|
222
311
|
return;
|
|
223
312
|
}
|
|
224
313
|
if (cmd === 'help' && sub === 'deploy') {
|
|
225
|
-
console.log(DEPLOY_HELP);
|
|
314
|
+
console.log(renderHelp(DEPLOY_HELP));
|
|
226
315
|
return;
|
|
227
316
|
}
|
|
228
317
|
if (cmd === 'help' && ['promote', 'observe'].includes(sub || '')) {
|
|
229
|
-
console.log(PROMOTION_HELP);
|
|
318
|
+
console.log(renderHelp(PROMOTION_HELP));
|
|
230
319
|
return;
|
|
231
320
|
}
|
|
232
321
|
if (cmd === 'help' && sub) {
|
|
233
322
|
fail(`不认识的帮助主题: ${sub}`, 1, '运行 dta --help 回到产品入口;事件宿主可用 dta help runtime。');
|
|
234
323
|
}
|
|
235
324
|
if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {
|
|
236
|
-
console.log(HELP);
|
|
325
|
+
console.log(renderHelp(HELP));
|
|
237
326
|
return;
|
|
238
327
|
}
|
|
239
328
|
if (cmd === '--version' || cmd === '-V' || cmd === 'version') {
|
|
@@ -437,23 +526,23 @@ async function main() {
|
|
|
437
526
|
return;
|
|
438
527
|
}
|
|
439
528
|
if (out.count === 0) {
|
|
440
|
-
console.log('本 Project 未声明任何常驻节律(schedules)。');
|
|
529
|
+
console.log(muted('本 Project 未声明任何常驻节律(schedules)。'));
|
|
441
530
|
return;
|
|
442
531
|
}
|
|
443
|
-
console.log(
|
|
532
|
+
console.log(`${strong('声明的常驻节律(internalized cron)')} · ${out.count} 条`);
|
|
444
533
|
for (const s of out.schedules) {
|
|
445
|
-
console.log(`\n ${s.name} ${s.cron} ${s.timezone} [${s.mode}]`);
|
|
534
|
+
console.log(`\n ${noun(s.name)} ${s.cron} ${s.timezone} ${muted(`[${s.mode}]`)}`);
|
|
446
535
|
if (s.wake)
|
|
447
|
-
console.log(` 唤醒 ${s.wake}`);
|
|
536
|
+
console.log(muted(` 唤醒 ${s.wake}`));
|
|
448
537
|
if (s.completion)
|
|
449
|
-
console.log(` ②判据 ${s.completion}`);
|
|
538
|
+
console.log(muted(` ②判据 ${s.completion}`));
|
|
450
539
|
}
|
|
451
540
|
if (!out.minutesDistinct) {
|
|
452
|
-
console.log(`\n
|
|
541
|
+
console.log(`\n${mark('warn', `⚠️ 分钟位冲突: ${out.collidingMinutes.join(', ')} —— 外发类同分钟并发会重复送,请错开`)}`);
|
|
453
542
|
process.exitCode = 2;
|
|
454
543
|
}
|
|
455
544
|
else {
|
|
456
|
-
console.log('
|
|
545
|
+
console.log(`\n${mark('pass', '✓ 各节律分钟位互不相同(外发防重复的静态前提满足)')}`);
|
|
457
546
|
}
|
|
458
547
|
return;
|
|
459
548
|
}
|
|
@@ -467,17 +556,17 @@ async function main() {
|
|
|
467
556
|
console.log(JSON.stringify(plan, null, 2));
|
|
468
557
|
return;
|
|
469
558
|
}
|
|
470
|
-
console.log(
|
|
559
|
+
console.log(`${strong('schedule 部署计划')} · workspace=${noun(plan.workspace)} · provider=${plan.provider}`);
|
|
471
560
|
if (!plan.supported) {
|
|
472
|
-
console.log(`\n
|
|
473
|
-
console.log(` ${plan.reconcile}`);
|
|
561
|
+
console.log(`\n${mark('fail', `✗ 不支持: ${plan.reason}`)}`);
|
|
562
|
+
console.log(` ${noun(plan.reconcile)}`);
|
|
474
563
|
process.exitCode = 2;
|
|
475
564
|
return;
|
|
476
565
|
}
|
|
477
566
|
console.log(` ${plan.count} 条声明 → provider ops:\n`);
|
|
478
567
|
for (const s of plan.schedules)
|
|
479
|
-
console.log(`
|
|
480
|
-
console.log(`执行: ${plan.reconcile}`);
|
|
568
|
+
console.log(` ${muted(`# ${s.name}`)}\n ${noun(s.applyCommand)}\n`);
|
|
569
|
+
console.log(`执行: ${noun(plan.reconcile)}`);
|
|
481
570
|
return;
|
|
482
571
|
}
|
|
483
572
|
fail(`可用: dta schedule show | plan --workspace <name>${suggest(sub || '', ['show', 'plan'], 'dta schedule')}`);
|
|
@@ -670,7 +759,7 @@ async function main() {
|
|
|
670
759
|
if (o.json)
|
|
671
760
|
console.log(JSON.stringify(out, null, 2));
|
|
672
761
|
else
|
|
673
|
-
console.log(
|
|
762
|
+
console.log(`${mark('pass', '✅')} current workspace: ${muted(out.previous || '-')} → ${noun(out.current)}`);
|
|
674
763
|
return;
|
|
675
764
|
}
|
|
676
765
|
if (sub === 'run') {
|
|
@@ -716,19 +805,19 @@ async function main() {
|
|
|
716
805
|
if (o.json)
|
|
717
806
|
console.log(JSON.stringify(out, null, 2));
|
|
718
807
|
else if (out.$schema === 'dingtalk-agent/opencode-workspace-run-plan@1') {
|
|
719
|
-
console.log(
|
|
808
|
+
console.log(`${mark('muted', 'DRY-RUN')} workspace=${noun(out.workspace)} model=${out.model} prompt=${out.promptHash}`);
|
|
720
809
|
}
|
|
721
810
|
else if (out.$schema === 'dingtalk-agent/multica-workspace-run-plan@1') {
|
|
722
|
-
console.log(
|
|
811
|
+
console.log(`${mark('muted', 'DRY-RUN')} workspace=${noun(out.workspace)} agent=${out.agentId || '-'} prompt=${out.promptHash}`);
|
|
723
812
|
}
|
|
724
813
|
else {
|
|
725
|
-
console.log(`${out.passed ? '✅' : '❌'} workspace run ${out.runId}`);
|
|
814
|
+
console.log(`${mark(levelOf(Boolean(out.passed)), out.passed ? '✅' : '❌')} workspace run ${noun(out.runId)}`);
|
|
726
815
|
if ('execution' in out && out.execution?.answer)
|
|
727
816
|
console.log(out.execution.answer);
|
|
728
817
|
if ('answer' in out && out.answer)
|
|
729
818
|
console.log(out.answer);
|
|
730
819
|
if (out.evidencePath)
|
|
731
|
-
console.log(`evidence=${out.evidencePath}`);
|
|
820
|
+
console.log(`evidence=${noun(out.evidencePath)}`);
|
|
732
821
|
}
|
|
733
822
|
if (o.execute && !out.passed)
|
|
734
823
|
process.exitCode = 2;
|
|
@@ -797,23 +886,72 @@ async function main() {
|
|
|
797
886
|
return;
|
|
798
887
|
}
|
|
799
888
|
if (cmd === 'upgrade') {
|
|
889
|
+
// parseArgs strict 模式会把 --help 当成未知参数抛掉,必须先拦。
|
|
890
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
891
|
+
console.log(renderHelp(UPGRADE_HELP));
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
800
894
|
const { values: o } = parseArgs({
|
|
801
895
|
args: argv.slice(1),
|
|
802
896
|
options: {
|
|
803
897
|
channel: { type: 'string' }, version: { type: 'string' }, prefix: { type: 'string' },
|
|
804
898
|
'dry-run': { type: 'boolean' }, force: { type: 'boolean' }, json: { type: 'boolean' },
|
|
899
|
+
check: { type: 'boolean' }, yes: { type: 'boolean' },
|
|
805
900
|
},
|
|
806
901
|
});
|
|
807
|
-
const
|
|
808
|
-
|
|
809
|
-
|
|
902
|
+
const channel = o.channel;
|
|
903
|
+
const json = Boolean(o.json);
|
|
904
|
+
if (o.check) {
|
|
905
|
+
if (o['dry-run'] || o.force || o.prefix || o.yes) {
|
|
906
|
+
fail('upgrade --check 只接受 --channel / --version / --json');
|
|
907
|
+
}
|
|
908
|
+
const checked = checkUpgrade(PACKAGE_ROOT, { channel, version: o.version });
|
|
909
|
+
if (json)
|
|
910
|
+
console.log(JSON.stringify(checked, null, 2));
|
|
911
|
+
else
|
|
912
|
+
printUpgradeCheck(checked);
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
// --json 是机器通道:结构性绕开 tui,连回调都不构造。
|
|
916
|
+
// 非交互(管道/CI/Agent)也不提示,保持"敲下去就装"的既有行为。
|
|
917
|
+
const interactive = !json && Boolean(process.stdin.isTTY);
|
|
918
|
+
let known = null;
|
|
919
|
+
if (interactive) {
|
|
920
|
+
known = checkUpgrade(PACKAGE_ROOT, { channel, version: o.version });
|
|
921
|
+
printUpgradePreamble(known, { dryRun: Boolean(o['dry-run']), force: Boolean(o.force) });
|
|
922
|
+
const proceed = await confirm(o['dry-run'] ? '是否预览升级?' : '是否升级?', { yes: Boolean(o.yes), fallback: true });
|
|
923
|
+
if (!proceed) {
|
|
924
|
+
console.error(stderrUi().theme.dim(' 已取消'));
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
const reporter = json ? null : new StepReporter({ total: o['dry-run'] ? 3 : 7 });
|
|
929
|
+
const result = upgradeAgent(PACKAGE_ROOT, {
|
|
930
|
+
channel, version: o.version, prefix: o.prefix,
|
|
810
931
|
dryRun: o['dry-run'], force: o.force,
|
|
932
|
+
// 已经解析过就别再问一次 registry;**同时把安装源钉死到精确版本**——
|
|
933
|
+
// 只冻结期望版本而仍按 `pkg@latest` 安装,会在用户思考的这几秒里
|
|
934
|
+
// 被移动的 tag 装进另一个版本,然后按旧期望校验失败,而机器已经改了。
|
|
935
|
+
env: known
|
|
936
|
+
? {
|
|
937
|
+
DTA_UPGRADE_TARGET_VERSION: known.targetVersion,
|
|
938
|
+
DTA_UPGRADE_PACKAGE_SOURCE: known.pinnedSource,
|
|
939
|
+
}
|
|
940
|
+
: undefined,
|
|
941
|
+
onEvent: reporter
|
|
942
|
+
? (event) => {
|
|
943
|
+
if (event.phase === 'begin')
|
|
944
|
+
reporter.begin(event.label);
|
|
945
|
+
else
|
|
946
|
+
reporter.end(event.ok !== false, event.meta || '');
|
|
947
|
+
}
|
|
948
|
+
: undefined,
|
|
811
949
|
});
|
|
812
|
-
if (
|
|
813
|
-
console.log(JSON.stringify(
|
|
950
|
+
if (json)
|
|
951
|
+
console.log(JSON.stringify(result, null, 2));
|
|
814
952
|
else
|
|
815
|
-
printUpgrade(
|
|
816
|
-
if (!
|
|
953
|
+
printUpgrade(result);
|
|
954
|
+
if (!result.dryRun && !result.ready)
|
|
817
955
|
process.exitCode = 2;
|
|
818
956
|
return;
|
|
819
957
|
}
|
|
@@ -856,9 +994,14 @@ async function main() {
|
|
|
856
994
|
}
|
|
857
995
|
if (o.json)
|
|
858
996
|
console.log(JSON.stringify(out, null, 2));
|
|
859
|
-
else if ('skills' in out)
|
|
997
|
+
else if ('skills' in out) {
|
|
860
998
|
for (const item of out.skills)
|
|
861
999
|
printSkillStatus(item, sub, dryRun);
|
|
1000
|
+
// 静默删目录会让人以为什么都没发生;说清楚删了哪几个旧名。
|
|
1001
|
+
for (const item of out.prunedLegacy || []) {
|
|
1002
|
+
console.log(` 已清理改名前的旧副本 ${item.name} → 现用 ${item.replacedBy}`);
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
862
1005
|
else
|
|
863
1006
|
printSkillStatus(out, sub, dryRun);
|
|
864
1007
|
return;
|
|
@@ -913,7 +1056,7 @@ async function main() {
|
|
|
913
1056
|
if (o.json)
|
|
914
1057
|
console.log(JSON.stringify({ ...out, endpoint, readiness, targets, doc }, null, 2));
|
|
915
1058
|
else {
|
|
916
|
-
console.log(
|
|
1059
|
+
console.log(`${mark('pass', '✅')} 工作区已归属 ${strong(out.definition?.label)}(写入 ${noun(out.written)})`);
|
|
917
1060
|
for (const install of out.skillInstalls)
|
|
918
1061
|
printSkillStatus(install, 'install', false);
|
|
919
1062
|
if (!out.skillInstalls.length) {
|
|
@@ -953,14 +1096,14 @@ async function main() {
|
|
|
953
1096
|
if (o.json)
|
|
954
1097
|
console.log(JSON.stringify(out, null, 2));
|
|
955
1098
|
else {
|
|
956
|
-
console.log(
|
|
1099
|
+
console.log(`${mark('pass', '✅')} ${strong(out.mode === 'workspace' ? '已装载 Workspace' : '直接会话模式')}`);
|
|
957
1100
|
console.log(` scope=${out.scopeId} initialized=${out.initialized}`);
|
|
958
1101
|
console.log(` agent=${out.definition.id} definition=${out.definition.status}`);
|
|
959
1102
|
if (!out.mounts.length)
|
|
960
|
-
console.log(' 没有发现持久上下文;这不是错误,也不需要自动 init。');
|
|
1103
|
+
console.log(muted(' 没有发现持久上下文;这不是错误,也不需要自动 init。'));
|
|
961
1104
|
for (const mount of out.mounts)
|
|
962
|
-
console.log(` ${mount.slot}: ${mount.path}`);
|
|
963
|
-
console.log(` ${out.note}`);
|
|
1105
|
+
console.log(` ${mount.slot}: ${noun(mount.path)}`);
|
|
1106
|
+
console.log(` ${muted(out.note)}`);
|
|
964
1107
|
}
|
|
965
1108
|
return;
|
|
966
1109
|
}
|
|
@@ -1346,9 +1489,9 @@ async function main() {
|
|
|
1346
1489
|
if (o.json)
|
|
1347
1490
|
console.log(JSON.stringify(out, null, 2));
|
|
1348
1491
|
else if (!out.found)
|
|
1349
|
-
console.log('当前 Session 尚无 Task checkpoint。');
|
|
1492
|
+
console.log(muted('当前 Session 尚无 Task checkpoint。'));
|
|
1350
1493
|
else {
|
|
1351
|
-
console.log(
|
|
1494
|
+
console.log(`${mark('pass', '✅')} Task ${noun(out.checkpoint.taskId)} · ${out.checkpoint.status}`);
|
|
1352
1495
|
console.log(` revision=${out.checkpoint.revision} hash=${out.hash}`);
|
|
1353
1496
|
console.log(` next=${out.checkpoint.nextAction || '-'}`);
|
|
1354
1497
|
}
|
|
@@ -1373,7 +1516,7 @@ async function main() {
|
|
|
1373
1516
|
if (o.json || !o.live)
|
|
1374
1517
|
console.log(JSON.stringify(out, null, 2));
|
|
1375
1518
|
else {
|
|
1376
|
-
console.log(`${out.verified ? '✅' : '⚠️'} Operational Memory · ${out.mode}`);
|
|
1519
|
+
console.log(`${mark(out.verified ? 'pass' : 'warn', out.verified ? '✅' : '⚠️')} ${strong('Operational Memory')} · ${out.mode}`);
|
|
1377
1520
|
console.log(` record=${out.recordId || '-'} verification=${out.verification}`);
|
|
1378
1521
|
}
|
|
1379
1522
|
if (out.mode === 'uncertain')
|
|
@@ -1427,12 +1570,12 @@ async function main() {
|
|
|
1427
1570
|
if (o.json)
|
|
1428
1571
|
console.log(JSON.stringify(out, null, 2));
|
|
1429
1572
|
else if (action === 'publish') {
|
|
1430
|
-
console.log(`${out.verified ? '✅' : out.mode === 'dry-run' ? '🔎' : '⚠️'} Candidate ${o.id}`);
|
|
1573
|
+
console.log(`${mark(out.verified ? 'pass' : out.mode === 'dry-run' ? 'muted' : 'warn', out.verified ? '✅' : out.mode === 'dry-run' ? '🔎' : '⚠️')} Candidate ${noun(o.id)}`);
|
|
1431
1574
|
console.log(` mode=${out.mode} targetHash=${out.currentTargetHash}`);
|
|
1432
1575
|
}
|
|
1433
1576
|
else {
|
|
1434
|
-
console.log(
|
|
1435
|
-
console.log(` revision=${out.candidate.revision} path=${out.path}`);
|
|
1577
|
+
console.log(`${mark('pass', '✅')} Candidate ${noun(out.candidate.id)} · ${out.candidate.status}`);
|
|
1578
|
+
console.log(` revision=${out.candidate.revision} path=${noun(out.path)}`);
|
|
1436
1579
|
}
|
|
1437
1580
|
if (action === 'publish' && out.mode === 'uncertain')
|
|
1438
1581
|
process.exitCode = 2;
|
|
@@ -1463,10 +1606,10 @@ async function main() {
|
|
|
1463
1606
|
if (o.json || o['dry-run'])
|
|
1464
1607
|
console.log(JSON.stringify(out, null, 2));
|
|
1465
1608
|
else {
|
|
1466
|
-
console.log(`${out.verified ? '✅' : '⚠️'} ${out.kind} · ${out.outcome} · ${out.toState}`);
|
|
1467
|
-
console.log(` action=${out.actionId} run=${out.runId}`);
|
|
1609
|
+
console.log(`${mark(out.verified ? 'pass' : 'warn', out.verified ? '✅' : '⚠️')} ${strong(out.kind)} · ${out.outcome} · ${out.toState}`);
|
|
1610
|
+
console.log(` action=${noun(out.actionId)} run=${noun(out.runId)}`);
|
|
1468
1611
|
if (!out.verified)
|
|
1469
|
-
console.log(` ${out.verification}`);
|
|
1612
|
+
console.log(` ${muted(out.verification)}`);
|
|
1470
1613
|
}
|
|
1471
1614
|
if (out.outcome === 'uncertain')
|
|
1472
1615
|
process.exitCode = 2;
|
|
@@ -1538,11 +1681,41 @@ function editDistance(a, b) {
|
|
|
1538
1681
|
}
|
|
1539
1682
|
return row[b.length];
|
|
1540
1683
|
}
|
|
1684
|
+
/** 按语义给状态标记上色;字形原样返回,不做任何替换。 */
|
|
1685
|
+
function mark(level, text) {
|
|
1686
|
+
const { theme } = stdoutUi();
|
|
1687
|
+
return level === 'pass' ? theme.success(text)
|
|
1688
|
+
: level === 'warn' ? theme.warn(text)
|
|
1689
|
+
: level === 'fail' ? theme.danger(text)
|
|
1690
|
+
: theme.dim(text);
|
|
1691
|
+
}
|
|
1692
|
+
/** 可复制的名词:路径、版本号、ID、命令。 */
|
|
1693
|
+
function noun(text) {
|
|
1694
|
+
return stdoutUi().theme.noun(text);
|
|
1695
|
+
}
|
|
1696
|
+
/** 次要信息:补充说明、括注、下一步提示。 */
|
|
1697
|
+
function muted(text) {
|
|
1698
|
+
return stdoutUi().theme.dim(text);
|
|
1699
|
+
}
|
|
1700
|
+
/** 标题行 / key=value 的结构性强调。 */
|
|
1701
|
+
function strong(text) {
|
|
1702
|
+
return stdoutUi().theme.bold(text);
|
|
1703
|
+
}
|
|
1704
|
+
/** ready 布尔 → 语义级别,printX 里到处都是这个三态。 */
|
|
1705
|
+
function levelOf(state) {
|
|
1706
|
+
if (state === true)
|
|
1707
|
+
return 'pass';
|
|
1708
|
+
if (state === false)
|
|
1709
|
+
return 'fail';
|
|
1710
|
+
return state;
|
|
1711
|
+
}
|
|
1541
1712
|
function printDispatch(out, json = false) {
|
|
1542
1713
|
if (json)
|
|
1543
1714
|
return console.log(JSON.stringify(out, null, 2));
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1715
|
+
const state = out.duplicate
|
|
1716
|
+
? mark(out.launch ? 'warn' : 'muted', out.launch ? '🔁 REDELIVER' : '↩️ DUPLICATE')
|
|
1717
|
+
: mark('pass', '✅ READY');
|
|
1718
|
+
console.log(`${state} ${noun(out.runId)}`);
|
|
1546
1719
|
console.log(` Field=${out.fieldId} Session=${out.sessionId} Event=${out.eventKind}`);
|
|
1547
1720
|
console.log(` cwd=${out.cwd}`);
|
|
1548
1721
|
console.log(` entrypoint=${out.entrypoint} queue=${out.queue.key} (max=${out.queue.maxConcurrency})`);
|
|
@@ -1552,7 +1725,7 @@ function printDispatch(out, json = false) {
|
|
|
1552
1725
|
}
|
|
1553
1726
|
function printLab(out) {
|
|
1554
1727
|
const passed = out.ready ?? out.passed ?? out.assertions?.passed;
|
|
1555
|
-
console.log(`${passed === false ? '❌' : '✅'} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1728
|
+
console.log(`${mark(levelOf(passed !== false), passed === false ? '❌' : '✅')} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1556
1729
|
if (out.mode)
|
|
1557
1730
|
console.log(` mode=${out.mode}`);
|
|
1558
1731
|
if (out.marker)
|
|
@@ -1561,17 +1734,17 @@ function printLab(out) {
|
|
|
1561
1734
|
console.log(` evidence=${out.evidencePath}`);
|
|
1562
1735
|
if (Array.isArray(out.checks)) {
|
|
1563
1736
|
for (const check of out.checks) {
|
|
1564
|
-
console.log(` ${check.passed ? 'PASS' : 'FAIL'} ${check.id}: ${check.detail}`);
|
|
1737
|
+
console.log(` ${mark(levelOf(Boolean(check.passed)), check.passed ? 'PASS' : 'FAIL')} ${check.id}: ${check.detail}`);
|
|
1565
1738
|
}
|
|
1566
1739
|
}
|
|
1567
1740
|
}
|
|
1568
1741
|
function printAgentAudit(out) {
|
|
1569
|
-
console.log(
|
|
1742
|
+
console.log(`${strong('dingtalk-agent agent audit')} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1570
1743
|
console.log(` definition=${out.definition.hash} storage=${out.storageMode}`);
|
|
1571
1744
|
console.log(` dingtalkSideEffect=${out.dingtalkSideEffect} sideEffect=${out.sideEffect}`);
|
|
1572
1745
|
for (const check of out.checks) {
|
|
1573
|
-
const
|
|
1574
|
-
console.log(` ${mark} ${check.id}: ${check.summary}`);
|
|
1746
|
+
const word = check.level === 'pass' ? 'PASS' : check.level === 'warn' ? 'WARN' : 'FAIL';
|
|
1747
|
+
console.log(` ${mark(levelOf(check.level), word)} ${check.id}: ${check.summary}`);
|
|
1575
1748
|
}
|
|
1576
1749
|
if (out.repairs.length) {
|
|
1577
1750
|
console.log('\n修复建议:');
|
|
@@ -1584,7 +1757,7 @@ function printAgentAudit(out) {
|
|
|
1584
1757
|
}
|
|
1585
1758
|
function printAgentEnhance(out) {
|
|
1586
1759
|
if (out.$schema === 'dingtalk-agent/agent-enhancement-plan@1') {
|
|
1587
|
-
console.log(
|
|
1760
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY PLAN' : 'BLOCKED')}`);
|
|
1588
1761
|
console.log(` planId=${out.planId} project=${out.projectName}`);
|
|
1589
1762
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1590
1763
|
for (const operation of out.operations) {
|
|
@@ -1594,12 +1767,12 @@ function printAgentEnhance(out) {
|
|
|
1594
1767
|
console.log(` REVIEW ${out.semanticReview.files.join(', ')}: ${out.semanticReview.why}`);
|
|
1595
1768
|
}
|
|
1596
1769
|
for (const blocker of out.blockers)
|
|
1597
|
-
console.log(` BLOCK ${blocker}`);
|
|
1770
|
+
console.log(` ${mark('fail', 'BLOCK')} ${blocker}`);
|
|
1598
1771
|
if (out.ready)
|
|
1599
1772
|
console.log(`\nApply:\n ${out.apply.command}`);
|
|
1600
1773
|
return;
|
|
1601
1774
|
}
|
|
1602
|
-
console.log('dingtalk-agent agent enhance · APPLIED');
|
|
1775
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark('pass', 'APPLIED')}`);
|
|
1603
1776
|
console.log(` operation=${out.operationId} planId=${out.planId}`);
|
|
1604
1777
|
console.log(` changes=${out.changes.length} idempotent=${out.idempotent}`);
|
|
1605
1778
|
if (out.backupRoot)
|
|
@@ -1607,8 +1780,8 @@ function printAgentEnhance(out) {
|
|
|
1607
1780
|
console.log(` audit=${out.audit.status} missing=${out.audit.missing.join(', ') || '-'}`);
|
|
1608
1781
|
}
|
|
1609
1782
|
function printAgentPlatform(platform) {
|
|
1610
|
-
console.log(`${platform.status === 'supported' ? '✅' : '⏳'} ${platform.name} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
|
|
1611
|
-
console.log(` ${platform.description}`);
|
|
1783
|
+
console.log(`${mark(platform.status === 'supported' ? 'pass' : 'muted', platform.status === 'supported' ? '✅' : '⏳')} ${strong(platform.name)} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
|
|
1784
|
+
console.log(` ${muted(platform.description)}`);
|
|
1612
1785
|
for (const skill of platform.skills)
|
|
1613
1786
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
1614
1787
|
if (platform.commands.length)
|
|
@@ -1616,12 +1789,12 @@ function printAgentPlatform(platform) {
|
|
|
1616
1789
|
}
|
|
1617
1790
|
function printAgentPlatformResolution(out) {
|
|
1618
1791
|
if (!out.platform) {
|
|
1619
|
-
console.log('⚠️ 当前工作区未声明 managed agent platform');
|
|
1792
|
+
console.log(mark('warn', '⚠️ 当前工作区未声明 managed agent platform'));
|
|
1620
1793
|
console.log(' 运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。');
|
|
1621
1794
|
return;
|
|
1622
1795
|
}
|
|
1623
1796
|
const known = out.definition;
|
|
1624
|
-
console.log(`${known ? '✅' : '❌'} 当前 platform: ${out.platform}${known ? ` · ${known.label} · ${platformStatusLabel(known.status)}` : '(未知)'}`);
|
|
1797
|
+
console.log(`${mark(levelOf(Boolean(known)), known ? '✅' : '❌')} 当前 platform: ${strong(out.platform)}${known ? ` · ${known.label} · ${platformStatusLabel(known.status)}` : '(未知)'}`);
|
|
1625
1798
|
console.log(` 来源: ${out.source}${out.file ? ` · ${out.file}` : ''}`);
|
|
1626
1799
|
for (const skill of known?.skills || [])
|
|
1627
1800
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
@@ -1629,8 +1802,9 @@ function printAgentPlatformResolution(out) {
|
|
|
1629
1802
|
// 披露:dta 层平台命令关联到平台内确切的 Skill(诊断信息走 stderr,不污染 --json stdout)。
|
|
1630
1803
|
function disclosePlatformSkill(resolution, role) {
|
|
1631
1804
|
const skillName = resolution.definition ? platformSkillForRole(resolution.definition.name, role) : null;
|
|
1632
|
-
if (skillName)
|
|
1633
|
-
console.error(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`);
|
|
1805
|
+
if (skillName) {
|
|
1806
|
+
console.error(stderrUi().theme.dim(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`));
|
|
1807
|
+
}
|
|
1634
1808
|
}
|
|
1635
1809
|
function printEndpoint(endpoint) {
|
|
1636
1810
|
if (!endpoint)
|
|
@@ -1644,9 +1818,9 @@ function printEndpoint(endpoint) {
|
|
|
1644
1818
|
console.log(` Endpoint: 未解析——设 ${endpoint.envVar} 或登录 multica 后生效`);
|
|
1645
1819
|
return;
|
|
1646
1820
|
}
|
|
1647
|
-
const
|
|
1821
|
+
const glyph = mark(endpoint.confirmed ? 'pass' : 'warn', endpoint.confirmed ? '✅' : '⚠️');
|
|
1648
1822
|
const note = endpoint.confirmed ? '' : '(建议/未确认,deploy 前需显式确认是预发还是生产)';
|
|
1649
|
-
console.log(` ${
|
|
1823
|
+
console.log(` ${glyph} Endpoint: ${noun(endpoint.endpoint)} · 来源: ${endpoint.source}${muted(note)}`);
|
|
1650
1824
|
console.log(` (切换:设 ${endpoint.envVar}=<url>、写 dingtalk-agent.json#multicaEndpoint、或登录对应 profile;无需改代码)`);
|
|
1651
1825
|
}
|
|
1652
1826
|
function printPlatformDoc(platformName) {
|
|
@@ -1654,27 +1828,27 @@ function printPlatformDoc(platformName) {
|
|
|
1654
1828
|
return;
|
|
1655
1829
|
const path = platformDocPath(PACKAGE_ROOT, platformName);
|
|
1656
1830
|
if (path)
|
|
1657
|
-
console.log(` 平台说明: ${path}\n
|
|
1831
|
+
console.log(` 平台说明: ${noun(path)}\n${muted(' (切换到该平台后请阅读,了解各技能用途与交付链)')}`);
|
|
1658
1832
|
}
|
|
1659
1833
|
function printMulticaTargets(targets) {
|
|
1660
1834
|
if (!targets.length)
|
|
1661
1835
|
return;
|
|
1662
|
-
console.log(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):');
|
|
1836
|
+
console.log(strong(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):'));
|
|
1663
1837
|
for (const target of targets) {
|
|
1664
1838
|
console.log(` - profile=${target.profile} · ${target.serverUrl}${target.workspaceId ? ` · workspace=${target.workspaceId}` : ''}`);
|
|
1665
1839
|
}
|
|
1666
1840
|
}
|
|
1667
1841
|
function printAgentPlatformReadiness(checks) {
|
|
1668
1842
|
for (const check of checks) {
|
|
1669
|
-
console.log(` ${check.ok ? '✅' : '⚠️'} ${check.summary}`);
|
|
1843
|
+
console.log(` ${mark(check.ok ? 'pass' : 'warn', check.ok ? '✅' : '⚠️')} ${check.summary}`);
|
|
1670
1844
|
if (check.hint)
|
|
1671
|
-
console.log(` ${check.hint}`);
|
|
1845
|
+
console.log(` ${muted(check.hint)}`);
|
|
1672
1846
|
}
|
|
1673
1847
|
}
|
|
1674
1848
|
function printSkillStatus(out, action, dryRun) {
|
|
1675
|
-
const prefix = dryRun ? 'DRY-RUN' : '✅';
|
|
1849
|
+
const prefix = dryRun ? mark('muted', 'DRY-RUN') : mark('pass', '✅');
|
|
1676
1850
|
const verb = action === 'status' ? '全局 Skill 状态' : `skill ${action}`;
|
|
1677
|
-
console.log(`${prefix} ${verb}: ${out.name}`);
|
|
1851
|
+
console.log(`${prefix} ${verb}: ${strong(out.name)}`);
|
|
1678
1852
|
console.log(` manager=${out.manager} bundled=${out.bundled.skillVersion || '-'}`);
|
|
1679
1853
|
console.log(` canonical=${out.canonical.path}`);
|
|
1680
1854
|
console.log(` installed=${out.canonical.exists} ` +
|
|
@@ -1685,71 +1859,110 @@ function printSkillStatus(out, action, dryRun) {
|
|
|
1685
1859
|
` → ${out.operation.after.installedVersion}(${out.operation.after.state})`);
|
|
1686
1860
|
}
|
|
1687
1861
|
if (out.operation)
|
|
1688
|
-
console.log(` delegated: ${out.operation.command}`);
|
|
1862
|
+
console.log(` delegated: ${noun(out.operation.command)}`);
|
|
1689
1863
|
for (const client of out.clients) {
|
|
1690
|
-
console.log(` ${client.label}=${client.state} (${client.discovery}: ${client.path})`);
|
|
1864
|
+
console.log(` ${client.label}=${mark(client.state === 'ok' ? 'pass' : 'warn', client.state)} (${client.discovery}: ${noun(client.path)})`);
|
|
1691
1865
|
}
|
|
1692
1866
|
if (action === 'install' && !dryRun) {
|
|
1693
|
-
console.log(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。');
|
|
1867
|
+
console.log(muted(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。'));
|
|
1694
1868
|
}
|
|
1695
1869
|
}
|
|
1870
|
+
/**
|
|
1871
|
+
* doctor 的版面。改造前的问题不是"不够花哨",是三条实打实的:
|
|
1872
|
+
* 1. 同一事实说两遍——⚠️ 摘要和它的 detail 重复平台 Skill 漂移;三个客户端
|
|
1873
|
+
* 的 Skill 可见性在 check 区和「本机 Coding Agent」区各说一次。
|
|
1874
|
+
* 2. 一行塞太多——detail 用 ` | ` 把四条 canonical 路径和平台 Skill 状态拼在
|
|
1875
|
+
* 一起,200+ 字符,终端里必然折行。
|
|
1876
|
+
* 3. 分隔符混用 `·` `;` `|` 三种,没有一列是对齐的。
|
|
1877
|
+
* 所以这里按「一行一件事、明细缩进、列对齐」重排,并把客户端合并成一节。
|
|
1878
|
+
*/
|
|
1696
1879
|
function printDoctor(out) {
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1880
|
+
const { theme } = stdoutUi();
|
|
1881
|
+
// 字形沿用全 CLI 既定的 ✅/⚠️/❌(bin 里各出现 24/11/5 次)。上一版换成
|
|
1882
|
+
// ✔/!/✗ 让 doctor 成了唯一的异类,也违反 AGENTS.md「stdout 是稳定的人/
|
|
1883
|
+
// 机器接口」——颜色可以加,承载语义的字形不能动。三者都是 2 列宽,对齐不受影响。
|
|
1884
|
+
const glyph = (level) => level === 'pass' ? mark('pass', '✅')
|
|
1885
|
+
: level === 'warn' ? mark('warn', '⚠️') : mark('fail', '❌');
|
|
1886
|
+
const clientIds = new Set(['claude-code', 'codex', 'opencode']);
|
|
1887
|
+
const envChecks = out.checks.filter((check) => !clientIds.has(check.id));
|
|
1888
|
+
const clientChecks = out.checks.filter((check) => clientIds.has(check.id));
|
|
1889
|
+
console.log(`${strong('dingtalk-agent doctor')} · ${out.ready ? mark('pass', 'READY') : mark('fail', 'NOT READY')}`);
|
|
1890
|
+
console.log('');
|
|
1891
|
+
// 左列按显示宽度对齐——中文标签用 String.length 补齐必然错位
|
|
1892
|
+
const labelWidth = Math.max(...envChecks.map((check) => displayWidth(CHECK_LABELS[check.id])));
|
|
1893
|
+
for (const check of envChecks) {
|
|
1894
|
+
const label = padRight(CHECK_LABELS[check.id], labelWidth);
|
|
1895
|
+
console.log(` ${glyph(check.level)} ${strong(label)} ${check.value || check.summary}`);
|
|
1896
|
+
const items = check.items || [];
|
|
1897
|
+
const itemWidth = items.length ? Math.max(...items.map((i) => displayWidth(i.label))) : 0;
|
|
1898
|
+
const valueWidth = items.length ? Math.max(...items.map((i) => displayWidth(i.value || ''))) : 0;
|
|
1899
|
+
for (const item of items) {
|
|
1900
|
+
console.log(` ${noun(padRight(item.label, itemWidth))} ${padRight(item.value || '', valueWidth)}${item.note ? ` ${muted(item.note)}` : ''}`);
|
|
1901
|
+
}
|
|
1902
|
+
if (check.level !== 'pass' && check.fix) {
|
|
1903
|
+
// 一条命令一行。挤在同一行里用「与」串起来的命令没法直接复制。
|
|
1904
|
+
const commands = plain(check.fix).replace(/^运行\s*/, '').split(/\s*与\s*/);
|
|
1905
|
+
commands.forEach((command, index) => {
|
|
1906
|
+
console.log(` ${muted(index === 0 ? '修复' : ' ')} ${noun(command)}`);
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
if (clientChecks.length) {
|
|
1911
|
+
console.log('');
|
|
1912
|
+
console.log(` ${strong('Coding Agent')}`);
|
|
1913
|
+
const nameWidth = Math.max(...clientChecks.map((c) => displayWidth(CHECK_LABELS[c.id])));
|
|
1914
|
+
const hostOf = (id) => out.hosts.find((host) => host.name === id);
|
|
1915
|
+
// 版本列去掉冗余括注与前缀:claude 报 "2.1.218 (Claude Code)"、codex 报 "codex-cli 0.144.6"
|
|
1916
|
+
const versions = clientChecks.map((c) => (hostOf(c.id)?.cli.version || '')
|
|
1917
|
+
.replace(/\s*\(.*\)\s*$/, '').replace(/^\S+-cli\s+/, ''));
|
|
1918
|
+
const versionWidth = Math.max(...versions.map(displayWidth));
|
|
1919
|
+
clientChecks.forEach((check, index) => {
|
|
1920
|
+
const host = hostOf(check.id);
|
|
1921
|
+
const name = padRight(CHECK_LABELS[check.id], nameWidth);
|
|
1922
|
+
const version = padRight(versions[index], versionWidth);
|
|
1923
|
+
const where = host?.cli.found ? tilde(host.skillExposureRoot) : `未安装 ${host?.cli.command || ''}`;
|
|
1924
|
+
console.log(` ${glyph(check.level)} ${strong(name)} ${muted(version)} ${check.value || check.summary} ${noun(where)}`);
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
// 「下一步」此前逐字重复上面已经打过的修复命令。只留没展示过的。
|
|
1928
|
+
const shown = new Set(out.checks.filter((c) => c.level !== 'pass' && c.fix).map((c) => c.fix));
|
|
1929
|
+
const remaining = out.nextSteps.filter((step) => !shown.has(step));
|
|
1930
|
+
if (remaining.length) {
|
|
1931
|
+
console.log('');
|
|
1932
|
+
for (const step of remaining)
|
|
1933
|
+
console.log(` ${strong('下一步')} ${noun(plain(step))}`);
|
|
1723
1934
|
}
|
|
1724
1935
|
}
|
|
1725
|
-
/**
|
|
1726
|
-
function
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1936
|
+
/** 反引号在终端里不是强调,是噪声;着色已经承担了同一职责。 */
|
|
1937
|
+
function plain(text) {
|
|
1938
|
+
return text.replace(/`/g, '');
|
|
1939
|
+
}
|
|
1940
|
+
/** 家目录缩成 ~/,省掉对读者零信息量的前缀。 */
|
|
1941
|
+
function tilde(path) {
|
|
1942
|
+
const home = process.env.HOME || '';
|
|
1943
|
+
return home && path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
1731
1944
|
}
|
|
1732
1945
|
function printProjectInfo(out) {
|
|
1733
|
-
console.log(
|
|
1946
|
+
console.log(`${strong('dingtalk-agent Project')} · ${noun(out.project.name)}`);
|
|
1734
1947
|
console.log(` root=${out.root}`);
|
|
1735
1948
|
console.log(` source=${out.source} manifest=${out.manifest || '(synthetic legacy)'}`);
|
|
1736
1949
|
console.log(` hash=${out.manifestHash} dta=${out.project.dtaVersion}`);
|
|
1737
1950
|
console.log(` current=${out.currentWorkspace || '(not selected)'}`);
|
|
1738
1951
|
for (const workspace of out.workspaces) {
|
|
1739
|
-
console.log(` ${workspace.current ? '*' : '-'} ${workspace.name} · ${workspace.provider.kind} · ${workspace.status}`);
|
|
1952
|
+
console.log(` ${workspace.current ? strong('*') : muted('-')} ${workspace.name} · ${workspace.provider.kind} · ${workspace.status}`);
|
|
1740
1953
|
}
|
|
1741
1954
|
}
|
|
1742
1955
|
function printWorkspaceList(out) {
|
|
1743
|
-
console.log(
|
|
1956
|
+
console.log(`${strong('dingtalk-agent workspaces')} · ${noun(out.project.name)}`);
|
|
1744
1957
|
if (!out.workspaces.length)
|
|
1745
|
-
console.log(' 尚未声明 Development Workspace。');
|
|
1958
|
+
console.log(muted(' 尚未声明 Development Workspace。'));
|
|
1746
1959
|
for (const workspace of out.workspaces) {
|
|
1747
|
-
console.log(` ${workspace.current ? '*' : '-'} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1960
|
+
console.log(` ${workspace.current ? strong('*') : muted('-')} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1748
1961
|
`stage=${workspace.stage} status=${workspace.status}`);
|
|
1749
1962
|
}
|
|
1750
1963
|
}
|
|
1751
1964
|
function printDevelopmentWorkspace(out) {
|
|
1752
|
-
console.log(
|
|
1965
|
+
console.log(`${strong('dingtalk-agent workspace')} · ${noun(out.name)}`);
|
|
1753
1966
|
console.log(` provider=${out.provider.kind} stage=${out.stage} status=${out.status}`);
|
|
1754
1967
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1755
1968
|
console.log(` current=${out.current} legacy=${out.legacy}`);
|
|
@@ -1759,19 +1972,22 @@ function printDevelopmentWorkspace(out) {
|
|
|
1759
1972
|
console.log(` source=${source}`);
|
|
1760
1973
|
}
|
|
1761
1974
|
function printDevelopmentWorkspaceDoctor(out) {
|
|
1762
|
-
console.log(
|
|
1975
|
+
console.log(`${strong('dingtalk-agent workspace doctor')} · ${noun(out.workspace)} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1763
1976
|
console.log(` provider=${out.provider} status=${out.status}`);
|
|
1764
1977
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1765
1978
|
for (const check of out.checks) {
|
|
1766
|
-
const
|
|
1767
|
-
console.log(` ${mark} ${check.id}: ${check.summary}`);
|
|
1979
|
+
const word = check.level === 'pass' ? 'PASS' : check.level === 'warn' ? 'WARN' : 'FAIL';
|
|
1980
|
+
console.log(` ${mark(levelOf(check.level), word)} ${check.id}: ${check.summary}`);
|
|
1768
1981
|
if (check.fix && check.level !== 'pass')
|
|
1769
|
-
console.log(` fix: ${check.fix}`);
|
|
1982
|
+
console.log(` fix: ${noun(check.fix)}`);
|
|
1770
1983
|
}
|
|
1771
1984
|
}
|
|
1772
1985
|
function printOpenCodeWorkspaceOperation(out) {
|
|
1773
1986
|
const applied = out.$schema === 'dingtalk-agent/opencode-workspace-apply@1';
|
|
1774
|
-
|
|
1987
|
+
const glyph = applied
|
|
1988
|
+
? mark(out.applied ? 'pass' : 'muted', out.applied ? '✅' : '↩️')
|
|
1989
|
+
: mark('muted', 'DRY-RUN');
|
|
1990
|
+
console.log(`${glyph} OpenCode Workspace ${noun(out.workspace)}`);
|
|
1775
1991
|
console.log(` action=${out.action} model=${out.model}`);
|
|
1776
1992
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1777
1993
|
console.log(` managed=${out.managedPath}`);
|
|
@@ -1781,7 +1997,7 @@ function printOpenCodeWorkspaceOperation(out) {
|
|
|
1781
1997
|
function printMulticaWorkspaceOperation(out) {
|
|
1782
1998
|
const passed = out.passed ?? out.readyForApply ?? out.blocking?.length === 0;
|
|
1783
1999
|
const mode = out.remoteRead ? 'REMOTE-READ' : 'DRY-RUN';
|
|
1784
|
-
console.log(`${passed ? '✅' : '⚠️'} ${mode} Multica Workspace ${out.workspace}`);
|
|
2000
|
+
console.log(`${mark(passed ? 'pass' : 'warn', passed ? '✅' : '⚠️')} ${mode} Multica Workspace ${noun(out.workspace)}`);
|
|
1785
2001
|
console.log(` schema=${out.$schema} profile=${out.profile || '-'}`);
|
|
1786
2002
|
if (out.planId)
|
|
1787
2003
|
console.log(` plan=${out.planId}`);
|
|
@@ -1802,7 +2018,7 @@ function printMulticaWorkspaceOperation(out) {
|
|
|
1802
2018
|
console.log(` remoteWrite=${out.remoteWrite} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1803
2019
|
}
|
|
1804
2020
|
function printMulticaDeployment(out) {
|
|
1805
|
-
console.log(
|
|
2021
|
+
console.log(`${strong('Multica deploy')}: ${noun(out.workspace || '<unknown>')}`);
|
|
1806
2022
|
if (out.planId)
|
|
1807
2023
|
console.log(` plan: ${out.planId}`);
|
|
1808
2024
|
if (out.operationId)
|
|
@@ -1825,7 +2041,7 @@ function printMulticaDeployment(out) {
|
|
|
1825
2041
|
console.log(' triggers: unchanged');
|
|
1826
2042
|
}
|
|
1827
2043
|
function printPromotion(out) {
|
|
1828
|
-
console.log(
|
|
2044
|
+
console.log(`${strong('Promotion')}: ${noun(out.promotionId || out.candidateId || out.candidate?.candidateId || '<none>')}`);
|
|
1829
2045
|
if (out.planId)
|
|
1830
2046
|
console.log(` plan: ${out.planId}`);
|
|
1831
2047
|
if (out.routeId)
|
|
@@ -1876,33 +2092,84 @@ function rejectWorkspaceOptions(values, allowed, command) {
|
|
|
1876
2092
|
fail(`${command} 不接受参数: ${extras.join(', ')}`);
|
|
1877
2093
|
}
|
|
1878
2094
|
function printSetup(out) {
|
|
1879
|
-
console.log(`${out.dryRun ? 'DRY-RUN' : '✅'} dingtalk-agent setup`);
|
|
1880
|
-
console.log(` CLI: ${out.cli.executable}`);
|
|
1881
|
-
console.log(` 短命令: ${out.cli.alias}`);
|
|
1882
|
-
console.log(` Skill: ${out.skill.canonical.path}`);
|
|
2095
|
+
console.log(`${out.dryRun ? mark('muted', 'DRY-RUN') : mark('pass', '✅')} ${strong('dingtalk-agent setup')}`);
|
|
2096
|
+
console.log(` CLI: ${noun(out.cli.executable)}`);
|
|
2097
|
+
console.log(` 短命令: ${noun(out.cli.alias)}`);
|
|
2098
|
+
console.log(` Skill: ${noun(out.skill.canonical.path)}`);
|
|
1883
2099
|
if (!out.shell.pathReady) {
|
|
1884
|
-
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${out.shell.activateCommand}`);
|
|
2100
|
+
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${noun(out.shell.activateCommand)}`);
|
|
1885
2101
|
if (out.shell.rcFile)
|
|
1886
|
-
console.log(` 新终端会从 ${out.shell.rcFile} 自动加载`);
|
|
2102
|
+
console.log(muted(` 新终端会从 ${out.shell.rcFile} 自动加载`));
|
|
1887
2103
|
}
|
|
1888
2104
|
printDoctor(out.doctor);
|
|
1889
|
-
console.log(`\n开始使用: ${out.nextCommand}`);
|
|
2105
|
+
console.log(`\n开始使用: ${noun(out.nextCommand)}`);
|
|
2106
|
+
}
|
|
2107
|
+
/**
|
|
2108
|
+
* 确认之前的抬头:告诉人「将要去哪」,好让 [y/N] 是个有信息的决定。
|
|
2109
|
+
*
|
|
2110
|
+
* 三态必须分开说。只判 outdated 会让 `--version <旧版> --force` 显示成
|
|
2111
|
+
* "已是最新版本",用户确认之后却真的降级——在唯一的不可逆动作前给了反的信息。
|
|
2112
|
+
*/
|
|
2113
|
+
function printUpgradePreamble(checked, options) {
|
|
2114
|
+
const { theme } = stderrUi();
|
|
2115
|
+
const arrow = (from, to, paint) => `${theme.dim(from)} ${theme.bold('→')} ${paint(to)}`;
|
|
2116
|
+
if (checked.relation === 'same' && !options.force && !options.dryRun) {
|
|
2117
|
+
console.error(` ${theme.success('✔')} 已是最新版本 ${theme.bold(checked.currentVersion)}`);
|
|
2118
|
+
console.error(theme.dim(' 仍会重新校验环境;只想查版本可用 dta upgrade --check'));
|
|
2119
|
+
return;
|
|
2120
|
+
}
|
|
2121
|
+
const label = checked.relation === 'upgrade' ? '新版本可用'
|
|
2122
|
+
: checked.relation === 'downgrade' ? '降级' : '重装';
|
|
2123
|
+
const value = checked.relation === 'upgrade'
|
|
2124
|
+
? arrow(checked.currentVersion, checked.targetVersion, theme.success)
|
|
2125
|
+
: checked.relation === 'downgrade'
|
|
2126
|
+
? `${arrow(checked.currentVersion, checked.targetVersion, theme.warn)}${theme.warn('(降级)')}`
|
|
2127
|
+
: `${theme.bold(checked.targetVersion)}${theme.dim('(与当前版本相同,将强制重装)')}`;
|
|
2128
|
+
for (const line of renderPairs([
|
|
2129
|
+
[label, value],
|
|
2130
|
+
['通道', `${checked.channel} ${theme.dim(checked.pinnedSource)}`],
|
|
2131
|
+
]))
|
|
2132
|
+
console.error(line);
|
|
2133
|
+
console.error('');
|
|
2134
|
+
}
|
|
2135
|
+
function printUpgradeCheck(checked) {
|
|
2136
|
+
const { theme } = stdoutUi();
|
|
2137
|
+
const glyph = checked.relation === 'upgrade' ? theme.warn('⬆️')
|
|
2138
|
+
: checked.relation === 'downgrade' ? theme.warn('⬇️') : theme.success('✅');
|
|
2139
|
+
const summary = checked.relation === 'upgrade'
|
|
2140
|
+
? `${theme.dim(checked.currentVersion)} → ${theme.success(checked.targetVersion)}`
|
|
2141
|
+
: checked.relation === 'downgrade'
|
|
2142
|
+
? `${theme.dim(checked.currentVersion)} → ${theme.warn(checked.targetVersion)}(目标更旧)`
|
|
2143
|
+
: `${theme.bold(checked.currentVersion)}(已是最新)`;
|
|
2144
|
+
console.log(`${glyph} dta upgrade --check: ${summary}`);
|
|
2145
|
+
console.log(` target=${theme.noun(checked.pinnedSource)} channel=${checked.channel}`);
|
|
2146
|
+
if (checked.relation === 'upgrade')
|
|
2147
|
+
console.log(` ${theme.dim('运行 dta upgrade 执行升级')}`);
|
|
2148
|
+
if (checked.relation === 'downgrade') {
|
|
2149
|
+
console.log(` ${theme.dim(`降级需显式确认: dta upgrade --version ${checked.targetVersion} --force`)}`);
|
|
2150
|
+
}
|
|
1890
2151
|
}
|
|
1891
2152
|
function printUpgrade(out) {
|
|
1892
|
-
const
|
|
1893
|
-
const
|
|
2153
|
+
const { theme } = stdoutUi();
|
|
2154
|
+
const mark = out.dryRun ? theme.dim('DRY-RUN') : out.ready ? theme.success('✅') : theme.warn('⚠️');
|
|
2155
|
+
const relation = out.changed
|
|
2156
|
+
? `${theme.dim(out.currentVersion)} → ${theme.success(out.targetVersion)}`
|
|
2157
|
+
: `${out.targetVersion}(已是当前版本)`;
|
|
1894
2158
|
console.log(`${mark} dta upgrade: ${relation}`);
|
|
1895
|
-
console.log(` target=${out.target}`);
|
|
1896
|
-
console.log(` CLI=${out.executable}`);
|
|
2159
|
+
console.log(` target=${theme.noun(out.target)}`);
|
|
2160
|
+
console.log(` CLI=${theme.noun(out.executable)}`);
|
|
1897
2161
|
if (out.dryRun) {
|
|
1898
|
-
console.log(` 将执行: ${out.commands.install}`);
|
|
1899
|
-
console.log(` 将复核: ${out.commands.verify}`);
|
|
2162
|
+
console.log(` 将执行: ${theme.noun(out.commands.install)}`);
|
|
2163
|
+
console.log(` 将复核: ${theme.noun(out.commands.verify)}`);
|
|
2164
|
+
console.log(` ${theme.dim('移除 --dry-run 以实际执行升级')}`);
|
|
1900
2165
|
}
|
|
1901
2166
|
else if (out.ready) {
|
|
1902
2167
|
console.log(' setup / DWS / Skill / Claude Code / Codex / OpenCode 全部 ready');
|
|
2168
|
+
// 出口指引:验证命令 + 后悔药,都是可以直接复制的
|
|
2169
|
+
console.log(` ${theme.dim(`验证: dta --version${out.changed ? ` 回退: dta upgrade --version ${out.currentVersion} --force` : ''}`)}`);
|
|
1903
2170
|
}
|
|
1904
2171
|
else {
|
|
1905
|
-
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${out.commands.verify}`);
|
|
2172
|
+
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${theme.noun(out.commands.verify)}`);
|
|
1906
2173
|
}
|
|
1907
2174
|
}
|
|
1908
2175
|
//# sourceMappingURL=dingtalk-agent.js.map
|