diff --git a/README.md b/README.md
index 5d75bcc89d32..d5320e51a889 100644
--- a/README.md
+++ b/README.md
@@ -184,6 +184,7 @@ Works with **any CLI agent** — if it runs in a terminal, it runs in Orca.
OpenClaude
Antigravity
Pi
+
Gajae Code
oh-my-pi
Hermes Agent
Devin
diff --git a/config/scripts/locale-translation-policy.mjs b/config/scripts/locale-translation-policy.mjs
index eb1a7ea0b925..ec34a1c61bee 100644
--- a/config/scripts/locale-translation-policy.mjs
+++ b/config/scripts/locale-translation-policy.mjs
@@ -43,6 +43,7 @@ export const NEVER_TRANSLATE_VALUES = new Set([
'Cursor',
'Droid',
'Devin',
+ 'Gajae Code',
'Gemini',
'Git',
'Git Bash',
diff --git a/mobile/src/components/mobile-agent-icon-assets.ts b/mobile/src/components/mobile-agent-icon-assets.ts
index 38a48373734b..12311c2edcd8 100644
--- a/mobile/src/components/mobile-agent-icon-assets.ts
+++ b/mobile/src/components/mobile-agent-icon-assets.ts
@@ -39,5 +39,6 @@ export const MOBILE_AGENT_ICON_ASSETS: Partial
faviconDomain: 'primeintellect.ai',
homepageUrl: 'https://github.com/PrimeIntellect-ai/prime-agent'
},
+ {
+ id: 'gjc',
+ label: translate('auto.lib.agent.catalog.c851f042e2', 'Gajae Code'),
+ cmd: 'gjc',
+ faviconDomain: 'gajae-code.com',
+ homepageUrl: 'https://gajae-code.com'
+ },
{
id: 'gemini',
label: translate('auto.lib.agent.catalog.12e6baa4f7', 'Gemini'),
diff --git a/src/renderer/src/lib/agent-favicon-assets.ts b/src/renderer/src/lib/agent-favicon-assets.ts
index 565437f75bef..04327137341d 100644
--- a/src/renderer/src/lib/agent-favicon-assets.ts
+++ b/src/renderer/src/lib/agent-favicon-assets.ts
@@ -24,6 +24,7 @@ import rovoUrl from '../../../shared/agent-icons/rovo.png?url'
import hermesUrl from '../../../shared/agent-icons/hermes.png?url'
import devinUrl from '../../../shared/agent-icons/devin.png?url'
import openclawUrl from '../../../shared/agent-icons/openclaw.png?url'
+import gjcUrl from '../../../shared/agent-icons/gjc.png?url'
// Why: these agents have no hand-authored SVG glyph, so previously their icons
// loaded live from Google's favicon service. That service is unreachable in some
@@ -57,5 +58,6 @@ export const AGENT_FAVICON_ASSETS: Partial> = {
rovo: rovoUrl,
hermes: hermesUrl,
devin: devinUrl,
- openclaw: openclawUrl
+ openclaw: openclawUrl,
+ gjc: gjcUrl
}
diff --git a/src/renderer/src/lib/agent-status.ts b/src/renderer/src/lib/agent-status.ts
index 94933a05bffa..5d6d75613c7c 100644
--- a/src/renderer/src/lib/agent-status.ts
+++ b/src/renderer/src/lib/agent-status.ts
@@ -108,6 +108,7 @@ const ICONABLE_AGENT_TYPES: Record = {
pi: true,
omp: true,
'prime-agent': true,
+ gjc: true,
gemini: true,
antigravity: true,
aider: true,
diff --git a/src/shared/agent-icons/gjc.png b/src/shared/agent-icons/gjc.png
new file mode 100644
index 000000000000..e96bf3506688
Binary files /dev/null and b/src/shared/agent-icons/gjc.png differ
diff --git a/src/shared/agent-kind.ts b/src/shared/agent-kind.ts
index 324a73f2cd89..a549efb047fe 100644
--- a/src/shared/agent-kind.ts
+++ b/src/shared/agent-kind.ts
@@ -24,6 +24,7 @@ const TUI_AGENT_KIND_BY_AGENT = {
pi: 'pi',
omp: 'omp',
'prime-agent': 'prime-agent',
+ gjc: 'gjc',
gemini: 'gemini',
antigravity: 'antigravity',
aider: 'aider',
diff --git a/src/shared/gjc-agent-registration.test.ts b/src/shared/gjc-agent-registration.test.ts
new file mode 100644
index 000000000000..0862c5b28654
--- /dev/null
+++ b/src/shared/gjc-agent-registration.test.ts
@@ -0,0 +1,39 @@
+import { describe, expect, it } from 'vitest'
+import { tuiAgentToAgentKind } from './agent-kind'
+import { SKILLS_CLI_AGENT_KEY_BY_TUI_AGENT } from './skills-cli-agent-keys'
+import { TUI_AGENT_DISPLAY_NAMES } from './tui-agent-display-names'
+import { getTuiAgentLaunchCommand, isTuiAgent, TUI_AGENT_CONFIG } from './tui-agent-config'
+import { TUI_AGENT_AUTO_PICK_ORDER } from './tui-agent-selection'
+
+// Why: Gajae Code launches as a plain interactive TUI on `gjc`, so the only thing
+// that can silently break it is a half-finished registration (union member with no
+// config, or a config the auto-pick order never reaches).
+describe('Gajae Code agent registration', () => {
+ it('detects and launches the published `gjc` binary', () => {
+ expect(isTuiAgent('gjc')).toBe(true)
+ const config = TUI_AGENT_CONFIG.gjc
+ expect(config.detectCmd).toBe('gjc')
+ expect(getTuiAgentLaunchCommand(config, 'darwin')).toBe('gjc')
+ expect(config.expectedProcess).toBe('gjc')
+ })
+
+ it('injects the launch prompt after startup instead of as argv', () => {
+ // Why: `gjc -p ` is its non-interactive print mode, and it exposes no
+ // prefill flag or env var, so argv/flag injection would exit the hosted session.
+ expect(TUI_AGENT_CONFIG.gjc.promptInjectionMode).toBe('stdin-after-start')
+ expect(TUI_AGENT_CONFIG.gjc.draftPromptFlag).toBeUndefined()
+ expect(TUI_AGENT_CONFIG.gjc.draftPromptEnvVar).toBeUndefined()
+ })
+
+ it('is selectable, labelled, and telemetry-mapped', () => {
+ expect(TUI_AGENT_DISPLAY_NAMES.gjc).toBe('Gajae Code')
+ expect(TUI_AGENT_AUTO_PICK_ORDER).toContain('gjc')
+ expect(tuiAgentToAgentKind('gjc')).toBe('gjc')
+ })
+
+ it('claims no skills CLI agent key', () => {
+ // Why: the community skills CLI exits 1 on an unknown --agent value, and it has
+ // no gjc key; Gajae Code reads its own .gjc roots plus shared .agents/skills.
+ expect(SKILLS_CLI_AGENT_KEY_BY_TUI_AGENT.gjc).toBeNull()
+ })
+})
diff --git a/src/shared/skills-cli-agent-keys.ts b/src/shared/skills-cli-agent-keys.ts
index 3126c0a81e5f..5e0406ee16f5 100644
--- a/src/shared/skills-cli-agent-keys.ts
+++ b/src/shared/skills-cli-agent-keys.ts
@@ -23,6 +23,8 @@ export const SKILLS_CLI_AGENT_KEY_BY_TUI_AGENT = {
pi: 'pi',
omp: null,
'prime-agent': null,
+ // Why: the skills CLI has no gjc key; Gajae Code reads its own .gjc roots plus shared .agents/skills.
+ gjc: null,
gemini: 'gemini-cli',
antigravity: 'antigravity',
aider: null,
diff --git a/src/shared/telemetry-events.ts b/src/shared/telemetry-events.ts
index f6bbea3c755f..bf87ccdd555a 100644
--- a/src/shared/telemetry-events.ts
+++ b/src/shared/telemetry-events.ts
@@ -100,6 +100,7 @@ export const AGENT_KIND_VALUES = [
'devin',
'ante',
'trae',
+ 'gjc',
'other'
] as const
export const agentKindSchema = z.enum(AGENT_KIND_VALUES)
diff --git a/src/shared/tui-agent-config-table.ts b/src/shared/tui-agent-config-table.ts
new file mode 100644
index 000000000000..b96d8db9a722
--- /dev/null
+++ b/src/shared/tui-agent-config-table.ts
@@ -0,0 +1,300 @@
+// Why: split out of tui-agent-config.ts so the launch table can keep growing with
+// new agents without pushing that module past the 300-line lint ceiling; the types
+// and helpers live beside it in ./tui-agent-config.
+import { getOrcaCliCommandNameForPlatform } from './orca-cli-command-name'
+import type { TuiAgent } from './tui-agent'
+import type { TuiAgentConfig } from './tui-agent-config'
+
+export const TUI_AGENT_CONFIG: Record = {
+ claude: {
+ detectCmd: 'claude',
+ launchCmd: 'claude',
+ expectedProcess: 'claude',
+ promptInjectionMode: 'argv',
+ // Why: `claude --prefill ` seeds the input without submitting, avoiding the paste-after-ready race (PR https://github.com/stablyai/orca/pull/926).
+ draftPromptFlag: '--prefill'
+ },
+ 'claude-agent-teams': {
+ // Why: an Orca-provided launch mode, not a separate binary; detection follows the Orca CLI.
+ detectCmd: 'orca',
+ detectCmdAliases: ['orca-dev', 'orca-ide'],
+ // Why: require Claude too so fresh installs (Orca shim always present) don't report Agent Teams without an agent CLI.
+ detectRequiredCommands: ['claude'],
+ // Why: Windows/WSL use Claude's in-process Agent Teams fallback, not this Orca native-pane/tmux-shim wrapper.
+ detectUnsupportedRuntimes: ['win32', 'wsl'],
+ launchCmd: 'orca claude-teams',
+ launchCmdByPlatform: {
+ linux: `${getOrcaCliCommandNameForPlatform('linux')} claude-teams`,
+ win32: `${getOrcaCliCommandNameForPlatform('win32')} claude-teams`
+ },
+ expectedProcess: 'claude',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ openclaude: {
+ detectCmd: 'openclaude',
+ launchCmd: 'openclaude',
+ expectedProcess: 'openclaude',
+ promptInjectionMode: 'argv',
+ draftPromptFlag: '--prefill'
+ },
+ codex: {
+ detectCmd: 'codex',
+ launchCmd: 'codex',
+ expectedProcess: 'codex',
+ promptInjectionMode: 'argv',
+ windowsInputRecordPasteNewline: 'alt-enter',
+ preflightTrust: 'codex',
+ draftPasteReadySignal: 'codex-composer-prompt',
+ draftPasteReadyTimeoutMs: 20_000
+ },
+ autohand: {
+ detectCmd: 'autohand',
+ launchCmd: 'autohand',
+ expectedProcess: 'autohand',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ ante: {
+ detectCmd: 'ante',
+ launchCmd: 'ante',
+ expectedProcess: 'ante',
+ // Why: `ante --prompt` is headless (runs once and exits), so launch the bare TUI and inject after startup.
+ promptInjectionMode: 'stdin-after-start'
+ },
+ trae: {
+ // Why: the unrelated open-source bytedance/trae-agent also installs a `trae-cli`
+ // binary, so detect TRAE CN's CLI on `traecli`, an alias only TRAE CN ships.
+ detectCmd: 'traecli',
+ launchCmd: 'traecli',
+ expectedProcess: 'traecli',
+ // Why: `traecli [prompt]` takes the task as a positional argv, same as Claude/Codex.
+ promptInjectionMode: 'argv',
+ // Why: separator so prompts starting with `help`/`config`/`-…` aren't parsed as a
+ // Trae subcommand or flag — `--` stops both in its Cobra parser.
+ argvPromptSeparator: '--'
+ },
+ opencode: {
+ detectCmd: 'opencode',
+ launchCmd: 'opencode',
+ expectedProcess: 'opencode',
+ promptInjectionMode: 'flag-prompt',
+ // Why: opencode enables bracketed paste before its composer mounts; wait for the post-\x1b[?2004h show-cursor so paste lands.
+ draftPasteReadySignal: 'render-cursor-after-bracketed-paste'
+ },
+ 'mimo-code': {
+ detectCmd: 'mimo',
+ launchCmd: 'mimo',
+ expectedProcess: 'mimo',
+ promptInjectionMode: 'flag-prompt',
+ // Why: mirrors opencode's cursor-gated signal by parity; mimo's startup stream isn't separately validated.
+ draftPasteReadySignal: 'render-cursor-after-bracketed-paste'
+ },
+ pi: {
+ detectCmd: 'pi',
+ launchCmd: 'pi',
+ expectedProcess: 'pi',
+ promptInjectionMode: 'argv',
+ // Why: pi has no `--prefill` and paste-after-ready races its long startup; the orca-prefill extension seeds this env var instead.
+ draftPromptEnvVar: 'ORCA_PI_PREFILL',
+ // Why: Pi decodes CSI-u; Esc+CR submits after tool subprocesses reset live KKP state (#9703).
+ windowsShiftEnterEncoding: 'csi-u'
+ },
+ omp: {
+ detectCmd: 'omp',
+ launchCmd: 'omp',
+ expectedProcess: 'omp',
+ promptInjectionMode: 'argv',
+ draftPromptEnvVar: 'ORCA_OMP_PREFILL'
+ },
+ 'prime-agent': {
+ detectCmd: 'prime-agent',
+ launchCmd: 'prime-agent',
+ expectedProcess: 'prime-agent',
+ // Why: `prime-agent [options] [@files...] [message...]` takes the task as positional argv.
+ promptInjectionMode: 'argv',
+ // Why: separator so prompts starting with `help`/`agents`/`-…` aren't parsed as a
+ // subcommand or flag — its help documents `--` as "treat all following arguments as messages".
+ argvPromptSeparator: '--',
+ // Why: Prime Agent embeds Pi's TUI and decodes CSI-u the same way (see pi above).
+ windowsShiftEnterEncoding: 'csi-u'
+ },
+ gjc: {
+ detectCmd: 'gjc',
+ launchCmd: 'gjc',
+ expectedProcess: 'gjc',
+ // Why: `gjc -p ` is its non-interactive print mode (processes and exits), so
+ // launch the bare TUI and inject after startup instead of passing the task as argv.
+ promptInjectionMode: 'stdin-after-start'
+ },
+ gemini: {
+ detectCmd: 'gemini',
+ launchCmd: 'gemini',
+ expectedProcess: 'gemini',
+ promptInjectionMode: 'flag-prompt-interactive'
+ },
+ antigravity: {
+ detectCmd: 'agy',
+ launchCmd: 'agy',
+ expectedProcess: 'agy',
+ promptInjectionMode: 'flag-prompt-interactive'
+ },
+ aider: {
+ detectCmd: 'aider',
+ launchCmd: 'aider',
+ expectedProcess: 'aider',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ goose: {
+ detectCmd: 'goose',
+ launchCmd: 'goose',
+ expectedProcess: 'goose',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ amp: {
+ detectCmd: 'amp',
+ launchCmd: 'amp',
+ expectedProcess: 'amp',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ kilo: {
+ detectCmd: 'kilo',
+ launchCmd: 'kilo',
+ expectedProcess: 'kilo',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ kiro: {
+ // Why: the Kiro installer (https://cli.kiro.dev/install) ships `kiro-cli`, not `kiro`; keep id 'kiro' for stored prefs.
+ detectCmd: 'kiro-cli',
+ // Why: trust flags like --trust-all-tools attach to Kiro's `chat` subcommand, not top-level kiro-cli.
+ launchCmd: 'kiro-cli chat --tui',
+ expectedProcess: 'kiro-cli',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ crush: {
+ detectCmd: 'crush',
+ launchCmd: 'crush',
+ expectedProcess: 'crush',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ aug: {
+ // Why: @augmentcode/auggie installs a binary named `auggie`, not `aug`; keep id 'aug' for stored prefs.
+ detectCmd: 'auggie',
+ launchCmd: 'auggie',
+ expectedProcess: 'auggie',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ cline: {
+ detectCmd: 'cline',
+ launchCmd: 'cline',
+ expectedProcess: 'cline',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ codebuff: {
+ detectCmd: 'codebuff',
+ launchCmd: 'codebuff',
+ expectedProcess: 'codebuff',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ 'command-code': {
+ // Why: use the full name (not its `cmd` alias) so detection doesn't collide with Windows' built-in cmd.exe.
+ detectCmd: 'command-code',
+ // Why: `--trust` skips the first-run trust prompt so it doesn't consume the task text.
+ launchCmd: 'command-code --trust',
+ expectedProcess: 'command-code',
+ promptInjectionMode: 'argv'
+ },
+ continue: {
+ // Why: Continue's CLI binary is `cn`; `continue` is a bash/zsh builtin and would resolve to the shell keyword.
+ detectCmd: 'cn',
+ launchCmd: 'cn',
+ expectedProcess: 'cn',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ cursor: {
+ detectCmd: 'cursor-agent',
+ launchCmd: 'cursor-agent',
+ expectedProcess: 'cursor-agent',
+ promptInjectionMode: 'argv',
+ // Why: first-launch trust menu swallows the bracketed paste; pre-write the .workspace-trusted marker so it skips (agent-trust-presets.ts).
+ preflightTrust: 'cursor'
+ },
+ droid: {
+ detectCmd: 'droid',
+ launchCmd: 'droid',
+ expectedProcess: 'droid',
+ promptInjectionMode: 'argv',
+ // Why: Droid decodes CSI-u on Windows; the legacy Esc+CR fallback reads as Enter and submits instead of newline.
+ windowsShiftEnterEncoding: 'csi-u',
+ ctrlEnterEncoding: 'csi-u'
+ },
+ kimi: {
+ detectCmd: 'kimi',
+ launchCmd: 'kimi',
+ expectedProcess: 'kimi',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ 'mistral-vibe': {
+ // Why: installer exposes binary `vibe` though the package is mistral-vibe; keep old name as alias for wrapped installs.
+ detectCmd: 'vibe',
+ detectCmdAliases: ['mistral-vibe'],
+ launchCmd: 'vibe',
+ expectedProcess: 'vibe',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ 'qwen-code': {
+ // Why: package is qwen-code but its installed CLI binary on PATH is `qwen`.
+ detectCmd: 'qwen',
+ launchCmd: 'qwen',
+ expectedProcess: 'qwen',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ rovo: {
+ detectCmd: 'rovo',
+ launchCmd: 'rovo',
+ expectedProcess: 'rovo',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ hermes: {
+ detectCmd: 'hermes',
+ // Why: bare `hermes` opens the classic REPL; `--tui` starts the full-screen agent UI Orca hosts.
+ launchCmd: 'hermes --tui',
+ expectedProcess: 'hermes',
+ // Why: Hermes delivers the prompt via its startup-query contract, submitting only after the composer is ready.
+ promptInjectionMode: 'hermes-query'
+ },
+ openclaw: {
+ detectCmd: 'openclaw',
+ launchCmd: 'openclaw',
+ expectedProcess: 'openclaw',
+ promptInjectionMode: 'stdin-after-start'
+ },
+ copilot: {
+ detectCmd: 'copilot',
+ launchCmd: 'copilot',
+ expectedProcess: 'copilot',
+ // Why: `--prompt` exits on completion (kills the hosted session); `-i/--interactive` keeps it interactive.
+ promptInjectionMode: 'flag-interactive',
+ // Why: first-launch trust menu swallows the bracketed paste; pre-write trust so it skips (see agent-trust-presets.ts).
+ preflightTrust: 'copilot'
+ },
+ grok: {
+ detectCmd: 'grok',
+ launchCmd: 'grok',
+ expectedProcess: 'grok',
+ // Why: argv (grok takes a positional prompt) so multi-line/special-char text isn't mangled as raw PTY keystrokes.
+ promptInjectionMode: 'argv',
+ // Why: separator so prompts like `help`/`--version` aren't parsed as Grok CLI syntax.
+ argvPromptSeparator: '--',
+ // Why: grok shimmers its startup logo until the session opens, so the quiet
+ // window never settles and launch drafts waited out the full 8s hard
+ // timeout; its composer glyph lands ~0.6s in.
+ draftPasteReadySignal: 'grok-composer-prompt',
+ ctrlEnterEncoding: 'csi-u'
+ },
+ devin: {
+ detectCmd: 'devin',
+ launchCmd: 'devin',
+ expectedProcess: 'devin',
+ // Why: `devin -- ` auto-submits immediately (docs.devin.ai/cli), so start the REPL with no argv prompt.
+ promptInjectionMode: 'stdin-after-start'
+ }
+}
diff --git a/src/shared/tui-agent-config.ts b/src/shared/tui-agent-config.ts
index 78772924c4ce..10cd18728e5c 100644
--- a/src/shared/tui-agent-config.ts
+++ b/src/shared/tui-agent-config.ts
@@ -1,5 +1,4 @@
import type { TuiAgent } from './tui-agent'
-import { getOrcaCliCommandNameForPlatform } from './orca-cli-command-name'
export type AgentPromptInjectionMode =
| 'argv'
@@ -50,291 +49,11 @@ export type TuiAgentConfig = {
ctrlEnterEncoding?: 'csi-u'
}
-export const TUI_AGENT_CONFIG: Record = {
- claude: {
- detectCmd: 'claude',
- launchCmd: 'claude',
- expectedProcess: 'claude',
- promptInjectionMode: 'argv',
- // Why: `claude --prefill ` seeds the input without submitting, avoiding the paste-after-ready race (PR https://github.com/stablyai/orca/pull/926).
- draftPromptFlag: '--prefill'
- },
- 'claude-agent-teams': {
- // Why: an Orca-provided launch mode, not a separate binary; detection follows the Orca CLI.
- detectCmd: 'orca',
- detectCmdAliases: ['orca-dev', 'orca-ide'],
- // Why: require Claude too so fresh installs (Orca shim always present) don't report Agent Teams without an agent CLI.
- detectRequiredCommands: ['claude'],
- // Why: Windows/WSL use Claude's in-process Agent Teams fallback, not this Orca native-pane/tmux-shim wrapper.
- detectUnsupportedRuntimes: ['win32', 'wsl'],
- launchCmd: 'orca claude-teams',
- launchCmdByPlatform: {
- linux: `${getOrcaCliCommandNameForPlatform('linux')} claude-teams`,
- win32: `${getOrcaCliCommandNameForPlatform('win32')} claude-teams`
- },
- expectedProcess: 'claude',
- promptInjectionMode: 'stdin-after-start'
- },
- openclaude: {
- detectCmd: 'openclaude',
- launchCmd: 'openclaude',
- expectedProcess: 'openclaude',
- promptInjectionMode: 'argv',
- draftPromptFlag: '--prefill'
- },
- codex: {
- detectCmd: 'codex',
- launchCmd: 'codex',
- expectedProcess: 'codex',
- promptInjectionMode: 'argv',
- windowsInputRecordPasteNewline: 'alt-enter',
- preflightTrust: 'codex',
- draftPasteReadySignal: 'codex-composer-prompt',
- draftPasteReadyTimeoutMs: 20_000
- },
- autohand: {
- detectCmd: 'autohand',
- launchCmd: 'autohand',
- expectedProcess: 'autohand',
- promptInjectionMode: 'stdin-after-start'
- },
- ante: {
- detectCmd: 'ante',
- launchCmd: 'ante',
- expectedProcess: 'ante',
- // Why: `ante --prompt` is headless (runs once and exits), so launch the bare TUI and inject after startup.
- promptInjectionMode: 'stdin-after-start'
- },
- trae: {
- // Why: the unrelated open-source bytedance/trae-agent also installs a `trae-cli`
- // binary, so detect TRAE CN's CLI on `traecli`, an alias only TRAE CN ships.
- detectCmd: 'traecli',
- launchCmd: 'traecli',
- expectedProcess: 'traecli',
- // Why: `traecli [prompt]` takes the task as a positional argv, same as Claude/Codex.
- promptInjectionMode: 'argv',
- // Why: separator so prompts starting with `help`/`config`/`-…` aren't parsed as a
- // Trae subcommand or flag — `--` stops both in its Cobra parser.
- argvPromptSeparator: '--'
- },
- opencode: {
- detectCmd: 'opencode',
- launchCmd: 'opencode',
- expectedProcess: 'opencode',
- promptInjectionMode: 'flag-prompt',
- // Why: opencode enables bracketed paste before its composer mounts; wait for the post-\x1b[?2004h show-cursor so paste lands.
- draftPasteReadySignal: 'render-cursor-after-bracketed-paste'
- },
- 'mimo-code': {
- detectCmd: 'mimo',
- launchCmd: 'mimo',
- expectedProcess: 'mimo',
- promptInjectionMode: 'flag-prompt',
- // Why: mirrors opencode's cursor-gated signal by parity; mimo's startup stream isn't separately validated.
- draftPasteReadySignal: 'render-cursor-after-bracketed-paste'
- },
- pi: {
- detectCmd: 'pi',
- launchCmd: 'pi',
- expectedProcess: 'pi',
- promptInjectionMode: 'argv',
- // Why: pi has no `--prefill` and paste-after-ready races its long startup; the orca-prefill extension seeds this env var instead.
- draftPromptEnvVar: 'ORCA_PI_PREFILL',
- // Why: Pi decodes CSI-u; Esc+CR submits after tool subprocesses reset live KKP state (#9703).
- windowsShiftEnterEncoding: 'csi-u'
- },
- omp: {
- detectCmd: 'omp',
- launchCmd: 'omp',
- expectedProcess: 'omp',
- promptInjectionMode: 'argv',
- draftPromptEnvVar: 'ORCA_OMP_PREFILL'
- },
- 'prime-agent': {
- detectCmd: 'prime-agent',
- launchCmd: 'prime-agent',
- expectedProcess: 'prime-agent',
- // Why: `prime-agent [options] [@files...] [message...]` takes the task as positional argv.
- promptInjectionMode: 'argv',
- // Why: separator so prompts starting with `help`/`agents`/`-…` aren't parsed as a
- // subcommand or flag — its help documents `--` as "treat all following arguments as messages".
- argvPromptSeparator: '--',
- // Why: Prime Agent embeds Pi's TUI and decodes CSI-u the same way (see pi above).
- windowsShiftEnterEncoding: 'csi-u'
- },
- gemini: {
- detectCmd: 'gemini',
- launchCmd: 'gemini',
- expectedProcess: 'gemini',
- promptInjectionMode: 'flag-prompt-interactive'
- },
- antigravity: {
- detectCmd: 'agy',
- launchCmd: 'agy',
- expectedProcess: 'agy',
- promptInjectionMode: 'flag-prompt-interactive'
- },
- aider: {
- detectCmd: 'aider',
- launchCmd: 'aider',
- expectedProcess: 'aider',
- promptInjectionMode: 'stdin-after-start'
- },
- goose: {
- detectCmd: 'goose',
- launchCmd: 'goose',
- expectedProcess: 'goose',
- promptInjectionMode: 'stdin-after-start'
- },
- amp: {
- detectCmd: 'amp',
- launchCmd: 'amp',
- expectedProcess: 'amp',
- promptInjectionMode: 'stdin-after-start'
- },
- kilo: {
- detectCmd: 'kilo',
- launchCmd: 'kilo',
- expectedProcess: 'kilo',
- promptInjectionMode: 'stdin-after-start'
- },
- kiro: {
- // Why: the Kiro installer (https://cli.kiro.dev/install) ships `kiro-cli`, not `kiro`; keep id 'kiro' for stored prefs.
- detectCmd: 'kiro-cli',
- // Why: trust flags like --trust-all-tools attach to Kiro's `chat` subcommand, not top-level kiro-cli.
- launchCmd: 'kiro-cli chat --tui',
- expectedProcess: 'kiro-cli',
- promptInjectionMode: 'stdin-after-start'
- },
- crush: {
- detectCmd: 'crush',
- launchCmd: 'crush',
- expectedProcess: 'crush',
- promptInjectionMode: 'stdin-after-start'
- },
- aug: {
- // Why: @augmentcode/auggie installs a binary named `auggie`, not `aug`; keep id 'aug' for stored prefs.
- detectCmd: 'auggie',
- launchCmd: 'auggie',
- expectedProcess: 'auggie',
- promptInjectionMode: 'stdin-after-start'
- },
- cline: {
- detectCmd: 'cline',
- launchCmd: 'cline',
- expectedProcess: 'cline',
- promptInjectionMode: 'stdin-after-start'
- },
- codebuff: {
- detectCmd: 'codebuff',
- launchCmd: 'codebuff',
- expectedProcess: 'codebuff',
- promptInjectionMode: 'stdin-after-start'
- },
- 'command-code': {
- // Why: use the full name (not its `cmd` alias) so detection doesn't collide with Windows' built-in cmd.exe.
- detectCmd: 'command-code',
- // Why: `--trust` skips the first-run trust prompt so it doesn't consume the task text.
- launchCmd: 'command-code --trust',
- expectedProcess: 'command-code',
- promptInjectionMode: 'argv'
- },
- continue: {
- // Why: Continue's CLI binary is `cn`; `continue` is a bash/zsh builtin and would resolve to the shell keyword.
- detectCmd: 'cn',
- launchCmd: 'cn',
- expectedProcess: 'cn',
- promptInjectionMode: 'stdin-after-start'
- },
- cursor: {
- detectCmd: 'cursor-agent',
- launchCmd: 'cursor-agent',
- expectedProcess: 'cursor-agent',
- promptInjectionMode: 'argv',
- // Why: first-launch trust menu swallows the bracketed paste; pre-write the .workspace-trusted marker so it skips (agent-trust-presets.ts).
- preflightTrust: 'cursor'
- },
- droid: {
- detectCmd: 'droid',
- launchCmd: 'droid',
- expectedProcess: 'droid',
- promptInjectionMode: 'argv',
- // Why: Droid decodes CSI-u on Windows; the legacy Esc+CR fallback reads as Enter and submits instead of newline.
- windowsShiftEnterEncoding: 'csi-u',
- ctrlEnterEncoding: 'csi-u'
- },
- kimi: {
- detectCmd: 'kimi',
- launchCmd: 'kimi',
- expectedProcess: 'kimi',
- promptInjectionMode: 'stdin-after-start'
- },
- 'mistral-vibe': {
- // Why: installer exposes binary `vibe` though the package is mistral-vibe; keep old name as alias for wrapped installs.
- detectCmd: 'vibe',
- detectCmdAliases: ['mistral-vibe'],
- launchCmd: 'vibe',
- expectedProcess: 'vibe',
- promptInjectionMode: 'stdin-after-start'
- },
- 'qwen-code': {
- // Why: package is qwen-code but its installed CLI binary on PATH is `qwen`.
- detectCmd: 'qwen',
- launchCmd: 'qwen',
- expectedProcess: 'qwen',
- promptInjectionMode: 'stdin-after-start'
- },
- rovo: {
- detectCmd: 'rovo',
- launchCmd: 'rovo',
- expectedProcess: 'rovo',
- promptInjectionMode: 'stdin-after-start'
- },
- hermes: {
- detectCmd: 'hermes',
- // Why: bare `hermes` opens the classic REPL; `--tui` starts the full-screen agent UI Orca hosts.
- launchCmd: 'hermes --tui',
- expectedProcess: 'hermes',
- // Why: Hermes delivers the prompt via its startup-query contract, submitting only after the composer is ready.
- promptInjectionMode: 'hermes-query'
- },
- openclaw: {
- detectCmd: 'openclaw',
- launchCmd: 'openclaw',
- expectedProcess: 'openclaw',
- promptInjectionMode: 'stdin-after-start'
- },
- copilot: {
- detectCmd: 'copilot',
- launchCmd: 'copilot',
- expectedProcess: 'copilot',
- // Why: `--prompt` exits on completion (kills the hosted session); `-i/--interactive` keeps it interactive.
- promptInjectionMode: 'flag-interactive',
- // Why: first-launch trust menu swallows the bracketed paste; pre-write trust so it skips (see agent-trust-presets.ts).
- preflightTrust: 'copilot'
- },
- grok: {
- detectCmd: 'grok',
- launchCmd: 'grok',
- expectedProcess: 'grok',
- // Why: argv (grok takes a positional prompt) so multi-line/special-char text isn't mangled as raw PTY keystrokes.
- promptInjectionMode: 'argv',
- // Why: separator so prompts like `help`/`--version` aren't parsed as Grok CLI syntax.
- argvPromptSeparator: '--',
- // Why: grok shimmers its startup logo until the session opens, so the quiet
- // window never settles and launch drafts waited out the full 8s hard
- // timeout; its composer glyph lands ~0.6s in.
- draftPasteReadySignal: 'grok-composer-prompt',
- ctrlEnterEncoding: 'csi-u'
- },
- devin: {
- detectCmd: 'devin',
- launchCmd: 'devin',
- expectedProcess: 'devin',
- // Why: `devin -- ` auto-submits immediately (docs.devin.ai/cli), so start the REPL with no argv prompt.
- promptInjectionMode: 'stdin-after-start'
- }
-}
+import { TUI_AGENT_CONFIG } from './tui-agent-config-table'
+
+// Re-export: the launch table moved to its own module; every existing importer of
+// `TUI_AGENT_CONFIG` from this path keeps working unchanged.
+export { TUI_AGENT_CONFIG }
export function isTuiAgent(value: unknown): value is TuiAgent {
return typeof value === 'string' && Object.hasOwn(TUI_AGENT_CONFIG, value)
diff --git a/src/shared/tui-agent-display-names.ts b/src/shared/tui-agent-display-names.ts
index 0b2078f0479c..3dfe9193496c 100644
--- a/src/shared/tui-agent-display-names.ts
+++ b/src/shared/tui-agent-display-names.ts
@@ -19,6 +19,7 @@ export const TUI_AGENT_DISPLAY_NAMES: Record = {
pi: 'Pi',
omp: 'OMP',
'prime-agent': 'Prime Agent',
+ gjc: 'Gajae Code',
gemini: 'Gemini',
antigravity: 'Antigravity',
aider: 'Aider',
diff --git a/src/shared/tui-agent-selection.ts b/src/shared/tui-agent-selection.ts
index 86216e589b82..42d809b98a3d 100644
--- a/src/shared/tui-agent-selection.ts
+++ b/src/shared/tui-agent-selection.ts
@@ -17,6 +17,7 @@ export const TUI_AGENT_AUTO_PICK_ORDER = [
'pi',
'omp',
'prime-agent',
+ 'gjc',
'gemini',
'antigravity',
'aider',
diff --git a/src/shared/tui-agent.ts b/src/shared/tui-agent.ts
index a885e3dd24cb..f3ca2f38ed6b 100644
--- a/src/shared/tui-agent.ts
+++ b/src/shared/tui-agent.ts
@@ -37,3 +37,4 @@ export type TuiAgent =
| 'ante' // Ante (Antigma Labs)
| 'trae' // Trae CLI
| 'prime-agent' // Prime Agent (Prime Intellect)
+ | 'gjc' // Gajae Code (gajae-code.com)