agentgui 1.0.815 → 1.0.816

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.
@@ -1,7 +1,3 @@
1
- /**
2
- * Syntax Highlighter Integration
3
- * Handles lazy-loading and caching of Prism.js for code highlighting
4
- */
5
1
 
6
2
  class SyntaxHighlighter {
7
3
  constructor(config = {}) {
@@ -24,21 +20,15 @@ class SyntaxHighlighter {
24
20
  this.loadPromise = null;
25
21
  }
26
22
 
27
- /**
28
- * Ensure Prism is loaded
29
- */
30
23
  async ensureLoaded() {
31
- // Already loaded
32
24
  if (typeof Prism !== 'undefined' && this.isLoaded) {
33
25
  return true;
34
26
  }
35
27
 
36
- // Currently loading
37
28
  if (this.isLoading && this.loadPromise) {
38
29
  return this.loadPromise;
39
30
  }
40
31
 
41
- // Start loading
42
32
  this.isLoading = true;
43
33
  this.loadPromise = this.loadPrism();
44
34
 
@@ -54,19 +44,14 @@ class SyntaxHighlighter {
54
44
  }
55
45
  }
56
46
 
57
- /**
58
- * Load Prism library
59
- */
60
47
  async loadPrism() {
61
48
  return new Promise((resolve, reject) => {
62
49
  try {
63
- // Load main Prism JS
64
50
  const script = document.createElement('script');
65
51
  script.src = `${this.config.cdnUrl}/prism.js`;
66
52
  script.async = true;
67
53
 
68
54
  script.onload = () => {
69
- // Load common language files
70
55
  this.loadLanguages();
71
56
  this.isLoading = false;
72
57
  resolve(true);
@@ -85,9 +70,6 @@ class SyntaxHighlighter {
85
70
  });
86
71
  }
87
72
 
88
- /**
89
- * Load language files
90
- */
91
73
  loadLanguages() {
92
74
  const languages = ['javascript', 'python', 'sql', 'bash', 'json'];
93
75
 
@@ -99,13 +81,9 @@ class SyntaxHighlighter {
99
81
  }
100
82
  }
101
83
 
102
- /**
103
- * Highlight code
104
- */
105
84
  async highlight(code, language = 'plaintext') {
106
85
  if (!code) return '';
107
86
 
108
- // Ensure Prism is loaded
109
87
  if (this.config.lazyLoad) {
110
88
  try {
111
89
  await this.ensureLoaded();
@@ -115,19 +93,16 @@ class SyntaxHighlighter {
115
93
  }
116
94
  }
117
95
 
118
- // Check cache
119
96
  const cacheKey = `${language}:${code}`;
120
97
  if (this.config.enableCache && this.highlightCache.has(cacheKey)) {
121
98
  return this.highlightCache.get(cacheKey);
122
99
  }
123
100
 
124
- // Highlight code
125
101
  let highlighted;
126
102
  try {
127
103
  if (typeof Prism !== 'undefined' && Prism.languages[language]) {
128
104
  highlighted = Prism.highlight(code, Prism.languages[language], language);
129
105
  } else {
130
- // Fallback to escaped HTML if language not supported
131
106
  highlighted = this.escapeHtml(code);
132
107
  }
133
108
  } catch (error) {
@@ -135,11 +110,9 @@ class SyntaxHighlighter {
135
110
  highlighted = this.escapeHtml(code);
136
111
  }
137
112
 
138
- // Cache result
139
113
  if (this.config.enableCache) {
140
114
  this.highlightCache.set(cacheKey, highlighted);
141
115
 
142
- // Trim cache if too large
143
116
  if (this.highlightCache.size > this.config.maxCacheSize) {
144
117
  const firstKey = this.highlightCache.keys().next().value;
145
118
  this.highlightCache.delete(firstKey);
@@ -149,14 +122,10 @@ class SyntaxHighlighter {
149
122
  return highlighted;
150
123
  }
151
124
 
152
- /**
153
- * Create highlighted code element
154
- */
155
125
  async createHighlightedElement(code, language = 'plaintext') {
156
126
  const pre = document.createElement('pre');
157
127
  const code_el = document.createElement('code');
158
128
 
159
- // Set language class
160
129
  code_el.className = `language-${language}`;
161
130
 
162
131
  if (this.config.lazyLoad) {
@@ -175,9 +144,6 @@ class SyntaxHighlighter {
175
144
  return pre;
176
145
  }
177
146
 
178
- /**
179
- * Highlight DOM element
180
- */
181
147
  async highlightElement(element) {
182
148
  if (!element || !element.querySelector('code')) return;
183
149
 
@@ -199,13 +165,9 @@ class SyntaxHighlighter {
199
165
  }
200
166
  }
201
167
 
202
- /**
203
- * Detect language from code content
204
- */
205
168
  detectLanguage(code) {
206
169
  if (!code) return 'plaintext';
207
170
 
208
- // Shebang detection
209
171
  if (code.startsWith('#!/')) {
210
172
  if (code.includes('python')) return 'python';
211
173
  if (code.includes('node') || code.includes('node.js')) return 'javascript';
@@ -213,7 +175,6 @@ class SyntaxHighlighter {
213
175
  if (code.includes('ruby')) return 'ruby';
214
176
  }
215
177
 
216
- // Pattern detection
217
178
  if (code.includes('def ') && code.includes(':')) return 'python';
218
179
  if (code.includes('function') || code.includes('=>')) return 'javascript';
219
180
  if (code.includes('fn ') && code.includes('->')) return 'rust';
@@ -225,30 +186,18 @@ class SyntaxHighlighter {
225
186
  return 'plaintext';
226
187
  }
227
188
 
228
- /**
229
- * Get supported languages
230
- */
231
189
  getSupportedLanguages() {
232
190
  return [...this.config.supportedLanguages];
233
191
  }
234
192
 
235
- /**
236
- * Check if language is supported
237
- */
238
193
  isSupportedLanguage(language) {
239
194
  return this.config.supportedLanguages.includes(language);
240
195
  }
241
196
 
242
- /**
243
- * Clear cache
244
- */
245
197
  clearCache() {
246
198
  this.highlightCache.clear();
247
199
  }
248
200
 
249
- /**
250
- * Get cache stats
251
- */
252
201
  getCacheStats() {
253
202
  return {
254
203
  size: this.highlightCache.size,
@@ -256,15 +205,11 @@ class SyntaxHighlighter {
256
205
  };
257
206
  }
258
207
 
259
- /**
260
- * HTML escape utility
261
- */
262
208
  escapeHtml(text) {
263
209
  return window._escHtml(text);
264
210
  }
265
211
  }
266
212
 
267
- // Export for use in browser
268
213
  if (typeof module !== 'undefined' && module.exports) {
269
214
  module.exports = SyntaxHighlighter;
270
215
  }
@@ -1,12 +1,5 @@
1
- /**
2
- * UI Components
3
- * Reusable UI building blocks for modals, tabs, buttons, and more
4
- */
5
1
 
6
2
  class UIComponents {
7
- /**
8
- * Create a modal dialog
9
- */
10
3
  static createModal(config = {}) {
11
4
  const {
12
5
  title = 'Dialog',
@@ -45,14 +38,12 @@ class UIComponents {
45
38
  </div>
46
39
  `;
47
40
 
48
- // Add close handler
49
41
  const closeBtn = modal.querySelector('.modal-close');
50
42
  closeBtn.addEventListener('click', () => {
51
43
  modal.remove();
52
44
  if (onClose) onClose();
53
45
  });
54
46
 
55
- // Add button handlers
56
47
  modal.querySelectorAll('[data-action]').forEach(btn => {
57
48
  btn.addEventListener('click', (e) => {
58
49
  const action = e.target.dataset.action;
@@ -63,7 +54,6 @@ class UIComponents {
63
54
  });
64
55
  });
65
56
 
66
- // Close on background click
67
57
  modal.addEventListener('click', (e) => {
68
58
  if (e.target === modal) {
69
59
  modal.remove();
@@ -74,9 +64,6 @@ class UIComponents {
74
64
  return modal;
75
65
  }
76
66
 
77
- /**
78
- * Create a tabbed interface
79
- */
80
67
  static createTabs(config = {}) {
81
68
  const {
82
69
  tabs = [],
@@ -87,7 +74,6 @@ class UIComponents {
87
74
  const container = document.createElement('div');
88
75
  container.className = 'tabs';
89
76
 
90
- // Tab buttons
91
77
  const tabButtons = document.createElement('div');
92
78
  tabButtons.className = 'tab-buttons flex border-b';
93
79
 
@@ -98,7 +84,6 @@ class UIComponents {
98
84
  btn.dataset.tabIndex = index;
99
85
 
100
86
  btn.addEventListener('click', () => {
101
- // Update active button
102
87
  tabButtons.querySelectorAll('.tab-button').forEach((b, i) => {
103
88
  if (i === index) {
104
89
  b.classList.add('tab-active');
@@ -107,7 +92,6 @@ class UIComponents {
107
92
  }
108
93
  });
109
94
 
110
- // Update tab content
111
95
  tabContent.querySelectorAll('.tab-pane').forEach((pane, i) => {
112
96
  pane.style.display = i === index ? 'block' : 'none';
113
97
  });
@@ -120,7 +104,6 @@ class UIComponents {
120
104
 
121
105
  container.appendChild(tabButtons);
122
106
 
123
- // Tab content
124
107
  const tabContent = document.createElement('div');
125
108
  tabContent.className = 'tab-content mt-4';
126
109
 
@@ -136,9 +119,6 @@ class UIComponents {
136
119
  return container;
137
120
  }
138
121
 
139
- /**
140
- * Create an alert/notification
141
- */
142
122
  static createAlert(config = {}) {
143
123
  const {
144
124
  message = '',
@@ -175,9 +155,6 @@ class UIComponents {
175
155
  return alert;
176
156
  }
177
157
 
178
- /**
179
- * Create a loading spinner
180
- */
181
158
  static createSpinner(config = {}) {
182
159
  const {
183
160
  size = 'medium', // small, medium, large
@@ -199,9 +176,6 @@ class UIComponents {
199
176
  return container;
200
177
  }
201
178
 
202
- /**
203
- * Create a progress bar
204
- */
205
179
  static createProgressBar(config = {}) {
206
180
  const {
207
181
  percentage = 0,
@@ -225,9 +199,6 @@ class UIComponents {
225
199
  return container;
226
200
  }
227
201
 
228
- /**
229
- * Create a collapsible section
230
- */
231
202
  static createCollapsible(config = {}) {
232
203
  const {
233
204
  title = 'Details',
@@ -252,9 +223,6 @@ class UIComponents {
252
223
  return container;
253
224
  }
254
225
 
255
- /**
256
- * Create a form input
257
- */
258
226
  static createInput(config = {}) {
259
227
  const {
260
228
  type = 'text',
@@ -288,9 +256,6 @@ class UIComponents {
288
256
  return container;
289
257
  }
290
258
 
291
- /**
292
- * Create a select dropdown
293
- */
294
259
  static createSelect(config = {}) {
295
260
  const {
296
261
  name = '',
@@ -326,9 +291,6 @@ class UIComponents {
326
291
  return container;
327
292
  }
328
293
 
329
- /**
330
- * Create a button group
331
- */
332
294
  static createButtonGroup(config = {}) {
333
295
  const {
334
296
  buttons = [],
@@ -351,9 +313,6 @@ class UIComponents {
351
313
  return container;
352
314
  }
353
315
 
354
- /**
355
- * Create a badge/tag
356
- */
357
316
  static createBadge(config = {}) {
358
317
  const {
359
318
  label = '',
@@ -381,16 +340,10 @@ class UIComponents {
381
340
  return badge;
382
341
  }
383
342
 
384
- /**
385
- * HTML escape utility
386
- */
387
343
  static escapeHtml(text) {
388
344
  return window._escHtml(text);
389
345
  }
390
346
 
391
- /**
392
- * Copy text to clipboard
393
- */
394
347
  static copyToClipboard(text) {
395
348
  return navigator.clipboard.writeText(text).catch(err => {
396
349
  console.error('Failed to copy:', err);
@@ -398,9 +351,6 @@ class UIComponents {
398
351
  });
399
352
  }
400
353
 
401
- /**
402
- * Download data as file
403
- */
404
354
  static downloadFile(data, filename, mimeType = 'text/plain') {
405
355
  const blob = new Blob([data], { type: mimeType });
406
356
  const url = URL.createObjectURL(blob);
@@ -414,7 +364,6 @@ class UIComponents {
414
364
  }
415
365
  }
416
366
 
417
- // Export for use in browser
418
367
  if (typeof module !== 'undefined' && module.exports) {
419
368
  module.exports = UIComponents;
420
369
  }
@@ -1,5 +1,3 @@
1
- // codec is loaded as ES module and exposed globally by ws-client.js
2
- // or inline: import('./codec.js').then(m => window._codec = m)
3
1
 
4
2
  class WebSocketManager {
5
3
  constructor(config = {}) {
@@ -94,7 +92,6 @@ class WebSocketManager {
94
92
  }
95
93
  set connectionState(v) { this._connectionState = v; }
96
94
 
97
- // Machine context is authoritative for these flags
98
95
  get isManuallyDisconnected() {
99
96
  if (this._wsActor) return !!this._wsActor.getSnapshot().context.manualDisconnect;
100
97
  return this._isManuallyDisconnected;
@@ -201,7 +198,6 @@ class WebSocketManager {
201
198
  );
202
199
  }
203
200
 
204
- // RPC reply envelopes — emit for WsClient to intercept, then skip broadcast
205
201
  if (data.r !== undefined && !data.type) {
206
202
  this.emit('message', data);
207
203
  continue;
@@ -233,7 +229,6 @@ class WebSocketManager {
233
229
 
234
230
  this.latency.current = rtt;
235
231
 
236
- // EMA smoothing (α=0.2 → slow adaptation, less noise)
237
232
  const alpha = 0.2;
238
233
  this._latencyEma = this._latencyEma === null ? rtt : alpha * rtt + (1 - alpha) * this._latencyEma;
239
234
  this.latency.avg = this._latencyEma;
@@ -535,8 +530,6 @@ class WebSocketManager {
535
530
  this.stats.totalMessagesSent++;
536
531
  } catch (_) {}
537
532
  }
538
- // Server automatically sends streaming_start{resumed:true} on subscribe
539
- // when an active execution exists — no need to query conv.get here.
540
533
  }
541
534
 
542
535
  unsubscribeFromSession(sessionId) {
@@ -10,7 +10,6 @@ class WsClient {
10
10
  _install() {
11
11
  if (this._installed) return;
12
12
  this._installed = true;
13
- // Listen on decoded message objects — websocket-manager emits 'message' with decoded obj
14
13
  this._ws.on('message', (data) => {
15
14
  if (data.r && this._pending.has(data.r)) {
16
15
  const p = this._pending.get(data.r);
@@ -23,7 +22,6 @@ class WsClient {
23
22
  }
24
23
  return; // consumed — don't re-emit
25
24
  }
26
- // Non-RPC messages are already emitted by websocket-manager; nothing to do
27
25
  });
28
26
  this._ws.on('disconnected', () => this.cancelAll());
29
27
  }
@@ -78,8 +76,6 @@ class WsClient {
78
76
 
79
77
  window.WsClient = WsClient;
80
78
 
81
- // Bootstrap: create wsManager and wsClient synchronously so other modules can use them immediately.
82
- // Codec is loaded async and upgrades encoding once ready; websocket-manager falls back to msgpackr until then.
83
79
  window.wsManager = new WebSocketManager();
84
80
  window.wsClient = new WsClient(window.wsManager);
85
81
  window.wsManager.connect().catch(function() {});
@@ -1,5 +1,3 @@
1
- // WebSocket connection state machine using XState v5
2
- // Consumed by WebSocketManager to provide formal state tracking
3
1
 
4
2
  const { createMachine, createActor, assign } = XState;
5
3
 
package/static/theme.js CHANGED
@@ -1,4 +1,3 @@
1
- // Theme management for dark/light mode
2
1
  class ThemeManager {
3
2
  constructor() {
4
3
  this.THEME_KEY = 'gmgui-theme';
@@ -7,27 +6,22 @@ class ThemeManager {
7
6
  }
8
7
 
9
8
  init() {
10
- // Load saved theme or use system preference
11
9
  const savedTheme = localStorage.getItem(this.THEME_KEY);
12
10
  const prefersDark = this.SYSTEM_DARK_MODE.matches;
13
11
 
14
12
  if (savedTheme) {
15
13
  this.setTheme(savedTheme);
16
14
  } else {
17
- // Use system preference
18
15
  this.setTheme(prefersDark ? 'dark' : 'light');
19
16
  }
20
17
 
21
- // Listen for system theme changes
22
18
  this.SYSTEM_DARK_MODE.addEventListener('change', (e) => {
23
19
  const savedTheme = localStorage.getItem(this.THEME_KEY);
24
- // Only auto-switch if user hasn't manually set a preference
25
20
  if (!savedTheme) {
26
21
  this.setTheme(e.matches ? 'dark' : 'light');
27
22
  }
28
23
  });
29
24
 
30
- // Setup theme toggle button
31
25
  const themeToggle = document.getElementById('themeToggle');
32
26
  if (themeToggle) {
33
27
  themeToggle.addEventListener('click', () => this.toggleTheme());
@@ -45,7 +39,6 @@ class ThemeManager {
45
39
  localStorage.setItem(this.THEME_KEY, theme);
46
40
  this.updateThemeIcon(theme);
47
41
 
48
- // Notify embedded iframes (storage events don't fire in same window)
49
42
  const msg = { type: 'theme-change', theme };
50
43
  document.querySelectorAll('iframe').forEach(iframe => {
51
44
  try { iframe.contentWindow.postMessage(msg, '*'); } catch (_) {}
@@ -73,7 +66,6 @@ class ThemeManager {
73
66
  }
74
67
  }
75
68
 
76
- // Initialize theme manager when DOM is ready
77
69
  if (document.readyState === 'loading') {
78
70
  document.addEventListener('DOMContentLoaded', () => {
79
71
  window.themeManager = new ThemeManager();