diff --git a/docs/site/content/docs/agents/supported.mdx b/docs/site/content/docs/agents/supported.mdx index 1d2f4964577b..cf174afebf8a 100644 --- a/docs/site/content/docs/agents/supported.mdx +++ b/docs/site/content/docs/agents/supported.mdx @@ -59,3 +59,4 @@ To restore prompts for one agent only, edit that agent's default arguments or en | Hermes | Auto-setup | [Nous](https://hermes-agent.nousresearch.com/docs/) | | OpenClaw | Auto-setup | [OpenClaw](https://github.com/openclaw/openclaw) | | Trae | Auto-setup via `traecli` (TRAE CN CLI) | [Trae](https://www.trae.ai/) | +| ZCode | Auto-setup | [Z.ai](https://zcode.z.ai) | diff --git a/mobile/src/components/mobile-agent-icon-assets.ts b/mobile/src/components/mobile-agent-icon-assets.ts index 38a48373734b..003dcc61401e 100644 --- a/mobile/src/components/mobile-agent-icon-assets.ts +++ b/mobile/src/components/mobile-agent-icon-assets.ts @@ -17,6 +17,7 @@ export const MOBILE_AGENT_ICON_ASSETS: Partial> 'mimo-code': 'mimo.xiaomi.com', ante: 'antigma.ai', trae: 'www.trae.cn', + zcode: 'z.ai', omp: 'omp.sh', 'prime-agent': 'primeintellect.ai', gemini: 'gemini.google.com', diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index 487c8f9bdbe2..49cff6f1815a 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -606,6 +606,7 @@ "fc80296033": "Devin", "da41abbdd4": "Ante", "060d152fb5": "Trae", + "e6fdf4b9e0": "ZCode", "d443a47995": "Prime Agent", "mimo_code_label": "MiMo Code", "opencode2_label": "OpenCode 2" diff --git a/src/renderer/src/i18n/locales/es.json b/src/renderer/src/i18n/locales/es.json index cfccde752809..d304002501c1 100644 --- a/src/renderer/src/i18n/locales/es.json +++ b/src/renderer/src/i18n/locales/es.json @@ -354,6 +354,7 @@ "fc80296033": "Devin", "da41abbdd4": "Ante", "060d152fb5": "Trae", + "e6fdf4b9e0": "ZCode", "d443a47995": "Prime Agent", "mimo_code_label": "MiMo Code" }, diff --git a/src/renderer/src/i18n/locales/ja.json b/src/renderer/src/i18n/locales/ja.json index 0a3b2ee6c867..5f61e56bc51e 100644 --- a/src/renderer/src/i18n/locales/ja.json +++ b/src/renderer/src/i18n/locales/ja.json @@ -354,6 +354,7 @@ "fc80296033": "Devin", "da41abbdd4": "Ante", "060d152fb5": "Trae", + "e6fdf4b9e0": "ZCode", "d443a47995": "Prime Agent", "mimo_code_label": "MiMo Code" }, diff --git a/src/renderer/src/i18n/locales/ko.json b/src/renderer/src/i18n/locales/ko.json index 91aa9d8d74bb..b59b408cf594 100644 --- a/src/renderer/src/i18n/locales/ko.json +++ b/src/renderer/src/i18n/locales/ko.json @@ -357,6 +357,7 @@ "fc80296033": "Devin", "da41abbdd4": "Ante", "060d152fb5": "Trae", + "e6fdf4b9e0": "ZCode", "d443a47995": "Prime Agent", "mimo_code_label": "MiMo Code" }, diff --git a/src/renderer/src/i18n/locales/zh.json b/src/renderer/src/i18n/locales/zh.json index f460f007b2cd..0ff49f17951a 100644 --- a/src/renderer/src/i18n/locales/zh.json +++ b/src/renderer/src/i18n/locales/zh.json @@ -357,6 +357,7 @@ "fc80296033": "Devin", "da41abbdd4": "Ante", "060d152fb5": "Trae", + "e6fdf4b9e0": "ZCode", "d443a47995": "Prime Agent", "mimo_code_label": "MiMo Code" }, diff --git a/src/renderer/src/lib/agent-catalog.tsx b/src/renderer/src/lib/agent-catalog.tsx index 8217517ad8be..a175746e9055 100644 --- a/src/renderer/src/lib/agent-catalog.tsx +++ b/src/renderer/src/lib/agent-catalog.tsx @@ -120,6 +120,13 @@ export const getAgentCatalog = createLocalizedCatalog((): AgentCatalogEntry[] => faviconDomain: 'www.trae.cn', homepageUrl: 'https://docs.trae.cn/cli_get-started-with-trae-cli' }, + { + id: 'zcode', + label: translate('auto.lib.agent.catalog.e6fdf4b9e0', 'ZCode'), + cmd: 'zcode', + faviconDomain: 'z.ai', + homepageUrl: 'https://zcode.z.ai' + }, { id: 'pi', label: translate('auto.lib.agent.catalog.302934c5d9', 'Pi'), diff --git a/src/renderer/src/lib/agent-favicon-assets.ts b/src/renderer/src/lib/agent-favicon-assets.ts index 565437f75bef..13a8bbca8622 100644 --- a/src/renderer/src/lib/agent-favicon-assets.ts +++ b/src/renderer/src/lib/agent-favicon-assets.ts @@ -3,6 +3,7 @@ import grokUrl from '../../../shared/agent-icons/grok.png?url' import mimoCodeUrl from '../../../shared/agent-icons/mimo-code.png?url' import anteUrl from '../../../shared/agent-icons/ante.png?url' import traeUrl from '../../../shared/agent-icons/trae.png?url' +import zcodeUrl from '../../../shared/agent-icons/zcode.png?url' import primeAgentUrl from '../../../shared/agent-icons/prime-agent.png?url' import geminiUrl from '../../../shared/agent-icons/gemini.png?url' import antigravityUrl from '../../../shared/agent-icons/antigravity.png?url' @@ -37,6 +38,7 @@ export const AGENT_FAVICON_ASSETS: Partial> = { 'mimo-code': mimoCodeUrl, ante: anteUrl, trae: traeUrl, + zcode: zcodeUrl, 'prime-agent': primeAgentUrl, gemini: geminiUrl, antigravity: antigravityUrl, diff --git a/src/renderer/src/lib/agent-status.test.ts b/src/renderer/src/lib/agent-status.test.ts index 8bd1314d5774..333f9e1a2c84 100644 --- a/src/renderer/src/lib/agent-status.test.ts +++ b/src/renderer/src/lib/agent-status.test.ts @@ -866,6 +866,10 @@ describe('formatAgentTypeLabel', () => { expect(formatAgentTypeLabel('trae')).toBe('Trae') }) + it("maps 'zcode' to 'ZCode'", () => { + expect(formatAgentTypeLabel('zcode')).toBe('ZCode') + }) + it("maps 'prime-agent' to 'Prime Agent'", () => { expect(formatAgentTypeLabel('prime-agent')).toBe('Prime Agent') }) @@ -895,6 +899,7 @@ describe('agentTypeToIconAgent', () => { expect(agentTypeToIconAgent('command-code')).toBe('command-code') expect(agentTypeToIconAgent('ante')).toBe('ante') expect(agentTypeToIconAgent('trae')).toBe('trae') + expect(agentTypeToIconAgent('zcode')).toBe('zcode') expect(agentTypeToIconAgent('prime-agent')).toBe('prime-agent') }) diff --git a/src/renderer/src/lib/agent-status.ts b/src/renderer/src/lib/agent-status.ts index 3af7b38def92..d6b00492f234 100644 --- a/src/renderer/src/lib/agent-status.ts +++ b/src/renderer/src/lib/agent-status.ts @@ -134,7 +134,8 @@ const ICONABLE_AGENT_TYPES: Record = { grok: true, devin: true, ante: true, - trae: true + trae: true, + zcode: true } // Why: return null (not a 'claude' fallback) for unknown so Codex panes don't flash the Claude icon before the hook fires. diff --git a/src/renderer/src/lib/tui-agent-startup.test.ts b/src/renderer/src/lib/tui-agent-startup.test.ts index 422d7a8f6b44..89a9d4ca454d 100644 --- a/src/renderer/src/lib/tui-agent-startup.test.ts +++ b/src/renderer/src/lib/tui-agent-startup.test.ts @@ -144,6 +144,23 @@ describe('buildAgentStartupPlan', () => { ).toBe("traecli -- 'help me name this config'") }) + it('launches ZCode bare and injects the draft prompt after startup', () => { + expect( + buildAgentStartupPlan({ + agent: 'zcode', + prompt: 'Summarize the failing tests', + cmdOverrides: {}, + platform: 'linux' + }) + ).toEqual({ + agent: 'zcode', + launchCommand: 'zcode', + expectedProcess: 'zcode', + followupPrompt: 'Summarize the failing tests', + launchConfig: emptyLaunchConfig('zcode') + }) + }) + it('passes the prompt to Prime Agent as a positional argv behind a `--` separator', () => { expect( buildAgentStartupPlan({ diff --git a/src/shared/agent-headless-command.ts b/src/shared/agent-headless-command.ts index 9ff40e6af1d5..8b629e411262 100644 --- a/src/shared/agent-headless-command.ts +++ b/src/shared/agent-headless-command.ts @@ -4,15 +4,16 @@ import { isPrintModeHeadlessOneShotCommand } from './print-mode-headless-command import type { TuiAgent } from './tui-agent' // Why: a table (not an if-chain) so adding an agent is one entry; Claude and Trae share -// the same `--print` one-shot contract, Ante's `--prompt` form and Prime Agent's -// `--mode` forms need their own matchers. +// the same `--print` one-shot contract, Ante's and ZCode's `--prompt` form and Prime +// Agent's `--mode` forms need their own matchers. const HEADLESS_ONE_SHOT_MATCHERS: Partial< Record boolean> > = { claude: isPrintModeHeadlessOneShotCommand, trae: isPrintModeHeadlessOneShotCommand, 'prime-agent': isPrimeAgentHeadlessOneShotCommand, - ante: isAnteHeadlessOneShotCommand + ante: isAnteHeadlessOneShotCommand, + zcode: isAnteHeadlessOneShotCommand } export function isHeadlessOneShotAgentCommand(agent: TuiAgent, tokens: readonly string[]): boolean { diff --git a/src/shared/agent-icons/zcode.png b/src/shared/agent-icons/zcode.png new file mode 100644 index 000000000000..100269a57d26 Binary files /dev/null and b/src/shared/agent-icons/zcode.png differ diff --git a/src/shared/agent-kind.ts b/src/shared/agent-kind.ts index 8ca50cbcea64..f28845a0573d 100644 --- a/src/shared/agent-kind.ts +++ b/src/shared/agent-kind.ts @@ -50,7 +50,8 @@ const TUI_AGENT_KIND_BY_AGENT = { grok: 'grok', devin: 'devin', ante: 'ante', - trae: 'trae' + trae: 'trae', + zcode: 'zcode' } satisfies Record // Why: `satisfies Record` makes the lookup exhaustive at compile diff --git a/src/shared/agent-type-label.ts b/src/shared/agent-type-label.ts index 51f1695f5080..3d6d4a59c3c4 100644 --- a/src/shared/agent-type-label.ts +++ b/src/shared/agent-type-label.ts @@ -25,6 +25,7 @@ const WELL_KNOWN_LABELS: Record = { devin: 'Devin', ante: 'Ante', trae: 'Trae', + zcode: 'ZCode', kimi: 'Kimi' } diff --git a/src/shared/skills-cli-agent-keys.ts b/src/shared/skills-cli-agent-keys.ts index 7c49e0346cd0..7d0a9a5d679e 100644 --- a/src/shared/skills-cli-agent-keys.ts +++ b/src/shared/skills-cli-agent-keys.ts @@ -50,7 +50,8 @@ export const SKILLS_CLI_AGENT_KEY_BY_TUI_AGENT = { devin: 'devin', ante: null, // Why: Orca detects trae by `traecli`, an alias only TRAE CN ships. - trae: 'trae-cn' + trae: 'trae-cn', + zcode: 'zcode' } satisfies Record /** diff --git a/src/shared/telemetry-property-schemas.ts b/src/shared/telemetry-property-schemas.ts index 9d373903fdb6..2fd9e4d1767e 100644 --- a/src/shared/telemetry-property-schemas.ts +++ b/src/shared/telemetry-property-schemas.ts @@ -45,6 +45,7 @@ export const AGENT_KIND_VALUES = [ 'devin', 'ante', 'trae', + 'zcode', 'other' ] as const export const agentKindSchema = z.enum(AGENT_KIND_VALUES) diff --git a/src/shared/tui-agent-config.ts b/src/shared/tui-agent-config.ts index 46d382e7075f..64372230fd13 100644 --- a/src/shared/tui-agent-config.ts +++ b/src/shared/tui-agent-config.ts @@ -122,6 +122,12 @@ const TUI_AGENT_CONFIG_SOURCE: Record = { // Trae subcommand or flag — `--` stops both in its Cobra parser. argvPromptSeparator: '--' }, + zcode: { + detectCmd: 'zcode', + // Why: unknown positionals exit with `Unknown command` (no argv prompt form), so + // launch the bare TUI and paste the prompt once the composer is up. + promptInjectionMode: 'stdin-after-start' + }, opencode: { detectCmd: 'opencode', promptInjectionMode: 'flag-prompt', diff --git a/src/shared/tui-agent-display-names.ts b/src/shared/tui-agent-display-names.ts index 4c2576bddc89..ba1ee6c2c160 100644 --- a/src/shared/tui-agent-display-names.ts +++ b/src/shared/tui-agent-display-names.ts @@ -13,6 +13,7 @@ export const TUI_AGENT_DISPLAY_NAMES: Record = { devin: 'Devin', ante: 'Ante', trae: 'Trae', + zcode: 'ZCode', autohand: 'Autohand Code', opencode: 'OpenCode', opencode2: 'OpenCode 2', diff --git a/src/shared/tui-agent-permissions.ts b/src/shared/tui-agent-permissions.ts index c0808b41a3d6..7aa2c6b334a8 100644 --- a/src/shared/tui-agent-permissions.ts +++ b/src/shared/tui-agent-permissions.ts @@ -29,6 +29,8 @@ export const YOLO_TUI_AGENT_ARGS: Partial> = { devin: '--permission-mode bypass', ante: '--yolo', trae: '--yolo', + // Why: `--mode yolo` is ZCode's permission-bypass flag (`zcode --help`). + zcode: '--mode yolo', droid: '--auto high' } diff --git a/src/shared/tui-agent-selection.ts b/src/shared/tui-agent-selection.ts index 1de6301bd2fd..2bcb8dfafbd6 100644 --- a/src/shared/tui-agent-selection.ts +++ b/src/shared/tui-agent-selection.ts @@ -15,6 +15,7 @@ export const TUI_AGENT_AUTO_PICK_ORDER = [ 'mimo-code', 'ante', 'trae', + 'zcode', 'pi', 'omp', 'prime-agent', diff --git a/src/shared/tui-agent.ts b/src/shared/tui-agent.ts index b6901aa8ef15..34c2c2a822e8 100644 --- a/src/shared/tui-agent.ts +++ b/src/shared/tui-agent.ts @@ -37,4 +37,5 @@ export type TuiAgent = | 'devin' // Devin CLI | 'ante' // Ante (Antigma Labs) | 'trae' // Trae CLI + | 'zcode' // ZCode CLI | 'prime-agent' // Prime Agent (Prime Intellect)