From 7e86caf2ad5762d2c936ce244abe912831a2b0f6 Mon Sep 17 00:00:00 2001 From: twodogegg <971270272@qq.com> Date: Fri, 2 Oct 2026 14:18:16 +0800 Subject: [PATCH] feat(cli): add zcode agent profile Add a first-class zcode profile so skills can be installed into ZCode's skills directories with --agent zcode: - project-level: /.zcode/skills/ - user-level: ~/.zcode/skills/ The profile follows the existing makeProfile pattern with automatic detection of both scopes, and is covered by unit tests. Docs tables and the CLI changelog are updated accordingly. Signed-off-by: twodogegg <971270272@qq.com> --- cli/CHANGELOG.md | 2 ++ cli/README.md | 1 + cli/src/agents/detector.ts | 5 +++-- cli/src/agents/profiles/zcode.ts | 2 ++ cli/test/unit/agents/profiles.test.ts | 14 +++++++++++--- docs/skillhub/en/guide/cli.md | 1 + docs/skillhub/guide/cli.md | 1 + 7 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 cli/src/agents/profiles/zcode.ts diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index dcac2dfc..998bb731 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -6,6 +6,8 @@ All notable CLI behavior changes are documented in this file. ### Added +- Add the `zcode` agent profile, displayed as ZCode, with automatic detection of project-level + and user-level `.zcode/skills` directories. - Add the `dsh` agent profile, displayed as DeepSeek Harness, with automatic detection of project-level and user-level `.dsh/skills` directories. - Add OAuth Device Flow to `skillhub login` when no API token is supplied, including best-effort diff --git a/cli/README.md b/cli/README.md index 336b2cb5..f4a2e1f5 100644 --- a/cli/README.md +++ b/cli/README.md @@ -237,6 +237,7 @@ Most Agents have both project-level and user-level skills directories. Use `--sc | `opencode` | `/.opencode/skills/` | `~/.opencode/skills/` | | `kilo` | `/.kilo/skills/` | `~/.kilo/skills/` | | `pi` (Pi) | `/.pi/skills/` | `~/.pi/agent/skills/` | +| `zcode` | `/.zcode/skills/` | `~/.zcode/skills/` | | _fallback_ | `/.agents/skills/` | `~/.agents/skills/` | For a custom path or an unsupported Agent directory, use `--dir` to specify the installation path. In interactive user scope, the `generic` target is offered alongside detected Agent targets. AStudio appears in that selector when `~/.acode/skills/` exists. When `--scope user|project` finds no matching agent directory, the CLI falls back to the `_fallback_` row above. diff --git a/cli/src/agents/detector.ts b/cli/src/agents/detector.ts index 5873b98c..03f07aaf 100644 --- a/cli/src/agents/detector.ts +++ b/cli/src/agents/detector.ts @@ -16,19 +16,20 @@ import { traeCnProfile } from './profiles/trae-cn' import { opencodeProfile } from './profiles/opencode' import { kiloProfile } from './profiles/kilo' import { piProfile } from './profiles/pi' +import { zcodeProfile } from './profiles/zcode' export { aStudioProfile, claudeCodeProfile, codexProfile, cursorProfile, dshProfile, githubCopilotProfile, geminiCliProfile, openhandsProfile, windsurfProfile, openclawProfile, kiroCliProfile, rooProfile, traeProfile, traeCnProfile, - opencodeProfile, kiloProfile, piProfile + opencodeProfile, kiloProfile, piProfile, zcodeProfile } export const allProfiles: AgentProfile[] = [ aStudioProfile, claudeCodeProfile, codexProfile, cursorProfile, dshProfile, githubCopilotProfile, geminiCliProfile, openhandsProfile, windsurfProfile, openclawProfile, kiroCliProfile, rooProfile, traeProfile, traeCnProfile, - opencodeProfile, kiloProfile, piProfile + opencodeProfile, kiloProfile, piProfile, zcodeProfile ] export const profileMap = new Map(allProfiles.map(p => [p.id, p])) diff --git a/cli/src/agents/profiles/zcode.ts b/cli/src/agents/profiles/zcode.ts new file mode 100644 index 00000000..e96c78c3 --- /dev/null +++ b/cli/src/agents/profiles/zcode.ts @@ -0,0 +1,2 @@ +import { makeProfile } from './make-profile' +export const zcodeProfile = makeProfile('zcode', 'ZCode', '.zcode/skills', '.zcode/skills') diff --git a/cli/test/unit/agents/profiles.test.ts b/cli/test/unit/agents/profiles.test.ts index 2aabb0e0..a7be3c51 100644 --- a/cli/test/unit/agents/profiles.test.ts +++ b/cli/test/unit/agents/profiles.test.ts @@ -5,8 +5,8 @@ import { describe, expect, test } from 'bun:test' import { allProfiles, profileMap } from '../../../src/agents/detector' describe('agent profiles', () => { - test('has 17 tier 1 profiles', () => { - expect(allProfiles).toHaveLength(17) + test('has 18 tier 1 profiles', () => { + expect(allProfiles).toHaveLength(18) }) test('all profiles have unique ids', () => { @@ -15,7 +15,7 @@ describe('agent profiles', () => { }) test('profileMap contains all profiles', () => { - expect(profileMap.size).toBe(17) + expect(profileMap.size).toBe(18) expect(profileMap.has('astudio')).toBe(true) expect(profileMap.has('claude-code')).toBe(true) expect(profileMap.has('codex')).toBe(true) @@ -23,6 +23,7 @@ describe('agent profiles', () => { expect(profileMap.has('dsh')).toBe(true) expect(profileMap.has('kilo')).toBe(true) expect(profileMap.has('pi')).toBe(true) + expect(profileMap.has('zcode')).toBe(true) }) test('claude-code profile returns correct roots', () => { @@ -42,6 +43,13 @@ describe('agent profiles', () => { expect(profile.projectRoots('/repo')).toEqual(['/repo/.cursor/skills']) }) + test('zcode profile returns correct roots', () => { + const profile = profileMap.get('zcode')! + expect(profile.displayName).toBe('ZCode') + expect(profile.projectRoots('/repo')).toEqual(['/repo/.zcode/skills']) + expect(profile.userRoots('/home/user')).toEqual(['/home/user/.zcode/skills']) + }) + test('DeepSeek Harness exposes and detects its project and user skills directories', async () => { const base = await mkdtemp(join(tmpdir(), 'skillhub-dsh-profile-')) const cwd = join(base, 'repo') diff --git a/docs/skillhub/en/guide/cli.md b/docs/skillhub/en/guide/cli.md index 014cc29a..2ccc47f2 100644 --- a/docs/skillhub/en/guide/cli.md +++ b/docs/skillhub/en/guide/cli.md @@ -212,6 +212,7 @@ Most Agents have both project-level and user-level skills directories. Use `--sc | `opencode` | `/.opencode/skills/` | `~/.opencode/skills/` | | `kilo` | `/.kilo/skills/` | `~/.kilo/skills/` | | `pi` (Pi) | `/.pi/skills/` | `~/.pi/agent/skills/` | +| `zcode` | `/.zcode/skills/` | `~/.zcode/skills/` | | _fallback_ | `/.agents/skills/` | `~/.agents/skills/` | For a custom path or an unsupported Agent directory, use `--dir` to specify the installation path. In interactive user scope, the `generic` target is offered alongside detected Agent targets. AStudio appears in that selector when `~/.acode/skills/` exists. When `--scope user|project` finds no matching agent directory, the CLI falls back to the `_fallback_` row above. diff --git a/docs/skillhub/guide/cli.md b/docs/skillhub/guide/cli.md index f007f22c..da10fb01 100644 --- a/docs/skillhub/guide/cli.md +++ b/docs/skillhub/guide/cli.md @@ -208,6 +208,7 @@ CLI 按以下逻辑确定安装位置: | `opencode` | `/.opencode/skills/` | `~/.opencode/skills/` | | `kilo` | `/.kilo/skills/` | `~/.kilo/skills/` | | `pi`(Pi) | `/.pi/skills/` | `~/.pi/agent/skills/` | +| `zcode` | `/.zcode/skills/` | `~/.zcode/skills/` | | _fallback_ | `/.agents/skills/` | `~/.agents/skills/` | 对于自定义路径或不在列表中的 Agent 目录,使用 `--dir` 显式指定安装路径。交互式 user scope 下会与已探测 Agent 目标一同提供 `generic` 目标;当 `~/.acode/skills/` 存在时,选择器会显示 AStudio。当 `--scope user|project` 找不到匹配的 agent 目录时,CLI 会回退到上表的 `_fallback_` 行。