@xdxer/dingtalk-agent 0.1.4-beta.1 → 0.1.4-beta.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"skill-manager.js","sourceRoot":"","sources":["../../src/skill-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// 全局 Skill 生命周期:一个 canonical copy,按 Agent 客户端暴露。\n//\n// canonical: ~/.agents/skills/dingtalk-basic-behavior\n// Claude: ~/.claude/skills/dingtalk-basic-behavior -> canonical\n//\n// 不链接 npm/node_modules:包升级、卸载或 npx cache 清理都不应让 Skill 断掉。\n\nimport {\n cpSync, existsSync, lstatSync, mkdirSync, readFileSync, readlinkSync,\n readdirSync, renameSync, rmSync, symlinkSync, writeFileSync,\n} from 'node:fs'\nimport { createHash, randomUUID } from 'node:crypto'\nimport { homedir } from 'node:os'\nimport { dirname, join, relative, resolve } from 'node:path'\n\nexport const GLOBAL_SKILL_NAME = 'dingtalk-basic-behavior'\nconst MARKER = '.dingtalk-agent-install.json'\nconst MANAGER = '@xdxer/dingtalk-agent'\n\ninterface InstallMarker {\n $schema: 'dingtalk-agent/managed-skill@1'\n manager: typeof MANAGER\n packageVersion: string\n skillVersion: string\n sourceHash: string\n installedAt: string\n exposure: { claude: 'symlink' }\n}\n\nexport interface SkillManagerOptions {\n home?: string\n dryRun?: boolean\n discardLocalChanges?: boolean\n}\n\nexport interface GlobalSkillStatus {\n $schema: 'dingtalk-agent/skill-status@1'\n name: string\n bundled: { path: string; packageVersion: string; skillVersion: string; hash: string }\n canonical: {\n path: string\n exists: boolean\n managed: boolean\n installedHash: string\n modified: boolean\n current: boolean\n }\n claude: { path: string; state: 'ok' | 'missing' | 'conflict'; target: string }\n clients: Array<{\n name: 'claude-code' | 'codex' | 'opencode'\n label: string\n discovery: 'symlink' | 'shared-agent-skills'\n path: string\n state: 'ok' | 'missing' | 'conflict'\n }>\n legacyCodex: { path: string; conflict: boolean }\n}\n\nexport function skillStatus(packageRoot: string, options: SkillManagerOptions = {}): GlobalSkillStatus {\n const paths = globalPaths(packageRoot, options.home)\n const bundled = bundledInfo(packageRoot)\n const marker = readMarker(paths.canonical)\n const canonicalExists = pathExists(paths.canonical)\n const canonicalDirectory = canonicalExists && lstatSync(paths.canonical).isDirectory()\n const installedHash = canonicalDirectory ? hashDirectory(paths.canonical) : ''\n const managed = marker?.manager === MANAGER\n const modified = Boolean(managed && installedHash !== marker?.sourceHash)\n const claude = inspectExposure(paths.claude, paths.canonical)\n const sharedState = canonicalExists ? 'ok' : 'missing'\n return {\n $schema: 'dingtalk-agent/skill-status@1',\n name: GLOBAL_SKILL_NAME,\n bundled,\n canonical: {\n path: paths.canonical,\n exists: canonicalExists,\n managed,\n installedHash,\n modified,\n current: Boolean(managed && !modified && installedHash === bundled.hash),\n },\n claude: { path: paths.claude, ...claude },\n clients: [\n {\n name: 'claude-code', label: 'Claude Code', discovery: 'symlink',\n path: paths.claude, state: claude.state,\n },\n {\n name: 'codex', label: 'Codex', discovery: 'shared-agent-skills',\n path: paths.canonical, state: sharedState,\n },\n {\n name: 'opencode', label: 'OpenCode', discovery: 'shared-agent-skills',\n path: paths.canonical, state: sharedState,\n },\n ],\n legacyCodex: { path: paths.legacyCodex, conflict: pathExists(paths.legacyCodex) },\n }\n}\n\nexport function installGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n const before = skillStatus(packageRoot, options)\n if (before.canonical.exists) {\n if (!before.canonical.managed) {\n throw new Error(`全局 Skill 同名目录不归 dingtalk-agent 管理,拒绝覆盖: ${before.canonical.path}`)\n }\n if (before.canonical.modified) {\n throw new Error(`全局 Skill 有本地修改,拒绝覆盖: ${before.canonical.path}`)\n }\n if (!before.canonical.current) {\n throw new Error('已安装版本不是当前内置版本;请运行 `dingtalk-agent skill upgrade`')\n }\n ensureClaudeExposure(before.canonical.path, before.claude.path, options.dryRun)\n return options.dryRun ? before : skillStatus(packageRoot, options)\n }\n\n if (before.claude.state === 'conflict') {\n throw new Error(`Claude Skill 路径已有陌生内容,拒绝覆盖: ${before.claude.path}`)\n }\n if (!options.dryRun) {\n installCanonical(packageRoot, before.canonical.path)\n ensureClaudeExposure(before.canonical.path, before.claude.path, false)\n }\n return options.dryRun ? before : skillStatus(packageRoot, options)\n}\n\nexport function upgradeGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n const before = skillStatus(packageRoot, options)\n if (!before.canonical.exists) return installGlobalSkill(packageRoot, options)\n if (!before.canonical.managed) {\n throw new Error(`全局 Skill 不归 dingtalk-agent 管理,拒绝接管: ${before.canonical.path}`)\n }\n if (before.canonical.modified && !options.discardLocalChanges) {\n throw new Error(\n '全局 Skill 有本地修改;先保存改动,或显式使用 `--discard-local-changes` 放弃修改',\n )\n }\n if (before.claude.state === 'conflict') {\n throw new Error(`Claude Skill 路径已有陌生内容,拒绝覆盖: ${before.claude.path}`)\n }\n if (!options.dryRun && !before.canonical.current) {\n replaceCanonical(packageRoot, before.canonical.path)\n }\n ensureClaudeExposure(before.canonical.path, before.claude.path, options.dryRun)\n return options.dryRun ? before : skillStatus(packageRoot, options)\n}\n\nexport function uninstallGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n const before = skillStatus(packageRoot, options)\n if (!before.canonical.exists) return before\n if (!before.canonical.managed) {\n throw new Error(`全局 Skill 不归 dingtalk-agent 管理,拒绝删除: ${before.canonical.path}`)\n }\n if (before.canonical.modified && !options.discardLocalChanges) {\n throw new Error(\n '全局 Skill 有本地修改;先保存改动,或显式使用 `--discard-local-changes` 放弃修改',\n )\n }\n if (!options.dryRun) {\n if (before.claude.state === 'ok') rmSync(before.claude.path)\n rmSync(before.canonical.path, { recursive: true, force: true })\n }\n return options.dryRun ? before : skillStatus(packageRoot, options)\n}\n\nfunction globalPaths(packageRoot: string, home = homedir()) {\n return {\n source: join(packageRoot, 'skills', GLOBAL_SKILL_NAME),\n canonical: join(home, '.agents', 'skills', GLOBAL_SKILL_NAME),\n claude: join(home, '.claude', 'skills', GLOBAL_SKILL_NAME),\n legacyCodex: join(home, '.codex', 'skills', GLOBAL_SKILL_NAME),\n }\n}\n\nfunction bundledInfo(packageRoot: string) {\n const paths = globalPaths(packageRoot)\n validateSkill(paths.source)\n const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))\n const frontmatter = parseSkillFrontmatter(readFileSync(join(paths.source, 'SKILL.md'), 'utf8'))\n return {\n path: paths.source,\n packageVersion: String(pkg.version || ''),\n skillVersion: frontmatter.version,\n hash: hashDirectory(paths.source),\n }\n}\n\nfunction installCanonical(packageRoot: string, destination: string): void {\n const source = globalPaths(packageRoot).source\n const bundled = bundledInfo(packageRoot)\n const parent = dirname(destination)\n mkdirSync(parent, { recursive: true })\n const stage = join(parent, `.${GLOBAL_SKILL_NAME}.stage.${process.pid}.${randomUUID()}`)\n try {\n cpSync(source, stage, { recursive: true, errorOnExist: true, force: false })\n writeFileSync(join(stage, MARKER), JSON.stringify(markerFor(bundled), null, 2) + '\\n', { flag: 'wx' })\n validateSkill(stage)\n if (hashDirectory(stage) !== bundled.hash) throw new Error('Skill staging hash 与内置版本不一致')\n renameSync(stage, destination)\n } finally {\n rmSync(stage, { recursive: true, force: true })\n }\n}\n\nfunction replaceCanonical(packageRoot: string, destination: string): void {\n const parent = dirname(destination)\n const backup = join(parent, `.${GLOBAL_SKILL_NAME}.backup.${process.pid}.${randomUUID()}`)\n const stageDestination = join(parent, `.${GLOBAL_SKILL_NAME}.next.${process.pid}.${randomUUID()}`)\n installCanonical(packageRoot, stageDestination)\n renameSync(destination, backup)\n try {\n renameSync(stageDestination, destination)\n rmSync(backup, { recursive: true, force: true })\n } catch (error) {\n if (!existsSync(destination) && existsSync(backup)) renameSync(backup, destination)\n throw error\n } finally {\n rmSync(stageDestination, { recursive: true, force: true })\n }\n}\n\nfunction ensureClaudeExposure(canonical: string, exposure: string, dryRun = false): void {\n const state = inspectExposure(exposure, canonical)\n if (state.state === 'ok') return\n if (state.state === 'conflict') throw new Error(`Claude Skill 路径已有陌生内容: ${exposure}`)\n if (dryRun) return\n mkdirSync(dirname(exposure), { recursive: true })\n const target = relative(dirname(exposure), canonical) || '.'\n try {\n symlinkSync(target, exposure, 'dir')\n } catch (error) {\n throw new Error(\n `无法为 Claude Code 创建 Skill symlink: ${String(error.message || error)};` +\n '请检查 ~/.claude/skills 的写权限',\n )\n }\n}\n\nfunction inspectExposure(exposure: string, canonical: string): {\n state: 'ok' | 'missing' | 'conflict'\n target: string\n} {\n if (!pathExists(exposure)) return { state: 'missing', target: '' }\n const stat = lstatSync(exposure)\n if (!stat.isSymbolicLink()) return { state: 'conflict', target: '' }\n const raw = readlinkSync(exposure)\n const target = resolve(dirname(exposure), raw)\n return target === resolve(canonical)\n ? { state: 'ok', target: raw }\n : { state: 'conflict', target: raw }\n}\n\nfunction markerFor(bundled: ReturnType<typeof bundledInfo>): InstallMarker {\n return {\n $schema: 'dingtalk-agent/managed-skill@1',\n manager: MANAGER,\n packageVersion: bundled.packageVersion,\n skillVersion: bundled.skillVersion,\n sourceHash: bundled.hash,\n installedAt: new Date().toISOString(),\n exposure: { claude: 'symlink' },\n }\n}\n\nfunction readMarker(skillRoot: string): InstallMarker | null {\n const path = join(skillRoot, MARKER)\n if (!existsSync(path)) return null\n try {\n const value = JSON.parse(readFileSync(path, 'utf8'))\n return value?.$schema === 'dingtalk-agent/managed-skill@1' ? value : null\n } catch { return null }\n}\n\nfunction pathExists(path: string): boolean {\n try { lstatSync(path); return true } catch { return false }\n}\n\nfunction validateSkill(root: string): void {\n if (!existsSync(root) || !lstatSync(root).isDirectory()) {\n throw new Error(`内置 Skill 不存在: ${root}`)\n }\n const file = join(root, 'SKILL.md')\n if (!existsSync(file)) throw new Error(`Skill 缺少 SKILL.md: ${root}`)\n const metadata = parseSkillFrontmatter(readFileSync(file, 'utf8'))\n if (metadata.name !== GLOBAL_SKILL_NAME) {\n throw new Error(`Skill name=${metadata.name} 与目录名 ${GLOBAL_SKILL_NAME} 不一致`)\n }\n if (!metadata.description) throw new Error('Skill frontmatter 缺少 description')\n}\n\nfunction parseSkillFrontmatter(text: string): { name: string; description: string; version: string } {\n const match = text.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/)\n if (!match) throw new Error('SKILL.md 缺少 YAML frontmatter')\n const block = match[1]\n const readScalar = (key: string) => {\n const found = block.match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'))\n return found ? found[1].trim().replace(/^(['\"])(.*)\\1$/, '$2') : ''\n }\n const nestedVersion = block.match(/^metadata:\\s*\\r?\\n(?:[ \\t]+.*\\r?\\n)*?[ \\t]+version:\\s*['\"]?([^'\"\\r\\n]+)['\"]?\\s*$/m)\n return {\n name: readScalar('name'),\n description: readScalar('description'),\n version: nestedVersion?.[1]?.trim() || readScalar('version'),\n }\n}\n\nfunction hashDirectory(root: string): string {\n const hash = createHash('sha256')\n for (const path of walk(root)) {\n const rel = relative(root, path).split('\\\\').join('/')\n if (rel === MARKER) continue\n hash.update(rel).update('\\0').update(readFileSync(path)).update('\\0')\n }\n return hash.digest('hex')\n}\n\nfunction walk(root: string): string[] {\n const out: string[] = []\n for (const name of readdirSync(root).sort()) {\n const path = join(root, name)\n const stat = lstatSync(path)\n if (stat.isSymbolicLink()) throw new Error(`Skill 内不允许符号链接: ${path}`)\n if (stat.isDirectory()) out.push(...walk(path))\n else if (stat.isFile()) out.push(path)\n }\n return out\n}\n"]}
1
+ {"version":3,"file":"skill-manager.js","sourceRoot":"","sources":["../../src/skill-manager.ts"],"names":[],"mappings":"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","sourcesContent":["// Skill 安装生命周期由开放生态的 `npx skills` 负责。\n// dingtalk-agent 只做两件事:把内置 Skill 目录交给上游 CLI;只读验证客户端能否发现。\n\nimport { existsSync, lstatSync, readFileSync, readlinkSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join, resolve } from 'node:path'\nimport { spawnSync } from 'node:child_process'\n\nexport const GLOBAL_SKILL_NAME = 'dingtalk-basic-behavior'\nconst SKILLS_PACKAGE = 'skills@latest'\nconst REGISTRY = 'https://registry.npmjs.org'\nconst AGENTS = ['claude-code', 'codex', 'opencode']\n\nexport interface SkillManagerOptions {\n home?: string\n dryRun?: boolean\n env?: NodeJS.ProcessEnv\n}\n\nexport interface GlobalSkillStatus {\n $schema: 'dingtalk-agent/skill-status@2'\n name: string\n manager: 'skills-cli'\n bundled: { path: string; packageVersion: string; skillVersion: string }\n canonical: {\n path: string\n exists: boolean\n installedVersion: string\n current: boolean\n }\n claude: { path: string; state: 'ok' | 'missing' | 'conflict'; target: string }\n clients: Array<{\n name: 'claude-code' | 'codex' | 'opencode'\n label: string\n discovery: 'symlink' | 'shared-agent-skills'\n path: string\n state: 'ok' | 'missing' | 'conflict'\n }>\n operation?: {\n action: 'install' | 'upgrade' | 'uninstall'\n command: string\n executed: boolean\n exitCode: number | null\n output: string\n }\n}\n\nexport function skillStatus(packageRoot: string, options: SkillManagerOptions = {}): GlobalSkillStatus {\n const paths = globalPaths(packageRoot, options.home)\n const bundled = bundledInfo(packageRoot)\n const canonicalExists = isDirectory(paths.canonical)\n const installedVersion = canonicalExists\n ? parseSkillFrontmatter(readFileSync(join(paths.canonical, 'SKILL.md'), 'utf8')).version\n : ''\n const claude = inspectExposure(paths.claude, paths.canonical)\n const sharedState = canonicalExists ? 'ok' : 'missing'\n return {\n $schema: 'dingtalk-agent/skill-status@2',\n name: GLOBAL_SKILL_NAME,\n manager: 'skills-cli',\n bundled,\n canonical: {\n path: paths.canonical,\n exists: canonicalExists,\n installedVersion,\n current: Boolean(canonicalExists && installedVersion === bundled.skillVersion),\n },\n claude: { path: paths.claude, ...claude },\n clients: [\n {\n name: 'claude-code', label: 'Claude Code', discovery: 'symlink',\n path: paths.claude, state: claude.state,\n },\n {\n name: 'codex', label: 'Codex', discovery: 'shared-agent-skills',\n path: paths.canonical, state: sharedState,\n },\n {\n name: 'opencode', label: 'OpenCode', discovery: 'shared-agent-skills',\n path: paths.canonical, state: sharedState,\n },\n ],\n }\n}\n\nexport function installGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n return runSkills(packageRoot, 'install', [\n 'add', globalPaths(packageRoot).source,\n '--global', '--yes', '--agent', ...AGENTS,\n ], options)\n}\n\nexport function upgradeGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n // Skill 随 npm 包发布;重新 add 当前包内目录,让 skills CLI 执行自己的覆盖/链接语义。\n return runSkills(packageRoot, 'upgrade', [\n 'add', globalPaths(packageRoot).source,\n '--global', '--yes', '--agent', ...AGENTS,\n ], options)\n}\n\nexport function uninstallGlobalSkill(\n packageRoot: string,\n options: SkillManagerOptions = {},\n): GlobalSkillStatus {\n return runSkills(packageRoot, 'uninstall', [\n 'remove', GLOBAL_SKILL_NAME,\n '--global', '--yes', '--agent', ...AGENTS,\n ], options)\n}\n\nfunction runSkills(\n packageRoot: string,\n action: 'install' | 'upgrade' | 'uninstall',\n args: string[],\n options: SkillManagerOptions,\n): GlobalSkillStatus {\n const commandArgs = ['--yes', `--registry=${REGISTRY}`, SKILLS_PACKAGE, ...args]\n const command = ['npx', ...commandArgs].map(shellQuote).join(' ')\n const before = skillStatus(packageRoot, options)\n if (options.dryRun) {\n return {\n ...before,\n operation: { action, command, executed: false, exitCode: null, output: '' },\n }\n }\n\n const env = {\n ...process.env,\n ...(options.env || {}),\n HOME: options.home || options.env?.HOME || process.env.HOME || homedir(),\n }\n const run = spawnSync('npx', commandArgs, {\n encoding: 'utf8', env, timeout: 120_000,\n })\n const output = [run.stdout, run.stderr].filter(Boolean).join('\\n').trim()\n if (run.error || run.status !== 0) {\n const reason = (run.error as NodeJS.ErrnoException | undefined)?.code === 'ENOENT'\n ? 'PATH 找不到 npx;请安装带 npm/npx 的 Node.js 18.3+'\n : run.error?.message || output || `退出码 ${run.status}`\n throw new Error(\n `skills CLI ${action} 失败: ${reason}\\n` +\n `可手动执行: ${command}`,\n )\n }\n return {\n ...skillStatus(packageRoot, options),\n operation: { action, command, executed: true, exitCode: run.status, output },\n }\n}\n\nfunction globalPaths(packageRoot: string, home = homedir()) {\n return {\n source: join(packageRoot, 'skills', GLOBAL_SKILL_NAME),\n canonical: join(home, '.agents', 'skills', GLOBAL_SKILL_NAME),\n claude: join(home, '.claude', 'skills', GLOBAL_SKILL_NAME),\n }\n}\n\nfunction bundledInfo(packageRoot: string) {\n const source = globalPaths(packageRoot).source\n validateSkill(source)\n const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))\n const frontmatter = parseSkillFrontmatter(readFileSync(join(source, 'SKILL.md'), 'utf8'))\n return {\n path: source,\n packageVersion: String(pkg.version || ''),\n skillVersion: frontmatter.version,\n }\n}\n\nfunction inspectExposure(exposure: string, canonical: string): {\n state: 'ok' | 'missing' | 'conflict'\n target: string\n} {\n if (!pathExists(exposure)) return { state: 'missing', target: '' }\n const stat = lstatSync(exposure)\n if (!stat.isSymbolicLink()) return { state: 'conflict', target: '' }\n const raw = readlinkSync(exposure)\n return resolve(dirname(exposure), raw) === resolve(canonical)\n ? { state: 'ok', target: raw }\n : { state: 'conflict', target: raw }\n}\n\nfunction validateSkill(root: string): void {\n if (!isDirectory(root)) throw new Error(`内置 Skill 不存在: ${root}`)\n const file = join(root, 'SKILL.md')\n if (!existsSync(file)) throw new Error(`Skill 缺少 SKILL.md: ${root}`)\n const metadata = parseSkillFrontmatter(readFileSync(file, 'utf8'))\n if (metadata.name !== GLOBAL_SKILL_NAME) {\n throw new Error(`Skill name=${metadata.name} 与目录名 ${GLOBAL_SKILL_NAME} 不一致`)\n }\n if (!metadata.description) throw new Error('Skill frontmatter 缺少 description')\n}\n\nfunction parseSkillFrontmatter(text: string): { name: string; description: string; version: string } {\n const match = text.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---(?:\\r?\\n|$)/)\n if (!match) throw new Error('SKILL.md 缺少 YAML frontmatter')\n const block = match[1]\n const readScalar = (key: string) => {\n const found = block.match(new RegExp(`^${key}:\\\\s*(.+)$`, 'm'))\n return found ? found[1].trim().replace(/^(['\"])(.*)\\1$/, '$2') : ''\n }\n const nestedVersion = block.match(/^metadata:\\s*\\r?\\n(?:[ \\t]+.*\\r?\\n)*?[ \\t]+version:\\s*['\"]?([^'\"\\r\\n]+)['\"]?\\s*$/m)\n return {\n name: readScalar('name'),\n description: readScalar('description'),\n version: nestedVersion?.[1]?.trim() || readScalar('version'),\n }\n}\n\nfunction isDirectory(path: string): boolean {\n try { return lstatSync(path).isDirectory() } catch { return false }\n}\n\nfunction pathExists(path: string): boolean {\n try { lstatSync(path); return true } catch { return false }\n}\n\nfunction shellQuote(value: string): string {\n return /^[A-Za-z0-9_./:=@-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\"'\"'`)}'`\n}\n"]}
@@ -214,4 +214,4 @@ npm run typecheck
214
214
  npm run eval:contract
