@agent-link/server 0.1.133 → 0.1.135

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-link/server",
3
- "version": "0.1.133",
3
+ "version": "0.1.135",
4
4
  "description": "AgentLink relay server",
5
5
  "license": "MIT",
6
6
  "repository": {
package/web/app.js CHANGED
@@ -78,6 +78,13 @@ const App = {
78
78
  const renamingSessionId = ref(null);
79
79
  const renameText = ref('');
80
80
 
81
+ // Team rename/delete state
82
+ const renamingTeamId = ref(null);
83
+ const renameTeamText = ref('');
84
+ const deleteTeamConfirmOpen = ref(false);
85
+ const deleteTeamConfirmTitle = ref('');
86
+ const pendingDeleteTeamId = ref(null);
87
+
81
88
  // Working directory history
82
89
  const workdirHistory = ref([]);
83
90
 
@@ -309,6 +316,10 @@ const App = {
309
316
  wsSend, scrollToBottom,
310
317
  });
311
318
  setTeam(team);
319
+ sidebar.setOnSwitchToChat(() => {
320
+ team.teamMode.value = 'chat';
321
+ team.historicalTeam.value = null;
322
+ });
312
323
 
313
324
  // File browser module
314
325
  const fileBrowser = createFileBrowser({
@@ -533,6 +544,40 @@ const App = {
533
544
  startRename: sidebar.startRename,
534
545
  confirmRename: sidebar.confirmRename,
535
546
  cancelRename: sidebar.cancelRename,
547
+ // Team rename/delete
548
+ renamingTeamId, renameTeamText,
549
+ deleteTeamConfirmOpen, deleteTeamConfirmTitle, pendingDeleteTeamId,
550
+ startTeamRename(t) {
551
+ renamingTeamId.value = t.teamId;
552
+ renameTeamText.value = t.title || '';
553
+ },
554
+ confirmTeamRename() {
555
+ const tid = renamingTeamId.value;
556
+ const title = renameTeamText.value.trim();
557
+ if (!tid || !title) { renamingTeamId.value = null; renameTeamText.value = ''; return; }
558
+ team.renameTeamById(tid, title);
559
+ renamingTeamId.value = null;
560
+ renameTeamText.value = '';
561
+ },
562
+ cancelTeamRename() {
563
+ renamingTeamId.value = null;
564
+ renameTeamText.value = '';
565
+ },
566
+ requestDeleteTeam(t) {
567
+ pendingDeleteTeamId.value = t.teamId;
568
+ deleteTeamConfirmTitle.value = t.title || t.teamId.slice(0, 8);
569
+ deleteTeamConfirmOpen.value = true;
570
+ },
571
+ confirmDeleteTeam() {
572
+ if (!pendingDeleteTeamId.value) return;
573
+ team.deleteTeamById(pendingDeleteTeamId.value);
574
+ deleteTeamConfirmOpen.value = false;
575
+ pendingDeleteTeamId.value = null;
576
+ },
577
+ cancelDeleteTeam() {
578
+ deleteTeamConfirmOpen.value = false;
579
+ pendingDeleteTeamId.value = null;
580
+ },
536
581
  // Working directory history
537
582
  filteredWorkdirHistory: sidebar.filteredWorkdirHistory,
538
583
  switchToWorkdir: sidebar.switchToWorkdir,
@@ -592,6 +637,8 @@ const App = {
592
637
  viewDashboard: team.viewDashboard,
593
638
  viewHistoricalTeam: team.viewHistoricalTeam,
594
639
  requestTeamsList: team.requestTeamsList,
640
+ deleteTeamById: team.deleteTeamById,
641
+ renameTeamById: team.renameTeamById,
595
642
  getAgentColor: team.getAgentColor,
596
643
  findAgent: team.findAgent,
597
644
  getAgentMessages: team.getAgentMessages,
@@ -822,16 +869,36 @@ const App = {
822
869
  <div
823
870
  v-for="t in teamsList" :key="t.teamId"
824
871
  :class="['team-history-item', { active: displayTeam && displayTeam.teamId === t.teamId }]"
825
- @click="viewHistoricalTeam(t.teamId)"
872
+ @click="renamingTeamId !== t.teamId && viewHistoricalTeam(t.teamId)"
826
873
  :title="t.title"
827
874
  >
828
875
  <svg class="team-history-icon" viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></svg>
829
876
  <div class="team-history-info">
830
- <div class="team-history-title">{{ t.title || 'Untitled team' }}</div>
831
- <div class="team-history-meta">
877
+ <div v-if="renamingTeamId === t.teamId" class="session-rename-row">
878
+ <input
879
+ class="session-rename-input"
880
+ v-model="renameTeamText"
881
+ @click.stop
882
+ @keydown.enter.stop="confirmTeamRename"
883
+ @keydown.escape.stop="cancelTeamRename"
884
+ @vue:mounted="$event.el.focus()"
885
+ />
886
+ <button class="session-rename-ok" @click.stop="confirmTeamRename" title="Confirm">&#10003;</button>
887
+ <button class="session-rename-cancel" @click.stop="cancelTeamRename" title="Cancel">&times;</button>
888
+ </div>
889
+ <div v-else class="team-history-title">{{ t.title || 'Untitled team' }}</div>
890
+ <div v-if="renamingTeamId !== t.teamId" class="team-history-meta">
832
891
  <span :class="['team-status-badge', 'team-status-badge-sm', 'team-status-' + t.status]">{{ t.status }}</span>
833
892
  <span v-if="t.taskCount" class="team-history-tasks">{{ t.taskCount }} tasks</span>
834
893
  <span v-if="t.totalCost" class="team-history-tasks">{{'$' + t.totalCost.toFixed(2) }}</span>
894
+ <span class="session-actions">
895
+ <button class="session-rename-btn" @click.stop="startTeamRename(t)" title="Rename team">
896
+ <svg viewBox="0 0 24 24" width="12" height="12"><path fill="currentColor" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
897
+ </button>
898
+ <button class="session-delete-btn" @click.stop="requestDeleteTeam(t)" title="Delete team">
899
+ <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>
900
+ </button>
901
+ </span>
835
902
  </div>
836
903
  </div>
837
904
  </div>
@@ -1622,6 +1689,22 @@ const App = {
1622
1689
  </div>
1623
1690
  </div>
1624
1691
 
1692
+ <!-- Delete Team Confirmation Dialog -->
1693
+ <div class="folder-picker-overlay" v-if="deleteTeamConfirmOpen" @click.self="cancelDeleteTeam">
1694
+ <div class="delete-confirm-dialog">
1695
+ <div class="delete-confirm-header">Delete Team</div>
1696
+ <div class="delete-confirm-body">
1697
+ <p>Are you sure you want to delete this team?</p>
1698
+ <p class="delete-confirm-title">{{ deleteTeamConfirmTitle }}</p>
1699
+ <p class="delete-confirm-warning">This action cannot be undone.</p>
1700
+ </div>
1701
+ <div class="delete-confirm-footer">
1702
+ <button class="folder-picker-cancel" @click="cancelDeleteTeam">Cancel</button>
1703
+ <button class="delete-confirm-btn" @click="confirmDeleteTeam">Delete</button>
1704
+ </div>
1705
+ </div>
1706
+ </div>
1707
+
1625
1708
  <!-- Password Authentication Dialog -->
1626
1709
  <div class="folder-picker-overlay" v-if="authRequired && !authLocked">
1627
1710
  <div class="auth-dialog">
@@ -37,6 +37,10 @@ export function createSidebar(deps) {
37
37
  switchConversation,
38
38
  } = deps;
39
39
 
40
+ // Late-binding callback: called when user switches to a normal chat session
41
+ let _onSwitchToChat = null;
42
+ function setOnSwitchToChat(fn) { _onSwitchToChat = fn; }
43
+
40
44
  // ── Workdir switching timeout ──
41
45
  let _workdirSwitchTimer = null;
42
46
  function setWorkdirSwitching() {
@@ -69,6 +73,7 @@ export function createSidebar(deps) {
69
73
 
70
74
  function resumeSession(session) {
71
75
  if (window.innerWidth <= 768) sidebarOpen.value = false;
76
+ if (_onSwitchToChat) _onSwitchToChat();
72
77
 
73
78
  // Multi-session: check if we already have a conversation loaded for this claudeSessionId
74
79
  if (switchConversation && conversationCache) {
@@ -117,6 +122,7 @@ export function createSidebar(deps) {
117
122
 
118
123
  function newConversation() {
119
124
  if (window.innerWidth <= 768) sidebarOpen.value = false;
125
+ if (_onSwitchToChat) _onSwitchToChat();
120
126
 
121
127
  // Multi-session: just switch to a new blank conversation
122
128
  if (switchConversation) {
@@ -375,6 +381,7 @@ export function createSidebar(deps) {
375
381
 
376
382
  return {
377
383
  requestSessionList, resumeSession, newConversation, toggleSidebar,
384
+ setOnSwitchToChat,
378
385
  deleteSession, confirmDeleteSession, cancelDeleteSession,
379
386
  startRename, confirmRename, cancelRename,
380
387
  openFolderPicker, folderPickerNavigateUp, folderPickerSelectItem,
@@ -96,6 +96,14 @@ export function createTeam(deps) {
96
96
  wsSend({ type: 'list_teams' });
97
97
  }
98
98
 
99
+ function deleteTeamById(teamId) {
100
+ wsSend({ type: 'delete_team', teamId });
101
+ }
102
+
103
+ function renameTeamById(teamId, newTitle) {
104
+ wsSend({ type: 'rename_team', teamId, newTitle });
105
+ }
106
+
99
107
  function requestAgentHistory(teamId, agentId) {
100
108
  wsSend({ type: 'get_team_agent_history', teamId, agentId });
101
109
  }
@@ -220,6 +228,28 @@ export function createTeam(deps) {
220
228
  teamsList.value = msg.teams || [];
221
229
  return true;
222
230
 
231
+ case 'team_deleted':
232
+ teamsList.value = teamsList.value.filter(t => t.teamId !== msg.teamId);
233
+ // If viewing the deleted team, go back
234
+ if (historicalTeam.value && historicalTeam.value.teamId === msg.teamId) {
235
+ historicalTeam.value = null;
236
+ }
237
+ return true;
238
+
239
+ case 'team_renamed': {
240
+ const item = teamsList.value.find(t => t.teamId === msg.teamId);
241
+ if (item) item.title = msg.newTitle;
242
+ // Update historical view if showing this team
243
+ if (historicalTeam.value && historicalTeam.value.teamId === msg.teamId) {
244
+ historicalTeam.value.title = msg.newTitle;
245
+ }
246
+ // Update active team if it's the same
247
+ if (teamState.value && teamState.value.teamId === msg.teamId) {
248
+ teamState.value.title = msg.newTitle;
249
+ }
250
+ return true;
251
+ }
252
+
223
253
  case 'team_detail':
224
254
  historicalTeam.value = msg.team;
225
255
  teamMode.value = 'team';
@@ -334,7 +364,8 @@ export function createTeam(deps) {
334
364
  pendingTasks, activeTasks, doneTasks, failedTasks,
335
365
  // Methods
336
366
  launchTeam, dissolveTeam, viewAgent, viewDashboard,
337
- viewHistoricalTeam, requestTeamsList, requestAgentHistory,
367
+ viewHistoricalTeam, requestTeamsList, deleteTeamById, renameTeamById,
368
+ requestAgentHistory,
338
369
  getAgentColor, findAgent, getAgentMessages, backToChat, newTeam,
339
370
  // Message handling
340
371
  handleTeamMessage, handleTeamAgentOutput, handleActiveTeamRestore,
package/web/style.css CHANGED
@@ -566,6 +566,10 @@ body {
566
566
  visibility: visible;
567
567
  }
568
568
 
569
+ .team-history-item:hover .session-actions {
570
+ visibility: visible;
571
+ }
572
+
569
573
  .session-delete-btn {
570
574
  display: flex;
571
575
  align-items: center;
@@ -3534,6 +3538,9 @@ body {
3534
3538
  /* ── Teams sidebar section (history list in sidebar) ── */
3535
3539
  .sidebar-teams {
3536
3540
  padding: 0.75rem;
3541
+ max-height: 35%;
3542
+ overflow-y: auto;
3543
+ flex-shrink: 0;
3537
3544
  }
3538
3545
 
3539
3546
  .team-history-list {