Skip to content

feat: simplify session title chain + two-line list item (web + vscode)#153

Open
DrumRobot wants to merge 4 commits into
mainfrom
feat/140-summary-cleanup
Open

feat: simplify session title chain + two-line list item (web + vscode)#153
DrumRobot wants to merge 4 commits into
mainfrom
feat/140-summary-cleanup

Conversation

@DrumRobot
Copy link
Copy Markdown
Member

@DrumRobot DrumRobot commented May 16, 2026

Summary

  • Remove currentSummary field and its fallback usage from the title display chain.
  • Demote agentName from the primary title fallback to a secondary metadata line (matches the official Claude Code extension UX). New chain: customTitle ?? title.
  • Add getSecondaryInfo({ agentName, updatedAt, messageCount }) helper that renders "{agentName} · {relativeTime} · 💬 {messageCount}". Used as line 2 on the web (true two-line layout) and as TreeItem.description in the VSCode extension (muted text, same row — TreeItem API does not support true two lines).
  • Cross-session summary resolution (the summaries array, leafUuid sort timestamps, analysis.summaryCount) is preserved; only the cached "first summary as title" is dropped.
  • Bump npm packages (core/web/mcp + root) to v0.5.0 to surface the breaking type-surface change. vscode-extension version is unchanged (separate release cycle via beta/open-vsx).

Changes

File Change
packages/core/src/types.ts Drop SessionMeta.currentSummary and SessionTreeData.currentSummary fields
packages/core/src/utils.ts Drop DisplayTitleOptions.currentSummary and DisplayTitleOptions.agentName. Simplify positional getDisplayTitle(customTitle, title, fallback?). Remove currentSummary branches in getSessionTooltip. Add SecondaryInfoOptions interface + getSecondaryInfo helper.
packages/core/src/index.ts Export getSecondaryInfo and SecondaryInfoOptions
packages/core/src/utils.test.ts Rewrite getDisplayTitle tests for the new customTitle > title chain. Add describe('getSecondaryInfo') with 10 unit tests (agentName/time/count combinations, empty/edge cases, custom separator)
packages/core/src/session/crud-helpers.ts Drop currentSummary from buildSessionMeta fields/return
packages/core/src/session/tree.ts Drop currentSummary from sort comparator, builder, error filter, and summary cache update
packages/core/src/__tests__/{tree,sort-fields,crud-helpers,list}.test.ts Update test fixtures and assertions
packages/web/src/lib/api.ts Drop currentSummary from SessionData type
packages/web/src/lib/stores/projectTree.ts Drop currentSummary from SessionNode and defaults
packages/web/src/lib/components/ProjectTree.svelte Remove currentSummary arguments and the isSummaryFallback branch; renamed to isTitleFallback reflecting the chain. Two-line row template via flex-col: line 1 = title, line 2 = getSecondaryInfo (agentName · time · 💬 count). messageCount moved out of right-side icon strip into line 2; agents/todos icons remain on the right and only render when count > 0.
packages/web/src/lib/components/SessionViewer.svelte Remove currentSummary arguments and the isSummaryFallback branch. Drop the agentName prop (no longer used after chain change).
packages/web/src/routes/+page.svelte Simplify rename handler and SessionViewer props. Stop passing agentName to <SessionViewer> and drop it from the rename getDisplayTitle call.
packages/web/src/routes/session/[project]/[id]/+page.svelte Local state and displayTitle simplified to customTitle ?? title (agentName demoted). Stop passing agentName to <SessionViewer>.
packages/web/src/lib/components/{ProjectTree,MainPage}.stories.svelte Fixture cleanup
packages/vscode-extension/src/treeProvider.ts Remove currentSummary from filter text, datetime mode branch, and getDisplayTitle call. Replace conditional datetime-mode description with always-on getSecondaryInfo: TreeItem.label = customTitle ?? title (with datetime mode still honored), TreeItem.description = {agentName} · {relativeTime} · 💬 {messageCount} (muted text, same row).
package.json, packages/{core,web,mcp}/package.json 0.4.80.5.0

