Skip to content

Release v5.4.1#51

Merged
code-crusher merged 12 commits intomainfrom
release/v5.4.1
Feb 13, 2026
Merged

Release v5.4.1#51
code-crusher merged 12 commits intomainfrom
release/v5.4.1

Conversation

@code-crusher
Copy link
Member

Summary

This release includes several UI improvements, bug fixes, and feature enhancements.

Changes

  • Notifications Integration: Updated notifications integration with improved error handling and test coverage
  • Task History: Improved task history list UI and functionality
  • Codebase Indexing: Enhanced codebase indexing tool UI
  • Model Naming: Fixed auto model naming issues
  • Sticky User Messages: Added sticky user messages feature for better chat UX
  • Code Reviews: UI updates for code reviews and file path bug fix
  • API Host: Updated API host in relevant places
  • Model Names: Streamlined model names and auto model selection
  • Profile Page: Updated profile page with data display
  • Pro Model Info: Added pro model information display

Files Changed

  • 42 files changed
  • 859 additions, 567 deletions

Testing

  • All existing tests pass
  • Added/updated tests for notifications integration

Checklist

  • Code compiles correctly
  • Tests pass locally
  • No new warnings introduced

@matter-ai-bot
Copy link
Contributor

matter-ai-bot bot commented Feb 13, 2026

Code Quality type: bug fix

Context

This release refines the chat interface styling and integrates previous logic improvements for sticky headers and credit usage metrics to ensure a seamless user experience.

Implementation

In ChatView.tsx, CSS utility classes scrollable, grow, overflow-y-scroll, and scrollbar-hide were added to the Virtuoso component to manage layout and visibility. This builds upon the previous implementation of firstRenderedIndex detection for sticky headers. Additionally, the fallback logic for usagePercentage in KiloCode.tsx remains active to handle missing backend metrics.

Screenshots

before after
N/A N/A

How to Test

  1. Open the chat view and verify that the list fills the available space and scrolls vertically.
  2. Confirm that the scrollbar is hidden as per the scrollbar-hide class.
  3. Scroll rapidly to ensure sticky headers correctly track based on the firstRenderedIndex logic.
  4. Verify credit usage displays correctly even if the percentage field is missing from the API response.

Get in Touch

Axon Code Discord

Summary By MatterAI MatterAI logo

🔄 What Changed

Updated the Chat List styling with overflow and visibility utility classes and maintained Sticky Header and Credit Usage logic refinements.

🔍 Impact of the Change

Improves UI cleanliness by hiding scrollbars while ensuring robust data rendering and reliable header positioning during virtualization.

📁 Total Files Changed

Click to Expand
File ChangeLog
UI Styling webview-ui/src/components/chat/ChatView.tsx Added scrollbar-hide and overflow classes to the Virtuoso component.
Usage Fallback webview-ui/src/components/kilocode/settings/providers/KiloCode.tsx Implemented manual percentage calculation for user credits.

🧪 Test Added/Recommended

Recommended

  • Visual regression test to ensure scrollbar-hide works across Chrome and VS Code webviews.
  • Unit test for the credit percentage fallback logic to handle totalCredits = 0 scenarios.

🔒 Security Vulnerabilities

N/A. Changes are limited to CSS styling and local UI arithmetic.

Total Score: 5/5

⏳ Estimated code review effort

LOW (~5 minutes)

Tip

Quality Recommendations

  1. Verify that 'scrollbar-hide' is defined in the global CSS/Tailwind config to prevent silent failures.

  2. Consider extracting the credit percentage calculation into a utility function for better testability.

♫ Tanka Poem

Clean lines in the code 🧪
Scrollbars vanish from the view 🌊
Logic flows so deep 📊
Metrics find their way to light 💡
Users find their peace 😊

Sequence Diagram

sequenceDiagram
    participant U as User
    participant CV as ChatView
    participant V as Virtuoso
    participant KC as KiloCodeProvider

    U->>CV: Access Chat
    CV->>V: Render(groupedMessages, className="scrollbar-hide")
    Note over V: Apply overflow-y-scroll & hide scrollbar
    CV->>CV: calculateStickyHeader(firstRenderedIndex)
    U->>KC: View Settings
    KC->>KC: calculateUsage(used, total)
    KC-->>U: Display Usage %
