@ethisyscore/extension-runtime 1.59.0 → 1.62.0
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/{bridge-client-D5GY1Wih.d.ts → bridge-client-DD99netz.d.ts} +1 -1
- package/dist/{bridge-client-CyksRjrA.d.cts → bridge-client-DzRcKIJT.d.cts} +1 -1
- package/dist/host/index.cjs +116 -0
- package/dist/host/index.cjs.map +1 -1
- package/dist/host/index.d.cts +29 -3
- package/dist/host/index.d.ts +29 -3
- package/dist/host/index.js +112 -1
- package/dist/host/index.js.map +1 -1
- package/dist/mock-host/cli.cjs +80 -0
- package/dist/mock-host/cli.cjs.map +1 -1
- package/dist/mock-host/cli.d.cts +1 -1
- package/dist/mock-host/cli.d.ts +1 -1
- package/dist/mock-host/cli.js +80 -0
- package/dist/mock-host/cli.js.map +1 -1
- package/dist/mock-host/index.d.cts +1 -1
- package/dist/mock-host/index.d.ts +1 -1
- package/dist/plugin/index.d.cts +2 -2
- package/dist/plugin/index.d.ts +2 -2
- package/dist/{transport-CHa8ESUx.d.ts → transport-BPwasdNz.d.ts} +128 -6
- package/dist/{transport-DJE6ljme.d.cts → transport-BbSPAS_N.d.cts} +128 -6
- package/package.json +1 -1
package/dist/mock-host/cli.js
CHANGED
|
@@ -32,6 +32,50 @@ function createOffscreenCanvasTransfer(options) {
|
|
|
32
32
|
return { offscreen };
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
// src/host/version-skew.ts
|
|
36
|
+
var EXTENSION_VERSION_HEADER = "x-extension-version";
|
|
37
|
+
var EXTENSION_ACTIVE_VERSION_HEADER = "x-extension-active-version";
|
|
38
|
+
var CAPABILITY_REJECTION_REASON_HEADER = "x-capability-token-rejection-reason";
|
|
39
|
+
var VERSION_MISMATCH_REASON = "extensionversionmismatch";
|
|
40
|
+
function readHeader(headers, name) {
|
|
41
|
+
if (!headers) {
|
|
42
|
+
return void 0;
|
|
43
|
+
}
|
|
44
|
+
const direct = headers[name];
|
|
45
|
+
if (direct !== void 0) {
|
|
46
|
+
return direct;
|
|
47
|
+
}
|
|
48
|
+
const lowered = name.toLowerCase();
|
|
49
|
+
for (const key of Object.keys(headers)) {
|
|
50
|
+
if (key.toLowerCase() === lowered) {
|
|
51
|
+
return headers[key];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
function trimmedOrUndefined(value) {
|
|
57
|
+
const trimmed = value?.trim();
|
|
58
|
+
return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
|
|
59
|
+
}
|
|
60
|
+
function detectVersionSkew(response, mountedExtensionVersion) {
|
|
61
|
+
const reason = trimmedOrUndefined(readHeader(response.headers, CAPABILITY_REJECTION_REASON_HEADER));
|
|
62
|
+
if (reason !== void 0 && reason.toLowerCase() === VERSION_MISMATCH_REASON) {
|
|
63
|
+
return {
|
|
64
|
+
activeVersion: trimmedOrUndefined(readHeader(response.headers, EXTENSION_ACTIVE_VERSION_HEADER)),
|
|
65
|
+
detectedFrom: "rejection"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
const mounted = trimmedOrUndefined(mountedExtensionVersion);
|
|
72
|
+
const served = trimmedOrUndefined(readHeader(response.headers, EXTENSION_VERSION_HEADER));
|
|
73
|
+
if (mounted === void 0 || served === void 0 || served === mounted) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return { activeVersion: served, detectedFrom: "response-stamp" };
|
|
77
|
+
}
|
|
78
|
+
|
|
35
79
|
// src/host/worker/bridge-envelopes.ts
|
|
36
80
|
var BRIDGE_PUSH_THEME = "ethisys:bridge:theme";
|
|
37
81
|
var BRIDGE_PUSH_LOCALE = "ethisys:bridge:locale";
|
|
@@ -51,6 +95,9 @@ var WorkerRemoteDomTransport = class {
|
|
|
51
95
|
workerPort;
|
|
52
96
|
mcpClient;
|
|
53
97
|
capabilityTokenProvider;
|
|
98
|
+
mountedExtensionVersion;
|
|
99
|
+
onVersionSkew;
|
|
100
|
+
versionSkewReported = false;
|
|
54
101
|
coalesceMs;
|
|
55
102
|
maxConcurrentMcpRequests;
|
|
56
103
|
abortController;
|
|
@@ -73,6 +120,8 @@ var WorkerRemoteDomTransport = class {
|
|
|
73
120
|
}
|
|
74
121
|
this.mcpClient = options.mcpClient;
|
|
75
122
|
this.capabilityTokenProvider = options.capabilityToken;
|
|
123
|
+
this.mountedExtensionVersion = options.mountedExtensionVersion;
|
|
124
|
+
this.onVersionSkew = options.onVersionSkew;
|
|
76
125
|
this.coalesceMs = options.coalesceMs ?? 16;
|
|
77
126
|
this.maxConcurrentMcpRequests = Math.max(
|
|
78
127
|
1,
|
|
@@ -356,6 +405,34 @@ var WorkerRemoteDomTransport = class {
|
|
|
356
405
|
requestSignal(id) {
|
|
357
406
|
return this.inFlightAborts.get(id)?.signal ?? this.abortController.signal;
|
|
358
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* Raises the skew callback the first time this surface is seen to be running against a version
|
|
410
|
+
* that is no longer installed.
|
|
411
|
+
*
|
|
412
|
+
* Latched deliberately. A page typically has several MCP calls in flight, and after an upgrade
|
|
413
|
+
* every one of them reports the same skew — firing per response would ask the host to remount
|
|
414
|
+
* the same surface repeatedly, and the second remount would tear down the first. One signal per
|
|
415
|
+
* transport is all a remount needs, and the transport is discarded along with the surface.
|
|
416
|
+
*
|
|
417
|
+
* The callback is host code, so it is assumed to be able to throw. Two consequences are guarded
|
|
418
|
+
* here: the throw must not escape into the MCP handler's catch (which would reply `ok: false`
|
|
419
|
+
* for a call that actually succeeded), and it must not consume the latch (which would leave the
|
|
420
|
+
* surface with no response AND no further chance of being told to remount).
|
|
421
|
+
*/
|
|
422
|
+
reportVersionSkew(response) {
|
|
423
|
+
if (this.versionSkewReported || this.onVersionSkew === void 0) {
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
const skew = detectVersionSkew(response, this.mountedExtensionVersion);
|
|
427
|
+
if (skew === null) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
try {
|
|
431
|
+
this.onVersionSkew(skew);
|
|
432
|
+
this.versionSkewReported = true;
|
|
433
|
+
} catch {
|
|
434
|
+
}
|
|
435
|
+
}
|
|
359
436
|
async handleInvokeTool(message) {
|
|
360
437
|
let token;
|
|
361
438
|
try {
|
|
@@ -375,6 +452,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
375
452
|
capabilityToken: token,
|
|
376
453
|
signal: this.requestSignal(message.id)
|
|
377
454
|
});
|
|
455
|
+
this.reportVersionSkew(result);
|
|
378
456
|
this.safePostMessage({
|
|
379
457
|
id: message.id,
|
|
380
458
|
type: "ethisys:mcp:invokeTool:result",
|
|
@@ -404,6 +482,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
404
482
|
capabilityToken: token,
|
|
405
483
|
signal: this.requestSignal(message.id)
|
|
406
484
|
});
|
|
485
|
+
this.reportVersionSkew(result);
|
|
407
486
|
this.safePostMessage({
|
|
408
487
|
id: message.id,
|
|
409
488
|
type: "ethisys:mcp:getResource:result",
|
|
@@ -434,6 +513,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
434
513
|
capabilityToken: token,
|
|
435
514
|
signal: this.requestSignal(message.id)
|
|
436
515
|
});
|
|
516
|
+
this.reportVersionSkew(result);
|
|
437
517
|
this.safePostMessage({
|
|
438
518
|
id: message.id,
|
|
439
519
|
type: "ethisys:mcp:uploadDocument:result",
|