openpond 0.0.38 → 0.0.39

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 (212) hide show
  1. package/README.md +3 -4
  2. package/dist/api/core.d.ts +6 -0
  3. package/dist/api/vercel-protection.d.ts +1 -0
  4. package/dist/chunks/{app-layer-DPUJRNO2.js → app-layer-LTBWNA2F.js} +32 -10
  5. package/dist/chunks/app-server-runtime-VYYJ2AWX.js +18 -0
  6. package/dist/chunks/{apps-AKBI6AS7.js → apps-CZAJBGE3.js} +6 -4
  7. package/dist/chunks/{chunk-LZZM3IHS.js → chunk-2SF6HLT7.js} +5899 -5939
  8. package/dist/chunks/{chunk-XCATKTK3.js → chunk-3CDPPVLE.js} +108 -66
  9. package/dist/chunks/{chunk-JWF37O5E.js → chunk-3HW6OSHP.js} +1 -3
  10. package/dist/chunks/{chunk-43YI36NA.js → chunk-3KLQ52B2.js} +228 -5
  11. package/dist/chunks/chunk-4HIWFIMN.js +37172 -0
  12. package/dist/chunks/{chunk-AHPQTEIJ.js → chunk-4N6E3OVF.js} +4 -4
  13. package/dist/chunks/{chunk-YTJL6XPU.js → chunk-6V7MJVRO.js} +56 -11
  14. package/dist/chunks/{chunk-QRM7XMAO.js → chunk-BQQZNGI6.js} +152 -161
  15. package/dist/chunks/chunk-DBHSOTYZ.js +1552 -0
  16. package/dist/chunks/{chunk-275WCETC.js → chunk-FCVVOMIP.js} +145 -5
  17. package/dist/chunks/{chunk-GB6VUZUA.js → chunk-JIEUB6OS.js} +1 -1
  18. package/dist/chunks/{chunk-HS2AGRDV.js → chunk-JJPAMKXZ.js} +1 -1
  19. package/dist/chunks/{chunk-GDZYDLEL.js → chunk-JRROTGQT.js} +1 -110
  20. package/dist/chunks/chunk-KHNHUA2H.js +1737 -0
  21. package/dist/chunks/{chunk-AHNFNWUN.js → chunk-L6XH4ZGZ.js} +1 -1
  22. package/dist/chunks/chunk-M2NXTLH2.js +4054 -0
  23. package/dist/chunks/{chunk-SLMP353Q.js → chunk-MIZHCABO.js} +2 -195
  24. package/dist/chunks/chunk-SMNFI2FU.js +113 -0
  25. package/dist/chunks/chunk-VCVQLECH.js +675 -0
  26. package/dist/chunks/{chunk-V35STJF4.js → chunk-ZJBJQCQZ.js} +179 -52
  27. package/dist/chunks/{cli-7BKDWFNU.js → cli-JS76LCW2.js} +9 -5
  28. package/dist/chunks/{core-commands-YN4RMWA3.js → core-commands-4MRJQZJV.js} +7 -5
  29. package/dist/chunks/{harness-BHQRMXJR.js → desktop-test-RNMWLOVU.js} +15 -14
  30. package/dist/chunks/{chunk-XERQHYBO.js → extension-GDRW22N3.js} +5868 -3580
  31. package/dist/chunks/{help-VREQNA4I.js → help-LWNREJ7U.js} +1 -1
  32. package/dist/chunks/{opchat-D63YTNSX.js → opchat-2K2JIGK3.js} +9 -10
  33. package/dist/chunks/{organizations-I46KG7TC.js → organizations-Z5HVD2E7.js} +11 -9
  34. package/dist/chunks/{profile-WKZJHEPG.js → profile-QNECVVGN.js} +12 -38
  35. package/dist/chunks/{project-agent-ZUC3YMCT.js → project-agent-W3V75WBR.js} +9 -411
  36. package/dist/chunks/{sandbox-command-AAOPFTI5.js → sandbox-command-X3FO74NX.js} +7 -5
  37. package/dist/chunks/{sandbox-template-GKNVR4C5.js → sandbox-template-5B4T4BGU.js} +8 -6
  38. package/dist/chunks/{src-RPW5TOPI.js → src-ESAILPUH.js} +32 -30
  39. package/dist/chunks/src-IC5RX4L6.js +63517 -0
  40. package/dist/chunks/{teams-bot-PSL3ZO6Z.js → teams-bot-NTQ6VFFL.js} +6 -4
  41. package/dist/chunks/training-BR5A7SPU.js +320 -0
  42. package/dist/chunks/{workspaces-BPXC2DHT.js → workspaces-XC3QBD2Y.js} +2 -2
  43. package/dist/cli.js +24 -12
  44. package/dist/config.d.ts +9 -3
  45. package/dist/index.js +1300 -1045
  46. package/dist/profile/local-profile-types.d.ts +16 -0
  47. package/dist/profile/local-profile.d.ts +50 -4
  48. package/dist/sandbox/client-handles.d.ts +33 -46
  49. package/dist/sandbox/client.d.ts +4 -26
  50. package/dist/sandbox/sandbox-instance-client.d.ts +5 -5
  51. package/dist/sandbox/types/client.d.ts +1 -2
  52. package/dist/sandbox/types/core.d.ts +0 -1
  53. package/dist/sandbox/types/org-project-agent.d.ts +3 -89
  54. package/dist/sandbox/types/record.d.ts +1 -2
  55. package/dist/sandbox/types/runtime-profiles.d.ts +2 -2
  56. package/dist/sandbox-template/manifest.d.ts +1 -1
  57. package/dist/skills/openpond-agent-authoring/SKILL.md +40 -0
  58. package/dist/skills/openpond-agent-authoring/references/action-and-chat-design.md +13 -0
  59. package/dist/skills/openpond-agent-authoring/references/integrations-and-setup.md +13 -0
  60. package/dist/skills/openpond-agent-authoring/references/profile-layout.md +29 -0
  61. package/dist/skills/openpond-agent-authoring/references/validation-and-repair.md +14 -0
  62. package/dist/skills/openpond-desktop-harness/SKILL.md +1 -1
  63. package/dist/skills/openpond-skill-authoring/SKILL.md +44 -0
  64. package/dist/skills/openpond-skill-authoring/references/copying-and-adaptation.md +16 -0
  65. package/dist/skills/openpond-skill-authoring/references/skill-package-layout.md +38 -0
  66. package/dist/skills/openpond-skill-authoring/references/validation-and-repair.md +24 -0
  67. package/dist/skills/openpond-skill-authoring/scripts/validate-skill.mjs +102 -0
  68. package/dist/skills/openpond-taskset-authoring/SKILL.md +64 -22
  69. package/dist/skills/openpond-taskset-authoring/artifact.json +39 -0
  70. package/dist/skills/openpond-taskset-authoring/references/graders-and-rewards.md +3 -0
  71. package/dist/skills/openpond-taskset-authoring/references/method-selection.md +1 -1
  72. package/dist/skills/openpond-taskset-authoring/references/privacy-and-provenance.md +2 -0
  73. package/dist/skills/openpond-taskset-authoring/references/task-design.md +32 -0
  74. package/dist/web/assets/{AppDialog-DrwJb_wG.js → AppDialog-Bua3f-6v.js} +1 -1
  75. package/dist/web/assets/{AppsView-DPagLMsc.js → AppsView-DrJkHeSO.js} +1 -1
  76. package/dist/web/assets/BrowserSidebar-Bf-4Vozm.js +1 -0
  77. package/dist/web/assets/CommandMenu-DDZlGQiB.js +1 -0
  78. package/dist/web/assets/CommunityView-BtcCrba7.js +1 -0
  79. package/dist/web/assets/ComposerCreateImproveStrip-DOe5Otg6.js +1 -0
  80. package/dist/web/assets/GetStartedView-CG4z0Dtw.js +1 -0
  81. package/dist/web/assets/GetStartedView-yVmnGZPw.css +1 -0
  82. package/dist/web/assets/LabModelVersionDetailPage-BEkmSKuv.js +1 -0
  83. package/dist/web/assets/LabSkillSidebar-BIotN_RB.js +1 -0
  84. package/dist/web/assets/LabsRoute-CfOe0Zt5.js +3 -0
  85. package/dist/web/assets/LabsRoute-CoSPO4HR.css +1 -0
  86. package/dist/web/assets/MainChatThread-C0-l1mHt.js +2 -0
  87. package/dist/web/assets/MainPane-Bky_Rqcx.css +1 -0
  88. package/dist/web/assets/MainPane-aOVlVyRK.js +6 -0
  89. package/dist/web/assets/MarkdownText-D7DT1k1k.js +9 -0
  90. package/dist/web/assets/Messages-CBIXruA9.js +9 -0
  91. package/dist/web/assets/NativeSkillSidebar-C4t69Y7B.js +1 -0
  92. package/dist/web/assets/NewProjectDialog-Bat65tYD.js +1 -0
  93. package/dist/web/assets/OutputsPage-C58n39Db.js +1 -0
  94. package/dist/web/assets/RightChatPanelStack-Bp7nZxQ0.js +1 -0
  95. package/dist/web/assets/ScheduledWorkPage-BXP0j_c_.js +1 -0
  96. package/dist/web/assets/SettingsView-CtWK_aQ0.css +1 -0
  97. package/dist/web/assets/SettingsView-DOOfhO9a.js +6 -0
  98. package/dist/web/assets/TeamChatView-Cgxm-pKA.css +1 -0
  99. package/dist/web/assets/TeamChatView-De2wdqyY.js +3 -0
  100. package/dist/web/assets/{TerminalOverlay-BKl0p8pa.js → TerminalOverlay-BsuCH3NX.js} +1 -1
  101. package/dist/web/assets/TrainingCreationPanel-D2OFWyQ-.js +1 -0
  102. package/dist/web/assets/TrainingDraftPanel-DBpulXTz.js +1 -0
  103. package/dist/web/assets/{UsageSettingsSection-zDAwzTGl.js → UsageSettingsSection-DzMLUXAO.js} +37 -37
  104. package/dist/web/assets/WorkspaceDiffPanel-B7yIhjNF.js +14 -0
  105. package/dist/web/assets/WorkspaceEnvironmentMenu-B6jXM9xG.js +32 -0
  106. package/dist/web/assets/WorkspaceGitDialogs-CQ0fl9Qk.js +1 -0
  107. package/dist/web/assets/{WorkspaceMonacoEditor-DPGcG8fy.js → WorkspaceMonacoEditor-C2ctzITz.js} +3 -3
  108. package/dist/web/assets/arrow-up-right-ecwcx3xt.js +1 -0
  109. package/dist/web/assets/chevron-up-DP8PPfWd.js +1 -0
  110. package/dist/web/assets/circle-alert-envg1D6O.js +1 -0
  111. package/dist/web/assets/cloud-upload-5MGPLnaA.js +1 -0
  112. package/dist/web/assets/{cssMode-CKN9CcfG.js → cssMode-CFifcEfw.js} +1 -1
  113. package/dist/web/assets/folder-open-Dq3ZjeEP.js +1 -0
  114. package/dist/web/assets/folder-plus-EiZ5wbv_.js +1 -0
  115. package/dist/web/assets/git-branch-w29jmQ-X.js +1 -0
  116. package/dist/web/assets/{git-commit-horizontal-Bxi8YPep.js → git-commit-horizontal-CGZM0PZo.js} +1 -1
  117. package/dist/web/assets/{htmlMode-CeUcNhBZ.js → htmlMode-Ct1P-_lf.js} +1 -1
  118. package/dist/web/assets/index-ByIQyiUl.js +178 -0
  119. package/dist/web/assets/index-D4uCeiep.js +1 -0
  120. package/dist/web/assets/index-D9jTe16Q.css +1 -0
  121. package/dist/web/assets/info-Cd2HkIeb.js +1 -0
  122. package/dist/web/assets/{jsonMode-97z0Yz9u.js → jsonMode-BAUNCNAX.js} +1 -1
  123. package/dist/web/assets/{lspLanguageFeatures-D4Tp-JmI.js → lspLanguageFeatures-fucFYI1A.js} +1 -1
  124. package/dist/web/assets/monaco.contribution-Ce4v5kei.js +2 -0
  125. package/dist/web/assets/monaco.contribution-DLLMi4cB.js +2 -0
  126. package/dist/web/assets/monaco.contribution-g9QiIm1d.js +2 -0
  127. package/dist/web/assets/monaco.contribution-nG-5Cyjz.js +2 -0
  128. package/dist/web/assets/monitor-DgHCnCKl.js +1 -0
  129. package/dist/web/assets/{play-C-37dnR1.js → play-Be0XDHBu.js} +1 -1
  130. package/dist/web/assets/{python-CGpDXY7_.js → python-CEhEiPo7.js} +1 -1
  131. package/dist/web/assets/{refresh-cw-BAaaPCXl.js → refresh-cw-DH0KLbdD.js} +1 -1
  132. package/dist/web/assets/reply-D1TK2yV8.js +1 -0
  133. package/dist/web/assets/{save-Cvxs3XyC.js → save-C1MSeBnQ.js} +1 -1
  134. package/dist/web/assets/square-CemI-0g5.js +1 -0
  135. package/dist/web/assets/square-pen-CqfsvR_n.js +1 -0
  136. package/dist/web/assets/{toggleHighContrast-CD42jH4g.js → toggleHighContrast-DrdQN3Rl.js} +1 -1
  137. package/dist/web/assets/training-BQVNUTZA.css +1 -0
  138. package/dist/web/assets/training-model-data-B7-1Bxil.js +1 -0
  139. package/dist/web/assets/{tsMode-ZROIxEjv.js → tsMode-CKB5oOUU.js} +1 -1
  140. package/dist/web/assets/{upload-DvCSGERK.js → upload-t751LLqP.js} +1 -1
  141. package/dist/web/assets/useLocalAgentSchedules-CzC3wfIP.js +1 -0
  142. package/dist/web/assets/{wifi-off-BIb94PkS.js → wifi-off-CxTHH3JU.js} +1 -1
  143. package/dist/web/assets/{workers-oYqbrVYG.js → workers-CqYddzCd.js} +1 -1
  144. package/dist/web/assets/{yaml-WqBjNgOO.js → yaml-e5wBkc-C.js} +1 -1
  145. package/dist/web/index.html +2 -2
  146. package/docs/command-reference.md +75 -40
  147. package/package.json +3 -1
  148. package/dist/chunks/chunk-FWLOFUPU.js +0 -864
  149. package/dist/chunks/chunk-HLCTINEP.js +0 -224
  150. package/dist/chunks/chunk-MPGSHXGF.js +0 -3896
  151. package/dist/chunks/chunk-T4QXKU5Y.js +0 -1
  152. package/dist/chunks/chunk-XEJ7XXUQ.js +0 -1301
  153. package/dist/chunks/chunk-ZI4GDAUB.js +0 -3522
  154. package/dist/chunks/cli-2KBVNDRY.js +0 -23
  155. package/dist/chunks/extend-REGNTBK3.js +0 -89
  156. package/dist/chunks/extension-7K77DAVL.js +0 -121
  157. package/dist/chunks/fileFromPath-DHCRY3BD.js +0 -2151
  158. package/dist/chunks/src-MWDIK56B.js +0 -105881
  159. package/dist/web/assets/BrowserSidebar-DMn2V8RV.js +0 -1
  160. package/dist/web/assets/CloudWorkView-Cl_7mM3c.js +0 -1
  161. package/dist/web/assets/CloudWorkView-DNoPIlMj.css +0 -1
  162. package/dist/web/assets/CommandMenu-CHMQLez_.js +0 -1
  163. package/dist/web/assets/CommunityView-DcHVDUk0.js +0 -1
  164. package/dist/web/assets/ComposerCreateImproveStrip-BZ3Dgzmo.js +0 -1
  165. package/dist/web/assets/GetStartedView-DBLdduwr.css +0 -1
  166. package/dist/web/assets/GetStartedView-DTRotFqz.js +0 -1
  167. package/dist/web/assets/LabSkillSidebar-D-PqFe1T.js +0 -1
  168. package/dist/web/assets/LabsRoute-BrJkBNig.css +0 -1
  169. package/dist/web/assets/LabsRoute-Dew1BwK5.js +0 -3
  170. package/dist/web/assets/MainChatThread-BaPxxzrw.js +0 -2
  171. package/dist/web/assets/MakeAgentTutorialLearningPanel-CBsfnONQ.js +0 -2
  172. package/dist/web/assets/MarkdownText-DGLfAM_Z.js +0 -7
  173. package/dist/web/assets/Messages-CIX9uTjX.js +0 -10
  174. package/dist/web/assets/NativeSkillSidebar-AP_uHn6g.js +0 -1
  175. package/dist/web/assets/NewProjectDialog-C6lHkafU.js +0 -1
  176. package/dist/web/assets/PostTrainingLearningPanel-CZEgPc8O.js +0 -2
  177. package/dist/web/assets/PostTrainingStatusPill-CeEpwUDB.js +0 -1
  178. package/dist/web/assets/ProfileSettingsSection-Cg4tKO-C.css +0 -1
  179. package/dist/web/assets/ProfileSettingsSection-EumMLlEp.js +0 -1
  180. package/dist/web/assets/RightChatPanelStack-MXBcx3zO.js +0 -1
  181. package/dist/web/assets/SettingsView-Caljbns2.css +0 -1
  182. package/dist/web/assets/SettingsView-DyURG_Uh.js +0 -6
  183. package/dist/web/assets/TeamChatView-Bx44q3WV.css +0 -1
  184. package/dist/web/assets/TeamChatView-D3v6aqJ3.js +0 -3
  185. package/dist/web/assets/TrainingCreationPanel-CfZQTuT5.js +0 -1
  186. package/dist/web/assets/TrainingDraftPanel-DslRPSDW.js +0 -1
  187. package/dist/web/assets/WorkspaceDiffPanel-C_MZPPlL.js +0 -14
  188. package/dist/web/assets/WorkspaceEnvironmentMenu-BUAnn80j.js +0 -32
  189. package/dist/web/assets/WorkspaceGitDialogs-Drbf4ujA.js +0 -1
  190. package/dist/web/assets/activity-Dnr3jqb3.js +0 -1
  191. package/dist/web/assets/boxes-BinC8UPn.js +0 -1
  192. package/dist/web/assets/chevron-up-Bjp_-_Cb.js +0 -1
  193. package/dist/web/assets/circle-x-ubnvEYuE.js +0 -1
  194. package/dist/web/assets/copy-B_ZCCUMz.js +0 -1
  195. package/dist/web/assets/create-pipeline-request-D6uLUxe9.js +0 -4
  196. package/dist/web/assets/file-8HAMlTmQ.js +0 -1
  197. package/dist/web/assets/git-branch-l2Zih3Bv.js +0 -1
  198. package/dist/web/assets/index-BMFyOFRU.css +0 -1
  199. package/dist/web/assets/index-BzwcDzbT.js +0 -1
  200. package/dist/web/assets/index-KoQSSt_f.js +0 -177
  201. package/dist/web/assets/info-JTbDQxHx.js +0 -1
  202. package/dist/web/assets/make-agent-tutorial-D6nBCgv-.js +0 -2
  203. package/dist/web/assets/monaco.contribution-B3j6oown.js +0 -2
  204. package/dist/web/assets/monaco.contribution-BXHxPPWL.js +0 -2
  205. package/dist/web/assets/monaco.contribution-C2P5zIzh.js +0 -2
  206. package/dist/web/assets/monaco.contribution-C8c6OtGi.js +0 -2
  207. package/dist/web/assets/monitor-kzHtxHnA.js +0 -1
  208. package/dist/web/assets/reply-9rehU13k.js +0 -1
  209. package/dist/web/assets/rotate-cw-C1Z_Xs23.js +0 -1
  210. package/dist/web/assets/training-BN8CALIc.css +0 -1
  211. package/dist/web/assets/training-model-data-BXUCzS0p.js +0 -1
  212. package/docs/agent-edit-check-status-json.md +0 -132
@@ -0,0 +1,1552 @@
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
+ } from "./chunk-KSRWKXRB.js";
6
+
7
+ // ../../packages/cloud/src/api/vercel-protection.ts
8
+ var VERCEL_PROTECTION_BYPASS_HEADER = "x-vercel-protection-bypass";
9
+ function withVercelProtectionBypass(requestUrl, inputHeaders, env = typeof process === "undefined" ? {} : process.env) {
10
+ const headers = new Headers(inputHeaders);
11
+ const secret = env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();
12
+ if (!secret || !isOpenPondStagingUrl(requestUrl)) return headers;
13
+ headers.set(VERCEL_PROTECTION_BYPASS_HEADER, secret);
14
+ return headers;
15
+ }
16
+ function isOpenPondStagingUrl(requestUrl) {
17
+ try {
18
+ const hostname = new URL(requestUrl).hostname.toLowerCase();
19
+ return hostname === "staging.openpond.ai" || hostname === "staging-api.openpond.ai" || hostname.endsWith(".staging-api.openpond.ai");
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ // ../../packages/cloud/src/api/core.ts
26
+ var DEFAULT_API_TIMEOUT_MS = 3e4;
27
+ var DEFAULT_API_RESPONSE_BYTES = 8 * 1024 * 1024;
28
+ var LONG_STREAM_API_OPTIONS = { timeoutMs: 15 * 60 * 1e3, maxResponseBytes: 64 * 1024 * 1024 };
29
+ var ApiTimeoutError = class extends Error {
30
+ constructor(timeoutMs, requestUrl) {
31
+ super(`API request timed out after ${timeoutMs}ms: ${requestUrl}`);
32
+ this.timeoutMs = timeoutMs;
33
+ this.requestUrl = requestUrl;
34
+ this.name = "ApiTimeoutError";
35
+ }
36
+ timeoutMs;
37
+ requestUrl;
38
+ code = "OPENPOND_API_TIMEOUT";
39
+ };
40
+ var ApiResponseTooLargeError = class extends Error {
41
+ constructor(maximumBytes, requestUrl) {
42
+ super(`API response exceeded ${maximumBytes} bytes: ${requestUrl}`);
43
+ this.maximumBytes = maximumBytes;
44
+ this.requestUrl = requestUrl;
45
+ this.name = "ApiResponseTooLargeError";
46
+ }
47
+ maximumBytes;
48
+ requestUrl;
49
+ code = "OPENPOND_API_RESPONSE_TOO_LARGE";
50
+ };
51
+ async function apiFetch(baseUrl, token, requestPath, options = {}) {
52
+ const { timeoutMs = DEFAULT_API_TIMEOUT_MS, maxResponseBytes = DEFAULT_API_RESPONSE_BYTES, ...init } = options;
53
+ const requestUrl = `${baseUrl}${requestPath}`;
54
+ const headers = withVercelProtectionBypass(requestUrl, init.headers);
55
+ headers.set("Content-Type", "application/json");
56
+ const apiKey = process.env.OPENPOND_API_KEY;
57
+ const trimmedToken = token?.trim() || "";
58
+ const tokenIsApiKey = trimmedToken.startsWith("opk_");
59
+ const effectiveApiKey = apiKey || (tokenIsApiKey ? trimmedToken : null);
60
+ if (effectiveApiKey && !headers.has("openpond-api-key")) headers.set("openpond-api-key", effectiveApiKey);
61
+ if (token) {
62
+ headers.set("Authorization", tokenIsApiKey ? `ApiKey ${trimmedToken}` : `Bearer ${token}`);
63
+ } else if (apiKey && !headers.has("Authorization")) {
64
+ headers.set("Authorization", `ApiKey ${apiKey}`);
65
+ }
66
+ const timeoutController = new AbortController();
67
+ const timeoutError = new ApiTimeoutError(timeoutMs, requestUrl);
68
+ const timer = timeoutMs > 0 ? setTimeout(() => timeoutController.abort(timeoutError), timeoutMs) : null;
69
+ timer?.unref?.();
70
+ const signal = composedSignal(init.signal, timeoutController.signal, timeoutMs);
71
+ const cleanup = () => {
72
+ if (timer) clearTimeout(timer);
73
+ };
74
+ try {
75
+ const response = await fetch(requestUrl, { ...init, headers, signal });
76
+ return boundedResponse(response, {
77
+ cleanup,
78
+ maximumBytes: maxResponseBytes,
79
+ requestUrl,
80
+ timeoutController,
81
+ timeoutError
82
+ });
83
+ } catch (error) {
84
+ cleanup();
85
+ if (timeoutController.signal.aborted) throw timeoutError;
86
+ throw error;
87
+ }
88
+ }
89
+ function boundedResponse(response, input) {
90
+ if (!response.body) {
91
+ input.cleanup();
92
+ return response;
93
+ }
94
+ const contentLength = Number(response.headers.get("content-length"));
95
+ if (input.maximumBytes > 0 && Number.isFinite(contentLength) && contentLength > input.maximumBytes) {
96
+ input.cleanup();
97
+ void response.body.cancel();
98
+ throw new ApiResponseTooLargeError(input.maximumBytes, input.requestUrl);
99
+ }
100
+ const reader = response.body.getReader();
101
+ let receivedBytes = 0;
102
+ const body = new ReadableStream({
103
+ async pull(controller) {
104
+ try {
105
+ const result = await reader.read();
106
+ if (result.done) {
107
+ input.cleanup();
108
+ controller.close();
109
+ return;
110
+ }
111
+ receivedBytes += result.value.byteLength;
112
+ if (input.maximumBytes > 0 && receivedBytes > input.maximumBytes) {
113
+ input.cleanup();
114
+ await reader.cancel();
115
+ controller.error(new ApiResponseTooLargeError(input.maximumBytes, input.requestUrl));
116
+ return;
117
+ }
118
+ controller.enqueue(result.value);
119
+ } catch (error) {
120
+ input.cleanup();
121
+ controller.error(input.timeoutController.signal.aborted ? input.timeoutError : error);
122
+ }
123
+ },
124
+ async cancel(reason) {
125
+ input.cleanup();
126
+ await reader.cancel(reason);
127
+ }
128
+ });
129
+ return new Response(body, {
130
+ headers: response.headers,
131
+ status: response.status,
132
+ statusText: response.statusText
133
+ });
134
+ }
135
+ function composedSignal(callerSignal, timeoutSignal, timeoutMs) {
136
+ if (timeoutMs <= 0) return callerSignal ?? void 0;
137
+ return callerSignal ? AbortSignal.any([callerSignal, timeoutSignal]) : timeoutSignal;
138
+ }
139
+
140
+ // ../../packages/cloud/src/api/deployments.ts
141
+ async function deployApp(baseUrl, token, appId, input) {
142
+ const environment = input?.environment ?? "production";
143
+ const response = await apiFetch(
144
+ baseUrl,
145
+ token,
146
+ `/v4/apps/${appId}/deployments`,
147
+ {
148
+ method: "POST",
149
+ body: JSON.stringify({
150
+ environment,
151
+ ...input?.commitSha ? { commitSha: input.commitSha } : {},
152
+ ...input?.branch ? { branch: input.branch } : {}
153
+ })
154
+ }
155
+ );
156
+ if (!response.ok) {
157
+ const text = await response.text().catch(() => "");
158
+ throw new Error(`Deploy failed: ${response.status} ${text}`);
159
+ }
160
+ return await response.json();
161
+ }
162
+ async function getDeploymentLogs(apiBase, token, deploymentId) {
163
+ const response = await apiFetch(
164
+ apiBase,
165
+ token,
166
+ `/apps/deployments/${deploymentId}/logs`,
167
+ { method: "GET" }
168
+ );
169
+ if (!response.ok) {
170
+ const text = await response.text().catch(() => "");
171
+ throw new Error(`Deployment logs failed: ${response.status} ${text}`);
172
+ }
173
+ const payload = await response.json().catch(() => ({}));
174
+ const logs = Array.isArray(payload.logs) ? payload.logs : [];
175
+ return logs.map((log) => {
176
+ const createdAt = typeof log.createdAt === "string" ? log.createdAt : log.createdAt instanceof Date ? log.createdAt.toISOString() : (/* @__PURE__ */ new Date()).toISOString();
177
+ return {
178
+ id: typeof log.id === "string" ? log.id : `${Math.random()}`,
179
+ type: typeof log.type === "string" ? log.type : void 0,
180
+ message: typeof log.message === "string" ? log.message : "",
181
+ createdAt
182
+ };
183
+ });
184
+ }
185
+ async function getDeploymentStatus(apiBase, token, deploymentId) {
186
+ const response = await apiFetch(
187
+ apiBase,
188
+ token,
189
+ `/apps/deployments/${deploymentId}/status`,
190
+ { method: "GET" }
191
+ );
192
+ if (!response.ok) {
193
+ const text = await response.text().catch(() => "");
194
+ throw new Error(`Deployment status failed: ${response.status} ${text}`);
195
+ }
196
+ const payload = await response.json().catch(() => ({}));
197
+ return { status: payload.deployment?.status };
198
+ }
199
+ async function getLatestDeploymentForApp(apiBase, token, appId, options) {
200
+ const params = new URLSearchParams();
201
+ if (options?.status && options.status.length > 0) {
202
+ params.set("status", options.status.join(","));
203
+ }
204
+ if (options?.createdAfter) {
205
+ params.set("createdAfter", options.createdAfter);
206
+ }
207
+ if (options?.branch) {
208
+ params.set("branch", options.branch);
209
+ }
210
+ const query = params.toString();
211
+ const response = await apiFetch(
212
+ apiBase,
213
+ token,
214
+ `/apps/${appId}/deployments/latest${query ? `?${query}` : ""}`,
215
+ { method: "GET" }
216
+ );
217
+ if (!response.ok) {
218
+ const text = await response.text().catch(() => "");
219
+ throw new Error(
220
+ `Latest deployment lookup failed: ${response.status} ${text}`
221
+ );
222
+ }
223
+ const payload = await response.json().catch(() => ({}));
224
+ if (!payload.deployment) return null;
225
+ return {
226
+ id: payload.deployment.id,
227
+ status: payload.deployment.status
228
+ };
229
+ }
230
+ async function getDeploymentDetail(apiBase, token, deploymentId) {
231
+ const response = await apiFetch(
232
+ apiBase,
233
+ token,
234
+ `/apps/deployments/${deploymentId}`,
235
+ { method: "GET" }
236
+ );
237
+ if (!response.ok) {
238
+ const text = await response.text().catch(() => "");
239
+ throw new Error(`Deployment fetch failed: ${response.status} ${text}`);
240
+ }
241
+ const payload = await response.json().catch(() => ({}));
242
+ return payload.deployment ?? null;
243
+ }
244
+
245
+ // ../../packages/cloud/src/api.ts
246
+ var DEFAULT_OPENPOND_API_HOST = new URL(DEFAULT_OPENPOND_API_BASE_URL).hostname;
247
+ var DEFAULT_OPENPOND_WEB_HOST = new URL(DEFAULT_OPENPOND_WEB_BASE_URL).hostname;
248
+ async function listApps(apiBase, token, options) {
249
+ const params = new URLSearchParams();
250
+ if (options?.handle) {
251
+ params.set("handle", options.handle);
252
+ }
253
+ if (typeof options?.limit === "number" && Number.isFinite(options.limit)) {
254
+ params.set("limit", String(Math.max(1, Math.floor(options.limit))));
255
+ }
256
+ if (typeof options?.offset === "number" && Number.isFinite(options.offset)) {
257
+ params.set("offset", String(Math.max(0, Math.floor(options.offset))));
258
+ }
259
+ if (typeof options?.includeScheduled === "boolean") {
260
+ params.set("includeScheduled", options.includeScheduled ? "true" : "false");
261
+ }
262
+ const query = params.toString();
263
+ const response = await apiFetch(
264
+ apiBase,
265
+ token,
266
+ `/apps/list${query ? `?${query}` : ""}`,
267
+ { method: "GET" }
268
+ );
269
+ if (!response.ok) {
270
+ const text = await response.text().catch(() => "");
271
+ throw new Error(`Apps list failed: ${response.status} ${text}`);
272
+ }
273
+ const payload = await response.json().catch(() => ({}));
274
+ return Array.isArray(payload.apps) ? payload.apps : [];
275
+ }
276
+ async function createRepo(apiBase, apiKey, input) {
277
+ const response = await apiFetch(apiBase, apiKey, "/apps/repo/create", {
278
+ method: "POST",
279
+ body: JSON.stringify(input)
280
+ });
281
+ if (!response.ok) {
282
+ const text = await response.text().catch(() => "");
283
+ throw new Error(`Repo create failed: ${response.status} ${text}`);
284
+ }
285
+ return await response.json();
286
+ }
287
+ async function updateAppCodeVisibility(apiBase, apiKey, appId, codeVisibility) {
288
+ const response = await apiFetch(
289
+ apiBase,
290
+ apiKey,
291
+ `/apps/${encodeURIComponent(appId)}/code-visibility`,
292
+ {
293
+ method: "PATCH",
294
+ body: JSON.stringify({ codeVisibility })
295
+ }
296
+ );
297
+ if (!response.ok) {
298
+ const text = await response.text().catch(() => "");
299
+ throw new Error(
300
+ `Code visibility update failed: ${response.status} ${text}`
301
+ );
302
+ }
303
+ return await response.json();
304
+ }
305
+ async function createHeadlessApps(baseUrl, token, items, teamId) {
306
+ const response = await apiFetch(baseUrl, token, "/v4/apps/headless", {
307
+ method: "POST",
308
+ body: JSON.stringify({ items, ...teamId ? { teamId } : {} })
309
+ });
310
+ if (!response.ok) {
311
+ const text = await response.text().catch(() => "");
312
+ throw new Error(`Headless create failed: ${response.status} ${text}`);
313
+ }
314
+ return await response.json();
315
+ }
316
+ async function getTemplateStatus(apiBase, token, appId) {
317
+ const response = await apiFetch(
318
+ apiBase,
319
+ token,
320
+ `/v4/apps/${appId}/template/status`,
321
+ { method: "GET" }
322
+ );
323
+ if (!response.ok) {
324
+ const text = await response.text().catch(() => "");
325
+ throw new Error(`Template status failed: ${response.status} ${text}`);
326
+ }
327
+ return await response.json();
328
+ }
329
+ async function listTemplateBranches(apiBase, token, appId) {
330
+ const response = await apiFetch(
331
+ apiBase,
332
+ token,
333
+ `/v4/apps/${appId}/template/branches`,
334
+ { method: "GET" }
335
+ );
336
+ if (!response.ok) {
337
+ const text = await response.text().catch(() => "");
338
+ throw new Error(`Template branches failed: ${response.status} ${text}`);
339
+ }
340
+ return await response.json();
341
+ }
342
+ async function deployLatestTemplate(apiBase, token, appId, input) {
343
+ const response = await apiFetch(
344
+ apiBase,
345
+ token,
346
+ `/v4/apps/${appId}/template/deploy-latest`,
347
+ {
348
+ method: "POST",
349
+ body: JSON.stringify(input)
350
+ }
351
+ );
352
+ if (!response.ok) {
353
+ const text = await response.text().catch(() => "");
354
+ throw new Error(`Template deploy failed: ${response.status} ${text}`);
355
+ }
356
+ return await response.json();
357
+ }
358
+ async function updateAppEnvironment(apiBase, token, appId, input) {
359
+ const response = await apiFetch(
360
+ apiBase,
361
+ token,
362
+ `/v4/apps/${appId}/environment`,
363
+ {
364
+ method: "POST",
365
+ body: JSON.stringify(input)
366
+ }
367
+ );
368
+ if (!response.ok) {
369
+ const text = await response.text().catch(() => "");
370
+ throw new Error(`Environment update failed: ${response.status} ${text}`);
371
+ }
372
+ return await response.json();
373
+ }
374
+ async function getAppEnvironment(apiBase, token, appId) {
375
+ const response = await apiFetch(
376
+ apiBase,
377
+ token,
378
+ `/v4/apps/${appId}/environment`,
379
+ {
380
+ method: "GET"
381
+ }
382
+ );
383
+ if (!response.ok) {
384
+ const text = await response.text().catch(() => "");
385
+ throw new Error(`Environment get failed: ${response.status} ${text}`);
386
+ }
387
+ return await response.json();
388
+ }
389
+ async function listUserTools(baseUrl, token) {
390
+ const response = await apiFetch(baseUrl, token, "/apps/tools", {
391
+ method: "GET"
392
+ });
393
+ if (!response.ok) {
394
+ const text = await response.text().catch(() => "");
395
+ throw new Error(`Tools lookup failed: ${response.status} ${text}`);
396
+ }
397
+ return await response.json();
398
+ }
399
+ async function createAgentFromPrompt(baseUrl, token, payload) {
400
+ return apiFetch(baseUrl, token, "/apps/agent/create", {
401
+ method: "POST",
402
+ body: JSON.stringify(payload)
403
+ });
404
+ }
405
+ async function getUserPerformance(baseUrl, token, options) {
406
+ const params = new URLSearchParams();
407
+ if (options?.appId) {
408
+ params.set("appId", options.appId);
409
+ }
410
+ const qs = params.toString();
411
+ const response = await apiFetch(
412
+ baseUrl,
413
+ token,
414
+ `/apps/performance${qs ? `?${qs}` : ""}`,
415
+ {
416
+ method: "GET"
417
+ }
418
+ );
419
+ if (!response.ok) {
420
+ const text = await response.text().catch(() => "");
421
+ throw new Error(`Performance lookup failed: ${response.status} ${text}`);
422
+ }
423
+ return await response.json();
424
+ }
425
+ async function getAppRuntimeSummary(baseUrl, token, appId) {
426
+ const params = new URLSearchParams({ appId });
427
+ const response = await apiFetch(
428
+ baseUrl,
429
+ token,
430
+ `/apps/summary?${params.toString()}`,
431
+ {
432
+ method: "GET"
433
+ }
434
+ );
435
+ if (!response.ok) {
436
+ const text = await response.text().catch(() => "");
437
+ throw new Error(`Summary lookup failed: ${response.status} ${text}`);
438
+ }
439
+ return await response.json();
440
+ }
441
+ async function getOpenPondAccount(baseUrl, token) {
442
+ const response = await apiFetch(baseUrl, token, "/v1/account", {
443
+ method: "GET"
444
+ });
445
+ if (!response.ok) {
446
+ const text = await response.text().catch(() => "");
447
+ throw new Error(`Account lookup failed: ${response.status} ${text}`);
448
+ }
449
+ return await response.json();
450
+ }
451
+ async function checkOpenPondApiHealth(baseUrl, token) {
452
+ const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
453
+ const started = Date.now();
454
+ const normalizedBase = baseUrl.replace(/\/$/, "");
455
+ try {
456
+ const response = await apiFetch(normalizedBase, null, "/health", {
457
+ method: "GET",
458
+ headers: { Accept: "application/json" }
459
+ });
460
+ const latencyMs = Date.now() - started;
461
+ const payload = await response.json().catch(() => ({}));
462
+ let authenticated = null;
463
+ let account = null;
464
+ if (token?.trim()) {
465
+ try {
466
+ const accountPayload = await getOpenPondAccount(normalizedBase, token);
467
+ authenticated = true;
468
+ account = accountPayload.account;
469
+ } catch {
470
+ authenticated = false;
471
+ }
472
+ }
473
+ return {
474
+ reachable: response.ok,
475
+ authenticated,
476
+ apiBase: normalizedBase,
477
+ latencyMs,
478
+ status: response.status,
479
+ service: typeof payload.service === "string" ? payload.service : null,
480
+ checkedAt,
481
+ account,
482
+ ...response.ok ? {} : { error: response.statusText || `HTTP ${response.status}` }
483
+ };
484
+ } catch (error) {
485
+ return {
486
+ reachable: false,
487
+ authenticated: token?.trim() ? false : null,
488
+ apiBase: normalizedBase,
489
+ latencyMs: Date.now() - started,
490
+ status: null,
491
+ service: null,
492
+ checkedAt,
493
+ error: error instanceof Error ? error.message : String(error)
494
+ };
495
+ }
496
+ }
497
+ async function runAssistantMode(baseUrl, token, payload) {
498
+ const response = await apiFetch(baseUrl, token, "/apps/assistant/run", {
499
+ method: "POST",
500
+ body: JSON.stringify(payload)
501
+ });
502
+ if (!response.ok) {
503
+ const text = await response.text().catch(() => "");
504
+ throw new Error(`Assistant run failed: ${response.status} ${text}`);
505
+ }
506
+ return await response.json();
507
+ }
508
+ async function executeUserTool(baseUrl, token, body) {
509
+ const response = await apiFetch(baseUrl, token, "/apps/tools/execute", {
510
+ method: "POST",
511
+ body: JSON.stringify(body)
512
+ });
513
+ const text = await response.text().catch(() => "");
514
+ let payload = null;
515
+ try {
516
+ payload = text ? JSON.parse(text) : null;
517
+ } catch {
518
+ payload = text;
519
+ }
520
+ if (!response.ok) {
521
+ return {
522
+ ok: false,
523
+ status: response.status,
524
+ error: payload && typeof payload === "object" && "error" in payload ? String(payload.error) : text || response.statusText
525
+ };
526
+ }
527
+ return {
528
+ ok: true,
529
+ status: response.status,
530
+ data: payload
531
+ };
532
+ }
533
+ async function submitBacktestRun(baseUrl, token, body) {
534
+ const response = await apiFetch(baseUrl, token, "/apps/backtests/run", {
535
+ method: "POST",
536
+ body: JSON.stringify(body)
537
+ });
538
+ if (!response.ok) {
539
+ const text = await response.text().catch(() => "");
540
+ throw new Error(`Backtest run failed: ${response.status} ${text}`);
541
+ }
542
+ return await response.json();
543
+ }
544
+ async function submitBacktestTx(baseUrl, token, params) {
545
+ const qs = params.query && Object.keys(params.query).length > 0 ? `?${new URLSearchParams(params.query).toString()}` : "";
546
+ const response = await apiFetch(baseUrl, token, `/apps/backtests/tx${qs}`, {
547
+ method: params.method,
548
+ body: params.method === "POST" && params.body !== void 0 ? JSON.stringify(params.body) : void 0
549
+ });
550
+ if (!response.ok) {
551
+ const text = await response.text().catch(() => "");
552
+ throw new Error(`Backtests request failed: ${response.status} ${text}`);
553
+ }
554
+ return await response.json();
555
+ }
556
+ async function submitBacktestDetail(baseUrl, token, query) {
557
+ const qs = new URLSearchParams(query).toString();
558
+ const response = await apiFetch(
559
+ baseUrl,
560
+ token,
561
+ `/apps/backtests/detail?${qs}`,
562
+ {
563
+ method: "GET"
564
+ }
565
+ );
566
+ if (!response.ok) {
567
+ const text = await response.text().catch(() => "");
568
+ throw new Error(`Backtest detail failed: ${response.status} ${text}`);
569
+ }
570
+ return await response.json();
571
+ }
572
+ function normalizeToolPathSegment(toolName) {
573
+ const trimmed = toolName.trim().replace(/^\/+/, "");
574
+ return encodeURIComponent(trimmed || "tool");
575
+ }
576
+ function resolveWorkerBaseUrl(baseUrl) {
577
+ const trimmed = baseUrl.replace(/\/$/, "");
578
+ const workerEnv = process.env.OPENPOND_TOOL_URL;
579
+ if (workerEnv) {
580
+ return workerEnv.replace(/\/$/, "");
581
+ }
582
+ try {
583
+ const url = new URL(trimmed);
584
+ const host = url.hostname.toLowerCase();
585
+ const mappedHost = (() => {
586
+ if (host === "apps.openpond.live") {
587
+ return null;
588
+ }
589
+ if (host === DEFAULT_OPENPOND_API_HOST || host === DEFAULT_OPENPOND_WEB_HOST || host === "openpond.live" || host === "www.openpond.live") {
590
+ return "https://apps.openpond.live";
591
+ }
592
+ return null;
593
+ })();
594
+ if (mappedHost) {
595
+ return mappedHost;
596
+ }
597
+ const isLocal = host === "localhost" || host === "127.0.0.1";
598
+ const port = url.port || (url.protocol === "https:" ? "443" : "80");
599
+ if (isLocal && port === "3000") {
600
+ return trimmed;
601
+ }
602
+ } catch {
603
+ }
604
+ return trimmed;
605
+ }
606
+ async function executeHostedTool(baseUrl, token, payload) {
607
+ const workerBase = resolveWorkerBaseUrl(baseUrl);
608
+ const toolPath = normalizeToolPathSegment(payload.toolName);
609
+ const deploymentPrefix = payload.deploymentId ? `/${payload.appId}/deployments/${payload.deploymentId}` : `/${payload.appId}`;
610
+ const requestPath = `${deploymentPrefix}/${toolPath}`;
611
+ const headers = new Headers(payload.headers || {});
612
+ const method = payload.method ?? "POST";
613
+ const body = payload.body === void 0 || method === "GET" ? void 0 : JSON.stringify(payload.body);
614
+ const response = await apiFetch(workerBase, token, requestPath, {
615
+ method,
616
+ body,
617
+ headers
618
+ });
619
+ const text = await response.text().catch(() => "");
620
+ let data = null;
621
+ try {
622
+ data = text ? JSON.parse(text) : null;
623
+ } catch {
624
+ data = text;
625
+ }
626
+ const dataOk = data && typeof data === "object" && "ok" in data ? Boolean(data.ok) : true;
627
+ const ok = response.ok && dataOk;
628
+ const status = data && typeof data === "object" && "status" in data ? Number(data.status) || response.status : response.status;
629
+ const error = data && typeof data === "object" && "error" in data ? String(data.error) : response.ok ? void 0 : text || response.statusText;
630
+ const payloadData = data && typeof data === "object" && "data" in data ? data.data : data;
631
+ return { ok, status, data: payloadData, error };
632
+ }
633
+
634
+ // ../../packages/cloud/src/config.ts
635
+ import { promises as fs2 } from "node:fs";
636
+ import path2 from "node:path";
637
+
638
+ // ../../packages/cloud/src/private-json-file.ts
639
+ import { randomUUID } from "node:crypto";
640
+ import { promises as fs } from "node:fs";
641
+ import os from "node:os";
642
+ import path from "node:path";
643
+ var LOCK_WAIT_TIMEOUT_MS = 1e4;
644
+ var STALE_LOCK_MS = 6e4;
645
+ function openPondConfigDirectory() {
646
+ const override = process.env.OPENPOND_CONFIG_DIR?.trim();
647
+ return override || path.join(os.homedir(), ".openpond");
648
+ }
649
+ async function writePrivateJsonFile(filePath, value) {
650
+ await withPrivateJsonFileLock(filePath, () => writePrivateJsonFileUnlocked(filePath, value));
651
+ }
652
+ async function updatePrivateJsonFile(filePath, fallback, update) {
653
+ return withPrivateJsonFileLock(filePath, async () => {
654
+ const current = await readJsonFile(filePath, fallback);
655
+ const next = await update(current);
656
+ await writePrivateJsonFileUnlocked(filePath, next);
657
+ return next;
658
+ });
659
+ }
660
+ async function writePrivateJsonFileUnlocked(filePath, value) {
661
+ const directory = path.dirname(filePath);
662
+ await fs.mkdir(directory, { recursive: true, mode: 448 });
663
+ await fs.chmod(directory, 448).catch(() => void 0);
664
+ const temporaryPath = `${filePath}.${process.pid}.${randomUUID()}.tmp`;
665
+ try {
666
+ await fs.writeFile(temporaryPath, JSON.stringify(value, null, 2), {
667
+ encoding: "utf-8",
668
+ mode: 384
669
+ });
670
+ await fs.rename(temporaryPath, filePath);
671
+ await fs.chmod(filePath, 384).catch(() => void 0);
672
+ } finally {
673
+ await fs.rm(temporaryPath, { force: true }).catch(() => void 0);
674
+ }
675
+ }
676
+ async function withPrivateJsonFileLock(filePath, operation) {
677
+ const directory = path.dirname(filePath);
678
+ await fs.mkdir(directory, { recursive: true, mode: 448 });
679
+ await fs.chmod(directory, 448).catch(() => void 0);
680
+ const lockPath = `${filePath}.lock`;
681
+ const deadline = Date.now() + LOCK_WAIT_TIMEOUT_MS;
682
+ while (true) {
683
+ try {
684
+ await fs.mkdir(lockPath, { mode: 448 });
685
+ break;
686
+ } catch (error) {
687
+ if (error.code !== "EEXIST") throw error;
688
+ await removeStaleLock(lockPath);
689
+ if (Date.now() >= deadline) throw new Error(`Timed out waiting for private file lock: ${filePath}`);
690
+ await new Promise((resolve) => setTimeout(resolve, 20 + Math.floor(Math.random() * 30)));
691
+ }
692
+ }
693
+ try {
694
+ return await operation();
695
+ } finally {
696
+ await fs.rm(lockPath, { recursive: true, force: true }).catch(() => void 0);
697
+ }
698
+ }
699
+ async function readJsonFile(filePath, fallback) {
700
+ try {
701
+ return JSON.parse(await fs.readFile(filePath, "utf8"));
702
+ } catch (error) {
703
+ if (error.code === "ENOENT") return fallback();
704
+ throw error;
705
+ }
706
+ }
707
+ async function removeStaleLock(lockPath) {
708
+ const stats = await fs.stat(lockPath).catch(() => null);
709
+ if (stats && Date.now() - stats.mtimeMs > STALE_LOCK_MS) {
710
+ await fs.rm(lockPath, { recursive: true, force: true });
711
+ }
712
+ }
713
+
714
+ // ../../packages/cloud/src/config.ts
715
+ var GLOBAL_CONFIG_FILENAME = "config.json";
716
+ var DEFAULT_ACCOUNT_HANDLE = "default";
717
+ var ACCOUNT_SCOPED_KEYS = [
718
+ "apiKey",
719
+ "baseUrl",
720
+ "apiBaseUrl",
721
+ "chatApiBaseUrl",
722
+ "token",
723
+ "appId",
724
+ "conversationId"
725
+ ];
726
+ function getGlobalConfigPath() {
727
+ return path2.join(openPondConfigDirectory(), GLOBAL_CONFIG_FILENAME);
728
+ }
729
+ async function loadConfigFile(filePath) {
730
+ try {
731
+ const raw = await fs2.readFile(filePath, "utf-8");
732
+ return JSON.parse(raw);
733
+ } catch (error) {
734
+ if (error.code === "ENOENT") return {};
735
+ if (error instanceof SyntaxError) {
736
+ throw new Error(`OpenPond config is malformed JSON: ${filePath}`, { cause: error });
737
+ }
738
+ throw error;
739
+ }
740
+ }
741
+ function hasOwn(value, key) {
742
+ return Object.prototype.hasOwnProperty.call(value, key);
743
+ }
744
+ function normalizeHandle(value) {
745
+ if (typeof value !== "string") return null;
746
+ const trimmed = value.trim();
747
+ return trimmed.length > 0 ? trimmed : null;
748
+ }
749
+ function normalizeBaseUrl(value) {
750
+ if (typeof value !== "string") return null;
751
+ const trimmed = value.trim();
752
+ if (!trimmed) return null;
753
+ return trimmed.replace(/\/$/, "");
754
+ }
755
+ function requireHandle(value) {
756
+ const handle = normalizeHandle(value);
757
+ if (!handle) {
758
+ throw new Error("profile handle must be non-empty");
759
+ }
760
+ return handle;
761
+ }
762
+ function requireApiKey(value) {
763
+ if (typeof value !== "string") {
764
+ throw new Error("apiKey must be a non-empty string");
765
+ }
766
+ const trimmed = value.trim();
767
+ if (!trimmed) {
768
+ throw new Error("apiKey must be a non-empty string");
769
+ }
770
+ return trimmed;
771
+ }
772
+ function handleEquals(left, right) {
773
+ const normalizedLeft = normalizeHandle(left);
774
+ const normalizedRight = normalizeHandle(right);
775
+ return Boolean(
776
+ normalizedLeft && normalizedRight && normalizedLeft.toLowerCase() === normalizedRight.toLowerCase()
777
+ );
778
+ }
779
+ function findAccountIndex(accounts, handle, baseUrl) {
780
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
781
+ return accounts.findIndex((candidate) => {
782
+ if (!handleEquals(candidate.handle, handle)) return false;
783
+ if (!normalizedBaseUrl) return true;
784
+ return normalizeBaseUrl(candidate.baseUrl) === normalizedBaseUrl;
785
+ });
786
+ }
787
+ function selectorFromAccount(account) {
788
+ const handle = normalizeHandle(account.handle) ?? DEFAULT_ACCOUNT_HANDLE;
789
+ const baseUrl = normalizeBaseUrl(account.baseUrl);
790
+ return baseUrl ? { handle, baseUrl } : { handle };
791
+ }
792
+ function sanitizeActiveProfile(value) {
793
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
794
+ const input = value;
795
+ const handle = normalizeHandle(
796
+ typeof input.handle === "string" ? input.handle : void 0
797
+ );
798
+ if (!handle) return null;
799
+ const baseUrl = normalizeBaseUrl(
800
+ typeof input.baseUrl === "string" ? input.baseUrl : void 0
801
+ );
802
+ return baseUrl ? { handle, baseUrl } : { handle };
803
+ }
804
+ function sanitizeLocalOpenPondProfile(value) {
805
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
806
+ return void 0;
807
+ }
808
+ const input = value;
809
+ const repoPath = typeof input.repoPath === "string" ? input.repoPath.trim() : "";
810
+ const profile = typeof input.profile === "string" && input.profile.trim() ? input.profile.trim() : "default";
811
+ if (!repoPath) return void 0;
812
+ const out = {
813
+ repoPath,
814
+ profile,
815
+ mode: "local"
816
+ };
817
+ if (input.lastCheck && typeof input.lastCheck === "object" && !Array.isArray(input.lastCheck)) {
818
+ const check = input.lastCheck;
819
+ const command = check.command;
820
+ const status = check.status;
821
+ const checkedAt = check.checkedAt;
822
+ if ((command === "inspect" || command === "build" || command === "validate" || command === "eval" || command === "run") && (status === "passed" || status === "failed") && typeof checkedAt === "string") {
823
+ out.lastCheck = {
824
+ command,
825
+ status,
826
+ checkedAt,
827
+ ...typeof check.exitCode === "number" || check.exitCode === null ? { exitCode: check.exitCode } : {},
828
+ ...typeof check.sourceHead === "string" || check.sourceHead === null ? { sourceHead: check.sourceHead } : {}
829
+ };
830
+ }
831
+ }
832
+ if (input.lastPush && typeof input.lastPush === "object" && !Array.isArray(input.lastPush)) {
833
+ const push = input.lastPush;
834
+ const status = push.status;
835
+ const pushedAt = push.pushedAt;
836
+ if ((status === "pushed" || status === "failed") && typeof pushedAt === "string") {
837
+ out.lastPush = {
838
+ status,
839
+ pushedAt,
840
+ ...typeof push.teamId === "string" || push.teamId === null ? { teamId: push.teamId } : {},
841
+ ...typeof push.projectId === "string" || push.projectId === null ? { projectId: push.projectId } : {},
842
+ ...typeof push.localHead === "string" || push.localHead === null ? { localHead: push.localHead } : {},
843
+ ...typeof push.hostedHead === "string" || push.hostedHead === null ? { hostedHead: push.hostedHead } : {},
844
+ ...typeof push.sourceRef === "string" || push.sourceRef === null ? { sourceRef: push.sourceRef } : {},
845
+ ...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 } : {},
846
+ ...push.hostedRunStatus === "not_started" || push.hostedRunStatus === "running" || push.hostedRunStatus === "passed" || push.hostedRunStatus === "failed" || push.hostedRunStatus === null ? { hostedRunStatus: push.hostedRunStatus } : {},
847
+ ...typeof push.hostedRunAgentId === "string" || push.hostedRunAgentId === null ? { hostedRunAgentId: push.hostedRunAgentId } : {},
848
+ ...typeof push.hostedRunId === "string" || push.hostedRunId === null ? { hostedRunId: push.hostedRunId } : {},
849
+ ...typeof push.hostedRunAt === "string" || push.hostedRunAt === null ? { hostedRunAt: push.hostedRunAt } : {},
850
+ ...sanitizeHostedMaterializationStatus(push.hostedSourceMaterialization) ? { hostedSourceMaterialization: sanitizeHostedMaterializationStatus(push.hostedSourceMaterialization) } : {},
851
+ ...sanitizeHostedSourceCheckStatus(push.hostedSourceCheck) ? { hostedSourceCheck: sanitizeHostedSourceCheckStatus(push.hostedSourceCheck) } : {},
852
+ ...sanitizeHostedPublishStatus(push.hostedPublish) ? { hostedPublish: sanitizeHostedPublishStatus(push.hostedPublish) } : {},
853
+ ...sanitizeHostedRunSummary(push.hostedRun) ? { hostedRun: sanitizeHostedRunSummary(push.hostedRun) } : {},
854
+ ...typeof push.error === "string" || push.error === null ? { error: push.error } : {}
855
+ };
856
+ }
857
+ }
858
+ if (Array.isArray(input.profiles)) {
859
+ const profiles = input.profiles.flatMap((value2) => {
860
+ const entry = sanitizeLocalOpenPondProfile(value2);
861
+ if (!entry) return [];
862
+ const rawEntry = value2;
863
+ const source = rawEntry.source === "github" || rawEntry.source === "openpond_git" ? rawEntry.source : "local";
864
+ const repositoryId = typeof rawEntry.repositoryId === "string" && rawEntry.repositoryId.trim() ? rawEntry.repositoryId.trim() : path2.resolve(entry.repoPath);
865
+ return [{
866
+ source,
867
+ repositoryId,
868
+ repoPath: entry.repoPath,
869
+ profile: entry.profile,
870
+ ...entry.lastCheck ? { lastCheck: entry.lastCheck } : {},
871
+ ...entry.lastPush ? { lastPush: entry.lastPush } : {}
872
+ }];
873
+ });
874
+ if (profiles.length > 0) out.profiles = profiles;
875
+ }
876
+ return out;
877
+ }
878
+ function sanitizeHostedMaterializationStatus(value) {
879
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
880
+ const input = value;
881
+ const status = stringField(input.status);
882
+ if (!status) return null;
883
+ return {
884
+ status,
885
+ ...nullableStringProp(input, "agentId"),
886
+ ...nullableStringProp(input, "runtimeAgentId"),
887
+ ...nullableStringProp(input, "projectId"),
888
+ ...nullableStringProp(input, "sourceRoot"),
889
+ ...nullableStringProp(input, "sourceRef"),
890
+ ...nullableStringProp(input, "sourceCommitSha"),
891
+ ...nullableStringProp(input, "manifestHash"),
892
+ ...nullableStringProp(input, "manifestPath"),
893
+ ...nullableStringProp(input, "manifestSyncedAt"),
894
+ ...nullableNumberProp(input, "fileCount"),
895
+ ...nullableNumberProp(input, "totalBytes"),
896
+ ...nullableStringProp(input, "generatedManifestPath"),
897
+ ...nullableBooleanProp(input, "synthesizedOpenPondYaml"),
898
+ ...nullableStringProp(input, "uploadMetadataPath"),
899
+ ...stringArrayProp(input, "setupCommands"),
900
+ ...stringArrayProp(input, "validationCommands"),
901
+ ...nullableStringProp(input, "materializedAt"),
902
+ ...nullableStringProp(input, "error")
903
+ };
904
+ }
905
+ function sanitizeHostedSourceCheckStatus(value) {
906
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
907
+ const input = value;
908
+ const status = stringField(input.status);
909
+ if (!status) return null;
910
+ return {
911
+ status,
912
+ ...nullableStringProp(input, "agentId"),
913
+ ...nullableStringProp(input, "deployPlanStatus"),
914
+ ...nullableBooleanProp(input, "canRun"),
915
+ ...nullableBooleanProp(input, "canDeploy"),
916
+ ...nullableStringProp(input, "sourceRef"),
917
+ ...nullableStringProp(input, "sourceCommitSha"),
918
+ ...nullableStringProp(input, "manifestHash"),
919
+ ...nullableStringProp(input, "manifestPath"),
920
+ ...stringArrayProp(input, "setupCommands"),
921
+ ...stringArrayProp(input, "validationCommands"),
922
+ ...stringArrayProp(input, "requiredChecks"),
923
+ ...stringArrayProp(input, "evalNames"),
924
+ ...stringArrayProp(input, "blockedReasons"),
925
+ ...stringArrayProp(input, "staleReasons"),
926
+ ...nullableStringProp(input, "runtimeId"),
927
+ ...nullableStringProp(input, "sandboxId"),
928
+ ...stringArrayProp(input, "traceArtifactRefs"),
929
+ ...stringArrayProp(input, "evalResultArtifactRefs"),
930
+ ...stringArrayProp(input, "validatorArtifactRefs"),
931
+ ...nullableStringProp(input, "checkedAt"),
932
+ ...nullableStringProp(input, "error")
933
+ };
934
+ }
935
+ function sanitizeHostedPublishStatus(value) {
936
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
937
+ const input = value;
938
+ const status = stringField(input.status);
939
+ if (!status) return null;
940
+ return {
941
+ status,
942
+ ...nullableStringProp(input, "agentId"),
943
+ ...nullableStringProp(input, "snapshotId"),
944
+ ...nullableStringProp(input, "sourceRef"),
945
+ ...nullableStringProp(input, "sourceCommitSha"),
946
+ ...nullableStringProp(input, "manifestHash"),
947
+ ...nullableStringProp(input, "manifestPath"),
948
+ ...nullableStringProp(input, "buildStatus"),
949
+ ...nullableStringProp(input, "validationStatus"),
950
+ ...nullableStringProp(input, "evalStatus"),
951
+ ...nullableStringProp(input, "publishedAt"),
952
+ ...nullableStringProp(input, "error")
953
+ };
954
+ }
955
+ function sanitizeHostedRunSummary(value) {
956
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
957
+ const input = value;
958
+ const status = stringField(input.status);
959
+ if (!status) return null;
960
+ return {
961
+ status,
962
+ ...nullableStringProp(input, "agentId"),
963
+ ...nullableStringProp(input, "runId"),
964
+ ...nullableStringProp(input, "runtimeId"),
965
+ ...nullableStringProp(input, "sandboxId"),
966
+ ...nullableStringProp(input, "sourceRef"),
967
+ ...nullableStringProp(input, "sourceCommitSha"),
968
+ ...nullableStringProp(input, "manifestHash"),
969
+ ...nullableStringProp(input, "setupGateStatus"),
970
+ ...stringArrayProp(input, "setupRequirementRefs"),
971
+ ...stringArrayProp(input, "artifactRefs"),
972
+ ...stringArrayProp(input, "traceArtifactRefs"),
973
+ ...stringArrayProp(input, "evalArtifactRefs"),
974
+ ...nullableStringProp(input, "startedAt"),
975
+ ...nullableStringProp(input, "completedAt"),
976
+ ...nullableStringProp(input, "error")
977
+ };
978
+ }
979
+ function nullableStringProp(input, key) {
980
+ const value = input[key];
981
+ return typeof value === "string" || value === null ? { [key]: value } : {};
982
+ }
983
+ function nullableBooleanProp(input, key) {
984
+ const value = input[key];
985
+ return typeof value === "boolean" || value === null ? { [key]: value } : {};
986
+ }
987
+ function nullableNumberProp(input, key) {
988
+ const value = input[key];
989
+ return typeof value === "number" || value === null ? { [key]: value } : {};
990
+ }
991
+ function stringArrayProp(input, key) {
992
+ const value = input[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 input = value;
1030
+ const out = {};
1031
+ if (typeof input.token === "string") out.token = input.token;
1032
+ if (typeof input.appId === "string" || input.appId === null) {
1033
+ out.appId = input.appId;
1034
+ }
1035
+ if (typeof input.conversationId === "string" || input.conversationId === null) {
1036
+ out.conversationId = input.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 input = value;
1043
+ const handle = normalizeHandle(
1044
+ typeof input.handle === "string" ? input.handle : void 0
1045
+ );
1046
+ if (!handle) return null;
1047
+ const out = { handle };
1048
+ if (typeof input.apiKey === "string") out.apiKey = input.apiKey;
1049
+ if (typeof input.baseUrl === "string") out.baseUrl = input.baseUrl;
1050
+ if (typeof input.apiBaseUrl === "string") out.apiBaseUrl = input.apiBaseUrl;
1051
+ if (typeof input.chatApiBaseUrl === "string")
1052
+ out.chatApiBaseUrl = input.chatApiBaseUrl;
1053
+ if (typeof input.environment === "string")
1054
+ out.environment = input.environment;
1055
+ const session = sanitizeSession(input.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 (typeof raw.lspEnabled === "boolean")
1084
+ normalized.lspEnabled = raw.lspEnabled;
1085
+ if (raw.executionMode === "local" || raw.executionMode === "hosted") {
1086
+ normalized.executionMode = raw.executionMode;
1087
+ }
1088
+ if (raw.mode === "general" || raw.mode === "builder") {
1089
+ normalized.mode = raw.mode;
1090
+ }
1091
+ const openpondProfile = sanitizeLocalOpenPondProfile(raw.openpondProfile);
1092
+ if (openpondProfile) {
1093
+ normalized.openpondProfile = openpondProfile;
1094
+ }
1095
+ const accounts = [];
1096
+ const sourceAccounts = Array.isArray(raw.accounts) ? raw.accounts : [];
1097
+ for (const candidate of sourceAccounts) {
1098
+ const account = sanitizeAccount(candidate);
1099
+ if (!account) continue;
1100
+ if (findAccountIndex(accounts, account.handle, account.baseUrl) !== -1)
1101
+ continue;
1102
+ accounts.push(account);
1103
+ }
1104
+ if (accounts.length === 0) {
1105
+ const legacyHandle = sanitizeActiveProfile(raw.activeProfile)?.handle || DEFAULT_ACCOUNT_HANDLE;
1106
+ accounts.push(extractLegacyAccount(raw, legacyHandle));
1107
+ }
1108
+ const requested = sanitizeActiveProfile(raw.activeProfile);
1109
+ const activeIdx = requested ? findAccountIndexForSelector(accounts, requested) : -1;
1110
+ const activeAccount = accounts[activeIdx === -1 ? 0 : activeIdx];
1111
+ normalized.accounts = accounts;
1112
+ normalized.activeProfile = selectorFromAccount(activeAccount);
1113
+ return normalized;
1114
+ }
1115
+ function resolveRequestedProfile(global, explicitAccount, explicitBaseUrl) {
1116
+ const accounts = global.accounts ?? [];
1117
+ const requestedBaseUrl = normalizeBaseUrl(
1118
+ explicitBaseUrl ?? process.env.OPENPOND_BASE_URL
1119
+ );
1120
+ const explicit = normalizeHandle(explicitAccount);
1121
+ if (explicit) {
1122
+ return requestedBaseUrl ? { handle: explicit, baseUrl: requestedBaseUrl } : { handle: explicit };
1123
+ }
1124
+ const envAccount = normalizeHandle(process.env.OPENPOND_ACCOUNT);
1125
+ if (envAccount) {
1126
+ return requestedBaseUrl ? { handle: envAccount, baseUrl: requestedBaseUrl } : { handle: envAccount };
1127
+ }
1128
+ const activeProfile = sanitizeActiveProfile(global.activeProfile);
1129
+ if (activeProfile) {
1130
+ return requestedBaseUrl ? { handle: activeProfile.handle, baseUrl: requestedBaseUrl } : activeProfile;
1131
+ }
1132
+ return accounts[0] ? selectorFromAccount(accounts[0]) : { handle: DEFAULT_ACCOUNT_HANDLE };
1133
+ }
1134
+ function ensureAccount(accounts, handle, baseUrl) {
1135
+ const normalizedBaseUrl = normalizeBaseUrl(baseUrl);
1136
+ if (normalizedBaseUrl) {
1137
+ const idx = findAccountIndex(accounts, handle, normalizedBaseUrl);
1138
+ if (idx !== -1) {
1139
+ return accounts[idx];
1140
+ }
1141
+ } else {
1142
+ const matches = accounts.filter(
1143
+ (account) => handleEquals(account.handle, handle)
1144
+ );
1145
+ if (matches.length > 1) {
1146
+ throw new Error(
1147
+ `multiple profiles found for ${handle}; pass --base-url to select one`
1148
+ );
1149
+ }
1150
+ if (matches.length === 1) {
1151
+ return matches[0];
1152
+ }
1153
+ }
1154
+ const next = { handle };
1155
+ if (normalizedBaseUrl) {
1156
+ next.baseUrl = normalizedBaseUrl;
1157
+ }
1158
+ accounts.push(next);
1159
+ return next;
1160
+ }
1161
+ function cleanupAccount(account) {
1162
+ if (account.session && Object.keys(account.session).length === 0) {
1163
+ delete account.session;
1164
+ }
1165
+ }
1166
+ function applyScopedKey(account, key, value, options) {
1167
+ const shouldDelete = value === null || value === void 0 && options.undefinedDeletes;
1168
+ switch (key) {
1169
+ case "apiKey": {
1170
+ if (shouldDelete) {
1171
+ delete account.apiKey;
1172
+ return;
1173
+ }
1174
+ if (typeof value === "string") {
1175
+ account.apiKey = value;
1176
+ }
1177
+ return;
1178
+ }
1179
+ case "baseUrl": {
1180
+ if (shouldDelete) {
1181
+ delete account.baseUrl;
1182
+ return;
1183
+ }
1184
+ if (typeof value === "string") {
1185
+ account.baseUrl = value;
1186
+ }
1187
+ return;
1188
+ }
1189
+ case "apiBaseUrl": {
1190
+ if (shouldDelete) {
1191
+ delete account.apiBaseUrl;
1192
+ return;
1193
+ }
1194
+ if (typeof value === "string") {
1195
+ account.apiBaseUrl = value;
1196
+ }
1197
+ return;
1198
+ }
1199
+ case "chatApiBaseUrl": {
1200
+ if (shouldDelete) {
1201
+ delete account.chatApiBaseUrl;
1202
+ return;
1203
+ }
1204
+ if (typeof value === "string") {
1205
+ account.chatApiBaseUrl = value;
1206
+ }
1207
+ return;
1208
+ }
1209
+ case "token":
1210
+ case "appId":
1211
+ case "conversationId": {
1212
+ if (!account.session) account.session = {};
1213
+ if (shouldDelete) {
1214
+ delete account.session[key];
1215
+ cleanupAccount(account);
1216
+ return;
1217
+ }
1218
+ if (typeof value === "string" || value === null) {
1219
+ account.session[key] = value;
1220
+ }
1221
+ cleanupAccount(account);
1222
+ return;
1223
+ }
1224
+ }
1225
+ }
1226
+ function applyAccountPatch(global, source, options) {
1227
+ const hasScopedPatch = ACCOUNT_SCOPED_KEYS.some((key) => hasOwn(source, key));
1228
+ if (!hasScopedPatch) return false;
1229
+ const accounts = global.accounts ?? [];
1230
+ const selector = sanitizeActiveProfile(source.activeProfile) ?? resolveRequestedProfile(global);
1231
+ const requestedBaseUrl = normalizeBaseUrl(
1232
+ hasOwn(source, "baseUrl") ? source.baseUrl ?? null : selector.baseUrl ?? process.env.OPENPOND_BASE_URL
1233
+ );
1234
+ const account = ensureAccount(accounts, selector.handle, requestedBaseUrl);
1235
+ for (const key of ACCOUNT_SCOPED_KEYS) {
1236
+ if (!hasOwn(source, key)) continue;
1237
+ applyScopedKey(
1238
+ account,
1239
+ key,
1240
+ source[key],
1241
+ options
1242
+ );
1243
+ }
1244
+ global.accounts = accounts;
1245
+ global.activeProfile = selectorFromAccount(account);
1246
+ return true;
1247
+ }
1248
+ function applyTopLevelPatch(global, source) {
1249
+ if (hasOwn(source, "lspEnabled")) {
1250
+ if (typeof source.lspEnabled === "boolean") {
1251
+ global.lspEnabled = source.lspEnabled;
1252
+ } else if (source.lspEnabled === null) {
1253
+ delete global.lspEnabled;
1254
+ }
1255
+ }
1256
+ if (hasOwn(source, "executionMode")) {
1257
+ if (source.executionMode === "local" || source.executionMode === "hosted") {
1258
+ global.executionMode = source.executionMode;
1259
+ } else if (source.executionMode === null) {
1260
+ delete global.executionMode;
1261
+ }
1262
+ }
1263
+ if (hasOwn(source, "mode")) {
1264
+ if (source.mode === "general" || source.mode === "builder") {
1265
+ global.mode = source.mode;
1266
+ } else if (source.mode === null) {
1267
+ delete global.mode;
1268
+ }
1269
+ }
1270
+ if (hasOwn(source, "activeProfile")) {
1271
+ const selector = sanitizeActiveProfile(source.activeProfile);
1272
+ if (selector) {
1273
+ const idx = findAccountIndexForSelector(global.accounts ?? [], selector);
1274
+ global.activeProfile = idx === -1 ? selector : selectorFromAccount((global.accounts ?? [])[idx]);
1275
+ } else if (source.activeProfile === null) {
1276
+ delete global.activeProfile;
1277
+ }
1278
+ }
1279
+ if (hasOwn(source, "openpondProfile")) {
1280
+ const profile = sanitizeLocalOpenPondProfile(source.openpondProfile);
1281
+ if (profile) {
1282
+ global.openpondProfile = profile;
1283
+ } else if (source.openpondProfile === null) {
1284
+ delete global.openpondProfile;
1285
+ }
1286
+ }
1287
+ }
1288
+ async function updateGlobalConfig(update) {
1289
+ try {
1290
+ return await updatePrivateJsonFile(getGlobalConfigPath(), () => ({}), (raw) => {
1291
+ const current = normalizeGlobalConfig(raw);
1292
+ update(current);
1293
+ return current;
1294
+ });
1295
+ } catch (error) {
1296
+ if (error instanceof SyntaxError) {
1297
+ throw new Error(`OpenPond config is malformed JSON: ${getGlobalConfigPath()}`, { cause: error });
1298
+ }
1299
+ throw error;
1300
+ }
1301
+ }
1302
+ async function loadGlobalConfig() {
1303
+ const raw = await loadConfigFile(getGlobalConfigPath());
1304
+ return normalizeGlobalConfig(raw);
1305
+ }
1306
+ async function loadConfig(options = {}) {
1307
+ const global = await loadGlobalConfig();
1308
+ const accounts = global.accounts ?? [];
1309
+ const requested = resolveRequestedProfile(
1310
+ global,
1311
+ options.account,
1312
+ options.baseUrl
1313
+ );
1314
+ const idx = findAccountIndexForSelector(accounts, requested, {
1315
+ requireUnambiguous: true
1316
+ });
1317
+ const account = idx === -1 ? null : accounts[idx];
1318
+ const session = account?.session;
1319
+ return {
1320
+ ...global,
1321
+ activeProfile: account ? selectorFromAccount(account) : requested,
1322
+ apiKey: account?.apiKey,
1323
+ baseUrl: account?.baseUrl,
1324
+ apiBaseUrl: account?.apiBaseUrl,
1325
+ chatApiBaseUrl: account?.chatApiBaseUrl,
1326
+ token: session?.token,
1327
+ appId: session?.appId,
1328
+ conversationId: session?.conversationId
1329
+ };
1330
+ }
1331
+ async function listConfiguredProfiles() {
1332
+ const global = await loadGlobalConfig();
1333
+ const activeProfile = sanitizeActiveProfile(global.activeProfile);
1334
+ return (global.accounts ?? []).map((account) => {
1335
+ const handle = normalizeHandle(account.handle) ?? DEFAULT_ACCOUNT_HANDLE;
1336
+ return {
1337
+ handle,
1338
+ baseUrl: normalizeBaseUrl(account.baseUrl),
1339
+ apiBaseUrl: normalizeBaseUrl(account.apiBaseUrl),
1340
+ chatApiBaseUrl: normalizeBaseUrl(account.chatApiBaseUrl),
1341
+ environment: account.environment?.trim() || null,
1342
+ isActive: Boolean(
1343
+ activeProfile && accountMatchesSelector({ ...account, handle }, activeProfile)
1344
+ ),
1345
+ hasApiKey: Boolean(account.apiKey?.trim()),
1346
+ hasSessionToken: Boolean(account.session?.token?.trim()),
1347
+ sessionAppId: account.session?.appId ?? null,
1348
+ sessionConversationId: account.session?.conversationId ?? null
1349
+ };
1350
+ });
1351
+ }
1352
+ async function setActiveProfile(handle, options = {}) {
1353
+ const requestedHandle = requireHandle(handle);
1354
+ const requestedBaseUrl = normalizeBaseUrl(options.baseUrl);
1355
+ let selectedIndex = -1;
1356
+ await updateGlobalConfig((global) => {
1357
+ const accounts = global.accounts ?? [];
1358
+ selectedIndex = findAccountIndexForSelector(
1359
+ accounts,
1360
+ requestedBaseUrl ? { handle: requestedHandle, baseUrl: requestedBaseUrl } : { handle: requestedHandle },
1361
+ { requireUnambiguous: true }
1362
+ );
1363
+ if (selectedIndex === -1) throw new Error(`profile not found: ${requestedHandle}`);
1364
+ global.activeProfile = selectorFromAccount(accounts[selectedIndex]);
1365
+ });
1366
+ const profiles = await listConfiguredProfiles();
1367
+ return profiles.find((profile) => profile.isActive) ?? profiles[selectedIndex];
1368
+ }
1369
+ async function saveProfileApiKey(input) {
1370
+ const handle = requireHandle(input.handle);
1371
+ const apiKey = requireApiKey(input.apiKey);
1372
+ const baseUrl = normalizeBaseUrl(input.baseUrl);
1373
+ const apiBaseUrl = normalizeBaseUrl(input.apiBaseUrl);
1374
+ const chatApiBaseUrl = normalizeBaseUrl(input.chatApiBaseUrl);
1375
+ let savedSelector = { handle };
1376
+ await updateGlobalConfig((global) => {
1377
+ const accounts = global.accounts ?? [];
1378
+ const account = ensureAccount(accounts, handle, baseUrl);
1379
+ account.apiKey = apiKey;
1380
+ if (baseUrl) account.baseUrl = baseUrl;
1381
+ if (apiBaseUrl) account.apiBaseUrl = apiBaseUrl;
1382
+ else if (input.apiBaseUrl === null) delete account.apiBaseUrl;
1383
+ if (chatApiBaseUrl) account.chatApiBaseUrl = chatApiBaseUrl;
1384
+ else if (input.chatApiBaseUrl === null) delete account.chatApiBaseUrl;
1385
+ if (input.environment === null) delete account.environment;
1386
+ else if (typeof input.environment === "string" && input.environment.trim()) {
1387
+ account.environment = input.environment.trim();
1388
+ }
1389
+ global.accounts = accounts;
1390
+ savedSelector = selectorFromAccount(account);
1391
+ if (input.setActive !== false) global.activeProfile = savedSelector;
1392
+ });
1393
+ const profiles = await listConfiguredProfiles();
1394
+ const saved = profiles.find((profile) => {
1395
+ if (!handleEquals(profile.handle, savedSelector.handle)) return false;
1396
+ if (!baseUrl) return true;
1397
+ return normalizeBaseUrl(profile.baseUrl) === baseUrl;
1398
+ });
1399
+ if (!saved) {
1400
+ throw new Error(`failed to save profile: ${handle}`);
1401
+ }
1402
+ return saved;
1403
+ }
1404
+ async function saveGlobalConfig(next) {
1405
+ await updateGlobalConfig((current) => {
1406
+ applyTopLevelPatch(current, next);
1407
+ applyAccountPatch(current, next, { undefinedDeletes: false });
1408
+ });
1409
+ }
1410
+
1411
+ // ../../packages/cloud/src/cache.ts
1412
+ import { promises as fs3 } from "node:fs";
1413
+ import { createHash } from "node:crypto";
1414
+ import path3 from "node:path";
1415
+ var CACHE_FILENAME = "cache.json";
1416
+ var DEFAULT_CACHE_TTL_MS = 60 * 60 * 1e3;
1417
+ function getCachePath() {
1418
+ return path3.join(openPondConfigDirectory(), CACHE_FILENAME);
1419
+ }
1420
+ function buildCacheKey(apiBase, apiKey) {
1421
+ const credentialHash = createHash("sha256").update(apiKey.trim()).digest("hex");
1422
+ try {
1423
+ const host = new URL(apiBase).host;
1424
+ return `${host}:${credentialHash}`;
1425
+ } catch {
1426
+ return `${apiBase}:${credentialHash}`;
1427
+ }
1428
+ }
1429
+ function isFresh(updatedAt, ttlMs) {
1430
+ const timestamp = Date.parse(updatedAt);
1431
+ if (Number.isNaN(timestamp)) {
1432
+ return false;
1433
+ }
1434
+ return Date.now() - timestamp < ttlMs;
1435
+ }
1436
+ async function loadCache() {
1437
+ try {
1438
+ const raw = await fs3.readFile(getCachePath(), "utf-8");
1439
+ const parsed = JSON.parse(raw);
1440
+ if (!parsed || typeof parsed !== "object" || !parsed.byKey) {
1441
+ return emptyCacheStore();
1442
+ }
1443
+ return parsed;
1444
+ } catch {
1445
+ return emptyCacheStore();
1446
+ }
1447
+ }
1448
+ function emptyCacheStore() {
1449
+ return { version: 1, byKey: {} };
1450
+ }
1451
+ async function getCachedApps(params) {
1452
+ const ttlMs = params.ttlMs ?? DEFAULT_CACHE_TTL_MS;
1453
+ const store = await loadCache();
1454
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1455
+ const entry = store.byKey[cacheKey]?.apps;
1456
+ if (!entry || !isFresh(entry.updatedAt, ttlMs)) {
1457
+ return null;
1458
+ }
1459
+ return Array.isArray(entry.items) ? entry.items : null;
1460
+ }
1461
+ async function setCachedApps(params) {
1462
+ await mutateCache((store) => {
1463
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1464
+ const bucket = store.byKey[cacheKey] || {};
1465
+ bucket.apps = {
1466
+ items: params.apps,
1467
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1468
+ };
1469
+ store.byKey[cacheKey] = bucket;
1470
+ });
1471
+ }
1472
+ async function getCachedTools(params) {
1473
+ const ttlMs = params.ttlMs ?? DEFAULT_CACHE_TTL_MS;
1474
+ const store = await loadCache();
1475
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1476
+ const entry = store.byKey[cacheKey]?.tools;
1477
+ if (!entry || !isFresh(entry.updatedAt, ttlMs)) {
1478
+ return null;
1479
+ }
1480
+ return Array.isArray(entry.items) ? entry.items : null;
1481
+ }
1482
+ async function setCachedTools(params) {
1483
+ await mutateCache((store) => {
1484
+ const cacheKey = buildCacheKey(params.apiBase, params.apiKey);
1485
+ const bucket = store.byKey[cacheKey] || {};
1486
+ bucket.tools = {
1487
+ items: params.tools,
1488
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
1489
+ };
1490
+ store.byKey[cacheKey] = bucket;
1491
+ });
1492
+ }
1493
+ async function mutateCache(mutate) {
1494
+ await updatePrivateJsonFile(getCachePath(), emptyCacheStore, (raw) => {
1495
+ const store = raw && typeof raw === "object" && raw.byKey ? raw : emptyCacheStore();
1496
+ mutate(store);
1497
+ return store;
1498
+ });
1499
+ }
1500
+
1501
+ // ../../packages/cloud/src/sandbox/types/runtime-profiles.ts
1502
+ var SANDBOX_RUNTIME_PROFILE_IDS = [
1503
+ "openpond-generic-v1",
1504
+ "openpond-work-v1",
1505
+ "openpond-coding-core-v1",
1506
+ "openpond-agent-harness-v1"
1507
+ ];
1508
+
1509
+ export {
1510
+ withVercelProtectionBypass,
1511
+ deployApp,
1512
+ getDeploymentLogs,
1513
+ getDeploymentStatus,
1514
+ getLatestDeploymentForApp,
1515
+ getDeploymentDetail,
1516
+ listApps,
1517
+ createRepo,
1518
+ updateAppCodeVisibility,
1519
+ createHeadlessApps,
1520
+ getTemplateStatus,
1521
+ listTemplateBranches,
1522
+ deployLatestTemplate,
1523
+ updateAppEnvironment,
1524
+ getAppEnvironment,
1525
+ listUserTools,
1526
+ createAgentFromPrompt,
1527
+ getUserPerformance,
1528
+ getAppRuntimeSummary,
1529
+ getOpenPondAccount,
1530
+ checkOpenPondApiHealth,
1531
+ runAssistantMode,
1532
+ executeUserTool,
1533
+ submitBacktestRun,
1534
+ submitBacktestTx,
1535
+ submitBacktestDetail,
1536
+ executeHostedTool,
1537
+ openPondConfigDirectory,
1538
+ writePrivateJsonFile,
1539
+ updatePrivateJsonFile,
1540
+ loadGlobalConfig,
1541
+ loadConfig,
1542
+ listConfiguredProfiles,
1543
+ setActiveProfile,
1544
+ saveProfileApiKey,
1545
+ saveGlobalConfig,
1546
+ DEFAULT_CACHE_TTL_MS,
1547
+ getCachedApps,
1548
+ setCachedApps,
1549
+ getCachedTools,
1550
+ setCachedTools,
1551
+ SANDBOX_RUNTIME_PROFILE_IDS
1552
+ };