diff --git a/.changeset/fork-completed-agent-sessions.md b/.changeset/fork-completed-agent-sessions.md new file mode 100644 index 00000000000..9a406045a80 --- /dev/null +++ b/.changeset/fork-completed-agent-sessions.md @@ -0,0 +1,5 @@ +--- +"kilo-code": minor +--- + +Add a Fork Session button to completed Agent Manager sessions. diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png new file mode 100644 index 00000000000..0fd5ad4f06d --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/chat-view-agent-manager-completed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba55764c944231be2cd47c839d3a46c4bbdcb0a3060a1d8aa3ed7d391a34d722 +size 14749 diff --git a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx index 95f54955e8e..7853241b614 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/AgentManagerApp.tsx @@ -2999,6 +2999,7 @@ const AgentManagerContent: Component = () => { }} onShowHistory={() => setHistory(true)} onForkMessage={readOnly() ? undefined : handleForkSession} + onForkSession={readOnly() ? undefined : handleForkSession} readonly={readOnly()} continueInWorktree={selection() === LOCAL} promptBoxId={`agent-manager:${selection() ?? "unassigned"}`} diff --git a/packages/kilo-vscode/webview-ui/agent-manager/sortable-tab.tsx b/packages/kilo-vscode/webview-ui/agent-manager/sortable-tab.tsx index b091952f615..6d5a8393377 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/sortable-tab.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/sortable-tab.tsx @@ -114,7 +114,7 @@ export const SortableTab: Component<{ props.onFork?.()}> - + {t("agentManager.tab.forkSession")} diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx index 3dc6c7b794b..a0d09a9a629 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx @@ -28,6 +28,7 @@ interface ChatViewProps { onSelectSession?: (id: string) => void onShowHistory?: () => void onForkMessage?: (sessionId: string, messageId: string) => void + onForkSession?: (sessionId: string) => void readonly?: boolean /** When true, show the "Continue in Worktree" button. Defaults to true in the sidebar. */ continueInWorktree?: boolean @@ -129,6 +130,12 @@ export const ChatView: Component = (props) => { const startSession = () => window.dispatchEvent(new CustomEvent("newTaskRequest")) + const fork = () => { + const sid = id() + if (!sid) return + props.onForkSession?.(sid) + } + const startWorktree = () => vscode.postMessage({ type: "agentManager.createWorktree" }) const startWorktreeFromBranch = () => @@ -181,11 +188,14 @@ export const ChatView: Component = (props) => { const canStartSession = (hasChat: boolean) => hasChat + const canFork = (hasChat: boolean) => hasChat && !isSidebar() && session.status() === "idle" && !!props.onForkSession + const canStartWorktree = () => isSidebar() && server.gitInstalled() const canMoveToWorktree = (hasChat: boolean) => hasChat && canContinueInWorktree() && server.gitInstalled() - const hasActions = (hasChat: boolean) => canStartSession(hasChat) || canStartWorktree() || canMoveToWorktree(hasChat) + const hasActions = (hasChat: boolean) => + canStartSession(hasChat) || canFork(hasChat) || canStartWorktree() || canMoveToWorktree(hasChat) const renderActions = (hasChat: boolean) => ( @@ -204,6 +214,19 @@ export const ChatView: Component = (props) => { + + + + +
diff --git a/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx index c259d71b826..cdc7006d904 100644 --- a/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx +++ b/packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx @@ -19,6 +19,7 @@ import { MessageList } from "../components/chat/MessageList" import { TurnOutcome } from "../components/shared/TurnOutcome" import { SessionContext } from "../context/session" import { ServerContext } from "../context/server" +import { WorktreeModeProvider } from "../context/worktree-mode" import type { Message, Part, QuestionRequest, SuggestionRequest, TodoItem } from "../types/messages" const SESSION_ID = "story-session-chat-001" @@ -149,6 +150,30 @@ export const ChatViewWithMessages: Story = { }, } +export const ChatViewAgentManagerCompleted: Story = { + name: "ChatView — completed Agent Manager session actions", + render: () => { + const session = { + ...mockSessionValue({ id: SESSION_ID, status: "idle", closeReason: "completed" }), + messages: () => [{ id: "msg-001" }] as any[], + worktreeStats: () => ({ files: 2, additions: 12, deletions: 4 }), + } + return ( + + + + +
+ undefined} continueInWorktree /> +
+
+
+
+
+ ) + }, +} + /** * ChatView with a pending question tool call and an empty input. *