Skip to content

fix(kimi-code): revert the todo panel to its pre-turn state on undo - #3016

Merged
sailist merged 2 commits into
MoonshotAI:mainfrom
sailist:bug-037-08-17-undo-todo-state
Aug 18, 2026
Merged

fix(kimi-code): revert the todo panel to its pre-turn state on undo#3016
sailist merged 2 commits into
MoonshotAI:mainfrom
sailist:bug-037-08-17-undo-todo-state

Conversation

@sailist

@sailist sailist commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — the problem is explained below.

Problem

When the model updates the todo list during a turn and the user then runs /undo on that turn, the todo panel keeps showing the undone turn's items instead of reverting to the pre-turn state.

The engine already rolls the todo state back correctly (it is an undoable replayable state), but the TUI panel is a local copy fed only by TodoList tool-result events. Undo produces no new tool events, and the SDK exposed no way to read the rolled-back todo state, so the stale copy lingered on screen.

What changed

  • The SDK gains a getTodos() session read that returns the engine's current todo state. On the v2 engine it reads the live session todo state; the v1 client answers not_implemented since the legacy engine has no todo read path.
  • The /undo handler re-pulls the todo state after a successful undo and refreshes the panel, mirroring how resume hydrates it. If the read is unavailable or fails (e.g. the v1 engine), the panel is left untouched and the undo command still succeeds.
  • Tests: SDK coverage for the new read (empty state, round-trip after an engine-side write, missing-session rejection) and TUI coverage for the post-undo refresh and the degradation path, plus a test pinning the existing tool-result feed that drives the panel during normal turns.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Aug 18, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fd30311

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@moonshot-ai/kimi-code Patch
@moonshot-ai/kimi-code-sdk Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Aug 18, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@fd30311
npx https://pkg.pr.new/@moonshot-ai/kimi-code@fd30311

commit: fd30311

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4021c597fa

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/kimi-code/src/tui/commands/undo.ts Outdated
const session = host.session;
if (session === undefined) return;
try {
host.streamingUI.setTodoList(await session.getTodos());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the hidden state for completed todo lists

When the state before the undone turn contains only completed todos, the panel was empty because both turn-end handling and session replay deliberately hide all-done lists; this direct refresh instead remounts those completed items. For example, undoing a turn that changed an all-done list back to pending will restore the engine data but not the actual pre-turn panel state. Route the refreshed data through the same todo-display normalization used by replay/turn-end rather than setting the panel directly.

AGENTS.md reference: apps/kimi-code/AGENTS.md:L39-L40

Useful? React with 👍 / 👎.

*/
override async getTodos(input: SessionIdRpcInput): Promise<readonly SessionTodoItem[]> {
const session = this.requireLiveSession(input.sessionId);
return session.accessor.get(ISessionTodoService).getTodos();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Return a detached copy of the todo state

SDKRpcClientV2 is in-process, and ISessionTodoService.getTodos() returns the same array and item objects stored by IAgentStateService; therefore a JavaScript SDK consumer can mutate the result of session.getTodos() and silently alter live engine state without a durable event, change notification, or undo checkpoint. The TypeScript readonly annotations provide no runtime protection, so this method should clone the array and its items before exposing them.

Useful? React with 👍 / 👎.

@sailist
sailist merged commit 98ebda8 into MoonshotAI:main Aug 18, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant