@miosa/sdk 0.3.0 → 1.1.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { randomUUID } from 'crypto';
1
+ import { randomUUID, createHmac, timingSafeEqual } from 'crypto';
2
2
  import EventEmitter from 'events';
3
3
 
4
4
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
@@ -662,10 +662,11 @@ var ApiKeys = class {
662
662
  return listItems(data);
663
663
  }
664
664
  async create(params) {
665
- const { idempotencyKey: ikey, expiresAt, ...rest } = params;
665
+ const { idempotencyKey: ikey, expiresAt, workspaceId, ...rest } = params;
666
666
  const body = stripUndefined2({
667
667
  ...rest,
668
- expires_at: expiresAt ?? rest.expires_at
668
+ expires_at: expiresAt ?? rest.expires_at,
669
+ workspace_id: workspaceId ?? rest.workspace_id
669
670
  });
670
671
  const data = await this.http.request("/api-keys", {
671
672
  method: "POST",
@@ -1695,6 +1696,690 @@ var Desktop = class {
1695
1696
  return this.http.post(`${this.base()}/launch`, params);
1696
1697
  }
1697
1698
  };
1699
+
1700
+ // src/resources/egressAudit.ts
1701
+ function unwrap17(payload) {
1702
+ if (payload && typeof payload === "object") {
1703
+ const p = payload;
1704
+ for (const k of ["data", "event", "items"]) {
1705
+ if (k in p) return p[k];
1706
+ }
1707
+ }
1708
+ return payload;
1709
+ }
1710
+ function unwrapList8(payload) {
1711
+ if (Array.isArray(payload)) return payload;
1712
+ if (payload && typeof payload === "object") {
1713
+ const p = payload;
1714
+ for (const k of ["data", "events", "audit", "items"]) {
1715
+ if (Array.isArray(p[k])) return p[k];
1716
+ }
1717
+ }
1718
+ return [];
1719
+ }
1720
+ function stripUndefined5(input) {
1721
+ return Object.fromEntries(
1722
+ Object.entries(input).filter(([, v]) => v !== void 0)
1723
+ );
1724
+ }
1725
+ function pickFirst(...values) {
1726
+ for (const v of values) if (v !== void 0) return v;
1727
+ return void 0;
1728
+ }
1729
+ function listQuery(params) {
1730
+ return stripUndefined5({
1731
+ resource_id: pickFirst(params.resourceId, params.resource_id),
1732
+ resource_type: pickFirst(params.resourceType, params.resource_type),
1733
+ host: params.host,
1734
+ action: params.action,
1735
+ since: params.since,
1736
+ until: params.until,
1737
+ limit: params.limit,
1738
+ cursor: params.cursor,
1739
+ external_user_id: pickFirst(params.externalUserId, params.external_user_id),
1740
+ external_workspace_id: pickFirst(
1741
+ params.externalWorkspaceId,
1742
+ params.external_workspace_id
1743
+ )
1744
+ });
1745
+ }
1746
+ function sleep2(ms) {
1747
+ return new Promise((resolve) => setTimeout(resolve, ms));
1748
+ }
1749
+ var EgressAudit = class {
1750
+ constructor(http) {
1751
+ this.http = http;
1752
+ }
1753
+ http;
1754
+ /** List audit events with optional filters. */
1755
+ async list(params = {}) {
1756
+ const data = await this.http.get(
1757
+ "/egress/audit",
1758
+ listQuery(params)
1759
+ );
1760
+ return unwrapList8(data);
1761
+ }
1762
+ /** Get a single audit event by id. */
1763
+ async get(id) {
1764
+ const data = await this.http.get(
1765
+ `/egress/audit/${id}`
1766
+ );
1767
+ return unwrap17(data);
1768
+ }
1769
+ /**
1770
+ * Long-poll the audit endpoint and yield new events as they appear.
1771
+ *
1772
+ * Tenant-wide `client.audit.tail()` is REST-based long polling. A
1773
+ * live WebSocket / SSE tail is only available for the sandbox-scoped
1774
+ * variant — see {@link SandboxAudit.tail}.
1775
+ */
1776
+ async *tail(params = {}) {
1777
+ const pollMs = params.pollIntervalMs ?? 2e3;
1778
+ let since = params.since;
1779
+ const seen = /* @__PURE__ */ new Set();
1780
+ while (true) {
1781
+ const queryParams = { ...params };
1782
+ if (since !== void 0) queryParams.since = since;
1783
+ const data = await this.http.get(
1784
+ "/egress/audit",
1785
+ listQuery(queryParams)
1786
+ );
1787
+ const events = unwrapList8(data);
1788
+ for (const event of events) {
1789
+ if (event.id && seen.has(event.id)) continue;
1790
+ if (event.id) seen.add(event.id);
1791
+ yield event;
1792
+ const ts = event.inserted_at ?? event.timestamp;
1793
+ if (typeof ts === "string") since = ts;
1794
+ }
1795
+ await sleep2(pollMs);
1796
+ }
1797
+ }
1798
+ };
1799
+ var SandboxAudit = class {
1800
+ constructor(http, resourceId) {
1801
+ this.http = http;
1802
+ this.resourceId = resourceId;
1803
+ this.delegate = new EgressAudit(http);
1804
+ }
1805
+ http;
1806
+ resourceId;
1807
+ resourceType = "sandbox";
1808
+ delegate;
1809
+ list(params = {}) {
1810
+ return this.delegate.list({
1811
+ ...params,
1812
+ resource_id: params.resourceId ?? params.resource_id ?? this.resourceId,
1813
+ resource_type: params.resourceType ?? params.resource_type ?? this.resourceType
1814
+ });
1815
+ }
1816
+ get(id) {
1817
+ return this.delegate.get(id);
1818
+ }
1819
+ /** SSE tail of the sandbox-scoped audit stream. */
1820
+ async *tail(params = {}) {
1821
+ const streamPath = this.resourceType === "sandbox" ? `/sandboxes/${this.resourceId}/audit/stream` : `/computers/${this.resourceId}/audit/stream`;
1822
+ try {
1823
+ const stream = this.http.stream(streamPath, {
1824
+ method: "GET"
1825
+ });
1826
+ for await (const event of stream) {
1827
+ yield event;
1828
+ }
1829
+ } catch {
1830
+ yield* this.delegate.tail({
1831
+ ...params,
1832
+ resource_id: this.resourceId,
1833
+ resource_type: this.resourceType
1834
+ });
1835
+ }
1836
+ }
1837
+ };
1838
+ var ComputerAudit = class extends SandboxAudit {
1839
+ resourceType = "computer";
1840
+ };
1841
+
1842
+ // src/resources/egressNetwork.ts
1843
+ function unwrap18(payload) {
1844
+ if (payload && typeof payload === "object") {
1845
+ const p = payload;
1846
+ for (const k of ["data", "policy", "rule", "items"]) {
1847
+ if (k in p) return p[k];
1848
+ }
1849
+ }
1850
+ return payload;
1851
+ }
1852
+ function unwrapList9(payload) {
1853
+ if (Array.isArray(payload)) return payload;
1854
+ if (payload && typeof payload === "object") {
1855
+ const p = payload;
1856
+ for (const k of [
1857
+ "data",
1858
+ "policies",
1859
+ "rules",
1860
+ "allowlist",
1861
+ "suggestions",
1862
+ "items"
1863
+ ]) {
1864
+ if (Array.isArray(p[k])) return p[k];
1865
+ }
1866
+ }
1867
+ return [];
1868
+ }
1869
+ function stripUndefined6(input) {
1870
+ return Object.fromEntries(
1871
+ Object.entries(input).filter(([, v]) => v !== void 0)
1872
+ );
1873
+ }
1874
+ function pickFirst2(...values) {
1875
+ for (const v of values) if (v !== void 0) return v;
1876
+ return void 0;
1877
+ }
1878
+ function ruleBody(host, params, effect) {
1879
+ return stripUndefined6({
1880
+ host,
1881
+ effect,
1882
+ methods: params.methods,
1883
+ path_glob: pickFirst2(params.pathGlob, params.path_glob),
1884
+ policy_id: pickFirst2(params.policyId, params.policy_id),
1885
+ resource_id: pickFirst2(params.resourceId, params.resource_id),
1886
+ resource_type: pickFirst2(params.resourceType, params.resource_type),
1887
+ note: params.note
1888
+ });
1889
+ }
1890
+ var EgressNetwork = class {
1891
+ constructor(http) {
1892
+ this.http = http;
1893
+ }
1894
+ http;
1895
+ // ── allowlist ─────────────────────────────────────────────────────────────
1896
+ /** Add an `allow` rule for `host` to the allowlist. */
1897
+ async allow(host, params = {}) {
1898
+ const data = await this.http.post(
1899
+ "/egress/allowlist",
1900
+ ruleBody(host, params, "allow")
1901
+ );
1902
+ return unwrap18(data);
1903
+ }
1904
+ /** Add a `deny` rule for `host` to the allowlist. */
1905
+ async deny(host, params = {}) {
1906
+ const data = await this.http.post(
1907
+ "/egress/allowlist",
1908
+ ruleBody(host, params, "deny")
1909
+ );
1910
+ return unwrap18(data);
1911
+ }
1912
+ /** List allowlist rules. */
1913
+ async rules(params = {}) {
1914
+ const query = stripUndefined6({
1915
+ policy_id: pickFirst2(params.policyId, params.policy_id),
1916
+ resource_id: pickFirst2(params.resourceId, params.resource_id),
1917
+ resource_type: pickFirst2(params.resourceType, params.resource_type)
1918
+ });
1919
+ const data = await this.http.get("/egress/allowlist", query);
1920
+ return unwrapList9(data);
1921
+ }
1922
+ /** Delete an allowlist rule by id. */
1923
+ async removeRule(ruleId) {
1924
+ await this.http.delete(`/egress/allowlist/${ruleId}`);
1925
+ }
1926
+ // ── policies ──────────────────────────────────────────────────────────────
1927
+ /** List egress policies. */
1928
+ async policies(params = {}) {
1929
+ const query = stripUndefined6({
1930
+ resource_id: pickFirst2(params.resourceId, params.resource_id),
1931
+ resource_type: pickFirst2(params.resourceType, params.resource_type)
1932
+ });
1933
+ const data = await this.http.get("/egress/policies", query);
1934
+ return unwrapList9(data);
1935
+ }
1936
+ /** Create an egress policy. */
1937
+ async createPolicy(params) {
1938
+ const body = stripUndefined6({
1939
+ name: params.name,
1940
+ mode: params.mode ?? "enforce",
1941
+ default_effect: pickFirst2(
1942
+ params.defaultEffect,
1943
+ params.default_effect,
1944
+ "deny"
1945
+ ),
1946
+ resource_id: pickFirst2(params.resourceId, params.resource_id),
1947
+ resource_type: pickFirst2(params.resourceType, params.resource_type),
1948
+ description: params.description
1949
+ });
1950
+ const data = await this.http.post(
1951
+ "/egress/policies",
1952
+ body
1953
+ );
1954
+ return unwrap18(data);
1955
+ }
1956
+ /** Update an egress policy by id. */
1957
+ async updatePolicy(policyId, params) {
1958
+ const body = stripUndefined6({
1959
+ mode: params.mode,
1960
+ default_effect: pickFirst2(params.defaultEffect, params.default_effect),
1961
+ name: params.name,
1962
+ description: params.description
1963
+ });
1964
+ const data = await this.http.patch(
1965
+ `/egress/policies/${policyId}`,
1966
+ body
1967
+ );
1968
+ return unwrap18(data);
1969
+ }
1970
+ // ── mode helpers ──────────────────────────────────────────────────────────
1971
+ /** Set the policy to `mode="enforce"` — denied egress is blocked. */
1972
+ async lockdown(params = {}) {
1973
+ return this.setMode("enforce", params);
1974
+ }
1975
+ /** Set the policy to `mode="audit_only"` — log but do not block. */
1976
+ async observe(params = {}) {
1977
+ return this.setMode("audit_only", params);
1978
+ }
1979
+ async setMode(mode, params) {
1980
+ const policyId = pickFirst2(params.policyId, params.policy_id);
1981
+ const resourceId = pickFirst2(params.resourceId, params.resource_id);
1982
+ const resourceType = pickFirst2(params.resourceType, params.resource_type);
1983
+ if (policyId) {
1984
+ return this.updatePolicy(policyId, { mode });
1985
+ }
1986
+ const body = resourceId !== void 0 && resourceType !== void 0 ? stripUndefined6({
1987
+ mode,
1988
+ resource_id: resourceId,
1989
+ resource_type: resourceType
1990
+ }) : { mode };
1991
+ const data = await this.http.patch(
1992
+ "/egress/policies",
1993
+ body
1994
+ );
1995
+ return unwrap18(data);
1996
+ }
1997
+ // ── suggestions ───────────────────────────────────────────────────────────
1998
+ /** AI-generated allowlist suggestions from recent denied egress. */
1999
+ async suggestions(params = {}) {
2000
+ const query = stripUndefined6({
2001
+ resource_id: pickFirst2(params.resourceId, params.resource_id),
2002
+ resource_type: pickFirst2(params.resourceType, params.resource_type),
2003
+ since: params.since ?? "7d"
2004
+ });
2005
+ const data = await this.http.get(
2006
+ "/egress/audit/suggestions",
2007
+ query
2008
+ );
2009
+ return unwrapList9(data);
2010
+ }
2011
+ };
2012
+ var SandboxNetwork = class {
2013
+ constructor(http, resourceId) {
2014
+ this.resourceId = resourceId;
2015
+ this.delegate = new EgressNetwork(http);
2016
+ }
2017
+ resourceId;
2018
+ resourceType = "sandbox";
2019
+ delegate;
2020
+ resolvedResourceId(params) {
2021
+ return params.resourceId ?? params.resource_id ?? this.resourceId;
2022
+ }
2023
+ resolvedResourceType(params) {
2024
+ return params.resourceType ?? params.resource_type ?? this.resourceType;
2025
+ }
2026
+ allow(host, params = {}) {
2027
+ return this.delegate.allow(host, {
2028
+ ...params,
2029
+ resource_id: this.resolvedResourceId(params),
2030
+ resource_type: this.resolvedResourceType(params)
2031
+ });
2032
+ }
2033
+ deny(host, params = {}) {
2034
+ return this.delegate.deny(host, {
2035
+ ...params,
2036
+ resource_id: this.resolvedResourceId(params),
2037
+ resource_type: this.resolvedResourceType(params)
2038
+ });
2039
+ }
2040
+ rules(params = {}) {
2041
+ return this.delegate.rules({
2042
+ ...params,
2043
+ resource_id: this.resolvedResourceId(params),
2044
+ resource_type: this.resolvedResourceType(params)
2045
+ });
2046
+ }
2047
+ removeRule(ruleId) {
2048
+ return this.delegate.removeRule(ruleId);
2049
+ }
2050
+ lockdown(params = {}) {
2051
+ const body = {
2052
+ resource_id: this.resourceId,
2053
+ resource_type: this.resourceType
2054
+ };
2055
+ if (params.policyId !== void 0) body.policyId = params.policyId;
2056
+ return this.delegate.lockdown(body);
2057
+ }
2058
+ observe(params = {}) {
2059
+ const body = {
2060
+ resource_id: this.resourceId,
2061
+ resource_type: this.resourceType
2062
+ };
2063
+ if (params.policyId !== void 0) body.policyId = params.policyId;
2064
+ return this.delegate.observe(body);
2065
+ }
2066
+ suggestions(params = {}) {
2067
+ const body = {
2068
+ resource_id: this.resourceId,
2069
+ resource_type: this.resourceType
2070
+ };
2071
+ if (params.since !== void 0) body.since = params.since;
2072
+ return this.delegate.suggestions(body);
2073
+ }
2074
+ policies() {
2075
+ return this.delegate.policies({
2076
+ resource_id: this.resourceId,
2077
+ resource_type: this.resourceType
2078
+ });
2079
+ }
2080
+ };
2081
+ var ComputerNetwork = class extends SandboxNetwork {
2082
+ resourceType = "computer";
2083
+ };
2084
+
2085
+ // src/resources/egressSecrets.ts
2086
+ function unwrap19(payload) {
2087
+ if (payload && typeof payload === "object") {
2088
+ const p = payload;
2089
+ for (const k of ["data", "secret", "binding", "items"]) {
2090
+ if (k in p) return p[k];
2091
+ }
2092
+ }
2093
+ return payload;
2094
+ }
2095
+ function unwrapList10(payload) {
2096
+ if (Array.isArray(payload)) return payload;
2097
+ if (payload && typeof payload === "object") {
2098
+ const p = payload;
2099
+ for (const k of ["data", "secrets", "bindings", "providers", "items"]) {
2100
+ if (Array.isArray(p[k])) return p[k];
2101
+ }
2102
+ }
2103
+ return [];
2104
+ }
2105
+ function stripUndefined7(input) {
2106
+ return Object.fromEntries(
2107
+ Object.entries(input).filter(([, v]) => v !== void 0)
2108
+ );
2109
+ }
2110
+ function pickFirst3(...values) {
2111
+ for (const v of values) if (v !== void 0) return v;
2112
+ return void 0;
2113
+ }
2114
+ function setBody(params) {
2115
+ return stripUndefined7({
2116
+ name: params.name,
2117
+ value: params.value,
2118
+ type: params.type ?? "api_key",
2119
+ scope: params.scope ?? "user",
2120
+ expose_as_env: pickFirst3(params.exposeAsEnv, params.expose_as_env),
2121
+ workspace_id: pickFirst3(params.workspaceId, params.workspace_id),
2122
+ owner_user_id: pickFirst3(params.ownerUserId, params.owner_user_id),
2123
+ external_user_id: pickFirst3(params.externalUserId, params.external_user_id),
2124
+ external_workspace_id: pickFirst3(
2125
+ params.externalWorkspaceId,
2126
+ params.external_workspace_id
2127
+ ),
2128
+ resource_id: pickFirst3(params.resourceId, params.resource_id),
2129
+ resource_type: pickFirst3(params.resourceType, params.resource_type),
2130
+ refresh_token: pickFirst3(params.refreshToken, params.refresh_token),
2131
+ expires_at: pickFirst3(params.expiresAt, params.expires_at),
2132
+ metadata: params.metadata
2133
+ });
2134
+ }
2135
+ function listQuery2(params) {
2136
+ return stripUndefined7({
2137
+ scope: params.scope,
2138
+ type: params.type,
2139
+ workspace_id: pickFirst3(params.workspaceId, params.workspace_id),
2140
+ owner_user_id: pickFirst3(params.ownerUserId, params.owner_user_id),
2141
+ external_user_id: pickFirst3(params.externalUserId, params.external_user_id),
2142
+ external_workspace_id: pickFirst3(
2143
+ params.externalWorkspaceId,
2144
+ params.external_workspace_id
2145
+ ),
2146
+ resource_id: pickFirst3(params.resourceId, params.resource_id),
2147
+ resource_type: pickFirst3(params.resourceType, params.resource_type)
2148
+ });
2149
+ }
2150
+ function rotateBody(params) {
2151
+ return stripUndefined7({
2152
+ value: pickFirst3(params.newValue, params.new_value, params.value),
2153
+ refresh_token: pickFirst3(params.refreshToken, params.refresh_token),
2154
+ expires_at: pickFirst3(params.expiresAt, params.expires_at)
2155
+ });
2156
+ }
2157
+ function bindingBody(params) {
2158
+ return stripUndefined7({
2159
+ secret_id: pickFirst3(params.secretId, params.secret_id),
2160
+ resource_id: pickFirst3(params.resourceId, params.resource_id),
2161
+ resource_type: pickFirst3(params.resourceType, params.resource_type),
2162
+ expose_as_env: pickFirst3(params.exposeAsEnv, params.expose_as_env)
2163
+ });
2164
+ }
2165
+ function bindingQuery(params) {
2166
+ return stripUndefined7({
2167
+ resource_id: pickFirst3(params.resourceId, params.resource_id),
2168
+ resource_type: pickFirst3(params.resourceType, params.resource_type),
2169
+ secret_id: pickFirst3(params.secretId, params.secret_id)
2170
+ });
2171
+ }
2172
+ function oauthBody(params) {
2173
+ return stripUndefined7({
2174
+ provider: params.provider,
2175
+ expose_as_env: pickFirst3(params.exposeAsEnv, params.expose_as_env),
2176
+ scope: params.scope,
2177
+ owner_user_id: pickFirst3(params.ownerUserId, params.owner_user_id),
2178
+ external_user_id: pickFirst3(params.externalUserId, params.external_user_id),
2179
+ external_workspace_id: pickFirst3(
2180
+ params.externalWorkspaceId,
2181
+ params.external_workspace_id
2182
+ ),
2183
+ resource_id: pickFirst3(params.resourceId, params.resource_id),
2184
+ resource_type: pickFirst3(params.resourceType, params.resource_type),
2185
+ redirect_uri: pickFirst3(params.redirectUri, params.redirect_uri)
2186
+ });
2187
+ }
2188
+ function sleep3(ms) {
2189
+ return new Promise((resolve) => setTimeout(resolve, ms));
2190
+ }
2191
+ var OAuthFlow = class {
2192
+ authorizeUrl;
2193
+ state;
2194
+ provider;
2195
+ data;
2196
+ http;
2197
+ constructor(http, payload, provider) {
2198
+ this.http = http;
2199
+ this.authorizeUrl = payload.authorize_url ?? payload.authorizeUrl ?? "";
2200
+ this.state = payload.state ?? "";
2201
+ if (provider !== void 0) {
2202
+ this.provider = provider;
2203
+ }
2204
+ this.data = payload;
2205
+ }
2206
+ /**
2207
+ * Poll `GET /egress/oauth/status?state=...` until the flow completes.
2208
+ *
2209
+ * Returns the status payload once the upstream provider issues
2210
+ * tokens. Rejects with a `TimeoutError`-style Error if the flow does
2211
+ * not complete within `timeoutSec` seconds, or if the upstream
2212
+ * returns a failed status.
2213
+ */
2214
+ async waitForCompletion(options = {}) {
2215
+ const timeoutSec = options.timeoutSec ?? 300;
2216
+ const pollMs = options.pollIntervalMs ?? 2e3;
2217
+ const deadline = Date.now() + timeoutSec * 1e3;
2218
+ while (Date.now() < deadline) {
2219
+ const data = await this.http.get("/egress/oauth/status", {
2220
+ state: this.state
2221
+ });
2222
+ const payload = unwrap19(data) ?? {};
2223
+ const status = payload.status;
2224
+ if (status === "completed" || status === "ready" || status === "succeeded") {
2225
+ return payload;
2226
+ }
2227
+ if (status === "failed" || status === "error" || status === "denied") {
2228
+ throw new Error(
2229
+ `OAuth flow ${this.state} ended in status=${status}: ${payload.error ?? payload.message ?? "no detail"}`
2230
+ );
2231
+ }
2232
+ await sleep3(pollMs);
2233
+ }
2234
+ throw new Error(
2235
+ `OAuth flow ${this.state} did not complete within ${timeoutSec}s`
2236
+ );
2237
+ }
2238
+ };
2239
+ var EgressSecrets = class {
2240
+ constructor(http) {
2241
+ this.http = http;
2242
+ }
2243
+ http;
2244
+ /**
2245
+ * Create a secret. When `exposeAsEnv` is provided together with
2246
+ * `resourceId` the backend also creates a binding so the value is
2247
+ * injected as an env-var on that resource.
2248
+ */
2249
+ async set(params) {
2250
+ const data = await this.http.post(
2251
+ "/egress/secrets",
2252
+ setBody(params)
2253
+ );
2254
+ return unwrap19(data);
2255
+ }
2256
+ /** List secrets. */
2257
+ async list(params = {}) {
2258
+ const data = await this.http.get(
2259
+ "/egress/secrets",
2260
+ listQuery2(params)
2261
+ );
2262
+ return unwrapList10(data);
2263
+ }
2264
+ /** Get a single secret by id. */
2265
+ async get(id) {
2266
+ const data = await this.http.get(
2267
+ `/egress/secrets/${id}`
2268
+ );
2269
+ return unwrap19(data);
2270
+ }
2271
+ /** Rotate the secret's value. */
2272
+ async rotate(id, params) {
2273
+ const body = typeof params === "string" ? rotateBody({ newValue: params }) : rotateBody(params);
2274
+ const data = await this.http.patch(
2275
+ `/egress/secrets/${id}`,
2276
+ body
2277
+ );
2278
+ return unwrap19(data);
2279
+ }
2280
+ /** Delete a secret. */
2281
+ async delete(id) {
2282
+ await this.http.delete(`/egress/secrets/${id}`);
2283
+ }
2284
+ // ── bindings ───────────────────────────────────────────────────────────────
2285
+ /** Bind a secret to a resource as an env var. */
2286
+ async createBinding(params) {
2287
+ const data = await this.http.post(
2288
+ "/egress/bindings",
2289
+ bindingBody(params)
2290
+ );
2291
+ return unwrap19(data);
2292
+ }
2293
+ /** List secret bindings. */
2294
+ async listBindings(params = {}) {
2295
+ const data = await this.http.get(
2296
+ "/egress/bindings",
2297
+ bindingQuery(params)
2298
+ );
2299
+ return unwrapList10(data);
2300
+ }
2301
+ /** Delete a binding. */
2302
+ async deleteBinding(id) {
2303
+ await this.http.delete(`/egress/bindings/${id}`);
2304
+ }
2305
+ // ── OAuth Connect ──────────────────────────────────────────────────────────
2306
+ /** List OAuth providers visible to the current tenant. */
2307
+ async providers() {
2308
+ const data = await this.http.get("/egress/oauth/providers");
2309
+ return unwrapList10(data);
2310
+ }
2311
+ /**
2312
+ * Start an OAuth Connect flow.
2313
+ *
2314
+ * Returns an {@link OAuthFlow} — the caller must surface
2315
+ * `flow.authorizeUrl` to the end user (the SDK does NOT open the
2316
+ * browser) and then call `flow.waitForCompletion()` to receive the
2317
+ * resulting secret id.
2318
+ */
2319
+ async connect(params) {
2320
+ const data = await this.http.post(
2321
+ "/egress/oauth/start",
2322
+ oauthBody(params)
2323
+ );
2324
+ const payload = unwrap19(data) ?? {};
2325
+ return new OAuthFlow(this.http, payload, params.provider);
2326
+ }
2327
+ };
2328
+ var SandboxSecrets = class {
2329
+ constructor(http, resourceId) {
2330
+ this.resourceId = resourceId;
2331
+ this.delegate = new EgressSecrets(http);
2332
+ }
2333
+ resourceId;
2334
+ resourceType = "sandbox";
2335
+ delegate;
2336
+ resolvedResourceId(params) {
2337
+ return params.resourceId ?? params.resource_id ?? this.resourceId;
2338
+ }
2339
+ resolvedResourceType(params) {
2340
+ return params.resourceType ?? params.resource_type ?? this.resourceType;
2341
+ }
2342
+ set(params) {
2343
+ return this.delegate.set({
2344
+ ...params,
2345
+ resource_id: this.resolvedResourceId(params),
2346
+ resource_type: this.resolvedResourceType(params)
2347
+ });
2348
+ }
2349
+ list(params = {}) {
2350
+ return this.delegate.list({
2351
+ ...params,
2352
+ resource_id: this.resolvedResourceId(params),
2353
+ resource_type: this.resolvedResourceType(params)
2354
+ });
2355
+ }
2356
+ get(id) {
2357
+ return this.delegate.get(id);
2358
+ }
2359
+ rotate(id, params) {
2360
+ return this.delegate.rotate(id, params);
2361
+ }
2362
+ delete(id) {
2363
+ return this.delegate.delete(id);
2364
+ }
2365
+ connect(params) {
2366
+ return this.delegate.connect({
2367
+ ...params,
2368
+ resource_id: this.resolvedResourceId(params),
2369
+ resource_type: this.resolvedResourceType(params)
2370
+ });
2371
+ }
2372
+ listBindings(params = {}) {
2373
+ return this.delegate.listBindings({
2374
+ ...params,
2375
+ resource_id: this.resolvedResourceId(params),
2376
+ resource_type: this.resolvedResourceType(params)
2377
+ });
2378
+ }
2379
+ };
2380
+ var ComputerSecrets = class extends SandboxSecrets {
2381
+ resourceType = "computer";
2382
+ };
1698
2383
  var EventStream = class extends EventEmitter {
1699
2384
  ws = null;
1700
2385
  closed = false;
@@ -2252,6 +2937,12 @@ var Computer = class _Computer {
2252
2937
  ports;
2253
2938
  /** Volume attachment — list, attach, detach. */
2254
2939
  volumes;
2940
+ /** Encrypted secrets + OAuth credentials scoped to this computer. */
2941
+ secrets;
2942
+ /** Egress allowlist + policies scoped to this computer. */
2943
+ network;
2944
+ /** Egress audit log + live tail scoped to this computer. */
2945
+ audit;
2255
2946
  http;
2256
2947
  constructor(http, data) {
2257
2948
  this.http = http;
@@ -2272,6 +2963,9 @@ var Computer = class _Computer {
2272
2963
  this.logs = new ComputerLogs(http, id);
2273
2964
  this.ports = new ComputerPorts(http, id);
2274
2965
  this.volumes = new ComputerVolumes(http, id);
2966
+ this.secrets = new ComputerSecrets(http, id);
2967
+ this.network = new ComputerNetwork(http, id);
2968
+ this.audit = new ComputerAudit(http, id);
2275
2969
  }
2276
2970
  get id() {
2277
2971
  return this.data.id;
@@ -2668,7 +3362,7 @@ var Credits = class {
2668
3362
  return this.http.get("/credits/usage");
2669
3363
  }
2670
3364
  };
2671
- function unwrap17(payload) {
3365
+ function unwrap20(payload) {
2672
3366
  if (payload && typeof payload === "object" && "data" in payload) {
2673
3367
  return payload.data;
2674
3368
  }
@@ -2684,7 +3378,7 @@ function listItems2(payload, candidateKeys = ["data", "cron_jobs", "executions",
2684
3378
  }
2685
3379
  return [];
2686
3380
  }
2687
- function stripUndefined5(input) {
3381
+ function stripUndefined8(input) {
2688
3382
  return Object.fromEntries(
2689
3383
  Object.entries(input).filter(([, v]) => v !== void 0)
2690
3384
  );
@@ -2698,28 +3392,28 @@ var CronJobs = class {
2698
3392
  }
2699
3393
  http;
2700
3394
  async list(params = {}) {
2701
- const query = stripUndefined5({ ...params });
3395
+ const query = stripUndefined8({ ...params });
2702
3396
  const data = await this.http.get("/cron-jobs", query);
2703
3397
  return listItems2(data);
2704
3398
  }
2705
3399
  async get(jobId) {
2706
3400
  const data = await this.http.get(`/cron-jobs/${jobId}`);
2707
- return unwrap17(data);
3401
+ return unwrap20(data);
2708
3402
  }
2709
3403
  async create(params) {
2710
3404
  const { idempotencyKey: ikey, ...rest } = params;
2711
- const body = stripUndefined5(rest);
3405
+ const body = stripUndefined8(rest);
2712
3406
  const data = await this.http.request("/cron-jobs", {
2713
3407
  method: "POST",
2714
3408
  body,
2715
3409
  headers: { "Idempotency-Key": idempotencyKey2(ikey) }
2716
3410
  });
2717
- return unwrap17(data);
3411
+ return unwrap20(data);
2718
3412
  }
2719
3413
  async update(jobId, params) {
2720
- const body = stripUndefined5(params);
3414
+ const body = stripUndefined8(params);
2721
3415
  const data = await this.http.patch(`/cron-jobs/${jobId}`, body);
2722
- return unwrap17(data);
3416
+ return unwrap20(data);
2723
3417
  }
2724
3418
  async delete(jobId) {
2725
3419
  await this.http.delete(`/cron-jobs/${jobId}`);
@@ -2727,11 +3421,11 @@ var CronJobs = class {
2727
3421
  // ── Control ────────────────────────────────────────────────────────────────
2728
3422
  async pause(jobId) {
2729
3423
  const data = await this.http.post(`/cron-jobs/${jobId}/pause`);
2730
- return unwrap17(data);
3424
+ return unwrap20(data);
2731
3425
  }
2732
3426
  async resume(jobId) {
2733
3427
  const data = await this.http.post(`/cron-jobs/${jobId}/resume`);
2734
- return unwrap17(data);
3428
+ return unwrap20(data);
2735
3429
  }
2736
3430
  async runNow(jobId, opts = {}) {
2737
3431
  const data = await this.http.request(
@@ -2741,7 +3435,7 @@ var CronJobs = class {
2741
3435
  headers: { "Idempotency-Key": idempotencyKey2(opts.idempotencyKey) }
2742
3436
  }
2743
3437
  );
2744
- return unwrap17(data);
3438
+ return unwrap20(data);
2745
3439
  }
2746
3440
  // ── Execution history ──────────────────────────────────────────────────────
2747
3441
  async listExecutions(jobId) {
@@ -2756,12 +3450,12 @@ var CronJobs = class {
2756
3450
  const data = await this.http.get(
2757
3451
  `/cron-jobs/${jobId}/executions/${executionId}`
2758
3452
  );
2759
- return unwrap17(data);
3453
+ return unwrap20(data);
2760
3454
  }
2761
3455
  };
2762
3456
 
2763
3457
  // src/resources/dashboard.ts
2764
- function unwrap18(payload) {
3458
+ function unwrap21(payload) {
2765
3459
  if (payload && typeof payload === "object") {
2766
3460
  const p = payload;
2767
3461
  for (const k of ["data", "dashboard", "overview", "items"]) {
@@ -2778,15 +3472,15 @@ var Dashboard = class {
2778
3472
  /** Aggregated user dashboard payload. */
2779
3473
  async summary() {
2780
3474
  const data = await this.http.get("/dashboard");
2781
- return unwrap18(data);
3475
+ return unwrap21(data);
2782
3476
  }
2783
3477
  /** Status / health overview (public endpoint). */
2784
3478
  async overview() {
2785
3479
  const data = await this.http.get("/overview");
2786
- return unwrap18(data);
3480
+ return unwrap21(data);
2787
3481
  }
2788
3482
  };
2789
- function unwrap19(payload) {
3483
+ function unwrap22(payload) {
2790
3484
  if (payload && typeof payload === "object" && "data" in payload) {
2791
3485
  return payload.data;
2792
3486
  }
@@ -2802,7 +3496,7 @@ function listItems3(payload, candidateKeys = ["data", "databases", "items"]) {
2802
3496
  }
2803
3497
  return [];
2804
3498
  }
2805
- function stripUndefined6(input) {
3499
+ function stripUndefined9(input) {
2806
3500
  return Object.fromEntries(
2807
3501
  Object.entries(input).filter(([, v]) => v !== void 0)
2808
3502
  );
@@ -2816,13 +3510,13 @@ var Databases = class {
2816
3510
  }
2817
3511
  http;
2818
3512
  async list(params = {}) {
2819
- const query = stripUndefined6({ ...params });
3513
+ const query = stripUndefined9({ ...params });
2820
3514
  const data = await this.http.get("/databases", query);
2821
3515
  return listItems3(data);
2822
3516
  }
2823
3517
  async get(databaseId) {
2824
3518
  const data = await this.http.get(`/databases/${databaseId}`);
2825
- return unwrap19(data);
3519
+ return unwrap22(data);
2826
3520
  }
2827
3521
  async create(params) {
2828
3522
  const {
@@ -2833,7 +3527,7 @@ var Databases = class {
2833
3527
  size: _deprecatedSize,
2834
3528
  ...rest
2835
3529
  } = params;
2836
- const body = stripUndefined6({
3530
+ const body = stripUndefined9({
2837
3531
  ...rest,
2838
3532
  engine_version: engine_version ?? version
2839
3533
  });
@@ -2846,7 +3540,7 @@ var Databases = class {
2846
3540
  )
2847
3541
  }
2848
3542
  });
2849
- return unwrap19(data);
3543
+ return unwrap22(data);
2850
3544
  }
2851
3545
  async delete(databaseId) {
2852
3546
  await this.http.delete(`/databases/${databaseId}`);
@@ -2856,27 +3550,27 @@ var Databases = class {
2856
3550
  const data = await this.http.post(
2857
3551
  `/databases/${databaseId}/start`
2858
3552
  );
2859
- return unwrap19(data);
3553
+ return unwrap22(data);
2860
3554
  }
2861
3555
  async stop(databaseId) {
2862
3556
  const data = await this.http.post(`/databases/${databaseId}/stop`);
2863
- return unwrap19(data);
3557
+ return unwrap22(data);
2864
3558
  }
2865
3559
  async restart(databaseId) {
2866
3560
  const data = await this.http.post(
2867
3561
  `/databases/${databaseId}/restart`
2868
3562
  );
2869
- return unwrap19(data);
3563
+ return unwrap22(data);
2870
3564
  }
2871
3565
  // ── Credentials + logs ────────────────────────────────────────────────────
2872
3566
  async credentials(databaseId) {
2873
3567
  const data = await this.http.get(
2874
3568
  `/databases/${databaseId}/credentials`
2875
3569
  );
2876
- return unwrap19(data);
3570
+ return unwrap22(data);
2877
3571
  }
2878
3572
  async logs(databaseId, params = {}) {
2879
- const query = stripUndefined6({
3573
+ const query = stripUndefined9({
2880
3574
  lines: params.lines,
2881
3575
  since: params.since
2882
3576
  });
@@ -2903,7 +3597,7 @@ function attributionBody(p) {
2903
3597
  function idempotencyKey4(key) {
2904
3598
  return key ?? randomUUID();
2905
3599
  }
2906
- function unwrap20(payload) {
3600
+ function unwrap23(payload) {
2907
3601
  if (payload && typeof payload === "object" && "data" in payload) {
2908
3602
  return payload.data;
2909
3603
  }
@@ -2919,7 +3613,7 @@ function listItems4(payload, candidateKeys = ["items", "deployments", "versions"
2919
3613
  }
2920
3614
  return [];
2921
3615
  }
2922
- function stripUndefined7(input) {
3616
+ function stripUndefined10(input) {
2923
3617
  return Object.fromEntries(
2924
3618
  Object.entries(input).filter(([, v]) => v !== void 0)
2925
3619
  );
@@ -2932,7 +3626,7 @@ var DeploymentVersions = class {
2932
3626
  http;
2933
3627
  deploymentId;
2934
3628
  async list(params = {}) {
2935
- const query = stripUndefined7({
3629
+ const query = stripUndefined10({
2936
3630
  state: params.state,
2937
3631
  limit: params.limit,
2938
3632
  cursor: params.cursor,
@@ -2948,10 +3642,10 @@ var DeploymentVersions = class {
2948
3642
  const data = await this.http.get(
2949
3643
  `/deployments/${this.deploymentId}/versions/${versionId}`
2950
3644
  );
2951
- return unwrap20(data);
3645
+ return unwrap23(data);
2952
3646
  }
2953
3647
  async promote(versionId, opts = {}) {
2954
- const body = stripUndefined7({ environment: opts.environment });
3648
+ const body = stripUndefined10({ environment: opts.environment });
2955
3649
  const data = await this.http.request(
2956
3650
  `/deployments/${this.deploymentId}/versions/${versionId}/promote`,
2957
3651
  {
@@ -2960,7 +3654,7 @@ var DeploymentVersions = class {
2960
3654
  headers: { "Idempotency-Key": idempotencyKey4(opts.idempotencyKey) }
2961
3655
  }
2962
3656
  );
2963
- return unwrap20(data);
3657
+ return unwrap23(data);
2964
3658
  }
2965
3659
  };
2966
3660
  var DeploymentReleases = class {
@@ -2980,7 +3674,7 @@ var DeploymentReleases = class {
2980
3674
  const data = await this.http.get(
2981
3675
  `/deployments/${this.deploymentId}/releases/${releaseId}`
2982
3676
  );
2983
- return unwrap20(data);
3677
+ return unwrap23(data);
2984
3678
  }
2985
3679
  };
2986
3680
  var DeploymentRuntimeInstances = class {
@@ -3000,14 +3694,14 @@ var DeploymentRuntimeInstances = class {
3000
3694
  const data = await this.http.get(
3001
3695
  `/deployments/${this.deploymentId}/runtime-instances/${instanceId}`
3002
3696
  );
3003
- return unwrap20(data);
3697
+ return unwrap23(data);
3004
3698
  }
3005
3699
  async logs(instanceId, lines = 100) {
3006
3700
  const data = await this.http.get(
3007
3701
  `/deployments/${this.deploymentId}/runtime-instances/${instanceId}/logs`,
3008
3702
  { lines }
3009
3703
  );
3010
- const unwrapped = unwrap20(data);
3704
+ const unwrapped = unwrap23(data);
3011
3705
  const result = { logs: String(unwrapped.logs ?? "") };
3012
3706
  if (typeof unwrapped.runtime_instance_id === "string") {
3013
3707
  result.runtime_instance_id = unwrapped.runtime_instance_id;
@@ -3038,11 +3732,11 @@ var DeploymentDomains = class {
3038
3732
  `/deployments/${this.deploymentId}/domains`,
3039
3733
  {
3040
3734
  method: "POST",
3041
- body: stripUndefined7(body),
3735
+ body: stripUndefined10(body),
3042
3736
  headers: { "Idempotency-Key": idempotencyKey4(params.idempotencyKey) }
3043
3737
  }
3044
3738
  );
3045
- return unwrap20(data);
3739
+ return unwrap23(data);
3046
3740
  }
3047
3741
  async list(filters = {}) {
3048
3742
  const data = await this.http.get(
@@ -3055,7 +3749,7 @@ var DeploymentDomains = class {
3055
3749
  const data = await this.http.post(
3056
3750
  `/deployments/${this.deploymentId}/domains/${domainId}/verify`
3057
3751
  );
3058
- return unwrap20(data);
3752
+ return unwrap23(data);
3059
3753
  }
3060
3754
  async delete(domainId) {
3061
3755
  await this.http.delete(
@@ -3070,7 +3764,7 @@ var Deployments = class {
3070
3764
  http;
3071
3765
  async list(params = {}) {
3072
3766
  const projectId = params.projectId ?? params.project_id;
3073
- const query = stripUndefined7({
3767
+ const query = stripUndefined10({
3074
3768
  project_id: projectId,
3075
3769
  state: params.state,
3076
3770
  limit: params.limit,
@@ -3085,10 +3779,10 @@ var Deployments = class {
3085
3779
  }
3086
3780
  async get(deploymentId) {
3087
3781
  const data = await this.http.get(`/deployments/${deploymentId}`);
3088
- return unwrap20(data);
3782
+ return unwrap23(data);
3089
3783
  }
3090
3784
  async create(params) {
3091
- const body = stripUndefined7({
3785
+ const body = stripUndefined10({
3092
3786
  name: params.name,
3093
3787
  repo_url: params.repoUrl ?? params.repo_url,
3094
3788
  branch: params.branch,
@@ -3097,6 +3791,7 @@ var Deployments = class {
3097
3791
  auto_deploy: params.autoDeploy ?? params.auto_deploy,
3098
3792
  database: params.database,
3099
3793
  metadata: params.metadata,
3794
+ target_region: params.targetRegion ?? params.target_region,
3100
3795
  ...attributionBody(params)
3101
3796
  });
3102
3797
  const data = await this.http.request("/deployments", {
@@ -3104,10 +3799,10 @@ var Deployments = class {
3104
3799
  body,
3105
3800
  headers: { "Idempotency-Key": idempotencyKey4(params.idempotencyKey) }
3106
3801
  });
3107
- return unwrap20(data);
3802
+ return unwrap23(data);
3108
3803
  }
3109
3804
  async update(deploymentId, params) {
3110
- const body = stripUndefined7({
3805
+ const body = stripUndefined10({
3111
3806
  name: params.name,
3112
3807
  branch: params.branch,
3113
3808
  build_command: params.buildCommand ?? params.build_command,
@@ -3118,13 +3813,13 @@ var Deployments = class {
3118
3813
  `/deployments/${deploymentId}`,
3119
3814
  body
3120
3815
  );
3121
- return unwrap20(data);
3816
+ return unwrap23(data);
3122
3817
  }
3123
3818
  async delete(deploymentId) {
3124
3819
  await this.http.delete(`/deployments/${deploymentId}`);
3125
3820
  }
3126
3821
  async publish(deploymentId, params) {
3127
- const body = stripUndefined7({
3822
+ const body = stripUndefined10({
3128
3823
  source_sandbox_id: params.sourceSandboxId ?? params.source_sandbox_id,
3129
3824
  output_path: params.outputPath ?? params.output_path,
3130
3825
  entrypoint: params.entrypoint,
@@ -3138,7 +3833,7 @@ var Deployments = class {
3138
3833
  headers: { "Idempotency-Key": idempotencyKey4(params.idempotencyKey) }
3139
3834
  }
3140
3835
  );
3141
- return unwrap20(data);
3836
+ return unwrap23(data);
3142
3837
  }
3143
3838
  /**
3144
3839
  * Backward-compatible bridge: POST /sandboxes/:id/deploy. Works today;
@@ -3146,7 +3841,7 @@ var Deployments = class {
3146
3841
  * phase. Prefer `publish()` once Phase 2B/3 lands.
3147
3842
  */
3148
3843
  async publishFromSandbox(sandboxId, params = {}) {
3149
- const body = stripUndefined7({
3844
+ const body = stripUndefined10({
3150
3845
  name: params.name,
3151
3846
  deployment_id: params.deploymentId ?? params.deployment_id,
3152
3847
  output_path: params.outputPath ?? params.output_path,
@@ -3163,10 +3858,10 @@ var Deployments = class {
3163
3858
  headers: { "Idempotency-Key": idempotencyKey4(params.idempotencyKey) }
3164
3859
  }
3165
3860
  );
3166
- return unwrap20(data);
3861
+ return unwrap23(data);
3167
3862
  }
3168
3863
  async rollback(deploymentId, params = {}) {
3169
- const body = stripUndefined7({
3864
+ const body = stripUndefined10({
3170
3865
  version_id: params.versionId ?? params.version_id
3171
3866
  });
3172
3867
  const data = await this.http.request(
@@ -3177,7 +3872,7 @@ var Deployments = class {
3177
3872
  headers: { "Idempotency-Key": idempotencyKey4(params.idempotencyKey) }
3178
3873
  }
3179
3874
  );
3180
- return unwrap20(data);
3875
+ return unwrap23(data);
3181
3876
  }
3182
3877
  async listBuilds(deploymentId) {
3183
3878
  const data = await this.http.get(
@@ -3189,16 +3884,18 @@ var Deployments = class {
3189
3884
  const data = await this.http.get(
3190
3885
  `/deployments/${deploymentId}/builds/${buildId}`
3191
3886
  );
3192
- return unwrap20(data);
3887
+ return unwrap23(data);
3193
3888
  }
3194
- async listEnv(deploymentId) {
3889
+ async listEnv(deploymentId, opts = {}) {
3890
+ const query = stripUndefined10({ environment: opts.environment });
3195
3891
  const data = await this.http.get(
3196
- `/deployments/${deploymentId}/env`
3892
+ `/deployments/${deploymentId}/env`,
3893
+ Object.keys(query).length ? query : void 0
3197
3894
  );
3198
3895
  return listItems4(data);
3199
3896
  }
3200
3897
  async setEnv(deploymentId, vars, opts = {}) {
3201
- const body = stripUndefined7({ env: vars, environment: opts.environment });
3898
+ const body = stripUndefined10({ env: vars, environment: opts.environment });
3202
3899
  const data = await this.http.post(
3203
3900
  `/deployments/${deploymentId}/env`,
3204
3901
  body
@@ -3223,7 +3920,7 @@ var Deployments = class {
3223
3920
  };
3224
3921
 
3225
3922
  // src/resources/email.ts
3226
- function unwrap21(data) {
3923
+ function unwrap24(data) {
3227
3924
  if (data && typeof data === "object") {
3228
3925
  const d = data;
3229
3926
  for (const k of [
@@ -3239,7 +3936,7 @@ function unwrap21(data) {
3239
3936
  }
3240
3937
  return data;
3241
3938
  }
3242
- function unwrapList8(data) {
3939
+ function unwrapList11(data) {
3243
3940
  if (Array.isArray(data)) return data;
3244
3941
  if (data && typeof data === "object") {
3245
3942
  const d = data;
@@ -3267,7 +3964,7 @@ var EmailCampaigns = class {
3267
3964
  }
3268
3965
  http;
3269
3966
  async list(filters = {}) {
3270
- return unwrapList8(
3967
+ return unwrapList11(
3271
3968
  await this.http.get(
3272
3969
  "/admin/email-campaigns",
3273
3970
  filters
@@ -3275,12 +3972,12 @@ var EmailCampaigns = class {
3275
3972
  );
3276
3973
  }
3277
3974
  async create(attrs) {
3278
- return unwrap21(
3975
+ return unwrap24(
3279
3976
  await this.http.post("/admin/email-campaigns", strip(attrs))
3280
3977
  );
3281
3978
  }
3282
3979
  async recipientCount(filters = {}) {
3283
- return unwrap21(
3980
+ return unwrap24(
3284
3981
  await this.http.get(
3285
3982
  "/admin/email-campaigns/recipient-count",
3286
3983
  filters
@@ -3288,7 +3985,7 @@ var EmailCampaigns = class {
3288
3985
  );
3289
3986
  }
3290
3987
  async send(campaignId, opts = {}) {
3291
- return unwrap21(
3988
+ return unwrap24(
3292
3989
  await this.http.post(
3293
3990
  `/admin/email-campaigns/${campaignId}/send`,
3294
3991
  strip(opts)
@@ -3296,14 +3993,14 @@ var EmailCampaigns = class {
3296
3993
  );
3297
3994
  }
3298
3995
  async cancel(campaignId) {
3299
- return unwrap21(
3996
+ return unwrap24(
3300
3997
  await this.http.post(
3301
3998
  `/admin/email-campaigns/${campaignId}/cancel`
3302
3999
  )
3303
4000
  );
3304
4001
  }
3305
4002
  async deliveries(campaignId, filters = {}) {
3306
- return unwrapList8(
4003
+ return unwrapList11(
3307
4004
  await this.http.get(
3308
4005
  `/admin/email-campaigns/${campaignId}/deliveries`,
3309
4006
  filters
@@ -3317,12 +4014,12 @@ var EmailTemplates = class {
3317
4014
  }
3318
4015
  http;
3319
4016
  async list(filters = {}) {
3320
- return unwrapList8(
4017
+ return unwrapList11(
3321
4018
  await this.http.get("/admin/email-templates", filters)
3322
4019
  );
3323
4020
  }
3324
4021
  async create(key, attrs = {}) {
3325
- return unwrap21(
4022
+ return unwrap24(
3326
4023
  await this.http.post("/admin/email-templates", {
3327
4024
  key,
3328
4025
  ...strip(attrs)
@@ -3330,7 +4027,7 @@ var EmailTemplates = class {
3330
4027
  );
3331
4028
  }
3332
4029
  async update(key, attrs) {
3333
- return unwrap21(
4030
+ return unwrap24(
3334
4031
  await this.http.put(
3335
4032
  `/admin/email-templates/${key}`,
3336
4033
  strip(attrs)
@@ -3338,7 +4035,7 @@ var EmailTemplates = class {
3338
4035
  );
3339
4036
  }
3340
4037
  async reset(key) {
3341
- return unwrap21(
4038
+ return unwrap24(
3342
4039
  await this.http.post(`/admin/email-templates/${key}/reset`)
3343
4040
  );
3344
4041
  }
@@ -3349,22 +4046,22 @@ var EmailInbox = class {
3349
4046
  }
3350
4047
  http;
3351
4048
  async list(filters = {}) {
3352
- return unwrapList8(
4049
+ return unwrapList11(
3353
4050
  await this.http.get("/admin/email-inbox", filters)
3354
4051
  );
3355
4052
  }
3356
4053
  async send(attrs) {
3357
- return unwrap21(
4054
+ return unwrap24(
3358
4055
  await this.http.post("/admin/email-inbox/send", strip(attrs))
3359
4056
  );
3360
4057
  }
3361
4058
  async markRead(messageId) {
3362
- return unwrap21(
4059
+ return unwrap24(
3363
4060
  await this.http.post(`/admin/email-inbox/${messageId}/read`)
3364
4061
  );
3365
4062
  }
3366
4063
  async archive(messageId) {
3367
- return unwrap21(
4064
+ return unwrap24(
3368
4065
  await this.http.post(`/admin/email-inbox/${messageId}/archive`)
3369
4066
  );
3370
4067
  }
@@ -3404,7 +4101,7 @@ var Embeddings = class {
3404
4101
  };
3405
4102
 
3406
4103
  // src/resources/external-keys.ts
3407
- function unwrap22(payload) {
4104
+ function unwrap25(payload) {
3408
4105
  if (payload && typeof payload === "object") {
3409
4106
  const p = payload;
3410
4107
  for (const k of ["data", "external_keys", "items"]) {
@@ -3413,7 +4110,7 @@ function unwrap22(payload) {
3413
4110
  }
3414
4111
  return payload;
3415
4112
  }
3416
- function stripUndefined8(input) {
4113
+ function stripUndefined11(input) {
3417
4114
  return Object.fromEntries(
3418
4115
  Object.entries(input).filter(([, v]) => v !== void 0)
3419
4116
  );
@@ -3426,22 +4123,22 @@ var ExternalKeys = class {
3426
4123
  /** List configured external keys. */
3427
4124
  async list() {
3428
4125
  const data = await this.http.get("/external-keys");
3429
- const result = unwrap22(data);
4126
+ const result = unwrap25(data);
3430
4127
  if (Array.isArray(result)) return result;
3431
4128
  return [];
3432
4129
  }
3433
4130
  /** Create / register an external provider key. */
3434
4131
  async create(params) {
3435
- const body = stripUndefined8(params);
4132
+ const body = stripUndefined11(params);
3436
4133
  const data = await this.http.post("/external-keys", body);
3437
- return unwrap22(data);
4134
+ return unwrap25(data);
3438
4135
  }
3439
4136
  /** Resolve (preview) the stored key for a provider. */
3440
4137
  async resolve(provider) {
3441
4138
  const data = await this.http.get(
3442
4139
  `/external-keys/${provider}/resolve`
3443
4140
  );
3444
- return unwrap22(data);
4141
+ return unwrap25(data);
3445
4142
  }
3446
4143
  /**
3447
4144
  * Delete the stored key for a provider.
@@ -3451,7 +4148,7 @@ var ExternalKeys = class {
3451
4148
  await this.http.delete(`/external-keys/${provider}`);
3452
4149
  }
3453
4150
  };
3454
- function unwrap23(payload) {
4151
+ function unwrap26(payload) {
3455
4152
  if (payload && typeof payload === "object" && "data" in payload) {
3456
4153
  return payload.data;
3457
4154
  }
@@ -3467,7 +4164,7 @@ function listItems5(payload, candidateKeys = ["data", "domains", "items"]) {
3467
4164
  }
3468
4165
  return [];
3469
4166
  }
3470
- function stripUndefined9(input) {
4167
+ function stripUndefined12(input) {
3471
4168
  return Object.fromEntries(
3472
4169
  Object.entries(input).filter(([, v]) => v !== void 0)
3473
4170
  );
@@ -3481,7 +4178,7 @@ var FlatCustomDomains = class {
3481
4178
  }
3482
4179
  http;
3483
4180
  async list(params = {}) {
3484
- const query = stripUndefined9({ ...params });
4181
+ const query = stripUndefined12({ ...params });
3485
4182
  const data = await this.http.get("/custom-domains", query);
3486
4183
  return listItems5(data);
3487
4184
  }
@@ -3493,7 +4190,7 @@ var FlatCustomDomains = class {
3493
4190
  redirectPolicy,
3494
4191
  ...rest
3495
4192
  } = params;
3496
- const body = stripUndefined9({
4193
+ const body = stripUndefined12({
3497
4194
  ...rest,
3498
4195
  resource_type: resourceType ?? rest.resource_type,
3499
4196
  resource_id: resourceId ?? rest.resource_id,
@@ -3504,13 +4201,13 @@ var FlatCustomDomains = class {
3504
4201
  body,
3505
4202
  headers: { "Idempotency-Key": idempotencyKey5(ikey) }
3506
4203
  });
3507
- return unwrap23(data);
4204
+ return unwrap26(data);
3508
4205
  }
3509
4206
  async delete(domainId) {
3510
4207
  await this.http.delete(`/custom-domains/${domainId}`);
3511
4208
  }
3512
4209
  };
3513
- function unwrap24(payload) {
4210
+ function unwrap27(payload) {
3514
4211
  if (payload && typeof payload === "object" && "data" in payload) {
3515
4212
  return payload.data;
3516
4213
  }
@@ -3526,7 +4223,7 @@ function listItems6(payload, candidateKeys = ["data", "functions", "items"]) {
3526
4223
  }
3527
4224
  return [];
3528
4225
  }
3529
- function stripUndefined10(input) {
4226
+ function stripUndefined13(input) {
3530
4227
  return Object.fromEntries(
3531
4228
  Object.entries(input).filter(([, v]) => v !== void 0)
3532
4229
  );
@@ -3540,17 +4237,17 @@ var Functions = class {
3540
4237
  }
3541
4238
  http;
3542
4239
  async list(params = {}) {
3543
- const query = stripUndefined10({ ...params });
4240
+ const query = stripUndefined13({ ...params });
3544
4241
  const data = await this.http.get("/functions", query);
3545
4242
  return listItems6(data);
3546
4243
  }
3547
4244
  async get(functionId) {
3548
4245
  const data = await this.http.get(`/functions/${functionId}`);
3549
- return unwrap24(data);
4246
+ return unwrap27(data);
3550
4247
  }
3551
4248
  async create(params) {
3552
4249
  const { idempotencyKey: ikey, memoryMb, timeoutSec, ...rest } = params;
3553
- const body = stripUndefined10({
4250
+ const body = stripUndefined13({
3554
4251
  ...rest,
3555
4252
  memory_mb: memoryMb ?? rest.memory_mb,
3556
4253
  timeout_sec: timeoutSec ?? rest.timeout_sec
@@ -3560,11 +4257,11 @@ var Functions = class {
3560
4257
  body,
3561
4258
  headers: { "Idempotency-Key": idempotencyKey6(ikey) }
3562
4259
  });
3563
- return unwrap24(data);
4260
+ return unwrap27(data);
3564
4261
  }
3565
4262
  async update(functionId, params) {
3566
4263
  const { memoryMb, timeoutSec, ...rest } = params;
3567
- const body = stripUndefined10({
4264
+ const body = stripUndefined13({
3568
4265
  ...rest,
3569
4266
  memory_mb: memoryMb ?? rest.memory_mb,
3570
4267
  timeout_sec: timeoutSec ?? rest.timeout_sec
@@ -3573,7 +4270,7 @@ var Functions = class {
3573
4270
  `/functions/${functionId}`,
3574
4271
  body
3575
4272
  );
3576
- return unwrap24(data);
4273
+ return unwrap27(data);
3577
4274
  }
3578
4275
  async delete(functionId) {
3579
4276
  await this.http.delete(`/functions/${functionId}`);
@@ -3594,7 +4291,7 @@ var Functions = class {
3594
4291
  return data ?? {};
3595
4292
  }
3596
4293
  };
3597
- function unwrap25(payload) {
4294
+ function unwrap28(payload) {
3598
4295
  if (payload && typeof payload === "object" && "data" in payload) {
3599
4296
  return payload.data;
3600
4297
  }
@@ -3610,7 +4307,7 @@ function listItems7(payload, candidateKeys = ["data", "health_checks", "items"])
3610
4307
  }
3611
4308
  return [];
3612
4309
  }
3613
- function stripUndefined11(input) {
4310
+ function stripUndefined14(input) {
3614
4311
  return Object.fromEntries(
3615
4312
  Object.entries(input).filter(([, v]) => v !== void 0)
3616
4313
  );
@@ -3624,13 +4321,13 @@ var HealthChecks = class {
3624
4321
  }
3625
4322
  http;
3626
4323
  async list(params = {}) {
3627
- const query = stripUndefined11({ ...params });
4324
+ const query = stripUndefined14({ ...params });
3628
4325
  const data = await this.http.get("/health-checks", query);
3629
4326
  return listItems7(data);
3630
4327
  }
3631
4328
  async get(checkId) {
3632
4329
  const data = await this.http.get(`/health-checks/${checkId}`);
3633
- return unwrap25(data);
4330
+ return unwrap28(data);
3634
4331
  }
3635
4332
  async create(params) {
3636
4333
  const {
@@ -3640,7 +4337,7 @@ var HealthChecks = class {
3640
4337
  expectedStatus,
3641
4338
  ...rest
3642
4339
  } = params;
3643
- const body = stripUndefined11({
4340
+ const body = stripUndefined14({
3644
4341
  ...rest,
3645
4342
  interval_sec: intervalSec ?? rest.interval_sec,
3646
4343
  timeout_sec: timeoutSec ?? rest.timeout_sec,
@@ -3651,11 +4348,11 @@ var HealthChecks = class {
3651
4348
  body,
3652
4349
  headers: { "Idempotency-Key": idempotencyKey7(ikey) }
3653
4350
  });
3654
- return unwrap25(data);
4351
+ return unwrap28(data);
3655
4352
  }
3656
4353
  async update(checkId, params) {
3657
4354
  const { intervalSec, timeoutSec, expectedStatus, ...rest } = params;
3658
- const body = stripUndefined11({
4355
+ const body = stripUndefined14({
3659
4356
  ...rest,
3660
4357
  interval_sec: intervalSec ?? rest.interval_sec,
3661
4358
  timeout_sec: timeoutSec ?? rest.timeout_sec,
@@ -3665,7 +4362,7 @@ var HealthChecks = class {
3665
4362
  `/health-checks/${checkId}`,
3666
4363
  body
3667
4364
  );
3668
- return unwrap25(data);
4365
+ return unwrap28(data);
3669
4366
  }
3670
4367
  async delete(checkId) {
3671
4368
  await this.http.delete(`/health-checks/${checkId}`);
@@ -3673,7 +4370,7 @@ var HealthChecks = class {
3673
4370
  };
3674
4371
 
3675
4372
  // src/resources/integrations.ts
3676
- function unwrap26(payload) {
4373
+ function unwrap29(payload) {
3677
4374
  if (payload && typeof payload === "object") {
3678
4375
  const p = payload;
3679
4376
  for (const k of ["data", "integrations", "catalog", "items"]) {
@@ -3683,11 +4380,11 @@ function unwrap26(payload) {
3683
4380
  return payload;
3684
4381
  }
3685
4382
  function listItems8(payload) {
3686
- const result = unwrap26(payload);
4383
+ const result = unwrap29(payload);
3687
4384
  if (Array.isArray(result)) return result;
3688
4385
  return [];
3689
4386
  }
3690
- function stripUndefined12(input) {
4387
+ function stripUndefined15(input) {
3691
4388
  return Object.fromEntries(
3692
4389
  Object.entries(input).filter(([, v]) => v !== void 0)
3693
4390
  );
@@ -3712,14 +4409,14 @@ var Integrations = class {
3712
4409
  const data = await this.http.get(
3713
4410
  `/integrations/${provider}/start`
3714
4411
  );
3715
- return unwrap26(data);
4412
+ return unwrap29(data);
3716
4413
  }
3717
4414
  /** Force-refresh the access token for a provider. */
3718
4415
  async refresh(provider) {
3719
4416
  const data = await this.http.post(
3720
4417
  `/integrations/${provider}/refresh`
3721
4418
  );
3722
- return unwrap26(data);
4419
+ return unwrap29(data);
3723
4420
  }
3724
4421
  /** Disconnect (revoke) an integration. */
3725
4422
  async disconnect(provider) {
@@ -3739,41 +4436,41 @@ var Integrations = class {
3739
4436
  // ── Test hooks ─────────────────────────────────────────────────────────────
3740
4437
  /** Send a test message to the connected Slack channel. */
3741
4438
  async slackSendTest(params = {}) {
3742
- const body = stripUndefined12(params);
4439
+ const body = stripUndefined15(params);
3743
4440
  const data = await this.http.post(
3744
4441
  "/integrations/slack/send-test",
3745
4442
  body
3746
4443
  );
3747
- return unwrap26(data);
4444
+ return unwrap29(data);
3748
4445
  }
3749
4446
  /** Send a test message to the connected Discord channel. */
3750
4447
  async discordSendTest(params = {}) {
3751
- const body = stripUndefined12(params);
4448
+ const body = stripUndefined15(params);
3752
4449
  const data = await this.http.post(
3753
4450
  "/integrations/discord/send-test",
3754
4451
  body
3755
4452
  );
3756
- return unwrap26(data);
4453
+ return unwrap29(data);
3757
4454
  }
3758
4455
  // ── Linear dedicated controller ────────────────────────────────────────────
3759
4456
  /** Begin Linear OAuth — Linear has provider-specific error shapes. */
3760
4457
  async linearStart() {
3761
4458
  const data = await this.http.get("/integrations/linear/start");
3762
- return unwrap26(data);
4459
+ return unwrap29(data);
3763
4460
  }
3764
4461
  /** Create a Linear issue via the connected workspace. */
3765
4462
  async linearCreateIssue(params = {}) {
3766
- const body = stripUndefined12(params);
4463
+ const body = stripUndefined15(params);
3767
4464
  const data = await this.http.post(
3768
4465
  "/integrations/linear/create-issue",
3769
4466
  body
3770
4467
  );
3771
- return unwrap26(data);
4468
+ return unwrap29(data);
3772
4469
  }
3773
4470
  };
3774
4471
 
3775
4472
  // src/resources/mcp.ts
3776
- function unwrap27(payload) {
4473
+ function unwrap30(payload) {
3777
4474
  if (payload && typeof payload === "object") {
3778
4475
  const p = payload;
3779
4476
  for (const k of ["data", "mcp", "result", "items"]) {
@@ -3782,7 +4479,7 @@ function unwrap27(payload) {
3782
4479
  }
3783
4480
  return payload;
3784
4481
  }
3785
- function stripUndefined13(input) {
4482
+ function stripUndefined16(input) {
3786
4483
  return Object.fromEntries(
3787
4484
  Object.entries(input).filter(([, v]) => v !== void 0)
3788
4485
  );
@@ -3794,12 +4491,12 @@ var Mcp = class {
3794
4491
  http;
3795
4492
  /** Send a JSON-RPC request to the MCP endpoint. */
3796
4493
  async dispatch(params = {}) {
3797
- const body = stripUndefined13(params);
4494
+ const body = stripUndefined16(params);
3798
4495
  const data = await this.http.post(
3799
4496
  "/mcp",
3800
4497
  Object.keys(body).length > 0 ? body : void 0
3801
4498
  );
3802
- return unwrap27(data);
4499
+ return unwrap30(data);
3803
4500
  }
3804
4501
  /**
3805
4502
  * Open the MCP listen channel (GET).
@@ -3809,7 +4506,7 @@ var Mcp = class {
3809
4506
  */
3810
4507
  async listen() {
3811
4508
  const data = await this.http.get("/mcp");
3812
- return unwrap27(data);
4509
+ return unwrap30(data);
3813
4510
  }
3814
4511
  /** Close (terminate) the MCP session. */
3815
4512
  async close() {
@@ -3818,7 +4515,7 @@ var Mcp = class {
3818
4515
  };
3819
4516
 
3820
4517
  // src/resources/models.ts
3821
- function unwrap28(data) {
4518
+ function unwrap31(data) {
3822
4519
  if (Array.isArray(data)) return data;
3823
4520
  if (data && typeof data === "object") {
3824
4521
  const d = data;
@@ -3839,7 +4536,7 @@ var Models = class {
3839
4536
  Object.entries(filters).filter(([, v]) => v !== void 0)
3840
4537
  );
3841
4538
  const data = await this.http.get("/intelligence/models", query);
3842
- return unwrap28(data);
4539
+ return unwrap31(data);
3843
4540
  }
3844
4541
  /**
3845
4542
  * Get a single model by id.
@@ -4469,7 +5166,7 @@ function resourcePayload(params) {
4469
5166
  return { resource_type, resource_id };
4470
5167
  }
4471
5168
  function authConfig(params) {
4472
- return stripUndefined14({
5169
+ return stripUndefined17({
4473
5170
  ...params.config ?? {},
4474
5171
  signup_enabled: params.signup_enabled ?? params.signupEnabled,
4475
5172
  email_confirm_required: params.email_confirm_required ?? params.emailConfirmRequired,
@@ -4477,12 +5174,12 @@ function authConfig(params) {
4477
5174
  });
4478
5175
  }
4479
5176
  function requestBody(params) {
4480
- return stripUndefined14({
5177
+ return stripUndefined17({
4481
5178
  ...resourcePayload(params),
4482
5179
  config: authConfig(params)
4483
5180
  });
4484
5181
  }
4485
- function unwrap29(payload) {
5182
+ function unwrap32(payload) {
4486
5183
  if (payload && typeof payload === "object") {
4487
5184
  const p = payload;
4488
5185
  for (const k of ["data", "project_auth", "config", "items"]) {
@@ -4491,7 +5188,7 @@ function unwrap29(payload) {
4491
5188
  }
4492
5189
  return payload;
4493
5190
  }
4494
- function stripUndefined14(input) {
5191
+ function stripUndefined17(input) {
4495
5192
  return Object.fromEntries(
4496
5193
  Object.entries(input).filter(([, v]) => v !== void 0)
4497
5194
  );
@@ -4507,13 +5204,13 @@ var ProjectAuth = class {
4507
5204
  "/project-auth/status",
4508
5205
  resourcePayload(params)
4509
5206
  );
4510
- return unwrap29(data);
5207
+ return unwrap32(data);
4511
5208
  }
4512
5209
  /** Enable project auth. */
4513
5210
  async enable(params) {
4514
5211
  const body = requestBody(params);
4515
5212
  const data = await this.http.post("/project-auth/enable", body);
4516
- return unwrap29(data);
5213
+ return unwrap32(data);
4517
5214
  }
4518
5215
  /** Disable project auth. */
4519
5216
  async disable(params) {
@@ -4521,18 +5218,18 @@ var ProjectAuth = class {
4521
5218
  "/project-auth/disable",
4522
5219
  resourcePayload(params)
4523
5220
  );
4524
- return unwrap29(data);
5221
+ return unwrap32(data);
4525
5222
  }
4526
5223
  /** Update project-auth configuration. */
4527
5224
  async update(params) {
4528
5225
  const body = requestBody(params);
4529
5226
  const data = await this.http.patch("/project-auth/config", body);
4530
- return unwrap29(data);
5227
+ return unwrap32(data);
4531
5228
  }
4532
5229
  };
4533
5230
 
4534
5231
  // src/resources/project-integrations.ts
4535
- function unwrap30(payload) {
5232
+ function unwrap33(payload) {
4536
5233
  if (payload && typeof payload === "object") {
4537
5234
  const p = payload;
4538
5235
  for (const k of ["data", "project_integrations", "catalog", "items"]) {
@@ -4542,11 +5239,11 @@ function unwrap30(payload) {
4542
5239
  return payload;
4543
5240
  }
4544
5241
  function listItems9(payload) {
4545
- const result = unwrap30(payload);
5242
+ const result = unwrap33(payload);
4546
5243
  if (Array.isArray(result)) return result;
4547
5244
  return [];
4548
5245
  }
4549
- function stripUndefined15(input) {
5246
+ function stripUndefined18(input) {
4550
5247
  return Object.fromEntries(
4551
5248
  Object.entries(input).filter(([, v]) => v !== void 0)
4552
5249
  );
@@ -4563,7 +5260,7 @@ var ProjectIntegrations = class {
4563
5260
  http;
4564
5261
  /** List project integrations. */
4565
5262
  async list(params = {}) {
4566
- const query = stripUndefined15(params);
5263
+ const query = stripUndefined18(params);
4567
5264
  const data = await this.http.get("/project-integrations", query);
4568
5265
  return listItems9(data);
4569
5266
  }
@@ -4577,13 +5274,13 @@ var ProjectIntegrations = class {
4577
5274
  const data = await this.http.get(
4578
5275
  `/project-integrations/${integrationId}`
4579
5276
  );
4580
- return unwrap30(data);
5277
+ return unwrap33(data);
4581
5278
  }
4582
5279
  /** Create a project integration. */
4583
5280
  async create(params) {
4584
5281
  const body = stripUndefObj2(params);
4585
5282
  const data = await this.http.post("/project-integrations", body);
4586
- return unwrap30(data);
5283
+ return unwrap33(data);
4587
5284
  }
4588
5285
  /** Update a project integration. */
4589
5286
  async update(integrationId, params) {
@@ -4592,7 +5289,7 @@ var ProjectIntegrations = class {
4592
5289
  `/project-integrations/${integrationId}`,
4593
5290
  body
4594
5291
  );
4595
- return unwrap30(data);
5292
+ return unwrap33(data);
4596
5293
  }
4597
5294
  /** Delete a project integration. */
4598
5295
  async delete(integrationId) {
@@ -4601,7 +5298,7 @@ var ProjectIntegrations = class {
4601
5298
  };
4602
5299
 
4603
5300
  // src/resources/provider-defaults.ts
4604
- function unwrap31(data) {
5301
+ function unwrap34(data) {
4605
5302
  if (data && typeof data === "object") {
4606
5303
  const d = data;
4607
5304
  for (const k of ["data", "defaults", "provider_defaults", "config"]) {
@@ -4617,7 +5314,7 @@ var ProviderDefaults = class {
4617
5314
  http;
4618
5315
  /** Get the current fleet-wide provider defaults. */
4619
5316
  async list() {
4620
- return unwrap31(await this.http.get("/admin/provider-defaults"));
5317
+ return unwrap34(await this.http.get("/admin/provider-defaults"));
4621
5318
  }
4622
5319
  /** Return the defaults entry for a single provider, or {} if missing. */
4623
5320
  async get(provider) {
@@ -4633,13 +5330,13 @@ var ProviderDefaults = class {
4633
5330
  const body = Object.fromEntries(
4634
5331
  Object.entries(opts).filter(([, v]) => v !== void 0)
4635
5332
  );
4636
- return unwrap31(
5333
+ return unwrap34(
4637
5334
  await this.http.put("/admin/provider-defaults", body)
4638
5335
  );
4639
5336
  }
4640
5337
  // ── Per-tenant overrides ────────────────────────────────────────────────
4641
5338
  async getTenant(tenantId) {
4642
- return unwrap31(
5339
+ return unwrap34(
4643
5340
  await this.http.get(
4644
5341
  `/admin/tenants/${tenantId}/provider-config`
4645
5342
  )
@@ -4649,7 +5346,7 @@ var ProviderDefaults = class {
4649
5346
  const body = Object.fromEntries(
4650
5347
  Object.entries(opts).filter(([, v]) => v !== void 0)
4651
5348
  );
4652
- return unwrap31(
5349
+ return unwrap34(
4653
5350
  await this.http.put(
4654
5351
  `/admin/tenants/${tenantId}/provider-config`,
4655
5352
  body
@@ -4662,7 +5359,7 @@ var ProviderDefaults = class {
4662
5359
  };
4663
5360
 
4664
5361
  // src/resources/regions.ts
4665
- function unwrap32(payload) {
5362
+ function unwrap35(payload) {
4666
5363
  if (payload && typeof payload === "object") {
4667
5364
  const p = payload;
4668
5365
  for (const k of [
@@ -4679,7 +5376,7 @@ function unwrap32(payload) {
4679
5376
  return payload;
4680
5377
  }
4681
5378
  function listItems10(payload) {
4682
- const result = unwrap32(payload);
5379
+ const result = unwrap35(payload);
4683
5380
  if (Array.isArray(result)) return result;
4684
5381
  return [];
4685
5382
  }
@@ -4701,7 +5398,7 @@ var Regions = class {
4701
5398
  /** Get static compute pricing data. */
4702
5399
  async pricing() {
4703
5400
  const data = await this.http.get("/compute/pricing");
4704
- return unwrap32(data);
5401
+ return unwrap35(data);
4705
5402
  }
4706
5403
  /** List community computer templates. */
4707
5404
  async listTemplates() {
@@ -4713,13 +5410,21 @@ var Regions = class {
4713
5410
  const data = await this.http.get(
4714
5411
  `/compute/templates/${templateId}`
4715
5412
  );
4716
- return unwrap32(data);
5413
+ return unwrap35(data);
4717
5414
  }
4718
5415
  };
4719
5416
 
4720
5417
  // src/resources/sandboxes.ts
5418
+ function encodeContent(content) {
5419
+ const bytes = typeof content === "string" ? new TextEncoder().encode(content) : content;
5420
+ const maybeBuffer = globalThis.Buffer;
5421
+ if (maybeBuffer) return maybeBuffer.from(bytes).toString("base64");
5422
+ let bin = "";
5423
+ for (let i = 0; i < bytes.length; i++) bin += String.fromCharCode(bytes[i]);
5424
+ return btoa(bin);
5425
+ }
4721
5426
  var SANDBOX_TEMPLATE = "miosa-sandbox";
4722
- function unwrap33(payload) {
5427
+ function unwrap36(payload) {
4723
5428
  if (payload !== null && typeof payload === "object" && "data" in payload && payload.data !== void 0) {
4724
5429
  return payload.data;
4725
5430
  }
@@ -4735,7 +5440,7 @@ function listItems11(payload) {
4735
5440
  }
4736
5441
  function createBody(params = {}) {
4737
5442
  const templateId = params.templateId ?? params.template_id ?? params.image ?? SANDBOX_TEMPLATE;
4738
- return stripUndefined16({
5443
+ return stripUndefined19({
4739
5444
  template_id: templateId,
4740
5445
  cpu_count: params.cpuCount ?? params.cpu_count,
4741
5446
  memory_mb: params.memoryMb ?? params.memory_mb,
@@ -4756,20 +5461,21 @@ function createBody(params = {}) {
4756
5461
  region: params.region,
4757
5462
  entrypoint: params.entrypoint,
4758
5463
  tags: params.tags,
5464
+ slug: params.slug,
4759
5465
  external_workspace_id: params.externalWorkspaceId ?? params.external_workspace_id,
4760
5466
  external_user_id: params.externalUserId ?? params.external_user_id,
4761
5467
  external_project_id: params.externalProjectId ?? params.external_project_id
4762
5468
  });
4763
5469
  }
4764
5470
  function execBody(command, options = {}) {
4765
- return stripUndefined16({
5471
+ return stripUndefined19({
4766
5472
  command,
4767
5473
  cwd: options.cwd ?? options.workingDir ?? options.working_dir,
4768
5474
  env: options.env,
4769
5475
  timeout: options.timeout ?? options.timeoutSec ?? options.timeout_sec
4770
5476
  });
4771
5477
  }
4772
- function stripUndefined16(input) {
5478
+ function stripUndefined19(input) {
4773
5479
  return Object.fromEntries(
4774
5480
  Object.entries(input).filter(([, value]) => value !== void 0)
4775
5481
  );
@@ -4812,6 +5518,41 @@ var SandboxFiles = class {
4812
5518
  download(path) {
4813
5519
  return this.read(path);
4814
5520
  }
5521
+ /** GET /api/v1/sandboxes/{id}/files/tree — recursive directory tree. */
5522
+ async tree(path = "/workspace", depth = 3) {
5523
+ const http = this.sandbox.http;
5524
+ const response = await http.get(
5525
+ `/sandboxes/${this.sandbox.id}/files/tree`,
5526
+ { path, depth }
5527
+ );
5528
+ if (response && typeof response === "object" && "data" in response) {
5529
+ return response.data;
5530
+ }
5531
+ return response;
5532
+ }
5533
+ /** POST /api/v1/sandboxes/{id}/files/write-many — write multiple files atomically. */
5534
+ async writeMany(files) {
5535
+ const http = this.sandbox.http;
5536
+ const payload = files.map((f) => ({
5537
+ path: f.path,
5538
+ content_base64: encodeContent(f.content)
5539
+ }));
5540
+ const response = await http.post(
5541
+ `/sandboxes/${this.sandbox.id}/files/write-many`,
5542
+ { files: payload }
5543
+ );
5544
+ if (response && typeof response === "object" && "data" in response) {
5545
+ return response.data;
5546
+ }
5547
+ return response;
5548
+ }
5549
+ /** GET /api/v1/sandboxes/{id}/files/watch (SSE) — live file change events. */
5550
+ watch() {
5551
+ const http = this.sandbox.http;
5552
+ return http.stream(
5553
+ `/sandboxes/${this.sandbox.id}/files/watch`
5554
+ );
5555
+ }
4815
5556
  };
4816
5557
  var SandboxPreview = class {
4817
5558
  constructor(sandbox) {
@@ -4870,7 +5611,7 @@ var SandboxTerminal = class {
4870
5611
  const body = Object.fromEntries(
4871
5612
  Object.entries(params).filter(([, v]) => v !== void 0)
4872
5613
  );
4873
- const response = unwrap33(
5614
+ const response = unwrap36(
4874
5615
  await this.sandbox.http.post(`/sandboxes/${this.sandbox.id}/terminal`, body)
4875
5616
  );
4876
5617
  return response;
@@ -4919,7 +5660,7 @@ var SandboxPreviews = class {
4919
5660
  Object.entries(opts).filter(([, v]) => v !== void 0)
4920
5661
  )
4921
5662
  };
4922
- return unwrap33(
5663
+ return unwrap36(
4923
5664
  await this.http.post(
4924
5665
  `/sandboxes/${this.sandbox.id}/previews`,
4925
5666
  body
@@ -4927,7 +5668,7 @@ var SandboxPreviews = class {
4927
5668
  );
4928
5669
  }
4929
5670
  async get(previewId) {
4930
- return unwrap33(
5671
+ return unwrap36(
4931
5672
  await this.http.get(
4932
5673
  `/sandboxes/${this.sandbox.id}/previews/${previewId}`
4933
5674
  )
@@ -4940,7 +5681,7 @@ var SandboxPreviews = class {
4940
5681
  }
4941
5682
  /** Mint a share token for previewId. */
4942
5683
  async share(previewId, opts = {}) {
4943
- return unwrap33(
5684
+ return unwrap36(
4944
5685
  await this.http.post(
4945
5686
  `/sandboxes/${this.sandbox.id}/previews/${previewId}/share`,
4946
5687
  { ttl_seconds: opts.ttl_seconds ?? opts.expires_in_sec ?? 3600 }
@@ -4959,13 +5700,46 @@ var SandboxEnv = class {
4959
5700
  this.sandbox = sandbox;
4960
5701
  }
4961
5702
  sandbox;
4962
- /**
4963
- * Read-only listing of sandbox env vars.
4964
- * The backend has no per-name CRUD route; use Sandbox.create(env=...) to set values.
4965
- */
5703
+ get http() {
5704
+ return this.sandbox.http;
5705
+ }
5706
+ /** GET /api/v1/sandboxes/{id}/env → list of env vars. */
5707
+ async get() {
5708
+ const response = await this.http.get(
5709
+ `/sandboxes/${this.sandbox.id}/env`
5710
+ );
5711
+ if (Array.isArray(response)) return response;
5712
+ if (response && typeof response === "object") {
5713
+ const r = response;
5714
+ for (const k of ["data", "vars", "env", "items"]) {
5715
+ if (Array.isArray(r[k])) return r[k];
5716
+ }
5717
+ }
5718
+ return [];
5719
+ }
5720
+ /** @deprecated Use get() */
4966
5721
  async list() {
4967
- return unwrap33(
4968
- await this.sandbox.http.get(`/sandboxes/${this.sandbox.id}/env`)
5722
+ return this.get();
5723
+ }
5724
+ /** PUT /api/v1/sandboxes/{id}/env — set (replace) env vars. */
5725
+ async set(vars) {
5726
+ const response = await this.http.put(
5727
+ `/sandboxes/${this.sandbox.id}/env`,
5728
+ { vars }
5729
+ );
5730
+ if (Array.isArray(response)) return response;
5731
+ if (response && typeof response === "object") {
5732
+ const r = response;
5733
+ for (const k of ["data", "vars", "env", "items"]) {
5734
+ if (Array.isArray(r[k])) return r[k];
5735
+ }
5736
+ }
5737
+ return [];
5738
+ }
5739
+ /** DELETE /api/v1/sandboxes/{id}/env/{key} — remove a single env var. */
5740
+ async delete(key) {
5741
+ await this.http.delete(
5742
+ `/sandboxes/${this.sandbox.id}/env/${encodeURIComponent(key)}`
4969
5743
  );
4970
5744
  }
4971
5745
  };
@@ -4976,7 +5750,7 @@ var SandboxTags = class {
4976
5750
  sandbox;
4977
5751
  /** Replace the full tag list with tags. */
4978
5752
  async set(tags) {
4979
- return unwrap33(
5753
+ return unwrap36(
4980
5754
  await this.sandbox.http.patch(`/sandboxes/${this.sandbox.id}/tags`, { tags })
4981
5755
  );
4982
5756
  }
@@ -5001,6 +5775,10 @@ var Sandbox = class _Sandbox {
5001
5775
  this.previews = new SandboxPreviews(this);
5002
5776
  this.env = new SandboxEnv(this);
5003
5777
  this.tags = new SandboxTags(this);
5778
+ const sandboxId = data.id;
5779
+ this.secrets = new SandboxSecrets(http, sandboxId);
5780
+ this.network = new SandboxNetwork(http, sandboxId);
5781
+ this.audit = new SandboxAudit(http, sandboxId);
5004
5782
  }
5005
5783
  http;
5006
5784
  data;
@@ -5021,6 +5799,12 @@ var Sandbox = class _Sandbox {
5021
5799
  env;
5022
5800
  /** Tag replacement. */
5023
5801
  tags;
5802
+ /** Encrypted secrets + OAuth credentials scoped to this sandbox. */
5803
+ secrets;
5804
+ /** Egress allowlist + policies scoped to this sandbox. */
5805
+ network;
5806
+ /** Egress audit log + live tail scoped to this sandbox. */
5807
+ audit;
5024
5808
  get id() {
5025
5809
  return this.data.id;
5026
5810
  }
@@ -5034,14 +5818,14 @@ var Sandbox = class _Sandbox {
5034
5818
  return this.data.template_id ?? this.data.image_id ?? "";
5035
5819
  }
5036
5820
  async refresh() {
5037
- this.data = unwrap33(
5821
+ this.data = unwrap36(
5038
5822
  await this.http.get(`/sandboxes/${this.id}`)
5039
5823
  );
5040
5824
  return this;
5041
5825
  }
5042
5826
  async runExec(command, options) {
5043
5827
  this.assertRunning("exec");
5044
- const response = unwrap33(
5828
+ const response = unwrap36(
5045
5829
  await this.http.post(
5046
5830
  `/sandboxes/${this.id}/exec`,
5047
5831
  execBody(command, options)
@@ -5089,7 +5873,7 @@ var Sandbox = class _Sandbox {
5089
5873
  }
5090
5874
  async listFiles(path = "/workspace") {
5091
5875
  this.assertRunning("files.list");
5092
- const response = unwrap33(
5876
+ const response = unwrap36(
5093
5877
  await this.http.get(
5094
5878
  `/sandboxes/${this.id}/files`,
5095
5879
  { path }
@@ -5099,7 +5883,7 @@ var Sandbox = class _Sandbox {
5099
5883
  }
5100
5884
  async statFile(path) {
5101
5885
  this.assertRunning("files.stat");
5102
- return unwrap33(
5886
+ return unwrap36(
5103
5887
  await this.http.post(
5104
5888
  `/sandboxes/${this.id}/files/stat`,
5105
5889
  { path }
@@ -5108,7 +5892,7 @@ var Sandbox = class _Sandbox {
5108
5892
  }
5109
5893
  async expose(port) {
5110
5894
  this.assertRunning("expose");
5111
- const response = unwrap33(
5895
+ const response = unwrap36(
5112
5896
  await this.http.post(
5113
5897
  `/sandboxes/${this.id}/expose`,
5114
5898
  port === void 0 ? {} : { port }
@@ -5118,7 +5902,7 @@ var Sandbox = class _Sandbox {
5118
5902
  }
5119
5903
  async startTemplate(options = {}) {
5120
5904
  this.assertRunning("startTemplate");
5121
- return unwrap33(
5905
+ return unwrap36(
5122
5906
  await this.http.post(
5123
5907
  `/sandboxes/${this.id}/template/start`,
5124
5908
  options
@@ -5126,7 +5910,7 @@ var Sandbox = class _Sandbox {
5126
5910
  );
5127
5911
  }
5128
5912
  async getArtifacts() {
5129
- return unwrap33(
5913
+ return unwrap36(
5130
5914
  await this.http.get(
5131
5915
  `/sandboxes/${this.id}/artifacts`
5132
5916
  )
@@ -5137,7 +5921,7 @@ var Sandbox = class _Sandbox {
5137
5921
  `/sandboxes/${this.id}/logs`,
5138
5922
  { lines }
5139
5923
  );
5140
- return unwrap33(response);
5924
+ return unwrap36(response);
5141
5925
  }
5142
5926
  streamLogs() {
5143
5927
  return this.http.stream(
@@ -5146,7 +5930,7 @@ var Sandbox = class _Sandbox {
5146
5930
  }
5147
5931
  async createSnapshot(comment) {
5148
5932
  this.assertRunning("snapshots.create");
5149
- return unwrap33(
5933
+ return unwrap36(
5150
5934
  await this.http.post(
5151
5935
  `/sandboxes/${this.id}/snapshots`,
5152
5936
  comment ? { comment } : {}
@@ -5154,14 +5938,14 @@ var Sandbox = class _Sandbox {
5154
5938
  );
5155
5939
  }
5156
5940
  async listSnapshots() {
5157
- return unwrap33(
5941
+ return unwrap36(
5158
5942
  await this.http.get(
5159
5943
  `/sandboxes/${this.id}/snapshots`
5160
5944
  )
5161
5945
  );
5162
5946
  }
5163
5947
  async restoreSnapshot(snapshotId) {
5164
- const data = unwrap33(
5948
+ const data = unwrap36(
5165
5949
  await this.http.post(
5166
5950
  `/sandboxes/${this.id}/restore/${snapshotId}`,
5167
5951
  {}
@@ -5172,8 +5956,55 @@ var Sandbox = class _Sandbox {
5172
5956
  async deleteSnapshot(snapshotId) {
5173
5957
  await this.http.delete(`/sandboxes/${this.id}/snapshots/${snapshotId}`);
5174
5958
  }
5959
+ /**
5960
+ * Fork (clone) this sandbox into a new sandbox via copy-on-write snapshot.
5961
+ * The original sandbox continues running unchanged.
5962
+ */
5963
+ async fork(opts = {}) {
5964
+ this.assertRunning("fork");
5965
+ const body = {};
5966
+ if (opts.name !== void 0) body.name = opts.name;
5967
+ if (opts.metadata !== void 0) body.metadata = opts.metadata;
5968
+ const data = unwrap36(
5969
+ await this.http.post(
5970
+ `/sandboxes/${this.id}/fork`,
5971
+ body
5972
+ )
5973
+ );
5974
+ return new _Sandbox(this.http, data);
5975
+ }
5976
+ /**
5977
+ * PATCH /api/v1/sandboxes/{id} — update mutable sandbox fields.
5978
+ */
5979
+ async update(params) {
5980
+ const body = {};
5981
+ for (const [k, v] of Object.entries(params)) {
5982
+ if (v !== void 0) body[k] = v;
5983
+ }
5984
+ const data = unwrap36(
5985
+ await this.http.patch(
5986
+ `/sandboxes/${this.id}`,
5987
+ body
5988
+ )
5989
+ );
5990
+ this.data = data;
5991
+ return this;
5992
+ }
5993
+ /**
5994
+ * POST /api/v1/sandboxes/{id}/preview-token → {token, url, expires_at, scope}
5995
+ */
5996
+ async previewToken(expiresIn = 3600, scope = "read") {
5997
+ const raw = await this.http.post(
5998
+ `/sandboxes/${this.id}/preview-token`,
5999
+ { expires_in: expiresIn, scope }
6000
+ );
6001
+ if (raw && typeof raw === "object" && "data" in raw) {
6002
+ return raw.data;
6003
+ }
6004
+ return raw;
6005
+ }
5175
6006
  async pause() {
5176
- const data = unwrap33(
6007
+ const data = unwrap36(
5177
6008
  await this.http.post(
5178
6009
  `/sandboxes/${this.id}/pause`,
5179
6010
  {}
@@ -5183,7 +6014,7 @@ var Sandbox = class _Sandbox {
5183
6014
  return this;
5184
6015
  }
5185
6016
  async resume() {
5186
- const data = unwrap33(
6017
+ const data = unwrap36(
5187
6018
  await this.http.post(
5188
6019
  `/sandboxes/${this.id}/resume`,
5189
6020
  {}
@@ -5196,7 +6027,7 @@ var Sandbox = class _Sandbox {
5196
6027
  const idempotencyKey11 = params.idempotencyKey ?? params.idempotency_key;
5197
6028
  const requestOptions = {
5198
6029
  method: "POST",
5199
- body: stripUndefined16({
6030
+ body: stripUndefined19({
5200
6031
  name: params.name,
5201
6032
  deployment_id: params.deploymentId ?? params.deployment_id,
5202
6033
  output_path: params.outputPath ?? params.output_path ?? params.path ?? params.sourcePath ?? params.source_path,
@@ -5209,7 +6040,7 @@ var Sandbox = class _Sandbox {
5209
6040
  if (idempotencyKey11) {
5210
6041
  requestOptions.headers = { "Idempotency-Key": idempotencyKey11 };
5211
6042
  }
5212
- return unwrap33(
6043
+ return unwrap36(
5213
6044
  await this.http.request(
5214
6045
  `/sandboxes/${this.id}/deploy`,
5215
6046
  requestOptions
@@ -5218,12 +6049,102 @@ var Sandbox = class _Sandbox {
5218
6049
  }
5219
6050
  /** Check readiness of the sandbox (GET /sandboxes/:id/readiness). */
5220
6051
  async readiness() {
5221
- return unwrap33(
6052
+ return unwrap36(
5222
6053
  await this.http.get(
5223
6054
  `/sandboxes/${this.id}/readiness`
5224
6055
  )
5225
6056
  );
5226
6057
  }
6058
+ /**
6059
+ * Block until the sandbox reports ready, or *timeout* seconds elapse.
6060
+ *
6061
+ * When `stream` is `true` (the default) this opens an SSE connection
6062
+ * to `GET /sandboxes/:id/readiness/stream` and waits for an
6063
+ * `event: ready` frame. The server emits `ready` immediately if the
6064
+ * sandbox is already ready, otherwise as soon as the readiness PubSub
6065
+ * message fires.
6066
+ *
6067
+ * Returns `true` once the sandbox is ready, `false` on `event: timeout`
6068
+ * or when the local timeout elapses before ready.
6069
+ *
6070
+ * If the SSE endpoint returns 404 (server pre-dates the streaming
6071
+ * endpoint) this transparently falls back to polling
6072
+ * {@link readiness} every 10 ms until ready or timeout.
6073
+ */
6074
+ async waitUntilReady(options = {}) {
6075
+ const timeout = options.timeout ?? 30;
6076
+ const stream = options.stream ?? true;
6077
+ if (stream) {
6078
+ const sseResult = await this.tryReadinessStream(timeout);
6079
+ if (sseResult !== null) return sseResult;
6080
+ }
6081
+ const deadlineMs = Date.now() + timeout * 1e3;
6082
+ while (Date.now() < deadlineMs) {
6083
+ try {
6084
+ const data = await this.readiness();
6085
+ if (data.ready === true || data.status === "ready") return true;
6086
+ } catch {
6087
+ }
6088
+ await new Promise((resolve) => setTimeout(resolve, 10));
6089
+ }
6090
+ return false;
6091
+ }
6092
+ /**
6093
+ * Returns `true` / `false` for terminal SSE events, or `null` if the
6094
+ * stream endpoint is unavailable (404 or transport error) so callers
6095
+ * can fall back to polling.
6096
+ */
6097
+ async tryReadinessStream(timeoutSec) {
6098
+ const abort = new AbortController();
6099
+ const timer = setTimeout(() => abort.abort(), (timeoutSec + 5) * 1e3);
6100
+ try {
6101
+ const headers = {
6102
+ Authorization: `Bearer ${this.http.apiKey}`,
6103
+ Accept: "text/event-stream",
6104
+ "User-Agent": "@miosa/sdk/1.0.0"
6105
+ };
6106
+ const response = await fetch(
6107
+ `${this.http.baseUrl}/sandboxes/${this.id}/readiness/stream`,
6108
+ { method: "GET", headers, signal: abort.signal }
6109
+ );
6110
+ if (response.status === 404) return null;
6111
+ if (!response.ok || !response.body) return null;
6112
+ const reader = response.body.getReader();
6113
+ const decoder = new TextDecoder();
6114
+ let buffer = "";
6115
+ try {
6116
+ while (true) {
6117
+ const { done, value } = await reader.read();
6118
+ if (done) break;
6119
+ buffer += decoder.decode(value, { stream: true });
6120
+ let newlineIdx;
6121
+ while ((newlineIdx = buffer.indexOf("\n")) !== -1) {
6122
+ const line = buffer.slice(0, newlineIdx).replace(/\r$/, "");
6123
+ buffer = buffer.slice(newlineIdx + 1);
6124
+ if (line.startsWith("event:")) {
6125
+ const evt = line.slice(6).trim();
6126
+ if (evt === "ready") return true;
6127
+ if (evt === "timeout") return false;
6128
+ }
6129
+ }
6130
+ }
6131
+ } finally {
6132
+ try {
6133
+ reader.releaseLock();
6134
+ } catch {
6135
+ }
6136
+ }
6137
+ return null;
6138
+ } catch {
6139
+ return null;
6140
+ } finally {
6141
+ clearTimeout(timer);
6142
+ try {
6143
+ abort.abort();
6144
+ } catch {
6145
+ }
6146
+ }
6147
+ }
5227
6148
  async destroy() {
5228
6149
  if (this.data.state === "destroyed") return;
5229
6150
  await this.http.delete(`/sandboxes/${this.id}`);
@@ -5267,7 +6188,7 @@ var Sandboxes = class {
5267
6188
  if (idempotencyKey11) {
5268
6189
  requestOptions.headers = { "Idempotency-Key": idempotencyKey11 };
5269
6190
  }
5270
- const data = unwrap33(
6191
+ const data = unwrap36(
5271
6192
  await this.http.request(
5272
6193
  "/sandboxes",
5273
6194
  requestOptions
@@ -5286,7 +6207,7 @@ var Sandboxes = class {
5286
6207
  return listItems11(data).map((item) => new Sandbox(this.http, item));
5287
6208
  }
5288
6209
  async get(id) {
5289
- const data = unwrap33(
6210
+ const data = unwrap36(
5290
6211
  await this.http.get(`/sandboxes/${id}`)
5291
6212
  );
5292
6213
  return new Sandbox(this.http, data);
@@ -5321,7 +6242,7 @@ var Sandboxes = class {
5321
6242
  async createTemplate(params) {
5322
6243
  const response = await this.http.post(
5323
6244
  "/sandbox-templates",
5324
- stripUndefined16({
6245
+ stripUndefined19({
5325
6246
  name: params.name,
5326
6247
  slug: params.slug,
5327
6248
  description: params.description,
@@ -5329,29 +6250,29 @@ var Sandboxes = class {
5329
6250
  metadata: params.metadata
5330
6251
  })
5331
6252
  );
5332
- return unwrap33(response);
6253
+ return unwrap36(response);
5333
6254
  }
5334
6255
  async createTemplateBuild(templateId, params = {}) {
5335
6256
  const response = await this.http.post(
5336
6257
  `/sandbox-templates/${templateId}/builds`,
5337
- stripUndefined16({
6258
+ stripUndefined19({
5338
6259
  build_spec: params.buildSpec ?? params.build_spec,
5339
6260
  metadata: params.metadata
5340
6261
  })
5341
6262
  );
5342
- return unwrap33(response);
6263
+ return unwrap36(response);
5343
6264
  }
5344
6265
  async listTemplateBuilds(templateId) {
5345
6266
  const response = await this.http.get(
5346
6267
  `/sandbox-templates/${templateId}/builds`
5347
6268
  );
5348
- return unwrap33(response);
6269
+ return unwrap36(response);
5349
6270
  }
5350
6271
  async getTemplateBuild(buildId) {
5351
6272
  const response = await this.http.get(
5352
6273
  `/sandbox-template-builds/${buildId}`
5353
6274
  );
5354
- return unwrap33(response);
6275
+ return unwrap36(response);
5355
6276
  }
5356
6277
  };
5357
6278
  function toBase642(bytes) {
@@ -5363,7 +6284,7 @@ function toBase642(bytes) {
5363
6284
  }
5364
6285
  return btoa(binary);
5365
6286
  }
5366
- function unwrap34(payload) {
6287
+ function unwrap37(payload) {
5367
6288
  if (payload && typeof payload === "object" && "data" in payload) {
5368
6289
  return payload.data;
5369
6290
  }
@@ -5379,7 +6300,7 @@ function listItems12(payload, candidateKeys = ["data", "templates", "builds", "i
5379
6300
  }
5380
6301
  return [];
5381
6302
  }
5382
- function stripUndefined17(input) {
6303
+ function stripUndefined20(input) {
5383
6304
  return Object.fromEntries(
5384
6305
  Object.entries(input).filter(([, v]) => v !== void 0)
5385
6306
  );
@@ -5406,7 +6327,7 @@ var SandboxTemplates = class {
5406
6327
  const data = await this.http.get(
5407
6328
  `/sandbox-templates/${templateId}`
5408
6329
  );
5409
- return unwrap34(data);
6330
+ return unwrap37(data);
5410
6331
  }
5411
6332
  async create(params) {
5412
6333
  const {
@@ -5416,7 +6337,7 @@ var SandboxTemplates = class {
5416
6337
  name,
5417
6338
  ...rest
5418
6339
  } = params;
5419
- const body = stripUndefined17({
6340
+ const body = stripUndefined20({
5420
6341
  name,
5421
6342
  build_spec: buildSpec ?? build_spec,
5422
6343
  ...rest
@@ -5426,7 +6347,7 @@ var SandboxTemplates = class {
5426
6347
  body,
5427
6348
  headers: { "Idempotency-Key": idempotencyKey8(ikey) }
5428
6349
  });
5429
- return unwrap34(data);
6350
+ return unwrap37(data);
5430
6351
  }
5431
6352
  async buildSpecSchema() {
5432
6353
  const data = await this.http.get("/sandbox-templates/build-spec");
@@ -5450,7 +6371,7 @@ var SandboxTemplates = class {
5450
6371
  }
5451
6372
  async createBuild(templateId, params = {}) {
5452
6373
  const { idempotencyKey: ikey, ...rest } = params;
5453
- const body = stripUndefined17(rest);
6374
+ const body = stripUndefined20(rest);
5454
6375
  const data = await this.http.request(
5455
6376
  `/sandbox-templates/${templateId}/builds`,
5456
6377
  {
@@ -5459,12 +6380,12 @@ var SandboxTemplates = class {
5459
6380
  headers: { "Idempotency-Key": idempotencyKey8(ikey) }
5460
6381
  }
5461
6382
  );
5462
- return unwrap34(data);
6383
+ return unwrap37(data);
5463
6384
  }
5464
6385
  };
5465
6386
 
5466
6387
  // src/resources/settings.ts
5467
- function unwrap35(payload) {
6388
+ function unwrap38(payload) {
5468
6389
  if (payload && typeof payload === "object") {
5469
6390
  const p = payload;
5470
6391
  for (const k of [
@@ -5480,11 +6401,11 @@ function unwrap35(payload) {
5480
6401
  return payload;
5481
6402
  }
5482
6403
  function listItems13(payload) {
5483
- const result = unwrap35(payload);
6404
+ const result = unwrap38(payload);
5484
6405
  if (Array.isArray(result)) return result;
5485
6406
  return [];
5486
6407
  }
5487
- function stripUndefined18(input) {
6408
+ function stripUndefined21(input) {
5488
6409
  return Object.fromEntries(
5489
6410
  Object.entries(input).filter(([, v]) => v !== void 0)
5490
6411
  );
@@ -5497,46 +6418,46 @@ var Settings = class {
5497
6418
  /** Get the current tenant settings. */
5498
6419
  async get() {
5499
6420
  const data = await this.http.get("/settings");
5500
- return unwrap35(data);
6421
+ return unwrap38(data);
5501
6422
  }
5502
6423
  /** Update tenant settings. */
5503
6424
  async update(params) {
5504
- const body = stripUndefined18(params);
6425
+ const body = stripUndefined21(params);
5505
6426
  const data = await this.http.put("/settings", body);
5506
- return unwrap35(data);
6427
+ return unwrap38(data);
5507
6428
  }
5508
6429
  // ── Branding ──────────────────────────────────────────────────────────────
5509
6430
  /** Get tenant branding (logo, colors, custom wordmark). */
5510
6431
  async getBranding() {
5511
6432
  const data = await this.http.get("/settings/branding");
5512
- return unwrap35(data);
6433
+ return unwrap38(data);
5513
6434
  }
5514
6435
  /** Update tenant branding. */
5515
6436
  async updateBranding(params) {
5516
- const body = stripUndefined18(params);
6437
+ const body = stripUndefined21(params);
5517
6438
  const data = await this.http.put("/settings/branding", body);
5518
- return unwrap35(data);
6439
+ return unwrap38(data);
5519
6440
  }
5520
6441
  // ── Read-only reference data ───────────────────────────────────────────────
5521
6442
  /** Get tenant-scoped compute pricing. */
5522
6443
  async computePricing() {
5523
6444
  const data = await this.http.get("/settings/compute-pricing");
5524
- return unwrap35(data);
6445
+ return unwrap38(data);
5525
6446
  }
5526
6447
  /** Get tenant-scoped GPU pricing. */
5527
6448
  async gpuPricing() {
5528
6449
  const data = await this.http.get("/settings/gpu-pricing");
5529
- return unwrap35(data);
6450
+ return unwrap38(data);
5530
6451
  }
5531
6452
  /** List models available to this tenant. */
5532
6453
  async availableModels() {
5533
6454
  const data = await this.http.get("/settings/available-models");
5534
- return unwrap35(data);
6455
+ return unwrap38(data);
5535
6456
  }
5536
6457
  /** List regions enabled for this tenant. */
5537
6458
  async regions() {
5538
6459
  const data = await this.http.get("/settings/regions");
5539
- return unwrap35(data);
6460
+ return unwrap38(data);
5540
6461
  }
5541
6462
  // ── BYOK provider keys ────────────────────────────────────────────────────
5542
6463
  /** List tenant-level BYOK provider keys (Anthropic, OpenAI, etc.). */
@@ -5546,12 +6467,12 @@ var Settings = class {
5546
6467
  }
5547
6468
  /** Create or update a BYOK provider key. */
5548
6469
  async upsertProviderKey(provider, params) {
5549
- const body = stripUndefined18(params);
6470
+ const body = stripUndefined21(params);
5550
6471
  const data = await this.http.put(
5551
6472
  `/settings/provider-keys/${provider}`,
5552
6473
  body
5553
6474
  );
5554
- return unwrap35(data);
6475
+ return unwrap38(data);
5555
6476
  }
5556
6477
  /** Delete a BYOK provider key. */
5557
6478
  async deleteProviderKey(provider) {
@@ -5560,7 +6481,7 @@ var Settings = class {
5560
6481
  };
5561
6482
 
5562
6483
  // src/resources/snapshots-standalone.ts
5563
- function unwrap36(data) {
6484
+ function unwrap39(data) {
5564
6485
  if (data && typeof data === "object") {
5565
6486
  const d = data;
5566
6487
  for (const k of ["data", "snapshots", "items"]) {
@@ -5569,7 +6490,7 @@ function unwrap36(data) {
5569
6490
  }
5570
6491
  return data;
5571
6492
  }
5572
- function unwrapList9(data) {
6493
+ function unwrapList12(data) {
5573
6494
  if (Array.isArray(data)) return data;
5574
6495
  if (data && typeof data === "object") {
5575
6496
  const d = data;
@@ -5588,17 +6509,17 @@ var SnapshotsStandalone = class {
5588
6509
  const query = Object.fromEntries(
5589
6510
  Object.entries(filters).filter(([, v]) => v !== void 0)
5590
6511
  );
5591
- return unwrapList9(await this.http.get("/admin/snapshots", query));
6512
+ return unwrapList12(await this.http.get("/admin/snapshots", query));
5592
6513
  }
5593
6514
  async get(snapshotId) {
5594
- return unwrap36(
6515
+ return unwrap39(
5595
6516
  await this.http.get(`/admin/snapshots/${snapshotId}`)
5596
6517
  );
5597
6518
  }
5598
6519
  };
5599
6520
 
5600
6521
  // src/resources/storage.ts
5601
- function unwrap37(payload) {
6522
+ function unwrap40(payload) {
5602
6523
  if (payload && typeof payload === "object" && "data" in payload) {
5603
6524
  return payload.data;
5604
6525
  }
@@ -5614,7 +6535,7 @@ function listItems14(payload, candidateKeys = ["data", "buckets", "objects", "it
5614
6535
  }
5615
6536
  return [];
5616
6537
  }
5617
- function stripUndefined19(input) {
6538
+ function stripUndefined22(input) {
5618
6539
  return Object.fromEntries(
5619
6540
  Object.entries(input).filter(([, v]) => v !== void 0)
5620
6541
  );
@@ -5631,24 +6552,24 @@ var Storage = class {
5631
6552
  }
5632
6553
  async createBucket(params) {
5633
6554
  const { name, public: isPublic, visibility, ...rest } = params;
5634
- const body = stripUndefined19({
6555
+ const body = stripUndefined22({
5635
6556
  name,
5636
6557
  visibility: visibility ?? (isPublic === void 0 ? void 0 : isPublic ? "public" : "private"),
5637
6558
  ...rest
5638
6559
  });
5639
6560
  const data = await this.http.post("/storage/buckets", body);
5640
- return unwrap37(data);
6561
+ return unwrap40(data);
5641
6562
  }
5642
6563
  async getBucket(bucketId) {
5643
6564
  const data = await this.http.get(`/storage/buckets/${bucketId}`);
5644
- return unwrap37(data);
6565
+ return unwrap40(data);
5645
6566
  }
5646
6567
  async deleteBucket(bucketId) {
5647
6568
  await this.http.delete(`/storage/buckets/${bucketId}`);
5648
6569
  }
5649
6570
  // ── Objects ────────────────────────────────────────────────────────────────
5650
6571
  async listObjects(bucketId, params = {}) {
5651
- const query = stripUndefined19({
6572
+ const query = stripUndefined22({
5652
6573
  prefix: params.prefix,
5653
6574
  max_keys: params.max_keys ?? params.maxKeys ?? params.limit,
5654
6575
  marker: params.marker ?? params.cursor
@@ -5679,46 +6600,179 @@ var Storage = class {
5679
6600
  `/storage/buckets/${bucketId}/objects/${key}`
5680
6601
  );
5681
6602
  }
5682
- // ── Presigned URLs ─────────────────────────────────────────────────────────
5683
- async presign(bucketId, params) {
5684
- const operationMethod = params.operation === "put" ? "PUT" : params.operation === "get" ? "GET" : void 0;
5685
- const body = stripUndefined19({
5686
- key: params.key,
5687
- method: params.method ?? operationMethod ?? "GET",
5688
- expires_in: params.expiresIn ?? params.expires_in ?? params.expiresInSec ?? params.expires_in_sec ?? 3600
5689
- });
5690
- const data = await this.http.post(
5691
- `/storage/buckets/${bucketId}/presign`,
5692
- body
6603
+ // ── Presigned URLs ─────────────────────────────────────────────────────────
6604
+ async presign(bucketId, params) {
6605
+ const operationMethod = params.operation === "put" ? "PUT" : params.operation === "get" ? "GET" : void 0;
6606
+ const body = stripUndefined22({
6607
+ key: params.key,
6608
+ method: params.method ?? operationMethod ?? "GET",
6609
+ expires_in: params.expiresIn ?? params.expires_in ?? params.expiresInSec ?? params.expires_in_sec ?? 3600
6610
+ });
6611
+ const data = await this.http.post(
6612
+ `/storage/buckets/${bucketId}/presign`,
6613
+ body
6614
+ );
6615
+ return unwrap40(data);
6616
+ }
6617
+ };
6618
+
6619
+ // src/resources/org-invites.ts
6620
+ var OrgInvites = class {
6621
+ constructor(http) {
6622
+ this.http = http;
6623
+ }
6624
+ http;
6625
+ /**
6626
+ * Create an org invite and dispatch the invite email.
6627
+ *
6628
+ * The invite URL in the response is host-aware: on white-label tenants it
6629
+ * uses the custom domain so the recipient lands on the branded experience.
6630
+ * Requires `admin` or `owner` role in the tenant.
6631
+ *
6632
+ * `POST /tenants/:id/invites`
6633
+ */
6634
+ async create(tenantId, params) {
6635
+ const res = await this.http.post(
6636
+ `/tenants/${tenantId}/invites`,
6637
+ params
6638
+ );
6639
+ return res.data;
6640
+ }
6641
+ /**
6642
+ * List all pending (non-expired, non-accepted, non-revoked) org invites.
6643
+ *
6644
+ * Requires `admin` or `owner` role.
6645
+ *
6646
+ * `GET /tenants/:id/invites`
6647
+ */
6648
+ async list(tenantId) {
6649
+ const res = await this.http.get(
6650
+ `/tenants/${tenantId}/invites`
6651
+ );
6652
+ return res.data ?? [];
6653
+ }
6654
+ /**
6655
+ * Revoke a pending org invite.
6656
+ *
6657
+ * Returns `409` when the invite was already legitimately accepted.
6658
+ * Requires `admin` or `owner` role.
6659
+ *
6660
+ * `DELETE /tenants/:id/invites/:invite_id`
6661
+ */
6662
+ async revoke(tenantId, inviteId) {
6663
+ return this.http.delete(
6664
+ `/tenants/${tenantId}/invites/${inviteId}`
6665
+ );
6666
+ }
6667
+ /**
6668
+ * Preview an org invite by token (no auth required).
6669
+ *
6670
+ * Returns `null` when the token is unknown or has been revoked.
6671
+ *
6672
+ * `GET /invites/:token`
6673
+ */
6674
+ async preview(token) {
6675
+ try {
6676
+ const res = await this.http.get(
6677
+ `/invites/${token}`
6678
+ );
6679
+ return res.data ?? null;
6680
+ } catch {
6681
+ return null;
6682
+ }
6683
+ }
6684
+ /**
6685
+ * Accept an org invite on behalf of the authenticated user.
6686
+ *
6687
+ * The caller's JWT email must match the invite email (case-insensitive).
6688
+ * On success inserts a `tenant_members` row.
6689
+ *
6690
+ * Error responses:
6691
+ * - `400` — invalid or expired token.
6692
+ * - `422 EMAIL_MISMATCH` — JWT email does not match the invite email.
6693
+ *
6694
+ * `POST /invites/:token/accept`
6695
+ */
6696
+ async accept(token) {
6697
+ return this.http.post(
6698
+ `/invites/${token}/accept`,
6699
+ {}
5693
6700
  );
5694
- return unwrap37(data);
5695
6701
  }
5696
6702
  };
5697
6703
 
5698
6704
  // src/resources/tenant.ts
5699
- function unwrap38(payload) {
6705
+ function unwrap41(payload) {
5700
6706
  if (payload && typeof payload === "object") {
5701
6707
  const p = payload;
5702
- for (const k of ["data", "tenant", "items"]) {
6708
+ for (const k of ["data", "tenant", "branding", "preview_domain", "items"]) {
5703
6709
  if (k in p) return p[k];
5704
6710
  }
5705
6711
  }
5706
6712
  return payload;
5707
6713
  }
6714
+ var PreviewDomain = class {
6715
+ constructor(http) {
6716
+ this.http = http;
6717
+ }
6718
+ http;
6719
+ /** GET /api/v1/tenant/preview-domain → {domain, verified_at, cname_target} */
6720
+ async get() {
6721
+ return unwrap41(await this.http.get("/tenant/preview-domain"));
6722
+ }
6723
+ /** PUT /api/v1/tenant/preview-domain — set the preview domain. */
6724
+ async set(domain) {
6725
+ return unwrap41(
6726
+ await this.http.put("/tenant/preview-domain", { domain })
6727
+ );
6728
+ }
6729
+ /** POST /api/v1/tenant/preview-domain/verify → {verified, target, records} */
6730
+ async verify() {
6731
+ return unwrap41(
6732
+ await this.http.post("/tenant/preview-domain/verify", {})
6733
+ );
6734
+ }
6735
+ /** DELETE /api/v1/tenant/preview-domain */
6736
+ async delete() {
6737
+ await this.http.delete("/tenant/preview-domain");
6738
+ }
6739
+ };
6740
+ var Branding = class {
6741
+ constructor(http) {
6742
+ this.http = http;
6743
+ }
6744
+ http;
6745
+ /** GET /api/v1/tenant/branding */
6746
+ async get() {
6747
+ return unwrap41(await this.http.get("/tenant/branding"));
6748
+ }
6749
+ /** PUT /api/v1/tenant/branding — keys: product_name, logo_url, support_url, support_email, primary_color, background_color */
6750
+ async set(branding) {
6751
+ return unwrap41(await this.http.put("/tenant/branding", branding));
6752
+ }
6753
+ /** DELETE /api/v1/tenant/branding */
6754
+ async delete() {
6755
+ await this.http.delete("/tenant/branding");
6756
+ }
6757
+ };
5708
6758
  var Tenant = class {
5709
6759
  constructor(http) {
5710
6760
  this.http = http;
6761
+ this.preview_domain = new PreviewDomain(http);
6762
+ this.branding = new Branding(http);
5711
6763
  }
5712
6764
  http;
6765
+ preview_domain;
6766
+ branding;
5713
6767
  /** Get the current tenant's plan, limits, and live usage counters. */
5714
6768
  async current() {
5715
6769
  const data = await this.http.get("/tenant/plan");
5716
- return unwrap38(data);
6770
+ return unwrap41(data);
5717
6771
  }
5718
6772
  };
5719
6773
 
5720
6774
  // src/resources/usage.ts
5721
- function unwrap39(payload) {
6775
+ function unwrap42(payload) {
5722
6776
  if (payload && typeof payload === "object") {
5723
6777
  const p = payload;
5724
6778
  for (const k of ["data", "usage", "sessions", "summary", "items"]) {
@@ -5727,7 +6781,7 @@ function unwrap39(payload) {
5727
6781
  }
5728
6782
  return payload;
5729
6783
  }
5730
- function stripUndefined20(input) {
6784
+ function stripUndefined23(input) {
5731
6785
  return Object.fromEntries(
5732
6786
  Object.entries(input).filter(([, v]) => v !== void 0)
5733
6787
  );
@@ -5740,24 +6794,24 @@ var Usage = class {
5740
6794
  /** Get the current period usage summary. */
5741
6795
  async current() {
5742
6796
  const data = await this.http.get("/usage/summary");
5743
- return unwrap39(data);
6797
+ return unwrap42(data);
5744
6798
  }
5745
6799
  /** List per-session metering events. */
5746
6800
  async sessions(params = {}) {
5747
- const query = stripUndefined20(params);
6801
+ const query = stripUndefined23(params);
5748
6802
  const data = await this.http.get("/usage/sessions", query);
5749
- const result = unwrap39(data);
6803
+ const result = unwrap42(data);
5750
6804
  if (Array.isArray(result)) return result;
5751
6805
  return [];
5752
6806
  }
5753
6807
  /** Get a usage report for a period. */
5754
6808
  async report(params = {}) {
5755
- const query = stripUndefined20(params);
6809
+ const query = stripUndefined23(params);
5756
6810
  const data = await this.http.get("/usage/summary", query);
5757
- return unwrap39(data);
6811
+ return unwrap42(data);
5758
6812
  }
5759
6813
  };
5760
- function unwrap40(payload) {
6814
+ function unwrap43(payload) {
5761
6815
  if (payload && typeof payload === "object" && "data" in payload) {
5762
6816
  return payload.data;
5763
6817
  }
@@ -5773,7 +6827,7 @@ function listItems15(payload, candidateKeys = ["data", "volumes", "items"]) {
5773
6827
  }
5774
6828
  return [];
5775
6829
  }
5776
- function stripUndefined21(input) {
6830
+ function stripUndefined24(input) {
5777
6831
  return Object.fromEntries(
5778
6832
  Object.entries(input).filter(([, v]) => v !== void 0)
5779
6833
  );
@@ -5787,17 +6841,17 @@ var Volumes = class {
5787
6841
  }
5788
6842
  http;
5789
6843
  async list(params = {}) {
5790
- const query = stripUndefined21({ ...params });
6844
+ const query = stripUndefined24({ ...params });
5791
6845
  const data = await this.http.get("/volumes", query);
5792
6846
  return listItems15(data);
5793
6847
  }
5794
6848
  async get(volumeId) {
5795
6849
  const data = await this.http.get(`/volumes/${volumeId}`);
5796
- return unwrap40(data);
6850
+ return unwrap43(data);
5797
6851
  }
5798
6852
  async create(params) {
5799
6853
  const { idempotencyKey: ikey, sizeGb, ...rest } = params;
5800
- const body = stripUndefined21({
6854
+ const body = stripUndefined24({
5801
6855
  ...rest,
5802
6856
  size_gb: sizeGb ?? rest.size_gb
5803
6857
  });
@@ -5806,13 +6860,36 @@ var Volumes = class {
5806
6860
  body,
5807
6861
  headers: { "Idempotency-Key": idempotencyKey9(ikey) }
5808
6862
  });
5809
- return unwrap40(data);
6863
+ return unwrap43(data);
5810
6864
  }
5811
6865
  async delete(volumeId) {
5812
6866
  await this.http.delete(`/volumes/${volumeId}`);
5813
6867
  }
5814
6868
  };
5815
- function unwrap41(payload) {
6869
+ var MAX_TIMESTAMP_AGE_MS = 5 * 60 * 1e3;
6870
+ function verifySignature(payload, signatureHeader, secret) {
6871
+ const parts = {};
6872
+ for (const part of signatureHeader.split(",")) {
6873
+ const idx = part.indexOf("=");
6874
+ if (idx > 0) parts[part.slice(0, idx).trim()] = part.slice(idx + 1).trim();
6875
+ }
6876
+ const tsStr = parts["t"];
6877
+ const sig = parts["v1"];
6878
+ if (!tsStr || !sig) return false;
6879
+ const ts = parseInt(tsStr, 10);
6880
+ if (isNaN(ts)) return false;
6881
+ if (Date.now() - ts * 1e3 > MAX_TIMESTAMP_AGE_MS) {
6882
+ throw new Error(`Webhook timestamp is too old: ${ts}`);
6883
+ }
6884
+ const body = payload instanceof Uint8Array ? payload : Buffer.from(payload, "utf-8");
6885
+ const signed = Buffer.concat([Buffer.from(`${tsStr}.`, "utf-8"), body]);
6886
+ const expected = createHmac("sha256", secret).update(signed).digest("hex");
6887
+ return timingSafeEqual(
6888
+ Buffer.from(expected, "utf-8"),
6889
+ Buffer.from(sig, "utf-8")
6890
+ );
6891
+ }
6892
+ function unwrap44(payload) {
5816
6893
  if (payload && typeof payload === "object" && "data" in payload) {
5817
6894
  return payload.data;
5818
6895
  }
@@ -5828,7 +6905,7 @@ function listItems16(payload, candidateKeys = ["data", "webhooks", "deliveries",
5828
6905
  }
5829
6906
  return [];
5830
6907
  }
5831
- function stripUndefined22(input) {
6908
+ function stripUndefined25(input) {
5832
6909
  return Object.fromEntries(
5833
6910
  Object.entries(input).filter(([, v]) => v !== void 0)
5834
6911
  );
@@ -5842,28 +6919,28 @@ var Webhooks = class {
5842
6919
  }
5843
6920
  http;
5844
6921
  async list(params = {}) {
5845
- const query = stripUndefined22({ ...params });
6922
+ const query = stripUndefined25({ ...params });
5846
6923
  const data = await this.http.get("/webhooks", query);
5847
6924
  return listItems16(data);
5848
6925
  }
5849
6926
  async get(webhookId) {
5850
6927
  const data = await this.http.get(`/webhooks/${webhookId}`);
5851
- return unwrap41(data);
6928
+ return unwrap44(data);
5852
6929
  }
5853
6930
  async create(params) {
5854
6931
  const { idempotencyKey: ikey, ...rest } = params;
5855
- const body = stripUndefined22(rest);
6932
+ const body = stripUndefined25(rest);
5856
6933
  const data = await this.http.request("/webhooks", {
5857
6934
  method: "POST",
5858
6935
  body,
5859
6936
  headers: { "Idempotency-Key": idempotencyKey10(ikey) }
5860
6937
  });
5861
- return unwrap41(data);
6938
+ return unwrap44(data);
5862
6939
  }
5863
6940
  async update(webhookId, params) {
5864
- const body = stripUndefined22(params);
6941
+ const body = stripUndefined25(params);
5865
6942
  const data = await this.http.patch(`/webhooks/${webhookId}`, body);
5866
- return unwrap41(data);
6943
+ return unwrap44(data);
5867
6944
  }
5868
6945
  async delete(webhookId) {
5869
6946
  await this.http.delete(`/webhooks/${webhookId}`);
@@ -5876,7 +6953,7 @@ var Webhooks = class {
5876
6953
  headers: { "Idempotency-Key": idempotencyKey10(opts.idempotencyKey) }
5877
6954
  }
5878
6955
  );
5879
- return unwrap41(data);
6956
+ return unwrap44(data);
5880
6957
  }
5881
6958
  async deliveries(webhookId) {
5882
6959
  const data = await this.http.get(
@@ -5888,6 +6965,347 @@ var Webhooks = class {
5888
6965
  "items"
5889
6966
  ]);
5890
6967
  }
6968
+ /**
6969
+ * Verify an incoming ``X-Miosa-Signature`` header.
6970
+ *
6971
+ * Header format: ``t=<unix_ts>,v1=<hex_hmac>``
6972
+ * HMAC body: ``<t>.<raw_payload>``
6973
+ *
6974
+ * Throws if timestamp is older than 5 minutes.
6975
+ * Returns true if signature matches.
6976
+ */
6977
+ static verifySignature(payload, signatureHeader, secret) {
6978
+ return verifySignature(payload, signatureHeader, secret);
6979
+ }
6980
+ };
6981
+
6982
+ // src/resources/workspace-invites.ts
6983
+ var WorkspaceInvites = class {
6984
+ constructor(http) {
6985
+ this.http = http;
6986
+ }
6987
+ http;
6988
+ /**
6989
+ * Create a workspace invite or add a member directly.
6990
+ *
6991
+ * If `email` already maps to a tenant member the user is added directly and
6992
+ * `type === "added"` is returned with a `WorkspaceMemberRecord`. Otherwise
6993
+ * an invite row is created and `type === "invited"` is returned.
6994
+ *
6995
+ * `POST /workspaces/:id/invites`
6996
+ */
6997
+ async create(workspaceId, params) {
6998
+ return this.http.post(
6999
+ `/workspaces/${workspaceId}/invites`,
7000
+ params
7001
+ );
7002
+ }
7003
+ /**
7004
+ * List all pending (non-expired, non-accepted, non-revoked) workspace invites.
7005
+ *
7006
+ * `GET /workspaces/:id/invites`
7007
+ */
7008
+ async list(workspaceId) {
7009
+ const res = await this.http.get(
7010
+ `/workspaces/${workspaceId}/invites`
7011
+ );
7012
+ return res.data ?? [];
7013
+ }
7014
+ /**
7015
+ * Revoke a pending workspace invite.
7016
+ *
7017
+ * Already-revoked invites are idempotent (returns `revoked: true`). An invite
7018
+ * that was legitimately accepted throws `409 ALREADY_ACCEPTED`.
7019
+ *
7020
+ * `DELETE /workspaces/:id/invites/:invite_id`
7021
+ */
7022
+ async revoke(workspaceId, inviteId) {
7023
+ return this.http.delete(
7024
+ `/workspaces/${workspaceId}/invites/${inviteId}`
7025
+ );
7026
+ }
7027
+ /**
7028
+ * Preview a workspace invite by token (no auth required).
7029
+ *
7030
+ * Use this to render the invite landing page before prompting the user to
7031
+ * log in or sign up. Returns `null` when the token is unknown or revoked.
7032
+ *
7033
+ * `GET /workspace-invites/:token`
7034
+ */
7035
+ async preview(token) {
7036
+ try {
7037
+ const res = await this.http.get(
7038
+ `/workspace-invites/${token}`
7039
+ );
7040
+ return res.data ?? null;
7041
+ } catch {
7042
+ return null;
7043
+ }
7044
+ }
7045
+ /**
7046
+ * Accept a workspace invite on behalf of the authenticated user.
7047
+ *
7048
+ * The caller's JWT email must match the invite email (case-insensitive).
7049
+ *
7050
+ * Error codes:
7051
+ * - `INVALID_TOKEN` (404) — token not found.
7052
+ * - `EXPIRED` (410) — invite TTL elapsed.
7053
+ * - `REVOKED` (409) — invite was revoked.
7054
+ * - `ALREADY_ACCEPTED` (409) — already used.
7055
+ * - `EMAIL_MISMATCH` (422) — JWT email differs from invite email.
7056
+ *
7057
+ * `POST /workspace-invites/:token/accept`
7058
+ */
7059
+ async accept(token) {
7060
+ return this.http.post(
7061
+ `/workspace-invites/${token}/accept`,
7062
+ {}
7063
+ );
7064
+ }
7065
+ };
7066
+
7067
+ // src/resources/workspace-members.ts
7068
+ var WorkspaceMembers = class {
7069
+ constructor(http) {
7070
+ this.http = http;
7071
+ }
7072
+ http;
7073
+ /**
7074
+ * List all members of a workspace.
7075
+ *
7076
+ * `GET /workspaces/:id/members`
7077
+ */
7078
+ async list(workspaceId) {
7079
+ const res = await this.http.get(
7080
+ `/workspaces/${workspaceId}/members`
7081
+ );
7082
+ return res.data ?? res;
7083
+ }
7084
+ /**
7085
+ * Add an existing tenant user to a workspace.
7086
+ *
7087
+ * The `user_id` must already hold a `tenant_members` row for the parent org.
7088
+ * Use {@link WorkspaceInvites.create} to invite someone who is not yet an org
7089
+ * member.
7090
+ *
7091
+ * `POST /workspaces/:id/members`
7092
+ *
7093
+ * @throws `MiosaError` with code `NOT_TENANT_MEMBER` if the user is not an
7094
+ * org member.
7095
+ */
7096
+ async add(workspaceId, params) {
7097
+ const res = await this.http.post(
7098
+ `/workspaces/${workspaceId}/members`,
7099
+ params
7100
+ );
7101
+ return res.data ?? res;
7102
+ }
7103
+ /**
7104
+ * Change a workspace member's role.
7105
+ *
7106
+ * `PATCH /workspaces/:id/members/:user_id`
7107
+ */
7108
+ async updateRole(workspaceId, userId, params) {
7109
+ const res = await this.http.patch(
7110
+ `/workspaces/${workspaceId}/members/${userId}`,
7111
+ params
7112
+ );
7113
+ return res.data ?? res;
7114
+ }
7115
+ /**
7116
+ * Remove a user from a workspace.
7117
+ *
7118
+ * The last `owner` of a workspace cannot be removed. Promote another member
7119
+ * to `owner` first using {@link updateRole}.
7120
+ *
7121
+ * `DELETE /workspaces/:id/members/:user_id`
7122
+ *
7123
+ * @throws `MiosaError` with code `LAST_OWNER` if the target is the sole owner.
7124
+ */
7125
+ async remove(workspaceId, userId) {
7126
+ return this.http.delete(
7127
+ `/workspaces/${workspaceId}/members/${userId}`
7128
+ );
7129
+ }
7130
+ };
7131
+
7132
+ // src/resources/workspaces.ts
7133
+ function unwrap45(payload) {
7134
+ if (payload && typeof payload === "object" && "data" in payload) {
7135
+ return payload.data;
7136
+ }
7137
+ return payload;
7138
+ }
7139
+ function listItems17(payload, candidateKeys = ["data", "items"]) {
7140
+ if (Array.isArray(payload)) return payload;
7141
+ if (!payload || typeof payload !== "object") return [];
7142
+ const p = payload;
7143
+ if (Array.isArray(p.data)) return p.data;
7144
+ for (const key of candidateKeys) {
7145
+ if (Array.isArray(p[key])) return p[key];
7146
+ }
7147
+ return [];
7148
+ }
7149
+ var Workspaces = class {
7150
+ http;
7151
+ constructor(http) {
7152
+ this.http = http;
7153
+ }
7154
+ /**
7155
+ * Create a new workspace.
7156
+ */
7157
+ async create(params) {
7158
+ const payload = await this.http.post("/workspaces", params);
7159
+ return unwrap45(payload);
7160
+ }
7161
+ /**
7162
+ * List all workspaces visible to the current credential.
7163
+ */
7164
+ async list() {
7165
+ const payload = await this.http.get("/workspaces");
7166
+ if (payload && typeof payload === "object" && "workspaces" in payload) {
7167
+ const p = payload;
7168
+ return p["workspaces"] ?? [];
7169
+ }
7170
+ return listItems17(payload, ["data", "workspaces", "items"]);
7171
+ }
7172
+ /**
7173
+ * Get a single workspace by ID.
7174
+ */
7175
+ async get(id) {
7176
+ const payload = await this.http.get(`/workspaces/${id}`);
7177
+ return unwrap45(payload);
7178
+ }
7179
+ /**
7180
+ * Update a workspace's metadata.
7181
+ */
7182
+ async update(id, params) {
7183
+ const payload = await this.http.patch(`/workspaces/${id}`, params);
7184
+ return unwrap45(payload);
7185
+ }
7186
+ /**
7187
+ * Delete a workspace. Does not delete member computers.
7188
+ */
7189
+ async delete(id) {
7190
+ await this.http.delete(`/workspaces/${id}`);
7191
+ }
7192
+ /**
7193
+ * Update workspace-level settings.
7194
+ */
7195
+ async updateSettings(id, settings) {
7196
+ const payload = await this.http.put(
7197
+ `/workspaces/${id}/settings`,
7198
+ settings
7199
+ );
7200
+ return unwrap45(payload);
7201
+ }
7202
+ /**
7203
+ * List all computers that belong to the given workspace.
7204
+ */
7205
+ async listComputers(id) {
7206
+ const payload = await this.http.get(`/workspaces/${id}/computers`);
7207
+ const items = listItems17(payload, [
7208
+ "data",
7209
+ "computers",
7210
+ "items"
7211
+ ]);
7212
+ return items.map((d) => new Computer(this.http, d));
7213
+ }
7214
+ /**
7215
+ * List all sandboxes that belong to this workspace.
7216
+ */
7217
+ async listSandboxes(id) {
7218
+ const payload = await this.http.get(`/workspaces/${id}/sandboxes`);
7219
+ return listItems17(payload, [
7220
+ "data",
7221
+ "sandboxes",
7222
+ "items"
7223
+ ]);
7224
+ }
7225
+ /**
7226
+ * List all deployments that belong to this workspace.
7227
+ */
7228
+ async listDeployments(id) {
7229
+ const payload = await this.http.get(
7230
+ `/workspaces/${id}/deployments`
7231
+ );
7232
+ return listItems17(payload, [
7233
+ "data",
7234
+ "deployments",
7235
+ "items"
7236
+ ]);
7237
+ }
7238
+ /**
7239
+ * List all managed databases that belong to this workspace.
7240
+ */
7241
+ async listDatabases(id) {
7242
+ const payload = await this.http.get(`/workspaces/${id}/databases`);
7243
+ return listItems17(payload, [
7244
+ "data",
7245
+ "databases",
7246
+ "items"
7247
+ ]);
7248
+ }
7249
+ /**
7250
+ * List all projects that belong to this workspace.
7251
+ */
7252
+ async listProjects(id) {
7253
+ const payload = await this.http.get(`/workspaces/${id}/projects`);
7254
+ return listItems17(payload, [
7255
+ "data",
7256
+ "projects",
7257
+ "items"
7258
+ ]);
7259
+ }
7260
+ /**
7261
+ * Return aggregate resource stats for this workspace.
7262
+ */
7263
+ async stats(id) {
7264
+ const payload = await this.http.get(`/workspaces/${id}/stats`);
7265
+ return unwrap45(payload);
7266
+ }
7267
+ /**
7268
+ * Return metered usage data for this workspace.
7269
+ */
7270
+ async usage(id) {
7271
+ const payload = await this.http.get(`/workspaces/${id}/usage`);
7272
+ return unwrap45(payload);
7273
+ }
7274
+ /**
7275
+ * Return activity feed for this workspace.
7276
+ */
7277
+ async activity(id) {
7278
+ const payload = await this.http.get(`/workspaces/${id}/activity`);
7279
+ return listItems17(payload, [
7280
+ "data",
7281
+ "activity",
7282
+ "events",
7283
+ "items"
7284
+ ]);
7285
+ }
7286
+ /**
7287
+ * List computer templates available in this workspace.
7288
+ */
7289
+ async listComputerTemplates(id) {
7290
+ const payload = await this.http.get(
7291
+ `/workspaces/${id}/computer-templates`
7292
+ );
7293
+ return listItems17(payload, [
7294
+ "data",
7295
+ "templates",
7296
+ "items"
7297
+ ]);
7298
+ }
7299
+ /**
7300
+ * Create a computer template scoped to this workspace.
7301
+ */
7302
+ async createComputerTemplate(id, params) {
7303
+ const payload = await this.http.post(
7304
+ `/workspaces/${id}/computer-templates`,
7305
+ params
7306
+ );
7307
+ return unwrap45(payload);
7308
+ }
5891
7309
  };
5892
7310
 
5893
7311
  // src/client.ts
@@ -5895,6 +7313,20 @@ var DEFAULT_BASE_URL = "https://api.miosa.ai/api/v1";
5895
7313
  var DEFAULT_TIMEOUT2 = 3e4;
5896
7314
  var DEFAULT_MAX_RETRIES2 = 3;
5897
7315
  var Miosa = class {
7316
+ /** Workspace CRUD — create, list, get, update, delete, and sub-resource queries. */
7317
+ workspaces;
7318
+ /** Per-workspace user roster — list, add, update role, remove. */
7319
+ workspaceMembers;
7320
+ /**
7321
+ * Workspace invite flow — create invite, list, revoke, preview, accept.
7322
+ * Sending to an email already in the org adds the user directly.
7323
+ */
7324
+ workspaceInvites;
7325
+ /**
7326
+ * Org invite flow — create invite, list, revoke, preview, accept.
7327
+ * Requires admin/owner role for write operations.
7328
+ */
7329
+ orgInvites;
5898
7330
  /** Current tenant plan, limits, and live usage counters. */
5899
7331
  tenant;
5900
7332
  /** Datacenter regions, compute sizes, pricing, community templates. */
@@ -5980,6 +7412,13 @@ var Miosa = class {
5980
7412
  builderSessions;
5981
7413
  /** Admin: fleet-wide snapshot index. */
5982
7414
  snapshotsStandalone;
7415
+ // ── Egress (security) namespaces ───────────────────────────────────────────
7416
+ /** Encrypted secret + OAuth credential vault (`/egress/secrets`). */
7417
+ secrets;
7418
+ /** Egress allowlist + policies — host-level firewall (`/egress/policies`). */
7419
+ network;
7420
+ /** Egress audit log — every outbound request, paginated query + tail. */
7421
+ audit;
5983
7422
  http;
5984
7423
  constructor(config) {
5985
7424
  if (!config.apiKey) {
@@ -5998,6 +7437,10 @@ var Miosa = class {
5998
7437
  timeout: config.timeout ?? DEFAULT_TIMEOUT2,
5999
7438
  maxRetries: config.maxRetries ?? DEFAULT_MAX_RETRIES2
6000
7439
  });
7440
+ this.workspaces = new Workspaces(this.http);
7441
+ this.workspaceMembers = new WorkspaceMembers(this.http);
7442
+ this.workspaceInvites = new WorkspaceInvites(this.http);
7443
+ this.orgInvites = new OrgInvites(this.http);
6001
7444
  this.tenant = new Tenant(this.http);
6002
7445
  this.regions = new Regions(this.http);
6003
7446
  this.settings = new Settings(this.http);
@@ -6037,9 +7480,12 @@ var Miosa = class {
6037
7480
  this.email = new Email(this.http);
6038
7481
  this.builderSessions = new BuilderSessions(this.http);
6039
7482
  this.snapshotsStandalone = new SnapshotsStandalone(this.http);
7483
+ this.secrets = new EgressSecrets(this.http);
7484
+ this.network = new EgressNetwork(this.http);
7485
+ this.audit = new EgressAudit(this.http);
6040
7486
  }
6041
7487
  };
6042
7488
 
6043
- export { Admin, Analytics, ApiKeys, AuditLog, AuthError, Benchmarks, BuilderSessions, Channels, Checkpoints, CommandCenter, Community, Completions, Computer, ComputerAutoStop, ComputerEnv, ComputerInbox, ComputerLogs, ComputerOsa, ComputerPorts, ComputerTerminal, ComputerVolumes, Computers, Credits, CronJobs, Dashboard, Databases, DeploymentDomains, DeploymentReleases, DeploymentRuntimeInstances, DeploymentVersions, Deployments, Desktop, Email, EmailCampaigns, EmailInbox, EmailTemplates, Embeddings, Exec, ExternalKeys, Files, FlatCustomDomains, Functions, HealthChecks, InsufficientCreditsError, Integrations, Mcp, Miosa, MiosaError, Models, NetworkError, NetworkPolicy, NotFoundError, OpenComputers, ProjectAuth, ProjectIntegrations, ProviderDefaults, RateLimitError, Regions, SANDBOX_TEMPLATE, Sandbox, SandboxArtifacts, SandboxCommands, SandboxEnv, SandboxEvents, SandboxFiles, SandboxPreview, SandboxPreviews, SandboxTags, SandboxTemplates, SandboxTerminal, Sandboxes, ScopedFs, Settings, SnapshotsStandalone, Storage, Tenant, TimeoutError, Usage, ValidationError, Volumes, Webhooks };
7489
+ export { Admin, Analytics, ApiKeys, AuditLog, AuthError, Benchmarks, BuilderSessions, Channels, Checkpoints, CommandCenter, Community, Completions, Computer, ComputerAudit, ComputerAutoStop, ComputerEnv, ComputerInbox, ComputerLogs, ComputerNetwork, ComputerOsa, ComputerPorts, ComputerSecrets, ComputerTerminal, ComputerVolumes, Computers, Credits, CronJobs, Dashboard, Databases, DeploymentDomains, DeploymentReleases, DeploymentRuntimeInstances, DeploymentVersions, Deployments, Desktop, EgressAudit, EgressNetwork, EgressSecrets, Email, EmailCampaigns, EmailInbox, EmailTemplates, Embeddings, Exec, ExternalKeys, Files, FlatCustomDomains, Functions, HealthChecks, InsufficientCreditsError, Integrations, Mcp, Miosa, MiosaError, Models, NetworkError, NetworkPolicy, NotFoundError, OAuthFlow, OpenComputers, OrgInvites, ProjectAuth, ProjectIntegrations, ProviderDefaults, RateLimitError, Regions, SANDBOX_TEMPLATE, Sandbox, SandboxArtifacts, SandboxAudit, SandboxCommands, SandboxEnv, SandboxEvents, SandboxFiles, SandboxNetwork, SandboxPreview, SandboxPreviews, SandboxSecrets, SandboxTags, SandboxTemplates, SandboxTerminal, Sandboxes, ScopedFs, Settings, SnapshotsStandalone, Storage, Tenant, TimeoutError, Usage, ValidationError, Volumes, Webhooks, WorkspaceInvites, WorkspaceMembers, Workspaces };
6044
7490
  //# sourceMappingURL=index.js.map
6045
7491
  //# sourceMappingURL=index.js.map