openclaw-agent-dashboard 1.0.13 → 1.0.14

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": "openclaw-agent-dashboard",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "多 Agent 可视化看板 - 状态、任务、API、工作流、协作流程",
5
5
  "bin": {
6
6
  "openclaw-agent-dashboard": "scripts/install.js"
@@ -2,7 +2,7 @@
2
2
  "id": "openclaw-agent-dashboard",
3
3
  "name": "OpenClaw Agent Dashboard",
4
4
  "description": "多 Agent 可视化看板 - 状态、任务、API、工作流、协作流程",
5
- "version": "1.0.13",
5
+ "version": "1.0.14",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openclaw-agent-dashboard",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "多 Agent 可视化看板 - OpenClaw 插件",
5
5
  "main": "index.js",
6
6
  "openclaw": {
@@ -278,10 +278,60 @@ function resolveVersion(requested) {
278
278
  }
279
279
 
280
280
  // ============================================
281
- // 远程模式:下载安装
281
+ // 远程模式:从 npm 包自带的 plugin 目录安装(无需下载 tgz)
282
282
  // ============================================
283
283
 
284
- /**
284
+ async function localPluginInstall(bundledPluginDir, pluginPath, options) {
285
+ const newVersion = parseJsonVersion(path.join(bundledPluginDir, 'openclaw.plugin.json'));
286
+ const oldVersion = fs.existsSync(path.join(pluginPath, 'openclaw.plugin.json'))
287
+ ? parseJsonVersion(path.join(pluginPath, 'openclaw.plugin.json'))
288
+ : null;
289
+
290
+ logInfo(`版本: ${newVersion}(npm 包自带)`);
291
+ if (oldVersion) {
292
+ logInfo(` ${oldVersion} → ${newVersion}`);
293
+ }
294
+
295
+ // 备份旧版本
296
+ if (fs.existsSync(pluginPath)) {
297
+ logStep('备份旧版本...');
298
+ backupDir(pluginPath);
299
+ const extDir = path.dirname(pluginPath);
300
+ cleanupOldBackups(extDir, `${PLUGIN_ID}.backup-`, 2);
301
+ logOk('备份完成');
302
+ }
303
+
304
+ // 复制到插件目录
305
+ logStep('安装插件...');
306
+ if (fs.existsSync(pluginPath)) {
307
+ rmrf(pluginPath);
308
+ }
309
+ copyDir(bundledPluginDir, pluginPath);
310
+ logOk('插件已安装');
311
+
312
+ // 安装 Python 依赖
313
+ if (!options.skipPython && fs.existsSync(path.join(pluginPath, 'dashboard', 'requirements.txt'))) {
314
+ logStep('安装 Python 依赖...');
315
+ const scriptPath = path.join(__dirname, 'install-python-deps.js');
316
+ const args = [scriptPath, pluginPath];
317
+ if (options.verbose) args.push('--verbose');
318
+ const result = runCommand('node', args, { silent: !options.verbose });
319
+ if (!result.success) {
320
+ logWarn('Python 依赖安装失败,Dashboard 启动时可能需要手动安装');
321
+ }
322
+ }
323
+
324
+ // 清理旧备份
325
+ logStep('清理旧备份...');
326
+ const extDir = path.dirname(pluginPath);
327
+ cleanupOldBackups(extDir, `${PLUGIN_ID}.backup-`, 1);
328
+
329
+ return true;
330
+ }
331
+
332
+ // ============================================
333
+ // 远程模式:下载安装
334
+ // ============================================/**
285
335
  * 获取 tgz 缓存目录
286
336
  * @returns {string}
287
337
  */
@@ -300,6 +350,14 @@ async function remoteInstall(pluginPath, options) {
300
350
  const tmpDir = path.join(require('os').tmpdir(), `oc-dashboard-install-${Date.now()}`);
301
351
  fs.mkdirSync(tmpDir, { recursive: true });
302
352
 
353
+ // 优先使用 npm 包自带的 plugin 目录(npx 模式下 plugin 就在包里)
354
+ const bundledPluginDir = path.join(__dirname, '..', 'plugin');
355
+ const bundledPluginJson = path.join(bundledPluginDir, 'openclaw.plugin.json');
356
+
357
+ if (fs.existsSync(bundledPluginJson)) {
358
+ return await localPluginInstall(bundledPluginDir, pluginPath, options);
359
+ }
360
+
303
361
  try {
304
362
  // 1. 解析版本
305
363
  const version = await resolveVersion(options.version);
@@ -23,8 +23,8 @@ class VersionInfoReader:
23
23
  Args:
24
24
  package_json_path: package.json 文件路径,默认为项目根目录下的 package.json
25
25
  """
26
- # 默认路径:src/backend/data -> src/backend -> src -> package.json
27
- self.package_json_path = package_json_path or Path(__file__).parent.parent.parent / "package.json"
26
+ # 默认路径:src/backend/data -> src/backend -> src -> 项目根目录 -> package.json
27
+ self.package_json_path = package_json_path or Path(__file__).resolve().parent.parent.parent.parent / "package.json"
28
28
  self._cached_info: Optional[dict] = None
29
29
 
30
30
  def read_version_info(self) -> dict:
@@ -29,7 +29,7 @@ async def lifespan(app: FastAPI):
29
29
  # 创建 FastAPI 应用
30
30
  app = FastAPI(
31
31
  lifespan=lifespan,
32
- title="OpenClow Agent Dashboard",
32
+ title="OpenClaw Agent Dashboard",
33
33
  description="多 Agent 可视化看板 API",
34
34
  version="1.0.0"
35
35
  )