215
215
  ```
216
216
 
217
- 28 个确定性场景覆盖三条主链:setup/PATH/DWS/多客户端发现、Skill-first 安装/水合,以及 Prepared Run 的 Session、Wait、幂等、目标与回执。
217
+ 29 个确定性场景覆盖三条主链:setup/PATH/DWS/多客户端发现与错误提示、基于 `npx skills` 的 Skill-first 安装/水合,以及 Prepared Run 的 Session、Wait、幂等、目标与回执。
@@ -8,6 +8,14 @@
8
8
  npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@beta setup
9
9
  ```
10
10
 
11
+ 安装完成后优先使用短命令;长短名称完全等价:
12
+
13
+ ```bash
14
+ dta --version
15
+ dta doctor
16
+ # 等价于 dingtalk-agent doctor
17
+ ```
18
+
11
19
  Why:npm 全局命令会被链接到 `{prefix}/bin`,但不同 Node 版本管理器可能使用不同 prefix;包已经安装不代表该目录已进入当前 shell 的 PATH。`npx`/`npm exec` 会直接运行指定 npm 包,因此可以先启动安装器,再由安装器修复稳定入口。
12
20
 
13
21
  ## setup 做什么
@@ -65,7 +73,15 @@ dws auth login
65
73
 
66
74
  ## Skill 安装策略
