Skip to content

VS Code extension: TodoList tool card renders blank — v2 TodoListTool no longer emits display, webview renderer still requires result.display #3250

Description

@mozhi012

What version of Kimi Code is running?

VS Code extension 0.7.0 (moonshot-ai.kimi-code-0.7.0-win32-x64), paired with the latest CLI at time of testing

Which open platform/subscription were you using?

Kimi Code (managed provider, OAuth /login). Bug is in the extension UI layer, independent of provider/subscription.

Which model were you using?

Any (rendering-layer bug, reproduces regardless of model; tested with a local model proxied via claude-code-router)

What platform is your computer?

Microsoft Windows NT 10.0.19044.0 x64

What issue are you seeing?

In the VS Code extension chat panel, every TodoList tool-call card renders blank when expanded: no todo items, no status indicators — only a small dim "Todo list updated" line. The tool itself works correctly (state changes are reflected in subsequent system reminders), only the webview card is empty.

Root cause, traced through the shipped dist/extension.js + dist/webview.js of 0.7.0:

  1. Wire records carry no structured todo data. In agents/main/wire.jsonl:

    • tool.call: {name:"TodoList", args:{todos:[...]}} — no display, no description
    • tool.result: {result:{output:"Todo list updated.\nCurrent todo list:\n [in_progress] …"}} — plain text only
    • The structured todo state is only carried by separate tools.update_store events with key:"todo" and value:[{title,status}].
  2. v2 TodoListTool dropped the display field. packages/agent-core-v2/src/agent/tools/todo-list/todoListTool.tsresolveExecution returns only {description, approvalRule, execute} and execute() returns {isError, output}. The v1 tool (packages/agent-core/src/tools/builtin/state/todo-list.ts) used to return display: {kind:"todo_list", items:[...]} on every call. The v2 loop also writes tool.call records without display.

  3. The extension's legacy bridge never populates display for TodoList. mapLegacyWireEvent (with toLegacyToolName mapping TodoListSetTodoList) builds ToolResult.return_value.display from the tool.call.started event's display field, which is undefined for TodoList, so the webview receives display: []. Nothing consumes the tools.update_store (key:"todo") records to fill it in.

  4. The webview renderer only reads display. The dedicated case "SetTodoList" renderer looks for a {type:"todo", items:[{title,status}]} block in result.display and falls back to the dim "Todo list updated" line when empty; the output text is ignored.

Net effect: the v1 → v2 migration left the VS Code chat-panel tool card without its data source.

What steps can reproduce the bug?

  1. Install VS Code extension Kimi Code 0.7.0.
  2. Start any session and have the agent call TodoList (e.g. ask it to plan a multi-step task).
  3. Expand the TodoList tool card in the chat panel.

Actual: the card is blank / shows only a dim "Todo list updated" line.

The underlying state is correct: wire.jsonl shows proper tools.update_store events (key:"todo"), and the CLI-side todo reminders reflect the list — only the VS Code card rendering is broken.

What is the expected behavior?

The TodoList tool card renders the current items with status indicators (pending / in_progress / done), as the v1-based UI did. The structured data is already on the wire (tools.update_store, key:"todo"), so the fix belongs on the extension/rendering side.

Additional information

Workaround verified locally — patch in dist/extension.js, mapLegacyWireEventcase "tool.result": when display is empty and the output matches the TodoList render format, rebuild the legacy block from the text:

if (display.length === 0 && typeof output === "string" && (output.includes("Current todo list:") || output.includes("Todo list cleared."))) {
	const items = [];
	for (const line of output.split("\n")) {
		const m = line.match(/^\s*\[(in_progress|done|pending)\]\s+(.+?)\s*$/);
		if (m) items.push({ title: m[2], status: m[1] });
	}
	display = [{ type: "todo", items }];
}

With this patch the card renders items and statuses correctly (verified for write / query / clear, and that non-TodoList output is untouched). node --check passes.

Cleaner upstream fix options:

  • restore display: {kind:"todo_list", items} in the v2 TodoListTool (v1 parity), or
  • have the extension bridge materialize display from the tools.update_store (key:"todo") records when mapping ToolResult for TodoList.

Related: #3248 (another v1→v2 migration rendering gap in the same extension, reported by me).

Happy to submit a PR once a direction is confirmed.

Contribution

  • I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions