Skip to content

feat(agents): add Gajae Code to the built-in agent registry - #15025

Open
Yeachan-Heo wants to merge 1 commit into
stablyai:mainfrom
Yeachan-Heo:feat/gajae-code-agent
Open

Yeachan-Heo wants to merge 1 commit into
stablyai:mainfrom
Yeachan-Heo:feat/gajae-code-agent

Conversation

@Yeachan-Heo

Copy link
Copy Markdown

What this adds

Gajae Code (gjc) as a built-in agent: it shows up in the agent combobox, agent settings, auto-pick order, tab/status icons, and telemetry — no custom-command setup.

Gajae Code is a terminal coding agent that runs on the Claude/Codex/Gemini subscription you already pay for, and it is worktree-native (gjc --worktree), so Orca's one-worktree-per-agent model fits it exactly.

Files

File Why
src/shared/tui-agent.ts new 'gjc' union member
src/shared/tui-agent-config-table.ts new — the launch table, moved verbatim out of tui-agent-config.ts (see note below), plus the gjc entry
src/shared/tui-agent-config.ts keeps the types + helpers and re-exports TUI_AGENT_CONFIG, so no importer changes
src/shared/tui-agent-display-names.ts Gajae Code
src/shared/tui-agent-selection.ts auto-pick order
src/shared/agent-kind.ts, src/shared/telemetry-events.ts concrete gjc telemetry kind (the exhaustive-sync test requires it)
src/shared/skills-cli-agent-keys.ts null — the skills CLI has no gjc key, and it exits 1 on unknown --agent
src/renderer/src/lib/agent-catalog.tsx + i18n/locales/*.json + config/scripts/locale-translation-policy.mjs catalog entry, English-only label in all five locales, brand token added to NEVER_TRANSLATE_VALUES
src/renderer/src/lib/agent-status.ts ICONABLE_AGENT_TYPES
src/shared/agent-icons/gjc.png + agent-favicon-assets.ts + mobile/.../mobile-agent-icon-assets.ts bundled 64×64 icon (no favicon-service dependency, per #8451)
src/shared/gjc-agent-registration.test.ts new — tests below
README.md supported-agents badge row

Prompt injection is stdin-after-start on purpose. gjc -p <prompt> is its non-interactive print mode (processes and exits), and it exposes no --prefill-style flag or prefill env var, so argv/flag injection would kill the hosted session. No permission-bypass flag is set: gjc deliberately has none — its approval gates for shell and destructive edits stay in force. That means the global Yolo/Manual switch has nothing to write for it, which matches the other flagless agents.

The icon is our own artwork (Gajae Code's mascot from the project's MIT-licensed repo), downscaled to 64×64 to match the existing PNGs, so there is no third-party mark to license-check.

About the file split

Adding one agent pushed src/shared/tui-agent-config.ts from 297 to 303 counted lines, over the max-lines: 300 ceiling for src/shared/**. config/max-lines-baseline.txt says explicitly "only SHRINK. Do NOT add entries to get CI green — split the oversized file instead", so the table moved to its own module (tui-agent-config-table.ts, 300 lines incl. the new entry) with the types and helpers left in place and the table re-exported. The move is verbatim — git diff -M shows it as a rename plus the new entry. Happy to drop the split into a separate PR if you'd rather land it first.

QA evidence

Typechecks (all three projects):

$ pnpm run typecheck:web && pnpm run typecheck:node && pnpm run typecheck:cli
# clean, no output

The exhaustive maps caught two real omissions during this work (agent-status.ts ICONABLE_AGENT_TYPES, and the agent-kind ↔ AGENT_KIND_VALUES sync test), both fixed.

Tests — new registration suite plus every existing agent-registry suite:

$ pnpm vitest run --config config/vitest.config.ts \
    src/shared/gjc-agent-registration.test.ts src/shared/agent-kind.test.ts \
    src/shared/skills-cli-agent-keys.test.ts src/shared/tui-agent-startup.test.ts \
    src/renderer/src/lib/tui-agent-startup.test.ts src/renderer/src/lib/agent-status.test.ts \
    src/renderer/src/components/agent/AgentCombobox.test.tsx \
    src/renderer/src/components/tab-bar/tab-agent-launch-options.test.ts \
    src/shared/repro-8478-opencode-native-title-icon.test.ts

 Test Files  9 passed (9)
      Tests  260 passed (260)

Lint / gates touched by this change:

$ npx oxlint src/shared src/renderer/src/lib mobile/src/components
# clean

$ node config/scripts/check-max-lines-ratchet.mjs
max-lines ratchet OK — 191 grandfathered suppression(s), no new bypasses.

$ node config/scripts/verify-localization-catalog.mjs
Verified 12237 localization key references against en.json.
es.json coverage: 11811/13186 translated, 1375 missing.
... (ja/ko/zh same shape) ...

$ node config/scripts/verify-localization-extraction.mjs   # exit 0

The agent itself: gjc v0.13.3 installed from npm (@gajae-code/coding-agent), launches its TUI on bare gjc in a worktree cwd.

Platforms: tested on macOS (arm64). Not tested: Windows, Linux, or the mobile app build — the mobile change is one require() line in the existing icon map.

No new UI was designed, so there is no new screen to record: the entry renders through the existing catalog/combobox rows. Say the word if you still want a screen recording of the picker with the row present and I'll attach one.

Notes

  • Maintainer edits enabled — narrow, rename, or redesign freely.
  • If you'd rather this waited on a product discussion, close it and I'll open one instead.

Gajae Code (gjc) is a terminal coding agent that runs on an existing Claude/Codex
subscription. It launches as a plain interactive TUI in the worktree cwd, so it
only needed registry wiring: detection, display name, telemetry kind, icon, and
auto-pick order.

The launch table moved to src/shared/tui-agent-config-table.ts because one more
agent pushed tui-agent-config.ts past the 300-line ceiling; per AGENTS.md the file
is split instead of baselined, and the table is re-exported from the old path so no
importer changes.
@coderabbitai

coderabbitai Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: fcf2368b-45bd-487a-95d8-5b29c940214c

📥 Commits

Reviewing files that changed from the base of the PR and between 81d7f9b and 29cad73.

⛔ Files ignored due to path filters (1)
  • src/shared/agent-icons/gjc.png is excluded by !**/*.png
