agentgui 1.0.232 → 1.0.233

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.232",
3
+ "version": "1.0.233",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -1757,6 +1757,30 @@ const server = http.createServer(async (req, res) => {
1757
1757
  return;
1758
1758
  }
1759
1759
 
1760
+ if (pathOnly === '/api/git/check-remote-ownership' && req.method === 'GET') {
1761
+ try {
1762
+ const result = execSync('git remote get-url origin 2>/dev/null', { encoding: 'utf-8', cwd: STARTUP_CWD });
1763
+ const remoteUrl = result.trim();
1764
+ const statusResult = execSync('git status --porcelain', { encoding: 'utf-8', cwd: STARTUP_CWD });
1765
+ const hasChanges = statusResult.trim().length > 0;
1766
+ const ownsRemote = !remoteUrl.includes('github.com/') || remoteUrl.includes(process.env.GITHUB_USER || '');
1767
+ sendJSON(req, res, 200, { ownsRemote, hasChanges, remoteUrl });
1768
+ } catch {
1769
+ sendJSON(req, res, 200, { ownsRemote: false, hasChanges: false, remoteUrl: '' });
1770
+ }
1771
+ return;
1772
+ }
1773
+
1774
+ if (pathOnly === '/api/git/push' && req.method === 'POST') {
1775
+ try {
1776
+ execSync('git add -A && git commit -m "Auto-commit" && git push', { encoding: 'utf-8', cwd: STARTUP_CWD });
1777
+ sendJSON(req, res, 200, { success: true });
1778
+ } catch (err) {
1779
+ sendJSON(req, res, 500, { error: err.message });
1780
+ }
1781
+ return;
1782
+ }
1783
+
1760
1784
  if (routePath.startsWith('/api/image/')) {
1761
1785
  const imagePath = routePath.slice('/api/image/'.length);
1762
1786
  const decodedPath = decodeURIComponent(imagePath);
@@ -2085,6 +2109,7 @@ async function processMessageWithStreaming(conversationId, messageId, sessionId,
2085
2109
  type: 'streaming_complete',
2086
2110
  sessionId,
2087
2111
  conversationId,
2112
+ agentId,
2088
2113
  eventCount,
2089
2114
  seq: currentSequence,
2090
2115
  timestamp: Date.now()
@@ -764,7 +764,6 @@ class AgentGUIClient {
764
764
 
765
765
  this.state.streamingConversations.delete(conversationId);
766
766
 
767
- // Stop polling for chunks
768
767
  this.stopChunkPolling();
769
768
 
770
769
  const sessionId = data.sessionId || this.state.currentSession?.id;
@@ -782,13 +781,36 @@ class AgentGUIClient {
782
781
  streamingEl.appendChild(ts);
783
782
  }
784
783
 
785
- // Save scroll position after streaming completes
786
784
  if (conversationId) {
787
785
  this.saveScrollPosition(conversationId);
788
786
  }
789
787
 
790
788
  this.enableControls();
791
789
  this.emit('streaming:complete', data);
790
+
791
+ if (data.agentId && this._isACPAgent(data.agentId)) {
792
+ this._promptPushIfWeOwnRemote();
793
+ }
794
+ }
795
+
796
+ _isACPAgent(agentId) {
797
+ const acpAgents = ['opencode', 'gemini', 'goose', 'openhands', 'augment', 'cline', 'kimi', 'qwen', 'codex', 'mistral', 'kiro', 'fast-agent'];
798
+ return acpAgents.includes(agentId);
799
+ }
800
+
801
+ async _promptPushIfWeOwnRemote() {
802
+ try {
803
+ const result = await fetch(window.__BASE_URL + '/api/git/check-remote-ownership');
804
+ const { ownsRemote, hasChanges, remoteUrl } = await result.json();
805
+ if (ownsRemote && hasChanges) {
806
+ const shouldPush = confirm('Push changes to remote?');
807
+ if (shouldPush) {
808
+ await fetch(window.__BASE_URL + '/api/git/push', { method: 'POST' });
809
+ }
810
+ }
811
+ } catch (e) {
812
+ console.warn('Failed to check git remote ownership:', e);
813
+ }
792
814
  }
793
815
 
794
816
  /**
@@ -796,6 +818,9 @@ class AgentGUIClient {
796
818
  */
797
819
  handleConversationCreated(data) {
798
820
  if (data.conversation) {
821
+ if (this.state.conversations.some(c => c.id === data.conversation.id)) {
822
+ return;
823
+ }
799
824
  this.state.conversations.push(data.conversation);
800
825
  this.emit('conversation:created', data.conversation);
801
826
  }
@@ -1478,7 +1503,6 @@ class AgentGUIClient {
1478
1503
  }
1479
1504
 
1480
1505
  this._lastSendTime = Date.now();
1481
- this._startThinkingCountdown();
1482
1506
  this.emit('execution:started', result);
1483
1507
  } catch (error) {
1484
1508
  console.error('Stream execution error:', error);
@@ -1967,14 +1991,12 @@ class AgentGUIClient {
1967
1991
  * Disable UI controls during streaming
1968
1992
  */
1969
1993
  disableControls() {
1970
- if (this.ui.sendButton) this.ui.sendButton.disabled = true;
1971
1994
  }
1972
1995
 
1973
1996
  /**
1974
1997
  * Enable UI controls
1975
1998
  */
1976
1999
  enableControls() {
1977
- if (this.ui.sendButton) this.ui.sendButton.disabled = false;
1978
2000
  }
1979
2001
 
1980
2002
  /**
@@ -502,6 +502,9 @@ class ConversationManager {
502
502
  }
503
503
 
504
504
  addConversation(conv) {
505
+ if (this.conversations.some(c => c.id === conv.id)) {
506
+ return;
507
+ }
505
508
  this.conversations.unshift(conv);
506
509
  this.render();
507
510
  }