@poe-platform/safe-js 0.1.720 → 0.1.722

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +50 -7
  2. package/dist/config-mutations/types.d.ts +3 -1
  3. package/dist/safe-js/chunks/{chunk-B2SQLK4O.js → chunk-3QQYJ4RQ.js} +3 -2
  4. package/dist/safe-js/chunks/chunk-3QQYJ4RQ.js.map +7 -0
  5. package/dist/safe-js/chunks/{chunk-OP3H3ZDN.js → chunk-55RIIUGG.js} +23 -7
  6. package/dist/safe-js/chunks/chunk-55RIIUGG.js.map +7 -0
  7. package/dist/safe-js/chunks/{chunk-NJM2Q74Z.js → chunk-7SBQ7WTV.js} +10 -11
  8. package/dist/safe-js/chunks/chunk-7SBQ7WTV.js.map +7 -0
  9. package/dist/safe-js/chunks/{chunk-KP6I45ET.js → chunk-BNIEPGDU.js} +9885 -8523
  10. package/dist/safe-js/chunks/{chunk-KP6I45ET.js.map → chunk-BNIEPGDU.js.map} +4 -4
  11. package/dist/safe-js/chunks/{chunk-HYD4K4HN.js → chunk-D3GC5QPZ.js} +63 -1
  12. package/dist/safe-js/chunks/chunk-D3GC5QPZ.js.map +7 -0
  13. package/dist/safe-js/chunks/{chunk-KK5NCR5R.js → chunk-EH5A2EQI.js} +501 -150
  14. package/dist/safe-js/chunks/chunk-EH5A2EQI.js.map +7 -0
  15. package/dist/safe-js/chunks/{chunk-APKV5Y6T.js → chunk-FA5CQO6V.js} +2 -2
  16. package/dist/safe-js/chunks/{chunk-RML35GIF.js → chunk-GCOLKRMY.js} +4 -4
  17. package/dist/safe-js/chunks/{chunk-U6KZ2DQ2.js → chunk-K3ZRBAG5.js} +3 -3
  18. package/dist/safe-js/chunks/{chunk-BGJXQN4A.js → chunk-QL2ALAE6.js} +4 -4
  19. package/dist/safe-js/chunks/{chunk-IDQ67DY2.js → chunk-RYVHEOHM.js} +1131 -101
  20. package/dist/safe-js/chunks/chunk-RYVHEOHM.js.map +7 -0
  21. package/dist/safe-js/chunks/{chunk-A7CADQAD.js → chunk-S2GFVXSI.js} +3 -3
  22. package/dist/safe-js/chunks/{chunk-XMA6FOJU.js → chunk-WF7HYDJ4.js} +4 -5
  23. package/dist/safe-js/chunks/{chunk-XMA6FOJU.js.map → chunk-WF7HYDJ4.js.map} +2 -2
  24. package/dist/safe-js/chunks/{chunk-NEJ44T4Y.js → chunk-XHSOM5CG.js} +2 -2
  25. package/dist/safe-js/chunks/{cli-runtime-PO6DQDHP.js → cli-runtime-6QPGM3TX.js} +14 -14
  26. package/dist/safe-js/chunks/{dump-TRGFSCJ7.js → dump-TU6SYRFD.js} +4 -4
  27. package/dist/safe-js/chunks/{fs-4T5MZW5J.js → fs-HTZT32MQ.js} +4 -4
  28. package/dist/safe-js/chunks/harness-RYAMI444.js +10 -0
  29. package/dist/safe-js/chunks/mcp-DO2IRFGQ.js +11 -0
  30. package/dist/safe-js/chunks/migration-file-K7UH5ZG6.js +12 -0
  31. package/dist/safe-js/chunks/restore-7LRP4BM3.js +13 -0
  32. package/dist/safe-js/chunks/run-6SETM7SV.js +17 -0
  33. package/dist/safe-js/chunks/runtime-modules-MCQS2SHQ.js +10 -0
  34. package/dist/safe-js/cli.js +2 -2
  35. package/dist/safe-js/core.js +7 -7
  36. package/dist/safe-js/extensions.d.ts +3 -1
  37. package/dist/safe-js/index.js +14 -14
  38. package/dist/safe-js/interp/async.d.ts +4 -1
  39. package/dist/safe-js/interp/budget.d.ts +15 -6
  40. package/dist/safe-js/interp/collection-iterator.d.ts +1 -1
  41. package/dist/safe-js/interp/host-bridge.d.ts +1 -0
  42. package/dist/safe-js/interp/host-capabilities.d.ts +13 -4
  43. package/dist/safe-js/interp/interpreter.d.ts +5 -1
  44. package/dist/safe-js/interp/intl-numberformat.d.ts +2 -2
  45. package/dist/safe-js/interp/jobs.d.ts +8 -0
  46. package/dist/safe-js/interp/scope.d.ts +13 -3
  47. package/dist/safe-js/interp/typed-array.d.ts +5 -2
  48. package/dist/safe-js/interp/values.d.ts +1 -0
  49. package/dist/safe-js/modules/registry.d.ts +4 -1
  50. package/dist/safe-js/modules/source-graph.d.ts +19 -1
  51. package/dist/safe-js/parse/compact-spans.d.ts +18 -0
  52. package/dist/safe-js/parse/dynamic-source.d.ts +3 -1
  53. package/dist/safe-js/parse/function-source.d.ts +1 -1
  54. package/dist/safe-js/parse/parser.d.ts +8 -3
  55. package/dist/safe-js/parse/tokenizer.d.ts +4 -0
  56. package/dist/safe-js/realm.d.ts +17 -3
  57. package/dist/safe-js/restore.d.ts +1 -0
  58. package/dist/safe-js/run.d.ts +10 -0
  59. package/dist/safe-js/snapshot/guest-heap.d.ts +1 -0
  60. package/dist/toolcraft-design/prompts/primitives/note.d.ts +1 -1
  61. package/package.json +2 -2
  62. package/dist/safe-js/chunks/chunk-B2SQLK4O.js.map +0 -7
  63. package/dist/safe-js/chunks/chunk-HYD4K4HN.js.map +0 -7
  64. package/dist/safe-js/chunks/chunk-IDQ67DY2.js.map +0 -7
  65. package/dist/safe-js/chunks/chunk-KK5NCR5R.js.map +0 -7
  66. package/dist/safe-js/chunks/chunk-NJM2Q74Z.js.map +0 -7
  67. package/dist/safe-js/chunks/chunk-OP3H3ZDN.js.map +0 -7
  68. package/dist/safe-js/chunks/harness-DLEQ2Z3O.js +0 -10
  69. package/dist/safe-js/chunks/mcp-TNVEFJ6K.js +0 -11
  70. package/dist/safe-js/chunks/migration-file-IDIUFLKY.js +0 -12
  71. package/dist/safe-js/chunks/restore-P27AUZR2.js +0 -13
  72. package/dist/safe-js/chunks/run-KGAEHYMV.js +0 -17
  73. package/dist/safe-js/chunks/runtime-modules-KICK45EE.js +0 -10
  74. /package/dist/safe-js/chunks/{chunk-APKV5Y6T.js.map → chunk-FA5CQO6V.js.map} +0 -0
  75. /package/dist/safe-js/chunks/{chunk-RML35GIF.js.map → chunk-GCOLKRMY.js.map} +0 -0
  76. /package/dist/safe-js/chunks/{chunk-U6KZ2DQ2.js.map → chunk-K3ZRBAG5.js.map} +0 -0
  77. /package/dist/safe-js/chunks/{chunk-BGJXQN4A.js.map → chunk-QL2ALAE6.js.map} +0 -0
  78. /package/dist/safe-js/chunks/{chunk-A7CADQAD.js.map → chunk-S2GFVXSI.js.map} +0 -0
  79. /package/dist/safe-js/chunks/{chunk-NEJ44T4Y.js.map → chunk-XHSOM5CG.js.map} +0 -0
  80. /package/dist/safe-js/chunks/{cli-runtime-PO6DQDHP.js.map → cli-runtime-6QPGM3TX.js.map} +0 -0
  81. /package/dist/safe-js/chunks/{dump-TRGFSCJ7.js.map → dump-TU6SYRFD.js.map} +0 -0
  82. /package/dist/safe-js/chunks/{fs-4T5MZW5J.js.map → fs-HTZT32MQ.js.map} +0 -0
  83. /package/dist/safe-js/chunks/{harness-DLEQ2Z3O.js.map → harness-RYAMI444.js.map} +0 -0
  84. /package/dist/safe-js/chunks/{mcp-TNVEFJ6K.js.map → mcp-DO2IRFGQ.js.map} +0 -0
  85. /package/dist/safe-js/chunks/{migration-file-IDIUFLKY.js.map → migration-file-K7UH5ZG6.js.map} +0 -0
  86. /package/dist/safe-js/chunks/{restore-P27AUZR2.js.map → restore-7LRP4BM3.js.map} +0 -0
  87. /package/dist/safe-js/chunks/{run-KGAEHYMV.js.map → run-6SETM7SV.js.map} +0 -0
  88. /package/dist/safe-js/chunks/{runtime-modules-KICK45EE.js.map → runtime-modules-MCQS2SHQ.js.map} +0 -0
