openpond 0.2.0 → 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 (220) hide show
  1. package/dist/chunks/actions-command-QP3NMDK4.js +2 -0
  2. package/dist/chunks/app-layer-N7VFRVJ2.js +3 -0
  3. package/dist/chunks/app-server-runtime-OCLPUI7F.js +2 -0
  4. package/dist/chunks/apps-AMG75TI4.js +2 -0
  5. package/dist/chunks/chunk-22UARBPW.js +3 -0
  6. package/dist/chunks/chunk-3A7HZJNE.js +1 -0
  7. package/dist/chunks/chunk-3M53YXEI.js +2 -0
  8. package/dist/chunks/chunk-3NDRIQTI.js +2 -0
  9. package/dist/chunks/chunk-5BBVEWG3.js +2 -0
  10. package/dist/chunks/chunk-5O7ZVCMV.js +6 -0
  11. package/dist/chunks/chunk-6FA3GG5B.js +33 -0
  12. package/dist/chunks/chunk-6MI4KKWF.js +2 -0
  13. package/dist/chunks/chunk-BBG546O6.js +6 -0
  14. package/dist/chunks/chunk-BX4J2VDU.js +2 -0
  15. package/dist/chunks/chunk-BZMVB3GS.js +2 -0
  16. package/dist/chunks/chunk-C5LOZSVS.js +2 -0
  17. package/dist/chunks/chunk-CWQWV2T3.js +2 -0
  18. package/dist/chunks/chunk-DUA3QP6Y.js +19 -0
  19. package/dist/chunks/chunk-EAPFMACH.js +10 -0
  20. package/dist/chunks/chunk-ES2ISFJC.js +66 -0
  21. package/dist/chunks/chunk-F65NIZLM.js +2199 -0
  22. package/dist/chunks/chunk-FGJ5LFPL.js +5 -0
  23. package/dist/chunks/chunk-FTQLQJQV.js +2 -0
  24. package/dist/chunks/chunk-FY7OQ5RK.js +24 -0
  25. package/dist/chunks/chunk-FYCJSUFV.js +53 -0
  26. package/dist/chunks/chunk-GLUWATL5.js +2 -0
  27. package/dist/chunks/chunk-H7IWJN7L.js +17 -0
  28. package/dist/chunks/chunk-HZP5U2AA.js +3 -0
  29. package/dist/chunks/chunk-I5K74TOH.js +3 -0
  30. package/dist/chunks/chunk-IR3YJWPW.js +7 -0
  31. package/dist/chunks/chunk-KU7QOHFT.js +2872 -0
  32. package/dist/chunks/chunk-KV553EWX.js +16 -0
  33. package/dist/chunks/chunk-MGN6GLNZ.js +2 -0
  34. package/dist/chunks/chunk-OG5Q6NXK.js +28 -0
  35. package/dist/chunks/chunk-OGPHXXCD.js +1 -0
  36. package/dist/chunks/chunk-PI36UHRA.js +18 -0
  37. package/dist/chunks/chunk-RWSAGQTP.js +2 -0
  38. package/dist/chunks/chunk-SAE4OIPC.js +2 -0
  39. package/dist/chunks/chunk-SDO4FC4Q.js +2 -0
  40. package/dist/chunks/chunk-UKUVMXOW.js +12 -0
  41. package/dist/chunks/chunk-VCLCFK3O.js +36 -0
  42. package/dist/chunks/chunk-VYUMTRB3.js +5 -0
  43. package/dist/chunks/chunk-X37KMV27.js +1 -0
  44. package/dist/chunks/chunk-XDHAGACI.js +3 -0
  45. package/dist/chunks/chunk-XEOEKFG6.js +71 -0
  46. package/dist/chunks/chunk-ZF7TEGY5.js +5 -0
  47. package/dist/chunks/chunk-ZVOO7FKM.js +2 -0
  48. package/dist/chunks/cli-M2FG7SSI.js +2 -0
  49. package/dist/chunks/configuration-command-XBKBIZBO.js +2 -0
  50. package/dist/chunks/continual-D75WA7E7.js +7 -0
  51. package/dist/chunks/core-commands-LUZVWXQR.js +2 -0
  52. package/dist/chunks/database-X2CUV732.js +2 -0
  53. package/dist/chunks/desktop-test-KGC4JVJ7.js +3 -0
  54. package/dist/chunks/dist-NKLXFA37.js +2 -0
  55. package/dist/chunks/extension-NQ7N5LEY.js +5 -0
  56. package/dist/chunks/help-MWK66XZK.js +8 -0
  57. package/dist/chunks/module-ES6BEMUI-ZVL3F6NW.js +2 -0
  58. package/dist/chunks/module-asyncify-2EFITU5U-R7TVXNAE.js +2 -0
  59. package/dist/chunks/opchat-XJZA3QKZ.js +3 -0
  60. package/dist/chunks/organizations-UECDFEYE.js +2 -0
  61. package/dist/chunks/profile-KUMIZURM.js +3 -0
  62. package/dist/chunks/project-agent-NILMJHLV.js +2 -0
  63. package/dist/chunks/sandbox-command-QHH65OSE.js +2 -0
  64. package/dist/chunks/sandbox-template-N7I63PNU.js +10 -0
  65. package/dist/chunks/src-724HF43W.js +82 -0
  66. package/dist/chunks/src-VTKTTKQO.js +319 -0
  67. package/dist/chunks/taskset-PISBOILQ.js +2 -0
  68. package/dist/chunks/teams-bot-UV4RU53M.js +3 -0
  69. package/dist/chunks/training-2NDOWH5S.js +2 -0
  70. package/dist/chunks/workspaces-XXT4KUD3.js +2 -0
  71. package/dist/cli.js +3 -109
  72. package/dist/index.js +1 -31230
  73. package/dist/sandbox-template/manifest.js +1 -18380
  74. package/dist/web/assets/App-DxecRQUL.js +176 -0
  75. package/dist/web/assets/AppDialog-B65Eo3gp.js +1 -0
  76. package/dist/web/assets/AppTerminalPanel-B2EKQM7W.js +2 -0
  77. package/dist/web/assets/{AppsView-B1NUuAIf.js → AppsView-BBoVe7s2.js} +1 -1
  78. package/dist/web/assets/{BrowserSidebar-DOvYxXeP.js → BrowserSidebar-CSM1atSJ.js} +1 -1
  79. package/dist/web/assets/{CartesianChart-pOrYpzBr.js → CartesianChart-CJKfXiEG.js} +1 -1
  80. package/dist/web/assets/{CollaborationTabs-CgbR-MBJ.js → CollaborationTabs-BMZamWFC.js} +1 -1
  81. package/dist/web/assets/{CommandMenu-CrIr4qUX.js → CommandMenu-B3U1z2eo.js} +1 -1
  82. package/dist/web/assets/{CommunityView-CvAVQ_HZ.js → CommunityView-CTyRUcfy.js} +1 -1
  83. package/dist/web/assets/{ComposerCreateImproveStrip-DybcKwwd.js → ComposerCreateImproveStrip-D7usvRtK.js} +1 -1
  84. package/dist/web/assets/GetStartedView-Ibu7oKWJ.js +1 -0
  85. package/dist/web/assets/HostedModelLearningReview-qnzIkT70.js +1 -0
  86. package/dist/web/assets/HostedModelLearningSettings--PKjpYsy.js +1 -0
  87. package/dist/web/assets/LabModelVersionDetailPage-s9uUN6fV.js +1 -0
  88. package/dist/web/assets/{LabSkillSidebar-CuaYrtiu.js → LabSkillSidebar-BKYseMiJ.js} +1 -1
  89. package/dist/web/assets/LabsRoute-C1FWCoYb.css +1 -0
  90. package/dist/web/assets/LabsRoute-DoRs0K6v.js +32 -0
  91. package/dist/web/assets/MainChatThread-DvuyMcMB.js +2 -0
  92. package/dist/web/assets/MainPane-BWwcxgHD.js +8 -0
  93. package/dist/web/assets/{MarkdownText-DOlVQR8a.js → MarkdownText-D8XC5UT_.js} +1 -1
  94. package/dist/web/assets/{Messages-DMubppta.js → Messages-e4A8JUjD.js} +6 -6
  95. package/dist/web/assets/{NativeSkillSidebar-DSFwZ-od.js → NativeSkillSidebar-D2Joh8XB.js} +1 -1
  96. package/dist/web/assets/{NewExperienceSwitcher-Dj0ePIJ-.js → NewExperienceSwitcher-CzGebt2E.js} +1 -1
  97. package/dist/web/assets/{NewProjectDialog-B8NQV-Ji.js → NewProjectDialog-CdMTSxUE.js} +1 -1
  98. package/dist/web/assets/{OutputsPage-D_LDYTgV.js → OutputsPage-m7cSb8dW.js} +1 -1
  99. package/dist/web/assets/{ProjectsPage-xjDYPc_W.js → ProjectsPage-C9mz8W1g.js} +1 -1
  100. package/dist/web/assets/RightChatPanelStack-B4LEqKEj.js +1 -0
  101. package/dist/web/assets/{RightSidebarHomePanel-j0VckZUu.js → RightSidebarHomePanel-DOeUsH7h.js} +1 -1
  102. package/dist/web/assets/{ScheduledWorkPage-1aT4bBY-.js → ScheduledWorkPage-UXZSSWgA.js} +1 -1
  103. package/dist/web/assets/{SettingsView-BSpuMDpv.js → SettingsView-CQm1ai73.js} +7 -7
  104. package/dist/web/assets/TeamChatView-C4haojB7.js +3 -0
  105. package/dist/web/assets/{TerminalOverlay-CrSwUk2d.js → TerminalOverlay-p2GZsuyQ.js} +3 -3
  106. package/dist/web/assets/{TrainingCreationPanel-B4HMRwUg.js → TrainingCreationPanel-BYJSlO8X.js} +1 -1
  107. package/dist/web/assets/{TrainingDraftPanel-D4r1tN3I.js → TrainingDraftPanel-DR5KlayH.js} +1 -1
  108. package/dist/web/assets/{UsageSettingsSection-2aymqwIM.js → UsageSettingsSection-BQToNXE4.js} +5 -5
  109. package/dist/web/assets/{WorkSidebarPanel-B0X0OiR6.js → WorkSidebarPanel--EeytWeg.js} +1 -1
  110. package/dist/web/assets/WorkspaceDiffPanel-BrovSYhn.js +14 -0
  111. package/dist/web/assets/{WorkspaceEnvironmentMenu-OAfMEt7L.js → WorkspaceEnvironmentMenu-l-keRgvj.js} +3 -3
  112. package/dist/web/assets/{WorkspaceGitDialogs-YxcPH2Rq.js → WorkspaceGitDialogs-aicWzaZu.js} +1 -1
  113. package/dist/web/assets/{WorkspaceMonacoEditor-COKTiQZl.js → WorkspaceMonacoEditor-CO_E74jM.js} +36 -36
  114. package/dist/web/assets/{arrow-up-right-_TX-awvK.js → arrow-up-right-rwPXNfVn.js} +1 -1
  115. package/dist/web/assets/chat-file-links-B3jDstSC.js +1 -0
  116. package/dist/web/assets/chevron-up-D089nvYQ.js +1 -0
  117. package/dist/web/assets/{clipboard-CyRSS8Sy.js → clipboard-DwEExyU4.js} +1 -1
  118. package/dist/web/assets/{cloud-upload-uBJBUYTy.js → cloud-upload-D2he0-vQ.js} +1 -1
  119. package/dist/web/assets/{cssMode-BrXSsZYs.js → cssMode-DS4k0NcI.js} +1 -1
  120. package/dist/web/assets/{folder-open-DktdZNW7.js → folder-open-CAOLduKD.js} +1 -1
  121. package/dist/web/assets/{folder-plus-DO06i9Vo.js → folder-plus-D56MrxVT.js} +1 -1
  122. package/dist/web/assets/{git-commit-horizontal-zFSIkPs7.js → git-commit-horizontal-CeNM0oKJ.js} +1 -1
  123. package/dist/web/assets/{htmlMode-X9UMFkjt.js → htmlMode-Xkni5erh.js} +1 -1
  124. package/dist/web/assets/{index-ByQIHpc9.css → index-BGMzUaup.css} +1 -1
  125. package/dist/web/assets/{index-UOGdfLzi.js → index-KwyAyscP.js} +1 -1
  126. package/dist/web/assets/{info-BEJXUqCD.js → info-CcrBaEE_.js} +1 -1
  127. package/dist/web/assets/{jsonMode-DIsB-j2E.js → jsonMode-C4YPbQB7.js} +1 -1
  128. package/dist/web/assets/{lspLanguageFeatures-CmZ17KpA.js → lspLanguageFeatures-CF5oMTz6.js} +1 -1
  129. package/dist/web/assets/{minimize-2-DumTpFtE.js → minimize-2-DzHQnInk.js} +1 -1
  130. package/dist/web/assets/{monaco.contribution-DJ_NmcHu.js → monaco.contribution-0EN4mGCC.js} +2 -2
  131. package/dist/web/assets/{monaco.contribution-YVDfJcG4.js → monaco.contribution-B4qcTP0w.js} +2 -2
  132. package/dist/web/assets/{monaco.contribution-LZEujgny.js → monaco.contribution-CJK_NrBm.js} +2 -2
  133. package/dist/web/assets/{monaco.contribution-D6w5PJji.js → monaco.contribution-CkPGKNd-.js} +2 -2
  134. package/dist/web/assets/{play-CLFeH7CU.js → play-p3-AMTPL.js} +1 -1
  135. package/dist/web/assets/{python-Djbda_qZ.js → python-B0kpTxAZ.js} +1 -1
  136. package/dist/web/assets/{refresh-cw-B4IpQ_7Q.js → refresh-cw-_jbTIzzr.js} +1 -1
  137. package/dist/web/assets/{save-BbTHztnA.js → save-Cy6hEotx.js} +1 -1
  138. package/dist/web/assets/{square-BJrVbmz6.js → square-DKQkcrOH.js} +1 -1
  139. package/dist/web/assets/{toggleHighContrast-BopU5W9S.js → toggleHighContrast-Bnk1VVVq.js} +1 -1
  140. package/dist/web/assets/{tsMode-CH_0_YDX.js → tsMode-BDrSVy7V.js} +1 -1
  141. package/dist/web/assets/{upload-UumVeufu.js → upload-COn0my_O.js} +1 -1
  142. package/dist/web/assets/{useLocalAgentSchedules-BRa23U7O.js → useLocalAgentSchedules-iZNB4Oee.js} +1 -1
  143. package/dist/web/assets/{wifi-off-BWJWivn6.js → wifi-off-Cqt-ZLXY.js} +1 -1
  144. package/dist/web/assets/{workers-pTe8RvSI.js → workers-hu0Ym93h.js} +1 -1
  145. package/dist/web/assets/{yaml-DNLASORn.js → yaml-D-JLDGL6.js} +1 -1
  146. package/dist/web/index.html +2 -2
  147. package/package.json +4 -3
  148. package/dist/chunks/actions-command-6N5XWMR6.js +0 -185
  149. package/dist/chunks/app-layer-F3CGXB33.js +0 -216
  150. package/dist/chunks/app-server-runtime-RHO5TFUC.js +0 -23
  151. package/dist/chunks/apps-L5XCL7QY.js +0 -429
  152. package/dist/chunks/chunk-26AMV5ZI.js +0 -634
  153. package/dist/chunks/chunk-3EB7I67T.js +0 -630
  154. package/dist/chunks/chunk-3ELF4FXY.js +0 -96
  155. package/dist/chunks/chunk-3VEYNDHN.js +0 -669
  156. package/dist/chunks/chunk-4KA25HUP.js +0 -5648
  157. package/dist/chunks/chunk-4L3ZJS2T.js +0 -1207
  158. package/dist/chunks/chunk-6SMNG6YA.js +0 -1303
  159. package/dist/chunks/chunk-7RIGZB7N.js +0 -1148
  160. package/dist/chunks/chunk-A6G3PFA5.js +0 -2164
  161. package/dist/chunks/chunk-BVY5JYM6.js +0 -512
  162. package/dist/chunks/chunk-DLQQIWN2.js +0 -648
  163. package/dist/chunks/chunk-FJ2JGB2N.js +0 -1373
  164. package/dist/chunks/chunk-FQS2QL5F.js +0 -14522
  165. package/dist/chunks/chunk-G65WAOJV.js +0 -1643
  166. package/dist/chunks/chunk-JTHL5XJ2.js +0 -1838
  167. package/dist/chunks/chunk-K4TZEHAW.js +0 -602
  168. package/dist/chunks/chunk-KCRCIQPD.js +0 -66
  169. package/dist/chunks/chunk-KSRWKXRB.js +0 -12
  170. package/dist/chunks/chunk-MUMPWI4O.js +0 -92
  171. package/dist/chunks/chunk-NTK22KJD.js +0 -10707
  172. package/dist/chunks/chunk-OCBRPU2K.js +0 -629
  173. package/dist/chunks/chunk-PS37DB5F.js +0 -183
  174. package/dist/chunks/chunk-R3C3MNSI.js +0 -140
  175. package/dist/chunks/chunk-SMNFI2FU.js +0 -113
  176. package/dist/chunks/chunk-UACZUFIA.js +0 -47
  177. package/dist/chunks/chunk-UZMVNKXM.js +0 -1275
  178. package/dist/chunks/chunk-VT6BLHMB.js +0 -67198
  179. package/dist/chunks/chunk-W5GKHH77.js +0 -168
  180. package/dist/chunks/chunk-X6F4LBTQ.js +0 -832
  181. package/dist/chunks/chunk-X7ZG4TSW.js +0 -3063
  182. package/dist/chunks/chunk-XA4KBDMY.js +0 -13723
  183. package/dist/chunks/chunk-YVCYVDNP.js +0 -746
  184. package/dist/chunks/chunk-ZNQEROWP.js +0 -254
  185. package/dist/chunks/cli-D2MUUBEX.js +0 -23
  186. package/dist/chunks/configuration-command-NR6JYIUD.js +0 -187
  187. package/dist/chunks/continual-37CE4LLJ.js +0 -803
  188. package/dist/chunks/core-commands-SWGIOZLW.js +0 -50
  189. package/dist/chunks/database-DEYUZDIM.js +0 -20
  190. package/dist/chunks/desktop-test-QOS7G5NE.js +0 -148
  191. package/dist/chunks/dist-AKYCQNNF.js +0 -187
  192. package/dist/chunks/extension-HJUJBQAD.js +0 -9378
  193. package/dist/chunks/help-J6PZ23IC.js +0 -67
  194. package/dist/chunks/opchat-ABX5YBAT.js +0 -169
  195. package/dist/chunks/organizations-CPNC47DO.js +0 -806
  196. package/dist/chunks/profile-Q3HB5MIO.js +0 -1136
  197. package/dist/chunks/project-agent-YHUBX4OR.js +0 -516
  198. package/dist/chunks/sandbox-command-YFL5QTWX.js +0 -1661
  199. package/dist/chunks/sandbox-template-Z6P7NTNF.js +0 -1655
  200. package/dist/chunks/src-7XEENEBI.js +0 -3628
  201. package/dist/chunks/src-KBBIV4NT.js +0 -56125
  202. package/dist/chunks/taskset-2TRZBRRT.js +0 -66
  203. package/dist/chunks/teams-bot-WD33NLH5.js +0 -146
  204. package/dist/chunks/training-4XH37UZB.js +0 -17
  205. package/dist/chunks/workspaces-WG2MH2WE.js +0 -99
  206. package/dist/web/assets/App-C9aGkxVg.js +0 -173
  207. package/dist/web/assets/AppDialog-CK6_lg8c.js +0 -1
  208. package/dist/web/assets/AppTerminalPanel-BKqgX4sd.js +0 -2
  209. package/dist/web/assets/GetStartedView-DVInkexN.js +0 -1
  210. package/dist/web/assets/LabModelVersionDetailPage-NaaPElmM.js +0 -1
  211. package/dist/web/assets/LabsRoute-BRR6x3SX.js +0 -2
  212. package/dist/web/assets/LabsRoute-CGFgymTX.css +0 -1
  213. package/dist/web/assets/MainChatThread-BfkjCZB9.js +0 -2
  214. package/dist/web/assets/MainPane-Gw-YK38n.js +0 -8
  215. package/dist/web/assets/RightChatPanelStack-BktRQ9wg.js +0 -1
  216. package/dist/web/assets/TeamChatView-BPWJbDf1.js +0 -3
  217. package/dist/web/assets/WorkspaceDiffPanel-Pg7GL0br.js +0 -14
  218. package/dist/web/assets/chat-file-links-CWLsRYvW.js +0 -1
  219. package/dist/web/assets/chevron-up--mNnEqha.js +0 -1
  220. package/dist/web/assets/index-BEPmTPIA.js +0 -1