📒 Files selected for processing (20)
  • README.md
  • config/scripts/locale-translation-policy.mjs
  • mobile/src/components/mobile-agent-icon-assets.ts
  • src/renderer/src/i18n/locales/en.json
  • src/renderer/src/i18n/locales/es.json
  • src/renderer/src/i18n/locales/ja.json
  • src/renderer/src/i18n/locales/ko.json
  • src/renderer/src/i18n/locales/zh.json
  • src/renderer/src/lib/agent-catalog.tsx
  • src/renderer/src/lib/agent-favicon-assets.ts
  • src/renderer/src/lib/agent-status.ts
  • src/shared/agent-kind.ts
  • src/shared/gjc-agent-registration.test.ts
  • src/shared/skills-cli-agent-keys.ts
  • src/shared/telemetry-events.ts
  • src/shared/tui-agent-config-table.ts
  • src/shared/tui-agent-config.ts
  • src/shared/tui-agent-display-names.ts
  • src/shared/tui-agent-selection.ts
  • src/shared/tui-agent.ts

Included review availability: Your plan includes up to 10 reviews per rolling hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Added Gajae Code as the gjc TUI agent. The change defines its detection, launch, prompt injection, display, selection, telemetry, and Skills CLI mappings. It adds registration tests for these behaviors. The change also adds catalog metadata, localized labels, favicon assets, mobile icon assets, translation preservation, and README documentation. The shared TUI configuration table moved to a dedicated module while preserving its existing export path.

Merge Risk: 🔵 Low · up to 29cad

The PR adds Gajae Code as a built-in agent and enables prompt delivery through stdin after startup across desktop platforms. It is mergeable with explicit owner awareness, but Windows and Linux prompt-injection compatibility should be confirmed or guarded because only macOS arm64 validation is supplied.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the implementation and testing, but it omits the required Linked Issue section and several template checklist sections. Add the required Linked Issue with an issue reference, complete the template sections, and mark applicable checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: adding Gajae Code to the built-in agent registry.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nahyeongjin1

Copy link
Copy Markdown

Cross-posting verification, not a competing claim — I have the same registration open at #13952 and I'm happy to close it in favour of yours. Two fields would need to change first, and both are checkable against your own CLI.

1. promptInjectionMode. The description says argv/flag injection "would kill the hosted session" because gjc -p <prompt> is the non-interactive print mode. That holds for -p, but not for positional MESSAGES:

$ gjc --help
USAGE
  $ gjc [COMMAND]
ARGUMENTS
  MESSAGES   Messages to send (prefix files with @)

$ script -q out.log gjc -- hi        # real pty, gjc v0.14.2
→ inline TUI renders, the prompt is processed, the composer stays live
  ("Type your message..."), and the session is still alive when I SIGKILL it
  at 45s; on teardown it prints "Resume this session with: gjc --resume …"

Six of the seven open/closed gjc registrations landed on argv for this reason; #7805 verified it independently against v0.9.0.

2. argvPromptSeparator: '--' becomes required if you switch — normalizeResumeAlias in cli.ts maps a lone resume argument to --resume, so a prompt of exactly resume opens the session picker instead of being sent, and stats / models dispatch as subcommands:

/** Normalize the sole `gjc resume` alias into the value-less launch intent. */
export function normalizeResumeAlias(argv: readonly string[]): string[] {
  return argv.length === 1 && argv[0] === "resume" ? ["--resume"] : [...argv];
}

Why this matters in practice, not just in theory. gjc's 134 MB single-file binary can block in dyld for ~60 s before main on a first launch behind an exec-hooking security agent — sampled on macOS arm64:

$ sample <pid>
1786 Thread: Main Thread
  1786 _dyld_start (in dyld) + 0
  → dyld4::RuntimeState::notifyDebuggerLoad
  → RemoteNotificationResponder::blockOnSynchronousEvent
  → mach_msg2_trap

Orca's stdin-after-start delivery is gated by FOREGROUND_AGENT_WRAPPER_RETRY_TIMEOUT_MS (6.5 s) and DRAFT_PASTE_READY_TIMEOUT_MS (8 s), so on that cold start the worktree's initial prompt is silently dropped. argv can't lose it.

Everything else in yours is better than mine — the bundled 64×64 icon (mine falls back to AgentLetterIcon, since gajae-code.com serves a data: favicon and the s2 service 404s) and the telemetry/README coverage. Take these two fields and I'll close #13952, so @brennanb2025 isn't choosing between seven duplicates.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants