@hellolynk-ai/trae-work-mcp 0.4.96 → 0.4.98

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.
Files changed (35) hide show
  1. package/bin/hellolynk-client-setup.mjs +79 -13
  2. package/hellolynk-client-pack-manifest.json +75 -55
  3. package/hellolynk-client-pack-pin.json +1 -1
  4. package/integrations/trae-work/package.json +1 -1
  5. package/package.json +1 -1
  6. package/runtime/bootstrap/core/hellolynk-client-account.mjs +1 -1
  7. package/runtime/bootstrap/core/hellolynk-client-profile.mjs +25 -2
  8. package/runtime/bootstrap/core/hellolynk-darwin-host.mjs +269 -0
  9. package/runtime/bootstrap/core/hellolynk-darwin-vault.mjs +153 -0
  10. package/runtime/bootstrap/core/hellolynk-host-protected-store.mjs +20 -8
  11. package/runtime/bootstrap/core/hellolynk-neutral-host-installation-store.mjs +3 -7
  12. package/runtime/bootstrap/core/hellolynk-platform-credential-store.mjs +68 -14
  13. package/runtime/connect-activate.mjs +5 -1
  14. package/runtime/core/hellolynk-client-account.mjs +1 -1
  15. package/runtime/core/hellolynk-client-profile.mjs +25 -2
  16. package/runtime/core/hellolynk-client-update-entry.mjs +7 -3
  17. package/runtime/core/hellolynk-client-update-runtime.mjs +62 -33
  18. package/runtime/core/hellolynk-client-update.mjs +62 -18
  19. package/runtime/core/hellolynk-darwin-host.mjs +269 -0
  20. package/runtime/core/hellolynk-darwin-vault.mjs +153 -0
  21. package/runtime/core/hellolynk-host-protected-store.mjs +20 -8
  22. package/runtime/core/hellolynk-human-confirmation-ledger.mjs +53 -6
  23. package/runtime/core/hellolynk-local-data-protection.mjs +22 -7
  24. package/runtime/core/hellolynk-native-human-confirmation-broker.mjs +7 -5
  25. package/runtime/core/hellolynk-neutral-host-installation-store.mjs +3 -7
  26. package/runtime/core/hellolynk-neutral-host-launcher.mjs +9 -3
  27. package/runtime/core/hellolynk-neutral-host-process.mjs +1 -1
  28. package/runtime/core/hellolynk-platform-credential-store.mjs +68 -14
  29. package/runtime/core/hellolynk-release-retention.mjs +101 -2
  30. package/runtime/core/hellolynk-workbench-connection.mjs +5 -3
  31. package/runtime/neutral-host-release-loader.mjs +1 -1
  32. package/runtime/neutral-host-release-manifest.json +40 -24
  33. package/runtime/neutral-host-release-pin.json +1 -1
  34. package/runtime/platform/windows/credential-store.ps1 +46 -10
  35. package/tools/hellolynk-activate-neutral-host-clients.mjs +5 -1
@@ -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";
@@ -16,11 +16,14 @@ const PACK_PIN = "hellolynk-client-pack-pin.json";
16
16
 
17
17
  // A person at a terminal reads sentences in the system language; the updater, tests and other
18
18
  // programs read one JSON line.
19
- const jsonOutput = process.argv.includes("--json") || process.stdout.isTTY !== true;
19
+ const explicitJson = process.argv.includes("--json");
20
+ const jsonOutput = explicitJson || process.stdout.isTTY !== true;
20
21
  const CHINESE = /^zh\b/i.test(Intl.DateTimeFormat().resolvedOptions().locale);
21
22
  const CLIENT_NAMES = Object.freeze({ codex: "Codex", openclaw: "OpenClaw", "trae-work": "TRAE Work",
22
23
  workbuddy: "WorkBuddy", cursor: "Cursor", dsh: "DSH" });
23
24
  const { packageJson, metadata } = await readPackage();
25
+ const macPackage = metadata.client === "codex" && packageJson.os?.[0] === "darwin"
26
+ && packageJson.cpu?.[0] === "arm64";
24
27
  const commandArguments = process.argv.slice(2).filter((value) => value !== "--json");
25
28
  const command = String(commandArguments.shift() || "help").toLowerCase();
26
29
  const waitForPending = command === "--wait-for-pending";
@@ -61,8 +64,14 @@ try {
61
64
  "--expected-manifest-sha256", sourceRelease.outerManifestSha256,
62
65
  ]);
