Skip to content

First-class jcode harness support — identity + presence badges #815

Description

@jmpnop

What problem does this solve?

I use jcode (1jehuang/jcode, a Rust-native coding-agent harness) inside Supacode. Today jcode can only be launched as a plain terminal command (supacode.json{"setupScript": "jcode"}). It is not a recognized SkillAgent, so a jcode worktree gets a strictly degraded experience versus a Claude/Kimi/Codex worktree:

  • No presence badge — the pane never shows busy / idle / error, so I can't tell at a glance which worktrees need attention. That live-presence signal is Supacode's core value, and it's simply absent for jcode.
  • No harness identity — jcode panes are indistinguishable from any other shell: no name, no icon, no per-harness affordances in any surface where a harness is identified/selected.
  • No attention/notification flow — "move-notified-worktree-to-top" and the notification flows never fire for jcode.

jcode is a strong fit for Supacode's model because it already ships a first-class shell-command lifecycle hook system — the exact structural match for how Supacode already badges the other 11 harnesses (an OSC 3008 presence escape printed by a hook installed into the harness's own config). So this gap is closeable with the pattern the codebase already uses for Kimi.

Proposed solution

Make jcode the 12th first-class harness, using the existing Kimi TOML template as the model (Kimi already badges from ~/.kimi-code/config.toml; jcode uses ~/.jcode/config.toml [hooks]). This is small and additive — identity + hook-based busy / idle / error badges at parity with Kimi/Codex:

  1. Identity. Add case jcode to SkillAgent (configDirectoryName = ".jcode", displayName = "jcode", assetName = "jcode-mark"), plus its icon asset. Everything downstream of the enum is already agent-generic, so this lights up jcode in every surface.
  2. Hook install. When ~/.jcode exists, install a Supacode-managed [hooks] block into ~/.jcode/config.toml (ownership-marked with # supacode-managed-hook, so install/uninstall never touches user hooks), modeled on the existing Kimi{HookSettings,HookSettingsFileInstaller,SettingsInstaller} trio. One jcode-specific wrinkle: jcode execs hooks directly, not through a shell, so instead of inlining the shell one-liner (as Kimi does) the installer writes a tiny executable wrapper script (~/.jcode/hooks/supacode-presence.sh, chmod 0755) and points [hooks] at it. The wrapper reuses the existing AgentPresenceOSC emit snippets, so the emitted OSC is byte-identical to every other harness.
  3. Event mapping. jcode turn_start → busy; turn_end (STATUS=ok) → idle; turn_end (STATUS=error) → error (+ notification); session_start/session_end → sessionStart / sessionEnd+idle. Verified against jcode's hook env (JCODE_HOOK_EVENT, JCODE_HOOK_STATUS, JCODE_HOOK_SESSION_ID).

Scope: ~3 one-line edits to the exhaustive SkillAgent switches + 2 new Swift files (mirroring the Kimi trio) + 1 icon asset. No changes to the presence reducer, badge views, sidebar fan-out, or notification flows — all already agent- and source-generic. No changes to jcode itself; this only writes into jcode's own supported [hooks] config, exactly as Supacode already does for Kimi.

(A follow-up proposal would add an api-bridge ingest path for an awaiting-input badge and presence in detached daemon mode — the two gaps hooks alone cannot close. It's independently shippable and not required for this one; I'll file it separately so this stays focused.)

On the displayName: jcode brands itself lowercase — its README title is literally # jcode, its site is jcode.sh, and lowercase jcode dominates its README (~200:7) and binary strings (~2688:388) over the title-case "Jcode". So I've used "jcode" to match the project's own styling. If you'd prefer a title-case label for consistency with "Kimi Code"/"Grok Code", the brand-accurate form is "Jcode". Happy to match whatever you pick.

Alternatives considered

  • Keep the setupScript: "jcode" workaround. It launches jcode but yields no badge, no identity, no notifications — the exact degraded experience this solves. Route-around, not support.
  • Process-name / terminal-title / state-file scraping to infer presence. Rejected: the codebase has exactly one detection mechanism (hook → OSC 3008 over the pane TTY), and jcode offers a native hook system that matches it. Scraping would add a second, fragile mechanism no other harness uses.
  • Inline the shell one-liner in [hooks] like Kimi. Doesn't work: jcode execs hooks directly without a shell, so the printf/ps/case one-liner won't parse. The wrapper-script approach is the minimal fix and keeps the emitted OSC identical to every other harness.

Supacode version

0.10.8 (build 1785775286). Targeting main.

Are you planning to build this yourself?

  • I intend to open a pull request once this is approved and marked ready.

Before submitting

  • I searched existing issues and this is not a duplicate.
  • I understand feature pull requests are closed until the issue is marked ready.
  • I agree to follow this project's Code of Conduct.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestreadyApproved for a pull request. Added by a maintainer once an issue is triaged.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions