agentgui 1.0.931 → 1.0.933

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.
Files changed (129) hide show
  1. package/AGENTS.md +17 -12
  2. package/database.js +31 -2
  3. package/lib/http-handler.js +11 -25
  4. package/lib/routes-registry.js +4 -48
  5. package/lib/server-startup.js +3 -11
  6. package/lib/ws-setup.js +2 -1
  7. package/package.json +3 -3
  8. package/server.js +7 -1
  9. package/site/app/index.html +2 -2
  10. package/site/app/js/app.js +91 -86
  11. package/site/app/js/backend.js +1 -1
  12. package/static/lib/xstate.umd.min.js +1 -1
  13. package/lib/db-queries-chunks.js +0 -195
  14. package/lib/db-queries-chunks2.js +0 -82
  15. package/lib/db-queries-cleanup.js +0 -74
  16. package/lib/db-queries-del.js +0 -141
  17. package/lib/db-queries-events.js +0 -68
  18. package/lib/db-queries-import.js +0 -133
  19. package/lib/db-queries-messages.js +0 -102
  20. package/lib/db-queries-sessions.js +0 -112
  21. package/lib/db-queries-streams.js +0 -100
  22. package/lib/db-queries.js +0 -89
  23. package/lib/jsonl-parser.js +0 -190
  24. package/lib/jsonl-watcher.js +0 -64
  25. package/lib/routes-agent-actions.js +0 -61
  26. package/lib/routes-auth-config.js +0 -30
  27. package/lib/routes-conversations.js +0 -96
  28. package/lib/routes-debug.js +0 -119
  29. package/lib/routes-messages.js +0 -139
  30. package/lib/routes-runs.js +0 -156
  31. package/lib/routes-scripts.js +0 -135
  32. package/lib/routes-sessions.js +0 -144
  33. package/lib/routes-threads.js +0 -100
  34. package/lib/routes-util.js +0 -110
  35. package/lib/ws-handlers-conv.js +0 -138
  36. package/lib/ws-handlers-conv2.js +0 -169
  37. package/lib/ws-handlers-msg.js +0 -121
  38. package/lib/ws-handlers-queue.js +0 -56
  39. package/lib/ws-handlers-run.js +0 -182
  40. package/lib/ws-handlers-scripts.js +0 -66
  41. package/lib/ws-handlers-session.js +0 -105
  42. package/lib/ws-handlers-session2.js +0 -85
  43. package/lib/ws-legacy-handlers.js +0 -51
  44. package/static/app.js +0 -261
  45. package/static/css/app-shell.css +0 -419
  46. package/static/css/brand-bible.css +0 -591
  47. package/static/css/colors_and_type.css +0 -568
  48. package/static/css/gmail-skin.css +0 -663
  49. package/static/css/main.css +0 -4015
  50. package/static/css/tools-popup.css +0 -472
  51. package/static/index.html +0 -418
  52. package/static/js/agent-auth.js +0 -146
  53. package/static/js/app-shortcuts.js +0 -30
  54. package/static/js/audio-recorder-processor.js +0 -18
  55. package/static/js/client-agents.js +0 -155
  56. package/static/js/client-cache.js +0 -171
  57. package/static/js/client-conv.js +0 -198
  58. package/static/js/client-events.js +0 -164
  59. package/static/js/client-exec.js +0 -160
  60. package/static/js/client-helpers.js +0 -199
  61. package/static/js/client-load.js +0 -175
  62. package/static/js/client-render.js +0 -132
  63. package/static/js/client-scroll.js +0 -178
  64. package/static/js/client-status.js +0 -167
  65. package/static/js/client-streaming.js +0 -117
  66. package/static/js/client-streaming2.js +0 -116
  67. package/static/js/client-streaming3.js +0 -153
  68. package/static/js/client-streaming4.js +0 -194
  69. package/static/js/client-ui-controls.js +0 -170
  70. package/static/js/client-ui.js +0 -128
  71. package/static/js/client-ui2.js +0 -160
  72. package/static/js/client-url.js +0 -93
  73. package/static/js/client-utils.js +0 -174
  74. package/static/js/client-ws-msg.js +0 -88
  75. package/static/js/client-ws.js +0 -161
  76. package/static/js/client.js +0 -145
  77. package/static/js/codec.js +0 -4
  78. package/static/js/conv-list-machine.js +0 -145
  79. package/static/js/conv-list-renderer.js +0 -198
  80. package/static/js/conv-machine.js +0 -110
  81. package/static/js/conv-sidebar-actions.js +0 -188
  82. package/static/js/conv-sidebar-clone.js +0 -91
  83. package/static/js/conversations.js +0 -116
  84. package/static/js/dialogs-types.js +0 -111
  85. package/static/js/dialogs.js +0 -53
  86. package/static/js/event-filter-config.js +0 -36
  87. package/static/js/event-processor.js +0 -181
  88. package/static/js/features.js +0 -187
  89. package/static/js/image-loader-element.js +0 -76
  90. package/static/js/image-loader.js +0 -146
  91. package/static/js/prompt-machine.js +0 -108
  92. package/static/js/recording-machine.js +0 -49
  93. package/static/js/script-runner.js +0 -192
  94. package/static/js/state-barrier.js +0 -105
  95. package/static/js/streaming-renderer-dispatch.js +0 -144
  96. package/static/js/streaming-renderer-events.js +0 -163
  97. package/static/js/streaming-renderer-events2.js +0 -125
  98. package/static/js/streaming-renderer-params.js +0 -38
  99. package/static/js/streaming-renderer-render-misc.js +0 -107
  100. package/static/js/streaming-renderer-render.js +0 -181
  101. package/static/js/streaming-renderer-render2.js +0 -149
  102. package/static/js/streaming-renderer-render3.js +0 -142
  103. package/static/js/streaming-renderer-static.js +0 -181
  104. package/static/js/streaming-renderer-static2.js +0 -140
  105. package/static/js/streaming-renderer-stream.js +0 -170
  106. package/static/js/streaming-renderer-text.js +0 -185
  107. package/static/js/streaming-renderer-tools.js +0 -189
  108. package/static/js/streaming-renderer-tools2.js +0 -92
  109. package/static/js/streaming-renderer.js +0 -200
  110. package/static/js/syntax-highlighter-render.js +0 -72
  111. package/static/js/syntax-highlighter.js +0 -131
  112. package/static/js/terminal-machine.js +0 -51
  113. package/static/js/terminal.js +0 -178
  114. package/static/js/ui-components-rendering.js +0 -62
  115. package/static/js/ui-components.js +0 -88
  116. package/static/js/websocket-manager.js +0 -107
  117. package/static/js/ws-client.js +0 -87
  118. package/static/js/ws-core.js +0 -162
  119. package/static/js/ws-latency.js +0 -88
  120. package/static/js/ws-machine.js +0 -68
  121. package/static/lib/msgpackr.min.js +0 -2
  122. package/static/theme.js +0 -74
  123. package/static/vendor/highlight-js.css +0 -10
  124. package/static/vendor/highlight.min.js +0 -1244
  125. package/static/vendor/prism-dark.css +0 -129
  126. package/static/vendor/rippleui.css +0 -35
  127. package/static/vendor/xterm-addon-fit.min.js +0 -8
  128. package/static/vendor/xterm.css +0 -8
  129. package/static/vendor/xterm.min.js +0 -8
