openpond 0.0.30-bootstrap.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.
Files changed (193) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/LICENSE +21 -0
  3. package/README.md +162 -0
  4. package/RELEASE.md +20 -0
  5. package/dist/api/core.d.ts +22 -0
  6. package/dist/api/deployments.d.ts +30 -0
  7. package/dist/api/types.d.ts +624 -0
  8. package/dist/api.d.ts +90 -0
  9. package/dist/cache.d.ts +22 -0
  10. package/dist/chunks/app-layer-YKXEQGOW.js +163 -0
  11. package/dist/chunks/apps-GGSIN2ZF.js +539 -0
  12. package/dist/chunks/chunk-3CC6MH35.js +1663 -0
  13. package/dist/chunks/chunk-3Y4EL3P6.js +1090 -0
  14. package/dist/chunks/chunk-4HYJG2JE.js +3875 -0
  15. package/dist/chunks/chunk-5G4E547X.js +294 -0
  16. package/dist/chunks/chunk-74O6FGVN.js +598 -0
  17. package/dist/chunks/chunk-AUJLPKGI.js +632 -0
  18. package/dist/chunks/chunk-BYAPLT37.js +744 -0
  19. package/dist/chunks/chunk-FUP7EGT7.js +1845 -0
  20. package/dist/chunks/chunk-I6HN3ZGW.js +88 -0
  21. package/dist/chunks/chunk-KRKGHVMQ.js +294 -0
  22. package/dist/chunks/chunk-LHYK6QO2.js +1300 -0
  23. package/dist/chunks/chunk-NLBKZZEK.js +224 -0
  24. package/dist/chunks/chunk-OG75GMVO.js +1 -0
  25. package/dist/chunks/chunk-Q57SVPEH.js +11663 -0
  26. package/dist/chunks/chunk-UACZUFIA.js +47 -0
  27. package/dist/chunks/chunk-VQX33YAG.js +5135 -0
  28. package/dist/chunks/chunk-W5GKHH77.js +168 -0
  29. package/dist/chunks/chunk-WYDVQOBL.js +17581 -0
  30. package/dist/chunks/chunk-XSAXENQD.js +4167 -0
  31. package/dist/chunks/chunk-Y6G6WRTG.js +210 -0
  32. package/dist/chunks/cli-NVKNE4AZ.js +11 -0
  33. package/dist/chunks/cli-X3HPLSOV.js +19 -0
  34. package/dist/chunks/core-commands-IM2UKLU4.js +41 -0
  35. package/dist/chunks/extend-YXCBULPO.js +84 -0
  36. package/dist/chunks/harness-GMK6IY2U.js +140 -0
  37. package/dist/chunks/help-LMH5FGT2.js +65 -0
  38. package/dist/chunks/opchat-BWXZ32GX.js +169 -0
  39. package/dist/chunks/organizations-4ISQRGMQ.js +738 -0
  40. package/dist/chunks/profile-NLDZDT3L.js +1110 -0
  41. package/dist/chunks/project-agent-ZPVO25HA.js +892 -0
  42. package/dist/chunks/sandbox-command-5GFJ2U3V.js +1652 -0
  43. package/dist/chunks/sandbox-template-LZN4F55Z.js +1646 -0
  44. package/dist/chunks/src-3RBI4DNN.js +3595 -0
  45. package/dist/chunks/src-EYXQS6XD.js +73427 -0
  46. package/dist/chunks/teams-bot-WP3FHKGA.js +137 -0
  47. package/dist/cli.js +77 -0
  48. package/dist/client-types.d.ts +222 -0
  49. package/dist/client.d.ts +19 -0
  50. package/dist/config.d.ts +184 -0
  51. package/dist/hosted-chat.d.ts +162 -0
  52. package/dist/index.d.ts +5 -0
  53. package/dist/index.js +25481 -0
  54. package/dist/indicators.d.ts +38 -0
  55. package/dist/opchat-smoke.d.ts +47 -0
  56. package/dist/private-json-file.d.ts +3 -0
  57. package/dist/profile/local-profile-types.d.ts +160 -0
  58. package/dist/profile/local-profile.d.ts +69 -0
  59. package/dist/profile/profile-catalog.d.ts +14 -0
  60. package/dist/profile/profile-git.d.ts +17 -0
  61. package/dist/profile/profile-promotion.d.ts +21 -0
  62. package/dist/profile/profile-setup-gate.d.ts +22 -0
  63. package/dist/profile/profile-skills.d.ts +30 -0
  64. package/dist/profile/profile-source-upload.d.ts +29 -0
  65. package/dist/profile/source-upload-cache.d.ts +29 -0
  66. package/dist/sandbox/async-request-options.d.ts +2 -0
  67. package/dist/sandbox/client-handles.d.ts +113 -0
  68. package/dist/sandbox/client.d.ts +348 -0
  69. package/dist/sandbox/runtime-handle.d.ts +36 -0
  70. package/dist/sandbox/sandbox-instance-client.d.ts +72 -0
  71. package/dist/sandbox/smoke.d.ts +3 -0
  72. package/dist/sandbox/stream.d.ts +7 -0
  73. package/dist/sandbox/types/billing.d.ts +176 -0
  74. package/dist/sandbox/types/client.d.ts +103 -0
  75. package/dist/sandbox/types/core.d.ts +140 -0
  76. package/dist/sandbox/types/index.d.ts +14 -0
  77. package/dist/sandbox/types/io.d.ts +240 -0
  78. package/dist/sandbox/types/microsoft-teams-bot.d.ts +51 -0
  79. package/dist/sandbox/types/org-project-agent.d.ts +610 -0
  80. package/dist/sandbox/types/record.d.ts +53 -0
  81. package/dist/sandbox/types/responses.d.ts +295 -0
  82. package/dist/sandbox/types/runtime-profiles.d.ts +15 -0
  83. package/dist/sandbox/types/runtime.d.ts +152 -0
  84. package/dist/sandbox/types/schedules.d.ts +141 -0
  85. package/dist/sandbox/types/snapshots.d.ts +205 -0
  86. package/dist/sandbox/types/workflow-modes.d.ts +1 -0
  87. package/dist/sandbox/types/workload-sources.d.ts +20 -0
  88. package/dist/sandbox/url.d.ts +2 -0
  89. package/dist/sandbox-template/manifest.d.ts +304 -0
  90. package/dist/sandbox-template/manifest.js +18381 -0
  91. package/dist/skills/openpond-cli/SKILL.md +49 -0
  92. package/dist/skills/openpond-desktop-harness/SKILL.md +113 -0
  93. package/dist/skills/openpond-desktop-harness/agents/openai.yaml +4 -0
  94. package/dist/skills/openpond-taskset-authoring/SKILL.md +38 -0
  95. package/dist/skills/openpond-taskset-authoring/references/graders-and-rewards.md +11 -0
  96. package/dist/skills/openpond-taskset-authoring/references/method-selection.md +12 -0
  97. package/dist/skills/openpond-taskset-authoring/references/privacy-and-provenance.md +8 -0
  98. package/dist/skills/openpond-taskset-authoring/references/task-design.md +13 -0
  99. package/dist/stream.d.ts +20 -0
  100. package/dist/types.d.ts +57 -0
  101. package/dist/urls.d.ts +4 -0
  102. package/dist/web/assets/AppsView-Bu-Nc3Ew.js +1 -0
  103. package/dist/web/assets/AppsView-DIhprTIC.css +1 -0
  104. package/dist/web/assets/BrowserSidebar-CCguQ-DR.js +1 -0
  105. package/dist/web/assets/BrowserSidebar-D9i7gQzw.css +1 -0
  106. package/dist/web/assets/CloudWorkView-DNoPIlMj.css +1 -0
  107. package/dist/web/assets/CloudWorkView-Dr3xqLE5.js +1 -0
  108. package/dist/web/assets/CommandMenu-CnodJFHD.js +1 -0
  109. package/dist/web/assets/CommandMenu-hNQCm8mw.css +1 -0
  110. package/dist/web/assets/CommunityView-CIbjNUZr.js +1 -0
  111. package/dist/web/assets/CommunityView-DSik4sd2.css +1 -0
  112. package/dist/web/assets/GetStartedView-C3ZrnEz5.css +1 -0
  113. package/dist/web/assets/GetStartedView-C8nyH_PT.js +1 -0
  114. package/dist/web/assets/LabsExtensions-GtJzxDnK.js +1 -0
  115. package/dist/web/assets/LabsProfile-DG7rWYur.js +1 -0
  116. package/dist/web/assets/LabsRoute-D6MDHBzq.js +2 -0
  117. package/dist/web/assets/LabsRoute-TEt9j1vB.css +1 -0
  118. package/dist/web/assets/LabsSignals-BfsDN86w.js +1 -0
  119. package/dist/web/assets/LabsSignals-D6iA6Ryl.css +1 -0
  120. package/dist/web/assets/NewProjectDialog-CaKiCoVS.js +1 -0
  121. package/dist/web/assets/ProfileSettingsSection-DTQS2DVL.css +1 -0
  122. package/dist/web/assets/ProfileSettingsSection-DxEzoF3K.js +1 -0
  123. package/dist/web/assets/ProfileView-CEscW7Ru.js +1 -0
  124. package/dist/web/assets/SettingsView-DwbGu8Kj.css +1 -0
  125. package/dist/web/assets/SettingsView-JIRR_FO4.js +63 -0
  126. package/dist/web/assets/TeamChatView-B5M1ThhJ.js +3 -0
  127. package/dist/web/assets/TeamChatView-Bx44q3WV.css +1 -0
  128. package/dist/web/assets/TerminalOverlay-C1iP4OS1.js +19 -0
  129. package/dist/web/assets/TerminalOverlay-DwBiZLwk.css +1 -0
  130. package/dist/web/assets/TrainingSettingsSection-BDYvI2te.js +1 -0
  131. package/dist/web/assets/TrainingView-CoCFK6W3.js +5 -0
  132. package/dist/web/assets/WorkspaceDiffPanel-CMxKQeo7.js +14 -0
  133. package/dist/web/assets/WorkspaceEnvironmentMenu-B8JJbwIz.js +32 -0
  134. package/dist/web/assets/WorkspaceEnvironmentMenu-DGIFdG3o.css +1 -0
  135. package/dist/web/assets/WorkspaceGitDialogs-B4sp9BGn.js +1 -0
  136. package/dist/web/assets/WorkspaceMonacoEditor-BBqimG5X.js +845 -0
  137. package/dist/web/assets/WorkspaceMonacoEditor-BwKcXIZw.css +1 -0
  138. package/dist/web/assets/boxes-DAaDUabq.js +1 -0
  139. package/dist/web/assets/codicon-ngg6Pgfi.ttf +0 -0
  140. package/dist/web/assets/css.worker-DBVD8oXr.js +93 -0
  141. package/dist/web/assets/cssMode-CBF1mieJ.js +1 -0
  142. package/dist/web/assets/dockerfile-BG73LgW2.js +1 -0
  143. package/dist/web/assets/editor.worker-CdQrwHl8.js +26 -0
  144. package/dist/web/assets/git-commit-horizontal-CAickXpN.js +1 -0
  145. package/dist/web/assets/git-dialogs-BZDqS1eT.css +1 -0
  146. package/dist/web/assets/html.worker-CwpTb9lJ.js +470 -0
  147. package/dist/web/assets/htmlMode-2u8OHtWO.js +1 -0
  148. package/dist/web/assets/index-BdY6A-YN.css +1 -0
  149. package/dist/web/assets/index-CU2qhUYV.js +195 -0
  150. package/dist/web/assets/index-Dz2B3-4C.js +1 -0
  151. package/dist/web/assets/info-CQNTh78o.js +1 -0
  152. package/dist/web/assets/json.worker-BoL8UZqY.js +58 -0
  153. package/dist/web/assets/jsonMode-C4CWXViX.js +7 -0
  154. package/dist/web/assets/lspLanguageFeatures-CBs_BOlB.js +4 -0
  155. package/dist/web/assets/markdown-BFxVWTOG.js +1 -0
  156. package/dist/web/assets/monaco.contribution-C1LUxAKf.js +2 -0
  157. package/dist/web/assets/monaco.contribution-Cpf6dWsh.js +2 -0
  158. package/dist/web/assets/monaco.contribution-lOXpG2xQ.js +2 -0
  159. package/dist/web/assets/monaco.contribution-sd3cFkcN.js +2 -0
  160. package/dist/web/assets/monitor-DsIswrMV.js +1 -0
  161. package/dist/web/assets/play-CeRw21NV.js +1 -0
  162. package/dist/web/assets/python-CXYq3BUl.js +1 -0
  163. package/dist/web/assets/refresh-cw-N5b_6AP5.js +1 -0
  164. package/dist/web/assets/reply-BSKjZrJg.js +1 -0
  165. package/dist/web/assets/save-D0oHH1a3.js +1 -0
  166. package/dist/web/assets/settings-lists-BEg6LMcy.css +1 -0
  167. package/dist/web/assets/shell-DiJ1NA_G.js +1 -0
  168. package/dist/web/assets/toggleHighContrast-B7NOMXDY.css +1 -0
  169. package/dist/web/assets/toggleHighContrast-DRjlcwes.js +62 -0
  170. package/dist/web/assets/training-model-data-BPrc68VG.js +1 -0
  171. package/dist/web/assets/ts.worker-BH9nVgjN.js +67718 -0
  172. package/dist/web/assets/tsMode-x-1A7ZcB.js +11 -0
  173. package/dist/web/assets/wifi-off-Dt52ofzh.js +1 -0
  174. package/dist/web/assets/workers-Ciff6Dzi.js +1 -0
  175. package/dist/web/assets/yaml-CB67Kxnz.js +1 -0
  176. package/dist/web/connected-apps/github.svg +3 -0
  177. package/dist/web/connected-apps/google.svg +6 -0
  178. package/dist/web/connected-apps/linear.svg +3 -0
  179. package/dist/web/connected-apps/microsoft.svg +6 -0
  180. package/dist/web/connected-apps/notion.svg +3 -0
  181. package/dist/web/connected-apps/openpond-mcp.svg +4 -0
  182. package/dist/web/connected-apps/slack.svg +6 -0
  183. package/dist/web/connected-apps/x.svg +3 -0
  184. package/dist/web/favicon-16x16.png +0 -0
  185. package/dist/web/favicon-32x32.png +0 -0
  186. package/dist/web/index.html +16 -0
  187. package/dist/web/openpond-icon.png +0 -0
  188. package/dist/web/openpond-wordlogo-white.png +0 -0
  189. package/dist/web/tokens/eth.svg +1 -0
  190. package/dist/web/tokens/usdc.svg +1 -0
  191. package/docs/agent-edit-check-status-json.md +132 -0
  192. package/docs/command-reference.md +695 -0
  193. package/package.json +84 -0
