@xdxer/dingtalk-agent 0.1.4-beta.6 → 0.1.4-beta.8

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 (60) hide show
  1. package/README.md +12 -2
  2. package/dist/bin/dingtalk-agent.js +60 -333
  3. package/dist/bin/dingtalk-agent.js.map +1 -1
  4. package/dist/src/init.js +1 -1
  5. package/dist/src/init.js.map +1 -1
  6. package/dist/src/upgrade.js +137 -0
  7. package/dist/src/upgrade.js.map +1 -0
  8. package/docs/INSTALLATION.md +24 -0
  9. package/package.json +10 -12
  10. package/dist/src/boot.js +0 -70
  11. package/dist/src/boot.js.map +0 -1
  12. package/dist/src/duty.js +0 -74
  13. package/dist/src/duty.js.map +0 -1
  14. package/dist/src/kb.js +0 -240
  15. package/dist/src/kb.js.map +0 -1
  16. package/dist/src/runs.js +0 -79
  17. package/dist/src/runs.js.map +0 -1
  18. package/docs/ARCHITECTURE.md +0 -219
  19. package/docs/MINIMAL-WORKSPACE-V1.md +0 -172
  20. package/docs/OPEN-SOURCE-REFERENCES.md +0 -107
  21. package/docs/SELF-TEST.md +0 -252
  22. package/docs//345/206/205/347/275/221/345/256/236/347/233/270.md +0 -77
  23. package/evals/baselines/2026-07-14/behavior-summary.json +0 -28
  24. package/evals/baselines/2026-07-14/contract-summary.json +0 -18
  25. package/evals/baselines/2026-07-14/live-canary-summary.json +0 -25
  26. package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/SKILL.md +0 -72
  27. package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/action-contract.md +0 -31
  28. package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/event-to-behavior.md +0 -22
  29. package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/memory-and-evolution.md +0 -25
  30. package/evals/baselines/2026-07-15/dingtalk-basic-behavior-0.3.0/references/runtime-modes.md +0 -34
  31. package/evals/baselines/2026-07-15/task-lifecycle-summary.json +0 -50
  32. package/evals/evals.json +0 -327
  33. package/evals/fixtures/dm-ambiguous-send.json +0 -4
  34. package/evals/fixtures/dm-blocked.json +0 -4
  35. package/evals/fixtures/dm-clear.json +0 -4
  36. package/evals/fixtures/dm-discussion.json +0 -4
  37. package/evals/fixtures/dm-doc-write-no-tool.json +0 -4
  38. package/evals/fixtures/dm-long-task-ack.json +0 -4
  39. package/evals/fixtures/dm-nonblocking-gap.json +0 -4
  40. package/evals/fixtures/dm-structured-task.json +0 -4
  41. package/evals/fixtures/group.json +0 -10
  42. package/evals/fixtures/mentioned.json +0 -3
  43. package/evals/run-contract-evals.mjs +0 -1125
  44. package/evals/run-shadow-evals.mjs +0 -267
  45. package/evals/runners/README.md +0 -66
  46. package/evals/runners/claude-shadow.mjs +0 -533
  47. package/evals/schemas/action-request.schema.json +0 -77
  48. package/evals/shadow-evals.json +0 -133
  49. package/skills/AGENTS.md +0 -104
  50. package/skills//344/273/273/345/212/241.md +0 -48
  51. package/skills//345/237/272/347/241/200/350/241/214/344/270/272.md +0 -44
  52. package/skills//345/277/203/350/267/263.md +0 -79
  53. package/skills//346/266/210/346/201/257.md +0 -50
  54. package/skills//347/237/245/350/257/206.md +0 -55
  55. package/skills//350/257/204/346/265/213.md +0 -62
  56. package/skills//351/222/211/351/222/211.md +0 -64
  57. package/templates/ontology/index.md +0 -24
  58. package/templates/ontology/self/access.md +0 -38
  59. package/templates/ontology/self/role-spec.md +0 -34
  60. package/templates/ontology/self/workspace.md +0 -41
package/README.md CHANGED
@@ -62,6 +62,16 @@ dta --version
62
62
  dta doctor
