mooncat-browser 0.1.0 → 0.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/dist/config.d.ts CHANGED
@@ -1,61 +1,82 @@
1
- /** 解析后的运行时配置。 */
2
- export interface ResolvedConfig {
3
- /** browserd RPC 端口(client 连这里)。默认 17322。 */
1
+ /** 端口默认值(仅在 init 生成配置 / --temp 时使用,不作为运行时兜底)。 */
2
+ export declare const DEFAULT_RPC_PORT = 17322;
3
+ export declare const DEFAULT_HEALTH_PORT = 17440;
4
+ export declare const DEFAULT_EXTENSION_PORT = 17321;
5
+ /** 实例路由模式。第一版只保证 cdp 多实例;extension 路保持单实例。 */
6
+ export type RouteMode = "auto" | "cdp" | "extension";
7
+ /**
8
+ * 一个 browser 实例的完整配置 = 一组端口 + 一份 profile + 一套 state/log。
9
+ * 实例之间在文件系统与端口上完全隔离,互不串扰。
10
+ */
11
+ export interface BrowserInstanceConfig {
12
+ /** 实例名(配置里 instances 的 key)。 */
13
+ name: string;
14
+ /** browserd RPC 端口(client 连这里)。 */
4
15
  rpcPort: number;
5
- /** 服务包装层 health 端口。默认 17440。 */
16
+ /** 服务包装层 health 端口。 */
6
17
  healthPort: number;
7
- /** Chrome user-data-dir(绝对路径)。 */
8
- profile: string;
9
- /** Chrome 可执行文件路径(未指定时为 undefined,交给 browserd 自动探测)。 */
10
- chromePath?: string;
11
- /** 日志目录(绝对路径)。 */
18
+ /** extension WS 端口(每实例独立;由 prepare-extension 写入实例扩展目录)。 */
19
+ extensionPort: number;
20
+ /** Chrome user-data-dir(绝对路径)。 */
21
+ profileDir: string;
22
+ /** wrapper/browserd 运行态目录(绝对路径),放 service.json 等。 */
23
+ stateDir: string;
24
+ /** 日志目录(绝对路径)。 */
12
25
  logsDir: string;
13
- /** 配置文件路径(绝对路径)。 */
14
- configPath: string;
26
+ /** 实例扩展目录(绝对路径),prepare-extension 生成的 unpacked 扩展落点。 */
27
+ extensionDir: string;
28
+ /** Chrome 可执行文件路径(可选,未指定交给 browserd 自动探测)。 */
29
+ chromePath?: string;
30
+ /** 路由模式。第一版多实例只走 cdp;auto/extension 由 browserd 内部决策。 */
31
+ routeMode?: RouteMode;
15
32
  }
16
- /** 默认端口常量。 */
17
- export declare const DEFAULT_RPC_PORT = 17322;
18
- export declare const DEFAULT_HEALTH_PORT = 17440;
19
- /** CLI 传入的覆盖项(全部可选,未传则按优先级回退)。 */
33
+ /** CLI 高级覆盖项(覆盖配置文件里某实例的字段)。 */
20
34
  export interface CliOverrides {
21
35
  rpcPort?: number;
22
- /** CLI 的 --port 别名(语义同 rpcPort:client 连接的 RPC 端口)。 */
36
+ /** CLI 的 --port 别名(语义同 rpcPort)。 */
23
37
  port?: number;
24
38
  healthPort?: number;
25
- profile?: string;
39
+ extensionPort?: number;
40
+ profileDir?: string;
41
+ stateDir?: string;
42
+ logsDir?: string;
43
+ extensionDir?: string;
26
44
  chromePath?: string;
27
- configPath?: string;
45
+ routeMode?: RouteMode;
28
46
  }
29
- /** 跨平台 app-data 根目录(不含 mooncat-browser 子目录)。 */
30
- export declare function appDataRoot(): string;
31
- /** mooncat-browser 的数据根目录:<appDataRoot>/mooncat-browser。 */
32
- export declare function appDataDir(): string;
33
- /** 默认配置文件路径。 */
34
- export declare function defaultConfigPath(): string;
35
- /** 默认 profile(user-data-dir)路径。 */
36
- export declare function defaultProfile(): string;
37
- /** 默认日志目录。 */
38
- export declare function defaultLogsDir(): string;
39
- interface RawConfigFile {
47
+ /** 配置文件里单个实例的原始字段(全部可选,缺字段由 init 期已写齐)。 */
48
+ export interface RawInstance {
40
49
  rpcPort?: number;
41
50
  healthPort?: number;
42
- profile?: string;
51
+ extensionPort?: number;
52
+ profileDir?: string;
53
+ stateDir?: string;
54
+ logsDir?: string;
55
+ extensionDir?: string;
43
56
  chromePath?: string;
57
+ routeMode?: RouteMode;
58
+ }
59
+ /** 项目配置文件整体 shape。 */
60
+ export interface ProjectConfigFile {
61
+ /** 实例表,key = 实例名。 */
62
+ instances: Record<string, RawInstance>;
44
63
  }
45
- /** 读取配置文件(不存在返回空对象;解析失败返回空对象并打印警告到 stderr)。 */
46
- export declare function loadConfigFile(path: string): RawConfigFile;
64
+ /** 项目级配置文件候选名(在项目根下查找)。 */
65
+ export declare const CONFIG_FILE_NAMES: readonly ["mooncat-browser.config.json", "config/browser.json"];
66
+ /** 读取并解析项目配置文件。不存在返回 null;解析失败抛错。 */
67
+ export declare function loadProjectConfig(path: string): ProjectConfigFile | null;
47
68
  /**
48
- * 解析最终配置。优先级:cli > env > configFile > default
49
- *
50
- * @param cli CLI 覆盖项(可选)
51
- * @param configPathHint 配置文件路径提示(默认走 defaultConfigPath)
69
+ * 把"配置文件里某实例 + CLI 覆盖"合并成一份完整的 BrowserInstanceConfig
70
+ * 不做全局兜底:文件里没填、CLI 也没给的字段,用 DEFAULT_* 填(保证总能装出一个实例)。
71
+ * 相对路径基于 projectRoot 解析成绝对路径。
52
72
  */
53
- export declare function resolveConfig(cli?: CliOverrides, configPathHint?: string): ResolvedConfig;
73
+ export declare function resolveInstance(name: string, raw: RawInstance | null | undefined, cli: CliOverrides, projectRoot: string): BrowserInstanceConfig;
74
+ /** 确保实例的数据目录存在(profile/state/logs 父目录)。 */
75
+ export declare function ensureInstanceDirs(cfg: BrowserInstanceConfig): void;
54
76
  /**
55
- * 把解析后的配置翻译成 browserd 子进程需要的环境变量。
56
- * browserd.cjs 原生读取:BROWSERD_PORT / BROWSER_OP_USERDATA / BROWSER_OP_CHROME_PATH。
57
- * 这里做一次语义桥接,避免改动 browserd 核心。
77
+ * 把解析后的实例配置翻译成 browserd 子进程的环境变量。
78
+ * browserd.cjs 原生读取 BROWSERD_PORT / BROWSER_OP_USERDATA / BROWSER_OP_CHROME_PATH。
79
+ * 多实例下加 BROWSER_OP_WS_PORT(extension WS 端口)+ BROWSER_OP_EXTENSION_DIR(实例扩展目录)。
58
80
  */
59
- export declare function browserdEnv(cfg: ResolvedConfig): Record<string, string>;
60
- export {};
81
+ export declare function browserdEnv(cfg: BrowserInstanceConfig): Record<string, string>;
61
82
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAqBA,iBAAiB;AACjB,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,cAAc;AACd,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AACtC,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,kCAAkC;AAClC,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gDAAgD;AAChD,wBAAgB,WAAW,IAAI,MAAM,CAUpC;AAED,4DAA4D;AAC5D,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,gBAAgB;AAChB,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,mCAAmC;AACnC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,cAAc;AACd,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,+CAA+C;AAC/C,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAU1D;AAeD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,GAAE,YAAiB,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,cAAc,CAmC7F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQvE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AACtC,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AACzC,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C,8CAA8C;AAC9C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,aAAa,EAAE,MAAM,CAAC;IACtB,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,gCAAgC;AAChC,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,sBAAsB;AACtB,MAAM,WAAW,iBAAiB;IAChC,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACxC;AAED,2BAA2B;AAC3B,eAAO,MAAM,iBAAiB,iEAAkE,CAAC;AAEjG,qCAAqC;AACrC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAexE;AAoBD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,EACnC,GAAG,EAAE,YAAY,EACjB,WAAW,EAAE,MAAM,GAClB,qBAAqB,CAmDvB;AAED,2CAA2C;AAC3C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAQnE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAY9E"}
package/dist/config.js CHANGED
@@ -1,66 +1,37 @@
1
1
  // -*- coding: utf-8 -*-
2
- // config.ts — @mooncat/browser 配置解析。
2
+ // config.ts — @mooncat/browser 实例配置。
3
3
  //
4
- // 优先级(高 -> 低):CLI 参数 > 环境变量 > 配置文件 > 默认值。
4
+ // mooncat-browser 是独立包:不写全局 appData,不假设 mooncat space 目录。
5
+ // 所有运行数据(profile/state/logs)由项目配置显式声明,见 instance.ts 的查找逻辑。
5
6
  //
6
- // 环境变量:
7
- // MOONCAT_BROWSERD_PORT browserd RPC 端口(client 连这里,默认 17322)
8
- // MOONCAT_BROWSER_PORT 服务包装层 health 端口(默认 17440)
9
- // MOONCAT_BROWSER_PROFILE Chrome user-data-dir(默认 <appData>/mooncat-browser/profile)
10
- // MOONCAT_BROWSER_CHROME Chrome 可执行文件路径(可选,不传则自动探测)
11
- //
12
- // 配置文件(JSON):
13
- // Windows: %LOCALAPPDATA%\mooncat-browser\config.json
14
- // macOS: ~/Library/Application Support/mooncat-browser/config.json
15
- // Linux: $XDG_DATA_HOME/mooncat-browser/config.json (~/.local/share/...)
16
- // 可用 MOONCAT_BROWSER_CONFIG 覆盖路径。
7
+ // 配置优先级(单实例内):CLI 高级覆盖 > 配置文件该实例 > 报错(无全局兜底)。
17
8
  import { existsSync, mkdirSync, readFileSync } from "node:fs";
18
- import { dirname, join } from "node:path";
19
- import { homedir, platform } from "node:os";
20
- /** 默认端口常量。 */
9
+ import { join, resolve } from "node:path";
10
+ /** 端口默认值(仅在 init 生成配置 / --temp 时使用,不作为运行时兜底)。 */
21
11
  export const DEFAULT_RPC_PORT = 17322;
22
12
  export const DEFAULT_HEALTH_PORT = 17440;
23
- /** 跨平台 app-data 根目录(不含 mooncat-browser 子目录)。 */
24
- export function appDataRoot() {
25
- const p = platform();
26
- if (p === "win32") {
27
- return process.env.LOCALAPPDATA || join(homedir(), "AppData", "Local");
28
- }
29
- if (p === "darwin") {
30
- return join(homedir(), "Library", "Application Support");
31
- }
32
- // linux / 其它:XDG_DATA_HOME 或 ~/.local/share
33
- return process.env.XDG_DATA_HOME || join(homedir(), ".local", "share");
34
- }
35
- /** mooncat-browser 的数据根目录:<appDataRoot>/mooncat-browser。 */
36
- export function appDataDir() {
37
- return join(appDataRoot(), "mooncat-browser");
38
- }
39
- /** 默认配置文件路径。 */
40
- export function defaultConfigPath() {
41
- return process.env.MOONCAT_BROWSER_CONFIG || join(appDataDir(), "config.json");
42
- }
43
- /** 默认 profile(user-data-dir)路径。 */
44
- export function defaultProfile() {
45
- return join(appDataDir(), "profile");
46
- }
47
- /** 默认日志目录。 */
48
- export function defaultLogsDir() {
49
- return join(appDataDir(), "logs");
50
- }
51
- /** 读取配置文件(不存在返回空对象;解析失败返回空对象并打印警告到 stderr)。 */
52
- export function loadConfigFile(path) {
13
+ export const DEFAULT_EXTENSION_PORT = 17321;
14
+ /** 项目级配置文件候选名(在项目根下查找) */
15
+ export const CONFIG_FILE_NAMES = ["mooncat-browser.config.json", "config/browser.json"];
16
+ /** 读取并解析项目配置文件。不存在返回 null;解析失败抛错。 */
17
+ export function loadProjectConfig(path) {
53
18
  if (!path || !existsSync(path))
54
- return {};
19
+ return null;
20
+ const raw = readFileSync(path, "utf8");
21
+ let obj;
55
22
  try {
56
- const raw = readFileSync(path, "utf8");
57
- const obj = JSON.parse(raw);
58
- return obj && typeof obj === "object" ? obj : {};
23
+ obj = JSON.parse(raw);
59
24
  }
60
25
  catch (e) {
61
- console.error(`[mooncat-browser] config file parse failed (${path}): ${e.message}`);
62
- return {};
26
+ throw new Error(`config file parse failed (${path}): ${e.message}`);
27
+ }
28
+ if (!obj || typeof obj !== "object")
29
+ return null;
30
+ const file = obj;
31
+ if (!file.instances || typeof file.instances !== "object") {
32
+ throw new Error(`config file missing "instances" object (${path})`);
63
33
  }
34
+ return file;
64
35
  }
65
36
  function firstDefined(...vals) {
66
37
  for (const v of vals) {
@@ -75,45 +46,70 @@ function toPort(v, fallback) {
75
46
  return Math.floor(n);
76
47
  return fallback;
77
48
  }
49
+ function toAbs(unknown, projectRoot, fallback) {
50
+ const p = typeof unknown === "string" ? unknown : fallback;
51
+ return resolve(projectRoot, p);
52
+ }
78
53
  /**
79
- * 解析最终配置。优先级:cli > env > configFile > default
80
- *
81
- * @param cli CLI 覆盖项(可选)
82
- * @param configPathHint 配置文件路径提示(默认走 defaultConfigPath)
54
+ * 把"配置文件里某实例 + CLI 覆盖"合并成一份完整的 BrowserInstanceConfig
55
+ * 不做全局兜底:文件里没填、CLI 也没给的字段,用 DEFAULT_* 填(保证总能装出一个实例)。
56
+ * 相对路径基于 projectRoot 解析成绝对路径。
83
57
  */
84
- export function resolveConfig(cli = {}, configPathHint) {
85
- const configPath = configPathHint || cli.configPath || defaultConfigPath();
86
- const file = loadConfigFile(configPath);
87
- // rpcPort:cli.port cli.rpcPort 的别名(--port 语义)
88
- const rpcPort = toPort(firstDefined(cli.rpcPort, cli.port, process.env.MOONCAT_BROWSERD_PORT, file.rpcPort), DEFAULT_RPC_PORT);
89
- const healthPort = toPort(firstDefined(cli.healthPort, process.env.MOONCAT_BROWSER_PORT, file.healthPort), DEFAULT_HEALTH_PORT);
90
- const profile = firstDefined(cli.profile, process.env.MOONCAT_BROWSER_PROFILE, file.profile) || defaultProfile();
91
- const chromePath = firstDefined(cli.chromePath, process.env.MOONCAT_BROWSER_CHROME, file.chromePath);
92
- const logsDir = defaultLogsDir();
93
- // 确保数据目录存在(profile/logs 父目录)
94
- for (const dir of [appDataDir(), dirname(profile), logsDir]) {
58
+ export function resolveInstance(name, raw, cli, projectRoot) {
59
+ const rpcPort = toPort(firstDefined(cli.rpcPort, cli.port, raw?.rpcPort), DEFAULT_RPC_PORT);
60
+ const healthPort = toPort(firstDefined(cli.healthPort, raw?.healthPort), DEFAULT_HEALTH_PORT);
61
+ const extensionPort = toPort(firstDefined(cli.extensionPort, raw?.extensionPort), DEFAULT_EXTENSION_PORT);
62
+ // 相对路径基于项目根。若文件/CLI 都没给,落到 <projectRoot>/.browser/<name>/... (init 期默认值)
63
+ const baseFallback = join(".browser", name);
64
+ const profileDir = toAbs(firstDefined(cli.profileDir, raw?.profileDir), projectRoot, join(baseFallback, "profile"));
65
+ const stateDir = toAbs(firstDefined(cli.stateDir, raw?.stateDir), projectRoot, join(baseFallback, "state"));
66
+ const logsDir = toAbs(firstDefined(cli.logsDir, raw?.logsDir), projectRoot, join(baseFallback, "logs"));
67
+ // 实例扩展目录:prepare-extension 把包内 dist copy 到这里 + 换端口。
68
+ const extensionDir = toAbs(firstDefined(cli.extensionDir, raw?.extensionDir), projectRoot, join(baseFallback, "extension"));
69
+ const chromePath = firstDefined(cli.chromePath, raw?.chromePath);
70
+ const routeMode = firstDefined(cli.routeMode, raw?.routeMode);
71
+ return {
72
+ name,
73
+ rpcPort,
74
+ healthPort,
75
+ extensionPort,
76
+ profileDir,
77
+ stateDir,
78
+ logsDir,
79
+ extensionDir,
80
+ chromePath,
81
+ routeMode,
82
+ };
83
+ }
84
+ /** 确保实例的数据目录存在(profile/state/logs 父目录)。 */
85
+ export function ensureInstanceDirs(cfg) {
86
+ for (const dir of [cfg.profileDir, cfg.stateDir, cfg.logsDir]) {
95
87
  try {
96
88
  mkdirSync(dir, { recursive: true });
97
89
  }
98
90
  catch {
99
- /* 忽略:并发创建或权限问题,后续 IO 自行报错 */
91
+ /* 并发创建或权限问题,后续 IO 自行报错 */
100
92
  }
101
93
  }
102
- return { rpcPort, healthPort, profile, chromePath, logsDir, configPath };
103
94
  }
104
95
  /**
105
- * 把解析后的配置翻译成 browserd 子进程需要的环境变量。
106
- * browserd.cjs 原生读取:BROWSERD_PORT / BROWSER_OP_USERDATA / BROWSER_OP_CHROME_PATH。
107
- * 这里做一次语义桥接,避免改动 browserd 核心。
96
+ * 把解析后的实例配置翻译成 browserd 子进程的环境变量。
97
+ * browserd.cjs 原生读取 BROWSERD_PORT / BROWSER_OP_USERDATA / BROWSER_OP_CHROME_PATH。
98
+ * 多实例下加 BROWSER_OP_WS_PORT(extension WS 端口)+ BROWSER_OP_EXTENSION_DIR(实例扩展目录)。
108
99
  */
109
100
  export function browserdEnv(cfg) {
110
101
  const env = {
111
102
  BROWSERD_PORT: String(cfg.rpcPort),
112
103
  IPC_PORT: String(cfg.rpcPort), // browserd 旧名兼容
113
- BROWSER_OP_USERDATA: cfg.profile,
104
+ BROWSER_OP_USERDATA: cfg.profileDir,
105
+ BROWSER_OP_INSTANCE_NAME: cfg.name,
106
+ BROWSER_OP_WS_PORT: String(cfg.extensionPort),
107
+ BROWSER_OP_EXTENSION_DIR: cfg.extensionDir,
114
108
  };
115
109
  if (cfg.chromePath)
116
110
  env.BROWSER_OP_CHROME_PATH = cfg.chromePath;
111
+ if (cfg.routeMode)
112
+ env.BROWSER_OP_ROUTE_MODE = cfg.routeMode;
117
113
  return env;
118
114
  }
119
115
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import { BrowserInstanceConfig, CliOverrides, ProjectConfigFile } from "./config.js";
2
+ /** 未初始化错误(命令层捕获后输出友好提示并退出)。 */
3
+ export declare class NotInitializedError extends Error {
4
+ searchedFrom: string;
5
+ constructor(searchedFrom: string);
6
+ }
7
+ /** 找不到某实例名错误。 */
8
+ export declare class InstanceNotFoundError extends Error {
9
+ name: string;
10
+ available: string[];
11
+ constructor(name: string, available: string[]);
12
+ }
13
+ /** 项目配置查找结果。 */
14
+ export interface ProjectConfigHandle {
15
+ /** 配置文件绝对路径。 */
16
+ configPath: string;
17
+ /** 配置文件所在目录视为项目根(相对路径以此解析)。 */
18
+ projectRoot: string;
19
+ /** 解析后的配置对象。 */
20
+ config: ProjectConfigFile;
21
+ }
22
+ /**
23
+ * 从 startDir 向上递归查找项目配置。
24
+ * 候选名:mooncat-browser.config.json,然后 config/browser.json(同一目录两级)。
25
+ * 找不到抛 NotInitializedError。
26
+ */
27
+ export declare function findProjectConfig(startDir: string): ProjectConfigHandle;
28
+ /** 列出配置里所有实例名。 */
29
+ export declare function listInstanceNames(handle: ProjectConfigHandle): string[];
30
+ /**
31
+ * 加载指定实例:从配置读 raw + 合 CLI 覆盖 + 解析成 BrowserInstanceConfig。
32
+ * 实例不存在抛 InstanceNotFoundError。
33
+ * 同时确保数据目录存在。
34
+ */
35
+ export declare function loadInstance(name: string, handle: ProjectConfigHandle, cli?: CliOverrides): BrowserInstanceConfig;
36
+ /**
37
+ * 生成 --temp 临时实例:在系统 temp 下建随机目录,用默认端口。
38
+ * 不读项目配置,不留登录态,退出时由调用方清理。
39
+ */
40
+ export declare function tempInstance(name?: string, cli?: CliOverrides): {
41
+ cfg: BrowserInstanceConfig;
42
+ cleanup: () => void;
43
+ };
44
+ /**
45
+ * init 生成默认实例配置对象(供 cli init 命令写入文件)。
46
+ * 默认实例名 default,数据落到 <projectRoot>/.browser/default/{profile,state,logs,extension}。
47
+ */
48
+ export declare function defaultInstanceEntry(name?: string): {
49
+ rpcPort: number;
50
+ healthPort: number;
51
+ extensionPort: number;
52
+ profileDir: string;
53
+ stateDir: string;
54
+ logsDir: string;
55
+ extensionDir: string;
56
+ };
57
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,qBAAqB,EACrB,YAAY,EAKZ,iBAAiB,EAIlB,MAAM,aAAa,CAAC;AAErB,+BAA+B;AAC/B,qBAAa,mBAAoB,SAAQ,KAAK;IACzB,YAAY,EAAE,MAAM;gBAApB,YAAY,EAAE,MAAM;CAWxC;AAED,iBAAiB;AACjB,qBAAa,qBAAsB,SAAQ,KAAK;IAC3B,IAAI,EAAE,MAAM;IAAS,SAAS,EAAE,MAAM,EAAE;gBAAxC,IAAI,EAAE,MAAM,EAAS,SAAS,EAAE,MAAM,EAAE;CAM5D;AAED,gBAAgB;AAChB,MAAM,WAAW,mBAAmB;IAClC,gBAAgB;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB;IAChB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAkBvE;AAED,kBAAkB;AAClB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,mBAAmB,EAC3B,GAAG,GAAE,YAAiB,GACrB,qBAAqB,CASvB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,SAAS,EAAE,GAAG,GAAE,YAAiB,GAAG;IACnE,GAAG,EAAE,qBAAqB,CAAC;IAC3B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CA6BA;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,SAAY;;;;;;;;EAUpD"}
@@ -0,0 +1,128 @@
1
+ // -*- coding: utf-8 -*-
2
+ // instance.ts — 项目配置查找 + 实例加载。
3
+ //
4
+ // mooncat-browser 是独立包,运行必须基于项目配置:
5
+ // - 向上递归查找 mooncat-browser.config.json / config/browser.json
6
+ // - 找不到 → fail fast,提示 npx mooncat-browser init
7
+ // - 不写全局 appData,不在随机 cwd 偷建目录
8
+ //
9
+ // 唯一例外:start --temp 用系统 temp 下的随机目录,退出清理,仅供快速试用。
10
+ import { existsSync, mkdtempSync, rmSync } from "node:fs";
11
+ import { join, resolve, dirname } from "node:path";
12
+ import { tmpdir } from "node:os";
13
+ import { CONFIG_FILE_NAMES, DEFAULT_EXTENSION_PORT, DEFAULT_HEALTH_PORT, DEFAULT_RPC_PORT, ensureInstanceDirs, loadProjectConfig, resolveInstance, } from "./config.js";
14
+ /** 未初始化错误(命令层捕获后输出友好提示并退出)。 */
15
+ export class NotInitializedError extends Error {
16
+ searchedFrom;
17
+ constructor(searchedFrom) {
18
+ super(`mooncat-browser is not initialized in this project.\n\n` +
19
+ `Expected one of:\n` +
20
+ ` ./${CONFIG_FILE_NAMES[0]}\n` +
21
+ ` ./${CONFIG_FILE_NAMES[1]}\n\n` +
22
+ `Run:\n` +
23
+ ` npx mooncat-browser init`);
24
+ this.searchedFrom = searchedFrom;
25
+ this.name = "NotInitializedError";
26
+ }
27
+ }
28
+ /** 找不到某实例名错误。 */
29
+ export class InstanceNotFoundError extends Error {
30
+ name;
31
+ available;
32
+ constructor(name, available) {
33
+ super(`instance "${name}" not found in config. available: ${available.join(", ") || "(none)"}`);
34
+ this.name = name;
35
+ this.available = available;
36
+ this.name = "InstanceNotFoundError";
37
+ }
38
+ }
39
+ /**
40
+ * 从 startDir 向上递归查找项目配置。
41
+ * 候选名:mooncat-browser.config.json,然后 config/browser.json(同一目录两级)。
42
+ * 找不到抛 NotInitializedError。
43
+ */
44
+ export function findProjectConfig(startDir) {
45
+ let dir = resolve(startDir);
46
+ // 向上递归到文件系统根
47
+ for (;;) {
48
+ for (const name of CONFIG_FILE_NAMES) {
49
+ const p = join(dir, name);
50
+ if (existsSync(p)) {
51
+ const config = loadProjectConfig(p);
52
+ if (config) {
53
+ return { configPath: p, projectRoot: dir, config };
54
+ }
55
+ }
56
+ }
57
+ const parent = dirname(dir);
58
+ if (parent === dir)
59
+ break; // 到根了
60
+ dir = parent;
61
+ }
62
+ throw new NotInitializedError(startDir);
63
+ }
64
+ /** 列出配置里所有实例名。 */
65
+ export function listInstanceNames(handle) {
66
+ return Object.keys(handle.config.instances);
67
+ }
68
+ /**
69
+ * 加载指定实例:从配置读 raw + 合 CLI 覆盖 + 解析成 BrowserInstanceConfig。
70
+ * 实例不存在抛 InstanceNotFoundError。
71
+ * 同时确保数据目录存在。
72
+ */
73
+ export function loadInstance(name, handle, cli = {}) {
74
+ const names = listInstanceNames(handle);
75
+ if (!(name in handle.config.instances)) {
76
+ throw new InstanceNotFoundError(name, names);
77
+ }
78
+ const raw = handle.config.instances[name];
79
+ const cfg = resolveInstance(name, raw, cli, handle.projectRoot);
80
+ ensureInstanceDirs(cfg);
81
+ return cfg;
82
+ }
83
+ /**
84
+ * 生成 --temp 临时实例:在系统 temp 下建随机目录,用默认端口。
85
+ * 不读项目配置,不留登录态,退出时由调用方清理。
86
+ */
87
+ export function tempInstance(name = "temp", cli = {}) {
88
+ const root = mkdtempSync(join(tmpdir(), `mooncat-browser-`));
89
+ const cfg = resolveInstance(name, {
90
+ rpcPort: DEFAULT_RPC_PORT,
91
+ healthPort: DEFAULT_HEALTH_PORT,
92
+ extensionPort: DEFAULT_EXTENSION_PORT,
93
+ profileDir: join(root, "profile"),
94
+ stateDir: join(root, "state"),
95
+ logsDir: join(root, "logs"),
96
+ // temp 不走 extension 路(临时试用,无扩展)。extensionDir 给一个占位路径,
97
+ // 用户不显式 prepare-extension 就不会用到。
98
+ extensionDir: join(root, "extension"),
99
+ }, cli, root);
100
+ ensureInstanceDirs(cfg);
101
+ return {
102
+ cfg,
103
+ cleanup: () => {
104
+ try {
105
+ rmSync(root, { recursive: true, force: true });
106
+ }
107
+ catch {
108
+ /* 临时目录清理失败不阻塞 */
109
+ }
110
+ },
111
+ };
112
+ }
113
+ /**
114
+ * init 生成默认实例配置对象(供 cli init 命令写入文件)。
115
+ * 默认实例名 default,数据落到 <projectRoot>/.browser/default/{profile,state,logs,extension}。
116
+ */
117
+ export function defaultInstanceEntry(name = "default") {
118
+ return {
119
+ rpcPort: DEFAULT_RPC_PORT,
120
+ healthPort: DEFAULT_HEALTH_PORT,
121
+ extensionPort: DEFAULT_EXTENSION_PORT,
122
+ profileDir: `.browser/${name}/profile`,
123
+ stateDir: `.browser/${name}/state`,
124
+ logsDir: `.browser/${name}/logs`,
125
+ extensionDir: `.browser/${name}/extension`,
126
+ };
127
+ }
128
+ //# sourceMappingURL=instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.js","sourceRoot":"","sources":["../src/instance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { BrowserInstanceConfig } from "./config.js";
2
+ /** 源码 offscreen/main.ts 里的占位符,wxt build 保留字符串字面量。 */
3
+ export declare const HOST_WS_URL_PLACEHOLDER = "__MOONCAT_BROWSER_HOST_WS_URL__";
4
+ /** 包内 webplater 扩展模板目录。dist/cli.js -> ../../browser-op/webplater/dist/chrome-mv3。 */
5
+ export declare function extensionTemplateDir(): string;
6
+ /** 实例扩展目录内的 metadata 文件名。 */
7
+ export declare const METADATA_FILENAME = ".mooncat-instance.json";
8
+ /** metadata 结构。 */
9
+ export interface InstanceExtensionMetadata {
10
+ instance: string;
11
+ extensionPort: number;
12
+ hostWsUrl: string;
13
+ generatedAt: string;
14
+ /** 模板来源的 manifest version(用于检测包升级后需要重 prepare)。 */
15
+ sourceBuildVersion: string;
16
+ }
17
+ /**
18
+ * 为实例生成 unpacked 扩展目录。
19
+ *
20
+ * 步骤:rm 旧目录 → mkdir → copy 模板 → 替换占位符 → 写 metadata。
21
+ * 幂等:重复调用会清空重建。
22
+ *
23
+ * @returns 被替换占位符的文件数 + metadata
24
+ */
25
+ export declare function prepareExtension(cfg: BrowserInstanceConfig): {
26
+ replacedFiles: number;
27
+ metadata: InstanceExtensionMetadata;
28
+ templateDir: string;
29
+ };
30
+ /** 读实例 extensionDir 的 metadata。不存在返回 null。 */
31
+ export declare function readInstanceMetadata(cfg: BrowserInstanceConfig): InstanceExtensionMetadata | null;
32
+ /**
33
+ * 校验实例 extensionDir 是否就绪(用于 start --route extension 前置检查)。
34
+ * 返回 null 表示就绪;返回字符串表示需要重 prepare 的原因。
35
+ */
36
+ export declare function verifyInstanceExtension(cfg: BrowserInstanceConfig): string | null;
37
+ //# sourceMappingURL=prepare-extension.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepare-extension.d.ts","sourceRoot":"","sources":["../src/prepare-extension.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAIzD,qDAAqD;AACrD,eAAO,MAAM,uBAAuB,oCAAoC,CAAC;AAEzE,qFAAqF;AACrF,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED,6BAA6B;AAC7B,eAAO,MAAM,iBAAiB,2BAA2B,CAAC;AAE1D,mBAAmB;AACnB,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAoCD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,yBAAyB,CAAC;IACpC,WAAW,EAAE,MAAM,CAAC;CACrB,CA8CA;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,qBAAqB,GAAG,yBAAyB,GAAG,IAAI,CAQjG;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAwBjF"}