agent-window 1.0.7 → 1.0.8

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.0.7",
3
+ "version": "1.0.8",
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",
@@ -8,7 +8,7 @@
8
8
  import fs from 'fs/promises';
9
9
  import path from 'path';
10
10
  import { existsSync } from 'fs';
11
- import { validateInstance } from './validator.js';
11
+ import { validateInstance, detectInstanceType } from './validator.js';
12
12
  import { paths } from '../platform/index.js';
13
13
  import { getProcesses } from './pm2-bridge.js';
14
14
 
@@ -92,9 +92,16 @@ export async function addInstance(name, projectPath, options = {}) {
92
92
  // Validate the instance
93
93
  const validation = await validateInstance(projectPath);
94
94
  if (!validation.valid) {
95
+ // Provide helpful error message based on instance type
96
+ const typeMsg = validation.instanceType === 'simple-config'
97
+ ? '简单配置实例无法通过"添加实例"功能添加。请先使用 PM2 启动 bot,然后在 Web UI 中导入。'
98
+ : validation.instanceType === 'unknown'
99
+ ? '无法识别的项目类型'
100
+ : '项目不是有效的 AgentWindow BMAD 插件';
101
+
95
102
  return {
96
103
  success: false,
97
- error: '验证失败:项目不是有效的 AgentWindow BMAD 插件',
104
+ error: '验证失败:' + typeMsg,
98
105
  validation
99
106
  };
100
107
  }
@@ -113,6 +120,7 @@ export async function addInstance(name, projectPath, options = {}) {
113
120
  pluginPath: validation.pluginPath,
114
121
  configPath,
115
122
  botName: `bot-${name}`,
123
+ instanceType: validation.instanceType, // Save instance type
116
124
  addedAt: new Date().toISOString(),
117
125
  tags: options.tags || [],
118
126
  enabled: true
@@ -281,6 +289,23 @@ export async function discoverInstances() {
281
289
  pluginPath = path.join(projectPath, 'src');
282
290
  }
283
291
 
292
+ // Detect instance type based on project structure
293
+ let instanceType = 'unknown';
294
+ 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
+ }
307
+ }
308
+
284
309
  discovered.push({
285
310
  botName: proc.name,
286
311
  name: instanceName,
@@ -288,6 +313,7 @@ export async function discoverInstances() {
288
313
  projectPath,
289
314
  configPath,
290
315
  pluginPath,
316
+ instanceType, // 'bmad' | 'simple' | 'unknown'
291
317
  status: proc.status || 'unknown',
292
318
  pid: proc.pid,
293
319
  memory: proc.memory || 0,
@@ -339,6 +365,7 @@ export async function importInstance(discovered) {
339
365
  configPath: discovered.configPath,
340
366
  pluginPath: validatedPluginPath,
341
367
  botName: discovered.botName,
368
+ instanceType: discovered.instanceType || 'simple-config', // Save instance type
342
369
  addedAt: new Date().toISOString(),
343
370
  tags: ['imported'],
344
371
  enabled: true,
@@ -2,12 +2,39 @@
2
2
  * Instance Validator
3
3
  *
4
4
  * Validates if a project path contains a valid AgentWindow BMAD plugin instance.
5
+ * Supports two types:
6
+ * 1. Simple config (基础版) - Only has config.json
7
+ * 2. BMAD plugin (增强版) - Has _bmad and _agent-bridge directories
5
8
  */
6
9
 
7
10
  import fs from 'fs/promises';
8
11
  import path from 'path';
9
12
  import { existsSync } from 'fs';
10
13
 
14
+ /**
15
+ * Detect instance type
16
+ * @param {string} projectPath - Path to check
17
+ * @returns {string} 'bmad-plugin' | 'simple-config' | 'unknown'
18
+ */
19
+ export function detectInstanceType(projectPath) {
20
+ const normalizedPath = path.resolve(projectPath);
21
+
22
+ // Check if it has BMAD plugin (_agent-bridge directory)
23
+ const hasPlugin = existsSync(path.join(normalizedPath, '_agent-bridge'));
24
+
25
+ if (hasPlugin) {
26
+ return 'bmad-plugin';
27
+ }
28
+
29
+ // Check if it has config.json (simple config instance)
30
+ const hasConfig = existsSync(path.join(normalizedPath, 'config.json'));
31
+ if (hasConfig) {
32
+ return 'simple-config';
33
+ }
34
+
35
+ return 'unknown';
36
+ }
37
+
11
38
  /**
12
39
  * Validation check definition
13
40
  * @typedef {Object} ValidationCheck
@@ -21,6 +48,7 @@ import { existsSync } from 'fs';
21
48
  * Validation result
22
49
  * @typedef {Object} ValidationResult
23
50
  * @property {boolean} valid - Overall validation result
51
+ * @property {string} instanceType - 'bmad' | 'simple' | 'unknown'
24
52
  * @property {Array<Object>} checks - Individual check results
25
53
  * @property {string|null} pluginPath - Path to the plugin directory
26
54
  * @property {string} projectPath - Path to the project directory
@@ -61,63 +89,88 @@ export async function validateInstance(projectPath) {
61
89
  const checks = [];
62
90
  const normalizedPath = path.resolve(projectPath);
63
91
 
64
- // 1. Path exists check
65
- checks.push({
66
- name: 'path.exists',
67
- passed: pathExists(normalizedPath),
68
- required: true,
69
- error: pathExists(normalizedPath) ? null : '项目路径不存在'
70
- });
71
-
72
- // 2. BMAD framework check
73
- const bmadPath = path.join(normalizedPath, '_bmad');
74
- const bmadExists = pathExists(bmadPath);
75
- checks.push({
76
- name: 'bmad.exists',
77
- passed: bmadExists,
78
- required: true,
79
- error: bmadExists ? null : '未检测到 BMAD 框架 (_bmad 目录)'
80
- });
81
-
82
- // 3. Plugin directory check
83
- const pluginPath = path.join(normalizedPath, '_agent-bridge');
84
- const pluginExists = pathExists(pluginPath);
85
- checks.push({
86
- name: 'plugin.exists',
87
- passed: pluginExists,
88
- required: true,
89
- error: pluginExists ? null : '未检测到 _agent-bridge 插件目录'
90
- });
92
+ // Detect instance type
93
+ const instanceType = detectInstanceType(normalizedPath);
91
94
 
92
- // 4. Core bot.js file check
93
- const botJsPath = path.join(pluginPath, 'src/bot.js');
94
- const botJsExists = pathExists(botJsPath);
95
95
  checks.push({
96
- name: 'plugin.botjs',
97
- passed: botJsExists,
96
+ name: 'type.detected',
97
+ passed: instanceType !== 'unknown',
98
98
  required: true,
99
- error: botJsExists ? null : '插件缺少核心文件 src/bot.js'
99
+ error: instanceType === 'unknown' ? '无法识别的实例类型' : `检测到${instanceType === 'bmad-plugin' ? ' BMAD 插件' : '简单配置'}实例`
100
100
  });
101
101
 
102
- // 5. package.json validation (check dependencies, not hardcoded name)
103
- const pluginPkgPath = path.join(pluginPath, 'package.json');
104
- const hasDiscord = await hasDependency(pluginPkgPath, 'discord.js');
105
- checks.push({
106
- name: 'plugin.package',
107
- passed: hasDiscord,
108
- required: true,
109
- error: hasDiscord ? null : '插件 package.json 缺少 discord.js 依赖'
110
- });
111
-
112
- // 6. BMAD config check (optional)
113
- const bmadConfigPath = path.join(normalizedPath, '_bmad/core/config.yaml');
114
- const bmadConfigExists = pathExists(bmadConfigPath);
115
- checks.push({
116
- name: 'bmad.config',
117
- passed: bmadConfigExists,
118
- required: false,
119
- error: bmadConfigExists ? null : 'BMAD 配置文件不存在(非致命)'
120
- });
102
+ let pluginPath = null;
103
+
104
+ if (instanceType === 'bmad-plugin') {
105
+ // BMAD-specific checks
106
+ const bmadPath = path.join(normalizedPath, '_bmad');
107
+ const bmadExists = pathExists(bmadPath);
108
+ checks.push({
109
+ name: 'bmad.exists',
110
+ passed: bmadExists,
111
+ required: true,
112
+ error: bmadExists ? null : '未检测到 BMAD 框架 (_bmad 目录)'
113
+ });
114
+
115
+ pluginPath = path.join(normalizedPath, '_agent-bridge');
116
+ const pluginExists = pathExists(pluginPath);
117
+ checks.push({
118
+ name: 'plugin.exists',
119
+ passed: pluginExists,
120
+ required: true,
121
+ error: pluginExists ? null : '未检测到 _agent-bridge 插件目录'
122
+ });
123
+
124
+ const botJsPath = path.join(pluginPath, 'src/bot.js');
125
+ const botJsExists = pathExists(botJsPath);
126
+ checks.push({
127
+ name: 'plugin.botjs',
128
+ passed: botJsExists,
129
+ required: true,
130
+ error: botJsExists ? null : '插件缺少核心文件 src/bot.js'
131
+ });
132
+
133
+ const pluginPkgPath = path.join(pluginPath, 'package.json');
134
+ const hasDiscord = await hasDependency(pluginPkgPath, 'discord.js');
135
+ checks.push({
136
+ name: 'plugin.package',
137
+ passed: hasDiscord,
138
+ required: true,
139
+ error: hasDiscord ? null : '插件 package.json 缺少 discord.js 依赖'
140
+ });
141
+ } else if (instanceType === 'simple-config') {
142
+ // Simple config instance
143
+ const configPath = path.join(normalizedPath, 'config.json');
144
+ const configExists = pathExists(configPath);
145
+ checks.push({
146
+ name: 'config.exists',
147
+ passed: configExists,
148
+ required: true,
149
+ error: configExists ? null : '配置文件不存在'
150
+ });
151
+
152
+ // Try to validate config structure
153
+ if (configExists) {
154
+ try {
155
+ const configContent = await fs.readFile(configPath, 'utf-8');
156
+ const config = JSON.parse(configContent);
157
+ const hasBotToken = !!(config.BOT_TOKEN || config.token);
158
+ checks.push({
159
+ name: 'config.token',
160
+ passed: hasBotToken,
161
+ required: true,
162
+ error: hasBotToken ? null : '配置文件缺少 BOT_TOKEN'
163
+ });
164
+ } catch (e) {
165
+ checks.push({
166
+ name: 'config.valid',
167
+ passed: false,
168
+ required: true,
169
+ error: '配置文件格式错误'
170
+ });
171
+ }
172
+ }
173
+ }
121
174
 
122
175
  // Determine overall validity
123
176
  const allRequiredPassed = checks
@@ -126,8 +179,9 @@ export async function validateInstance(projectPath) {
126
179
 
127
180
  return {
128
181
  valid: allRequiredPassed,
182
+ instanceType,
129
183
  checks,
130
- pluginPath: pluginExists ? pluginPath : null,
184
+ pluginPath,
131
185
  projectPath: normalizedPath
132
186
  };
133
187
  }
@@ -140,6 +194,7 @@ export async function validateInstance(projectPath) {
140
194
  export function formatValidationResult(result) {
141
195
  const lines = [
142
196
  '验证结果: ' + (result.valid ? '✓ 通过' : '✗ 失败'),
197
+ `实例类型: ${result.instanceType === 'bmad-plugin' ? 'BMAD 插件' : result.instanceType === 'simple-config' ? '简单配置' : '未知'}`,
143
198
  ''
144
199
  ];
145
200
 
@@ -152,7 +207,7 @@ export function formatValidationResult(result) {
152
207
  }
153
208
  }
154
209
 
155
- if (result.valid) {
210
+ if (result.valid && result.pluginPath) {
156
211
  lines.push('');
157
212
  lines.push(`插件路径: ${result.pluginPath}`);
158
213
  }