package/static/index.html DELETED
@@ -1,418 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en" data-theme="dark">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
6
- <meta name="description" content="247420 branded AgentGUI - real-time multi-agent coding interface">
7
- <meta name="theme-color" content="#247420" media="(prefers-color-scheme: light)">
8
- <meta name="theme-color" content="#1f1f1a" media="(prefers-color-scheme: dark)">
9
- <title>247420 // AgentGUI</title>
10
- <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect width='100' height='100' fill='%23247420'/%3E%3Ctext x='50' y='68' font-size='50' font-family='sans-serif' font-weight='bold' fill='%23EFE9DD' text-anchor='middle'%3EG%3C/text%3E%3C/svg%3E">
11
- <link rel="preconnect" href="https://fonts.googleapis.com">
12
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
13
- <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Archivo+Black&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif&display=swap">
14
- <link rel="preload" href="/gm/css/main.css" as="style">
15
- <link rel="preload" href="/gm/lib/xstate.umd.min.js" as="script">
16
- <link rel="preload" href="/gm/lib/msgpackr.min.js" as="script">
17
-
18
-
19
-
20
- <script>
21
- (function(){
22
- var b=(window.__BASE_URL||'');
23
- // Critical CSS only - rippleui needed for layout
24
- ['vendor/rippleui.css'].forEach(function(h){
25
- var l=document.createElement('link');l.rel='stylesheet';l.href=b+'/'+h;document.head.appendChild(l);
26
- });
27
- // Non-critical CSS - load async via media trick
28
- ['vendor/prism-dark.css','vendor/highlight-js.css','vendor/xterm.css'].forEach(function(h){
29
- var l=document.createElement('link');l.rel='stylesheet';l.href=b+'/'+h;l.media='print';l.onload=function(){l.media='all';};document.head.appendChild(l);
30
- });
31
- // Vendor JS - lazy load on idle or first use
32
- window._vendorLoaded = false;
33
- window._loadVendorJS = function() {
34
- if (window._vendorLoaded) return;
35
- window._vendorLoaded = true;
36
- ['vendor/highlight.min.js','vendor/xterm.min.js','vendor/xterm-addon-fit.min.js'].forEach(function(s){
37
- var e=document.createElement('script');e.defer=true;e.src=b+'/'+s;document.head.appendChild(e);
38
- });
39
- };
40
- if (typeof requestIdleCallback !== 'undefined') requestIdleCallback(window._loadVendorJS, { timeout: 3000 });
41
- else setTimeout(window._loadVendorJS, 1500);
42
- })();
43
- </script>
44
-
45
- <link rel="stylesheet" href="/gm/css/main.css">
46
- <link rel="stylesheet" href="/gm/css/tools-popup.css" media="print" onload="this.media='all'">
47
- <link rel="stylesheet" href="/gm/css/brand-bible.css">
48
- <link rel="stylesheet" href="/gm/css/gmail-skin.css">
49
- </head>
50
- <body>
51
- <a href="#app" class="skip-link">Skip to conversation</a>
52
-
53
- <!-- Sidebar overlay (mobile) -->
54
- <div class="sidebar-overlay" data-sidebar-overlay></div>
55
-
56
- <div class="app-shell">
57
- <!-- ===== GMAIL NAV RAIL ===== -->
58
- <nav class="nav-rail" aria-label="Navigation">
59
- <button class="nav-rail-item nav-rail-compose" id="newConversationBtnRail" data-new-conversation title="Compose (Ctrl+N)" aria-label="New conversation">
60
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
61
- <span class="nav-rail-label">Compose</span>
62
- </button>
63
- <button class="nav-rail-item nav-rail-inbox active" data-nav-rail="inbox" title="Inbox" aria-label="Inbox">
64
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 16 12 14 15 10 15 8 12 2 12"/><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"/></svg>
65
- <span class="nav-rail-label">Chats</span>
66
- </button>
67
- <button class="nav-rail-item" id="viewArchivedBtnRail" data-nav-rail="archived" title="Archived" aria-label="Archived conversations">
68
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>
69
- <span class="nav-rail-label">Archived</span>
70
- </button>
71
- <button class="nav-rail-item" id="toolsManagerBtnRail" data-nav-rail="tools" title="Tools" aria-label="Tools">
72
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
73
- <span class="nav-rail-label">Tools</span>
74
- </button>
75
- </nav>
76
-
77
- <!-- ===== SIDEBAR ===== -->
78
- <aside class="sidebar" data-sidebar role="navigation" aria-label="Conversation history">
79
- <div class="sidebar-header">
80
- <h2 class="brand-line">247420<span class="slash"> / </span>agentgui</h2>
81
- <div class="sidebar-header-actions">
82
- <div class="sidebar-overflow-menu-wrapper">
83
- <button class="sidebar-overflow-btn" id="sidebarOverflowBtn" title="More options" aria-label="More options">···</button>
84
- <div class="sidebar-overflow-menu" id="sidebarOverflowMenu">
85
- <button class="sidebar-overflow-menu-item" id="importConversationBtn" title="Import conversation from JSON">
86
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" y1="3" x2="12" y2="15"/></svg>
87
- Import Conversation
88
- </button>
89
- <button class="sidebar-overflow-menu-item" id="viewArchivedBtn" title="View archived conversations">
90
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 8v13H3V8"/><path d="M1 3h22v5H1z"/><path d="M10 12h4"/></svg>
91
- Archived
92
- </button>
93
- <button class="sidebar-overflow-menu-item" id="cloneRepoBtn" data-clone-repo title="Clone a GitHub repo">
94
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="18" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><path d="M6 21V9a9 9 0 0 0 9 9"/></svg>
95
- Clone Repo
96
- </button>
97
- <button class="sidebar-overflow-menu-item danger" id="deleteAllConversationsBtn" data-delete-all-conversations title="Delete all conversations">
98
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
99
- Clear All
100
- </button>
101
- </div>
102
- </div>
103
- <button id="newConversationBtn" class="sidebar-new-btn btn-stamp green" data-new-conversation title="Start new conversation (Ctrl+N)">new</button>
104
- </div>
105
- </div>
106
- <div class="sidebar-search-bar" id="sidebarSearchBar">
107
- <input type="text" class="sidebar-search-input" id="sidebarSearchInput" placeholder="Search conversations..." autocomplete="off" spellcheck="false" aria-label="Search conversations">
108
- </div>
109
- <div class="clone-input-bar" id="cloneInputBar" style="display:none;">
110
- <input type="text" class="clone-input" id="cloneRepoInput" placeholder="org/repo" autocomplete="off" spellcheck="false">
111
- <button class="clone-go-btn" id="cloneGoBtn" title="Clone">Go</button>
112
- <button class="clone-cancel-btn" id="cloneCancelBtn" title="Cancel">&times;</button>
113
- </div>
114
- <div class="bulk-action-bar" id="bulkActionBar" style="display:none;padding:0.375rem 0.75rem;background:var(--color-primary);display:none;gap:0.5rem;align-items:center;">
115
- <span id="bulkCount" style="color:white;font-size:0.75rem;flex:1;">0 selected</span>
116
- <button id="bulkArchiveBtn" style="background:rgba(255,255,255,0.2);color:white;border:none;border-radius:0.25rem;padding:0.25rem 0.5rem;font-size:0.75rem;cursor:pointer;">Archive</button>
117
- <button id="bulkDeleteBtn" style="background:rgba(255,255,255,0.2);color:white;border:none;border-radius:0.25rem;padding:0.25rem 0.5rem;font-size:0.75rem;cursor:pointer;">Delete</button>
118
- </div>
119
- <ul class="sidebar-list" data-conversation-list role="listbox" aria-label="Conversations">
120
- <li class="sidebar-empty" data-conversation-empty>Loading...</li>
121
- </ul>
122
- <!-- PM2 Monitor Panel: hidden until active processes detected -->
123
- <div class="pm2-monitor-panel" id="pm2MonitorPanel" style="display:none">
124
- <div class="pm2-monitor-header">
125
- <span>PM2 Processes</span>
126
- <div class="pm2-monitor-actions">
127
- <button class="pm2-action-btn" id="pm2RefreshBtn" title="Refresh">↻</button>
128
- </div>
129
- </div>
130
- <div class="pm2-process-list" id="pm2ProcessList"></div>
131
- </div>
132
- </aside>
133
-
134
- <!-- ===== MAIN PANEL ===== -->
135
- <main id="app" class="main-panel" role="main" aria-label="Conversation">
136
- <!-- Header bar -->
137
- <div class="main-header">
138
- <button class="sidebar-toggle-btn" data-sidebar-toggle title="Toggle sidebar (Ctrl+B)" aria-label="Toggle sidebar">
139
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
140
- <line x1="3" y1="6" x2="21" y2="6"></line>
141
- <line x1="3" y1="12" x2="21" y2="12"></line>
142
- <line x1="3" y1="18" x2="21" y2="18"></line>
143
- </svg>
144
- </button>
145
-
146
- <div class="header-search-wrap">
147
- <svg class="header-search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
148
- <input class="header-search-input" id="headerSearchInput" type="text" placeholder="Search in chats" autocomplete="off" spellcheck="false" aria-label="Search conversations">
149
- </div>
150
- <h1 class="header-title brand-line">247420<span class="slash"> / </span>agentgui<span class="slash"> / </span><span class="leaf" id="headerLeaf">chat</span></h1>
151
-
152
- <div class="header-controls">
153
- <div class="script-buttons" id="scriptButtons" style="display:none;">
154
- <button class="header-icon-btn" id="scriptStartBtn" title="Run start script" aria-label="Run start script" style="display:none;">
155
- <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><polygon points="6,3 20,12 6,21"></polygon></svg>
156
- </button>
157
- <button class="header-icon-btn script-dev-btn" id="scriptDevBtn" title="Run dev script" aria-label="Run dev script" style="display:none;">
158
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>
159
- </button>
160
- <button class="header-icon-btn script-stop-btn" id="scriptStopBtn" title="Stop running script" aria-label="Stop running script" style="display:none;">
161
- <svg viewBox="0 0 24 24" fill="currentColor" stroke="none"><rect x="5" y="5" width="14" height="14" rx="1"></rect></svg>
162
- </button>
163
- </div>
164
- <div class="model-dl-indicator" id="modelDlIndicator" title="Downloading voice models...">
165
- <svg viewBox="0 0 24 24"><circle class="track" cx="12" cy="12" r="10"/><circle class="progress" cx="12" cy="12" r="10" stroke-dasharray="62.83" stroke-dashoffset="62.83"/></svg>
166
- <div class="icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/></svg></div>
167
- <div class="model-dl-indicator-tooltip" id="modelDlTooltip">Preparing voice models...</div>
168
- </div>
169
- <button class="header-icon-btn agent-auth-btn" id="agentAuthBtn" title="Agent authentication" aria-label="Agent authentication" style="display:none;">
170
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path></svg>
171
- <div class="agent-auth-dropdown" id="agentAuthDropdown"></div>
172
- </button>
173
- <button class="header-icon-btn tools-manager-btn" id="toolsManagerBtn" title="Tools & extensions" aria-label="Tools & extensions" style="display:none;">
174
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 6V2M12 22v-4M6 12H2M22 12h-4M7.07 7.07L4.22 4.22M19.78 19.78L16.93 16.93M7.07 16.93L4.22 19.78M19.78 4.22L16.93 7.07"/></svg>
175
- </button>
176
- <div class="tools-popup" id="toolsPopup">
177
- <div class="tools-popup-content" onclick="event.stopPropagation()">
178
- <div class="tools-popup-header">
179
- <div style="display: flex; align-items: center; gap: 0.75rem; flex: 1;">
180
- <h2 style="margin: 0; font-size: 1rem;">Tools & Extensions</h2>
181
- </div>
182
- <div class="tools-popup-header-controls" style="display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0;">
183
- <label class="tools-voice-toggle" style="display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; cursor: pointer; user-select: none;">
184
- <input type="checkbox" id="toolsAutoSpeakToggle" style="width: 1rem; height: 1rem; cursor: pointer;">
185
- <span>Auto-speak</span>
186
- </label>
187
- <select class="tools-voice-selector" id="toolsVoiceSelector" style="padding: 0.4rem 0.6rem; font-size: 0.8rem; border-radius: 0.3rem; border: 1px solid var(--color-border); background: var(--color-bg-primary); color: var(--color-text-primary); cursor: pointer;">
188
- <option value="default">Voice</option>
189
- </select>
190
- <button class="tools-popup-close" onclick="document.getElementById('toolsPopup').classList.remove('open')" style="background: none; border: none; color: var(--color-text-secondary); font-size: 1.5rem; cursor: pointer; padding: 0; line-height: 1; transition: color 0.2s;">×</button>
191
- </div>
192
- </div>
193
- <div class="tools-popup-scroll"></div>
194
- <div class="tools-popup-footer">
195
- <button class="tools-popup-refresh-btn" onclick="window.toolsManager.refresh()">Refresh All</button>
196
- <button class="tools-popup-update-btn" onclick="window.toolsManager.updateAll()" id="toolsUpdateAllBtn">Update All</button>
197
- </div>
198
- </div>
199
- </div>
200
- <div class="status-badge" title="Connection status">
201
- <div class="status-indicator" data-status="disconnected"></div>
202
- <span id="connectionStatus" data-status-indicator style="font-size:0.75rem;"></span>
203
- </div>
204
- <button class="theme-toggle-btn" data-theme-toggle title="Toggle dark mode" aria-label="Toggle dark mode">
205
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
206
- <circle cx="12" cy="12" r="5"></circle>
207
- <line x1="12" y1="1" x2="12" y2="3"></line>
208
- <line x1="12" y1="21" x2="12" y2="23"></line>
209
- <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
210
- <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
211
- <line x1="1" y1="12" x2="3" y2="12"></line>
212
- <line x1="21" y1="12" x2="23" y2="12"></line>
213
- <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
214
- <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
215
- </svg>
216
- </button>
217
- </div>
218
- </div>
219
-
220
- <!-- View toggle bar (hidden by default) -->
221
- <div class="view-toggle-bar" id="viewToggleBar">
222
- <button class="view-toggle-btn active" data-view="chat" title="Chat"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path></svg></button>
223
- <button class="view-toggle-btn" data-view="files" title="Files"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline></svg></button>
224
- <button class="view-toggle-btn" data-view="terminal" id="terminalTabBtn" title="Terminal"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line></svg></button>
225
- </div>
226
-
227
- <!-- Messages scroll area -->
228
- <div id="output-scroll" role="region" aria-label="Chat messages" aria-live="polite" data-drop-zone>
229
- <div class="messages-wrapper">
230
- <div id="output"></div>
231
- </div>
232
- <div class="drop-zone-overlay" id="dropZoneOverlay">
233
- <div class="drop-zone-content">
234
- <div class="drop-zone-icon">+</div>
235
- <div class="drop-zone-text">Drop files here to copy to working directory</div>
236
- </div>
237
- </div>
238
- </div>
239
-
240
- <!-- File browser (hidden by default) -->
241
- <div id="fileBrowserContainer" class="file-browser-container" style="display:none;">
242
- <iframe id="fileBrowserIframe" class="file-browser-iframe"></iframe>
243
- </div>
244
-
245
- <!-- Terminal output view -->
246
- <div id="terminalContainer" class="terminal-container" style="display:none;">
247
- <div id="terminalOutput" class="terminal-output"></div>
248
- </div>
249
-
250
-
251
- <!-- Streaming status bar -->
252
- <div class="streaming-status-bar" id="streamingStatusBar">
253
- <div class="typing-dots"><span></span><span></span><span></span></div>
254
- <span class="status-agent-name" id="streamingStatusAgent">Claude Code</span>
255
- <span style="color: var(--color-text-muted)">is thinking...</span>
256
- <button class="status-cancel-btn" id="streamingStatusCancel">Cancel</button>
257
- </div>
258
-
259
- <!-- Input area: fixed at bottom -->
260
- <div class="input-section">
261
- <!-- Hidden legacy selectors for backward-compat with JS logic -->
262
- <div style="display:none">
263
- <select class="agent-selector sub-agent-selector" data-agent-selector title="Select sub-agent"></select>
264
- <select id="presetSelector" class="preset-selector" title="Load preset"></select>
265
- </div>
266
- <div class="input-card">
267
- <textarea
268
- class="input-card-textarea message-textarea"
269
- id="inputCardTextarea"
270
- data-message-input
271
- placeholder="message agentgui..."
272
- aria-label="Message input"
273
- rows="1"
274
- ></textarea>
275
- <div class="input-card-toolbar">
276
- <div class="input-card-selectors">
277
- <select class="input-chip-select agent-selector cli-selector" id="inputCardAgentSelect" data-cli-selector title="Select agent"></select>
278
- <select class="input-chip-select model-selector" id="inputCardModelSelect" data-model-selector title="Select model" data-empty="true"></select>
279
- <button id="savePresetBtn" class="preset-btn input-icon-btn" title="Save current agent/model as preset" style="width:28px;height:28px;">&#9733;</button>
280
- </div>
281
- <div class="input-card-actions">
282
- <button class="inject-btn input-icon-btn" id="injectBtn" title="Steer into running agent" aria-label="Steer/Inject" style="display:none">
283
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1 .12-14.85"></path></svg>
284
- </button>
285
- <button class="queue-btn input-icon-btn" id="queueBtn" title="Queue message" aria-label="Queue message" style="display:none">
286
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>
287
- </button>
288
- <button class="stop-btn input-icon-btn" id="stopBtn" title="Stop agent" aria-label="Stop agent" style="display:none">
289
- <svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h12v12H6z"/></svg>
290
- </button>
291
- <button class="voice-mic-btn input-icon-btn" id="chatMicBtn" title="Voice input" aria-label="Voice input">
292
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/><path d="M19 10v2a7 7 0 0 1-14 0v-2"/><line x1="12" y1="19" x2="12" y2="23"/><line x1="8" y1="23" x2="16" y2="23"/></svg>
293
- </button>
294
- <button class="send-btn input-send-btn" data-send-button title="Send message (Ctrl+Enter)" aria-label="Send message">
295
- <svg viewBox="0 0 24 24" fill="currentColor"><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>
296
- </button>
297
- </div>
298
- </div>
299
- </div>
300
- </div>
301
- </main>
302
- </div>
303
-
304
- <!-- Folder Browser Modal -->
305
- <div id="folderBrowserModal" class="folder-modal-overlay">
306
- <div class="folder-modal">
307
- <div class="folder-modal-header">
308
- <h3>Select Working Directory</h3>
309
- <button class="folder-modal-close" data-folder-close>&times;</button>
310
- </div>
311
- <div id="folderBreadcrumb" class="folder-breadcrumb"></div>
312
- <ul id="folderList" class="folder-list">
313
- <li class="folder-list-loading">Loading...</li>
314
- </ul>
315
- <div class="folder-modal-footer">
316
- <button class="btn btn-secondary" data-folder-cancel>Cancel</button>
317
- <button class="btn btn-primary" data-folder-select>Select This Folder</button>
318
- </div>
319
- </div>
320
- </div>
321
-
322
- <script>
323
- var _escHtmlMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
324
- var _escHtmlRe = /[&<>"']/g;
325
- window._escHtml = function(t) { return t.replace(_escHtmlRe, function(c) { return _escHtmlMap[c]; }); };
326
- </script>
327
- <script defer src="/gm/js/event-processor.js"></script>
328
- <script defer src="/gm/js/streaming-renderer.js"></script>
329
- <script defer src="/gm/js/streaming-renderer-static.js"></script>
330
- <script defer src="/gm/js/streaming-renderer-static2.js"></script>
331
- <script defer src="/gm/js/streaming-renderer-dispatch.js"></script>
332
- <script defer src="/gm/js/streaming-renderer-text.js"></script>
333
- <script defer src="/gm/js/streaming-renderer-tools.js"></script>
334
- <script defer src="/gm/js/streaming-renderer-tools2.js"></script>
335
- <script defer src="/gm/js/streaming-renderer-params.js"></script>
336
- <script defer src="/gm/js/streaming-renderer-events.js"></script>
337
- <script defer src="/gm/js/streaming-renderer-events2.js"></script>
338
- <script defer src="/gm/js/streaming-renderer-stream.js"></script>
339
- <script defer src="/gm/js/streaming-renderer-render.js"></script>
340
- <script defer src="/gm/js/streaming-renderer-render-misc.js"></script>
341
- <script defer src="/gm/js/streaming-renderer-render2.js"></script>
342
- <script defer src="/gm/js/streaming-renderer-render3.js"></script>
343
- <script defer src="/gm/js/image-loader.js"></script>
344
- <script defer src="/gm/js/image-loader-element.js"></script>
345
- <script defer src="/gm/lib/webjsx.js"></script>
346
- <script defer src="/gm/lib/xstate.umd.min.js"></script>
347
- <script defer src="/gm/js/ws-machine.js"></script>
348
- <script defer src="/gm/js/conv-machine.js"></script>
349
- <script defer src="/gm/js/tool-install-machine.js"></script>
350
- <script defer src="/gm/js/voice-machine.js"></script>
351
- <script defer src="/gm/js/conv-list-machine.js"></script>
352
- <script defer src="/gm/js/prompt-machine.js"></script>
353
- <script defer src="/gm/js/recording-machine.js"></script>
354
- <script defer src="/gm/js/terminal-machine.js"></script>
355
- <script defer src="/gm/js/conversations.js"></script>
356
- <script defer src="/gm/js/conv-sidebar-actions.js"></script>
357
- <script defer src="/gm/js/conv-list-renderer.js"></script>
358
- <script defer src="/gm/js/conv-sidebar-clone.js"></script>
359
- <script defer src="/gm/lib/msgpackr.min.js"></script>
360
- <script defer src="/gm/js/ws-core.js"></script>
361
- <script defer src="/gm/js/ws-latency.js"></script>
362
- <script defer src="/gm/js/websocket-manager.js"></script>
363
- <script defer src="/gm/js/ws-client.js"></script>
364
- <script defer src="/gm/js/syntax-highlighter.js"></script>
365
- <script defer src="/gm/js/syntax-highlighter-render.js"></script>
366
- <script defer src="/gm/js/dialogs.js"></script>
367
- <script defer src="/gm/js/dialogs-types.js"></script>
368
- <script defer src="/gm/js/ui-components.js"></script>
369
- <script defer src="/gm/js/ui-components-rendering.js"></script>
370
- <script defer src="/gm/js/state-barrier.js"></script>
371
- <script defer src="/gm/js/terminal.js"></script>
372
- <script defer src="/gm/js/script-runner.js"></script>
373
- <script defer src="/gm/js/tools-manager-ui.js"></script>
374
- <script defer src="/gm/js/tools-manager.js"></script>
375
- <script defer src="/gm/js/stt-handler.js"></script>
376
- <script defer src="/gm/js/voice.js"></script>
377
- <script defer src="/gm/js/pm2-monitor.js"></script>
378
- <script defer src="/gm/js/event-filter-config.js"></script>
379
- <script defer src="/gm/js/client.js"></script>
380
- <script defer src="/gm/js/client-ws.js"></script>
381
- <script defer src="/gm/js/client-url.js"></script>
382
- <script defer src="/gm/js/client-ui.js"></script>
383
- <script defer src="/gm/js/client-ui-controls.js"></script>
384
- <script defer src="/gm/js/client-ws-msg.js"></script>
385
- <script defer src="/gm/js/client-streaming.js"></script>
386
- <script defer src="/gm/js/client-streaming2.js"></script>
387
- <script defer src="/gm/js/client-streaming3.js"></script>
388
- <script defer src="/gm/js/client-streaming4.js"></script>
389
- <script defer src="/gm/js/client-events.js"></script>
390
- <script defer src="/gm/js/client-render.js"></script>
391
- <script defer src="/gm/js/client-exec.js"></script>
392
- <script defer src="/gm/js/client-helpers.js"></script>
393
- <script defer src="/gm/js/client-ui2.js"></script>
394
- <script defer src="/gm/js/client-conv.js"></script>
395
- <script defer src="/gm/js/client-agents.js"></script>
396
- <script defer src="/gm/js/client-status.js"></script>
397
- <script defer src="/gm/js/client-cache.js"></script>
398
- <script defer src="/gm/js/client-load.js"></script>
399
- <script defer src="/gm/js/client-scroll.js"></script>
400
- <script defer src="/gm/js/client-utils.js"></script>
401
- <script defer src="/gm/js/features.js"></script>
402
- <script defer src="/gm/js/agent-auth.js"></script>
403
- <script defer src="/gm/js/agent-auth-oauth.js"></script>
404
- <script defer src="/gm/js/app-shortcuts.js"></script>
405
- <script defer src="/gm/app.js"></script>
406
-
407
- <script>
408
- const savedTheme = localStorage.getItem('theme') || 'light';
409
- if (savedTheme === 'dark') document.documentElement.classList.add('dark');
410
-
411
- window.addEventListener('error', (event) => console.error('Uncaught error:', event.error));
412
- window.addEventListener('unhandledrejection', (event) => console.error('Unhandled rejection:', event.reason));
413
- </script>
414
- </body>
415
- </html>
416
-
417
-
418
-
@@ -1,146 +0,0 @@
1
- (function() {
2
- var btn = document.getElementById('agentAuthBtn');
3
- var dropdown = document.getElementById('agentAuthDropdown');
4
- var agents = [], providers = {}, authRunning = false, editingProvider = null;
5
-
6
- window.__agentAuthState = {
7
- get authRunning() { return authRunning; },
8
- set authRunning(v) { authRunning = v; },
9
- refresh: function() { refresh(); },
10
- closeDropdown: function() { closeDropdown(); }
11
- };
12
-
13
- function init() {
14
- if (!btn || !dropdown) return;
15
- btn.style.display = 'flex';
16
- btn.addEventListener('click', toggleDropdown);
17
- document.addEventListener('click', function(e) {
18
- if (!btn.contains(e.target) && !dropdown.contains(e.target)) closeDropdown();
19
- });
20
- window.addEventListener('conversation-selected', function() { refresh(); });
21
- window.addEventListener('ws-message', function(e) {
22
- if (window.__agentAuthOAuth && window.__agentAuthOAuth.onWsMessage) window.__agentAuthOAuth.onWsMessage(e);
23
- });
24
- refresh();
25
- }
26
-
27
- function refresh() { fetchAuthStatus(); fetchProviderConfigs(); }
28
-
29
- function fetchAuthStatus() {
30
- window.wsClient.rpc('agent.authstat')
31
- .then(function(data) { agents = data.agents || []; updateButton(); renderDropdown(); })
32
- .catch(function() {});
33
- }
34
-
35
- function fetchProviderConfigs() {
36
- window.wsClient.rpc('auth.configs')
37
- .then(function(data) { providers = data || {}; updateButton(); renderDropdown(); })
38
- .catch(function() {});
39
- }
40
-
41
- function updateButton() {
42
- btn.style.display = 'flex';
43
- var agentOk = agents.length === 0 || agents.every(function(a) { return a.authenticated; });
44
- var pkeys = Object.keys(providers);
45
- var provOk = pkeys.length === 0 || pkeys.some(function(k) { return providers[k].hasKey; });
46
- var anyWarn = agents.some(function(a) { return !a.authenticated; }) ||
47
- pkeys.some(function(k) { return !providers[k].hasKey; });
48
- btn.classList.toggle('auth-ok', agentOk && provOk && (agents.length > 0 || pkeys.length > 0));
49
- btn.classList.toggle('auth-warn', anyWarn);
50
- }
51
-
52
- function renderDropdown() {
53
- dropdown.innerHTML = '';
54
- if (agents.length > 0) {
55
- appendHeader('Agent CLI Auth');
56
- agents.forEach(function(agent) {
57
- var dotClass = agent.authenticated ? 'ok' : (agent.detail === 'unknown' ? 'unknown' : 'missing');
58
- var item = makeItem(dotClass, agent.name, agent.detail);
59
- item.addEventListener('click', function(e) {
60
- e.stopPropagation();
61
- closeDropdown();
62
- if (window.__agentAuthOAuth && window.__agentAuthOAuth.triggerAuth) window.__agentAuthOAuth.triggerAuth(agent.id);
63
- });
64
- dropdown.appendChild(item);
65
- });
66
- }
67
- var pkeys = Object.keys(providers);
68
- if (pkeys.length > 0) {
69
- if (agents.length > 0) appendSep();
70
- appendHeader('Provider Keys');
71
- pkeys.forEach(function(pid) {
72
- var p = providers[pid];
73
- var item = makeItem(p.hasKey ? 'ok' : 'missing', p.name || pid, p.hasKey ? p.apiKey : 'not set');
74
- item.style.flexWrap = 'wrap';
75
- item.addEventListener('click', function(e) { e.stopPropagation(); toggleEdit(pid); });
76
- dropdown.appendChild(item);
77
- if (editingProvider === pid) dropdown.appendChild(makeEditForm(pid));
78
- });
79
- }
80
- }
81
-
82
- function appendHeader(text) {
83
- var h = document.createElement('div');
84
- h.className = 'agent-auth-section-header';
85
- h.textContent = text;
86
- dropdown.appendChild(h);
87
- }
88
-
89
- function appendSep() {
90
- var s = document.createElement('div');
91
- s.style.cssText = 'height:1px;background:var(--color-border);margin:0.25rem 0;';
92
- dropdown.appendChild(s);
93
- }
94
-
95
- function makeItem(dotClass, name, detail) {
96
- var el = document.createElement('button');
97
- el.className = 'agent-auth-item';
98
- el.innerHTML = '<span class="agent-auth-dot ' + dotClass + '"></span><span>' + esc(name) +
99
- '</span><span style="margin-left:auto;font-size:0.7rem;color:var(--color-text-secondary)">' + esc(detail) + '</span>';
100
- return el;
101
- }
102
-
103
- function makeEditForm(pid) {
104
- var form = document.createElement('div');
105
- form.style.cssText = 'width:100%;padding:0.375rem 0.75rem;display:flex;gap:0.375rem;';
106
- var input = document.createElement('input');
107
- input.type = 'password'; input.placeholder = 'API key';
108
- input.style.cssText = 'flex:1;min-width:0;padding:0.25rem 0.5rem;font-size:0.75rem;border:1px solid var(--color-border);border-radius:0.25rem;background:var(--color-bg-primary);color:var(--color-text-primary);outline:none;';
109
- input.addEventListener('click', function(e) { e.stopPropagation(); });
110
- var saveBtn = document.createElement('button');
111
- saveBtn.textContent = 'Save';
112
- saveBtn.style.cssText = 'padding:0.25rem 0.5rem;font-size:0.7rem;font-weight:600;background:var(--color-primary);color:white;border:none;border-radius:0.25rem;cursor:pointer;flex-shrink:0;';
113
- saveBtn.addEventListener('click', function(e) {
114
- e.stopPropagation();
115
- var key = input.value.trim();
116
- if (!key) return;
117
- saveBtn.disabled = true; saveBtn.textContent = '...';
118
- saveProviderKey(pid, key);
119
- });
120
- form.appendChild(input); form.appendChild(saveBtn);
121
- setTimeout(function() { input.focus(); }, 50);
122
- return form;
123
- }
124
-
125
- function toggleEdit(pid) { editingProvider = editingProvider === pid ? null : pid; renderDropdown(); }
126
-
127
- function saveProviderKey(providerId, apiKey) {
128
- window.wsClient.rpc('auth.save', { providerId: providerId, apiKey: apiKey, defaultModel: '' })
129
- .then(function(data) {
130
- if (data.success) { editingProvider = null; fetchProviderConfigs(); }
131
- }).catch(function() { editingProvider = null; renderDropdown(); });
132
- }
133
-
134
- function toggleDropdown(e) {
135
- e.stopPropagation();
136
- if (!dropdown.classList.contains('open')) { editingProvider = null; refresh(); }
137
- dropdown.classList.toggle('open');
138
- }
139
-
140
- function closeDropdown() { dropdown.classList.remove('open'); editingProvider = null; }
141
- function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
142
-
143
- if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
144
- else init();
145
- window.agentAuth = { refresh: refresh };
146
- })();
@@ -1,30 +0,0 @@
1
- function showShortcutsOverlay() {
2
- if (document.querySelector('.shortcuts-overlay')) return;
3
- const overlay = document.createElement('div');
4
- overlay.className = 'shortcuts-overlay';
5
- overlay.innerHTML = `<div class="shortcuts-panel">
6
- <h3>Keyboard Shortcuts</h3>
7
- <table>
8
- <tr><td><kbd>Ctrl</kbd>+<kbd>N</kbd></td><td>New conversation</td></tr>
9
- <tr><td><kbd>Ctrl</kbd>+<kbd>B</kbd></td><td>Toggle sidebar</td></tr>
10
- <tr><td><kbd>Ctrl</kbd>+<kbd>Enter</kbd></td><td>Send message</td></tr>
11
- <tr><td><kbd>Escape</kbd></td><td>Cancel stream / blur input</td></tr>
12
- <tr><td><kbd>?</kbd></td><td>Show this help</td></tr>
13
- </table>
14
- <p style="margin:1rem 0 0;font-size:0.75rem;color:#9ca3af;">Press Escape to close</p>
15
- </div>`;
16
- overlay.addEventListener('click', (e) => { if (e.target === overlay) overlay.remove(); });
17
- document.body.appendChild(overlay);
18
- }
19
-
20
- document.addEventListener('keydown', (e) => {
21
- if (e.key === '?' && !e.ctrlKey && !e.metaKey) {
22
- const tag = document.activeElement?.tagName;
23
- if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') return;
24
- e.preventDefault();
25
- showShortcutsOverlay();
26
- }
27
- if (e.key === 'Escape' && document.querySelector('.shortcuts-overlay')) {
28
- document.querySelector('.shortcuts-overlay').remove();
29
- }
30
- });
@@ -1,18 +0,0 @@
1
- class RecorderProcessor extends AudioWorkletProcessor {
2
- constructor() {
3
- super();
4
- this._stopped = false;
5
- this.port.onmessage = (e) => {
6
- if (e.data === 'stop') this._stopped = true;
7
- };
8
- }
9
- process(inputs) {
10
- if (this._stopped) return false;
11
- const input = inputs[0];
12
- if (input && input[0] && input[0].length > 0) {
13
- this.port.postMessage(new Float32Array(input[0]));
14
- }
15
- return true;
16
- }
17
- }
18
- registerProcessor('recorder-processor', RecorderProcessor);