Loading

Copy link
Contributor

@matter-ai-bot matter-ai-bot bot left a comment

Choose a reason for hiding this comment

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

🧪 PR Review is completed: Review of Release v5.4.1: Rebranding to Axon Code and Sticky User Messages.

Key findings:

  1. Critical logic flaw in sticky message scrolling for virtualized lists.
  2. Invalid Tailwind class in new component.
  3. Potential division by zero in settings.
  4. Incomplete state cleanup in reset script.
Skipped files
  • apps/kilocode-docs/.kilocode/rules/memory-bank/tech.md: Skipped file pattern
  • apps/kilocode-docs/docs/getting-started/installing.md: Skipped file pattern
  • apps/kilocode-docs/docs/seats/getting-started.md: Skipped file pattern
  • apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/getting-started/installing.md: Skipped file pattern
  • apps/kilocode-docs/i18n/zh-CN/docusaurus-theme-classic/footer.json: Skipped file pattern
  • webview-ui/src/i18n/locales/en/chat.json: Skipped file pattern
⬇️ Low Priority Suggestions (2)
webview-ui/src/components/kilocode/StickyUserMessage.tsx (1 suggestion)

Location: webview-ui/src/components/kilocode/StickyUserMessage.tsx (Lines 67-70)

🔵 CSS/Style

Issue: ml-0.9 is not a valid Tailwind CSS class (unless customized). Standard spacing scale uses 0.5, 1, 1.5, etc.

Fix: Use ml-1 (4px) or an arbitrary value like ml-[3.5px] if precision is needed.

Impact: Ensures consistent styling and avoids invalid class names.

