Skip to content

Add Gajae Code (gjc) agent integration - #9017

Open
jeongjin0 wants to merge 2 commits into
manaflow-ai:mainfrom
jeongjin0:feat/gajae-code-integration
Open

jeongjin0 wants to merge 2 commits into
manaflow-ai:mainfrom
jeongjin0:feat/gajae-code-integration

Conversation

@jeongjin0

@jeongjin0 jeongjin0 commented Jul 27, 2026 •

Copy link
Copy Markdown

Summary

  • add first-class gajae-code / gjc hook installation using Gajae Code's native TypeScript extension API
  • persist and restore GJC sessions, including session switch/branch rebinding and managed tmux identity
  • detect GJC processes in Task Manager and add safe launch argument/environment capture policies
  • document the integration, localize new CLI/task-manager strings, and wire end-to-end coverage into CI

Compatibility and scope

Validated against the locally installed GJC 0.10.0 and upstream Gajae Code 0.11.11 (0a18757555932a646b30ea99337fe42ffb016686). The extension uses the shared event surface present in both versions: session_start, session_switch, session_branch, before_agent_start, and agent_end.

GJC sub-sessions and team workers are intentionally ignored so they cannot overwrite the leader surface binding. This PR provides lifecycle/restore integration only; it does not add Feed approval cards or workspace auto-naming because GJC does not expose the required stable approval/conversation-source contracts yet.

Testing

  • swift test in Packages/macOS/CMUXAgentLaunch: 253 tests passed
  • python3 tests/test_gajae_code_extension_install.py: passed against the tagged app's bundled CLI
  • xcodebuild ... -scheme cmux-unit ... -only-testing:cmuxTests/TaskManagerResourcesTests: 22 tests passed
  • ./scripts/lint-pbxproj-test-wiring.sh: 602 test files checked
  • pbxproj normalization/check, JSON parse, git diff --check, and localization audit passed
  • CMUX_SKIP_ZIG_BUILD=1 ./scripts/reload.sh --tag gajae-code-integration: succeeded on pushed HEAD b4efe428c

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Adds first-class Gajae Code (gjc) integration with an installable TypeScript extension that persists/restores sessions and preserves tmux identity. Task Manager now detects gjc, and resume args/env are sanitized with safer defaults; CI covers the end-to-end flow.

  • New Features

    • cmux hooks gajae-code (alias: gjc) installs/uninstalls a native @gajae-code/coding-agent extension at ~/.gjc/agent/extensions/cmux-gajae-code-session.ts (respects GJC_CODING_AGENT_DIR or GJC_CONFIG_DIR).
    • Tracks session_start, session_switch, session_branch, before_agent_start, agent_end; on switch/branch we rebind the same surface and retire the prior record with address checks to avoid clobbering.
    • Safe relaunch: gjc --resume <id> with tmux-aware restore (--tmux, GJC_TMUX_SESSION); sanitizer preserves tmux flags and essential GJC_* config, and drops secrets, noninteractive flags, and team/worker identity.
    • Task Manager detects gjc processes and @gajae-code/coding-agent paths (incl. gjc.js/bun/node entry points); resume argv uses gjc --resume <id>.
    • Docs and localized CLI strings added; CI runs tests/test_gajae_code_extension_install.py. Validated against GJC 0.10.0 and Gajae Code 0.11.x.
  • Migration

    • Install: cmux hooks gajae-code install (or cmux hooks setup). Uninstall: cmux hooks gajae-code uninstall.
    • Configure location with GJC_CODING_AGENT_DIR (full agent dir) or GJC_CONFIG_DIR (config root). Disable via CMUX_GAJAE_CODE_HOOKS_DISABLED=1.

Written for commit 3ed7ef6. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added Gajae Code (gjc) integration with session hooks, restoration, environment handling, and process detection.
    • Added CLI support to install and remove the Gajae Code extension safely and idempotently.
    • Added localized user-facing messages for installation and hook lifecycle flows.
  • Documentation
    • Updated agent hooks docs with Gajae Code setup details, environment overrides, and troubleshooting guidance.
  • Bug Fixes
    • Improved session retirement/rebinding behavior when Gajae Code switches session IDs.
  • Tests
    • Added integration tests covering install/uninstall, hook persistence, event lifecycle, and argv/environment sanitization (plus expanded unit coverage).

@jeongjin0
jeongjin0 requested a review from lawrencecchen as a code owner July 27, 2026 23:52
@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds Gajae Code (gajae-code/gjc) support across cmux hook installation, session lifecycle persistence, launch detection, restore sanitization, localization, documentation, tests, and CI regression coverage.

Changes

Gajae Code support

