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:
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:clide/builtin/claude/src/session_orchestrator.dart';
|
||||
@@ -12,6 +13,7 @@ class _FakeProc implements StreamJsonProcess {
|
||||
bool killed = false;
|
||||
@override
|
||||
Stream<String> get lines => _ctl.stream;
|
||||
void emit(String line) => _ctl.add(line);
|
||||
@override
|
||||
void writeLine(String line) => writes.add(line);
|
||||
@override
|
||||
@@ -41,6 +43,26 @@ void main() {
|
||||
expect(orch.byId('teammate:tyre')!.role, 'teammate:tyre');
|
||||
});
|
||||
|
||||
test('folds the real claude session id from the init event into the session (T-185)', () async {
|
||||
final m = await orch.spawn(SpawnSpec(
|
||||
id: 'fork-x',
|
||||
role: 'teammate',
|
||||
sessionId: 'placeholder-uuid',
|
||||
cwd: '/repo',
|
||||
forkSourceSessionId: 'source-uuid',
|
||||
));
|
||||
expect(m.sessionId, 'placeholder-uuid'); // starts as the placeholder
|
||||
created.last.emit(jsonEncode({
|
||||
'type': 'system',
|
||||
'subtype': 'init',
|
||||
'session_id': 'real-fork-id',
|
||||
'model': 'claude-opus-4-8',
|
||||
'permissionMode': 'default',
|
||||
}));
|
||||
await Future<void>.delayed(Duration.zero);
|
||||
expect(m.sessionId, 'real-fork-id'); // updated to the branch's real id
|
||||
});
|
||||
|
||||
test('spawn is idempotent on id — no second process', () async {
|
||||
final a = await orch.spawn(spec('primary'));
|
||||
final b = await orch.spawn(spec('primary'));
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user