openpond 0.0.38 → 0.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/README.md +3 -4
  2. package/dist/api/core.d.ts +6 -0
  3. package/dist/api/vercel-protection.d.ts +1 -0
  4. package/dist/chunks/{app-layer-DPUJRNO2.js → app-layer-LTBWNA2F.js} +32 -10
  5. package/dist/chunks/app-server-runtime-VYYJ2AWX.js +18 -0
  6. package/dist/chunks/{apps-AKBI6AS7.js → apps-CZAJBGE3.js} +6 -4
  7. package/dist/chunks/{chunk-LZZM3IHS.js → chunk-2SF6HLT7.js} +5899 -5939
  8. package/dist/chunks/{chunk-XCATKTK3.js → chunk-3CDPPVLE.js} +108 -66
  9. package/dist/chunks/{chunk-JWF37O5E.js → chunk-3HW6OSHP.js} +1 -3
  10. package/dist/chunks/{chunk-43YI36NA.js → chunk-3KLQ52B2.js} +228 -5
  11. package/dist/chunks/chunk-4HIWFIMN.js +37172 -0
  12. package/dist/chunks/{chunk-AHPQTEIJ.js → chunk-4N6E3OVF.js} +4 -4
  13. package/dist/chunks/{chunk-YTJL6XPU.js → chunk-6V7MJVRO.js} +56 -11
  14. package/dist/chunks/{chunk-QRM7XMAO.js → chunk-BQQZNGI6.js} +152 -161
  15. package/dist/chunks/chunk-DBHSOTYZ.js +1552 -0
  16. package/dist/chunks/{chunk-275WCETC.js → chunk-FCVVOMIP.js} +145 -5
  17. package/dist/chunks/{chunk-GB6VUZUA.js → chunk-JIEUB6OS.js} +1 -1
  18. package/dist/chunks/{chunk-HS2AGRDV.js → chunk-JJPAMKXZ.js} +1 -1
  19. package/dist/chunks/{chunk-GDZYDLEL.js → chunk-JRROTGQT.js} +1 -110
  20. package/dist/chunks/chunk-KHNHUA2H.js +1737 -0
  21. package/dist/chunks/{chunk-AHNFNWUN.js → chunk-L6XH4ZGZ.js} +1 -1
  22. package/dist/chunks/chunk-M2NXTLH2.js +4054 -0
  23. package/dist/chunks/{chunk-SLMP353Q.js → chunk-MIZHCABO.js} +2 -195
  24. package/dist/chunks/chunk-SMNFI2FU.js +113 -0
  25. package/dist/chunks/chunk-VCVQLECH.js +675 -0
  26. package/dist/chunks/{chunk-V35STJF4.js → chunk-ZJBJQCQZ.js} +179 -52
  27. package/dist/chunks/{cli-7BKDWFNU.js → cli-JS76LCW2.js} +9 -5
  28. package/dist/chunks/{core-commands-YN4RMWA3.js → core-commands-4MRJQZJV.js} +7 -5
  29. package/dist/chunks/{harness-BHQRMXJR.js → desktop-test-RNMWLOVU.js} +15 -14
  30. package/dist/chunks/{chunk-XERQHYBO.js → extension-GDRW22N3.js} +5868 -3580
  31. package/dist/chunks/{help-VREQNA4I.js → help-LWNREJ7U.js} +1 -1
  32. package/dist/chunks/{opchat-D63YTNSX.js → opchat-2K2JIGK3.js} +9 -10
  33. package/dist/chunks/{organizations-I46KG7TC.js → organizations-Z5HVD2E7.js} +11 -9
  34. package/dist/chunks/{profile-WKZJHEPG.js → profile-QNECVVGN.js} +12 -38
  35. package/dist/chunks/{project-agent-ZUC3YMCT.js → project-agent-W3V75WBR.js} +9 -411
  36. package/dist/chunks/{sandbox-command-AAOPFTI5.js → sandbox-command-X3FO74NX.js} +7 -5
  37. package/dist/chunks/{sandbox-template-GKNVR4C5.js → sandbox-template-5B4T4BGU.js} +8 -6
  38. package/dist/chunks/{src-RPW5TOPI.js → src-ESAILPUH.js} +32 -30
  39. package/dist/chunks/src-IC5RX4L6.js +63517 -0
  40. package/dist/chunks/{teams-bot-PSL3ZO6Z.js → teams-bot-NTQ6VFFL.js} +6 -4
  41. package/dist/chunks/training-BR5A7SPU.js +320 -0
  42. package/dist/chunks/{workspaces-BPXC2DHT.js → workspaces-XC3QBD2Y.js} +2 -2
  43. package/dist/cli.js +24 -12
  44. package/dist/config.d.ts +9 -3
  45. package/dist/index.js +1300 -1045
  46. package/dist/profile/local-profile-types.d.ts +16 -0
  47. package/dist/profile/local-profile.d.ts +50 -4
  48. package/dist/sandbox/client-handles.d.ts +33 -46
  49. package/dist/sandbox/client.d.ts +4 -26
  50. package/dist/sandbox/sandbox-instance-client.d.ts +5 -5
  51. package/dist/sandbox/types/client.d.ts +1 -2
  52. package/dist/sandbox/types/core.d.ts +0 -1
  53. package/dist/sandbox/types/org-project-agent.d.ts +3 -89
  54. package/dist/sandbox/types/record.d.ts +1 -2
  55. package/dist/sandbox/types/runtime-profiles.d.ts +2 -2
  56. package/dist/sandbox-template/manifest.d.ts +1 -1
  57. package/dist/skills/openpond-agent-authoring/SKILL.md +40 -0
  58. package/dist/skills/openpond-agent-authoring/references/action-and-chat-design.md +13 -0
  59. package/dist/skills/openpond-agent-authoring/references/integrations-and-setup.md +13 -0
  60. package/dist/skills/openpond-agent-authoring/references/profile-layout.md +29 -0
  61. package/dist/skills/openpond-agent-authoring/references/validation-and-repair.md +14 -0
  62. package/dist/skills/openpond-desktop-harness/SKILL.md +1 -1
  63. package/dist/skills/openpond-skill-authoring/SKILL.md +44 -0
  64. package/dist/skills/openpond-skill-authoring/references/copying-and-adaptation.md +16 -0
  65. package/dist/skills/openpond-skill-authoring/references/skill-package-layout.md +38 -0
  66. package/dist/skills/openpond-skill-authoring/references/validation-and-repair.md +24 -0
  67. package/dist/skills/openpond-skill-authoring/scripts/validate-skill.mjs +102 -0
  68. package/dist/skills/openpond-taskset-authoring/SKILL.md +64 -22
  69. package/dist/skills/openpond-taskset-authoring/artifact.json +39 -0
  70. package/dist/skills/openpond-taskset-authoring/references/graders-and-rewards.md +3 -0
  71. package/dist/skills/openpond-taskset-authoring/references/method-selection.md +1 -1
  72. package/dist/skills/openpond-taskset-authoring/references/privacy-and-provenance.md +2 -0
  73. package/dist/skills/openpond-taskset-authoring/references/task-design.md +32 -0
  74. package/dist/web/assets/{AppDialog-DrwJb_wG.js → AppDialog-Bua3f-6v.js} +1 -1
  75. package/dist/web/assets/{AppsView-DPagLMsc.js → AppsView-DrJkHeSO.js} +1 -1
  76. package/dist/web/assets/BrowserSidebar-Bf-4Vozm.js +1 -0
  77. package/dist/web/assets/CommandMenu-DDZlGQiB.js +1 -0
  78. package/dist/web/assets/CommunityView-BtcCrba7.js +1 -0
  79. package/dist/web/assets/ComposerCreateImproveStrip-DOe5Otg6.js +1 -0
  80. package/dist/web/assets/GetStartedView-CG4z0Dtw.js +1 -0
  81. package/dist/web/assets/GetStartedView-yVmnGZPw.css +1 -0
  82. package/dist/web/assets/LabModelVersionDetailPage-BEkmSKuv.js +1 -0
  83. package/dist/web/assets/LabSkillSidebar-BIotN_RB.js +1 -0
  84. package/dist/web/assets/LabsRoute-CfOe0Zt5.js +3 -0
  85. package/dist/web/assets/LabsRoute-CoSPO4HR.css +1 -0
  86. package/dist/web/assets/MainChatThread-C0-l1mHt.js +2 -0
  87. package/dist/web/assets/MainPane-Bky_Rqcx.css +1 -0
  88. package/dist/web/assets/MainPane-aOVlVyRK.js +6 -0
  89. package/dist/web/assets/MarkdownText-D7DT1k1k.js +9 -0
  90. package/dist/web/assets/Messages-CBIXruA9.js +9 -0
  91. package/dist/web/assets/NativeSkillSidebar-C4t69Y7B.js +1 -0
  92. package/dist/web/assets/NewProjectDialog-Bat65tYD.js +1 -0
  93. package/dist/web/assets/OutputsPage-C58n39Db.js +1 -0
  94. package/dist/web/assets/RightChatPanelStack-Bp7nZxQ0.js +1 -0
  95. package/dist/web/assets/ScheduledWorkPage-BXP0j_c_.js +1 -0
  96. package/dist/web/assets/SettingsView-CtWK_aQ0.css +1 -0
  97. package/dist/web/assets/SettingsView-DOOfhO9a.js +6 -0
  98. package/dist/web/assets/TeamChatView-Cgxm-pKA.css +1 -0
  99. package/dist/web/assets/TeamChatView-De2wdqyY.js +3 -0
  100. package/dist/web/assets/{TerminalOverlay-BKl0p8pa.js → TerminalOverlay-BsuCH3NX.js} +1 -1
  101. package/dist/web/assets/TrainingCreationPanel-D2OFWyQ-.js +1 -0
  102. package/dist/web/assets/TrainingDraftPanel-DBpulXTz.js +1 -0
  103. package/dist/web/assets/{UsageSettingsSection-zDAwzTGl.js → UsageSettingsSection-DzMLUXAO.js} +37 -37
  104. package/dist/web/assets/WorkspaceDiffPanel-B7yIhjNF.js +14 -0
  105. package/dist/web/assets/WorkspaceEnvironmentMenu-B6jXM9xG.js +32 -0
  106. package/dist/web/assets/WorkspaceGitDialogs-CQ0fl9Qk.js +1 -0
  107. package/dist/web/assets/{WorkspaceMonacoEditor-DPGcG8fy.js → WorkspaceMonacoEditor-C2ctzITz.js} +3 -3
  108. package/dist/web/assets/arrow-up-right-ecwcx3xt.js +1 -0
  109. package/dist/web/assets/chevron-up-DP8PPfWd.js +1 -0
  110. package/dist/web/assets/circle-alert-envg1D6O.js +1 -0
  111. package/dist/web/assets/cloud-upload-5MGPLnaA.js +1 -0
  112. package/dist/web/assets/{cssMode-CKN9CcfG.js → cssMode-CFifcEfw.js} +1 -1
  113. package/dist/web/assets/folder-open-Dq3ZjeEP.js +1 -0
  114. package/dist/web/assets/folder-plus-EiZ5wbv_.js +1 -0
  115. package/dist/web/assets/git-branch-w29jmQ-X.js +1 -0
  116. package/dist/web/assets/{git-commit-horizontal-Bxi8YPep.js → git-commit-horizontal-CGZM0PZo.js} +1 -1
  117. package/dist/web/assets/{htmlMode-CeUcNhBZ.js → htmlMode-Ct1P-_lf.js} +1 -1
  118. package/dist/web/assets/index-ByIQyiUl.js +178 -0
  119. package/dist/web/assets/index-D4uCeiep.js +1 -0
  120. package/dist/web/assets/index-D9jTe16Q.css +1 -0
  121. package/dist/web/assets/info-Cd2HkIeb.js +1 -0
  122. package/dist/web/assets/{jsonMode-97z0Yz9u.js → jsonMode-BAUNCNAX.js} +1 -1
  123. package/dist/web/assets/{lspLanguageFeatures-D4Tp-JmI.js → lspLanguageFeatures-fucFYI1A.js} +1 -1
  124. package/dist/web/assets/monaco.contribution-Ce4v5kei.js +2 -0
  125. package/dist/web/assets/monaco.contribution-DLLMi4cB.js +2 -0
  126. package/dist/web/assets/monaco.contribution-g9QiIm1d.js +2 -0
  127. package/dist/web/assets/monaco.contribution-nG-5Cyjz.js +2 -0
  128. package/dist/web/assets/monitor-DgHCnCKl.js +1 -0
  129. package/dist/web/assets/{play-C-37dnR1.js → play-Be0XDHBu.js} +1 -1
  130. package/dist/web/assets/{python-CGpDXY7_.js → python-CEhEiPo7.js} +1 -1
  131. package/dist/web/assets/{refresh-cw-BAaaPCXl.js → refresh-cw-DH0KLbdD.js} +1 -1
  132. package/dist/web/assets/reply-D1TK2yV8.js +1 -0
  133. package/dist/web/assets/{save-Cvxs3XyC.js → save-C1MSeBnQ.js} +1 -1
  134. package/dist/web/assets/square-CemI-0g5.js +1 -0
  135. package/dist/web/assets/square-pen-CqfsvR_n.js +1 -0
  136. package/dist/web/assets/{toggleHighContrast-CD42jH4g.js → toggleHighContrast-DrdQN3Rl.js} +1 -1
  137. package/dist/web/assets/training-BQVNUTZA.css +1 -0
  138. package/dist/web/assets/training-model-data-B7-1Bxil.js +1 -0
  139. package/dist/web/assets/{tsMode-ZROIxEjv.js → tsMode-CKB5oOUU.js} +1 -1
  140. package/dist/web/assets/{upload-DvCSGERK.js → upload-t751LLqP.js} +1 -1
  141. package/dist/web/assets/useLocalAgentSchedules-CzC3wfIP.js +1 -0
  142. package/dist/web/assets/{wifi-off-BIb94PkS.js → wifi-off-CxTHH3JU.js} +1 -1
  143. package/dist/web/assets/{workers-oYqbrVYG.js → workers-CqYddzCd.js} +1 -1
  144. package/dist/web/assets/{yaml-WqBjNgOO.js → yaml-e5wBkc-C.js} +1 -1
  145. package/dist/web/index.html +2 -2
  146. package/docs/command-reference.md +75 -40
  147. package/package.json +3 -1
  148. package/dist/chunks/chunk-FWLOFUPU.js +0 -864
  149. package/dist/chunks/chunk-HLCTINEP.js +0 -224
  150. package/dist/chunks/chunk-MPGSHXGF.js +0 -3896
  151. package/dist/chunks/chunk-T4QXKU5Y.js +0 -1
  152. package/dist/chunks/chunk-XEJ7XXUQ.js +0 -1301
  153. package/dist/chunks/chunk-ZI4GDAUB.js +0 -3522
  154. package/dist/chunks/cli-2KBVNDRY.js +0 -23
  155. package/dist/chunks/extend-REGNTBK3.js +0 -89
  156. package/dist/chunks/extension-7K77DAVL.js +0 -121
  157. package/dist/chunks/fileFromPath-DHCRY3BD.js +0 -2151
  158. package/dist/chunks/src-MWDIK56B.js +0 -105881
  159. package/dist/web/assets/BrowserSidebar-DMn2V8RV.js +0 -1
  160. package/dist/web/assets/CloudWorkView-Cl_7mM3c.js +0 -1
  161. package/dist/web/assets/CloudWorkView-DNoPIlMj.css +0 -1
  162. package/dist/web/assets/CommandMenu-CHMQLez_.js +0 -1
  163. package/dist/web/assets/CommunityView-DcHVDUk0.js +0 -1
  164. package/dist/web/assets/ComposerCreateImproveStrip-BZ3Dgzmo.js +0 -1
  165. package/dist/web/assets/GetStartedView-DBLdduwr.css +0 -1
  166. package/dist/web/assets/GetStartedView-DTRotFqz.js +0 -1
  167. package/dist/web/assets/LabSkillSidebar-D-PqFe1T.js +0 -1
  168. package/dist/web/assets/LabsRoute-BrJkBNig.css +0 -1
  169. package/dist/web/assets/LabsRoute-Dew1BwK5.js +0 -3
  170. package/dist/web/assets/MainChatThread-BaPxxzrw.js +0 -2
  171. package/dist/web/assets/MakeAgentTutorialLearningPanel-CBsfnONQ.js +0 -2
  172. package/dist/web/assets/MarkdownText-DGLfAM_Z.js +0 -7
  173. package/dist/web/assets/Messages-CIX9uTjX.js +0 -10
  174. package/dist/web/assets/NativeSkillSidebar-AP_uHn6g.js +0 -1
  175. package/dist/web/assets/NewProjectDialog-C6lHkafU.js +0 -1
  176. package/dist/web/assets/PostTrainingLearningPanel-CZEgPc8O.js +0 -2
  177. package/dist/web/assets/PostTrainingStatusPill-CeEpwUDB.js +0 -1
  178. package/dist/web/assets/ProfileSettingsSection-Cg4tKO-C.css +0 -1
  179. package/dist/web/assets/ProfileSettingsSection-EumMLlEp.js +0 -1
  180. package/dist/web/assets/RightChatPanelStack-MXBcx3zO.js +0 -1
  181. package/dist/web/assets/SettingsView-Caljbns2.css +0 -1
  182. package/dist/web/assets/SettingsView-DyURG_Uh.js +0 -6
  183. package/dist/web/assets/TeamChatView-Bx44q3WV.css +0 -1
  184. package/dist/web/assets/TeamChatView-D3v6aqJ3.js +0 -3
  185. package/dist/web/assets/TrainingCreationPanel-CfZQTuT5.js +0 -1
  186. package/dist/web/assets/TrainingDraftPanel-DslRPSDW.js +0 -1
  187. package/dist/web/assets/WorkspaceDiffPanel-C_MZPPlL.js +0 -14
  188. package/dist/web/assets/WorkspaceEnvironmentMenu-BUAnn80j.js +0 -32
  189. package/dist/web/assets/WorkspaceGitDialogs-Drbf4ujA.js +0 -1
  190. package/dist/web/assets/activity-Dnr3jqb3.js +0 -1
  191. package/dist/web/assets/boxes-BinC8UPn.js +0 -1
  192. package/dist/web/assets/chevron-up-Bjp_-_Cb.js +0 -1
  193. package/dist/web/assets/circle-x-ubnvEYuE.js +0 -1
  194. package/dist/web/assets/copy-B_ZCCUMz.js +0 -1
  195. package/dist/web/assets/create-pipeline-request-D6uLUxe9.js +0 -4
  196. package/dist/web/assets/file-8HAMlTmQ.js +0 -1
  197. package/dist/web/assets/git-branch-l2Zih3Bv.js +0 -1
  198. package/dist/web/assets/index-BMFyOFRU.css +0 -1
  199. package/dist/web/assets/index-BzwcDzbT.js +0 -1
  200. package/dist/web/assets/index-KoQSSt_f.js +0 -177
  201. package/dist/web/assets/info-JTbDQxHx.js +0 -1
  202. package/dist/web/assets/make-agent-tutorial-D6nBCgv-.js +0 -2
  203. package/dist/web/assets/monaco.contribution-B3j6oown.js +0 -2
  204. package/dist/web/assets/monaco.contribution-BXHxPPWL.js +0 -2
  205. package/dist/web/assets/monaco.contribution-C2P5zIzh.js +0 -2
  206. package/dist/web/assets/monaco.contribution-C8c6OtGi.js +0 -2
  207. package/dist/web/assets/monitor-kzHtxHnA.js +0 -1
  208. package/dist/web/assets/reply-9rehU13k.js +0 -1
  209. package/dist/web/assets/rotate-cw-C1Z_Xs23.js +0 -1
  210. package/dist/web/assets/training-BN8CALIc.css +0 -1
  211. package/dist/web/assets/training-model-data-BXUCzS0p.js +0 -1
  212. package/docs/agent-edit-check-status-json.md +0 -132
