seed resumed Claude session from the transcript tail

claude --resume keeps the model's prior context but emits no past
turns over stream-json, so the pane was visually empty until the
user sent a new prompt. The orchestrator now reads the last 256 KB
of the on-disk transcript JSONL when SpawnSpec.resume is true and
seeds the ConversationController with the parsed items before the
stream subscription starts. Best-effort: missing or unreadable file
just falls back to the previous empty-pane behaviour.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jeroen Schweitzer
2026-05-28 10:17:32 +02:00
co-authored by Claude
parent 762d66e819
commit 6e4c3c4bf4
5 changed files with 112 additions and 4 deletions
@@ -15,13 +15,18 @@ import 'package:clide/kernel/src/events/message_bus.dart';
import 'package:flutter/foundation.dart';
class ConversationController extends ChangeNotifier {
/// Listens to [stream] and accumulates items. [onDispose] is invoked
/// from [dispose] — wire it to the reader's `dispose` so cancelling
/// the view tears down the underlying tail.
/// Listens to [stream] and accumulates items. [seed] pre-populates the
/// item list synchronously before subscribing — used when resuming a
/// session (D-77), where `claude --resume` doesn't replay prior turns
/// over stream-json so the pane would otherwise start empty. [onDispose]
/// is invoked from [dispose] — wire it to the reader's `dispose` so
/// cancelling the view tears down the underlying tail.
ConversationController({
required Stream<ConversationItem> stream,
Iterable<ConversationItem>? seed,
Future<void> Function()? onDispose,
}) : _onDispose = onDispose {
if (seed != null) _items.addAll(seed);
_sub = stream.listen(_onItem);
}