@hellolynk-ai/codex-plugin 0.2.101 → 0.2.102-macos.1
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/README.md +17 -17
- package/bin/hellolynk-client-setup.mjs +72 -11
- package/hellolynk-client-pack-manifest.json +109 -69
- package/hellolynk-client-pack-pin.json +1 -1
- package/package.json +8 -4
- package/plugins/hellolynk-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/hellolynk-codex/.mcp.json +20 -19
- package/plugins/hellolynk-codex/package.json +1 -1
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-account.mjs +1 -1
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-client-profile.mjs +25 -2
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-darwin-host.mjs +256 -0
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-darwin-vault.mjs +153 -0
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-host-protected-store.mjs +20 -8
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-neutral-host-installation-store.mjs +3 -7
- package/plugins/hellolynk-codex/runtime/bootstrap/core/hellolynk-platform-credential-store.mjs +68 -14
- package/plugins/hellolynk-codex/runtime/bootstrap/platform/darwin/hellolynk-keychain-helper.bin +0 -0
- package/plugins/hellolynk-codex/runtime/bootstrap/platform/darwin/hellolynk-keychain-helper.swift +149 -0
- package/plugins/hellolynk-codex/runtime/connect-activate.mjs +5 -1
- package/plugins/hellolynk-codex/runtime/core/hellolynk-client-account.mjs +1 -1
- package/plugins/hellolynk-codex/runtime/core/hellolynk-client-profile.mjs +25 -2
- package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-entry.mjs +7 -3
- package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update-runtime.mjs +24 -8
- package/plugins/hellolynk-codex/runtime/core/hellolynk-client-update.mjs +23 -9
- package/plugins/hellolynk-codex/runtime/core/hellolynk-darwin-host.mjs +256 -0
- package/plugins/hellolynk-codex/runtime/core/hellolynk-darwin-vault.mjs +153 -0
- package/plugins/hellolynk-codex/runtime/core/hellolynk-host-protected-store.mjs +20 -8
- package/plugins/hellolynk-codex/runtime/core/hellolynk-human-confirmation-ledger.mjs +53 -6
- package/plugins/hellolynk-codex/runtime/core/hellolynk-local-data-protection.mjs +22 -7
- package/plugins/hellolynk-codex/runtime/core/hellolynk-native-human-confirmation-broker.mjs +7 -5
- package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-installation-store.mjs +3 -7
- package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-launcher.mjs +9 -3
- package/plugins/hellolynk-codex/runtime/core/hellolynk-neutral-host-process.mjs +1 -1
- package/plugins/hellolynk-codex/runtime/core/hellolynk-platform-credential-store.mjs +68 -14
- package/plugins/hellolynk-codex/runtime/core/hellolynk-release-retention.mjs +78 -2
- package/plugins/hellolynk-codex/runtime/core/hellolynk-workbench-connection.mjs +5 -3
- package/plugins/hellolynk-codex/runtime/neutral-host-release-entry.mjs +1 -1
- package/plugins/hellolynk-codex/runtime/neutral-host-release-loader.mjs +1 -1
- package/plugins/hellolynk-codex/runtime/neutral-host-release-manifest.json +58 -26
- package/plugins/hellolynk-codex/runtime/neutral-host-release-pin.json +1 -1
- package/plugins/hellolynk-codex/runtime/platform/darwin/hellolynk-keychain-helper.bin +0 -0
- package/plugins/hellolynk-codex/runtime/platform/darwin/hellolynk-keychain-helper.swift +149 -0
- package/plugins/hellolynk-codex/server/codex-neutral-production.mjs +15 -9
- package/plugins/hellolynk-codex/server/mcp-server.mjs +1193 -1193
- package/plugins/hellolynk-codex/server/native-conversation-directory.mjs +33 -33
- package/plugins/hellolynk-codex/server/workbench-runtime.mjs +42 -42
- package/tools/hellolynk-activate-neutral-host-clients.mjs +5 -1
package/README.md
CHANGED
|
@@ -35,35 +35,35 @@
|
|
|
35
35
|
|
|
36
36
|
Codex、OpenClaw、TRAE Work、WorkBuddy。装哪个客户端,就选哪个包。同一个账号下,它们共用你的灵信号。
|
|
37
37
|
|
|
38
|
-
源码见 [Codex 客户端源码](https://github.com/haoyun18881-beep/HelloLynk/tree/main/clients/codex),完整介绍见 [HelloLynk on GitHub](https://github.com/haoyun18881-beep/HelloLynk)。
|
|
38
|
+
源码见 [Codex 客户端源码](https://github.com/haoyun18881-beep/HelloLynk/tree/main/clients/codex-macos),完整介绍见 [HelloLynk on GitHub](https://github.com/haoyun18881-beep/HelloLynk)。
|
|
39
39
|
|
|
40
40
|
## 前提
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Apple 芯片、macOS 13 或更高版本、Node.js 22.16 或更高版本,以及安装在「应用程序」中的 ChatGPT(已打开过 Codex)。
|
|
43
43
|
|
|
44
44
|
## 安装
|
|
45
45
|
|
|
46
46
|
1. 打开 [HelloLynk 官网(Official site)](https://hellolynk.com)。新用户注册账号;已有账号登录后,查看自己的公开灵信号。
|
|
47
47
|
2. 两种装法任选一种。
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
推荐用 npm,在终端运行:
|
|
50
50
|
|
|
51
|
-
```
|
|
52
|
-
|
|
51
|
+
```sh
|
|
52
|
+
npm install -g @hellolynk-ai/codex-plugin@macos
|
|
53
|
+
hellolynk-codex init
|
|
53
54
|
```
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
用安装包,在官网或 [GitHub Release](https://github.com/haoyun18881-beep/HelloLynk/releases) 下载 Codex for Mac 安装包,完整解压,在包含 `package` 文件夹的目录打开 终端,运行:
|
|
56
57
|
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
hellolynk-codex init
|
|
58
|
+
```sh
|
|
59
|
+
node ./package/bin/hellolynk-client-setup.mjs init
|
|
60
60
|
```
|
|
61
61
|
|
|
62
62
|
3. 完全退出并重新打开 Codex。
|
|
63
63
|
|
|
64
64
|
可以把本说明交给你的本地 AI,请它帮你安装;用安装包时,把解压目录也告诉它。
|
|
65
65
|
|
|
66
|
-
下文命令按安装包写法给出。用 npm 装的,把 `node
|
|
66
|
+
下文命令按安装包写法给出。用 npm 装的,把 `node ./package/bin/hellolynk-client-setup.mjs` 换成 `hellolynk-codex`,在任意目录运行。
|
|
67
67
|
|
|
68
68
|
## 首次连接
|
|
69
69
|
|
|
@@ -73,8 +73,8 @@ Windows 10/11、Node.js 22.16 或更高版本、PowerShell 7,以及打开过
|
|
|
73
73
|
|
|
74
74
|
也可以让 AI 用命令连接,把示例换成自己的公开灵信号:
|
|
75
75
|
|
|
76
|
-
```
|
|
77
|
-
node
|
|
76
|
+
```sh
|
|
77
|
+
node ./package/bin/hellolynk-client-setup.mjs connect --hellolynk-id hellolynk:intl:your-name
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
首次连接这台电脑时,命令会给出官网确认链接。AI 把链接给用户;用户确认后,AI 继续执行同一条连接命令。
|
|
@@ -83,20 +83,20 @@ node .\package\bin\hellolynk-client-setup.mjs connect --hellolynk-id hellolynk:i
|
|
|
83
83
|
|
|
84
84
|
插件会自动更新,不用操作。要手动更新,下载新版安装包,在包含 `package` 文件夹的目录运行:
|
|
85
85
|
|
|
86
|
-
```
|
|
87
|
-
node
|
|
86
|
+
```sh
|
|
87
|
+
node ./package/bin/hellolynk-client-setup.mjs setup
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
用 npm 装的,先运行 `npm install -g @hellolynk-ai/codex-plugin` 装上新版,再运行 `hellolynk-codex setup`。
|
|
90
|
+
用 npm 装的,先运行 `npm install -g @hellolynk-ai/codex-plugin@macos` 装上新版,再运行 `hellolynk-codex setup`。
|
|
91
91
|
|
|
92
92
|
## 卸载
|
|
93
93
|
|
|
94
|
-
在包含 `package` 文件夹的目录运行 `node
|
|
94
|
+
在包含 `package` 文件夹的目录运行 `node ./package/bin/hellolynk-client-setup.mjs uninstall`。账号、联系人和聊天记录留在这台电脑上,重新安装后不用重新连接。
|
|
95
95
|
|
|
96
96
|
用 npm 装的,运行 `hellolynk-codex uninstall`,再运行 `npm uninstall -g @hellolynk-ai/codex-plugin`。
|
|
97
97
|
|
|
98
98
|
## 求助
|
|
99
99
|
|
|
100
|
-
运行 `node
|
|
100
|
+
运行 `node ./package/bin/hellolynk-client-setup.mjs doctor` 检查安装,把结果和错误码发到 [haoyun18881@gmail.com](mailto:haoyun18881@gmail.com)。
|
|
101
101
|
|
|
102
102
|
许可:PolyForm Shield License 1.0.0,只覆盖本包内的客户端源码,完整条款见 LICENSE。
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import crypto from "node:crypto";
|
|
4
|
-
import { lstatSync, realpathSync, writeSync } from "node:fs";
|
|
4
|
+
import { constants, lstatSync, realpathSync, writeSync } from "node:fs";
|
|
5
5
|
import fs from "node:fs/promises";
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import path from "node:path";
|
|
@@ -21,6 +21,8 @@ const CHINESE = /^zh\b/i.test(Intl.DateTimeFormat().resolvedOptions().locale);
|
|
|
21
21
|
const CLIENT_NAMES = Object.freeze({ codex: "Codex", openclaw: "OpenClaw", "trae-work": "TRAE Work",
|
|
22
22
|
workbuddy: "WorkBuddy", cursor: "Cursor", dsh: "DSH" });
|
|
23
23
|
const { packageJson, metadata } = await readPackage();
|
|
24
|
+
const macPackage = metadata.client === "codex" && packageJson.os?.[0] === "darwin"
|
|
25
|
+
&& packageJson.cpu?.[0] === "arm64";
|
|
24
26
|
const commandArguments = process.argv.slice(2).filter((value) => value !== "--json");
|
|
25
27
|
const command = String(commandArguments.shift() || "help").toLowerCase();
|
|
26
28
|
const waitForPending = command === "--wait-for-pending";
|
|
@@ -61,8 +63,14 @@ try {
|
|
|
61
63
|
"--expected-manifest-sha256", sourceRelease.outerManifestSha256,
|
|
62
64
|
]);
|
|
63
65
|
} else {
|
|
64
|
-
const originalLocations = resolveLocations();
|
|
65
66
|
const accountModule = await importStableCore(PACKAGE_ROOT, "hellolynk-client-account.mjs", "hellolynk_npm_account_runtime_invalid");
|
|
67
|
+
const originalLocations = resolveLocations(accountModule.clientAccountBaseRoot);
|
|
68
|
+
if (macPackage && command !== "uninstall") {
|
|
69
|
+
const config = await readJson(path.join(sourceReleaseRoot, ".mcp.json"), "hellolynk_npm_release_invalid", true);
|
|
70
|
+
const commandPath = config.mcpServers?.["hellolynk-codex"]?.command;
|
|
71
|
+
if (typeof commandPath !== "string" || !path.isAbsolute(commandPath)) fail("hellolynk_npm_release_invalid");
|
|
72
|
+
await fs.access(commandPath, constants.X_OK).catch(() => fail("hellolynk_npm_codex_mac_node_required"));
|
|
73
|
+
}
|
|
66
74
|
const baseRoot = accountModule.clientAccountBaseRoot(originalLocations.hostRoot);
|
|
67
75
|
const packageLocations = { ...originalLocations, hostRoot: baseRoot, finalCurrentRoot: path.dirname(baseRoot) };
|
|
68
76
|
const accounts = accountModule.createClientAccountActions({ client: metadata.client, storeRoot: baseRoot });
|
|
@@ -429,7 +437,8 @@ async function uninstallClient(locations) {
|
|
|
429
437
|
if (receiverConfigured) await receiver.configureTraeNativeTaskWorker({ storeRoot: locations.hostRoot, enabled: false });
|
|
430
438
|
}
|
|
431
439
|
// A binding names the release it starts, so it cannot outlive the releases removed below.
|
|
432
|
-
|
|
440
|
+
const protectedFile = macPackage ? "protected-v1.sqlite" : "capabilities-v1.dpapi.clixml";
|
|
441
|
+
if (await exists(path.join(locations.hostRoot, protectedFile))) {
|
|
433
442
|
const store = await importStableCore(PACKAGE_ROOT, "hellolynk-host-protected-store.mjs", "hellolynk_npm_binding_invalid");
|
|
434
443
|
await store.createHostProtectedStore({ root: locations.hostRoot, followClientAccount: false }).disconnectLocalClient(metadata.client);
|
|
435
444
|
}
|
|
@@ -838,17 +847,20 @@ async function verifyRelease(releaseRoot, packageRoot, expectedMetadata = metada
|
|
|
838
847
|
return Object.freeze({ manifestSha256, outerManifestSha256 });
|
|
839
848
|
}
|
|
840
849
|
|
|
841
|
-
function resolveLocations() {
|
|
842
|
-
if (
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
const
|
|
850
|
+
function resolveLocations(getDefaultHostRoot) {
|
|
851
|
+
if (macPackage) {
|
|
852
|
+
if (process.platform !== "darwin" || process.arch !== "arm64") fail("hellolynk_npm_platform_unsupported");
|
|
853
|
+
} else if (process.platform !== "win32") fail("hellolynk_npm_windows_only");
|
|
854
|
+
const home = path.resolve((macPackage ? process.env.HOME : process.env.USERPROFILE) || os.homedir());
|
|
855
|
+
const localAppData = macPackage ? path.join(home, "Library", "Application Support")
|
|
856
|
+
: path.resolve(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"));
|
|
857
|
+
const appData = macPackage ? localAppData : path.resolve(process.env.APPDATA || path.join(home, "AppData", "Roaming"));
|
|
846
858
|
const configuredCodexHome = String(process.env.CODEX_HOME || "");
|
|
847
859
|
if (configuredCodexHome && !path.isAbsolute(configuredCodexHome)) fail("hellolynk_npm_codex_home_invalid");
|
|
848
860
|
const codexHome = path.resolve(configuredCodexHome || path.join(home, ".codex"));
|
|
849
861
|
const configuredHostRoot = String(process.env.HELLOLYNK_NEUTRAL_STORE_ROOT || "").trim();
|
|
850
862
|
if (configuredHostRoot && !path.isAbsolute(configuredHostRoot)) fail("hellolynk_npm_store_root_invalid");
|
|
851
|
-
const hostRoot = path.resolve(configuredHostRoot ||
|
|
863
|
+
const hostRoot = path.resolve(configuredHostRoot || getDefaultHostRoot());
|
|
852
864
|
if (configuredHostRoot && path.basename(hostRoot).toLowerCase() !== "host") {
|
|
853
865
|
fail("hellolynk_npm_store_root_invalid");
|
|
854
866
|
}
|
|
@@ -1004,6 +1016,12 @@ async function startHostWhenAbsent(runtime, binding) {
|
|
|
1004
1016
|
}
|
|
1005
1017
|
|
|
1006
1018
|
async function secureStableReleaseTree(locations, releaseId, options = {}) {
|
|
1019
|
+
const releasePath = path.resolve(locations.finalCurrentRoot, "releases", releaseId);
|
|
1020
|
+
// An existing AppData root can be shared while a new release is redirected
|
|
1021
|
+
// into one desktop app's private cache. Other clients cannot use that release.
|
|
1022
|
+
if (process.platform === "win32" && realpathSync.native(releasePath).toLowerCase() !== releasePath.toLowerCase()) {
|
|
1023
|
+
fail("client_root_alias_rejected");
|
|
1024
|
+
}
|
|
1007
1025
|
const module = await importCore(
|
|
1008
1026
|
"hellolynk-platform-credential-store.mjs",
|
|
1009
1027
|
"hellolynk_npm_client_root_security_unavailable",
|
|
@@ -2246,6 +2264,13 @@ function runCodexJson(args, code, codexHome) {
|
|
|
2246
2264
|
}
|
|
2247
2265
|
|
|
2248
2266
|
function minimalEnv({ codexHome = null } = {}) {
|
|
2267
|
+
if (macPackage) return Object.freeze({
|
|
2268
|
+
PATH: process.env.PATH || "/usr/bin:/bin",
|
|
2269
|
+
HOME: process.env.HOME || os.homedir(),
|
|
2270
|
+
TMPDIR: process.env.TMPDIR || os.tmpdir(),
|
|
2271
|
+
LANG: process.env.LANG || "en_US.UTF-8",
|
|
2272
|
+
...(codexHome ? { CODEX_HOME: codexHome } : {}),
|
|
2273
|
+
});
|
|
2249
2274
|
return Object.freeze({
|
|
2250
2275
|
PATH: process.env.Path || process.env.PATH || "",
|
|
2251
2276
|
PATHEXT: process.env.PATHEXT || "",
|
|
@@ -2261,13 +2286,18 @@ function minimalEnv({ codexHome = null } = {}) {
|
|
|
2261
2286
|
|
|
2262
2287
|
function resolveCodexRunner(codexHome) {
|
|
2263
2288
|
if (resolvedCodexRunner) return resolvedCodexRunner;
|
|
2264
|
-
const searchPath = String(process.env.Path || process.env.PATH || "");
|
|
2289
|
+
const searchPath = String((macPackage ? process.env.PATH : process.env.Path || process.env.PATH) || "");
|
|
2265
2290
|
let sawLoaderCandidate = false;
|
|
2266
2291
|
let sawNativeCandidate = false;
|
|
2267
2292
|
for (const rawEntry of searchPath.split(path.delimiter)) {
|
|
2268
2293
|
try {
|
|
2269
2294
|
const logical = rawEntry.trim().replace(/^"(.*)"$/, "$1");
|
|
2270
2295
|
if (!logical || !path.isAbsolute(logical)) continue;
|
|
2296
|
+
if (macPackage) {
|
|
2297
|
+
const runner = probeMacCodex(path.join(logical, "codex"), codexHome);
|
|
2298
|
+
if (runner) return (resolvedCodexRunner = runner);
|
|
2299
|
+
continue;
|
|
2300
|
+
}
|
|
2271
2301
|
// nvm/fnm and user profile mappings can put a junction on PATH. Resolve
|
|
2272
2302
|
// that directory once, then retain the ordinary-file checks below it.
|
|
2273
2303
|
const entry = realpathSync(path.resolve(logical));
|
|
@@ -2321,6 +2351,15 @@ function resolveCodexRunner(codexHome) {
|
|
|
2321
2351
|
}
|
|
2322
2352
|
|
|
2323
2353
|
function resolveCodexDesktopRunner(codexHome) {
|
|
2354
|
+
if (macPackage) {
|
|
2355
|
+
for (const directory of ["/Applications", path.join(os.homedir(), "Applications")]) {
|
|
2356
|
+
for (const app of ["ChatGPT.app", "Codex.app"]) {
|
|
2357
|
+
const runner = probeMacCodex(path.join(directory, app, "Contents", "Resources", "codex"), codexHome);
|
|
2358
|
+
if (runner) return runner;
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
return null;
|
|
2362
|
+
}
|
|
2324
2363
|
if (process.platform !== "win32") return null;
|
|
2325
2364
|
const systemRoot = process.env.SystemRoot || process.env.SYSTEMROOT;
|
|
2326
2365
|
if (!systemRoot || !path.isAbsolute(systemRoot)) return null;
|
|
@@ -2348,6 +2387,22 @@ function resolveCodexDesktopRunner(codexHome) {
|
|
|
2348
2387
|
return null;
|
|
2349
2388
|
}
|
|
2350
2389
|
|
|
2390
|
+
function probeMacCodex(logicalPath, codexHome) {
|
|
2391
|
+
// npm and Homebrew commonly expose a symlink. Execute the canonical file directly.
|
|
2392
|
+
try {
|
|
2393
|
+
const command = realpathSync(logicalPath);
|
|
2394
|
+
const metadata = lstatSync(command);
|
|
2395
|
+
if (!metadata.isFile() || !(metadata.mode & 0o111)) return null;
|
|
2396
|
+
const result = spawnSync(command, ["--version"], {
|
|
2397
|
+
encoding: "utf8", shell: false, timeout: 5000, env: minimalEnv({ codexHome }),
|
|
2398
|
+
});
|
|
2399
|
+
if (result.status === 0 && /^codex-cli\s+\d+\.\d+\.\d+/u.test(String(result.stdout || "").trim())) {
|
|
2400
|
+
return Object.freeze({ command, argsPrefix: Object.freeze([]), kind: "native" });
|
|
2401
|
+
}
|
|
2402
|
+
} catch { /* Missing or unusable CLI. */ }
|
|
2403
|
+
return null;
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2351
2406
|
function resolveRegularDescendantSync(anchor, anchorRealPath, segments) {
|
|
2352
2407
|
let observed = anchor;
|
|
2353
2408
|
for (let index = 0; index < segments.length; index += 1) {
|
|
@@ -2527,6 +2582,7 @@ function samePath(left, right) {
|
|
|
2527
2582
|
const resolved = normalizeWindowsNamespacePath(value);
|
|
2528
2583
|
let canonical = resolved;
|
|
2529
2584
|
try { canonical = realpathSync(resolved); } catch { /* comparison can still reject a missing path */ }
|
|
2585
|
+
if (macPackage) return canonical;
|
|
2530
2586
|
return normalizeWindowsNamespacePath(canonical).replace(/[\\/]+$/u, "").toLowerCase();
|
|
2531
2587
|
};
|
|
2532
2588
|
return normalize(left) === normalize(right);
|
|
@@ -2646,7 +2702,9 @@ function helpText() {
|
|
|
2646
2702
|
: [[say("安装", "Install"), "init"], [say("连接账号", "Connect an account"), connect],
|
|
2647
2703
|
[say("更新或修复", "Update or repair"), "setup"], [say("检查", "Check"), "doctor"],
|
|
2648
2704
|
[say("卸载", "Uninstall"), "uninstall"]];
|
|
2649
|
-
|
|
2705
|
+
const platform = macPackage ? " (macOS arm64, Node.js 22.16.0+)"
|
|
2706
|
+
: say("(Windows,Node.js 22.16.0+)", " (Windows, Node.js 22.16.0+)");
|
|
2707
|
+
return `${[`HelloLynk for ${CLIENT_NAMES[metadata.client]}${platform}`,
|
|
2650
2708
|
...rows.map(([label, args]) => `${label}${say(":", ": ")}${run} ${args}`),
|
|
2651
2709
|
say("加 --json 输出一行 JSON。", "Add --json for one line of JSON.")].join("\n")}\n`;
|
|
2652
2710
|
}
|
|
@@ -2720,6 +2778,9 @@ function failureText(failure) {
|
|
|
2720
2778
|
function failureReason(code, name) {
|
|
2721
2779
|
if (code === "hellolynk_node_22_16_required") return say("需要 Node.js 22.16 或更高版本。", "Node.js 22.16 or later is required.");
|
|
2722
2780
|
if (code === "hellolynk_npm_windows_only") return say("只支持 Windows。", "Windows only.");
|
|
2781
|
+
if (code === "hellolynk_npm_platform_unsupported") return say("此安装包适用于 Apple 芯片的 Mac。", "This package requires an Apple silicon Mac.");
|
|
2782
|
+
if (code === "hellolynk_npm_codex_mac_node_required") return say("请将 ChatGPT 安装到「应用程序」,打开 Codex 后再试。",
|
|
2783
|
+
"Install ChatGPT in Applications, open Codex, and try again.");
|
|
2723
2784
|
if (code === "hellolynk_npm_connect_id_invalid") {
|
|
2724
2785
|
return say("灵信号不对。请从官网复制从 hellolynk: 开始的完整灵信号。",
|
|
2725
2786
|
"This HelloLynk ID is not valid. Copy the complete ID, starting with hellolynk:, from the website.");
|