@@ -1,2164 +0,0 @@
1
- import { createRequire as __openpondCreateRequire } from "node:module"; var require = __openpondCreateRequire(import.meta.url);
2
- import {
3
- SOURCE_UPLOAD_CACHE_PATH,
4
- materializeSourceUploadFile,
5
- readSourceUploadCache,
6
- writeSourceUploadCache
7
- } from "./chunk-3ELF4FXY.js";
8
- import {
9
- yaml
10
- } from "./chunk-X7ZG4TSW.js";
11
- import {
12
- loadGlobalConfig,
13
- saveGlobalConfig
14
- } from "./chunk-FJ2JGB2N.js";
15
- import {
16
- resolveOpenPondHome
17
- } from "./chunk-ZNQEROWP.js";
18
-
19
- // ../../packages/cloud/src/profile/profile-setup-gate.ts
20
- var OpenPondProfileSetupRequiredError = class extends Error {
21
- code = "agent_source_setup_required";
22
- details;
23
- constructor(actionId, setupGate) {
24
- const labels = setupGate.blockingRequirements.map((requirement) => requirement.label);
25
- super(
26
- [
27
- "agent_source_setup_required",
28
- `Profile action ${actionId} has unresolved required setup.`,
29
- labels.length ? `Missing setup: ${labels.join(", ")}` : ""
30
- ].filter(Boolean).join("\n")
31
- );
32
- this.name = "OpenPondProfileSetupRequiredError";
33
- this.details = {
34
- error: "agent_source_setup_required",
35
- actionId,
36
- setupGate,
37
- missing: labels,
38
- blockingSetupRequirements: setupGate.blockingRequirements,
39
- setupRequirements: setupGate.requirements
40
- };
41
- }
42
- };
43
- function buildOpenPondProfileSetupGate(input) {
44
- const requirements = /* @__PURE__ */ new Map();
45
- for (const record2 of input.sourceSetupRequirements ?? []) {
46
- const sourceActionId = setupRequirementActionId(record2);
47
- if (input.actionId && sourceActionId && sourceActionId !== input.actionId && text(record2.actionName) !== input.actionId && text(record2.sourceActionId) !== input.actionId) {
48
- continue;
49
- }
50
- const requirement = setupRequirementFromRecord({
51
- record: record2,
52
- source: "source_upload_metadata",
53
- actionId: sourceActionId
54
- });
55
- if (requirement) requirements.set(requirement.ref, requirement);
56
- }
57
- for (const action of input.actionCatalog) {
58
- if (input.actionId && action.id !== input.actionId && action.name !== input.actionId) {
59
- continue;
60
- }
61
- for (const record2 of action.setupRequirements ?? []) {
62
- const requirement = setupRequirementFromRecord({
63
- record: record2,
64
- source: "action_catalog",
65
- actionId: action.id
66
- });
67
- if (requirement) requirements.set(requirement.ref, requirement);
68
- }
69
- }
70
- const allRequirements = Array.from(requirements.values());
71
- const blockingRequirements = allRequirements.filter((requirement) => requirement.blocking);
72
- const optionalMissingCount = allRequirements.filter(
73
- (requirement) => !requirement.required && !isReadyStatus(requirement.status)
74
- ).length;
75
- const readyCount = allRequirements.filter((requirement) => isReadyStatus(requirement.status)).length;
76
- return {
77
- status: gateStatus(blockingRequirements),
78
- requirementCount: allRequirements.length,
79
- blockingCount: blockingRequirements.length,
80
- optionalMissingCount,
81
- readyCount,
82
- requirements: allRequirements,
83
- blockingRequirements
84
- };
85
- }
86
- function assertOpenPondProfileActionReady(actionId, setupGate) {
87
- if (setupGate.blockingRequirements.length > 0) {
88
- throw new OpenPondProfileSetupRequiredError(actionId, setupGate);
89
- }
90
- }
91
- function formatOpenPondProfileSetupRequirement(requirement) {
92
- const prefix = requirement.actionId ? `${requirement.actionId}: ` : "";
93
- const required = requirement.required ? "required" : "optional";
94
- return `${prefix}${requirement.label} (${required}, ${requirement.status})`;
95
- }
96
- function setupRequirementFromRecord(input) {
97
- const source = input.source === "action_catalog" && text(input.record.source) === "source_upload_metadata" ? "source_upload_metadata" : input.source;
98
- const kind = text(input.record.kind) ?? text(input.record.type);
99
- const label = text(input.record.label) ?? text(input.record.name) ?? text(input.record.key) ?? text(input.record.provider) ?? text(input.record.tool) ?? text(input.record.command) ?? text(input.record.packageName) ?? text(input.record.path) ?? text(input.record.repo) ?? text(input.record.url) ?? text(input.record.id) ?? kind ?? "setup requirement";
100
- const required = input.record.required !== false;
101
- const status = setupStatus(input.record);
102
- const ref = [
103
- source,
104
- input.actionId ?? "source",
105
- kind ?? "requirement",
106
- label
107
- ].join(":");
108
- return {
109
- ref,
110
- source,
111
- actionId: input.actionId,
112
- kind,
113
- label,
114
- status,
115
- required,
116
- blocking: required && !isReadyStatus(status)
117
- };
118
- }
119
- function setupRequirementActionId(record2) {
120
- return text(record2.actionId) ?? text(record2.sourceActionId) ?? text(record2.actionName);
121
- }
122
- function setupStatus(record2) {
123
- const explicit = text(record2.status) ?? text(record2.state);
124
- if (explicit) {
125
- if (explicit === "satisfied" || explicit === "connected" || explicit === "provided") {
126
- return "ready";
127
- }
128
- return explicit;
129
- }
130
- if (typeof record2.satisfied === "boolean") {
131
- return record2.satisfied ? "ready" : "setup_required";
132
- }
133
- if (typeof record2.ready === "boolean") {
134
- return record2.ready ? "ready" : "setup_required";
135
- }
136
- return "setup_required";
137
- }
138
- function gateStatus(blockingRequirements) {
139
- if (blockingRequirements.length === 0) return "ready";
140
- return blockingRequirements.some(
141
- (requirement) => ["blocked", "unsupported", "unsupported_dependency", "stale"].includes(requirement.status)
142
- ) ? "blocked" : "setup_required";
143
- }
144
- function isReadyStatus(status) {
145
- return status === "ready" || status === "disabled";
146
- }
147
- function text(value) {
148
- return typeof value === "string" && value.trim() ? value.trim() : null;
149
- }
150
-
151
- // ../../packages/cloud/src/profile/profile-source-upload.ts
152
- import { stat } from "node:fs/promises";
153
- import path2 from "node:path";
154
-
155
- // ../../packages/cloud/src/profile/profile-git.ts
156
- import { spawn } from "node:child_process";
157
- import { existsSync } from "node:fs";
158
- import { readFile, rm, writeFile } from "node:fs/promises";
159
- import path from "node:path";
160
- var PROFILE_REPO_GITIGNORE = [
161
- "**/node_modules/",
162
- "**/.bun/",
163
- "**/.env",
164
- "**/.env.*",
165
- "**/.openpond/traces/",
166
- "**/.openpond/vendor/",
167
- "**/.openpond/eval-results.json",
168
- "**/.openpond/artifact-index.json",
169
- "**/.openpond/source-upload-cache.json",
170
- ""
171
- ].join("\n");
172
- async function ensureProfileGitRepo(repoPath) {
173
- if (!existsSync(path.join(repoPath, ".git"))) {
174
- const init = await runGitCommand(repoPath, ["init", "-b", "main"]);
175
- if (init.code !== 0) {
176
- throw new Error(gitFailureMessage("git init", init));
177
- }
178
- }
179
- const gitignorePath = path.join(repoPath, ".gitignore");
180
- if (!existsSync(gitignorePath)) {
181
- await writeFile(gitignorePath, PROFILE_REPO_GITIGNORE, "utf8");
182
- } else {
183
- await ensureProfileGitignoreRules(gitignorePath);
184
- }
185
- if (await hasGitHead(repoPath)) return;
186
- const state = await loadProfileGitState(repoPath);
187
- if (!state.dirty && state.files.length === 0) return;
188
- const add = await runGitCommand(repoPath, ["add", "-A"]);
189
- if (add.code !== 0) {
190
- throw new Error(gitFailureMessage("git add", add));
191
- }
192
- const commit = await runGitCommand(repoPath, ["commit", "-m", "Initialize OpenPond profile"], {
193
- env: {
194
- ...process.env,
195
- GIT_AUTHOR_NAME: process.env.GIT_AUTHOR_NAME || "OpenPond",
196
- GIT_AUTHOR_EMAIL: process.env.GIT_AUTHOR_EMAIL || "openpond@example.invalid",
197
- GIT_COMMITTER_NAME: process.env.GIT_COMMITTER_NAME || "OpenPond",
198
- GIT_COMMITTER_EMAIL: process.env.GIT_COMMITTER_EMAIL || "openpond@example.invalid"
199
- }
200
- });
201
- if (commit.code !== 0 && !/nothing to commit/i.test(commit.stdout + commit.stderr)) {
202
- throw new Error(gitFailureMessage("git commit", commit));
203
- }
204
- }
205
- async function ensureProfileGitignoreRules(gitignorePath) {
206
- const current = await readFile(gitignorePath, "utf8").catch(() => "");
207
- const missing = PROFILE_REPO_GITIGNORE.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).filter((line) => !current.split(/\r?\n/).some((existing) => existing.trim() === line));
208
- if (missing.length === 0) return;
209
- const suffix = current.endsWith("\n") || current.length === 0 ? "" : "\n";
210
- await writeFile(gitignorePath, `${current}${suffix}${missing.join("\n")}
211
- `, "utf8");
212
- }
213
- async function loadProfileGitState(repoPath) {
214
- if (!existsSync(path.join(repoPath, ".git"))) {
215
- return {
216
- isRepo: false,
217
- branch: null,
218
- head: null,
219
- shortHead: null,
220
- dirty: false,
221
- upstream: null,
222
- ahead: null,
223
- behind: null,
224
- remoteUrl: null,
225
- files: [],
226
- error: null
227
- };
228
- }
229
- const inside = await runGitCommand(repoPath, ["rev-parse", "--is-inside-work-tree"]);
230
- if (inside.code !== 0 || inside.stdout.trim() !== "true") {
231
- return {
232
- isRepo: false,
233
- branch: null,
234
- head: null,
235
- shortHead: null,
236
- dirty: false,
237
- upstream: null,
238
- ahead: null,
239
- behind: null,
240
- remoteUrl: null,
241
- files: [],
242
- error: inside.stderr.trim() || inside.stdout.trim() || "not a Git work tree"
243
- };
244
- }
245
- const [branch, head, status, upstream, remoteUrl] = await Promise.all([
246
- gitText(repoPath, ["branch", "--show-current"]),
247
- gitText(repoPath, ["rev-parse", "HEAD"]),
248
- runGitCommand(repoPath, ["status", "--porcelain=v1", "-uall"]),
249
- gitText(repoPath, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}"]),
250
- gitText(repoPath, ["remote", "get-url", "origin"])
251
- ]);
252
- const files = status.code === 0 ? parsePorcelainStatus(status.stdout) : [];
253
- const aheadBehind = upstream ? await loadAheadBehind(repoPath) : { ahead: null, behind: null };
254
- const resolvedHead = head || null;
255
- return {
256
- isRepo: true,
257
- branch: branch || null,
258
- head: resolvedHead,
259
- shortHead: resolvedHead ? resolvedHead.slice(0, 12) : null,
260
- dirty: files.length > 0,
261
- upstream,
262
- ahead: aheadBehind.ahead,
263
- behind: aheadBehind.behind,
264
- remoteUrl,
265
- files,
266
- error: status.code === 0 ? null : gitFailureMessage("git status", status)
267
- };
268
- }
269
- async function commitProfileChanges(repoPath, message) {
270
- const before = await loadProfileGitState(repoPath);
271
- if (!before.isRepo) {
272
- throw new Error(before.error ?? "Active OpenPond profile source is not a Git repo.");
273
- }
274
- if (!before.dirty) {
275
- return {
276
- committed: false,
277
- stdout: "",
278
- stderr: "",
279
- state: before
280
- };
281
- }
282
- const add = await runGitCommand(repoPath, ["add", "-A"]);
283
- if (add.code !== 0) {
284
- throw new Error(gitFailureMessage("git add", add));
285
- }
286
- const commit = await runGitCommand(repoPath, ["commit", "-m", message]);
287
- if (commit.code !== 0) {
288
- throw new Error(gitFailureMessage("git commit", commit));
289
- }
290
- return {
291
- committed: true,
292
- stdout: commit.stdout,
293
- stderr: commit.stderr,
294
- state: await loadProfileGitState(repoPath)
295
- };
296
- }
297
- async function profileGitHead(repoPath) {
298
- return gitText(repoPath, ["rev-parse", "HEAD"]);
299
- }
300
- async function hasGitHead(repoPath) {
301
- const result = await runGitCommand(repoPath, ["rev-parse", "--verify", "HEAD"]);
302
- return result.code === 0;
303
- }
304
- async function loadAheadBehind(repoPath) {
305
- const result = await runGitCommand(repoPath, ["rev-list", "--left-right", "--count", "@{u}...HEAD"]);
306
- if (result.code !== 0) return { ahead: null, behind: null };
307
- const [behindRaw, aheadRaw] = result.stdout.trim().split(/\s+/);
308
- const behind = behindRaw ? Number.parseInt(behindRaw, 10) : Number.NaN;
309
- const ahead = aheadRaw ? Number.parseInt(aheadRaw, 10) : Number.NaN;
310
- return {
311
- ahead: Number.isFinite(ahead) ? ahead : null,
312
- behind: Number.isFinite(behind) ? behind : null
313
- };
314
- }
315
- async function gitText(repoPath, args) {
316
- const result = await runGitCommand(repoPath, args);
317
- if (result.code !== 0) return null;
318
- const text5 = result.stdout.trim();
319
- return text5 || null;
320
- }
321
- function parsePorcelainStatus(output) {
322
- return output.split(/\r?\n/).map((line) => line.trimEnd()).filter(Boolean).map((line) => {
323
- const rawIndex = line[0] ?? " ";
324
- const rawWorktree = line[1] ?? " ";
325
- const status = `${rawIndex}${rawWorktree}`.trim() || "changed";
326
- const rawPath = line.slice(3);
327
- const renameParts = rawPath.split(" -> ");
328
- const indexStatus = rawIndex === " " ? null : rawIndex;
329
- const worktreeStatus = rawWorktree === " " ? null : rawWorktree;
330
- const pathValue = renameParts.length === 2 ? renameParts[1] : rawPath;
331
- const originalPath = renameParts.length === 2 ? renameParts[0] : null;
332
- return {
333
- path: unquoteGitPath(pathValue),
334
- originalPath: originalPath ? unquoteGitPath(originalPath) : null,
335
- indexStatus,
336
- worktreeStatus,
337
- status,
338
- category: gitChangeCategory(indexStatus, worktreeStatus)
339
- };
340
- });
341
- }
342
- function gitChangeCategory(indexStatus, worktreeStatus) {
343
- if (indexStatus === "?" && worktreeStatus === "?") return "untracked";
344
- if (indexStatus === "R" || worktreeStatus === "R") return "renamed";
345
- if (indexStatus === "A" || worktreeStatus === "A") return "added";
346
- if (indexStatus === "D" || worktreeStatus === "D") return "deleted";
347
- if (indexStatus === "M" || worktreeStatus === "M") return "modified";
348
- return "changed";
349
- }
350
- function unquoteGitPath(value) {
351
- const trimmed = value.trim();
352
- if (!trimmed.startsWith('"') || !trimmed.endsWith('"')) return trimmed;
353
- try {
354
- return JSON.parse(trimmed);
355
- } catch {
356
- return trimmed.slice(1, -1);
357
- }
358
- }
359
- function gitFailureMessage(label, result) {
360
- const detail = result.stderr.trim() || result.stdout.trim();
361
- return detail || `${label} failed with exit code ${result.code ?? "unknown"}`;
362
- }
363
- async function runGitCommand(repoPath, args, options = {}) {
364
- return new Promise((resolve, reject) => {
365
- const proc = spawn("git", args, {
366
- cwd: repoPath,
367
- env: options.env,
368
- stdio: "pipe"
369
- });
370
- let stdout = "";
371
- let stderr = "";
372
- proc.stdout?.on("data", (chunk) => {
373
- stdout += String(chunk);
374
- });
375
- proc.stderr?.on("data", (chunk) => {
376
- stderr += String(chunk);
377
- });
378
- proc.on("error", reject);
379
- proc.on("close", (code) => {
380
- resolve({ code, stdout, stderr });
381
- });
382
- if (options.input !== void 0) proc.stdin?.end(options.input);
383
- else proc.stdin?.end();
384
- });
385
- }
386
-
387
- // ../../packages/cloud/src/profile/profile-source-upload.ts
388
- var PROFILE_SOURCE_UPLOAD_MAX_FILES = 1500;
389
- var PROFILE_SOURCE_UPLOAD_MAX_FILE_BYTES = 8 * 1024 * 1024;
390
- var PROFILE_SOURCE_UPLOAD_MAX_BYTES = 100 * 1024 * 1024;
391
- var PROFILE_SOURCE_UPLOAD_CONCURRENCY = 8;
392
- var PROFILE_SOURCE_UPLOAD_LIMITS = {
393
- maxFiles: PROFILE_SOURCE_UPLOAD_MAX_FILES,
394
- maxFileBytes: PROFILE_SOURCE_UPLOAD_MAX_FILE_BYTES,
395
- maxTotalBytes: PROFILE_SOURCE_UPLOAD_MAX_BYTES,
396
- concurrency: PROFILE_SOURCE_UPLOAD_CONCURRENCY
397
- };
398
- var PROFILE_SOURCE_UPLOAD_TRANSPORT = {
399
- mode: "single_json_payload",
400
- chunkingSupported: false
401
- };
402
- async function collectProfileSourceUploadEntries(repoPath) {
403
- const files = await runGitCommand(repoPath, ["ls-files", "-z"]);
404
- if (files.code !== 0) {
405
- throw new Error(files.stderr.trim() || files.stdout.trim() || "git ls-files failed for profile source upload");
406
- }
407
- const sourcePaths = files.stdout.split("\0").map((filePath) => filePath.trim()).filter(Boolean).filter((filePath) => {
408
- const normalized = filePath.replace(/\\/g, "/");
409
- return isSafeProfileSourcePath(normalized) && !shouldSkipProfileSourcePath(normalized);
410
- }).sort();
411
- if (sourcePaths.length === 0) {
412
- throw new Error("No committed profile source files found to upload.");
413
- }
414
- if (sourcePaths.length > PROFILE_SOURCE_UPLOAD_MAX_FILES) {
415
- throw new Error(`Too many profile source files to upload: ${sourcePaths.length} > ${PROFILE_SOURCE_UPLOAD_MAX_FILES}`);
416
- }
417
- const filesToUpload = (await mapWithConcurrency(sourcePaths, PROFILE_SOURCE_UPLOAD_CONCURRENCY, async (sourcePath) => {
418
- const absolutePath = path2.resolve(repoPath, sourcePath);
419
- const relative = path2.relative(repoPath, absolutePath).replace(/\\/g, "/");
420
- if (!isSafeProfileSourcePath(relative)) {
421
- throw new Error(`Profile source path escapes repo: ${sourcePath}`);
422
- }
423
- const fileStat = await stat(absolutePath);
424
- if (!fileStat.isFile()) return null;
425
- if (fileStat.size > PROFILE_SOURCE_UPLOAD_MAX_FILE_BYTES) {
426
- throw new Error(`Profile source file is too large: ${sourcePath} (${fileStat.size} bytes)`);
427
- }
428
- return {
429
- path: relative,
430
- absolutePath,
431
- size: fileStat.size,
432
- mtimeMs: Math.trunc(fileStat.mtimeMs),
433
- ctimeMs: Math.trunc(fileStat.ctimeMs)
434
- };
435
- })).filter((file) => file !== null);
436
- let totalBytes = 0;
437
- for (const file of filesToUpload) {
438
- totalBytes += file.size;
439
- if (totalBytes > PROFILE_SOURCE_UPLOAD_MAX_BYTES) {
440
- throw new Error(`Profile source upload is too large: ${totalBytes} > ${PROFILE_SOURCE_UPLOAD_MAX_BYTES}`);
441
- }
442
- }
443
- const cache = await readSourceUploadCache(repoPath);
444
- const materialized = await mapWithConcurrency(
445
- filesToUpload,
446
- PROFILE_SOURCE_UPLOAD_CONCURRENCY,
447
- async (file) => materializeSourceUploadFile(file, cache)
448
- );
449
- await writeSourceUploadCache(repoPath, materialized).catch(() => {
450
- });
451
- const entries = materialized.map((item) => item.entry);
452
- return {
453
- entries,
454
- fileCount: entries.length,
455
- totalBytes,
456
- limits: PROFILE_SOURCE_UPLOAD_LIMITS,
457
- transport: PROFILE_SOURCE_UPLOAD_TRANSPORT
458
- };
459
- }
460
- async function mapWithConcurrency(items, concurrency, mapper) {
461
- const results = new Array(items.length);
462
- let nextIndex = 0;
463
- const workerCount = Math.max(1, Math.min(concurrency, items.length));
464
- await Promise.all(
465
- Array.from({ length: workerCount }, async () => {
466
- while (nextIndex < items.length) {
467
- const index = nextIndex;
468
- nextIndex += 1;
469
- results[index] = await mapper(items[index], index);
470
- }
471
- })
472
- );
473
- return results;
474
- }
475
- function isSafeProfileSourcePath(filePath) {
476
- return filePath.length > 0 && !filePath.includes("\0") && !path2.isAbsolute(filePath) && !filePath.split(/[\\/]+/).some((part) => !part || part === "." || part === "..");
477
- }
478
- function shouldSkipProfileSourcePath(filePath) {
479
- return filePath.split(/[\\/]+/).some((segment, index, segments) => {
480
- const lower = segment.toLowerCase();
481
- if (lower === ".git" || lower === "node_modules" || lower === ".bun") return true;
482
- if (lower === ".env" || lower.startsWith(".env.")) return true;
483
- if (filePath.replace(/\\/g, "/") === SOURCE_UPLOAD_CACHE_PATH) return true;
484
- if (lower !== ".openpond") return false;
485
- const nested = segments[index + 1]?.toLowerCase();
486
- return nested === "goals" || nested === "traces" || nested === "vendor" || nested === "eval-results.json" || nested === "artifact-index.json";
487
- });
488
- }
489
-
490
- // ../../packages/cloud/src/profile/profile-promotion.ts
491
- function hostedSourceCheckStatusFromPayload(input) {
492
- const checkResult = record(input.checkResult);
493
- const deployPlan = record(checkResult?.deployPlan) ?? record(input.deployPlan);
494
- const source = record(deployPlan?.source);
495
- const checks = record(deployPlan?.checks);
496
- const sourceCheckStatus = record(checkResult?.sourceCheckStatus);
497
- return {
498
- status: input.status,
499
- agentId: input.agentId,
500
- deployPlanStatus: text2(deployPlan?.status),
501
- canRun: booleanValue(deployPlan?.canRun),
502
- canDeploy: booleanValue(deployPlan?.canDeploy),
503
- sourceRef: text2(source?.sourceRef),
504
- sourceCommitSha: text2(source?.sourceCommitSha),
505
- manifestHash: text2(source?.manifestHash),
506
- manifestPath: text2(source?.manifestPath),
507
- setupCommands: textArray(checks?.setupCommands),
508
- validationCommands: textArray(checks?.validationCommands),
509
- requiredChecks: textArray(checks?.requiredChecks),
510
- evalNames: textArray(checks?.evalNames),
511
- blockedReasons: textArray(deployPlan?.blockedReasons),
512
- staleReasons: textArray(deployPlan?.staleReasons),
513
- runtimeId: text2(sourceCheckStatus?.latestRuntimeId),
514
- sandboxId: text2(sourceCheckStatus?.latestSandboxId),
515
- traceArtifactRefs: textArray(sourceCheckStatus?.traceArtifactRefs),
516
- evalResultArtifactRefs: textArray(sourceCheckStatus?.evalResultArtifactRefs),
517
- validatorArtifactRefs: textArray(sourceCheckStatus?.validatorArtifactRefs),
518
- checkedAt: input.checkedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
519
- error: input.error ?? null
520
- };
521
- }
522
- function hostedPublishStatusFromPayload(input) {
523
- const result = record(input.publishResult);
524
- const snapshot = record(result?.activeManifestSnapshot) ?? record(result?.manifestSnapshot) ?? record(result?.snapshot);
525
- return {
526
- status: input.status ?? "published",
527
- agentId: input.agentId,
528
- snapshotId: text2(snapshot?.id),
529
- sourceRef: text2(snapshot?.sourceRef),
530
- sourceCommitSha: text2(snapshot?.sourceCommitSha),
531
- manifestHash: text2(snapshot?.manifestHash),
532
- manifestPath: text2(snapshot?.manifestPath),
533
- buildStatus: text2(snapshot?.buildStatus),
534
- validationStatus: text2(snapshot?.validationStatus),
535
- evalStatus: text2(snapshot?.evalStatus),
536
- publishedAt: text2(result?.publishedAt) ?? text2(snapshot?.publishedAt),
537
- error: input.error ?? null
538
- };
539
- }
540
- function hostedRunSummaryFromPayload(input) {
541
- const result = record(input.runResult);
542
- const run = record(result?.run);
543
- const runtimeSource = record(run?.runtimeSource);
544
- const metadata = record(run?.metadata);
545
- const sourceSummary = record(metadata?.sourceSummary);
546
- const setupGate = record(metadata?.setupGate);
547
- const responseSummary = record(metadata?.responseSummary);
548
- const traceSummary = record(metadata?.traceSummary);
549
- const evalSummary = record(metadata?.evalSummary);
550
- return {
551
- status: text2(run?.status) ?? (input.error ? "failed" : "running"),
552
- agentId: text2(run?.agentId) ?? input.agentId,
553
- runId: text2(run?.id),
554
- runtimeId: text2(run?.runtimeId),
555
- sandboxId: text2(run?.sandboxId),
556
- sourceRef: text2(runtimeSource?.sourceRef) ?? text2(sourceSummary?.sourceRef) ?? text2(metadata?.sourceRef),
557
- sourceCommitSha: text2(runtimeSource?.sourceCommitSha) ?? text2(sourceSummary?.sourceCommitSha) ?? text2(metadata?.hostedHead),
558
- manifestHash: text2(runtimeSource?.manifestHash) ?? text2(sourceSummary?.manifestHash),
559
- setupGateStatus: text2(setupGate?.status),
560
- setupRequirementRefs: setupRequirementRefs(setupGate),
561
- artifactRefs: textArray(responseSummary?.artifactRefs),
562
- traceArtifactRefs: textArray(traceSummary?.artifactRefs),
563
- evalArtifactRefs: textArray(evalSummary?.artifactRefs),
564
- startedAt: text2(run?.createdAt),
565
- completedAt: text2(run?.completedAt),
566
- error: input.error ?? null
567
- };
568
- }
569
- function hostedRunStatusFromRunSummary(summary) {
570
- if (!summary?.status) return "not_started";
571
- if (summary.status === "succeeded" || summary.status === "passed") return "passed";
572
- if (summary.status === "failed" || summary.status === "cancelled") return "failed";
573
- return "running";
574
- }
575
- function setupRequirementRefs(setupGate) {
576
- if (!setupGate) return [];
577
- const requirements = Array.isArray(setupGate.requirements) ? setupGate.requirements : Array.isArray(setupGate.blockingRequirements) ? setupGate.blockingRequirements : [];
578
- return requirements.map((item) => {
579
- const requirement = record(item);
580
- return text2(requirement?.ref) ?? text2(requirement?.id) ?? text2(requirement?.label);
581
- }).filter((item) => Boolean(item));
582
- }
583
- function record(value) {
584
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
585
- }
586
- function text2(value) {
587
- return typeof value === "string" && value.trim() ? value.trim() : null;
588
- }
589
- function booleanValue(value) {
590
- return typeof value === "boolean" ? value : null;
591
- }
592
- function textArray(value) {
593
- return Array.isArray(value) ? value.filter((item) => typeof item === "string" && item.trim().length > 0) : [];
594
- }
595
-
596
- // ../../packages/cloud/src/profile/local-profile.ts
597
- import { createRequire } from "node:module";
598
- import { spawn as spawn2 } from "node:child_process";
599
- import { existsSync as existsSync4 } from "node:fs";
600
- import {
601
- cp,
602
- mkdir,
603
- readFile as readFile4,
604
- readdir as readdir2,
605
- rename,
606
- rm as rm2,
607
- symlink,
608
- writeFile as writeFile2
609
- } from "node:fs/promises";
610
- import path5 from "node:path";
611
-
612
- // ../../packages/cloud/src/profile/local-profile-types.ts
613
- function emptyProfileCatalogState(error = null) {
614
- return {
615
- actionCount: 0,
616
- generatedAt: null,
617
- manifestPath: null,
618
- registryPath: null,
619
- stale: true,
620
- error
621
- };
622
- }
623
- function emptyProfileSkillCatalogState(error = null) {
624
- return {
625
- skillCount: 0,
626
- generatedAt: null,
627
- stale: true,
628
- error
629
- };
630
- }
631
- function emptyProfileSetupGate() {
632
- return {
633
- status: "ready",
634
- requirementCount: 0,
635
- blockingCount: 0,
636
- optionalMissingCount: 0,
637
- readyCount: 0,
638
- requirements: [],
639
- blockingRequirements: []
640
- };
641
- }
642
- function emptyProfileDiffSummary() {
643
- return {
644
- changedAgents: [],
645
- newAgents: [],
646
- deletedAgents: [],
647
- changedSkills: [],
648
- changedActions: [],
649
- changedExtensions: [],
650
- setupChanges: [],
651
- envRequirementChanges: [],
652
- files: []
653
- };
654
- }
655
- function emptyProfileSummary(error = null) {
656
- return {
657
- state: error ? "error" : "none",
658
- message: error ?? "No active OpenPond profile.",
659
- agentCount: 0,
660
- actionCount: 0,
661
- defaultAction: null,
662
- checkFresh: false,
663
- checkStaleReason: error ?? "No active profile.",
664
- localHead: null,
665
- hostedHead: null
666
- };
667
- }
668
-
669
- // ../../packages/cloud/src/profile/profile-catalog.ts
670
- import { existsSync as existsSync2 } from "node:fs";
671
- import { readFile as readFile2, stat as stat2 } from "node:fs/promises";
672
- import path3 from "node:path";
673
- var AGENT_MANIFEST_PATH = ".openpond/agent-manifest.json";
674
- var ACTION_REGISTRY_PATH = ".openpond/action-registry.json";
675
- var SOURCE_UPLOAD_METADATA_PATH = ".openpond/source-upload-metadata.json";
676
- var AGENT_PACKAGE_ORIGIN_PATH = ".openpond/agent-package-origin.json";
677
- async function loadProfileActionCatalog(sourcePath) {
678
- return loadProfileActionCatalogSource({
679
- agentId: "default",
680
- sourcePath,
681
- preferred: true
682
- });
683
- }
684
- async function loadProfileActionCatalogForSources(sources) {
685
- if (sources.length === 0) {
686
- return {
687
- catalog: {
688
- actionCount: 0,
689
- generatedAt: null,
690
- manifestPath: null,
691
- registryPath: null,
692
- stale: true,
693
- error: "No profile agent sources are enabled."
694
- },
695
- actionCatalog: [],
696
- sourceSetupRequirements: []
697
- };
698
- }
699
- const sortedSources = [
700
- ...sources.filter((source) => source.preferred),
701
- ...sources.filter((source) => !source.preferred)
702
- ];
703
- const results = await Promise.all(
704
- sortedSources.map(loadProfileActionCatalogSource)
705
- );
706
- const byId = /* @__PURE__ */ new Map();
707
- const actionCatalog = [];
708
- for (const result of results) {
709
- for (const action of result.actionCatalog) {
710
- const uniqueId = byId.has(action.id) ? `${action.agentId ?? "agent"}.${action.sourceActionId ?? action.id}` : action.id;
711
- const next = uniqueId === action.id ? action : { ...action, id: uniqueId };
712
- byId.set(uniqueId, next);
713
- actionCatalog.push(next);
714
- }
715
- }
716
- const generatedAt = latestIso(
717
- results.map((result) => result.catalog.generatedAt)
718
- );
719
- const errors = results.map((result) => result.catalog.error).filter(Boolean);
720
- return {
721
- catalog: {
722
- actionCount: actionCatalog.length,
723
- generatedAt,
724
- manifestPath: results.find((result) => result.catalog.manifestPath)?.catalog.manifestPath ?? null,
725
- registryPath: results.find((result) => result.catalog.registryPath)?.catalog.registryPath ?? null,
726
- stale: results.some((result) => result.catalog.stale),
727
- error: errors.length > 0 ? errors.join("; ") : null
728
- },
729
- actionCatalog,
730
- sourceSetupRequirements: results.flatMap(
731
- (result) => result.sourceSetupRequirements
732
- )
733
- };
734
- }
735
- async function loadProfileActionCatalogSource(source) {
736
- const sourcePath = source.sourcePath;
737
- const manifestPath = path3.join(sourcePath, AGENT_MANIFEST_PATH);
738
- const registryPath = path3.join(sourcePath, ACTION_REGISTRY_PATH);
739
- const sourceUploadMetadataPath = path3.join(
740
- sourcePath,
741
- SOURCE_UPLOAD_METADATA_PATH
742
- );
743
- const agentPackageOriginPath = path3.join(
744
- sourcePath,
745
- AGENT_PACKAGE_ORIGIN_PATH
746
- );
747
- try {
748
- const manifest = await readJsonIfExists(manifestPath);
749
- const registry = await readJsonIfExists(registryPath);
750
- const sourceUploadMetadata = await readJsonIfExists(
751
- sourceUploadMetadataPath
752
- );
753
- const agentPackageOrigin = asRecord(
754
- await readJsonIfExists(agentPackageOriginPath)
755
- );
756
- const namedInputSchemas = asRecord(asRecord(manifest)?.inputSchemas);
757
- const sourceSetupRequirements = recordArray(asRecord(sourceUploadMetadata)?.setupRequirements) ?? [];
758
- const sourceRequirementsByAction = sourceSetupRequirementsByAction(
759
- sourceSetupRequirements
760
- );
761
- const byId = /* @__PURE__ */ new Map();
762
- for (const record2 of [
763
- ...records(asRecord(manifest)?.actionCatalog),
764
- ...records(asRecord(registry)?.actions),
765
- ...records(asRecord(manifest)?.actions)
766
- ]) {
767
- const id = text3(record2.id) ?? text3(record2.name);
768
- if (!id) continue;
769
- const existing = byId.get(id);
770
- const actionSourceRequirements = setupRequirementsForActionSource({
771
- sourceRequirementsByAction,
772
- actionId: id,
773
- actionName: text3(record2.name)
774
- });
775
- const setupRequirements = mergeSetupRequirements(
776
- recordArray(record2.setupRequirements) ?? existing?.setupRequirements ?? [],
777
- actionSourceRequirements
778
- );
779
- const next = {
780
- id,
781
- agentId: source.agentId,
782
- sourcePath,
783
- sourceActionId: id,
784
- name: text3(record2.name) ?? existing?.name ?? id,
785
- label: text3(record2.label) ?? existing?.label ?? titleFromActionId(id),
786
- description: text3(record2.description) ?? existing?.description ?? null,
787
- visibility: text3(record2.visibility) ?? existing?.visibility ?? "default",
788
- inputSchema: resolvedSchemaValue(record2.inputSchema, namedInputSchemas) ?? existing?.inputSchema ?? null,
789
- outputSchema: schemaValue(record2.outputSchema) ?? existing?.outputSchema ?? null,
790
- approvalPolicy: asRecord(record2.approvalPolicy) ?? existing?.approvalPolicy ?? null,
791
- artifactPolicy: asRecord(record2.artifactPolicy) ?? existing?.artifactPolicy ?? null,
792
- setupRequirements,
793
- mcp: asRecord(record2.mcp) ?? existing?.mcp ?? null,
794
- schedulePolicy: asRecord(record2.schedulePolicy) ?? existing?.schedulePolicy ?? null,
795
- trace: mergeAgentPackageTrace(
796
- asRecord(record2.trace) ?? existing?.trace ?? null,
797
- agentPackageOrigin
798
- ),
799
- implementation: asRecord(record2.implementation) ?? existing?.implementation ?? null,
800
- invokesModel: typeof record2.invokesModel === "boolean" ? record2.invokesModel : existing?.invokesModel
801
- };
802
- byId.set(id, next);
803
- }
804
- const actionCatalog = Array.from(byId.values()).filter(
805
- (action) => action.visibility !== "internal" && action.visibility !== "debug"
806
- );
807
- const missingArtifacts = [
808
- ...!manifest ? [AGENT_MANIFEST_PATH] : [],
809
- ...!registry ? [ACTION_REGISTRY_PATH] : []
810
- ];
811
- const generatedAt = await latestMtime([manifestPath, registryPath]);
812
- return {
813
- catalog: {
814
- actionCount: actionCatalog.length,
815
- generatedAt,
816
- manifestPath: existsSync2(manifestPath) ? manifestPath : null,
817
- registryPath: existsSync2(registryPath) ? registryPath : null,
818
- stale: missingArtifacts.length > 0,
819
- error: missingArtifacts.length > 0 ? missingSourceArtifactsMessage(source, missingArtifacts) : null
820
- },
821
- actionCatalog,
822
- sourceSetupRequirements
823
- };
824
- } catch (error) {
825
- return {
826
- catalog: {
827
- actionCount: 0,
828
- generatedAt: null,
829
- manifestPath: existsSync2(manifestPath) ? manifestPath : null,
830
- registryPath: existsSync2(registryPath) ? registryPath : null,
831
- stale: true,
832
- error: error instanceof Error ? error.message : String(error)
833
- },
834
- actionCatalog: [],
835
- sourceSetupRequirements: []
836
- };
837
- }
838
- }
839
- function mergeAgentPackageTrace(trace, origin) {
840
- if (!origin) return trace;
841
- const versionId = text3(origin.versionId);
842
- const digest = text3(origin.digest);
843
- if (!versionId || !digest) return trace;
844
- return {
845
- ...trace ?? {},
846
- agentVersionId: versionId,
847
- agentPackageDigest: digest,
848
- validationReceiptIds: stringArray(origin.validationReceiptIds),
849
- evalReceiptIds: stringArray(origin.evalReceiptIds)
850
- };
851
- }
852
- function stringArray(value) {
853
- return Array.isArray(value) ? value.filter(
854
- (entry) => typeof entry === "string" && entry.trim().length > 0
855
- ) : [];
856
- }
857
- function latestIso(values) {
858
- let latest = 0;
859
- for (const value of values) {
860
- if (!value) continue;
861
- const time = Date.parse(value);
862
- if (Number.isFinite(time)) latest = Math.max(latest, time);
863
- }
864
- return latest > 0 ? new Date(latest).toISOString() : null;
865
- }
866
- function sourceSetupRequirementsByAction(records2) {
867
- const byAction = /* @__PURE__ */ new Map();
868
- for (const record2 of records2) {
869
- const actionIds = [
870
- text3(record2.actionId),
871
- text3(record2.sourceActionId),
872
- text3(record2.actionName)
873
- ].filter((value) => Boolean(value));
874
- for (const actionId of actionIds) {
875
- const current = byAction.get(actionId) ?? [];
876
- current.push(record2);
877
- byAction.set(actionId, current);
878
- }
879
- }
880
- return byAction;
881
- }
882
- function setupRequirementsForActionSource(input) {
883
- const matched = [
884
- ...input.sourceRequirementsByAction.get(input.actionId) ?? [],
885
- ...input.actionName && input.actionName !== input.actionId ? input.sourceRequirementsByAction.get(input.actionName) ?? [] : []
886
- ];
887
- return matched.map((record2) => ({
888
- ...record2,
889
- source: "source_upload_metadata"
890
- }));
891
- }
892
- function mergeSetupRequirements(primary, sourceUploadMetadata) {
893
- if (sourceUploadMetadata.length === 0) return primary;
894
- const merged = [];
895
- const seen = /* @__PURE__ */ new Set();
896
- for (const record2 of [...primary, ...sourceUploadMetadata]) {
897
- const key = setupRequirementIdentity(record2);
898
- if (seen.has(key)) continue;
899
- seen.add(key);
900
- merged.push(record2);
901
- }
902
- return merged;
903
- }
904
- function setupRequirementIdentity(record2) {
905
- return [
906
- text3(record2.actionId) ?? text3(record2.sourceActionId) ?? text3(record2.actionName) ?? "",
907
- text3(record2.kind) ?? text3(record2.type) ?? "",
908
- text3(record2.name) ?? text3(record2.key) ?? text3(record2.provider) ?? text3(record2.tool) ?? text3(record2.command) ?? text3(record2.packageName) ?? text3(record2.path) ?? text3(record2.repo) ?? text3(record2.url) ?? text3(record2.id) ?? ""
909
- ].join(":");
910
- }
911
- function missingSourceArtifactsMessage(source, missingArtifacts) {
912
- return [
913
- `Profile agent ${source.agentId} at ${source.sourcePath} is missing SDK catalog artifact(s): ${missingArtifacts.join(", ")}.`,
914
- "Run `openpond profile check --kind all` after source materialization so each enabled profile agent has inspect/build artifacts."
915
- ].join(" ");
916
- }
917
- async function readJsonIfExists(filePath) {
918
- if (!existsSync2(filePath)) return null;
919
- return JSON.parse(await readFile2(filePath, "utf8"));
920
- }
921
- async function latestMtime(filePaths) {
922
- let latest = 0;
923
- for (const filePath of filePaths) {
924
- if (!existsSync2(filePath)) continue;
925
- const fileStat = await stat2(filePath);
926
- latest = Math.max(latest, fileStat.mtimeMs);
927
- }
928
- return latest > 0 ? new Date(latest).toISOString() : null;
929
- }
930
- function asRecord(value) {
931
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
932
- }
933
- function records(value) {
934
- return Array.isArray(value) ? value.filter(
935
- (item) => Boolean(asRecord(item))
936
- ) : [];
937
- }
938
- function recordArray(value) {
939
- if (!Array.isArray(value)) return null;
940
- return value.filter(
941
- (item) => Boolean(asRecord(item))
942
- );
943
- }
944
- function text3(value) {
945
- return typeof value === "string" && value.trim() ? value.trim() : null;
946
- }
947
- function schemaValue(value) {
948
- return text3(value) ?? asRecord(value);
949
- }
950
- function resolvedSchemaValue(value, namedSchemas) {
951
- const schema = schemaValue(value);
952
- if (typeof schema !== "string") return schema;
953
- return asRecord(namedSchemas?.[schema]) ?? schema;
954
- }
955
- function titleFromActionId(id) {
956
- const title = id.replace(/[._-]+/g, " ").trim();
957
- return title ? title.replace(/\b\w/g, (letter) => letter.toUpperCase()) : id;
958
- }
959
-
960
- // ../../packages/cloud/src/profile/profile-skills.ts
961
- import { createHash } from "node:crypto";
962
- import { existsSync as existsSync3 } from "node:fs";
963
- import { readdir, readFile as readFile3, stat as stat3 } from "node:fs/promises";
964
- import path4 from "node:path";
965
- var PROFILE_SKILLS_DIR = "skills";
966
- var PROFILE_SKILL_FILE = "SKILL.md";
967
- var PROFILE_SKILL_MAX_CHARS = 8e4;
968
- async function loadProfileSkills(profileSourcePath2) {
969
- const skillsDir = path4.join(profileSourcePath2, PROFILE_SKILLS_DIR);
970
- if (!existsSync3(skillsDir)) {
971
- return {
972
- skillCatalog: emptyProfileSkillCatalogState2({ stale: false }),
973
- skills: []
974
- };
975
- }
976
- try {
977
- const entries = await readdir(skillsDir, { withFileTypes: true });
978
- const skills = (await Promise.all(
979
- entries.filter((entry) => entry.isDirectory()).map((entry) => loadProfileSkillDirectory(profileSourcePath2, entry.name))
980
- )).sort((left, right) => left.name.localeCompare(right.name) || left.path.localeCompare(right.path));
981
- markDuplicateSkillNames(skills);
982
- const generatedAt = await latestSkillMtime(profileSourcePath2, skills);
983
- return {
984
- skillCatalog: {
985
- skillCount: skills.length,
986
- generatedAt,
987
- stale: false,
988
- error: null
989
- },
990
- skills
991
- };
992
- } catch (error) {
993
- return {
994
- skillCatalog: emptyProfileSkillCatalogState2({
995
- stale: true,
996
- error: error instanceof Error ? error.message : String(error)
997
- }),
998
- skills: []
999
- };
1000
- }
1001
- }
1002
- function parseProfileSkillMarkdown(markdown) {
1003
- const messages = [];
1004
- const match = /^---\r?\n([\s\S]*?)\r?\n---(?:\r?\n|$)([\s\S]*)$/.exec(markdown);
1005
- if (!match) {
1006
- return {
1007
- name: null,
1008
- description: null,
1009
- body: markdown.trim(),
1010
- messages: ["SKILL.md must start with YAML frontmatter bounded by ---."]
1011
- };
1012
- }
1013
- const frontmatterSource = match[1] ?? "";
1014
- const body = (match[2] ?? "").trim();
1015
- let frontmatter;
1016
- try {
1017
- frontmatter = yaml.load(frontmatterSource);
1018
- } catch (error) {
1019
- messages.push(`SKILL.md frontmatter is invalid YAML: ${error instanceof Error ? error.message : String(error)}`);
1020
- }
1021
- const record2 = asRecord2(frontmatter);
1022
- const name = text4(record2?.name);
1023
- const description = text4(record2?.description);
1024
- if (!name) messages.push("Skill frontmatter must include a non-empty name.");
1025
- if (!description) messages.push("Skill frontmatter must include a non-empty description.");
1026
- if (!body) messages.push("Skill body must be non-empty markdown.");
1027
- return {
1028
- name,
1029
- description,
1030
- body,
1031
- messages
1032
- };
1033
- }
1034
- function emptyProfileSkillCatalogState2(input = {}) {
1035
- return {
1036
- skillCount: 0,
1037
- generatedAt: null,
1038
- stale: input.stale ?? true,
1039
- error: input.error ?? null
1040
- };
1041
- }
1042
- async function loadProfileSkillDirectory(profileSourcePath2, directoryName) {
1043
- const relativePath = path4.join(PROFILE_SKILLS_DIR, directoryName, PROFILE_SKILL_FILE).replace(/\\/g, "/");
1044
- const absolutePath = path4.join(profileSourcePath2, relativePath);
1045
- const messages = [];
1046
- const packageRoot = path4.join(profileSourcePath2, PROFILE_SKILLS_DIR, directoryName);
1047
- const packageFiles = await listPackageFiles(packageRoot);
1048
- let contents = "";
1049
- if (!existsSync3(absolutePath)) {
1050
- messages.push(`Missing ${PROFILE_SKILL_FILE}.`);
1051
- } else {
1052
- contents = await readFile3(absolutePath, "utf8");
1053
- }
1054
- if (contents.length > PROFILE_SKILL_MAX_CHARS) {
1055
- messages.push(`Skill markdown exceeds the limit of ${PROFILE_SKILL_MAX_CHARS} characters.`);
1056
- }
1057
- const parsed = parseProfileSkillMarkdown(contents);
1058
- messages.push(...parsed.messages);
1059
- const name = parsed.name ?? directoryName;
1060
- const description = parsed.description ?? "";
1061
- if (!isKebabCaseSkillName(name)) {
1062
- messages.push("Skill name must be lowercase kebab-case.");
1063
- }
1064
- if (name !== directoryName) {
1065
- messages.push(`Skill name must match its directory name (${directoryName}).`);
1066
- }
1067
- return {
1068
- name,
1069
- description,
1070
- path: relativePath,
1071
- scope: "profile",
1072
- enabled: messages.length === 0,
1073
- sourcePath: profileSourcePath2,
1074
- charCount: contents.length,
1075
- sourceHash: sha256Hex(contents),
1076
- validationStatus: messages.length > 0 ? "error" : "valid",
1077
- validationMessages: messages,
1078
- resourceFiles: packageFiles.filter((file) => file !== PROFILE_SKILL_FILE)
1079
- };
1080
- }
1081
- async function listPackageFiles(root) {
1082
- const files = [];
1083
- async function visit(directory, prefix) {
1084
- const entries = await readdir(directory, { withFileTypes: true });
1085
- await Promise.all(entries.map(async (entry) => {
1086
- const relativePath = prefix ? `${prefix}/${entry.name}` : entry.name;
1087
- if (entry.isDirectory()) {
1088
- await visit(path4.join(directory, entry.name), relativePath);
1089
- } else if (entry.isFile()) {
1090
- files.push(relativePath);
1091
- }
1092
- }));
1093
- }
1094
- await visit(root, "");
1095
- return files.sort();
1096
- }
1097
- function markDuplicateSkillNames(skills) {
1098
- const counts = /* @__PURE__ */ new Map();
1099
- for (const skill of skills) {
1100
- counts.set(skill.name, (counts.get(skill.name) ?? 0) + 1);
1101
- }
1102
- for (const skill of skills) {
1103
- if ((counts.get(skill.name) ?? 0) <= 1) continue;
1104
- skill.enabled = false;
1105
- skill.validationStatus = "error";
1106
- skill.validationMessages = [
1107
- ...skill.validationMessages,
1108
- `Duplicate skill name: ${skill.name}`
1109
- ];
1110
- }
1111
- }
1112
- async function latestSkillMtime(profileSourcePath2, skills) {
1113
- let latest = 0;
1114
- for (const skill of skills) {
1115
- const packageRoot = path4.dirname(path4.join(profileSourcePath2, skill.path));
1116
- const packageFiles = [PROFILE_SKILL_FILE, ...skill.resourceFiles];
1117
- for (const file of packageFiles) {
1118
- const fileStat = await stat3(path4.join(packageRoot, file)).catch(() => null);
1119
- if (!fileStat?.isFile()) continue;
1120
- latest = Math.max(latest, fileStat.mtimeMs);
1121
- }
1122
- }
1123
- return latest > 0 ? new Date(latest).toISOString() : null;
1124
- }
1125
- function isKebabCaseSkillName(value) {
1126
- return /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value);
1127
- }
1128
- function asRecord2(value) {
1129
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
1130
- }
1131
- function text4(value) {
1132
- if (typeof value !== "string") return null;
1133
- const trimmed = value.trim();
1134
- return trimmed.length > 0 ? trimmed : null;
1135
- }
1136
- function sha256Hex(contents) {
1137
- return createHash("sha256").update(contents).digest("hex");
1138
- }
1139
-
1140
- // ../../packages/cloud/src/profile/local-profile.ts
1141
- var PROFILE_REPO_MANIFEST = "openpond-profile.json";
1142
- var PROFILE_MANIFEST = "settings/profile.yaml";
1143
- var DEFAULT_LOCAL_PROFILE = "default";
1144
- var DEFAULT_PROFILE_AGENT = "default";
1145
- function mergeProfileRepoManifestEntry(existing, profilePath) {
1146
- const defaultAgent = existing?.defaultAgent ?? DEFAULT_PROFILE_AGENT;
1147
- const enabledAgents = existing?.enabledAgents && existing.enabledAgents.length > 0 ? existing.enabledAgents : [defaultAgent];
1148
- return {
1149
- ...existing ?? {},
1150
- path: profilePath,
1151
- defaultAgent,
1152
- enabledAgents
1153
- };
1154
- }
1155
- function mergeActiveLocalProfileConfig(existing, repoPath, profile) {
1156
- const previousEntries = profileConfigEntries(existing);
1157
- if (existing) {
1158
- const previousIndex = previousEntries.findIndex(
1159
- (entry) => path5.resolve(entry.repoPath) === path5.resolve(existing.repoPath) && entry.profile === existing.profile
1160
- );
1161
- const previousEntry = {
1162
- source: previousEntries[previousIndex]?.source ?? "local",
1163
- repositoryId: previousEntries[previousIndex]?.repositoryId ?? path5.resolve(existing.repoPath),
1164
- repoPath: path5.resolve(existing.repoPath),
1165
- profile: existing.profile,
1166
- ...existing.lastCheck ? { lastCheck: existing.lastCheck } : {},
1167
- ...existing.lastPush ? { lastPush: existing.lastPush } : {}
1168
- };
1169
- if (previousIndex >= 0) previousEntries[previousIndex] = previousEntry;
1170
- else previousEntries.push(previousEntry);
1171
- }
1172
- const targetIndex = previousEntries.findIndex(
1173
- (entry) => path5.resolve(entry.repoPath) === path5.resolve(repoPath) && entry.profile === profile
1174
- );
1175
- const target = targetIndex >= 0 ? previousEntries[targetIndex] : {
1176
- source: "local",
1177
- repositoryId: path5.resolve(repoPath),
1178
- repoPath: path5.resolve(repoPath),
1179
- profile
1180
- };
1181
- if (targetIndex < 0) previousEntries.push(target);
1182
- const next = {
1183
- repoPath: path5.resolve(repoPath),
1184
- profile,
1185
- mode: "local",
1186
- profiles: previousEntries,
1187
- ...target.lastCheck ? { lastCheck: target.lastCheck } : {},
1188
- ...target.lastPush ? { lastPush: target.lastPush } : {}
1189
- };
1190
- return next;
1191
- }
1192
- function profileConfigEntries(config) {
1193
- if (!config) return [];
1194
- const configured = config.profiles?.map((entry) => ({ ...entry })) ?? [];
1195
- if (!configured.some(
1196
- (entry) => path5.resolve(entry.repoPath) === path5.resolve(config.repoPath) && entry.profile === config.profile
1197
- )) {
1198
- configured.push({
1199
- source: "local",
1200
- repositoryId: path5.resolve(config.repoPath),
1201
- repoPath: path5.resolve(config.repoPath),
1202
- profile: config.profile,
1203
- ...config.lastCheck ? { lastCheck: config.lastCheck } : {},
1204
- ...config.lastPush ? { lastPush: config.lastPush } : {}
1205
- });
1206
- }
1207
- return configured;
1208
- }
1209
- var require2 = createRequire(import.meta.url);
1210
- function defaultLocalProfileRepoPath() {
1211
- return path5.join(resolveOpenPondHome(), "library", "profiles", "default-repo");
1212
- }
1213
- function emptyProfileState(error = null) {
1214
- return {
1215
- mode: "none",
1216
- repoPath: null,
1217
- activeProfile: null,
1218
- sourcePath: null,
1219
- manifestPath: null,
1220
- agents: [],
1221
- skills: [],
1222
- evals: [],
1223
- git: null,
1224
- catalog: emptyProfileCatalogState(error),
1225
- skillCatalog: emptyProfileSkillCatalogState(error),
1226
- actionCatalog: [],
1227
- sourceSetupRequirements: [],
1228
- setupGate: emptyProfileSetupGate(),
1229
- diff: emptyProfileDiffSummary(),
1230
- hosted: null,
1231
- summary: emptyProfileSummary(error),
1232
- lastCheck: null,
1233
- error
1234
- };
1235
- }
1236
- async function initLocalProfileRepo(input = {}) {
1237
- const repoPath = path5.resolve(
1238
- input.repoPath ?? defaultLocalProfileRepoPath()
1239
- );
1240
- const profile = normalizeProfileName(input.profile);
1241
- const profilePath = path5.join("profiles", profile);
1242
- const profileSourcePath2 = path5.join(repoPath, profilePath);
1243
- const template = input.template ?? "blank-agent";
1244
- const blankProfile = template === "blank-profile";
1245
- await mkdir(repoPath, { recursive: true });
1246
- const manifestAlreadyExists = existsSync4(
1247
- path5.join(repoPath, PROFILE_REPO_MANIFEST)
1248
- );
1249
- const manifest = await readProfileManifest(repoPath).catch(
1250
- () => defaultProfileManifest(profile, profilePath)
1251
- );
1252
- if (blankProfile && manifestAlreadyExists && manifest.profiles[profile]) {
1253
- throw new Error(`Profile "${profile}" already exists in ${repoPath}.`);
1254
- }
1255
- manifest.defaultProfile = manifest.defaultProfile || profile;
1256
- manifest.profiles[profile] = mergeProfileRepoManifestEntry(
1257
- manifest.profiles[profile],
1258
- profilePath
1259
- );
1260
- if (blankProfile) manifest.profiles[profile].enabledAgents = [];
1261
- if (blankProfile) await mkdir(profileSourcePath2, { recursive: true });
1262
- else {
1263
- await ensureProfileSource(
1264
- profileSourcePath2,
1265
- template,
1266
- Boolean(input.force)
1267
- );
1268
- }
1269
- await ensureProfileDependencies(profileSourcePath2);
1270
- await ensureProfileScaffoldFiles(repoPath, profileSourcePath2, profile, {
1271
- includeDefaultAgent: !blankProfile
1272
- });
1273
- await writeProfileManifest(repoPath, manifest);
1274
- await ensureProfileGitRepo(repoPath);
1275
- const currentConfig = (await loadGlobalConfig()).openpondProfile;
1276
- await saveGlobalConfig({
1277
- openpondProfile: mergeActiveLocalProfileConfig(
1278
- currentConfig,
1279
- repoPath,
1280
- profile
1281
- )
1282
- });
1283
- return loadOpenPondProfileState();
1284
- }
1285
- async function loadLocalProfileRepo(repoPathInput, profileInput, identity) {
1286
- const repoPath = path5.resolve(repoPathInput);
1287
- const manifest = await readProfileManifest(repoPath);
1288
- const profile = normalizeProfileName(profileInput ?? manifest.defaultProfile);
1289
- profileSourcePath(manifest, repoPath, profile);
1290
- const currentConfig = (await loadGlobalConfig()).openpondProfile;
1291
- const next = mergeActiveLocalProfileConfig(currentConfig, repoPath, profile);
1292
- applyProfileIdentity(next, repoPath, profile, identity);
1293
- await saveGlobalConfig({ openpondProfile: next });
1294
- return loadOpenPondProfileState();
1295
- }
1296
- function applyProfileIdentity(config, repoPath, profile, identity) {
1297
- if (!identity) return;
1298
- config.profiles = profileConfigEntries(config).map(
1299
- (entry) => path5.resolve(entry.repoPath) === repoPath && entry.profile === profile ? {
1300
- ...entry,
1301
- source: identity.source,
1302
- repositoryId: identity.repositoryId
1303
- } : entry
1304
- );
1305
- }
1306
- async function loadOpenPondProfileState() {
1307
- const config = await loadGlobalConfig();
1308
- const active = config.openpondProfile;
1309
- if (!active) return emptyProfileState();
1310
- return loadOpenPondProfileStateForConfig(active);
1311
- }
1312
- async function loadOpenPondProfileStateForConfig(active) {
1313
- try {
1314
- const manifest = await readProfileManifest(active.repoPath);
1315
- const sourcePath = profileSourcePath(
1316
- manifest,
1317
- active.repoPath,
1318
- active.profile
1319
- );
1320
- const agents = await listProfileAgents(manifest, active.profile);
1321
- const catalogSources = profileCatalogSources({
1322
- manifest,
1323
- profile: active.profile,
1324
- profileSourcePath: sourcePath,
1325
- agents
1326
- });
1327
- const [git, catalogResult, skillResult, evals] = await Promise.all([
1328
- loadProfileGitState(active.repoPath),
1329
- loadProfileActionCatalogForSources(catalogSources),
1330
- loadProfileSkills(sourcePath),
1331
- loadProfileEvals(sourcePath, catalogSources)
1332
- ]);
1333
- const hosted = hostedBindingFromConfig(active);
1334
- const diff = summarizeProfileDiff(git, active.profile);
1335
- const setupGate = buildOpenPondProfileSetupGate({
1336
- actionCatalog: catalogResult.actionCatalog,
1337
- sourceSetupRequirements: catalogResult.sourceSetupRequirements
1338
- });
1339
- const summary = summarizeProfileState({
1340
- agents,
1341
- actionCatalog: catalogResult.actionCatalog,
1342
- catalog: catalogResult.catalog,
1343
- diff,
1344
- git,
1345
- hosted,
1346
- lastCheck: active.lastCheck ?? null,
1347
- error: null
1348
- });
1349
- return {
1350
- mode: "local",
1351
- repoPath: active.repoPath,
1352
- activeProfile: active.profile,
1353
- sourcePath,
1354
- manifestPath: path5.join(active.repoPath, PROFILE_REPO_MANIFEST),
1355
- agents,
1356
- skills: skillResult.skills,
1357
- evals,
1358
- git,
1359
- catalog: catalogResult.catalog,
1360
- skillCatalog: skillResult.skillCatalog,
1361
- actionCatalog: catalogResult.actionCatalog,
1362
- sourceSetupRequirements: catalogResult.sourceSetupRequirements,
1363
- setupGate,
1364
- diff,
1365
- hosted,
1366
- summary,
1367
- lastCheck: active.lastCheck ?? null,
1368
- error: null
1369
- };
1370
- } catch (error) {
1371
- const git = await loadProfileGitState(active.repoPath).catch(() => null);
1372
- const errorMessage = error instanceof Error ? error.message : String(error);
1373
- return {
1374
- mode: "local",
1375
- repoPath: active.repoPath,
1376
- activeProfile: active.profile,
1377
- sourcePath: null,
1378
- manifestPath: path5.join(active.repoPath, PROFILE_REPO_MANIFEST),
1379
- agents: [],
1380
- skills: [],
1381
- evals: [],
1382
- git,
1383
- catalog: emptyProfileCatalogState(errorMessage),
1384
- skillCatalog: emptyProfileSkillCatalogState(errorMessage),
1385
- actionCatalog: [],
1386
- sourceSetupRequirements: [],
1387
- setupGate: emptyProfileSetupGate(),
1388
- diff: emptyProfileDiffSummary(),
1389
- hosted: hostedBindingFromConfig(active),
1390
- summary: emptyProfileSummary(errorMessage),
1391
- lastCheck: active.lastCheck ?? null,
1392
- error: errorMessage
1393
- };
1394
- }
1395
- }
1396
- async function requireActiveLocalProfile() {
1397
- const config = (await loadGlobalConfig()).openpondProfile;
1398
- if (!config) {
1399
- throw new Error(
1400
- "No active OpenPond profile. Run `openpond init` or `openpond profile load --path <dir>`."
1401
- );
1402
- }
1403
- const state = await loadOpenPondProfileState();
1404
- if (state.error) throw new Error(state.error);
1405
- if (!state.sourcePath)
1406
- throw new Error("Active OpenPond profile has no source path.");
1407
- return { config, state };
1408
- }
1409
- async function runProfileSdkCommand(input) {
1410
- const active = await requireActiveLocalProfile();
1411
- const requestedRunArgs = input.command === "run" ? input.args ?? [] : [];
1412
- const selectedAction = input.command === "run" ? active.state.actionCatalog.find(
1413
- (action) => action.id === requestedRunArgs[0]
1414
- ) : null;
1415
- const cwd = path5.resolve(
1416
- input.cwd ?? selectedAction?.sourcePath ?? active.state.sourcePath
1417
- );
1418
- const runArgs = input.command === "run" ? runCommandArgs(
1419
- cwd,
1420
- input.args ?? [],
1421
- selectedAction?.sourceActionId ?? null
1422
- ) : null;
1423
- if (input.command === "run" && runArgs) {
1424
- const actionId = runArgs[0];
1425
- const catalog = path5.resolve(active.state.sourcePath) === cwd ? {
1426
- actionCatalog: active.state.actionCatalog,
1427
- sourceSetupRequirements: active.state.sourceSetupRequirements
1428
- } : await loadProfileActionCatalog(cwd);
1429
- assertOpenPondProfileActionReady(
1430
- actionId,
1431
- buildOpenPondProfileSetupGate({
1432
- actionCatalog: catalog.actionCatalog,
1433
- sourceSetupRequirements: catalog.sourceSetupRequirements,
1434
- actionId
1435
- })
1436
- );
1437
- }
1438
- const result = await runAgentSdkProjectCommand({
1439
- command: input.command,
1440
- args: input.command === "run" ? runArgs ?? runCommandArgs(cwd, input.args ?? []) : input.args,
1441
- cwd,
1442
- inherit: input.inherit,
1443
- throwOnFailure: false
1444
- });
1445
- if (input.command === "inspect" || input.command === "build" || input.command === "validate" || input.command === "eval") {
1446
- await saveProfileCheckStatus(input.command, result.code);
1447
- }
1448
- if (result.code !== 0) {
1449
- const detail = result.stderr.trim() || result.stdout.trim();
1450
- throw new Error(
1451
- detail || `${input.command} failed with exit code ${result.code ?? "unknown"}`
1452
- );
1453
- }
1454
- return result;
1455
- }
1456
- async function runAgentSdkProjectCommand(input) {
1457
- const cwd = path5.resolve(input.cwd);
1458
- const cli = resolveAgentSdkCliLaunch();
1459
- const args = input.command === "run" ? [...cli.args, input.command, ...input.args ?? []] : [...cli.args, input.command, "--cwd", cwd, ...input.args ?? []];
1460
- const result = await spawnCommand(cli.command, args, {
1461
- cwd,
1462
- inherit: input.inherit,
1463
- timeoutMs: input.timeoutMs,
1464
- maxOutputBytes: input.maxOutputBytes
1465
- });
1466
- if (input.throwOnFailure !== false && result.code !== 0) {
1467
- const detail = commandFailureDetail(result, input.command);
1468
- throw new Error(
1469
- detail || `${input.command} failed with exit code ${result.code ?? "unknown"}`
1470
- );
1471
- }
1472
- return result;
1473
- }
1474
- function runCommandArgs(cwd, args, sourceActionId = null) {
1475
- const [actionName, ...rest] = args;
1476
- if (!actionName || actionName.startsWith("--")) {
1477
- throw new Error("run requires an action name");
1478
- }
1479
- return [sourceActionId ?? actionName, "--cwd", cwd, ...rest];
1480
- }
1481
- async function runProfileCheck(kind) {
1482
- const checks = !kind || kind === "all" ? ["inspect", "build", "validate", "eval"] : [kind];
1483
- const active = await requireActiveLocalProfile();
1484
- const manifest = await readProfileManifest(active.config.repoPath);
1485
- const sources = profileCatalogSources({
1486
- manifest,
1487
- profile: active.config.profile,
1488
- profileSourcePath: active.state.sourcePath,
1489
- agents: active.state.agents
1490
- });
1491
- for (const command of checks) {
1492
- if (command !== "inspect" && command !== "build" && command !== "validate" && command !== "eval") {
1493
- throw new Error(
1494
- "check kind must be one of inspect, build, validate, eval, all"
1495
- );
1496
- }
1497
- for (const source of sources) {
1498
- await runProfileCheckForSource({
1499
- command,
1500
- source,
1501
- profileSourcePath: active.state.sourcePath,
1502
- sourceCount: sources.length
1503
- });
1504
- }
1505
- }
1506
- }
1507
- async function runProfileCheckForSource(input) {
1508
- const args = input.command === "inspect" || input.command === "validate" || input.command === "eval" ? ["--json"] : [];
1509
- if (input.sourceCount > 1) {
1510
- const label = path5.relative(input.profileSourcePath, input.source.sourcePath) || ".";
1511
- console.log(
1512
- `
1513
- [profile:${input.source.agentId}] ${input.command} ${label}`
1514
- );
1515
- }
1516
- const result = await runAgentSdkProjectCommand({
1517
- command: input.command,
1518
- args,
1519
- cwd: input.source.sourcePath,
1520
- inherit: false,
1521
- throwOnFailure: false
1522
- });
1523
- if (result.stdout.trim()) console.log(result.stdout.trim());
1524
- if (result.stderr.trim()) console.error(result.stderr.trim());
1525
- await saveProfileCheckStatus(input.command, result.code);
1526
- if (result.code !== 0) {
1527
- const detail = commandFailureDetail(result, input.command);
1528
- throw new Error(
1529
- [
1530
- `Profile check failed for enabled agent ${input.source.agentId} at ${input.source.sourcePath}.`,
1531
- detail || `${input.command} failed with exit code ${result.code ?? "unknown"}`
1532
- ].join("\n")
1533
- );
1534
- }
1535
- }
1536
- async function commitActiveProfileChanges(message) {
1537
- const active = await requireActiveLocalProfile();
1538
- if (!active.state.repoPath) {
1539
- throw new Error("Active OpenPond profile has no repo path.");
1540
- }
1541
- const result = await commitProfileChanges(
1542
- active.state.repoPath,
1543
- message?.trim() || `Update OpenPond profile ${active.state.activeProfile ?? DEFAULT_LOCAL_PROFILE}`
1544
- );
1545
- return {
1546
- committed: result.committed,
1547
- stdout: result.stdout,
1548
- stderr: result.stderr,
1549
- state: await loadOpenPondProfileState()
1550
- };
1551
- }
1552
- async function saveProfilePushStatus(status) {
1553
- const config = (await loadGlobalConfig()).openpondProfile;
1554
- if (!config) return;
1555
- const profiles = profileConfigEntries(config).map(
1556
- (entry) => path5.resolve(entry.repoPath) === path5.resolve(config.repoPath) && entry.profile === config.profile ? { ...entry, lastPush: status } : entry
1557
- );
1558
- await saveGlobalConfig({
1559
- openpondProfile: {
1560
- ...config,
1561
- lastPush: status,
1562
- profiles
1563
- }
1564
- });
1565
- }
1566
- async function saveProfileCheckStatus(command, exitCode) {
1567
- const config = (await loadGlobalConfig()).openpondProfile;
1568
- if (!config) return;
1569
- const sourceHead = await profileGitHead(config.repoPath).catch(() => null);
1570
- const lastCheck = {
1571
- command,
1572
- status: exitCode === 0 ? "passed" : "failed",
1573
- checkedAt: (/* @__PURE__ */ new Date()).toISOString(),
1574
- exitCode,
1575
- sourceHead
1576
- };
1577
- const profiles = profileConfigEntries(config).map(
1578
- (entry) => path5.resolve(entry.repoPath) === path5.resolve(config.repoPath) && entry.profile === config.profile ? { ...entry, lastCheck } : entry
1579
- );
1580
- await saveGlobalConfig({
1581
- openpondProfile: {
1582
- ...config,
1583
- lastCheck,
1584
- profiles
1585
- }
1586
- });
1587
- }
1588
- async function ensureProfileSource(profileSourcePath2, template, force) {
1589
- await mkdir(profileSourcePath2, { recursive: true });
1590
- const entries = await readdir2(profileSourcePath2);
1591
- if (entries.length > 0 && !force) return;
1592
- const sdkRoot = resolveAgentSdkRoot();
1593
- const templateDir = path5.join(sdkRoot, "templates", template);
1594
- if (!existsSync4(templateDir)) {
1595
- throw new Error(`Unknown agent template "${template}".`);
1596
- }
1597
- await cp(templateDir, profileSourcePath2, {
1598
- recursive: true,
1599
- force,
1600
- errorOnExist: false
1601
- });
1602
- await rewriteTemplateSdkDependency(profileSourcePath2, sdkRoot);
1603
- }
1604
- async function ensureProfileScaffoldFiles(repoPath, profileSourcePath2, profile, options = {}) {
1605
- await mkdir(path5.join(repoPath, "profiles"), { recursive: true });
1606
- for (const dir of [
1607
- "agents",
1608
- "skills",
1609
- "actions",
1610
- "extensions",
1611
- "prompts",
1612
- "goals",
1613
- "evals",
1614
- "settings",
1615
- "traces"
1616
- ]) {
1617
- await mkdir(path5.join(profileSourcePath2, dir), { recursive: true });
1618
- }
1619
- const profileManifestPath = path5.join(profileSourcePath2, PROFILE_MANIFEST);
1620
- if (!existsSync4(profileManifestPath)) {
1621
- const agentLines = options.includeDefaultAgent === false ? ["agents: []"] : [
1622
- "agents:",
1623
- ` - id: ${DEFAULT_PROFILE_AGENT}`,
1624
- " path: agent/agent.ts",
1625
- " enabled: true"
1626
- ];
1627
- await writeFile2(
1628
- profileManifestPath,
1629
- [
1630
- "schema: openpond.profile.v1",
1631
- `profile: ${profile}`,
1632
- ...agentLines,
1633
- ""
1634
- ].join("\n"),
1635
- "utf8"
1636
- );
1637
- }
1638
- const lockPath = path5.join(profileSourcePath2, "openpond.lock");
1639
- if (!existsSync4(lockPath)) {
1640
- await writeFile2(
1641
- lockPath,
1642
- "# OpenPond profile lockfile placeholder\n",
1643
- "utf8"
1644
- );
1645
- }
1646
- }
1647
- async function rewriteTemplateSdkDependency(profileSourcePath2, sdkRoot) {
1648
- const packageJsonPath = path5.join(profileSourcePath2, "package.json");
1649
- const raw = await readFile4(packageJsonPath, "utf8");
1650
- const packageJson = JSON.parse(raw);
1651
- packageJson.dependencies = {
1652
- ...packageJson.dependencies ?? {},
1653
- "openpond-agent-sdk": `file:${sdkRoot}`
1654
- };
1655
- await writeFile2(
1656
- packageJsonPath,
1657
- `${JSON.stringify(packageJson, null, 2)}
1658
- `,
1659
- "utf8"
1660
- );
1661
- }
1662
- async function ensureProfileDependencies(profileSourcePath2) {
1663
- if (!existsSync4(path5.join(profileSourcePath2, "package.json"))) return;
1664
- const sdkRoot = resolveAgentSdkRoot();
1665
- await ensureAgentSdkBuilt(sdkRoot);
1666
- const nodeModulesPath = path5.join(profileSourcePath2, "node_modules");
1667
- const sdkLinkPath = path5.join(nodeModulesPath, "openpond-agent-sdk");
1668
- await mkdir(nodeModulesPath, { recursive: true });
1669
- if (!existsSync4(sdkLinkPath)) {
1670
- await symlink(sdkRoot, sdkLinkPath, "dir");
1671
- }
1672
- }
1673
- async function ensureAgentSdkBuilt(sdkRoot) {
1674
- if (existsSync4(path5.join(sdkRoot, "dist", "cli.js")) && existsSync4(path5.join(sdkRoot, "dist", "primitives", "index.js"))) {
1675
- return;
1676
- }
1677
- const buildScript = path5.join(sdkRoot, "scripts", "build.ts");
1678
- if (!existsSync4(buildScript)) {
1679
- throw new Error(
1680
- `Resolved openpond-agent-sdk at ${sdkRoot}, but built SDK files are missing.`
1681
- );
1682
- }
1683
- const result = await spawnCommand(
1684
- process.execPath,
1685
- [resolveTsxCli(sdkRoot), buildScript],
1686
- { cwd: sdkRoot }
1687
- );
1688
- if (result.code !== 0) {
1689
- const detail = result.stderr.trim() || result.stdout.trim();
1690
- throw new Error(
1691
- detail || `openpond-agent-sdk build failed with exit code ${result.code ?? "unknown"}`
1692
- );
1693
- }
1694
- }
1695
- async function listProfileAgents(manifest, profile) {
1696
- const profileConfig = manifest.profiles[profile];
1697
- if (!profileConfig) return [];
1698
- const defaultAgent = profileConfig.defaultAgent ?? DEFAULT_PROFILE_AGENT;
1699
- const enabled = new Set(profileConfig.enabledAgents ?? [defaultAgent]);
1700
- return Array.from(enabled).map((id) => ({
1701
- id,
1702
- name: profileConfig.agentNames?.[id]?.trim() || id,
1703
- path: id === DEFAULT_PROFILE_AGENT ? "agent/agent.ts" : `agents/${id}`,
1704
- enabled: true
1705
- }));
1706
- }
1707
- function profileCatalogSources(input) {
1708
- const defaultAgent = input.manifest.profiles[input.profile]?.defaultAgent ?? DEFAULT_PROFILE_AGENT;
1709
- const agents = input.agents.length > 0 ? input.agents : [
1710
- {
1711
- id: DEFAULT_PROFILE_AGENT,
1712
- name: DEFAULT_PROFILE_AGENT,
1713
- path: "agent/agent.ts",
1714
- enabled: true
1715
- }
1716
- ];
1717
- return agents.map((agent) => ({
1718
- agentId: agent.id,
1719
- sourcePath: agent.id === DEFAULT_PROFILE_AGENT ? input.profileSourcePath : path5.join(input.profileSourcePath, "agents", agent.id),
1720
- preferred: agent.id === defaultAgent
1721
- }));
1722
- }
1723
- async function loadProfileEvals(profileSourcePath2, sources) {
1724
- const evals = /* @__PURE__ */ new Map();
1725
- const roots = [
1726
- {
1727
- root: path5.join(profileSourcePath2, "evals"),
1728
- agentId: null
1729
- },
1730
- ...sources.flatMap((source) => [
1731
- {
1732
- root: path5.join(source.sourcePath, "agent", "evals"),
1733
- agentId: source.agentId
1734
- },
1735
- { root: path5.join(source.sourcePath, "evals"), agentId: source.agentId }
1736
- ])
1737
- ];
1738
- for (const entry of roots) {
1739
- for (const sourcePath of await listEvalSourceFiles(entry.root)) {
1740
- const relativePath = path5.relative(profileSourcePath2, sourcePath).split(path5.sep).join("/");
1741
- if (evals.has(relativePath)) continue;
1742
- evals.set(relativePath, {
1743
- id: relativePath,
1744
- name: path5.basename(sourcePath).replace(/\.eval\.[^.]+$/i, "").replace(/\.[^.]+$/i, ""),
1745
- path: relativePath,
1746
- agentId: entry.agentId,
1747
- sourcePath
1748
- });
1749
- }
1750
- }
1751
- return [...evals.values()].sort(
1752
- (left, right) => left.name.localeCompare(right.name) || left.path.localeCompare(right.path)
1753
- );
1754
- }
1755
- async function listEvalSourceFiles(root) {
1756
- if (!existsSync4(root)) return [];
1757
- const files = [];
1758
- for (const entry of await readdir2(root, { withFileTypes: true })) {
1759
- const sourcePath = path5.join(root, entry.name);
1760
- if (entry.isDirectory()) {
1761
- files.push(...await listEvalSourceFiles(sourcePath));
1762
- } else if (entry.isFile() && /\.eval\.(?:[cm]?[jt]sx?)$/i.test(entry.name)) {
1763
- files.push(sourcePath);
1764
- }
1765
- }
1766
- return files;
1767
- }
1768
- function hostedBindingFromConfig(config) {
1769
- const push = config.lastPush;
1770
- if (!push) return null;
1771
- return {
1772
- teamId: push.teamId ?? null,
1773
- projectId: push.projectId ?? null,
1774
- sourceRef: push.sourceRef ?? null,
1775
- sourceCommitSha: push.hostedHead ?? null,
1776
- lastPushedAt: push.pushedAt,
1777
- lastPushedLocalHead: push.localHead ?? null,
1778
- lastPushedHostedHead: push.hostedHead ?? null,
1779
- promotionStatus: push.promotionStatus ?? null,
1780
- hostedRunStatus: push.hostedRunStatus ?? null,
1781
- hostedRunAgentId: push.hostedRunAgentId ?? null,
1782
- hostedRunId: push.hostedRunId ?? null,
1783
- hostedRunAt: push.hostedRunAt ?? null,
1784
- hostedSourceMaterialization: push.hostedSourceMaterialization ?? null,
1785
- hostedSourceCheck: push.hostedSourceCheck ?? null,
1786
- hostedPublish: push.hostedPublish ?? null,
1787
- hostedRun: push.hostedRun ?? null
1788
- };
1789
- }
1790
- function summarizeProfileState(input) {
1791
- const defaultAction = input.actionCatalog.find((action) => action.id === "chat")?.id ?? input.actionCatalog.find((action) => action.name === "chat")?.id ?? input.actionCatalog.find((action) => action.id.endsWith(".chat"))?.id ?? null;
1792
- const checkFresh = Boolean(
1793
- input.lastCheck && input.lastCheck.status === "passed" && input.lastCheck.sourceHead && input.lastCheck.sourceHead === input.git.head && !input.git.dirty && !input.catalog.stale
1794
- );
1795
- const checkStaleReason = profileCheckStaleReason({
1796
- catalog: input.catalog,
1797
- git: input.git,
1798
- lastCheck: input.lastCheck
1799
- });
1800
- if (input.error) {
1801
- return {
1802
- state: "error",
1803
- message: input.error,
1804
- agentCount: input.agents.length,
1805
- actionCount: input.actionCatalog.length,
1806
- defaultAction,
1807
- checkFresh,
1808
- checkStaleReason,
1809
- localHead: input.git.head,
1810
- hostedHead: input.hosted?.sourceCommitSha ?? null
1811
- };
1812
- }
1813
- if (!input.git.isRepo) {
1814
- return {
1815
- state: "error",
1816
- message: "Profile source is not Git-backed.",
1817
- agentCount: input.agents.length,
1818
- actionCount: input.actionCatalog.length,
1819
- defaultAction,
1820
- checkFresh: false,
1821
- checkStaleReason: "Profile source is not Git-backed.",
1822
- localHead: null,
1823
- hostedHead: input.hosted?.sourceCommitSha ?? null
1824
- };
1825
- }
1826
- if (!input.git.head) {
1827
- return {
1828
- state: "pending_commit",
1829
- message: "Profile source is ready for its first commit.",
1830
- agentCount: input.agents.length,
1831
- actionCount: input.actionCatalog.length,
1832
- defaultAction,
1833
- checkFresh: false,
1834
- checkStaleReason: "Profile source has no committed head.",
1835
- localHead: null,
1836
- hostedHead: input.hosted?.sourceCommitSha ?? null
1837
- };
1838
- }
1839
- if (input.git.dirty) {
1840
- return {
1841
- state: "dirty",
1842
- message: profileDirtyMessage(input.diff),
1843
- agentCount: input.agents.length,
1844
- actionCount: input.actionCatalog.length,
1845
- defaultAction,
1846
- checkFresh,
1847
- checkStaleReason,
1848
- localHead: input.git.head,
1849
- hostedHead: input.hosted?.sourceCommitSha ?? null
1850
- };
1851
- }
1852
- return {
1853
- state: "ready",
1854
- message: input.catalog.stale ? "Profile source is clean; action catalog needs inspect/build." : "Profile source is clean.",
1855
- agentCount: input.agents.length,
1856
- actionCount: input.actionCatalog.length,
1857
- defaultAction,
1858
- checkFresh,
1859
- checkStaleReason,
1860
- localHead: input.git.head,
1861
- hostedHead: input.hosted?.sourceCommitSha ?? null
1862
- };
1863
- }
1864
- function profileCheckStaleReason(input) {
1865
- if (input.catalog.error) return `Catalog error: ${input.catalog.error}`;
1866
- if (input.catalog.stale)
1867
- return "Action catalog artifacts are missing or stale.";
1868
- if (!input.lastCheck) return "Profile checks have not run.";
1869
- if (input.lastCheck.status !== "passed")
1870
- return `Last ${input.lastCheck.command} check failed.`;
1871
- if (!input.lastCheck.sourceHead)
1872
- return "Last check did not record a source head.";
1873
- if (input.git.head && input.lastCheck.sourceHead !== input.git.head) {
1874
- return "Profile source changed since the last check.";
1875
- }
1876
- if (input.git.dirty) return "Profile has uncommitted source changes.";
1877
- return null;
1878
- }
1879
- function profileDirtyMessage(diff) {
1880
- const parts = [];
1881
- if (diff.changedAgents.length > 0)
1882
- parts.push(`${diff.changedAgents.length} changed agent(s)`);
1883
- if (diff.newAgents.length > 0)
1884
- parts.push(`${diff.newAgents.length} new agent(s)`);
1885
- if (diff.deletedAgents.length > 0)
1886
- parts.push(`${diff.deletedAgents.length} deleted agent(s)`);
1887
- if (diff.changedSkills.length > 0)
1888
- parts.push(`${diff.changedSkills.length} changed skill(s)`);
1889
- if (diff.changedActions.length > 0)
1890
- parts.push(`${diff.changedActions.length} changed action(s)`);
1891
- if (diff.changedExtensions.length > 0)
1892
- parts.push(`${diff.changedExtensions.length} changed extension(s)`);
1893
- if (diff.setupChanges.length > 0)
1894
- parts.push(`${diff.setupChanges.length} setup change(s)`);
1895
- if (diff.envRequirementChanges.length > 0)
1896
- parts.push(
1897
- `${diff.envRequirementChanges.length} env requirement change(s)`
1898
- );
1899
- return parts.length > 0 ? `Profile has ${parts.join(", ")}.` : "Profile has uncommitted source changes.";
1900
- }
1901
- function summarizeProfileDiff(git, profile) {
1902
- const diff = emptyProfileDiffSummary();
1903
- diff.files = git.files;
1904
- const profileRoot = `profiles/${profile}/`;
1905
- for (const file of git.files) {
1906
- const normalized = file.path.replace(/\\/g, "/");
1907
- if (normalized === PROFILE_REPO_MANIFEST || normalized === ".gitignore") {
1908
- addUnique(diff.setupChanges, normalized);
1909
- continue;
1910
- }
1911
- if (!normalized.startsWith(profileRoot)) continue;
1912
- const relative = normalized.slice(profileRoot.length);
1913
- classifyProfileFileChange(diff, file, relative);
1914
- }
1915
- return diff;
1916
- }
1917
- function classifyProfileFileChange(diff, file, relativePath) {
1918
- const firstSegment = relativePath.split("/")[0] ?? "";
1919
- if (firstSegment === "agent") {
1920
- addAgentChange(diff, DEFAULT_PROFILE_AGENT, file.category);
1921
- } else if (firstSegment === "agents") {
1922
- const agentId = relativePath.split("/")[1];
1923
- if (agentId) addAgentChange(diff, agentId, file.category);
1924
- } else if (firstSegment === "skills") {
1925
- addUnique(diff.changedSkills, relativePath.split("/")[1] ?? relativePath);
1926
- } else if (firstSegment === "actions") {
1927
- addUnique(diff.changedActions, relativePath.split("/")[1] ?? relativePath);
1928
- } else if (firstSegment === "extensions") {
1929
- addUnique(
1930
- diff.changedExtensions,
1931
- relativePath.split("/")[1] ?? relativePath
1932
- );
1933
- } else if (firstSegment === "settings" || relativePath === "package.json" || relativePath === "openpond.yaml" || relativePath === "openpond.lock") {
1934
- addUnique(diff.setupChanges, relativePath);
1935
- }
1936
- if (relativePath.toLowerCase().includes("env")) {
1937
- addUnique(diff.envRequirementChanges, relativePath);
1938
- }
1939
- if (relativePath.startsWith(".openpond/")) {
1940
- addUnique(diff.changedActions, "catalog");
1941
- }
1942
- }
1943
- function addAgentChange(diff, agentId, category) {
1944
- if (category === "added" || category === "untracked") {
1945
- addUnique(diff.newAgents, agentId);
1946
- return;
1947
- }
1948
- if (category === "deleted") {
1949
- addUnique(diff.deletedAgents, agentId);
1950
- return;
1951
- }
1952
- addUnique(diff.changedAgents, agentId);
1953
- }
1954
- function addUnique(values, value) {
1955
- if (!value || values.includes(value)) return;
1956
- values.push(value);
1957
- }
1958
- function normalizeProfileName(value) {
1959
- const trimmed = value?.trim();
1960
- if (!trimmed) return DEFAULT_LOCAL_PROFILE;
1961
- if (!/^[a-zA-Z0-9._-]+$/.test(trimmed)) {
1962
- throw new Error(
1963
- "profile name may only contain letters, numbers, dots, underscores, and hyphens"
1964
- );
1965
- }
1966
- return trimmed;
1967
- }
1968
- function defaultProfileManifest(profile, profilePath) {
1969
- return {
1970
- schema: "openpond.profileRepo.v1",
1971
- defaultProfile: profile,
1972
- profiles: {
1973
- [profile]: {
1974
- path: profilePath,
1975
- defaultAgent: DEFAULT_PROFILE_AGENT,
1976
- enabledAgents: [DEFAULT_PROFILE_AGENT]
1977
- }
1978
- }
1979
- };
1980
- }
1981
- async function readProfileManifest(repoPath) {
1982
- const manifestPath = path5.join(repoPath, PROFILE_REPO_MANIFEST);
1983
- const raw = await readFile4(manifestPath, "utf8");
1984
- const parsed = JSON.parse(raw);
1985
- if (parsed.schema !== "openpond.profileRepo.v1" || !parsed.profiles || typeof parsed.profiles !== "object") {
1986
- throw new Error(
1987
- `${manifestPath} is not an OpenPond profile repo manifest.`
1988
- );
1989
- }
1990
- return parsed;
1991
- }
1992
- async function writeProfileManifest(repoPath, manifest) {
1993
- await writeFile2(
1994
- path5.join(repoPath, PROFILE_REPO_MANIFEST),
1995
- `${JSON.stringify(manifest, null, 2)}
1996
- `,
1997
- "utf8"
1998
- );
1999
- }
2000
- function profileSourcePath(manifest, repoPath, profile) {
2001
- const profileConfig = manifest.profiles[profile];
2002
- if (!profileConfig) {
2003
- throw new Error(
2004
- `Profile "${profile}" was not found in ${path5.join(
2005
- repoPath,
2006
- PROFILE_REPO_MANIFEST
2007
- )}.`
2008
- );
2009
- }
2010
- const sourcePath = path5.resolve(repoPath, profileConfig.path);
2011
- if (!existsSync4(sourcePath)) {
2012
- throw new Error(`Profile source path does not exist: ${sourcePath}`);
2013
- }
2014
- return sourcePath;
2015
- }
2016
- function resolveAgentSdkRoot() {
2017
- const packageJsonPath = require2.resolve("openpond-agent-sdk/package.json");
2018
- return path5.dirname(packageJsonPath);
2019
- }
2020
- function resolveAgentSdkCliLaunch() {
2021
- const sdkRoot = resolveAgentSdkRoot();
2022
- const distCli = path5.join(sdkRoot, "dist", "cli.js");
2023
- if (existsSync4(distCli))
2024
- return { command: process.execPath, args: [distCli] };
2025
- const sourceCli = path5.join(sdkRoot, "src", "cli.ts");
2026
- if (existsSync4(sourceCli)) {
2027
- return {
2028
- command: process.execPath,
2029
- args: [resolveTsxCli(sdkRoot), sourceCli]
2030
- };
2031
- }
2032
- throw new Error(`openpond-agent CLI was not found under ${sdkRoot}`);
2033
- }
2034
- function resolveTsxCli(packageRoot) {
2035
- return createRequire(path5.join(packageRoot, "package.json")).resolve(
2036
- "tsx/cli"
2037
- );
2038
- }
2039
- async function spawnCommand(command, args, options = {}) {
2040
- return new Promise((resolve, reject) => {
2041
- const proc = spawn2(command, args, {
2042
- cwd: options.cwd,
2043
- stdio: options.inherit ? "inherit" : "pipe"
2044
- });
2045
- let stdout = "";
2046
- let stderr = "";
2047
- let stdoutTruncated = false;
2048
- let stderrTruncated = false;
2049
- let timedOut = false;
2050
- const timeoutMs = options.timeoutMs ?? 10 * 60 * 1e3;
2051
- const maxOutputBytes = options.maxOutputBytes ?? 2 * 1024 * 1024;
2052
- const timeout = timeoutMs > 0 ? setTimeout(() => {
2053
- timedOut = true;
2054
- proc.kill("SIGTERM");
2055
- }, timeoutMs) : null;
2056
- const forceKill = timeoutMs > 0 ? setTimeout(() => {
2057
- if (timedOut && proc.exitCode === null) proc.kill("SIGKILL");
2058
- }, timeoutMs + 5e3) : null;
2059
- if (!options.inherit) {
2060
- proc.stdout?.on("data", (chunk) => {
2061
- const next = appendBoundedOutput(
2062
- stdout,
2063
- String(chunk),
2064
- maxOutputBytes,
2065
- stdoutTruncated
2066
- );
2067
- stdout = next.text;
2068
- stdoutTruncated = next.truncated;
2069
- });
2070
- proc.stderr?.on("data", (chunk) => {
2071
- const next = appendBoundedOutput(
2072
- stderr,
2073
- String(chunk),
2074
- maxOutputBytes,
2075
- stderrTruncated
2076
- );
2077
- stderr = next.text;
2078
- stderrTruncated = next.truncated;
2079
- });
2080
- }
2081
- const clearTimers = () => {
2082
- if (timeout) clearTimeout(timeout);
2083
- if (forceKill) clearTimeout(forceKill);
2084
- };
2085
- proc.on("error", (error) => {
2086
- clearTimers();
2087
- reject(error);
2088
- });
2089
- proc.on("close", (code) => {
2090
- clearTimers();
2091
- resolve({
2092
- code,
2093
- stdout,
2094
- stderr,
2095
- timedOut,
2096
- stdoutTruncated,
2097
- stderrTruncated
2098
- });
2099
- });
2100
- });
2101
- }
2102
- function appendBoundedOutput(current, chunk, maxBytes, alreadyTruncated) {
2103
- if (alreadyTruncated) return { text: current, truncated: true };
2104
- const combined = `${current}${chunk}`;
2105
- if (Buffer.byteLength(combined, "utf8") <= maxBytes) {
2106
- return { text: combined, truncated: false };
2107
- }
2108
- const text5 = `${Buffer.from(combined).subarray(0, Math.max(0, maxBytes)).toString("utf8")}
2109
- [truncated after ${maxBytes} bytes]
2110
- `;
2111
- return { text: text5, truncated: true };
2112
- }
2113
- function commandFailureDetail(result, command) {
2114
- const detail = result.stderr.trim() || result.stdout.trim();
2115
- const notes = [
2116
- result.timedOut ? `${command} timed out` : "",
2117
- result.stdoutTruncated ? "stdout truncated" : "",
2118
- result.stderrTruncated ? "stderr truncated" : ""
2119
- ].filter(Boolean);
2120
- return [detail, ...notes].filter(Boolean).join("\n");
2121
- }
2122
-
2123
- // ../../packages/cloud/src/profile/hosted-run-idempotency.ts
2124
- import { createHash as createHash2, randomUUID } from "node:crypto";
2125
- function buildHostedRunIdempotencyKey(input) {
2126
- const explicit = input.explicitKey?.trim();
2127
- if (explicit) return explicit;
2128
- const sourceHead = input.sourceHead?.trim() || "unknown-source";
2129
- const targetProjectId = input.targetProjectId?.trim() || "no-target-project";
2130
- const inputHash = hashStableJson(input.input).slice(0, 16);
2131
- const base = `profile-push-run:${input.localHead}:${sourceHead}:${input.runtimeAgentId}:${targetProjectId}:${inputHash}`;
2132
- if (!input.retry) return base;
2133
- return `${base}:retry:${(input.randomId ?? randomUUID)()}`;
2134
- }
2135
- function hashStableJson(value) {
2136
- return createHash2("sha256").update(stableJsonStringify(value)).digest("hex");
2137
- }
2138
- function stableJsonStringify(value) {
2139
- if (value === void 0) return "undefined";
2140
- if (value === null || typeof value !== "object") return JSON.stringify(value) ?? "null";
2141
- if (Array.isArray(value)) {
2142
- return `[${value.map((item) => stableJsonStringify(item)).join(",")}]`;
2143
- }
2144
- return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, item]) => `${JSON.stringify(key)}:${stableJsonStringify(item)}`).join(",")}}`;
2145
- }
2146
-
2147
- export {
2148
- parseProfileSkillMarkdown,
2149
- formatOpenPondProfileSetupRequirement,
2150
- collectProfileSourceUploadEntries,
2151
- hostedSourceCheckStatusFromPayload,
2152
- hostedPublishStatusFromPayload,
2153
- hostedRunSummaryFromPayload,
2154
- hostedRunStatusFromRunSummary,
2155
- defaultLocalProfileRepoPath,
2156
- initLocalProfileRepo,
2157
- loadLocalProfileRepo,
2158
- loadOpenPondProfileState,
2159
- runProfileSdkCommand,
2160
- runProfileCheck,
2161
- commitActiveProfileChanges,
2162
- saveProfilePushStatus,
2163
- buildHostedRunIdempotencyKey
2164
- };