Skip to content

fix(status-line): honor hidden jobs segment for background job count - #3784

Closed
pers0n4 wants to merge 1 commit into
Yeachan-Heo:devfrom
pers0n4:fix/status-line-jobs-hidden
Closed

fix(status-line): honor hidden jobs segment for background job count#3784
pers0n4 wants to merge 1 commit into
Yeachan-Heo:devfrom
pers0n4:fix/status-line-jobs-hidden

Conversation

@pers0n4

@pers0n4 pers0n4 commented Aug 3, 2026

Copy link
Copy Markdown

What

Hiding the jobs status-line segment now also hides the background-job counter.

StatusLineComponent#collectStatusSegments() appended a hardcoded N jobs running chip to the right group after rendering the configured segments, without ever consulting statusLine.leftSegments / statusLine.rightSegments:

for (const segId of effectiveSettings.rightSegments) { ... }   // configured segments
right.push(...actionHints.map(hint => hint.content));

const runningBackgroundJobs =                                  // ungated
    this.session.getAsyncJobSnapshot()?.running.filter(job => job.metadata?.monitor !== true).length ?? 0;

This PR gates that counter on the jobs segment placement resolved by #resolveSettings(), so preset users and preset: custom users share one code path.

Why

GJC has two independent job-rendering paths:

Path Data Config-controlled
jobs segment (status-line/segments.ts) JobsObserver snapshot — monitor/cron counts yes, via left/rightSegments
legacy chip (tool-status-header.ts:809) AsyncJobManager running jobs minus monitors — async bash / task subagents no

Setting jobs to hidden in /settings calls #setSegmentPlacement(), which only removes "jobs" from the two arrays. The legacy chip never reads those arrays, and it renders with the same theme.icon.agents glyph and the same statusLineSubagents color as the segment — so the user sees an identical-looking job indicator survive the setting and concludes it was ignored.

Turning off async.enabled does not help either: isBackgroundJobSupportEnabled() unconditionally returns true, so AsyncJobManager exists in every top-level session and the chip appears whenever any non-monitor background job runs.

Existing coverage missed this because both legacy-chip tests in test/jobs-segment.test.ts configure rightSegments: ["jobs"]; there was no hidden-placement case.

Every bundled preset keeps jobs in rightSegments (asserted by the existing AC4 test), so default output is unchanged. Only users who explicitly hid the segment see a difference — which is the point.

Testing

bun test packages/coding-agent/test/jobs-segment.test.ts
#  7 pass, 0 fail

bun test packages/coding-agent/test/status-line-*.test.ts \
         packages/coding-agent/test/jobs-*.test.ts \
         packages/coding-agent/test/interactive-mode-status.test.ts
#  130 pass, 0 fail across 18 files

bun --cwd=packages/coding-agent run check
#  biome: 2508 files, no fixes applied; tsc -p tsconfig.json --noEmit: clean

The new regression test fails on the parent commit with exactly the reported symptom:

error: expect(received).not.toContain(expected)
Expected to not contain: "job running"
Received: " 🦞 1 job running "

Known unrelated failure on dev

Root bun run check currently fails at check:sdk-closure on unmodified origin/dev (9d0a1c3), before and after this change:

Telegram baseline manifest does not exactly match the generated baseline:
- missing command: bun test packages/coding-agent/test/notifications-telegram-daemon-staging-temp-leak.test.ts
- missing command: bun test packages/coding-agent/test/notifications-topic-settle-fence-epoch.test.ts

Both test files exist on dev but are absent from scripts/telegram-daemon-generation-manifest.json, which was last regenerated at 45bc057 — before b8ea855 and a10c6de added those tests. This PR touches neither the manifest nor any notifications code; the drift is pre-existing and out of scope here.

GJC verdict

No independent architect/critic/human review has happened — the author of this change is also the only party that has looked at it, and the template treats self-approval as BLOCK.

gajae.pr-review-verdict.v1 needs-human sha256:8445809c833f420afc1fa2869596e99ba83cc8eb3d2f838f3a2e31d780020b46 reviewer:human evidence:bun --cwd=packages/coding-agent run check && bun test packages/coding-agent/test/jobs-segment.test.ts

