mioku-service-webui 4.11.1 → 4.11.3

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.
@@ -1,7 +1,9 @@
1
+ import { createRequire } from "node:module";
1
2
  import * as fs from "node:fs";
2
3
  import * as path from "node:path";
3
4
  import matter from "gray-matter";
4
- import { logger } from "mioku";
5
+ import { BOT_CWD, logger } from "mioku";
6
+ import { projectRoot } from "./utils";
5
7
 
6
8
  export interface ConfigField {
7
9
  key: string;
@@ -27,39 +29,63 @@ export interface ConfigPageManifest {
27
29
  }
28
30
 
29
31
  export function loadPluginConfigPage(pluginName: string): ConfigPageManifest | null {
30
- const possiblePaths = [
31
- path.join(process.cwd(), "plugins", pluginName),
32
- path.join(process.cwd(), "node_modules", `mioku-plugin-${pluginName}`),
33
- ];
34
-
35
- return loadConfigPage(pluginName, possiblePaths);
32
+ const root = projectRoot();
33
+ return loadConfigPage(pluginName, `mioku-plugin-${pluginName}`, [
34
+ path.join(root, "plugins", pluginName),
35
+ path.join(root, "node_modules", `mioku-plugin-${pluginName}`),
36
+ ]);
36
37
  }
37
38
 
38
39
  export function loadServiceConfigPage(serviceName: string): ConfigPageManifest | null {
39
- const possiblePaths = [
40
- path.join(process.cwd(), "services", serviceName),
41
- path.join(process.cwd(), "node_modules", `mioku-service-${serviceName}`),
42
- ];
43
-
44
- return loadConfigPage(serviceName, possiblePaths);
40
+ const root = projectRoot();
41
+ return loadConfigPage(serviceName, `mioku-service-${serviceName}`, [
42
+ path.join(root, "services", serviceName),
43
+ path.join(root, "node_modules", `mioku-service-${serviceName}`),
44
+ ]);
45
45
  }
46
46
 
47
47
  export function loadAdapterConfigPage(adapterName: string): ConfigPageManifest | null {
48
- const possiblePaths = [
49
- path.join(process.cwd(), "node_modules", `mioku-adapter-${adapterName}`),
50
- ];
48
+ return loadConfigPage(adapterName, `mioku-adapter-${adapterName}`, [
49
+ path.join(projectRoot(), "node_modules", `mioku-adapter-${adapterName}`),
50
+ ]);
51
+ }
51
52
 
52
- return loadConfigPage(adapterName, possiblePaths);
53
+ /** 从机器人根目录按 node_modules 依赖解析包真实目录(pnpm / 提升安装等布局) */
54
+ function resolvePackageDir(root: string, packageName: string): string | null {
55
+ const require = createRequire(path.join(root, "package.json"));
56
+ try {
57
+ return path.dirname(require.resolve(`${packageName}/package.json`));
58
+ } catch {
59
+ // exports 未暴露 package.json 时,从入口文件向上找
60
+ }
61
+ try {
62
+ let dir = path.dirname(require.resolve(packageName));
63
+ for (let i = 0; i < 5; i++) {
64
+ if (fs.existsSync(path.join(dir, "package.json"))) return dir;
65
+ const parent = path.dirname(dir);
66
+ if (parent === dir) break;
67
+ dir = parent;
68
+ }
69
+ } catch {
70
+ // 未安装该依赖
71
+ }
72
+ return null;
53
73
  }
54
74
 
55
75
  function loadConfigPage(
56
76
  packageName: string,
77
+ npmName: string,
57
78
  possiblePaths: string[],
58
79
  ): ConfigPageManifest | null {
80
+ const resolved = resolvePackageDir(projectRoot(), npmName);
81
+ const candidates =
82
+ resolved && !possiblePaths.includes(resolved)
83
+ ? [...possiblePaths, resolved]
84
+ : possiblePaths;
59
85
  let configMdPath: string | null = null;
60
86
  let packageDir: string | null = null;
61
87
 
62
- for (const dir of possiblePaths) {
88
+ for (const dir of candidates) {
63
89
  const candidate = path.join(dir, "config.md");
64
90
  if (fs.existsSync(candidate)) {
65
91
  configMdPath = candidate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mioku-service-webui",
3
- "version": "4.11.1",
3
+ "version": "4.11.3",
4
4
  "description": "Mioku WebUI 服务",
5
5
  "main": "index.ts",
6
6
  "type": "module",
@@ -3,10 +3,10 @@ import * as fs from "node:fs";
3
3
  import * as path from "node:path";
4
4
  import { loadAdapterConfigPage } from "../config-page-loader";
5
5
  import { getAdapterConfigs, updateAdapterConfig } from "../system";
6
- import { isPackageDir } from "../utils";
6
+ import { isPackageDir, projectRoot } from "../utils";
7
7
 
8
8
  function listAdaptersFromNodeModules(): string[] {
9
- const modulesPath = path.join(process.cwd(), "node_modules");
9
+ const modulesPath = path.join(projectRoot(), "node_modules");
10
10
  const adapters: string[] = [];
11
11
  if (!fs.existsSync(modulesPath)) return adapters;
12
12
 
package/system.ts CHANGED
@@ -333,6 +333,22 @@ function writeRootPackageJson(data: any): void {
333
333
  fs.writeFileSync(ROOT_PACKAGE_PATH, JSON.stringify(data, null, 2), "utf-8");
334
334
  }
335
335
 
336
+ function resolveWebUIHost(configured: unknown): string {
337
+ const fromEnv = process.env.MIOKU_WEBUI_HOST?.trim();
338
+ if (fromEnv) return fromEnv;
339
+ return typeof configured === "string" && configured.trim()
340
+ ? configured.trim()
341
+ : defaultWebUISettings.host;
342
+ }
343
+
344
+ function resolveWebUIPort(configured: unknown): number {
345
+ const fromEnv = Number(process.env.MIOKU_WEBUI_PORT);
346
+ if (Number.isFinite(fromEnv) && fromEnv > 0) return fromEnv;
347
+ return typeof configured === "number" && Number.isFinite(configured)
348
+ ? configured
349
+ : defaultWebUISettings.port;
350
+ }
351
+
336
352
  export function getWebUISettings(): WebUISettings {
337
353
  ensureDir(path.dirname(SETTINGS_PATH));
338
354
  const settings = readJsonFile<Record<string, unknown>>(
@@ -340,14 +356,8 @@ export function getWebUISettings(): WebUISettings {
340
356
  defaultWebUISettings as unknown as Record<string, unknown>,
341
357
  );
342
358
  const merged: WebUISettings = {
343
- port:
344
- typeof settings.port === "number" && Number.isFinite(settings.port)
345
- ? settings.port
346
- : defaultWebUISettings.port,
347
- host:
348
- typeof settings.host === "string" && settings.host.trim()
349
- ? settings.host
350
- : defaultWebUISettings.host,
359
+ port: resolveWebUIPort(settings.port),
360
+ host: resolveWebUIHost(settings.host),
351
361
  packageManager: "bun",
352
362
  };
353
363
  writeJsonFile(SETTINGS_PATH, merged);
@@ -369,6 +379,11 @@ export function updateWebUISettings(
369
379
  : current.host,
370
380
  packageManager: "bun",
371
381
  };
382
+ if (process.env.MIOKU_WEBUI_HOST?.trim() && input.host !== undefined) {
383
+ logger.warn(
384
+ `[webui] 监听地址由环境变量 MIOKU_WEBUI_HOST=${process.env.MIOKU_WEBUI_HOST} 决定,配置里的 ${next.host} 不会生效`,
385
+ );
386
+ }
372
387
  writeJsonFile(SETTINGS_PATH, next);
373
388
  return next;
374
389
  }
package/utils.ts CHANGED
@@ -3,6 +3,7 @@ import * as path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import type { PackageManager, WebUISettings } from "./types";
5
5
  import {
6
+ BOT_CWD,
6
7
  getServiceConfigDir,
7
8
  getServiceDataDir,
8
9
  getConfigDir,
@@ -19,7 +20,13 @@ export const SETTINGS_PATH = path.join(
19
20
  "settings.json",
20
21
  );
21
22
  export const AUTH_PATH = path.join(getServiceConfigDir("webui"), "auth.json");
22
- export const ROOT_PACKAGE_PATH = path.join(process.cwd(), "package.json");
23
+
24
+ /** 机器人根目录:进程 cwd 可能与 start({ cwd }) 不一致,以框架记录为准 */
25
+ export function projectRoot(): string {
26
+ return BOT_CWD.value || process.cwd();
27
+ }
28
+
29
+ export const ROOT_PACKAGE_PATH = path.join(projectRoot(), "package.json");
23
30
 
24
31
  export const WEBUI_DIST = path.join(__dirname, "dist");
25
32
  export const CONFIG_DIR = getConfigDir();