MoonshotAI / MoonshotAI/kimi-code

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

Open
#3,250 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

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)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in mapLegacyWireEvent in the VS Code extension and compare its TodoList handling with packages/agent-core-v2/src/agent/tools/todo-list/todoListTool.ts and the v1 tool. Reproduce the blank card, then use the wire tools.update_store records and the webview SetTodoList renderer to verify the chosen data path. Done means TodoList cards show titles and pending, in_progress, and done statuses without changing other tool output; node --check passes.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vscode
Domain
desktop, frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.