Head: 4b240ca04fe80369e00d183047124ad4d4741139
Hash reproduces with git diff origin/dev..HEAD | shasum -a 256.


  • Target branch is dev
  • bun check passes — package-level bun --cwd=packages/coding-agent run check passes; root bun run check fails only at the pre-existing check:sdk-closure telegram manifest drift documented above
  • Tested locally
  • CHANGELOG updated (if user-facing)
  • Verdict above matches the exact PR head, not an earlier commit

@Yeachan-Heo

Copy link
Copy Markdown
Owner

@pers0n4 — this PR can't be merged as-is: the merge attempt was refused and GitHub currently reports the branch as conflicting with dev (mergeable: CONFLICTING / merge-state DIRTY).

  • PUT /pulls/3784/merge405 Pull Request has merge conflicts
  • Base dev has moved since the branch was cut; the PR touches packages/coding-agent/CHANGELOG.md (a high-churn file), so a textual conflict is expected.

Please rebase fix/status-line-jobs-hidden onto the current dev tip and push — that should clear the conflict and let CI run. The change itself was already reviewed as correct with mutation-proven tests; only the rebase is blocking the merge.

@pers0n4
pers0n4 force-pushed the fix/status-line-jobs-hidden branch 2 times, most recently from b042c6e to 64d9a1b Compare August 5, 2026 07:39

@yazzang-homelab yazzang-homelab left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Independent architect review. The code change is right; the CHANGELOG entry is in the wrong section and needs one move before this lands.

Blocking — the entry was filed into an already-released version.

On this head, packages/coding-agent/CHANGELOG.md:

32| ## [0.12.11] - 2026-08-03
34| ### Fixed
...
40| - The legacy interactive footer now uses the session manager's cumulative usage index...
41| ### Fixed          <- second heading, no blank line above
43| - Hiding the `jobs` status-line segment now also hides the background-job counter...
45| ## [0.12.10] - 2026-08-03

The new entry sits under ## [0.12.11], which shipped on 2026-08-03. It also introduces a duplicate ### Fixed heading directly against the preceding bullet with no blank line.

