@ethisyscore/extension-runtime 1.136.0 → 1.138.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.
Files changed (34) hide show
  1. package/README.md +2 -2
  2. package/dist/MockPluginStorage-DF3DL1dI.d.ts +59 -0
  3. package/dist/MockPluginStorage-QKfz8CMt.d.cts +59 -0
  4. package/dist/{bridge-client-RJOl8WlU.d.ts → bridge-client-CkxYcZcm.d.ts} +1 -1
  5. package/dist/{bridge-client-D9EYFq1l.d.cts → bridge-client-DkogtCvn.d.cts} +1 -1
  6. package/dist/{bridge-envelopes-M5a42rAy.d.cts → bridge-envelopes-BcKu-nQm.d.cts} +72 -1
  7. package/dist/{bridge-envelopes-M5a42rAy.d.ts → bridge-envelopes-BcKu-nQm.d.ts} +72 -1
  8. package/dist/host/index.cjs +84 -2
  9. package/dist/host/index.cjs.map +1 -1
  10. package/dist/host/index.d.cts +3 -3
  11. package/dist/host/index.d.ts +3 -3
  12. package/dist/host/index.js +84 -2
  13. package/dist/host/index.js.map +1 -1
  14. package/dist/mock-host/cli.cjs +340 -7
  15. package/dist/mock-host/cli.cjs.map +1 -1
  16. package/dist/mock-host/cli.d.cts +10 -3
  17. package/dist/mock-host/cli.d.ts +10 -3
  18. package/dist/mock-host/cli.js +339 -8
  19. package/dist/mock-host/cli.js.map +1 -1
  20. package/dist/mock-host/index.cjs +276 -1
  21. package/dist/mock-host/index.cjs.map +1 -1
  22. package/dist/mock-host/index.d.cts +14 -4
  23. package/dist/mock-host/index.d.ts +14 -4
  24. package/dist/mock-host/index.js +276 -2
  25. package/dist/mock-host/index.js.map +1 -1
  26. package/dist/plugin/index.cjs +407 -100
  27. package/dist/plugin/index.cjs.map +1 -1
  28. package/dist/plugin/index.d.cts +186 -6
  29. package/dist/plugin/index.d.ts +186 -6
  30. package/dist/plugin/index.js +395 -101
  31. package/dist/plugin/index.js.map +1 -1
  32. package/dist/{transport-UaoDRdm3.d.cts → transport-D1lE-5nt.d.cts} +30 -3
  33. package/dist/{transport-CFzJQiFG.d.ts → transport-INVtDo2s.d.ts} +30 -3
  34. package/package.json +2 -2
@@ -3,12 +3,12 @@ import { C as ComponentRegistry } from '../registry-DpCx_LxF.cjs';
3
3
  export { P as PrimitiveProps } from '../registry-DpCx_LxF.cjs';
4
4
  import { SduiNode } from '@ethisyscore/protocol';
5
5
  export { PrimitiveName, SduiNode } from '@ethisyscore/protocol';
6
- import { M as McpHttpClient, f as VersionSkew } from '../transport-UaoDRdm3.cjs';
7
- export { C as CAPABILITY_REJECTION_REASON_HEADER, D as DEFAULT_MAX_CONCURRENT_MCP_REQUESTS, E as EXTENSION_ACTIVE_VERSION_HEADER, a as EXTENSION_VERSION_HEADER, I as InputEventPayload, b as McpHttpRequest, c as McpHttpResponse, d as McpResponseMetadata, e as McpUploadRequest, V as VERSION_MISMATCH_REASON, g as VersionSkewSource, W as WORKER_TRANSPORT_PROTOCOL, h as WorkerCtor, i as WorkerHandshakePayload, j as WorkerLike, k as WorkerRemoteDomTransport, l as WorkerRemoteDomTransportOptions, m as detectVersionSkew } from '../transport-UaoDRdm3.cjs';
6
+ import { M as McpHttpClient, g as VersionSkew } from '../transport-D1lE-5nt.cjs';
7
+ export { C as CAPABILITY_REJECTION_REASON_HEADER, D as DEFAULT_MAX_CONCURRENT_MCP_REQUESTS, E as EXTENSION_ACTIVE_VERSION_HEADER, a as EXTENSION_VERSION_HEADER, I as InputEventPayload, b as McpHttpRequest, c as McpHttpResponse, d as McpResponseMetadata, e as McpUploadRequest, f as McpUploadToStorageRequest, V as VERSION_MISMATCH_REASON, h as VersionSkewSource, W as WORKER_TRANSPORT_PROTOCOL, i as WorkerCtor, j as WorkerHandshakePayload, k as WorkerLike, l as WorkerRemoteDomTransport, m as WorkerRemoteDomTransportOptions, n as detectVersionSkew } from '../transport-D1lE-5nt.cjs';
8
8
  export { RemoteReceiver, RemoteReceiverComment, RemoteReceiverElement, RemoteReceiverNode, RemoteReceiverParent, RemoteReceiverRoot, RemoteReceiverText } from '@remote-dom/core/receivers';
