@xdxer/dingtalk-agent 0.1.4-beta.9 → 0.1.5-beta.1

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.
Files changed (129) hide show
  1. package/CHANGELOG.md +229 -0
  2. package/README.en.md +89 -324
  3. package/README.md +88 -674
  4. package/dist/bin/dingtalk-agent.js +207 -21
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/agent-audit.js +1014 -89
  7. package/dist/src/agent-audit.js.map +1 -1
  8. package/dist/src/agent-enhance.js +41 -8
  9. package/dist/src/agent-enhance.js.map +1 -1
  10. package/dist/src/agent-platform.js +299 -0
  11. package/dist/src/agent-platform.js.map +1 -0
  12. package/dist/src/config.js +1 -7
  13. package/dist/src/config.js.map +1 -1
  14. package/dist/src/development-workspace.js +31 -5
  15. package/dist/src/development-workspace.js.map +1 -1
  16. package/dist/src/doctor.js +74 -15
  17. package/dist/src/doctor.js.map +1 -1
  18. package/dist/src/host-detect.js +146 -0
  19. package/dist/src/host-detect.js.map +1 -0
  20. package/dist/src/instruction-path.js +270 -0
  21. package/dist/src/instruction-path.js.map +1 -0
  22. package/dist/src/multica-deploy.js +78 -20
  23. package/dist/src/multica-deploy.js.map +1 -1
  24. package/dist/src/multica-provider.js +1 -1
  25. package/dist/src/multica-provider.js.map +1 -1
  26. package/dist/src/opencode-evals.js +710 -225
  27. package/dist/src/opencode-evals.js.map +1 -1
  28. package/dist/src/opencode-isolation.js +124 -0
  29. package/dist/src/opencode-isolation.js.map +1 -0
  30. package/dist/src/opencode-provider.js +1 -0
  31. package/dist/src/opencode-provider.js.map +1 -1
  32. package/dist/src/opencode-workspace.js +21 -10
  33. package/dist/src/opencode-workspace.js.map +1 -1
  34. package/dist/src/remote-state-evals.js +2 -1
  35. package/dist/src/remote-state-evals.js.map +1 -1
  36. package/dist/src/robot-evals.js +2 -1
  37. package/dist/src/robot-evals.js.map +1 -1
  38. package/dist/src/setup.js +6 -5
  39. package/dist/src/setup.js.map +1 -1
  40. package/dist/src/skill-manager.js +141 -12
  41. package/dist/src/skill-manager.js.map +1 -1
  42. package/dist/src/skills.js +2 -1
  43. package/dist/src/skills.js.map +1 -1
  44. package/dist/src/types.js.map +1 -1
  45. package/dist/src/upgrade.js +23 -27
  46. package/dist/src/upgrade.js.map +1 -1
  47. package/dist/src/version.js +73 -0
  48. package/dist/src/version.js.map +1 -0
  49. package/docs/ARCHITECTURE.md +232 -0
  50. package/docs/INSTALLATION.md +3 -3
  51. package/docs/PRIOR-ART.md +122 -0
  52. package/docs/SELF-TEST.md +182 -0
  53. package/docs/assets/agent-delivery-lifecycle.svg +103 -0
  54. package/docs/schemas/agent-platform.schema.json +13 -0
  55. package/docs/schemas/project.schema.json +3 -0
  56. package/docs/schemas/release-readiness.schema.json +2 -1
  57. package/evals/README.md +17 -0
  58. package/examples/agents/README.md +43 -0
  59. package/examples/agents/fde-coach/AGENTS.md +26 -17
  60. package/examples/agents/release-manager/AGENTS.md +26 -17
  61. package/lab/README.md +3 -3
  62. package/lab/agent-eval/catalog.json +5 -5
  63. package/lab/agent-eval/classic-failures.json +9 -9
  64. package/lab/agent-eval/completion-gate-regression.json +6 -6
  65. package/lab/agent-eval/remote-state-workspace/opencode.json +1 -1
  66. package/lab/agent-eval/workspace/AGENTS.md +1 -1
  67. package/lab/project-workspace/fake-multica-provider.mjs +17 -6
  68. package/lab/project-workspace/opencode-provider-suite.json +2 -2
  69. package/lab/robot-eval/suite.json +1 -1
  70. package/lab/robot-eval/workspace/AGENTS.md +1 -1
  71. package/lab/schemas/agent-eval-catalog.schema.json +1 -1
  72. package/package.json +18 -13
  73. package/skills/README.md +23 -0
  74. package/skills/core/dingtalk-agent-compose/SKILL.md +151 -0
  75. package/skills/core/dingtalk-agent-compose/assets/AGENTS.template.md +35 -0
  76. package/skills/core/dingtalk-agent-compose/assets/role-skill.template.md +32 -0
  77. package/skills/core/dingtalk-agent-compose/evals/evals.json +129 -0
  78. package/skills/{dingtalk-agent-compose → core/dingtalk-agent-compose}/references/agent-definition-contract.md +3 -3
  79. package/skills/core/dingtalk-agent-compose/references/host-loading-contract.md +58 -0
  80. package/skills/core/dingtalk-agent-compose/references/hosts/claude-code.md +48 -0
  81. package/skills/core/dingtalk-agent-compose/references/hosts/opencode.md +77 -0
  82. package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/SKILL.md +57 -8
  83. package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/assets/eval-catalog.template.json +1 -1
  84. package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/evals/evals.json +22 -0
  85. package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/references/eval-topology.md +14 -0
  86. package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/references/evidence-contract.md +21 -0
  87. package/skills/core/dingtalk-agent-eval/references/failure-to-case.md +35 -0
  88. package/skills/core/dingtalk-agent-eval/references/interactive-debug-channels.md +93 -0
  89. package/skills/core/dingtalk-agent-eval/references/local-connector-smoke.md +75 -0
  90. package/skills/core/dingtalk-basic-behavior/SKILL.md +87 -0
  91. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/memory-and-evolution.md +12 -0
  92. package/skills/core/dingtalk-basic-behavior/references/risk-authority-and-privacy.md +62 -0
  93. package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/task-lifecycle.md +15 -3
  94. package/skills/core/dingtalk-basic-behavior/references/truth-and-recovery.md +65 -0
  95. package/skills/platforms/deap/PLATFORM.md +3 -0
  96. package/skills/platforms/multica-dingtalk/PLATFORM.md +40 -0
  97. package/skills/{dingtalk-agent-boot-multica → platforms/multica-dingtalk/dingtalk-agent-boot-multica}/SKILL.md +4 -4
  98. package/skills/{dingtalk-agent-deploy → platforms/multica-dingtalk/dingtalk-agent-deploy-multica}/SKILL.md +1 -1
  99. package/skills/platforms/multica-dingtalk/multica-external/SKILL.md +282 -0
  100. package/skills/platforms/multica-dingtalk/multica-external/scripts/bootstrap.sh +78 -0
  101. package/skills/platforms/multica-dingtalk/multica-external/scripts/multica_ext.py +1180 -0
  102. package/docs/SECOND-AGENT-ACCEPTANCE.md +0 -62
  103. package/docs/architecture/agent-memory-topology.png +0 -0
  104. package/docs/architecture/agent-memory-topology.svg +0 -132
  105. package/docs/architecture/dingtalk-agent-blueprint.png +0 -0
  106. package/docs/architecture/durable-async-agent-runtime.png +0 -0
  107. package/docs/architecture/general-agent-kernel-topology.png +0 -0
  108. package/docs/architecture/provider-bound-development-workspace.png +0 -0
  109. package/docs/architecture/task-completion-gate.png +0 -0
  110. package/skills/dingtalk-agent-compose/SKILL.md +0 -110
  111. package/skills/dingtalk-agent-compose/assets/AGENTS.template.md +0 -26
  112. package/skills/dingtalk-agent-compose/assets/role-skill.template.md +0 -24
  113. package/skills/dingtalk-agent-compose/evals/evals.json +0 -94
  114. package/skills/dingtalk-agent-compose/references/opencode-host-contract.md +0 -65
  115. package/skills/dingtalk-basic-behavior/SKILL.md +0 -146
  116. /package/skills/{dingtalk-agent-compose → core/dingtalk-agent-compose}/assets/agent.bindings.dingtalk-doc.template.json +0 -0
  117. /package/skills/{dingtalk-agent-compose → core/dingtalk-agent-compose}/assets/agent.bindings.local.template.json +0 -0
  118. /package/skills/{dingtalk-agent-compose/assets → core/dingtalk-agent-compose/assets/hosts/opencode}/opencode.template.json +0 -0
  119. /package/skills/{dingtalk-agent-compose → core/dingtalk-agent-compose}/references/storage-routing.md +0 -0
  120. /package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/references/scenario-taxonomy.md +0 -0
  121. /package/skills/{dingtalk-agent-eval → core/dingtalk-agent-eval}/references/storage-modes.md +0 -0
  122. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/assets/memory-candidate-proposal.json +0 -0
  123. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/assets/task-checkpoint.json +0 -0
  124. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/action-contract.md +0 -0
  125. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/event-to-behavior.md +0 -0
  126. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/perception-and-gates.md +0 -0
  127. /package/skills/{dingtalk-basic-behavior → core/dingtalk-basic-behavior}/references/runtime-modes.md +0 -0
  128. /package/skills/{dingtalk-agent-deploy → platforms/multica-dingtalk/dingtalk-agent-deploy-multica}/references/multica-deployment-contract.md +0 -0
  129. /package/skills/{dingtalk-agent-deploy → platforms/multica-dingtalk/dingtalk-agent-deploy-multica}/references/promotion-observation-contract.md +0 -0
