@caplets/core 0.25.0 → 0.26.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.
@@ -1,7 +1,7 @@
1
- import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-C0PNPwjS.js";
2
- import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-DgxCzt-A.js";
1
+ import { A as safeParseAsync$1, C as toJSONSchema, D as parse$3, E as $ZodType, F as NEVER, M as defineLazy, N as normalizeParams, O as parseAsync, P as $constructor, S as datetime, T as $ZodObject, _ as record, a as any, b as unknown, c as custom, d as literal, f as looseObject, g as preprocess, h as optional, i as _null, j as clone, k as safeParse$1, l as discriminatedUnion, m as object$1, o as array, p as number$1, r as _enum, s as boolean, t as ZodNumber$1, u as intersection, v as string, w as _coercedNumber, x as url, y as union } from "./schemas-BoqMu4MG.js";
2
+ import { a as isAllowedHttpBaseUrl, c as validateHttpActionHeaders, d as errorResult, f as redactSecrets, i as SERVER_ID_PATTERN, n as HEADER_NAME_PATTERN, o as isAllowedRemoteUrl, p as toSafeError, r as HTTP_BASE_URL_PATTERN, s as isUrl, t as FORBIDDEN_HEADERS, u as CapletsError } from "./validation-C4tYXw6G.js";
3
3
  import { generatedToolInputJsonSchema, generatedToolInputJsonSchemaForCaplet, generatedToolInputSchemaForCaplet, mcpOperations, operations } from "./generated-tool-input-schema.js";
4
- import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-D2k2-q8K.js";
4
+ import { f as observedOutputShapeKey, i as observeOutputShape, r as normalizedObservableValue, t as usefulOutputSchema, u as FileObservedOutputShapeStore } from "./observed-output-shapes-DuP7mJQf.js";
5
5
  import { createRequire } from "node:module";
6
6
  import { accessSync, chmodSync, constants, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync, watch, writeFileSync } from "node:fs";
7
7
  import { basename, delimiter, dirname, extname, isAbsolute, join, parse, posix, relative, resolve, sep, win32 } from "node:path";
@@ -9,8 +9,9 @@ import { spawn } from "node:child_process";
9
9
  import process$1 from "node:process";
10
10
  import { PassThrough } from "node:stream";
11
11
  import { createServer } from "node:http";
12
- import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
12
+ import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
13
13
  import { homedir } from "node:os";
14
+ import { Buffer as Buffer$1 } from "node:buffer";
14
15
  import { readFile } from "node:fs/promises";
15
16
  import ts from "typescript";
16
17
  import { getQuickJS, shouldInterruptAfterDeadline } from "quickjs-emscripten";
@@ -45,7 +46,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
45
46
  value: mod,
46
47
  enumerable: true
47
48
  }) : target, mod));
48
- var __require = /* @__PURE__ */ createRequire(import.meta.url);
49
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
49
50
  //#endregion
50
51
  //#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v3/helpers/util.js
51
52
  var util$1;
