Skip to content

feat: Editable session titles with double-click inline editing#57

Open
tijszwinkels wants to merge 3 commits intomainfrom
feature/editable-session-titles
Open

feat: Editable session titles with double-click inline editing#57
tijszwinkels wants to merge 3 commits intomainfrom
feature/editable-session-titles

Conversation

@tijszwinkels
Copy link
Copy Markdown
Owner

Summary

Add the ability to manually override session titles by double-clicking on them in the sidebar or the top title bar. Custom titles persist across browser reloads and server restarts.

How it works

  • Double-click any session title in the sidebar or header bar → inline text input appears
  • Enter commits, Escape cancels, blur (click away) commits
  • Clearing the input reverts to the auto-generated title
  • Custom titles are stored in ~/.config/vibedeck/session-titles.json
  • Auto-generated summary titles won't overwrite a custom title

Changes

Backend

  • New routes/titles.py with GET /api/session-titles and POST /api/session-titles/set endpoints (same pattern as session statuses)
  • Registered in router and server

Frontend

  • sessions.js: loadCustomTitles(), setCustomTitle() (optimistic update + rollback), startTitleEdit() (inline editing), initTitleBarEdit()
  • connection.js: session_summary_updated skips title update when custom title exists
  • state.js: Added customTitles Map
  • style.css: Styled inline edit input

Tests

  • 11 new tests in test_titles.py covering persistence, API routes, edge cases (empty, too long, whitespace trimming, corrupt file)

The pending-to-real session merge in session_added was matching ANY
pending+starting session within a 30-second window, regardless of which
project it belonged to. This caused unrelated session_added events
(subagents, manually started sessions, etc.) to incorrectly merge with
and replace the pending session the user was looking at.

Now requires cwd match (both must be set and equal, trailing slashes
stripped) and optionally checks backend name if both are known. If the
incoming session has no projectPath, no merge happens — the session
appears normally in the sidebar instead of silently replacing the wrong
pending session.

Before:
  if (session.pending && session.starting &&
      (Date.now() - session.startedAt) < MERGE_WINDOW_MS) {
      mergedPendingId = sessionId;
      break;
  }

After:
  if (!pendingCwd || !incomingCwd || pendingCwd !== incomingCwd) continue;
  if (session.selectedBackend && incomingBackend &&
      session.selectedBackend !== incomingBackend) continue;
Add the ability to manually override session titles by double-clicking
on them in the sidebar or in the top title bar. Custom titles persist
to ~/.config/vibedeck/session-titles.json across browser reloads and
server restarts.

Backend:
- New routes/titles.py with GET /api/session-titles and
  POST /api/session-titles/set endpoints (same pattern as statuses)
- Titles are stripped, max 200 chars, null/empty clears the override

Frontend (sessions.js):
- loadCustomTitles() loads overrides on init, applies to existing sessions
- setCustomTitle() does optimistic update + server persist with rollback
- startTitleEdit() creates an inline <input> on double-click
  (Enter commits, Escape cancels, blur commits)
- initTitleBarEdit() wires up dblclick on the header title bar
- createSession() respects customTitles when building display title
- session_summary_updated (connection.js) skips title update when a
  custom title is set (status colors still update from summary)

State:
- Added customTitles Map to state.js

CSS:
- .title-edit-input styled to match the surrounding text
- cursor: default + hover opacity on session-title-bar
Read Pi's session_info.name into VibeDeck as sessionName and use the
precedence chain:

  customTitle > sessionName > summaryTitle > firstMessage > name

Also folds in the follow-up hardening from review:
- preserve sessionName over later summary updates
- live-update Pi session names when name_session appends session_info
- broadcast session_name_updated to both HTML and JSON SSE clients
- ensure session_name_updated uses the correct broadcast_event signature
- normalize ~/... new-session cwd handling early enough to avoid pending
  session merge races
- bootstrap homeDir in initial HTML so tilde expansion works before the
  first SSE connect on cold load
- use server-provided homeDir for portability across /home, /Users, etc.
- keep pending-session merge working when cwd spellings differ between
  user input and resolved backend paths
@tijszwinkels tijszwinkels force-pushed the feature/editable-session-titles branch from 778fa64 to 7eba42b Compare April 3, 2026 11:24
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