Repository navigation
feat(agents): add Gajae Code as a supported TUI agent - #13952
nahyeongjin1 wants to merge 2 commits into
Conversation
📝 WalkthroughWalkthroughAdds Gajae Code as the 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
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. Comment |
9a7c8e5 to
6f1e200
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
|
Rebased onto The only conflict was Re-verified on the rebased branch (macOS arm64):
The pre-existing @brennanb2025 only |
Why this one, and the one field the other argv PRs missThere are now seven $ gjc --help
USAGE
$ gjc [COMMAND]
ARGUMENTS
MESSAGES Messages to send (prefix files with @)
$ script -q out.log gjc -- hi # real pty
→ inline TUI renders, the prompt is processed, the composer stays live
("Type your message...")
→ the session survives until I SIGKILL it at 45s; on teardown it prints
"Resume this session with: gjc --resume 01a0276d-…"Positional The /** 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];
}A worktree created with the prompt Field data for argv over stdin-after-start. gjc ships as a 134 MB single-file Mach-O. On a machine with an exec-hooking security agent, its first launch blocks in dyld before $ sample <pid>
1786 Thread: Main Thread
1786 _dyld_start (in dyld) + 0
→ dyld4::RuntimeState::notifyDebuggerLoad
→ dyld4::ExternallyViewableState::triggerNotifications
→ RemoteNotificationResponder::blockOnSynchronousEvent
→ mach_msg2_trap~60 s from exec to first paint (RSS 32 KB → 570 MB); warm start ~4 s. I've posted the same verification on #15025 with an offer to close this PR if that one adopts these two fields — it has the bundled icon and the telemetry coverage that mine deliberately skipped. Either registration is fine by me as long as the launch config is the one above; I'm not asking for a review race between seven duplicates. |
Why: tui-agent-config.ts sat at 297 of the 300 counted lines oxlint allows for `src/**/*.ts`, so registering any further agent trips max-lines before the entry is even written. The per-agent table now has 27 lines of headroom. Type-only move — no behavior change. Consumers import from the new module directly rather than through a re-export, per stablyai#14447. Co-Authored-By: Claude <noreply@anthropic.com>
Register the `gjc` CLI (https://gajae-code.com, npm `gajae-code`) in the desktop and mobile agent catalogs following the Trae/Prime Agent registration pattern. Every field was verified against the installed CLI and its source rather than assumed from the Pi lineage it forked: - `expectedProcess: 'gjc'` — it ships as a compiled single-file binary (Mach-O/ELF), so the foreground process carries its own name. Unlike Pi and Prime Agent there is no Node/Bun shim launching a generic `cli.js`, so no entrypoint identity is needed in `agent-node-entrypoint-identities.ts`. - `promptInjectionMode: 'argv'` with `argvPromptSeparator: '--'` — its help documents `gjc [prompt]`, and its arg parser skips a bare `--` while pushing every following non-flag token into `messages`. Without the separator a prompt of exactly `resume` takes the `gjc resume` launch alias, and `stats`/`models` dispatch as subcommands. - No `windowsShiftEnterEncoding` — this is where it diverges from Pi. `interactive-mode.ts` binds newline to `alt+enter`/`ctrl+j` on win32 instead of `shift+enter`, so the default Esc+CR path is already the encoding it expects and a `csi-u` override would be wrong. - No `faviconDomain` — gajae-code.com serves an inline data-URI favicon, so Google's favicon service returns 404 with its generic globe placeholder. The `AgentLetterIcon` fallback is the honest icon, same reasoning already recorded for OMP. - `skills-cli-agent-keys`: `null`, following the file's stated rule that an unconfirmed key is dropped rather than guessed. Scope is registration only. Pi-style status hooks, prefill, and AI Vault session history are deliberately left out of this PR. Co-Authored-By: Claude <noreply@anthropic.com>
6f1e200 to
2f92c36
Compare
|
Follow-up to the rebase above: it surfaced a blocker that is worth flagging on its own, so the PR is now two commits and the description has been rewritten around it.
Full verification is in the updated description. Two notes on what is not green: 13 tests fail in four Happy to split the refactor into its own PR if you would rather review it separately — say the word and I will reorder. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/shared/tui-agent-config.ts (1)
120-132: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winShorten the
gjcconfiguration comments.These comments restate configured fields and explain the default Windows behavior. Remove the
expectedProcessand default-encoding rationale. Keep one short comment forargvPromptSeparator.Proposed reduction
expectedProcess: 'gjc', promptInjectionMode: 'argv', - // Why: separator so a prompt that is exactly a subcommand word (`resume`, `stats`, - // `models`) or starts with `/` reaches the parser as message text instead of - // dispatching. Verified against its arg parser: a bare `--` is skipped and every - // following non-flag token lands in `messages`. + // Keep command-like prompts as positional messages. argvPromptSeparator: '--'As per coding guidelines, “Comments must be concise, non-obvious, and brief—prefer one line; do not explain obvious behavior or walk through code.”
Source: Coding guidelines
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: aa9330d8-9e44-4894-b769-f4df20512b6a
📥 Commits
Reviewing files that changed from the base of the PR and between 6f1e200e01383ef854f20c20e8c3fa0e41c7959f and 2f92c36.
📒 Files selected for processing (6)
src/renderer/src/lib/agent-draft-readiness.tssrc/shared/draft-paste-ready-scanner-grok-trace-replay.test.tssrc/shared/draft-paste-ready-scanner.tssrc/shared/tui-agent-config-types.tssrc/shared/tui-agent-config.tssrc/shared/tui-agent-detection-commands.ts
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.
What & Why
Registers the
gjcCLI (Gajae Code, npmgajae-code) as a supported TUI agent, following the Trae/Prime Agent registration pattern.ELI5: Orca can already run
gjcin a terminal, but it doesn't know what it is — no entry in the agent picker, no process attribution, no prompt injection when you create a worktree. This adds the one catalog entry that makes it a first-class agent like the other 36.Scope is registration only. Pi-style status hooks, prefill, and AI Vault session history are deliberately left out.
Two commits, and the first one is a prerequisite, not scope creep. On a rebase onto current
mainI found thatsrc/shared/tui-agent-config.tshad reached 297 of the 300 counted lines oxlint allows forsrc/**/*.ts. A minimal agent entry is 7 code lines (5 fields plus braces), sopnpm lintnow fails on any new agent registration, not just this one — andAGENTS.mdforbids amax-linesdisable.bdc9b61therefore moves the four type declarations (TuiAgentConfig,AgentPromptInjectionMode,DraftPasteReadySignal,TuiAgentDetectionRuntime) intosrc/shared/tui-agent-config-types.ts, leaving the per-agent table at 273/300. It is a type-only move with no behavior change, four import sites repointed at the real module rather than a re-export (per #14447), and it lands before the registration so no commit on this branch is lint-red.Field-by-field rationale
Gajae Code is a Pi fork, so the tempting move is to copy Pi's config. Every field was instead verified against the installed CLI and its source — and two of them turn out to differ from Pi:
expectedProcessgjcfile $(which gjc)→Mach-O 64-bit executable arm64), so the foreground process carries its own name. Unlike Pi and Prime Agent there is no Node/Bun shim launching a genericcli.js, so no entry is needed inagent-node-entrypoint-identities.ts.promptInjectionModeargvgjc --helpdocumentsgjc [prompt]with the examplegjc "List all .ts files in src/".argvPromptSeparator----and pushes every following non-flag token intomessages. Without the separator a prompt of exactlyresumetakes thegjc resumelaunch alias, andstats/modelsdispatch as subcommands.windowsShiftEnterEncodinginteractive-mode.tsbinds newline toalt+enter/ctrl+jon win32 rather thanshift+enter, so the default Esc+CR path is already what it expects; acsi-uoverride would be wrong here.faviconDomaindata:image/svg+xmlfavicon, sohttps://www.google.com/s2/favicons?domain=gajae-code.com&sz=64returns 404 with the generic globe placeholder. TheAgentLetterIconfallback is the honest icon — same reasoning already recorded for OMP.skills-cli-agent-keysnullI verified the separator behavior by running its parser directly rather than reading the help text:
Testing
Added to
src/renderer/src/lib/tui-agent-startup.test.ts, mirroring the existing Trae/Prime Agent cases:--resume) stays a promptRebased onto
mainat013eb53. The only conflict wassrc/shared/types.ts, deleted by #14447 (drop theshared/typesbarrel); theTuiAgentunion member moved to its new home insrc/shared/tui-agent.ts. The other fifteen files merged cleanly.Re-run on the rebased branch, macOS arm64:
pnpm typecheck(node + web)npx oxlintpnpm run audit:code-quality:nativepnpm run audit:code-quality:type-awarepnpm run check:reliability-gatespnpm run check:max-lines-ratchetpnpm run verify:localization-{catalog,extraction,coverage}pnpm run verify:bundled-skill-guides,verify:skill-bundle-manifestnpx oxfmt --checkon the touched filesvitest run --config config/vitest.config.ts src/shared src/rendererThe 13 failures are all in four
terminal-ime-xterm-*preedit-overlay suites. I ran those same four files on a clean013eb53checkout in the same environment and got an identical 13 failed / 9 passed, so they are environmental here and untouched by this PR. Theautomation-schedules.test.tslocale failure I reported in the original description is gone on currentmain, so it is no longer a caveat.pnpm testas a whole still could not run locally:ensure-native-runtime.mjscannot bind node-pty for Node 24.16.0 on this machine, so I invoked vitest directly againstconfig/vitest.config.ts. CI covers the native path.The i18n key
c851f042e2was not hand-computed — I confirmed it by runningnpx i18next-cli extract -c config/i18next.config.tsand diffing the generated catalog. Added to all five locale files (en/es/ja/ko/zh) with the untranslated product name, as done for Prime Agent.Mobile has no local
node_moduleshere (separate Expo workspace), so in place oftsc --noEmitandvitest runI asserted the invariants those checks enforce:TuiAgentunion,MOBILE_TUI_AGENT_LABELSkeys, andMOBILE_TUI_AGENT_AUTO_PICK_ORDERare all 37 with no missing or extra entries;mobile-agent-catalog.test.tsparsestui-agent-config.tsby regex forTUI_AGENT_CONFIG: Record<TuiAgent, TuiAgentConfig> = {…^}, which the type split could have broken — I ran that regex against the post-split file and it still yields all 37 keys, with mobile and desktop auto-pick order equal element-for-element andgjcat index 13 in both.Not touched: README's Supported Agents badge list — the Prime Agent registration (#12935) did not touch it either, and doing so would pull in five translated READMEs.
Review
gjcis the binary name on all three platforms, so nolaunchCmdByPlatform. The win32 newline divergence from Pi is called out above and is the reason thecsi-uoverride is intentionally absent.detectCmdpath; mobile registry updated in the same commit.agent-kind.tskeeps its'other'runtime fallback for stale persisted settings.bdc9b61moves types only — no value, function, or export shape changes, andTUI_AGENT_CONFIGitself stays intui-agent-config.tsso the mobile test's source regex andtui-agent-detection-commands.tsstill resolve it there. Reviewable as its own commit.Screenshots
N/A — no new UI. The agent picker renders the existing
AgentLetterIcon("G") through the unchanged catalog code path.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)AI Disclosure
Authored with Claude (Sonnet 4.5) via Gajae Code. All CLI-contract claims above were verified against the installed binary and its source; none were inferred from the model's prior knowledge.
The rebase, the type split, and the re-verification above were done with Claude Opus 5 in Claude Code. Every result in the tables was run, not predicted; the IME baseline was measured on a clean
maincheckout rather than assumed.