From 284f80995ea978ade80da9af4c96e8ee9a52b20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Can=20B=C3=B6l=C3=BCk?= Date: Wed, 28 Jan 2026 01:45:34 +0100 Subject: [PATCH] fix(coding-agent): guarded fork during streaming - Blocked /fork while streaming to avoid split session logs. - Preserved queued and next-turn messages when forking. --- .../coding-agent/src/modes/controllers/command-controller.ts | 4 ++++ packages/coding-agent/src/modes/interactive-mode.ts | 2 ++ packages/coding-agent/src/session/agent-session.ts | 5 ----- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/coding-agent/src/modes/controllers/command-controller.ts b/packages/coding-agent/src/modes/controllers/command-controller.ts index aa64cd50f..7dbb25a83 100644 --- a/packages/coding-agent/src/modes/controllers/command-controller.ts +++ b/packages/coding-agent/src/modes/controllers/command-controller.ts @@ -419,6 +419,10 @@ export class CommandController { } async handleForkCommand(): Promise { + if (this.ctx.session.isStreaming) { + this.ctx.showWarning("Wait for the current response to finish or abort it before forking."); + return; + } if (this.ctx.loadingAnimation) { this.ctx.loadingAnimation.stop(); this.ctx.loadingAnimation = undefined; diff --git a/packages/coding-agent/src/modes/interactive-mode.ts b/packages/coding-agent/src/modes/interactive-mode.ts index a3d82d701..506aec73a 100644 --- a/packages/coding-agent/src/modes/interactive-mode.ts +++ b/packages/coding-agent/src/modes/interactive-mode.ts @@ -212,11 +212,13 @@ export class InteractiveMode implements InteractiveModeContext { { name: "login", description: "Login with OAuth provider" }, { name: "logout", description: "Logout from OAuth provider" }, { name: "new", description: "Start a new session" }, + { name: "fork", description: "Duplicate current session into a new session" }, { name: "compact", description: "Manually compact the session context" }, { name: "handoff", description: "Hand off the session context to a new session" }, { name: "background", description: "Detach UI and continue running in background" }, { name: "bg", description: "Alias for /background" }, { name: "resume", description: "Resume a different session" }, + { name: "debug", description: "Write debug log (TUI state and messages)" }, { name: "exit", description: "Exit the application" }, ]; diff --git a/packages/coding-agent/src/session/agent-session.ts b/packages/coding-agent/src/session/agent-session.ts index 15d43abb6..d69076aa3 100644 --- a/packages/coding-agent/src/session/agent-session.ts +++ b/packages/coding-agent/src/session/agent-session.ts @@ -1710,11 +1710,6 @@ export class AgentSession { // Update agent session ID this.agent.sessionId = this.sessionManager.getSessionId(); - // Clear queued messages (they would be duplicated otherwise) - this._steeringMessages = []; - this._followUpMessages = []; - this._pendingNextTurnMessages = []; - // Emit session_switch event with reason "fork" to hooks if (this._extensionRunner) { await this._extensionRunner.emit({