sandboxedjs 0.1.93 → 0.1.94

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.
package/dist/agent.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as Container } from './container-BGmhPbSD.cjs';
2
- import './contracts-BkWBTH8E.cjs';
1
+ import { C as Container } from './container-C3cgcnXZ.cjs';
2
+ import './contracts-B6SHFjma.cjs';
3
3
 
4
4
  /**
5
5
  * Structural copies of the LangChain Deep Agents backend contract.
package/dist/agent.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as Container } from './container-DCwYX_Cx.js';
2
- import './contracts-BkWBTH8E.js';
1
+ import { C as Container } from './container-WEYRUg6Q.js';
2
+ import './contracts-B6SHFjma.js';
3
3
 
4
4
  /**
5
5
  * Structural copies of the LangChain Deep Agents backend contract.
@@ -1,4 +1,4 @@
1
- import { V as Vfs, C as Cred, f as RuntimePod, O as OutboundPolicy, D as DirEntry, p as Stats } from './contracts-BkWBTH8E.cjs';
1
+ import { V as Vfs, C as Cred, f as RuntimePod, O as OutboundPolicy, D as DirEntry, p as Stats } from './contracts-B6SHFjma.cjs';
2
2
 
3
3
  /**
4
4
  * Byte streams for stdin/stdout/stderr, pipelines and redirections.
@@ -1,4 +1,4 @@
1
- import { V as Vfs, C as Cred, f as RuntimePod, O as OutboundPolicy, D as DirEntry, p as Stats } from './contracts-BkWBTH8E.js';
1
+ import { V as Vfs, C as Cred, f as RuntimePod, O as OutboundPolicy, D as DirEntry, p as Stats } from './contracts-B6SHFjma.js';
2
2
 
3
3
  /**
4
4
  * Byte streams for stdin/stdout/stderr, pipelines and redirections.
@@ -95,6 +95,101 @@ declare function createChildProcessModule(spawnChild: SpawnChild, defaultCwd: ()
95
95
  ipc?: IpcTransport;
96
96
  }): Record<string, unknown>;
97
97
 
98
+ /**
99
+ * The outbound network policy, as plain functions every client consults.
100
+ *
101
+ * The container has several ways out — `curl` and `wget` in the shell, `http`,
102
+ * `https`, `fetch` and `WebSocket` in a Node program, sockets in Python — and
103
+ * they used to decide separately. Only the shell asked: a Node program's
104
+ * `fetch("https://…")` reached the internet from a container booted with
105
+ * outbound access off. One policy, applied at each exit, is what makes
106
+ * `network: { allowOutbound: false }` mean what it says.
107
+ *
108
+ * Loopback is not "outbound" at all. `127.0.0.1` inside the container is the
109
+ * container, so those requests are routed to its own servers and never handed
110
+ * to the host's network stack, whatever the policy allows.
111
+ */
112
+ interface OutboundPolicy {
113
+ /** Whether requests may leave the container at all. */
114
+ allowOutbound: boolean;
115
+ /** When outbound is on, the hosts it may reach (subdomains included). `null` means any. */
116
+ allowedHosts: string[] | null;
117
+ }
118
+
119
+ /**
120
+ * Outbound TCP: names resolved by the host, connections dialled by the host.
121
+ *
122
+ * Until now a guest socket could reach only loopback. Everything that speaks a
123
+ * protocol other than HTTP -- Postgres, Redis, SMTP, an LLM gateway over a raw
124
+ * stream -- was therefore unreachable, and so was every HTTP client that opens
125
+ * its own socket rather than going through the egress. Extensions do not help:
126
+ * no wheel can create a connection the container cannot make.
127
+ *
128
+ * Two things are needed, and both belong to the host.
129
+ *
130
+ * **Names.** Emscripten's own `getaddrinfo` invents an address per hostname and
131
+ * keeps the table inside the guest's JavaScript module, where the kernel cannot
132
+ * see it -- so a later `connect` arrived as an address nobody could map back to
133
+ * a name. Resolution is therefore a host operation: the host allocates the
134
+ * address, remembers which name it stands for, and recognises it on connect. A
135
+ * guest still sees ordinary addresses, `getaddrinfo` still returns tuples, and
136
+ * reverse lookup answers.
137
+ *
138
+ * **The connection.** Only the host can open a socket. In Node that is
139
+ * `node:net`; in a browser there is no such thing, and a page cannot be given
140
+ * one, so a browser host supplies no dialer and outbound connects fail with a
141
+ * message that says to use the HTTP egress instead.
142
+ *
143
+ * The outbound policy applies here as it does at every other exit, and it is
144
+ * applied to the *name* the guest asked for, not to the address it was handed.
145
+ */
146
+
147
+ /** A real connection the host owns, as this module needs to use it. */
148
+ interface HostTcpConnection {
149
+ write(bytes: Uint8Array): void;
150
+ /** Half-close: the guest has finished writing. */
151
+ end(): void;
152
+ close(): void;
153
+ onData(handler: (bytes: Uint8Array) => void): void;
154
+ onClose(handler: () => void): void;
155
+ /** The address the host actually connected to, for `getpeername`. */
156
+ readonly remoteAddress: string;
157
+ readonly remotePort: number;
158
+ readonly localPort: number;
159
+ }
160
+ /** What a host must provide for a guest to reach the network. */
161
+ interface TcpDialer {
162
+ (host: string, port: number): Promise<HostTcpConnection>;
163
+ }
164
+ declare class OutboundTcp {
165
+ private readonly policy;
166
+ private readonly dialer;
167
+ private readonly byName;
168
+ private readonly byAddress;
169
+ private next;
170
+ constructor(policy: () => OutboundPolicy, dialer: TcpDialer | null);
171
+ /** Whether this address was handed out by `resolve`. */
172
+ knows(address: string): boolean;
173
+ hostnameFor(address: string): string | undefined;
174
+ /**
175
+ * The address for `hostname`, allocating one on first use.
176
+ *
177
+ * Refusal happens here as well as at connect, because a name that cannot be
178
+ * reached should fail as a resolution failure -- which is what every client
179
+ * reports as "unknown host" rather than as a mid-connection error.
180
+ */
181
+ resolve(hostname: string): string;
182
+ /** Open a connection to a resolved address, or to a literal one. */
183
+ connect(address: string, port: number, local: {
184
+ address: string;
185
+ port: number;
186
+ }): Promise<{
187
+ connection: VirtualTcpConnection;
188
+ host: HostTcpConnection;
189
+ }>;
190
+ private allowed;
191
+ }
192
+
98
193
  type FileKind = "file" | "directory" | "symlink" | "chardev" | "blockdev" | "fifo" | "socket";