-  			className={cn(
-  				"px-2 py-2 flex flex-col gap-1 relative ml-0.9 mr-1",
-  				"rounded-lg",
-  				"border border-[var(--color-matterai-border)]",
+  			className={cn(
+  				"px-2 py-2 flex flex-col gap-1 relative ml-1 mr-1",
+  				"rounded-lg",
+  				"border border-[var(--color-matterai-border)]",
scripts/reset-kilocode-state.sh (1 suggestion)

Location: scripts/reset-kilocode-state.sh (Lines 8-10)

🟡 Configuration

Issue: The script deletes keys matching workbench.view.extension.kilo-code%. With the rebranding to axon-code, the view container ID likely changed to axon-code. This script might miss cleaning up the new view state.

Fix: Include the new view ID pattern in the DELETE statement.

Impact: Ensures complete state reset for the rebranded extension.

-      key = 'matterai.axon-code' OR \
-      key LIKE 'workbench.view.extension.kilo-code%' OR \
-      key LIKE 'secret://{\"extensionId\":\"matterai.axon-code\",%';"
+      key = 'matterai.axon-code' OR \
+      key LIKE 'workbench.view.extension.kilo-code%' OR \
+      key LIKE 'workbench.view.extension.axon-code%' OR \
+      key LIKE 'secret://{\"extensionId\":\"matterai.axon-code\",%';"

Comment on lines 1775 to 1803
const stickyHeight = stickyHeaderRef.current?.offsetHeight ?? 40
const scrollerRect = scroller.getBoundingClientRect()
const threshold = scrollerRect.top + stickyHeight

let bestIndex: number | null = null
let passedRenderedRegion = false

for (const idx of userFeedbackIndices) {
const el = scroller.querySelector(`[data-item-index="${idx}"]`) as HTMLElement | null

if (!el) {
if (passedRenderedRegion) {
// Past the rendered region — below viewport, stop
break
}
// Not yet in rendered region — above viewport (scrolled past)
bestIndex = idx
continue
}

passedRenderedRegion = true
const elTop = el.getBoundingClientRect().top
if (elTop <= threshold) {
bestIndex = idx
} else {
// Below the threshold, everything after will be too
break
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🟠 Logic Error

Issue: The sticky header logic assumes that if an element is not found in the DOM (!el), it must be above the viewport. In a virtualized list (Virtuoso), items below the viewport are also not in the DOM. This causes the sticky header to incorrectly show future messages when at the top of the chat if the first user message is outside the initial render window.

Fix: Determine the first rendered index by querying the DOM once, then use it to decide if a missing element is above or below the viewport.

Impact: Prevents sticky header from showing incorrect future messages.

Suggested change
const stickyHeight = stickyHeaderRef.current?.offsetHeight ?? 40
const scrollerRect = scroller.getBoundingClientRect()
const threshold = scrollerRect.top + stickyHeight
let bestIndex: number | null = null
let passedRenderedRegion = false
for (const idx of userFeedbackIndices) {
const el = scroller.querySelector(`[data-item-index="${idx}"]`) as HTMLElement | null
if (!el) {
if (passedRenderedRegion) {
// Past the rendered region — below viewport, stop
break
}
// Not yet in rendered region — above viewport (scrolled past)
bestIndex = idx
continue
}
passedRenderedRegion = true
const elTop = el.getBoundingClientRect().top
if (elTop <= threshold) {
bestIndex = idx
} else {
// Below the threshold, everything after will be too
break
}
}
const stickyHeight = stickyHeaderRef.current?.offsetHeight ?? 40
const scrollerRect = scroller.getBoundingClientRect()
const threshold = scrollerRect.top + stickyHeight
// Find the first rendered item to determine our position relative to the virtual list
const firstRenderedEl = scroller.querySelector('[data-item-index]')
const firstRenderedIndex = firstRenderedEl ? parseInt(firstRenderedEl.getAttribute('data-item-index') || "0", 10) : 0
let bestIndex: number | null = null
for (const idx of userFeedbackIndices) {
const el = scroller.querySelector(`[data-item-index="${idx}"]`) as HTMLElement | null
if (!el) {
if (idx < firstRenderedIndex) {
// Not in DOM and index is lower than first rendered -> Above viewport
bestIndex = idx
continue
} else {
// Not in DOM and index is higher -> Below viewport
break
}
}
const elTop = el.getBoundingClientRect().top
if (elTop <= threshold) {
bestIndex = idx
} else {
// Below the threshold, everything after will be too
break
}
}

Comment on lines 99 to 104
const usagePercentage =
profileData?.usagePercentage !== undefined
? profileData.usagePercentage
: profileData?.usedCredits !== undefined && profileData?.totalCredits !== undefined
? (profileData.usedCredits / profileData.totalCredits) * 100
: null
Copy link
Contributor

Choose a reason for hiding this comment

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

🟡 Robustness

Issue: Potential division by zero if profileData.totalCredits is 0, which could result in NaN or Infinity displayed in the UI.

Fix: Add a check to ensure totalCredits is greater than 0 before dividing.

Impact: Prevents UI display errors.

Suggested change
const usagePercentage =
profileData?.usagePercentage !== undefined
? profileData.usagePercentage
: profileData?.usedCredits !== undefined && profileData?.totalCredits !== undefined
? (profileData.usedCredits / profileData.totalCredits) * 100
: null
const usagePercentage =
profileData?.usagePercentage !== undefined
? profileData.usagePercentage
: profileData?.usedCredits !== undefined && (profileData?.totalCredits || 0) > 0
? (profileData.usedCredits / profileData.totalCredits) * 100
: null

- ChatView.tsx: Fix sticky header logic for virtualized list by checking
  first rendered index to correctly determine if missing elements are
  above or below viewport
- KiloCode.tsx: Add division-by-zero guard for usagePercentage calculation
@matter-ai-bot
Copy link
Contributor

matter-ai-bot bot commented Feb 13, 2026

✅ Reviewed the changes: The changes correctly address the virtualization logic in ChatView.tsx and the division by zero issue in KiloCode.tsx. The implementation is robust and follows the previous recommendations.

@code-crusher code-crusher merged commit 9b00e37 into main Feb 13, 2026
4 of 12 checks passed
@code-crusher code-crusher deleted the release/v5.4.1 branch February 13, 2026 19:38
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