@xdxer/dingtalk-agent 0.1.5-beta.4 → 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 +43 -0
- package/dist/bin/dingtalk-agent.js +339 -124
- 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/doctor.js +1 -1
- 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/skill-manager.js +5 -0
- 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/package.json +3 -2
- package/skills/core/dingtalk-agent-compose/SKILL.md +19 -1
- package/skills/core/dingtalk-people-group-memory/COMPLETENESS.md +36 -0
- package/skills/core/dingtalk-people-group-memory/SKILL.md +69 -0
- package/skills/core/dingtalk-people-group-memory/references/adapters.md +273 -0
- package/skills/core/dingtalk-people-group-memory/references/assembly-guidance.md +40 -0
- package/skills/core/dingtalk-people-group-memory/references/binding.md +110 -0
- package/skills/core/dingtalk-people-group-memory/references/cold-start.md +70 -0
- package/skills/core/dingtalk-people-group-memory/references/config-binding.md +89 -0
- package/skills/core/dingtalk-people-group-memory/references/consent-and-visibility.md +83 -0
- package/skills/core/dingtalk-people-group-memory/references/consolidation.md +162 -0
- package/skills/core/dingtalk-people-group-memory/references/event-ingest.md +103 -0
- package/skills/core/dingtalk-people-group-memory/references/guided-setup.md +70 -0
- package/skills/core/dingtalk-people-group-memory/references/model.md +148 -0
- package/skills/core/dingtalk-people-group-memory/references/storage-port.md +107 -0
|
@@ -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';
|
|
@@ -65,8 +67,7 @@ dta —— 给 Agent 安装钉钉员工的基础行为和工作环境
|
|
|
65
67
|
dta setup 首次配置 CLI、DWS 和内置 Skill(基础行为 + Agent 装配 + 交付后评测)
|
|
66
68
|
dta bootstrap --json 为当前 Agent 会话加载工作区
|
|
67
69
|
dta agent enhance / audit 安全增强已有仓库,再审计定义、存储与 Skill 真加载
|
|
68
|
-
dta info /
|
|
69
|
-
dta schedule show / plan --workspace <name> 查看声明的常驻节律并生成 provider 部署计划
|
|
70
|
+
dta info / workspace doctor / schedule show <name> 只读诊断 Project、Workspace 与声明的常驻节律
|
|
70
71
|
dta agent-platform use <platform> → dta deploy / dta promote 声明平台归属并装平台技能包,再受控部署与晋级
|
|
71
72
|
|
|
72
73
|
维护环境:
|
|
@@ -184,13 +185,100 @@ dingtalk-agent 已验版本晋级与反馈候选
|
|
|
184
185
|
Promotion 只接受指定 suite 的 load/hard/surface gate 与精确 W2 evidence hash,并委托 W4 deploy。
|
|
185
186
|
Observe 只写 gitignored、proposed、不可直接发布的 Eval candidate;不修改 AGENTS.md、Prompt、Skill 或 Trigger。
|
|
186
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
|
+
}
|
|
187
244
|
function fail(msg, code = 1, hint = '') {
|
|
188
|
-
|
|
245
|
+
// 整行染色,绝不做 danger('错误') + ': ' + msg 这种切分——
|
|
246
|
+
// 契约 eval 断言的是 stderr.includes('错误:'),切开就再也匹配不上。
|
|
247
|
+
const { theme } = stderrUi();
|
|
248
|
+
console.error(theme.danger(`错误: ${msg}`));
|
|
189
249
|
if (hint)
|
|
190
|
-
console.error(`提示: ${hint}`);
|
|
250
|
+
console.error(theme.dim(`提示: ${hint}`));
|
|
191
251
|
process.exit(code);
|
|
192
252
|
}
|
|
193
|
-
|
|
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)];
|
|
194
282
|
const cmd = argv[0];
|
|
195
283
|
const sub = argv[1];
|
|
196
284
|
try {
|
|
@@ -203,38 +291,38 @@ catch (e) {
|
|
|
203
291
|
}
|
|
204
292
|
async function main() {
|
|
205
293
|
if (cmd === 'help' && sub === 'runtime') {
|
|
206
|
-
console.log(RUNTIME_HELP);
|
|
294
|
+
console.log(renderHelp(RUNTIME_HELP));
|
|
207
295
|
return;
|
|
208
296
|
}
|
|
209
297
|
if (cmd === 'help' && sub === 'adapters') {
|
|
210
|
-
console.log(ADAPTER_HELP);
|
|
298
|
+
console.log(renderHelp(ADAPTER_HELP));
|
|
211
299
|
return;
|
|
212
300
|
}
|
|
213
301
|
if (cmd === 'help' && sub === 'lab') {
|
|
214
|
-
console.log(LAB_HELP);
|
|
302
|
+
console.log(renderHelp(LAB_HELP));
|
|
215
303
|
return;
|
|
216
304
|
}
|
|
217
305
|
if (cmd === 'help' && sub === 'agent') {
|
|
218
|
-
console.log(AGENT_HELP);
|
|
306
|
+
console.log(renderHelp(AGENT_HELP));
|
|
219
307
|
return;
|
|
220
308
|
}
|
|
221
309
|
if (cmd === 'help' && sub === 'workspace') {
|
|
222
|
-
console.log(WORKSPACE_HELP);
|
|
310
|
+
console.log(renderHelp(WORKSPACE_HELP));
|
|
223
311
|
return;
|
|
224
312
|
}
|
|
225
313
|
if (cmd === 'help' && sub === 'deploy') {
|
|
226
|
-
console.log(DEPLOY_HELP);
|
|
314
|
+
console.log(renderHelp(DEPLOY_HELP));
|
|
227
315
|
return;
|
|
228
316
|
}
|
|
229
317
|
if (cmd === 'help' && ['promote', 'observe'].includes(sub || '')) {
|
|
230
|
-
console.log(PROMOTION_HELP);
|
|
318
|
+
console.log(renderHelp(PROMOTION_HELP));
|
|
231
319
|
return;
|
|
232
320
|
}
|
|
233
321
|
if (cmd === 'help' && sub) {
|
|
234
322
|
fail(`不认识的帮助主题: ${sub}`, 1, '运行 dta --help 回到产品入口;事件宿主可用 dta help runtime。');
|
|
235
323
|
}
|
|
236
324
|
if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {
|
|
237
|
-
console.log(HELP);
|
|
325
|
+
console.log(renderHelp(HELP));
|
|
238
326
|
return;
|
|
239
327
|
}
|
|
240
328
|
if (cmd === '--version' || cmd === '-V' || cmd === 'version') {
|
|
@@ -438,23 +526,23 @@ async function main() {
|
|
|
438
526
|
return;
|
|
439
527
|
}
|
|
440
528
|
if (out.count === 0) {
|
|
441
|
-
console.log('本 Project 未声明任何常驻节律(schedules)。');
|
|
529
|
+
console.log(muted('本 Project 未声明任何常驻节律(schedules)。'));
|
|
442
530
|
return;
|
|
443
531
|
}
|
|
444
|
-
console.log(
|
|
532
|
+
console.log(`${strong('声明的常驻节律(internalized cron)')} · ${out.count} 条`);
|
|
445
533
|
for (const s of out.schedules) {
|
|
446
|
-
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}]`)}`);
|
|
447
535
|
if (s.wake)
|
|
448
|
-
console.log(` 唤醒 ${s.wake}`);
|
|
536
|
+
console.log(muted(` 唤醒 ${s.wake}`));
|
|
449
537
|
if (s.completion)
|
|
450
|
-
console.log(` ②判据 ${s.completion}`);
|
|
538
|
+
console.log(muted(` ②判据 ${s.completion}`));
|
|
451
539
|
}
|
|
452
540
|
if (!out.minutesDistinct) {
|
|
453
|
-
console.log(`\n
|
|
541
|
+
console.log(`\n${mark('warn', `⚠️ 分钟位冲突: ${out.collidingMinutes.join(', ')} —— 外发类同分钟并发会重复送,请错开`)}`);
|
|
454
542
|
process.exitCode = 2;
|
|
455
543
|
}
|
|
456
544
|
else {
|
|
457
|
-
console.log('
|
|
545
|
+
console.log(`\n${mark('pass', '✓ 各节律分钟位互不相同(外发防重复的静态前提满足)')}`);
|
|
458
546
|
}
|
|
459
547
|
return;
|
|
460
548
|
}
|
|
@@ -468,17 +556,17 @@ async function main() {
|
|
|
468
556
|
console.log(JSON.stringify(plan, null, 2));
|
|
469
557
|
return;
|
|
470
558
|
}
|
|
471
|
-
console.log(
|
|
559
|
+
console.log(`${strong('schedule 部署计划')} · workspace=${noun(plan.workspace)} · provider=${plan.provider}`);
|
|
472
560
|
if (!plan.supported) {
|
|
473
|
-
console.log(`\n
|
|
474
|
-
console.log(` ${plan.reconcile}`);
|
|
561
|
+
console.log(`\n${mark('fail', `✗ 不支持: ${plan.reason}`)}`);
|
|
562
|
+
console.log(` ${noun(plan.reconcile)}`);
|
|
475
563
|
process.exitCode = 2;
|
|
476
564
|
return;
|
|
477
565
|
}
|
|
478
566
|
console.log(` ${plan.count} 条声明 → provider ops:\n`);
|
|
479
567
|
for (const s of plan.schedules)
|
|
480
|
-
console.log(`
|
|
481
|
-
console.log(`执行: ${plan.reconcile}`);
|
|
568
|
+
console.log(` ${muted(`# ${s.name}`)}\n ${noun(s.applyCommand)}\n`);
|
|
569
|
+
console.log(`执行: ${noun(plan.reconcile)}`);
|
|
482
570
|
return;
|
|
483
571
|
}
|
|
484
572
|
fail(`可用: dta schedule show | plan --workspace <name>${suggest(sub || '', ['show', 'plan'], 'dta schedule')}`);
|
|
@@ -671,7 +759,7 @@ async function main() {
|
|
|
671
759
|
if (o.json)
|
|
672
760
|
console.log(JSON.stringify(out, null, 2));
|
|
673
761
|
else
|
|
674
|
-
console.log(
|
|
762
|
+
console.log(`${mark('pass', '✅')} current workspace: ${muted(out.previous || '-')} → ${noun(out.current)}`);
|
|
675
763
|
return;
|
|
676
764
|
}
|
|
677
765
|
if (sub === 'run') {
|
|
@@ -717,19 +805,19 @@ async function main() {
|
|
|
717
805
|
if (o.json)
|
|
718
806
|
console.log(JSON.stringify(out, null, 2));
|
|
719
807
|
else if (out.$schema === 'dingtalk-agent/opencode-workspace-run-plan@1') {
|
|
720
|
-
console.log(
|
|
808
|
+
console.log(`${mark('muted', 'DRY-RUN')} workspace=${noun(out.workspace)} model=${out.model} prompt=${out.promptHash}`);
|
|
721
809
|
}
|
|
722
810
|
else if (out.$schema === 'dingtalk-agent/multica-workspace-run-plan@1') {
|
|
723
|
-
console.log(
|
|
811
|
+
console.log(`${mark('muted', 'DRY-RUN')} workspace=${noun(out.workspace)} agent=${out.agentId || '-'} prompt=${out.promptHash}`);
|
|
724
812
|
}
|
|
725
813
|
else {
|
|
726
|
-
console.log(`${out.passed ? '✅' : '❌'} workspace run ${out.runId}`);
|
|
814
|
+
console.log(`${mark(levelOf(Boolean(out.passed)), out.passed ? '✅' : '❌')} workspace run ${noun(out.runId)}`);
|
|
727
815
|
if ('execution' in out && out.execution?.answer)
|
|
728
816
|
console.log(out.execution.answer);
|
|
729
817
|
if ('answer' in out && out.answer)
|
|
730
818
|
console.log(out.answer);
|
|
731
819
|
if (out.evidencePath)
|
|
732
|
-
console.log(`evidence=${out.evidencePath}`);
|
|
820
|
+
console.log(`evidence=${noun(out.evidencePath)}`);
|
|
733
821
|
}
|
|
734
822
|
if (o.execute && !out.passed)
|
|
735
823
|
process.exitCode = 2;
|
|
@@ -798,23 +886,72 @@ async function main() {
|
|
|
798
886
|
return;
|
|
799
887
|
}
|
|
800
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
|
+
}
|
|
801
894
|
const { values: o } = parseArgs({
|
|
802
895
|
args: argv.slice(1),
|
|
803
896
|
options: {
|
|
804
897
|
channel: { type: 'string' }, version: { type: 'string' }, prefix: { type: 'string' },
|
|
805
898
|
'dry-run': { type: 'boolean' }, force: { type: 'boolean' }, json: { type: 'boolean' },
|
|
899
|
+
check: { type: 'boolean' }, yes: { type: 'boolean' },
|
|
806
900
|
},
|
|
807
901
|
});
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
|
|
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,
|
|
811
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,
|
|
812
949
|
});
|
|
813
|
-
if (
|
|
814
|
-
console.log(JSON.stringify(
|
|
950
|
+
if (json)
|
|
951
|
+
console.log(JSON.stringify(result, null, 2));
|
|
815
952
|
else
|
|
816
|
-
printUpgrade(
|
|
817
|
-
if (!
|
|
953
|
+
printUpgrade(result);
|
|
954
|
+
if (!result.dryRun && !result.ready)
|
|
818
955
|
process.exitCode = 2;
|
|
819
956
|
return;
|
|
820
957
|
}
|
|
@@ -914,7 +1051,7 @@ async function main() {
|
|
|
914
1051
|
if (o.json)
|
|
915
1052
|
console.log(JSON.stringify({ ...out, endpoint, readiness, targets, doc }, null, 2));
|
|
916
1053
|
else {
|
|
917
|
-
console.log(
|
|
1054
|
+
console.log(`${mark('pass', '✅')} 工作区已归属 ${strong(out.definition?.label)}(写入 ${noun(out.written)})`);
|
|
918
1055
|
for (const install of out.skillInstalls)
|
|
919
1056
|
printSkillStatus(install, 'install', false);
|
|
920
1057
|
if (!out.skillInstalls.length) {
|
|
@@ -954,14 +1091,14 @@ async function main() {
|
|
|
954
1091
|
if (o.json)
|
|
955
1092
|
console.log(JSON.stringify(out, null, 2));
|
|
956
1093
|
else {
|
|
957
|
-
console.log(
|
|
1094
|
+
console.log(`${mark('pass', '✅')} ${strong(out.mode === 'workspace' ? '已装载 Workspace' : '直接会话模式')}`);
|
|
958
1095
|
console.log(` scope=${out.scopeId} initialized=${out.initialized}`);
|
|
959
1096
|
console.log(` agent=${out.definition.id} definition=${out.definition.status}`);
|
|
960
1097
|
if (!out.mounts.length)
|
|
961
|
-
console.log(' 没有发现持久上下文;这不是错误,也不需要自动 init。');
|
|
1098
|
+
console.log(muted(' 没有发现持久上下文;这不是错误,也不需要自动 init。'));
|
|
962
1099
|
for (const mount of out.mounts)
|
|
963
|
-
console.log(` ${mount.slot}: ${mount.path}`);
|
|
964
|
-
console.log(` ${out.note}`);
|
|
1100
|
+
console.log(` ${mount.slot}: ${noun(mount.path)}`);
|
|
1101
|
+
console.log(` ${muted(out.note)}`);
|
|
965
1102
|
}
|
|
966
1103
|
return;
|
|
967
1104
|
}
|
|
@@ -1347,9 +1484,9 @@ async function main() {
|
|
|
1347
1484
|
if (o.json)
|
|
1348
1485
|
console.log(JSON.stringify(out, null, 2));
|
|
1349
1486
|
else if (!out.found)
|
|
1350
|
-
console.log('当前 Session 尚无 Task checkpoint。');
|
|
1487
|
+
console.log(muted('当前 Session 尚无 Task checkpoint。'));
|
|
1351
1488
|
else {
|
|
1352
|
-
console.log(
|
|
1489
|
+
console.log(`${mark('pass', '✅')} Task ${noun(out.checkpoint.taskId)} · ${out.checkpoint.status}`);
|
|
1353
1490
|
console.log(` revision=${out.checkpoint.revision} hash=${out.hash}`);
|
|
1354
1491
|
console.log(` next=${out.checkpoint.nextAction || '-'}`);
|
|
1355
1492
|
}
|
|
@@ -1374,7 +1511,7 @@ async function main() {
|
|
|
1374
1511
|
if (o.json || !o.live)
|
|
1375
1512
|
console.log(JSON.stringify(out, null, 2));
|
|
1376
1513
|
else {
|
|
1377
|
-
console.log(`${out.verified ? '✅' : '⚠️'} Operational Memory · ${out.mode}`);
|
|
1514
|
+
console.log(`${mark(out.verified ? 'pass' : 'warn', out.verified ? '✅' : '⚠️')} ${strong('Operational Memory')} · ${out.mode}`);
|
|
1378
1515
|
console.log(` record=${out.recordId || '-'} verification=${out.verification}`);
|
|
1379
1516
|
}
|
|
1380
1517
|
if (out.mode === 'uncertain')
|
|
@@ -1428,12 +1565,12 @@ async function main() {
|
|
|
1428
1565
|
if (o.json)
|
|
1429
1566
|
console.log(JSON.stringify(out, null, 2));
|
|
1430
1567
|
else if (action === 'publish') {
|
|
1431
|
-
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)}`);
|
|
1432
1569
|
console.log(` mode=${out.mode} targetHash=${out.currentTargetHash}`);
|
|
1433
1570
|
}
|
|
1434
1571
|
else {
|
|
1435
|
-
console.log(
|
|
1436
|
-
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)}`);
|
|
1437
1574
|
}
|
|
1438
1575
|
if (action === 'publish' && out.mode === 'uncertain')
|
|
1439
1576
|
process.exitCode = 2;
|
|
@@ -1464,10 +1601,10 @@ async function main() {
|
|
|
1464
1601
|
if (o.json || o['dry-run'])
|
|
1465
1602
|
console.log(JSON.stringify(out, null, 2));
|
|
1466
1603
|
else {
|
|
1467
|
-
console.log(`${out.verified ? '✅' : '⚠️'} ${out.kind} · ${out.outcome} · ${out.toState}`);
|
|
1468
|
-
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)}`);
|
|
1469
1606
|
if (!out.verified)
|
|
1470
|
-
console.log(` ${out.verification}`);
|
|
1607
|
+
console.log(` ${muted(out.verification)}`);
|
|
1471
1608
|
}
|
|
1472
1609
|
if (out.outcome === 'uncertain')
|
|
1473
1610
|
process.exitCode = 2;
|
|
@@ -1539,11 +1676,41 @@ function editDistance(a, b) {
|
|
|
1539
1676
|
}
|
|
1540
1677
|
return row[b.length];
|
|
1541
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
|
+
}
|
|
1542
1707
|
function printDispatch(out, json = false) {
|
|
1543
1708
|
if (json)
|
|
1544
1709
|
return console.log(JSON.stringify(out, null, 2));
|
|
1545
|
-
const
|
|
1546
|
-
|
|
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)}`);
|
|
1547
1714
|
console.log(` Field=${out.fieldId} Session=${out.sessionId} Event=${out.eventKind}`);
|
|
1548
1715
|
console.log(` cwd=${out.cwd}`);
|
|
1549
1716
|
console.log(` entrypoint=${out.entrypoint} queue=${out.queue.key} (max=${out.queue.maxConcurrency})`);
|
|
@@ -1553,7 +1720,7 @@ function printDispatch(out, json = false) {
|
|
|
1553
1720
|
}
|
|
1554
1721
|
function printLab(out) {
|
|
1555
1722
|
const passed = out.ready ?? out.passed ?? out.assertions?.passed;
|
|
1556
|
-
console.log(`${passed === false ? '❌' : '✅'} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1723
|
+
console.log(`${mark(levelOf(passed !== false), passed === false ? '❌' : '✅')} ${out.$schema || 'dingtalk-agent/lab'}`);
|
|
1557
1724
|
if (out.mode)
|
|
1558
1725
|
console.log(` mode=${out.mode}`);
|
|
1559
1726
|
if (out.marker)
|
|
@@ -1562,17 +1729,17 @@ function printLab(out) {
|
|
|
1562
1729
|
console.log(` evidence=${out.evidencePath}`);
|
|
1563
1730
|
if (Array.isArray(out.checks)) {
|
|
1564
1731
|
for (const check of out.checks) {
|
|
1565
|
-
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}`);
|
|
1566
1733
|
}
|
|
1567
1734
|
}
|
|
1568
1735
|
}
|
|
1569
1736
|
function printAgentAudit(out) {
|
|
1570
|
-
console.log(
|
|
1737
|
+
console.log(`${strong('dingtalk-agent agent audit')} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1571
1738
|
console.log(` definition=${out.definition.hash} storage=${out.storageMode}`);
|
|
1572
1739
|
console.log(` dingtalkSideEffect=${out.dingtalkSideEffect} sideEffect=${out.sideEffect}`);
|
|
1573
1740
|
for (const check of out.checks) {
|
|
1574
|
-
const
|
|
1575
|
-
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}`);
|
|
1576
1743
|
}
|
|
1577
1744
|
if (out.repairs.length) {
|
|
1578
1745
|
console.log('\n修复建议:');
|
|
@@ -1585,7 +1752,7 @@ function printAgentAudit(out) {
|
|
|
1585
1752
|
}
|
|
1586
1753
|
function printAgentEnhance(out) {
|
|
1587
1754
|
if (out.$schema === 'dingtalk-agent/agent-enhancement-plan@1') {
|
|
1588
|
-
console.log(
|
|
1755
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY PLAN' : 'BLOCKED')}`);
|
|
1589
1756
|
console.log(` planId=${out.planId} project=${out.projectName}`);
|
|
1590
1757
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1591
1758
|
for (const operation of out.operations) {
|
|
@@ -1595,12 +1762,12 @@ function printAgentEnhance(out) {
|
|
|
1595
1762
|
console.log(` REVIEW ${out.semanticReview.files.join(', ')}: ${out.semanticReview.why}`);
|
|
1596
1763
|
}
|
|
1597
1764
|
for (const blocker of out.blockers)
|
|
1598
|
-
console.log(` BLOCK ${blocker}`);
|
|
1765
|
+
console.log(` ${mark('fail', 'BLOCK')} ${blocker}`);
|
|
1599
1766
|
if (out.ready)
|
|
1600
1767
|
console.log(`\nApply:\n ${out.apply.command}`);
|
|
1601
1768
|
return;
|
|
1602
1769
|
}
|
|
1603
|
-
console.log('dingtalk-agent agent enhance · APPLIED');
|
|
1770
|
+
console.log(`${strong('dingtalk-agent agent enhance')} · ${mark('pass', 'APPLIED')}`);
|
|
1604
1771
|
console.log(` operation=${out.operationId} planId=${out.planId}`);
|
|
1605
1772
|
console.log(` changes=${out.changes.length} idempotent=${out.idempotent}`);
|
|
1606
1773
|
if (out.backupRoot)
|
|
@@ -1608,8 +1775,8 @@ function printAgentEnhance(out) {
|
|
|
1608
1775
|
console.log(` audit=${out.audit.status} missing=${out.audit.missing.join(', ') || '-'}`);
|
|
1609
1776
|
}
|
|
1610
1777
|
function printAgentPlatform(platform) {
|
|
1611
|
-
console.log(`${platform.status === 'supported' ? '✅' : '⏳'} ${platform.name} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
|
|
1612
|
-
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)}`);
|
|
1613
1780
|
for (const skill of platform.skills)
|
|
1614
1781
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
1615
1782
|
if (platform.commands.length)
|
|
@@ -1617,12 +1784,12 @@ function printAgentPlatform(platform) {
|
|
|
1617
1784
|
}
|
|
1618
1785
|
function printAgentPlatformResolution(out) {
|
|
1619
1786
|
if (!out.platform) {
|
|
1620
|
-
console.log('⚠️ 当前工作区未声明 managed agent platform');
|
|
1787
|
+
console.log(mark('warn', '⚠️ 当前工作区未声明 managed agent platform'));
|
|
1621
1788
|
console.log(' 运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。');
|
|
1622
1789
|
return;
|
|
1623
1790
|
}
|
|
1624
1791
|
const known = out.definition;
|
|
1625
|
-
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)}` : '(未知)'}`);
|
|
1626
1793
|
console.log(` 来源: ${out.source}${out.file ? ` · ${out.file}` : ''}`);
|
|
1627
1794
|
for (const skill of known?.skills || [])
|
|
1628
1795
|
console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
|
|
@@ -1630,8 +1797,9 @@ function printAgentPlatformResolution(out) {
|
|
|
1630
1797
|
// 披露:dta 层平台命令关联到平台内确切的 Skill(诊断信息走 stderr,不污染 --json stdout)。
|
|
1631
1798
|
function disclosePlatformSkill(resolution, role) {
|
|
1632
1799
|
const skillName = resolution.definition ? platformSkillForRole(resolution.definition.name, role) : null;
|
|
1633
|
-
if (skillName)
|
|
1634
|
-
console.error(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`);
|
|
1800
|
+
if (skillName) {
|
|
1801
|
+
console.error(stderrUi().theme.dim(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`));
|
|
1802
|
+
}
|
|
1635
1803
|
}
|
|
1636
1804
|
function printEndpoint(endpoint) {
|
|
1637
1805
|
if (!endpoint)
|
|
@@ -1645,9 +1813,9 @@ function printEndpoint(endpoint) {
|
|
|
1645
1813
|
console.log(` Endpoint: 未解析——设 ${endpoint.envVar} 或登录 multica 后生效`);
|
|
1646
1814
|
return;
|
|
1647
1815
|
}
|
|
1648
|
-
const
|
|
1816
|
+
const glyph = mark(endpoint.confirmed ? 'pass' : 'warn', endpoint.confirmed ? '✅' : '⚠️');
|
|
1649
1817
|
const note = endpoint.confirmed ? '' : '(建议/未确认,deploy 前需显式确认是预发还是生产)';
|
|
1650
|
-
console.log(` ${
|
|
1818
|
+
console.log(` ${glyph} Endpoint: ${noun(endpoint.endpoint)} · 来源: ${endpoint.source}${muted(note)}`);
|
|
1651
1819
|
console.log(` (切换:设 ${endpoint.envVar}=<url>、写 dingtalk-agent.json#multicaEndpoint、或登录对应 profile;无需改代码)`);
|
|
1652
1820
|
}
|
|
1653
1821
|
function printPlatformDoc(platformName) {
|
|
@@ -1655,27 +1823,27 @@ function printPlatformDoc(platformName) {
|
|
|
1655
1823
|
return;
|
|
1656
1824
|
const path = platformDocPath(PACKAGE_ROOT, platformName);
|
|
1657
1825
|
if (path)
|
|
1658
|
-
console.log(` 平台说明: ${path}\n
|
|
1826
|
+
console.log(` 平台说明: ${noun(path)}\n${muted(' (切换到该平台后请阅读,了解各技能用途与交付链)')}`);
|
|
1659
1827
|
}
|
|
1660
1828
|
function printMulticaTargets(targets) {
|
|
1661
1829
|
if (!targets.length)
|
|
1662
1830
|
return;
|
|
1663
|
-
console.log(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):');
|
|
1831
|
+
console.log(strong(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):'));
|
|
1664
1832
|
for (const target of targets) {
|
|
1665
1833
|
console.log(` - profile=${target.profile} · ${target.serverUrl}${target.workspaceId ? ` · workspace=${target.workspaceId}` : ''}`);
|
|
1666
1834
|
}
|
|
1667
1835
|
}
|
|
1668
1836
|
function printAgentPlatformReadiness(checks) {
|
|
1669
1837
|
for (const check of checks) {
|
|
1670
|
-
console.log(` ${check.ok ? '✅' : '⚠️'} ${check.summary}`);
|
|
1838
|
+
console.log(` ${mark(check.ok ? 'pass' : 'warn', check.ok ? '✅' : '⚠️')} ${check.summary}`);
|
|
1671
1839
|
if (check.hint)
|
|
1672
|
-
console.log(` ${check.hint}`);
|
|
1840
|
+
console.log(` ${muted(check.hint)}`);
|
|
1673
1841
|
}
|
|
1674
1842
|
}
|
|
1675
1843
|
function printSkillStatus(out, action, dryRun) {
|
|
1676
|
-
const prefix = dryRun ? 'DRY-RUN' : '✅';
|
|
1844
|
+
const prefix = dryRun ? mark('muted', 'DRY-RUN') : mark('pass', '✅');
|
|
1677
1845
|
const verb = action === 'status' ? '全局 Skill 状态' : `skill ${action}`;
|
|
1678
|
-
console.log(`${prefix} ${verb}: ${out.name}`);
|
|
1846
|
+
console.log(`${prefix} ${verb}: ${strong(out.name)}`);
|
|
1679
1847
|
console.log(` manager=${out.manager} bundled=${out.bundled.skillVersion || '-'}`);
|
|
1680
1848
|
console.log(` canonical=${out.canonical.path}`);
|
|
1681
1849
|
console.log(` installed=${out.canonical.exists} ` +
|
|
@@ -1686,71 +1854,64 @@ function printSkillStatus(out, action, dryRun) {
|
|
|
1686
1854
|
` → ${out.operation.after.installedVersion}(${out.operation.after.state})`);
|
|
1687
1855
|
}
|
|
1688
1856
|
if (out.operation)
|
|
1689
|
-
console.log(` delegated: ${out.operation.command}`);
|
|
1857
|
+
console.log(` delegated: ${noun(out.operation.command)}`);
|
|
1690
1858
|
for (const client of out.clients) {
|
|
1691
|
-
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)})`);
|
|
1692
1860
|
}
|
|
1693
1861
|
if (action === 'install' && !dryRun) {
|
|
1694
|
-
console.log(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。');
|
|
1862
|
+
console.log(muted(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。'));
|
|
1695
1863
|
}
|
|
1696
1864
|
}
|
|
1697
1865
|
function printDoctor(out) {
|
|
1698
|
-
console.log(
|
|
1866
|
+
console.log(`${strong('dingtalk-agent doctor')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY' : 'NOT READY')}`);
|
|
1699
1867
|
for (const check of out.checks) {
|
|
1700
|
-
const
|
|
1701
|
-
console.log(`${mark} ${check.summary}`);
|
|
1868
|
+
const glyph = check.level === 'pass' ? '✅' : check.level === 'warn' ? '⚠️' : '❌';
|
|
1869
|
+
console.log(`${mark(levelOf(check.level), glyph)} ${check.summary}`);
|
|
1702
1870
|
if (check.detail)
|
|
1703
|
-
console.log(` ${check.detail}`);
|
|
1871
|
+
console.log(` ${muted(check.detail)}`);
|
|
1704
1872
|
if (check.fix)
|
|
1705
|
-
console.log(` 修复: ${check.fix}`);
|
|
1873
|
+
console.log(` 修复: ${noun(check.fix)}`);
|
|
1706
1874
|
}
|
|
1707
1875
|
if (out.hosts.length) {
|
|
1708
1876
|
// Host 面回答"本地能在哪跑",不改变上面的 ready 结论。
|
|
1709
|
-
console.log('
|
|
1877
|
+
console.log(`\n${strong('本机 Coding Agent:')}`);
|
|
1710
1878
|
const width = Math.max(...out.hosts.map((host) => displayWidth(host.label)));
|
|
1711
1879
|
for (const host of out.hosts) {
|
|
1712
1880
|
const label = host.label + ' '.repeat(width - displayWidth(host.label));
|
|
1713
1881
|
const where = host.cli.found
|
|
1714
1882
|
? [host.cli.path, host.cli.version].filter(Boolean).join(' ')
|
|
1715
1883
|
: `未找到 ${host.cli.command}`;
|
|
1716
|
-
console.log(` ${host.cli.found ? '✅' : '❌'} ${label} ${where}`);
|
|
1717
|
-
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}`));
|
|
1718
1886
|
}
|
|
1719
1887
|
}
|
|
1720
1888
|
if (out.nextSteps.length) {
|
|
1721
|
-
console.log('
|
|
1889
|
+
console.log(`\n${strong('下一步:')}`);
|
|
1722
1890
|
for (const step of out.nextSteps)
|
|
1723
|
-
console.log(` ${step}`);
|
|
1891
|
+
console.log(` ${noun(step)}`);
|
|
1724
1892
|
}
|
|
1725
1893
|
}
|
|
1726
|
-
/** 全角字符按两列计宽,避免中英混排的 Host 列表错位。 */
|
|
1727
|
-
function displayWidth(text) {
|
|
1728
|
-
let width = 0;
|
|
1729
|
-
for (const char of text)
|
|
1730
|
-
width += /[ᄀ-ᅟ⺀-가-힣豈-︰--⦆¢-₩]/.test(char) ? 2 : 1;
|
|
1731
|
-
return width;
|
|
1732
|
-
}
|
|
1733
1894
|
function printProjectInfo(out) {
|
|
1734
|
-
console.log(
|
|
1895
|
+
console.log(`${strong('dingtalk-agent Project')} · ${noun(out.project.name)}`);
|
|
1735
1896
|
console.log(` root=${out.root}`);
|
|
1736
1897
|
console.log(` source=${out.source} manifest=${out.manifest || '(synthetic legacy)'}`);
|
|
1737
1898
|
console.log(` hash=${out.manifestHash} dta=${out.project.dtaVersion}`);
|
|
1738
1899
|
console.log(` current=${out.currentWorkspace || '(not selected)'}`);
|
|
1739
1900
|
for (const workspace of out.workspaces) {
|
|
1740
|
-
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}`);
|
|
1741
1902
|
}
|
|
1742
1903
|
}
|
|
1743
1904
|
function printWorkspaceList(out) {
|
|
1744
|
-
console.log(
|
|
1905
|
+
console.log(`${strong('dingtalk-agent workspaces')} · ${noun(out.project.name)}`);
|
|
1745
1906
|
if (!out.workspaces.length)
|
|
1746
|
-
console.log(' 尚未声明 Development Workspace。');
|
|
1907
|
+
console.log(muted(' 尚未声明 Development Workspace。'));
|
|
1747
1908
|
for (const workspace of out.workspaces) {
|
|
1748
|
-
console.log(` ${workspace.current ? '*' : '-'} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1909
|
+
console.log(` ${workspace.current ? strong('*') : muted('-')} ${workspace.name} provider=${workspace.provider.kind} ` +
|
|
1749
1910
|
`stage=${workspace.stage} status=${workspace.status}`);
|
|
1750
1911
|
}
|
|
1751
1912
|
}
|
|
1752
1913
|
function printDevelopmentWorkspace(out) {
|
|
1753
|
-
console.log(
|
|
1914
|
+
console.log(`${strong('dingtalk-agent workspace')} · ${noun(out.name)}`);
|
|
1754
1915
|
console.log(` provider=${out.provider.kind} stage=${out.stage} status=${out.status}`);
|
|
1755
1916
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1756
1917
|
console.log(` current=${out.current} legacy=${out.legacy}`);
|
|
@@ -1760,19 +1921,22 @@ function printDevelopmentWorkspace(out) {
|
|
|
1760
1921
|
console.log(` source=${source}`);
|
|
1761
1922
|
}
|
|
1762
1923
|
function printDevelopmentWorkspaceDoctor(out) {
|
|
1763
|
-
console.log(
|
|
1924
|
+
console.log(`${strong('dingtalk-agent workspace doctor')} · ${noun(out.workspace)} · ${mark(out.ready ? 'pass' : 'warn', out.ready ? 'READY' : 'PARTIAL')}`);
|
|
1764
1925
|
console.log(` provider=${out.provider} status=${out.status}`);
|
|
1765
1926
|
console.log(` sideEffect=${out.sideEffect} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1766
1927
|
for (const check of out.checks) {
|
|
1767
|
-
const
|
|
1768
|
-
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}`);
|
|
1769
1930
|
if (check.fix && check.level !== 'pass')
|
|
1770
|
-
console.log(` fix: ${check.fix}`);
|
|
1931
|
+
console.log(` fix: ${noun(check.fix)}`);
|
|
1771
1932
|
}
|
|
1772
1933
|
}
|
|
1773
1934
|
function printOpenCodeWorkspaceOperation(out) {
|
|
1774
1935
|
const applied = out.$schema === 'dingtalk-agent/opencode-workspace-apply@1';
|
|
1775
|
-
|
|
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)}`);
|
|
1776
1940
|
console.log(` action=${out.action} model=${out.model}`);
|
|
1777
1941
|
console.log(` desired=${out.desiredHash} observed=${out.observedHash || '-'}`);
|
|
1778
1942
|
console.log(` managed=${out.managedPath}`);
|
|
@@ -1782,7 +1946,7 @@ function printOpenCodeWorkspaceOperation(out) {
|
|
|
1782
1946
|
function printMulticaWorkspaceOperation(out) {
|
|
1783
1947
|
const passed = out.passed ?? out.readyForApply ?? out.blocking?.length === 0;
|
|
1784
1948
|
const mode = out.remoteRead ? 'REMOTE-READ' : 'DRY-RUN';
|
|
1785
|
-
console.log(`${passed ? '✅' : '⚠️'} ${mode} Multica Workspace ${out.workspace}`);
|
|
1949
|
+
console.log(`${mark(passed ? 'pass' : 'warn', passed ? '✅' : '⚠️')} ${mode} Multica Workspace ${noun(out.workspace)}`);
|
|
1786
1950
|
console.log(` schema=${out.$schema} profile=${out.profile || '-'}`);
|
|
1787
1951
|
if (out.planId)
|
|
1788
1952
|
console.log(` plan=${out.planId}`);
|
|
@@ -1803,7 +1967,7 @@ function printMulticaWorkspaceOperation(out) {
|
|
|
1803
1967
|
console.log(` remoteWrite=${out.remoteWrite} dingtalkSideEffect=${out.dingtalkSideEffect}`);
|
|
1804
1968
|
}
|
|
1805
1969
|
function printMulticaDeployment(out) {
|
|
1806
|
-
console.log(
|
|
1970
|
+
console.log(`${strong('Multica deploy')}: ${noun(out.workspace || '<unknown>')}`);
|
|
1807
1971
|
if (out.planId)
|
|
1808
1972
|
console.log(` plan: ${out.planId}`);
|
|
1809
1973
|
if (out.operationId)
|
|
@@ -1826,7 +1990,7 @@ function printMulticaDeployment(out) {
|
|
|
1826
1990
|
console.log(' triggers: unchanged');
|
|
1827
1991
|
}
|
|
1828
1992
|
function printPromotion(out) {
|
|
1829
|
-
console.log(
|
|
1993
|
+
console.log(`${strong('Promotion')}: ${noun(out.promotionId || out.candidateId || out.candidate?.candidateId || '<none>')}`);
|
|
1830
1994
|
if (out.planId)
|
|
1831
1995
|
console.log(` plan: ${out.planId}`);
|
|
1832
1996
|
if (out.routeId)
|
|
@@ -1877,33 +2041,84 @@ function rejectWorkspaceOptions(values, allowed, command) {
|
|
|
1877
2041
|
fail(`${command} 不接受参数: ${extras.join(', ')}`);
|
|
1878
2042
|
}
|
|
1879
2043
|
function printSetup(out) {
|
|
1880
|
-
console.log(`${out.dryRun ? 'DRY-RUN' : '✅'} dingtalk-agent setup`);
|
|
1881
|
-
console.log(` CLI: ${out.cli.executable}`);
|
|
1882
|
-
console.log(` 短命令: ${out.cli.alias}`);
|
|
1883
|
-
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)}`);
|
|
1884
2048
|
if (!out.shell.pathReady) {
|
|
1885
|
-
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${out.shell.activateCommand}`);
|
|
2049
|
+
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${noun(out.shell.activateCommand)}`);
|
|
1886
2050
|
if (out.shell.rcFile)
|
|
1887
|
-
console.log(` 新终端会从 ${out.shell.rcFile} 自动加载`);
|
|
2051
|
+
console.log(muted(` 新终端会从 ${out.shell.rcFile} 自动加载`));
|
|
1888
2052
|
}
|
|
1889
2053
|
printDoctor(out.doctor);
|
|
1890
|
-
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
|
+
}
|
|
1891
2100
|
}
|
|
1892
2101
|
function printUpgrade(out) {
|
|
1893
|
-
const
|
|
1894
|
-
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}(已是当前版本)`;
|
|
1895
2107
|
console.log(`${mark} dta upgrade: ${relation}`);
|
|
1896
|
-
console.log(` target=${out.target}`);
|
|
1897
|
-
console.log(` CLI=${out.executable}`);
|
|
2108
|
+
console.log(` target=${theme.noun(out.target)}`);
|
|
2109
|
+
console.log(` CLI=${theme.noun(out.executable)}`);
|
|
1898
2110
|
if (out.dryRun) {
|
|
1899
|
-
console.log(` 将执行: ${out.commands.install}`);
|
|
1900
|
-
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 以实际执行升级')}`);
|
|
1901
2114
|
}
|
|
1902
2115
|
else if (out.ready) {
|
|
1903
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` : ''}`)}`);
|
|
1904
2119
|
}
|
|
1905
2120
|
else {
|
|
1906
|
-
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${out.commands.verify}`);
|
|
2121
|
+
console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${theme.noun(out.commands.verify)}`);
|
|
1907
2122
|
}
|
|
1908
2123
|
}
|
|
1909
2124
|
//# sourceMappingURL=dingtalk-agent.js.map
|