capture a forked session's real id from its init event

A --fork-session branch is spawned without --session-id, so claude mints
a new session id that only arrives in the init event; the ManagedSession
was left holding its placeholder. StreamJsonSession now captures
session_id from the first event that carries it and exposes it via
claudeSessionId / sessionIdResolved; the orchestrator folds that back into
ManagedSession.sessionId (idempotent for normal sessions). A fork can now
itself be resumed or forked.

T-185.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-31 12:21:56 +02:00
co-authored by Claude
parent d0ad8ed4aa
commit e866da9fd8
7 changed files with 79 additions and 4 deletions
@@ -206,6 +206,21 @@ void main() {
expect(statuses, hasLength(1));
});
test('captures the claude session id from the first event carrying it (T-185)', () async {
final ids = <String>[];
session.sessionIdResolved.listen(ids.add);
proc.emit(jsonEncode({
'type': 'system',
'subtype': 'init',
'session_id': 'sess-abc',
'model': 'claude-opus-4-7',
'permissionMode': 'default',
}));
await Future<void>.delayed(Duration.zero);
expect(session.claudeSessionId, 'sess-abc');
expect(ids, ['sess-abc']);
});
group('live cost/context from result events (T-168)', () {
test('result event with total_cost_usd populates cost field', () async {
proc.emit(resultEvent(cost: 0.042));