feat: unified hook notifier, agent auto-detection, terminal transition UI
- Add hooks/notify.ps1 as single hook handler for all events - Refactor settings.local.json to use notify.ps1 instead of inline PS - Add Notification hook, auto-detect agent from session_id/transcript - Rename agent 'main' to 'claude' across server routes and terminal - Add loading overlay and error state for terminal switching transitions - Add transitionError ref to useTranscriptDebug composable
This commit is contained in:
@@ -28,6 +28,8 @@ const {
|
||||
selectedSessionId,
|
||||
conversation,
|
||||
loading,
|
||||
transitioning,
|
||||
transitionError,
|
||||
error,
|
||||
isRealtime,
|
||||
processing,
|
||||
@@ -702,6 +704,22 @@ onBeforeUnmount(() => {
|
||||
<div class="content">
|
||||
<AquaticBackground />
|
||||
<div class="readability-overlay" :style="{ background: `rgba(0, 0, 0, ${overlayOpacity})` }" />
|
||||
<Transition name="terminal-loading">
|
||||
<div v-if="transitioning" class="terminal-loading-overlay">
|
||||
<div class="terminal-loading-spinner" />
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition name="terminal-loading">
|
||||
<div v-if="transitionError" class="terminal-error-overlay" @click="transitionError = null">
|
||||
<div class="terminal-error-content">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#f87171" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
|
||||
</svg>
|
||||
<span class="terminal-error-msg">{{ transitionError }}</span>
|
||||
<span class="terminal-error-hint">Click to dismiss</span>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<ChatContainer
|
||||
ref="chatRef"
|
||||
v-if="conversation"
|
||||
@@ -1180,6 +1198,73 @@ onBeforeUnmount(() => {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* ── Terminal switching loading overlay ── */
|
||||
.terminal-loading-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.35);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.terminal-loading-spinner {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border: 2.5px solid rgba(255, 255, 255, 0.15);
|
||||
border-top-color: rgba(255, 255, 255, 0.7);
|
||||
border-radius: 50%;
|
||||
animation: tl-spin 0.7s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes tl-spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
.terminal-error-overlay {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
backdrop-filter: blur(6px);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.terminal-error-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
max-width: 80%;
|
||||
padding: 1.2rem 1.5rem;
|
||||
background: rgba(30, 30, 30, 0.85);
|
||||
border: 1px solid rgba(248, 113, 113, 0.3);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.terminal-error-msg {
|
||||
font-size: 12px;
|
||||
color: #fca5a5;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.terminal-error-hint {
|
||||
font-size: 10px;
|
||||
color: rgba(255, 255, 255, 0.35);
|
||||
}
|
||||
|
||||
.terminal-loading-enter-active { transition: opacity 0.15s ease; }
|
||||
.terminal-loading-leave-active { transition: opacity 0.25s ease; }
|
||||
.terminal-loading-enter-from,
|
||||
.terminal-loading-leave-to { opacity: 0; }
|
||||
|
||||
/* Override ChatContainer backgrounds: glass-transparent */
|
||||
.content :deep(.chat-container) {
|
||||
background: transparent !important;
|
||||
|
||||
Reference in New Issue
Block a user