@declaw/sdk 1.1.9 → 1.1.11

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/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to the Declaw TypeScript / JavaScript SDK are documented in
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.1.11]
9
+
10
+ ### Added
11
+
12
+ - `sandbox.stdio.start(cmd)` — native interactive stdio for sandboxed
13
+ processes. Returns a `StdioProcess` handle with `sendStdin()`,
14
+ `closeStdin()`, `stream()`, `kill()`, and `wait()`. Supports
15
+ callbacks (`onStdout`, `onStderr`) and async iteration.
16
+ - `sandbox.getHost(port)` — inbound HTTP port proxy URL for accessing
17
+ services running inside the sandbox.
18
+ - `sandbox.getMcpUrl()` — convenience URL for MCP servers on port 50005.
19
+
8
20
  ## [1.1.8]
9
21
 
10
22
  ### Documentation
package/dist/index.cjs CHANGED
@@ -59,6 +59,8 @@ __export(index_exports, {
59
59
  SandboxPaginator: () => SandboxPaginator,
60
60
  SandboxState: () => SandboxState,
61
61
  SnapshotPaginator: () => SnapshotPaginator,
62
+ Stdio: () => Stdio,
63
+ StdioProcess: () => StdioProcess,
62
64
  Template: () => Template,
63
65
  TemplateBase: () => TemplateBase,
64
66
  TemplateError: () => TemplateError,
@@ -1885,6 +1887,136 @@ var Pty = class {
1885
1887
  }
1886
1888
  };
1887
1889
 
1890
+ // src/sandbox/stdio/stdio.ts
1891
+ var import_stream2 = require("eventsource-parser/stream");
1892
+ var StdioProcess = class {
1893
+ cmdId;
1894
+ sandboxId;
1895
+ client;
1896
+ lastEntryId = 0;
1897
+ _exitCode = null;
1898
+ _bgStream = null;
1899
+ constructor(cmdId, sandboxId, client, opts) {
1900
+ this.cmdId = cmdId;
1901
+ this.sandboxId = sandboxId;
1902
+ this.client = client;
1903
+ if (opts?.onStdout || opts?.onStderr) {
1904
+ this._bgStream = this.stream({
1905
+ onStdout: opts.onStdout,
1906
+ onStderr: opts.onStderr
1907
+ });
1908
+ }
1909
+ }
1910
+ get exitCode() {
1911
+ return this._exitCode;
1912
+ }
1913
+ async sendStdin(data, requestTimeout) {
1914
+ const raw = typeof data === "string" ? new TextEncoder().encode(data) : data;
1915
+ let binary = "";
1916
+ for (let i = 0; i < raw.length; i++) {
1917
+ binary += String.fromCharCode(raw[i]);
1918
+ }
1919
+ const encoded = btoa(binary);
1920
+ await this.client.post(
1921
+ `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin`,
1922
+ {
1923
+ json: { data: encoded },
1924
+ timeout: requestTimeout
1925
+ }
1926
+ );
1927
+ }
1928
+ async closeStdin(requestTimeout) {
1929
+ await this.client.post(
1930
+ `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stdin/close`,
1931
+ { timeout: requestTimeout }
1932
+ );
1933
+ }
1934
+ async kill(requestTimeout) {
1935
+ const resp = await this.client.delete(
1936
+ `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}`,
1937
+ { timeout: requestTimeout }
1938
+ );
1939
+ return Boolean(resp.killed);
1940
+ }
1941
+ async wait() {
1942
+ if (this._bgStream) {
1943
+ return this._bgStream;
1944
+ }
1945
+ return this.stream();
1946
+ }
1947
+ async stream(opts) {
1948
+ if (this._bgStream && !opts) {
1949
+ return this._bgStream;
1950
+ }
1951
+ let url = `/sandboxes/${this.sandboxId}/stdio/${this.cmdId}/stream`;
1952
+ if (this.lastEntryId > 0) {
1953
+ url += `?last_entry_id=${this.lastEntryId}`;
1954
+ }
1955
+ const response = await this.client.streamGet(url);
1956
+ const stream = response.body;
1957
+ if (!stream) {
1958
+ throw new SandboxError("No response body for stdio stream");
1959
+ }
1960
+ const eventStream = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new import_stream2.EventSourceParserStream());
1961
+ for await (const event of eventStream) {
1962
+ if (event.event === "exit") {
1963
+ try {
1964
+ const parsed = JSON.parse(event.data);
1965
+ this._exitCode = parsed.exit_code ?? -1;
1966
+ } catch {
1967
+ this._exitCode = -1;
1968
+ }
1969
+ break;
1970
+ }
1971
+ if (event.event === "stdout" || event.event === "stderr") {
1972
+ try {
1973
+ const parsed = JSON.parse(event.data);
1974
+ const entryId = parsed.entry_id ?? 0;
1975
+ if (entryId > this.lastEntryId) {
1976
+ this.lastEntryId = entryId;
1977
+ }
1978
+ const raw = atob(parsed.data ?? "");
1979
+ const bytes = new Uint8Array(raw.length);
1980
+ for (let i = 0; i < raw.length; i++) {
1981
+ bytes[i] = raw.charCodeAt(i);
1982
+ }
1983
+ if (event.event === "stdout" && opts?.onStdout) {
1984
+ opts.onStdout(bytes);
1985
+ } else if (event.event === "stderr" && opts?.onStderr) {
1986
+ opts.onStderr(bytes);
1987
+ }
1988
+ } catch {
1989
+ continue;
1990
+ }
1991
+ }
1992
+ }
1993
+ return { exitCode: this._exitCode ?? -1 };
1994
+ }
1995
+ };
1996
+ var Stdio = class {
1997
+ sandboxId;
1998
+ client;
1999
+ constructor(sandboxId, client) {
2000
+ this.sandboxId = sandboxId;
2001
+ this.client = client;
2002
+ }
2003
+ async start(cmd, opts) {
2004
+ const user = opts?.user ?? "user";
2005
+ const body = { cmd, user };
2006
+ if (opts?.envs) body.envs = opts.envs;
2007
+ if (opts?.cwd) body.cwd = opts.cwd;
2008
+ const data = await this.client.post(
2009
+ `/sandboxes/${this.sandboxId}/stdio`,
2010
+ { json: body, timeout: opts?.requestTimeout }
2011
+ );
2012
+ const cmdId = data.cmd_id;
2013
+ return new StdioProcess(cmdId, this.sandboxId, this.client, {
2014
+ onStdout: opts?.onStdout,
2015
+ onStderr: opts?.onStderr
2016
+ });
2017
+ }
2018
+ };
2019
+
1888
2020
  // src/volumes/models.ts