@@ -1,13 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  // dingtalk-agent —— 钉钉数字员工的标准范式(TypeScript source)。
3
3
  //
4
- // CLI = 拦 标准动作:可程序化、可强制、可验证。撞上去没得商量。
5
4
  // Skill = 劝 判断:只有 LLM 能做的(该不该答、话题归属、怎么写点评)。
6
- // 本体 = 它是谁 + 它知道什么。git clone 就带走。
5
+ // CLI = 标准动作:可程序化、可强制、可验证。撞上去没得商量。
6
+ // DWS = 做 真正的钉钉产品能力;本文件只在需要冻结事务边界时包一层。
7
7
  //
8
- // **分界线:凡是能程序化的,收进 CLI;凡是需要判断的,留在 Skill。**
8
+ // 本体(AGENTS.md + Role Skills)负责"它是谁、它知道什么",git clone 就带走;
9
+ // 它是被上面三者加载和校验的对象,不是第四个执行者。
9
10
  //
11
+ // **分界线:凡是能程序化的,收进 CLI;凡是需要判断的,留在 Skill。**
10
12
  // 因为:文档会被漏读、误读、自我说服;**撞到闸门上就没得商量。**
13
+ //
14
+ // 完整架构见 docs/ARCHITECTURE.md。
11
15
  import { parseArgs } from 'node:util';