BREAKING CHANGES

  • SessionMeta.currentSummary and SessionTreeData.currentSummary removed
  • getDisplayTitle positional overload simplified to (customTitle, title, fallback?). The currentSummary parameter is no longer accepted
  • DisplayTitleOptions.currentSummary removed
  • DisplayTitleOptions.agentName removed. getDisplayTitle no longer falls back to agentName. Callers that need the old behavior should render agentName separately via the new getSecondaryInfo() helper.
  • getSessionTooltip no longer renders summary as fallback content
  • SessionViewer no longer accepts the agentName prop
  • npm packages bumped to 0.5.0

Migration:

  • Callers that passed currentSummary should drop the argument. If the goal was to surface a session summary in the UI, read it from sessionData.summaries[0]?.summary directly instead of relying on the cached fallback.
  • Callers that passed agentName to getDisplayTitle should drop it from the call and render it through getSecondaryInfo({ agentName, updatedAt, messageCount }) as a secondary line.

Related Issues

Relates to #140

Test plan

  • pnpm -F core test — all 438 tests pass (was 429; +10 getSecondaryInfo, −3 obsolete agentName, +2 new chain tests after rewrite)
  • pnpm -F core buildgrep -r currentSummary packages/core/dist/ returns 0 hits
  • pnpm -F web build — SvelteKit production build succeeds
  • pnpm typecheck — 0 type errors across the monorepo
  • pnpm -F vscode-extension build — tsup build succeeds
  • Manual smoke (web): web dev server, render project tree, rename session — confirm titles use customTitle ?? title without summary or agentName fallback. Verified 2026-05-25 via chrome-devtools-mcp at port 5181 on head bearing the two-line patch: tree rows render as two visual lines (line 1 = title, line 2 = {agentName} · {relativeTime} · 💬 {count}); rename round-trip updates line 1 immediately, line 2 unchanged; API /api/sessions response contains 0 occurrences of currentSummary. Screenshot: ~/ghq/github.com/es6kr/.ralph/docs/generated/pr153-twoline-smoke.png
  • Manual smoke (vscode): /vsix rebuild + install (just rebuilt + installed at 2026-05-25 ~23:21 KST) → TreeView label = title only, description = {agentName} · {relativeTime} · 💬 {count} rendered muted on the same row; titleDisplayMode toggle (message ↔ datetime) flips line 1 between first message and relative time, line 2 stays as agentName + time + count; filter input still matches across title, agentName, customTitle, and summaries

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Bumped package versions from 0.4.8 to 0.5.0
  • New Features

    • Two-line session rows with a consolidated secondary line (agent, relative time, message count)
    • Exposed helper for building secondary-info strings and improved tooltips/title rendering
  • Bug Fixes

    • Title selection now prefers custom titles and agent names; removed reliance on autogenerated summary text
    • Search/filtering now indexes agent names and custom titles
  • Tests

    • Updated tests to align with the new title/summary model and rendering rules

Removes the currentSummary field used as a fallback in display titles.
The fallback chain simplifies to customTitle > agentName > title.

BREAKING CHANGES:
- Drop SessionMeta.currentSummary and SessionTreeData.currentSummary fields
- getDisplayTitle no longer accepts currentSummary; positional overload
  simplified to (customTitle, title, fallback?)
- Drop DisplayTitleOptions.currentSummary
- getSessionTooltip no longer renders summary as fallback content

Affects core, web, and vscode-extension packages. Cross-session
summary resolution (summaries array, leafUuid sort timestamps,
analysis.summaryCount) is preserved; only the cached "first summary
as title fallback" is removed.

Version bumped from 0.4.8 to 0.5.0 (core/web/mcp + root).
vscode-extension version unchanged (separate release cycle).

Closes #140

Signed-off-by: DrumRobot <drumrobot43@gmail.com>
@DrumRobot DrumRobot added this to the v0.5.0 milestone May 16, 2026
@DrumRobot DrumRobot added the enhancement New feature or request label May 16, 2026
@DrumRobot DrumRobot self-assigned this May 16, 2026
@DrumRobot DrumRobot requested a review from Copilot May 16, 2026 00:37
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR removes the currentSummary field from the core/web/vscode type surface and eliminates its use as a title/tooltip fallback, standardizing the title display chain to customTitle > agentName > title. It also bumps published package versions to 0.5.0 to reflect the breaking API change.