package/README.md CHANGED
@@ -42,7 +42,7 @@ console.log(result.returnValue);
42
42
 
43
43
  - **JavaScript control flow:** functions and closures, classes, async/await, loops, destructuring, spread, templates, exceptions, and synchronous and asynchronous generators.
44
44
  - **Guest function objects:** own properties on functions and arrows; ordinary constructors with shared prototypes, inherited methods and `instanceof`. `Object.create`, `getPrototypeOf`, `setPrototypeOf`, own-property inspection, and data descriptors work on ordinary sandbox records.
45
- - **Data processing:** arrays, objects, strings, numbers, BigInt, Symbol, JSON, Math, Date, Map, Set, WeakMap, WeakSet, typed arrays, ArrayBuffer/DataView, promises, Intl APIs, and budgeted regular expressions.
45
+ - **Data processing:** arrays, objects, strings, numbers, BigInt, Symbol, JSON, Math, Date, Map, Set, WeakMap, WeakSet, typed arrays, ArrayBuffer/DataView, UTF-8 TextEncoder, promises, Intl APIs, and budgeted regular expressions.
46
46
  - **Language and object APIs:** guest `eval`, `Function` and async/generator function constructors, `Proxy`, `Reflect`, property descriptors, accessors, and prototype mutation. Dynamically generated code executes inside the interpreter with its existing capabilities and budgets.
