@caplets/core 0.23.0 → 0.24.1

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.
@@ -9,7 +9,7 @@ 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, randomBytes, randomUUID } from "node:crypto";
12
+ import { createHash, createHmac, randomBytes, randomUUID } from "node:crypto";
13
13
  import { homedir } from "node:os";
14
14
  import { readFile } from "node:fs/promises";
15
15
  import ts from "typescript";
@@ -27102,6 +27102,16 @@ const publicCapletSetSchema = object$1({
27102
27102
  });
27103
27103
  });
27104
27104
  const normalizedCapletSetSchema = publicCapletSetSchema.extend({ body: string().optional() });
27105
+ const CAPLET_BACKEND_KEYS = [
27106
+ "mcpServers",
27107
+ "openapiEndpoints",
27108
+ "googleDiscoveryApis",
27109
+ "graphqlEndpoints",
27110
+ "httpApis",
27111
+ "cliTools",
27112
+ "capletSets"
27113
+ ];
27114
+ const CAPLET_BACKEND_KEY_SET = new Set(CAPLET_BACKEND_KEYS);
27105
27115
  function configSchemaFor(serverValueSchema, openApiEndpointValueSchema, googleDiscoveryApiValueSchema, graphQlEndpointValueSchema, httpApiValueSchema, cliToolsValueSchema, capletSetValueSchema) {
27106
27116
  return object$1({
27107
27117
  $schema: string().optional().describe("Optional JSON Schema for editor validation."),
@@ -27555,8 +27565,11 @@ function loadLocalOverlayConfigWithSources(path = resolveConfigPath(), projectPa
27555
27565
  }
27556
27566
  function readBestEffortConfigInput(path, kind, warnings, transform) {
27557
27567
  try {
27558
- const input = readPublicConfigInput(path);
27559
- return transform ? transform(input) : input;
27568
+ const normalized = normalizeLocalPaths(readBestEffortJsonConfigInput(path), dirname(path));
27569
+ const filtered = quarantineMissingEnvCaplets(transform ? transform(normalized) : normalized, kind, path, warnings);
27570
+ const parsed = configFileSchema.safeParse(interpolateConfig(filtered));
27571
+ if (!parsed.success) throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is invalid`, parsed.error.issues);
27572
+ return filtered;
27560
27573
  } catch (error) {
27561
27574
  warnings.push({
27562
27575
  kind,
@@ -27566,6 +27579,55 @@ function readBestEffortConfigInput(path, kind, warnings, transform) {
27566
27579
  return;
27567
27580
  }
27568
27581
  }
27582
+ function readBestEffortJsonConfigInput(path) {
27583
+ try {
27584
+ return JSON.parse(readFileSync(path, "utf8"));
27585
+ } catch (error) {
27586
+ throw new CapletsError("CONFIG_INVALID", `Caplets config at ${path} is not valid JSON`, redactSecrets(error));
27587
+ }
27588
+ }
27589
+ function quarantineMissingEnvCaplets(input, kind, sourcePath, warnings) {
27590
+ let filtered = input;
27591
+ for (const backend of CAPLET_BACKEND_KEYS) {
27592
+ const caplets = filtered[backend];
27593
+ if (!isPlainObject$5(caplets)) continue;
27594
+ for (const [id, caplet] of Object.entries(caplets)) {
27595
+ const missing = missingEnvReferences(caplet, [backend, id]);
27596
+ if (missing.length === 0) continue;
27597
+ filtered = removeCapletBackendId(filtered, backend, id);
27598
+ warnings.push({
27599
+ kind,
27600
+ path: typeof sourcePath === "function" ? sourcePath(id) : sourcePath,
27601
+ message: formatMissingEnvWarning(id, missing),
27602
+ recoverable: true
27603
+ });
27604
+ }
27605
+ }
27606
+ return filtered;
27607
+ }
27608
+ function missingEnvReferences(value, path) {
27609
+ if (isPublicMetadataPath(path)) return [];
27610
+ if (typeof value === "string") return missingEnvReferencesInString(value, path.join("."));
27611
+ if (Array.isArray(value)) return value.flatMap((item, index) => missingEnvReferences(item, [...path, String(index)]));
27612
+ if (isPlainObject$5(value)) return Object.entries(value).flatMap(([key, nested]) => missingEnvReferences(nested, [...path, key]));
27613
+ return [];
27614
+ }
27615
+ function missingEnvReferencesInString(value, path) {
27616
+ const missing = [];
27617
+ for (const match of value.matchAll(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$env:([A-Za-z_][A-Za-z0-9_]*)/g)) {
27618
+ const name = match[1] ?? match[2];
27619
+ if (name && process.env[name] === void 0) missing.push({
27620
+ name,
27621
+ path
27622
+ });
27623
+ }
27624
+ return missing;
27625
+ }
27626
+ function formatMissingEnvWarning(id, missing) {
27627
+ const names = [...new Set(missing.map((reference) => reference.name))];
27628
+ const paths = [...new Set(missing.map((reference) => reference.path))];
27629
+ return `Caplet ${id} references missing ${names.length === 1 ? "environment variable" : "environment variables"} ${names.join(", ")} at ${paths.join(", ")}; skipping Caplet ${id}.`;
27630
+ }
27569
27631
  function loadBestEffortCapletFiles(root, kind, warnings) {
27570
27632
  const result = loadCapletFilesWithPathsBestEffort(root);
27571
27633
  if (!result) return;
@@ -27574,9 +27636,11 @@ function loadBestEffortCapletFiles(root, kind, warnings) {
27574
27636
  path: warning.path ?? root,
27575
27637
  message: warning.message
27576
27638
  });
27639
+ const config = quarantineMissingEnvCaplets(result.config, kind, (id) => result.paths[id] ?? root, warnings);
27640
+ const retainedIds = new Set(capletIds(config));
27577
27641
  return {
27578
- config: result.config,
27579
- paths: result.paths
27642
+ config,
27643
+ paths: Object.fromEntries(Object.entries(result.paths).filter(([id]) => retainedIds.has(id)))
27580
27644
  };
27581
27645
  }
27582
27646
  function errorMessage$3(error) {
@@ -27737,6 +27801,15 @@ function mergeConfigInputsWithSources(...inputs) {
27737
27801
  shadows
27738
27802
  };
27739
27803
  }
27804
+ function removeCapletBackendId(input, backend, id) {
27805
+ const caplets = input[backend];
27806
+ if (!isPlainObject$5(caplets)) return input;
27807
+ const { [id]: _removed, ...remaining } = caplets;
27808
+ return {
27809
+ ...input,
27810
+ [backend]: remaining
27811
+ };
27812
+ }
27740
27813
  function removeCapletId(input, id) {
27741
27814
  const { [id]: _mcpServer, ...mcpServers } = input.mcpServers ?? {};
27742
27815
  const { [id]: _openapiEndpoint, ...openapiEndpoints } = input.openapiEndpoints ?? {};
@@ -27867,7 +27940,7 @@ function interpolateConfig(value, path = []) {
27867
27940
  return value;
27868
27941
  }
27869
27942
  function isPublicMetadataPath(path) {
27870
- if (path.length < 3 || path[0] !== "mcpServers" && path[0] !== "openapiEndpoints" && path[0] !== "googleDiscoveryApis" && path[0] !== "graphqlEndpoints" && path[0] !== "httpApis" && path[0] !== "cliTools" && path[0] !== "capletSets") return false;
27943
+ if (path.length < 3 || !CAPLET_BACKEND_KEY_SET.has(path[0] ?? "")) return false;
27871
27944
  return NON_INTERPOLATED_SERVER_FIELDS.has(path[2] ?? "");
27872
27945
  }
27873
27946
  function isPlainObject$5(value) {
@@ -28269,7 +28342,7 @@ async function writeMediaArtifact(input) {
28269
28342
  const callId = safePathSegment(input.callId ?? defaultCallId(), "call");
28270
28343
  const filename = safeFilename(input.suggestedFilename ?? (input.outputPath ? basename(input.outputPath) : "response.bin"));
28271
28344
  const target = input.outputPath ? assertInsideRoot(rootDir, input.outputPath) : assertInsideRoot(rootDir, resolve(rootDir, capletId, callId, filename));
28272
- rejectSymlinkPathComponents(rootDir, target, true);
28345
+ rejectSymlinkPathComponents$1(rootDir, target, true);
28273
28346
  const uriParts = input.outputPath ? uriPartsForOutputPath(rootDir, target) : {
28274
28347
  capletId,
28275
28348
  callId,
@@ -28297,7 +28370,7 @@ function resolveMediaArtifact(uri, options = {}) {
28297
28370
  const parsed = parseArtifactUri(uri);
28298
28371
  const rootDir = resolve(options.artifactRoot ?? DEFAULT_ARTIFACT_DIR);
28299
28372
  const path = assertInsideRoot(rootDir, resolve(rootDir, parsed.capletId, parsed.callId, parsed.filename));
28300
- rejectSymlinkPathComponents(rootDir, path, true);
28373
+ rejectSymlinkPathComponents$1(rootDir, path, true);
28301
28374
  if (!existsSync(path)) throw new CapletsError("REQUEST_INVALID", "Media artifact was not found");
28302
28375
  const stat = statSync(path);
28303
28376
  if (!stat.isFile()) throw new CapletsError("REQUEST_INVALID", "Media artifact must resolve to a file");
@@ -28356,9 +28429,9 @@ function assertInsideRoot(rootDir, candidate) {
28356
28429
  if (rel.startsWith("..") || isAbsolute(rel)) throw new CapletsError("REQUEST_INVALID", "Media artifact outputPath must stay inside the artifact root");
28357
28430
  return resolved;
28358
28431
  }
28359
- function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
28432
+ function rejectSymlinkPathComponents$1(rootDir, target, includeTarget) {
28360
28433
  const resolvedRoot = resolve(rootDir);
28361
- rejectSymlinkRoot(resolvedRoot);
28434
+ rejectSymlinkRoot$1(resolvedRoot);
28362
28435
  const parts = relative(resolvedRoot, resolve(target)).split(/[\\/]+/u).filter(Boolean);
28363
28436
  let current = resolvedRoot;
28364
28437
  const limit = includeTarget ? parts.length : Math.max(0, parts.length - 1);
@@ -28373,7 +28446,7 @@ function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
28373
28446
  }
28374
28447
  }
28375
28448
  }
28376
- function rejectSymlinkRoot(rootDir) {
28449
+ function rejectSymlinkRoot$1(rootDir) {
28377
28450
  try {
28378
28451
  if (lstatSync(rootDir).isSymbolicLink()) throw new CapletsError("REQUEST_INVALID", "Media artifact root must not be a symlink");
28379
28452
  } catch (error) {
@@ -63362,7 +63435,7 @@ var CapletsEngine = class {
63362
63435
  }
63363
63436
  }
63364
63437
  async completeCliWords(words) {
63365
- const { completeCliWords } = await import("./completion-BC4BNWo0.js").then((n) => n.r);
63438
+ const { completeCliWords } = await import("./completion-BeVXdm9q.js").then((n) => n.r);
63366
63439
  return await completeCliWords(words, {
63367
63440
  config: this.registry.config,
63368
63441
  managers: {
@@ -63670,11 +63743,12 @@ function isRecord$2(value) {
63670
63743
  }
63671
63744
  //#endregion
63672
63745
  //#region src/code-mode/runtime-api.generated.ts
63673
- const CODE_MODE_RUNTIME_API_DECLARATION = "type JsonPrimitive=string|number|boolean|null;type JsonValue=JsonPrimitive|JsonValue[]|{[key:string]:JsonValue};interface CapletHandle<Id extends string>{readonly id:Id;/** Show this Caplet card,without tool/resource/prompt schemas. */ inspect():Promise<CapletCard<Id>>;/** Check backend readiness/auth;expected unavailable states return ok:false. */ check():Promise<CapletsResult<BackendCheckResult>>;/** List tool summaries for the discovery pass;may be empty. */ tools(input?:PageInput):Promise<Page<ToolSummary>>;/** Search tool summaries for the discovery pass;may be empty. */ searchTools(query:string,input?:PageInput):Promise<Page<ToolSummary>>;/** Get schema,callSignature,types,examples;prefer outputSchema/outputTypeScript over observed hints. */ describeTool(name:string):Promise<CapletsResult<ToolDescriptor>>;/** Call one tool;expected failures return ok:false. Filter bulky data in script before returning. */ callTool(name:string,args?:unknown):Promise<CapletsResult<unknown>>;/** List readable resources for the discovery pass;many backends expose none. */ resources(input?:PageInput):Promise<Page<ResourceSummary>>;/** Search readable resources for the discovery pass;many backends expose none. */ searchResources(query:string,input?:PageInput):Promise<Page<ResourceSummary>>;/** List resource templates for the discovery pass;many backends expose none. */ resourceTemplates(input?:PageInput):Promise<Page<ResourceTemplateSummary>>;/** Read one resource by URI;unsupported/missing resources return ok:false. */ readResource(uri:string):Promise<CapletsResult<ResourceReadResult>>;/** List reusable prompts for the discovery pass;many backends expose none. */ prompts(input?:PageInput):Promise<Page<PromptSummary>>;/** Search reusable prompts for the discovery pass;many backends expose none. */ searchPrompts(query:string,input?:PageInput):Promise<Page<PromptSummary>>;/** Get one prompt by name and args;unsupported/missing prompts return ok:false. */ getPrompt(name:string,args?:unknown):Promise<CapletsResult<PromptResult>>;/** Complete a prompt or resource-template argument. */ complete(input:CompleteInput):Promise<CapletsResult<CompleteResult>>;}interface DebugApi{readLogs(input:ReadLogsInput):Promise<ReadLogsResult>;}type CapletCard<Id extends string>={id:Id;name:string;description:string;useWhen?:string;avoidWhen?:string;tags?:string[];backend?:unknown;};type PageInput={limit?:number;cursor?:string};type Page<T>={items:T[];nextCursor?:string;truncated?:boolean};type CapletsResult<T>=|{ok:true;data:T;meta?:CapletsMeta}|{ok:false;error:CapletsError;meta?:CapletsMeta};type CapletsMeta={[key:string]:unknown};type CapletsError={code:string;message:string;details?:unknown};type BackendCheckResult=unknown;type ToolSummary={/** Exact downstream tool identifier for describeTool(name)and callTool(name,args). */ name:string;title?:string;description?:string;/** Optional author-supplied hint for when to prefer this tool. */ useWhen?:string;/** Optional author-supplied hint for when to avoid this tool. */ avoidWhen?:string;/** True when the tool declares that it only reads data. */ readOnlyHint?:boolean;/** True when the tool declares that it may perform destructive writes. */ destructiveHint?:boolean;};type ToolDescriptor={id?:string;tool?:unknown;inputSchema?:unknown;outputSchema?:unknown;callSignature?:string;inputTypeScript?:string;outputTypeScript?:string;observedOutputShape?:ObservedOutputShape;examples?:unknown[];};type ObservedOutputShape={version:1;source:\"observed\";observedAt:string;sampleCount:number;typeScript:string;jsonShape:JsonShape;truncated:boolean;};type JsonShape=|{kind:\"null\"}|{kind:\"boolean\"}|{kind:\"number\"}|{kind:\"string\"}|{kind:\"unknown\"}|{kind:\"array\";element?:JsonShape;truncated?:boolean}|{kind:\"object\";fields:Record<string,{optional:boolean;shape:JsonShape}>;truncated?:boolean;}|{kind:\"union\";variants:JsonShape[]};type ResourceSummary={uri?:string;name?:string;title?:string;description?:string};type ResourceTemplateSummary={uriTemplate?:string;name?:string;title?:string;description?:string;};type ResourceReadResult=unknown;type PromptSummary={name?:string;title?:string;description?:string};type PromptResult=unknown;type CompleteInput={ref:{type:\"prompt\";name:string}|{type:\"resourceTemplate\";uri:string};argument:{name:string;value:string};};type CompleteResult=unknown;type ReadLogsInput={logRef:string;cursor?:string;limit?:number};type ReadLogsResult={entries:CodeModeLogEntry[];nextCursor?:string};type CodeModeLogEntry={level:\"log\"|\"info\"|\"warn\"|\"error\"|\"debug\";message:string;timestamp:string;};interface Console{log(...values:unknown[]):void;info(...values:unknown[]):void;warn(...values:unknown[]):void;error(...values:unknown[]):void;debug(...values:unknown[]):void;}declare const console:Console;";
63746
+ const CODE_MODE_RUNTIME_API_DECLARATION = "type JsonPrimitive=string|number|boolean|null;type JsonValue=JsonPrimitive|JsonValue[]|{[key:string]:JsonValue};interface CapletHandle<Id extends string>{readonly id:Id;/** Show this Caplet card,without tool/resource/prompt schemas. */ inspect():Promise<CapletCard<Id>>;/** Check backend readiness/auth;expected unavailable states return ok:false. */ check():Promise<CapletsResult<BackendCheckResult>>;/** List tool summaries for the discovery pass;may be empty. */ tools(input?:PageInput):Promise<Page<ToolSummary>>;/** Search tool summaries for the discovery pass;may be empty. */ searchTools(query:string,input?:PageInput):Promise<Page<ToolSummary>>;/** Get schema,callSignature,types,examples;prefer outputSchema/outputTypeScript over observed hints. */ describeTool(name:string):Promise<CapletsResult<ToolDescriptor>>;/** Call one tool;expected failures return ok:false. Filter bulky data in script before returning. */ callTool(name:string,args?:unknown):Promise<CapletsResult<unknown>>;/** List readable resources for the discovery pass;many backends expose none. */ resources(input?:PageInput):Promise<Page<ResourceSummary>>;/** Search readable resources for the discovery pass;many backends expose none. */ searchResources(query:string,input?:PageInput):Promise<Page<ResourceSummary>>;/** List resource templates for the discovery pass;many backends expose none. */ resourceTemplates(input?:PageInput):Promise<Page<ResourceTemplateSummary>>;/** Read one resource by URI;unsupported/missing resources return ok:false. */ readResource(uri:string):Promise<CapletsResult<ResourceReadResult>>;/** List reusable prompts for the discovery pass;many backends expose none. */ prompts(input?:PageInput):Promise<Page<PromptSummary>>;/** Search reusable prompts for the discovery pass;many backends expose none. */ searchPrompts(query:string,input?:PageInput):Promise<Page<PromptSummary>>;/** Get one prompt by name and args;unsupported/missing prompts return ok:false. */ getPrompt(name:string,args?:unknown):Promise<CapletsResult<PromptResult>>;/** Complete a prompt or resource-template argument. */ complete(input:CompleteInput):Promise<CapletsResult<CompleteResult>>;}interface DebugApi{readLogs(input:ReadLogsInput):Promise<ReadLogsResult>;readRecovery(input:ReadCodeModeRecoveryInput):Promise<ReadCodeModeRecoveryResult>;}type CapletCard<Id extends string>={id:Id;name:string;description:string;useWhen?:string;avoidWhen?:string;tags?:string[];backend?:unknown;};type PageInput={limit?:number;cursor?:string};type Page<T>={items:T[];nextCursor?:string;truncated?:boolean};type CapletsResult<T>=|{ok:true;data:T;meta?:CapletsMeta}|{ok:false;error:CapletsError;meta?:CapletsMeta};type CapletsMeta={[key:string]:unknown};type CapletsError={code:string;message:string;details?:unknown};type BackendCheckResult=unknown;type ToolSummary={/** Exact downstream tool identifier for describeTool(name)and callTool(name,args). */ name:string;title?:string;description?:string;/** Optional author-supplied hint for when to prefer this tool. */ useWhen?:string;/** Optional author-supplied hint for when to avoid this tool. */ avoidWhen?:string;/** True when the tool declares that it only reads data. */ readOnlyHint?:boolean;/** True when the tool declares that it may perform destructive writes. */ destructiveHint?:boolean;};type ToolDescriptor={id?:string;tool?:unknown;inputSchema?:unknown;outputSchema?:unknown;callSignature?:string;inputTypeScript?:string;outputTypeScript?:string;observedOutputShape?:ObservedOutputShape;examples?:unknown[];};type ObservedOutputShape={version:1;source:\"observed\";observedAt:string;sampleCount:number;typeScript:string;jsonShape:JsonShape;truncated:boolean;};type JsonShape=|{kind:\"null\"}|{kind:\"boolean\"}|{kind:\"number\"}|{kind:\"string\"}|{kind:\"unknown\"}|{kind:\"array\";element?:JsonShape;truncated?:boolean}|{kind:\"object\";fields:Record<string,{optional:boolean;shape:JsonShape}>;truncated?:boolean;}|{kind:\"union\";variants:JsonShape[]};type ResourceSummary={uri?:string;name?:string;title?:string;description?:string};type ResourceTemplateSummary={uriTemplate?:string;name?:string;title?:string;description?:string;};type ResourceReadResult=unknown;type PromptSummary={name?:string;title?:string;description?:string};type PromptResult=unknown;type CompleteInput={ref:{type:\"prompt\";name:string}|{type:\"resourceTemplate\";uri:string};argument:{name:string;value:string};};type CompleteResult=unknown;type ReadLogsInput={logRef:string;cursor?:string;limit?:number};type ReadLogsResult={entries:CodeModeLogEntry[];nextCursor?:string};type ReadCodeModeRecoveryInput={recoveryRef:string;cursor?:string;limit?:number};type CodeModeDiagnostic={code:string;message:string;severity:\"error\"|\"warning\"|\"info\";line?:number;column?:number;};type CodeModeRecoveryClassification=\"setup_like\"|\"side_effecting\"|\"unknown\";type CodeModeRecoveryEntry={timestamp:string;code:string;declarationHash:string;outcome:{ok:true}|{ok:false;code:string;message:string};diagnostics:Array<Pick<CodeModeDiagnostic,\"code\"|\"severity\"|\"message\">>;recoveryClassification:CodeModeRecoveryClassification;logsStored?:boolean;summary?:string;};type ReadCodeModeRecoveryResult={entries:CodeModeRecoveryEntry[];nextCursor?:string};type CodeModeLogEntry={level:\"log\"|\"info\"|\"warn\"|\"error\"|\"debug\";message:string;timestamp:string;};type CodeModeSessionStatus=\"created\"|\"reused\";type CodeModeRunMeta={runId:string;traceId:string;declarationHash:string;durationMs:number;timeoutMs:number;maxTimeoutMs:number;sessionId?:string|null;sessionStatus?:CodeModeSessionStatus|null;recoveryRef?:string|null;};interface Console{log(...values:unknown[]):void;info(...values:unknown[]):void;warn(...values:unknown[]):void;error(...values:unknown[]):void;debug(...values:unknown[]):void;}declare const console:Console;";
63674
63747
  //#endregion
63675
63748
  //#region src/code-mode/declarations.ts
63676
63749
  const JS_IDENTIFIER = /^[A-Za-z_$][\w$]*$/u;
63677
63750
  const MAX_JSDOC_CHARS = 180;
63751
+ const CODE_MODE_REPL_GUIDANCE = "REPL reuse: omit `sessionId` to start a fresh reusable Code Mode session; after a successful run, keep `meta.sessionId` and pass it as `sessionId` on later calls when you want to reuse live state. Reused sessions preserve successful top-level `var` bindings, function declarations, and runtime state only while the live session remains available and compatible. A supplied `sessionId` that is unknown or no longer available fails before executing your code instead of starting an empty context. Use `meta.recoveryRef` with `caplets.debug.readRecovery({ recoveryRef })` for audit and manual reconstruction; do not automatically replay recovery history.";
63678
63752
  function generateCodeModeDeclarations(input) {
63679
63753
  const caplets = [...input.caplets].sort((left, right) => left.id.localeCompare(right.id));
63680
63754
  const properties = caplets.map((caplet) => {
@@ -63694,6 +63768,7 @@ function generateCodeModeDeclarations(input) {
63694
63768
  function generateCodeModeRunToolDescription(declaration) {
63695
63769
  return [
63696
63770
  "Run TypeScript with generated `caplets.<id>` handles and declaration hints below. Prefer a compact one-pass script for most tasks: discover, filter, execute, and synthesize inside Code Mode, then return only decision-ready JSON. Do not return full tool lists, full descriptors, schemas, raw tool payloads, or exploratory transcripts unless the user specifically needs them; keep bulky intermediate data inside the script. For discovery, use tools/searchTools for names and arg hints, then describeTool only for short-listed operations needing exact schemas, nested args, fields, or disambiguation. Never invent tool names, resource URIs, prompt names, input args, output fields, or schemas; use requiredArgs/acceptedArgs for simple calls, otherwise use describeTool for the exact callSignature/inputSchema/inputTypeScript. For fallback, check candidate handles first: `for(const h of candidates){const ready=await h.check();if(!ready.ok)continue;}`. For triage, list broad candidate records and filter in script before targeted searches so adjacent relevant items are not missed. Execute with exact args, handle `{ok:false}`, and derive final recommendations from all relevant records, not the first matching record. If records disagree or have ranges/statuses, compute the strictest applicable conclusion and preserve only the compact evidence used. Return summaries, key ids/names/titles/statuses/urls, derived fields, recommendation, caveats, and residual missing data. Before returning, remove unused descriptors/schemas/raw content. Pattern: `const h=caplets[\"caplet-id\"];const tools=await h.searchTools(\"query\");const d=needSchema?await h.describeTool(\"tool_name\"):undefined;const r=await h.callTool(\"tool_name\",args);return {facts:[...],evidence:[...]};`",
63771
+ CODE_MODE_REPL_GUIDANCE,
63697
63772
  "",
63698
63773
  "Generated declaration hints:",
63699
63774
  "```ts",
@@ -63756,8 +63831,8 @@ function fnv1a32(value, seed) {
63756
63831
  //#endregion
63757
63832
  //#region src/code-mode/logs.ts
63758
63833
  const DEFAULT_LOG_REF_TTL_MS = 3600 * 1e3;
63759
- const DEFAULT_PAGE_LIMIT = 100;
63760
- const MAX_PAGE_LIMIT = 500;
63834
+ const DEFAULT_PAGE_LIMIT$1 = 100;
63835
+ const MAX_PAGE_LIMIT$1 = 500;
63761
63836
  const SECRET_KEY_VALUE_PATTERN = /\b(?:authorization|cookie|set-cookie|password|passphrase|secret|token|api[-_]?key|clientsecret|client_secret|privatekey|private_key|credential|refreshToken|accessToken)\b\s*[:=]\s*([^\s,;]+)/giu;
63762
63837
  const BEARER_PATTERN = /\bbearer\s+([a-z0-9._~+/=-]{8,})/giu;
63763
63838
  const BASIC_PATTERN = /\bbasic\s+([a-z0-9._~+/=-]{8,})/giu;
@@ -63798,8 +63873,8 @@ var CodeModeLogStore = class {
63798
63873
  if (!existsSync(path)) return { entries: [] };
63799
63874
  const parsed = parseStoredLogs(readFileSync(path, "utf8"));
63800
63875
  if (!parsed || new Date(parsed.expiresAt).getTime() <= this.now().getTime()) return { entries: [] };
63801
- const offset = parseCursor(input.cursor);
63802
- const limit = Math.min(Math.max(input.limit ?? DEFAULT_PAGE_LIMIT, 0), MAX_PAGE_LIMIT);
63876
+ const offset = parseCursor$1(input.cursor);
63877
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_PAGE_LIMIT$1, 0), MAX_PAGE_LIMIT$1);
63803
63878
  const entries = parsed.entries.slice(offset, offset + limit).map(redactEntry);
63804
63879
  const nextOffset = offset + entries.length;
63805
63880
  return nextOffset < parsed.entries.length ? {
@@ -63823,7 +63898,7 @@ function redactEntry(entry) {
63823
63898
  message: redactCodeModeLogText(entry.message)
63824
63899
  };
63825
63900
  }
63826
- function parseCursor(cursor) {
63901
+ function parseCursor$1(cursor) {
63827
63902
  if (!cursor) return 0;
63828
63903
  const parsed = Number.parseInt(cursor, 10);
63829
63904
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
@@ -63847,6 +63922,373 @@ function isLogEntry(value) {
63847
63922
  return (entry.level === "log" || entry.level === "info" || entry.level === "warn" || entry.level === "error" || entry.level === "debug") && typeof entry.message === "string" && typeof entry.timestamp === "string";
63848
63923
  }
63849
63924
  //#endregion
63925
+ //#region src/code-mode/journal.ts
63926
+ const DEFAULT_JOURNAL_RETENTION_MS = 10080 * 60 * 1e3;
63927
+ const DEFAULT_MAX_ENTRIES = 100;
63928
+ const DEFAULT_MAX_CODE_BYTES = 64 * 1024;
63929
+ const DEFAULT_MAX_SUMMARY_BYTES = 16 * 1024;
63930
+ const DEFAULT_PAGE_LIMIT = 25;
63931
+ const MAX_PAGE_LIMIT = 100;
63932
+ const JOURNAL_VERSION = 1;
63933
+ var CodeModeJournalStore = class {
63934
+ stateDir;
63935
+ now;
63936
+ retentionMs;
63937
+ maxEntries;
63938
+ maxCodeBytes;
63939
+ maxSummaryBytes;
63940
+ configuredSecret;
63941
+ secret;
63942
+ recoveryRefs = /* @__PURE__ */ new Map();
63943
+ sessionRecoveryRefs = /* @__PURE__ */ new Map();
63944
+ nextPruneAt = 0;
63945
+ constructor(options = {}) {
63946
+ this.stateDir = options.stateDir ?? join(defaultStateBaseDir(), "caplets");
63947
+ this.now = options.now ?? (() => /* @__PURE__ */ new Date());
63948
+ this.retentionMs = options.retentionMs ?? DEFAULT_JOURNAL_RETENTION_MS;
63949
+ this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
63950
+ this.maxCodeBytes = options.maxCodeBytes ?? DEFAULT_MAX_CODE_BYTES;
63951
+ this.maxSummaryBytes = options.maxSummaryBytes ?? DEFAULT_MAX_SUMMARY_BYTES;
63952
+ this.configuredSecret = options.secret;
63953
+ }
63954
+ async store(input) {
63955
+ this.ensureJournalDir();
63956
+ this.pruneExpired();
63957
+ const now = this.now();
63958
+ const expiresAt = new Date(now.getTime() + this.retentionMs).toISOString();
63959
+ const journalKey = this.journalKey(input.sessionId, input.journalScope);
63960
+ const recoveryRef = this.recoveryRefs.get(journalKey) ?? this.recoveryRefForJournalKey(journalKey);
63961
+ this.recoveryRefs.set(journalKey, recoveryRef);
63962
+ this.sessionRecoveryRefs.set(input.sessionId, {
63963
+ recoveryRef,
63964
+ expiresAt
63965
+ });
63966
+ const recoveryRefHash = this.recoveryRefHash(recoveryRef);
63967
+ const path = this.journalPath(journalKey);
63968
+ const existing = this.readJournalPath(path);
63969
+ const entry = this.entryFromInput(input, now, recoveryRef);
63970
+ const stored = {
63971
+ version: JOURNAL_VERSION,
63972
+ journalKey,
63973
+ sessionIdHash: this.sessionIdHash(input.sessionId),
63974
+ recoveryRefHashes: [...new Set([...existing?.recoveryRefHashes ?? [], recoveryRefHash])],
63975
+ createdAt: existing?.createdAt ?? now.toISOString(),
63976
+ updatedAt: now.toISOString(),
63977
+ expiresAt,
63978
+ entries: [...existing?.entries ?? [], entry].slice(-this.maxEntries)
63979
+ };
63980
+ this.writeJournal(path, stored);
63981
+ this.writeIndex(this.recoveryIndexPath(recoveryRefHash), stored);
63982
+ this.writeIndex(this.sessionIndexPath(stored.sessionIdHash), stored);
63983
+ return {
63984
+ recoveryRef,
63985
+ expiresAt,
63986
+ journalKey
63987
+ };
63988
+ }
63989
+ async lookupSession(sessionId) {
63990
+ this.ensureJournalDir();
63991
+ this.pruneExpired();
63992
+ const retained = this.sessionRecoveryRefs.get(sessionId);
63993
+ if (retained && new Date(retained.expiresAt).getTime() > this.now().getTime()) return retained;
63994
+ const scopedJournal = this.findBySessionIdHash(this.sessionIdHash(sessionId));
63995
+ if (scopedJournal && !this.isExpired(scopedJournal)) return {
63996
+ expiresAt: scopedJournal.expiresAt,
63997
+ recoveryRef: this.recoveryRefForJournalKey(scopedJournal.journalKey)
63998
+ };
63999
+ const journal = this.readJournalPath(this.journalPath(this.journalKey(sessionId)));
64000
+ if (!journal || this.isExpired(journal)) return void 0;
64001
+ return { expiresAt: journal.expiresAt };
64002
+ }
64003
+ async lookupRecoveryRef(recoveryRef) {
64004
+ if (!isRecoveryRef(recoveryRef)) return void 0;
64005
+ this.ensureJournalDir();
64006
+ this.pruneExpired();
64007
+ const journal = this.findByRecoveryRefHash(this.recoveryRefHash(recoveryRef));
64008
+ if (!journal || this.isExpired(journal)) return void 0;
64009
+ return { expiresAt: journal.expiresAt };
64010
+ }
64011
+ async readRecovery(input) {
64012
+ if (!isRecoveryRef(input.recoveryRef)) return { entries: [] };
64013
+ this.ensureJournalDir();
64014
+ this.pruneExpired();
64015
+ const recoveryRefHash = this.recoveryRefHash(input.recoveryRef);
64016
+ const journal = this.findByRecoveryRefHash(recoveryRefHash);
64017
+ if (!journal || this.isExpired(journal)) return { entries: [] };
64018
+ const offset = parseCursor(input.cursor);
64019
+ if (input.limit !== void 0 && input.limit <= 0) return { entries: [] };
64020
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_PAGE_LIMIT, 0), MAX_PAGE_LIMIT);
64021
+ const entries = journal.entries.slice(offset, offset + limit);
64022
+ const nextOffset = offset + entries.length;
64023
+ return nextOffset < journal.entries.length ? {
64024
+ entries,
64025
+ nextCursor: String(nextOffset)
64026
+ } : { entries };
64027
+ }
64028
+ entryFromInput(input, now, recoveryRef) {
64029
+ const exactSecrets = [
64030
+ input.sessionId,
64031
+ recoveryRef,
64032
+ input.logRef
64033
+ ].filter((value) => Boolean(value));
64034
+ return {
64035
+ timestamp: now.toISOString(),
64036
+ code: truncateUtf8(redactJournalText(input.code, exactSecrets), this.maxCodeBytes),
64037
+ declarationHash: input.declarationHash,
64038
+ outcome: input.outcome.ok === true ? { ok: true } : {
64039
+ ok: false,
64040
+ code: input.outcome.code,
64041
+ message: truncateUtf8(redactJournalText(input.outcome.message, exactSecrets), 2e3)
64042
+ },
64043
+ diagnostics: input.diagnostics.map((diagnostic) => ({
64044
+ code: diagnostic.code,
64045
+ severity: diagnostic.severity,
64046
+ message: truncateUtf8(redactJournalText(diagnostic.message, exactSecrets), 2e3)
64047
+ })),
64048
+ recoveryClassification: input.recoveryClassification,
64049
+ ...input.logRef ? { logsStored: true } : {},
64050
+ ...input.summary ? { summary: truncateUtf8(redactJournalText(input.summary, exactSecrets), this.maxSummaryBytes) } : {}
64051
+ };
64052
+ }
64053
+ findByRecoveryRefHash(recoveryRefHash) {
64054
+ const indexed = this.readIndexPath(this.recoveryIndexPath(recoveryRefHash));
64055
+ if (indexed) return this.readJournalPath(this.journalPath(indexed.journalKey));
64056
+ return this.findByRecoveryRefHashSlow(recoveryRefHash);
64057
+ }
64058
+ findBySessionIdHash(sessionIdHash) {
64059
+ const indexed = this.readIndexPath(this.sessionIndexPath(sessionIdHash));
64060
+ if (indexed) return this.readJournalPath(this.journalPath(indexed.journalKey));
64061
+ return this.findBySessionIdHashSlow(sessionIdHash);
64062
+ }
64063
+ findByRecoveryRefHashSlow(recoveryRefHash) {
64064
+ for (const filename of readdirSync(this.journalDir())) {
64065
+ if (!filename.endsWith(".json")) continue;
64066
+ const journal = this.readJournalPath(join(this.journalDir(), filename));
64067
+ if (journal?.recoveryRefHashes.includes(recoveryRefHash)) return journal;
64068
+ }
64069
+ }
64070
+ findBySessionIdHashSlow(sessionIdHash) {
64071
+ const journals = [];
64072
+ for (const filename of readdirSync(this.journalDir())) {
64073
+ if (!filename.endsWith(".json")) continue;
64074
+ const journal = this.readJournalPath(join(this.journalDir(), filename));
64075
+ if (journal?.sessionIdHash === sessionIdHash) journals.push(journal);
64076
+ }
64077
+ return journals.sort((left, right) => new Date(right.updatedAt).getTime() - new Date(left.updatedAt).getTime())[0];
64078
+ }
64079
+ writeIndex(path, journal) {
64080
+ const index = {
64081
+ version: JOURNAL_VERSION,
64082
+ journalKey: journal.journalKey,
64083
+ updatedAt: journal.updatedAt
64084
+ };
64085
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64086
+ mkdirSync(dirname(path), {
64087
+ recursive: true,
64088
+ mode: 448
64089
+ });
64090
+ chmodSync(dirname(path), 448);
64091
+ const tempPath = `${path}.${randomBytes(8).toString("hex")}.tmp`;
64092
+ writeFileSync(tempPath, `${JSON.stringify(index, null, 2)}\n`, { mode: 384 });
64093
+ chmodSync(tempPath, 384);
64094
+ renameSync(tempPath, path);
64095
+ chmodSync(path, 384);
64096
+ }
64097
+ readIndexPath(path) {
64098
+ try {
64099
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64100
+ if (!existsSync(path)) return void 0;
64101
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
64102
+ if (parsed.version !== JOURNAL_VERSION || typeof parsed.journalKey !== "string" || typeof parsed.updatedAt !== "string") return;
64103
+ return {
64104
+ version: JOURNAL_VERSION,
64105
+ journalKey: parsed.journalKey,
64106
+ updatedAt: parsed.updatedAt
64107
+ };
64108
+ } catch {
64109
+ return;
64110
+ }
64111
+ }
64112
+ readJournalPath(path) {
64113
+ try {
64114
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64115
+ if (!existsSync(path)) return void 0;
64116
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
64117
+ if (parsed.version !== JOURNAL_VERSION || typeof parsed.journalKey !== "string" || !Array.isArray(parsed.recoveryRefHashes) || typeof parsed.createdAt !== "string" || typeof parsed.updatedAt !== "string" || typeof parsed.expiresAt !== "string" || !Array.isArray(parsed.entries)) return;
64118
+ return {
64119
+ version: JOURNAL_VERSION,
64120
+ journalKey: parsed.journalKey,
64121
+ ...typeof parsed.sessionIdHash === "string" ? { sessionIdHash: parsed.sessionIdHash } : {},
64122
+ recoveryRefHashes: parsed.recoveryRefHashes.filter((hash) => typeof hash === "string"),
64123
+ createdAt: parsed.createdAt,
64124
+ updatedAt: parsed.updatedAt,
64125
+ expiresAt: parsed.expiresAt,
64126
+ entries: parsed.entries.filter(isJournalEntry)
64127
+ };
64128
+ } catch {
64129
+ return;
64130
+ }
64131
+ }
64132
+ writeJournal(path, journal) {
64133
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64134
+ mkdirSync(dirname(path), {
64135
+ recursive: true,
64136
+ mode: 448
64137
+ });
64138
+ chmodSync(dirname(path), 448);
64139
+ const tempPath = `${path}.${randomBytes(8).toString("hex")}.tmp`;
64140
+ writeFileSync(tempPath, `${JSON.stringify(journal, null, 2)}\n`, { mode: 384 });
64141
+ chmodSync(tempPath, 384);
64142
+ renameSync(tempPath, path);
64143
+ chmodSync(path, 384);
64144
+ }
64145
+ pruneExpired() {
64146
+ const dir = this.journalDir();
64147
+ if (!existsSync(dir)) return;
64148
+ const now = this.now().getTime();
64149
+ if (now < this.nextPruneAt) return;
64150
+ this.nextPruneAt = now + 6e4;
64151
+ for (const filename of readdirSync(dir)) {
64152
+ if (!filename.endsWith(".json")) continue;
64153
+ const path = join(dir, filename);
64154
+ const journal = this.readJournalPath(path);
64155
+ if (!journal || this.isExpired(journal)) rmSync(path, { force: true });
64156
+ }
64157
+ }
64158
+ isExpired(journal) {
64159
+ return new Date(journal.expiresAt).getTime() <= this.now().getTime();
64160
+ }
64161
+ journalKey(sessionId, journalScope = "default") {
64162
+ return this.hmac(`journal:${sessionId}:${journalScope}`);
64163
+ }
64164
+ recoveryRefHash(recoveryRef) {
64165
+ return this.hmac(`recovery-ref:${recoveryRef}`);
64166
+ }
64167
+ recoveryRefForJournalKey(journalKey) {
64168
+ return this.hmac(`recovery-ref-material:${journalKey}`).slice(0, 48);
64169
+ }
64170
+ sessionIdHash(sessionId) {
64171
+ return this.hmac(`session-id:${sessionId}`);
64172
+ }
64173
+ hmac(value) {
64174
+ return createHmac("sha256", this.loadSecret()).update(value).digest("hex");
64175
+ }
64176
+ loadSecret() {
64177
+ if (this.configuredSecret) return this.configuredSecret;
64178
+ if (this.secret) return this.secret;
64179
+ this.ensureJournalDir();
64180
+ const path = this.secretPath();
64181
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64182
+ if (existsSync(path)) {
64183
+ this.secret = readFileSync(path, "utf8").trim();
64184
+ return this.secret;
64185
+ }
64186
+ this.secret = randomBytes(32).toString("hex");
64187
+ writeFileSync(path, `${this.secret}\n`, { mode: 384 });
64188
+ chmodSync(path, 384);
64189
+ return this.secret;
64190
+ }
64191
+ ensureJournalDir() {
64192
+ const dir = this.journalDir();
64193
+ rejectSymlinkRoot(resolve(this.stateDir));
64194
+ rejectSymlinkPathComponents(resolve(this.stateDir), dir, true);
64195
+ mkdirSync(dir, {
64196
+ recursive: true,
64197
+ mode: 448
64198
+ });
64199
+ rejectSymlinkPathComponents(resolve(this.stateDir), dir, true);
64200
+ chmodSync(dir, 448);
64201
+ }
64202
+ journalDir() {
64203
+ return join(this.stateDir, "code-mode", "journal");
64204
+ }
64205
+ journalPath(journalKey) {
64206
+ return join(this.journalDir(), `${journalKey}.json`);
64207
+ }
64208
+ recoveryIndexPath(recoveryRefHash) {
64209
+ return join(this.journalDir(), "recovery-index", `${recoveryRefHash}.json`);
64210
+ }
64211
+ sessionIndexPath(sessionIdHash) {
64212
+ return join(this.journalDir(), "session-index", `${sessionIdHash ?? "unknown"}.json`);
64213
+ }
64214
+ secretPath() {
64215
+ return join(this.journalDir(), "secret.key");
64216
+ }
64217
+ };
64218
+ function classifyCodeModeRecovery(input) {
64219
+ if (input.invokedCaplet) return "side_effecting";
64220
+ if (input.sessionDisposedAfterRun) return "unknown";
64221
+ return /\b(?:function|var|let|const|class)\b/u.test(input.code) ? "setup_like" : "unknown";
64222
+ }
64223
+ function isRecoveryRef(value) {
64224
+ return /^[a-f0-9]{48}$/u.test(value);
64225
+ }
64226
+ function parseCursor(cursor) {
64227
+ if (!cursor) return 0;
64228
+ const parsed = Number.parseInt(cursor, 10);
64229
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
64230
+ }
64231
+ function truncateUtf8(value, maxBytes) {
64232
+ let bytes = 0;
64233
+ let output = "";
64234
+ for (const char of value) {
64235
+ const next = Buffer.byteLength(char, "utf8");
64236
+ if (bytes + next > maxBytes) break;
64237
+ output += char;
64238
+ bytes += next;
64239
+ }
64240
+ return output;
64241
+ }
64242
+ function redactJournalText(text, exactSecrets) {
64243
+ let redacted = redactCodeModeLogText(text);
64244
+ for (const secret of exactSecrets) {
64245
+ if (!secret) continue;
64246
+ redacted = redacted.replaceAll(secret, "[REDACTED:capability]");
64247
+ }
64248
+ return redacted.replace(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/giu, "[REDACTED:capability]");
64249
+ }
64250
+ function isJournalEntry(value) {
64251
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64252
+ const entry = value;
64253
+ return typeof entry.timestamp === "string" && typeof entry.code === "string" && typeof entry.declarationHash === "string" && isJournalOutcome(entry.outcome) && Array.isArray(entry.diagnostics) && entry.diagnostics.every(isJournalDiagnostic) && (entry.recoveryClassification === "setup_like" || entry.recoveryClassification === "side_effecting" || entry.recoveryClassification === "unknown") && (entry.logsStored === void 0 || typeof entry.logsStored === "boolean") && (entry.summary === void 0 || typeof entry.summary === "string");
64254
+ }
64255
+ function isJournalOutcome(value) {
64256
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64257
+ const outcome = value;
64258
+ return outcome.ok === true || outcome.ok === false && typeof outcome.code === "string";
64259
+ }
64260
+ function isJournalDiagnostic(value) {
64261
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64262
+ const diagnostic = value;
64263
+ return typeof diagnostic.code === "string" && typeof diagnostic.message === "string" && (diagnostic.severity === "error" || diagnostic.severity === "warning" || diagnostic.severity === "info");
64264
+ }
64265
+ function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
64266
+ const resolvedRoot = resolve(rootDir);
64267
+ rejectSymlinkRoot(resolvedRoot);
64268
+ const rel = relative(resolvedRoot, resolve(target));
64269
+ if (rel.startsWith("..") || rel === "") return;
64270
+ const parts = rel.split(/[\\/]+/u).filter(Boolean);
64271
+ let current = resolvedRoot;
64272
+ const limit = includeTarget ? parts.length : Math.max(0, parts.length - 1);
64273
+ for (let index = 0; index < limit; index += 1) {
64274
+ current = resolve(current, parts[index]);
64275
+ try {
64276
+ if (lstatSync(current).isSymbolicLink()) throw new Error("Code Mode journal path must not contain symlinks.");
64277
+ } catch (error) {
64278
+ if (error.code === "ENOENT") return;
64279
+ throw error;
64280
+ }
64281
+ }
64282
+ }
64283
+ function rejectSymlinkRoot(rootDir) {
64284
+ try {
64285
+ if (lstatSync(rootDir).isSymbolicLink()) throw new Error("Code Mode journal root must not be a symlink.");
64286
+ } catch (error) {
64287
+ if (error.code === "ENOENT") return;
64288
+ throw error;
64289
+ }
64290
+ }
64291
+ //#endregion
63850
64292
  //#region src/code-mode/api.ts
63851
64293
  const MAX_TOOL_TEXT_CHARS = 2e3;
63852
64294
  const MAX_ERROR_MESSAGE_CHARS = 1e3;
@@ -63870,7 +64312,10 @@ function dedupeCallableCaplets(caplets) {
63870
64312
  function createCodeModeCapletsApi(input) {
63871
64313
  const api = {};
63872
64314
  for (const caplet of listCodeModeCallableCaplets(input.service)) api[caplet.id] = createHandle(input.service, caplet.id);
63873
- const debugApi = { readLogs: input.readLogs ?? defaultReadLogs };
64315
+ const debugApi = {
64316
+ readLogs: input.readLogs ?? defaultReadLogs,
64317
+ readRecovery: input.readRecovery ?? defaultReadRecovery
64318
+ };
63874
64319
  api.debug = "debug" in api ? Object.assign(api.debug, debugApi) : debugApi;
63875
64320
  return api;
63876
64321
  }
@@ -64199,6 +64644,9 @@ async function defaultReadLogs() {
64199
64644
  timestamp: (/* @__PURE__ */ new Date(0)).toISOString()
64200
64645
  }] };
64201
64646
  }
64647
+ async function defaultReadRecovery() {
64648
+ return { entries: [] };
64649
+ }
64202
64650
  function resultIsError(result) {
64203
64651
  if (!isPlainObject$1(result)) return false;
64204
64652
  if (result.isError === true) return true;
@@ -77011,18 +77459,7 @@ function diagnoseCodeModeTypeScript(input) {
77011
77459
  const startedAt = Date.now();
77012
77460
  const diagnostics = [...preflightDiagnostics(input.code)];
77013
77461
  if (diagnostics.length >= maxDiagnostics) return diagnostics.slice(0, maxDiagnostics);
77014
- const compilerOptions = {
77015
- target: ts.ScriptTarget.ES2022,
77016
- module: ts.ModuleKind.ESNext,
77017
- moduleResolution: ts.ModuleResolutionKind.Bundler,
77018
- lib: ["lib.es2022.d.ts"],
77019
- types: [],
77020
- strict: true,
77021
- noEmit: true,
77022
- skipLibCheck: true,
77023
- noErrorTruncation: true,
77024
- allowJs: false
77025
- };
77462
+ const compilerOptions = codeModeCompilerOptions();
77026
77463
  const wrappedCode = [
77027
77464
  "async function __capletsCodeModeMain(): Promise<unknown> {",
77028
77465
  input.code,
@@ -77031,7 +77468,7 @@ function diagnoseCodeModeTypeScript(input) {
77031
77468
  const host = createVirtualCompilerHost(compilerOptions, {
77032
77469
  [CODE_FILE]: wrappedCode,
77033
77470
  [DECLARATION_FILE]: input.declaration,
77034
- [AMBIENT_FILE]: CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION
77471
+ [AMBIENT_FILE]: [CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION, input.session?.declaration() ?? ""].join("\n")
77035
77472
  });
77036
77473
  const program = ts.createProgram([
77037
77474
  CODE_FILE,
@@ -77062,6 +77499,172 @@ function diagnoseCodeModeTypeScript(input) {
77062
77499
  }
77063
77500
  return diagnostics.slice(0, maxDiagnostics);
77064
77501
  }
77502
+ function codeModeCompilerOptions() {
77503
+ return {
77504
+ target: ts.ScriptTarget.ES2022,
77505
+ module: ts.ModuleKind.ESNext,
77506
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
77507
+ lib: ["lib.es2022.d.ts"],
77508
+ types: [],
77509
+ strict: true,
77510
+ noEmit: true,
77511
+ skipLibCheck: true,
77512
+ noErrorTruncation: true,
77513
+ allowJs: false
77514
+ };
77515
+ }
77516
+ var CodeModeDiagnosticsSession = class {
77517
+ #declarations = /* @__PURE__ */ new Map();
77518
+ declaration() {
77519
+ return [...this.#declarations.values()].join("\n");
77520
+ }
77521
+ recordSuccessfulCell(code, declaration = "") {
77522
+ const source = ts.createSourceFile("/caplets-code-mode/session-cell.ts", code, ts.ScriptTarget.ES2022, true);
77523
+ const compilerOptions = codeModeCompilerOptions();
77524
+ const ambientDeclarations = [
77525
+ CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION,
77526
+ declaration,
77527
+ this.declaration()
77528
+ ].join("\n");
77529
+ const host = createVirtualCompilerHost(compilerOptions, {
77530
+ [CODE_FILE]: code,
77531
+ [AMBIENT_FILE]: ambientDeclarations
77532
+ });
77533
+ const program = ts.createProgram([CODE_FILE, AMBIENT_FILE], compilerOptions, host);
77534
+ const checker = program.getTypeChecker();
77535
+ const programSource = program.getSourceFile(CODE_FILE) ?? source;
77536
+ for (const statement of programSource.statements) if (ts.isFunctionDeclaration(statement) && statement.name) {
77537
+ const typeParameters = statement.typeParameters ? `<${statement.typeParameters.map((typeParameter) => typeParameter.getText(programSource)).join(", ")}>` : "";
77538
+ const params = statement.parameters.map((parameter) => ambientParameter(parameter, programSource));
77539
+ const signature = checker.getSignatureFromDeclaration(statement);
77540
+ const inferredReturnType = signature ? safeAmbientFunctionReturnType(checker.getReturnTypeOfSignature(signature), checker, ambientDeclarations) : "unknown";
77541
+ const returnType = statement.type ? statement.type.getText(programSource) : inferredReturnType;
77542
+ this.#declarations.set(statement.name.text, `declare function ${statement.name.text}${typeParameters}(${params.join(", ")}): ${returnType};`);
77543
+ }
77544
+ const previousBindingNames = new Set(this.#declarations.keys());
77545
+ const assignedNames = collectFunctionScopedAssignedNames(programSource);
77546
+ for (const binding of collectFunctionScopedVarBindings(programSource, checker, {
77547
+ ambientDeclarationFor: (name) => [
77548
+ CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION,
77549
+ declaration,
77550
+ this.declarationExcluding(name)
77551
+ ].filter(Boolean).join("\n"),
77552
+ assignedNames,
77553
+ previousBindingNames
77554
+ })) this.#declarations.set(binding.name, `declare var ${binding.name}: ${binding.type};`);
77555
+ }
77556
+ clear() {
77557
+ this.#declarations.clear();
77558
+ }
77559
+ declarationExcluding(name) {
77560
+ const declarations = [CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION];
77561
+ for (const [declarationName, declaration] of this.#declarations) if (declarationName !== name) declarations.push(declaration);
77562
+ return declarations.join("\n");
77563
+ }
77564
+ };
77565
+ function collectFunctionScopedVarBindings(source, checker, options) {
77566
+ const bindings = /* @__PURE__ */ new Map();
77567
+ const visit = (node) => {
77568
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
77569
+ if (ts.isVariableStatement(node)) collectVarDeclarationListBindings(node.declarationList, checker, bindings, options);
77570
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer)) collectVarDeclarationListBindings(node.initializer, checker, bindings, options);
77571
+ ts.forEachChild(node, visit);
77572
+ };
77573
+ visit(source);
77574
+ return [...bindings.entries()].map(([name, type]) => ({
77575
+ name,
77576
+ type
77577
+ }));
77578
+ }
77579
+ function collectVarDeclarationListBindings(declarationList, checker, bindings, options) {
77580
+ if (!((ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0)) return;
77581
+ for (const declaration of declarationList.declarations) for (const name of bindingNames$1(declaration.name)) {
77582
+ const type = ambientTypeForBindingName(name, checker, options.ambientDeclarationFor(name.text));
77583
+ if (options.previousBindingNames.has(name.text) && declaration.initializer === void 0 && !options.assignedNames.has(name.text)) continue;
77584
+ bindings.set(name.text, type);
77585
+ }
77586
+ }
77587
+ function bindingNames$1(name) {
77588
+ if (ts.isIdentifier(name)) return [name];
77589
+ return name.elements.flatMap((element) => {
77590
+ if (ts.isOmittedExpression(element)) return [];
77591
+ return bindingNames$1(element.name);
77592
+ });
77593
+ }
77594
+ function collectFunctionScopedAssignedNames(source) {
77595
+ const names = /* @__PURE__ */ new Set();
77596
+ const visit = (node) => {
77597
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
77598
+ if (ts.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) collectAssignedBindingNames(node.left, names);
77599
+ if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) && (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken)) collectAssignedBindingNames(node.operand, names);
77600
+ ts.forEachChild(node, visit);
77601
+ };
77602
+ visit(source);
77603
+ return names;
77604
+ }
77605
+ function isAssignmentOperator(kind) {
77606
+ return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
77607
+ }
77608
+ function collectAssignedBindingNames(node, names) {
77609
+ if (ts.isIdentifier(node)) {
77610
+ names.add(node.text);
77611
+ return;
77612
+ }
77613
+ if (ts.isPropertyAssignment(node)) {
77614
+ collectAssignedBindingNames(node.initializer, names);
77615
+ return;
77616
+ }
77617
+ if (ts.isShorthandPropertyAssignment(node)) {
77618
+ names.add(node.name.text);
77619
+ return;
77620
+ }
77621
+ if (ts.isSpreadAssignment(node)) {
77622
+ collectAssignedBindingNames(node.expression, names);
77623
+ return;
77624
+ }
77625
+ if (ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node)) ts.forEachChild(node, (child) => collectAssignedBindingNames(child, names));
77626
+ }
77627
+ function ambientTypeForBindingName(name, checker, ambientDeclaration) {
77628
+ const type = checker.getTypeAtLocation(name);
77629
+ return safeAmbientType(name.text, type, checker, ambientDeclaration);
77630
+ }
77631
+ function safeAmbientType(name, type, checker, ambientDeclaration) {
77632
+ return safeAmbientTypeText(type, checker, ambientDeclaration, (typeText) => isSelfContainedAmbientDeclaration(`declare let ${name}: ${typeText};`, ambientDeclaration));
77633
+ }
77634
+ function safeAmbientFunctionReturnType(type, checker, ambientDeclaration) {
77635
+ return safeAmbientTypeText(type, checker, ambientDeclaration, (typeText) => isSelfContainedAmbientDeclaration(`declare function __caplets_return_probe__(): ${typeText};`, ambientDeclaration));
77636
+ }
77637
+ function safeAmbientTypeText(type, checker, ambientDeclaration, isSelfContained) {
77638
+ if (isUnsafeAmbientType(type)) return "unknown";
77639
+ const text = checker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts.TypeFormatFlags.WriteArrayAsGenericType);
77640
+ if (!text || text === "any" || text === "{}" || text === "never") return "unknown";
77641
+ if (text.length > 500) return "unknown";
77642
+ if (/\bimport\(/u.test(text)) return "unknown";
77643
+ if (!isSelfContained(text)) return "unknown";
77644
+ return text;
77645
+ }
77646
+ function isUnsafeAmbientType(type) {
77647
+ return Boolean(type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never));
77648
+ }
77649
+ function isSelfContainedAmbientDeclaration(candidateDeclaration, ambientDeclaration) {
77650
+ const compilerOptions = codeModeCompilerOptions();
77651
+ const host = createVirtualCompilerHost(compilerOptions, {
77652
+ [CODE_FILE]: candidateDeclaration,
77653
+ [AMBIENT_FILE]: ambientDeclaration
77654
+ });
77655
+ const program = ts.createProgram([CODE_FILE, AMBIENT_FILE], compilerOptions, host);
77656
+ return program.getSemanticDiagnostics(program.getSourceFile(CODE_FILE)).length === 0;
77657
+ }
77658
+ function ambientParameter(parameter, source) {
77659
+ return `${parameter.dotDotDotToken ? "..." : ""}${parameter.name.getText(source)}${parameter.questionToken || parameter.initializer ? "?" : ""}: ${parameter.type?.getText(source) ?? (parameter.initializer ? inferLiteralType(parameter.initializer) : "unknown")}`;
77660
+ }
77661
+ function inferLiteralType(initializer) {
77662
+ if (!initializer) return "unknown";
77663
+ if (ts.isNumericLiteral(initializer)) return "number";
77664
+ if (ts.isStringLiteral(initializer)) return "string";
77665
+ if (initializer.kind === ts.SyntaxKind.TrueKeyword || initializer.kind === ts.SyntaxKind.FalseKeyword) return "boolean";
77666
+ return "unknown";
77667
+ }
77065
77668
  function preflightDiagnostics(code) {
77066
77669
  const diagnostics = [];
77067
77670
  if (!hasExecutableImport(code)) {} else diagnostics.push({
@@ -77192,10 +77795,393 @@ function resolveTimer(context, deferred, fired) {
77192
77795
  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})();";
77193
77796
  //#endregion
77194
77797
  //#region src/code-mode/sandbox.ts
77798
+ const CODE_MODE_SANDBOX_METHODS = new Set([
77799
+ "inspect",
77800
+ "check",
77801
+ "tools",
77802
+ "searchTools",
77803
+ "describeTool",
77804
+ "callTool",
77805
+ "resources",
77806
+ "searchResources",
77807
+ "resourceTemplates",
77808
+ "readResource",
77809
+ "prompts",
77810
+ "searchPrompts",
77811
+ "getPrompt",
77812
+ "complete",
77813
+ "readLogs",
77814
+ "readRecovery"
77815
+ ]);
77816
+ const CODE_MODE_DEBUG_METHODS = new Set(["readLogs", "readRecovery"]);
77195
77817
  var QuickJsCodeModeSandbox = class {
77196
77818
  async run(input) {
77197
77819
  return await evaluateInQuickJs(input);
77198
77820
  }
77821
+ async createSession() {
77822
+ return new QuickJsCodeModeReplSession((await getQuickJS()).newRuntime());
77823
+ }
77824
+ };
77825
+ var QuickJsCodeModeReplSession = class {
77826
+ #runtime;
77827
+ #context;
77828
+ #pendingDeferreds = /* @__PURE__ */ new Set();
77829
+ #pendingInvokes = /* @__PURE__ */ new Set();
77830
+ #platformHost;
77831
+ #capletIds = /* @__PURE__ */ new Set();
77832
+ #persistentNames = /* @__PURE__ */ new Set();
77833
+ #invoke = async () => {
77834
+ throw new Error("Code Mode invoke bridge is not initialized.");
77835
+ };
77836
+ #deadlineMs = 0;
77837
+ #timeoutMs = 0;
77838
+ #logs = [];
77839
+ #disposed = false;
77840
+ #running = false;
77841
+ #disposeRequested = false;
77842
+ #globalNameCheckpoint = /* @__PURE__ */ new Set();
77843
+ #persistDescriptorCheckpoint = "";
77844
+ #checkpointToken = randomUUID();
77845
+ constructor(runtime) {
77846
+ this.#runtime = runtime;
77847
+ this.#runtime.setMemoryLimit(64 * 1024 * 1024);
77848
+ this.#runtime.setMaxStackSize(1 * 1024 * 1024);
77849
+ this.#context = runtime.newContext();
77850
+ this.#installStableBridges();
77851
+ this.#platformHost = installCodeModePlatformHost(this.#context, this.#pendingDeferreds, {});
77852
+ this.#evalInitSource();
77853
+ }
77854
+ async run(input) {
77855
+ if (this.#disposed) return {
77856
+ ok: false,
77857
+ error: "Code Mode session is disposed.",
77858
+ logs: []
77859
+ };
77860
+ if (this.#disposeRequested) return {
77861
+ ok: false,
77862
+ error: "Code Mode session is disposed.",
77863
+ logs: []
77864
+ };
77865
+ if (this.#running) return {
77866
+ ok: false,
77867
+ error: "Code Mode session is already running.",
77868
+ logs: []
77869
+ };
77870
+ this.#running = true;
77871
+ const timeoutMs = Math.max(100, input.timeoutMs);
77872
+ const deadlineMs = Date.now() + timeoutMs;
77873
+ this.#runtime.setInterruptHandler(shouldInterruptAfterDeadline(deadlineMs));
77874
+ this.#logs = [];
77875
+ let shouldDispose = false;
77876
+ try {
77877
+ this.#refreshInvokeBridge(input.invoke, deadlineMs, timeoutMs);
77878
+ const bridgeResult = this.#context.evalCode(buildBridgeRefreshSource(input.capletIds, [...this.#capletIds]));
77879
+ if (bridgeResult.error) {
77880
+ const error = this.#context.dump(bridgeResult.error);
77881
+ bridgeResult.error.dispose();
77882
+ const result = {
77883
+ ok: false,
77884
+ error: normalizeError(error, deadlineMs, timeoutMs),
77885
+ logs: this.#logs,
77886
+ ...optionalStack(stackFromDump(error))
77887
+ };
77888
+ shouldDispose = isTimeoutMessage(result.error, timeoutMs);
77889
+ return result;
77890
+ }
77891
+ bridgeResult.value.dispose();
77892
+ this.#capletIds = new Set(input.capletIds);
77893
+ const cell = buildSessionCellSource(input.code, input.capletIds, [...this.#persistentNames], this.#checkpointToken);
77894
+ const resetResult = this.#context.evalCode(buildPlatformResetSource());
77895
+ if (resetResult.error) {
77896
+ const error = this.#context.dump(resetResult.error);
77897
+ resetResult.error.dispose();
77898
+ const result = {
77899
+ ok: false,
77900
+ error: `Code Mode session state is corrupted: ${normalizeError(error, deadlineMs, timeoutMs)}`,
77901
+ logs: this.#logs,
77902
+ ...optionalStack(stackFromDump(error))
77903
+ };
77904
+ shouldDispose = true;
77905
+ return result;
77906
+ }
77907
+ resetResult.value.dispose();
77908
+ this.#snapshotGlobalNames();
77909
+ this.#snapshotPersistDescriptors();
77910
+ this.#snapshotPersistentNames([...this.#persistentNames]);
77911
+ let pendingInvokePersistentValuesChanged = false;
77912
+ const result = await evaluateCellInContext({
77913
+ code: input.code,
77914
+ compiledSource: cell.source,
77915
+ context: this.#context,
77916
+ runtime: this.#runtime,
77917
+ pendingDeferreds: this.#pendingDeferreds,
77918
+ pendingInvokes: this.#pendingInvokes,
77919
+ deadlineMs,
77920
+ timeoutMs,
77921
+ logs: this.#logs,
77922
+ session: true,
77923
+ afterPendingInvokesDrained: () => {
77924
+ pendingInvokePersistentValuesChanged = this.#persistentValuesDivergedFromPersist(cell.persistentNames);
77925
+ this.#snapshotPersistentNames(cell.persistentNames);
77926
+ }
77927
+ });
77928
+ if (result.ok) {
77929
+ for (const name of cell.persistentNames) this.#persistentNames.add(name);
77930
+ this.#snapshotPersistentNames(cell.persistentNames);
77931
+ } else {
77932
+ this.#restorePersistentNames([...this.#persistentNames]);
77933
+ this.#rollbackNewPersistentNames(cell.newNames);
77934
+ }
77935
+ const platformRestored = result.ok ? this.#restorePlatformAfterRun() : true;
77936
+ const persistenceDescriptorsOk = result.ok && platformRestored ? this.#persistentDescriptorsOk(cell.persistentNames) : true;
77937
+ const persistentGlobalDescriptorsOk = this.#persistentGlobalDescriptorsOk(result.ok ? cell.persistentNames : [...this.#persistentNames]);
77938
+ const hasGlobalNameAdditions = this.#hasGlobalNameAdditions(result.ok ? cell.persistentNames : []);
77939
+ const directPersistAccess = this.#isPersistTainted();
77940
+ const persistDescriptorsChanged = this.#persistDescriptorsChanged(result.ok ? cell.snapshotNames : []);
77941
+ const hasObjectLikePersistentState = this.#hasObjectLikePersistentState();
77942
+ shouldDispose = result.ok ? pendingInvokePersistentValuesChanged || this.#pendingDeferreds.size > 0 || hasGlobalNameAdditions || directPersistAccess || persistDescriptorsChanged || !this.#isGlobalExtensible() || !persistentGlobalDescriptorsOk || !persistenceDescriptorsOk || !platformRestored : isTimeoutMessage(result.error, timeoutMs) || this.#pendingDeferreds.size > 0 || cell.newNames.length > 0 || hasGlobalNameAdditions || directPersistAccess || persistDescriptorsChanged || hasObjectLikePersistentState || !persistentGlobalDescriptorsOk || !this.#isGlobalExtensible();
77943
+ if (!shouldDispose) this.#clearPendingDeferreds();
77944
+ return result;
77945
+ } catch (error) {
77946
+ const result = {
77947
+ ok: false,
77948
+ error: normalizeError(error, deadlineMs, timeoutMs),
77949
+ logs: this.#logs,
77950
+ ...optionalStack(stackFromError(error))
77951
+ };
77952
+ shouldDispose = true;
77953
+ return result;
77954
+ } finally {
77955
+ this.#running = false;
77956
+ if (!this.#disposed) this.#runtime.setInterruptHandler(() => false);
77957
+ if (shouldDispose) this.dispose();
77958
+ if (this.#disposeRequested) this.#disposeNow();
77959
+ }
77960
+ }
77961
+ dispose() {
77962
+ if (this.#disposed) return;
77963
+ if (this.#running) {
77964
+ this.#disposeRequested = true;
77965
+ return;
77966
+ }
77967
+ this.#disposeNow();
77968
+ }
77969
+ isDisposed() {
77970
+ return this.#disposed;
77971
+ }
77972
+ #disposeNow() {
77973
+ if (this.#disposed) return;
77974
+ this.#disposeRequested = false;
77975
+ this.#disposed = true;
77976
+ this.#platformHost.dispose();
77977
+ for (const deferred of this.#pendingDeferreds) if (deferred.alive) deferred.dispose();
77978
+ this.#pendingDeferreds.clear();
77979
+ this.#pendingInvokes.clear();
77980
+ this.#context.dispose();
77981
+ this.#runtime.dispose();
77982
+ }
77983
+ #installStableBridges() {
77984
+ const logBridge = this.#context.newFunction("__caplets_log", (levelHandle, messageHandle) => {
77985
+ this.#logs.push({
77986
+ level: logLevel(this.#context.getString(levelHandle)),
77987
+ message: this.#context.getString(messageHandle),
77988
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
77989
+ });
77990
+ return this.#context.undefined;
77991
+ });
77992
+ this.#context.setProp(this.#context.global, "__caplets_log", logBridge);
77993
+ logBridge.dispose();
77994
+ const invokeBridge = createInvokeJsonBridge(this.#context, this.#pendingDeferreds, this.#pendingInvokes, () => this.#invoke, () => this.#deadlineMs, () => this.#timeoutMs, (capletId) => this.#capletIds.has(capletId));
77995
+ this.#context.setProp(this.#context.global, "__caplets_invoke_json", invokeBridge);
77996
+ invokeBridge.dispose();
77997
+ const activeCapletBridge = this.#context.newFunction("__caplets_is_active_id", (capletIdHandle) => this.#capletIds.has(this.#context.getString(capletIdHandle)) ? this.#context.true : this.#context.false);
77998
+ this.#context.setProp(this.#context.global, "__caplets_is_active_id", activeCapletBridge);
77999
+ activeCapletBridge.dispose();
78000
+ const protectInvokeBridge = this.#context.evalCode([
78001
+ "Object.defineProperty(globalThis, '__caplets_log', { configurable: false, writable: false, value: globalThis.__caplets_log });",
78002
+ "Object.defineProperty(globalThis, '__caplets_invoke_json', { configurable: false, writable: false, value: globalThis.__caplets_invoke_json });",
78003
+ "Object.defineProperty(globalThis, '__caplets_is_active_id', { configurable: false, writable: false, value: globalThis.__caplets_is_active_id });"
78004
+ ].join("\n"));
78005
+ if (protectInvokeBridge.error) {
78006
+ const error = this.#context.dump(protectInvokeBridge.error);
78007
+ protectInvokeBridge.error.dispose();
78008
+ throw new Error(errorMessage$2(error));
78009
+ }
78010
+ protectInvokeBridge.value.dispose();
78011
+ }
78012
+ #evalInitSource() {
78013
+ const result = this.#context.evalCode(buildSessionInitSource(this.#checkpointToken));
78014
+ if (result.error) {
78015
+ const error = this.#context.dump(result.error);
78016
+ result.error.dispose();
78017
+ throw new Error(errorMessage$2(error));
78018
+ }
78019
+ result.value.dispose();
78020
+ }
78021
+ #refreshInvokeBridge(invoke, deadlineMs, timeoutMs) {
78022
+ this.#invoke = invoke;
78023
+ this.#deadlineMs = deadlineMs;
78024
+ this.#timeoutMs = timeoutMs;
78025
+ }
78026
+ #rollbackNewPersistentNames(names) {
78027
+ if (names.length === 0 || this.#disposed) return;
78028
+ const result = this.#context.evalCode(names.map((name) => `(0, eval)(${JSON.stringify(`${name} = undefined;`)});`).join("\n"));
78029
+ if (result.error) {
78030
+ result.error.dispose();
78031
+ return;
78032
+ }
78033
+ result.value.dispose();
78034
+ }
78035
+ #clearPendingDeferreds() {
78036
+ this.#platformHost.dispose();
78037
+ for (const deferred of this.#pendingDeferreds) if (deferred.alive) deferred.dispose();
78038
+ this.#pendingDeferreds.clear();
78039
+ }
78040
+ #snapshotGlobalNames() {
78041
+ if (this.#disposed) return;
78042
+ const result = this.#context.evalCode("__caplets_global_keys()");
78043
+ if (result.error) {
78044
+ result.error.dispose();
78045
+ return;
78046
+ }
78047
+ const names = this.#context.dump(result.value);
78048
+ this.#globalNameCheckpoint = new Set(names.filter((name) => !this.#isInternalGlobalName(name)));
78049
+ result.value.dispose();
78050
+ }
78051
+ #snapshotPersistDescriptors() {
78052
+ if (this.#disposed) return;
78053
+ const result = this.#context.evalCode("__caplets_persist_descriptor_fingerprint()");
78054
+ if (result.error) {
78055
+ result.error.dispose();
78056
+ this.#persistDescriptorCheckpoint = "";
78057
+ return;
78058
+ }
78059
+ this.#persistDescriptorCheckpoint = String(this.#context.dump(result.value));
78060
+ result.value.dispose();
78061
+ }
78062
+ #persistDescriptorsChanged(allowedNames = []) {
78063
+ if (this.#disposed) return false;
78064
+ const result = this.#context.evalCode(`__caplets_persist_descriptor_fingerprint(${JSON.stringify(allowedNames)})`);
78065
+ if (result.error) {
78066
+ result.error.dispose();
78067
+ return true;
78068
+ }
78069
+ const fingerprint = String(this.#context.dump(result.value));
78070
+ result.value.dispose();
78071
+ return fingerprint !== filterPersistDescriptorFingerprint(this.#persistDescriptorCheckpoint, allowedNames);
78072
+ }
78073
+ #hasGlobalNameAdditions(allowedNames = []) {
78074
+ if (this.#disposed) return false;
78075
+ const result = this.#context.evalCode("__caplets_global_keys()");
78076
+ if (result.error) {
78077
+ result.error.dispose();
78078
+ return true;
78079
+ }
78080
+ const names = this.#context.dump(result.value);
78081
+ const allowedTokens = new Set(allowedNames.map((name) => `string:${name}`));
78082
+ const hasAdditions = names.filter((name) => !this.#isInternalGlobalName(name)).filter((name) => !allowedTokens.has(name)).some((name) => !this.#globalNameCheckpoint.has(name));
78083
+ result.value.dispose();
78084
+ return hasAdditions;
78085
+ }
78086
+ #isGlobalExtensible() {
78087
+ if (this.#disposed) return false;
78088
+ const result = this.#context.evalCode("__caplets_is_global_extensible()");
78089
+ if (result.error) {
78090
+ result.error.dispose();
78091
+ return false;
78092
+ }
78093
+ const isExtensible = this.#context.dump(result.value) === true;
78094
+ result.value.dispose();
78095
+ return isExtensible;
78096
+ }
78097
+ #restorePlatformAfterRun() {
78098
+ if (this.#disposed) return false;
78099
+ const result = this.#context.evalCode(buildPlatformResetSource());
78100
+ if (result.error) {
78101
+ result.error.dispose();
78102
+ return false;
78103
+ }
78104
+ result.value.dispose();
78105
+ return true;
78106
+ }
78107
+ #persistentDescriptorsOk(names) {
78108
+ if (names.length === 0 || this.#disposed) return true;
78109
+ const result = this.#context.evalCode(`__caplets_persist_descriptors_ok(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)})`);
78110
+ if (result.error) {
78111
+ result.error.dispose();
78112
+ return false;
78113
+ }
78114
+ const ok = this.#context.dump(result.value) === true;
78115
+ result.value.dispose();
78116
+ return ok;
78117
+ }
78118
+ #isPersistTainted() {
78119
+ if (this.#disposed) return false;
78120
+ const result = this.#context.evalCode(`__caplets_persist_is_tainted(${JSON.stringify(this.#checkpointToken)})`);
78121
+ if (result.error) {
78122
+ result.error.dispose();
78123
+ return true;
78124
+ }
78125
+ const tainted = this.#context.dump(result.value) === true;
78126
+ result.value.dispose();
78127
+ return tainted;
78128
+ }
78129
+ #hasObjectLikePersistentState() {
78130
+ if (this.#disposed || this.#persistentNames.size === 0) return false;
78131
+ const result = this.#context.evalCode(`__caplets_persist_has_object_like_values(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify([...this.#persistentNames])})`);
78132
+ if (result.error) {
78133
+ result.error.dispose();
78134
+ return true;
78135
+ }
78136
+ const hasObjectLike = this.#context.dump(result.value) === true;
78137
+ result.value.dispose();
78138
+ return hasObjectLike;
78139
+ }
78140
+ #persistentGlobalDescriptorsOk(names) {
78141
+ if (names.length === 0 || this.#disposed) return true;
78142
+ const result = this.#context.evalCode(`__caplets_persist_global_descriptors_ok(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)})`);
78143
+ if (result.error) {
78144
+ result.error.dispose();
78145
+ return false;
78146
+ }
78147
+ const ok = this.#context.dump(result.value) === true;
78148
+ result.value.dispose();
78149
+ return ok;
78150
+ }
78151
+ #isInternalGlobalName(name) {
78152
+ return name === "string:__caplets_log" || name === "string:__caplets_invoke_json" || name === "string:__caplets_is_active_id" || name === "string:__caplets_restore_platform" || name === "string:__caplets_global_keys" || name === "string:__caplets_assert_active_id" || name === "string:__caplets_handle" || name === "string:__caplets_persist" || name === "string:__caplets_persist_descriptor_fingerprint" || name === "string:__caplets_persist_descriptors_ok" || name === "string:__caplets_persist_is_tainted" || name === "string:__caplets_persist_has_object_like_values" || name === "string:__caplets_persist_global_descriptors_ok" || name === "string:__caplets_get_persist" || name === "string:__caplets_set_persist" || name === "string:__caplets_snapshot_persist" || name === "string:__caplets_checkpoint_value" || name === "string:__caplets_observe_promise" || name === "string:__caplets_json_parse";
78153
+ }
78154
+ #snapshotPersistentNames(names) {
78155
+ if (names.length === 0 || this.#disposed) return;
78156
+ const result = this.#context.evalCode(`globalThis.__caplets_snapshot_persist(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)});`);
78157
+ if (result.error) {
78158
+ result.error.dispose();
78159
+ return;
78160
+ }
78161
+ result.value.dispose();
78162
+ }
78163
+ #persistentValuesDivergedFromPersist(names) {
78164
+ if (this.#disposed || names.length === 0) return false;
78165
+ const result = this.#context.evalCode(`(${JSON.stringify(names)}).some((name) => !Object.is((0, eval)(name), globalThis.__caplets_get_persist(${JSON.stringify(this.#checkpointToken)}, name)))`);
78166
+ if (result.error) {
78167
+ result.error.dispose();
78168
+ return true;
78169
+ }
78170
+ try {
78171
+ return this.#context.dump(result.value) === true;
78172
+ } finally {
78173
+ result.value.dispose();
78174
+ }
78175
+ }
78176
+ #restorePersistentNames(names) {
78177
+ if (names.length === 0 || this.#disposed) return;
78178
+ const result = this.#context.evalCode(names.map((name) => [`globalThis.__caplets_set_persist(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(name)}, globalThis.__caplets_checkpoint_value(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(name)}));`, `(0, eval)(${JSON.stringify(`${name} = globalThis.__caplets_checkpoint_value(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(name)});`)});`].join("\n")).join("\n"));
78179
+ if (result.error) {
78180
+ result.error.dispose();
78181
+ return;
78182
+ }
78183
+ result.value.dispose();
78184
+ }
77199
78185
  };
77200
78186
  async function evaluateInQuickJs(input) {
77201
78187
  const timeoutMs = Math.max(100, input.timeoutMs);
@@ -77223,62 +78209,20 @@ async function evaluateInQuickJs(input) {
77223
78209
  const invokeBridge = createInvokeBridge(context, pendingDeferreds, input.invoke, deadlineMs, timeoutMs);
77224
78210
  context.setProp(context.global, "__caplets_invoke", invokeBridge);
77225
78211
  invokeBridge.dispose();
77226
- const evaluated = context.evalCode(buildExecutionSource(input.code, input.capletIds));
77227
- if (evaluated.error) {
77228
- const error = context.dump(evaluated.error);
77229
- evaluated.error.dispose();
77230
- return {
77231
- ok: false,
77232
- error: normalizeError(error, deadlineMs, timeoutMs),
77233
- logs,
77234
- ...optionalStack(stackFromDump(error))
77235
- };
77236
- }
77237
- context.setProp(context.global, "__caplets_result", evaluated.value);
77238
- evaluated.value.dispose();
77239
- const stateResult = context.evalCode([
77240
- "(function(p) {",
77241
- " var s = { settled: false, value: void 0, error: void 0 };",
77242
- " var formatError = function(e) {",
77243
- " if (e && typeof e === 'object' && typeof e.message === 'string') return e.message;",
77244
- " return String(e);",
77245
- " };",
77246
- " p.then(function(value) { s.value = value; s.settled = true; },",
77247
- " function(error) { s.error = formatError(error); s.settled = true; });",
77248
- " return s;",
77249
- "})(__caplets_result)"
77250
- ].join("\n"));
77251
- if (stateResult.error) {
77252
- const error = context.dump(stateResult.error);
77253
- stateResult.error.dispose();
77254
- return {
77255
- ok: false,
77256
- error: normalizeError(error, deadlineMs, timeoutMs),
77257
- logs,
77258
- ...optionalStack(stackFromDump(error))
77259
- };
77260
- }
77261
- const stateHandle = stateResult.value;
77262
78212
  try {
77263
- await drainAsync(context, runtime, pendingDeferreds, deadlineMs, timeoutMs);
77264
- if (!(readProp(context, stateHandle, "settled") === true)) return {
77265
- ok: false,
77266
- error: timeoutMessage(timeoutMs),
77267
- logs
77268
- };
77269
- const error = readProp(context, stateHandle, "error");
77270
- if (typeof error !== "undefined") return {
77271
- ok: false,
77272
- error: normalizeError(error, deadlineMs, timeoutMs),
77273
- logs
77274
- };
77275
- return {
77276
- ok: true,
77277
- value: readProp(context, stateHandle, "value"),
77278
- logs
77279
- };
78213
+ return await evaluateCellInContext({
78214
+ code: input.code,
78215
+ capletIds: input.capletIds,
78216
+ context,
78217
+ runtime,
78218
+ pendingDeferreds,
78219
+ pendingInvokes: pendingDeferreds,
78220
+ deadlineMs,
78221
+ timeoutMs,
78222
+ logs,
78223
+ session: false
78224
+ });
77280
78225
  } finally {
77281
- stateHandle.dispose();
77282
78226
  platformHost.dispose();
77283
78227
  }
77284
78228
  } finally {
@@ -77297,6 +78241,96 @@ async function evaluateInQuickJs(input) {
77297
78241
  runtime.dispose();
77298
78242
  }
77299
78243
  }
78244
+ async function evaluateCellInContext(input) {
78245
+ const observerResult = input.context.evalCode(buildPromiseObserverSource());
78246
+ if (observerResult.error) {
78247
+ const error = input.context.dump(observerResult.error);
78248
+ observerResult.error.dispose();
78249
+ return {
78250
+ ok: false,
78251
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78252
+ logs: input.logs,
78253
+ ...optionalStack(stackFromDump(error))
78254
+ };
78255
+ }
78256
+ observerResult.value.dispose();
78257
+ const evaluated = input.context.evalCode(input.compiledSource ?? (input.session ? buildSessionCellSource(input.code, input.capletIds ?? []).source : buildExecutionSource(input.code, input.capletIds ?? [])));
78258
+ if (evaluated.error) {
78259
+ const error = input.context.dump(evaluated.error);
78260
+ evaluated.error.dispose();
78261
+ return {
78262
+ ok: false,
78263
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78264
+ logs: input.logs,
78265
+ ...optionalStack(stackFromDump(error))
78266
+ };
78267
+ }
78268
+ const resultName = `__caplets_result_${randomUUID().replace(/-/gu, "_")}`;
78269
+ input.context.setProp(input.context.global, resultName, evaluated.value);
78270
+ evaluated.value.dispose();
78271
+ const stateResult = input.context.evalCode(buildPromiseStateSource(JSON.stringify(resultName)));
78272
+ cleanupTemporaryGlobals(input.context, JSON.stringify(resultName));
78273
+ if (stateResult.error) {
78274
+ const error = input.context.dump(stateResult.error);
78275
+ stateResult.error.dispose();
78276
+ return {
78277
+ ok: false,
78278
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78279
+ logs: input.logs,
78280
+ ...optionalStack(stackFromDump(error))
78281
+ };
78282
+ }
78283
+ const stateHandle = stateResult.value;
78284
+ try {
78285
+ if (input.session) {
78286
+ if (input.pendingInvokes.size > 0) {
78287
+ await drainAsync(input.context, input.runtime, input.pendingInvokes, input.deadlineMs, input.timeoutMs);
78288
+ await drainAsync(input.context, input.runtime, input.pendingDeferreds, input.deadlineMs, input.timeoutMs);
78289
+ await Promise.resolve();
78290
+ drainJobs(input.context, input.runtime, input.deadlineMs, input.timeoutMs);
78291
+ input.afterPendingInvokesDrained?.();
78292
+ } else drainJobs(input.context, input.runtime, input.deadlineMs, input.timeoutMs);
78293
+ const earlyResult = readSettledPromiseState(input.context, stateHandle, input.logs);
78294
+ if (earlyResult) return earlyResult;
78295
+ }
78296
+ await drainAsync(input.context, input.runtime, input.pendingDeferreds, input.deadlineMs, input.timeoutMs);
78297
+ if (!(readProp(input.context, stateHandle, "settled") === true)) return {
78298
+ ok: false,
78299
+ error: timeoutMessage(input.timeoutMs),
78300
+ logs: input.logs
78301
+ };
78302
+ return readSettledPromiseState(input.context, stateHandle, input.logs) ?? {
78303
+ ok: false,
78304
+ error: timeoutMessage(input.timeoutMs),
78305
+ logs: input.logs
78306
+ };
78307
+ } finally {
78308
+ stateHandle.dispose();
78309
+ }
78310
+ }
78311
+ function cleanupTemporaryGlobals(context, ...names) {
78312
+ if (names.length === 0) return;
78313
+ const result = context.evalCode(names.map((name) => `delete globalThis[${name}];`).join("\n"));
78314
+ if (result.error) {
78315
+ result.error.dispose();
78316
+ return;
78317
+ }
78318
+ result.value.dispose();
78319
+ }
78320
+ function readSettledPromiseState(context, stateHandle, logs) {
78321
+ if (!(readProp(context, stateHandle, "settled") === true)) return;
78322
+ const error = readProp(context, stateHandle, "error");
78323
+ if (typeof error !== "undefined") return {
78324
+ ok: false,
78325
+ error: errorMessage$2(error),
78326
+ logs
78327
+ };
78328
+ return {
78329
+ ok: true,
78330
+ value: readProp(context, stateHandle, "value"),
78331
+ logs
78332
+ };
78333
+ }
77300
78334
  function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeoutMs) {
77301
78335
  return context.newFunction("__caplets_invoke", (capletHandle, methodHandle, argsHandle) => {
77302
78336
  const capletId = context.getString(capletHandle);
@@ -77304,7 +78338,10 @@ function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeo
77304
78338
  const args = context.dump(argsHandle);
77305
78339
  const deferred = context.newPromise();
77306
78340
  pendingDeferreds.add(deferred);
77307
- deferred.settled.finally(() => pendingDeferreds.delete(deferred));
78341
+ deferred.settled.finally(() => {
78342
+ pendingDeferreds.delete(deferred);
78343
+ if (deferred.alive) deferred.dispose();
78344
+ });
77308
78345
  invoke({
77309
78346
  capletId,
77310
78347
  method,
@@ -77331,6 +78368,78 @@ function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeo
77331
78368
  return deferred.handle;
77332
78369
  });
77333
78370
  }
78371
+ function createInvokeJsonBridge(context, pendingDeferreds, pendingInvokes, invoke, deadlineMs, timeoutMs, isCapletActive) {
78372
+ return context.newFunction("__caplets_invoke_json", (capletHandle, methodHandle, argsHandle) => {
78373
+ const capletId = context.getString(capletHandle);
78374
+ const method = context.getString(methodHandle);
78375
+ const args = context.dump(argsHandle);
78376
+ const deferred = context.newPromise();
78377
+ pendingDeferreds.add(deferred);
78378
+ pendingInvokes.add(deferred);
78379
+ deferred.settled.finally(() => {
78380
+ pendingDeferreds.delete(deferred);
78381
+ pendingInvokes.delete(deferred);
78382
+ if (deferred.alive) deferred.dispose();
78383
+ });
78384
+ const debugMethod = CODE_MODE_DEBUG_METHODS.has(method);
78385
+ const debugCapletActive = capletId === "debug" && isCapletActive("debug");
78386
+ if (!isCodeModeSandboxMethod(method) || capletId === "debug" && !debugMethod && !debugCapletActive || capletId !== "debug" && debugMethod) {
78387
+ const errorHandle = context.newError(`Method ${method} is not available in this Code Mode session cell.`);
78388
+ deferred.reject(errorHandle);
78389
+ errorHandle.dispose();
78390
+ return deferred.handle;
78391
+ }
78392
+ if (!(capletId === "debug" && debugMethod) && !isCapletActive(capletId)) {
78393
+ const errorHandle = context.newError(`Caplet ${capletId} is not available in this Code Mode session cell.`);
78394
+ deferred.reject(errorHandle);
78395
+ errorHandle.dispose();
78396
+ return deferred.handle;
78397
+ }
78398
+ invoke()({
78399
+ capletId,
78400
+ method,
78401
+ args
78402
+ }).then((value) => {
78403
+ if (!deferred.alive) return;
78404
+ let valueHandle;
78405
+ try {
78406
+ const serialized = JSON.stringify(value);
78407
+ const parsed = context.evalCode(`globalThis.__caplets_json_parse(${JSON.stringify(serialized ?? "null")})`);
78408
+ if (parsed.error) {
78409
+ const error = context.dump(parsed.error);
78410
+ parsed.error.dispose();
78411
+ throw new Error(errorMessage$2(error));
78412
+ }
78413
+ valueHandle = parsed.value;
78414
+ deferred.resolve(valueHandle);
78415
+ } catch (error) {
78416
+ const errorHandle = context.newError(errorMessage$2(error));
78417
+ deferred.reject(errorHandle);
78418
+ errorHandle.dispose();
78419
+ } finally {
78420
+ valueHandle?.dispose();
78421
+ }
78422
+ }, (error) => {
78423
+ if (!deferred.alive) return;
78424
+ const message = Date.now() >= deadlineMs() ? timeoutMessage(timeoutMs()) : errorMessage$2(error);
78425
+ const errorHandle = context.newError(message);
78426
+ deferred.reject(errorHandle);
78427
+ errorHandle.dispose();
78428
+ });
78429
+ return deferred.handle;
78430
+ });
78431
+ }
78432
+ function isCodeModeSandboxMethod(method) {
78433
+ return CODE_MODE_SANDBOX_METHODS.has(method);
78434
+ }
78435
+ function filterPersistDescriptorFingerprint(fingerprint, allowedNames) {
78436
+ if (!fingerprint || allowedNames.length === 0) return fingerprint;
78437
+ const allowedTokens = new Set(allowedNames.map((name) => `string:${name}`));
78438
+ return fingerprint.split("|").filter((entry) => {
78439
+ const token = entry.startsWith("string:") ? entry.slice(0, entry.indexOf(":", 7)) : entry.startsWith("symbol:") ? entry.slice(0, entry.indexOf(":", 7)) : entry;
78440
+ return !allowedTokens.has(token);
78441
+ }).join("|");
78442
+ }
77334
78443
  function buildExecutionSource(code, capletIds) {
77335
78444
  const javascript = ts.transpileModule(code, { compilerOptions: {
77336
78445
  target: ts.ScriptTarget.ES2022,
@@ -77362,11 +78471,546 @@ function buildExecutionSource(code, capletIds) {
77362
78471
  ...capletIds.map((capletId) => `caplets[${JSON.stringify(capletId)}] = __handle(${JSON.stringify(capletId)});`),
77363
78472
  "caplets.debug = caplets.debug || {};",
77364
78473
  "caplets.debug.readLogs = (input) => __invoke('debug', 'readLogs', [input]);",
78474
+ "caplets.debug.readRecovery = (input) => __invoke('debug', 'readRecovery', [input]);",
77365
78475
  "(async () => {",
77366
78476
  javascript,
77367
78477
  "})()"
77368
78478
  ].join("\n");
77369
78479
  }
78480
+ function buildSessionInitSource(checkpointToken) {
78481
+ return [
78482
+ CODE_MODE_PLATFORM_RUNTIME_SOURCE,
78483
+ "const __caplets_restore_platform = (() => {",
78484
+ " const defineProperty = Object.defineProperty.bind(Object);",
78485
+ " const defineProperties = Object.defineProperties.bind(Object);",
78486
+ " const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors.bind(Object);",
78487
+ " const getPrototypeOf = Object.getPrototypeOf.bind(Object);",
78488
+ " const setPrototypeOf = Object.setPrototypeOf.bind(Object);",
78489
+ " const isExtensible = Object.isExtensible.bind(Object);",
78490
+ " const ownKeys = Reflect.ownKeys.bind(Reflect);",
78491
+ " const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);",
78492
+ " const arrayPush = Function.prototype.call.bind(Array.prototype.push);",
78493
+ " const globalSymbolIds = new Map();",
78494
+ " let nextGlobalSymbolId = 1;",
78495
+ " const keyToken = (key) => {",
78496
+ " if (typeof key !== 'symbol') return `string:${key}`;",
78497
+ " if (!globalSymbolIds.has(key)) globalSymbolIds.set(key, nextGlobalSymbolId++);",
78498
+ " return `symbol:${globalSymbolIds.get(key)}`;",
78499
+ " };",
78500
+ " const platformGlobals = [];",
78501
+ " const globalPrototypeSnapshot = getPrototypeOf(globalThis);",
78502
+ " const platformExtraObjects = [",
78503
+ " ['AsyncFunction.prototype', getPrototypeOf(async function() {})],",
78504
+ " ['AsyncFunctionConstructor', getPrototypeOf(async function() {}).constructor],",
78505
+ " ['GeneratorFunction.prototype', getPrototypeOf(function*() {})],",
78506
+ " ['GeneratorFunctionConstructor', getPrototypeOf(function*() {}).constructor],",
78507
+ " ['AsyncGeneratorFunction.prototype', getPrototypeOf(async function*() {})],",
78508
+ " ['AsyncGeneratorFunctionConstructor', getPrototypeOf(async function*() {}).constructor],",
78509
+ " ['GeneratorObjectPrototype', getPrototypeOf((function*() {})())],",
78510
+ " ['GeneratorObjectPrototypeParent', getPrototypeOf(getPrototypeOf((function*() {})()))],",
78511
+ " ['AsyncGeneratorObjectPrototype', getPrototypeOf((async function*() {})())],",
78512
+ " ['AsyncGeneratorObjectPrototypeParent', getPrototypeOf(getPrototypeOf((async function*() {})()))],",
78513
+ " ['ArrayIteratorPrototype', getPrototypeOf([][Symbol.iterator]())],",
78514
+ " ['IteratorPrototype', getPrototypeOf(getPrototypeOf([][Symbol.iterator]()))],",
78515
+ " ['StringIteratorPrototype', getPrototypeOf(''[Symbol.iterator]())],",
78516
+ " ['RegExpStringIteratorPrototype', getPrototypeOf(''.matchAll(/(?:)/g))],",
78517
+ " ['RegExpStringIteratorPrototypeParent', getPrototypeOf(getPrototypeOf(''.matchAll(/(?:)/g)))],",
78518
+ " ['MapIteratorPrototype', getPrototypeOf(new Map()[Symbol.iterator]())],",
78519
+ " ['SetIteratorPrototype', getPrototypeOf(new Set()[Symbol.iterator]())],",
78520
+ " ['TypedArrayConstructor', getPrototypeOf(Int8Array)],",
78521
+ " ['TypedArrayPrototype', getPrototypeOf(Int8Array.prototype)],",
78522
+ " ['AsyncFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(async function() {}))],",
78523
+ " ['GeneratorFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(function*() {}))],",
78524
+ " ['AsyncGeneratorFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(async function*() {}))],",
78525
+ " ];",
78526
+ " const platformExtraSnapshot = Object.create(null);",
78527
+ " const platformExtraPrototypeSnapshot = Object.create(null);",
78528
+ " const platformExtraExtensibleSnapshot = Object.create(null);",
78529
+ " const platformGlobalNames = ownKeys(globalThis);",
78530
+ " for (const name of platformGlobalNames) {",
78531
+ " const record = {",
78532
+ " name,",
78533
+ " descriptor: Object.getOwnPropertyDescriptor(globalThis, name),",
78534
+ " value: globalThis[name],",
78535
+ " objectPrototype: undefined,",
78536
+ " properties: undefined,",
78537
+ " prototypeProperties: undefined,",
78538
+ " prototypeChain: undefined,",
78539
+ " extensible: undefined,",
78540
+ " prototypeExtensible: undefined,",
78541
+ " };",
78542
+ " const value = globalThis[name];",
78543
+ " if (value !== globalThis && ((typeof value === 'object' && value !== null) || typeof value === 'function')) {",
78544
+ " record.objectPrototype = getPrototypeOf(value);",
78545
+ " record.properties = getOwnPropertyDescriptors(value);",
78546
+ " record.extensible = isExtensible(value);",
78547
+ " const prototype = value.prototype;",
78548
+ " if ((typeof prototype === 'object' && prototype !== null) || typeof prototype === 'function') {",
78549
+ " record.prototypeChain = getPrototypeOf(prototype);",
78550
+ " record.prototypeProperties = getOwnPropertyDescriptors(prototype);",
78551
+ " record.prototypeExtensible = isExtensible(prototype);",
78552
+ " }",
78553
+ " }",
78554
+ " arrayPush(platformGlobals, record);",
78555
+ " }",
78556
+ " for (const [name, value] of platformExtraObjects) {",
78557
+ " if ((typeof value === 'object' && value !== null) || typeof value === 'function') {",
78558
+ " platformExtraSnapshot[name] = getOwnPropertyDescriptors(value);",
78559
+ " platformExtraPrototypeSnapshot[name] = getPrototypeOf(value);",
78560
+ " platformExtraExtensibleSnapshot[name] = isExtensible(value);",
78561
+ " }",
78562
+ " }",
78563
+ " const globalKeys = () => {",
78564
+ " const keys = ownKeys(globalThis);",
78565
+ " const tokens = [];",
78566
+ " for (let index = 0; index < keys.length; index += 1) {",
78567
+ " const key = keys[index];",
78568
+ " arrayPush(tokens, keyToken(key));",
78569
+ " }",
78570
+ " return tokens;",
78571
+ " };",
78572
+ " const restore = () => {",
78573
+ " if (getPrototypeOf(globalThis) !== globalPrototypeSnapshot) {",
78574
+ " try { setPrototypeOf(globalThis, globalPrototypeSnapshot); } catch { throw new Error('Code Mode global prototype chain is not restorable'); }",
78575
+ " }",
78576
+ " for (const record of platformGlobals) {",
78577
+ " const name = record.name;",
78578
+ " try {",
78579
+ " defineProperty(globalThis, name, record.descriptor);",
78580
+ " const descriptors = record.properties;",
78581
+ " const value = globalThis[name];",
78582
+ " if (descriptors && ((typeof value === 'object' && value !== null) || typeof value === 'function')) {",
78583
+ " if (record.extensible && !isExtensible(value)) throw new Error(`Code Mode platform global ${String(name)} is non-extensible`);",
78584
+ " if (getPrototypeOf(value) !== record.objectPrototype) {",
78585
+ " try { setPrototypeOf(value, record.objectPrototype); } catch { throw new Error(`Code Mode platform global ${String(name)} prototype chain is not restorable`); }",
78586
+ " }",
78587
+ " for (const key of ownKeys(value)) {",
78588
+ " if (!hasOwn(descriptors, key)) {",
78589
+ " try { delete value[key]; } catch {}",
78590
+ " if (hasOwn(value, key)) throw new Error(`Code Mode platform global ${String(name)} has non-restorable property ${String(key)}`);",
78591
+ " }",
78592
+ " }",
78593
+ " defineProperties(value, descriptors);",
78594
+ " const prototypeDescriptors = record.prototypeProperties;",
78595
+ " const prototype = value.prototype;",
78596
+ " if (prototypeDescriptors && ((typeof prototype === 'object' && prototype !== null) || typeof prototype === 'function')) {",
78597
+ " if (record.prototypeExtensible && !isExtensible(prototype)) throw new Error(`Code Mode platform prototype ${String(name)}.prototype is non-extensible`);",
78598
+ " if (getPrototypeOf(prototype) !== record.prototypeChain) {",
78599
+ " try { setPrototypeOf(prototype, record.prototypeChain); } catch { throw new Error(`Code Mode platform prototype ${String(name)}.prototype chain is not restorable`); }",
78600
+ " }",
78601
+ " for (const key of ownKeys(prototype)) {",
78602
+ " if (!hasOwn(prototypeDescriptors, key)) {",
78603
+ " try { delete prototype[key]; } catch {}",
78604
+ " if (hasOwn(prototype, key)) throw new Error(`Code Mode platform prototype ${String(name)}.prototype has non-restorable property ${String(key)}`);",
78605
+ " }",
78606
+ " }",
78607
+ " defineProperties(prototype, prototypeDescriptors);",
78608
+ " }",
78609
+ " }",
78610
+ " } catch (error) {",
78611
+ " throw new Error(`Code Mode platform global ${String(name)} is not restorable: ${String(error && error.message ? error.message : error)}`);",
78612
+ " }",
78613
+ " }",
78614
+ " for (const [name, value] of platformExtraObjects) {",
78615
+ " const descriptors = platformExtraSnapshot[name];",
78616
+ " if (!descriptors || !((typeof value === 'object' && value !== null) || typeof value === 'function')) continue;",
78617
+ " if (platformExtraExtensibleSnapshot[name] && !isExtensible(value)) throw new Error(`Code Mode platform intrinsic ${name} is non-extensible`);",
78618
+ " if (getPrototypeOf(value) !== platformExtraPrototypeSnapshot[name]) {",
78619
+ " try { setPrototypeOf(value, platformExtraPrototypeSnapshot[name]); } catch { throw new Error(`Code Mode platform intrinsic ${name} prototype chain is not restorable`); }",
78620
+ " }",
78621
+ " for (const key of ownKeys(value)) {",
78622
+ " if (!hasOwn(descriptors, key)) {",
78623
+ " try { delete value[key]; } catch {}",
78624
+ " if (hasOwn(value, key)) throw new Error(`Code Mode platform intrinsic ${name} has non-restorable property ${String(key)}`);",
78625
+ " }",
78626
+ " }",
78627
+ " defineProperties(value, descriptors);",
78628
+ " }",
78629
+ " };",
78630
+ " return { restore, globalKeys, isGlobalExtensible: () => isExtensible(globalThis) };",
78631
+ "})();",
78632
+ "Object.defineProperty(globalThis, '__caplets_restore_platform', { configurable: false, writable: false, value: __caplets_restore_platform.restore });",
78633
+ "Object.defineProperty(globalThis, '__caplets_global_keys', { configurable: false, writable: false, value: __caplets_restore_platform.globalKeys });",
78634
+ "Object.defineProperty(globalThis, '__caplets_is_global_extensible', { configurable: false, writable: false, value: __caplets_restore_platform.isGlobalExtensible });",
78635
+ "Object.defineProperty(globalThis, '__caplets_assert_active_id', { configurable: false, writable: false, value: (capletId) => {",
78636
+ " if (capletId === 'debug' && !__caplets_is_active_id(capletId)) return;",
78637
+ " if (!__caplets_is_active_id(capletId)) throw new Error(`Caplet ${capletId} is not available in this Code Mode session cell.`);",
78638
+ "} });",
78639
+ "Object.defineProperty(globalThis, '__caplets_handle', { configurable: false, writable: false, value: (capletId) => ({",
78640
+ " id: capletId,",
78641
+ " inspect: () => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'inspect', [])),",
78642
+ " check: () => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'check', [])),",
78643
+ " tools: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'tools', [input])),",
78644
+ " searchTools: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchTools', [query, input])),",
78645
+ " describeTool: (name) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'describeTool', [name])),",
78646
+ " callTool: (name, args) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'callTool', [name, args])),",
78647
+ " resources: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'resources', [input])),",
78648
+ " searchResources: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchResources', [query, input])),",
78649
+ " resourceTemplates: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'resourceTemplates', [input])),",
78650
+ " readResource: (uri) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'readResource', [uri])),",
78651
+ " prompts: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'prompts', [input])),",
78652
+ " searchPrompts: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchPrompts', [query, input])),",
78653
+ " getPrompt: (name, args) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'getPrompt', [name, args])),",
78654
+ " complete: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'complete', [input])),",
78655
+ "}) });",
78656
+ "(() => {",
78657
+ ` const checkpointToken = ${JSON.stringify(checkpointToken)};`,
78658
+ " const persistBacking = Object.create(null);",
78659
+ " let persistTainted = false;",
78660
+ " const checkpointState = { current: Object.create(null) };",
78661
+ " const ownKeys = Reflect.ownKeys.bind(Reflect);",
78662
+ " const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor.bind(Object);",
78663
+ " const defineProperty = Object.defineProperty.bind(Object);",
78664
+ " const getPrototypeOf = Object.getPrototypeOf.bind(Object);",
78665
+ " const reflectGet = Reflect.get.bind(Reflect);",
78666
+ " const reflectSet = Reflect.set.bind(Reflect);",
78667
+ " const reflectDefineProperty = Reflect.defineProperty.bind(Reflect);",
78668
+ " const reflectDeleteProperty = Reflect.deleteProperty.bind(Reflect);",
78669
+ " const reflectSetPrototypeOf = Reflect.setPrototypeOf.bind(Reflect);",
78670
+ " const reflectPreventExtensions = Reflect.preventExtensions.bind(Reflect);",
78671
+ " const reflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor.bind(Reflect);",
78672
+ " const reflectOwnKeys = Reflect.ownKeys.bind(Reflect);",
78673
+ " const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);",
78674
+ " const objectIds = new WeakMap();",
78675
+ " let nextObjectId = 1;",
78676
+ " const keyToken = (key) => typeof key === 'symbol' ? `symbol:${String(key)}` : `string:${key}`;",
78677
+ " const valueToken = (value) => {",
78678
+ " const type = typeof value;",
78679
+ " if ((type === 'object' && value !== null) || type === 'function') {",
78680
+ " if (!objectIds.has(value)) objectIds.set(value, nextObjectId++);",
78681
+ " return `${type}:${objectIds.get(value)}`;",
78682
+ " }",
78683
+ " return `${type}:${String(value)}`;",
78684
+ " };",
78685
+ " const descriptorToken = (descriptor) => {",
78686
+ " if (!descriptor) return 'missing';",
78687
+ " return [",
78688
+ " hasOwn(descriptor, 'value') ? 'data' : 'accessor',",
78689
+ " descriptor.writable === true ? 'w' : 'nw',",
78690
+ " descriptor.configurable === true ? 'c' : 'nc',",
78691
+ " descriptor.enumerable === true ? 'e' : 'ne',",
78692
+ " typeof descriptor.get,",
78693
+ " typeof descriptor.set,",
78694
+ " ].join(':');",
78695
+ " };",
78696
+ " const assertToken = (token) => {",
78697
+ " if (token !== checkpointToken) throw new Error('Code Mode persistence checkpoint token is invalid.');",
78698
+ " };",
78699
+ " const persistProxy = new Proxy(persistBacking, {",
78700
+ " get(target, key, receiver) { persistTainted = true; return reflectGet(target, key, receiver); },",
78701
+ " set(target, key, value, receiver) { persistTainted = true; return reflectSet(target, key, value, receiver); },",
78702
+ " defineProperty(target, key, descriptor) { persistTainted = true; return reflectDefineProperty(target, key, descriptor); },",
78703
+ " deleteProperty(target, key) { persistTainted = true; return reflectDeleteProperty(target, key); },",
78704
+ " setPrototypeOf(target, prototype) { persistTainted = true; return reflectSetPrototypeOf(target, prototype); },",
78705
+ " preventExtensions(target) { persistTainted = true; return reflectPreventExtensions(target); },",
78706
+ " getOwnPropertyDescriptor(target, key) { persistTainted = true; return reflectGetOwnPropertyDescriptor(target, key); },",
78707
+ " ownKeys(target) { persistTainted = true; return reflectOwnKeys(target); },",
78708
+ " getPrototypeOf(target) { persistTainted = true; return getPrototypeOf(target); },",
78709
+ " });",
78710
+ " Object.defineProperty(globalThis, '__caplets_persist', { configurable: false, writable: false, value: persistProxy });",
78711
+ " Object.defineProperty(globalThis, '__caplets_get_persist', { configurable: false, writable: false, value: (token, name) => {",
78712
+ " assertToken(token);",
78713
+ " return hasOwn(persistBacking, name) ? persistBacking[name] : undefined;",
78714
+ " } });",
78715
+ " Object.defineProperty(globalThis, '__caplets_set_persist', { configurable: false, writable: false, value: (token, name, value) => {",
78716
+ " assertToken(token);",
78717
+ " defineProperty(persistBacking, name, { value, writable: true, configurable: true, enumerable: true });",
78718
+ " return value;",
78719
+ " } });",
78720
+ " Object.defineProperty(globalThis, '__caplets_persist_is_tainted', { configurable: false, writable: false, value: (token) => {",
78721
+ " assertToken(token);",
78722
+ " return persistTainted;",
78723
+ " } });",
78724
+ " Object.defineProperty(globalThis, '__caplets_persist_has_object_like_values', { configurable: false, writable: false, value: (token, names) => {",
78725
+ " assertToken(token);",
78726
+ " for (const name of names) {",
78727
+ " if (!hasOwn(persistBacking, name)) continue;",
78728
+ " const value = persistBacking[name];",
78729
+ " if ((typeof value === 'object' && value !== null) || typeof value === 'function') return true;",
78730
+ " }",
78731
+ " return false;",
78732
+ " } });",
78733
+ " Object.defineProperty(globalThis, '__caplets_persist_global_descriptors_ok', { configurable: false, writable: false, value: (token, names) => {",
78734
+ " assertToken(token);",
78735
+ " for (const name of names) {",
78736
+ " const descriptor = getOwnPropertyDescriptor(globalThis, name);",
78737
+ " if (!descriptor || !hasOwn(descriptor, 'value') || descriptor.writable !== true) return false;",
78738
+ " }",
78739
+ " return true;",
78740
+ " } });",
78741
+ " Object.defineProperty(globalThis, '__caplets_persist_descriptor_fingerprint', { configurable: false, writable: false, value: (allowedNames = []) => {",
78742
+ " const allowed = new Set(allowedNames.map((name) => `string:${name}`));",
78743
+ " const prototype = getPrototypeOf(persistBacking);",
78744
+ " const keys = ownKeys(persistBacking).map((key) => keyToken(key)).filter((token) => !allowed.has(token)).sort();",
78745
+ " return keys.map((token) => {",
78746
+ " const key = token.startsWith('symbol:') ? ownKeys(persistBacking).find((candidate) => keyToken(candidate) === token) : token.slice('string:'.length);",
78747
+ " const descriptor = getOwnPropertyDescriptor(persistBacking, key);",
78748
+ " const value = descriptor && hasOwn(descriptor, 'value') ? valueToken(descriptor.value) : 'accessor';",
78749
+ " return `${token}:${descriptorToken(descriptor)}:${value}`;",
78750
+ " }).concat(`[[Prototype]]:${valueToken(prototype)}`).join('|');",
78751
+ " } });",
78752
+ " Object.defineProperty(globalThis, '__caplets_persist_descriptors_ok', { configurable: false, writable: false, value: (token, names) => {",
78753
+ " assertToken(token);",
78754
+ " if (getPrototypeOf(persistBacking) !== null) return false;",
78755
+ " for (const name of names) {",
78756
+ " const descriptor = getOwnPropertyDescriptor(persistBacking, name);",
78757
+ " if (!descriptor || !hasOwn(descriptor, 'value')) return false;",
78758
+ " if (descriptor.get || descriptor.set || descriptor.writable !== true || descriptor.configurable !== true) return false;",
78759
+ " }",
78760
+ " return true;",
78761
+ " } });",
78762
+ " Object.defineProperty(globalThis, '__caplets_snapshot_persist', { configurable: false, writable: false, value: (token, names) => {",
78763
+ " assertToken(token);",
78764
+ " const next = Object.create(null);",
78765
+ " for (const name of names) {",
78766
+ " try { next[name] = (0, eval)(name); }",
78767
+ " catch { next[name] = hasOwn(globalThis, name) ? globalThis[name] : hasOwn(persistBacking, name) ? persistBacking[name] : undefined; }",
78768
+ " }",
78769
+ " checkpointState.current = next;",
78770
+ " } });",
78771
+ " Object.defineProperty(globalThis, '__caplets_checkpoint_value', { configurable: false, writable: false, value: (token, name) => {",
78772
+ " assertToken(token);",
78773
+ " return checkpointState.current[name];",
78774
+ " } });",
78775
+ "})();",
78776
+ "Object.defineProperty(globalThis, '__caplets_json_parse', { configurable: false, writable: false, value: JSON.parse.bind(JSON) });"
78777
+ ].join("\n");
78778
+ }
78779
+ function buildBridgeRefreshSource(_capletIds, _previousCapletIds = []) {
78780
+ return "";
78781
+ }
78782
+ function buildSessionCellSource(code, capletIds, existingNames = [], checkpointToken = "") {
78783
+ const javascript = ts.transpileModule(code, { compilerOptions: {
78784
+ target: ts.ScriptTarget.ES2022,
78785
+ module: ts.ModuleKind.ESNext,
78786
+ importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Remove
78787
+ } }).outputText;
78788
+ const split = splitPersistentPrelude(javascript, existingNames, checkpointToken);
78789
+ return {
78790
+ source: [
78791
+ split.prelude,
78792
+ "(async () => {",
78793
+ "\"use strict\";",
78794
+ buildPlatformResetSource(),
78795
+ buildPlatformShadowRestoreSource(existingNames, checkpointToken),
78796
+ buildCellCapletsSource(capletIds),
78797
+ split.body,
78798
+ split.postlude,
78799
+ "})()"
78800
+ ].join("\n"),
78801
+ persistentNames: split.persistentNames,
78802
+ newNames: split.newNames,
78803
+ snapshotNames: split.snapshotNames
78804
+ };
78805
+ }
78806
+ function buildPlatformResetSource() {
78807
+ return "globalThis.__caplets_restore_platform();";
78808
+ }
78809
+ function buildPlatformShadowRestoreSource(existingNames, checkpointToken) {
78810
+ return existingNames.map((name) => `(0, eval)(${JSON.stringify(`${name} = globalThis.__caplets_get_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)});`)});`).join("\n");
78811
+ }
78812
+ function buildCellCapletsSource(capletIds) {
78813
+ return [
78814
+ "const caplets = {};",
78815
+ ...capletIds.map((capletId) => `caplets[${JSON.stringify(capletId)}] = __caplets_handle(${JSON.stringify(capletId)});`),
78816
+ "caplets.debug = caplets.debug ?? {};",
78817
+ "caplets.debug.readLogs = (input) => __caplets_invoke_json('debug', 'readLogs', [input]);",
78818
+ "caplets.debug.readRecovery = (input) => __caplets_invoke_json('debug', 'readRecovery', [input]);"
78819
+ ].join("\n");
78820
+ }
78821
+ function splitPersistentPrelude(javascript, existingNames = [], checkpointToken = "") {
78822
+ const source = ts.createSourceFile("/caplets-code-mode/session-cell.js", javascript, ts.ScriptTarget.ES2022, true);
78823
+ const ranges = [];
78824
+ const names = collectPersistentBindingNames(source);
78825
+ const lexicalNames = collectTopLevelLexicalBindingNames(source);
78826
+ const allNames = [...new Set([...existingNames, ...names])];
78827
+ const snapshotNames = allNames.filter((name) => !lexicalNames.has(name));
78828
+ const returnTempName = uniqueInternalName("__caplets_return", allNames);
78829
+ const postlude = snapshotNames.map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
78830
+ for (const statement of source.statements) {
78831
+ collectPersistentVarRewriteRanges(statement, source, lexicalNames, ranges);
78832
+ collectPersistentReturnRanges(statement, source, snapshotNames, ranges, returnTempName, checkpointToken);
78833
+ collectPersistentFinallyRanges(statement, snapshotNames, ranges, checkpointToken);
78834
+ }
78835
+ ranges.sort((left, right) => left.start - right.start);
78836
+ const prelude = [...allNames.map((name) => `var ${name} = globalThis.__caplets_get_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)});`), ...ranges.map((range) => range.prelude)].filter(Boolean).join("\n");
78837
+ let body = "";
78838
+ let cursor = 0;
78839
+ for (const range of ranges) {
78840
+ body += javascript.slice(cursor, range.start);
78841
+ body += range.body;
78842
+ cursor = range.end;
78843
+ }
78844
+ body += javascript.slice(cursor);
78845
+ if (postlude) body += `\n${postlude}`;
78846
+ return {
78847
+ prelude,
78848
+ body,
78849
+ postlude,
78850
+ persistentNames: allNames,
78851
+ newNames: names.filter((name) => !existingNames.includes(name)),
78852
+ snapshotNames
78853
+ };
78854
+ }
78855
+ function collectPersistentReturnRanges(node, source, snapshotNames, ranges, returnTempName, checkpointToken, shadowedNames = /* @__PURE__ */ new Set()) {
78856
+ if (snapshotNames.length === 0) return;
78857
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78858
+ const declared = lexicalNamesDeclaredByNode(node);
78859
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
78860
+ if (ts.isReturnStatement(node)) {
78861
+ const expression = node.expression?.getText(source);
78862
+ const postludeExpression = snapshotNames.filter((name) => !activeShadowedNames.has(name)).map((name) => persistentBindingExpression(name, checkpointToken)).join(", ");
78863
+ ranges.push({
78864
+ start: node.getFullStart(),
78865
+ end: node.end,
78866
+ prelude: "",
78867
+ body: returnWithPersistenceExpression(expression, postludeExpression, returnTempName)
78868
+ });
78869
+ return;
78870
+ }
78871
+ ts.forEachChild(node, (child) => collectPersistentReturnRanges(child, source, snapshotNames, ranges, returnTempName, checkpointToken, activeShadowedNames));
78872
+ }
78873
+ function lexicalNamesDeclaredByNode(node) {
78874
+ const names = /* @__PURE__ */ new Set();
78875
+ if (ts.isBlock(node) || ts.isCaseClause(node) || ts.isDefaultClause(node)) for (const statement of node.statements) {
78876
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78877
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78878
+ if (ts.isFunctionDeclaration(statement) && statement.name) names.add(statement.name.text);
78879
+ }
78880
+ if (ts.isSwitchStatement(node)) for (const clause of node.caseBlock.clauses) for (const statement of clause.statements) {
78881
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78882
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78883
+ if (ts.isFunctionDeclaration(statement) && statement.name) names.add(statement.name.text);
78884
+ }
78885
+ if (ts.isCatchClause(node) && node.variableDeclaration) for (const name of bindingNames(node.variableDeclaration.name)) names.add(name);
78886
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer) && !isVarDeclarationList(node.initializer)) for (const name of declarationListBindingNames(node.initializer)) names.add(name);
78887
+ return names;
78888
+ }
78889
+ function returnWithPersistenceExpression(expression, postludeExpression, returnTempName) {
78890
+ if (!postludeExpression) return expression ? `return ${expression};` : "return;";
78891
+ return expression ? `return (async (${returnTempName}) => { await Promise.resolve(); ${postludeExpression}; return ${returnTempName}; })((${expression}));` : `await Promise.resolve();\nreturn void (${postludeExpression});`;
78892
+ }
78893
+ function uniqueInternalName(baseName, unavailableNames) {
78894
+ const unavailable = new Set(unavailableNames);
78895
+ let name = baseName;
78896
+ while (unavailable.has(name)) name = `_${name}`;
78897
+ return name;
78898
+ }
78899
+ function collectPersistentVarRewriteRanges(node, source, lexicalNames, ranges) {
78900
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78901
+ if (ts.isVariableStatement(node) && isVarDeclarationList(node.declarationList)) {
78902
+ if (!declarationListBindingNames(node.declarationList).some((name) => lexicalNames.has(name))) ranges.push({
78903
+ start: node.getFullStart(),
78904
+ end: node.end,
78905
+ prelude: "",
78906
+ body: varStatementAssignments(node.declarationList, source)
78907
+ });
78908
+ return;
78909
+ }
78910
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer) && isVarDeclarationList(node.initializer)) {
78911
+ if (!declarationListBindingNames(node.initializer).some((name) => lexicalNames.has(name))) ranges.push({
78912
+ start: node.initializer.getStart(source),
78913
+ end: node.initializer.end,
78914
+ prelude: "",
78915
+ body: forInitializerAssignment(node.initializer, source)
78916
+ });
78917
+ }
78918
+ ts.forEachChild(node, (child) => collectPersistentVarRewriteRanges(child, source, lexicalNames, ranges));
78919
+ }
78920
+ function collectPersistentFinallyRanges(node, snapshotNames, ranges, checkpointToken, shadowedNames = /* @__PURE__ */ new Set()) {
78921
+ if (snapshotNames.length === 0) return;
78922
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78923
+ const declared = lexicalNamesDeclaredByNode(node);
78924
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
78925
+ if (ts.isTryStatement(node) && node.finallyBlock) {
78926
+ const finallyDeclared = lexicalNamesDeclaredByNode(node.finallyBlock);
78927
+ const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : new Set([...activeShadowedNames, ...finallyDeclared]);
78928
+ const postlude = snapshotNames.filter((name) => !finallyShadowedNames.has(name)).map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
78929
+ if (postlude) ranges.push({
78930
+ start: node.finallyBlock.end - 1,
78931
+ end: node.finallyBlock.end - 1,
78932
+ prelude: "",
78933
+ body: `\n${postlude}\n`
78934
+ });
78935
+ }
78936
+ ts.forEachChild(node, (child) => collectPersistentFinallyRanges(child, snapshotNames, ranges, checkpointToken, activeShadowedNames));
78937
+ }
78938
+ function collectPersistentBindingNames(source) {
78939
+ const names = /* @__PURE__ */ new Set();
78940
+ const visit = (node) => {
78941
+ if (ts.isFunctionDeclaration(node) && node.name && node.parent === source) names.add(node.name.text);
78942
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
78943
+ if (ts.isVariableStatement(node)) collectVarDeclarationListNames(node.declarationList, names);
78944
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer)) collectVarDeclarationListNames(node.initializer, names);
78945
+ ts.forEachChild(node, visit);
78946
+ };
78947
+ visit(source);
78948
+ return [...names];
78949
+ }
78950
+ function collectTopLevelLexicalBindingNames(source) {
78951
+ const names = /* @__PURE__ */ new Set();
78952
+ for (const statement of source.statements) {
78953
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78954
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78955
+ }
78956
+ return names;
78957
+ }
78958
+ function collectVarDeclarationListNames(declarationList, names) {
78959
+ if (!((ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0)) return;
78960
+ for (const declaration of declarationList.declarations) for (const name of bindingNames(declaration.name)) names.add(name);
78961
+ }
78962
+ function isVarDeclarationList(declarationList) {
78963
+ return (ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0;
78964
+ }
78965
+ function declarationListBindingNames(declarationList) {
78966
+ return declarationList.declarations.flatMap((declaration) => bindingNames(declaration.name));
78967
+ }
78968
+ function varStatementAssignments(declarationList, source) {
78969
+ return declarationList.declarations.map((declaration) => declaration.initializer ? assignmentStatement(declaration.name, declaration.initializer, source) : "").filter(Boolean).join("\n");
78970
+ }
78971
+ function forInitializerAssignment(declarationList, source) {
78972
+ return declarationList.declarations.map((declaration) => declaration.initializer ? assignmentExpression(declaration.name, declaration.initializer, source) : declaration.name.getText(source)).join(", ");
78973
+ }
78974
+ function persistentBindingPostlude(name, checkpointToken) {
78975
+ return [`globalThis.__caplets_set_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)}, ${name});`, `(0, eval)(${JSON.stringify(`${name} = globalThis.__caplets_get_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)});`)});`].join("\n");
78976
+ }
78977
+ function persistentBindingExpression(name, checkpointToken) {
78978
+ return [`globalThis.__caplets_set_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)}, ${name})`, `(0, eval)(${JSON.stringify(`${name} = globalThis.__caplets_get_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)});`)})`].join(", ");
78979
+ }
78980
+ function bindingNames(name) {
78981
+ if (ts.isIdentifier(name)) return [name.text];
78982
+ return name.elements.flatMap((element) => {
78983
+ if (ts.isOmittedExpression(element)) return [];
78984
+ return bindingNames(element.name);
78985
+ });
78986
+ }
78987
+ function assignmentStatement(name, initializer, source) {
78988
+ const expression = assignmentExpression(name, initializer, source);
78989
+ return ts.isObjectBindingPattern(name) ? `(${expression});` : `${expression};`;
78990
+ }
78991
+ function assignmentExpression(name, initializer, source) {
78992
+ return `${name.getText(source)} = ${initializer.getText(source)}`;
78993
+ }
78994
+ function buildPromiseObserverSource() {
78995
+ return [
78996
+ "(() => {",
78997
+ " const then = Promise.prototype.then;",
78998
+ " const formatError = function(e) {",
78999
+ " if (e && typeof e === 'object' && typeof e.message === 'string') return e.message;",
79000
+ " return String(e);",
79001
+ " };",
79002
+ " try { Object.defineProperty(globalThis, '__caplets_observe_promise', { configurable: false, writable: false, value: function(p) {",
79003
+ " var s = { settled: false, value: void 0, error: void 0 };",
79004
+ " then.call(p, function(value) { s.value = value; s.settled = true; },",
79005
+ " function(error) { s.error = formatError(error); s.settled = true; });",
79006
+ " return s;",
79007
+ " } }); } catch {}",
79008
+ "})()"
79009
+ ].join("\n");
79010
+ }
79011
+ function buildPromiseStateSource(resultName) {
79012
+ return [`globalThis.__caplets_observe_promise(globalThis[${resultName}])`].join("\n");
79013
+ }
77370
79014
  async function drainAsync(context, runtime, pendingDeferreds, deadlineMs, timeoutMs) {
77371
79015
  drainJobs(context, runtime, deadlineMs, timeoutMs);
77372
79016
  while (pendingDeferreds.size > 0) {
@@ -77409,6 +79053,9 @@ function readProp(context, handle, key) {
77409
79053
  function timeoutMessage(timeoutMs) {
77410
79054
  return `Code Mode execution timed out after ${timeoutMs}ms`;
77411
79055
  }
79056
+ function isTimeoutMessage(message, timeoutMs) {
79057
+ return message === timeoutMessage(timeoutMs);
79058
+ }
77412
79059
  function normalizeError(error, deadlineMs, timeoutMs) {
77413
79060
  const message = errorMessage$2(error);
77414
79061
  return Date.now() >= deadlineMs && /\binterrupted\b/iu.test(message) ? timeoutMessage(timeoutMs) : message;
@@ -77431,6 +79078,181 @@ function optionalStack(stack) {
77431
79078
  function logLevel(value) {
77432
79079
  return value === "info" || value === "warn" || value === "error" || value === "debug" || value === "log" ? value : "log";
77433
79080
  }
79081
+ var CodeModeSessionManager = class {
79082
+ ttlMs;
79083
+ maxSessions;
79084
+ #sessions = /* @__PURE__ */ new Map();
79085
+ #idGenerator;
79086
+ #now;
79087
+ #sandboxFactory;
79088
+ #closed = false;
79089
+ constructor(options = {}) {
79090
+ this.ttlMs = options.ttlMs ?? 18e5;
79091
+ this.maxSessions = options.maxSessions ?? 32;
79092
+ this.#idGenerator = options.idGenerator ?? randomUUID;
79093
+ this.#now = options.now ?? Date.now;
79094
+ this.#sandboxFactory = options.sandboxFactory ?? (() => new QuickJsCodeModeSandbox());
79095
+ }
79096
+ async run(input) {
79097
+ if (this.#closed) return {
79098
+ ok: false,
79099
+ sessionId: input.sessionId ?? "",
79100
+ sessionStatus: null,
79101
+ error: "closed"
79102
+ };
79103
+ this.#evictExpired();
79104
+ const compatibilityKey = compatibilityKeyFor(input.compatibility);
79105
+ const requestedSessionId = input.sessionId;
79106
+ let record;
79107
+ let sessionStatus;
79108
+ if (requestedSessionId) {
79109
+ record = this.#sessions.get(requestedSessionId);
79110
+ if (!record) return {
79111
+ ok: false,
79112
+ sessionId: requestedSessionId,
79113
+ sessionStatus: null,
79114
+ error: "not_found"
79115
+ };
79116
+ if (record.busy) return {
79117
+ ok: false,
79118
+ sessionId: requestedSessionId,
79119
+ sessionStatus: null,
79120
+ error: "busy"
79121
+ };
79122
+ if (record.compatibilityKey !== compatibilityKey) {
79123
+ this.#disposeRecord(record.id);
79124
+ return {
79125
+ ok: false,
79126
+ sessionId: requestedSessionId,
79127
+ sessionStatus: null,
79128
+ error: "not_found"
79129
+ };
79130
+ } else sessionStatus = "reused";
79131
+ } else {
79132
+ const sessionId = this.#nextSessionId();
79133
+ record = await this.#createRecord(sessionId, compatibilityKey);
79134
+ if (!record) return this.#closedResult(sessionId);
79135
+ sessionStatus = "created";
79136
+ }
79137
+ this.#evictToLimit(record.id);
79138
+ record.busy = true;
79139
+ try {
79140
+ const result = await record.session.run({
79141
+ ...input,
79142
+ invoke: async (invokeInput) => {
79143
+ if (this.#closed) throw new Error("Code Mode session manager is closed.");
79144
+ return await input.invoke(invokeInput);
79145
+ }
79146
+ });
79147
+ record.lastUsedAt = this.#now();
79148
+ const sessionDisposedAfterRun = record.session.isDisposed();
79149
+ if (sessionDisposedAfterRun) this.#sessions.delete(record.id);
79150
+ else if (result.ok) input.onSuccessfulCell?.(record.id, input.code);
79151
+ return {
79152
+ ok: true,
79153
+ sessionId: record.id,
79154
+ sessionStatus,
79155
+ sessionDisposedAfterRun,
79156
+ compatibilityKey: record.compatibilityKey,
79157
+ result
79158
+ };
79159
+ } finally {
79160
+ record.busy = false;
79161
+ this.#evictToLimit(record.id);
79162
+ }
79163
+ }
79164
+ close() {
79165
+ this.#closed = true;
79166
+ for (const record of this.#sessions.values()) record.session.dispose();
79167
+ this.#sessions.clear();
79168
+ }
79169
+ has(sessionId) {
79170
+ this.#evictExpired();
79171
+ return this.#sessions.has(sessionId);
79172
+ }
79173
+ compatibilityKey(sessionId) {
79174
+ this.#evictExpired();
79175
+ return this.#sessions.get(sessionId)?.compatibilityKey;
79176
+ }
79177
+ diagnosticsSession(sessionId, compatibility) {
79178
+ this.#evictExpired();
79179
+ const record = this.#sessions.get(sessionId);
79180
+ if (!record) return void 0;
79181
+ const compatibilityKey = compatibilityKeyFor(compatibility);
79182
+ if (record.compatibilityKey !== compatibilityKey) {
79183
+ this.#disposeRecord(sessionId);
79184
+ return;
79185
+ }
79186
+ return record.diagnosticsSession;
79187
+ }
79188
+ isBusy(sessionId, compatibility) {
79189
+ this.#evictExpired();
79190
+ const record = this.#sessions.get(sessionId);
79191
+ if (!record) return false;
79192
+ const compatibilityKey = compatibilityKeyFor(compatibility);
79193
+ if (record.compatibilityKey !== compatibilityKey) return false;
79194
+ return record.busy;
79195
+ }
79196
+ recordSuccessfulCell(sessionId, code, declaration = "") {
79197
+ this.#sessions.get(sessionId)?.diagnosticsSession.recordSuccessfulCell(code, declaration);
79198
+ }
79199
+ async #createRecord(id, compatibilityKey) {
79200
+ if (this.#closed) return;
79201
+ const session = await this.#sandboxFactory().createSession();
79202
+ if (this.#closed) {
79203
+ session.dispose();
79204
+ return;
79205
+ }
79206
+ const record = {
79207
+ id,
79208
+ session,
79209
+ diagnosticsSession: new CodeModeDiagnosticsSession(),
79210
+ compatibilityKey,
79211
+ lastUsedAt: this.#now(),
79212
+ busy: false
79213
+ };
79214
+ this.#sessions.set(id, record);
79215
+ return record;
79216
+ }
79217
+ #nextSessionId() {
79218
+ let id = this.#idGenerator();
79219
+ while (this.#sessions.has(id)) id = this.#idGenerator();
79220
+ return id;
79221
+ }
79222
+ #evictExpired() {
79223
+ const now = this.#now();
79224
+ for (const record of this.#sessions.values()) if (!record.busy && now - record.lastUsedAt > this.ttlMs) this.#disposeRecord(record.id);
79225
+ }
79226
+ #evictToLimit(protectedId) {
79227
+ while (this.#sessions.size > this.maxSessions) {
79228
+ const candidate = [...this.#sessions.values()].filter((record) => !record.busy && record.id !== protectedId).sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0];
79229
+ if (!candidate) return;
79230
+ this.#disposeRecord(candidate.id);
79231
+ }
79232
+ }
79233
+ #disposeRecord(id) {
79234
+ const record = this.#sessions.get(id);
79235
+ if (!record) return;
79236
+ record.session.dispose();
79237
+ this.#sessions.delete(id);
79238
+ }
79239
+ #closedResult(sessionId) {
79240
+ return {
79241
+ ok: false,
79242
+ sessionId,
79243
+ sessionStatus: null,
79244
+ error: "closed"
79245
+ };
79246
+ }
79247
+ };
79248
+ function compatibilityKeyFor(input) {
79249
+ return JSON.stringify({
79250
+ declarationHash: input.declarationHash,
79251
+ platformRuntimeHash: input.platformRuntimeHash,
79252
+ runtimeScope: input.runtimeScope,
79253
+ version: input.version ?? 1
79254
+ });
79255
+ }
77434
79256
  //#endregion
77435
79257
  //#region src/code-mode/runner.ts
77436
79258
  const DEFAULT_TIMEOUT_MS = 1e4;
@@ -77443,45 +79265,126 @@ async function runCodeMode(input) {
77443
79265
  const callable = listCodeModeCallableCaplets(input.service);
77444
79266
  const declaration = generateCodeModeDeclarations({ caplets: callable });
77445
79267
  const declarationHash = codeModeDeclarationHash(declaration);
79268
+ const sessionCompatibility = {
79269
+ declarationHash,
79270
+ platformRuntimeHash: codeModeDeclarationHash(CODE_MODE_PLATFORM_RUNTIME_SOURCE),
79271
+ runtimeScope: input.runtimeScope ?? "",
79272
+ version: 1
79273
+ };
79274
+ const diagnosticsSession = input.sessionManager && input.sessionId ? input.sessionManager.diagnosticsSession(input.sessionId, sessionCompatibility) : void 0;
77446
79275
  const metaBase = {
77447
79276
  runId: randomUUID(),
77448
79277
  traceId: randomUUID(),
77449
79278
  declarationHash,
77450
79279
  timeoutMs,
77451
- maxTimeoutMs
79280
+ maxTimeoutMs,
79281
+ sessionId: input.sessionManager ? null : input.sessionId ?? null,
79282
+ sessionStatus: null,
79283
+ recoveryRef: null
77452
79284
  };
77453
- const diagnostics = timeoutMs > maxTimeoutMs ? [{
77454
- code: "TIMEOUT_POLICY_EXCEEDED",
77455
- severity: "error",
77456
- message: `timeoutMs must be <= ${maxTimeoutMs}.`
77457
- }] : diagnoseCodeModeTypeScript({
77458
- code: input.code,
77459
- declaration
79285
+ const meta = () => ({
79286
+ ...metaBase,
79287
+ durationMs: Date.now() - startedAt
77460
79288
  });
77461
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) return {
79289
+ if (input.sessionId !== void 0 && !input.sessionManager) return {
77462
79290
  ok: false,
77463
79291
  error: {
77464
- code: "diagnostic_blocked",
77465
- message: "Code Mode diagnostics failed before execution."
79292
+ code: "SESSION_NOT_FOUND",
79293
+ message: "Code Mode session reuse is not available in this runtime. Omit sessionId to run one-shot."
77466
79294
  },
77467
- diagnostics,
79295
+ diagnostics: [],
79296
+ logs: emptyLogs(),
79297
+ meta: meta()
79298
+ };
79299
+ if (input.sessionManager && input.sessionId && input.sessionManager.isBusy(input.sessionId, sessionCompatibility)) return {
79300
+ ok: false,
79301
+ error: {
79302
+ code: "SESSION_BUSY",
79303
+ message: `Code Mode session ${input.sessionId} is already running.`
79304
+ },
79305
+ diagnostics: [],
77468
79306
  logs: emptyLogs(),
77469
79307
  meta: {
77470
- ...metaBase,
77471
- durationMs: Date.now() - startedAt
79308
+ ...meta(),
79309
+ sessionId: input.sessionId,
79310
+ sessionStatus: null
77472
79311
  }
77473
79312
  };
79313
+ const diagnostics = timeoutMs > maxTimeoutMs ? [{
79314
+ code: "TIMEOUT_POLICY_EXCEEDED",
79315
+ severity: "error",
79316
+ message: `timeoutMs must be <= ${maxTimeoutMs}.`
79317
+ }] : diagnoseCodeModeTypeScript({
79318
+ code: input.code,
79319
+ declaration,
79320
+ ...diagnosticsSession === void 0 ? {} : { session: diagnosticsSession }
79321
+ });
79322
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
79323
+ const diagnosticJournalScope = input.sessionManager && input.sessionId ? input.sessionManager.compatibilityKey(input.sessionId) : void 0;
79324
+ if (input.sessionManager && input.sessionId && diagnosticJournalScope === void 0) {
79325
+ const recoveryRef = await recoveryRefForSession(input, input.sessionId);
79326
+ return {
79327
+ ok: false,
79328
+ error: {
79329
+ code: "SESSION_NOT_FOUND",
79330
+ message: `Code Mode session ${input.sessionId} was not found.`
79331
+ },
79332
+ diagnostics,
79333
+ logs: emptyLogs(),
79334
+ meta: {
79335
+ ...meta(),
79336
+ sessionId: input.sessionId,
79337
+ sessionStatus: null,
79338
+ ...recoveryMeta(recoveryRef)
79339
+ }
79340
+ };
79341
+ }
79342
+ const recoveryRef = await journalRun(input, {
79343
+ sessionId: input.sessionId ?? null,
79344
+ code: input.code,
79345
+ declarationHash,
79346
+ diagnostics,
79347
+ logs: emptyLogs(),
79348
+ outcome: {
79349
+ ok: false,
79350
+ code: "diagnostic_blocked",
79351
+ message: "Code Mode diagnostics failed before execution."
79352
+ },
79353
+ invokedCaplet: false,
79354
+ sessionDisposedAfterRun: false,
79355
+ journalScope: diagnosticJournalScope
79356
+ });
79357
+ if (input.sessionManager && input.sessionId) {
79358
+ metaBase.sessionId = input.sessionId;
79359
+ metaBase.sessionStatus = "reused";
79360
+ }
79361
+ if (recoveryRef && !input.sessionManager) setRecoveryMeta(metaBase, recoveryRef);
79362
+ return {
79363
+ ok: false,
79364
+ error: {
79365
+ code: "diagnostic_blocked",
79366
+ message: "Code Mode diagnostics failed before execution."
79367
+ },
79368
+ diagnostics,
79369
+ logs: emptyLogs(),
79370
+ meta: meta()
79371
+ };
79372
+ }
77474
79373
  const capturedLogs = [];
79374
+ let invokedCaplet = false;
77475
79375
  const api = createCodeModeCapletsApi({
77476
79376
  service: input.service,
77477
- readLogs: async (readInput) => input.logStore?.read(readInput) ?? { entries: [] }
79377
+ readLogs: async (readInput) => input.logStore?.read(readInput) ?? { entries: [] },
79378
+ readRecovery: async (readInput) => input.journalStore?.readRecovery(readInput) ?? { entries: [] }
77478
79379
  });
77479
- const result = await (input.sandbox ?? new QuickJsCodeModeSandbox()).run({
79380
+ const sandboxInput = {
77480
79381
  code: input.code,
77481
79382
  capletIds: callable.map((caplet) => caplet.id),
77482
79383
  timeoutMs,
77483
79384
  invoke: async ({ capletId, method, args }) => {
77484
79385
  if (method === "readLogs") return await api.debug.readLogs(args[0]);
79386
+ if (method === "readRecovery") return await api.debug.readRecovery(args[0]);
79387
+ invokedCaplet = true;
77485
79388
  const handle = api[capletId];
77486
79389
  if (!handle || !("callTool" in handle)) throw new Error(`Caplet ${capletId} is not available.`);
77487
79390
  if (method === "inspect") return await handle.inspect();
@@ -77500,19 +79403,66 @@ async function runCodeMode(input) {
77500
79403
  if (method === "complete") return await handle.complete(args[0]);
77501
79404
  throw new Error(`Unknown Code Mode CapletHandle method: ${method}.`);
77502
79405
  }
77503
- });
79406
+ };
79407
+ const sessionRun = input.sessionManager ? await input.sessionManager.run({
79408
+ ...sandboxInput,
79409
+ ...input.sessionId === void 0 ? {} : { sessionId: input.sessionId },
79410
+ compatibility: sessionCompatibility,
79411
+ onSuccessfulCell: (sessionId, code) => {
79412
+ input.sessionManager?.recordSuccessfulCell(sessionId, code, declaration);
79413
+ }
79414
+ }) : void 0;
79415
+ if (sessionRun && !sessionRun.ok) {
79416
+ const recoveryRef = sessionRun.error === "not_found" ? await recoveryRefForSession(input, sessionRun.sessionId) : void 0;
79417
+ return {
79418
+ ok: false,
79419
+ error: {
79420
+ code: sessionRun.error === "not_found" ? "SESSION_NOT_FOUND" : sessionRun.error === "closed" ? "SESSION_CLOSED" : "SESSION_BUSY",
79421
+ message: sessionRun.error === "not_found" ? `Code Mode session ${sessionRun.sessionId} was not found.` : sessionRun.error === "closed" ? "Code Mode session manager is closed." : `Code Mode session ${sessionRun.sessionId} is already running.`
79422
+ },
79423
+ diagnostics,
79424
+ logs: emptyLogs(),
79425
+ meta: {
79426
+ ...meta(),
79427
+ sessionId: sessionRun.sessionId,
79428
+ sessionStatus: null,
79429
+ ...recoveryMeta(recoveryRef)
79430
+ }
79431
+ };
79432
+ }
79433
+ const result = sessionRun?.result ?? await (input.sandbox ?? new QuickJsCodeModeSandbox()).run(sandboxInput);
79434
+ const sessionId = sessionRun?.sessionId ?? metaBase.sessionId ?? null;
79435
+ const sessionStatus = sessionRun?.sessionStatus ?? metaBase.sessionStatus ?? null;
79436
+ const exposeRecoveryRef = !input.sessionManager || sessionStatus === "created";
79437
+ metaBase.sessionId = sessionRun?.sessionDisposedAfterRun ? null : sessionId;
79438
+ metaBase.sessionStatus = sessionRun?.sessionDisposedAfterRun ? null : sessionStatus;
77504
79439
  capturedLogs.push(...result.logs.map(redactLogEntry));
77505
79440
  const logs = await buildLogs(capturedLogs, input.logStore, input.returnedLogBytes);
77506
- if (!result.ok) return {
77507
- ok: false,
77508
- error: codeModeRuntimeError(result.error, result.stack),
77509
- diagnostics,
77510
- logs,
77511
- meta: {
77512
- ...metaBase,
77513
- durationMs: Date.now() - startedAt
77514
- }
77515
- };
79441
+ if (!result.ok) {
79442
+ const recoveryRef = await journalRun(input, {
79443
+ sessionId,
79444
+ code: input.code,
79445
+ declarationHash,
79446
+ diagnostics,
79447
+ logs,
79448
+ outcome: {
79449
+ ok: false,
79450
+ code: runtimeErrorCode(result.error),
79451
+ message: result.error
79452
+ },
79453
+ invokedCaplet,
79454
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79455
+ journalScope: sessionRun?.compatibilityKey
79456
+ });
79457
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
79458
+ return {
79459
+ ok: false,
79460
+ error: codeModeRuntimeError(result.error, result.stack),
79461
+ diagnostics,
79462
+ logs,
79463
+ meta: meta()
79464
+ };
79465
+ }
77516
79466
  const serialized = serializeJsonValue(result.value);
77517
79467
  if (!serialized.ok) {
77518
79468
  const serializationDiagnostic = {
@@ -77520,6 +79470,22 @@ async function runCodeMode(input) {
77520
79470
  severity: "error",
77521
79471
  message: serialized.message
77522
79472
  };
79473
+ const recoveryRef = await journalRun(input, {
79474
+ sessionId,
79475
+ code: input.code,
79476
+ declarationHash,
79477
+ diagnostics: [...diagnostics, serializationDiagnostic],
79478
+ logs,
79479
+ outcome: {
79480
+ ok: false,
79481
+ code: "SERIALIZATION_ERROR",
79482
+ message: serialized.message
79483
+ },
79484
+ invokedCaplet,
79485
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79486
+ journalScope: sessionRun?.compatibilityKey
79487
+ });
79488
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
77523
79489
  return {
77524
79490
  ok: false,
77525
79491
  error: {
@@ -77528,23 +79494,60 @@ async function runCodeMode(input) {
77528
79494
  },
77529
79495
  diagnostics: [...diagnostics, serializationDiagnostic],
77530
79496
  logs,
77531
- meta: {
77532
- ...metaBase,
77533
- durationMs: Date.now() - startedAt
77534
- }
79497
+ meta: meta()
77535
79498
  };
77536
79499
  }
79500
+ const recoveryRef = await journalRun(input, {
79501
+ sessionId,
79502
+ code: input.code,
79503
+ declarationHash,
79504
+ diagnostics,
79505
+ logs,
79506
+ outcome: { ok: true },
79507
+ invokedCaplet,
79508
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79509
+ journalScope: sessionRun?.compatibilityKey
79510
+ });
79511
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
77537
79512
  return {
77538
79513
  ok: true,
77539
79514
  value: serialized.value,
77540
79515
  diagnostics,
77541
79516
  logs,
77542
- meta: {
77543
- ...metaBase,
77544
- durationMs: Date.now() - startedAt
77545
- }
79517
+ meta: meta()
77546
79518
  };
77547
79519
  }
79520
+ async function journalRun(input, run) {
79521
+ if (!input.journalStore || !run.sessionId) return void 0;
79522
+ try {
79523
+ return (await input.journalStore.store({
79524
+ sessionId: run.sessionId,
79525
+ ...run.journalScope === void 0 ? {} : { journalScope: run.journalScope },
79526
+ code: run.code,
79527
+ declarationHash: run.declarationHash,
79528
+ outcome: run.outcome,
79529
+ diagnostics: run.diagnostics,
79530
+ recoveryClassification: classifyCodeModeRecovery({
79531
+ code: run.code,
79532
+ invokedCaplet: run.invokedCaplet,
79533
+ sessionDisposedAfterRun: run.sessionDisposedAfterRun
79534
+ }),
79535
+ ...run.logs.logRef ? { logRef: run.logs.logRef } : {}
79536
+ })).recoveryRef;
79537
+ } catch {
79538
+ return;
79539
+ }
79540
+ }
79541
+ function setRecoveryMeta(metaBase, recoveryRef) {
79542
+ metaBase.recoveryRef = recoveryRef;
79543
+ }
79544
+ async function recoveryRefForSession(input, sessionId) {
79545
+ return (await input.journalStore?.lookupSession(sessionId))?.recoveryRef;
79546
+ }
79547
+ function recoveryMeta(recoveryRef) {
79548
+ if (!recoveryRef) return { recoveryRef: null };
79549
+ return { recoveryRef };
79550
+ }
77548
79551
  function codeModeRuntimeError(message, stack) {
77549
79552
  const location = userCodeLocation(stack);
77550
79553
  const stackPreview = location === void 0 ? void 0 : [`at user code line ${location.line} column ${location.column}`];
@@ -77636,9 +79639,11 @@ function redactLogEntry(entry) {
77636
79639
  }
77637
79640
  //#endregion
77638
79641
  //#region src/code-mode/tool.ts
79642
+ const CODE_MODE_SESSION_ID_DESCRIPTION = "Optional Code Mode session identifier. Omit to create a fresh reusable session; pass a known live session ID from meta.sessionId to reuse existing REPL state. Unknown or unavailable session IDs fail before code execution instead of starting an empty context.";
77639
79643
  const codeModeRunInputSchema = object$1({
77640
79644
  code: string().describe("TypeScript Code Mode source to execute."),
77641
- timeoutMs: number$1().int().positive().optional().describe("Optional execution timeout in milliseconds.")
79645
+ timeoutMs: number$1().int().positive().optional().describe("Optional execution timeout in milliseconds."),
79646
+ sessionId: string().min(1).optional().describe(CODE_MODE_SESSION_ID_DESCRIPTION)
77642
79647
  });
77643
79648
  const codeModeRunParamsSchema = codeModeRunInputSchema.shape;
77644
79649
  function codeModeRunInputJsonSchema() {
@@ -77653,12 +79658,30 @@ function codeModeRunInputJsonSchema() {
77653
79658
  type: "integer",
77654
79659
  minimum: 1,
77655
79660
  description: "Optional execution timeout in milliseconds."
79661
+ },
79662
+ sessionId: {
79663
+ type: "string",
79664
+ minLength: 1,
79665
+ description: CODE_MODE_SESSION_ID_DESCRIPTION
77656
79666
  }
77657
79667
  },
77658
79668
  required: ["code"],
77659
79669
  additionalProperties: false
77660
79670
  };
77661
79671
  }
79672
+ function emptyCodeModeRunMeta() {
79673
+ return {
79674
+ runId: "",
79675
+ traceId: "",
79676
+ declarationHash: "",
79677
+ durationMs: 0,
79678
+ timeoutMs: 0,
79679
+ maxTimeoutMs: 0,
79680
+ sessionId: null,
79681
+ sessionStatus: null,
79682
+ recoveryRef: null
79683
+ };
79684
+ }
77662
79685
  //#endregion
77663
79686
  //#region src/native/tools.ts
77664
79687
  const nativeCodeModeToolId = "code_mode";
@@ -77676,12 +79699,23 @@ function nativeCapletsSystemGuidance(toolNames) {
77676
79699
  toolNames.length > 0 ? toolNames.map((tool) => `- ${tool}`).join("\n") : "- none",
77677
79700
  "",
77678
79701
  `${nativeCodeModeToolName} executes Caplets Code Mode: TypeScript with generated caplets.<id> handles for multi-step discovery, tool calls, filtering, and compact synthesis in one native call.`,
79702
+ ...nativeCodeModePromptGuidance(),
77679
79703
  "Flow: inspect when the domain is unfamiliar; use tools/search_tools for downstream names, arg hints, and callTemplate; call_tool directly from callTemplate/argsTemplate for simple calls; reserve describe_tool for complex schemas, nested args, fields, or uncertainty.",
77680
79704
  "Do not guess downstream tool names, resource URIs, prompt names, input args, output fields, or schemas. Do not infer input/output schemas from memory.",
77681
79705
  "Prefer list/read/search operations for triage and avoid broad provider searches that can return huge payloads or hit rate limits.",
77682
79706
  "When output shaping matters, inspect one tool with describe_tool and follow its fieldSelection hint."
77683
79707
  ].join("\n");
77684
79708
  }
79709
+ function nativeCodeModePromptGuidance() {
79710
+ return [
79711
+ `Use ${nativeCodeModeToolName} to run Caplets Code Mode TypeScript with generated caplets.<id> handles.`,
79712
+ "Prefer Code Mode for multi-step Caplet discovery, tool calls, filtering, joins, and compact synthesis.",
79713
+ "For REPL reuse, omit sessionId to start fresh, then pass the returned meta.sessionId on later calls that should reuse live state.",
79714
+ "Reused sessions preserve successful top-level var bindings, function declarations, and runtime state only while the live session remains available and compatible.",
79715
+ "Unknown or unavailable sessionId values fail before code execution; use meta.recoveryRef with caplets.debug.readRecovery({ recoveryRef }) for audit and manual reconstruction, not automatic replay.",
79716
+ "Return decision-ready JSON from Code Mode rather than raw bulky provider payloads."
79717
+ ];
79718
+ }
77685
79719
  function nativeCapletPromptGuidance(toolName, caplet) {
77686
79720
  const descriptorFirst = "Use tools/search_tools callTemplate/arg hints for simple calls; reserve describe_tool for exact schemas, nested args, fields, or uncertainty. call_tool.args must match inputSchema exactly. Do not guess tool names or schemas.";
77687
79721
  return caplet.backend === "mcp" ? [
@@ -77702,16 +79736,6 @@ function nativeCapletToolDescription(toolName, caplet) {
77702
79736
  //#endregion
77703
79737
  //#region src/server/options.ts
77704
79738
  const DEFAULT_SERVER_USER = "caplets";
77705
- function resolveCapletsMode(input = {}, env = process.env) {
77706
- const mode = parseCapletsMode$1(input.mode ?? env.CAPLETS_MODE ?? "auto");
77707
- if (mode === "local") return { mode: "local" };
77708
- const rawUrl = nonEmpty$1(input.serverUrl, "serverUrl") ?? nonEmpty$1(env.CAPLETS_SERVER_URL, "CAPLETS_SERVER_URL");
77709
- if (mode === "remote") {
77710
- if (rawUrl === void 0) throw new CapletsError("REQUEST_INVALID", "CAPLETS_MODE=remote requires CAPLETS_SERVER_URL or serverUrl.");
77711
- return { mode: "remote" };
77712
- }
77713
- return rawUrl === void 0 ? { mode: "local" } : { mode: "remote" };
77714
- }
77715
79739
  function resolveCapletsServer(input = {}, env = process.env) {
77716
79740
  const rawUrl = nonEmpty$1(input.url, "url") ?? nonEmpty$1(env.CAPLETS_SERVER_URL, "CAPLETS_SERVER_URL");
77717
79741
  if (rawUrl === void 0) throw new CapletsError("REQUEST_INVALID", "CAPLETS_SERVER_URL or url is required.");
@@ -77773,10 +79797,6 @@ function isLoopbackHost(host) {
77773
79797
  const normalized = host.toLocaleLowerCase();
77774
79798
  return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1" || normalized === "[::1]";
77775
79799
  }
77776
- function parseCapletsMode$1(value) {
77777
- if (value === "auto" || value === "local" || value === "remote") return value;
77778
- throw new CapletsError("REQUEST_INVALID", `Expected CAPLETS_MODE to be auto, local, or remote, got ${value}`);
77779
- }
77780
79800
  function basicAuthHeader$1(user, password) {
77781
79801
  return `Basic ${Buffer$1.from(`${user}:${password}`).toString("base64")}`;
77782
79802
  }
@@ -77936,15 +79956,11 @@ const DEFAULT_PRESENCE_HEARTBEAT_INTERVAL_MS = 3e4;
77936
79956
  function resolveNativeCapletsServiceOptions(input = {}, env = process.env) {
77937
79957
  const mode = resolveRemoteMode({
77938
79958
  ...input.mode ? { mode: input.mode } : {},
77939
- ...input.server?.url ? { remoteUrl: input.server.url } : {}
79959
+ ...input.remote?.url ? { remoteUrl: input.remote.url } : {}
77940
79960
  }, env);
77941
79961
  if (mode.mode === "local") return { mode: "local" };
77942
- const serverFetch = input.remote?.fetch ?? input.server?.fetch;
77943
- const serverInput = {
77944
- ...input.server,
77945
- ...serverFetch ? { fetch: serverFetch } : {}
77946
- };
77947
- const server = mode.mode === "cloud" ? resolveNativeHostedCloudRemote(input.server?.url ?? env.CAPLETS_REMOTE_URL ?? "", optionalWorkspace(input, env).workspace, serverFetch) : resolveCapletsRemote(serverInput, env);
79962
+ const remoteFetch = input.remote?.fetch;
79963
+ const server = mode.mode === "cloud" ? resolveNativeHostedCloudRemote(input.remote?.url ?? env.CAPLETS_REMOTE_URL ?? "", optionalWorkspace(input, env).workspace, remoteFetch) : resolveCapletsRemote(input.remote, env);
77948
79964
  const cloud = resolveNativeCloudPresence(input.remote?.cloud, env);
77949
79965
  return {
77950
79966
  mode: mode.mode,
@@ -77966,7 +79982,7 @@ function resolveNativeHostedCloudRemote(url, workspace, fetch) {
77966
79982
  });
77967
79983
  }
77968
79984
  function optionalWorkspace(input, env) {
77969
- const workspace = input.remote?.cloud?.workspaceId ?? env.CAPLETS_REMOTE_WORKSPACE ?? env.CAPLETS_CLOUD_WORKSPACE_ID;
79985
+ const workspace = input.remote?.cloud?.workspaceId ?? input.remote?.workspace ?? env.CAPLETS_REMOTE_WORKSPACE ?? env.CAPLETS_CLOUD_WORKSPACE_ID;
77970
79986
  return workspace ? { workspace } : {};
77971
79987
  }
77972
79988
  function nativeAuthFromRemoteAuth$1(auth) {
@@ -78394,6 +80410,7 @@ var RemoteNativeCapletsService = class {
78394
80410
  client;
78395
80411
  unsubscribeRemote;
78396
80412
  pollTimer;
80413
+ codeModeSessions = new CodeModeSessionManager();
78397
80414
  closed = false;
78398
80415
  resetInFlight;
78399
80416
  constructor(options) {
@@ -78410,7 +80427,7 @@ var RemoteNativeCapletsService = class {
78410
80427
  return [...this.tools];
78411
80428
  }
78412
80429
  async execute(capletId, request) {
78413
- if (capletId === "code_mode") return await executeCodeModeRunRemote(this, request);
80430
+ if (capletId === "code_mode") return await executeCodeModeRunRemote(this, request, this.codeModeSessions);
78414
80431
  const remoteToolId = this.toolRoutes.get(capletId) ?? capletId;
78415
80432
  try {
78416
80433
  return await this.client.callTool(remoteToolId, request);
@@ -78428,6 +80445,16 @@ var RemoteNativeCapletsService = class {
78428
80445
  throw error;
78429
80446
  }
78430
80447
  }
80448
+ codeModeService() {
80449
+ return {
80450
+ listTools: () => remoteCodeModeCallableNativeTools$1(this.listTools()),
80451
+ execute: async (capletId, request) => await this.execute(capletId, request),
80452
+ codeModeService: () => this.codeModeService(),
80453
+ reload: async () => await this.reload(),
80454
+ onToolsChanged: () => () => void 0,
80455
+ close: async () => void 0
80456
+ };
80457
+ }
78431
80458
  async reload() {
78432
80459
  if (this.closed) return false;
78433
80460
  try {
@@ -78454,6 +80481,7 @@ var RemoteNativeCapletsService = class {
78454
80481
  if (this.closed) return;
78455
80482
  this.closed = true;
78456
80483
  clearInterval(this.pollTimer);
80484
+ this.codeModeSessions.close();
78457
80485
  this.unsubscribeRemote();
78458
80486
  this.listeners.clear();
78459
80487
  await this.client.close();
@@ -78508,6 +80536,7 @@ function remoteToolToNativeTool(tool) {
78508
80536
  const toolName = tool.codeModeRun ? nativeCodeModeToolName : nativeCapletToolName(capletId);
78509
80537
  const inputSchema = isPlainObject(tool.inputSchema) ? tool.inputSchema : generatedToolInputJsonSchemaForCaplet({ backend: "tool" });
78510
80538
  const operationNames = tool.sourceCapletId === void 0 && !tool.codeModeRun ? operationNamesFromSchema(inputSchema) : void 0;
80539
+ const description = tool.codeModeRun ? remoteCodeModeToolDescription(tool) : tool.description;
78511
80540
  return {
78512
80541
  caplet: capletId,
78513
80542
  ...sourceCaplet && sourceCaplet !== capletId ? { sourceCaplet } : {},
@@ -78515,12 +80544,12 @@ function remoteToolToNativeTool(tool) {
78515
80544
  toolName,
78516
80545
  title: tool.title ?? capletId,
78517
80546
  description: [
78518
- tool.description ?? "Remote Caplets tool.",
80547
+ description ?? "Remote Caplets tool.",
78519
80548
  "",
78520
80549
  `Native tool name: ${toolName}`,
78521
80550
  `Remote Caplet ID: ${capletId}`
78522
80551
  ].join("\n"),
78523
- promptGuidance: [`Use ${toolName} through the remote Caplets service.`],
80552
+ promptGuidance: tool.codeModeRun ? nativeCodeModePromptGuidance() : [`Use ${toolName} through the remote Caplets service.`],
78524
80553
  ...tool.codeModeRun || capletId === "code_mode" ? { codeModeRun: true } : {},
78525
80554
  ...tool.codeModeCaplets ? { codeModeCaplets: tool.codeModeCaplets.map((caplet) => ({
78526
80555
  id: caplet.capletId,
@@ -78534,6 +80563,34 @@ function remoteToolToNativeTool(tool) {
78534
80563
  ...operationNames ? { operationNames } : {}
78535
80564
  };
78536
80565
  }
80566
+ function remoteCodeModeToolDescription(tool) {
80567
+ if (!tool.codeModeCaplets || tool.codeModeCaplets.length === 0) return tool.description;
80568
+ return generateCodeModeRunToolDescription(generateCodeModeDeclarations({ caplets: tool.codeModeCaplets.map((caplet) => ({
80569
+ id: caplet.capletId,
80570
+ name: caplet.name,
80571
+ description: caplet.description ?? "",
80572
+ shadowing: caplet.shadowing
80573
+ })) }));
80574
+ }
80575
+ function remoteCodeModeCallableNativeTools$1(tools) {
80576
+ const codeModeCaplets = tools.flatMap((tool) => tool.codeModeCaplets ?? []);
80577
+ const hasExplicitCodeModeManifest = tools.some((tool) => tool.codeModeCaplets !== void 0);
80578
+ if (codeModeCaplets.length === 0) return hasExplicitCodeModeManifest ? [] : tools.filter((tool) => tool.codeModeRun !== true);
80579
+ const byId = new Map(tools.map((tool) => [tool.caplet, tool]));
80580
+ return codeModeCaplets.map((caplet) => {
80581
+ const tool = byId.get(caplet.id);
80582
+ return {
80583
+ caplet: caplet.id,
80584
+ toolName: tool?.toolName ?? nativeCapletToolName(caplet.id),
80585
+ title: caplet.name,
80586
+ description: caplet.description,
80587
+ ...caplet.shadowing ? { shadowing: caplet.shadowing } : {},
80588
+ ...caplet.useWhen ? { useWhen: caplet.useWhen } : {},
80589
+ ...caplet.avoidWhen ? { avoidWhen: caplet.avoidWhen } : {},
80590
+ promptGuidance: tool?.promptGuidance ?? []
80591
+ };
80592
+ });
80593
+ }
78537
80594
  function nativeToolRouteId(tool) {
78538
80595
  return tool.codeModeRun ? nativeCodeModeToolId : tool.name;
78539
80596
  }
@@ -78659,8 +80716,9 @@ function primitiveInvokeInput(capletId, operation, input) {
78659
80716
  return input;
78660
80717
  }
78661
80718
  function toolsFromManifest(manifest) {
78662
- const codeModeMarker = attachCodeModeMarker(manifest);
78663
- const codeModeShadowing = manifest.codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
80719
+ const codeModeCaplets = manifest.codeModeCaplets ?? [];
80720
+ const codeModeMarker = attachCodeModeMarker(codeModeCaplets);
80721
+ const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
78664
80722
  return [
78665
80723
  ...manifest.caplets.map((entry) => ({
78666
80724
  name: entry.capletId,
@@ -78684,20 +80742,20 @@ function toolsFromManifest(manifest) {
78684
80742
  ...codeModeMarker
78685
80743
  })),
78686
80744
  ...primitiveToolsFromManifest(manifest, codeModeMarker),
78687
- ...manifest.codeModeCaplets.length > 0 ? [{
80745
+ ...codeModeCaplets.length > 0 ? [{
78688
80746
  name: nativeCodeModeToolId,
78689
80747
  capletId: nativeCodeModeToolId,
78690
80748
  title: "Code Mode",
78691
80749
  description: "Remote Caplets available to locally-run attached Code Mode.",
78692
80750
  codeModeRun: true,
78693
- codeModeCaplets: manifest.codeModeCaplets,
80751
+ codeModeCaplets,
78694
80752
  shadowing: codeModeShadowing,
78695
80753
  inputSchema: codeModeRunInputJsonSchema()
78696
80754
  }] : []
78697
80755
  ];
78698
80756
  }
78699
- function attachCodeModeMarker(manifest) {
78700
- return manifest.codeModeCaplets.length === 0 ? { codeModeCaplets: [] } : {};
80757
+ function attachCodeModeMarker(codeModeCaplets = []) {
80758
+ return codeModeCaplets.length === 0 ? { codeModeCaplets: [] } : {};
78701
80759
  }
78702
80760
  function primitiveToolsFromManifest(manifest, codeModeMarker) {
78703
80761
  const directToolNames = new Set(manifest.tools.map((entry) => entry.name));
@@ -78806,7 +80864,7 @@ function exportMapFor(manifest) {
78806
80864
  mapped.set(entry.name, entry);
78807
80865
  }
78808
80866
  for (const entry of manifest.tools) mapped.set(entry.name, entry);
78809
- for (const entry of manifest.codeModeCaplets) {
80867
+ for (const entry of manifest.codeModeCaplets ?? []) {
78810
80868
  setIfAbsent(entry.capletId, entry);
78811
80869
  setIfAbsent(entry.name, entry);
78812
80870
  }
@@ -78866,7 +80924,7 @@ function startAttachEvents(attachUrl, requestInit, fetchImpl, listeners, onClose
78866
80924
  })();
78867
80925
  return abort;
78868
80926
  }
78869
- async function executeCodeModeRunRemote(service, request) {
80927
+ async function executeCodeModeRunRemote(service, request, sessionManager) {
78870
80928
  const parsed = codeModeRunInputSchema.safeParse(request);
78871
80929
  if (!parsed.success) return {
78872
80930
  ok: false,
@@ -78881,20 +80939,16 @@ async function executeCodeModeRunRemote(service, request) {
78881
80939
  truncated: false,
78882
80940
  stored: false
78883
80941
  },
78884
- meta: {
78885
- runId: "",
78886
- traceId: "",
78887
- declarationHash: "",
78888
- durationMs: 0,
78889
- timeoutMs: 0,
78890
- maxTimeoutMs: 0
78891
- }
80942
+ meta: emptyCodeModeRunMeta()
78892
80943
  };
78893
80944
  return await runCodeMode({
78894
80945
  code: parsed.data.code,
78895
80946
  service,
78896
80947
  ...parsed.data.timeoutMs === void 0 ? {} : { timeoutMs: parsed.data.timeoutMs },
78897
- runtimeScope: process.env.CAPLETS_MODE?.trim() || "remote"
80948
+ ...parsed.data.sessionId === void 0 ? {} : { sessionId: parsed.data.sessionId },
80949
+ runtimeScope: process.env.CAPLETS_MODE?.trim() || "remote",
80950
+ journalStore: new CodeModeJournalStore(),
80951
+ ...sessionManager === void 0 ? {} : { sessionManager }
78898
80952
  });
78899
80953
  }
78900
80954
  function compatibleExport(manifest, previous) {
@@ -78905,7 +80959,7 @@ function compatibleExport(manifest, previous) {
78905
80959
  ...manifest.resourceTemplates,
78906
80960
  ...manifest.prompts,
78907
80961
  ...manifest.completions,
78908
- ...manifest.codeModeCaplets
80962
+ ...manifest.codeModeCaplets ?? []
78909
80963
  ].find((entry) => entry.stableId === previous.stableId);
78910
80964
  if (!next) return void 0;
78911
80965
  if (next.kind !== previous.kind) return void 0;
@@ -79346,6 +81400,7 @@ var DefaultNativeCapletsService = class {
79346
81400
  toolListeners = /* @__PURE__ */ new Set();
79347
81401
  directToolRoutes = /* @__PURE__ */ new Map();
79348
81402
  exposureSnapshot;
81403
+ codeModeSessions = new CodeModeSessionManager();
79349
81404
  postReloadRefresh;
79350
81405
  exposureRefreshGeneration = 0;
79351
81406
  constructor(options) {
@@ -79383,7 +81438,7 @@ var DefaultNativeCapletsService = class {
79383
81438
  ];
79384
81439
  }
79385
81440
  async execute(capletId, request) {
79386
- if (capletId === "code_mode") return await executeCodeModeRunNative(this.codeModeDelegate(), request);
81441
+ if (capletId === "code_mode") return await executeCodeModeRunNative(this.codeModeDelegate(), request, this.codeModeSessions);
79387
81442
  const route = this.directToolRoutes.get(capletId);
79388
81443
  if (route) {
79389
81444
  if (isMcpPrimitiveRoute(route.operationName)) return await this.engine.execute(route.capletId, nativeMcpPrimitiveRequest(route.operationName, request));
@@ -79391,6 +81446,9 @@ var DefaultNativeCapletsService = class {
79391
81446
  }
79392
81447
  return await this.engine.execute(capletId, request);
79393
81448
  }
81449
+ codeModeService() {
81450
+ return this.codeModeDelegate();
81451
+ }
79394
81452
  async reload() {
79395
81453
  const reloaded = await this.engine.reload();
79396
81454
  await this.postReloadRefresh;
@@ -79404,6 +81462,7 @@ var DefaultNativeCapletsService = class {
79404
81462
  }
79405
81463
  async close() {
79406
81464
  this.unsubscribeEngineReload();
81465
+ this.codeModeSessions.close();
79407
81466
  this.toolListeners.clear();
79408
81467
  await this.engine.close();
79409
81468
  }
@@ -79630,11 +81689,7 @@ function codeModeRunNativeTool(capletTools) {
79630
81689
  ].join("\n"),
79631
81690
  codeModeRun: true,
79632
81691
  codeModeCaplets,
79633
- promptGuidance: [
79634
- `Use ${nativeCodeModeToolName} to run Caplets Code Mode TypeScript with generated caplets.<id> handles.`,
79635
- "Prefer Code Mode for multi-step Caplet discovery, tool calls, filtering, joins, and compact synthesis.",
79636
- "Return decision-ready JSON from Code Mode rather than raw bulky provider payloads."
79637
- ],
81692
+ promptGuidance: nativeCodeModePromptGuidance(),
79638
81693
  inputSchema: codeModeRunInputJsonSchema()
79639
81694
  };
79640
81695
  }
@@ -79657,7 +81712,7 @@ function codeModeCallableNativeTools(tools, options) {
79657
81712
  };
79658
81713
  });
79659
81714
  }
79660
- async function executeCodeModeRunNative(service, request) {
81715
+ async function executeCodeModeRunNative(service, request, sessionManager) {
79661
81716
  const parsed = codeModeRunInputSchema.safeParse(request);
79662
81717
  if (!parsed.success) return {
79663
81718
  ok: false,
@@ -79672,20 +81727,16 @@ async function executeCodeModeRunNative(service, request) {
79672
81727
  truncated: false,
79673
81728
  stored: false
79674
81729
  },
79675
- meta: {
79676
- runId: "",
79677
- traceId: "",
79678
- declarationHash: "",
79679
- durationMs: 0,
79680
- timeoutMs: 0,
79681
- maxTimeoutMs: 0
79682
- }
81730
+ meta: emptyCodeModeRunMeta()
79683
81731
  };
79684
81732
  return await runCodeMode({
79685
81733
  code: parsed.data.code,
79686
81734
  service,
79687
81735
  ...parsed.data.timeoutMs === void 0 ? {} : { timeoutMs: parsed.data.timeoutMs },
79688
- runtimeScope: process.env.CAPLETS_MODE?.trim() || "local"
81736
+ ...parsed.data.sessionId === void 0 ? {} : { sessionId: parsed.data.sessionId },
81737
+ runtimeScope: process.env.CAPLETS_MODE?.trim() || "local",
81738
+ journalStore: new CodeModeJournalStore(),
81739
+ ...sessionManager === void 0 ? {} : { sessionManager }
79689
81740
  });
79690
81741
  }
79691
81742
  function createDefaultNativeCapletsService(options) {
@@ -79727,11 +81778,14 @@ var CloudNativeCapletsService = class {
79727
81778
  async execute(capletId, request) {
79728
81779
  return await (this.delegate ?? this.local).execute(capletId, request);
79729
81780
  }
81781
+ codeModeService() {
81782
+ return (this.delegate ?? this.local).codeModeService?.() ?? this.delegate ?? this.local;
81783
+ }
79730
81784
  async reload() {
79731
81785
  if (this.closed) return false;
79732
81786
  if (!this.delegate) try {
79733
- const cloudFetch = this.options.remote?.fetch ?? this.options.server?.fetch;
79734
- const remoteUrl = this.options.server?.url ?? this.baseRemote.url.toString().replace(/\/mcp$/u, "");
81787
+ const cloudFetch = this.options.remote?.fetch;
81788
+ const remoteUrl = this.options.remote?.url ?? this.baseRemote.url.toString().replace(/\/mcp$/u, "");
79735
81789
  const selection = await resolveRemoteSelection({
79736
81790
  mode: "cloud",
79737
81791
  remoteUrl,
@@ -79807,6 +81861,7 @@ var CompositeNativeCapletsService = class {
79807
81861
  tools = [];
79808
81862
  closed = false;
79809
81863
  batchingReload = false;
81864
+ codeModeSessions = new CodeModeSessionManager();
79810
81865
  constructor(remote, local, options, presence) {
79811
81866
  this.remote = remote;
79812
81867
  this.local = local;
@@ -79822,10 +81877,20 @@ var CompositeNativeCapletsService = class {
79822
81877
  return [...this.tools];
79823
81878
  }
79824
81879
  async execute(capletId, request) {
79825
- if (capletId === "code_mode") return await executeCodeModeRunNative(this, request);
81880
+ if (capletId === "code_mode") return await executeCodeModeRunNative(this, request, this.codeModeSessions);
79826
81881
  if (this.localCanExecute(capletId)) return await this.local.execute(capletId, request);
79827
81882
  return await this.remote.execute(capletId, request);
79828
81883
  }
81884
+ codeModeService() {
81885
+ return {
81886
+ listTools: () => codeModeCallableNativeTools(this.listTools(), { fallbackToVisible: false }),
81887
+ execute: async (capletId, request) => await this.execute(capletId, request),
81888
+ codeModeService: () => this.codeModeService(),
81889
+ reload: async () => await this.reload(),
81890
+ onToolsChanged: () => () => void 0,
81891
+ close: async () => void 0
81892
+ };
81893
+ }
79829
81894
  async reload() {
79830
81895
  if (this.closed) return false;
79831
81896
  this.batchingReload = true;
@@ -79846,6 +81911,7 @@ var CompositeNativeCapletsService = class {
79846
81911
  this.closed = true;
79847
81912
  for (const unsubscribe of this.unsubscribers.splice(0)) unsubscribe();
79848
81913
  this.listeners.clear();
81914
+ this.codeModeSessions.close();
79849
81915
  await Promise.all([
79850
81916
  this.remote.close(),
79851
81917
  this.local.close(),
@@ -79917,7 +81983,7 @@ function localExecutionKeys(tools, capletId) {
79917
81983
  function createProjectBindingSessionManager(cloud, local, options) {
79918
81984
  if (!cloud) return;
79919
81985
  const projectRoot = cloud.projectRoot ?? findProjectRoot();
79920
- const cloudFetch = options.remote?.fetch ?? options.server?.fetch;
81986
+ const cloudFetch = options.remote?.fetch;
79921
81987
  return new ProjectBindingSessionManager({
79922
81988
  client: new CapletsCloudClient({
79923
81989
  baseUrl: cloud.url,
@@ -79949,9 +82015,9 @@ function createLocalOverlayConfigLoader(options) {
79949
82015
  return parseConfig({});
79950
82016
  }
79951
82017
  for (const warning of result.warnings) writeErr(options, `Caplets local overlay warning${typeof warning.path === "string" ? ` at ${warning.path}` : ""}: ${warning.message}\n`);
79952
- const warnings = new Set(result.warnings.map(warningKey));
79953
- if (hasLoaded && [...warnings].some((warning) => !previousWarnings.has(warning))) throw new CapletsError("CONFIG_INVALID", "Caplets local overlay reload produced new warnings; keeping last known-good config.");
79954
- previousWarnings = warnings;
82018
+ const fatalWarnings = new Set(result.warnings.filter((warning) => !warning.recoverable).map(warningKey));
82019
+ if (hasLoaded && [...fatalWarnings].some((warning) => !previousWarnings.has(warning))) throw new CapletsError("CONFIG_INVALID", "Caplets local overlay reload produced new warnings; keeping last known-good config.");
82020
+ previousWarnings = fatalWarnings;
79955
82021
  hasLoaded = true;
79956
82022
  return result.config;
79957
82023
  };
@@ -79971,4 +82037,4 @@ function errorMessage(error) {
79971
82037
  return error instanceof Error ? error.message : String(error);
79972
82038
  }
79973
82039
  //#endregion
79974
- export { loadConfigWithSources as $, ListResourcesRequestSchema as $t, codeModeRunParamsSchema as A, assertClientRequestTaskCapability as At, generateCodeModeRunToolDescription as B, CreateMessageResultWithToolsSchema as Bt, nativeCapletPromptGuidance as C, __exportAll as Cn, defaultStateBaseDir as Ct, nativeCodeModeToolId as D, resolveProjectConfigPath as Dt, nativeCapletsSystemGuidance as E, resolveProjectCapletsRoot as Et, listCodeModeCallableCaplets as F, toJsonSchemaCompat as Ft, directResourceUriMatchesTemplate as G, ErrorCode as Gt, CapletsEngine as H, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as Ht, CodeModeLogStore as I, CallToolRequestSchema as It, handleServerTool as J, InitializedNotificationSchema as Jt, findProjectRoot as K, GetPromptRequestSchema as Kt, redactCodeModeLogText as L, CallToolResultSchema as Lt, QuickJsCodeModeSandbox as M, AjvJsonSchemaValidator as Mt, diagnoseCodeModeTypeScript as N, Protocol as Nt, nativeCodeModeToolName as O, ReadBuffer as Ot, createCodeModeCapletsApi as P, mergeCapabilities as Pt, loadConfig as Q, ListResourceTemplatesRequestSchema as Qt, codeModeDeclarationHash as R, CompleteRequestSchema as Rt, resolveCapletsServer as S, safeParseAsync as Sn, defaultConfigBaseDir as St, nativeCapletToolName as T, resolveConfigPath as Tt, resolveExposure as U, ElicitResultSchema as Ut, minifyCodeModeDeclarationText as V, CreateTaskResultSchema as Vt, decodeDirectResourceUri as W, EmptyResultSchema as Wt, capabilityDescription as X, LATEST_PROTOCOL_VERSION as Xt, ServerRegistry as Y, JSONRPCMessageSchema as Yt, GoogleDiscoveryManager as Z, ListPromptsRequestSchema as Zt, resolveHostedCloudRemote as _, isSchemaOptional as _n, readTokenBundle as _t, projectBindingError as a, SUPPORTED_PROTOCOL_VERSIONS as an, validateCapletFile as at, parseServerBaseUrl as b, objectFromShape as bn, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as bt, cloudAuthPath as c, assertCompleteRequestResourceTemplate as cn, markdownCallToolResultContent as ct, CloudAuthClient as d, isJSONRPCRequest as dn, runGenericOAuthFlow as dt, ListRootsResultSchema as en, loadGlobalConfig as et, RemoteNativeCapletsService as f, isJSONRPCResultResponse as fn, runOAuthFlow as ft, resolveCapletsRemote as g, getSchemaDescription as gn, isTokenBundleExpired as gt, resolveNativeCapletsServiceOptions as h, getParseErrorMessage as hn, deleteTokenBundle as ht, ProjectBindingError as i, ReadResourceRequestSchema as in, discoverCapletFiles as it, runCodeMode as j, assertToolsCallTaskCapability as jt, codeModeRunInputSchema as k, serializeMessage as kt, migrateCredentials as l, isInitializeRequest as ln, markdownStructuredContent as lt, buildProjectSyncManifest as m, getObjectShape as mn, startOAuthFlow as mt, resolveRemoteSelection as n, LoggingLevelSchema as nn, loadProjectConfig as nt, projectBindingRecovery as o, SetLevelRequestSchema as on, loadCapletFilesFromMap as ot, createSdkRemoteCapletsClient as p, getLiteralValue as pn, startGenericOAuthFlow as pt, fingerprintProjectRoot as q, InitializeRequestSchema as qt, PROJECT_BINDING_ERROR_CODES as r, McpError as rn, parseConfig as rt, CloudAuthStore as s, assertCompleteRequestPrompt as sn, hasRenderableStructuredContent as st, createNativeCapletsService as t, ListToolsRequestSchema as tn, loadLocalOverlayConfigWithSources as tt, redactedCloudAuthStatus as u, isJSONRPCErrorResponse as un, refreshOAuthTokenBundle as ut, resolveRemoteMode as v, isZ4Schema as vn, DEFAULT_AUTH_DIR as vt, nativeCapletToolDescription as w, resolveCapletsRoot as wt, resolveCapletsMode as x, safeParse as xn, defaultCacheBaseDir as xt, controlUrlForBase as y, normalizeObjectSchema as yn, DEFAULT_COMPLETION_CACHE_DIR as yt, generateCodeModeDeclarations as z, CreateMessageResultSchema as zt };
82040
+ export { GoogleDiscoveryManager as $, ListPromptsRequestSchema as $t, emptyCodeModeRunMeta as A, ReadBuffer as At, codeModeDeclarationHash as B, CompleteRequestSchema as Bt, nativeCapletToolDescription as C, safeParse as Cn, defaultCacheBaseDir as Ct, nativeCodeModeToolName as D, resolveConfigPath as Dt, nativeCodeModeToolId as E, resolveCapletsRoot as Et, createCodeModeCapletsApi as F, Protocol as Ft, resolveExposure as G, ElicitResultSchema as Gt, generateCodeModeRunToolDescription as H, CreateMessageResultWithToolsSchema as Ht, listCodeModeCallableCaplets as I, mergeCapabilities as It, findProjectRoot as J, GetPromptRequestSchema as Jt, decodeDirectResourceUri as K, EmptyResultSchema as Kt, CodeModeJournalStore as L, toJsonSchemaCompat as Lt, CodeModeSessionManager as M, assertClientRequestTaskCapability as Mt, QuickJsCodeModeSandbox as N, assertToolsCallTaskCapability as Nt, codeModeRunInputSchema as O, resolveProjectCapletsRoot as Ot, diagnoseCodeModeTypeScript as P, AjvJsonSchemaValidator as Pt, capabilityDescription as Q, LATEST_PROTOCOL_VERSION as Qt, CodeModeLogStore as R, CallToolRequestSchema as Rt, nativeCapletPromptGuidance as S, objectFromShape as Sn, DEFAULT_OBSERVED_OUTPUT_SHAPE_CACHE_DIR as St, nativeCapletsSystemGuidance as T, __exportAll as Tn, defaultStateBaseDir as Tt, minifyCodeModeDeclarationText as U, CreateTaskResultSchema as Ut, generateCodeModeDeclarations as V, CreateMessageResultSchema as Vt, CapletsEngine as W, DEFAULT_NEGOTIATED_PROTOCOL_VERSION as Wt, handleServerTool as X, InitializedNotificationSchema as Xt, fingerprintProjectRoot as Y, InitializeRequestSchema as Yt, ServerRegistry as Z, JSONRPCMessageSchema as Zt, resolveHostedCloudRemote as _, getParseErrorMessage as _n, deleteTokenBundle as _t, projectBindingError as a, McpError as an, parseConfig as at, parseServerBaseUrl as b, isZ4Schema as bn, DEFAULT_AUTH_DIR as bt, cloudAuthPath as c, SetLevelRequestSchema as cn, loadCapletFilesFromMap as ct, CloudAuthClient as d, isInitializeRequest as dn, markdownStructuredContent as dt, ListResourceTemplatesRequestSchema as en, loadConfig as et, RemoteNativeCapletsService as f, isJSONRPCErrorResponse as fn, refreshOAuthTokenBundle as ft, resolveCapletsRemote as g, getObjectShape as gn, startOAuthFlow as gt, resolveNativeCapletsServiceOptions as h, getLiteralValue as hn, startGenericOAuthFlow as ht, ProjectBindingError as i, LoggingLevelSchema as in, loadProjectConfig as it, runCodeMode as j, serializeMessage as jt, codeModeRunParamsSchema as k, resolveProjectConfigPath as kt, migrateCredentials as l, assertCompleteRequestPrompt as ln, hasRenderableStructuredContent as lt, buildProjectSyncManifest as m, isJSONRPCResultResponse as mn, runOAuthFlow as mt, resolveRemoteSelection as n, ListRootsResultSchema as nn, loadGlobalConfig as nt, projectBindingRecovery as o, ReadResourceRequestSchema as on, discoverCapletFiles as ot, createSdkRemoteCapletsClient as p, isJSONRPCRequest as pn, runGenericOAuthFlow as pt, directResourceUriMatchesTemplate as q, ErrorCode as qt, PROJECT_BINDING_ERROR_CODES as r, ListToolsRequestSchema as rn, loadLocalOverlayConfigWithSources as rt, CloudAuthStore as s, SUPPORTED_PROTOCOL_VERSIONS as sn, validateCapletFile as st, createNativeCapletsService as t, ListResourcesRequestSchema as tn, loadConfigWithSources as tt, redactedCloudAuthStatus as u, assertCompleteRequestResourceTemplate as un, markdownCallToolResultContent as ut, resolveRemoteMode as v, getSchemaDescription as vn, isTokenBundleExpired as vt, nativeCapletToolName as w, safeParseAsync as wn, defaultConfigBaseDir as wt, resolveCapletsServer as x, normalizeObjectSchema as xn, DEFAULT_COMPLETION_CACHE_DIR as xt, controlUrlForBase as y, isSchemaOptional as yn, readTokenBundle as yt, redactCodeModeLogText as z, CallToolResultSchema as zt };