openpond 0.2.0 → 0.2.2

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 (220) hide show
  1. package/dist/chunks/actions-command-F55CBR2K.js +2 -0
  2. package/dist/chunks/app-layer-GNYLOBCX.js +3 -0
  3. package/dist/chunks/app-server-runtime-VAGY4LQS.js +2 -0
  4. package/dist/chunks/apps-HZ5JGBDR.js +2 -0
  5. package/dist/chunks/chunk-22UARBPW.js +3 -0
  6. package/dist/chunks/chunk-3A7HZJNE.js +1 -0
  7. package/dist/chunks/chunk-3M53YXEI.js +2 -0
  8. package/dist/chunks/chunk-3NDRIQTI.js +2 -0
  9. package/dist/chunks/chunk-6FA3GG5B.js +33 -0
  10. package/dist/chunks/chunk-6MI4KKWF.js +2 -0
  11. package/dist/chunks/chunk-7D2LMRP7.js +2 -0
  12. package/dist/chunks/chunk-A42DFLOR.js +16 -0
  13. package/dist/chunks/chunk-AF57BF75.js +24 -0
  14. package/dist/chunks/chunk-BX4J2VDU.js +2 -0
  15. package/dist/chunks/chunk-BZMVB3GS.js +2 -0
  16. package/dist/chunks/chunk-CCJG7GLE.js +5 -0
  17. package/dist/chunks/chunk-CWQWV2T3.js +2 -0
  18. package/dist/chunks/chunk-DUA3QP6Y.js +19 -0
  19. package/dist/chunks/chunk-EAPFMACH.js +10 -0
  20. package/dist/chunks/chunk-EG3XB6M6.js +5 -0
  21. package/dist/chunks/chunk-ES2ISFJC.js +66 -0
  22. package/dist/chunks/chunk-FTQLQJQV.js +2 -0
  23. package/dist/chunks/chunk-FYCJSUFV.js +53 -0
  24. package/dist/chunks/chunk-GEANXBLX.js +2 -0
  25. package/dist/chunks/chunk-GLUWATL5.js +2 -0
  26. package/dist/chunks/chunk-GPZYIVFV.js +2199 -0
  27. package/dist/chunks/chunk-H7IWJN7L.js +17 -0
  28. package/dist/chunks/chunk-HZP5U2AA.js +3 -0
  29. package/dist/chunks/chunk-I5K74TOH.js +3 -0
  30. package/dist/chunks/chunk-I7G35U7K.js +2 -0
  31. package/dist/chunks/chunk-IR3YJWPW.js +7 -0
  32. package/dist/chunks/chunk-J7WZSLHS.js +18 -0
  33. package/dist/chunks/chunk-K35OOAW2.js +6 -0
  34. package/dist/chunks/chunk-KDXLNQNF.js +12 -0
  35. package/dist/chunks/chunk-KJYNLFWD.js +2872 -0
  36. package/dist/chunks/chunk-KV2IXO2T.js +6 -0
  37. package/dist/chunks/chunk-NVGMZ2IN.js +2 -0
  38. package/dist/chunks/chunk-OGPHXXCD.js +1 -0
  39. package/dist/chunks/chunk-RAKJWIYO.js +36 -0
  40. package/dist/chunks/chunk-RWSAGQTP.js +2 -0
  41. package/dist/chunks/chunk-SDO4FC4Q.js +2 -0
  42. package/dist/chunks/chunk-T5XCPX4P.js +3 -0
  43. package/dist/chunks/chunk-VYUMTRB3.js +5 -0
  44. package/dist/chunks/chunk-X37KMV27.js +1 -0
  45. package/dist/chunks/chunk-XAYIETBO.js +28 -0
  46. package/dist/chunks/chunk-XEOEKFG6.js +71 -0
  47. package/dist/chunks/chunk-ZVOO7FKM.js +2 -0
  48. package/dist/chunks/cli-UYTSZB4Y.js +2 -0
  49. package/dist/chunks/configuration-command-HAPIYG25.js +2 -0
  50. package/dist/chunks/continual-D75WA7E7.js +7 -0
  51. package/dist/chunks/core-commands-N37UZEVE.js +2 -0
  52. package/dist/chunks/database-X2CUV732.js +2 -0
  53. package/dist/chunks/desktop-test-V7FBEG7U.js +3 -0
  54. package/dist/chunks/dist-NKLXFA37.js +2 -0
  55. package/dist/chunks/extension-NEPOQ44P.js +5 -0
  56. package/dist/chunks/help-HC4N5ZQC.js +8 -0
  57. package/dist/chunks/module-ES6BEMUI-ZVL3F6NW.js +2 -0
  58. package/dist/chunks/module-asyncify-2EFITU5U-R7TVXNAE.js +2 -0
  59. package/dist/chunks/opchat-C7XRN4ZW.js +3 -0
  60. package/dist/chunks/organizations-LQGRZJ2V.js +2 -0
  61. package/dist/chunks/profile-UWM24A7R.js +3 -0
  62. package/dist/chunks/project-agent-2ME52ZJW.js +2 -0
  63. package/dist/chunks/sandbox-command-53L3ZICT.js +2 -0
  64. package/dist/chunks/sandbox-template-55HUM5H7.js +10 -0
  65. package/dist/chunks/src-EYJF2LWV.js +319 -0
  66. package/dist/chunks/src-VGW2UEMV.js +82 -0
  67. package/dist/chunks/taskset-PISBOILQ.js +2 -0
  68. package/dist/chunks/teams-bot-FHD2HCHN.js +3 -0
  69. package/dist/chunks/training-2NDOWH5S.js +2 -0
  70. package/dist/chunks/workspaces-CQFVCR7T.js +2 -0
  71. package/dist/cli.js +3 -109
  72. package/dist/index.js +1 -31230
  73. package/dist/sandbox-template/manifest.js +1 -18380
  74. package/dist/web/assets/App-BoJQRfeu.js +176 -0
  75. package/dist/web/assets/AppDialog-rdfmJsGF.js +1 -0
  76. package/dist/web/assets/AppTerminalPanel-CLW0kxtg.js +2 -0
  77. package/dist/web/assets/{AppsView-B1NUuAIf.js → AppsView-DxMXadnp.js} +1 -1
  78. package/dist/web/assets/{BrowserSidebar-DOvYxXeP.js → BrowserSidebar-BH_jl0JS.js} +1 -1
  79. package/dist/web/assets/{CartesianChart-pOrYpzBr.js → CartesianChart-oT_rMYpf.js} +1 -1
  80. package/dist/web/assets/{CollaborationTabs-CgbR-MBJ.js → CollaborationTabs-CukgFGE0.js} +1 -1
  81. package/dist/web/assets/{CommandMenu-CrIr4qUX.js → CommandMenu-2btBTgOF.js} +1 -1
  82. package/dist/web/assets/{CommunityView-CvAVQ_HZ.js → CommunityView-DMTREmN5.js} +1 -1
  83. package/dist/web/assets/{ComposerCreateImproveStrip-DybcKwwd.js → ComposerCreateImproveStrip-3tN55cg9.js} +1 -1
  84. package/dist/web/assets/GetStartedView-CMHL24_w.js +1 -0
  85. package/dist/web/assets/HostedModelLearningReview-CqkSelkC.js +1 -0
  86. package/dist/web/assets/HostedModelLearningSettings-xqd2lSW3.js +1 -0
  87. package/dist/web/assets/LabModelVersionDetailPage-Bpnya5DM.js +1 -0
  88. package/dist/web/assets/{LabSkillSidebar-CuaYrtiu.js → LabSkillSidebar-BKZjScr8.js} +1 -1
  89. package/dist/web/assets/LabsRoute-BhPFmA_Z.js +32 -0
  90. package/dist/web/assets/LabsRoute-C1FWCoYb.css +1 -0
  91. package/dist/web/assets/MainChatThread-Bosxokt-.js +2 -0
  92. package/dist/web/assets/MainPane-Di-Rwe7x.js +8 -0
  93. package/dist/web/assets/{MarkdownText-DOlVQR8a.js → MarkdownText-dK4SBPp_.js} +1 -1
  94. package/dist/web/assets/{Messages-DMubppta.js → Messages-ftYRMKYa.js} +6 -6
  95. package/dist/web/assets/{NativeSkillSidebar-DSFwZ-od.js → NativeSkillSidebar-Cwo7JdB2.js} +1 -1
  96. package/dist/web/assets/{NewExperienceSwitcher-Dj0ePIJ-.js → NewExperienceSwitcher-C1_JzTq2.js} +1 -1
  97. package/dist/web/assets/{NewProjectDialog-B8NQV-Ji.js → NewProjectDialog-CxP6v6YW.js} +1 -1
  98. package/dist/web/assets/{OutputsPage-D_LDYTgV.js → OutputsPage-DL21_Alp.js} +1 -1
  99. package/dist/web/assets/{ProjectsPage-xjDYPc_W.js → ProjectsPage-BO9VyvMA.js} +1 -1
  100. package/dist/web/assets/RightChatPanelStack-DaqAnzdR.js +1 -0
  101. package/dist/web/assets/{RightSidebarHomePanel-j0VckZUu.js → RightSidebarHomePanel-PbUG12AO.js} +1 -1
  102. package/dist/web/assets/{ScheduledWorkPage-1aT4bBY-.js → ScheduledWorkPage-BhL-cXML.js} +1 -1
  103. package/dist/web/assets/{SettingsView-BSpuMDpv.js → SettingsView-D6-s7G88.js} +7 -7
  104. package/dist/web/assets/TeamChatView-DbS1N-fo.js +3 -0
  105. package/dist/web/assets/{TerminalOverlay-CrSwUk2d.js → TerminalOverlay-CphyBXJR.js} +3 -3
  106. package/dist/web/assets/{TrainingCreationPanel-B4HMRwUg.js → TrainingCreationPanel-Czsdraix.js} +1 -1
  107. package/dist/web/assets/{TrainingDraftPanel-D4r1tN3I.js → TrainingDraftPanel-Bq3B5pUk.js} +1 -1
  108. package/dist/web/assets/{UsageSettingsSection-2aymqwIM.js → UsageSettingsSection-B74FNwaP.js} +5 -5
  109. package/dist/web/assets/{WorkSidebarPanel-B0X0OiR6.js → WorkSidebarPanel-BgaK4XSg.js} +1 -1
  110. package/dist/web/assets/WorkspaceDiffPanel-C3seHnVY.js +14 -0
  111. package/dist/web/assets/{WorkspaceEnvironmentMenu-OAfMEt7L.js → WorkspaceEnvironmentMenu-DPghQUdv.js} +3 -3
  112. package/dist/web/assets/{WorkspaceGitDialogs-YxcPH2Rq.js → WorkspaceGitDialogs-D8c6Okb_.js} +1 -1
  113. package/dist/web/assets/{WorkspaceMonacoEditor-COKTiQZl.js → WorkspaceMonacoEditor-2kjRFf4l.js} +36 -36
  114. package/dist/web/assets/{arrow-up-right-_TX-awvK.js → arrow-up-right-C5X-29oa.js} +1 -1
  115. package/dist/web/assets/chat-file-links-Bmz9kVct.js +1 -0
  116. package/dist/web/assets/chevron-up-NbP9vY4E.js +1 -0
  117. package/dist/web/assets/{clipboard-CyRSS8Sy.js → clipboard-fvHMXPWa.js} +1 -1
  118. package/dist/web/assets/{cloud-upload-uBJBUYTy.js → cloud-upload-BAycsdHL.js} +1 -1
  119. package/dist/web/assets/{cssMode-BrXSsZYs.js → cssMode-Yis679a5.js} +1 -1
  120. package/dist/web/assets/{folder-open-DktdZNW7.js → folder-open-bii4KUCv.js} +1 -1
  121. package/dist/web/assets/{folder-plus-DO06i9Vo.js → folder-plus-B0B7mUCx.js} +1 -1
  122. package/dist/web/assets/{git-commit-horizontal-zFSIkPs7.js → git-commit-horizontal-B6yTdtnB.js} +1 -1
  123. package/dist/web/assets/{htmlMode-X9UMFkjt.js → htmlMode-DHeBSKVF.js} +1 -1
  124. package/dist/web/assets/{index-UOGdfLzi.js → index-667pXXsu.js} +1 -1
  125. package/dist/web/assets/{index-ByQIHpc9.css → index-BGMzUaup.css} +1 -1
  126. package/dist/web/assets/{info-BEJXUqCD.js → info-NCOESX3I.js} +1 -1
  127. package/dist/web/assets/{jsonMode-DIsB-j2E.js → jsonMode-C4oxy1cU.js} +1 -1
  128. package/dist/web/assets/{lspLanguageFeatures-CmZ17KpA.js → lspLanguageFeatures-CLj3WGZW.js} +1 -1
  129. package/dist/web/assets/{minimize-2-DumTpFtE.js → minimize-2-DtI1vgd7.js} +1 -1
  130. package/dist/web/assets/{monaco.contribution-D6w5PJji.js → monaco.contribution-DZPgekIQ.js} +2 -2
  131. package/dist/web/assets/{monaco.contribution-DJ_NmcHu.js → monaco.contribution-Ddw-TznO.js} +2 -2
  132. package/dist/web/assets/{monaco.contribution-YVDfJcG4.js → monaco.contribution-DhVPJ-oY.js} +2 -2
  133. package/dist/web/assets/{monaco.contribution-LZEujgny.js → monaco.contribution-DrW6DjWP.js} +2 -2
  134. package/dist/web/assets/{play-CLFeH7CU.js → play-DB3XFAnG.js} +1 -1
  135. package/dist/web/assets/{python-Djbda_qZ.js → python-DLyUeEeL.js} +1 -1
  136. package/dist/web/assets/{refresh-cw-B4IpQ_7Q.js → refresh-cw-0zSLZtfp.js} +1 -1
  137. package/dist/web/assets/{save-BbTHztnA.js → save-BCZlshOA.js} +1 -1
  138. package/dist/web/assets/{square-BJrVbmz6.js → square-CRytZWR_.js} +1 -1
  139. package/dist/web/assets/{toggleHighContrast-BopU5W9S.js → toggleHighContrast-TXg0rI_R.js} +1 -1
  140. package/dist/web/assets/{tsMode-CH_0_YDX.js → tsMode-Bj1019AY.js} +1 -1
  141. package/dist/web/assets/{upload-UumVeufu.js → upload-CnE9u7GB.js} +1 -1
  142. package/dist/web/assets/{useLocalAgentSchedules-BRa23U7O.js → useLocalAgentSchedules-qI87RHVI.js} +1 -1
  143. package/dist/web/assets/{wifi-off-BWJWivn6.js → wifi-off-CfuwRBx7.js} +1 -1
  144. package/dist/web/assets/{workers-pTe8RvSI.js → workers-CXdUI7wU.js} +1 -1
  145. package/dist/web/assets/{yaml-DNLASORn.js → yaml-AP8aiwLm.js} +1 -1
  146. package/dist/web/index.html +2 -2
  147. package/package.json +4 -3
  148. package/dist/chunks/actions-command-6N5XWMR6.js +0 -185
  149. package/dist/chunks/app-layer-F3CGXB33.js +0 -216
  150. package/dist/chunks/app-server-runtime-RHO5TFUC.js +0 -23
  151. package/dist/chunks/apps-L5XCL7QY.js +0 -429
  152. package/dist/chunks/chunk-26AMV5ZI.js +0 -634
  153. package/dist/chunks/chunk-3EB7I67T.js +0 -630
  154. package/dist/chunks/chunk-3ELF4FXY.js +0 -96
  155. package/dist/chunks/chunk-3VEYNDHN.js +0 -669
  156. package/dist/chunks/chunk-4KA25HUP.js +0 -5648
  157. package/dist/chunks/chunk-4L3ZJS2T.js +0 -1207
  158. package/dist/chunks/chunk-6SMNG6YA.js +0 -1303
  159. package/dist/chunks/chunk-7RIGZB7N.js +0 -1148
  160. package/dist/chunks/chunk-A6G3PFA5.js +0 -2164
  161. package/dist/chunks/chunk-BVY5JYM6.js +0 -512
  162. package/dist/chunks/chunk-DLQQIWN2.js +0 -648
  163. package/dist/chunks/chunk-FJ2JGB2N.js +0 -1373
  164. package/dist/chunks/chunk-FQS2QL5F.js +0 -14522
  165. package/dist/chunks/chunk-G65WAOJV.js +0 -1643
  166. package/dist/chunks/chunk-JTHL5XJ2.js +0 -1838
  167. package/dist/chunks/chunk-K4TZEHAW.js +0 -602
  168. package/dist/chunks/chunk-KCRCIQPD.js +0 -66
  169. package/dist/chunks/chunk-KSRWKXRB.js +0 -12
  170. package/dist/chunks/chunk-MUMPWI4O.js +0 -92
  171. package/dist/chunks/chunk-NTK22KJD.js +0 -10707
  172. package/dist/chunks/chunk-OCBRPU2K.js +0 -629
  173. package/dist/chunks/chunk-PS37DB5F.js +0 -183
  174. package/dist/chunks/chunk-R3C3MNSI.js +0 -140
  175. package/dist/chunks/chunk-SMNFI2FU.js +0 -113
  176. package/dist/chunks/chunk-UACZUFIA.js +0 -47
  177. package/dist/chunks/chunk-UZMVNKXM.js +0 -1275
  178. package/dist/chunks/chunk-VT6BLHMB.js +0 -67198
  179. package/dist/chunks/chunk-W5GKHH77.js +0 -168
  180. package/dist/chunks/chunk-X6F4LBTQ.js +0 -832
  181. package/dist/chunks/chunk-X7ZG4TSW.js +0 -3063
  182. package/dist/chunks/chunk-XA4KBDMY.js +0 -13723
  183. package/dist/chunks/chunk-YVCYVDNP.js +0 -746
  184. package/dist/chunks/chunk-ZNQEROWP.js +0 -254
  185. package/dist/chunks/cli-D2MUUBEX.js +0 -23
  186. package/dist/chunks/configuration-command-NR6JYIUD.js +0 -187
  187. package/dist/chunks/continual-37CE4LLJ.js +0 -803
  188. package/dist/chunks/core-commands-SWGIOZLW.js +0 -50
  189. package/dist/chunks/database-DEYUZDIM.js +0 -20
  190. package/dist/chunks/desktop-test-QOS7G5NE.js +0 -148
  191. package/dist/chunks/dist-AKYCQNNF.js +0 -187
  192. package/dist/chunks/extension-HJUJBQAD.js +0 -9378
  193. package/dist/chunks/help-J6PZ23IC.js +0 -67
  194. package/dist/chunks/opchat-ABX5YBAT.js +0 -169
  195. package/dist/chunks/organizations-CPNC47DO.js +0 -806
  196. package/dist/chunks/profile-Q3HB5MIO.js +0 -1136
  197. package/dist/chunks/project-agent-YHUBX4OR.js +0 -516
  198. package/dist/chunks/sandbox-command-YFL5QTWX.js +0 -1661
  199. package/dist/chunks/sandbox-template-Z6P7NTNF.js +0 -1655
  200. package/dist/chunks/src-7XEENEBI.js +0 -3628
  201. package/dist/chunks/src-KBBIV4NT.js +0 -56125
  202. package/dist/chunks/taskset-2TRZBRRT.js +0 -66
  203. package/dist/chunks/teams-bot-WD33NLH5.js +0 -146
  204. package/dist/chunks/training-4XH37UZB.js +0 -17
  205. package/dist/chunks/workspaces-WG2MH2WE.js +0 -99
  206. package/dist/web/assets/App-C9aGkxVg.js +0 -173
  207. package/dist/web/assets/AppDialog-CK6_lg8c.js +0 -1
  208. package/dist/web/assets/AppTerminalPanel-BKqgX4sd.js +0 -2
  209. package/dist/web/assets/GetStartedView-DVInkexN.js +0 -1
  210. package/dist/web/assets/LabModelVersionDetailPage-NaaPElmM.js +0 -1
  211. package/dist/web/assets/LabsRoute-BRR6x3SX.js +0 -2
  212. package/dist/web/assets/LabsRoute-CGFgymTX.css +0 -1
  213. package/dist/web/assets/MainChatThread-BfkjCZB9.js +0 -2
  214. package/dist/web/assets/MainPane-Gw-YK38n.js +0 -8
  215. package/dist/web/assets/RightChatPanelStack-BktRQ9wg.js +0 -1
  216. package/dist/web/assets/TeamChatView-BPWJbDf1.js +0 -3
  217. package/dist/web/assets/WorkspaceDiffPanel-Pg7GL0br.js +0 -14
  218. package/dist/web/assets/chat-file-links-CWLsRYvW.js +0 -1
  219. package/dist/web/assets/chevron-up--mNnEqha.js +0 -1
  220. package/dist/web/assets/index-BEPmTPIA.js +0 -1
@@ -1,1655 +0,0 @@
1
- import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
- import {
3
- createSandboxFromPlan,
4
- summarizeSandbox
5
- } from "./chunk-3EB7I67T.js";
6
- import {
7
- resolveGitBranch
8
- } from "./chunk-K4TZEHAW.js";
9
- import {
10
- OPENPOND_MANIFEST_FILE_NAME,
11
- SANDBOX_TEMPLATE_BUILD_PLAN_FILE_NAME,
12
- SANDBOX_TEMPLATE_BUILD_PLAN_KIND,
13
- formatSandboxTemplateDiagnostics,
14
- sandboxTemplateBuildMetadata,
15
- sandboxTemplateBuildPlan,
16
- sandboxTemplateExecutableEntries,
17
- sandboxTemplateJsonSchema,
18
- sandboxTemplateScaffoldFiles,
19
- validateSandboxTemplateYaml
20
- } from "./chunk-YVCYVDNP.js";
21
- import "./chunk-X7ZG4TSW.js";
22
- import {
23
- ensureApiKey,
24
- formatTokenizedRepoUrl,
25
- getGitRemoteUrl,
26
- parseSandboxRuntimePromotionPolicyOption,
27
- parseSandboxTemplateEnvOptions,
28
- parseSandboxWorkflowModeOption,
29
- promptConfirm,
30
- redactToken,
31
- resolveRepoUrl,
32
- resolveSandboxClient,
33
- runCommand,
34
- runShellCommand,
35
- warnOnRepoHostMismatch
36
- } from "./chunk-3VEYNDHN.js";
37
- import {
38
- createRepo,
39
- loadConfig
40
- } from "./chunk-FJ2JGB2N.js";
41
- import {
42
- resolveBaseUrl,
43
- resolvePublicApiBaseUrl
44
- } from "./chunk-SMNFI2FU.js";
45
- import "./chunk-KSRWKXRB.js";
46
- import "./chunk-PS37DB5F.js";
47
- import "./chunk-4KA25HUP.js";
48
- import "./chunk-ZNQEROWP.js";
49
- import "./chunk-7RIGZB7N.js";
50
- import "./chunk-4L3ZJS2T.js";
51
- import "./chunk-JTHL5XJ2.js";
52
- import "./chunk-FQS2QL5F.js";
53
- import {
54
- parseBooleanOption,
55
- parseIntegerOption,
56
- parseJsonOption
57
- } from "./chunk-MUMPWI4O.js";
58
- import "./chunk-UACZUFIA.js";
59
-
60
- // src/cli/sandbox-template.ts
61
- import { promises as fs3, existsSync as existsSync2 } from "node:fs";
62
- import path4 from "node:path";
63
-
64
- // src/cli/sandbox-template-local.ts
65
- import { Buffer as Buffer2 } from "node:buffer";
66
- import { promises as fs2 } from "node:fs";
67
- import path3 from "node:path";
68
-
69
- // src/cli/sandbox-template-start.ts
70
- import { Buffer } from "node:buffer";
71
- import { promises as fs } from "node:fs";
72
- import path2 from "node:path";
73
-
74
- // src/cli/sandbox-template-schedules.ts
75
- async function createSandboxTemplateStartSchedules(client, sandboxId, manifest, options) {
76
- const selection = resolveSandboxTemplateStartScheduleSelection(
77
- manifest,
78
- options
79
- );
80
- if (!selection) {
81
- return [];
82
- }
83
- const overrides = parseSandboxTemplateScheduleOverrides(manifest, options);
84
- const projectId = typeof options.projectId === "string" && options.projectId.trim() ? options.projectId.trim() : typeof options.runtimeProjectId === "string" ? options.runtimeProjectId.trim() : "";
85
- const teamId = typeof options.teamId === "string" ? options.teamId.trim() : "";
86
- const created = [];
87
- for (const schedule of selection.schedules) {
88
- const input2 = buildSandboxTemplateStartScheduleInput({
89
- manifest,
90
- schedule,
91
- override: overrides.get(schedule.name),
92
- mode: selection.mode,
93
- sourceSandboxId: sandboxId,
94
- teamId,
95
- projectId
96
- });
97
- const result = await client.createSchedule(input2);
98
- created.push({
99
- id: result.schedule.id,
100
- name: result.schedule.name,
101
- enabled: result.schedule.enabled,
102
- scheduleType: result.schedule.scheduleType,
103
- scheduleExpression: result.schedule.scheduleExpression,
104
- syncStatus: result.schedule.syncStatus,
105
- awsScheduleArn: result.schedule.awsScheduleArn ?? null,
106
- target: result.schedule.target
107
- });
108
- }
109
- return created;
110
- }
111
- function resolveSandboxTemplateStartScheduleSelection(manifest, options) {
112
- const enableRaw = options.enableSchedules ?? options.enableSchedule;
113
- const disableRaw = options.disableSchedules ?? options.disableSchedule;
114
- if (enableRaw !== void 0 && disableRaw !== void 0) {
115
- throw new Error(
116
- "pass only one of --enable-schedules or --disable-schedules"
117
- );
118
- }
119
- let mode = null;
120
- let rawSelection;
121
- if (enableRaw !== void 0) {
122
- mode = "enabled";
123
- rawSelection = enableRaw;
124
- } else if (disableRaw !== void 0) {
125
- mode = "disabled";
126
- rawSelection = disableRaw;
127
- } else if (options.schedules !== void 0) {
128
- rawSelection = options.schedules;
129
- const rawMode = typeof options.scheduleMode === "string" ? options.scheduleMode.trim().toLowerCase() : "disabled";
130
- if (rawMode === "none") {
131
- return null;
132
- }
133
- if (rawMode !== "enabled" && rawMode !== "disabled") {
134
- throw new Error("--schedule-mode must be enabled, disabled, or none");
135
- }
136
- mode = rawMode;
137
- }
138
- if (!mode) {
139
- return null;
140
- }
141
- if (manifest.schedules.length === 0) {
142
- return { mode, schedules: [] };
143
- }
144
- const selectedNames = parseSandboxTemplateScheduleNameSelection(
145
- rawSelection,
146
- manifest
147
- );
148
- const schedules = selectedNames === null ? manifest.schedules : manifest.schedules.filter(
149
- (schedule) => selectedNames.has(schedule.name)
150
- );
151
- return { mode, schedules };
152
- }
153
- function parseSandboxTemplateScheduleNameSelection(value, manifest) {
154
- if (value === void 0 || value === true) {
155
- return null;
156
- }
157
- const raw = String(value).trim();
158
- if (!raw || raw === "true" || raw.toLowerCase() === "all") {
159
- return null;
160
- }
161
- if (raw.toLowerCase() === "none") {
162
- return /* @__PURE__ */ new Set();
163
- }
164
- const known = new Set(manifest.schedules.map((schedule) => schedule.name));
165
- const selected = new Set(
166
- raw.split(",").map((item) => item.trim()).filter(Boolean)
167
- );
168
- for (const name of selected) {
169
- if (!known.has(name)) {
170
- throw new Error(`manifest schedule not found: ${name}`);
171
- }
172
- }
173
- return selected;
174
- }
175
- function parseSandboxTemplateScheduleOverrides(manifest, options) {
176
- const raw = typeof options.scheduleOverrides === "string" ? options.scheduleOverrides : typeof options.scheduleOverride === "string" ? options.scheduleOverride : "";
177
- if (!raw.trim()) {
178
- return /* @__PURE__ */ new Map();
179
- }
180
- const parsed = parseJsonOption(raw, "schedule-overrides");
181
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
182
- throw new Error(
183
- "schedule-overrides must be a JSON object keyed by schedule name"
184
- );
185
- }
186
- const known = new Set(manifest.schedules.map((schedule) => schedule.name));
187
- const out = /* @__PURE__ */ new Map();
188
- for (const [name, override] of Object.entries(parsed)) {
189
- if (!known.has(name)) {
190
- throw new Error(`schedule override target does not exist: ${name}`);
191
- }
192
- if (!override || typeof override !== "object" || Array.isArray(override)) {
193
- throw new Error(`schedule override for ${name} must be an object`);
194
- }
195
- out.set(name, override);
196
- }
197
- return out;
198
- }
199
- function buildSandboxTemplateStartScheduleInput(params) {
200
- const schedule = mergeSandboxTemplateScheduleOverride(
201
- params.schedule,
202
- params.override
203
- );
204
- const expression = sandboxTemplateScheduleExpression(schedule);
205
- return {
206
- sourceSandboxId: params.sourceSandboxId,
207
- ...params.teamId ? { teamId: params.teamId } : {},
208
- ...params.projectId ? { projectId: params.projectId } : {},
209
- name: schedule.name,
210
- ...schedule.description ? { description: schedule.description } : {},
211
- ...expression,
212
- ...schedule.timezone ? { timezone: schedule.timezone } : {},
213
- enabled: typeof params.override?.enabled === "boolean" ? params.override.enabled : params.mode === "enabled",
214
- ...schedule.startAt ? { startAt: schedule.startAt } : {},
215
- ...schedule.endAt ? { endAt: schedule.endAt } : {},
216
- ...schedule.maxRuns !== void 0 ? { maxRuns: schedule.maxRuns } : {},
217
- runtimePolicy: schedule.runtimePolicy,
218
- target: sandboxTemplateScheduleCommandTarget(params.manifest, schedule),
219
- ...schedule.budget ? { budget: schedule.budget } : {},
220
- ...schedule.resources ? { resources: schedule.resources } : {},
221
- ...schedule.quotas ? { quotas: schedule.quotas } : {},
222
- ...schedule.lifecycle ? { lifecycle: schedule.lifecycle } : {},
223
- ...schedule.retentionPolicy ? { retentionPolicy: schedule.retentionPolicy } : {},
224
- ...schedule.env ? { env: schedule.env } : {},
225
- ...schedule.integrationLeases ? {
226
- integrationLeases: schedule.integrationLeases
227
- } : {},
228
- metadata: {
229
- ...schedule.metadata ?? {},
230
- manifestScheduleName: schedule.name,
231
- source: "openpond-code-sandbox-template-start"
232
- },
233
- managementSource: "openpond.yaml",
234
- manifestPath: OPENPOND_MANIFEST_FILE_NAME
235
- };
236
- }
237
- function mergeSandboxTemplateScheduleOverride(schedule, override) {
238
- if (!override) {
239
- return schedule;
240
- }
241
- return {
242
- ...schedule,
243
- ...override,
244
- target: schedule.target || override.target ? {
245
- ...schedule.target ?? {},
246
- ...override.target ?? {}
247
- } : void 0,
248
- metadata: schedule.metadata || override.metadata ? {
249
- ...schedule.metadata ?? {},
250
- ...override.metadata ?? {}
251
- } : void 0
252
- };
253
- }
254
- function sandboxTemplateScheduleExpression(schedule) {
255
- if (schedule.scheduleExpression) {
256
- return {
257
- scheduleType: schedule.scheduleType ?? "cron",
258
- scheduleExpression: schedule.scheduleExpression
259
- };
260
- }
261
- if (schedule.rate) {
262
- return {
263
- scheduleType: "rate",
264
- scheduleExpression: /^rate\(/i.test(schedule.rate) ? schedule.rate : `rate(${schedule.rate})`
265
- };
266
- }
267
- if (schedule.once) {
268
- return {
269
- scheduleType: "once",
270
- scheduleExpression: /^at\(/i.test(schedule.once) ? schedule.once : `at(${schedule.once})`
271
- };
272
- }
273
- return {
274
- scheduleType: "cron",
275
- scheduleExpression: schedule.cron ?? ""
276
- };
277
- }
278
- function sandboxTemplateScheduleCommandTarget(manifest, schedule) {
279
- const explicitCommand = schedule.command ?? schedule.target?.command ?? null;
280
- if (explicitCommand) {
281
- return {
282
- kind: "command",
283
- command: explicitCommand,
284
- requiresStart: schedule.requiresStart ?? schedule.target?.requiresStart ?? false
285
- };
286
- }
287
- const targetKind = schedule.target?.kind ?? "action";
288
- if (targetKind === "start") {
289
- return {
290
- kind: "command",
291
- command: manifest.start.command,
292
- requiresStart: schedule.requiresStart ?? schedule.target?.requiresStart ?? manifest.start.requiresStart ?? false
293
- };
294
- }
295
- if (targetKind === "service") {
296
- const serviceName = schedule.target?.name ?? "";
297
- const service = manifest.services.find((item) => item.name === serviceName);
298
- if (!service) {
299
- throw new Error(`schedule service target does not exist: ${serviceName}`);
300
- }
301
- return {
302
- kind: "command",
303
- command: service.command,
304
- requiresStart: schedule.requiresStart ?? schedule.target?.requiresStart ?? service.requiresStart ?? false
305
- };
306
- }
307
- const actionName = schedule.actionName ?? schedule.action ?? schedule.target?.actionName ?? (schedule.target?.kind === "action" ? schedule.target?.name : void 0);
308
- const action = manifest.actions.find((item) => item.name === actionName);
309
- if (!action) {
310
- throw new Error(
311
- `schedule action target does not exist: ${actionName ?? ""}`
312
- );
313
- }
314
- return {
315
- kind: "command",
316
- command: action.command,
317
- requiresStart: schedule.requiresStart ?? schedule.target?.requiresStart ?? action.requiresStart ?? false
318
- };
319
- }
320
-
321
- // src/cli/sandbox-template-git.ts
322
- import { existsSync } from "node:fs";
323
- import path from "node:path";
324
- import { stdin as input } from "node:process";
325
- async function resolveSandboxTemplateStartRepo(manifest, options, projectPath) {
326
- const explicitRepo = typeof options.repo === "string" ? options.repo.trim() : "";
327
- if (explicitRepo) {
328
- return normalizeSandboxTemplateRepoUrl(explicitRepo);
329
- }
330
- await ensureGitRepository(projectPath);
331
- const config = await loadConfig();
332
- const uiBase = resolveBaseUrl(config);
333
- const apiBase = resolvePublicApiBaseUrl(config);
334
- const apiKey = await ensureApiKey(config, uiBase);
335
- let originUrl = await getGitRemoteUrl(projectPath, "origin");
336
- if (!originUrl) {
337
- const teamId = typeof options.teamId === "string" ? options.teamId.trim() : "";
338
- const response = await createRepo(apiBase, apiKey, {
339
- name: manifest.name,
340
- description: manifest.description,
341
- repoInit: "empty",
342
- ...teamId ? { teamId } : {}
343
- });
344
- originUrl = resolveRepoUrl(response);
345
- const remoteResult = await runCommand(
346
- "git",
347
- ["remote", "add", "origin", originUrl],
348
- {
349
- cwd: projectPath
350
- }
351
- );
352
- if (remoteResult.code !== 0) {
353
- throw new Error(
354
- `git remote add failed: ${remoteResult.stderr.trim() || remoteResult.stdout.trim() || "unknown error"}`
355
- );
356
- }
357
- }
358
- warnOnRepoHostMismatch(originUrl);
359
- await ensureGitCommitForSandboxTemplateStart(projectPath, options);
360
- if (!parseBooleanOption(options.noPush)) {
361
- const branch = await resolveSandboxTemplateStartBranch(
362
- projectPath,
363
- options
364
- );
365
- await pushGitBranchForSandboxTemplateStart(
366
- projectPath,
367
- originUrl,
368
- branch,
369
- apiKey,
370
- options
371
- );
372
- }
373
- return normalizeSandboxTemplateRepoUrl(originUrl);
374
- }
375
- async function ensureGitRepository(projectPath) {
376
- const gitDir = path.join(projectPath, ".git");
377
- if (existsSync(gitDir)) return;
378
- const result = await runCommand("git", ["init"], { cwd: projectPath });
379
- if (result.code !== 0) {
380
- throw new Error(
381
- `git init failed: ${result.stderr.trim() || result.stdout.trim() || "unknown error"}`
382
- );
383
- }
384
- }
385
- async function ensureGitCommitForSandboxTemplateStart(projectPath, options) {
386
- const status = await runCommand("git", ["status", "--porcelain"], {
387
- cwd: projectPath
388
- });
389
- if (status.code !== 0) {
390
- throw new Error(
391
- `git status failed: ${status.stderr.trim() || status.stdout.trim() || "unknown error"}`
392
- );
393
- }
394
- const head = await runCommand("git", ["rev-parse", "--verify", "HEAD"], {
395
- cwd: projectPath
396
- });
397
- const hasHead = head.code === 0;
398
- const dirty = status.stdout.trim().length > 0;
399
- if (!dirty && hasHead) return;
400
- const shouldCommit = parseBooleanOption(options.commit) || parseBooleanOption(options.yes) || (input.isTTY ? await promptConfirm(
401
- hasHead ? "Commit local changes before starting the sandbox?" : "Create the initial git commit before starting the sandbox?",
402
- !hasHead
403
- ) : false);
404
- if (!shouldCommit) {
405
- if (!hasHead) {
406
- throw new Error(
407
- "local repository has no commits; pass --commit or commit before starting"
408
- );
409
- }
410
- if (dirty) {
411
- console.warn(
412
- "warning: uncommitted local changes will not be included in the sandbox"
413
- );
414
- }
415
- return;
416
- }
417
- const add = await runCommand("git", ["add", "-A"], { cwd: projectPath });
418
- if (add.code !== 0) {
419
- throw new Error(
420
- `git add failed: ${add.stderr.trim() || add.stdout.trim() || "unknown error"}`
421
- );
422
- }
423
- const message = typeof options.commitMessage === "string" && options.commitMessage.trim() ? options.commitMessage.trim() : `start ${OPENPOND_MANIFEST_FILE_NAME} sandbox`;
424
- const commit = await runCommand("git", ["commit", "-m", message], {
425
- cwd: projectPath
426
- });
427
- if (commit.code !== 0) {
428
- const output = commit.stderr.trim() || commit.stdout.trim();
429
- if (output.includes("nothing to commit") && hasHead) return;
430
- throw new Error(`git commit failed: ${output || "unknown error"}`);
431
- }
432
- }
433
- async function resolveSandboxTemplateStartBranch(projectPath, options) {
434
- const branchOption = typeof options.branch === "string" ? options.branch.trim() : "";
435
- const branch = branchOption || await resolveGitBranch(projectPath);
436
- if (!branch) {
437
- throw new Error("unable to resolve git branch; pass --branch");
438
- }
439
- return branch;
440
- }
441
- async function pushGitBranchForSandboxTemplateStart(projectPath, originUrl, branch, apiKey, options) {
442
- let tokenRemote;
443
- try {
444
- tokenRemote = formatTokenizedRepoUrl(originUrl, apiKey);
445
- } catch {
446
- throw new Error("origin remote must be https for tokenized pushes");
447
- }
448
- const keepTokenRemote = parseBooleanOption(options.keepTokenRemote) || parseBooleanOption(options.token) || parseBooleanOption(options.setRemoteToken);
449
- const alreadyTokenized = originUrl.includes("x-access-token:");
450
- const restoreUrl = !keepTokenRemote && !alreadyTokenized ? originUrl : null;
451
- const previousPrompt = process.env.GIT_TERMINAL_PROMPT;
452
- process.env.GIT_TERMINAL_PROMPT = "0";
453
- try {
454
- if (!alreadyTokenized) {
455
- const setResult = await runCommand(
456
- "git",
457
- ["remote", "set-url", "origin", tokenRemote],
458
- {
459
- cwd: projectPath
460
- }
461
- );
462
- if (setResult.code !== 0) {
463
- throw new Error(
464
- `git remote set-url failed: ${redactToken(
465
- setResult.stderr.trim() || setResult.stdout.trim() || "unknown error"
466
- )}`
467
- );
468
- }
469
- }
470
- const push = await runCommand("git", ["push", "-u", "origin", branch], {
471
- cwd: projectPath,
472
- inherit: true
473
- });
474
- if (push.code !== 0) {
475
- throw new Error("git push failed");
476
- }
477
- } finally {
478
- if (restoreUrl) {
479
- await runCommand("git", ["remote", "set-url", "origin", restoreUrl], {
480
- cwd: projectPath
481
- }).catch(() => null);
482
- }
483
- if (previousPrompt === void 0) {
484
- delete process.env.GIT_TERMINAL_PROMPT;
485
- } else {
486
- process.env.GIT_TERMINAL_PROMPT = previousPrompt;
487
- }
488
- }
489
- }
490
- function normalizeSandboxTemplateRepoIdentity(repoUrl) {
491
- return normalizeSandboxTemplateRepoUrl(repoUrl).replace(/\.git$/, "");
492
- }
493
- function normalizeSandboxTemplateRepoUrl(repoUrl) {
494
- const parsed = new URL(repoUrl);
495
- parsed.username = "";
496
- parsed.password = "";
497
- const text = parsed.toString();
498
- return text.endsWith(".git") ? text : `${text.replace(/\/$/, "")}.git`;
499
- }
500
-
501
- // src/cli/sandbox-template-start.ts
502
- async function runSandboxTemplateStart(options) {
503
- const filePath = resolveSandboxTemplateFilePath(options);
504
- const projectPath = path2.dirname(filePath);
505
- const source = await fs.readFile(filePath, "utf8");
506
- const result = validateSandboxTemplateYaml(source);
507
- if (!result.ok) {
508
- console.error(formatSandboxTemplateDiagnostics(result.diagnostics));
509
- process.exitCode = 1;
510
- return;
511
- }
512
- const manifest = result.manifest;
513
- const executable = resolveSandboxTemplateStartExecutable(manifest, options);
514
- const input2 = await resolveSandboxTemplateStartInput(
515
- manifest,
516
- options,
517
- projectPath
518
- );
519
- const repo = await resolveSandboxTemplateStartRepo(
520
- manifest,
521
- options,
522
- projectPath
523
- );
524
- const client = await resolveSandboxClient(options);
525
- const createInput = buildSandboxTemplateStartCreateInput(
526
- manifest,
527
- options,
528
- repo
529
- );
530
- const sandbox = await createSandboxTemplateStartSandbox(
531
- client,
532
- createInput,
533
- repo
534
- );
535
- await waitForSandboxTemplateRunnerReady(client, sandbox.id);
536
- const setupCommands = await runSandboxTemplateSetupCommands(
537
- client,
538
- sandbox.id,
539
- manifest,
540
- options
541
- );
542
- const uploadedFiles = await uploadSandboxTemplateStartFiles(
543
- client,
544
- sandbox.id,
545
- input2.uploadRequests
546
- );
547
- const commandInput = {
548
- ...input2.scalars,
549
- ...formatUploadedFileParams(uploadedFiles, input2.uploadRequests)
550
- };
551
- const execution = await runSandboxTemplateExecutable(
552
- client,
553
- sandbox.id,
554
- executable,
555
- commandInput,
556
- sandboxTemplateRuntimeEnv(sandbox)
557
- );
558
- const previews = await openSandboxTemplatePorts(
559
- client,
560
- sandbox.id,
561
- executable.ports
562
- );
563
- const schedules = await createSandboxTemplateStartSchedules(
564
- client,
565
- sandbox.id,
566
- manifest,
567
- options
568
- );
569
- console.log(
570
- JSON.stringify(
571
- {
572
- ok: true,
573
- file: filePath,
574
- repo,
575
- executable: {
576
- kind: executable.kind,
577
- name: executable.name,
578
- command: executable.command
579
- },
580
- sandbox: summarizeSandbox(sandbox),
581
- setupCommands,
582
- uploadedFiles,
583
- input: commandInput,
584
- execution,
585
- previews,
586
- schedules,
587
- expectedArtifacts: executable.artifactPaths
588
- },
589
- null,
590
- 2
591
- )
592
- );
593
- }
594
- function resolveSandboxTemplateStartExecutable(manifest, options) {
595
- const executables = sandboxTemplateExecutableEntries(manifest);
596
- const action = typeof options.action === "string" ? options.action.trim() : "";
597
- const service = typeof options.service === "string" ? options.service.trim() : "";
598
- const target = typeof options.target === "string" ? options.target.trim() : "";
599
- const entrypoint = typeof options.entrypoint === "string" ? options.entrypoint.trim() : "";
600
- const requested = action || service || target || entrypoint || "start";
601
- const kind = action ? "action" : service ? "service" : "";
602
- const match = executables.find(
603
- (candidate) => candidate.name === requested && (!kind || candidate.kind === kind)
604
- );
605
- if (!match) {
606
- throw new Error(
607
- `manifest executable not found: ${requested}. Available: ${executables.map((candidate) => `${candidate.kind}:${candidate.name}`).join(", ")}`
608
- );
609
- }
610
- return match;
611
- }
612
- function buildSandboxTemplateStartCreateInput(manifest, options, repo) {
613
- const budgetUsd = typeof options.budgetUsd === "string" && options.budgetUsd.trim() ? options.budgetUsd.trim() : typeof options.budget === "string" && options.budget.trim() ? options.budget.trim() : "0.05";
614
- const maxDurationSeconds = parseIntegerOption(
615
- options.maxDurationSeconds,
616
- "max-duration-seconds"
617
- );
618
- const idleTimeoutSeconds = parseIntegerOption(
619
- options.idleTimeoutSeconds,
620
- "idle-timeout-seconds"
621
- );
622
- const teamId = typeof options.teamId === "string" ? options.teamId.trim() : "";
623
- const requestedProjectId = typeof options.projectId === "string" ? options.projectId.trim() : "";
624
- const sandboxRuntimeProjectId = typeof options.runtimeProjectId === "string" ? options.runtimeProjectId.trim() : "";
625
- if (requestedProjectId && sandboxRuntimeProjectId && requestedProjectId !== sandboxRuntimeProjectId) {
626
- throw new Error(
627
- "project-id and runtime-project-id must match when both are set"
628
- );
629
- }
630
- const projectId = requestedProjectId || sandboxRuntimeProjectId;
631
- const requestedAgentId = typeof options.agentId === "string" ? options.agentId.trim() : "";
632
- const sandboxRuntimeAgentId = typeof options.runtimeAgentId === "string" ? options.runtimeAgentId.trim() : "";
633
- if (requestedAgentId && sandboxRuntimeAgentId && requestedAgentId !== sandboxRuntimeAgentId) {
634
- throw new Error(
635
- "agent-id and runtime-agent-id must match when both are set"
636
- );
637
- }
638
- const agentId = requestedAgentId || sandboxRuntimeAgentId;
639
- const sandboxWorkflowMode = parseSandboxWorkflowModeOption(options.workflowMode);
640
- const sandboxRuntimePromotionPolicy = parseSandboxRuntimePromotionPolicyOption(options.runtimePromotionPolicy);
641
- const sandboxRuntimeBaseBranch = typeof options.runtimeBaseBranch === "string" && options.runtimeBaseBranch.trim() ? options.runtimeBaseBranch.trim() : "";
642
- const sandboxRuntimeBaseSha = typeof options.runtimeBaseSha === "string" && options.runtimeBaseSha.trim() ? options.runtimeBaseSha.trim() : "";
643
- const runtimeId = typeof options.runtimeId === "string" && options.runtimeId.trim() ? options.runtimeId.trim() : "";
644
- const sandboxRuntimeRequested = Boolean(
645
- sandboxWorkflowMode || sandboxRuntimePromotionPolicy || sandboxRuntimeBaseBranch || sandboxRuntimeBaseSha || runtimeId || sandboxRuntimeProjectId || sandboxRuntimeAgentId
646
- );
647
- const env = parseSandboxTemplateEnvOptions(manifest, options);
648
- const workloadSource = sandboxWorkloadSourceFromManifest(manifest);
649
- const sandbox = {
650
- repo,
651
- ...teamId ? { teamId } : {},
652
- ...projectId ? { projectId } : {},
653
- ...agentId ? { agentId } : {},
654
- resources: manifest.resources ?? {},
655
- networkPolicy: {
656
- internetEgress: sandboxTemplateInternetEgressPolicy(
657
- manifest.network.egress
658
- )
659
- },
660
- budget: { maxUsd: budgetUsd },
661
- quotas: {
662
- maxSpendUsd: budgetUsd,
663
- ...maxDurationSeconds !== void 0 ? { maxDurationSeconds } : {},
664
- ...idleTimeoutSeconds !== void 0 ? { idleTimeoutSeconds } : {}
665
- },
666
- ...env.length > 0 ? { env } : {},
667
- ...workloadSource ? { workloadSource } : {},
668
- volumes: manifest.volumes,
669
- metadata: {
670
- source: "openpond-code-sandbox-template-start",
671
- manifestFile: OPENPOND_MANIFEST_FILE_NAME,
672
- template: {
673
- name: manifest.name,
674
- version: manifest.version,
675
- useCase: manifest.useCase
676
- }
677
- }
678
- };
679
- return {
680
- sandbox,
681
- ...sandboxRuntimeRequested && runtimeId ? { runtimeId } : {},
682
- ...sandboxRuntimeRequested && !runtimeId ? {
683
- sandboxRuntime: {
684
- ...teamId ? { teamId } : {},
685
- ...sandboxWorkflowMode ? { workflowMode: sandboxWorkflowMode } : {},
686
- ...projectId ? { projectId } : {},
687
- ...agentId ? { agentId } : {},
688
- baseBranch: sandboxRuntimeBaseBranch || "master",
689
- ...sandboxRuntimeBaseSha ? { baseSha: sandboxRuntimeBaseSha } : {},
690
- ...sandboxRuntimePromotionPolicy ? { promotionPolicy: sandboxRuntimePromotionPolicy } : {}
691
- }
692
- } : {}
693
- };
694
- }
695
- function sandboxWorkloadSourceFromManifest(manifest) {
696
- if (manifest.runtime.image) {
697
- return { image: manifest.runtime.image };
698
- }
699
- if (manifest.runtime.dockerfile) {
700
- return { dockerfile: manifest.runtime.dockerfile };
701
- }
702
- return void 0;
703
- }
704
- function sandboxTemplateInternetEgressPolicy(egress) {
705
- return egress === "allow" ? "allow" : "block";
706
- }
707
- async function createSandboxTemplateStartSandbox(client, plan, repo) {
708
- const requestedAt = Date.now();
709
- try {
710
- return (await createSandboxFromPlan(client, plan)).sandbox;
711
- } catch (error) {
712
- if (!isLikelySandboxCreateTimeout(error)) {
713
- throw error;
714
- }
715
- console.warn(
716
- "warning: sandbox create timed out; checking for the created sandbox record"
717
- );
718
- return recoverTimedOutSandboxCreate(
719
- client,
720
- plan.sandbox,
721
- repo,
722
- requestedAt
723
- );
724
- }
725
- }
726
- function isLikelySandboxCreateTimeout(error) {
727
- return error instanceof Error && /\b(504|timed out|timeout)\b/i.test(error.message);
728
- }
729
- async function recoverTimedOutSandboxCreate(client, input2, repo, requestedAt) {
730
- const timeoutMs = 12 * 6e4;
731
- const pollMs = 3e3;
732
- const deadline = Date.now() + timeoutMs;
733
- const repoIdentity = normalizeSandboxTemplateRepoIdentity(repo);
734
- const metadata = input2.metadata ?? {};
735
- while (Date.now() < deadline) {
736
- const sandboxes = await client.list({
737
- ...input2.teamId ? { teamId: input2.teamId } : {},
738
- ...input2.projectId ? { projectId: input2.projectId } : {},
739
- ...input2.agentId ? { agentId: input2.agentId } : {}
740
- });
741
- const match = sandboxes.filter((sandbox) => {
742
- if (!sandbox.repo) return false;
743
- if (normalizeSandboxTemplateRepoIdentity(sandbox.repo) !== repoIdentity)
744
- return false;
745
- const createdAt = Date.parse(sandbox.createdAt);
746
- if (Number.isFinite(createdAt) && createdAt < requestedAt - 3e4)
747
- return false;
748
- if (metadata.source && sandbox.metadata?.source !== metadata.source)
749
- return false;
750
- return true;
751
- }).sort(
752
- (left, right) => Date.parse(right.createdAt) - Date.parse(left.createdAt)
753
- )[0];
754
- if (match?.state === "running" || match?.state === "stopped") {
755
- return match;
756
- }
757
- if (match?.state === "error") {
758
- throw new Error(
759
- `sandbox create failed after timeout: ${match.id}
760
- ${match.logs.join(
761
- "\n"
762
- )}`
763
- );
764
- }
765
- await sleep(pollMs);
766
- }
767
- throw new Error(
768
- "sandbox create timed out and no matching created sandbox reached running state"
769
- );
770
- }
771
- async function waitForSandboxTemplateRunnerReady(client, sandboxId) {
772
- const timeoutMs = 12e4;
773
- const pollMs = 3e3;
774
- const deadline = Date.now() + timeoutMs;
775
- let lastError = null;
776
- while (Date.now() < deadline) {
777
- try {
778
- const result = await client.exec(sandboxId, {
779
- command: "true",
780
- timeoutSeconds: 30
781
- });
782
- if (result.command.status === "succeeded" && result.command.exitCode === 0) {
783
- return;
784
- }
785
- lastError = new Error(
786
- `readiness command ${result.command.status} with exit code ${String(
787
- result.command.exitCode
788
- )}`
789
- );
790
- } catch (error) {
791
- lastError = error;
792
- if (!isRetryableSandboxRunnerReadyError(error)) {
793
- throw error;
794
- }
795
- }
796
- await sleep(pollMs);
797
- }
798
- throw new Error(
799
- `sandbox runner was not ready after create: ${formatUnknownError(
800
- lastError
801
- )}`
802
- );
803
- }
804
- function isRetryableSandboxRunnerReadyError(error) {
805
- return error instanceof Error && /\b(502|503|504|timed out|timeout|sandbox_not_found|sandbox_not_ready|sandbox_runner_failed)\b/i.test(
806
- error.message
807
- );
808
- }
809
- function formatUnknownError(error) {
810
- if (error instanceof Error) return error.message;
811
- if (typeof error === "string") return error;
812
- return "unknown error";
813
- }
814
- function sleep(ms) {
815
- return new Promise((resolve) => setTimeout(resolve, ms));
816
- }
817
- async function resolveSandboxTemplateStartInput(manifest, options, projectPath) {
818
- const scalars = parseSandboxTemplateScalarInputs(options);
819
- const uploadSpecs = collectSandboxTemplateUploadSpecs(manifest);
820
- const uploadRequests = [];
821
- const fileInputs = parseSandboxTemplateFileInputOptions(options);
822
- for (const [inputName, rawValue] of Object.entries(fileInputs)) {
823
- const spec = uploadSpecs.get(inputName);
824
- if (!spec) {
825
- throw new Error(
826
- `${inputName} is not declared as a file upload input in ${OPENPOND_MANIFEST_FILE_NAME}`
827
- );
828
- }
829
- const localPaths = await expandSandboxTemplateUploadPaths(
830
- rawValue,
831
- projectPath
832
- );
833
- if (!spec.multiple && localPaths.length > 1) {
834
- throw new Error(
835
- `${inputName} accepts one file, got ${localPaths.length}`
836
- );
837
- }
838
- uploadRequests.push({ inputName, localPaths, spec });
839
- }
840
- const requiredInputs = Array.isArray(manifest.inputs.schema.required) ? manifest.inputs.schema.required.filter(
841
- (value) => typeof value === "string"
842
- ) : [];
843
- for (const inputName of requiredInputs) {
844
- if (uploadSpecs.has(inputName) && !uploadRequests.some((request) => request.inputName === inputName)) {
845
- throw new Error(
846
- `${inputName} is required; pass --input-file ${inputName}=<path> or --input-files ${inputName}=<glob>`
847
- );
848
- }
849
- }
850
- return { scalars, uploadRequests };
851
- }
852
- function parseSandboxTemplateScalarInputs(options) {
853
- const rawInputs = typeof options.inputs === "string" ? options.inputs : typeof options.inputJson === "string" ? options.inputJson : typeof options.params === "string" ? options.params : "";
854
- const scalars = rawInputs ? parseJsonOption(rawInputs, "inputs") : {};
855
- if (!scalars || typeof scalars !== "object" || Array.isArray(scalars)) {
856
- throw new Error("inputs must be a JSON object");
857
- }
858
- const rawInput = typeof options.input === "string" ? options.input.trim() : "";
859
- if (rawInput) {
860
- const [name, value] = parseKeyValueOption(rawInput, "input");
861
- scalars[name] = value;
862
- }
863
- return scalars;
864
- }
865
- function parseSandboxTemplateFileInputOptions(options) {
866
- const out = {};
867
- const rawFile = typeof options.inputFile === "string" ? options.inputFile.trim() : "";
868
- if (rawFile) {
869
- const [name, value] = parseKeyValueOption(rawFile, "input-file");
870
- out[name] = value;
871
- }
872
- const rawFiles = typeof options.inputFiles === "string" ? options.inputFiles.trim() : "";
873
- if (rawFiles) {
874
- const [name, value] = parseKeyValueOption(rawFiles, "input-files");
875
- out[name] = value;
876
- }
877
- return out;
878
- }
879
- function parseKeyValueOption(value, label) {
880
- const index = value.indexOf("=");
881
- if (index <= 0) {
882
- throw new Error(`${label} must be formatted as name=value`);
883
- }
884
- const key = value.slice(0, index).trim();
885
- const raw = value.slice(index + 1).trim();
886
- if (!key || !raw) {
887
- throw new Error(`${label} must be formatted as name=value`);
888
- }
889
- return [key, raw];
890
- }
891
- function collectSandboxTemplateUploadSpecs(manifest) {
892
- const properties = asPlainRecord(manifest.inputs.schema.properties) ?? {};
893
- const specs = /* @__PURE__ */ new Map();
894
- for (const [inputName, rawProperty] of Object.entries(properties)) {
895
- const property = asPlainRecord(rawProperty);
896
- if (!property) continue;
897
- const upload = asPlainRecord(
898
- property["x-openpond-upload"] ?? property.xOpenPondUpload
899
- );
900
- if (!upload) continue;
901
- const targetPath = typeof upload.targetPath === "string" && upload.targetPath.trim() ? normalizeSandboxUploadTargetPath(upload.targetPath) : "";
902
- if (!targetPath) {
903
- throw new Error(`${inputName} upload metadata is missing targetPath`);
904
- }
905
- const multiple = upload.multiple === true || property.type === "array" || asPlainRecord(property.items)?.format === "file";
906
- specs.set(inputName, { inputName, multiple, targetPath });
907
- }
908
- return specs;
909
- }
910
- function asPlainRecord(value) {
911
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
912
- return value;
913
- }
914
- function normalizeSandboxUploadTargetPath(value) {
915
- const normalized = value.trim().replace(/\\/g, "/").replace(/^\/workspace\//, "").replace(/^\.\//, "").replace(/^\/+/, "");
916
- if (!normalized || normalized.split("/").some((segment) => segment === ".." || segment === "")) {
917
- throw new Error(`invalid upload target path: ${value}`);
918
- }
919
- if (normalized.split("/").some(isSandboxEnvFileName)) {
920
- throw new Error(
921
- "sandbox template uploads cannot target .env* files; create sandbox secrets and pass refs with --env-ref"
922
- );
923
- }
924
- return normalized;
925
- }
926
- async function expandSandboxTemplateUploadPaths(rawValue, projectPath) {
927
- const values = rawValue.split(",").map((item) => item.trim()).filter(Boolean);
928
- const paths = (await Promise.all(
929
- values.map((value) => expandSandboxTemplateUploadPath(value, projectPath))
930
- )).flat();
931
- if (paths.length === 0) {
932
- throw new Error(`no files matched ${rawValue}`);
933
- }
934
- return paths;
935
- }
936
- async function expandSandboxTemplateUploadPath(rawValue, projectPath) {
937
- const absolute = path2.resolve(projectPath, rawValue);
938
- if (!rawValue.includes("*")) {
939
- assertSandboxTemplateUploadPathAllowed(absolute);
940
- const stats = await fs.stat(absolute);
941
- if (!stats.isFile()) {
942
- throw new Error(`upload path is not a file: ${absolute}`);
943
- }
944
- return [absolute];
945
- }
946
- const directory = path2.dirname(absolute);
947
- const basename = path2.basename(absolute);
948
- const regex = globBasenameToRegExp(basename);
949
- const entries = await fs.readdir(directory, { withFileTypes: true });
950
- const matchingEntries = entries.filter((entry) => entry.isFile() && regex.test(entry.name)).sort((left, right) => left.name.localeCompare(right.name));
951
- const blocked = matchingEntries.find(
952
- (entry) => isSandboxEnvFileName(entry.name)
953
- );
954
- if (blocked) {
955
- throw new Error(
956
- "sandbox template uploads cannot include .env* files; create sandbox secrets and pass refs with --env-ref"
957
- );
958
- }
959
- return matchingEntries.map((entry) => path2.join(directory, entry.name)).sort((left, right) => left.localeCompare(right));
960
- }
961
- function assertSandboxTemplateUploadPathAllowed(localPath) {
962
- if (isSandboxEnvFileName(path2.basename(localPath))) {
963
- throw new Error(
964
- "sandbox template uploads cannot include .env* files; create sandbox secrets and pass refs with --env-ref"
965
- );
966
- }
967
- }
968
- function isSandboxEnvFileName(name) {
969
- return name === ".env" || name.startsWith(".env.");
970
- }
971
- function globBasenameToRegExp(pattern) {
972
- const escaped = pattern.split("*").map((part) => part.replace(/[.+?^${}()|[\]\\]/g, "\\$&")).join(".*");
973
- return new RegExp(`^${escaped}$`);
974
- }
975
- async function runSandboxTemplateSetupCommands(client, sandboxId, manifest, options) {
976
- const timeoutSeconds = parseIntegerOption(options.setupTimeoutSeconds, "setup-timeout-seconds") ?? 900;
977
- const results = [];
978
- for (const command of manifest.setup.commands) {
979
- const result = await runSandboxTemplateShellCommand(
980
- client,
981
- sandboxId,
982
- command,
983
- timeoutSeconds
984
- );
985
- results.push({
986
- command,
987
- status: result.status,
988
- exitCode: result.exitCode
989
- });
990
- if (result.status !== "succeeded" || result.exitCode !== 0) {
991
- throw new Error(`setup command failed: ${command}
992
- ${result.output}`);
993
- }
994
- }
995
- return results;
996
- }
997
- async function uploadSandboxTemplateStartFiles(client, sandboxId, requests) {
998
- const uploaded = [];
999
- for (const request of requests) {
1000
- for (const localPath of request.localPaths) {
1001
- const contents = await fs.readFile(localPath);
1002
- const sandboxPath = joinSandboxUploadPath(
1003
- request.spec.targetPath,
1004
- path2.basename(localPath)
1005
- );
1006
- await client.uploadFileBase64(
1007
- sandboxId,
1008
- sandboxPath,
1009
- contents.toString("base64")
1010
- );
1011
- uploaded.push({
1012
- inputName: request.inputName,
1013
- localPath,
1014
- sandboxPath,
1015
- sizeBytes: contents.byteLength
1016
- });
1017
- }
1018
- }
1019
- return uploaded;
1020
- }
1021
- function joinSandboxUploadPath(targetPath, basename) {
1022
- return `${targetPath.replace(/\/+$/, "")}/${basename.replace(/^\/+/, "")}`;
1023
- }
1024
- function formatUploadedFileParams(uploadedFiles, requests) {
1025
- const out = {};
1026
- for (const request of requests) {
1027
- const files = uploadedFiles.filter((file) => file.inputName === request.inputName).map((file) => file.sandboxPath);
1028
- out[request.inputName] = request.spec.multiple ? files : files[0] ?? "";
1029
- }
1030
- return out;
1031
- }
1032
- async function runSandboxTemplateExecutable(client, sandboxId, executable, input2, env = {}) {
1033
- await uploadSandboxTemplateReplayParams(client, sandboxId, input2);
1034
- const command = formatSandboxTemplateCommand(executable, env);
1035
- const timeoutSeconds = executable.timeoutSeconds;
1036
- if (executable.kind === "service") {
1037
- const result2 = await client.startProcess(sandboxId, {
1038
- command,
1039
- ...timeoutSeconds !== void 0 ? { timeoutSeconds } : {}
1040
- });
1041
- return { kind: "service", process: result2.process };
1042
- }
1043
- const result = await runSandboxTemplateProcessToCompletion(
1044
- client,
1045
- sandboxId,
1046
- command,
1047
- timeoutSeconds ?? 900
1048
- );
1049
- if (result.status !== "succeeded" || result.exitCode !== 0) {
1050
- throw new Error(
1051
- `template command failed: ${executable.name}
1052
- ${result.output}`
1053
- );
1054
- }
1055
- return { kind: executable.kind, process: result };
1056
- }
1057
- async function runSandboxTemplateShellCommand(client, sandboxId, command, timeoutSeconds) {
1058
- return runSandboxTemplateProcessToCompletion(
1059
- client,
1060
- sandboxId,
1061
- command,
1062
- timeoutSeconds ?? 900
1063
- );
1064
- }
1065
- async function uploadSandboxTemplateReplayParams(client, sandboxId, input2) {
1066
- const paramsJson = `${JSON.stringify({ input: input2 }, null, 2)}
1067
- `;
1068
- await client.uploadFileBase64(
1069
- sandboxId,
1070
- "openpond-replay-params.json",
1071
- Buffer.from(paramsJson, "utf8").toString("base64")
1072
- );
1073
- }
1074
- async function runSandboxTemplateProcessToCompletion(client, sandboxId, command, timeoutSeconds) {
1075
- const started = await client.startProcess(sandboxId, {
1076
- command,
1077
- timeoutSeconds
1078
- });
1079
- let current = started.process;
1080
- const deadline = Date.now() + timeoutSeconds * 1e3 + 3e4;
1081
- while (current.status === "running" && Date.now() < deadline) {
1082
- await sleep(3e3);
1083
- const polled = await client.getProcess(sandboxId, current.id);
1084
- current = polled.process;
1085
- }
1086
- return {
1087
- command: current.command,
1088
- status: current.status,
1089
- output: current.output,
1090
- exitCode: current.exitCode,
1091
- processId: current.id
1092
- };
1093
- }
1094
- function sandboxTemplateRuntimeEnv(sandbox) {
1095
- return {
1096
- OPENPOND_SANDBOX_ID: sandbox.id,
1097
- ...sandbox.runtimeId ? { OPENPOND_SANDBOX_RUNTIME_ID: sandbox.runtimeId } : {}
1098
- };
1099
- }
1100
- function formatSandboxTemplateCommand(executable, env = {}) {
1101
- const paramsPath = quoteShellArg(replayParamsPathForExecutable(executable));
1102
- const envPrefix = `OPENPOND_REPLAY_PARAMS_BASE64="$(base64 -w0 ${paramsPath} 2>/dev/null || base64 ${paramsPath} | tr -d '\\n')"`;
1103
- const runtimeEnvPrefix = Object.entries(env).filter(([, value]) => value.length > 0).map(([name, value]) => `${name}=${quoteShellArg(value)}`).join(" ");
1104
- const command = [runtimeEnvPrefix, envPrefix, executable.command].filter(Boolean).join(" ");
1105
- if (!executable.cwd) return command;
1106
- return `cd ${quoteShellArg(executable.cwd)} && ${command}`;
1107
- }
1108
- function replayParamsPathForExecutable(executable) {
1109
- if (!executable.cwd) return "openpond-replay-params.json";
1110
- const cwd = executable.cwd.replace(/\\/g, "/").replace(/\/+$/, "") || ".";
1111
- return path2.posix.relative(cwd, "openpond-replay-params.json") || "openpond-replay-params.json";
1112
- }
1113
- function quoteShellArg(value) {
1114
- return `'${value.replace(/'/g, "'\\''")}'`;
1115
- }
1116
- async function openSandboxTemplatePorts(client, sandboxId, ports) {
1117
- const previews = [];
1118
- for (const port of ports) {
1119
- const result = await client.openPort(sandboxId, {
1120
- port: port.port,
1121
- ...port.label ? { label: port.label } : {},
1122
- access: port.access,
1123
- autoStart: false
1124
- });
1125
- previews.push(result.preview);
1126
- }
1127
- return previews;
1128
- }
1129
- function resolveSandboxTemplateFilePath(options) {
1130
- const rawFile = typeof options.file === "string" && options.file.trim().length > 0 ? options.file.trim() : typeof options.manifest === "string" && options.manifest.trim().length > 0 ? options.manifest.trim() : OPENPOND_MANIFEST_FILE_NAME;
1131
- return path2.resolve(process.cwd(), rawFile);
1132
- }
1133
- function resolveSandboxTemplateScaffoldPath(options) {
1134
- const rawPath = typeof options.path === "string" && options.path.trim().length > 0 ? options.path.trim() : typeof options.dir === "string" && options.dir.trim().length > 0 ? options.dir.trim() : process.cwd();
1135
- return path2.resolve(process.cwd(), rawPath);
1136
- }
1137
-
1138
- // src/cli/sandbox-template-local.ts
1139
- async function runSandboxTemplateLocal(options, mode) {
1140
- const { plan, filePath, projectPath } = await loadSandboxTemplateBuildPlan(
1141
- options
1142
- );
1143
- const executable = resolveSandboxTemplateLocalExecutable(
1144
- plan.manifest,
1145
- options,
1146
- mode
1147
- );
1148
- const input2 = await resolveSandboxTemplateStartInput(
1149
- plan.manifest,
1150
- options,
1151
- projectPath
1152
- );
1153
- const volumes = await prepareLocalSandboxTemplateVolumes(
1154
- plan.manifest,
1155
- projectPath
1156
- );
1157
- const setupCommands = await runLocalSandboxTemplateSetupCommands(
1158
- plan.manifest,
1159
- projectPath,
1160
- options
1161
- );
1162
- const uploadedFiles = await prepareLocalSandboxTemplateUploads(
1163
- input2.uploadRequests,
1164
- projectPath
1165
- );
1166
- const commandInput = {
1167
- ...input2.scalars,
1168
- ...formatUploadedFileParams(uploadedFiles, input2.uploadRequests)
1169
- };
1170
- const replay = await writeLocalSandboxTemplateReplayParams(
1171
- projectPath,
1172
- executable,
1173
- commandInput
1174
- );
1175
- const previews = localSandboxTemplatePreviews(executable);
1176
- if (mode === "dev" || executable.kind === "service") {
1177
- console.log(
1178
- JSON.stringify(
1179
- {
1180
- ok: true,
1181
- mode,
1182
- file: filePath,
1183
- template: plan.manifest.name,
1184
- executable: summarizeSandboxTemplateExecutable(executable),
1185
- volumes,
1186
- setupCommands,
1187
- uploadedFiles,
1188
- input: commandInput,
1189
- replayParamsPath: replay.paramsPath,
1190
- previews,
1191
- status: "starting"
1192
- },
1193
- null,
1194
- 2
1195
- )
1196
- );
1197
- const result = await runLocalSandboxTemplateCommand(
1198
- projectPath,
1199
- executable,
1200
- replay,
1201
- {
1202
- inherit: true,
1203
- timeoutSeconds: executable.timeoutSeconds
1204
- }
1205
- );
1206
- if (result.status !== "succeeded") process.exitCode = 1;
1207
- return;
1208
- }
1209
- const execution = await runLocalSandboxTemplateCommand(
1210
- projectPath,
1211
- executable,
1212
- replay,
1213
- {
1214
- timeoutSeconds: executable.timeoutSeconds ?? 900
1215
- }
1216
- );
1217
- const artifacts = await collectLocalSandboxTemplateArtifacts(
1218
- projectPath,
1219
- executable.artifactPaths
1220
- );
1221
- if (execution.status !== "succeeded") process.exitCode = 1;
1222
- console.log(
1223
- JSON.stringify(
1224
- {
1225
- ok: execution.status === "succeeded",
1226
- mode,
1227
- file: filePath,
1228
- template: plan.manifest.name,
1229
- executable: summarizeSandboxTemplateExecutable(executable),
1230
- volumes,
1231
- setupCommands,
1232
- uploadedFiles,
1233
- input: commandInput,
1234
- replayParamsPath: replay.paramsPath,
1235
- execution,
1236
- previews,
1237
- artifacts
1238
- },
1239
- null,
1240
- 2
1241
- )
1242
- );
1243
- }
1244
- async function runSandboxTemplateExistingSandboxAction(options, rest) {
1245
- const sandboxId = rest[0]?.trim() || (typeof options.sandboxId === "string" ? options.sandboxId.trim() : "");
1246
- const actionName = rest[1]?.trim() || (typeof options.action === "string" ? options.action.trim() : "") || (typeof options.target === "string" ? options.target.trim() : "");
1247
- if (!sandboxId || !actionName) {
1248
- throw new Error(
1249
- `usage: sandbox-template action <sandboxId> <actionName> [--file ${OPENPOND_MANIFEST_FILE_NAME}]`
1250
- );
1251
- }
1252
- const { plan, filePath, projectPath } = await loadSandboxTemplateBuildPlan(
1253
- options
1254
- );
1255
- const executable = resolveSandboxTemplateActionExecutable(
1256
- plan.manifest,
1257
- actionName
1258
- );
1259
- const input2 = await resolveSandboxTemplateStartInput(
1260
- plan.manifest,
1261
- options,
1262
- projectPath
1263
- );
1264
- const client = await resolveSandboxClient(options);
1265
- const uploadedFiles = await uploadSandboxTemplateStartFiles(
1266
- client,
1267
- sandboxId,
1268
- input2.uploadRequests
1269
- );
1270
- const commandInput = {
1271
- ...input2.scalars,
1272
- ...formatUploadedFileParams(uploadedFiles, input2.uploadRequests)
1273
- };
1274
- const execution = await runSandboxTemplateExecutable(
1275
- client,
1276
- sandboxId,
1277
- executable,
1278
- commandInput
1279
- );
1280
- console.log(
1281
- JSON.stringify(
1282
- {
1283
- ok: true,
1284
- file: filePath,
1285
- sandboxId,
1286
- executable: summarizeSandboxTemplateExecutable(executable),
1287
- uploadedFiles,
1288
- input: commandInput,
1289
- execution,
1290
- expectedArtifacts: executable.artifactPaths
1291
- },
1292
- null,
1293
- 2
1294
- )
1295
- );
1296
- }
1297
- function resolveSandboxTemplateLocalExecutable(manifest, options, mode) {
1298
- if (mode === "dev" && typeof options.target !== "string" && typeof options.action !== "string" && typeof options.service !== "string" && typeof options.entrypoint !== "string") {
1299
- const firstService = sandboxTemplateExecutableEntries(manifest).find(
1300
- (candidate) => candidate.kind === "service"
1301
- );
1302
- if (firstService) return firstService;
1303
- }
1304
- return resolveSandboxTemplateStartExecutable(manifest, options);
1305
- }
1306
- function resolveSandboxTemplateActionExecutable(manifest, actionName) {
1307
- const match = sandboxTemplateExecutableEntries(manifest).find(
1308
- (candidate) => candidate.kind === "action" && candidate.name === actionName
1309
- );
1310
- if (!match) {
1311
- const actions = manifest.actions.map((action) => action.name).join(", ") || "(none)";
1312
- throw new Error(
1313
- `manifest action not found: ${actionName}. Available actions: ${actions}`
1314
- );
1315
- }
1316
- return match;
1317
- }
1318
- function summarizeSandboxTemplateExecutable(executable) {
1319
- return {
1320
- kind: executable.kind,
1321
- name: executable.name,
1322
- command: executable.command,
1323
- cwd: executable.cwd ?? null,
1324
- timeoutSeconds: executable.timeoutSeconds ?? null,
1325
- ports: executable.ports,
1326
- artifactPaths: executable.artifactPaths
1327
- };
1328
- }
1329
- async function prepareLocalSandboxTemplateVolumes(manifest, projectPath) {
1330
- const volumes = [];
1331
- for (const volume of manifest.volumes) {
1332
- const mountPath = typeof volume.mountPath === "string" && volume.mountPath.trim() ? volume.mountPath.trim() : volume.name ? `/workspace/volumes/${volume.name}` : "";
1333
- if (!mountPath) continue;
1334
- const localPath = path3.resolve(
1335
- projectPath,
1336
- normalizeLocalWorkspacePath(mountPath)
1337
- );
1338
- await fs2.mkdir(localPath, { recursive: true });
1339
- volumes.push({
1340
- name: volume.name ?? null,
1341
- mountPath,
1342
- localPath
1343
- });
1344
- }
1345
- return volumes;
1346
- }
1347
- async function runLocalSandboxTemplateSetupCommands(manifest, projectPath, options) {
1348
- const timeoutSeconds = parseIntegerOption(options.setupTimeoutSeconds, "setup-timeout-seconds") ?? 900;
1349
- const results = [];
1350
- for (const command of manifest.setup.commands) {
1351
- const result = await runLocalShellCommandResult(command, projectPath, {
1352
- timeoutSeconds
1353
- });
1354
- results.push(result);
1355
- if (result.status !== "succeeded") {
1356
- throw new Error(
1357
- `local setup command failed: ${command}
1358
- ${result.output}`
1359
- );
1360
- }
1361
- }
1362
- return results;
1363
- }
1364
- async function prepareLocalSandboxTemplateUploads(requests, projectPath) {
1365
- const uploaded = [];
1366
- for (const request of requests) {
1367
- for (const localPath of request.localPaths) {
1368
- const contents = await fs2.readFile(localPath);
1369
- const sandboxPath = joinSandboxUploadPath(
1370
- request.spec.targetPath,
1371
- path3.basename(localPath)
1372
- );
1373
- const destination = path3.resolve(
1374
- projectPath,
1375
- normalizeLocalWorkspacePath(sandboxPath)
1376
- );
1377
- await fs2.mkdir(path3.dirname(destination), { recursive: true });
1378
- await fs2.copyFile(localPath, destination);
1379
- uploaded.push({
1380
- inputName: request.inputName,
1381
- localPath,
1382
- sandboxPath,
1383
- sizeBytes: contents.byteLength
1384
- });
1385
- }
1386
- }
1387
- return uploaded;
1388
- }
1389
- async function writeLocalSandboxTemplateReplayParams(projectPath, executable, input2) {
1390
- const paramsJson = `${JSON.stringify({ input: input2 }, null, 2)}
1391
- `;
1392
- const encoded = Buffer2.from(paramsJson, "utf8").toString("base64");
1393
- const paramsPath = path3.join(projectPath, "openpond-replay-params.json");
1394
- await fs2.writeFile(paramsPath, paramsJson, "utf8");
1395
- if (executable.cwd) {
1396
- const cwdParamsPath = path3.join(
1397
- projectPath,
1398
- executable.cwd,
1399
- "openpond-replay-params.json"
1400
- );
1401
- if (cwdParamsPath !== paramsPath) {
1402
- await fs2.mkdir(path3.dirname(cwdParamsPath), { recursive: true });
1403
- await fs2.writeFile(cwdParamsPath, paramsJson, "utf8");
1404
- }
1405
- }
1406
- return { paramsPath, encoded };
1407
- }
1408
- async function runLocalSandboxTemplateCommand(projectPath, executable, replay, options = {}) {
1409
- const cwd = executable.cwd ? path3.resolve(projectPath, executable.cwd) : projectPath;
1410
- return runLocalShellCommandResult(executable.command, cwd, {
1411
- env: {
1412
- OPENPOND_REPLAY_PARAMS_BASE64: replay.encoded
1413
- },
1414
- timeoutSeconds: options.timeoutSeconds,
1415
- inherit: options.inherit
1416
- });
1417
- }
1418
- async function runLocalShellCommandResult(command, cwd, options = {}) {
1419
- const result = await runShellCommand(command, {
1420
- cwd,
1421
- env: options.env,
1422
- timeoutSeconds: options.timeoutSeconds,
1423
- inherit: options.inherit
1424
- });
1425
- const output = [result.stdout, result.stderr].filter(Boolean).join("");
1426
- return {
1427
- command,
1428
- cwd,
1429
- status: result.timedOut ? "timed_out" : result.code === 0 ? "succeeded" : "failed",
1430
- output,
1431
- exitCode: result.code
1432
- };
1433
- }
1434
- function localSandboxTemplatePreviews(executable) {
1435
- return executable.ports.map((port) => ({
1436
- port: port.port,
1437
- label: port.label ?? null,
1438
- access: port.access,
1439
- url: `http://127.0.0.1:${port.port}${port.path}`
1440
- }));
1441
- }
1442
- async function collectLocalSandboxTemplateArtifacts(projectPath, artifactPaths) {
1443
- const artifacts = [];
1444
- for (const artifactPath of artifactPaths) {
1445
- const localPath = path3.resolve(
1446
- projectPath,
1447
- normalizeLocalWorkspacePath(artifactPath)
1448
- );
1449
- try {
1450
- const stat = await fs2.stat(localPath);
1451
- artifacts.push({
1452
- path: artifactPath,
1453
- exists: stat.isFile(),
1454
- sizeBytes: stat.size
1455
- });
1456
- } catch {
1457
- artifacts.push({ path: artifactPath, exists: false, sizeBytes: null });
1458
- }
1459
- }
1460
- return artifacts;
1461
- }
1462
- function normalizeLocalWorkspacePath(value) {
1463
- const normalized = value.trim().replace(/\\/g, "/").replace(/^\/workspace\//, "").replace(/^workspace\//, "").replace(/^\.\//, "").replace(/^\/+/, "");
1464
- if (!normalized || normalized.split("/").some((segment) => segment === ".." || segment === "")) {
1465
- throw new Error(`invalid workspace path: ${value}`);
1466
- }
1467
- return normalized;
1468
- }
1469
-
1470
- // src/cli/sandbox-template.ts
1471
- async function runSandboxTemplateCommand(options, rest) {
1472
- const subcommand = rest[0] || "validate";
1473
- if (subcommand === "validate") {
1474
- const filePath = resolveSandboxTemplateFilePath(options);
1475
- const source = await fs3.readFile(filePath, "utf8");
1476
- const result = validateSandboxTemplateYaml(source);
1477
- if (!result.ok) {
1478
- console.error(formatSandboxTemplateDiagnostics(result.diagnostics));
1479
- process.exitCode = 1;
1480
- return;
1481
- }
1482
- console.log(
1483
- JSON.stringify(
1484
- {
1485
- ok: true,
1486
- file: filePath,
1487
- name: result.manifest.name,
1488
- version: result.manifest.version,
1489
- start: result.manifest.start.command,
1490
- actions: result.manifest.actions.map((action) => action.name),
1491
- services: result.manifest.services.map((service) => service.name),
1492
- schedules: result.manifest.schedules.map((schedule) => schedule.name)
1493
- },
1494
- null,
1495
- 2
1496
- )
1497
- );
1498
- return;
1499
- }
1500
- if (subcommand === "print-schema") {
1501
- console.log(JSON.stringify(sandboxTemplateJsonSchema(), null, 2));
1502
- return;
1503
- }
1504
- if (subcommand === "scaffold") {
1505
- const outputPath = resolveSandboxTemplateScaffoldPath(options);
1506
- const rawName = typeof options.name === "string" && options.name.trim().length > 0 ? options.name.trim() : path4.basename(outputPath);
1507
- const description = typeof options.description === "string" && options.description.trim().length > 0 ? options.description.trim() : void 0;
1508
- const files = sandboxTemplateScaffoldFiles({ name: rawName, description });
1509
- const manifestPath = path4.join(outputPath, OPENPOND_MANIFEST_FILE_NAME);
1510
- if (existsSync2(manifestPath)) {
1511
- throw new Error(
1512
- `${OPENPOND_MANIFEST_FILE_NAME} already exists at ${manifestPath}`
1513
- );
1514
- }
1515
- await fs3.mkdir(outputPath, { recursive: true });
1516
- for (const [relativePath, contents] of Object.entries(files)) {
1517
- const filePath = path4.join(outputPath, relativePath);
1518
- await fs3.mkdir(path4.dirname(filePath), { recursive: true });
1519
- await fs3.writeFile(filePath, contents, "utf8");
1520
- }
1521
- console.log(
1522
- JSON.stringify(
1523
- {
1524
- ok: true,
1525
- path: outputPath,
1526
- files: Object.keys(files).sort(
1527
- (left, right) => left.localeCompare(right)
1528
- )
1529
- },
1530
- null,
1531
- 2
1532
- )
1533
- );
1534
- return;
1535
- }
1536
- if (subcommand === "build") {
1537
- await runSandboxTemplateBuild(options);
1538
- return;
1539
- }
1540
- if (subcommand === "run") {
1541
- await runSandboxTemplateLocal(options, "run");
1542
- return;
1543
- }
1544
- if (subcommand === "dev") {
1545
- await runSandboxTemplateLocal(options, "dev");
1546
- return;
1547
- }
1548
- if (subcommand === "action") {
1549
- await runSandboxTemplateExistingSandboxAction(options, rest.slice(1));
1550
- return;
1551
- }
1552
- if (subcommand === "start") {
1553
- await runSandboxTemplateStart(options);
1554
- return;
1555
- }
1556
- throw new Error(
1557
- `usage: sandbox-template <validate|print-schema|scaffold|build|run|dev|start|action> [--file ${OPENPOND_MANIFEST_FILE_NAME}] [--path <dir>] [--name <name>]`
1558
- );
1559
- }
1560
- async function runSandboxTemplateBuild(options) {
1561
- const context = await loadSandboxTemplateManifestContext(options);
1562
- const outputPath = resolveSandboxTemplateBuildOutputPath(
1563
- options,
1564
- context.projectPath
1565
- );
1566
- const plan = sandboxTemplateBuildPlan({
1567
- manifest: context.manifest,
1568
- manifestFile: path4.relative(context.projectPath, context.filePath) || OPENPOND_MANIFEST_FILE_NAME,
1569
- projectRoot: path4.relative(path4.dirname(outputPath), context.projectPath) || "."
1570
- });
1571
- const shouldWrite = !parseBooleanOption(options.noWrite);
1572
- if (shouldWrite) {
1573
- await fs3.mkdir(path4.dirname(outputPath), { recursive: true });
1574
- await fs3.writeFile(
1575
- outputPath,
1576
- `${JSON.stringify(plan, null, 2)}
1577
- `,
1578
- "utf8"
1579
- );
1580
- }
1581
- const metadata = sandboxTemplateBuildMetadata(context.manifest);
1582
- const executables = sandboxTemplateExecutableEntries(context.manifest);
1583
- console.log(
1584
- JSON.stringify(
1585
- {
1586
- ok: true,
1587
- file: context.filePath,
1588
- output: shouldWrite ? outputPath : null,
1589
- ...metadata,
1590
- startCommand: executables[0]?.command ?? null,
1591
- plan
1592
- },
1593
- null,
1594
- 2
1595
- )
1596
- );
1597
- }
1598
- async function loadSandboxTemplateManifestContext(options) {
1599
- const filePath = resolveSandboxTemplateFilePath(options);
1600
- const source = await fs3.readFile(filePath, "utf8");
1601
- const result = validateSandboxTemplateYaml(source);
1602
- if (!result.ok) {
1603
- process.exitCode = 1;
1604
- throw new Error(formatSandboxTemplateDiagnostics(result.diagnostics));
1605
- }
1606
- return {
1607
- filePath,
1608
- projectPath: path4.dirname(filePath),
1609
- manifest: result.manifest
1610
- };
1611
- }
1612
- function resolveSandboxTemplateBuildOutputPath(options, projectPath) {
1613
- const rawOutput = typeof options.output === "string" && options.output.trim() ? options.output.trim() : typeof options.out === "string" && options.out.trim() ? options.out.trim() : "";
1614
- if (rawOutput) return path4.resolve(process.cwd(), rawOutput);
1615
- const rawOutputDir = typeof options.outputDir === "string" && options.outputDir.trim() ? options.outputDir.trim() : typeof options.outDir === "string" && options.outDir.trim() ? options.outDir.trim() : "dist";
1616
- return path4.resolve(
1617
- projectPath,
1618
- rawOutputDir,
1619
- SANDBOX_TEMPLATE_BUILD_PLAN_FILE_NAME
1620
- );
1621
- }
1622
- async function loadSandboxTemplateBuildPlan(options) {
1623
- const rawBuild = typeof options.build === "string" && options.build.trim() ? options.build.trim() : typeof options.plan === "string" && options.plan.trim() ? options.plan.trim() : "";
1624
- if (rawBuild) {
1625
- const filePath = path4.resolve(process.cwd(), rawBuild);
1626
- const parsed = JSON.parse(
1627
- await fs3.readFile(filePath, "utf8")
1628
- );
1629
- if (parsed.kind !== SANDBOX_TEMPLATE_BUILD_PLAN_KIND || parsed.schemaVersion !== 1) {
1630
- throw new Error(`invalid sandbox template build plan: ${filePath}`);
1631
- }
1632
- return {
1633
- plan: parsed,
1634
- filePath,
1635
- projectPath: path4.resolve(path4.dirname(filePath), parsed.projectRoot)
1636
- };
1637
- }
1638
- const context = await loadSandboxTemplateManifestContext(options);
1639
- return {
1640
- plan: sandboxTemplateBuildPlan({
1641
- manifest: context.manifest,
1642
- manifestFile: path4.relative(context.projectPath, context.filePath) || OPENPOND_MANIFEST_FILE_NAME,
1643
- projectRoot: context.projectPath
1644
- }),
1645
- filePath: context.filePath,
1646
- projectPath: context.projectPath
1647
- };
1648
- }
1649
- export {
1650
- loadSandboxTemplateBuildPlan,
1651
- loadSandboxTemplateManifestContext,
1652
- resolveSandboxTemplateBuildOutputPath,
1653
- runSandboxTemplateBuild,
1654
- runSandboxTemplateCommand
1655
- };