codewave-openclaw-installer 2.1.2 → 2.1.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.
- package/bin/check.mjs +65 -2
- package/bin/install-lib.mjs +8 -0
- package/package.json +1 -1
package/bin/check.mjs
CHANGED
|
@@ -16,6 +16,11 @@ import { spawn } from 'node:child_process';
|
|
|
16
16
|
import { existsSync, readFileSync } from 'node:fs';
|
|
17
17
|
import { join } from 'node:path';
|
|
18
18
|
import { homedir, platform } from 'node:os';
|
|
19
|
+
import {
|
|
20
|
+
CHANNEL_DEFINITIONS,
|
|
21
|
+
detectDesktopAppInstallMatches,
|
|
22
|
+
getDesktopAppCandidates,
|
|
23
|
+
} from './install-lib.mjs';
|
|
19
24
|
|
|
20
25
|
// ─── 颜色 ───
|
|
21
26
|
const NO_COLOR = process.env.NO_COLOR || process.argv.includes('--json');
|
|
@@ -32,6 +37,12 @@ const isMac = process.platform === 'darwin';
|
|
|
32
37
|
const isLinux = process.platform === 'linux';
|
|
33
38
|
const JSON_MODE = process.argv.includes('--json');
|
|
34
39
|
const FIX_MODE = process.argv.includes('--fix');
|
|
40
|
+
const WINDOWS_UNINSTALL_KEYS = [
|
|
41
|
+
'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
|
|
42
|
+
'HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
|
|
43
|
+
'HKLM\\Software\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
|
|
44
|
+
];
|
|
45
|
+
let windowsUninstallDisplayNamesPromise = null;
|
|
35
46
|
|
|
36
47
|
// ─── 工具函数 ───
|
|
37
48
|
|
|
@@ -86,6 +97,54 @@ function run(cmd, args) {
|
|
|
86
97
|
});
|
|
87
98
|
}
|
|
88
99
|
|
|
100
|
+
function runCapture(cmd, args) {
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
const child = spawn(cmd, args, { stdio: ['ignore', 'pipe', 'pipe'], shell: isWin });
|
|
103
|
+
let stdout = '';
|
|
104
|
+
let stderr = '';
|
|
105
|
+
child.stdout?.on('data', (chunk) => { stdout += chunk.toString(); });
|
|
106
|
+
child.stderr?.on('data', (chunk) => { stderr += chunk.toString(); });
|
|
107
|
+
child.on('close', (code) => resolve({ code: code ?? 1, stdout, stderr }));
|
|
108
|
+
child.on('error', (err) => resolve({ code: 1, stdout, stderr: err.message }));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function getWindowsUninstallDisplayNames() {
|
|
113
|
+
if (!isWin) {
|
|
114
|
+
return [];
|
|
115
|
+
}
|
|
116
|
+
if (!windowsUninstallDisplayNamesPromise) {
|
|
117
|
+
windowsUninstallDisplayNamesPromise = (async () => {
|
|
118
|
+
const displayNames = [];
|
|
119
|
+
for (const registryKey of WINDOWS_UNINSTALL_KEYS) {
|
|
120
|
+
const result = await runCapture('reg', ['query', registryKey, '/s', '/v', 'DisplayName']);
|
|
121
|
+
const lines = `${result.stdout}\n${result.stderr}`.split(/\r?\n/);
|
|
122
|
+
for (const line of lines) {
|
|
123
|
+
const match = line.match(/^\s*DisplayName\s+REG_\w+\s+(.+?)\s*$/i);
|
|
124
|
+
if (match?.[1]) {
|
|
125
|
+
displayNames.push(match[1].trim());
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return [...new Set(displayNames)];
|
|
130
|
+
})();
|
|
131
|
+
}
|
|
132
|
+
return windowsUninstallDisplayNamesPromise;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function findDesktopApps(definition) {
|
|
136
|
+
const installedRegistryDisplayNames = await getWindowsUninstallDisplayNames();
|
|
137
|
+
return detectDesktopAppInstallMatches({
|
|
138
|
+
platform: process.platform,
|
|
139
|
+
homeDir: homedir(),
|
|
140
|
+
env: process.env,
|
|
141
|
+
fileCandidates: getDesktopAppCandidates(definition, process.platform),
|
|
142
|
+
registryDisplayNames: definition.desktopAppWindowsRegistryNames ?? [],
|
|
143
|
+
installedRegistryDisplayNames,
|
|
144
|
+
exists: existsSync,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
89
148
|
// ─── 检测项定义 ───
|
|
90
149
|
|
|
91
150
|
/** @typedef {{ name: string, status: 'ok'|'warn'|'fail', version?: string, message: string, fix?: string }} CheckResult */
|
|
@@ -267,9 +326,11 @@ async function checkChannel(name, configPaths, envVars, commands, options = {})
|
|
|
267
326
|
|
|
268
327
|
const configMatches = configPaths.filter(fileExists);
|
|
269
328
|
const envMatches = envVars.filter((key) => Boolean(process.env[key]));
|
|
329
|
+
const desktopMatches = options.definition ? await findDesktopApps(options.definition) : [];
|
|
270
330
|
|
|
271
331
|
const hints = [
|
|
272
332
|
...commandMatches.map((cmd) => `命令:${cmd}`),
|
|
333
|
+
...desktopMatches.map((path) => `桌面客户端:${path}`),
|
|
273
334
|
...configMatches.map((path) => `配置:${path}`),
|
|
274
335
|
...envMatches.map((key) => `环境变量:${key}`),
|
|
275
336
|
];
|
|
@@ -282,7 +343,7 @@ async function checkChannel(name, configPaths, envVars, commands, options = {})
|
|
|
282
343
|
};
|
|
283
344
|
}
|
|
284
345
|
|
|
285
|
-
if (configMatches.length > 0 || envMatches.length > 0) {
|
|
346
|
+
if (desktopMatches.length > 0 || configMatches.length > 0 || envMatches.length > 0) {
|
|
286
347
|
return {
|
|
287
348
|
name,
|
|
288
349
|
status: 'warn',
|
|
@@ -416,11 +477,12 @@ async function main() {
|
|
|
416
477
|
],
|
|
417
478
|
['LARK_APP_ID', 'LARK_APP_SECRET', 'FEISHU_APP_ID', 'FEISHU_APP_SECRET'],
|
|
418
479
|
[],
|
|
419
|
-
{ hintMessage: `检测到环境线索,可通过 openclaw 渠道引导继续 (${[
|
|
480
|
+
{ definition: CHANNEL_DEFINITIONS.lark, hintMessage: `检测到环境线索,可通过 openclaw 渠道引导继续 (${[
|
|
420
481
|
join(homedir(), '.openclaw', 'lark.json'),
|
|
421
482
|
join(homedir(), '.openclaw', 'extensions', '@openclaw', 'feishu'),
|
|
422
483
|
join(homedir(), '.openclaw', 'extensions', 'openclaw-lark'),
|
|
423
484
|
].filter(fileExists).map((path) => `配置:${path}`).concat(
|
|
485
|
+
await findDesktopApps(CHANNEL_DEFINITIONS.lark).then((matches) => matches.map((path) => `桌面客户端:${path}`)),
|
|
424
486
|
['LARK_APP_ID', 'LARK_APP_SECRET', 'FEISHU_APP_ID', 'FEISHU_APP_SECRET']
|
|
425
487
|
.filter((key) => Boolean(process.env[key]))
|
|
426
488
|
.map((key) => `环境变量:${key}`),
|
|
@@ -435,6 +497,7 @@ async function main() {
|
|
|
435
497
|
],
|
|
436
498
|
['DWS_CLIENT_ID', 'DWS_CLIENT_SECRET'],
|
|
437
499
|
['dws', 'dingtalk', 'dingtalk-workspace-cli'],
|
|
500
|
+
{ definition: CHANNEL_DEFINITIONS.dingtalk },
|
|
438
501
|
);
|
|
439
502
|
|
|
440
503
|
// 打印基础环境结果
|
package/bin/install-lib.mjs
CHANGED
|
@@ -22,9 +22,17 @@ export const CHANNEL_DEFINITIONS = {
|
|
|
22
22
|
desktopAppCandidates: ['Feishu.app', 'Lark.app', '飞书.app'],
|
|
23
23
|
desktopAppWindowsCandidates: [
|
|
24
24
|
'Feishu.exe',
|
|
25
|
+
'FeishuLauncher.exe',
|
|
26
|
+
'Feishu/Feishu.exe',
|
|
27
|
+
'Feishu/FeishuLauncher.exe',
|
|
25
28
|
'Lark.exe',
|
|
29
|
+
'LarkLauncher.exe',
|
|
30
|
+
'Lark/Lark.exe',
|
|
31
|
+
'Lark/LarkLauncher.exe',
|
|
26
32
|
'Programs/Feishu/Feishu.exe',
|
|
33
|
+
'Programs/Feishu/FeishuLauncher.exe',
|
|
27
34
|
'Programs/Lark/Lark.exe',
|
|
35
|
+
'Programs/Lark/LarkLauncher.exe',
|
|
28
36
|
],
|
|
29
37
|
desktopAppWindowsRegistryNames: ['Feishu', 'Lark', '飞书'],
|
|
30
38
|
configPaths: [
|