agentgui 1.0.751 → 1.0.753

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/static/app.js CHANGED
@@ -749,4 +749,82 @@ function downloadScreenshot() {
749
749
  console.log('Download screenshot not yet implemented');
750
750
  }
751
751
 
752
+ function showShortcutsOverlay() {
753
+ if (document.querySelector('.shortcuts-overlay')) return;
754
+ const overlay = document.createElement('div');
755
+ overlay.className = 'shortcuts-overlay';
756
+ overlay.innerHTML = `<div class="shortcuts-panel">
757
+ <h3>Keyboard Shortcuts</h3>
758
+ <table>
759
+ <tr><td><kbd>Ctrl</kbd>+<kbd>N</kbd></td><td>New conversation</td></tr>
760
+ <tr><td><kbd>Ctrl</kbd>+<kbd>B</kbd></td><td>Toggle sidebar</td></tr>
761
+ <tr><td><kbd>Ctrl</kbd>+<kbd>Enter</kbd></td><td>Send message</td></tr>
762
+ <tr><td><kbd>Escape</kbd></td><td>Cancel stream / blur input</td></tr>
763
+ <tr><td><kbd>?</kbd></td><td>Show this help</td></tr>
764
+ </table>
765
+ <p style="margin:1rem 0 0;font-size:0.75rem;color:#9ca3af;">Press Escape to close</p>
766
+ </div>`;
767
+ overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
768
+ document.body.appendChild(overlay);
769
+ }
770
+
771
+ document.addEventListener('keydown', (e) => {
772
+ if (e.key === '?' && !e.ctrlKey && !e.metaKey) {
773
+ const tag = document.activeElement?.tagName;
774
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
775
+ e.preventDefault();
776
+ showShortcutsOverlay();
777
+ }
778
+ if (e.key === 'Escape' && document.querySelector('.shortcuts-overlay')) {
779
+ document.querySelector('.shortcuts-overlay').remove();
780
+ }
781
+ });
782
+
783
+ (function initSidebarSearch() {
784
+ const input = document.getElementById('sidebarSearchInput');
785
+ if (!input) return;
786
+ let debounceTimer;
787
+ input.addEventListener('input', () => {
788
+ clearTimeout(debounceTimer);
789
+ debounceTimer = setTimeout(() => {
790
+ const query = input.value.trim();
791
+ const list = document.querySelector('[data-conversation-list]');
792
+ if (!list) return;
793
+ const items = list.querySelectorAll('li[data-conv-id]');
794
+ if (!query) {
795
+ items.forEach(li => li.style.display = '');
796
+ return;
797
+ }
798
+ const lower = query.toLowerCase();
799
+ items.forEach(li => {
800
+ const text = li.textContent.toLowerCase();
801
+ li.style.display = text.includes(lower) ? '' : 'none';
802
+ });
803
+ }, 150);
804
+ });
805
+ })();
806
+
807
+ (function initErrorBoundary() {
808
+ let toastEl = null;
809
+ let hideTimer = null;
810
+ function showErrorToast(title, detail) {
811
+ if (toastEl) toastEl.remove();
812
+ toastEl = document.createElement('div');
813
+ toastEl.className = 'error-toast';
814
+ toastEl.innerHTML = `<div class="error-toast-title">${title}</div><div class="error-toast-detail">${detail}</div>`;
815
+ toastEl.addEventListener('click', () => { toastEl.remove(); toastEl = null; });
816
+ document.body.appendChild(toastEl);
817
+ clearTimeout(hideTimer);
818
+ hideTimer = setTimeout(() => { if (toastEl) { toastEl.remove(); toastEl = null; } }, 8000);
819
+ }
820
+ window.addEventListener('error', (e) => {
821
+ if (e.filename) showErrorToast('JavaScript Error', `${e.message} at ${e.filename.split('/').pop()}:${e.lineno}`);
822
+ });
823
+ window.addEventListener('unhandledrejection', (e) => {
824
+ const msg = e.reason?.message || String(e.reason || 'Unknown');
825
+ showErrorToast('Unhandled Promise Rejection', msg);
826
+ });
827
+ window.showErrorToast = showErrorToast;
828
+ })();
829
+
752
830
  window.addEventListener('load', initializeApp);
@@ -3054,4 +3054,108 @@
3054
3054
  html.dark .html-rendered-container {
3055
3055
  border-color: #262626;
3056
3056
  }