12
16
  import { join, relative, resolve } from 'node:path';
13
17
  import { existsSync, readFileSync, realpathSync } from 'node:fs';
@@ -38,7 +42,8 @@ import { upgradeAgent } from '../src/upgrade.js';
38
42
  import { checkpointTask, showTaskCheckpoint } from '../src/memory/task-checkpoints.js';
39
43
  import { upsertOperationalMemory } from '../src/memory/operational.js';
40
44
  import { proposeMemoryCandidate, publishMemoryCandidate, reviewMemoryCandidate, showMemoryCandidate, } from '../src/memory/candidates.js';
41
- import { installGlobalSkill, skillStatus, uninstallGlobalSkill, upgradeGlobalSkill, } from '../src/skill-manager.js';
45
+ import { installBundledSkills, installGlobalSkill, skillStatus, skillSuiteStatus, uninstallBundledSkills, uninstallGlobalSkill, upgradeBundledSkills, upgradeGlobalSkill, } from '../src/skill-manager.js';
46
+ import { agentPlatformReadiness, MANAGED_AGENT_PLATFORMS, multicaTargets, platformDocPath, platformSkillForRole, requireSupportedAgentPlatform, resolveAgentPlatform, resolveEndpoint, statusLabel as platformStatusLabel, useAgentPlatform, } from '../src/agent-platform.js';
42
47
  const PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