63
63
  ```
64
64
 
65
+ 之后升级不再重复安装步骤,直接运行:
66
+
67
+ ```bash
68
+ dta upgrade # beta 版默认继续跟随 beta
69
+ dta upgrade --channel latest # 显式切换稳定通道
70
+ dta upgrade --dry-run # 只查看目标版本和将执行的命令
71
+ ```
72
+
73
+ 升级完成后,新的 CLI 会自动重新执行 setup,复核 PATH、DWS、Skill 与三个 Agent 客户端。
74
+
65
75
  安装后推荐使用短命令 `dta`;完整名称 `dingtalk-agent` 与它完全等价。错误会同时输出原因和一条可复制的 `提示:`,命令或子命令拼错时会给出最接近的建议。
66
76
 
67
77
  安装后,Skill 只有一份 canonical copy:
@@ -243,7 +253,6 @@ dingtalk-agent init
243
253
  dingtalk-agent prepare --event-file event.json --json
244
254
  dingtalk-agent help runtime
245
255
  dingtalk-agent help adapters
246
- dingtalk-agent eval contract
247
256
  ```
248
257
 
249
258
  `listen` 是可选的开发联调 Adapter,不是 Agent 主进程。云端 Driver、Claude Code 插件或本地 DWS 都可以提供事件,并从标准化事件之后复用同一 Session / Run / Action 内核。
@@ -256,11 +265,12 @@ npm run typecheck
256
265
  npm run eval:contract
257
266
  ```
258
267
 
259
- 当前确定性合同包含 **29 个场景**,覆盖:
268
+ 当前确定性合同包含 **31 个场景**,覆盖:
260
269
 
261
270
  - 通过 `npx skills` 委托全局 Skill 安装、发现、重装和卸载;
262
271
  - 首次 setup、用户级 PATH、DWS 版本/认证和三端客户端发现;
263
272
  - `dta` 短命令安装,以及命令、子命令和参数错误的可恢复提示;
273
+ - CLI 自升级、新 binary 版本校验和升级后 setup 复核;
264
274
  - 无 init bootstrap、本地/远端 Storage 与类型闸门;
265
275
  - Direct Session 外发边界;
266
276
  - Session continuation、Wait、幂等和目标防篡改;
@@ -13,10 +13,6 @@ import { join, resolve } from 'node:path';
13
13
  import { readFileSync } from 'node:fs';
14
14
  import { spawn, spawnSync } from 'node:child_process';
15
15
  import * as cfgmod from '../src/config.js';
16
- import * as kbmod from '../src/kb.js';
17
- import * as runsmod from '../src/runs.js';
18
- import * as dutymod from '../src/duty.js';
19
- import { boot } from '../src/boot.js';
20
16
  import { init } from '../src/init.js';
21
17
  import { ackDispatch, listPendingDispatches, prepareSession } from '../src/sessions.js';
22
18
  import { readEventFile, consumeNdjson, heartbeatEvent } from '../src/driver.js';
@@ -25,6 +21,7 @@ import { resolvePackageRoot } from '../src/package-root.js';
25
21
  import { bootstrap } from '../src/bootstrap.js';
26
22
  import { doctor } from '../src/doctor.js';
27
23
  import { setup } from '../src/setup.js';
24
+ import { upgradeAgent } from '../src/upgrade.js';
28
25
  import { installGlobalSkill, skillStatus, uninstallGlobalSkill, upgradeGlobalSkill, } from '../src/skill-manager.js';
29
26
  const PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
30
27
  const PACKAGE_JSON = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
@@ -34,45 +31,23 @@ const ROOT = process.env.DTA_ROOT
34
31
  ? resolve(process.env.DTA_ROOT)
35
32
  : (cfgmod.findRoot(process.cwd()) || process.cwd());
36
33
  const HELP = `
37
- dta(dingtalk-agent)—— Skill-first 的钉钉数字员工行为容器
34
+ dta —— 给 Agent 安装钉钉员工的基础行为和工作环境
38
35
 
