@xdxer/dingtalk-agent 0.1.5-beta.5 → 0.1.5-beta.6
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 +23 -0
- package/dist/bin/dingtalk-agent.js +338 -122
- 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/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/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/package.json +2 -2
|
@@ -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
|
}
|
|
@@ -913,7 +1051,7 @@ async function main() {
|
|
|
913
1051
|
if (o.json)
|
|
914
1052
|
console.log(JSON.stringify({ ...out, endpoint, readiness, targets, doc }, null, 2));
|
|
915
1053
|
else {
|
|
916
|
-
console.log(
|
|
1054
|
+
console.log(`${mark('pass', '✅')} 工作区已归属 ${strong(out.definition?.label)}(写入 ${noun(out.written)})`);
|
|
917
1055
|
for (const install of out.skillInstalls)
|
|
918
1056
|
printSkillStatus(install, 'install', false);
|
|
919
1057
|
if (!out.skillInstalls.length) {
|
|
@@ -953,14 +1091,14 @@ async function main() {
|
|
|
953
1091
|
if (o.json)
|
|
954
1092
|
console.log(JSON.stringify(out, null, 2));
|
|
955
1093
|
else {
|
|
956
|
-
console.log(
|
|
1094
|
+
console.log(`${mark('pass', '✅')} ${strong(out.mode === 'workspace' ? '已装载 Workspace' : '直接会话模式')}`);
|
|
957
1095
|
console.log(` scope=${out.scopeId} initialized=${out.initialized}`);
|
|
958
1096
|
console.log(` agent=${out.definition.id} definition=${out.definition.status}`);
|
|
959
1097
|
if (!out.mounts.length)
|
|
960
|
-
console.log(' 没有发现持久上下文;这不是错误,也不需要自动 init。');
|
|
1098
|
+
console.log(muted(' 没有发现持久上下文;这不是错误,也不需要自动 init。'));
|
|
961
1099
|
for (const mount of out.mounts)
|
|
962
|
-
console.log(` ${mount.slot}: ${mount.path}`);
|
|
963
|
-
console.log(` ${out.note}`);
|
|
1100
|
+
console.log(` ${mount.slot}: ${noun(mount.path)}`);
|
|
1101
|
+
console.log(` ${muted(out.note)}`);
|
|
964
1102
|
}
|
|
965
1103
|
return;
|
|
966
1104
|
}
|
|
@@ -1346,9 +1484,9 @@ async function main() {
|
|
|
1346
1484
|
if (o.json)
|
|
1347
1485
|
console.log(JSON.stringify(out, null, 2));
|
|
1348
1486
|
else if (!out.found)
|
|
1349
|
-
console.log('当前 Session 尚无 Task checkpoint。');
|
|
1487
|
+
console.log(muted('当前 Session 尚无 Task checkpoint。'));
|
|
1350
1488
|
else {
|
|
1351
|
-
console.log(
|
|
1489
|
+
console.log(`${mark('pass', '✅')} Task ${noun(out.checkpoint.taskId)} · ${out.checkpoint.status}`);
|
|
1352
1490
|
console.log(` revision=${out.checkpoint.revision} hash=${out.hash}`);
|
|
1353
1491
|
console.log(` next=${out.checkpoint.nextAction || '-'}`);
|
|
1354
1492
|
}
|
|
@@ -1373,7 +1511,7 @@ async function main() {
|
|
|
1373
1511
|
if (o.json || !o.live)
|
|
1374
1512
|
console.log(JSON.stringify(out, null, 2));
|
|
1375
1513
|
else {
|
|
1376
|
-
console.log(`${out.verified ? '✅' : '⚠️'} Operational Memory · ${out.mode}`);
|
|
1514
|
+
console.log(`${mark(out.verified ? 'pass' : 'warn', out.verified ? '✅' : '⚠️')} ${strong('Operational Memory')} · ${out.mode}`);
|
|
1377
1515
|
console.log(` record=${out.recordId || '-'} verification=${out.verification}`);
|
|
1378
1516
|
}
|
|
1379
1517
|
if (out.mode === 'uncertain')
|
|
@@ -1427,12 +1565,12 @@ async function main() {
|
|
|
1427
1565
|
if (o.json)
|
|
1428
1566
|
console.log(JSON.stringify(out, null, 2));
|
|
1429
1567
|
else if (action === 'publish') {
|
|
1430
|
-
console.log(`${out.verified ? '✅' : out.mode === 'dry-run' ? '🔎' : '⚠️'} Candidate ${o.id}`);
|
|
1568
|
+
console.log(`${mark(out.verified ? 'pass' : out.mode === 'dry-run' ? 'muted' : 'warn', out.verified ? '✅' : out.mode === 'dry-run' ? '🔎' : '⚠️')} Candidate ${noun(o.id)}`);
|
|
1431
1569
|
console.log(` mode=${out.mode} targetHash=${out.currentTargetHash}`);
|
|
1432
1570
|
}
|
|
1433
1571
|
else {
|
|
1434
|
-
console.log(
|
|
1435
|
-
console.log(` revision=${out.candidate.revision} path=${out.path}`);
|
|
1572
|
+
console.log(`${mark('pass', '✅')} Candidate ${noun(out.candidate.id)} · ${out.candidate.status}`);
|
|
1573
|
+
console.log(` revision=${out.candidate.revision} path=${noun(out.path)}`);
|
|
1436
1574
|
}
|
|
1437
1575
|
if (action === 'publish' && out.mode === 'uncertain')
|
|
1438
1576
|
process.exitCode = 2;
|
|
@@ -1463,10 +1601,10 @@ async function main() {
|
|
|
1463
1601
|
if (o.json || o['dry-run'])
|
|
1464
1602
|
console.log(JSON.stringify(out, null, 2));
|
|
1465
1603
|
else {
|
|
1466
|
-
console.log(`${out.verified ? '✅' : '⚠️'} ${out.kind} · ${out.outcome} · ${out.toState}`);
|
|
1467
|
-
console.log(` action=${out.actionId} run=${out.runId}`);
|
|
1604
|
+
console.log(`${mark(out.verified ? 'pass' : 'warn', out.verified ? '✅' : '⚠️')} ${strong(out.kind)} · ${out.outcome} · ${out.toState}`);
|
|
1605
|
+
console.log(` action=${noun(out.actionId)} run=${noun(out.runId)}`);
|
|
1468
1606
|
if (!out.verified)
|
|
1469
|
-
console.log(` ${out.verification}`);
|
|
1607
|
+
console.log(` ${muted(out.verification)}`);
|
|
1470
1608
|
}
|
|
1471
1609
|
if (out.outcome === 'uncertain')
|
|
1472
1610
|
process.exitCode = 2;
|
|
@@ -1538,11 +1676,41 @@ function editDistance(a, b) {
|
|
|
1538
1676
|
}
|
|
1539
1677
|
return row[b.length];
|
|
1540
1678
|
}
|
|
1679
|
+
/** 按语义给状态标记上色;字形原样返回,不做任何替换。 */
|
|
1680
|
+
function mark(level, text) {
|
|
1681
|
+
const { theme } = stdoutUi();
|
|
1682
|
+
return level === 'pass' ? theme.success(text)
|
|
1683
|
+
: level === 'warn' ? theme.warn(text)
|
|
1684
|
+
: level === 'fail' ? theme.danger(text)
|
|
1685
|
+
: theme.dim(text);
|
|
1686
|
+
}
|
|
1687
|
+
/** 可复制的名词:路径、版本号、ID、命令。 */
|
|
1688
|
+
function noun(text) {
|
|
1689
|
+
return stdoutUi().theme.noun(text);
|
|
1690
|
+
}
|
|
1691
|
+
/** 次要信息:补充说明、括注、下一步提示。 */
|
|
1692
|
+
function muted(text) {
|
|
1693
|
+
return stdoutUi().theme.dim(text);
|
|
1694
|
+
}
|
|
1695
|
+
/** 标题行 / key=value 的结构性强调。 */
|
|
1696
|
+
function strong(text) {
|
|
1697
|
+
return stdoutUi().theme.bold(text);
|
|
1698
|
+
}
|
|
1699
|
+
/** ready 布尔 → 语义级别,printX 里到处都是这个三态。 */
|
|
1700
|
+
function levelOf(state) {
|
|
1701
|
+
if (state === true)
|
|
1702
|
+
return 'pass';
|
|
1703
|
+
if (state === false)
|
|
1704
|
+
return 'fail';
|
|
1705
|
+
return state;
|
|
1706
|
+
}
|
|
1541
1707
|
function printDispatch(out, json = false) {
|
|
1542
1708
|
if (json)
|
|
1543
1709
|
return console.log(JSON.stringify(out, null, 2));
|
|
1544
|
-
const
|
|
1545
|
-
|
|
1710
|
+
const state = out.duplicate
|
|
1711
|
+
? mark(out.launch ? 'warn' : 'muted', out.launch ? '🔁 REDELIVER' : '↩️ DUPLICATE')
|
|
1712
|
+
: mark('pass', '✅ READY');
|
|
1713
|
+
console.log(`${state} ${noun(out.runId)}`);
|
|
1546
1714
|
console.log(` Field=${out.fieldId} Session=${out.sessionId} Event=${out.eventKind}`);
|
|
1547
1715
|
console.log(` cwd=${out.cwd}`);
|
|
1548
1716
|
console.log(` entrypoint=${out.entrypoint} queue=${out.queue.key} (max=${out.queue.maxConcurrency})`);
|
|
@@ -1552,7 +1720,7 @@ function printDispatch(out, json = false) {
|
|
|
1552
1720
|
}
|
|
1553
1721
|
function printLab(out) {
|
|
1554
1722
|
const passed = out.ready ?? out.passed ?? out.assertions?.passed;
|
|
1555
|
-
console.log(`${passed === false ? '❌' : '✅'} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1723
|
+
console.log(`${mark(levelOf(passed !== false), passed === false ? '❌' : '✅')} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1556
1724
|
if (out.mode)
|
|
1557
1725
|
console.log(` mode=${out.mode}`);
|
|
1558
1726
|
if (out.marker)
|
|
@@ -1561,17 +1729,17 @@ function printLab(out) {
|
|
|
1561
1729
|
console.log(` evidence=${out.evidencePath}`);
|
|
1562
1730
|
if (Array.isArray(out.checks)) {
|
|
1563
1731
|
for (const check of out.checks) {
|
|
1564
|
-
console.log(` ${check.passed ? 'PASS' : 'FAIL'} ${check.id}: ${check.detail}`);
|
|
1732
|
+
console.log(` ${mark(levelOf(Boolean(check.passed)), check.passed ? 'PASS' : 'FAIL')} ${check.id}: ${check.detail}`);
|
|
1565
1733
|
}
|
|
1566
1734
|
}
|
|
1567
1735
|
}
|
|
1568
1736
|
function printAgentAudit(out) {
|
|
1569
|
-
console.log(
|
|
1737
|
+
console.log(`${strong('dingtalk-agent agent audit')} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1570
1738
|
console.log(` definition=${out.definition.hash} storage=${out.storageMode}`);
|
|
1571
1739
|
console.log(` dingtalkSideEffect=${out.dingtalkSideEffect} sideEffect=${out.sideEffect}`);
|
|
1572
1740
|
for (const check of out.checks) {
|
|
1573
|
-
const
|
|
1574
|
-
console.log(` ${mark} ${check.id}: ${check.summary}`);
|
|
1741
|
+
const word = check.level === 'pass' ? 'PASS' : check.level === 'warn' ? 'WARN' : 'FAIL';
|
|
1742
|
+
console.log(` ${mark(levelOf(check.level), word)} ${check.id}: ${check.summary}`);
|
|
1575
1743
|
}
|
|
1576
1744
|
if (out.repairs.length) {
|
|
1577
1745
|
console.log('\n修复建议:');
|
|
@@ -1584,7 +1752,7 @@ function printAgentAudit(out) {
|
|
|
1584
1752
|
}
|
|
1585
1753
|
function printAgentEnhance(out) {
|
|
1586
1754
|
if (out.$schema === 'dingtalk-agent/agent-enhancement-plan@1') {
|
|
1587
|
-
console.log(
|
|
1755
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY PLAN' : 'BLOCKED')}`);
|
|
1588
1756
|
console.log(` planId=${out.planId} project=${out.projectName}`);
|
|
1589
1757
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1590
1758
|
for (const operation of out.operations) {
|
|
@@ -1594,12 +1762,12 @@ function printAgentEnhance(out) {
|
|
|
1594
1762
|
console.log(` REVIEW ${out.semanticReview.files.join(', ')}: ${out.semanticReview.why}`);
|
|
1595
1763
|
}
|
|
1596
1764
|
for (const blocker of out.blockers)
|
|
1597
|
-
console.log(` BLOCK ${blocker}`);
|
|
1765
|
+
console.log(` ${mark('fail', 'BLOCK')} ${blocker}`);
|
|
1598
1766
|
if (out.ready)
|
|
1599
1767
|
console.log(`\nApply:\n ${out.apply.command}`);
|
|
1600
1768
|
return;
|
|
1601
1769
|
}
|
|
1602
|
-
console.log('dingtalk-agent agent enhance · APPLIED');
|
|
1770
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark('pass', 'APPLIED')}`);
|
|
1603
1771
|
console.log(` operation=${out.operationId} planId=${out.planId}`);
|
|
1604
1772
|
console.log(` changes=${out.changes.length} idempotent=${out.idempotent}`);
|
|
1605
1773
|
if (out.backupRoot)
|
|
@@ -1607,8 +1775,8 @@ function printAgentEnhance(out) {
|
|
|
1607
1775
|
console.log(` audit=${out.audit.status} missing=${out.audit.missing.join(', ') || '-'}`);
|
|
1608
1776
|
}
|
|
1609
1777
|
function printAgentPlatform(platform) {
|
|
1610
|
-
console.log(`${platform.status === 'supported' ? '✅' : '⏳'} ${platform.name} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
|
|
1611
|
-
console.log(` ${platform.description}`);
|
|
1778
|
+
console.log(`${mark(platform.status === 'supported' ? 'pass' : 'muted', platform.status === 'supported' ? '✅' : '⏳')} ${strong(platform.name)} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
|
|
1779
|
+
console.log(` ${muted(platform.description)}`);
|
|
1612
1780
|
for (const skill of platform.skills)
|
|
1613
1781
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
1614
1782
|
if (platform.commands.length)
|
|
@@ -1616,12 +1784,12 @@ function printAgentPlatform(platform) {
|
|
|
1616
1784
|
}
|
|
1617
1785
|
function printAgentPlatformResolution(out) {
|
|
1618
1786
|
if (!out.platform) {
|
|
1619
|
-
console.log('⚠️ 当前工作区未声明 managed agent platform');
|
|
1787
|
+
console.log(mark('warn', '⚠️ 当前工作区未声明 managed agent platform'));
|
|
1620
1788
|
console.log(' 运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。');
|
|
1621
1789
|
return;
|
|
1622
1790
|
}
|
|
1623
1791
|
const known = out.definition;
|
|
1624
|
-
console.log(`${known ? '✅' : '❌'} 当前 platform: ${out.platform}${known ? ` · ${known.label} · ${platformStatusLabel(known.status)}` : '(未知)'}`);
|
|
1792
|
+
console.log(`${mark(levelOf(Boolean(known)), known ? '✅' : '❌')} 当前 platform: ${strong(out.platform)}${known ? ` · ${known.label} · ${platformStatusLabel(known.status)}` : '(未知)'}`);
|
|
1625
1793
|
console.log(` 来源: ${out.source}${out.file ? ` · ${out.file}` : ''}`);
|
|
1626
1794
|
for (const skill of known?.skills || [])
|
|
1627
1795
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
@@ -1629,8 +1797,9 @@ function printAgentPlatformResolution(out) {
|
|
|
1629
1797
|
// 披露:dta 层平台命令关联到平台内确切的 Skill(诊断信息走 stderr,不污染 --json stdout)。
|
|
1630
1798
|
function disclosePlatformSkill(resolution, role) {
|
|
1631
1799
|
const skillName = resolution.definition ? platformSkillForRole(resolution.definition.name, role) : null;
|
|
1632
|
-
if (skillName)
|
|
1633
|
-
console.error(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`);
|
|
1800
|
+
if (skillName) {
|
|
1801
|
+
console.error(stderrUi().theme.dim(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`));
|
|
1802
|
+
}
|
|
1634
1803
|
}
|
|
1635
1804
|
function printEndpoint(endpoint) {
|
|
1636
1805
|
if (!endpoint)
|
|
@@ -1644,9 +1813,9 @@ function printEndpoint(endpoint) {
|
|
|
1644
1813
|
console.log(` Endpoint: 未解析——设 ${endpoint.envVar} 或登录 multica 后生效`);
|
|
1645
1814
|
return;
|
|
1646
1815
|
}
|
|
1647
|
-
const
|
|
1816
|
+
const glyph = mark(endpoint.confirmed ? 'pass' : 'warn', endpoint.confirmed ? '✅' : '⚠️');
|
|
1648
1817
|
const note = endpoint.confirmed ? '' : '(建议/未确认,deploy 前需显式确认是预发还是生产)';
|
|
1649
|
-
console.log(` ${
|
|
1818
|
+
console.log(` ${glyph} Endpoint: ${noun(endpoint.endpoint)} · 来源: ${endpoint.source}${muted(note)}`);
|
|
1650
1819
|
console.log(` (切换:设 ${endpoint.envVar}=<url>、写 dingtalk-agent.json#multicaEndpoint、或登录对应 profile;无需改代码)`);
|
|
1651
1820
|
}
|
|
1652
1821
|
function printPlatformDoc(platformName) {
|
|
@@ -1654,27 +1823,27 @@ function printPlatformDoc(platformName) {
|
|
|
1654
1823
|
return;
|
|
1655
1824
|
const path = platformDocPath(PACKAGE_ROOT, platformName);
|
|
1656
1825
|
if (path)
|
|
1657
|
-
console.log(` 平台说明: ${path}\n
|
|
1826
|
+
console.log(` 平台说明: ${noun(path)}\n${muted(' (切换到该平台后请阅读,了解各技能用途与交付链)')}`);
|
|
1658
1827
|
}
|
|
1659
1828
|
function printMulticaTargets(targets) {
|
|
1660
1829
|
if (!targets.length)
|
|
1661
1830
|
return;
|
|
1662
|
-
console.log(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):');
|
|
1831
|
+
console.log(strong(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):'));
|
|
1663
1832
|
for (const target of targets) {
|
|
1664
1833
|
console.log(` - profile=${target.profile} · ${target.serverUrl}${target.workspaceId ? ` · workspace=${target.workspaceId}` : ''}`);
|
|
1665
1834
|
}
|
|
1666
1835
|
}
|
|
1667
1836
|
function printAgentPlatformReadiness(checks) {
|
|
1668
1837
|
for (const check of checks) {
|
|
1669
|
-
console.log(` ${check.ok ? '✅' : '⚠️'} ${check.summary}`);
|
|
1838
|
+
console.log(` ${mark(check.ok ? 'pass' : 'warn', check.ok ? '✅' : '⚠️')} ${check.summary}`);
|
|
1670
1839
|
if (check.hint)
|
|
1671
|
-
console.log(` ${check.hint}`);
|
|
1840
|
+
console.log(` ${muted(check.hint)}`);
|
|
1672
1841
|
}
|
|
1673
1842
|
}
|
|
1674
1843
|
function printSkillStatus(out, action, dryRun) {
|
|
1675
|
-
const prefix = dryRun ? 'DRY-RUN' : '✅';
|
|
1844
|
+
const prefix = dryRun ? mark('muted', 'DRY-RUN') : mark('pass', '✅');
|
|
1676
1845
|
const verb = action === 'status' ? '全局 Skill 状态' : `skill ${action}`;
|
|
1677
|
-
console.log(`${prefix} ${verb}: ${out.name}`);
|
|
1846
|
+
console.log(`${prefix} ${verb}: ${strong(out.name)}`);
|
|
1678
1847
|
console.log(` manager=${out.manager} bundled=${out.bundled.skillVersion || '-'}`);
|
|
1679
1848
|
console.log(` canonical=${out.canonical.path}`);
|
|
1680
1849
|
console.log(` installed=${out.canonical.exists} ` +
|
|
@@ -1685,71 +1854,64 @@ function printSkillStatus(out, action, dryRun) {
|
|
|
1685
1854
|
` → ${out.operation.after.installedVersion}(${out.operation.after.state})`);
|
|
1686
1855
|
}
|
|
1687
1856
|
if (out.operation)
|
|
1688
|
-
console.log(` delegated: ${out.operation.command}`);
|
|
1857
|
+
console.log(` delegated: ${noun(out.operation.command)}`);
|
|
1689
1858
|
for (const client of out.clients) {
|
|
1690
|
-
console.log(` ${client.label}=${client.state} (${client.discovery}: ${client.path})`);
|
|
1859
|
+
console.log(` ${client.label}=${mark(client.state === 'ok' ? 'pass' : 'warn', client.state)} (${client.discovery}: ${noun(client.path)})`);
|
|
1691
1860
|
}
|
|
1692
1861
|
if (action === 'install' && !dryRun) {
|
|
1693
|
-
console.log(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。');
|
|
1862
|
+
console.log(muted(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。'));
|
|
1694
1863
|
}
|
|
1695
1864
|
}
|
|
1696
1865
|
function printDoctor(out) {
|
|
1697
|
-
console.log(
|
|
1866
|
+
console.log(`${strong('dingtalk-agent doctor')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY' : 'NOT READY')}`);
|
|
1698
1867
|
for (const check of out.checks) {
|
|
1699
|
-
const
|
|
1700
|
-
console.log(`${mark} ${check.summary}`);
|
|
1868
|
+
const glyph = check.level === 'pass' ? '✅' : check.level === 'warn' ? '⚠️' : '❌';
|
|
1869
|
+
console.log(`${mark(levelOf(check.level), glyph)} ${check.summary}`);
|
|
1701
1870
|
if (check.detail)
|
|
1702
|
-
console.log(` ${check.detail}`);
|
|
1871
|
+
console.log(` ${muted(check.detail)}`);
|
|
1703
1872
|
if (check.fix)
|
|
1704
|
-
console.log(` 修复: ${check.fix}`);
|
|
1873
|
+
console.log(` 修复: ${noun(check.fix)}`);
|
|
1705
1874
|
}
|
|
1706
1875
|
if (out.hosts.length) {
|
|
1707
1876
|
// Host 面回答"本地能在哪跑",不改变上面的 ready 结论。
|
|
1708
|
-
console.log('
|
|
1877
|
+
console.log(`\n${strong('本机 Coding Agent:')}`);
|
|
1709
1878
|
const width = Math.max(...out.hosts.map((host) => displayWidth(host.label)));
|
|
1710
1879
|
for (const host of out.hosts) {
|
|
1711
1880
|
const label = host.label + ' '.repeat(width - displayWidth(host.label));
|
|
1712
1881
|
const where = host.cli.found
|
|
1713
1882
|
? [host.cli.path, host.cli.version].filter(Boolean).join(' ')
|
|
1714
1883
|
: `未找到 ${host.cli.command}`;
|
|
1715
|
-
console.log(` ${host.cli.found ? '✅' : '❌'} ${label} ${where}`);
|
|
1716
|
-
console.log(` Skill 可见性: ${host.skillExposure.exists ? '已暴露' : '未暴露'} · ${host.skillExposureRoot}`);
|
|
1884
|
+
console.log(` ${mark(levelOf(host.cli.found), host.cli.found ? '✅' : '❌')} ${label} ${noun(where)}`);
|
|
1885
|
+
console.log(muted(` Skill 可见性: ${host.skillExposure.exists ? '已暴露' : '未暴露'} · ${host.skillExposureRoot}`));
|
|
1717
1886
|
}
|
|
1718
1887
|
}
|
|
1719
1888
|
if (out.nextSteps.length) {
|
|
1720
|
-
console.log('
|
|
1889
|
+
console.log(`\n${strong('下一步:')}`);
|
|
1721
1890
|
for (const step of out.nextSteps)
|
|
1722
|
-
console.log(` ${step}`);
|
|
1891
|
+
console.log(` ${noun(step)}`);
|
|
1723
1892
|
}
|
|
1724
1893
|
}
|
|
1725
|
-
/** 全角字符按两列计宽,避免中英混排的 Host 列表错位。 */
|
|
1726
|
-
function displayWidth(text) {
|
|
1727
|
-
let width = 0;
|
|
1728
|
-
for (const char of text)
|
|
1729
|
-
width += /[ᄀ-ᅟ⺀-가-힣豈-︰--⦆¢-₩]/.test(char) ? 2 : 1;
|
|
1730
|
-
return width;
|
|
1731
|
-
}
|
|
1732
1894
|
function printProjectInfo(out) {
|
|
1733
|
-
console.log(
|
|
1895
|
+
console.log(`${strong('dingtalk-agent Project')} · ${noun(out.project.name)}`);
|
|
1734
1896
|
console.log(` root=${out.root}`);
|
|
1735
1897
|
console.log(` source=${out.source} manifest=${out.manifest || '(synthetic legacy)'}`);
|
|
1736
1898
|
console.log(` hash=${out.manifestHash} dta=${out.project.dtaVersion}`);
|
|
1737
1899
|
console.log(` current=${out.currentWorkspace || '(not selected)'}`);
|
|
1738
1900
|
for (const workspace of out.workspaces) {
|
|
1739
|
-
console.log(` ${workspace.current ? '*' : '-'} ${workspace.name} · ${workspace.provider.kind} · ${workspace.status}`);
|
|
1901
|
+
console.log(` ${workspace.current ? strong('*') : muted('-')} ${workspace.name} · ${workspace.provider.kind} · ${workspace.status}`);
|
|
1740
1902
|
}
|
|
1741
1903
|
}
|
|
1742
1904
|
function printWorkspaceList(out) {
|
|
1743
|
-
console.log(
|
|
1905
|
+
console.log(`${strong('dingtalk-agent workspaces')} · ${noun(out.project.name)}`);
|
|
1744
1906
|
if (!out.workspaces.length)
|
|
1745
|
-
console.log(' 尚未声明 Development Workspace。');
|
|
1907
|
+
console.log(muted(' 尚未声明 Development Workspace。'));
|
|
1746
1908
|
for (const workspace of out.workspaces) {
|
|
1747
|
-
console.log(` ${workspace.current ? '*' : '-'} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1909
|
+
console.log(` ${workspace.current ? strong('*') : muted('-')} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1748
1910
|
`stage=${workspace.stage} status=${workspace.status}`);
|
|
1749
1911
|
}
|
|
1750
1912
|
}
|
|
1751
1913
|
function printDevelopmentWorkspace(out) {
|
|
1752
|
-
console.log(
|
|
1914
|
+
console.log(`${strong('dingtalk-agent workspace')} · ${noun(out.name)}`);
|
|
1753
1915
|
console.log(` provider=${out.provider.kind} stage=${out.stage} status=${out.status}`);
|
|
1754
1916
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1755
1917
|
console.log(` current=${out.current} legacy=${out.legacy}`);
|
|
@@ -1759,19 +1921,22 @@ function printDevelopmentWorkspace(out) {
|
|
|
1759
1921
|
console.log(` source=${source}`);
|
|
1760
1922
|
}
|
|
1761
1923
|
function printDevelopmentWorkspaceDoctor(out) {
|
|
1762
|
-
console.log(
|
|
1924
|
+
console.log(`${strong('dingtalk-agent workspace doctor')} · ${noun(out.workspace)} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1763
1925
|
console.log(` provider=${out.provider} status=${out.status}`);
|
|
1764
1926
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1765
1927
|
for (const check of out.checks) {
|
|
1766
|
-
const
|
|
1767
|
-
console.log(` ${mark} ${check.id}: ${check.summary}`);
|
|
1928
|
+
const word = check.level === 'pass' ? 'PASS' : check.level === 'warn' ? 'WARN' : 'FAIL';
|
|
1929
|
+
console.log(` ${mark(levelOf(check.level), word)} ${check.id}: ${check.summary}`);
|
|
1768
1930
|
if (check.fix && check.level !== 'pass')
|
|
1769
|
-
console.log(` fix: ${check.fix}`);
|
|
1931
|
+
console.log(` fix: ${noun(check.fix)}`);
|
|
1770
1932
|
}
|
|
1771
1933
|
}
|
|
1772
1934
|
function printOpenCodeWorkspaceOperation(out) {
|
|
1773
1935
|
const applied = out.$schema === 'dingtalk-agent/opencode-workspace-apply@1';
|
|
1774
|
-
|
|
1936
|
+
const glyph = applied
|
|
1937
|
+
? mark(out.applied ? 'pass' : 'muted', out.applied ? '✅' : '↩️')
|
|
1938
|
+
: mark('muted', 'DRY-RUN');
|
|
1939
|
+
console.log(`${glyph} OpenCode Workspace ${noun(out.workspace)}`);
|
|
1775
1940
|
console.log(` action=${out.action} model=${out.model}`);
|
|
1776
1941
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1777
1942
|
console.log(` managed=${out.managedPath}`);
|
|
@@ -1781,7 +1946,7 @@ function printOpenCodeWorkspaceOperation(out) {
|
|
|
1781
1946
|
function printMulticaWorkspaceOperation(out) {
|
|
1782
1947
|
const passed = out.passed ?? out.readyForApply ?? out.blocking?.length === 0;
|
|
1783
1948
|
const mode = out.remoteRead ? 'REMOTE-READ' : 'DRY-RUN';
|
|
1784
|
-
console.log(`${passed ? '✅' : '⚠️'} ${mode} Multica Workspace ${out.workspace}`);
|
|
1949
|
+
console.log(`${mark(passed ? 'pass' : 'warn', passed ? '✅' : '⚠️')} ${mode} Multica Workspace ${noun(out.workspace)}`);
|
|
1785
1950
|
console.log(` schema=${out.$schema} profile=${out.profile || '-'}`);
|
|
1786
1951
|
if (out.planId)
|
|
1787
1952
|
console.log(` plan=${out.planId}`);
|
|
@@ -1802,7 +1967,7 @@ function printMulticaWorkspaceOperation(out) {
|
|
|
1802
1967
|
console.log(` remoteWrite=${out.remoteWrite} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1803
1968
|
}
|
|
1804
1969
|
function printMulticaDeployment(out) {
|
|
1805
|
-
console.log(
|
|
1970
|
+
console.log(`${strong('Multica deploy')}: ${noun(out.workspace || '<unknown>')}`);
|
|
1806
1971
|
if (out.planId)
|
|
1807
1972
|
console.log(` plan: ${out.planId}`);
|
|
1808
1973
|
if (out.operationId)
|
|
@@ -1825,7 +1990,7 @@ function printMulticaDeployment(out) {
|
|
|
1825
1990
|
console.log(' triggers: unchanged');
|
|
1826
1991
|
}
|
|
1827
1992
|
function printPromotion(out) {
|
|
1828
|
-
console.log(
|
|
1993
|
+
console.log(`${strong('Promotion')}: ${noun(out.promotionId || out.candidateId || out.candidate?.candidateId || '<none>')}`);
|
|
1829
1994
|
if (out.planId)
|
|
1830
1995
|
console.log(` plan: ${out.planId}`);
|
|
1831
1996
|
if (out.routeId)
|
|
@@ -1876,33 +2041,84 @@ function rejectWorkspaceOptions(values, allowed, command) {
|
|
|
1876
2041
|
fail(`${command} 不接受参数: ${extras.join(', ')}`);
|
|
1877
2042
|
}
|
|
1878
2043
|
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}`);
|
|
2044
|
+
console.log(`${out.dryRun ? mark('muted', 'DRY-RUN') : mark('pass', '✅')} ${strong('dingtalk-agent setup')}`);
|
|
2045
|
+
console.log(` CLI: ${noun(out.cli.executable)}`);
|
|
2046
|
+
console.log(` 短命令: ${noun(out.cli.alias)}`);
|
|
2047
|
+
console.log(` Skill: ${noun(out.skill.canonical.path)}`);
|
|
1883
2048
|
if (!out.shell.pathReady) {
|
|
1884
|
-
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${out.shell.activateCommand}`);
|
|
2049
|
+
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${noun(out.shell.activateCommand)}`);
|
|
1885
2050
|
if (out.shell.rcFile)
|
|
1886
|
-
console.log(` 新终端会从 ${out.shell.rcFile} 自动加载`);
|
|
2051
|
+
console.log(muted(` 新终端会从 ${out.shell.rcFile} 自动加载`));
|
|
1887
2052
|
}
|
|
1888
2053
|
printDoctor(out.doctor);
|
|
1889
|
-
console.log(`\n开始使用: ${out.nextCommand}`);
|
|
2054
|
+
console.log(`\n开始使用: ${noun(out.nextCommand)}`);
|
|
2055
|
+
}
|
|
2056
|
+
/**
|
|
2057
|
+
* 确认之前的抬头:告诉人「将要去哪」,好让 [y/N] 是个有信息的决定。
|
|
2058
|
+
*
|
|
2059
|
+
* 三态必须分开说。只判 outdated 会让 `--version <旧版> --force` 显示成
|
|
2060
|
+
* "已是最新版本",用户确认之后却真的降级——在唯一的不可逆动作前给了反的信息。
|
|
2061
|
+
*/
|
|
2062
|
+
function printUpgradePreamble(checked, options) {
|
|
2063
|
+
const { theme } = stderrUi();
|
|
2064
|
+
const arrow = (from, to, paint) => `${theme.dim(from)} ${theme.bold('→')} ${paint(to)}`;
|
|
2065
|
+
if (checked.relation === 'same' && !options.force && !options.dryRun) {
|
|
2066
|
+
console.error(` ${theme.success('✔')} 已是最新版本 ${theme.bold(checked.currentVersion)}`);
|
|
2067
|
+
console.error(theme.dim(' 仍会重新校验环境;只想查版本可用 dta upgrade --check'));
|
|
2068
|
+
return;
|
|
2069
|
+
}
|
|
2070
|
+
const label = checked.relation === 'upgrade' ? '新版本可用'
|
|
2071
|
+
: checked.relation === 'downgrade' ? '降级' : '重装';
|
|
2072
|
+
const value = checked.relation === 'upgrade'
|
|
2073
|
+
? arrow(checked.currentVersion, checked.targetVersion, theme.success)
|
|
2074
|
+
: checked.relation === 'downgrade'
|
|
2075
|
+
? `${arrow(checked.currentVersion, checked.targetVersion, theme.warn)}${theme.warn('(降级)')}`
|
|
2076
|
+
: `${theme.bold(checked.targetVersion)}${theme.dim('(与当前版本相同,将强制重装)')}`;
|
|
2077
|
+
for (const line of renderPairs([
|
|
2078
|
+
[label, value],
|
|
2079
|
+
['通道', `${checked.channel} ${theme.dim(checked.pinnedSource)}`],
|
|
2080
|
+
]))
|
|
2081
|
+
console.error(line);
|
|
2082
|
+
console.error('');
|
|
2083
|
+
}
|
|
2084
|
+
function printUpgradeCheck(checked) {
|
|
2085
|
+
const { theme } = stdoutUi();
|
|
2086
|
+
const glyph = checked.relation === 'upgrade' ? theme.warn('⬆️')
|
|
2087
|
+
: checked.relation === 'downgrade' ? theme.warn('⬇️') : theme.success('✅');
|
|
2088
|
+
const summary = checked.relation === 'upgrade'
|
|
2089
|
+
? `${theme.dim(checked.currentVersion)} → ${theme.success(checked.targetVersion)}`
|
|
2090
|
+
: checked.relation === 'downgrade'
|
|
2091
|
+
? `${theme.dim(checked.currentVersion)} → ${theme.warn(checked.targetVersion)}(目标更旧)`
|
|
2092
|
+
: `${theme.bold(checked.currentVersion)}(已是最新)`;
|
|
2093
|
+
console.log(`${glyph} dta upgrade --check: ${summary}`);
|
|
2094
|
+
console.log(` target=${theme.noun(checked.pinnedSource)} channel=${checked.channel}`);
|
|
2095
|
+
if (checked.relation === 'upgrade')
|
|
2096
|
+
console.log(` ${theme.dim('运行 dta upgrade 执行升级')}`);
|
|
2097
|
+
if (checked.relation === 'downgrade') {
|
|
2098
|
+
console.log(` ${theme.dim(`降级需显式确认: dta upgrade --version ${checked.targetVersion} --force`)}`);
|
|
2099
|
+
}
|
|
1890
2100
|
}
|
|
1891
2101
|
function printUpgrade(out) {
|
|
1892
|
-
const
|
|
1893
|
-
const
|
|
2102
|
+
const { theme } = stdoutUi();
|
|
2103
|
+
const mark = out.dryRun ? theme.dim('DRY-RUN') : out.ready ? theme.success('✅') : theme.warn('⚠️');
|
|
2104
|
+
const relation = out.changed
|
|
2105
|
+
? `${theme.dim(out.currentVersion)} → ${theme.success(out.targetVersion)}`
|
|
2106
|
+
: `${out.targetVersion}(已是当前版本)`;
|
|
1894
2107
|
console.log(`${mark} dta upgrade: ${relation}`);
|
|
1895
|
-
console.log(` target=${out.target}`);
|
|
1896
|
-
console.log(` CLI=${out.executable}`);
|
|
2108
|
+
console.log(` target=${theme.noun(out.target)}`);
|
|
2109
|
+
console.log(` CLI=${theme.noun(out.executable)}`);
|
|
1897
2110
|
if (out.dryRun) {
|
|
1898
|
-
console.log(` 将执行: ${out.commands.install}`);
|
|
1899
|
-
console.log(` 将复核: ${out.commands.verify}`);
|
|
2111
|
+
console.log(` 将执行: ${theme.noun(out.commands.install)}`);
|
|
2112
|
+
console.log(` 将复核: ${theme.noun(out.commands.verify)}`);
|
|
2113
|
+
console.log(` ${theme.dim('移除 --dry-run 以实际执行升级')}`);
|
|
1900
2114
|
}
|
|
1901
2115
|
else if (out.ready) {
|
|
1902
2116
|
console.log(' setup / DWS / Skill / Claude Code / Codex / OpenCode 全部 ready');
|
|
2117
|
+
// 出口指引:验证命令 + 后悔药,都是可以直接复制的
|
|
2118
|
+
console.log(` ${theme.dim(`验证: dta --version${out.changed ? ` 回退: dta upgrade --version ${out.currentVersion} --force` : ''}`)}`);
|
|
1903
2119
|
}
|
|
1904
2120
|
else {
|
|
1905
|
-
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${out.commands.verify}`);
|
|
2121
|
+
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${theme.noun(out.commands.verify)}`);
|
|
1906
2122
|
}
|
|
1907
2123
|
}
|
|
1908
2124
|
//# sourceMappingURL=dingtalk-agent.js.map
|