43
48
  const PACKAGE_JSON = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
44
49
  // ROOT = **你的工作区**(当前目录),不是包所在的目录。
@@ -56,16 +61,16 @@ dta —— 给 Agent 安装钉钉员工的基础行为和工作环境
56
61
  · 从本地目录或钉钉文档加载身份、记忆和知识
57
62
 
58
63
  开始使用:
59
- dta setup 首次配置 CLI、DWS 和基础行为 Skill
64
+ dta setup 首次配置 CLI、DWS 和内置 Skill(基础行为 + Agent 装配 + 交付后评测)
60
65
  dta bootstrap --json 为当前 Agent 会话加载工作区
61
66
  dta agent enhance / audit 安全增强已有仓库,再审计定义、存储与 Skill 真加载
62
67
  dta info / dta workspace doctor <name> 查看 Project 并只读诊断 Workspace
63
- dta deploy ... / dta promote ... 预览 Multica 受控部署或已验版本晋级
68
+ dta agent-platform use <platform> → dta deploy / dta promote 声明平台归属并装平台技能包,再受控部署与晋级
64
69
 
65
70
  维护环境:
66
71
  dta doctor 检查哪里没装好,并给出修复提示
67
72
  dta upgrade 自升级,再重新检查完整环境
68
- dta skill status 查看 Claude Code、Codex、OpenCode 能否发现 Skill
73
+ dta skill status 查看内置 Skill 的版本状态与三个客户端能否发现(可加 name 只查一个)
69
74
 
70
75
  接入钉钉事件和可靠外发:dta help runtime