Layer / File(s) Summary
Hook registration and installation
CLI/CMUXCLI+AgentHookCatalog.swift, CLI/CMUXCLI+GajaeCodeExtension.swift, CLI/cmux.swift, cmux.xcodeproj/project.pbxproj, Resources/Localizable.xcstrings
Registers Gajae Code and its gjc alias, generates and manages the native extension, wires installation and removal commands, and adds build and localization entries.
Session lifecycle and persistence
CLI/CMUXCLI+GajaeCodeExtension.swift, CLI/cmux.swift, tests/test_gajae_code_extension_install.py, docs/agent-hooks.md, .github/workflows/ci.yml
Forwards lifecycle events, handles previous-session rebinding and retirement, validates tmux restore persistence, documents integration behavior, and runs the new regression test in CI.
Launch recognition and restore policy
Packages/macOS/CMUXAgentLaunch/..., Sources/CmuxTaskManagerCodingAgentDefinition+BuiltIns.swift, cmuxTests/TaskManagerResourcesTests.swift
Adds Gajae Code process matching, safe environment keys, argument filtering, resume argv construction, coding-agent metadata, and unit tests for these behaviors.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GajaeCodeExtension
  participant CmuxCLI
  participant HookSessionStore
  participant SurfaceBinding
  GajaeCodeExtension->>CmuxCLI: Forward session lifecycle event
  CmuxCLI->>HookSessionStore: Accept session and retire previous record
  CmuxCLI->>SurfaceBinding: Set restore binding
  SurfaceBinding-->>GajaeCodeExtension: Retain launch and tmux metadata
Loading

Suggested reviewers: lawrencecchen


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Cmux Swift Package Boundaries ❌ Error The diff extends app-target Sources/TaskManagerTypes.swift/CLI/cmux.swift with reusable agent-catalog and session-retirement logic used by app, tests, and CLI, not a small SwiftPM package. Move CmuxTaskManagerCodingAgentDefinition built-ins and the session-retirement helper into a small package target (e.g. Packages/macOS/CmuxCore) and keep only app wiring in Sources/.
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 (23 passed)
Check name Status Explanation
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.
Cmux Swift Actor Isolation ✅ Passed The new Swift code adds pure value/CLI helpers and locked session-store logic, with no new @MainActor, actor, or unsafe Sendable reference types introduced.
Cmux Swift Blocking Runtime ✅ Passed No new blocking primitives were added in production Swift; the gajae-code change reuses an existing file lock and replaces a lookup+consume path with a single locked removal.
Cmux Browser Automation Off-Main ✅ Passed No changed file is in the rule scope; this PR only touches Gajae Code integration, not browser.* routing or WebKit wait paths.
Cmux Expensive Synchronous Load ✅ Passed No diff hunk adds RestorableAgentSessionIndex.load() or other large history parsing to main/interactive paths; gajae-code changes are small hook-install and session-retire logic.
Cmux Cache Substitution Correctness ✅ Passed The new session cache is event-driven and only carries prior IDs; current state is freshly read, and cmux still validates workspace/surface before retiring records.
Cmux No Hacky Sleeps ✅ Passed No hacky production waits were introduced; the only new timer is a 5s child-process timeout/kill fallback, while test sleeps and CI waits are allowed by the rule.
Cmux Algorithmic Complexity ✅ Passed New gajae-code logic uses O(1) session dict lookup and fixed-size agent/env lists; no nested rescans, sorts, or batch joins were added in hot paths.
Cmux Swift Concurrency ✅ Passed Touched Swift additions are synchronous; no new DispatchQueue, Combine, completion-handler, or fire-and-forget Task patterns appear in the diff.
Cmux Swift @Concurrent ✅ Passed Touched Swift files add only synchronous helpers; no Swift @concurrent/async functions or actor-isolation changes were introduced.
Cmux Swiftpm Lockfiles ✅ Passed PR only adds source-file/CI wiring; no SwiftPM pins, Package.resolved, or .gitignore lockfile ignores changed, and the pbxproj edit is just source registration.
Cmux Swift Logging ✅ Passed No new production Swift logging: the changed runtime files add no Logger/NSLog/debugPrint/dump, and the only prints are CLI user-facing output.
Cmux User-Facing Error Privacy ✅ Passed User-facing production strings stay generic; no new error/output copy leaks secrets, session IDs, or env-var details. Restricted names appear only in code/docs.
Cmux Full Internationalization ✅ Passed All new Gajae Code user-facing Swift strings are localized and each new catalog key has all 20 locales; remaining changes are literal tokens/docs.
Cmux Swiftui State Layout ✅ Passed The diff touches only backend/CLI, launch-policy, tests, and localization files; no SwiftUI views or state/layout antipatterns were introduced.
Cmux Architecture Rethink ✅ Passed The gajae-code addition is a required bridge with clear ownership/invariants and adds no new Swift-side sleeps, locks, observers, or split lifecycle ownership.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed Diff only touches CLI/agent-launch/sanitizer code and tests; no NSWindow/WindowGroup/NSPanel/NSWindowController changes or cmuxAuxiliaryWindowIdentifiers edits.
Cmux Source Artifacts ✅ Passed Changed paths are intentional source, test, docs, and localization files; no logs, caches, build output, or scratch dirs were added.
Cmux No Test Or Debug Seam In Production Source ✅ Passed No new #if DEBUG/test-only members or widened test seams were added in the changed production Sources files; the diff only adds gajae-code runtime/policy logic.
Cmux No Ambient Global State ✅ Passed No new file-scope Swift API, mutable globals, or singletons; the added helpers stay inside existing types and the new policy is a static constant.
Title check ✅ Passed The title is concise and accurately summarizes the main change: Gajae Code agent integration.
Description check ✅ Passed The description covers summary, scope, and testing well, but it omits the Demo Video, Review Trigger, and Checklist sections.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 30827-30845: Replace the lookup-then-consume sequence in the
gajae-code handling block with an atomic store helper that, within one locked
transaction, verifies the current previous session’s workspaceId and surfaceId
before removing it. Add the helper near the existing session-store methods, have
it no-op when either binding no longer matches, and invoke it using
previousSessionId, workspaceId, and surfaceId.

