consume the fork source on first bind (T-375)

widget.forkSourceId took precedence over the fresh/resume logic on
EVERY (re)bind, so /clear in a fork pane re-forked the original
conversation instead of clearing, and /resume re-forked the same way.
The source is now copied into one-shot pane state and cleared after
the first successful fork spawn; later respawns operate on the pane's
own session.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 01:11:17 +02:00
co-authored by Claude Fable 5
parent 51957eb0ac
commit bbc6899df2
5 changed files with 43 additions and 1 deletions
+17
View File
@@ -52,15 +52,18 @@ void main() {
late ClaudeSessionOrchestrator orch;
late String root;
final created = <_FakeProc>[];
final spawnArgs = <List<String>>[];
setUp(() async {
f = await KernelFixture.create();
created.clear();
spawnArgs.clear();
root = '/repo-a';
orch = ClaudeSessionOrchestrator(
processFactory: ({required sessionArgs, required cwd, env}) async {
final p = _FakeProc();
created.add(p);
spawnArgs.add(sessionArgs);
return p;
},
);
@@ -175,6 +178,20 @@ void main() {
expect(orch.byId('primary')!.sessionId, id);
});
testWidgets('/clear in a fork pane clears instead of re-forking (T-375)', (tester) async {
await mount(tester, const ClaudePane(showChrome: false, isPrimary: false, secondaryIndex: 1, forkSourceId: 'source-session-uuid'));
// First bind forks from the source.
expect(spawnArgs.single, containsAll(['--fork-session', 'source-session-uuid']));
await act(tester, () => composer(tester).onSubmit('/clear'));
// The respawn must NOT fork the original again — the fork source is a
// one-shot spawn parameter consumed by the first bind.
expect(spawnArgs, hasLength(2));
expect(spawnArgs.last, isNot(contains('--fork-session')));
expect(spawnArgs.last, isNot(contains('source-session-uuid')));
});
testWidgets('/fork delegates to the onFork callback with the session id', (tester) async {
String? forkedWith;
await mount(tester, ClaudePane(showChrome: false, onFork: (sid) => forkedWith = sid));