@@ -8910,7 +8911,7 @@ var require_boolSchema = /* @__PURE__ */ __commonJSMin(((exports) => {
8910
8911
  var require_rules = /* @__PURE__ */ __commonJSMin(((exports) => {
8911
8912
  Object.defineProperty(exports, "__esModule", { value: true });
8912
8913
  exports.getRules = exports.isJSONType = void 0;
8913
- const jsonTypes = new Set([
8914
+ const jsonTypes = /* @__PURE__ */ new Set([
8914
8915
  "string",
8915
8916
  "number",
8916
8917
  "integer",
@@ -9029,7 +9030,7 @@ var require_dataType = /* @__PURE__ */ __commonJSMin(((exports) => {
9029
9030
  return checkTypes;
9030
9031
  }
9031
9032
  exports.coerceAndCheckDataType = coerceAndCheckDataType;
9032
- const COERCIBLE = new Set([
9033
+ const COERCIBLE = /* @__PURE__ */ new Set([
9033
9034
  "string",
9034
9035
  "number",
9035
9036
  "integer",
@@ -9583,7 +9584,7 @@ var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
9583
9584
  const util_1 = require_util$1();
9584
9585
  const equal = require_fast_deep_equal();
9585
9586
  const traverse = require_json_schema_traverse();
9586
- const SIMPLE_INLINED = new Set([
9587
+ const SIMPLE_INLINED = /* @__PURE__ */ new Set([
9587
9588
  "type",
9588
9589
  "format",
9589
9590
  "pattern",
@@ -9608,7 +9609,7 @@ var require_resolve = /* @__PURE__ */ __commonJSMin(((exports) => {
9608
9609
  return countKeys(schema) <= limit;
9609
9610
  }
9610
9611
  exports.inlineRef = inlineRef;
9611
- const REF_KEYWORDS = new Set([
9612
+ const REF_KEYWORDS = /* @__PURE__ */ new Set([
9612
9613
  "$ref",
9613
9614
  "$recursiveRef",
9614
9615
  "$recursiveAnchor",
@@ -10329,7 +10330,7 @@ var require_compile = /* @__PURE__ */ __commonJSMin(((exports) => {
10329
10330
  return getJsonPointer.call(this, p, schOrRef);
10330
10331
  }
10331
10332
  exports.resolveSchema = resolveSchema;
10332
- const PREVENT_SCOPE_CHANGE = new Set([
10333
+ const PREVENT_SCOPE_CHANGE = /* @__PURE__ */ new Set([
10333
10334
  "properties",
10334
10335
  "patternProperties",
10335
10336
  "enum",
@@ -11281,7 +11282,7 @@ var require_core$4 = /* @__PURE__ */ __commonJSMin(((exports) => {
11281
11282
  "useDefaults",
11282
11283
  "coerceTypes"
11283
11284
  ];
11284
- const EXT_SCOPE_NAMES = new Set([
11285
+ const EXT_SCOPE_NAMES = /* @__PURE__ */ new Set([
11285
11286
  "validate",
11286
11287
  "serialize",
11287
11288
  "parse",
@@ -18095,7 +18096,7 @@ function searchToolList(tools, query, limit, compact) {
18095
18096
  return utility === 0 ? left.tool.name.localeCompare(right.tool.name) : utility;
18096
18097
  }).slice(0, limit).map((candidate) => compact(candidate.tool));
18097
18098
  }
18098
- const MUTATING_QUERY_TOKENS = new Set([
18099
+ const MUTATING_QUERY_TOKENS = /* @__PURE__ */ new Set([
18099
18100
  "add",
18100
18101
  "create",
18101
18102
  "delete",
@@ -20097,7 +20098,7 @@ var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
20097
20098
  const a = [];
20098
20099
  a[k] = v;
20099
20100
  v = a;
20100
- } else v = new Map([[k, v]]);
20101
+ } else v = /* @__PURE__ */ new Map([[k, v]]);
20101
20102
  }
20102
20103
  return createNode.createNode(v, void 0, {
20103
20104
  aliasDuplicateObjects: false,
@@ -20656,7 +20657,7 @@ var require_stringify = /* @__PURE__ */ __commonJSMin(((exports) => {
20656
20657
  if (ctx.resolvedAliases?.has(item)) throw new TypeError(`Cannot stringify circular structure without alias nodes`);
20657
20658
  else {
20658
20659
  if (ctx.resolvedAliases) ctx.resolvedAliases.add(item);
20659
- else ctx.resolvedAliases = new Set([item]);
20660
+ else ctx.resolvedAliases = /* @__PURE__ */ new Set([item]);
20660
20661
  item = item.resolve(ctx.doc);
20661
20662
  }
20662
20663
  }
@@ -22050,7 +22051,7 @@ var require_tags = /* @__PURE__ */ __commonJSMin(((exports) => {
22050
22051
  var schema$2 = require_schema$7();
22051
22052
  var set = require_set$1();
22052
22053
  var timestamp = require_timestamp$1();
22053
- const schemas = new Map([
22054
+ const schemas = /* @__PURE__ */ new Map([
22054
22055
  ["core", schema.schema],
22055
22056
  ["failsafe", [
22056
22057
  map.map,
@@ -26078,7 +26079,7 @@ const capletMcpServerSchema = object$1({
26078
26079
  path: ["url"],
26079
26080
  message: "remote servers require url"
26080
26081
  });
26081
- if (server.url && !hasEnvReference$2(server.url) && !isAllowedRemoteUrl(server.url)) ctx.addIssue({
26082
+ if (server.url && !hasInterpolationReference$2(server.url) && !isAllowedRemoteUrl(server.url)) ctx.addIssue({
26082
26083
  code: "custom",
26083
26084
  path: ["url"],
26084
26085
  message: "remote url must use https except loopback development urls"
@@ -26091,7 +26092,7 @@ const capletMcpServerSchema = object$1({
26091
26092
  "redirectUri"
26092
26093
  ]) {
26093
26094
  const value = server.auth[field];
26094
- if (value && !hasEnvReference$2(value) && !isUrl(value)) ctx.addIssue({
26095
+ if (value && !hasInterpolationReference$2(value) && !isUrl(value)) ctx.addIssue({
26095
26096
  code: "custom",
26096
26097
  path: ["auth", field],
26097
26098
  message: `${field} must be a URL or environment reference`
@@ -26125,12 +26126,12 @@ const capletOpenApiEndpointSchema = object$1({
26125
26126
  code: "custom",
26126
26127
  message: "openapiEndpoint must define exactly one spec source: specPath or specUrl"
26127
26128
  });
26128
- if (endpoint.specUrl && !hasEnvReference$2(endpoint.specUrl) && !isAllowedRemoteUrl(endpoint.specUrl)) ctx.addIssue({
26129
+ if (endpoint.specUrl && !hasInterpolationReference$2(endpoint.specUrl) && !isAllowedRemoteUrl(endpoint.specUrl)) ctx.addIssue({
26129
26130
  code: "custom",
26130
26131
  path: ["specUrl"],
26131
26132
  message: "OpenAPI specUrl must use https except loopback development urls"
26132
26133
  });
26133
- if (endpoint.baseUrl && !hasEnvReference$2(endpoint.baseUrl) && !isAllowedRemoteUrl(endpoint.baseUrl)) ctx.addIssue({
26134
+ if (endpoint.baseUrl && !hasInterpolationReference$2(endpoint.baseUrl) && !isAllowedRemoteUrl(endpoint.baseUrl)) ctx.addIssue({
26134
26135
  code: "custom",
26135
26136
  path: ["baseUrl"],
26136
26137
  message: "OpenAPI baseUrl must use https except loopback development urls"
@@ -26155,12 +26156,12 @@ const capletGoogleDiscoveryApiSchema = object$1({
26155
26156
  code: "custom",
26156
26157
  message: "googleDiscoveryApi must define exactly one discovery source: discoveryPath or discoveryUrl"
26157
26158
  });
26158
- if (api.discoveryUrl && !hasEnvReference$2(api.discoveryUrl) && !isAllowedRemoteUrl(api.discoveryUrl)) ctx.addIssue({
26159
+ if (api.discoveryUrl && !hasInterpolationReference$2(api.discoveryUrl) && !isAllowedRemoteUrl(api.discoveryUrl)) ctx.addIssue({
26159
26160
  code: "custom",
26160
26161
  path: ["discoveryUrl"],
26161
26162
  message: "Google Discovery discoveryUrl must use https except loopback development urls"
26162
26163
  });
26163
- if (api.baseUrl && !hasEnvReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
26164
+ if (api.baseUrl && !hasInterpolationReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
26164
26165
  code: "custom",
26165
26166
  path: ["baseUrl"],
26166
26167
  message: "Google Discovery baseUrl must use https except loopback development urls and must not include credentials, query, or fragment"
@@ -26197,12 +26198,12 @@ const capletGraphQlEndpointSchema = object$1({
26197
26198
  code: "custom",
26198
26199
  message: "graphqlEndpoint must define exactly one schema source: schemaPath, schemaUrl, or introspection"
26199
26200
  });
26200
- if (endpoint.endpointUrl && !hasEnvReference$2(endpoint.endpointUrl) && !isAllowedRemoteUrl(endpoint.endpointUrl)) ctx.addIssue({
26201
+ if (endpoint.endpointUrl && !hasInterpolationReference$2(endpoint.endpointUrl) && !isAllowedRemoteUrl(endpoint.endpointUrl)) ctx.addIssue({
26201
26202
  code: "custom",
26202
26203
  path: ["endpointUrl"],
26203
26204
  message: "GraphQL endpointUrl must use https except loopback development urls"
26204
26205
  });
26205
- if (endpoint.schemaUrl && !hasEnvReference$2(endpoint.schemaUrl) && !isAllowedRemoteUrl(endpoint.schemaUrl)) ctx.addIssue({
26206
+ if (endpoint.schemaUrl && !hasInterpolationReference$2(endpoint.schemaUrl) && !isAllowedRemoteUrl(endpoint.schemaUrl)) ctx.addIssue({
26206
26207
  code: "custom",
26207
26208
  path: ["schemaUrl"],
26208
26209
  message: "GraphQL schemaUrl must use https except loopback development urls"
@@ -26246,7 +26247,7 @@ const capletHttpApiSchema = object$1({
26246
26247
  projectBinding: capletProjectBindingSchema.optional(),
26247
26248
  runtime: capletRuntimeRequirementsSchema.optional()
26248
26249
  }).strict().superRefine((api, ctx) => {
26249
- if (api.baseUrl && !hasEnvReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
26250
+ if (api.baseUrl && !hasInterpolationReference$2(api.baseUrl) && !isAllowedHttpBaseUrl(api.baseUrl)) ctx.addIssue({
26250
26251
  code: "custom",
26251
26252
  path: ["baseUrl"],
26252
26253
  message: "HTTP API baseUrl must use https except loopback development urls and must not include credentials, query, or fragment"
@@ -26445,7 +26446,7 @@ function discoverCapletFileMapCandidates(paths) {
26445
26446
  });
26446
26447
  }
26447
26448
  return candidates.map(({ id, path }) => {
26448
- validateCapletId(id, path);
26449
+ validateCapletId$1(id, path);
26449
26450
  return {
26450
26451
  id,
26451
26452
  path
@@ -26551,7 +26552,7 @@ function normalizeGraphQlOperations(operations, baseDir, normalizePath) {
26551
26552
  }]));
26552
26553
  }
26553
26554
  function normalizeBundleLocalPath(value, baseDir) {
26554
- if (!value || isMapAbsolutePath(value) || hasEnvReference$2(value)) return value;
26555
+ if (!value || isMapAbsolutePath(value) || hasInterpolationReference$2(value)) return value;
26555
26556
  const parts = [...baseDir ? baseDir.split("/") : [], ...value.split("/")];
26556
26557
  const normalized = [];
26557
26558
  for (const part of parts) {
@@ -26625,21 +26626,18 @@ function parseFrontmatter(text, path) {
26625
26626
  function isPlainObject$6(value) {
26626
26627
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
26627
26628
  }
26628
- function validateCapletId(id, path) {
26629
+ function validateCapletId$1(id, path) {
26629
26630
  if (!SERVER_ID_PATTERN.test(id)) throw new CapletsError("CONFIG_INVALID", `Caplet file at ${path} derives invalid ID ${id}; ID must match ^[a-zA-Z0-9_-]{1,64}$`);
26630
26631
  }
26631
26632
  function errorMessage$4(error) {
26632
26633
  return error instanceof Error ? error.message : String(error);
26633
26634
  }
26634
- function hasEnvReference$2(value) {
26635
- return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*/.test(value);
26635
+ function hasInterpolationReference$2(value) {
26636
+ return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*|\$\{vault:[^}]+\}|\$vault:[A-Za-z0-9_-]+/.test(value);
26636
26637
  }
26637
26638
  //#endregion
26638
26639
  //#region src/caplet-files.ts
26639
26640
  const MAX_CAPLET_FILE_BYTES = 128 * 1024;
26640
- function loadCapletFiles(root) {
26641
- return loadCapletFilesWithPaths(root)?.config;
26642
- }
26643
26641
  function loadCapletFilesWithPaths(root) {
26644
26642
  if (!existsSync(root)) return;
26645
26643
  return buildCapletFileLoadResultFromEntries(root, discoverCapletFiles(root), (path) => readCapletFile(path));
@@ -26653,7 +26651,7 @@ function discoverCapletFiles(root) {
26653
26651
  const entries = readdirSync(root, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name));
26654
26652
  const candidates = [];
26655
26653
  function addCandidate(id, path) {
26656
- validateCapletId(id, path);
26654
+ validateCapletId$1(id, path);
26657
26655
  candidates.push({
26658
26656
  id,
26659
26657
  path
@@ -26679,7 +26677,7 @@ function discoverCapletFilesBestEffort(root, warnings) {
26679
26677
  const duplicateIds = /* @__PURE__ */ new Set();
26680
26678
  function addCandidate(id, path, isDirectoryCaplet) {
26681
26679
  try {
26682
- validateCapletId(id, path);
26680
+ validateCapletId$1(id, path);
26683
26681
  } catch (error) {
26684
26682
  warnings.push({
26685
26683
  path,
@@ -26754,20 +26752,430 @@ function validateCapletFile(path) {
26754
26752
  readCapletFile(path);
26755
26753
  }
26756
26754
  function normalizeLocalPath$1(value, baseDir) {
26757
- if (!value || isAbsolute(value) || hasEnvReference$1(value)) return value;
26755
+ if (!value || isAbsolute(value) || hasInterpolationReference$1(value)) return value;
26758
26756
  return join(baseDir, value);
26759
26757
  }
26760
- function hasEnvReference$1(value) {
26761
- return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*/.test(value);
26758
+ function hasInterpolationReference$1(value) {
26759
+ return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*|\$\{vault:[^}]+\}|\$vault:[A-Za-z0-9_-]+/.test(value);
26760
+ }
26761
+ //#endregion
26762
+ //#region src/vault/crypto.ts
26763
+ const NONCE_BYTES = 12;
26764
+ function encryptVaultValue(input) {
26765
+ const nonce = randomBytes(NONCE_BYTES);
26766
+ const cipher = createCipheriv("aes-256-gcm", input.key, nonce);
26767
+ const ciphertext = Buffer$1.concat([cipher.update(input.plaintext, "utf8"), cipher.final()]);
26768
+ const authTag = cipher.getAuthTag();
26769
+ const timestamp = input.now.toISOString();
26770
+ return {
26771
+ version: 1,
26772
+ algorithm: "aes-256-gcm",
26773
+ nonce: nonce.toString("base64url"),
26774
+ ciphertext: ciphertext.toString("base64url"),
26775
+ authTag: authTag.toString("base64url"),
26776
+ valueBytes: Buffer$1.byteLength(input.plaintext, "utf8"),
26777
+ createdAt: input.existing?.createdAt ?? timestamp,
26778
+ updatedAt: timestamp
26779
+ };
26780
+ }
26781
+ function decryptVaultValue(record, key) {
26782
+ const parsed = parseEncryptedRecord(record);
26783
+ try {
26784
+ const decipher = createDecipheriv("aes-256-gcm", key, Buffer$1.from(parsed.nonce, "base64url"));
26785
+ decipher.setAuthTag(Buffer$1.from(parsed.authTag, "base64url"));
26786
+ return Buffer$1.concat([decipher.update(Buffer$1.from(parsed.ciphertext, "base64url")), decipher.final()]).toString("utf8");
26787
+ } catch {
26788
+ throw new CapletsError("CONFIG_INVALID", "Vault encrypted record could not be decrypted.");
26789
+ }
26790
+ }
26791
+ function parseEncryptedRecord(record) {
26792
+ if (!record || typeof record !== "object" || Array.isArray(record)) throw new CapletsError("CONFIG_INVALID", "Vault encrypted record must be an object.");
26793
+ const value = record;
26794
+ if (value.version !== 1 || value.algorithm !== "aes-256-gcm") throw new CapletsError("CONFIG_INVALID", "Vault encrypted record version is unsupported.");
26795
+ if (typeof value.nonce !== "string" || typeof value.ciphertext !== "string" || typeof value.authTag !== "string" || typeof value.valueBytes !== "number" || typeof value.createdAt !== "string" || typeof value.updatedAt !== "string") throw new CapletsError("CONFIG_INVALID", "Vault encrypted record is malformed.");
26796
+ return value;
26797
+ }
26798
+ //#endregion
26799
+ //#region src/vault/store.ts
26800
+ function ensurePrivateDir(path) {
26801
+ mkdirSync(path, {
26802
+ recursive: true,
26803
+ mode: 448
26804
+ });
26805
+ try {
26806
+ chmodSync(path, 448);
26807
+ } catch {}
26808
+ }
26809
+ function writePrivateFileAtomic(path, contents) {
26810
+ ensurePrivateDir(dirname(path));
26811
+ const tempPath = `${path}.${process.pid}.${Date.now()}.tmp`;
26812
+ writeFileSync(tempPath, contents, { mode: 384 });
26813
+ try {
26814
+ chmodSync(tempPath, 384);
26815
+ } catch {}
26816
+ renameSync(tempPath, path);
26817
+ }
26818
+ function readJsonFile(path, fallback) {
26819
+ if (!existsSync(path)) return fallback;
26820
+ return JSON.parse(readFileSync(path, "utf8"));
26821
+ }
26822
+ function deleteFile(path) {
26823
+ if (!existsSync(path)) return false;
26824
+ rmSync(path, { force: true });
26825
+ return true;
26826
+ }
26827
+ //#endregion
26828
+ //#region src/vault/keys.ts
26829
+ const VAULT_KEY_PATTERN = /^[A-Z_][A-Z0-9_]{0,127}$/;
26830
+ const KEY_FILE_PREFIX = "caplets-vault-key-v1.";
26831
+ const KEY_BYTES = 32;
26832
+ function validateVaultKeyName(name) {
26833
+ if (!VAULT_KEY_PATTERN.test(name)) throw new CapletsError("REQUEST_INVALID", "Vault key names must match ^[A-Z_][A-Z0-9_]{0,127}$");
26834
+ return name;
26835
+ }
26836
+ function loadVaultKey(input) {
26837
+ const envKey = input.env?.CAPLETS_ENCRYPTION_KEY;
26838
+ if (envKey !== void 0) return decodeExactKey(envKey, "CAPLETS_ENCRYPTION_KEY");
26839
+ const status = vaultKeySourceStatus(input);
26840
+ if (!status.available) throw new CapletsError("CONFIG_INVALID", `Vault key source is unavailable: ${"reason" in status ? status.reason : "invalid"}`);
26841
+ return parseKeyFile(readFileSync(input.keyFile, "utf8"));
26842
+ }
26843
+ function ensureVaultKey(input) {
26844
+ const envKey = input.env?.CAPLETS_ENCRYPTION_KEY;
26845
+ if (envKey !== void 0) return decodeExactKey(envKey, "CAPLETS_ENCRYPTION_KEY");
26846
+ if (!existsSync(input.keyFile)) {
26847
+ ensurePrivateDir(dirname(input.keyFile));
26848
+ const encoded = randomBytes(KEY_BYTES).toString("base64url");
26849
+ writePrivateFileAtomic(input.keyFile, `${KEY_FILE_PREFIX}${encoded}\n`);
26850
+ try {
26851
+ chmodSync(input.keyFile, 384);
26852
+ } catch {}
26853
+ }
26854
+ return loadVaultKey(input);
26855
+ }
26856
+ function vaultKeySourceStatus(input) {
26857
+ const envKey = input.env?.CAPLETS_ENCRYPTION_KEY;
26858
+ if (envKey !== void 0) try {
26859
+ decodeExactKey(envKey, "CAPLETS_ENCRYPTION_KEY");
26860
+ return {
26861
+ available: true,
26862
+ source: "env"
26863
+ };
26864
+ } catch {
26865
+ return {
26866
+ available: false,
26867
+ source: "env",
26868
+ reason: "invalid"
26869
+ };
26870
+ }
26871
+ if (!existsSync(input.keyFile)) return {
26872
+ available: false,
26873
+ source: "file",
26874
+ reason: "missing",
26875
+ keyFile: input.keyFile
26876
+ };
26877
+ let mode;
26878
+ try {
26879
+ mode = statSync(input.keyFile).mode;
26880
+ } catch (error) {
26881
+ return unavailableKeyFileStatus(input.keyFile, error);
26882
+ }
26883
+ if (process.platform !== "win32" && (mode & 63) !== 0) return {
26884
+ available: false,
26885
+ source: "file",
26886
+ reason: "wrong-permissions",
26887
+ keyFile: input.keyFile
26888
+ };
26889
+ let contents;
26890
+ try {
26891
+ contents = readFileSync(input.keyFile, "utf8");
26892
+ } catch (error) {
26893
+ return unavailableKeyFileStatus(input.keyFile, error);
26894
+ }
26895
+ try {
26896
+ parseKeyFile(contents);
26897
+ return {
26898
+ available: true,
26899
+ source: "file",
26900
+ keyFile: input.keyFile
26901
+ };
26902
+ } catch (error) {
26903
+ return {
26904
+ available: false,
26905
+ source: "file",
26906
+ reason: error instanceof CapletsError && error.message.includes("unsupported") ? "unsupported-version" : "invalid",
26907
+ keyFile: input.keyFile
26908
+ };
26909
+ }
26910
+ }
26911
+ function unavailableKeyFileStatus(keyFile, error) {
26912
+ return {
26913
+ available: false,
26914
+ source: "file",
26915
+ reason: (error && typeof error === "object" && "code" in error ? String(error.code) : "") === "ENOENT" ? "missing" : "unreadable",
26916
+ keyFile
26917
+ };
26918
+ }
26919
+ function parseKeyFile(contents) {
26920
+ const trimmed = contents.trim();
26921
+ if (!trimmed.startsWith(KEY_FILE_PREFIX)) throw new CapletsError("CONFIG_INVALID", "Vault key file has an unsupported format version.");
26922
+ return decodeExactKey(trimmed.slice(21), "Vault key file");
26923
+ }
26924
+ function decodeExactKey(encoded, label) {
26925
+ let decoded;
26926
+ try {
26927
+ decoded = Buffer$1.from(encoded, "base64url");
26928
+ } catch {
26929
+ throw new CapletsError("REQUEST_INVALID", `${label} must be a base64url-encoded 32-byte key.`);
26930
+ }
26931
+ if (decoded.length !== KEY_BYTES || decoded.toString("base64url") !== encoded.replace(/=+$/u, "")) throw new CapletsError("REQUEST_INVALID", `${label} must be a base64url-encoded 32-byte key.`);
26932
+ return decoded;
26933
+ }
26934
+ //#endregion
26935
+ //#region src/vault/access.ts
26936
+ function normalizeVaultGrant(input) {
26937
+ const now = (input.now ?? /* @__PURE__ */ new Date()).toISOString();
26938
+ return {
26939
+ storedKey: validateVaultKeyName(input.storedKey),
26940
+ referenceName: validateVaultKeyName(input.referenceName),
26941
+ capletId: validateCapletId(input.capletId),
26942
+ origin: normalizeOrigin(input.origin),
26943
+ createdAt: now,
26944
+ updatedAt: now
26945
+ };
26946
+ }
26947
+ function upsertVaultGrant(grants, input) {
26948
+ const next = normalizeVaultGrant(input);
26949
+ return [...grants.filter((grant) => !sameGrantIdentity(grant, next)), {
26950
+ ...next,
26951
+ createdAt: grants.find((grant) => sameGrantIdentity(grant, next))?.createdAt ?? next.createdAt
26952
+ }].sort(compareGrants);
26953
+ }
26954
+ function filterVaultGrants(grants, filter = {}) {
26955
+ return grants.filter((grant) => {
26956
+ if (filter.storedKey !== void 0 && grant.storedKey !== filter.storedKey) return false;
26957
+ if (filter.referenceName !== void 0 && grant.referenceName !== filter.referenceName) return false;
26958
+ if (filter.capletId !== void 0 && grant.capletId !== filter.capletId) return false;
26959
+ if (filter.origin !== void 0 && !sameOrigin(grant.origin, filter.origin)) return false;
26960
+ return true;
26961
+ });
26962
+ }
26963
+ function sameOrigin(left, right) {
26964
+ return left.kind === right.kind && left.path === right.path;
26965
+ }
26966
+ function sameGrantIdentity(left, right) {
26967
+ return left.referenceName === right.referenceName && left.capletId === right.capletId && sameOrigin(left.origin, right.origin);
26968
+ }
26969
+ function normalizeOrigin(origin) {
26970
+ if (!origin.path) throw new CapletsError("REQUEST_INVALID", "Vault access grants require a config origin path.");
26971
+ return {
26972
+ kind: origin.kind,
26973
+ path: origin.path
26974
+ };
26975
+ }
26976
+ function validateCapletId(capletId) {
26977
+ if (!/^[a-zA-Z0-9_-]{1,64}$/u.test(capletId)) throw new CapletsError("REQUEST_INVALID", "Vault access grants require a valid Caplet ID.");
26978
+ return capletId;
26979
+ }
26980
+ function compareGrants(left, right) {
26981
+ return left.capletId.localeCompare(right.capletId) || left.referenceName.localeCompare(right.referenceName) || left.storedKey.localeCompare(right.storedKey) || left.origin.kind.localeCompare(right.origin.kind) || left.origin.path.localeCompare(right.origin.path);
26982
+ }
26983
+ //#endregion
26984
+ //#region src/vault/types.ts
26985
+ const VAULT_MAX_VALUE_BYTES = 64 * 1024;
26986
+ //#endregion
26987
+ //#region src/vault/index.ts
26988
+ var FileVaultStore = class {
26989
+ root;
26990
+ env;
26991
+ paths;
26992
+ constructor(options = {}) {
26993
+ this.root = options.root ?? join(defaultStateBaseDir(options.env), "caplets", "vault");
26994
+ this.env = options.env ?? process.env;
26995
+ this.paths = {
26996
+ keyFile: join(this.root, "vault-key"),
26997
+ valuesDir: join(this.root, "values"),
26998
+ grantsFile: join(this.root, "access-grants.json")
26999
+ };
27000
+ }
27001
+ valuePath(key) {
27002
+ return join(this.paths.valuesDir, `${encodeURIComponent(validateVaultKeyName(key))}.json`);
27003
+ }
27004
+ set(key, value, options = {}) {
27005
+ const normalizedKey = validateVaultKeyName(key);
27006
+ if (Buffer$1.byteLength(value, "utf8") > 65536) throw new CapletsError("REQUEST_INVALID", `Vault values must be ${VAULT_MAX_VALUE_BYTES} bytes or smaller.`);
27007
+ const path = this.valuePath(normalizedKey);
27008
+ const existing = this.loadValueRecord(normalizedKey);
27009
+ if (existing && !options.force) throw new CapletsError("CONFIG_EXISTS", `Vault key ${normalizedKey} already exists.`);
27010
+ ensurePrivateDir(this.root);
27011
+ ensurePrivateDir(this.paths.valuesDir);
27012
+ const encrypted = encryptVaultValue({
27013
+ plaintext: value,
27014
+ key: ensureVaultKey({
27015
+ keyFile: this.paths.keyFile,
27016
+ env: this.env
27017
+ }),
27018
+ now: options.now ?? /* @__PURE__ */ new Date(),
27019
+ ...existing ? { existing } : {}
27020
+ });
27021
+ writePrivateFileAtomic(path, `${JSON.stringify(encrypted, null, 2)}\n`);
27022
+ return this.statusForRecord(normalizedKey, encrypted);
27023
+ }
27024
+ getStatus(key) {
27025
+ const normalizedKey = validateVaultKeyName(key);
27026
+ const record = this.loadValueRecord(normalizedKey);
27027
+ return record ? this.statusForRecord(normalizedKey, record) : {
27028
+ key: normalizedKey,
27029
+ present: false
27030
+ };
27031
+ }
27032
+ listValues() {
27033
+ if (!existsSync(this.paths.valuesDir)) return [];
27034
+ return readdirSync(this.paths.valuesDir).filter((entry) => entry.endsWith(".json")).map((entry) => decodeURIComponent(basename(entry, ".json"))).map((key) => this.getStatus(key)).filter((status) => status.present).sort((left, right) => left.key.localeCompare(right.key));
27035
+ }
27036
+ resolveValue(key) {
27037
+ const normalizedKey = validateVaultKeyName(key);
27038
+ const record = this.loadValueRecord(normalizedKey);
27039
+ if (!record) throw new CapletsError("CONFIG_INVALID", `Vault key ${normalizedKey} is missing.`);
27040
+ return decryptVaultValue(record, loadVaultKey({
27041
+ keyFile: this.paths.keyFile,
27042
+ env: this.env
27043
+ }));
27044
+ }
27045
+ delete(key) {
27046
+ const normalizedKey = validateVaultKeyName(key);
27047
+ return {
27048
+ key: normalizedKey,
27049
+ deleted: deleteFile(this.valuePath(normalizedKey)),
27050
+ grantsRetained: this.listAccess({ storedKey: normalizedKey }).length
27051
+ };
27052
+ }
27053
+ keySourceStatus() {
27054
+ return vaultKeySourceStatus({
27055
+ keyFile: this.paths.keyFile,
27056
+ env: this.env
27057
+ });
27058
+ }
27059
+ grantAccess(input) {
27060
+ const next = normalizeVaultGrant(input);
27061
+ const grants = upsertVaultGrant(this.loadAccessGrants(), input);
27062
+ this.saveAccessGrants(grants);
27063
+ return grants.find((grant) => grant.storedKey === next.storedKey && grant.referenceName === next.referenceName && grant.capletId === next.capletId && sameOrigin(grant.origin, next.origin));
27064
+ }
27065
+ listAccess(filter = {}) {
27066
+ return filterVaultGrants(this.loadAccessGrants(), filter);
27067
+ }
27068
+ revokeAccess(filter) {
27069
+ const removed = this.listAccess(filter);
27070
+ if (removed.length === 0) return [];
27071
+ const removedKeys = new Set(removed.map(accessGrantIdentity));
27072
+ const remaining = this.loadAccessGrants().filter((grant) => !removedKeys.has(accessGrantIdentity(grant)));
27073
+ this.saveAccessGrants(remaining);
27074
+ return removed;
27075
+ }
27076
+ resolveGrantedValue(input) {
27077
+ const referenceName = validateVaultKeyName(input.referenceName);
27078
+ const grant = this.listAccess({
27079
+ referenceName,
27080
+ capletId: input.capletId,
27081
+ origin: input.origin
27082
+ })[0];
27083
+ if (!grant) return {
27084
+ reason: "ungranted",
27085
+ referenceName,
27086
+ capletId: input.capletId,
27087
+ origin: input.origin
27088
+ };
27089
+ if (!existsSync(this.valuePath(grant.storedKey))) return {
27090
+ reason: "missing",
27091
+ storedKey: grant.storedKey,
27092
+ referenceName,
27093
+ capletId: input.capletId,
27094
+ origin: input.origin
27095
+ };
27096
+ return {
27097
+ storedKey: grant.storedKey,
27098
+ value: this.resolveValue(grant.storedKey)
27099
+ };
27100
+ }
27101
+ loadValueRecord(key) {
27102
+ const path = this.valuePath(key);
27103
+ if (!existsSync(path)) return void 0;
27104
+ let raw;
27105
+ try {
27106
+ raw = readJsonFile(path, {});
27107
+ } catch {
27108
+ throw new CapletsError("CONFIG_INVALID", `Vault value record for ${key} is not valid JSON.`);
27109
+ }
27110
+ return parseEncryptedRecord(raw);
27111
+ }
27112
+ statusForRecord(key, record) {
27113
+ return {
27114
+ key,
27115
+ present: true,
27116
+ valueBytes: record.valueBytes,
27117
+ createdAt: record.createdAt,
27118
+ updatedAt: record.updatedAt
27119
+ };
27120
+ }
27121
+ loadAccessGrants() {
27122
+ let raw;
27123
+ try {
27124
+ raw = readJsonFile(this.paths.grantsFile, []);
27125
+ } catch {
27126
+ throw new CapletsError("CONFIG_INVALID", "Vault access grants file is not valid JSON.");
27127
+ }
27128
+ if (!Array.isArray(raw)) throw new CapletsError("CONFIG_INVALID", "Vault access grants file must contain an array.");
27129
+ return raw.map(parseStoredGrant);
27130
+ }
27131
+ saveAccessGrants(grants) {
27132
+ ensurePrivateDir(this.root);
27133
+ writePrivateFileAtomic(this.paths.grantsFile, `${JSON.stringify(grants, null, 2)}\n`);
27134
+ }
27135
+ };
27136
+ function accessGrantIdentity(grant) {
27137
+ return [
27138
+ grant.storedKey,
27139
+ grant.referenceName,
27140
+ grant.capletId,
27141
+ grant.origin.kind,
27142
+ grant.origin.path
27143
+ ].join("\0");
27144
+ }
27145
+ function parseStoredGrant(value) {
27146
+ if (!value || typeof value !== "object" || Array.isArray(value)) throw new CapletsError("CONFIG_INVALID", "Vault access grant must be an object.");
27147
+ const record = value;
27148
+ if (typeof record.storedKey !== "string" || typeof record.referenceName !== "string" || typeof record.capletId !== "string" || typeof record.createdAt !== "string" || typeof record.updatedAt !== "string" || !record.origin || typeof record.origin !== "object" || Array.isArray(record.origin)) throw new CapletsError("CONFIG_INVALID", "Vault access grant is malformed.");
27149
+ const originRecord = record.origin;
27150
+ if (typeof originRecord.kind !== "string" || typeof originRecord.path !== "string" || ![
27151
+ "global-config",
27152
+ "global-file",
27153
+ "project-config",
27154
+ "project-file"
27155
+ ].includes(originRecord.kind)) throw new CapletsError("CONFIG_INVALID", "Vault access grant origin is malformed.");
27156
+ return {
27157
+ ...normalizeVaultGrant({
27158
+ storedKey: record.storedKey,
27159
+ referenceName: record.referenceName,
27160
+ capletId: record.capletId,
27161
+ origin: {
27162
+ kind: originRecord.kind,
27163
+ path: originRecord.path
27164
+ }
27165
+ }),
27166
+ createdAt: record.createdAt,
27167
+ updatedAt: record.updatedAt
27168
+ };
26762
27169
  }
26763
27170
  //#endregion
26764
27171
  //#region src/config.ts
26765
- const NON_INTERPOLATED_SERVER_FIELDS = new Set([
27172
+ const NON_INTERPOLATED_SERVER_FIELDS = /* @__PURE__ */ new Set([
26766
27173
  "name",
26767
27174
  "description",
26768
27175
  "tags",
26769
27176
  "body"
26770
27177
  ]);
27178
+ const VAULT_BARE_REFERENCE = "[A-Za-z0-9_-]+";
26771
27179
  const remoteAuthSchema = discriminatedUnion("type", [
26772
27180
  object$1({ type: literal("none") }).strict(),
26773
27181
  object$1({
@@ -27430,10 +27838,10 @@ function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, googleDi
27430
27838
  }
27431
27839
  const configFileSchema = configSchemaFor(publicServerSchema, publicOpenApiEndpointSchema, publicGoogleDiscoveryApiSchema, publicGraphQlEndpointSchema, publicHttpApiSchema, publicCliToolsSchema, publicCapletSetSchema);
27432
27840
  const normalizedConfigFileSchema = configSchemaFor(normalizedServerSchema, normalizedOpenApiEndpointSchema, normalizedGoogleDiscoveryApiSchema, normalizedGraphQlEndpointSchema, normalizedHttpApiSchema, normalizedCliToolsSchema, normalizedCapletSetSchema);
27433
- function loadConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
27434
- return loadConfigWithSources(path, projectPath).config;
27841
+ function loadConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath(), options = {}) {
27842
+ return loadConfigWithSources(path, projectPath, options).config;
27435
27843
  }
27436
- function loadConfigWithSources(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
27844
+ function loadConfigWithSources(path = resolveConfigPath(), projectPath = resolveProjectConfigPath(), options = {}) {
27437
27845
  const hasUserConfig = existsSync(path);
27438
27846
  const hasProjectConfig = existsSync(projectPath);
27439
27847
  const userConfig = hasUserConfig ? readPublicConfigInput(path) : void 0;
@@ -27470,9 +27878,9 @@ function loadConfigWithSources(path = resolveConfigPath(), projectPath = resolve
27470
27878
  path: projectCaplets.paths
27471
27879
  }
27472
27880
  } : void 0
27473
- ], `Caplets config not found at ${path} or ${projectPath}`, "Caplets config must define at least one MCP server, OpenAPI endpoint, Google Discovery API, GraphQL endpoint, HTTP API, CLI tools backend, or Caplet set");
27881
+ ], `Caplets config not found at ${path} or ${projectPath}`, "Caplets config must define at least one MCP server, OpenAPI endpoint, Google Discovery API, GraphQL endpoint, HTTP API, CLI tools backend, or Caplet set", options);
27474
27882
  }
27475
- function loadGlobalConfig(path = resolveConfigPath()) {
27883
+ function loadGlobalConfig(path = resolveConfigPath(), options = {}) {
27476
27884
  const userConfig = existsSync(path) ? readPublicConfigInput(path) : void 0;
27477
27885
  const userCaplets = loadCapletFilesWithPaths(resolveCapletsRoot(path));
27478
27886
  return buildConfigWithSources([{
@@ -27487,9 +27895,9 @@ function loadGlobalConfig(path = resolveConfigPath()) {
27487
27895
  kind: "global-file",
27488
27896
  path: userCaplets.paths
27489
27897
  }
27490
- } : void 0], `Caplets user config not found at ${path}`, void 0).config;
27898
+ } : void 0], `Caplets user config not found at ${path}`, void 0, options).config;
27491
27899
  }
27492
- function loadProjectConfig(projectPath = resolveProjectConfigPath()) {
27900
+ function loadProjectConfig(projectPath = resolveProjectConfigPath(), options = {}) {
27493
27901
  const projectConfig = existsSync(projectPath) ? rejectProjectConfigExecutableBackendMaps(readPublicConfigInput(projectPath), projectPath) : void 0;
27494
27902
  const projectCapletsRoot = resolveProjectCapletsRootForConfigPath(projectPath);
27495
27903
  const projectCaplets = projectCapletsRoot ? loadCapletFilesWithPaths(projectCapletsRoot) : void 0;
@@ -27505,13 +27913,16 @@ function loadProjectConfig(projectPath = resolveProjectConfigPath()) {
27505
27913
  kind: "project-file",
27506
27914
  path: projectCaplets.paths
27507
27915
  }
27508
- } : void 0], `Caplets project config not found at ${projectPath}`, void 0).config;
27916
+ } : void 0], `Caplets project config not found at ${projectPath}`, void 0, options).config;
27509
27917
  }
27510
- function buildConfigWithSources(inputs, notFoundMessage, emptyMessage) {
27918
+ function buildConfigWithSources(inputs, notFoundMessage, emptyMessage, options = {}) {
27511
27919
  if (!inputs.some((entry) => entry?.input !== void 0)) throw new CapletsError("CONFIG_NOT_FOUND", notFoundMessage);
27512
27920
  try {
27513
27921
  const { input, sources, shadows } = mergeConfigInputsWithSources(...inputs);
27514
- const config = parseConfig(input);
27922
+ const config = parseConfig(input, {
27923
+ sources,
27924
+ vaultResolver: options.vaultResolver ?? defaultVaultResolver()
27925
+ });
27515
27926
  if (emptyMessage && Object.keys(config.mcpServers).length === 0 && Object.keys(config.openapiEndpoints).length === 0 && Object.keys(config.googleDiscoveryApis).length === 0 && Object.keys(config.graphqlEndpoints).length === 0 && Object.keys(config.httpApis).length === 0 && Object.keys(config.cliTools).length === 0 && Object.keys(config.capletSets).length === 0) throw new CapletsError("CONFIG_INVALID", emptyMessage);
27516
27927
  return {
27517
27928
  config,
@@ -27523,13 +27934,18 @@ function buildConfigWithSources(inputs, notFoundMessage, emptyMessage) {
27523
27934
  throw new CapletsError("CONFIG_INVALID", "Caplets config is not valid JSON", redactSecrets(error));
27524
27935
  }
27525
27936
  }
27526
- function loadLocalOverlayConfigWithSources(path = resolveConfigPath(), projectPath = resolveProjectConfigPath()) {
27937
+ function loadLocalOverlayConfigWithSources(path = resolveConfigPath(), projectPath = resolveProjectConfigPath(), options = {}) {
27938
+ const parseOptions = {
27939
+ vaultResolver: options.vaultResolver ?? defaultVaultResolver(),
27940
+ vaultRecoveryTarget: options.vaultRecoveryTarget
27941
+ };
27527
27942
  const warnings = [];
27528
- const userConfig = existsSync(path) ? readBestEffortConfigInput(path, "global-config", warnings) : void 0;
27529
- const userCaplets = loadBestEffortCapletFiles(resolveCapletsRoot(path), "global-file", warnings);
27530
- const projectConfig = existsSync(projectPath) ? readBestEffortConfigInput(projectPath, "project-config", warnings, (input) => rejectProjectConfigExecutableBackendMaps(input, projectPath)) : void 0;
27943
+ const userConfig = existsSync(path) ? readBestEffortConfigInput(path, "global-config", warnings, void 0, parseOptions) : void 0;
27944
+ const userCaplets = loadBestEffortCapletFiles(resolveCapletsRoot(path), "global-file", warnings, parseOptions);
27945
+ const projectConfig = existsSync(projectPath) ? readBestEffortConfigInput(projectPath, "project-config", warnings, (input) => rejectProjectConfigExecutableBackendMaps(input, projectPath), parseOptions) : void 0;
27531
27946
  const projectCapletsRoot = resolveProjectCapletsRootForConfigPath(projectPath);
27532
- const projectCaplets = projectCapletsRoot ? loadBestEffortCapletFiles(projectCapletsRoot, "project-file", warnings) : void 0;
27947
+ const projectCaplets = projectCapletsRoot ? loadBestEffortCapletFiles(projectCapletsRoot, "project-file", warnings, parseOptions) : void 0;
27948
+ const sourceFound = Boolean(userConfig || userCaplets || projectConfig || projectCaplets);
27533
27949
  const { input, sources, shadows } = mergeConfigInputsWithSources({
27534
27950
  input: userConfig,
27535
27951
  source: {
@@ -27556,17 +27972,40 @@ function loadLocalOverlayConfigWithSources(path = resolveConfigPath(), projectPa
27556
27972
  }
27557
27973
  } : void 0);
27558
27974
  return {
27559
- config: parseConfig(input),
27975
+ config: parseConfig(input, {
27976
+ sources,
27977
+ vaultResolver: parseOptions.vaultResolver
27978
+ }),
27560
27979
  sources,
27561
27980
  shadows,
27562
- warnings
27981
+ warnings,
27982
+ sourceFound
27563
27983
  };
27564
27984
  }
27565
- function readBestEffortConfigInput(path, kind, warnings, transform) {
27985
+ function loadLocalRuntimeConfig(path = resolveConfigPath(), projectPath = resolveProjectConfigPath(), options = {}) {
27986
+ const overlay = loadLocalOverlayConfigWithSources(path, projectPath, {
27987
+ vaultResolver: options.vaultResolver,
27988
+ vaultRecoveryTarget: options.vaultRecoveryTarget
27989
+ });
27990
+ for (const warning of overlay.warnings) options.writeWarning?.(warning);
27991
+ const blockingWarning = overlay.warnings.find((warning) => !warning.recoverable && (warning.kind === "global-config" || warning.kind === "project-config"));
27992
+ if (blockingWarning) throw new CapletsError("CONFIG_INVALID", blockingWarning.message);
27993
+ if (!overlay.sourceFound) throw new CapletsError("CONFIG_NOT_FOUND", `Caplets config not found at ${path} or ${projectPath}`);
27994
+ if (!configHasAnyCaplets(overlay.config) && !overlay.warnings.some((warning) => warning.recoverable)) throw new CapletsError("CONFIG_INVALID", "Caplets config must define at least one MCP server, OpenAPI endpoint, Google Discovery API, GraphQL endpoint, HTTP API, CLI tools backend, or Caplet set");
27995
+ return overlay.config;
27996
+ }
27997
+ function readBestEffortConfigInput(path, kind, warnings, transform, options = {}) {
27566
27998
  try {
27567
27999
  const normalized = normalizeLocalPaths(readBestEffortJsonConfigInput(path), dirname(path));
27568
- const filtered = quarantineMissingEnvCaplets(transform ? transform(normalized) : normalized, kind, path, warnings);
27569
- const parsed = configFileSchema.safeParse(interpolateConfig(filtered));
28000
+ const filtered = quarantineUnresolvedReferenceCaplets(transform ? transform(normalized) : normalized, kind, path, warnings, options);
28001
+ const validationOptions = {
28002
+ ...options,
28003
+ sources: Object.fromEntries(capletIds(filtered).map((id) => [id, {
28004
+ kind,
28005
+ path
28006
+ }]))
28007
+ };
28008
+ const parsed = configFileSchema.safeParse(interpolateConfig(filtered, [], validationOptions));
27570
28009
  if (!parsed.success) throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is invalid`, parsed.error.issues);
27571
28010
  return filtered;
27572
28011
  } catch (error) {
@@ -27585,21 +28024,35 @@ function readBestEffortJsonConfigInput(path) {
27585
28024
  throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is not valid JSON`, redactSecrets(error));
27586
28025
  }
27587
28026
  }
27588
- function quarantineMissingEnvCaplets(input, kind, sourcePath, warnings) {
28027
+ function quarantineUnresolvedReferenceCaplets(input, kind, sourcePath, warnings, options = {}) {
27589
28028
  let filtered = input;
27590
28029
  for (const backend of CAPLET_BACKEND_KEYS) {
27591
28030
  const caplets = filtered[backend];
27592
28031
  if (!isPlainObject$5(caplets)) continue;
27593
28032
  for (const [id, caplet] of Object.entries(caplets)) {
27594
- const missing = missingEnvReferences(caplet, [backend, id]);
27595
- if (missing.length === 0) continue;
28033
+ const envMissing = missingEnvReferences(caplet, [backend, id]);
28034
+ const capletSourcePath = typeof sourcePath === "function" ? sourcePath(id) : sourcePath;
28035
+ const vaultIssues = unresolvedVaultReferences(caplet, [backend, id], {
28036
+ capletId: id,
28037
+ origin: {
28038
+ kind,
28039
+ path: capletSourcePath
28040
+ }
28041
+ }, options);
28042
+ if (envMissing.length === 0 && vaultIssues.length === 0) continue;
27596
28043
  filtered = removeCapletBackendId(filtered, backend, id);
27597
- warnings.push({
28044
+ for (const missing of groupMissingEnvReferences(envMissing)) warnings.push({
27598
28045
  kind,
27599
- path: typeof sourcePath === "function" ? sourcePath(id) : sourcePath,
28046
+ path: capletSourcePath,
27600
28047
  message: formatMissingEnvWarning(id, missing),
27601
28048
  recoverable: true
27602
28049
  });
28050
+ for (const issue of vaultIssues) warnings.push({
28051
+ kind,
28052
+ path: capletSourcePath,
28053
+ message: formatVaultReferenceWarning(id, issue, options.vaultRecoveryTarget),
28054
+ recoverable: true
28055
+ });
27603
28056
  }
27604
28057
  }
27605
28058
  return filtered;
@@ -27627,7 +28080,90 @@ function formatMissingEnvWarning(id, missing) {
27627
28080
  const paths = [...new Set(missing.map((reference) => reference.path))];
27628
28081
  return `Caplet ${id} references missing ${names.length === 1 ? "environment variable" : "environment variables"} ${names.join(", ")} at ${paths.join(", ")}; skipping Caplet ${id}.`;
27629
28082
  }
27630
- function loadBestEffortCapletFiles(root, kind, warnings) {
28083
+ function groupMissingEnvReferences(missing) {
28084
+ return missing.length === 0 ? [] : [missing];
28085
+ }
28086
+ function configHasAnyCaplets(config) {
28087
+ return Object.keys(config.mcpServers).length > 0 || Object.keys(config.openapiEndpoints).length > 0 || Object.keys(config.googleDiscoveryApis).length > 0 || Object.keys(config.graphqlEndpoints).length > 0 || Object.keys(config.httpApis).length > 0 || Object.keys(config.cliTools).length > 0 || Object.keys(config.capletSets).length > 0;
28088
+ }
28089
+ function unresolvedVaultReferences(value, path, context, options) {
28090
+ if (isPublicMetadataPath(path)) return [];
28091
+ if (typeof value === "string") return unresolvedVaultReferencesInString(value, path.join("."), context, options);
28092
+ if (Array.isArray(value)) return value.flatMap((item, index) => unresolvedVaultReferences(item, [...path, String(index)], context, options));
28093
+ if (isPlainObject$5(value)) return Object.entries(value).flatMap(([key, nested]) => unresolvedVaultReferences(nested, [...path, key], context, options));
28094
+ return [];
28095
+ }
28096
+ function unresolvedVaultReferencesInString(value, path, context, options) {
28097
+ const issues = [];
28098
+ for (const match of value.matchAll(VAULT_REFERENCE_PATTERN)) {
28099
+ const name = match[1] ?? match[2];
28100
+ if (!name) continue;
28101
+ try {
28102
+ validateVaultKeyName(name);
28103
+ } catch {
28104
+ issues.push({
28105
+ name,
28106
+ path,
28107
+ reason: "invalid-key-source"
28108
+ });
28109
+ continue;
28110
+ }
28111
+ const resolution = options.vaultResolver?.({
28112
+ referenceName: name,
28113
+ capletId: context.capletId,
28114
+ origin: context.origin,
28115
+ path
28116
+ });
28117
+ if (!resolution || !("value" in resolution)) {
28118
+ const reason = resolution && "reason" in resolution ? resolution.reason : "unavailable";
28119
+ issues.push({
28120
+ name,
28121
+ path,
28122
+ reason,
28123
+ ...resolution && "storedKey" in resolution && resolution.storedKey ? { storedKey: resolution.storedKey } : {}
28124
+ });
28125
+ }
28126
+ }
28127
+ return issues;
28128
+ }
28129
+ function formatVaultReferenceWarning(id, issue, target) {
28130
+ const key = issue.storedKey ?? issue.name;
28131
+ const targetFlag = target === "remote" ? " --remote" : "";
28132
+ if (issue.reason === "invalid-key-source") return `Caplet ${id} references invalid-key-source Vault key ${key} at ${issue.path}; run \`caplets doctor\` for key-source details, then reload Caplets; skipping Caplet ${id}.`;
28133
+ if (issue.reason === "missing") return `Caplet ${id} references missing Vault key ${key} at ${issue.path}; run \`caplets vault set ${key}${targetFlag}\`, then reload Caplets; skipping Caplet ${id}.`;
28134
+ const grantCommand = `caplets vault access grant ${key} ${id}${targetFlag}${key !== issue.name ? ` --as ${issue.name}` : ""}`;
28135
+ return `Caplet ${id} references ${issue.reason} Vault key ${key} at ${issue.path}; run \`${grantCommand}\` after setting the value, then reload Caplets; skipping Caplet ${id}.`;
28136
+ }
28137
+ function defaultVaultResolver(store = new FileVaultStore()) {
28138
+ return (reference) => {
28139
+ try {
28140
+ return store.resolveGrantedValue(reference);
28141
+ } catch (error) {
28142
+ return {
28143
+ reason: error instanceof CapletsError ? "invalid-key-source" : "unavailable",
28144
+ referenceName: reference.referenceName,
28145
+ capletId: reference.capletId,
28146
+ origin: reference.origin
28147
+ };
28148
+ }
28149
+ };
28150
+ }
28151
+ function vaultStoreForAuthDir(authDir) {
28152
+ return new FileVaultStore(authDir ? { root: join(authDir, "vault") } : {});
28153
+ }
28154
+ function vaultResolverForAuthDir(authDir) {
28155
+ return defaultVaultResolver(vaultStoreForAuthDir(authDir));
28156
+ }
28157
+ const vaultBootstrapResolver = (reference) => ({
28158
+ storedKey: reference.referenceName,
28159
+ value: vaultBootstrapPlaceholderValue(reference.path)
28160
+ });
28161
+ function vaultBootstrapPlaceholderValue(path) {
28162
+ const leaf = path.split(".").at(-1)?.toLowerCase() ?? "";
28163
+ if (leaf.endsWith("url") || leaf.endsWith("uri") || leaf === "issuer") return "https://caplets.local/vault-placeholder";
28164
+ return "caplets-vault-placeholder";
28165
+ }
28166
+ function loadBestEffortCapletFiles(root, kind, warnings, options = {}) {
27631
28167
  const result = loadCapletFilesWithPathsBestEffort(root);
27632
28168
  if (!result) return;
27633
28169
  for (const warning of result.warnings) warnings.push({
@@ -27635,7 +28171,7 @@ function loadBestEffortCapletFiles(root, kind, warnings) {
27635
28171
  path: warning.path ?? root,
27636
28172
  message: warning.message
27637
28173
  });
27638
- const config = quarantineMissingEnvCaplets(result.config, kind, (id) => result.paths[id] ?? root, warnings);
28174
+ const config = quarantineUnresolvedReferenceCaplets(result.config, kind, (id) => result.paths[id] ?? root, warnings, options);
27639
28175
  const retainedIds = new Set(capletIds(config));
27640
28176
  return {
27641
28177
  config,
@@ -27647,14 +28183,44 @@ function errorMessage$3(error) {
27647
28183
  }
27648
28184
  function loadIsolatedConfig(options) {
27649
28185
  if (!options.configPath && !options.capletsRoot) throw new CapletsError("CONFIG_INVALID", "Nested Caplet set must define at least one source: configPath or capletsRoot");
27650
- const configInput = options.configPath ? readPublicConfigInput(options.configPath) : void 0;
27651
- const capletInput = options.capletsRoot ? loadCapletFiles(options.capletsRoot) : void 0;
27652
- if (!configInput && !capletInput) throw new CapletsError("CONFIG_NOT_FOUND", `Nested Caplet set sources not found: ${[options.configPath, options.capletsRoot].filter(Boolean).join(", ")}`);
27653
- const config = parseConfig(mergeConfigInputs(configInput, capletInput, {
27654
- version: 1,
27655
- defaultSearchLimit: options.defaultSearchLimit,
27656
- maxSearchLimit: options.maxSearchLimit
27657
- }));
28186
+ const warnings = [];
28187
+ const parseOptions = {
28188
+ vaultResolver: options.vaultResolver ?? defaultVaultResolver(),
28189
+ vaultRecoveryTarget: options.vaultRecoveryTarget
28190
+ };
28191
+ const configExists = Boolean(options.configPath && existsSync(options.configPath));
28192
+ const configInput = configExists ? readBestEffortConfigInput(options.configPath, "global-config", warnings, void 0, parseOptions) : void 0;
28193
+ const capletInput = options.capletsRoot ? loadBestEffortCapletFiles(options.capletsRoot, "global-file", warnings, parseOptions) : void 0;
28194
+ if (!configExists && !capletInput) throw new CapletsError("CONFIG_NOT_FOUND", `Nested Caplet set sources not found: ${[options.configPath, options.capletsRoot].filter(Boolean).join(", ")}`);
28195
+ const blockingWarning = warnings.find((warning) => !warning.recoverable);
28196
+ if (blockingWarning) throw new CapletsError("CONFIG_INVALID", blockingWarning.message);
28197
+ const { input, sources } = mergeConfigInputsWithSources({
28198
+ input: configInput,
28199
+ source: {
28200
+ kind: "global-config",
28201
+ path: options.configPath ?? ""
28202
+ }
28203
+ }, capletInput ? {
28204
+ input: capletInput.config,
28205
+ source: {
28206
+ kind: "global-file",
28207
+ path: capletInput.paths
28208
+ }
28209
+ } : void 0, {
28210
+ input: {
28211
+ version: 1,
28212
+ defaultSearchLimit: options.defaultSearchLimit,
28213
+ maxSearchLimit: options.maxSearchLimit
28214
+ },
28215
+ source: {
28216
+ kind: "global-config",
28217
+ path: options.configPath ?? ""
28218
+ }
28219
+ });
28220
+ const config = parseConfig(input, {
28221
+ sources,
28222
+ vaultResolver: parseOptions.vaultResolver
28223
+ });
27658
28224
  if (Object.keys(config.mcpServers).length === 0 && Object.keys(config.openapiEndpoints).length === 0 && Object.keys(config.googleDiscoveryApis).length === 0 && Object.keys(config.graphqlEndpoints).length === 0 && Object.keys(config.httpApis).length === 0 && Object.keys(config.cliTools).length === 0 && Object.keys(config.capletSets).length === 0) throw new CapletsError("CONFIG_INVALID", "Nested Caplet set must define at least one Caplet");
27659
28225
  return config;
27660
28226
  }
@@ -27665,7 +28231,14 @@ function resolveProjectCapletsRootForConfigPath(projectPath) {
27665
28231
  function readPublicConfigInput(path) {
27666
28232
  try {
27667
28233
  const normalized = normalizeLocalPaths(JSON.parse(readFileSync(path, "utf8")), dirname(path));
27668
- const parsed = configFileSchema.safeParse(interpolateConfig(normalized));
28234
+ const validationOptions = {
28235
+ sources: Object.fromEntries(capletIds(normalized).map((id) => [id, {
28236
+ kind: "global-config",
28237
+ path
28238
+ }])),
28239
+ vaultResolver: vaultBootstrapResolver
28240
+ };
28241
+ const parsed = configFileSchema.safeParse(interpolateConfig(normalized, [], validationOptions));
27669
28242
  if (!parsed.success) throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is invalid`, parsed.error.issues);
27670
28243
  return normalized;
27671
28244
  } catch (error) {
@@ -27729,7 +28302,7 @@ function normalizeCapletSetPaths(endpoint, baseDir) {
27729
28302
  };
27730
28303
  }
27731
28304
  function normalizeLocalPath(value, baseDir) {
27732
- if (typeof value !== "string" || !value || isAbsolute(value) || hasEnvReference(value)) return value;
28305
+ if (typeof value !== "string" || !value || isAbsolute(value) || hasInterpolationReference(value)) return value;
27733
28306
  return join(baseDir, value);
27734
28307
  }
27735
28308
  function rejectProjectConfigExecutableBackendMaps(input, path) {
@@ -27845,8 +28418,8 @@ function sourceForId(source, id) {
27845
28418
  path: typeof source.path === "string" ? source.path : source.path[id] ?? ""
27846
28419
  };
27847
28420
  }
27848
- function parseConfig(input) {
27849
- const parsed = normalizedConfigFileSchema.safeParse(interpolateConfig(input));
28421
+ function parseConfig(input, options = {}) {
28422
+ const parsed = normalizedConfigFileSchema.safeParse(interpolateConfig(input, [], options));
27850
28423
  if (!parsed.success) throw new CapletsError("CONFIG_INVALID", "Caplets config is invalid", parsed.error.issues);
27851
28424
  const servers = {};
27852
28425
  for (const [server, raw] of Object.entries(parsed.data.mcpServers)) {
@@ -27931,11 +28504,11 @@ function validateEndpointAuthHeaders(auth, ctx, path) {
27931
28504
  function stripUndefined(value) {
27932
28505
  return Object.fromEntries(Object.entries(value).filter(([, nested]) => nested !== void 0));
27933
28506
  }
27934
- function interpolateConfig(value, path = []) {
28507
+ function interpolateConfig(value, path = [], options = {}) {
27935
28508
  if (isPublicMetadataPath(path)) return value;
27936
- if (typeof value === "string") return interpolateEnv(value);
27937
- if (Array.isArray(value)) return value.map((item, index) => interpolateConfig(item, [...path, String(index)]));
27938
- if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([nestedKey, nested]) => [nestedKey, interpolateConfig(nested, [...path, nestedKey])]));
28509
+ if (typeof value === "string") return interpolateVault(interpolateEnv(value), path, options);
28510
+ if (Array.isArray(value)) return value.map((item, index) => interpolateConfig(item, [...path, String(index)], options));
28511
+ if (value && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([nestedKey, nested]) => [nestedKey, interpolateConfig(nested, [...path, nestedKey], options)]));
27939
28512
  return value;
27940
28513
  }
27941
28514
  function isPublicMetadataPath(path) {
@@ -27945,8 +28518,28 @@ function isPublicMetadataPath(path) {
27945
28518
  function isPlainObject$5(value) {
27946
28519
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
27947
28520
  }
27948
- function hasEnvReference(value) {
27949
- return /\$\{[A-Za-z_][A-Za-z0-9_]*\}|\$env:[A-Za-z_][A-Za-z0-9_]*/.test(value);
28521
+ function hasInterpolationReference(value) {
28522
+ return new RegExp(`\\$\\{[A-Za-z_][A-Za-z0-9_]*\\}|\\$env:[A-Za-z_][A-Za-z0-9_]*|\\$\\{vault:[^}]+\\}|\\$vault:${VAULT_BARE_REFERENCE}`).test(value);
28523
+ }
28524
+ const VAULT_REFERENCE_PATTERN = new RegExp(`\\$\\{vault:([^}]+)\\}|\\$vault:(${VAULT_BARE_REFERENCE})`, "g");
28525
+ function interpolateVault(value, path, options) {
28526
+ if (!options.vaultResolver) return value;
28527
+ const backend = path[0];
28528
+ const capletId = path[1];
28529
+ if (!backend || !capletId || !CAPLET_BACKEND_KEY_SET.has(backend)) return value;
28530
+ const origin = options.sources?.[capletId];
28531
+ if (!origin) return value;
28532
+ return value.replace(VAULT_REFERENCE_PATTERN, (_match, braced, bare) => {
28533
+ const referenceName = validateVaultKeyName(braced ?? bare);
28534
+ const resolution = options.vaultResolver?.({
28535
+ referenceName,
28536
+ capletId,
28537
+ origin,
28538
+ path: path.join(".")
28539
+ });
28540
+ if (!resolution || !("value" in resolution)) throw new CapletsError("CONFIG_INVALID", `Vault key ${referenceName} is unresolved for Caplet ${capletId}`);
28541
+ return resolution.value;
28542
+ });
27950
28543
  }
27951
28544
  function interpolateEnv(value) {
27952
28545
  return value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (_match, name) => process.env[name] ?? "").replace(/\$env:([A-Za-z_][A-Za-z0-9_]*)/g, (_match, name) => process.env[name] ?? "");
@@ -27961,7 +28554,7 @@ function googleDiscoverySchemaToJsonSchema(value, schemas = {}, seen = /* @__PUR
27961
28554
  type: "object",
27962
28555
  additionalProperties: true
27963
28556
  };
27964
- return googleDiscoverySchemaToJsonSchema(target, schemas, new Set([...seen, value.$ref]));
28557
+ return googleDiscoverySchemaToJsonSchema(target, schemas, /* @__PURE__ */ new Set([...seen, value.$ref]));
27965
28558
  }
27966
28559
  const type = discoveryTypeToJsonSchemaType(value.type);
27967
28560
  const converted = {};
@@ -41372,7 +41965,7 @@ var require_OverlappingFieldsCanBeMergedRule = /* @__PURE__ */ __commonJSMin(((e
41372
41965
  }
41373
41966
  add(a, b, weaklyPresent) {
41374
41967
  const map = this._data.get(a);
41375
- if (map === void 0) this._data.set(a, new Map([[b, weaklyPresent]]));
41968
+ if (map === void 0) this._data.set(a, /* @__PURE__ */ new Map([[b, weaklyPresent]]));
41376
41969
  else map.set(b, weaklyPresent);
41377
41970
  }
41378
41971
  };
@@ -61332,7 +61925,7 @@ const HTTP_METHODS = [
61332
61925
  ];
61333
61926
  const DEFAULT_OPENAPI_RESPONSE_MAX_BYTES = 100 * 1024 * 1024;
61334
61927
  const JSON_CONTENT_TYPES = ["application/json"];
61335
- const FORBIDDEN_ARGUMENT_HEADERS = new Set([
61928
+ const FORBIDDEN_ARGUMENT_HEADERS = /* @__PURE__ */ new Set([
61336
61929
  "accept",
61337
61930
  "authorization",
61338
61931
  "connection",
@@ -62987,14 +63580,15 @@ var CapletSetManager = class CapletSetManager {
62987
63580
  ...config.configPath ? { configPath: config.configPath } : {},
62988
63581
  ...config.capletsRoot ? { capletsRoot: config.capletsRoot } : {},
62989
63582
  defaultSearchLimit: config.defaultSearchLimit,
62990
- maxSearchLimit: config.maxSearchLimit
63583
+ maxSearchLimit: config.maxSearchLimit,
63584
+ vaultResolver: vaultResolverForAuthDir(this.options.authDir)
62991
63585
  }));
62992
63586
  const sharedOptions = {
62993
63587
  ...this.options.authDir ? { authDir: this.options.authDir } : {},
62994
63588
  ...this.options.artifactDir ? { artifactDir: this.options.artifactDir } : {},
62995
63589
  ...this.options.exposeLocalArtifactPaths === false ? { exposeLocalArtifactPaths: false } : {}
62996
63590
  };
62997
- const childAncestry = new Set([...ancestry, cacheKey]);
63591
+ const childAncestry = /* @__PURE__ */ new Set([...ancestry, cacheKey]);
62998
63592
  child = {
62999
63593
  registry,
63000
63594
  downstream: new DownstreamManager(registry, sharedOptions),
@@ -63329,8 +63923,9 @@ var CapletsEngine = class {
63329
63923
  configPath: resolveConfigPath(options.configPath),
63330
63924
  projectConfigPath: options.projectConfigPath ?? resolveProjectConfigPath()
63331
63925
  };
63332
- this.configLoader = options.configLoader ?? loadConfig;
63333
- const config = this.configLoader(this.paths.configPath, this.paths.projectConfigPath);
63926
+ this.writeErr = options.writeErr ?? ((value) => process.stderr.write(value));
63927
+ this.configLoader = options.configLoader ?? runtimeConfigLoader(options.authDir, options.vaultRecoveryTarget);
63928
+ const config = this.loadConfigWithWarnings();
63334
63929
  this.registry = new ServerRegistry(config);
63335
63930
  this.downstream = new DownstreamManager(this.registry, selectAuthOptions(options.authDir));
63336
63931
  this.openapi = new OpenApiManager(this.registry, selectHttpLikeOptions(options));
@@ -63341,7 +63936,6 @@ var CapletsEngine = class {
63341
63936
  this.capletSets = new CapletSetManager(this.registry, selectHttpLikeOptions(options));
63342
63937
  this.watchDebounceMs = options.watchDebounceMs ?? 250;
63343
63938
  this.watchEnabled = options.watch ?? true;
63344
- this.writeErr = options.writeErr ?? ((value) => process.stderr.write(value));
63345
63939
  this.observedOutputShapeStore = options.observedOutputShapeStore ?? new FileObservedOutputShapeStore(options.observedOutputShapeCacheDir ?? DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR);
63346
63940
  this.observedOutputShapeScope = options.observedOutputShapeScope ?? "local";
63347
63941
  this.projectFingerprint = options.projectFingerprint ?? safeProjectFingerprint();
@@ -63434,7 +64028,7 @@ var CapletsEngine = class {
63434
64028
  }
63435
64029
  }
63436
64030
  async completeCliWords(words) {
63437
- const { completeCliWords } = await import("./completion-DrPr2vYw.js").then((n) => n.r);
64031
+ const { completeCliWords } = await import("./completion-DaYL-XQN.js").then((n) => n.r);
63438
64032
  return await completeCliWords(words, {
63439
64033
  config: this.registry.config,
63440
64034
  managers: {
@@ -63508,7 +64102,7 @@ var CapletsEngine = class {
63508
64102
  if (this.closed) return false;
63509
64103
  let nextConfig;
63510
64104
  try {
63511
- nextConfig = this.configLoader(this.paths.configPath, this.paths.projectConfigPath);
64105
+ nextConfig = this.loadConfigWithWarnings();
63512
64106
  } catch (error) {
63513
64107
  this.writeErr(`Caplets config reload failed; keeping last known-good config.\n`);
63514
64108
  this.writeErr(`${JSON.stringify(toSafeError(error, "CONFIG_INVALID"), null, 2)}\n`);
@@ -63542,6 +64136,11 @@ var CapletsEngine = class {
63542
64136
  });
63543
64137
  return invalidated;
63544
64138
  }
64139
+ loadConfigWithWarnings() {
64140
+ return this.configLoader(this.paths.configPath, this.paths.projectConfigPath, { writeWarning: (warning) => {
64141
+ this.writeErr(`Warning: ${warning.kind} at ${warning.path}: ${warning.message}\n`);
64142
+ } });
64143
+ }
63545
64144
  async reloadUntilSettled() {
63546
64145
  let succeeded = true;
63547
64146
  do {
@@ -63567,7 +64166,7 @@ var CapletsEngine = class {
63567
64166
  async invalidateChangedBackends(previous, next) {
63568
64167
  const previousCaplets = new Map(allCaplets(previous).map((server) => [server.server, server]));
63569
64168
  const nextCaplets = new Map(allCaplets(next).map((server) => [server.server, server]));
63570
- const changedIds = new Set([...previousCaplets.keys(), ...nextCaplets.keys()]);
64169
+ const changedIds = /* @__PURE__ */ new Set([...previousCaplets.keys(), ...nextCaplets.keys()]);
63571
64170
  for (const serverId of changedIds) {
63572
64171
  const before = previousCaplets.get(serverId);
63573
64172
  const after = nextCaplets.get(serverId);
@@ -63631,6 +64230,14 @@ var CapletsEngine = class {
63631
64230
  }, this.watchDebounceMs);
63632
64231
  }
63633
64232
  };
64233
+ function runtimeConfigLoader(authDir, vaultRecoveryTarget) {
64234
+ const vaultResolver = vaultResolverForAuthDir(authDir);
64235
+ return (configPath, projectConfigPath, options) => loadLocalRuntimeConfig(configPath, projectConfigPath, {
64236
+ ...options,
64237
+ vaultResolver,
64238
+ vaultRecoveryTarget
64239
+ });
64240
+ }
63634
64241
  function selectAuthOptions(authDir) {
63635
64242
  return authDir ? { authDir } : {};
63636
64243
  }
@@ -63970,7 +64577,7 @@ var CodeModeJournalStore = class {
63970
64577
  version: JOURNAL_VERSION,
63971
64578
  journalKey,
63972
64579
  sessionIdHash: this.sessionIdHash(input.sessionId),
63973
- recoveryRefHashes: [...new Set([...existing?.recoveryRefHashes ?? [], recoveryRefHash])],
64580
+ recoveryRefHashes: [.../* @__PURE__ */ new Set([...existing?.recoveryRefHashes ?? [], recoveryRefHash])],
63974
64581
  createdAt: existing?.createdAt ?? now.toISOString(),
63975
64582
  updatedAt: now.toISOString(),
63976
64583
  expiresAt,
@@ -65029,7 +65636,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
65029
65636
  ParseExpressionEmptyInput: "Unexpected parseExpression() input: The input is empty or contains only comments.",
65030
65637
  ParseExpressionExpectsEOF: ({ unexpected }) => `Unexpected parseExpression() input: The input should contain exactly one expression, but the first expression is followed by the unexpected character \`${String.fromCodePoint(unexpected)}\`.`
65031
65638
  };
65032
- const UnparenthesizedPipeBodyDescriptions = new Set([
65639
+ const UnparenthesizedPipeBodyDescriptions = /* @__PURE__ */ new Set([
65033
65640
  "ArrowFunctionExpression",
65034
65641
  "AssignmentExpression",
65035
65642
  "ConditionalExpression",
@@ -66930,7 +67537,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
66930
67537
  function isIteratorStart(current, next, next2) {
66931
67538
  return current === 64 && next === 64 && isIdentifierStart(next2);
66932
67539
  }
66933
- const reservedWordLikeSet = new Set([
67540
+ const reservedWordLikeSet = /* @__PURE__ */ new Set([
66934
67541
  "break",
66935
67542
  "case",
66936
67543
  "catch",
@@ -67136,7 +67743,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
67136
67743
  if (!this.scopeStack[0].declareFunctions.has(id.name)) super.checkLocalExport(id);
67137
67744
  }
67138
67745
  };
67139
- const reservedTypes = new Set([
67746
+ const reservedTypes = /* @__PURE__ */ new Set([
67140
67747
  "_",
67141
67748
  "any",
67142
67749
  "bool",
@@ -70115,7 +70722,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
70115
70722
  return code >= 48 && code <= 57;
70116
70723
  };
70117
70724
  const forbiddenNumericSeparatorSiblings = {
70118
- decBinOct: new Set([
70725
+ decBinOct: /* @__PURE__ */ new Set([
70119
70726
  46,
70120
70727
  66,
70121
70728
  69,
@@ -70125,7 +70732,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
70125
70732
  101,
70126
70733
  111
70127
70734
  ]),
70128
- hex: new Set([
70735
+ hex: /* @__PURE__ */ new Set([
70129
70736
  46,
70130
70737
  88,
70131
70738
  95,
@@ -70333,7 +70940,7 @@ var import_lib = (/* @__PURE__ */ __commonJSMin(((exports) => {
70333
70940
  function buildPosition(pos, lineStart, curLine) {
70334
70941
  return new Position(curLine, pos - lineStart, pos);
70335
70942
  }
70336
- const VALID_REGEX_FLAGS = new Set([
70943
+ const VALID_REGEX_FLAGS = /* @__PURE__ */ new Set([
70337
70944
  103,
70338
70945
  109,
70339
70946
  115,
@@ -77791,10 +78398,10 @@ function resolveTimer(context, deferred, fired) {
77791
78398
  }
77792
78399
  //#endregion
77793
78400
  //#region src/code-mode/platform-runtime.generated.ts
77794
- const CODE_MODE_PLATFORM_RUNTIME_SOURCE = "(function() {\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/deserialize.js\n const env = typeof self === \"object\" ? self : globalThis;\n const guard = (name, init) => {\n switch (name) {\n case \"Function\":\n case \"SharedWorker\":\n case \"Worker\":\n case \"eval\":\n case \"setInterval\":\n case \"setTimeout\": throw new TypeError(\"unable to deserialize \" + name);\n }\n return new env[name](init);\n };\n const deserializer = ($, _) => {\n const as = (out, index) => {\n $.set(index, out);\n return out;\n };\n const unpair = (index) => {\n if ($.has(index)) return $.get(index);\n const [type, value] = _[index];\n switch (type) {\n case 0:\n case -1: return as(value, index);\n case 1: {\n const arr = as([], index);\n for (const index of value) arr.push(unpair(index));\n return arr;\n }\n case 2: {\n const object = as({}, index);\n for (const [key, index] of value) object[unpair(key)] = unpair(index);\n return object;\n }\n case 3: return as(new Date(value), index);\n case 4: {\n const { source, flags } = value;\n return as(new RegExp(source, flags), index);\n }\n case 5: {\n const map = as(/* @__PURE__ */ new Map(), index);\n for (const [key, index] of value) map.set(unpair(key), unpair(index));\n return map;\n }\n case 6: {\n const set = as(/* @__PURE__ */ new Set(), index);\n for (const index of value) set.add(unpair(index));\n return set;\n }\n case 7: {\n const { name, message } = value;\n return as(guard(name, message), index);\n }\n case 8: return as(BigInt(value), index);\n case \"BigInt\": return as(Object(BigInt(value)), index);\n case \"ArrayBuffer\": return as(new Uint8Array(value).buffer, value);\n case \"DataView\": {\n const { buffer } = new Uint8Array(value);\n return as(new DataView(buffer), value);\n }\n }\n return as(guard(type, value), index);\n };\n return unpair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns a deserialized value from a serialized array of Records.\n * @param {Record[]} serialized a previously serialized value.\n * @returns {any}\n */\n const deserialize = (serialized) => deserializer(/* @__PURE__ */ new Map(), serialized)(0);\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/serialize.js\n const EMPTY = \"\";\n const { toString } = {};\n const { keys } = Object;\n const typeOf = (value) => {\n const type = typeof value;\n if (type !== \"object\" || !value) return [0, type];\n const asString = toString.call(value).slice(8, -1);\n switch (asString) {\n case \"Array\": return [1, EMPTY];\n case \"Object\": return [2, EMPTY];\n case \"Date\": return [3, EMPTY];\n case \"RegExp\": return [4, EMPTY];\n case \"Map\": return [5, EMPTY];\n case \"Set\": return [6, EMPTY];\n case \"DataView\": return [1, asString];\n }\n if (asString.includes(\"Array\")) return [1, asString];\n if (asString.includes(\"Error\")) return [7, asString];\n return [2, asString];\n };\n const shouldSkip = ([TYPE, type]) => TYPE === 0 && (type === \"function\" || type === \"symbol\");\n const serializer = (strict, json, $, _) => {\n const as = (out, value) => {\n const index = _.push(out) - 1;\n $.set(value, index);\n return index;\n };\n const pair = (value) => {\n if ($.has(value)) return $.get(value);\n let [TYPE, type] = typeOf(value);\n switch (TYPE) {\n case 0: {\n let entry = value;\n switch (type) {\n case \"bigint\":\n TYPE = 8;\n entry = value.toString();\n break;\n case \"function\":\n case \"symbol\":\n if (strict) throw new TypeError(\"unable to serialize \" + type);\n entry = null;\n break;\n case \"undefined\": return as([-1], value);\n }\n return as([TYPE, entry], value);\n }\n case 1: {\n if (type) {\n let spread = value;\n if (type === \"DataView\") spread = new Uint8Array(value.buffer);\n else if (type === \"ArrayBuffer\") spread = new Uint8Array(value);\n return as([type, [...spread]], value);\n }\n const arr = [];\n const index = as([TYPE, arr], value);\n for (const entry of value) arr.push(pair(entry));\n return index;\n }\n case 2: {\n if (type) switch (type) {\n case \"BigInt\": return as([type, value.toString()], value);\n case \"Boolean\":\n case \"Number\":\n case \"String\": return as([type, value.valueOf()], value);\n }\n if (json && \"toJSON\" in value) return pair(value.toJSON());\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const key of keys(value)) if (strict || !shouldSkip(typeOf(value[key]))) entries.push([pair(key), pair(value[key])]);\n return index;\n }\n case 3: return as([TYPE, value.toISOString()], value);\n case 4: {\n const { source, flags } = value;\n return as([TYPE, {\n source,\n flags\n }], value);\n }\n case 5: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const [key, entry] of value) if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry)))) entries.push([pair(key), pair(entry)]);\n return index;\n }\n case 6: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const entry of value) if (strict || !shouldSkip(typeOf(entry))) entries.push(pair(entry));\n return index;\n }\n }\n const { message } = value;\n return as([TYPE, {\n name: type,\n message\n }], value);\n };\n return pair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} value a serializable value.\n * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,\n * if `true`, will not throw errors on incompatible types, and behave more\n * like JSON stringify would behave. Symbol and Function will be discarded.\n * @returns {Record[]}\n */\n const serialize = (value, { json, lossy } = {}) => {\n const _ = [];\n return serializer(!(json || lossy), !!json, /* @__PURE__ */ new Map(), _)(value), _;\n };\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/index.js\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} any a serializable value.\n * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with\n * a transfer option (ignored when polyfilled) and/or non standard fields that\n * fallback to the polyfill if present.\n * @returns {Record[]}\n */\n var esm_default = typeof structuredClone === \"function\" ? (any, options) => options && (\"json\" in options || \"lossy\" in options) ? deserialize(serialize(any, options)) : structuredClone(any) : (any, options) => deserialize(serialize(any, options));\n //#endregion\n //#region node_modules/.pnpm/formdata-node@6.0.3/node_modules/formdata-node/lib/form-data.js\n var __accessCheck = (obj, member, msg) => {\n if (!member.has(obj)) throw TypeError(\"Cannot \" + msg);\n };\n var __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n };\n var __privateAdd = (obj, member, value) => {\n if (member.has(obj)) throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n };\n var __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n };\n var __privateMethod = (obj, member, method) => {\n __accessCheck(obj, member, \"access private method\");\n return method;\n };\n var isFunction = (value) => typeof value === \"function\";\n var isObject = (value) => typeof value === \"object\" && value != null && !Array.isArray(value);\n var isAsyncIterable = (value) => isObject(value) && isFunction(value[Symbol.asyncIterator]);\n var MAX_CHUNK_SIZE = 65536;\n async function* clonePart(value) {\n if (value.byteLength <= MAX_CHUNK_SIZE) {\n yield value;\n return;\n }\n let offset = 0;\n while (offset < value.byteLength) {\n const size = Math.min(value.byteLength - offset, MAX_CHUNK_SIZE);\n const buffer = value.buffer.slice(offset, offset + size);\n offset += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* readStream(readable) {\n const reader = readable.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n }\n }\n async function* chunkStream(stream) {\n for await (const value of stream) yield* clonePart(value);\n }\n var getStreamIterator = (source) => {\n if (isAsyncIterable(source)) return chunkStream(source);\n if (isFunction(source.getReader)) return chunkStream(readStream(source));\n throw new TypeError(\"Unsupported data source: Expected either ReadableStream or async iterable.\");\n };\n async function* consumeNodeBlob(blob) {\n let position = 0;\n while (position !== blob.size) {\n const buffer = await blob.slice(position, Math.min(blob.size, position + MAX_CHUNK_SIZE)).arrayBuffer();\n position += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* consumeBlobParts(parts, clone = false) {\n for (const part of parts) if (ArrayBuffer.isView(part)) if (clone) yield* clonePart(part);\n else yield part;\n else if (isFunction(part.stream)) yield* getStreamIterator(part.stream());\n else yield* consumeNodeBlob(part);\n }\n function* sliceBlob(blobParts, blobSize, start = 0, end) {\n end ??= blobSize;\n let relativeStart = start < 0 ? Math.max(blobSize + start, 0) : Math.min(start, blobSize);\n let relativeEnd = end < 0 ? Math.max(blobSize + end, 0) : Math.min(end, blobSize);\n const span = Math.max(relativeEnd - relativeStart, 0);\n let added = 0;\n for (const part of blobParts) {\n if (added >= span) break;\n const partSize = ArrayBuffer.isView(part) ? part.byteLength : part.size;\n if (relativeStart && partSize <= relativeStart) {\n relativeStart -= partSize;\n relativeEnd -= partSize;\n } else {\n let chunk;\n if (ArrayBuffer.isView(part)) {\n chunk = part.subarray(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.byteLength;\n } else {\n chunk = part.slice(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.size;\n }\n relativeEnd -= partSize;\n relativeStart = 0;\n yield chunk;\n }\n }\n }\n var _parts, _type, _size;\n var _Blob = class _Blob {\n /**\n * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.\n * The content of the blob consists of the concatenation of the values given in the parameter array.\n *\n * @param blobParts An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n * @param options An optional object of type `BlobPropertyBag`.\n */\n constructor(blobParts = [], options = {}) {\n /**\n * An `Array` of [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) or [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n __privateAdd(this, _parts, []);\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n __privateAdd(this, _type, \"\");\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n __privateAdd(this, _size, 0);\n options ??= {};\n if (typeof blobParts !== \"object\" || blobParts === null) throw new TypeError(\"Failed to construct 'Blob': The provided value cannot be converted to a sequence.\");\n if (!isFunction(blobParts[Symbol.iterator])) throw new TypeError(\"Failed to construct 'Blob': The object must have a callable @@iterator property.\");\n if (typeof options !== \"object\" && !isFunction(options)) throw new TypeError(\"Failed to construct 'Blob': parameter 2 cannot convert to dictionary.\");\n const encoder = new TextEncoder();\n for (const raw of blobParts) {\n let part;\n if (ArrayBuffer.isView(raw)) part = new Uint8Array(raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength));\n else if (raw instanceof ArrayBuffer) part = new Uint8Array(raw.slice(0));\n else if (raw instanceof _Blob) part = raw;\n else part = encoder.encode(String(raw));\n __privateSet(this, _size, __privateGet(this, _size) + (ArrayBuffer.isView(part) ? part.byteLength : part.size));\n __privateGet(this, _parts).push(part);\n }\n const type = options.type === void 0 ? \"\" : String(options.type);\n __privateSet(this, _type, /^[\\x20-\\x7E]*$/.test(type) ? type : \"\");\n }\n static [Symbol.hasInstance](value) {\n return Boolean(value && typeof value === \"object\" && isFunction(value.constructor) && (isFunction(value.stream) || isFunction(value.arrayBuffer)) && /^(Blob|File)$/.test(value[Symbol.toStringTag]));\n }\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n get type() {\n return __privateGet(this, _type);\n }\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n get size() {\n return __privateGet(this, _size);\n }\n /**\n * Creates and returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which contains data from a subset of the blob on which it's called.\n *\n * @param start An index into the Blob indicating the first byte to include in the new Blob. If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is 0. If you specify a value for start that is larger than the size of the source Blob, the returned Blob has size 0 and contains no data.\n * @param end An index into the Blob indicating the first byte that will *not* be included in the new Blob (i.e. the byte exactly at this index is not included). If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is size.\n * @param contentType The content type to assign to the new Blob; this will be the value of its type property. The default value is an empty string.\n */\n slice(start, end, contentType) {\n return new _Blob(sliceBlob(__privateGet(this, _parts), this.size, start, end), { type: contentType });\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with a string containing the contents of the blob, interpreted as UTF-8.\n */\n async text() {\n const decoder = new TextDecoder();\n let result = \"\";\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) result += decoder.decode(chunk, { stream: true });\n result += decoder.decode();\n return result;\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the contents of the blob as binary data contained in an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).\n */\n async arrayBuffer() {\n const view = new Uint8Array(this.size);\n let offset = 0;\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) {\n view.set(chunk, offset);\n offset += chunk.length;\n }\n return view.buffer;\n }\n /**\n * Returns a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) which upon reading returns the data contained within the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n stream() {\n const iterator = consumeBlobParts(__privateGet(this, _parts), true);\n return new ReadableStream({\n async pull(controller) {\n const { value, done } = await iterator.next();\n if (done) return queueMicrotask(() => controller.close());\n controller.enqueue(value);\n },\n async cancel() {\n await iterator.return();\n }\n });\n }\n get [Symbol.toStringTag]() {\n return \"Blob\";\n }\n };\n _parts = /* @__PURE__ */ new WeakMap();\n _type = /* @__PURE__ */ new WeakMap();\n _size = /* @__PURE__ */ new WeakMap();\n var Blob = _Blob;\n Object.defineProperties(Blob.prototype, {\n type: { enumerable: true },\n size: { enumerable: true },\n slice: { enumerable: true },\n stream: { enumerable: true },\n text: { enumerable: true },\n arrayBuffer: { enumerable: true }\n });\n var isBlob = (value) => value instanceof Blob;\n var _name, _lastModified;\n var File = class extends Blob {\n /**\n * Creates a new File instance.\n *\n * @param fileBits An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n * @param name The name of the file.\n * @param options An options object containing optional attributes for the file.\n */\n constructor(fileBits, name, options = {}) {\n super(fileBits, options);\n /**\n * Returns the name of the file referenced by the File object.\n */\n __privateAdd(this, _name, void 0);\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n __privateAdd(this, _lastModified, 0);\n if (arguments.length < 2) throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`);\n __privateSet(this, _name, String(name));\n const lastModified = options.lastModified === void 0 ? Date.now() : Number(options.lastModified);\n if (!Number.isNaN(lastModified)) __privateSet(this, _lastModified, lastModified);\n }\n static [Symbol.hasInstance](value) {\n return value instanceof Blob && value[Symbol.toStringTag] === \"File\" && typeof value.name === \"string\";\n }\n /**\n * Name of the file referenced by the File object.\n */\n get name() {\n return __privateGet(this, _name);\n }\n /* c8 ignore next 3 */\n get webkitRelativePath() {\n return \"\";\n }\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n get lastModified() {\n return __privateGet(this, _lastModified);\n }\n get [Symbol.toStringTag]() {\n return \"File\";\n }\n };\n _name = /* @__PURE__ */ new WeakMap();\n _lastModified = /* @__PURE__ */ new WeakMap();\n var isFile = (value) => value instanceof File;\n var _entries, _setEntry, setEntry_fn;\n var FormData = class {\n constructor() {\n __privateAdd(this, _setEntry);\n /**\n * Stores internal data for every entry\n */\n __privateAdd(this, _entries, /* @__PURE__ */ new Map());\n }\n static [Symbol.hasInstance](value) {\n if (!value) return false;\n const val = value;\n return Boolean(isFunction(val.constructor) && val[Symbol.toStringTag] === \"FormData\" && isFunction(val.append) && isFunction(val.set) && isFunction(val.get) && isFunction(val.getAll) && isFunction(val.has) && isFunction(val.delete) && isFunction(val.entries) && isFunction(val.values) && isFunction(val.keys) && isFunction(val[Symbol.iterator]) && isFunction(val.forEach));\n }\n /**\n * Appends a new value onto an existing key inside a FormData object,\n * or adds the key if it does not already exist.\n *\n * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n */\n append(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: true,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Set a new value for an existing key inside FormData,\n * or add the new field if it does not already exist.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n *\n */\n set(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: false,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Returns the first value associated with a given key from within a `FormData` object.\n * If you expect multiple values and want all of them, use the `getAll()` method instead.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.\n */\n get(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return null;\n return field[0];\n }\n /**\n * Returns all the values associated with a given key from within a `FormData` object.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.\n */\n getAll(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return [];\n return field.slice();\n }\n /**\n * Returns a boolean stating whether a `FormData` object contains a certain key.\n *\n * @param name A string representing the name of the key you want to test for.\n *\n * @return A boolean value.\n */\n has(name) {\n return __privateGet(this, _entries).has(String(name));\n }\n /**\n * Deletes a key and its value(s) from a `FormData` object.\n *\n * @param name The name of the key you want to delete.\n */\n delete(name) {\n __privateGet(this, _entries).delete(String(name));\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.\n * Each key is a `string`.\n */\n *keys() {\n for (const key of __privateGet(this, _entries).keys()) yield key;\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.\n * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *entries() {\n for (const name of this.keys()) {\n const values = this.getAll(name);\n for (const value of values) yield [name, value];\n }\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.\n * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *values() {\n for (const [, value] of this) yield value;\n }\n /**\n * An alias for FormData#entries()\n */\n [Symbol.iterator]() {\n return this.entries();\n }\n /**\n * Executes given callback function for each field of the FormData instance\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this) callback.call(thisArg, value, name, this);\n }\n get [Symbol.toStringTag]() {\n return \"FormData\";\n }\n };\n _entries = /* @__PURE__ */ new WeakMap();\n _setEntry = /* @__PURE__ */ new WeakSet();\n setEntry_fn = function({ name, rawValue, append, fileName, argsLength }) {\n const methodName = append ? \"append\" : \"set\";\n if (argsLength < 2) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': 2 arguments required, but only ${argsLength} present.`);\n name = String(name);\n let value;\n if (isFile(rawValue)) value = fileName === void 0 ? rawValue : new File([rawValue], fileName, {\n type: rawValue.type,\n lastModified: rawValue.lastModified\n });\n else if (isBlob(rawValue)) value = new File([rawValue], fileName === void 0 ? \"blob\" : fileName, { type: rawValue.type });\n else if (fileName) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': parameter 2 is not of type 'Blob'.`);\n else value = String(rawValue);\n const values = __privateGet(this, _entries).get(name);\n if (!values) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n if (!append) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n values.push(value);\n };\n /*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */\n //#endregion\n //#region node_modules/.pnpm/set-cookie-parser@3.1.0/node_modules/set-cookie-parser/lib/set-cookie.js\n var defaultParseOptions = {\n decodeValues: true,\n map: false,\n silent: false,\n split: \"auto\"\n };\n function isForbiddenKey(key) {\n return typeof key !== \"string\" || key in {};\n }\n function createNullObj() {\n return Object.create(null);\n }\n function isNonEmptyString(str) {\n return typeof str === \"string\" && !!str.trim();\n }\n function parseString(setCookieValue, options) {\n var parts = setCookieValue.split(\";\").filter(isNonEmptyString);\n var parsed = parseNameValuePair(parts.shift());\n var name = parsed.name;\n var value = parsed.value;\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (isForbiddenKey(name)) return null;\n try {\n value = options.decodeValues ? decodeURIComponent(value) : value;\n } catch (e) {\n console.error(\"set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.\", e);\n }\n var cookie = createNullObj();\n cookie.name = name;\n cookie.value = value;\n parts.forEach(function(part) {\n var sides = part.split(\"=\");\n var key = sides.shift().trimLeft().toLowerCase();\n if (isForbiddenKey(key)) return;\n var value = sides.join(\"=\");\n if (key === \"expires\") cookie.expires = new Date(value);\n else if (key === \"max-age\") {\n var n = parseInt(value, 10);\n if (!Number.isNaN(n)) cookie.maxAge = n;\n } else if (key === \"secure\") cookie.secure = true;\n else if (key === \"httponly\") cookie.httpOnly = true;\n else if (key === \"samesite\") cookie.sameSite = value;\n else if (key === \"partitioned\") cookie.partitioned = true;\n else if (key) cookie[key] = value;\n });\n return cookie;\n }\n function parseNameValuePair(nameValuePairStr) {\n var name = \"\";\n var value = \"\";\n var nameValueArr = nameValuePairStr.split(\"=\");\n if (nameValueArr.length > 1) {\n name = nameValueArr.shift();\n value = nameValueArr.join(\"=\");\n } else value = nameValuePairStr;\n return {\n name,\n value\n };\n }\n function parseSetCookie(input, options) {\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (!input) if (!options.map) return [];\n else return createNullObj();\n if (input.headers) if (typeof input.headers.getSetCookie === \"function\") input = input.headers.getSetCookie();\n else if (input.headers[\"set-cookie\"]) input = input.headers[\"set-cookie\"];\n else {\n var sch = input.headers[Object.keys(input.headers).find(function(key) {\n return key.toLowerCase() === \"set-cookie\";\n })];\n if (!sch && input.headers.cookie && !options.silent) console.warn(\"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning.\");\n input = sch;\n }\n var split = options.split;\n var isArray = Array.isArray(input);\n if (split === \"auto\") split = !isArray;\n if (!isArray) input = [input];\n input = input.filter(isNonEmptyString);\n if (split) input = input.map(splitCookiesString).flat();\n if (!options.map) return input.map(function(str) {\n return parseString(str, options);\n }).filter(Boolean);\n else {\n var cookies = createNullObj();\n return input.reduce(function(cookies, str) {\n var cookie = parseString(str, options);\n if (cookie && !isForbiddenKey(cookie.name)) cookies[cookie.name] = cookie;\n return cookies;\n }, cookies);\n }\n }\n function splitCookiesString(cookiesString) {\n if (Array.isArray(cookiesString)) return cookiesString;\n if (typeof cookiesString !== \"string\") return [];\n var cookiesStrings = [];\n var pos = 0;\n var start;\n var ch;\n var lastComma;\n var nextStart;\n var cookiesSeparatorFound;\n function skipWhitespace() {\n while (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n return pos < cookiesString.length;\n }\n function notSpecialChar() {\n ch = cookiesString.charAt(pos);\n return ch !== \"=\" && ch !== \";\" && ch !== \",\";\n }\n while (pos < cookiesString.length) {\n start = pos;\n cookiesSeparatorFound = false;\n while (skipWhitespace()) {\n ch = cookiesString.charAt(pos);\n if (ch === \",\") {\n lastComma = pos;\n pos += 1;\n skipWhitespace();\n nextStart = pos;\n while (pos < cookiesString.length && notSpecialChar()) pos += 1;\n if (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n cookiesSeparatorFound = true;\n pos = nextStart;\n cookiesStrings.push(cookiesString.substring(start, lastComma));\n start = pos;\n } else pos = lastComma + 1;\n } else pos += 1;\n }\n if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length));\n }\n return cookiesStrings;\n }\n parseSetCookie.parseSetCookie = parseSetCookie;\n parseSetCookie.parse = parseSetCookie;\n parseSetCookie.parseString = parseString;\n parseSetCookie.splitCookiesString = splitCookiesString;\n //#endregion\n //#region node_modules/.pnpm/headers-polyfill@5.0.1/node_modules/headers-polyfill/lib/index.mjs\n const HEADERS_INVALID_CHARACTERS = /[^a-z0-9\\-#$%&'*+.^_`|~]/i;\n function normalizeHeaderName(name) {\n if (HEADERS_INVALID_CHARACTERS.test(name) || name.trim() === \"\") throw new TypeError(\"Invalid character in header field name\");\n return name.trim().toLowerCase();\n }\n const charCodesToRemove = [\n String.fromCharCode(10),\n String.fromCharCode(13),\n String.fromCharCode(9),\n String.fromCharCode(32)\n ];\n const HEADER_VALUE_REMOVE_REGEXP = new RegExp(`(^[${charCodesToRemove.join(\"\")}]|$[${charCodesToRemove.join(\"\")}])`, \"g\");\n /**\n * Normalize the given header value.\n * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize\n */\n function normalizeHeaderValue(value) {\n return value.replace(HEADER_VALUE_REMOVE_REGEXP, \"\");\n }\n /**\n * Validate the given header name.\n * @see https://fetch.spec.whatwg.org/#header-name\n */\n function isValidHeaderName(value) {\n if (typeof value !== \"string\") return false;\n if (value.length === 0) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character > 127 || !isToken(character)) return false;\n }\n return true;\n }\n function isToken(value) {\n return ![\n 127,\n 32,\n \"(\",\n \")\",\n \"<\",\n \">\",\n \"@\",\n \",\",\n \";\",\n \":\",\n \"\\\\\",\n \"\\\"\",\n \"/\",\n \"[\",\n \"]\",\n \"?\",\n \"=\",\n \"{\",\n \"}\"\n ].includes(value);\n }\n /**\n * Validate the given header value.\n * @see https://fetch.spec.whatwg.org/#header-value\n */\n function isValidHeaderValue(value) {\n if (typeof value !== \"string\") return false;\n if (value.trim() !== value) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character === 0 || character === 10 || character === 13) return false;\n }\n return true;\n }\n let _Symbol$toStringTag;\n const NORMALIZED_HEADERS = Symbol(\"normalizedHeaders\");\n const RAW_HEADER_NAMES = Symbol(\"rawHeaderNames\");\n const HEADER_VALUE_DELIMITER = \", \";\n var Headers = class Headers {\n constructor(init) {\n this[NORMALIZED_HEADERS] = {};\n this[RAW_HEADER_NAMES] = /* @__PURE__ */ new Map();\n this[_Symbol$toStringTag] = \"Headers\";\n /**\n * @note Cannot necessarily check if the `init` is an instance of the\n * `Headers` because that class may not be defined in Node or jsdom.\n */\n if ([\"Headers\", \"HeadersPolyfill\"].includes(init?.constructor?.name) || init instanceof Headers || typeof globalThis.Headers !== \"undefined\" && init instanceof globalThis.Headers) init.forEach((value, name) => {\n this.append(name, value);\n }, this);\n else if (Array.isArray(init)) init.forEach(([name, value]) => {\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n else if (init) Object.getOwnPropertyNames(init).forEach((name) => {\n const value = init[name];\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n }\n [(_Symbol$toStringTag = Symbol.toStringTag, Symbol.iterator)]() {\n return this.entries();\n }\n *keys() {\n for (const [name] of this.entries()) yield name;\n }\n *values() {\n for (const [, value] of this.entries()) yield value;\n }\n *entries() {\n let sortedKeys = Object.keys(this[NORMALIZED_HEADERS]).sort((a, b) => a.localeCompare(b));\n for (const name of sortedKeys) if (name === \"set-cookie\") for (const value of this.getSetCookie()) yield [name, value];\n else yield [name, this.get(name)];\n }\n /**\n * Returns a boolean stating whether a `Headers` object contains a certain header.\n */\n has(name) {\n if (!isValidHeaderName(name)) throw new TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS].hasOwnProperty(normalizeHeaderName(name));\n }\n /**\n * Returns a `ByteString` sequence of all the values of a header with a given name.\n */\n get(name) {\n if (!isValidHeaderName(name)) throw TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS][normalizeHeaderName(name)] ?? null;\n }\n /**\n * Sets a new value for an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n set(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n this[NORMALIZED_HEADERS][normalizedName] = normalizeHeaderValue(normalizedValue);\n this[RAW_HEADER_NAMES].set(normalizedName, name);\n }\n /**\n * Appends a new value onto an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n append(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n let resolvedValue = this.has(normalizedName) ? `${this.get(normalizedName)}, ${normalizedValue}` : normalizedValue;\n this.set(name, resolvedValue);\n }\n /**\n * Deletes a header from the `Headers` object.\n */\n delete(name) {\n if (!isValidHeaderName(name)) return;\n if (!this.has(name)) return;\n const normalizedName = normalizeHeaderName(name);\n delete this[NORMALIZED_HEADERS][normalizedName];\n this[RAW_HEADER_NAMES].delete(normalizedName);\n }\n /**\n * Traverses the `Headers` object,\n * calling the given callback for each header.\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this);\n }\n /**\n * Returns an array containing the values\n * of all Set-Cookie headers associated\n * with a response\n */\n getSetCookie() {\n const setCookieHeader = this.get(\"set-cookie\");\n if (setCookieHeader === null) return [];\n if (setCookieHeader === \"\") return [\"\"];\n return splitCookiesString(setCookieHeader);\n }\n };\n //#endregion\n //#region packages/core/src/code-mode/platform-entry.ts\n const platformBridgeGlobalThis = globalThis;\n const capletsPlatformHost = {\n randomUUID: platformBridgeGlobalThis.__caplets_platform_random_uuid,\n randomValues: platformBridgeGlobalThis.__caplets_platform_random_values,\n sleep: platformBridgeGlobalThis.__caplets_platform_sleep,\n clearTimer: platformBridgeGlobalThis.__caplets_platform_clear_timer\n };\n delete platformBridgeGlobalThis.__caplets_platform_random_uuid;\n delete platformBridgeGlobalThis.__caplets_platform_random_values;\n delete platformBridgeGlobalThis.__caplets_platform_sleep;\n delete platformBridgeGlobalThis.__caplets_platform_clear_timer;\n const DISABLED_FETCH_MESSAGE = \"Direct fetch is not available in Code Mode; use a Caplet instead.\";\n const BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n const base64Lookup = new Map(BASE64_ALPHABET.split(\"\").map((char, index) => [char, index]));\n function utf8Encode(input) {\n const encoded = encodeURIComponent(input);\n const bytes = [];\n for (let index = 0; index < encoded.length; index += 1) {\n if (encoded[index] === \"%\") {\n bytes.push(Number.parseInt(encoded.slice(index + 1, index + 3), 16));\n index += 2;\n continue;\n }\n bytes.push(encoded.charCodeAt(index));\n }\n return Uint8Array.from(bytes);\n }\n function utf8Decode(input) {\n let output = \"\";\n for (let index = 0; index < input.length; index += 1) {\n const first = input[index] ?? 0;\n if (first < 128) {\n output += String.fromCharCode(first);\n continue;\n }\n if (first >= 194 && first <= 223) {\n const second = input[index + 1];\n if (isUtf8Continuation(second)) {\n output += String.fromCodePoint((first & 31) << 6 | second & 63);\n index += 1;\n continue;\n }\n output += \"�\";\n continue;\n }\n if (first >= 224 && first <= 239) {\n const second = input[index + 1];\n const third = input[index + 2];\n if (isValidUtf8SecondForThreeByte(first, second) && isUtf8Continuation(third)) {\n output += String.fromCodePoint((first & 15) << 12 | (second & 63) << 6 | third & 63);\n index += 2;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForThreeByte(first, second)) index += 1;\n continue;\n }\n if (first >= 240 && first <= 244) {\n const second = input[index + 1];\n const third = input[index + 2];\n const fourth = input[index + 3];\n if (isValidUtf8SecondForFourByte(first, second) && isUtf8Continuation(third) && isUtf8Continuation(fourth)) {\n output += String.fromCodePoint((first & 7) << 18 | (second & 63) << 12 | (third & 63) << 6 | fourth & 63);\n index += 3;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForFourByte(first, second)) index += isUtf8Continuation(third) ? 2 : 1;\n continue;\n }\n output += \"�\";\n }\n return output;\n }\n function isUtf8Continuation(value) {\n return value !== void 0 && value >= 128 && value <= 191;\n }\n function isValidUtf8SecondForThreeByte(first, second) {\n if (second === void 0) return false;\n if (first === 224) return second >= 160 && second <= 191;\n if (first === 237) return second >= 128 && second <= 159;\n return second >= 128 && second <= 191;\n }\n function isValidUtf8SecondForFourByte(first, second) {\n if (second === void 0) return false;\n if (first === 240) return second >= 144 && second <= 191;\n if (first === 244) return second >= 128 && second <= 143;\n return second >= 128 && second <= 191;\n }\n var TextEncoderShim = class {\n encoding = \"utf-8\";\n encode(input = \"\") {\n return utf8Encode(String(input));\n }\n };\n var TextDecoderShim = class {\n encoding;\n constructor(label = \"utf-8\") {\n const normalized = label.toLowerCase();\n if (![\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\"\n ].includes(normalized)) throw new TypeError(`Unsupported encoding: ${label}`);\n this.encoding = \"utf-8\";\n }\n decode(input) {\n if (input === void 0) return \"\";\n return utf8Decode(copyBytes(input));\n }\n };\n const textEncoder = new TextEncoderShim();\n const textDecoder = new TextDecoderShim();\n var URLSearchParamsShim = class URLSearchParamsShim {\n #entries = [];\n #onChange;\n constructor(init = \"\", onChange) {\n this.#onChange = onChange;\n if (typeof init === \"string\") {\n const source = init.startsWith(\"?\") ? init.slice(1) : init;\n if (!source) return;\n for (const pair of source.split(\"&\")) {\n if (!pair) continue;\n const separatorIndex = pair.indexOf(\"=\");\n const key = separatorIndex >= 0 ? pair.slice(0, separatorIndex) : pair;\n const value = separatorIndex >= 0 ? pair.slice(separatorIndex + 1) : \"\";\n this.#entries.push([decodeUrlParam(key), decodeUrlParam(value)]);\n }\n return;\n }\n if (init instanceof URLSearchParamsShim) {\n this.#entries = [...init.#entries];\n return;\n }\n if (Array.isArray(init)) {\n this.#entries = init.map(([key, value]) => [String(key), String(value)]);\n return;\n }\n this.#entries = Object.entries(init).map(([key, value]) => [key, String(value)]);\n }\n append(name, value) {\n this.#entries.push([String(name), String(value)]);\n this.#onChange?.();\n }\n delete(name) {\n const normalized = String(name);\n this.#entries = this.#entries.filter(([key]) => key !== normalized);\n this.#onChange?.();\n }\n entries() {\n return this.#entries[Symbol.iterator]();\n }\n forEach(callback) {\n for (const [key, value] of this.#entries) callback(value, key, this);\n }\n get(name) {\n return this.#entries.find(([key]) => key === String(name))?.[1] ?? null;\n }\n getAll(name) {\n return this.#entries.filter(([key]) => key === String(name)).map(([, value]) => value);\n }\n has(name) {\n return this.#entries.some(([key]) => key === String(name));\n }\n keys() {\n return this.#entries.map(([key]) => key)[Symbol.iterator]();\n }\n set(name, value) {\n const normalizedName = String(name);\n const normalizedValue = String(value);\n const next = [];\n let replaced = false;\n for (const entry of this.#entries) {\n if (entry[0] !== normalizedName) {\n next.push(entry);\n continue;\n }\n if (!replaced) {\n next.push([normalizedName, normalizedValue]);\n replaced = true;\n }\n }\n if (!replaced) next.push([normalizedName, normalizedValue]);\n this.#entries = next;\n this.#onChange?.();\n }\n toString() {\n return this.#entries.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n }\n values() {\n return this.#entries.map(([, value]) => value)[Symbol.iterator]();\n }\n [Symbol.iterator]() {\n return this.entries();\n }\n };\n function decodeUrlParam(value) {\n return decodeURIComponent(value.replace(/\\+/gu, \" \"));\n }\n function parseAbsoluteUrl(input) {\n const match = /^(?<protocol>[a-zA-Z][a-zA-Z\\d+.-]*:)\\/\\/(?<host>[^/?#]*)(?<pathname>[^?#]*)?(?<search>\\?[^#]*)?(?<hash>#.*)?$/u.exec(input);\n if (!match?.groups?.protocol || !match.groups.host) return;\n return {\n protocol: match.groups.protocol,\n host: match.groups.host,\n pathname: match.groups.pathname || \"/\",\n search: match.groups.search || \"\",\n hash: match.groups.hash || \"\"\n };\n }\n function normalizePathname(pathname) {\n const segments = [];\n for (const part of pathname.split(\"/\")) {\n if (!part || part === \".\") continue;\n if (part === \"..\") {\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return `/${segments.join(\"/\")}`;\n }\n function resolveUrl(input, base) {\n const absolute = parseAbsoluteUrl(input);\n if (absolute) return absolute;\n if (base === void 0) throw new TypeError(`Invalid URL: ${input}`);\n const baseUrl = base instanceof URLShim ? base : new URLShim(String(base));\n const basePath = baseUrl.pathname.endsWith(\"/\") ? baseUrl.pathname : baseUrl.pathname.slice(0, baseUrl.pathname.lastIndexOf(\"/\") + 1);\n const [beforeHash, rawHash = \"\"] = input.split(\"#\");\n const hasExplicitSearch = beforeHash?.includes(\"?\") ?? false;\n const [rawPath, rawSearch = \"\"] = (beforeHash ?? \"\").split(\"?\");\n const pathname = rawPath === \"\" && (input === \"\" || input.startsWith(\"?\") || input.startsWith(\"#\")) ? baseUrl.pathname : rawPath?.startsWith(\"/\") ? rawPath : `${basePath}${rawPath || \"\"}`;\n return {\n protocol: baseUrl.protocol,\n host: baseUrl.host,\n pathname: normalizePathname(pathname),\n search: hasExplicitSearch ? `?${rawSearch}` : rawPath === \"\" && (input === \"\" || input.startsWith(\"#\")) ? baseUrl.search : \"\",\n hash: rawHash ? `#${rawHash}` : \"\"\n };\n }\n var URLShim = class {\n host;\n hostname;\n origin;\n password = \"\";\n port;\n protocol;\n searchParams;\n username = \"\";\n hash;\n pathname;\n #search;\n constructor(input, base) {\n const parsed = resolveUrl(String(input), base);\n this.protocol = parsed.protocol;\n this.host = parsed.host;\n const portIndex = this.host.lastIndexOf(\":\");\n this.hostname = portIndex >= 0 ? this.host.slice(0, portIndex) : this.host;\n this.port = portIndex >= 0 ? this.host.slice(portIndex + 1) : \"\";\n this.pathname = parsed.pathname;\n this.#search = parsed.search;\n this.hash = parsed.hash;\n this.origin = `${this.protocol}//${this.host}`;\n this.searchParams = new URLSearchParamsShim(this.#search, () => {\n const next = this.searchParams.toString();\n this.#search = next ? `?${next}` : \"\";\n });\n }\n get href() {\n return `${this.origin}${this.pathname}${this.#search}${this.hash}`;\n }\n get search() {\n return this.#search;\n }\n toString() {\n return this.href;\n }\n toJSON() {\n return this.href;\n }\n };\n var ReadableStreamShim = class {\n #queue = [];\n #closed = false;\n #pulling = false;\n #source;\n #controller;\n #pending;\n constructor(source = {}) {\n this.#source = source;\n this.#controller = {\n enqueue: (value) => {\n if (this.#pending) {\n this.#pending.resolve({\n done: false,\n value\n });\n this.#pending = void 0;\n return;\n }\n this.#queue.push(value);\n },\n close: () => {\n this.#closed = true;\n if (this.#pending) {\n this.#pending.resolve({ done: true });\n this.#pending = void 0;\n }\n }\n };\n source.start?.(this.#controller);\n }\n async #pull() {\n if (this.#pulling || this.#closed || !this.#source.pull) return;\n this.#pulling = true;\n try {\n await this.#source.pull(this.#controller);\n } finally {\n this.#pulling = false;\n }\n }\n getReader() {\n return { read: async () => {\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n await this.#pull();\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n if (this.#closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n this.#pending = { resolve };\n this.#pull();\n });\n } };\n }\n };\n var WritableStreamShim = class {\n #sink;\n constructor(sink = {}) {\n this.#sink = sink;\n }\n getWriter() {\n return {\n write: async (chunk) => {\n await this.#sink.write?.(chunk);\n },\n close: async () => {\n await this.#sink.close?.();\n }\n };\n }\n };\n var TransformStreamShim = class {\n readable;\n writable;\n constructor(transformer = {}) {\n const queue = [];\n let closed = false;\n let pending;\n const controller = {\n enqueue: (value) => {\n if (pending) {\n pending.resolve({\n done: false,\n value\n });\n pending = void 0;\n return;\n }\n queue.push(value);\n },\n close: () => {\n closed = true;\n if (pending) {\n pending.resolve({ done: true });\n pending = void 0;\n }\n }\n };\n this.readable = { getReader() {\n return { read: async () => {\n if (queue.length > 0) return {\n done: false,\n value: queue.shift()\n };\n if (closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n pending = { resolve };\n });\n } };\n } };\n this.writable = new WritableStreamShim({\n write: async (chunk) => {\n transformer.transform?.(chunk, controller);\n },\n close: async () => {\n transformer.flush?.(controller);\n controller.close();\n }\n });\n }\n };\n function definePlatformGlobal(name, value, options = {}) {\n if (!options.overwrite && name in globalThis) return;\n Object.defineProperty(globalThis, name, {\n value,\n writable: true,\n configurable: true\n });\n }\n function formatLogArg(value) {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n function formatLogLine(args) {\n return args.map(formatLogArg).join(\" \");\n }\n const platformConsole = {\n log: (...args) => __caplets_log(\"log\", formatLogLine(args)),\n info: (...args) => __caplets_log(\"info\", formatLogLine(args)),\n warn: (...args) => __caplets_log(\"warn\", formatLogLine(args)),\n error: (...args) => __caplets_log(\"error\", formatLogLine(args)),\n debug: (...args) => __caplets_log(\"debug\", formatLogLine(args))\n };\n function normalizeEncoding(encoding) {\n const normalized = (encoding ?? \"utf8\").toLowerCase();\n switch (normalized) {\n case \"utf8\":\n case \"utf-8\":\n case \"base64\":\n case \"base64url\":\n case \"hex\": return normalized;\n default: throw new TypeError(`Unsupported Buffer encoding: ${encoding}`);\n }\n }\n function hexToBytes(value) {\n if (value.length % 2 !== 0) throw new TypeError(\"Invalid hex string length\");\n const bytes = new Uint8Array(value.length / 2);\n for (let index = 0; index < value.length; index += 2) {\n const parsed = Number.parseInt(value.slice(index, index + 2), 16);\n if (Number.isNaN(parsed)) throw new TypeError(\"Invalid hex string\");\n bytes[index / 2] = parsed;\n }\n return bytes;\n }\n function bytesToHex(bytes) {\n return Array.from(bytes, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n }\n function base64ToBytes(value, encoding) {\n let normalized = value.replace(/\\s+/gu, \"\");\n if (encoding === \"base64url\") normalized = normalized.replace(/-/gu, \"+\").replace(/_/gu, \"/\");\n const padding = normalized.length % 4;\n if (padding === 1) throw new TypeError(\"Invalid base64 string\");\n if (padding > 0) normalized = normalized.padEnd(normalized.length + (4 - padding), \"=\");\n const output = [];\n for (let index = 0; index < normalized.length; index += 4) {\n const values = normalized.slice(index, index + 4).split(\"\").map((char) => char === \"=\" ? 64 : base64Lookup.get(char) ?? NaN);\n if (values.some((entry) => Number.isNaN(entry))) throw new TypeError(\"Invalid base64 string\");\n const [a = 0, b = 0, c = 64, d = 64] = values;\n const triple = a << 18 | b << 12 | (c & 63) << 6 | d & 63;\n output.push(triple >> 16 & 255);\n if (c !== 64) output.push(triple >> 8 & 255);\n if (d !== 64) output.push(triple & 255);\n }\n return Uint8Array.from(output);\n }\n function bytesToBase64(bytes, encoding) {\n let output = \"\";\n for (let index = 0; index < bytes.length; index += 3) {\n const a = bytes[index] ?? 0;\n const b = bytes[index + 1] ?? 0;\n const c = bytes[index + 2] ?? 0;\n const triple = a << 16 | b << 8 | c;\n output += BASE64_ALPHABET[triple >> 18 & 63];\n output += BASE64_ALPHABET[triple >> 12 & 63];\n output += index + 1 < bytes.length ? BASE64_ALPHABET[triple >> 6 & 63] : \"=\";\n output += index + 2 < bytes.length ? BASE64_ALPHABET[triple & 63] : \"=\";\n }\n if (encoding === \"base64url\") return output.replace(/\\+/gu, \"-\").replace(/\\//gu, \"_\").replace(/=+$/gu, \"\");\n return output;\n }\n function copyBytes(input) {\n if (input instanceof ArrayBuffer) return new Uint8Array(input.slice(0));\n return new Uint8Array(input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength));\n }\n function toBytes(input, encoding) {\n if (input instanceof BufferShim) return input.toUint8Array();\n if (typeof input === \"string\") switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textEncoder.encode(input);\n case \"base64\":\n case \"base64url\": return base64ToBytes(input, normalizeEncoding(encoding));\n case \"hex\": return hexToBytes(input);\n }\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n if (Array.isArray(input)) return Uint8Array.from(input);\n throw new TypeError(\"Buffer.from only supports strings, arrays, ArrayBuffers, and typed arrays\");\n }\n var BufferShim = class BufferShim {\n #bytes;\n byteLength;\n length;\n constructor(bytes) {\n this.#bytes = bytes;\n this.byteLength = bytes.byteLength;\n this.length = bytes.length;\n }\n static from(input, encoding) {\n return new BufferShim(toBytes(input, encoding));\n }\n static isBuffer(value) {\n return value instanceof BufferShim;\n }\n static byteLength(input, encoding) {\n return toBytes(input, encoding).byteLength;\n }\n toUint8Array() {\n return new Uint8Array(this.#bytes);\n }\n toString(encoding) {\n switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textDecoder.decode(this.#bytes);\n case \"base64\":\n case \"base64url\": return bytesToBase64(this.#bytes, normalizeEncoding(encoding));\n case \"hex\": return bytesToHex(this.#bytes);\n }\n }\n };\n function atobShim(input) {\n return Array.from(base64ToBytes(String(input), \"base64\"), (value) => String.fromCharCode(value)).join(\"\");\n }\n function btoaShim(input) {\n const bytes = new Uint8Array(input.length);\n for (let index = 0; index < input.length; index += 1) {\n const codePoint = input.charCodeAt(index);\n if (codePoint > 255) throw new TypeError(\"The string to be encoded contains characters outside of Latin1\");\n bytes[index] = codePoint;\n }\n return bytesToBase64(bytes, \"base64\");\n }\n function queueMicrotaskShim(callback) {\n Promise.resolve().then(callback);\n }\n var AbortSignalShim = class AbortSignalShim {\n aborted = false;\n reason;\n onabort = null;\n #listeners = /* @__PURE__ */ new Set();\n addEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.add(listener);\n }\n removeEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.delete(listener);\n }\n dispatchEvent(event) {\n if (event.type !== \"abort\") return true;\n this.onabort?.(event);\n for (const listener of this.#listeners) listener(event);\n return true;\n }\n throwIfAborted() {\n if (this.aborted) throw this.reason ?? /* @__PURE__ */ new Error(\"Operation was aborted\");\n }\n static abort(reason) {\n const signal = new AbortSignalShim();\n signal.abort(reason);\n return signal;\n }\n abort(reason) {\n if (this.aborted) return;\n this.aborted = true;\n this.reason = reason;\n this.dispatchEvent({\n type: \"abort\",\n target: this\n });\n }\n };\n var AbortControllerShim = class {\n signal = new AbortSignalShim();\n abort(reason) {\n this.signal.abort(reason);\n }\n };\n function cloneFormData(input) {\n const clone = new FormData();\n for (const [name, value] of input.entries()) {\n if (value instanceof File) {\n clone.append(name, new File([value], value.name, { type: value.type }), value.name);\n continue;\n }\n clone.append(name, value);\n }\n return clone;\n }\n function cloneBodyValue(input) {\n if (input === null || input === void 0 || typeof input === \"string\") return input;\n if (input instanceof FormData) return cloneFormData(input);\n if (input instanceof Blob) return input.slice(0, input.size, input.type);\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n return input;\n }\n function blobFromBody(input) {\n if (input instanceof Blob) return input;\n if (typeof input === \"string\") return new Blob([input], { type: \"text/plain;charset=utf-8\" });\n if (input instanceof FormData) throw new TypeError(\"FormData body reading is not supported in Code Mode\");\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return new Blob([copyBytes(input)]);\n return new Blob([]);\n }\n var BodyMixin = class {\n _bodyInit;\n bodyUsed = false;\n body = null;\n constructor(body) {\n this._bodyInit = cloneBodyValue(body);\n }\n async arrayBuffer() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).arrayBuffer();\n }\n async blob() {\n this.bodyUsed = true;\n return blobFromBody(this._bodyInit);\n }\n async formData() {\n this.bodyUsed = true;\n if (this._bodyInit instanceof FormData) return cloneFormData(this._bodyInit);\n throw new TypeError(\"Body does not contain FormData\");\n }\n async json() {\n return JSON.parse(await this.text());\n }\n async text() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).text();\n }\n };\n function toHeaders(init) {\n return init instanceof Headers ? new Headers(init) : new Headers(init ?? {});\n }\n function normalizeMethod(method) {\n return String(method ?? \"GET\").toUpperCase();\n }\n var RequestShim = class RequestShim extends BodyMixin {\n headers;\n method;\n signal;\n url;\n constructor(input, init = {}) {\n const sourceBody = input instanceof RequestShim ? input._bodyInit : void 0;\n super(init.body ?? sourceBody);\n if (input instanceof RequestShim) this.url = input.url;\n else this.url = input instanceof URLShim ? input.href : new URLShim(String(input)).href;\n this.method = normalizeMethod(init.method ?? (input instanceof RequestShim ? input.method : \"GET\"));\n this.headers = toHeaders(init.headers ?? (input instanceof RequestShim ? input.headers : void 0));\n this.signal = init.signal ?? (input instanceof RequestShim ? input.signal : new AbortControllerShim().signal);\n }\n clone() {\n return new RequestShim(this, {\n method: this.method,\n headers: this.headers,\n body: this._bodyInit,\n signal: this.signal\n });\n }\n };\n var ResponseShim = class ResponseShim extends BodyMixin {\n headers;\n ok;\n redirected = false;\n status;\n statusText;\n type = \"default\";\n url = \"\";\n constructor(body, init = {}) {\n super(body);\n this.status = init.status ?? 200;\n this.statusText = init.statusText ?? \"\";\n this.headers = toHeaders(init.headers);\n this.ok = this.status >= 200 && this.status <= 299;\n }\n clone() {\n return new ResponseShim(this._bodyInit, {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText\n });\n }\n static json(data, init) {\n const headers = toHeaders(init?.headers);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n const responseInit = { headers };\n if (init?.status !== void 0) responseInit.status = init.status;\n if (init?.statusText !== void 0) responseInit.statusText = init.statusText;\n return new ResponseShim(JSON.stringify(data), responseInit);\n }\n };\n function disabledFetch() {\n throw new Error(DISABLED_FETCH_MESSAGE);\n }\n const integerTypedArrayConstructors = new Set([\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n typeof BigInt64Array === \"undefined\" ? void 0 : BigInt64Array,\n typeof BigUint64Array === \"undefined\" ? void 0 : BigUint64Array\n ]);\n var QuotaExceededErrorShim = class extends Error {\n constructor(message) {\n super(message);\n this.name = \"QuotaExceededError\";\n }\n };\n const platformCrypto = {\n randomUUID() {\n const randomUUID = capletsPlatformHost.randomUUID;\n if (!randomUUID) throw new Error(\"Code Mode platform random UUID bridge is not installed\");\n return randomUUID();\n },\n getRandomValues(typedArray) {\n if (!ArrayBuffer.isView(typedArray) || typedArray instanceof DataView) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (!integerTypedArrayConstructors.has(typedArray.constructor)) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (typedArray.byteLength > 65536) throw new QuotaExceededErrorShim(\"crypto.getRandomValues cannot generate more than 65,536 bytes\");\n const randomValues = capletsPlatformHost.randomValues;\n if (!randomValues) throw new Error(\"Code Mode platform random values bridge is not installed\");\n const bytes = randomValues(typedArray.byteLength);\n new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength).set(bytes);\n return typedArray;\n }\n };\n let nextTimerId = 1;\n const activeTimers = /* @__PURE__ */ new Set();\n function normalizeTimerDelay(delay) {\n const value = Number(delay ?? 0);\n if (!Number.isFinite(value) || value <= 0) return 0;\n return Math.trunc(value);\n }\n function setTimeoutShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setTimeout callback must be a function\");\n const timerId = nextTimerId++;\n activeTimers.add(timerId);\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, normalizeTimerDelay(delay)).then((fired) => {\n activeTimers.delete(timerId);\n if (fired) callback(...args);\n });\n return timerId;\n }\n function clearTimeoutShim(timerId) {\n const id = Number(timerId);\n activeTimers.delete(id);\n capletsPlatformHost.clearTimer?.(id);\n }\n function setIntervalShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setInterval callback must be a function\");\n const timerId = nextTimerId++;\n const intervalDelay = normalizeTimerDelay(delay);\n activeTimers.add(timerId);\n const tick = () => {\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, intervalDelay).then((fired) => {\n if (!fired || !activeTimers.has(timerId)) {\n activeTimers.delete(timerId);\n return;\n }\n callback(...args);\n if (activeTimers.has(timerId)) tick();\n });\n };\n tick();\n return timerId;\n }\n function clearIntervalShim(timerId) {\n clearTimeoutShim(timerId);\n }\n definePlatformGlobal(\"atob\", atobShim);\n definePlatformGlobal(\"btoa\", btoaShim);\n definePlatformGlobal(\"Buffer\", BufferShim);\n definePlatformGlobal(\"TextEncoder\", TextEncoderShim);\n definePlatformGlobal(\"TextDecoder\", TextDecoderShim);\n definePlatformGlobal(\"URL\", URLShim);\n definePlatformGlobal(\"URLSearchParams\", URLSearchParamsShim);\n definePlatformGlobal(\"structuredClone\", esm_default);\n definePlatformGlobal(\"Headers\", Headers);\n definePlatformGlobal(\"Blob\", Blob);\n definePlatformGlobal(\"File\", File);\n definePlatformGlobal(\"FormData\", FormData);\n definePlatformGlobal(\"ReadableStream\", ReadableStreamShim);\n definePlatformGlobal(\"WritableStream\", WritableStreamShim);\n definePlatformGlobal(\"TransformStream\", TransformStreamShim);\n definePlatformGlobal(\"AbortController\", AbortControllerShim);\n definePlatformGlobal(\"AbortSignal\", AbortSignalShim);\n definePlatformGlobal(\"Request\", RequestShim);\n definePlatformGlobal(\"Response\", ResponseShim);\n definePlatformGlobal(\"crypto\", platformCrypto);\n definePlatformGlobal(\"setTimeout\", setTimeoutShim);\n definePlatformGlobal(\"clearTimeout\", clearTimeoutShim);\n definePlatformGlobal(\"setInterval\", setIntervalShim);\n definePlatformGlobal(\"clearInterval\", clearIntervalShim);\n definePlatformGlobal(\"queueMicrotask\", queueMicrotaskShim);\n definePlatformGlobal(\"console\", platformConsole);\n definePlatformGlobal(\"fetch\", disabledFetch, { overwrite: true });\n //#endregion\n})();";
78401
+ const CODE_MODE_PLATFORM_RUNTIME_SOURCE = "(function() {\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/deserialize.js\n const env = typeof self === \"object\" ? self : globalThis;\n const guard = (name, init) => {\n switch (name) {\n case \"Function\":\n case \"SharedWorker\":\n case \"Worker\":\n case \"eval\":\n case \"setInterval\":\n case \"setTimeout\": throw new TypeError(\"unable to deserialize \" + name);\n }\n return new env[name](init);\n };\n const deserializer = ($, _) => {\n const as = (out, index) => {\n $.set(index, out);\n return out;\n };\n const unpair = (index) => {\n if ($.has(index)) return $.get(index);\n const [type, value] = _[index];\n switch (type) {\n case 0:\n case -1: return as(value, index);\n case 1: {\n const arr = as([], index);\n for (const index of value) arr.push(unpair(index));\n return arr;\n }\n case 2: {\n const object = as({}, index);\n for (const [key, index] of value) object[unpair(key)] = unpair(index);\n return object;\n }\n case 3: return as(new Date(value), index);\n case 4: {\n const { source, flags } = value;\n return as(new RegExp(source, flags), index);\n }\n case 5: {\n const map = as(/* @__PURE__ */ new Map(), index);\n for (const [key, index] of value) map.set(unpair(key), unpair(index));\n return map;\n }\n case 6: {\n const set = as(/* @__PURE__ */ new Set(), index);\n for (const index of value) set.add(unpair(index));\n return set;\n }\n case 7: {\n const { name, message } = value;\n return as(guard(name, message), index);\n }\n case 8: return as(BigInt(value), index);\n case \"BigInt\": return as(Object(BigInt(value)), index);\n case \"ArrayBuffer\": return as(new Uint8Array(value).buffer, value);\n case \"DataView\": {\n const { buffer } = new Uint8Array(value);\n return as(new DataView(buffer), value);\n }\n }\n return as(guard(type, value), index);\n };\n return unpair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns a deserialized value from a serialized array of Records.\n * @param {Record[]} serialized a previously serialized value.\n * @returns {any}\n */\n const deserialize = (serialized) => deserializer(/* @__PURE__ */ new Map(), serialized)(0);\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/serialize.js\n const EMPTY = \"\";\n const { toString } = {};\n const { keys } = Object;\n const typeOf = (value) => {\n const type = typeof value;\n if (type !== \"object\" || !value) return [0, type];\n const asString = toString.call(value).slice(8, -1);\n switch (asString) {\n case \"Array\": return [1, EMPTY];\n case \"Object\": return [2, EMPTY];\n case \"Date\": return [3, EMPTY];\n case \"RegExp\": return [4, EMPTY];\n case \"Map\": return [5, EMPTY];\n case \"Set\": return [6, EMPTY];\n case \"DataView\": return [1, asString];\n }\n if (asString.includes(\"Array\")) return [1, asString];\n if (asString.includes(\"Error\")) return [7, asString];\n return [2, asString];\n };\n const shouldSkip = ([TYPE, type]) => TYPE === 0 && (type === \"function\" || type === \"symbol\");\n const serializer = (strict, json, $, _) => {\n const as = (out, value) => {\n const index = _.push(out) - 1;\n $.set(value, index);\n return index;\n };\n const pair = (value) => {\n if ($.has(value)) return $.get(value);\n let [TYPE, type] = typeOf(value);\n switch (TYPE) {\n case 0: {\n let entry = value;\n switch (type) {\n case \"bigint\":\n TYPE = 8;\n entry = value.toString();\n break;\n case \"function\":\n case \"symbol\":\n if (strict) throw new TypeError(\"unable to serialize \" + type);\n entry = null;\n break;\n case \"undefined\": return as([-1], value);\n }\n return as([TYPE, entry], value);\n }\n case 1: {\n if (type) {\n let spread = value;\n if (type === \"DataView\") spread = new Uint8Array(value.buffer);\n else if (type === \"ArrayBuffer\") spread = new Uint8Array(value);\n return as([type, [...spread]], value);\n }\n const arr = [];\n const index = as([TYPE, arr], value);\n for (const entry of value) arr.push(pair(entry));\n return index;\n }\n case 2: {\n if (type) switch (type) {\n case \"BigInt\": return as([type, value.toString()], value);\n case \"Boolean\":\n case \"Number\":\n case \"String\": return as([type, value.valueOf()], value);\n }\n if (json && \"toJSON\" in value) return pair(value.toJSON());\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const key of keys(value)) if (strict || !shouldSkip(typeOf(value[key]))) entries.push([pair(key), pair(value[key])]);\n return index;\n }\n case 3: return as([TYPE, value.toISOString()], value);\n case 4: {\n const { source, flags } = value;\n return as([TYPE, {\n source,\n flags\n }], value);\n }\n case 5: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const [key, entry] of value) if (strict || !(shouldSkip(typeOf(key)) || shouldSkip(typeOf(entry)))) entries.push([pair(key), pair(entry)]);\n return index;\n }\n case 6: {\n const entries = [];\n const index = as([TYPE, entries], value);\n for (const entry of value) if (strict || !shouldSkip(typeOf(entry))) entries.push(pair(entry));\n return index;\n }\n }\n const { message } = value;\n return as([TYPE, {\n name: type,\n message\n }], value);\n };\n return pair;\n };\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} value a serializable value.\n * @param {{json?: boolean, lossy?: boolean}?} options an object with a `lossy` or `json` property that,\n * if `true`, will not throw errors on incompatible types, and behave more\n * like JSON stringify would behave. Symbol and Function will be discarded.\n * @returns {Record[]}\n */\n const serialize = (value, { json, lossy } = {}) => {\n const _ = [];\n return serializer(!(json || lossy), !!json, /* @__PURE__ */ new Map(), _)(value), _;\n };\n //#endregion\n //#region node_modules/.pnpm/@ungap+structured-clone@1.3.1/node_modules/@ungap/structured-clone/esm/index.js\n /**\n * @typedef {Array<string,any>} Record a type representation\n */\n /**\n * Returns an array of serialized Records.\n * @param {any} any a serializable value.\n * @param {{transfer?: any[], json?: boolean, lossy?: boolean}?} options an object with\n * a transfer option (ignored when polyfilled) and/or non standard fields that\n * fallback to the polyfill if present.\n * @returns {Record[]}\n */\n var esm_default = typeof structuredClone === \"function\" ? (any, options) => options && (\"json\" in options || \"lossy\" in options) ? deserialize(serialize(any, options)) : structuredClone(any) : (any, options) => deserialize(serialize(any, options));\n //#endregion\n //#region node_modules/.pnpm/formdata-node@6.0.3/node_modules/formdata-node/lib/form-data.js\n var __accessCheck = (obj, member, msg) => {\n if (!member.has(obj)) throw TypeError(\"Cannot \" + msg);\n };\n var __privateGet = (obj, member, getter) => {\n __accessCheck(obj, member, \"read from private field\");\n return getter ? getter.call(obj) : member.get(obj);\n };\n var __privateAdd = (obj, member, value) => {\n if (member.has(obj)) throw TypeError(\"Cannot add the same private member more than once\");\n member instanceof WeakSet ? member.add(obj) : member.set(obj, value);\n };\n var __privateSet = (obj, member, value, setter) => {\n __accessCheck(obj, member, \"write to private field\");\n setter ? setter.call(obj, value) : member.set(obj, value);\n return value;\n };\n var __privateMethod = (obj, member, method) => {\n __accessCheck(obj, member, \"access private method\");\n return method;\n };\n var isFunction = (value) => typeof value === \"function\";\n var isObject = (value) => typeof value === \"object\" && value != null && !Array.isArray(value);\n var isAsyncIterable = (value) => isObject(value) && isFunction(value[Symbol.asyncIterator]);\n var MAX_CHUNK_SIZE = 65536;\n async function* clonePart(value) {\n if (value.byteLength <= MAX_CHUNK_SIZE) {\n yield value;\n return;\n }\n let offset = 0;\n while (offset < value.byteLength) {\n const size = Math.min(value.byteLength - offset, MAX_CHUNK_SIZE);\n const buffer = value.buffer.slice(offset, offset + size);\n offset += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* readStream(readable) {\n const reader = readable.getReader();\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n yield value;\n }\n }\n async function* chunkStream(stream) {\n for await (const value of stream) yield* clonePart(value);\n }\n var getStreamIterator = (source) => {\n if (isAsyncIterable(source)) return chunkStream(source);\n if (isFunction(source.getReader)) return chunkStream(readStream(source));\n throw new TypeError(\"Unsupported data source: Expected either ReadableStream or async iterable.\");\n };\n async function* consumeNodeBlob(blob) {\n let position = 0;\n while (position !== blob.size) {\n const buffer = await blob.slice(position, Math.min(blob.size, position + MAX_CHUNK_SIZE)).arrayBuffer();\n position += buffer.byteLength;\n yield new Uint8Array(buffer);\n }\n }\n async function* consumeBlobParts(parts, clone = false) {\n for (const part of parts) if (ArrayBuffer.isView(part)) if (clone) yield* clonePart(part);\n else yield part;\n else if (isFunction(part.stream)) yield* getStreamIterator(part.stream());\n else yield* consumeNodeBlob(part);\n }\n function* sliceBlob(blobParts, blobSize, start = 0, end) {\n end ??= blobSize;\n let relativeStart = start < 0 ? Math.max(blobSize + start, 0) : Math.min(start, blobSize);\n let relativeEnd = end < 0 ? Math.max(blobSize + end, 0) : Math.min(end, blobSize);\n const span = Math.max(relativeEnd - relativeStart, 0);\n let added = 0;\n for (const part of blobParts) {\n if (added >= span) break;\n const partSize = ArrayBuffer.isView(part) ? part.byteLength : part.size;\n if (relativeStart && partSize <= relativeStart) {\n relativeStart -= partSize;\n relativeEnd -= partSize;\n } else {\n let chunk;\n if (ArrayBuffer.isView(part)) {\n chunk = part.subarray(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.byteLength;\n } else {\n chunk = part.slice(relativeStart, Math.min(partSize, relativeEnd));\n added += chunk.size;\n }\n relativeEnd -= partSize;\n relativeStart = 0;\n yield chunk;\n }\n }\n }\n var _parts, _type, _size;\n var _Blob = class _Blob {\n /**\n * Returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object.\n * The content of the blob consists of the concatenation of the values given in the parameter array.\n *\n * @param blobParts An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n * @param options An optional object of type `BlobPropertyBag`.\n */\n constructor(blobParts = [], options = {}) {\n /**\n * An `Array` of [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView) or [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n __privateAdd(this, _parts, []);\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n __privateAdd(this, _type, \"\");\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n __privateAdd(this, _size, 0);\n options ??= {};\n if (typeof blobParts !== \"object\" || blobParts === null) throw new TypeError(\"Failed to construct 'Blob': The provided value cannot be converted to a sequence.\");\n if (!isFunction(blobParts[Symbol.iterator])) throw new TypeError(\"Failed to construct 'Blob': The object must have a callable @@iterator property.\");\n if (typeof options !== \"object\" && !isFunction(options)) throw new TypeError(\"Failed to construct 'Blob': parameter 2 cannot convert to dictionary.\");\n const encoder = new TextEncoder();\n for (const raw of blobParts) {\n let part;\n if (ArrayBuffer.isView(raw)) part = new Uint8Array(raw.buffer.slice(raw.byteOffset, raw.byteOffset + raw.byteLength));\n else if (raw instanceof ArrayBuffer) part = new Uint8Array(raw.slice(0));\n else if (raw instanceof _Blob) part = raw;\n else part = encoder.encode(String(raw));\n __privateSet(this, _size, __privateGet(this, _size) + (ArrayBuffer.isView(part) ? part.byteLength : part.size));\n __privateGet(this, _parts).push(part);\n }\n const type = options.type === void 0 ? \"\" : String(options.type);\n __privateSet(this, _type, /^[\\x20-\\x7E]*$/.test(type) ? type : \"\");\n }\n static [Symbol.hasInstance](value) {\n return Boolean(value && typeof value === \"object\" && isFunction(value.constructor) && (isFunction(value.stream) || isFunction(value.arrayBuffer)) && /^(Blob|File)$/.test(value[Symbol.toStringTag]));\n }\n /**\n * Returns the [`MIME type`](https://developer.mozilla.org/en-US/docs/Glossary/MIME_type) of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n */\n get type() {\n return __privateGet(this, _type);\n }\n /**\n * Returns the size of the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) in bytes.\n */\n get size() {\n return __privateGet(this, _size);\n }\n /**\n * Creates and returns a new [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) object which contains data from a subset of the blob on which it's called.\n *\n * @param start An index into the Blob indicating the first byte to include in the new Blob. If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is 0. If you specify a value for start that is larger than the size of the source Blob, the returned Blob has size 0 and contains no data.\n * @param end An index into the Blob indicating the first byte that will *not* be included in the new Blob (i.e. the byte exactly at this index is not included). If you specify a negative value, it's treated as an offset from the end of the Blob toward the beginning. For example, -10 would be the 10th from last byte in the Blob. The default value is size.\n * @param contentType The content type to assign to the new Blob; this will be the value of its type property. The default value is an empty string.\n */\n slice(start, end, contentType) {\n return new _Blob(sliceBlob(__privateGet(this, _parts), this.size, start, end), { type: contentType });\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with a string containing the contents of the blob, interpreted as UTF-8.\n */\n async text() {\n const decoder = new TextDecoder();\n let result = \"\";\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) result += decoder.decode(chunk, { stream: true });\n result += decoder.decode();\n return result;\n }\n /**\n * Returns a [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) that resolves with the contents of the blob as binary data contained in an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).\n */\n async arrayBuffer() {\n const view = new Uint8Array(this.size);\n let offset = 0;\n for await (const chunk of consumeBlobParts(__privateGet(this, _parts))) {\n view.set(chunk, offset);\n offset += chunk.length;\n }\n return view.buffer;\n }\n /**\n * Returns a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) which upon reading returns the data contained within the [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).\n */\n stream() {\n const iterator = consumeBlobParts(__privateGet(this, _parts), true);\n return new ReadableStream({\n async pull(controller) {\n const { value, done } = await iterator.next();\n if (done) return queueMicrotask(() => controller.close());\n controller.enqueue(value);\n },\n async cancel() {\n await iterator.return();\n }\n });\n }\n get [Symbol.toStringTag]() {\n return \"Blob\";\n }\n };\n _parts = /* @__PURE__ */ new WeakMap();\n _type = /* @__PURE__ */ new WeakMap();\n _size = /* @__PURE__ */ new WeakMap();\n var Blob = _Blob;\n Object.defineProperties(Blob.prototype, {\n type: { enumerable: true },\n size: { enumerable: true },\n slice: { enumerable: true },\n stream: { enumerable: true },\n text: { enumerable: true },\n arrayBuffer: { enumerable: true }\n });\n var isBlob = (value) => value instanceof Blob;\n var _name, _lastModified;\n var File = class extends Blob {\n /**\n * Creates a new File instance.\n *\n * @param fileBits An `Array` strings, or [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), [`ArrayBufferView`](https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView), [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) objects, or a mix of any of such objects, that will be put inside the [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File).\n * @param name The name of the file.\n * @param options An options object containing optional attributes for the file.\n */\n constructor(fileBits, name, options = {}) {\n super(fileBits, options);\n /**\n * Returns the name of the file referenced by the File object.\n */\n __privateAdd(this, _name, void 0);\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n __privateAdd(this, _lastModified, 0);\n if (arguments.length < 2) throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`);\n __privateSet(this, _name, String(name));\n const lastModified = options.lastModified === void 0 ? Date.now() : Number(options.lastModified);\n if (!Number.isNaN(lastModified)) __privateSet(this, _lastModified, lastModified);\n }\n static [Symbol.hasInstance](value) {\n return value instanceof Blob && value[Symbol.toStringTag] === \"File\" && typeof value.name === \"string\";\n }\n /**\n * Name of the file referenced by the File object.\n */\n get name() {\n return __privateGet(this, _name);\n }\n /* c8 ignore next 3 */\n get webkitRelativePath() {\n return \"\";\n }\n /**\n * The last modified date of the file as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). Files without a known last modified date return the current date.\n */\n get lastModified() {\n return __privateGet(this, _lastModified);\n }\n get [Symbol.toStringTag]() {\n return \"File\";\n }\n };\n _name = /* @__PURE__ */ new WeakMap();\n _lastModified = /* @__PURE__ */ new WeakMap();\n var isFile = (value) => value instanceof File;\n var _entries, _setEntry, setEntry_fn;\n var FormData = class {\n constructor() {\n __privateAdd(this, _setEntry);\n /**\n * Stores internal data for every entry\n */\n __privateAdd(this, _entries, /* @__PURE__ */ new Map());\n }\n static [Symbol.hasInstance](value) {\n if (!value) return false;\n const val = value;\n return Boolean(isFunction(val.constructor) && val[Symbol.toStringTag] === \"FormData\" && isFunction(val.append) && isFunction(val.set) && isFunction(val.get) && isFunction(val.getAll) && isFunction(val.has) && isFunction(val.delete) && isFunction(val.entries) && isFunction(val.values) && isFunction(val.keys) && isFunction(val[Symbol.iterator]) && isFunction(val.forEach));\n }\n /**\n * Appends a new value onto an existing key inside a FormData object,\n * or adds the key if it does not already exist.\n *\n * The difference between `set()` and `append()` is that if the specified key already exists, `set()` will overwrite all existing values with the new one, whereas `append()` will append the new value onto the end of the existing set of values.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n */\n append(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: true,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Set a new value for an existing key inside FormData,\n * or add the new field if it does not already exist.\n *\n * @param name The name of the field whose data is contained in `value`.\n * @param value The field's value. This can be [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n or [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File). If none of these are specified the value is converted to a string.\n * @param fileName The filename reported to the server, when a Blob or File is passed as the second parameter. The default filename for Blob objects is \"blob\". The default filename for File objects is the file's filename.\n *\n */\n set(name, value, fileName) {\n __privateMethod(this, _setEntry, setEntry_fn).call(this, {\n name,\n fileName,\n append: false,\n rawValue: value,\n argsLength: arguments.length\n });\n }\n /**\n * Returns the first value associated with a given key from within a `FormData` object.\n * If you expect multiple values and want all of them, use the `getAll()` method instead.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns A `FormDataEntryValue` containing the value. If the key doesn't exist, the method returns null.\n */\n get(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return null;\n return field[0];\n }\n /**\n * Returns all the values associated with a given key from within a `FormData` object.\n *\n * @param {string} name A name of the value you want to retrieve.\n *\n * @returns An array of `FormDataEntryValue` whose key matches the value passed in the `name` parameter. If the key doesn't exist, the method returns an empty list.\n */\n getAll(name) {\n const field = __privateGet(this, _entries).get(String(name));\n if (!field) return [];\n return field.slice();\n }\n /**\n * Returns a boolean stating whether a `FormData` object contains a certain key.\n *\n * @param name A string representing the name of the key you want to test for.\n *\n * @return A boolean value.\n */\n has(name) {\n return __privateGet(this, _entries).has(String(name));\n }\n /**\n * Deletes a key and its value(s) from a `FormData` object.\n *\n * @param name The name of the key you want to delete.\n */\n delete(name) {\n __privateGet(this, _entries).delete(String(name));\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all keys contained in this `FormData` object.\n * Each key is a `string`.\n */\n *keys() {\n for (const key of __privateGet(this, _entries).keys()) yield key;\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through the `FormData` key/value pairs.\n * The key of each pair is a string; the value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *entries() {\n for (const name of this.keys()) {\n const values = this.getAll(name);\n for (const value of values) yield [name, value];\n }\n }\n /**\n * Returns an [`iterator`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) allowing to go through all values contained in this object `FormData` object.\n * Each value is a [`FormDataValue`](https://developer.mozilla.org/en-US/docs/Web/API/FormDataEntryValue).\n */\n *values() {\n for (const [, value] of this) yield value;\n }\n /**\n * An alias for FormData#entries()\n */\n [Symbol.iterator]() {\n return this.entries();\n }\n /**\n * Executes given callback function for each field of the FormData instance\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this) callback.call(thisArg, value, name, this);\n }\n get [Symbol.toStringTag]() {\n return \"FormData\";\n }\n };\n _entries = /* @__PURE__ */ new WeakMap();\n _setEntry = /* @__PURE__ */ new WeakSet();\n setEntry_fn = function({ name, rawValue, append, fileName, argsLength }) {\n const methodName = append ? \"append\" : \"set\";\n if (argsLength < 2) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': 2 arguments required, but only ${argsLength} present.`);\n name = String(name);\n let value;\n if (isFile(rawValue)) value = fileName === void 0 ? rawValue : new File([rawValue], fileName, {\n type: rawValue.type,\n lastModified: rawValue.lastModified\n });\n else if (isBlob(rawValue)) value = new File([rawValue], fileName === void 0 ? \"blob\" : fileName, { type: rawValue.type });\n else if (fileName) throw new TypeError(`Failed to execute '${methodName}' on 'FormData': parameter 2 is not of type 'Blob'.`);\n else value = String(rawValue);\n const values = __privateGet(this, _entries).get(name);\n if (!values) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n if (!append) {\n __privateGet(this, _entries).set(name, [value]);\n return;\n }\n values.push(value);\n };\n /*! Based on fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> & David Frank */\n //#endregion\n //#region node_modules/.pnpm/set-cookie-parser@3.1.0/node_modules/set-cookie-parser/lib/set-cookie.js\n var defaultParseOptions = {\n decodeValues: true,\n map: false,\n silent: false,\n split: \"auto\"\n };\n function isForbiddenKey(key) {\n return typeof key !== \"string\" || key in {};\n }\n function createNullObj() {\n return Object.create(null);\n }\n function isNonEmptyString(str) {\n return typeof str === \"string\" && !!str.trim();\n }\n function parseString(setCookieValue, options) {\n var parts = setCookieValue.split(\";\").filter(isNonEmptyString);\n var parsed = parseNameValuePair(parts.shift());\n var name = parsed.name;\n var value = parsed.value;\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (isForbiddenKey(name)) return null;\n try {\n value = options.decodeValues ? decodeURIComponent(value) : value;\n } catch (e) {\n console.error(\"set-cookie-parser: failed to decode cookie value. Set options.decodeValues=false to disable decoding.\", e);\n }\n var cookie = createNullObj();\n cookie.name = name;\n cookie.value = value;\n parts.forEach(function(part) {\n var sides = part.split(\"=\");\n var key = sides.shift().trimLeft().toLowerCase();\n if (isForbiddenKey(key)) return;\n var value = sides.join(\"=\");\n if (key === \"expires\") cookie.expires = new Date(value);\n else if (key === \"max-age\") {\n var n = parseInt(value, 10);\n if (!Number.isNaN(n)) cookie.maxAge = n;\n } else if (key === \"secure\") cookie.secure = true;\n else if (key === \"httponly\") cookie.httpOnly = true;\n else if (key === \"samesite\") cookie.sameSite = value;\n else if (key === \"partitioned\") cookie.partitioned = true;\n else if (key) cookie[key] = value;\n });\n return cookie;\n }\n function parseNameValuePair(nameValuePairStr) {\n var name = \"\";\n var value = \"\";\n var nameValueArr = nameValuePairStr.split(\"=\");\n if (nameValueArr.length > 1) {\n name = nameValueArr.shift();\n value = nameValueArr.join(\"=\");\n } else value = nameValuePairStr;\n return {\n name,\n value\n };\n }\n function parseSetCookie(input, options) {\n options = options ? Object.assign({}, defaultParseOptions, options) : defaultParseOptions;\n if (!input) if (!options.map) return [];\n else return createNullObj();\n if (input.headers) if (typeof input.headers.getSetCookie === \"function\") input = input.headers.getSetCookie();\n else if (input.headers[\"set-cookie\"]) input = input.headers[\"set-cookie\"];\n else {\n var sch = input.headers[Object.keys(input.headers).find(function(key) {\n return key.toLowerCase() === \"set-cookie\";\n })];\n if (!sch && input.headers.cookie && !options.silent) console.warn(\"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning.\");\n input = sch;\n }\n var split = options.split;\n var isArray = Array.isArray(input);\n if (split === \"auto\") split = !isArray;\n if (!isArray) input = [input];\n input = input.filter(isNonEmptyString);\n if (split) input = input.map(splitCookiesString).flat();\n if (!options.map) return input.map(function(str) {\n return parseString(str, options);\n }).filter(Boolean);\n else {\n var cookies = createNullObj();\n return input.reduce(function(cookies, str) {\n var cookie = parseString(str, options);\n if (cookie && !isForbiddenKey(cookie.name)) cookies[cookie.name] = cookie;\n return cookies;\n }, cookies);\n }\n }\n function splitCookiesString(cookiesString) {\n if (Array.isArray(cookiesString)) return cookiesString;\n if (typeof cookiesString !== \"string\") return [];\n var cookiesStrings = [];\n var pos = 0;\n var start;\n var ch;\n var lastComma;\n var nextStart;\n var cookiesSeparatorFound;\n function skipWhitespace() {\n while (pos < cookiesString.length && /\\s/.test(cookiesString.charAt(pos))) pos += 1;\n return pos < cookiesString.length;\n }\n function notSpecialChar() {\n ch = cookiesString.charAt(pos);\n return ch !== \"=\" && ch !== \";\" && ch !== \",\";\n }\n while (pos < cookiesString.length) {\n start = pos;\n cookiesSeparatorFound = false;\n while (skipWhitespace()) {\n ch = cookiesString.charAt(pos);\n if (ch === \",\") {\n lastComma = pos;\n pos += 1;\n skipWhitespace();\n nextStart = pos;\n while (pos < cookiesString.length && notSpecialChar()) pos += 1;\n if (pos < cookiesString.length && cookiesString.charAt(pos) === \"=\") {\n cookiesSeparatorFound = true;\n pos = nextStart;\n cookiesStrings.push(cookiesString.substring(start, lastComma));\n start = pos;\n } else pos = lastComma + 1;\n } else pos += 1;\n }\n if (!cookiesSeparatorFound || pos >= cookiesString.length) cookiesStrings.push(cookiesString.substring(start, cookiesString.length));\n }\n return cookiesStrings;\n }\n parseSetCookie.parseSetCookie = parseSetCookie;\n parseSetCookie.parse = parseSetCookie;\n parseSetCookie.parseString = parseString;\n parseSetCookie.splitCookiesString = splitCookiesString;\n //#endregion\n //#region node_modules/.pnpm/headers-polyfill@5.0.1/node_modules/headers-polyfill/lib/index.mjs\n const HEADERS_INVALID_CHARACTERS = /[^a-z0-9\\-#$%&'*+.^_`|~]/i;\n function normalizeHeaderName(name) {\n if (HEADERS_INVALID_CHARACTERS.test(name) || name.trim() === \"\") throw new TypeError(\"Invalid character in header field name\");\n return name.trim().toLowerCase();\n }\n const charCodesToRemove = [\n String.fromCharCode(10),\n String.fromCharCode(13),\n String.fromCharCode(9),\n String.fromCharCode(32)\n ];\n const HEADER_VALUE_REMOVE_REGEXP = new RegExp(`(^[${charCodesToRemove.join(\"\")}]|$[${charCodesToRemove.join(\"\")}])`, \"g\");\n /**\n * Normalize the given header value.\n * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize\n */\n function normalizeHeaderValue(value) {\n return value.replace(HEADER_VALUE_REMOVE_REGEXP, \"\");\n }\n /**\n * Validate the given header name.\n * @see https://fetch.spec.whatwg.org/#header-name\n */\n function isValidHeaderName(value) {\n if (typeof value !== \"string\") return false;\n if (value.length === 0) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character > 127 || !isToken(character)) return false;\n }\n return true;\n }\n function isToken(value) {\n return ![\n 127,\n 32,\n \"(\",\n \")\",\n \"<\",\n \">\",\n \"@\",\n \",\",\n \";\",\n \":\",\n \"\\\\\",\n \"\\\"\",\n \"/\",\n \"[\",\n \"]\",\n \"?\",\n \"=\",\n \"{\",\n \"}\"\n ].includes(value);\n }\n /**\n * Validate the given header value.\n * @see https://fetch.spec.whatwg.org/#header-value\n */\n function isValidHeaderValue(value) {\n if (typeof value !== \"string\") return false;\n if (value.trim() !== value) return false;\n for (let i = 0; i < value.length; i++) {\n const character = value.charCodeAt(i);\n if (character === 0 || character === 10 || character === 13) return false;\n }\n return true;\n }\n let _Symbol$toStringTag;\n const NORMALIZED_HEADERS = Symbol(\"normalizedHeaders\");\n const RAW_HEADER_NAMES = Symbol(\"rawHeaderNames\");\n const HEADER_VALUE_DELIMITER = \", \";\n var Headers = class Headers {\n constructor(init) {\n this[NORMALIZED_HEADERS] = {};\n this[RAW_HEADER_NAMES] = /* @__PURE__ */ new Map();\n this[_Symbol$toStringTag] = \"Headers\";\n /**\n * @note Cannot necessarily check if the `init` is an instance of the\n * `Headers` because that class may not be defined in Node or jsdom.\n */\n if ([\"Headers\", \"HeadersPolyfill\"].includes(init?.constructor?.name) || init instanceof Headers || typeof globalThis.Headers !== \"undefined\" && init instanceof globalThis.Headers) init.forEach((value, name) => {\n this.append(name, value);\n }, this);\n else if (Array.isArray(init)) init.forEach(([name, value]) => {\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n else if (init) Object.getOwnPropertyNames(init).forEach((name) => {\n const value = init[name];\n this.append(name, Array.isArray(value) ? value.join(HEADER_VALUE_DELIMITER) : value);\n });\n }\n [(_Symbol$toStringTag = Symbol.toStringTag, Symbol.iterator)]() {\n return this.entries();\n }\n *keys() {\n for (const [name] of this.entries()) yield name;\n }\n *values() {\n for (const [, value] of this.entries()) yield value;\n }\n *entries() {\n let sortedKeys = Object.keys(this[NORMALIZED_HEADERS]).sort((a, b) => a.localeCompare(b));\n for (const name of sortedKeys) if (name === \"set-cookie\") for (const value of this.getSetCookie()) yield [name, value];\n else yield [name, this.get(name)];\n }\n /**\n * Returns a boolean stating whether a `Headers` object contains a certain header.\n */\n has(name) {\n if (!isValidHeaderName(name)) throw new TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS].hasOwnProperty(normalizeHeaderName(name));\n }\n /**\n * Returns a `ByteString` sequence of all the values of a header with a given name.\n */\n get(name) {\n if (!isValidHeaderName(name)) throw TypeError(`Invalid header name \"${name}\"`);\n return this[NORMALIZED_HEADERS][normalizeHeaderName(name)] ?? null;\n }\n /**\n * Sets a new value for an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n set(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n this[NORMALIZED_HEADERS][normalizedName] = normalizeHeaderValue(normalizedValue);\n this[RAW_HEADER_NAMES].set(normalizedName, name);\n }\n /**\n * Appends a new value onto an existing header inside a `Headers` object, or adds the header if it does not already exist.\n */\n append(name, value) {\n if (!isValidHeaderName(name) || !isValidHeaderValue(value)) return;\n const normalizedName = normalizeHeaderName(name);\n const normalizedValue = normalizeHeaderValue(value);\n let resolvedValue = this.has(normalizedName) ? `${this.get(normalizedName)}, ${normalizedValue}` : normalizedValue;\n this.set(name, resolvedValue);\n }\n /**\n * Deletes a header from the `Headers` object.\n */\n delete(name) {\n if (!isValidHeaderName(name)) return;\n if (!this.has(name)) return;\n const normalizedName = normalizeHeaderName(name);\n delete this[NORMALIZED_HEADERS][normalizedName];\n this[RAW_HEADER_NAMES].delete(normalizedName);\n }\n /**\n * Traverses the `Headers` object,\n * calling the given callback for each header.\n */\n forEach(callback, thisArg) {\n for (const [name, value] of this.entries()) callback.call(thisArg, value, name, this);\n }\n /**\n * Returns an array containing the values\n * of all Set-Cookie headers associated\n * with a response\n */\n getSetCookie() {\n const setCookieHeader = this.get(\"set-cookie\");\n if (setCookieHeader === null) return [];\n if (setCookieHeader === \"\") return [\"\"];\n return splitCookiesString(setCookieHeader);\n }\n };\n //#endregion\n //#region packages/core/src/code-mode/platform-entry.ts\n const platformBridgeGlobalThis = globalThis;\n const capletsPlatformHost = {\n randomUUID: platformBridgeGlobalThis.__caplets_platform_random_uuid,\n randomValues: platformBridgeGlobalThis.__caplets_platform_random_values,\n sleep: platformBridgeGlobalThis.__caplets_platform_sleep,\n clearTimer: platformBridgeGlobalThis.__caplets_platform_clear_timer\n };\n delete platformBridgeGlobalThis.__caplets_platform_random_uuid;\n delete platformBridgeGlobalThis.__caplets_platform_random_values;\n delete platformBridgeGlobalThis.__caplets_platform_sleep;\n delete platformBridgeGlobalThis.__caplets_platform_clear_timer;\n const DISABLED_FETCH_MESSAGE = \"Direct fetch is not available in Code Mode; use a Caplet instead.\";\n const BASE64_ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n const base64Lookup = new Map(BASE64_ALPHABET.split(\"\").map((char, index) => [char, index]));\n function utf8Encode(input) {\n const encoded = encodeURIComponent(input);\n const bytes = [];\n for (let index = 0; index < encoded.length; index += 1) {\n if (encoded[index] === \"%\") {\n bytes.push(Number.parseInt(encoded.slice(index + 1, index + 3), 16));\n index += 2;\n continue;\n }\n bytes.push(encoded.charCodeAt(index));\n }\n return Uint8Array.from(bytes);\n }\n function utf8Decode(input) {\n let output = \"\";\n for (let index = 0; index < input.length; index += 1) {\n const first = input[index] ?? 0;\n if (first < 128) {\n output += String.fromCharCode(first);\n continue;\n }\n if (first >= 194 && first <= 223) {\n const second = input[index + 1];\n if (isUtf8Continuation(second)) {\n output += String.fromCodePoint((first & 31) << 6 | second & 63);\n index += 1;\n continue;\n }\n output += \"�\";\n continue;\n }\n if (first >= 224 && first <= 239) {\n const second = input[index + 1];\n const third = input[index + 2];\n if (isValidUtf8SecondForThreeByte(first, second) && isUtf8Continuation(third)) {\n output += String.fromCodePoint((first & 15) << 12 | (second & 63) << 6 | third & 63);\n index += 2;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForThreeByte(first, second)) index += 1;\n continue;\n }\n if (first >= 240 && first <= 244) {\n const second = input[index + 1];\n const third = input[index + 2];\n const fourth = input[index + 3];\n if (isValidUtf8SecondForFourByte(first, second) && isUtf8Continuation(third) && isUtf8Continuation(fourth)) {\n output += String.fromCodePoint((first & 7) << 18 | (second & 63) << 12 | (third & 63) << 6 | fourth & 63);\n index += 3;\n continue;\n }\n output += \"�\";\n if (isValidUtf8SecondForFourByte(first, second)) index += isUtf8Continuation(third) ? 2 : 1;\n continue;\n }\n output += \"�\";\n }\n return output;\n }\n function isUtf8Continuation(value) {\n return value !== void 0 && value >= 128 && value <= 191;\n }\n function isValidUtf8SecondForThreeByte(first, second) {\n if (second === void 0) return false;\n if (first === 224) return second >= 160 && second <= 191;\n if (first === 237) return second >= 128 && second <= 159;\n return second >= 128 && second <= 191;\n }\n function isValidUtf8SecondForFourByte(first, second) {\n if (second === void 0) return false;\n if (first === 240) return second >= 144 && second <= 191;\n if (first === 244) return second >= 128 && second <= 143;\n return second >= 128 && second <= 191;\n }\n var TextEncoderShim = class {\n encoding = \"utf-8\";\n encode(input = \"\") {\n return utf8Encode(String(input));\n }\n };\n var TextDecoderShim = class {\n encoding;\n constructor(label = \"utf-8\") {\n const normalized = label.toLowerCase();\n if (![\n \"utf-8\",\n \"utf8\",\n \"unicode-1-1-utf-8\"\n ].includes(normalized)) throw new TypeError(`Unsupported encoding: ${label}`);\n this.encoding = \"utf-8\";\n }\n decode(input) {\n if (input === void 0) return \"\";\n return utf8Decode(copyBytes(input));\n }\n };\n const textEncoder = new TextEncoderShim();\n const textDecoder = new TextDecoderShim();\n var URLSearchParamsShim = class URLSearchParamsShim {\n #entries = [];\n #onChange;\n constructor(init = \"\", onChange) {\n this.#onChange = onChange;\n if (typeof init === \"string\") {\n const source = init.startsWith(\"?\") ? init.slice(1) : init;\n if (!source) return;\n for (const pair of source.split(\"&\")) {\n if (!pair) continue;\n const separatorIndex = pair.indexOf(\"=\");\n const key = separatorIndex >= 0 ? pair.slice(0, separatorIndex) : pair;\n const value = separatorIndex >= 0 ? pair.slice(separatorIndex + 1) : \"\";\n this.#entries.push([decodeUrlParam(key), decodeUrlParam(value)]);\n }\n return;\n }\n if (init instanceof URLSearchParamsShim) {\n this.#entries = [...init.#entries];\n return;\n }\n if (Array.isArray(init)) {\n this.#entries = init.map(([key, value]) => [String(key), String(value)]);\n return;\n }\n this.#entries = Object.entries(init).map(([key, value]) => [key, String(value)]);\n }\n append(name, value) {\n this.#entries.push([String(name), String(value)]);\n this.#onChange?.();\n }\n delete(name) {\n const normalized = String(name);\n this.#entries = this.#entries.filter(([key]) => key !== normalized);\n this.#onChange?.();\n }\n entries() {\n return this.#entries[Symbol.iterator]();\n }\n forEach(callback) {\n for (const [key, value] of this.#entries) callback(value, key, this);\n }\n get(name) {\n return this.#entries.find(([key]) => key === String(name))?.[1] ?? null;\n }\n getAll(name) {\n return this.#entries.filter(([key]) => key === String(name)).map(([, value]) => value);\n }\n has(name) {\n return this.#entries.some(([key]) => key === String(name));\n }\n keys() {\n return this.#entries.map(([key]) => key)[Symbol.iterator]();\n }\n set(name, value) {\n const normalizedName = String(name);\n const normalizedValue = String(value);\n const next = [];\n let replaced = false;\n for (const entry of this.#entries) {\n if (entry[0] !== normalizedName) {\n next.push(entry);\n continue;\n }\n if (!replaced) {\n next.push([normalizedName, normalizedValue]);\n replaced = true;\n }\n }\n if (!replaced) next.push([normalizedName, normalizedValue]);\n this.#entries = next;\n this.#onChange?.();\n }\n toString() {\n return this.#entries.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join(\"&\");\n }\n values() {\n return this.#entries.map(([, value]) => value)[Symbol.iterator]();\n }\n [Symbol.iterator]() {\n return this.entries();\n }\n };\n function decodeUrlParam(value) {\n return decodeURIComponent(value.replace(/\\+/gu, \" \"));\n }\n function parseAbsoluteUrl(input) {\n const match = /^(?<protocol>[a-zA-Z][a-zA-Z\\d+.-]*:)\\/\\/(?<host>[^/?#]*)(?<pathname>[^?#]*)?(?<search>\\?[^#]*)?(?<hash>#.*)?$/u.exec(input);\n if (!match?.groups?.protocol || !match.groups.host) return;\n return {\n protocol: match.groups.protocol,\n host: match.groups.host,\n pathname: match.groups.pathname || \"/\",\n search: match.groups.search || \"\",\n hash: match.groups.hash || \"\"\n };\n }\n function normalizePathname(pathname) {\n const segments = [];\n for (const part of pathname.split(\"/\")) {\n if (!part || part === \".\") continue;\n if (part === \"..\") {\n segments.pop();\n continue;\n }\n segments.push(part);\n }\n return `/${segments.join(\"/\")}`;\n }\n function resolveUrl(input, base) {\n const absolute = parseAbsoluteUrl(input);\n if (absolute) return absolute;\n if (base === void 0) throw new TypeError(`Invalid URL: ${input}`);\n const baseUrl = base instanceof URLShim ? base : new URLShim(String(base));\n const basePath = baseUrl.pathname.endsWith(\"/\") ? baseUrl.pathname : baseUrl.pathname.slice(0, baseUrl.pathname.lastIndexOf(\"/\") + 1);\n const [beforeHash, rawHash = \"\"] = input.split(\"#\");\n const hasExplicitSearch = beforeHash?.includes(\"?\") ?? false;\n const [rawPath, rawSearch = \"\"] = (beforeHash ?? \"\").split(\"?\");\n const pathname = rawPath === \"\" && (input === \"\" || input.startsWith(\"?\") || input.startsWith(\"#\")) ? baseUrl.pathname : rawPath?.startsWith(\"/\") ? rawPath : `${basePath}${rawPath || \"\"}`;\n return {\n protocol: baseUrl.protocol,\n host: baseUrl.host,\n pathname: normalizePathname(pathname),\n search: hasExplicitSearch ? `?${rawSearch}` : rawPath === \"\" && (input === \"\" || input.startsWith(\"#\")) ? baseUrl.search : \"\",\n hash: rawHash ? `#${rawHash}` : \"\"\n };\n }\n var URLShim = class {\n host;\n hostname;\n origin;\n password = \"\";\n port;\n protocol;\n searchParams;\n username = \"\";\n hash;\n pathname;\n #search;\n constructor(input, base) {\n const parsed = resolveUrl(String(input), base);\n this.protocol = parsed.protocol;\n this.host = parsed.host;\n const portIndex = this.host.lastIndexOf(\":\");\n this.hostname = portIndex >= 0 ? this.host.slice(0, portIndex) : this.host;\n this.port = portIndex >= 0 ? this.host.slice(portIndex + 1) : \"\";\n this.pathname = parsed.pathname;\n this.#search = parsed.search;\n this.hash = parsed.hash;\n this.origin = `${this.protocol}//${this.host}`;\n this.searchParams = new URLSearchParamsShim(this.#search, () => {\n const next = this.searchParams.toString();\n this.#search = next ? `?${next}` : \"\";\n });\n }\n get href() {\n return `${this.origin}${this.pathname}${this.#search}${this.hash}`;\n }\n get search() {\n return this.#search;\n }\n toString() {\n return this.href;\n }\n toJSON() {\n return this.href;\n }\n };\n var ReadableStreamShim = class {\n #queue = [];\n #closed = false;\n #pulling = false;\n #source;\n #controller;\n #pending;\n constructor(source = {}) {\n this.#source = source;\n this.#controller = {\n enqueue: (value) => {\n if (this.#pending) {\n this.#pending.resolve({\n done: false,\n value\n });\n this.#pending = void 0;\n return;\n }\n this.#queue.push(value);\n },\n close: () => {\n this.#closed = true;\n if (this.#pending) {\n this.#pending.resolve({ done: true });\n this.#pending = void 0;\n }\n }\n };\n source.start?.(this.#controller);\n }\n async #pull() {\n if (this.#pulling || this.#closed || !this.#source.pull) return;\n this.#pulling = true;\n try {\n await this.#source.pull(this.#controller);\n } finally {\n this.#pulling = false;\n }\n }\n getReader() {\n return { read: async () => {\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n await this.#pull();\n if (this.#queue.length > 0) return {\n done: false,\n value: this.#queue.shift()\n };\n if (this.#closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n this.#pending = { resolve };\n this.#pull();\n });\n } };\n }\n };\n var WritableStreamShim = class {\n #sink;\n constructor(sink = {}) {\n this.#sink = sink;\n }\n getWriter() {\n return {\n write: async (chunk) => {\n await this.#sink.write?.(chunk);\n },\n close: async () => {\n await this.#sink.close?.();\n }\n };\n }\n };\n var TransformStreamShim = class {\n readable;\n writable;\n constructor(transformer = {}) {\n const queue = [];\n let closed = false;\n let pending;\n const controller = {\n enqueue: (value) => {\n if (pending) {\n pending.resolve({\n done: false,\n value\n });\n pending = void 0;\n return;\n }\n queue.push(value);\n },\n close: () => {\n closed = true;\n if (pending) {\n pending.resolve({ done: true });\n pending = void 0;\n }\n }\n };\n this.readable = { getReader() {\n return { read: async () => {\n if (queue.length > 0) return {\n done: false,\n value: queue.shift()\n };\n if (closed) return {\n done: true,\n value: void 0\n };\n return await new Promise((resolve) => {\n pending = { resolve };\n });\n } };\n } };\n this.writable = new WritableStreamShim({\n write: async (chunk) => {\n transformer.transform?.(chunk, controller);\n },\n close: async () => {\n transformer.flush?.(controller);\n controller.close();\n }\n });\n }\n };\n function definePlatformGlobal(name, value, options = {}) {\n if (!options.overwrite && name in globalThis) return;\n Object.defineProperty(globalThis, name, {\n value,\n writable: true,\n configurable: true\n });\n }\n function formatLogArg(value) {\n if (typeof value === \"string\") return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n function formatLogLine(args) {\n return args.map(formatLogArg).join(\" \");\n }\n const platformConsole = {\n log: (...args) => __caplets_log(\"log\", formatLogLine(args)),\n info: (...args) => __caplets_log(\"info\", formatLogLine(args)),\n warn: (...args) => __caplets_log(\"warn\", formatLogLine(args)),\n error: (...args) => __caplets_log(\"error\", formatLogLine(args)),\n debug: (...args) => __caplets_log(\"debug\", formatLogLine(args))\n };\n function normalizeEncoding(encoding) {\n const normalized = (encoding ?? \"utf8\").toLowerCase();\n switch (normalized) {\n case \"utf8\":\n case \"utf-8\":\n case \"base64\":\n case \"base64url\":\n case \"hex\": return normalized;\n default: throw new TypeError(`Unsupported Buffer encoding: ${encoding}`);\n }\n }\n function hexToBytes(value) {\n if (value.length % 2 !== 0) throw new TypeError(\"Invalid hex string length\");\n const bytes = new Uint8Array(value.length / 2);\n for (let index = 0; index < value.length; index += 2) {\n const parsed = Number.parseInt(value.slice(index, index + 2), 16);\n if (Number.isNaN(parsed)) throw new TypeError(\"Invalid hex string\");\n bytes[index / 2] = parsed;\n }\n return bytes;\n }\n function bytesToHex(bytes) {\n return Array.from(bytes, (value) => value.toString(16).padStart(2, \"0\")).join(\"\");\n }\n function base64ToBytes(value, encoding) {\n let normalized = value.replace(/\\s+/gu, \"\");\n if (encoding === \"base64url\") normalized = normalized.replace(/-/gu, \"+\").replace(/_/gu, \"/\");\n const padding = normalized.length % 4;\n if (padding === 1) throw new TypeError(\"Invalid base64 string\");\n if (padding > 0) normalized = normalized.padEnd(normalized.length + (4 - padding), \"=\");\n const output = [];\n for (let index = 0; index < normalized.length; index += 4) {\n const values = normalized.slice(index, index + 4).split(\"\").map((char) => char === \"=\" ? 64 : base64Lookup.get(char) ?? NaN);\n if (values.some((entry) => Number.isNaN(entry))) throw new TypeError(\"Invalid base64 string\");\n const [a = 0, b = 0, c = 64, d = 64] = values;\n const triple = a << 18 | b << 12 | (c & 63) << 6 | d & 63;\n output.push(triple >> 16 & 255);\n if (c !== 64) output.push(triple >> 8 & 255);\n if (d !== 64) output.push(triple & 255);\n }\n return Uint8Array.from(output);\n }\n function bytesToBase64(bytes, encoding) {\n let output = \"\";\n for (let index = 0; index < bytes.length; index += 3) {\n const a = bytes[index] ?? 0;\n const b = bytes[index + 1] ?? 0;\n const c = bytes[index + 2] ?? 0;\n const triple = a << 16 | b << 8 | c;\n output += BASE64_ALPHABET[triple >> 18 & 63];\n output += BASE64_ALPHABET[triple >> 12 & 63];\n output += index + 1 < bytes.length ? BASE64_ALPHABET[triple >> 6 & 63] : \"=\";\n output += index + 2 < bytes.length ? BASE64_ALPHABET[triple & 63] : \"=\";\n }\n if (encoding === \"base64url\") return output.replace(/\\+/gu, \"-\").replace(/\\//gu, \"_\").replace(/=+$/gu, \"\");\n return output;\n }\n function copyBytes(input) {\n if (input instanceof ArrayBuffer) return new Uint8Array(input.slice(0));\n return new Uint8Array(input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength));\n }\n function toBytes(input, encoding) {\n if (input instanceof BufferShim) return input.toUint8Array();\n if (typeof input === \"string\") switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textEncoder.encode(input);\n case \"base64\":\n case \"base64url\": return base64ToBytes(input, normalizeEncoding(encoding));\n case \"hex\": return hexToBytes(input);\n }\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n if (Array.isArray(input)) return Uint8Array.from(input);\n throw new TypeError(\"Buffer.from only supports strings, arrays, ArrayBuffers, and typed arrays\");\n }\n var BufferShim = class BufferShim {\n #bytes;\n byteLength;\n length;\n constructor(bytes) {\n this.#bytes = bytes;\n this.byteLength = bytes.byteLength;\n this.length = bytes.length;\n }\n static from(input, encoding) {\n return new BufferShim(toBytes(input, encoding));\n }\n static isBuffer(value) {\n return value instanceof BufferShim;\n }\n static byteLength(input, encoding) {\n return toBytes(input, encoding).byteLength;\n }\n toUint8Array() {\n return new Uint8Array(this.#bytes);\n }\n toString(encoding) {\n switch (normalizeEncoding(encoding)) {\n case \"utf8\":\n case \"utf-8\": return textDecoder.decode(this.#bytes);\n case \"base64\":\n case \"base64url\": return bytesToBase64(this.#bytes, normalizeEncoding(encoding));\n case \"hex\": return bytesToHex(this.#bytes);\n }\n }\n };\n function atobShim(input) {\n return Array.from(base64ToBytes(String(input), \"base64\"), (value) => String.fromCharCode(value)).join(\"\");\n }\n function btoaShim(input) {\n const bytes = new Uint8Array(input.length);\n for (let index = 0; index < input.length; index += 1) {\n const codePoint = input.charCodeAt(index);\n if (codePoint > 255) throw new TypeError(\"The string to be encoded contains characters outside of Latin1\");\n bytes[index] = codePoint;\n }\n return bytesToBase64(bytes, \"base64\");\n }\n function queueMicrotaskShim(callback) {\n Promise.resolve().then(callback);\n }\n var AbortSignalShim = class AbortSignalShim {\n aborted = false;\n reason;\n onabort = null;\n #listeners = /* @__PURE__ */ new Set();\n addEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.add(listener);\n }\n removeEventListener(type, listener) {\n if (type === \"abort\" && listener) this.#listeners.delete(listener);\n }\n dispatchEvent(event) {\n if (event.type !== \"abort\") return true;\n this.onabort?.(event);\n for (const listener of this.#listeners) listener(event);\n return true;\n }\n throwIfAborted() {\n if (this.aborted) throw this.reason ?? /* @__PURE__ */ new Error(\"Operation was aborted\");\n }\n static abort(reason) {\n const signal = new AbortSignalShim();\n signal.abort(reason);\n return signal;\n }\n abort(reason) {\n if (this.aborted) return;\n this.aborted = true;\n this.reason = reason;\n this.dispatchEvent({\n type: \"abort\",\n target: this\n });\n }\n };\n var AbortControllerShim = class {\n signal = new AbortSignalShim();\n abort(reason) {\n this.signal.abort(reason);\n }\n };\n function cloneFormData(input) {\n const clone = new FormData();\n for (const [name, value] of input.entries()) {\n if (value instanceof File) {\n clone.append(name, new File([value], value.name, { type: value.type }), value.name);\n continue;\n }\n clone.append(name, value);\n }\n return clone;\n }\n function cloneBodyValue(input) {\n if (input === null || input === void 0 || typeof input === \"string\") return input;\n if (input instanceof FormData) return cloneFormData(input);\n if (input instanceof Blob) return input.slice(0, input.size, input.type);\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return copyBytes(input);\n return input;\n }\n function blobFromBody(input) {\n if (input instanceof Blob) return input;\n if (typeof input === \"string\") return new Blob([input], { type: \"text/plain;charset=utf-8\" });\n if (input instanceof FormData) throw new TypeError(\"FormData body reading is not supported in Code Mode\");\n if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) return new Blob([copyBytes(input)]);\n return new Blob([]);\n }\n var BodyMixin = class {\n _bodyInit;\n bodyUsed = false;\n body = null;\n constructor(body) {\n this._bodyInit = cloneBodyValue(body);\n }\n async arrayBuffer() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).arrayBuffer();\n }\n async blob() {\n this.bodyUsed = true;\n return blobFromBody(this._bodyInit);\n }\n async formData() {\n this.bodyUsed = true;\n if (this._bodyInit instanceof FormData) return cloneFormData(this._bodyInit);\n throw new TypeError(\"Body does not contain FormData\");\n }\n async json() {\n return JSON.parse(await this.text());\n }\n async text() {\n this.bodyUsed = true;\n return await blobFromBody(this._bodyInit).text();\n }\n };\n function toHeaders(init) {\n return init instanceof Headers ? new Headers(init) : new Headers(init ?? {});\n }\n function normalizeMethod(method) {\n return String(method ?? \"GET\").toUpperCase();\n }\n var RequestShim = class RequestShim extends BodyMixin {\n headers;\n method;\n signal;\n url;\n constructor(input, init = {}) {\n const sourceBody = input instanceof RequestShim ? input._bodyInit : void 0;\n super(init.body ?? sourceBody);\n if (input instanceof RequestShim) this.url = input.url;\n else this.url = input instanceof URLShim ? input.href : new URLShim(String(input)).href;\n this.method = normalizeMethod(init.method ?? (input instanceof RequestShim ? input.method : \"GET\"));\n this.headers = toHeaders(init.headers ?? (input instanceof RequestShim ? input.headers : void 0));\n this.signal = init.signal ?? (input instanceof RequestShim ? input.signal : new AbortControllerShim().signal);\n }\n clone() {\n return new RequestShim(this, {\n method: this.method,\n headers: this.headers,\n body: this._bodyInit,\n signal: this.signal\n });\n }\n };\n var ResponseShim = class ResponseShim extends BodyMixin {\n headers;\n ok;\n redirected = false;\n status;\n statusText;\n type = \"default\";\n url = \"\";\n constructor(body, init = {}) {\n super(body);\n this.status = init.status ?? 200;\n this.statusText = init.statusText ?? \"\";\n this.headers = toHeaders(init.headers);\n this.ok = this.status >= 200 && this.status <= 299;\n }\n clone() {\n return new ResponseShim(this._bodyInit, {\n headers: this.headers,\n status: this.status,\n statusText: this.statusText\n });\n }\n static json(data, init) {\n const headers = toHeaders(init?.headers);\n if (!headers.has(\"content-type\")) headers.set(\"content-type\", \"application/json\");\n const responseInit = { headers };\n if (init?.status !== void 0) responseInit.status = init.status;\n if (init?.statusText !== void 0) responseInit.statusText = init.statusText;\n return new ResponseShim(JSON.stringify(data), responseInit);\n }\n };\n function disabledFetch() {\n throw new Error(DISABLED_FETCH_MESSAGE);\n }\n const integerTypedArrayConstructors = /* @__PURE__ */ new Set([\n Int8Array,\n Uint8Array,\n Uint8ClampedArray,\n Int16Array,\n Uint16Array,\n Int32Array,\n Uint32Array,\n typeof BigInt64Array === \"undefined\" ? void 0 : BigInt64Array,\n typeof BigUint64Array === \"undefined\" ? void 0 : BigUint64Array\n ]);\n var QuotaExceededErrorShim = class extends Error {\n constructor(message) {\n super(message);\n this.name = \"QuotaExceededError\";\n }\n };\n const platformCrypto = {\n randomUUID() {\n const randomUUID = capletsPlatformHost.randomUUID;\n if (!randomUUID) throw new Error(\"Code Mode platform random UUID bridge is not installed\");\n return randomUUID();\n },\n getRandomValues(typedArray) {\n if (!ArrayBuffer.isView(typedArray) || typedArray instanceof DataView) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (!integerTypedArrayConstructors.has(typedArray.constructor)) throw new TypeError(\"crypto.getRandomValues requires an integer typed array\");\n if (typedArray.byteLength > 65536) throw new QuotaExceededErrorShim(\"crypto.getRandomValues cannot generate more than 65,536 bytes\");\n const randomValues = capletsPlatformHost.randomValues;\n if (!randomValues) throw new Error(\"Code Mode platform random values bridge is not installed\");\n const bytes = randomValues(typedArray.byteLength);\n new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength).set(bytes);\n return typedArray;\n }\n };\n let nextTimerId = 1;\n const activeTimers = /* @__PURE__ */ new Set();\n function normalizeTimerDelay(delay) {\n const value = Number(delay ?? 0);\n if (!Number.isFinite(value) || value <= 0) return 0;\n return Math.trunc(value);\n }\n function setTimeoutShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setTimeout callback must be a function\");\n const timerId = nextTimerId++;\n activeTimers.add(timerId);\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, normalizeTimerDelay(delay)).then((fired) => {\n activeTimers.delete(timerId);\n if (fired) callback(...args);\n });\n return timerId;\n }\n function clearTimeoutShim(timerId) {\n const id = Number(timerId);\n activeTimers.delete(id);\n capletsPlatformHost.clearTimer?.(id);\n }\n function setIntervalShim(callback, delay, ...args) {\n if (typeof callback !== \"function\") throw new TypeError(\"setInterval callback must be a function\");\n const timerId = nextTimerId++;\n const intervalDelay = normalizeTimerDelay(delay);\n activeTimers.add(timerId);\n const tick = () => {\n const sleep = capletsPlatformHost.sleep;\n if (!sleep) throw new Error(\"Code Mode platform sleep bridge is not installed\");\n sleep(timerId, intervalDelay).then((fired) => {\n if (!fired || !activeTimers.has(timerId)) {\n activeTimers.delete(timerId);\n return;\n }\n callback(...args);\n if (activeTimers.has(timerId)) tick();\n });\n };\n tick();\n return timerId;\n }\n function clearIntervalShim(timerId) {\n clearTimeoutShim(timerId);\n }\n definePlatformGlobal(\"atob\", atobShim);\n definePlatformGlobal(\"btoa\", btoaShim);\n definePlatformGlobal(\"Buffer\", BufferShim);\n definePlatformGlobal(\"TextEncoder\", TextEncoderShim);\n definePlatformGlobal(\"TextDecoder\", TextDecoderShim);\n definePlatformGlobal(\"URL\", URLShim);\n definePlatformGlobal(\"URLSearchParams\", URLSearchParamsShim);\n definePlatformGlobal(\"structuredClone\", esm_default);\n definePlatformGlobal(\"Headers\", Headers);\n definePlatformGlobal(\"Blob\", Blob);\n definePlatformGlobal(\"File\", File);\n definePlatformGlobal(\"FormData\", FormData);\n definePlatformGlobal(\"ReadableStream\", ReadableStreamShim);\n definePlatformGlobal(\"WritableStream\", WritableStreamShim);\n definePlatformGlobal(\"TransformStream\", TransformStreamShim);\n definePlatformGlobal(\"AbortController\", AbortControllerShim);\n definePlatformGlobal(\"AbortSignal\", AbortSignalShim);\n definePlatformGlobal(\"Request\", RequestShim);\n definePlatformGlobal(\"Response\", ResponseShim);\n definePlatformGlobal(\"crypto\", platformCrypto);\n definePlatformGlobal(\"setTimeout\", setTimeoutShim);\n definePlatformGlobal(\"clearTimeout\", clearTimeoutShim);\n definePlatformGlobal(\"setInterval\", setIntervalShim);\n definePlatformGlobal(\"clearInterval\", clearIntervalShim);\n definePlatformGlobal(\"queueMicrotask\", queueMicrotaskShim);\n definePlatformGlobal(\"console\", platformConsole);\n definePlatformGlobal(\"fetch\", disabledFetch, { overwrite: true });\n //#endregion\n})();";
77795
78402
  //#endregion
77796
78403
  //#region src/code-mode/sandbox.ts
77797
- const CODE_MODE_SANDBOX_METHODS = new Set([
78404
+ const CODE_MODE_SANDBOX_METHODS = /* @__PURE__ */ new Set([
77798
78405
  "inspect",
77799
78406
  "check",
77800
78407
  "tools",
@@ -77812,7 +78419,7 @@ const CODE_MODE_SANDBOX_METHODS = new Set([
77812
78419
  "readLogs",
77813
78420
  "readRecovery"
77814
78421
  ]);
77815
- const CODE_MODE_DEBUG_METHODS = new Set(["readLogs", "readRecovery"]);
78422
+ const CODE_MODE_DEBUG_METHODS = /* @__PURE__ */ new Set(["readLogs", "readRecovery"]);
77816
78423
  var QuickJsCodeModeSandbox = class {
77817
78424
  async run(input) {
77818
78425
  return await evaluateInQuickJs(input);
@@ -78822,7 +79429,7 @@ function splitPersistentPrelude(javascript, existingNames = [], checkpointToken
78822
79429
  const ranges = [];
78823
79430
  const names = collectPersistentBindingNames(source);
78824
79431
  const lexicalNames = collectTopLevelLexicalBindingNames(source);
78825
- const allNames = [...new Set([...existingNames, ...names])];
79432
+ const allNames = [.../* @__PURE__ */ new Set([...existingNames, ...names])];
78826
79433
  const snapshotNames = allNames.filter((name) => !lexicalNames.has(name));
78827
79434
  const returnTempName = uniqueInternalName("__caplets_return", allNames);
78828
79435
  const postlude = snapshotNames.map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
@@ -78855,7 +79462,7 @@ function collectPersistentReturnRanges(node, source, snapshotNames, ranges, retu
78855
79462
  if (snapshotNames.length === 0) return;
78856
79463
  if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78857
79464
  const declared = lexicalNamesDeclaredByNode(node);
78858
- const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
79465
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : /* @__PURE__ */ new Set([...shadowedNames, ...declared]);
78859
79466
  if (ts.isReturnStatement(node)) {
78860
79467
  const expression = node.expression?.getText(source);
78861
79468
  const postludeExpression = snapshotNames.filter((name) => !activeShadowedNames.has(name)).map((name) => persistentBindingExpression(name, checkpointToken)).join(", ");
@@ -78920,10 +79527,10 @@ function collectPersistentFinallyRanges(node, snapshotNames, ranges, checkpointT
78920
79527
  if (snapshotNames.length === 0) return;
78921
79528
  if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78922
79529
  const declared = lexicalNamesDeclaredByNode(node);
78923
- const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
79530
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : /* @__PURE__ */ new Set([...shadowedNames, ...declared]);
78924
79531
  if (ts.isTryStatement(node) && node.finallyBlock) {
78925
79532
  const finallyDeclared = lexicalNamesDeclaredByNode(node.finallyBlock);
78926
- const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : new Set([...activeShadowedNames, ...finallyDeclared]);
79533
+ const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : /* @__PURE__ */ new Set([...activeShadowedNames, ...finallyDeclared]);
78927
79534
  const postlude = snapshotNames.filter((name) => !finallyShadowedNames.has(name)).map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
78928
79535
  if (postlude) ranges.push({
78929
79536
  start: node.finallyBlock.end - 1,
@@ -80061,6 +80668,79 @@ var CapletsCloudClient = class {
80061
80668
  });
80062
80669
  if (!response.ok) throw new Error(`Caplets Cloud Project Binding update failed: HTTP ${response.status}`);
80063
80670
  }
80671
+ async setVaultValue(input) {
80672
+ const response = await this.fetchImpl(this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/values/${encodeURIComponent(input.name)}`), {
80673
+ method: "PUT",
80674
+ headers: this.headers({ json: true }),
80675
+ body: JSON.stringify({
80676
+ value: input.value,
80677
+ force: Boolean(input.force),
80678
+ ...input.grant ? { grant: input.grant } : {},
80679
+ ...input.referenceName ? { referenceName: input.referenceName } : {}
80680
+ })
80681
+ });
80682
+ if (!response.ok) throw new Error(`Caplets Cloud Vault set failed: HTTP ${response.status}`);
80683
+ return await response.json();
80684
+ }
80685
+ async getVaultValue(input) {
80686
+ const url = this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/values/${encodeURIComponent(input.name)}`);
80687
+ if (input.reveal) {
80688
+ url.searchParams.set("reveal", "true");
80689
+ url.searchParams.set("revealContext", input.revealContext ?? "human-cli");
80690
+ }
80691
+ const response = await this.fetchImpl(url, {
80692
+ method: "GET",
80693
+ headers: this.headers()
80694
+ });
80695
+ if (!response.ok) throw new Error(`Caplets Cloud Vault get failed: HTTP ${response.status}`);
80696
+ return await response.json();
80697
+ }
80698
+ async listVaultValues(input) {
80699
+ const response = await this.fetchImpl(this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/values`), {
80700
+ method: "GET",
80701
+ headers: this.headers()
80702
+ });
80703
+ if (!response.ok) throw new Error(`Caplets Cloud Vault list failed: HTTP ${response.status}`);
80704
+ return await response.json();
80705
+ }
80706
+ async deleteVaultValue(input) {
80707
+ const response = await this.fetchImpl(this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/values/${encodeURIComponent(input.name)}`), {
80708
+ method: "DELETE",
80709
+ headers: this.headers()
80710
+ });
80711
+ if (!response.ok) throw new Error(`Caplets Cloud Vault delete failed: HTTP ${response.status}`);
80712
+ return await response.json();
80713
+ }
80714
+ async grantVaultAccess(input) {
80715
+ const response = await this.fetchImpl(this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/access/${encodeURIComponent(input.name)}/${encodeURIComponent(input.capletId)}`), {
80716
+ method: "PUT",
80717
+ headers: this.headers({ json: true }),
80718
+ body: JSON.stringify({ referenceName: input.referenceName ?? input.name })
80719
+ });
80720
+ if (!response.ok) throw new Error(`Caplets Cloud Vault access grant failed: HTTP ${response.status}`);
80721
+ return await response.json();
80722
+ }
80723
+ async listVaultAccess(input) {
80724
+ const url = this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/access`);
80725
+ if (input.name) url.searchParams.set("name", input.name);
80726
+ if (input.capletId) url.searchParams.set("capletId", input.capletId);
80727
+ const response = await this.fetchImpl(url, {
80728
+ method: "GET",
80729
+ headers: this.headers()
80730
+ });
80731
+ if (!response.ok) throw new Error(`Caplets Cloud Vault access list failed: HTTP ${response.status}`);
80732
+ return await response.json();
80733
+ }
80734
+ async revokeVaultAccess(input) {
80735
+ const url = this.endpoint(`api/workspaces/${encodeURIComponent(input.workspace)}/vault/access/${encodeURIComponent(input.name)}/${encodeURIComponent(input.capletId)}`);
80736
+ if (input.referenceName) url.searchParams.set("referenceName", input.referenceName);
80737
+ const response = await this.fetchImpl(url, {
80738
+ method: "DELETE",
80739
+ headers: this.headers()
80740
+ });
80741
+ if (!response.ok) throw new Error(`Caplets Cloud Vault access revoke failed: HTTP ${response.status}`);
80742
+ return await response.json();
80743
+ }
80064
80744
  headers(options = {}) {
80065
80745
  const headers = new Headers();
80066
80746
  headers.set("authorization", `Bearer ${this.options.accessToken}`);
@@ -82771,7 +83451,7 @@ var CompositeNativeCapletsService = class {
82771
83451
  return localExecutionKeys(this.local.listTools(), capletId).some((key) => !remoteIds.has(key));
82772
83452
  }
82773
83453
  warnShadowedLocalCaplets(localTools, remoteIds) {
82774
- const localIds = new Set([...localTools.filter((tool) => tool.codeModeRun !== true).map((tool) => tool.sourceCaplet ?? tool.caplet), ...codeModeCallableNativeTools(localTools, { fallbackToVisible: false }).map((tool) => tool.caplet)]);
83454
+ const localIds = /* @__PURE__ */ new Set([...localTools.filter((tool) => tool.codeModeRun !== true).map((tool) => tool.sourceCaplet ?? tool.caplet), ...codeModeCallableNativeTools(localTools, { fallbackToVisible: false }).map((tool) => tool.caplet)]);
82775
83455
  for (const capletId of localIds) {
82776
83456
  if (!remoteIds.has(capletId)) continue;
82777
83457
  if (this.warnedShadowedLocalCaplets.has(capletId)) continue;
@@ -82867,4 +83547,4 @@ function errorMessage(error) {
82867
83547
  return error instanceof Error ? error.message : String(error);
82868
83548
  }
82869
83549
  //#endregion
82870
- export { decodeDirectResourceUri as $, ElicitResultSchema as $t, nativeCapletToolDescription as A, objectFromShape as An, defaultCacheBaseDir as At, QuickJsCodeModeSandbox as B, assertClientRequestTaskCapability as Bt, resolveRemoteMode as C, getLiteralValue as Cn, startOAuthFlow as Ct, parseServerBaseUrl as D, isSchemaOptional as Dn, DEFAULT_AUTH_DIR as Dt, isLoopbackHost as E, getSchemaDescription as En, readTokenBundle as Et, codeModeRunInputSchema as F, resolveConfigPath as Ft, CodeModeLogStore as G, toJsonSchemaCompat as Gt, createCodeModeCapletsApi as H, AjvJsonSchemaValidator as Ht, codeModeRunParamsSchema as I, resolveProjectCapletsRoot as It, generateCodeModeDeclarations as J, CompleteRequestSchema as Jt, redactCodeModeLogText as K, CallToolRequestSchema as Kt, emptyCodeModeRunMeta as L, resolveProjectConfigPath as Lt, nativeCapletsSystemGuidance as M, safeParseAsync as Mn, defaultConfigPath as Mt, nativeCodeModeToolId as N, __exportAll as Nn, defaultStateBaseDir as Nt, resolveCapletsServer as O, isZ4Schema as On, DEFAULT_COMPLETION_CACHE_DIR as Ot, nativeCodeModeToolName as P, resolveCapletsRoot as Pt, resolveExposure as Q, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as Qt, runCodeMode as R, ReadBuffer as Rt, resolveHostedCloudRemote as S, isJSONRPCResultResponse as Sn, startGenericOAuthFlow as St, controlUrlForBase as T, getParseErrorMessage as Tn, isTokenBundleExpired as Tt, listCodeModeCallableCaplets as U, Protocol as Ut, diagnoseCodeModeTypeScript as V, assertToolsCallTaskCapability as Vt, CodeModeJournalStore as W, mergeCapabilities as Wt, minifyCodeModeDeclarationText as X, CreateMessageResultWithToolsSchema as Xt, generateCodeModeRunToolDescription as Y, CreateMessageResultSchema as Yt, CapletsEngine as Z, CreateTaskResultSchema as Zt, resolveNativeCapletsServiceOptions as _, assertCompleteRequestPrompt as _n, markdownCallToolResultContent as _t, CloudAuthStore as a, JSONRPCMessageSchema as an, capabilityDescription as at, normalizeRemoteProfileHostUrl as b, isJSONRPCErrorResponse as bn, runGenericOAuthFlow as bt, redactedCloudAuthStatus as c, ListResourceTemplatesRequestSchema as cn, loadConfigWithSources as ct, projectBindingError as d, ListToolsRequestSchema as dn, loadProjectConfig as dt, EmptyResultSchema as en, directResourceUriMatchesTemplate as et, projectBindingRecovery as f, LoggingLevelSchema as fn, parseConfig as ft, buildProjectSyncManifest as g, SetLevelRequestSchema as gn, hasRenderableStructuredContent as gt, createSdkRemoteCapletsClient as h, SUPPORTED_PROTOCOL_VERSIONS as hn, loadCapletFilesFromMap as ht, createRemoteProfileStore as i, InitializedNotificationSchema as in, ServerRegistry as it, nativeCapletToolName as j, safeParse as jn, defaultConfigBaseDir as jt, nativeCapletPromptGuidance as k, normalizeObjectSchema as kn, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as kt, PROJECT_BINDING_ERROR_CODES as l, ListResourcesRequestSchema as ln, loadGlobalConfig as lt, RemoteNativeCapletsService as m, ReadResourceRequestSchema as mn, validateCapletFile as mt, resolveRemoteSelection as n, GetPromptRequestSchema as nn, fingerprintProjectRoot as nt, cloudAuthPath as o, LATEST_PROTOCOL_VERSION as on, GoogleDiscoveryManager as ot, CloudAuthClient as p, McpError as pn, discoverCapletFiles as pt, codeModeDeclarationHash as q, CallToolResultSchema as qt, cloudCredentialsFromRemoteProfile as r, InitializeRequestSchema as rn, handleServerTool as rt, migrateCredentials as s, ListPromptsRequestSchema as sn, loadConfig as st, createNativeCapletsService as t, ErrorCode as tn, findProjectRoot as tt, ProjectBindingError as u, ListRootsResultSchema as un, loadLocalOverlayConfigWithSources as ut, hostedCloudWorkspaceFromRemoteUrl as v, assertCompleteRequestResourceTemplate as vn, markdownStructuredContent as vt, appendBasePath as w, getObjectShape as wn, deleteTokenBundle as wt, resolveCapletsRemote as x, isJSONRPCRequest as xn, runOAuthFlow as xt, isCapletsCloudUrl as y, isInitializeRequest as yn, refreshOAuthTokenBundle as yt, CodeModeSessionManager as z, serializeMessage as zt };
83550
+ export { resolveExposure as $, CallToolRequestSchema as $t, nativeCapletPromptGuidance as A, getLiteralValue as An, startOAuthFlow as At, CodeModeSessionManager as B, __exportAll as Bn, defaultStateBaseDir as Bt, resolveHostedCloudRemote as C, SetLevelRequestSchema as Cn, hasRenderableStructuredContent as Ct, isLoopbackHost as D, isJSONRPCErrorResponse as Dn, runGenericOAuthFlow as Dt, controlUrlForBase as E, isInitializeRequest as En, refreshOAuthTokenBundle as Et, nativeCodeModeToolName as F, isZ4Schema as Fn, DEFAULT_COMPLETION_CACHE_DIR as Ft, CodeModeJournalStore as G, ReadBuffer as Gt, diagnoseCodeModeTypeScript as H, resolveConfigPath as Ht, codeModeRunInputSchema as I, normalizeObjectSchema as In, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as It, codeModeDeclarationHash as J, assertToolsCallTaskCapability as Jt, CodeModeLogStore as K, serializeMessage as Kt, codeModeRunParamsSchema as L, objectFromShape as Ln, defaultCacheBaseDir as Lt, nativeCapletToolName as M, getParseErrorMessage as Mn, isTokenBundleExpired as Mt, nativeCapletsSystemGuidance as N, getSchemaDescription as Nn, readTokenBundle as Nt, parseServerBaseUrl as O, isJSONRPCRequest as On, runOAuthFlow as Ot, nativeCodeModeToolId as P, isSchemaOptional as Pn, DEFAULT_AUTH_DIR as Pt, CapletsEngine as Q, toJsonSchemaCompat as Qt, emptyCodeModeRunMeta as R, safeParse as Rn, defaultConfigBaseDir as Rt, resolveCapletsRemote as S, SUPPORTED_PROTOCOL_VERSIONS as Sn, loadCapletFilesFromMap as St, appendBasePath as T, assertCompleteRequestResourceTemplate as Tn, markdownStructuredContent as Tt, createCodeModeCapletsApi as U, resolveProjectCapletsRoot as Ut, QuickJsCodeModeSandbox as V, resolveCapletsRoot as Vt, listCodeModeCallableCaplets as W, resolveProjectConfigPath as Wt, generateCodeModeRunToolDescription as X, Protocol as Xt, generateCodeModeDeclarations as Y, AjvJsonSchemaValidator as Yt, minifyCodeModeDeclarationText as Z, mergeCapabilities as Zt, CapletsCloudClient as _, ListRootsResultSchema as _n, FileVaultStore as _t, CloudAuthStore as a, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as an, ServerRegistry as at, isCapletsCloudUrl as b, McpError as bn, discoverCapletFiles as bt, redactedCloudAuthStatus as c, ErrorCode as cn, loadConfig as ct, projectBindingError as d, InitializedNotificationSchema as dn, loadLocalOverlayConfigWithSources as dt, CallToolResultSchema as en, decodeDirectResourceUri as et, projectBindingRecovery as f, JSONRPCMessageSchema as fn, loadProjectConfig as ft, buildProjectSyncManifest as g, ListResourcesRequestSchema as gn, vaultStoreForAuthDir as gt, createSdkRemoteCapletsClient as h, ListResourceTemplatesRequestSchema as hn, vaultResolverForAuthDir as ht, createRemoteProfileStore as i, CreateTaskResultSchema as in, handleServerTool as it, nativeCapletToolDescription as j, getObjectShape as jn, deleteTokenBundle as jt, resolveCapletsServer as k, isJSONRPCResultResponse as kn, startGenericOAuthFlow as kt, PROJECT_BINDING_ERROR_CODES as l, GetPromptRequestSchema as ln, loadConfigWithSources as lt, RemoteNativeCapletsService as m, ListPromptsRequestSchema as mn, vaultBootstrapResolver as mt, resolveRemoteSelection as n, CreateMessageResultSchema as nn, findProjectRoot as nt, cloudAuthPath as o, ElicitResultSchema as on, capabilityDescription as ot, CloudAuthClient as p, LATEST_PROTOCOL_VERSION as pn, parseConfig as pt, redactCodeModeLogText as q, assertClientRequestTaskCapability as qt, cloudCredentialsFromRemoteProfile as r, CreateMessageResultWithToolsSchema as rn, fingerprintProjectRoot as rt, migrateCredentials as s, EmptyResultSchema as sn, GoogleDiscoveryManager as st, createNativeCapletsService as t, CompleteRequestSchema as tn, directResourceUriMatchesTemplate as tt, ProjectBindingError as u, InitializeRequestSchema as un, loadGlobalConfig as ut, resolveNativeCapletsServiceOptions as v, ListToolsRequestSchema as vn, VAULT_MAX_VALUE_BYTES as vt, resolveRemoteMode as w, assertCompleteRequestPrompt as wn, markdownCallToolResultContent as wt, normalizeRemoteProfileHostUrl as x, ReadResourceRequestSchema as xn, validateCapletFile as xt, hostedCloudWorkspaceFromRemoteUrl as y, LoggingLevelSchema as yn, validateVaultKeyName as yt, runCodeMode as z, safeParseAsync as zn, defaultConfigPath as zt };