feat(vscode): refine timeline step details UX#12256
feat(vscode): refine timeline step details UX#12256sylwester-liljegren wants to merge 8 commits into
Conversation
Introduces authoritative step timing in the session schema and implements visual dividers in the task timeline to clearly separate activity steps. - Update `StepStartPart` and `StepFinishPart` schemas to include `time` metadata (start/end timestamps). - Implement `withDividers` logic in `TaskTimeline` to inject visual separators after step-finish events. - Update timeline geometry calculations to support divider positioning. - Add detailed step information view in the task header. - Update session processor to capture and attach step timing to parts.
Introduces authoritative step timing in the session schema and implements visual dividers in the task timeline to clearly separate activity steps. - Update `StepStartPart` and `StepFinishPart` schemas to include `time` metadata (start/end timestamps). - Implement `withDividers` logic in `TaskTimeline` to inject visual separators after step-finish events. - Update timeline geometry calculations to support divider positioning. - Add detailed step information view in the task header. - Update session processor to capture and attach step timing to parts.
| // kilocode_change start - authoritative step timing for the activity timeline | ||
| time: { | ||
| start: ctx.stepStartAt || Date.now(), | ||
| end: Date.now(), |
There was a problem hiding this comment.
WARNING: time.end includes unrelated post-step work, inflating the recorded step duration
end: Date.now() is captured here, after completedSnapshot tracking, finishReasoning, usage/model computation, KiloSessionProcessor.trackStep, the v2 event mirror publish, and reconcile() (which does an async DB round-trip via MessageV2.get). This makes the timeline's authoritative step duration include several unrelated async operations rather than just the LLM step itself, and it will be inconsistent with the elapsed value computed earlier (line 854) for telemetry on the very same step. Consider capturing end immediately when the step-finish event is received, before the snapshot/reconcile work runs.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| if (!ref || !["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return | ||
| e.preventDefault() | ||
| const idx = navigate(selected(), bars().length, e.key) | ||
| const idx = navigate(selected(), items().length, e.key) |
There was a problem hiding this comment.
WARNING: No keyboard path to open the new bar context menu / "Step details" action
onKeyDown (this function) only wires Enter/Space to select() (jump-to-part) and arrow/Home/End to navigation. The new left-click menu (openMenuAt, opened via onPointerUp for a non-dragged left click) has no keyboard equivalent, so "Step details" is unreachable from the keyboard — only mouse users can open it. Consider adding a keyboard shortcut (e.g. a dedicated key, or Shift+Enter) that calls openMenuAt for the currently selected bar.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| font-size: var(--kilo-font-size-13); | ||
| } | ||
|
|
||
| .task-timeline-detail-badge { |
There was a problem hiding this comment.
SUGGESTION: Unused CSS selectors added by this PR
.task-timeline-detail-badge (262), .task-timeline-detail-meta (271), .task-timeline-detail-value (276), .task-timeline-detail-block (282), .task-timeline-detail-label (286), and .task-timeline-detail-pre (292) aren't referenced anywhere in webview-ui/src — the step details dialog in TaskTimeline.tsx only renders .task-timeline-detail, -summary, -body, -summary-body, -grid, -tokens, -token-label, and -token-line. These look like leftovers from an earlier iteration of the dialog. Consider removing the unused rules.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
| }) | ||
|
|
||
| it("renders slim dividers and hides the trailing one while idle", () => { | ||
| expect(src).toMatch(/function withDividers\(bars: TimelineBar\[], ends: string\[], tail: boolean\)/) |
There was a problem hiding this comment.
SUGGESTION: New tests assert on source text instead of exercising real behavior
The two new tests ("renders slim dividers and hides the trailing one while idle", "opens a context menu on right-clicked bars") use readFileSync + regex toMatch against the component's source string rather than calling withDividers, rendering the component, or dispatching real events and asserting on the resulting output. They'll pass unchanged even if the actual divider placement or menu logic is wrong, and will fail on purely cosmetic refactors that don't change behavior — this runs against the repo convention that "tests MUST test actual implementation, do not duplicate logic into a test." Consider testing withDividers directly with sample bars/ends/tail input and asserting on the resulting array, and/or rendering TaskTimeline to assert the menu opens with real DOM state.
Reply with @kilocode-bot fix it to have Kilo Code address this issue.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge This is an incremental review at Files Reviewed (12 files)
Previous Review Summaries (2 snapshots, latest commit 3f6fe3f)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 3f6fe3f)Status: No Issues Found | Recommendation: Merge All 4 previously reported issues in this PR have been fixed in the latest commit:
No new issues found in the incremental diff. Files Reviewed (7 files)
Previous review (commit 0b6d8ee)Status: 4 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (28 files)
Reviewed by claude-sonnet-5 · Input: 62 · Output: 14.5K · Cached: 1.8M Review guidance: REVIEW.md from base branch |
|
Addressed the Kilo Code Review feedback in
Local validation run after fixes:
|
# Conflicts: # packages/kilo-vscode/webview-ui/src/stories/chat.stories.tsx # packages/opencode/src/session/processor.ts
Issue
No linked issue. This is a self-contained UX improvement for the task timeline and step details experience.
Fixes # (exception: no dedicated issue exists for this follow-up UX work)
Context
The task timeline currently compresses an entire assistant session into a compact row of activity bars. That works for quick navigation, but it becomes hard to understand where one assistant step ends and the next begins, especially in longer sessions with reasoning, tool calls, and final text responses.
This PR makes the timeline step-aware. The CLI records authoritative start/end timestamps on step boundary parts, and the VS Code webview uses those markers to visually separate steps, expose step-level metadata, and make bar actions more explicit.
The intended product behavior is:
Implementation
The backend/session data now includes authoritative timing for step boundaries:
step-startparts carry atime.starttimestamp.step-finishparts carrytime.startandtime.endtimestamps.step-finishis received, before snapshot/reconcile/event-publishing work, so recorded duration does not include unrelated post-step processing.The timeline rendering now treats step markers as metadata, not ordinary visible activity bars:
step-startandstep-finishare retained while building step metadata.Timeline interactions are explicit and keyboard-accessible:
Go to partandStep details.Go to partscrolls the chat transcript to the referenced message part.Step detailsopens the step-level details dialog.The step details dialog was redesigned to show only step-level information:
Details - Step N.In,Out,Reason, plusCache R,W, and cache hit rate.Go to part.The webview strings added by this feature are now localized through
@kilocode/kilo-i18n:The changeset was updated so release notes describe the final user-facing behavior rather than an intermediate implementation.
Screenshots / Video
The CI visual-regression run generated an updated
task-header-with-steps-chromium-linux.pngbaseline for the new timeline state. Because this is a fork PR, the workflow cannot auto-commit that baseline; a maintainer may need to update/accept the screenshot baseline.How to Test
Manual/local verification
bun run lintinpackages/kilo-vscodebun run typecheckinpackages/kilo-vscodebun test tests/unit/task-timeline-tooltip.test.ts tests/unit/font-size-arch.test.ts tests/unit/timeline-geometry.test.ts tests/unit/timeline-highlight-events.test.ts tests/unit/transcript-parts.test.ts --timeout 60000inpackages/kilo-vscodebun run typecheckinpackages/opencodebun test test/kilocode/session-processor-empty-tool-calls.test.ts --timeout 60000inpackages/opencodebun run typecheckinpackages/kilo-i18nbun run script/check-opencode-annotations.tsfrom the repo rootReviewer test steps
step-finishbars are not shown as separate green activity bars.Go to partandStep details.Go to partand confirm the transcript scrolls to the referenced part.Step detailsfrom the left-click or keyboard menu and confirm the dialog title isDetails - Step N.Blocked checks and substitute verification
--no-verify; CI runs JetBrains checks separately.bun run test:unitfrompackages/kilo-vscodeis not reliable in this Windows shell because unrelated tests depend on POSIX paths, symlink privileges, or/bin/bash. Substitute verification is the targeted VS Code unit coverage listed above plus CI.Checklist