@hellolynk-ai/trae-work-mcp 0.4.101 → 0.4.102

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.
@@ -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.101",
5
+ "version": "0.4.102",
6
6
  "workbench": {
7
7
  "path": "runtime/workbench/hellolynk-workbench-build.json",
8
8
  "contract": "hellolynk-shared-workbench-build-v1",
@@ -23,7 +23,7 @@
23
23
  {
24
24
  "path": "integrations/trae-work/package.json",
25
25
  "bytes": 496,
26
- "sha256": "2eb6935f4e8faf49d6010c810eac516b5887f8aee4d534a486d486cac60235b2"
26
+ "sha256": "cffb8384ee280dd92011c0ad57052ccccf2bbf7138ef0bec635ae33e8532e9ed"
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": 1851,
106
- "sha256": "9d932e4a6de05ea4db57fa083e3c5bc8cc27c170376393fdb05ea8d40fad33a0"
106
+ "sha256": "01fbaf301446a6a11313101972885ad30ea4cb960cccd7400c0516a36c4d35ac"
107
107
  },
108
108
  {
109
109
  "path": "README.md",
@@ -117,8 +117,8 @@
117
117
  },
118
118
  {
119
119
  "path": "runtime/bootstrap/core/hellolynk-client-core.mjs",
120
- "bytes": 36628,
121
- "sha256": "5d2190c2354ede169b2053864674c7ae5b80985970dc13609d6818c5a6d16940"
120
+ "bytes": 37550,
121
+ "sha256": "186332d5dea8876cf8ca57fef35e9810df5256ed36f704f7bd3840e45c406a4a"
122
122
  },
123
123
  {
124
124
  "path": "runtime/bootstrap/core/hellolynk-client-profile.mjs",
@@ -187,8 +187,8 @@
187
187
  },
188
188
  {
189
189
  "path": "runtime/core/hellolynk-client-core.mjs",
190
- "bytes": 36628,
191
- "sha256": "5d2190c2354ede169b2053864674c7ae5b80985970dc13609d6818c5a6d16940"
190
+ "bytes": 37550,
191
+ "sha256": "186332d5dea8876cf8ca57fef35e9810df5256ed36f704f7bd3840e45c406a4a"
192
192
  },
193
193
  {
194
194
  "path": "runtime/core/hellolynk-client-profile.mjs",
@@ -388,7 +388,7 @@
388
388
  {
389
389
  "path": "runtime/core/hellolynk-neutral-host-process.mjs",
390
390
  "bytes": 234159,
391
- "sha256": "0a66fca2b862fde9269722f026fc67e9d1c79435f0d410809aee669be9f9f497"
391
+ "sha256": "42d29af2f0ac96252d694996864d54b3fddda47d6ad5405020a1354e13372efa"
392
392
  },
393
393
  {
394
394
  "path": "runtime/core/hellolynk-neutral-host-store-adapters.mjs",
@@ -448,12 +448,12 @@
448
448
  {
449
449
  "path": "runtime/neutral-host-release-manifest.json",
450
450
  "bytes": 15630,
451
- "sha256": "8561015215e14fe8f8b5f1a18ecccefa717cdff05c40f8eee8d21af328bc3174"
451
+ "sha256": "d2cff22cd8e4a224bf24c4a57b67d4c7a4adce9721405d81da52c7eb3c3032ab"
452
452
  },
453
453
  {
454
454
  "path": "runtime/neutral-host-release-pin.json",
455
455
  "bytes": 146,
456
- "sha256": "e68717f720a3f92c3af036dc99556ff188c6b3249f65c55bbbef675d92235176"
456
+ "sha256": "1a602dba63e67f62d8050cba71fde3a7c468b5acfa8568fe459b540bbfce57ad"
457
457
  },
458
458
  {
459
459
  "path": "runtime/platform/windows/configure-agent.ps1",
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "contract": "hellolynk-client-npm-pack-pin-v1",
3
- "manifestSha256": "bec00be31829b1e18fe19ef76fd7b5650ce85c0f9f2c2d45ddf5203559b65037"
3
+ "manifestSha256": "f1543b1479b699c126c965e05f9f0543c8d4225f54e2211166043d9f9476362f"
4
4
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hellolynk-ai/trae-work-mcp",
3
- "version": "0.4.101",
3
+ "version": "0.4.102",
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.101",
3
+ "version": "0.4.102",
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": {
@@ -387,7 +387,9 @@ export async function issueDeviceRuntimeSession(options) {
387
387
  }
388
388
  return fresh;
389
389
  }
390
- throw new HelloLynkClientError(safeDeviceRuntimeErrorCode(result?.error), {
390
+ const code = response.status === 401 && result?.error === "device_credential_invalid"
391
+ && result?.reason === "device_credential_revoked" ? result.reason : safeDeviceRuntimeErrorCode(result?.error);
392
+ throw new HelloLynkClientError(code, {
391
393
  httpStatus: response.status,
392
394
  retryable: response.status === 408 || response.status === 425 || response.status === 429 || response.status >= 500,
393
395
  });
@@ -584,6 +586,7 @@ export function createDeviceRuntimeSessionManager(options = {}) {
584
586
  );
585
587
  let current = null;
586
588
  let rejectedCredential = null;
589
+ const revokedFingerprints = new Set();
587
590
  let localIssueTail = Promise.resolve();
588
591
 
589
592
  const routeMatches = (session, input) => {
@@ -668,7 +671,15 @@ export function createDeviceRuntimeSessionManager(options = {}) {
668
671
  : null;
669
672
  // The production caller holds the existing session lock, including across
670
673
  // Host processes. An authority denial may drain the current Host.
674
+ const revocationKey = fingerprint && `revoked-${fingerprint}`;
671
675
  if (fingerprint) {
676
+ // An older process may update or clear its temporary rejection for the
677
+ // profile. Keep permanent revocation under the credential's own key.
678
+ if (revokedFingerprints.has(fingerprint)
679
+ || (await credentialRejections?.load(revocationKey).catch(() => null))?.fingerprint === fingerprint) {
680
+ revokedFingerprints.add(fingerprint);
681
+ throw new HelloLynkClientError("device_credential_revoked", { httpStatus: 401 });
682
+ }
672
683
  const isCoolingDown = (rejection) => {
673
684
  if (rejection?.fingerprint !== fingerprint) return false;
674
685
  const age = now() - rejection.rejectedAtMs;
@@ -685,10 +696,14 @@ export function createDeviceRuntimeSessionManager(options = {}) {
685
696
  try {
686
697
  session = reusable(await issue(request), input);
687
698
  } catch (error) {
688
- if (fingerprint && error?.httpStatus === 401 && error.code === "device_credential_invalid") {
689
- rejectedCredential = { fingerprint, rejectedAtMs: now() };
690
- // Preserve the authority denial even if local storage is unavailable.
691
- await credentialRejections?.save(sessionKey, rejectedCredential).catch(() => {});
699
+ if (fingerprint && error?.httpStatus === 401) {
700
+ if (error.code === "device_credential_revoked") {
701
+ revokedFingerprints.add(fingerprint);
702
+ await credentialRejections?.save(revocationKey, { fingerprint, rejectedAtMs: now() }).catch(() => {});
703
+ } else if (error.code === "device_credential_invalid") {
704
+ rejectedCredential = { fingerprint, rejectedAtMs: now() };
705
+ await credentialRejections?.save(sessionKey, rejectedCredential).catch(() => {});
706
+ }
692
707
  }
693
708
  throw error;
694
709
  }
@@ -387,7 +387,9 @@ export async function issueDeviceRuntimeSession(options) {
387
387
  }
388
388
  return fresh;
389
389
  }
390
- throw new HelloLynkClientError(safeDeviceRuntimeErrorCode(result?.error), {
390
+ const code = response.status === 401 && result?.error === "device_credential_invalid"
391
+ && result?.reason === "device_credential_revoked" ? result.reason : safeDeviceRuntimeErrorCode(result?.error);
392
+ throw new HelloLynkClientError(code, {
391
393
  httpStatus: response.status,
392
394
  retryable: response.status === 408 || response.status === 425 || response.status === 429 || response.status >= 500,
393
395
  });
@@ -584,6 +586,7 @@ export function createDeviceRuntimeSessionManager(options = {}) {
584
586
  );
585
587
  let current = null;
586
588
  let rejectedCredential = null;
589
+ const revokedFingerprints = new Set();
587
590
  let localIssueTail = Promise.resolve();
588
591
 
589
592
  const routeMatches = (session, input) => {
@@ -668,7 +671,15 @@ export function createDeviceRuntimeSessionManager(options = {}) {
668
671
  : null;
669
672
  // The production caller holds the existing session lock, including across
670
673
  // Host processes. An authority denial may drain the current Host.
674
+ const revocationKey = fingerprint && `revoked-${fingerprint}`;
671
675
  if (fingerprint) {
676
+ // An older process may update or clear its temporary rejection for the
677
+ // profile. Keep permanent revocation under the credential's own key.
678
+ if (revokedFingerprints.has(fingerprint)
679
+ || (await credentialRejections?.load(revocationKey).catch(() => null))?.fingerprint === fingerprint) {
680
+ revokedFingerprints.add(fingerprint);
681
+ throw new HelloLynkClientError("device_credential_revoked", { httpStatus: 401 });
682
+ }
672
683
  const isCoolingDown = (rejection) => {
673
684
  if (rejection?.fingerprint !== fingerprint) return false;
674
685
  const age = now() - rejection.rejectedAtMs;
@@ -685,10 +696,14 @@ export function createDeviceRuntimeSessionManager(options = {}) {
685
696
  try {
686
697
  session = reusable(await issue(request), input);
687
698
  } catch (error) {
688
- if (fingerprint && error?.httpStatus === 401 && error.code === "device_credential_invalid") {
689
- rejectedCredential = { fingerprint, rejectedAtMs: now() };
690
- // Preserve the authority denial even if local storage is unavailable.
691
- await credentialRejections?.save(sessionKey, rejectedCredential).catch(() => {});
699
+ if (fingerprint && error?.httpStatus === 401) {
700
+ if (error.code === "device_credential_revoked") {
701
+ revokedFingerprints.add(fingerprint);
702
+ await credentialRejections?.save(revocationKey, { fingerprint, rejectedAtMs: now() }).catch(() => {});
703
+ } else if (error.code === "device_credential_invalid") {
704
+ rejectedCredential = { fingerprint, rejectedAtMs: now() };
705
+ await credentialRejections?.save(sessionKey, rejectedCredential).catch(() => {});
706
+ }
692
707
  }
693
708
  throw error;
694
709
  }
@@ -35,7 +35,7 @@ export const HELLOLYNK_NEUTRAL_HOST_PROCESS_CONTRACT = "hellolynk-neutral-host-p
35
35
  export const HELLOLYNK_NEUTRAL_HOST_DISCOVERY_CONTRACT = "hellolynk-neutral-host-discovery-v1";
36
36
  // Raised with every release batch, together with the six client versions. A Host reports it
37
37
  // in its health; the higher release stays and the lower one makes room.
38
- export const HELLOLYNK_HOST_RELEASE_ORDINAL = 18;
38
+ export const HELLOLYNK_HOST_RELEASE_ORDINAL = 19;
39
39
 
40
40
  const INSTALLATION_LOCK_CONTRACT = "hellolynk-neutral-host-installation-lock-v2";
41
41
  const INSTALLATION_LOCK_MAX_BYTES = 4 * 1024;
@@ -4,7 +4,7 @@
4
4
  "files": [
5
5
  {
6
6
  "path": "release/integrations/trae-work/package.json",
7
- "sha256": "2eb6935f4e8faf49d6010c810eac516b5887f8aee4d534a486d486cac60235b2"
7
+ "sha256": "cffb8384ee280dd92011c0ad57052ccccf2bbf7138ef0bec635ae33e8532e9ed"
8
8
  },
9
9
  {
10
10
  "path": "connect-activate.mjs",
@@ -36,7 +36,7 @@
36
36
  },
37
37
  {
38
38
  "path": "core/hellolynk-client-core.mjs",
39
- "sha256": "5d2190c2354ede169b2053864674c7ae5b80985970dc13609d6818c5a6d16940"
39
+ "sha256": "186332d5dea8876cf8ca57fef35e9810df5256ed36f704f7bd3840e45c406a4a"
40
40
  },
41
41
  {
42
42
  "path": "core/hellolynk-client-profile.mjs",
@@ -200,7 +200,7 @@
200
200
  },
201
201
  {
202
202
  "path": "core/hellolynk-neutral-host-process.mjs",
203
- "sha256": "0a66fca2b862fde9269722f026fc67e9d1c79435f0d410809aee669be9f9f497"
203
+ "sha256": "42d29af2f0ac96252d694996864d54b3fddda47d6ad5405020a1354e13372efa"
204
204
  },
205
205
  {
206
206
  "path": "core/hellolynk-neutral-host-store-adapters.mjs",
@@ -328,7 +328,7 @@
328
328
  },
329
329
  {
330
330
  "path": "bootstrap/core/hellolynk-client-core.mjs",
331
- "sha256": "5d2190c2354ede169b2053864674c7ae5b80985970dc13609d6818c5a6d16940"
331
+ "sha256": "186332d5dea8876cf8ca57fef35e9810df5256ed36f704f7bd3840e45c406a4a"
332
332
  },
333
333
  {
334
334
  "path": "bootstrap/core/hellolynk-client-profile.mjs",
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "contract": "hellolynk-neutral-host-release-pin-v1",
3
- "manifestSha256": "8561015215e14fe8f8b5f1a18ecccefa717cdff05c40f8eee8d21af328bc3174"
3
+ "manifestSha256": "d2cff22cd8e4a224bf24c4a57b67d4c7a4adce9721405d81da52c7eb3c3032ab"
4
4
  }