47
47
  - **Additional built-ins:** all eight Temporal types and `Temporal.Now`, iterator helpers, disposable stacks, `WeakRef`, `FinalizationRegistry`, `SharedArrayBuffer`, and `Atomics`. Availability does not imply complete conformance or portable recovery; see the limitations below.
48
48
  - **Explicit capabilities:** static imports and dynamic `import()` resolve against host-supplied modules, not arbitrary npm packages or files. Optional helpers cover agents, MCP tools, files, environment reads, time, logging, and metrics.
@@ -88,6 +88,10 @@ const result = await run(`
88
88
  Builtin prototypes retain their originating Object prototype when inspected
89
89
  from another realm, including when a budget is reused. Checkpoints preserve
90
90
  constructor/prototype identity and their supported property mutations.
91
+ Persistent realms can use `budget.forkRealm()` to keep separate globals and
92
+ intrinsic caches while sharing step, call-depth and retained-data limits. A fork
93
+ preserves consumed allowances, including when a sibling closes. Each budget view
94
+ supports one live realm; suspended invocation data remains charged until released.
91
95
  Map and Set instances also retain their selected prototype during inspection
92
96
  from another realm.
93
97
  Mixed-realm intrinsic checkpoints preserve separate constructor/prototype
@@ -210,6 +214,10 @@ try {
210
214
 
211
215
  This prints `2`. Evaluations share declarations, closures and object identity without rerunning earlier source. Budgets are cumulative. `evaluate(source, { filename? })` returns `ok`, `returnValue` or `error`, and `stats`; it can also reject. Concurrent evaluations are rejected. Deferred callbacks can run while guest code awaits their result; overlapping invocation of the same callback is rejected. Close cancels pending work, revokes capabilities and awaits cleanup; repeated close does not rerun cleanup. Unhandled execution failures also close the realm.
212
216
 
217
+ For scripts whose completion value is unused, call `evaluate(source, { discardResult: true })`. A successful result omits `returnValue`, so guest values with custom prototypes can remain inside the realm without crossing the data-copy boundary. Effects, resource limits and error handling still apply. `realm.supportsDiscardResult` is an immutable `true` marker for adapters that support older SDK versions.
218
+
219
+ Execution gives host timers and cancellation turns between guest nodes after elapsed host time as well as interpreter work. This preserves guest job ownership and resource checks. A synchronous native call or an individual data scan can still delay delivery; cancellation is cooperative.
220
+
213
221
  `createRealm(options?)` accepts `bindings`, `modules`, `budget`, `clock`, `signal`, `sink` and `randomSeed` as described below, plus:
214
222
 
215
223
  | Option | Purpose / default |
@@ -218,11 +226,35 @@ This prints `2`. Evaluations share declarations, closures and object identity wi
218
226
  | `grants` | Granted capability names; `[]`. Every requested capability must be granted before any extension setup runs. |
219
227
  | `builtinOverrides` | Optional `{ console: "extension-name" }` authorizes that registered extension to replace only the builtin console. It must declare `console` and export a host object created in the realm. No overrides by default. |
220
228
  | `limits` | Positive integer caps: `extensions: 32`, `hostObjects: 1024`, `callbacks: 1024`, `guestReferences: 1024`, `cleanups: 1024`, `nestedEvaluations: 16`. Collection budgets also apply. |
221
-
222
- Ordinary host arguments/results are still copied. To preserve live native identity, explicitly create a host object. A guest function crossing to the host becomes an opaque callback: invoke it with `realm.invokeCallback(callback, { thisValue?, args? })`, then `realm.releaseCallback(callback)` when no longer needed. Callbacks and live objects cannot cross realms or survive close. For deferred arguments that must preserve guest identity, opt into retained references as described below.
229
+ | `stringCompilation` | Optional `"allow"` (default) or `"deny"`. Denial raises a catchable guest EvalError for string eval and Function/AsyncFunction/GeneratorFunction/AsyncGeneratorFunction compilation, including retained callbacks. Host source evaluation remains available. This is separate from WebAssembly compilation policy. |
230
+ | `classicScripts` | Optional boolean, default `false`. Evaluations use classic Script grammar with persistent globals: top-level `this` is the intrinsic global object, `var` and functions create global properties, and `let`/`const` remain lexical. Injected capabilities stay immutable lexical bindings. Explicit source modules retain module semantics. |
231
+ | `classicScriptErrors` | Optional `"fatal"` (default) or `"report"`; reporting requires `classicScripts: true`. Ordinary escaped Script exceptions return `ok: false` with `recoverable: true` while preserving realm state. Syntax, budget, cancellation, module, callback and unhandled rejection failures remain fatal. |
232
+ | `callbackScheduling` | Optional `"after-prefix"` for a trusted host scheduler. Allows later source after every admitted callback finishes its synchronous prefix, while their asynchronous tails remain pending. Omit for exclusive source evaluation. |
233
+ | `sourceResolver` | Explicitly grants source text and a canonical identity for each imported source. Classic Scripts use their evaluation filename as the referrer, including later calls to saved functions and generators. No filesystem or network access is granted by default. |
234
+ | `sourceImportTimeoutMs` | Optional integer from 1 to 2147483647, disabled by default. Limits elapsed host time for each dynamic source import across resolution, linking and evaluation, including top-level await. Expiry revokes the entire realm with a deadline budget error. Timers are cooperative; synchronous host work can delay delivery. |
235
+
236
+ Classic Scripts reject top-level return, await and static imports/exports. This
237
+ option preserves declaration history across evaluations and checkpoints; browser
238
+ window aliases and callback scheduling belong to the host. Dynamic source imports
239
+ require an explicit `sourceResolver` and share canonical module instances with
240
+ source-module evaluations. `realm.sourceModuleStatus()` returns an immutable
241
+ snapshot with `pendingImports`, `preparedModules`, `fulfilledImports` and
242
+ `rejectedImports`; it rejects after realm revocation. Import settlement does not
243
+ establish application readiness.
244
+
245
+ Ordinary host arguments/results are still copied. To preserve live native identity, explicitly create a host object. A guest function crossing to the host becomes an opaque callback: invoke it with `realm.invokeCallback(callback, { thisValue?, args? })`, then `realm.releaseCallback(callback)` when no longer needed. Inside a declared and granted `context.nestedOperation`, await `context.invokeCallback` to settle the full guest result, including nested host calls and returned promises. Callbacks and live objects cannot cross realms or survive close. For deferred arguments that must preserve guest identity, opt into retained references as described below.
223
246
 
224
247
  Need synchronous effects without waiting for an async callback's tail? Use `realm.startCallback(callback, options)` or `context.startCallback(callback, options)`. The frozen `CallbackInvocation` exposes two promises: await `synchronous` when the guest function returns or its async body reaches its first `await`; await `result` for the final value. Interpreter implementation awaits and budget work do not complete the prefix. Ordinary throws reject both promises; nonfatal async-function errors reject only `result`, even before the first `await`. Close, abort and fatal errors reject still-pending handles without changing a completed prefix. The same callback limits, identity and reentry rules apply; no extra grant is required. Calls started outside a host operation are queued in invocation order. Browser event/default-action policy remains the host's responsibility.
225
248
 
249
+ With `callbackScheduling: "after-prefix"`, the host must retain and observe callback
250
+ results. Source remains exclusive, including top-level await; guest-owned host
251
+ operations cannot use this option to admit another source. All work shares the
252
+ realm queue and cumulative limits. Suspended frames remain included in full graph
253
+ accounting. Compilation tickets and allocation charges may remain conservatively
254
+ held until pending work completes. External close waits for canceled work and
255
+ cleanup; close from a guest-owned host operation initiates cancellation and rejects
256
+ with `reentry` instead of awaiting its own caller.
257
+
226
258
  <details>
227
259
  <summary>Trusted extensions and live host objects</summary>
228
260
 
@@ -287,7 +319,8 @@ Supply your own bounded `journal`; this does not add browser console behavior. W
287
319
  | `signal` | Realm cancellation signal; aborted on close or failure. |
288
320
  | `onCleanup(fn)` | Register a sync/async disposer. Cleanup runs in reverse order, awaits every disposer, and reports failures without skipping the rest. |
289
321
  | `chargeWork(units = 1)` | Charge a nonnegative integer against the shared execution budget. Fatal exhaustion cannot be swallowed to continue execution. |
290
- | `createHostObject({ properties?, methods?, indexed?, named? })` | Create a realm-owned capability. Properties declare synchronous `get`/`set` functions; methods are host functions. Optional `indexed` and `named` expose bounded live members. Undeclared members expose no native prototype. |
322
+ | `createHostObject({ properties?, methods?, indexed?, named?, expandos? })` | Create a realm-owned capability. Properties declare synchronous `get`/`set` functions; methods are host functions. Optional `indexed` and `named` expose bounded live members. Optional `expandos` stores guest fields with guest identity preserved. Undeclared members expose no native prototype. |
323
+ | `createArrayBufferReference(buffer)` | Create an opaque live reference to a fixed, attached, plain ArrayBuffer without own metadata. Requires declared and granted `array-buffer:share`; full buffer bytes count against array/data budgets and `limits.guestReferences`. |
291
324
  | `invokeCallback(callback, { thisValue?, args? })` | Invoke a captured guest function with the realm's state, cancellation and budgets. Same operation as on the realm. |
292
325
  | `startCallback(callback, { thisValue?, args? })` | Return separate `synchronous` and `result` promises for the same realm-owned invocation. Also available on the realm. |
293
326
  | `releaseCallback(callback)` | Revoke the callback and release its retained guest state. |
@@ -296,8 +329,12 @@ Supply your own bounded `journal`; this does not add browser console behavior. W
296
329
  | `nestedOperation(fn)` | During setup, mark a host operation authorized to run nested source. Requires declared and granted `source:nested`. |
297
330
  | `evaluateNested(source)` | Only inside that extension's authorized operation. Completes before the enclosing call returns to guest code, shares scope/budgets, and propagates errors. Parallel nested evaluations and ordinary source reentry are rejected. |
298
331
 
332
+ Use `expandos: { maxKeys, maxKeyCodeUnits, assertActive? }` to allow guest assignment, deletion and enumeration of string and symbol fields. `maxKeys` must be 1–65,536; `maxKeyCodeUnits` must be 1–1,048,576 and counts string keys plus symbol descriptions in UTF-16 units. Guest graphs and closures remain subject to the realm's data budget. The optional synchronous `assertActive` hook must return `undefined` and can enforce the publisher's lifetime. Declared members, indexed names and prototype-related names remain protected. Expandos cannot be combined with `named`; arbitrary descriptors and prototype links remain unsupported.
333
+
299
334
  For a timer-shaped `schedule(callback, delay, ...args)`, register `context.retainGuestArguments(schedule, 2)`. The host receives normal callback/delay values and opaque `GuestReference` handles for the remaining arguments. Pass those handles to `context.invokeCallback(callback, { args })` to recover the original guest objects and observe mutations made after scheduling. References also work as callback receivers and host return values, including cycles, closures, primitives and live host objects.
300
335
 
336
+ For a trusted native buffer such as WebAssembly memory, use `context.createArrayBufferReference(buffer)` and return the handle from a host property or operation. Guest ArrayBuffer views then share its bytes with the host, preserving identity and bidirectional writes. Ordinary host buffers still copy. Shared, resizable, detached, subclassed and proxy buffers reject, as do buffers with own properties or symbols. After native memory growth detaches the old buffer, create a new reference to the new buffer; the old reference continues to denote the detached buffer.
337
+
301
338
  Release each reference when the host no longer needs it; returning it does not release it. Retained graphs count against data budgets and `limits.guestReferences`. Synchronous native failure releases references captured for that call; asynchronous operations must release theirs in host cleanup. Close revokes all remaining references. Handles cannot be inspected, used in another realm, or serialized into replay/error data. Unmarked operations still copy values.
302
339
 
303
340
  For a live collection, keep the elements in your adapter and expose virtual indices instead of declaring one getter per element:
@@ -376,10 +413,12 @@ For one-shot use, `run(source, { extensions, grants, ... })` accepts the same re
376
413
  | --- | --- |
377
414
  | `bindings` | Global input values and host functions; none by default. |
378
415
  | `modules` | Module names mapped to export records or Maps; none by default. |
416
+ | `importSpecifiers` | Optional exact names admitted beyond bare imports in harness execution; every name still requires explicit registration in `modules`. Supply the same allowlist to `restore` or snapshot replay. This does not load native, local, or network modules. |
379
417
  | `extensions`, `grants`, `builtinOverrides`, `limits` | Opt into a one-shot extension realm; see the supported options and lifetime rules above. |
380
418
  | `budget` | A `Budget` instance. Without one, only the default call-depth limit of 1,000 is configured. |
381
419
  | `signal` | Host `AbortSignal` for cancellation. |
382
420
  | `filename` | Diagnostic filename; defaults to `<input>`. |
421
+ | `sourceLocation` | Optional trusted callback mapping one-based guest stack `{ line, column }` positions to `{ filename, line, column }`. Return `undefined` to retain a generated frame. It changes diagnostics only; re-supply it when resuming snapshots. |
383
422
  | `entryPointArgs` | Arguments for invoking the default-exported function. Omit for top-level execution only. |
384
423
  | `importMeta` | Host-supplied fields exposed through `import.meta`. |
385
424
  | `sink` | Console destination with `log(...args)` and `error(...args)`; defaults to the host console. |
@@ -399,8 +438,12 @@ For one-shot use, `run(source, { extensions, grants, ... })` accepts the same re
399
438
  | `deadline` | Absolute epoch milliseconds or a `Date`, not a duration. |
400
439
  | `maxCallDepth` | Nested interpreter calls. |
401
440
  | `stringLength`, `arrayLength` | Individual string and array lengths. |
441
+ | `regexSourceLength` | Optional regex source cap; positive safe integer, unlimited when omitted. The general `stringLength` limit also applies. |
442
+ | `regexCompileAllocations` | Optional per-regex compilation allocation cap; positive safe integer, unlimited when omitted. Compilation still charges work and retained data against the shared budget. |
402
443
  | `dataSize` | Retained sandbox data units, not bytes of process memory. |
403
444
 
445
+ `JSON.parse` checks both parse paths before building native objects: input work counts toward steps and deadlines, array lengths and object member counts use `arrayLength`, and nesting uses `maxCallDepth` with an additional ceiling of 256 containers. Parsing requires room for a conservative temporary allocation bound of `16 * text.length + 8` data units alongside existing data; whitespace and duplicate keys count toward this bound.
446
+
404
447
  There are no runtime environment variables to set. `makeEnvModule({ allow, values? })` grants reads of names in `allow`; `values` supplies an explicit string map instead of reading the host's `process.env`. Disallowed reads throw `EnvAccessError`; allowed but unset names return `undefined`. Agent and MCP integrations may require their own credentials.
405
448
 
406
449
  <details>
@@ -426,7 +469,7 @@ Compiling stored module source enforces the owning budget's string-length
426
469
  limit and charges one step per UTF-16 source unit before parsing. Regex
427
470
  compilation retains its additional work charges.
428
471
 
429
- `deepCopyToSandbox(value)` and `deepCopyFromSandbox(value, { wrapClosure? })` convert supported values. `wrapClosure` lets the host choose how to represent an exported sandbox function. Not every native JavaScript object is convertible.
472
+ `deepCopyToSandbox(value)` and `deepCopyFromSandbox(value, { wrapClosure? })` convert supported values. `wrapClosure` lets the host choose how to represent an exported sandbox function. Not every native JavaScript object is convertible. When passing sandbox typed arrays to native APIs, use `deepCopyFromSandbox`: SDK-created views use internal wrappers and do not satisfy the host's native `ArrayBuffer.isView` check. Guest reflection and `ArrayBuffer.isView` retain their normal behavior.
430
473
 
431
474
  Native Promise imports accept genuine promises from other JavaScript realms,
432
475
  preserving aliases and copying fulfillment or rejection values. Own string-keyed
@@ -478,7 +521,7 @@ Factories return exports to register in `modules`; calling a factory alone does
478
521
  | --- | --- |
479
522
  | `makeAgentModule(spawnAgent, options?)` | Inject the agent runner. Options: `defaultRetry`, `onEvent`, `otelSink`. Exposes `spawn`, `spawn.retry`, and `spawn.parallel`; call options follow this table. |
480
523
  | `makeMcpModule(options)` | Required `servers` map: stdio `{ command, args?, cwd?, env? }` or HTTP `{ url, headers? }`. Options: `requestTimeoutMs` (30,000), `closeTimeoutMs` (1,000), `maxToolPages` (100), `signal`, and injected `fetch`/`spawn`. Named clients expose `tools`, `tool`, `toolBatch`, and `close`; close managed clients when finished. A custom connector function is also accepted. |
481
- | `makeFsModule(options?)` | Node-backed `{ root?, fs? }`, or shared-filesystem `{ adapter, root?, cwd?, signal? }`; do not combine `fs` and `adapter`. Node access without `root` is unconfined. With an adapter, `root` confines access and `cwd` selects the virtual relative-path base; without `root`, explicit `cwd` also confines access. Omitting both uses virtual `/`. Read text with `readFile(path, "utf8")`; see the [module methods](src/modules/fs.ts) and [filesystem package](../safe-fs/README.md). |
524
+ | `makeFsModule(options?)` | Node-backed `{ root?, fs? }`, or shared-filesystem `{ adapter, root?, cwd?, signal? }`; do not combine `fs` and `adapter`. Node access without `root` is unconfined. Rooted calls sharing the same adapter or Node implementation are serialized through path checks and backend completion to prevent guest namespace races. External host mutations or distinct adapters over the same storage require independent backend confinement. With an adapter, `root` confines access and `cwd` selects the virtual relative-path base; without `root`, explicit `cwd` also confines access. Omitting both uses virtual `/`. Read text with `readFile(path, "utf8")`; see the [module methods](src/modules/fs.ts) and [filesystem package](../safe-fs/README.md). |
482
525
  | `makeEnvModule(namesOrOptions)` | Allowed-name array or `{ allow, values? }`; exposes `get(name)`. `parseEnvConfig(json)` accepts the object form. |
483
526
  | `makeTimeModule(options?)` | `now`, `random`, `seed`, `signal`; exposes `now`, `random`, `sleep`, `uuid`. Defaults to host time/randomness; `seed` makes the random generator deterministic, and explicit `random` takes precedence. |
484
527
  | `makeLogModule(sink)` | Sends timestamped `info`, `error`, and `event` entries to your callback. |
@@ -508,7 +551,7 @@ functions can still be retained by custom Promise constructors.
508
551
  - `restore(snapshot, { source })` validates state for compatible source; pass it as `run`'s `snapshot` option. It does not run the program.
509
552
  - `new FileSnapshotBackend(path, { writeMaxAttempts?, writeRetryDelayMs? })` defaults to 3 write attempts and a 100 ms retry delay.
510
553
  - `createReplayableRandom({ seed?, snapshot? })` supplies `next`, `seed`, `snapshot`, and `restore` for reproducible random sequences.
511
- - `declareHostOperation(fn, policy, { onReplay? })` declares `re-issue` or `read-side-effect` recovery policy. `registerPendingHostCallPolicy({ moduleId, operation, policy })` registers it by name. Only mark operations re-issuable when repeating them is acceptable; a declaration does not implement deduplication or external recovery.
554
+ - `declareHostOperation(fn, policy, { onReplay?, awaitResult? })` declares `re-issue` or `read-side-effect` recovery policy. `registerPendingHostCallPolicy({ moduleId, operation, policy })` registers it by name. Only mark operations re-issuable when repeating them is acceptable; a declaration does not implement deduplication or external recovery. With `awaitResult: true`, an asynchronous host operation completes before the guest call returns its copied value or throws its error, without exposing a guest Promise. This is an explicit host capability; the host event loop still runs, and cancellation, value budgets, and host-call recovery still apply.
512
555
  - `inspectSnapshotMigration(snapshot, { source })` inspects outstanding work. `migrateSnapshot(snapshot, { source, targetSource, state, reconciliation })` creates a continuation checkpoint. Reconciliation supplies `checkpointDigest`, `quiescent`, and `calls`; each call has `callId` and disposition `not-performed`, `fulfilled` with `value`, or `rejected` with `reason`.
513
556
  - `migrateSnapshotFile(options)` accepts `snapshotPath`, `sourcePath`, `targetSourcePath`, `planPath`, `outputPath`, `inspect`, `dryRun`, and `cwd`. Inspect mode needs the checkpoint and original source; migration also needs the target, plan, and new output path. See [continuation migration](MIGRATION.md) before changing a checkpointed program.
514
557
 
@@ -13,7 +13,7 @@ export interface FileSystem {
13
13
  }): Promise<void>;
14
14
  mkdir(path: string, options?: {
15
15
  recursive: boolean;
16
- }): Promise<void>;
16
+ }): Promise<unknown>;
17
17
  rename(oldPath: string, newPath: string): Promise<void>;
18
18
  unlink(path: string): Promise<void>;
19
19
  rm?(path: string, options?: {
@@ -52,6 +52,8 @@ export interface PathMapper {
52
52
  }): string;
53
53
  }
54
54
  export interface MutationContext {
55
+ /** Path operations for the filesystem namespace; defaults to native host paths. */
56
+ paths?: typeof import("node:path");
55
57
  /** Filesystem interface - required */
56
58
  fs: FileSystem;
57
59
  /** Home directory for ~ expansion - required */
@@ -8,7 +8,7 @@ import {
8
8
  numericTypedArrayConstructors,
9
9
  parseModule,
10
10
  tokenize
11
- } from "./chunk-IDQ67DY2.js";
11
+ } from "./chunk-RYVHEOHM.js";
12
12
 
13
13
  // packages/safe-js/src/lint/rules/AS001.ts
14
14
  function AS001(source, options = {}) {
@@ -708,6 +708,7 @@ var KNOWN_RUNTIME_GLOBALS = [
708
708
  "structuredClone",
709
709
  "SyntaxError",
710
710
  "Temporal",
711
+ "TextEncoder",
711
712
  "TypeError",
712
713
  "URIError",
713
714
  "undefined",
@@ -11176,4 +11177,4 @@ function hasOnlyRegexLiteralDiagnostics(diagnostics) {
11176
11177
  export {
11177
11178
  lint
11178
11179
  };
11179
- //# sourceMappingURL=chunk-B2SQLK4O.js.map
11180
+ //# sourceMappingURL=chunk-3QQYJ4RQ.js.map