@caplets/core 0.23.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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";
@@ -28269,7 +28269,7 @@ async function writeMediaArtifact(input) {
28269
28269
  const callId = safePathSegment(input.callId ?? defaultCallId(), "call");
28270
28270
  const filename = safeFilename(input.suggestedFilename ?? (input.outputPath ? basename(input.outputPath) : "response.bin"));
28271
28271
  const target = input.outputPath ? assertInsideRoot(rootDir, input.outputPath) : assertInsideRoot(rootDir, resolve(rootDir, capletId, callId, filename));
28272
- rejectSymlinkPathComponents(rootDir, target, true);
28272
+ rejectSymlinkPathComponents$1(rootDir, target, true);
28273
28273
  const uriParts = input.outputPath ? uriPartsForOutputPath(rootDir, target) : {
28274
28274
  capletId,
28275
28275
  callId,
@@ -28297,7 +28297,7 @@ function resolveMediaArtifact(uri, options = {}) {
28297
28297
  const parsed = parseArtifactUri(uri);
28298
28298
  const rootDir = resolve(options.artifactRoot ?? DEFAULT_ARTIFACT_DIR);
28299
28299
  const path = assertInsideRoot(rootDir, resolve(rootDir, parsed.capletId, parsed.callId, parsed.filename));
28300
- rejectSymlinkPathComponents(rootDir, path, true);
28300
+ rejectSymlinkPathComponents$1(rootDir, path, true);
28301
28301
  if (!existsSync(path)) throw new CapletsError("REQUEST_INVALID", "Media artifact was not found");
28302
28302
  const stat = statSync(path);
28303
28303
  if (!stat.isFile()) throw new CapletsError("REQUEST_INVALID", "Media artifact must resolve to a file");
@@ -28356,9 +28356,9 @@ function assertInsideRoot(rootDir, candidate) {
28356
28356
  if (rel.startsWith("..") || isAbsolute(rel)) throw new CapletsError("REQUEST_INVALID", "Media artifact outputPath must stay inside the artifact root");
28357
28357
  return resolved;
28358
28358
  }
28359
- function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
28359
+ function rejectSymlinkPathComponents$1(rootDir, target, includeTarget) {
28360
28360
  const resolvedRoot = resolve(rootDir);
28361
- rejectSymlinkRoot(resolvedRoot);
28361
+ rejectSymlinkRoot$1(resolvedRoot);
28362
28362
  const parts = relative(resolvedRoot, resolve(target)).split(/[\\/]+/u).filter(Boolean);
28363
28363
  let current = resolvedRoot;
28364
28364
  const limit = includeTarget ? parts.length : Math.max(0, parts.length - 1);
@@ -28373,7 +28373,7 @@ function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
28373
28373
  }
28374
28374
  }
28375
28375
  }
28376
- function rejectSymlinkRoot(rootDir) {
28376
+ function rejectSymlinkRoot$1(rootDir) {
28377
28377
  try {
28378
28378
  if (lstatSync(rootDir).isSymbolicLink()) throw new CapletsError("REQUEST_INVALID", "Media artifact root must not be a symlink");
28379
28379
  } catch (error) {
@@ -63362,7 +63362,7 @@ var CapletsEngine = class {
63362
63362
  }
63363
63363
  }
63364
63364
  async completeCliWords(words) {
63365
- const { completeCliWords } = await import("./completion-BC4BNWo0.js").then((n) => n.r);
63365
+ const { completeCliWords } = await import("./completion-CzHdM9B_.js").then((n) => n.r);
63366
63366
  return await completeCliWords(words, {
63367
63367
  config: this.registry.config,
63368
63368
  managers: {
@@ -63670,11 +63670,12 @@ function isRecord$2(value) {
63670
63670
  }
63671
63671
  //#endregion
63672
63672
  //#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;";
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>;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
63674
  //#endregion
63675
63675
  //#region src/code-mode/declarations.ts
63676
63676
  const JS_IDENTIFIER = /^[A-Za-z_$][\w$]*$/u;
63677
63677
  const MAX_JSDOC_CHARS = 180;
63678
+ 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
63679
  function generateCodeModeDeclarations(input) {
63679
63680
  const caplets = [...input.caplets].sort((left, right) => left.id.localeCompare(right.id));
63680
63681
  const properties = caplets.map((caplet) => {
@@ -63694,6 +63695,7 @@ function generateCodeModeDeclarations(input) {
63694
63695
  function generateCodeModeRunToolDescription(declaration) {
63695
63696
  return [
63696
63697
  "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:[...]};`",
63698
+ CODE_MODE_REPL_GUIDANCE,
63697
63699
  "",
63698
63700
  "Generated declaration hints:",
63699
63701
  "```ts",
@@ -63756,8 +63758,8 @@ function fnv1a32(value, seed) {
63756
63758
  //#endregion
63757
63759
  //#region src/code-mode/logs.ts
63758
63760
  const DEFAULT_LOG_REF_TTL_MS = 3600 * 1e3;
63759
- const DEFAULT_PAGE_LIMIT = 100;
63760
- const MAX_PAGE_LIMIT = 500;
63761
+ const DEFAULT_PAGE_LIMIT$1 = 100;
63762
+ const MAX_PAGE_LIMIT$1 = 500;
63761
63763
  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
63764
  const BEARER_PATTERN = /\bbearer\s+([a-z0-9._~+/=-]{8,})/giu;
63763
63765
  const BASIC_PATTERN = /\bbasic\s+([a-z0-9._~+/=-]{8,})/giu;
@@ -63798,8 +63800,8 @@ var CodeModeLogStore = class {
63798
63800
  if (!existsSync(path)) return { entries: [] };
63799
63801
  const parsed = parseStoredLogs(readFileSync(path, "utf8"));
63800
63802
  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);
63803
+ const offset = parseCursor$1(input.cursor);
63804
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_PAGE_LIMIT$1, 0), MAX_PAGE_LIMIT$1);
63803
63805
  const entries = parsed.entries.slice(offset, offset + limit).map(redactEntry);
63804
63806
  const nextOffset = offset + entries.length;
63805
63807
  return nextOffset < parsed.entries.length ? {
@@ -63823,7 +63825,7 @@ function redactEntry(entry) {
63823
63825
  message: redactCodeModeLogText(entry.message)
63824
63826
  };
63825
63827
  }
63826
- function parseCursor(cursor) {
63828
+ function parseCursor$1(cursor) {
63827
63829
  if (!cursor) return 0;
63828
63830
  const parsed = Number.parseInt(cursor, 10);
63829
63831
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
@@ -63847,6 +63849,373 @@ function isLogEntry(value) {
63847
63849
  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
63850
  }
63849
63851
  //#endregion
63852
+ //#region src/code-mode/journal.ts
63853
+ const DEFAULT_JOURNAL_RETENTION_MS = 10080 * 60 * 1e3;
63854
+ const DEFAULT_MAX_ENTRIES = 100;
63855
+ const DEFAULT_MAX_CODE_BYTES = 64 * 1024;
63856
+ const DEFAULT_MAX_SUMMARY_BYTES = 16 * 1024;
63857
+ const DEFAULT_PAGE_LIMIT = 25;
63858
+ const MAX_PAGE_LIMIT = 100;
63859
+ const JOURNAL_VERSION = 1;
63860
+ var CodeModeJournalStore = class {
63861
+ stateDir;
63862
+ now;
63863
+ retentionMs;
63864
+ maxEntries;
63865
+ maxCodeBytes;
63866
+ maxSummaryBytes;
63867
+ configuredSecret;
63868
+ secret;
63869
+ recoveryRefs = /* @__PURE__ */ new Map();
63870
+ sessionRecoveryRefs = /* @__PURE__ */ new Map();
63871
+ nextPruneAt = 0;
63872
+ constructor(options = {}) {
63873
+ this.stateDir = options.stateDir ?? join(defaultStateBaseDir(), "caplets");
63874
+ this.now = options.now ?? (() => /* @__PURE__ */ new Date());
63875
+ this.retentionMs = options.retentionMs ?? DEFAULT_JOURNAL_RETENTION_MS;
63876
+ this.maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
63877
+ this.maxCodeBytes = options.maxCodeBytes ?? DEFAULT_MAX_CODE_BYTES;
63878
+ this.maxSummaryBytes = options.maxSummaryBytes ?? DEFAULT_MAX_SUMMARY_BYTES;
63879
+ this.configuredSecret = options.secret;
63880
+ }
63881
+ async store(input) {
63882
+ this.ensureJournalDir();
63883
+ this.pruneExpired();
63884
+ const now = this.now();
63885
+ const expiresAt = new Date(now.getTime() + this.retentionMs).toISOString();
63886
+ const journalKey = this.journalKey(input.sessionId, input.journalScope);
63887
+ const recoveryRef = this.recoveryRefs.get(journalKey) ?? this.recoveryRefForJournalKey(journalKey);
63888
+ this.recoveryRefs.set(journalKey, recoveryRef);
63889
+ this.sessionRecoveryRefs.set(input.sessionId, {
63890
+ recoveryRef,
63891
+ expiresAt
63892
+ });
63893
+ const recoveryRefHash = this.recoveryRefHash(recoveryRef);
63894
+ const path = this.journalPath(journalKey);
63895
+ const existing = this.readJournalPath(path);
63896
+ const entry = this.entryFromInput(input, now, recoveryRef);
63897
+ const stored = {
63898
+ version: JOURNAL_VERSION,
63899
+ journalKey,
63900
+ sessionIdHash: this.sessionIdHash(input.sessionId),
63901
+ recoveryRefHashes: [...new Set([...existing?.recoveryRefHashes ?? [], recoveryRefHash])],
63902
+ createdAt: existing?.createdAt ?? now.toISOString(),
63903
+ updatedAt: now.toISOString(),
63904
+ expiresAt,
63905
+ entries: [...existing?.entries ?? [], entry].slice(-this.maxEntries)
63906
+ };
63907
+ this.writeJournal(path, stored);
63908
+ this.writeIndex(this.recoveryIndexPath(recoveryRefHash), stored);
63909
+ this.writeIndex(this.sessionIndexPath(stored.sessionIdHash), stored);
63910
+ return {
63911
+ recoveryRef,
63912
+ expiresAt,
63913
+ journalKey
63914
+ };
63915
+ }
63916
+ async lookupSession(sessionId) {
63917
+ this.ensureJournalDir();
63918
+ this.pruneExpired();
63919
+ const retained = this.sessionRecoveryRefs.get(sessionId);
63920
+ if (retained && new Date(retained.expiresAt).getTime() > this.now().getTime()) return retained;
63921
+ const scopedJournal = this.findBySessionIdHash(this.sessionIdHash(sessionId));
63922
+ if (scopedJournal && !this.isExpired(scopedJournal)) return {
63923
+ expiresAt: scopedJournal.expiresAt,
63924
+ recoveryRef: this.recoveryRefForJournalKey(scopedJournal.journalKey)
63925
+ };
63926
+ const journal = this.readJournalPath(this.journalPath(this.journalKey(sessionId)));
63927
+ if (!journal || this.isExpired(journal)) return void 0;
63928
+ return { expiresAt: journal.expiresAt };
63929
+ }
63930
+ async lookupRecoveryRef(recoveryRef) {
63931
+ if (!isRecoveryRef(recoveryRef)) return void 0;
63932
+ this.ensureJournalDir();
63933
+ this.pruneExpired();
63934
+ const journal = this.findByRecoveryRefHash(this.recoveryRefHash(recoveryRef));
63935
+ if (!journal || this.isExpired(journal)) return void 0;
63936
+ return { expiresAt: journal.expiresAt };
63937
+ }
63938
+ async readRecovery(input) {
63939
+ if (!isRecoveryRef(input.recoveryRef)) return { entries: [] };
63940
+ this.ensureJournalDir();
63941
+ this.pruneExpired();
63942
+ const recoveryRefHash = this.recoveryRefHash(input.recoveryRef);
63943
+ const journal = this.findByRecoveryRefHash(recoveryRefHash);
63944
+ if (!journal || this.isExpired(journal)) return { entries: [] };
63945
+ const offset = parseCursor(input.cursor);
63946
+ if (input.limit !== void 0 && input.limit <= 0) return { entries: [] };
63947
+ const limit = Math.min(Math.max(input.limit ?? DEFAULT_PAGE_LIMIT, 0), MAX_PAGE_LIMIT);
63948
+ const entries = journal.entries.slice(offset, offset + limit);
63949
+ const nextOffset = offset + entries.length;
63950
+ return nextOffset < journal.entries.length ? {
63951
+ entries,
63952
+ nextCursor: String(nextOffset)
63953
+ } : { entries };
63954
+ }
63955
+ entryFromInput(input, now, recoveryRef) {
63956
+ const exactSecrets = [
63957
+ input.sessionId,
63958
+ recoveryRef,
63959
+ input.logRef
63960
+ ].filter((value) => Boolean(value));
63961
+ return {
63962
+ timestamp: now.toISOString(),
63963
+ code: truncateUtf8(redactJournalText(input.code, exactSecrets), this.maxCodeBytes),
63964
+ declarationHash: input.declarationHash,
63965
+ outcome: input.outcome.ok === true ? { ok: true } : {
63966
+ ok: false,
63967
+ code: input.outcome.code,
63968
+ message: truncateUtf8(redactJournalText(input.outcome.message, exactSecrets), 2e3)
63969
+ },
63970
+ diagnostics: input.diagnostics.map((diagnostic) => ({
63971
+ code: diagnostic.code,
63972
+ severity: diagnostic.severity,
63973
+ message: truncateUtf8(redactJournalText(diagnostic.message, exactSecrets), 2e3)
63974
+ })),
63975
+ recoveryClassification: input.recoveryClassification,
63976
+ ...input.logRef ? { logsStored: true } : {},
63977
+ ...input.summary ? { summary: truncateUtf8(redactJournalText(input.summary, exactSecrets), this.maxSummaryBytes) } : {}
63978
+ };
63979
+ }
63980
+ findByRecoveryRefHash(recoveryRefHash) {
63981
+ const indexed = this.readIndexPath(this.recoveryIndexPath(recoveryRefHash));
63982
+ if (indexed) return this.readJournalPath(this.journalPath(indexed.journalKey));
63983
+ return this.findByRecoveryRefHashSlow(recoveryRefHash);
63984
+ }
63985
+ findBySessionIdHash(sessionIdHash) {
63986
+ const indexed = this.readIndexPath(this.sessionIndexPath(sessionIdHash));
63987
+ if (indexed) return this.readJournalPath(this.journalPath(indexed.journalKey));
63988
+ return this.findBySessionIdHashSlow(sessionIdHash);
63989
+ }
63990
+ findByRecoveryRefHashSlow(recoveryRefHash) {
63991
+ for (const filename of readdirSync(this.journalDir())) {
63992
+ if (!filename.endsWith(".json")) continue;
63993
+ const journal = this.readJournalPath(join(this.journalDir(), filename));
63994
+ if (journal?.recoveryRefHashes.includes(recoveryRefHash)) return journal;
63995
+ }
63996
+ }
63997
+ findBySessionIdHashSlow(sessionIdHash) {
63998
+ const journals = [];
63999
+ for (const filename of readdirSync(this.journalDir())) {
64000
+ if (!filename.endsWith(".json")) continue;
64001
+ const journal = this.readJournalPath(join(this.journalDir(), filename));
64002
+ if (journal?.sessionIdHash === sessionIdHash) journals.push(journal);
64003
+ }
64004
+ return journals.sort((left, right) => new Date(right.updatedAt).getTime() - new Date(left.updatedAt).getTime())[0];
64005
+ }
64006
+ writeIndex(path, journal) {
64007
+ const index = {
64008
+ version: JOURNAL_VERSION,
64009
+ journalKey: journal.journalKey,
64010
+ updatedAt: journal.updatedAt
64011
+ };
64012
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64013
+ mkdirSync(dirname(path), {
64014
+ recursive: true,
64015
+ mode: 448
64016
+ });
64017
+ chmodSync(dirname(path), 448);
64018
+ const tempPath = `${path}.${randomBytes(8).toString("hex")}.tmp`;
64019
+ writeFileSync(tempPath, `${JSON.stringify(index, null, 2)}\n`, { mode: 384 });
64020
+ chmodSync(tempPath, 384);
64021
+ renameSync(tempPath, path);
64022
+ chmodSync(path, 384);
64023
+ }
64024
+ readIndexPath(path) {
64025
+ try {
64026
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64027
+ if (!existsSync(path)) return void 0;
64028
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
64029
+ if (parsed.version !== JOURNAL_VERSION || typeof parsed.journalKey !== "string" || typeof parsed.updatedAt !== "string") return;
64030
+ return {
64031
+ version: JOURNAL_VERSION,
64032
+ journalKey: parsed.journalKey,
64033
+ updatedAt: parsed.updatedAt
64034
+ };
64035
+ } catch {
64036
+ return;
64037
+ }
64038
+ }
64039
+ readJournalPath(path) {
64040
+ try {
64041
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64042
+ if (!existsSync(path)) return void 0;
64043
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
64044
+ 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;
64045
+ return {
64046
+ version: JOURNAL_VERSION,
64047
+ journalKey: parsed.journalKey,
64048
+ ...typeof parsed.sessionIdHash === "string" ? { sessionIdHash: parsed.sessionIdHash } : {},
64049
+ recoveryRefHashes: parsed.recoveryRefHashes.filter((hash) => typeof hash === "string"),
64050
+ createdAt: parsed.createdAt,
64051
+ updatedAt: parsed.updatedAt,
64052
+ expiresAt: parsed.expiresAt,
64053
+ entries: parsed.entries.filter(isJournalEntry)
64054
+ };
64055
+ } catch {
64056
+ return;
64057
+ }
64058
+ }
64059
+ writeJournal(path, journal) {
64060
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64061
+ mkdirSync(dirname(path), {
64062
+ recursive: true,
64063
+ mode: 448
64064
+ });
64065
+ chmodSync(dirname(path), 448);
64066
+ const tempPath = `${path}.${randomBytes(8).toString("hex")}.tmp`;
64067
+ writeFileSync(tempPath, `${JSON.stringify(journal, null, 2)}\n`, { mode: 384 });
64068
+ chmodSync(tempPath, 384);
64069
+ renameSync(tempPath, path);
64070
+ chmodSync(path, 384);
64071
+ }
64072
+ pruneExpired() {
64073
+ const dir = this.journalDir();
64074
+ if (!existsSync(dir)) return;
64075
+ const now = this.now().getTime();
64076
+ if (now < this.nextPruneAt) return;
64077
+ this.nextPruneAt = now + 6e4;
64078
+ for (const filename of readdirSync(dir)) {
64079
+ if (!filename.endsWith(".json")) continue;
64080
+ const path = join(dir, filename);
64081
+ const journal = this.readJournalPath(path);
64082
+ if (!journal || this.isExpired(journal)) rmSync(path, { force: true });
64083
+ }
64084
+ }
64085
+ isExpired(journal) {
64086
+ return new Date(journal.expiresAt).getTime() <= this.now().getTime();
64087
+ }
64088
+ journalKey(sessionId, journalScope = "default") {
64089
+ return this.hmac(`journal:${sessionId}:${journalScope}`);
64090
+ }
64091
+ recoveryRefHash(recoveryRef) {
64092
+ return this.hmac(`recovery-ref:${recoveryRef}`);
64093
+ }
64094
+ recoveryRefForJournalKey(journalKey) {
64095
+ return this.hmac(`recovery-ref-material:${journalKey}`).slice(0, 48);
64096
+ }
64097
+ sessionIdHash(sessionId) {
64098
+ return this.hmac(`session-id:${sessionId}`);
64099
+ }
64100
+ hmac(value) {
64101
+ return createHmac("sha256", this.loadSecret()).update(value).digest("hex");
64102
+ }
64103
+ loadSecret() {
64104
+ if (this.configuredSecret) return this.configuredSecret;
64105
+ if (this.secret) return this.secret;
64106
+ this.ensureJournalDir();
64107
+ const path = this.secretPath();
64108
+ rejectSymlinkPathComponents(this.journalDir(), path, true);
64109
+ if (existsSync(path)) {
64110
+ this.secret = readFileSync(path, "utf8").trim();
64111
+ return this.secret;
64112
+ }
64113
+ this.secret = randomBytes(32).toString("hex");
64114
+ writeFileSync(path, `${this.secret}\n`, { mode: 384 });
64115
+ chmodSync(path, 384);
64116
+ return this.secret;
64117
+ }
64118
+ ensureJournalDir() {
64119
+ const dir = this.journalDir();
64120
+ rejectSymlinkRoot(resolve(this.stateDir));
64121
+ rejectSymlinkPathComponents(resolve(this.stateDir), dir, true);
64122
+ mkdirSync(dir, {
64123
+ recursive: true,
64124
+ mode: 448
64125
+ });
64126
+ rejectSymlinkPathComponents(resolve(this.stateDir), dir, true);
64127
+ chmodSync(dir, 448);
64128
+ }
64129
+ journalDir() {
64130
+ return join(this.stateDir, "code-mode", "journal");
64131
+ }
64132
+ journalPath(journalKey) {
64133
+ return join(this.journalDir(), `${journalKey}.json`);
64134
+ }
64135
+ recoveryIndexPath(recoveryRefHash) {
64136
+ return join(this.journalDir(), "recovery-index", `${recoveryRefHash}.json`);
64137
+ }
64138
+ sessionIndexPath(sessionIdHash) {
64139
+ return join(this.journalDir(), "session-index", `${sessionIdHash ?? "unknown"}.json`);
64140
+ }
64141
+ secretPath() {
64142
+ return join(this.journalDir(), "secret.key");
64143
+ }
64144
+ };
64145
+ function classifyCodeModeRecovery(input) {
64146
+ if (input.invokedCaplet) return "side_effecting";
64147
+ if (input.sessionDisposedAfterRun) return "unknown";
64148
+ return /\b(?:function|var|let|const|class)\b/u.test(input.code) ? "setup_like" : "unknown";
64149
+ }
64150
+ function isRecoveryRef(value) {
64151
+ return /^[a-f0-9]{48}$/u.test(value);
64152
+ }
64153
+ function parseCursor(cursor) {
64154
+ if (!cursor) return 0;
64155
+ const parsed = Number.parseInt(cursor, 10);
64156
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
64157
+ }
64158
+ function truncateUtf8(value, maxBytes) {
64159
+ let bytes = 0;
64160
+ let output = "";
64161
+ for (const char of value) {
64162
+ const next = Buffer.byteLength(char, "utf8");
64163
+ if (bytes + next > maxBytes) break;
64164
+ output += char;
64165
+ bytes += next;
64166
+ }
64167
+ return output;
64168
+ }
64169
+ function redactJournalText(text, exactSecrets) {
64170
+ let redacted = redactCodeModeLogText(text);
64171
+ for (const secret of exactSecrets) {
64172
+ if (!secret) continue;
64173
+ redacted = redacted.replaceAll(secret, "[REDACTED:capability]");
64174
+ }
64175
+ 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]");
64176
+ }
64177
+ function isJournalEntry(value) {
64178
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64179
+ const entry = value;
64180
+ 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");
64181
+ }
64182
+ function isJournalOutcome(value) {
64183
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64184
+ const outcome = value;
64185
+ return outcome.ok === true || outcome.ok === false && typeof outcome.code === "string";
64186
+ }
64187
+ function isJournalDiagnostic(value) {
64188
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
64189
+ const diagnostic = value;
64190
+ return typeof diagnostic.code === "string" && typeof diagnostic.message === "string" && (diagnostic.severity === "error" || diagnostic.severity === "warning" || diagnostic.severity === "info");
64191
+ }
64192
+ function rejectSymlinkPathComponents(rootDir, target, includeTarget) {
64193
+ const resolvedRoot = resolve(rootDir);
64194
+ rejectSymlinkRoot(resolvedRoot);
64195
+ const rel = relative(resolvedRoot, resolve(target));
64196
+ if (rel.startsWith("..") || rel === "") return;
64197
+ const parts = rel.split(/[\\/]+/u).filter(Boolean);
64198
+ let current = resolvedRoot;
64199
+ const limit = includeTarget ? parts.length : Math.max(0, parts.length - 1);
64200
+ for (let index = 0; index < limit; index += 1) {
64201
+ current = resolve(current, parts[index]);
64202
+ try {
64203
+ if (lstatSync(current).isSymbolicLink()) throw new Error("Code Mode journal path must not contain symlinks.");
64204
+ } catch (error) {
64205
+ if (error.code === "ENOENT") return;
64206
+ throw error;
64207
+ }
64208
+ }
64209
+ }
64210
+ function rejectSymlinkRoot(rootDir) {
64211
+ try {
64212
+ if (lstatSync(rootDir).isSymbolicLink()) throw new Error("Code Mode journal root must not be a symlink.");
64213
+ } catch (error) {
64214
+ if (error.code === "ENOENT") return;
64215
+ throw error;
64216
+ }
64217
+ }
64218
+ //#endregion
63850
64219
  //#region src/code-mode/api.ts
63851
64220
  const MAX_TOOL_TEXT_CHARS = 2e3;
63852
64221
  const MAX_ERROR_MESSAGE_CHARS = 1e3;
@@ -63870,7 +64239,10 @@ function dedupeCallableCaplets(caplets) {
63870
64239
  function createCodeModeCapletsApi(input) {
63871
64240
  const api = {};
63872
64241
  for (const caplet of listCodeModeCallableCaplets(input.service)) api[caplet.id] = createHandle(input.service, caplet.id);
63873
- const debugApi = { readLogs: input.readLogs ?? defaultReadLogs };
64242
+ const debugApi = {
64243
+ readLogs: input.readLogs ?? defaultReadLogs,
64244
+ readRecovery: input.readRecovery ?? defaultReadRecovery
64245
+ };
63874
64246
  api.debug = "debug" in api ? Object.assign(api.debug, debugApi) : debugApi;
63875
64247
  return api;
63876
64248
  }
@@ -64199,6 +64571,9 @@ async function defaultReadLogs() {
64199
64571
  timestamp: (/* @__PURE__ */ new Date(0)).toISOString()
64200
64572
  }] };
64201
64573
  }
64574
+ async function defaultReadRecovery() {
64575
+ return { entries: [] };
64576
+ }
64202
64577
  function resultIsError(result) {
64203
64578
  if (!isPlainObject$1(result)) return false;
64204
64579
  if (result.isError === true) return true;
@@ -77011,18 +77386,7 @@ function diagnoseCodeModeTypeScript(input) {
77011
77386
  const startedAt = Date.now();
77012
77387
  const diagnostics = [...preflightDiagnostics(input.code)];
77013
77388
  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
- };
77389
+ const compilerOptions = codeModeCompilerOptions();
77026
77390
  const wrappedCode = [
77027
77391
  "async function __capletsCodeModeMain(): Promise<unknown> {",
77028
77392
  input.code,
@@ -77031,7 +77395,7 @@ function diagnoseCodeModeTypeScript(input) {
77031
77395
  const host = createVirtualCompilerHost(compilerOptions, {
77032
77396
  [CODE_FILE]: wrappedCode,
77033
77397
  [DECLARATION_FILE]: input.declaration,
77034
- [AMBIENT_FILE]: CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION
77398
+ [AMBIENT_FILE]: [CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION, input.session?.declaration() ?? ""].join("\n")
77035
77399
  });
77036
77400
  const program = ts.createProgram([
77037
77401
  CODE_FILE,
@@ -77062,6 +77426,172 @@ function diagnoseCodeModeTypeScript(input) {
77062
77426
  }
77063
77427
  return diagnostics.slice(0, maxDiagnostics);
77064
77428
  }
77429
+ function codeModeCompilerOptions() {
77430
+ return {
77431
+ target: ts.ScriptTarget.ES2022,
77432
+ module: ts.ModuleKind.ESNext,
77433
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
77434
+ lib: ["lib.es2022.d.ts"],
77435
+ types: [],
77436
+ strict: true,
77437
+ noEmit: true,
77438
+ skipLibCheck: true,
77439
+ noErrorTruncation: true,
77440
+ allowJs: false
77441
+ };
77442
+ }
77443
+ var CodeModeDiagnosticsSession = class {
77444
+ #declarations = /* @__PURE__ */ new Map();
77445
+ declaration() {
77446
+ return [...this.#declarations.values()].join("\n");
77447
+ }
77448
+ recordSuccessfulCell(code, declaration = "") {
77449
+ const source = ts.createSourceFile("/caplets-code-mode/session-cell.ts", code, ts.ScriptTarget.ES2022, true);
77450
+ const compilerOptions = codeModeCompilerOptions();
77451
+ const ambientDeclarations = [
77452
+ CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION,
77453
+ declaration,
77454
+ this.declaration()
77455
+ ].join("\n");
77456
+ const host = createVirtualCompilerHost(compilerOptions, {
77457
+ [CODE_FILE]: code,
77458
+ [AMBIENT_FILE]: ambientDeclarations
77459
+ });
77460
+ const program = ts.createProgram([CODE_FILE, AMBIENT_FILE], compilerOptions, host);
77461
+ const checker = program.getTypeChecker();
77462
+ const programSource = program.getSourceFile(CODE_FILE) ?? source;
77463
+ for (const statement of programSource.statements) if (ts.isFunctionDeclaration(statement) && statement.name) {
77464
+ const typeParameters = statement.typeParameters ? `<${statement.typeParameters.map((typeParameter) => typeParameter.getText(programSource)).join(", ")}>` : "";
77465
+ const params = statement.parameters.map((parameter) => ambientParameter(parameter, programSource));
77466
+ const signature = checker.getSignatureFromDeclaration(statement);
77467
+ const inferredReturnType = signature ? safeAmbientFunctionReturnType(checker.getReturnTypeOfSignature(signature), checker, ambientDeclarations) : "unknown";
77468
+ const returnType = statement.type ? statement.type.getText(programSource) : inferredReturnType;
77469
+ this.#declarations.set(statement.name.text, `declare function ${statement.name.text}${typeParameters}(${params.join(", ")}): ${returnType};`);
77470
+ }
77471
+ const previousBindingNames = new Set(this.#declarations.keys());
77472
+ const assignedNames = collectFunctionScopedAssignedNames(programSource);
77473
+ for (const binding of collectFunctionScopedVarBindings(programSource, checker, {
77474
+ ambientDeclarationFor: (name) => [
77475
+ CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION,
77476
+ declaration,
77477
+ this.declarationExcluding(name)
77478
+ ].filter(Boolean).join("\n"),
77479
+ assignedNames,
77480
+ previousBindingNames
77481
+ })) this.#declarations.set(binding.name, `declare var ${binding.name}: ${binding.type};`);
77482
+ }
77483
+ clear() {
77484
+ this.#declarations.clear();
77485
+ }
77486
+ declarationExcluding(name) {
77487
+ const declarations = [CODE_MODE_DIAGNOSTICS_BUILTINS_DECLARATION];
77488
+ for (const [declarationName, declaration] of this.#declarations) if (declarationName !== name) declarations.push(declaration);
77489
+ return declarations.join("\n");
77490
+ }
77491
+ };
77492
+ function collectFunctionScopedVarBindings(source, checker, options) {
77493
+ const bindings = /* @__PURE__ */ new Map();
77494
+ const visit = (node) => {
77495
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
77496
+ if (ts.isVariableStatement(node)) collectVarDeclarationListBindings(node.declarationList, checker, bindings, options);
77497
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer)) collectVarDeclarationListBindings(node.initializer, checker, bindings, options);
77498
+ ts.forEachChild(node, visit);
77499
+ };
77500
+ visit(source);
77501
+ return [...bindings.entries()].map(([name, type]) => ({
77502
+ name,
77503
+ type
77504
+ }));
77505
+ }
77506
+ function collectVarDeclarationListBindings(declarationList, checker, bindings, options) {
77507
+ if (!((ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0)) return;
77508
+ for (const declaration of declarationList.declarations) for (const name of bindingNames$1(declaration.name)) {
77509
+ const type = ambientTypeForBindingName(name, checker, options.ambientDeclarationFor(name.text));
77510
+ if (options.previousBindingNames.has(name.text) && declaration.initializer === void 0 && !options.assignedNames.has(name.text)) continue;
77511
+ bindings.set(name.text, type);
77512
+ }
77513
+ }
77514
+ function bindingNames$1(name) {
77515
+ if (ts.isIdentifier(name)) return [name];
77516
+ return name.elements.flatMap((element) => {
77517
+ if (ts.isOmittedExpression(element)) return [];
77518
+ return bindingNames$1(element.name);
77519
+ });
77520
+ }
77521
+ function collectFunctionScopedAssignedNames(source) {
77522
+ const names = /* @__PURE__ */ new Set();
77523
+ const visit = (node) => {
77524
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
77525
+ if (ts.isBinaryExpression(node) && isAssignmentOperator(node.operatorToken.kind)) collectAssignedBindingNames(node.left, names);
77526
+ if ((ts.isPrefixUnaryExpression(node) || ts.isPostfixUnaryExpression(node)) && (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator === ts.SyntaxKind.MinusMinusToken)) collectAssignedBindingNames(node.operand, names);
77527
+ ts.forEachChild(node, visit);
77528
+ };
77529
+ visit(source);
77530
+ return names;
77531
+ }
77532
+ function isAssignmentOperator(kind) {
77533
+ return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
77534
+ }
77535
+ function collectAssignedBindingNames(node, names) {
77536
+ if (ts.isIdentifier(node)) {
77537
+ names.add(node.text);
77538
+ return;
77539
+ }
77540
+ if (ts.isPropertyAssignment(node)) {
77541
+ collectAssignedBindingNames(node.initializer, names);
77542
+ return;
77543
+ }
77544
+ if (ts.isShorthandPropertyAssignment(node)) {
77545
+ names.add(node.name.text);
77546
+ return;
77547
+ }
77548
+ if (ts.isSpreadAssignment(node)) {
77549
+ collectAssignedBindingNames(node.expression, names);
77550
+ return;
77551
+ }
77552
+ if (ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node)) ts.forEachChild(node, (child) => collectAssignedBindingNames(child, names));
77553
+ }
77554
+ function ambientTypeForBindingName(name, checker, ambientDeclaration) {
77555
+ const type = checker.getTypeAtLocation(name);
77556
+ return safeAmbientType(name.text, type, checker, ambientDeclaration);
77557
+ }
77558
+ function safeAmbientType(name, type, checker, ambientDeclaration) {
77559
+ return safeAmbientTypeText(type, checker, ambientDeclaration, (typeText) => isSelfContainedAmbientDeclaration(`declare let ${name}: ${typeText};`, ambientDeclaration));
77560
+ }
77561
+ function safeAmbientFunctionReturnType(type, checker, ambientDeclaration) {
77562
+ return safeAmbientTypeText(type, checker, ambientDeclaration, (typeText) => isSelfContainedAmbientDeclaration(`declare function __caplets_return_probe__(): ${typeText};`, ambientDeclaration));
77563
+ }
77564
+ function safeAmbientTypeText(type, checker, ambientDeclaration, isSelfContained) {
77565
+ if (isUnsafeAmbientType(type)) return "unknown";
77566
+ const text = checker.typeToString(type, void 0, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope | ts.TypeFormatFlags.WriteArrayAsGenericType);
77567
+ if (!text || text === "any" || text === "{}" || text === "never") return "unknown";
77568
+ if (text.length > 500) return "unknown";
77569
+ if (/\bimport\(/u.test(text)) return "unknown";
77570
+ if (!isSelfContained(text)) return "unknown";
77571
+ return text;
77572
+ }
77573
+ function isUnsafeAmbientType(type) {
77574
+ return Boolean(type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Never));
77575
+ }
77576
+ function isSelfContainedAmbientDeclaration(candidateDeclaration, ambientDeclaration) {
77577
+ const compilerOptions = codeModeCompilerOptions();
77578
+ const host = createVirtualCompilerHost(compilerOptions, {
77579
+ [CODE_FILE]: candidateDeclaration,
77580
+ [AMBIENT_FILE]: ambientDeclaration
77581
+ });
77582
+ const program = ts.createProgram([CODE_FILE, AMBIENT_FILE], compilerOptions, host);
77583
+ return program.getSemanticDiagnostics(program.getSourceFile(CODE_FILE)).length === 0;
77584
+ }
77585
+ function ambientParameter(parameter, source) {
77586
+ return `${parameter.dotDotDotToken ? "..." : ""}${parameter.name.getText(source)}${parameter.questionToken || parameter.initializer ? "?" : ""}: ${parameter.type?.getText(source) ?? (parameter.initializer ? inferLiteralType(parameter.initializer) : "unknown")}`;
77587
+ }
77588
+ function inferLiteralType(initializer) {
77589
+ if (!initializer) return "unknown";
77590
+ if (ts.isNumericLiteral(initializer)) return "number";
77591
+ if (ts.isStringLiteral(initializer)) return "string";
77592
+ if (initializer.kind === ts.SyntaxKind.TrueKeyword || initializer.kind === ts.SyntaxKind.FalseKeyword) return "boolean";
77593
+ return "unknown";
77594
+ }
77065
77595
  function preflightDiagnostics(code) {
77066
77596
  const diagnostics = [];
77067
77597
  if (!hasExecutableImport(code)) {} else diagnostics.push({
@@ -77192,10 +77722,393 @@ function resolveTimer(context, deferred, fired) {
77192
77722
  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
77723
  //#endregion
77194
77724
  //#region src/code-mode/sandbox.ts
77725
+ const CODE_MODE_SANDBOX_METHODS = new Set([
77726
+ "inspect",
77727
+ "check",
77728
+ "tools",
77729
+ "searchTools",
77730
+ "describeTool",
77731
+ "callTool",
77732
+ "resources",
77733
+ "searchResources",
77734
+ "resourceTemplates",
77735
+ "readResource",
77736
+ "prompts",
77737
+ "searchPrompts",
77738
+ "getPrompt",
77739
+ "complete",
77740
+ "readLogs",
77741
+ "readRecovery"
77742
+ ]);
77743
+ const CODE_MODE_DEBUG_METHODS = new Set(["readLogs", "readRecovery"]);
77195
77744
  var QuickJsCodeModeSandbox = class {
77196
77745
  async run(input) {
77197
77746
  return await evaluateInQuickJs(input);
77198
77747
  }
77748
+ async createSession() {
77749
+ return new QuickJsCodeModeReplSession((await getQuickJS()).newRuntime());
77750
+ }
77751
+ };
77752
+ var QuickJsCodeModeReplSession = class {
77753
+ #runtime;
77754
+ #context;
77755
+ #pendingDeferreds = /* @__PURE__ */ new Set();
77756
+ #pendingInvokes = /* @__PURE__ */ new Set();
77757
+ #platformHost;
77758
+ #capletIds = /* @__PURE__ */ new Set();
77759
+ #persistentNames = /* @__PURE__ */ new Set();
77760
+ #invoke = async () => {
77761
+ throw new Error("Code Mode invoke bridge is not initialized.");
77762
+ };
77763
+ #deadlineMs = 0;
77764
+ #timeoutMs = 0;
77765
+ #logs = [];
77766
+ #disposed = false;
77767
+ #running = false;
77768
+ #disposeRequested = false;
77769
+ #globalNameCheckpoint = /* @__PURE__ */ new Set();
77770
+ #persistDescriptorCheckpoint = "";
77771
+ #checkpointToken = randomUUID();
77772
+ constructor(runtime) {
77773
+ this.#runtime = runtime;
77774
+ this.#runtime.setMemoryLimit(64 * 1024 * 1024);
77775
+ this.#runtime.setMaxStackSize(1 * 1024 * 1024);
77776
+ this.#context = runtime.newContext();
77777
+ this.#installStableBridges();
77778
+ this.#platformHost = installCodeModePlatformHost(this.#context, this.#pendingDeferreds, {});
77779
+ this.#evalInitSource();
77780
+ }
77781
+ async run(input) {
77782
+ if (this.#disposed) return {
77783
+ ok: false,
77784
+ error: "Code Mode session is disposed.",
77785
+ logs: []
77786
+ };
77787
+ if (this.#disposeRequested) return {
77788
+ ok: false,
77789
+ error: "Code Mode session is disposed.",
77790
+ logs: []
77791
+ };
77792
+ if (this.#running) return {
77793
+ ok: false,
77794
+ error: "Code Mode session is already running.",
77795
+ logs: []
77796
+ };
77797
+ this.#running = true;
77798
+ const timeoutMs = Math.max(100, input.timeoutMs);
77799
+ const deadlineMs = Date.now() + timeoutMs;
77800
+ this.#runtime.setInterruptHandler(shouldInterruptAfterDeadline(deadlineMs));
77801
+ this.#logs = [];
77802
+ let shouldDispose = false;
77803
+ try {
77804
+ this.#refreshInvokeBridge(input.invoke, deadlineMs, timeoutMs);
77805
+ const bridgeResult = this.#context.evalCode(buildBridgeRefreshSource(input.capletIds, [...this.#capletIds]));
77806
+ if (bridgeResult.error) {
77807
+ const error = this.#context.dump(bridgeResult.error);
77808
+ bridgeResult.error.dispose();
77809
+ const result = {
77810
+ ok: false,
77811
+ error: normalizeError(error, deadlineMs, timeoutMs),
77812
+ logs: this.#logs,
77813
+ ...optionalStack(stackFromDump(error))
77814
+ };
77815
+ shouldDispose = isTimeoutMessage(result.error, timeoutMs);
77816
+ return result;
77817
+ }
77818
+ bridgeResult.value.dispose();
77819
+ this.#capletIds = new Set(input.capletIds);
77820
+ const cell = buildSessionCellSource(input.code, input.capletIds, [...this.#persistentNames], this.#checkpointToken);
77821
+ const resetResult = this.#context.evalCode(buildPlatformResetSource());
77822
+ if (resetResult.error) {
77823
+ const error = this.#context.dump(resetResult.error);
77824
+ resetResult.error.dispose();
77825
+ const result = {
77826
+ ok: false,
77827
+ error: `Code Mode session state is corrupted: ${normalizeError(error, deadlineMs, timeoutMs)}`,
77828
+ logs: this.#logs,
77829
+ ...optionalStack(stackFromDump(error))
77830
+ };
77831
+ shouldDispose = true;
77832
+ return result;
77833
+ }
77834
+ resetResult.value.dispose();
77835
+ this.#snapshotGlobalNames();
77836
+ this.#snapshotPersistDescriptors();
77837
+ this.#snapshotPersistentNames([...this.#persistentNames]);
77838
+ let pendingInvokePersistentValuesChanged = false;
77839
+ const result = await evaluateCellInContext({
77840
+ code: input.code,
77841
+ compiledSource: cell.source,
77842
+ context: this.#context,
77843
+ runtime: this.#runtime,
77844
+ pendingDeferreds: this.#pendingDeferreds,
77845
+ pendingInvokes: this.#pendingInvokes,
77846
+ deadlineMs,
77847
+ timeoutMs,
77848
+ logs: this.#logs,
77849
+ session: true,
77850
+ afterPendingInvokesDrained: () => {
77851
+ pendingInvokePersistentValuesChanged = this.#persistentValuesDivergedFromPersist(cell.persistentNames);
77852
+ this.#snapshotPersistentNames(cell.persistentNames);
77853
+ }
77854
+ });
77855
+ if (result.ok) {
77856
+ for (const name of cell.persistentNames) this.#persistentNames.add(name);
77857
+ this.#snapshotPersistentNames(cell.persistentNames);
77858
+ } else {
77859
+ this.#restorePersistentNames([...this.#persistentNames]);
77860
+ this.#rollbackNewPersistentNames(cell.newNames);
77861
+ }
77862
+ const platformRestored = result.ok ? this.#restorePlatformAfterRun() : true;
77863
+ const persistenceDescriptorsOk = result.ok && platformRestored ? this.#persistentDescriptorsOk(cell.persistentNames) : true;
77864
+ const persistentGlobalDescriptorsOk = this.#persistentGlobalDescriptorsOk(result.ok ? cell.persistentNames : [...this.#persistentNames]);
77865
+ const hasGlobalNameAdditions = this.#hasGlobalNameAdditions(result.ok ? cell.persistentNames : []);
77866
+ const directPersistAccess = this.#isPersistTainted();
77867
+ const persistDescriptorsChanged = this.#persistDescriptorsChanged(result.ok ? cell.snapshotNames : []);
77868
+ const hasObjectLikePersistentState = this.#hasObjectLikePersistentState();
77869
+ 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();
77870
+ if (!shouldDispose) this.#clearPendingDeferreds();
77871
+ return result;
77872
+ } catch (error) {
77873
+ const result = {
77874
+ ok: false,
77875
+ error: normalizeError(error, deadlineMs, timeoutMs),
77876
+ logs: this.#logs,
77877
+ ...optionalStack(stackFromError(error))
77878
+ };
77879
+ shouldDispose = true;
77880
+ return result;
77881
+ } finally {
77882
+ this.#running = false;
77883
+ if (!this.#disposed) this.#runtime.setInterruptHandler(() => false);
77884
+ if (shouldDispose) this.dispose();
77885
+ if (this.#disposeRequested) this.#disposeNow();
77886
+ }
77887
+ }
77888
+ dispose() {
77889
+ if (this.#disposed) return;
77890
+ if (this.#running) {
77891
+ this.#disposeRequested = true;
77892
+ return;
77893
+ }
77894
+ this.#disposeNow();
77895
+ }
77896
+ isDisposed() {
77897
+ return this.#disposed;
77898
+ }
77899
+ #disposeNow() {
77900
+ if (this.#disposed) return;
77901
+ this.#disposeRequested = false;
77902
+ this.#disposed = true;
77903
+ this.#platformHost.dispose();
77904
+ for (const deferred of this.#pendingDeferreds) if (deferred.alive) deferred.dispose();
77905
+ this.#pendingDeferreds.clear();
77906
+ this.#pendingInvokes.clear();
77907
+ this.#context.dispose();
77908
+ this.#runtime.dispose();
77909
+ }
77910
+ #installStableBridges() {
77911
+ const logBridge = this.#context.newFunction("__caplets_log", (levelHandle, messageHandle) => {
77912
+ this.#logs.push({
77913
+ level: logLevel(this.#context.getString(levelHandle)),
77914
+ message: this.#context.getString(messageHandle),
77915
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
77916
+ });
77917
+ return this.#context.undefined;
77918
+ });
77919
+ this.#context.setProp(this.#context.global, "__caplets_log", logBridge);
77920
+ logBridge.dispose();
77921
+ const invokeBridge = createInvokeJsonBridge(this.#context, this.#pendingDeferreds, this.#pendingInvokes, () => this.#invoke, () => this.#deadlineMs, () => this.#timeoutMs, (capletId) => this.#capletIds.has(capletId));
77922
+ this.#context.setProp(this.#context.global, "__caplets_invoke_json", invokeBridge);
77923
+ invokeBridge.dispose();
77924
+ const activeCapletBridge = this.#context.newFunction("__caplets_is_active_id", (capletIdHandle) => this.#capletIds.has(this.#context.getString(capletIdHandle)) ? this.#context.true : this.#context.false);
77925
+ this.#context.setProp(this.#context.global, "__caplets_is_active_id", activeCapletBridge);
77926
+ activeCapletBridge.dispose();
77927
+ const protectInvokeBridge = this.#context.evalCode([
77928
+ "Object.defineProperty(globalThis, '__caplets_log', { configurable: false, writable: false, value: globalThis.__caplets_log });",
77929
+ "Object.defineProperty(globalThis, '__caplets_invoke_json', { configurable: false, writable: false, value: globalThis.__caplets_invoke_json });",
77930
+ "Object.defineProperty(globalThis, '__caplets_is_active_id', { configurable: false, writable: false, value: globalThis.__caplets_is_active_id });"
77931
+ ].join("\n"));
77932
+ if (protectInvokeBridge.error) {
77933
+ const error = this.#context.dump(protectInvokeBridge.error);
77934
+ protectInvokeBridge.error.dispose();
77935
+ throw new Error(errorMessage$2(error));
77936
+ }
77937
+ protectInvokeBridge.value.dispose();
77938
+ }
77939
+ #evalInitSource() {
77940
+ const result = this.#context.evalCode(buildSessionInitSource(this.#checkpointToken));
77941
+ if (result.error) {
77942
+ const error = this.#context.dump(result.error);
77943
+ result.error.dispose();
77944
+ throw new Error(errorMessage$2(error));
77945
+ }
77946
+ result.value.dispose();
77947
+ }
77948
+ #refreshInvokeBridge(invoke, deadlineMs, timeoutMs) {
77949
+ this.#invoke = invoke;
77950
+ this.#deadlineMs = deadlineMs;
77951
+ this.#timeoutMs = timeoutMs;
77952
+ }
77953
+ #rollbackNewPersistentNames(names) {
77954
+ if (names.length === 0 || this.#disposed) return;
77955
+ const result = this.#context.evalCode(names.map((name) => `(0, eval)(${JSON.stringify(`${name} = undefined;`)});`).join("\n"));
77956
+ if (result.error) {
77957
+ result.error.dispose();
77958
+ return;
77959
+ }
77960
+ result.value.dispose();
77961
+ }
77962
+ #clearPendingDeferreds() {
77963
+ this.#platformHost.dispose();
77964
+ for (const deferred of this.#pendingDeferreds) if (deferred.alive) deferred.dispose();
77965
+ this.#pendingDeferreds.clear();
77966
+ }
77967
+ #snapshotGlobalNames() {
77968
+ if (this.#disposed) return;
77969
+ const result = this.#context.evalCode("__caplets_global_keys()");
77970
+ if (result.error) {
77971
+ result.error.dispose();
77972
+ return;
77973
+ }
77974
+ const names = this.#context.dump(result.value);
77975
+ this.#globalNameCheckpoint = new Set(names.filter((name) => !this.#isInternalGlobalName(name)));
77976
+ result.value.dispose();
77977
+ }
77978
+ #snapshotPersistDescriptors() {
77979
+ if (this.#disposed) return;
77980
+ const result = this.#context.evalCode("__caplets_persist_descriptor_fingerprint()");
77981
+ if (result.error) {
77982
+ result.error.dispose();
77983
+ this.#persistDescriptorCheckpoint = "";
77984
+ return;
77985
+ }
77986
+ this.#persistDescriptorCheckpoint = String(this.#context.dump(result.value));
77987
+ result.value.dispose();
77988
+ }
77989
+ #persistDescriptorsChanged(allowedNames = []) {
77990
+ if (this.#disposed) return false;
77991
+ const result = this.#context.evalCode(`__caplets_persist_descriptor_fingerprint(${JSON.stringify(allowedNames)})`);
77992
+ if (result.error) {
77993
+ result.error.dispose();
77994
+ return true;
77995
+ }
77996
+ const fingerprint = String(this.#context.dump(result.value));
77997
+ result.value.dispose();
77998
+ return fingerprint !== filterPersistDescriptorFingerprint(this.#persistDescriptorCheckpoint, allowedNames);
77999
+ }
78000
+ #hasGlobalNameAdditions(allowedNames = []) {
78001
+ if (this.#disposed) return false;
78002
+ const result = this.#context.evalCode("__caplets_global_keys()");
78003
+ if (result.error) {
78004
+ result.error.dispose();
78005
+ return true;
78006
+ }
78007
+ const names = this.#context.dump(result.value);
78008
+ const allowedTokens = new Set(allowedNames.map((name) => `string:${name}`));
78009
+ const hasAdditions = names.filter((name) => !this.#isInternalGlobalName(name)).filter((name) => !allowedTokens.has(name)).some((name) => !this.#globalNameCheckpoint.has(name));
78010
+ result.value.dispose();
78011
+ return hasAdditions;
78012
+ }
78013
+ #isGlobalExtensible() {
78014
+ if (this.#disposed) return false;
78015
+ const result = this.#context.evalCode("__caplets_is_global_extensible()");
78016
+ if (result.error) {
78017
+ result.error.dispose();
78018
+ return false;
78019
+ }
78020
+ const isExtensible = this.#context.dump(result.value) === true;
78021
+ result.value.dispose();
78022
+ return isExtensible;
78023
+ }
78024
+ #restorePlatformAfterRun() {
78025
+ if (this.#disposed) return false;
78026
+ const result = this.#context.evalCode(buildPlatformResetSource());
78027
+ if (result.error) {
78028
+ result.error.dispose();
78029
+ return false;
78030
+ }
78031
+ result.value.dispose();
78032
+ return true;
78033
+ }
78034
+ #persistentDescriptorsOk(names) {
78035
+ if (names.length === 0 || this.#disposed) return true;
78036
+ const result = this.#context.evalCode(`__caplets_persist_descriptors_ok(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)})`);
78037
+ if (result.error) {
78038
+ result.error.dispose();
78039
+ return false;
78040
+ }
78041
+ const ok = this.#context.dump(result.value) === true;
78042
+ result.value.dispose();
78043
+ return ok;
78044
+ }
78045
+ #isPersistTainted() {
78046
+ if (this.#disposed) return false;
78047
+ const result = this.#context.evalCode(`__caplets_persist_is_tainted(${JSON.stringify(this.#checkpointToken)})`);
78048
+ if (result.error) {
78049
+ result.error.dispose();
78050
+ return true;
78051
+ }
78052
+ const tainted = this.#context.dump(result.value) === true;
78053
+ result.value.dispose();
78054
+ return tainted;
78055
+ }
78056
+ #hasObjectLikePersistentState() {
78057
+ if (this.#disposed || this.#persistentNames.size === 0) return false;
78058
+ const result = this.#context.evalCode(`__caplets_persist_has_object_like_values(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify([...this.#persistentNames])})`);
78059
+ if (result.error) {
78060
+ result.error.dispose();
78061
+ return true;
78062
+ }
78063
+ const hasObjectLike = this.#context.dump(result.value) === true;
78064
+ result.value.dispose();
78065
+ return hasObjectLike;
78066
+ }
78067
+ #persistentGlobalDescriptorsOk(names) {
78068
+ if (names.length === 0 || this.#disposed) return true;
78069
+ const result = this.#context.evalCode(`__caplets_persist_global_descriptors_ok(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)})`);
78070
+ if (result.error) {
78071
+ result.error.dispose();
78072
+ return false;
78073
+ }
78074
+ const ok = this.#context.dump(result.value) === true;
78075
+ result.value.dispose();
78076
+ return ok;
78077
+ }
78078
+ #isInternalGlobalName(name) {
78079
+ 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";
78080
+ }
78081
+ #snapshotPersistentNames(names) {
78082
+ if (names.length === 0 || this.#disposed) return;
78083
+ const result = this.#context.evalCode(`globalThis.__caplets_snapshot_persist(${JSON.stringify(this.#checkpointToken)}, ${JSON.stringify(names)});`);
78084
+ if (result.error) {
78085
+ result.error.dispose();
78086
+ return;
78087
+ }
78088
+ result.value.dispose();
78089
+ }
78090
+ #persistentValuesDivergedFromPersist(names) {
78091
+ if (this.#disposed || names.length === 0) return false;
78092
+ const result = this.#context.evalCode(`(${JSON.stringify(names)}).some((name) => !Object.is((0, eval)(name), globalThis.__caplets_get_persist(${JSON.stringify(this.#checkpointToken)}, name)))`);
78093
+ if (result.error) {
78094
+ result.error.dispose();
78095
+ return true;
78096
+ }
78097
+ try {
78098
+ return this.#context.dump(result.value) === true;
78099
+ } finally {
78100
+ result.value.dispose();
78101
+ }
78102
+ }
78103
+ #restorePersistentNames(names) {
78104
+ if (names.length === 0 || this.#disposed) return;
78105
+ 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"));
78106
+ if (result.error) {
78107
+ result.error.dispose();
78108
+ return;
78109
+ }
78110
+ result.value.dispose();
78111
+ }
77199
78112
  };
77200
78113
  async function evaluateInQuickJs(input) {
77201
78114
  const timeoutMs = Math.max(100, input.timeoutMs);
@@ -77223,62 +78136,20 @@ async function evaluateInQuickJs(input) {
77223
78136
  const invokeBridge = createInvokeBridge(context, pendingDeferreds, input.invoke, deadlineMs, timeoutMs);
77224
78137
  context.setProp(context.global, "__caplets_invoke", invokeBridge);
77225
78138
  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
78139
  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
- };
78140
+ return await evaluateCellInContext({
78141
+ code: input.code,
78142
+ capletIds: input.capletIds,
78143
+ context,
78144
+ runtime,
78145
+ pendingDeferreds,
78146
+ pendingInvokes: pendingDeferreds,
78147
+ deadlineMs,
78148
+ timeoutMs,
78149
+ logs,
78150
+ session: false
78151
+ });
77280
78152
  } finally {
77281
- stateHandle.dispose();
77282
78153
  platformHost.dispose();
77283
78154
  }
77284
78155
  } finally {
@@ -77297,6 +78168,96 @@ async function evaluateInQuickJs(input) {
77297
78168
  runtime.dispose();
77298
78169
  }
77299
78170
  }
78171
+ async function evaluateCellInContext(input) {
78172
+ const observerResult = input.context.evalCode(buildPromiseObserverSource());
78173
+ if (observerResult.error) {
78174
+ const error = input.context.dump(observerResult.error);
78175
+ observerResult.error.dispose();
78176
+ return {
78177
+ ok: false,
78178
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78179
+ logs: input.logs,
78180
+ ...optionalStack(stackFromDump(error))
78181
+ };
78182
+ }
78183
+ observerResult.value.dispose();
78184
+ const evaluated = input.context.evalCode(input.compiledSource ?? (input.session ? buildSessionCellSource(input.code, input.capletIds ?? []).source : buildExecutionSource(input.code, input.capletIds ?? [])));
78185
+ if (evaluated.error) {
78186
+ const error = input.context.dump(evaluated.error);
78187
+ evaluated.error.dispose();
78188
+ return {
78189
+ ok: false,
78190
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78191
+ logs: input.logs,
78192
+ ...optionalStack(stackFromDump(error))
78193
+ };
78194
+ }
78195
+ const resultName = `__caplets_result_${randomUUID().replace(/-/gu, "_")}`;
78196
+ input.context.setProp(input.context.global, resultName, evaluated.value);
78197
+ evaluated.value.dispose();
78198
+ const stateResult = input.context.evalCode(buildPromiseStateSource(JSON.stringify(resultName)));
78199
+ cleanupTemporaryGlobals(input.context, JSON.stringify(resultName));
78200
+ if (stateResult.error) {
78201
+ const error = input.context.dump(stateResult.error);
78202
+ stateResult.error.dispose();
78203
+ return {
78204
+ ok: false,
78205
+ error: normalizeError(error, input.deadlineMs, input.timeoutMs),
78206
+ logs: input.logs,
78207
+ ...optionalStack(stackFromDump(error))
78208
+ };
78209
+ }
78210
+ const stateHandle = stateResult.value;
78211
+ try {
78212
+ if (input.session) {
78213
+ if (input.pendingInvokes.size > 0) {
78214
+ await drainAsync(input.context, input.runtime, input.pendingInvokes, input.deadlineMs, input.timeoutMs);
78215
+ await drainAsync(input.context, input.runtime, input.pendingDeferreds, input.deadlineMs, input.timeoutMs);
78216
+ await Promise.resolve();
78217
+ drainJobs(input.context, input.runtime, input.deadlineMs, input.timeoutMs);
78218
+ input.afterPendingInvokesDrained?.();
78219
+ } else drainJobs(input.context, input.runtime, input.deadlineMs, input.timeoutMs);
78220
+ const earlyResult = readSettledPromiseState(input.context, stateHandle, input.logs);
78221
+ if (earlyResult) return earlyResult;
78222
+ }
78223
+ await drainAsync(input.context, input.runtime, input.pendingDeferreds, input.deadlineMs, input.timeoutMs);
78224
+ if (!(readProp(input.context, stateHandle, "settled") === true)) return {
78225
+ ok: false,
78226
+ error: timeoutMessage(input.timeoutMs),
78227
+ logs: input.logs
78228
+ };
78229
+ return readSettledPromiseState(input.context, stateHandle, input.logs) ?? {
78230
+ ok: false,
78231
+ error: timeoutMessage(input.timeoutMs),
78232
+ logs: input.logs
78233
+ };
78234
+ } finally {
78235
+ stateHandle.dispose();
78236
+ }
78237
+ }
78238
+ function cleanupTemporaryGlobals(context, ...names) {
78239
+ if (names.length === 0) return;
78240
+ const result = context.evalCode(names.map((name) => `delete globalThis[${name}];`).join("\n"));
78241
+ if (result.error) {
78242
+ result.error.dispose();
78243
+ return;
78244
+ }
78245
+ result.value.dispose();
78246
+ }
78247
+ function readSettledPromiseState(context, stateHandle, logs) {
78248
+ if (!(readProp(context, stateHandle, "settled") === true)) return;
78249
+ const error = readProp(context, stateHandle, "error");
78250
+ if (typeof error !== "undefined") return {
78251
+ ok: false,
78252
+ error: errorMessage$2(error),
78253
+ logs
78254
+ };
78255
+ return {
78256
+ ok: true,
78257
+ value: readProp(context, stateHandle, "value"),
78258
+ logs
78259
+ };
78260
+ }
77300
78261
  function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeoutMs) {
77301
78262
  return context.newFunction("__caplets_invoke", (capletHandle, methodHandle, argsHandle) => {
77302
78263
  const capletId = context.getString(capletHandle);
@@ -77304,7 +78265,10 @@ function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeo
77304
78265
  const args = context.dump(argsHandle);
77305
78266
  const deferred = context.newPromise();
77306
78267
  pendingDeferreds.add(deferred);
77307
- deferred.settled.finally(() => pendingDeferreds.delete(deferred));
78268
+ deferred.settled.finally(() => {
78269
+ pendingDeferreds.delete(deferred);
78270
+ if (deferred.alive) deferred.dispose();
78271
+ });
77308
78272
  invoke({
77309
78273
  capletId,
77310
78274
  method,
@@ -77331,6 +78295,78 @@ function createInvokeBridge(context, pendingDeferreds, invoke, deadlineMs, timeo
77331
78295
  return deferred.handle;
77332
78296
  });
77333
78297
  }
78298
+ function createInvokeJsonBridge(context, pendingDeferreds, pendingInvokes, invoke, deadlineMs, timeoutMs, isCapletActive) {
78299
+ return context.newFunction("__caplets_invoke_json", (capletHandle, methodHandle, argsHandle) => {
78300
+ const capletId = context.getString(capletHandle);
78301
+ const method = context.getString(methodHandle);
78302
+ const args = context.dump(argsHandle);
78303
+ const deferred = context.newPromise();
78304
+ pendingDeferreds.add(deferred);
78305
+ pendingInvokes.add(deferred);
78306
+ deferred.settled.finally(() => {
78307
+ pendingDeferreds.delete(deferred);
78308
+ pendingInvokes.delete(deferred);
78309
+ if (deferred.alive) deferred.dispose();
78310
+ });
78311
+ const debugMethod = CODE_MODE_DEBUG_METHODS.has(method);
78312
+ const debugCapletActive = capletId === "debug" && isCapletActive("debug");
78313
+ if (!isCodeModeSandboxMethod(method) || capletId === "debug" && !debugMethod && !debugCapletActive || capletId !== "debug" && debugMethod) {
78314
+ const errorHandle = context.newError(`Method ${method} is not available in this Code Mode session cell.`);
78315
+ deferred.reject(errorHandle);
78316
+ errorHandle.dispose();
78317
+ return deferred.handle;
78318
+ }
78319
+ if (!(capletId === "debug" && debugMethod) && !isCapletActive(capletId)) {
78320
+ const errorHandle = context.newError(`Caplet ${capletId} is not available in this Code Mode session cell.`);
78321
+ deferred.reject(errorHandle);
78322
+ errorHandle.dispose();
78323
+ return deferred.handle;
78324
+ }
78325
+ invoke()({
78326
+ capletId,
78327
+ method,
78328
+ args
78329
+ }).then((value) => {
78330
+ if (!deferred.alive) return;
78331
+ let valueHandle;
78332
+ try {
78333
+ const serialized = JSON.stringify(value);
78334
+ const parsed = context.evalCode(`globalThis.__caplets_json_parse(${JSON.stringify(serialized ?? "null")})`);
78335
+ if (parsed.error) {
78336
+ const error = context.dump(parsed.error);
78337
+ parsed.error.dispose();
78338
+ throw new Error(errorMessage$2(error));
78339
+ }
78340
+ valueHandle = parsed.value;
78341
+ deferred.resolve(valueHandle);
78342
+ } catch (error) {
78343
+ const errorHandle = context.newError(errorMessage$2(error));
78344
+ deferred.reject(errorHandle);
78345
+ errorHandle.dispose();
78346
+ } finally {
78347
+ valueHandle?.dispose();
78348
+ }
78349
+ }, (error) => {
78350
+ if (!deferred.alive) return;
78351
+ const message = Date.now() >= deadlineMs() ? timeoutMessage(timeoutMs()) : errorMessage$2(error);
78352
+ const errorHandle = context.newError(message);
78353
+ deferred.reject(errorHandle);
78354
+ errorHandle.dispose();
78355
+ });
78356
+ return deferred.handle;
78357
+ });
78358
+ }
78359
+ function isCodeModeSandboxMethod(method) {
78360
+ return CODE_MODE_SANDBOX_METHODS.has(method);
78361
+ }
78362
+ function filterPersistDescriptorFingerprint(fingerprint, allowedNames) {
78363
+ if (!fingerprint || allowedNames.length === 0) return fingerprint;
78364
+ const allowedTokens = new Set(allowedNames.map((name) => `string:${name}`));
78365
+ return fingerprint.split("|").filter((entry) => {
78366
+ const token = entry.startsWith("string:") ? entry.slice(0, entry.indexOf(":", 7)) : entry.startsWith("symbol:") ? entry.slice(0, entry.indexOf(":", 7)) : entry;
78367
+ return !allowedTokens.has(token);
78368
+ }).join("|");
78369
+ }
77334
78370
  function buildExecutionSource(code, capletIds) {
77335
78371
  const javascript = ts.transpileModule(code, { compilerOptions: {
77336
78372
  target: ts.ScriptTarget.ES2022,
@@ -77362,11 +78398,546 @@ function buildExecutionSource(code, capletIds) {
77362
78398
  ...capletIds.map((capletId) => `caplets[${JSON.stringify(capletId)}] = __handle(${JSON.stringify(capletId)});`),
77363
78399
  "caplets.debug = caplets.debug || {};",
77364
78400
  "caplets.debug.readLogs = (input) => __invoke('debug', 'readLogs', [input]);",
78401
+ "caplets.debug.readRecovery = (input) => __invoke('debug', 'readRecovery', [input]);",
77365
78402
  "(async () => {",
77366
78403
  javascript,
77367
78404
  "})()"
77368
78405
  ].join("\n");
77369
78406
  }
78407
+ function buildSessionInitSource(checkpointToken) {
78408
+ return [
78409
+ CODE_MODE_PLATFORM_RUNTIME_SOURCE,
78410
+ "const __caplets_restore_platform = (() => {",
78411
+ " const defineProperty = Object.defineProperty.bind(Object);",
78412
+ " const defineProperties = Object.defineProperties.bind(Object);",
78413
+ " const getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors.bind(Object);",
78414
+ " const getPrototypeOf = Object.getPrototypeOf.bind(Object);",
78415
+ " const setPrototypeOf = Object.setPrototypeOf.bind(Object);",
78416
+ " const isExtensible = Object.isExtensible.bind(Object);",
78417
+ " const ownKeys = Reflect.ownKeys.bind(Reflect);",
78418
+ " const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);",
78419
+ " const arrayPush = Function.prototype.call.bind(Array.prototype.push);",
78420
+ " const globalSymbolIds = new Map();",
78421
+ " let nextGlobalSymbolId = 1;",
78422
+ " const keyToken = (key) => {",
78423
+ " if (typeof key !== 'symbol') return `string:${key}`;",
78424
+ " if (!globalSymbolIds.has(key)) globalSymbolIds.set(key, nextGlobalSymbolId++);",
78425
+ " return `symbol:${globalSymbolIds.get(key)}`;",
78426
+ " };",
78427
+ " const platformGlobals = [];",
78428
+ " const globalPrototypeSnapshot = getPrototypeOf(globalThis);",
78429
+ " const platformExtraObjects = [",
78430
+ " ['AsyncFunction.prototype', getPrototypeOf(async function() {})],",
78431
+ " ['AsyncFunctionConstructor', getPrototypeOf(async function() {}).constructor],",
78432
+ " ['GeneratorFunction.prototype', getPrototypeOf(function*() {})],",
78433
+ " ['GeneratorFunctionConstructor', getPrototypeOf(function*() {}).constructor],",
78434
+ " ['AsyncGeneratorFunction.prototype', getPrototypeOf(async function*() {})],",
78435
+ " ['AsyncGeneratorFunctionConstructor', getPrototypeOf(async function*() {}).constructor],",
78436
+ " ['GeneratorObjectPrototype', getPrototypeOf((function*() {})())],",
78437
+ " ['GeneratorObjectPrototypeParent', getPrototypeOf(getPrototypeOf((function*() {})()))],",
78438
+ " ['AsyncGeneratorObjectPrototype', getPrototypeOf((async function*() {})())],",
78439
+ " ['AsyncGeneratorObjectPrototypeParent', getPrototypeOf(getPrototypeOf((async function*() {})()))],",
78440
+ " ['ArrayIteratorPrototype', getPrototypeOf([][Symbol.iterator]())],",
78441
+ " ['IteratorPrototype', getPrototypeOf(getPrototypeOf([][Symbol.iterator]()))],",
78442
+ " ['StringIteratorPrototype', getPrototypeOf(''[Symbol.iterator]())],",
78443
+ " ['RegExpStringIteratorPrototype', getPrototypeOf(''.matchAll(/(?:)/g))],",
78444
+ " ['RegExpStringIteratorPrototypeParent', getPrototypeOf(getPrototypeOf(''.matchAll(/(?:)/g)))],",
78445
+ " ['MapIteratorPrototype', getPrototypeOf(new Map()[Symbol.iterator]())],",
78446
+ " ['SetIteratorPrototype', getPrototypeOf(new Set()[Symbol.iterator]())],",
78447
+ " ['TypedArrayConstructor', getPrototypeOf(Int8Array)],",
78448
+ " ['TypedArrayPrototype', getPrototypeOf(Int8Array.prototype)],",
78449
+ " ['AsyncFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(async function() {}))],",
78450
+ " ['GeneratorFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(function*() {}))],",
78451
+ " ['AsyncGeneratorFunctionPrototypeParent', getPrototypeOf(getPrototypeOf(async function*() {}))],",
78452
+ " ];",
78453
+ " const platformExtraSnapshot = Object.create(null);",
78454
+ " const platformExtraPrototypeSnapshot = Object.create(null);",
78455
+ " const platformExtraExtensibleSnapshot = Object.create(null);",
78456
+ " const platformGlobalNames = ownKeys(globalThis);",
78457
+ " for (const name of platformGlobalNames) {",
78458
+ " const record = {",
78459
+ " name,",
78460
+ " descriptor: Object.getOwnPropertyDescriptor(globalThis, name),",
78461
+ " value: globalThis[name],",
78462
+ " objectPrototype: undefined,",
78463
+ " properties: undefined,",
78464
+ " prototypeProperties: undefined,",
78465
+ " prototypeChain: undefined,",
78466
+ " extensible: undefined,",
78467
+ " prototypeExtensible: undefined,",
78468
+ " };",
78469
+ " const value = globalThis[name];",
78470
+ " if (value !== globalThis && ((typeof value === 'object' && value !== null) || typeof value === 'function')) {",
78471
+ " record.objectPrototype = getPrototypeOf(value);",
78472
+ " record.properties = getOwnPropertyDescriptors(value);",
78473
+ " record.extensible = isExtensible(value);",
78474
+ " const prototype = value.prototype;",
78475
+ " if ((typeof prototype === 'object' && prototype !== null) || typeof prototype === 'function') {",
78476
+ " record.prototypeChain = getPrototypeOf(prototype);",
78477
+ " record.prototypeProperties = getOwnPropertyDescriptors(prototype);",
78478
+ " record.prototypeExtensible = isExtensible(prototype);",
78479
+ " }",
78480
+ " }",
78481
+ " arrayPush(platformGlobals, record);",
78482
+ " }",
78483
+ " for (const [name, value] of platformExtraObjects) {",
78484
+ " if ((typeof value === 'object' && value !== null) || typeof value === 'function') {",
78485
+ " platformExtraSnapshot[name] = getOwnPropertyDescriptors(value);",
78486
+ " platformExtraPrototypeSnapshot[name] = getPrototypeOf(value);",
78487
+ " platformExtraExtensibleSnapshot[name] = isExtensible(value);",
78488
+ " }",
78489
+ " }",
78490
+ " const globalKeys = () => {",
78491
+ " const keys = ownKeys(globalThis);",
78492
+ " const tokens = [];",
78493
+ " for (let index = 0; index < keys.length; index += 1) {",
78494
+ " const key = keys[index];",
78495
+ " arrayPush(tokens, keyToken(key));",
78496
+ " }",
78497
+ " return tokens;",
78498
+ " };",
78499
+ " const restore = () => {",
78500
+ " if (getPrototypeOf(globalThis) !== globalPrototypeSnapshot) {",
78501
+ " try { setPrototypeOf(globalThis, globalPrototypeSnapshot); } catch { throw new Error('Code Mode global prototype chain is not restorable'); }",
78502
+ " }",
78503
+ " for (const record of platformGlobals) {",
78504
+ " const name = record.name;",
78505
+ " try {",
78506
+ " defineProperty(globalThis, name, record.descriptor);",
78507
+ " const descriptors = record.properties;",
78508
+ " const value = globalThis[name];",
78509
+ " if (descriptors && ((typeof value === 'object' && value !== null) || typeof value === 'function')) {",
78510
+ " if (record.extensible && !isExtensible(value)) throw new Error(`Code Mode platform global ${String(name)} is non-extensible`);",
78511
+ " if (getPrototypeOf(value) !== record.objectPrototype) {",
78512
+ " try { setPrototypeOf(value, record.objectPrototype); } catch { throw new Error(`Code Mode platform global ${String(name)} prototype chain is not restorable`); }",
78513
+ " }",
78514
+ " for (const key of ownKeys(value)) {",
78515
+ " if (!hasOwn(descriptors, key)) {",
78516
+ " try { delete value[key]; } catch {}",
78517
+ " if (hasOwn(value, key)) throw new Error(`Code Mode platform global ${String(name)} has non-restorable property ${String(key)}`);",
78518
+ " }",
78519
+ " }",
78520
+ " defineProperties(value, descriptors);",
78521
+ " const prototypeDescriptors = record.prototypeProperties;",
78522
+ " const prototype = value.prototype;",
78523
+ " if (prototypeDescriptors && ((typeof prototype === 'object' && prototype !== null) || typeof prototype === 'function')) {",
78524
+ " if (record.prototypeExtensible && !isExtensible(prototype)) throw new Error(`Code Mode platform prototype ${String(name)}.prototype is non-extensible`);",
78525
+ " if (getPrototypeOf(prototype) !== record.prototypeChain) {",
78526
+ " try { setPrototypeOf(prototype, record.prototypeChain); } catch { throw new Error(`Code Mode platform prototype ${String(name)}.prototype chain is not restorable`); }",
78527
+ " }",
78528
+ " for (const key of ownKeys(prototype)) {",
78529
+ " if (!hasOwn(prototypeDescriptors, key)) {",
78530
+ " try { delete prototype[key]; } catch {}",
78531
+ " if (hasOwn(prototype, key)) throw new Error(`Code Mode platform prototype ${String(name)}.prototype has non-restorable property ${String(key)}`);",
78532
+ " }",
78533
+ " }",
78534
+ " defineProperties(prototype, prototypeDescriptors);",
78535
+ " }",
78536
+ " }",
78537
+ " } catch (error) {",
78538
+ " throw new Error(`Code Mode platform global ${String(name)} is not restorable: ${String(error && error.message ? error.message : error)}`);",
78539
+ " }",
78540
+ " }",
78541
+ " for (const [name, value] of platformExtraObjects) {",
78542
+ " const descriptors = platformExtraSnapshot[name];",
78543
+ " if (!descriptors || !((typeof value === 'object' && value !== null) || typeof value === 'function')) continue;",
78544
+ " if (platformExtraExtensibleSnapshot[name] && !isExtensible(value)) throw new Error(`Code Mode platform intrinsic ${name} is non-extensible`);",
78545
+ " if (getPrototypeOf(value) !== platformExtraPrototypeSnapshot[name]) {",
78546
+ " try { setPrototypeOf(value, platformExtraPrototypeSnapshot[name]); } catch { throw new Error(`Code Mode platform intrinsic ${name} prototype chain is not restorable`); }",
78547
+ " }",
78548
+ " for (const key of ownKeys(value)) {",
78549
+ " if (!hasOwn(descriptors, key)) {",
78550
+ " try { delete value[key]; } catch {}",
78551
+ " if (hasOwn(value, key)) throw new Error(`Code Mode platform intrinsic ${name} has non-restorable property ${String(key)}`);",
78552
+ " }",
78553
+ " }",
78554
+ " defineProperties(value, descriptors);",
78555
+ " }",
78556
+ " };",
78557
+ " return { restore, globalKeys, isGlobalExtensible: () => isExtensible(globalThis) };",
78558
+ "})();",
78559
+ "Object.defineProperty(globalThis, '__caplets_restore_platform', { configurable: false, writable: false, value: __caplets_restore_platform.restore });",
78560
+ "Object.defineProperty(globalThis, '__caplets_global_keys', { configurable: false, writable: false, value: __caplets_restore_platform.globalKeys });",
78561
+ "Object.defineProperty(globalThis, '__caplets_is_global_extensible', { configurable: false, writable: false, value: __caplets_restore_platform.isGlobalExtensible });",
78562
+ "Object.defineProperty(globalThis, '__caplets_assert_active_id', { configurable: false, writable: false, value: (capletId) => {",
78563
+ " if (capletId === 'debug' && !__caplets_is_active_id(capletId)) return;",
78564
+ " if (!__caplets_is_active_id(capletId)) throw new Error(`Caplet ${capletId} is not available in this Code Mode session cell.`);",
78565
+ "} });",
78566
+ "Object.defineProperty(globalThis, '__caplets_handle', { configurable: false, writable: false, value: (capletId) => ({",
78567
+ " id: capletId,",
78568
+ " inspect: () => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'inspect', [])),",
78569
+ " check: () => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'check', [])),",
78570
+ " tools: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'tools', [input])),",
78571
+ " searchTools: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchTools', [query, input])),",
78572
+ " describeTool: (name) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'describeTool', [name])),",
78573
+ " callTool: (name, args) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'callTool', [name, args])),",
78574
+ " resources: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'resources', [input])),",
78575
+ " searchResources: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchResources', [query, input])),",
78576
+ " resourceTemplates: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'resourceTemplates', [input])),",
78577
+ " readResource: (uri) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'readResource', [uri])),",
78578
+ " prompts: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'prompts', [input])),",
78579
+ " searchPrompts: (query, input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'searchPrompts', [query, input])),",
78580
+ " getPrompt: (name, args) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'getPrompt', [name, args])),",
78581
+ " complete: (input) => (__caplets_assert_active_id(capletId), __caplets_invoke_json(capletId, 'complete', [input])),",
78582
+ "}) });",
78583
+ "(() => {",
78584
+ ` const checkpointToken = ${JSON.stringify(checkpointToken)};`,
78585
+ " const persistBacking = Object.create(null);",
78586
+ " let persistTainted = false;",
78587
+ " const checkpointState = { current: Object.create(null) };",
78588
+ " const ownKeys = Reflect.ownKeys.bind(Reflect);",
78589
+ " const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor.bind(Object);",
78590
+ " const defineProperty = Object.defineProperty.bind(Object);",
78591
+ " const getPrototypeOf = Object.getPrototypeOf.bind(Object);",
78592
+ " const reflectGet = Reflect.get.bind(Reflect);",
78593
+ " const reflectSet = Reflect.set.bind(Reflect);",
78594
+ " const reflectDefineProperty = Reflect.defineProperty.bind(Reflect);",
78595
+ " const reflectDeleteProperty = Reflect.deleteProperty.bind(Reflect);",
78596
+ " const reflectSetPrototypeOf = Reflect.setPrototypeOf.bind(Reflect);",
78597
+ " const reflectPreventExtensions = Reflect.preventExtensions.bind(Reflect);",
78598
+ " const reflectGetOwnPropertyDescriptor = Reflect.getOwnPropertyDescriptor.bind(Reflect);",
78599
+ " const reflectOwnKeys = Reflect.ownKeys.bind(Reflect);",
78600
+ " const hasOwn = Function.prototype.call.bind(Object.prototype.hasOwnProperty);",
78601
+ " const objectIds = new WeakMap();",
78602
+ " let nextObjectId = 1;",
78603
+ " const keyToken = (key) => typeof key === 'symbol' ? `symbol:${String(key)}` : `string:${key}`;",
78604
+ " const valueToken = (value) => {",
78605
+ " const type = typeof value;",
78606
+ " if ((type === 'object' && value !== null) || type === 'function') {",
78607
+ " if (!objectIds.has(value)) objectIds.set(value, nextObjectId++);",
78608
+ " return `${type}:${objectIds.get(value)}`;",
78609
+ " }",
78610
+ " return `${type}:${String(value)}`;",
78611
+ " };",
78612
+ " const descriptorToken = (descriptor) => {",
78613
+ " if (!descriptor) return 'missing';",
78614
+ " return [",
78615
+ " hasOwn(descriptor, 'value') ? 'data' : 'accessor',",
78616
+ " descriptor.writable === true ? 'w' : 'nw',",
78617
+ " descriptor.configurable === true ? 'c' : 'nc',",
78618
+ " descriptor.enumerable === true ? 'e' : 'ne',",
78619
+ " typeof descriptor.get,",
78620
+ " typeof descriptor.set,",
78621
+ " ].join(':');",
78622
+ " };",
78623
+ " const assertToken = (token) => {",
78624
+ " if (token !== checkpointToken) throw new Error('Code Mode persistence checkpoint token is invalid.');",
78625
+ " };",
78626
+ " const persistProxy = new Proxy(persistBacking, {",
78627
+ " get(target, key, receiver) { persistTainted = true; return reflectGet(target, key, receiver); },",
78628
+ " set(target, key, value, receiver) { persistTainted = true; return reflectSet(target, key, value, receiver); },",
78629
+ " defineProperty(target, key, descriptor) { persistTainted = true; return reflectDefineProperty(target, key, descriptor); },",
78630
+ " deleteProperty(target, key) { persistTainted = true; return reflectDeleteProperty(target, key); },",
78631
+ " setPrototypeOf(target, prototype) { persistTainted = true; return reflectSetPrototypeOf(target, prototype); },",
78632
+ " preventExtensions(target) { persistTainted = true; return reflectPreventExtensions(target); },",
78633
+ " getOwnPropertyDescriptor(target, key) { persistTainted = true; return reflectGetOwnPropertyDescriptor(target, key); },",
78634
+ " ownKeys(target) { persistTainted = true; return reflectOwnKeys(target); },",
78635
+ " getPrototypeOf(target) { persistTainted = true; return getPrototypeOf(target); },",
78636
+ " });",
78637
+ " Object.defineProperty(globalThis, '__caplets_persist', { configurable: false, writable: false, value: persistProxy });",
78638
+ " Object.defineProperty(globalThis, '__caplets_get_persist', { configurable: false, writable: false, value: (token, name) => {",
78639
+ " assertToken(token);",
78640
+ " return hasOwn(persistBacking, name) ? persistBacking[name] : undefined;",
78641
+ " } });",
78642
+ " Object.defineProperty(globalThis, '__caplets_set_persist', { configurable: false, writable: false, value: (token, name, value) => {",
78643
+ " assertToken(token);",
78644
+ " defineProperty(persistBacking, name, { value, writable: true, configurable: true, enumerable: true });",
78645
+ " return value;",
78646
+ " } });",
78647
+ " Object.defineProperty(globalThis, '__caplets_persist_is_tainted', { configurable: false, writable: false, value: (token) => {",
78648
+ " assertToken(token);",
78649
+ " return persistTainted;",
78650
+ " } });",
78651
+ " Object.defineProperty(globalThis, '__caplets_persist_has_object_like_values', { configurable: false, writable: false, value: (token, names) => {",
78652
+ " assertToken(token);",
78653
+ " for (const name of names) {",
78654
+ " if (!hasOwn(persistBacking, name)) continue;",
78655
+ " const value = persistBacking[name];",
78656
+ " if ((typeof value === 'object' && value !== null) || typeof value === 'function') return true;",
78657
+ " }",
78658
+ " return false;",
78659
+ " } });",
78660
+ " Object.defineProperty(globalThis, '__caplets_persist_global_descriptors_ok', { configurable: false, writable: false, value: (token, names) => {",
78661
+ " assertToken(token);",
78662
+ " for (const name of names) {",
78663
+ " const descriptor = getOwnPropertyDescriptor(globalThis, name);",
78664
+ " if (!descriptor || !hasOwn(descriptor, 'value') || descriptor.writable !== true) return false;",
78665
+ " }",
78666
+ " return true;",
78667
+ " } });",
78668
+ " Object.defineProperty(globalThis, '__caplets_persist_descriptor_fingerprint', { configurable: false, writable: false, value: (allowedNames = []) => {",
78669
+ " const allowed = new Set(allowedNames.map((name) => `string:${name}`));",
78670
+ " const prototype = getPrototypeOf(persistBacking);",
78671
+ " const keys = ownKeys(persistBacking).map((key) => keyToken(key)).filter((token) => !allowed.has(token)).sort();",
78672
+ " return keys.map((token) => {",
78673
+ " const key = token.startsWith('symbol:') ? ownKeys(persistBacking).find((candidate) => keyToken(candidate) === token) : token.slice('string:'.length);",
78674
+ " const descriptor = getOwnPropertyDescriptor(persistBacking, key);",
78675
+ " const value = descriptor && hasOwn(descriptor, 'value') ? valueToken(descriptor.value) : 'accessor';",
78676
+ " return `${token}:${descriptorToken(descriptor)}:${value}`;",
78677
+ " }).concat(`[[Prototype]]:${valueToken(prototype)}`).join('|');",
78678
+ " } });",
78679
+ " Object.defineProperty(globalThis, '__caplets_persist_descriptors_ok', { configurable: false, writable: false, value: (token, names) => {",
78680
+ " assertToken(token);",
78681
+ " if (getPrototypeOf(persistBacking) !== null) return false;",
78682
+ " for (const name of names) {",
78683
+ " const descriptor = getOwnPropertyDescriptor(persistBacking, name);",
78684
+ " if (!descriptor || !hasOwn(descriptor, 'value')) return false;",
78685
+ " if (descriptor.get || descriptor.set || descriptor.writable !== true || descriptor.configurable !== true) return false;",
78686
+ " }",
78687
+ " return true;",
78688
+ " } });",
78689
+ " Object.defineProperty(globalThis, '__caplets_snapshot_persist', { configurable: false, writable: false, value: (token, names) => {",
78690
+ " assertToken(token);",
78691
+ " const next = Object.create(null);",
78692
+ " for (const name of names) {",
78693
+ " try { next[name] = (0, eval)(name); }",
78694
+ " catch { next[name] = hasOwn(globalThis, name) ? globalThis[name] : hasOwn(persistBacking, name) ? persistBacking[name] : undefined; }",
78695
+ " }",
78696
+ " checkpointState.current = next;",
78697
+ " } });",
78698
+ " Object.defineProperty(globalThis, '__caplets_checkpoint_value', { configurable: false, writable: false, value: (token, name) => {",
78699
+ " assertToken(token);",
78700
+ " return checkpointState.current[name];",
78701
+ " } });",
78702
+ "})();",
78703
+ "Object.defineProperty(globalThis, '__caplets_json_parse', { configurable: false, writable: false, value: JSON.parse.bind(JSON) });"
78704
+ ].join("\n");
78705
+ }
78706
+ function buildBridgeRefreshSource(_capletIds, _previousCapletIds = []) {
78707
+ return "";
78708
+ }
78709
+ function buildSessionCellSource(code, capletIds, existingNames = [], checkpointToken = "") {
78710
+ const javascript = ts.transpileModule(code, { compilerOptions: {
78711
+ target: ts.ScriptTarget.ES2022,
78712
+ module: ts.ModuleKind.ESNext,
78713
+ importsNotUsedAsValues: ts.ImportsNotUsedAsValues.Remove
78714
+ } }).outputText;
78715
+ const split = splitPersistentPrelude(javascript, existingNames, checkpointToken);
78716
+ return {
78717
+ source: [
78718
+ split.prelude,
78719
+ "(async () => {",
78720
+ "\"use strict\";",
78721
+ buildPlatformResetSource(),
78722
+ buildPlatformShadowRestoreSource(existingNames, checkpointToken),
78723
+ buildCellCapletsSource(capletIds),
78724
+ split.body,
78725
+ split.postlude,
78726
+ "})()"
78727
+ ].join("\n"),
78728
+ persistentNames: split.persistentNames,
78729
+ newNames: split.newNames,
78730
+ snapshotNames: split.snapshotNames
78731
+ };
78732
+ }
78733
+ function buildPlatformResetSource() {
78734
+ return "globalThis.__caplets_restore_platform();";
78735
+ }
78736
+ function buildPlatformShadowRestoreSource(existingNames, checkpointToken) {
78737
+ return existingNames.map((name) => `(0, eval)(${JSON.stringify(`${name} = globalThis.__caplets_get_persist(${JSON.stringify(checkpointToken)}, ${JSON.stringify(name)});`)});`).join("\n");
78738
+ }
78739
+ function buildCellCapletsSource(capletIds) {
78740
+ return [
78741
+ "const caplets = {};",
78742
+ ...capletIds.map((capletId) => `caplets[${JSON.stringify(capletId)}] = __caplets_handle(${JSON.stringify(capletId)});`),
78743
+ "caplets.debug = caplets.debug ?? {};",
78744
+ "caplets.debug.readLogs = (input) => __caplets_invoke_json('debug', 'readLogs', [input]);",
78745
+ "caplets.debug.readRecovery = (input) => __caplets_invoke_json('debug', 'readRecovery', [input]);"
78746
+ ].join("\n");
78747
+ }
78748
+ function splitPersistentPrelude(javascript, existingNames = [], checkpointToken = "") {
78749
+ const source = ts.createSourceFile("/caplets-code-mode/session-cell.js", javascript, ts.ScriptTarget.ES2022, true);
78750
+ const ranges = [];
78751
+ const names = collectPersistentBindingNames(source);
78752
+ const lexicalNames = collectTopLevelLexicalBindingNames(source);
78753
+ const allNames = [...new Set([...existingNames, ...names])];
78754
+ const snapshotNames = allNames.filter((name) => !lexicalNames.has(name));
78755
+ const returnTempName = uniqueInternalName("__caplets_return", allNames);
78756
+ const postlude = snapshotNames.map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
78757
+ for (const statement of source.statements) {
78758
+ collectPersistentVarRewriteRanges(statement, source, lexicalNames, ranges);
78759
+ collectPersistentReturnRanges(statement, source, snapshotNames, ranges, returnTempName, checkpointToken);
78760
+ collectPersistentFinallyRanges(statement, snapshotNames, ranges, checkpointToken);
78761
+ }
78762
+ ranges.sort((left, right) => left.start - right.start);
78763
+ 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");
78764
+ let body = "";
78765
+ let cursor = 0;
78766
+ for (const range of ranges) {
78767
+ body += javascript.slice(cursor, range.start);
78768
+ body += range.body;
78769
+ cursor = range.end;
78770
+ }
78771
+ body += javascript.slice(cursor);
78772
+ if (postlude) body += `\n${postlude}`;
78773
+ return {
78774
+ prelude,
78775
+ body,
78776
+ postlude,
78777
+ persistentNames: allNames,
78778
+ newNames: names.filter((name) => !existingNames.includes(name)),
78779
+ snapshotNames
78780
+ };
78781
+ }
78782
+ function collectPersistentReturnRanges(node, source, snapshotNames, ranges, returnTempName, checkpointToken, shadowedNames = /* @__PURE__ */ new Set()) {
78783
+ if (snapshotNames.length === 0) return;
78784
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78785
+ const declared = lexicalNamesDeclaredByNode(node);
78786
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
78787
+ if (ts.isReturnStatement(node)) {
78788
+ const expression = node.expression?.getText(source);
78789
+ const postludeExpression = snapshotNames.filter((name) => !activeShadowedNames.has(name)).map((name) => persistentBindingExpression(name, checkpointToken)).join(", ");
78790
+ ranges.push({
78791
+ start: node.getFullStart(),
78792
+ end: node.end,
78793
+ prelude: "",
78794
+ body: returnWithPersistenceExpression(expression, postludeExpression, returnTempName)
78795
+ });
78796
+ return;
78797
+ }
78798
+ ts.forEachChild(node, (child) => collectPersistentReturnRanges(child, source, snapshotNames, ranges, returnTempName, checkpointToken, activeShadowedNames));
78799
+ }
78800
+ function lexicalNamesDeclaredByNode(node) {
78801
+ const names = /* @__PURE__ */ new Set();
78802
+ if (ts.isBlock(node) || ts.isCaseClause(node) || ts.isDefaultClause(node)) for (const statement of node.statements) {
78803
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78804
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78805
+ if (ts.isFunctionDeclaration(statement) && statement.name) names.add(statement.name.text);
78806
+ }
78807
+ if (ts.isSwitchStatement(node)) for (const clause of node.caseBlock.clauses) for (const statement of clause.statements) {
78808
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78809
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78810
+ if (ts.isFunctionDeclaration(statement) && statement.name) names.add(statement.name.text);
78811
+ }
78812
+ if (ts.isCatchClause(node) && node.variableDeclaration) for (const name of bindingNames(node.variableDeclaration.name)) names.add(name);
78813
+ 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);
78814
+ return names;
78815
+ }
78816
+ function returnWithPersistenceExpression(expression, postludeExpression, returnTempName) {
78817
+ if (!postludeExpression) return expression ? `return ${expression};` : "return;";
78818
+ return expression ? `return (async (${returnTempName}) => { await Promise.resolve(); ${postludeExpression}; return ${returnTempName}; })((${expression}));` : `await Promise.resolve();\nreturn void (${postludeExpression});`;
78819
+ }
78820
+ function uniqueInternalName(baseName, unavailableNames) {
78821
+ const unavailable = new Set(unavailableNames);
78822
+ let name = baseName;
78823
+ while (unavailable.has(name)) name = `_${name}`;
78824
+ return name;
78825
+ }
78826
+ function collectPersistentVarRewriteRanges(node, source, lexicalNames, ranges) {
78827
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78828
+ if (ts.isVariableStatement(node) && isVarDeclarationList(node.declarationList)) {
78829
+ if (!declarationListBindingNames(node.declarationList).some((name) => lexicalNames.has(name))) ranges.push({
78830
+ start: node.getFullStart(),
78831
+ end: node.end,
78832
+ prelude: "",
78833
+ body: varStatementAssignments(node.declarationList, source)
78834
+ });
78835
+ return;
78836
+ }
78837
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer) && isVarDeclarationList(node.initializer)) {
78838
+ if (!declarationListBindingNames(node.initializer).some((name) => lexicalNames.has(name))) ranges.push({
78839
+ start: node.initializer.getStart(source),
78840
+ end: node.initializer.end,
78841
+ prelude: "",
78842
+ body: forInitializerAssignment(node.initializer, source)
78843
+ });
78844
+ }
78845
+ ts.forEachChild(node, (child) => collectPersistentVarRewriteRanges(child, source, lexicalNames, ranges));
78846
+ }
78847
+ function collectPersistentFinallyRanges(node, snapshotNames, ranges, checkpointToken, shadowedNames = /* @__PURE__ */ new Set()) {
78848
+ if (snapshotNames.length === 0) return;
78849
+ if (ts.isFunctionLike(node) || ts.isClassLike(node)) return;
78850
+ const declared = lexicalNamesDeclaredByNode(node);
78851
+ const activeShadowedNames = declared.size === 0 ? shadowedNames : new Set([...shadowedNames, ...declared]);
78852
+ if (ts.isTryStatement(node) && node.finallyBlock) {
78853
+ const finallyDeclared = lexicalNamesDeclaredByNode(node.finallyBlock);
78854
+ const finallyShadowedNames = finallyDeclared.size === 0 ? activeShadowedNames : new Set([...activeShadowedNames, ...finallyDeclared]);
78855
+ const postlude = snapshotNames.filter((name) => !finallyShadowedNames.has(name)).map((name) => persistentBindingPostlude(name, checkpointToken)).join("\n");
78856
+ if (postlude) ranges.push({
78857
+ start: node.finallyBlock.end - 1,
78858
+ end: node.finallyBlock.end - 1,
78859
+ prelude: "",
78860
+ body: `\n${postlude}\n`
78861
+ });
78862
+ }
78863
+ ts.forEachChild(node, (child) => collectPersistentFinallyRanges(child, snapshotNames, ranges, checkpointToken, activeShadowedNames));
78864
+ }
78865
+ function collectPersistentBindingNames(source) {
78866
+ const names = /* @__PURE__ */ new Set();
78867
+ const visit = (node) => {
78868
+ if (ts.isFunctionDeclaration(node) && node.name && node.parent === source) names.add(node.name.text);
78869
+ if (node !== source && (ts.isFunctionLike(node) || ts.isClassLike(node))) return;
78870
+ if (ts.isVariableStatement(node)) collectVarDeclarationListNames(node.declarationList, names);
78871
+ if ((ts.isForStatement(node) || ts.isForInStatement(node) || ts.isForOfStatement(node)) && node.initializer && ts.isVariableDeclarationList(node.initializer)) collectVarDeclarationListNames(node.initializer, names);
78872
+ ts.forEachChild(node, visit);
78873
+ };
78874
+ visit(source);
78875
+ return [...names];
78876
+ }
78877
+ function collectTopLevelLexicalBindingNames(source) {
78878
+ const names = /* @__PURE__ */ new Set();
78879
+ for (const statement of source.statements) {
78880
+ if (ts.isVariableStatement(statement) && !isVarDeclarationList(statement.declarationList)) for (const name of declarationListBindingNames(statement.declarationList)) names.add(name);
78881
+ if ((ts.isClassDeclaration(statement) || ts.isEnumDeclaration(statement)) && statement.name) names.add(statement.name.text);
78882
+ }
78883
+ return names;
78884
+ }
78885
+ function collectVarDeclarationListNames(declarationList, names) {
78886
+ if (!((ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0)) return;
78887
+ for (const declaration of declarationList.declarations) for (const name of bindingNames(declaration.name)) names.add(name);
78888
+ }
78889
+ function isVarDeclarationList(declarationList) {
78890
+ return (ts.getCombinedNodeFlags(declarationList) & ts.NodeFlags.BlockScoped) === 0;
78891
+ }
78892
+ function declarationListBindingNames(declarationList) {
78893
+ return declarationList.declarations.flatMap((declaration) => bindingNames(declaration.name));
78894
+ }
78895
+ function varStatementAssignments(declarationList, source) {
78896
+ return declarationList.declarations.map((declaration) => declaration.initializer ? assignmentStatement(declaration.name, declaration.initializer, source) : "").filter(Boolean).join("\n");
78897
+ }
78898
+ function forInitializerAssignment(declarationList, source) {
78899
+ return declarationList.declarations.map((declaration) => declaration.initializer ? assignmentExpression(declaration.name, declaration.initializer, source) : declaration.name.getText(source)).join(", ");
78900
+ }
78901
+ function persistentBindingPostlude(name, checkpointToken) {
78902
+ 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");
78903
+ }
78904
+ function persistentBindingExpression(name, checkpointToken) {
78905
+ 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(", ");
78906
+ }
78907
+ function bindingNames(name) {
78908
+ if (ts.isIdentifier(name)) return [name.text];
78909
+ return name.elements.flatMap((element) => {
78910
+ if (ts.isOmittedExpression(element)) return [];
78911
+ return bindingNames(element.name);
78912
+ });
78913
+ }
78914
+ function assignmentStatement(name, initializer, source) {
78915
+ const expression = assignmentExpression(name, initializer, source);
78916
+ return ts.isObjectBindingPattern(name) ? `(${expression});` : `${expression};`;
78917
+ }
78918
+ function assignmentExpression(name, initializer, source) {
78919
+ return `${name.getText(source)} = ${initializer.getText(source)}`;
78920
+ }
78921
+ function buildPromiseObserverSource() {
78922
+ return [
78923
+ "(() => {",
78924
+ " const then = Promise.prototype.then;",
78925
+ " const formatError = function(e) {",
78926
+ " if (e && typeof e === 'object' && typeof e.message === 'string') return e.message;",
78927
+ " return String(e);",
78928
+ " };",
78929
+ " try { Object.defineProperty(globalThis, '__caplets_observe_promise', { configurable: false, writable: false, value: function(p) {",
78930
+ " var s = { settled: false, value: void 0, error: void 0 };",
78931
+ " then.call(p, function(value) { s.value = value; s.settled = true; },",
78932
+ " function(error) { s.error = formatError(error); s.settled = true; });",
78933
+ " return s;",
78934
+ " } }); } catch {}",
78935
+ "})()"
78936
+ ].join("\n");
78937
+ }
78938
+ function buildPromiseStateSource(resultName) {
78939
+ return [`globalThis.__caplets_observe_promise(globalThis[${resultName}])`].join("\n");
78940
+ }
77370
78941
  async function drainAsync(context, runtime, pendingDeferreds, deadlineMs, timeoutMs) {
77371
78942
  drainJobs(context, runtime, deadlineMs, timeoutMs);
77372
78943
  while (pendingDeferreds.size > 0) {
@@ -77409,6 +78980,9 @@ function readProp(context, handle, key) {
77409
78980
  function timeoutMessage(timeoutMs) {
77410
78981
  return `Code Mode execution timed out after ${timeoutMs}ms`;
77411
78982
  }
78983
+ function isTimeoutMessage(message, timeoutMs) {
78984
+ return message === timeoutMessage(timeoutMs);
78985
+ }
77412
78986
  function normalizeError(error, deadlineMs, timeoutMs) {
77413
78987
  const message = errorMessage$2(error);
77414
78988
  return Date.now() >= deadlineMs && /\binterrupted\b/iu.test(message) ? timeoutMessage(timeoutMs) : message;
@@ -77431,6 +79005,181 @@ function optionalStack(stack) {
77431
79005
  function logLevel(value) {
77432
79006
  return value === "info" || value === "warn" || value === "error" || value === "debug" || value === "log" ? value : "log";
77433
79007
  }
79008
+ var CodeModeSessionManager = class {
79009
+ ttlMs;
79010
+ maxSessions;
79011
+ #sessions = /* @__PURE__ */ new Map();
79012
+ #idGenerator;
79013
+ #now;
79014
+ #sandboxFactory;
79015
+ #closed = false;
79016
+ constructor(options = {}) {
79017
+ this.ttlMs = options.ttlMs ?? 18e5;
79018
+ this.maxSessions = options.maxSessions ?? 32;
79019
+ this.#idGenerator = options.idGenerator ?? randomUUID;
79020
+ this.#now = options.now ?? Date.now;
79021
+ this.#sandboxFactory = options.sandboxFactory ?? (() => new QuickJsCodeModeSandbox());
79022
+ }
79023
+ async run(input) {
79024
+ if (this.#closed) return {
79025
+ ok: false,
79026
+ sessionId: input.sessionId ?? "",
79027
+ sessionStatus: null,
79028
+ error: "closed"
79029
+ };
79030
+ this.#evictExpired();
79031
+ const compatibilityKey = compatibilityKeyFor(input.compatibility);
79032
+ const requestedSessionId = input.sessionId;
79033
+ let record;
79034
+ let sessionStatus;
79035
+ if (requestedSessionId) {
79036
+ record = this.#sessions.get(requestedSessionId);
79037
+ if (!record) return {
79038
+ ok: false,
79039
+ sessionId: requestedSessionId,
79040
+ sessionStatus: null,
79041
+ error: "not_found"
79042
+ };
79043
+ if (record.busy) return {
79044
+ ok: false,
79045
+ sessionId: requestedSessionId,
79046
+ sessionStatus: null,
79047
+ error: "busy"
79048
+ };
79049
+ if (record.compatibilityKey !== compatibilityKey) {
79050
+ this.#disposeRecord(record.id);
79051
+ return {
79052
+ ok: false,
79053
+ sessionId: requestedSessionId,
79054
+ sessionStatus: null,
79055
+ error: "not_found"
79056
+ };
79057
+ } else sessionStatus = "reused";
79058
+ } else {
79059
+ const sessionId = this.#nextSessionId();
79060
+ record = await this.#createRecord(sessionId, compatibilityKey);
79061
+ if (!record) return this.#closedResult(sessionId);
79062
+ sessionStatus = "created";
79063
+ }
79064
+ this.#evictToLimit(record.id);
79065
+ record.busy = true;
79066
+ try {
79067
+ const result = await record.session.run({
79068
+ ...input,
79069
+ invoke: async (invokeInput) => {
79070
+ if (this.#closed) throw new Error("Code Mode session manager is closed.");
79071
+ return await input.invoke(invokeInput);
79072
+ }
79073
+ });
79074
+ record.lastUsedAt = this.#now();
79075
+ const sessionDisposedAfterRun = record.session.isDisposed();
79076
+ if (sessionDisposedAfterRun) this.#sessions.delete(record.id);
79077
+ else if (result.ok) input.onSuccessfulCell?.(record.id, input.code);
79078
+ return {
79079
+ ok: true,
79080
+ sessionId: record.id,
79081
+ sessionStatus,
79082
+ sessionDisposedAfterRun,
79083
+ compatibilityKey: record.compatibilityKey,
79084
+ result
79085
+ };
79086
+ } finally {
79087
+ record.busy = false;
79088
+ this.#evictToLimit(record.id);
79089
+ }
79090
+ }
79091
+ close() {
79092
+ this.#closed = true;
79093
+ for (const record of this.#sessions.values()) record.session.dispose();
79094
+ this.#sessions.clear();
79095
+ }
79096
+ has(sessionId) {
79097
+ this.#evictExpired();
79098
+ return this.#sessions.has(sessionId);
79099
+ }
79100
+ compatibilityKey(sessionId) {
79101
+ this.#evictExpired();
79102
+ return this.#sessions.get(sessionId)?.compatibilityKey;
79103
+ }
79104
+ diagnosticsSession(sessionId, compatibility) {
79105
+ this.#evictExpired();
79106
+ const record = this.#sessions.get(sessionId);
79107
+ if (!record) return void 0;
79108
+ const compatibilityKey = compatibilityKeyFor(compatibility);
79109
+ if (record.compatibilityKey !== compatibilityKey) {
79110
+ this.#disposeRecord(sessionId);
79111
+ return;
79112
+ }
79113
+ return record.diagnosticsSession;
79114
+ }
79115
+ isBusy(sessionId, compatibility) {
79116
+ this.#evictExpired();
79117
+ const record = this.#sessions.get(sessionId);
79118
+ if (!record) return false;
79119
+ const compatibilityKey = compatibilityKeyFor(compatibility);
79120
+ if (record.compatibilityKey !== compatibilityKey) return false;
79121
+ return record.busy;
79122
+ }
79123
+ recordSuccessfulCell(sessionId, code, declaration = "") {
79124
+ this.#sessions.get(sessionId)?.diagnosticsSession.recordSuccessfulCell(code, declaration);
79125
+ }
79126
+ async #createRecord(id, compatibilityKey) {
79127
+ if (this.#closed) return;
79128
+ const session = await this.#sandboxFactory().createSession();
79129
+ if (this.#closed) {
79130
+ session.dispose();
79131
+ return;
79132
+ }
79133
+ const record = {
79134
+ id,
79135
+ session,
79136
+ diagnosticsSession: new CodeModeDiagnosticsSession(),
79137
+ compatibilityKey,
79138
+ lastUsedAt: this.#now(),
79139
+ busy: false
79140
+ };
79141
+ this.#sessions.set(id, record);
79142
+ return record;
79143
+ }
79144
+ #nextSessionId() {
79145
+ let id = this.#idGenerator();
79146
+ while (this.#sessions.has(id)) id = this.#idGenerator();
79147
+ return id;
79148
+ }
79149
+ #evictExpired() {
79150
+ const now = this.#now();
79151
+ for (const record of this.#sessions.values()) if (!record.busy && now - record.lastUsedAt > this.ttlMs) this.#disposeRecord(record.id);
79152
+ }
79153
+ #evictToLimit(protectedId) {
79154
+ while (this.#sessions.size > this.maxSessions) {
79155
+ const candidate = [...this.#sessions.values()].filter((record) => !record.busy && record.id !== protectedId).sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0];
79156
+ if (!candidate) return;
79157
+ this.#disposeRecord(candidate.id);
79158
+ }
79159
+ }
79160
+ #disposeRecord(id) {
79161
+ const record = this.#sessions.get(id);
79162
+ if (!record) return;
79163
+ record.session.dispose();
79164
+ this.#sessions.delete(id);
79165
+ }
79166
+ #closedResult(sessionId) {
79167
+ return {
79168
+ ok: false,
79169
+ sessionId,
79170
+ sessionStatus: null,
79171
+ error: "closed"
79172
+ };
79173
+ }
79174
+ };
79175
+ function compatibilityKeyFor(input) {
79176
+ return JSON.stringify({
79177
+ declarationHash: input.declarationHash,
79178
+ platformRuntimeHash: input.platformRuntimeHash,
79179
+ runtimeScope: input.runtimeScope,
79180
+ version: input.version ?? 1
79181
+ });
79182
+ }
77434
79183
  //#endregion
77435
79184
  //#region src/code-mode/runner.ts
77436
79185
  const DEFAULT_TIMEOUT_MS = 1e4;
@@ -77443,45 +79192,126 @@ async function runCodeMode(input) {
77443
79192
  const callable = listCodeModeCallableCaplets(input.service);
77444
79193
  const declaration = generateCodeModeDeclarations({ caplets: callable });
77445
79194
  const declarationHash = codeModeDeclarationHash(declaration);
79195
+ const sessionCompatibility = {
79196
+ declarationHash,
79197
+ platformRuntimeHash: codeModeDeclarationHash(CODE_MODE_PLATFORM_RUNTIME_SOURCE),
79198
+ runtimeScope: input.runtimeScope ?? "",
79199
+ version: 1
79200
+ };
79201
+ const diagnosticsSession = input.sessionManager && input.sessionId ? input.sessionManager.diagnosticsSession(input.sessionId, sessionCompatibility) : void 0;
77446
79202
  const metaBase = {
77447
79203
  runId: randomUUID(),
77448
79204
  traceId: randomUUID(),
77449
79205
  declarationHash,
77450
79206
  timeoutMs,
77451
- maxTimeoutMs
79207
+ maxTimeoutMs,
79208
+ sessionId: input.sessionManager ? null : input.sessionId ?? null,
79209
+ sessionStatus: null,
79210
+ recoveryRef: null
77452
79211
  };
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
79212
+ const meta = () => ({
79213
+ ...metaBase,
79214
+ durationMs: Date.now() - startedAt
77460
79215
  });
77461
- if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) return {
79216
+ if (input.sessionId !== void 0 && !input.sessionManager) return {
77462
79217
  ok: false,
77463
79218
  error: {
77464
- code: "diagnostic_blocked",
77465
- message: "Code Mode diagnostics failed before execution."
79219
+ code: "SESSION_NOT_FOUND",
79220
+ message: "Code Mode session reuse is not available in this runtime. Omit sessionId to run one-shot."
77466
79221
  },
77467
- diagnostics,
79222
+ diagnostics: [],
79223
+ logs: emptyLogs(),
79224
+ meta: meta()
79225
+ };
79226
+ if (input.sessionManager && input.sessionId && input.sessionManager.isBusy(input.sessionId, sessionCompatibility)) return {
79227
+ ok: false,
79228
+ error: {
79229
+ code: "SESSION_BUSY",
79230
+ message: `Code Mode session ${input.sessionId} is already running.`
79231
+ },
79232
+ diagnostics: [],
77468
79233
  logs: emptyLogs(),
77469
79234
  meta: {
77470
- ...metaBase,
77471
- durationMs: Date.now() - startedAt
79235
+ ...meta(),
79236
+ sessionId: input.sessionId,
79237
+ sessionStatus: null
77472
79238
  }
77473
79239
  };
79240
+ const diagnostics = timeoutMs > maxTimeoutMs ? [{
79241
+ code: "TIMEOUT_POLICY_EXCEEDED",
79242
+ severity: "error",
79243
+ message: `timeoutMs must be <= ${maxTimeoutMs}.`
79244
+ }] : diagnoseCodeModeTypeScript({
79245
+ code: input.code,
79246
+ declaration,
79247
+ ...diagnosticsSession === void 0 ? {} : { session: diagnosticsSession }
79248
+ });
79249
+ if (diagnostics.some((diagnostic) => diagnostic.severity === "error")) {
79250
+ const diagnosticJournalScope = input.sessionManager && input.sessionId ? input.sessionManager.compatibilityKey(input.sessionId) : void 0;
79251
+ if (input.sessionManager && input.sessionId && diagnosticJournalScope === void 0) {
79252
+ const recoveryRef = await recoveryRefForSession(input, input.sessionId);
79253
+ return {
79254
+ ok: false,
79255
+ error: {
79256
+ code: "SESSION_NOT_FOUND",
79257
+ message: `Code Mode session ${input.sessionId} was not found.`
79258
+ },
79259
+ diagnostics,
79260
+ logs: emptyLogs(),
79261
+ meta: {
79262
+ ...meta(),
79263
+ sessionId: input.sessionId,
79264
+ sessionStatus: null,
79265
+ ...recoveryMeta(recoveryRef)
79266
+ }
79267
+ };
79268
+ }
79269
+ const recoveryRef = await journalRun(input, {
79270
+ sessionId: input.sessionId ?? null,
79271
+ code: input.code,
79272
+ declarationHash,
79273
+ diagnostics,
79274
+ logs: emptyLogs(),
79275
+ outcome: {
79276
+ ok: false,
79277
+ code: "diagnostic_blocked",
79278
+ message: "Code Mode diagnostics failed before execution."
79279
+ },
79280
+ invokedCaplet: false,
79281
+ sessionDisposedAfterRun: false,
79282
+ journalScope: diagnosticJournalScope
79283
+ });
79284
+ if (input.sessionManager && input.sessionId) {
79285
+ metaBase.sessionId = input.sessionId;
79286
+ metaBase.sessionStatus = "reused";
79287
+ }
79288
+ if (recoveryRef && !input.sessionManager) setRecoveryMeta(metaBase, recoveryRef);
79289
+ return {
79290
+ ok: false,
79291
+ error: {
79292
+ code: "diagnostic_blocked",
79293
+ message: "Code Mode diagnostics failed before execution."
79294
+ },
79295
+ diagnostics,
79296
+ logs: emptyLogs(),
79297
+ meta: meta()
79298
+ };
79299
+ }
77474
79300
  const capturedLogs = [];
79301
+ let invokedCaplet = false;
77475
79302
  const api = createCodeModeCapletsApi({
77476
79303
  service: input.service,
77477
- readLogs: async (readInput) => input.logStore?.read(readInput) ?? { entries: [] }
79304
+ readLogs: async (readInput) => input.logStore?.read(readInput) ?? { entries: [] },
79305
+ readRecovery: async (readInput) => input.journalStore?.readRecovery(readInput) ?? { entries: [] }
77478
79306
  });
77479
- const result = await (input.sandbox ?? new QuickJsCodeModeSandbox()).run({
79307
+ const sandboxInput = {
77480
79308
  code: input.code,
77481
79309
  capletIds: callable.map((caplet) => caplet.id),
77482
79310
  timeoutMs,
77483
79311
  invoke: async ({ capletId, method, args }) => {
77484
79312
  if (method === "readLogs") return await api.debug.readLogs(args[0]);
79313
+ if (method === "readRecovery") return await api.debug.readRecovery(args[0]);
79314
+ invokedCaplet = true;
77485
79315
  const handle = api[capletId];
77486
79316
  if (!handle || !("callTool" in handle)) throw new Error(`Caplet ${capletId} is not available.`);
77487
79317
  if (method === "inspect") return await handle.inspect();
@@ -77500,19 +79330,66 @@ async function runCodeMode(input) {
77500
79330
  if (method === "complete") return await handle.complete(args[0]);
77501
79331
  throw new Error(`Unknown Code Mode CapletHandle method: ${method}.`);
77502
79332
  }
77503
- });
79333
+ };
79334
+ const sessionRun = input.sessionManager ? await input.sessionManager.run({
79335
+ ...sandboxInput,
79336
+ ...input.sessionId === void 0 ? {} : { sessionId: input.sessionId },
79337
+ compatibility: sessionCompatibility,
79338
+ onSuccessfulCell: (sessionId, code) => {
79339
+ input.sessionManager?.recordSuccessfulCell(sessionId, code, declaration);
79340
+ }
79341
+ }) : void 0;
79342
+ if (sessionRun && !sessionRun.ok) {
79343
+ const recoveryRef = sessionRun.error === "not_found" ? await recoveryRefForSession(input, sessionRun.sessionId) : void 0;
79344
+ return {
79345
+ ok: false,
79346
+ error: {
79347
+ code: sessionRun.error === "not_found" ? "SESSION_NOT_FOUND" : sessionRun.error === "closed" ? "SESSION_CLOSED" : "SESSION_BUSY",
79348
+ 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.`
79349
+ },
79350
+ diagnostics,
79351
+ logs: emptyLogs(),
79352
+ meta: {
79353
+ ...meta(),
79354
+ sessionId: sessionRun.sessionId,
79355
+ sessionStatus: null,
79356
+ ...recoveryMeta(recoveryRef)
79357
+ }
79358
+ };
79359
+ }
79360
+ const result = sessionRun?.result ?? await (input.sandbox ?? new QuickJsCodeModeSandbox()).run(sandboxInput);
79361
+ const sessionId = sessionRun?.sessionId ?? metaBase.sessionId ?? null;
79362
+ const sessionStatus = sessionRun?.sessionStatus ?? metaBase.sessionStatus ?? null;
79363
+ const exposeRecoveryRef = !input.sessionManager || sessionStatus === "created";
79364
+ metaBase.sessionId = sessionRun?.sessionDisposedAfterRun ? null : sessionId;
79365
+ metaBase.sessionStatus = sessionRun?.sessionDisposedAfterRun ? null : sessionStatus;
77504
79366
  capturedLogs.push(...result.logs.map(redactLogEntry));
77505
79367
  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
- };
79368
+ if (!result.ok) {
79369
+ const recoveryRef = await journalRun(input, {
79370
+ sessionId,
79371
+ code: input.code,
79372
+ declarationHash,
79373
+ diagnostics,
79374
+ logs,
79375
+ outcome: {
79376
+ ok: false,
79377
+ code: runtimeErrorCode(result.error),
79378
+ message: result.error
79379
+ },
79380
+ invokedCaplet,
79381
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79382
+ journalScope: sessionRun?.compatibilityKey
79383
+ });
79384
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
79385
+ return {
79386
+ ok: false,
79387
+ error: codeModeRuntimeError(result.error, result.stack),
79388
+ diagnostics,
79389
+ logs,
79390
+ meta: meta()
79391
+ };
79392
+ }
77516
79393
  const serialized = serializeJsonValue(result.value);
77517
79394
  if (!serialized.ok) {
77518
79395
  const serializationDiagnostic = {
@@ -77520,6 +79397,22 @@ async function runCodeMode(input) {
77520
79397
  severity: "error",
77521
79398
  message: serialized.message
77522
79399
  };
79400
+ const recoveryRef = await journalRun(input, {
79401
+ sessionId,
79402
+ code: input.code,
79403
+ declarationHash,
79404
+ diagnostics: [...diagnostics, serializationDiagnostic],
79405
+ logs,
79406
+ outcome: {
79407
+ ok: false,
79408
+ code: "SERIALIZATION_ERROR",
79409
+ message: serialized.message
79410
+ },
79411
+ invokedCaplet,
79412
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79413
+ journalScope: sessionRun?.compatibilityKey
79414
+ });
79415
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
77523
79416
  return {
77524
79417
  ok: false,
77525
79418
  error: {
@@ -77528,23 +79421,60 @@ async function runCodeMode(input) {
77528
79421
  },
77529
79422
  diagnostics: [...diagnostics, serializationDiagnostic],
77530
79423
  logs,
77531
- meta: {
77532
- ...metaBase,
77533
- durationMs: Date.now() - startedAt
77534
- }
79424
+ meta: meta()
77535
79425
  };
77536
79426
  }
79427
+ const recoveryRef = await journalRun(input, {
79428
+ sessionId,
79429
+ code: input.code,
79430
+ declarationHash,
79431
+ diagnostics,
79432
+ logs,
79433
+ outcome: { ok: true },
79434
+ invokedCaplet,
79435
+ sessionDisposedAfterRun: sessionRun?.sessionDisposedAfterRun ?? false,
79436
+ journalScope: sessionRun?.compatibilityKey
79437
+ });
79438
+ if (recoveryRef && exposeRecoveryRef) setRecoveryMeta(metaBase, recoveryRef);
77537
79439
  return {
77538
79440
  ok: true,
77539
79441
  value: serialized.value,
77540
79442
  diagnostics,
77541
79443
  logs,
77542
- meta: {
77543
- ...metaBase,
77544
- durationMs: Date.now() - startedAt
77545
- }
79444
+ meta: meta()
77546
79445
  };
77547
79446
  }
79447
+ async function journalRun(input, run) {
79448
+ if (!input.journalStore || !run.sessionId) return void 0;
79449
+ try {
79450
+ return (await input.journalStore.store({
79451
+ sessionId: run.sessionId,
79452
+ ...run.journalScope === void 0 ? {} : { journalScope: run.journalScope },
79453
+ code: run.code,
79454
+ declarationHash: run.declarationHash,
79455
+ outcome: run.outcome,
79456
+ diagnostics: run.diagnostics,
79457
+ recoveryClassification: classifyCodeModeRecovery({
79458
+ code: run.code,
79459
+ invokedCaplet: run.invokedCaplet,
79460
+ sessionDisposedAfterRun: run.sessionDisposedAfterRun
79461
+ }),
79462
+ ...run.logs.logRef ? { logRef: run.logs.logRef } : {}
79463
+ })).recoveryRef;
79464
+ } catch {
79465
+ return;
79466
+ }
79467
+ }
79468
+ function setRecoveryMeta(metaBase, recoveryRef) {
79469
+ metaBase.recoveryRef = recoveryRef;
79470
+ }
79471
+ async function recoveryRefForSession(input, sessionId) {
79472
+ return (await input.journalStore?.lookupSession(sessionId))?.recoveryRef;
79473
+ }
79474
+ function recoveryMeta(recoveryRef) {
79475
+ if (!recoveryRef) return { recoveryRef: null };
79476
+ return { recoveryRef };
79477
+ }
77548
79478
  function codeModeRuntimeError(message, stack) {
77549
79479
  const location = userCodeLocation(stack);
77550
79480
  const stackPreview = location === void 0 ? void 0 : [`at user code line ${location.line} column ${location.column}`];
@@ -77636,9 +79566,11 @@ function redactLogEntry(entry) {
77636
79566
  }
77637
79567
  //#endregion
77638
79568
  //#region src/code-mode/tool.ts
79569
+ 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
79570
  const codeModeRunInputSchema = object$1({
77640
79571
  code: string().describe("TypeScript Code Mode source to execute."),
77641
- timeoutMs: number$1().int().positive().optional().describe("Optional execution timeout in milliseconds.")
79572
+ timeoutMs: number$1().int().positive().optional().describe("Optional execution timeout in milliseconds."),
79573
+ sessionId: string().min(1).optional().describe(CODE_MODE_SESSION_ID_DESCRIPTION)
77642
79574
  });
77643
79575
  const codeModeRunParamsSchema = codeModeRunInputSchema.shape;
77644
79576
  function codeModeRunInputJsonSchema() {
@@ -77653,12 +79585,30 @@ function codeModeRunInputJsonSchema() {
77653
79585
  type: "integer",
77654
79586
  minimum: 1,
77655
79587
  description: "Optional execution timeout in milliseconds."
79588
+ },
79589
+ sessionId: {
79590
+ type: "string",
79591
+ minLength: 1,
79592
+ description: CODE_MODE_SESSION_ID_DESCRIPTION
77656
79593
  }
77657
79594
  },
77658
79595
  required: ["code"],
77659
79596
  additionalProperties: false
77660
79597
  };
77661
79598
  }
79599
+ function emptyCodeModeRunMeta() {
79600
+ return {
79601
+ runId: "",
79602
+ traceId: "",
79603
+ declarationHash: "",
79604
+ durationMs: 0,
79605
+ timeoutMs: 0,
79606
+ maxTimeoutMs: 0,
79607
+ sessionId: null,
79608
+ sessionStatus: null,
79609
+ recoveryRef: null
79610
+ };
79611
+ }
77662
79612
  //#endregion
77663
79613
  //#region src/native/tools.ts
77664
79614
  const nativeCodeModeToolId = "code_mode";
@@ -77676,12 +79626,23 @@ function nativeCapletsSystemGuidance(toolNames) {
77676
79626
  toolNames.length > 0 ? toolNames.map((tool) => `- ${tool}`).join("\n") : "- none",
77677
79627
  "",
77678
79628
  `${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.`,
79629
+ ...nativeCodeModePromptGuidance(),
77679
79630
  "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
79631
  "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
79632
  "Prefer list/read/search operations for triage and avoid broad provider searches that can return huge payloads or hit rate limits.",
77682
79633
  "When output shaping matters, inspect one tool with describe_tool and follow its fieldSelection hint."
77683
79634
  ].join("\n");
77684
79635
  }
79636
+ function nativeCodeModePromptGuidance() {
79637
+ return [
79638
+ `Use ${nativeCodeModeToolName} to run Caplets Code Mode TypeScript with generated caplets.<id> handles.`,
79639
+ "Prefer Code Mode for multi-step Caplet discovery, tool calls, filtering, joins, and compact synthesis.",
79640
+ "For REPL reuse, omit sessionId to start fresh, then pass the returned meta.sessionId on later calls that should reuse live state.",
79641
+ "Reused sessions preserve successful top-level var bindings, function declarations, and runtime state only while the live session remains available and compatible.",
79642
+ "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.",
79643
+ "Return decision-ready JSON from Code Mode rather than raw bulky provider payloads."
79644
+ ];
79645
+ }
77685
79646
  function nativeCapletPromptGuidance(toolName, caplet) {
77686
79647
  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
79648
  return caplet.backend === "mcp" ? [
@@ -77702,16 +79663,6 @@ function nativeCapletToolDescription(toolName, caplet) {
77702
79663
  //#endregion
77703
79664
  //#region src/server/options.ts
77704
79665
  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
79666
  function resolveCapletsServer(input = {}, env = process.env) {
77716
79667
  const rawUrl = nonEmpty$1(input.url, "url") ?? nonEmpty$1(env.CAPLETS_SERVER_URL, "CAPLETS_SERVER_URL");
77717
79668
  if (rawUrl === void 0) throw new CapletsError("REQUEST_INVALID", "CAPLETS_SERVER_URL or url is required.");
@@ -77773,10 +79724,6 @@ function isLoopbackHost(host) {
77773
79724
  const normalized = host.toLocaleLowerCase();
77774
79725
  return normalized === "localhost" || normalized === "127.0.0.1" || normalized === "::1" || normalized === "[::1]";
77775
79726
  }
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
79727
  function basicAuthHeader$1(user, password) {
77781
79728
  return `Basic ${Buffer$1.from(`${user}:${password}`).toString("base64")}`;
77782
79729
  }
@@ -77936,15 +79883,11 @@ const DEFAULT_PRESENCE_HEARTBEAT_INTERVAL_MS = 3e4;
77936
79883
  function resolveNativeCapletsServiceOptions(input = {}, env = process.env) {
77937
79884
  const mode = resolveRemoteMode({
77938
79885
  ...input.mode ? { mode: input.mode } : {},
77939
- ...input.server?.url ? { remoteUrl: input.server.url } : {}
79886
+ ...input.remote?.url ? { remoteUrl: input.remote.url } : {}
77940
79887
  }, env);
77941
79888
  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);
79889
+ const remoteFetch = input.remote?.fetch;
79890
+ const server = mode.mode === "cloud" ? resolveNativeHostedCloudRemote(input.remote?.url ?? env.CAPLETS_REMOTE_URL ?? "", optionalWorkspace(input, env).workspace, remoteFetch) : resolveCapletsRemote(input.remote, env);
77948
79891
  const cloud = resolveNativeCloudPresence(input.remote?.cloud, env);
77949
79892
  return {
77950
79893
  mode: mode.mode,
@@ -77966,7 +79909,7 @@ function resolveNativeHostedCloudRemote(url, workspace, fetch) {
77966
79909
  });
77967
79910
  }
77968
79911
  function optionalWorkspace(input, env) {
77969
- const workspace = input.remote?.cloud?.workspaceId ?? env.CAPLETS_REMOTE_WORKSPACE ?? env.CAPLETS_CLOUD_WORKSPACE_ID;
79912
+ const workspace = input.remote?.cloud?.workspaceId ?? input.remote?.workspace ?? env.CAPLETS_REMOTE_WORKSPACE ?? env.CAPLETS_CLOUD_WORKSPACE_ID;
77970
79913
  return workspace ? { workspace } : {};
77971
79914
  }
77972
79915
  function nativeAuthFromRemoteAuth$1(auth) {
@@ -78394,6 +80337,7 @@ var RemoteNativeCapletsService = class {
78394
80337
  client;
78395
80338
  unsubscribeRemote;
78396
80339
  pollTimer;
80340
+ codeModeSessions = new CodeModeSessionManager();
78397
80341
  closed = false;
78398
80342
  resetInFlight;
78399
80343
  constructor(options) {
@@ -78410,7 +80354,7 @@ var RemoteNativeCapletsService = class {
78410
80354
  return [...this.tools];
78411
80355
  }
78412
80356
  async execute(capletId, request) {
78413
- if (capletId === "code_mode") return await executeCodeModeRunRemote(this, request);
80357
+ if (capletId === "code_mode") return await executeCodeModeRunRemote(this, request, this.codeModeSessions);
78414
80358
  const remoteToolId = this.toolRoutes.get(capletId) ?? capletId;
78415
80359
  try {
78416
80360
  return await this.client.callTool(remoteToolId, request);
@@ -78428,6 +80372,16 @@ var RemoteNativeCapletsService = class {
78428
80372
  throw error;
78429
80373
  }
78430
80374
  }
80375
+ codeModeService() {
80376
+ return {
80377
+ listTools: () => remoteCodeModeCallableNativeTools$1(this.listTools()),
80378
+ execute: async (capletId, request) => await this.execute(capletId, request),
80379
+ codeModeService: () => this.codeModeService(),
80380
+ reload: async () => await this.reload(),
80381
+ onToolsChanged: () => () => void 0,
80382
+ close: async () => void 0
80383
+ };
80384
+ }
78431
80385
  async reload() {
78432
80386
  if (this.closed) return false;
78433
80387
  try {
@@ -78454,6 +80408,7 @@ var RemoteNativeCapletsService = class {
78454
80408
  if (this.closed) return;
78455
80409
  this.closed = true;
78456
80410
  clearInterval(this.pollTimer);
80411
+ this.codeModeSessions.close();
78457
80412
  this.unsubscribeRemote();
78458
80413
  this.listeners.clear();
78459
80414
  await this.client.close();
@@ -78508,6 +80463,7 @@ function remoteToolToNativeTool(tool) {
78508
80463
  const toolName = tool.codeModeRun ? nativeCodeModeToolName : nativeCapletToolName(capletId);
78509
80464
  const inputSchema = isPlainObject(tool.inputSchema) ? tool.inputSchema : generatedToolInputJsonSchemaForCaplet({ backend: "tool" });
78510
80465
  const operationNames = tool.sourceCapletId === void 0 && !tool.codeModeRun ? operationNamesFromSchema(inputSchema) : void 0;
80466
+ const description = tool.codeModeRun ? remoteCodeModeToolDescription(tool) : tool.description;
78511
80467
  return {
78512
80468
  caplet: capletId,
78513
80469
  ...sourceCaplet && sourceCaplet !== capletId ? { sourceCaplet } : {},
@@ -78515,12 +80471,12 @@ function remoteToolToNativeTool(tool) {
78515
80471
  toolName,
78516
80472
  title: tool.title ?? capletId,
78517
80473
  description: [
78518
- tool.description ?? "Remote Caplets tool.",
80474
+ description ?? "Remote Caplets tool.",
78519
80475
  "",
78520
80476
  `Native tool name: ${toolName}`,
78521
80477
  `Remote Caplet ID: ${capletId}`
78522
80478
  ].join("\n"),
78523
- promptGuidance: [`Use ${toolName} through the remote Caplets service.`],
80479
+ promptGuidance: tool.codeModeRun ? nativeCodeModePromptGuidance() : [`Use ${toolName} through the remote Caplets service.`],
78524
80480
  ...tool.codeModeRun || capletId === "code_mode" ? { codeModeRun: true } : {},
78525
80481
  ...tool.codeModeCaplets ? { codeModeCaplets: tool.codeModeCaplets.map((caplet) => ({
78526
80482
  id: caplet.capletId,
@@ -78534,6 +80490,34 @@ function remoteToolToNativeTool(tool) {
78534
80490
  ...operationNames ? { operationNames } : {}
78535
80491
  };
78536
80492
  }
80493
+ function remoteCodeModeToolDescription(tool) {
80494
+ if (!tool.codeModeCaplets || tool.codeModeCaplets.length === 0) return tool.description;
80495
+ return generateCodeModeRunToolDescription(generateCodeModeDeclarations({ caplets: tool.codeModeCaplets.map((caplet) => ({
80496
+ id: caplet.capletId,
80497
+ name: caplet.name,
80498
+ description: caplet.description ?? "",
80499
+ shadowing: caplet.shadowing
80500
+ })) }));
80501
+ }
80502
+ function remoteCodeModeCallableNativeTools$1(tools) {
80503
+ const codeModeCaplets = tools.flatMap((tool) => tool.codeModeCaplets ?? []);
80504
+ const hasExplicitCodeModeManifest = tools.some((tool) => tool.codeModeCaplets !== void 0);
80505
+ if (codeModeCaplets.length === 0) return hasExplicitCodeModeManifest ? [] : tools.filter((tool) => tool.codeModeRun !== true);
80506
+ const byId = new Map(tools.map((tool) => [tool.caplet, tool]));
80507
+ return codeModeCaplets.map((caplet) => {
80508
+ const tool = byId.get(caplet.id);
80509
+ return {
80510
+ caplet: caplet.id,
80511
+ toolName: tool?.toolName ?? nativeCapletToolName(caplet.id),
80512
+ title: caplet.name,
80513
+ description: caplet.description,
80514
+ ...caplet.shadowing ? { shadowing: caplet.shadowing } : {},
80515
+ ...caplet.useWhen ? { useWhen: caplet.useWhen } : {},
80516
+ ...caplet.avoidWhen ? { avoidWhen: caplet.avoidWhen } : {},
80517
+ promptGuidance: tool?.promptGuidance ?? []
80518
+ };
80519
+ });
80520
+ }
78537
80521
  function nativeToolRouteId(tool) {
78538
80522
  return tool.codeModeRun ? nativeCodeModeToolId : tool.name;
78539
80523
  }
@@ -78659,8 +80643,9 @@ function primitiveInvokeInput(capletId, operation, input) {
78659
80643
  return input;
78660
80644
  }
78661
80645
  function toolsFromManifest(manifest) {
78662
- const codeModeMarker = attachCodeModeMarker(manifest);
78663
- const codeModeShadowing = manifest.codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
80646
+ const codeModeCaplets = manifest.codeModeCaplets ?? [];
80647
+ const codeModeMarker = attachCodeModeMarker(codeModeCaplets);
80648
+ const codeModeShadowing = codeModeCaplets.some((entry) => entry.shadowing === "forbid") ? "forbid" : "allow";
78664
80649
  return [
78665
80650
  ...manifest.caplets.map((entry) => ({
78666
80651
  name: entry.capletId,
@@ -78684,20 +80669,20 @@ function toolsFromManifest(manifest) {
78684
80669
  ...codeModeMarker
78685
80670
  })),
78686
80671
  ...primitiveToolsFromManifest(manifest, codeModeMarker),
78687
- ...manifest.codeModeCaplets.length > 0 ? [{
80672
+ ...codeModeCaplets.length > 0 ? [{
78688
80673
  name: nativeCodeModeToolId,
78689
80674
  capletId: nativeCodeModeToolId,
78690
80675
  title: "Code Mode",
78691
80676
  description: "Remote Caplets available to locally-run attached Code Mode.",
78692
80677
  codeModeRun: true,
78693
- codeModeCaplets: manifest.codeModeCaplets,
80678
+ codeModeCaplets,
78694
80679
  shadowing: codeModeShadowing,
78695
80680
  inputSchema: codeModeRunInputJsonSchema()
78696
80681
  }] : []
78697
80682
  ];
78698
80683
  }
78699
- function attachCodeModeMarker(manifest) {
78700
- return manifest.codeModeCaplets.length === 0 ? { codeModeCaplets: [] } : {};
80684
+ function attachCodeModeMarker(codeModeCaplets = []) {
80685
+ return codeModeCaplets.length === 0 ? { codeModeCaplets: [] } : {};
78701
80686
  }
78702
80687
  function primitiveToolsFromManifest(manifest, codeModeMarker) {
78703
80688
  const directToolNames = new Set(manifest.tools.map((entry) => entry.name));
@@ -78806,7 +80791,7 @@ function exportMapFor(manifest) {
78806
80791
  mapped.set(entry.name, entry);
78807
80792
  }
78808
80793
  for (const entry of manifest.tools) mapped.set(entry.name, entry);
78809
- for (const entry of manifest.codeModeCaplets) {
80794
+ for (const entry of manifest.codeModeCaplets ?? []) {
78810
80795
  setIfAbsent(entry.capletId, entry);
78811
80796
  setIfAbsent(entry.name, entry);
78812
80797
  }
@@ -78866,7 +80851,7 @@ function startAttachEvents(attachUrl, requestInit, fetchImpl, listeners, onClose
78866
80851
  })();
78867
80852
  return abort;
78868
80853
  }
78869
- async function executeCodeModeRunRemote(service, request) {
80854
+ async function executeCodeModeRunRemote(service, request, sessionManager) {
78870
80855
  const parsed = codeModeRunInputSchema.safeParse(request);
78871
80856
  if (!parsed.success) return {
78872
80857
  ok: false,
@@ -78881,20 +80866,16 @@ async function executeCodeModeRunRemote(service, request) {
78881
80866
  truncated: false,
78882
80867
  stored: false
78883
80868
  },
78884
- meta: {
78885
- runId: "",
78886
- traceId: "",
78887
- declarationHash: "",
78888
- durationMs: 0,
78889
- timeoutMs: 0,
78890
- maxTimeoutMs: 0
78891
- }
80869
+ meta: emptyCodeModeRunMeta()
78892
80870
  };
78893
80871
  return await runCodeMode({
78894
80872
  code: parsed.data.code,
78895
80873
  service,
78896
80874
  ...parsed.data.timeoutMs === void 0 ? {} : { timeoutMs: parsed.data.timeoutMs },
78897
- runtimeScope: process.env.CAPLETS_MODE?.trim() || "remote"
80875
+ ...parsed.data.sessionId === void 0 ? {} : { sessionId: parsed.data.sessionId },
80876
+ runtimeScope: process.env.CAPLETS_MODE?.trim() || "remote",
80877
+ journalStore: new CodeModeJournalStore(),
80878
+ ...sessionManager === void 0 ? {} : { sessionManager }
78898
80879
  });
78899
80880
  }
78900
80881
  function compatibleExport(manifest, previous) {
@@ -78905,7 +80886,7 @@ function compatibleExport(manifest, previous) {
78905
80886
  ...manifest.resourceTemplates,
78906
80887
  ...manifest.prompts,
78907
80888
  ...manifest.completions,
78908
- ...manifest.codeModeCaplets
80889
+ ...manifest.codeModeCaplets ?? []
78909
80890
  ].find((entry) => entry.stableId === previous.stableId);
78910
80891
  if (!next) return void 0;
78911
80892
  if (next.kind !== previous.kind) return void 0;
@@ -79346,6 +81327,7 @@ var DefaultNativeCapletsService = class {
79346
81327
  toolListeners = /* @__PURE__ */ new Set();
79347
81328
  directToolRoutes = /* @__PURE__ */ new Map();
79348
81329
  exposureSnapshot;
81330
+ codeModeSessions = new CodeModeSessionManager();
79349
81331
  postReloadRefresh;
79350
81332
  exposureRefreshGeneration = 0;
79351
81333
  constructor(options) {
@@ -79383,7 +81365,7 @@ var DefaultNativeCapletsService = class {
79383
81365
  ];
79384
81366
  }
79385
81367
  async execute(capletId, request) {
79386
- if (capletId === "code_mode") return await executeCodeModeRunNative(this.codeModeDelegate(), request);
81368
+ if (capletId === "code_mode") return await executeCodeModeRunNative(this.codeModeDelegate(), request, this.codeModeSessions);
79387
81369
  const route = this.directToolRoutes.get(capletId);
79388
81370
  if (route) {
79389
81371
  if (isMcpPrimitiveRoute(route.operationName)) return await this.engine.execute(route.capletId, nativeMcpPrimitiveRequest(route.operationName, request));
@@ -79391,6 +81373,9 @@ var DefaultNativeCapletsService = class {
79391
81373
  }
79392
81374
  return await this.engine.execute(capletId, request);
79393
81375
  }
81376
+ codeModeService() {
81377
+ return this.codeModeDelegate();
81378
+ }
79394
81379
  async reload() {
79395
81380
  const reloaded = await this.engine.reload();
79396
81381
  await this.postReloadRefresh;
@@ -79404,6 +81389,7 @@ var DefaultNativeCapletsService = class {
79404
81389
  }
79405
81390
  async close() {
79406
81391
  this.unsubscribeEngineReload();
81392
+ this.codeModeSessions.close();
79407
81393
  this.toolListeners.clear();
79408
81394
  await this.engine.close();
79409
81395
  }
@@ -79630,11 +81616,7 @@ function codeModeRunNativeTool(capletTools) {
79630
81616
  ].join("\n"),
79631
81617
  codeModeRun: true,
79632
81618
  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
- ],
81619
+ promptGuidance: nativeCodeModePromptGuidance(),
79638
81620
  inputSchema: codeModeRunInputJsonSchema()
79639
81621
  };
79640
81622
  }
@@ -79657,7 +81639,7 @@ function codeModeCallableNativeTools(tools, options) {
79657
81639
  };
79658
81640
  });
79659
81641
  }
79660
- async function executeCodeModeRunNative(service, request) {
81642
+ async function executeCodeModeRunNative(service, request, sessionManager) {
79661
81643
  const parsed = codeModeRunInputSchema.safeParse(request);
79662
81644
  if (!parsed.success) return {
79663
81645
  ok: false,
@@ -79672,20 +81654,16 @@ async function executeCodeModeRunNative(service, request) {
79672
81654
  truncated: false,
79673
81655
  stored: false
79674
81656
  },
79675
- meta: {
79676
- runId: "",
79677
- traceId: "",
79678
- declarationHash: "",
79679
- durationMs: 0,
79680
- timeoutMs: 0,
79681
- maxTimeoutMs: 0
79682
- }
81657
+ meta: emptyCodeModeRunMeta()
79683
81658
  };
79684
81659
  return await runCodeMode({
79685
81660
  code: parsed.data.code,
79686
81661
  service,
79687
81662
  ...parsed.data.timeoutMs === void 0 ? {} : { timeoutMs: parsed.data.timeoutMs },
79688
- runtimeScope: process.env.CAPLETS_MODE?.trim() || "local"
81663
+ ...parsed.data.sessionId === void 0 ? {} : { sessionId: parsed.data.sessionId },
81664
+ runtimeScope: process.env.CAPLETS_MODE?.trim() || "local",
81665
+ journalStore: new CodeModeJournalStore(),
81666
+ ...sessionManager === void 0 ? {} : { sessionManager }
79689
81667
  });
79690
81668
  }
79691
81669
  function createDefaultNativeCapletsService(options) {
@@ -79727,11 +81705,14 @@ var CloudNativeCapletsService = class {
79727
81705
  async execute(capletId, request) {
79728
81706
  return await (this.delegate ?? this.local).execute(capletId, request);
79729
81707
  }
81708
+ codeModeService() {
81709
+ return (this.delegate ?? this.local).codeModeService?.() ?? this.delegate ?? this.local;
81710
+ }
79730
81711
  async reload() {
79731
81712
  if (this.closed) return false;
79732
81713
  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, "");
81714
+ const cloudFetch = this.options.remote?.fetch;
81715
+ const remoteUrl = this.options.remote?.url ?? this.baseRemote.url.toString().replace(/\/mcp$/u, "");
79735
81716
  const selection = await resolveRemoteSelection({
79736
81717
  mode: "cloud",
79737
81718
  remoteUrl,
@@ -79807,6 +81788,7 @@ var CompositeNativeCapletsService = class {
79807
81788
  tools = [];
79808
81789
  closed = false;
79809
81790
  batchingReload = false;
81791
+ codeModeSessions = new CodeModeSessionManager();
79810
81792
  constructor(remote, local, options, presence) {
79811
81793
  this.remote = remote;
79812
81794
  this.local = local;
@@ -79822,10 +81804,20 @@ var CompositeNativeCapletsService = class {
79822
81804
  return [...this.tools];
79823
81805
  }
79824
81806
  async execute(capletId, request) {
79825
- if (capletId === "code_mode") return await executeCodeModeRunNative(this, request);
81807
+ if (capletId === "code_mode") return await executeCodeModeRunNative(this, request, this.codeModeSessions);
79826
81808
  if (this.localCanExecute(capletId)) return await this.local.execute(capletId, request);
79827
81809
  return await this.remote.execute(capletId, request);
79828
81810
  }
81811
+ codeModeService() {
81812
+ return {
81813
+ listTools: () => codeModeCallableNativeTools(this.listTools(), { fallbackToVisible: false }),
81814
+ execute: async (capletId, request) => await this.execute(capletId, request),
81815
+ codeModeService: () => this.codeModeService(),
81816
+ reload: async () => await this.reload(),
81817
+ onToolsChanged: () => () => void 0,
81818
+ close: async () => void 0
81819
+ };
81820
+ }
79829
81821
  async reload() {
79830
81822
  if (this.closed) return false;
79831
81823
  this.batchingReload = true;
@@ -79846,6 +81838,7 @@ var CompositeNativeCapletsService = class {
79846
81838
  this.closed = true;
79847
81839
  for (const unsubscribe of this.unsubscribers.splice(0)) unsubscribe();
79848
81840
  this.listeners.clear();
81841
+ this.codeModeSessions.close();
79849
81842
  await Promise.all([
79850
81843
  this.remote.close(),
79851
81844
  this.local.close(),
@@ -79917,7 +81910,7 @@ function localExecutionKeys(tools, capletId) {
79917
81910
  function createProjectBindingSessionManager(cloud, local, options) {
79918
81911
  if (!cloud) return;
79919
81912
  const projectRoot = cloud.projectRoot ?? findProjectRoot();
79920
- const cloudFetch = options.remote?.fetch ?? options.server?.fetch;
81913
+ const cloudFetch = options.remote?.fetch;
79921
81914
  return new ProjectBindingSessionManager({
79922
81915
  client: new CapletsCloudClient({
79923
81916
  baseUrl: cloud.url,
@@ -79971,4 +81964,4 @@ function errorMessage(error) {
79971
81964
  return error instanceof Error ? error.message : String(error);
79972
81965
  }
79973
81966
  //#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 };
81967
+ 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 };