agentgui 1.0.25 → 1.0.27

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.
@@ -0,0 +1,284 @@
1
+ # Automatic Continuous Importing Feature
2
+
3
+ ## Overview
4
+ AgentGUI now automatically and continuously imports Claude Code conversations **without requiring any user action**. This ensures conversations are always available and up-to-date.
5
+
6
+ ## How It Works
7
+
8
+ ### Server-Side (Every 30 Seconds)
9
+ ```
10
+ Server startup
11
+
12
+ [IMMEDIATE] Import Claude Code conversations (first run)
13
+
14
+ [EVERY 30 SECONDS] Auto-import new conversations
15
+
16
+ If new conversations found:
17
+ • Add them to database
18
+ • Broadcast 'conversations_updated' event to all connected clients
19
+ • Log: "[AUTO-IMPORT] Imported X new Claude Code conversations"
20
+ ```
21
+
22
+ ### Frontend-Side
23
+ ```
24
+ Page loads
25
+
26
+ [IMMEDIATE] Fetch conversations from API
27
+
28
+ [EVERY 10 SECONDS] Fetch conversations again (as fallback)
29
+
30
+ [ON SYNC EVENT] Receive 'conversations_updated' from server
31
+
32
+ Immediately refresh conversation list
33
+
34
+ Users see new conversations appear in real-time
35
+ ```
36
+
37
+ ## Key Features
38
+
39
+ ✅ **Automatic**: No user action needed
40
+ ✅ **Continuous**: Runs every 30 seconds (server) and 10 seconds (client)
41
+ ✅ **Real-time**: New conversations appear immediately via WebSocket
42
+ ✅ **No Duplicates**: Skips conversations already imported
43
+ ✅ **Cross-tab**: Broadcasts via BroadcastChannel API
44
+ ✅ **Resilient**: Fallback mechanism if WebSocket fails
45
+ ✅ **Logging**: All imports logged for debugging
46
+
47
+ ## Where Conversations Come From
48
+
49
+ ### Automatically Discovered From:
50
+ 1. **Claude Code Projects** (~/.claude/projects/)
51
+ - Scans sessions-index.json files
52
+ - Reads .jsonl message files
53
+ - Imports with "[project] title" format
54
+
55
+ 2. **Created in AgentGUI**
56
+ - New conversations created via UI
57
+ - Automatically stored in database
58
+
59
+ ## Example Flow
60
+
61
+ ### Scenario: User Uses Claude Code, Then Opens AgentGUI
62
+
63
+ ```
64
+ 11:00:00 - User creates conversation in Claude Code
65
+ 11:00:15 - AgentGUI server detects new conversation in ~/.claude/projects/
66
+ 11:00:20 - Server imports conversation automatically
67
+ 11:00:20 - Server broadcasts 'conversations_updated' event
68
+ 11:00:21 - All connected browser tabs receive update
69
+ 11:00:21 - Users see new conversation appear in sidebar
70
+ ```
71
+
72
+ ### Scenario: Multiple Tabs Open
73
+
74
+ ```
75
+ Tab 1 opens AgentGUI
76
+ Tab 2 opens AgentGUI (few seconds later)
77
+
78
+ Tab 1 receives 'conversations_updated' from server
79
+ Tab 1 uses BroadcastChannel to notify Tab 2
80
+ Tab 2 also refreshes conversation list
81
+ Both tabs show latest conversations in sync
82
+ ```
83
+
84
+ ## Server Logs
85
+
86
+ You'll see logs like:
87
+ ```
88
+ [AUTO-IMPORT] Imported 2 new Claude Code conversations (42 already exist)
89
+ [AUTO-IMPORT] Imported 1 new Claude Code conversation (43 already exist)
90
+ [AUTO-IMPORT] (nothing new this cycle)
91
+ ```
92
+
93
+ ## Client Logs
94
+
95
+ In browser console:
96
+ ```
97
+ [SYNC] Server imported 3 new conversations, refreshing...
98
+ [DEBUG] Init: Auto-imported Claude Code conversations
99
+ [DEBUG] Loaded conversations, total: 86
100
+ ```
101
+
102
+ ## Configuration
103
+
104
+ ### Import Frequency (Server)
105
+ Current: **30 seconds**
106
+ Location: `server.js` line `setInterval(performAutoImport, 30000);`
107
+
108
+ To change:
109
+ ```javascript
110
+ setInterval(performAutoImport, 60000); // 60 seconds
111
+ setInterval(performAutoImport, 5000); // 5 seconds
112
+ ```
113
+
114
+ ### Refresh Frequency (Client)
115
+ Current: **10 seconds**
116
+ Location: `app.js` line `setInterval(() => { ... }, 10000);`
117
+
118
+ To change:
119
+ ```javascript
120
+ }, 60000); // 60 seconds
121
+ }, 5000); // 5 seconds
122
+ ```
123
+
124
+ ## Data Flow Diagram
125
+
126
+ ```
127
+ ┌─────────────────────────────────────────────────────┐
128
+ │ Claude Code │
129
+ │ ~/.claude/projects/*/sessions-index.json │
130
+ └─────────────────┬───────────────────────────────────┘
131
+ │ (monitors every 30s)
132
+
133
+ ┌─────────────────────────────────────────────────────┐
134
+ │ AgentGUI Server │
135
+ │ • queries.importClaudeCodeConversations() │
136
+ │ • Stores in ~/.gmgui/data.db │
137
+ │ • Broadcasts via WebSocket │
138
+ └──────┬──────────────────────────┬────────────────────┘
139
+ │ │
140
+ │ (WebSocket event) │ (HTTP API)
141
+ ↓ ↓
142
+ ┌─────────────────────────────────────────────────────┐
143
+ │ Browser (Frontend) │
144
+ │ • Listens on sync WebSocket │
145
+ │ • Receives 'conversations_updated' event │
146
+ │ • Calls fetchConversations() │
147
+ │ • Calls renderChatHistory() │
148
+ └──────┬──────────────────────────────────────────────┘
149
+
150
+
151
+ ┌─────────────────────────────────────────────────────┐
152
+ │ Chat Sidebar │
153
+ │ • Displays conversation list │
154
+ │ • User can click to view conversation │
155
+ └─────────────────────────────────────────────────────┘
156
+ ```
157
+
158
+ ## Troubleshooting
159
+
160
+ ### Conversations Not Appearing
161
+
162
+ **Check 1: Server Auto-Import**
163
+ ```bash
164
+ # Look for these logs in server output
165
+ grep "\[AUTO-IMPORT\]" server.log
166
+
167
+ # If no logs, auto-import might not be running
168
+ ```
169
+
170
+ **Check 2: Claude Code Availability**
171
+ ```bash
172
+ # Check if Claude Code projects exist
173
+ ls -la ~/.claude/projects/
174
+
175
+ # Count projects with conversations
176
+ find ~/.claude/projects -name "sessions-index.json" | wc -l
177
+ ```
178
+
179
+ **Check 3: Browser Sync**
180
+ ```javascript
181
+ // In browser console
182
+ // Check if WebSocket is connected
183
+ console.log('WebSocket state:', app.syncWs.ws?.readyState);
184
+
185
+ // Try manual refresh
186
+ await app.fetchConversations();
187
+ app.renderChatHistory();
188
+ ```
189
+
190
+ **Check 4: Database**
191
+ ```bash
192
+ # Check total conversations in DB
193
+ node -e "
194
+ const DB = require('better-sqlite3');
195
+ const db = new DB(process.env.HOME + '/.gmgui/data.db');
196
+ const count = db.prepare('SELECT COUNT(*) as c FROM conversations').get();
197
+ console.log('Database has:', count.c, 'conversations');
198
+ db.close();
199
+ "
200
+ ```
201
+
202
+ ### Too Many Import Logs
203
+
204
+ If server logs are too verbose:
205
+ 1. Increase `setInterval` time (30000 → 60000 or more)
206
+ 2. Add log level filtering
207
+
208
+ ### Conversations Take Too Long to Appear
209
+
210
+ If new conversations take > 1 minute:
211
+ 1. Check server auto-import interval (default 30s)
212
+ 2. Check client refresh interval (default 10s)
213
+ 3. Check network connectivity
214
+ 4. Check browser console for errors
215
+
216
+ ## Performance Considerations
217
+
218
+ ### Import Impact
219
+ - **Minimal**: Import skips existing conversations
220
+ - **Fast**: Only processes new conversations
221
+ - **Efficient**: Uses database transactions
222
+
223
+ ### Client Impact
224
+ - **WebSocket**: Real-time updates, low bandwidth
225
+ - **Polling**: Every 10 seconds, minimal traffic
226
+ - **Rendering**: Only updates when conversations change
227
+
228
+ ## Security Notes
229
+
230
+ - Only imports from user's local `.claude/projects/`
231
+ - No external network access needed
232
+ - All conversations stored locally
233
+ - Respects filesystem permissions
234
+
235
+ ## Future Enhancements
236
+
237
+ Potential improvements:
238
+ - Configurable import interval via UI
239
+ - Import from multiple sources
240
+ - Batch import optimization
241
+ - Import history/logs viewer
242
+ - Import statistics dashboard
243
+ - Per-project import settings
244
+
245
+ ## Testing
246
+
247
+ ### Manual Test: Add Claude Code Conversation
248
+ ```bash
249
+ # 1. Use Claude Code (creates ~/.claude/projects/*/sessions-index.json)
250
+ # 2. Wait up to 30 seconds
251
+ # 3. Check browser - should see new conversation appear
252
+ # 4. Confirm console logs show "[AUTO-IMPORT] Imported X..."
253
+ ```
254
+
255
+ ### Manual Test: Force Import
256
+ ```javascript
257
+ // In browser console
258
+ await fetch('/gm/api/import/claude-code')
259
+ .then(r => r.json())
260
+ .then(d => console.log('Manual import result:', d));
261
+
262
+ // Then refresh
263
+ await app.fetchConversations();
264
+ app.renderChatHistory();
265
+ ```
266
+
267
+ ## Related Files
268
+
269
+ - `server.js` - Server auto-import implementation
270
+ - `app.js` - Frontend sync handling
271
+ - `database.js` - Query functions
272
+ - `acp-launcher.js` - Claude Code connection
273
+
274
+ ## Changelog
275
+
276
+ ### Version 1.1.0 (Current)
277
+ - ✅ Added automatic server-side importing every 30 seconds
278
+ - ✅ Added WebSocket broadcast for instant updates
279
+ - ✅ Added client-side sync event handler
280
+ - ✅ Integrated with existing periodic sync
281
+
282
+ ### Version 1.0.0 (Previous)
283
+ - Manual import on demand via `/api/import/claude-code`
284
+ - No automatic background importing
@@ -0,0 +1,225 @@
1
+ # Remote Server Debugging Guide
2
+
3
+ ## Issue
4
+ Conversations are not displaying in AgentGUI on remote server (https://buildesk.acc.l-inc.co.za/gm/), even though:
5
+ - ✅ The application loads
6
+ - ✅ The layout works
7
+ - ✅ The sidebar is visible
8
+
9
+ ## Root Cause Analysis
10
+
11
+ ### On Local Server ✅
12
+ - 83 conversations stored in `~/.gmgui/data.db`
13
+ - 68 Claude Code conversations discovered in `~/.claude/projects/`
14
+ - All 68 imported successfully
15
+ - API returns conversations correctly
16
+ - Frontend fetches and displays them
17
+
18
+ ### On Remote Server ❓
19
+ - Unknown database state
20
+ - Unknown Claude Code availability
21
+ - Conversations showing as empty
22
+
23
+ ## Diagnostic Checklist
24
+
25
+ ### 1. Check if API is returning conversations
26
+
27
+ In browser console:
28
+ ```javascript
29
+ fetch('/gm/api/conversations')
30
+ .then(r => r.json())
31
+ .then(d => console.log('Conversations from API:', d.conversations?.length || 0))
32
+ ```
33
+
34
+ If this returns 0: **Database is empty or API is failing**
35
+ If this returns > 0: **API is working, issue is in frontend**
36
+
37
+ ### 2. Check frontend state
38
+
39
+ In browser console:
40
+ ```javascript
41
+ // Check if app was initialized
42
+ console.log('app.conversations.size:', app.conversations.size);
43
+
44
+ // If size is 0, check if fetchConversations was called
45
+ console.log('API returned data:', app.conversations);
46
+
47
+ // Force a refetch
48
+ await app.fetchConversations();
49
+ console.log('After refetch:', app.conversations.size);
50
+
51
+ // If still 0, render to see debug info
52
+ app.renderChatHistory();
53
+ ```
54
+
55
+ ### 3. Manually trigger import
56
+
57
+ In browser console:
58
+ ```javascript
59
+ // Try to import Claude Code conversations
60
+ await fetch('/gm/api/import/claude-code')
61
+ .then(r => r.json())
62
+ .then(d => console.log('Import result:', d));
63
+ ```
64
+
65
+ Then refetch:
66
+ ```javascript
67
+ await app.fetchConversations();
68
+ app.renderChatHistory();
69
+ ```
70
+
71
+ ### 4. Check Claude Code projects
72
+
73
+ In terminal on remote server:
74
+ ```bash
75
+ # Check if Claude Code directory exists
76
+ ls -la ~/.claude/projects/
77
+
78
+ # List all projects
79
+ find ~/.claude/projects -name "sessions-index.json" 2>/dev/null | wc -l
80
+
81
+ # Check first project
82
+ ls -la ~/.claude/projects/ | head
83
+ ```
84
+
85
+ If directory doesn't exist or is empty: **Claude Code hasn't been used on this server**
86
+
87
+ ### 5. Check database directly
88
+
89
+ In terminal on remote server:
90
+ ```bash
91
+ # Check database location (should be ~/.gmgui/data.db)
92
+ ls -lh ~/.gmgui/data.db
93
+
94
+ # Get conversation count (if Node/better-sqlite3 available)
95
+ node -e "
96
+ const DB = require('better-sqlite3');
97
+ const db = new DB(process.env.HOME + '/.gmgui/data.db');
98
+ const count = db.prepare('SELECT COUNT(*) as c FROM conversations').get();
99
+ console.log('DB Conversations:', count.c);
100
+ db.close();
101
+ "
102
+ ```
103
+
104
+ If file doesn't exist: **Database not initialized**
105
+ If count is 0: **No conversations in database**
106
+
107
+ ## Solutions by Scenario
108
+
109
+ ### Scenario A: API returns 0, Database is empty
110
+ **Problem:** No conversations to display (first time setup)
111
+ **Solution:**
112
+ 1. Import Claude Code conversations (if available)
113
+ 2. Or create new conversations
114
+ 3. Or import from JSON
115
+
116
+ ### Scenario B: API returns conversations, Frontend shows 0
117
+ **Problem:** Frontend not fetching/displaying properly
118
+ **Solution:**
119
+ 1. Check browser console for errors
120
+ 2. Check [DEBUG] logs
121
+ 3. Try `_debug.forceRefetch()` in console
122
+ 4. Check if BASE_URL is set correctly
123
+
124
+ ### Scenario C: Claude Code projects exist but no conversations
125
+ **Problem:** Discovered conversations but not imported
126
+ **Solution:**
127
+ 1. Open browser console
128
+ 2. Call import endpoint
129
+ 3. Call `app.fetchConversations()`
130
+ 4. Call `app.renderChatHistory()`
131
+
132
+ ### Scenario D: Conversations exist but frontend won't display
133
+ **Problem:** Rendering issue
134
+ **Solution:**
135
+ 1. Check HTML element `#chatList` exists
136
+ 2. Check CSS isn't hiding it
137
+ 3. Check for JavaScript errors
138
+ 4. Test `_debug.forceRefetch()`
139
+
140
+ ## What to Look For in Console
141
+
142
+ When page loads, should see these logs:
143
+ ```
144
+ [DEBUG] Init: Starting initialization
145
+ [DEBUG] Init: BASE_URL = /gm
146
+ [DEBUG] Init: Window width: XXXX
147
+ [DEBUG] Init: Fetched agents, count: X
148
+ [DEBUG] Init: Auto-imported Claude Code conversations
149
+ [DEBUG] fetchConversations: Starting fetch from /gm/api/conversations
150
+ [DEBUG] fetchConversations response count: X
151
+ [DEBUG] Init: Fetched conversations, count: X
152
+ [DEBUG] renderChatHistory - conversations.size: X
153
+ ```
154
+
155
+ If you see `conversations.size: 0` anywhere, that's the issue.
156
+
157
+ ## Commands to Run in Browser Console
158
+
159
+ ```javascript
160
+ // 1. Comprehensive status check
161
+ {
162
+ api: await fetch('/gm/api/conversations').then(r => r.json()).then(d => d.conversations?.length),
163
+ app: app.conversations.size,
164
+ baseUrl: BASE_URL,
165
+ windowWidth: window.innerWidth,
166
+ chatList: !!document.getElementById('chatList'),
167
+ agents: app.agents.size
168
+ }
169
+
170
+ // 2. Force refetch and render
171
+ await app.fetchConversations();
172
+ app.renderChatHistory();
173
+ window.app.conversations.size
174
+
175
+ // 3. Check Claude Code availability
176
+ await fetch('/gm/api/discover/claude-code').then(r => r.json()).then(d => console.log('Claude Code available:', d.discovered?.length))
177
+
178
+ // 4. Manual import
179
+ await fetch('/gm/api/import/claude-code').then(r => r.json()).then(d => console.log('Import:', d))
180
+ ```
181
+
182
+ ## Expected Behavior
183
+
184
+ **After Fix:**
185
+ 1. Page loads
186
+ 2. Console shows [DEBUG] logs
187
+ 3. Page title shows "GMGUI (XX chats)"
188
+ 4. Sidebar shows conversation list
189
+ 5. Can click conversation to view it
190
+ 6. Can create new conversations
191
+ 7. Can import Claude Code conversations
192
+
193
+ ## If Still Stuck
194
+
195
+ 1. **Collect information:**
196
+ - Output of all console commands above
197
+ - Screenshot of browser console showing all [DEBUG] logs
198
+ - Output of `echo $HOME` on remote server
199
+ - Output of `ls -la ~/.claude/projects/` on remote server
200
+ - Output of `ls -la ~/.gmgui/` on remote server
201
+
202
+ 2. **Share these logs** for remote debugging
203
+
204
+ 3. **Try manual steps:**
205
+ - In console: `await _debug.forceRefetch()`
206
+ - Then: `app.renderChatHistory()`
207
+ - Screenshot result
208
+
209
+ ## Important Notes
210
+
211
+ - `~/.gmgui/data.db` - AgentGUI database (stores conversations)
212
+ - `~/.claude/projects/` - Claude Code storage (where conversations come from)
213
+ - `/gm/api/conversations` - Endpoint to get all conversations
214
+ - `/gm/api/discover/claude-code` - Find available Claude Code conversations
215
+ - `/gm/api/import/claude-code` - Import Claude Code conversations to AgentGUI
216
+
217
+ ## Performance Tip
218
+
219
+ If you have lots of conversations (100+), they might load slowly. You can paginate by checking:
220
+ ```javascript
221
+ // Check how many are in the list element
222
+ document.getElementById('chatList').children.length
223
+ ```
224
+
225
+ If this is less than the API count, pagination is needed (future enhancement).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.25",
3
+ "version": "1.0.27",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -454,16 +454,30 @@ function onServerReady() {
454
454
  console.log(`GMGUI running on http://localhost:${PORT}${BASE_URL}/`);
455
455
  console.log(`Agents: ${discoveredAgents.map(a => a.name).join(', ') || 'none'}`);
456
456
  console.log(`Hot reload: ${watch ? 'on' : 'off'}`);
457
- // Auto-import Claude Code conversations
458
- const imported = queries.importClaudeCodeConversations();
459
- if (imported.length > 0) {
460
- const importedCount = imported.filter(i => i.status === 'imported').length;
461
- const skippedCount = imported.filter(i => i.status === 'skipped').length;
462
- if (importedCount > 0) {
463
- console.log(`Auto-imported ${importedCount} new Claude Code conversations (${skippedCount} already imported)`);
464
- } else if (skippedCount > 0) {
465
- console.log(`Claude Code conversations ready (${skippedCount} already imported)`);
457
+
458
+ // Run auto-import immediately
459
+ performAutoImport();
460
+
461
+ // Then run it every 30 seconds (constant automatic importing)
462
+ setInterval(performAutoImport, 30000);
463
+ }
464
+
465
+ function performAutoImport() {
466
+ try {
467
+ const imported = queries.importClaudeCodeConversations();
468
+ if (imported.length > 0) {
469
+ const importedCount = imported.filter(i => i.status === 'imported').length;
470
+ const skippedCount = imported.filter(i => i.status === 'skipped').length;
471
+ if (importedCount > 0) {
472
+ console.log(`[AUTO-IMPORT] Imported ${importedCount} new Claude Code conversations (${skippedCount} already exist)`);
473
+ // Broadcast to all connected clients that conversations were updated
474
+ broadcastSync({ type: 'conversations_updated', count: importedCount });
475
+ } else if (skippedCount > 0) {
476
+ // All conversations already imported, don't spam logs
477
+ }
466
478
  }
479
+ } catch (err) {
480
+ console.error('[AUTO-IMPORT] Error:', err.message);
467
481
  }
468
482
  }
469
483
 
package/static/app.js CHANGED
@@ -226,11 +226,20 @@ class GMGUIApp {
226
226
  }
227
227
  break;
228
228
 
229
- case 'message_created':
230
- if (!fromBroadcast && this.broadcastChannel) {
231
- this.broadcastChannel.postMessage(event);
232
- }
233
- break;
229
+ case 'conversations_updated':
230
+ // Server notified us that new conversations were imported
231
+ console.log('[SYNC] Server imported', event.count, 'new conversations, refreshing...');
232
+ this.fetchConversations().then(() => this.renderChatHistory());
233
+ if (!fromBroadcast && this.broadcastChannel) {
234
+ this.broadcastChannel.postMessage(event);
235
+ }
236
+ break;
237
+
238
+ case 'message_created':
239
+ if (!fromBroadcast && this.broadcastChannel) {
240
+ this.broadcastChannel.postMessage(event);
241
+ }
242
+ break;
234
243
 
235
244
  case 'session_updated':
236
245
  if (event.status === 'completed' && event.message) {