@xdxer/dingtalk-agent 0.1.5-beta.14 → 0.1.5-beta.15

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.
@@ -6,6 +6,7 @@ import { tmpdir } from 'node:os';
6
6
  import { countInstructionsForPath, instructionTargetsPath, instructionUsesGlob, } from './instruction-path.js';
7
7
  export const REQUIRED_BASIC_SKILL = 'dta-basic-behavior';
8
8
  export const REQUIRED_BASIC_SKILL_INSTRUCTION = '.agents/skills/dta-basic-behavior/SKILL.md';
9
+ export const DEFAULT_OPENCODE_MODEL = 'deepseek/deepseek-v4-flash';
9
10
  /**
10
11
  * OpenCode only discovers project Skills by default; it does not load their body.
11
12
  * This binding makes the Basic Skill an unconditional instruction while retaining
@@ -1 +1 @@
1
- {"version":3,"file":"opencode-workspace.js","sourceRoot":"","sources":["../../src/opencode-workspace.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport {\n existsSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync,\n} from 'node:fs'\nimport { spawnSync } from 'node:child_process'\nimport { join, relative, resolve } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport {\n countInstructionsForPath, instructionTargetsPath, instructionUsesGlob,\n} from './instruction-path.js'\n\nexport const REQUIRED_BASIC_SKILL = 'dta-basic-behavior'\nexport const REQUIRED_BASIC_SKILL_INSTRUCTION =\n '.agents/skills/dta-basic-behavior/SKILL.md'\n\nexport interface OpenCodeSkillBinding {\n $schema: 'dingtalk-agent/opencode-skill-binding@1'\n host: 'opencode'\n required: true\n strategy: 'instructions'\n workspace: string\n configPath: string\n instruction: string\n skill: {\n name: string\n version: string\n path: string\n hash: string\n }\n configHash: string\n}\n\nexport interface OpenCodeSkillPreflight extends OpenCodeSkillBinding {\n verified: true\n openCodeVersion: string\n resolvedInstruction: true\n resolvedInstructions: string[]\n discoveredProjectSkill: true\n}\n\n/**\n * OpenCode only discovers project Skills by default; it does not load their body.\n * This binding makes the Basic Skill an unconditional instruction while retaining\n * the native project Skill for discovery and explicit inspection.\n */\nexport function bindRequiredBasicSkill(workspace: string): OpenCodeSkillBinding {\n const workspaceReal = realpathSync(resolve(workspace))\n const skillPath = join(workspaceReal, REQUIRED_BASIC_SKILL_INSTRUCTION)\n if (!existsSync(skillPath)) {\n throw new Error(`OpenCode 必需 Basic Skill 不存在: ${skillPath}`)\n }\n const skillBody = readFileSync(skillPath, 'utf8')\n const name = frontmatterValue(skillBody, 'name')\n const version = metadataVersion(skillBody)\n if (name !== REQUIRED_BASIC_SKILL || !version) {\n throw new Error(`OpenCode Basic Skill 元数据非法: name=${name || 'missing'} version=${version || 'missing'}`)\n }\n\n const configPath = join(workspaceReal, 'opencode.json')\n const config = existsSync(configPath)\n ? parseObject(readFileSync(configPath, 'utf8'), 'opencode.json')\n : {}\n const instructions = config.instructions === undefined\n ? []\n : stringArray(config.instructions, 'opencode.json#instructions')\n const conflictingGlob = instructions.find((item) =>\n instructionUsesGlob(item) && instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n if (conflictingGlob) {\n throw new Error(\n `OpenCode instruction glob 命中 Basic Skill,无法安全去重: ${conflictingGlob}`)\n }\n config.$schema ||= 'https://opencode.ai/config.json'\n config.instructions = [\n REQUIRED_BASIC_SKILL_INSTRUCTION,\n ...instructions.filter((item) => !instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION)),\n ]\n\n const permission = config.permission === undefined\n ? {}\n : objectValue(config.permission, 'opencode.json#permission')\n const skillPermission = permission.skill === undefined\n ? {}\n : objectValue(permission.skill, 'opencode.json#permission.skill')\n skillPermission[REQUIRED_BASIC_SKILL] = 'allow'\n permission.skill = skillPermission\n config.permission = permission\n atomicJson(configPath, config)\n\n return {\n $schema: 'dingtalk-agent/opencode-skill-binding@1',\n host: 'opencode',\n required: true,\n strategy: 'instructions',\n workspace: workspaceReal,\n configPath,\n instruction: REQUIRED_BASIC_SKILL_INSTRUCTION,\n skill: {\n name,\n version,\n path: realpathSync(skillPath),\n hash: sha256(skillBody),\n },\n configHash: sha256(readFileSync(configPath, 'utf8')),\n }\n}\n\nexport function verifyRequiredBasicSkill(\n binding: OpenCodeSkillBinding,\n command = process.env.DTA_OPENCODE_BIN || 'opencode',\n environment?: NodeJS.ProcessEnv,\n): OpenCodeSkillPreflight {\n const current = bindRequiredBasicSkill(binding.workspace)\n if (current.skill.hash !== binding.skill.hash || current.configHash !== binding.configHash) {\n throw new Error('OpenCode Basic Skill 或配置在 preflight 前发生漂移')\n }\n\n const versionRun = runOpenCode(command, ['--version'], binding.workspace, undefined, environment)\n const configRun = runOpenCode(\n command, ['debug', 'config', '--pure'], binding.workspace, undefined, environment)\n const resolved = parseObject(configRun, 'opencode debug config')\n const resolvedInstructions = stringArray(\n resolved.instructions || [], 'opencode resolved instructions')\n if (countInstructionsForPath(\n binding.workspace, resolvedInstructions, REQUIRED_BASIC_SKILL_INSTRUCTION,\n ) !== 1) {\n throw new Error('OpenCode resolved config 未唯一加载 dta-basic-behavior')\n }\n\n const isolatedHome = mkdtempSync(join(tmpdir(), 'dta-opencode-preflight-'))\n let skillsRun = ''\n try {\n skillsRun = runOpenCode(\n command, ['debug', 'skill', '--pure'], binding.workspace, 4 * 1024 * 1024, {\n ...(environment || process.env),\n HOME: isolatedHome,\n XDG_CONFIG_HOME: join(isolatedHome, 'config'),\n XDG_DATA_HOME: join(isolatedHome, 'data'),\n XDG_CACHE_HOME: join(isolatedHome, 'cache'),\n XDG_STATE_HOME: join(isolatedHome, 'state'),\n })\n } finally {\n rmSync(isolatedHome, { recursive: true, force: true })\n }\n const discoveredLocation = skillsRun.match(\n new RegExp(`\"name\":\\\\s*\"${REQUIRED_BASIC_SKILL}\"[\\\\s\\\\S]{0,4000}?\"location\":\\\\s*\"([^\"]+)\"`),\n )?.[1]\n let discovered = false\n if (discoveredLocation) {\n try {\n const decoded = JSON.parse(`\"${discoveredLocation}\"`)\n discovered = existsSync(decoded) && realpathSync(decoded) === binding.skill.path\n } catch { /* malformed or truncated debug output */ }\n }\n if (!discovered) {\n const marker = skillsRun.indexOf(REQUIRED_BASIC_SKILL)\n const nearby = marker >= 0\n ? skillsRun.slice(Math.max(0, marker - 160), marker + 600).replace(/\\s+/g, ' ')\n : `debug skill bytes=${Buffer.byteLength(skillsRun)}`\n throw new Error(`OpenCode 未从当前项目发现 Basic Skill: ${binding.skill.path}; ${nearby}`)\n }\n\n return {\n ...binding,\n verified: true,\n openCodeVersion: versionRun.trim(),\n resolvedInstruction: true,\n resolvedInstructions,\n discoveredProjectSkill: true,\n }\n}\n\nexport function removeRequiredBasicSkillInstruction(workspace: string): void {\n const workspaceReal = realpathSync(resolve(workspace))\n const configPath = join(workspaceReal, 'opencode.json')\n const config = existsSync(configPath)\n ? parseObject(readFileSync(configPath, 'utf8'), 'opencode.json')\n : {}\n const instructions = config.instructions === undefined\n ? []\n : stringArray(config.instructions, 'opencode.json#instructions')\n const conflictingGlob = instructions.find((item) =>\n instructionUsesGlob(item) && instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n if (conflictingGlob) {\n throw new Error(\n `OpenCode instruction glob 命中 Basic Skill,无法生成可信 without-skill baseline: ${conflictingGlob}`)\n }\n config.instructions = instructions.filter((item) => !instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n const permission = config.permission === undefined\n ? {}\n : objectValue(config.permission, 'opencode.json#permission')\n const skillPermission = permission.skill === undefined\n ? {}\n : objectValue(permission.skill, 'opencode.json#permission.skill')\n skillPermission[REQUIRED_BASIC_SKILL] = 'deny'\n permission.skill = skillPermission\n config.permission = permission\n atomicJson(configPath, config)\n}\n\nfunction runOpenCode(\n command: string,\n args: string[],\n cwd: string,\n maxBuffer = 4 * 1024 * 1024,\n environment?: NodeJS.ProcessEnv,\n): string {\n const child = spawnSync(command, args, {\n cwd,\n encoding: 'utf8',\n timeout: 30_000,\n maxBuffer,\n env: environment || process.env,\n })\n if (child.error || child.status !== 0) {\n throw new Error(`OpenCode preflight 失败 (${args.join(' ')}): ${\n child.error?.message || String(child.stderr || child.stdout || `exit=${child.status}`).trim()}`)\n }\n return String(child.stdout || '')\n}\n\nfunction frontmatterValue(body: string, key: string): string {\n const frontmatter = body.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)?.[1] || ''\n return frontmatter.match(new RegExp(`^${key}:\\\\s*[\"']?([^\"'\\\\n]+)[\"']?\\\\s*$`, 'm'))?.[1]?.trim() || ''\n}\n\nfunction metadataVersion(body: string): string {\n const frontmatter = body.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)?.[1] || ''\n return frontmatter.match(/^metadata:\\s*\\n(?:^[ \\t]+.*\\n)*?^[ \\t]+version:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m)?.[1]?.trim() || ''\n}\n\nfunction parseObject(text: string, label: string): Record<string, any> {\n let value: unknown\n try { value = JSON.parse(text) }\n catch (error) { throw new Error(`${label} 不是合法 JSON: ${(error as Error).message}`) }\n return objectValue(value, label)\n}\n\nfunction objectValue(value: unknown, label: string): Record<string, any> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`${label} 必须是 JSON object`)\n }\n return value as Record<string, any>\n}\n\nfunction stringArray(value: unknown, label: string): string[] {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {\n throw new Error(`${label} 必须是 string[]`)\n }\n return value as string[]\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex')\n}\n\nfunction atomicJson(path: string, value: unknown): void {\n const body = JSON.stringify(value, null, 2) + '\\n'\n const temporary = `${path}.${process.pid}.${Date.now()}.tmp`\n writeFileSync(temporary, body, { flag: 'wx' })\n renameSync(temporary, path)\n}\n\nexport function relativeBinding(binding: OpenCodeSkillBinding): Record<string, unknown> {\n return {\n ...binding,\n configPath: relative(binding.workspace, binding.configPath),\n skill: {\n ...binding.skill,\n path: relative(binding.workspace, binding.skill.path),\n },\n }\n}\n"]}
1
+ {"version":3,"file":"opencode-workspace.js","sourceRoot":"","sources":["../../src/opencode-workspace.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from 'node:crypto'\nimport {\n existsSync, mkdtempSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync,\n} from 'node:fs'\nimport { spawnSync } from 'node:child_process'\nimport { join, relative, resolve } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport {\n countInstructionsForPath, instructionTargetsPath, instructionUsesGlob,\n} from './instruction-path.js'\n\nexport const REQUIRED_BASIC_SKILL = 'dta-basic-behavior'\nexport const REQUIRED_BASIC_SKILL_INSTRUCTION =\n '.agents/skills/dta-basic-behavior/SKILL.md'\nexport const DEFAULT_OPENCODE_MODEL = 'deepseek/deepseek-v4-flash'\n\nexport interface OpenCodeSkillBinding {\n $schema: 'dingtalk-agent/opencode-skill-binding@1'\n host: 'opencode'\n required: true\n strategy: 'instructions'\n workspace: string\n configPath: string\n instruction: string\n skill: {\n name: string\n version: string\n path: string\n hash: string\n }\n configHash: string\n}\n\nexport interface OpenCodeSkillPreflight extends OpenCodeSkillBinding {\n verified: true\n openCodeVersion: string\n resolvedInstruction: true\n resolvedInstructions: string[]\n discoveredProjectSkill: true\n}\n\n/**\n * OpenCode only discovers project Skills by default; it does not load their body.\n * This binding makes the Basic Skill an unconditional instruction while retaining\n * the native project Skill for discovery and explicit inspection.\n */\nexport function bindRequiredBasicSkill(workspace: string): OpenCodeSkillBinding {\n const workspaceReal = realpathSync(resolve(workspace))\n const skillPath = join(workspaceReal, REQUIRED_BASIC_SKILL_INSTRUCTION)\n if (!existsSync(skillPath)) {\n throw new Error(`OpenCode 必需 Basic Skill 不存在: ${skillPath}`)\n }\n const skillBody = readFileSync(skillPath, 'utf8')\n const name = frontmatterValue(skillBody, 'name')\n const version = metadataVersion(skillBody)\n if (name !== REQUIRED_BASIC_SKILL || !version) {\n throw new Error(`OpenCode Basic Skill 元数据非法: name=${name || 'missing'} version=${version || 'missing'}`)\n }\n\n const configPath = join(workspaceReal, 'opencode.json')\n const config = existsSync(configPath)\n ? parseObject(readFileSync(configPath, 'utf8'), 'opencode.json')\n : {}\n const instructions = config.instructions === undefined\n ? []\n : stringArray(config.instructions, 'opencode.json#instructions')\n const conflictingGlob = instructions.find((item) =>\n instructionUsesGlob(item) && instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n if (conflictingGlob) {\n throw new Error(\n `OpenCode instruction glob 命中 Basic Skill,无法安全去重: ${conflictingGlob}`)\n }\n config.$schema ||= 'https://opencode.ai/config.json'\n config.instructions = [\n REQUIRED_BASIC_SKILL_INSTRUCTION,\n ...instructions.filter((item) => !instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION)),\n ]\n\n const permission = config.permission === undefined\n ? {}\n : objectValue(config.permission, 'opencode.json#permission')\n const skillPermission = permission.skill === undefined\n ? {}\n : objectValue(permission.skill, 'opencode.json#permission.skill')\n skillPermission[REQUIRED_BASIC_SKILL] = 'allow'\n permission.skill = skillPermission\n config.permission = permission\n atomicJson(configPath, config)\n\n return {\n $schema: 'dingtalk-agent/opencode-skill-binding@1',\n host: 'opencode',\n required: true,\n strategy: 'instructions',\n workspace: workspaceReal,\n configPath,\n instruction: REQUIRED_BASIC_SKILL_INSTRUCTION,\n skill: {\n name,\n version,\n path: realpathSync(skillPath),\n hash: sha256(skillBody),\n },\n configHash: sha256(readFileSync(configPath, 'utf8')),\n }\n}\n\nexport function verifyRequiredBasicSkill(\n binding: OpenCodeSkillBinding,\n command = process.env.DTA_OPENCODE_BIN || 'opencode',\n environment?: NodeJS.ProcessEnv,\n): OpenCodeSkillPreflight {\n const current = bindRequiredBasicSkill(binding.workspace)\n if (current.skill.hash !== binding.skill.hash || current.configHash !== binding.configHash) {\n throw new Error('OpenCode Basic Skill 或配置在 preflight 前发生漂移')\n }\n\n const versionRun = runOpenCode(command, ['--version'], binding.workspace, undefined, environment)\n const configRun = runOpenCode(\n command, ['debug', 'config', '--pure'], binding.workspace, undefined, environment)\n const resolved = parseObject(configRun, 'opencode debug config')\n const resolvedInstructions = stringArray(\n resolved.instructions || [], 'opencode resolved instructions')\n if (countInstructionsForPath(\n binding.workspace, resolvedInstructions, REQUIRED_BASIC_SKILL_INSTRUCTION,\n ) !== 1) {\n throw new Error('OpenCode resolved config 未唯一加载 dta-basic-behavior')\n }\n\n const isolatedHome = mkdtempSync(join(tmpdir(), 'dta-opencode-preflight-'))\n let skillsRun = ''\n try {\n skillsRun = runOpenCode(\n command, ['debug', 'skill', '--pure'], binding.workspace, 4 * 1024 * 1024, {\n ...(environment || process.env),\n HOME: isolatedHome,\n XDG_CONFIG_HOME: join(isolatedHome, 'config'),\n XDG_DATA_HOME: join(isolatedHome, 'data'),\n XDG_CACHE_HOME: join(isolatedHome, 'cache'),\n XDG_STATE_HOME: join(isolatedHome, 'state'),\n })\n } finally {\n rmSync(isolatedHome, { recursive: true, force: true })\n }\n const discoveredLocation = skillsRun.match(\n new RegExp(`\"name\":\\\\s*\"${REQUIRED_BASIC_SKILL}\"[\\\\s\\\\S]{0,4000}?\"location\":\\\\s*\"([^\"]+)\"`),\n )?.[1]\n let discovered = false\n if (discoveredLocation) {\n try {\n const decoded = JSON.parse(`\"${discoveredLocation}\"`)\n discovered = existsSync(decoded) && realpathSync(decoded) === binding.skill.path\n } catch { /* malformed or truncated debug output */ }\n }\n if (!discovered) {\n const marker = skillsRun.indexOf(REQUIRED_BASIC_SKILL)\n const nearby = marker >= 0\n ? skillsRun.slice(Math.max(0, marker - 160), marker + 600).replace(/\\s+/g, ' ')\n : `debug skill bytes=${Buffer.byteLength(skillsRun)}`\n throw new Error(`OpenCode 未从当前项目发现 Basic Skill: ${binding.skill.path}; ${nearby}`)\n }\n\n return {\n ...binding,\n verified: true,\n openCodeVersion: versionRun.trim(),\n resolvedInstruction: true,\n resolvedInstructions,\n discoveredProjectSkill: true,\n }\n}\n\nexport function removeRequiredBasicSkillInstruction(workspace: string): void {\n const workspaceReal = realpathSync(resolve(workspace))\n const configPath = join(workspaceReal, 'opencode.json')\n const config = existsSync(configPath)\n ? parseObject(readFileSync(configPath, 'utf8'), 'opencode.json')\n : {}\n const instructions = config.instructions === undefined\n ? []\n : stringArray(config.instructions, 'opencode.json#instructions')\n const conflictingGlob = instructions.find((item) =>\n instructionUsesGlob(item) && instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n if (conflictingGlob) {\n throw new Error(\n `OpenCode instruction glob 命中 Basic Skill,无法生成可信 without-skill baseline: ${conflictingGlob}`)\n }\n config.instructions = instructions.filter((item) => !instructionTargetsPath(\n workspaceReal, item, REQUIRED_BASIC_SKILL_INSTRUCTION))\n const permission = config.permission === undefined\n ? {}\n : objectValue(config.permission, 'opencode.json#permission')\n const skillPermission = permission.skill === undefined\n ? {}\n : objectValue(permission.skill, 'opencode.json#permission.skill')\n skillPermission[REQUIRED_BASIC_SKILL] = 'deny'\n permission.skill = skillPermission\n config.permission = permission\n atomicJson(configPath, config)\n}\n\nfunction runOpenCode(\n command: string,\n args: string[],\n cwd: string,\n maxBuffer = 4 * 1024 * 1024,\n environment?: NodeJS.ProcessEnv,\n): string {\n const child = spawnSync(command, args, {\n cwd,\n encoding: 'utf8',\n timeout: 30_000,\n maxBuffer,\n env: environment || process.env,\n })\n if (child.error || child.status !== 0) {\n throw new Error(`OpenCode preflight 失败 (${args.join(' ')}): ${\n child.error?.message || String(child.stderr || child.stdout || `exit=${child.status}`).trim()}`)\n }\n return String(child.stdout || '')\n}\n\nfunction frontmatterValue(body: string, key: string): string {\n const frontmatter = body.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)?.[1] || ''\n return frontmatter.match(new RegExp(`^${key}:\\\\s*[\"']?([^\"'\\\\n]+)[\"']?\\\\s*$`, 'm'))?.[1]?.trim() || ''\n}\n\nfunction metadataVersion(body: string): string {\n const frontmatter = body.match(/^---\\s*\\n([\\s\\S]*?)\\n---/)?.[1] || ''\n return frontmatter.match(/^metadata:\\s*\\n(?:^[ \\t]+.*\\n)*?^[ \\t]+version:\\s*[\"']?([^\"'\\n]+)[\"']?\\s*$/m)?.[1]?.trim() || ''\n}\n\nfunction parseObject(text: string, label: string): Record<string, any> {\n let value: unknown\n try { value = JSON.parse(text) }\n catch (error) { throw new Error(`${label} 不是合法 JSON: ${(error as Error).message}`) }\n return objectValue(value, label)\n}\n\nfunction objectValue(value: unknown, label: string): Record<string, any> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error(`${label} 必须是 JSON object`)\n }\n return value as Record<string, any>\n}\n\nfunction stringArray(value: unknown, label: string): string[] {\n if (!Array.isArray(value) || value.some((item) => typeof item !== 'string')) {\n throw new Error(`${label} 必须是 string[]`)\n }\n return value as string[]\n}\n\nfunction sha256(value: string): string {\n return createHash('sha256').update(value).digest('hex')\n}\n\nfunction atomicJson(path: string, value: unknown): void {\n const body = JSON.stringify(value, null, 2) + '\\n'\n const temporary = `${path}.${process.pid}.${Date.now()}.tmp`\n writeFileSync(temporary, body, { flag: 'wx' })\n renameSync(temporary, path)\n}\n\nexport function relativeBinding(binding: OpenCodeSkillBinding): Record<string, unknown> {\n return {\n ...binding,\n configPath: relative(binding.workspace, binding.configPath),\n skill: {\n ...binding.skill,\n path: relative(binding.workspace, binding.skill.path),\n },\n }\n}\n"]}
@@ -199,11 +199,13 @@ dta prepare --event-file event.json --json
199
199
  ```bash
200
200
  # 在 Agent 根目录
201
201
  dta agent enhance --project-name <agent-name> \
202
- --role-skill <role-skill-name> --dry-run --json
202
+ --role-skill <role-skill-name> \
203
+ --host <opencode|none> --dry-run --json
203
204
 
204
205
  # 审阅 plan 后执行其 apply.command(当前 plan-id + 显式 yes)
205
206
  dta agent enhance --project-name <agent-name> \
206
207
  --role-skill <role-skill-name> \
208
+ --host <opencode|none> \
207
209
  --plan-id <current-plan-id> --yes --json
208
210
 
209
211
  # 把 AGENTS.md 与 Role Skill 的模板占位符替换为真实岗位语义后
@@ -216,7 +218,7 @@ dta agent audit --bindings agent.bindings.json \
216
218
  --require-skill <role-skill-name> --verify-load --yes --json
217
219
  ```
218
220
 
219
- `agent enhance` 默认只生成计划,不写文件、不访问 DWS、也不创建 Triggerapply 更新旧文件前把原值备份到 gitignored state 目录,并在 source/config 漂移时拒绝旧 plan-id。第一次 `agent audit` 默认不访问 DWS、不调用模型。它分别检查 Definition、本地文件/产物目录、Role Skill 真实语义、OpenCode Basic instruction/exposure 和已有证据,缺口用稳定 check ID 与修复动作返回;`partial` 的退出码是 2。`--verify-load --yes` 只增加隔离 OpenCode 评测,并生成与当前 Definition、bindings、配置和 Skill hash 绑定的 load evidence。
221
+ `agent enhance` 默认只生成计划,不写文件、不访问 DWS、也不创建 Trigger;新项目必须显式用 `--host opencode` 选择当前完整 adapter,或用 `--host none` 只落成 harness 无关交付包(审计上限为 `partial`)。apply 更新旧文件前把原值备份到 gitignored state 目录,并在 source/config 漂移时拒绝旧 plan-id。第一次 `agent audit` 默认不访问 DWS、不调用模型。它分别检查 Definition、本地文件/产物目录、Role Skill 真实语义、OpenCode Basic instruction/exposure 和已有证据,缺口用稳定 check ID 与修复动作返回;`partial` 的退出码是 2。`--verify-load --yes` 只增加隔离 OpenCode 评测,并生成与当前 Definition、bindings、配置和 Skill hash 绑定的 load evidence。
220
222
 
221
223
  远端 memory/knowledge 需要另跑授权的 `dta lab eval --engine storage`,再把其报告传给 `--remote-report`。审计不会用旧缓存替代 DWS 身份、类型、hash 和独立回读,也不会把远端文档升级为 Wait、Receipt、锁或凭据介质。
222
224
 
@@ -7,7 +7,7 @@
7
7
  "required": [
8
8
  "$schema", "planId", "ready", "status", "sideEffect", "dingtalkSideEffect",
9
9
  "triggerSideEffect", "root", "source", "projectName", "roleSkills", "bindings",
10
- "baselineHash", "desiredHash", "operations", "blockers", "warnings",
10
+ "host", "baselineHash", "desiredHash", "operations", "blockers", "warnings",
11
11
  "semanticReview", "apply", "verification"
12
12
  ],
13
13
  "properties": {
@@ -33,6 +33,7 @@
33
33
  "type": "array", "uniqueItems": true,
34
34
  "items": { "type": "string", "minLength": 1 }
35
35
  },
36
+ "host": { "enum": ["opencode", "none", "unselected"] },
36
37
  "bindings": { "type": "string", "minLength": 1 },
37
38
  "baselineHash": { "$ref": "#/$defs/hash" },
38
39
  "desiredHash": { "$ref": "#/$defs/hash" },
@@ -6,7 +6,7 @@
6
6
  "additionalProperties": false,
7
7
  "required": [
8
8
  "$schema", "status", "operationId", "planId", "sideEffect", "dingtalkSideEffect",
9
- "triggerSideEffect", "root", "backupRoot", "idempotent", "changes", "audit"
9
+ "triggerSideEffect", "root", "backupRoot", "host", "idempotent", "changes", "audit"
10
10
  ],
11
11
  "properties": {
12
12
  "$schema": { "const": "dingtalk-agent/agent-enhancement-receipt@1" },
@@ -18,6 +18,7 @@
18
18
  "triggerSideEffect": { "const": false },
19
19
  "root": { "type": "string", "minLength": 1 },
20
20
  "backupRoot": { "type": "string" },
21
+ "host": { "enum": ["opencode", "none"] },
21
22
  "idempotent": { "type": "boolean" },
22
23
  "changes": {
23
24
  "type": "array",
@@ -24,7 +24,7 @@
24
24
  }
25
25
  ],
26
26
  "modelProbe": {
27
- "model": "deepseek/deepseek-chat",
27
+ "model": "deepseek/deepseek-v4-flash",
28
28
  "prompt": "只根据宿主已经挂载的长期记忆和知识回答:先写记忆评测代号,再写知识评测代号。两者之间用一个空格,不要猜测。",
29
29
  "expectedText": ["DTA_REMOTE_MEMORY_SENTINEL", "DTA_REMOTE_KNOWLEDGE_SENTINEL"]
30
30
  }
@@ -14,7 +14,7 @@
14
14
  "stage": "dev",
15
15
  "provider": {
16
16
  "kind": "opencode",
17
- "model": "deepseek/deepseek-chat"
17
+ "model": "deepseek/deepseek-v4-flash"
18
18
  },
19
19
  "storage": {
20
20
  "memory": "local-md:MEMORY.md",
@@ -23,7 +23,7 @@
23
23
  "botOpenDingTalkId": "replace-with-bot-open-dingtalk-id",
24
24
  "workspaceTemplate": "lab/robot-eval/workspace",
25
25
  "channel": "opencode",
26
- "model": "deepseek/deepseek-chat",
26
+ "model": "deepseek/deepseek-v4-flash",
27
27
  "agentMemory": false
28
28
  }
29
29
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdxer/dingtalk-agent",
3
- "version": "0.1.5-beta.14",
3
+ "version": "0.1.5-beta.15",
4
4
  "description": "在你熟悉的终端里,用手边的 Coding Agent 把现成的 Agent 装配成钉钉数字员工:建起来、部署交付、评测、观察四段全程有引导,硬门禁只挡不可逆的副作用。",
5
5
  "keywords": [
6
6
  "dingtalk",
@@ -3,7 +3,7 @@ name: dta-agent-compose
3
3
  description: 当用户要创建、新建、装配一个 Agent 或钉钉数字员工——包括把 GitHub 仓库、本地文件夹或钉钉文档定义成 Agent,或要审计、补齐、优化 Agent 的 AGENTS.md、本体职责、岗位 Skills、记忆/知识/产物存储、DWS 权限绑定与「谁叫醒它」的驱动节律时使用。即使尚未 init Workspace,也按 dingtalk-agent 的 AgentDefinition 范式给出可运行的最小装配方案;声明驱动节律但不实现触发器本身。
4
4
  compatibility: Requires dingtalk-agent on PATH; remote DingTalk documents require authenticated dws.
5
5
  metadata:
6
- version: "0.16.5"
6
+ version: "0.17.0"
7
7
  ---
8
8
 
9
9
  # 装配一个可工作的钉钉数字员工 Agent
@@ -15,7 +15,7 @@ metadata:
15
15
  1. 识别来源和运行方式:GitHub 先由宿主 clone/checkout,本 Skill 不接管凭证;本地目录直接读取;钉钉文档只承担 memory/knowledge 等远端语义状态。新项目的本体与 Role Skills 统一放在可版本化的 `agent/` 交付包;已有仓库按 manifest 显式路径读取。
16
16
  2. **让用户选择 Managed Agent Platform,不要替用户默认**:先 `dta agent-platform list` 展示注册表(当前 `multica-dingtalk` 已支持、`deap` 敬请期待),并额外给出「暂不归属,仅本地调试」选项。用户选定托管平台后运行 `dta agent-platform use <platform>`——它写入归属声明并按需安装平台技能包(`multica-dingtalk` 对应 `dta-deploy-multica` 与 `dta-ops-multica`)。命令会同时输出 readiness 检查:multica CLI 未安装时按提示安装(`curl -fsSL https://raw.githubusercontent.com/multica-ai/multica/main/scripts/install.sh | bash`),未登录时 readiness 会给出带解析 endpoint 的完整登录命令(endpoint 来源见 `dta agent-platform show` 的 Endpoint 行:env `MULTICA_SERVER_URL` > 项目 config > profile > 建议值;建议值为线上正式域名,仍标「未确认」,须先与用户确认再用),检测到代理环境变量时提醒连接失败可用 `env -u` 剥离。readiness 未过先引导用户补齐,再继续装配;选「暂不归属」则跳过,后续仍可随时归属。切换到某平台后,`agent-platform use/show` 会给出该平台的 `平台说明: <PLATFORM.md 路径>`——先读它,了解该平台 deploy/ops 技能的用途、完整交付链与绑定/验收/解绑方式,再开始平台侧操作。
17
17
  3. **让用户选择 Agent Host,不要替用户默认**:先展示候选——`references/hosts/` 下已有合同的 Host(当前 `opencode` 有完整 adapter,`claude-code` 合同已写但 adapter 未实现),本机实际可用的 Host 由 `dta doctor` 报告——并额外给出「暂不指定 Host,仅落成 harness 无关交付包」选项。绝不默默使用 OpenCode 或当前正在运行本 Skill 的 Host 作为默认。Host exposure 由 dta 在隔离运行/评测目录临时生成,不提交回仓库;选「暂不指定」时明确结论上限是 `partial`。
18
- 4. 对已有仓库优先运行 `dta agent enhance --project-name <name> --role-skill <role> --dry-run --json`。它只生成 `agent-enhancement-plan@1`,不会写文件、访问 DWS 或创建 Trigger。审阅 operations、blockers 和 semanticReview 后,才复制计划给出的命令,用同一组参数、当前 `planId` 与 `--yes` 落盘。
18
+ 4. 对已有仓库优先运行 `dta agent enhance --project-name <name> --role-skill <role> --host <opencode|none> --dry-run --json`。`opencode` 声明本地 OpenCode workspace 并合并 `opencode.json`;`none` 只落成 harness 无关交付包,不声明 local workspace,审计结论上限为 `partial`。它只生成 `agent-enhancement-plan@1`,不会写文件、访问 DWS 或创建 Trigger。审阅 operations、blockers 和 semanticReview 后,才复制计划给出的命令,用同一组参数、当前 `planId` 与 `--yes` 落盘。
19
19
  5. apply 只允许本地文件副作用:先把被更新的旧文件备份到 `.dingtalk-agent/backups/agent-enhance/<operationId>/`,再写入并按 hash 回读;自定义 private state 目录必须同步进入 `.gitignore`。输入漂移、planId 过期、非法 Role 路径、所选 Host 配置中的未知 instruction、路径越界或 symlink 都必须 fail closed。不要跳过 plan,也不要把 `--yes` 写进无人审阅的默认脚本。
20
20
  6. 审核本体:优先使用 `agent/AGENTS.md` 精简表达四块长期语义——定义、不能做的底线、做事标准范式、常犯错误。模板必须保留一条可执行的 Basic 启动继承声明:在分析、回复或调用岗位能力前,先通过 Host 原生 Skill 工具加载 Basic,未成功加载则不继续;以及不猜身份/目标/权限、不扩大副作用、不虚报完成、隐私不越界四条最小公共底线。完整协议仍只在 Basic Skill。CLI 只补骨架,绝不虚构岗位语义;只要 Agent Definition 或 Role Skill 仍含模板 `<...>`,`agent audit` 必须保持 `partial`。
21
21
  7. 审核能力:Basic Behavior 是所有钉钉员工共享且**每个 Session 必须加载**的协议;岗位知识和流程拆到独立 Role/Workflow Skill。目录可发现不等于正文已加载,必须为目标 Agent Host 生成可验证的加载合同。不要把 FDE、招聘、事故处理等岗位方法写回 Basic Skill。
@@ -98,11 +98,13 @@ metadata:
98
98
  ```bash
99
99
  # GitHub 仓库由宿主先 checkout;默认只生成改造计划,零写入
100
100
  dta agent enhance --project-name <agent-name> \
101
- --role-skill <role-skill-name> --dry-run --json
101
+ --role-skill <role-skill-name> \
102
+ --host <opencode|none> --dry-run --json
102
103
 
103
104
  # 审阅后执行 plan.apply.command;必须使用当前 planId + 显式 yes
104
105
  dta agent enhance --project-name <agent-name> \
105
106
  --role-skill <role-skill-name> \
107
+ --host <opencode|none> \
106
108
  --plan-id <current-plan-id> --yes --json
107
109
 
108
110
  # 填完 AGENTS.md 与 Role Skill 的真实身份、职责、SOP 和验收后再水合