67
75
 
68
- `dingtalk-agent skill install` 使用一份 canonical copy,避免 npm cache 清理或包升级导致软链接断裂:
76
+ `dta` 不维护第二套 Skill 安装器。`dta skill install` 等价于把 npm 包内的 Skill 目录交给开放生态的 `npx skills add`:
77
+
78
+ ```bash
79
+ npx --yes --registry=https://registry.npmjs.org skills@latest add \
80
+ <package>/skills/dingtalk-basic-behavior \
81
+ --global --yes --agent claude-code codex opencode
82
+ ```
83
+
84
+ 上游 `skills` CLI 负责 canonical copy、客户端链接、覆盖和卸载语义:
69
85
 
70
86
  | 客户端 | 发现方式 | 路径 |
71
87
  |---|---|---|
@@ -73,13 +89,16 @@ dws auth login
73
89
  | Codex | shared Agent Skills | `~/.agents/skills/dingtalk-basic-behavior` |
74
90
  | OpenCode | shared Agent Skills | `~/.agents/skills/dingtalk-basic-behavior` |
75
91
 
76
- 安装器不会覆盖陌生同名目录,也不会静默覆盖用户对受管 Skill 的本地修改。检查和升级:
92
+ 检查、重装当前 npm 包内版本和卸载:
77
93
 