Changes:

  • Removed currentSummary from SessionMeta / SessionTreeData and from all UI call sites (web + VSCode extension).
  • Simplified getDisplayTitle positional overload and updated tests/fixtures accordingly.
  • Updated tree building/sorting to stop caching/using “first summary as title”, while preserving the summaries[] resolution behavior.

Reviewed changes

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
package.json Bump workspace version to 0.5.0.
packages/core/package.json Bump core package version to 0.5.0.
packages/core/src/types.ts Remove currentSummary from core session types.
packages/core/src/utils.ts Remove currentSummary from title/tooltip utilities and simplify overloads.
packages/core/src/utils.test.ts Update getDisplayTitle tests for the new fallback chain.
packages/core/src/session/crud-helpers.ts Stop accepting/returning currentSummary in buildSessionMeta.
packages/core/src/session/tree.ts Remove currentSummary from tree building, sorting, filtering, and cache update.
packages/core/src/tests/tree.test.ts Update tree/sort/filter tests for removed currentSummary.
packages/core/src/tests/sort-fields.test.ts Update title-sort fixtures/expectations for removed currentSummary.
packages/core/src/tests/list.test.ts Update list-session tests to reflect removal of currentSummary.
packages/core/src/tests/crud-helpers.test.ts Update buildSessionMeta tests for removed currentSummary.
packages/mcp/package.json Bump MCP package version to 0.5.0.
packages/web/package.json Bump web package version to 0.5.0.
packages/web/src/lib/api.ts Remove currentSummary from SessionData type.
packages/web/src/lib/stores/projectTree.ts Remove currentSummary from SessionNode store model.
packages/web/src/lib/components/SessionViewer.svelte Remove currentSummary prop usage when computing display title.
packages/web/src/lib/components/ProjectTree.svelte Remove currentSummary usage and rename “summary fallback” styling to “title fallback”.
packages/web/src/lib/components/ProjectTree.stories.svelte Remove currentSummary from story fixtures.
packages/web/src/lib/components/MainPage.stories.svelte Remove currentSummary from story fixtures and component props.
packages/web/src/routes/+page.svelte Remove currentSummary usage from title display and rename handler.
packages/web/src/routes/session/[project]/[id]/+page.svelte Simplify local displayTitle and remove currentSummary state/props.
packages/vscode-extension/src/treeProvider.ts Remove currentSummary from filtering/text display logic and update getDisplayTitle calls.
Comments suppressed due to low confidence (2)

packages/core/src/utils.ts:155

  • DisplayTitleOptions.maxLength is still part of the public options type, but getDisplayTitle no longer reads or applies it. Callers in web (e.g. SessionViewer uses maxLength: 50) will now see no effect, and the option is misleading. Either remove maxLength from DisplayTitleOptions (and update call sites) or reintroduce truncation (e.g. truncate the selected title/agentName output to maxLength).
export interface DisplayTitleOptions {
  agentName?: string
  customTitle?: string
  title?: string
  createdAt?: string
  maxLength?: number
  fallback?: string

packages/web/src/routes/session/[project]/[id]/+page.svelte:220