@@ -0,0 +1,4167 @@
1
+ import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
+ import {
3
+ DEFAULT_OPENPOND_API_BASE_URL,
4
+ DEFAULT_OPENPOND_WEB_BASE_URL,
5
+ mapUiBaseToApiBase,
6
+ resolveBaseUrl,
7
+ resolveSandboxApiUrlOption
8
+ } from "./chunk-5G4E547X.js";
9
+ import {
10
+ parseBooleanOption
11
+ } from "./chunk-3Y4EL3P6.js";
12
+
13
+ // ../../packages/cloud/src/api/core.ts
14
+ var DEFAULT_API_TIMEOUT_MS = 3e4;
15
+ var DEFAULT_API_RESPONSE_BYTES = 8 * 1024 * 1024;
16
+ var LONG_STREAM_API_OPTIONS = { timeoutMs: 15 * 60 * 1e3, maxResponseBytes: 64 * 1024 * 1024 };
17
+ var ApiTimeoutError = class extends Error {
18
+ constructor(timeoutMs, requestUrl) {
19
+ super(`API request timed out after ${timeoutMs}ms: ${requestUrl}`);
20
+ this.timeoutMs = timeoutMs;
21
+ this.requestUrl = requestUrl;
22
+ this.name = "ApiTimeoutError";
23
+ }
24
+ timeoutMs;
25
+ requestUrl;
26
+ code = "OPENPOND_API_TIMEOUT";
27
+ };
28
+ var ApiResponseTooLargeError = class extends Error {
29
+ constructor(maximumBytes, requestUrl) {
30
+ super(`API response exceeded ${maximumBytes} bytes: ${requestUrl}`);
31
+ this.maximumBytes = maximumBytes;
32
+ this.requestUrl = requestUrl;
33
+ this.name = "ApiResponseTooLargeError";
34
+ }
35
+ maximumBytes;
36
+ requestUrl;
37
+ code = "OPENPOND_API_RESPONSE_TOO_LARGE";
38
+ };
39
+ async function apiFetch(baseUrl, token, requestPath, options = {}) {
40
+ const { timeoutMs = DEFAULT_API_TIMEOUT_MS, maxResponseBytes = DEFAULT_API_RESPONSE_BYTES, ...init } = options;
41
+ const headers = new Headers(init.headers || {});
42
+ headers.set("Content-Type", "application/json");
43
+ const apiKey = process.env.OPENPOND_API_KEY;
44
+ const trimmedToken = token?.trim() || "";
45
+ const tokenIsApiKey = trimmedToken.startsWith("opk_");
46
+ const effectiveApiKey = apiKey || (tokenIsApiKey ? trimmedToken : null);
47
+ if (effectiveApiKey && !headers.has("openpond-api-key")) headers.set("openpond-api-key", effectiveApiKey);
48
+ if (token) {
49
+ headers.set("Authorization", tokenIsApiKey ? `ApiKey ${trimmedToken}` : `Bearer ${token}`);
50
+ } else if (apiKey && !headers.has("Authorization")) {
51
+ headers.set("Authorization", `ApiKey ${apiKey}`);
52
+ }
53
+ const requestUrl = `${baseUrl}${requestPath}`;
54
+ const timeoutController = new AbortController();
55
+ const timeoutError = new ApiTimeoutError(timeoutMs, requestUrl);
56
+ const timer = timeoutMs > 0 ? setTimeout(() => timeoutController.abort(timeoutError), timeoutMs) : null;
57
+ timer?.unref?.();
58
+ const signal = composedSignal(init.signal, timeoutController.signal, timeoutMs);
59
+ const cleanup = () => {
60
+ if (timer) clearTimeout(timer);
61
+ };
62
+ try {
63
+ const response = await fetch(requestUrl, { ...init, headers, signal });
64
+ return boundedResponse(response, {
65
+ cleanup,
66
+ maximumBytes: maxResponseBytes,
67
+ requestUrl,
68
+ timeoutController,
69
+ timeoutError
70
+ });
71
+ } catch (error) {
72
+ cleanup();
73
+ if (timeoutController.signal.aborted) throw timeoutError;
74
+ throw error;
75
+ }
76
+ }
77
+ async function readApiJson(response, label) {
78
+ let payload;
79
+ try {
80
+ const text = await response.text();
81
+ payload = text ? JSON.parse(text) : {};
82
+ } catch (error) {
83
+ if (error instanceof ApiTimeoutError || error instanceof ApiResponseTooLargeError) throw error;
84
+ payload = {};
85
+ }
86
+ if (!response.ok) {
87
+ const message = typeof payload.message === "string" ? payload.message : typeof payload.error === "string" ? payload.error : "";
88
+ throw new Error(`${label} failed: ${response.status}${message ? ` ${message}` : ""}`);
89
+ }
90
+ return payload;
91
+ }
92
+ function boundedResponse(response, input3) {
93
+ if (!response.body) {
94
+ input3.cleanup();
95
+ return response;
96
+ }
97
+ const contentLength = Number(response.headers.get("content-length"));
98
+ if (input3.maximumBytes > 0 && Number.isFinite(contentLength) && contentLength > input3.maximumBytes) {
99
+ input3.cleanup();
100
+ void response.body.cancel();
101
+ throw new ApiResponseTooLargeError(input3.maximumBytes, input3.requestUrl);
102
+ }
103
+ const reader = response.body.getReader();
104
+ let receivedBytes = 0;
105
+ const body = new ReadableStream({
106
+ async pull(controller) {
107
+ try {
108
+ const result = await reader.read();
109
+ if (result.done) {
110
+ input3.cleanup();
111
+ controller.close();
112
+ return;
113
+ }
114
+ receivedBytes += result.value.byteLength;
115
+ if (input3.maximumBytes > 0 && receivedBytes > input3.maximumBytes) {
116
+ input3.cleanup();
117
+ await reader.cancel();
118
+ controller.error(new ApiResponseTooLargeError(input3.maximumBytes, input3.requestUrl));
119
+ return;
120
+ }
121
+ controller.enqueue(result.value);
122
+ } catch (error) {
123
+ input3.cleanup();
124
+ controller.error(input3.timeoutController.signal.aborted ? input3.timeoutError : error);
125
+ }
126
+ },
127
+ async cancel(reason) {
128
+ input3.cleanup();
129
+ await reader.cancel(reason);
130
+ }
131
+ });
132
+ return new Response(body, {
133
+ headers: response.headers,
134
+ status: response.status,
135
+ statusText: response.statusText
136
+ });
137
+ }
138
+ function composedSignal(callerSignal, timeoutSignal, timeoutMs) {
139
+ if (timeoutMs <= 0) return callerSignal ?? void 0;
140
+ return callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal;
141
+ }
142
+
143
+ // ../../packages/cloud/src/api/deployments.ts
144
+ async function deployApp(baseUrl, token, appId, input3) {
145
+ const environment = input3?.environment ?? "production";
146
+ const response = await apiFetch(
147
+ baseUrl,
148
+ token,
149
+ `/v4/apps/${appId}/deployments`,
150
+ {
151
+ method: "POST",
152
+ body: JSON.stringify({
153
+ environment,
154
+ ...input3?.commitSha ? { commitSha: input3.commitSha } : {},
155
+ ...input3?.branch ? { branch: input3.branch } : {}
156
+ })
157
+ }
158
+ );
159
+ if (!response.ok) {
160
+ const text = await response.text().catch(() => "");
161
+ throw new Error(`Deploy failed: ${response.status} ${text}`);
162
+ }
163
+ return await response.json();
164
+ }
165
+ async function getDeploymentLogs(apiBase, token, deploymentId) {
166
+ const response = await apiFetch(
167
+ apiBase,
168
+ token,
169
+ `/apps/deployments/${deploymentId}/logs`,
170
+ { method: "GET" }
171
+ );
172
+ if (!response.ok) {
173
+ const text = await response.text().catch(() => "");
174
+ throw new Error(`Deployment logs failed: ${response.status} ${text}`);
175
+ }
176
+ const payload = await response.json().catch(() => ({}));
177
+ const logs = Array.isArray(payload.logs) ? payload.logs : [];
178
+ return logs.map((log) => {
179
+ const createdAt = typeof log.createdAt === "string" ? log.createdAt : log.createdAt instanceof Date ? log.createdAt.toISOString() : (/* @__PURE__ */ new Date()).toISOString();
180
+ return {
181
+ id: typeof log.id === "string" ? log.id : `${Math.random()}`,
182
+ type: typeof log.type === "string" ? log.type : void 0,
183
+ message: typeof log.message === "string" ? log.message : "",
184
+ createdAt
185
+ };
186
+ });
187
+ }
188
+ async function getDeploymentStatus(apiBase, token, deploymentId) {
189
+ const response = await apiFetch(
190
+ apiBase,
191
+ token,
192
+ `/apps/deployments/${deploymentId}/status`,
193
+ { method: "GET" }
194
+ );
195
+ if (!response.ok) {
196
+ const text = await response.text().catch(() => "");
197
+ throw new Error(`Deployment status failed: ${response.status} ${text}`);
198
+ }
199
+ const payload = await response.json().catch(() => ({}));
200
+ return { status: payload.deployment?.status };
201
+ }
202
+ async function getLatestDeploymentForApp(apiBase, token, appId, options) {
203
+ const params = new URLSearchParams();
204
+ if (options?.status && options.status.length > 0) {
205
+ params.set("status", options.status.join(","));
206
+ }
207
+ if (options?.createdAfter) {
208
+ params.set("createdAfter", options.createdAfter);
209
+ }
210
+ if (options?.branch) {
211
+ params.set("branch", options.branch);
212
+ }
213
+ const query = params.toString();
214
+ const response = await apiFetch(
215
+ apiBase,
216
+ token,
217
+ `/apps/${appId}/deployments/latest${query ? `?${query}` : ""}`,
218
+ { method: "GET" }
219
+ );
220
+ if (!response.ok) {
221
+ const text = await response.text().catch(() => "");
222
+ throw new Error(
223
+ `Latest deployment lookup failed: ${response.status} ${text}`
224
+ );
225
+ }
226
+ const payload = await response.json().catch(() => ({}));
227
+ if (!payload.deployment) return null;
228
+ return {
229
+ id: payload.deployment.id,
230
+ status: payload.deployment.status
231
+ };
232
+ }
233
+ async function getDeploymentDetail(apiBase, token, deploymentId) {
234
+ const response = await apiFetch(
235
+ apiBase,
236
+ token,
237
+ `/apps/deployments/${deploymentId}`,
238
+ { method: "GET" }
239
+ );
240
+ if (!response.ok) {
241
+ const text = await response.text().catch(() => "");
242
+ throw new Error(`Deployment fetch failed: ${response.status} ${text}`);
243
+ }
244
+ const payload = await response.json().catch(() => ({}));
245
+ return payload.deployment ?? null;
246
+ }
247
+
248
+ // ../../packages/cloud/src/api.ts
249
+ var DEFAULT_OPENPOND_API_HOST = new URL(DEFAULT_OPENPOND_API_BASE_URL).hostname;
250
+ var DEFAULT_OPENPOND_WEB_HOST = new URL(DEFAULT_OPENPOND_WEB_BASE_URL).hostname;
251
+ async function listApps(apiBase, token, options) {
252
+ const params = new URLSearchParams();
253
+ if (options?.handle) {
254
+ params.set("handle", options.handle);
255
+ }
256
+ if (typeof options?.limit === "number" && Number.isFinite(options.limit)) {
257
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
258
+ }
259
+ if (typeof options?.offset === "number" && Number.isFinite(options.offset)) {
260
+ params.set("offset", String(Math.max(0, Math.floor(options.offset))));
261
+ }
262
+ if (typeof options?.includeScheduled === "boolean") {
263
+ params.set("includeScheduled", options.includeScheduled ? "true" : "false");
264
+ }
265
+ const query = params.toString();
266
+ const response = await apiFetch(
267
+ apiBase,
268
+ token,
269
+ `/apps/list${query ? `?${query}` : ""}`,
270
+ { method: "GET" }
271
+ );
272
+ if (!response.ok) {
273
+ const text = await response.text().catch(() => "");
274
+ throw new Error(`Apps list failed: ${response.status} ${text}`);
275
+ }
276
+ const payload = await response.json().catch(() => ({}));
277
+ return Array.isArray(payload.apps) ? payload.apps : [];
278
+ }
279
+ async function createRepo(apiBase, apiKey, input3) {
280
+ const response = await apiFetch(apiBase, apiKey, "/apps/repo/create", {
281
+ method: "POST",
282
+ body: JSON.stringify(input3)
283
+ });
284
+ if (!response.ok) {
285
+ const text = await response.text().catch(() => "");
286
+ throw new Error(`Repo create failed: ${response.status} ${text}`);
287
+ }
288
+ return await response.json();
289
+ }
290
+ async function updateAppCodeVisibility(apiBase, apiKey, appId, codeVisibility) {
291
+ const response = await apiFetch(
292
+ apiBase,
293
+ apiKey,
294
+ `/apps/${encodeURIComponent(appId)}/code-visibility`,
295
+ {
296
+ method: "PATCH",
297
+ body: JSON.stringify({ codeVisibility })
298
+ }
299
+ );
300
+ if (!response.ok) {
301
+ const text = await response.text().catch(() => "");
302
+ throw new Error(
303
+ `Code visibility update failed: ${response.status} ${text}`
304
+ );
305
+ }
306
+ return await response.json();
307
+ }
308
+ async function createHeadlessApps(baseUrl, token, items, teamId) {
309
+ const response = await apiFetch(baseUrl, token, "/v4/apps/headless", {
310
+ method: "POST",
311
+ body: JSON.stringify({ items, ...teamId ? { teamId } : {} })
312
+ });
313
+ if (!response.ok) {
314
+ const text = await response.text().catch(() => "");
315
+ throw new Error(`Headless create failed: ${response.status} ${text}`);
316
+ }
317
+ return await response.json();
318
+ }
319
+ async function getTemplateStatus(apiBase, token, appId) {
320
+ const response = await apiFetch(
321
+ apiBase,
322
+ token,
323
+ `/v4/apps/${appId}/template/status`,
324
+ { method: "GET" }
325
+ );
326
+ if (!response.ok) {
327
+ const text = await response.text().catch(() => "");
328
+ throw new Error(`Template status failed: ${response.status} ${text}`);
329
+ }
330
+ return await response.json();
331
+ }
332
+ async function listTemplateBranches(apiBase, token, appId) {
333
+ const response = await apiFetch(
334
+ apiBase,
335
+ token,
336
+ `/v4/apps/${appId}/template/branches`,
337
+ { method: "GET" }
338
+ );
339
+ if (!response.ok) {
340
+ const text = await response.text().catch(() => "");
341
+ throw new Error(`Template branches failed: ${response.status} ${text}`);
342
+ }
343
+ return await response.json();
344
+ }
345
+ async function deployLatestTemplate(apiBase, token, appId, input3) {
346
+ const response = await apiFetch(
347
+ apiBase,
348
+ token,
349
+ `/v4/apps/${appId}/template/deploy-latest`,
350
+ {
351
+ method: "POST",
352
+ body: JSON.stringify(input3)
353
+ }
354
+ );
355
+ if (!response.ok) {
356
+ const text = await response.text().catch(() => "");
357
+ throw new Error(`Template deploy failed: ${response.status} ${text}`);
358
+ }
359
+ return await response.json();
360
+ }
361
+ async function updateAppEnvironment(apiBase, token, appId, input3) {
362
+ const response = await apiFetch(
363
+ apiBase,
364
+ token,
365
+ `/v4/apps/${appId}/environment`,
366
+ {
367
+ method: "POST",
368
+ body: JSON.stringify(input3)
369
+ }
370
+ );
371
+ if (!response.ok) {
372
+ const text = await response.text().catch(() => "");
373
+ throw new Error(`Environment update failed: ${response.status} ${text}`);
374
+ }
375
+ return await response.json();
376
+ }
377
+ async function getAppEnvironment(apiBase, token, appId) {
378
+ const response = await apiFetch(
379
+ apiBase,
380
+ token,
381
+ `/v4/apps/${appId}/environment`,
382
+ {
383
+ method: "GET"
384
+ }
385
+ );
386
+ if (!response.ok) {
387
+ const text = await response.text().catch(() => "");
388
+ throw new Error(`Environment get failed: ${response.status} ${text}`);
389
+ }
390
+ return await response.json();
391
+ }
392
+ async function listUserTools(baseUrl, token) {
393
+ const response = await apiFetch(baseUrl, token, "/apps/tools", {
394
+ method: "GET"
395
+ });
396
+ if (!response.ok) {
397
+ const text = await response.text().catch(() => "");
398
+ throw new Error(`Tools lookup failed: ${response.status} ${text}`);
399
+ }
400
+ return await response.json();
401
+ }
402
+ async function createAgentFromPrompt(baseUrl, token, payload) {
403
+ return apiFetch(baseUrl, token, "/apps/agent/create", {
404
+ method: "POST",
405
+ body: JSON.stringify(payload)
406
+ });
407
+ }
408
+ async function getUserPerformance(baseUrl, token, options) {
409
+ const params = new URLSearchParams();
410
+ if (options?.appId) {
411
+ params.set("appId", options.appId);
412
+ }
413
+ const qs = params.toString();
414
+ const response = await apiFetch(
415
+ baseUrl,
416
+ token,
417
+ `/apps/performance${qs ? `?${qs}` : ""}`,
418
+ {
419
+ method: "GET"
420
+ }
421
+ );
422
+ if (!response.ok) {
423
+ const text = await response.text().catch(() => "");
424
+ throw new Error(`Performance lookup failed: ${response.status} ${text}`);
425
+ }
426
+ return await response.json();
427
+ }
428
+ async function getAppRuntimeSummary(baseUrl, token, appId) {
429
+ const params = new URLSearchParams({ appId });
430
+ const response = await apiFetch(
431
+ baseUrl,
432
+ token,
433
+ `/apps/summary?${params.toString()}`,
434
+ {
435
+ method: "GET"
436
+ }
437
+ );
438
+ if (!response.ok) {
439
+ const text = await response.text().catch(() => "");
440
+ throw new Error(`Summary lookup failed: ${response.status} ${text}`);
441
+ }
442
+ return await response.json();
443
+ }
444
+ async function getOpenPondAccount(baseUrl, token) {
445
+ const response = await apiFetch(baseUrl, token, "/account", {
446
+ method: "GET"
447
+ });
448
+ if (!response.ok) {
449
+ const text = await response.text().catch(() => "");
450
+ throw new Error(`Account lookup failed: ${response.status} ${text}`);
451
+ }
452
+ return await response.json();
453
+ }
454
+ async function checkOpenPondApiHealth(baseUrl, token) {
455
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
456
+ const started = Date.now();
457
+ const normalizedBase = baseUrl.replace(/\/$/, "");
458
+ try {
459
+ const response = await fetch(`${normalizedBase}/health`, {
460
+ method: "GET",
461
+ headers: { Accept: "application/json" }
462
+ });
463
+ const latencyMs = Date.now() - started;
464
+ const payload = await response.json().catch(() => ({}));
465
+ let authenticated = null;
466
+ let account = null;
467
+ if (token?.trim()) {
468
+ try {
469
+ const accountPayload = await getOpenPondAccount(normalizedBase, token);
470
+ authenticated = true;
471
+ account = accountPayload.account;
472
+ } catch {
473
+ authenticated = false;
474
+ }
475
+ }
476
+ return {
477
+ reachable: response.ok,
478
+ authenticated,
479
+ apiBase: normalizedBase,
480
+ latencyMs,
481
+ status: response.status,
482
+ service: typeof payload.service === "string" ? payload.service : null,
483
+ checkedAt,
484
+ account,
485
+ ...response.ok ? {} : { error: response.statusText || `HTTP ${response.status}` }
486
+ };
487
+ } catch (error) {
488
+ return {
489
+ reachable: false,
490
+ authenticated: token?.trim() ? false : null,
491
+ apiBase: normalizedBase,
492
+ latencyMs: Date.now() - started,
493
+ status: null,
494
+ service: null,
495
+ checkedAt,
496
+ error: error instanceof Error ? error.message : String(error)
497
+ };
498
+ }
499
+ }
500
+ async function runAssistantMode(baseUrl, token, payload) {
501
+ const response = await apiFetch(baseUrl, token, "/apps/assistant/run", {
502
+ method: "POST",
503
+ body: JSON.stringify(payload)
504
+ });
505
+ if (!response.ok) {
506
+ const text = await response.text().catch(() => "");
507
+ throw new Error(`Assistant run failed: ${response.status} ${text}`);
508
+ }
509
+ return await response.json();
510
+ }
511
+ async function executeUserTool(baseUrl, token, body) {
512
+ const response = await apiFetch(baseUrl, token, "/apps/tools/execute", {
513
+ method: "POST",
514
+ body: JSON.stringify(body)
515
+ });
516
+ const text = await response.text().catch(() => "");
517
+ let payload = null;
518
+ try {
519
+ payload = text ? JSON.parse(text) : null;
520
+ } catch {
521
+ payload = text;
522
+ }
523
+ if (!response.ok) {
524
+ return {
525
+ ok: false,
526
+ status: response.status,
527
+ error: payload && typeof payload === "object" && "error" in payload ? String(payload.error) : text || response.statusText
528
+ };
529
+ }
530
+ return {
531
+ ok: true,
532
+ status: response.status,
533
+ data: payload
534
+ };
535
+ }
536
+ async function submitPositionsTx(baseUrl, token, params) {
537
+ const qs = params.query && Object.keys(params.query).length > 0 ? `?${new URLSearchParams(params.query).toString()}` : "";
538
+ const response = await apiFetch(baseUrl, token, `/apps/positions/tx${qs}`, {
539
+ method: params.method,
540
+ body: params.method === "POST" && params.body !== void 0 ? JSON.stringify(params.body) : void 0
541
+ });
542
+ if (!response.ok) {
543
+ const text = await response.text().catch(() => "");
544
+ throw new Error(`Positions request failed: ${response.status} ${text}`);
545
+ }
546
+ return await response.json();
547
+ }
548
+ async function submitBacktestRun(baseUrl, token, body) {
549
+ const response = await apiFetch(baseUrl, token, "/apps/backtests/run", {
550
+ method: "POST",
551
+ body: JSON.stringify(body)
552
+ });
553
+ if (!response.ok) {
554
+ const text = await response.text().catch(() => "");
555
+ throw new Error(`Backtest run failed: ${response.status} ${text}`);
556
+ }
557
+ return await response.json();
558
+ }
559
+ async function submitBacktestTx(baseUrl, token, params) {
560
+ const qs = params.query && Object.keys(params.query).length > 0 ? `?${new URLSearchParams(params.query).toString()}` : "";
561
+ const response = await apiFetch(baseUrl, token, `/apps/backtests/tx${qs}`, {
562
+ method: params.method,
563
+ body: params.method === "POST" && params.body !== void 0 ? JSON.stringify(params.body) : void 0
564
+ });
565
+ if (!response.ok) {
566
+ const text = await response.text().catch(() => "");
567
+ throw new Error(`Backtests request failed: ${response.status} ${text}`);
568
+ }
569
+ return await response.json();
570
+ }
571
+ async function submitBacktestDetail(baseUrl, token, query) {
572
+ const qs = new URLSearchParams(query).toString();
573
+ const response = await apiFetch(
574
+ baseUrl,
575
+ token,
576
+ `/apps/backtests/detail?${qs}`,
577
+ {
578
+ method: "GET"
579
+ }
580
+ );
581
+ if (!response.ok) {
582
+ const text = await response.text().catch(() => "");
583
+ throw new Error(`Backtest detail failed: ${response.status} ${text}`);
584
+ }
585
+ return await response.json();
586
+ }
587
+ function normalizeToolPathSegment(toolName) {
588
+ const trimmed = toolName.trim().replace(/^\/+/, "");
589
+ return encodeURIComponent(trimmed || "tool");
590
+ }
591
+ function resolveWorkerBaseUrl(baseUrl) {
592
+ const trimmed = baseUrl.replace(/\/$/, "");
593
+ const workerEnv = process.env.OPENPOND_TOOL_URL;
594
+ if (workerEnv) {
595
+ return workerEnv.replace(/\/$/, "");
596
+ }
597
+ try {
598
+ const url = new URL(trimmed);
599
+ const host = url.hostname.toLowerCase();
600
+ const mappedHost = (() => {
601
+ if (host === "apps.openpond.live") {
602
+ return null;
603
+ }
604
+ if (host === DEFAULT_OPENPOND_API_HOST || host === DEFAULT_OPENPOND_WEB_HOST || host === "openpond.live" || host === "www.openpond.live") {
605
+ return "https://apps.openpond.live";
606
+ }
607
+ return null;
608
+ })();
609
+ if (mappedHost) {
610
+ return mappedHost;
611
+ }
612
+ const isLocal = host === "localhost" || host === "127.0.0.1";
613
+ const port = url.port || (url.protocol === "https:" ? "443" : "80");
614
+ if (isLocal && port === "3000") {
615
+ return trimmed;
616
+ }
617
+ } catch {
618
+ }
619
+ return trimmed;
620
+ }
621
+ async function executeHostedTool(baseUrl, token, payload) {
622
+ const workerBase = resolveWorkerBaseUrl(baseUrl);
623
+ const toolPath = normalizeToolPathSegment(payload.toolName);
624
+ const deploymentPrefix = payload.deploymentId ? `/${payload.appId}/deployments/${payload.deploymentId}` : `/${payload.appId}`;
625
+ const requestPath = `${deploymentPrefix}/${toolPath}`;
626
+ const headers = new Headers(payload.headers || {});
627
+ const method = payload.method ?? "POST";
628
+ const body = payload.body === void 0 || method === "GET" ? void 0 : JSON.stringify(payload.body);
629
+ const response = await apiFetch(workerBase, token, requestPath, {
630
+ method,
631
+ body,
632
+ headers
633
+ });
634
+ const text = await response.text().catch(() => "");
635
+ let data = null;
636
+ try {
637
+ data = text ? JSON.parse(text) : null;
638
+ } catch {
639
+ data = text;
640
+ }
641
+ const dataOk = data && typeof data === "object" && "ok" in data ? Boolean(data.ok) : true;
642
+ const ok = response.ok && dataOk;
643
+ const status = data && typeof data === "object" && "status" in data ? Number(data.status) || response.status : response.status;
644
+ const error = data && typeof data === "object" && "error" in data ? String(data.error) : response.ok ? void 0 : text || response.statusText;
645
+ const payloadData = data && typeof data === "object" && "data" in data ? data.data : data;
646
+ return { ok, status, data: payloadData, error };
647
+ }
648
+
649
+ // ../../packages/cloud/src/config.ts
650
+ import { promises as fs2 } from "node:fs";
651
+ import path2 from "node:path";
652
+
653
+ // ../../packages/cloud/src/private-json-file.ts
654
+ import { randomUUID } from "node:crypto";
655
+ import { promises as fs } from "node:fs";
656
+ import os from "node:os";
657
+ import path from "node:path";
658
+ var LOCK_WAIT_TIMEOUT_MS = 1e4;
659
+ var STALE_LOCK_MS = 6e4;
660
+ function openPondConfigDirectory() {
661
+ const override = process.env.OPENPOND_CONFIG_DIR?.trim();
662
+ return override || path.join(os.homedir(), ".openpond");
663
+ }
664
+ async function writePrivateJsonFile(filePath, value) {
665
+ await withPrivateJsonFileLock(filePath, () => writePrivateJsonFileUnlocked(filePath, value));
666
+ }
667
+ async function updatePrivateJsonFile(filePath, fallback, update) {
668
+ return withPrivateJsonFileLock(filePath, async () => {
669
+ const current = await readJsonFile(filePath, fallback);
670
+ const next = await update(current);
671
+ await writePrivateJsonFileUnlocked(filePath, next);
672
+ return next;
673
+ });
674
+ }
675
+ async function writePrivateJsonFileUnlocked(filePath, value) {
676
+ const directory = path.dirname(filePath);
677
+ await fs.mkdir(directory, { recursive: true, mode: 448 });
678
+ await fs.chmod(directory, 448).catch(() => void 0);
679
+ const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
680
+ try {
681
+ await fs.writeFile(temporaryPath, JSON.stringify(value, null, 2), {
682
+ encoding: "utf-8",
683
+ mode: 384
684
+ });
685
+ await fs.rename(temporaryPath, filePath);
686
+ await fs.chmod(filePath, 384).catch(() => void 0);
687
+ } finally {
688
+ await fs.rm(temporaryPath, { force: true }).catch(() => void 0);
689
+ }
690
+ }
691
+ async function withPrivateJsonFileLock(filePath, operation) {
692
+ const directory = path.dirname(filePath);
693
+ await fs.mkdir(directory, { recursive: true, mode: 448 });
694
+ await fs.chmod(directory, 448).catch(() => void 0);
695
+ const lockPath = `${filePath}.lock`;
696
+ const deadline = Date.now() + LOCK_WAIT_TIMEOUT_MS;
697
+ while (true) {
698
+ try {
699
+ await fs.mkdir(lockPath, { mode: 448 });
700
+ break;
701
+ } catch (error) {
702
+ if (error.code !== "EEXIST") throw error;
703
+ await removeStaleLock(lockPath);
704
+ if (Date.now() >= deadline) throw new Error(`Timed out waiting for private file lock: ${filePath}`);
705
+ await new Promise((resolve) => setTimeout(resolve, 20 + Math.floor(Math.random() * 30)));
706
+ }
707
+ }
708
+ try {
709
+ return await operation();
710
+ } finally {
711
+ await fs.rm(lockPath, { recursive: true, force: true }).catch(() => void 0);
712
+ }
713
+ }
714
+ async function readJsonFile(filePath, fallback) {
715
+ try {
716
+ return JSON.parse(await fs.readFile(filePath, "utf8"));
717
+ } catch (error) {
718
+ if (error.code === "ENOENT") return fallback();
719
+ throw error;
720
+ }
721
+ }
722
+ async function removeStaleLock(lockPath) {
723
+ const stats = await fs.stat(lockPath).catch(() => null);
724
+ if (stats && Date.now() - stats.mtimeMs > STALE_LOCK_MS) {
725
+ await fs.rm(lockPath, { recursive: true, force: true });
726
+ }
727
+ }
728
+
729
+ // ../../packages/cloud/src/config.ts
730
+ var GLOBAL_CONFIG_FILENAME = "config.json";
731
+ var DEFAULT_ACCOUNT_HANDLE = "default";
732
+ var ACCOUNT_SCOPED_KEYS = [
733
+ "apiKey",
734
+ "baseUrl",
735
+ "apiBaseUrl",
736
+ "chatApiBaseUrl",
737
+ "token",
738
+ "appId",
739
+ "conversationId"
740
+ ];
741
+ function getGlobalConfigPath() {
742
+ return path2.join(openPondConfigDirectory(), GLOBAL_CONFIG_FILENAME);
743
+ }
744
+ async function loadConfigFile(filePath) {
745
+ try {
746
+ const raw = await fs2.readFile(filePath, "utf-8");
747
+ return JSON.parse(raw);
748
+ } catch (error) {
749
+ if (error.code === "ENOENT") return {};
750
+ if (error instanceof SyntaxError) {
751
+ throw new Error(`OpenPond config is malformed JSON: ${filePath}`, { cause: error });
752
+ }
753
+ throw error;
754
+ }
755
+ }
756
+ function hasOwn(value, key) {
757
+ return Object.prototype.hasOwnProperty.call(value, key);
758
+ }
759
+ function normalizeHandle(value) {
760
+ if (typeof value !== "string") return null;
761
+ const trimmed = value.trim();
762
+ return trimmed.length > 0 ? trimmed : null;
763
+ }
764
+ function normalizeBaseUrl(value) {
765
+ if (typeof value !== "string") return null;
766
+ const trimmed = value.trim();
767
+ if (!trimmed) return null;
768
+ return trimmed.replace(/\/$/, "");
769
+ }
770
+ function requireHandle(value) {
771
+ const handle = normalizeHandle(value);
772
+ if (!handle) {
773
+ throw new Error("profile handle must be non-empty");
774
+ }
775
+ return handle;
776
+ }
777
+ function requireApiKey(value) {
778
+ if (typeof value !== "string") {
779
+ throw new Error("apiKey must be a non-empty string");
780
+ }
781
+ const trimmed = value.trim();
782
+ if (!trimmed) {
783
+ throw new Error("apiKey must be a non-empty string");
784
+ }
785
+ return trimmed;
786
+ }
787
+ function handleEquals(left, right) {
788
+ const normalizedLeft = normalizeHandle(left);
789
+ const normalizedRight = normalizeHandle(right);
790
+ return Boolean(
791
+ normalizedLeft && normalizedRight && normalizedLeft.toLowerCase() === normalizedRight.toLowerCase()
792
+ );
793
+ }
794
+ function findAccountIndex(accounts, handle, baseUrl) {
795
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
796
+ return accounts.findIndex((candidate) => {
797
+ if (!handleEquals(candidate.handle, handle)) return false;
798
+ if (!normalizedBaseUrl) return true;
799
+ return normalizeBaseUrl(candidate.baseUrl) === normalizedBaseUrl;
800
+ });
801
+ }
802
+ function selectorFromAccount(account) {
803
+ const handle = normalizeHandle(account.handle) ?? DEFAULT_ACCOUNT_HANDLE;
804
+ const baseUrl = normalizeBaseUrl(account.baseUrl);
805
+ return baseUrl ? { handle, baseUrl } : { handle };
806
+ }
807
+ function sanitizeActiveProfile(value) {
808
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
809
+ const input3 = value;
810
+ const handle = normalizeHandle(
811
+ typeof input3.handle === "string" ? input3.handle : void 0
812
+ );
813
+ if (!handle) return null;
814
+ const baseUrl = normalizeBaseUrl(
815
+ typeof input3.baseUrl === "string" ? input3.baseUrl : void 0
816
+ );
817
+ return baseUrl ? { handle, baseUrl } : { handle };
818
+ }
819
+ function sanitizeLocalOpenPondProfile(value) {
820
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
821
+ return void 0;
822
+ }
823
+ const input3 = value;
824
+ const repoPath = typeof input3.repoPath === "string" ? input3.repoPath.trim() : "";
825
+ const profile = typeof input3.profile === "string" && input3.profile.trim() ? input3.profile.trim() : "default";
826
+ if (!repoPath) return void 0;
827
+ const out = {
828
+ repoPath,
829
+ profile,
830
+ mode: "local"
831
+ };
832
+ if (input3.lastCheck && typeof input3.lastCheck === "object" && !Array.isArray(input3.lastCheck)) {
833
+ const check = input3.lastCheck;
834
+ const command = check.command;
835
+ const status = check.status;
836
+ const checkedAt = check.checkedAt;
837
+ if ((command === "inspect" || command === "build" || command === "validate" || command === "eval" || command === "run") && (status === "passed" || status === "failed") && typeof checkedAt === "string") {
838
+ out.lastCheck = {
839
+ command,
840
+ status,
841
+ checkedAt,
842
+ ...typeof check.exitCode === "number" || check.exitCode === null ? { exitCode: check.exitCode } : {},
843
+ ...typeof check.sourceHead === "string" || check.sourceHead === null ? { sourceHead: check.sourceHead } : {}
844
+ };
845
+ }
846
+ }
847
+ if (input3.lastPush && typeof input3.lastPush === "object" && !Array.isArray(input3.lastPush)) {
848
+ const push = input3.lastPush;
849
+ const status = push.status;
850
+ const pushedAt = push.pushedAt;
851
+ if ((status === "pushed" || status === "failed") && typeof pushedAt === "string") {
852
+ out.lastPush = {
853
+ status,
854
+ pushedAt,
855
+ ...typeof push.teamId === "string" || push.teamId === null ? { teamId: push.teamId } : {},
856
+ ...typeof push.projectId === "string" || push.projectId === null ? { projectId: push.projectId } : {},
857
+ ...typeof push.localHead === "string" || push.localHead === null ? { localHead: push.localHead } : {},
858
+ ...typeof push.hostedHead === "string" || push.hostedHead === null ? { hostedHead: push.hostedHead } : {},
859
+ ...typeof push.sourceRef === "string" || push.sourceRef === null ? { sourceRef: push.sourceRef } : {},
860
+ ...push.promotionStatus === "uploaded" || push.promotionStatus === "hosted_source_materialized" || push.promotionStatus === "hosted_source_materialize_failed" || push.promotionStatus === "hosted_source_check_pending" || push.promotionStatus === "hosted_source_check_failed" || push.promotionStatus === "hosted_source_published" || push.promotionStatus === "hosted_source_publish_failed" || push.promotionStatus === "hosted_run_pending" || push.promotionStatus === "hosted_run_passed" || push.promotionStatus === "hosted_run_failed" || push.promotionStatus === null ? { promotionStatus: push.promotionStatus } : {},
861
+ ...push.hostedRunStatus === "not_started" || push.hostedRunStatus === "running" || push.hostedRunStatus === "passed" || push.hostedRunStatus === "failed" || push.hostedRunStatus === null ? { hostedRunStatus: push.hostedRunStatus } : {},
862
+ ...typeof push.localGoalId === "string" || push.localGoalId === null ? { localGoalId: push.localGoalId } : {},
863
+ ...typeof push.hostedGoalId === "string" || push.hostedGoalId === null ? { hostedGoalId: push.hostedGoalId } : {},
864
+ ...typeof push.hostedRunAgentId === "string" || push.hostedRunAgentId === null ? { hostedRunAgentId: push.hostedRunAgentId } : {},
865
+ ...typeof push.hostedRunId === "string" || push.hostedRunId === null ? { hostedRunId: push.hostedRunId } : {},
866
+ ...typeof push.hostedRunAt === "string" || push.hostedRunAt === null ? { hostedRunAt: push.hostedRunAt } : {},
867
+ ...sanitizeHostedMaterializationStatus(push.hostedSourceMaterialization) ? { hostedSourceMaterialization: sanitizeHostedMaterializationStatus(push.hostedSourceMaterialization) } : {},
868
+ ...sanitizeHostedSourceCheckStatus(push.hostedSourceCheck) ? { hostedSourceCheck: sanitizeHostedSourceCheckStatus(push.hostedSourceCheck) } : {},
869
+ ...sanitizeHostedPublishStatus(push.hostedPublish) ? { hostedPublish: sanitizeHostedPublishStatus(push.hostedPublish) } : {},
870
+ ...sanitizeHostedRunSummary(push.hostedRun) ? { hostedRun: sanitizeHostedRunSummary(push.hostedRun) } : {},
871
+ ...typeof push.error === "string" || push.error === null ? { error: push.error } : {}
872
+ };
873
+ }
874
+ }
875
+ return out;
876
+ }
877
+ function sanitizeHostedMaterializationStatus(value) {
878
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
879
+ const input3 = value;
880
+ const status = stringField(input3.status);
881
+ if (!status) return null;
882
+ return {
883
+ status,
884
+ ...nullableStringProp(input3, "agentId"),
885
+ ...nullableStringProp(input3, "runtimeAgentId"),
886
+ ...nullableStringProp(input3, "projectId"),
887
+ ...nullableStringProp(input3, "sourceRoot"),
888
+ ...nullableStringProp(input3, "sourceRef"),
889
+ ...nullableStringProp(input3, "sourceCommitSha"),
890
+ ...nullableStringProp(input3, "manifestHash"),
891
+ ...nullableStringProp(input3, "manifestPath"),
892
+ ...nullableStringProp(input3, "manifestSyncedAt"),
893
+ ...nullableNumberProp(input3, "fileCount"),
894
+ ...nullableNumberProp(input3, "totalBytes"),
895
+ ...nullableStringProp(input3, "generatedManifestPath"),
896
+ ...nullableBooleanProp(input3, "synthesizedOpenPondYaml"),
897
+ ...nullableStringProp(input3, "uploadMetadataPath"),
898
+ ...stringArrayProp(input3, "setupCommands"),
899
+ ...stringArrayProp(input3, "validationCommands"),
900
+ ...nullableStringProp(input3, "materializedAt"),
901
+ ...nullableStringProp(input3, "error")
902
+ };
903
+ }
904
+ function sanitizeHostedSourceCheckStatus(value) {
905
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
906
+ const input3 = value;
907
+ const status = stringField(input3.status);
908
+ if (!status) return null;
909
+ return {
910
+ status,
911
+ ...nullableStringProp(input3, "agentId"),
912
+ ...nullableStringProp(input3, "workItemId"),
913
+ ...nullableStringProp(input3, "deployPlanStatus"),
914
+ ...nullableBooleanProp(input3, "canRun"),
915
+ ...nullableBooleanProp(input3, "canDeploy"),
916
+ ...nullableStringProp(input3, "sourceRef"),
917
+ ...nullableStringProp(input3, "sourceCommitSha"),
918
+ ...nullableStringProp(input3, "manifestHash"),
919
+ ...nullableStringProp(input3, "manifestPath"),
920
+ ...stringArrayProp(input3, "setupCommands"),
921
+ ...stringArrayProp(input3, "validationCommands"),
922
+ ...stringArrayProp(input3, "requiredChecks"),
923
+ ...stringArrayProp(input3, "evalNames"),
924
+ ...stringArrayProp(input3, "blockedReasons"),
925
+ ...stringArrayProp(input3, "staleReasons"),
926
+ ...nullableStringProp(input3, "runtimeId"),
927
+ ...nullableStringProp(input3, "sandboxId"),
928
+ ...stringArrayProp(input3, "traceArtifactRefs"),
929
+ ...stringArrayProp(input3, "evalResultArtifactRefs"),
930
+ ...stringArrayProp(input3, "validatorArtifactRefs"),
931
+ ...nullableStringProp(input3, "checkedAt"),
932
+ ...nullableStringProp(input3, "error")
933
+ };
934
+ }
935
+ function sanitizeHostedPublishStatus(value) {
936
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
937
+ const input3 = value;
938
+ const status = stringField(input3.status);
939
+ if (!status) return null;
940
+ return {
941
+ status,
942
+ ...nullableStringProp(input3, "agentId"),
943
+ ...nullableStringProp(input3, "snapshotId"),
944
+ ...nullableStringProp(input3, "sourceRef"),
945
+ ...nullableStringProp(input3, "sourceCommitSha"),
946
+ ...nullableStringProp(input3, "manifestHash"),
947
+ ...nullableStringProp(input3, "manifestPath"),
948
+ ...nullableStringProp(input3, "buildStatus"),
949
+ ...nullableStringProp(input3, "validationStatus"),
950
+ ...nullableStringProp(input3, "evalStatus"),
951
+ ...nullableStringProp(input3, "publishedAt"),
952
+ ...nullableStringProp(input3, "error")
953
+ };
954
+ }
955
+ function sanitizeHostedRunSummary(value) {
956
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
957
+ const input3 = value;
958
+ const status = stringField(input3.status);
959
+ if (!status) return null;
960
+ return {
961
+ status,
962
+ ...nullableStringProp(input3, "agentId"),
963
+ ...nullableStringProp(input3, "runId"),
964
+ ...nullableStringProp(input3, "runtimeId"),
965
+ ...nullableStringProp(input3, "sandboxId"),
966
+ ...nullableStringProp(input3, "sourceRef"),
967
+ ...nullableStringProp(input3, "sourceCommitSha"),
968
+ ...nullableStringProp(input3, "manifestHash"),
969
+ ...nullableStringProp(input3, "setupGateStatus"),
970
+ ...stringArrayProp(input3, "setupRequirementRefs"),
971
+ ...stringArrayProp(input3, "artifactRefs"),
972
+ ...stringArrayProp(input3, "traceArtifactRefs"),
973
+ ...stringArrayProp(input3, "evalArtifactRefs"),
974
+ ...nullableStringProp(input3, "startedAt"),
975
+ ...nullableStringProp(input3, "completedAt"),
976
+ ...nullableStringProp(input3, "error")
977
+ };
978
+ }
979
+ function nullableStringProp(input3, key) {
980
+ const value = input3[key];
981
+ return typeof value === "string" || value === null ? { [key]: value } : {};
982
+ }
983
+ function nullableBooleanProp(input3, key) {
984
+ const value = input3[key];
985
+ return typeof value === "boolean" || value === null ? { [key]: value } : {};
986
+ }
987
+ function nullableNumberProp(input3, key) {
988
+ const value = input3[key];
989
+ return typeof value === "number" || value === null ? { [key]: value } : {};
990
+ }
991
+ function stringArrayProp(input3, key) {
992
+ const value = input3[key];
993
+ if (!Array.isArray(value)) return {};
994
+ const strings = value.filter((item) => typeof item === "string");
995
+ return { [key]: strings };
996
+ }
997
+ function stringField(value) {
998
+ return typeof value === "string" && value.trim() ? value.trim() : null;
999
+ }
1000
+ function accountMatchesSelector(account, selector) {
1001
+ if (!handleEquals(account.handle, selector.handle)) return false;
1002
+ const selectorBaseUrl = normalizeBaseUrl(selector.baseUrl);
1003
+ if (selectorBaseUrl) {
1004
+ return normalizeBaseUrl(account.baseUrl) === selectorBaseUrl;
1005
+ }
1006
+ return !normalizeBaseUrl(account.baseUrl);
1007
+ }
1008
+ function findAccountIndexForSelector(accounts, selector, options = {}) {
1009
+ const normalizedBaseUrl = normalizeBaseUrl(selector.baseUrl);
1010
+ if (normalizedBaseUrl) {
1011
+ return findAccountIndex(accounts, selector.handle, normalizedBaseUrl);
1012
+ }
1013
+ const noBaseIdx = accounts.findIndex(
1014
+ (account) => accountMatchesSelector(account, selector)
1015
+ );
1016
+ if (noBaseIdx !== -1) return noBaseIdx;
1017
+ const matches = accounts.map((account, index) => ({ account, index })).filter(({ account }) => handleEquals(account.handle, selector.handle));
1018
+ if (matches.length > 1 && options.requireUnambiguous) {
1019
+ throw new Error(
1020
+ `multiple profiles found for ${selector.handle}; pass --base-url to select one`
1021
+ );
1022
+ }
1023
+ return matches[0]?.index ?? -1;
1024
+ }
1025
+ function sanitizeSession(value) {
1026
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
1027
+ return void 0;
1028
+ }
1029
+ const input3 = value;
1030
+ const out = {};
1031
+ if (typeof input3.token === "string") out.token = input3.token;
1032
+ if (typeof input3.appId === "string" || input3.appId === null) {
1033
+ out.appId = input3.appId;
1034
+ }
1035
+ if (typeof input3.conversationId === "string" || input3.conversationId === null) {
1036
+ out.conversationId = input3.conversationId;
1037
+ }
1038
+ return Object.keys(out).length > 0 ? out : void 0;
1039
+ }
1040
+ function sanitizeAccount(value) {
1041
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
1042
+ const input3 = value;
1043
+ const handle = normalizeHandle(
1044
+ typeof input3.handle === "string" ? input3.handle : void 0
1045
+ );
1046
+ if (!handle) return null;
1047
+ const out = { handle };
1048
+ if (typeof input3.apiKey === "string") out.apiKey = input3.apiKey;
1049
+ if (typeof input3.baseUrl === "string") out.baseUrl = input3.baseUrl;
1050
+ if (typeof input3.apiBaseUrl === "string") out.apiBaseUrl = input3.apiBaseUrl;
1051
+ if (typeof input3.chatApiBaseUrl === "string")
1052
+ out.chatApiBaseUrl = input3.chatApiBaseUrl;
1053
+ if (typeof input3.environment === "string")
1054
+ out.environment = input3.environment;
1055
+ const session = sanitizeSession(input3.session);
1056
+ if (session) out.session = session;
1057
+ return out;
1058
+ }
1059
+ function extractLegacySession(raw) {
1060
+ const session = {};
1061
+ if (typeof raw.token === "string") session.token = raw.token;
1062
+ if (typeof raw.appId === "string" || raw.appId === null) {
1063
+ session.appId = raw.appId;
1064
+ }
1065
+ if (typeof raw.conversationId === "string" || raw.conversationId === null) {
1066
+ session.conversationId = raw.conversationId;
1067
+ }
1068
+ return Object.keys(session).length > 0 ? session : void 0;
1069
+ }
1070
+ function extractLegacyAccount(raw, handle) {
1071
+ const out = { handle };
1072
+ if (typeof raw.apiKey === "string") out.apiKey = raw.apiKey;
1073
+ if (typeof raw.baseUrl === "string") out.baseUrl = raw.baseUrl;
1074
+ if (typeof raw.apiBaseUrl === "string") out.apiBaseUrl = raw.apiBaseUrl;
1075
+ if (typeof raw.chatApiBaseUrl === "string")
1076
+ out.chatApiBaseUrl = raw.chatApiBaseUrl;
1077
+ const session = extractLegacySession(raw);
1078
+ if (session) out.session = session;
1079
+ return out;
1080
+ }
1081
+ function normalizeGlobalConfig(raw) {
1082
+ const normalized = {};
1083
+ if (raw.goalStorageLocation === "global" || raw.goalStorageLocation === "workspace") {
1084
+ normalized.goalStorageLocation = raw.goalStorageLocation;
1085
+ }
1086
+ if (typeof raw.lspEnabled === "boolean")
1087
+ normalized.lspEnabled = raw.lspEnabled;
1088
+ if (raw.executionMode === "local" || raw.executionMode === "hosted") {
1089
+ normalized.executionMode = raw.executionMode;
1090
+ }
1091
+ if (raw.mode === "general" || raw.mode === "builder") {
1092
+ normalized.mode = raw.mode;
1093
+ }
1094
+ const openpondProfile = sanitizeLocalOpenPondProfile(raw.openpondProfile);
1095
+ if (openpondProfile) {
1096
+ normalized.openpondProfile = openpondProfile;
1097
+ }
1098
+ const accounts = [];
1099
+ const sourceAccounts = Array.isArray(raw.accounts) ? raw.accounts : [];
1100
+ for (const candidate of sourceAccounts) {
1101
+ const account = sanitizeAccount(candidate);
1102
+ if (!account) continue;
1103
+ if (findAccountIndex(accounts, account.handle, account.baseUrl) !== -1)
1104
+ continue;
1105
+ accounts.push(account);
1106
+ }
1107
+ if (accounts.length === 0) {
1108
+ const legacyHandle = sanitizeActiveProfile(raw.activeProfile)?.handle || DEFAULT_ACCOUNT_HANDLE;
1109
+ accounts.push(extractLegacyAccount(raw, legacyHandle));
1110
+ }
1111
+ const requested = sanitizeActiveProfile(raw.activeProfile);
1112
+ const activeIdx = requested ? findAccountIndexForSelector(accounts, requested) : -1;
1113
+ const activeAccount = accounts[activeIdx === -1 ? 0 : activeIdx];
1114
+ normalized.accounts = accounts;
1115
+ normalized.activeProfile = selectorFromAccount(activeAccount);
1116
+ return normalized;
1117
+ }
1118
+ function resolveRequestedProfile(global, explicitAccount, explicitBaseUrl) {
1119
+ const accounts = global.accounts ?? [];
1120
+ const requestedBaseUrl = normalizeBaseUrl(
1121
+ explicitBaseUrl ?? process.env.OPENPOND_BASE_URL
1122
+ );
1123
+ const explicit = normalizeHandle(explicitAccount);
1124
+ if (explicit) {
1125
+ return requestedBaseUrl ? { handle: explicit, baseUrl: requestedBaseUrl } : { handle: explicit };
1126
+ }
1127
+ const envAccount = normalizeHandle(process.env.OPENPOND_ACCOUNT);
1128
+ if (envAccount) {
1129
+ return requestedBaseUrl ? { handle: envAccount, baseUrl: requestedBaseUrl } : { handle: envAccount };
1130
+ }
1131
+ const activeProfile = sanitizeActiveProfile(global.activeProfile);
1132
+ if (activeProfile) {
1133
+ return requestedBaseUrl ? { handle: activeProfile.handle, baseUrl: requestedBaseUrl } : activeProfile;
1134
+ }
1135
+ return accounts[0] ? selectorFromAccount(accounts[0]) : { handle: DEFAULT_ACCOUNT_HANDLE };
1136
+ }
1137
+ function ensureAccount(accounts, handle, baseUrl) {
1138
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
1139
+ if (normalizedBaseUrl) {
1140
+ const idx = findAccountIndex(accounts, handle, normalizedBaseUrl);
1141
+ if (idx !== -1) {
1142
+ return accounts[idx];
1143
+ }
1144
+ } else {
1145
+ const matches = accounts.filter(
1146
+ (account) => handleEquals(account.handle, handle)
1147
+ );
1148
+ if (matches.length > 1) {
1149
+ throw new Error(
1150
+ `multiple profiles found for ${handle}; pass --base-url to select one`
1151
+ );
1152
+ }
1153
+ if (matches.length === 1) {
1154
+ return matches[0];
1155
+ }
1156
+ }
1157
+ const next = { handle };
1158
+ if (normalizedBaseUrl) {
1159
+ next.baseUrl = normalizedBaseUrl;
1160
+ }
1161
+ accounts.push(next);
1162
+ return next;
1163
+ }
1164
+ function cleanupAccount(account) {
1165
+ if (account.session && Object.keys(account.session).length === 0) {
1166
+ delete account.session;
1167
+ }
1168
+ }
1169
+ function applyScopedKey(account, key, value, options) {
1170
+ const shouldDelete = value === null || value === void 0 && options.undefinedDeletes;
1171
+ switch (key) {
1172
+ case "apiKey": {
1173
+ if (shouldDelete) {
1174
+ delete account.apiKey;
1175
+ return;
1176
+ }
1177
+ if (typeof value === "string") {
1178
+ account.apiKey = value;
1179
+ }
1180
+ return;
1181
+ }
1182
+ case "baseUrl": {
1183
+ if (shouldDelete) {
1184
+ delete account.baseUrl;
1185
+ return;
1186
+ }
1187
+ if (typeof value === "string") {
1188
+ account.baseUrl = value;
1189
+ }
1190
+ return;
1191
+ }
1192
+ case "apiBaseUrl": {
1193
+ if (shouldDelete) {
1194
+ delete account.apiBaseUrl;
1195
+ return;
1196
+ }
1197
+ if (typeof value === "string") {
1198
+ account.apiBaseUrl = value;
1199
+ }
1200
+ return;
1201
+ }
1202
+ case "chatApiBaseUrl": {
1203
+ if (shouldDelete) {
1204
+ delete account.chatApiBaseUrl;
1205
+ return;
1206
+ }
1207
+ if (typeof value === "string") {
1208
+ account.chatApiBaseUrl = value;
1209
+ }
1210
+ return;
1211
+ }
1212
+ case "token":
1213
+ case "appId":
1214
+ case "conversationId": {
1215
+ if (!account.session) account.session = {};
1216
+ if (shouldDelete) {
1217
+ delete account.session[key];
1218
+ cleanupAccount(account);
1219
+ return;
1220
+ }
1221
+ if (typeof value === "string" || value === null) {
1222
+ account.session[key] = value;
1223
+ }
1224
+ cleanupAccount(account);
1225
+ return;
1226
+ }
1227
+ }
1228
+ }
1229
+ function applyAccountPatch(global, source, options) {
1230
+ const hasScopedPatch = ACCOUNT_SCOPED_KEYS.some((key) => hasOwn(source, key));
1231
+ if (!hasScopedPatch) return false;
1232
+ const accounts = global.accounts ?? [];
1233
+ const selector = sanitizeActiveProfile(source.activeProfile) ?? resolveRequestedProfile(global);
1234
+ const requestedBaseUrl = normalizeBaseUrl(
1235
+ hasOwn(source, "baseUrl") ? source.baseUrl ?? null : selector.baseUrl ?? process.env.OPENPOND_BASE_URL
1236
+ );
1237
+ const account = ensureAccount(accounts, selector.handle, requestedBaseUrl);
1238
+ for (const key of ACCOUNT_SCOPED_KEYS) {
1239
+ if (!hasOwn(source, key)) continue;
1240
+ applyScopedKey(
1241
+ account,
1242
+ key,
1243
+ source[key],
1244
+ options
1245
+ );
1246
+ }
1247
+ global.accounts = accounts;
1248
+ global.activeProfile = selectorFromAccount(account);
1249
+ return true;
1250
+ }
1251
+ function applyTopLevelPatch(global, source) {
1252
+ if (hasOwn(source, "goalStorageLocation")) {
1253
+ if (source.goalStorageLocation === "global" || source.goalStorageLocation === "workspace") {
1254
+ global.goalStorageLocation = source.goalStorageLocation;
1255
+ } else if (source.goalStorageLocation === null) {
1256
+ delete global.goalStorageLocation;
1257
+ }
1258
+ }
1259
+ if (hasOwn(source, "lspEnabled")) {
1260
+ if (typeof source.lspEnabled === "boolean") {
1261
+ global.lspEnabled = source.lspEnabled;
1262
+ } else if (source.lspEnabled === null) {
1263
+ delete global.lspEnabled;
1264
+ }
1265
+ }
1266
+ if (hasOwn(source, "executionMode")) {
1267
+ if (source.executionMode === "local" || source.executionMode === "hosted") {
1268
+ global.executionMode = source.executionMode;
1269
+ } else if (source.executionMode === null) {
1270
+ delete global.executionMode;
1271
+ }
1272
+ }
1273
+ if (hasOwn(source, "mode")) {
1274
+ if (source.mode === "general" || source.mode === "builder") {
1275
+ global.mode = source.mode;
1276
+ } else if (source.mode === null) {
1277
+ delete global.mode;
1278
+ }
1279
+ }
1280
+ if (hasOwn(source, "activeProfile")) {
1281
+ const selector = sanitizeActiveProfile(source.activeProfile);
1282
+ if (selector) {
1283
+ const idx = findAccountIndexForSelector(global.accounts ?? [], selector);
1284
+ global.activeProfile = idx === -1 ? selector : selectorFromAccount((global.accounts ?? [])[idx]);
1285
+ } else if (source.activeProfile === null) {
1286
+ delete global.activeProfile;
1287
+ }
1288
+ }
1289
+ if (hasOwn(source, "openpondProfile")) {
1290
+ const profile = sanitizeLocalOpenPondProfile(source.openpondProfile);
1291
+ if (profile) {
1292
+ global.openpondProfile = profile;
1293
+ } else if (source.openpondProfile === null) {
1294
+ delete global.openpondProfile;
1295
+ }
1296
+ }
1297
+ }
1298
+ async function updateGlobalConfig(update) {
1299
+ try {
1300
+ return await updatePrivateJsonFile(getGlobalConfigPath(), () => ({}), (raw) => {
1301
+ const current = normalizeGlobalConfig(raw);
1302
+ update(current);
1303
+ return current;
1304
+ });
1305
+ } catch (error) {
1306
+ if (error instanceof SyntaxError) {
1307
+ throw new Error(`OpenPond config is malformed JSON: ${getGlobalConfigPath()}`, { cause: error });
1308
+ }
1309
+ throw error;
1310
+ }
1311
+ }
1312
+ async function loadGlobalConfig() {
1313
+ const raw = await loadConfigFile(getGlobalConfigPath());
1314
+ return normalizeGlobalConfig(raw);
1315
+ }
1316
+ async function loadConfig(options = {}) {
1317
+ const global = await loadGlobalConfig();
1318
+ const accounts = global.accounts ?? [];
1319
+ const requested = resolveRequestedProfile(
1320
+ global,
1321
+ options.account,
1322
+ options.baseUrl
1323
+ );
1324
+ const idx = findAccountIndexForSelector(accounts, requested, {
1325
+ requireUnambiguous: true
1326
+ });
1327
+ const account = idx === -1 ? null : accounts[idx];
1328
+ const session = account?.session;
1329
+ return {
1330
+ ...global,
1331
+ activeProfile: account ? selectorFromAccount(account) : requested,
1332
+ apiKey: account?.apiKey,
1333
+ baseUrl: account?.baseUrl,
1334
+ apiBaseUrl: account?.apiBaseUrl,
1335
+ chatApiBaseUrl: account?.chatApiBaseUrl,
1336
+ token: session?.token,
1337
+ appId: session?.appId,
1338
+ conversationId: session?.conversationId
1339
+ };
1340
+ }
1341
+ async function listConfiguredProfiles() {
1342
+ const global = await loadGlobalConfig();
1343
+ const activeProfile = sanitizeActiveProfile(global.activeProfile);
1344
+ return (global.accounts ?? []).map((account) => {
1345
+ const handle = normalizeHandle(account.handle) ?? DEFAULT_ACCOUNT_HANDLE;
1346
+ return {
1347
+ handle,
1348
+ baseUrl: normalizeBaseUrl(account.baseUrl),
1349
+ apiBaseUrl: normalizeBaseUrl(account.apiBaseUrl),
1350
+ chatApiBaseUrl: normalizeBaseUrl(account.chatApiBaseUrl),
1351
+ environment: account.environment?.trim() || null,
1352
+ isActive: Boolean(
1353
+ activeProfile && accountMatchesSelector({ ...account, handle }, activeProfile)
1354
+ ),
1355
+ hasApiKey: Boolean(account.apiKey?.trim()),
1356
+ hasSessionToken: Boolean(account.session?.token?.trim()),
1357
+ sessionAppId: account.session?.appId ?? null,
1358
+ sessionConversationId: account.session?.conversationId ?? null
1359
+ };
1360
+ });
1361
+ }
1362
+ async function setActiveProfile(handle, options = {}) {
1363
+ const requestedHandle = requireHandle(handle);
1364
+ const requestedBaseUrl = normalizeBaseUrl(options.baseUrl);
1365
+ let selectedIndex = -1;
1366
+ await updateGlobalConfig((global) => {
1367
+ const accounts = global.accounts ?? [];
1368
+ selectedIndex = findAccountIndexForSelector(
1369
+ accounts,
1370
+ requestedBaseUrl ? { handle: requestedHandle, baseUrl: requestedBaseUrl } : { handle: requestedHandle },
1371
+ { requireUnambiguous: true }
1372
+ );
1373
+ if (selectedIndex === -1) throw new Error(`profile not found: ${requestedHandle}`);
1374
+ global.activeProfile = selectorFromAccount(accounts[selectedIndex]);
1375
+ });
1376
+ const profiles = await listConfiguredProfiles();
1377
+ return profiles.find((profile) => profile.isActive) ?? profiles[selectedIndex];
1378
+ }
1379
+ async function saveProfileApiKey(input3) {
1380
+ const handle = requireHandle(input3.handle);
1381
+ const apiKey = requireApiKey(input3.apiKey);
1382
+ const baseUrl = normalizeBaseUrl(input3.baseUrl);
1383
+ const apiBaseUrl = normalizeBaseUrl(input3.apiBaseUrl);
1384
+ const chatApiBaseUrl = normalizeBaseUrl(input3.chatApiBaseUrl);
1385
+ let savedSelector = { handle };
1386
+ await updateGlobalConfig((global) => {
1387
+ const accounts = global.accounts ?? [];
1388
+ const account = ensureAccount(accounts, handle, baseUrl);
1389
+ account.apiKey = apiKey;
1390
+ if (baseUrl) account.baseUrl = baseUrl;
1391
+ if (apiBaseUrl) account.apiBaseUrl = apiBaseUrl;
1392
+ else if (input3.apiBaseUrl === null) delete account.apiBaseUrl;
1393
+ if (chatApiBaseUrl) account.chatApiBaseUrl = chatApiBaseUrl;
1394
+ else if (input3.chatApiBaseUrl === null) delete account.chatApiBaseUrl;
1395
+ if (input3.environment === null) delete account.environment;
1396
+ else if (typeof input3.environment === "string" && input3.environment.trim()) {
1397
+ account.environment = input3.environment.trim();
1398
+ }
1399
+ global.accounts = accounts;
1400
+ savedSelector = selectorFromAccount(account);
1401
+ if (input3.setActive !== false) global.activeProfile = savedSelector;
1402
+ });
1403
+ const profiles = await listConfiguredProfiles();
1404
+ const saved = profiles.find((profile) => {
1405
+ if (!handleEquals(profile.handle, savedSelector.handle)) return false;
1406
+ if (!baseUrl) return true;
1407
+ return normalizeBaseUrl(profile.baseUrl) === baseUrl;
1408
+ });
1409
+ if (!saved) {
1410
+ throw new Error(`failed to save profile: ${handle}`);
1411
+ }
1412
+ return saved;
1413
+ }
1414
+ async function saveGlobalConfig(next) {
1415
+ await updateGlobalConfig((current) => {
1416
+ applyTopLevelPatch(current, next);
1417
+ applyAccountPatch(current, next, { undefinedDeletes: false });
1418
+ });
1419
+ }
1420
+
1421
+ // src/cli/common/auth.ts
1422
+ import { stdin as input, stdout as output } from "node:process";
1423
+ import { createInterface } from "node:readline/promises";
1424
+ var UI_API_KEY_URL = `${DEFAULT_OPENPOND_WEB_BASE_URL}/settings/api-keys`;
1425
+ function resolveApiKey(config) {
1426
+ const envKey = process.env.OPENPOND_API_KEY?.trim();
1427
+ if (envKey) return envKey;
1428
+ const stored = config.apiKey?.trim();
1429
+ if (stored) return stored;
1430
+ const legacy = config.token?.trim();
1431
+ if (legacy && legacy.startsWith("opk_")) return legacy;
1432
+ return null;
1433
+ }
1434
+ async function promptForApiKey() {
1435
+ if (!input.isTTY || !output.isTTY) {
1436
+ throw new Error(
1437
+ "OpenPond API key is required in non-interactive mode. Set OPENPOND_API_KEY or run `openpond login` in a terminal."
1438
+ );
1439
+ }
1440
+ console.log("Open the OpenPond UI to create an API key:");
1441
+ console.log(UI_API_KEY_URL);
1442
+ const rl = createInterface({ input, output });
1443
+ try {
1444
+ const value = (await rl.question("Paste your OpenPond API key: ")).trim();
1445
+ if (!value) {
1446
+ throw new Error("API key is required");
1447
+ }
1448
+ if (!value.startsWith("opk_")) {
1449
+ console.log("warning: API keys usually start with opk_.");
1450
+ }
1451
+ return value;
1452
+ } finally {
1453
+ rl.close();
1454
+ }
1455
+ }
1456
+ async function ensureApiKey(config, baseUrl) {
1457
+ const existing = resolveApiKey(config);
1458
+ if (existing) return existing;
1459
+ const apiKey = await promptForApiKey();
1460
+ await saveGlobalConfig({
1461
+ apiKey,
1462
+ baseUrl,
1463
+ activeProfile: config.activeProfile
1464
+ });
1465
+ console.log("saved api key to ~/.openpond/config.json");
1466
+ return apiKey;
1467
+ }
1468
+
1469
+ // src/cli/common/repo-format.ts
1470
+ function resolveRepoUrl(response) {
1471
+ if (response.repoUrl) return response.repoUrl;
1472
+ if (response.gitHost && response.gitOwner && response.gitRepo) {
1473
+ return `https://${response.gitHost}/${response.gitOwner}/${response.gitRepo}.git`;
1474
+ }
1475
+ throw new Error("repoUrl missing from API response");
1476
+ }
1477
+ function formatTokenizedRepoUrl(repoUrl, token) {
1478
+ const url = new URL(repoUrl);
1479
+ const encodedToken = encodeURIComponent(token);
1480
+ return `${url.protocol}//x-access-token:${encodedToken}@${url.host}${url.pathname}`;
1481
+ }
1482
+ function formatTokenizedRepoUrlForPrint(repoUrl) {
1483
+ const url = new URL(repoUrl);
1484
+ return `${url.protocol}//x-access-token:$OPENPOND_API_KEY@${url.host}${url.pathname}`;
1485
+ }
1486
+ function redactToken(value) {
1487
+ return value.replace(/x-access-token:[^@]+@/g, "x-access-token:***@");
1488
+ }
1489
+ function warnOnRepoHostMismatch(repoUrl) {
1490
+ const envBase = process.env.OPENPOND_BASE_URL;
1491
+ if (!envBase) return;
1492
+ try {
1493
+ const baseHost = new URL(envBase).hostname;
1494
+ const repoHost = new URL(repoUrl).hostname;
1495
+ if (baseHost && repoHost && baseHost !== repoHost) {
1496
+ console.warn(
1497
+ `warning: repo host (${repoHost}) does not match OPENPOND_BASE_URL (${baseHost})`
1498
+ );
1499
+ console.warn(
1500
+ "warning: verify your git host configuration matches OPENPOND_BASE_URL."
1501
+ );
1502
+ }
1503
+ } catch {
1504
+ }
1505
+ }
1506
+ function parseHandleRepo(value) {
1507
+ const parts = value.split("/").filter(Boolean);
1508
+ if (parts.length !== 2) {
1509
+ throw new Error("expected <handle>/<repo>");
1510
+ }
1511
+ return { handle: parts[0], repo: parts[1] };
1512
+ }
1513
+ function normalizeRepoName(value) {
1514
+ return (value || "").trim().toLowerCase();
1515
+ }
1516
+
1517
+ // ../../packages/cloud/src/cache.ts
1518
+ import { promises as fs3 } from "node:fs";
1519
+ import { createHash } from "node:crypto";
1520
+ import path3 from "node:path";
1521
+ var CACHE_FILENAME = "cache.json";
1522
+ var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1e3;
1523
+ function getCachePath() {
1524
+ return path3.join(openPondConfigDirectory(), CACHE_FILENAME);
1525
+ }
1526
+ function buildCacheKey(apiBase, apiKey) {
1527
+ const credentialHash = createHash("sha256").update(apiKey.trim()).digest("hex");
1528
+ try {
1529
+ const host = new URL(apiBase).host;
1530
+ return `${host}:${credentialHash}`;
1531
+ } catch {
1532
+ return `${apiBase}:${credentialHash}`;
1533
+ }
1534
+ }
1535
+ function isFresh(updatedAt, ttlMs) {
1536
+ const timestamp = Date.parse(updatedAt);
1537
+ if (Number.isNaN(timestamp)) {
1538
+ return false;
1539
+ }
1540
+ return Date.now() - timestamp < ttlMs;
1541
+ }
1542
+ async function loadCache() {
1543
+ try {
1544
+ const raw = await fs3.readFile(getCachePath(), "utf-8");
1545
+ const parsed = JSON.parse(raw);
1546
+ if (!parsed || typeof parsed !== "object" || !parsed.byKey) {
1547
+ return emptyCacheStore();
1548
+ }
1549
+ return parsed;
1550
+ } catch {
1551
+ return emptyCacheStore();
1552
+ }
1553
+ }
1554
+ function emptyCacheStore() {
1555
+ return { version: 1, byKey: {} };
1556
+ }
1557
+ async function getCachedApps(params) {
1558
+ const ttlMs = params.ttlMs ?? DEFAULT_CACHE_TTL_MS;
1559
+ const store = await loadCache();
1560
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1561
+ const entry = store.byKey[cacheKey]?.apps;
1562
+ if (!entry || !isFresh(entry.updatedAt, ttlMs)) {
1563
+ return null;
1564
+ }
1565
+ return Array.isArray(entry.items) ? entry.items : null;
1566
+ }
1567
+ async function setCachedApps(params) {
1568
+ await mutateCache((store) => {
1569
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1570
+ const bucket = store.byKey[cacheKey] || {};
1571
+ bucket.apps = {
1572
+ items: params.apps,
1573
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1574
+ };
1575
+ store.byKey[cacheKey] = bucket;
1576
+ });
1577
+ }
1578
+ async function getCachedTools(params) {
1579
+ const ttlMs = params.ttlMs ?? DEFAULT_CACHE_TTL_MS;
1580
+ const store = await loadCache();
1581
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1582
+ const entry = store.byKey[cacheKey]?.tools;
1583
+ if (!entry || !isFresh(entry.updatedAt, ttlMs)) {
1584
+ return null;
1585
+ }
1586
+ return Array.isArray(entry.items) ? entry.items : null;
1587
+ }
1588
+ async function setCachedTools(params) {
1589
+ await mutateCache((store) => {
1590
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1591
+ const bucket = store.byKey[cacheKey] || {};
1592
+ bucket.tools = {
1593
+ items: params.tools,
1594
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1595
+ };
1596
+ store.byKey[cacheKey] = bucket;
1597
+ });
1598
+ }
1599
+ async function mutateCache(mutate) {
1600
+ await updatePrivateJsonFile(getCachePath(), emptyCacheStore, (raw) => {
1601
+ const store = raw && typeof raw === "object" && raw.byKey ? raw : emptyCacheStore();
1602
+ mutate(store);
1603
+ return store;
1604
+ });
1605
+ }
1606
+
1607
+ // src/cli/common/cache.ts
1608
+ async function fetchAppsWithCache(params) {
1609
+ if (!params.forceRefresh) {
1610
+ const cached = await getCachedApps({
1611
+ apiBase: params.apiBase,
1612
+ apiKey: params.apiKey,
1613
+ ttlMs: DEFAULT_CACHE_TTL_MS
1614
+ });
1615
+ if (cached) {
1616
+ return cached;
1617
+ }
1618
+ }
1619
+ const apps = await listApps(params.apiBase, params.apiKey);
1620
+ await setCachedApps({
1621
+ apiBase: params.apiBase,
1622
+ apiKey: params.apiKey,
1623
+ apps
1624
+ });
1625
+ return apps;
1626
+ }
1627
+ async function fetchToolsWithCache(params) {
1628
+ if (!params.forceRefresh) {
1629
+ const cached = await getCachedTools({
1630
+ apiBase: params.apiBase,
1631
+ apiKey: params.apiKey,
1632
+ ttlMs: DEFAULT_CACHE_TTL_MS
1633
+ });
1634
+ if (cached) {
1635
+ return cached;
1636
+ }
1637
+ }
1638
+ const result = await listUserTools(params.apiBase, params.apiKey);
1639
+ const tools = Array.isArray(result.tools) ? result.tools : [];
1640
+ await setCachedTools({
1641
+ apiBase: params.apiBase,
1642
+ apiKey: params.apiKey,
1643
+ tools
1644
+ });
1645
+ return tools;
1646
+ }
1647
+ async function resolveAppTarget(apiBase, apiKey, target) {
1648
+ const { handle, repo } = parseHandleRepo(target);
1649
+ const apps = await fetchAppsWithCache({ apiBase, apiKey });
1650
+ const normalizedRepo = normalizeRepoName(repo);
1651
+ const match = apps.find((app) => {
1652
+ if (app.handle && app.handle !== handle) {
1653
+ return false;
1654
+ }
1655
+ const candidates = [app.repo, app.gitRepo, app.id].map(normalizeRepoName);
1656
+ return candidates.includes(normalizedRepo);
1657
+ });
1658
+ if (!match) {
1659
+ throw new Error(`app not found for ${handle}/${repo}`);
1660
+ }
1661
+ return { app: match, handle, repo };
1662
+ }
1663
+ async function pollDeploymentLogs(params) {
1664
+ const intervalMs = params.intervalMs ?? 5e3;
1665
+ const timeoutMs = params.timeoutMs ?? 4 * 60 * 1e3;
1666
+ const seen = /* @__PURE__ */ new Set();
1667
+ const startedAt = Date.now();
1668
+ while (Date.now() - startedAt < timeoutMs) {
1669
+ const logs = await getDeploymentLogs(
1670
+ params.baseUrl,
1671
+ params.apiKey,
1672
+ params.deploymentId
1673
+ );
1674
+ const newLogs = logs.filter((log) => !seen.has(log.id));
1675
+ for (const log of newLogs) {
1676
+ seen.add(log.id);
1677
+ }
1678
+ for (const log of newLogs) {
1679
+ console.log(`${params.prefix}${log.message}`);
1680
+ }
1681
+ const status = await getDeploymentStatus(
1682
+ params.baseUrl,
1683
+ params.apiKey,
1684
+ params.deploymentId
1685
+ );
1686
+ if (status.status === "failed") {
1687
+ console.log(`${params.prefix}deployment failed`);
1688
+ return;
1689
+ }
1690
+ if (status.status === "running" || status.status === "deployed") {
1691
+ console.log(`${params.prefix}deployment complete`);
1692
+ return;
1693
+ }
1694
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
1695
+ }
1696
+ console.log(`${params.prefix}deployment still in progress`);
1697
+ }
1698
+
1699
+ // src/cli/common/prompts.ts
1700
+ import { stdin as input2, stdout as output2 } from "node:process";
1701
+ import { createInterface as createInterface2 } from "node:readline/promises";
1702
+ async function readAllStdin() {
1703
+ const chunks = [];
1704
+ for await (const chunk of process.stdin) {
1705
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
1706
+ }
1707
+ return Buffer.concat(chunks).toString("utf8").replace(/\r?\n$/, "");
1708
+ }
1709
+ function readMaskedLine(prompt) {
1710
+ return new Promise((resolve, reject) => {
1711
+ const stdin = process.stdin;
1712
+ const stderr = process.stderr;
1713
+ let value = "";
1714
+ const wasRaw = stdin.isRaw;
1715
+ function cleanup() {
1716
+ stdin.off("data", onData);
1717
+ if (stdin.setRawMode) stdin.setRawMode(wasRaw);
1718
+ stdin.pause();
1719
+ stderr.write("\n");
1720
+ }
1721
+ function onData(chunk) {
1722
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
1723
+ for (const byte of buffer) {
1724
+ if (byte === 3) {
1725
+ cleanup();
1726
+ reject(new Error("secret prompt cancelled"));
1727
+ return;
1728
+ }
1729
+ if (byte === 13 || byte === 10) {
1730
+ cleanup();
1731
+ resolve(value);
1732
+ return;
1733
+ }
1734
+ if (byte === 127 || byte === 8) {
1735
+ if (value.length > 0) {
1736
+ value = value.slice(0, -1);
1737
+ stderr.write("\b \b");
1738
+ }
1739
+ continue;
1740
+ }
1741
+ value += Buffer.from([byte]).toString("utf8");
1742
+ stderr.write("*");
1743
+ }
1744
+ }
1745
+ stderr.write(prompt);
1746
+ stdin.resume();
1747
+ if (stdin.setRawMode) stdin.setRawMode(true);
1748
+ stdin.on("data", onData);
1749
+ });
1750
+ }
1751
+ async function promptConfirm(question, defaultValue = false) {
1752
+ const rl = createInterface2({ input: input2, output: output2 });
1753
+ try {
1754
+ const suffix = defaultValue ? "[Y/n]" : "[y/N]";
1755
+ const answer = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();
1756
+ if (!answer) return defaultValue;
1757
+ return answer === "y" || answer === "yes";
1758
+ } finally {
1759
+ rl.close();
1760
+ }
1761
+ }
1762
+ async function promptForPath(defaultPath) {
1763
+ const rl = createInterface2({ input: input2, output: output2 });
1764
+ try {
1765
+ const answer = (await rl.question(`Local path (default: ${defaultPath}): `)).trim();
1766
+ return answer || defaultPath;
1767
+ } finally {
1768
+ rl.close();
1769
+ }
1770
+ }
1771
+
1772
+ // ../../packages/cloud/src/sandbox/client-handles.ts
1773
+ function createSandboxRuntimeNamespace(client) {
1774
+ return {
1775
+ list: (input3 = {}) => client.listSandboxRuntimes(input3),
1776
+ create: (input3) => client.createSandboxRuntime(input3),
1777
+ handle: (runtimeId, initial = null) => client.sandboxRuntime(runtimeId, initial),
1778
+ get: (runtimeId) => client.getSandboxRuntime(runtimeId),
1779
+ createSandbox: (runtimeId, input3 = {}, options = {}) => client.createSandboxRuntimeSandbox(runtimeId, input3, options),
1780
+ updateStatus: (runtimeId, input3) => client.updateSandboxRuntimeStatus(runtimeId, input3),
1781
+ events: (runtimeId) => client.listSandboxRuntimeEvents(runtimeId),
1782
+ event: (runtimeId, input3) => client.emitSandboxRuntimeEvent(runtimeId, input3),
1783
+ checkpoint: (runtimeId, input3 = {}) => client.checkpointSandboxRuntime(runtimeId, input3),
1784
+ promote: (runtimeId, input3, options = {}) => client.promoteSandboxRuntime(runtimeId, input3, options),
1785
+ preserveSource: (runtimeId, input3 = {}, options = {}) => client.preserveSandboxRuntimeSource(runtimeId, input3, options)
1786
+ };
1787
+ }
1788
+ function createSandboxNamespace(client) {
1789
+ return {
1790
+ list: (input3 = {}) => client.list(input3),
1791
+ create: (input3) => client.create(input3),
1792
+ get: (sandboxId) => client.get(sandboxId),
1793
+ pricing: () => client.pricing(),
1794
+ costs: (input3 = {}) => client.costs(input3)
1795
+ };
1796
+ }
1797
+ function createSandboxProjectNamespace(client) {
1798
+ return {
1799
+ list: (input3) => client.listProjects(input3),
1800
+ upsert: (input3) => client.upsertProject(input3),
1801
+ upsertGitRemote: (input3) => client.upsertProjectGitRemote(input3),
1802
+ get: (projectId, input3) => client.getProject(projectId, input3),
1803
+ update: (projectId, input3) => client.updateProject(projectId, input3),
1804
+ sync: (projectId, input3) => client.syncProject(projectId, input3),
1805
+ ensureGitRemote: (projectId, input3) => client.ensureProjectGitRemote(projectId, input3),
1806
+ getGitRemote: (projectId, input3) => client.ensureProjectGitRemote(projectId, input3),
1807
+ git: (projectId, input3) => client.ensureProjectGitRemote(projectId, input3),
1808
+ uploadSource: (projectId, input3) => client.uploadProjectSource(projectId, input3),
1809
+ archive: (projectId, input3) => client.archiveProject(projectId, input3)
1810
+ };
1811
+ }
1812
+ function createSandboxProfileNamespace(client) {
1813
+ return {
1814
+ get: (input3) => client.getHostedProfile(input3),
1815
+ status: (input3) => client.getHostedProfile(input3),
1816
+ ensureHosted: (input3) => client.ensureHostedProfile(input3),
1817
+ push: (input3) => client.pushHostedProfile(input3)
1818
+ };
1819
+ }
1820
+ function createSandboxAgentNamespace(client) {
1821
+ return {
1822
+ list: (input3) => client.listAgents(input3),
1823
+ upsert: (input3) => client.upsertAgent(input3),
1824
+ get: (agentId, input3) => client.getAgent(agentId, input3),
1825
+ update: (agentId, input3) => client.updateAgent(agentId, input3),
1826
+ archive: (agentId, input3) => client.archiveAgent(agentId, input3),
1827
+ run: (agentId, input3) => client.runAgent(agentId, input3),
1828
+ sourceDeployPlan: (agentId, input3) => client.getAgentSourceDeployPlan(agentId, input3),
1829
+ manifestSnapshots: (agentId, input3) => client.listAgentManifestSnapshots(agentId, input3),
1830
+ requestSourceChecks: (agentId, input3) => client.requestAgentSourceChecks(agentId, input3),
1831
+ publishSource: (agentId, input3) => client.publishAgentSource(agentId, input3),
1832
+ openEditWorkItem: (agentId, input3) => client.openAgentEditWorkItem(agentId, input3)
1833
+ };
1834
+ }
1835
+ function createSandboxWorkItemNamespace(client) {
1836
+ return {
1837
+ get: (workItemId, input3) => client.getCodingWorkItem(workItemId, input3),
1838
+ chat: (workItemId, input3) => client.sendCodingWorkItemChat(workItemId, input3),
1839
+ activity: (workItemId, input3) => client.listCodingWorkItemActivity(workItemId, input3),
1840
+ status: (workItemId, input3) => client.getCodingWorkItemStatus(workItemId, input3),
1841
+ handleBackground: (workItemId, input3) => client.handleCodingWorkItemInBackground(workItemId, input3),
1842
+ promoteCheckpoint: (workItemId, input3) => client.promoteCodingWorkItemResult(workItemId, "checkpoint", input3),
1843
+ promoteCommit: (workItemId, input3) => client.promoteCodingWorkItemResult(workItemId, "commit", input3),
1844
+ promotePullRequest: (workItemId, input3) => client.promoteCodingWorkItemResult(workItemId, "pr", input3)
1845
+ };
1846
+ }
1847
+
1848
+ // ../../packages/cloud/src/sandbox/runtime-handle.ts
1849
+ function createSandboxRuntimeHandle(client, runtimeId, initial = null) {
1850
+ const currentSandbox = async (input3 = {}, options = {}) => {
1851
+ const runtime = await client.getSandboxRuntime(runtimeId);
1852
+ if (runtime.sandboxId) {
1853
+ return client.get(runtime.sandboxId);
1854
+ }
1855
+ return client.createSandboxRuntimeSandbox(runtimeId, input3, options).then((payload) => payload.sandbox);
1856
+ };
1857
+ const resume = async (input3 = {}, options = {}) => {
1858
+ const runtime = await client.getSandboxRuntime(runtimeId);
1859
+ if (!runtime.sandboxId) {
1860
+ return client.createSandboxRuntimeSandbox(runtimeId, input3, options).then((payload) => payload.sandbox);
1861
+ }
1862
+ const sandbox = await client.get(runtime.sandboxId);
1863
+ if (sandbox.state === "stopped") {
1864
+ return client.start(sandbox.id, options).then((payload) => payload.sandbox);
1865
+ }
1866
+ if (sandbox.state === "archived") {
1867
+ return client.restore(sandbox.id).then((payload) => payload.sandbox);
1868
+ }
1869
+ if (sandbox.state === "deleted" || sandbox.state === "error") {
1870
+ return client.createSandboxRuntimeSandbox(runtimeId, input3, options).then((payload) => payload.sandbox);
1871
+ }
1872
+ return sandbox;
1873
+ };
1874
+ const checkpointHint = (input3 = {}) => client.emitSandboxRuntimeEvent(runtimeId, {
1875
+ type: "workflow.checkpoint_hint",
1876
+ summary: input3.summary ?? input3.reason ?? "Workflow checkpoint hint",
1877
+ payload: {
1878
+ ...input3.payload,
1879
+ reason: input3.reason ?? null
1880
+ },
1881
+ artifactRefs: input3.artifactRefs,
1882
+ lifecycleHint: {
1883
+ kind: "checkpoint",
1884
+ reason: input3.reason ?? null
1885
+ }
1886
+ });
1887
+ const waitForUser = async (input3 = {}) => {
1888
+ await client.emitSandboxRuntimeEvent(runtimeId, {
1889
+ type: "workflow.waiting_for_user",
1890
+ summary: input3.summary ?? input3.reason ?? "Waiting for user",
1891
+ payload: {
1892
+ ...input3.payload,
1893
+ reason: input3.reason ?? null
1894
+ },
1895
+ lifecycleHint: {
1896
+ kind: "waiting_for_user",
1897
+ reason: input3.reason ?? null
1898
+ }
1899
+ });
1900
+ const current = await client.getSandboxRuntime(runtimeId);
1901
+ if (current.status === "waiting_for_user") return current;
1902
+ return client.updateSandboxRuntimeStatus(runtimeId, {
1903
+ status: "waiting_for_user",
1904
+ expectedVersion: current.version,
1905
+ summary: input3.summary ?? input3.reason,
1906
+ metadata: {
1907
+ workflowWaitForUserReason: input3.reason ?? null
1908
+ }
1909
+ });
1910
+ };
1911
+ const keepAlive = (input3 = {}) => {
1912
+ const keepaliveUntil = runtimeKeepaliveUntilIso(input3);
1913
+ return client.emitSandboxRuntimeEvent(runtimeId, {
1914
+ type: "workflow.keepalive",
1915
+ summary: input3.summary ?? input3.reason ?? "Workflow keepalive",
1916
+ payload: {
1917
+ ...input3.payload,
1918
+ reason: input3.reason ?? null,
1919
+ keepaliveUntil
1920
+ },
1921
+ lifecycleHint: {
1922
+ kind: "keepalive",
1923
+ reason: input3.reason ?? null,
1924
+ keepaliveUntil
1925
+ }
1926
+ });
1927
+ };
1928
+ return {
1929
+ id: runtimeId,
1930
+ initial,
1931
+ get: () => client.getSandboxRuntime(runtimeId),
1932
+ sandbox: currentSandbox,
1933
+ resume,
1934
+ createSandbox: (input3 = {}, options = {}) => client.createSandboxRuntimeSandbox(runtimeId, input3, options),
1935
+ status: async (input3) => {
1936
+ if (typeof input3 !== "string") {
1937
+ return client.updateSandboxRuntimeStatus(runtimeId, input3);
1938
+ }
1939
+ const current = await client.getSandboxRuntime(runtimeId);
1940
+ return client.updateSandboxRuntimeStatus(runtimeId, {
1941
+ status: input3,
1942
+ expectedVersion: current.version
1943
+ });
1944
+ },
1945
+ events: () => client.listSandboxRuntimeEvents(runtimeId),
1946
+ event: (input3) => client.emitSandboxRuntimeEvent(runtimeId, input3),
1947
+ recordCommit: (commitSha, input3 = {}) => client.emitSandboxRuntimeEvent(runtimeId, {
1948
+ ...input3,
1949
+ type: input3.type ?? "git.commit",
1950
+ commitSha
1951
+ }),
1952
+ checkpointHint,
1953
+ waitForUser,
1954
+ keepAlive,
1955
+ checkpoint: (input3) => client.checkpointSandboxRuntime(runtimeId, input3),
1956
+ files: {
1957
+ write: async (path4, contents) => client.uploadFile((await resume()).id, path4, contents),
1958
+ read: async (path4) => client.downloadFile((await resume()).id, path4),
1959
+ readResponse: async (input3) => client.downloadFileResponse((await resume()).id, input3),
1960
+ list: async (input3 = {}) => client.listFiles((await resume()).id, input3),
1961
+ delete: async (path4, input3 = {}) => client.deleteFile((await resume()).id, path4, input3),
1962
+ search: async (input3) => client.searchFiles((await resume()).id, input3),
1963
+ stat: async (path4) => client.statFile((await resume()).id, path4),
1964
+ mkdir: async (input3) => client.mkdir((await resume()).id, input3),
1965
+ move: async (input3) => client.moveFile((await resume()).id, input3)
1966
+ },
1967
+ commands: {
1968
+ run: async (command) => client.exec(
1969
+ (await resume()).id,
1970
+ typeof command === "string" ? { command } : command
1971
+ )
1972
+ },
1973
+ ports: {
1974
+ expose: async (port) => client.openPort(
1975
+ (await resume()).id,
1976
+ typeof port === "number" ? { port } : port
1977
+ )
1978
+ },
1979
+ promote: (input3, options = {}) => client.promoteSandboxRuntime(runtimeId, input3, options),
1980
+ preserveSource: (input3 = {}, options = {}) => client.preserveSandboxRuntimeSource(runtimeId, input3, options),
1981
+ archive: async (expectedVersion) => {
1982
+ const version = expectedVersion ?? (await client.getSandboxRuntime(runtimeId)).version;
1983
+ return client.updateSandboxRuntimeStatus(runtimeId, {
1984
+ status: "archived",
1985
+ expectedVersion: version
1986
+ });
1987
+ }
1988
+ };
1989
+ }
1990
+ function runtimeKeepaliveUntilIso(input3) {
1991
+ if (input3?.until instanceof Date) {
1992
+ return input3.until.toISOString();
1993
+ }
1994
+ if (typeof input3?.until === "string" && input3.until.trim()) {
1995
+ return new Date(input3.until).toISOString();
1996
+ }
1997
+ const seconds = typeof input3?.seconds === "number" && Number.isFinite(input3.seconds) ? Math.max(1, Math.trunc(input3.seconds)) : 60;
1998
+ return new Date(Date.now() + seconds * 1e3).toISOString();
1999
+ }
2000
+
2001
+ // ../../packages/cloud/src/sandbox/smoke.ts
2002
+ async function runSandboxSmoke(client, options = {}) {
2003
+ const runId = `openpond-code-smoke-${Date.now()}`;
2004
+ const expectedExec = `openpond-code-exec-ok:${runId}`;
2005
+ const expectedPreview = `openpond-code-preview-ok:${runId}`;
2006
+ const expectedFile = `openpond-code-file-ok:${runId}`;
2007
+ const previewPort = 4173;
2008
+ let sandboxId = null;
2009
+ let forkSandboxId = null;
2010
+ let deleted = false;
2011
+ let forkDeleted = false;
2012
+ try {
2013
+ const sandbox = await waitForCreateReady(
2014
+ client,
2015
+ await client.create(
2016
+ {
2017
+ repo: options.repo ?? "https://github.com/octocat/Hello-World",
2018
+ resources: {
2019
+ cpu: options.cpu ?? 1,
2020
+ memoryGb: options.memoryGb ?? 1,
2021
+ diskGb: options.diskGb ?? 8
2022
+ },
2023
+ budget: { maxUsd: options.budgetUsd ?? "0.05" },
2024
+ quotas: {
2025
+ maxSpendUsd: options.budgetUsd ?? "0.05",
2026
+ maxDurationSeconds: 600,
2027
+ idleTimeoutSeconds: 600,
2028
+ maxOpenPorts: 2
2029
+ },
2030
+ metadata: {
2031
+ runId,
2032
+ source: "openpond-code-sandbox-smoke"
2033
+ }
2034
+ },
2035
+ { async: true }
2036
+ )
2037
+ );
2038
+ sandboxId = sandbox.id;
2039
+ const expectedRuntimeDriver = options.expectedRuntimeDriver ?? "remote-firecracker";
2040
+ if (sandbox.runtimeDriver !== expectedRuntimeDriver) {
2041
+ throw new Error(
2042
+ `expected ${expectedRuntimeDriver}, got ${sandbox.runtimeDriver}`
2043
+ );
2044
+ }
2045
+ const expectedMppMode = options.expectedMppMode;
2046
+ if (expectedMppMode && sandbox.reservation.mpp?.mode !== expectedMppMode) {
2047
+ throw new Error(
2048
+ `expected ${expectedMppMode} reservation, got ${sandbox.reservation.mpp?.mode ?? "none"}`
2049
+ );
2050
+ }
2051
+ if (!expectedMppMode && !sandbox.reservation.mpp?.mode) {
2052
+ throw new Error("expected sandbox reservation MPP metadata");
2053
+ }
2054
+ const exec = await client.exec(sandbox.id, {
2055
+ command: [
2056
+ `printf '${expectedExec}\\n'`,
2057
+ "test -f README && printf 'repo-clone-ok\\n'",
2058
+ "cat > server.cjs <<'EOF'",
2059
+ "const { createServer } = require('node:http');",
2060
+ `createServer((_request, response) => response.end('${expectedPreview}')).listen(${previewPort}, '0.0.0.0');`,
2061
+ "EOF",
2062
+ "nohup node server.cjs > server.log 2>&1 & sleep 1"
2063
+ ].join("\n"),
2064
+ timeoutSeconds: 120
2065
+ });
2066
+ if (exec.command.status !== "succeeded") {
2067
+ throw new Error(`expected command success, got ${exec.command.status}`);
2068
+ }
2069
+ if (!exec.command.output.includes(expectedExec)) {
2070
+ throw new Error("expected exec marker");
2071
+ }
2072
+ await client.uploadFile(
2073
+ sandbox.id,
2074
+ "openpond-code-smoke.txt",
2075
+ expectedFile
2076
+ );
2077
+ const downloaded = await client.downloadFile(
2078
+ sandbox.id,
2079
+ "openpond-code-smoke.txt"
2080
+ );
2081
+ if (downloaded !== expectedFile) {
2082
+ throw new Error("expected file roundtrip marker");
2083
+ }
2084
+ let snapshotId = null;
2085
+ if (options.snapshot || options.fork) {
2086
+ const snapshotResponse = await client.createSnapshot(sandbox.id, {
2087
+ async: true,
2088
+ name: `openpond-code-smoke-${runId}`,
2089
+ replay: {
2090
+ entrypoints: [
2091
+ {
2092
+ command: "cat openpond-code-smoke.txt",
2093
+ name: "default"
2094
+ }
2095
+ ],
2096
+ retention: {
2097
+ class: "pinned"
2098
+ },
2099
+ safety: {
2100
+ cleanup: "delete",
2101
+ idleTimeoutSeconds: 600,
2102
+ internetEgress: "block",
2103
+ maxDurationSeconds: 600,
2104
+ maxSpendUsd: options.budgetUsd ?? "0.05",
2105
+ publicPreview: false
2106
+ },
2107
+ validation: {
2108
+ commands: [
2109
+ {
2110
+ command: "test -f openpond-code-smoke.txt"
2111
+ }
2112
+ ]
2113
+ }
2114
+ }
2115
+ });
2116
+ const snapshot = snapshotResponse.snapshot ?? (await waitForSnapshotReady(
2117
+ client,
2118
+ sandbox.id,
2119
+ snapshotResponse.snapshotJob?.snapshotId
2120
+ )).snapshot;
2121
+ snapshotId = snapshot.id;
2122
+ if (snapshot.state !== "ready") {
2123
+ throw new Error(`expected ready snapshot, got ${snapshot.state}`);
2124
+ }
2125
+ }
2126
+ if (options.fork) {
2127
+ if (!snapshotId) {
2128
+ throw new Error("expected snapshot id before fork");
2129
+ }
2130
+ const forked = await waitForCreateReady(
2131
+ client,
2132
+ (await client.forkSnapshot(
2133
+ snapshotId,
2134
+ {
2135
+ budget: { maxUsd: options.budgetUsd ?? "0.05" },
2136
+ metadata: {
2137
+ source: "openpond-code-sandbox-smoke-fork",
2138
+ templateSnapshotId: snapshotId
2139
+ }
2140
+ },
2141
+ { async: true }
2142
+ )).sandbox
2143
+ );
2144
+ forkSandboxId = forked.id;
2145
+ const forkExec = await client.exec(forked.id, {
2146
+ command: "cat openpond-code-smoke.txt",
2147
+ timeoutSeconds: 120
2148
+ });
2149
+ if (forkExec.command.status !== "succeeded") {
2150
+ throw new Error(
2151
+ `expected fork command success, got ${forkExec.command.status}`
2152
+ );
2153
+ }
2154
+ if (!forkExec.command.output.includes(expectedFile)) {
2155
+ throw new Error("expected fork snapshot marker");
2156
+ }
2157
+ if (!options.keep) {
2158
+ await deleteSandboxForSmoke(client, forked.id);
2159
+ forkDeleted = true;
2160
+ }
2161
+ }
2162
+ let previewStatus = null;
2163
+ if (options.preview !== false) {
2164
+ const opened = await client.openPort(sandbox.id, {
2165
+ label: "openpond-code-smoke",
2166
+ port: previewPort
2167
+ });
2168
+ const preview = await fetch(opened.preview.url);
2169
+ previewStatus = preview.status;
2170
+ const body = await preview.text();
2171
+ if (preview.status !== 200) {
2172
+ throw new Error(`expected preview HTTP 200, got ${preview.status}`);
2173
+ }
2174
+ if (!body.includes(expectedPreview)) {
2175
+ throw new Error("expected preview marker");
2176
+ }
2177
+ }
2178
+ const { sandbox: readback, receipts } = await stopSandboxForSmoke(
2179
+ client,
2180
+ sandbox.id
2181
+ );
2182
+ if (!options.keep) {
2183
+ await deleteSandboxForSmoke(client, sandbox.id);
2184
+ deleted = true;
2185
+ }
2186
+ return {
2187
+ deleted,
2188
+ execOutput: exec.command.output.trim(),
2189
+ fileRoundtrip: true,
2190
+ forkSandboxId,
2191
+ previewStatus,
2192
+ receiptRefs: receipts.map((receipt) => receipt.mpp.receiptRef ?? null),
2193
+ reservationRef: sandbox.reservation.mpp?.reservationRef ?? null,
2194
+ runId,
2195
+ sandboxId: sandbox.id,
2196
+ snapshotId,
2197
+ state: readback.state
2198
+ };
2199
+ } finally {
2200
+ if (forkSandboxId && !options.keep && !forkDeleted) {
2201
+ await cleanupSandboxBestEffort(client, forkSandboxId);
2202
+ }
2203
+ if (sandboxId && !options.keep && !deleted) {
2204
+ await cleanupSandboxBestEffort(client, sandboxId);
2205
+ }
2206
+ }
2207
+ }
2208
+ async function stopSandboxForSmoke(client, sandboxId) {
2209
+ try {
2210
+ await client.stop(sandboxId);
2211
+ } catch {
2212
+ await client.stop(sandboxId, { async: true });
2213
+ }
2214
+ const sandbox = await waitForSandboxState(
2215
+ client,
2216
+ sandboxId,
2217
+ /* @__PURE__ */ new Set(["stopped", "deleted"]),
2218
+ "stop"
2219
+ );
2220
+ const receipts = await waitForReceipts(client, sandboxId);
2221
+ if (receipts.length === 0) {
2222
+ throw new Error("expected receipt readback");
2223
+ }
2224
+ return { sandbox, receipts };
2225
+ }
2226
+ async function deleteSandboxForSmoke(client, sandboxId) {
2227
+ try {
2228
+ const deleted = await client.delete(sandboxId);
2229
+ if (deleted.state === "deleted") {
2230
+ return deleted;
2231
+ }
2232
+ await client.delete(sandboxId, { async: true });
2233
+ } catch {
2234
+ await client.delete(sandboxId, { async: true });
2235
+ }
2236
+ return waitForSandboxState(
2237
+ client,
2238
+ sandboxId,
2239
+ /* @__PURE__ */ new Set(["deleted"]),
2240
+ "delete"
2241
+ );
2242
+ }
2243
+ async function cleanupSandboxBestEffort(client, sandboxId) {
2244
+ try {
2245
+ await deleteSandboxForSmoke(client, sandboxId);
2246
+ } catch {
2247
+ await client.delete(sandboxId, { async: true }).catch(() => void 0);
2248
+ }
2249
+ }
2250
+ async function waitForSandboxState(client, sandboxId, targetStates, operation) {
2251
+ const timeoutMs = 5 * 6e4;
2252
+ const pollMs = 3e3;
2253
+ const deadline = Date.now() + timeoutMs;
2254
+ let latest = await client.get(sandboxId);
2255
+ while (Date.now() < deadline) {
2256
+ if (targetStates.has(latest.state)) {
2257
+ return latest;
2258
+ }
2259
+ if (latest.state === "error") {
2260
+ throw new Error(`sandbox ${operation} failed: ${sandboxId}`);
2261
+ }
2262
+ await sleep(pollMs);
2263
+ latest = await client.get(sandboxId);
2264
+ }
2265
+ throw new Error(
2266
+ `sandbox ${operation} did not reach ${[...targetStates].join(
2267
+ "/"
2268
+ )} before timeout: ${sandboxId} (${latest.state})`
2269
+ );
2270
+ }
2271
+ async function waitForReceipts(client, sandboxId) {
2272
+ const timeoutMs = 2 * 6e4;
2273
+ const pollMs = 3e3;
2274
+ const deadline = Date.now() + timeoutMs;
2275
+ let receipts = await client.receipts(sandboxId);
2276
+ while (Date.now() < deadline) {
2277
+ if (receipts.length > 0) {
2278
+ return receipts;
2279
+ }
2280
+ await sleep(pollMs);
2281
+ receipts = await client.receipts(sandboxId);
2282
+ }
2283
+ return receipts;
2284
+ }
2285
+ async function waitForCreateReady(client, sandbox) {
2286
+ if (sandbox.state === "running" || sandbox.state === "stopped") {
2287
+ return sandbox;
2288
+ }
2289
+ if (sandbox.state === "error") {
2290
+ throw new Error(
2291
+ `sandbox create failed: ${sandbox.id}
2292
+ ${sandbox.logs.join("\n")}`
2293
+ );
2294
+ }
2295
+ const timeoutMs = 12 * 6e4;
2296
+ const pollMs = 3e3;
2297
+ const deadline = Date.now() + timeoutMs;
2298
+ let latest = sandbox;
2299
+ while (Date.now() < deadline) {
2300
+ await sleep(pollMs);
2301
+ latest = await client.get(sandbox.id);
2302
+ if (latest.state === "running" || latest.state === "stopped") {
2303
+ return latest;
2304
+ }
2305
+ if (latest.state === "error") {
2306
+ throw new Error(
2307
+ `sandbox create failed: ${latest.id}
2308
+ ${latest.logs.join("\n")}`
2309
+ );
2310
+ }
2311
+ }
2312
+ throw new Error(
2313
+ `sandbox create did not reach running state before timeout: ${latest.id} (${latest.state})`
2314
+ );
2315
+ }
2316
+ async function waitForSnapshotReady(client, sandboxId, snapshotId) {
2317
+ if (!snapshotId) {
2318
+ throw new Error("snapshot job did not return snapshot id");
2319
+ }
2320
+ const timeoutMs = 12 * 6e4;
2321
+ const pollMs = 3e3;
2322
+ const deadline = Date.now() + timeoutMs;
2323
+ let latest = await client.get(sandboxId);
2324
+ while (Date.now() < deadline) {
2325
+ const snapshot = latest.snapshots?.find((item) => item.id === snapshotId);
2326
+ if (snapshot?.state === "ready") {
2327
+ return { sandbox: latest, snapshot };
2328
+ }
2329
+ const job = latest.snapshotJobs?.find(
2330
+ (item) => item.snapshotId === snapshotId
2331
+ );
2332
+ if (job?.status === "failed") {
2333
+ throw new Error(`snapshot job failed: ${job.error ?? snapshotId}`);
2334
+ }
2335
+ await sleep(pollMs);
2336
+ latest = await client.get(sandboxId);
2337
+ }
2338
+ throw new Error(
2339
+ `snapshot did not reach ready state before timeout: ${snapshotId}`
2340
+ );
2341
+ }
2342
+ function sleep(ms) {
2343
+ return new Promise((resolve) => setTimeout(resolve, ms));
2344
+ }
2345
+
2346
+ // ../../packages/cloud/src/sandbox/async-request-options.ts
2347
+ function asyncRequestHeaders(options = {}) {
2348
+ return options.async || options.respondAsync ? { Prefer: "respond-async" } : void 0;
2349
+ }
2350
+
2351
+ // ../../packages/cloud/src/sandbox/stream.ts
2352
+ async function streamSandboxEventOutput(params) {
2353
+ const response = await apiFetch(
2354
+ params.sandboxApiUrl,
2355
+ params.apiKey,
2356
+ params.path,
2357
+ { timeoutMs: 0, maxResponseBytes: 0 }
2358
+ );
2359
+ if (!response.body) {
2360
+ return;
2361
+ }
2362
+ const reader = response.body.getReader();
2363
+ const decoder = new TextDecoder();
2364
+ let buffered = "";
2365
+ try {
2366
+ while (true) {
2367
+ const { done, value } = await reader.read();
2368
+ if (done) break;
2369
+ buffered += decoder.decode(value, { stream: true });
2370
+ let separatorIndex = buffered.indexOf("\n\n");
2371
+ while (separatorIndex !== -1) {
2372
+ const event = buffered.slice(0, separatorIndex);
2373
+ buffered = buffered.slice(separatorIndex + 2);
2374
+ const output3 = parseProcessOutputEvent(event);
2375
+ if (output3) process.stdout.write(output3);
2376
+ separatorIndex = buffered.indexOf("\n\n");
2377
+ }
2378
+ }
2379
+ } finally {
2380
+ reader.releaseLock();
2381
+ }
2382
+ }
2383
+ function normalizePtyInput(input3) {
2384
+ if (typeof input3 === "string") {
2385
+ return { dataBase64: Buffer.from(input3, "utf-8").toString("base64") };
2386
+ }
2387
+ if (input3 instanceof Uint8Array) {
2388
+ return { dataBase64: Buffer.from(input3).toString("base64") };
2389
+ }
2390
+ return input3;
2391
+ }
2392
+ function parseProcessOutputEvent(event) {
2393
+ if (!event.includes("event: output")) {
2394
+ return null;
2395
+ }
2396
+ const dataLines = event.split(/\r?\n/).filter((line) => line.startsWith("data: ")).map((line) => line.slice("data: ".length));
2397
+ if (dataLines.length === 0) {
2398
+ return null;
2399
+ }
2400
+ try {
2401
+ const parsed = JSON.parse(dataLines.join("\n"));
2402
+ return typeof parsed.output === "string" ? parsed.output : null;
2403
+ } catch {
2404
+ return null;
2405
+ }
2406
+ }
2407
+
2408
+ // ../../packages/cloud/src/sandbox/url.ts
2409
+ function normalizeSandboxApiUrl(baseUrlOrApiUrl) {
2410
+ const trimmed = baseUrlOrApiUrl.trim().replace(/\/$/, "");
2411
+ if (!trimmed) {
2412
+ throw new Error("sandbox API URL must be non-empty");
2413
+ }
2414
+ const url = new URL(trimmed);
2415
+ const normalizedPath = url.pathname.replace(/\/$/, "");
2416
+ if (normalizedPath.endsWith("/v1/sandboxes") || normalizedPath.endsWith("/api/sandboxes")) {
2417
+ return `${url.origin}${normalizedPath}`;
2418
+ }
2419
+ if (normalizedPath.endsWith("/v1")) {
2420
+ return `${url.origin}${normalizedPath}/sandboxes`;
2421
+ }
2422
+ if (isOpenPondHostedApiHost(url.hostname)) {
2423
+ return `${url.origin}${normalizedPath}/v1/sandboxes`;
2424
+ }
2425
+ if (url.origin === DEFAULT_OPENPOND_WEB_BASE_URL) {
2426
+ return `${DEFAULT_OPENPOND_API_BASE_URL}/v1/sandboxes`;
2427
+ }
2428
+ return `${url.origin}${normalizedPath}/api/sandboxes`;
2429
+ }
2430
+ function apiRootUrlFromSandboxApiUrl(sandboxApiUrl) {
2431
+ const suffix = "/sandboxes";
2432
+ if (!sandboxApiUrl.endsWith(suffix)) {
2433
+ throw new Error("sandbox API URL must end with /sandboxes");
2434
+ }
2435
+ return sandboxApiUrl.slice(0, -suffix.length);
2436
+ }
2437
+ function isOpenPondHostedApiHost(hostname) {
2438
+ return hostname === "api.openpond.ai" || hostname.startsWith("api") && hostname.endsWith(".openpond.ai");
2439
+ }
2440
+
2441
+ // ../../packages/cloud/src/sandbox/sandbox-instance-client.ts
2442
+ var OpenPondSandboxInstanceClient = class {
2443
+ apiKey;
2444
+ apiRootUrl;
2445
+ sandboxApiUrl;
2446
+ constructor(options) {
2447
+ this.apiKey = options.apiKey;
2448
+ this.sandboxApiUrl = normalizeSandboxApiUrl(
2449
+ options.sandboxApiUrl ?? options.baseUrl ?? DEFAULT_OPENPOND_API_BASE_URL
2450
+ );
2451
+ this.apiRootUrl = apiRootUrlFromSandboxApiUrl(this.sandboxApiUrl);
2452
+ }
2453
+ create(input3, options = {}) {
2454
+ return this.request("", {
2455
+ method: "POST",
2456
+ headers: asyncRequestHeaders(options),
2457
+ body: JSON.stringify(input3)
2458
+ }).then((payload) => payload.sandbox);
2459
+ }
2460
+ get(sandboxId) {
2461
+ return this.request(
2462
+ `/${encodeURIComponent(sandboxId)}`
2463
+ ).then((payload) => payload.sandbox);
2464
+ }
2465
+ exec(sandboxId, input3) {
2466
+ return this.request(
2467
+ `/${encodeURIComponent(sandboxId)}/exec`,
2468
+ {
2469
+ method: "POST",
2470
+ body: JSON.stringify(input3)
2471
+ }
2472
+ );
2473
+ }
2474
+ startProcess(sandboxId, input3) {
2475
+ return this.request(
2476
+ `/${encodeURIComponent(sandboxId)}/processes`,
2477
+ {
2478
+ method: "POST",
2479
+ body: JSON.stringify(input3)
2480
+ }
2481
+ );
2482
+ }
2483
+ listProcesses(sandboxId) {
2484
+ return this.request(
2485
+ `/${encodeURIComponent(sandboxId)}/processes`
2486
+ );
2487
+ }
2488
+ getProcess(sandboxId, processId, input3 = {}) {
2489
+ const query = new URLSearchParams();
2490
+ if (input3.since !== void 0)
2491
+ query.set("since", String(Math.max(0, input3.since)));
2492
+ return this.request(
2493
+ `/${encodeURIComponent(sandboxId)}/processes/${encodeURIComponent(
2494
+ processId
2495
+ )}${query.size > 0 ? `?${query.toString()}` : ""}`
2496
+ );
2497
+ }
2498
+ stopProcess(sandboxId, processId) {
2499
+ return this.request(
2500
+ `/${encodeURIComponent(sandboxId)}/processes/${encodeURIComponent(
2501
+ processId
2502
+ )}`,
2503
+ {
2504
+ method: "DELETE"
2505
+ }
2506
+ );
2507
+ }
2508
+ async streamProcessOutput(sandboxId, processId, input3 = {}) {
2509
+ const query = new URLSearchParams();
2510
+ if (input3.since !== void 0)
2511
+ query.set("since", String(Math.max(0, input3.since)));
2512
+ await streamSandboxEventOutput({
2513
+ sandboxApiUrl: this.sandboxApiUrl,
2514
+ apiKey: this.apiKey,
2515
+ path: `/${encodeURIComponent(sandboxId)}/processes/${encodeURIComponent(
2516
+ processId
2517
+ )}/stream${query.size > 0 ? `?${query.toString()}` : ""}`
2518
+ });
2519
+ }
2520
+ startPty(sandboxId, input3 = {}) {
2521
+ return this.request(
2522
+ `/${encodeURIComponent(sandboxId)}/pty`,
2523
+ {
2524
+ method: "POST",
2525
+ body: JSON.stringify(input3)
2526
+ }
2527
+ );
2528
+ }
2529
+ listPtys(sandboxId) {
2530
+ return this.request(
2531
+ `/${encodeURIComponent(sandboxId)}/pty`
2532
+ );
2533
+ }
2534
+ getPty(sandboxId, ptyId, input3 = {}) {
2535
+ const query = new URLSearchParams();
2536
+ if (input3.since !== void 0)
2537
+ query.set("since", String(Math.max(0, input3.since)));
2538
+ return this.request(
2539
+ `/${encodeURIComponent(sandboxId)}/pty/${encodeURIComponent(ptyId)}${query.size > 0 ? `?${query.toString()}` : ""}`
2540
+ );
2541
+ }
2542
+ writePtyInput(sandboxId, ptyId, input3) {
2543
+ return this.request(
2544
+ `/${encodeURIComponent(sandboxId)}/pty/${encodeURIComponent(
2545
+ ptyId
2546
+ )}/input`,
2547
+ {
2548
+ method: "POST",
2549
+ body: JSON.stringify(normalizePtyInput(input3))
2550
+ }
2551
+ );
2552
+ }
2553
+ stopPty(sandboxId, ptyId) {
2554
+ return this.request(
2555
+ `/${encodeURIComponent(sandboxId)}/pty/${encodeURIComponent(ptyId)}`,
2556
+ {
2557
+ method: "DELETE"
2558
+ }
2559
+ );
2560
+ }
2561
+ async streamPtyOutput(sandboxId, ptyId, input3 = {}) {
2562
+ const query = new URLSearchParams();
2563
+ if (input3.since !== void 0)
2564
+ query.set("since", String(Math.max(0, input3.since)));
2565
+ await streamSandboxEventOutput({
2566
+ sandboxApiUrl: this.sandboxApiUrl,
2567
+ apiKey: this.apiKey,
2568
+ path: `/${encodeURIComponent(sandboxId)}/pty/${encodeURIComponent(
2569
+ ptyId
2570
+ )}/stream${query.size > 0 ? `?${query.toString()}` : ""}`
2571
+ });
2572
+ }
2573
+ uploadFile(sandboxId, path4, contents) {
2574
+ return this.uploadFileBase64(
2575
+ sandboxId,
2576
+ path4,
2577
+ Buffer.from(contents, "utf-8").toString("base64")
2578
+ );
2579
+ }
2580
+ uploadFileBase64(sandboxId, path4, contentsBase64) {
2581
+ return this.request(
2582
+ `/${encodeURIComponent(sandboxId)}/files`,
2583
+ {
2584
+ method: "POST",
2585
+ body: JSON.stringify({
2586
+ path: path4,
2587
+ contentsBase64
2588
+ })
2589
+ }
2590
+ );
2591
+ }
2592
+ async downloadFile(sandboxId, path4) {
2593
+ const payload = await this.downloadFileResponse(sandboxId, path4);
2594
+ return Buffer.from(payload.file.contentsBase64, "base64").toString("utf-8");
2595
+ }
2596
+ downloadFileResponse(sandboxId, input3) {
2597
+ const normalized = typeof input3 === "string" ? { path: input3 } : input3;
2598
+ const query = new URLSearchParams({ path: normalized.path });
2599
+ if (normalized.offsetBytes !== void 0) {
2600
+ query.set("offsetBytes", String(normalized.offsetBytes));
2601
+ }
2602
+ if (normalized.maxBytes !== void 0) {
2603
+ query.set("maxBytes", String(normalized.maxBytes));
2604
+ }
2605
+ return this.request(
2606
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`
2607
+ );
2608
+ }
2609
+ listFiles(sandboxId, input3 = {}) {
2610
+ const query = new URLSearchParams({ list: "1" });
2611
+ if (input3.path) query.set("path", input3.path);
2612
+ if (input3.recursive !== void 0)
2613
+ query.set("recursive", String(input3.recursive));
2614
+ if (input3.maxEntries !== void 0)
2615
+ query.set("maxEntries", String(input3.maxEntries));
2616
+ return this.request(
2617
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`
2618
+ );
2619
+ }
2620
+ deleteFile(sandboxId, path4, input3 = {}) {
2621
+ const query = new URLSearchParams({ path: path4 });
2622
+ if (input3.recursive !== void 0)
2623
+ query.set("recursive", String(input3.recursive));
2624
+ return this.request(
2625
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`,
2626
+ {
2627
+ method: "DELETE"
2628
+ }
2629
+ );
2630
+ }
2631
+ statFile(sandboxId, path4) {
2632
+ const query = new URLSearchParams({ stat: "1", path: path4 });
2633
+ return this.request(
2634
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`
2635
+ );
2636
+ }
2637
+ mkdir(sandboxId, input3) {
2638
+ const normalized = typeof input3 === "string" ? { path: input3 } : input3;
2639
+ const query = new URLSearchParams({ path: normalized.path });
2640
+ if (normalized.recursive !== void 0)
2641
+ query.set("recursive", String(normalized.recursive));
2642
+ return this.request(
2643
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`,
2644
+ {
2645
+ method: "PUT"
2646
+ }
2647
+ );
2648
+ }
2649
+ moveFile(sandboxId, input3) {
2650
+ const query = new URLSearchParams({
2651
+ fromPath: input3.fromPath,
2652
+ toPath: input3.toPath
2653
+ });
2654
+ if (input3.overwrite !== void 0)
2655
+ query.set("overwrite", String(input3.overwrite));
2656
+ return this.request(
2657
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`,
2658
+ {
2659
+ method: "PATCH"
2660
+ }
2661
+ );
2662
+ }
2663
+ searchFiles(sandboxId, input3) {
2664
+ const query = new URLSearchParams({
2665
+ search: "1",
2666
+ query: input3.query
2667
+ });
2668
+ if (input3.path) query.set("path", input3.path);
2669
+ if (input3.maxResults !== void 0)
2670
+ query.set("maxResults", String(input3.maxResults));
2671
+ return this.request(
2672
+ `/${encodeURIComponent(sandboxId)}/files?${query.toString()}`
2673
+ );
2674
+ }
2675
+ openPort(sandboxId, input3) {
2676
+ return this.request(
2677
+ `/${encodeURIComponent(sandboxId)}/ports`,
2678
+ {
2679
+ method: "POST",
2680
+ body: JSON.stringify(input3)
2681
+ }
2682
+ );
2683
+ }
2684
+ createSnapshot(sandboxId, input3) {
2685
+ return this.request(
2686
+ `/${encodeURIComponent(sandboxId)}/snapshots`,
2687
+ {
2688
+ method: "POST",
2689
+ body: JSON.stringify(input3)
2690
+ }
2691
+ );
2692
+ }
2693
+ updateSnapshot(sandboxId, snapshotId, input3) {
2694
+ return this.request(
2695
+ `/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(
2696
+ snapshotId
2697
+ )}`,
2698
+ {
2699
+ method: "PATCH",
2700
+ body: JSON.stringify(input3)
2701
+ }
2702
+ );
2703
+ }
2704
+ validateSnapshot(sandboxId, snapshotId, input3 = {}) {
2705
+ return this.request(
2706
+ `/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(
2707
+ snapshotId
2708
+ )}/validate`,
2709
+ {
2710
+ method: "POST",
2711
+ body: JSON.stringify(input3)
2712
+ }
2713
+ );
2714
+ }
2715
+ publishSnapshot(sandboxId, snapshotId) {
2716
+ return this.request(
2717
+ `/${encodeURIComponent(sandboxId)}/snapshots/${encodeURIComponent(
2718
+ snapshotId
2719
+ )}/publish`,
2720
+ {
2721
+ method: "POST"
2722
+ }
2723
+ );
2724
+ }
2725
+ fork(sandboxId, input3 = {}) {
2726
+ return this.request(
2727
+ `/${encodeURIComponent(sandboxId)}/fork`,
2728
+ {
2729
+ method: "POST",
2730
+ body: JSON.stringify(input3)
2731
+ }
2732
+ );
2733
+ }
2734
+ stop(sandboxId, options = {}) {
2735
+ const query = new URLSearchParams();
2736
+ if (options.failOnUnpreservedChanges) {
2737
+ query.set("failOnUnpreservedChanges", "true");
2738
+ }
2739
+ return this.request(
2740
+ `/${encodeURIComponent(sandboxId)}/stop${query.size > 0 ? `?${query.toString()}` : ""}`,
2741
+ {
2742
+ method: "POST",
2743
+ headers: asyncRequestHeaders(options)
2744
+ }
2745
+ );
2746
+ }
2747
+ start(sandboxId, options = {}) {
2748
+ return this.request(
2749
+ `/${encodeURIComponent(sandboxId)}/start`,
2750
+ {
2751
+ method: "POST",
2752
+ headers: asyncRequestHeaders(options)
2753
+ }
2754
+ );
2755
+ }
2756
+ restore(sandboxId) {
2757
+ return this.request(
2758
+ `/${encodeURIComponent(sandboxId)}/restore`,
2759
+ {
2760
+ method: "POST"
2761
+ }
2762
+ );
2763
+ }
2764
+ delete(sandboxId, options = {}) {
2765
+ const query = new URLSearchParams();
2766
+ if (options.failOnUnpreservedChanges) {
2767
+ query.set("failOnUnpreservedChanges", "true");
2768
+ }
2769
+ return this.request(
2770
+ `/${encodeURIComponent(sandboxId)}${query.size > 0 ? `?${query.toString()}` : ""}`,
2771
+ {
2772
+ method: "DELETE",
2773
+ headers: asyncRequestHeaders(options)
2774
+ }
2775
+ ).then((payload) => payload.sandbox);
2776
+ }
2777
+ receipts(sandboxId) {
2778
+ return this.request(
2779
+ `/${encodeURIComponent(sandboxId)}/receipts`
2780
+ ).then((payload) => payload.receipts);
2781
+ }
2782
+ logs(sandboxId) {
2783
+ return this.request(
2784
+ `/${encodeURIComponent(sandboxId)}/logs`
2785
+ ).then((payload) => payload.logs);
2786
+ }
2787
+ gitStatus(sandboxId) {
2788
+ return this.request(
2789
+ `/${encodeURIComponent(sandboxId)}/git/status`
2790
+ );
2791
+ }
2792
+ gitDiff(sandboxId, input3 = {}) {
2793
+ return this.request(
2794
+ `/${encodeURIComponent(sandboxId)}/git/diff`,
2795
+ {
2796
+ method: "POST",
2797
+ body: JSON.stringify(input3)
2798
+ }
2799
+ );
2800
+ }
2801
+ gitExportPatch(sandboxId, input3 = {}) {
2802
+ return this.request(
2803
+ `/${encodeURIComponent(sandboxId)}/git/export-patch`,
2804
+ {
2805
+ method: "POST",
2806
+ body: JSON.stringify(input3)
2807
+ }
2808
+ );
2809
+ }
2810
+ gitBranch(sandboxId, input3) {
2811
+ return this.request(
2812
+ `/${encodeURIComponent(sandboxId)}/git/branch`,
2813
+ {
2814
+ method: "POST",
2815
+ body: JSON.stringify(input3)
2816
+ }
2817
+ );
2818
+ }
2819
+ gitCommit(sandboxId, input3) {
2820
+ return this.request(
2821
+ `/${encodeURIComponent(sandboxId)}/git/commit`,
2822
+ {
2823
+ method: "POST",
2824
+ body: JSON.stringify(input3)
2825
+ }
2826
+ );
2827
+ }
2828
+ gitPull(sandboxId, input3 = {}) {
2829
+ return this.request(
2830
+ `/${encodeURIComponent(sandboxId)}/git/pull`,
2831
+ {
2832
+ method: "POST",
2833
+ body: JSON.stringify(input3)
2834
+ }
2835
+ );
2836
+ }
2837
+ gitPush(sandboxId, input3 = {}) {
2838
+ return this.request(
2839
+ `/${encodeURIComponent(sandboxId)}/git/push`,
2840
+ {
2841
+ method: "POST",
2842
+ body: JSON.stringify(input3)
2843
+ }
2844
+ );
2845
+ }
2846
+ billing(sandboxId) {
2847
+ return this.request(
2848
+ `/${encodeURIComponent(sandboxId)}/billing`
2849
+ );
2850
+ }
2851
+ pricing() {
2852
+ return this.request("/pricing");
2853
+ }
2854
+ costs(input3 = {}) {
2855
+ const query = new URLSearchParams();
2856
+ if (input3.teamId) query.set("teamId", input3.teamId);
2857
+ if (input3.projectId) query.set("projectId", input3.projectId);
2858
+ if (input3.agentId) query.set("agentId", input3.agentId);
2859
+ return this.request(
2860
+ `/costs${query.size > 0 ? `?${query.toString()}` : ""}`
2861
+ );
2862
+ }
2863
+ integrationLeases(sandboxId) {
2864
+ return this.request(
2865
+ `/${encodeURIComponent(sandboxId)}/integrations`
2866
+ );
2867
+ }
2868
+ attachIntegrationConnection(sandboxId, input3) {
2869
+ return this.request(
2870
+ `/${encodeURIComponent(sandboxId)}/integrations`,
2871
+ {
2872
+ method: "POST",
2873
+ body: JSON.stringify(input3)
2874
+ }
2875
+ );
2876
+ }
2877
+ removeIntegrationLease(sandboxId, leaseId) {
2878
+ return this.request(
2879
+ `/${encodeURIComponent(sandboxId)}/integrations`,
2880
+ {
2881
+ method: "DELETE",
2882
+ body: JSON.stringify({ leaseId })
2883
+ }
2884
+ );
2885
+ }
2886
+ async request(path4, init = {}) {
2887
+ const response = await apiFetch(
2888
+ this.sandboxApiUrl,
2889
+ this.apiKey,
2890
+ path4,
2891
+ init
2892
+ );
2893
+ return readApiJson(response, "Sandbox request");
2894
+ }
2895
+ async requestApiRoot(path4, init = {}) {
2896
+ const response = await apiFetch(this.apiRootUrl, this.apiKey, path4, init);
2897
+ return readApiJson(response, "OpenPond API request");
2898
+ }
2899
+ };
2900
+
2901
+ // ../../packages/cloud/src/sandbox/client.ts
2902
+ var OpenPondSandboxClient = class extends OpenPondSandboxInstanceClient {
2903
+ runtimes = createSandboxRuntimeNamespace(this);
2904
+ sandboxes = createSandboxNamespace(this);
2905
+ profile = createSandboxProfileNamespace(this);
2906
+ projects = createSandboxProjectNamespace(this);
2907
+ agents = createSandboxAgentNamespace(this);
2908
+ workItems = createSandboxWorkItemNamespace(this);
2909
+ list(input3 = {}) {
2910
+ const query = new URLSearchParams();
2911
+ if (input3.teamId) query.set("teamId", input3.teamId);
2912
+ if (input3.projectId) query.set("projectId", input3.projectId);
2913
+ if (input3.agentId) query.set("agentId", input3.agentId);
2914
+ return this.request(
2915
+ query.size > 0 ? `?${query.toString()}` : ""
2916
+ ).then((payload) => payload.sandboxes);
2917
+ }
2918
+ listSecrets(input3 = {}) {
2919
+ const query = new URLSearchParams();
2920
+ if (input3.teamId) query.set("teamId", input3.teamId);
2921
+ return this.requestApiRoot(
2922
+ `/sandbox-secrets${query.size > 0 ? `?${query.toString()}` : ""}`
2923
+ ).then((payload) => payload.secrets);
2924
+ }
2925
+ getSecret(secretId, input3 = {}) {
2926
+ const query = new URLSearchParams();
2927
+ if (input3.teamId) query.set("teamId", input3.teamId);
2928
+ return this.requestApiRoot(
2929
+ `/sandbox-secrets/${encodeURIComponent(secretId)}${query.size > 0 ? `?${query.toString()}` : ""}`
2930
+ ).then((payload) => payload.secret);
2931
+ }
2932
+ createSecret(input3) {
2933
+ return this.requestApiRoot("/sandbox-secrets", {
2934
+ method: "POST",
2935
+ body: JSON.stringify(input3)
2936
+ }).then((payload) => payload.secret);
2937
+ }
2938
+ rotateSecret(secretId, input3) {
2939
+ const query = new URLSearchParams();
2940
+ if (input3.teamId) query.set("teamId", input3.teamId);
2941
+ const { teamId: _teamId, ...body } = input3;
2942
+ return this.requestApiRoot(
2943
+ `/sandbox-secrets/${encodeURIComponent(secretId)}/rotate${query.size > 0 ? `?${query.toString()}` : ""}`,
2944
+ {
2945
+ method: "POST",
2946
+ body: JSON.stringify(body)
2947
+ }
2948
+ ).then((payload) => payload.secret);
2949
+ }
2950
+ attachSecret(secretId, input3) {
2951
+ const query = new URLSearchParams();
2952
+ if (input3.teamId) query.set("teamId", input3.teamId);
2953
+ const { teamId: _teamId, ...body } = input3;
2954
+ return this.requestApiRoot(
2955
+ `/sandbox-secrets/${encodeURIComponent(secretId)}/attach${query.size > 0 ? `?${query.toString()}` : ""}`,
2956
+ {
2957
+ method: "POST",
2958
+ body: JSON.stringify(body)
2959
+ }
2960
+ ).then((payload) => payload.secret);
2961
+ }
2962
+ revokeSecret(secretId, input3 = {}) {
2963
+ const query = new URLSearchParams();
2964
+ if (input3.teamId) query.set("teamId", input3.teamId);
2965
+ return this.requestApiRoot(
2966
+ `/sandbox-secrets/${encodeURIComponent(secretId)}/revoke${query.size > 0 ? `?${query.toString()}` : ""}`,
2967
+ { method: "POST" }
2968
+ ).then((payload) => payload.secret);
2969
+ }
2970
+ deleteSecret(secretId, input3 = {}) {
2971
+ const query = new URLSearchParams();
2972
+ if (input3.teamId) query.set("teamId", input3.teamId);
2973
+ return this.requestApiRoot(
2974
+ `/sandbox-secrets/${encodeURIComponent(secretId)}${query.size > 0 ? `?${query.toString()}` : ""}`,
2975
+ { method: "DELETE" }
2976
+ ).then((payload) => payload.secret);
2977
+ }
2978
+ snapshotCatalog(input3 = {}) {
2979
+ const query = new URLSearchParams();
2980
+ if (input3.teamId) query.set("teamId", input3.teamId);
2981
+ if (input3.projectId) query.set("projectId", input3.projectId);
2982
+ if (input3.agentId) query.set("agentId", input3.agentId);
2983
+ if (input3.q) query.set("q", input3.q);
2984
+ if (input3.kind) query.set("kind", input3.kind);
2985
+ if (input3.replayState) query.set("replayState", input3.replayState);
2986
+ if (input3.visibility) query.set("visibility", input3.visibility);
2987
+ if (input3.tag) query.set("tag", input3.tag);
2988
+ if (input3.useCase) query.set("useCase", input3.useCase);
2989
+ if (input3.limit) query.set("limit", String(input3.limit));
2990
+ return this.request(
2991
+ `/catalog/snapshots${query.size > 0 ? `?${query.toString()}` : ""}`
2992
+ );
2993
+ }
2994
+ listSandboxRuntimes(input3 = {}) {
2995
+ const query = new URLSearchParams();
2996
+ if (input3.teamId) query.set("teamId", input3.teamId);
2997
+ if (input3.projectId) query.set("projectId", input3.projectId);
2998
+ if (input3.agentId) query.set("agentId", input3.agentId);
2999
+ return this.requestApiRoot(
3000
+ `/runtimes${query.size > 0 ? `?${query.toString()}` : ""}`
3001
+ ).then((payload) => payload.runtimes);
3002
+ }
3003
+ listProjects(input3) {
3004
+ const query = new URLSearchParams({ teamId: input3.teamId });
3005
+ return this.requestApiRoot(
3006
+ `/projects?${query.toString()}`
3007
+ ).then((payload) => payload.projects);
3008
+ }
3009
+ upsertProject(input3) {
3010
+ return this.requestApiRoot("/projects", {
3011
+ method: "POST",
3012
+ body: JSON.stringify(input3)
3013
+ }).then((payload) => payload.project);
3014
+ }
3015
+ getHostedProfile(input3) {
3016
+ const query = new URLSearchParams({ teamId: input3.teamId });
3017
+ return this.requestApiRoot(
3018
+ `/profile?${query.toString()}`
3019
+ ).then((payload) => payload.profile);
3020
+ }
3021
+ ensureHostedProfile(input3) {
3022
+ const query = new URLSearchParams({ teamId: input3.teamId });
3023
+ return this.requestApiRoot(
3024
+ `/profile/ensure?${query.toString()}`,
3025
+ { method: "POST" }
3026
+ ).then((payload) => {
3027
+ if (!payload.profile) {
3028
+ throw new Error("hosted_profile_missing");
3029
+ }
3030
+ return payload.profile;
3031
+ });
3032
+ }
3033
+ pushHostedProfile(input3) {
3034
+ const query = new URLSearchParams({ teamId: input3.teamId });
3035
+ const { teamId: _teamId, ...body } = input3;
3036
+ return this.requestApiRoot(
3037
+ `/profile/push?${query.toString()}`,
3038
+ {
3039
+ method: "POST",
3040
+ body: JSON.stringify(body)
3041
+ }
3042
+ );
3043
+ }
3044
+ async upsertProjectGitRemote(input3) {
3045
+ const project = await this.upsertProject(input3);
3046
+ return this.ensureProjectGitRemote(project.id, { teamId: input3.teamId });
3047
+ }
3048
+ getProject(projectId, input3) {
3049
+ const query = new URLSearchParams({ teamId: input3.teamId });
3050
+ return this.requestApiRoot(
3051
+ `/projects/${encodeURIComponent(projectId)}?${query.toString()}`
3052
+ ).then((payload) => payload.project);
3053
+ }
3054
+ syncProject(projectId, input3) {
3055
+ const query = new URLSearchParams({ teamId: input3.teamId });
3056
+ return this.requestApiRoot(
3057
+ `/projects/${encodeURIComponent(projectId)}/sync?${query.toString()}`,
3058
+ { method: "POST" }
3059
+ ).then((payload) => payload.project);
3060
+ }
3061
+ ensureProjectGitRemote(projectId, input3) {
3062
+ const query = new URLSearchParams({ teamId: input3.teamId });
3063
+ return this.requestApiRoot(
3064
+ `/projects/${encodeURIComponent(projectId)}/git?${query.toString()}`,
3065
+ { method: "POST" }
3066
+ );
3067
+ }
3068
+ uploadProjectSource(projectId, input3) {
3069
+ const query = new URLSearchParams({ teamId: input3.teamId });
3070
+ const { teamId: _teamId, ...body } = input3;
3071
+ return this.requestApiRoot(
3072
+ `/projects/${encodeURIComponent(projectId)}/source?${query.toString()}`,
3073
+ {
3074
+ method: "POST",
3075
+ body: JSON.stringify(body)
3076
+ }
3077
+ ).then((payload) => payload.project);
3078
+ }
3079
+ updateProject(projectId, input3) {
3080
+ const query = new URLSearchParams({ teamId: input3.teamId });
3081
+ const { teamId: _teamId, ...body } = input3;
3082
+ return this.requestApiRoot(
3083
+ `/projects/${encodeURIComponent(projectId)}?${query.toString()}`,
3084
+ {
3085
+ method: "PATCH",
3086
+ body: JSON.stringify(body)
3087
+ }
3088
+ ).then((payload) => payload.project);
3089
+ }
3090
+ archiveProject(projectId, input3) {
3091
+ const query = new URLSearchParams({ teamId: input3.teamId });
3092
+ return this.requestApiRoot(
3093
+ `/projects/${encodeURIComponent(projectId)}?${query.toString()}`,
3094
+ { method: "DELETE" }
3095
+ ).then((payload) => payload.project);
3096
+ }
3097
+ listAgents(input3) {
3098
+ const query = new URLSearchParams({ teamId: input3.teamId });
3099
+ return this.requestApiRoot(
3100
+ `/agents?${query.toString()}`
3101
+ ).then((payload) => payload.agents);
3102
+ }
3103
+ upsertAgent(input3) {
3104
+ return this.requestApiRoot("/agents", {
3105
+ method: "POST",
3106
+ body: JSON.stringify(input3)
3107
+ }).then((payload) => payload.agent);
3108
+ }
3109
+ getAgent(agentId, input3) {
3110
+ const query = new URLSearchParams({ teamId: input3.teamId });
3111
+ return this.requestApiRoot(
3112
+ `/agents/${encodeURIComponent(agentId)}?${query.toString()}`
3113
+ ).then((payload) => payload.agent);
3114
+ }
3115
+ archiveAgent(agentId, input3) {
3116
+ const query = new URLSearchParams({ teamId: input3.teamId });
3117
+ return this.requestApiRoot(
3118
+ `/agents/${encodeURIComponent(agentId)}?${query.toString()}`,
3119
+ { method: "DELETE" }
3120
+ ).then((payload) => payload.agent);
3121
+ }
3122
+ updateAgent(agentId, input3) {
3123
+ const query = new URLSearchParams({ teamId: input3.teamId });
3124
+ const { teamId: _teamId, ...body } = input3;
3125
+ return this.requestApiRoot(
3126
+ `/agents/${encodeURIComponent(agentId)}?${query.toString()}`,
3127
+ {
3128
+ method: "PATCH",
3129
+ body: JSON.stringify(body)
3130
+ }
3131
+ ).then((payload) => payload.agent);
3132
+ }
3133
+ runAgent(agentId, input3) {
3134
+ return this.requestApiRoot(
3135
+ `/agents/${encodeURIComponent(agentId)}/run`,
3136
+ {
3137
+ method: "POST",
3138
+ headers: {
3139
+ Prefer: "respond-async"
3140
+ },
3141
+ body: JSON.stringify(input3)
3142
+ }
3143
+ );
3144
+ }
3145
+ getAgentSourceDeployPlan(agentId, input3) {
3146
+ const query = new URLSearchParams({ teamId: input3.teamId });
3147
+ return this.requestApiRoot(
3148
+ `/agents/${encodeURIComponent(
3149
+ agentId
3150
+ )}/source/deploy-plan?${query.toString()}`
3151
+ ).then((payload) => payload.deployPlan);
3152
+ }
3153
+ listAgentManifestSnapshots(agentId, input3) {
3154
+ const query = new URLSearchParams({ teamId: input3.teamId });
3155
+ if (input3.limit !== void 0) query.set("limit", String(input3.limit));
3156
+ return this.requestApiRoot(
3157
+ `/agents/${encodeURIComponent(
3158
+ agentId
3159
+ )}/source/manifest-snapshots?${query.toString()}`
3160
+ ).then((payload) => payload.manifestSnapshots);
3161
+ }
3162
+ requestAgentSourceChecks(agentId, input3) {
3163
+ const query = new URLSearchParams({ teamId: input3.teamId });
3164
+ const { teamId: _teamId, ...body } = input3;
3165
+ return this.requestApiRoot(
3166
+ `/agents/${encodeURIComponent(
3167
+ agentId
3168
+ )}/source/checks?${query.toString()}`,
3169
+ {
3170
+ method: "POST",
3171
+ body: JSON.stringify(body)
3172
+ }
3173
+ );
3174
+ }
3175
+ publishAgentSource(agentId, input3) {
3176
+ const query = new URLSearchParams({ teamId: input3.teamId });
3177
+ const { teamId: _teamId, ...body } = input3;
3178
+ return this.requestApiRoot(
3179
+ `/agents/${encodeURIComponent(
3180
+ agentId
3181
+ )}/source/publish?${query.toString()}`,
3182
+ {
3183
+ method: "POST",
3184
+ body: JSON.stringify(body)
3185
+ }
3186
+ );
3187
+ }
3188
+ openAgentEditWorkItem(agentId, input3) {
3189
+ const query = new URLSearchParams({ teamId: input3.teamId });
3190
+ const { teamId: _teamId, ...body } = input3;
3191
+ return this.requestApiRoot(
3192
+ `/agents/${encodeURIComponent(
3193
+ agentId
3194
+ )}/edit-work-item?${query.toString()}`,
3195
+ {
3196
+ method: "POST",
3197
+ body: JSON.stringify(body)
3198
+ }
3199
+ );
3200
+ }
3201
+ getCodingWorkItem(workItemId, input3) {
3202
+ const query = new URLSearchParams({ teamId: input3.teamId });
3203
+ if (input3.includeArchived) query.set("includeArchived", "true");
3204
+ return this.requestApiRoot(
3205
+ `/work-items/${encodeURIComponent(workItemId)}?${query.toString()}`
3206
+ ).then((payload) => payload.workItem);
3207
+ }
3208
+ sendCodingWorkItemChat(workItemId, input3) {
3209
+ return this.requestApiRoot(
3210
+ `/work-items/${encodeURIComponent(workItemId)}/chat`,
3211
+ {
3212
+ method: "POST",
3213
+ body: JSON.stringify(input3)
3214
+ }
3215
+ );
3216
+ }
3217
+ listCodingWorkItemActivity(workItemId, input3) {
3218
+ const query = new URLSearchParams({ teamId: input3.teamId });
3219
+ if (input3.limit !== void 0) query.set("limit", String(input3.limit));
3220
+ return this.requestApiRoot(
3221
+ `/work-items/${encodeURIComponent(
3222
+ workItemId
3223
+ )}/activity?${query.toString()}`
3224
+ ).then((payload) => payload.activity);
3225
+ }
3226
+ getCodingWorkItemStatus(workItemId, input3) {
3227
+ const query = new URLSearchParams({ teamId: input3.teamId });
3228
+ if (input3.limit !== void 0) query.set("limit", String(input3.limit));
3229
+ if (input3.includeArchived) query.set("includeArchived", "true");
3230
+ return this.requestApiRoot(
3231
+ `/work-items/${encodeURIComponent(workItemId)}/status?${query.toString()}`
3232
+ );
3233
+ }
3234
+ handleCodingWorkItemInBackground(workItemId, input3) {
3235
+ return this.requestApiRoot(
3236
+ `/work-items/${encodeURIComponent(workItemId)}/handle-background`,
3237
+ {
3238
+ method: "POST",
3239
+ body: JSON.stringify(input3)
3240
+ }
3241
+ );
3242
+ }
3243
+ promoteCodingWorkItemResult(workItemId, action, input3) {
3244
+ return this.requestApiRoot(
3245
+ `/work-items/${encodeURIComponent(workItemId)}/result/${action}`,
3246
+ {
3247
+ method: "POST",
3248
+ body: JSON.stringify(input3)
3249
+ }
3250
+ ).then((payload) => payload.artifact);
3251
+ }
3252
+ getMicrosoftTeamsBotOverview(input3) {
3253
+ const query = new URLSearchParams({ teamId: input3.teamId });
3254
+ return this.requestApiRoot(
3255
+ `/teams/bot/overview?${query.toString()}`
3256
+ );
3257
+ }
3258
+ bindMicrosoftTeamsBotConversation(input3) {
3259
+ return this.requestApiRoot(
3260
+ "/teams/bot/bindings",
3261
+ {
3262
+ method: "POST",
3263
+ body: JSON.stringify(input3)
3264
+ }
3265
+ );
3266
+ }
3267
+ rebindMicrosoftTeamsBotConversation(bindingId, input3) {
3268
+ return this.requestApiRoot(
3269
+ `/teams/bot/bindings/${encodeURIComponent(bindingId)}`,
3270
+ {
3271
+ method: "PATCH",
3272
+ body: JSON.stringify(input3)
3273
+ }
3274
+ );
3275
+ }
3276
+ unlinkMicrosoftTeamsBotConversation(input3) {
3277
+ return this.requestApiRoot(
3278
+ `/teams/bot/bindings/${encodeURIComponent(input3.bindingId)}`,
3279
+ {
3280
+ method: "DELETE",
3281
+ body: JSON.stringify({ teamId: input3.teamId })
3282
+ }
3283
+ );
3284
+ }
3285
+ sendMicrosoftTeamsBotDiagnostic(input3) {
3286
+ return this.requestApiRoot("/teams/bot/diagnostics", {
3287
+ method: "POST",
3288
+ body: JSON.stringify(input3)
3289
+ });
3290
+ }
3291
+ sendMicrosoftTeamsBotDiagnosticRun(input3) {
3292
+ return this.requestApiRoot(
3293
+ "/teams/bot/diagnostics/run",
3294
+ {
3295
+ method: "POST",
3296
+ body: JSON.stringify(input3)
3297
+ }
3298
+ );
3299
+ }
3300
+ createSandboxRuntime(input3) {
3301
+ return this.requestApiRoot("/runtimes", {
3302
+ method: "POST",
3303
+ body: JSON.stringify(input3)
3304
+ }).then((payload) => payload.runtime);
3305
+ }
3306
+ sandboxRuntime(runtimeId, initial = null) {
3307
+ return createSandboxRuntimeHandle(this, runtimeId, initial);
3308
+ }
3309
+ getSandboxRuntime(runtimeId) {
3310
+ return this.requestApiRoot(
3311
+ `/runtimes/${encodeURIComponent(runtimeId)}`
3312
+ ).then((payload) => payload.runtime);
3313
+ }
3314
+ createSandboxRuntimeSandbox(runtimeId, input3 = {}, options = {}) {
3315
+ return this.requestApiRoot(
3316
+ `/runtimes/${encodeURIComponent(runtimeId)}/sandbox`,
3317
+ {
3318
+ method: "POST",
3319
+ headers: asyncRequestHeaders(options),
3320
+ body: JSON.stringify(input3)
3321
+ }
3322
+ );
3323
+ }
3324
+ updateSandboxRuntimeStatus(runtimeId, input3) {
3325
+ return this.requestApiRoot(
3326
+ `/runtimes/${encodeURIComponent(runtimeId)}/status`,
3327
+ {
3328
+ method: "PATCH",
3329
+ body: JSON.stringify(input3)
3330
+ }
3331
+ ).then((payload) => payload.runtime);
3332
+ }
3333
+ listSandboxRuntimeEvents(runtimeId) {
3334
+ return this.requestApiRoot(
3335
+ `/runtimes/${encodeURIComponent(runtimeId)}/events`
3336
+ );
3337
+ }
3338
+ emitSandboxRuntimeEvent(runtimeId, input3) {
3339
+ return this.requestApiRoot(
3340
+ `/runtimes/${encodeURIComponent(runtimeId)}/events`,
3341
+ {
3342
+ method: "POST",
3343
+ body: JSON.stringify(input3)
3344
+ }
3345
+ );
3346
+ }
3347
+ checkpointSandboxRuntime(runtimeId, input3) {
3348
+ return this.requestApiRoot(
3349
+ `/runtimes/${encodeURIComponent(runtimeId)}/checkpoints`,
3350
+ {
3351
+ method: "POST",
3352
+ body: JSON.stringify(input3)
3353
+ }
3354
+ ).then((payload) => payload.runtime);
3355
+ }
3356
+ promoteSandboxRuntime(runtimeId, input3, options = {}) {
3357
+ const query = new URLSearchParams();
3358
+ if (options.teamId) query.set("teamId", options.teamId);
3359
+ return this.requestApiRoot(
3360
+ `/runtimes/${encodeURIComponent(runtimeId)}/promote${query.size > 0 ? `?${query.toString()}` : ""}`,
3361
+ {
3362
+ method: "POST",
3363
+ body: JSON.stringify(input3)
3364
+ }
3365
+ );
3366
+ }
3367
+ preserveSandboxRuntimeSource(runtimeId, input3 = {}, options = {}) {
3368
+ const query = new URLSearchParams();
3369
+ if (options.teamId) query.set("teamId", options.teamId);
3370
+ return this.requestApiRoot(
3371
+ `/runtimes/${encodeURIComponent(runtimeId)}/preserve-source${query.size > 0 ? `?${query.toString()}` : ""}`,
3372
+ {
3373
+ method: "POST",
3374
+ body: JSON.stringify(input3)
3375
+ }
3376
+ );
3377
+ }
3378
+ forkSnapshot(snapshotId, input3 = {}, options = {}) {
3379
+ const query = new URLSearchParams();
3380
+ if (input3.teamId) query.set("teamId", input3.teamId);
3381
+ if (input3.projectId) query.set("projectId", input3.projectId);
3382
+ if (options.async) query.set("async", "1");
3383
+ const { teamId: _teamId, projectId: _projectId, ...body } = input3;
3384
+ return this.request(
3385
+ `/catalog/snapshots/${encodeURIComponent(snapshotId)}/fork${query.size > 0 ? `?${query.toString()}` : ""}`,
3386
+ {
3387
+ method: "POST",
3388
+ headers: options.async ? { Prefer: "respond-async" } : void 0,
3389
+ body: JSON.stringify({
3390
+ ...body,
3391
+ snapshotId
3392
+ })
3393
+ }
3394
+ );
3395
+ }
3396
+ templates(input3 = {}) {
3397
+ const query = new URLSearchParams();
3398
+ if (input3.teamId) query.set("teamId", input3.teamId);
3399
+ if (input3.projectId) query.set("projectId", input3.projectId);
3400
+ if (input3.q) query.set("q", input3.q);
3401
+ if (input3.name) query.set("name", input3.name);
3402
+ if (input3.version) query.set("version", input3.version);
3403
+ if (input3.visibility) query.set("visibility", input3.visibility);
3404
+ if (input3.tag) query.set("tag", input3.tag);
3405
+ if (input3.useCase) query.set("useCase", input3.useCase);
3406
+ if (input3.limit) query.set("limit", String(input3.limit));
3407
+ return this.request(
3408
+ `/templates${query.size > 0 ? `?${query.toString()}` : ""}`
3409
+ );
3410
+ }
3411
+ publishedSnapshots(input3 = {}) {
3412
+ const query = new URLSearchParams();
3413
+ if (input3.teamId) query.set("teamId", input3.teamId);
3414
+ if (input3.projectId) query.set("projectId", input3.projectId);
3415
+ if (input3.q) query.set("q", input3.q);
3416
+ if (input3.name) query.set("name", input3.name);
3417
+ if (input3.version) query.set("version", input3.version);
3418
+ if (input3.visibility) query.set("visibility", input3.visibility);
3419
+ if (input3.tag) query.set("tag", input3.tag);
3420
+ if (input3.useCase) query.set("useCase", input3.useCase);
3421
+ if (input3.limit) query.set("limit", String(input3.limit));
3422
+ return this.request(
3423
+ `/published-snapshots${query.size > 0 ? `?${query.toString()}` : ""}`
3424
+ ).then((payload) => {
3425
+ const publishedSnapshots = payload.publishedSnapshots ?? payload.templates;
3426
+ return {
3427
+ ...payload,
3428
+ templates: publishedSnapshots,
3429
+ publishedSnapshots
3430
+ };
3431
+ });
3432
+ }
3433
+ launchTemplate(input3) {
3434
+ const query = new URLSearchParams();
3435
+ if (input3.teamId) query.set("teamId", input3.teamId);
3436
+ if (input3.projectId) query.set("projectId", input3.projectId);
3437
+ const { teamId: _teamId, projectId: _projectId, ...body } = input3;
3438
+ return this.request(
3439
+ `/templates/launch${query.size > 0 ? `?${query.toString()}` : ""}`,
3440
+ {
3441
+ method: "POST",
3442
+ body: JSON.stringify(body)
3443
+ }
3444
+ );
3445
+ }
3446
+ runPublishedSnapshot(input3) {
3447
+ const query = new URLSearchParams();
3448
+ if (input3.teamId) query.set("teamId", input3.teamId);
3449
+ if (input3.projectId) query.set("projectId", input3.projectId);
3450
+ const { teamId: _teamId, projectId: _projectId, ...body } = input3;
3451
+ return this.request(
3452
+ `/published-snapshots/launch${query.size > 0 ? `?${query.toString()}` : ""}`,
3453
+ {
3454
+ method: "POST",
3455
+ body: JSON.stringify(body)
3456
+ }
3457
+ ).then((payload) => {
3458
+ const publishedSnapshot = payload.publishedSnapshot ?? payload.template;
3459
+ return {
3460
+ ...payload,
3461
+ template: publishedSnapshot,
3462
+ publishedSnapshot
3463
+ };
3464
+ });
3465
+ }
3466
+ listSchedules(input3 = {}) {
3467
+ const query = new URLSearchParams();
3468
+ if (input3.teamId) query.set("teamId", input3.teamId);
3469
+ if (input3.projectId) query.set("projectId", input3.projectId);
3470
+ if (input3.sourceSandboxId)
3471
+ query.set("sourceSandboxId", input3.sourceSandboxId);
3472
+ return this.request(
3473
+ `/schedules${query.size > 0 ? `?${query.toString()}` : ""}`
3474
+ );
3475
+ }
3476
+ createSchedule(input3) {
3477
+ const query = new URLSearchParams();
3478
+ if (input3.projectId) query.set("projectId", input3.projectId);
3479
+ const { projectId: _projectId, ...body } = input3;
3480
+ return this.request(
3481
+ `/schedules${query.size > 0 ? `?${query.toString()}` : ""}`,
3482
+ {
3483
+ method: "POST",
3484
+ body: JSON.stringify(body)
3485
+ }
3486
+ );
3487
+ }
3488
+ getSchedule(scheduleId) {
3489
+ return this.request(
3490
+ `/schedules/${encodeURIComponent(scheduleId)}`
3491
+ );
3492
+ }
3493
+ updateSchedule(scheduleId, input3) {
3494
+ return this.request(
3495
+ `/schedules/${encodeURIComponent(scheduleId)}`,
3496
+ {
3497
+ method: "PATCH",
3498
+ body: JSON.stringify(input3)
3499
+ }
3500
+ );
3501
+ }
3502
+ deleteSchedule(scheduleId) {
3503
+ return this.request(
3504
+ `/schedules/${encodeURIComponent(scheduleId)}`,
3505
+ {
3506
+ method: "DELETE"
3507
+ }
3508
+ );
3509
+ }
3510
+ listScheduleRuns(scheduleId, input3 = {}) {
3511
+ const query = new URLSearchParams();
3512
+ if (input3.limit !== void 0) query.set("limit", String(input3.limit));
3513
+ return this.request(
3514
+ `/schedules/${encodeURIComponent(scheduleId)}/runs${query.size > 0 ? `?${query.toString()}` : ""}`
3515
+ );
3516
+ }
3517
+ runScheduleNow(scheduleId, input3 = {}) {
3518
+ return this.request(
3519
+ `/schedules/${encodeURIComponent(scheduleId)}/run`,
3520
+ {
3521
+ method: "POST",
3522
+ body: JSON.stringify(input3)
3523
+ }
3524
+ );
3525
+ }
3526
+ listTemplateBuilds(input3) {
3527
+ const query = new URLSearchParams({ teamId: input3.teamId });
3528
+ return this.requestApiRoot(
3529
+ `/sandbox-template-builds?${query.toString()}`
3530
+ ).then((payload) => payload.builds);
3531
+ }
3532
+ createTemplateBuild(input3) {
3533
+ return this.requestApiRoot(
3534
+ "/sandbox-template-builds",
3535
+ {
3536
+ method: "POST",
3537
+ body: JSON.stringify(input3)
3538
+ }
3539
+ ).then((payload) => payload.build);
3540
+ }
3541
+ getTemplateBuild(buildId) {
3542
+ return this.requestApiRoot(
3543
+ `/sandbox-template-builds/${encodeURIComponent(buildId)}`
3544
+ ).then((payload) => payload.build);
3545
+ }
3546
+ getTemplateBuildLogs(buildId) {
3547
+ return this.requestApiRoot(
3548
+ `/sandbox-template-builds/${encodeURIComponent(buildId)}/logs`
3549
+ );
3550
+ }
3551
+ cancelTemplateBuild(buildId) {
3552
+ return this.requestApiRoot(
3553
+ `/sandbox-template-builds/${encodeURIComponent(buildId)}/cancel`,
3554
+ {
3555
+ method: "POST"
3556
+ }
3557
+ ).then((payload) => payload.build);
3558
+ }
3559
+ listPublishedSnapshotBuilds(input3) {
3560
+ const query = new URLSearchParams({ teamId: input3.teamId });
3561
+ return this.requestApiRoot(
3562
+ `/published-snapshot-builds?${query.toString()}`
3563
+ ).then((payload) => payload.builds);
3564
+ }
3565
+ createPublishedSnapshotBuild(input3) {
3566
+ return this.requestApiRoot(
3567
+ "/published-snapshot-builds",
3568
+ {
3569
+ method: "POST",
3570
+ body: JSON.stringify(input3)
3571
+ }
3572
+ ).then((payload) => payload.build);
3573
+ }
3574
+ getPublishedSnapshotBuild(buildId) {
3575
+ return this.requestApiRoot(
3576
+ `/published-snapshot-builds/${encodeURIComponent(buildId)}`
3577
+ ).then((payload) => payload.build);
3578
+ }
3579
+ getPublishedSnapshotBuildLogs(buildId) {
3580
+ return this.requestApiRoot(
3581
+ `/published-snapshot-builds/${encodeURIComponent(buildId)}/logs`
3582
+ );
3583
+ }
3584
+ cancelPublishedSnapshotBuild(buildId) {
3585
+ return this.requestApiRoot(
3586
+ `/published-snapshot-builds/${encodeURIComponent(buildId)}/cancel`,
3587
+ {
3588
+ method: "POST"
3589
+ }
3590
+ ).then((payload) => payload.build);
3591
+ }
3592
+ listOrganizations() {
3593
+ return this.requestApiRoot(
3594
+ "/organizations"
3595
+ ).then((payload) => payload.organizations ?? payload.teams ?? []);
3596
+ }
3597
+ createOrganization(input3) {
3598
+ return this.requestApiRoot("/organizations", {
3599
+ method: "POST",
3600
+ body: JSON.stringify(input3)
3601
+ }).then((payload) => payload.organization);
3602
+ }
3603
+ getOrganization(slug) {
3604
+ return this.requestApiRoot(
3605
+ `/organizations/${encodeURIComponent(slug)}`
3606
+ ).then((payload) => payload.organization);
3607
+ }
3608
+ updateOrganization(slug, input3) {
3609
+ return this.requestApiRoot(
3610
+ `/organizations/${encodeURIComponent(slug)}`,
3611
+ {
3612
+ method: "PATCH",
3613
+ body: JSON.stringify(input3)
3614
+ }
3615
+ ).then((payload) => payload.organization);
3616
+ }
3617
+ listOrganizationMembers(slug) {
3618
+ return this.requestApiRoot(
3619
+ `/organizations/${encodeURIComponent(slug)}/members`
3620
+ ).then((payload) => payload.members);
3621
+ }
3622
+ upsertOrganizationMember(slug, input3) {
3623
+ return this.requestApiRoot(
3624
+ `/organizations/${encodeURIComponent(slug)}/members`,
3625
+ {
3626
+ method: "POST",
3627
+ body: JSON.stringify(input3)
3628
+ }
3629
+ ).then((payload) => payload.member);
3630
+ }
3631
+ getOrganizationMcpServer(slug) {
3632
+ return this.requestApiRoot(
3633
+ `/organizations/${encodeURIComponent(slug)}/mcp-server`
3634
+ ).then((payload) => payload.mcpServer);
3635
+ }
3636
+ generateOrganizationMcpServer(slug, input3 = {}) {
3637
+ return this.requestApiRoot(
3638
+ `/organizations/${encodeURIComponent(slug)}/mcp-server`,
3639
+ {
3640
+ method: "POST",
3641
+ body: JSON.stringify(input3)
3642
+ }
3643
+ ).then((payload) => payload.mcpServer);
3644
+ }
3645
+ rotateOrganizationMcpServer(slug) {
3646
+ return this.requestApiRoot(
3647
+ `/organizations/${encodeURIComponent(slug)}/mcp-server/rotate`,
3648
+ {
3649
+ method: "POST"
3650
+ }
3651
+ ).then((payload) => payload.mcpServer);
3652
+ }
3653
+ disableOrganizationMcpServer(slug) {
3654
+ return this.requestApiRoot(
3655
+ `/organizations/${encodeURIComponent(slug)}/mcp-server/disable`,
3656
+ {
3657
+ method: "POST"
3658
+ }
3659
+ ).then((payload) => payload.mcpServer);
3660
+ }
3661
+ enableOrganizationMcpServer(slug) {
3662
+ return this.requestApiRoot(
3663
+ `/organizations/${encodeURIComponent(slug)}/mcp-server/enable`,
3664
+ {
3665
+ method: "POST"
3666
+ }
3667
+ ).then((payload) => payload.mcpServer);
3668
+ }
3669
+ startReplay(input3) {
3670
+ const query = new URLSearchParams();
3671
+ if (input3.teamId) query.set("teamId", input3.teamId);
3672
+ if (input3.projectId) query.set("projectId", input3.projectId);
3673
+ const { teamId: _teamId, projectId: _projectId, ...body } = input3;
3674
+ return this.requestApiRoot(
3675
+ `/sandbox-replays${query.size > 0 ? `?${query.toString()}` : ""}`,
3676
+ {
3677
+ method: "POST",
3678
+ body: JSON.stringify(body)
3679
+ }
3680
+ );
3681
+ }
3682
+ listReplays(input3 = {}) {
3683
+ const query = new URLSearchParams();
3684
+ if (input3.teamId) query.set("teamId", input3.teamId);
3685
+ if (input3.projectId) query.set("projectId", input3.projectId);
3686
+ return this.requestApiRoot(
3687
+ `/sandbox-replays${query.size > 0 ? `?${query.toString()}` : ""}`
3688
+ );
3689
+ }
3690
+ getReplay(replayId, input3 = {}) {
3691
+ const query = new URLSearchParams();
3692
+ if (input3.teamId) query.set("teamId", input3.teamId);
3693
+ if (input3.projectId) query.set("projectId", input3.projectId);
3694
+ return this.requestApiRoot(
3695
+ `/sandbox-replays/${encodeURIComponent(replayId)}${query.size > 0 ? `?${query.toString()}` : ""}`
3696
+ );
3697
+ }
3698
+ getReplayLogs(replayId, input3 = {}) {
3699
+ const query = new URLSearchParams();
3700
+ if (input3.teamId) query.set("teamId", input3.teamId);
3701
+ if (input3.projectId) query.set("projectId", input3.projectId);
3702
+ return this.requestApiRoot(
3703
+ `/sandbox-replays/${encodeURIComponent(replayId)}/logs${query.size > 0 ? `?${query.toString()}` : ""}`
3704
+ );
3705
+ }
3706
+ getReplayArtifacts(replayId, input3 = {}) {
3707
+ const query = new URLSearchParams();
3708
+ if (input3.teamId) query.set("teamId", input3.teamId);
3709
+ if (input3.projectId) query.set("projectId", input3.projectId);
3710
+ return this.requestApiRoot(
3711
+ `/sandbox-replays/${encodeURIComponent(replayId)}/artifacts${query.size > 0 ? `?${query.toString()}` : ""}`
3712
+ );
3713
+ }
3714
+ cancelReplay(replayId, input3 = {}) {
3715
+ const query = new URLSearchParams();
3716
+ if (input3.teamId) query.set("teamId", input3.teamId);
3717
+ if (input3.projectId) query.set("projectId", input3.projectId);
3718
+ return this.requestApiRoot(
3719
+ `/sandbox-replays/${encodeURIComponent(replayId)}/cancel${query.size > 0 ? `?${query.toString()}` : ""}`,
3720
+ {
3721
+ method: "POST"
3722
+ }
3723
+ );
3724
+ }
3725
+ integrationConnections(input3 = {}) {
3726
+ const query = new URLSearchParams();
3727
+ if (input3.teamId) query.set("teamId", input3.teamId);
3728
+ if (input3.projectId) query.set("projectId", input3.projectId);
3729
+ if (input3.agentId) query.set("agentId", input3.agentId);
3730
+ if (input3.status) query.set("status", input3.status);
3731
+ return this.requestApiRoot(
3732
+ `/integrations/connections${query.size > 0 ? `?${query.toString()}` : ""}`
3733
+ );
3734
+ }
3735
+ mcpServerConfig() {
3736
+ return {
3737
+ name: "openpond-sandboxes",
3738
+ transport: "streamable-http",
3739
+ url: `${this.sandboxApiUrl}/mcp`,
3740
+ headers: {
3741
+ "openpond-api-key": this.apiKey
3742
+ }
3743
+ };
3744
+ }
3745
+ smoke(options = {}) {
3746
+ return runSandboxSmoke(this, options);
3747
+ }
3748
+ };
3749
+ function createOpenPondSandboxClient(options) {
3750
+ return new OpenPondSandboxClient(options);
3751
+ }
3752
+
3753
+ // ../../packages/cloud/src/sandbox/types/runtime-profiles.ts
3754
+ var SANDBOX_RUNTIME_PROFILE_IDS = [
3755
+ "openpond-coding-core-v1"
3756
+ ];
3757
+
3758
+ // src/cli/common/sandbox-options.ts
3759
+ var SANDBOX_WORKFLOW_MODES = [
3760
+ "readonly",
3761
+ "attempt",
3762
+ "feature",
3763
+ "rollout",
3764
+ "replay",
3765
+ "template_build",
3766
+ "scheduled_run",
3767
+ "patch_only",
3768
+ "hotfix",
3769
+ "multi_feature_batch"
3770
+ ];
3771
+ var SANDBOX_RUNTIME_PROMOTION_POLICIES = ["none", "manual", "auto_after_checks"];
3772
+ var SANDBOX_RUNTIME_PROFILES = [
3773
+ ...SANDBOX_RUNTIME_PROFILE_IDS
3774
+ ];
3775
+ function resolveSandboxBaseUrl(config, options) {
3776
+ const envName = typeof options.env === "string" ? options.env.trim().toLowerCase() : typeof options.environment === "string" ? options.environment.trim().toLowerCase() : "";
3777
+ if (envName === "staging") {
3778
+ return "https://api-new.staging-api.openpond.ai";
3779
+ }
3780
+ if (envName && envName !== "production") {
3781
+ throw new Error("sandbox env must be staging or production");
3782
+ }
3783
+ const base = process.env.OPENPOND_SANDBOX_BASE_URL || process.env.OPENPOND_API_URL || config.apiBaseUrl || mapUiBaseToApiBase(process.env.OPENPOND_BASE_URL || config.baseUrl) || DEFAULT_OPENPOND_API_BASE_URL;
3784
+ return base.replace(/\/$/, "");
3785
+ }
3786
+ async function resolveSandboxClient(options) {
3787
+ const config = await loadConfig();
3788
+ const uiBase = resolveBaseUrl(config);
3789
+ const apiKey = await ensureApiKey(config, uiBase);
3790
+ const sandboxApiUrl = resolveSandboxApiUrlOption(options) || process.env.OPENPOND_SANDBOX_API_URL?.trim() || null;
3791
+ return createOpenPondSandboxClient(
3792
+ sandboxApiUrl ? { apiKey, sandboxApiUrl } : { apiKey, baseUrl: resolveSandboxBaseUrl(config, options) }
3793
+ );
3794
+ }
3795
+ function parseSandboxWorkflowModeOption(value) {
3796
+ if (value === void 0) return void 0;
3797
+ if (typeof value !== "string" || !value.trim()) {
3798
+ throw new Error("workflow-mode must be a non-empty value");
3799
+ }
3800
+ const mode = value.trim();
3801
+ if (!SANDBOX_WORKFLOW_MODES.includes(mode)) {
3802
+ throw new Error(
3803
+ `workflow-mode must be one of ${SANDBOX_WORKFLOW_MODES.join(", ")}`
3804
+ );
3805
+ }
3806
+ return mode;
3807
+ }
3808
+ function parseSandboxRuntimePromotionPolicyOption(value) {
3809
+ if (value === void 0) return void 0;
3810
+ if (typeof value !== "string" || !value.trim()) {
3811
+ throw new Error("runtime-promotion-policy must be a non-empty value");
3812
+ }
3813
+ const policy = value.trim();
3814
+ if (!SANDBOX_RUNTIME_PROMOTION_POLICIES.includes(policy)) {
3815
+ throw new Error(
3816
+ `runtime-promotion-policy must be one of ${SANDBOX_RUNTIME_PROMOTION_POLICIES.join(
3817
+ ", "
3818
+ )}`
3819
+ );
3820
+ }
3821
+ return policy;
3822
+ }
3823
+ function parseSandboxRuntimeProfileIdOption(value) {
3824
+ if (typeof value !== "string" || !value.trim()) return void 0;
3825
+ const runtimeProfileId = value.trim();
3826
+ if (!SANDBOX_RUNTIME_PROFILES.includes(runtimeProfileId)) {
3827
+ throw new Error(
3828
+ `runtime-profile-id must be one of ${SANDBOX_RUNTIME_PROFILES.join(
3829
+ ", "
3830
+ )}`
3831
+ );
3832
+ }
3833
+ return runtimeProfileId;
3834
+ }
3835
+ function parseSandboxEnvOptions(options) {
3836
+ const refs = parseSandboxEnvAssignments(options.envRef, "env-ref").map(
3837
+ ({ name, value }) => ({ name, secretRef: value })
3838
+ );
3839
+ const literals = parseSandboxEnvAssignments(
3840
+ options.envLiteral,
3841
+ "env-literal"
3842
+ ).map(({ name, value }) => {
3843
+ if (isSecretLikeEnvName(name) && !parseBooleanOption(options.allowPlainSecretEnv)) {
3844
+ throw new Error(
3845
+ `refusing plaintext value for secret-like env ${name}; create a sandbox secret and pass --env-ref ${name}=openpond://secret/...`
3846
+ );
3847
+ }
3848
+ return { name, value };
3849
+ });
3850
+ const env = [...refs, ...literals];
3851
+ const names = /* @__PURE__ */ new Set();
3852
+ for (const item of env) {
3853
+ if (names.has(item.name)) {
3854
+ throw new Error(`duplicate sandbox env var: ${item.name}`);
3855
+ }
3856
+ names.add(item.name);
3857
+ }
3858
+ return env;
3859
+ }
3860
+ function parseSandboxTemplateEnvOptions(manifest, options) {
3861
+ const env = parseSandboxEnvOptions(options);
3862
+ const provided = new Set(env.map((item) => item.name));
3863
+ const providedByName = new Map(env.map((item) => [item.name, item]));
3864
+ for (const requirement of manifest.inputs.env) {
3865
+ const value = providedByName.get(requirement.name);
3866
+ if (value?.value !== void 0 && requirement.secret !== false) {
3867
+ throw new Error(
3868
+ `sandbox template env ${requirement.name} requires a secret ref. Pass --env-ref ${requirement.name}=openpond://secret/...`
3869
+ );
3870
+ }
3871
+ }
3872
+ const missing = manifest.inputs.env.filter((item) => item.required && !provided.has(item.name)).map((item) => item.name);
3873
+ if (missing.length > 0) {
3874
+ throw new Error(
3875
+ `missing required sandbox template env refs: ${missing.join(
3876
+ ", "
3877
+ )}. Pass --env-ref NAME=openpond://secret/...`
3878
+ );
3879
+ }
3880
+ return env;
3881
+ }
3882
+ function parseSandboxEnvAssignments(value, label) {
3883
+ if (typeof value !== "string") return [];
3884
+ return value.split(",").map((item) => item.trim()).filter(Boolean).map((item) => {
3885
+ const separator = item.indexOf("=");
3886
+ if (separator <= 0) {
3887
+ throw new Error(`${label} entries must use NAME=value`);
3888
+ }
3889
+ const name = item.slice(0, separator).trim();
3890
+ const entryValue = item.slice(separator + 1).trim();
3891
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name)) {
3892
+ throw new Error(`${label} has invalid env name: ${name}`);
3893
+ }
3894
+ if (!entryValue) {
3895
+ throw new Error(`${label} value is required for ${name}`);
3896
+ }
3897
+ return { name, value: entryValue };
3898
+ });
3899
+ }
3900
+ function isSecretLikeEnvName(name) {
3901
+ return /(?:SECRET|TOKEN|KEY|PASSWORD|PASSWD|PRIVATE|CREDENTIAL|DATABASE_URL|DSN)/i.test(
3902
+ name
3903
+ );
3904
+ }
3905
+ async function readSandboxSecretValue(options, label) {
3906
+ if (typeof options.value === "string" || typeof options.secretValue === "string") {
3907
+ throw new Error(
3908
+ "sandbox secret values must be provided with --stdin or the masked prompt"
3909
+ );
3910
+ }
3911
+ const useStdin = parseBooleanOption(options.stdin);
3912
+ if (useStdin) {
3913
+ const value2 = await readAllStdin();
3914
+ if (!value2) throw new Error(`${label} read no secret value from stdin`);
3915
+ return value2;
3916
+ }
3917
+ if (!process.stdin.isTTY) {
3918
+ throw new Error(`${label} requires --stdin when not running in a TTY`);
3919
+ }
3920
+ const value = await readMaskedLine(`${label}: `);
3921
+ if (!value) throw new Error(`${label} cannot be empty`);
3922
+ return value;
3923
+ }
3924
+ function summarizeSandboxSecret(secret) {
3925
+ return {
3926
+ id: secret.id,
3927
+ teamId: secret.teamId,
3928
+ name: secret.name,
3929
+ scope: secret.scope,
3930
+ status: secret.status,
3931
+ secretRef: secret.secretRef,
3932
+ currentVersion: secret.currentVersion,
3933
+ updatedAt: secret.updatedAt,
3934
+ lastUsedAt: secret.lastUsedAt,
3935
+ attachedDestinations: secret.attachments?.length ?? 0
3936
+ };
3937
+ }
3938
+
3939
+ // src/process-runner.ts
3940
+ import { Buffer as Buffer2 } from "node:buffer";
3941
+ import { spawn } from "node:child_process";
3942
+ var DEFAULT_PROCESS_TIMEOUT_MS = 10 * 60 * 1e3;
3943
+ var DEFAULT_PROCESS_MAX_OUTPUT_BYTES = 2 * 1024 * 1024;
3944
+ function runProcessCommand(command, args = [], options = {}) {
3945
+ if (options.inherit && options.terminateWhenStdoutIncludes !== void 0) {
3946
+ return Promise.reject(new Error("terminateWhenStdoutIncludes requires captured stdout"));
3947
+ }
3948
+ if (options.terminateWhenStdoutIncludes === "") {
3949
+ return Promise.reject(new Error("terminateWhenStdoutIncludes must not be empty"));
3950
+ }
3951
+ return new Promise((resolve, reject) => {
3952
+ const proc = spawn(command, args, {
3953
+ cwd: options.cwd,
3954
+ env: options.env ? { ...process.env, ...options.env } : void 0,
3955
+ shell: options.shell,
3956
+ detached: options.detached ?? process.platform !== "win32",
3957
+ stdio: options.inherit ? "inherit" : [options.stdin === void 0 ? "ignore" : "pipe", "pipe", "pipe"]
3958
+ });
3959
+ const stdout = new BoundedOutput(maxOutputBytes(options));
3960
+ const stderr = new BoundedOutput(maxOutputBytes(options));
3961
+ let timedOut = false;
3962
+ const timeoutMs = options.timeoutMs ?? DEFAULT_PROCESS_TIMEOUT_MS;
3963
+ let timeout;
3964
+ let forceKill;
3965
+ let requestedTermination = null;
3966
+ let settled = false;
3967
+ const clearTimers = () => {
3968
+ if (timeout) clearTimeout(timeout);
3969
+ if (forceKill) clearTimeout(forceKill);
3970
+ };
3971
+ const requestTermination = (reason) => {
3972
+ if (requestedTermination !== null || settled) return;
3973
+ requestedTermination = reason;
3974
+ timedOut = reason === "timeout";
3975
+ if (timeout) {
3976
+ clearTimeout(timeout);
3977
+ timeout = void 0;
3978
+ }
3979
+ terminateProcessTree(proc.pid, "SIGTERM");
3980
+ forceKill = setTimeout(() => {
3981
+ if (proc.exitCode === null && proc.signalCode === null) terminateProcessTree(proc.pid, "SIGKILL");
3982
+ }, 5e3);
3983
+ };
3984
+ if (timeoutMs > 0) {
3985
+ timeout = setTimeout(() => {
3986
+ requestTermination("timeout");
3987
+ }, timeoutMs);
3988
+ }
3989
+ if (!options.inherit) {
3990
+ proc.stdout?.on("data", (chunk) => {
3991
+ stdout.append(chunk);
3992
+ const marker = options.terminateWhenStdoutIncludes;
3993
+ if (marker !== void 0 && stdout.text().includes(marker)) {
3994
+ requestTermination("output");
3995
+ }
3996
+ });
3997
+ proc.stderr?.on("data", (chunk) => {
3998
+ stderr.append(chunk);
3999
+ });
4000
+ }
4001
+ proc.on("error", (error) => {
4002
+ clearTimers();
4003
+ settled = true;
4004
+ reject(error);
4005
+ });
4006
+ proc.on("close", (code, signal) => {
4007
+ if (settled) return;
4008
+ settled = true;
4009
+ clearTimers();
4010
+ resolve({
4011
+ code,
4012
+ signal,
4013
+ terminationReason: requestedTermination ?? (signal ? "signal" : "exit"),
4014
+ stdout: stdout.text(),
4015
+ stderr: stderr.text(),
4016
+ timedOut,
4017
+ stdoutTruncated: stdout.truncated,
4018
+ stderrTruncated: stderr.truncated
4019
+ });
4020
+ });
4021
+ if (options.stdin !== void 0) {
4022
+ proc.stdin?.end(options.stdin);
4023
+ }
4024
+ });
4025
+ }
4026
+ var BoundedOutput = class {
4027
+ #chunks = [];
4028
+ #maxBytes;
4029
+ #bytes = 0;
4030
+ truncated = false;
4031
+ constructor(maxBytes) {
4032
+ this.#maxBytes = maxBytes;
4033
+ }
4034
+ append(value) {
4035
+ const chunk = Buffer2.isBuffer(value) ? value : Buffer2.from(value);
4036
+ const remaining = this.#maxBytes - this.#bytes;
4037
+ if (remaining <= 0) {
4038
+ if (chunk.byteLength > 0) this.truncated = true;
4039
+ return;
4040
+ }
4041
+ if (chunk.byteLength <= remaining) {
4042
+ this.#chunks.push(chunk);
4043
+ this.#bytes += chunk.byteLength;
4044
+ return;
4045
+ }
4046
+ this.#chunks.push(chunk.subarray(0, remaining));
4047
+ this.#bytes += remaining;
4048
+ this.truncated = true;
4049
+ }
4050
+ text() {
4051
+ const value = Buffer2.concat(this.#chunks, this.#bytes).toString("utf8");
4052
+ return this.truncated ? `${value}
4053
+ [truncated after ${this.#maxBytes} bytes]
4054
+ ` : value;
4055
+ }
4056
+ };
4057
+ function maxOutputBytes(options) {
4058
+ const value = options.maxOutputBytes ?? DEFAULT_PROCESS_MAX_OUTPUT_BYTES;
4059
+ return Math.max(0, Math.floor(value));
4060
+ }
4061
+ function terminateProcessTree(pid, signal) {
4062
+ if (!pid) return;
4063
+ if (process.platform === "win32") {
4064
+ const args = ["/PID", String(pid), "/T"];
4065
+ if (signal === "SIGKILL") args.push("/F");
4066
+ const killer = spawn("taskkill", args, { stdio: "ignore", windowsHide: true });
4067
+ killer.unref();
4068
+ return;
4069
+ }
4070
+ try {
4071
+ process.kill(-pid, signal);
4072
+ } catch (error) {
4073
+ if (error.code !== "ESRCH") throw error;
4074
+ }
4075
+ }
4076
+
4077
+ // src/cli/common/shell.ts
4078
+ async function runCommand(command, args, options = {}) {
4079
+ return runProcessCommand(command, args, {
4080
+ cwd: options.cwd,
4081
+ inherit: options.inherit,
4082
+ timeoutMs: options.timeoutMs,
4083
+ maxOutputBytes: options.maxOutputBytes,
4084
+ terminateWhenStdoutIncludes: options.terminateWhenStdoutIncludes
4085
+ });
4086
+ }
4087
+ async function runShellCommand(command, options = {}) {
4088
+ const timeoutMs = options.timeoutSeconds === void 0 ? void 0 : options.timeoutSeconds * 1e3;
4089
+ return runProcessCommand(command, [], {
4090
+ cwd: options.cwd,
4091
+ env: options.env,
4092
+ shell: true,
4093
+ inherit: options.inherit,
4094
+ timeoutMs,
4095
+ maxOutputBytes: options.maxOutputBytes
4096
+ });
4097
+ }
4098
+ async function getGitRemoteUrl(cwd, remoteName) {
4099
+ const result = await runCommand("git", ["remote", "get-url", remoteName], {
4100
+ cwd
4101
+ });
4102
+ if (result.code !== 0) return null;
4103
+ const url = result.stdout.trim();
4104
+ return url.length > 0 ? url : null;
4105
+ }
4106
+
4107
+ export {
4108
+ apiFetch,
4109
+ readApiJson,
4110
+ deployApp,
4111
+ getLatestDeploymentForApp,
4112
+ getDeploymentDetail,
4113
+ createRepo,
4114
+ updateAppCodeVisibility,
4115
+ createHeadlessApps,
4116
+ getTemplateStatus,
4117
+ listTemplateBranches,
4118
+ deployLatestTemplate,
4119
+ updateAppEnvironment,
4120
+ getAppEnvironment,
4121
+ createAgentFromPrompt,
4122
+ getUserPerformance,
4123
+ getAppRuntimeSummary,
4124
+ getOpenPondAccount,
4125
+ checkOpenPondApiHealth,
4126
+ runAssistantMode,
4127
+ executeUserTool,
4128
+ submitPositionsTx,
4129
+ submitBacktestRun,
4130
+ submitBacktestTx,
4131
+ submitBacktestDetail,
4132
+ executeHostedTool,
4133
+ writePrivateJsonFile,
4134
+ loadGlobalConfig,
4135
+ loadConfig,
4136
+ listConfiguredProfiles,
4137
+ setActiveProfile,
4138
+ saveProfileApiKey,
4139
+ saveGlobalConfig,
4140
+ resolveApiKey,
4141
+ promptForApiKey,
4142
+ ensureApiKey,
4143
+ resolveRepoUrl,
4144
+ formatTokenizedRepoUrl,
4145
+ formatTokenizedRepoUrlForPrint,
4146
+ redactToken,
4147
+ warnOnRepoHostMismatch,
4148
+ normalizeRepoName,
4149
+ fetchAppsWithCache,
4150
+ fetchToolsWithCache,
4151
+ resolveAppTarget,
4152
+ pollDeploymentLogs,
4153
+ promptConfirm,
4154
+ promptForPath,
4155
+ resolveSandboxClient,
4156
+ parseSandboxWorkflowModeOption,
4157
+ parseSandboxRuntimePromotionPolicyOption,
4158
+ parseSandboxRuntimeProfileIdOption,
4159
+ parseSandboxEnvOptions,
4160
+ parseSandboxTemplateEnvOptions,
4161
+ readSandboxSecretValue,
4162
+ summarizeSandboxSecret,
4163
+ runProcessCommand,
4164
+ runCommand,
4165
+ runShellCommand,
4166
+ getGitRemoteUrl
4167
+ };