1889
2021
  function parseVolumeInfo(data) {
1890
2022
  return {
@@ -1924,6 +2056,7 @@ var Sandbox = class _Sandbox {
1924
2056
  _commands;
1925
2057
  _files;
1926
2058
  _pty;
2059
+ _stdio;
1927
2060
  constructor(sandboxId, config, client, envdAccessToken, sandboxDomain, trafficAccessToken) {
1928
2061
  this._sandboxId = sandboxId;
1929
2062
  this._config = config;
@@ -1934,6 +2067,7 @@ var Sandbox = class _Sandbox {
1934
2067
  this._commands = new Commands(sandboxId, client);
1935
2068
  this._files = new Filesystem(sandboxId, client);
1936
2069
  this._pty = new Pty(sandboxId, client);
2070
+ this._stdio = new Stdio(sandboxId, client);
1937
2071
  }
1938
2072
  /** The unique sandbox identifier. */
1939
2073
  get sandboxId() {
@@ -1967,6 +2101,10 @@ var Sandbox = class _Sandbox {
1967
2101
  get pty() {
1968
2102
  return this._pty;
1969
2103
  }
2104
+ /** Stdio sub-module for interactive subprocess sessions with stdin pipe. */
2105
+ get stdio() {
2106
+ return this._stdio;
2107
+ }
1970
2108
  /**
1971
2109
  * Base URL for this sandbox's namespace on the Declaw API.
1972
2110
  *
@@ -1980,17 +2118,15 @@ var Sandbox = class _Sandbox {
1980
2118
  /**
1981
2119
  * Return the path-based URL that reverse-proxies to `port` inside the sandbox.
1982
2120
  *
1983
- * Note: the reverse-proxy backend is not yet deployed; calls to the returned
1984
- * URL will 404 until that feature ships. The URL shape is stable and safe to
1985
- * script against.
2121
+ * Requires `allowPublicTraffic` to be enabled on the sandbox's network
2122
+ * config (the default). The returned URL is authenticated via the same
2123
+ * API key as all other sandbox operations.
1986
2124
  */
1987
2125
  getHost(port) {
1988
2126
  return `${this.envdApiUrl}/ports/${port}`;
1989
2127
  }
1990
2128
  /**
1991
2129
  * Return the URL for an MCP server listening on port 50005 inside the sandbox.
1992
- *
1993
- * Same deployment caveat as {@link getHost}.
1994
2130
  */
1995
2131
  getMcpUrl() {
1996
2132
  return `${this.getHost(MCP_PORT)}/mcp`;
@@ -2826,6 +2962,8 @@ var Volumes = class {
2826
2962
  SandboxPaginator,
2827
2963
  SandboxState,
2828
2964
  SnapshotPaginator,
2965
+ Stdio,
2966
+ StdioProcess,
2829
2967
  Template,
2830
2968
  TemplateBase,
2831
2969
  TemplateError,