@ethisyscore/extension-runtime 1.137.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.
@@ -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";
@@ -963,7 +977,10 @@ var WorkerRemoteDomTransport = class {
963
977
  // The HTTP status, on failure only. A bare number carries no host internals, and it
964
978
  // is the only way the plugin can tell 413 (file too large) from 507 (quota) from 503
965
979
  // (storage lock busy): the closed MCP code folds all three into `internal`/`unavailable`.
966
- ...!result.ok && typeof result.status === "number" ? { status: result.status } : {}
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)
967
984
  });
968
985
  } catch (err) {
969
986
  this.replyError(message.id, resultType, err, true);
@@ -972,16 +989,26 @@ var WorkerRemoteDomTransport = class {
972
989
  replyError(id, type, err, includeStatus = false) {
973
990
  const message = err instanceof Error ? err.message : "MCP request failed";
974
991
  const status = includeStatus ? statusOf(err) : void 0;
992
+ const retryAfterSeconds = includeStatus && err !== null && typeof err === "object" ? parsePluginStorageRetryAfter(err.retryAfterSeconds) : void 0;
975
993
  this.safePostMessage({
976
994
  id,
977
995
  type,
978
996
  ok: false,
979
997
  error: message,
980
998
  code: classifyHostError(err),
981
- ...status !== void 0 ? { status } : {}
999
+ ...status !== void 0 ? { status } : {},
1000
+ ...retryAfterSeconds !== void 0 ? { retryAfterSeconds } : {}
982
1001
  });
983
1002
  }
984
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
+ }
985
1012
  function statusOf(err) {
986
1013
  if (err === null || typeof err !== "object") {
987
1014
  return void 0;