290 Chat Ux V2 Technical Summary

Documentation for Sessions

S290.20 — Chat UX v2 Technical Summary

Session: S290.20 | Date: 2026-03-31 | Version: 0.21.0 | Branch: session-290-299
Commits: 12 (38083e19f..71e123fd5)


Architecture

Component Model

Three new reusable Lit components in components/shared/, composed into the existing agent-chat-view (2064 lines pre-change). No new Angular libraries — all changes are within the extension source.

apps/vitto-vscode-extension/src/
  panels/
    main-panel.ts                    # +5 case handlers, +1 helper method
    webview/
      api.ts                         # +request/response resolver for file search
      types.ts                       # +2 interfaces, +7 message variants
      components/
        shared/
          drop-zone-overlay.ts       # NEW: reusable drag overlay
          mention-autocomplete.ts    # NEW: provider-based @mention
          context-chips.ts           # NEW: context transparency pills
          markdown-view.ts           # Modified: 4 action buttons on code blocks
        agent/
          agent-chat-view.ts         # Modified: integration of all features
          agent-message.ts           # Modified: streaming caret, context chips

Message Protocol Extensions

Seven new message types following the existing MessageToExtension / MessageFromExtension union pattern:

Message Direction Handler VSCode API
insertAtCursor webview -> host activeTextEditor.insertSnippet() SnippetString at cursor
sendToTerminal webview -> host createTerminal().sendText() Named "Vitto" terminal
applyCodeToFile webview -> host vscode.diff or untitled doc Diff view or beside editor
searchWorkspaceFiles webview -> host workspace.findFiles() Glob search, 50 max, excludes node_modules
readFileForContext webview -> host openTextDocument().getText() 60-line preview
workspaceFilesResult host -> webview Resolves request() promise Via requestId correlation
fileContextResult host -> webview Resolves request() promise Via requestId correlation

Provider Architecture (@mentions)

interface MentionSource {
  id: string;              // 'file', 'selection', 'terminal', 'errors'
  label: string;           // 'Files'
  icon: string;            // emoji
  search(query: string): Promise<MentionItem[]>;
  showOnEmpty?: boolean;   // show in initial dropdown
}

Shipped: FileMentionSource — searches workspace via searchWorkspaceFiles message, falls back to open files from ideContext.openFiles.

Planned providers (one class + one array push each):

Context Snapshot Flow

User types message
  -> captureContextSnapshot() reads ideContext + pendingMentions + pendingAttachments
  -> ContextSnapshot stored in messages[] alongside user message
  -> Persisted in NativeChatPersistedMessage (survives panel reload)
  -> <context-chips> component renders pills from ContextSnapshot
  -> File chips dispatch 'chip-click' -> 'open-file' -> send({ type: 'openFile' })

Drag-Drop MIME Type Handling

Priority 1: Files         (OS file drops — images, documents)
  -> ingestFiles() -> Canvas compression -> PendingAgentAttachment

Priority 2: text/uri-list (editor tabs, file explorer)
  -> addFileContextFromUri() -> readFileForContext -> PendingMention

Priority 3: text/plain    (fallback, path-like strings)
  -> addFileContextFromUri() if starts with / or file://

Code Block Action Visibility

markdown-it fence renderer extracts:
  - lang: first token of fence info
  - filename: parsed from colon (ts:file.ts) or space (typescript file.ts)

Button visibility:
  Copy     -> always
  Insert   -> always
  Terminal -> SHELL_LANGS.has(lang)  // bash, sh, shell, zsh, powershell, cmd, console, bat
  Apply    -> filename !== null

Files Changed

Created (3)

File Lines Purpose
components/shared/drop-zone-overlay.ts ~110 Reusable overlay: visible prop, message, Shift hint, upload SVG, frosted glass animation
components/shared/mention-autocomplete.ts ~270 Provider interface (MentionSource/MentionItem/PendingMention), debounced search, keyboard nav (navigateUp/Down, selectCurrent), grouped results
components/shared/context-chips.ts ~120 Builds chips from ContextSnapshot (active file, branch, errors, attachments, mentions), deduplicates, clickable file chips

Modified (6)

