@xdxer/dingtalk-agent 0.1.5-beta.6 → 0.1.5-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 (119) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.en.md +6 -6
  3. package/README.md +6 -6
  4. package/dist/bin/dingtalk-agent.js +81 -28
  5. package/dist/bin/dingtalk-agent.js.map +1 -1
  6. package/dist/src/agent-audit.js +29 -25
  7. package/dist/src/agent-audit.js.map +1 -1
  8. package/dist/src/agent-definition.js +7 -3
  9. package/dist/src/agent-definition.js.map +1 -1
  10. package/dist/src/agent-enhance.js +2 -2
  11. package/dist/src/agent-enhance.js.map +1 -1
  12. package/dist/src/agent-platform.js +2 -2
  13. package/dist/src/agent-platform.js.map +1 -1
  14. package/dist/src/development-workspace.js +14 -9
  15. package/dist/src/development-workspace.js.map +1 -1
  16. package/dist/src/doctor.js +58 -7
  17. package/dist/src/doctor.js.map +1 -1
  18. package/dist/src/opencode-evals.js +6 -6
  19. package/dist/src/opencode-evals.js.map +1 -1
  20. package/dist/src/opencode-provider.js +2 -2
  21. package/dist/src/opencode-provider.js.map +1 -1
  22. package/dist/src/opencode-workspace.js +3 -3
  23. package/dist/src/opencode-workspace.js.map +1 -1
  24. package/dist/src/personal-event-evals.js +4 -2
  25. package/dist/src/personal-event-evals.js.map +1 -1
  26. package/dist/src/remote-semantic-state-live-evals.js +5 -4
  27. package/dist/src/remote-semantic-state-live-evals.js.map +1 -1
  28. package/dist/src/remote-state-evals.js +2 -2
  29. package/dist/src/remote-state-evals.js.map +1 -1
  30. package/dist/src/robot-evals.js +3 -3
  31. package/dist/src/robot-evals.js.map +1 -1
  32. package/dist/src/schedule-plan.js +1 -1
  33. package/dist/src/schedule-plan.js.map +1 -1
  34. package/dist/src/sessions.js +1 -1
  35. package/dist/src/sessions.js.map +1 -1
  36. package/dist/src/skill-manager.js +141 -13
  37. package/dist/src/skill-manager.js.map +1 -1
  38. package/dist/src/workspace.js +2 -2
  39. package/dist/src/workspace.js.map +1 -1
  40. package/docs/ARCHITECTURE.md +9 -9
  41. package/docs/INSTALLATION.md +6 -6
  42. package/docs/SELF-TEST.md +3 -3
  43. package/docs/schemas/project.schema.json +2 -2
  44. package/examples/agents/README.md +1 -1
  45. package/examples/agents/fde-coach/agent/AGENTS.md +1 -1
  46. package/examples/agents/release-manager/agent/AGENTS.md +1 -1
  47. package/lab/agent-eval/catalog.json +5 -5
  48. package/lab/agent-eval/classic-failures.json +4 -4
  49. package/lab/agent-eval/completion-gate-regression.json +9 -9
  50. package/lab/agent-eval/personal-event-live.example.json +3 -3
  51. package/lab/agent-eval/remote-semantic-state-live.example.json +1 -1
  52. package/lab/agent-eval/workspace/opencode.json +2 -2
  53. package/lab/project-workspace/multica-readonly.fixture.json +2 -2
  54. package/lab/project-workspace/opencode-provider-suite.json +2 -2
  55. package/lab/project-workspace/project.fixture.json +1 -1
  56. package/lab/robot-eval/suite.json +1 -1
  57. package/lab/robot-eval/workspace/AGENTS.md +1 -1
  58. package/lab/robot-eval/workspace/opencode.json +2 -2
  59. package/lab/schemas/personal-event-eval.schema.json +1 -1
  60. package/package.json +7 -7
  61. package/skills/README.md +10 -7
  62. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/SKILL.md +8 -8
  63. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/AGENTS.template.md +1 -1
  64. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/hosts/opencode/opencode.template.json +2 -2
  65. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/evals/evals.json +3 -3
  66. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/host-loading-contract.md +1 -1
  67. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/claude-code.md +1 -1
  68. package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/hosts/opencode.md +2 -2
  69. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/SKILL.md +2 -2
  70. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/assets/eval-catalog.template.json +1 -1
  71. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/evals/evals.json +1 -1
  72. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/eval-topology.md +3 -3
  73. package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/interactive-debug-channels.md +1 -1
  74. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/SKILL.md +2 -2
  75. package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/event-to-behavior.md +1 -1
  76. package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/COMPLETENESS.md +1 -1
  77. package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/SKILL.md +2 -2
  78. package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/config-binding.md +1 -1
  79. package/skills/platforms/deap/PLATFORM.md +1 -1
  80. package/skills/platforms/multica-dingtalk/PLATFORM.md +4 -4
  81. package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/SKILL.md +3 -3
  82. package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/SKILL.md +5 -5
  83. package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/bootstrap.sh +2 -2
  84. package/dist/src/map.js +0 -157
  85. package/dist/src/map.js.map +0 -1
  86. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/REPOSITORY.template.md +0 -0
  87. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.dingtalk-doc.template.json +0 -0
  88. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/agent.bindings.local.template.json +0 -0
  89. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/assets/role-skill.template.md +0 -0
  90. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/agent-definition-contract.md +0 -0
  91. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/drive-and-schedules.md +0 -0
  92. /package/skills/core/{dingtalk-agent-compose → dta-agent-compose}/references/storage-routing.md +0 -0
  93. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/evidence-contract.md +0 -0
  94. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/failure-to-case.md +0 -0
  95. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/local-connector-smoke.md +0 -0
  96. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/scenario-taxonomy.md +0 -0
  97. /package/skills/core/{dingtalk-agent-eval → dta-agent-eval}/references/storage-modes.md +0 -0
  98. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/memory-candidate-proposal.json +0 -0
  99. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/assets/task-checkpoint.json +0 -0
  100. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/action-contract.md +0 -0
  101. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/memory-and-evolution.md +0 -0
  102. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/perception-and-gates.md +0 -0
  103. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/risk-authority-and-privacy.md +0 -0
  104. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/runtime-modes.md +0 -0
  105. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/task-lifecycle.md +0 -0
  106. /package/skills/core/{dingtalk-basic-behavior → dta-basic-behavior}/references/truth-and-recovery.md +0 -0
  107. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/adapters.md +0 -0
  108. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/assembly-guidance.md +0 -0
  109. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/binding.md +0 -0
  110. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/cold-start.md +0 -0
  111. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/consent-and-visibility.md +0 -0
  112. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/consolidation.md +0 -0
  113. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/event-ingest.md +0 -0
  114. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/guided-setup.md +0 -0
  115. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/model.md +0 -0
  116. /package/skills/core/{dingtalk-people-group-memory → dta-people-group-memory}/references/storage-port.md +0 -0
  117. /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/multica-deployment-contract.md +0 -0
  118. /package/skills/platforms/multica-dingtalk/{dingtalk-agent-deploy-multica → dta-deploy-multica}/references/promotion-observation-contract.md +0 -0
  119. /package/skills/platforms/multica-dingtalk/{multica-external → dta-ops-multica}/scripts/multica_ext.py +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,49 @@