71
76
  `;
@@ -232,6 +237,8 @@ async function main() {
232
237
  return;
233
238
  }
234
239
  if (cmd === 'deploy') {
240
+ const platformForDeploy = requireSupportedAgentPlatform('deploy', PROJECT_START);
241
+ disclosePlatformSkill(platformForDeploy, 'deploy');
235
242
  const { values: o, positionals } = parseArgs({
236
243
  args: argv.slice(1), allowPositionals: true,
237
244
  options: {
@@ -307,6 +314,8 @@ async function main() {
307
314
  return;
308
315
  }
309
316
  if (cmd === 'promote') {
317
+ const platformForPromote = requireSupportedAgentPlatform('promote', PROJECT_START);
318
+ disclosePlatformSkill(platformForPromote, 'deploy');
310
319
  const { values: o, positionals } = parseArgs({
311
320
  args: argv.slice(1), allowPositionals: true,
312
321
  options: {
@@ -366,6 +375,8 @@ async function main() {
366
375
  return;
367
376
  }
368
377
  if (cmd === 'observe') {
378
+ const platformForObserve = requireSupportedAgentPlatform('observe', PROJECT_START);
379
+ disclosePlatformSkill(platformForObserve, 'deploy');
369
380
  const { values: o, positionals } = parseArgs({
370
381
  args: argv.slice(1), allowPositionals: true,
371
382
  options: {
@@ -676,28 +687,112 @@ async function main() {
676
687
  allowPositionals: true,
677
688
  options: {
678
689
  name: { type: 'string' }, 'dry-run': { type: 'boolean' }, json: { type: 'boolean' },
690
+ 'allow-downgrade': { type: 'boolean' },
679
691
  },
680
692
  });
681
693
  if (positionals.length > 1)
682
694
  fail('skill 最多接受一个 Skill name');
683
- const options = { dryRun: o['dry-run'], name: o.name || positionals[0] };
695
+ const name = o.name || positionals[0];
696
+ const dryRun = Boolean(o['dry-run']);
697
+ const allowDowngrade = Boolean(o['allow-downgrade']);
684
698
  let out;
685
- if (sub === 'install')
686
- out = installGlobalSkill(PACKAGE_ROOT, options);
687
- else if (sub === 'status')
688
- out = skillStatus(PACKAGE_ROOT, options);
689
- else if (sub === 'upgrade')
690
- out = upgradeGlobalSkill(PACKAGE_ROOT, options);
691
- else if (sub === 'uninstall')
692
- out = uninstallGlobalSkill(PACKAGE_ROOT, options);
693
- else
699
+ if (sub === 'install') {
700
+ out = name
701
+ ? installGlobalSkill(PACKAGE_ROOT, { dryRun, name, allowDowngrade })
702
+ : installBundledSkills(PACKAGE_ROOT, { dryRun, allowDowngrade });
703
+ }
704
+ else if (sub === 'status') {
705
+ out = name ? skillStatus(PACKAGE_ROOT, { dryRun, name }) : skillSuiteStatus(PACKAGE_ROOT, { dryRun });
706
+ }
707
+ else if (sub === 'upgrade') {
708
+ out = name
709
+ ? upgradeGlobalSkill(PACKAGE_ROOT, { dryRun, name, allowDowngrade })
710
+ : upgradeBundledSkills(PACKAGE_ROOT, { dryRun, allowDowngrade });
711
+ }
712
+ else if (sub === 'uninstall') {
713
+ out = name
714
+ ? uninstallGlobalSkill(PACKAGE_ROOT, { dryRun, name })
715
+ : uninstallBundledSkills(PACKAGE_ROOT, { dryRun });
716
+ }
717
+ else {
694
718
  fail(`不认识的 skill 子命令: ${sub || '(缺失)'}`, 1, `可用命令: dta skill install | status | upgrade | uninstall${suggest(sub || '', ['install', 'status', 'upgrade', 'uninstall'], 'dta skill')}`);
719
+ }
695
720
  if (o.json)
696
721
  console.log(JSON.stringify(out, null, 2));
722
+ else if ('skills' in out)
723
+ for (const item of out.skills)
724
+ printSkillStatus(item, sub, dryRun);
697
725
  else
698
- printSkillStatus(out, sub, Boolean(o['dry-run']));
726
+ printSkillStatus(out, sub, dryRun);
699
727
  return;
700
728
  }
729
+ // ── agent-platform:工作区归属的 managed agent platform;平台工具包按选择惰性安装。──
730
+ if (cmd === 'agent-platform') {
731
+ const { values: o, positionals } = parseArgs({
732
+ args: argv.slice(2),
733
+ allowPositionals: true,
734
+ options: { json: { type: 'boolean' }, 'no-install': { type: 'boolean' } },
735
+ });
736
+ if (sub === 'list') {
737
+ if (positionals.length)
738
+ fail('agent-platform list 不接受位置参数');
739
+ const out = { $schema: 'dingtalk-agent/agent-platform-list@1', platforms: MANAGED_AGENT_PLATFORMS };
740
+ if (o.json)
741
+ console.log(JSON.stringify(out, null, 2));
742
+ else
743
+ for (const platform of MANAGED_AGENT_PLATFORMS)
744
+ printAgentPlatform(platform);
745
+ return;
746
+ }
747
+ if (sub === 'show') {
748
+ if (positionals.length)
749
+ fail('agent-platform show 不接受位置参数');
750
+ const out = resolveAgentPlatform(PROJECT_START);
751
+ const readiness = out.definition ? agentPlatformReadiness(out.definition.name, process.env, undefined, PROJECT_START) : [];
752
+ const targets = out.definition?.name === 'multica-dingtalk' ? multicaTargets() : [];
753
+ const endpoint = out.definition ? resolveEndpoint(out.definition.name, PROJECT_START) : null;
754
+ const doc = out.definition ? platformDocPath(PACKAGE_ROOT, out.definition.name) : null;
755
+ if (o.json)
756
+ console.log(JSON.stringify({ ...out, endpoint, readiness, targets, doc }, null, 2));
757
+ else {
758
+ printAgentPlatformResolution(out);
759
+ printEndpoint(endpoint);
760
+ printAgentPlatformReadiness(readiness);
761
+ printMulticaTargets(targets);
762
+ printPlatformDoc(out.definition?.name);
763
+ }
764
+ return;
765
+ }
766
+ if (sub === 'use') {
767
+ if (positionals.length !== 1)
768
+ fail('agent-platform use 需要且只接受一个 platform name');
769
+ const out = useAgentPlatform(PROJECT_START, positionals[0], {
770
+ packageRoot: PACKAGE_ROOT, installSkills: !o['no-install'],
771
+ });
772
+ const readiness = out.definition ? agentPlatformReadiness(out.definition.name, process.env, undefined, PROJECT_START) : [];
773
+ const targets = out.definition?.name === 'multica-dingtalk' ? multicaTargets() : [];
774
+ const endpoint = out.definition ? resolveEndpoint(out.definition.name, PROJECT_START) : null;
775
+ const doc = out.definition ? platformDocPath(PACKAGE_ROOT, out.definition.name) : null;
776
+ if (o.json)
777
+ console.log(JSON.stringify({ ...out, endpoint, readiness, targets, doc }, null, 2));
778
+ else {
779
+ console.log(`✅ 工作区已归属 ${out.definition?.label}(写入 ${out.written})`);
780
+ for (const install of out.skillInstalls)
781
+ printSkillStatus(install, 'install', false);
782
+ if (!out.skillInstalls.length) {
783
+ console.log(out.definition?.skills.length
784
+ ? ` 已跳过平台技能包安装(--no-install):${out.definition.skills.map((item) => item.name).join(', ')}`
785
+ : ' 该平台无需额外技能包。');
786
+ }
787
+ printEndpoint(endpoint);
788
+ printAgentPlatformReadiness(readiness);
789
+ printMulticaTargets(targets);
790
+ printPlatformDoc(out.definition?.name);
791
+ }
792
+ return;
793
+ }
794
+ fail(`不认识的 agent-platform 子命令: ${sub || '(缺失)'}`, 1, `可用命令: dta agent-platform list | show | use <platform>${suggest(sub || '', ['list', 'show', 'use'], 'dta agent-platform')}`);
795
+ }
701
796
  // ── bootstrap:当前 Agent Session 按需发现/拉取语义上下文。──
702
797
  if (cmd === 'bootstrap') {
703
798
  const { values: o } = parseArgs({
@@ -1241,7 +1336,8 @@ async function main() {
1241
1336
  return;
1242
1337
  }
1243
1338
  fail(`不认识的命令: ${cmd}`, 1, `运行 dta --help 查看全部命令${suggest(cmd, [
1244
- 'setup', 'upgrade', 'doctor', 'skill', 'bootstrap', 'init', 'prepare', 'run', 'dispatch', 'task', 'memory', 'act',
1339
+ 'setup', 'upgrade', 'doctor', 'skill', 'agent-platform', 'bootstrap', 'init', 'prepare', 'run', 'dispatch', 'task', 'memory', 'act',
1340
+ 'lab', 'listen', 'deploy', 'promote', 'observe',
1245
1341
  'agent',
1246
1342
  'info', 'workspace',
1247
1343
  ])}`);
@@ -1373,14 +1469,84 @@ function printAgentEnhance(out) {
1373
1469
  console.log(` backup=${out.backupRoot}`);
1374
1470
  console.log(` audit=${out.audit.status} missing=${out.audit.missing.join(', ') || '-'}`);
1375
1471
  }
1472
+ function printAgentPlatform(platform) {
1473
+ console.log(`${platform.status === 'supported' ? '✅' : '⏳'} ${platform.name} · ${platform.label} · ${platformStatusLabel(platform.status)}`);
1474
+ console.log(` ${platform.description}`);
1475
+ for (const skill of platform.skills)
1476
+ console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
1477
+ if (platform.commands.length)
1478
+ console.log(` 平台命令: ${platform.commands.map((item) => `dta ${item}`).join(' · ')}`);
1479
+ }
1480
+ function printAgentPlatformResolution(out) {
1481
+ if (!out.platform) {
1482
+ console.log('⚠️ 当前工作区未声明 managed agent platform');
1483
+ console.log(' 运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。');
1484
+ return;
1485
+ }
1486
+ const known = out.definition;
1487
+ console.log(`${known ? '✅' : '❌'} 当前 platform: ${out.platform}${known ? ` · ${known.label} · ${platformStatusLabel(known.status)}` : '(未知)'}`);
1488
+ console.log(` 来源: ${out.source}${out.file ? ` · ${out.file}` : ''}`);
1489
+ for (const skill of known?.skills || [])
1490
+ console.log(` 技能[${skill.role}] ${skill.name} —— ${skill.purpose}`);
1491
+ }
1492
+ // 披露:dta 层平台命令关联到平台内确切的 Skill(诊断信息走 stderr,不污染 --json stdout)。
1493
+ function disclosePlatformSkill(resolution, role) {
1494
+ const skillName = resolution.definition ? platformSkillForRole(resolution.definition.name, role) : null;
1495
+ if (skillName)
1496
+ console.error(`提示: 平台 ${resolution.definition.name} 的该命令方法学由 Skill ${skillName} 承载`);
1497
+ }
1498
+ function printEndpoint(endpoint) {
1499
+ if (!endpoint)
1500
+ return;
1501
+ if (endpoint.source === 'ambiguous') {
1502
+ console.log(` Endpoint: 多个已登录目标未选定(${endpoint.candidates.join(' / ')})——` +
1503
+ `用 ${endpoint.envVar} 或指定 profile 明确选择`);
1504
+ return;
1505
+ }
1506
+ if (!endpoint.endpoint) {
1507
+ console.log(` Endpoint: 未解析——设 ${endpoint.envVar} 或登录 multica 后生效`);
1508
+ return;
1509
+ }
1510
+ const mark = endpoint.confirmed ? '✅' : '⚠️';
1511
+ const note = endpoint.confirmed ? '' : '(建议/未确认,deploy 前需显式确认是预发还是生产)';
1512
+ console.log(` ${mark} Endpoint: ${endpoint.endpoint} · 来源: ${endpoint.source}${note}`);
1513
+ console.log(` (切换:设 ${endpoint.envVar}=<url>、写 dingtalk-agent.json#multicaEndpoint、或登录对应 profile;无需改代码)`);
1514
+ }
1515
+ function printPlatformDoc(platformName) {
1516
+ if (!platformName)
1517
+ return;
1518
+ const path = platformDocPath(PACKAGE_ROOT, platformName);
1519
+ if (path)
1520
+ console.log(` 平台说明: ${path}\n (切换到该平台后请阅读,了解各技能用途与交付链)`);
1521
+ }
1522
+ function printMulticaTargets(targets) {
1523
+ if (!targets.length)
1524
+ return;
1525
+ console.log(' 本机 Multica 登录目标(发布前必须与用户确认 endpoint 与 workspace):');
1526
+ for (const target of targets) {
1527
+ console.log(` - profile=${target.profile} · ${target.serverUrl}${target.workspaceId ? ` · workspace=${target.workspaceId}` : ''}`);
1528
+ }
1529
+ }
1530
+ function printAgentPlatformReadiness(checks) {
1531
+ for (const check of checks) {
1532
+ console.log(` ${check.ok ? '✅' : '⚠️'} ${check.summary}`);
1533
+ if (check.hint)
1534
+ console.log(` ${check.hint}`);
1535
+ }
1536
+ }
1376
1537
  function printSkillStatus(out, action, dryRun) {
1377
1538
  const prefix = dryRun ? 'DRY-RUN' : '✅';
1378
1539
  const verb = action === 'status' ? '全局 Skill 状态' : `skill ${action}`;
1379
1540
  console.log(`${prefix} ${verb}: ${out.name}`);
1380
1541
  console.log(` manager=${out.manager} bundled=${out.bundled.skillVersion || '-'}`);
1381
1542
  console.log(` canonical=${out.canonical.path}`);
1382
- console.log(` installed=${out.canonical.exists} installedVersion=${out.canonical.installedVersion || '-'} ` +
1383
- `current=${out.canonical.current}`);
1543
+ console.log(` installed=${out.canonical.exists} ` +
1544
+ `${out.canonical.installedVersion || '—'} → ${out.bundled.skillVersion} ` +
1545
+ `state=${out.canonical.state}`);
1546
+ if (out.operation?.after) {
1547
+ console.log(` ${out.operation.before.installedVersion || '—'}(${out.operation.before.state})` +
1548
+ ` → ${out.operation.after.installedVersion}(${out.operation.after.state})`);
1549
+ }
1384
1550
  if (out.operation)
1385
1551
  console.log(` delegated: ${out.operation.command}`);
1386
1552
  for (const client of out.clients) {
@@ -1400,12 +1566,32 @@ function printDoctor(out) {
1400
1566
  if (check.fix)
1401
1567
  console.log(` 修复: ${check.fix}`);
1402
1568
  }
1569
+ if (out.hosts.length) {
1570
+ // Host 面回答"本地能在哪跑",不改变上面的 ready 结论。
1571
+ console.log('\n本机 Coding Agent:');
1572
+ const width = Math.max(...out.hosts.map((host) => displayWidth(host.label)));
1573
+ for (const host of out.hosts) {
1574
+ const label = host.label + ' '.repeat(width - displayWidth(host.label));
1575
+ const where = host.cli.found
1576
+ ? [host.cli.path, host.cli.version].filter(Boolean).join(' ')
1577
+ : `未找到 ${host.cli.command}`;
1578
+ console.log(` ${host.cli.found ? '✅' : '❌'} ${label} ${where}`);
1579
+ console.log(` Skill 可见性: ${host.skillExposure.exists ? '已暴露' : '未暴露'} · ${host.skillExposureRoot}`);
1580
+ }
1581
+ }
1403
1582
  if (out.nextSteps.length) {
1404
1583
  console.log('\n下一步:');
1405
1584
  for (const step of out.nextSteps)
1406
1585
  console.log(` ${step}`);
1407
1586
  }
1408
1587
  }
1588
+ /** 全角字符按两列计宽,避免中英混排的 Host 列表错位。 */
1589
+ function displayWidth(text) {
1590
+ let width = 0;
1591
+ for (const char of text)
1592
+ width += /[ᄀ-ᅟ⺀-꓏가-힣豈-﫿︰-﹯＀-⦆¢-₩]/.test(char) ? 2 : 1;
1593
+ return width;
1594
+ }
1409
1595
  function printProjectInfo(out) {
1410
1596
  console.log(`dingtalk-agent Project · ${out.project.name}`);
1411
1597
  console.log(` root=${out.root}`);