  • The rename modal is prefilled with agentName when there is no customTitle. Since renameSession writes both custom-title and agent-name, confirming without edits can create a redundant custom title (and potentially change metadata) even though the user didn’t actually rename anything. Consider prefilling with customTitle ?? session.title ?? '' (or displayTitle) and adding a no-op guard (skip API call when the trimmed input matches the current value).
    showInput(
      'Rename Session',
      'Session title:',
      customTitle ?? agentName ?? session.title ?? '',
      async (newTitle) => {
        closeInput()
        const trimmed = newTitle.trim()


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +76 to +78
// Alphabetical by display title (customTitle > title)
const titleA = a.customTitle ?? a.title
const titleB = b.customTitle ?? b.title
@@ -135,7 +134,6 @@
id: session.id,
title: session.title,
customTitle: data?.customTitle,
@es6kr es6kr deleted a comment from coderabbitai Bot May 17, 2026
@es6kr es6kr deleted a comment from coderabbitai Bot May 18, 2026
@es6kr es6kr deleted a comment from coderabbitai Bot May 18, 2026
@DrumRobot
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

Removes the deprecated session currentSummary field, replaces it with customTitle/agentName, updates title/tooltip utilities (adds getSecondaryInfo), updates core types, UI consumers, tests, and bumps package versions to 0.5.0.

Changes

Core Type Contracts and Utility Functions

Layer / File(s) Summary
Type definitions and core API contracts
packages/core/src/types.ts
SessionMeta and SessionTreeData remove currentSummary and add agentName?: string and customTitle?: string.
getDisplayTitle, getSecondaryInfo and getSessionTooltip utilities
packages/core/src/utils.ts, packages/core/src/index.ts
getDisplayTitle removes legacy overloads and currentSummary usage; priority becomes customTitle → (datetime mode) → parsed title → fallback. New getSecondaryInfo builds secondary metadata from agentName, updatedAt, and messageCount. getSessionTooltip input drops currentSummary. Core index re-exports getSecondaryInfo and its options type.
Utility function tests
packages/core/src/utils.test.ts
Tests rewritten/extended to validate new title precedence, parsing rules, and getSecondaryInfo outputs (relative times, message counts, separators).

Session Metadata Building and Tree Operations

Layer / File(s) Summary
Session metadata construction
packages/core/src/session/crud-helpers.ts
buildSessionMeta drops currentSummary from its inputs and uses userAssistantCount/hasSummary to derive messageCount; returned SessionMeta no longer sets currentSummary.
Session tree loading, sorting, and filtering
packages/core/src/session/tree.ts
Title-sorting uses customTitle ?? title; loadSessionTreeDataInternal and updateSessionSummaries stop including currentSummary. Project-level error filtering no longer inspects currentSummary.
CRUD and tree operation tests
packages/core/src/__tests__/*
Tests and fixtures updated to remove currentSummary assertions and fields; listing and sorting tests now validate customTitle vs title precedence and agentName behavior.

Web UI Components and Pages

Layer / File(s) Summary
Web API interface and session store
packages/web/src/lib/api.ts, packages/web/src/lib/stores/projectTree.ts
SessionData removes currentSummary. SessionNode drops currentSummary and adds lazy messages?: Message[]; factory initializes messages as undefined.
Component updates and stories
packages/web/src/lib/components/SessionViewer.svelte, packages/web/src/lib/components/ProjectTree.svelte, Storybook files
SessionViewer drops currentSummary prop. ProjectTree calls core helpers without currentSummary, renders two-line rows (title + secondary metadata via getSecondaryInfo), and updates icon placement. Story fixtures switched from currentSummary to summaries arrays and updated props.
Page route handlers
packages/web/src/routes/+page.svelte, packages/web/src/routes/session/[project]/[id]/+page.svelte
Rename modal and session pages derive titles from customTitle/title only; rename updates the summaries array instead of currentSummary; SessionViewer wiring drops agentName/currentSummary.

VSCode Extension

Layer / File(s) Summary
VSCode extension tree provider
packages/vscode-extension/src/treeProvider.ts
Search/filter corpus updated to exclude currentSummary and include title, agentName, customTitle, and summaries[*].summary. Building session items uses getDisplayTitle and getSecondaryInfo for label/description.

Version Updates

Layer / File(s) Summary
Package version updates
package.json, packages/core/package.json, packages/mcp/package.json, packages/web/package.json
Bumps from 0.4.8 to 0.5.0 across manifests.

🎯 3 (Moderate) | ⏱️ ~22 minutes

🐰 A whisker-thinning refactor, quite clear!
Remove summaries old, bring new fields near—
currentSummary fades, customTitle takes the stage,
Display rules refined for a brighter page! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main changes: removing currentSummary from the title chain and implementing a two-line list item UI in web and VSCode components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/140-summary-cleanup

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/core/src/types.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

packages/core/src/utils.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

packages/vscode-extension/src/treeProvider.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 1 others

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@DrumRobot
Copy link
Copy Markdown
Member Author

AI Review Summary — Superpowers requesting-code-review

Reviewer Finding Severity Status
CodeRabbit No actionable comments generated in the recent review 🟢 No issue ✅ Clean
Copilot 💡 packages/core/src/utils.ts:155 DisplayTitleOptions.maxLength is still part of the public options type, but getDisplayTitle no longer reads or applies it. Callers in web (e.g. SessionViewer uses maxLength: 50) will see no effect, and the option is misleading. Either remove maxLength from DisplayTitleOptions (and update call sites) or reintroduce truncation 🟡 Minor (low-confidence) 🟡 Deferred (author decision)
Copilot 💡 packages/web/src/routes/session/[project]/[id]/+page.svelte:220 Rename modal is prefilled with agentName when no customTitle. Since renameSession writes both custom-title and agent-name, confirming without edits can create a redundant custom title (and potentially change metadata) even though the user didn't actually rename anything. Suggest prefilling with customTitle ?? session.title ?? '' (or displayTitle) and adding a no-op guard (skip API call when the trimmed input matches the current value) 🟡 Minor (low-confidence) 🟡 Deferred (author decision)

Notes

  • CodeRabbit re-review on 9308d38e (2026-05-18T00:53Z) returned zero actionable findings.
  • Both Copilot findings are low-confidence (Copilot itself suppressed them); they are real consistency concerns worth tracking even if not blocking.
  • Both Copilot findings target files within the PR diff (verified via gh pr view --json files).
  • PR carries a BREAKING marker (refactor!) and bumps package.json versions to 0.5.0; coordinate with the planned v0.4.10-beta.x line before tagging.

Status

⏳ Test plan: 5/7 ✅ (2 manual smoke verification items unchecked — web rename flow, VSCode tree datetime mode). Actionable: 0 from CodeRabbit, 2 low-confidence from Copilot. No code changes required from this consolidation; author (DrumRobot) to decide on the two Copilot consistency suggestions and verify the remaining manual smoke checks before merge.

… list items

Following review of PR #153, agentName is removed from the primary title
fallback chain (was: customTitle ?? agentName ?? title) and rendered as a
secondary metadata line via the new getSecondaryInfo() helper. Aligns with
the official Claude Code extension's two-row layout.

- Web: real two-line layout via flex-col (line 1 = title, line 2 =
  agentName · {relativeTime} · 💬 {count}). messageCount moved out of the
  right-side icon strip; agents/todos icons remain when count > 0
- VSCode: TreeItem.label = customTitle ?? title, TreeItem.description =
  secondary info rendered muted on the same row (TreeItem API does not
  support true two lines; matches the official extension)
- New getSecondaryInfo({ agentName, updatedAt, messageCount, locale, separator })
  helper exported from @claude-sessions/core with 10 unit tests
- Standalone /session/[project]/[id] route and SessionViewer header now
  follow the same customTitle ?? title chain for consistency

BREAKING CHANGES:
- DisplayTitleOptions.agentName removed; use getSecondaryInfo() to render
  agentName as a secondary metadata line
- SessionViewer no longer accepts the agentName prop

Signed-off-by: DrumRobot <drumrobot43@gmail.com>
@DrumRobot DrumRobot changed the title refactor!: remove currentSummary from title display chain feat: simplify session title chain + two-line list item (web + vscode) May 25, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/src/routes/session/[project]/[id]/+page.svelte (1)

210-220: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Skip no-op rename requests when the normalized value didn’t change.

The rename flow currently always calls api.renameSession(...) after trim, even if the user confirms without edits. Add a normalized equality guard before Line 219 to avoid redundant writes.

Suggested patch
   showInput(
     'Rename Session',
     'Session title:',
     customTitle ?? session.title ?? '',
     async (newTitle) => {
       closeInput()
       const trimmed = newTitle.trim()
+      const current = (customTitle ?? session?.title ?? '').trim()
+      if (trimmed === current) return

       try {
         await api.renameSession(session!.projectName, session!.id, trimmed)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/web/src/routes/session/`[project]/[id]/+page.svelte around lines 210
- 220, Before calling api.renameSession in the showInput callback, compare the
normalized (trimmed) newTitle against the current normalized title (use
customTitle ?? session.title ?? '') and if they are equal, call closeInput() and
return early to skip the no-op rename; update the callback in the showInput
handler (the async (newTitle) => { ... } block) to perform this guard using
trimmed and the existing title normalization before making the api.renameSession
call.
🧹 Nitpick comments (1)
packages/core/src/utils.ts (1)

149-154: ⚡ Quick win

Remove or implement maxLength in DisplayTitleOptions to avoid a misleading API.

maxLength is still part of the public options type (Line 153), but getDisplayTitle no longer uses it (Lines 189-219). That makes existing callers think truncation still works when it does not.

Also applies to: 189-219

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/utils.ts` around lines 149 - 154, The DisplayTitleOptions
interface exposes maxLength but getDisplayTitle no longer uses it, causing a
misleading API; either remove maxLength from DisplayTitleOptions (and update any
callers/types/docs) or reintroduce truncation logic inside getDisplayTitle to
honor options.maxLength (e.g., truncate title/customTitle/fallback with an
ellipsis when length exceeds maxLength). Locate the type DisplayTitleOptions and
the function getDisplayTitle and apply the chosen change consistently across
code, types, and tests so the public API matches actual behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/vscode-extension/src/treeProvider.ts`:
- Around line 321-326: Session message counts are shown twice because
session.getSecondaryInfo(...) already includes "💬 {messageCount}" and
SessionTreeItem prepends the count; remove the redundant prepend in the
SessionTreeItem implementation (the code that builds the tree label/description)
so it no longer prepends {count}, relying on session.getSecondaryInfo to show
the message count; update both places where SessionTreeItem builds the
label/description that currently prepend the count to avoid duplicate display.

In `@packages/web/src/routes/session/`[project]/[id]/+page.svelte:
- Around line 80-82: The current displayTitle computed with nullish coalescing
treats an empty string as a valid title and can produce a blank <title>; update
the logic that computes displayTitle (the const displayTitle using customTitle
and session?.title) to use a truthy fallback instead of ?? (e.g., check
customTitle is non-empty/trimmed before using it) or call the existing
getDisplayTitle utility with (session, customTitle) so empty strings fall
through to session?.title and ultimately to 'Untitled'.

---

Outside diff comments:
In `@packages/web/src/routes/session/`[project]/[id]/+page.svelte:
- Around line 210-220: Before calling api.renameSession in the showInput
callback, compare the normalized (trimmed) newTitle against the current
normalized title (use customTitle ?? session.title ?? '') and if they are equal,
call closeInput() and return early to skip the no-op rename; update the callback
in the showInput handler (the async (newTitle) => { ... } block) to perform this
guard using trimmed and the existing title normalization before making the
api.renameSession call.

---

Nitpick comments:
In `@packages/core/src/utils.ts`:
- Around line 149-154: The DisplayTitleOptions interface exposes maxLength but
getDisplayTitle no longer uses it, causing a misleading API; either remove
maxLength from DisplayTitleOptions (and update any callers/types/docs) or
reintroduce truncation logic inside getDisplayTitle to honor options.maxLength
(e.g., truncate title/customTitle/fallback with an ellipsis when length exceeds
maxLength). Locate the type DisplayTitleOptions and the function getDisplayTitle
and apply the chosen change consistently across code, types, and tests so the
public API matches actual behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 18ff2b6e-d349-47df-b069-7699adb910ba

📥 Commits

Reviewing files that changed from the base of the PR and between 9308d38 and 0c77dd9.

📒 Files selected for processing (8)
  • packages/core/src/index.ts
  • packages/core/src/utils.test.ts
  • packages/core/src/utils.ts
  • packages/vscode-extension/src/treeProvider.ts
  • packages/web/src/lib/components/ProjectTree.svelte
  • packages/web/src/lib/components/SessionViewer.svelte
  • packages/web/src/routes/+page.svelte
  • packages/web/src/routes/session/[project]/[id]/+page.svelte
💤 Files with no reviewable changes (2)
  • packages/web/src/lib/components/SessionViewer.svelte
  • packages/web/src/routes/+page.svelte

Comment thread packages/vscode-extension/src/treeProvider.ts
Comment on lines +80 to 82
// Display title for page title (customTitle ?? title chain — agentName demoted to secondary line in list items)
const displayTitle = $derived(customTitle ?? session?.title ?? 'Untitled')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid blank page titles when customTitle is an empty string.

Using nullish coalescing here treats '' as a valid title. On Line 81 that can render an empty <title>. Prefer truthy fallback logic (or reuse getDisplayTitle) so empty strings fall through to session?.title.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/web/src/routes/session/`[project]/[id]/+page.svelte around lines 80
- 82, The current displayTitle computed with nullish coalescing treats an empty
string as a valid title and can produce a blank <title>; update the logic that
computes displayTitle (the const displayTitle using customTitle and
session?.title) to use a truthy fallback instead of ?? (e.g., check customTitle
is non-empty/trimmed before using it) or call the existing getDisplayTitle
utility with (session, customTitle) so empty strings fall through to
session?.title and ultimately to 'Untitled'.

DrumRobot added 2 commits May 26, 2026 00:46
… in description

Two issues surfaced after the two-line patch landed on PR #153:

1. Description invisible for long titles. VSCode TreeView uses flex layout
   where the label has flex:1 and shrinks before the description, so any
   reasonably long session title pushed the secondary info off-screen.
   Pre-truncating the label to 40 chars + ellipsis reverses the priority
   and guarantees the description (count · agentName · time) stays visible.
   Full title remains available in the tooltip.

2. Count appeared twice in the description. SessionTreeItem's constructor
   already prefixes the session-type description with `${count} · ...`,
   so passing messageCount to getSecondaryInfo again produced
   "121 · agentName · 2h ago · 💬 121". Dropped messageCount from the
   getSecondaryInfo call here; the web ProjectTree still passes it (count
   only lives in the row icon strip there, not the description).

Signed-off-by: DrumRobot <drumrobot43@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/src/utils.ts (1)

161-171: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

maxLength option is defined but never used.

The DisplayTitleOptions interface includes maxLength?: number (line 165), but the getDisplayTitle implementation (lines 201-211) never reads or applies this option. Callers passing maxLength (e.g., the web route at packages/web/src/routes/+page.svelte:273 passing maxLength: Infinity) expect truncation behavior that no longer exists.

Either remove maxLength from the interface to reflect the new behavior, or reintroduce truncation logic in getDisplayTitle.

Proposed fix: Remove the unused field
 export interface DisplayTitleOptions {
   customTitle?: string
   title?: string
   createdAt?: string
-  maxLength?: number
   fallback?: string
   /** 'message' = first user message (default), 'datetime' = relative date/time */
   mode?: TitleDisplayMode
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/src/utils.ts` around lines 161 - 171, DisplayTitleOptions
declares maxLength but getDisplayTitle doesn't use it; reintroduce truncation in
getDisplayTitle by reading options.maxLength (from the DisplayTitleOptions
object) after computing the final title, treat undefined or Infinity as “no
truncation”, and if maxLength is a finite number and the title length exceeds
it, truncate to maxLength characters and append an ellipsis (or trim to
maxLength-1 and append “…” to keep total length equal to maxLength). Update
getDisplayTitle to apply this logic to the computed title so callers (e.g.,
those passing maxLength: Infinity) get the expected behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/core/src/utils.ts`:
- Around line 161-171: DisplayTitleOptions declares maxLength but
getDisplayTitle doesn't use it; reintroduce truncation in getDisplayTitle by
reading options.maxLength (from the DisplayTitleOptions object) after computing
the final title, treat undefined or Infinity as “no truncation”, and if
maxLength is a finite number and the title length exceeds it, truncate to
maxLength characters and append an ellipsis (or trim to maxLength-1 and append
“…” to keep total length equal to maxLength). Update getDisplayTitle to apply
this logic to the computed title so callers (e.g., those passing maxLength:
Infinity) get the expected behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 258c1bcc-6e9f-407e-ba31-ff8f0ce0dc68

📥 Commits

Reviewing files that changed from the base of the PR and between 0c77dd9 and f882e73.

📒 Files selected for processing (8)
  • package.json
  • packages/core/package.json
  • packages/core/src/types.ts
  • packages/core/src/utils.ts
  • packages/mcp/package.json
  • packages/vscode-extension/src/treeProvider.ts
  • packages/web/package.json
  • packages/web/src/lib/components/ProjectTree.svelte
✅ Files skipped from review due to trivial changes (4)
  • packages/mcp/package.json
  • packages/web/package.json
  • packages/core/package.json
  • package.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants