openpond 0.1.1 → 0.2.1

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