78
94
  ```bash
79
- dingtalk-agent skill status
80
- dingtalk-agent skill upgrade
95
+ dta skill status
96
+ dta skill upgrade
97
+ dta skill uninstall
81
98
  ```
82
99
 
100
+ `skill status` 只做只读发现检查;`install/upgrade/uninstall` 分别委托 `skills add/add/remove`。旧版 dta 写入的管理 marker 会在第一次 `skills add` 时被上游 canonical copy 替换,此后不再存在两套管理状态。
101
+
83
102
  OpenCode 官方同时支持 `.opencode/skills`、`.claude/skills` 和 `.agents/skills`,所以不需要再复制第三份内容。
84
103
 
85
104
  ## 使用 npx skills
@@ -97,7 +116,7 @@ npx skills add ./skills/dingtalk-basic-behavior \
97
116
  --global --yes --agent claude-code --agent codex --agent opencode
98
117
  ```
99
118
 
100
- 两种管理器不要交叉覆盖同一个安装。`dingtalk-agent` 发现 canonical 目录不归自己管理时会 fail closed;此时继续使用 `npx skills update/remove` 管理即可。
119
+ 也可以完全绕过 `dta skill ...`,直接使用 `npx skills` 管理;两种入口最终调用的是同一个上游安装器。
101
120
 
102
121
  ## 初始化的三个层级
103
122
 
@@ -110,14 +129,14 @@ init Workspace 级,可选:只为长期 Workspace / Prepared Run 创建
110
129
  普通 Claude Code、Codex 或 OpenCode 会话:
111
130
 
112
131
  ```bash
