@hangox/mg-cli 1.5.0 → 1.5.2
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/cli.js +219 -32
- package/dist/cli.js.map +1 -1
- package/dist/native-host.js +5329 -140
- package/dist/native-host.js.map +1 -1
- package/dist/postinstall.js +89 -8
- package/dist/postinstall.js.map +1 -1
- package/package.json +1 -1
package/dist/postinstall.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
#!/usr/bin/env node
|
|
3
3
|
|
|
4
|
+
// src/scripts/postinstall.ts
|
|
5
|
+
import { pathToFileURL } from "url";
|
|
6
|
+
|
|
4
7
|
// src/scripts/register-utils.ts
|
|
5
8
|
import fs from "fs";
|
|
6
9
|
import path from "path";
|
|
@@ -61,11 +64,50 @@ function getNativeHostPath() {
|
|
|
61
64
|
const distDir = path.dirname(currentFile);
|
|
62
65
|
return path.join(distDir, "native-host.js");
|
|
63
66
|
}
|
|
64
|
-
|
|
67
|
+
var INSTALL_DIR_NAME = "mg-cli";
|
|
68
|
+
function getInstallDir() {
|
|
69
|
+
const home = os.homedir();
|
|
70
|
+
if (os.platform() === "win32") {
|
|
71
|
+
const appData = process.env.APPDATA || path.join(home, "AppData/Roaming");
|
|
72
|
+
return path.join(appData, INSTALL_DIR_NAME);
|
|
73
|
+
}
|
|
74
|
+
return path.join(home, ".config", INSTALL_DIR_NAME);
|
|
75
|
+
}
|
|
76
|
+
var WRAPPER_FILENAME_UNIX = "native-host-wrapper.sh";
|
|
77
|
+
var WRAPPER_FILENAME_WIN = "native-host-wrapper.cmd";
|
|
78
|
+
function getWrapperPath(installDir) {
|
|
79
|
+
const filename = os.platform() === "win32" ? WRAPPER_FILENAME_WIN : WRAPPER_FILENAME_UNIX;
|
|
80
|
+
return path.join(installDir, filename);
|
|
81
|
+
}
|
|
82
|
+
function ensureNativeHostWrapper(sourceNativeHostPath) {
|
|
83
|
+
const installDir = getInstallDir();
|
|
84
|
+
fs.mkdirSync(installDir, { recursive: true });
|
|
85
|
+
const installedNativeHostPath = path.join(installDir, "native-host.js");
|
|
86
|
+
fs.copyFileSync(sourceNativeHostPath, installedNativeHostPath);
|
|
87
|
+
const wrapperPath = getWrapperPath(installDir);
|
|
88
|
+
if (os.platform() === "win32") {
|
|
89
|
+
const wrapperContent2 = `@echo off\r
|
|
90
|
+
"${process.execPath}" "${installedNativeHostPath}" %*\r
|
|
91
|
+
`;
|
|
92
|
+
fs.writeFileSync(wrapperPath, wrapperContent2);
|
|
93
|
+
return wrapperPath;
|
|
94
|
+
}
|
|
95
|
+
const wrapperContent = `#!/bin/sh
|
|
96
|
+
exec "${process.execPath}" "${installedNativeHostPath}" "$@"
|
|
97
|
+
`;
|
|
98
|
+
fs.writeFileSync(wrapperPath, wrapperContent);
|
|
99
|
+
try {
|
|
100
|
+
fs.chmodSync(wrapperPath, "755");
|
|
101
|
+
} catch {
|
|
102
|
+
console.warn(" \u26A0\uFE0F \u65E0\u6CD5\u8BBE\u7F6E wrapper \u6267\u884C\u6743\u9650\uFF0C\u53EF\u80FD\u9700\u8981\u624B\u52A8\u8BBE\u7F6E");
|
|
103
|
+
}
|
|
104
|
+
return wrapperPath;
|
|
105
|
+
}
|
|
106
|
+
function createManifest(hostPath) {
|
|
65
107
|
return {
|
|
66
108
|
name: HOST_NAME,
|
|
67
109
|
description: DESCRIPTION,
|
|
68
|
-
path:
|
|
110
|
+
path: hostPath,
|
|
69
111
|
type: "stdio",
|
|
70
112
|
allowed_origins: [`chrome-extension://${EXTENSION_ID}/`]
|
|
71
113
|
};
|
|
@@ -73,7 +115,9 @@ function createManifest() {
|
|
|
73
115
|
function register(browser = "chrome") {
|
|
74
116
|
const config = getBrowserPaths(browser);
|
|
75
117
|
const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`);
|
|
76
|
-
const
|
|
118
|
+
const nativeHostPath = getNativeHostPath();
|
|
119
|
+
const wrapperPath = ensureNativeHostWrapper(nativeHostPath);
|
|
120
|
+
const manifest = createManifest(wrapperPath);
|
|
77
121
|
console.log("\u6B63\u5728\u6CE8\u518C Native Messaging Host...");
|
|
78
122
|
console.log(` Host Name: ${HOST_NAME}`);
|
|
79
123
|
console.log(` Extension ID: ${EXTENSION_ID}`);
|
|
@@ -101,14 +145,26 @@ function register(browser = "chrome") {
|
|
|
101
145
|
}
|
|
102
146
|
console.log("\u2713 Native Messaging Host \u6CE8\u518C\u6210\u529F");
|
|
103
147
|
}
|
|
148
|
+
function registerAll(browsers) {
|
|
149
|
+
return browsers.map((browser) => {
|
|
150
|
+
try {
|
|
151
|
+
register(browser);
|
|
152
|
+
return { browser, success: true };
|
|
153
|
+
} catch (error) {
|
|
154
|
+
return { browser, success: false, error: error instanceof Error ? error.message : String(error) };
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
104
158
|
|
|
105
159
|
// src/scripts/postinstall.ts
|
|
106
|
-
|
|
160
|
+
var DEFAULT_BROWSERS = ["chrome", "chromium"];
|
|
161
|
+
function isGlobalInstall(dirnameOverride) {
|
|
107
162
|
if (process.env.npm_config_global === "true") return true;
|
|
163
|
+
const dir = dirnameOverride ?? __dirname;
|
|
108
164
|
const pnpmPatterns = ["/pnpm/global/", "/.local/share/pnpm/", "/pnpm-global/"];
|
|
109
|
-
if (pnpmPatterns.some((p) =>
|
|
165
|
+
if (pnpmPatterns.some((p) => dir.includes(p))) return true;
|
|
110
166
|
const yarnPatterns = ["/.config/yarn/global/", "/yarn/global/"];
|
|
111
|
-
if (yarnPatterns.some((p) =>
|
|
167
|
+
if (yarnPatterns.some((p) => dir.includes(p))) return true;
|
|
112
168
|
return false;
|
|
113
169
|
}
|
|
114
170
|
function main() {
|
|
@@ -120,13 +176,38 @@ function main() {
|
|
|
120
176
|
console.log("[mg-cli] \u68C0\u6D4B\u5230\u5168\u5C40\u5B89\u88C5\uFF0C\u5F00\u59CB\u6CE8\u518C Native Messaging Host...");
|
|
121
177
|
console.log(`[mg-cli] Host Name: ${HOST_NAME}`);
|
|
122
178
|
console.log(`[mg-cli] Extension ID: ${EXTENSION_ID}`);
|
|
179
|
+
console.log(`[mg-cli] \u6D4F\u89C8\u5668: ${DEFAULT_BROWSERS.join(", ")}`);
|
|
123
180
|
try {
|
|
124
|
-
|
|
181
|
+
const results = registerAll(DEFAULT_BROWSERS);
|
|
182
|
+
for (const r of results) {
|
|
183
|
+
if (r.success) {
|
|
184
|
+
console.log(`[mg-cli] \u2713 ${r.browser} \u6CE8\u518C\u6210\u529F`);
|
|
185
|
+
} else {
|
|
186
|
+
console.warn(`[mg-cli] \u2717 ${r.browser} \u6CE8\u518C\u5931\u8D25: ${r.error}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (results.every((r) => !r.success)) {
|
|
190
|
+
console.log("\n[mg-cli] \u8BF7\u624B\u52A8\u8FD0\u884C: npx @hangox/mg-cli register");
|
|
191
|
+
}
|
|
125
192
|
} catch (error) {
|
|
126
193
|
console.error("[mg-cli] Native Host \u6CE8\u518C\u5931\u8D25:", error);
|
|
127
194
|
console.log("\n[mg-cli] \u8BF7\u624B\u52A8\u8FD0\u884C: npx @hangox/mg-cli register");
|
|
195
|
+
} finally {
|
|
128
196
|
process.exitCode = 0;
|
|
129
197
|
}
|
|
130
198
|
}
|
|
131
|
-
|
|
199
|
+
var isDirectlyExecuted = (() => {
|
|
200
|
+
try {
|
|
201
|
+
return import.meta.url === pathToFileURL(process.argv[1] ?? "").href;
|
|
202
|
+
} catch {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
})();
|
|
206
|
+
if (isDirectlyExecuted) {
|
|
207
|
+
main();
|
|
208
|
+
}
|
|
209
|
+
export {
|
|
210
|
+
isGlobalInstall,
|
|
211
|
+
main
|
|
212
|
+
};
|
|
132
213
|
//# sourceMappingURL=postinstall.js.map
|
package/dist/postinstall.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/scripts/register-utils.ts","../src/scripts/postinstall.ts"],"sourcesContent":["/**\n * Native Messaging Host 注册辅助函数\n * 支持 macOS, Linux, Windows\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { execSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\n\n// ==================== 配置常量 ====================\n\nexport const HOST_NAME = 'com.hangox.mgplugin'\nexport const EXTENSION_ID = 'ddhihanlpcdneicohnglnaliefnkaeja'\nconst DESCRIPTION = 'MasterGo Plugin Native Messaging Host'\n\n// ==================== 平台适配 ====================\n\ntype BrowserType = 'chrome' | 'chromium' | 'edge'\n\ninterface PlatformConfig {\n manifestDir: string\n registryKey?: string // Windows only\n}\n\nfunction getBrowserPaths(browser: BrowserType): PlatformConfig {\n const home = os.homedir()\n const platform = os.platform()\n\n const browserDirs: Record<BrowserType, Record<string, string>> = {\n chrome: {\n darwin: path.join(home, 'Library/Application Support/Google/Chrome/NativeMessagingHosts'),\n linux: path.join(home, '.config/google-chrome/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Google/Chrome/NativeMessagingHosts'\n ),\n },\n chromium: {\n darwin: path.join(home, 'Library/Application Support/Chromium/NativeMessagingHosts'),\n linux: path.join(home, '.config/chromium/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Chromium/NativeMessagingHosts'\n ),\n },\n edge: {\n darwin: path.join(\n home,\n 'Library/Application Support/Microsoft Edge/NativeMessagingHosts'\n ),\n linux: path.join(home, '.config/microsoft-edge/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Microsoft/Edge/NativeMessagingHosts'\n ),\n },\n }\n\n const registryKeys: Record<BrowserType, string> = {\n chrome: `HKCU\\\\Software\\\\Google\\\\Chrome\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n chromium: `HKCU\\\\Software\\\\Chromium\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n edge: `HKCU\\\\Software\\\\Microsoft\\\\Edge\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n }\n\n const manifestDir = browserDirs[browser][platform]\n if (!manifestDir) {\n throw new Error(`不支持的平台: ${platform}`)\n }\n\n return {\n manifestDir,\n registryKey: platform === 'win32' ? registryKeys[browser] : undefined,\n }\n}\n\n// ==================== Manifest 生成 ====================\n\nfunction getNativeHostPath(): string {\n // 获取当前文件位置,推算 native-host 入口\n const currentFile = fileURLToPath(import.meta.url)\n const distDir = path.dirname(currentFile)\n return path.join(distDir, 'native-host.js')\n}\n\nfunction createManifest(): { name: string; description: string; path: string; type: string; allowed_origins: string[] } {\n return {\n name: HOST_NAME,\n description: DESCRIPTION,\n path: getNativeHostPath(),\n type: 'stdio',\n allowed_origins: [`chrome-extension://${EXTENSION_ID}/`],\n }\n}\n\n// ==================== 注册逻辑 ====================\n\nexport function register(browser: BrowserType = 'chrome'): void {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n const manifest = createManifest()\n\n console.log('正在注册 Native Messaging Host...')\n console.log(` Host Name: ${HOST_NAME}`)\n console.log(` Extension ID: ${EXTENSION_ID}`)\n console.log(` Browser: ${browser}`)\n console.log(` Native Host: ${manifest.path}`)\n console.log(` Manifest: ${manifestPath}`)\n\n // 1. 确保目录存在\n fs.mkdirSync(config.manifestDir, { recursive: true })\n\n // 2. 写入 manifest\n fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))\n\n // 3. 设置执行权限 (Unix)\n if (os.platform() !== 'win32') {\n try {\n fs.chmodSync(manifest.path, '755')\n } catch {\n console.warn(' ⚠️ 无法设置执行权限,可能需要手动设置')\n }\n }\n\n // 4. Windows: 写入注册表\n if (config.registryKey) {\n try {\n execSync(`reg add \"${config.registryKey}\" /ve /t REG_SZ /d \"${manifestPath}\" /f`, {\n stdio: 'pipe',\n })\n console.log(' ✓ Windows 注册表已更新')\n } catch {\n console.warn(' ⚠️ 注册表写入失败,可能需要管理员权限')\n }\n }\n\n console.log('✓ Native Messaging Host 注册成功')\n}\n\nexport function unregister(browser: BrowserType = 'chrome'): void {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n\n // 删除 manifest 文件\n if (fs.existsSync(manifestPath)) {\n fs.unlinkSync(manifestPath)\n console.log(` 已删除: ${manifestPath}`)\n }\n\n // Windows: 删除注册表项\n if (config.registryKey) {\n try {\n execSync(`reg delete \"${config.registryKey}\" /f`, { stdio: 'pipe' })\n console.log(' ✓ Windows 注册表项已删除')\n } catch {\n // 忽略不存在的情况\n }\n }\n}\n\nexport function checkRegistration(browser: BrowserType = 'chrome'): {\n registered: boolean\n manifestPath?: string\n manifest?: unknown\n} {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n\n if (!fs.existsSync(manifestPath)) {\n return { registered: false }\n }\n\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'))\n return {\n registered: true,\n manifestPath,\n manifest,\n }\n } catch {\n return { registered: false, manifestPath }\n }\n}\n","#!/usr/bin/env node\n/**\n * npm postinstall 脚本\n * 全局安装时自动注册 Native Messaging Host\n */\n\nimport { register, HOST_NAME, EXTENSION_ID } from './register-utils.js'\n\n// ==================== 入口 ====================\n\nfunction isGlobalInstall(): boolean {\n // npm 全局安装\n if (process.env.npm_config_global === 'true') return true\n\n // pnpm 全局安装检测\n const pnpmPatterns = ['/pnpm/global/', '/.local/share/pnpm/', '/pnpm-global/']\n if (pnpmPatterns.some((p) => __dirname.includes(p))) return true\n\n // yarn 全局安装检测\n const yarnPatterns = ['/.config/yarn/global/', '/yarn/global/']\n if (yarnPatterns.some((p) => __dirname.includes(p))) return true\n\n return false\n}\n\nfunction main(): void {\n // 仅全局安装时执行\n if (!isGlobalInstall()) {\n console.log('[mg-cli] 本地安装,跳过 Native Host 注册')\n console.log('[mg-cli] 如需注册,请运行: npx @hangox/mg-cli register')\n return\n }\n\n console.log('[mg-cli] 检测到全局安装,开始注册 Native Messaging Host...')\n console.log(`[mg-cli] Host Name: ${HOST_NAME}`)\n console.log(`[mg-cli] Extension ID: ${EXTENSION_ID}`)\n\n try {\n register('chrome')\n } catch (error) {\n console.error('[mg-cli] Native Host 注册失败:', error)\n console.log('\\n[mg-cli] 请手动运行: npx @hangox/mg-cli register')\n // 不要让 postinstall 失败阻止安装\n process.exitCode = 0\n }\n}\n\nmain()\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/scripts/postinstall.ts","../src/scripts/register-utils.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * npm postinstall 脚本\n * 全局安装时自动注册 Native Messaging Host\n */\n\nimport { pathToFileURL } from 'node:url'\nimport { registerAll, HOST_NAME, EXTENSION_ID, type BrowserType } from './register-utils.js'\n\n/** postinstall 默认注册的浏览器(不含 edge,避免过度扩散);理由见 CLI 层 register.ts 的同名常量 */\nconst DEFAULT_BROWSERS: BrowserType[] = ['chrome', 'chromium']\n\n// ==================== 入口 ====================\n\n/**\n * @param dirnameOverride 仅供测试注入自定义 dirname,验证 pnpm/yarn 全局路径特征识别逻辑;\n * 生产调用不传,使用真实的 __dirname(当前文件所在目录)\n */\nexport function isGlobalInstall(dirnameOverride?: string): boolean {\n // npm 全局安装\n if (process.env.npm_config_global === 'true') return true\n\n const dir = dirnameOverride ?? __dirname\n\n // pnpm 全局安装检测\n const pnpmPatterns = ['/pnpm/global/', '/.local/share/pnpm/', '/pnpm-global/']\n if (pnpmPatterns.some((p) => dir.includes(p))) return true\n\n // yarn 全局安装检测\n const yarnPatterns = ['/.config/yarn/global/', '/yarn/global/']\n if (yarnPatterns.some((p) => dir.includes(p))) return true\n\n return false\n}\n\nexport function main(): void {\n // 仅全局安装时执行\n if (!isGlobalInstall()) {\n console.log('[mg-cli] 本地安装,跳过 Native Host 注册')\n console.log('[mg-cli] 如需注册,请运行: npx @hangox/mg-cli register')\n return\n }\n\n console.log('[mg-cli] 检测到全局安装,开始注册 Native Messaging Host...')\n console.log(`[mg-cli] Host Name: ${HOST_NAME}`)\n console.log(`[mg-cli] Extension ID: ${EXTENSION_ID}`)\n console.log(`[mg-cli] 浏览器: ${DEFAULT_BROWSERS.join(', ')}`)\n\n try {\n const results = registerAll(DEFAULT_BROWSERS)\n for (const r of results) {\n if (r.success) {\n console.log(`[mg-cli] ✓ ${r.browser} 注册成功`)\n } else {\n console.warn(`[mg-cli] ✗ ${r.browser} 注册失败: ${r.error}`)\n }\n }\n if (results.every((r) => !r.success)) {\n console.log('\\n[mg-cli] 请手动运行: npx @hangox/mg-cli register')\n }\n } catch (error) {\n console.error('[mg-cli] Native Host 注册失败:', error)\n console.log('\\n[mg-cli] 请手动运行: npx @hangox/mg-cli register')\n } finally {\n // 不要让 postinstall 失败阻止安装\n process.exitCode = 0\n }\n}\n\n// 仅在作为入口脚本直接运行时执行(`node dist/postinstall.js`),被测试 import 时不触发副作用;\n// 判断依据:import.meta.url 是否等于当前进程实际启动的入口文件(process.argv[1])\n//\n// 判断是否作为脚本直接被执行(区分自执行 vs. 被测试 import)。\n// 前提:npm/pnpm/yarn 触发 postinstall 时用相对路径 + cwd=包目录,\n// process.cwd() 走 getcwd() 会自动 realpath,与 import.meta.url 一致。\n// 已知边界:如果用绝对路径且路径穿过符号链接调用(如 `node /path/via/symlink/postinstall.js`),\n// import.meta.url 会被 realpath、process.argv[1] 不会,导致判断为 false 而跳过执行。\n// 真实包管理器场景不触发此边界,保持现状。\nconst isDirectlyExecuted = (() => {\n try {\n return import.meta.url === pathToFileURL(process.argv[1] ?? '').href\n } catch {\n return false\n }\n})()\n\nif (isDirectlyExecuted) {\n main()\n}\n","/**\n * Native Messaging Host 注册辅助函数\n * 支持 macOS, Linux, Windows\n */\n\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { execSync } from 'node:child_process'\nimport { fileURLToPath } from 'node:url'\n\n// ==================== 配置常量 ====================\n\nexport const HOST_NAME = 'com.hangox.mgplugin'\nexport const EXTENSION_ID = 'ddhihanlpcdneicohnglnaliefnkaeja'\nconst DESCRIPTION = 'MasterGo Plugin Native Messaging Host'\n\n// ==================== 平台适配 ====================\n\nexport type BrowserType = 'chrome' | 'chromium' | 'edge'\n\n/** 当前已知(已实测支持)的浏览器类型,供 CLI 层 --all / --check / --unregister 默认值使用 */\nexport const KNOWN_BROWSERS: BrowserType[] = ['chrome', 'chromium', 'edge']\n\ninterface PlatformConfig {\n manifestDir: string\n registryKey?: string // Windows only\n}\n\nfunction getBrowserPaths(browser: BrowserType): PlatformConfig {\n const home = os.homedir()\n const platform = os.platform()\n\n const browserDirs: Record<BrowserType, Record<string, string>> = {\n chrome: {\n darwin: path.join(home, 'Library/Application Support/Google/Chrome/NativeMessagingHosts'),\n linux: path.join(home, '.config/google-chrome/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Google/Chrome/NativeMessagingHosts'\n ),\n },\n chromium: {\n darwin: path.join(home, 'Library/Application Support/Chromium/NativeMessagingHosts'),\n linux: path.join(home, '.config/chromium/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Chromium/NativeMessagingHosts'\n ),\n },\n edge: {\n darwin: path.join(\n home,\n 'Library/Application Support/Microsoft Edge/NativeMessagingHosts'\n ),\n linux: path.join(home, '.config/microsoft-edge/NativeMessagingHosts'),\n win32: path.join(\n process.env.APPDATA || path.join(home, 'AppData/Roaming'),\n 'Microsoft/Edge/NativeMessagingHosts'\n ),\n },\n }\n\n const registryKeys: Record<BrowserType, string> = {\n chrome: `HKCU\\\\Software\\\\Google\\\\Chrome\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n chromium: `HKCU\\\\Software\\\\Chromium\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n edge: `HKCU\\\\Software\\\\Microsoft\\\\Edge\\\\NativeMessagingHosts\\\\${HOST_NAME}`,\n }\n\n const manifestDir = browserDirs[browser][platform]\n if (!manifestDir) {\n throw new Error(`不支持的平台: ${platform}`)\n }\n\n return {\n manifestDir,\n registryKey: platform === 'win32' ? registryKeys[browser] : undefined,\n }\n}\n\n// ==================== Manifest 生成 ====================\n\nfunction getNativeHostPath(): string {\n // 获取当前文件位置,推算 native-host 入口\n const currentFile = fileURLToPath(import.meta.url)\n const distDir = path.dirname(currentFile)\n return path.join(distDir, 'native-host.js')\n}\n\n/** wrapper 脚本 / native-host.js 副本的固定安装目录名 */\nconst INSTALL_DIR_NAME = 'mg-cli'\n\n/**\n * 固定的用户级安装目录,独立于 npm 包版本升级/卸载:\n * - macOS/Linux: `~/.config/mg-cli/`\n * - Windows: `%APPDATA%\\mg-cli\\`\n *\n * 不用 mg-cli 的 npm 全局安装路径本身(不同版本/包管理器切换会移动或覆盖该路径),\n * 也不用 /tmp(系统会定期清理),这里用标准的用户配置目录,稳定且每用户独立。\n */\nfunction getInstallDir(): string {\n const home = os.homedir()\n if (os.platform() === 'win32') {\n const appData = process.env.APPDATA || path.join(home, 'AppData/Roaming')\n return path.join(appData, INSTALL_DIR_NAME)\n }\n return path.join(home, '.config', INSTALL_DIR_NAME)\n}\n\nconst WRAPPER_FILENAME_UNIX = 'native-host-wrapper.sh'\nconst WRAPPER_FILENAME_WIN = 'native-host-wrapper.cmd'\n\n/** 当前平台下 wrapper 脚本的完整路径(安装目录 + 平台专属文件名) */\nfunction getWrapperPath(installDir: string): string {\n const filename = os.platform() === 'win32' ? WRAPPER_FILENAME_WIN : WRAPPER_FILENAME_UNIX\n return path.join(installDir, filename)\n}\n\n/**\n * 把 native-host.js 拷贝到固定安装目录,并生成一个绝对路径 wrapper 脚本,manifest.path\n * 指向这个 wrapper 而不是直接指向 native-host.js。\n *\n * 背景:native-host.js 首行 `#!/usr/bin/env node` 依赖运行时 PATH 解析 node 解释器。Chrome\n * 作为 GUI App 启动时使用系统默认 PATH(不含用户 shell rc 里 nvm/fnm/volta 等版本管理器追加\n * 的路径),对应场景下 spawn native-host.js 会直接失败(\"Native host has exited.\"),导致\n * 插件诊断报告显示\"不可用\",即便 manifest 已经正确注册。\n *\n * 修复:**不直接改 native-host.js 的 shebang**(绝对路径 shebang 在 Linux 上有 128 字节长度\n * 上限,nvm 深层版本路径容易超限;且路径含空格时 shebang 行不支持加引号,两条都是真实存在\n * 的边界问题)。改用 wrapper 脚本方案:register() 运行在终端/npm 上下文(`mg-cli register`\n * 手动执行,或 postinstall 触发),此时 `process.execPath` 就是当前正确解析出来的、真正可用\n * 的 node 绝对路径。把它写进一个小 wrapper 脚本,由 shell/cmd 自己解析路径(不受 128 字节\n * shebang 限制,双引号包裹后空格也不是问题),manifest.path 指向这个 wrapper,Chrome spawn\n * 时就是 `execve(wrapper)` → wrapper 内部再 `exec <绝对路径 node> <绝对路径 native-host.js>`,\n * 完全不需要经过 PATH 解析。\n *\n * native-host.js 本身也拷贝一份到安装目录(而不是让 wrapper 指回 npm 包的 dist/ 目录),\n * 避免 npm 升级/卸载 mg-cli 时安装目录发生变化导致 wrapper 引用悬空;每次 register() 都会\n * 用当前版本重新覆盖这份拷贝,保持同步。\n *\n * 幂等 / 版本切换:每次调用都用当前 `process.execPath` 无条件重新生成 wrapper 内容(不是\n * \"已存在就跳过\"),所以用户 `nvm use` 切换 node 版本后只需要重新运行一次 `mg-cli register`,\n * wrapper 就会指向新版本——不会因为文件已存在而被跳过导致修复失效。\n *\n * Windows 没有 shebang 概念,`.cmd` 参数透传语法是 `%*`(不是 shell 的 `$@`)。\n */\nfunction ensureNativeHostWrapper(sourceNativeHostPath: string): string {\n const installDir = getInstallDir()\n fs.mkdirSync(installDir, { recursive: true })\n\n const installedNativeHostPath = path.join(installDir, 'native-host.js')\n fs.copyFileSync(sourceNativeHostPath, installedNativeHostPath)\n\n const wrapperPath = getWrapperPath(installDir)\n\n if (os.platform() === 'win32') {\n const wrapperContent = `@echo off\\r\\n\"${process.execPath}\" \"${installedNativeHostPath}\" %*\\r\\n`\n fs.writeFileSync(wrapperPath, wrapperContent)\n return wrapperPath\n }\n\n const wrapperContent = `#!/bin/sh\\nexec \"${process.execPath}\" \"${installedNativeHostPath}\" \"$@\"\\n`\n fs.writeFileSync(wrapperPath, wrapperContent)\n try {\n fs.chmodSync(wrapperPath, '755')\n } catch {\n console.warn(' ⚠️ 无法设置 wrapper 执行权限,可能需要手动设置')\n }\n return wrapperPath\n}\n\n/**\n * 从 wrapper 脚本内容里解析出写死的 node 绝对路径,供 `--check` 展示排查信息用\n * (\"到底 spawn 的是哪个 node\")。wrapper 内容里第一个双引号包裹的片段就是 node 路径。\n */\nfunction readWrapperNodePath(wrapperPath: string): string | undefined {\n try {\n const content = fs.readFileSync(wrapperPath, 'utf-8')\n const match = content.match(/\"([^\"]+)\"/)\n return match?.[1]\n } catch {\n return undefined\n }\n}\n\n/**\n * unregister 之后,检查安装目录(`~/.config/mg-cli/` 等)下的 wrapper 是否还被任何一个\n * 已知浏览器(KNOWN_BROWSERS:chrome/chromium/edge)的 manifest 引用着——wrapper 是跨浏览器\n * 共用的(一份 wrapper,多个浏览器的 manifest.path 都指向它),只有当**所有**已知浏览器要么\n * 没注册、要么 manifest 指向的不是这个 wrapper 时,才能认定它是孤儿文件,顺手清理掉,避免\n * 用户\"全部 unregister 干净\"之后,`~/.config/mg-cli/` 下还留着 wrapper + 187KB 的\n * native-host.js 拷贝没人管。\n *\n * 保守策略:manifest 存在但解析失败(corrupt JSON)时,无法确认它是否指向这个 wrapper,\n * 按\"可能还在用\"处理、不清理——宁可漏清一次,也不要误删一个其实还被引用的 wrapper。\n *\n * 只删 wrapper 脚本和 native-host.js 这两个文件,不删整个安装目录本身——目录下可能还有\n * 其他文件(比如版本检查用的缓存文件),删目录会把这些无关文件一起带走。\n */\nfunction cleanupOrphanWrapperIfUnused(): void {\n const installDir = getInstallDir()\n const wrapperPath = getWrapperPath(installDir)\n\n if (!fs.existsSync(wrapperPath)) return\n\n const stillReferenced = KNOWN_BROWSERS.some((browser) => {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n if (!fs.existsSync(manifestPath)) return false\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { path?: string }\n return manifest.path === wrapperPath\n } catch {\n return true\n }\n })\n\n if (stillReferenced) return\n\n const installedNativeHostPath = path.join(installDir, 'native-host.js')\n try {\n fs.unlinkSync(wrapperPath)\n } catch {\n // 忽略:可能已经被清理过或没有权限,不影响 unregister 本身的成功\n }\n try {\n if (fs.existsSync(installedNativeHostPath)) {\n fs.unlinkSync(installedNativeHostPath)\n }\n } catch {\n // 忽略\n }\n console.log(`已清理 wrapper 安装目录: ${installDir}`)\n}\n\nfunction createManifest(hostPath: string): {\n name: string\n description: string\n path: string\n type: string\n allowed_origins: string[]\n} {\n return {\n name: HOST_NAME,\n description: DESCRIPTION,\n path: hostPath,\n type: 'stdio',\n allowed_origins: [`chrome-extension://${EXTENSION_ID}/`],\n }\n}\n\n// ==================== 注册逻辑 ====================\n\nexport function register(browser: BrowserType = 'chrome'): void {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n const nativeHostPath = getNativeHostPath()\n const wrapperPath = ensureNativeHostWrapper(nativeHostPath)\n const manifest = createManifest(wrapperPath)\n\n console.log('正在注册 Native Messaging Host...')\n console.log(` Host Name: ${HOST_NAME}`)\n console.log(` Extension ID: ${EXTENSION_ID}`)\n console.log(` Browser: ${browser}`)\n console.log(` Native Host: ${manifest.path}`)\n console.log(` Manifest: ${manifestPath}`)\n\n // 1. 确保目录存在\n fs.mkdirSync(config.manifestDir, { recursive: true })\n\n // 2. 写入 manifest\n fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2))\n\n // 3. 设置执行权限 (Unix)\n if (os.platform() !== 'win32') {\n try {\n fs.chmodSync(manifest.path, '755')\n } catch {\n console.warn(' ⚠️ 无法设置执行权限,可能需要手动设置')\n }\n }\n\n // 4. Windows: 写入注册表\n if (config.registryKey) {\n try {\n execSync(`reg add \"${config.registryKey}\" /ve /t REG_SZ /d \"${manifestPath}\" /f`, {\n stdio: 'pipe',\n })\n console.log(' ✓ Windows 注册表已更新')\n } catch {\n console.warn(' ⚠️ 注册表写入失败,可能需要管理员权限')\n }\n }\n\n console.log('✓ Native Messaging Host 注册成功')\n}\n\nexport function unregister(browser: BrowserType = 'chrome'): void {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n\n // 删除 manifest 文件\n if (fs.existsSync(manifestPath)) {\n fs.unlinkSync(manifestPath)\n console.log(` 已删除: ${manifestPath}`)\n }\n\n // Windows: 删除注册表项\n if (config.registryKey) {\n try {\n execSync(`reg delete \"${config.registryKey}\" /f`, { stdio: 'pipe' })\n console.log(' ✓ Windows 注册表项已删除')\n } catch {\n // 忽略不存在的情况\n }\n }\n\n // 顺手检查一下 wrapper 是不是已经没有任何浏览器引用了(孤儿文件),是的话清理掉\n cleanupOrphanWrapperIfUnused()\n}\n\nexport interface CheckRegistrationResult {\n registered: boolean\n manifestPath?: string\n manifest?: unknown\n /** manifest.path 指向的 wrapper 路径(manifest 存在且可解析时才有) */\n wrapperPath?: string\n /** wrapper 文件是否真的存在于磁盘上;缺失时不应该判定为\"已注册\" */\n wrapperExists?: boolean\n /** 从 wrapper 内容里解析出的 node 绝对路径,供 --check 展示排查信息 */\n wrapperNodePath?: string\n}\n\nexport function checkRegistration(browser: BrowserType = 'chrome'): CheckRegistrationResult {\n const config = getBrowserPaths(browser)\n const manifestPath = path.join(config.manifestDir, `${HOST_NAME}.json`)\n\n if (!fs.existsSync(manifestPath)) {\n return { registered: false }\n }\n\n let manifest: { path?: string } | undefined\n try {\n manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { path?: string }\n } catch {\n return { registered: false, manifestPath }\n }\n\n const wrapperPath = manifest.path\n const wrapperExists = wrapperPath ? fs.existsSync(wrapperPath) : false\n\n if (!wrapperExists) {\n // manifest 本身存在且能解析,但它指向的 wrapper 文件缺失(比如用户手动删了)——\n // 这种\"配置不完整\"状态不能算作\"已注册\",否则用户会被 --check 的绿勾误导\n return { registered: false, manifestPath, manifest, wrapperPath, wrapperExists: false }\n }\n\n return {\n registered: true,\n manifestPath,\n manifest,\n wrapperPath,\n wrapperExists: true,\n wrapperNodePath: wrapperPath ? readWrapperNodePath(wrapperPath) : undefined,\n }\n}\n\n// ==================== 批量操作(多浏览器) ====================\n\n/** 单个浏览器的批量操作结果 */\nexport interface BrowserActionResult {\n browser: BrowserType\n success: boolean\n error?: string\n}\n\n/** 单个浏览器的检查结果(带上 browser 字段,便于批量汇总展示) */\nexport interface BrowserCheckResult extends CheckRegistrationResult {\n browser: BrowserType\n}\n\n/**\n * 批量注册:对每个浏览器独立 try/catch,单个失败不影响其他浏览器继续执行\n * 调用方(CLI / postinstall)根据返回结果自行决定输出格式和退出码\n */\nexport function registerAll(browsers: BrowserType[]): BrowserActionResult[] {\n return browsers.map((browser) => {\n try {\n register(browser)\n return { browser, success: true }\n } catch (error) {\n return { browser, success: false, error: error instanceof Error ? error.message : String(error) }\n }\n })\n}\n\n/**\n * 批量卸载:对每个浏览器独立 try/catch。\n * unregister() 本身对\"manifest 不存在\"是幂等的(内部 existsSync 判断后跳过,不报错),\n * 这里只兜住真正意外的失败(如文件存在但删除时权限不足)\n */\nexport function unregisterAll(browsers: BrowserType[]): BrowserActionResult[] {\n return browsers.map((browser) => {\n try {\n unregister(browser)\n return { browser, success: true }\n } catch (error) {\n return { browser, success: false, error: error instanceof Error ? error.message : String(error) }\n }\n })\n}\n\n/** 批量检查:checkRegistration 本身不会抛异常,这里只是逐个调用并附上 browser 字段 */\nexport function checkAll(browsers: BrowserType[]): BrowserCheckResult[] {\n return browsers.map((browser) => ({ browser, ...checkRegistration(browser) }))\n}\n"],"mappings":"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","names":["wrapperContent"]}
|