agentgui 1.0.930 → 1.0.932

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 (128) hide show
  1. package/AGENTS.md +35 -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/js/app.js +64 -68
  10. package/site/app/js/backend.js +1 -1
  11. package/static/lib/xstate.umd.min.js +1 -1
  12. package/lib/db-queries-chunks.js +0 -195
  13. package/lib/db-queries-chunks2.js +0 -82
  14. package/lib/db-queries-cleanup.js +0 -74
  15. package/lib/db-queries-del.js +0 -141
  16. package/lib/db-queries-events.js +0 -68
  17. package/lib/db-queries-import.js +0 -133
  18. package/lib/db-queries-messages.js +0 -102
  19. package/lib/db-queries-sessions.js +0 -112
  20. package/lib/db-queries-streams.js +0 -100
  21. package/lib/db-queries.js +0 -89
  22. package/lib/jsonl-parser.js +0 -190
  23. package/lib/jsonl-watcher.js +0 -64
  24. package/lib/routes-agent-actions.js +0 -61
  25. package/lib/routes-auth-config.js +0 -30
  26. package/lib/routes-conversations.js +0 -96
  27. package/lib/routes-debug.js +0 -119
  28. package/lib/routes-messages.js +0 -139
  29. package/lib/routes-runs.js +0 -156
  30. package/lib/routes-scripts.js +0 -135
  31. package/lib/routes-sessions.js +0 -144
  32. package/lib/routes-threads.js +0 -100
  33. package/lib/routes-util.js +0 -110
  34. package/lib/ws-handlers-conv.js +0 -138
  35. package/lib/ws-handlers-conv2.js +0 -169
  36. package/lib/ws-handlers-msg.js +0 -121
  37. package/lib/ws-handlers-queue.js +0 -56
  38. package/lib/ws-handlers-run.js +0 -182
  39. package/lib/ws-handlers-scripts.js +0 -66
  40. package/lib/ws-handlers-session.js +0 -105
  41. package/lib/ws-handlers-session2.js +0 -85
  42. package/lib/ws-legacy-handlers.js +0 -51
  43. package/static/app.js +0 -261
  44. package/static/css/app-shell.css +0 -419
  45. package/static/css/brand-bible.css +0 -591
  46. package/static/css/colors_and_type.css +0 -568
  47. package/static/css/gmail-skin.css +0 -663
  48. package/static/css/main.css +0 -4015
  49. package/static/css/tools-popup.css +0 -472
  50. package/static/index.html +0 -418
  51. package/static/js/agent-auth.js +0 -146
  52. package/static/js/app-shortcuts.js +0 -30
  53. package/static/js/audio-recorder-processor.js +0 -18
  54. package/static/js/client-agents.js +0 -155
  55. package/static/js/client-cache.js +0 -171
  56. package/static/js/client-conv.js +0 -198
  57. package/static/js/client-events.js +0 -164
  58. package/static/js/client-exec.js +0 -160
  59. package/static/js/client-helpers.js +0 -199
  60. package/static/js/client-load.js +0 -175
  61. package/static/js/client-render.js +0 -132
  62. package/static/js/client-scroll.js +0 -178
  63. package/static/js/client-status.js +0 -167
  64. package/static/js/client-streaming.js +0 -117
  65. package/static/js/client-streaming2.js +0 -116
  66. package/static/js/client-streaming3.js +0 -153
  67. package/static/js/client-streaming4.js +0 -194
  68. package/static/js/client-ui-controls.js +0 -170
  69. package/static/js/client-ui.js +0 -128
  70. package/static/js/client-ui2.js +0 -160
  71. package/static/js/client-url.js +0 -93
  72. package/static/js/client-utils.js +0 -174
  73. package/static/js/client-ws-msg.js +0 -88
  74. package/static/js/client-ws.js +0 -161
  75. package/static/js/client.js +0 -145
  76. package/static/js/codec.js +0 -4
  77. package/static/js/conv-list-machine.js +0 -145
  78. package/static/js/conv-list-renderer.js +0 -198
  79. package/static/js/conv-machine.js +0 -110
  80. package/static/js/conv-sidebar-actions.js +0 -188
  81. package/static/js/conv-sidebar-clone.js +0 -91
  82. package/static/js/conversations.js +0 -116
  83. package/static/js/dialogs-types.js +0 -111
  84. package/static/js/dialogs.js +0 -53
  85. package/static/js/event-filter-config.js +0 -36
  86. package/static/js/event-processor.js +0 -181
  87. package/static/js/features.js +0 -187
  88. package/static/js/image-loader-element.js +0 -76
  89. package/static/js/image-loader.js +0 -146
  90. package/static/js/prompt-machine.js +0 -108
  91. package/static/js/recording-machine.js +0 -49
  92. package/static/js/script-runner.js +0 -192
  93. package/static/js/state-barrier.js +0 -105
  94. package/static/js/streaming-renderer-dispatch.js +0 -144
  95. package/static/js/streaming-renderer-events.js +0 -163
  96. package/static/js/streaming-renderer-events2.js +0 -125
  97. package/static/js/streaming-renderer-params.js +0 -38
  98. package/static/js/streaming-renderer-render-misc.js +0 -107
  99. package/static/js/streaming-renderer-render.js +0 -181
  100. package/static/js/streaming-renderer-render2.js +0 -149
  101. package/static/js/streaming-renderer-render3.js +0 -142
  102. package/static/js/streaming-renderer-static.js +0 -181
  103. package/static/js/streaming-renderer-static2.js +0 -140
  104. package/static/js/streaming-renderer-stream.js +0 -170
  105. package/static/js/streaming-renderer-text.js +0 -185
  106. package/static/js/streaming-renderer-tools.js +0 -189
  107. package/static/js/streaming-renderer-tools2.js +0 -92
  108. package/static/js/streaming-renderer.js +0 -200
  109. package/static/js/syntax-highlighter-render.js +0 -72
  110. package/static/js/syntax-highlighter.js +0 -131
  111. package/static/js/terminal-machine.js +0 -51
  112. package/static/js/terminal.js +0 -178
  113. package/static/js/ui-components-rendering.js +0 -62
  114. package/static/js/ui-components.js +0 -88
  115. package/static/js/websocket-manager.js +0 -107
  116. package/static/js/ws-client.js +0 -87
  117. package/static/js/ws-core.js +0 -162
  118. package/static/js/ws-latency.js +0 -88
  119. package/static/js/ws-machine.js +0 -68
  120. package/static/lib/msgpackr.min.js +0 -2
  121. package/static/theme.js +0 -74
  122. package/static/vendor/highlight-js.css +0 -10
  123. package/static/vendor/highlight.min.js +0 -1244
  124. package/static/vendor/prism-dark.css +0 -129
  125. package/static/vendor/rippleui.css +0 -35
  126. package/static/vendor/xterm-addon-fit.min.js +0 -8
  127. package/static/vendor/xterm.css +0 -8
  128. 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);