63
66
  } else {
64
- const originalLocations = resolveLocations();
65
67
  const accountModule = await importStableCore(PACKAGE_ROOT, "hellolynk-client-account.mjs", "hellolynk_npm_account_runtime_invalid");
68
+ const originalLocations = resolveLocations(accountModule.clientAccountBaseRoot);
69
+ if (macPackage && command !== "uninstall") {
70
+ const config = await readJson(path.join(sourceReleaseRoot, ".mcp.json"), "hellolynk_npm_release_invalid", true);
71
+ const commandPath = config.mcpServers?.["hellolynk-codex"]?.command;
72
+ if (typeof commandPath !== "string" || !path.isAbsolute(commandPath)) fail("hellolynk_npm_release_invalid");
73
+ await fs.access(commandPath, constants.X_OK).catch(() => fail("hellolynk_npm_codex_mac_node_required"));
74
+ }
66
75
  const baseRoot = accountModule.clientAccountBaseRoot(originalLocations.hostRoot);
67
76
  const packageLocations = { ...originalLocations, hostRoot: baseRoot, finalCurrentRoot: path.dirname(baseRoot) };
68
77
  const accounts = accountModule.createClientAccountActions({ client: metadata.client, storeRoot: baseRoot });
@@ -250,6 +259,10 @@ try {
250
259
  await verifyExactBinding({ ...installed, locations, activation });
251
260
  await verifyClientConfiguration({ ...installed, locations });
252
261
  }
262
+ // A running unsigned updater asks the stable package for implicit JSON. A
263
+ // staged package may still prove its own first install after lost stdout.
264
+ const legacyUpdateProof = installed && !existingDoctor && !explicitJson && jsonOutput
265
+ && process.env.HELLOLYNK_NEUTRAL_STORE_ROOT && samePath(PACKAGE_ROOT, installed.packageRoot);
253
266
  print({
254
267
  ok: true,
255
268
  client: metadata.client,
@@ -260,7 +273,7 @@ try {
260
273
  activated: activation.ready,
261
274
  activationState: activation.state,
262
275
  stableReleaseVerified: installed != null,
263
- exactBindingVerified: installed != null,
276
+ ...(legacyUpdateProof ? {} : { exactBindingVerified: installed != null }),
264
277
  clientConfigurationVerified: installed != null,
265
278
  installsNode: false,
266
279
  installsGit: false,
@@ -429,7 +442,8 @@ async function uninstallClient(locations) {
429
442
  if (receiverConfigured) await receiver.configureTraeNativeTaskWorker({ storeRoot: locations.hostRoot, enabled: false });
430
443
  }
431
444
  // A binding names the release it starts, so it cannot outlive the releases removed below.
432
- if (await exists(path.join(locations.hostRoot, "capabilities-v1.dpapi.clixml"))) {
445
+ const protectedFile = macPackage ? "protected-v1.sqlite" : "capabilities-v1.dpapi.clixml";
446
+ if (await exists(path.join(locations.hostRoot, protectedFile))) {
433
447
  const store = await importStableCore(PACKAGE_ROOT, "hellolynk-host-protected-store.mjs", "hellolynk_npm_binding_invalid");
434
448
  await store.createHostProtectedStore({ root: locations.hostRoot, followClientAccount: false }).disconnectLocalClient(metadata.client);
435
449
  }
@@ -838,17 +852,20 @@ async function verifyRelease(releaseRoot, packageRoot, expectedMetadata = metada
838
852
  return Object.freeze({ manifestSha256, outerManifestSha256 });
839
853
  }
840
854
 
841
- function resolveLocations() {
842
- if (process.platform !== "win32") fail("hellolynk_npm_windows_only");
843
- const home = path.resolve(process.env.USERPROFILE || os.homedir());
844
- const localAppData = path.resolve(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"));
845
- const appData = path.resolve(process.env.APPDATA || path.join(home, "AppData", "Roaming"));
855
+ function resolveLocations(getDefaultHostRoot) {
856
+ if (macPackage) {
857
+ if (process.platform !== "darwin" || process.arch !== "arm64") fail("hellolynk_npm_platform_unsupported");
858
+ } else if (process.platform !== "win32") fail("hellolynk_npm_windows_only");
859
+ const home = path.resolve((macPackage ? process.env.HOME : process.env.USERPROFILE) || os.homedir());
860
+ const localAppData = macPackage ? path.join(home, "Library", "Application Support")
861
+ : path.resolve(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"));
862
+ const appData = macPackage ? localAppData : path.resolve(process.env.APPDATA || path.join(home, "AppData", "Roaming"));
846
863
  const configuredCodexHome = String(process.env.CODEX_HOME || "");
847
864
  if (configuredCodexHome && !path.isAbsolute(configuredCodexHome)) fail("hellolynk_npm_codex_home_invalid");
848
865
  const codexHome = path.resolve(configuredCodexHome || path.join(home, ".codex"));
849
866
  const configuredHostRoot = String(process.env.HELLOLYNK_NEUTRAL_STORE_ROOT || "").trim();
850
867
  if (configuredHostRoot && !path.isAbsolute(configuredHostRoot)) fail("hellolynk_npm_store_root_invalid");
851
- const hostRoot = path.resolve(configuredHostRoot || path.join(localAppData, "HelloLynk", "host"));
868
+ const hostRoot = path.resolve(configuredHostRoot || getDefaultHostRoot());
852
869
  if (configuredHostRoot && path.basename(hostRoot).toLowerCase() !== "host") {
853
870
  fail("hellolynk_npm_store_root_invalid");
854
871
  }
@@ -1004,6 +1021,12 @@ async function startHostWhenAbsent(runtime, binding) {
1004
1021
  }
1005
1022
 
1006
1023
  async function secureStableReleaseTree(locations, releaseId, options = {}) {
1024
+ const releasePath = path.resolve(locations.finalCurrentRoot, "releases", releaseId);
1025
+ // An existing AppData root can be shared while a new release is redirected
1026
+ // into one desktop app's private cache. Other clients cannot use that release.
1027
+ if (process.platform === "win32" && realpathSync.native(releasePath).toLowerCase() !== releasePath.toLowerCase()) {
1028
+ fail("client_root_alias_rejected");
1029
+ }
1007
1030
  const module = await importCore(
1008
1031
  "hellolynk-platform-credential-store.mjs",
1009
1032
  "hellolynk_npm_client_root_security_unavailable",
@@ -2246,6 +2269,13 @@ function runCodexJson(args, code, codexHome) {
2246
2269
  }
2247
2270
 
2248
2271
  function minimalEnv({ codexHome = null } = {}) {
2272
+ if (macPackage) return Object.freeze({
2273
+ PATH: process.env.PATH || "/usr/bin:/bin",
2274
+ HOME: process.env.HOME || os.homedir(),
2275
+ TMPDIR: process.env.TMPDIR || os.tmpdir(),
2276
+ LANG: process.env.LANG || "en_US.UTF-8",
2277
+ ...(codexHome ? { CODEX_HOME: codexHome } : {}),
2278
+ });
2249
2279
  return Object.freeze({
2250
2280
  PATH: process.env.Path || process.env.PATH || "",
2251
2281
  PATHEXT: process.env.PATHEXT || "",
@@ -2261,13 +2291,18 @@ function minimalEnv({ codexHome = null } = {}) {
2261
2291
 
2262
2292
  function resolveCodexRunner(codexHome) {
2263
2293
  if (resolvedCodexRunner) return resolvedCodexRunner;
2264
- const searchPath = String(process.env.Path || process.env.PATH || "");
2294
+ const searchPath = String((macPackage ? process.env.PATH : process.env.Path || process.env.PATH) || "");
2265
2295
  let sawLoaderCandidate = false;
2266
2296
  let sawNativeCandidate = false;
2267
2297
  for (const rawEntry of searchPath.split(path.delimiter)) {
2268
2298
  try {
2269
2299
  const logical = rawEntry.trim().replace(/^"(.*)"$/, "$1");
2270
2300
  if (!logical || !path.isAbsolute(logical)) continue;
2301
+ if (macPackage) {
2302
+ const runner = probeMacCodex(path.join(logical, "codex"), codexHome);
2303
+ if (runner) return (resolvedCodexRunner = runner);
2304
+ continue;
2305
+ }
2271
2306
  // nvm/fnm and user profile mappings can put a junction on PATH. Resolve
2272
2307
  // that directory once, then retain the ordinary-file checks below it.
2273
2308
  const entry = realpathSync(path.resolve(logical));
@@ -2321,6 +2356,15 @@ function resolveCodexRunner(codexHome) {
2321
2356
  }
2322
2357
 
2323
2358
  function resolveCodexDesktopRunner(codexHome) {
2359
+ if (macPackage) {
2360
+ for (const directory of ["/Applications", path.join(os.homedir(), "Applications")]) {
2361
+ for (const app of ["ChatGPT.app", "Codex.app"]) {
2362
+ const runner = probeMacCodex(path.join(directory, app, "Contents", "Resources", "codex"), codexHome);
2363
+ if (runner) return runner;
2364
+ }
2365
+ }
2366
+ return null;
2367
+ }
2324
2368
  if (process.platform !== "win32") return null;
2325
2369
  const systemRoot = process.env.SystemRoot || process.env.SYSTEMROOT;
2326
2370
  if (!systemRoot || !path.isAbsolute(systemRoot)) return null;
@@ -2348,6 +2392,22 @@ function resolveCodexDesktopRunner(codexHome) {
2348
2392
  return null;
2349
2393
  }
2350
2394
 
2395
+ function probeMacCodex(logicalPath, codexHome) {
2396
+ // npm and Homebrew commonly expose a symlink. Execute the canonical file directly.
2397
+ try {
2398
+ const command = realpathSync(logicalPath);
2399
+ const metadata = lstatSync(command);
2400
+ if (!metadata.isFile() || !(metadata.mode & 0o111)) return null;
2401
+ const result = spawnSync(command, ["--version"], {
2402
+ encoding: "utf8", shell: false, timeout: 5000, env: minimalEnv({ codexHome }),
2403
+ });
2404
+ if (result.status === 0 && /^codex-cli\s+\d+\.\d+\.\d+/u.test(String(result.stdout || "").trim())) {
2405
+ return Object.freeze({ command, argsPrefix: Object.freeze([]), kind: "native" });
2406
+ }
2407
+ } catch { /* Missing or unusable CLI. */ }
2408
+ return null;
2409
+ }
2410
+
2351
2411
  function resolveRegularDescendantSync(anchor, anchorRealPath, segments) {
2352
2412
  let observed = anchor;
2353
2413
  for (let index = 0; index < segments.length; index += 1) {
@@ -2527,6 +2587,7 @@ function samePath(left, right) {
2527
2587
  const resolved = normalizeWindowsNamespacePath(value);
2528
2588
  let canonical = resolved;
2529
2589
  try { canonical = realpathSync(resolved); } catch { /* comparison can still reject a missing path */ }
2590
+ if (macPackage) return canonical;
2530
2591
  return normalizeWindowsNamespacePath(canonical).replace(/[\\/]+$/u, "").toLowerCase();
2531
2592
  };
2532
2593
  return normalize(left) === normalize(right);
@@ -2646,7 +2707,9 @@ function helpText() {
2646
2707
  : [[say("安装", "Install"), "init"], [say("连接账号", "Connect an account"), connect],
2647
2708
  [say("更新或修复", "Update or repair"), "setup"], [say("检查", "Check"), "doctor"],
2648
2709
  [say("卸载", "Uninstall"), "uninstall"]];
2649
- return `${[`HelloLynk for ${CLIENT_NAMES[metadata.client]}${say("(Windows,Node.js 22.16.0+)", " (Windows, Node.js 22.16.0+)")}`,
2710
+ const platform = macPackage ? " (macOS arm64, Node.js 22.16.0+)"
2711
+ : say("(Windows,Node.js 22.16.0+)", " (Windows, Node.js 22.16.0+)");
2712
+ return `${[`HelloLynk for ${CLIENT_NAMES[metadata.client]}${platform}`,
2650
2713
  ...rows.map(([label, args]) => `${label}${say(":", ": ")}${run} ${args}`),
2651
2714
  say("加 --json 输出一行 JSON。", "Add --json for one line of JSON.")].join("\n")}\n`;
2652
2715
  }
@@ -2720,6 +2783,9 @@ function failureText(failure) {
2720
2783
  function failureReason(code, name) {
2721
2784
  if (code === "hellolynk_node_22_16_required") return say("需要 Node.js 22.16 或更高版本。", "Node.js 22.16 or later is required.");
2722
2785
  if (code === "hellolynk_npm_windows_only") return say("只支持 Windows。", "Windows only.");
2786
+ if (code === "hellolynk_npm_platform_unsupported") return say("此安装包适用于 Apple 芯片的 Mac。", "This package requires an Apple silicon Mac.");
2787
+ if (code === "hellolynk_npm_codex_mac_node_required") return say("请将 ChatGPT 安装到「应用程序」,打开 Codex 后再试。",
2788
+ "Install ChatGPT in Applications, open Codex, and try again.");
2723
2789
  if (code === "hellolynk_npm_connect_id_invalid") {
2724
2790
  return say("灵信号不对。请从官网复制从 hellolynk: 开始的完整灵信号。",
2725
2791
  "This HelloLynk ID is not valid. Copy the complete ID, starting with hellolynk:, from the website.");
@@ -2,7 +2,7 @@
2
2
  "contract": "hellolynk-client-npm-pack-manifest-v1",
3
3
  "client": "trae-work",
4
4
  "packageName": "@hellolynk-ai/trae-work-mcp",
5
- "version": "0.4.96",
5
+ "version": "0.4.98",
6
6
  "workbench": {
7
7
  "path": "runtime/workbench/hellolynk-workbench-build.json",
8
8
  "contract": "hellolynk-shared-workbench-build-v1",
@@ -12,8 +12,8 @@
12
12
  "files": [
13
13
  {
14
14
  "path": "bin/hellolynk-client-setup.mjs",
15
- "bytes": 141769,
16
- "sha256": "0bb0706c06bd193cfa37007dd95e3107b52aacb0a7ebaec2249b153ff7dd772b"
15
+ "bytes": 145615,
16
+ "sha256": "044321ea6c5757a985b92a826ffc1fb3ffa4fb8355b732abecc64210d4ac3399"
17
17
  },
18
18
  {
19
19
  "path": "bin/hellolynk-mcp-config-shape.mjs",
@@ -23,7 +23,7 @@
23
23
  {
24
24
  "path": "integrations/trae-work/package.json",
25
25
  "bytes": 495,
26
- "sha256": "ce683cd463372123a217bf1c12273acd4ca18d52061fa9be3d3928416c2962d1"
26
+ "sha256": "76d72f67de8dc545e61f39ad7edc996f5ce6344078e897fddfe3ff3c67eb5994"
27
27
  },
28
28
  {
29
29
  "path": "integrations/trae-work/runtime/neutral-host-bootstrap.mjs",
@@ -103,7 +103,7 @@
103
103
  {
104
104
  "path": "package.json",
105
105
  "bytes": 1850,
106
- "sha256": "49eccf3664afaea43b576bced8afdcaef575f4d77fdf95bcc0d79119898a4d6b"
106
+ "sha256": "044b9058ec8fbd7c098085fd0bfc72401a65fed9c4a9bc2700be9214a5adba85"
107
107
  },
108
108
  {
109
109
  "path": "README.md",
@@ -112,8 +112,8 @@
112
112
  },
113
113
  {
114
114
  "path": "runtime/bootstrap/core/hellolynk-client-account.mjs",
115
- "bytes": 8594,
116
- "sha256": "a22f14f494c1a44a9272ca95e160f8cb1df612a1ceb8b54e32596b13f90c3740"
115
+ "bytes": 8603,
116
+ "sha256": "57082d5ea5e068dad81a47dd8abd38e34663e4563d8efa40f5130b817a346670"
117
117
  },
118
118
  {
119
119
  "path": "runtime/bootstrap/core/hellolynk-client-core.mjs",
@@ -122,8 +122,18 @@
122
122
  },
123
123
  {
124
124
  "path": "runtime/bootstrap/core/hellolynk-client-profile.mjs",
125
- "bytes": 8473,
126
- "sha256": "81d4f64c11c8dbccec04a05435cc42b53823db2649f2c88739647299b3c97fd2"
125
+ "bytes": 9573,
126
+ "sha256": "4528f2eb90417dbe232c4fef254beeb20c94f9216388ec721f982dd7ee4adde5"
127
+ },
128
+ {
129
+ "path": "runtime/bootstrap/core/hellolynk-darwin-host.mjs",
130
+ "bytes": 15511,
131
+ "sha256": "43dba4cd61cff66f2479c39532e504348a46e76faae0f7b1e09a7a7f5362e64a"
132
+ },
133
+ {
134
+ "path": "runtime/bootstrap/core/hellolynk-darwin-vault.mjs",
135
+ "bytes": 7659,
136
+ "sha256": "2972df9fa8a0d7594072a39bc8dfa2a41b8fb33ddf79cc5abe5e66636c1ea3ca"
127
137
  },
128
138
  {
129
139
  "path": "runtime/bootstrap/core/hellolynk-host-auth.mjs",
@@ -132,8 +142,8 @@
132
142
  },
133
143
  {
134
144
  "path": "runtime/bootstrap/core/hellolynk-host-protected-store.mjs",
135
- "bytes": 129557,
136
- "sha256": "0cefa22574df9dd99073d73bb688e9cae3faf6da862af013c1dfe9c87efef32e"
145
+ "bytes": 130518,
146
+ "sha256": "bb0167b7861de2c408b90c16f24765f45dfeca7033f90d31e17dca3fc9e30c41"
137
147
  },
138
148
  {
139
149
  "path": "runtime/bootstrap/core/hellolynk-local-process-lock.mjs",
@@ -142,13 +152,13 @@
142
152
  },
143
153
  {
144
154
  "path": "runtime/bootstrap/core/hellolynk-neutral-host-installation-store.mjs",
145
- "bytes": 34290,
146
- "sha256": "9ff399639d320e5527e51cd0ddbf049e7e0e8d3cc225cdc30f0d4637356a1590"
155
+ "bytes": 33993,
156
+ "sha256": "f6e04183e8e0c945006c5348ed251833ec12a6ab9777031609b5a3ccd0d2252d"
147
157
  },
148
158
  {
149
159
  "path": "runtime/bootstrap/core/hellolynk-platform-credential-store.mjs",
150
- "bytes": 35294,
151
- "sha256": "0558aca043ff586f10d7b82e1b2fe9b537ff661913dce76fc92feaf9bd7e5546"
160
+ "bytes": 39386,
161
+ "sha256": "0ab136d36e890309b4cb5ff6f1cef6f3d82caf65f5b1d08c7b3992442ffe38a7"
152
162
  },
153
163
  {
154
164
  "path": "runtime/bootstrap/core/hellolynk-runtime-safety.cjs",
@@ -162,8 +172,8 @@
162
172
  },
163
173
  {
164
174
  "path": "runtime/connect-activate.mjs",
165
- "bytes": 33499,
166
- "sha256": "50ec8b0a58ac5b099a653722b0946acb23d0a29a054bfb3856dc963db6f84bee"
175
+ "bytes": 33789,
176
+ "sha256": "93c68c23ed2d18e87766ecd8dae6c3d8e757eca6ad7569477c8ec994402a8b0e"
167
177
  },
168
178
  {
169
179
  "path": "runtime/core/hellolynk-agent-configurator.mjs",
@@ -172,8 +182,8 @@
172
182
  },
173
183
  {
174
184
  "path": "runtime/core/hellolynk-client-account.mjs",
175
- "bytes": 8594,
176
- "sha256": "a22f14f494c1a44a9272ca95e160f8cb1df612a1ceb8b54e32596b13f90c3740"
185
+ "bytes": 8603,
186
+ "sha256": "57082d5ea5e068dad81a47dd8abd38e34663e4563d8efa40f5130b817a346670"
177
187
  },
178
188
  {
179
189
  "path": "runtime/core/hellolynk-client-core.mjs",
@@ -182,29 +192,39 @@
182
192
  },
183
193
  {
184
194
  "path": "runtime/core/hellolynk-client-profile.mjs",
185
- "bytes": 8473,
186
- "sha256": "81d4f64c11c8dbccec04a05435cc42b53823db2649f2c88739647299b3c97fd2"
195
+ "bytes": 9573,
196
+ "sha256": "4528f2eb90417dbe232c4fef254beeb20c94f9216388ec721f982dd7ee4adde5"
187
197
  },
188
198
  {
189
199
  "path": "runtime/core/hellolynk-client-update-entry.mjs",
190
- "bytes": 1612,
191
- "sha256": "dc62228a7351c721514b5ca7921d485dc6aa05475aaa2e3881b78d7de0e1a134"
200
+ "bytes": 1974,
201
+ "sha256": "8b872933f9883a92889202cf370e1e8d878c2172e4e1c5d8aa8261f314577d90"
192
202
  },
193
203
  {
194
204
  "path": "runtime/core/hellolynk-client-update-runtime.mjs",
195
- "bytes": 40309,
196
- "sha256": "0a76f2bdcf338c544e493ca7d0b7168f03ffa32ed223e3537eccafc1cbaafba0"
205
+ "bytes": 42247,
206
+ "sha256": "6bdcc525579963fa3ffc46f29527817acc0b8090fdc6a9cbdadb0fc262eee12e"
197
207
  },
198
208
  {
199
209
  "path": "runtime/core/hellolynk-client-update.mjs",
200
- "bytes": 28385,
201
- "sha256": "a4104a67dd72cb7a1950585c92aa8424b9387c1eda4f191e0df3f901c4f16a8f"
210
+ "bytes": 31391,
211
+ "sha256": "374690bb6cc7335b5f1cf030c33989aba9713e0922369edda0348b40ef71b02f"
202
212
  },
203
213
  {
204
214
  "path": "runtime/core/hellolynk-contact-request-e2ee.mjs",
205
215
  "bytes": 35030,
206
216
  "sha256": "18526628b354d18bcbe5e621360ecfcd5dfa4cb4d91397fb87d0c20e1f332a5d"
207
217
  },
218
+ {
219
+ "path": "runtime/core/hellolynk-darwin-host.mjs",
220
+ "bytes": 15511,
221
+ "sha256": "43dba4cd61cff66f2479c39532e504348a46e76faae0f7b1e09a7a7f5362e64a"
222
+ },
223
+ {
224
+ "path": "runtime/core/hellolynk-darwin-vault.mjs",
225
+ "bytes": 7659,
226
+ "sha256": "2972df9fa8a0d7594072a39bc8dfa2a41b8fb33ddf79cc5abe5e66636c1ea3ca"
227
+ },
208
228
  {
209
229
  "path": "runtime/core/hellolynk-device-enrollment.mjs",
210
230
  "bytes": 27099,
@@ -227,8 +247,8 @@
227
247
  },
228
248
  {
229
249
  "path": "runtime/core/hellolynk-host-protected-store.mjs",
230
- "bytes": 129557,
231
- "sha256": "0cefa22574df9dd99073d73bb688e9cae3faf6da862af013c1dfe9c87efef32e"
250
+ "bytes": 130518,
251
+ "sha256": "bb0167b7861de2c408b90c16f24765f45dfeca7033f90d31e17dca3fc9e30c41"
232
252
  },
233
253
  {
234
254
  "path": "runtime/core/hellolynk-host-transport-client.mjs",
@@ -242,8 +262,8 @@
242
262
  },
243
263
  {
244
264
  "path": "runtime/core/hellolynk-human-confirmation-ledger.mjs",
245
- "bytes": 11327,
246
- "sha256": "265ae39e93112416588841a14eb0351905d60b2552cf04c8cf8bd057acd64586"
265
+ "bytes": 14719,
266
+ "sha256": "746f2d23f19fa110ecd87d0b1dc3d88138776accc3b177afd8f5d266223ccc81"
247
267
  },
248
268
  {
249
269
  "path": "runtime/core/hellolynk-human-relationship-controller.mjs",
@@ -282,8 +302,8 @@
282
302
  },
283
303
  {
284
304
  "path": "runtime/core/hellolynk-local-data-protection.mjs",
285
- "bytes": 26467,
286
- "sha256": "798f42e9bd45a00565b628282233a55abfdc4d7102423cb0558a7e01fab76810"
305
+ "bytes": 27425,
306
+ "sha256": "e33b0c83fff59ba3ed49ae880d1b95016be4457bc7fd223367683942c78525bc"
287
307
  },
288
308
  {
289
309
  "path": "runtime/core/hellolynk-local-identity-trust.mjs",
@@ -327,8 +347,8 @@
327
347
  },
328
348
  {
329
349
  "path": "runtime/core/hellolynk-native-human-confirmation-broker.mjs",
330
- "bytes": 40527,
331
- "sha256": "755fd03a4ee3b97cdfdb1efc491fb4cf602e25173819380ea8a715c04c82ea5a"
350
+ "bytes": 40773,
351
+ "sha256": "98d986f492a9e646f4601f25588cabe065e3c7bb00f0773b5dfd99e72e65c324"
332
352
  },
333
353
  {
334
354
  "path": "runtime/core/hellolynk-native-inbox-runtime.mjs",
@@ -357,18 +377,18 @@
357
377
  },
358
378
  {
359
379
  "path": "runtime/core/hellolynk-neutral-host-installation-store.mjs",
360
- "bytes": 34290,
361
- "sha256": "9ff399639d320e5527e51cd0ddbf049e7e0e8d3cc225cdc30f0d4637356a1590"
380
+ "bytes": 33993,
381
+ "sha256": "f6e04183e8e0c945006c5348ed251833ec12a6ab9777031609b5a3ccd0d2252d"
362
382
  },
363
383
  {
364
384
  "path": "runtime/core/hellolynk-neutral-host-launcher.mjs",
365
- "bytes": 30122,
366
- "sha256": "490f8010bd84fc7c92a00ec4d4a996c27dd398b2e3584ded8bcebb74c598c18d"
385
+ "bytes": 30326,
386
+ "sha256": "0afe5310d1d9f7b1448a9f50aeb2c1fc93b42ce7eb48dd8472fbde5d33e898af"
367
387
  },
368
388
  {
369
389
  "path": "runtime/core/hellolynk-neutral-host-process.mjs",
370
390
  "bytes": 229535,
371
- "sha256": "5e5b9f535331444d284b2e62cc2593d6279b8a30332c82f4f85c7ff25e2f3727"
391
+ "sha256": "634279c96b8b4e83bcbcc92c5184f4ec7c31713a097f45af3f5650f8151fb78b"
372
392
  },
373
393
  {
374
394
  "path": "runtime/core/hellolynk-neutral-host-store-adapters.mjs",
@@ -382,8 +402,8 @@
382
402
  },
383
403
  {
384
404
  "path": "runtime/core/hellolynk-platform-credential-store.mjs",
385
- "bytes": 35294,
386
- "sha256": "0558aca043ff586f10d7b82e1b2fe9b537ff661913dce76fc92feaf9bd7e5546"
405
+ "bytes": 39386,
406
+ "sha256": "0ab136d36e890309b4cb5ff6f1cef6f3d82caf65f5b1d08c7b3992442ffe38a7"
387
407
  },
388
408
  {
389
409
  "path": "runtime/core/hellolynk-relay-client-cli.mjs",
@@ -392,8 +412,8 @@
392
412
  },
393
413
  {
394
414
  "path": "runtime/core/hellolynk-release-retention.mjs",
395
- "bytes": 20922,
396
- "sha256": "9f8b5b97eee7530dc8ef965b0df6a19065b06012255100977d8abb17ce50d204"
415
+ "bytes": 26013,
416
+ "sha256": "b894c452019b89486dd3090c9eeee7b7c2bb4e50753565bf88ecd14ce0efeaf1"
397
417
  },
398
418
  {
399
419
  "path": "runtime/core/hellolynk-runtime-safety.cjs",
@@ -407,8 +427,8 @@
407
427
  },
408
428
  {
409
429
  "path": "runtime/core/hellolynk-workbench-connection.mjs",
410
- "bytes": 14486,
411
- "sha256": "198fb21c3db2c91b85ca38d334c0ffe56ef28f2f052b6b62a8d2ed5c166fcd82"
430
+ "bytes": 14575,
431
+ "sha256": "0f24d28316253a761dc03d8096dace3da7a3cf8cb8eaf575765b2aa07d30274c"
412
432
  },
413
433
  {
414
434
  "path": "runtime/neutral-host-bootstrap.mjs",
@@ -422,18 +442,18 @@
422
442
  },
423
443
  {
424
444
  "path": "runtime/neutral-host-release-loader.mjs",
425
- "bytes": 7599,
426
- "sha256": "70bacded7cd42bef424e927d4002b6171aa613b0609f62ea02ebe8344359bfd6"
445
+ "bytes": 7609,
446
+ "sha256": "137c5663e34ef8ee62340b1c2d46f7284dc60576b6f25d3d0122390bb600e372"
427
447
  },
428
448
  {
429
449
  "path": "runtime/neutral-host-release-manifest.json",
430
- "bytes": 15032,
431
- "sha256": "b5af5aa6e30ccbb16a0f2f7d93297dda19871e52bf69d3e222667e5258f38db4"
450
+ "bytes": 15630,
451
+ "sha256": "719385851a5847c41a5d32c1ab1c13d6057db194f9345e1df3212190b13d1192"
432
452
  },
433
453
  {
434
454
  "path": "runtime/neutral-host-release-pin.json",
435
455
  "bytes": 146,
436
- "sha256": "8ca524cbb349659eb01dbfaa36d63a54a2780e77ee8a449441afd6c1bfcba9af"
456
+ "sha256": "5e85436a917df172ea0e8fbddf1ec296135d7b1ec847d5a54ccc5a8db4078010"
437
457
  },
438
458
  {
439
459
  "path": "runtime/platform/windows/configure-agent.ps1",
@@ -442,8 +462,8 @@
442
462
  },
443
463
  {
444
464
  "path": "runtime/platform/windows/credential-store.ps1",
445
- "bytes": 39278,
446
- "sha256": "7ec7362eba2c442d9417035ff14c1108c7a58558b6f09ac36a2275828370debb"
465
+ "bytes": 41068,
466
+ "sha256": "4817c3c91d5d180763794a7a528f83664602f34cf1d1a8396e75ad6d56bd874f"
447
467
  },
448
468
  {
449
469
  "path": "runtime/platform/windows/hellolynk-host-protected-store.ps1",
@@ -607,8 +627,8 @@
607
627
  },
608
628
  {
609
629
  "path": "tools/hellolynk-activate-neutral-host-clients.mjs",
610
- "bytes": 33553,
611
- "sha256": "f8007370c54756e4792affe3fbffe5209b3ece619eddc5713c20c8bed8a86b34"
630
+ "bytes": 33852,
631
+ "sha256": "123eb4a08cf5a6df748972c64c5cf911697a669e68ecab7c409c1c4006c47277"
612
632
  },
613
633
  {
614
634
  "path": "tools/hellolynk-install-client-skills.mjs",
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "contract": "hellolynk-client-npm-pack-pin-v1",
3
- "manifestSha256": "2c72d065aff9243a2e32740fe00f4304c7559123f97418f9b12f7563eebb889e"
3
+ "manifestSha256": "1978e485dcdcfaa07baf9a8ee837b111ab28a25cc1ee6e24d49c2bd02d3608c4"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellolynk-ai/trae-work-mcp",
3
- "version": "0.4.96",
3
+ "version": "0.4.98",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "TRAE Work one-click bridge for local HelloLynk Messaging.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellolynk-ai/trae-work-mcp",
3
- "version": "0.4.96",
3
+ "version": "0.4.98",
4
4
  "description": "HelloLynk Messaging for TRAE Work: open conversations and let your AI message other people's AI assistants.",
5
5
  "homepage": "https://hellolynk.com",
6
6
  "repository": {
@@ -68,7 +68,7 @@ export function withClientAccountLock(client, root, operation) {
68
68
 
69
69
  export function createClientAccountActions(options) {
70
70
  const client = options?.client;
71
- const root = options?.storeRoot || defaultNeutralHostStoreRoot("win32", options?.env || process.env);
71
+ const root = options?.storeRoot || defaultNeutralHostStoreRoot(process.platform, options?.env || process.env);
72
72
  statePath(client, clientAccountBaseRoot(root));
73
73
  const readAccountState = () => {
74
74
  const state = readClientAccount(client, root);
@@ -1,4 +1,5 @@
1
1
  import { lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
2
+ import { readdirSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
4
5
  import { randomUUID } from "node:crypto";
@@ -19,12 +20,34 @@ const SAFE_SCOPE = /^[a-z][a-z0-9_.:-]{0,127}$/;
19
20
  const MAX_PROFILE_BYTES = 64 * 1024;
20
21
 
21
22
  export function defaultHelloLynkClientRoot(platform = process.platform, env = process.env) {
22
- const home = resolve(String(env.HOME || env.USERPROFILE || homedir()));
23
- if (platform === "win32") return resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
23
+ const home = resolve(String((platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME || env.USERPROFILE) || homedir()));
24
+ if (platform === "win32") {
25
+ const current = join(home, ".hellolynk", "hellolynk-v2");
26
+ // Once selected, another client's older installer must not move us back.
27
+ if (hasWindowsClientInstallation(current)) return current;
28
+ const existing = resolve(String(env.LOCALAPPDATA || join(home, "AppData", "Local")), "HelloLynk");
29
+ // AppData created from a packaged desktop app can be private to that app.
30
+ // Keep an existing installation; an empty failed setup is not an account.
31
+ if (hasWindowsClientInstallation(existing)) return existing;
32
+ return current;
33
+ }
24
34
  if (platform === "darwin") return join(home, "Library", "Application Support", "HelloLynk");
25
35
  return resolve(String(env.XDG_DATA_HOME || join(home, ".local", "share")), "hellolynk");
26
36
  }
27
37
 
38
+ function hasWindowsClientInstallation(root) {
39
+ for (const directory of ["profiles", "releases", "host", "credentials", "e2ee-private-keys"]) {
40
+ try {
41
+ const entries = readdirSync(join(root, directory), { withFileTypes: true });
42
+ if (entries.some((entry) => directory !== "host" || entry.name !== "runtime")) return true;
43
+ } catch (error) {
44
+ // An unreadable existing location must not silently become a fresh account.
45
+ if (error.code !== "ENOENT") return true;
46
+ }
47
+ }
48
+ return false;
49
+ }
50
+
28
51
  function safeId(value, code) {
29
52
  const normalized = String(value || "").trim();
30
53
  if (!SAFE_ID.test(normalized)) throw new Error(code);