3057
+
3058
+ .sidebar-search-bar {
3059
+ padding: 0.25rem 0.75rem 0.5rem;
3060
+ }
3061
+ .sidebar-search-input {
3062
+ width: 100%;
3063
+ padding: 0.375rem 0.5rem;
3064
+ border: 1px solid #d1d5db;
3065
+ border-radius: 0.375rem;
3066
+ background: #f9fafb;
3067
+ color: #111827;
3068
+ font-size: 0.8125rem;
3069
+ outline: none;
3070
+ box-sizing: border-box;
3071
+ }
3072
+ .sidebar-search-input:focus {
3073
+ border-color: #3b82f6;
3074
+ box-shadow: 0 0 0 2px rgba(59,130,246,0.15);
3075
+ }
3076
+ html.dark .sidebar-search-input {
3077
+ background: #1f2937;
3078
+ border-color: #374151;
3079
+ color: #e5e7eb;
3080
+ }
3081
+
3082
+ .shortcuts-overlay {
3083
+ position: fixed;
3084
+ inset: 0;
3085
+ background: rgba(0,0,0,0.5);
3086
+ display: flex;
3087
+ align-items: center;
3088
+ justify-content: center;
3089
+ z-index: 9999;
3090
+ }
3091
+ .shortcuts-panel {
3092
+ background: white;
3093
+ border-radius: 0.75rem;
3094
+ padding: 1.5rem;
3095
+ max-width: 400px;
3096
+ width: 90%;
3097
+ box-shadow: 0 25px 50px rgba(0,0,0,0.25);
3098
+ }
3099
+ html.dark .shortcuts-panel {
3100
+ background: #1f2937;
3101
+ color: #e5e7eb;
3102
+ }
3103
+ .shortcuts-panel h3 {
3104
+ margin: 0 0 1rem;
3105
+ font-size: 1.125rem;
3106
+ }
3107
+ .shortcuts-panel table {
3108
+ width: 100%;
3109
+ border-collapse: collapse;
3110
+ }
3111
+ .shortcuts-panel td {
3112
+ padding: 0.375rem 0;
3113
+ font-size: 0.875rem;
3114
+ }
3115
+ .shortcuts-panel td:first-child {
3116
+ font-weight: 600;
3117
+ white-space: nowrap;
3118
+ padding-right: 1rem;
3119
+ }
3120
+ .shortcuts-panel kbd {
3121
+ background: #f3f4f6;
3122
+ border: 1px solid #d1d5db;
3123
+ border-radius: 0.25rem;
3124
+ padding: 0.125rem 0.375rem;
3125
+ font-size: 0.75rem;
3126
+ font-family: inherit;
3127
+ }
3128
+ html.dark .shortcuts-panel kbd {
3129
+ background: #374151;
3130
+ border-color: #4b5563;
3131
+ }
3132
+
3133
+ .error-toast {
3134
+ position: fixed;
3135
+ bottom: 1rem;
3136
+ right: 1rem;
3137
+ background: #dc2626;
3138
+ color: white;
3139
+ padding: 0.75rem 1rem;
3140
+ border-radius: 0.5rem;
3141
+ font-size: 0.875rem;
3142
+ max-width: 400px;
3143
+ z-index: 9998;
3144
+ box-shadow: 0 10px 25px rgba(0,0,0,0.2);
3145
+ cursor: pointer;
3146
+ animation: slideInRight 0.2s ease-out;
3147
+ }
3148
+ .error-toast-title {
3149
+ font-weight: 600;
3150
+ margin-bottom: 0.25rem;
3151
+ }
3152
+ .error-toast-detail {
3153
+ opacity: 0.85;
3154
+ font-size: 0.8125rem;
3155
+ word-break: break-word;
3156
+ }
3157
+ @keyframes slideInRight {
3158
+ from { transform: translateX(100%); opacity: 0; }
3159
+ to { transform: translateX(0); opacity: 1; }
3160
+ }
3057
3161
 
package/static/index.html CHANGED
@@ -21,7 +21,7 @@
21
21
  })();
22
22
  </script>
23
23
 
24
- <link rel="stylesheet" href="/gm/css/main.css">
24
+ <link rel="stylesheet" href="/gm/css/main.css">
25
25
  <link rel="stylesheet" href="/gm/css/tools-popup.css">
26
26
  </head>
27
27
  <body>
@@ -39,6 +39,9 @@
39
39
  <button id="newConversationBtn" class="sidebar-new-btn" data-new-conversation title="Start new conversation">+ New</button>
40
40
  </div>
41
41
  </div>
42
+ <div class="sidebar-search-bar" id="sidebarSearchBar">
43
+ <input type="text" class="sidebar-search-input" id="sidebarSearchInput" placeholder="Search conversations..." autocomplete="off" spellcheck="false">
44
+ </div>
42
45
  <div class="clone-input-bar" id="cloneInputBar" style="display:none;">
43
46
  <input type="text" class="clone-input" id="cloneRepoInput" placeholder="org/repo" autocomplete="off" spellcheck="false">
44
47
  <button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>