agent-window 1.1.4 → 1.2.0

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": "agent-window",
3
- "version": "1.1.4",
3
+ "version": "1.2.0",
4
4
  "description": "A window to interact with AI agents through chat interfaces. Simplified interaction, powerful backend capabilities.",
5
5
  "type": "module",
6
6
  "main": "src/bot.js",
@@ -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,231 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * agentbridge 实例修复脚本
4
+ *
5
+ * 自动修复 agentbridge 实例的配置路径问题
6
+ * 支持三种修复模式:
7
+ * - A: 创建标准 bots 目录结构并设置 PM2 环境变量
8
+ * - B: 手动设置 configPath (快速修复)
9
+ * - C: 仅创建目录,不修改 PM2
10
+ */
11
+
12
+ import fs from 'fs/promises';
13
+ import path from 'path';
14
+ import { existsSync } from 'fs';
15
+ import { execSync } from 'child_process';
16
+ import { readInstances, writeInstances, importInstance } from '../src/core/instance/manager.js';
17
+ import { paths } from '../src/core/platform/index.js';
18
+
19
+ const MODE = process.argv[2] || 'A'; // 默认使用方案 A
20
+
21
+ console.log('\n=== agentbridge 实例修复工具 ===\n');
22
+ console.log(`修复模式: ${MODE}`);
23
+ console.log('');
24
+
25
+ async function main() {
26
+ const data = await readInstances();
27
+ const agentbridge = data.instances.find(i => i.name === 'agentbridge');
28
+
29
+ if (!agentbridge) {
30
+ console.log('❌ 未找到 agentbridge 实例');
31
+ process.exit(1);
32
+ }
33
+
34
+ console.log('当前实例状态:');
35
+ console.log(`- name: ${agentbridge.name}`);
36
+ console.log(`- projectPath: ${agentbridge.projectPath}`);
37
+ console.log(`- configPath: ${agentbridge.configPath || '未设置'}`);
38
+ console.log('');
39
+
40
+ if (MODE === 'A') {
41
+ await fixModeA(agentbridge);
42
+ } else if (MODE === 'B') {
43
+ await fixModeB(agentbridge);
44
+ } else if (MODE === 'C') {
45
+ await fixModeC(agentbridge);
46
+ } else {
47
+ console.log('❌ 未知模式');
48
+ console.log('用法: node scripts/fix-agentbridge-instance.js [A|B|C]');
49
+ console.log(' A - 标准模式: 创建 bots 目录并设置 PM2 环境变量 (推荐)');
50
+ console.log(' B - 快速模式: 手动设置 configPath 指向项目内配置');
51
+ console.log(' C - 仅创建目录,不修改 PM2 和 instances.json');
52
+ process.exit(1);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * 方案 A: 标准模式
58
+ * 1. 创建 ~/bots/agentbridge/ 目录
59
+ * 2. 复制配置文件
60
+ * 3. 重启 PM2 进程并设置 CONFIG_PATH
61
+ * 4. 重新导入实例
62
+ */
63
+ async function fixModeA(instance) {
64
+ console.log('【方案 A: 标准模式】\n');
65
+
66
+ const botsDir = paths.getBotsDir();
67
+ const agentbridgeDir = path.join(botsDir, 'agentbridge');
68
+ const configDir = path.join(instance.projectPath, 'config');
69
+ const sourceConfig = path.join(configDir, 'config.json');
70
+ const targetConfig = path.join(agentbridgeDir, 'config.json');
71
+
72
+ // Step 1: 创建目录
73
+ console.log('1. 创建目录结构...');
74
+ if (!existsSync(agentbridgeDir)) {
75
+ await fs.mkdir(agentbridgeDir, { recursive: true });
76
+ console.log(` ✓ 创建目录: ${agentbridgeDir}`);
77
+ } else {
78
+ console.log(` ✓ 目录已存在: ${agentbridgeDir}`);
79
+ }
80
+
81
+ // Step 2: 复制配置文件
82
+ console.log('\n2. 复制配置文件...');
83
+ if (existsSync(sourceConfig)) {
84
+ await fs.copyFile(sourceConfig, targetConfig);
85
+ console.log(` ✓ 复制 ${sourceConfig}`);
86
+ console.log(` → ${targetConfig}`);
87
+ } else {
88
+ console.log(` ❌ 源文件不存在: ${sourceConfig}`);
89
+ process.exit(1);
90
+ }
91
+
92
+ // Step 3: 删除现有实例
93
+ console.log('\n3. 删除现有实例...');
94
+ const removeResult = await import('../src/core/instance/manager.js').then(m => m.removeInstance(instance.name));
95
+ if (removeResult.success) {
96
+ console.log(` ✓ 已删除实例: ${instance.name}`);
97
+ } else {
98
+ console.log(` ⚠ 删除失败: ${removeResult.error}`);
99
+ }
100
+
101
+ // Step 4: 重启 PM2 进程并设置环境变量
102
+ console.log('\n4. 重启 PM2 进程并设置 CONFIG_PATH...');
103
+ try {
104
+ const pm2Cmd = `pm2 restart bot-agentbridge --env CONFIG_PATH=${targetConfig}`;
105
+ console.log(` $ ${pm2Cmd}`);
106
+ execSync(pm2Cmd, { stdio: 'inherit' });
107
+ console.log(' ✓ PM2 进程已更新');
108
+ } catch (error) {
109
+ console.log(` ❌ PM2 重启失败: ${error.message}`);
110
+ process.exit(1);
111
+ }
112
+
113
+ // Step 5: 保存 PM2 配置
114
+ console.log('\n5. 保存 PM2 配置...');
115
+ try {
116
+ execSync('pm2 save', { stdio: 'inherit' });
117
+ console.log(' ✓ PM2 配置已保存');
118
+ } catch (error) {
119
+ console.log(` ⚠ PM2 保存失败: ${error.message}`);
120
+ }
121
+
122
+ // Step 6: 等待并重新发现实例
123
+ console.log('\n6. 重新发现实例...');
124
+ await new Promise(resolve => setTimeout(resolve, 2000));
125
+
126
+ const discoverResult = await import('../src/core/instance/manager.js').then(m => m.discoverInstances());
127
+ const discovered = discoverResult.find(d => d.name === 'agentbridge');
128
+
129
+ if (discovered) {
130
+ console.log(' ✓ 发现实例:');
131
+ console.log(` - configPath: ${discovered.configPath}`);
132
+ console.log(` - projectPath: ${discovered.projectPath}`);
133
+
134
+ // 导入实例
135
+ const importResult = await import('../src/core/instance/manager.js').then(m => m.importInstance(discovered));
136
+ if (importResult.success) {
137
+ console.log(' ✓ 实例已导入');
138
+ } else {
139
+ console.log(` ⚠ 导入失败: ${importResult.error}`);
140
+ }
141
+ } else {
142
+ console.log(' ❌ 未发现实例');
143
+ }
144
+
145
+ console.log('\n✅ 修复完成!');
146
+ console.log(`\n配置文件路径: ${targetConfig}`);
147
+ console.log('请验证 Web UI 中的 Edit Config 功能是否正常');
148
+ }
149
+
150
+ /**
151
+ * 方案 B: 快速模式
152
+ * 手动设置 configPath 指向项目内配置
153
+ */
154
+ async function fixModeB(instance) {
155
+ console.log('【方案 B: 快速模式】\n');
156
+
157
+ const configPath = path.join(instance.projectPath, 'config', 'config.json');
158
+
159
+ console.log(`设置 configPath: ${configPath}`);
160
+
161
+ // 检查文件是否存在
162
+ if (!existsSync(configPath)) {
163
+ console.log(`❌ 配置文件不存在: ${configPath}`);
164
+ process.exit(1);
165
+ }
166
+
167
+ // 更新实例
168
+ const data = await readInstances();
169
+ const index = data.instances.findIndex(i => i.name === instance.name);
170
+
171
+ if (index === -1) {
172
+ console.log('❌ 未找到实例');
173
+ process.exit(1);
174
+ }
175
+
176
+ data.instances[index].configPath = configPath;
177
+ data.instances[index].updatedAt = new Date().toISOString();
178
+
179
+ await writeInstances(data);
180
+
181
+ console.log('✅ instances.json 已更新');
182
+ console.log(` configPath: ${configPath}`);
183
+ console.log('\n注意: 这是快速修复方案,配置文件仍在项目目录内。');
184
+ console.log('建议后续迁移到 ~/bots/agentbridge/ 目录结构。');
185
+ }
186
+
187
+ /**
188
+ * 方案 C: 仅创建目录
189
+ */
190
+ async function fixModeC(instance) {
191
+ console.log('【方案 C: 仅创建目录】\n');
192
+
193
+ const botsDir = paths.getBotsDir();
194
+ const agentbridgeDir = path.join(botsDir, 'agentbridge');
195
+ const configDir = path.join(instance.projectPath, 'config');
196
+ const sourceConfig = path.join(configDir, 'config.json');
197
+ const targetConfig = path.join(agentbridgeDir, 'config.json');
198
+
199
+ // 创建目录
200
+ console.log('1. 创建目录...');
201
+ if (!existsSync(agentbridgeDir)) {
202
+ await fs.mkdir(agentbridgeDir, { recursive: true });
203
+ console.log(` ✓ 创建目录: ${agentbridgeDir}`);
204
+ } else {
205
+ console.log(` ✓ 目录已存在: ${agentbridgeDir}`);
206
+ }
207
+
208
+ // 复制配置文件
209
+ console.log('\n2. 复制配置文件...');
210
+ if (existsSync(sourceConfig)) {
211
+ await fs.copyFile(sourceConfig, targetConfig);
212
+ console.log(` ✓ 复制到: ${targetConfig}`);
213
+ } else {
214
+ console.log(` ❌ 源文件不存在: ${sourceConfig}`);
215
+ process.exit(1);
216
+ }
217
+
218
+ console.log('\n✅ 目录和配置文件已创建');
219
+ console.log(`\n配置文件: ${targetConfig}`);
220
+ console.log('\n后续步骤:');
221
+ console.log('1. 重启 PM2 进程并设置 CONFIG_PATH:');
222
+ console.log(` pm2 restart bot-agentbridge --env CONFIG_PATH=${targetConfig}`);
223
+ console.log('2. 重新导入实例');
224
+ console.log('3. 验证 Edit Config 功能');
225
+ }
226
+
227
+ main().catch(error => {
228
+ console.error('\n❌ 修复失败:', error.message);
229
+ console.error(error.stack);
230
+ process.exit(1);
231
+ });
@@ -276,7 +276,32 @@ export async function discoverInstances() {
276
276
  projectPath = path.dirname(configPath);
277
277
  }
278
278
  }
279
- // Priority 2: Use cwd
279
+ // Priority 2: Infer config path from instance name (bots/{name}/config.json)
280
+ else if (instanceName) {
281
+ const botsDir = paths.getBotsDir();
282
+ const inferredConfigPath = path.join(botsDir, instanceName, 'config.json');
283
+
284
+ if (existsSync(inferredConfigPath)) {
285
+ configPath = inferredConfigPath;
286
+
287
+ // Try to read PROJECT_DIR from inferred config
288
+ try {
289
+ const configContent = await fs.readFile(inferredConfigPath, 'utf8');
290
+ const config = JSON.parse(configContent);
291
+
292
+ if (config.PROJECT_DIR) {
293
+ projectPath = config.PROJECT_DIR;
294
+ } else {
295
+ // Fallback to cwd if available
296
+ projectPath = proc.cwd || null;
297
+ }
298
+ } catch {
299
+ // If config read fails, use cwd
300
+ projectPath = proc.cwd || null;
301
+ }
302
+ }
303
+ }
304
+ // Priority 3: Use cwd
280
305
  else if (proc.cwd) {
281
306
  projectPath = proc.cwd;
282
307
  }
@@ -292,18 +317,7 @@ export async function discoverInstances() {
292
317
  // Detect instance type based on project structure
293
318
  let instanceType = 'unknown';
294
319
  if (projectPath) {
295
- // Check if it has BMAD plugin (_agent-bridge directory)
296
- if (existsSync(path.join(projectPath, '_agent-bridge'))) {
297
- instanceType = 'bmad-plugin';
298
- }
299
- // Check if it has a config file (simple config instance)
300
- else if (existsSync(path.join(projectPath, 'config.json'))) {
301
- instanceType = 'simple-config';
302
- }
303
- // Check if configPath exists and has config.json
304
- else if (configPath && existsSync(configPath)) {
305
- instanceType = 'simple-config';
306
- }
320
+ instanceType = detectInstanceType(projectPath);
307
321
  }
308
322
 
309
323
  discovered.push({