agentgui 1.0.471 → 1.0.472
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/CLAUDE.md +11 -0
- package/lib/tool-manager.js +18 -4
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -83,6 +83,17 @@ All routes are prefixed with `BASE_URL` (default `/gm`).
|
|
|
83
83
|
- `POST /api/tts` - Text-to-speech (body: text)
|
|
84
84
|
- `GET /api/speech-status` - Speech model loading status
|
|
85
85
|
- `POST /api/folders` - Create folder
|
|
86
|
+
- `GET /api/tools` - List detected tools with installation status (via WebSocket tools.list handler)
|
|
87
|
+
|
|
88
|
+
## Tool Detection System
|
|
89
|
+
|
|
90
|
+
The system auto-detects installed AI coding tools via `bunx` package resolution:
|
|
91
|
+
- **OpenCode**: `opencode-ai` package (id: gm-oc)
|
|
92
|
+
- **Gemini CLI**: `@google/gemini-cli` package (id: gm-gc)
|
|
93
|
+
- **Kilo**: `@kilocode/cli` package (id: gm-kilo)
|
|
94
|
+
- **Claude Code**: `@anthropic-ai/claude-code` package (id: gm-cc)
|
|
95
|
+
|
|
96
|
+
Tool package names are configured in `lib/tool-manager.js` TOOLS array (lines 6-11). Detection happens by spawning `bunx <package> --version` to check if tools are installed. Response from `/api/tools` includes: id, name, pkg, installed, status (one of: installed|needs_update|not_installed), isUpToDate, upgradeNeeded, hasUpdate. Frontend displays tools in UI and updates based on installation status.
|
|
86
97
|
|
|
87
98
|
## WebSocket Protocol
|
|
88
99
|
|
package/lib/tool-manager.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { spawn } from 'child_process';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import os from 'os';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
4
6
|
|
|
5
7
|
const isWindows = os.platform() === 'win32';
|
|
6
8
|
const TOOLS = [
|
|
@@ -15,6 +17,16 @@ const installLocks = new Map();
|
|
|
15
17
|
|
|
16
18
|
const getTool = (id) => TOOLS.find(t => t.id === id);
|
|
17
19
|
|
|
20
|
+
const checkToolInstalled = (pkg) => {
|
|
21
|
+
try {
|
|
22
|
+
const __dirname = path.dirname(new URL(import.meta.url).pathname);
|
|
23
|
+
const nodeModulesPath = path.join(__dirname, '..', 'node_modules', pkg);
|
|
24
|
+
return fs.existsSync(nodeModulesPath);
|
|
25
|
+
} catch (_) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
18
30
|
const checkToolViaBunx = async (pkg) => {
|
|
19
31
|
try {
|
|
20
32
|
const cmd = isWindows ? 'bunx.cmd' : 'bunx';
|
|
@@ -29,23 +41,25 @@ const checkToolViaBunx = async (pkg) => {
|
|
|
29
41
|
proc.stderr.on('data', (d) => { stderr += d.toString(); });
|
|
30
42
|
const timer = setTimeout(() => {
|
|
31
43
|
try { proc.kill('SIGKILL'); } catch (_) {}
|
|
32
|
-
|
|
44
|
+
const installed = checkToolInstalled(pkg);
|
|
45
|
+
resolve({ installed, isUpToDate: false, upgradeNeeded: false, output: 'timeout' });
|
|
33
46
|
}, 10000);
|
|
34
47
|
proc.on('close', (code) => {
|
|
35
48
|
clearTimeout(timer);
|
|
36
49
|
const output = stdout + stderr;
|
|
37
|
-
const installed =
|
|
50
|
+
const installed = code === 0 || checkToolInstalled(pkg);
|
|
38
51
|
const upgradeNeeded = output.includes('Upgrading') || output.includes('upgrade');
|
|
39
52
|
const isUpToDate = installed && !upgradeNeeded;
|
|
40
53
|
resolve({ installed, isUpToDate, upgradeNeeded, output });
|
|
41
54
|
});
|
|
42
55
|
proc.on('error', () => {
|
|
43
56
|
clearTimeout(timer);
|
|
44
|
-
|
|
57
|
+
const installed = checkToolInstalled(pkg);
|
|
58
|
+
resolve({ installed, isUpToDate: false, upgradeNeeded: false, output: '' });
|
|
45
59
|
});
|
|
46
60
|
});
|
|
47
61
|
} catch (_) {
|
|
48
|
-
return { installed:
|
|
62
|
+
return { installed: checkToolInstalled(pkg), isUpToDate: false, upgradeNeeded: false, output: '' };
|
|
49
63
|
}
|
|
50
64
|
};
|
|
51
65
|
|