refactor: remove todo tool (#35989)

This commit is contained in:
Aiden Cline 2026-07-09 00:13:48 -05:00 committed by GitHub
commit 7feefb697f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
250 changed files with 237 additions and 4755 deletions

View file

@ -1,32 +0,0 @@
import { useTheme } from "../context/theme"
export interface TodoItemProps {
status: string
content: string
}
export function TodoItem(props: TodoItemProps) {
const { theme } = useTheme()
return (
<box flexDirection="row" gap={0}>
<text
flexShrink={0}
style={{
fg: props.status === "in_progress" ? theme.warning : theme.textMuted,
}}
>
[{props.status === "completed" ? "✓" : props.status === "in_progress" ? "•" : " "}]{" "}
</text>
<text
flexGrow={1}
wrapMode="word"
style={{
fg: props.status === "in_progress" ? theme.warning : theme.textMuted,
}}
>
{props.content}
</text>
</box>
)
}

View file

@ -16,7 +16,6 @@ import type {
QuestionRequest,
Session,
FileDiffInfo,
Todo,
VcsInfo,
} from "@opencode-ai/sdk/v2"
import { createStore } from "solid-js/store"
@ -50,7 +49,6 @@ export const {
config: Config
session: Session[]
session_diff: Record<string, FileDiffInfo[]>
todo: Record<string, Todo[]>
message: Record<string, Message[]>
part: Record<string, Part[]>
lsp: LspStatus[]
@ -76,7 +74,6 @@ export const {
config: {},
session: [],
session_diff: {},
todo: {},
message: {},
part: {},
lsp: [],

View file

@ -7,7 +7,6 @@ import SidebarFiles from "./sidebar/files"
import SidebarFooter from "./sidebar/footer"
import SidebarLsp from "./sidebar/lsp"
import SidebarMcp from "./sidebar/mcp"
import SidebarTodo from "./sidebar/todo"
import DiffViewer from "./system/diff-viewer"
import Notifications from "./system/notifications"
import PluginManager from "./system/plugins"
@ -27,7 +26,6 @@ export function createBuiltinPlugins(): BuiltinTuiPlugin[] {
SidebarContext,
SidebarMcp,
SidebarLsp,
SidebarTodo,
SidebarFiles,
SidebarFooter,
Notifications,

View file

@ -1,49 +0,0 @@
import type { TuiPlugin, TuiPluginApi } from "@opencode-ai/plugin/tui"
import type { BuiltinTuiPlugin } from "../builtins"
import { createMemo, For, Show, createSignal } from "solid-js"
import { TodoItem } from "../../component/todo-item"
const id = "internal:sidebar-todo"
function View(props: { api: TuiPluginApi; session_id: string }) {
const [open, setOpen] = createSignal(true)
const theme = () => props.api.theme.current
const list = createMemo(() => props.api.state.session.todo(props.session_id))
const show = createMemo(() => list().length > 0 && list().some((item) => item.status !== "completed"))
return (
<Show when={show()}>
<box>
<box flexDirection="row" gap={1} onMouseDown={() => list().length > 2 && setOpen((x) => !x)}>
<Show when={list().length > 2}>
<text fg={theme().text}>{open() ? "▼" : "▶"}</text>
</Show>
<text fg={theme().text}>
<b>Todo</b>
</text>
</box>
<Show when={list().length <= 2 || open()}>
<For each={list()}>{(item) => <TodoItem status={item.status} content={item.content} />}</For>
</Show>
</box>
</Show>
)
}
const tui: TuiPlugin = async (api) => {
api.slots.register({
order: 400,
slots: {
sidebar_content(_ctx, props) {
return <View api={api} session_id={props.session_id} />
},
},
})
}
const plugin: BuiltinTuiPlugin = {
id,
tui,
}
export default plugin

View file

@ -130,9 +130,6 @@ function stateApi(sync: ReturnType<typeof useSync>, data: ReturnType<typeof useD
item.file === undefined ? [] : [{ ...item, file: item.file }],
)
},
todo(sessionID) {
return sync.data.todo[sessionID] ?? []
},
messages(sessionID) {
return sync.data.message[sessionID] ?? []
},

View file

@ -45,7 +45,6 @@ import { useEditorContext } from "../../context/editor"
import { openEditor } from "../../editor"
import { useDialog } from "../../ui/dialog"
import { DialogSessionRename } from "../../component/dialog-session-rename"
import { TodoItem } from "../../component/todo-item"
import { DialogMessage } from "./dialog-message"
import { DialogFork } from "./dialog-fork"
import { Sidebar } from "./sidebar"
@ -1934,9 +1933,6 @@ function ToolPart(props: { part: SessionMessageAssistantTool }) {
<Match when={display() === "patch"}>
<ApplyPatch {...toolprops} />
</Match>
<Match when={display() === "todowrite"}>
<TodoWrite {...toolprops} />
</Match>
<Match when={display() === "question"}>
<Question {...toolprops} />
</Match>
@ -2636,32 +2632,6 @@ function ApplyPatch(props: ToolProps) {
)
}
function TodoWrite(props: ToolProps) {
const todos = createMemo(() => parseTodos(props.input.todos))
return (
<Switch>
<Match when={parseTodos(props.metadata.todos).length}>
<BlockTool title="# Todos" part={props.part}>
<box>
<For each={todos()}>{(todo) => <TodoItem status={todo.status} content={todo.content} />}</For>
</box>
</BlockTool>
</Match>
<Match when={true}>
<InlineTool
icon="⚙"
pending="Updating todos..."
failure="Todo update failed"
complete={false}
part={props.part}
>
Updating todos...
</InlineTool>
</Match>
</Switch>
)
}
function Question(props: ToolProps) {
const { theme } = useTheme()
const questions = createMemo(() => parseQuestions(props.input.questions))
@ -2762,7 +2732,6 @@ const toolDisplays = new Set([
"subagent",
"execute",
"patch",
"todowrite",
"question",
"skill",
])
@ -2844,16 +2813,6 @@ export function parseApplyPatchFiles(value: unknown) {
})
}
export function parseTodos(value: unknown) {
if (!Array.isArray(value)) return []
return value.flatMap((item) => {
const todo = recordValue(item)
const status = stringValue(todo?.status)
const content = stringValue(todo?.content)
return status && content ? [{ status, content }] : []
})
}
export function parseQuestions(value: unknown) {
if (!Array.isArray(value)) return []
return value.flatMap((item) => {