agentgui 1.0.275 → 1.0.277

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/agentgui.ico ADDED
Binary file
package/build-portable.js CHANGED
@@ -50,8 +50,18 @@ rmrf(out);
50
50
  fs.mkdirSync(out, { recursive: true });
51
51
 
52
52
  log('Compiling Windows executable...');
53
+ const onWindows = process.platform === 'win32';
54
+ const icoPath = path.join(src, 'agentgui.ico');
55
+ const winFlags = onWindows ? [
56
+ '--windows-hide-console',
57
+ '--windows-title=AgentGUI',
58
+ '--windows-description=Multi-agent GUI client for AI coding agents',
59
+ '--windows-version=1.0.0.0',
60
+ ...(fs.existsSync(icoPath) ? [`--windows-icon=${icoPath}`] : []),
61
+ ] : [];
53
62
  execSync(
54
- `~/.bun/bin/bun build --compile --target=bun-windows-x64 --outfile=${path.join(out, 'agentgui.exe')} ${path.join(src, 'portable-entry.js')}`,
63
+ [`~/.bun/bin/bun build --compile --target=bun-windows-x64`, ...winFlags,
64
+ `--outfile=${path.join(out, 'agentgui.exe')}`, path.join(src, 'portable-entry.js')].join(' '),
55
65
  { stdio: 'inherit', cwd: src }
56
66
  );
57
67
 
@@ -19,7 +19,7 @@ const CONFIG = {
19
19
  TIMEOUT_MS: 30000,
20
20
  INITIAL_BACKOFF_MS: 1000,
21
21
  BACKOFF_MULTIPLIER: 2,
22
- DOWNLOADS_DIR: path.join(os.homedir(), '.gmgui', 'downloads'),
22
+ get DOWNLOADS_DIR() { return path.join(process.env.PORTABLE_DATA_DIR || path.join(os.homedir(), '.gmgui'), 'downloads'); },
23
23
  RESUME_THRESHOLD: 0.5
24
24
  };
25
25
 
package/lib/speech.js CHANGED
@@ -78,12 +78,19 @@ function synthesizeDirect(text, voiceId) {
78
78
  });
79
79
  }
80
80
 
81
+ function getSttOptions() {
82
+ if (process.env.PORTABLE_DATA_DIR) {
83
+ return { cacheDir: path.join(process.env.PORTABLE_DATA_DIR, 'models') };
84
+ }
85
+ return {};
86
+ }
87
+
81
88
  function transcribe(audioBuffer) {
82
- return serverSTT.transcribe(audioBuffer);
89
+ return serverSTT.transcribe(audioBuffer, getSttOptions());
83
90
  }
84
91
 
85
92
  function getSTT() {
86
- return serverSTT.getSTT();
93
+ return serverSTT.getSTT(getSttOptions());
87
94
  }
88
95
 
89
96
  function synthesize(text, voiceId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentgui",
3
- "version": "1.0.275",
3
+ "version": "1.0.277",
4
4
  "description": "Multi-agent ACP client with real-time communication",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -8,6 +8,9 @@ import { fileURLToPath } from 'url';
8
8
  import { WebSocketServer } from 'ws';
9
9
  import { execSync, spawn } from 'child_process';
10
10
  import { createRequire } from 'module';
11
+ import express from 'express';
12
+ import Busboy from 'busboy';
13
+ import fsbrowse from 'fsbrowse';
11
14
  import { OAuth2Client } from 'google-auth-library';
12
15
  import { queries, dataDir } from './database.js';
13
16
  import { runClaudeWithStreaming } from './lib/claude-runner.js';
@@ -69,12 +72,9 @@ async function ensureModelsDownloaded() {
69
72
  }
70
73
 
71
74
  try {
72
- const { createRequire: cr } = await import('module');
73
- const r = cr(import.meta.url);
74
-
75
- const gmguiModels = path.join(dataDir, 'models');
76
- const sttDir = path.join(gmguiModels, 'onnx-community', 'whisper-base');
77
- const ttsDir = path.join(gmguiModels, 'tts');
75
+ const gmguiModels = path.join(dataDir, 'models');
76
+ const sttDir = path.join(gmguiModels, 'onnx-community', 'whisper-base');
77
+ const ttsDir = path.join(gmguiModels, 'tts');
78
78
 
79
79
  const sttOk = fs.existsSync(sttDir) && fs.readdirSync(sttDir).length > 0;
80
80
  const ttsOk = fs.existsSync(ttsDir) && fs.readdirSync(ttsDir).length > 0;
@@ -276,10 +276,6 @@ function pushTTSAudio(cacheKey, wav, conversationId, sessionId, voiceId) {
276
276
  });
277
277
  }