File Insertions Deletions Key Changes
types.ts +31 -2 ContextSnapshot, FileSearchResult interfaces; contextSnapshot on NativeChatPersistedMessage; mentionedFiles on agentMessage; 5 new MessageToExtension, 2 new MessageFromExtension
main-panel.ts +85 -2 5 case handlers (insertAtCursor, sendToTerminal, applyCodeToFile, searchWorkspaceFiles, readFileForContext); inferLanguageFromFilename helper; mentionedFiles passthrough
markdown-view.ts +90 -30 SHELL_LANGS set, parseFenceFilename, new fence renderer with 4 buttons, code-block-actions CSS, decodeDataCode/flashButton helpers, unified handleClick
agent-message.ts +35 -5 streaming-caret CSS + keyframes, streaming-text class, caret in text render, contextSnapshot on AgentMessage, context-chips import + render, handleChipClick
agent-chat-view.ts +254 -21 FileMentionSource class, 6 new state properties, mention chip CSS, enhanced drag handlers (URI + vscode types), addFileContextFromUri, handleMentionSelect, captureContextSnapshot, handleOpenFile, @mention detection in handleInput, mention nav in handleKeydown, mention autocomplete + chips in render, contextSnapshot persistence
api.ts +13 0 requestId correlation resolver for workspaceFilesResult and fileContextResult

Commit Log

71e123fd5 [S290.20] chore: bump to v0.21.0 Chat UX v2
0c21c168d [S290.20] feat: integrate @mention autocomplete, tab drag-drop, mention chips, and context snapshots
dde77ca6a [S290.20] feat: wire workspaceFilesResult and fileContextResult to request/response correlation
91b334319 [S290.20] feat: add reusable <context-chips> component showing per-message context transparency
b8a74d5ac [S290.20] feat: add reusable <mention-autocomplete> with provider interface and keyboard navigation
beb0fd5a1 [S290.20] feat: add keyboard shortcut hints to chat header buttons
cdcc9fea2 [S290.20] feat: add Insert, Terminal, Apply action buttons to code blocks in markdown-view
c48765663 [S290.20] feat: add reusable <drop-zone-overlay> with Shift hint, replace CSS pseudo-element
fec37a13d [S290.20] feat: add extension host handlers for insertAtCursor, sendToTerminal, applyCodeToFile, searchWorkspaceFiles, readFileForContext
f9e38ddf0 [S290.20] feat: add blinking streaming caret to AI text messages
38083e19f [S290.20] feat: add Chat UX v2 types — ContextSnapshot, FileSearchResult, 7 new message variants
3402cac98 [S290.20] docs: add Chat UX v2 spec and implementation plan

MCP Intelligence

Decisions Logged (7)

ID Type Summary
dev_..._z0fi7g8 architecture 3 reusable Lit components, not inlined — agent-chat-view already 2064 lines
dev_..._ddvtw4v implementation Code block data-action event delegation — cleanest for markdown-it HTML
dev_..._hpg4tee architecture Provider-based MentionSource — extensible without rewrites
dev_..._iulytbm implementation ContextSnapshot at send-time, not render-time — correct moment
dev_..._c55mtsl implementation URI list + vnd.code MIME types for tab drag-drop
dev_..._zvymzei implementation Reusable overlay component with Shift hint
dev_..._adkzyfh milestone 7 features, 12 commits, v0.21.0, matches industry standard

Conventions Added (4)

Convention Rule
Component extraction New webview features must be Lit components in shared/, not inlined
Code block actions Use data-action event delegation in markdown-view.ts
@mention providers Implement MentionSource interface, register in mentionSources[]
Drag-drop MIME types Handle Files + text/uri-list + application/vnd.code.*, show Shift hint

Reflections (7 lessons)

  1. Cross-product research before implementation ensures features match industry standards
  2. Parallel subagent dispatch (4 simultaneous) = 3-4x faster than sequential
  3. Provider interfaces add minimal overhead but prevent architectural rewrites
  4. Event delegation with data-action is the cleanest pattern for markdown-it rendered HTML
  5. ContextSnapshot must be captured at send-time, not render-time
  6. Textarea + chip row avoids contenteditable complexity trap
  7. Extension host message protocol (types.ts union + main-panel.ts switch) scales well

Edge Cases and Known Limitations

Case Status
workspace.findFiles slow in large monorepo Mitigated: 200ms debounce, 50 max results, excludes node_modules/dist/.git/tmp
Tab drag MIME varies across VSCode/Cursor Handled: checks Files, text/uri-list, text/plain, application/vnd.code.*
No active editor for "Insert" Warning shown via vscode.window.showWarningMessage
Mention dropdown covers textarea Positioned above (relative z-index 60), capped at 250px height
Large files via @mention Only 60-line preview sent (same as ContextProviderService.getFilePreview)
Old messages lack contextSnapshot Render nothing — chips only appear on messages sent after v0.21.0
"Apply" smart placement Phase 1: opens diff view or untitled editor. Smart Apply (find exact insert point) deferred

Testing Checklist