9
9
  export { RemoteComponentRendererMap, RemoteComponentRendererProps, RemoteRootRenderer, RemoteRootRendererProps, createRemoteComponentRenderer } from '@remote-dom/react/host';
10
10
  export { M as MCP_ERROR_CODES, a as McpErrorCode, b as McpToolError, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.cjs';
11
- import '../bridge-envelopes-M5a42rAy.cjs';
11
+ import '../bridge-envelopes-BcKu-nQm.cjs';
12
12
 
13
13
  /**
14
14
  * Resolution context for `var` references. Keys are looked up via dot-path
@@ -3,12 +3,12 @@ import { C as ComponentRegistry } from '../registry-DpCx_LxF.js';
3
3
  export { P as PrimitiveProps } from '../registry-DpCx_LxF.js';
4
4
  import { SduiNode } from '@ethisyscore/protocol';
5
5
  export { PrimitiveName, SduiNode } from '@ethisyscore/protocol';
6
- import { M as McpHttpClient, f as VersionSkew } from '../transport-CFzJQiFG.js';
7
- export { C as CAPABILITY_REJECTION_REASON_HEADER, D as DEFAULT_MAX_CONCURRENT_MCP_REQUESTS, E as EXTENSION_ACTIVE_VERSION_HEADER, a as EXTENSION_VERSION_HEADER, I as InputEventPayload, b as McpHttpRequest, c as McpHttpResponse, d as McpResponseMetadata, e as McpUploadRequest, V as VERSION_MISMATCH_REASON, g as VersionSkewSource, W as WORKER_TRANSPORT_PROTOCOL, h as WorkerCtor, i as WorkerHandshakePayload, j as WorkerLike, k as WorkerRemoteDomTransport, l as WorkerRemoteDomTransportOptions, m as detectVersionSkew } from '../transport-CFzJQiFG.js';
6
+ import { M as McpHttpClient, g as VersionSkew } from '../transport-INVtDo2s.js';
7
+ export { C as CAPABILITY_REJECTION_REASON_HEADER, D as DEFAULT_MAX_CONCURRENT_MCP_REQUESTS, E as EXTENSION_ACTIVE_VERSION_HEADER, a as EXTENSION_VERSION_HEADER, I as InputEventPayload, b as McpHttpRequest, c as McpHttpResponse, d as McpResponseMetadata, e as McpUploadRequest, f as McpUploadToStorageRequest, V as VERSION_MISMATCH_REASON, h as VersionSkewSource, W as WORKER_TRANSPORT_PROTOCOL, i as WorkerCtor, j as WorkerHandshakePayload, k as WorkerLike, l as WorkerRemoteDomTransport, m as WorkerRemoteDomTransportOptions, n as detectVersionSkew } from '../transport-INVtDo2s.js';
8
8
  export { RemoteReceiver, RemoteReceiverComment, RemoteReceiverElement, RemoteReceiverNode, RemoteReceiverParent, RemoteReceiverRoot, RemoteReceiverText } from '@remote-dom/core/receivers';
9
9
  export { RemoteComponentRendererMap, RemoteComponentRendererProps, RemoteRootRenderer, RemoteRootRendererProps, createRemoteComponentRenderer } from '@remote-dom/react/host';
10
10
  export { M as MCP_ERROR_CODES, a as McpErrorCode, b as McpToolError, c as classifyHostError, d as classifyHostResponse, i as isMcpErrorCode, e as isMcpToolError, f as isRetryableMcpErrorCode, m as mcpErrorCodeFromHttpStatus } from '../mcp-error-CCZQd8Xl.js';
11
- import '../bridge-envelopes-M5a42rAy.js';
11
+ import '../bridge-envelopes-BcKu-nQm.js';
12
12
 
13
13
  /**
14
14
  * Resolution context for `var` references. Keys are looked up via dot-path
@@ -378,6 +378,20 @@ function classifyHostError(err) {
378
378
  }
379
379
  return "internal";
380
380
  }
381
+ function parsePluginStorageRetryAfter(raw, nowMs = Date.now()) {
382
+ if (typeof raw === "number") {
383
+ return Number.isFinite(raw) && raw >= 0 ? Math.ceil(raw) : void 0;
384
+ }
385
+ if (typeof raw !== "string" || raw.trim().length === 0) {
386
+ return void 0;
387
+ }
388
+ const text = raw.trim();
389
+ if (/^\d+$/.test(text)) {
390
+ return Number(text);
391
+ }
392
+ const at = /[A-Za-z]/.test(text) ? Date.parse(text) : Number.NaN;
393
+ return Number.isNaN(at) ? void 0 : Math.max(0, Math.ceil((at - nowMs) / 1e3));
394
+ }
381
395
 
382
396
  // src/host/version-skew.ts
383
397
  var EXTENSION_VERSION_HEADER = "x-extension-version";
@@ -692,6 +706,9 @@ var WorkerRemoteDomTransport = class {
692
706
  case "ethisys:mcp:uploadDocument":
693
707
  this.dispatchMcp(message, "ethisys:mcp:uploadDocument:result", (m) => this.handleUploadDocument(m));
694
708
  return;
709
+ case "ethisys:mcp:uploadToStorage":
710
+ this.dispatchMcp(message, "ethisys:mcp:uploadToStorage:result", (m) => this.handleUploadToStorage(m));
711
+ return;
695
712
  case "ethisys:mcp:abort":
696
713
  this.inFlightAborts.get(message.id ?? "")?.abort();
697
714
  return;
@@ -929,11 +946,76 @@ var WorkerRemoteDomTransport = class {
929
946
  this.replyError(message.id, "ethisys:mcp:uploadDocument:result", err);
930
947
  }
931
948
  }
932
- replyError(id, type, err) {
949
+ async handleUploadToStorage(message) {
950
+ const resultType = "ethisys:mcp:uploadToStorage:result";
951
+ let token;
952
+ try {
953
+ token = await this.capabilityTokenProvider();
954
+ } catch (err) {
955
+ this.replyError(message.id, resultType, err, true);
956
+ return;
957
+ }
958
+ if (this.disposed) {
959
+ return;
960
+ }
961
+ try {
962
+ const result = await this.mcpClient.fetch({
963
+ kind: "uploadToStorage",
964
+ meta: message.meta,
965
+ buffer: message.buffer,
966
+ capabilityToken: token,
967
+ signal: this.requestSignal(message.id)
968
+ });
969
+ this.reportVersionSkew(result);
970
+ this.safePostMessage({
971
+ id: message.id,
972
+ type: resultType,
973
+ ok: result.ok,
974
+ data: result.data,
975
+ error: result.error,
976
+ code: classifyHostResponse(result),
977
+ // The HTTP status, on failure only. A bare number carries no host internals, and it
978
+ // is the only way the plugin can tell 413 (file too large) from 507 (quota) from 503
979
+ // (storage lock busy): the closed MCP code folds all three into `internal`/`unavailable`.
980
+ ...!result.ok && typeof result.status === "number" ? { status: result.status } : {},
981
+ // The server's `Retry-After` (429), as whole seconds, so a plugin can show how long
982
+ // to wait. Never acted on here: an upload is not retried automatically.
983
+ ...retryAfterField(result)
984
+ });
985
+ } catch (err) {
986
+ this.replyError(message.id, resultType, err, true);
987
+ }
988
+ }
989
+ replyError(id, type, err, includeStatus = false) {
933
990
  const message = err instanceof Error ? err.message : "MCP request failed";
934
- this.safePostMessage({ id, type, ok: false, error: message, code: classifyHostError(err) });
991
+ const status = includeStatus ? statusOf(err) : void 0;
992
+ const retryAfterSeconds = includeStatus && err !== null && typeof err === "object" ? parsePluginStorageRetryAfter(err.retryAfterSeconds) : void 0;
993
+ this.safePostMessage({
994
+ id,
995
+ type,
996
+ ok: false,
997
+ error: message,
998
+ code: classifyHostError(err),
999
+ ...status !== void 0 ? { status } : {},
1000
+ ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
1001
+ });
935
1002
  }
936
1003
  };
1004
+ function retryAfterField(result) {
1005
+ if (result.ok || !result.headers) {
1006
+ return {};
1007
+ }
1008
+ const key = Object.keys(result.headers).find((k) => k.toLowerCase() === "retry-after");
1009
+ const seconds = key === void 0 ? void 0 : parsePluginStorageRetryAfter(result.headers[key]);
1010
+ return seconds === void 0 ? {} : { retryAfterSeconds: seconds };
1011
+ }
1012
+ function statusOf(err) {
1013
+ if (err === null || typeof err !== "object") {
1014
+ return void 0;
1015
+ }
1016
+ const candidate = err;
1017
+ return typeof candidate.status === "number" ? candidate.status : typeof candidate.statusCode === "number" ? candidate.statusCode : void 0;
1018
+ }
937
1019
  var IFRAME_BRIDGE_PROTOCOL = "ethisys.iframe.bridge.v1";
938
1020
  var InboundEnvelope = z.discriminatedUnion("type", [
939
1021
  z.object({ type: z.literal("ethisys:mcp:invokeTool"), id: z.string().min(1), name: z.string().min(1), args: z.unknown(), nonce: z.string() }),