Skip to content

feat(cli): add sticky todo panel to app layouts#3507

Merged
wenshao merged 2 commits into
QwenLM:mainfrom
shenyankm:sheny/feat-cli-sticky-todo-panel
Apr 26, 2026
Merged

feat(cli): add sticky todo panel to app layouts#3507
wenshao merged 2 commits into
QwenLM:mainfrom
shenyankm:sheny/feat-cli-sticky-todo-panel

Conversation

@shenyankm

Copy link
Copy Markdown
Contributor

TLDR

This PR adds a sticky todo panel to the CLI so the latest task list stays visible while the conversation continues.

It addresses the request in #2987 by making task progress easier to track without scrolling back through prior output.

Screenshots / Video Demo

1 2 3

Dive Deeper

This change introduces a dedicated sticky todo rendering path in the CLI UI.

Key points:

  • derive the latest todo snapshot from history and pending tool results
  • render the sticky todo panel in both the default layout and the screen-reader layout
  • hide the panel when dialogs are visible
  • hide the panel while the UI is waiting for confirmation
  • preserve original task numbering while reordering items by status priority
  • add focused tests for todo snapshot extraction, sticky panel rendering, and the updated UIState fixture shape

Reviewer Test Plan

  1. Run the targeted tests:

    • cd packages/cli
    • npx vitest run src/ui/App.test.tsx src/ui/layouts/DefaultAppLayout.test.tsx src/ui/layouts/ScreenReaderAppLayout.test.tsx src/ui/components/StickyTodoList.test.tsx src/ui/utils/todoSnapshot.test.ts
  2. Build the CLI:

    • npm run build
  3. Manually verify the behavior in the CLI:

    • start the app
    • use a prompt that causes the model to create or update a todo list
    • confirm the latest todo snapshot appears above the composer
    • confirm the panel updates as task statuses change
    • confirm the panel is hidden when a dialog is open
    • confirm the panel is hidden while waiting for confirmation

Example prompt:

  • Create a todo list with three implementation steps, mark one step in progress, and continue updating it while you work.

Testing Matrix

🍏 🪟 🐧
npm run
npx
Docker
Podman - -
Seatbelt - -

Linked issues / bugs

Closes #2987

wenshao
wenshao previously approved these changes Apr 24, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review

@wenshao

wenshao commented Apr 24, 2026

Copy link
Copy Markdown
Collaborator

Hi @shenyankm, this PR currently has merge conflicts with main. Could you please rebase or merge the latest main to resolve them? Thanks!

@shenyankm

Copy link
Copy Markdown
Contributor Author

Hi @shenyankm, this PR currently has merge conflicts with main. Could you please rebase or merge the latest main to resolve them? Thanks!

Okay, please wait a moment.

wenshao
wenshao previously approved these changes Apr 24, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review

@wenshao

wenshao commented Apr 24, 2026

Copy link
Copy Markdown
Collaborator

This PR currently has merge conflicts. Please resolve the conflicts with the latest main branch so the review and checks can proceed cleanly.

wenshao
wenshao previously approved these changes Apr 25, 2026

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review

@wenshao wenshao requested a review from LaZzyMan April 25, 2026 03:07
@wenshao

wenshao commented Apr 25, 2026

Copy link
Copy Markdown
Collaborator