@@ -1,1301 +0,0 @@
1
- import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
- import {
3
- external_exports,
4
- yaml
5
- } from "./chunk-WYDVQOBL.js";
6
-
7
- // ../../packages/cloud/dist/sandbox-template/manifest.js
8
- var SANDBOX_TEMPLATE_PREVIEW_PORT_MIN = 3e3;
9
- var SANDBOX_TEMPLATE_PREVIEW_PORT_MAX = 9999;
10
- var OPENPOND_MANIFEST_FILE_NAME = "openpond.yaml";
11
- var SANDBOX_TEMPLATE_BUILD_PLAN_FILE_NAME = "openpond-template-plan.json";
12
- var SANDBOX_TEMPLATE_BUILD_PLAN_KIND = "openpond.sandboxTemplate.buildPlan.v1";
13
- var INTEGRATION_PROVIDERS = [
14
- "google",
15
- "github",
16
- "x"
17
- ];
18
- var RESERVED_PREVIEW_PORTS = /* @__PURE__ */ new Set([
19
- 22,
20
- 2222,
21
- 2375,
22
- 2376,
23
- 3108,
24
- 5900,
25
- 5901,
26
- 6080,
27
- 7818
28
- ]);
29
- var CommandListSchema = external_exports.array(external_exports.string().trim().min(1).max(1e3)).max(50);
30
- var RelativeWorkspacePathSchema = external_exports.string().trim().min(1).max(4096).refine(isSafeRelativeWorkspacePath, {
31
- message: "path must be a relative workspace path"
32
- });
33
- var OciImageRefSchema = external_exports.string().trim().min(1).max(500).refine((value) => !value.includes("\0") && !/\s/.test(value), "image ref must be a single OCI reference");
34
- var OciDigestSchema = external_exports.string().trim().regex(/^sha256:[0-9a-f]{64}$/i);
35
- var RuntimeWorkspaceRootSchema = external_exports.string().trim().min(1).max(500).refine((value) => value.startsWith("/") && !value.includes("\0"), "workspaceRoot must be an absolute guest path");
36
- var DockerfileRuntimeImageSchema = external_exports.object({
37
- ref: OciImageRefSchema,
38
- digest: OciDigestSchema.optional(),
39
- registrySecretRef: external_exports.string().trim().min(1).max(500).optional(),
40
- platform: external_exports.literal("linux/amd64").optional(),
41
- workspaceRoot: RuntimeWorkspaceRootSchema.optional()
42
- }).strict();
43
- var DockerfileRuntimeSourceSchema = external_exports.object({
44
- context: RelativeWorkspacePathSchema.default("."),
45
- path: RelativeWorkspacePathSchema.default("Dockerfile"),
46
- target: external_exports.string().trim().min(1).max(191).optional(),
47
- buildArgs: external_exports.record(external_exports.string().max(191), external_exports.string().max(500)).optional(),
48
- registrySecretRefs: external_exports.array(external_exports.string().trim().min(1).max(500)).max(10).optional(),
49
- platform: external_exports.literal("linux/amd64").optional(),
50
- workspaceRoot: RuntimeWorkspaceRootSchema.optional()
51
- }).strict();
52
- var SandboxTemplateRuntimeSchema = external_exports.object({
53
- base: external_exports.string().trim().min(1).max(120).optional(),
54
- snapshot: external_exports.string().trim().min(1).max(191).optional(),
55
- image: DockerfileRuntimeImageSchema.optional(),
56
- dockerfile: DockerfileRuntimeSourceSchema.optional()
57
- }).strict().superRefine((runtime, context) => {
58
- const selected = [
59
- runtime.base,
60
- runtime.snapshot,
61
- runtime.image,
62
- runtime.dockerfile
63
- ].filter(Boolean).length;
64
- if (selected !== 1) {
65
- context.addIssue({
66
- code: external_exports.ZodIssueCode.custom,
67
- message: "runtime must declare exactly one of base, snapshot, image, or dockerfile"
68
- });
69
- }
70
- });
71
- var SandboxTemplateResourcesSchema = external_exports.object({
72
- cpu: external_exports.number().positive().max(8).optional(),
73
- memoryGb: external_exports.number().positive().max(32).optional(),
74
- diskGb: external_exports.number().positive().max(100).optional()
75
- }).strict();
76
- var SandboxTemplateRequiredLeaseSchema = external_exports.object({
77
- provider: external_exports.enum(INTEGRATION_PROVIDERS),
78
- scopes: external_exports.array(external_exports.string().trim().min(1).max(200)).max(100).default([]),
79
- capabilities: external_exports.array(external_exports.string().trim().min(1).max(200)).max(100).default([])
80
- }).strict();
81
- var SandboxTemplateOpChatPermissionsSchema = external_exports.object({
82
- models: external_exports.array(external_exports.string().trim().min(1).max(200)).max(100).default([]),
83
- scopes: external_exports.array(external_exports.string().trim().min(1).max(200)).max(100).default([])
84
- }).strict();
85
- var SandboxTemplatePermissionsSchema = external_exports.object({
86
- opchat: SandboxTemplateOpChatPermissionsSchema.optional()
87
- }).catchall(external_exports.record(external_exports.string(), external_exports.unknown())).default({});
88
- var SandboxTemplateVolumeSchema = external_exports.object({
89
- name: external_exports.string().trim().regex(/^[A-Za-z_][A-Za-z0-9_-]*$/).max(63).optional(),
90
- mountPath: external_exports.string().trim().min(1).max(256).optional(),
91
- storageGb: external_exports.number().int().positive().max(100).optional(),
92
- deleteOnSandboxDelete: external_exports.boolean().optional()
93
- }).strict();
94
- var SandboxTemplatePortSchema = external_exports.object({
95
- port: external_exports.number().int().min(SANDBOX_TEMPLATE_PREVIEW_PORT_MIN).max(SANDBOX_TEMPLATE_PREVIEW_PORT_MAX).refine((port) => !RESERVED_PREVIEW_PORTS.has(port), {
96
- message: "preview port is reserved"
97
- }),
98
- protocol: external_exports.literal("http").default("http"),
99
- label: external_exports.string().trim().min(1).max(80).optional(),
100
- access: external_exports.enum(["private", "public"]).default("private"),
101
- path: external_exports.string().trim().min(1).max(512).refine((value) => value.startsWith("/"), {
102
- message: "preview path must start with /"
103
- }).default("/")
104
- }).strict();
105
- var SandboxTemplateCommandSchema = external_exports.object({
106
- command: external_exports.string().trim().min(1).max(1e3),
107
- cwd: RelativeWorkspacePathSchema.optional(),
108
- timeoutSeconds: external_exports.number().int().positive().max(86400).optional(),
109
- requiresStart: external_exports.boolean().default(false),
110
- ports: external_exports.array(SandboxTemplatePortSchema).max(20).default([]),
111
- artifactPaths: external_exports.array(RelativeWorkspacePathSchema).max(100).default([])
112
- }).strict();
113
- var SandboxTemplateNamedCommandSchema = SandboxTemplateCommandSchema.extend({
114
- name: external_exports.string().trim().min(1).max(80)
115
- }).strict();
116
- var SandboxTemplateMcpEndpointSchema = external_exports.object({
117
- name: external_exports.string().trim().min(1).max(80).optional(),
118
- service: external_exports.string().trim().min(1).max(80).optional(),
119
- port: external_exports.number().int().min(SANDBOX_TEMPLATE_PREVIEW_PORT_MIN).max(SANDBOX_TEMPLATE_PREVIEW_PORT_MAX).refine((port) => !RESERVED_PREVIEW_PORTS.has(port), {
120
- message: "app MCP port is reserved"
121
- }),
122
- path: external_exports.string().trim().min(1).max(512).refine((value) => value.startsWith("/"), {
123
- message: "app MCP path must start with /"
124
- }).default("/mcp")
125
- }).strict();
126
- var SandboxTemplateValidationProbeSchema = external_exports.object({
127
- name: external_exports.string().trim().min(1).max(80).optional(),
128
- port: external_exports.number().int().min(SANDBOX_TEMPLATE_PREVIEW_PORT_MIN).max(SANDBOX_TEMPLATE_PREVIEW_PORT_MAX).refine((port) => !RESERVED_PREVIEW_PORTS.has(port), {
129
- message: "validation probe port is reserved"
130
- }),
131
- path: external_exports.string().trim().min(1).max(512).refine((value) => value.startsWith("/"), {
132
- message: "validation probe path must start with /"
133
- }).default("/"),
134
- expectedStatus: external_exports.number().int().min(100).max(599).default(200)
135
- }).strict();
136
- var SandboxTemplateJsonSchema = external_exports.record(external_exports.string(), external_exports.unknown()).refine((schema) => schema.type === "object", "input schema must be a JSON schema object");
137
- var SandboxTemplateEnvInputSchema = external_exports.object({
138
- name: external_exports.string().trim().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).max(191),
139
- required: external_exports.boolean().default(false),
140
- secret: external_exports.boolean().default(true),
141
- description: external_exports.string().trim().max(500).optional()
142
- }).strict();
143
- var SandboxTemplateScheduleDateSchema = external_exports.string().trim().min(1).max(120);
144
- var SandboxTemplateScheduleSchema = external_exports.object({
145
- name: external_exports.string().trim().min(1).max(120),
146
- description: external_exports.string().trim().max(500).optional(),
147
- cron: external_exports.string().trim().min(1).max(500).optional(),
148
- rate: external_exports.string().trim().min(1).max(500).optional(),
149
- once: SandboxTemplateScheduleDateSchema.optional(),
150
- scheduleType: external_exports.enum(["rate", "cron", "once"]).optional(),
151
- scheduleExpression: external_exports.string().trim().min(1).max(500).optional(),
152
- timezone: external_exports.string().trim().min(1).max(100).optional(),
153
- enabled: external_exports.boolean().default(true),
154
- startAt: SandboxTemplateScheduleDateSchema.optional(),
155
- endAt: SandboxTemplateScheduleDateSchema.optional(),
156
- maxRuns: external_exports.number().int().positive().nullable().optional(),
157
- runtimePolicy: external_exports.enum([
158
- "run_and_stop",
159
- "run_and_archive",
160
- "run_and_delete",
161
- "use_existing_running"
162
- ]).default("run_and_stop"),
163
- action: external_exports.string().trim().min(1).max(120).optional(),
164
- actionName: external_exports.string().trim().min(1).max(120).optional(),
165
- command: external_exports.string().trim().min(1).max(2e3).optional(),
166
- target: external_exports.object({
167
- kind: external_exports.enum(["start", "action", "service", "command"]).optional(),
168
- name: external_exports.string().trim().min(1).max(120).optional(),
169
- actionName: external_exports.string().trim().min(1).max(120).optional(),
170
- command: external_exports.string().trim().min(1).max(2e3).optional(),
171
- requiresStart: external_exports.boolean().optional()
172
- }).strict().optional(),
173
- requiresStart: external_exports.boolean().optional(),
174
- budget: external_exports.object({
175
- maxUsd: external_exports.string().trim().min(1).max(40).optional()
176
- }).strict().optional(),
177
- resources: SandboxTemplateResourcesSchema.optional(),
178
- quotas: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
179
- lifecycle: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
180
- retentionPolicy: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
181
- env: external_exports.array(external_exports.object({
182
- name: external_exports.string().trim().regex(/^[A-Za-z_][A-Za-z0-9_]*$/).max(191),
183
- value: external_exports.string().optional(),
184
- secretRef: external_exports.string().optional()
185
- }).strict()).max(100).optional(),
186
- integrationLeases: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).max(20).optional(),
187
- metadata: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
188
- }).strict().superRefine((schedule, context) => {
189
- const expressionCount = [
190
- schedule.cron,
191
- schedule.rate,
192
- schedule.once,
193
- schedule.scheduleExpression
194
- ].filter((value) => typeof value === "string" && value.trim()).length;
195
- if (expressionCount !== 1) {
196
- context.addIssue({
197
- code: external_exports.ZodIssueCode.custom,
198
- path: ["scheduleExpression"],
199
- message: "schedule must declare exactly one of cron, rate, once, or scheduleExpression"
200
- });
201
- }
202
- if (schedule.scheduleExpression && !schedule.scheduleType) {
203
- context.addIssue({
204
- code: external_exports.ZodIssueCode.custom,
205
- path: ["scheduleType"],
206
- message: "scheduleType is required with scheduleExpression"
207
- });
208
- }
209
- const command = schedule.command ?? schedule.target?.command ?? null;
210
- const targetName = schedule.target?.name ?? null;
211
- const actionName = schedule.actionName ?? schedule.action ?? schedule.target?.actionName ?? (schedule.target?.kind === "action" ? targetName : null);
212
- const kind = schedule.target?.kind ?? (command ? "command" : "action");
213
- if (kind === "action" && !actionName) {
214
- context.addIssue({
215
- code: external_exports.ZodIssueCode.custom,
216
- path: ["action"],
217
- message: "schedule action target is required"
218
- });
219
- }
220
- if (kind === "service" && !targetName) {
221
- context.addIssue({
222
- code: external_exports.ZodIssueCode.custom,
223
- path: ["target", "name"],
224
- message: "schedule service target name is required"
225
- });
226
- }
227
- if (kind === "command" && !command) {
228
- context.addIssue({
229
- code: external_exports.ZodIssueCode.custom,
230
- path: ["command"],
231
- message: "schedule command target is required"
232
- });
233
- }
234
- });
235
- var SandboxTemplateManifestSchema = external_exports.object({
236
- schemaVersion: external_exports.literal(1),
237
- name: external_exports.string().trim().min(1).max(80).regex(/^[a-z0-9][a-z0-9-]*[a-z0-9]$/),
238
- version: external_exports.string().trim().min(1).max(40),
239
- useCase: external_exports.string().trim().min(1).max(80),
240
- description: external_exports.string().trim().min(1).max(500),
241
- runtime: SandboxTemplateRuntimeSchema,
242
- resources: SandboxTemplateResourcesSchema.optional(),
243
- setup: external_exports.object({
244
- commands: CommandListSchema.default([])
245
- }).strict().default({ commands: [] }),
246
- validation: external_exports.object({
247
- commands: CommandListSchema.min(1),
248
- probes: external_exports.array(SandboxTemplateValidationProbeSchema).max(20).default([])
249
- }).strict(),
250
- start: SandboxTemplateCommandSchema,
251
- actions: external_exports.array(SandboxTemplateNamedCommandSchema).max(20).default([]),
252
- services: external_exports.array(SandboxTemplateNamedCommandSchema).max(20).default([]),
253
- schedules: external_exports.array(SandboxTemplateScheduleSchema).max(20).default([]),
254
- mcp: external_exports.object({
255
- endpoints: external_exports.array(SandboxTemplateMcpEndpointSchema).max(10).default([])
256
- }).strict().default({ endpoints: [] }),
257
- volumes: external_exports.array(SandboxTemplateVolumeSchema).max(5).default([]),
258
- integrations: external_exports.object({
259
- requiredLeases: external_exports.array(SandboxTemplateRequiredLeaseSchema).max(20).default([])
260
- }).strict().default({ requiredLeases: [] }),
261
- permissions: SandboxTemplatePermissionsSchema,
262
- inputs: external_exports.object({
263
- schema: SandboxTemplateJsonSchema.default({ type: "object" }),
264
- env: external_exports.array(SandboxTemplateEnvInputSchema).max(100).default([])
265
- }).strict().default({ schema: { type: "object" }, env: [] }),
266
- artifacts: external_exports.object({
267
- paths: external_exports.array(RelativeWorkspacePathSchema).max(100).default([])
268
- }).strict().default({ paths: [] }),
269
- network: external_exports.object({
270
- egress: external_exports.enum(["restricted", "allow", "block"]).default("restricted")
271
- }).strict().default({ egress: "restricted" })
272
- }).strict().superRefine((manifest, context) => {
273
- validateExecutableNames(manifest, context);
274
- addDuplicateNameIssue(context, manifest.volumes.flatMap((volume) => volume.name ? [volume.name] : []), "volume names must be unique", "volumes");
275
- validateInputSchemaUploadTargets(manifest, context);
276
- validateEnvInputs(manifest, context);
277
- validateMcpEndpoints(manifest, context);
278
- validateScheduleTargets(manifest, context);
279
- });
280
- var SandboxTemplateValidationDiagnosticSchema = external_exports.object({
281
- path: external_exports.string(),
282
- message: external_exports.string(),
283
- code: external_exports.string()
284
- });
285
- function validateSandboxTemplateYaml(source) {
286
- let parsed;
287
- try {
288
- parsed = yaml.load(source);
289
- } catch (error) {
290
- return {
291
- ok: false,
292
- manifest: null,
293
- diagnostics: [
294
- {
295
- path: "$",
296
- code: "invalid_yaml",
297
- message: error instanceof Error ? error.message : "Invalid YAML"
298
- }
299
- ]
300
- };
301
- }
302
- return validateSandboxTemplateManifest(parsed);
303
- }
304
- function validateSandboxTemplateManifest(value) {
305
- if (!value || typeof value !== "object" || Array.isArray(value)) {
306
- return {
307
- ok: false,
308
- manifest: null,
309
- diagnostics: [
310
- {
311
- path: "$",
312
- code: "invalid_type",
313
- message: `${OPENPOND_MANIFEST_FILE_NAME} must be an object`
314
- }
315
- ]
316
- };
317
- }
318
- if (Object.prototype.hasOwnProperty.call(value, "databases")) {
319
- return {
320
- ok: false,
321
- manifest: null,
322
- diagnostics: [
323
- {
324
- path: "$.databases",
325
- code: "database_resources_removed",
326
- message: "managed database requests are unsupported for Firecracker sandbox templates; use a durable volume with SQLite or files instead"
327
- }
328
- ]
329
- };
330
- }
331
- const result = SandboxTemplateManifestSchema.safeParse(value);
332
- if (result.success)
333
- return { ok: true, manifest: result.data, diagnostics: [] };
334
- return {
335
- ok: false,
336
- manifest: null,
337
- diagnostics: result.error.issues.map((issue) => ({
338
- path: formatIssuePath(issue.path),
339
- code: issue.code,
340
- message: issue.message
341
- }))
342
- };
343
- }
344
- function formatSandboxTemplateDiagnostics(diagnostics) {
345
- return diagnostics.map((diagnostic) => `${diagnostic.path}: ${diagnostic.message}`).join("\n");
346
- }
347
- function sandboxTemplateExecutableEntries(manifest) {
348
- return [
349
- {
350
- kind: "start",
351
- name: "start",
352
- ...manifest.start,
353
- artifactPaths: commandArtifactPaths(manifest.start, manifest)
354
- },
355
- ...manifest.actions.map((action) => ({
356
- kind: "action",
357
- name: action.name,
358
- command: action.command,
359
- cwd: action.cwd,
360
- timeoutSeconds: action.timeoutSeconds,
361
- requiresStart: action.requiresStart,
362
- ports: action.ports,
363
- artifactPaths: commandArtifactPaths(action, manifest)
364
- })),
365
- ...manifest.services.map((service) => ({
366
- kind: "service",
367
- name: service.name,
368
- command: service.command,
369
- cwd: service.cwd,
370
- timeoutSeconds: service.timeoutSeconds,
371
- requiresStart: service.requiresStart,
372
- ports: service.ports,
373
- artifactPaths: commandArtifactPaths(service, manifest)
374
- }))
375
- ];
376
- }
377
- function sandboxTemplateBuildMetadata(manifest) {
378
- const executables = sandboxTemplateExecutableEntries(manifest);
379
- return {
380
- template: {
381
- name: manifest.name,
382
- version: manifest.version,
383
- useCase: manifest.useCase,
384
- runtime: manifest.runtime
385
- },
386
- resources: manifest.resources ?? null,
387
- volumes: manifest.volumes,
388
- executables: executables.map((entry) => ({
389
- kind: entry.kind,
390
- name: entry.name,
391
- command: entry.command,
392
- cwd: entry.cwd ?? null,
393
- timeoutSeconds: entry.timeoutSeconds ?? null,
394
- requiresStart: entry.requiresStart,
395
- ports: entry.ports.map((port) => port.port),
396
- artifactPaths: entry.artifactPaths
397
- })),
398
- ports: executables.flatMap((entry) => entry.ports.map((port) => ({
399
- executable: entry.name,
400
- kind: entry.kind,
401
- port: port.port,
402
- access: port.access,
403
- label: port.label ?? null
404
- }))),
405
- appMcpEndpoints: manifest.mcp.endpoints.map((endpoint) => ({
406
- name: endpoint.name ?? null,
407
- service: endpoint.service ?? null,
408
- port: endpoint.port,
409
- path: endpoint.path
410
- })),
411
- validation: {
412
- commands: manifest.validation.commands,
413
- probes: manifest.validation.probes
414
- },
415
- schedules: manifest.schedules
416
- };
417
- }
418
- function sandboxTemplateBuildPlan(input) {
419
- return {
420
- kind: SANDBOX_TEMPLATE_BUILD_PLAN_KIND,
421
- schemaVersion: 1,
422
- manifestFile: input.manifestFile,
423
- projectRoot: input.projectRoot,
424
- manifest: input.manifest,
425
- metadata: sandboxTemplateBuildMetadata(input.manifest),
426
- executables: sandboxTemplateExecutableEntries(input.manifest)
427
- };
428
- }
429
- function sandboxTemplateScaffoldFiles(input) {
430
- const displayName = input.name.trim() || "Sandbox Template";
431
- const name = slug(displayName);
432
- const description = input.description?.trim() || `Local scaffold for ${displayName}.`;
433
- return {
434
- ".gitignore": ["node_modules", "artifacts", ".DS_Store", ""].join("\n"),
435
- "README.md": [
436
- `# ${displayName}`,
437
- "",
438
- "Local sandbox template scaffold.",
439
- "",
440
- "## Commands",
441
- "",
442
- "- `pnpm dev` starts the preview service on port 3000.",
443
- "- `pnpm process` writes a sample artifact.",
444
- `- \`pnpm validate\` validates ${OPENPOND_MANIFEST_FILE_NAME}.`,
445
- ""
446
- ].join("\n"),
447
- "package.json": `${JSON.stringify({
448
- private: true,
449
- type: "module",
450
- scripts: {
451
- dev: "node src/server.ts",
452
- process: "node scripts/process.ts",
453
- validate: `openpond sandbox-template validate --file ${OPENPOND_MANIFEST_FILE_NAME}`
454
- }
455
- }, null, 2)}
456
- `,
457
- [OPENPOND_MANIFEST_FILE_NAME]: [
458
- "schemaVersion: 1",
459
- `name: ${name}`,
460
- "version: 0.1.0",
461
- "useCase: sandbox-template-scaffold",
462
- `description: ${description}`,
463
- "runtime:",
464
- " base: node-bun-workspace",
465
- "resources:",
466
- " cpu: 1",
467
- " memoryGb: 1",
468
- " diskGb: 8",
469
- "setup:",
470
- " commands:",
471
- " - mkdir -p artifacts",
472
- "validation:",
473
- " commands:",
474
- " - test -f src/server.ts",
475
- " - test -f scripts/process.ts",
476
- "start:",
477
- " command: pnpm process",
478
- " timeoutSeconds: 300",
479
- " ports: []",
480
- " artifactPaths:",
481
- " - artifacts/result.json",
482
- "actions: []",
483
- "schedules: []",
484
- "services:",
485
- " - name: web",
486
- " command: pnpm dev",
487
- " timeoutSeconds: 3600",
488
- " ports:",
489
- " - port: 3000",
490
- " protocol: http",
491
- " label: web",
492
- " access: private",
493
- " path: /",
494
- " artifactPaths: []",
495
- "inputs:",
496
- " env:",
497
- " - name: FOO_API_KEY",
498
- " required: false",
499
- " secret: true",
500
- " description: API key used by the sample action.",
501
- " schema:",
502
- " type: object",
503
- " properties:",
504
- " subject:",
505
- " type: string",
506
- " title: Subject",
507
- " default: Example",
508
- "artifacts:",
509
- " paths:",
510
- " - artifacts/result.json",
511
- "network:",
512
- " egress: restricted",
513
- ""
514
- ].join("\n"),
515
- "src/server.ts": [
516
- "import { createServer } from 'node:http';",
517
- "",
518
- "createServer((_request, response) => {",
519
- " response.setHeader('content-type', 'application/json');",
520
- " response.end(JSON.stringify({ ok: true, template: 'sandbox-template-scaffold' }));",
521
- "}).listen(3000, '0.0.0.0');",
522
- ""
523
- ].join("\n"),
524
- "scripts/process.ts": [
525
- "import { mkdir, writeFile } from 'node:fs/promises';",
526
- "",
527
- "const raw = process.env.OPENPOND_REPLAY_PARAMS_BASE64;",
528
- "const params = raw ? JSON.parse(Buffer.from(raw, 'base64').toString('utf8')).input ?? {} : {};",
529
- "await mkdir('artifacts', { recursive: true });",
530
- "await writeFile('artifacts/result.json', JSON.stringify({ ok: true, input: params }, null, 2));",
531
- "console.log('wrote artifacts/result.json');",
532
- ""
533
- ].join("\n"),
534
- "fixtures/input.txt": "Example input\n"
535
- };
536
- }
537
- function isSafeRelativeWorkspacePath(value) {
538
- return !value.includes("\0") && !value.startsWith("/") && !value.split(/[\\/]+/).some((segment) => segment === ".." || segment === "");
539
- }
540
- function formatIssuePath(path) {
541
- if (path.length === 0)
542
- return "$";
543
- return `$${path.map((part) => typeof part === "number" ? `[${part}]` : `.${String(part)}`).join("")}`;
544
- }
545
- function addDuplicateNameIssue(context, names, message, path) {
546
- const seen = /* @__PURE__ */ new Set();
547
- for (const name of names) {
548
- if (seen.has(name)) {
549
- context.addIssue({
550
- code: external_exports.ZodIssueCode.custom,
551
- path: [path],
552
- message
553
- });
554
- return;
555
- }
556
- seen.add(name);
557
- }
558
- }
559
- function validateExecutableNames(manifest, context) {
560
- const names = [
561
- "start",
562
- ...manifest.actions.map((action) => action.name),
563
- ...manifest.services.map((service) => service.name)
564
- ];
565
- addDuplicateNameIssue(context, names, "start, action, and service names must be unique", "actions");
566
- }
567
- function validateInputSchemaUploadTargets(manifest, context) {
568
- const properties = asRecord(manifest.inputs.schema.properties);
569
- const volumeNames = new Set(manifest.volumes.map((volume) => volume.name).filter((name) => Boolean(name)));
570
- for (const [inputName, rawProperty] of Object.entries(properties)) {
571
- const property = asRecord(rawProperty);
572
- const upload = asRecord(property["x-openpond-upload"] ?? property.xOpenPondUpload);
573
- const targetPath = typeof upload.targetPath === "string" && upload.targetPath.trim() ? upload.targetPath.trim() : typeof upload.path === "string" && upload.path.trim() ? upload.path.trim() : "";
574
- if (!targetPath)
575
- continue;
576
- const normalizedTargetPath = targetPath.replace(/^workspace\//, "").replace(/^\/+/, "").replace(/\/+$/, "");
577
- if (!isSafeRelativeWorkspacePath(normalizedTargetPath)) {
578
- context.addIssue({
579
- code: external_exports.ZodIssueCode.custom,
580
- path: [
581
- "inputs",
582
- "schema",
583
- "properties",
584
- inputName,
585
- "x-openpond-upload",
586
- "targetPath"
587
- ],
588
- message: "upload target must be a relative workspace path"
589
- });
590
- continue;
591
- }
592
- const parts = normalizedTargetPath.split("/");
593
- if (parts[0] === "volumes" && (!parts[1] || !volumeNames.has(parts[1]))) {
594
- context.addIssue({
595
- code: external_exports.ZodIssueCode.custom,
596
- path: [
597
- "inputs",
598
- "schema",
599
- "properties",
600
- inputName,
601
- "x-openpond-upload",
602
- "targetPath"
603
- ],
604
- message: "upload target references an undeclared volume"
605
- });
606
- }
607
- }
608
- }
609
- function validateEnvInputs(manifest, context) {
610
- addDuplicateNameIssue(context, manifest.inputs.env.map((env) => env.name), "env input names must be unique", "inputs");
611
- }
612
- function validateMcpEndpoints(manifest, context) {
613
- const servicePorts = new Map(manifest.services.map((service) => [
614
- service.name,
615
- new Set(service.ports.map((port) => port.port))
616
- ]));
617
- const declaredPorts = /* @__PURE__ */ new Set([
618
- ...manifest.start.ports.map((port) => port.port),
619
- ...manifest.services.flatMap((service) => service.ports.map((port) => port.port))
620
- ]);
621
- for (const [index, endpoint] of manifest.mcp.endpoints.entries()) {
622
- if (endpoint.service) {
623
- const ports = servicePorts.get(endpoint.service);
624
- if (!ports) {
625
- context.addIssue({
626
- code: external_exports.ZodIssueCode.custom,
627
- path: ["mcp", "endpoints", index, "service"],
628
- message: `app MCP service does not exist: ${endpoint.service}`
629
- });
630
- continue;
631
- }
632
- if (!ports.has(endpoint.port)) {
633
- context.addIssue({
634
- code: external_exports.ZodIssueCode.custom,
635
- path: ["mcp", "endpoints", index, "port"],
636
- message: `app MCP port ${endpoint.port} is not declared on service ${endpoint.service}`
637
- });
638
- }
639
- continue;
640
- }
641
- if (!declaredPorts.has(endpoint.port)) {
642
- context.addIssue({
643
- code: external_exports.ZodIssueCode.custom,
644
- path: ["mcp", "endpoints", index, "port"],
645
- message: `app MCP port ${endpoint.port} is not declared on start or services`
646
- });
647
- }
648
- }
649
- }
650
- function validateScheduleTargets(manifest, context) {
651
- const actionNames = new Set(manifest.actions.map((action) => action.name));
652
- const serviceNames = new Set(manifest.services.map((service) => service.name));
653
- for (const [index, schedule] of manifest.schedules.entries()) {
654
- const command = schedule.command ?? schedule.target?.command ?? null;
655
- if (schedule.target?.kind === "command" || command) {
656
- continue;
657
- }
658
- const actionName = schedule.actionName ?? schedule.action ?? schedule.target?.actionName ?? (schedule.target?.kind === "action" ? schedule.target?.name : null);
659
- if (actionName && !actionNames.has(actionName)) {
660
- context.addIssue({
661
- code: external_exports.ZodIssueCode.custom,
662
- path: ["schedules", index, "action"],
663
- message: `schedule action target does not exist: ${actionName}`
664
- });
665
- }
666
- if (schedule.target?.kind === "service") {
667
- const serviceName = schedule.target.name ?? "";
668
- if (serviceName && !serviceNames.has(serviceName)) {
669
- context.addIssue({
670
- code: external_exports.ZodIssueCode.custom,
671
- path: ["schedules", index, "target", "name"],
672
- message: `schedule service target does not exist: ${serviceName}`
673
- });
674
- }
675
- }
676
- }
677
- }
678
- function asRecord(value) {
679
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
680
- }
681
- function commandArtifactPaths(command, manifest) {
682
- return command.artifactPaths.length > 0 ? command.artifactPaths : manifest.artifacts.paths;
683
- }
684
- function slug(value) {
685
- return value.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 80) || "sandbox-template";
686
- }
687
-
688
- // ../../packages/connected-apps/dist/index.js
689
- var CONNECTED_APP_PROVIDER_TOOL_NAMES = [
690
- "connected_app_search",
691
- "connected_app_read",
692
- "connected_app_write"
693
- ];
694
- var CONNECTED_APP_TOOL_CALL_ENDPOINT = "/v1/integrations/tool-calls";
695
- var DEFAULT_OPENPOND_WEB_BASE_URL = "https://openpond.ai";
696
- var CONNECTED_APP_PROVIDER_ORDER = [
697
- "slack",
698
- "google",
699
- "github",
700
- "x",
701
- "microsoft_teams",
702
- "mcp"
703
- ];
704
- var CAPABILITIES = {
705
- slack: [
706
- capability("slack.channel.bind", "Bind channels", "Bind Slack channels or threads to OpenPond profiles.", "setup", false),
707
- capability("slack.message.ingest", "Ingest messages", "Ingest Slack channel or thread activity into OpenPond context.", "setup", false)
708
- ],
709
- microsoft_teams: [
710
- capability("microsoft_teams.channel.bind", "Bind channels", "Bind Teams channels or chats to OpenPond profiles.", "setup", false),
711
- capability("microsoft_teams.message.ingest", "Ingest messages", "Ingest Teams channel or chat activity into OpenPond context.", "setup", false)
712
- ],
713
- google: [
714
- capability("google.drive.file.read", "Read Drive files", "Find and read Google Drive files.", "read", true),
715
- capability("google.drive.file.write", "Write Drive files", "Create or update approved Google Drive files.", "write", true),
716
- capability("google.docs.read", "Read Docs", "Read Google Docs content and structure.", "read", true),
717
- capability("google.docs.write", "Edit Docs", "Apply approved Google Docs edits.", "write", true),
718
- capability("google.comments.read", "Read comments", "Read Google file comments.", "read", true),
719
- capability("google.comments.write", "Write comments", "Create or resolve approved Google comments.", "write", true)
720
- ],
721
- github: [
722
- capability("github.repo.read", "Read repositories", "Read repository metadata and file context.", "read", true),
723
- capability("github.issue.read", "Read issues", "Read GitHub issues and comments.", "read", true),
724
- capability("github.issue.write", "Update issues", "Create or update approved GitHub issue content.", "write", true),
725
- capability("github.pull_request.read", "Read pull requests", "Read pull request metadata, diffs, checks, and reviews.", "read", true),
726
- capability("github.pull_request.write", "Update pull requests", "Create approved comments or pull request updates.", "write", true)
727
- ],
728
- x: [
729
- capability("x.profile.read", "Read profile", "Read the connected X profile.", "read", true),
730
- capability("x.search.read", "Search X", "Search public X posts when granted.", "read", true),
731
- capability("x.mentions.read", "Read mentions", "Read mentions for the connected X account.", "read", true),
732
- capability("x.post.write", "Post", "Create approved X posts.", "write", true),
733
- capability("x.reply.write", "Reply", "Create approved X replies.", "write", true)
734
- ],
735
- mcp: [
736
- capability("mcp.tool.discover", "Discover tools", "Discover team-scoped MCP tools.", "tooling", false),
737
- capability("mcp.tool.call", "Call tools", "Call approved MCP tools through the team endpoint.", "tooling", false)
738
- ]
739
- };
740
- var PROVIDER_OPERATIONS = {
741
- slack: [],
742
- microsoft_teams: [],
743
- google: [
744
- providerOperation("google.drive.search", "search", "Search Drive", "Search Google Drive files by grounded query.", ["google.drive.file.read"]),
745
- providerOperation("google.drive.read_file", "read", "Read Drive file", "Read Drive file metadata or exported content by stable ref.", ["google.drive.file.read"], { requiredKeys: ["ref"] }),
746
- providerOperation("google.docs.read", "read", "Read Google Doc", "Read Google Docs content and structure by stable ref.", ["google.docs.read"], { requiredKeys: ["ref"] }),
747
- providerOperation("google.comments.read", "read", "Read comments", "Read comments for a grounded Google file ref.", ["google.comments.read"], { requiredKeys: ["ref"] }),
748
- providerOperation("google.docs.update", "write", "Update Google Doc", "Apply an explicitly approved Google Docs edit and return readback verification.", ["google.docs.write"], { requiredKeys: ["ref", "patch"] }),
749
- providerOperation("google.comments.create", "write", "Create comment", "Create an explicitly approved Google file comment and return readback verification.", ["google.comments.write"], { requiredKeys: ["ref", "body"] }),
750
- providerOperation("google.comments.resolve", "write", "Resolve comment", "Resolve an explicitly approved Google comment and return readback verification.", ["google.comments.write"], { requiredKeys: ["ref", "commentId"] })
751
- ],
752
- github: [
753
- providerOperation("github.repo.search", "search", "Search repositories", "Search accessible repositories by owner, name, or topic.", ["github.repo.read"]),
754
- providerOperation("github.issue.search", "search", "Search issues", "Search accessible GitHub issues.", ["github.issue.read"]),
755
- providerOperation("github.pull_request.search", "search", "Search pull requests", "Search accessible GitHub pull requests.", ["github.pull_request.read"]),
756
- providerOperation("github.repo.read", "read", "Read repository", "Read grounded repository metadata or file context.", ["github.repo.read"], { requiredKeys: ["ref"] }),
757
- providerOperation("github.issue.read", "read", "Read issue", "Read a grounded GitHub issue and comments.", ["github.issue.read"], { requiredKeys: ["ref"] }),
758
- providerOperation("github.pull_request.read", "read", "Read pull request", "Read a grounded pull request, checks, reviews, or diff summary.", ["github.pull_request.read"], { requiredKeys: ["ref"] }),
759
- providerOperation("github.issue.create", "write", "Create issue", "Create an explicitly approved GitHub issue and return readback verification.", ["github.issue.write"], { requiredKeys: ["repo", "title", "body"] }),
760
- providerOperation("github.issue.comment", "write", "Comment on issue", "Create an explicitly approved GitHub issue comment and return readback verification.", ["github.issue.write"], { requiredKeys: ["ref", "body"] }),
761
- providerOperation("github.issue.update", "write", "Update issue", "Apply an explicitly approved issue metadata/content update and return readback verification.", ["github.issue.write"], { requiredKeys: ["ref"] }),
762
- providerOperation("github.pull_request.comment", "write", "Comment on pull request", "Create an explicitly approved pull request comment and return readback verification.", ["github.pull_request.write"], { requiredKeys: ["ref", "body"] }),
763
- providerOperation("github.pull_request.update", "write", "Update pull request", "Apply an explicitly approved pull request metadata update and return readback verification.", ["github.pull_request.write"], { requiredKeys: ["ref"] })
764
- ],
765
- x: [
766
- providerOperation("x.profile.read", "read", "Read profile", "Read the connected X account profile.", ["x.profile.read"]),
767
- providerOperation("x.post.read", "read", "Read post", "Read a public X post by stable ref, status URL, or post id.", ["x.search.read"], { requiredKeys: ["ref"] }),
768
- providerOperation("x.search.posts", "search", "Search recent posts", "Search public X posts from the X recent-search window by grounded query.", ["x.search.read"]),
769
- providerOperation("x.mentions.search", "search", "Search mentions", "Search mentions for the connected X account.", ["x.mentions.read"]),
770
- providerOperation("x.mention.read", "read", "Read mention", "Read a grounded mention or post ref.", ["x.mentions.read"], { requiredKeys: ["ref"] }),
771
- providerOperation("x.post.create", "write", "Create post", "Create an explicitly approved X post and return readback verification.", ["x.post.write"], { requiredKeys: ["text"] }),
772
- providerOperation("x.reply.create", "write", "Create reply", "Create an explicitly approved X reply and return readback verification.", ["x.reply.write"], { requiredKeys: ["inReplyToRef", "text"] })
773
- ],
774
- mcp: []
775
- };
776
- var INTEGRATION_SKILL_BODIES = {
777
- google: [
778
- "# Google Connected App",
779
- "",
780
- "Use Google only through server-provided connected app tools. Never ask for or infer OAuth tokens.",
781
- "Before reading or editing, identify the exact Drive file, Doc, Sheet, Slide, or comment thread. If the target is ambiguous, ask a short clarification or search first.",
782
- "Use only declared Google operation ids: google.drive.search, google.drive.read_file, google.docs.read, google.comments.read, google.docs.update, google.comments.create, google.comments.resolve.",
783
- "For writes, require explicit user intent, summarize the planned change, and verify the target identity before applying updates.",
784
- "After a write, read back the changed object or relevant range and report the result with the provider file name or stable reference.",
785
- "Prefer narrow reads over broad Drive scans. Do not expose private file ids unless the tool result already presents them as stable refs."
786
- ].join("\n"),
787
- github: [
788
- "# GitHub Connected App",
789
- "",
790
- "Use GitHub only through server-provided connected app tools. Repository, issue, and pull request identity must be grounded before action.",
791
- "Use only declared GitHub operation ids: github.repo.search, github.issue.search, github.pull_request.search, github.repo.read, github.issue.read, github.pull_request.read, github.issue.create, github.issue.comment, github.issue.update, github.pull_request.comment, github.pull_request.update.",
792
- "For reads, name the owner/repo and issue or pull request number when available. If several targets match, ask or inspect before proceeding.",
793
- "For writes, require explicit user intent and avoid destructive repository changes. Create issues only when the user clearly asks to submit or file a new issue. Prefer comments, labels, or metadata updates unless a stronger operation is clearly requested.",
794
- "Do not claim CI, review, branch, or PR state changed until a tool result confirms it.",
795
- "Keep local workspace git operations separate from connected GitHub operations unless the user explicitly asks to bridge them."
796
- ].join("\n"),
797
- x: [
798
- "# X Connected App",
799
- "",
800
- "Use X only through server-provided connected app tools. Distinguish profile, recent search, mention, post, and reply operations.",
801
- "Use only declared X operation ids: x.profile.read, x.post.read, x.search.posts, x.mentions.search, x.mention.read, x.post.create, x.reply.create.",
802
- "For x.com, twitter.com, or stable status URLs, first parse the status/post id and read the post with connected_app_read using operation x.post.read and ref set to the original URL, stable ref, or id. Do not open a browser before trying the X connector.",
803
- "Use x.search.posts for discovery, related public posts, replies, quote-post searches, and conversation scans. It uses X API recent search, so report zero-result searches as zero recent public posts returned by X.",
804
- "For conversation or reply collection, dedupe by returned post id/ref. Do not repeat the same search call unless the result exposes a usable cursor or next token; if pagination is unavailable, state that coverage is limited to returned recent-search results.",
805
- "Reads can summarize recent public posts, connected-account profile details, and mentions when the capability is available.",
806
- "Writes require explicit user intent for the exact post or reply. Do not publish drafts, jokes, endorsements, or replies unless the user clearly approves the content.",
807
- "Before posting or replying, preserve account identity, quote the proposed content in summary form, and respect provider limits and policy boundaries.",
808
- "After a write, verify the returned post or reply ref before reporting success."
809
- ].join("\n"),
810
- microsoft_teams: [
811
- "# Microsoft Teams Connected App",
812
- "",
813
- "Microsoft Teams is currently an ingestion/native binding surface only. Do not expose Teams OAuth reads, replies, file operations, or sandbox leases.",
814
- "Native Teams setup can bind chats or channels to OpenPond profiles and ingest activity into OpenPond context.",
815
- "If the user asks for Teams actions beyond ingestion or binding status, explain that the connector is not available yet rather than inventing tool access."
816
- ].join("\n"),
817
- slack: [
818
- "# Slack Connected App",
819
- "",
820
- "Slack is currently an ingestion/native binding surface only. Do not expose Slack OAuth reads, replies, file operations, or sandbox leases.",
821
- "Native Slack setup can bind channels or threads to OpenPond profiles and ingest activity into OpenPond context.",
822
- "If the user asks for Slack actions beyond ingestion or binding status, explain that the connector is not available yet rather than inventing tool access."
823
- ].join("\n"),
824
- mcp: [
825
- "# OpenPond MCP Connected App",
826
- "",
827
- "Use OpenPond MCP only through server-provided tool discovery and call paths. Do not invent MCP tools or endpoints.",
828
- "Treat MCP as team-scoped tooling, not an OAuth connector. Tool availability must come from server-confirmed discovery results.",
829
- "Before calling an MCP tool, match the requested operation to the tool name, description, input schema, and allowed team context.",
830
- "For writes or side effects, require explicit user intent and report only confirmed tool results."
831
- ].join("\n")
832
- };
833
- var CONNECTED_APP_INTEGRATION_SKILLS = CONNECTED_APP_PROVIDER_ORDER.map((provider) => {
834
- const descriptor = integrationSkillDescriptor(provider);
835
- const body = INTEGRATION_SKILL_BODIES[provider];
836
- return {
837
- ...descriptor,
838
- provider,
839
- body,
840
- sourceHash: `connected-app-skill:${provider}:${hashString(body)}`,
841
- charCount: body.length
842
- };
843
- });
844
- function connectedAppIntegrationSkillByProvider(provider) {
845
- const normalized = normalizeConnectedAppProviderFamilyId(provider);
846
- if (!normalized)
847
- return null;
848
- return CONNECTED_APP_INTEGRATION_SKILLS.find((skill) => skill.provider === normalized) ?? null;
849
- }
850
- function validateConnectedAppToolCallRequest(request) {
851
- const bundle = connectedAppBundleByProvider(request.provider);
852
- if (!bundle) {
853
- return { ok: false, error: `Connected app provider is not supported: ${request.provider}` };
854
- }
855
- if (!bundle.leasePolicy.leaseable) {
856
- return {
857
- ok: false,
858
- error: `Connected app provider ${request.provider} is not leaseable for cloud connector execution.`
859
- };
860
- }
861
- const expectedToolName = toolNameForOperation(request.operation);
862
- if (request.toolName !== expectedToolName) {
863
- return {
864
- ok: false,
865
- error: `Connected app tool ${request.toolName} does not match ${request.operation} operation.`
866
- };
867
- }
868
- const access = request.operation === "write" ? "write" : "read";
869
- const allowedCapabilityIds = new Set(bundle.capabilities.filter((capability2) => capability2.access === access && capability2.leaseable).map((capability2) => capability2.id));
870
- const unauthorized = request.capabilityIds.filter((capabilityId) => !allowedCapabilityIds.has(capabilityId));
871
- if (unauthorized.length > 0) {
872
- return {
873
- ok: false,
874
- error: `Connected app capability ${unauthorized[0]} is not allowed for ${request.provider} ${request.operation}.`
875
- };
876
- }
877
- const operationValidation = validateConnectedAppProviderOperationRequest(request);
878
- if (!operationValidation.ok)
879
- return operationValidation;
880
- return { ok: true, request };
881
- }
882
- function connectedAppProviderOperations(provider) {
883
- const normalized = normalizeConnectedAppProviderFamilyId(provider);
884
- return normalized ? PROVIDER_OPERATIONS[normalized] : [];
885
- }
886
- function connectedAppProviderOperationById(provider, operationId) {
887
- const normalizedId = normalizeProviderOperationId(operationId);
888
- if (!normalizedId)
889
- return null;
890
- return connectedAppProviderOperations(provider).find((operation) => operation.id === normalizedId) ?? null;
891
- }
892
- function validateConnectedAppProviderOperationRequest(request) {
893
- const requestedOperation = providerOperationIdFromArgs(request.args);
894
- const operations = connectedAppProviderOperations(request.provider).filter((operation2) => operation2.operation === request.operation);
895
- if (operations.length === 0) {
896
- return {
897
- ok: false,
898
- error: `Connected app provider ${request.provider} does not declare ${request.operation} operations.`
899
- };
900
- }
901
- if (!requestedOperation) {
902
- if (request.operation === "write") {
903
- return {
904
- ok: false,
905
- error: `Connected app ${request.provider} write calls require a provider operation id.`
906
- };
907
- }
908
- return { ok: true, request };
909
- }
910
- const operation = operations.find((candidate) => candidate.id === requestedOperation);
911
- if (!operation) {
912
- return {
913
- ok: false,
914
- error: `Connected app operation ${requestedOperation} is not allowed for ${request.provider} ${request.operation}.`
915
- };
916
- }
917
- const deniedCapabilities = request.capabilityIds.filter((capabilityId) => !operation.capabilityIds.includes(capabilityId));
918
- if (deniedCapabilities.length > 0) {
919
- return {
920
- ok: false,
921
- error: `Connected app operation ${operation.id} does not allow capability ${deniedCapabilities[0]}.`
922
- };
923
- }
924
- const input = providerOperationInputFromArgs(request.args, request.operation);
925
- for (const key of operation.input?.requiredKeys ?? []) {
926
- const value = input[key];
927
- if (value === void 0 || value === null || typeof value === "string" && !value.trim()) {
928
- return {
929
- ok: false,
930
- error: `Connected app operation ${operation.id} requires input.${key}.`
931
- };
932
- }
933
- }
934
- return { ok: true, request };
935
- }
936
- var CATALOG = [
937
- catalogEntry({
938
- id: "slack",
939
- providerFamily: "slack",
940
- setupSurface: "native_bot",
941
- statusSource: "native_binding",
942
- label: "Slack",
943
- shortLabel: "Slack",
944
- kind: "native",
945
- category: "Chat",
946
- description: "Bind Slack channels or threads for ingestion into OpenPond profiles.",
947
- icon: "/connected-apps/slack.svg",
948
- installLabel: "Continue to Slack details"
949
- }),
950
- catalogEntry({
951
- id: "google",
952
- providerFamily: "google",
953
- setupSurface: "oauth_connector",
954
- statusSource: "integration_connection",
955
- label: "Google",
956
- shortLabel: "Google",
957
- kind: "oauth",
958
- category: "Productivity",
959
- description: "Docs, Drive files, and comments for sandbox workflows.",
960
- icon: "/connected-apps/google.svg",
961
- installLabel: "Continue to Google details"
962
- }),
963
- catalogEntry({
964
- id: "github",
965
- providerFamily: "github",
966
- setupSurface: "oauth_connector",
967
- statusSource: "integration_connection",
968
- label: "GitHub",
969
- shortLabel: "GitHub",
970
- kind: "oauth",
971
- category: "Developer tools",
972
- description: "Access repositories, issues, and pull requests.",
973
- icon: "/connected-apps/github.svg",
974
- installLabel: "Continue to GitHub details"
975
- }),
976
- catalogEntry({
977
- id: "x",
978
- providerFamily: "x",
979
- setupSurface: "oauth_connector",
980
- statusSource: "integration_connection",
981
- label: "X",
982
- shortLabel: "X",
983
- kind: "oauth",
984
- category: "Productivity",
985
- description: "User profile, mentions, and approved reply access.",
986
- icon: "/connected-apps/x.svg",
987
- installLabel: "Continue to X details"
988
- }),
989
- catalogEntry({
990
- id: "microsoft_teams",
991
- providerFamily: "microsoft_teams",
992
- setupSurface: "native_bot",
993
- statusSource: "native_binding",
994
- label: "Teams",
995
- shortLabel: "Teams",
996
- kind: "native",
997
- category: "Chat",
998
- description: "Bind Teams chats or channels for ingestion into OpenPond profiles.",
999
- icon: "/connected-apps/microsoft.svg",
1000
- installLabel: "Continue to Teams details"
1001
- }),
1002
- catalogEntry({
1003
- id: "mcp",
1004
- providerFamily: "mcp",
1005
- setupSurface: "mcp_endpoint",
1006
- statusSource: "mcp_endpoint",
1007
- label: "OpenPond MCP",
1008
- shortLabel: "MCP",
1009
- kind: "mcp",
1010
- category: "Tools",
1011
- description: "Expose workspace tools through a team-scoped MCP endpoint.",
1012
- icon: "/connected-apps/openpond-mcp.svg",
1013
- installLabel: "Open MCP settings"
1014
- })
1015
- ];
1016
- var CONNECTED_APP_CATALOG = CATALOG;
1017
- var CONNECTED_APP_BUNDLES = CONNECTED_APP_PROVIDER_ORDER.map((providerFamily) => {
1018
- const setupSurfaces = CONNECTED_APP_CATALOG.filter((entry) => entry.providerFamily === providerFamily);
1019
- const firstSurface = setupSurfaces[0];
1020
- return {
1021
- id: providerFamily,
1022
- label: providerFamilyLabel(providerFamily),
1023
- shortLabel: firstSurface.shortLabel,
1024
- category: firstSurface.category,
1025
- icon: firstSurface.icon,
1026
- description: firstSurface.description,
1027
- setupSurfaces,
1028
- capabilities: CAPABILITIES[providerFamily],
1029
- skills: providerSkills(providerFamily),
1030
- tools: providerTools(providerFamily),
1031
- operations: PROVIDER_OPERATIONS[providerFamily],
1032
- leasePolicy: leasePolicy(providerFamily)
1033
- };
1034
- });
1035
- function connectedAppById(appId) {
1036
- const normalized = normalizeConnectedAppId(appId);
1037
- if (!normalized)
1038
- return null;
1039
- return CONNECTED_APP_CATALOG.find((app) => app.id === normalized) ?? null;
1040
- }
1041
- function connectedAppBundleByProvider(provider) {
1042
- const normalized = normalizeConnectedAppProviderFamilyId(provider);
1043
- if (!normalized)
1044
- return null;
1045
- return CONNECTED_APP_BUNDLES.find((bundle) => bundle.id === normalized) ?? null;
1046
- }
1047
- function buildConnectedAppInstallUrl(input) {
1048
- const app = connectedAppById(input.appId);
1049
- const baseUrl = normalizeOpenPondWebBaseUrl(input.baseUrl);
1050
- const path = app?.kind === "mcp" ? "/sandboxes/mcp" : "/sandboxes/apps";
1051
- const url = new URL(path, baseUrl);
1052
- if (app?.kind !== "mcp") {
1053
- url.searchParams.set("app", app?.deepLinkAppId ?? input.appId);
1054
- }
1055
- const teamId = input.teamId?.trim();
1056
- if (teamId)
1057
- url.searchParams.set("teamId", teamId);
1058
- return url.toString();
1059
- }
1060
- function normalizeConnectedAppId(value) {
1061
- const normalized = value?.trim().toLowerCase().replace(/[-\s]+/g, "_");
1062
- if (!normalized)
1063
- return null;
1064
- if (normalized === "teams" || normalized === "microsoft")
1065
- return "microsoft_teams";
1066
- return CONNECTED_APP_CATALOG.some((app) => app.id === normalized) ? normalized : null;
1067
- }
1068
- function normalizeConnectedAppProviderFamilyId(value) {
1069
- const normalized = value?.trim().toLowerCase().replace(/[-\s]+/g, "_");
1070
- if (!normalized)
1071
- return null;
1072
- if (normalized === "teams" || normalized === "microsoft") {
1073
- return "microsoft_teams";
1074
- }
1075
- if (CONNECTED_APP_PROVIDER_ORDER.includes(normalized)) {
1076
- return normalized;
1077
- }
1078
- const app = connectedAppById(normalized);
1079
- return app?.providerFamily ?? null;
1080
- }
1081
- function buildConnectedAppStatusRows(input = {}) {
1082
- const connections = normalizeConnections(input.connections ?? []);
1083
- return CONNECTED_APP_CATALOG.map((entry) => {
1084
- const bundle = connectedAppBundleByProvider(entry.providerFamily);
1085
- const matchingConnections = entry.statusSource === "integration_connection" ? connections.filter((connection) => connection.provider === entry.providerFamily) : [];
1086
- const connected = matchingConnections.some((connection) => connection.status === "active");
1087
- const status = surfaceStatus(entry, connected);
1088
- return {
1089
- ...entry,
1090
- providerLabel: bundle.label,
1091
- setupSurfaceLabel: setupSurfaceLabel(entry.setupSurface),
1092
- status,
1093
- statusLabel: statusLabel(entry, status, matchingConnections),
1094
- connections: matchingConnections,
1095
- connected,
1096
- capabilities: capabilitiesForSurface(entry, bundle.capabilities),
1097
- capabilityLabels: capabilitiesForSurface(entry, bundle.capabilities).map((capability2) => capability2.label),
1098
- leasePolicy: bundle.leasePolicy
1099
- };
1100
- });
1101
- }
1102
- function capability(id, label, description, access, leaseable) {
1103
- return { id, label, description, access, leaseable };
1104
- }
1105
- function catalogEntry(entry) {
1106
- return entry;
1107
- }
1108
- function providerOperation(id, operation, label, description, capabilityIds, input) {
1109
- return {
1110
- id,
1111
- operation,
1112
- label,
1113
- description,
1114
- capabilityIds,
1115
- ...input ? { input } : {},
1116
- requiresReadback: operation === "write",
1117
- requiresRuntimeLease: false
1118
- };
1119
- }
1120
- function providerOperationIdFromArgs(args) {
1121
- return normalizeProviderOperationId(args.operation);
1122
- }
1123
- function normalizeProviderOperationId(value) {
1124
- return typeof value === "string" && value.trim() ? value.trim() : null;
1125
- }
1126
- function providerOperationInputFromArgs(args, operation) {
1127
- if (operation === "write") {
1128
- return isRecord(args.input) ? args.input : {};
1129
- }
1130
- return args;
1131
- }
1132
- function isRecord(value) {
1133
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1134
- }
1135
- function normalizeOpenPondWebBaseUrl(value) {
1136
- const trimmed = value?.trim();
1137
- if (!trimmed)
1138
- return DEFAULT_OPENPOND_WEB_BASE_URL;
1139
- try {
1140
- const url = new URL(trimmed);
1141
- if (url.protocol !== "http:" && url.protocol !== "https:")
1142
- return DEFAULT_OPENPOND_WEB_BASE_URL;
1143
- url.pathname = "/";
1144
- url.search = "";
1145
- url.hash = "";
1146
- return url.toString();
1147
- } catch {
1148
- return DEFAULT_OPENPOND_WEB_BASE_URL;
1149
- }
1150
- }
1151
- function providerFamilyLabel(provider) {
1152
- if (provider === "microsoft_teams")
1153
- return "Microsoft Teams";
1154
- if (provider === "mcp")
1155
- return "OpenPond MCP";
1156
- if (provider === "x")
1157
- return "X";
1158
- return provider[0].toUpperCase() + provider.slice(1);
1159
- }
1160
- function setupSurfaceLabel(surface) {
1161
- if (surface === "native_bot")
1162
- return "Native app";
1163
- if (surface === "oauth_connector")
1164
- return "OAuth connector";
1165
- return "MCP endpoint";
1166
- }
1167
- function providerSkills(provider) {
1168
- return [integrationSkillDescriptor(provider)];
1169
- }
1170
- function integrationSkillDescriptor(provider) {
1171
- return {
1172
- name: `${provider}-connected-app`,
1173
- description: `Use ${providerFamilyLabel(provider)} safely through connected app tools.`,
1174
- path: `integration_skills/${provider}.md`
1175
- };
1176
- }
1177
- function providerTools(provider) {
1178
- if (provider === "mcp")
1179
- return [];
1180
- const capabilities = CAPABILITIES[provider];
1181
- const readCapabilityIds = capabilities.filter((capability2) => capability2.access === "read").map((capability2) => capability2.id);
1182
- const writeCapabilityIds = capabilities.filter((capability2) => capability2.access === "write").map((capability2) => capability2.id);
1183
- const tools = [];
1184
- if (readCapabilityIds.length > 0) {
1185
- tools.push({
1186
- name: "connected_app_search",
1187
- description: `Search ${providerFamilyLabel(provider)} through a server-owned connected app connector.`,
1188
- capabilityIds: readCapabilityIds,
1189
- write: false
1190
- }, {
1191
- name: "connected_app_read",
1192
- description: `Read a grounded ${providerFamilyLabel(provider)} object through a server-owned connected app connector.`,
1193
- capabilityIds: readCapabilityIds,
1194
- write: false
1195
- });
1196
- }
1197
- if (writeCapabilityIds.length > 0) {
1198
- tools.push({
1199
- name: "connected_app_write",
1200
- description: `Perform an explicitly approved ${providerFamilyLabel(provider)} write through a server-owned connected app connector.`,
1201
- capabilityIds: writeCapabilityIds,
1202
- write: true
1203
- });
1204
- }
1205
- return tools;
1206
- }
1207
- function toolNameForOperation(operation) {
1208
- if (operation === "search")
1209
- return "connected_app_search";
1210
- if (operation === "read")
1211
- return "connected_app_read";
1212
- return "connected_app_write";
1213
- }
1214
- function leasePolicy(provider) {
1215
- const capabilities = CAPABILITIES[provider].filter((item) => item.leaseable).map((item) => item.id);
1216
- const leaseable = provider !== "mcp" && capabilities.length > 0;
1217
- return {
1218
- leaseable,
1219
- defaultTtlSeconds: leaseable ? 3600 : null,
1220
- allowedCapabilityIds: capabilities,
1221
- requiresProxy: leaseable
1222
- };
1223
- }
1224
- function capabilitiesForSurface(entry, capabilities) {
1225
- if (entry.setupSurface === "native_bot") {
1226
- return capabilities.filter((capability2) => capability2.access === "setup");
1227
- }
1228
- if (entry.setupSurface === "mcp_endpoint")
1229
- return capabilities;
1230
- return capabilities.filter((capability2) => capability2.access !== "setup");
1231
- }
1232
- function normalizeConnections(connections) {
1233
- return connections.flatMap((connection) => {
1234
- const provider = normalizeConnectedAppProviderFamilyId(connection.provider);
1235
- if (!provider)
1236
- return [];
1237
- return [
1238
- {
1239
- id: connection.id ?? null,
1240
- teamId: connection.teamId?.trim() || null,
1241
- provider,
1242
- accountLabel: connection.providerAccountName ?? null,
1243
- workspaceLabel: connection.providerWorkspaceName ?? null,
1244
- scopes: Array.isArray(connection.scopes) ? connection.scopes : [],
1245
- capabilities: Array.isArray(connection.capabilities) ? connection.capabilities : [],
1246
- status: connection.status?.trim().toLowerCase() || "active"
1247
- }
1248
- ];
1249
- });
1250
- }
1251
- function surfaceStatus(entry, connected) {
1252
- if (entry.statusSource === "integration_connection") {
1253
- return connected ? "connected" : "disconnected";
1254
- }
1255
- return "setup_available";
1256
- }
1257
- function statusLabel(entry, status, connections) {
1258
- if (status === "connected") {
1259
- const activeCount = connections.filter((connection) => connection.status === "active").length;
1260
- return activeCount > 1 ? `${activeCount} connected` : "Connected";
1261
- }
1262
- if (status === "disconnected")
1263
- return "Not connected";
1264
- if (entry.statusSource === "native_binding")
1265
- return "Bot setup";
1266
- return "Configure";
1267
- }
1268
- function hashString(value) {
1269
- let hash = 5381;
1270
- for (let index = 0; index < value.length; index += 1) {
1271
- hash = (hash << 5) + hash ^ value.charCodeAt(index);
1272
- }
1273
- return (hash >>> 0).toString(36);
1274
- }
1275
-
1276
- export {
1277
- SANDBOX_TEMPLATE_PREVIEW_PORT_MIN,
1278
- SANDBOX_TEMPLATE_PREVIEW_PORT_MAX,
1279
- OPENPOND_MANIFEST_FILE_NAME,
1280
- SANDBOX_TEMPLATE_BUILD_PLAN_FILE_NAME,
1281
- SandboxTemplateManifestSchema,
1282
- SandboxTemplateValidationDiagnosticSchema,
1283
- validateSandboxTemplateYaml,
1284
- formatSandboxTemplateDiagnostics,
1285
- sandboxTemplateExecutableEntries,
1286
- sandboxTemplateBuildPlan,
1287
- sandboxTemplateScaffoldFiles,
1288
- CONNECTED_APP_PROVIDER_TOOL_NAMES,
1289
- CONNECTED_APP_TOOL_CALL_ENDPOINT,
1290
- CONNECTED_APP_INTEGRATION_SKILLS,
1291
- connectedAppIntegrationSkillByProvider,
1292
- validateConnectedAppToolCallRequest,
1293
- connectedAppProviderOperationById,
1294
- validateConnectedAppProviderOperationRequest,
1295
- CONNECTED_APP_CATALOG,
1296
- connectedAppById,
1297
- connectedAppBundleByProvider,
1298
- buildConnectedAppInstallUrl,
1299
- normalizeConnectedAppProviderFamilyId,
1300
- buildConnectedAppStatusRows
1301
- };