This is almost certainly not your doing. .gitattributes carries packages/*/CHANGELOG.md merge=union, and union never conflicts — it concatenates both sides of an overlapping hunk. Release commits insert ## [X.Y.Z] directly beneath the surviving ## [Unreleased] heading, so a branch that added entries under Unreleased overlaps exactly that region and gets silently relocated on rebase. #3929 has the reproduction and an audit finding 35 pre-existing instances on dev; #3932 removes the driver.

Fix: move the entry under ## [Unreleased] and drop the duplicate ### Fixed heading (reuse the existing one). Nothing else needs to change.

The code itself is sound. Verified:

  • jobsSegmentVisible is computed from effectiveSettings, i.e. the output of #resolveSettings(), so preset users and preset: "custom" users go through one path rather than the counter having its own placement rule.
  • Gating the count at the source rather than at the render site means the runningBackgroundJobs > 0 branch below stays untouched, so icon, color, and overflow behaviour are unchanged when the segment is visible.
  • Every bundled preset keeps jobs in rightSegments, so default output does not move. The added test pins the hidden case with an explicit rightSegments: ["cost"].
  • Rejecting a new statusLine.showBackgroundJobs setting is the right call — it would have been a second source of truth for a placement the user already expressed.

One non-blocking note: with the segment hidden, getAsyncJobSnapshot() is no longer called at all on that path. That is fine today because the call is pure, but if it ever acquires a side effect (lazy snapshot materialization, for instance) the visible and hidden paths would diverge. Worth a comment if that ever becomes a possibility.

gajae.pr-review-verdict.v1 merge-blocked sha256:64d9a1b8d35bd6fa533439418b4189d51415a505 reviewer:architect evidence:https://github.com/Yeachan-Heo/gajae-code/pull/3784/files

`#collectStatusSegments()` appended a hardcoded "N jobs running" chip to the
right group after rendering the configured segments, without consulting
`statusLine.leftSegments` / `statusLine.rightSegments`. Setting the `jobs`
segment to hidden in `/settings` removed only the monitor/cron widget, while
the async background-job counter kept rendering with the same icon and the
same `statusLineSubagents` color, so the setting looked ignored. `async.enabled`
does not help either: `isBackgroundJobSupportEnabled()` always returns true, so
the manager and the counter exist in every top-level session.

Gate the counter on the `jobs` segment placement resolved by `#resolveSettings()`,
so preset and `preset: custom` users share one code path. Every bundled preset
keeps `jobs` in `rightSegments`, so default output is unchanged.

Lore-id: 4b7e2c19
Rejected: new statusLine.showBackgroundJobs setting | duplicates the existing jobs segment placement the user already set
Confidence: high
Scope-risk: narrow
Reversibility: clean
Tested: jobs-segment suite (7); status-line-*, jobs-*, interactive-mode-status (130); biome check
Not-tested: live TUI overflow trimming when the counter is the last right-group entry
@yazzang-homelab

Copy link
Copy Markdown
Contributor

CI가 안 도는 이유를 확인했다 — 네 잘못이 아니다.

이 PR의 워크플로 런은 action_required 상태로 멈춰 있다. 즉 실행된 적이 없고, 그래서 head에 체크가 0건이다. GitHub의 포크 PR 워크플로 승인 게이트이고, 저장소 소유자가 "Approve and run workflows"를 눌러야 시작된다.

gh api "repos/Yeachan-Heo/gajae-code/actions/runs?head_sha=<이 PR head>" \
  -q ".workflow_runs[]|[.name,.status,.conclusion]|@tsv"
# -> Dev CI  completed  action_required

푸시를 더 해도 달라지지 않는다. 승인 없이는 새 런도 같은 상태로 들어간다. 같은 사유로 막힌 PR이 6건이라 #3940 으로 정리해 올렸다.

리뷰는 CI와 무관하게 진행하고 있으니 코드 피드백은 그대로 받으면 된다. 다만 이 저장소는 머지에 exact-head CI 증거를 요구하므로, 승인이 떨어지기 전까지는 머지가 불가능하다는 점만 알아두면 된다.

@Yeachan-Heo

Copy link
Copy Markdown
Owner

Closing during the emergency maintenance freeze. This PR is not in the retained critical or maintainer-owned set. Do not open a replacement PR unless a maintainer explicitly directs it.


[repo owner's gaebal-gajae (clawdbot) 🦞]

@yazzang-homelab

Copy link
Copy Markdown
Contributor

CHANGELOG 항목이 이미 릴리스된 섹션에 들어가 있다.

dev의 릴리스 구간과 이 PR head의 릴리스 구간을 비교해, 이 PR이 추가한 줄만 뽑았다(coding-agent). ## [Unreleased]가 아니라 이미 배포된 ## [X.Y.Z] 아래에 있다.

원인은 .gitattributespackages/*/CHANGELOG.md merge=union이다(오늘 11:25:32Z에 #3932로 제거됨). union은 충돌을 내지 않고 양쪽 청크를 이어붙이는데, 릴리스 커밋이 ## [X.Y.Z]를 살아남은 ## [Unreleased] 바로 아래에 삽입하기 때문에 Unreleased에 넣은 항목이 리베이스에서 새 버전 헤딩 밑으로 조용히 옮겨진다. 충돌 마커도 CI 신호도 없다. dev에서 같은 상태인 기존 항목 35건, 열린 PR 8건을 확인했다(#3929).

리베이스로는 안 풀린다 — 위치가 이미 커밋돼 있어서 직접 옮겨야 한다. 해당 줄을 잘라 ## [Unreleased] 아래로 넣으면 된다. 드라이버는 제거됐으니 한 번 옮기면 다시 움직이지 않는다.

내 PR(#3844)도 같은 상태였고 방금 고쳤다.

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.

3 participants