39
- 用法: dta <command> [options]
40
- 完整名称 dingtalk-agent 与 dta 完全等价。
36
+ 装好后,Agent 可以:
37
+ · 判断 @、单聊和群消息是否应该回应
38
+ · 通过 DWS 回复消息、协作并使用钉钉标准产品
39
+ · 从本地目录或钉钉文档加载身份、记忆和知识
41
40
 
42
- 首次安装或升级:
43
- npm install --global --prefix "$HOME/.local" --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${PACKAGE_JSON.version}
44
- "$HOME/.local/bin/dta" setup --skip-cli-install
45
- setup 用户级安装 CLI、修复 PATH、安装 Skill、检查 DWS
46
- doctor 检查 PATH / Node / DWS / Skill / Agent 客户端
41
+ 开始使用:
42
+ dta setup 首次配置 CLI、DWS 和基础行为 Skill
43
+ dta bootstrap --json 为当前 Agent 会话加载工作区
47
44
 
48
- Skill(不要求 Workspace)
49
- skill install 安装全局 Basic Behavior(Claude Code + Codex + OpenCode)
50
- skill status 检查版本、漂移和客户端可发现性
51
- skill upgrade 通过 npx skills 重装当前包内 Skill
52
- skill uninstall 通过 npx skills 卸载全局 Skill
53
- 通用: [--dry-run] [--json];安装生命周期委托给 npx skills
45
+ 维护环境:
46
+ dta doctor 检查哪里没装好,并给出修复提示
47
+ dta upgrade 自升级,再重新检查完整环境
48
+ dta skill status 查看 Claude Code、Codex、OpenCode 能否发现 Skill
54
49
 
55
- 每个 Agent Session(不要求 init)
56
- bootstrap 发现当前本地 Workspace;不修改项目文件
57
- [--storage <uri>] local-dir:<path> | dingtalk-doc:<node-or-url>
58
- [--state-dir <path>] 远端文档只读快照目录
59
- [--profile <dws-profile>] [--json]
60
-
61
- 可信事件模式(可选;需要一次 init)
62
- init [--context-id X] 仅为 Prepared Run 建最小 Workspace
63
- prepare --event-file <file|-> 事件 → Session → Run
64
- act ack 对原消息贴「收到」;不代表接单
65
- act reply --text "…" 引用回复原消息
66
- act ask --text "…" 只问一个真正阻塞的问题
67
- act silence [--reason "…"] 不外发,但留下行为回执
68
- 通用: [--run <path>] [--dry-run] [--json]
69
-
70
- smoke 极简本地验收(不写钉钉)
71
- eval contract / behavior 完整合同或模型行为评测
72
-
73
- help runtime 事件宿主与 controller 命令
74
- help adapters 可选 DWS listen 适配器
75
- help legacy 查看兼容的本体、KB、值班与进化命令
50
+ 接入钉钉事件和可靠外发:dta help runtime
76
51
  `;
77
52
  const RUNTIME_HELP = `
78
53
  dingtalk-agent 可信事件运行时(可选宿主能力)
@@ -95,17 +70,6 @@ dingtalk-agent 可选 Driver / 开发联调适配器
95
70
 
96
71
  listen 不是 Agent 主入口。Claude Code、DWS 云端或其他宿主都可以直接提供事件。