In `@CLI/CMUXCLI`+GajaeCodeExtension.swift:
- Around line 267-272: Update the config-root construction near
nonEmptyGajaeCodeEnvironmentValue for GJC_CONFIG_DIR to detect whether configDir
is absolute; use it directly when absolute, otherwise append it to home,
matching the existing GJC_CODING_AGENT_DIR behavior. Keep the subsequent agent
URL construction unchanged.
- Around line 315-321: Add localized `cli.hooks.gajaeCode.*` entries to
`Resources/Localizable.xcstrings` for every supported catalog locale, including
`zh-Hant`, `zh-Hans`, and all existing non-English locales. Cover the keys used
by the Gajae Code hook messages, preserving the existing English and Japanese
translations and matching the catalog’s established localization structure.
- Around line 71-73: Update the tmux argument check in the
GJC_TMUX_ACTIVE_SESSION handling to recognize both the exact --tmux token and
arguments beginning with --tmux=. Only append the bare --tmux flag when no
tmux-form argument is already present, preserving the existing argv behavior
otherwise.
- Around line 216-229: Update sendHook to return whether the hook was
successfully delivered, including false for spawn, stdin, and timeout failures.
In bindCurrentSession, retain the current activeSessionId until sendHook reports
success, then commit nextSessionId; preserve the previous_session_id payload so
failed retire attempts can be retried with the original session identifier.
- Around line 100-103: Update isRootSession to require an explicit root
indicator from ctx.sessionMetadata, such as kind === "root", and ensure missing
sessionMetadata or kind does not qualify as a root session. Preserve the
existing worker-environment exclusion before applying this authoritative
metadata check.

In
`@Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift`:
- Around line 294-310: The booleanOptions list in
AgentLaunchSanitizerPrimaryPolicies must no longer treat --default as a restored
Gajae Code argument. Remove --default from booleanOptions, add it to
droppedOptions, and add a regression assertion confirming restored argv omits
--default while preserving the remaining options.

In `@tests/test_gajae_code_extension_install.py`:
- Around line 354-361: Replace the fixed time.sleep(0.3) in the invocation-count
check with a deterministic completion signal. Update the fake bun script flow to
emit a sentinel invocation after all sub-session and team-worker calls, wait for
that sentinel through the existing wait_for_text mechanism, then assert the
non-empty invocation count remains exactly expected_invocations.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 930b0088-42d8-44c6-9134-9d793f222ade

📥 Commits

Reviewing files that changed from the base of the PR and between 18396f2 and b4efe42.

📒 Files selected for processing (19)
  • .github/workflows/ci.yml
  • CLI/CMUXCLI+AgentHookCatalog.swift
  • CLI/CMUXCLI+GajaeCodeExtension.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchCaptureTrust.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentResumeArgv.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchCaptureTrustTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchEnvironmentPolicyTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchSanitizerTests.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentResumeArgvTests.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxTaskManagerCodingAgentDefinition+BuiltIns.swift
  • cmux.xcodeproj/project.pbxproj
  • cmuxTests/TaskManagerResourcesTests.swift
  • docs/agent-hooks.md
  • tests/test_gajae_code_extension_install.py