99
194
  /** Render as `drwxr-xr-x`, honouring setuid/setgid/sticky. */
100
195
  declare function formatMode(mode: number): string;
@@ -368,36 +463,29 @@ declare class VirtualTcpListener {
368
463
  declare class VirtualTcpNetwork {
369
464
  private readonly occupied?;
370
465
  private readonly listeners;
466
+ /** The host's outbound stack, when this host can open sockets at all. */
467
+ outbound: OutboundTcp | null;
468
+ /**
469
+ * Ports held by in-container servers that are not sockets.
470
+ *
471
+ * A JavaScript HTTP server in the container is registered with the request
472
+ * router and never binds one of these sockets, so a guest connecting to its
473
+ * port found nothing listening. Before sockets could leave the container
474
+ * this did not arise -- every guest client went out through the egress --
475
+ * and afterwards `urllib` dialling a container server got ECONNREFUSED.
476
+ */
477
+ loopbackHttp: ((port: number, connection: VirtualTcpConnection) => boolean) | null;
371
478
  constructor(occupied?: ((port: number) => boolean) | undefined);
372
479
  listen(port: number, address?: string, backlog?: number): VirtualTcpListener;
373
480
  close(listener: VirtualTcpListener): void;
374
481
  connect(port: number, localPort?: number, localAddress?: string): VirtualTcpConnection;
482
+ /** A connection to a port an in-container server holds without a socket. */
483
+ private connectToNonSocketServer;
375
484
  hasListener(port: number): boolean;
376
485
  ports(): number[];
377
486
  closeAll(): void;
378
487
  }
379
488
 
380
- /**
381
- * The outbound network policy, as plain functions every client consults.
382
- *
383
- * The container has several ways out — `curl` and `wget` in the shell, `http`,
384
- * `https`, `fetch` and `WebSocket` in a Node program, sockets in Python — and
385
- * they used to decide separately. Only the shell asked: a Node program's
386
- * `fetch("https://…")` reached the internet from a container booted with
387
- * outbound access off. One policy, applied at each exit, is what makes
388
- * `network: { allowOutbound: false }` mean what it says.
389
- *
390
- * Loopback is not "outbound" at all. `127.0.0.1` inside the container is the
391
- * container, so those requests are routed to its own servers and never handed
392
- * to the host's network stack, whatever the policy allows.
393
- */
394
- interface OutboundPolicy {
395
- /** Whether requests may leave the container at all. */
396
- allowOutbound: boolean;
397
- /** When outbound is on, the hosts it may reach (subdomains included). `null` means any. */
398
- allowedHosts: string[] | null;
399
- }
400
-
401
489
  /**
402
490
  * Clean-room contracts between SandboxedJS and its JavaScript runtime.
403
491
  *
@@ -95,6 +95,101 @@ declare function createChildProcessModule(spawnChild: SpawnChild, defaultCwd: ()
95
95
  ipc?: IpcTransport;
96
96
  }): Record<string, unknown>;
97
97
 
98
+ /**
99
+ * The outbound network policy, as plain functions every client consults.
100
+ *
101
+ * The container has several ways out — `curl` and `wget` in the shell, `http`,
102
+ * `https`, `fetch` and `WebSocket` in a Node program, sockets in Python — and
103
+ * they used to decide separately. Only the shell asked: a Node program's
104
+ * `fetch("https://…")` reached the internet from a container booted with
105
+ * outbound access off. One policy, applied at each exit, is what makes
106
+ * `network: { allowOutbound: false }` mean what it says.
107
+ *
108
+ * Loopback is not "outbound" at all. `127.0.0.1` inside the container is the
109
+ * container, so those requests are routed to its own servers and never handed
110
+ * to the host's network stack, whatever the policy allows.
111
+ */
112
+ interface OutboundPolicy {
113
+ /** Whether requests may leave the container at all. */
114
+ allowOutbound: boolean;
115
+ /** When outbound is on, the hosts it may reach (subdomains included). `null` means any. */
116
+ allowedHosts: string[] | null;
117
+ }
118
+
119
+ /**
120
+ * Outbound TCP: names resolved by the host, connections dialled by the host.
121
+ *
122
+ * Until now a guest socket could reach only loopback. Everything that speaks a
123
+ * protocol other than HTTP -- Postgres, Redis, SMTP, an LLM gateway over a raw
124
+ * stream -- was therefore unreachable, and so was every HTTP client that opens
125
+ * its own socket rather than going through the egress. Extensions do not help:
126
+ * no wheel can create a connection the container cannot make.
127
+ *
128
+ * Two things are needed, and both belong to the host.
129
+ *
130
+ * **Names.** Emscripten's own `getaddrinfo` invents an address per hostname and
131
+ * keeps the table inside the guest's JavaScript module, where the kernel cannot
132
+ * see it -- so a later `connect` arrived as an address nobody could map back to
133
+ * a name. Resolution is therefore a host operation: the host allocates the
134
+ * address, remembers which name it stands for, and recognises it on connect. A
135
+ * guest still sees ordinary addresses, `getaddrinfo` still returns tuples, and
136
+ * reverse lookup answers.
137
+ *
138
+ * **The connection.** Only the host can open a socket. In Node that is
139
+ * `node:net`; in a browser there is no such thing, and a page cannot be given
140
+ * one, so a browser host supplies no dialer and outbound connects fail with a
141
+ * message that says to use the HTTP egress instead.
142
+ *
143
+ * The outbound policy applies here as it does at every other exit, and it is
144
+ * applied to the *name* the guest asked for, not to the address it was handed.
145
+ */
146
+
147
+ /** A real connection the host owns, as this module needs to use it. */
148
+ interface HostTcpConnection {
149
+ write(bytes: Uint8Array): void;
150
+ /** Half-close: the guest has finished writing. */
151
+ end(): void;
152
+ close(): void;
153
+ onData(handler: (bytes: Uint8Array) => void): void;
154
+ onClose(handler: () => void): void;
155
+ /** The address the host actually connected to, for `getpeername`. */
156
+ readonly remoteAddress: string;
157
+ readonly remotePort: number;
158
+ readonly localPort: number;
159
+ }
160
+ /** What a host must provide for a guest to reach the network. */
161
+ interface TcpDialer {
162
+ (host: string, port: number): Promise<HostTcpConnection>;
163
+ }
164
+ declare class OutboundTcp {
165
+ private readonly policy;
166
+ private readonly dialer;
167
+ private readonly byName;
168
+ private readonly byAddress;
169
+ private next;
170
+ constructor(policy: () => OutboundPolicy, dialer: TcpDialer | null);
171
+ /** Whether this address was handed out by `resolve`. */
172
+ knows(address: string): boolean;
173
+ hostnameFor(address: string): string | undefined;
174
+ /**
175
+ * The address for `hostname`, allocating one on first use.
176
+ *
177
+ * Refusal happens here as well as at connect, because a name that cannot be
178
+ * reached should fail as a resolution failure -- which is what every client
179
+ * reports as "unknown host" rather than as a mid-connection error.
180
+ */
181
+ resolve(hostname: string): string;
182
+ /** Open a connection to a resolved address, or to a literal one. */
183
+ connect(address: string, port: number, local: {
184
+ address: string;
185
+ port: number;
186
+ }): Promise<{
187
+ connection: VirtualTcpConnection;
188
+ host: HostTcpConnection;
189
+ }>;
190
+ private allowed;
191
+ }
192
+
98
193
  type FileKind = "file" | "directory" | "symlink" | "chardev" | "blockdev" | "fifo" | "socket";
99
194
  /** Render as `drwxr-xr-x`, honouring setuid/setgid/sticky. */
100
195
  declare function formatMode(mode: number): string;
@@ -368,36 +463,29 @@ declare class VirtualTcpListener {
368
463
  declare class VirtualTcpNetwork {
369
464
  private readonly occupied?;
370
465
  private readonly listeners;
466
+ /** The host's outbound stack, when this host can open sockets at all. */
467
+ outbound: OutboundTcp | null;
468
+ /**
469
+ * Ports held by in-container servers that are not sockets.
470
+ *
471
+ * A JavaScript HTTP server in the container is registered with the request
472
+ * router and never binds one of these sockets, so a guest connecting to its
473
+ * port found nothing listening. Before sockets could leave the container
474
+ * this did not arise -- every guest client went out through the egress --
475
+ * and afterwards `urllib` dialling a container server got ECONNREFUSED.
476
+ */
477
+ loopbackHttp: ((port: number, connection: VirtualTcpConnection) => boolean) | null;
371
478
  constructor(occupied?: ((port: number) => boolean) | undefined);
372
479
  listen(port: number, address?: string, backlog?: number): VirtualTcpListener;
373
480
  close(listener: VirtualTcpListener): void;
374
481
  connect(port: number, localPort?: number, localAddress?: string): VirtualTcpConnection;
482
+ /** A connection to a port an in-container server holds without a socket. */
483
+ private connectToNonSocketServer;
375
484
  hasListener(port: number): boolean;
376
485
  ports(): number[];
377
486
  closeAll(): void;
378
487
  }
379
488
 
380
- /**
381
- * The outbound network policy, as plain functions every client consults.
382
- *
383
- * The container has several ways out — `curl` and `wget` in the shell, `http`,
384
- * `https`, `fetch` and `WebSocket` in a Node program, sockets in Python — and
385
- * they used to decide separately. Only the shell asked: a Node program's
386
- * `fetch("https://…")` reached the internet from a container booted with
387
- * outbound access off. One policy, applied at each exit, is what makes
388
- * `network: { allowOutbound: false }` mean what it says.
389
- *
390
- * Loopback is not "outbound" at all. `127.0.0.1` inside the container is the
391
- * container, so those requests are routed to its own servers and never handed
392
- * to the host's network stack, whatever the policy allows.
393
- */
394
- interface OutboundPolicy {
395
- /** Whether requests may leave the container at all. */
396
- allowOutbound: boolean;
397
- /** When outbound is on, the hosts it may reach (subdomains included). `null` means any. */
398
- allowedHosts: string[] | null;
399
- }
400
-
401
489
  /**
402
490
  * Clean-room contracts between SandboxedJS and its JavaScript runtime.
403
491
  *