Agents/jobs list: show forked sessions as a fork tree off their parent (via forkParentSessionId)
Feature request
Render forked sessions as a tree in the background agents / jobs list — forks flowing to the right of the session they were forked from, each node carrying a status sign — instead of showing them as unrelated flat rows.
Motivation
When you fork a session (e.g. claude --resume <id> --fork-session, or forking a background job), the fork inherits the parent's full conversation context. Which session a fork branched from is essential context when scanning the agents list — today that lineage is invisible: the list is flat, and the only hint is a ⑂ marker prepended to the fork's name.
The data model already records the lineage. Each job's ~/.claude/jobs/<id>/state.json contains:
{
"forkSessionId": "39368a90-...",
"forkParentSessionId": "71059e06-...",
"forkBoundaryAt": "2026-08-21T07:52:35.852Z",
"forkSourceAlive": true
}
So the model is a tree; only the view is a list. This makes it a small change: group jobs by forkParentSessionId and draw children off their parent.
Proposed rendering (horizontal fork timeline)
Forks extend rightward from their parent — depth reads as a timeline of where the work traveled — with a status sign on every node (● working, ✓ done, ⌨ waiting input, ✗ failed). Long chains scroll horizontally:
✓ done gemini models evaluation framework 71059e06 972k 7h ──⑂──▶ ✓ done gemini models eval 2 39368a90 1.3M 7h
✓ done model pinning dts-ocr 72590de6 22k 4d ──⑂──▶ ✓ done plan for fine tuning gemma… 73adbd22 21k 4d
● working tree view agent forks 524f87c2 21k 1m
When a session has several forks, it branches with aligned rails:
✓ done root ─┬─⑂──▶ ✓ done fork A ─┬─⑂──▶ ● working fork A.1
│ └─⑂──▶ ✓ done fork A.2
└─⑂──▶ ✗ failed fork B
Alternative: vertical indent
✓ gemini models evaluation framework 71059e06 972k tok 7h ago
└─ ✓ ⑂ gemini models eval 2 39368a90 1.3M tok 7h ago
- Depth in the tree = context lineage (a fork of a fork extends one more hop).
- If the fork parent isn't in the list (e.g. an interactive session that never ran as a job), show a dimmed placeholder parent or fall back to the current flat row with the
⑂marker. - Sorting: roots by recency as today; children off their parent.
Prior art / workaround
I prototyped both layouts as an external script reading jobs/*/state.json; it reconstructs the tree correctly from existing on-disk data — no new state is needed, only a view change.
Related: interactive sessions forked with --fork-session don't appear to persist forkParentSessionId anywhere (the transcript is copied with the new session ID). Recording the parent ID for those as well would let the resume picker show the same lineage.