278
278
 
279
- const require = createRequire(import.meta.url);
280
- const express = require('express');
281
- const Busboy = require('busboy');
282
- const fsbrowse = require('fsbrowse');
283
279
 
284
280
  const SYSTEM_PROMPT = `Your output will be spoken aloud by a text-to-speech system. Write ONLY plain conversational sentences that sound natural when read aloud. Never use markdown, bold, italics, headers, bullet points, numbered lists, tables, or any formatting. Never use colons to introduce lists or options. Never use labels like "Option A" or "1." followed by a title. Instead of listing options, describe them conversationally in flowing sentences. For example, instead of "**Option 1**: Do X" say "One approach would be to do X." Keep sentences short and simple. Use transition words like "also", "another option", "or alternatively" to connect ideas. When mentioning file names, spell out the dot between the name and extension as the word "dot" so it is spoken clearly. For example, say "server dot js" instead of "server.js", "index dot html" instead of "index.html", and "package dot json" instead of "package.json". Write as if you are speaking to someone in a casual conversation.`;
285
281
 
@@ -296,16 +292,16 @@ const debugLog = (msg) => {
296
292
  console.error(`[${timestamp}] ${msg}`);
297
293
  };
298
294
 
299
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
300
- const PORT = process.env.PORT || 3000;
301
- const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
302
- const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
303
-
304
- const STARTUP_CWD = process.env.STARTUP_CWD || process.cwd();
305
- const staticDir = process.env.PORTABLE_EXE_DIR
306
- ? path.join(process.env.PORTABLE_EXE_DIR, 'static')
307
- : path.join(__dirname, 'static');
308
- if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
295
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
296
+ const PORT = process.env.PORT || 3000;
297
+ const BASE_URL = (process.env.BASE_URL || '/gm').replace(/\/+$/, '');
298
+ const watch = process.argv.includes('--no-watch') ? false : (process.argv.includes('--watch') || process.env.HOT_RELOAD !== 'false');
299
+
300
+ const STARTUP_CWD = process.env.STARTUP_CWD || process.cwd();
301
+ const staticDir = process.env.PORTABLE_EXE_DIR
302
+ ? path.join(process.env.PORTABLE_EXE_DIR, 'static')
303
+ : path.join(__dirname, 'static');
304
+ if (!fs.existsSync(staticDir)) fs.mkdirSync(staticDir, { recursive: true });
309
305
 
310
306
  // Express sub-app for fsbrowse file browser and file upload
311
307
  const expressApp = express();
@@ -3697,21 +3693,21 @@ function onServerReady() {
3697
3693
 
3698
3694
  resumeInterruptedStreams().catch(err => console.error('[RESUME] Startup error:', err.message));
3699
3695
 
3700
- ensureModelsDownloaded().then(ok => {
3696
+ ensureModelsDownloaded().then(async ok => {
3701
3697
  if (ok) console.log('[MODELS] Speech models ready');
3702
3698
  else console.log('[MODELS] Speech model download failed');
3703
3699
  try {
3704
- const { getVoices } = require('./lib/speech.js');
3700
+ const { getVoices } = await getSpeech();
3705
3701
  const voices = getVoices();
3706
3702
  broadcastSync({ type: 'voice_list', voices });
3707
3703
  } catch (err) {
3708
3704
  debugLog('[VOICE] Failed to broadcast voices: ' + err.message);
3709
3705
  broadcastSync({ type: 'voice_list', voices: [] });
3710
3706
  }
3711
- }).catch(err => {
3707
+ }).catch(async err => {
3712
3708
  console.error('[MODELS] Download error:', err.message);
3713
3709
  try {
3714
- const { getVoices } = require('./lib/speech.js');
3710
+ const { getVoices } = await getSpeech();
3715
3711
  const voices = getVoices();
3716
3712
  broadcastSync({ type: 'voice_list', voices });
3717
3713
  } catch (err2) {