agentgui 1.0.57 → 1.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/acp-launcher.js CHANGED
@@ -33,7 +33,6 @@ export default class ACPConnection {
33
33
  }
34
34
 
35
35
  async sendPrompt(prompt) {
36
- const messages = [];
37
36
  let fullResponse = '';
38
37
 
39
38
  try {
@@ -45,19 +44,33 @@ export default class ACPConnection {
45
44
  options: {}
46
45
  });
47
46
 
47
+ // query() returns an async iterable
48
+ // Iterate through all messages and collect the response
48
49
  for await (const message of response) {
49
- fullResponse += message.content?.map(c => c.text || '').join('') || '';
50
-
51
- if (this.onUpdate) {
52
- this.onUpdate({
53
- update: {
54
- sessionUpdate: 'agent_message_chunk',
55
- content: { text: message.content?.map(c => c.text || '').join('') || '' }
56
- }
57
- });
50
+ // Try multiple content paths: direct .content or .message.content
51
+ let content = message.content || message.message?.content;
52
+
53
+ if (content && Array.isArray(content)) {
54
+ const textChunks = content.map(c => c.text || '').join('');
55
+ fullResponse += textChunks;
56
+
57
+ // Emit update for real-time display
58
+ if (this.onUpdate && textChunks) {
59
+ this.onUpdate({
60
+ update: {
61
+ sessionUpdate: 'agent_message_chunk',
62
+ content: { text: textChunks }
63
+ }
64
+ });
65
+ }
58
66
  }
59
67
  }
60
68
 
69
+ // Fallback if nothing was collected
70
+ if (!fullResponse) {
71
+ fullResponse = 'No response from agent';
72
+ }
73
+
61
74
  return { content: fullResponse };
62
75
  } catch (err) {
63
76
  console.error(`[ACP] Query error: ${err.message}`);
@@ -52,18 +52,11 @@ export class ConversationImporter {
52
52
  return imported;
53
53
  }
54
54
 
55
- static async importOpenCodeSessions() {
56
- // TODO: Implement OpenCode session import once storage location is determined
57
- return [];
58
- }
59
-
60
55
  static async importAll() {
61
56
  console.log('[Importer] Starting conversation import...');
62
57
  const claudeCode = await this.importClaudeCodeSessions();
63
- const openCode = await this.importOpenCodeSessions();
64
58
  console.log(`[Importer] Imported ${claudeCode.length} Claude Code conversations`);
65
- console.log(`[Importer] Imported ${openCode.length} OpenCode conversations`);
66
- return { claudeCode, openCode };
59
+ return claudeCode;
67
60
  }
68
61
  }
69
62
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.57",
3
+ "version": "1.0.59",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -558,8 +558,8 @@ const hotReloadClients = [];
558
558
  const syncClients = new Set();
559
559
 
560
560
  wss.on('connection', (ws, req) => {
561
- const url = new URL(req.url, 'http://localhost');
562
- const wsPath = url.pathname.startsWith(BASE_URL) ? url.pathname.slice(BASE_URL.length) : url.pathname;
561
+ // req.url in WebSocket is just the path (e.g., '/gm/sync'), not a full URL
562
+ const wsPath = req.url.startsWith(BASE_URL) ? req.url.slice(BASE_URL.length) : req.url;
563
563
  if (wsPath === '/hot-reload') {
564
564
  hotReloadClients.push(ws);
565
565
  ws.on('close', () => { const i = hotReloadClients.indexOf(ws); if (i > -1) hotReloadClients.splice(i, 1); });
package/static/app.js CHANGED
@@ -108,7 +108,7 @@ class GMGUIApp {
108
108
  console.log('[DEBUG] Init: Starting initialization');
109
109
  console.log('[DEBUG] Init: BASE_URL =', BASE_URL);
110
110
  console.log('[DEBUG] Init: Window width:', window.innerWidth);
111
-
111
+
112
112
  // Ensure sidebar is visible on desktop (open on wide screens)
113
113
  const sidebar = document.getElementById('sidebar');
114
114
  if (window.innerWidth >= 768 && sidebar) {
@@ -118,13 +118,25 @@ class GMGUIApp {
118
118
  console.log('[DEBUG] Init: Mobile/narrow screen detected, opening sidebar');
119
119
  sidebar.classList.add('open');
120
120
  }
121
-
121
+
122
122
  this.loadSettings();
123
123
  this.setupEventListeners();
124
124
  await this.fetchHome();
125
125
  console.log('[DEBUG] Init: Fetched home');
126
126
  await this.fetchAgents();
127
127
  console.log('[DEBUG] Init: Fetched agents, count:', this.agents.size);
128
+
129
+ // Pre-select agent on first load: try from localStorage, otherwise pick first available
130
+ const savedAgent = localStorage.getItem('gmgui-selectedAgent');
131
+ if (savedAgent && this.agents.has(savedAgent)) {
132
+ this.selectedAgent = savedAgent;
133
+ console.log('[DEBUG] Init: Restored selected agent from localStorage:', savedAgent);
134
+ } else if (this.agents.size > 0) {
135
+ this.selectedAgent = Array.from(this.agents.keys())[0];
136
+ localStorage.setItem('gmgui-selectedAgent', this.selectedAgent);
137
+ console.log('[DEBUG] Init: Pre-selected first available agent:', this.selectedAgent);
138
+ }
139
+
128
140
  await this.autoImportClaudeCode();
129
141
  console.log('[DEBUG] Init: Auto-imported Claude Code conversations');
130
142
  await this.fetchConversations();
@@ -1057,7 +1069,17 @@ class GMGUIApp {
1057
1069
  // Fallback for non-string, non-object content
1058
1070
  const bubble = document.createElement('div');
1059
1071
  bubble.className = 'message-bubble';
1060
- bubble.textContent = JSON.stringify(msg.content);
1072
+ // Handle all object types: convert to string safely
1073
+ if (typeof msg.content === 'object' && msg.content !== null) {
1074
+ try {
1075
+ bubble.textContent = JSON.stringify(msg.content, null, 2);
1076
+ } catch (e) {
1077
+ // If stringify fails (circular ref, etc), use toString
1078
+ bubble.textContent = String(msg.content);
1079
+ }
1080
+ } else {
1081
+ bubble.textContent = String(msg.content);
1082
+ }
1061
1083
  el.appendChild(bubble);
1062
1084
  }
1063
1085