2
2
 
3
3
  All notable changes to `@xdxer/dingtalk-agent` are documented here. The project follows semantic versioning; prerelease entries describe release candidates and do not imply that Live canaries or registry publication have completed.
4
4
 
5
+ ## 0.1.5-beta.8 - 2026-07-23
6
+
7
+ Follow-up to the beta.7 rename, from watching a real machine take the upgrade: the four core skills migrated cleanly, the two platform skills sat untouched and unannounced. The three defects below are the same shape — "clean up" was not carried through to the end. Ships on the `beta` dist-tag; `latest` stays at 0.1.4.
8
+
9
+ ### Fixed
10
+
11
+ - Renamed platform skills were stranded, not migrated. `skill install` / `upgrade` only install `BUNDLED_SKILL_NAMES` (the four core skills), so the "replacement must exist before deleting the old copy" gate correctly declined to touch `dingtalk-agent-deploy-multica` and `multica-external` — but nothing ever installed their replacements either, leaving those machines permanently on pre-rename copies with no notice. Stale-copy handling is now a real migration: a legacy skill that is present but whose replacement is not installed gets the replacement installed first, then the old copy removed. This only ever acts on skills the machine already had, so it preserves existing capability rather than adding anything.
12
+ - Dangling exposure symlinks survived cleanup. `~/.agents/skills/<name>` is deleted before `~/.claude/skills/<name>`, which leaves the latter pointing at nothing — and `rmSync` stats the *target*, so `force: true` swallowed the resulting `ENOENT` as "already gone" and left the link in place. The skill therefore stayed visible to Claude Code and was re-reported on every pass. Symlinks are now removed with `unlinkSync`.
13
+ - `dingtalk-agent-boot-multica`, removed from the package back in 0.1.5-beta.2, was still installed on machines and still exposed to Hosts through its `~/.claude/skills` symlink. Withdrawn skills now have their own removal list; unlike a rename they have no replacement to gate on, so they are simply deleted.
14
+
15
+ ### Migration
16
+
17
+ `dta upgrade` once more. A machine that took beta.7 has its platform skills carried to the new names on the next `skill install` / `upgrade`, and every removed copy is printed by name — the operation is never silent.
18
+
19
+ ## 0.1.5-beta.7 - 2026-07-23
20
+
21
+ **BREAKING.** All six first-party skills move to a `dta-` prefix. The names were previously drawn from three unrelated grammars (`dingtalk-*`, `dingtalk-agent-*`, and a bare `multica-external` with no first-party signal at all), and they all land in `~/.agents/skills/<name>/` — a flat namespace shared with Claude Code, Codex, and OpenCode that this repository does not own. The prefix puts the package owner in the first segment. Ships on the `beta` dist-tag; `latest` stays at 0.1.4.
22
+
23
+ ### Changed
24
+
25
+ - Renamed, with directories, frontmatter `name`, the platform registry, and `package.json#files` all moved together: `dingtalk-basic-behavior` → `dta-basic-behavior`, `dingtalk-agent-compose` → `dta-agent-compose`, `dingtalk-agent-eval` → `dta-agent-eval`, `dingtalk-people-group-memory` → `dta-people-group-memory`, `dingtalk-agent-deploy-multica` → `dta-deploy-multica`, `multica-external` → `dta-ops-multica`.
26
+ - Two naming grammars are now stated and enforced: core skills are `dta-<domain>`, platform skills are `dta-<role>-<platform>` where `<role>` equals the role in the `src/agent-platform.ts` registry. The old `ops` role carried the name `multica-external`, so the filesystem and the registry disagreed about what that skill was; they no longer can.
27
+ - `skill install` / `skill upgrade` (and therefore `setup`) delete the pre-rename copies from `~/.agents/skills` and `~/.claude/skills` after the new names are in place. A renamed skill is not a second skill — leaving both installed means two nearly identical descriptions are visible to every Host at once, and which one triggers is undefined. Removal is limited to names registered in `LEGACY_SKILL_RENAMES` and to this package's own two install locations; current-name copies and third-party skills are untouched, and repeating the operation is a no-op.
28
+ - An Agent Project manifest that still declares the old Basic name in `agent.skills` is accepted and counts as declaring Basic, but the name is **not** normalized: path resolution keeps following the declared name, because the directory checked into the user's repository still carries it. This is the one place `dta` cannot migrate on the user's behalf.
29
+
30
+ ### Added
31
+
32
+ - `check:docs` gains a fourth finding kind, `legacy-skill-name`: any pre-rename name appearing anywhere in the repository fails the check. The allowlist is explicit and short — historical evidence that must not be rewritten (`CHANGELOG.md`, `evals/baselines/`, the dated `docs/roadmap/` studies) plus the migration machinery that has to spell the old names out loud. A one-time sweep cleans the present; only a standing gate keeps it clean.
33
+ - Contract scenarios #67–#69 cover the pruning of stale copies, manifest tolerance for the old Basic name, and self-consistency of the naming grammar (prefix, directory basename = frontmatter `name` = registry name, platform role/suffix shape, complete rename ledger, and `package.json#files` coverage). All three run in-process and add no measurable time to the core suite.
34
+
35
+ ### Fixed
36
+
37
+ - `dta doctor` output is re-laid out (PR #20). Three concrete defects, not cosmetics: the `⚠️` summary and its `detail` printed the same platform-skill drift twice; `detail` joined four canonical paths and the drift string with ` | ` into a 200+ character line that always wrapped; and three separator styles (`·`, `;`, `|`) coexisted with no column aligned. The cause was that the renderer only ever received pre-joined sentences, so `DoctorCheck` now carries structured `value` / `items` fields (additive — existing `--json` assertions are untouched) and the printer lays out one fact per line with indented details, aligned by `displayWidth`. The three client checks and the `hosts` section are merged into one block instead of stating the same thing twice. Status glyphs stay `✅`/`⚠️`/`❌`: colour may be added, but the glyphs that carry the meaning are part of the stable stdout interface.
38
+ - `dta doctor` pointed at a command that could not fix the problem it reported. On platform-skill drift it suggested `skill upgrade`, which only iterates `BUNDLED_SKILL_NAMES` and never touches a platform skill; on an `ahead` copy it omitted `--allow-downgrade`, which `upgradeGlobalSkill` requires before it will overwrite. Repair commands are now generated per skill from `canonical.state`, and the `outdated` / `modified` / `ahead` states are spelled out in words rather than printed as bare identifiers.
39
+ - `package-lock.json` is realigned to `0.1.5-beta.7`; the manifest had been bumped without it.
40
+ - `check:docs` walked into directories that `.gitignore` had already declared as not-repository-content: `.claude/worktrees/` (full working copies of other branches) and `.dingtalk-agent/` (runtime state). The markdown count had silently grown from 88 to 773, and the new `legacy-skill-name` gate then failed on pre-rename names sitting in someone else's branch — making `release:check` unpassable on any machine that has a worktree. The walker now derives its skip set from `.gitignore`'s directory entries instead of keeping a second hardcoded list.
41
+ - `lab/robot-eval/suite.json` pinned `dta-basic-behavior@0.12.0` while the skill's `metadata.version` had moved to 0.13.0, so the robot-pool scenario's version-sync assertion failed.
42
+ - `npm run release:check` now builds first. The contract runner imports 17 modules from `dist/` at load time, so the gate only ever worked when `dist/` happened to be current — any newly added source file turned the whole release gate into an opaque `ERR_MODULE_NOT_FOUND` before a single check ran.
43
+
44
+ ### Migration
45
+
46
+ Existing installs need `dta upgrade` (or `dta skill upgrade`) once; it installs the new names and removes the old copies in the same run. Beyond this repository, three steps are **not** automated: push the renamed platform skills to the Multica workspace and delete the old-named server-side entries (`bootstrap.sh` pulls by name, so both present means pulling the wrong one), and redeploy any deployed Agent whose instructions reference the old Basic name.
47
+
5
48
  ## 0.1.5-beta.6 - 2026-07-23
6
49
 
7
50
  The CLI's output layer becomes a human/machine dual channel: a person at a terminal gets colour, hierarchy and step-by-step progress, while an Agent capturing stdout through a Bash tool reads text with **not a single ANSI escape** in it (PR #17). Ships on the `beta` dist-tag; `latest` stays at 0.1.4.
package/README.en.md CHANGED
@@ -54,7 +54,7 @@ dta bootstrap --json # Was the body recognized? Check definition.status and
54
54
  dta agent audit --json # Expect partial — the role semantics are still template text, which is correct
55
55
  ```
56
56
 
57
- `release-manager` is a complete sample of a release-manager digital employee: it picks up "can we ship this version?" in a group, checks the gates, summarizes the verdict, and requires human confirmation before moving on. Replace the role duties in `agent/AGENTS.md` with your own, run `agent audit` again, and the only gap left is the load probe — which needs an Agent Host, see the [Compose Skill](skills/core/dingtalk-agent-compose/SKILL.md).
57
+ `release-manager` is a complete sample of a release-manager digital employee: it picks up "can we ship this version?" in a group, checks the gates, summarizes the verdict, and requires human confirmation before moving on. Replace the role duties in `agent/AGENTS.md` with your own, run `agent audit` again, and the only gap left is the load probe — which needs an Agent Host, see the [Compose Skill](skills/core/dta-agent-compose/SKILL.md).
58
58
 
59
59
  ### Full delivery chain
60
60
 
@@ -89,11 +89,11 @@ Turning an Agent into a DingTalk digital employee takes six stages, and dta cove
89
89
 
90
90
  | Lifecycle stage | What dta does | With what |
91
91
  |---|---|---|
92
- | **① Body and employee skills** | An inheritable, verifiable shared behavior contract: when to speak, whether a message is even a task, who must approve an outbound action, how risk is graded, what counts as done, what to remember and forget. You write only the few dozen lines that differ by role | `dingtalk-basic-behavior` · `agent enhance` · `examples/agents/` |
92
+ | **① Body and employee skills** | An inheritable, verifiable shared behavior contract: when to speak, whether a message is even a task, who must approve an outbound action, how risk is graded, what counts as done, what to remember and forget. You write only the few dozen lines that differ by role | `dta-basic-behavior` · `agent enhance` · `examples/agents/` |
93
93
  | **② Identity acquisition and event perception** | Normalize differently shaped raw events into a stable structure; freeze the reply target and execution identity into a snapshot message text cannot alter, making wrong-recipient structurally impossible; bind permissions and outbound ownership per field; one event yields exactly one Run, losing and duplicating nothing across crashes | `prepare` · `run` · Field config |
94
94
  | **③ Managed-platform deployment** | See the plan before anything lands: frozen hashes for the body and the whole Skill tree plus a write budget; independent readback and a load smoke test after writing; re-running the same version writes nothing; failures roll back and shipped agents can be retired (today this lands on Multica) | `deploy` · `promote` · `--retire` |
95
95
  | **④ Driving it to work inside DingTalk** | Outbound has only four atoms; before an action the gate blocks overreach and target drift, after it a platform readback is mandatory; no blind retries when the outcome is uncertain; a "done" report must carry re-verifiable evidence | `act` · Action Gate · `task checkpoint` |
96
- | **⑤ Evaluation design** | Not a scoring tool but a method: how to pick the cheapest sufficient level, which evidence surfaces one verdict must collect, which failures may never be averaged away, how a real incident becomes a replayable case, and what blocks a release | `lab` · `workspace eval` · `dingtalk-agent-eval` |
96
+ | **⑤ Evaluation design** | Not a scoring tool but a method: how to pick the cheapest sufficient level, which evidence surfaces one verdict must collect, which failures may never be averaged away, how a real incident becomes a replayable case, and what blocks a release | `lab` · `workspace eval` · `dta-agent-eval` |
97
97
  | **⑥ Observation and feedback** | Bind a production finding to the exact version that ran, desensitize it, and feed it back into evaluation material, without ever changing the Agent's behavior on its own | `observe` |
98
98
 
99
99
  ## When to use it
@@ -181,9 +181,9 @@ Prepared Runs expose four message atoms: `ack`, `reply`, `ask`, and `silence`. A
181
181
  | Understand the Agent architecture and how the repo is divided | [Architecture](docs/ARCHITECTURE.md) |
182
182
  | Install, upgrade, or troubleshoot | [Installation](docs/INSTALLATION.md) |
183
183
  | Understand evaluation and evidence levels | [Self-test](docs/SELF-TEST.md) |
184
- | Create or audit an Agent | [Compose Skill](skills/core/dingtalk-agent-compose/SKILL.md) |
185
- | Test or debug a delivered Agent | [Eval Skill](skills/core/dingtalk-agent-eval/SKILL.md) |
186
- | Read the shared behavior protocol (a contract written for models, not a tutorial) | [Basic Behavior Skill](skills/core/dingtalk-basic-behavior/SKILL.md) |
184
+ | Create or audit an Agent | [Compose Skill](skills/core/dta-agent-compose/SKILL.md) |
185
+ | Test or debug a delivered Agent | [Eval Skill](skills/core/dta-agent-eval/SKILL.md) |
186
+ | Read the shared behavior protocol (a contract written for models, not a tutorial) | [Basic Behavior Skill](skills/core/dta-basic-behavior/SKILL.md) |
187
187
  | Copy a complete example and edit from there | [Example Agents](examples/agents) |
188
188
  | Which platforms and open-source projects we keep absorbing practices from | [Prior Art](docs/PRIOR-ART.md) |
189
189
 
package/README.md CHANGED
@@ -53,7 +53,7 @@ dta bootstrap --json # 本体被识别了吗:看 definition.status 与 st
53
53
  dta agent audit --json # 预期 partial:岗位语义还是模板,这是正确结果
54
54
  ```
55
55
 
56
- `release-manager` 是一个发布管理员数字员工的完整样例:它在群里接"这个版本能发吗",检查门禁、汇总结论、需要人确认才推进。把 `agent/AGENTS.md` 里的岗位职责换成你自己的,再跑一次 `agent audit`,缺口就只剩加载探针,那需要一个 Agent Host,见 [Compose Skill](skills/core/dingtalk-agent-compose/SKILL.md)。
56
+ `release-manager` 是一个发布管理员数字员工的完整样例:它在群里接"这个版本能发吗",检查门禁、汇总结论、需要人确认才推进。把 `agent/AGENTS.md` 里的岗位职责换成你自己的,再跑一次 `agent audit`,缺口就只剩加载探针,那需要一个 Agent Host,见 [Compose Skill](skills/core/dta-agent-compose/SKILL.md)。
57
57
 
58
58
  ### 完整交付链
59
59
 
@@ -88,11 +88,11 @@ dta observe --promotion-id <promotion-id> --input <observation.json> --dry-run -
88
88
 
89
89
  | 开发生命周期 | dta 做的 | 用什么 |
90
90
  |---|---|---|
91
- | **① 本体与员工技能** | 一套可继承、可验证的共享行为合同:什么时候该开口、消息算不算任务、外部动作要谁批准、风险怎么分级、什么算完成、哪些要记哪些能忘。你只写岗位不一样的那几十行 | `dingtalk-basic-behavior` · `agent enhance` · `examples/agents/` |
91
+ | **① 本体与员工技能** | 一套可继承、可验证的共享行为合同:什么时候该开口、消息算不算任务、外部动作要谁批准、风险怎么分级、什么算完成、哪些要记哪些能忘。你只写岗位不一样的那几十行 | `dta-basic-behavior` · `agent enhance` · `examples/agents/` |
92
92
  | **② 身份获取与事件感知** | 把格式各异的原始事件归一成稳定结构。回复对象和执行身份会冻结成正文改不动的快照,发错人在结构上就做不到;权限和出口按场域绑定;同一个事件只产生一个 Run,崩了也不会丢、不会重复 | `prepare` · `run` · Field 配置 |
93
93
  | **③ 托管平台部署** | 先看计划再落盘:冻结本体和整棵 Skill 树的 hash 和写预算,写完独立回读、发加载烟测,重复跑同一版不再写入。出问题能回滚,上了线也能退役(当前落地于 Multica) | `deploy` · `promote` · `--retire` |
94
94
  | **④ 驱动它在钉钉里干活** | 外发就四个原语。动作做之前挡掉越权和发错目标,做完之后强制回读平台确认;结果不确定时不许乱重发,报完成得留下能再核验的证据 | `act` · Action Gate · `task checkpoint` |
95
- | **⑤ 评测设计** | 一套评测方法:帮你选够用的最低层级,决定一次结论要看哪几类证据,避免个别失败被平均分掩盖,把真实事故变成能复跑的用例,也给出什么时候不能上线 | `lab` · `workspace eval` · `dingtalk-agent-eval` |
95
+ | **⑤ 评测设计** | 一套评测方法:帮你选够用的最低层级,决定一次结论要看哪几类证据,避免个别失败被平均分掩盖,把真实事故变成能复跑的用例,也给出什么时候不能上线 | `lab` · `workspace eval` · `dta-agent-eval` |
96
96
  | **⑥ 观测与反馈** | 把线上发现的问题绑定到具体哪一版,脱敏后回流评测素材,不会自动改动 Agent 的行为 | `observe` |
97
97
 
98
98
  ## 什么时候该用它
@@ -180,9 +180,9 @@ Prepared Run 只开放 `ack`、`reply`、`ask`、`silence` 四个消息原子动
180
180
  | 理解 Agent 架构与仓库分工 | [Architecture](docs/ARCHITECTURE.md) |
181
181
  | 安装、升级与排障 | [Installation](docs/INSTALLATION.md) |
182
182
  | 理解评测与证据分层 | [Self-test](docs/SELF-TEST.md) |
183
- | 创建或审计 Agent | [Compose Skill](skills/core/dingtalk-agent-compose/SKILL.md) |
184
- | 测试或调试已交付的 Agent | [Eval Skill](skills/core/dingtalk-agent-eval/SKILL.md) |
185
- | 查看公共行为协议(写给模型读的合同,不是教程) | [Basic Behavior Skill](skills/core/dingtalk-basic-behavior/SKILL.md) |
183
+ | 创建或审计 Agent | [Compose Skill](skills/core/dta-agent-compose/SKILL.md) |
184
+ | 测试或调试已交付的 Agent | [Eval Skill](skills/core/dta-agent-eval/SKILL.md) |
185
+ | 查看公共行为协议(写给模型读的合同,不是教程) | [Basic Behavior Skill](skills/core/dta-basic-behavior/SKILL.md) |
186
186
  | 复制一个完整示例开始改 | [Example Agents](examples/agents) |
187
187
  | 从哪些平台与开源项目持续吸收最佳实践 | [Prior Art](docs/PRIOR-ART.md) |
188
188
 
@@ -31,7 +31,7 @@ import { runRobotEvaluation } from '../src/robot-evals.js';
31
31
  import { runOpenCodeEvaluation } from '../src/opencode-evals.js';
32
32
  import { runStorageEvaluation } from '../src/storage-evals.js';
33
33
  import { runPersonalEventEvaluation } from '../src/personal-event-evals.js';
34
- import { doctor } from '../src/doctor.js';
34
+ import { CHECK_LABELS, doctor } from '../src/doctor.js';
35
35
  import { doctorDevelopmentWorkspace, inspectAgentProject, showDevelopmentWorkspace, } from '../src/development-workspace.js';
36
36
  import { buildScheduleShow, buildSchedulePlan } from '../src/schedule-plan.js';
37
37
  import { applyOpenCodeWorkspace, evalOpenCodeWorkspace, planOpenCodeWorkspace, runOpenCodeWorkspace, useOpenCodeWorkspace, } from '../src/opencode-provider.js';
@@ -994,9 +994,16 @@ async function main() {
994
994
  }
995
995
  if (o.json)
996
996
  console.log(JSON.stringify(out, null, 2));
997
- else if ('skills' in out)
997
+ else if ('skills' in out) {
998
998
  for (const item of out.skills)
999
999
  printSkillStatus(item, sub, dryRun);
1000
+ // 静默删目录会让人以为什么都没发生;说清楚删了哪几个旧名。
1001
+ for (const item of out.prunedLegacy || []) {
1002
+ console.log(item.replacedBy
1003
+ ? ` 已迁移 ${item.name} → ${item.replacedBy}`
1004
+ : ` 已清理停用的 Skill ${item.name}`);
1005
+ }
1006
+ }
1000
1007
  else
1001
1008
  printSkillStatus(out, sub, dryRun);
1002
1009
  return;
@@ -1862,34 +1869,80 @@ function printSkillStatus(out, action, dryRun) {
1862
1869
  console.log(muted(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。'));
1863
1870
  }
1864
1871
  }
1872
+ /**
1873
+ * doctor 的版面。改造前的问题不是"不够花哨",是三条实打实的:
1874
+ * 1. 同一事实说两遍——⚠️ 摘要和它的 detail 重复平台 Skill 漂移;三个客户端
1875
+ * 的 Skill 可见性在 check 区和「本机 Coding Agent」区各说一次。
1876
+ * 2. 一行塞太多——detail 用 ` | ` 把四条 canonical 路径和平台 Skill 状态拼在
1877
+ * 一起,200+ 字符,终端里必然折行。
1878
+ * 3. 分隔符混用 `·` `;` `|` 三种,没有一列是对齐的。
1879
+ * 所以这里按「一行一件事、明细缩进、列对齐」重排,并把客户端合并成一节。
1880
+ */
1865
1881
  function printDoctor(out) {
1866
- console.log(`${strong('dingtalk-agent doctor')} · ${mark(out.ready ? 'pass' : 'fail', out.ready ? 'READY' : 'NOT READY')}`);
1867
- for (const check of out.checks) {
1868
- const glyph = check.level === 'pass' ? '✅' : check.level === 'warn' ? '⚠️' : '❌';
1869
- console.log(`${mark(levelOf(check.level), glyph)} ${check.summary}`);
1870
- if (check.detail)
1871
- console.log(` ${muted(check.detail)}`);
1872
- if (check.fix)
1873
- console.log(` 修复: ${noun(check.fix)}`);
1874
- }
1875
- if (out.hosts.length) {
1876
- // Host 面回答"本地能在哪跑",不改变上面的 ready 结论。
1877
- console.log(`\n${strong('本机 Coding Agent:')}`);
1878
- const width = Math.max(...out.hosts.map((host) => displayWidth(host.label)));
1879
- for (const host of out.hosts) {
1880
- const label = host.label + ' '.repeat(width - displayWidth(host.label));
1881
- const where = host.cli.found
1882
- ? [host.cli.path, host.cli.version].filter(Boolean).join(' ')
1883
- : `未找到 ${host.cli.command}`;
1884
- console.log(` ${mark(levelOf(host.cli.found), host.cli.found ? '' : '❌')} ${label} ${noun(where)}`);
1885
- console.log(muted(` Skill 可见性: ${host.skillExposure.exists ? '已暴露' : '未暴露'} · ${host.skillExposureRoot}`));
1886
- }
1887
- }
1888
- if (out.nextSteps.length) {
1889
- console.log(`\n${strong('下一步:')}`);
1890
- for (const step of out.nextSteps)
1891
- console.log(` ${noun(step)}`);
1882
+ const { theme } = stdoutUi();
1883
+ // 字形沿用全 CLI 既定的 ✅/⚠️/❌(bin 里各出现 24/11/5 次)。上一版换成
1884
+ // ✔/!/✗ doctor 成了唯一的异类,也违反 AGENTS.md「stdout 是稳定的人/
1885
+ // 机器接口」——颜色可以加,承载语义的字形不能动。三者都是 2 列宽,对齐不受影响。
1886
+ const glyph = (level) => level === 'pass' ? mark('pass', '✅')
1887
+ : level === 'warn' ? mark('warn', '⚠️') : mark('fail', '❌');
1888
+ const clientIds = new Set(['claude-code', 'codex', 'opencode']);
1889
+ const envChecks = out.checks.filter((check) => !clientIds.has(check.id));
1890
+ const clientChecks = out.checks.filter((check) => clientIds.has(check.id));
1891
+ console.log(`${strong('dingtalk-agent doctor')} · ${out.ready ? mark('pass', 'READY') : mark('fail', 'NOT READY')}`);
1892
+ console.log('');
1893
+ // 左列按显示宽度对齐——中文标签用 String.length 补齐必然错位
1894
+ const labelWidth = Math.max(...envChecks.map((check) => displayWidth(CHECK_LABELS[check.id])));
1895
+ for (const check of envChecks) {
1896
+ const label = padRight(CHECK_LABELS[check.id], labelWidth);
1897
+ console.log(` ${glyph(check.level)} ${strong(label)} ${check.value || check.summary}`);
1898
+ const items = check.items || [];
1899
+ const itemWidth = items.length ? Math.max(...items.map((i) => displayWidth(i.label))) : 0;
1900
+ const valueWidth = items.length ? Math.max(...items.map((i) => displayWidth(i.value || ''))) : 0;
1901
+ for (const item of items) {
1902
+ console.log(` ${noun(padRight(item.label, itemWidth))} ${padRight(item.value || '', valueWidth)}${item.note ? ` ${muted(item.note)}` : ''}`);
1903
+ }
1904
+ if (check.level !== 'pass' && check.fix) {
1905
+ // 一条命令一行。挤在同一行里用「与」串起来的命令没法直接复制。
1906
+ const commands = plain(check.fix).replace(/^运行\s*/, '').split(/\s*与\s*/);
1907
+ commands.forEach((command, index) => {
1908
+ console.log(` ${muted(index === 0 ? '修复' : ' ')} ${noun(command)}`);
1909
+ });
1910
+ }
1911
+ }
1912
+ if (clientChecks.length) {
1913
+ console.log('');
1914
+ console.log(` ${strong('Coding Agent')}`);
1915
+ const nameWidth = Math.max(...clientChecks.map((c) => displayWidth(CHECK_LABELS[c.id])));
1916
+ const hostOf = (id) => out.hosts.find((host) => host.name === id);
1917
+ // 版本列去掉冗余括注与前缀:claude 报 "2.1.218 (Claude Code)"、codex 报 "codex-cli 0.144.6"
1918
+ const versions = clientChecks.map((c) => (hostOf(c.id)?.cli.version || '')
1919
+ .replace(/\s*\(.*\)\s*$/, '').replace(/^\S+-cli\s+/, ''));
1920
+ const versionWidth = Math.max(...versions.map(displayWidth));
1921
+ clientChecks.forEach((check, index) => {
1922
+ const host = hostOf(check.id);
1923
+ const name = padRight(CHECK_LABELS[check.id], nameWidth);
1924
+ const version = padRight(versions[index], versionWidth);
1925
+ const where = host?.cli.found ? tilde(host.skillExposureRoot) : `未安装 ${host?.cli.command || ''}`;
1926
+ console.log(` ${glyph(check.level)} ${strong(name)} ${muted(version)} ${check.value || check.summary} ${noun(where)}`);
1927
+ });
1892
1928
  }
1929
+ // 「下一步」此前逐字重复上面已经打过的修复命令。只留没展示过的。
1930
+ const shown = new Set(out.checks.filter((c) => c.level !== 'pass' && c.fix).map((c) => c.fix));
1931
+ const remaining = out.nextSteps.filter((step) => !shown.has(step));
1932
+ if (remaining.length) {
1933
+ console.log('');
1934
+ for (const step of remaining)
1935
+ console.log(` ${strong('下一步')} ${noun(plain(step))}`);
1936
+ }
1937
+ }
1938
+ /** 反引号在终端里不是强调,是噪声;着色已经承担了同一职责。 */
1939
+ function plain(text) {
1940
+ return text.replace(/`/g, '');
1941
+ }
1942
+ /** 家目录缩成 ~/,省掉对读者零信息量的前缀。 */
1943
+ function tilde(path) {
1944
+ const home = process.env.HOME || '';
1945
+ return home && path.startsWith(home) ? `~${path.slice(home.length)}` : path;
1893
1946
  }
1894
1947
  function printProjectInfo(out) {
1895
1948
  console.log(`${strong('dingtalk-agent Project')} · ${noun(out.project.name)}`);