@agent-link/server 0.1.174 → 0.1.176

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.174",
3
+ "version": "0.1.176",
4
4
  "description": "AgentLink relay server",
5
5
  "license": "MIT",
6
6
  "repository": {
package/web/app.js CHANGED
@@ -439,18 +439,24 @@ const App = {
439
439
  });
440
440
  const filteredSlashCommands = computed(() => {
441
441
  if (slashMenuOpen.value && !inputText.value.startsWith('/')) return SLASH_COMMANDS;
442
+ if (!inputText.value.startsWith('/')) return SLASH_COMMANDS;
442
443
  const txt = inputText.value.toLowerCase();
443
444
  return SLASH_COMMANDS.filter(c => c.command.startsWith(txt));
444
445
  });
445
446
  watch(filteredSlashCommands, () => { slashMenuIndex.value = 0; });
446
447
 
447
448
  // ── Auto-resize textarea ──
449
+ let _autoResizeRaf = null;
448
450
  function autoResize() {
449
- const ta = inputRef.value;
450
- if (ta) {
451
- ta.style.height = 'auto';
452
- ta.style.height = Math.min(ta.scrollHeight, 160) + 'px';
453
- }
451
+ if (_autoResizeRaf) return;
452
+ _autoResizeRaf = requestAnimationFrame(() => {
453
+ _autoResizeRaf = null;
454
+ const ta = inputRef.value;
455
+ if (ta) {
456
+ ta.style.height = 'auto';
457
+ ta.style.height = Math.min(ta.scrollHeight, 160) + 'px';
458
+ }
459
+ });
454
460
  }
455
461
 
456
462
  // ── Send message ──
@@ -666,13 +672,23 @@ const App = {
666
672
  watch(loop.loopsList, () => { loadingLoops.value = false; });
667
673
 
668
674
  // ── Lifecycle ──
669
- onMounted(() => { connect(scheduleHighlight); });
675
+ function _onVisibilityChange() {
676
+ if (!document.hidden) {
677
+ nextTick(() => scrollToBottom(true));
678
+ }
679
+ }
680
+
681
+ onMounted(() => {
682
+ connect(scheduleHighlight);
683
+ document.addEventListener('visibilitychange', _onVisibilityChange);
684
+ });
670
685
  onUnmounted(() => {
671
686
  closeWs(); streaming.cleanup(); cleanupScroll(); cleanupHighlight();
672
687
  window.removeEventListener('resize', _resizeHandler);
673
688
  document.removeEventListener('click', _workdirMenuClickHandler);
674
689
  document.removeEventListener('click', _slashMenuClickOutside);
675
690
  document.removeEventListener('keydown', _workdirMenuKeyHandler);
691
+ document.removeEventListener('visibilitychange', _onVisibilityChange);
676
692
  });
677
693
 
678
694
  return {
package/web/css/input.css CHANGED
@@ -50,7 +50,7 @@
50
50
  border-radius: 16px;
51
51
  padding: 0.5rem;
52
52
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
53
- transition: border-color 0.2s, box-shadow 0.2s;
53
+ transition: border-color 0.2s;
54
54
  }
55
55
 
56
56
  .input-card:focus-within {
package/web/css/tools.css CHANGED
@@ -93,6 +93,12 @@
93
93
  border-left: 1px solid var(--border);
94
94
  padding-left: 8px;
95
95
  overflow: hidden;
96
+ animation: toolExpand 0.15s ease-out;
97
+ }
98
+
99
+ @keyframes toolExpand {
100
+ from { opacity: 0; max-height: 0; }
101
+ to { opacity: 1; max-height: 500px; }
96
102
  }
97
103
 
98
104
  .tool-block {
@@ -6,7 +6,7 @@
6
6
  * @returns {{ onScroll, scrollToBottom, cleanup }}
7
7
  */
8
8
  export function createScrollManager(selector) {
9
- let _scrollTimer = null;
9
+ let _rafId = null;
10
10
  let _userScrolledUp = false;
11
11
 
12
12
  function onScroll(e) {
@@ -16,16 +16,17 @@ export function createScrollManager(selector) {
16
16
 
17
17
  function scrollToBottom(force) {
18
18
  if (_userScrolledUp && !force) return;
19
- if (_scrollTimer) return;
20
- _scrollTimer = setTimeout(() => {
21
- _scrollTimer = null;
19
+ if (document.hidden) return;
20
+ if (_rafId) return;
21
+ _rafId = requestAnimationFrame(() => {
22
+ _rafId = null;
22
23
  const el = document.querySelector(selector);
23
24
  if (el) el.scrollTop = el.scrollHeight;
24
- }, 50);
25
+ });
25
26
  }
26
27
 
27
28
  function cleanup() {
28
- if (_scrollTimer) { clearTimeout(_scrollTimer); _scrollTimer = null; }
29
+ if (_rafId) { cancelAnimationFrame(_rafId); _rafId = null; }
29
30
  }
30
31
 
31
32
  return { onScroll, scrollToBottom, cleanup };