Skip to content

Commit 4c315b4

Browse files
ozgesolidkeyclaude
andcommitted
Redesign annotations as speech balloons, improve folder panel buttons
Annotations: - Changed from inline overlays to speech balloon style on right side - Colored dot indicator (purple/amber/red) with count badge - Balloon with arrow, agent name, and comment text - No longer mixes with log line content Folder panel: - Replaced text buttons (+/SSH) with SVG icon buttons - SSH button now opens Live panel when no SSH connection active (instead of showing a blocking alert) - Better tooltip explains SSH requires active connection Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5c4027e commit 4c315b4

3 files changed

Lines changed: 99 additions & 34 deletions

File tree

src/renderer/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,12 @@
121121
<!-- Folders Panel -->
122122
<div class="panel-view" id="panel-folders" data-panel="folders">
123123
<div class="section-header-inline">
124-
<button id="btn-add-folder" class="section-btn" title="Open folder">+</button>
125-
<button id="btn-open-ssh-folder" class="section-btn" title="Browse SSH remote files">SSH</button>
124+
<button id="btn-add-folder" class="section-btn" title="Open local folder">
125+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/><line x1="12" y1="11" x2="12" y2="17"/><line x1="9" y1="14" x2="15" y2="14"/></svg>
126+
</button>
127+
<button id="btn-open-ssh-folder" class="section-btn" title="Browse SSH remote files (requires active SSH connection in Live panel)">
128+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="2"/><path d="M7 8l4 4-4 4"/><line x1="13" y1="16" x2="17" y2="16"/></svg>
129+
</button>
126130
</div>
127131
<div class="folder-search-container">
128132
<input type="text" id="folder-search-input" class="folder-search-input" placeholder="Search in folders..." disabled>

src/renderer/renderer.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,18 +2474,36 @@ function renderVisibleLines(): void {
24742474

24752475
fragment.appendChild(lineElement);
24762476

2477-
// Agent annotation overlay (only when visible and annotations exist for this line)
2477+
// Agent annotation balloon (only when visible and annotations exist for this line)
24782478
if (state.showAnnotations && state.annotationsByLine.size > 0) {
24792479
const lineAnns = state.annotationsByLine.get(line.lineNumber);
24802480
if (lineAnns) {
2481+
// Show a small indicator dot on the line + balloon on hover/always
2482+
const indicator = document.createElement('div');
2483+
indicator.className = 'annotation-indicator';
2484+
indicator.style.cssText = `position:absolute;right:44px;transform:translateY(${top}px);z-index:3;`;
2485+
indicator.dataset.lineNumber = String(line.lineNumber);
2486+
2487+
// Build balloon content (stacked if multiple)
2488+
let balloonHtml = '';
24812489
for (const ann of lineAnns) {
2482-
const annEl = document.createElement('div');
2483-
annEl.className = `annotation-row severity-${ann.severity || 'info'}`;
2484-
annEl.style.cssText = `position:absolute;left:0;right:0;transform:translateY(${top + getLineHeight()}px);z-index:2;pointer-events:auto;`;
2485-
annEl.innerHTML = `<span class="annotation-agent">${escapeHtml(ann.agentName)}</span> <span class="annotation-text">${escapeHtml(ann.text)}</span>`;
2486-
annEl.title = `${ann.agentName}${new Date(ann.timestamp).toLocaleTimeString()}`;
2487-
fragment.appendChild(annEl);
2490+
const sevClass = `severity-${ann.severity || 'info'}`;
2491+
balloonHtml += `<div class="annotation-balloon ${sevClass}">` +
2492+
`<span class="annotation-agent">${escapeHtml(ann.agentName)}</span>` +
2493+
`<span class="annotation-text">${escapeHtml(ann.text)}</span>` +
2494+
`</div>`;
24882495
}
2496+
2497+
const balloon = document.createElement('div');
2498+
balloon.className = 'annotation-balloon-container';
2499+
balloon.style.cssText = `position:absolute;right:48px;transform:translateY(${top - 4}px);z-index:10;`;
2500+
balloon.innerHTML = balloonHtml;
2501+
2502+
indicator.innerHTML = `<span class="annotation-dot severity-${lineAnns[0].severity || 'info'}">${lineAnns.length > 1 ? lineAnns.length : ''}</span>`;
2503+
indicator.title = lineAnns.map(a => `${a.agentName}: ${a.text}`).join('\n');
2504+
2505+
fragment.appendChild(indicator);
2506+
fragment.appendChild(balloon);
24892507
}
24902508
}
24912509

@@ -6773,7 +6791,9 @@ async function openSshFolder(): Promise<void> {
67736791
}
67746792
}
67756793
if (!sshConn) {
6776-
alert('Connect to an SSH host first via the Live panel, then use this button to browse its files.');
6794+
// No active SSH — open Live panel so user can connect
6795+
openBottomTab('live');
6796+
addChatMessage({ from: 'agent', text: 'To browse SSH files, first connect to a host in the Live panel, then click the SSH browse button again.', timestamp: Date.now() });
67776797
return;
67786798
}
67796799

src/renderer/styles.css

Lines changed: 65 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3152,41 +3152,82 @@ body.platform-darwin .titlebar {
31523152
background-color: rgba(180, 120, 255, 0.8);
31533153
}
31543154

3155-
/* Agent Annotations */
3156-
.annotation-row {
3155+
/* Agent Annotations — Speech Balloon Style */
3156+
.annotation-indicator {
3157+
width: 20px;
3158+
height: 20px;
31573159
display: flex;
31583160
align-items: center;
3159-
gap: 6px;
3160-
height: 20px;
3161-
padding: 0 8px 0 60px;
3161+
justify-content: center;
3162+
cursor: pointer;
3163+
}
3164+
3165+
.annotation-dot {
3166+
display: inline-flex;
3167+
align-items: center;
3168+
justify-content: center;
3169+
width: 18px;
3170+
height: 18px;
3171+
border-radius: 50%;
3172+
font-size: 9px;
3173+
font-weight: 700;
3174+
color: #fff;
3175+
background: rgba(180, 120, 255, 0.8);
3176+
}
3177+
.annotation-dot.severity-warning { background: rgba(255, 180, 40, 0.85); }
3178+
.annotation-dot.severity-error { background: rgba(255, 80, 80, 0.85); }
3179+
3180+
.annotation-balloon-container {
3181+
display: flex;
3182+
flex-direction: column;
3183+
gap: 4px;
3184+
max-width: 320px;
3185+
pointer-events: auto;
3186+
}
3187+
3188+
.annotation-balloon {
3189+
background: rgba(40, 35, 55, 0.95);
3190+
border: 1px solid rgba(180, 120, 255, 0.4);
3191+
border-radius: 8px;
3192+
padding: 5px 10px;
31623193
font-size: 11px;
3163-
line-height: 20px;
3164-
overflow: hidden;
3165-
white-space: nowrap;
3166-
text-overflow: ellipsis;
3167-
border-left: 2px solid rgba(180, 120, 255, 0.6);
3168-
background: rgba(180, 120, 255, 0.08);
3194+
line-height: 1.4;
3195+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
3196+
position: relative;
31693197
}
3170-
.annotation-row.severity-warning {
3171-
border-left-color: rgba(255, 180, 40, 0.7);
3172-
background: rgba(255, 180, 40, 0.08);
3198+
.annotation-balloon.severity-warning {
3199+
border-color: rgba(255, 180, 40, 0.5);
3200+
background: rgba(50, 40, 25, 0.95);
31733201
}
3174-
.annotation-row.severity-error {
3175-
border-left-color: rgba(255, 80, 80, 0.7);
3176-
background: rgba(255, 80, 80, 0.08);
3202+
.annotation-balloon.severity-error {
3203+
border-color: rgba(255, 80, 80, 0.5);
3204+
background: rgba(50, 25, 25, 0.95);
31773205
}
3206+
/* Speech bubble arrow */
3207+
.annotation-balloon::after {
3208+
content: '';
3209+
position: absolute;
3210+
right: -6px;
3211+
top: 8px;
3212+
width: 0;
3213+
height: 0;
3214+
border-top: 5px solid transparent;
3215+
border-bottom: 5px solid transparent;
3216+
border-left: 6px solid rgba(180, 120, 255, 0.4);
3217+
}
3218+
.annotation-balloon.severity-warning::after { border-left-color: rgba(255, 180, 40, 0.5); }
3219+
.annotation-balloon.severity-error::after { border-left-color: rgba(255, 80, 80, 0.5); }
3220+
31783221
.annotation-agent {
3179-
color: rgba(180, 120, 255, 0.7);
3222+
color: rgba(180, 120, 255, 0.8);
31803223
font-weight: 600;
31813224
font-size: 10px;
3182-
flex-shrink: 0;
3225+
margin-right: 6px;
31833226
}
3184-
.severity-warning .annotation-agent { color: rgba(255, 180, 40, 0.8); }
3185-
.severity-error .annotation-agent { color: rgba(255, 80, 80, 0.8); }
3227+
.severity-warning .annotation-agent { color: rgba(255, 180, 40, 0.9); }
3228+
.severity-error .annotation-agent { color: rgba(255, 80, 80, 0.9); }
31863229
.annotation-text {
3187-
color: var(--text-secondary);
3188-
overflow: hidden;
3189-
text-overflow: ellipsis;
3230+
color: var(--text-primary);
31903231
}
31913232

31923233
/* Tab Bar */

0 commit comments

Comments
 (0)