97
72
  `;
98
- const LEGACY_HELP = `
99
- dingtalk-agent 兼容命令(不属于 P0 四对象主链)
100
-
101
- boot
102
- kb mount|list|sync|search
103
- duty --check|--run|--list
104
- todo
105
- log / feedback / runs / evolve
106
-
107
- 这些能力继续可用,但新增 Agent 应先安装全局 Skill;只有可信事件宿主才需要 runtime。
108
- `;
109
73
  function fail(msg, code = 1, hint = '') {
110
74
  console.error(`错误: ${msg}`);
111
75
  if (hint)
@@ -124,10 +88,6 @@ catch (e) {
124
88
  fail(message, Number(error?.exitCode) || 2, errorHint(message));
125
89
  }
126
90
  async function main() {
127
- if (cmd === 'help' && sub === 'legacy') {
128
- console.log(LEGACY_HELP);
129
- return;
130
- }
131
91
  if (cmd === 'help' && sub === 'runtime') {
132
92
  console.log(RUNTIME_HELP);
133
93
  return;
@@ -136,6 +96,9 @@ async function main() {
136
96
  console.log(ADAPTER_HELP);
137
97
  return;
138
98
  }
99
+ if (cmd === 'help' && sub) {
100
+ fail(`不认识的帮助主题: ${sub}`, 1, '运行 dta --help 回到产品入口;事件宿主可用 dta help runtime。');
101
+ }
139
102
  if (!cmd || cmd === '--help' || cmd === '-h' || cmd === 'help') {
140
103
  console.log(HELP);
141
104
  return;
@@ -144,7 +107,7 @@ async function main() {
144
107
  console.log(PACKAGE_JSON.version);
145
108
  return;
146
109
  }
147
- // ── setup / doctor:npx 永远可启动的首次使用入口。──
110
+ // ── setup / upgrade / doctor:机器级安装与环境闭环。──
148
111
  if (cmd === 'setup') {
149
112
  const { values: o } = parseArgs({
150
113
  args: argv.slice(1),
@@ -181,6 +144,27 @@ async function main() {
181
144
  process.exitCode = 2;
182
145
  return;
183
146
  }
147
+ if (cmd === 'upgrade') {
148
+ const { values: o } = parseArgs({
149
+ args: argv.slice(1),
150
+ options: {
151
+ channel: { type: 'string' }, version: { type: 'string' }, prefix: { type: 'string' },
152
+ 'dry-run': { type: 'boolean' }, force: { type: 'boolean' }, json: { type: 'boolean' },
153
+ },
154
+ });
155
+ const out = upgradeAgent(PACKAGE_ROOT, {
156
+ channel: o.channel,
157
+ version: o.version, prefix: o.prefix,
158
+ dryRun: o['dry-run'], force: o.force,
159
+ });
160
+ if (o.json)
161
+ console.log(JSON.stringify(out, null, 2));
162
+ else
163
+ printUpgrade(out);
164
+ if (!out.dryRun && !out.ready)
165
+ process.exitCode = 2;
166
+ return;
167
+ }
184
168
  // ── skill:唯一一次性的主入口;完全不依赖 Workspace。──
185
169
  if (cmd === 'skill') {
186
170
  const { values: o } = parseArgs({
@@ -426,285 +410,8 @@ async function main() {
426
410
  process.exitCode = 2;
427
411
  return;
428
412
  }
429
- // ── eval:宿主评测入口;shadow 永不调用 act / DWS。──
430
- if (cmd === 'eval') {
431
- const script = sub === 'contract'
432
- ? join(PACKAGE_ROOT, 'evals', 'run-contract-evals.mjs')
433
- : sub === 'shadow'
434
- ? join(PACKAGE_ROOT, 'evals', 'runners', 'claude-shadow.mjs')
435
- : sub === 'behavior'
436
- ? join(PACKAGE_ROOT, 'evals', 'run-shadow-evals.mjs')
437
- : '';
438
- if (!script)
439
- fail('eval 的子命令: contract / shadow / behavior');
440
- const childEnv = { ...process.env };
441
- // 合同评测会创建隔离工作区;继承宿主 DTA_ROOT 会让 Action Gate 错读外层 control store。
442
- delete childEnv.DTA_ROOT;
443
- const child = spawnSync(process.execPath, [script, ...argv.slice(2)], {
444
- cwd: ROOT,
445
- env: childEnv,
446
- stdio: 'inherit',
447
- });
448
- if (child.error)
449
- throw child.error;
450
- if (child.signal)
451
- throw new Error(`评测进程被 ${child.signal} 终止`);
452
- process.exitCode = child.status ?? 2;
453
- return;
454
- }
455
- if (cmd === 'smoke') {
456
- const script = join(PACKAGE_ROOT, 'evals', 'run-contract-evals.mjs');
457
- const childEnv = { ...process.env };
458
- delete childEnv.DTA_ROOT;
459
- const child = spawnSync(process.execPath, [script, '--smoke'], {
460
- cwd: ROOT, env: childEnv, stdio: 'inherit',
461
- });
462
- if (child.error)
463
- throw child.error;
464
- if (child.signal)
465
- throw new Error(`Smoke 被 ${child.signal} 终止`);
466
- process.exitCode = child.status ?? 2;
467
- return;
468
- }
469
- // ── kb ──
470
- if (cmd === 'kb') {
471
- const cfg = cfgmod.must(ROOT);
472
- const { values: o } = parseArgs({
473
- args: argv.slice(2), allowPositionals: true,
474
- options: {
475
- name: { type: 'string' }, from: { type: 'string' }, own: { type: 'string' },
476
- sync: { type: 'string' }, local: { type: 'string' }, force: { type: 'boolean' },
477
- },
478
- });
479
- if (sub === 'mount') {
480
- if (!o.name || !o.from)
481
- fail('要 --name 和 --from。源的写法见 --help');
482
- kbmod.parseSource(o.from); // 写错了当场炸
483
- const own = o.own || kbmod.EXTERNAL;
484
- const sync = o.sync || (own === kbmod.OWNED ? kbmod.PUSH : kbmod.PULL);
485
- if (own === kbmod.OWNED && sync === kbmod.PULL) {
486
- fail('owned 的真值在 Git,不该 pull —— 那会把远端的东西覆盖到本地。\n' +
487
- ' **所有权决定真值方向。** owned → push;external → pull。');
488
- }
489
- const local = o.local || join('.cache/kb', o.name);
490
- cfg.kb = (cfg.kb || []).filter((k) => k.name !== o.name);
491
- cfg.kb.push({ name: o.name, from: o.from, own, sync, local });
492
- cfgmod.save(ROOT, cfg);
493
- console.log(`✅ 挂上「${o.name}」 ${o.from}`);
494
- console.log(` 所有权=${own} · 同步=${sync} · 落在 ${local}`);
495
- console.log(own === kbmod.OWNED
496
- ? ' (真值在 Git,钉钉是暴露层。人在钉钉里改了 → sync 时会【停下来问】,不盲覆盖。)'
497
- : ' (真值在钉钉,本地只是【可丢弃的缓存】。过期了 kb search 会警告。)');
498
- return;
499
- }
500
- if (sub === 'list') {
501
- if (!cfg.kb?.length)
502
- return console.log('一个都没挂。 kb mount --help');
503
- for (const kb of cfg.kb) {
504
- const s = kbmod.stale(kb);
505
- console.log(` ${s ? '⚠️' : '·'} ${kb.name.padEnd(14)} ${kb.own.padEnd(9)} ${kb.sync.padEnd(5)} ${kb.from}`);
506
- console.log(` 落在 ${kb.local} 上次同步 ${kb._syncedAt || '从未'}${s ? ' ← **过期了,不许拿来回答**' : ''}`);
507
- }
508
- return;
509
- }
510
- if (sub === 'sync') {
511
- const targets = (cfg.kb || []).filter((k) => !o.name || k.name === o.name);
512
- if (!targets.length)
513
- fail('没有这个知识库。 kb list');
514
- for (const kb of targets) {
515
- if (kb.sync === kbmod.NONE) {
516
- console.log(` skip ${kb.name}(sync=none)`);
517
- continue;
518
- }
519
- if (kb.sync === kbmod.PULL)
520
- kbmod.pull(kb, ROOT, o.force);
521
- else
522
- kbmod.push(kb, ROOT, o.force);
523
- }
524
- cfgmod.save(ROOT, cfg);
525
- return;
526
- }
527
- if (sub === 'search') {
528
- const kw = argv[2];
529
- if (!kw)
530
- fail('要给关键词。 kb search "<关键词>"');
531
- kbmod.search(cfg, ROOT, kw);
532
- return;
533
- }
534
- fail('kb 的子命令: mount / list / sync / search');
535
- }
536
- // ── boot ──
537
- if (cmd === 'boot') {
538
- boot(cfgmod.must(ROOT), ROOT);
539
- return;
540
- }
541
- // ── duty ──
542
- if (cmd === 'duty') {
543
- const cfg = cfgmod.must(ROOT);
544
- const { values: o } = parseArgs({
545
- args: argv.slice(1), allowPositionals: true,
546
- options: { check: { type: 'boolean' }, run: { type: 'string' },
547
- list: { type: 'boolean' }, force: { type: 'boolean' } },
548
- });
549
- const duties = dutymod.loadDuties(cfg, ROOT);
550
- if (o.list) {
551
- const ks = Object.keys(duties);
552
- console.log(ks.length ? ks.join('\n')
553
- : '(值班表是空的 —— 母体出厂如此,这是【正确】的。在 .dingtalk-agent/config.json 的 duties 里加。)');
554
- return;
555
- }
556
- if (o.run) {
557
- const fn = duties[o.run];
558
- if (!fn)
559
- fail(`没有这个值班: ${o.run}(有: ${Object.keys(duties).join('、') || '无'})`);
560
- const s = fn();
561
- if (s.kind === '交付' && !dutymod.inDeliver() && !o.force) {
562
- return console.log(`⏸ 「${o.run}」是外发动作,静默时段顺延,**不打扰第三方**。`);
563
- }
564
- if (s.done)
565
- return console.log(`✅ 「${o.run}」已完成,本拍无需执行。${s.detail}`);
566
- console.log(`【${o.run}】该做了。${s.gap}`);
567
- console.log(` 剧本: ${s.playbook || '(没写剧本 —— 这个值班不合格)'}`);
568
- console.log(` ⚠️ 送达【回读确认】之后才准记 pass。没送达就写 pass = 自己骗自己。`);
569
- return;
570
- }
571
- // --check(默认)
572
- console.log('值班表(**完成状态在数据里,不在记忆里**;幂等,漏拍下一拍自愈)');
573
- console.log(` 现在 ${runsmod.now().slice(11, 16)} · ${dutymod.inNight() ? '夜间窗口(重活可跑)' : '白天(重活挂起)'} · 外发窗口${dutymod.inDeliver() ? '开' : '关'}`);
574
- const ids = Object.keys(duties);
575
- if (!ids.length) {
576
- console.log('\n (值班表是空的 —— 母体出厂如此。)');
577
- return;
578
- }
579
- const todo = [];
580
- for (const id of ids) {
581
- const s = duties[id]();
582
- const mark = s.done ? '✅ 已完成' : (s.due ? '⬜ 待补齐' : '⏸ 不在窗口');
583
- console.log(` ${s.id.padEnd(8)} [${s.kind}] ${mark} ${s.detail}${s.gap ? ' → ' + s.gap : ''}`);
584
- if (!s.done && s.due)
585
- todo.push(s.id);
586
- }
587
- if (todo.length) {
588
- console.log(`\n本拍要做: ${todo.map((t) => 'duty --run ' + t).join('、')}`);
589
- process.exit(1);
590
- }
591
- console.log('\n全部补齐,静默即可(**不要为此打扰主人**)');
592
- return;
593
- }
594
- // ── 留痕与进化 ──
595
- if (cmd === 'log' || cmd === 'logq') {
596
- const { values: o } = parseArgs({
597
- args: argv.slice(1),
598
- options: { did: { type: 'string' }, asked: { type: 'string' }, kind: { type: 'string' },
599
- secs: { type: 'string' }, r: { type: 'string' }, ev: { type: 'string' },
600
- ch: { type: 'string' }, issue: { type: 'string' },
601
- conv: { type: 'string' }, msg: { type: 'string' } },
602
- });
603
- if (!o.did)
604
- fail('要 --did(我怎么答的)');
605
- const t = runsmod.logq(ROOT, {
606
- ...o, did: o.did, secs: +(o.secs || 0), r: o.r || 'pass',
607
- });
608
- console.log(`运行记录已落: runs/${runsmod.today()}.md @${t}`);
609
- if (!o.conv)
610
- console.log(' ⚠️ 没带 --conv —— 事后【拉不出对话流】,这一条基本没有训练价值。');
611
- return;
612
- }
613
- if (cmd === 'feedback') {
614
- const { values: o } = parseArgs({
615
- args: argv.slice(1),
616
- options: { kind: { type: 'string' }, text: { type: 'string' },
617
- conv: { type: 'string' }, at: { type: 'string' } },
618
- });
619
- if (!o.kind || ![runsmod.FB_OK, runsmod.FB_MORE, runsmod.FB_FIX].includes(o.kind)) {
620
- fail('--kind 只能是 认可 / 追问 / 纠正');
621
- }
622
- const day = runsmod.today();
623
- const rows = runsmod.read(ROOT, day);
624
- let cand = rows.filter((r) => r.asked);
625
- if (o.conv)
626
- cand = cand.filter((r) => r.conv === o.conv);
627
- if (!cand.length)
628
- fail(`今天没有可回填的问答行 —— **是不是答完忘了 logq?**`);
629
- const tgt = o.at ? cand.find((r) => r.t === o.at) : cand[cand.length - 1];
630
- if (!tgt)
631
- fail(`找不到 t=${o.at} 的行`);
632
- tgt.fb = o.kind;
633
- if (o.text)
634
- tgt.fbt = o.text.slice(0, 600);
635
- runsmod.write(ROOT, day, rows);
636
- console.log(`已回填: ${day} @${tgt.t} → 「${o.kind}」(原问: ${(tgt.asked || '').slice(0, 40)})`);
637
- return;
638
- }
639
- if (cmd === 'runs') {
640
- const { values: o } = parseArgs({
641
- args: argv.slice(1),
642
- options: { days: { type: 'string' }, conv: { type: 'string' },
643
- issue: { type: 'string' }, top: { type: 'string' } },
644
- });
645
- let rows = runsmod.scan(ROOT, +(o.days || 1));
646
- if (o.conv) {
647
- rows = rows.filter((r) => r.conv === o.conv);
648
- console.log(`【对话流】会话 ${o.conv} · ${rows.length} 条 —— **这就是训练素材**`);
649
- for (const r of rows) {
650
- console.log(` ── ${r._day} ${r.t} issue=${r.issue || '-'} msg=${r.msg || '-'}`);
651
- if (r.asked)
652
- console.log(` 主人: ${r.asked}`);
653
- console.log(` 我 : ${r.did} [${r.r}]`);
654
- if (r.fb)
655
- console.log(` 反馈: ${r.fb}${r.fbt ? ` 「${r.fbt}」` : ''}`);
656
- }
657
- if (!rows.length)
658
- console.log(' (空 —— 这个会话没留痕。**没留痕 = 这些交互等于没发生过。**)');
659
- return;
660
- }
661
- if (o.issue) {
662
- const issue = o.issue;
663
- rows = rows.filter((r) => (r.issue || '').startsWith(issue));
664
- }
665
- console.log(`运行记录 runs/ · ${rows.length} 条`);
666
- for (const r of rows.slice(-(+(o.top || 30)))) {
667
- console.log(` ${r._day} ${r.t} [${(r.r || '').padEnd(11)}] ${(r.ch || '').padEnd(6)} ${(r.did || '').slice(0, 30)} ${r.fb ? '← ' + r.fb : ''}`);
668
- }
669
- return;
670
- }
671
- if (cmd === 'evolve') {
672
- const { values: o } = parseArgs({ args: argv.slice(1), options: { days: { type: 'string' } } });
673
- const rows = runsmod.scan(ROOT, +(o.days || 7));
674
- const ans = rows.filter((r) => r.asked);
675
- const bad = ans.filter((r) => [runsmod.FB_FIX, runsmod.FB_MORE].includes(r.fb || ''));
676
- const unk = ans.filter((r) => !r.fb);
677
- const failed = rows.filter((r) => ['fail', 'unsupported', 'degraded'].includes(r.r));
678
- console.log(`【进化清单】近 ${o.days || 7} 天`);
679
- console.log(` 面向主人的回答 ${ans.length} 条 · 被【打回】${bad.length} 条 · 引擎层没答出来 ${failed.length} 条`);
680
- if (unk.length)
681
- console.log(` ⚠️ ${unk.length} 条【没收到反馈就结案了】—— 答完没回填,这次交互等于白跑。`);
682
- if (bad.length) {
683
- console.log('\n── 主人打回的(**直接就是这周该改什么**)──');
684
- for (const r of bad) {
685
- console.log(` ${r._day} ${r.t} [${r.fb}] 会话=${r.conv || '-'}`);
686
- console.log(` 主人问: ${(r.asked || '').slice(0, 60)}`);
687
- console.log(` 我答 : ${(r.did || '').slice(0, 60)}`);
688
- console.log(` 他说 : ${r.fbt || '(没记下来)'}`);
689
- console.log(` 复盘 : dingtalk-agent runs --conv ${r.conv || '<会话id>'}`);
690
- }
691
- }
692
- if (!bad.length && !failed.length) {
693
- console.log('\n (没有打回,也没有失败 —— 要么真的都对,要么【没人回填反馈】。看上面那行。)');
694
- }
695
- return;
696
- }
697
- // ── todo:把待办拉全(心跳收件用)──
698
- if (cmd === 'todo') {
699
- const dws = await import('../src/dws.js');
700
- const all = dws.todosAll('false');
701
- console.log(`未完成待办 ${all.length} 条(**已翻页拉全** —— 只看第一页会漏掉循环件)`);
702
- for (const t of all)
703
- console.log(` ${t.taskId} ${(t.subject || '').slice(0, 60)}`);
704
- return;
705
- }
706
413
  fail(`不认识的命令: ${cmd}`, 1, `运行 dta --help 查看全部命令${suggest(cmd, [
707
- 'setup', 'doctor', 'skill', 'bootstrap', 'init', 'prepare', 'act', 'smoke', 'eval',
414
+ 'setup', 'upgrade', 'doctor', 'skill', 'bootstrap', 'init', 'prepare', 'run', 'dispatch', 'act',
708
415
  ])}`);
709
416
  }
710
417
  function errorHint(message) {
@@ -720,6 +427,9 @@ function errorHint(message) {
720
427
  if (/skills CLI|\bnpx\b/.test(message)) {
721
428
  return '确认 node、npm、npx 在 PATH 中;也可以复制错误中的 npx skills 命令单独执行。';
722
429
  }
430
+ if (/升级目标|CLI 升级|npm view|npm install/.test(message)) {
431
+ return '检查 npm registry 与网络后重试 dta upgrade;可先运行 dta upgrade --dry-run 查看目标和完整命令。';
432
+ }
723
433
  if (/Workspace|Field|Storage|contextId/.test(message)) {
724
434
  return '先运行 dta bootstrap --json 查看当前上下文;确实需要持久 Workspace 时再运行 dta init。';
725
435
  }
@@ -807,4 +517,21 @@ function printSetup(out) {
807
517
  printDoctor(out.doctor);
808
518
  console.log(`\n开始使用: ${out.nextCommand}`);
809
519
  }
520
+ function printUpgrade(out) {
521
+ const mark = out.dryRun ? 'DRY-RUN' : out.ready ? '✅' : '⚠️';
522
+ const relation = out.changed ? `${out.currentVersion} → ${out.targetVersion}` : `${out.targetVersion}(已是当前版本)`;
523
+ console.log(`${mark} dta upgrade: ${relation}`);
524
+ console.log(` target=${out.target}`);
525
+ console.log(` CLI=${out.executable}`);
526
+ if (out.dryRun) {
527
+ console.log(` 将执行: ${out.commands.install}`);
528
+ console.log(` 将复核: ${out.commands.verify}`);
529
+ }
530
+ else if (out.ready) {
531
+ console.log(' setup / DWS / Skill / Claude Code / Codex / OpenCode 全部 ready');
532
+ }
533
+ else {
534
+ console.log(` CLI 已更新;环境复核未完全 ready,请运行: ${out.commands.verify}`);
535
+ }
536
+ }
810
537
  //# sourceMappingURL=dingtalk-agent.js.map