113
- dingtalk-agent bootstrap --json
132
+ dta bootstrap --json
114
133
  ```
115
134
 
116
135
  需要可信钉钉事件、Session/Run/Wait/Receipt 时才执行:
117
136
 
118
137
  ```bash
119
- dingtalk-agent init
120
- dingtalk-agent prepare --event-file event.json --json
138
+ dta init
139
+ dta prepare --event-file event.json --json
121
140
  ```
122
141
 
123
142
  ## Doctor 退出码
@@ -126,6 +145,17 @@ dingtalk-agent prepare --event-file event.json --json
126
145
  - `2`:至少一个必要条件不满足,同时输出确定的修复命令;
127
146
  - `--json`:输出 `dingtalk-agent/doctor@1`,供安装器、CI 或宿主解析。
128
147
 
148
+ ## 错误提示约定
149
+
150
+ CLI 错误统一包含两层信息:
151
+
152
+ ```text
153
+ 错误: 发生了什么,以及为什么拒绝继续
154
+ 提示: 下一条可复制执行的恢复命令
155
+ ```
156
+
157
+ 命令拼写错误会建议最接近的命令;DWS 错误指向 `dta doctor`/`dws auth login`;没有可信 Run 时会明确要求先 `prepare`,不会暗中初始化或猜测目标。
158
+
129
159
  ## 设计依据
130
160
 
131
161
  - [npm Folders](https://docs.npmjs.com/files/folders.html/):Unix 全局 executable 被链接到 `{prefix}/bin`;
package/evals/evals.json CHANGED
@@ -214,13 +214,13 @@
214
214
  {
215
215
  "id": 20,
216
216
  "prompt": "在一个没有 Workspace 的空目录安装全局 Basic Behavior,重复安装,再制造一个同名陌生 Skill。",
217
- "expected_output": "安装不依赖 init;canonical copy 可被 Codex 发现,Claude 使用相对 symlink;重复安装幂等;陌生同名目录绝不覆盖。",
217
+ "expected_output": "安装不依赖 init;dta 将本地 Skill source 委托给 npx skills;canonical copy 可被 Codex/OpenCode 发现,Claude 使用 symlink;重复安装由上游处理。",
218
218
  "files": [],
219
219
  "expectations": [
220
220
  "空目录可直接安装 canonical Skill",
221
- "重复安装保持 current 且无漂移",
222
- "Claude exposure 是指向 canonical 的相对 symlink",
223
- "同名陌生 Skill fail closed"
221
+ "重复安装由 skills CLI 执行并保持 current",
222
+ "Claude exposure 指向 canonical copy",
223
+ "安装结果不再包含 dta 自定义管理 marker"
224
224
  ]
225
225
  },
226
226
  {
@@ -259,14 +259,14 @@
259
259
  },
260
260
  {
261
261
  "id": 24,
262
- "prompt": "安装受管 Skill 后手工修改内容,再尝试 upgrade/uninstall,最后显式放弃本地修改并卸载。",
263
- "expected_output": "status 识别漂移;默认升级和卸载都保护本地修改;显式 discard 后原子修复;卸载只移除受管 canonical 与准确的 Claude exposure。",
262
+ "prompt": "通过 dta 安装 Skill 后手工修改内容,再执行 upgradeuninstall",
263
+ "expected_output": "status 只读报告 skills-cli 管理状态;upgrade 通过 npx skills add 重装;uninstall 通过 npx skills remove 清理所有目标客户端。",
264
264
  "files": [],
265
265
  "expectations": [
266
- "受管 Skill 的本地漂移可被检测",
267
- "upgrade 默认不覆盖本地修改",
268
- "uninstall 默认不删除本地修改",
269
- "显式 discard 可修复,随后安全卸载 canonical 与 exposure"
266
+ "status 明确报告 manager=skills-cli",
267
+ "upgrade 委托 skills add 并采用上游覆盖语义",
268
+ "uninstall 委托 skills remove",
269
+ "升级后版本 current,卸载后 canonical 与 exposure 消失"
270
270
  ]
271
271
  },
272
272
  {
@@ -311,6 +311,17 @@
311
311
  "canonical Skill 与 Claude exposure 安装成功,三个 Agent 客户端均可发现",
312
312
  "DWS 版本和认证检查通过,setup 最终 ready"
313
313
  ]
314
+ },
315
+ {
316
+ "id": 29,
317
+ "prompt": "分别输入拼错的顶层命令、拼错的 skill 子命令和不支持的参数。",
318
+ "expected_output": "CLI 使用统一的错误与提示格式,给出最接近的 dta 命令或明确的参数恢复入口。",
319
+ "files": [],
320
+ "expectations": [
321
+ "顶层命令拼错时同时输出原因和 dta doctor 建议",
322
+ "skill 子命令拼错时建议 dta skill install",
323
+ "参数错误时提示检查拼写并运行 dta --help"
324
+ ]
314
325
  }
315
326
  ]
316
327
  }
@@ -6,7 +6,7 @@ import {
6
6
  readdirSync, cpSync, existsSync, lstatSync, readlinkSync,
7
7
  } from 'node:fs'
8
8
  import { tmpdir } from 'node:os'
9
- import { join, dirname } from 'node:path'
9
+ import { join, dirname, resolve } from 'node:path'
10
10
  import { fileURLToPath } from 'node:url'
11
11
  import { spawnSync } from 'node:child_process'
12
12
  import { init } from '../dist/src/init.js'
@@ -42,7 +42,7 @@ const cases = [
42
42
  evalWorkspaceAuthority, evalSessionSkillBinding,
43
43
  evalGlobalSkillInstall, evalBootstrapLocal, evalBootstrapRemote, evalOptionalInit,
44
44
  evalManagedSkillLifecycle, evalRemoteStorageTypeGate, evalDirectActGate,
45
- evalDoctorMissingDependencies, evalFirstRunSetup,
45
+ evalDoctorMissingDependencies, evalFirstRunSetup, evalCliErrorHints,
46
46
  ]
47
47
  const benchmarkRuns = []
48
48
  for (let i = 0; i < cases.length; i++) {
@@ -748,8 +748,7 @@ function evalSessionSkillBinding() {
748
748
  function evalGlobalSkillInstall() {
749
749
  const home = mkdtempSync(join(tmpdir(), 'dta-skill-home-'))
750
750
  const cwd = mkdtempSync(join(tmpdir(), 'dta-skill-cwd-'))
751
- const foreignHome = mkdtempSync(join(tmpdir(), 'dta-skill-foreign-'))
752
- WORKSPACES.push(home, cwd, foreignHome)
751
+ WORKSPACES.push(home, cwd)
753
752
  const env = { ...process.env, HOME: home }
754
753
  const first = spawnSync(process.execPath, [CLI, 'skill', 'install', '--json'], {
755
754
  cwd, env, encoding: 'utf8',
@@ -761,29 +760,23 @@ function evalGlobalSkillInstall() {
761
760
  const canonical = join(home, '.agents', 'skills', 'dingtalk-basic-behavior')
762
761
  const claude = join(home, '.claude', 'skills', 'dingtalk-basic-behavior')
763
762
 
764
- const foreign = join(foreignHome, '.agents', 'skills', 'dingtalk-basic-behavior')
765
- mkdirSync(foreign, { recursive: true })
766
- writeFileSync(join(foreign, 'SKILL.md'), '---\nname: dingtalk-basic-behavior\ndescription: foreign\n---\n')
767
- const conflict = spawnSync(process.execPath, [CLI, 'skill', 'install'], {
768
- cwd, env: { ...process.env, HOME: foreignHome }, encoding: 'utf8',
769
- })
763
+ const marker = join(canonical, '.dingtalk-agent-install.json')
770
764
  return {
771
765
  output: {
772
766
  firstStatus: first.status, secondStatus: second.status, status,
773
- claudeTarget: readlinkSync(claude), conflictStatus: conflict.status,
774
- conflictError: conflict.stderr.trim(),
767
+ claudeTarget: readlinkSync(claude), markerExists: existsSync(marker),
775
768
  },
776
769
  toolCalls: 3, steps: 6,
777
770
  checks: [
778
771
  check(first.status === 0 && existsSync(join(canonical, 'SKILL.md')),
779
772
  `status=${first.status}; canonical=${canonical}`),
780
- check(second.status === 0 && status.canonical.current === true &&
781
- status.canonical.modified === false,
782
- `status=${second.status}; current=${status.canonical.current}; modified=${status.canonical.modified}`),
773
+ check(second.status === 0 && status.manager === 'skills-cli' &&
774
+ status.canonical.current === true && status.operation?.command.includes('skills@latest add'),
775
+ `status=${second.status}; manager=${status.manager}; current=${status.canonical.current}`),
783
776
  check(lstatSync(claude).isSymbolicLink() &&
784
- readlinkSync(claude) === '../../.agents/skills/dingtalk-basic-behavior',
777
+ resolve(dirname(claude), readlinkSync(claude)) === resolve(canonical),
785
778
  `target=${readlinkSync(claude)}`),
786
- check(conflict.status !== 0 && conflict.stderr.includes('拒绝覆盖'), conflict.stderr.trim()),
779
+ check(!existsSync(marker), '上游 skills CLI 接管后不存在 dta 自定义 marker'),
787
780
  ],
788
781
  }
789
782
  }
@@ -879,33 +872,29 @@ function evalManagedSkillLifecycle() {
879
872
  cwd, env, encoding: 'utf8',
880
873
  })
881
874
  const modified = JSON.parse(statusRun.stdout)
882
- const guardedUpgrade = spawnSync(process.execPath, [CLI, 'skill', 'upgrade'], {
883
- cwd, env, encoding: 'utf8',
884
- })
885
- const guardedUninstall = spawnSync(process.execPath, [CLI, 'skill', 'uninstall'], {
875
+ const repaired = spawnSync(process.execPath, [CLI, 'skill', 'upgrade', '--json'], {
886
876
  cwd, env, encoding: 'utf8',
887
877
  })
888
- const repaired = spawnSync(process.execPath, [
889
- CLI, 'skill', 'upgrade', '--discard-local-changes', '--json',
890
- ], { cwd, env, encoding: 'utf8' })
891
878
  const repairedStatus = JSON.parse(repaired.stdout)
879
+ const repairedBody = readFileSync(file, 'utf8')
892
880
  const removed = spawnSync(process.execPath, [CLI, 'skill', 'uninstall', '--json'], {
893
881
  cwd, env, encoding: 'utf8',
894
882
  })
895
883
  const removedStatus = JSON.parse(removed.stdout)
896
884
  return {
897
885
  output: {
898
- modified, guardedUpgrade: guardedUpgrade.stderr.trim(),
899
- guardedUninstall: guardedUninstall.stderr.trim(), repairedStatus, removedStatus,
886
+ modified, repairedStatus, removedStatus,
900
887
  },
901
- toolCalls: 6, steps: 7,
888
+ toolCalls: 4, steps: 6,
902
889
  checks: [
903
- check(modified.canonical.modified === true, JSON.stringify(modified.canonical)),
904
- check(guardedUpgrade.status !== 0 && guardedUpgrade.stderr.includes('本地修改'),
905
- guardedUpgrade.stderr.trim()),
906
- check(guardedUninstall.status !== 0 && guardedUninstall.stderr.includes('本地修改'),
907
- guardedUninstall.stderr.trim()),
908
- check(repaired.status === 0 && repairedStatus.canonical.current === true &&
890
+ check(modified.manager === 'skills-cli' && modified.canonical.exists === true,
891
+ JSON.stringify(modified.canonical)),
892
+ check(repaired.status === 0 && !repairedBody.includes('local edit') &&
893
+ repairedStatus.operation?.command.includes('skills@latest add'),
894
+ `status=${repaired.status}; command=${repairedStatus.operation?.command}`),
895
+ check(removed.status === 0 && removedStatus.operation?.command.includes('skills@latest remove'),
896
+ `status=${removed.status}; command=${removedStatus.operation?.command}`),
897
+ check(repairedStatus.canonical.current === true &&
909
898
  removed.status === 0 && removedStatus.canonical.exists === false &&
910
899
  removedStatus.claude.state === 'missing',
911
900
  `repaired=${repairedStatus.canonical.current}; removed=${removedStatus.canonical.exists}; ` +
@@ -996,21 +985,28 @@ function evalFirstRunSetup() {
996
985
  })
997
986
  const out = run.stdout ? JSON.parse(run.stdout) : null
998
987
  const executable = join(home, '.local', 'bin', 'dingtalk-agent')
988
+ const alias = join(home, '.local', 'bin', 'dta')
999
989
  const version = existsSync(executable)
1000
990
  ? spawnSync(executable, ['--version'], { env, encoding: 'utf8' })
1001
991
  : { status: -1, stdout: '' }
992
+ const aliasVersion = existsSync(alias)
993
+ ? spawnSync(alias, ['--version'], { env, encoding: 'utf8' })
994
+ : { status: -1, stdout: '' }
1002
995
  const rc = existsSync(join(home, '.zshrc')) ? readFileSync(join(home, '.zshrc'), 'utf8') : ''
1003
996
  const canonical = join(home, '.agents', 'skills', 'dingtalk-basic-behavior')
1004
997
  const claude = join(home, '.claude', 'skills', 'dingtalk-basic-behavior')
1005
998
  return {
1006
999
  output: {
1007
1000
  status: run.status, stderr: run.stderr.trim(), report: out,
1008
- executable, version: String(version.stdout || '').trim(), rc,
1001
+ executable, alias, version: String(version.stdout || '').trim(),
1002
+ aliasVersion: String(aliasVersion.stdout || '').trim(), rc,
1009
1003
  },
1010
1004
  toolCalls: 1, steps: 6,
1011
1005
  checks: [
1012
- check(run.status === 0 && existsSync(executable) && version.status === 0,
1013
- `status=${run.status}; executable=${existsSync(executable)}; version=${version.status}`),
1006
+ check(run.status === 0 && existsSync(executable) && version.status === 0 &&
1007
+ existsSync(alias) && aliasVersion.status === 0 && aliasVersion.stdout === version.stdout,
1008
+ `status=${run.status}; executable=${existsSync(executable)}; alias=${existsSync(alias)}; ` +
1009
+ `version=${version.status}/${aliasVersion.status}`),
1014
1010
  check(out?.shell.updated === true && rc.includes('dingtalk-agent PATH') &&
1015
1011
  rc.includes('$HOME/.local/bin'),
1016
1012
  `updated=${out?.shell.updated}; rc=${JSON.stringify(rc)}`),
@@ -1025,6 +1021,28 @@ function evalFirstRunSetup() {
1025
1021
  }
1026
1022
  }
1027
1023
 
1024
+ function evalCliErrorHints() {
1025
+ const typo = spawnSync(process.execPath, [CLI, 'doctro'], { encoding: 'utf8' })
1026
+ const subcommand = spawnSync(process.execPath, [CLI, 'skill', 'instal'], { encoding: 'utf8' })
1027
+ const option = spawnSync(process.execPath, [CLI, 'doctor', '--bogus'], { encoding: 'utf8' })
1028
+ return {
1029
+ output: {
1030
+ typo: { status: typo.status, stderr: typo.stderr.trim() },
1031
+ subcommand: { status: subcommand.status, stderr: subcommand.stderr.trim() },
1032
+ option: { status: option.status, stderr: option.stderr.trim() },
1033
+ },
1034
+ toolCalls: 3, steps: 3,
1035
+ checks: [
1036
+ check(typo.status === 1 && typo.stderr.includes('错误:') &&
1037
+ typo.stderr.includes('提示:') && typo.stderr.includes('dta doctor'), typo.stderr.trim()),
1038
+ check(subcommand.status === 1 && subcommand.stderr.includes('dta skill install'),
1039
+ subcommand.stderr.trim()),
1040
+ check(option.status === 2 && option.stderr.includes('检查参数拼写') &&
1041
+ option.stderr.includes('dta --help'), option.stderr.trim()),
1042
+ ],
1043
+ }
1044
+ }
1045
+
1028
1046
  function dmEvent(eventId, messageId, actor, text, extra = {}) {
1029
1047
  return {
1030
1048
  event_corp_id: extra.tenantId || 'tenant-wait-eval',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xdxer/dingtalk-agent",
3
- "version": "0.1.4-beta.1",
3
+ "version": "0.1.4-beta.3",
4
4
  "description": "钉钉数字员工的 Skill-first 行为范式:全局 Skill 决策,CLI 固定事务边界,Workspace 按需。",
5
5
  "keywords": [
6
6
  "dingtalk",