1jehuang / 1jehuang/jcode

feat: emit OSC 9 progress for reliable agent status detection (herdr integration)

Open
#574 7 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement from-pr priority: medium triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Problem

Herdr currently detects jcode's agent state using only screen-scraping (TOML manifest regex/contains rules). This is fragile because:

  1. Spinner frames change⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏ are matched per-frame, but any visual change breaks detection
  2. Status text is version-dependent"sending…", "thinking…", "running tool" labels change between jcode releases
  3. False positives — generic words like "permission", "allow", "deny" appear in conversation text
  4. No transcript viewer rule — scrollback text can confuse state detection
  5. Stale text handling — requires complex bottom_non_empty_lines(N) + not gate tuning

How reliable agents do it

Every well-detected agent (codex, claude, opencode, kilo) uses OSC sequences as the primary detection path, with screen-scrape as a lower-priority fallback. jcode currently emits none.

Herdr captures two OSC channels from the terminal stream:

  • OSC 0/2 (terminal title) → osc_title region in manifests
  • OSC 9 (progress) → osc_progress region in manifests

Proposed solution

Emit structured OSC 9 progress sequences with a stable, version-independent payload when the TUI's ProcessingStatus changes:

Working:  ESC ] 9 ;jcode:working BEL
Idle:     ESC ] 9 ;jcode:idle BEL
Blocked:  ESC ] 9 ;jcode:blocked BEL
Implementation
  • tui_lifecycle_runtime.rsemit_agent_status_osc() method that writes the OSC 9 escape sequence to stdout, with dedup so it only emits on state transitions (safe to call on every redraw)
  • run_shell.rs — call emit_agent_status_osc() on every completed spinner frame
  • local.rs — call it when a turn finishes (→ idle)
  • jcode-tui-permissions/src/lib.rs — emit jcode:blocked when the permissions viewer opens and jcode:idle when it closes (the main TUI is paused during permission prompts)
  • app.rs / tui_lifecycle.rslast_osc_state field for dedup tracking
Test coverage

Unit tests verify:

  • Idle state when not processing
  • Working state when processing
  • Dedup skips repeated same-state calls
  • State transitions emit correctly (working → idle → working)
  • Suppressed in replay mode
  • Suppressed when terminal title updates are off
Benefits
  1. Version-stablejcode:working string never changes even if UI text changes
  2. No false positives — structured payload can't appear in conversation text
  3. No stale text issues — OSC is a live signal, not screen-scraped
  4. Cheap — one escape sequence per status change, negligible overhead
  5. Backward compatible — screen-scrape rules remain as fallback
  6. Consistent with ecosystem — matches codex/claude OSC-first approach

Reference branch

Changes available at: https://github.com/alecuba16/jcode/tree/herdr_detectable

Commit: acb185a3feat: emit OSC 9 progress for herdr agent status detection

Files changed (6 files, +172 lines)
crates/jcode-tui-permissions/src/lib.rs            |  21 +++
crates/jcode-tui/src/tui/app.rs                    |   2 +
crates/jcode-tui/src/tui/app/local.rs              |   1 +
crates/jcode-tui/src/tui/app/run_shell.rs          |   5 +
crates/jcode-tui/src/tui/app/tui_lifecycle.rs      |   2 +
crates/jcode-tui/src/tui/app/tui_lifecycle_runtime.rs | 141 +++++++++++

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with crates/jcode-tui/src/tui/app/tui_lifecycle_runtime.rs and inspect the related changes in app.rs, tui_lifecycle.rs, run_shell.rs, local.rs, and jcode-tui-permissions/src/lib.rs. Run the relevant unit tests for status emission and confirm that OSC 9 transitions, deduplication, replay suppression, and terminal-title settings behave as described.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.