@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
@@ -0,0 +1,299 @@
1
+ // Managed Agent Platform 注册表与工作区归属解析。
2
+ //
3
+ // 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:
4
+ // DTA_AGENT_PLATFORM 环境变量 > dingtalk-agent.json#agentPlatform
5
+ // > .dingtalk-agent/agent-platform.json > 按 Provider 声明推断。
6
+ // 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。
7
+ // 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。
8
+ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
9
+ import { homedir } from 'node:os';
10
+ import { dirname, join, parse, resolve } from 'node:path';
11
+ import { findAgentProjectRoot } from './development-workspace.js';
12
+ import { findExecutable } from './doctor.js';
13
+ import { installGlobalSkill } from './skill-manager.js';
14
+ export const MANAGED_AGENT_PLATFORMS = [
15
+ {
16
+ name: 'multica-dingtalk',
17
+ label: 'Multica (DingTalk)',
18
+ status: 'supported',
19
+ description: '钉钉 Multica 托管平台:供给、部署、钉钉机器人绑定、观测与调度。',
20
+ skills: [
21
+ { role: 'deploy', name: 'dingtalk-agent-deploy-multica', purpose: '经 dta 稳定 CLI 受控部署/晋级/观测到 Multica' },
22
+ { role: 'boot', name: 'dingtalk-agent-boot-multica', purpose: '部署产物在 Multica Host 内每次任务的启动协议' },
23
+ { role: 'ops', name: 'multica-external', purpose: '平台运维执行体:供给/绑定机器人/观测/调度(纯 HTTPS)' },
24
+ ],
25
+ commands: ['deploy', 'promote', 'observe'],
26
+ suggestedEndpoint: 'https://fde-workbench.dingtalk.com',
27
+ endpointEnv: 'MULTICA_SERVER_URL',
28
+ },
29
+ {
30
+ name: 'deap',
31
+ label: 'DEAP',
32
+ status: 'coming-soon',
33
+ description: '敬请期待。',
34
+ skills: [],
35
+ commands: [],
36
+ },
37
+ ];
38
+ export const AGENT_PLATFORM_FILE = '.dingtalk-agent/agent-platform.json';
39
+ const PROJECT_FILE = 'dingtalk-agent.json';
40
+ export function agentPlatformDefinition(name) {
41
+ return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null;
42
+ }
43
+ export function resolveAgentPlatform(start = process.cwd(), env = process.env) {
44
+ const fromEnv = String(env.DTA_AGENT_PLATFORM || '').trim();
45
+ if (fromEnv)
46
+ return resolution(fromEnv, 'env', '');
47
+ const projectRoot = findAgentProjectRoot(start);
48
+ if (projectRoot) {
49
+ const manifestPath = join(projectRoot, PROJECT_FILE);
50
+ if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {
51
+ const manifest = readJsonOrNull(manifestPath);
52
+ const declared = typeof manifest?.agentPlatform === 'string' ? manifest.agentPlatform.trim() : '';
53
+ if (declared)
54
+ return resolution(declared, 'project-manifest', manifestPath);
55
+ }
56
+ }
57
+ const platformPath = findUp(start, AGENT_PLATFORM_FILE);
58
+ if (platformPath) {
59
+ const stored = readJsonOrNull(platformPath);
60
+ const declared = typeof stored?.agentPlatform === 'string' ? stored.agentPlatform.trim() : '';
61
+ if (declared)
62
+ return resolution(declared, 'platform-file', platformPath);
63
+ }
64
+ if (projectRoot) {
65
+ const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE));
66
+ const providers = Object.values(manifest?.workspaces || {})
67
+ .map((workspace) => workspace?.provider?.kind);
68
+ if (providers.includes('multica')) {
69
+ return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE));
70
+ }
71
+ }
72
+ return resolution(null, 'none', '');
73
+ }
74
+ export function useAgentPlatform(start, name, options) {
75
+ const definition = agentPlatformDefinition(name);
76
+ if (!definition) {
77
+ throw new Error(`未知 managed agent platform: ${name}\n` +
78
+ `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`);
79
+ }
80
+ if (definition.status !== 'supported') {
81
+ throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`);
82
+ }
83
+ const projectRoot = findAgentProjectRoot(start);
84
+ let written;
85
+ if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {
86
+ const manifestPath = join(projectRoot, PROJECT_FILE);
87
+ if (lstatSync(manifestPath).isSymbolicLink()) {
88
+ throw new Error(`${PROJECT_FILE} 不能是符号链接`);
89
+ }
90
+ const manifest = readJsonOrNull(manifestPath);
91
+ if (!manifest || typeof manifest !== 'object') {
92
+ throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 agentPlatform 归属`);
93
+ }
94
+ manifest.agentPlatform = definition.name;
95
+ writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
96
+ written = manifestPath;
97
+ }
98
+ else {
99
+ const target = join(resolve(start), AGENT_PLATFORM_FILE);
100
+ mkdirSync(dirname(target), { recursive: true });
101
+ writeFileSync(target, JSON.stringify({ $schema: 'dingtalk-agent/agent-platform@1', agentPlatform: definition.name }, null, 2) + '\n');
102
+ written = target;
103
+ }
104
+ const skillInstalls = [];
105
+ if (options.installSkills !== false) {
106
+ for (const skill of definition.skills) {
107
+ skillInstalls.push(installGlobalSkill(options.packageRoot, {
108
+ name: skill.name, home: options.home, env: options.env,
109
+ }));
110
+ }
111
+ }
112
+ return { ...resolveAgentPlatform(start, options.env || process.env), written, skillInstalls };
113
+ }
114
+ /** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */
115
+ export function requireSupportedAgentPlatform(command, start = process.cwd(), env = process.env) {
116
+ const resolved = resolveAgentPlatform(start, env);
117
+ if (!resolved.platform) {
118
+ throw new Error(`当前工作区未声明 managed agent platform,无法执行 \`${command}\`。\n` +
119
+ '先运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。');
120
+ }
121
+ if (!resolved.definition) {
122
+ throw new Error(`工作区声明了未知 platform: ${resolved.platform}(来源 ${resolved.source})。\n` +
123
+ `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`);
124
+ }
125
+ if (resolved.definition.status !== 'supported') {
126
+ throw new Error(`${resolved.definition.label} 敬请期待——\`${command}\` 尚未在该平台开放。`);
127
+ }
128
+ if (!resolved.definition.commands.includes(command)) {
129
+ throw new Error(`${resolved.definition.label} 不承接命令 \`${command}\`。`);
130
+ }
131
+ return resolved;
132
+ }
133
+ /** dta 层的平台命令/角色(deploy、boot、ops…)关联到该平台内确切的 Skill 名。 */
134
+ export function platformSkillForRole(platformName, role) {
135
+ const definition = agentPlatformDefinition(platformName);
136
+ return definition?.skills.find((item) => item.role === role)?.name || null;
137
+ }
138
+ const PLATFORM_DIRS = {
139
+ 'multica-dingtalk': 'skills/platforms/multica-dingtalk',
140
+ deap: 'skills/platforms/deap',
141
+ };
142
+ /** 平台说明文档(PLATFORM.md)在包内的路径;切换到该平台时应加载让维护者/Agent 知道各技能用途。 */
143
+ export function platformDocPath(packageRoot, platformName) {
144
+ const dir = PLATFORM_DIRS[platformName];
145
+ if (!dir)
146
+ return null;
147
+ const path = join(packageRoot, dir, 'PLATFORM.md');
148
+ return existsSync(path) ? path : null;
149
+ }
150
+ export function readPlatformDoc(packageRoot, platformName) {
151
+ const path = platformDocPath(packageRoot, platformName);
152
+ return path ? readFileSync(path, 'utf8') : '';
153
+ }
154
+ export function statusLabel(status) {
155
+ return status === 'supported' ? '已支持' : '敬请期待';
156
+ }
157
+ /**
158
+ * 解析平台 endpoint,与真实执行体(multica_ext.py 读 MULTICA_SERVER_URL/--profile)同源,
159
+ * 不新造命名空间、不静默默认连预发。顺序:
160
+ * MULTICA_SERVER_URL 环境变量 > 项目 config(dingtalk-agent.json#multicaEndpoint /
161
+ * .dingtalk-agent/agent-platform.json.endpoint)> 恰好一个已登录 profile 的 server_url
162
+ * (多个则 ambiguous,不自动挑)> suggestedEndpoint(仅建议,未确认)。
163
+ */
164
+ export function resolveEndpoint(platformName, start = process.cwd(), env = process.env, home = homedir()) {
165
+ const definition = agentPlatformDefinition(platformName);
166
+ const envVar = definition?.endpointEnv || 'MULTICA_SERVER_URL';
167
+ const base = { envVar, candidates: [] };
168
+ const fromEnv = String(env[envVar] || '').trim();
169
+ if (fromEnv)
170
+ return { endpoint: fromEnv, source: 'env', confirmed: true, ...base };
171
+ const fromConfig = projectEndpoint(start);
172
+ if (fromConfig)
173
+ return { endpoint: fromConfig, source: 'project-config', confirmed: true, ...base };
174
+ const serverUrls = [...new Set(multicaTargets(home)
175
+ .map((target) => target.serverUrl.trim()).filter(Boolean))];
176
+ if (serverUrls.length === 1) {
177
+ return { endpoint: serverUrls[0], source: 'profile', confirmed: true, ...base };
178
+ }
179
+ if (serverUrls.length > 1) {
180
+ return { endpoint: '', source: 'ambiguous', confirmed: false, ...base, candidates: serverUrls };
181
+ }
182
+ if (definition?.suggestedEndpoint) {
183
+ return { endpoint: definition.suggestedEndpoint, source: 'suggested', confirmed: false, ...base };
184
+ }
185
+ return { endpoint: '', source: 'none', confirmed: false, ...base };
186
+ }
187
+ function projectEndpoint(start) {
188
+ const projectRoot = findAgentProjectRoot(start);
189
+ if (!projectRoot)
190
+ return '';
191
+ const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE));
192
+ const fromManifest = typeof manifest?.multicaEndpoint === 'string' ? manifest.multicaEndpoint.trim() : '';
193
+ if (fromManifest)
194
+ return fromManifest;
195
+ const platform = readJsonOrNull(join(projectRoot, AGENT_PLATFORM_FILE));
196
+ return typeof platform?.endpoint === 'string' ? platform.endpoint.trim() : '';
197
+ }
198
+ /**
199
+ * 平台工具链就绪检查(只读,不阻断):选择/查看平台归属时提示用户缺什么、怎么补。
200
+ * 强制门禁仍由 requireSupportedAgentPlatform 与各平台命令自身承担。
201
+ */
202
+ export function agentPlatformReadiness(name, env = process.env, home = homedir(), start = process.cwd()) {
203
+ if (name !== 'multica-dingtalk')
204
+ return [];
205
+ const checks = [];
206
+ const cli = findExecutable('multica', env);
207
+ checks.push(cli
208
+ ? { id: 'multica-cli', ok: true, summary: `multica CLI 已安装(${cli})` }
209
+ : {
210
+ id: 'multica-cli', ok: false, summary: '未找到 multica CLI',
211
+ hint: '安装:curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash',
212
+ });
213
+ const ep = resolveEndpoint(name, start, env, home);
214
+ const loginTarget = ep.endpoint || '<endpoint>';
215
+ const suffix = ep.confirmed ? '' : '(未确认,请核对是预发还是生产)';
216
+ checks.push(hasMulticaToken(home)
217
+ ? { id: 'multica-login', ok: true, summary: 'Multica 已登录(本地存在 token)' }
218
+ : {
219
+ id: 'multica-login', ok: false, summary: 'Multica 尚未登录',
220
+ hint: `登录:multica login --server-url ${loginTarget} --token <你的 mul_ PAT>` +
221
+ `(endpoint 来源 ${ep.source}${suffix};用 MULTICA_SERVER_URL 或登录别的 profile 可切换)`,
222
+ });
223
+ if (['HTTPS_PROXY', 'https_proxy', 'ALL_PROXY', 'all_proxy'].some((key) => env[key])) {
224
+ checks.push({
225
+ id: 'proxy-env', ok: false, summary: '检测到代理环境变量,可能阻断 Multica 直连',
226
+ hint: '连接失败时用 env -u HTTPS_PROXY -u https_proxy -u ALL_PROXY -u all_proxy 运行 multica 与平台脚本',
227
+ });
228
+ }
229
+ return checks;
230
+ }
231
+ /**
232
+ * 本机已登录的 Multica 目标清单(default 配置 + 各 profile)。只暴露 endpoint 与
233
+ * workspace 标识,不读取 token 内容。发布前必须把候选交给用户选择,绝不默默用默认配置。
234
+ */
235
+ export function multicaTargets(home = homedir()) {
236
+ const targets = [];
237
+ const push = (profile, path) => {
238
+ const config = readJsonOrNull(path);
239
+ if (typeof config?.token === 'string' && config.token.trim()) {
240
+ targets.push({
241
+ profile,
242
+ serverUrl: String(config.server_url || ''),
243
+ workspaceId: String(config.workspace_id || ''),
244
+ });
245
+ }
246
+ };
247
+ push('default', join(home, '.multica', 'config.json'));
248
+ try {
249
+ for (const entry of readdirSync(join(home, '.multica', 'profiles'))) {
250
+ push(entry, join(home, '.multica', 'profiles', entry, 'config.json'));
251
+ }
252
+ }
253
+ catch { /* profiles 目录不存在 */ }
254
+ return targets;
255
+ }
256
+ function hasMulticaToken(home) {
257
+ const candidates = [join(home, '.multica', 'config.json')];
258
+ try {
259
+ for (const entry of readdirSync(join(home, '.multica', 'profiles'))) {
260
+ candidates.push(join(home, '.multica', 'profiles', entry, 'config.json'));
261
+ }
262
+ }
263
+ catch { /* profiles 目录不存在 */ }
264
+ return candidates.some((path) => {
265
+ const config = readJsonOrNull(path);
266
+ return typeof config?.token === 'string' && config.token.trim().length > 0;
267
+ });
268
+ }
269
+ function resolution(name, source, file) {
270
+ return {
271
+ $schema: 'dingtalk-agent/agent-platform-resolution@1',
272
+ platform: name,
273
+ source,
274
+ file,
275
+ definition: name ? agentPlatformDefinition(name) : null,
276
+ platforms: MANAGED_AGENT_PLATFORMS,
277
+ };
278
+ }
279
+ function readJsonOrNull(path) {
280
+ try {
281
+ return JSON.parse(readFileSync(path, 'utf8'));
282
+ }
283
+ catch {
284
+ return null;
285
+ }
286
+ }
287
+ function findUp(start, relativePath) {
288
+ let dir = resolve(start);
289
+ while (true) {
290
+ const candidate = join(dir, relativePath);
291
+ if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink())
292
+ return candidate;
293
+ const parent = dirname(dir);
294
+ if (parent === dir || dir === parse(dir).root)
295
+ return null;
296
+ dir = parent;
297
+ }
298
+ }
299
+ //# sourceMappingURL=agent-platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-platform.js","sourceRoot":"","sources":["../../src/agent-platform.ts"],"names":[],"mappings":"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","sourcesContent":["// Managed Agent Platform 注册表与工作区归属解析。\n//\n// 一个 Agent 工作区归属于至多一个托管平台;归属解析顺序固定:\n// DTA_AGENT_PLATFORM 环境变量 > dingtalk-agent.json#agentPlatform\n// > .dingtalk-agent/agent-platform.json > 按 Provider 声明推断。\n// 平台相关的方法学不写进 CLI——它们随对应平台的 Skill 包分发,只在用户选择该平台时安装。\n// 平台命令(如 deploy/promote/observe)必须先通过归属门禁;coming-soon 平台一律 fail-closed。\n\nimport { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join, parse, resolve } from 'node:path'\n\nimport { findAgentProjectRoot } from './development-workspace.js'\nimport { findExecutable } from './doctor.js'\nimport { installGlobalSkill, type GlobalSkillStatus } from './skill-manager.js'\n\nexport type AgentPlatformStatus = 'supported' | 'coming-soon'\n\nexport interface AgentPlatformSkillBinding {\n role: string\n name: string\n purpose: string\n}\n\nexport interface AgentPlatformDefinition {\n name: string\n label: string\n status: AgentPlatformStatus\n description: string\n skills: AgentPlatformSkillBinding[]\n commands: string[]\n // 建议 endpoint(不是静默默认直连:真实执行仍 fail-closed,见 resolveEndpoint)。\n // 已指向线上正式域名——正因为是生产环境,resolveEndpoint 仍返回 confirmed: false,用前必须显式确认。\n // 可被 MULTICA_SERVER_URL 环境变量 / 项目 config / 已登录 profile 覆盖。\n suggestedEndpoint?: string\n endpointEnv?: string\n}\n\nexport const MANAGED_AGENT_PLATFORMS: AgentPlatformDefinition[] = [\n {\n name: 'multica-dingtalk',\n label: 'Multica (DingTalk)',\n status: 'supported',\n description: '钉钉 Multica 托管平台:供给、部署、钉钉机器人绑定、观测与调度。',\n skills: [\n { role: 'deploy', name: 'dingtalk-agent-deploy-multica', purpose: '经 dta 稳定 CLI 受控部署/晋级/观测到 Multica' },\n { role: 'boot', name: 'dingtalk-agent-boot-multica', purpose: '部署产物在 Multica Host 内每次任务的启动协议' },\n { role: 'ops', name: 'multica-external', purpose: '平台运维执行体:供给/绑定机器人/观测/调度(纯 HTTPS)' },\n ],\n commands: ['deploy', 'promote', 'observe'],\n suggestedEndpoint: 'https://fde-workbench.dingtalk.com',\n endpointEnv: 'MULTICA_SERVER_URL',\n },\n {\n name: 'deap',\n label: 'DEAP',\n status: 'coming-soon',\n description: '敬请期待。',\n skills: [],\n commands: [],\n },\n]\n\nexport const AGENT_PLATFORM_FILE = '.dingtalk-agent/agent-platform.json'\nconst PROJECT_FILE = 'dingtalk-agent.json'\n\nexport type AgentPlatformSource = 'env' | 'project-manifest' | 'platform-file' | 'inferred' | 'none'\n\nexport interface AgentPlatformResolution {\n $schema: 'dingtalk-agent/agent-platform-resolution@1'\n platform: string | null\n source: AgentPlatformSource\n file: string\n definition: AgentPlatformDefinition | null\n platforms: AgentPlatformDefinition[]\n}\n\nexport interface AgentPlatformUseResult extends AgentPlatformResolution {\n written: string\n skillInstalls: GlobalSkillStatus[]\n}\n\nexport function agentPlatformDefinition(name: string): AgentPlatformDefinition | null {\n return MANAGED_AGENT_PLATFORMS.find((item) => item.name === name) || null\n}\n\nexport function resolveAgentPlatform(\n start = process.cwd(), env: NodeJS.ProcessEnv = process.env,\n): AgentPlatformResolution {\n const fromEnv = String(env.DTA_AGENT_PLATFORM || '').trim()\n if (fromEnv) return resolution(fromEnv, 'env', '')\n\n const projectRoot = findAgentProjectRoot(start)\n if (projectRoot) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (existsSync(manifestPath) && !lstatSync(manifestPath).isSymbolicLink()) {\n const manifest = readJsonOrNull(manifestPath)\n const declared = typeof manifest?.agentPlatform === 'string' ? manifest.agentPlatform.trim() : ''\n if (declared) return resolution(declared, 'project-manifest', manifestPath)\n }\n }\n\n const platformPath = findUp(start, AGENT_PLATFORM_FILE)\n if (platformPath) {\n const stored = readJsonOrNull(platformPath)\n const declared = typeof stored?.agentPlatform === 'string' ? stored.agentPlatform.trim() : ''\n if (declared) return resolution(declared, 'platform-file', platformPath)\n }\n\n if (projectRoot) {\n const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE))\n const providers = Object.values(manifest?.workspaces || {})\n .map((workspace: any) => workspace?.provider?.kind)\n if (providers.includes('multica')) {\n return resolution('multica-dingtalk', 'inferred', join(projectRoot, PROJECT_FILE))\n }\n }\n\n return resolution(null, 'none', '')\n}\n\nexport interface AgentPlatformUseOptions {\n packageRoot: string\n home?: string\n env?: NodeJS.ProcessEnv\n installSkills?: boolean\n}\n\nexport function useAgentPlatform(\n start: string, name: string, options: AgentPlatformUseOptions,\n): AgentPlatformUseResult {\n const definition = agentPlatformDefinition(name)\n if (!definition) {\n throw new Error(\n `未知 managed agent platform: ${name}\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => `${item.name}(${statusLabel(item.status)})`).join('、')}`,\n )\n }\n if (definition.status !== 'supported') {\n throw new Error(`${definition.label} 敬请期待——当前版本尚未开放该平台。`)\n }\n\n const projectRoot = findAgentProjectRoot(start)\n let written: string\n if (projectRoot && existsSync(join(projectRoot, PROJECT_FILE))) {\n const manifestPath = join(projectRoot, PROJECT_FILE)\n if (lstatSync(manifestPath).isSymbolicLink()) {\n throw new Error(`${PROJECT_FILE} 不能是符号链接`)\n }\n const manifest = readJsonOrNull(manifestPath)\n if (!manifest || typeof manifest !== 'object') {\n throw new Error(`${PROJECT_FILE} 不是合法 JSON,无法写入 agentPlatform 归属`)\n }\n manifest.agentPlatform = definition.name\n writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\\n')\n written = manifestPath\n } else {\n const target = join(resolve(start), AGENT_PLATFORM_FILE)\n mkdirSync(dirname(target), { recursive: true })\n writeFileSync(target, JSON.stringify(\n { $schema: 'dingtalk-agent/agent-platform@1', agentPlatform: definition.name }, null, 2,\n ) + '\\n')\n written = target\n }\n\n const skillInstalls: GlobalSkillStatus[] = []\n if (options.installSkills !== false) {\n for (const skill of definition.skills) {\n skillInstalls.push(installGlobalSkill(options.packageRoot, {\n name: skill.name, home: options.home, env: options.env,\n }))\n }\n }\n\n return { ...resolveAgentPlatform(start, options.env || process.env), written, skillInstalls }\n}\n\n/** deploy/promote/observe 等平台命令的归属门禁:未归属、未知或 coming-soon 一律 fail-closed。 */\nexport function requireSupportedAgentPlatform(\n command: string, start = process.cwd(), env: NodeJS.ProcessEnv = process.env,\n): AgentPlatformResolution {\n const resolved = resolveAgentPlatform(start, env)\n if (!resolved.platform) {\n throw new Error(\n `当前工作区未声明 managed agent platform,无法执行 \\`${command}\\`。\\n` +\n '先运行 `dta agent-platform use multica-dingtalk`,或设置 DTA_AGENT_PLATFORM 环境变量。',\n )\n }\n if (!resolved.definition) {\n throw new Error(\n `工作区声明了未知 platform: ${resolved.platform}(来源 ${resolved.source})。\\n` +\n `可用: ${MANAGED_AGENT_PLATFORMS.map((item) => item.name).join('、')}`,\n )\n }\n if (resolved.definition.status !== 'supported') {\n throw new Error(`${resolved.definition.label} 敬请期待——\\`${command}\\` 尚未在该平台开放。`)\n }\n if (!resolved.definition.commands.includes(command)) {\n throw new Error(`${resolved.definition.label} 不承接命令 \\`${command}\\`。`)\n }\n return resolved\n}\n\n/** dta 层的平台命令/角色(deploy、boot、ops…)关联到该平台内确切的 Skill 名。 */\nexport function platformSkillForRole(platformName: string, role: string): string | null {\n const definition = agentPlatformDefinition(platformName)\n return definition?.skills.find((item) => item.role === role)?.name || null\n}\n\nconst PLATFORM_DIRS: Record<string, string> = {\n 'multica-dingtalk': 'skills/platforms/multica-dingtalk',\n deap: 'skills/platforms/deap',\n}\n\n/** 平台说明文档(PLATFORM.md)在包内的路径;切换到该平台时应加载让维护者/Agent 知道各技能用途。 */\nexport function platformDocPath(packageRoot: string, platformName: string): string | null {\n const dir = PLATFORM_DIRS[platformName]\n if (!dir) return null\n const path = join(packageRoot, dir, 'PLATFORM.md')\n return existsSync(path) ? path : null\n}\n\nexport function readPlatformDoc(packageRoot: string, platformName: string): string {\n const path = platformDocPath(packageRoot, platformName)\n return path ? readFileSync(path, 'utf8') : ''\n}\n\nexport function statusLabel(status: AgentPlatformStatus): string {\n return status === 'supported' ? '已支持' : '敬请期待'\n}\n\nexport type EndpointSource = 'env' | 'project-config' | 'profile' | 'suggested' | 'ambiguous' | 'none'\n\nexport interface EndpointResolution {\n endpoint: string\n source: EndpointSource\n // confirmed=true 仅当来自真实来源(env / 项目 config / 恰好一个已登录 profile);\n // suggested(预发建议)与 ambiguous(多目标未选)均为 false —— 发布前仍需用户显式确认,不得据此直连。\n confirmed: boolean\n envVar: string\n candidates: string[]\n}\n\n/**\n * 解析平台 endpoint,与真实执行体(multica_ext.py 读 MULTICA_SERVER_URL/--profile)同源,\n * 不新造命名空间、不静默默认连预发。顺序:\n * MULTICA_SERVER_URL 环境变量 > 项目 config(dingtalk-agent.json#multicaEndpoint /\n * .dingtalk-agent/agent-platform.json.endpoint)> 恰好一个已登录 profile 的 server_url\n * (多个则 ambiguous,不自动挑)> suggestedEndpoint(仅建议,未确认)。\n */\nexport function resolveEndpoint(\n platformName: string, start = process.cwd(),\n env: NodeJS.ProcessEnv = process.env, home = homedir(),\n): EndpointResolution {\n const definition = agentPlatformDefinition(platformName)\n const envVar = definition?.endpointEnv || 'MULTICA_SERVER_URL'\n const base: Omit<EndpointResolution, 'endpoint' | 'source' | 'confirmed'> = { envVar, candidates: [] }\n\n const fromEnv = String(env[envVar] || '').trim()\n if (fromEnv) return { endpoint: fromEnv, source: 'env', confirmed: true, ...base }\n\n const fromConfig = projectEndpoint(start)\n if (fromConfig) return { endpoint: fromConfig, source: 'project-config', confirmed: true, ...base }\n\n const serverUrls = [...new Set(multicaTargets(home)\n .map((target) => target.serverUrl.trim()).filter(Boolean))]\n if (serverUrls.length === 1) {\n return { endpoint: serverUrls[0], source: 'profile', confirmed: true, ...base }\n }\n if (serverUrls.length > 1) {\n return { endpoint: '', source: 'ambiguous', confirmed: false, ...base, candidates: serverUrls }\n }\n\n if (definition?.suggestedEndpoint) {\n return { endpoint: definition.suggestedEndpoint, source: 'suggested', confirmed: false, ...base }\n }\n return { endpoint: '', source: 'none', confirmed: false, ...base }\n}\n\nfunction projectEndpoint(start: string): string {\n const projectRoot = findAgentProjectRoot(start)\n if (!projectRoot) return ''\n const manifest = readJsonOrNull(join(projectRoot, PROJECT_FILE))\n const fromManifest = typeof manifest?.multicaEndpoint === 'string' ? manifest.multicaEndpoint.trim() : ''\n if (fromManifest) return fromManifest\n const platform = readJsonOrNull(join(projectRoot, AGENT_PLATFORM_FILE))\n return typeof platform?.endpoint === 'string' ? platform.endpoint.trim() : ''\n}\n\nexport interface AgentPlatformReadinessCheck {\n id: string\n ok: boolean\n summary: string\n hint?: string\n}\n\n/**\n * 平台工具链就绪检查(只读,不阻断):选择/查看平台归属时提示用户缺什么、怎么补。\n * 强制门禁仍由 requireSupportedAgentPlatform 与各平台命令自身承担。\n */\nexport function agentPlatformReadiness(\n name: string, env: NodeJS.ProcessEnv = process.env, home = homedir(),\n start: string = process.cwd(),\n): AgentPlatformReadinessCheck[] {\n if (name !== 'multica-dingtalk') return []\n const checks: AgentPlatformReadinessCheck[] = []\n const cli = findExecutable('multica', env)\n checks.push(cli\n ? { id: 'multica-cli', ok: true, summary: `multica CLI 已安装(${cli})` }\n : {\n id: 'multica-cli', ok: false, summary: '未找到 multica CLI',\n hint: '安装:curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash',\n })\n const ep = resolveEndpoint(name, start, env, home)\n const loginTarget = ep.endpoint || '<endpoint>'\n const suffix = ep.confirmed ? '' : '(未确认,请核对是预发还是生产)'\n checks.push(hasMulticaToken(home)\n ? { id: 'multica-login', ok: true, summary: 'Multica 已登录(本地存在 token)' }\n : {\n id: 'multica-login', ok: false, summary: 'Multica 尚未登录',\n hint: `登录:multica login --server-url ${loginTarget} --token <你的 mul_ PAT>` +\n `(endpoint 来源 ${ep.source}${suffix};用 MULTICA_SERVER_URL 或登录别的 profile 可切换)`,\n })\n if (['HTTPS_PROXY', 'https_proxy', 'ALL_PROXY', 'all_proxy'].some((key) => env[key])) {\n checks.push({\n id: 'proxy-env', ok: false, summary: '检测到代理环境变量,可能阻断 Multica 直连',\n hint: '连接失败时用 env -u HTTPS_PROXY -u https_proxy -u ALL_PROXY -u all_proxy 运行 multica 与平台脚本',\n })\n }\n return checks\n}\n\nexport interface MulticaTarget {\n profile: string\n serverUrl: string\n workspaceId: string\n}\n\n/**\n * 本机已登录的 Multica 目标清单(default 配置 + 各 profile)。只暴露 endpoint 与\n * workspace 标识,不读取 token 内容。发布前必须把候选交给用户选择,绝不默默用默认配置。\n */\nexport function multicaTargets(home = homedir()): MulticaTarget[] {\n const targets: MulticaTarget[] = []\n const push = (profile: string, path: string) => {\n const config = readJsonOrNull(path)\n if (typeof config?.token === 'string' && config.token.trim()) {\n targets.push({\n profile,\n serverUrl: String(config.server_url || ''),\n workspaceId: String(config.workspace_id || ''),\n })\n }\n }\n push('default', join(home, '.multica', 'config.json'))\n try {\n for (const entry of readdirSync(join(home, '.multica', 'profiles'))) {\n push(entry, join(home, '.multica', 'profiles', entry, 'config.json'))\n }\n } catch { /* profiles 目录不存在 */ }\n return targets\n}\n\nfunction hasMulticaToken(home: string): boolean {\n const candidates = [join(home, '.multica', 'config.json')]\n try {\n for (const entry of readdirSync(join(home, '.multica', 'profiles'))) {\n candidates.push(join(home, '.multica', 'profiles', entry, 'config.json'))\n }\n } catch { /* profiles 目录不存在 */ }\n return candidates.some((path) => {\n const config = readJsonOrNull(path)\n return typeof config?.token === 'string' && config.token.trim().length > 0\n })\n}\n\nfunction resolution(\n name: string | null, source: AgentPlatformSource, file: string,\n): AgentPlatformResolution {\n return {\n $schema: 'dingtalk-agent/agent-platform-resolution@1',\n platform: name,\n source,\n file,\n definition: name ? agentPlatformDefinition(name) : null,\n platforms: MANAGED_AGENT_PLATFORMS,\n }\n}\n\nfunction readJsonOrNull(path: string): any {\n try { return JSON.parse(readFileSync(path, 'utf8')) } catch { return null }\n}\n\nfunction findUp(start: string, relativePath: string): string | null {\n let dir = resolve(start)\n while (true) {\n const candidate = join(dir, relativePath)\n if (existsSync(candidate) && !lstatSync(candidate).isSymbolicLink()) return candidate\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  // 配置 —— CLI 记住的东西(TypeScript source)。
2
2
  //
3
- // **记什么**:身份 · 挂载的知识库 · 值班表 · 评测目标。
3
+ // **记什么**:身份 · DWS 绑定 · 运行时根目录 · Field 挂载。
4
4
  // **不记什么**:凭证(那是 dws 的事,别在这里存 token)。
5
5
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
6
6
  import { join, dirname, resolve, parse } from 'node:path';
@@ -26,9 +26,6 @@ export const DEFAULT = {
26
26
  fields: [
27
27
  { id: 'default', path: 'fields/default/field.json', default: true, priority: 0 },
28
28
  ],
29
- kb: [],
30
- duties: [],
31
- eval: { target: '' },
32
29
  };
33
30
  export const path = (root) => join(root, FILE);
34
31
  /**
@@ -58,9 +55,6 @@ export function normalize(input = {}) {
58
55
  fields: value.fields === undefined
59
56
  ? DEFAULT.fields.map((x) => ({ ...x }))
60
57
  : (Array.isArray(value.fields) ? value.fields : []),
61
- kb: Array.isArray(value.kb) ? value.kb : [],
62
- duties: Array.isArray(value.duties) ? value.duties : [],
63
- eval: { ...DEFAULT.eval, ...(isRecord(value.eval) ? value.eval : {}) },
64
58
  };
65
59
  }
66
60
  export function load(root) {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["// 配置 —— CLI 记住的东西(TypeScript source)。\n//\n// **记什么**:身份 · 挂载的知识库 · 值班表 · 评测目标。\n// **不记什么**:凭证(那是 dws 的事,别在这里存 token)。\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join, dirname, resolve, parse } from 'node:path'\nimport type { AgentConfig } from './types.js'\n\nexport const FILE = '.dingtalk-agent/config.json'\n\nexport const DEFAULT: AgentConfig = {\n schemaVersion: 2,\n agent: {\n name: '<还没起名>',\n userId: '<从 dws contact 取,不要猜>',\n ownerId: '<主人的 userId>',\n },\n dws: {\n // 外发前二者都必须固定;留空只允许 prepare/silence,不允许消息外发。\n profile: '',\n expectedUserId: '',\n },\n runtime: {\n sessionRoot: '.dingtalk-agent/sessions',\n eventIndexRoot: '.dingtalk-agent/event-index',\n waitRoot: '.dingtalk-agent/waits',\n waitTtlMs: 604800000,\n },\n fields: [\n { id: 'default', path: 'fields/default/field.json', default: true, priority: 0 },\n ],\n kb: [],\n duties: [],\n eval: { target: '' },\n}\n\nexport const path = (root: string): string => join(root, FILE)\n\n/**\n * 沙箱 cwd 往往落在 Session/Run 子目录里,不能再假设 cwd 就是工作区根。\n * 显式 DTA_ROOT 优先;否则向上寻找配置。init 场景找不到时由调用方回退到 cwd。\n */\nexport function findRoot(start = process.cwd()): string | null {\n let dir = resolve(start)\n while (true) {\n if (existsSync(path(dir))) return dir\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n\n/** 老工作区按默认值补齐新字段,但绝不覆盖已有配置。 */\nexport function normalize(input: unknown = {}): AgentConfig {\n const value = isRecord(input) ? input : {}\n return {\n ...DEFAULT,\n ...value,\n agent: { ...DEFAULT.agent, ...(isRecord(value.agent) ? value.agent : {}) },\n dws: { ...DEFAULT.dws, ...(isRecord(value.dws) ? value.dws : {}) },\n runtime: { ...DEFAULT.runtime, ...(isRecord(value.runtime) ? value.runtime : {}) },\n fields: value.fields === undefined\n ? DEFAULT.fields.map((x) => ({ ...x }))\n : (Array.isArray(value.fields) ? value.fields as AgentConfig['fields'] : []),\n kb: Array.isArray(value.kb) ? value.kb as AgentConfig['kb'] : [],\n duties: Array.isArray(value.duties) ? value.duties as AgentConfig['duties'] : [],\n eval: { ...DEFAULT.eval, ...(isRecord(value.eval) ? value.eval : {}) },\n }\n}\n\nexport function load(root: string): AgentConfig | null {\n const p = path(root)\n return existsSync(p) ? normalize(JSON.parse(readFileSync(p, 'utf8'))) : null\n}\n\nexport function save(root: string, value: unknown): void {\n const p = path(root)\n mkdirSync(dirname(p), { recursive: true })\n writeFileSync(p, JSON.stringify(normalize(value), null, 2) + '\\n')\n}\n\nexport function must(root: string): AgentConfig {\n const cfg = load(root)\n if (!cfg) {\n throw new Error(\n 'Prepared Run runtime 尚未初始化 —— 先跑一次 `dingtalk-agent init`。\\n' +\n ' 普通 Agent Session 不需要 init;请使用全局 Skill,并按需运行 `dingtalk-agent bootstrap`。')\n }\n return cfg\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["// 配置 —— CLI 记住的东西(TypeScript source)。\n//\n// **记什么**:身份 · DWS 绑定 · 运行时根目录 · Field 挂载。\n// **不记什么**:凭证(那是 dws 的事,别在这里存 token)。\nimport { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs'\nimport { join, dirname, resolve, parse } from 'node:path'\nimport type { AgentConfig } from './types.js'\n\nexport const FILE = '.dingtalk-agent/config.json'\n\nexport const DEFAULT: AgentConfig = {\n schemaVersion: 2,\n agent: {\n name: '<还没起名>',\n userId: '<从 dws contact 取,不要猜>',\n ownerId: '<主人的 userId>',\n },\n dws: {\n // 外发前二者都必须固定;留空只允许 prepare/silence,不允许消息外发。\n profile: '',\n expectedUserId: '',\n },\n runtime: {\n sessionRoot: '.dingtalk-agent/sessions',\n eventIndexRoot: '.dingtalk-agent/event-index',\n waitRoot: '.dingtalk-agent/waits',\n waitTtlMs: 604800000,\n },\n fields: [\n { id: 'default', path: 'fields/default/field.json', default: true, priority: 0 },\n ],\n}\n\nexport const path = (root: string): string => join(root, FILE)\n\n/**\n * 沙箱 cwd 往往落在 Session/Run 子目录里,不能再假设 cwd 就是工作区根。\n * 显式 DTA_ROOT 优先;否则向上寻找配置。init 场景找不到时由调用方回退到 cwd。\n */\nexport function findRoot(start = process.cwd()): string | null {\n let dir = resolve(start)\n while (true) {\n if (existsSync(path(dir))) return dir\n const parent = dirname(dir)\n if (parent === dir || dir === parse(dir).root) return null\n dir = parent\n }\n}\n\n/** 老工作区按默认值补齐新字段,但绝不覆盖已有配置。 */\nexport function normalize(input: unknown = {}): AgentConfig {\n const value = isRecord(input) ? input : {}\n return {\n ...DEFAULT,\n ...value,\n agent: { ...DEFAULT.agent, ...(isRecord(value.agent) ? value.agent : {}) },\n dws: { ...DEFAULT.dws, ...(isRecord(value.dws) ? value.dws : {}) },\n runtime: { ...DEFAULT.runtime, ...(isRecord(value.runtime) ? value.runtime : {}) },\n fields: value.fields === undefined\n ? DEFAULT.fields.map((x) => ({ ...x }))\n : (Array.isArray(value.fields) ? value.fields as AgentConfig['fields'] : []),\n }\n}\n\nexport function load(root: string): AgentConfig | null {\n const p = path(root)\n return existsSync(p) ? normalize(JSON.parse(readFileSync(p, 'utf8'))) : null\n}\n\nexport function save(root: string, value: unknown): void {\n const p = path(root)\n mkdirSync(dirname(p), { recursive: true })\n writeFileSync(p, JSON.stringify(normalize(value), null, 2) + '\\n')\n}\n\nexport function must(root: string): AgentConfig {\n const cfg = load(root)\n if (!cfg) {\n throw new Error(\n 'Prepared Run runtime 尚未初始化 —— 先跑一次 `dingtalk-agent init`。\\n' +\n ' 普通 Agent Session 不需要 init;请使用全局 Skill,并按需运行 `dingtalk-agent bootstrap`。')\n }\n return cfg\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n"]}
@@ -5,12 +5,15 @@ import { findExecutable } from './doctor.js';
5
5
  import { digest, stableStringify } from './events.js';
6
6
  import { resolvePackageRoot } from './package-root.js';
7
7
  import { loadWorkspace, workspacePath } from './workspace.js';
8
+ import { bundledSkillPath } from './skill-manager.js';
8
9
  export const PROJECT_FILE = 'dingtalk-agent.json';
9
10
  export const CURRENT_WORKSPACE_FILE = '.dingtalk-agent/current-workspace';
10
11
  export const WORKSPACE_STATE_ROOT = '.dingtalk-agent/state/workspaces';
11
12
  export const LEGACY_WORKSPACE_NAME = 'legacy-prepared';
12
13
  const PROJECT_KEYS = new Set(['$schema', 'name', 'dtaVersion', 'agent', 'workspaces']);
13
- const AGENT_KEYS = new Set(['definition', 'skills']);
14
+ const PROJECT_OPTIONAL_KEYS = new Set([...PROJECT_KEYS, 'agentPlatform', 'multicaEndpoint']);
15
+ const AGENT_KEYS = new Set(['definition', 'displayName', 'skills']);
16
+ const AGENT_REQUIRED_KEYS = new Set(['definition', 'skills']);
14
17
  const WORKSPACE_KEYS = new Set(['stage', 'provider', 'storage', 'authority']);
15
18
  const OPENCODE_KEYS = new Set(['kind', 'model']);
16
19
  const MULTICA_KEYS = new Set([
@@ -63,6 +66,7 @@ export function inspectAgentProject(start = process.cwd(), cliVersion = '') {
63
66
  manifestHash: loaded.manifestHash,
64
67
  project: {
65
68
  name: loaded.manifest.name,
69
+ displayName: loaded.manifest.agent.displayName || loaded.manifest.name,
66
70
  dtaVersion: loaded.manifest.dtaVersion,
67
71
  compatibleWithCli: !cliVersion || versionSatisfies(cliVersion, loaded.manifest.dtaVersion),
68
72
  definition: loaded.manifest.agent.definition,
@@ -187,15 +191,27 @@ function loadAgentProject(start) {
187
191
  }
188
192
  function validateProjectManifest(value, root) {
189
193
  const input = objectValue(value, 'Project manifest');
190
- assertExactKeys(input, PROJECT_KEYS, 'Project manifest');
194
+ assertAllowedKeys(input, PROJECT_OPTIONAL_KEYS, 'Project manifest');
195
+ const missing = [...PROJECT_KEYS].filter((key) => !(key in input));
196
+ if (missing.length)
197
+ throw new Error(`Project manifest 缺少字段: ${missing.join(', ')}`);
191
198
  if (input.$schema !== 'dingtalk-agent/project@1') {
192
199
  throw new Error('Project manifest 缺少 dingtalk-agent/project@1 schema');
193
200
  }
194
201
  const name = stableName(input.name, 'Project name');
195
202
  const dtaVersion = requiredString(input.dtaVersion, 'dtaVersion');
203
+ const agentPlatform = input.agentPlatform === undefined
204
+ ? undefined : requiredString(input.agentPlatform, 'agentPlatform');
205
+ const multicaEndpoint = input.multicaEndpoint === undefined
206
+ ? undefined : requiredString(input.multicaEndpoint, 'multicaEndpoint');
196
207
  const agentInput = objectValue(input.agent, 'Project agent');
197
- assertExactKeys(agentInput, AGENT_KEYS, 'Project agent');
208
+ assertAllowedKeys(agentInput, AGENT_KEYS, 'Project agent');
209
+ const missingAgent = [...AGENT_REQUIRED_KEYS].filter((key) => !(key in agentInput));
210
+ if (missingAgent.length)
211
+ throw new Error(`Project agent 缺少字段: ${missingAgent.join(', ')}`);
198
212
  const definition = safeRelativePath(root, requiredString(agentInput.definition, 'agent.definition'), 'agent.definition', false);
213
+ const displayName = agentInput.displayName === undefined
214
+ ? undefined : agentDisplayName(agentInput.displayName, 'agent.displayName');
199
215
  if (!Array.isArray(agentInput.skills) || agentInput.skills.length === 0) {
200
216
  throw new Error('agent.skills 必须是非空 string[]');
201
217
  }
@@ -216,7 +232,9 @@ function validateProjectManifest(value, root) {
216
232
  }
217
233
  return {
218
234
  $schema: 'dingtalk-agent/project@1', name, dtaVersion,
219
- agent: { definition, skills }, workspaces,
235
+ ...(agentPlatform === undefined ? {} : { agentPlatform }),
236
+ ...(multicaEndpoint === undefined ? {} : { multicaEndpoint }),
237
+ agent: { definition, ...(displayName === undefined ? {} : { displayName }), skills }, workspaces,
220
238
  };
221
239
  }
222
240
  function validateDeclaredWorkspace(value, root, name) {
@@ -447,7 +465,8 @@ function inspectOpenCodeWorkspace(info, workspace, env, add) {
447
465
  add('provider.opencode-model', 'provider', workspace.provider.model ? 'pass' : 'fail', true, workspace.provider.model ? 'OpenCode model 已显式声明' : 'OpenCode model 缺失', { model: workspace.provider.model || '' });
448
466
  const basicPath = '.agents/skills/dingtalk-basic-behavior/SKILL.md';
449
467
  const basic = inspectLocalFile(info.root, basicPath);
450
- const canonicalBasic = inspectLocalFile(resolvePackageRoot(import.meta.url), 'skills/dingtalk-basic-behavior/SKILL.md');
468
+ const canonicalPackageRoot = resolvePackageRoot(import.meta.url);
469
+ const canonicalBasic = inspectLocalFile(canonicalPackageRoot, relative(canonicalPackageRoot, join(bundledSkillPath(canonicalPackageRoot, 'dingtalk-basic-behavior'), 'SKILL.md')));
451
470
  const basicMatched = basic.valid && canonicalBasic.valid && basic.hash === canonicalBasic.hash;
452
471
  add('skills.basic-exposure', 'skills', basicMatched ? 'pass' : 'fail', true, basicMatched ? 'Basic Skill exposure 与当前 canonical source 一致'
453
472
  : 'Basic Skill exposure 缺失、越界或 hash 漂移', { exposure: basic, canonicalHash: canonicalBasic.hash || '' }, `重新物化 ${basicPath}`);
@@ -648,6 +667,13 @@ function stableName(value, label) {
648
667
  throw new Error(`${label} 非法: ${text}`);
649
668
  return text;
650
669
  }
670
+ function agentDisplayName(value, label) {
671
+ const text = requiredString(value, label);
672
+ if (text.length > 128 || /[\u0000-\u001f\u007f]/.test(text)) {
673
+ throw new Error(`${label} 必须是不超过 128 字符且不含控制字符的显示名`);
674
+ }
675
+ return text;
676
+ }
651
677
  function requiredString(value, label) {
652
678
  if (typeof value !== 'string' || !value.trim())
653
679
  throw new Error(`${label} 必须是非空字符串`);