agent-window 1.1.5 → 1.2.1
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/bin/cli.js +45 -45
- package/docker-compose.yml +5 -5
- package/ecosystem.config.cjs +4 -4
- package/package.json +1 -1
- package/scripts/diagnose-instances.js +152 -0
- package/scripts/final-test.sh +136 -0
- package/scripts/fix-agentbridge-instance.js +89 -0
- package/scripts/import-instances.js +55 -0
- package/scripts/test-api-endpoints.js +39 -0
- package/scripts/test-discovery.js +95 -0
- package/scripts/test-instance-type.js +85 -0
- package/scripts/test-pm2-data.js +54 -0
- package/src/api/routes/instances.js +3 -30
- package/src/core/instance/manager.js +30 -3
- package/web/dist/assets/Dashboard-BTrinn8p.js +1 -0
- package/web/dist/assets/{Dashboard-CJDMEpOk.css → Dashboard-BicWOr3D.css} +1 -1
- package/web/dist/assets/{InstanceDetail-E-9-YoyH.css → InstanceDetail-B2M2l7Dy.css} +1 -1
- package/web/dist/assets/InstanceDetail-DAERYy59.js +3 -0
- package/web/dist/assets/{Instances-DFQOoLYE.js → Instances-VQZar42B.js} +1 -1
- package/web/dist/assets/{Settings-DUvrHXXe.js → Settings-BCwW_7gk.js} +1 -1
- package/web/dist/assets/{main-CICHNbG_.js → main-BGxPBmf2.js} +2 -2
- package/web/dist/index.html +1 -1
- package/web/dist/assets/Dashboard-CK9p-dpz.js +0 -1
- package/web/dist/assets/InstanceDetail-txSTEfck.js +0 -3
package/bin/cli.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* AgentWindow - Command Line Interface
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* A window to interact with AI agents through chat interfaces
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
|
-
* agent-
|
|
10
|
-
* agent-
|
|
11
|
-
* agent-
|
|
12
|
-
* agent-
|
|
13
|
-
* agent-
|
|
14
|
-
* agent-
|
|
15
|
-
* agent-
|
|
16
|
-
* agent-
|
|
9
|
+
* agent-window setup - Interactive setup wizard
|
|
10
|
+
* agent-window start - Start the service
|
|
11
|
+
* agent-window stop - Stop the service
|
|
12
|
+
* agent-window restart - Restart the service
|
|
13
|
+
* agent-window status - Check status
|
|
14
|
+
* agent-window logs - View logs
|
|
15
|
+
* agent-window update - Update to latest version
|
|
16
|
+
* agent-window config - Show config location
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
import { spawn, execSync } from 'child_process';
|
|
@@ -27,7 +27,7 @@ const PROJECT_ROOT = join(__dirname, '..');
|
|
|
27
27
|
const CONFIG_DIR = join(PROJECT_ROOT, 'config');
|
|
28
28
|
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
29
29
|
const CONFIG_EXAMPLE = join(CONFIG_DIR, 'config.example.json');
|
|
30
|
-
const PM2_NAME = 'agent-
|
|
30
|
+
const PM2_NAME = 'agent-window';
|
|
31
31
|
|
|
32
32
|
// Colors for terminal output
|
|
33
33
|
const colors = {
|
|
@@ -182,7 +182,7 @@ async function verifyDiscordToken(token) {
|
|
|
182
182
|
function testDockerMount(testPath) {
|
|
183
183
|
log('\n🔍 Testing Docker file sharing...', colors.cyan);
|
|
184
184
|
try {
|
|
185
|
-
const testContainer = 'agent-
|
|
185
|
+
const testContainer = 'agent-window-mount-test';
|
|
186
186
|
// Remove any old test container
|
|
187
187
|
execSync(`docker rm -f ${testContainer} 2>/dev/null`, { stdio: 'ignore' });
|
|
188
188
|
|
|
@@ -203,7 +203,7 @@ function testDockerMount(testPath) {
|
|
|
203
203
|
log(`3. Add: ${testPath}`);
|
|
204
204
|
log('4. Click "Apply & Restart"');
|
|
205
205
|
log('\nAlternative: Install to user directory instead of global:');
|
|
206
|
-
log(' mkdir -p ~/agent-
|
|
206
|
+
log(' mkdir -p ~/agent-window && cd ~/agent-window && npm install agent-window\n');
|
|
207
207
|
return false;
|
|
208
208
|
}
|
|
209
209
|
}
|
|
@@ -305,7 +305,7 @@ async function setup() {
|
|
|
305
305
|
const discordValid = await verifyDiscordToken(config.BOT_TOKEN);
|
|
306
306
|
if (!discordValid) {
|
|
307
307
|
logError('\n❌ Setup failed: Discord configuration invalid');
|
|
308
|
-
logInfo('Fix the issues above and run: agent-
|
|
308
|
+
logInfo('Fix the issues above and run: agent-window setup');
|
|
309
309
|
process.exit(1);
|
|
310
310
|
}
|
|
311
311
|
}
|
|
@@ -319,7 +319,7 @@ async function setup() {
|
|
|
319
319
|
const mountOk = testDockerMount(PROJECT_ROOT);
|
|
320
320
|
if (!mountOk) {
|
|
321
321
|
logError('\n❌ Setup failed: Docker file sharing not configured');
|
|
322
|
-
logInfo('Fix the issues above and run: agent-
|
|
322
|
+
logInfo('Fix the issues above and run: agent-window setup');
|
|
323
323
|
process.exit(1);
|
|
324
324
|
}
|
|
325
325
|
|
|
@@ -359,13 +359,13 @@ async function setup() {
|
|
|
359
359
|
|
|
360
360
|
log('\n✨ Setup complete!\n', colors.green + colors.bright);
|
|
361
361
|
log('Start the bridge with:', colors.cyan);
|
|
362
|
-
log(' agent-
|
|
362
|
+
log(' agent-window start\n');
|
|
363
363
|
}
|
|
364
364
|
|
|
365
365
|
// Start
|
|
366
366
|
function start() {
|
|
367
367
|
if (!existsSync(CONFIG_FILE)) {
|
|
368
|
-
logError('Configuration not found. Run "agent-
|
|
368
|
+
logError('Configuration not found. Run "agent-window setup" first.');
|
|
369
369
|
process.exit(1);
|
|
370
370
|
}
|
|
371
371
|
|
|
@@ -376,7 +376,7 @@ function start() {
|
|
|
376
376
|
stdio: 'inherit'
|
|
377
377
|
});
|
|
378
378
|
logSuccess('AgentBridge started');
|
|
379
|
-
log('\nView logs: agent-
|
|
379
|
+
log('\nView logs: agent-window logs', colors.dim);
|
|
380
380
|
} catch (e) {
|
|
381
381
|
logError('Failed to start: ' + e.message);
|
|
382
382
|
}
|
|
@@ -464,7 +464,7 @@ async function update() {
|
|
|
464
464
|
logSuccess('Update complete');
|
|
465
465
|
} else {
|
|
466
466
|
log('Updating via npm...', colors.cyan);
|
|
467
|
-
execSync('npm update -g agent-
|
|
467
|
+
execSync('npm update -g agent-window', { stdio: 'inherit' });
|
|
468
468
|
logSuccess('Update complete. Please restart.');
|
|
469
469
|
}
|
|
470
470
|
} catch (e) {
|
|
@@ -481,7 +481,7 @@ function showConfig() {
|
|
|
481
481
|
if (existsSync(CONFIG_FILE)) {
|
|
482
482
|
logSuccess('Config exists');
|
|
483
483
|
} else {
|
|
484
|
-
logWarning('Config not found. Run "agent-
|
|
484
|
+
logWarning('Config not found. Run "agent-window setup"');
|
|
485
485
|
}
|
|
486
486
|
}
|
|
487
487
|
|
|
@@ -496,20 +496,20 @@ async function initBotsDir() {
|
|
|
496
496
|
const botsDir = await prompt('Bots directory (press Enter for default): ') || defaultBotsDir;
|
|
497
497
|
|
|
498
498
|
// Create directory structure
|
|
499
|
-
const botTypesDir = join(botsDir, 'agent-
|
|
499
|
+
const botTypesDir = join(botsDir, 'agent-window@latest');
|
|
500
500
|
try {
|
|
501
501
|
execSync(`mkdir -p "${botTypesDir}"`, { stdio: 'inherit' });
|
|
502
502
|
} catch {
|
|
503
503
|
// Directory already exists or was created
|
|
504
504
|
}
|
|
505
505
|
|
|
506
|
-
// Create symlink to global agent-
|
|
507
|
-
const
|
|
508
|
-
if (existsSync(
|
|
509
|
-
const linkPath = join(botsDir, 'agent-
|
|
506
|
+
// Create symlink to global agent-window
|
|
507
|
+
const globalAgentWindow = '/opt/homebrew/lib/node_modules/agent-window';
|
|
508
|
+
if (existsSync(globalAgentWindow)) {
|
|
509
|
+
const linkPath = join(botsDir, 'agent-window');
|
|
510
510
|
try {
|
|
511
|
-
execSync(`ln -sf "${
|
|
512
|
-
logSuccess('Linked to global agent-
|
|
511
|
+
execSync(`ln -sf "${globalAgentWindow}" "${linkPath}"`, { stdio: 'inherit' });
|
|
512
|
+
logSuccess('Linked to global agent-window installation');
|
|
513
513
|
} catch {
|
|
514
514
|
logWarning('Could not create symlink (may already exist)');
|
|
515
515
|
}
|
|
@@ -519,12 +519,12 @@ async function initBotsDir() {
|
|
|
519
519
|
const ecosystemFile = join(botsDir, 'ecosystem.config.cjs');
|
|
520
520
|
if (!existsSync(ecosystemFile)) {
|
|
521
521
|
const ecosystemTemplate = `/**
|
|
522
|
-
*
|
|
522
|
+
* AgentWindow - Multi-Bot Management
|
|
523
523
|
*
|
|
524
|
-
* Add new bots with: agent-
|
|
524
|
+
* Add new bots with: agent-window add-bot <name>
|
|
525
525
|
*/
|
|
526
526
|
|
|
527
|
-
const
|
|
527
|
+
const AGENT_WINDOW = '${globalAgentWindow}';
|
|
528
528
|
const BOTS_DIR = '${botsDir}';
|
|
529
529
|
|
|
530
530
|
module.exports = {
|
|
@@ -551,7 +551,7 @@ module.exports = {
|
|
|
551
551
|
log('\n✨ Multi-bot directory initialized!\n', colors.green + colors.bright);
|
|
552
552
|
log('Next steps:', colors.cyan);
|
|
553
553
|
log(` cd ${botsDir}`);
|
|
554
|
-
log(' agent-
|
|
554
|
+
log(' agent-window add-bot <name> # Add a new bot');
|
|
555
555
|
log(' pm2 start ecosystem.config.cjs # Start all bots\n');
|
|
556
556
|
}
|
|
557
557
|
|
|
@@ -559,8 +559,8 @@ module.exports = {
|
|
|
559
559
|
async function addBot() {
|
|
560
560
|
const botName = process.argv[3];
|
|
561
561
|
if (!botName) {
|
|
562
|
-
logError('Usage: agent-
|
|
563
|
-
logInfo('Example: agent-
|
|
562
|
+
logError('Usage: agent-window add-bot <name>');
|
|
563
|
+
logInfo('Example: agent-window add-bot myproject');
|
|
564
564
|
process.exit(1);
|
|
565
565
|
}
|
|
566
566
|
|
|
@@ -570,7 +570,7 @@ async function addBot() {
|
|
|
570
570
|
|
|
571
571
|
if (!botsDir || !existsSync(join(botsDir, 'ecosystem.config.cjs'))) {
|
|
572
572
|
logError('Bots directory not initialized.');
|
|
573
|
-
logInfo('Run: agent-
|
|
573
|
+
logInfo('Run: agent-window init');
|
|
574
574
|
process.exit(1);
|
|
575
575
|
}
|
|
576
576
|
|
|
@@ -631,8 +631,8 @@ async function addBot() {
|
|
|
631
631
|
const newApp = `,
|
|
632
632
|
{
|
|
633
633
|
name: 'bot-` + botName + `',
|
|
634
|
-
script: process.env.
|
|
635
|
-
cwd: process.env.
|
|
634
|
+
script: process.env.GLOBAL_AGENT_WINDOW || '/opt/homebrew/lib/node_modules/agent-window/src/bot.js',
|
|
635
|
+
cwd: process.env.GLOBAL_AGENT_WINDOW ? process.env.GLOBAL_AGENT_WINDOW : '/opt/homebrew/lib/node_modules/agent-window',
|
|
636
636
|
env: {
|
|
637
637
|
CONFIG_PATH: '` + botsDir + '/' + botName + `/config.json'
|
|
638
638
|
},
|
|
@@ -704,13 +704,13 @@ async function ui() {
|
|
|
704
704
|
function showHelp() {
|
|
705
705
|
showBanner();
|
|
706
706
|
log(`${colors.cyan}Usage:${colors.reset}
|
|
707
|
-
agent-
|
|
707
|
+
agent-window <command>
|
|
708
708
|
|
|
709
709
|
${colors.cyan}Single-Bot Commands:${colors.reset}
|
|
710
710
|
setup Interactive setup wizard
|
|
711
|
-
start Start the
|
|
712
|
-
stop Stop the
|
|
713
|
-
restart Restart the
|
|
711
|
+
start Start the service
|
|
712
|
+
stop Stop the service
|
|
713
|
+
restart Restart the service
|
|
714
714
|
status Show status
|
|
715
715
|
logs View logs (live)
|
|
716
716
|
update Update to latest version
|
|
@@ -727,14 +727,14 @@ ${colors.cyan}General:${colors.reset}
|
|
|
727
727
|
help Show this help
|
|
728
728
|
|
|
729
729
|
${colors.cyan}Examples:${colors.reset}
|
|
730
|
-
agent-
|
|
731
|
-
agent-
|
|
732
|
-
agent-
|
|
733
|
-
agent-
|
|
730
|
+
agent-window setup ${colors.dim}# First time setup${colors.reset}
|
|
731
|
+
agent-window init ${colors.dim}# Initialize ~/bots directory${colors.reset}
|
|
732
|
+
agent-window add-bot myproject ${colors.dim}# Add a new bot${colors.reset}
|
|
733
|
+
agent-window ui ${colors.dim}# Launch web UI${colors.reset}
|
|
734
734
|
pm2 start ~/bots/ecosystem.config.cjs ${colors.dim}# Start all bots${colors.reset}
|
|
735
735
|
|
|
736
736
|
${colors.cyan}Documentation:${colors.reset}
|
|
737
|
-
https://github.com/
|
|
737
|
+
https://github.com/Observer-GGboy/AgentWindow
|
|
738
738
|
`);
|
|
739
739
|
}
|
|
740
740
|
|
package/docker-compose.yml
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AgentWindow - Docker Compose
|
|
2
2
|
#
|
|
3
3
|
# Usage:
|
|
4
4
|
# docker-compose up -d # Start in background
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
version: '3.8'
|
|
9
9
|
|
|
10
10
|
services:
|
|
11
|
-
agent-
|
|
11
|
+
agent-window:
|
|
12
12
|
build:
|
|
13
13
|
context: .
|
|
14
14
|
dockerfile: Dockerfile
|
|
15
|
-
container_name: agent-
|
|
15
|
+
container_name: agent-window
|
|
16
16
|
restart: unless-stopped
|
|
17
17
|
volumes:
|
|
18
18
|
- ./config/config.json:/app/config/config.json:ro
|
|
@@ -24,8 +24,8 @@ services:
|
|
|
24
24
|
environment:
|
|
25
25
|
- NODE_ENV=production
|
|
26
26
|
networks:
|
|
27
|
-
- agent-
|
|
27
|
+
- agent-window-network
|
|
28
28
|
|
|
29
29
|
networks:
|
|
30
|
-
agent-
|
|
30
|
+
agent-window-network:
|
|
31
31
|
driver: bridge
|
package/ecosystem.config.cjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PM2 Ecosystem Configuration for
|
|
2
|
+
* PM2 Ecosystem Configuration for AgentWindow
|
|
3
3
|
*
|
|
4
4
|
* Start: pm2 start ecosystem.config.cjs
|
|
5
|
-
* Stop: pm2 stop agent-
|
|
6
|
-
* Logs: pm2 logs agent-
|
|
5
|
+
* Stop: pm2 stop agent-window
|
|
6
|
+
* Logs: pm2 logs agent-window
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
module.exports = {
|
|
10
10
|
apps: [{
|
|
11
|
-
name: 'agent-
|
|
11
|
+
name: 'agent-window',
|
|
12
12
|
script: 'src/bot.js',
|
|
13
13
|
watch: false,
|
|
14
14
|
autorestart: true,
|
package/package.json
CHANGED
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* 实例管理诊断脚本
|
|
4
|
+
*
|
|
5
|
+
* 用于诊断实例管理中的问题:
|
|
6
|
+
* 1. agentbridge 实例的配置路径错误
|
|
7
|
+
* 2. Edit Config 点击报错
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readInstances } from '../src/core/instance/manager.js';
|
|
11
|
+
import { getProcesses } from '../src/core/instance/pm2-bridge.js';
|
|
12
|
+
import { existsSync } from 'fs';
|
|
13
|
+
import { paths } from '../src/core/platform/index.js';
|
|
14
|
+
|
|
15
|
+
console.log('\n=== AgentWindow 实例管理诊断 ===\n');
|
|
16
|
+
|
|
17
|
+
// 1. 检查 instances.json 状态
|
|
18
|
+
console.log('1. instances.json 状态');
|
|
19
|
+
try {
|
|
20
|
+
const data = await readInstances();
|
|
21
|
+
console.log(` 总实例数: ${data.instances.length}`);
|
|
22
|
+
data.instances.forEach(inst => {
|
|
23
|
+
console.log(`\n 实例: ${inst.name}`);
|
|
24
|
+
console.log(` - displayName: ${inst.displayName}`);
|
|
25
|
+
console.log(` - botName: ${inst.botName}`);
|
|
26
|
+
console.log(` - projectPath: ${inst.projectPath}`);
|
|
27
|
+
console.log(` - configPath: ${inst.configPath || '未设置'}`);
|
|
28
|
+
console.log(` - pluginPath: ${inst.pluginPath || '未设置'}`);
|
|
29
|
+
console.log(` - instanceType: ${inst.instanceType}`);
|
|
30
|
+
console.log(` - enabled: ${inst.enabled}`);
|
|
31
|
+
});
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.log(` 读取失败: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 2. 检查 PM2 进程状态
|
|
37
|
+
console.log('\n2. PM2 进程状态');
|
|
38
|
+
try {
|
|
39
|
+
const processes = await getProcesses();
|
|
40
|
+
const botProcesses = processes.filter(p => p.name && p.name.startsWith('bot-'));
|
|
41
|
+
|
|
42
|
+
console.log(` 总 bot 进程数: ${botProcesses.length}`);
|
|
43
|
+
botProcesses.forEach(proc => {
|
|
44
|
+
console.log(`\n 进程: ${proc.name}`);
|
|
45
|
+
console.log(` - pid: ${proc.pid}`);
|
|
46
|
+
console.log(` - status: ${proc.status}`);
|
|
47
|
+
console.log(` - cwd: ${proc.cwd}`);
|
|
48
|
+
console.log(` - configPath (从 env): ${proc.configPath || '未设置'}`);
|
|
49
|
+
console.log(` - memory: ${(proc.memory / 1024 / 1024).toFixed(1)} MB`);
|
|
50
|
+
console.log(` - cpu: ${proc.cpu}%`);
|
|
51
|
+
|
|
52
|
+
// 检查环境变量
|
|
53
|
+
if (proc.env && proc.env.CONFIG_PATH) {
|
|
54
|
+
console.log(` - env.CONFIG_PATH: ${proc.env.CONFIG_PATH}`);
|
|
55
|
+
const configExists = existsSync(proc.env.CONFIG_PATH);
|
|
56
|
+
console.log(` - CONFIG_PATH 存在: ${configExists ? '是' : '否'}`);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
} catch (error) {
|
|
60
|
+
console.log(` 读取 PM2 失败: ${error.message}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 3. 检查 bots 目录
|
|
64
|
+
console.log('\n3. Bots 目录检查');
|
|
65
|
+
const botsDir = paths.getBotsDir();
|
|
66
|
+
console.log(` Bots Dir: ${botsDir}`);
|
|
67
|
+
|
|
68
|
+
// 4. 分析问题
|
|
69
|
+
console.log('\n4. 问题分析');
|
|
70
|
+
|
|
71
|
+
// 检查 agentbridge 实例
|
|
72
|
+
const data = await readInstances();
|
|
73
|
+
const agentbridge = data.instances.find(i => i.name === 'agentbridge');
|
|
74
|
+
|
|
75
|
+
if (agentbridge) {
|
|
76
|
+
console.log('\n 【问题 1】agentbridge 实例配置路径分析');
|
|
77
|
+
console.log(` 当前 configPath: ${agentbridge.configPath || '未设置'}`);
|
|
78
|
+
|
|
79
|
+
// 检查 PM2 进程
|
|
80
|
+
const processes = await getProcesses();
|
|
81
|
+
const proc = processes.find(p => p.name === 'bot-agentbridge');
|
|
82
|
+
|
|
83
|
+
if (proc) {
|
|
84
|
+
console.log(` PM2 进程 cwd: ${proc.cwd}`);
|
|
85
|
+
console.log(` PM2 env.CONFIG_PATH: ${proc.configPath || '未设置'}`);
|
|
86
|
+
|
|
87
|
+
// 分析期望的配置路径
|
|
88
|
+
const expectedConfigPath = `${botsDir}/agentbridge/config.json`;
|
|
89
|
+
console.log(`\n 期望配置路径: ${expectedConfigPath}`);
|
|
90
|
+
console.log(` 配置文件存在: ${existsSync(expectedConfigPath) ? '是' : '否'}`);
|
|
91
|
+
|
|
92
|
+
// 判断问题
|
|
93
|
+
if (!agentbridge.configPath || agentbridge.configPath.includes('agent-bridge-main/config')) {
|
|
94
|
+
console.log('\n ❌ 问题确认: configPath 指向项目内配置,而非 ~/bots/agentbridge/config.json');
|
|
95
|
+
console.log(' 原因: discoverInstances() 未能正确读取 CONFIG_PATH 环境变量');
|
|
96
|
+
} else {
|
|
97
|
+
console.log('\n ✓ configPath 设置正确');
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
console.log(' ⚠ 未找到 bot-agentbridge 进程');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// 检查 Edit Config 问题
|
|
105
|
+
console.log('\n 【问题 2】Edit Config 功能分析');
|
|
106
|
+
|
|
107
|
+
for (const inst of data.instances) {
|
|
108
|
+
console.log(`\n 实例: ${inst.name}`);
|
|
109
|
+
console.log(` - configPath: ${inst.configPath || '未设置'}`);
|
|
110
|
+
console.log(` - configPath 为 null: ${inst.configPath === null ? '是(会触发错误)' : '否'}`);
|
|
111
|
+
|
|
112
|
+
if (inst.configPath) {
|
|
113
|
+
const exists = existsSync(inst.configPath);
|
|
114
|
+
console.log(` - 配置文件存在: ${exists ? '是' : '否'}`);
|
|
115
|
+
|
|
116
|
+
if (!exists) {
|
|
117
|
+
console.log(` ⚠ 警告: configPath 指向的文件不存在`);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
console.log(` ❌ 问题: configPath 为 null,点击 Edit Config 会报错`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 5. 根本原因分析
|
|
125
|
+
console.log('\n5. 根本原因分析');
|
|
126
|
+
console.log('\n 问题 1 - agentbridge 配置路径错误:');
|
|
127
|
+
console.log(' - discoverInstances() 依赖 PM2 进程的 CONFIG_PATH 环境变量');
|
|
128
|
+
console.log(' - bot-agentbridge 进程没有设置 CONFIG_PATH 环境变量');
|
|
129
|
+
console.log(' - 导致 discoverInstances() 无法获取正确的配置路径');
|
|
130
|
+
console.log(' - 最后回退到使用 cwd 作为项目路径,但配置路径仍为 null');
|
|
131
|
+
|
|
132
|
+
console.log('\n 问题 2 - Edit Config 报错:');
|
|
133
|
+
console.log(' - 前端检查 instance.configPath 是否存在');
|
|
134
|
+
console.log(' - 如果 configPath 为 null,显示错误 "This instance does not have a config file"');
|
|
135
|
+
console.log(' - 这是因为 discoverInstances() 未能从 PM2 获取 CONFIG_PATH');
|
|
136
|
+
|
|
137
|
+
// 6. 解决方案
|
|
138
|
+
console.log('\n6. 建议解决方案');
|
|
139
|
+
console.log('\n 方案 A: 为 bot-agentbridge 设置 CONFIG_PATH 环境变量');
|
|
140
|
+
console.log(` pm2 restart bot-agentbridge --env CONFIG_PATH=/Users/cyrus/bots/agentbridge/config.json`);
|
|
141
|
+
|
|
142
|
+
console.log('\n 方案 B: 修改 discoverInstances() 逻辑');
|
|
143
|
+
console.log(' - 在 discoverInstances() 中,按实例名推断配置路径');
|
|
144
|
+
console.log(` - 如果实例名为 "agentbridge",自动推断 configPath 为 ~/bots/agentbridge/config.json`);
|
|
145
|
+
console.log(' - 优先级: CONFIG_PATH > 推断路径 > null');
|
|
146
|
+
|
|
147
|
+
console.log('\n 方案 C: 创建 ~/bots/agentbridge/ 目录并设置配置');
|
|
148
|
+
console.log(' mkdir -p ~/bots/agentbridge');
|
|
149
|
+
console.log(' cp config/config.json ~/bots/agentbridge/');
|
|
150
|
+
console.log(' pm2 restart bot-agentbridge --env CONFIG_PATH=~/bots/agentbridge/config.json');
|
|
151
|
+
|
|
152
|
+
console.log('\n=== 诊断完成 ===\n');
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "=== AgentWindow 实例类型显示问题 - 最终验证测试 ==="
|
|
4
|
+
echo ""
|
|
5
|
+
|
|
6
|
+
# 颜色定义
|
|
7
|
+
GREEN='\033[0;32m'
|
|
8
|
+
RED='\033[0;31m'
|
|
9
|
+
YELLOW='\033[1;33m'
|
|
10
|
+
NC='\033[0m' # No Color
|
|
11
|
+
|
|
12
|
+
# 测试计数
|
|
13
|
+
TOTAL=0
|
|
14
|
+
PASSED=0
|
|
15
|
+
FAILED=0
|
|
16
|
+
|
|
17
|
+
# 测试函数
|
|
18
|
+
test_case() {
|
|
19
|
+
local name="$1"
|
|
20
|
+
local command="$2"
|
|
21
|
+
local expected="$3"
|
|
22
|
+
|
|
23
|
+
TOTAL=$((TOTAL + 1))
|
|
24
|
+
echo -n "测试 $TOTAL: $name ... "
|
|
25
|
+
|
|
26
|
+
result=$(eval "$command" 2>/dev/null)
|
|
27
|
+
|
|
28
|
+
if echo "$result" | grep -q "$expected"; then
|
|
29
|
+
echo -e "${GREEN}✓ 通过${NC}"
|
|
30
|
+
PASSED=$((PASSED + 1))
|
|
31
|
+
return 0
|
|
32
|
+
else
|
|
33
|
+
echo -e "${RED}✗ 失败${NC}"
|
|
34
|
+
echo " 期望: $expected"
|
|
35
|
+
echo " 实际: $result"
|
|
36
|
+
FAILED=$((FAILED + 1))
|
|
37
|
+
return 1
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
echo "1. 测试实例类型检测"
|
|
42
|
+
echo "-------------------"
|
|
43
|
+
|
|
44
|
+
test_case \
|
|
45
|
+
"agentbridge 实例类型" \
|
|
46
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"agentbridge\") | .instanceType'" \
|
|
47
|
+
"bmad-plugin"
|
|
48
|
+
|
|
49
|
+
test_case \
|
|
50
|
+
"cognitive 实例类型" \
|
|
51
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"cognitive\") | .instanceType'" \
|
|
52
|
+
"bmad-plugin"
|
|
53
|
+
|
|
54
|
+
test_case \
|
|
55
|
+
"corp 实例类型" \
|
|
56
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"corp\") | .instanceType'" \
|
|
57
|
+
"bmad-plugin"
|
|
58
|
+
|
|
59
|
+
echo ""
|
|
60
|
+
echo "2. 测试实例数据完整性"
|
|
61
|
+
echo "---------------------"
|
|
62
|
+
|
|
63
|
+
test_case \
|
|
64
|
+
"agentbridge 有 projectPath" \
|
|
65
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"agentbridge\") | .projectPath'" \
|
|
66
|
+
"cognitive-prototype"
|
|
67
|
+
|
|
68
|
+
test_case \
|
|
69
|
+
"cognitive 有 projectPath" \
|
|
70
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"cognitive\") | .projectPath'" \
|
|
71
|
+
"cognitive-prototype"
|
|
72
|
+
|
|
73
|
+
test_case \
|
|
74
|
+
"corp 有 projectPath" \
|
|
75
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[] | select(.name==\"corp\") | .projectPath'" \
|
|
76
|
+
"corp-office"
|
|
77
|
+
|
|
78
|
+
echo ""
|
|
79
|
+
echo "3. 测试 API 响应结构"
|
|
80
|
+
echo "-------------------"
|
|
81
|
+
|
|
82
|
+
test_case \
|
|
83
|
+
"API 返回 instanceType 字段" \
|
|
84
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[0] | keys[]' | grep instanceType" \
|
|
85
|
+
"instanceType"
|
|
86
|
+
|
|
87
|
+
test_case \
|
|
88
|
+
"API 返回 botName 字段" \
|
|
89
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[0] | keys[]' | grep botName" \
|
|
90
|
+
"botName"
|
|
91
|
+
|
|
92
|
+
test_case \
|
|
93
|
+
"API 返回 configPath 字段" \
|
|
94
|
+
"curl -s http://127.0.0.1:3721/api/instances | jq -r '.[0] | keys[]' | grep configPath" \
|
|
95
|
+
"configPath"
|
|
96
|
+
|
|
97
|
+
echo ""
|
|
98
|
+
echo "4. 验证 instances.json 文件"
|
|
99
|
+
echo "-------------------------"
|
|
100
|
+
|
|
101
|
+
test_case \
|
|
102
|
+
"instances.json 存在" \
|
|
103
|
+
"test -f ~/.agent-window/instances.json && echo 'exists'" \
|
|
104
|
+
"exists"
|
|
105
|
+
|
|
106
|
+
test_case \
|
|
107
|
+
"instances.json 包含 3 个实例" \
|
|
108
|
+
"cat ~/.agent-window/instances.json | jq '.instances | length'" \
|
|
109
|
+
"3"
|
|
110
|
+
|
|
111
|
+
test_case \
|
|
112
|
+
"所有实例都有 instanceType" \
|
|
113
|
+
"cat ~/.agent-window/instances.json | jq -r '.instances[].instanceType' | sort -u" \
|
|
114
|
+
"bmad-plugin"
|
|
115
|
+
|
|
116
|
+
echo ""
|
|
117
|
+
echo "=== 测试总结 ==="
|
|
118
|
+
echo "----------------"
|
|
119
|
+
echo "总测试数: $TOTAL"
|
|
120
|
+
echo -e "通过: ${GREEN}$PASSED${NC}"
|
|
121
|
+
echo -e "失败: ${RED}$FAILED${NC}"
|
|
122
|
+
|
|
123
|
+
if [ $FAILED -eq 0 ]; then
|
|
124
|
+
echo ""
|
|
125
|
+
echo -e "${GREEN}✓ 所有测试通过!实例类型显示问题已完全修复。${NC}"
|
|
126
|
+
echo ""
|
|
127
|
+
echo "前端预期显示:"
|
|
128
|
+
echo " - agentbridge: BMAD 插件 (绿色)"
|
|
129
|
+
echo " - cognitive: BMAD 插件 (绿色)"
|
|
130
|
+
echo " - corp: BMAD 插件 (绿色)"
|
|
131
|
+
exit 0
|
|
132
|
+
else
|
|
133
|
+
echo ""
|
|
134
|
+
echo -e "${RED}✗ 有 $FAILED 个测试失败,请检查修复。${NC}"
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Fix agentbridge instance to use correct project path
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { readInstances, writeInstances, updateInstance } from '../src/core/instance/manager.js';
|
|
8
|
+
import { detectInstanceType } from '../src/core/instance/validator.js';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
import fs from 'fs/promises';
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
console.log('=== Fix AgentBridge Instance ===\n');
|
|
14
|
+
|
|
15
|
+
const data = await readInstances();
|
|
16
|
+
const agentbridge = data.instances.find(i => i.name === 'agentbridge');
|
|
17
|
+
|
|
18
|
+
if (!agentbridge) {
|
|
19
|
+
console.log('No agentbridge instance found');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log('Current agentbridge instance:');
|
|
24
|
+
console.log(` Name: ${agentbridge.name}`);
|
|
25
|
+
console.log(` Project Path: ${agentbridge.projectPath}`);
|
|
26
|
+
console.log(` Config Path: ${agentbridge.configPath}`);
|
|
27
|
+
console.log(` Instance Type: ${agentbridge.instanceType}`);
|
|
28
|
+
|
|
29
|
+
// Read config to get PROJECT_DIR
|
|
30
|
+
if (agentbridge.configPath && existsSync(agentbridge.configPath)) {
|
|
31
|
+
try {
|
|
32
|
+
const configContent = await fs.readFile(agentbridge.configPath, 'utf8');
|
|
33
|
+
const config = JSON.parse(configContent);
|
|
34
|
+
|
|
35
|
+
if (config.PROJECT_DIR) {
|
|
36
|
+
console.log(`\nConfig PROJECT_DIR: ${config.PROJECT_DIR}`);
|
|
37
|
+
|
|
38
|
+
// Check if PROJECT_DIR exists and detect its type
|
|
39
|
+
if (existsSync(config.PROJECT_DIR)) {
|
|
40
|
+
const projectType = detectInstanceType(config.PROJECT_DIR);
|
|
41
|
+
console.log(`PROJECT_DIR Type: ${projectType}`);
|
|
42
|
+
|
|
43
|
+
if (projectType === 'bmad-plugin') {
|
|
44
|
+
console.log('\n✓ PROJECT_DIR is a valid BMAD plugin');
|
|
45
|
+
|
|
46
|
+
// Update instance
|
|
47
|
+
const index = data.instances.findIndex(i => i.name === 'agentbridge');
|
|
48
|
+
data.instances[index].projectPath = config.PROJECT_DIR;
|
|
49
|
+
data.instances[index].instanceType = projectType;
|
|
50
|
+
|
|
51
|
+
// Try to find plugin path
|
|
52
|
+
const pluginPath = existsSync(config.PROJECT_DIR + '/_agent-bridge')
|
|
53
|
+
? config.PROJECT_DIR + '/_agent-bridge/src'
|
|
54
|
+
: existsSync(config.PROJECT_DIR + '/src/bot.js')
|
|
55
|
+
? config.PROJECT_DIR + '/src'
|
|
56
|
+
: null;
|
|
57
|
+
|
|
58
|
+
if (pluginPath) {
|
|
59
|
+
data.instances[index].pluginPath = pluginPath;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
data.instances[index].updatedAt = new Date().toISOString();
|
|
63
|
+
|
|
64
|
+
await writeInstances(data);
|
|
65
|
+
|
|
66
|
+
console.log('\n✓ Instance updated successfully');
|
|
67
|
+
console.log(` New Project Path: ${data.instances[index].projectPath}`);
|
|
68
|
+
console.log(` New Instance Type: ${data.instances[index].instanceType}`);
|
|
69
|
+
console.log(` New Plugin Path: ${data.instances[index].pluginPath || 'none'}`);
|
|
70
|
+
} else {
|
|
71
|
+
console.log('\n✗ PROJECT_DIR is not a BMAD plugin');
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
console.log('\n✗ PROJECT_DIR does not exist');
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
console.log('\n✗ Config does not have PROJECT_DIR');
|
|
78
|
+
}
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(`\n✗ Error reading config: ${error.message}`);
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
console.log('\n✗ Config path does not exist');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.log('\n=== Fix Complete ===');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
main().catch(console.error);
|