@shenyankm This PR is approved and ready to merge — the only remaining blocker is the merge conflict with main (mergeStateStatus: DIRTY). Recent merges to main touched the App / layout code paths (PR #3591 TUI flicker fixes and PR #3605 session preview), which is likely where the conflict comes from.

Could you rebase onto the latest main and force-push when you have a moment? Once it's clean again I'll merge it.

@shenyankm shenyankm force-pushed the sheny/feat-cli-sticky-todo-panel branch from 3910fc8 to e74ade8 Compare April 25, 2026 15:42
@shenyankm shenyankm requested a review from wenshao April 25, 2026 16:03
const hasAgents = agents.size > 0;
const isAgentTab = activeView !== 'main' && agents.has(activeView);
const stickyTodoWidth = Math.min(uiState.mainAreaWidth, 64);
const shouldShowStickyTodos =

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[Suggestion] The sticky todo visibility predicate hides the panel for dialogsVisible and WaitingForConfirmation, but it does not account for uiState.isFeedbackDialogOpen. The feedback dialog is rendered inside Composer, not through DialogManager, so dialogsVisible remains false and the sticky todo panel can stay visible above the feedback dialog, stealing vertical space and visually competing with it. The same condition should also be reflected in the AppContainer measurement predicate and screen-reader layout if this predicate is centralized.

Suggested change
const shouldShowStickyTodos =
const shouldShowStickyTodos =
uiState.stickyTodos !== null &&
!uiState.dialogsVisible &&
!uiState.isFeedbackDialogOpen &&
uiState.streamingState !== StreamingState.WaitingForConfirmation;

— gpt-5.5 via Qwen Code /review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the suggestion. I’ve addressed it in 654930c by hiding the sticky todo panel when uiState.isFeedbackDialogOpen is true, and kept the AppContainer measurement predicate and both default/screen-reader layouts consistent. CI is green now. Could you please re-review when convenient?

@wenshao wenshao left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No issues found. LGTM! ✅ — gpt-5.5 via Qwen Code /review

@wenshao

wenshao commented Apr 26, 2026

Copy link
Copy Markdown
Collaborator

Verified the sticky todo behavior locally with npm run dev in a tmux session — all the documented behaviors check out:

  • Panel renders above the composer once todo_write is called
  • Status changes propagate to the panel immediately
  • Tasks are reordered by status priority (in_progress → pending → completed) while their original numbering is preserved
  • Panel is hidden when a modal dialog (e.g. /settings) is open and reappears when the dialog closes

Squashing in. Thanks for the contribution!

@wenshao wenshao merged commit eea4e10 into QwenLM:main Apr 26, 2026
13 checks passed
@shenyankm shenyankm deleted the sheny/feat-cli-sticky-todo-panel branch April 26, 2026 05:36
@yiliang114

Copy link
Copy Markdown
Collaborator

I did one extra manual check around the sticky todo panel and noticed a layout edge case.

1. Long todo lists in a small terminal

When the todo list contains many long items, the sticky panel can take a large amount of vertical space after the terminal is narrowed or resized.

image

2. Question about when the sticky panel should appear

One related design question: should the sticky panel always appear whenever a todo snapshot exists, or should it only appear once the original TodoWrite result is no longer visible?

In some cases, the original todo list may still be visible in the conversation, while the sticky Current tasks panel also appears above the composer. That can feel a little duplicative, especially since the feature is enabled by default.

Not sure this needs to block the current change, but it may be worth considering whether the sticky panel should be more viewport-aware or more compact.

@shenyankm

Copy link
Copy Markdown
Contributor Author

I did one extra manual check around the sticky todo panel and noticed a layout edge case.

1. Long todo lists in a small terminal

When the todo list contains many long items, the sticky panel can take a large amount of vertical space after the terminal is narrowed or resized.

image ### 2. Question about when the sticky panel should appear One related design question: should the sticky panel always appear whenever a todo snapshot exists, or should it only appear once the original `TodoWrite` result is no longer visible?

In some cases, the original todo list may still be visible in the conversation, while the sticky Current tasks panel also appears above the composer. That can feel a little duplicative, especially since the feature is enabled by default.

Not sure this needs to block the current change, but it may be worth considering whether the sticky panel should be more viewport-aware or more compact.

Thanks for the extra check. Good catch.

I agree this is a valid UX edge case for small terminals and long todo lists. I’ll look into it and update this tomorrow (2026-04-27), probably by making the sticky panel more compact / viewport-aware.

xaelistic pushed a commit to xaelistic/qwen-code that referenced this pull request Jun 7, 2026
xaelistic pushed a commit to xaelistic/qwen-code that referenced this pull request Jun 7, 2026
* feat(cli): add sticky todo panel to app layouts

* fix(cli): hide sticky todos during feedback dialog
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.

建议在cli界面加入todo任务列表

3 participants