@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.cjs
CHANGED
|
@@ -54,6 +54,50 @@ function createOffscreenCanvasTransfer(options) {
|
|
|
54
54
|
return { offscreen };
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
// src/host/version-skew.ts
|
|
58
|
+
var EXTENSION_VERSION_HEADER = "x-extension-version";
|
|
59
|
+
var EXTENSION_ACTIVE_VERSION_HEADER = "x-extension-active-version";
|
|
60
|
+
var CAPABILITY_REJECTION_REASON_HEADER = "x-capability-token-rejection-reason";
|
|
61
|
+
var VERSION_MISMATCH_REASON = "extensionversionmismatch";
|
|
62
|
+
function readHeader(headers, name) {
|
|
63
|
+
if (!headers) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
const direct = headers[name];
|
|
67
|
+
if (direct !== void 0) {
|
|
68
|
+
return direct;
|
|
69
|
+
}
|
|
70
|
+
const lowered = name.toLowerCase();
|
|
71
|
+
for (const key of Object.keys(headers)) {
|
|
72
|
+
if (key.toLowerCase() === lowered) {
|
|
73
|
+
return headers[key];
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
function trimmedOrUndefined(value) {
|
|
79
|
+
const trimmed = value?.trim();
|
|
80
|
+
return trimmed !== void 0 && trimmed.length > 0 ? trimmed : void 0;
|
|
81
|
+
}
|
|
82
|
+
function detectVersionSkew(response, mountedExtensionVersion) {
|
|
83
|
+
const reason = trimmedOrUndefined(readHeader(response.headers, CAPABILITY_REJECTION_REASON_HEADER));
|
|
84
|
+
if (reason !== void 0 && reason.toLowerCase() === VERSION_MISMATCH_REASON) {
|
|
85
|
+
return {
|
|
86
|
+
activeVersion: trimmedOrUndefined(readHeader(response.headers, EXTENSION_ACTIVE_VERSION_HEADER)),
|
|
87
|
+
detectedFrom: "rejection"
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
const mounted = trimmedOrUndefined(mountedExtensionVersion);
|
|
94
|
+
const served = trimmedOrUndefined(readHeader(response.headers, EXTENSION_VERSION_HEADER));
|
|
95
|
+
if (mounted === void 0 || served === void 0 || served === mounted) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return { activeVersion: served, detectedFrom: "response-stamp" };
|
|
99
|
+
}
|
|
100
|
+
|
|
57
101
|
// src/host/worker/bridge-envelopes.ts
|
|
58
102
|
var BRIDGE_PUSH_THEME = "ethisys:bridge:theme";
|
|
59
103
|
var BRIDGE_PUSH_LOCALE = "ethisys:bridge:locale";
|
|
@@ -73,6 +117,9 @@ var WorkerRemoteDomTransport = class {
|
|
|
73
117
|
workerPort;
|
|
74
118
|
mcpClient;
|
|
75
119
|
capabilityTokenProvider;
|
|
120
|
+
mountedExtensionVersion;
|
|
121
|
+
onVersionSkew;
|
|
122
|
+
versionSkewReported = false;
|
|
76
123
|
coalesceMs;
|
|
77
124
|
maxConcurrentMcpRequests;
|
|
78
125
|
abortController;
|
|
@@ -95,6 +142,8 @@ var WorkerRemoteDomTransport = class {
|
|
|
95
142
|
}
|
|
96
143
|
this.mcpClient = options.mcpClient;
|
|
97
144
|
this.capabilityTokenProvider = options.capabilityToken;
|
|
145
|
+
this.mountedExtensionVersion = options.mountedExtensionVersion;
|
|
146
|
+
this.onVersionSkew = options.onVersionSkew;
|
|
98
147
|
this.coalesceMs = options.coalesceMs ?? 16;
|
|
99
148
|
this.maxConcurrentMcpRequests = Math.max(
|
|
100
149
|
1,
|
|
@@ -378,6 +427,34 @@ var WorkerRemoteDomTransport = class {
|
|
|
378
427
|
requestSignal(id) {
|
|
379
428
|
return this.inFlightAborts.get(id)?.signal ?? this.abortController.signal;
|
|
380
429
|
}
|
|
430
|
+
/**
|
|
431
|
+
* Raises the skew callback the first time this surface is seen to be running against a version
|
|
432
|
+
* that is no longer installed.
|
|
433
|
+
*
|
|
434
|
+
* Latched deliberately. A page typically has several MCP calls in flight, and after an upgrade
|
|
435
|
+
* every one of them reports the same skew — firing per response would ask the host to remount
|
|
436
|
+
* the same surface repeatedly, and the second remount would tear down the first. One signal per
|
|
437
|
+
* transport is all a remount needs, and the transport is discarded along with the surface.
|
|
438
|
+
*
|
|
439
|
+
* The callback is host code, so it is assumed to be able to throw. Two consequences are guarded
|
|
440
|
+
* here: the throw must not escape into the MCP handler's catch (which would reply `ok: false`
|
|
441
|
+
* for a call that actually succeeded), and it must not consume the latch (which would leave the
|
|
442
|
+
* surface with no response AND no further chance of being told to remount).
|
|
443
|
+
*/
|
|
444
|
+
reportVersionSkew(response) {
|
|
445
|
+
if (this.versionSkewReported || this.onVersionSkew === void 0) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const skew = detectVersionSkew(response, this.mountedExtensionVersion);
|
|
449
|
+
if (skew === null) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
try {
|
|
453
|
+
this.onVersionSkew(skew);
|
|
454
|
+
this.versionSkewReported = true;
|
|
455
|
+
} catch {
|
|
456
|
+
}
|
|
457
|
+
}
|
|
381
458
|
async handleInvokeTool(message) {
|
|
382
459
|
let token;
|
|
383
460
|
try {
|
|
@@ -397,6 +474,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
397
474
|
capabilityToken: token,
|
|
398
475
|
signal: this.requestSignal(message.id)
|
|
399
476
|
});
|
|
477
|
+
this.reportVersionSkew(result);
|
|
400
478
|
this.safePostMessage({
|
|
401
479
|
id: message.id,
|
|
402
480
|
type: "ethisys:mcp:invokeTool:result",
|
|
@@ -426,6 +504,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
426
504
|
capabilityToken: token,
|
|
427
505
|
signal: this.requestSignal(message.id)
|
|
428
506
|
});
|
|
507
|
+
this.reportVersionSkew(result);
|
|
429
508
|
this.safePostMessage({
|
|
430
509
|
id: message.id,
|
|
431
510
|
type: "ethisys:mcp:getResource:result",
|
|
@@ -456,6 +535,7 @@ var WorkerRemoteDomTransport = class {
|
|
|
456
535
|
capabilityToken: token,
|
|
457
536
|
signal: this.requestSignal(message.id)
|
|
458
537
|
});
|
|
538
|
+
this.reportVersionSkew(result);
|
|
459
539
|
this.safePostMessage({
|
|
460
540
|
id: message.id,
|
|
461
541
|
type: "ethisys:mcp:uploadDocument:result",
|