Comment thread CLI/cmux.swift
Comment on lines +71 to +73
if (firstString(process.env.GJC_TMUX_ACTIVE_SESSION) && !argv.includes("--tmux")) {
argv.push("--tmux");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

--tmux dedupe misses the --tmux=<value> form.

argv.includes("--tmux") only matches the exact token, so an original launch using --tmux=name gets a second, bare --tmux appended into the persisted resume argv. Match by prefix instead.

🐛 Proposed fix
-  if (firstString(process.env.GJC_TMUX_ACTIVE_SESSION) && !argv.includes("--tmux")) {
+  const hasTmuxFlag = argv.some((value) => value === "--tmux" || value.startsWith("--tmux="));
+  if (firstString(process.env.GJC_TMUX_ACTIVE_SESSION) && !hasTmuxFlag) {
     argv.push("--tmux");
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (firstString(process.env.GJC_TMUX_ACTIVE_SESSION) && !argv.includes("--tmux")) {
argv.push("--tmux");
}
const hasTmuxFlag = argv.some((value) => value === "--tmux" || value.startsWith("--tmux="));
if (firstString(process.env.GJC_TMUX_ACTIVE_SESSION) && !hasTmuxFlag) {
argv.push("--tmux");
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+GajaeCodeExtension.swift around lines 71 - 73, Update the tmux
argument check in the GJC_TMUX_ACTIVE_SESSION handling to recognize both the
exact --tmux token and arguments beginning with --tmux=. Only append the bare
--tmux flag when no tmux-form argument is already present, preserving the
existing argv behavior otherwise.

Comment on lines +100 to +103
function isRootSession(ctx: ExtensionContext): boolean {
if (firstString(process.env.GJC_TEAM_WORKER, process.env.GJC_TEAM_INTERNAL_WORKER)) return false;
return ctx.sessionMetadata?.kind !== "sub";
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

@gajae-code/coding-agent ExtensionContext sessionMetadata kind sub session

💡 Result:

In the context of the @gajae-code/coding-agent package, there is no standardized, public-facing API or configuration property strictly named "ExtensionContext sessionMetadata kind sub session". The terms you are referencing appear to be a mixture of internal concepts from the Gajae Code codebase and unrelated VS Code platform definitions: 1. Gajae Code Concepts: The project uses an SDK-based session system (accessible via packages/coding-agent/src/sdk/session.ts) [1][2]. It supports "subagents" for specialized task delegation [3] and provides a harness for managing agent sessions, often using custom plugin skills like gjc-session to manage worktree-backed sessions [4][5]. However, the specific string "ExtensionContext sessionMetadata kind sub session" is not a recognized configuration or API path in the Gajae Code documentation or public codebase [6][7]. 2. VS Code Concepts: The terminology closely resembles recent internal work within the VS Code platform (specifically the Agent Host integration), which includes managing "session metadata" [8][9], "custom agents" [10][11], and "session summaries" [12][9]. The VS Code API distinguishes between various session states and metadata types (e.g., IAgentSessionMetadata, SessionSummary), but "kind" and "sub session" are not standard top-level properties in that documented schema [10][8]. If you are encountering this string in an error log or code snippet, it is likely an internal debugging label, a custom key-value pair used by a specific extension, or a misconfiguration within an implementation of the Gajae Code harness or a VS Code Agent Host provider [6][8]. For managing sessions in Gajae Code, refer to the documented SDK methods for creating and controlling sessions (e.g., createAgentSession) rather than attempting to manipulate internal metadata structures directly [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate CLI file and package references =="
fd -a 'CMUXCLI+GajaeCodeExtension.swift|package.json|Package.swift|Info.plist|README.*' . | sed 's#^\./##' | head -100

echo
echo "== relevant Swift file outline/lines =="
FILE="$(fd 'CMUXCLI+GajaeCodeExtension.swift' . | head -1)"
if [ -n "${FILE:-}" ]; then
  echo "FILE=$FILE"
  wc -l "$FILE"
  sed -n '1,180p' "$FILE" | cat -n
fi

echo
echo "== search session metadata / allowed versions =="
rg -n "sessionMetadata|GJC_TEAM_WORKER|GJC_TEAM_INTERNAL_WORKER|Gj[aA]e|0\.10\.0|0\.11\.11|rootSession|isRootSession|kind" -S --glob '!node_modules' --glob '!build' --glob '!Dist' .

Repository: manaflow-ai/cmux

Length of output: 50373


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== git status/stat =="
git status --short 2>/dev/null || true
git diff --stat 2>/dev/null || true
echo

echo "== candidate Swift files =="
git ls-files '*.swift' | rg 'CLI/CMUXCLI|Gajae|Extension' || true
echo

echo "== exact relevant Swift file =="
FILE="$(git ls-files | rg '(^|/)CMUXCLI+GajaeCodeExtension\.swift$' | head -1)"
if [ -n "${FILE:-}" ]; then
  echo "FILE=$FILE"
  wc -l "$FILE"
  sed -n '1,220p' "$FILE" | cat -n
fi

echo
echo "== focused searches =="
rg -n "isRootSession|sessionMetadata|GJC_TEAM_WORKER|GJC_TEAM_INTERNAL_WORKER|kind" . --glob '!node_modules' --glob '!build' --glob '!Dist' --glob '!*.png' --glob '!*.jpg' --glob '!*.jpeg' --max-count 80 || true
echo

echo "== dependency/version references for gajae/coding-agent =="
git ls-files | rg '(^|/)(package\.json|Package\.swift|.*gajae.*|.*coding-agent.*)' | head -100 | while read -r f; do
  echo "--- $f"
  rg -n "`@gajae`|coding-agent|Gajae|GJC|@.*gajae" "$f" -C 3 || true
done

Repository: manaflow-ai/cmux

Length of output: 8374


🌐 Web query:

github Yeachan-Heo gajae-code "ExtensionContext" "sessionMetadata"

💡 Result:

The terms Yeachan-Heo, gajae-code, ExtensionContext, and sessionMetadata belong to two distinct development ecosystems and are not directly related [1][2][3]. 1. Yeachan-Heo / gajae-code: This is an independent open-source project managed by Yeachan-Heo [1][4]. Gajae-Code (gjc) is a focused AI coding agent and harness designed to be repository-native, utilizing tmux and Git worktrees for isolated execution [1][5]. It explicitly positions itself as an external coding-agent harness that does not install into or replace existing IDE extensions like Claude Code or Claw Code [1]. It utilizes its own SDK, WebSocket-based loopback protocols, and Coordinator MCP (Model Context Protocol) to facilitate external control and automation, rather than relying on standard IDE extension APIs [1][6][7]. 2. ExtensionContext and sessionMetadata: These terms are standard components of the VS Code Extension API and Microsoft's Copilot Chat architecture [2][3][8]. ExtensionContext: A standard VS Code API object passed to extensions to manage lifecycle, storage, and subscriptions [3]. sessionMetadata: A data structure used within VS Code's internal Copilot Chat and GitHub Pull Request extensions to manage chat session states, workspace context, and pull request information [2][3][9]. There is no functional or technical overlap between the gajae-code project's architecture and the VS Code Extension API's session metadata management [1][6][2]. Any perceived connection is likely an artifact of searching codebases that share common TypeScript/Node.js terminology [7][2][8].

Citations:


🌐 Web query:

github Yeachan-Heo gajae-code "kind" "sub" sessionMetadata

💡 Result:

In the context of the Yeachan-Heo/gajae-code repository, sessionMetadata.kind === "sub" refers to in-process sub-agent sessions [1][2]. Gajae-Code is an experimental coding-agent harness that supports structured workflows and team-based execution [3][4]. When the system spawns child sessions (for example, to handle parallel tasks or delegated sub-agent work), it classifies them as "sub" sessions [1][2]. These sub-sessions are often excluded from certain primary session notifications or forum topic generation to avoid clutter and maintain focus on the root session [1][2]. The sessionMetadata object is part of the internal architecture used by the coding agent to track session types, hierarchy, and state, ensuring that the system can distinguish between primary user-driven sessions and automated in-process sub-agents [5][1].

Citations:


🌐 Web query:

Yeachan-Heo gajae-code "GJC_TEAM_WORKER" "GJC_TEAM_INTERNAL_WORKER"

💡 Result:

Gajae-Code (gjc) is an open-source, experimental coding-agent harness developed by Yeachan-Heo [1][2]. It is designed to provide structured planning, persistent evidence, and tmux-backed, multi-worker execution for software development tasks [1][3]. The terms GJC_TEAM_WORKER and GJC_TEAM_INTERNAL_WORKER (or similar environment-level configurations like GJC_TEAM_WORKER_COMMAND, GJC_TEAM_WORKER_CLI, and GJC_TEAM_WORKER_ID) are part of the internal orchestration system within Gajae-Code, specifically related to the gjc team command [4][5]. Key technical aspects include: 1. Team Orchestration: The gjc team functionality allows for multi-worker coordination within a tmux environment [3][5]. When a team session is launched, it splits the current tmux leader window into multiple panes to run individual agent workers [4][3]. 2. Environment Configuration: - GJC_TEAM_WORKER: Used to identify specific workers, typically formatted as team_name/worker_id [6]. - GJC_TEAM_WORKER_COMMAND: Defines the command used to launch individual agent workers within the team session [4][5]. - GJC_TEAM_WORKER_CLI / GJC_TEAM_WORKER_CLI_MAP: Configure which CLI tool (e.g., gjc or other compatible workers) is used for the agent workers [4]. 3. State and Lifecycle: The system relies on configuration files and state directories under.gjc/ (e.g.,.gjc/state/team) to manage task claims, worker heartbeats, and team metadata [4][5]. The architecture supports isolated worktrees for individual workers, allowing them to operate concurrently on different parts of a project [7]. For detailed usage, architecture, and developer documentation, you can refer to the official repository at github.com/Yeachan-Heo/gajae-code [1][8].

Citations:


Gate isRootSession on an explicit root indicator.

ctx.sessionMetadata?.kind !== "sub" treats missing metadata as root, so if sessionMetadata/kind is absent on any supported GJC version, a real sub-session can bind the leader surface. Use kind === "root" or reject missing metadata; only fall back when the metadata source is guaranteed and the failure mode is non-authoritative.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+GajaeCodeExtension.swift around lines 100 - 103, Update
isRootSession to require an explicit root indicator from ctx.sessionMetadata,
such as kind === "root", and ensure missing sessionMetadata or kind does not
qualify as a root session. Preserve the existing worker-environment exclusion
before applying this authoritative metadata check.

Source: Path instructions

Comment thread CLI/CMUXCLI+GajaeCodeExtension.swift
Comment on lines +267 to +272
let home = nonEmptyGajaeCodeEnvironmentValue("HOME", in: environment) ?? NSHomeDirectory()
let configDir = nonEmptyGajaeCodeEnvironmentValue("GJC_CONFIG_DIR", in: environment) ?? ".gjc"
let configRoot = (home as NSString).appendingPathComponent(configDir)
return URL(fileURLWithPath: configRoot, isDirectory: true)
.appendingPathComponent("agent", isDirectory: true)
.standardizedFileURL

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Absolute GJC_CONFIG_DIR is joined onto HOME.

(home as NSString).appendingPathComponent(configDir) produces $HOME/abs/path when GJC_CONFIG_DIR is an absolute path, installing the extension outside the real agent directory. GJC_CODING_AGENT_DIR already handles this case; apply the same check here.

🐛 Proposed fix
         let configDir = nonEmptyGajaeCodeEnvironmentValue("GJC_CONFIG_DIR", in: environment) ?? ".gjc"
-        let configRoot = (home as NSString).appendingPathComponent(configDir)
+        let configRoot = (configDir as NSString).isAbsolutePath
+            ? configDir
+            : (home as NSString).appendingPathComponent(configDir)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let home = nonEmptyGajaeCodeEnvironmentValue("HOME", in: environment) ?? NSHomeDirectory()
let configDir = nonEmptyGajaeCodeEnvironmentValue("GJC_CONFIG_DIR", in: environment) ?? ".gjc"
let configRoot = (home as NSString).appendingPathComponent(configDir)
return URL(fileURLWithPath: configRoot, isDirectory: true)
.appendingPathComponent("agent", isDirectory: true)
.standardizedFileURL
let home = nonEmptyGajaeCodeEnvironmentValue("HOME", in: environment) ?? NSHomeDirectory()
let configDir = nonEmptyGajaeCodeEnvironmentValue("GJC_CONFIG_DIR", in: environment) ?? ".gjc"
let configRoot = (configDir as NSString).isAbsolutePath
? configDir
: (home as NSString).appendingPathComponent(configDir)
return URL(fileURLWithPath: configRoot, isDirectory: true)
.appendingPathComponent("agent", isDirectory: true)
.standardizedFileURL
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+GajaeCodeExtension.swift around lines 267 - 272, Update the
config-root construction near nonEmptyGajaeCodeEnvironmentValue for
GJC_CONFIG_DIR to detect whether configDir is absolute; use it directly when
absolute, otherwise append it to home, matching the existing
GJC_CODING_AGENT_DIR behavior. Keep the subsequent agent URL construction
unchanged.

Comment thread CLI/CMUXCLI+GajaeCodeExtension.swift
Comment on lines +294 to +310
booleanOptions: [
"--allow-home",
"--continue",
"--default",
"--no-lsp",
"--no-pty",
"--no-rules",
"--no-session",
"--no-title",
"--no-tools",
"--print",
"--tmux",
"-c",
"-h",
"-p",
"-v"
],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files | rg 'AgentLaunchSanitizerPrimaryPolicies\.swift|CMAgent|Launch|Sanitizer|restore|default|mpreset' || true

echo
echo "Target excerpt:"
file="$(git ls-files | rg 'AgentLaunchSanitizerPrimaryPolicies\.swift$' | head -n1)"
if [ -n "$file" ]; then
  wc -l "$file"
  ast-grep outline "$file" --view compact || true
  sed -n '240,340p' "$file" | nl -ba -v240
fi

echo
echo "Search policy constants/usages:"
rg -n "booleanOptions|droppedOptions|--default|mpreset|sanitize|Restore|restore" -S . --glob '!node_modules' --glob '!build' --glob '!DerivedData' | head -n 200

Repository: manaflow-ai/cmux

Length of output: 10918


🌐 Web query:

Yeachan-Heo gajae-code packages/coding-agent/src/cli.ts --default --mpreset documentation

💡 Result:

The command you referenced relates to the Gajae-Code (gjc) project, an experimental coding-agent harness developed by Yeachan-Heo [1][2]. The command bun packages/coding-agent/src/cli.ts --default --mpreset documentation is a way to execute the agent's CLI directly from source using the Bun runtime, specifically configured to use a "documentation" preset [1][3]. Gajae-Code is designed as an external coding-agent harness that provides a focused workflow for tasks like interviews, plan reviews, and tmux-native execution [1][2]. By running packages/coding-agent/src/cli.ts from source, users can bypass the compiled binary version to access the latest development features and settings [4][3]. Key components of this command include: - bun: The JavaScript runtime used to execute the TypeScript CLI file [3]. - packages/coding-agent/src/cli.ts: The source entry point for the coding-agent CLI [3][5]. - --default: Typically signals the use of default configurations or a default startup mode [6][7]. - --mpreset documentation: This argument selects a specific model preset (or "mode preset") optimized for documentation tasks [8]. For further details on command arguments, environment variables, and workflow configurations, consult the documentation within the repository, such as docs/environment-variables.md or the main README.md file [7][2]. Gajae-Code remains in beta, and users are encouraged to verify outputs before applying them to critical workflows [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file="Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift"

echo "Target lines:"
awk 'NR>=260 && NR<=325 { printf "%6d  %s\n", NR, $0 }' "$file"

echo
echo "Relevant sanitizer definitions/usages:"
rg -n "static let .*booleanOptions|static let .*droppedOptions|booleanOptions|droppedOptions|sanitize|AgentLaunchSanitizerPrimaryPolicies|PrimaryPolicies" Packages/macOS/CMUXAgentLaunch/Sources Packages/macOS/CMUXAgentLaunch/Tests -S

echo
echo "Gajae cli snippets from known github blob if network available:"
python3 - <<'PY'
import urllib.request
urls = [
    "https://raw.githubusercontent.com/Yeachan-Heo/gajae-code/main/packages/coding-agent/src/cli.ts",
    "https://raw.githubusercontent.com/Yeachan-Heo/gajae-code/main/packages/coding-agent/src/cli.js",
]
for url in urls:
    try:
        text=urllib.request.urlopen(url, timeout=15).read().decode("utf-8", "replace")
        print(f"\n--- {url} ---")
        for i,line in enumerate(text.splitlines(), 1):
            if "default" in line or "mpreset" in line or "Set as default" in line or "persist" in line:
                if i>1: print(text.splitlines()[i-2])
                print(f"{i}: {line}")
                if i<text.splitlines().index(line): print(text.splitlines()[i])
    except Exception as e:
        print(f"Failed {url}: {e}")
PY

Repository: manaflow-ai/cmux

Length of output: 34170


🌐 Web query:

github raw.githubusercontent.com Yeachan-Heo gajae-code packages/coding-agent/src/cli.ts --default

💡 Result:

The file packages/coding-agent/src/cli.ts within the Yeachan-Heo/gajae-code repository serves as the primary executable bootstrap for Gajae-Code (gjc) [1]. It is responsible for registering the CLI commands—including setup, deep-interview, ralplan, ultragoal, team, and rlm—and dispatching the agent into various operating modes such as interactive (TUI), print, RPC, bridge, and research [1][2][3]. Gajae-Code is an experimental, beta-stage coding-agent harness designed to run alongside existing developer tools like Claude Code or OpenCode [4][2]. It focuses on structured planning, persistent evidence, and isolated execution through a deliberately small workflow surface [2][5]. When executed, the CLI adapts user options into session configurations, which are then passed to the SDK layer (specifically packages/coding-agent/src/main.ts and the session manager) to construct and run the agent loop [1][3]. The project maintains its state, goals, and local overrides within a.gjc/ directory in the target repository [6][3].

Citations:


🌐 Web query:

github raw.githubusercontent.com Yeachan-Heo gajae-code packages/coding-agent src cli.ts --mpreset --default

💡 Result:

The file packages/coding-agent/src/cli.ts in the Yeachan-Heo/gajae-code repository serves as the primary executable bootstrap for the Gajae-Code (gjc) coding-agent harness [1][2]. It handles the registration of CLI commands (such as setup, deep-interview, ralplan, ultragoal, and team) and initiates the session by routing requests through to packages/coding-agent/src/main.ts [1][2]. The command usage mentioned in your query—specifically --mpreset and --default—relates to the configuration of the agent session. These flags are used within the CLI to initialize or configure the runtime environment with specific defaults [1][2]. Gajae-Code is designed as an external coding-agent harness that operates within a repository or worktree to provide structured planning, persistent evidence, and tmux-backed worker execution [3][4]. It is not a plugin for other agents like Claude Code or Codex CLI, but rather an independent tool that can be used alongside them [4]. For technical details regarding the CLI bootstrap, session lifecycle, and command handling, you can consult the codebase overview in the repository [1][2]. Integration patterns for external controllers are further documented in docs/bot-integration.md and docs/external-control-readiness.md [5][6].

Citations:


🌐 Web query:

"github --default" "gajae-code" "mpreset"

💡 Result:

In the context of the Gajae Code (gjc) project, --mpreset is a command-line interface (CLI) flag used to specify a model profile [1][2][3]. Gajae Code is an experimental coding-agent harness [4][5][6]. When running gjc, the --mpreset flag allows users to define or select a pre-configured profile that determines which AI model and associated settings the agent uses for a given session [2][3][7]. Examples of usage found in project documentation and issues include: gjc --mpreset codex-medium gjc --mpreset codex-pro gjc --mpreset procedural These profiles are often used to manage model capabilities, thinking behaviors, and provider credentials [3]. The project maintains these model profiles to help users quickly switch between different operational modes [2][7]. You can find more information about configuring and using model profiles in the official Gajae Code documentation at gajae-code.com [5][6]. Note: The flag is specific to the gajae-code repository by Yeachan-Heo [4]. It should not be confused with the miniprogram-properties-reset library found on GitHub, which uses a different naming convention and purpose [8].

Citations:


🌐 Web query:

site:gajae-code.com/docs/models.md "default" "--default" "mpreset"

💡 Result:

I couldn’t find a docs/models.md page on gajae-code.com, but the closest relevant doc says:

  • --mpreset selects a session preset.
  • --default persists that preset as the startup default in config.yml.
  • Example: gjc --mpreset daily
  • Example: gjc --mpreset ultimate --default (ithub.global.ssl.fastly.net)

So the answer is: --mpreset is the runtime preset selector, and --default makes it the saved startup default. (ithub.global.ssl.fastly.net)

Citations:


🌐 Web query:

site:gajae-code.com/docs/gajae-code-mode.html "default" "--default" "mpreset"

💡 Result:

I couldn’t find an exact page match for site:gajae-code.com/docs/gajae-code-mode.html "default" "--default" "mpreset". The closest relevant docs are the v0.11.0 changelog and homepage, which mention --mpreset and default-model selection behavior. (gajae-code.com)

Citations:


Drop --default from restored Gajae Code argv.

--default persists --mpreset in the persistent Gajae configuration, not in one-off session behavior. Keeping it in booleanOptions rewrites the user’s configured startup default when a stale gjc --mpreset X --default launch is restored; move it to droppedOptions and cover it with a regression assertion.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift`
around lines 294 - 310, The booleanOptions list in
AgentLaunchSanitizerPrimaryPolicies must no longer treat --default as a restored
Gajae Code argument. Remove --default from booleanOptions, add it to
droppedOptions, and add a regression assertion confirming restored argv omits
--default while preserving the remaining options.

Comment thread tests/test_gajae_code_extension_install.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift (1)

353-364: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove -v from the GjC reject list unless it is specifically non-restorable.

-v is not the GjC version flag (--version), and GjC supports verbose/session verbosity via separate settings (--verbose and /verbose). Rejecting -v here can prevent restoring saved interactive GjC launches that happen to include that flag.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift`
around lines 353 - 364, Remove the "-v" entry from the GjC rejectOptions list,
while retaining "--version" and the other explicitly rejected options. Do not
add replacement flags; allow saved interactive GjC launches containing "-v" to
be restored.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Resources/Localizable.xcstrings`:
- Around line 256691-256810: Limit all newly added localization entries in the
affected string blocks to the supported en and ja locales. Remove the added
legacy-locale blocks, including ar, bs, da, de, es, fr, it, km, ko, nb, pl,
pt-BR, ru, th, tr, uk, zh-Hans, and zh-Hant, while preserving the English and
Japanese entries across all referenced blocks.

---

Outside diff comments:
In
`@Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift`:
- Around line 353-364: Remove the "-v" entry from the GjC rejectOptions list,
while retaining "--version" and the other explicitly rejected options. Do not
add replacement flags; allow saved interactive GjC launches containing "-v" to
be restored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: db2d014c-7463-4c20-83b9-79aa6c3b2680

📥 Commits

Reviewing files that changed from the base of the PR and between b4efe42 and 3ed7ef6.

📒 Files selected for processing (6)
  • CLI/CMUXCLI+GajaeCodeExtension.swift
  • CLI/cmux.swift
  • Packages/macOS/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerPrimaryPolicies.swift
  • Packages/macOS/CMUXAgentLaunch/Tests/CMUXAgentLaunchTests/AgentLaunchSanitizerTests.swift
  • Resources/Localizable.xcstrings
  • tests/test_gajae_code_extension_install.py

Comment on lines +256691 to +256810
"ar": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"bs": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"da": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"de": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"en": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"es": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"fr": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"it": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"km": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"ko": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"nb": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"pl": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"pt-BR": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"ru": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"th": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"tr": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"uk": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"zh-Hans": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
},
"zh-Hant": {
"stringUnit": {
"state": "translated",
"value": "Gajae Code"
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Limit new localization entries to supported locales.

These new keys add translations for legacy locales even though this project currently requires only English (en) and Japanese (ja) for new localization work. Keep the en/ja entries and remove the newly added legacy-locale blocks unless those locales are intentionally reintroduced project-wide.

Based on learnings, new localization changes should target only English and Japanese; do not expand legacy locales with unaudited translations.

Also applies to: 256816-256934, 256941-257059, 257066-257185, 257191-257310, 257316-257435, 257441-257560, 257566-257685, 257691-257810, 257816-257934

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Resources/Localizable.xcstrings` around lines 256691 - 256810, Limit all
newly added localization entries in the affected string blocks to the supported
en and ja locales. Remove the added legacy-locale blocks, including ar, bs, da,
de, es, fr, it, km, ko, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, and zh-Hant,
while preserving the English and Japanese entries across all referenced blocks.

Source: Learnings

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.

2 participants