@agent-link/server 0.1.52 → 0.1.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/app.js +38 -2
- package/web/modules/connection.js +10 -2
- package/web/modules/sidebar.js +28 -0
- package/web/style.css +114 -1
package/package.json
CHANGED
package/web/app.js
CHANGED
|
@@ -64,6 +64,10 @@ const App = {
|
|
|
64
64
|
const folderPickerLoading = ref(false);
|
|
65
65
|
const folderPickerSelected = ref('');
|
|
66
66
|
|
|
67
|
+
// Delete confirmation dialog state
|
|
68
|
+
const deleteConfirmOpen = ref(false);
|
|
69
|
+
const deleteConfirmTitle = ref('');
|
|
70
|
+
|
|
67
71
|
// File attachment state
|
|
68
72
|
const attachments = ref([]);
|
|
69
73
|
const fileInputRef = ref(null);
|
|
@@ -136,6 +140,7 @@ const App = {
|
|
|
136
140
|
loadingSessions, loadingHistory, workDir, visibleLimit,
|
|
137
141
|
folderPickerOpen, folderPickerPath, folderPickerEntries,
|
|
138
142
|
folderPickerLoading, folderPickerSelected, streaming,
|
|
143
|
+
deleteConfirmOpen, deleteConfirmTitle,
|
|
139
144
|
});
|
|
140
145
|
|
|
141
146
|
const { connect, wsSend, closeWs } = createConnection({
|
|
@@ -268,6 +273,11 @@ const App = {
|
|
|
268
273
|
folderPickerEnter: sidebar.folderPickerEnter,
|
|
269
274
|
folderPickerGoToPath: sidebar.folderPickerGoToPath,
|
|
270
275
|
confirmFolderPicker: sidebar.confirmFolderPicker,
|
|
276
|
+
// Delete session
|
|
277
|
+
deleteConfirmOpen, deleteConfirmTitle,
|
|
278
|
+
deleteSession: sidebar.deleteSession,
|
|
279
|
+
confirmDeleteSession: sidebar.confirmDeleteSession,
|
|
280
|
+
cancelDeleteSession: sidebar.cancelDeleteSession,
|
|
271
281
|
// File attachments
|
|
272
282
|
attachments, fileInputRef, dragOver,
|
|
273
283
|
triggerFileInput: fileAttach.triggerFileInput,
|
|
@@ -362,7 +372,17 @@ const App = {
|
|
|
362
372
|
:title="s.preview"
|
|
363
373
|
>
|
|
364
374
|
<div class="session-title">{{ s.title }}</div>
|
|
365
|
-
<div class="session-meta">
|
|
375
|
+
<div class="session-meta">
|
|
376
|
+
<span>{{ formatRelativeTime(s.lastModified) }}</span>
|
|
377
|
+
<button
|
|
378
|
+
v-if="currentClaudeSessionId !== s.sessionId"
|
|
379
|
+
class="session-delete-btn"
|
|
380
|
+
@click.stop="deleteSession(s)"
|
|
381
|
+
title="Delete session"
|
|
382
|
+
>
|
|
383
|
+
<svg viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
|
|
384
|
+
</button>
|
|
385
|
+
</div>
|
|
366
386
|
</div>
|
|
367
387
|
</div>
|
|
368
388
|
</div>
|
|
@@ -505,7 +525,7 @@ const App = {
|
|
|
505
525
|
</div>
|
|
506
526
|
|
|
507
527
|
<!-- System message -->
|
|
508
|
-
<div v-else-if="msg.role === 'system'" :class="['system-msg', { 'compact-msg': msg.isCompactStart, 'command-output-msg': msg.isCommandOutput }]">
|
|
528
|
+
<div v-else-if="msg.role === 'system'" :class="['system-msg', { 'compact-msg': msg.isCompactStart, 'command-output-msg': msg.isCommandOutput, 'error-msg': msg.isError }]">
|
|
509
529
|
<template v-if="msg.isCompactStart && !msg.compactDone">
|
|
510
530
|
<span class="compact-inline-spinner"></span>
|
|
511
531
|
</template>
|
|
@@ -614,6 +634,22 @@ const App = {
|
|
|
614
634
|
</div>
|
|
615
635
|
</div>
|
|
616
636
|
</div>
|
|
637
|
+
|
|
638
|
+
<!-- Delete Session Confirmation Dialog -->
|
|
639
|
+
<div class="folder-picker-overlay" v-if="deleteConfirmOpen" @click.self="cancelDeleteSession">
|
|
640
|
+
<div class="delete-confirm-dialog">
|
|
641
|
+
<div class="delete-confirm-header">Delete Session</div>
|
|
642
|
+
<div class="delete-confirm-body">
|
|
643
|
+
<p>Are you sure you want to delete this session?</p>
|
|
644
|
+
<p class="delete-confirm-title">{{ deleteConfirmTitle }}</p>
|
|
645
|
+
<p class="delete-confirm-warning">This action cannot be undone.</p>
|
|
646
|
+
</div>
|
|
647
|
+
<div class="delete-confirm-footer">
|
|
648
|
+
<button class="folder-picker-cancel" @click="cancelDeleteSession">Cancel</button>
|
|
649
|
+
<button class="delete-confirm-btn" @click="confirmDeleteSession">Delete</button>
|
|
650
|
+
</div>
|
|
651
|
+
</div>
|
|
652
|
+
</div>
|
|
617
653
|
</div>
|
|
618
654
|
`
|
|
619
655
|
};
|
|
@@ -173,8 +173,14 @@ export function createConnection(deps) {
|
|
|
173
173
|
}
|
|
174
174
|
sidebar.requestSessionList();
|
|
175
175
|
} else if (msg.type === 'error') {
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
streaming.flushReveal();
|
|
177
|
+
finalizeStreamingMsg(scheduleHighlight);
|
|
178
|
+
messages.value.push({
|
|
179
|
+
id: streaming.nextId(), role: 'system',
|
|
180
|
+
content: msg.message, isError: true,
|
|
181
|
+
timestamp: new Date(),
|
|
182
|
+
});
|
|
183
|
+
scrollToBottom();
|
|
178
184
|
isProcessing.value = false;
|
|
179
185
|
isCompacting.value = false;
|
|
180
186
|
} else if (msg.type === 'claude_output') {
|
|
@@ -251,6 +257,8 @@ export function createConnection(deps) {
|
|
|
251
257
|
} else if (msg.type === 'sessions_list') {
|
|
252
258
|
historySessions.value = msg.sessions || [];
|
|
253
259
|
loadingSessions.value = false;
|
|
260
|
+
} else if (msg.type === 'session_deleted') {
|
|
261
|
+
historySessions.value = historySessions.value.filter(s => s.sessionId !== msg.sessionId);
|
|
254
262
|
} else if (msg.type === 'conversation_resumed') {
|
|
255
263
|
currentClaudeSessionId.value = msg.claudeSessionId;
|
|
256
264
|
if (msg.history && Array.isArray(msg.history)) {
|
package/web/modules/sidebar.js
CHANGED
|
@@ -79,6 +79,33 @@ export function createSidebar(deps) {
|
|
|
79
79
|
sidebarOpen.value = !sidebarOpen.value;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// ── Delete session ──
|
|
83
|
+
|
|
84
|
+
/** Session pending delete confirmation (null = dialog closed) */
|
|
85
|
+
let pendingDeleteSession = null;
|
|
86
|
+
const deleteConfirmOpen = deps.deleteConfirmOpen;
|
|
87
|
+
const deleteConfirmTitle = deps.deleteConfirmTitle;
|
|
88
|
+
|
|
89
|
+
function deleteSession(session) {
|
|
90
|
+
if (isProcessing.value) return;
|
|
91
|
+
if (currentClaudeSessionId.value === session.sessionId) return; // guard
|
|
92
|
+
pendingDeleteSession = session;
|
|
93
|
+
deleteConfirmTitle.value = session.title || session.sessionId.slice(0, 8);
|
|
94
|
+
deleteConfirmOpen.value = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function confirmDeleteSession() {
|
|
98
|
+
if (!pendingDeleteSession) return;
|
|
99
|
+
wsSend({ type: 'delete_session', sessionId: pendingDeleteSession.sessionId });
|
|
100
|
+
deleteConfirmOpen.value = false;
|
|
101
|
+
pendingDeleteSession = null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function cancelDeleteSession() {
|
|
105
|
+
deleteConfirmOpen.value = false;
|
|
106
|
+
pendingDeleteSession = null;
|
|
107
|
+
}
|
|
108
|
+
|
|
82
109
|
// ── Folder picker ──
|
|
83
110
|
|
|
84
111
|
function openFolderPicker() {
|
|
@@ -179,6 +206,7 @@ export function createSidebar(deps) {
|
|
|
179
206
|
|
|
180
207
|
return {
|
|
181
208
|
requestSessionList, resumeSession, newConversation, toggleSidebar,
|
|
209
|
+
deleteSession, confirmDeleteSession, cancelDeleteSession,
|
|
182
210
|
openFolderPicker, folderPickerNavigateUp, folderPickerSelectItem,
|
|
183
211
|
folderPickerEnter, folderPickerGoToPath, confirmFolderPicker,
|
|
184
212
|
groupedSessions,
|
package/web/style.css
CHANGED
|
@@ -438,6 +438,100 @@ body {
|
|
|
438
438
|
font-size: 0.7rem;
|
|
439
439
|
color: var(--text-secondary);
|
|
440
440
|
margin-top: 2px;
|
|
441
|
+
display: flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
justify-content: space-between;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.session-delete-btn {
|
|
447
|
+
display: none;
|
|
448
|
+
align-items: center;
|
|
449
|
+
justify-content: center;
|
|
450
|
+
width: 20px;
|
|
451
|
+
height: 20px;
|
|
452
|
+
background: none;
|
|
453
|
+
border: none;
|
|
454
|
+
border-radius: 4px;
|
|
455
|
+
color: var(--text-secondary);
|
|
456
|
+
cursor: pointer;
|
|
457
|
+
padding: 0;
|
|
458
|
+
transition: color 0.15s, background 0.15s;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
.session-item:hover .session-delete-btn {
|
|
462
|
+
display: flex;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
.session-delete-btn:hover {
|
|
466
|
+
color: var(--error);
|
|
467
|
+
background: rgba(239, 68, 68, 0.1);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/* ── Delete confirmation dialog ── */
|
|
471
|
+
.delete-confirm-dialog {
|
|
472
|
+
width: 360px;
|
|
473
|
+
background: var(--bg-secondary);
|
|
474
|
+
border: 1px solid var(--border);
|
|
475
|
+
border-radius: 12px;
|
|
476
|
+
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
.delete-confirm-header {
|
|
480
|
+
padding: 12px 16px;
|
|
481
|
+
font-size: 0.95rem;
|
|
482
|
+
font-weight: 600;
|
|
483
|
+
border-bottom: 1px solid var(--border);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
.delete-confirm-body {
|
|
487
|
+
padding: 16px;
|
|
488
|
+
font-size: 0.88rem;
|
|
489
|
+
line-height: 1.5;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.delete-confirm-body p {
|
|
493
|
+
margin-bottom: 6px;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.delete-confirm-title {
|
|
497
|
+
font-weight: 500;
|
|
498
|
+
color: var(--text-primary);
|
|
499
|
+
overflow: hidden;
|
|
500
|
+
text-overflow: ellipsis;
|
|
501
|
+
white-space: nowrap;
|
|
502
|
+
padding: 6px 10px;
|
|
503
|
+
background: var(--bg-tertiary);
|
|
504
|
+
border-radius: 6px;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
.delete-confirm-warning {
|
|
508
|
+
font-size: 0.78rem;
|
|
509
|
+
color: var(--text-secondary);
|
|
510
|
+
margin-top: 4px;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
.delete-confirm-footer {
|
|
514
|
+
padding: 10px 16px;
|
|
515
|
+
display: flex;
|
|
516
|
+
justify-content: flex-end;
|
|
517
|
+
gap: 8px;
|
|
518
|
+
border-top: 1px solid var(--border);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.delete-confirm-btn {
|
|
522
|
+
padding: 6px 20px;
|
|
523
|
+
background: var(--error);
|
|
524
|
+
color: #fff;
|
|
525
|
+
border: none;
|
|
526
|
+
border-radius: 8px;
|
|
527
|
+
font-size: 0.85rem;
|
|
528
|
+
font-weight: 600;
|
|
529
|
+
cursor: pointer;
|
|
530
|
+
transition: background 0.15s;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
.delete-confirm-btn:hover {
|
|
534
|
+
background: #dc2626;
|
|
441
535
|
}
|
|
442
536
|
|
|
443
537
|
/* ── Chat area (message list + input) ── */
|
|
@@ -693,6 +787,7 @@ body {
|
|
|
693
787
|
.tool-line-wrapper {
|
|
694
788
|
max-width: 100%;
|
|
695
789
|
padding-left: 0.25rem;
|
|
790
|
+
overflow: hidden;
|
|
696
791
|
}
|
|
697
792
|
|
|
698
793
|
.tool-line {
|
|
@@ -706,6 +801,8 @@ body {
|
|
|
706
801
|
user-select: none;
|
|
707
802
|
transition: background 0.15s;
|
|
708
803
|
color: var(--text-secondary);
|
|
804
|
+
min-width: 0;
|
|
805
|
+
overflow: hidden;
|
|
709
806
|
}
|
|
710
807
|
|
|
711
808
|
.tool-line:hover {
|
|
@@ -723,7 +820,10 @@ body {
|
|
|
723
820
|
.tool-name {
|
|
724
821
|
font-weight: 500;
|
|
725
822
|
color: var(--text-secondary);
|
|
726
|
-
|
|
823
|
+
overflow: hidden;
|
|
824
|
+
text-overflow: ellipsis;
|
|
825
|
+
white-space: nowrap;
|
|
826
|
+
min-width: 0;
|
|
727
827
|
}
|
|
728
828
|
|
|
729
829
|
.tool-summary {
|
|
@@ -1197,6 +1297,19 @@ body {
|
|
|
1197
1297
|
padding: 0.5rem 0;
|
|
1198
1298
|
}
|
|
1199
1299
|
|
|
1300
|
+
.system-msg.error-msg {
|
|
1301
|
+
text-align: left;
|
|
1302
|
+
font-style: normal;
|
|
1303
|
+
color: #ef4444;
|
|
1304
|
+
background: rgba(239, 68, 68, 0.08);
|
|
1305
|
+
border: 1px solid rgba(239, 68, 68, 0.2);
|
|
1306
|
+
border-radius: 8px;
|
|
1307
|
+
padding: 0.75rem 1rem;
|
|
1308
|
+
font-size: 0.85rem;
|
|
1309
|
+
word-break: break-word;
|
|
1310
|
+
overflow-wrap: break-word;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1200
1313
|
/* ── History loading indicator ── */
|
|
1201
1314
|
.history-loading {
|
|
1202
1315
|
display: flex;
|