mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
feat: highlight session cards with orange border when 'esc to interrupt' is detected
- Add checkForEscPrompt() method to scan buffer content on each update - Emit 'esc-prompt-change' event when prompt presence changes - Apply orange border to session card when prompt is detected - Case-insensitive search for 'esc to interrupt' text 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3ec549344b
commit
de8952d34a
2 changed files with 41 additions and 3 deletions
|
|
@ -27,6 +27,7 @@ export class SessionCard extends LitElement {
|
||||||
@property({ type: Object }) session!: Session;
|
@property({ type: Object }) session!: Session;
|
||||||
@state() private killing = false;
|
@state() private killing = false;
|
||||||
@state() private killingFrame = 0;
|
@state() private killingFrame = 0;
|
||||||
|
@state() private hasEscPrompt = false;
|
||||||
|
|
||||||
private killingInterval: number | null = null;
|
private killingInterval: number | null = null;
|
||||||
|
|
||||||
|
|
@ -47,6 +48,10 @@ export class SessionCard extends LitElement {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private handleEscPromptChange(event: CustomEvent) {
|
||||||
|
this.hasEscPrompt = event.detail.hasEscPrompt;
|
||||||
|
}
|
||||||
|
|
||||||
private async handleKillClick(e: Event) {
|
private async handleKillClick(e: Event) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -151,10 +156,9 @@ export class SessionCard extends LitElement {
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class="bg-vs-bg border border-vs-border rounded shadow cursor-pointer overflow-hidden ${this
|
class="bg-vs-bg rounded shadow cursor-pointer overflow-hidden ${this.killing
|
||||||
.killing
|
|
||||||
? 'opacity-60'
|
? 'opacity-60'
|
||||||
: ''}"
|
: ''} ${this.hasEscPrompt ? 'border-2 border-orange-500' : 'border border-vs-border'}"
|
||||||
@click=${this.handleCardClick}
|
@click=${this.handleCardClick}
|
||||||
>
|
>
|
||||||
<!-- Compact Header -->
|
<!-- Compact Header -->
|
||||||
|
|
@ -211,6 +215,7 @@ export class SessionCard extends LitElement {
|
||||||
.sessionId=${this.session.id}
|
.sessionId=${this.session.id}
|
||||||
class="w-full h-full"
|
class="w-full h-full"
|
||||||
style="pointer-events: none;"
|
style="pointer-events: none;"
|
||||||
|
@esc-prompt-change=${this.handleEscPromptChange}
|
||||||
></vibe-terminal-buffer>
|
></vibe-terminal-buffer>
|
||||||
`}
|
`}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ export class VibeTerminalBuffer extends LitElement {
|
||||||
@state() private error: string | null = null;
|
@state() private error: string | null = null;
|
||||||
@state() private displayedFontSize = 14;
|
@state() private displayedFontSize = 14;
|
||||||
@state() private visibleRows = 0;
|
@state() private visibleRows = 0;
|
||||||
|
@state() private containsEscPrompt = false;
|
||||||
|
|
||||||
private container: HTMLElement | null = null;
|
private container: HTMLElement | null = null;
|
||||||
private resizeObserver: ResizeObserver | null = null;
|
private resizeObserver: ResizeObserver | null = null;
|
||||||
|
|
@ -122,6 +123,9 @@ export class VibeTerminalBuffer extends LitElement {
|
||||||
this.buffer = snapshot;
|
this.buffer = snapshot;
|
||||||
this.error = null;
|
this.error = null;
|
||||||
|
|
||||||
|
// Check if buffer contains "esc to interrupt" text
|
||||||
|
this.checkForEscPrompt();
|
||||||
|
|
||||||
// Recalculate dimensions now that we have the actual cols
|
// Recalculate dimensions now that we have the actual cols
|
||||||
this.calculateDimensions();
|
this.calculateDimensions();
|
||||||
|
|
||||||
|
|
@ -130,6 +134,35 @@ export class VibeTerminalBuffer extends LitElement {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private checkForEscPrompt() {
|
||||||
|
if (!this.buffer) {
|
||||||
|
this.containsEscPrompt = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if any line contains "esc to interrupt" (case insensitive)
|
||||||
|
const searchText = 'esc to interrupt';
|
||||||
|
const found = this.buffer.cells.some((row) => {
|
||||||
|
const lineText = row
|
||||||
|
.map((cell) => cell.char)
|
||||||
|
.join('')
|
||||||
|
.toLowerCase();
|
||||||
|
return lineText.includes(searchText);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (found !== this.containsEscPrompt) {
|
||||||
|
this.containsEscPrompt = found;
|
||||||
|
// Dispatch event to notify parent
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('esc-prompt-change', {
|
||||||
|
detail: { hasEscPrompt: found },
|
||||||
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private unsubscribeFromBuffer() {
|
private unsubscribeFromBuffer() {
|
||||||
if (this.unsubscribe) {
|
if (this.unsubscribe) {
|
||||||
this.unsubscribe();
|
this.unsubscribe();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue